wine-staging/patches/winedevice-DriverUnload/0001-winedevice-Call-DriverUnload-function-when-unloading.patch

84 lines
2.9 KiB
Diff
Raw Normal View History

From 2ccb50c0dd04ae77d39dac6406f8cfa6e102aa91 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Mon, 26 Jan 2015 04:31:10 +0100
Subject: winedevice: Call DriverUnload function when unloading a driver.
Based on a patch by Alexander Morozov.
---
programs/winedevice/device.c | 29 +++++++++++++++++++++++++----
1 file changed, 25 insertions(+), 4 deletions(-)
diff --git a/programs/winedevice/device.c b/programs/winedevice/device.c
index 72bc124..edd7c83 100644
--- a/programs/winedevice/device.c
+++ b/programs/winedevice/device.c
@@ -45,6 +45,7 @@ static SERVICE_STATUS_HANDLE service_handle;
static HKEY driver_hkey;
static HANDLE stop_event;
static DRIVER_OBJECT driver_obj;
+static HMODULE driver_module;
static DRIVER_EXTENSION driver_extension;
/* find the LDR_MODULE corresponding to the driver module */
@@ -167,8 +168,26 @@ static NTSTATUS init_driver( HMODULE module, UNICODE_STRING *keyname )
return status;
}
+/* call the driver unload function */
+static void unload_driver( HMODULE module, DRIVER_OBJECT *driver_obj )
+{
+ if (driver_obj->DriverUnload)
+ {
+ if (WINE_TRACE_ON(relay))
+ WINE_DPRINTF( "%04x:Call driver unload %p (obj=%p)\n", GetCurrentThreadId(),
+ driver_obj->DriverUnload, driver_obj );
+
+ driver_obj->DriverUnload( driver_obj );
+
+ if (WINE_TRACE_ON(relay))
+ WINE_DPRINTF( "%04x:Ret driver unload %p (obj=%p)\n", GetCurrentThreadId(),
+ driver_obj->DriverUnload, driver_obj );
+ }
+ FreeLibrary( module );
+}
+
/* load the .sys module for a device driver */
-static BOOL load_driver(void)
+static HMODULE load_driver(void)
{
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};
@@ -249,10 +268,10 @@ static BOOL load_driver(void)
module = load_driver_module( str );
HeapFree( GetProcessHeap(), 0, path );
- if (!module) return FALSE;
+ if (!module) return NULL;
init_driver( module, &keypath );
- return TRUE;
+ return module;
}
static DWORD WINAPI service_handler( DWORD ctrl, DWORD event_type, LPVOID event_data, LPVOID context )
@@ -305,13 +324,15 @@ static void WINAPI ServiceMain( DWORD argc, LPWSTR *argv )
status.dwWaitHint = 10000;
SetServiceStatus( service_handle, &status );
- if (load_driver())
+ driver_module = load_driver();
+ if (driver_module)
{
status.dwCurrentState = SERVICE_RUNNING;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
SetServiceStatus( service_handle, &status );
wine_ntoskrnl_main_loop( stop_event );
+ unload_driver( driver_module, &driver_obj );
}
else WINE_ERR( "driver %s failed to load\n", wine_dbgstr_w(driver_name) );
--
1.9.1