From 959ced4e3c65d3702043cd2cef1bd2f78e4174d8 Mon Sep 17 00:00:00 2001 From: Francois Gouget Date: Mon, 26 Oct 2009 09:28:38 +0100 Subject: [PATCH] mmsystem.dll16: Reorder the thread and time functions to avoid the need for forward declarations. --- dlls/mmsystem.dll16/mmsystem.c | 623 ++++++++++++++++++++--------------------- 1 file changed, 310 insertions(+), 313 deletions(-) diff --git a/dlls/mmsystem.dll16/mmsystem.c b/dlls/mmsystem.dll16/mmsystem.c index a7578e78e4c..b07629bd7b8 100644 --- a/dlls/mmsystem.dll16/mmsystem.c +++ b/dlls/mmsystem.dll16/mmsystem.c @@ -46,7 +46,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(mmsys); -static WINE_MMTHREAD* WINMM_GetmmThread(HANDLE16); static CRITICAL_SECTION_DEBUG mmdrv_critsect_debug = { @@ -86,6 +85,190 @@ int WINAPI MMSYSTEM_WEP(HINSTANCE16 hInstance, WORD wDataSeg, } /* ################################################### + * # TIME # + * ################################################### + */ + +/****************************************************************** + * MMSYSTEM_MMTIME32to16 + * + * + */ +void MMSYSTEM_MMTIME32to16(LPMMTIME16 mmt16, const MMTIME* mmt32) +{ + mmt16->wType = mmt32->wType; + /* layout of rest is the same for 32/16, + * Note: mmt16->u is 2 bytes smaller than mmt32->u, which has padding + */ + memcpy(&(mmt16->u), &(mmt32->u), sizeof(mmt16->u)); +} + +/****************************************************************** + * MMSYSTEM_MMTIME16to32 + * + * + */ +void MMSYSTEM_MMTIME16to32(LPMMTIME mmt32, const MMTIME16* mmt16) +{ + mmt32->wType = mmt16->wType; + /* layout of rest is the same for 32/16, + * Note: mmt16->u is 2 bytes smaller than mmt32->u, which has padding + */ + memcpy(&(mmt32->u), &(mmt16->u), sizeof(mmt16->u)); +} + +/************************************************************************** + * timeGetSystemTime [MMSYSTEM.601] + */ +MMRESULT16 WINAPI timeGetSystemTime16(LPMMTIME16 lpTime, UINT16 wSize) +{ + if (wSize >= sizeof(*lpTime)) { + lpTime->wType = TIME_MS; + lpTime->u.ms = GetTickCount(); + + TRACE("=> %u\n", lpTime->u.ms); + } + + return 0; +} + +struct timer_entry { + struct list entry; + UINT id; + LPTIMECALLBACK16 func16; + DWORD user; +}; + +static struct list timer_list = LIST_INIT(timer_list); + +static void CALLBACK timeCB3216(UINT id, UINT uMsg, DWORD_PTR user, DWORD_PTR dw1, DWORD_PTR dw2) +{ + struct timer_entry* te = (void*)user; + WORD args[8]; + DWORD ret; + + args[7] = LOWORD(id); + args[6] = LOWORD(uMsg); + args[5] = HIWORD(te->user); + args[4] = LOWORD(te->user); + args[3] = HIWORD(dw1); + args[2] = LOWORD(dw2); + args[1] = HIWORD(dw2); + args[0] = LOWORD(dw2); + WOWCallback16Ex((DWORD)te->func16, WCB16_PASCAL, sizeof(args), args, &ret); +} + +/************************************************************************** + * timeSetEvent [MMSYSTEM.602] + */ +MMRESULT16 WINAPI timeSetEvent16(UINT16 wDelay, UINT16 wResol, LPTIMECALLBACK16 lpFunc, + DWORD dwUser, UINT16 wFlags) +{ + MMRESULT16 id; + struct timer_entry* te; + + switch (wFlags & (TIME_CALLBACK_EVENT_SET|TIME_CALLBACK_EVENT_PULSE)) + { + case TIME_CALLBACK_EVENT_SET: + case TIME_CALLBACK_EVENT_PULSE: + id = timeSetEvent(wDelay, wResol, (LPTIMECALLBACK)lpFunc, dwUser, wFlags); + break; + case TIME_CALLBACK_FUNCTION: + te = HeapAlloc(GetProcessHeap(), 0, sizeof(*te)); + if (!te) return 0; + te->func16 = lpFunc; + te->user = dwUser; + id = te->id = timeSetEvent(wDelay, wResol, timeCB3216, (DWORD_PTR)te, wFlags); + if (id) + { + EnterCriticalSection(&mmdrv_cs); + list_add_tail(&timer_list, &te->entry); + LeaveCriticalSection(&mmdrv_cs); + } + else HeapFree(GetProcessHeap(), 0, te); + break; + default: + id = 0; + break; + } + return id; +} + +/************************************************************************** + * timeKillEvent [MMSYSTEM.603] + */ +MMRESULT16 WINAPI timeKillEvent16(UINT16 wID) +{ + MMRESULT16 ret = timeKillEvent(wID); + struct timer_entry* te; + + if (ret == TIMERR_NOERROR) + { + EnterCriticalSection(&mmdrv_cs); + LIST_FOR_EACH_ENTRY(te, &timer_list, struct timer_entry, entry) + { + if (wID == te->id) + { + list_remove(&te->entry); + HeapFree(GetProcessHeap(), 0, te); + break; + } + } + LeaveCriticalSection(&mmdrv_cs); + } + return ret; +} + +/************************************************************************** + * timeGetDevCaps [MMSYSTEM.604] + */ +MMRESULT16 WINAPI timeGetDevCaps16(LPTIMECAPS16 lpCaps, UINT16 wSize) +{ + TIMECAPS caps; + MMRESULT ret; + TRACE("(%p, %u) !\n", lpCaps, wSize); + + if (lpCaps == NULL) return MMSYSERR_INVALPARAM; + + ret = timeGetDevCaps(&caps, sizeof(caps)); + if (ret == MMSYSERR_NOERROR) { + TIMECAPS16 tc16; + tc16.wPeriodMin = caps.wPeriodMin; + tc16.wPeriodMax = caps.wPeriodMax; + memcpy(lpCaps, &tc16, min(wSize, sizeof(tc16))); + } + return ret; +} + +/************************************************************************** + * timeBeginPeriod [MMSYSTEM.605] + */ +MMRESULT16 WINAPI timeBeginPeriod16(UINT16 wPeriod) +{ + TRACE("(%u) !\n", wPeriod); + + return timeBeginPeriod(wPeriod); +} + +/************************************************************************** + * timeEndPeriod [MMSYSTEM.606] + */ +MMRESULT16 WINAPI timeEndPeriod16(UINT16 wPeriod) +{ + TRACE("(%u) !\n", wPeriod); + + return timeEndPeriod(wPeriod); +} + +/************************************************************************** + * timeGetTime [MMSYSTEM.607] + */ +DWORD WINAPI timeGetTime16(void) +{ + return timeGetTime(); +} + +/* ################################################### * # PlaySound # * ################################################### */ @@ -1684,8 +1867,6 @@ void WINAPI mmTaskYield16(void) } } -extern DWORD WINAPI GetProcessFlags(DWORD); - /****************************************************************** * WINMM_GetmmThread * @@ -1696,45 +1877,140 @@ static WINE_MMTHREAD* WINMM_GetmmThread(HANDLE16 h) return MapSL(MAKESEGPTR(h, 0)); } -DWORD WINAPI WINE_mmThreadEntryPoint(LPVOID); +static void MMSYSTEM_ThreadBlock(WINE_MMTHREAD* lpMMThd) +{ + MSG msg; + DWORD ret; + + if (lpMMThd->dwThreadID != GetCurrentThreadId()) + ERR("Not called by thread itself\n"); + + for (;;) { + ResetEvent(lpMMThd->hEvent); + if (InterlockedDecrement(&lpMMThd->dwSignalCount) >= 0) + break; + InterlockedIncrement(&lpMMThd->dwSignalCount); + + TRACE("S1\n"); + + ret = MsgWaitForMultipleObjects(1, &lpMMThd->hEvent, FALSE, INFINITE, QS_ALLINPUT); + switch (ret) { + case WAIT_OBJECT_0: /* Event */ + TRACE("S2.1\n"); + break; + case WAIT_OBJECT_0 + 1: /* Msg */ + TRACE("S2.2\n"); + if (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) { + TranslateMessage(&msg); + DispatchMessageA(&msg); + } + break; + default: + WARN("S2.x unsupported ret val 0x%08x\n", ret); + } + TRACE("S3\n"); + } +} /************************************************************************** - * mmThreadCreate [MMSYSTEM.1120] - * - * undocumented - * Creates a MM thread, calling fpThreadAddr(dwPmt). - * dwFlags: - * bit.0 set means create a 16 bit task instead of thread calling a 16 bit proc - * bit.1 set means to open a VxD for this thread (unsupported) + * mmThreadBlock [MMSYSTEM.1122] */ -LRESULT WINAPI mmThreadCreate16(FARPROC16 fpThreadAddr, LPHANDLE16 lpHndl, DWORD dwPmt, DWORD dwFlags) +void WINAPI mmThreadBlock16(HANDLE16 hndl) { - HANDLE16 hndl; - LRESULT ret; - - TRACE("(%p, %p, %08x, %08x)!\n", fpThreadAddr, lpHndl, dwPmt, dwFlags); - - hndl = GlobalAlloc16(sizeof(WINE_MMTHREAD), GMEM_SHARE|GMEM_ZEROINIT); + TRACE("(%04x)!\n", hndl); - if (hndl == 0) { - ret = 2; - } else { + if (hndl) { WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl); -#if 0 - /* force mmtask routines even if mmthread is required */ - /* this will work only if the patch about binary cmd line and NE tasks - * is committed - */ - dwFlags |= 1; -#endif + if (lpMMThd->hThread != 0) { + DWORD lc; - lpMMThd->dwSignature = WINE_MMTHREAD_CREATED; - lpMMThd->dwCounter = 0; - lpMMThd->hThread = 0; - lpMMThd->dwThreadID = 0; - lpMMThd->fpThread = (DWORD)fpThreadAddr; - lpMMThd->dwThreadPmt = dwPmt; + ReleaseThunkLock(&lc); + MMSYSTEM_ThreadBlock(lpMMThd); + RestoreThunkLock(lc); + } else { + mmTaskBlock16(lpMMThd->hTask); + } + } + TRACE("done\n"); +} + +/************************************************************************** + * __wine_mmThreadEntryPoint (MMSYSTEM.2047) + */ +DWORD WINAPI WINE_mmThreadEntryPoint(LPVOID p) +{ + HANDLE16 hndl = (HANDLE16)(DWORD_PTR)p; + WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl); + + TRACE("(%04x %p)\n", hndl, lpMMThd); + + lpMMThd->hTask = LOWORD(GetCurrentTask()); + TRACE("[10-%p] setting hTask to 0x%08x\n", lpMMThd->hThread, lpMMThd->hTask); + lpMMThd->dwStatus = 0x10; + MMSYSTEM_ThreadBlock(lpMMThd); + TRACE("[20-%p]\n", lpMMThd->hThread); + lpMMThd->dwStatus = 0x20; + if (lpMMThd->fpThread) { + WOWCallback16(lpMMThd->fpThread, lpMMThd->dwThreadPmt); + } + lpMMThd->dwStatus = 0x30; + TRACE("[30-%p]\n", lpMMThd->hThread); + while (lpMMThd->dwCounter) { + Sleep(1); + /* WOWYield16();*/ + } + TRACE("[XX-%p]\n", lpMMThd->hThread); + /* paranoia */ + lpMMThd->dwSignature = WINE_MMTHREAD_DELETED; + /* close lpMMThread->hVxD directIO */ + if (lpMMThd->hEvent) + CloseHandle(lpMMThd->hEvent); + GlobalFree16(hndl); + TRACE("done\n"); + + return 0; +} + +extern DWORD WINAPI GetProcessFlags(DWORD); + +/************************************************************************** + * mmThreadCreate [MMSYSTEM.1120] + * + * undocumented + * Creates a MM thread, calling fpThreadAddr(dwPmt). + * dwFlags: + * bit.0 set means create a 16 bit task instead of thread calling a 16 bit proc + * bit.1 set means to open a VxD for this thread (unsupported) + */ +LRESULT WINAPI mmThreadCreate16(FARPROC16 fpThreadAddr, LPHANDLE16 lpHndl, DWORD dwPmt, DWORD dwFlags) +{ + HANDLE16 hndl; + LRESULT ret; + + TRACE("(%p, %p, %08x, %08x)!\n", fpThreadAddr, lpHndl, dwPmt, dwFlags); + + hndl = GlobalAlloc16(sizeof(WINE_MMTHREAD), GMEM_SHARE|GMEM_ZEROINIT); + + if (hndl == 0) { + ret = 2; + } else { + WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl); + +#if 0 + /* force mmtask routines even if mmthread is required */ + /* this will work only if the patch about binary cmd line and NE tasks + * is committed + */ + dwFlags |= 1; +#endif + + lpMMThd->dwSignature = WINE_MMTHREAD_CREATED; + lpMMThd->dwCounter = 0; + lpMMThd->hThread = 0; + lpMMThd->dwThreadID = 0; + lpMMThd->fpThread = (DWORD)fpThreadAddr; + lpMMThd->dwThreadPmt = dwPmt; lpMMThd->dwSignalCount = 0; lpMMThd->hEvent = 0; lpMMThd->hVxD = 0; @@ -1821,64 +2097,6 @@ void WINAPI mmThreadSignal16(HANDLE16 hndl) } } -static void MMSYSTEM_ThreadBlock(WINE_MMTHREAD* lpMMThd) -{ - MSG msg; - DWORD ret; - - if (lpMMThd->dwThreadID != GetCurrentThreadId()) - ERR("Not called by thread itself\n"); - - for (;;) { - ResetEvent(lpMMThd->hEvent); - if (InterlockedDecrement(&lpMMThd->dwSignalCount) >= 0) - break; - InterlockedIncrement(&lpMMThd->dwSignalCount); - - TRACE("S1\n"); - - ret = MsgWaitForMultipleObjects(1, &lpMMThd->hEvent, FALSE, INFINITE, QS_ALLINPUT); - switch (ret) { - case WAIT_OBJECT_0: /* Event */ - TRACE("S2.1\n"); - break; - case WAIT_OBJECT_0 + 1: /* Msg */ - TRACE("S2.2\n"); - if (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessageA(&msg); - } - break; - default: - WARN("S2.x unsupported ret val 0x%08x\n", ret); - } - TRACE("S3\n"); - } -} - -/************************************************************************** - * mmThreadBlock [MMSYSTEM.1122] - */ -void WINAPI mmThreadBlock16(HANDLE16 hndl) -{ - TRACE("(%04x)!\n", hndl); - - if (hndl) { - WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl); - - if (lpMMThd->hThread != 0) { - DWORD lc; - - ReleaseThunkLock(&lc); - MMSYSTEM_ThreadBlock(lpMMThd); - RestoreThunkLock(lc); - } else { - mmTaskBlock16(lpMMThd->hTask); - } - } - TRACE("done\n"); -} - /************************************************************************** * mmThreadIsCurrent [MMSYSTEM.1123] */ @@ -1944,43 +2162,6 @@ HANDLE16 WINAPI mmThreadGetTask16(HANDLE16 hndl) return ret; } -/************************************************************************** - * __wine_mmThreadEntryPoint (MMSYSTEM.2047) - */ -DWORD WINAPI WINE_mmThreadEntryPoint(LPVOID p) -{ - HANDLE16 hndl = (HANDLE16)(DWORD_PTR)p; - WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl); - - TRACE("(%04x %p)\n", hndl, lpMMThd); - - lpMMThd->hTask = LOWORD(GetCurrentTask()); - TRACE("[10-%p] setting hTask to 0x%08x\n", lpMMThd->hThread, lpMMThd->hTask); - lpMMThd->dwStatus = 0x10; - MMSYSTEM_ThreadBlock(lpMMThd); - TRACE("[20-%p]\n", lpMMThd->hThread); - lpMMThd->dwStatus = 0x20; - if (lpMMThd->fpThread) { - WOWCallback16(lpMMThd->fpThread, lpMMThd->dwThreadPmt); - } - lpMMThd->dwStatus = 0x30; - TRACE("[30-%p]\n", lpMMThd->hThread); - while (lpMMThd->dwCounter) { - Sleep(1); - /* WOWYield16();*/ - } - TRACE("[XX-%p]\n", lpMMThd->hThread); - /* paranoia */ - lpMMThd->dwSignature = WINE_MMTHREAD_DELETED; - /* close lpMMThread->hVxD directIO */ - if (lpMMThd->hEvent) - CloseHandle(lpMMThd->hEvent); - GlobalFree16(hndl); - TRACE("done\n"); - - return 0; -} - typedef BOOL16 (WINAPI *MMCPLCALLBACK)(HWND, LPCSTR, LPCSTR, LPCSTR); /************************************************************************** @@ -2094,190 +2275,6 @@ LRESULT WINAPI DriverProc16(DWORD dwDevID, HDRVR16 hDrv, WORD wMsg, } /* ################################################### - * # TIME # - * ################################################### - */ - -/****************************************************************** - * MMSYSTEM_MMTIME32to16 - * - * - */ -void MMSYSTEM_MMTIME32to16(LPMMTIME16 mmt16, const MMTIME* mmt32) -{ - mmt16->wType = mmt32->wType; - /* layout of rest is the same for 32/16, - * Note: mmt16->u is 2 bytes smaller than mmt32->u, which has padding - */ - memcpy(&(mmt16->u), &(mmt32->u), sizeof(mmt16->u)); -} - -/****************************************************************** - * MMSYSTEM_MMTIME16to32 - * - * - */ -void MMSYSTEM_MMTIME16to32(LPMMTIME mmt32, const MMTIME16* mmt16) -{ - mmt32->wType = mmt16->wType; - /* layout of rest is the same for 32/16, - * Note: mmt16->u is 2 bytes smaller than mmt32->u, which has padding - */ - memcpy(&(mmt32->u), &(mmt16->u), sizeof(mmt16->u)); -} - -/************************************************************************** - * timeGetSystemTime [MMSYSTEM.601] - */ -MMRESULT16 WINAPI timeGetSystemTime16(LPMMTIME16 lpTime, UINT16 wSize) -{ - if (wSize >= sizeof(*lpTime)) { - lpTime->wType = TIME_MS; - lpTime->u.ms = GetTickCount(); - - TRACE("=> %u\n", lpTime->u.ms); - } - - return 0; -} - -struct timer_entry { - struct list entry; - UINT id; - LPTIMECALLBACK16 func16; - DWORD user; -}; - -static struct list timer_list = LIST_INIT(timer_list); - -static void CALLBACK timeCB3216(UINT id, UINT uMsg, DWORD_PTR user, DWORD_PTR dw1, DWORD_PTR dw2) -{ - struct timer_entry* te = (void*)user; - WORD args[8]; - DWORD ret; - - args[7] = LOWORD(id); - args[6] = LOWORD(uMsg); - args[5] = HIWORD(te->user); - args[4] = LOWORD(te->user); - args[3] = HIWORD(dw1); - args[2] = LOWORD(dw2); - args[1] = HIWORD(dw2); - args[0] = LOWORD(dw2); - WOWCallback16Ex((DWORD)te->func16, WCB16_PASCAL, sizeof(args), args, &ret); -} - -/************************************************************************** - * timeSetEvent [MMSYSTEM.602] - */ -MMRESULT16 WINAPI timeSetEvent16(UINT16 wDelay, UINT16 wResol, LPTIMECALLBACK16 lpFunc, - DWORD dwUser, UINT16 wFlags) -{ - MMRESULT16 id; - struct timer_entry* te; - - switch (wFlags & (TIME_CALLBACK_EVENT_SET|TIME_CALLBACK_EVENT_PULSE)) - { - case TIME_CALLBACK_EVENT_SET: - case TIME_CALLBACK_EVENT_PULSE: - id = timeSetEvent(wDelay, wResol, (LPTIMECALLBACK)lpFunc, dwUser, wFlags); - break; - case TIME_CALLBACK_FUNCTION: - te = HeapAlloc(GetProcessHeap(), 0, sizeof(*te)); - if (!te) return 0; - te->func16 = lpFunc; - te->user = dwUser; - id = te->id = timeSetEvent(wDelay, wResol, timeCB3216, (DWORD_PTR)te, wFlags); - if (id) - { - EnterCriticalSection(&mmdrv_cs); - list_add_tail(&timer_list, &te->entry); - LeaveCriticalSection(&mmdrv_cs); - } - else HeapFree(GetProcessHeap(), 0, te); - break; - default: - id = 0; - break; - } - return id; -} - -/************************************************************************** - * timeKillEvent [MMSYSTEM.603] - */ -MMRESULT16 WINAPI timeKillEvent16(UINT16 wID) -{ - MMRESULT16 ret = timeKillEvent(wID); - struct timer_entry* te; - - if (ret == TIMERR_NOERROR) - { - EnterCriticalSection(&mmdrv_cs); - LIST_FOR_EACH_ENTRY(te, &timer_list, struct timer_entry, entry) - { - if (wID == te->id) - { - list_remove(&te->entry); - HeapFree(GetProcessHeap(), 0, te); - break; - } - } - LeaveCriticalSection(&mmdrv_cs); - } - return ret; -} - -/************************************************************************** - * timeGetDevCaps [MMSYSTEM.604] - */ -MMRESULT16 WINAPI timeGetDevCaps16(LPTIMECAPS16 lpCaps, UINT16 wSize) -{ - TIMECAPS caps; - MMRESULT ret; - TRACE("(%p, %u) !\n", lpCaps, wSize); - - if (lpCaps == NULL) return MMSYSERR_INVALPARAM; - - ret = timeGetDevCaps(&caps, sizeof(caps)); - if (ret == MMSYSERR_NOERROR) { - TIMECAPS16 tc16; - tc16.wPeriodMin = caps.wPeriodMin; - tc16.wPeriodMax = caps.wPeriodMax; - memcpy(lpCaps, &tc16, min(wSize, sizeof(tc16))); - } - return ret; -} - -/************************************************************************** - * timeBeginPeriod [MMSYSTEM.605] - */ -MMRESULT16 WINAPI timeBeginPeriod16(UINT16 wPeriod) -{ - TRACE("(%u) !\n", wPeriod); - - return timeBeginPeriod(wPeriod); -} - -/************************************************************************** - * timeEndPeriod [MMSYSTEM.606] - */ -MMRESULT16 WINAPI timeEndPeriod16(UINT16 wPeriod) -{ - TRACE("(%u) !\n", wPeriod); - - return timeEndPeriod(wPeriod); -} - -/************************************************************************** - * timeGetTime [MMSYSTEM.607] - */ -DWORD WINAPI timeGetTime16(void) -{ - return timeGetTime(); -} - -/* ################################################### * # JOYSTICK # * ################################################### */ -- 2.11.4.GIT