[ros-diffs] [ion] 22786: - Add proper sync handling to NtUnlockFile.

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


Author: ion
Date: Mon Jul  3 02:07:20 2006
New Revision: 22786

URL: http://svn.reactos.org/svn/reactos?rev=22786&view=rev
Log:
- Add proper sync handling to NtUnlockFile.

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=22786&r1=22785&r2=22786&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/iofunc.c (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/iofunc.c Mon Jul  3 02:07:20 2006
@@ -20,6 +20,17 @@
             __FUNCTION__,
             Irp);
 #endif
+
+///
+//
+// TODO:
+//  - Lock/Unlock <= DONE
+//  - Query/Set Volume Info
+//  - Read/Write file
+//  - QuerySet/ File Info
+//  - NtQueryDirectoryFile
+//
+///
 
 /* PRIVATE FUNCTIONS *********************************************************/
 
@@ -1104,8 +1115,8 @@
            IN BOOLEAN ExclusiveLock)
 {
     PFILE_OBJECT FileObject;
-    PLARGE_INTEGER LocalLength = NULL;
-    PIRP Irp = NULL;
+    PLARGE_INTEGER LocalLength;
+    PIRP Irp;
     PIO_STACK_LOCATION StackPtr;
     PDEVICE_OBJECT DeviceObject;
     PKEVENT Event = NULL;
@@ -2231,19 +2242,19 @@
              IN PLARGE_INTEGER Length,
              IN ULONG Key OPTIONAL)
 {
-    PFILE_OBJECT FileObject = NULL;
-    PLARGE_INTEGER LocalLength = NULL;
-    PIRP Irp = NULL;
+    PFILE_OBJECT FileObject;
+    PLARGE_INTEGER LocalLength;
+    PIRP Irp;
     PIO_STACK_LOCATION StackPtr;
     PDEVICE_OBJECT DeviceObject;
-    KEVENT Event;
+    PKEVENT Event = NULL;
     BOOLEAN LocalEvent = FALSE;
     KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
+    LARGE_INTEGER CapturedByteOffset, CapturedLength;
     NTSTATUS Status = STATUS_SUCCESS;
-    LARGE_INTEGER CapturedByteOffset, CapturedLength;
     OBJECT_HANDLE_INFORMATION HandleInformation;
+    IO_STATUS_BLOCK KernelIosb;
     PAGED_CODE();
-
     CapturedByteOffset.QuadPart = 0;
     CapturedLength.QuadPart = 0;
 
@@ -2256,38 +2267,47 @@
                                        &HandleInformation);
     if (!NT_SUCCESS(Status)) return Status;
 
+    /* Check if we're called from user mode */
     if (PreviousMode != KernelMode)
     {
-        /* Must have either FILE_READ_DATA or FILE_WRITE_DATA access unless we're
-           in KernelMode! */
-        if (!(HandleInformation.GrantedAccess & (FILE_WRITE_DATA | FILE_READ_DATA)))
+        /* Must have either FILE_READ_DATA or FILE_WRITE_DATA access */
+        if (!(HandleInformation.GrantedAccess &
+            (FILE_WRITE_DATA | FILE_READ_DATA)))
         {
             ObDereferenceObject(FileObject);
             return STATUS_ACCESS_DENIED;
         }
 
+        /* Enter SEH for probing */
         _SEH_TRY
         {
+            /* Probe the I/O Status block */
             ProbeForWrite(IoStatusBlock,
                           sizeof(IO_STATUS_BLOCK),
                           sizeof(ULONG));
+
+            /* Probe and capture the large integers */
             CapturedByteOffset = ProbeForReadLargeInteger(ByteOffset);
             CapturedLength = ProbeForReadLargeInteger(Length);
         }
         _SEH_HANDLE
         {
+            /* Get the exception code */
             Status = _SEH_GetExceptionCode();
         }
         _SEH_END;
 
+        /* Check if probing failed */
         if (!NT_SUCCESS(Status))
         {
+            /* Dereference the object and return exception code */
             ObDereferenceObject(FileObject);
             return Status;
         }
     }
     else
     {
+        /* Otherwise, capture them directly */
         CapturedByteOffset = *ByteOffset;
         CapturedLength = *Length;
     }
@@ -2305,23 +2325,38 @@
     /* Check if we should use Sync IO or not */
     if (FileObject->Flags & FO_SYNCHRONOUS_IO)
     {
-        /* Use File Object event */
-        KeClearEvent(&FileObject->Event);
+        /* Lock it */
+        IopLockFileObject(FileObject);
     }
     else
     {
         /* Use local event */
-        KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
+        Event = ExAllocatePoolWithTag(NonPagedPool, sizeof(KEVENT), TAG_IO);
+        KeInitializeEvent(Event, SynchronizationEvent, FALSE);
         LocalEvent = TRUE;
     }
+
+    /* Clear File Object event */
+    KeClearEvent(&FileObject->Event);
 
     /* Allocate the IRP */
     Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
-    if (!Irp)
-    {
-        ObDereferenceObject(FileObject);
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
+    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;
+
+    /* Set up Stack Data */
+    StackPtr = IoGetNextIrpStackLocation(Irp);
+    StackPtr->MajorFunction = IRP_MJ_LOCK_CONTROL;
+    StackPtr->MinorFunction = IRP_MN_UNLOCK_SINGLE;
+    StackPtr->FileObject = FileObject;
 
     /* Allocate local buffer */
     LocalLength = ExAllocatePoolWithTag(NonPagedPool,
@@ -2329,56 +2364,44 @@
                                         TAG_LOCK);
     if (!LocalLength)
     {
+        /* Fail */
         IoFreeIrp(Irp);
+        if (Event) ObDereferenceObject(Event);
         ObDereferenceObject(FileObject);
         return STATUS_INSUFFICIENT_RESOURCES;
     }
+
+    /* Set the length */
     *LocalLength = CapturedLength;
 
-    /* Set up the IRP */
-    Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;
-    Irp->RequestorMode = PreviousMode;
-    Irp->UserIosb = IoStatusBlock;
-    Irp->UserEvent = (LocalEvent) ? &Event : NULL;
-    Irp->Tail.Overlay.Thread = PsGetCurrentThread();
-    Irp->Tail.Overlay.OriginalFileObject = FileObject;
-
-    /* Set up Stack Data */
-    StackPtr = IoGetNextIrpStackLocation(Irp);
-    StackPtr->MajorFunction = IRP_MJ_LOCK_CONTROL;
-    StackPtr->MinorFunction = IRP_MN_UNLOCK_SINGLE;
-    StackPtr->FileObject = FileObject;
-
     /* Set Parameters */
+    Irp->Tail.Overlay.AuxiliaryBuffer = (PVOID)LocalLength;
     StackPtr->Parameters.LockControl.Length = LocalLength;
     StackPtr->Parameters.LockControl.ByteOffset = CapturedByteOffset;
     StackPtr->Parameters.LockControl.Key = Key;
 
     /* Call the Driver */
-    Status = IoCallDriver(DeviceObject, Irp);
-    if (Status == STATUS_PENDING)
-    {
-        if (LocalEvent)
-        {
-            KeWaitForSingleObject(&Event,
-                                  Executive,
-                                  PreviousMode,
-                                  FileObject->Flags & FO_ALERTABLE_IO,
-                                  NULL);
-            Status = IoStatusBlock->Status;
-        }
-        else
-        {
-            KeWaitForSingleObject(&FileObject->Event,
-                                  Executive,
-                                  PreviousMode,
-                                  FileObject->Flags & FO_ALERTABLE_IO,
-                                  NULL);
-            Status = FileObject->FinalStatus;
-        }
-    }
-
-    /* Return the Status */
+    Status = IopPerformSynchronousRequest(DeviceObject,
+                                          Irp,
+                                          FileObject,
+                                          FALSE,
+                                          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