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…
==============================================================================
--- 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 */