Hello, Please apply after MCI #4. Changelog: Dmitry Timoshkov <dmitry@xxxxxxxxxxxxxxx> Much improved mciavi driver. Fixed synchronization, RIFF file with many streams parsing, added support for some MCI_PUT and MCI_WHERE cases. diff -u cvs/hq/wine/dlls/winmm/mciavi/info.c wine/dlls/winmm/mciavi/info.c --- cvs/hq/wine/dlls/winmm/mciavi/info.c 2003-12-30 22:44:20.000000000 +0800 +++ wine/dlls/winmm/mciavi/info.c 2003-12-30 23:28:23.000000000 +0800 @@ -82,6 +82,8 @@ DWORD MCIAVI_mciGetDevCaps(UINT wDevID, if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; + EnterCriticalSection(&wma->cs); + if (dwFlags & MCI_GETDEVCAPS_ITEM) { switch (lpParms->dwItem) { case MCI_GETDEVCAPS_DEVICE_TYPE: @@ -131,12 +133,15 @@ DWORD MCIAVI_mciGetDevCaps(UINT wDevID, break; default: FIXME("Unknown capability (%08lx) !\n", lpParms->dwItem); - return MCIERR_UNRECOGNIZED_COMMAND; + ret = MCIERR_UNRECOGNIZED_COMMAND; + break; } } else { WARN("No GetDevCaps-Item !\n"); - return MCIERR_UNRECOGNIZED_COMMAND; + ret = MCIERR_UNRECOGNIZED_COMMAND; } + + LeaveCriticalSection(&wma->cs); return ret; } @@ -155,15 +160,18 @@ DWORD MCIAVI_mciInfo(UINT wDevID, DWORD TRACE("buf=%p, len=%lu\n", lpParms->lpstrReturn, lpParms->dwRetSize); + EnterCriticalSection(&wma->cs); + switch (dwFlags) { case MCI_INFO_PRODUCT: str = "Wine's AVI player"; break; case MCI_INFO_FILE: - str = wma->openParms.lpstrElementName; + str = wma->lpFileName; break; default: WARN("Don't know this info command (%lu)\n", dwFlags); + LeaveCriticalSection(&wma->cs); return MCIERR_UNRECOGNIZED_COMMAND; } if (str) { @@ -175,6 +183,8 @@ DWORD MCIAVI_mciInfo(UINT wDevID, DWORD } else { lpParms->lpstrReturn[0] = 0; } + + LeaveCriticalSection(&wma->cs); return ret; } @@ -188,6 +198,8 @@ DWORD MCIAVI_mciSet(UINT wDevID, DWORD d if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; + EnterCriticalSection(&wma->cs); + if (dwFlags & MCI_SET_TIME_FORMAT) { switch (lpParms->dwTimeFormat) { case MCI_FORMAT_MILLISECONDS: @@ -200,18 +212,22 @@ DWORD MCIAVI_mciSet(UINT wDevID, DWORD d break; default: WARN("Bad time format %lu!\n", lpParms->dwTimeFormat); + LeaveCriticalSection(&wma->cs); return MCIERR_BAD_TIME_FORMAT; } } if (dwFlags & MCI_SET_DOOR_OPEN) { TRACE("No support for door open !\n"); + LeaveCriticalSection(&wma->cs); return MCIERR_UNSUPPORTED_FUNCTION; } if (dwFlags & MCI_SET_DOOR_CLOSED) { TRACE("No support for door close !\n"); + LeaveCriticalSection(&wma->cs); return MCIERR_UNSUPPORTED_FUNCTION; } + if (dwFlags & MCI_SET_ON) { char buffer[256]; @@ -302,6 +318,7 @@ DWORD MCIAVI_mciSet(UINT wDevID, DWORD d FIXME("Setting speed to %ld\n", lpParms->dwSpeed); } + LeaveCriticalSection(&wma->cs); return 0; } @@ -316,6 +333,8 @@ DWORD MCIAVI_mciStatus(UINT wDevID, DWOR if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; + EnterCriticalSection(&wma->cs); + if (dwFlags & MCI_STATUS_ITEM) { switch (lpParms->dwItem) { case MCI_STATUS_CURRENT_TRACK: @@ -325,6 +344,7 @@ DWORD MCIAVI_mciStatus(UINT wDevID, DWOR case MCI_STATUS_LENGTH: if (!wma->hFile) { lpParms->dwReturn = 0; + LeaveCriticalSection(&wma->cs); return MCIERR_UNSUPPORTED_FUNCTION; } /* only one track in file is currently handled, so don't take care of MCI_TRACK flag */ @@ -334,7 +354,7 @@ DWORD MCIAVI_mciStatus(UINT wDevID, DWOR case MCI_STATUS_MODE: lpParms->dwReturn = MAKEMCIRESOURCE(wma->dwStatus, wma->dwStatus); ret = MCI_RESOURCE_RETURNED; - TRACE("MCI_STATUS_MODE => %u\n", LOWORD(lpParms->dwReturn)); + TRACE("MCI_STATUS_MODE => 0x%04x\n", LOWORD(lpParms->dwReturn)); break; case MCI_STATUS_MEDIA_PRESENT: TRACE("MCI_STATUS_MEDIA_PRESENT => TRUE\n"); @@ -348,6 +368,7 @@ DWORD MCIAVI_mciStatus(UINT wDevID, DWOR case MCI_STATUS_POSITION: if (!wma->hFile) { lpParms->dwReturn = 0; + LeaveCriticalSection(&wma->cs); return MCIERR_UNSUPPORTED_FUNCTION; } /* only one track in file is currently handled, so don't take care of MCI_TRACK flag */ @@ -401,7 +422,7 @@ DWORD MCIAVI_mciStatus(UINT wDevID, DWOR TRACE("MCI_DGV_STATUS_HPAL => %lx\n", lpParms->dwReturn); break; case MCI_DGV_STATUS_HWND: - lpParms->dwReturn = (DWORD)wma->hWndPaint; + lpParms->dwReturn = (DWORD_PTR)wma->hWndPaint; TRACE("MCI_DGV_STATUS_HWND => %p\n", wma->hWndPaint); break; #if 0 @@ -436,17 +457,20 @@ DWORD MCIAVI_mciStatus(UINT wDevID, DWOR default: FIXME("Unknowm command %08lX !\n", lpParms->dwItem); TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpParms); + LeaveCriticalSection(&wma->cs); return MCIERR_UNRECOGNIZED_COMMAND; } } else { WARN("No Status-Item!\n"); + LeaveCriticalSection(&wma->cs); return MCIERR_UNRECOGNIZED_COMMAND; } + if (dwFlags & MCI_NOTIFY) { TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback); mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)), - wma->openParms.wDeviceID, MCI_NOTIFY_SUCCESSFUL); + wDevID, MCI_NOTIFY_SUCCESSFUL); } - + LeaveCriticalSection(&wma->cs); return ret; } diff -u cvs/hq/wine/dlls/winmm/mciavi/mciavi.c wine/dlls/winmm/mciavi/mciavi.c --- cvs/hq/wine/dlls/winmm/mciavi/mciavi.c 2003-12-30 22:44:20.000000000 +0800 +++ wine/dlls/winmm/mciavi/mciavi.c 2003-12-30 23:28:23.000000000 +0800 @@ -4,6 +4,7 @@ * Digital video MCI Wine Driver * * Copyright 1999, 2000 Eric POUECH + * Copyright 2003 Dmitry Timoshkov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -26,24 +27,25 @@ * - lots of messages still need to be handled (cf FIXME) * - synchronization between audio and video (especially for interleaved * files) - * - synchronization (as in all the Wine MCI drivers (MCI_WAIT) messages) * - robustness when reading file can be enhanced * - better move the AVI handling part to avifile DLL and make use of it * - some files appear to have more than one audio stream (we only play the * first one) * - some files contain an index of audio/video frame. Better use it, * instead of rebuilding it - * - mciWindow (for setting the hWnd) is broken with media player * - stopping while playing a file with sound blocks until all buffered * audio is played... still should be stopped ASAP */ +#include <assert.h> #include <string.h> #include "private_mciavi.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(mciavi); +static DWORD MCIAVI_mciStop(UINT, DWORD, LPMCI_GENERIC_PARMS); + /* =================================================================== * =================================================================== * FIXME: should be using the new mmThreadXXXX functions from WINMM @@ -54,10 +56,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(mciavi); * =================================================================== */ struct SCA { - UINT wDevID; - UINT wMsg; - DWORD dwParam1; - DWORD dwParam2; + MCIDEVICEID wDevID; + UINT wMsg; + DWORD_PTR dwParam1; + DWORD_PTR dwParam2; }; /************************************************************************** @@ -68,15 +70,15 @@ static DWORD CALLBACK MCI_SCAStarter(LPV struct SCA* sca = (struct SCA*)arg; DWORD ret; - TRACE("In thread before async command (%08x,%u,%08lx,%08lx)\n", + TRACE("In thread before async command (%08x,%04x,%08lx,%08lx)\n", sca->wDevID, sca->wMsg, sca->dwParam1, sca->dwParam2); ret = mciSendCommandA(sca->wDevID, sca->wMsg, sca->dwParam1 | MCI_WAIT, sca->dwParam2); - TRACE("In thread after async command (%08x,%u,%08lx,%08lx)\n", + TRACE("In thread after async command (%08x,%04x,%08lx,%08lx)\n", sca->wDevID, sca->wMsg, sca->dwParam1, sca->dwParam2); HeapFree(GetProcessHeap(), 0, sca); ExitThread(ret); - WARN("Should not happen ? what's wrong \n"); /* should not go after this point */ + assert(0); return ret; } @@ -84,7 +86,7 @@ static DWORD CALLBACK MCI_SCAStarter(LPV * MCI_SendCommandAsync [internal] */ static DWORD MCI_SendCommandAsync(UINT wDevID, UINT wMsg, DWORD dwParam1, - DWORD dwParam2, UINT size) + DWORD_PTR dwParam2, UINT size) { struct SCA* sca = HeapAlloc(GetProcessHeap(), 0, sizeof(struct SCA) + size); @@ -96,7 +98,7 @@ static DWORD MCI_SendCommandAsync(UINT w sca->dwParam1 = dwParam1; if (size && dwParam2) { - sca->dwParam2 = (DWORD)sca + sizeof(struct SCA); + sca->dwParam2 = (DWORD_PTR)sca + sizeof(struct SCA); /* copy structure passed by program in dwParam2 to be sure * we can still use it whatever the program does */ @@ -137,17 +139,22 @@ static DWORD MCIAVI_drvOpen(LPSTR str, L WINE_MCIAVI* wma; static const WCHAR mciAviWStr[] = {'M','C','I','A','V','I',0}; + TRACE("%s, %p\n", debugstr_a(str), modp); + + /* session instance */ if (!modp) return 0xFFFFFFFF; wma = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_MCIAVI)); if (!wma) return 0; + InitializeCriticalSection(&wma->cs); wma->wDevID = modp->wDeviceID; - mciSetDriverData(wma->wDevID, (DWORD)wma); wma->wCommandTable = mciLoadCommandResource(MCIAVI_hInstance, mciAviWStr, 0); modp->wCustomCommandTable = wma->wCommandTable; modp->wType = MCI_DEVTYPE_DIGITAL_VIDEO; + mciSetDriverData(wma->wDevID, (DWORD)wma); + return modp->wDeviceID; } @@ -156,11 +163,24 @@ static DWORD MCIAVI_drvOpen(LPSTR str, L */ static DWORD MCIAVI_drvClose(DWORD dwDevID) { - WINE_MCIAVI* wma = (WINE_MCIAVI*)mciGetDriverData(dwDevID); + WINE_MCIAVI *wma; + + TRACE("%04lx\n", dwDevID); + + /* finish all outstanding things */ + MCIAVI_mciClose(dwDevID, MCI_WAIT, NULL); + + wma = (WINE_MCIAVI*)mciGetDriverData(dwDevID); if (wma) { + EnterCriticalSection(&wma->cs); + mciSetDriverData(dwDevID, 0); mciFreeCommandResource(wma->wCommandTable); + + LeaveCriticalSection(&wma->cs); + DeleteCriticalSection(&wma->cs); + HeapFree(GetProcessHeap(), 0, wma); return 1; } @@ -172,7 +192,13 @@ static DWORD MCIAVI_drvClose(DWORD dwDev */ static DWORD MCIAVI_drvConfigure(DWORD dwDevID) { - WINE_MCIAVI* wma = (WINE_MCIAVI*)mciGetDriverData(dwDevID); + WINE_MCIAVI *wma; + + TRACE("%04lx\n", dwDevID); + + MCIAVI_mciStop(dwDevID, MCI_WAIT, NULL); + + wma = (WINE_MCIAVI*)mciGetDriverData(dwDevID); if (wma) { MessageBoxA(0, "Sample AVI Wine Driver !", "MM-Wine Driver", MB_OK); @@ -202,6 +228,10 @@ static void MCIAVI_CleanUp(WINE_MCIAVI* if (wma->hFile) { mmioClose(wma->hFile, 0); wma->hFile = 0; + + if (wma->lpFileName) HeapFree(GetProcessHeap(), 0, wma->lpFileName); + wma->lpFileName = NULL; + if (wma->lpVideoIndex) HeapFree(GetProcessHeap(), 0, wma->lpVideoIndex); wma->lpVideoIndex = NULL; if (wma->lpAudioIndex) HeapFree(GetProcessHeap(), 0, wma->lpAudioIndex); @@ -231,22 +261,26 @@ static void MCIAVI_CleanUp(WINE_MCIAVI* } } -static DWORD MCIAVI_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms); - /*************************************************************************** * MCIAVI_mciOpen [internal] */ static DWORD MCIAVI_mciOpen(UINT wDevID, DWORD dwFlags, LPMCI_DGV_OPEN_PARMSA lpOpenParms) { - WINE_MCIAVI* wma = (WINE_MCIAVI*)mciGetDriverData(wDevID); + WINE_MCIAVI *wma; LRESULT dwRet = 0; TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpOpenParms); + MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); + if (lpOpenParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + + wma = (WINE_MCIAVI *)mciGetDriverData(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; + EnterCriticalSection(&wma->cs); + if (wma->nUseCount > 0) { /* The driver is already open on this channel */ /* If the driver was opened shareable before and this open specifies */ @@ -254,14 +288,16 @@ static DWORD MCIAVI_mciOpen(UINT wDevID, if (wma->fShareable && (dwFlags & MCI_OPEN_SHAREABLE)) ++wma->nUseCount; else + { + LeaveCriticalSection(&wma->cs); return MCIERR_MUST_USE_SHAREABLE; + } } else { wma->nUseCount = 1; wma->fShareable = dwFlags & MCI_OPEN_SHAREABLE; } wma->dwStatus = MCI_MODE_NOT_READY; - InitializeCriticalSection(&wma->cs); if (dwFlags & MCI_OPEN_ELEMENT) { if (dwFlags & MCI_OPEN_ELEMENT_ID) { @@ -273,7 +309,11 @@ static DWORD MCIAVI_mciOpen(UINT wDevID, /* FIXME : what should be done id wma->hFile is already != 0, or the driver is playin' */ TRACE("MCI_OPEN_ELEMENT '%s' !\n", lpOpenParms->lpstrElementName); - if (lpOpenParms->lpstrElementName && (strlen(lpOpenParms->lpstrElementName) > 0)) { + if (lpOpenParms->lpstrElementName && (strlen(lpOpenParms->lpstrElementName) > 0)) + { + wma->lpFileName = HeapAlloc(GetProcessHeap(), 0, strlen(lpOpenParms->lpstrElementName) + 1); + strcpy(wma->lpFileName, lpOpenParms->lpstrElementName); + wma->hFile = mmioOpenA(lpOpenParms->lpstrElementName, NULL, MMIO_ALLOCBUF | MMIO_DENYWRITE | MMIO_READWRITE); @@ -295,44 +335,52 @@ static DWORD MCIAVI_mciOpen(UINT wDevID, } } - memcpy(&wma->openParms, lpOpenParms, sizeof(MCI_WAVE_OPEN_PARMSA)); - if (dwRet == 0) { + TRACE("lpOpenParms->wDeviceID = %04x\n", lpOpenParms->wDeviceID); + wma->dwStatus = MCI_MODE_STOP; wma->dwMciTimeFormat = MCI_FORMAT_FRAMES; } else { MCIAVI_CleanUp(wma); } - return dwRet; + LeaveCriticalSection(&wma->cs); + return dwRet; } /*************************************************************************** * MCIAVI_mciClose [internal] */ -static DWORD MCIAVI_mciClose(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms) +DWORD MCIAVI_mciClose(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms) { - WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID); + WINE_MCIAVI *wma; DWORD dwRet = 0; TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpParms); + MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); + + wma = (WINE_MCIAVI *)MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; + EnterCriticalSection(&wma->cs); + if (wma->nUseCount == 1) { if (wma->dwStatus != MCI_MODE_STOP) - dwRet = MCIAVI_mciStop(wDevID, MCI_WAIT, lpParms); + dwRet = MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); MCIAVI_CleanUp(wma); if ((dwFlags & MCI_NOTIFY) && lpParms) { mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)), - wma->openParms.wDeviceID, + wDevID, MCI_NOTIFY_SUCCESSFUL); } - HeapFree(GetProcessHeap(), 0, wma); + LeaveCriticalSection(&wma->cs); return dwRet; } wma->nUseCount--; + + LeaveCriticalSection(&wma->cs); return dwRet; } @@ -341,7 +389,7 @@ static DWORD MCIAVI_mciClose(UINT wDevID */ static DWORD MCIAVI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms) { - WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID); + WINE_MCIAVI *wma; DWORD tc; DWORD frameTime; DWORD delta; @@ -353,19 +401,34 @@ static DWORD MCIAVI_mciPlay(UINT wDevID, TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpParms); if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + + wma = (WINE_MCIAVI *)MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; - if (!wma->hFile) return MCIERR_FILE_NOT_FOUND; - if (!wma->hWndPaint) return MCIERR_NO_WINDOW; + EnterCriticalSection(&wma->cs); + + if (!wma->hFile) + { + LeaveCriticalSection(&wma->cs); + return MCIERR_FILE_NOT_FOUND; + } + if (!wma->hWndPaint) + { + LeaveCriticalSection(&wma->cs); + return MCIERR_NO_WINDOW; + } wma->dwStatus = MCI_MODE_PLAY; + LeaveCriticalSection(&wma->cs); if (!(dwFlags & MCI_WAIT)) { - return MCI_SendCommandAsync(wma->openParms.wDeviceID, MCI_PLAY, dwFlags, - (DWORD)lpParms, sizeof(MCI_PLAY_PARMS)); + return MCI_SendCommandAsync(wDevID, MCI_PLAY, dwFlags, + (DWORD_PTR)lpParms, sizeof(MCI_PLAY_PARMS)); } - ShowWindow(wma->hWndPaint, SW_SHOW); + ShowWindow(wma->hWndPaint, SW_SHOWNA); + + EnterCriticalSection(&wma->cs); dwFromFrame = wma->dwCurrVideoFrame; dwToFrame = wma->dwPlayableVideoFrames - 1; @@ -381,10 +444,14 @@ static DWORD MCIAVI_mciPlay(UINT wDevID, TRACE("Playing from frame=%lu to frame=%lu\n", dwFromFrame, dwToFrame); - if (dwToFrame <= wma->dwCurrVideoFrame) - return TRUE; wma->dwCurrVideoFrame = dwFromFrame; + if (dwToFrame <= wma->dwCurrVideoFrame) + { + dwRet = 0; + goto mci_play_done; + } + if (dwFlags & (MCI_DGV_PLAY_REPEAT|MCI_DGV_PLAY_REVERSE|MCI_MCIAVI_PLAY_WINDOW|MCI_MCIAVI_PLAY_FULLSCREEN)) FIXME("Unsupported flag %08lx\n", dwFlags); @@ -392,13 +459,19 @@ static DWORD MCIAVI_mciPlay(UINT wDevID, frameTime = (wma->mah.dwMicroSecPerFrame + 500) / 1000; if (wma->lpWaveFormat) { - if ((dwRet = MCIAVI_OpenAudio(wma, &nHdr, &waveHdr)) != 0) - goto cleanUp; + if (MCIAVI_OpenAudio(wma, &nHdr, &waveHdr) != 0) + { + /* can't play audio */ + HeapFree(GetProcessHeap(), 0, wma->lpWaveFormat); + wma->lpWaveFormat = NULL; + } + else /* fill the queue with as many wave headers as possible */ MCIAVI_PlayAudioBlocks(wma, nHdr, waveHdr); } - while (wma->dwStatus != MCI_MODE_STOP && wma->dwStatus != MCI_MODE_NOT_READY) { + while (wma->dwStatus == MCI_MODE_PLAY) + { tc = GetTickCount(); MCIAVI_DrawFrame(wma); @@ -406,23 +479,36 @@ static DWORD MCIAVI_mciPlay(UINT wDevID, if (wma->lpWaveFormat) { MCIAVI_PlayAudioBlocks(wma, nHdr, waveHdr); delta = GetTickCount() - tc; - WaitForSingleObject(wma->hEvent, (delta >= frameTime) ? 0 : frameTime - delta); + + LeaveCriticalSection(&wma->cs); + MsgWaitForMultipleObjects(1, &wma->hEvent, FALSE, + (delta >= frameTime) ? 0 : frameTime - delta, MWMO_INPUTAVAILABLE); + EnterCriticalSection(&wma->cs); + + if (wma->dwStatus != MCI_MODE_PLAY) break; } delta = GetTickCount() - tc; if (delta < frameTime) - Sleep(frameTime - delta); - - if (wma->dwCurrVideoFrame++ >= dwToFrame) { - wma->dwCurrVideoFrame--; - wma->dwStatus = MCI_MODE_STOP; - } + { + LeaveCriticalSection(&wma->cs); + MsgWaitForMultipleObjects(0, NULL, FALSE, frameTime - delta, MWMO_INPUTAVAILABLE); + EnterCriticalSection(&wma->cs); + } + + if (wma->dwCurrVideoFrame < dwToFrame) + wma->dwCurrVideoFrame++; + else + break; } if (wma->lpWaveFormat) { - while (*(volatile DWORD*)&wma->dwEventCount != nHdr - 1) { - Sleep(100); - } + while (wma->dwEventCount != nHdr - 1) + { + LeaveCriticalSection(&wma->cs); + Sleep(100); + EnterCriticalSection(&wma->cs); + } /* just to get rid of some race conditions between play, stop and pause */ waveOutReset(wma->hWave); @@ -432,7 +518,7 @@ static DWORD MCIAVI_mciPlay(UINT wDevID, } dwRet = 0; -cleanUp: + if (wma->lpWaveFormat) { HeapFree(GetProcessHeap(), 0, waveHdr); @@ -443,14 +529,15 @@ cleanUp: CloseHandle(wma->hEvent); } +mci_play_done: + wma->dwStatus = MCI_MODE_STOP; + if (lpParms && (dwFlags & MCI_NOTIFY)) { TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback); mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)), - wma->openParms.wDeviceID, MCI_NOTIFY_SUCCESSFUL); + wDevID, MCI_NOTIFY_SUCCESSFUL); } - - wma->dwStatus = MCI_MODE_STOP; - + LeaveCriticalSection(&wma->cs); return dwRet; } @@ -459,14 +546,20 @@ cleanUp: */ static DWORD MCIAVI_mciRecord(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RECORD_PARMS lpParms) { - WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID); + WINE_MCIAVI *wma; FIXME("(%04x, %08lX, %p) : stub\n", wDevID, dwFlags, lpParms); + MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); + if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + + wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; + EnterCriticalSection(&wma->cs); wma->dwStatus = MCI_MODE_RECORD; + LeaveCriticalSection(&wma->cs); return 0; } @@ -475,14 +568,16 @@ static DWORD MCIAVI_mciRecord(UINT wDevI */ static DWORD MCIAVI_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms) { - WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID); + WINE_MCIAVI *wma; DWORD dwRet = 0; TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpParms); - if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; + EnterCriticalSection(&wma->cs); + switch (wma->dwStatus) { case MCI_MODE_PAUSE: case MCI_MODE_PLAY: @@ -493,19 +588,26 @@ static DWORD MCIAVI_mciStop(UINT wDevID, if (oldStat == MCI_MODE_PAUSE) dwRet = waveOutReset(wma->hWave); } - while (wma->dwStatus != MCI_MODE_STOP) - Sleep(10); - break; + /* fall through */ default: - wma->dwStatus = MCI_MODE_STOP; + do /* one more chance for an async thread to finish */ + { + LeaveCriticalSection(&wma->cs); + Sleep(10); + EnterCriticalSection(&wma->cs); + } while (wma->dwStatus != MCI_MODE_STOP); + break; + + case MCI_MODE_NOT_READY: + break; } if ((dwFlags & MCI_NOTIFY) && lpParms) { mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)), - wma->openParms.wDeviceID, MCI_NOTIFY_SUCCESSFUL); + wDevID, MCI_NOTIFY_SUCCESSFUL); } - + LeaveCriticalSection(&wma->cs); return dwRet; } @@ -514,15 +616,21 @@ static DWORD MCIAVI_mciStop(UINT wDevID, */ static DWORD MCIAVI_mciPause(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms) { - WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID); + WINE_MCIAVI *wma; + DWORD ret; - if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; + EnterCriticalSection(&wma->cs); + if (wma->dwStatus == MCI_MODE_PLAY) wma->dwStatus = MCI_MODE_PAUSE; - return (wma->lpWaveFormat) ? waveOutPause(wma->hWave) : 0; + ret = (wma->lpWaveFormat) ? waveOutPause(wma->hWave) : 0; + + LeaveCriticalSection(&wma->cs); + return ret; } /*************************************************************************** @@ -530,17 +638,23 @@ static DWORD MCIAVI_mciPause(UINT wDevID */ static DWORD MCIAVI_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms) { - WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID); + WINE_MCIAVI *wma; + DWORD ret; FIXME("(%04x, %08lX, %p) : stub\n", wDevID, dwFlags, lpParms); - if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; + EnterCriticalSection(&wma->cs); + if (wma->dwStatus == MCI_MODE_PAUSE) wma->dwStatus = MCI_MODE_PLAY; - return (wma->lpWaveFormat) ? waveOutRestart(wma->hWave) : 0; + ret = (wma->lpWaveFormat) ? waveOutRestart(wma->hWave) : 0; + + LeaveCriticalSection(&wma->cs); + return ret; } /*************************************************************************** @@ -548,17 +662,19 @@ static DWORD MCIAVI_mciResume(UINT wDevI */ static DWORD MCIAVI_mciSeek(UINT wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms) { - WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID); + WINE_MCIAVI *wma; TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpParms); + MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); + if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + + wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; EnterCriticalSection(&wma->cs); - MCIAVI_mciStop(wDevID, MCI_WAIT, 0); - if (dwFlags & MCI_SEEK_TO_START) { wma->dwCurrVideoFrame = 0; } else if (dwFlags & MCI_SEEK_TO_END) { @@ -575,11 +691,9 @@ static DWORD MCIAVI_mciSeek(UINT wDevID, if (dwFlags & MCI_NOTIFY) { mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)), - wma->openParms.wDeviceID, MCI_NOTIFY_SUCCESSFUL); + wDevID, MCI_NOTIFY_SUCCESSFUL); } - LeaveCriticalSection(&wma->cs); - return 0; } @@ -588,11 +702,15 @@ static DWORD MCIAVI_mciSeek(UINT wDevID, */ static DWORD MCIAVI_mciLoad(UINT wDevID, DWORD dwFlags, LPMCI_DGV_LOAD_PARMSA lpParms) { - WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID); + WINE_MCIAVI *wma; FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms); + MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); + if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + + wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; return 0; @@ -603,11 +721,15 @@ static DWORD MCIAVI_mciLoad(UINT wDevID, */ static DWORD MCIAVI_mciSave(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SAVE_PARMSA lpParms) { - WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID); + WINE_MCIAVI *wma; FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms); + MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); + if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + + wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; return 0; @@ -618,11 +740,15 @@ static DWORD MCIAVI_mciSave(UINT wDevID, */ static DWORD MCIAVI_mciFreeze(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RECT_PARMS lpParms) { - WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID); + WINE_MCIAVI *wma; FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms); + MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); + if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + + wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; return 0; @@ -633,11 +759,15 @@ static DWORD MCIAVI_mciFreeze(UINT wDevI */ static DWORD MCIAVI_mciRealize(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms) { - WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID); + WINE_MCIAVI *wma; FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms); + MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); + if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + + wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; return 0; @@ -648,11 +778,15 @@ static DWORD MCIAVI_mciRealize(UINT wDev */ static DWORD MCIAVI_mciUnFreeze(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RECT_PARMS lpParms) { - WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID); + WINE_MCIAVI *wma; FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms); + MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); + if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + + wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; return 0; @@ -663,11 +797,15 @@ static DWORD MCIAVI_mciUnFreeze(UINT wDe */ static DWORD MCIAVI_mciUpdate(UINT wDevID, DWORD dwFlags, LPMCI_DGV_UPDATE_PARMS lpParms) { - WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID); + WINE_MCIAVI *wma; FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms); + MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); + if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + + wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; return 0; @@ -678,11 +816,15 @@ static DWORD MCIAVI_mciUpdate(UINT wDevI */ static DWORD MCIAVI_mciStep(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STEP_PARMS lpParms) { - WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID); + WINE_MCIAVI *wma; FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms); + MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); + if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + + wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; return 0; @@ -693,11 +835,15 @@ static DWORD MCIAVI_mciStep(UINT wDevID, */ static DWORD MCIAVI_mciCopy(UINT wDevID, DWORD dwFlags, LPMCI_DGV_COPY_PARMS lpParms) { - WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID); + WINE_MCIAVI *wma; FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms); + MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); + if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + + wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; return 0; @@ -708,11 +854,15 @@ static DWORD MCIAVI_mciCopy(UINT wDevID, */ static DWORD MCIAVI_mciCut(UINT wDevID, DWORD dwFlags, LPMCI_DGV_CUT_PARMS lpParms) { - WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID); + WINE_MCIAVI *wma; FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms); + MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); + if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + + wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; return 0; @@ -723,11 +873,15 @@ static DWORD MCIAVI_mciCut(UINT wDevID, */ static DWORD MCIAVI_mciDelete(UINT wDevID, DWORD dwFlags, LPMCI_DGV_DELETE_PARMS lpParms) { - WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID); + WINE_MCIAVI *wma; FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms); + MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); + if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + + wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; return 0; @@ -738,11 +892,15 @@ static DWORD MCIAVI_mciDelete(UINT wDevI */ static DWORD MCIAVI_mciPaste(UINT wDevID, DWORD dwFlags, LPMCI_DGV_PASTE_PARMS lpParms) { - WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID); + WINE_MCIAVI *wma; FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms); + MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); + if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + + wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; return 0; @@ -753,11 +911,15 @@ static DWORD MCIAVI_mciPaste(UINT wDevID */ static DWORD MCIAVI_mciCue(UINT wDevID, DWORD dwFlags, LPMCI_DGV_CUE_PARMS lpParms) { - WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID); + WINE_MCIAVI *wma; FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms); + MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); + if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + + wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; return 0; @@ -768,11 +930,15 @@ static DWORD MCIAVI_mciCue(UINT wDevID, */ static DWORD MCIAVI_mciCapture(UINT wDevID, DWORD dwFlags, LPMCI_DGV_CAPTURE_PARMSA lpParms) { - WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID); + WINE_MCIAVI *wma; FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms); + MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); + if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + + wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; return 0; @@ -783,11 +949,15 @@ static DWORD MCIAVI_mciCapture(UINT wDev */ static DWORD MCIAVI_mciMonitor(UINT wDevID, DWORD dwFlags, LPMCI_DGV_MONITOR_PARMS lpParms) { - WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID); + WINE_MCIAVI *wma; FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms); + MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); + if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + + wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; return 0; @@ -798,11 +968,15 @@ static DWORD MCIAVI_mciMonitor(UINT wDev */ static DWORD MCIAVI_mciReserve(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RESERVE_PARMSA lpParms) { - WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID); + WINE_MCIAVI *wma; FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms); + MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); + if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + + wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; return 0; @@ -813,11 +987,15 @@ static DWORD MCIAVI_mciReserve(UINT wDev */ static DWORD MCIAVI_mciSetAudio(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SETAUDIO_PARMSA lpParms) { - WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID); + WINE_MCIAVI *wma; FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms); + MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); + if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + + wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; return 0; @@ -828,11 +1006,15 @@ static DWORD MCIAVI_mciSetAudio(UINT wDe */ static DWORD MCIAVI_mciSignal(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SIGNAL_PARMS lpParms) { - WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID); + WINE_MCIAVI *wma; FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms); + MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); + if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + + wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; return 0; @@ -843,11 +1025,15 @@ static DWORD MCIAVI_mciSignal(UINT wDevI */ static DWORD MCIAVI_mciSetVideo(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SETVIDEO_PARMSA lpParms) { - WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID); + WINE_MCIAVI *wma; FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms); + MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); + if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + + wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; return 0; @@ -858,11 +1044,15 @@ static DWORD MCIAVI_mciSetVideo(UINT wDe */ static DWORD MCIAVI_mciQuality(UINT wDevID, DWORD dwFlags, LPMCI_DGV_QUALITY_PARMSA lpParms) { - WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID); + WINE_MCIAVI *wma; FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms); + MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); + if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + + wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; return 0; @@ -873,11 +1063,15 @@ static DWORD MCIAVI_mciQuality(UINT wDev */ static DWORD MCIAVI_mciList(UINT wDevID, DWORD dwFlags, LPMCI_DGV_LIST_PARMSA lpParms) { - WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID); + WINE_MCIAVI *wma; FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms); + MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); + if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + + wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; return 0; @@ -888,11 +1082,15 @@ static DWORD MCIAVI_mciList(UINT wDevID, */ static DWORD MCIAVI_mciUndo(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms) { - WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID); + WINE_MCIAVI *wma; FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms); + MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); + if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + + wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; return 0; @@ -903,11 +1101,15 @@ static DWORD MCIAVI_mciUndo(UINT wDevID, */ static DWORD MCIAVI_mciConfigure(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms) { - WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID); + WINE_MCIAVI *wma; FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms); + MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); + if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + + wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; return 0; @@ -918,11 +1120,15 @@ static DWORD MCIAVI_mciConfigure(UINT wD */ static DWORD MCIAVI_mciRestore(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RESTORE_PARMSA lpParms) { - WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID); + WINE_MCIAVI *wma; FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms); + MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); + if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + + wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; return 0; @@ -954,7 +1160,8 @@ LONG CALLBACK MCIAVI_DriverProc(DWORD dw case DRV_REMOVE: return DRVCNF_RESTART; } - if (dwDevID == 0xFFFFFFFF) return MCIERR_UNSUPPORTED_FUNCTION; + /* session instance */ + if (dwDevID == 0xFFFFFFFF) return 1; switch (wMsg) { case MCI_OPEN_DRIVER: return MCIAVI_mciOpen (dwDevID, dwParam1, (LPMCI_DGV_OPEN_PARMSA) dwParam2); diff -u cvs/hq/wine/dlls/winmm/mciavi/mmoutput.c wine/dlls/winmm/mciavi/mmoutput.c --- cvs/hq/wine/dlls/winmm/mciavi/mmoutput.c 2003-12-30 22:44:20.000000000 +0800 +++ wine/dlls/winmm/mciavi/mmoutput.c 2003-12-30 23:28:23.000000000 +0800 @@ -4,6 +4,7 @@ * Digital video MCI Wine Driver * * Copyright 1999, 2000 Eric POUECH + * Copyright 2003 Dmitry Timoshkov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,16 +26,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(mciavi); -static BOOL MCIAVI_GetInfoAudio(WINE_MCIAVI* wma, const MMCKINFO* mmckList) +static BOOL MCIAVI_GetInfoAudio(WINE_MCIAVI* wma, const MMCKINFO* mmckList, MMCKINFO *mmckStream) { MMCKINFO mmckInfo; - mmckInfo.ckid = ckidSTREAMHEADER; - if (mmioDescend(wma->hFile, &mmckInfo, mmckList, MMIO_FINDCHUNK) != 0) { - WARN("Can't find 'strh' chunk\n"); - return FALSE; - } - mmioRead(wma->hFile, (LPSTR)&wma->ash_audio, sizeof(wma->ash_audio)); TRACE("ash.fccType='%c%c%c%c'\n", LOBYTE(LOWORD(wma->ash_audio.fccType)), @@ -59,11 +54,12 @@ static BOOL MCIAVI_GetInfoAudio(WINE_MCI TRACE("ash.rcFrame=(%d,%d,%d,%d)\n", wma->ash_audio.rcFrame.top, wma->ash_audio.rcFrame.left, wma->ash_audio.rcFrame.bottom, wma->ash_audio.rcFrame.right); - mmioAscend(wma->hFile, &mmckInfo, 0); + /* rewind to the start of the stream */ + mmioAscend(wma->hFile, mmckStream, 0); mmckInfo.ckid = ckidSTREAMFORMAT; if (mmioDescend(wma->hFile, &mmckInfo, mmckList, MMIO_FINDCHUNK) != 0) { - WARN("Can't find 'strh' chunk\n"); + WARN("Can't find 'strf' chunk\n"); return FALSE; } if (mmckInfo.cksize < sizeof(WAVEFORMAT)) { @@ -87,21 +83,13 @@ static BOOL MCIAVI_GetInfoAudio(WINE_MCI if (mmckInfo.cksize >= sizeof(WAVEFORMATEX)) TRACE("waveFormat.cbSize=%d\n", wma->lpWaveFormat->cbSize); - mmioAscend(wma->hFile, &mmckInfo, 0); - return TRUE; } -static BOOL MCIAVI_GetInfoVideo(WINE_MCIAVI* wma, const MMCKINFO* mmckList) +static BOOL MCIAVI_GetInfoVideo(WINE_MCIAVI* wma, const MMCKINFO* mmckList, MMCKINFO* mmckStream) { MMCKINFO mmckInfo; - mmckInfo.ckid = ckidSTREAMHEADER; - if (mmioDescend(wma->hFile, &mmckInfo, mmckList, MMIO_FINDCHUNK) != 0) { - WARN("Can't find 'strh' chunk\n"); - return FALSE; - } - mmioRead(wma->hFile, (LPSTR)&wma->ash_video, sizeof(wma->ash_video)); TRACE("ash.fccType='%c%c%c%c'\n", LOBYTE(LOWORD(wma->ash_video.fccType)), @@ -126,11 +114,12 @@ static BOOL MCIAVI_GetInfoVideo(WINE_MCI TRACE("ash.rcFrame=(%d,%d,%d,%d)\n", wma->ash_video.rcFrame.top, wma->ash_video.rcFrame.left, wma->ash_video.rcFrame.bottom, wma->ash_video.rcFrame.right); - mmioAscend(wma->hFile, &mmckInfo, 0); + /* rewind to the start of the stream */ + mmioAscend(wma->hFile, mmckStream, 0); mmckInfo.ckid = ckidSTREAMFORMAT; if (mmioDescend(wma->hFile, &mmckInfo, mmckList, MMIO_FINDCHUNK) != 0) { - WARN("Can't find 'strh' chunk\n"); + WARN("Can't find 'strf' chunk\n"); return FALSE; } @@ -154,7 +143,12 @@ static BOOL MCIAVI_GetInfoVideo(WINE_MCI TRACE("bih.biClrUsed=%ld\n", wma->inbih->biClrUsed); TRACE("bih.biClrImportant=%ld\n", wma->inbih->biClrImportant); - mmioAscend(wma->hFile, &mmckInfo, 0); + wma->source.left = 0; + wma->source.top = 0; + wma->source.right = wma->inbih->biWidth; + wma->source.bottom = wma->inbih->biHeight; + + wma->dest = wma->source; return TRUE; } @@ -178,6 +172,9 @@ static BOOL MCIAVI_AddFrame(WINE_MCIAVI* case cktypePALchange: TRACE("Adding video frame[%ld]: %ld bytes\n", alb->numVideoFrames, mmck->cksize); + if (!mmck->cksize) + TRACE("got a zero sized frame\n"); + if (alb->numVideoFrames < wma->dwPlayableVideoFrames) { wma->lpVideoIndex[alb->numVideoFrames].dwOffset = mmck->dwDataOffset; wma->lpVideoIndex[alb->numVideoFrames].dwSize = mmck->cksize; @@ -263,25 +260,43 @@ BOOL MCIAVI_GetInfo(WINE_MCIAVI* wma) mmioAscend(wma->hFile, &mmckInfo, 0); - mmckList.fccType = listtypeSTREAMHEADER; - if (mmioDescend(wma->hFile, &mmckList, &mmckHead, MMIO_FINDLIST) != 0) { - WARN("Can't find 'strl' list\n"); - return FALSE; - } + TRACE("Start of streams\n"); + do + { + MMCKINFO mmckStream; + + mmckList.fccType = listtypeSTREAMHEADER; + if (mmioDescend(wma->hFile, &mmckList, &mmckHead, MMIO_FINDLIST) != 0) + break; + + mmckStream.ckid = ckidSTREAMHEADER; + if (mmioDescend(wma->hFile, &mmckStream, &mmckList, MMIO_FINDCHUNK) != 0) + { + WARN("Can't find 'strh' chunk\n"); + continue; + } + + TRACE("Stream fccType %4.4s\n", (LPSTR)&mmckStream.fccType); + + if (mmckStream.fccType == streamtypeVIDEO) + { + TRACE("found video stream\n"); + if (!MCIAVI_GetInfoVideo(wma, &mmckList, &mmckStream)) + return FALSE; + } + else if (mmckStream.fccType == streamtypeAUDIO) + { + TRACE("found audio stream\n"); + if (!MCIAVI_GetInfoAudio(wma, &mmckList, &mmckStream)) + return FALSE; + } + else + TRACE("Unsupported stream type %4.4s\n", (LPSTR)&mmckStream.fccType); - if (!MCIAVI_GetInfoVideo(wma, &mmckList)) { - return FALSE; - } + mmioAscend(wma->hFile, &mmckList, 0); + } while(1); - mmioAscend(wma->hFile, &mmckList, 0); - - mmckList.fccType = listtypeSTREAMHEADER; - if (mmioDescend(wma->hFile, &mmckList, &mmckHead, MMIO_FINDLIST) == 0) { - if (!MCIAVI_GetInfoAudio(wma, &mmckList)) { - return FALSE; - } - mmioAscend(wma->hFile, &mmckList, 0); - } + TRACE("End of streams\n"); mmioAscend(wma->hFile, &mmckHead, 0); @@ -351,6 +366,8 @@ BOOL MCIAVI_OpenVideo(WINE_MCIAVI* wm DWORD outSize; FOURCC fcc = wma->ash_video.fccHandler; + TRACE("fcc %4.4s\n", (LPSTR)&fcc); + /* check uncompressed AVI */ if ((fcc == mmioFOURCC('D','I','B',' ')) || (fcc == mmioFOURCC('R','L','E',' '))) { @@ -411,10 +428,14 @@ BOOL MCIAVI_OpenVideo(WINE_MCIAVI* wm return TRUE; } -static void CALLBACK MCIAVI_waveCallback(HWAVEOUT hwo, UINT uMsg, DWORD dwInstance, - DWORD dwParam1, DWORD dwParam2) +static void CALLBACK MCIAVI_waveCallback(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, + DWORD_PTR dwParam1, DWORD_PTR dwParam2) { - WINE_MCIAVI* wma = (WINE_MCIAVI*)dwInstance; + WINE_MCIAVI *wma = (WINE_MCIAVI *)MCIAVI_mciGetOpenDev(dwInstance); + + if (!wma) return; + + EnterCriticalSection(&wma->cs); switch (uMsg) { case WOM_OPEN: @@ -428,6 +449,8 @@ static void CALLBACK MCIAVI_waveCallback default: ERR("Unknown uMsg=%d\n", uMsg); } + + LeaveCriticalSection(&wma->cs); } DWORD MCIAVI_OpenAudio(WINE_MCIAVI* wma, unsigned* nHdr, LPWAVEHDR* pWaveHdr) @@ -437,7 +460,7 @@ DWORD MCIAVI_OpenAudio(WINE_MCIAVI* wma, unsigned i; dwRet = waveOutOpen((HWAVEOUT *)&wma->hWave, WAVE_MAPPER, wma->lpWaveFormat, - (DWORD)MCIAVI_waveCallback, (DWORD)wma, CALLBACK_FUNCTION); + (DWORD_PTR)MCIAVI_waveCallback, wma->wDevID, CALLBACK_FUNCTION); if (dwRet != 0) { TRACE("Can't open low level audio device %ld\n", dwRet); dwRet = MCIERR_DEVICE_OPEN; @@ -543,7 +566,11 @@ LRESULT MCIAVI_PaintFrame(WINE_MCIAVI* w hdcMem = CreateCompatibleDC(hDC); hbmOld = SelectObject(hdcMem, wma->hbmFrame); - BitBlt(hDC, 0, 0, nWidth, nHeight, hdcMem, 0, 0, SRCCOPY); + StretchBlt(hDC, + wma->dest.left, wma->dest.top, wma->dest.right, wma->dest.bottom, + hdcMem, + wma->source.left, wma->source.top, wma->source.right, wma->source.bottom, + SRCCOPY); SelectObject(hdcMem, hbmOld); DeleteDC(hdcMem); @@ -559,8 +586,6 @@ LRESULT MCIAVI_DrawFrame(WINE_MCIAVI* wm if (!wma->lpVideoIndex[wma->dwCurrVideoFrame].dwOffset) return FALSE; - EnterCriticalSection(&wma->cs); - mmioSeek(wma->hFile, wma->lpVideoIndex[wma->dwCurrVideoFrame].dwOffset, SEEK_SET); mmioRead(wma->hFile, wma->indata, wma->lpVideoIndex[wma->dwCurrVideoFrame].dwSize); @@ -570,7 +595,6 @@ LRESULT MCIAVI_DrawFrame(WINE_MCIAVI* wm if (wma->hic && ICDecompress(wma->hic, 0, wma->inbih, wma->indata, wma->outbih, wma->outdata) != ICERR_OK) { - LeaveCriticalSection(&wma->cs); WARN("Decompression error\n"); return FALSE; } @@ -580,8 +604,5 @@ LRESULT MCIAVI_DrawFrame(WINE_MCIAVI* wm ReleaseDC(wma->hWndPaint, hDC); } - LeaveCriticalSection(&wma->cs); - return TRUE; } - diff -u cvs/hq/wine/dlls/winmm/mciavi/private_mciavi.h wine/dlls/winmm/mciavi/private_mciavi.h --- cvs/hq/wine/dlls/winmm/mciavi/private_mciavi.h 2003-12-30 22:44:20.000000000 +0800 +++ wine/dlls/winmm/mciavi/private_mciavi.h 2003-12-30 23:28:23.000000000 +0800 @@ -41,12 +41,12 @@ struct MMIOPos { }; typedef struct { - UINT wDevID; + MCIDEVICEID wDevID; int nUseCount; /* Incremented for each shared open */ BOOL fShareable; /* TRUE if first open was shareable */ WORD wCommandTable; /* custom MCI command table */ - volatile DWORD dwStatus; /* One of MCI_MODE_XXX */ - MCI_OPEN_PARMSA openParms; + DWORD dwStatus; /* One of MCI_MODE_XXX */ + LPSTR lpFileName; DWORD dwMciTimeFormat; /* current time format */ DWORD dwSet; /* what's turned on: video & audio l&r */ /* information on the loaded AVI file */ @@ -75,6 +75,7 @@ typedef struct { HWND hWnd, hWndPaint; DWORD dwCurrVideoFrame; /* video frame to display and current position */ DWORD dwCurrAudioBlock; /* current audio block being played */ + RECT source, dest; /* data for the background mechanism */ CRITICAL_SECTION cs; } WINE_MCIAVI; @@ -99,6 +100,7 @@ LRESULT MCIAVI_PaintFrame(WINE_MCIAVI* w /* mciavi.c */ WINE_MCIAVI* MCIAVI_mciGetOpenDev(UINT wDevID); +DWORD MCIAVI_mciClose(UINT, DWORD, LPMCI_GENERIC_PARMS); /* window.c */ BOOL MCIAVI_CreateWindow(WINE_MCIAVI* wma, DWORD dwFlags, LPMCI_DGV_OPEN_PARMSA lpOpenParms); diff -u cvs/hq/wine/dlls/winmm/mciavi/wnd.c wine/dlls/winmm/mciavi/wnd.c --- cvs/hq/wine/dlls/winmm/mciavi/wnd.c 2003-12-30 22:44:20.000000000 +0800 +++ wine/dlls/winmm/mciavi/wnd.c 2003-12-30 23:28:23.000000000 +0800 @@ -4,6 +4,7 @@ * Digital video MCI Wine Driver * * Copyright 1999, 2000 Eric POUECH + * Copyright 2003 Dmitry Timoshkov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -30,15 +31,13 @@ static LRESULT WINAPI MCIAVI_WindowProc( { TRACE("hwnd=%p msg=%x wparam=%x lparam=%lx\n", hWnd, uMsg, wParam, lParam); - if (!(WINE_MCIAVI*)GetWindowLongA(hWnd, 0) && uMsg != WM_CREATE) - return DefWindowProcA(hWnd, uMsg, wParam, lParam); - switch (uMsg) { case WM_CREATE: SetWindowLongA(hWnd, 0, (LPARAM)((CREATESTRUCTA*)lParam)->lpCreateParams); return DefWindowProcA(hWnd, uMsg, wParam, lParam); case WM_DESTROY: + MCIAVI_mciClose(GetWindowLongA(hWnd, 0), MCI_WAIT, NULL); SetWindowLongA(hWnd, 0, 0); return DefWindowProcA(hWnd, uMsg, wParam, lParam); @@ -48,32 +47,38 @@ static LRESULT WINAPI MCIAVI_WindowProc( GetClientRect(hWnd, &rect); FillRect((HDC)wParam, &rect, GetStockObject(BLACK_BRUSH)); } - break; + return 1; + case WM_PAINT: { - WINE_MCIAVI* wma = (WINE_MCIAVI*)GetWindowLongA(hWnd, 0); + WINE_MCIAVI *wma = (WINE_MCIAVI *)mciGetDriverData(GetWindowLongA(hWnd, 0)); + + if (!wma) + return DefWindowProcA(hWnd, uMsg, wParam, lParam); + + EnterCriticalSection(&wma->cs); /* the animation isn't playing, don't paint */ if (wma->dwStatus == MCI_MODE_NOT_READY) + { + LeaveCriticalSection(&wma->cs); /* default paint handling */ return DefWindowProcA(hWnd, uMsg, wParam, lParam); + } - if (wParam) { - EnterCriticalSection(&wma->cs); + if (wParam) MCIAVI_PaintFrame(wma, (HDC)wParam); - LeaveCriticalSection(&wma->cs); - } else { + else + { PAINTSTRUCT ps; HDC hDC = BeginPaint(hWnd, &ps); - - EnterCriticalSection(&wma->cs); MCIAVI_PaintFrame(wma, hDC); - LeaveCriticalSection(&wma->cs); - EndPaint(hWnd, &ps); } + + LeaveCriticalSection(&wma->cs); } - break; + return 1; default: return DefWindowProcA(hWnd, uMsg, wParam, lParam); @@ -93,15 +98,16 @@ BOOL MCIAVI_CreateWindow(WINE_MCIAVI* if (wma->hWnd) return TRUE; ZeroMemory(&wndClass, sizeof(WNDCLASSA)); - wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS; + wndClass.style = CS_DBLCLKS; wndClass.lpfnWndProc = (WNDPROC)MCIAVI_WindowProc; wndClass.cbClsExtra = 0; - wndClass.cbWndExtra = sizeof(WINE_MCIAVI*); + wndClass.cbWndExtra = sizeof(MCIDEVICEID); + wndClass.hInstance = MCIAVI_hInstance; wndClass.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW); wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); wndClass.lpszClassName = "MCIAVI"; - RegisterClassA(&wndClass); + if (!RegisterClassA(&wndClass)) return FALSE; if (dwFlags & MCI_DGV_OPEN_PARENT) hParent = lpOpenParms->hWndParent; if (dwFlags & MCI_DGV_OPEN_WS) dwStyle = lpOpenParms->dwStyle; @@ -116,7 +122,8 @@ BOOL MCIAVI_CreateWindow(WINE_MCIAVI* wma->hWnd = CreateWindowA("MCIAVI", "Wine MCI-AVI player", dwStyle, rc.left, rc.top, rc.right, rc.bottom, - hParent, 0, MCIAVI_hInstance, wma); + hParent, 0, MCIAVI_hInstance, + (LPVOID)wma->wDevID); wma->hWndPaint = wma->hWnd; return (BOOL)wma->hWnd; } @@ -128,40 +135,49 @@ DWORD MCIAVI_mciPut(UINT wDevID, DWORD d { WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID); RECT rc; - char buffer[256]; - FIXME("(%04x, %08lX, %p) : stub\n", wDevID, dwFlags, lpParms); + TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpParms); if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; + EnterCriticalSection(&wma->cs); + if (dwFlags & MCI_DGV_RECT) { rc = lpParms->rc; } else { - SetRectEmpty(&rc); + GetClientRect(wma->hWndPaint, &rc); } - *buffer = 0; if (dwFlags & MCI_DGV_PUT_CLIENT) { - strncat(buffer, "PUT_CLIENT", sizeof(buffer)); + FIXME("PUT_CLIENT %s\n", wine_dbgstr_rect(&rc)); + LeaveCriticalSection(&wma->cs); + return MCIERR_UNRECOGNIZED_COMMAND; } if (dwFlags & MCI_DGV_PUT_DESTINATION) { - strncat(buffer, "PUT_DESTINATION", sizeof(buffer)); + TRACE("PUT_DESTINATION %s\n", wine_dbgstr_rect(&rc)); + wma->dest = rc; } if (dwFlags & MCI_DGV_PUT_FRAME) { - strncat(buffer, "PUT_FRAME", sizeof(buffer)); + FIXME("PUT_FRAME %s\n", wine_dbgstr_rect(&rc)); + LeaveCriticalSection(&wma->cs); + return MCIERR_UNRECOGNIZED_COMMAND; } if (dwFlags & MCI_DGV_PUT_SOURCE) { - strncat(buffer, "PUT_SOURCE", sizeof(buffer)); + TRACE("PUT_SOURCE %s\n", wine_dbgstr_rect(&rc)); + wma->source = rc; } if (dwFlags & MCI_DGV_PUT_VIDEO) { - strncat(buffer, "PUT_VIDEO", sizeof(buffer)); + FIXME("PUT_VIDEO %s\n", wine_dbgstr_rect(&rc)); + LeaveCriticalSection(&wma->cs); + return MCIERR_UNRECOGNIZED_COMMAND; } if (dwFlags & MCI_DGV_PUT_WINDOW) { - strncat(buffer, "PUT_WINDOW", sizeof(buffer)); + FIXME("PUT_WINDOW %s\n", wine_dbgstr_rect(&rc)); + LeaveCriticalSection(&wma->cs); + return MCIERR_UNRECOGNIZED_COMMAND; } - TRACE("%s (%ld,%ld,%ld,%ld)\n", buffer, rc.left, rc.top, rc.right, rc.bottom); - + LeaveCriticalSection(&wma->cs); return 0; } @@ -171,40 +187,43 @@ DWORD MCIAVI_mciPut(UINT wDevID, DWORD d DWORD MCIAVI_mciWhere(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RECT_PARMS lpParms) { WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID); - LPCSTR x = ""; TRACE("(%04x, %08lx, %p)\n", wDevID, dwFlags, lpParms); if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; - if (dwFlags & MCI_DGV_WHERE_MAX) FIXME("Max NIY\n"); + if (dwFlags & MCI_DGV_WHERE_MAX) + { + FIXME("WHERE_MAX\n"); + return MCIERR_UNRECOGNIZED_COMMAND; + } + + EnterCriticalSection(&wma->cs); if (dwFlags & MCI_DGV_WHERE_DESTINATION) { - x = "Dest"; - GetClientRect(wma->hWnd, &lpParms->rc); + TRACE("WHERE_DESTINATION %s\n", wine_dbgstr_rect(&wma->dest)); + lpParms->rc = wma->dest; } if (dwFlags & MCI_DGV_WHERE_FRAME) { - FIXME(x = "Frame\n"); + FIXME("MCI_DGV_WHERE_FRAME\n"); + LeaveCriticalSection(&wma->cs); return MCIERR_UNRECOGNIZED_COMMAND; } if (dwFlags & MCI_DGV_WHERE_SOURCE) { - x = "Source"; - lpParms->rc.left = lpParms->rc.top = 0; - lpParms->rc.right = wma->mah.dwWidth; - lpParms->rc.bottom = wma->mah.dwHeight; + TRACE("WHERE_SOURCE %s\n", wine_dbgstr_rect(&wma->source)); + lpParms->rc = wma->source; } if (dwFlags & MCI_DGV_WHERE_VIDEO) { - FIXME(x = "Video\n"); + FIXME("WHERE_VIDEO\n"); + LeaveCriticalSection(&wma->cs); return MCIERR_UNRECOGNIZED_COMMAND; } if (dwFlags & MCI_DGV_WHERE_WINDOW) { - x = "Window"; - GetClientRect(wma->hWndPaint, &lpParms->rc); + GetClientRect(wma->hWndPaint, &lpParms->rc); + TRACE("WHERE_WINDOW %s\n", wine_dbgstr_rect(&lpParms->rc)); } - TRACE("%s -> (%ld,%ld,%ld,%ld)\n", - x, lpParms->rc.left, lpParms->rc.top, lpParms->rc.right, lpParms->rc.bottom); - + LeaveCriticalSection(&wma->cs); return 0; } @@ -220,11 +239,16 @@ DWORD MCIAVI_mciWindow(UINT wDevID, DWOR if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; + EnterCriticalSection(&wma->cs); + if (dwFlags & MCI_DGV_WINDOW_HWND) { - TRACE("Setting hWnd to %p\n", lpParms->hWnd); - if (wma->hWnd) ShowWindow(wma->hWnd, SW_HIDE); - wma->hWndPaint = (lpParms->hWnd == MCI_DGV_WINDOW_DEFAULT) ? wma->hWnd : lpParms->hWnd; - InvalidateRect(wma->hWndPaint, NULL, FALSE); + if (IsWindow(lpParms->hWnd)) + { + TRACE("Setting hWnd to %p\n", lpParms->hWnd); + if (wma->hWnd) ShowWindow(wma->hWnd, SW_HIDE); + wma->hWndPaint = (lpParms->hWnd == MCI_DGV_WINDOW_DEFAULT) ? wma->hWnd : lpParms->hWnd; + InvalidateRect(wma->hWndPaint, NULL, FALSE); + } } if (dwFlags & MCI_DGV_WINDOW_STATE) { TRACE("Setting nCmdShow to %d\n", lpParms->nCmdShow); @@ -235,5 +259,6 @@ DWORD MCIAVI_mciWindow(UINT wDevID, DWOR SetWindowTextA(wma->hWndPaint, lpParms->lpstrText); } + LeaveCriticalSection(&wma->cs); return 0; } diff -u cvs/hq/wine/dlls/winmm/mci.c wine/dlls/winmm/mci.c --- cvs/hq/wine/dlls/winmm/mci.c 2003-12-30 22:44:20.000000000 +0800 +++ wine/dlls/winmm/mci.c 2003-12-30 23:28:23.000000000 +0800 @@ -1027,7 +1027,7 @@ DWORD WINAPI mciSendStringA(LPCSTR lpstr */ if (lpstrRet && uRetLen) *lpstrRet = '\0'; -#define STR_OF(_x) (IsBadReadPtr((char*)_x,1)?"?":(char*)(_x)) +#define STR_OF(_x) ((!(_x) || IsBadReadPtr((char*)(_x),1)) ? "?" : (char*)(_x)) TRACE("[%d, %s, %08lx, %08lx/%s %08lx/%s %08lx/%s %08lx/%s %08lx/%s %08lx/%s]\n", wmd->wDeviceID, MCI_MessageToString(MCI_GetMessage(lpCmd)), dwFlags, data[0], STR_OF(data[0]), data[1], STR_OF(data[1]),