Alexandre Julliard <julliard@winehq.org>
- Added rules for building import libraries in the individual dll
  makefiles, and added support for building a .def.a static import
  library too.
- Removed unnecessary code in the 16-bit DllEntryPoint function of some
  dlls, and also fixed its ordinal in a few places.
Mike McCormack <mike@codeweavers.com>
- Make WINMM_IData statically allocated.
- Make multimedia threads high priority.
Robert Reif <reif@earthlink.net>
- Change FIXME to WARN.
- Set thread priority for timer thread.
- Add timer thread priority test.
Modified: trunk/reactos/lib/winmm/Makefile.in
Modified: trunk/reactos/lib/winmm/mci.c
Modified: trunk/reactos/lib/winmm/mmio.c
Modified: trunk/reactos/lib/winmm/mmsystem.c
Modified: trunk/reactos/lib/winmm/mmsystem.spec
Modified: trunk/reactos/lib/winmm/playsound.c
Modified: trunk/reactos/lib/winmm/time.c
Modified: trunk/reactos/lib/winmm/winemm.h
Modified: trunk/reactos/lib/winmm/winmm.c

Modified: trunk/reactos/lib/winmm/Makefile.in
--- trunk/reactos/lib/winmm/Makefile.in	2005-05-28 22:00:46 UTC (rev 15628)
+++ trunk/reactos/lib/winmm/Makefile.in	2005-05-28 22:01:15 UTC (rev 15629)
@@ -4,6 +4,7 @@
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = winmm.dll
+IMPORTLIB = libwinmm.$(IMPLIBEXT)
 IMPORTS   = user32 advapi32 kernel32 ntdll
 EXTRALIBS = $(LIBUNICODE)
 

Modified: trunk/reactos/lib/winmm/mci.c
--- trunk/reactos/lib/winmm/mci.c	2005-05-28 22:00:46 UTC (rev 15628)
+++ trunk/reactos/lib/winmm/mci.c	2005-05-28 22:01:15 UTC (rev 15629)
@@ -104,12 +104,12 @@
 {
     LPWINE_MCIDRIVER	wmd = 0;
 
-    EnterCriticalSection(&WINMM_IData->cs);
-    for (wmd = WINMM_IData->lpMciDrvs; wmd; wmd = wmd->lpNext) {
+    EnterCriticalSection(&WINMM_IData.cs);
+    for (wmd = WINMM_IData.lpMciDrvs; wmd; wmd = wmd->lpNext) {
 	if (wmd->wDeviceID == wDevID)
 	    break;
     }
-    LeaveCriticalSection(&WINMM_IData->cs);
+    LeaveCriticalSection(&WINMM_IData.cs);
     return wmd;
 }
 
@@ -127,8 +127,8 @@
     if (!strcmpiW(lpstrName, wszAll))
 	return MCI_ALL_DEVICE_ID;
 
-    EnterCriticalSection(&WINMM_IData->cs);
-    for (wmd = WINMM_IData->lpMciDrvs; wmd; wmd = wmd->lpNext) {
+    EnterCriticalSection(&WINMM_IData.cs);
+    for (wmd = WINMM_IData.lpMciDrvs; wmd; wmd = wmd->lpNext) {
 	if (wmd->lpstrElementName && strcmpW(wmd->lpstrElementName, lpstrName) == 0) {
 	    ret = wmd->wDeviceID;
 	    break;
@@ -142,7 +142,7 @@
 	    break;
 	}
     }
-    LeaveCriticalSection(&WINMM_IData->cs);
+    LeaveCriticalSection(&WINMM_IData.cs);
 
     return ret;
 }
@@ -679,7 +679,7 @@
 
     /* well try to load id */
     if (uDevType >= MCI_DEVTYPE_FIRST && uDevType <= MCI_DEVTYPE_LAST) {
-	if (LoadStringW(WINMM_IData->hWinMM32Instance, uDevType, buf, sizeof(buf) / sizeof(WCHAR))) {
+	if (LoadStringW(WINMM_IData.hWinMM32Instance, uDevType, buf, sizeof(buf) / sizeof(WCHAR))) {
 	    str = buf;
 	}
     } else if (uDevType == 0) {
@@ -688,15 +688,15 @@
     }
     uTbl = MCI_NO_COMMAND_TABLE;
     if (str) {
-	HRSRC 	hRsrc = FindResourceW(WINMM_IData->hWinMM32Instance, str, (LPCWSTR)RT_RCDATA);
+	HRSRC 	hRsrc = FindResourceW(WINMM_IData.hWinMM32Instance, str, (LPCWSTR)RT_RCDATA);
 	HANDLE	hMem = 0;
 
-	if (hRsrc) hMem = LoadResource(WINMM_IData->hWinMM32Instance, hRsrc);
+	if (hRsrc) hMem = LoadResource(WINMM_IData.hWinMM32Instance, hRsrc);
 	if (hMem) {
 	    uTbl = MCI_SetCommandTable(LockResource(hMem), uDevType);
 	} else {
 	    WARN("No command table found in resource %p[%s]\n",
-		 WINMM_IData->hWinMM32Instance, debugstr_w(str));
+		 WINMM_IData.hWinMM32Instance, debugstr_w(str));
 	}
     }
     TRACE("=> %d\n", uTbl);
@@ -799,14 +799,14 @@
     if (wmd->dwPrivate != 0)
 	WARN("Unloading mci driver with non nul dwPrivate field\n");
 
-    EnterCriticalSection(&WINMM_IData->cs);
-    for (tmp = &WINMM_IData->lpMciDrvs; *tmp; tmp = &(*tmp)->lpNext) {
+    EnterCriticalSection(&WINMM_IData.cs);
+    for (tmp = &WINMM_IData.lpMciDrvs; *tmp; tmp = &(*tmp)->lpNext) {
 	if (*tmp == wmd) {
 	    *tmp = wmd->lpNext;
 	    break;
 	}
     }
-    LeaveCriticalSection(&WINMM_IData->cs);
+    LeaveCriticalSection(&WINMM_IData.cs);
 
     HeapFree(GetProcessHeap(), 0, wmd->lpstrDeviceType);
     HeapFree(GetProcessHeap(), 0, wmd->lpstrAlias);
@@ -871,12 +871,12 @@
     wmd->dwYieldData = VK_CANCEL;
     wmd->CreatorThread = GetCurrentThreadId();
 
-    EnterCriticalSection(&WINMM_IData->cs);
+    EnterCriticalSection(&WINMM_IData.cs);
     /* wmd must be inserted in list before sending opening the driver, coz' it
      * may want to lookup at wDevID
      */
-    wmd->lpNext = WINMM_IData->lpMciDrvs;
-    WINMM_IData->lpMciDrvs = wmd;
+    wmd->lpNext = WINMM_IData.lpMciDrvs;
+    WINMM_IData.lpMciDrvs = wmd;
 
     for (modp.wDeviceID = MCI_MAGIC;
 	 MCI_GetDriver(modp.wDeviceID) != 0;
@@ -884,7 +884,7 @@
 
     wmd->wDeviceID = modp.wDeviceID;
 
-    LeaveCriticalSection(&WINMM_IData->cs);
+    LeaveCriticalSection(&WINMM_IData.cs);
 
     TRACE("wDevID=%04X \n", modp.wDeviceID);
 
@@ -1195,7 +1195,7 @@
 	    case MCI_RESOURCE_RETURNED:
 		/* return string which ID is HIWORD(data[1]),
 		 * string is loaded from mmsystem.dll */
-		LoadStringW(WINMM_IData->hWinMM32Instance, HIWORD(data[1]),
+		LoadStringW(WINMM_IData.hWinMM32Instance, HIWORD(data[1]),
 			    lpstrRet, uRetLen);
 		break;
 	    case MCI_RESOURCE_RETURNED|MCI_RESOURCE_DRIVER:
@@ -1647,7 +1647,7 @@
 
 	    if (uDevType < MCI_DEVTYPE_FIRST ||
 		uDevType > MCI_DEVTYPE_LAST ||
-		!LoadStringW(WINMM_IData->hWinMM32Instance, uDevType, 
+		!LoadStringW(WINMM_IData.hWinMM32Instance, uDevType, 
                              strDevTyp, sizeof(strDevTyp) / sizeof(WCHAR))) {
 		dwRet = MCIERR_BAD_INTEGER;
 		goto errCleanUp;
@@ -1762,17 +1762,17 @@
     if (wDevID == MCI_ALL_DEVICE_ID) {
 	LPWINE_MCIDRIVER	next;
 
-	EnterCriticalSection(&WINMM_IData->cs);
+	EnterCriticalSection(&WINMM_IData.cs);
 	/* FIXME: shall I notify once after all is done, or for
 	 * each of the open drivers ? if the latest, which notif
 	 * to return when only one fails ?
 	 */
-	for (wmd = WINMM_IData->lpMciDrvs; wmd; ) {
+	for (wmd = WINMM_IData.lpMciDrvs; wmd; ) {
 	    next = wmd->lpNext;
 	    MCI_Close(wmd->wDeviceID, dwParam, lpParms);
 	    wmd = next;
 	}
-	LeaveCriticalSection(&WINMM_IData->cs);
+	LeaveCriticalSection(&WINMM_IData.cs);
 	return 0;
     }
 
@@ -1832,11 +1832,11 @@
 	if (lpParms->wDeviceType < MCI_DEVTYPE_FIRST || lpParms->wDeviceType > MCI_DEVTYPE_LAST) {
 	    if (dwFlags & MCI_SYSINFO_OPEN) {
 		TRACE("MCI_SYSINFO_QUANTITY: # of open MCI drivers\n");
-		EnterCriticalSection(&WINMM_IData->cs);
-		for (wmd = WINMM_IData->lpMciDrvs; wmd; wmd = wmd->lpNext) {
+		EnterCriticalSection(&WINMM_IData.cs);
+		for (wmd = WINMM_IData.lpMciDrvs; wmd; wmd = wmd->lpNext) {
 		    cnt++;
 		}
-		LeaveCriticalSection(&WINMM_IData->cs);
+		LeaveCriticalSection(&WINMM_IData.cs);
 	    } else {
 		TRACE("MCI_SYSINFO_QUANTITY: # of installed MCI drivers\n");
 		if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, wszHklmMci,
@@ -1850,11 +1850,11 @@
 	} else {
 	    if (dwFlags & MCI_SYSINFO_OPEN) {
 		TRACE("MCI_SYSINFO_QUANTITY: # of open MCI drivers of type %u\n", lpParms->wDeviceType);
-		EnterCriticalSection(&WINMM_IData->cs);
-		for (wmd = WINMM_IData->lpMciDrvs; wmd; wmd = wmd->lpNext) {
+		EnterCriticalSection(&WINMM_IData.cs);
+		for (wmd = WINMM_IData.lpMciDrvs; wmd; wmd = wmd->lpNext) {
 		    if (wmd->wType == lpParms->wDeviceType) cnt++;
 		}
-		LeaveCriticalSection(&WINMM_IData->cs);
+		LeaveCriticalSection(&WINMM_IData.cs);
 	    } else {
 		TRACE("MCI_SYSINFO_QUANTITY: # of installed MCI drivers of type %u\n", lpParms->wDeviceType);
 		FIXME("Don't know how to get # of MCI devices of a given type\n");
@@ -2135,7 +2135,7 @@
     if (lpstrBuffer != NULL && uLength > 0 &&
 	wError >= MCIERR_BASE && wError <= MCIERR_CUSTOM_DRIVER_BASE) {
 
-	if (LoadStringW(WINMM_IData->hWinMM32Instance,
+	if (LoadStringW(WINMM_IData.hWinMM32Instance,
 			wError, lpstrBuffer, uLength) > 0) {
 	    ret = TRUE;
 	}
@@ -2153,7 +2153,7 @@
     if (lpstrBuffer != NULL && uLength > 0 &&
 	dwError >= MCIERR_BASE && dwError <= MCIERR_CUSTOM_DRIVER_BASE) {
 
-	if (LoadStringA(WINMM_IData->hWinMM32Instance,
+	if (LoadStringA(WINMM_IData.hWinMM32Instance,
 			dwError, lpstrBuffer, uLength) > 0) {
 	    ret = TRUE;
 	}

Modified: trunk/reactos/lib/winmm/mmio.c
--- trunk/reactos/lib/winmm/mmio.c	2005-05-28 22:00:46 UTC (rev 15628)
+++ trunk/reactos/lib/winmm/mmio.c	2005-05-28 22:01:15 UTC (rev 15629)
@@ -440,12 +440,12 @@
 {
     LPWINE_MMIO		wm = NULL;
 
-    EnterCriticalSection(&WINMM_IData->cs);
-    for (wm = WINMM_IData->lpMMIO; wm; wm = wm->lpNext) {
+    EnterCriticalSection(&WINMM_IData.cs);
+    for (wm = WINMM_IData.lpMMIO; wm; wm = wm->lpNext) {
 	if (wm->info.hmmio == h)
 	    break;
     }
-    LeaveCriticalSection(&WINMM_IData->cs);
+    LeaveCriticalSection(&WINMM_IData.cs);
     return wm;
 }
 
@@ -461,13 +461,13 @@
 
     wm = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_MMIO));
     if (wm) {
-	EnterCriticalSection(&WINMM_IData->cs);
+	EnterCriticalSection(&WINMM_IData.cs);
         /* lookup next unallocated WORD handle, with a non NULL value */
 	while (++MMIO_counter == 0 || MMIO_Get((HMMIO)(ULONG_PTR)MMIO_counter));
 	wm->info.hmmio = (HMMIO)(ULONG_PTR)MMIO_counter;
-	wm->lpNext = WINMM_IData->lpMMIO;
-	WINMM_IData->lpMMIO = wm;
-	LeaveCriticalSection(&WINMM_IData->cs);
+	wm->lpNext = WINMM_IData.lpMMIO;
+	WINMM_IData.lpMMIO = wm;
+	LeaveCriticalSection(&WINMM_IData.cs);
     }
     return wm;
 }
@@ -481,9 +481,9 @@
 {
     LPWINE_MMIO*	m;
 
-    EnterCriticalSection(&WINMM_IData->cs);
+    EnterCriticalSection(&WINMM_IData.cs);
     /* search for the matching one... */
-    m = &(WINMM_IData->lpMMIO);
+    m = &(WINMM_IData.lpMMIO);
     while (*m && *m != wm) m = &(*m)->lpNext;
     /* ...and destroy */
     if (*m) {
@@ -491,7 +491,7 @@
 	HeapFree(GetProcessHeap(), 0, wm);
 	wm = NULL;
     }
-    LeaveCriticalSection(&WINMM_IData->cs);
+    LeaveCriticalSection(&WINMM_IData.cs);
     return wm ? FALSE : TRUE;
 }
 

Modified: trunk/reactos/lib/winmm/mmsystem.c
--- trunk/reactos/lib/winmm/mmsystem.c	2005-05-28 22:00:46 UTC (rev 15628)
+++ trunk/reactos/lib/winmm/mmsystem.c	2005-05-28 22:01:15 UTC (rev 15629)
@@ -59,7 +59,7 @@
  */
 
 /**************************************************************************
- * 			DllEntryPoint (MMSYSTEM.2046)
+ * 			DllEntryPoint (MMSYSTEM.4)
  *
  * MMSYSTEM DLL entry point
  *
@@ -74,12 +74,12 @@
 	/* need to load WinMM in order to:
 	 * - initiate correctly shared variables (WINMM_Init())
 	 */
-        if (!GetModuleHandleA("WINMM.DLL") && !LoadLibraryA("WINMM.DLL"))
+        if (!GetModuleHandleA("WINMM.DLL"))
         {
             ERR("Could not load sibling WinMM.dll\n");
             return FALSE;
 	}
-	WINMM_IData->hWinMM16Instance = hinstDLL;
+	WINMM_IData.hWinMM16Instance = hinstDLL;
         /* hook in our 16 bit function pointers */
         pFnGetMMThread16    = WINMM_GetmmThread;
         pFnOpenDriver16     = DRIVER_OpenDriver16;
@@ -91,7 +91,7 @@
         MMDRV_Init16();
 	break;
     case DLL_PROCESS_DETACH:
-	WINMM_IData->hWinMM16Instance = 0;
+	WINMM_IData.hWinMM16Instance = 0;
         pFnGetMMThread16    = NULL;
         pFnOpenDriver16     = NULL;
         pFnCloseDriver16    = NULL;
@@ -114,7 +114,7 @@
 int WINAPI MMSYSTEM_WEP(HINSTANCE16 hInstance, WORD wDataSeg,
                         WORD cbHeapSize, LPSTR lpCmdLine)
 {
-    FIXME("STUB: Unloading MMSystem DLL ... hInst=%04X \n", hInstance);
+    TRACE("STUB: Unloading MMSystem DLL ... hInst=%04X \n", hInstance);
     return TRUE;
 }
 
@@ -1946,6 +1946,7 @@
 		    CloseHandle(lpMMThd->hEvent);
 		ret = 2;
 	    } else {
+                SetThreadPriority(lpMMThd->hThread, THREAD_PRIORITY_TIME_CRITICAL);
 		TRACE("Got a nice thread hndl=%p id=0x%08lx\n", lpMMThd->hThread, lpMMThd->dwThreadID);
 		ret = 0;
 	    }

Modified: trunk/reactos/lib/winmm/mmsystem.spec
--- trunk/reactos/lib/winmm/mmsystem.spec	2005-05-28 22:00:46 UTC (rev 15628)
+++ trunk/reactos/lib/winmm/mmsystem.spec	2005-05-28 22:01:15 UTC (rev 15629)
@@ -1,6 +1,7 @@
-#1      pascal  MMSYSTEM_WEP(word word word ptr) MMSYSTEM_WEP
+1      pascal  WEP(word word word ptr) MMSYSTEM_WEP
 2      pascal  sndPlaySound(ptr word) sndPlaySound16
 3      pascal  PlaySound(ptr word long) PlaySound16
+4      pascal  DllEntryPoint(long word word word long word) MMSYSTEM_LibMain
 5      pascal  mmsystemGetVersion() mmsystemGetVersion16
 6      pascal  DriverProc(long word word long long) DriverProc16
 8      pascal  WMMMidiRunOnce() WMMMidiRunOnce16
@@ -171,6 +172,5 @@
 #2005   stub    MCIGETTHUNKTABLE
 #2006   stub    WINMMSL_THUNKDATA16
 
-2046   pascal  DllEntryPoint(long word word word long word) MMSYSTEM_LibMain
 # these are Wine only exported functions. Is there another way to do it ?
 2047   pascal  __wine_mmThreadEntryPoint(long) WINE_mmThreadEntryPoint

Modified: trunk/reactos/lib/winmm/playsound.c
--- trunk/reactos/lib/winmm/playsound.c	2005-05-28 22:00:46 UTC (rev 15628)
+++ trunk/reactos/lib/winmm/playsound.c	2005-05-28 22:01:15 UTC (rev 15629)
@@ -194,11 +194,11 @@
 {
     WINE_PLAYSOUND**    p;
 
-    EnterCriticalSection(&WINMM_IData->cs);
-    for (p = &WINMM_IData->lpPlaySound; *p && *p != wps; p = &((*p)->lpNext));
+    EnterCriticalSection(&WINMM_IData.cs);
+    for (p = &WINMM_IData.lpPlaySound; *p && *p != wps; p = &((*p)->lpNext));
     if (*p) *p = (*p)->lpNext;
-    if (WINMM_IData->lpPlaySound == NULL) SetEvent(WINMM_IData->psLastEvent);
-    LeaveCriticalSection(&WINMM_IData->cs);
+    if (WINMM_IData.lpPlaySound == NULL) SetEvent(WINMM_IData.psLastEvent);
+    LeaveCriticalSection(&WINMM_IData.cs);
     if (wps->bAlloc) HeapFree(GetProcessHeap(), 0, (void*)wps->pszSound);
     if (wps->hThread) CloseHandle(wps->hThread);
     HeapFree(GetProcessHeap(), 0, wps);
@@ -382,7 +382,7 @@
 	mmioSeek(hmmio, mmckInfo.dwDataOffset, SEEK_SET);
 	while (left)
         {
-	    if (WaitForSingleObject(WINMM_IData->psStopEvent, 0) == WAIT_OBJECT_0)
+	    if (WaitForSingleObject(WINMM_IData.psStopEvent, 0) == WAIT_OBJECT_0)
             {
 		wps->bLoop = FALSE;
 		break;
@@ -430,7 +430,7 @@
     /* FIXME? I see no difference between SND_NOWAIT and SND_NOSTOP !
      * there could be one if several sounds can be played at once...
      */
-    if ((fdwSound & (SND_NOWAIT | SND_NOSTOP)) && WINMM_IData->lpPlaySound != NULL)
+    if ((fdwSound & (SND_NOWAIT | SND_NOSTOP)) && WINMM_IData.lpPlaySound != NULL)
 	return FALSE;
 
     /* alloc internal structure, if we need to play something */
@@ -440,27 +440,27 @@
             return FALSE;
     }
 
-    EnterCriticalSection(&WINMM_IData->cs);
+    EnterCriticalSection(&WINMM_IData.cs);
     /* since several threads can enter PlaySound in parallel, we're not
      * sure, at this point, that another thread didn't start a new playsound
      */
-    while (WINMM_IData->lpPlaySound != NULL)
+    while (WINMM_IData.lpPlaySound != NULL)
     {
-        ResetEvent(WINMM_IData->psLastEvent);
+        ResetEvent(WINMM_IData.psLastEvent);
         /* FIXME: doc says we have to stop all instances of pszSound if it's non
          * NULL... as of today, we stop all playing instances */
-        SetEvent(WINMM_IData->psStopEvent);
+        SetEvent(WINMM_IData.psStopEvent);
 
-        LeaveCriticalSection(&WINMM_IData->cs);
-        WaitForSingleObject(WINMM_IData->psLastEvent, INFINITE);
-        EnterCriticalSection(&WINMM_IData->cs);
+        LeaveCriticalSection(&WINMM_IData.cs);
+        WaitForSingleObject(WINMM_IData.psLastEvent, INFINITE);
+        EnterCriticalSection(&WINMM_IData.cs);
 
-        ResetEvent(WINMM_IData->psStopEvent);
+        ResetEvent(WINMM_IData.psStopEvent);
     }
 
-    if (wps) wps->lpNext = WINMM_IData->lpPlaySound;
-    WINMM_IData->lpPlaySound = wps;
-    LeaveCriticalSection(&WINMM_IData->cs);
+    if (wps) wps->lpNext = WINMM_IData.lpPlaySound;
+    WINMM_IData.lpPlaySound = wps;
+    LeaveCriticalSection(&WINMM_IData.cs);
 
     if (!pszSound || (fdwSound & SND_PURGE)) return TRUE;
 
@@ -471,6 +471,7 @@
         wps->bLoop = (fdwSound & SND_LOOP) ? TRUE : FALSE;
         if ((handle = CreateThread(NULL, 0, proc_PlaySound, wps, 0, &id)) != 0) {
             wps->hThread = handle;
+            SetThreadPriority(handle, THREAD_PRIORITY_TIME_CRITICAL);
             return TRUE;
         }
     }

Modified: trunk/reactos/lib/winmm/time.c
--- trunk/reactos/lib/winmm/time.c	2005-05-28 22:00:46 UTC (rev 15628)
+++ trunk/reactos/lib/winmm/time.c	2005-05-28 22:01:15 UTC (rev 15629)
@@ -264,7 +264,8 @@
 	TIME_TimersList = NULL;
         TIME_hWakeEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
         TIME_TimeToDie = FALSE;
-	TIME_hMMTimer = CreateThread(NULL, 0, TIME_MMSysTimeThread, WINMM_IData, 0, NULL);
+	TIME_hMMTimer = CreateThread(NULL, 0, TIME_MMSysTimeThread, &WINMM_IData, 0, NULL);
+        SetThreadPriority(TIME_hMMTimer, THREAD_PRIORITY_TIME_CRITICAL);
     }
 }
 
@@ -334,7 +335,7 @@
     lpNewTimer->dwUser = dwUser;
     lpNewTimer->wFlags = wFlags;
 
-    EnterCriticalSection(&WINMM_IData->cs);
+    EnterCriticalSection(&WINMM_IData.cs);
 
     if ((wFlags & TIME_KILL_SYNCHRONOUS) && !TIME_hKillEvent)
         TIME_hKillEvent = CreateEventW(NULL, TRUE, TRUE, NULL);
@@ -347,7 +348,7 @@
     TIME_TimersList = lpNewTimer;
     lpNewTimer->wTimerID = wNewID + 1;
 
-    LeaveCriticalSection(&WINMM_IData->cs);
+    LeaveCriticalSection(&WINMM_IData.cs);
 
     /* Wake the service thread in case there is work to be done */
     SetEvent(TIME_hWakeEvent);
@@ -378,7 +379,7 @@
     LPWINE_TIMERENTRY   lpSelf = NULL, *lpTimer;
 
     TRACE("(%u)\n", wID);
-    EnterCriticalSection(&WINMM_IData->cs);
+    EnterCriticalSection(&WINMM_IData.cs);
     /* remove WINE_TIMERENTRY from list */
     for (lpTimer = &TIME_TimersList; *lpTimer; lpTimer = &(*lpTimer)->lpNext) {
 	if (wID == (*lpTimer)->wTimerID) {
@@ -388,7 +389,7 @@
 	    break;
 	}
     }
-    LeaveCriticalSection(&WINMM_IData->cs);
+    LeaveCriticalSection(&WINMM_IData.cs);
 
     if (!lpSelf)
     {
@@ -433,7 +434,7 @@
 
     if (wPeriod > MMSYSTIME_MININTERVAL)
     {
-        FIXME("Stub; we set our timer resolution at minimum\n");
+        WARN("Stub; we set our timer resolution at minimum\n");
     }
 
     return 0;
@@ -449,7 +450,7 @@
 
     if (wPeriod > MMSYSTIME_MININTERVAL)
     {
-        FIXME("Stub; we set our timer resolution at minimum\n");
+        WARN("Stub; we set our timer resolution at minimum\n");
     }
     return 0;
 }

Modified: trunk/reactos/lib/winmm/winemm.h
--- trunk/reactos/lib/winmm/winemm.h	2005-05-28 22:00:46 UTC (rev 15628)
+++ trunk/reactos/lib/winmm/winemm.h	2005-05-28 22:01:15 UTC (rev 15629)
@@ -292,7 +292,7 @@
 void		TIME_MMTimeStop(void);
 
 /* Global variables */
-extern LPWINE_MM_IDATA  WINMM_IData;
+extern WINE_MM_IDATA  WINMM_IData;
 
 /* pointers to 16 bit functions (if sibling MMSYSTEM.DLL is loaded
  * NULL otherwise

Modified: trunk/reactos/lib/winmm/winmm.c
--- trunk/reactos/lib/winmm/winmm.c	2005-05-28 22:00:46 UTC (rev 15628)
+++ trunk/reactos/lib/winmm/winmm.c	2005-05-28 22:01:15 UTC (rev 15629)
@@ -65,25 +65,23 @@
  *                   G L O B A L   S E T T I N G S
  * ========================================================================*/
 
-LPWINE_MM_IDATA		WINMM_IData /* = NULL */;
+WINE_MM_IDATA WINMM_IData;
 
 /**************************************************************************
  * 			WINMM_CreateIData			[internal]
  */
 static	BOOL	WINMM_CreateIData(HINSTANCE hInstDLL)
 {
-    WINMM_IData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_MM_IDATA));
+    memset( &WINMM_IData, 0, sizeof WINMM_IData );
 
-    if (!WINMM_IData)
-	return FALSE;
-    WINMM_IData->hWinMM32Instance = hInstDLL;
-    InitializeCriticalSection(&WINMM_IData->cs);
+    WINMM_IData.hWinMM32Instance = hInstDLL;
+    InitializeCriticalSection(&WINMM_IData.cs);
 /* FIXME crashes in ReactOS
-    WINMM_IData->cs.DebugInfo->Spare[1] = (DWORD)"WINMM_IData";
+    WINMM_IData.cs.DebugInfo->Spare[1] = (DWORD)"WINMM_IData";
 */
-    WINMM_IData->psStopEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
-    WINMM_IData->psLastEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
-    TRACE("Created IData (%p)\n", WINMM_IData);
+    WINMM_IData.psStopEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
+    WINMM_IData.psLastEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
+    TRACE("Initialized IData (%p)\n", &WINMM_IData);
     return TRUE;
 }
 
@@ -92,17 +90,13 @@
  */
 static	void WINMM_DeleteIData(void)
 {
-    if (WINMM_IData) {
-	TIME_MMTimeStop();
+    TIME_MMTimeStop();
 
-	/* FIXME: should also free content and resources allocated
-	 * inside WINMM_IData */
-        CloseHandle(WINMM_IData->psStopEvent);
-        CloseHandle(WINMM_IData->psLastEvent);
-        DeleteCriticalSection(&WINMM_IData->cs);
-        HeapFree(GetProcessHeap(), 0, WINMM_IData);
-        WINMM_IData = NULL;
-    }
+    /* FIXME: should also free content and resources allocated
+     * inside WINMM_IData */
+    CloseHandle(WINMM_IData.psStopEvent);
+    CloseHandle(WINMM_IData.psLastEvent);
+    DeleteCriticalSection(&WINMM_IData.cs);
 }
 
 /******************************************************************
@@ -867,7 +861,7 @@
 		* a warning for the test was always true */
 	       (/*uError >= MMSYSERR_BASE && */ uError <= MMSYSERR_LASTERROR) ||
 	       (uError >= MIDIERR_BASE  && uError <= MIDIERR_LASTERROR)) {
-	if (LoadStringW(WINMM_IData->hWinMM32Instance,
+	if (LoadStringW(WINMM_IData.hWinMM32Instance,
 			uError, lpText, uSize) > 0) {
 	    ret = MMSYSERR_NOERROR;
 	}
@@ -1796,6 +1790,7 @@
 	midiStreamClose((HMIDISTRM)hMidiOut);
 	return MMSYSERR_NOMEM;
     }
+    SetThreadPriority(lpMidiStrm->hThread, THREAD_PRIORITY_TIME_CRITICAL);
 
     /* wait for thread to have started, and for its queue to be created */
     {
@@ -2177,7 +2172,7 @@
 		* a warning for the test was always true */
 	       (/*uError >= MMSYSERR_BASE && */ uError <= MMSYSERR_LASTERROR) ||
 	       (uError >= WAVERR_BASE  && uError <= WAVERR_LASTERROR)) {
-	if (LoadStringW(WINMM_IData->hWinMM32Instance,
+	if (LoadStringW(WINMM_IData.hWinMM32Instance,
 			uError, lpText, uSize) > 0) {
 	    ret = MMSYSERR_NOERROR;
 	}
@@ -2807,6 +2802,7 @@
         if (hEvent) CloseHandle(hEvent);
         return TASKERR_OUTOFMEMORY;
     }
+    SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL);
     if (ph) *ph = hEvent;
     CloseHandle(hThread);
     return 0;