[ros-diffs] [cgutman] 56068: [NTOSKRNL] - Cleanup device removal/unloading - Should not have any behavior changes yet

cgutman at svn.reactos.org cgutman at svn.reactos.org
Tue Mar 6 22:36:27 UTC 2012


Author: cgutman
Date: Tue Mar  6 22:36:27 2012
New Revision: 56068

URL: http://svn.reactos.org/svn/reactos?rev=56068&view=rev
Log:
[NTOSKRNL]
- Cleanup device removal/unloading
- Should not have any behavior changes yet

Modified:
    trunk/reactos/ntoskrnl/io/iomgr/device.c

Modified: trunk/reactos/ntoskrnl/io/iomgr/device.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/device.c?rev=56068&r1=56067&r2=56068&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/device.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/device.c [iso-8859-1] Tue Mar  6 22:36:27 2012
@@ -359,78 +359,37 @@
 IopUnloadDevice(IN PDEVICE_OBJECT DeviceObject)
 {
     PDRIVER_OBJECT DriverObject = DeviceObject->DriverObject;
-    PDEVICE_OBJECT AttachedDeviceObject, LowestDeviceObject;
-    PEXTENDED_DEVOBJ_EXTENSION ThisExtension, DeviceExtension;
-    PDEVICE_NODE DeviceNode;
-    BOOLEAN SafeToUnload = TRUE;
+    PEXTENDED_DEVOBJ_EXTENSION ThisExtension = IoGetDevObjExtension(DeviceObject);
+    PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject);
+
+    /* Return if we've already called unload (maybe we're in it?) */
+    if (DriverObject->Flags & DRVO_UNLOAD_INVOKED) return;
 
     /* We can't unload unless there's an unload handler */
     if (!DriverObject->DriverUnload)
     {
-        DPRINT("No DriverUnload function! '%wZ' will not be unloaded!\n", &DriverObject->DriverName);
-        return;
-    }
-
-    /* Check if removal is pending */
-    ThisExtension = IoGetDevObjExtension(DeviceObject);
-    if (ThisExtension->ExtensionFlags & DOE_REMOVE_PENDING)
-    {
-        /* Get the PDO, extension, and node */
-        LowestDeviceObject = IopGetLowestDevice(DeviceObject);
-        DeviceExtension = IoGetDevObjExtension(LowestDeviceObject);
-        DeviceNode = DeviceExtension->DeviceNode;
-
-        /* The PDO needs a device node */
-        ASSERT(DeviceNode != NULL);
-
-        /* Loop all attached objects */
-        AttachedDeviceObject = LowestDeviceObject;
-        while (AttachedDeviceObject)
-        {
-            /* Make sure they're dereferenced */
-            if (AttachedDeviceObject->ReferenceCount) return;
-            AttachedDeviceObject = AttachedDeviceObject->AttachedDevice;
-        }
-
-        /* Loop all attached objects */
-        AttachedDeviceObject = LowestDeviceObject;
-        while (AttachedDeviceObject)
-        {
-            /* Get the device extension */
-            DeviceExtension = IoGetDevObjExtension(AttachedDeviceObject);
-
-            /* Remove the pending flag and set processed */
-            DeviceExtension->ExtensionFlags &= ~DOE_REMOVE_PENDING;
-            DeviceExtension->ExtensionFlags |= DOE_REMOVE_PROCESSED;
-            AttachedDeviceObject = AttachedDeviceObject->AttachedDevice;
-        }
-
-        /*
-         * FIXME: TODO HPOUSSIN
-         * We need to parse/lock the device node, and if we have any pending
-         * surprise removals, query all relationships and send IRP_MN_REMOVE_
-         * _DEVICE to the devices related...
-         */
+        if (DeviceNode && !(DeviceNode->Flags & DNF_LEGACY_DRIVER))
+            DPRINT1("No DriverUnload function on PnP driver! '%wZ' will not be unloaded!\n", &DriverObject->DriverName);
+
         return;
     }
 
     /* Check if deletion is pending */
     if (ThisExtension->ExtensionFlags & DOE_DELETE_PENDING)
     {
-        /* Make sure unload is pending */
-        if (!(ThisExtension->ExtensionFlags & DOE_UNLOAD_PENDING) ||
-            (DriverObject->Flags & DRVO_UNLOAD_INVOKED))
-        {
-            /* We can't unload anymore */
-            SafeToUnload = FALSE;
-        }
-
-        /*
-         * Check if we have an attached device and fail if we're attached
-         * or still have a reference count.
-         */
-        AttachedDeviceObject = DeviceObject->AttachedDevice;
-        if ((AttachedDeviceObject) || (DeviceObject->ReferenceCount)) return;
+		if (!(ThisExtension->ExtensionFlags & DOE_UNLOAD_PENDING)) return;
+
+        if (DeviceObject->AttachedDevice)
+        {
+            DPRINT("Device object is in the middle of a device stack\n");
+            return;
+        }
+
+        if (DeviceObject->ReferenceCount)
+        {
+            DPRINT("Device object still has %d references\n", DeviceObject->ReferenceCount);
+            return;
+        }
 
         /* Check if we have a Security Descriptor */
         if (DeviceObject->SecurityDescriptor)
@@ -444,9 +403,6 @@
 
         /* Dereference the keep-alive */
         ObDereferenceObject(DeviceObject);
-
-        /* If we're not unloading, stop here */
-        if (!SafeToUnload) return;
     }
 
     /* Loop all the device objects */
@@ -457,12 +413,21 @@
          * Make sure we're not attached, having a reference count
          * or already deleting
          */
-        if ((DeviceObject->ReferenceCount) ||
-             (DeviceObject->AttachedDevice) ||
-             (IoGetDevObjExtension(DeviceObject)->ExtensionFlags &
-              (DOE_DELETE_PENDING | DOE_REMOVE_PENDING)))
-        {
-            /* We're not safe to unload, quit */
+        if (DeviceObject->ReferenceCount)
+        {
+               DPRINT("Device object still has %d references\n", DeviceObject->ReferenceCount);
+            return;
+        }
+
+        if (DeviceObject->AttachedDevice)
+        {
+            DPRINT("Device object is in the middle of a device stack\n");
+            return;
+        }
+
+        if (IoGetDevObjExtension(DeviceObject)->ExtensionFlags & (DOE_DELETE_PENDING | DOE_REMOVE_PENDING))
+        {
+            DPRINT("Device object has a pending destructive operation\n");
             return;
         }
 
@@ -501,12 +466,9 @@
      * Check if we can unload it and it's safe to unload (or if we're forcing
      * an unload, which is OK too).
      */
+    ASSERT(!ForceUnload);
     if (!(DeviceObject->ReferenceCount) &&
-        ((ForceUnload) || (IoGetDevObjExtension(DeviceObject)->ExtensionFlags &
-                           (DOE_UNLOAD_PENDING |
-                            DOE_DELETE_PENDING |
-                            DOE_REMOVE_PENDING |
-                            DOE_REMOVE_PROCESSED))))
+        (IoGetDevObjExtension(DeviceObject)->ExtensionFlags & DOE_DELETE_PENDING))
     {
         /* Unload it */
         IopUnloadDevice(DeviceObject);
@@ -1111,8 +1073,7 @@
     TargetDevice->AttachedDevice = NULL;
 
     /* Check if it's ok to delete this device */
-    if ((IoGetDevObjExtension(TargetDevice)->ExtensionFlags &
-        (DOE_UNLOAD_PENDING | DOE_DELETE_PENDING | DOE_REMOVE_PENDING)) &&
+    if ((IoGetDevObjExtension(TargetDevice)->ExtensionFlags & DOE_DELETE_PENDING) &&
         !(TargetDevice->ReferenceCount))
     {
         /* It is, do it */




More information about the Ros-diffs mailing list