Author: ion
Date: Fri Jul 7 20:26:05 2006
New Revision: 22902
URL:
http://svn.reactos.org/svn/reactos?rev=22902&view=rev
Log:
- Use a simpler and more robust way to detect direct device opens and save it in a
variable that's read when needed, instead of having multiple large code paths.
Modified:
trunk/reactos/ntoskrnl/io/iomgr/file.c
Modified: trunk/reactos/ntoskrnl/io/iomgr/file.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/file.c?r…
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/file.c (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/file.c Fri Jul 7 20:26:05 2006
@@ -30,7 +30,7 @@
OUT PVOID *Object)
{
POPEN_PACKET OpenPacket = (POPEN_PACKET)Context;
- PDEVICE_OBJECT DeviceObject;
+ PDEVICE_OBJECT OriginalDeviceObject = (PDEVICE_OBJECT)ParseObject, DeviceObject;
NTSTATUS Status;
PFILE_OBJECT FileObject;
PVPB Vpb;
@@ -38,6 +38,8 @@
PEXTENDED_IO_STACK_LOCATION StackLoc;
IO_SECURITY_CONTEXT SecurityContext;
IO_STATUS_BLOCK IoStatusBlock;
+ BOOLEAN DirectOpen = FALSE;
+ OBJECT_ATTRIBUTES ObjectAttributes;
DPRINT("IopParseDevice:\n"
"DeviceObject : %p\n"
"RelatedFileObject : %p\n"
@@ -53,6 +55,17 @@
/* Validate the open packet */
if (!IopValidateOpenPacket(OpenPacket)) return STATUS_OBJECT_TYPE_MISMATCH;
+ /* Check if we have a related file object */
+ if (OpenPacket->RelatedFileObject)
+ {
+ /* Use the related file object's device object */
+ OriginalDeviceObject = OpenPacket->RelatedFileObject->DeviceObject;
+ }
+
+ /* Reference the DO FIXME: Don't allow failure */
+ Status = IopReferenceDeviceObject(OriginalDeviceObject);
+
+ /* Map the generic mask and set the new mapping in the access state */
RtlMapGenericMask(&AccessState->RemainingDesiredAccess,
&IoFileObjectType->TypeInfo.GenericMapping);
RtlMapGenericMask(&AccessState->OriginalDesiredAccess,
@@ -60,10 +73,73 @@
SeSetAccessStateGenericMapping(AccessState,
&IoFileObjectType->TypeInfo.GenericMapping);
+ /* Check if this is a direct open */
+ if (!(RemainingName->Length) && !(OpenPacket->RelatedFileObject))
+ {
+ /* Remember this for later */
+ DirectOpen = TRUE;
+ }
+
+ /* Check if we have a related FO that wasn't a direct open */
+ if ((OpenPacket->RelatedFileObject) &&
+ !(OpenPacket->RelatedFileObject->Flags & FO_DIRECT_DEVICE_OPEN))
+ {
+ /* The device object is the one we were given */
+ DeviceObject = OriginalDeviceObject;
+
+ /* Check if the related FO had a VPB */
+ if (OpenPacket->RelatedFileObject->Vpb)
+ {
+ /* Yes, remember it */
+ Vpb = OpenPacket->RelatedFileObject->Vpb;
+ }
+ }
+ else
+ {
+ /* The device object is the one we were given */
+ DeviceObject = OriginalDeviceObject;
+
+ /* Check if it has a VPB */
+ if ((DeviceObject->Vpb) && !(DirectOpen))
+ {
+ /* Check if it's not already mounted */
+ if (!(DeviceObject->Vpb->Flags & VPB_MOUNTED))
+ {
+ /* Mount the volume */
+ Status = IopMountVolume(DeviceObject,
+ FALSE,
+ FALSE,
+ FALSE,
+ &Vpb);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Couldn't mount, fail the lookup */
+ ObDereferenceObject(FileObject);
+ return STATUS_UNSUCCESSFUL;
+ }
+ }
+
+ /* Get the VPB's device object */
+ DeviceObject = DeviceObject->Vpb->DeviceObject;
+ }
+
+ /* Check if there's an attached device */
+ if (DeviceObject->AttachedDevice)
+ {
+ /* Get the attached device */
+ DeviceObject = IoGetAttachedDevice(DeviceObject);
+ }
+ }
+
/* Create the actual file object */
- Status = ObCreateObject(AccessMode,
+ InitializeObjectAttributes(&ObjectAttributes,
+ NULL,
+ Attributes,
+ NULL,
+ NULL);
+ Status = ObCreateObject(KernelMode,
IoFileObjectType,
- NULL,
+ &ObjectAttributes,
AccessMode,
NULL,
sizeof(FILE_OBJECT),
@@ -72,54 +148,8 @@
(PVOID*)&FileObject);
RtlZeroMemory(FileObject, sizeof(FILE_OBJECT));
- /* Parent is a device object */
- DeviceObject = IoGetAttachedDevice(ParseObject);
-
- /* Check if we don't have a remaining name */
- if (!*RemainingName->Buffer)
- {
- /* Then this is a device */
- FileObject->Flags |= FO_DIRECT_DEVICE_OPEN;
- }
- else
- {
- /* Check if we don't have a related file object */
- if (!OpenPacket->RelatedFileObject)
- {
- /* Check if it has a VPB */
- if (DeviceObject->Vpb)
- {
- /* Check if it's not already mounted */
- if (!(DeviceObject->Vpb->Flags & VPB_MOUNTED))
- {
- /* Mount the volume */
- Status = IopMountVolume(DeviceObject,
- FALSE,
- FALSE,
- FALSE,
- &Vpb);
- if (!NT_SUCCESS(Status))
- {
- /* Couldn't mount, fail the lookup */
- ObDereferenceObject(FileObject);
- return STATUS_UNSUCCESSFUL;
- }
- }
-
- /* Get the VPB's device object */
- DeviceObject = DeviceObject->Vpb->DeviceObject;
- }
- }
- else
- {
- /* Otherwise, this is an open */
- FileObject->RelatedFileObject = OpenPacket->RelatedFileObject;
- DeviceObject = OpenPacket->RelatedFileObject->DeviceObject;
- }
-
- /* Create the name for the file object */
- RtlCreateUnicodeString(&FileObject->FileName, RemainingName->Buffer);
- }
+ /* Create the name for the file object */
+ RtlCreateUnicodeString(&FileObject->FileName, RemainingName->Buffer);
/* Set the device object and reference it */
Status = IopReferenceDeviceObject(DeviceObject);
@@ -127,6 +157,7 @@
FileObject->Type = IO_TYPE_FILE;
FileObject->Size = sizeof(FILE_OBJECT);
+ FileObject->RelatedFileObject = OpenPacket->RelatedFileObject;
if (OpenPacket->CreateOptions &
(FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT))
@@ -153,6 +184,11 @@
if (OpenPacket->CreateOptions & FILE_RANDOM_ACCESS)
{
FileObject->Flags |= FO_RANDOM_ACCESS;
+ }
+
+ if (DirectOpen)
+ {
+ FileObject->Flags |= FO_DIRECT_DEVICE_OPEN;
}
if (!(Attributes & OBJ_CASE_INSENSITIVE))
@@ -168,7 +204,7 @@
KeInitializeEvent(&FileObject->Lock, SynchronizationEvent, TRUE);
KeInitializeEvent(&FileObject->Event, NotificationEvent, FALSE);
- Irp = IoAllocateIrp(FileObject->DeviceObject->StackSize, FALSE);
+ Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (!Irp) return STATUS_UNSUCCESSFUL;
/* Now set the IRP data */