[2/2] winedevice: special-case usbd.sys loading
Damjan Jovanovic
damjan.jov at gmail.com
Mon Nov 15 14:03:56 CST 2010
Changelog:
* winedevice: special-case usbd.sys loading
Damjan Jovanovic
-------------- next part --------------
diff --git a/programs/winedevice/device.c b/programs/winedevice/device.c
index 2ce8c15..c92bc11 100644
--- a/programs/winedevice/device.c
+++ b/programs/winedevice/device.c
@@ -46,6 +46,8 @@ static HKEY driver_hkey;
static HANDLE stop_event;
static DRIVER_OBJECT driver_obj;
static DRIVER_EXTENSION driver_extension;
+static DRIVER_OBJECT usbd_driver;
+static DRIVER_EXTENSION usbd_extension;
/* find the LDR_MODULE corresponding to the driver module */
static LDR_MODULE *find_ldr_module( HMODULE module )
@@ -130,7 +132,7 @@ error:
}
/* call the driver init entry point */
-static NTSTATUS init_driver( HMODULE module, UNICODE_STRING *keyname )
+static NTSTATUS init_driver( DRIVER_OBJECT *driver_obj, DRIVER_EXTENSION *driver_extension, HMODULE module, UNICODE_STRING *keyname )
{
unsigned int i;
NTSTATUS status;
@@ -138,34 +140,55 @@ static NTSTATUS init_driver( HMODULE module, UNICODE_STRING *keyname )
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->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_extension.DriverObject = &driver_obj;
- driver_extension.ServiceKeyName = *keyname;
+ driver_extension->DriverObject = driver_obj;
+ driver_extension->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] );
return status;
}
+static void load_additional_drivers(void)
+{
+ /* Tests on Windows show DriverEntry() is not called
+ * on SYS files loaded via DLL imports, but we must
+ * initialize USBD.SYS somehow...
+ */
+ HMODULE usbd = GetModuleHandleA( "USBD.SYS" );
+ if (usbd)
+ {
+ void (WINAPI *__wine_usbd_init)(DRIVER_OBJECT*,DRIVER_OBJECT*);
+ UNICODE_STRING str;
+ static const WCHAR emptyW[] = {0};
+
+ RtlInitUnicodeString( &str, emptyW );
+ init_driver( &usbd_driver, &usbd_extension, usbd, &str );
+ __wine_usbd_init = (void*) GetProcAddress( usbd, "__wine_usbd_init" );
+ if (__wine_usbd_init)
+ __wine_usbd_init( &usbd_driver, &driver_obj );
+ }
+}
+
/* load the .sys module for a device driver */
static BOOL load_driver(void)
{
@@ -183,6 +206,7 @@ static BOOL load_driver(void)
HMODULE module;
LPWSTR path = NULL, str;
DWORD type, size;
+ NTSTATUS status;
str = HeapAlloc( GetProcessHeap(), 0, sizeof(servicesW) + strlenW(driver_name)*sizeof(WCHAR) );
lstrcpyW( str, servicesW );
@@ -234,8 +258,10 @@ static BOOL load_driver(void)
HeapFree( GetProcessHeap(), 0, path );
if (!module) return FALSE;
- init_driver( module, &keypath );
- return TRUE;
+ status = init_driver( &driver_obj, &driver_extension, module, &keypath );
+ if (status == STATUS_SUCCESS)
+ load_additional_drivers();
+ return status == STATUS_SUCCESS;
}
static DWORD WINAPI service_handler( DWORD ctrl, DWORD event_type, LPVOID event_data, LPVOID context )
More information about the wine-patches
mailing list