another winmm test patch

Robert Reif reif at earthlink.net
Wed May 26 21:38:06 CDT 2004


This patch exercises the wave mapper and msacm pcmconverter
much harder than before.

Adds WAVE_MAPPED flag test.
Adds 8000 Hz test as a typically supported format.
Adds 12000 Hz test as a typically unsupported format.
Tests error reporting better by testing unsupported formats.
Tests using PCMWAVEFORMAT in place of WAVEFORMATEX.

This test works fine on Windows XP but uncovers problems with
the wave mapper and the msacm pcmconverter.  The wave mapper
returns improper error results for unsupported formats.  There is an off
by one bug in the pcmconverter that can show up while doing capture.
This test will crash when tracing winmm because waveOutOpen has
a trace that accesses cbSize which may not be there when passed a
PCMWAVEFORMAT structure.
-------------- next part --------------
Index: dlls/winmm/tests/capture.c
===================================================================
RCS file: /home/wine/wine/dlls/winmm/tests/capture.c,v
retrieving revision 1.2
diff -u -r1.2 capture.c
--- dlls/winmm/tests/capture.c	21 May 2004 20:53:45 -0000	1.2
+++ dlls/winmm/tests/capture.c	27 May 2004 02:20:53 -0000
@@ -46,37 +46,43 @@
     return long_msg;
 }
 
-static void wave_in_test_deviceIn(int device, int format, DWORD flags, LPWAVEINCAPS pcaps)
+static void wave_in_test_deviceIn(int device, LPWAVEFORMATEX pwfx, DWORD format, DWORD flags, LPWAVEINCAPS pcaps)
 {
-    WAVEFORMATEX wfx;
     HWAVEIN win;
     HANDLE hevent;
     WAVEHDR frag;
     MMRESULT rc;
     DWORD res;
+    WORD nChannels = pwfx->nChannels;
+    WORD wBitsPerSample = pwfx->wBitsPerSample;
+    DWORD nSamplesPerSec = pwfx->nSamplesPerSec;
 
     hevent=CreateEvent(NULL,FALSE,FALSE,NULL);
     ok(hevent!=NULL,"CreateEvent: error=%ld\n",GetLastError());
     if (hevent==NULL)
         return;
 
-    wfx.wFormatTag=WAVE_FORMAT_PCM;
-    wfx.nChannels=win_formats[format][3];
-    wfx.wBitsPerSample=win_formats[format][2];
-    wfx.nSamplesPerSec=win_formats[format][1];
-    wfx.nBlockAlign=wfx.nChannels*wfx.wBitsPerSample/8;
-    wfx.nAvgBytesPerSec=wfx.nSamplesPerSec*wfx.nBlockAlign;
-    wfx.cbSize=0;
-
     win=NULL;
-    rc=waveInOpen(&win,device,&wfx,(DWORD)hevent,0,CALLBACK_EVENT|flags);
+    rc=waveInOpen(&win,device,pwfx,(DWORD)hevent,0,CALLBACK_EVENT|flags);
     /* Note: Win9x doesn't know WAVE_FORMAT_DIRECT */
     ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_BADDEVICEID ||
-       (rc==WAVERR_BADFORMAT && (flags & WAVE_FORMAT_DIRECT) && (pcaps->dwFormats & win_formats[format][0])) ||
+       ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
+       (flags & WAVE_FORMAT_DIRECT) && !(pcaps->dwFormats & format)) ||
+       ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
+       (!(flags & WAVE_FORMAT_DIRECT) || (flags & WAVE_MAPPED)) && !(pcaps->dwFormats & format)) ||
        (rc==MMSYSERR_INVALFLAG && (flags & WAVE_FORMAT_DIRECT)),
        "waveInOpen: device=%d format=%ldx%2dx%d flags=%lx(%s) rc=%s\n",device,
-       wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,CALLBACK_EVENT|flags,
+       pwfx->nSamplesPerSec,pwfx->wBitsPerSample,pwfx->nChannels,CALLBACK_EVENT|flags,
        wave_open_flags(CALLBACK_EVENT|flags),wave_in_error(rc));
+    if ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
+       (flags & WAVE_FORMAT_DIRECT) && (pcaps->dwFormats & format))
+        trace(" Reason: The device lists this format as supported in it's capabilities but opening it failed.\n");
+    if ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
+       !(pcaps->dwFormats & format))
+        trace("waveInOpen: device=%d format=%ldx%2dx%d %s rc=%s failed but format not supported so OK.\n",
+              device, pwfx->nSamplesPerSec,pwfx->wBitsPerSample,pwfx->nChannels,
+              flags & WAVE_FORMAT_DIRECT ? "flags=WAVE_FORMAT_DIRECT" :
+              flags & WAVE_MAPPED ? "flags=WAVE_MAPPED" : "", mmsys_error(rc));
     if (rc!=MMSYSERR_NOERROR) {
         CloseHandle(hevent);
         return;
@@ -84,16 +90,15 @@
     res=WaitForSingleObject(hevent,1000);
     ok(res==WAIT_OBJECT_0,"WaitForSingleObject failed for open\n");
 
-    ok(wfx.nChannels==win_formats[format][3] &&
-       wfx.wBitsPerSample==win_formats[format][2] &&
-       wfx.nSamplesPerSec==win_formats[format][1],
-       "got the wrong format: %ldx%2dx%d instead of %dx%2dx%d\n",
-       wfx.nSamplesPerSec, wfx.wBitsPerSample,
-       wfx.nChannels, win_formats[format][1], win_formats[format][2],
-       win_formats[format][3]);
+    ok(pwfx->nChannels==nChannels &&
+       pwfx->wBitsPerSample==wBitsPerSample &&
+       pwfx->nSamplesPerSec==nSamplesPerSec,
+       "got the wrong format: %ldx%2dx%d instead of %ldx%2dx%d\n",
+       pwfx->nSamplesPerSec, pwfx->wBitsPerSample,
+       pwfx->nChannels, nSamplesPerSec, wBitsPerSample, nChannels);
 
-    frag.lpData=malloc(wfx.nAvgBytesPerSec);
-    frag.dwBufferLength=wfx.nAvgBytesPerSec;
+    frag.lpData=malloc(pwfx->nAvgBytesPerSec);
+    frag.dwBufferLength=pwfx->nAvgBytesPerSec;
     frag.dwBytesRecorded=0;
     frag.dwUser=0;
     frag.dwFlags=0;
@@ -105,9 +110,10 @@
     ok(frag.dwFlags&WHDR_PREPARED,"waveInPrepareHeader: prepared flag not set\n");
 
     if (winetest_interactive && rc==MMSYSERR_NOERROR) {
-        trace("Recording for 1 second at %5ldx%2dx%d %04lx\n",
-              wfx.nSamplesPerSec, wfx.wBitsPerSample,wfx.nChannels,flags);
-
+        trace("Recording for 1 second at %5ldx%2dx%d %s\n",
+              pwfx->nSamplesPerSec, pwfx->wBitsPerSample,pwfx->nChannels,
+              flags & WAVE_FORMAT_DIRECT ? "WAVE_FORMAT_DIRECT" :
+              flags & WAVE_MAPPED ? "WAVE_MAPPED" : "");
         rc=waveInAddBuffer(win, &frag, sizeof(frag));
         ok(rc==MMSYSERR_NOERROR,"waveInAddBuffer: device=%d rc=%s\n",device,wave_in_error(rc));
 
@@ -117,8 +123,8 @@
         res = WaitForSingleObject(hevent,1200);
         ok(res==WAIT_OBJECT_0,"WaitForSingleObject failed for header\n");
         ok(frag.dwFlags&WHDR_DONE,"WHDR_DONE not set in frag.dwFlags\n");
-        ok(frag.dwBytesRecorded==wfx.nAvgBytesPerSec,"frag.dwBytesRecorded=%ld, should=%ld\n",
-           frag.dwBytesRecorded,wfx.nAvgBytesPerSec);
+        ok(frag.dwBytesRecorded==pwfx->nAvgBytesPerSec,"frag.dwBytesRecorded=%ld, should=%ld\n",
+           frag.dwBytesRecorded,pwfx->nAvgBytesPerSec);
         /* stop playing on error */
         if (res!=WAIT_OBJECT_0) {
             rc=waveInStop(win);
@@ -131,7 +137,9 @@
     ok(rc==MMSYSERR_NOERROR,
        "waveInUnprepareHeader: device=%d rc=%s\n",device,wave_in_error(rc));
 
-    waveInClose(win);
+    rc=waveInClose(win);
+    ok(rc==MMSYSERR_NOERROR,
+       "waveInClose: device=%d rc=%s\n",device,wave_in_error(rc));
     res=WaitForSingleObject(hevent,1000);
     ok(res==WAIT_OBJECT_0,"WaitForSingleObject failed for close\n");
     free(frag.lpData);
@@ -148,6 +156,14 @@
     WCHAR * wname;
     CHAR * name;
     DWORD size;
+    DWORD dwPageSize;
+    BYTE * twoPages;
+    SYSTEM_INFO sSysInfo;
+    DWORD flOldProtect;
+    BOOL res;
+
+    GetSystemInfo(&sSysInfo);
+    dwPageSize = sSysInfo.dwPageSize;
 
     ndev=waveInGetNumDevs();
     trace("found %d WaveIn devices\n",ndev);
@@ -205,13 +221,41 @@
               caps.vDriverVersion & 0xff,
               caps.wMid,caps.wPid,
               caps.wChannels,caps.dwFormats);
+
         free(name);
 
         for (f=0;f<NB_WIN_FORMATS;f++) {
-            if (caps.dwFormats & win_formats[f][0]) {
-                wave_in_test_deviceIn(d,f,0, &caps);
-                wave_in_test_deviceIn(d,f,WAVE_FORMAT_DIRECT, &caps);
+            format.wFormatTag=WAVE_FORMAT_PCM;
+            format.nChannels=win_formats[f][3];
+            format.wBitsPerSample=win_formats[f][2];
+            format.nSamplesPerSec=win_formats[f][1];
+            format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
+            format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
+            format.cbSize=0;
+            wave_in_test_deviceIn(d,&format,win_formats[f][0],0, &caps);
+            wave_in_test_deviceIn(d,&format,win_formats[f][0],WAVE_FORMAT_DIRECT, &caps);
+            wave_in_test_deviceIn(d,&format,win_formats[f][0],WAVE_MAPPED, &caps);
+        }
+
+        /* Try a PCMWAVEFORMAT aligned next to an unaccessable page for bounds checking */
+        twoPages = VirtualAlloc(NULL, 2 * dwPageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
+        ok(twoPages!=NULL,"Failed to allocate 2 pages of memory\n");
+        if (twoPages) {
+            res = VirtualProtect(twoPages + dwPageSize, dwPageSize, PAGE_NOACCESS, &flOldProtect);
+            ok(res, "Failed to set memory access on second page\n");
+            if (res) {
+                LPWAVEFORMATEX pwfx = (LPWAVEFORMATEX)(twoPages + dwPageSize - sizeof(PCMWAVEFORMAT));
+                pwfx->wFormatTag=WAVE_FORMAT_PCM;
+                pwfx->nChannels=1;
+                pwfx->wBitsPerSample=8;
+                pwfx->nSamplesPerSec=22050;
+                pwfx->nBlockAlign=pwfx->nChannels*pwfx->wBitsPerSample/8;
+                pwfx->nAvgBytesPerSec=pwfx->nSamplesPerSec*pwfx->nBlockAlign;
+                wave_in_test_deviceIn(d,pwfx,WAVE_FORMAT_2M08,0, &caps);
+                wave_in_test_deviceIn(d,pwfx,WAVE_FORMAT_2M08,WAVE_FORMAT_DIRECT, &caps);
+                wave_in_test_deviceIn(d,pwfx,WAVE_FORMAT_2M08,WAVE_MAPPED, &caps);
             }
+            VirtualFree(twoPages, 2 * dwPageSize, MEM_RELEASE);
         }
 
         /* Try invalid formats to test error handling */
Index: dlls/winmm/tests/wave.c
===================================================================
RCS file: /home/wine/wine/dlls/winmm/tests/wave.c,v
retrieving revision 1.25
diff -u -r1.25 wave.c
--- dlls/winmm/tests/wave.c	21 May 2004 20:53:45 -0000	1.25
+++ dlls/winmm/tests/wave.c	27 May 2004 02:20:53 -0000
@@ -77,29 +77,29 @@
 
 const char* mmsys_error(MMRESULT error)
 {
-#define DEVTYPE_TO_STR(dev) case dev: return #dev
+#define ERR_TO_STR(dev) case dev: return #dev
     static char	unknown[32];
     switch (error) {
-    DEVTYPE_TO_STR(MMSYSERR_NOERROR);
-    DEVTYPE_TO_STR(MMSYSERR_ERROR);
-    DEVTYPE_TO_STR(MMSYSERR_BADDEVICEID);
-    DEVTYPE_TO_STR(MMSYSERR_NOTENABLED);
-    DEVTYPE_TO_STR(MMSYSERR_ALLOCATED);
-    DEVTYPE_TO_STR(MMSYSERR_INVALHANDLE);
-    DEVTYPE_TO_STR(MMSYSERR_NODRIVER);
-    DEVTYPE_TO_STR(MMSYSERR_NOMEM);
-    DEVTYPE_TO_STR(MMSYSERR_NOTSUPPORTED);
-    DEVTYPE_TO_STR(MMSYSERR_BADERRNUM);
-    DEVTYPE_TO_STR(MMSYSERR_INVALFLAG);
-    DEVTYPE_TO_STR(MMSYSERR_INVALPARAM);
-    DEVTYPE_TO_STR(WAVERR_BADFORMAT);
-    DEVTYPE_TO_STR(WAVERR_STILLPLAYING);
-    DEVTYPE_TO_STR(WAVERR_UNPREPARED);
-    DEVTYPE_TO_STR(WAVERR_SYNC);
-    } 
+    ERR_TO_STR(MMSYSERR_NOERROR);
+    ERR_TO_STR(MMSYSERR_ERROR);
+    ERR_TO_STR(MMSYSERR_BADDEVICEID);
+    ERR_TO_STR(MMSYSERR_NOTENABLED);
+    ERR_TO_STR(MMSYSERR_ALLOCATED);
+    ERR_TO_STR(MMSYSERR_INVALHANDLE);
+    ERR_TO_STR(MMSYSERR_NODRIVER);
+    ERR_TO_STR(MMSYSERR_NOMEM);
+    ERR_TO_STR(MMSYSERR_NOTSUPPORTED);
+    ERR_TO_STR(MMSYSERR_BADERRNUM);
+    ERR_TO_STR(MMSYSERR_INVALFLAG);
+    ERR_TO_STR(MMSYSERR_INVALPARAM);
+    ERR_TO_STR(WAVERR_BADFORMAT);
+    ERR_TO_STR(WAVERR_STILLPLAYING);
+    ERR_TO_STR(WAVERR_UNPREPARED);
+    ERR_TO_STR(WAVERR_SYNC);
+    }
     sprintf(unknown, "Unknown(0x%08x)", error);
     return unknown;
-#undef DEVTYPE_TO_STR
+#undef ERR_TO_STR
 }
 
 static const char * wave_out_error(MMRESULT error)
@@ -185,51 +185,57 @@
 #undef ADD_FLAG
 }
 
-static void wave_out_test_deviceOut(int device, double duration, int format, DWORD flags, LPWAVEOUTCAPS pcaps)
+static void wave_out_test_deviceOut(int device, double duration, LPWAVEFORMATEX pwfx, DWORD format, DWORD flags, LPWAVEOUTCAPS pcaps)
 {
-    WAVEFORMATEX wfx;
     HWAVEOUT wout;
     HANDLE hevent;
     WAVEHDR frag;
     MMRESULT rc;
     DWORD volume;
+    WORD nChannels = pwfx->nChannels;
+    WORD wBitsPerSample = pwfx->wBitsPerSample;
+    DWORD nSamplesPerSec = pwfx->nSamplesPerSec;
 
     hevent=CreateEvent(NULL,FALSE,FALSE,NULL);
     ok(hevent!=NULL,"CreateEvent: error=%ld\n",GetLastError());
     if (hevent==NULL)
         return;
 
-    wfx.wFormatTag=WAVE_FORMAT_PCM;
-    wfx.nChannels=win_formats[format][3];
-    wfx.wBitsPerSample=win_formats[format][2];
-    wfx.nSamplesPerSec=win_formats[format][1];
-    wfx.nBlockAlign=wfx.nChannels*wfx.wBitsPerSample/8;
-    wfx.nAvgBytesPerSec=wfx.nSamplesPerSec*wfx.nBlockAlign;
-    wfx.cbSize=0;
-
     wout=NULL;
-    rc=waveOutOpen(&wout,device,&wfx,(DWORD)hevent,0,CALLBACK_EVENT|flags);
+    rc=waveOutOpen(&wout,device,pwfx,(DWORD)hevent,0,CALLBACK_EVENT|flags);
     /* Note: Win9x doesn't know WAVE_FORMAT_DIRECT */
+    /* It is acceptable to fail on formats that are not specified to work */
     ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_BADDEVICEID ||
-       (rc==WAVERR_BADFORMAT && (flags & WAVE_FORMAT_DIRECT) && (pcaps->dwFormats & win_formats[format][0])) ||
+       ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
+       (flags & WAVE_FORMAT_DIRECT) && !(pcaps->dwFormats & format)) ||
+       ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
+       (!(flags & WAVE_FORMAT_DIRECT) || (flags & WAVE_MAPPED)) && !(pcaps->dwFormats & format)) ||
        (rc==MMSYSERR_INVALFLAG && (flags & WAVE_FORMAT_DIRECT)),
        "waveOutOpen: device=%d format=%ldx%2dx%d flags=%lx(%s) rc=%s\n",device,
-       wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,CALLBACK_EVENT|flags,
+       pwfx->nSamplesPerSec,pwfx->wBitsPerSample,pwfx->nChannels,CALLBACK_EVENT|flags,
        wave_open_flags(CALLBACK_EVENT|flags),wave_out_error(rc));
+    if ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
+       (flags & WAVE_FORMAT_DIRECT) && (pcaps->dwFormats & format))
+        trace(" Reason: The device lists this format as supported in it's capabilities but opening it failed.\n");
+    if ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
+       !(pcaps->dwFormats & format))
+        trace("waveOutOpen: device=%d format=%ldx%2dx%d %s rc=%s failed but format not supported so OK.\n",
+              device, pwfx->nSamplesPerSec,pwfx->wBitsPerSample,pwfx->nChannels,
+              flags & WAVE_FORMAT_DIRECT ? "flags=WAVE_FORMAT_DIRECT" :
+              flags & WAVE_MAPPED ? "flags=WAVE_MAPPED" : "", mmsys_error(rc));
     if (rc!=MMSYSERR_NOERROR) {
         CloseHandle(hevent);
         return;
     }
 
-    ok(wfx.nChannels==win_formats[format][3] &&
-       wfx.wBitsPerSample==win_formats[format][2] &&
-       wfx.nSamplesPerSec==win_formats[format][1],
-       "got the wrong format: %ldx%2dx%d instead of %dx%2dx%d\n",
-       wfx.nSamplesPerSec, wfx.wBitsPerSample,
-       wfx.nChannels, win_formats[format][1], win_formats[format][2],
-       win_formats[format][3]);
+    ok(pwfx->nChannels==nChannels &&
+       pwfx->wBitsPerSample==wBitsPerSample &&
+       pwfx->nSamplesPerSec==nSamplesPerSec,
+       "got the wrong format: %ldx%2dx%d instead of %ldx%2dx%d\n",
+       pwfx->nSamplesPerSec, pwfx->wBitsPerSample,
+       pwfx->nChannels, nSamplesPerSec, wBitsPerSample, nChannels);
 
-    frag.lpData=wave_generate_la(&wfx,duration,&frag.dwBufferLength);
+    frag.lpData=wave_generate_la(pwfx,duration,&frag.dwBufferLength);
     frag.dwFlags=0;
     frag.dwLoops=0;
 
@@ -241,8 +247,10 @@
        "waveOutPrepareHeader: device=%d rc=%s\n",device,wave_out_error(rc));
 
     if (winetest_interactive && rc==MMSYSERR_NOERROR) {
-        trace("Playing %g second 440Hz tone at %5ldx%2dx%d %04lx\n",duration,
-              wfx.nSamplesPerSec, wfx.wBitsPerSample,wfx.nChannels,flags);
+        trace("Playing %g second 440Hz tone at %5ldx%2dx%d %s\n",duration,
+              pwfx->nSamplesPerSec, pwfx->wBitsPerSample,pwfx->nChannels,
+              flags & WAVE_FORMAT_DIRECT ? "WAVE_FORMAT_DIRECT" :
+              flags & WAVE_MAPPED ? "WAVE_MAPPED" : "");
         rc=waveOutSetVolume(wout,0x20002000);
         ok(rc==MMSYSERR_NOERROR,"waveOutSetVolume: device=%d rc=%s\n",device,wave_out_error(rc));
         WaitForSingleObject(hevent,INFINITE);
@@ -261,7 +269,8 @@
     free(frag.lpData);
 
     CloseHandle(hevent);
-    waveOutClose(wout);
+    rc=waveOutClose(wout);
+    ok(rc==MMSYSERR_NOERROR,"waveOutClose: device=%d rc=%s\n",device,wave_out_error(rc));
 }
 
 static void wave_out_tests()
@@ -274,6 +283,14 @@
     WCHAR * wname;
     CHAR * name;
     DWORD size;
+    DWORD dwPageSize;
+    BYTE * twoPages;
+    SYSTEM_INFO sSysInfo;
+    DWORD flOldProtect;
+    BOOL res;
+
+    GetSystemInfo(&sSysInfo);
+    dwPageSize = sSysInfo.dwPageSize;
 
     ndev=waveOutGetNumDevs();
     trace("found %d WaveOut devices\n",ndev);
@@ -339,14 +356,48 @@
             trace("Playing a 5 seconds reference tone.\n");
             trace("All subsequent tones should be identical to this one.\n");
             trace("Listen for stutter, changes in pitch, volume, etc.\n");
-            wave_out_test_deviceOut(d,5.0,0,0,&caps);
+            format.wFormatTag=WAVE_FORMAT_PCM;
+            format.nChannels=1;
+            format.wBitsPerSample=8;
+            format.nSamplesPerSec=22050;
+            format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
+            format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
+            format.cbSize=0;
+            wave_out_test_deviceOut(d,5.0,&format,WAVE_FORMAT_2M08,0,&caps);
         }
 
         for (f=0;f<NB_WIN_FORMATS;f++) {
-            if (caps.dwFormats & win_formats[f][0]) {
-                wave_out_test_deviceOut(d,1.0,f,0,&caps);
-                wave_out_test_deviceOut(d,1.0,f,WAVE_FORMAT_DIRECT,&caps);
+            format.wFormatTag=WAVE_FORMAT_PCM;
+            format.nChannels=win_formats[f][3];
+            format.wBitsPerSample=win_formats[f][2];
+            format.nSamplesPerSec=win_formats[f][1];
+            format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
+            format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
+            format.cbSize=0;
+            wave_out_test_deviceOut(d,1.0,&format,win_formats[f][0],0,&caps);
+            wave_out_test_deviceOut(d,1.0,&format,win_formats[f][0],WAVE_FORMAT_DIRECT,&caps);
+            wave_out_test_deviceOut(d,1.0,&format,win_formats[f][0],WAVE_MAPPED,&caps);
+        }
+
+        /* Try a PCMWAVEFORMAT aligned next to an unaccessable page for bounds checking */
+        twoPages = VirtualAlloc(NULL, 2 * dwPageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
+        ok(twoPages!=NULL,"Failed to allocate 2 pages of memory\n");
+        if (twoPages) {
+            res = VirtualProtect(twoPages + dwPageSize, dwPageSize, PAGE_NOACCESS, &flOldProtect);
+            ok(res, "Failed to set memory access on second page\n");
+            if (res) {
+                LPWAVEFORMATEX pwfx = (LPWAVEFORMATEX)(twoPages + dwPageSize - sizeof(PCMWAVEFORMAT));
+                pwfx->wFormatTag=WAVE_FORMAT_PCM;
+                pwfx->nChannels=1;
+                pwfx->wBitsPerSample=8;
+                pwfx->nSamplesPerSec=22050;
+                pwfx->nBlockAlign=pwfx->nChannels*pwfx->wBitsPerSample/8;
+                pwfx->nAvgBytesPerSec=pwfx->nSamplesPerSec*pwfx->nBlockAlign;
+                wave_out_test_deviceOut(d,1.0,pwfx,WAVE_FORMAT_2M08,0,&caps);
+                wave_out_test_deviceOut(d,1.0,pwfx,WAVE_FORMAT_2M08,WAVE_FORMAT_DIRECT,&caps);
+                wave_out_test_deviceOut(d,1.0,pwfx,WAVE_FORMAT_2M08,WAVE_MAPPED,&caps);
             }
+            VirtualFree(twoPages, 2 * dwPageSize, MEM_RELEASE);
         }
 
         /* Try invalid formats to test error handling */
Index: dlls/winmm/tests/winmm_test.h
===================================================================
RCS file: /home/wine/wine/dlls/winmm/tests/winmm_test.h,v
retrieving revision 1.2
diff -u -r1.2 winmm_test.h
--- dlls/winmm/tests/winmm_test.h	21 May 2004 20:53:45 -0000	1.2
+++ dlls/winmm/tests/winmm_test.h	27 May 2004 02:20:53 -0000
@@ -28,6 +28,11 @@
 #endif
 
 static const unsigned int win_formats[][4] = {
+    {0,                  8000,  8, 1},
+    {0,                  8000,  8, 2},
+    {0,                  8000, 16, 1},
+    {0,                  8000, 16, 2},
+    {0,                 12000, 16, 2},
     {WAVE_FORMAT_1M08,  11025,  8, 1},
     {WAVE_FORMAT_1S08,  11025,  8, 2},
     {WAVE_FORMAT_1M16,  11025, 16, 1},


More information about the wine-patches mailing list