/************************************************************************** * DRIVER_RemoveFromList [internal] * * Generates all the logic to handle driver closure / deletion * Removes a driver struct to the list of open drivers. */ static BOOL DRIVER_RemoveFromList(LPWINE_DRIVER lpDrv) { /* last of this driver in list ? */ if (DRIVER_GetNumberOfModuleRefs(lpDrv->hModule, NULL) == 1) { DRIVER_SendMessage(lpDrv, DRV_DISABLE, 0L, 0L); DRIVER_SendMessage(lpDrv, DRV_FREE, 0L, 0L); } EnterCriticalSection( &mmdriver_lock ); if (lpDrv->lpPrevItem) lpDrv->lpPrevItem->lpNextItem = lpDrv->lpNextItem; else lpDrvItemList = lpDrv->lpNextItem; if (lpDrv->lpNextItem) lpDrv->lpNextItem->lpPrevItem = lpDrv->lpPrevItem; /* trash magic number */ lpDrv->dwMagic ^= 0xa5a5a5a5; lpDrv->lpDrvProc = NULL; lpDrv->dwDriverID = 0; LeaveCriticalSection( &mmdriver_lock ); return TRUE; }
/************************************************************************** * DRIVER_AddToList [internal] * * Adds a driver struct to the list of open drivers. * Generates all the logic to handle driver creation / open. */ static BOOL DRIVER_AddToList(LPWINE_DRIVER lpNewDrv, LPARAM lParam1, LPARAM lParam2) { /* First driver to be loaded for this module, need to load correctly the module */ if (DRIVER_GetNumberOfModuleRefs(lpNewDrv) == 0) { if (DRIVER_SendMessage(lpNewDrv, DRV_LOAD, 0L, 0L) != DRV_SUCCESS) { TRACE("DRV_LOAD failed on driver %p\n", lpNewDrv); return FALSE; } /* returned value is not checked */ DRIVER_SendMessage(lpNewDrv, DRV_ENABLE, 0L, 0L); } lpNewDrv->lpNextItem = NULL; if (lpDrvItemList == NULL) { lpDrvItemList = lpNewDrv; lpNewDrv->lpPrevItem = NULL; } else { LPWINE_DRIVER lpDrv = lpDrvItemList; /* find end of list */ while (lpDrv->lpNextItem != NULL) lpDrv = lpDrv->lpNextItem; lpDrv->lpNextItem = lpNewDrv; lpNewDrv->lpPrevItem = lpDrv; } /* Now just open a new instance of a driver on this module */ lpNewDrv->dwDriverID = DRIVER_SendMessage(lpNewDrv, DRV_OPEN, lParam1, lParam2); if (lpNewDrv->dwDriverID == 0) { TRACE("DRV_OPEN failed on driver %p\n", lpNewDrv); DRIVER_RemoveFromList(lpNewDrv); return FALSE; } return TRUE; }
/************************************************************************** * DRIVER_RemoveFromList [internal] * * Generates all the logic to handle driver closure / deletion * Removes a driver struct to the list of open drivers. */ static BOOL DRIVER_RemoveFromList(LPWINE_DRIVER lpDrv) { lpDrv->dwDriverID = 0; if (DRIVER_GetNumberOfModuleRefs(lpDrv) == 1) { DRIVER_SendMessage(lpDrv, DRV_DISABLE, 0L, 0L); DRIVER_SendMessage(lpDrv, DRV_FREE, 0L, 0L); } if (lpDrv->lpPrevItem) lpDrv->lpPrevItem->lpNextItem = lpDrv->lpNextItem; else lpDrvItemList = lpDrv->lpNextItem; if (lpDrv->lpNextItem) lpDrv->lpNextItem->lpPrevItem = lpDrv->lpPrevItem; return TRUE; }
/************************************************************************** * CloseDriver [WINMM.@] * DrvClose [WINMM.@] */ LRESULT WINAPI CloseDriver(HDRVR hDrvr, LPARAM lParam1, LPARAM lParam2) { BOOL ret; LPWINE_DRIVER lpDrv; TRACE("(%p, %08lX, %08lX);\n", hDrvr, lParam1, lParam2); DRIVER_Dump("BEFORE:"); if ((lpDrv = DRIVER_FindFromHDrvr(hDrvr)) != NULL) { LPWINE_DRIVER lpDrv0; DRIVER_SendMessage(lpDrv, DRV_CLOSE, lParam1, lParam2); DRIVER_RemoveFromList(lpDrv); if (lpDrv->dwFlags & WINE_GDF_SESSION) FIXME("WINE_GDF_SESSION: Shouldn't happen (%p)\n", lpDrv); /* if driver has an opened session instance, we have to close it too */ if (DRIVER_GetNumberOfModuleRefs(lpDrv->hModule, &lpDrv0) == 1 && (lpDrv0->dwFlags & WINE_GDF_SESSION)) { DRIVER_SendMessage(lpDrv0, DRV_CLOSE, 0, 0); DRIVER_RemoveFromList(lpDrv0); FreeLibrary(lpDrv0->hModule); HeapFree(GetProcessHeap(), 0, lpDrv0); } FreeLibrary(lpDrv->hModule); HeapFree(GetProcessHeap(), 0, lpDrv); ret = TRUE; } else { WARN("Failed to close driver\n"); ret = FALSE; } DRIVER_Dump("AFTER:"); return ret; }
/************************************************************************** * DrvSendMessage (MMSYSTEM.1102) */ LRESULT WINAPI DrvSendMessage16(HDRVR16 hDriver, UINT16 msg, LPARAM lParam1, LPARAM lParam2) { LPWINE_DRIVER lpDrv; LRESULT retval = 0; TRACE("(%04x, %04X, %08lX, %08lX)\n", hDriver, msg, lParam1, lParam2); if ((lpDrv = DRIVER_FindFromHDrvr16(hDriver)) != NULL) { retval = DRIVER_SendMessage(lpDrv, msg, lParam1, lParam2); } else { WARN("Bad driver handle %u\n", hDriver); } TRACE("retval = %ld\n", retval); return retval; }
/************************************************************************** * CloseDriver (USER.253) */ LRESULT WINAPI CloseDriver16(HDRVR16 hDrvr, LPARAM lParam1, LPARAM lParam2) { LPWINE_DRIVER lpDrv; TRACE("(%04x, %08lX, %08lX);\n", hDrvr, lParam1, lParam2); if ((lpDrv = DRIVER_FindFromHDrvr16(hDrvr)) != NULL) { DRIVER_SendMessage(lpDrv, DRV_CLOSE, lParam1, lParam2); if (DRIVER_RemoveFromList(lpDrv)) { HeapFree(GetProcessHeap(), 0, lpDrv); return TRUE; } } WARN("Failed to close driver\n"); return FALSE; }