/************************************************************************** * MCIAVI_drvClose [internal] */ static DWORD MCIAVI_drvClose(DWORD dwDevID) { WINE_MCIAVI *wma; TRACE("%04x\n", dwDevID); /* finish all outstanding things */ MCIAVI_mciClose(dwDevID, MCI_WAIT, NULL); wma = (WINE_MCIAVI*)mciGetDriverData(dwDevID); if (wma) { MCIAVI_UnregisterClass(); EnterCriticalSection(&wma->cs); mciSetDriverData(dwDevID, 0); mciFreeCommandResource(wma->wCommandTable); CloseHandle(wma->hStopEvent); LeaveCriticalSection(&wma->cs); wma->cs.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&wma->cs); HeapFree(GetProcessHeap(), 0, wma); return 1; } return (dwDevID == 0xFFFFFFFF) ? 1 : 0; }
static LRESULT WINAPI MCIAVI_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { TRACE("hwnd=%p msg=%x wparam=%lx lparam=%lx\n", hWnd, uMsg, wParam, lParam); switch (uMsg) { case WM_CREATE: SetWindowLongW(hWnd, 0, (LPARAM)((CREATESTRUCTW *)lParam)->lpCreateParams); return DefWindowProcW(hWnd, uMsg, wParam, lParam); case WM_DESTROY: MCIAVI_mciClose(GetWindowLongW(hWnd, 0), MCI_WAIT, NULL); SetWindowLongW(hWnd, 0, 0); return DefWindowProcW(hWnd, uMsg, wParam, lParam); case WM_ERASEBKGND: { RECT rect; GetClientRect(hWnd, &rect); FillRect((HDC)wParam, &rect, GetStockObject(BLACK_BRUSH)); } return 1; case WM_PAINT: { WINE_MCIAVI *wma = (WINE_MCIAVI *)mciGetDriverData(GetWindowLongW(hWnd, 0)); if (!wma) return DefWindowProcW(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 DefWindowProcW(hWnd, uMsg, wParam, lParam); } if (wParam) MCIAVI_PaintFrame(wma, (HDC)wParam); else { PAINTSTRUCT ps; BeginPaint(hWnd, &ps); MCIAVI_PaintFrame(wma, ps.hdc); EndPaint(hWnd, &ps); } LeaveCriticalSection(&wma->cs); } return 1; default: return DefWindowProcW(hWnd, uMsg, wParam, lParam); } }
/************************************************************************** * MCICDA_GetOpenDrv [internal] */ static WINE_MCICDAUDIO* MCICDA_GetOpenDrv(UINT wDevID) { WINE_MCICDAUDIO* wmcda = (WINE_MCICDAUDIO*)mciGetDriverData(wDevID); if (wmcda == NULL || wmcda->nUseCount == 0) { WARN("Invalid wDevID=%u\n", wDevID); return 0; } return wmcda; }
/************************************************************************** * MCIQTZ_mciGetOpenDev [internal] */ static WINE_MCIQTZ* MCIQTZ_mciGetOpenDev(UINT wDevID) { WINE_MCIQTZ* wma = (WINE_MCIQTZ*)mciGetDriverData(wDevID); if (!wma) { WARN("Invalid wDevID=%u\n", wDevID); return NULL; } return wma; }
/************************************************************************** * MCIAVI_mciGetOpenDev [internal] */ WINE_MCIAVI* MCIAVI_mciGetOpenDev(UINT wDevID) { WINE_MCIAVI* wma = (WINE_MCIAVI*)mciGetDriverData(wDevID); if (wma == NULL || wma->nUseCount == 0) { WARN("Invalid wDevID=%u\n", wDevID); return 0; } return wma; }
/************************************************************************** * MCICDA_drvClose [internal] */ static DWORD MCICDA_drvClose(DWORD dwDevID) { WINE_MCICDAUDIO* wmcda = (WINE_MCICDAUDIO*)mciGetDriverData(dwDevID); if (wmcda) { HeapFree(GetProcessHeap(), 0, wmcda); mciSetDriverData(dwDevID, 0); } return (dwDevID == 0xFFFFFFFF) ? 1 : 0; }
/************************************************************************** * MCIAVI_drvConfigure [internal] */ static DWORD MCIAVI_drvConfigure(DWORD dwDevID) { WINE_MCIAVI *wma; TRACE("%04x\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); return 1; } return 0; }
/************************************************************************** * mciGetDriverData [MMSYSTEM.708] */ DWORD WINAPI mciGetDriverData16(UINT16 uDeviceID) { return mciGetDriverData(uDeviceID); }
/************************************************************************** * MCICDA_GetDevCaps [internal] */ static DWORD MCICDA_GetDevCaps(UINT wDevID, DWORD dwFlags, LPMCI_GETDEVCAPS_PARMS lpParms) { WINE_MCICDAUDIO* wmcda = (WINE_MCICDAUDIO*)mciGetDriverData(wDevID); DWORD ret = 0; TRACE("(%04X, %08X, %p);\n", wDevID, dwFlags, lpParms); if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID; if (dwFlags & MCI_GETDEVCAPS_ITEM) { TRACE("MCI_GETDEVCAPS_ITEM dwItem=%08X;\n", lpParms->dwItem); switch (lpParms->dwItem) { case MCI_GETDEVCAPS_CAN_RECORD: lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); ret = MCI_RESOURCE_RETURNED; break; case MCI_GETDEVCAPS_HAS_AUDIO: lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE); ret = MCI_RESOURCE_RETURNED; break; case MCI_GETDEVCAPS_HAS_VIDEO: lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); ret = MCI_RESOURCE_RETURNED; break; case MCI_GETDEVCAPS_DEVICE_TYPE: lpParms->dwReturn = MAKEMCIRESOURCE(MCI_DEVTYPE_CD_AUDIO, MCI_DEVTYPE_CD_AUDIO); ret = MCI_RESOURCE_RETURNED; break; case MCI_GETDEVCAPS_USES_FILES: lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); ret = MCI_RESOURCE_RETURNED; break; case MCI_GETDEVCAPS_COMPOUND_DEVICE: lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); ret = MCI_RESOURCE_RETURNED; break; case MCI_GETDEVCAPS_CAN_EJECT: lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE); ret = MCI_RESOURCE_RETURNED; break; case MCI_GETDEVCAPS_CAN_PLAY: lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE); ret = MCI_RESOURCE_RETURNED; break; case MCI_GETDEVCAPS_CAN_SAVE: lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); ret = MCI_RESOURCE_RETURNED; break; default: WARN("Unsupported %x devCaps item\n", lpParms->dwItem); return MCIERR_UNSUPPORTED_FUNCTION; } } else { TRACE("No GetDevCaps-Item !\n"); return MCIERR_MISSING_PARAMETER; } TRACE("lpParms->dwReturn=%08X;\n", lpParms->dwReturn); if (dwFlags & MCI_NOTIFY) { MCICDA_Notify(lpParms->dwCallback, wmcda, MCI_NOTIFY_SUCCESSFUL); } return ret; }
/************************************************************************** * MCICDA_Open [internal] */ static DWORD MCICDA_Open(UINT wDevID, DWORD dwFlags, LPMCI_OPEN_PARMSW lpOpenParms) { MCIDEVICEID dwDeviceID; DWORD ret; WINE_MCICDAUDIO* wmcda = (WINE_MCICDAUDIO*)mciGetDriverData(wDevID); WCHAR root[7], drive = 0; TRACE("(%04X, %08X, %p);\n", wDevID, dwFlags, lpOpenParms); if (lpOpenParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID; dwDeviceID = lpOpenParms->wDeviceID; if (wmcda->nUseCount > 0) { /* The driver is already open on this channel */ /* If the driver was opened shareable before and this open specifies */ /* shareable then increment the use count */ if (wmcda->fShareable && (dwFlags & MCI_OPEN_SHAREABLE)) ++wmcda->nUseCount; else return MCIERR_MUST_USE_SHAREABLE; } else { wmcda->nUseCount = 1; wmcda->fShareable = dwFlags & MCI_OPEN_SHAREABLE; } if (dwFlags & MCI_OPEN_ELEMENT) { if (dwFlags & MCI_OPEN_ELEMENT_ID) { WARN("MCI_OPEN_ELEMENT_ID %p! Abort\n", lpOpenParms->lpstrElementName); ret = MCIERR_FLAGS_NOT_COMPATIBLE; goto the_error; } TRACE("MCI_OPEN_ELEMENT element name: %s\n", debugstr_w(lpOpenParms->lpstrElementName)); /* Only the first letter counts since w2k * Win9x-NT accept only d: and w98SE accepts d:\foobar as well. * Play d:\Track03.cda plays from the first track, not #3. */ if (!isalpha(lpOpenParms->lpstrElementName[0])) { ret = MCIERR_INVALID_FILE; goto the_error; } drive = toupper(lpOpenParms->lpstrElementName[0]); root[0] = drive; root[1] = ':'; root[2] = '\\'; root[3] = '\0'; if (GetDriveTypeW(root) != DRIVE_CDROM) { ret = MCIERR_INVALID_FILE; goto the_error; } } else { root[0] = 'A'; root[1] = ':'; root[2] = '\\'; root[3] = '\0'; for ( ; root[0] <= 'Z'; root[0]++) { if (GetDriveTypeW(root) == DRIVE_CDROM) { drive = root[0]; break; } } if (!drive) { ret = MCIERR_CANNOT_LOAD_DRIVER; /* drvOpen should return this */ goto the_error; } } wmcda->wNotifyDeviceID = dwDeviceID; wmcda->dwTimeFormat = MCI_FORMAT_MSF; /* now, open the handle */ root[0] = root[1] = '\\'; root[2] = '.'; root[3] = '\\'; root[4] = drive; root[5] = ':'; root[6] = '\0'; wmcda->handle = CreateFileW(root, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); if (wmcda->handle == INVALID_HANDLE_VALUE) { ret = MCIERR_MUST_USE_SHAREABLE; goto the_error; } if (dwFlags & MCI_NOTIFY) { mciDriverNotify(HWND_32(LOWORD(lpOpenParms->dwCallback)), dwDeviceID, MCI_NOTIFY_SUCCESSFUL); } return 0; the_error: --wmcda->nUseCount; return ret; }
/*************************************************************************** * MCIAVI_mciOpen [internal] */ static DWORD MCIAVI_mciOpen(UINT wDevID, DWORD dwFlags, LPMCI_DGV_OPEN_PARMSW lpOpenParms) { WINE_MCIAVI *wma; LRESULT dwRet = 0; TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpOpenParms); 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 */ /* shareable then increment the use count */ 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; if (dwFlags & MCI_OPEN_ELEMENT) { if (dwFlags & MCI_OPEN_ELEMENT_ID) { /* could it be that (DWORD)lpOpenParms->lpstrElementName * contains the hFile value ? */ dwRet = MCIERR_UNRECOGNIZED_COMMAND; } else if (lpOpenParms->lpstrElementName && lpOpenParms->lpstrElementName[0]) { /* FIXME : what should be done id wma->hFile is already != 0, or the driver is playin' */ TRACE("MCI_OPEN_ELEMENT %s!\n", debugstr_w(lpOpenParms->lpstrElementName)); wma->lpFileName = HeapAlloc(GetProcessHeap(), 0, (strlenW(lpOpenParms->lpstrElementName) + 1) * sizeof(WCHAR)); strcpyW(wma->lpFileName, lpOpenParms->lpstrElementName); if (lpOpenParms->lpstrElementName[0] == '@') { /* The file name @11223344 encodes an AVIFile handle in decimal notation * in Win3.1 and w2k/NT, but this feature is absent in win95 (KB140750). * wma->hFile = LongToHandle(strtolW(lpOpenParms->lpstrElementName+1, NULL, 10)); */ FIXME("Using AVIFile/Stream %s NIY\n", debugstr_w(lpOpenParms->lpstrElementName)); } wma->hFile = mmioOpenW(lpOpenParms->lpstrElementName, NULL, MMIO_ALLOCBUF | MMIO_DENYWRITE | MMIO_READ); if (wma->hFile == 0) { WARN("can't find file=%s!\n", debugstr_w(lpOpenParms->lpstrElementName)); dwRet = MCIERR_FILE_NOT_FOUND; } else { if (!MCIAVI_GetInfo(wma)) dwRet = MCIERR_INVALID_FILE; else if (!MCIAVI_OpenVideo(wma)) dwRet = MCIERR_CANNOT_LOAD_DRIVER; else if (!MCIAVI_CreateWindow(wma, dwFlags, lpOpenParms)) dwRet = MCIERR_CREATEWINDOW; } } else { FIXME("Don't record yet\n"); dwRet = MCIERR_UNSUPPORTED_FUNCTION; } } if (dwRet == 0) { TRACE("lpOpenParms->wDeviceID = %04x\n", lpOpenParms->wDeviceID); wma->dwStatus = MCI_MODE_STOP; wma->dwMciTimeFormat = MCI_FORMAT_FRAMES; } else { MCIAVI_CleanUp(wma); } LeaveCriticalSection(&wma->cs); if (!dwRet && (dwFlags & MCI_NOTIFY)) { mciDriverNotify(HWND_32(LOWORD(lpOpenParms->dwCallback)), wDevID, MCI_NOTIFY_SUCCESSFUL); } return dwRet; }
/************************************************************************** * MCICDA_Open [internal] */ static DWORD MCICDA_Open(UINT wDevID, DWORD dwFlags, LPMCI_OPEN_PARMSA lpOpenParms) { DWORD dwDeviceID; DWORD ret = MCIERR_HARDWARE; WINE_MCICDAUDIO* wmcda = (WINE_MCICDAUDIO*)mciGetDriverData(wDevID); char root[7]; int count; char drive = 0; TRACE("(%04X, %08lX, %p);\n", wDevID, dwFlags, lpOpenParms); if (lpOpenParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID; dwDeviceID = lpOpenParms->wDeviceID; if (wmcda->nUseCount > 0) { /* The driver is already open on this channel */ /* If the driver was opened shareable before and this open specifies */ /* shareable then increment the use count */ if (wmcda->fShareable && (dwFlags & MCI_OPEN_SHAREABLE)) ++wmcda->nUseCount; else return MCIERR_MUST_USE_SHAREABLE; } else { wmcda->nUseCount = 1; wmcda->fShareable = dwFlags & MCI_OPEN_SHAREABLE; } if (dwFlags & MCI_OPEN_ELEMENT) { if (dwFlags & MCI_OPEN_ELEMENT_ID) { WARN("MCI_OPEN_ELEMENT_ID %8lx ! Abort\n", (DWORD)lpOpenParms->lpstrElementName); return MCIERR_NO_ELEMENT_ALLOWED; } if (!isalpha(lpOpenParms->lpstrElementName[0]) || lpOpenParms->lpstrElementName[1] != ':' || lpOpenParms->lpstrElementName[2]) { WARN("MCI_OPEN_ELEMENT unsupported format: %s\n", lpOpenParms->lpstrElementName); ret = MCIERR_NO_ELEMENT_ALLOWED; goto the_error; } drive = toupper(lpOpenParms->lpstrElementName[0]); strcpy(root, "A:\\"); root[0] = drive; if (GetDriveTypeA(root) != DRIVE_CDROM) { ret = MCIERR_INVALID_DEVICE_NAME; goto the_error; } } else { /* drive letter isn't passed... get the dwDeviceID'th cdrom in the system */ strcpy(root, "A:\\"); for (count = 0; root[0] <= 'Z'; root[0]++) { if (GetDriveTypeA(root) == DRIVE_CDROM && ++count >= dwDeviceID) { drive = root[0]; break; } } if (!drive) { ret = MCIERR_INVALID_DEVICE_ID; goto the_error; } } wmcda->wNotifyDeviceID = dwDeviceID; wmcda->dwTimeFormat = MCI_FORMAT_MSF; /* now, open the handle */ strcpy(root, "\\\\.\\A:"); root[4] = drive; wmcda->handle = CreateFileA(root, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); if (wmcda->handle != INVALID_HANDLE_VALUE) return 0; the_error: --wmcda->nUseCount; return ret; }