[ros-diffs] [ion] 22902: - 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.

ion at svn.reactos.org ion at svn.reactos.org
Fri Jul 7 18:26:06 CEST 2006


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?rev=22902&r1=22901&r2=22902&view=diff
==============================================================================
--- 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 */




More information about the Ros-diffs mailing list