#include <ntoskrnl.h>
#define NDEBUG
-#include <internal/debug.h>
+#include <debug.h>
/* GLOBALS ********************************************************************/
ULONG IopDeviceObjectNumber = 0;
-
LIST_ENTRY ShutdownListHead, LastChanceShutdownListHead;
KSPIN_LOCK ShutdownListLock;
+extern LIST_ENTRY IopDiskFsListHead;
+extern LIST_ENTRY IopCdRomFsListHead;
+extern LIST_ENTRY IopTapeFsListHead;
/* PRIVATE FUNCTIONS **********************************************************/
VOID
NTAPI
-IoShutdownRegisteredDevices(VOID)
+IopReadyDeviceObjects(IN PDRIVER_OBJECT Driver)
+{
+ PDEVICE_OBJECT DeviceObject;
+ PAGED_CODE();
+
+ /* Set the driver as initialized */
+ Driver->Flags |= DRVO_INITIALIZED;
+ DeviceObject = Driver->DeviceObject;
+ while (DeviceObject)
+ {
+ /* Set every device as initialized too */
+ DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
+ DeviceObject = DeviceObject->NextDevice;
+ }
+}
+
+VOID
+NTAPI
+IopDeleteDevice(IN PVOID ObjectBody)
+{
+ PDEVICE_OBJECT DeviceObject = ObjectBody;
+ PAGED_CODE();
+
+ /* TODO: Delete Device Node */
+
+ /* Dereference the driver object, referenced in IoCreateDevice */
+ if (DeviceObject->DriverObject)
+ ObDereferenceObject(DeviceObject->DriverObject);
+}
+
+
+PDEVICE_OBJECT
+NTAPI
+IopAttachDeviceToDeviceStackSafe(IN PDEVICE_OBJECT SourceDevice,
+ IN PDEVICE_OBJECT TargetDevice,
+ OUT PDEVICE_OBJECT *AttachedToDeviceObject OPTIONAL)
+{
+ PDEVICE_OBJECT AttachedDevice;
+ PEXTENDED_DEVOBJ_EXTENSION SourceDeviceExtension;
+
+ /* Get the Attached Device and source extension */
+ AttachedDevice = IoGetAttachedDevice(TargetDevice);
+ SourceDeviceExtension = IoGetDevObjExtension(SourceDevice);
+ ASSERT(SourceDeviceExtension->AttachedTo == NULL);
+
+ /* Make sure that it's in a correct state */
+ if ((AttachedDevice->Flags & DO_DEVICE_INITIALIZING) ||
+ (IoGetDevObjExtension(AttachedDevice)->ExtensionFlags &
+ (DOE_UNLOAD_PENDING |
+ DOE_DELETE_PENDING |
+ DOE_REMOVE_PENDING |
+ DOE_REMOVE_PROCESSED)))
+ {
+ /* Device was unloading or being removed */
+ AttachedDevice = NULL;
+ }
+ else
+ {
+ /* Update atached device fields */
+ AttachedDevice->AttachedDevice = SourceDevice;
+ AttachedDevice->Spare1++;
+
+ /* Update the source with the attached data */
+ SourceDevice->StackSize = AttachedDevice->StackSize + 1;
+ SourceDevice->AlignmentRequirement = AttachedDevice->
+ AlignmentRequirement;
+ SourceDevice->SectorSize = AttachedDevice->SectorSize;
+
+ /* Check for pending start flag */
+ if (IoGetDevObjExtension(AttachedDevice)->ExtensionFlags &
+ DOE_START_PENDING)
+ {
+ /* Propagate */
+ IoGetDevObjExtension(SourceDevice)->ExtensionFlags |=
+ DOE_START_PENDING;
+ }
+
+ /* Set the attachment in the device extension */
+ SourceDeviceExtension->AttachedTo = AttachedDevice;
+ }
+
+ /* Return the attached device */
+ if (AttachedToDeviceObject) *AttachedToDeviceObject = AttachedDevice;
+ return AttachedDevice;
+}
+
+VOID
+NTAPI
+IoShutdownPnpDevices(VOID)
+{
+ /* This routine is only used by Driver Verifier to validate shutdown */
+ return;
+}
+
+VOID
+NTAPI
+IoShutdownSystem(IN ULONG Phase)
{
PLIST_ENTRY ListEntry;
PDEVICE_OBJECT DeviceObject;
PIRP Irp;
KEVENT Event;
NTSTATUS Status;
-
+
/* Initialize an event to wait on */
KeInitializeEvent(&Event, NotificationEvent, FALSE);
-
- /* Get the first entry and start looping */
- ListEntry = ExInterlockedRemoveHeadList(&ShutdownListHead,
- &ShutdownListLock);
- while (ListEntry)
+
+ /* What phase? */
+ if (Phase == 0)
{
- /* Get the shutdown entry */
- ShutdownEntry = CONTAINING_RECORD(ListEntry,
- SHUTDOWN_ENTRY,
- ShutdownList);
+ /* Shutdown PnP */
+ IoShutdownPnpDevices();
- /* Get the attached device */
- DeviceObject = IoGetAttachedDevice(ShutdownEntry->DeviceObject);
-
- /* Build the shutdown IRP and call the driver */
- Irp = IoBuildSynchronousFsdRequest(IRP_MJ_SHUTDOWN,
- DeviceObject,
- NULL,
- 0,
- NULL,
- &Event,
- &StatusBlock);
- Status = IoCallDriver(DeviceObject, Irp);
- if (Status == STATUS_PENDING)
+ /* Loop first-chance shutdown notifications */
+ ListEntry = ExInterlockedRemoveHeadList(&ShutdownListHead,
+ &ShutdownListLock);
+ while (ListEntry)
{
- /* Wait on the driver */
- KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
- }
+ /* Get the shutdown entry */
+ ShutdownEntry = CONTAINING_RECORD(ListEntry,
+ SHUTDOWN_ENTRY,
+ ShutdownList);
+
+ /* Get the attached device */
+ DeviceObject = IoGetAttachedDevice(ShutdownEntry->DeviceObject);
+
+ /* Build the shutdown IRP and call the driver */
+ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_SHUTDOWN,
+ DeviceObject,
+ NULL,
+ 0,
+ NULL,
+ &Event,
+ &StatusBlock);
+ Status = IoCallDriver(DeviceObject, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ /* Wait on the driver */
+ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+ }
- /* Free the shutdown entry and reset the event */
- ExFreePool(ShutdownEntry);
- KeClearEvent(&Event);
+ /* Get rid of our reference to it */
+ ObDereferenceObject(DeviceObject);
+
+ /* Free the shutdown entry and reset the event */
+ ExFreePoolWithTag(ShutdownEntry, TAG_SHUTDOWN_ENTRY);
+ KeClearEvent(&Event);
+
+ /* Go to the next entry */
+ ListEntry = ExInterlockedRemoveHeadList(&ShutdownListHead,
+ &ShutdownListLock);
+ }
+ }
+ else if (Phase == 1)
+ {
+ /* Shutdown disk file systems */
+ IopShutdownBaseFileSystems(&IopDiskFsListHead);
- /* Go to the next entry */
- ListEntry = ExInterlockedRemoveHeadList(&ShutdownListHead,
+ /* Shutdown cdrom file systems */
+ IopShutdownBaseFileSystems(&IopCdRomFsListHead);
+
+ /* Shutdown tape filesystems */
+ IopShutdownBaseFileSystems(&IopTapeFsListHead);
+
+ /* Loop last-chance shutdown notifications */
+ ListEntry = ExInterlockedRemoveHeadList(&LastChanceShutdownListHead,
&ShutdownListLock);
- }
+ while (ListEntry)
+ {
+ /* Get the shutdown entry */
+ ShutdownEntry = CONTAINING_RECORD(ListEntry,
+ SHUTDOWN_ENTRY,
+ ShutdownList);
+
+ /* Get the attached device */
+ DeviceObject = IoGetAttachedDevice(ShutdownEntry->DeviceObject);
+
+ /* Build the shutdown IRP and call the driver */
+ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_SHUTDOWN,
+ DeviceObject,
+ NULL,
+ 0,
+ NULL,
+ &Event,
+ &StatusBlock);
+ Status = IoCallDriver(DeviceObject, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ /* Wait on the driver */
+ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+ }
+
+ /* Get rid of our reference to it */
+ ObDereferenceObject(DeviceObject);
+
+ /* Free the shutdown entry and reset the event */
+ ExFreePoolWithTag(ShutdownEntry, TAG_SHUTDOWN_ENTRY);
+ KeClearEvent(&Event);
+
+ /* Go to the next entry */
+ ListEntry = ExInterlockedRemoveHeadList(&LastChanceShutdownListHead,
+ &ShutdownListLock);
+ }
+
+ }
}
NTSTATUS
/* Open the Device */
InitializeObjectAttributes(&ObjectAttributes,
ObjectName,
- 0,
+ OBJ_KERNEL_HANDLE,
NULL,
NULL);
Status = ZwOpenFile(&FileHandle,
/* Return the requested data */
*DeviceObject = IoGetRelatedDeviceObject(LocalFileObject);
*FileObject = LocalFileObject;
- ZwClose(FileHandle);
}
/* Close the handle */
+ ZwClose(FileHandle);
+
return Status;
}
if (DeviceObject->SecurityDescriptor)
{
/* Free it */
- ExFreePool(DeviceObject->SecurityDescriptor);
+ ExFreePoolWithTag(DeviceObject->SecurityDescriptor, TAG_SD);
}
/* Remove the device from the list */
/* Unload it */
if (DriverObject->DriverUnload) DriverObject->DriverUnload(DriverObject);
+
+ /* Make object temporary so it can be deleted */
+ ObMakeTemporaryObject(DriverObject);
+
+ /* Dereference once more, referenced at driver object creation */
+ ObDereferenceObject(DriverObject);
+
}
VOID
}
}
-NTSTATUS
-NTAPI
-IopReferenceDeviceObject(IN PDEVICE_OBJECT DeviceObject)
-{
- /* Make sure the object is valid */
- if ((IoGetDevObjExtension(DeviceObject)->ExtensionFlags &
- (DOE_UNLOAD_PENDING |
- DOE_DELETE_PENDING |
- DOE_REMOVE_PENDING |
- DOE_REMOVE_PROCESSED)) ||
- (DeviceObject->Flags & DO_DEVICE_INITIALIZING))
- {
- /* It's unloading or initializing, so fail */
- DPRINT1("You are seeing this because the following ROS driver: %wZ\n"
- " sucks. Please fix it's AddDevice Routine\n",
- &DeviceObject->DriverObject->DriverName);
- return STATUS_NO_SUCH_DEVICE;
- }
- else
- {
- /* Increase reference count */
- DeviceObject->ReferenceCount++;
- return STATUS_SUCCESS;
- }
-}
-
VOID
NTAPI
IopStartNextPacketByKey(IN PDEVICE_OBJECT DeviceObject,
{
/* Start the packet with a key */
IopStartNextPacketByKey(DeviceObject,
- (DOE_SIO_CANCELABLE) ? TRUE : FALSE,
+ (Flags & DOE_SIO_CANCELABLE) ?
+ TRUE : FALSE,
CurrentKey);
}
else if (Flags & DOE_SIO_NO_KEY)
{
/* Start the packet */
IopStartNextPacket(DeviceObject,
- (DOE_SIO_CANCELABLE) ? TRUE : FALSE);
+ (Flags & DOE_SIO_CANCELABLE) ?
+ TRUE : FALSE);
}
}
}
}
+NTSTATUS
+NTAPI
+IopGetRelatedTargetDevice(IN PFILE_OBJECT FileObject,
+ OUT PDEVICE_NODE *DeviceNode)
+{
+ NTSTATUS Status;
+ IO_STACK_LOCATION Stack = {0};
+ PDEVICE_RELATIONS DeviceRelations;
+ PDEVICE_OBJECT DeviceObject = NULL;
+
+ ASSERT(FileObject);
+
+ /* Get DeviceObject related to given FileObject */
+ DeviceObject = IoGetRelatedDeviceObject(FileObject);
+ if (!DeviceObject) return STATUS_NO_SUCH_DEVICE;
+
+ /* Define input parameters */
+ Stack.MajorFunction = IRP_MJ_PNP;
+ Stack.MinorFunction = IRP_MN_QUERY_DEVICE_RELATIONS;
+ Stack.Parameters.QueryDeviceRelations.Type = TargetDeviceRelation;
+ Stack.FileObject = FileObject;
+
+ /* Call the driver to query all relations (IRP_MJ_PNP) */
+ Status = IopSynchronousCall(DeviceObject,
+ &Stack,
+ (PVOID)&DeviceRelations);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Make sure it's not NULL and contains only one object */
+ ASSERT(DeviceRelations);
+ ASSERT(DeviceRelations->Count == 1);
+
+ /* Finally get the device node */
+ *DeviceNode = IopGetDeviceNode(DeviceRelations->Objects[0]);
+ if (!*DeviceNode) Status = STATUS_NO_SUCH_DEVICE;
+
+ /* Free the DEVICE_RELATIONS structure, it's not needed anymore */
+ ExFreePool(DeviceRelations);
+
+ return Status;
+}
+
/* PUBLIC FUNCTIONS ***********************************************************/
/*
Status = IoAttachDeviceToDeviceStackSafe(SourceDevice,
TargetDevice,
AttachedDevice);
- if (!*AttachedDevice) Status = STATUS_NO_SUCH_DEVICE;
/* Dereference it */
ObDereferenceObject(FileObject);
}
/*
- * IoAttachDeviceToDeviceStack
- *
- * Status
- * @implemented
+ * @implemented
*/
PDEVICE_OBJECT
NTAPI
-IoAttachDeviceToDeviceStack(PDEVICE_OBJECT SourceDevice,
- PDEVICE_OBJECT TargetDevice)
+IoAttachDeviceToDeviceStack(IN PDEVICE_OBJECT SourceDevice,
+ IN PDEVICE_OBJECT TargetDevice)
{
- NTSTATUS Status;
- PDEVICE_OBJECT LocalAttach;
-
/* Attach it safely */
- Status = IoAttachDeviceToDeviceStackSafe(SourceDevice,
- TargetDevice,
- &LocalAttach);
-
- /* Return it */
- return LocalAttach;
+ return IopAttachDeviceToDeviceStackSafe(SourceDevice,
+ TargetDevice,
+ NULL);
}
/*
NTAPI
IoAttachDeviceToDeviceStackSafe(IN PDEVICE_OBJECT SourceDevice,
IN PDEVICE_OBJECT TargetDevice,
- OUT PDEVICE_OBJECT *AttachedToDeviceObject)
+ IN OUT PDEVICE_OBJECT *AttachedToDeviceObject)
{
- PDEVICE_OBJECT AttachedDevice;
- PEXTENDED_DEVOBJ_EXTENSION SourceDeviceExtension;
-
- /* Get the Attached Device and source extension */
- AttachedDevice = IoGetAttachedDevice(TargetDevice);
- SourceDeviceExtension = IoGetDevObjExtension(SourceDevice);
-
- /* Make sure that it's in a correct state */
- if (!IoGetDevObjExtension(AttachedDevice)->ExtensionFlags &
- (DOE_UNLOAD_PENDING |
- DOE_DELETE_PENDING |
- DOE_REMOVE_PENDING |
- DOE_REMOVE_PROCESSED))
- {
- /* Update atached device fields */
- AttachedDevice->AttachedDevice = SourceDevice;
- AttachedDevice->Spare1++;
-
- /* Update the source with the attached data */
- SourceDevice->StackSize = AttachedDevice->StackSize + 1;
- SourceDevice->AlignmentRequirement = AttachedDevice->
- AlignmentRequirement;
- SourceDevice->SectorSize = AttachedDevice->SectorSize;
-
- /* Set the attachment in the device extension */
- SourceDeviceExtension->AttachedTo = AttachedDevice;
- }
- else
+ /* Call the internal function */
+ if (!IopAttachDeviceToDeviceStackSafe(SourceDevice,
+ TargetDevice,
+ AttachedToDeviceObject))
{
- /* Device was unloading or being removed */
- AttachedDevice = NULL;
+ /* Nothing found */
+ return STATUS_NO_SUCH_DEVICE;
}
- /* Return the attached device */
- *AttachedToDeviceObject = AttachedDevice;
+ /* Success! */
return STATUS_SUCCESS;
}
}
/* Initialize the Object Attributes */
- InitializeObjectAttributes(&ObjectAttributes, DeviceName, 0, NULL, NULL);
+ InitializeObjectAttributes(&ObjectAttributes,
+ DeviceName,
+ OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL);
/* Honor exclusive flag */
if (Exclusive) ObjectAttributes.Attributes |= OBJ_EXCLUSIVE;
* because that's only padding for the DevObjExt and not part of the Object.
*/
CreatedDeviceObject->Type = IO_TYPE_DEVICE;
- CreatedDeviceObject->Size = sizeof(DEVICE_OBJECT) + DeviceExtensionSize;
+ CreatedDeviceObject->Size = sizeof(DEVICE_OBJECT) + (USHORT)DeviceExtensionSize;
/* The kernel extension is after the driver internal extension */
DeviceObjectExtension = (PDEVOBJ_EXTENSION)
/* Set the Type and Size. Question: why is Size 0 on Windows? */
DeviceObjectExtension->Type = IO_TYPE_DEVICE_OBJECT_EXTENSION;
DeviceObjectExtension->Size = 0;
+
+ /* Initialize with Power Manager */
+ PoInitializeDeviceObject(DeviceObjectExtension);
/* Link the Object and Extension */
DeviceObjectExtension->DeviceObject = CreatedDeviceObject;
if (DeviceName) CreatedDeviceObject->Flags |= DO_DEVICE_HAS_NAME;
/* Attach a Vpb for Disks and Tapes, and create the Device Lock */
- if (CreatedDeviceObject->DeviceType == FILE_DEVICE_DISK ||
- CreatedDeviceObject->DeviceType == FILE_DEVICE_VIRTUAL_DISK ||
- CreatedDeviceObject->DeviceType == FILE_DEVICE_CD_ROM ||
- CreatedDeviceObject->DeviceType == FILE_DEVICE_TAPE)
+ if ((CreatedDeviceObject->DeviceType == FILE_DEVICE_DISK) ||
+ (CreatedDeviceObject->DeviceType == FILE_DEVICE_VIRTUAL_DISK) ||
+ (CreatedDeviceObject->DeviceType == FILE_DEVICE_CD_ROM) ||
+ (CreatedDeviceObject->DeviceType == FILE_DEVICE_TAPE))
{
/* Create Vpb */
- IopCreateVpb(CreatedDeviceObject);
+ Status = IopCreateVpb(CreatedDeviceObject);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Reference the device object and fail */
+ ObDereferenceObject(DeviceObject);
+ return Status;
+ }
/* Initialize Lock Event */
KeInitializeEvent(&CreatedDeviceObject->DeviceLock,
}
/* Create the Device Queue */
- if (CreatedDeviceObject->DeviceType == FILE_DEVICE_DISK_FILE_SYSTEM ||
- CreatedDeviceObject->DeviceType == FILE_DEVICE_FILE_SYSTEM ||
- CreatedDeviceObject->DeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM ||
- CreatedDeviceObject->DeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM ||
- CreatedDeviceObject->DeviceType == FILE_DEVICE_TAPE_FILE_SYSTEM)
+ if ((CreatedDeviceObject->DeviceType == FILE_DEVICE_DISK_FILE_SYSTEM) ||
+ (CreatedDeviceObject->DeviceType == FILE_DEVICE_FILE_SYSTEM) ||
+ (CreatedDeviceObject->DeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM) ||
+ (CreatedDeviceObject->DeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM) ||
+ (CreatedDeviceObject->DeviceType == FILE_DEVICE_TAPE_FILE_SYSTEM))
{
/* Simple FS Devices, they don't need a real Device Queue */
InitializeListHead(&CreatedDeviceObject->Queue.ListEntry);
1,
(PVOID*)&CreatedDeviceObject,
&TempHandle);
- if (!NT_SUCCESS(Status))
- {
- /* Clear the device object and fail */
- *DeviceObject = NULL;
- return Status;
- }
+ if (!NT_SUCCESS(Status)) return Status;
/* Now do the final linking */
ObReferenceObject(DriverObject);
+ ASSERT((DriverObject->Flags & DRVO_UNLOAD_INVOKED) == 0);
CreatedDeviceObject->DriverObject = DriverObject;
IopEditDeviceList(DriverObject, CreatedDeviceObject, IopAdd);
+
+ /* Link with the power manager */
+ if (CreatedDeviceObject->Vpb) PoVolumeDevice(CreatedDeviceObject);
/* Close the temporary handle and return to caller */
- NtClose(TempHandle);
+ ObCloseHandle(TempHandle, KernelMode);
*DeviceObject = CreatedDeviceObject;
return STATUS_SUCCESS;
}
NTAPI
IoDetachDevice(IN PDEVICE_OBJECT TargetDevice)
{
+ PEXTENDED_DEVOBJ_EXTENSION DeviceExtension;
+
+ /* Sanity check */
+ DeviceExtension = IoGetDevObjExtension(TargetDevice->AttachedDevice);
+ ASSERT(DeviceExtension->AttachedTo == TargetDevice);
+
/* Remove the attachment */
- IoGetDevObjExtension(TargetDevice->AttachedDevice)->AttachedTo = NULL;
+ DeviceExtension->AttachedTo = NULL;
TargetDevice->AttachedDevice = NULL;
/* Check if it's ok to delete this device */
NTAPI
IoGetDeviceAttachmentBaseRef(IN PDEVICE_OBJECT DeviceObject)
{
- /* Return the attached Device */
- return IoGetDevObjExtension(DeviceObject)->AttachedTo;
+ /* Reference the lowest attached device */
+ DeviceObject = IopGetLowestDevice(DeviceObject);
+ ObReferenceObject(DeviceObject);
+ return DeviceObject;
}
/*
/* Make sure it's not getting deleted */
DeviceExtension = IoGetDevObjExtension(DeviceObject);
- if (DeviceExtension->ExtensionFlags & (DOE_UNLOAD_PENDING |
+ if (!(DeviceExtension->ExtensionFlags & (DOE_UNLOAD_PENDING |
DOE_DELETE_PENDING |
DOE_REMOVE_PENDING |
- DOE_REMOVE_PROCESSED))
+ DOE_REMOVE_PROCESSED)))
{
/* Get the Lower Device Object */
LowerDeviceObject = DeviceExtension->AttachedTo;
- /* Reference it */
- ObReferenceObject(LowerDeviceObject);
+ /* Check that we got a valid device object */
+ if (LowerDeviceObject)
+ {
+ /* We did so let's reference it */
+ ObReferenceObject(LowerDeviceObject);
+ }
}
/* Return it */
}
/*
- * IoGetRelatedDeviceObject
- *
- * Remarks
- * See "Windows NT File System Internals", page 633 - 634.
- *
- * Status
- * @implemented
+ * @implemented
*/
PDEVICE_OBJECT
NTAPI
DeviceObject = FileObject->DeviceObject;
}
+ /* Sanity check */
+ ASSERT(DeviceObject != NULL);
+
/* Check if we were attached */
if (DeviceObject->AttachedDevice)
{
+ /* Check if the file object has an extension present */
+ if (FileObject->Flags & FO_FILE_OBJECT_HAS_EXTENSION)
+ {
+ /* Sanity check, direct open files can't have this */
+ ASSERT(!(FileObject->Flags & FO_DIRECT_DEVICE_OPEN));
+
+ /* Check if the extension is really present */
+ if (FileObject->FileObjectExtension)
+ {
+ /* FIXME: Unhandled yet */
+ DPRINT1("FOEs not supported\n");
+ ASSERT(FALSE);
+ }
+ }
+
/* Return the highest attached device */
DeviceObject = IoGetAttachedDevice(DeviceObject);
}
return DeviceObject;
}
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IoGetRelatedTargetDevice(IN PFILE_OBJECT FileObject,
+ OUT PDEVICE_OBJECT *DeviceObject)
+{
+ NTSTATUS Status;
+ PDEVICE_NODE DeviceNode = NULL;
+
+ /* Call the internal helper function */
+ Status = IopGetRelatedTargetDevice(FileObject, &DeviceNode);
+ if (NT_SUCCESS(Status) && DeviceNode)
+ {
+ *DeviceObject = DeviceNode->PhysicalDeviceObject;
+ }
+ return Status;
+}
+
/*
* @implemented
*/
}
/* Return the device object we found */
+ ASSERT(DeviceObject != NULL);
return DeviceObject;
}
/* Set the DO */
Entry->DeviceObject = DeviceObject;
+
+ /* Reference it so it doesn't go away */
+ ObReferenceObject(DeviceObject);
/* Insert it into the list */
ExInterlockedInsertHeadList(&LastChanceShutdownListHead,
/* Set the DO */
Entry->DeviceObject = DeviceObject;
+
+ /* Reference it so it doesn't go away */
+ ObReferenceObject(DeviceObject);
/* Insert it into the list */
ExInterlockedInsertHeadList(&ShutdownListHead,
NextEntry = NextEntry->Blink;
/* Free the entry */
- ExFreePool(ShutdownEntry);
+ ExFreePoolWithTag(ShutdownEntry, TAG_SHUTDOWN_ENTRY);
+
+ /* Get rid of our reference to it */
+ ObDereferenceObject(DeviceObject);
}
/* Go to the next entry */
NextEntry = NextEntry->Blink;
/* Free the entry */
- ExFreePool(ShutdownEntry);
+ ExFreePoolWithTag(ShutdownEntry, TAG_SHUTDOWN_ENTRY);
+
+ /* Get rid of our reference to it */
+ ObDereferenceObject(DeviceObject);
}
/* Go to the next entry */
NextEntry = NextEntry->Flink;
}
+ /* Release the shutdown lock */
+ KeReleaseSpinLock(&ShutdownListLock, OldIrql);
+
/* Now remove the flag */
DeviceObject->Flags &= ~DO_SHUTDOWN_REGISTERED;
}
IopStartNextPacketByKeyEx(DeviceObject,
Key,
DOE_SIO_WITH_KEY |
- (Cancelable) ? DOE_SIO_CANCELABLE : 0);
+ (Cancelable ? DOE_SIO_CANCELABLE : 0));
}
else
{
IopStartNextPacketByKeyEx(DeviceObject,
0,
DOE_SIO_NO_KEY |
- (Cancelable) ? DOE_SIO_CANCELABLE : 0);
+ (Cancelable ? DOE_SIO_CANCELABLE : 0));
}
else
{
}
/* Release the cancel lock */
- IoReleaseCancelSpinLock(OldIrql);
+ IoReleaseCancelSpinLock(CancelIrql);
}
/* Call the Start I/O function */