/* * WINE Drivers functions * * Copyright 1994 Martin Ayotte * Copyright 1998 Marcus Meissner */ #include "wine/winuser16.h" #include "heap.h" #include "win.h" #include "callback.h" #include "driver.h" #include "module.h" #include "debug.h" #include LPDRIVERITEM lpDrvItemList = NULL; LPDRIVERITEM32A lpDrvItemList32 = NULL; /************************************************************************** * LoadStartupDrivers */ static void LoadStartupDrivers(void) { HDRVR16 hDrv; char str[256]; LPSTR ptr; if (GetPrivateProfileString32A( "drivers", NULL, "", str, sizeof(str), "SYSTEM.INI" ) < 2) { ERR( driver,"Can't find drivers section in system.ini\n" ); return; } ptr = str; while (lstrlen32A( ptr ) != 0) { TRACE(driver, "str='%s'\n", ptr ); hDrv = OpenDriver16( ptr, "drivers", 0L ); TRACE(driver, "hDrv=%04x\n", hDrv ); ptr += lstrlen32A(ptr) + 1; } TRACE(driver, "end of list !\n" ); return; } /************************************************************************** * SendDriverMessage [USER.251] */ LRESULT WINAPI SendDriverMessage16(HDRVR16 hDriver, UINT16 msg, LPARAM lParam1, LPARAM lParam2) { LPDRIVERITEM lpdrv; LRESULT retval; TRACE(driver, "(%04x, %04X, %08lX, %08lX)\n", hDriver, msg, lParam1, lParam2 ); lpdrv = (LPDRIVERITEM)GlobalLock16( hDriver ); if (lpdrv == NULL || lpdrv->dis.hDriver != hDriver) { GlobalUnlock16( hDriver ); return 0; } retval = Callbacks->CallDriverProc( lpdrv->lpDrvProc, 0L /* FIXME */, hDriver, msg, lParam1, lParam2 ); TRACE(driver, "retval = %ld\n", retval ); GlobalUnlock16( hDriver ); return retval; } /************************************************************************** * SendDriverMessage [WINMM.19] */ LRESULT WINAPI SendDriverMessage32(HDRVR32 hDriver, UINT32 msg, LPARAM lParam1, LPARAM lParam2) { LPDRIVERITEM32A lpdrv; LRESULT retval; TRACE(driver, "(%04x, %04X, %08lX, %08lX)\n", hDriver, msg, lParam1, lParam2 ); lpdrv = (LPDRIVERITEM32A)hDriver; if (!lpdrv) return 0; retval = lpdrv->driverproc(lpdrv->dis.hDriver,hDriver,msg,lParam1,lParam2); TRACE(driver, "retval = %ld\n", retval ); return retval; } /************************************************************************** * OpenDriver [USER.252] */ HDRVR16 WINAPI OpenDriver16( LPCSTR lpDriverName, LPCSTR lpSectionName, LPARAM lParam ) { HDRVR16 hDrvr; LPDRIVERITEM lpdrv, lpnewdrv; char DrvName[128]; TRACE(driver,"('%s', '%s', %08lX);\n", lpDriverName, lpSectionName, lParam ); if (lpSectionName == NULL) { lstrcpyn32A(DrvName,lpDriverName,sizeof(DrvName)); FIXME(driver,"sectionname NULL, assuming directfilename (%s)\n",lpDriverName); } else { GetPrivateProfileString32A( lpSectionName, lpDriverName, "", DrvName, sizeof(DrvName), "SYSTEM.INI" ); } TRACE(driver,"DrvName='%s'\n", DrvName ); if (lstrlen32A(DrvName) < 1) return 0; lpdrv = lpDrvItemList; while (lpdrv) /* XXX find it... like this? */ { if (!strcasecmp( lpDriverName, lpdrv->dis.szAliasName )) { lpdrv->count++; SendDriverMessage16( lpdrv->dis.hDriver, DRV_OPEN, 0L, lParam ); return lpdrv->dis.hDriver; } lpdrv = lpdrv->lpNextItem; } lpdrv = lpDrvItemList; /* find end of list */ if (lpdrv != NULL) while (lpdrv->lpNextItem != NULL) lpdrv = lpdrv->lpNextItem; hDrvr = GlobalAlloc16( GMEM_MOVEABLE, sizeof(DRIVERITEM) ); lpnewdrv = (LPDRIVERITEM)GlobalLock16( hDrvr ); if (lpnewdrv == NULL) return 0; lpnewdrv->dis.length = sizeof( DRIVERINFOSTRUCT16 ); lpnewdrv->dis.hModule = LoadModule16( DrvName, (LPVOID)-1 ); if (!lpnewdrv->dis.hModule) { GlobalUnlock16( hDrvr ); GlobalFree16( hDrvr ); return 0; } lpnewdrv->dis.hDriver = hDrvr; lstrcpy32A( lpnewdrv->dis.szAliasName, lpDriverName ); lpnewdrv->count = 1; if (!(lpnewdrv->lpDrvProc = (DRIVERPROC16)WIN32_GetProcAddress16(lpnewdrv->dis.hModule, "DRIVERPROC" ))) { FreeModule16( lpnewdrv->dis.hModule ); GlobalUnlock16( hDrvr ); GlobalFree16( hDrvr ); return 0; } lpnewdrv->lpNextItem = NULL; if (lpDrvItemList == NULL) { lpDrvItemList = lpnewdrv; lpnewdrv->lpPrevItem = NULL; } else { lpdrv->lpNextItem = lpnewdrv; lpnewdrv->lpPrevItem = lpdrv; } SendDriverMessage16( hDrvr, DRV_LOAD, 0L, lParam ); SendDriverMessage16( hDrvr, DRV_ENABLE, 0L, lParam ); SendDriverMessage16( hDrvr, DRV_OPEN, 0L, lParam ); TRACE(driver, "hDrvr=%04x loaded !\n", hDrvr ); return hDrvr; } /************************************************************************** * OpenDriver [WINMM.15] * (0,1,DRV_LOAD ,0 ,0) * (0,1,DRV_ENABLE,0 ,0) * (0,1,DRV_OPEN ,buf[256],0) */ HDRVR32 WINAPI OpenDriver32A( LPCSTR lpDriverName, LPCSTR lpSectionName, LPARAM lParam ) { HDRVR32 hDrvr; LPDRIVERITEM32A lpdrv, lpnewdrv; char DrvName[128],*tmpbuf; TRACE(driver,"('%s', '%s', %08lX);\n", lpDriverName,lpSectionName,lParam ); if (lpSectionName == NULL) { lstrcpyn32A(DrvName,lpDriverName,sizeof(DrvName)); FIXME(driver,"sectionname NULL, assuming directfilename (%s)\n",lpDriverName); } else { GetPrivateProfileString32A( lpSectionName, lpDriverName, "", DrvName, sizeof(DrvName), "system.ini" ); } TRACE(driver,"DrvName='%s'\n", DrvName ); if (lstrlen32A(DrvName) < 1) return 0; lpdrv = lpDrvItemList32; while (lpdrv) { if (!strcasecmp( lpDriverName, lpdrv->dis.szAliasName )) { lpdrv->count++; lpdrv->dis.hDriver = SendDriverMessage32( lpdrv->dis.hDriver, DRV_OPEN, (LPARAM)""/*FIXME*/, 0L ); return (HDRVR32)lpdrv; } lpdrv = lpdrv->next; } hDrvr = (HDRVR32)HeapAlloc(SystemHeap,0, sizeof(DRIVERITEM32A) ); if (!hDrvr) { ERR(driver,"out of memory"); return 0; } lpnewdrv = (DRIVERITEM32A*)hDrvr; lpnewdrv->dis.length = sizeof( DRIVERINFOSTRUCT32A ); lpnewdrv->dis.hModule = LoadLibrary32A( DrvName ); if (!lpnewdrv->dis.hModule) { FIXME(driver,"could not load library %s\n",DrvName); HeapFree( SystemHeap,0,(LPVOID)hDrvr ); return 0; } lstrcpy32A( lpnewdrv->dis.szAliasName, lpDriverName ); lpnewdrv->count = 1; if (!(lpnewdrv->driverproc = (DRIVERPROC32)GetProcAddress32(lpnewdrv->dis.hModule, "DriverProc" ))) { FIXME(driver,"no 'DriverProc' found in %s\n",DrvName); FreeModule32( lpnewdrv->dis.hModule ); HeapFree( SystemHeap,0, (LPVOID)hDrvr ); return 0; } lpnewdrv->next = lpDrvItemList32; lpDrvItemList32 = lpnewdrv; SendDriverMessage32( hDrvr, DRV_LOAD, 0L, lParam ); SendDriverMessage32( hDrvr, DRV_ENABLE, 0L, lParam ); tmpbuf = HeapAlloc(SystemHeap,0,256); lpnewdrv->dis.hDriver=SendDriverMessage32(hDrvr,DRV_OPEN,(LPARAM)tmpbuf,lParam); HeapFree(SystemHeap,0,tmpbuf); TRACE(driver, "hDrvr=%04x loaded !\n", hDrvr ); return hDrvr; } /************************************************************************** * OpenDriver [WINMM.15] */ HDRVR32 WINAPI OpenDriver32W( LPCWSTR lpDriverName, LPCWSTR lpSectionName, LPARAM lParam ) { LPSTR dn = HEAP_strdupWtoA(GetProcessHeap(),0,lpDriverName); LPSTR sn = HEAP_strdupWtoA(GetProcessHeap(),0,lpSectionName); HDRVR32 ret = OpenDriver32A(dn,sn,lParam); if (dn) HeapFree(GetProcessHeap(),0,dn); if (sn) HeapFree(GetProcessHeap(),0,sn); return ret; } /************************************************************************** * CloseDriver [USER.253] */ LRESULT WINAPI CloseDriver16(HDRVR16 hDrvr, LPARAM lParam1, LPARAM lParam2) { LPDRIVERITEM lpdrv; TRACE(driver, "(%04x, %08lX, %08lX);\n", hDrvr, lParam1, lParam2 ); lpdrv = (LPDRIVERITEM)GlobalLock16( hDrvr ); if (lpdrv != NULL && lpdrv->dis.hDriver == hDrvr) { SendDriverMessage16( hDrvr, DRV_CLOSE, lParam1, lParam2 ); if (--lpdrv->count == 0) { SendDriverMessage16( hDrvr, DRV_DISABLE, lParam1, lParam2 ); SendDriverMessage16( hDrvr, DRV_FREE, lParam1, lParam2 ); if (lpdrv->lpPrevItem) lpdrv->lpPrevItem->lpNextItem = lpdrv->lpNextItem; else lpDrvItemList = lpdrv->lpNextItem; if (lpdrv->lpNextItem) lpdrv->lpNextItem->lpPrevItem = lpdrv->lpPrevItem; FreeModule16( lpdrv->dis.hModule ); GlobalUnlock16( hDrvr ); GlobalFree16( hDrvr ); } TRACE(driver, "hDrvr=%04x closed !\n", hDrvr ); return TRUE; } return FALSE; } /************************************************************************** * GetDriverModuleHandle [USER.254] */ HMODULE16 WINAPI GetDriverModuleHandle16(HDRVR16 hDrvr) { LPDRIVERITEM lpdrv; HMODULE16 hModule = 0; TRACE(driver, "(%04x);\n", hDrvr); lpdrv = (LPDRIVERITEM)GlobalLock16( hDrvr ); if (lpdrv != NULL && lpdrv->dis.hDriver == hDrvr) { hModule = lpdrv->dis.hModule; GlobalUnlock16( hDrvr ); } return hModule; } /************************************************************************** * GetDriverModuleHandle [USER.254] */ HMODULE32 WINAPI GetDriverModuleHandle32(HDRVR32 hDrvr) { LPDRIVERITEM32A lpdrv = (LPDRIVERITEM32A)hDrvr; TRACE(driver, "(%04x);\n", hDrvr); if (!lpdrv) return 0; return lpdrv->dis.hModule; } /************************************************************************** * DefDriverProc16 [USER.255] */ LRESULT WINAPI DefDriverProc16(DWORD dwDevID, HDRVR16 hDriv, UINT16 wMsg, LPARAM lParam1, LPARAM lParam2) { switch(wMsg) { case DRV_LOAD: return (LRESULT)0L; case DRV_FREE: return (LRESULT)0L; case DRV_OPEN: return (LRESULT)0L; case DRV_CLOSE: return (LRESULT)0L; case DRV_ENABLE: return (LRESULT)0L; case DRV_DISABLE: return (LRESULT)0L; case DRV_QUERYCONFIGURE: return (LRESULT)0L; case DRV_CONFIGURE: MessageBox16( 0, "Driver isn't configurable !", "Wine Driver", MB_OK ); return (LRESULT)0L; case DRV_INSTALL: return (LRESULT)DRVCNF_RESTART; case DRV_REMOVE: return (LRESULT)DRVCNF_RESTART; default: return (LRESULT)0L; } } /************************************************************************** * GetDriverInfo [USER.256] */ BOOL16 WINAPI GetDriverInfo(HDRVR16 hDrvr, LPDRIVERINFOSTRUCT16 lpDrvInfo) { LPDRIVERITEM lpdrv; TRACE(driver, "(%04x, %p);\n", hDrvr, lpDrvInfo ); if (lpDrvInfo == NULL) return FALSE; lpdrv = (LPDRIVERITEM)GlobalLock16( hDrvr ); if (lpdrv == NULL) return FALSE; memcpy( lpDrvInfo, &lpdrv->dis, sizeof(DRIVERINFOSTRUCT16) ); GlobalUnlock16( hDrvr ); return TRUE; } /************************************************************************** * GetNextDriver [USER.257] */ HDRVR16 WINAPI GetNextDriver(HDRVR16 hDrvr, DWORD dwFlags) { LPDRIVERITEM lpdrv; HDRVR16 hRetDrv = 0; TRACE(driver, "(%04x, %08lX);\n", hDrvr, dwFlags ); if (hDrvr == 0) { if (lpDrvItemList == NULL) { TRACE(driver, "drivers list empty !\n"); LoadStartupDrivers(); if (lpDrvItemList == NULL) return 0; } TRACE(driver,"return first %04x !\n", lpDrvItemList->dis.hDriver ); return lpDrvItemList->dis.hDriver; } lpdrv = (LPDRIVERITEM)GlobalLock16( hDrvr ); if (lpdrv != NULL) { if (dwFlags & GND_REVERSE) { if (lpdrv->lpPrevItem) hRetDrv = lpdrv->lpPrevItem->dis.hDriver; } else { if (lpdrv->lpNextItem) hRetDrv = lpdrv->lpNextItem->dis.hDriver; } GlobalUnlock16( hDrvr ); } TRACE(driver, "return %04x !\n", hRetDrv ); return hRetDrv; }