Author: cgutman
Date: Tue May 31 19:34:08 2011
New Revision: 52029

URL: http://svn.reactos.org/svn/reactos?rev=52029&view=rev
Log:
[NTOSKRNL]
- Implement IopRemoveDevice and IopStopDevice
- Do a graceful remove before installing new drivers (like Windows does)
- Debug log warnings abound (don't be alarmed ;)) because drivers aren't used 
to receiving IRP_MN_QUERY_REMOVE_DEVICE, IRP_MN_REMOVE_DEVICE and 
IRP_MN_QUERY_PNP_DEVICE_STATE from our (formly) crippled PnP manager

Modified:
    trunk/reactos/ntoskrnl/include/internal/io.h
    trunk/reactos/ntoskrnl/io/pnpmgr/plugplay.c
    trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c

Modified: trunk/reactos/ntoskrnl/include/internal/io.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/io.h?rev=52029&r1=52028&r2=52029&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/io.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/io.h [iso-8859-1] Tue May 31 
19:34:08 2011
@@ -790,6 +790,16 @@
     IN PDEVICE_NODE DeviceNode
 );
 
+NTSTATUS
+IopStopDevice(
+    IN PDEVICE_NODE DeviceNode
+);
+
+NTSTATUS
+IopRemoveDevice(
+    IN PDEVICE_NODE DeviceNode
+);
+
 PVPB
 NTAPI
 IopCheckVpbMounted(

Modified: trunk/reactos/ntoskrnl/io/pnpmgr/plugplay.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/plugplay.c?rev=52029&r1=52028&r2=52029&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr/plugplay.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/plugplay.c [iso-8859-1] Tue May 31 
19:34:08 2011
@@ -551,10 +551,18 @@
 
     DeviceNode = IopGetDeviceNode(DeviceObject);
 
-    /* FIXME: we should stop the device, before starting it again */
-
-    /* Start the device */
-    IopDeviceNodeClearFlag(DeviceNode, DNF_DISABLED);
+    /* Remove the device */
+    if (DeviceNode->Flags & DNF_ENUMERATED)
+    {
+        Status = IopRemoveDevice(DeviceNode);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("WARNING: Ignoring failed IopRemoveDevice() for %wZ 
(likely a driver bug)\n", &DeviceNode->InstancePath);
+        }
+    }
+
+    /* Reenumerate the device and its children */
+    DeviceNode->Flags &= ~DNF_DISABLED;
     Status = IopActionConfigureChildServices(DeviceNode, DeviceNode->Parent);
 
     if (NT_SUCCESS(Status))

Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c?rev=52029&r1=52028&r2=52029&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c [iso-8859-1] Tue May 31 19:34:08 
2011
@@ -335,6 +335,24 @@
     
     /* Return */
     return Status;
+}
+
+NTSTATUS
+IopStopDevice(
+   PDEVICE_NODE DeviceNode)
+{
+   NTSTATUS Status;
+
+   DPRINT("Stopping device: %wZ\n", &DeviceNode->InstancePath);
+
+   Status = IopQueryStopDevice(DeviceNode->PhysicalDeviceObject);
+   if (!NT_SUCCESS(Status))
+   {
+       IopSendStopDevice(DeviceNode->PhysicalDeviceObject);
+       return STATUS_SUCCESS;
+   }
+
+   return Status;
 }
 
 NTSTATUS
@@ -420,7 +438,7 @@
        return Status;
    }
 
-   DeviceNode->CapabilityFlags = *(PULONG)((ULONG_PTR)&DeviceCaps + 4);
+   DeviceNode->CapabilityFlags = *(PULONG)((ULONG_PTR)&DeviceCaps->Version + 
sizeof(DeviceCaps->Version));;
 
    if (DeviceCaps->NoDisplayInUI)
        DeviceNode->UserFlags |= DNUF_DONT_SHOW_IN_UI;
@@ -3873,6 +3891,12 @@
     PDEVICE_RELATIONS DeviceRelations;
     NTSTATUS Status;
     ULONG i;
+
+    if (DeviceNode->UserFlags & DNUF_NOT_DISABLEABLE)
+    {
+        DPRINT1("Removal not allowed for %wZ\n", &DeviceNode->InstancePath);
+        return STATUS_UNSUCCESSFUL;
+    }
     
     IopQueueTargetDeviceEvent(&GUID_DEVICE_REMOVE_PENDING,
                               &DeviceNode->InstancePath);
@@ -3958,6 +3982,23 @@
     return Status;
 }
 
+NTSTATUS
+IopRemoveDevice(PDEVICE_NODE DeviceNode)
+{
+    NTSTATUS Status;
+
+    DPRINT("Removing device: %wZ\n", &DeviceNode->InstancePath);
+
+    Status = IopPrepareDeviceForRemoval(DeviceNode->PhysicalDeviceObject);
+    if (NT_SUCCESS(Status))
+    {
+        IopSendRemoveDevice(DeviceNode->PhysicalDeviceObject);
+        return STATUS_SUCCESS;
+    }
+
+    return Status;
+}
+
 /*
  * @implemented
  */


Reply via email to