winmm: Restrict some MCI actions to the creating thread.
This reverts commit 46d5973961
and fixes
bug 38241 another way.
Signed-off-by: Andrew Eikum <aeikum@codeweavers.com>
Signed-off-by: Akihiro Sagawa <sagawa.aki@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
3d73f62f01
commit
d7cc002566
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(mciqtz);
|
WINE_DEFAULT_DEBUG_CHANNEL(mciqtz);
|
||||||
|
|
||||||
static DWORD CALLBACK MCIQTZ_taskThread(LPVOID arg);
|
static DWORD MCIQTZ_mciClose(UINT, DWORD, LPMCI_GENERIC_PARMS);
|
||||||
static DWORD MCIQTZ_mciStop(UINT, DWORD, LPMCI_GENERIC_PARMS);
|
static DWORD MCIQTZ_mciStop(UINT, DWORD, LPMCI_GENERIC_PARMS);
|
||||||
|
|
||||||
/*======================================================================*
|
/*======================================================================*
|
||||||
|
@ -67,40 +67,6 @@ static WINE_MCIQTZ* MCIQTZ_mciGetOpenDev(UINT wDevID)
|
||||||
return wma;
|
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]
|
* MCIQTZ_drvOpen [internal]
|
||||||
*/
|
*/
|
||||||
|
@ -120,25 +86,12 @@ static DWORD MCIQTZ_drvOpen(LPCWSTR str, LPMCI_OPEN_DRIVER_PARMSW modp)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
wma->stop_event = CreateEventW(NULL, FALSE, FALSE, NULL);
|
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;
|
modp->wType = MCI_DEVTYPE_DIGITAL_VIDEO;
|
||||||
wma->wDevID = modp->wDeviceID;
|
wma->wDevID = modp->wDeviceID;
|
||||||
modp->wCustomCommandTable = wma->command_table = mciLoadCommandResource(MCIQTZ_hInstance, mciAviWStr, 0);
|
modp->wCustomCommandTable = wma->command_table = mciLoadCommandResource(MCIQTZ_hInstance, mciAviWStr, 0);
|
||||||
mciSetDriverData(wma->wDevID, (DWORD_PTR)wma);
|
mciSetDriverData(wma->wDevID, (DWORD_PTR)wma);
|
||||||
|
|
||||||
return modp->wDeviceID;
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -154,16 +107,9 @@ static DWORD MCIQTZ_drvClose(DWORD dwDevID)
|
||||||
|
|
||||||
if (wma) {
|
if (wma) {
|
||||||
/* finish all outstanding things */
|
/* finish all outstanding things */
|
||||||
MCIQTZ_relayTaskMessage(dwDevID, MCI_CLOSE_DRIVER, MCI_WAIT, 0);
|
MCIQTZ_mciClose(dwDevID, MCI_WAIT, NULL);
|
||||||
|
|
||||||
mciFreeCommandResource(wma->command_table);
|
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);
|
|
||||||
wma->cs.DebugInfo->Spare[0] = 0;
|
|
||||||
DeleteCriticalSection(&wma->cs);
|
|
||||||
mciSetDriverData(dwDevID, 0);
|
mciSetDriverData(dwDevID, 0);
|
||||||
CloseHandle(wma->stop_event);
|
CloseHandle(wma->stop_event);
|
||||||
HeapFree(GetProcessHeap(), 0, wma);
|
HeapFree(GetProcessHeap(), 0, wma);
|
||||||
|
@ -220,6 +166,9 @@ static DWORD MCIQTZ_mciOpen(UINT wDevID, DWORD dwFlags,
|
||||||
|
|
||||||
TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpOpenParms);
|
TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpOpenParms);
|
||||||
|
|
||||||
|
if(!lpOpenParms)
|
||||||
|
return MCIERR_NULL_PARAMETER_BLOCK;
|
||||||
|
|
||||||
wma = MCIQTZ_mciGetOpenDev(wDevID);
|
wma = MCIQTZ_mciGetOpenDev(wDevID);
|
||||||
if (!wma)
|
if (!wma)
|
||||||
return MCIERR_INVALID_DEVICE_ID;
|
return MCIERR_INVALID_DEVICE_ID;
|
||||||
|
@ -443,6 +392,9 @@ static DWORD MCIQTZ_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms
|
||||||
|
|
||||||
TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms);
|
TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms);
|
||||||
|
|
||||||
|
if(!lpParms)
|
||||||
|
return MCIERR_NULL_PARAMETER_BLOCK;
|
||||||
|
|
||||||
wma = MCIQTZ_mciGetOpenDev(wDevID);
|
wma = MCIQTZ_mciGetOpenDev(wDevID);
|
||||||
if (!wma)
|
if (!wma)
|
||||||
return MCIERR_INVALID_DEVICE_ID;
|
return MCIERR_INVALID_DEVICE_ID;
|
||||||
|
@ -500,6 +452,9 @@ static DWORD MCIQTZ_mciSeek(UINT wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms
|
||||||
|
|
||||||
TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms);
|
TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms);
|
||||||
|
|
||||||
|
if(!lpParms)
|
||||||
|
return MCIERR_NULL_PARAMETER_BLOCK;
|
||||||
|
|
||||||
wma = MCIQTZ_mciGetOpenDev(wDevID);
|
wma = MCIQTZ_mciGetOpenDev(wDevID);
|
||||||
if (!wma)
|
if (!wma)
|
||||||
return MCIERR_INVALID_DEVICE_ID;
|
return MCIERR_INVALID_DEVICE_ID;
|
||||||
|
@ -615,6 +570,9 @@ static DWORD MCIQTZ_mciGetDevCaps(UINT wDevID, DWORD dwFlags, LPMCI_GETDEVCAPS_P
|
||||||
|
|
||||||
TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms);
|
TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms);
|
||||||
|
|
||||||
|
if(!lpParms)
|
||||||
|
return MCIERR_NULL_PARAMETER_BLOCK;
|
||||||
|
|
||||||
wma = MCIQTZ_mciGetOpenDev(wDevID);
|
wma = MCIQTZ_mciGetOpenDev(wDevID);
|
||||||
if (!wma)
|
if (!wma)
|
||||||
return MCIERR_INVALID_DEVICE_ID;
|
return MCIERR_INVALID_DEVICE_ID;
|
||||||
|
@ -711,6 +669,9 @@ static DWORD MCIQTZ_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SET_PARMS lpPar
|
||||||
|
|
||||||
TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms);
|
TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms);
|
||||||
|
|
||||||
|
if(!lpParms)
|
||||||
|
return MCIERR_NULL_PARAMETER_BLOCK;
|
||||||
|
|
||||||
wma = MCIQTZ_mciGetOpenDev(wDevID);
|
wma = MCIQTZ_mciGetOpenDev(wDevID);
|
||||||
if (!wma)
|
if (!wma)
|
||||||
return MCIERR_INVALID_DEVICE_ID;
|
return MCIERR_INVALID_DEVICE_ID;
|
||||||
|
@ -765,6 +726,9 @@ static DWORD MCIQTZ_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STATUS_PARMS
|
||||||
|
|
||||||
TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms);
|
TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms);
|
||||||
|
|
||||||
|
if(!lpParms)
|
||||||
|
return MCIERR_NULL_PARAMETER_BLOCK;
|
||||||
|
|
||||||
wma = MCIQTZ_mciGetOpenDev(wDevID);
|
wma = MCIQTZ_mciGetOpenDev(wDevID);
|
||||||
if (!wma)
|
if (!wma)
|
||||||
return MCIERR_INVALID_DEVICE_ID;
|
return MCIERR_INVALID_DEVICE_ID;
|
||||||
|
@ -865,6 +829,9 @@ static DWORD MCIQTZ_mciWhere(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RECT_PARMS lp
|
||||||
|
|
||||||
TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms);
|
TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms);
|
||||||
|
|
||||||
|
if(!lpParms)
|
||||||
|
return MCIERR_NULL_PARAMETER_BLOCK;
|
||||||
|
|
||||||
wma = MCIQTZ_mciGetOpenDev(wDevID);
|
wma = MCIQTZ_mciGetOpenDev(wDevID);
|
||||||
if (!wma)
|
if (!wma)
|
||||||
return MCIERR_INVALID_DEVICE_ID;
|
return MCIERR_INVALID_DEVICE_ID;
|
||||||
|
@ -927,6 +894,9 @@ static DWORD MCIQTZ_mciWindow(UINT wDevID, DWORD dwFlags, LPMCI_DGV_WINDOW_PARMS
|
||||||
|
|
||||||
TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms);
|
TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms);
|
||||||
|
|
||||||
|
if(!lpParms)
|
||||||
|
return MCIERR_NULL_PARAMETER_BLOCK;
|
||||||
|
|
||||||
if (!wma)
|
if (!wma)
|
||||||
return MCIERR_INVALID_DEVICE_ID;
|
return MCIERR_INVALID_DEVICE_ID;
|
||||||
if (dwFlags & MCI_TEST)
|
if (dwFlags & MCI_TEST)
|
||||||
|
@ -971,6 +941,9 @@ static DWORD MCIQTZ_mciPut(UINT wDevID, DWORD dwFlags, MCI_GENERIC_PARMS *lpParm
|
||||||
|
|
||||||
TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms);
|
TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms);
|
||||||
|
|
||||||
|
if(!lpParms)
|
||||||
|
return MCIERR_NULL_PARAMETER_BLOCK;
|
||||||
|
|
||||||
if (!wma)
|
if (!wma)
|
||||||
return MCIERR_INVALID_DEVICE_ID;
|
return MCIERR_INVALID_DEVICE_ID;
|
||||||
|
|
||||||
|
@ -1017,6 +990,9 @@ static DWORD MCIQTZ_mciUpdate(UINT wDevID, DWORD dwFlags, LPMCI_DGV_UPDATE_PARMS
|
||||||
|
|
||||||
TRACE("%04x, %08x, %p\n", wDevID, dwFlags, lpParms);
|
TRACE("%04x, %08x, %p\n", wDevID, dwFlags, lpParms);
|
||||||
|
|
||||||
|
if(!lpParms)
|
||||||
|
return MCIERR_NULL_PARAMETER_BLOCK;
|
||||||
|
|
||||||
wma = MCIQTZ_mciGetOpenDev(wDevID);
|
wma = MCIQTZ_mciGetOpenDev(wDevID);
|
||||||
if (!wma)
|
if (!wma)
|
||||||
return MCIERR_INVALID_DEVICE_ID;
|
return MCIERR_INVALID_DEVICE_ID;
|
||||||
|
@ -1078,6 +1054,9 @@ static DWORD MCIQTZ_mciSetAudio(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SETAUDIO_P
|
||||||
|
|
||||||
TRACE("(%04x, %08x, %p)\n", wDevID, dwFlags, lpParms);
|
TRACE("(%04x, %08x, %p)\n", wDevID, dwFlags, lpParms);
|
||||||
|
|
||||||
|
if(!lpParms)
|
||||||
|
return MCIERR_NULL_PARAMETER_BLOCK;
|
||||||
|
|
||||||
wma = MCIQTZ_mciGetOpenDev(wDevID);
|
wma = MCIQTZ_mciGetOpenDev(wDevID);
|
||||||
if (!wma)
|
if (!wma)
|
||||||
return MCIERR_INVALID_DEVICE_ID;
|
return MCIERR_INVALID_DEVICE_ID;
|
||||||
|
@ -1116,82 +1095,6 @@ static DWORD MCIQTZ_mciSetAudio(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SETAUDIO_P
|
||||||
return ret;
|
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_RESUME:
|
|
||||||
task->res = MCIQTZ_mciResume(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_PUT:
|
|
||||||
task->res = MCIQTZ_mciPut(task->devid, task->flags, (MCI_GENERIC_PARMS*)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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*======================================================================*
|
/*======================================================================*
|
||||||
* MCI QTZ entry points *
|
* MCI QTZ entry points *
|
||||||
*======================================================================*/
|
*======================================================================*/
|
||||||
|
@ -1223,27 +1126,25 @@ LRESULT CALLBACK MCIQTZ_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg,
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
switch (wMsg) {
|
switch (wMsg) {
|
||||||
case MCI_OPEN_DRIVER:
|
case MCI_OPEN_DRIVER: return MCIQTZ_mciOpen (dwDevID, dwParam1, (LPMCI_DGV_OPEN_PARMSW) dwParam2);
|
||||||
case MCI_PLAY:
|
case MCI_CLOSE_DRIVER: return MCIQTZ_mciClose (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2);
|
||||||
case MCI_SEEK:
|
case MCI_PLAY: return MCIQTZ_mciPlay (dwDevID, dwParam1, (LPMCI_PLAY_PARMS) dwParam2);
|
||||||
case MCI_GETDEVCAPS:
|
case MCI_SEEK: return MCIQTZ_mciSeek (dwDevID, dwParam1, (LPMCI_SEEK_PARMS) dwParam2);
|
||||||
case MCI_SET:
|
case MCI_STOP: return MCIQTZ_mciStop (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2);
|
||||||
case MCI_STATUS:
|
case MCI_PAUSE: return MCIQTZ_mciPause (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2);
|
||||||
case MCI_WHERE:
|
case MCI_RESUME: return MCIQTZ_mciResume (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2);
|
||||||
if (!dwParam2) return MCIERR_NULL_PARAMETER_BLOCK;
|
case MCI_GETDEVCAPS: return MCIQTZ_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS) dwParam2);
|
||||||
return MCIQTZ_relayTaskMessage(dwDevID, wMsg, dwParam1, dwParam2);
|
case MCI_SET: return MCIQTZ_mciSet (dwDevID, dwParam1, (LPMCI_DGV_SET_PARMS) dwParam2);
|
||||||
case MCI_CLOSE_DRIVER:
|
case MCI_STATUS: return MCIQTZ_mciStatus (dwDevID, dwParam1, (LPMCI_DGV_STATUS_PARMSW) dwParam2);
|
||||||
case MCI_STOP:
|
case MCI_WHERE: return MCIQTZ_mciWhere (dwDevID, dwParam1, (LPMCI_DGV_RECT_PARMS) dwParam2);
|
||||||
case MCI_PAUSE:
|
|
||||||
case MCI_RESUME:
|
|
||||||
return MCIQTZ_relayTaskMessage(dwDevID, wMsg, dwParam1, dwParam2);
|
|
||||||
/* Digital Video specific */
|
/* Digital Video specific */
|
||||||
case MCI_SETAUDIO:
|
case MCI_SETAUDIO: return MCIQTZ_mciSetAudio (dwDevID, dwParam1, (LPMCI_DGV_SETAUDIO_PARMSW) dwParam2);
|
||||||
case MCI_UPDATE:
|
case MCI_UPDATE:
|
||||||
|
return MCIQTZ_mciUpdate(dwDevID, dwParam1, (LPMCI_DGV_UPDATE_PARMS)dwParam2);
|
||||||
case MCI_WINDOW:
|
case MCI_WINDOW:
|
||||||
|
return MCIQTZ_mciWindow(dwDevID, dwParam1, (LPMCI_DGV_WINDOW_PARMSW)dwParam2);
|
||||||
case MCI_PUT:
|
case MCI_PUT:
|
||||||
if (!dwParam2) return MCIERR_NULL_PARAMETER_BLOCK;
|
return MCIQTZ_mciPut(dwDevID, dwParam1, (MCI_GENERIC_PARMS*)dwParam2);
|
||||||
return MCIQTZ_relayTaskMessage(dwDevID, wMsg, dwParam1, dwParam2);
|
|
||||||
case MCI_RECORD:
|
case MCI_RECORD:
|
||||||
case MCI_INFO:
|
case MCI_INFO:
|
||||||
case MCI_LOAD:
|
case MCI_LOAD:
|
||||||
|
|
|
@ -25,17 +25,6 @@
|
||||||
|
|
||||||
#include "dshow.h"
|
#include "dshow.h"
|
||||||
|
|
||||||
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 {
|
typedef struct {
|
||||||
MCIDEVICEID wDevID;
|
MCIDEVICEID wDevID;
|
||||||
BOOL opened;
|
BOOL opened;
|
||||||
|
@ -54,8 +43,6 @@ typedef struct {
|
||||||
HANDLE callback;
|
HANDLE callback;
|
||||||
HANDLE thread;
|
HANDLE thread;
|
||||||
HANDLE stop_event;
|
HANDLE stop_event;
|
||||||
CRITICAL_SECTION cs;
|
|
||||||
WINE_MCIQTZ_TASK task;
|
|
||||||
} WINE_MCIQTZ;
|
} WINE_MCIQTZ;
|
||||||
|
|
||||||
#endif /* __WINE_PRIVATE_MCIQTZ_H */
|
#endif /* __WINE_PRIVATE_MCIQTZ_H */
|
||||||
|
|
|
@ -891,6 +891,9 @@ static DWORD MCI_SendCommandFrom32(MCIDEVICEID wDevID, UINT16 wMsg, DWORD_PTR dw
|
||||||
LPWINE_MCIDRIVER wmd = MCI_GetDriver(wDevID);
|
LPWINE_MCIDRIVER wmd = MCI_GetDriver(wDevID);
|
||||||
|
|
||||||
if (wmd) {
|
if (wmd) {
|
||||||
|
if(wmd->CreatorThread != GetCurrentThreadId())
|
||||||
|
return MCIERR_INVALID_DEVICE_NAME;
|
||||||
|
|
||||||
dwRet = SendDriverMessage(wmd->hDriver, wMsg, dwParam1, dwParam2);
|
dwRet = SendDriverMessage(wmd->hDriver, wMsg, dwParam1, dwParam2);
|
||||||
}
|
}
|
||||||
return dwRet;
|
return dwRet;
|
||||||
|
@ -1872,6 +1875,9 @@ static DWORD MCI_Close(UINT wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
|
||||||
return MCIERR_INVALID_DEVICE_ID;
|
return MCIERR_INVALID_DEVICE_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(wmd->CreatorThread != GetCurrentThreadId())
|
||||||
|
return MCIERR_INVALID_DEVICE_NAME;
|
||||||
|
|
||||||
dwRet = MCI_SendCommandFrom32(wDevID, MCI_CLOSE_DRIVER, dwParam, (DWORD_PTR)lpParms);
|
dwRet = MCI_SendCommandFrom32(wDevID, MCI_CLOSE_DRIVER, dwParam, (DWORD_PTR)lpParms);
|
||||||
|
|
||||||
MCI_UnLoadMciDriver(wmd);
|
MCI_UnLoadMciDriver(wmd);
|
||||||
|
|
|
@ -1391,6 +1391,46 @@ static void test_asyncWaveTypeMpegvideo(HWND hwnd)
|
||||||
test_notification(hwnd,"play (aborted by close)",MCI_NOTIFY_ABORTED);
|
test_notification(hwnd,"play (aborted by close)",MCI_NOTIFY_ABORTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DWORD CALLBACK thread_cb(void *p)
|
||||||
|
{
|
||||||
|
HANDLE evt = p;
|
||||||
|
MCIERROR mr;
|
||||||
|
|
||||||
|
mr = mciSendStringA("play x", NULL, 0, NULL);
|
||||||
|
ok(mr == MCIERR_INVALID_DEVICE_NAME, "play gave: 0x%x\n", mr);
|
||||||
|
|
||||||
|
mr = mciSendStringA("close x", NULL, 0, NULL);
|
||||||
|
ok(mr == MCIERR_INVALID_DEVICE_NAME, "close gave: 0x%x\n", mr);
|
||||||
|
|
||||||
|
SetEvent(evt);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_threads(void)
|
||||||
|
{
|
||||||
|
MCIERROR mr;
|
||||||
|
HANDLE evt;
|
||||||
|
|
||||||
|
mr = mciSendStringA("open tempfile.wav alias x", NULL, 0, NULL);
|
||||||
|
ok(mr == 0 || mr == ok_saved, "open gave: 0x%x\n", mr);
|
||||||
|
if(mr){
|
||||||
|
skip("Cannot open tempfile.wav for playing (%s), skipping\n", dbg_mcierr(mr));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
evt = CreateEventW( NULL, TRUE, FALSE, NULL );
|
||||||
|
|
||||||
|
CloseHandle(CreateThread(NULL, 0, &thread_cb, evt, 0, NULL));
|
||||||
|
|
||||||
|
WaitForSingleObject(evt, INFINITE);
|
||||||
|
|
||||||
|
CloseHandle(evt);
|
||||||
|
|
||||||
|
mr = mciSendStringA("close x", NULL, 0, NULL);
|
||||||
|
ok(mr == 0, "close gave: 0x%x\n", mr);
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(mci)
|
START_TEST(mci)
|
||||||
{
|
{
|
||||||
char curdir[MAX_PATH], tmpdir[MAX_PATH];
|
char curdir[MAX_PATH], tmpdir[MAX_PATH];
|
||||||
|
@ -1407,6 +1447,7 @@ START_TEST(mci)
|
||||||
test_openCloseWAVE(hwnd);
|
test_openCloseWAVE(hwnd);
|
||||||
test_recordWAVE(hwnd);
|
test_recordWAVE(hwnd);
|
||||||
if(waveOutGetNumDevs()){
|
if(waveOutGetNumDevs()){
|
||||||
|
test_threads();
|
||||||
test_playWAVE(hwnd);
|
test_playWAVE(hwnd);
|
||||||
test_asyncWAVE(hwnd);
|
test_asyncWAVE(hwnd);
|
||||||
test_AutoOpenWAVE(hwnd);
|
test_AutoOpenWAVE(hwnd);
|
||||||
|
|
Loading…
Reference in New Issue