📄 driver.c
字号:
{cause = "load failed"; goto exit;}
TRACE("=> %p\n", lpDrv);
return lpDrv;
exit:
FreeLibrary(hModule);
HeapFree(GetProcessHeap(), 0, lpDrv);
TRACE("Unable to load 32 bit module %s: %s\n", debugstr_w(fn), cause);
return NULL;
}
/**************************************************************************
* OpenDriverA [WINMM.@]
* DrvOpenA [WINMM.@]
* (0,1,DRV_LOAD ,0 ,0)
* (0,1,DRV_ENABLE,0 ,0)
* (0,1,DRV_OPEN ,buf[256],0)
*/
HDRVR WINAPI OpenDriverA(LPCSTR lpDriverName, LPCSTR lpSectionName, LPARAM lParam)
{
INT len;
LPWSTR dn = NULL;
LPWSTR sn = NULL;
HDRVR ret = 0;
if (lpDriverName)
{
len = MultiByteToWideChar( CP_ACP, 0, lpDriverName, -1, NULL, 0 );
dn = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
if (!dn) goto done;
MultiByteToWideChar( CP_ACP, 0, lpDriverName, -1, dn, len );
}
if (lpSectionName)
{
len = MultiByteToWideChar( CP_ACP, 0, lpSectionName, -1, NULL, 0 );
sn = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
if (!sn) goto done;
MultiByteToWideChar( CP_ACP, 0, lpSectionName, -1, sn, len );
}
ret = OpenDriver(dn, sn, lParam);
done:
HeapFree(GetProcessHeap(), 0, dn);
HeapFree(GetProcessHeap(), 0, sn);
return ret;
}
/**************************************************************************
* OpenDriver [WINMM.@]
* DrvOpen [WINMM.@]
*/
HDRVR WINAPI OpenDriver(LPCWSTR lpDriverName, LPCWSTR lpSectionName, LPARAM lParam)
{
LPWINE_DRIVER lpDrv = NULL;
WCHAR libName[128];
LPCWSTR lsn = lpSectionName;
TRACE("(%s, %s, 0x%08lx);\n",
debugstr_w(lpDriverName), debugstr_w(lpSectionName), lParam);
if (lsn == NULL) {
static const WCHAR wszDrivers32[] = {'D','r','i','v','e','r','s','3','2',0};
lstrcpynW(libName, lpDriverName, sizeof(libName) / sizeof(WCHAR));
if ((lpDrv = DRIVER_TryOpenDriver32(libName, lParam)))
goto the_end;
lsn = wszDrivers32;
}
if (DRIVER_GetLibName(lpDriverName, lsn, libName, sizeof(libName)) &&
(lpDrv = DRIVER_TryOpenDriver32(libName, lParam)))
goto the_end;
/* now we will try a 16 bit driver (and add all the glue to make it work... which
* is located in our mmsystem implementation)
* so ensure, we can load our mmsystem, otherwise just fail
*/
WINMM_CheckForMMSystem();
if (pFnOpenDriver16 &&
(lpDrv = pFnOpenDriver16(lpDriverName, lpSectionName, lParam)))
{
if (DRIVER_AddToList(lpDrv, 0, lParam)) goto the_end;
HeapFree(GetProcessHeap(), 0, lpDrv);
}
TRACE("Failed to open driver %s from system.ini file, section %s\n",
debugstr_w(lpDriverName), debugstr_w(lpSectionName));
return 0;
the_end:
if (lpDrv) TRACE("=> %08lx\n", (DWORD)lpDrv);
return (HDRVR)lpDrv;
}
/**************************************************************************
* CloseDriver [WINMM.@]
* DrvClose [WINMM.@]
*/
LRESULT WINAPI CloseDriver(HDRVR hDrvr, LPARAM lParam1, LPARAM lParam2)
{
LPWINE_DRIVER lpDrv;
TRACE("(%p, %08lX, %08lX);\n", hDrvr, lParam1, lParam2);
if ((lpDrv = DRIVER_FindFromHDrvr(hDrvr)) != NULL)
{
if (lpDrv->dwFlags & WINE_GDF_16BIT)
{
if (pFnCloseDriver16)
pFnCloseDriver16(lpDrv->d.d16.hDriver16, lParam1, lParam2);
}
else
{
DRIVER_SendMessage(lpDrv, DRV_CLOSE, lParam1, lParam2);
lpDrv->d.d32.dwDriverID = 0;
}
if (DRIVER_RemoveFromList(lpDrv)) {
if (!(lpDrv->dwFlags & WINE_GDF_16BIT))
{
LPWINE_DRIVER lpDrv0;
/* if driver has an opened session instance, we have to close it too */
if (DRIVER_GetNumberOfModuleRefs(lpDrv->d.d32.hModule, &lpDrv0) == 1)
{
DRIVER_SendMessage(lpDrv0, DRV_CLOSE, 0L, 0L);
lpDrv0->d.d32.dwDriverID = 0;
DRIVER_RemoveFromList(lpDrv0);
FreeLibrary(lpDrv0->d.d32.hModule);
HeapFree(GetProcessHeap(), 0, lpDrv0);
}
FreeLibrary(lpDrv->d.d32.hModule);
}
HeapFree(GetProcessHeap(), 0, lpDrv);
return TRUE;
}
}
WARN("Failed to close driver\n");
return FALSE;
}
/**************************************************************************
* GetDriverFlags [WINMM.@]
* [in] hDrvr handle to the driver
*
* Returns:
* 0x00000000 if hDrvr is an invalid handle
* 0x80000000 if hDrvr is a valid 32 bit driver
* 0x90000000 if hDrvr is a valid 16 bit driver
*
* native WINMM doesn't return those flags
* 0x80000000 for a valid 32 bit driver and that's it
* (I may have mixed up the two flags :-(
*/
DWORD WINAPI GetDriverFlags(HDRVR hDrvr)
{
LPWINE_DRIVER lpDrv;
DWORD ret = 0;
TRACE("(%p)\n", hDrvr);
if ((lpDrv = DRIVER_FindFromHDrvr(hDrvr)) != NULL) {
ret = WINE_GDF_EXIST | lpDrv->dwFlags;
}
return ret;
}
/**************************************************************************
* GetDriverModuleHandle [WINMM.@]
* DrvGetModuleHandle [WINMM.@]
*/
HMODULE WINAPI GetDriverModuleHandle(HDRVR hDrvr)
{
LPWINE_DRIVER lpDrv;
HMODULE hModule = 0;
TRACE("(%p);\n", hDrvr);
if ((lpDrv = DRIVER_FindFromHDrvr(hDrvr)) != NULL) {
if (!(lpDrv->dwFlags & WINE_GDF_16BIT))
hModule = lpDrv->d.d32.hModule;
}
TRACE("=> %p\n", hModule);
return hModule;
}
/**************************************************************************
* DefDriverProc [WINMM.@]
* DrvDefDriverProc [WINMM.@]
*/
LRESULT WINAPI DefDriverProc(DWORD_PTR dwDriverIdentifier, HDRVR hDrv,
UINT Msg, LPARAM lParam1, LPARAM lParam2)
{
switch (Msg) {
case DRV_LOAD:
case DRV_FREE:
case DRV_ENABLE:
case DRV_DISABLE:
return 1;
case DRV_INSTALL:
case DRV_REMOVE:
return DRV_SUCCESS;
default:
return 0;
}
}
/**************************************************************************
* DriverCallback [WINMM.@]
*/
BOOL WINAPI DriverCallback(DWORD dwCallBack, UINT uFlags, HDRVR hDev,
UINT wMsg, DWORD dwUser, DWORD dwParam1,
DWORD dwParam2)
{
TRACE("(%08lX, %04X, %p, %04X, %08lX, %08lX, %08lX); !\n",
dwCallBack, uFlags, hDev, wMsg, dwUser, dwParam1, dwParam2);
switch (uFlags & DCB_TYPEMASK) {
case DCB_NULL:
TRACE("Null !\n");
if (dwCallBack)
WARN("uFlags=%04X has null DCB value, but dwCallBack=%08lX is not null !\n", uFlags, dwCallBack);
break;
case DCB_WINDOW:
TRACE("Window(%04lX) handle=%p!\n", dwCallBack, hDev);
PostMessageA((HWND)dwCallBack, wMsg, (WPARAM)hDev, dwParam1);
break;
case DCB_TASK: /* aka DCB_THREAD */
TRACE("Task(%04lx) !\n", dwCallBack);
PostThreadMessageA(dwCallBack, wMsg, (WPARAM)hDev, dwParam1);
break;
case DCB_FUNCTION:
TRACE("Function (32 bit) !\n");
((LPDRVCALLBACK)dwCallBack)(hDev, wMsg, dwUser, dwParam1, dwParam2);
break;
case DCB_EVENT:
TRACE("Event(%08lx) !\n", dwCallBack);
SetEvent((HANDLE)dwCallBack);
break;
case 6: /* I would dub it DCB_MMTHREADSIGNAL */
/* this is an undocumented DCB_ value used for mmThreads
* loword of dwCallBack contains the handle of the lpMMThd block
* which dwSignalCount has to be incremented
*/
if (pFnGetMMThread16)
{
WINE_MMTHREAD* lpMMThd = pFnGetMMThread16(LOWORD(dwCallBack));
TRACE("mmThread (%04x, %p) !\n", LOWORD(dwCallBack), lpMMThd);
/* same as mmThreadSignal16 */
InterlockedIncrement(&lpMMThd->dwSignalCount);
SetEvent(lpMMThd->hEvent);
/* some other stuff on lpMMThd->hVxD */
}
break;
#if 0
case 4:
/* this is an undocumented DCB_ value for... I don't know */
break;
#endif
default:
WARN("Unknown callback type %d\n", uFlags & DCB_TYPEMASK);
return FALSE;
}
TRACE("Done\n");
return TRUE;
}
/******************************************************************
* DRIVER_UnloadAll
*
*
*/
void DRIVER_UnloadAll(void)
{
LPWINE_DRIVER lpDrv;
LPWINE_DRIVER lpNextDrv = NULL;
unsigned count = 0;
for (lpDrv = lpDrvItemList; lpDrv != NULL; lpDrv = lpNextDrv)
{
lpNextDrv = lpDrv->lpNextItem;
CloseDriver((HDRVR)lpDrv, 0, 0);
count++;
}
TRACE("Unloaded %u drivers\n", count);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -