[ros-diffs] [ion] 22771: - Same changes for IoSertInformation: Lock the FO, queue the IRP, support alerted I/O, etc...

ion at svn.reactos.org ion at svn.reactos.org
Sun Jul 2 18:41:50 CEST 2006


Author: ion
Date: Sun Jul  2 20:41:49 2006
New Revision: 22771

URL: http://svn.reactos.org/svn/reactos?rev=22771&view=rev
Log:
- Same changes for IoSertInformation: Lock the FO, queue the IRP, support alerted I/O, etc...

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=22771&r1=22770&r2=22771&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/iofunc.c (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/iofunc.c Sun Jul  2 20:41:49 2006
@@ -635,59 +635,100 @@
     PIRP Irp;
     PDEVICE_OBJECT DeviceObject;
     PIO_STACK_LOCATION StackPtr;
+    BOOLEAN LocalEvent = FALSE;
+    KEVENT Event;
     NTSTATUS Status;
-
-    if (FileInformationClass == FileCompletionInformation)
-    {
-        return STATUS_NOT_IMPLEMENTED;
-    }
-
-    Status = ObReferenceObjectByPointer(FileObject,
-                                        0, /* FIXME - depends on the information class */
-                                        IoFileObjectType,
-                                        KernelMode);
-    if (!NT_SUCCESS(Status)) return(Status);
-
-
-    DeviceObject = FileObject->DeviceObject;
-
-    Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
-    if (!Irp)
-    {
-        ObDereferenceObject(FileObject);
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    /* Trigger FileObject/Event dereferencing */
+    PAGED_CODE();
+
+    /* Reference the object */
+    ObReferenceObject(FileObject);
+
+    /* Check if this is a file that was opened for Synch I/O */
+    if (FileObject->Flags & FO_SYNCHRONOUS_IO)
+    {
+        /* Lock it */
+        IopLockFileObject(FileObject);
+
+        /* Use File Object event */
+        KeClearEvent(&FileObject->Event);
+    }
+    else
+    {
+        /* Use local event */
+        KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
+        LocalEvent = TRUE;
+    }
+
+    /* Get the Device Object */
+    DeviceObject = IoGetRelatedDeviceObject(FileObject);
+
+    /* Allocate the IRP */
+    Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
+    if (!Irp) return IopCleanupFailedIrp(FileObject, NULL);
+
+    /* Set the IRP */
     Irp->Tail.Overlay.OriginalFileObject = FileObject;
     Irp->RequestorMode = KernelMode;
+    Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
+    Irp->UserIosb = &IoStatusBlock;
+    Irp->UserEvent = (LocalEvent) ? &Event : NULL;
+    Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;
+    Irp->Flags |= IRP_BUFFERED_IO;
     Irp->AssociatedIrp.SystemBuffer = FileInformation;
-    Irp->UserIosb = &IoStatusBlock;
-    Irp->UserEvent = &FileObject->Event;
     Irp->Tail.Overlay.Thread = PsGetCurrentThread();
-    KeResetEvent( &FileObject->Event );
-
+
+    /* Set the Stack Data */
     StackPtr = IoGetNextIrpStackLocation(Irp);
     StackPtr->MajorFunction = IRP_MJ_SET_INFORMATION;
-    StackPtr->MinorFunction = 0;
-    StackPtr->Flags = 0;
-    StackPtr->Control = 0;
-    StackPtr->DeviceObject = DeviceObject;
     StackPtr->FileObject = FileObject;
+
+    /* Set Parameters */
     StackPtr->Parameters.SetFile.FileInformationClass = FileInformationClass;
     StackPtr->Parameters.SetFile.Length = Length;
 
+    /* Queue the IRP */
+    IopQueueIrpToThread(Irp);
+
+    /* Call the Driver */
     Status = IoCallDriver(FileObject->DeviceObject, Irp);
-    if (Status==STATUS_PENDING)
-    {
-        KeWaitForSingleObject(&FileObject->Event,
+
+    /* Check if this was synch I/O */
+    if (!LocalEvent)
+    {
+        /* Check if the requet is pending */
+        if (Status == STATUS_PENDING)
+        {
+            /* Wait on the file object */
+            Status = KeWaitForSingleObject(&FileObject->Event,
+                                           Executive,
+                                           KernelMode,
+                                           FileObject->Flags & FO_ALERTABLE_IO,
+                                           NULL);
+            if (Status == STATUS_ALERTED)
+            {
+                /* Abort the operation */
+                IopAbortInterruptedIrp(&FileObject->Event, Irp);
+            }
+
+            /* Get the final status */
+            Status = FileObject->FinalStatus;
+        }
+
+        /* Release the file lock */
+        IopUnlockFileObject(FileObject);
+    }
+    else if (Status == STATUS_PENDING)
+    {
+        /* Wait on the local event and get the final status */
+        KeWaitForSingleObject(&Event,
                               Executive,
                               KernelMode,
-                              FileObject->Flags & FO_ALERTABLE_IO,
+                              FALSE,
                               NULL);
         Status = IoStatusBlock.Status;
     }
 
+    /* Return the status */
     return Status;
 }
 




More information about the Ros-diffs mailing list