Add a test for mmioDescend, make it pass under Wine

Dmitry Timoshkov dmitry at baikal.ru
Fri Sep 16 07:12:35 CDT 2005


Hello,

this is a proper fix for the mmioDescend problems.

Changelog:
    Dmitry Timoshkov <dmitry at codeweavers.com>
    Add a test for mmioDescend, make it pass under Wine.

diff -up cvs/hq/wine/dlls/winmm/mmio.c wine/dlls/winmm/mmio.c
--- cvs/hq/wine/dlls/winmm/mmio.c	2005-09-09 17:40:30.000000000 +0900
+++ wine/dlls/winmm/mmio.c	2005-09-16 20:49:16.000000000 +0900
@@ -1143,7 +1143,6 @@ MMRESULT WINAPI mmioDescend(HMMIO hmmio,
     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,
      * 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 ");
-
-	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:"<na>",
-		  lpck->cksize);
-	    if ((srchCkId == lpck->ckid) &&
-		(!srchType || (srchType == lpck->fccType))
-		)
-		break;
+    TRACE("searching for %4.4s.%4.4s\n",
+          (LPCSTR)&srchCkId, srchType ? (LPCSTR)&srchType : "any");
 
-	    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);
+    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=%4.4s fcc=%4.4s cksize=%08lX !\n",
+              (LPCSTR)&lpck->ckid,
+              srchType ? (LPCSTR)&lpck->fccType:"<na>",
+              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 -up cvs/hq/wine/dlls/winmm/tests/.cvsignore wine/dlls/winmm/tests/.cvsignore
--- cvs/hq/wine/dlls/winmm/tests/.cvsignore	2005-02-15 19:10:26.000000000 +0800
+++ wine/dlls/winmm/tests/.cvsignore	2005-09-16 20:29:06.000000000 +0900
@@ -1,6 +1,7 @@
 Makefile
 capture.ok
 mixer.ok
+mmio.ok
 testlist.c
 timer.ok
 wave.ok
diff -up cvs/hq/wine/dlls/winmm/tests/Makefile.in wine/dlls/winmm/tests/Makefile.in
--- cvs/hq/wine/dlls/winmm/tests/Makefile.in	2005-02-15 19:10:26.000000000 +0800
+++ wine/dlls/winmm/tests/Makefile.in	2005-09-16 20:29:20.000000000 +0900
@@ -8,6 +8,7 @@ IMPORTS   = winmm kernel32
 CTESTS = \
 	capture.c \
 	mixer.c \
+	mmio.c \
 	timer.c \
 	wave.c
 
diff -up /dev/null wine/dlls/winmm/tests/mmio.c
--- /dev/null	1970-01-01 08:00:00.000000000 +0800
+++ wine/dlls/winmm/tests/mmio.c	2005-09-16 20:32:12.000000000 +0900
@@ -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 <assert.h>
+#include <stdarg.h>
+
+#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 -up cvs/hq/wine/include/mmsystem.h wine/include/mmsystem.h
--- cvs/hq/wine/include/mmsystem.h	2005-08-22 11:43:36.000000000 +0900
+++ wine/include/mmsystem.h	2005-09-16 20:34:44.000000000 +0900
@@ -1515,6 +1515,12 @@ UINT		WINAPI	mixerSetControlDetails(HMIX
 #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. */
 






More information about the wine-patches mailing list