From 08de86c831eb3ef429f84458c014ed9252f6bbc8 Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Fri, 16 Sep 2005 19:40:27 +0000 Subject: [PATCH] Add a test for mmioDescend, make it pass under Wine. --- dlls/winmm/mmio.c | 72 +++++++------- dlls/winmm/tests/.cvsignore | 1 + dlls/winmm/tests/Makefile.in | 1 + dlls/winmm/tests/mmio.c | 176 +++++++++++++++++++++++++++++++++++ include/mmsystem.h | 6 ++ 5 files changed, 218 insertions(+), 38 deletions(-) create mode 100644 dlls/winmm/tests/mmio.c diff --git a/dlls/winmm/mmio.c b/dlls/winmm/mmio.c index 5fc8dfe1fd5..c47e7a7bae6 100644 --- a/dlls/winmm/mmio.c +++ b/dlls/winmm/mmio.c @@ -1143,7 +1143,6 @@ MMRESULT WINAPI mmioDescend(HMMIO hmmio, LPMMCKINFO lpck, FOURCC srchCkId; FOURCC srchType; - TRACE("(%p, %p, %p, %04X);\n", hmmio, lpck, lpckParent, uFlags); if (lpck == NULL) @@ -1166,57 +1165,54 @@ MMRESULT WINAPI mmioDescend(HMMIO hmmio, LPMMCKINFO lpck, * examples disagree -Marcus,990216. */ + srchCkId = 0; srchType = 0; + /* find_chunk looks for 'ckid' */ if (uFlags & MMIO_FINDCHUNK) srchCkId = lpck->ckid; + /* find_riff and find_list look for 'fccType' */ - if (uFlags & MMIO_FINDLIST) { + if (uFlags & MMIO_FINDLIST) + { srchCkId = FOURCC_LIST; - srchType = lpck->ckid; + srchType = lpck->fccType; } - if (uFlags & MMIO_FINDRIFF) { + + if (uFlags & MMIO_FINDRIFF) + { srchCkId = FOURCC_RIFF; - srchType = lpck->ckid; + srchType = lpck->fccType; } - if (uFlags & (MMIO_FINDCHUNK|MMIO_FINDLIST|MMIO_FINDRIFF)) { - TRACE("searching for %.4s.%.4s\n", - (LPSTR)&srchCkId, - srchType?(LPSTR)&srchType:"any "); + TRACE("searching for %4.4s.%4.4s\n", + (LPCSTR)&srchCkId, srchType ? (LPCSTR)&srchType : "any"); - while (TRUE) { - LONG ix; + while (TRUE) + { + LONG ix; - ix = mmioRead(hmmio, (LPSTR)lpck, 3 * sizeof(DWORD)); - if (ix < 2*sizeof(DWORD)) { - mmioSeek(hmmio, dwOldPos, SEEK_SET); - WARN("return ChunkNotFound\n"); - return MMIOERR_CHUNKNOTFOUND; - } - lpck->dwDataOffset = dwOldPos + 2 * sizeof(DWORD); - TRACE("ckid=%.4s fcc=%.4s cksize=%08lX !\n", - (LPSTR)&lpck->ckid, - srchType?(LPSTR)&lpck->fccType:"", - lpck->cksize); - if ((srchCkId == lpck->ckid) && - (!srchType || (srchType == lpck->fccType)) - ) - break; + ix = mmioRead(hmmio, (LPSTR)lpck, 3 * sizeof(DWORD)); + if (ix < 2*sizeof(DWORD)) + { + mmioSeek(hmmio, dwOldPos, SEEK_SET); + WARN("return ChunkNotFound\n"); + return MMIOERR_CHUNKNOTFOUND; + } - dwOldPos = lpck->dwDataOffset + ((lpck->cksize + 1) & ~1); - mmioSeek(hmmio, dwOldPos, SEEK_SET); - } - } else { - /* FIXME: unverified, does it do this? */ - /* NB: This part is used by WAVE_mciOpen, among others */ - if (mmioRead(hmmio, (LPSTR)lpck, 3 * sizeof(DWORD)) < 3 * sizeof(DWORD)) { - mmioSeek(hmmio, dwOldPos, SEEK_SET); - WARN("return ChunkNotFound 2nd\n"); - return MMIOERR_CHUNKNOTFOUND; - } - lpck->dwDataOffset = dwOldPos + 2 * sizeof(DWORD); + lpck->dwDataOffset = dwOldPos + 2 * sizeof(DWORD); + TRACE("ckid=%4.4s fcc=%4.4s cksize=%08lX !\n", + (LPCSTR)&lpck->ckid, + srchType ? (LPCSTR)&lpck->fccType:"", + lpck->cksize); + if ( (!srchCkId || (srchCkId == lpck->ckid)) && + (!srchType || (srchType == lpck->fccType)) ) + break; + + dwOldPos = lpck->dwDataOffset + ((lpck->cksize + 1) & ~1); + mmioSeek(hmmio, dwOldPos, SEEK_SET); } + lpck->dwFlags = 0; /* If we were looking for RIFF/LIST chunks, the final file position * is after the chunkid. If we were just looking for the chunk diff --git a/dlls/winmm/tests/.cvsignore b/dlls/winmm/tests/.cvsignore index 5e5f8e4c265..c2fb2987e9f 100644 --- a/dlls/winmm/tests/.cvsignore +++ b/dlls/winmm/tests/.cvsignore @@ -1,6 +1,7 @@ Makefile capture.ok mixer.ok +mmio.ok testlist.c timer.ok wave.ok diff --git a/dlls/winmm/tests/Makefile.in b/dlls/winmm/tests/Makefile.in index 28774f328c4..3b0928dbb9c 100644 --- a/dlls/winmm/tests/Makefile.in +++ b/dlls/winmm/tests/Makefile.in @@ -8,6 +8,7 @@ IMPORTS = winmm kernel32 CTESTS = \ capture.c \ mixer.c \ + mmio.c \ timer.c \ wave.c diff --git a/dlls/winmm/tests/mmio.c b/dlls/winmm/tests/mmio.c new file mode 100644 index 00000000000..debc88327cc --- /dev/null +++ b/dlls/winmm/tests/mmio.c @@ -0,0 +1,176 @@ +/* + * Unit tests for mmio APIs + * + * Copyright 2005 Dmitry Timoshkov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "mmsystem.h" +#include "vfw.h" +#include "wine/test.h" + +static const DWORD RIFF_buf[] = +{ + FOURCC_RIFF, 7*sizeof(DWORD)+sizeof(MainAVIHeader), mmioFOURCC('A','V','I',' '), + FOURCC_LIST, sizeof(DWORD)+sizeof(MMCKINFO)+sizeof(MainAVIHeader), listtypeAVIHEADER, + ckidAVIMAINHDR, sizeof(MainAVIHeader), + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static void test_mmioDescend(void) +{ + MMRESULT ret; + HMMIO hmmio; + MMIOINFO mmio; + MMCKINFO ckRiff, ckList, ck; + + memset(&mmio, 0, sizeof(mmio)); + mmio.fccIOProc = FOURCC_MEM; + mmio.cchBuffer = sizeof(RIFF_buf); + mmio.pchBuffer = (char *)&RIFF_buf; + + /*hmmio = mmioOpen("msrle.avi", NULL, MMIO_READ);*/ + hmmio = mmioOpen(NULL, &mmio, MMIO_READ); + ok(hmmio != 0, "mmioOpen error %u\n", mmio.wErrorRet); + trace("hmmio = %p\n", hmmio); + + /* first normal RIFF AVI parsing */ + ret = mmioDescend(hmmio, &ckRiff, NULL, 0); + ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret); + ok(ckRiff.ckid == FOURCC_RIFF, "wrong ckid: %04lx\n", ckRiff.ckid); + ok(ckRiff.fccType == formtypeAVI, "wrong fccType: %04lx\n", ckRiff.fccType); + trace("ckid %4.4s cksize %04lx fccType %4.4s off %04lx flags %04lx\n", + (LPCSTR)&ckRiff.ckid, ckRiff.cksize, (LPCSTR)&ckRiff.fccType, + ckRiff.dwDataOffset, ckRiff.dwFlags); + + ret = mmioDescend(hmmio, &ckList, &ckRiff, 0); + ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret); + ok(ckList.ckid == FOURCC_LIST, "wrong ckid: %04lx\n", ckList.ckid); + ok(ckList.fccType == listtypeAVIHEADER, "wrong fccType: %04lx\n", ckList.fccType); + trace("ckid %4.4s cksize %04lx fccType %4.4s off %04lx flags %04lx\n", + (LPCSTR)&ckList.ckid, ckList.cksize, (LPCSTR)&ckList.fccType, + ckList.dwDataOffset, ckList.dwFlags); + + ret = mmioDescend(hmmio, &ck, &ckList, 0); + ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret); + ok(ck.ckid == ckidAVIMAINHDR, "wrong ckid: %04lx\n", ck.ckid); + ok(ck.fccType == 0, "wrong fccType: %04lx\n", ck.fccType); + trace("ckid %4.4s cksize %04lx fccType %4.4s off %04lx flags %04lx\n", + (LPCSTR)&ck.ckid, ck.cksize, (LPCSTR)&ck.fccType, + ck.dwDataOffset, ck.dwFlags); + + /* test various mmioDescend flags */ + + mmioSeek(hmmio, 0, SEEK_SET); + memset(&ck, 0x55, sizeof(ck)); + ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDRIFF); + ok(ret == MMIOERR_CHUNKNOTFOUND || + ret == MMIOERR_INVALIDFILE, "mmioDescend returned %u\n", ret); + + mmioSeek(hmmio, 0, SEEK_SET); + memset(&ck, 0x55, sizeof(ck)); + ck.ckid = 0; + ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDRIFF); + ok(ret == MMIOERR_CHUNKNOTFOUND || + ret == MMIOERR_INVALIDFILE, "mmioDescend returned %u\n", ret); + + mmioSeek(hmmio, 0, SEEK_SET); + memset(&ck, 0x55, sizeof(ck)); + ck.fccType = 0; + ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDRIFF); + ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret); + ok(ck.ckid == FOURCC_RIFF, "wrong ckid: %04lx\n", ck.ckid); + ok(ck.fccType == formtypeAVI, "wrong fccType: %04lx\n", ck.fccType); + + mmioSeek(hmmio, 0, SEEK_SET); + memset(&ck, 0x55, sizeof(ck)); + ret = mmioDescend(hmmio, &ck, NULL, 0); + ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret); + ok(ck.ckid == FOURCC_RIFF, "wrong ckid: %04lx\n", ck.ckid); + ok(ck.fccType == formtypeAVI, "wrong fccType: %04lx\n", ck.fccType); + + /* do NOT seek, use current file position */ + memset(&ck, 0x55, sizeof(ck)); + ck.fccType = 0; + ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDLIST); + ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret); + ok(ck.ckid == FOURCC_LIST, "wrong ckid: %04lx\n", ck.ckid); + ok(ck.fccType == listtypeAVIHEADER, "wrong fccType: %04lx\n", ck.fccType); + + mmioSeek(hmmio, 0, SEEK_SET); + memset(&ck, 0x55, sizeof(ck)); + ck.ckid = 0; + ck.fccType = listtypeAVIHEADER; + ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDCHUNK); + ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret); + ok(ck.ckid == FOURCC_RIFF, "wrong ckid: %04lx\n", ck.ckid); + ok(ck.fccType == formtypeAVI, "wrong fccType: %04lx\n", ck.fccType); + + /* do NOT seek, use current file position */ + memset(&ck, 0x55, sizeof(ck)); + ck.ckid = FOURCC_LIST; + ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDCHUNK); + ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret); + ok(ck.ckid == FOURCC_LIST, "wrong ckid: %04lx\n", ck.ckid); + ok(ck.fccType == listtypeAVIHEADER, "wrong fccType: %04lx\n", ck.fccType); + + mmioSeek(hmmio, 0, SEEK_SET); + memset(&ck, 0x55, sizeof(ck)); + ck.ckid = FOURCC_RIFF; + ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDCHUNK); + ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret); + ok(ck.ckid == FOURCC_RIFF, "wrong ckid: %04lx\n", ck.ckid); + ok(ck.fccType == formtypeAVI, "wrong fccType: %04lx\n", ck.fccType); + + /* do NOT seek, use current file position */ + memset(&ckList, 0x55, sizeof(ckList)); + ckList.ckid = 0; + ret = mmioDescend(hmmio, &ckList, &ck, MMIO_FINDCHUNK); + ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret); + ok(ckList.ckid == FOURCC_LIST, "wrong ckid: %04lx\n", ckList.ckid); + ok(ckList.fccType == listtypeAVIHEADER, "wrong fccType: %04lx\n", ckList.fccType); + + mmioSeek(hmmio, 0, SEEK_SET); + memset(&ck, 0x55, sizeof(ck)); + ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDCHUNK); + ok(ret == MMIOERR_CHUNKNOTFOUND || + ret == MMIOERR_INVALIDFILE, "mmioDescend returned %u\n", ret); + ok(ck.ckid != 0x55555555, "wrong ckid: %04lx\n", ck.ckid); + ok(ck.fccType != 0x55555555, "wrong fccType: %04lx\n", ck.fccType); + ok(ck.dwDataOffset != 0x55555555, "wrong dwDataOffset: %04lx\n", ck.dwDataOffset); + + mmioSeek(hmmio, 0, SEEK_SET); + memset(&ck, 0x55, sizeof(ck)); + ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDRIFF); + ok(ret == MMIOERR_CHUNKNOTFOUND || + ret == MMIOERR_INVALIDFILE, "mmioDescend returned %u\n", ret); + + mmioClose(hmmio, 0); +} + +START_TEST(mmio) +{ + test_mmioDescend(); +} diff --git a/include/mmsystem.h b/include/mmsystem.h index 3ee92cf7b05..81b34e6d97d 100644 --- a/include/mmsystem.h +++ b/include/mmsystem.h @@ -1515,6 +1515,12 @@ UINT WINAPI mixerSetControlDetails(HMIXEROBJ,LPMIXERCONTROLDETAILS,DWORD); #define MMIOERR_CANNOTEXPAND (MMIOERR_BASE + 8) /* cannot expand file */ #define MMIOERR_CHUNKNOTFOUND (MMIOERR_BASE + 9) /* chunk not found */ #define MMIOERR_UNBUFFERED (MMIOERR_BASE + 10) /* file is unbuffered */ +#define MMIOERR_PATHNOTFOUND (MMIOERR_BASE + 11) +#define MMIOERR_ACCESSDENIED (MMIOERR_BASE + 12) +#define MMIOERR_SHARINGVIOLATION (MMIOERR_BASE + 13) +#define MMIOERR_NETWORKERROR (MMIOERR_BASE + 14) +#define MMIOERR_TOOMANYOPENFILES (MMIOERR_BASE + 15) +#define MMIOERR_INVALIDFILE (MMIOERR_BASE + 16) #define CFSEPCHAR '+' /* compound file name separator char. */