From cefc253b6668ac0a866a3bc7b2d143c56daaba8e Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Wed, 25 Jan 2012 19:12:49 +0000 Subject: [PATCH] [MCISEQ] * Sync to Wine 1.3.37. svn path=/trunk/; revision=55179 --- reactos/dll/win32/mciseq/mcimidi.c | 341 ++++++++++------------------- reactos/media/doc/README.WINE | 2 +- 2 files changed, 120 insertions(+), 223 deletions(-) diff --git a/reactos/dll/win32/mciseq/mcimidi.c b/reactos/dll/win32/mciseq/mcimidi.c index ec9a24ae4f9..2783c079a86 100644 --- a/reactos/dll/win32/mciseq/mcimidi.c +++ b/reactos/dll/win32/mciseq/mcimidi.c @@ -21,9 +21,8 @@ /* TODO: * + implement it correctly - * + finish asynchronous commands (especially for reading/record) + * + finish asynchronous commands * + better implement non waiting command (without the MCI_WAIT flag). - * + implement the recording features */ #include @@ -62,13 +61,12 @@ typedef struct tagWINE_MCIMIDI { UINT wDevID; /* the MCI one */ HMIDI hMidi; int nUseCount; /* Incremented for each shared open */ - WORD wPort; /* the WINMM device unit */ - WORD wNotifyDeviceID; /* MCI device ID with a pending notification */ HANDLE hCallback; /* Callback handle for pending notification */ HMMIO hFile; /* mmio file handle open as Element */ LPWSTR lpstrElementName; /* Name of file (if any) */ LPWSTR lpstrCopyright; LPWSTR lpstrName; + WORD wPort; /* the WINMM device unit */ WORD dwStatus; /* one from MCI_MODE_xxxx */ DWORD dwMciTimeFormat; /* One of the supported MCI_FORMAT_xxxx */ WORD wFormat; /* Format of MIDI hFile (0, 1 or 2) */ @@ -156,7 +154,7 @@ static DWORD MCI_SendCommandAsync(UINT wDevID, UINT wMsg, DWORD_PTR dwParam1, * MCI MIDI implementation * *======================================================================*/ -static DWORD MIDI_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms); +static DWORD MIDI_mciResume(WINE_MCIMIDI* wmm, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms); /************************************************************************** * MIDI_drvOpen [internal] @@ -197,17 +195,35 @@ static DWORD MIDI_drvClose(DWORD dwDevID) /************************************************************************** * MIDI_mciGetOpenDev [internal] */ -static WINE_MCIMIDI* MIDI_mciGetOpenDev(UINT wDevID) +static WINE_MCIMIDI* MIDI_mciGetOpenDev(MCIDEVICEID wDevID, UINT wMsg) { WINE_MCIMIDI* wmm = (WINE_MCIMIDI*)mciGetDriverData(wDevID); - if (wmm == NULL || wmm->nUseCount == 0) { + if (wmm == NULL || ((wmm->nUseCount == 0) ^ (wMsg == MCI_OPEN_DRIVER))) { WARN("Invalid wDevID=%u\n", wDevID); return 0; } return wmm; } +/************************************************************************** + * MIDI_mciNotify [internal] + * + * Notifications in MCI work like a 1-element queue. + * Each new notification request supersedes the previous one. + * This affects Play and Record; other commands are immediate. + */ +static void MIDI_mciNotify(DWORD_PTR hWndCallBack, WINE_MCIMIDI* wmm, UINT wStatus) +{ + /* We simply save one parameter by not passing the wDevID local + * to the command. They are the same (via mciGetDriverData). + */ + MCIDEVICEID wDevID = wmm->wDevID; + HANDLE old = InterlockedExchangePointer(&wmm->hCallback, NULL); + if (old) mciDriverNotify(old, wDevID, MCI_NOTIFY_SUPERSEDED); + mciDriverNotify(HWND_32(LOWORD(hWndCallBack)), wDevID, wStatus); +} + /************************************************************************** * MIDI_mciReadByte [internal] */ @@ -704,16 +720,13 @@ static DWORD MIDI_GetMThdLengthMS(WINE_MCIMIDI* wmm) /************************************************************************** * MIDI_mciOpen [internal] */ -static DWORD MIDI_mciOpen(UINT wDevID, DWORD dwFlags, LPMCI_OPEN_PARMSW lpParms) +static DWORD MIDI_mciOpen(WINE_MCIMIDI* wmm, DWORD dwFlags, LPMCI_OPEN_PARMSW lpParms) { DWORD dwRet = 0; - DWORD dwDeviceID; - WINE_MCIMIDI* wmm = (WINE_MCIMIDI*)mciGetDriverData(wDevID); - TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms); + TRACE("(%d, %08X, %p)\n", wmm->wDevID, dwFlags, lpParms); if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; - if (wmm == NULL) return MCIERR_INVALID_DEVICE_ID; if (dwFlags & MCI_OPEN_SHAREABLE) return MCIERR_HARDWARE; @@ -729,9 +742,8 @@ static DWORD MIDI_mciOpen(UINT wDevID, DWORD dwFlags, LPMCI_OPEN_PARMSW lpParms) wmm->hMidi = 0; wmm->wPort = MIDI_MAPPER; wmm->lpstrElementName = NULL; - dwDeviceID = lpParms->wDeviceID; - TRACE("wDevID=%04X (lpParams->wDeviceID=%08X)\n", wDevID, dwDeviceID); + TRACE("wDevID=%d (lpParams->wDeviceID=%d)\n", wmm->wDevID, lpParms->wDeviceID); /* lpParms->wDeviceID = wDevID;*/ if (dwFlags & MCI_OPEN_ELEMENT) { @@ -754,7 +766,6 @@ static DWORD MIDI_mciOpen(UINT wDevID, DWORD dwFlags, LPMCI_OPEN_PARMSW lpParms) wmm->lpstrCopyright = NULL; wmm->lpstrName = NULL; - wmm->wNotifyDeviceID = dwDeviceID; wmm->dwStatus = MCI_MODE_NOT_READY; /* while loading file contents */ /* spec says it should be the default format from the MIDI file... */ wmm->dwMciTimeFormat = MCI_FORMAT_MILLISECONDS; @@ -799,11 +810,8 @@ static DWORD MIDI_mciOpen(UINT wDevID, DWORD dwFlags, LPMCI_OPEN_PARMSW lpParms) } else { wmm->dwPositionMS = 0; wmm->dwStatus = MCI_MODE_STOP; - if (dwFlags & MCI_NOTIFY) { - TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback); - mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)), - wmm->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL); - } + if (dwFlags & MCI_NOTIFY) + MIDI_mciNotify(lpParms->dwCallback, wmm, MCI_NOTIFY_SUCCESSFUL); } return dwRet; } @@ -811,20 +819,23 @@ static DWORD MIDI_mciOpen(UINT wDevID, DWORD dwFlags, LPMCI_OPEN_PARMSW lpParms) /************************************************************************** * MIDI_mciStop [internal] */ -static DWORD MIDI_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms) +static DWORD MIDI_mciStop(WINE_MCIMIDI* wmm, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms) { - WINE_MCIMIDI* wmm = MIDI_mciGetOpenDev(wDevID); + DWORD dwRet = 0; - TRACE("(%04X, %08X, %p);\n", wDevID, dwFlags, lpParms); + TRACE("(%d, %08X, %p);\n", wmm->wDevID, dwFlags, lpParms); - if (wmm == NULL) return MCIERR_INVALID_DEVICE_ID; + if (wmm->dwStatus != MCI_MODE_STOP) { + HANDLE old = InterlockedExchangePointer(&wmm->hCallback, NULL); + if (old) mciDriverNotify(old, wmm->wDevID, MCI_NOTIFY_ABORTED); + } if (wmm->dwStatus != MCI_MODE_STOP) { int oldstat = wmm->dwStatus; wmm->dwStatus = MCI_MODE_NOT_READY; if (oldstat == MCI_MODE_PAUSE) - midiOutReset((HMIDIOUT)wmm->hMidi); + dwRet = midiOutReset((HMIDIOUT)wmm->hMidi); while (wmm->dwStatus != MCI_MODE_STOP) Sleep(10); @@ -833,29 +844,22 @@ static DWORD MIDI_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParm /* sanity reset */ wmm->dwStatus = MCI_MODE_STOP; - TRACE("wmm->dwStatus=%d\n", wmm->dwStatus); - - if (lpParms && (dwFlags & MCI_NOTIFY)) { - TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback); - mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)), - wmm->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL); - } - return 0; + if ((dwFlags & MCI_NOTIFY) && lpParms && MMSYSERR_NOERROR==dwRet) + MIDI_mciNotify(lpParms->dwCallback, wmm, MCI_NOTIFY_SUCCESSFUL); + return dwRet; } /************************************************************************** * MIDI_mciClose [internal] */ -static DWORD MIDI_mciClose(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms) +static DWORD MIDI_mciClose(WINE_MCIMIDI* wmm, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms) { - WINE_MCIMIDI* wmm = MIDI_mciGetOpenDev(wDevID); - TRACE("(%04X, %08X, %p);\n", wDevID, dwFlags, lpParms); - - if (wmm == NULL) return MCIERR_INVALID_DEVICE_ID; + TRACE("(%d, %08X, %p);\n", wmm->wDevID, dwFlags, lpParms); if (wmm->dwStatus != MCI_MODE_STOP) { - MIDI_mciStop(wDevID, MCI_WAIT, lpParms); + /* mciStop handles MCI_NOTIFY_ABORTED */ + MIDI_mciStop(wmm, MCI_WAIT, lpParms); } wmm->nUseCount--; @@ -874,10 +878,8 @@ static DWORD MIDI_mciClose(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpPar return MCIERR_INTERNAL; } - if (lpParms && (dwFlags & MCI_NOTIFY)) { - TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback); - mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)), - wmm->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL); + if ((dwFlags & MCI_NOTIFY) && lpParms) { + MIDI_mciNotify(lpParms->dwCallback, wmm, MCI_NOTIFY_SUCCESSFUL); } return 0; } @@ -909,18 +911,16 @@ static MCI_MIDITRACK* MIDI_mciFindNextEvent(WINE_MCIMIDI* wmm, LPDWORD hiPulse) /************************************************************************** * MIDI_mciPlay [internal] */ -static DWORD MIDI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms) +static DWORD MIDI_mciPlay(WINE_MCIMIDI* wmm, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms) { DWORD dwStartMS, dwEndMS; DWORD dwRet = 0; WORD doPlay, nt; MCI_MIDITRACK* mmt; DWORD hiPulse; - WINE_MCIMIDI* wmm = MIDI_mciGetOpenDev(wDevID); + HANDLE oldcb; - TRACE("(%04X, %08X, %p);\n", wDevID, dwFlags, lpParms); - - if (wmm == NULL) return MCIERR_INVALID_DEVICE_ID; + TRACE("(%d, %08X, %p);\n", wmm->wDevID, dwFlags, lpParms); if (wmm->hFile == 0) { WARN("Can't play: no file %s!\n", debugstr_w(wmm->lpstrElementName)); @@ -930,15 +930,14 @@ static DWORD MIDI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms) if (wmm->dwStatus != MCI_MODE_STOP) { if (wmm->dwStatus == MCI_MODE_PAUSE) { /* FIXME: parameters (start/end) in lpParams may not be used */ - return MIDI_mciResume(wDevID, dwFlags, (LPMCI_GENERIC_PARMS)lpParms); + return MIDI_mciResume(wmm, dwFlags, (LPMCI_GENERIC_PARMS)lpParms); } WARN("Can't play: device is not stopped !\n"); return MCIERR_INTERNAL; } if (!(dwFlags & MCI_WAIT)) { - /** FIXME: I'm not 100% sure that wNotifyDeviceID is the right value in all cases ??? */ - return MCI_SendCommandAsync(wmm->wNotifyDeviceID, MCI_PLAY, dwFlags, (DWORD_PTR)lpParms, sizeof(LPMCI_PLAY_PARMS)); + return MCI_SendCommandAsync(wmm->wDevID, MCI_PLAY, dwFlags, (DWORD_PTR)lpParms, sizeof(MCI_PLAY_PARMS)); } if (lpParms && (dwFlags & MCI_FROM)) { @@ -955,6 +954,11 @@ static DWORD MIDI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms) TRACE("Playing from %u to %u\n", dwStartMS, dwEndMS); + oldcb = InterlockedExchangePointer(&wmm->hCallback, + (dwFlags & MCI_NOTIFY) ? HWND_32(LOWORD(lpParms->dwCallback)) : NULL); + if (oldcb) mciDriverNotify(oldcb, wmm->wDevID, MCI_NOTIFY_ABORTED); + oldcb = NULL; + /* init tracks */ for (nt = 0; nt < wmm->nTracks; nt++) { mmt = &wmm->tracks[nt]; @@ -970,7 +974,6 @@ static DWORD MIDI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms) } dwRet = midiOutOpen((LPHMIDIOUT)&wmm->hMidi, wmm->wPort, 0L, 0L, CALLBACK_NULL); - /* dwRet = midiInOpen(&wmm->hMidi, wmm->wPort, 0L, 0L, CALLBACK_NULL);*/ if (dwRet != MMSYSERR_NOERROR) { return dwRet; } @@ -1173,87 +1176,24 @@ static DWORD MIDI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms) midiOutReset((HMIDIOUT)wmm->hMidi); dwRet = midiOutClose((HMIDIOUT)wmm->hMidi); - /* to restart playing at beginning when it's over */ - wmm->dwPositionMS = 0; - if (lpParms && (dwFlags & MCI_NOTIFY)) { - TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback); - mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)), - wmm->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL); - } + if (dwFlags & MCI_NOTIFY) + oldcb = InterlockedExchangePointer(&wmm->hCallback, NULL); wmm->dwStatus = MCI_MODE_STOP; + + /* Let the potentially asynchronous commands support FAILURE notification. */ + if (oldcb) mciDriverNotify(oldcb, wmm->wDevID, + dwRet ? MCI_NOTIFY_FAILURE : MCI_NOTIFY_SUCCESSFUL); return dwRet; } -/************************************************************************** - * MIDI_mciRecord [internal] - */ -static DWORD MIDI_mciRecord(UINT wDevID, DWORD dwFlags, LPMCI_RECORD_PARMS lpParms) -{ - int start, end; - MIDIHDR midiHdr; - WINE_MCIMIDI* wmm = MIDI_mciGetOpenDev(wDevID); - - TRACE("(%04X, %08X, %p);\n", wDevID, dwFlags, lpParms); - - if (wmm == 0) return MCIERR_INVALID_DEVICE_ID; - - if (wmm->hFile == 0) { - WARN("Can't find file=%s!\n", debugstr_w(wmm->lpstrElementName)); - return MCIERR_FILE_NOT_FOUND; - } - start = 1; end = 99999; - if (lpParms && (dwFlags & MCI_FROM)) { - start = lpParms->dwFrom; - TRACE("MCI_FROM=%d\n", start); - } - if (lpParms && (dwFlags & MCI_TO)) { - end = lpParms->dwTo; - TRACE("MCI_TO=%d\n", end); - } - midiHdr.lpData = HeapAlloc(GetProcessHeap(), 0, 1200); - if (!midiHdr.lpData) - return MCIERR_OUT_OF_MEMORY; - midiHdr.dwBufferLength = 1024; - midiHdr.dwUser = 0L; - midiHdr.dwFlags = 0L; - midiInPrepareHeader((HMIDIIN)wmm->hMidi, &midiHdr, sizeof(MIDIHDR)); - TRACE("After MIDM_PREPARE\n"); - wmm->dwStatus = MCI_MODE_RECORD; - /* FIXME: there is no buffer added */ - while (wmm->dwStatus != MCI_MODE_STOP) { - TRACE("wmm->dwStatus=%p %d\n", - &wmm->dwStatus, wmm->dwStatus); - midiHdr.dwBytesRecorded = 0; - midiInStart((HMIDIIN)wmm->hMidi); - TRACE("midiInStart => dwBytesRecorded=%u\n", midiHdr.dwBytesRecorded); - if (midiHdr.dwBytesRecorded == 0) break; - } - TRACE("Before MIDM_UNPREPARE\n"); - midiInUnprepareHeader((HMIDIIN)wmm->hMidi, &midiHdr, sizeof(MIDIHDR)); - TRACE("After MIDM_UNPREPARE\n"); - HeapFree(GetProcessHeap(), 0, midiHdr.lpData); - midiHdr.lpData = NULL; - wmm->dwStatus = MCI_MODE_STOP; - if (lpParms && (dwFlags & MCI_NOTIFY)) { - TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback); - mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)), - wmm->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL); - } - return 0; -} - /************************************************************************** * MIDI_mciPause [internal] */ -static DWORD MIDI_mciPause(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms) +static DWORD MIDI_mciPause(WINE_MCIMIDI* wmm, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms) { - WINE_MCIMIDI* wmm = MIDI_mciGetOpenDev(wDevID); - - TRACE("(%04X, %08X, %p);\n", wDevID, dwFlags, lpParms); - - if (wmm == NULL) return MCIERR_INVALID_DEVICE_ID; + TRACE("(%d, %08X, %p);\n", wmm->wDevID, dwFlags, lpParms); if (wmm->dwStatus == MCI_MODE_PLAY) { /* stop all notes */ @@ -1262,49 +1202,35 @@ static DWORD MIDI_mciPause(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpPar midiOutShortMsg((HMIDIOUT)(wmm->hMidi), 0x78B0 | chn); wmm->dwStatus = MCI_MODE_PAUSE; } - if (lpParms && (dwFlags & MCI_NOTIFY)) { - TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback); - mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)), - wmm->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL); - } - + if ((dwFlags & MCI_NOTIFY) && lpParms) + MIDI_mciNotify(lpParms->dwCallback, wmm, MCI_NOTIFY_SUCCESSFUL); return 0; } /************************************************************************** * MIDI_mciResume [internal] */ -static DWORD MIDI_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms) +static DWORD MIDI_mciResume(WINE_MCIMIDI* wmm, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms) { - WINE_MCIMIDI* wmm = MIDI_mciGetOpenDev(wDevID); - - TRACE("(%04X, %08X, %p);\n", wDevID, dwFlags, lpParms); - - if (wmm == NULL) return MCIERR_INVALID_DEVICE_ID; + TRACE("(%d, %08X, %p);\n", wmm->wDevID, dwFlags, lpParms); if (wmm->dwStatus == MCI_MODE_PAUSE) { wmm->wStartedPlaying = FALSE; wmm->dwStatus = MCI_MODE_PLAY; } - if (lpParms && (dwFlags & MCI_NOTIFY)) { - TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback); - mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)), - wmm->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL); - } + if ((dwFlags & MCI_NOTIFY) && lpParms) + MIDI_mciNotify(lpParms->dwCallback, wmm, MCI_NOTIFY_SUCCESSFUL); return 0; } /************************************************************************** * MIDI_mciSet [internal] */ -static DWORD MIDI_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_SEQ_SET_PARMS lpParms) +static DWORD MIDI_mciSet(WINE_MCIMIDI* wmm, DWORD dwFlags, LPMCI_SEQ_SET_PARMS lpParms) { - WINE_MCIMIDI* wmm = MIDI_mciGetOpenDev(wDevID); - - TRACE("(%04X, %08X, %p);\n", wDevID, dwFlags, lpParms); + TRACE("(%d, %08X, %p);\n", wmm->wDevID, dwFlags, lpParms); if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; - if (wmm == NULL) return MCIERR_INVALID_DEVICE_ID; if (dwFlags & MCI_SET_TIME_FORMAT) { switch (lpParms->dwTimeFormat) { @@ -1377,21 +1303,21 @@ static DWORD MIDI_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_SEQ_SET_PARMS lpParms } if (dwFlags & MCI_SEQ_SET_TEMPO) TRACE("MCI_SEQ_SET_TEMPO !\n"); + if (dwFlags & MCI_NOTIFY) + MIDI_mciNotify(lpParms->dwCallback, wmm, MCI_NOTIFY_SUCCESSFUL); return 0; } /************************************************************************** * MIDI_mciStatus [internal] */ -static DWORD MIDI_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms) +static DWORD MIDI_mciStatus(WINE_MCIMIDI* wmm, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms) { - WINE_MCIMIDI* wmm = MIDI_mciGetOpenDev(wDevID); DWORD ret = 0; - TRACE("(%04X, %08X, %p);\n", wDevID, dwFlags, lpParms); + TRACE("(%d, %08X, %p);\n", wmm->wDevID, dwFlags, lpParms); if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; - if (wmm == NULL) return MCIERR_INVALID_DEVICE_ID; if (dwFlags & MCI_STATUS_ITEM) { switch (lpParms->dwItem) { @@ -1493,27 +1419,22 @@ static DWORD MIDI_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpPar WARN("No Status-Item!\n"); return MCIERR_UNRECOGNIZED_COMMAND; } - if (dwFlags & MCI_NOTIFY) { - TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback); - mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)), - wmm->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL); - } + if ((dwFlags & MCI_NOTIFY) && HRESULT_CODE(ret)==0) + MIDI_mciNotify(lpParms->dwCallback, wmm, MCI_NOTIFY_SUCCESSFUL); return ret; } /************************************************************************** * MIDI_mciGetDevCaps [internal] */ -static DWORD MIDI_mciGetDevCaps(UINT wDevID, DWORD dwFlags, +static DWORD MIDI_mciGetDevCaps(WINE_MCIMIDI* wmm, DWORD dwFlags, LPMCI_GETDEVCAPS_PARMS lpParms) { - WINE_MCIMIDI* wmm = MIDI_mciGetOpenDev(wDevID); DWORD ret; - TRACE("(%04X, %08X, %p);\n", wDevID, dwFlags, lpParms); + TRACE("(%d, %08X, %p);\n", wmm->wDevID, dwFlags, lpParms); if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; - if (wmm == NULL) return MCIERR_INVALID_DEVICE_ID; if (dwFlags & MCI_GETDEVCAPS_ITEM) { switch (lpParms->dwItem) { @@ -1554,7 +1475,7 @@ static DWORD MIDI_mciGetDevCaps(UINT wDevID, DWORD dwFlags, break; case MCI_GETDEVCAPS_CAN_RECORD: TRACE("MCI_GETDEVCAPS_CAN_RECORD !\n"); - lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE); + lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); ret = MCI_RESOURCE_RETURNED; break; case MCI_GETDEVCAPS_CAN_SAVE: @@ -1570,24 +1491,24 @@ static DWORD MIDI_mciGetDevCaps(UINT wDevID, DWORD dwFlags, WARN("No GetDevCaps-Item !\n"); return MCIERR_UNRECOGNIZED_COMMAND; } + if ((dwFlags & MCI_NOTIFY) && HRESULT_CODE(ret)==0) + MIDI_mciNotify(lpParms->dwCallback, wmm, MCI_NOTIFY_SUCCESSFUL); return ret; } /************************************************************************** * MIDI_mciInfo [internal] */ -static DWORD MIDI_mciInfo(UINT wDevID, DWORD dwFlags, LPMCI_INFO_PARMSW lpParms) +static DWORD MIDI_mciInfo(WINE_MCIMIDI* wmm, DWORD dwFlags, LPMCI_INFO_PARMSW lpParms) { LPCWSTR str = 0; - WINE_MCIMIDI* wmm = MIDI_mciGetOpenDev(wDevID); DWORD ret = 0; static const WCHAR wszMidiSeq[] = {'W','i','n','e','\'','s',' ','M','I','D','I',' ','s','e','q','u','e','n','c','e','r',0}; - TRACE("(%04X, %08X, %p);\n", wDevID, dwFlags, lpParms); + TRACE("(%d, %08X, %p);\n", wmm->wDevID, dwFlags, lpParms); if (lpParms == NULL || lpParms->lpstrReturn == NULL) return MCIERR_NULL_PARAMETER_BLOCK; - if (wmm == NULL) return MCIERR_INVALID_DEVICE_ID; TRACE("buf=%p, len=%u\n", lpParms->lpstrReturn, lpParms->dwRetSize); @@ -1600,35 +1521,32 @@ static DWORD MIDI_mciInfo(UINT wDevID, DWORD dwFlags, LPMCI_INFO_PARMSW lpParms) WARN("Don't know this info command (%u)\n", dwFlags); return MCIERR_UNRECOGNIZED_COMMAND; } - if (str) { - if (lpParms->dwRetSize <= strlenW(str)) { - lstrcpynW(lpParms->lpstrReturn, str, lpParms->dwRetSize - 1); - ret = MCIERR_PARAM_OVERFLOW; - } else { - strcpyW(lpParms->lpstrReturn, str); - } - } else { - *lpParms->lpstrReturn = 0; + if (!ret) { + if (lpParms->dwRetSize) { + WCHAR zero = 0; + /* FIXME? Since NT, mciwave, mciseq and mcicda set dwRetSize + * to the number of characters written, excluding \0. */ + lstrcpynW(lpParms->lpstrReturn, str ? str : &zero, lpParms->dwRetSize); + } else ret = MCIERR_PARAM_OVERFLOW; } + if (MMSYSERR_NOERROR==ret && (dwFlags & MCI_NOTIFY)) + MIDI_mciNotify(lpParms->dwCallback, wmm, MCI_NOTIFY_SUCCESSFUL); return ret; } /************************************************************************** * MIDI_mciSeek [internal] */ -static DWORD MIDI_mciSeek(UINT wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms) +static DWORD MIDI_mciSeek(WINE_MCIMIDI* wmm, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms) { DWORD ret = 0; - WINE_MCIMIDI* wmm = MIDI_mciGetOpenDev(wDevID); - TRACE("(%04X, %08X, %p);\n", wDevID, dwFlags, lpParms); + TRACE("(%d, %08X, %p);\n", wmm->wDevID, dwFlags, lpParms); if (lpParms == NULL) { ret = MCIERR_NULL_PARAMETER_BLOCK; - } else if (wmm == NULL) { - ret = MCIERR_INVALID_DEVICE_ID; } else { - MIDI_mciStop(wDevID, MCI_WAIT, 0); + MIDI_mciStop(wmm, MCI_WAIT, 0); if (dwFlags & MCI_SEEK_TO_START) { wmm->dwPositionMS = 0; @@ -1643,11 +1561,8 @@ static DWORD MIDI_mciSeek(UINT wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms) TRACE("Seeking to position=%u ms\n", wmm->dwPositionMS); - if (dwFlags & MCI_NOTIFY) { - TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback); - mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)), - wmm->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL); - } + if (dwFlags & MCI_NOTIFY) + MIDI_mciNotify(lpParms->dwCallback, wmm, MCI_NOTIFY_SUCCESSFUL); } return ret; } @@ -1662,6 +1577,7 @@ static DWORD MIDI_mciSeek(UINT wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms) LRESULT CALLBACK MCIMIDI_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg, LPARAM dwParam1, LPARAM dwParam2) { + WINE_MCIMIDI* wmm; switch (wMsg) { case DRV_LOAD: return 1; case DRV_FREE: return 1; @@ -1674,51 +1590,32 @@ LRESULT CALLBACK MCIMIDI_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg, case DRV_OPEN: return MIDI_drvOpen((LPCWSTR)dwParam1, (LPMCI_OPEN_DRIVER_PARMSW)dwParam2); case DRV_CLOSE: return MIDI_drvClose(dwDevID); } + if ((wMsg < DRV_MCI_FIRST) || (wMsg > DRV_MCI_LAST)) { + TRACE("Sending msg %04x to default driver proc\n", wMsg); + return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2); + } - if (dwDevID == 0xFFFFFFFF) return MCIERR_UNSUPPORTED_FUNCTION; + wmm = MIDI_mciGetOpenDev(dwDevID, wMsg); + if (wmm == NULL) return MCIERR_INVALID_DEVICE_ID; switch (wMsg) { - case MCI_OPEN_DRIVER: return MIDI_mciOpen (dwDevID, dwParam1, (LPMCI_OPEN_PARMSW) dwParam2); - case MCI_CLOSE_DRIVER: return MIDI_mciClose (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2); - case MCI_PLAY: return MIDI_mciPlay (dwDevID, dwParam1, (LPMCI_PLAY_PARMS) dwParam2); - case MCI_RECORD: return MIDI_mciRecord (dwDevID, dwParam1, (LPMCI_RECORD_PARMS) dwParam2); - case MCI_STOP: return MIDI_mciStop (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2); - case MCI_SET: return MIDI_mciSet (dwDevID, dwParam1, (LPMCI_SEQ_SET_PARMS) dwParam2); - case MCI_PAUSE: return MIDI_mciPause (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2); - case MCI_RESUME: return MIDI_mciResume (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2); - case MCI_STATUS: return MIDI_mciStatus (dwDevID, dwParam1, (LPMCI_STATUS_PARMS) dwParam2); - case MCI_GETDEVCAPS: return MIDI_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS)dwParam2); - case MCI_INFO: return MIDI_mciInfo (dwDevID, dwParam1, (LPMCI_INFO_PARMSW) dwParam2); - case MCI_SEEK: return MIDI_mciSeek (dwDevID, dwParam1, (LPMCI_SEEK_PARMS) dwParam2); - /* commands that should be supported */ - case MCI_LOAD: - case MCI_SAVE: - case MCI_FREEZE: - case MCI_PUT: - case MCI_REALIZE: - case MCI_UNFREEZE: - case MCI_UPDATE: - case MCI_WHERE: - case MCI_STEP: - case MCI_SPIN: - case MCI_ESCAPE: - case MCI_COPY: - case MCI_CUT: - case MCI_DELETE: - case MCI_PASTE: - WARN("Unsupported command [%u]\n", wMsg); - break; - /* commands that should report an error */ - case MCI_WINDOW: - TRACE("Unsupported command [%u]\n", wMsg); - break; + case MCI_OPEN_DRIVER: return MIDI_mciOpen (wmm, dwParam1, (LPMCI_OPEN_PARMSW) dwParam2); + case MCI_CLOSE_DRIVER: return MIDI_mciClose (wmm, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2); + case MCI_PLAY: return MIDI_mciPlay (wmm, dwParam1, (LPMCI_PLAY_PARMS) dwParam2); + case MCI_STOP: return MIDI_mciStop (wmm, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2); + case MCI_SET: return MIDI_mciSet (wmm, dwParam1, (LPMCI_SEQ_SET_PARMS) dwParam2); + case MCI_PAUSE: return MIDI_mciPause (wmm, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2); + case MCI_RESUME: return MIDI_mciResume (wmm, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2); + case MCI_STATUS: return MIDI_mciStatus (wmm, dwParam1, (LPMCI_STATUS_PARMS) dwParam2); + case MCI_GETDEVCAPS: return MIDI_mciGetDevCaps(wmm, dwParam1, (LPMCI_GETDEVCAPS_PARMS)dwParam2); + case MCI_INFO: return MIDI_mciInfo (wmm, dwParam1, (LPMCI_INFO_PARMSW) dwParam2); + case MCI_SEEK: return MIDI_mciSeek (wmm, dwParam1, (LPMCI_SEEK_PARMS) dwParam2); case MCI_OPEN: case MCI_CLOSE: FIXME("Shouldn't receive a MCI_OPEN or CLOSE message\n"); - break; + /* fall through */ default: - TRACE("Sending msg [%u] to default driver proc\n", wMsg); - return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2); + TRACE("Unsupported command [0x%x]\n", wMsg); + return MCIERR_UNSUPPORTED_FUNCTION; /* Win9x: MCIERR_UNRECOGNIZED_COMMAND */ } - return MCIERR_UNRECOGNIZED_COMMAND; } diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index 56d163b4a89..f255446c5cc 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -86,7 +86,7 @@ reactos/dll/win32/mapi32 # Autosync reactos/dll/win32/mciavi32 # Synced to Wine-1.3.37 reactos/dll/win32/mcicda # Synced to Wine-1.3.37 reactos/dll/win32/mciqtz32 # Autosync -reactos/dll/win32/mciseq # Autosync +reactos/dll/win32/mciseq # Synced to Wine-1.3.37 reactos/dll/win32/mciwave # Autosync reactos/dll/win32/mlang # Autosync reactos/dll/win32/mpr # Autosync