[NTOSKRNL]
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Tue, 23 Oct 2012 05:42:17 +0000 (05:42 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Tue, 23 Oct 2012 05:42:17 +0000 (05:42 +0000)
- Unregister dope (device object power extension) from volume list when device object is deleted
- Core-6691 #resolve

svn path=/trunk/; revision=57599

reactos/ntoskrnl/include/internal/po.h
reactos/ntoskrnl/io/iomgr/device.c
reactos/ntoskrnl/po/povolume.c

index dcc4d0d..1189120 100644 (file)
@@ -285,6 +285,11 @@ PoVolumeDevice(
     IN PDEVICE_OBJECT DeviceObject
 );
 
+VOID
+NTAPI
+PoRemoveVolumeDevice(
+    IN PDEVICE_OBJECT DeviceObject);
+
 //
 // Power State routines
 //
index 0b1a886..a0e1961 100644 (file)
@@ -1035,6 +1035,9 @@ IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
     /* Set the pending delete flag */
     IoGetDevObjExtension(DeviceObject)->ExtensionFlags |= DOE_DELETE_PENDING;
 
+    /* Unlink with the power manager */
+    if (DeviceObject->Vpb) PoRemoveVolumeDevice(DeviceObject);
+
     /* Check if the device object can be unloaded */
     if (!DeviceObject->ReferenceCount) IopUnloadDevice(DeviceObject);
 }
index 15aaebf..7700302 100644 (file)
@@ -97,7 +97,52 @@ PoVolumeDevice(IN PDEVICE_OBJECT DeviceObject)
         KeReleaseGuardedMutex(&PopVolumeLock);
     }
 }
-    
+
+VOID
+NTAPI
+PoRemoveVolumeDevice(IN PDEVICE_OBJECT DeviceObject)
+{
+    PDEVICE_OBJECT_POWER_EXTENSION Dope;
+    PEXTENDED_DEVOBJ_EXTENSION DeviceExtension;
+    KIRQL OldIrql;
+    PAGED_CODE();
+
+    /* If the device already has the dope, return it */
+    DeviceExtension = IoGetDevObjExtension(DeviceObject);
+    if (!DeviceExtension->Dope)
+    {
+        /* no dope */
+        return;
+    }
+
+    /* Make sure we can flush safely */
+    KeAcquireGuardedMutex(&PopVolumeLock);
+
+    /* Get dope from device */
+    Dope = (PDEVICE_OBJECT_POWER_EXTENSION)DeviceExtension->Dope;
+
+    if (Dope->Volume.Flink)
+    {
+        /* Remove from volume from list */
+        RemoveEntryList(&Dope->Volume);
+    }
+
+    /* Allow flushes to go through */
+    KeReleaseGuardedMutex(&PopVolumeLock);
+
+    /* Now remove dope from device object */
+    KeAcquireSpinLock(&PopDopeGlobalLock, &OldIrql);
+
+    /* remove from dev obj */
+    DeviceExtension->Dope = NULL;
+
+    /* Release lock */
+    KeReleaseSpinLock(&PopDopeGlobalLock, OldIrql);
+
+    /* Free dope */
+    ExFreePoolWithTag(Dope, 'Dope');
+}
+
 VOID
 NTAPI
 PopFlushVolumeWorker(IN PVOID Context)