Do not free the header while unmapping the xxxx_UNPREPARE messages

Dmitry Timoshkov dmitry at baikal.ru
Wed Dec 25 09:53:26 CST 2002


Hello,

this patch is aimed to fix crashes in the old 16-bit game, which
calls waveOutUnprepareHeader16 for busy headers. MMDRV_Message
in that case returns WAVERR_STILLPLAYING, but it's not stopping
MMDRV_WaveOut_UnMap16To32A() from freeing the header. Slightly
later game calls waveOutReset16() which crashes. In that case
the duty of freeing the header should be moved to a higher level.
I have generalized this approach to all similar cases.

Changelog:
    Do not free the header while unmapping the xxxx_UNPREPARE messages,
    do it at the higher level API.

diff -u cvs/cw/crossover/office/wine/dlls/winmm/message16.c wine/dlls/winmm/message16.c
--- cvs/cw/crossover/office/wine/dlls/winmm/message16.c	Sat Nov  9 08:12:50 2002
+++ wine/dlls/winmm/message16.c	Wed Dec 25 23:14:34 2002
@@ -411,10 +411,6 @@
 	    if (mh16->reserved >= sizeof(MIDIHDR))
 		mh16->dwOffset = mh32->dwOffset;
 
-	    if (wMsg == MODM_UNPREPARE) {
-		HeapFree(GetProcessHeap(), 0, (LPSTR)mh32 - sizeof(LPMIDIHDR));
-		mh16->lpNext = 0;
-	    }
 	    ret = WINMM_MAP_OK;
 	}
 	break;
@@ -617,10 +613,6 @@
 	    mh32->dwUser = mh16->dwUser;
 	    mh32->dwFlags = mh16->dwFlags;
 
-	    if (wMsg == MODM_UNPREPARE) {
-                HeapFree( GetProcessHeap(), 0, ptr );
-		mh32->lpNext = 0;
-	    }
 	    ret = WINMM_MAP_OK;
 	}
 	break;
@@ -860,10 +852,6 @@
 	    wh16->dwFlags = wh32->dwFlags;
 	    wh16->dwLoops = wh32->dwLoops;
 
-	    if (wMsg == WIDM_UNPREPARE) {
-		HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
-		wh16->lpNext = 0;
-	    }
 	    ret = WINMM_MAP_OK;
 	}
 	break;
@@ -1089,10 +1077,6 @@
 	    wh32->dwLoops = wh16->dwLoops;
             UnMapLS( *lpParam1 );
 
-	    if (wMsg == WIDM_UNPREPARE) {
-                HeapFree( GetProcessHeap(), 0, ptr );
-		wh32->lpNext = 0;
-	    }
 	    ret = WINMM_MAP_OK;
 	}
 	break;
@@ -1369,10 +1353,6 @@
 	    wh16->dwFlags = wh32->dwFlags;
 	    wh16->dwLoops = wh32->dwLoops;
 
-	    if (wMsg == WODM_UNPREPARE) {
-		HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
-		wh16->lpNext = 0;
-	    }
 	    ret = WINMM_MAP_OK;
 	}
 	break;
@@ -1659,10 +1639,7 @@
 	    wh32->dwLoops = wh16->dwLoops;
 
             UnMapLS( *lpParam1 );
-	    if (wMsg == WODM_UNPREPARE) {
-                HeapFree( GetProcessHeap(), 0, ptr );
-		wh32->lpNext = 0;
-	    }
+
 	    ret = WINMM_MAP_OK;
 	}
 	break;
diff -u cvs/cw/crossover/office/wine/dlls/winmm/mmsystem.c wine/dlls/winmm/mmsystem.c
--- cvs/cw/crossover/office/wine/dlls/winmm/mmsystem.c	Sat Dec 21 14:03:30 2002
+++ wine/dlls/winmm/mmsystem.c	Wed Dec 25 23:29:58 2002
@@ -755,6 +755,7 @@
 				       SEGPTR lpsegMidiOutHdr,      /* [???] */
 				       UINT16 uSize)                /* [in] */
 {
+    UINT16 ret;
     LPWINE_MLD		wmld;
     LPMIDIHDR16		lpMidiOutHdr = MapSL(lpsegMidiOutHdr);
 
@@ -767,7 +768,14 @@
     if ((wmld = MMDRV_Get(HMIDIOUT_32(hMidiOut), MMDRV_MIDIOUT, FALSE)) == NULL)
 	return MMSYSERR_INVALHANDLE;
 
-    return MMDRV_Message(wmld, MODM_UNPREPARE, (DWORD)lpsegMidiOutHdr, uSize, FALSE);
+    ret = MMDRV_Message(wmld, MODM_UNPREPARE, (DWORD)lpsegMidiOutHdr, uSize, FALSE);
+
+    if (ret == MMSYSERR_NOERROR)
+    {
+	HeapFree(GetProcessHeap(), 0, (LPSTR)lpMidiOutHdr - sizeof(LPMIDIHDR));
+	lpMidiOutHdr->lpNext = 0;
+    }
+    return ret;
 }
 
 /**************************************************************************
@@ -970,6 +978,7 @@
                                       SEGPTR lpsegMidiInHdr,     /* [???] */
 				      UINT16 uSize)              /* [in] */
 {
+    UINT16 ret;
     LPWINE_MLD		wmld;
     LPMIDIHDR16		lpMidiInHdr = MapSL(lpsegMidiInHdr);
 
@@ -982,7 +991,14 @@
     if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, FALSE)) == NULL)
 	return MMSYSERR_INVALHANDLE;
 
-    return MMDRV_Message(wmld, MIDM_UNPREPARE, (DWORD)lpsegMidiInHdr, uSize, FALSE);
+    ret = MMDRV_Message(wmld, MIDM_UNPREPARE, (DWORD)lpsegMidiInHdr, uSize, FALSE);
+
+    if (ret == MMSYSERR_NOERROR)
+    {
+	HeapFree(GetProcessHeap(), 0, (LPSTR)lpMidiInHdr - sizeof(LPMIDIHDR));
+	lpMidiInHdr->lpNext = 0;
+    }
+    return ret;
 }
 
 /**************************************************************************
@@ -1273,6 +1289,7 @@
 				       SEGPTR lpsegWaveOutHdr,    /* [???] */
 				       UINT16 uSize)              /* [in] */
 {
+    UINT16 ret;
     LPWINE_MLD		wmld;
     LPWAVEHDR		lpWaveOutHdr = MapSL(lpsegWaveOutHdr);
 
@@ -1285,7 +1302,14 @@
     if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL)
 	return MMSYSERR_INVALHANDLE;
 
-    return MMDRV_Message(wmld, WODM_UNPREPARE, (DWORD)lpsegWaveOutHdr, uSize, FALSE);
+    ret = MMDRV_Message(wmld, WODM_UNPREPARE, (DWORD)lpsegWaveOutHdr, uSize, FALSE);
+    
+    if (ret == MMSYSERR_NOERROR)
+    {
+	HeapFree(GetProcessHeap(), 0, (LPSTR)lpWaveOutHdr - sizeof(LPWAVEHDR));
+	lpWaveOutHdr->lpNext = 0;
+    }
+    return ret;
 }
 
 /**************************************************************************
@@ -1570,6 +1594,7 @@
 				      SEGPTR lpsegWaveInHdr,   /* [???] */
 				      UINT16 uSize)            /* [in] */
 {
+    UINT16 ret;
     LPWINE_MLD		wmld;
     LPWAVEHDR		lpWaveInHdr = MapSL(lpsegWaveInHdr);
 
@@ -1584,7 +1609,14 @@
     if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL)
 	return MMSYSERR_INVALHANDLE;
 
-    return MMDRV_Message(wmld, WIDM_UNPREPARE, (DWORD)lpsegWaveInHdr, uSize, FALSE);
+    ret = MMDRV_Message(wmld, WIDM_UNPREPARE, (DWORD)lpsegWaveInHdr, uSize, FALSE);
+
+    if (ret == MMSYSERR_NOERROR)
+    {
+	HeapFree(GetProcessHeap(), 0, (LPSTR)lpWaveInHdr - sizeof(LPWAVEHDR));
+	lpWaveInHdr->lpNext = 0;
+    }
+    return ret;
 }
 
 /**************************************************************************
diff -u cvs/cw/crossover/office/wine/dlls/winmm/winmm.c wine/dlls/winmm/winmm.c
--- cvs/cw/crossover/office/wine/dlls/winmm/winmm.c	Sat Dec 21 14:03:30 2002
+++ wine/dlls/winmm/winmm.c	Wed Dec 25 23:30:35 2002
@@ -1119,6 +1119,7 @@
 UINT WINAPI midiOutUnprepareHeader(HMIDIOUT hMidiOut,
 				   MIDIHDR* lpMidiOutHdr, UINT uSize)
 {
+    UINT ret;
     LPWINE_MLD		wmld;
 
     TRACE("(%p, %p, %d)\n", hMidiOut, lpMidiOutHdr, uSize);
@@ -1130,7 +1131,14 @@
     if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
 	return MMSYSERR_INVALHANDLE;
 
-    return MMDRV_Message(wmld, MODM_UNPREPARE, (DWORD)lpMidiOutHdr, uSize, TRUE);
+    ret = MMDRV_Message(wmld, MODM_UNPREPARE, (DWORD)lpMidiOutHdr, uSize, TRUE);
+
+    if (ret == MMSYSERR_NOERROR)
+    {
+	HeapFree(GetProcessHeap(), 0, (LPSTR)lpMidiOutHdr - sizeof(LPMIDIHDR));
+	lpMidiOutHdr->lpNext = 0;
+    }
+    return ret;
 }
 
 /**************************************************************************
@@ -1425,6 +1433,7 @@
 UINT WINAPI midiInUnprepareHeader(HMIDIIN hMidiIn,
 				  MIDIHDR* lpMidiInHdr, UINT uSize)
 {
+    UINT ret;
     LPWINE_MLD		wmld;
 
     TRACE("(%p, %p, %d)\n", hMidiIn, lpMidiInHdr, uSize);
@@ -1436,7 +1445,14 @@
     if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
 	return MMSYSERR_INVALHANDLE;
 
-    return MMDRV_Message(wmld, MIDM_UNPREPARE, (DWORD)lpMidiInHdr, uSize, TRUE);
+    ret = MMDRV_Message(wmld, MIDM_UNPREPARE, (DWORD)lpMidiInHdr, uSize, TRUE);
+
+    if (ret == MMSYSERR_NOERROR)
+    {
+	HeapFree(GetProcessHeap(), 0, (LPSTR)lpMidiInHdr - sizeof(LPMIDIHDR));
+	lpMidiInHdr->lpNext = 0;
+    }
+    return ret;
 }
 
 /**************************************************************************
@@ -2358,6 +2374,7 @@
 UINT WINAPI waveOutUnprepareHeader(HWAVEOUT hWaveOut,
 				   LPWAVEHDR lpWaveOutHdr, UINT uSize)
 {
+    UINT ret;
     LPWINE_MLD		wmld;
 
     TRACE("(%p, %p, %u);\n", hWaveOut, lpWaveOutHdr, uSize);
@@ -2369,7 +2386,14 @@
     if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
 	return MMSYSERR_INVALHANDLE;
 
-    return MMDRV_Message(wmld, WODM_UNPREPARE, (DWORD)lpWaveOutHdr, uSize, TRUE);
+    ret = MMDRV_Message(wmld, WODM_UNPREPARE, (DWORD)lpWaveOutHdr, uSize, TRUE);
+
+    if (ret == MMSYSERR_NOERROR)
+    {
+	HeapFree(GetProcessHeap(), 0, (LPSTR)lpWaveOutHdr - sizeof(LPWAVEHDR));
+	lpWaveOutHdr->lpNext = 0;
+    }
+    return ret;
 }
 
 /**************************************************************************
@@ -2707,6 +2731,7 @@
 UINT WINAPI waveInUnprepareHeader(HWAVEIN hWaveIn, WAVEHDR* lpWaveInHdr,
 				  UINT uSize)
 {
+    UINT ret;
     LPWINE_MLD		wmld;
 
     TRACE("(%p, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
@@ -2719,7 +2744,14 @@
     if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
 	return MMSYSERR_INVALHANDLE;
 
-    return MMDRV_Message(wmld, WIDM_UNPREPARE, (DWORD)lpWaveInHdr, uSize, TRUE);
+    ret = MMDRV_Message(wmld, WIDM_UNPREPARE, (DWORD)lpWaveInHdr, uSize, TRUE);
+
+    if (ret == MMSYSERR_NOERROR)
+    {
+	HeapFree(GetProcessHeap(), 0, (LPSTR)lpWaveInHdr - sizeof(LPWAVEHDR));
+	lpWaveInHdr->lpNext = 0;
+    }
+    return ret;
 }
 
 /**************************************************************************







More information about the wine-patches mailing list