From 6a5123b065f32ec78c84ad2d4bd2e7926beeb409 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Wed, 4 Apr 2007 02:49:41 +0000 Subject: [PATCH] - Implement IopAttachDeviceToDeviceStackSafe for future use. - Use OBJ_KERNEL_HANDLE for various internal Device Object handles. - Fix bug in IopStartNextPacketByKeyEx which didn't actually read the flags to see if the I/O was cancelleable or not. - Fail DO creation if the VPB couldn't be created. - Fix completely wrong implementation of IoGetDeviceAttachmentBaseRef. It was getting the attached device instead of the base device, and wasn't even referencing it!. - svn path=/trunk/; revision=26257 --- reactos/ntoskrnl/io/iomgr/device.c | 131 ++++++++++++++++++++--------- 1 file changed, 93 insertions(+), 38 deletions(-) diff --git a/reactos/ntoskrnl/io/iomgr/device.c b/reactos/ntoskrnl/io/iomgr/device.c index 888613d9e51..b1811f4cc3b 100644 --- a/reactos/ntoskrnl/io/iomgr/device.c +++ b/reactos/ntoskrnl/io/iomgr/device.c @@ -23,6 +23,61 @@ KSPIN_LOCK ShutdownListLock; /* PRIVATE FUNCTIONS **********************************************************/ +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 IoShutdownRegisteredDevices(VOID) @@ -93,7 +148,7 @@ IopGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, /* Open the Device */ InitializeObjectAttributes(&ObjectAttributes, ObjectName, - 0, + OBJ_KERNEL_HANDLE, NULL, NULL); Status = ZwOpenFile(&FileHandle, @@ -463,14 +518,16 @@ IopStartNextPacketByKeyEx(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); } } @@ -536,7 +593,6 @@ IoAttachDevice(PDEVICE_OBJECT SourceDevice, Status = IoAttachDeviceToDeviceStackSafe(SourceDevice, TargetDevice, AttachedDevice); - if (!*AttachedDevice) Status = STATUS_NO_SUCH_DEVICE; /* Dereference it */ ObDereferenceObject(FileObject); @@ -566,15 +622,12 @@ IoAttachDeviceByPointer(IN PDEVICE_OBJECT SourceDevice, } /* - * 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; @@ -595,7 +648,7 @@ NTSTATUS 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; @@ -702,7 +755,11 @@ IoCreateDevice(IN PDRIVER_OBJECT DriverObject, } /* 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; @@ -769,13 +826,19 @@ IoCreateDevice(IN PDRIVER_OBJECT DriverObject, 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, @@ -803,11 +866,11 @@ IoCreateDevice(IN PDRIVER_OBJECT DriverObject, } /* 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); @@ -825,20 +888,16 @@ IoCreateDevice(IN PDRIVER_OBJECT DriverObject, 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); /* Close the temporary handle and return to caller */ - NtClose(TempHandle); + ObCloseHandle(TempHandle, KernelMode); *DeviceObject = CreatedDeviceObject; return STATUS_SUCCESS; } @@ -1011,8 +1070,10 @@ PDEVICE_OBJECT 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; } /* @@ -1119,13 +1180,7 @@ IoGetLowerDeviceObject(IN PDEVICE_OBJECT DeviceObject) } /* - * IoGetRelatedDeviceObject - * - * Remarks - * See "Windows NT File System Internals", page 633 - 634. - * - * Status - * @implemented + * @implemented */ PDEVICE_OBJECT NTAPI