Rémi Bernon : ntoskrnl.exe: Send IRP_MN_SURPRISE_REMOVAL to the device stack first.

Alexandre Julliard julliard at winehq.org
Tue Jul 6 18:09:36 CDT 2021


Module: wine
Branch: master
Commit: b065daa600e858823944f996144ed233065da7fd
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=b065daa600e858823944f996144ed233065da7fd

Author: Rémi Bernon <rbernon at codeweavers.com>
Date:   Tue Jul  6 11:00:47 2021 +0200

ntoskrnl.exe: Send IRP_MN_SURPRISE_REMOVAL to the device stack first.

Instead of sending both IRP_MN_SURPRISE_REMOVAL and IRP_MN_REMOVE_DEVICE
to all children first.

They may have pending IRPs sent to their parent PDO driver, which need
to be cancelled before IRP_MN_REMOVE_DEVICE can complete. This is the
case for hidclass.sys and its thread calling the lower driver for
instance.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntoskrnl.exe/pnp.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/dlls/ntoskrnl.exe/pnp.c b/dlls/ntoskrnl.exe/pnp.c
index e425712d738..d8eb62bc17a 100644
--- a/dlls/ntoskrnl.exe/pnp.c
+++ b/dlls/ntoskrnl.exe/pnp.c
@@ -350,21 +350,20 @@ static void enumerate_new_device( DEVICE_OBJECT *device, HDEVINFO set )
     start_device( device, set, &sp_device );
 }
 
-static void remove_device( DEVICE_OBJECT *device )
+static void send_remove_device_irp( DEVICE_OBJECT *device, UCHAR code )
 {
     struct wine_device *wine_device = CONTAINING_RECORD(device, struct wine_device, device_obj);
 
-    TRACE("Removing device %p.\n", device);
+    TRACE( "Removing device %p, code %x.\n", device, code );
 
     if (wine_device->children)
     {
         ULONG i;
         for (i = 0; i < wine_device->children->Count; ++i)
-            remove_device( wine_device->children->Objects[i] );
+            send_remove_device_irp( wine_device->children->Objects[i], code );
     }
 
-    send_pnp_irp( device, IRP_MN_SURPRISE_REMOVAL );
-    send_pnp_irp( device, IRP_MN_REMOVE_DEVICE );
+    send_pnp_irp( device, code );
 }
 
 static BOOL device_in_list( const DEVICE_RELATIONS *list, const DEVICE_OBJECT *device )
@@ -441,7 +440,8 @@ static void handle_bus_relations( DEVICE_OBJECT *parent )
             if (!device_in_list( relations, child ))
             {
                 TRACE("Removing device %p.\n", child);
-                remove_device( child );
+                send_remove_device_irp( child, IRP_MN_SURPRISE_REMOVAL );
+                send_remove_device_irp( child, IRP_MN_REMOVE_DEVICE );
             }
             ObDereferenceObject( child );
         }
@@ -1105,7 +1105,10 @@ void pnp_manager_stop_driver( struct wine_driver *driver )
     struct root_pnp_device *device, *next;
 
     LIST_FOR_EACH_ENTRY_SAFE( device, next, &driver->root_pnp_devices, struct root_pnp_device, entry )
-        remove_device( device->device );
+    {
+        send_remove_device_irp( device->device, IRP_MN_SURPRISE_REMOVAL );
+        send_remove_device_irp( device->device, IRP_MN_REMOVE_DEVICE );
+    }
 }
 
 void pnp_manager_stop(void)
@@ -1179,7 +1182,8 @@ void CDECL wine_enumerate_root_devices( const WCHAR *driver_name )
     {
         TRACE("Removing device %s.\n", debugstr_w(pnp_device->id));
 
-        remove_device( pnp_device->device );
+        send_remove_device_irp( pnp_device->device, IRP_MN_SURPRISE_REMOVAL );
+        send_remove_device_irp( pnp_device->device, IRP_MN_REMOVE_DEVICE );
     }
 
     list_move_head( &driver->root_pnp_devices, &new_list );




More information about the wine-cvs mailing list