[1/2] ntoskrnl.exe: Track drivers created with IoCreateDriver. (v2)

Sebastian Lackner sebastian at fds-team.de
Wed Aug 3 11:41:30 CDT 2016


From: Aric Stewart <aric at codeweavers.com>

Signed-off-by: Aric Stewart <aric at codeweavers.com>
Signed-off-by: Sebastian Lackner <sebastian at fds-team.de>
---

I'm not completely happy with this approach, but as an intermediate solution
(until we directory objects in ntoskrnl) its probably good enough.

Changes in v2:
* Move rb tree functions to the beginning to avoid forward declarations.
* Make wine_drivers variable statically and initialize in DllMain.
* Print error if wine_rb_put() fails (could be useful if something goes wrong).
* Some minor style fixes.

 dlls/ntoskrnl.exe/ntoskrnl.c |   99 +++++++++++++++++++++++++++++++++++--------
 1 file changed, 81 insertions(+), 18 deletions(-)

diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index 9acfeaa..0837fc3 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -39,9 +39,10 @@
 #include "ddk/wdm.h"
 #include "wine/unicode.h"
 #include "wine/server.h"
-#include "wine/list.h"
 #include "wine/debug.h"
 
+#include "wine/rbtree.h"
+
 WINE_DEFAULT_DEBUG_CHANNEL(ntoskrnl);
 WINE_DECLARE_DEBUG_CHANNEL(relay);
 
@@ -72,6 +73,56 @@ static DWORD request_thread;
 static DWORD client_tid;
 static DWORD client_pid;
 
+struct wine_driver
+{
+    struct wine_rb_entry entry;
+
+    DRIVER_OBJECT driver_obj;
+    DRIVER_EXTENSION driver_extension;
+};
+
+struct wine_rb_tree wine_drivers;
+
+static CRITICAL_SECTION drivers_cs;
+static CRITICAL_SECTION_DEBUG critsect_debug =
+{
+    0, 0, &drivers_cs,
+    { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
+      0, 0, { (DWORD_PTR)(__FILE__ ": drivers_cs") }
+};
+static CRITICAL_SECTION drivers_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
+
+static void *wine_drivers_rb_alloc( size_t size )
+{
+    return HeapAlloc( GetProcessHeap(), 0, size );
+}
+
+static void *wine_drivers_rb_realloc( void *ptr, size_t size )
+{
+    return HeapReAlloc( GetProcessHeap(), 0, ptr, size );
+}
+
+static void wine_drivers_rb_free( void *ptr )
+{
+    HeapFree( GetProcessHeap(), 0, ptr );
+}
+
+static int wine_drivers_rb_compare( const void *key, const struct wine_rb_entry *entry )
+{
+    const struct wine_driver *driver = WINE_RB_ENTRY_VALUE( entry, const struct wine_driver, entry );
+    const UNICODE_STRING *k = key;
+
+    return RtlCompareUnicodeString( k, &driver->driver_obj.DriverName, FALSE );
+}
+
+static const struct wine_rb_functions wine_drivers_rb_functions =
+{
+    wine_drivers_rb_alloc,
+    wine_drivers_rb_realloc,
+    wine_drivers_rb_free,
+    wine_drivers_rb_compare,
+};
+
 #ifdef __i386__
 #define DEFINE_FASTCALL1_ENTRYPOINT( name ) \
     __ASM_STDCALL_FUNC( name, 4, \
@@ -846,41 +897,48 @@ static void build_driver_keypath( const WCHAR *name, UNICODE_STRING *keypath )
     RtlInitUnicodeString( keypath, str );
 }
 
+
 /***********************************************************************
  *           IoCreateDriver   (NTOSKRNL.EXE.@)
  */
 NTSTATUS WINAPI IoCreateDriver( UNICODE_STRING *name, PDRIVER_INITIALIZE init )
 {
-    DRIVER_OBJECT *driver;
-    DRIVER_EXTENSION *extension;
+    struct wine_driver *driver;
     NTSTATUS status;
 
     TRACE("(%s, %p)\n", debugstr_us(name), init);
 
     if (!(driver = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY,
-                                    sizeof(*driver) + sizeof(*extension) )))
+                                    sizeof(*driver) )))
         return STATUS_NO_MEMORY;
 
-    if ((status = RtlDuplicateUnicodeString( 1, name, &driver->DriverName )))
+    if ((status = RtlDuplicateUnicodeString( 1, name, &driver->driver_obj.DriverName )))
     {
         RtlFreeHeap( GetProcessHeap(), 0, driver );
         return status;
     }
 
-    extension = (DRIVER_EXTENSION *)(driver + 1);
-    driver->Size            = sizeof(*driver);
-    driver->DriverInit      = init;
-    driver->DriverExtension = extension;
-    extension->DriverObject   = driver;
-    build_driver_keypath( driver->DriverName.Buffer, &extension->ServiceKeyName );
+    driver->driver_obj.Size            = sizeof(driver->driver_obj);
+    driver->driver_obj.DriverInit      = init;
+    driver->driver_obj.DriverExtension = &driver->driver_extension;
+    driver->driver_extension.DriverObject   = &driver->driver_obj;
+    build_driver_keypath( driver->driver_obj.DriverName.Buffer, &driver->driver_extension.ServiceKeyName );
 
-    status = driver->DriverInit( driver, &extension->ServiceKeyName );
+    status = driver->driver_obj.DriverInit( &driver->driver_obj, &driver->driver_extension.ServiceKeyName );
 
     if (status)
     {
-        RtlFreeUnicodeString( &driver->DriverName );
+        RtlFreeUnicodeString( &driver->driver_obj.DriverName );
         RtlFreeHeap( GetProcessHeap(), 0, driver );
     }
+    else
+    {
+        EnterCriticalSection( &drivers_cs );
+        if (wine_rb_put( &wine_drivers, &driver->driver_obj.DriverName, &driver->entry ))
+            ERR( "failed to insert driver %s in tree\n", debugstr_us(name) );
+        LeaveCriticalSection( &drivers_cs );
+    }
+
     return status;
 }
 
@@ -888,13 +946,17 @@ NTSTATUS WINAPI IoCreateDriver( UNICODE_STRING *name, PDRIVER_INITIALIZE init )
 /***********************************************************************
  *           IoDeleteDriver   (NTOSKRNL.EXE.@)
  */
-void WINAPI IoDeleteDriver( DRIVER_OBJECT *driver )
+void WINAPI IoDeleteDriver( DRIVER_OBJECT *driver_object )
 {
-    TRACE("(%p)\n", driver);
+    TRACE( "(%p)\n", driver_object );
+
+    EnterCriticalSection( &drivers_cs );
+    wine_rb_remove( &wine_drivers, &driver_object->DriverName );
+    LeaveCriticalSection( &drivers_cs );
 
-    RtlFreeUnicodeString( &driver->DriverName );
-    RtlFreeUnicodeString( &driver->DriverExtension->ServiceKeyName );
-    RtlFreeHeap( GetProcessHeap(), 0, driver );
+    RtlFreeUnicodeString( &driver_object->DriverName );
+    RtlFreeUnicodeString( &driver_object->DriverExtension->ServiceKeyName );
+    RtlFreeHeap( GetProcessHeap(), 0, CONTAINING_RECORD( driver_object, struct wine_driver, driver_obj ) );
 }
 
 
@@ -2344,6 +2406,7 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
     {
     case DLL_PROCESS_ATTACH:
         DisableThreadLibraryCalls( inst );
+        if (wine_rb_init( &wine_drivers, &wine_drivers_rb_functions )) return FALSE;
 #if defined(__i386__) || defined(__x86_64__)
         handler = RtlAddVectoredExceptionHandler( TRUE, vectored_handler );
 #endif
-- 
2.9.0



More information about the wine-patches mailing list