Fixed bugs on MCI notification (callback info are copied before

asynchronous return) - make use of it in MCI wave and midi.
Implemented mci(Set|Get)DeviceID(16|32) functions.
This commit is contained in:
Eric Pouech 1999-02-14 11:26:34 +00:00 committed by Alexandre Julliard
parent 8cef89652d
commit e518cba579
4 changed files with 135 additions and 91 deletions

View File

@ -70,7 +70,7 @@ extern const char* MCI_CommandToString(UINT16 wMsg);
extern DWORD MCI_SendCommand32(UINT32 wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2);
extern DWORD MCI_SendCommandAsync32(UINT32 wDevID, UINT32 wMsg, DWORD dwParam1, DWORD dwParam2);
extern DWORD MCI_SendCommandAsync32(UINT32 wDevID, UINT32 wMsg, DWORD dwParam1, DWORD dwParam2, UINT32 size);
LONG MCIWAVE_DriverProc32(DWORD dwDevID, HDRVR16 hDriv, DWORD wMsg,
DWORD dwParam1, DWORD dwParam2);

View File

@ -554,7 +554,10 @@ static DWORD MIDI_mciOpen(UINT16 wDevID, DWORD dwFlags, LPMCI_OPEN_PARMS32A lpPa
if (wDevID >= MAX_MCIMIDIDRV) {
WARN(mcimidi, "Invalid wDevID=%u\n", wDevID);
return MCIERR_INVALID_DEVICE_ID;
}
}
if (dwFlags & MCI_OPEN_SHAREABLE)
return MCIERR_HARDWARE;
wmm = &MCIMidiDev[wDevID];
if (wmm->nUseCount > 0) {
@ -765,7 +768,7 @@ static DWORD MIDI_mciPlay(UINT16 wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms
if (!(dwFlags & MCI_WAIT)) {
/** FIXME: I'm not 100% sure that wNotifyDeviceID is the right value in all cases ??? */
return MCI_SendCommandAsync32(wmm->wNotifyDeviceID, MCI_PLAY, dwFlags, (DWORD)lpParms);
return MCI_SendCommandAsync32(wmm->wNotifyDeviceID, MCI_PLAY, dwFlags, (DWORD)lpParms, sizeof(LPMCI_PLAY_PARMS));
}
if (lpParms && (dwFlags & MCI_FROM)) {

View File

@ -155,21 +155,18 @@ static DWORD WAVE_mciOpen(UINT16 wDevID, DWORD dwFlags, LPMCI_WAVE_OPEN_PARMS32A
WARN(mciwave, "Invalid wDevID=%u\n", wDevID);
return MCIERR_INVALID_DEVICE_ID;
}
if (dwFlags & MCI_OPEN_SHAREABLE)
return MCIERR_HARDWARE;
wmw = &MCIWaveDev[wDevID];
if (wmw->nUseCount > 0) {
/* The driver already open on this channel */
/* If the driver was opened shareable before and this open specifies */
/* shareable then increment the use count */
if (wmw->fShareable && (dwFlags & MCI_OPEN_SHAREABLE))
++wmw->nUseCount;
else
return MCIERR_MUST_USE_SHAREABLE;
} else {
wmw->nUseCount = 1;
wmw->fShareable = dwFlags & MCI_OPEN_SHAREABLE;
/* The driver is already opened on this channel
* Wave driver cannot be shared
*/
return MCIERR_DEVICE_OPEN;
}
wmw->nUseCount++;
dwDeviceID = lpOpenParms->wDeviceID;
@ -189,7 +186,7 @@ static DWORD WAVE_mciOpen(UINT16 wDevID, DWORD dwFlags, LPMCI_WAVE_OPEN_PARMS32A
/*FIXME : what should be done id wmw->hFile is already != 0, or the driver is playin' */
TRACE(mciwave,"MCI_OPEN_ELEMENT '%s' !\n", lpstrElementName);
if (lpstrElementName && (strlen(lpstrElementName) > 0)) {
wmw->hFile = mmioOpen32A(lpstrElementName, NULL,
wmw->hFile = mmioOpen32A((LPSTR)lpstrElementName, NULL,
MMIO_ALLOCBUF | MMIO_READWRITE | MMIO_EXCLUSIVE);
if (wmw->hFile == 0) {
WARN(mciwave, "can't find file='%s' !\n", lpstrElementName);
@ -327,35 +324,38 @@ static DWORD WAVE_mciStop(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpPa
*/
static DWORD WAVE_mciClose(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
{
DWORD dwRet;
DWORD dwRet = 0;
WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
TRACE(mciwave, "(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
if (wmw->dwStatus != MCI_MODE_STOP) {
WAVE_mciStop(wDevID, MCI_WAIT, lpParms);
dwRet = WAVE_mciStop(wDevID, MCI_WAIT, lpParms);
}
wmw->dwStatus = MCI_MODE_STOP;
wmw->nUseCount--;
if (wmw->nUseCount == 0) {
DWORD mmRet;
if (wmw->hFile != 0) {
mmioClose32(wmw->hFile, 0);
wmw->hFile = 0;
}
if (wmw->fInput) dwRet = widMessage(wDevID, WIDM_CLOSE, 0, 0L, 0L);
else dwRet = wodMessage(wDevID, WODM_CLOSE, 0, 0L, 0L);
mmRet = (wmw->fInput) ? widMessage(wDevID, WIDM_CLOSE, 0, 0L, 0L) :
wodMessage(wDevID, WODM_CLOSE, 0, 0L, 0L);
if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
if (mmRet != MMSYSERR_NOERROR) dwRet = MCIERR_INTERNAL;
}
if (lpParms && (dwFlags & MCI_NOTIFY)) {
if (dwFlags & MCI_NOTIFY) {
TRACE(mciwave, "MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
mciDriverNotify16((HWND16)LOWORD(lpParms->dwCallback),
wmw->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
wmw->wNotifyDeviceID,
(dwRet == 0) ? MCI_NOTIFY_SUCCESSFUL : MCI_NOTIFY_FAILURE);
}
return 0;
}
@ -370,10 +370,11 @@ static DWORD WAVE_mciPlay(UINT16 wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms
HGLOBAL16 hData;
DWORD dwRet;
WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
TRACE(mciwave, "(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
if (wmw->fInput) {
WARN(mciwave, "cannot play on input device\n");
@ -385,9 +386,9 @@ static DWORD WAVE_mciPlay(UINT16 wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms
return MCIERR_FILE_NOT_FOUND;
}
if (!(dwFlags & MCI_WAIT)) {
/** FIXME: I'm not 100% sure that wNotifyDeviceID is the right value in all cases ??? */
return MCI_SendCommandAsync32(wmw->wNotifyDeviceID, MCI_PLAY, dwFlags, (DWORD)lpParms);
if (!(dwFlags & MCI_WAIT)) {
return MCI_SendCommandAsync32(wmw->wNotifyDeviceID, MCI_PLAY, dwFlags,
(DWORD)lpParms, sizeof(MCI_PLAY_PARMS));
}
end = 0xFFFFFFFF;
@ -462,7 +463,8 @@ static DWORD WAVE_mciRecord(UINT16 wDevID, DWORD dwFlags, LPMCI_RECORD_PARMS lpP
TRACE(mciwave, "(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
if (!wmw->fInput) {
WARN(mciwave, "cannot record on output device\n");
@ -599,7 +601,7 @@ static DWORD WAVE_mciSeek(UINT16 wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms
if (dwFlags & MCI_NOTIFY) {
TRACE(mciwave, "MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
mciDriverNotify16((HWND16)LOWORD(lpParms->dwCallback),
wmw->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
wmw->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
}
}
return ret;
@ -613,6 +615,7 @@ static DWORD WAVE_mciSet(UINT16 wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms)
WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
TRACE(mciwave, "(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;

View File

@ -1114,6 +1114,9 @@ BOOL16 WINAPI mciGetErrorString16(DWORD wError, LPSTR lpstrBuffer,UINT16 uLength
lpstrBuffer[0] = '\0';
switch (wError) {
case 0:
msgptr = "The specified command has been executed.";
break;
case MCIERR_INVALID_DEVICE_ID:
msgptr = "Invalid MCI device ID. Use the ID returned when opening the MCI device.";
break;
@ -1384,11 +1387,14 @@ BOOL16 WINAPI mciGetErrorString16(DWORD wError, LPSTR lpstrBuffer,UINT16 uLength
*/
BOOL16 WINAPI mciDriverNotify16(HWND16 hWndCallBack, UINT16 wDevID, UINT16 wStatus)
{
TRACE(mmsys, "(%04X, %u, %04X)\n", hWndCallBack, wDevID, wStatus);
TRACE(mmsys, "(%04X, %04x, %04X)\n", hWndCallBack, wDevID, wStatus);
if (!IsWindow32(hWndCallBack)) return FALSE;
if (!IsWindow32(hWndCallBack)) {
WARN(mmsys, "bad hWnd for call back\n");
return FALSE;
}
TRACE(mmsys, "before PostMessage\n");
PostMessage32A(hWndCallBack, MM_MCINOTIFY, wStatus, MAKELONG(wDevID, 0));
PostMessage32A(hWndCallBack, MM_MCINOTIFY, wStatus, wDevID);
return TRUE;
}
@ -1397,9 +1403,15 @@ BOOL16 WINAPI mciDriverNotify16(HWND16 hWndCallBack, UINT16 wDevID, UINT16 wStat
*/
BOOL32 WINAPI mciDriverNotify32(HWND32 hWndCallBack, UINT32 wDevID, UINT32 wStatus)
{
FIXME(mmsys, "stub(%04X, %u, %04X)\n", hWndCallBack, wDevID, wStatus);
FIXME(mmsys, "(%08X, %04x, %04X)\n", hWndCallBack, wDevID, wStatus);
return FALSE;
if (!IsWindow32(hWndCallBack)) {
WARN(mmsys, "bad hWnd for call back\n");
return FALSE;
}
TRACE(mmsys, "before PostMessage\n");
PostMessage32A(hWndCallBack, MM_MCINOTIFY, wStatus, wDevID);
return TRUE;
}
/**************************************************************************
@ -1407,9 +1419,7 @@ BOOL32 WINAPI mciDriverNotify32(HWND32 hWndCallBack, UINT32 wDevID, UINT32 wStat
*/
DWORD WINAPI mciGetDriverData16(HDRVR16 hdrv)
{
FIXME(mmsys,"(%04x): stub!\n", hdrv);
return 0x42;
return mciGetDriverData32(hdrv);
}
/**************************************************************************
@ -1417,9 +1427,12 @@ DWORD WINAPI mciGetDriverData16(HDRVR16 hdrv)
*/
DWORD WINAPI mciGetDriverData32(HDRVR32 hdrv)
{
FIXME(mmsys,"(%04x): stub!\n", hdrv);
return 0x42;
TRACE(mmsys,"(%04x)\n", hdrv);
if (!MCI_DevIDValid(hdrv) || MCI_GetDrv(hdrv)->modp.wType == 0) {
return 0L;
}
return MCI_GetDrv(hdrv)->dwPrivate;
}
/**************************************************************************
@ -1427,9 +1440,7 @@ DWORD WINAPI mciGetDriverData32(HDRVR32 hdrv)
*/
BOOL16 WINAPI mciSetDriverData16(HDRVR16 hdrv, DWORD data)
{
FIXME(mmsys,"(%04x,%08lx): stub!\n", hdrv, data);
return 0;
return mciSetDriverData32(hdrv, data);
}
/**************************************************************************
@ -1437,9 +1448,13 @@ BOOL16 WINAPI mciSetDriverData16(HDRVR16 hdrv, DWORD data)
*/
BOOL32 WINAPI mciSetDriverData32(HDRVR32 hdrv, DWORD data)
{
FIXME(mmsys,"(%04x,%08lx): stub!\n", hdrv, data);
return 0;
TRACE(mmsys,"(%04x,%08lx)\n", hdrv, data);
if (!MCI_DevIDValid(hdrv) || MCI_GetDrv(hdrv)->modp.wType == 0) {
return FALSE;
}
MCI_GetDrv(hdrv)->dwPrivate = data;
return TRUE;
}
/**************************************************************************
@ -1577,20 +1592,20 @@ DWORD MCI_SendCommand32(UINT32 wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwPara
dwRet = MCIERR_INVALID_DEVICE_ID;
} else {
MCIPROC32 proc = MCI_GetProc32(MCI_GetDrv(wDevID)->modp.wType);
if (proc) {
dwRet = (*proc)(MCI_GetDrv(wDevID)->modp.wDeviceID,
MCI_GetDrv(wDevID)->hDrv,
wMsg, dwParam1, dwParam2);
} else if (MCI_GetDrv(wDevID)->driverProc) {
FIXME(mmsys, "is that correct ?\n");
dwRet = Callbacks->CallDriverProc(MCI_GetDrv(wDevID)->driverProc,
MCI_GetDrv(wDevID)->modp.wDeviceID,
MCI_GetDrv(wDevID)->hDrv,
wMsg, dwParam1, dwParam2);
} else {
WARN(mmsys, "unknown device type=%04X !\n", MCI_GetDrv(wDevID)->modp.wType);
}
if (proc) {
dwRet = (*proc)(MCI_GetDrv(wDevID)->modp.wDeviceID,
MCI_GetDrv(wDevID)->hDrv,
wMsg, dwParam1, dwParam2);
} else if (MCI_GetDrv(wDevID)->driverProc) {
FIXME(mmsys, "is that correct ?\n");
dwRet = Callbacks->CallDriverProc(MCI_GetDrv(wDevID)->driverProc,
MCI_GetDrv(wDevID)->modp.wDeviceID,
MCI_GetDrv(wDevID)->hDrv,
wMsg, dwParam1, dwParam2);
} else {
WARN(mmsys, "unknown device type=%04X !\n", MCI_GetDrv(wDevID)->modp.wType);
}
}
return dwRet;
}
@ -1642,18 +1657,18 @@ static DWORD MCI_Open(DWORD dwParam, LPMCI_OPEN_PARMS32A lpParms)
#if testing32
/* FIXME has to be re-written, seems to be experimental 16 bit code anyway */
else {
HDRVR16 hdrv = OpenDriver32(str, "mci", NULL);
if (hdrv) {
HMODULE16 hmod;
hmod = GetDriverModuleHandle(hdrv);
HDRVR16 hdrv = OpenDriver32(str, "mci", NULL);
if (hdrv) {
HMODULE16 hmod;
hmod = GetDriverModuleHandle(hdrv);
MCI_GetDrv(wDevID)->hDrv = hdrv;
MCI_GetDrv(wDevID)->driverProc = GetProcAddress32(hmod,oouch SEGPTR_GET(SEGPTR_STRDUP("DriverProc")));
uDevTyp = MCI_DEVTYPE_OTHER;
} else {
FIXME(mmsys, "[mci extensions] entry %s for %s not supported.\n", str, t);
return MCIERR_DEVICE_NOT_INSTALLED;
}
MCI_GetDrv(wDevID)->driverProc = GetProcAddress32(hmod,oouch SEGPTR_GET(SEGPTR_STRDUP("DRIVERPROC")));
uDevTyp = MCI_DEVTYPE_OTHER;
} else {
FIXME(mmsys, "[mci extensions] entry %s for %s not supported.\n", str, t);
return MCIERR_DEVICE_NOT_INSTALLED;
}
}
#endif
}
@ -1706,6 +1721,7 @@ static DWORD MCI_Open(DWORD dwParam, LPMCI_OPEN_PARMS32A lpParms)
}
MCI_GetDrv(wDevID)->modp.wType = uDevTyp;
MCI_GetDrv(wDevID)->modp.wDeviceID = 0; /* FIXME? for multiple devices */
MCI_GetDrv(wDevID)->dwPrivate = 0;
lpParms->wDeviceID = wDevID;
TRACE(mmsys, "mcidev=%d, uDevTyp=%04X wDeviceID=%04X !\n",
wDevID, uDevTyp, lpParms->wDeviceID);
@ -1850,6 +1866,7 @@ struct SCA32 {
UINT32 wMsg;
DWORD dwParam1;
DWORD dwParam2;
BOOL32 allocatedCopy;
};
DWORD WINAPI mciSendCommand32A(UINT32 wDevID, UINT32 wMsg, DWORD dwParam1, DWORD dwParam2);
@ -1867,7 +1884,9 @@ static DWORD WINAPI MCI_SCAStarter32(LPVOID arg)
ret = mciSendCommand32A(sca->wDevID, sca->wMsg, sca->dwParam1 | MCI_WAIT, sca->dwParam2);
TRACE(mci, "In thread after async command (%08x,%s,%08lx,%08lx)\n",
sca->wDevID, MCI_CommandToString(sca->wMsg), sca->dwParam1, sca->dwParam2);
free(sca);
if (sca->allocatedCopy)
HeapFree(GetProcessHeap(), 0, (LPVOID)sca->dwParam2);
HeapFree(GetProcessHeap(), 0, sca);
ExitThread(ret);
WARN(mci, "Should not happen ? what's wrong \n");
/* should not go after this point */
@ -1877,17 +1896,33 @@ static DWORD WINAPI MCI_SCAStarter32(LPVOID arg)
/**************************************************************************
* MCI_SendCommandAsync32 [internal]
*/
DWORD MCI_SendCommandAsync32(UINT32 wDevID, UINT32 wMsg, DWORD dwParam1, DWORD dwParam2)
DWORD MCI_SendCommandAsync32(UINT32 wDevID, UINT32 wMsg, DWORD dwParam1, DWORD dwParam2, UINT32 size)
{
struct SCA32* sca = malloc(sizeof(struct SCA32));
struct SCA32* sca = HeapAlloc(GetProcessHeap(), 0, sizeof(struct SCA32));
if (sca == 0) return MCIERR_OUT_OF_MEMORY;
if (sca == 0)
return MCIERR_OUT_OF_MEMORY;
sca->wDevID = wDevID;
sca->wMsg = wMsg;
sca->dwParam1 = dwParam1;
sca->dwParam2 = dwParam2;
if (size) {
sca->dwParam2 = (DWORD)HeapAlloc(GetProcessHeap(), 0, size);
if (sca->dwParam2 == 0) {
HeapFree(GetProcessHeap(), 0, sca);
return MCIERR_OUT_OF_MEMORY;
}
sca->allocatedCopy = TRUE;
/* copy structure passed by program in dwParam2 to be sure
* we can still use it whatever the program does
*/
memcpy((LPVOID)sca->dwParam2, (LPVOID)dwParam2, size);
} else {
sca->dwParam2 = dwParam2;
sca->allocatedCopy = FALSE;
}
if (CreateThread(NULL, 0, MCI_SCAStarter32, sca, 0, NULL) == 0) {
WARN(mci, "Couldn't allocate thread for async command handling, sending synchonously\n");
return MCI_SCAStarter32(&sca);
@ -2200,6 +2235,7 @@ DWORD WINAPI mciSendCommand16(UINT16 wDevID, UINT16 wMsg, DWORD dwParam1, DWORD
MCI_UnMapMsg16To32A(0, wDevID, dwParam2);
}
break;
/* FIXME: it seems that MCI_BREAK and MCI_SOUND need the same handling */
default:
if (wDevID == MCI_ALL_DEVICE_ID) {
FIXME(mci, "unhandled MCI_ALL_DEVICE_ID\n");
@ -2233,7 +2269,6 @@ DWORD WINAPI mciSendCommand16(UINT16 wDevID, UINT16 wMsg, DWORD dwParam1, DWORD
UINT16 WINAPI mciGetDeviceID16(LPCSTR lpstrName)
{
UINT16 wDevID;
TRACE(mmsys, "(\"%s\")\n", lpstrName);
if (!lpstrName)
@ -2242,18 +2277,21 @@ UINT16 WINAPI mciGetDeviceID16(LPCSTR lpstrName)
if (!lstrcmpi32A(lpstrName, "ALL"))
return MCI_ALL_DEVICE_ID;
wDevID = MCI_FirstDevID();
while (MCI_DevIDValid(wDevID) && MCI_GetDrv(wDevID)->modp.wType) {
if (MCI_GetOpenDrv(wDevID)->lpstrDeviceType &&
strcmp(MCI_GetOpenDrv(wDevID)->lpstrDeviceType, lpstrName) == 0)
return wDevID;
for (wDevID = MCI_FirstDevID(); MCI_DevIDValid(wDevID); wDevID = MCI_NextDevID(wDevID)) {
if (MCI_GetDrv(wDevID)->modp.wType) {
FIXME(mmsys, "This is wrong for compound devices\n");
/* FIXME: for compound devices, lpstrName is matched against
* the name of the file, not the name of the device...
*/
if (MCI_GetOpenDrv(wDevID)->lpstrDeviceType &&
strcmp(MCI_GetOpenDrv(wDevID)->lpstrDeviceType, lpstrName) == 0)
return wDevID;
if (MCI_GetOpenDrv(wDevID)->lpstrAlias &&
strcmp(MCI_GetOpenDrv(wDevID)->lpstrAlias, lpstrName) == 0)
return wDevID;
wDevID = MCI_NextDevID(wDevID);
}
if (MCI_GetOpenDrv(wDevID)->lpstrAlias &&
strcmp(MCI_GetOpenDrv(wDevID)->lpstrAlias, lpstrName) == 0)
return wDevID;
}
}
return 0;
}
@ -2306,7 +2344,7 @@ BOOL32 WINAPI mciSetYieldProc32(UINT32 uDeviceID,
UINT16 WINAPI mciGetDeviceIDFromElementID16(DWORD dwElementID, LPCSTR lpstrType)
{
FIXME(mci, "(%lu, %s) stub\n", dwElementID, lpstrType);
return 0;
return 0;
}
/**************************************************************************