diff --git a/reactos/dll/win32/mciqtz32/mciqtz.c b/reactos/dll/win32/mciqtz32/mciqtz.c index 44712515a2f..3269c0c5b26 100644 --- a/reactos/dll/win32/mciqtz32/mciqtz.c +++ b/reactos/dll/win32/mciqtz32/mciqtz.c @@ -33,7 +33,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(mciqtz); -static DWORD MCIQTZ_mciClose(UINT, DWORD, LPMCI_GENERIC_PARMS); +static DWORD CALLBACK MCIQTZ_taskThread(LPVOID arg); static DWORD MCIQTZ_mciStop(UINT, DWORD, LPMCI_GENERIC_PARMS); /*======================================================================* @@ -70,6 +70,40 @@ static WINE_MCIQTZ* MCIQTZ_mciGetOpenDev(UINT wDevID) return wma; } +/*************************************************************************** + * MCIQTZ_relayTaskMessage [internal] + */ +static LRESULT MCIQTZ_relayTaskMessage(DWORD_PTR dwDevID, UINT wMsg, + DWORD dwFlags, LPARAM lpParms) +{ + WINE_MCIQTZ *wma; + LRESULT res; + HANDLE handles[2]; + DWORD ret; + TRACE("(%08lX, %08x, %08x, %08lx)\n", dwDevID, wMsg, dwFlags, lpParms); + + wma = MCIQTZ_mciGetOpenDev(dwDevID); + if (!wma) + return MCIERR_INVALID_DEVICE_ID; + EnterCriticalSection(&wma->cs); + wma->task.devid = dwDevID; + wma->task.msg = wMsg; + wma->task.flags = dwFlags; + wma->task.parms = lpParms; + SetEvent(wma->task.notify); + handles[0] = wma->task.done; + handles[1] = wma->task.thread; + ret = WaitForMultipleObjects(sizeof(handles)/sizeof(handles[0]), handles, + FALSE, INFINITE); + if (ret == WAIT_OBJECT_0) + res = wma->task.res; + else + res = MCIERR_INTERNAL; + LeaveCriticalSection(&wma->cs); + + return res; +} + /************************************************************************** * MCIQTZ_drvOpen [internal] */ @@ -88,12 +122,26 @@ static DWORD MCIQTZ_drvOpen(LPCWSTR str, LPMCI_OPEN_DRIVER_PARMSW modp) if (!wma) return 0; + wma->stop_event = CreateEventW(NULL, FALSE, FALSE, NULL); + wma->task.notify = CreateEventW(NULL, FALSE, FALSE, NULL); + if (!wma->task.notify) goto err; + wma->task.done = CreateEventW(NULL, FALSE, FALSE, NULL); + if (!wma->task.done) goto err; + wma->task.thread = CreateThread(NULL, 0, MCIQTZ_taskThread, &wma->task, 0, NULL); + if (!wma->task.thread) goto err; + InitializeCriticalSection(&wma->cs); + wma->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": WINE_MCIQTZ"); modp->wType = MCI_DEVTYPE_DIGITAL_VIDEO; wma->wDevID = modp->wDeviceID; modp->wCustomCommandTable = wma->command_table = mciLoadCommandResource(MCIQTZ_hInstance, mciAviWStr, 0); mciSetDriverData(wma->wDevID, (DWORD_PTR)wma); return modp->wDeviceID; +err: + if (wma->task.notify) CloseHandle(wma->task.notify); + if (wma->task.done) CloseHandle(wma->task.done); + HeapFree(GetProcessHeap(), 0, wma); + return 0; } /************************************************************************** @@ -109,10 +157,17 @@ static DWORD MCIQTZ_drvClose(DWORD dwDevID) if (wma) { /* finish all outstanding things */ - MCIQTZ_mciClose(dwDevID, MCI_WAIT, NULL); + MCIQTZ_relayTaskMessage(dwDevID, MCI_CLOSE_DRIVER, MCI_WAIT, 0); mciFreeCommandResource(wma->command_table); + MCIQTZ_relayTaskMessage(dwDevID, MCI_CLOSE, MCI_WAIT, 0); + WaitForSingleObject(wma->task.thread, INFINITE); + CloseHandle(wma->task.notify); + CloseHandle(wma->task.done); + CloseHandle(wma->task.thread); + DeleteCriticalSection(&wma->cs); mciSetDriverData(dwDevID, 0); + CloseHandle(wma->stop_event); HeapFree(GetProcessHeap(), 0, wma); return 1; } @@ -140,6 +195,20 @@ static DWORD MCIQTZ_drvConfigure(DWORD dwDevID) return 1; } +/************************************************************************** + * MCIQTZ_mciNotify [internal] + * + * Notifications in MCI work like a 1-element queue. + * Each new notification request supersedes the previous one. + */ +static void MCIQTZ_mciNotify(DWORD_PTR hWndCallBack, WINE_MCIQTZ* wma, UINT wStatus) +{ + MCIDEVICEID wDevID = wma->notify_devid; + HANDLE old = InterlockedExchangePointer(&wma->callback, NULL); + if (old) mciDriverNotify(old, wDevID, MCI_NOTIFY_SUPERSEDED); + mciDriverNotify(HWND_32(LOWORD(hWndCallBack)), wDevID, wStatus); +} + /*************************************************************************** * MCIQTZ_mciOpen [internal] */ @@ -153,9 +222,6 @@ static DWORD MCIQTZ_mciOpen(UINT wDevID, DWORD dwFlags, TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpOpenParms); - if (!lpOpenParms) - return MCIERR_NULL_PARAMETER_BLOCK; - wma = MCIQTZ_mciGetOpenDev(wDevID); if (!wma) return MCIERR_INVALID_DEVICE_ID; @@ -201,6 +267,12 @@ static DWORD MCIQTZ_mciOpen(UINT wDevID, DWORD dwFlags, goto err; } + hr = IGraphBuilder_QueryInterface(wma->pgraph, &IID_IBasicAudio, (void**)&wma->audio); + if (FAILED(hr)) { + TRACE("Cannot get IBasicAudio interface (hr = %x)\n", hr); + goto err; + } + if (!(dwFlags & MCI_OPEN_ELEMENT) || (dwFlags & MCI_OPEN_ELEMENT_ID)) { TRACE("Wrong dwFlags %x\n", dwFlags); goto err; @@ -243,6 +315,9 @@ static DWORD MCIQTZ_mciOpen(UINT wDevID, DWORD dwFlags, return 0; err: + if (wma->audio) + IBasicAudio_Release(wma->audio); + wma->audio = NULL; if (wma->vidbasic) IBasicVideo_Release(wma->vidbasic); wma->vidbasic = NULL; @@ -287,6 +362,7 @@ static DWORD MCIQTZ_mciClose(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpP if (wma->opened) { IVideoWindow_Release(wma->vidwin); IBasicVideo_Release(wma->vidbasic); + IBasicAudio_Release(wma->audio); IMediaSeeking_Release(wma->seek); IMediaEvent_Release(wma->mevent); IGraphBuilder_Release(wma->pgraph); @@ -299,6 +375,63 @@ static DWORD MCIQTZ_mciClose(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpP return 0; } +/*************************************************************************** + * MCIQTZ_notifyThread [internal] + */ +static DWORD CALLBACK MCIQTZ_notifyThread(LPVOID parm) +{ + WINE_MCIQTZ* wma = (WINE_MCIQTZ *)parm; + HRESULT hr; + HANDLE handle[2]; + DWORD n = 0, ret = 0; + + handle[n++] = wma->stop_event; + IMediaEvent_GetEventHandle(wma->mevent, (OAEVENT *)&handle[n++]); + + for (;;) { + DWORD r; + HANDLE old; + + r = WaitForMultipleObjects(n, handle, FALSE, INFINITE); + if (r == WAIT_OBJECT_0) { + TRACE("got stop event\n"); + old = InterlockedExchangePointer(&wma->callback, NULL); + if (old) + mciDriverNotify(old, wma->notify_devid, MCI_NOTIFY_ABORTED); + break; + } + else if (r == WAIT_OBJECT_0+1) { + LONG event_code; + LONG_PTR p1, p2; + do { + hr = IMediaEvent_GetEvent(wma->mevent, &event_code, &p1, &p2, 0); + if (SUCCEEDED(hr)) { + TRACE("got event_code = 0x%02x\n", event_code); + IMediaEvent_FreeEventParams(wma->mevent, event_code, p1, p2); + } + } while (hr == S_OK && event_code != EC_COMPLETE); + if (hr == S_OK && event_code == EC_COMPLETE) { + old = InterlockedExchangePointer(&wma->callback, NULL); + if (old) + mciDriverNotify(old, wma->notify_devid, MCI_NOTIFY_SUCCESSFUL); + break; + } + } + else { + TRACE("Unknown error (%d)\n", (int)r); + break; + } + } + + hr = IMediaControl_Stop(wma->pmctrl); + if (FAILED(hr)) { + TRACE("Cannot stop filtergraph (hr = %x)\n", hr); + ret = MCIERR_INTERNAL; + } + + return ret; +} + /*************************************************************************** * MCIQTZ_mciPlay [internal] */ @@ -312,13 +445,18 @@ static DWORD MCIQTZ_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms); - if (!lpParms) - return MCIERR_NULL_PARAMETER_BLOCK; - wma = MCIQTZ_mciGetOpenDev(wDevID); if (!wma) return MCIERR_INVALID_DEVICE_ID; + ResetEvent(wma->stop_event); + if (dwFlags & MCI_NOTIFY) { + HANDLE old; + old = InterlockedExchangePointer(&wma->callback, HWND_32(LOWORD(lpParms->dwCallback))); + if (old) + mciDriverNotify(old, wma->notify_devid, MCI_NOTIFY_ABORTED); + } + IMediaSeeking_GetTimeFormat(wma->seek, &format); if (dwFlags & MCI_FROM) { if (IsEqualGUID(&format, &TIME_FORMAT_MEDIA_TIME)) @@ -345,8 +483,11 @@ static DWORD MCIQTZ_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms IVideoWindow_put_Visible(wma->vidwin, OATRUE); - if (dwFlags & MCI_NOTIFY) - mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)), wDevID, MCI_NOTIFY_SUCCESSFUL); + wma->thread = CreateThread(NULL, 0, MCIQTZ_notifyThread, wma, 0, NULL); + if (!wma->thread) { + TRACE("Can't create thread\n"); + return MCIERR_INTERNAL; + } return 0; } @@ -361,9 +502,6 @@ static DWORD MCIQTZ_mciSeek(UINT wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms); - if (!lpParms) - return MCIERR_NULL_PARAMETER_BLOCK; - wma = MCIQTZ_mciGetOpenDev(wDevID); if (!wma) return MCIERR_INVALID_DEVICE_ID; @@ -390,7 +528,7 @@ static DWORD MCIQTZ_mciSeek(UINT wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms } if (dwFlags & MCI_NOTIFY) - mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)), wDevID, MCI_NOTIFY_SUCCESSFUL); + MCIQTZ_mciNotify(lpParms->dwCallback, wma, MCI_NOTIFY_SUCCESSFUL); return 0; } @@ -401,7 +539,6 @@ static DWORD MCIQTZ_mciSeek(UINT wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms static DWORD MCIQTZ_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms) { WINE_MCIQTZ* wma; - HRESULT hr; TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms); @@ -412,10 +549,11 @@ static DWORD MCIQTZ_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpPa if (!wma->opened) return 0; - hr = IMediaControl_Stop(wma->pmctrl); - if (FAILED(hr)) { - TRACE("Cannot stop filtergraph (hr = %x)\n", hr); - return MCIERR_INTERNAL; + if (wma->thread) { + SetEvent(wma->stop_event); + WaitForSingleObject(wma->thread, INFINITE); + CloseHandle(wma->thread); + wma->thread = NULL; } if (!wma->parent) @@ -456,9 +594,6 @@ static DWORD MCIQTZ_mciGetDevCaps(UINT wDevID, DWORD dwFlags, LPMCI_GETDEVCAPS_P TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms); - if (!lpParms) - return MCIERR_NULL_PARAMETER_BLOCK; - wma = MCIQTZ_mciGetOpenDev(wDevID); if (!wma) return MCIERR_INVALID_DEVICE_ID; @@ -555,9 +690,6 @@ static DWORD MCIQTZ_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SET_PARMS lpPar TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms); - if (!lpParms) - return MCIERR_NULL_PARAMETER_BLOCK; - wma = MCIQTZ_mciGetOpenDev(wDevID); if (!wma) return MCIERR_INVALID_DEVICE_ID; @@ -612,9 +744,6 @@ static DWORD MCIQTZ_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STATUS_PARMS TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms); - if (!lpParms) - return MCIERR_NULL_PARAMETER_BLOCK; - wma = MCIQTZ_mciGetOpenDev(wDevID); if (!wma) return MCIERR_INVALID_DEVICE_ID; @@ -669,19 +798,9 @@ static DWORD MCIQTZ_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STATUS_PARMS if (state == State_Stopped) lpParms->dwReturn = MAKEMCIRESOURCE(MCI_MODE_STOP, MCI_MODE_STOP); else if (state == State_Running) { - LONG code; - LONG_PTR p1, p2; - lpParms->dwReturn = MAKEMCIRESOURCE(MCI_MODE_PLAY, MCI_MODE_PLAY); - - do { - hr = IMediaEvent_GetEvent(wma->mevent, &code, &p1, &p2, 0); - if (hr == S_OK && code == EC_COMPLETE){ - lpParms->dwReturn = MAKEMCIRESOURCE(MCI_MODE_STOP, MCI_MODE_STOP); - IMediaControl_Stop(wma->pmctrl); - } - } while (hr == S_OK); - + if (!wma->thread || WaitForSingleObject(wma->thread, 0) == WAIT_OBJECT_0) + lpParms->dwReturn = MAKEMCIRESOURCE(MCI_MODE_STOP, MCI_MODE_STOP); } else if (state == State_Paused) lpParms->dwReturn = MAKEMCIRESOURCE(MCI_MODE_PAUSE, MCI_MODE_PAUSE); ret = MCI_RESOURCE_RETURNED; @@ -707,7 +826,7 @@ static DWORD MCIQTZ_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STATUS_PARMS } if (dwFlags & MCI_NOTIFY) - mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)), wDevID, MCI_NOTIFY_SUCCESSFUL); + MCIQTZ_mciNotify(lpParms->dwCallback, wma, MCI_NOTIFY_SUCCESSFUL); return ret; } @@ -725,9 +844,6 @@ static DWORD MCIQTZ_mciWhere(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RECT_PARMS lp TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms); - if (!lpParms) - return MCIERR_NULL_PARAMETER_BLOCK; - wma = MCIQTZ_mciGetOpenDev(wDevID); if (!wma) return MCIERR_INVALID_DEVICE_ID; @@ -790,8 +906,6 @@ static DWORD MCIQTZ_mciWindow(UINT wDevID, DWORD dwFlags, LPMCI_DGV_WINDOW_PARMS TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms); - if (!lpParms) - return MCIERR_NULL_PARAMETER_BLOCK; if (!wma) return MCIERR_INVALID_DEVICE_ID; if (dwFlags & MCI_TEST) @@ -835,9 +949,6 @@ static DWORD MCIQTZ_mciUpdate(UINT wDevID, DWORD dwFlags, LPMCI_DGV_UPDATE_PARMS TRACE("%04x, %08x, %p\n", wDevID, dwFlags, lpParms); - if (!lpParms) - return MCIERR_NULL_PARAMETER_BLOCK; - wma = MCIQTZ_mciGetOpenDev(wDevID); if (!wma) return MCIERR_INVALID_DEVICE_ID; @@ -895,18 +1006,115 @@ out: static DWORD MCIQTZ_mciSetAudio(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SETAUDIO_PARMSW lpParms) { WINE_MCIQTZ *wma; + DWORD ret = 0; - FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms); - - if (!lpParms) - return MCIERR_NULL_PARAMETER_BLOCK; + TRACE("(%04x, %08x, %p)\n", wDevID, dwFlags, lpParms); wma = MCIQTZ_mciGetOpenDev(wDevID); if (!wma) return MCIERR_INVALID_DEVICE_ID; - MCIQTZ_mciStop(wDevID, MCI_WAIT, NULL); + if (!(dwFlags & MCI_DGV_SETAUDIO_ITEM)) { + FIXME("Unknown flags (%08x)\n", dwFlags); + return 0; + } + if (dwFlags & MCI_DGV_SETAUDIO_ITEM) { + switch (lpParms->dwItem) { + case MCI_DGV_SETAUDIO_VOLUME: + if (dwFlags & MCI_DGV_SETAUDIO_VALUE) { + long vol = -10000; + HRESULT hr; + if (lpParms->dwValue > 1000) { + ret = MCIERR_OUTOFRANGE; + break; + } + if (dwFlags & MCI_TEST) + break; + vol += (long)lpParms->dwValue * 10; + hr = IBasicAudio_put_Volume(wma->audio, vol); + if (FAILED(hr)) { + WARN("Cannot set volume (hr = %x)\n", hr); + ret = MCIERR_INTERNAL; + } + } + break; + default: + FIXME("Unknown item %08x\n", lpParms->dwItem); + break; + } + } + + return ret; +} + +/*************************************************************************** + * MCIQTZ_taskThread [internal] + */ +static DWORD CALLBACK MCIQTZ_taskThread(LPVOID arg) +{ + WINE_MCIQTZ_TASK *task = (WINE_MCIQTZ_TASK *)arg; + + for (;;) { + DWORD ret = WaitForSingleObject(task->notify, INFINITE); + if (ret != WAIT_OBJECT_0) { + TRACE("Got error (%u)\n", ret); + continue; + } + + switch (task->msg) { + case MCI_OPEN_DRIVER: + task->res = MCIQTZ_mciOpen(task->devid, task->flags, (LPMCI_DGV_OPEN_PARMSW)task->parms); + break; + case MCI_CLOSE_DRIVER: + task->res = MCIQTZ_mciClose(task->devid, task->flags, (LPMCI_GENERIC_PARMS)task->parms); + break; + case MCI_PLAY: + task->res = MCIQTZ_mciPlay(task->devid, task->flags, (LPMCI_PLAY_PARMS)task->parms); + break; + case MCI_SEEK: + task->res = MCIQTZ_mciSeek(task->devid, task->flags, (LPMCI_SEEK_PARMS)task->parms); + break; + case MCI_STOP: + task->res = MCIQTZ_mciStop(task->devid, task->flags, (LPMCI_GENERIC_PARMS)task->parms); + break; + case MCI_PAUSE: + task->res = MCIQTZ_mciPause(task->devid, task->flags, (LPMCI_GENERIC_PARMS)task->parms); + break; + case MCI_GETDEVCAPS: + task->res = MCIQTZ_mciGetDevCaps(task->devid, task->flags, (LPMCI_GETDEVCAPS_PARMS)task->parms); + break; + case MCI_SET: + task->res = MCIQTZ_mciSet(task->devid, task->flags, (LPMCI_DGV_SET_PARMS)task->parms); + break; + case MCI_STATUS: + task->res = MCIQTZ_mciStatus(task->devid, task->flags, (LPMCI_DGV_STATUS_PARMSW)task->parms); + break; + case MCI_WHERE: + task->res = MCIQTZ_mciWhere(task->devid, task->flags, (LPMCI_DGV_RECT_PARMS)task->parms); + break; + case MCI_SETAUDIO: + task->res = MCIQTZ_mciSetAudio(task->devid, task->flags, (LPMCI_DGV_SETAUDIO_PARMSW)task->parms); + break; + case MCI_UPDATE: + task->res = MCIQTZ_mciUpdate(task->devid, task->flags, (LPMCI_DGV_UPDATE_PARMS)task->parms); + break; + case MCI_WINDOW: + task->res = MCIQTZ_mciWindow(task->devid, task->flags, (LPMCI_DGV_WINDOW_PARMSW)task->parms); + break; + case MCI_CLOSE: + /* Special internal message */ + SetEvent(task->done); + goto end; + default: + FIXME("Shouldn't receive another message (%04x)\n", task->msg); + task->res = MCIERR_UNRECOGNIZED_COMMAND; + break; + } + SetEvent(task->done); + } + +end: return 0; } @@ -941,22 +1149,25 @@ LRESULT CALLBACK MCIQTZ_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg, return 1; switch (wMsg) { - case MCI_OPEN_DRIVER: return MCIQTZ_mciOpen (dwDevID, dwParam1, (LPMCI_DGV_OPEN_PARMSW) dwParam2); - case MCI_CLOSE_DRIVER: return MCIQTZ_mciClose (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2); - case MCI_PLAY: return MCIQTZ_mciPlay (dwDevID, dwParam1, (LPMCI_PLAY_PARMS) dwParam2); - case MCI_SEEK: return MCIQTZ_mciSeek (dwDevID, dwParam1, (LPMCI_SEEK_PARMS) dwParam2); - case MCI_STOP: return MCIQTZ_mciStop (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2); - case MCI_PAUSE: return MCIQTZ_mciPause (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2); - case MCI_GETDEVCAPS: return MCIQTZ_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS) dwParam2); - case MCI_SET: return MCIQTZ_mciSet (dwDevID, dwParam1, (LPMCI_DGV_SET_PARMS) dwParam2); - case MCI_STATUS: return MCIQTZ_mciStatus (dwDevID, dwParam1, (LPMCI_DGV_STATUS_PARMSW) dwParam2); - case MCI_WHERE: return MCIQTZ_mciWhere (dwDevID, dwParam1, (LPMCI_DGV_RECT_PARMS) dwParam2); + case MCI_OPEN_DRIVER: + case MCI_PLAY: + case MCI_SEEK: + case MCI_GETDEVCAPS: + case MCI_SET: + case MCI_STATUS: + case MCI_WHERE: + if (!dwParam2) return MCIERR_NULL_PARAMETER_BLOCK; + return MCIQTZ_relayTaskMessage(dwDevID, wMsg, dwParam1, dwParam2); + case MCI_CLOSE_DRIVER: + case MCI_STOP: + case MCI_PAUSE: + return MCIQTZ_relayTaskMessage(dwDevID, wMsg, dwParam1, dwParam2); /* Digital Video specific */ - case MCI_SETAUDIO: return MCIQTZ_mciSetAudio (dwDevID, dwParam1, (LPMCI_DGV_SETAUDIO_PARMSW) dwParam2); + case MCI_SETAUDIO: case MCI_UPDATE: - return MCIQTZ_mciUpdate(dwDevID, dwParam1, (LPMCI_DGV_UPDATE_PARMS)dwParam2); case MCI_WINDOW: - return MCIQTZ_mciWindow(dwDevID, dwParam1, (LPMCI_DGV_WINDOW_PARMSW)dwParam2); + if (!dwParam2) return MCIERR_NULL_PARAMETER_BLOCK; + return MCIQTZ_relayTaskMessage(dwDevID, wMsg, dwParam1, dwParam2); case MCI_PUT: case MCI_RECORD: case MCI_RESUME: diff --git a/reactos/dll/win32/mciqtz32/mciqtz_private.h b/reactos/dll/win32/mciqtz32/mciqtz_private.h index 9ed972fc53b..20d5742edf5 100644 --- a/reactos/dll/win32/mciqtz32/mciqtz_private.h +++ b/reactos/dll/win32/mciqtz32/mciqtz_private.h @@ -25,6 +25,17 @@ #include +typedef struct { + HANDLE thread; + HANDLE notify; + HANDLE done; + DWORD msg; + DWORD_PTR devid; + DWORD flags; + DWORD_PTR parms; + LRESULT res; +} WINE_MCIQTZ_TASK; + typedef struct { MCIDEVICEID wDevID; BOOL opened; @@ -35,9 +46,16 @@ typedef struct { IMediaEvent* mevent; IVideoWindow* vidwin; IBasicVideo* vidbasic; + IBasicAudio* audio; DWORD time_format; UINT command_table; - HWND parent; + HWND parent; + MCIDEVICEID notify_devid; + HANDLE callback; + HANDLE thread; + HANDLE stop_event; + CRITICAL_SECTION cs; + WINE_MCIQTZ_TASK task; } WINE_MCIQTZ; #endif /* __WINE_PRIVATE_MCIQTZ_H */ diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index 2cd7e40396b..91f9f4029a7 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -97,7 +97,7 @@ reactos/dll/win32/lz32 # Synced to WineStaging-1.7.37 reactos/dll/win32/mapi32 # Synced to WineStaging-1.7.37 reactos/dll/win32/mciavi32 # Synced to WineStaging-1.7.37 reactos/dll/win32/mcicda # Synced to WineStaging-1.7.37 -reactos/dll/win32/mciqtz32 # Synced to WineStaging-1.7.37 +reactos/dll/win32/mciqtz32 # Synced to WineStaging-1.7.47 reactos/dll/win32/mciseq # Synced to WineStaging-1.7.37 reactos/dll/win32/mciwave # Synced to WineStaging-1.7.37 reactos/dll/win32/mgmtapi # Synced to WineStaging-1.7.37