[prev in list] [next in list] [prev in thread] [next in thread] 

List:       wine-devel
Subject:    [PATCH 5/8] =?UTF-8?q?ntoskrnl:=20Introduce=20a=20custom=20servic?= =?UTF-8?q?e=20control=20to=20re=
From:       Zebediah Figura <z.figura12 () gmail ! com>
Date:       2021-03-31 16:16:35
Message-ID: 20210331161638.1014645-5-z.figura12 () gmail ! com
[Download RAW message or body]

Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
---
 dlls/ntoskrnl.exe/ntoskrnl.c | 48 +++++++++++++++++++++++++-----------
 dlls/ntoskrnl.exe/pnp.c      | 21 +++++++++++++---
 2 files changed, 51 insertions(+), 18 deletions(-)

diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index f51055fd6c0..d4536c39578 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -88,6 +88,21 @@ static struct wine_rb_tree wine_drivers = { \
wine_drivers_rb_compare };  
 DECLARE_CRITICAL_SECTION(drivers_cs);
 
+static BOOLEAN get_drv_name( UNICODE_STRING *drv_name, const UNICODE_STRING \
*service_name ) +{
+    static const WCHAR driverW[] = {'\\','D','r','i','v','e','r','\\',0};
+    WCHAR *str;
+
+    if (!(str = heap_alloc( sizeof(driverW) + service_name->Length - \
lstrlenW(servicesW)*sizeof(WCHAR) ))) +        return FALSE;
+
+    lstrcpyW( str, driverW );
+    lstrcpynW( str + lstrlenW(driverW), service_name->Buffer + lstrlenW(servicesW),
+            service_name->Length/sizeof(WCHAR) - lstrlenW(servicesW) + 1 );
+    RtlInitUnicodeString( drv_name, str );
+    return TRUE;
+}
+
 static HANDLE get_device_manager(void)
 {
     static HANDLE device_manager;
@@ -875,6 +890,8 @@ PEPROCESS PsInitialSystemProcess = NULL;
 static HANDLE stop_event;
 static SERVICE_STATUS_HANDLE group_handle;
 
+#define SERVICE_CONTROL_REENUMERATE_ROOT_DEVICES 128
+
 static DWORD device_handler( DWORD ctrl, const WCHAR *driver_name )
 {
     UNICODE_STRING service_name;
@@ -898,6 +915,22 @@ static DWORD device_handler( DWORD ctrl, const WCHAR \
                *driver_name )
         result = RtlNtStatusToDosError( ZwUnloadDriver( &service_name ) );
         break;
 
+    case SERVICE_CONTROL_REENUMERATE_ROOT_DEVICES:
+    {
+        struct wine_rb_entry *entry;
+        UNICODE_STRING drv_name;
+
+        if (!get_drv_name( &drv_name, &service_name ))
+            return STATUS_NO_MEMORY;
+
+        entry = wine_rb_get( &wine_drivers, &drv_name );
+        RtlFreeUnicodeString( &drv_name );
+
+        TRACE( "reenumerating PnP devices for %s\n", debugstr_w(service_name.Buffer) \
); +        pnp_manager_enumerate_root_devices( WINE_RB_ENTRY_VALUE( entry, struct \
wine_driver, entry ) ); +        return NO_ERROR;
+    }
+
     default:
         FIXME( "got driver ctrl %#x for %s\n", ctrl, debugstr_w(driver_name) );
         break;
@@ -3834,21 +3867,6 @@ static NTSTATUS WINAPI init_driver( DRIVER_OBJECT \
*driver_object, UNICODE_STRING  return status;
 }
 
-static BOOLEAN get_drv_name( UNICODE_STRING *drv_name, const UNICODE_STRING \
                *service_name )
-{
-    static const WCHAR driverW[] = {'\\','D','r','i','v','e','r','\\',0};
-    WCHAR *str;
-
-    if (!(str = heap_alloc( sizeof(driverW) + service_name->Length - \
                lstrlenW(servicesW)*sizeof(WCHAR) )))
-        return FALSE;
-
-    lstrcpyW( str, driverW );
-    lstrcpynW( str + lstrlenW(driverW), service_name->Buffer + lstrlenW(servicesW),
-            service_name->Length/sizeof(WCHAR) - lstrlenW(servicesW) + 1 );
-    RtlInitUnicodeString( drv_name, str );
-    return TRUE;
-}
-
 /***********************************************************************
  *           ZwLoadDriver (NTOSKRNL.EXE.@)
  */
diff --git a/dlls/ntoskrnl.exe/pnp.c b/dlls/ntoskrnl.exe/pnp.c
index 1c1f241591b..9c86450406d 100644
--- a/dlls/ntoskrnl.exe/pnp.c
+++ b/dlls/ntoskrnl.exe/pnp.c
@@ -1054,7 +1054,8 @@ void pnp_manager_enumerate_root_devices( struct wine_driver \
*driver )  static const WCHAR rootW[] = {'R','O','O','T',0};
     WCHAR buffer[MAX_SERVICE_NAME + ARRAY_SIZE(driverW)], id[MAX_DEVICE_ID_LEN];
     SP_DEVINFO_DATA sp_device = {sizeof(sp_device)};
-    struct root_pnp_device *pnp_device;
+    struct list new_list = LIST_INIT(new_list);
+    struct root_pnp_device *pnp_device, *next;
     DEVICE_OBJECT *device;
     NTSTATUS status;
     unsigned int i;
@@ -1080,8 +1081,13 @@ void pnp_manager_enumerate_root_devices( struct wine_driver \
*driver )  
         SetupDiGetDeviceInstanceIdW( set, &sp_device, id, ARRAY_SIZE(id), NULL );
 
-        if (find_root_pnp_device( driver, id ))
+        if ((pnp_device = find_root_pnp_device( driver, id )))
+        {
+            TRACE("Found device %s already enumerated.\n", debugstr_w(id));
+            list_remove( &pnp_device->entry );
+            list_add_tail( &new_list, &pnp_device->entry );
             continue;
+        }
 
         TRACE("Adding new root-enumerated device %s.\n", debugstr_w(id));
 
@@ -1095,10 +1101,19 @@ void pnp_manager_enumerate_root_devices( struct wine_driver \
*driver )  pnp_device = device->DeviceExtension;
         wcscpy( pnp_device->id, id );
         pnp_device->device = device;
-        list_add_tail( &driver->root_pnp_devices, &pnp_device->entry );
+        list_add_tail( &new_list, &pnp_device->entry );
 
         start_device( device, set, &sp_device );
     }
 
+    LIST_FOR_EACH_ENTRY_SAFE( pnp_device, next, &driver->root_pnp_devices, struct \
root_pnp_device, entry ) +    {
+        TRACE("Removing device %s.\n", debugstr_w(pnp_device->id));
+
+        remove_device( pnp_device->device );
+    }
+
+    list_move_head( &driver->root_pnp_devices, &new_list );
+
     SetupDiDestroyDeviceInfoList(set);
 }
-- 
2.30.2


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic