From 0b8426d44c4bd887d067c8886a500437a42e630e Mon Sep 17 00:00:00 2001 From: Damjan Jovanovic Date: Sun, 1 Mar 2015 20:25:02 +0200 Subject: winedevice: Make driver loading independent of global variables. To: wine-patches@winehq.org MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------2.6.3" This is a multi-part message in MIME format. --------------2.6.3 Content-Type: text/plain; charset=UTF-8; format=fixed Content-Transfer-Encoding: 8bit --- programs/winedevice/device.c | 60 ++++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 22 deletions(-) --------------2.6.3 Content-Type: text/x-patch; name="0001-winedevice-Make-driver-loading-independent-of-global-v.txt" Content-Transfer-Encoding: 8bit Content-Disposition: attachment; filename="0001-winedevice-Make-driver-loading-independent-of-global-v.txt" diff --git a/programs/winedevice/device.c b/programs/winedevice/device.c index ef1e1ef..a1508a7 100644 --- a/programs/winedevice/device.c +++ b/programs/winedevice/device.c @@ -42,10 +42,7 @@ extern NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event ); static WCHAR *driver_name; static SERVICE_STATUS_HANDLE service_handle; -static HKEY driver_hkey; static HANDLE stop_event; -static DRIVER_OBJECT driver_obj; -static DRIVER_EXTENSION driver_extension; /* find the LDR_MODULE corresponding to the driver module */ static LDR_MODULE *find_ldr_module( HMODULE module ) @@ -131,39 +128,51 @@ error: } /* call the driver init entry point */ -static NTSTATUS init_driver( HMODULE module, UNICODE_STRING *keyname ) +static NTSTATUS init_driver( HMODULE module, LPCWSTR driver_name, DRIVER_OBJECT **p_driver_obj, + UNICODE_STRING *keyname ) { unsigned int i; + DRIVER_OBJECT *driver_obj = NULL; NTSTATUS status; const IMAGE_NT_HEADERS *nt = RtlImageNtHeader( module ); if (!nt->OptionalHeader.AddressOfEntryPoint) return STATUS_SUCCESS; - driver_obj.Size = sizeof(driver_obj); - driver_obj.DriverSection = find_ldr_module( module ); - driver_obj.DriverInit = (PDRIVER_INITIALIZE)((char *)module + nt->OptionalHeader.AddressOfEntryPoint); - driver_obj.DriverExtension = &driver_extension; + driver_obj = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(DRIVER_OBJECT) + sizeof(DRIVER_EXTENSION) ); + if (driver_obj == NULL) + return STATUS_NO_MEMORY; - driver_extension.DriverObject = &driver_obj; - driver_extension.ServiceKeyName = *keyname; + driver_obj->Size = sizeof(*driver_obj); + /* FIXME: DriverSection is wrong, see http://stackoverflow.com/questions/9017952/driver-object-driversection */ + driver_obj->DriverSection = find_ldr_module( module ); + driver_obj->DriverInit = (PDRIVER_INITIALIZE)((char *)module + nt->OptionalHeader.AddressOfEntryPoint); + driver_obj->DriverExtension = (DRIVER_EXTENSION *)(driver_obj + 1); + + driver_obj->DriverExtension->DriverObject = driver_obj; + driver_obj->DriverExtension->ServiceKeyName = *keyname; if (WINE_TRACE_ON(relay)) WINE_DPRINTF( "%04x:Call driver init %p (obj=%p,str=%s)\n", GetCurrentThreadId(), - driver_obj.DriverInit, &driver_obj, wine_dbgstr_w(keyname->Buffer) ); + driver_obj->DriverInit, driver_obj, wine_dbgstr_w(keyname->Buffer) ); - status = driver_obj.DriverInit( &driver_obj, keyname ); + status = driver_obj->DriverInit( driver_obj, keyname ); if (WINE_TRACE_ON(relay)) WINE_DPRINTF( "%04x:Ret driver init %p (obj=%p,str=%s) retval=%08x\n", GetCurrentThreadId(), - driver_obj.DriverInit, &driver_obj, wine_dbgstr_w(keyname->Buffer), status ); + driver_obj->DriverInit, driver_obj, wine_dbgstr_w(keyname->Buffer), status ); - WINE_TRACE( "init done for %s obj %p\n", wine_dbgstr_w(driver_name), &driver_obj ); - WINE_TRACE( "- DriverInit = %p\n", driver_obj.DriverInit ); - WINE_TRACE( "- DriverStartIo = %p\n", driver_obj.DriverStartIo ); - WINE_TRACE( "- DriverUnload = %p\n", driver_obj.DriverUnload ); + WINE_TRACE( "init done for %s obj %p\n", wine_dbgstr_w(driver_name), driver_obj ); + WINE_TRACE( "- DriverInit = %p\n", driver_obj->DriverInit ); + WINE_TRACE( "- DriverStartIo = %p\n", driver_obj->DriverStartIo ); + WINE_TRACE( "- DriverUnload = %p\n", driver_obj->DriverUnload ); for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) - WINE_TRACE( "- MajorFunction[%d] = %p\n", i, driver_obj.MajorFunction[i] ); + WINE_TRACE( "- MajorFunction[%d] = %p\n", i, driver_obj->MajorFunction[i] ); + if (status == STATUS_SUCCESS) + *p_driver_obj = driver_obj; + else + RtlFreeHeap( GetProcessHeap(), 0, driver_obj ); return status; } @@ -186,7 +195,7 @@ static void unload_driver( HMODULE module, DRIVER_OBJECT *driver_obj ) } /* load the .sys module for a device driver */ -static HMODULE load_driver(void) +static HMODULE load_driver( LPCWSTR driver_name, DRIVER_OBJECT **driver_obj ) { static const WCHAR driversW[] = {'\\','d','r','i','v','e','r','s','\\',0}; static const WCHAR systemrootW[] = {'\\','S','y','s','t','e','m','R','o','o','t','\\',0}; @@ -201,6 +210,7 @@ static HMODULE load_driver(void) UNICODE_STRING keypath; HMODULE module; + HKEY driver_hkey; LPWSTR path = NULL, str; DWORD type, size; @@ -269,7 +279,11 @@ static HMODULE load_driver(void) HeapFree( GetProcessHeap(), 0, path ); if (!module) return NULL; - init_driver( module, &keypath ); + if (init_driver( module, driver_name, driver_obj, &keypath ) != STATUS_SUCCESS) + { + FreeLibrary(module); + return NULL; + } return module; } @@ -306,6 +320,7 @@ static void WINAPI ServiceMain( DWORD argc, LPWSTR *argv ) { SERVICE_STATUS status; HMODULE driver_module; + DRIVER_OBJECT *driver_obj; WINE_TRACE( "starting service %s\n", wine_dbgstr_w(driver_name) ); @@ -324,7 +339,7 @@ static void WINAPI ServiceMain( DWORD argc, LPWSTR *argv ) status.dwWaitHint = 10000; SetServiceStatus( service_handle, &status ); - driver_module = load_driver(); + driver_module = load_driver( driver_name, &driver_obj ); if (driver_module) { status.dwCurrentState = SERVICE_RUNNING; @@ -332,7 +347,8 @@ static void WINAPI ServiceMain( DWORD argc, LPWSTR *argv ) SetServiceStatus( service_handle, &status ); wine_ntoskrnl_main_loop( stop_event ); - unload_driver( driver_module, &driver_obj ); + unload_driver( driver_module, driver_obj ); + RtlFreeHeap( GetProcessHeap(), 0, driver_obj ); } else WINE_ERR( "driver %s failed to load\n", wine_dbgstr_w(driver_name) ); --------------2.6.3--