[ros-diffs] [ion] 22787: - Fix sync usage in NtQueryVolumeInformationFile, set the right IRP flags so that the I/O manager can handle copying the data back and freeing the buffer, and enable deferred completion.

ion at svn.reactos.org ion at svn.reactos.org
Mon Jul 3 00:14:20 CEST 2006


Author: ion
Date: Mon Jul  3 02:14:20 2006
New Revision: 22787

URL: http://svn.reactos.org/svn/reactos?rev=22787&view=rev
Log:
- Fix sync usage in NtQueryVolumeInformationFile, set the right IRP flags so that the I/O manager can handle copying the data back and freeing the buffer, and enable deferred completion.

Modified:
    trunk/reactos/ntoskrnl/io/iomgr/iofunc.c

Modified: trunk/reactos/ntoskrnl/io/iomgr/iofunc.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/iofunc.c?rev=22787&r1=22786&r2=22787&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/iofunc.c (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/iofunc.c Mon Jul  3 02:14:20 2006
@@ -2642,111 +2642,137 @@
                              IN FS_INFORMATION_CLASS FsInformationClass)
 {
     PFILE_OBJECT FileObject;
+    PIRP Irp;
+    PIO_STACK_LOCATION StackPtr;
     PDEVICE_OBJECT DeviceObject;
-    PIRP Irp;
+    PKEVENT Event = NULL;
+    BOOLEAN LocalEvent = FALSE;
+    KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
     NTSTATUS Status = STATUS_SUCCESS;
-    PIO_STACK_LOCATION StackPtr;
-    PVOID SystemBuffer;
-    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
-
+    OBJECT_HANDLE_INFORMATION HandleInformation;
+    IO_STATUS_BLOCK KernelIosb;
+    PAGED_CODE();
+
+    /* Check if we're called from user mode */
     if (PreviousMode != KernelMode)
     {
+        /* Enter SEH for probing */
         _SEH_TRY
         {
-            if (IoStatusBlock)
-            {
-                ProbeForWrite(IoStatusBlock,
-                              sizeof(IO_STATUS_BLOCK),
-                              sizeof(ULONG));
-            }
-
+            /* Probe the I/O Status block */
+            ProbeForWrite(IoStatusBlock,
+                          sizeof(IO_STATUS_BLOCK),
+                          sizeof(ULONG));
+
+            /* Probe the information */
             if (Length) ProbeForWrite(FsInformation, Length, 1);
         }
         _SEH_HANDLE
         {
+            /* Get the exception code */
             Status = _SEH_GetExceptionCode();
         }
         _SEH_END;
 
-        if (!NT_SUCCESS(Status))
-        {
-            return Status;
-        }
-    }
-
+        /* Check if probing failed */
+        if (!NT_SUCCESS(Status)) return Status;
+    }
+
+    /* Get File Object */
     Status = ObReferenceObjectByHandle(FileHandle,
-                                       0, /* FIXME - depends on the information class! */
+                                       0, // FIXME
                                        IoFileObjectType,
                                        PreviousMode,
                                        (PVOID*)&FileObject,
-                                       NULL);
+                                       &HandleInformation);
     if (!NT_SUCCESS(Status)) return Status;
 
-    DeviceObject = FileObject->DeviceObject;
-
-    Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
-    if (!Irp)
-    {
+    /* Check if we should use Sync IO or not */
+    if (FileObject->Flags & FO_SYNCHRONOUS_IO)
+    {
+        /* Lock it */
+        IopLockFileObject(FileObject);
+    }
+    else
+    {
+        /* Use local event */
+        Event = ExAllocatePoolWithTag(NonPagedPool, sizeof(KEVENT), TAG_IO);
+        KeInitializeEvent(Event, SynchronizationEvent, FALSE);
+        LocalEvent = TRUE;
+    }
+
+    /* Get the device object */
+    DeviceObject = IoGetRelatedDeviceObject(FileObject);
+
+    /* Clear File Object event */
+    KeClearEvent(&FileObject->Event);
+
+    /* Allocate the IRP */
+    Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
+    if (!Irp) return IopCleanupFailedIrp(FileObject, Event);
+
+    /* Set up the IRP */
+    Irp->RequestorMode = PreviousMode;
+    Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;
+    Irp->UserIosb = (LocalEvent) ? &KernelIosb : IoStatusBlock;
+    Irp->UserEvent = (LocalEvent) ? Event : NULL;
+    Irp->Tail.Overlay.Thread = PsGetCurrentThread();
+    Irp->Tail.Overlay.OriginalFileObject = FileObject;
+    Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
+    Irp->UserBuffer = FsInformation;
+    Irp->AssociatedIrp.SystemBuffer = NULL;
+    Irp->MdlAddress = NULL;
+
+    /* Set up Stack Data */
+    StackPtr = IoGetNextIrpStackLocation(Irp);
+    StackPtr->MajorFunction = IRP_MJ_QUERY_VOLUME_INFORMATION;
+    StackPtr->FileObject = FileObject;
+
+    /* Allocate system buffer */
+    Irp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
+                                                            Length,
+                                                            TAG_SYSB);
+    if (!Irp->AssociatedIrp.SystemBuffer)
+    {
+        /* Fail */
+        IoFreeIrp(Irp);
+        if (Event) ObDereferenceObject(Event);
         ObDereferenceObject(FileObject);
         return STATUS_INSUFFICIENT_RESOURCES;
     }
 
-    SystemBuffer = ExAllocatePoolWithTag(NonPagedPool, Length, TAG_SYSB);
-    if (!SystemBuffer)
-    {
-        IoFreeIrp(Irp);
-        ObDereferenceObject(FileObject);
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    /* Trigger FileObject/Event dereferencing */
-    Irp->Tail.Overlay.OriginalFileObject = FileObject;
-
-    Irp->RequestorMode = PreviousMode;
-    Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
-    KeResetEvent( &FileObject->Event );
-    Irp->UserEvent = &FileObject->Event;
-    Irp->UserIosb = IoStatusBlock;
-    Irp->Tail.Overlay.Thread = PsGetCurrentThread();
-
-    StackPtr = IoGetNextIrpStackLocation(Irp);
-    StackPtr->MajorFunction = IRP_MJ_QUERY_VOLUME_INFORMATION;
-    StackPtr->MinorFunction = 0;
-    StackPtr->Flags = 0;
-    StackPtr->Control = 0;
-    StackPtr->DeviceObject = DeviceObject;
-    StackPtr->FileObject = FileObject;
+    /* Set the flags for this buffered + deferred I/O */
+    Irp->Flags |= (IRP_BUFFERED_IO |
+                   IRP_DEALLOCATE_BUFFER |
+                   IRP_INPUT_OPERATION |
+                   IRP_DEFER_IO_COMPLETION);
+
+    /* Set Parameters */
     StackPtr->Parameters.QueryVolume.Length = Length;
-    StackPtr->Parameters.QueryVolume.FsInformationClass =
-    FsInformationClass;
-
-    Status = IoCallDriver(DeviceObject, Irp);
-    if (Status == STATUS_PENDING)
-    {
-        KeWaitForSingleObject(&FileObject->Event,
-                              UserRequest,
-                              PreviousMode,
-                              FALSE,
-                              NULL);
-        Status = IoStatusBlock->Status;
-     }
-
-    if (NT_SUCCESS(Status))
-        {
-        _SEH_TRY
-        {
-            RtlCopyMemory(FsInformation,
-                          SystemBuffer,
-                          IoStatusBlock->Information);
-        }
-        _SEH_HANDLE
-        {
-            Status = _SEH_GetExceptionCode();
-        }
-        _SEH_END;
-     }
-
-    ExFreePool(SystemBuffer);
+    StackPtr->Parameters.QueryVolume.FsInformationClass = FsInformationClass;
+
+    /* Call the Driver */
+    Status = IopPerformSynchronousRequest(DeviceObject,
+                                          Irp,
+                                          FileObject,
+                                          TRUE,
+                                          PreviousMode,
+                                          !LocalEvent,
+                                          IopOtherTransfer);
+
+    /* Check if this was async I/O */
+    if (LocalEvent)
+    {
+        /* It was, finalize this request */
+        Status = IopFinalizeAsynchronousIo(Status,
+                                           Event,
+                                           Irp,
+                                           PreviousMode,
+                                           &KernelIosb,
+                                           IoStatusBlock);
+    }
+
+    /* Return status */
     return Status;
 }
 




More information about the Ros-diffs mailing list