| /* | |
| * WINE Drivers functions | |
| * | |
| * Copyright 1994 Martin Ayotte | |
| * Copyright 1998 Marcus Meissner | |
| */ | |
| #include "windows.h" | |
| #include "heap.h" | |
| #include "win.h" | |
| #include "callback.h" | |
| #include "driver.h" | |
| #include "module.h" | |
| #include "debug.h" | |
| #include <string.h> | |
| 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; | |
| } |