[PATCH] ntoskrnl.exe: Send IRP_MN_SURPRISE_REMOVAL to the device stack first.

Rémi Bernon rbernon at codeweavers.com
Tue Jun 22 07:13:10 CDT 2021


Instead of sending both IRP_MN_SURPRISE_REMOVAL and IRP_MN_REMOVE_DEVICE
to all children first, which may have pending IRPs sent to their parent
PDO driver, which need to be cancelled before IRP_MN_REMOVE_DEVICE can
complete.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/ntoskrnl.exe/pnp.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/dlls/ntoskrnl.exe/pnp.c b/dlls/ntoskrnl.exe/pnp.c
index e425712d738..0b4e4ef4613 100644
--- a/dlls/ntoskrnl.exe/pnp.c
+++ b/dlls/ntoskrnl.exe/pnp.c
@@ -350,12 +350,26 @@ static void enumerate_new_device( DEVICE_OBJECT *device, HDEVINFO set )
     start_device( device, set, &sp_device );
 }
 
+static void send_surprise_removal( DEVICE_OBJECT *device )
+{
+    struct wine_device *impl = CONTAINING_RECORD(device, struct wine_device, device_obj);
+    ULONG i;
+
+    if (impl->children)
+        for (i = 0; i < impl->children->Count; ++i)
+            send_surprise_removal( impl->children->Objects[i] );
+
+    send_pnp_irp( device, IRP_MN_SURPRISE_REMOVAL );
+}
+
 static void remove_device( DEVICE_OBJECT *device )
 {
     struct wine_device *wine_device = CONTAINING_RECORD(device, struct wine_device, device_obj);
 
     TRACE("Removing device %p.\n", device);
 
+    send_surprise_removal( device );
+
     if (wine_device->children)
     {
         ULONG i;
@@ -363,7 +377,6 @@ static void remove_device( DEVICE_OBJECT *device )
             remove_device( wine_device->children->Objects[i] );
     }
 
-    send_pnp_irp( device, IRP_MN_SURPRISE_REMOVAL );
     send_pnp_irp( device, IRP_MN_REMOVE_DEVICE );
 }
 
-- 
2.31.0




More information about the wine-devel mailing list