/* 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);
}
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)