Fix NtWriteFile: Get right Deviceobject, Use FileObject->FinalStatus, use FileObject...
authorAlex Ionescu <aionescu@gmail.com>
Mon, 9 May 2005 02:15:03 +0000 (02:15 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Mon, 9 May 2005 02:15:03 +0000 (02:15 +0000)
svn path=/trunk/; revision=15175

reactos/ntoskrnl/io/file.c

index faa1d82..430a4a5 100644 (file)
@@ -3,7 +3,7 @@
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/io/file.c
  * PURPOSE:         I/O File Object & NT File Handle Access/Managment of Files.
- *
+ * 
  * PROGRAMMERS:     David Welch (welch@mcmail.com)
  */
 
@@ -23,8 +23,8 @@ extern GENERIC_MAPPING IopFileMapping;
 
 /* INTERNAL FUNCTIONS ********************************************************/
 
-static
-NTSTATUS
+static 
+NTSTATUS 
 STDCALL
 IopLockFileCompletionRoutine(IN PDEVICE_OBJECT DeviceObject,
                              IN PIRP Irp,
@@ -38,16 +38,16 @@ IopLockFileCompletionRoutine(IN PDEVICE_OBJECT DeviceObject,
 /*
  * NAME       INTERNAL
  *  IopCreateFile
- *
+ *  
  * DESCRIPTION
- *
+ *  
  * ARGUMENTS
- *
+ *  
  * RETURN VALUE
  *
  * REVISIONS
  */
-NTSTATUS
+NTSTATUS 
 STDCALL
 IopCreateFile(PVOID ObjectBody,
               PVOID Parent,
@@ -173,7 +173,7 @@ IopCreateFile(PVOID ObjectBody,
   return(STATUS_SUCCESS);
 }
 
-VOID
+VOID 
 STDCALL
 IopDeleteFile(PVOID ObjectBody)
 {
@@ -183,11 +183,11 @@ IopDeleteFile(PVOID ObjectBody)
     NTSTATUS Status;
     KEVENT Event;
     PDEVICE_OBJECT DeviceObject;
-
+   
     DPRINT("IopDeleteFile()\n");
 
     if (FileObject->DeviceObject)
-    {
+    {    
         /* Check if this is a direct open or not */
         if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
         {
@@ -197,46 +197,46 @@ IopDeleteFile(PVOID ObjectBody)
         {
             DeviceObject = IoGetRelatedDeviceObject(FileObject);
         }
-
+        
         /* Clear and set up Events */
         KeClearEvent(&FileObject->Event);
         KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
-
+         
         /* Allocate an IRP */
         Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
-
+        
         /* Set it up */
         Irp->UserEvent = &Event;
         Irp->UserIosb = &Irp->IoStatus;
         Irp->Tail.Overlay.Thread = PsGetCurrentThread();
         Irp->Tail.Overlay.OriginalFileObject = FileObject;
         Irp->Flags = IRP_CLOSE_OPERATION | IRP_SYNCHRONOUS_API;
-
+        
         /* Set up Stack Pointer Data */
         StackPtr = IoGetNextIrpStackLocation(Irp);
         StackPtr->MajorFunction = IRP_MJ_CLOSE;
         StackPtr->DeviceObject = DeviceObject;
         StackPtr->FileObject = FileObject;
-
+   
         /* Call the FS Driver */
         Status = IoCallDriver(DeviceObject, Irp);
-
+        
         /* Wait for completion */
         if (Status == STATUS_PENDING)
         {
             KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
         }
        IoFreeIrp(Irp);
-
+      
     }
 
-    /* Clear the file name */
+    /* Clear the file name */  
     if (FileObject->FileName.Buffer)
     {
        ExFreePool(FileObject->FileName.Buffer);
        FileObject->FileName.Buffer = NULL;
     }
-
+        
     /* Free the completion context */
     if (FileObject->CompletionContext)
     {
@@ -245,7 +245,7 @@ IopDeleteFile(PVOID ObjectBody)
     }
 }
 
-static
+static 
 NTSTATUS
 IopSetDefaultSecurityDescriptor(SECURITY_INFORMATION SecurityInformation,
                                 PSECURITY_DESCRIPTOR SecurityDescriptor,
@@ -489,7 +489,7 @@ IopQueryNameFile(PVOID ObjectBody,
   return Status;
 }
 
-VOID
+VOID 
 STDCALL
 IopCloseFile(PVOID ObjectBody,
              ULONG HandleCount)
@@ -500,9 +500,9 @@ IopCloseFile(PVOID ObjectBody,
     PIO_STACK_LOCATION StackPtr;
     NTSTATUS Status;
     PDEVICE_OBJECT DeviceObject;
-
+   
     DPRINT("IopCloseFile()\n");
-
+   
     if (HandleCount > 1 || FileObject->DeviceObject == NULL) return;
 
     /* Check if this is a direct open or not */
@@ -514,29 +514,29 @@ IopCloseFile(PVOID ObjectBody,
     {
         DeviceObject = IoGetRelatedDeviceObject(FileObject);
     }
-
+    
     /* Clear and set up Events */
     KeClearEvent(&FileObject->Event);
     KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
-
+  
     /* Allocate an IRP */
     Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
-
+        
     /* Set it up */
     Irp->UserEvent = &Event;
     Irp->UserIosb = &Irp->IoStatus;
     Irp->Tail.Overlay.Thread = PsGetCurrentThread();
     Irp->Tail.Overlay.OriginalFileObject = FileObject;
     Irp->Flags = IRP_CLOSE_OPERATION | IRP_SYNCHRONOUS_API;
-
+        
     /* Set up Stack Pointer Data */
     StackPtr = IoGetNextIrpStackLocation(Irp);
     StackPtr->MajorFunction = IRP_MJ_CLEANUP;
     StackPtr->FileObject = FileObject;
-
+   
     /* Call the FS Driver */
     Status = IoCallDriver(DeviceObject, Irp);
-
+        
     /* Wait for completion */
     if (Status == STATUS_PENDING)
     {
@@ -576,60 +576,60 @@ IoCheckQuotaBufferValidity(IN PFILE_QUOTA_INFORMATION QuotaBuffer,
 /*
  * NAME       EXPORTED
  *  IoCreateFile@56
- *
+ *  
  * DESCRIPTION
  *  Either causes a new file or directory to be created, or it
  *  opens an existing file, device, directory or volume, giving
  *  the caller a handle for the file object. This handle can be
  *  used by subsequent calls to manipulate data within the file
  *  or the file object's state of attributes.
- *
+ *  
  * ARGUMENTS
  * FileHandle (OUT)
  *  Points to a variable which receives the file handle
  *  on return;
- *
+ *  
  * DesiredAccess
  *  Desired access to the file;
- *
+ *  
  * ObjectAttributes
  *  Structure describing the file;
- *
+ *  
  * IoStatusBlock (OUT)
  *  Receives information about the operation on return;
- *
+ *  
  * AllocationSize [OPTIONAL]
  *  Initial size of the file in bytes;
- *
+ *  
  * FileAttributes
  *  Attributes to create the file with;
- *
+ *  
  * ShareAccess
  *  Type of shared access the caller would like to the
  *  file;
- *
+ *  
  * CreateDisposition
  *  Specifies what to do, depending on whether the
  *  file already exists;
- *
+ *  
  * CreateOptions
  *  Options for creating a new file;
- *
+ *  
  * EaBuffer [OPTIONAL]
  *  Undocumented;
- *
+ *  
  * EaLength
  *  Undocumented;
- *
+ *  
  * CreateFileType
  *  Type of file (normal, named pipe, mailslot) to create;
- *
+ *  
  * ExtraCreateParameters [OPTIONAL]
  *  Additional creation data for named pipe and mailsots;
- *
+ *  
  * Options
  *  Undocumented.
- *
+ *  
  * RETURN VALUE
  *  Status
  *
@@ -637,12 +637,12 @@ IoCheckQuotaBufferValidity(IN PFILE_QUOTA_INFORMATION QuotaBuffer,
  *  Prototype taken from Bo Branten's ntifs.h v15.
  *  Description taken from old NtCreateFile's which is
  *  now a wrapper of this call.
- *
+ *  
  * REVISIONS
- *
+ * 
  * @implemented
  */
-NTSTATUS
+NTSTATUS 
 STDCALL
 IoCreateFile(OUT PHANDLE  FileHandle,
              IN ACCESS_MASK  DesiredAccess,
@@ -670,12 +670,12 @@ IoCreateFile(OUT PHANDLE  FileHandle,
    LARGE_INTEGER        SafeAllocationSize;
    PVOID                SystemEaBuffer = NULL;
    NTSTATUS  Status = STATUS_SUCCESS;
-
+   
    DPRINT("IoCreateFile(FileHandle %x, DesiredAccess %x, "
    "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
    FileHandle,DesiredAccess,ObjectAttributes,
    ObjectAttributes->ObjectName->Buffer);
-
+   
    ASSERT_IRQL(PASSIVE_LEVEL);
 
    if (IoStatusBlock == NULL || FileHandle == NULL)
@@ -687,7 +687,7 @@ IoCreateFile(OUT PHANDLE  FileHandle,
      AccessMode = KernelMode;
    else
      AccessMode = ExGetPreviousMode();
-
+   
    if(AccessMode != KernelMode)
    {
      _SEH_TRY
@@ -733,7 +733,7 @@ IoCreateFile(OUT PHANDLE  FileHandle,
        Status = _SEH_GetExceptionCode();
      }
      _SEH_END;
-
+     
      if(!NT_SUCCESS(Status))
      {
        return Status;
@@ -775,7 +775,7 @@ IoCreateFile(OUT PHANDLE  FileHandle,
          AccessMode,
          (PVOID*)&DeviceObject,
          NULL);
-         ZwClose(LocalHandle);
+         ZwClose(LocalHandle); 
   if (!NT_SUCCESS(Status))
   {
      return Status;
@@ -808,9 +808,9 @@ IoCreateFile(OUT PHANDLE  FileHandle,
  return Status;
       }
    }
-   RtlMapGenericMask(&DesiredAccess,
+   RtlMapGenericMask(&DesiredAccess,    
                       BODY_TO_HEADER(FileObject)->ObjectType->Mapping);
-
+                      
    Status = ObInsertObject ((PVOID)FileObject,
        NULL,
        DesiredAccess,
@@ -840,10 +840,10 @@ IoCreateFile(OUT PHANDLE  FileHandle,
    SecurityContext.AccessState = NULL; /* ?? */
    SecurityContext.DesiredAccess = DesiredAccess;
    SecurityContext.FullCreateOptions = 0; /* ?? */
-
+   
    KeInitializeEvent(&FileObject->Lock, SynchronizationEvent, TRUE);
    KeInitializeEvent(&FileObject->Event, NotificationEvent, FALSE);
-
+   
    DPRINT("FileObject %x\n", FileObject);
    DPRINT("FileObject->DeviceObject %x\n", FileObject->DeviceObject);
    /*
@@ -867,7 +867,7 @@ IoCreateFile(OUT PHANDLE  FileHandle,
    Irp->Tail.Overlay.Thread = PsGetCurrentThread();
    Irp->UserEvent = &FileObject->Event;
    Irp->Overlay.AllocationSize = SafeAllocationSize;
-
+   
    /*
     * Get the stack location for the new
     * IRP and prepare it.
@@ -891,7 +891,7 @@ IoCreateFile(OUT PHANDLE  FileHandle,
    StackLoc->Parameters.Create.ShareAccess = (USHORT)ShareAccess;
    StackLoc->Parameters.Create.EaLength = SystemEaBuffer != NULL ? EaLength : 0;
    break;
-
  case CreateFileTypeNamedPipe:
    StackLoc->MajorFunction = IRP_MJ_CREATE_NAMED_PIPE;
    StackLoc->Parameters.CreatePipe.SecurityContext = &SecurityContext;
@@ -919,7 +919,7 @@ IoCreateFile(OUT PHANDLE  FileHandle,
     */
    Status = IofCallDriver(FileObject->DeviceObject, Irp );
    DPRINT("Status :%x\n", Status);
-
+   
    if (Status == STATUS_PENDING)
      {
  KeWaitForSingleObject(&FileObject->Event,
@@ -992,25 +992,25 @@ IoCreateFileSpecifyDeviceObjectHint(OUT PHANDLE FileHandle,
 /*
  * NAME       EXPORTED
  *  IoCreateStreamFileObject@8
- *
+ *  
  * DESCRIPTION
- *
+ *  
  * ARGUMENTS
  * FileObject
  *  ?
- *
+ *  
  * DeviceObject
  *  ?
- *
+ *  
  * RETURN VALUE
  *
  * NOTE
- *
+ *  
  * REVISIONS
- *
+ * 
  * @implemented
  */
-PFILE_OBJECT
+PFILE_OBJECT 
 STDCALL
 IoCreateStreamFileObject(PFILE_OBJECT FileObject,
                          PDEVICE_OBJECT DeviceObject)
@@ -1046,14 +1046,14 @@ IoCreateStreamFileObject(PFILE_OBJECT FileObject,
 
   DPRINT("DeviceObject %x\n", DeviceObject);
 
-  if (DeviceObject->Vpb &&
+  if (DeviceObject->Vpb && 
       DeviceObject->Vpb->DeviceObject)
     {
       CreatedFileObject->DeviceObject = DeviceObject->Vpb->DeviceObject;
     }
   else
     {
-      CreatedFileObject->DeviceObject = DeviceObject;
+      CreatedFileObject->DeviceObject = DeviceObject; 
     }
   CreatedFileObject->Vpb = DeviceObject->Vpb;
   CreatedFileObject->Type = IO_TYPE_FILE;
@@ -1093,7 +1093,7 @@ IoCreateStreamFileObjectLite(IN PFILE_OBJECT FileObject OPTIONAL,
 /*
  * @implemented
  */
-PGENERIC_MAPPING
+PGENERIC_MAPPING 
 STDCALL
 IoGetFileObjectGenericMapping(VOID)
 {
@@ -1126,7 +1126,7 @@ IoQueryFileDosDeviceName(IN PFILE_OBJECT FileObject,
 /*
  * @implemented
  */
-NTSTATUS
+NTSTATUS 
 STDCALL
 IoQueryFileInformation(IN PFILE_OBJECT FileObject,
                        IN FILE_INFORMATION_CLASS FileInformationClass,
@@ -1141,20 +1141,20 @@ IoQueryFileInformation(IN PFILE_OBJECT FileObject,
     BOOLEAN LocalEvent = FALSE;
     KEVENT Event;
     NTSTATUS Status;
-
+   
     ASSERT(FileInformation != NULL);
-
+   
     Status = ObReferenceObjectByPointer(FileObject,
                                         FILE_READ_ATTRIBUTES,
                                         IoFileObjectType,
                                         KernelMode);
     if (!NT_SUCCESS(Status)) return(Status);
-
+   
     DPRINT("FileObject %x\n", FileObject);
-
+   
     /* Get the Device Object */
     DeviceObject = IoGetRelatedDeviceObject(FileObject);
-
+    
     /* Check if we should use Sync IO or not */
     if (FileObject->Flags & FO_SYNCHRONOUS_IO)
     {
@@ -1167,10 +1167,10 @@ IoQueryFileInformation(IN PFILE_OBJECT FileObject,
         KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
         LocalEvent = TRUE;
     }
-
+   
     /* Allocate the IRP */
     Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
-
+     
     /* Set the IRP */
     Irp->Tail.Overlay.OriginalFileObject = FileObject;
     Irp->RequestorMode = KernelMode;
@@ -1179,42 +1179,42 @@ IoQueryFileInformation(IN PFILE_OBJECT FileObject,
     Irp->UserEvent = (LocalEvent) ? &Event : NULL;
     Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;
     Irp->Tail.Overlay.Thread = PsGetCurrentThread();
-
+   
     /* Set the Stack Data */
     StackPtr = IoGetNextIrpStackLocation(Irp);
-    StackPtr->MajorFunction = IRP_MJ_QUERY_INFORMATION;
+    StackPtr->MajorFunction = IRP_MJ_QUERY_INFORMATION;    
     StackPtr->FileObject = FileObject;
-
+   
     /* Set Parameters */
     StackPtr->Parameters.QueryFile.FileInformationClass = FileInformationClass;
     StackPtr->Parameters.QueryFile.Length = Length;
-
+   
     /* Call the Driver */
     Status = IoCallDriver(FileObject->DeviceObject, Irp);
-
+    
     if (Status == STATUS_PENDING)
     {
         if (LocalEvent)
         {
-            KeWaitForSingleObject(&Event,
-                                  Executive,
-                                  KernelMode,
-                                  FileObject->Flags & FO_ALERTABLE_IO,
+            KeWaitForSingleObject(&Event, 
+                                  Executive, 
+                                  KernelMode, 
+                                  FileObject->Flags & FO_ALERTABLE_IO, 
                                   NULL);
             Status = IoStatusBlock.Status;
         }
         else
         {
             KeWaitForSingleObject(&FileObject->Event,
-                                  Executive,
-                                  KernelMode,
-                                  FileObject->Flags & FO_ALERTABLE_IO,
+                                  Executive, 
+                                  KernelMode, 
+                                  FileObject->Flags & FO_ALERTABLE_IO, 
                                   NULL);
             Status = FileObject->FinalStatus;
         }
     }
-
-
+        
+   
     /* Return the Length and Status. ReturnedLength is NOT optional */
     *ReturnedLength = IoStatusBlock.Information;
     return Status;
@@ -1235,7 +1235,7 @@ IoSetFileOrigin(IN PFILE_OBJECT FileObject,
 /**
  * @name NtCancelIoFile
  *
- * Cancel all pending I/O operations in the current thread for specified
+ * Cancel all pending I/O operations in the current thread for specified 
  * file object.
  *
  * @param FileHandle
@@ -1249,7 +1249,7 @@ IoSetFileOrigin(IN PFILE_OBJECT FileObject,
  *
  * @implemented
  */
-NTSTATUS
+NTSTATUS 
 STDCALL
 NtCancelIoFile(IN HANDLE FileHandle,
                OUT PIO_STATUS_BLOCK IoStatusBlock)
@@ -1293,7 +1293,7 @@ NtCancelIoFile(IN HANDLE FileHandle,
          /* Don't break here, we want to cancel all IRPs for the file object. */
          OurIrpsInList = TRUE;
       }
-   }
+   }   
 
    KfLowerIrql(OldIrql);
 
@@ -1349,14 +1349,14 @@ NtCancelIoFile(IN HANDLE FileHandle,
 /*
  * NAME       EXPORTED
  * NtCreateFile@44
- *
+ * 
  * DESCRIPTION
  * Entry point to call IoCreateFile with
  * default parameters.
  *
  * ARGUMENTS
  *  See IoCreateFile.
- *
+ * 
  * RETURN VALUE
  *  See IoCreateFile.
  *
@@ -1366,7 +1366,7 @@ NtCancelIoFile(IN HANDLE FileHandle,
  *
  * @implemented
  */
-NTSTATUS
+NTSTATUS 
 STDCALL
 NtCreateFile(PHANDLE FileHandle,
              ACCESS_MASK DesiredAccess,
@@ -1409,14 +1409,14 @@ NtCreateMailslotFile(OUT PHANDLE FileHandle,
                      IN PLARGE_INTEGER TimeOut)
 {
    MAILSLOT_CREATE_PARAMETERS Buffer;
-
+   
    DPRINT("NtCreateMailslotFile(FileHandle %x, DesiredAccess %x, "
    "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
    FileHandle,DesiredAccess,ObjectAttributes,
    ObjectAttributes->ObjectName->Buffer);
-
+   
    ASSERT_IRQL(PASSIVE_LEVEL);
-
+   
    if (TimeOut != NULL)
      {
  Buffer.ReadTimeout.QuadPart = TimeOut->QuadPart;
@@ -1506,9 +1506,9 @@ NtCreateNamedPipeFile(PHANDLE FileHandle,
 /*
  * NAME       EXPORTED
  * NtDeleteFile@4
- *
+ *  
  * DESCRIPTION
- *
+ *  
  * ARGUMENTS
  * ObjectAttributes
  *  ?
@@ -1516,10 +1516,10 @@ NtCreateNamedPipeFile(PHANDLE FileHandle,
  * RETURN VALUE
  *
  * REVISIONS
- *
+ * 
  * @unimplemented
  */
-NTSTATUS
+NTSTATUS 
 STDCALL
 NtDeleteFile(IN POBJECT_ATTRIBUTES ObjectAttributes)
 {
@@ -1539,10 +1539,10 @@ NtFlushWriteBuffer(VOID)
  * FUNCTION: Flushes cached file data to disk
  * ARGUMENTS:
  *       FileHandle = Points to the file
- *  IoStatusBlock = Caller must supply storage to receive the result of
+ *  IoStatusBlock = Caller must supply storage to receive the result of 
  *                       the flush buffers operation. The information field is
  *                       set to number of bytes flushed to disk.
- * RETURNS: Status
+ * RETURNS: Status 
  * REMARKS: This function maps to the win32 FlushFileBuffers
  */
 NTSTATUS
@@ -1577,7 +1577,7 @@ NtFlushBuffersFile(IN  HANDLE FileHandle,
     {
         DeviceObject = IoGetRelatedDeviceObject(FileObject);
     }
-
+    
     /* Check if we should use Sync IO or not */
     if (FileObject->Flags & FO_SYNCHRONOUS_IO)
     {
@@ -1597,7 +1597,7 @@ NtFlushBuffersFile(IN  HANDLE FileHandle,
         ObDereferenceObject(FileObject);
         return STATUS_INSUFFICIENT_RESOURCES;
     }
-
+    
     /* Set up the IRP */
     Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;
     Irp->RequestorMode = PreviousMode;
@@ -1610,26 +1610,26 @@ NtFlushBuffersFile(IN  HANDLE FileHandle,
     StackPtr = IoGetNextIrpStackLocation(Irp);
     StackPtr->MajorFunction = IRP_MJ_FLUSH_BUFFERS;
     StackPtr->FileObject = FileObject;
-
+    
     /* Call the Driver */
     Status = IoCallDriver(DeviceObject, Irp);
     if (Status == STATUS_PENDING)
     {
         if (LocalEvent)
         {
-            KeWaitForSingleObject(&Event,
-                                  Executive,
-                                  PreviousMode,
-                                  FileObject->Flags & FO_ALERTABLE_IO,
+            KeWaitForSingleObject(&Event, 
+                                  Executive, 
+                                  PreviousMode, 
+                                  FileObject->Flags & FO_ALERTABLE_IO, 
                                   NULL);
             Status = IoStatusBlock->Status;
         }
         else
         {
             KeWaitForSingleObject(&FileObject->Event,
-                                  Executive,
-                                  PreviousMode,
-                                  FileObject->Flags & FO_ALERTABLE_IO,
+                                  Executive, 
+                                  PreviousMode, 
+                                  FileObject->Flags & FO_ALERTABLE_IO, 
                                   NULL);
             Status = FileObject->FinalStatus;
         }
@@ -1645,9 +1645,9 @@ NtFlushBuffersFile(IN  HANDLE FileHandle,
 NTSTATUS
 STDCALL
 NtNotifyChangeDirectoryFile(IN HANDLE FileHandle,
-                            IN HANDLE Event OPTIONAL,
-                            IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
-                            IN PVOID ApcContext OPTIONAL,
+                            IN HANDLE Event OPTIONAL, 
+                            IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, 
+                            IN PVOID ApcContext OPTIONAL, 
                             OUT PIO_STATUS_BLOCK IoStatusBlock,
                             OUT PVOID Buffer,
                             IN ULONG BufferSize,
@@ -1660,13 +1660,13 @@ NtNotifyChangeDirectoryFile(IN HANDLE FileHandle,
    PIO_STACK_LOCATION IoStack;
    KPROCESSOR_MODE PreviousMode;
    NTSTATUS Status = STATUS_SUCCESS;
-
+   
    DPRINT("NtNotifyChangeDirectoryFile()\n");
-
+   
    PAGED_CODE();
 
    PreviousMode = ExGetPreviousMode();
-
+   
    if(PreviousMode != KernelMode)
    {
      _SEH_TRY
@@ -1686,7 +1686,7 @@ NtNotifyChangeDirectoryFile(IN HANDLE FileHandle,
        Status = _SEH_GetExceptionCode();
      }
      _SEH_END;
-
+     
      if(!NT_SUCCESS(Status))
      {
        return Status;
@@ -1700,18 +1700,18 @@ NtNotifyChangeDirectoryFile(IN HANDLE FileHandle,
                                        (PVOID *)&FileObject,
                                        NULL);
     if (Status != STATUS_SUCCESS) return(Status);
-
-
+   
+   
    DeviceObject = FileObject->DeviceObject;
-
-
+   
+   
    Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
    if (Irp==NULL)
      {
  ObDereferenceObject(FileObject);
  return STATUS_UNSUCCESSFUL;
      }
-
+   
    if (Event == NULL)
      {
        Event = &FileObject->Event;
@@ -1727,16 +1727,16 @@ NtNotifyChangeDirectoryFile(IN HANDLE FileHandle,
    Irp->UserBuffer = Buffer;
    Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
    Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
-
+   
    IoStack = IoGetNextIrpStackLocation(Irp);
-
+   
    IoStack->MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
    IoStack->MinorFunction = IRP_MN_NOTIFY_CHANGE_DIRECTORY;
    IoStack->Flags = 0;
    IoStack->Control = 0;
    IoStack->DeviceObject = DeviceObject;
    IoStack->FileObject = FileObject;
-
+   
    if (WatchTree)
      {
  IoStack->Flags = SL_WATCH_TREE;
@@ -1744,7 +1744,7 @@ NtNotifyChangeDirectoryFile(IN HANDLE FileHandle,
 
    IoStack->Parameters.NotifyDirectory.CompletionFilter = CompletionFilter;
    IoStack->Parameters.NotifyDirectory.Length = BufferSize;
-
+   
    Status = IoCallDriver(FileObject->DeviceObject,Irp);
 
    /* FIXME: Should we wait here or not for synchronously opened files? */
@@ -1915,39 +1915,39 @@ fail:;
 /*
  * NAME       EXPORTED
  *  NtOpenFile@24
- *
+ *  
  * DESCRIPTION
  *  Opens an existing file (simpler than NtCreateFile).
  *
  * ARGUMENTS
  * FileHandle (OUT)
  *  Variable that receives the file handle on return;
- *
+ *  
  * DesiredAccess
  *  Access desired by the caller to the file;
- *
+ *  
  * ObjectAttributes
  *  Structue describing the file to be opened;
- *
+ *  
  * IoStatusBlock (OUT)
  *  Receives details about the result of the
  *  operation;
- *
+ *  
  * ShareAccess
  *  Type of shared access the caller requires;
- *
+ *  
  * OpenOptions
  *  Options for the file open.
  *
  * RETURN VALUE
  *  Status.
- *
+ *  
  * NOTE
  *  Undocumented.
  *
  * @implemented
  */
-NTSTATUS
+NTSTATUS 
 STDCALL
 NtOpenFile(PHANDLE FileHandle,
            ACCESS_MASK DesiredAccess,
@@ -1973,7 +1973,7 @@ NtOpenFile(PHANDLE FileHandle,
                         0);
 }
 
-NTSTATUS
+NTSTATUS 
 STDCALL
 NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
                       OUT PFILE_BASIC_INFORMATION FileInformation)
@@ -2028,10 +2028,10 @@ NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
  *  FileBothDirectoryInformation FILE_BOTH_DIR_INFORMATION
  *
  *   Length = Size of the storage supplied
- *   FileInformationClass = Indicates the type of information requested.
- *   ReturnSingleEntry = Specify true if caller only requests the first
+ *   FileInformationClass = Indicates the type of information requested.  
+ *   ReturnSingleEntry = Specify true if caller only requests the first 
  *                            directory found.
- *   FileName = Initial directory name to query, that may contain wild
+ *   FileName = Initial directory name to query, that may contain wild 
  *                   cards.
  *        RestartScan = Number of times the action should be repeated
  * RETURNS: Status [ STATUS_SUCCESS, STATUS_ACCESS_DENIED, STATUS_INSUFFICIENT_RESOURCES,
@@ -2039,7 +2039,7 @@ NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
  *       STATUS_INVALID_INFO_CLASS, STATUS_NO_SUCH_FILE, STATUS_NO_MORE_FILES ]
  */
 NTSTATUS
-STDCALL
+STDCALL 
 NtQueryDirectoryFile(IN HANDLE FileHandle,
                      IN HANDLE PEvent OPTIONAL,
                      IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
@@ -2060,10 +2060,10 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
     NTSTATUS Status = STATUS_SUCCESS;
     BOOLEAN LocalEvent = FALSE;
     PKEVENT Event = NULL;
-
+   
     DPRINT("NtQueryDirectoryFile()\n");
     PAGED_CODE();
-
+    
     /* Validate User-Mode Buffers */
     if(PreviousMode != KernelMode)
     {
@@ -2093,7 +2093,7 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
                                        (PVOID *)&FileObject,
                                        NULL);
     if (Status != STATUS_SUCCESS) return(Status);
-
+    
     /* Get Event Object */
     if (PEvent)
     {
@@ -2116,7 +2116,7 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
     {
         DeviceObject = IoGetRelatedDeviceObject(FileObject);
     }
-
+   
     /* Check if we should use Sync IO or not */
     if (FileObject->Flags & FO_SYNCHRONOUS_IO)
     {
@@ -2127,14 +2127,14 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
     {
         LocalEvent = TRUE;
     }
-
+   
     /* Allocate the IRP */
     if (!(Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE)))
     {
         ObDereferenceObject(FileObject);
         return STATUS_INSUFFICIENT_RESOURCES;
     }
-
+   
     /* Set up the IRP */
     Irp->RequestorMode = PreviousMode;
     Irp->UserIosb = IoStatusBlock;
@@ -2144,13 +2144,13 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
     Irp->UserBuffer = FileInformation;
     Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
     Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
-
+   
     /* Set up Stack Data */
     StackPtr = IoGetNextIrpStackLocation(Irp);
     StackPtr->FileObject = FileObject;
     StackPtr->MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
     StackPtr->MinorFunction = IRP_MN_QUERY_DIRECTORY;
-
+   
     /* Set Parameters */
     StackPtr->Parameters.QueryDirectory.FileInformationClass = FileInformationClass;
     StackPtr->Parameters.QueryDirectory.FileName = FileName;
@@ -2159,7 +2159,7 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
     StackPtr->Flags = 0;
     if (RestartScan) StackPtr->Flags = SL_RESTART_SCAN;
     if (ReturnSingleEntry) StackPtr->Flags |= SL_RETURN_SINGLE_ENTRY;
-
+   
     /* Call the Driver */
     Status = IoCallDriver(DeviceObject, Irp);
     if (Status == STATUS_PENDING)
@@ -2167,9 +2167,9 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
         if (!LocalEvent)
         {
             KeWaitForSingleObject(&FileObject->Event,
-                                  Executive,
-                                  PreviousMode,
-                                  FileObject->Flags & FO_ALERTABLE_IO,
+                                  Executive, 
+                                  PreviousMode, 
+                                  FileObject->Flags & FO_ALERTABLE_IO, 
                                   NULL);
             Status = FileObject->FinalStatus;
         }
@@ -2197,7 +2197,7 @@ NtQueryEaFile(IN HANDLE FileHandle,
     return STATUS_NOT_IMPLEMENTED;
 }
 
-NTSTATUS
+NTSTATUS 
 STDCALL
 NtQueryFullAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
                           OUT PFILE_NETWORK_OPEN_INFORMATION FileInformation)
@@ -2302,7 +2302,7 @@ NtQueryInformationFile(HANDLE FileHandle,
     }
 
     DPRINT("FileObject %x\n", FileObject);
-
+        
     /* Check if this is a direct open or not */
     if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
     {
@@ -2312,7 +2312,7 @@ NtQueryInformationFile(HANDLE FileHandle,
     {
         DeviceObject = IoGetRelatedDeviceObject(FileObject);
     }
-
+    
     /* Check if we should use Sync IO or not */
     if (FileObject->Flags & FO_SYNCHRONOUS_IO)
     {
@@ -2332,10 +2332,10 @@ NtQueryInformationFile(HANDLE FileHandle,
         ObDereferenceObject(FileObject);
         return STATUS_INSUFFICIENT_RESOURCES;
     }
-
+    
     /* Allocate the System Buffer */
-    if (!(Irp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
-                                                                  Length,
+    if (!(Irp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithTag(NonPagedPool, 
+                                                                  Length, 
                                                                   TAG_SYSB)))
     {
         IoFreeIrp(Irp);
@@ -2352,7 +2352,7 @@ NtQueryInformationFile(HANDLE FileHandle,
     Irp->Tail.Overlay.Thread = PsGetCurrentThread();
     Irp->Flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER | IRP_INPUT_OPERATION;
     Irp->Flags |= (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;
-
+    
     /* Set up Stack Data */
     StackPtr = IoGetNextIrpStackLocation(Irp);
     StackPtr->MajorFunction = IRP_MJ_QUERY_INFORMATION;
@@ -2361,26 +2361,26 @@ NtQueryInformationFile(HANDLE FileHandle,
     /* Set the Parameters */
     StackPtr->Parameters.QueryFile.FileInformationClass = FileInformationClass;
     StackPtr->Parameters.QueryFile.Length = Length;
-
+    
     /* Call the Driver */
     Status = IoCallDriver(DeviceObject, Irp);
     if (Status == STATUS_PENDING)
     {
         if (LocalEvent)
         {
-            KeWaitForSingleObject(&Event,
-                                  Executive,
-                                  PreviousMode,
-                                  FileObject->Flags & FO_ALERTABLE_IO,
+            KeWaitForSingleObject(&Event, 
+                                  Executive, 
+                                  PreviousMode, 
+                                  FileObject->Flags & FO_ALERTABLE_IO, 
                                   NULL);
             Status = IoStatusBlock->Status;
         }
         else
         {
             KeWaitForSingleObject(&FileObject->Event,
-                                  Executive,
-                                  PreviousMode,
-                                  FileObject->Flags & FO_ALERTABLE_IO,
+                                  Executive, 
+                                  PreviousMode, 
+                                  FileObject->Flags & FO_ALERTABLE_IO, 
                                   NULL);
             Status = FileObject->FinalStatus;
         }
@@ -2423,7 +2423,7 @@ NtQueryQuotaInformationFile(IN HANDLE FileHandle,
  *
  * @implemented
  */
-NTSTATUS
+NTSTATUS 
 STDCALL
 NtReadFile(IN HANDLE FileHandle,
            IN HANDLE Event OPTIONAL,
@@ -2448,7 +2448,7 @@ NtReadFile(IN HANDLE FileHandle,
            "IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset,
             IoStatusBlock);
     PAGED_CODE();
-
+    
     /* Validate User-Mode Buffers */
     if(PreviousMode != KernelMode)
     {
@@ -2461,7 +2461,7 @@ NtReadFile(IN HANDLE FileHandle,
             ProbeForWrite(Buffer,
                           Length,
                           sizeof(ULONG));
-            #endif
+            #endif                          
         }
         _SEH_HANDLE
         {
@@ -2480,9 +2480,9 @@ NtReadFile(IN HANDLE FileHandle,
                                        (PVOID*)&FileObject,
                                        NULL);
     if (!NT_SUCCESS(Status)) return Status;
-
+    
     /* Check the Byte Offset */
-    if (!ByteOffset ||
+    if (!ByteOffset || 
         (ByteOffset->u.LowPart == FILE_USE_FILE_POINTER_POSITION &&
          ByteOffset->u.HighPart == 0xffffffff))
     {
@@ -2525,7 +2525,7 @@ NtReadFile(IN HANDLE FileHandle,
     {
         DeviceObject = IoGetRelatedDeviceObject(FileObject);
     }
-
+   
     /* Check if we should use Sync IO or not */
     if (FileObject->Flags & FO_SYNCHRONOUS_IO)
     {
@@ -2536,7 +2536,7 @@ NtReadFile(IN HANDLE FileHandle,
     {
         LocalEvent = TRUE;
     }
-
+    
     /* Create the IRP */
     _SEH_TRY
     {
@@ -2573,7 +2573,7 @@ NtReadFile(IN HANDLE FileHandle,
     Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
     Irp->Flags |= IRP_READ_OPERATION;
     if (FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING) Irp->Flags |= IRP_NOCACHE;
-
+    
     /* Setup Stack Data */
     StackPtr = IoGetNextIrpStackLocation(Irp);
     StackPtr->FileObject = FileObject;
@@ -2586,9 +2586,9 @@ NtReadFile(IN HANDLE FileHandle,
         if (!LocalEvent)
         {
             KeWaitForSingleObject(&FileObject->Event,
-                                  Executive,
-                                  PreviousMode,
-                                  FileObject->Flags & FO_ALERTABLE_IO,
+                                  Executive, 
+                                  PreviousMode, 
+                                  FileObject->Flags & FO_ALERTABLE_IO, 
                                   NULL);
             Status = FileObject->FinalStatus;
         }
@@ -2601,7 +2601,7 @@ NtReadFile(IN HANDLE FileHandle,
 /*
  * NAME       EXPORTED
  * NtReadFileScatter
- *
+ * 
  * DESCRIPTION
  *
  * ARGUMENTS
@@ -2629,7 +2629,7 @@ NtReadFileScatter(IN HANDLE FileHandle,
 /*
  * @unimplemented
  */
-NTSTATUS
+NTSTATUS 
 STDCALL
 NtSetEaFile(IN HANDLE FileHandle,
             IN PIO_STATUS_BLOCK IoStatusBlock,
@@ -2820,7 +2820,7 @@ NtSetInformationFile(HANDLE FileHandle,
 /*
  * @unimplemented
  */
-NTSTATUS
+NTSTATUS 
 STDCALL
 NtSetQuotaInformationFile(HANDLE FileHandle,
                           PIO_STATUS_BLOCK IoStatusBlock,
@@ -2945,7 +2945,7 @@ fail:;
  *
  * @implemented
  */
-NTSTATUS
+NTSTATUS 
 STDCALL
 NtWriteFile (IN HANDLE FileHandle,
              IN HANDLE Event OPTIONAL,
@@ -2957,158 +2957,200 @@ NtWriteFile (IN HANDLE FileHandle,
              IN PLARGE_INTEGER ByteOffset OPTIONAL, /* NOT optional for asynch. operations! */
              IN PULONG Key OPTIONAL)
 {
-  OBJECT_HANDLE_INFORMATION HandleInformation;
-  NTSTATUS Status;
-  PFILE_OBJECT FileObject;
-  PIRP Irp = NULL;
-  PIO_STACK_LOCATION StackPtr;
-  KPROCESSOR_MODE PreviousMode;
-  PKEVENT EventObject = NULL;
-  LARGE_INTEGER Offset;
-
-  DPRINT("NtWriteFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
-  "IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset,
-  IoStatusBlock);
+    OBJECT_HANDLE_INFORMATION HandleInformation;
+    NTSTATUS Status = STATUS_SUCCESS;
+    PFILE_OBJECT FileObject;
+    PIRP Irp = NULL;
+    PDEVICE_OBJECT DeviceObject;
+    PIO_STACK_LOCATION StackPtr;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    BOOLEAN LocalEvent = FALSE;
+    PKEVENT EventObject = NULL;
 
-  if (IoStatusBlock == NULL)
-    return STATUS_ACCESS_VIOLATION;
+    DPRINT("NtWriteFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
+            "IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset,
+            IoStatusBlock);
 
-  PreviousMode = ExGetPreviousMode();
+    /* Validate User-Mode Buffers */
+    if(PreviousMode != KernelMode)
+    {
+        _SEH_TRY
+        {
+            ProbeForWrite(IoStatusBlock,
+                          sizeof(IO_STATUS_BLOCK),
+                          sizeof(ULONG));
+            #if 0
+            ProbeForRead(Buffer,
+                         Length,
+                         sizeof(ULONG));
+            #endif
+        }
+        _SEH_HANDLE
+        {
+            Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
 
-  Status = ObReferenceObjectByHandle(FileHandle,
-         0,
-         IoFileObjectType,
-         PreviousMode,
-         (PVOID*)&FileObject,
-         &HandleInformation);
-  if (!NT_SUCCESS(Status))
-  {
-    return Status;
-  }
+        if(!NT_SUCCESS(Status)) return Status;
+    }
 
-  /* Must have FILE_WRITE_DATA | FILE_APPEND_DATA access */
-  if (!(HandleInformation.GrantedAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA)))
-  {
-    DPRINT1("Invalid access rights\n");
-    ObDereferenceObject(FileObject);
-    return STATUS_ACCESS_DENIED;
-  }
+    /* Get File Object */
+    Status = ObReferenceObjectByHandle(FileHandle,
+                                       0,
+                                       IoFileObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&FileObject,
+                                       &HandleInformation);
+    if (!NT_SUCCESS(Status)) return Status;
 
-  if (HandleInformation.GrantedAccess & FILE_WRITE_DATA)
-  {
-    if (ByteOffset == NULL)
+    /* Must have FILE_WRITE_DATA | FILE_APPEND_DATA access */
+    if (!(HandleInformation.GrantedAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA)))
     {
-      /* a valid ByteOffset is required if asynch. op. */
-      if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
-      {
-        DPRINT1("NtWriteFile: missing ByteOffset for asynch. op\n");
+        DPRINT1("Invalid access rights\n");
         ObDereferenceObject(FileObject);
-        return STATUS_INVALID_PARAMETER;
-      }
+        return STATUS_ACCESS_DENIED;
+    }
 
-      ByteOffset = &FileObject->CurrentByteOffset;
+    /* Check if we got write Access */
+    if (HandleInformation.GrantedAccess & FILE_WRITE_DATA)
+    {
+        /* Check the Byte Offset */
+        if (!ByteOffset || 
+            (ByteOffset->u.LowPart == FILE_USE_FILE_POINTER_POSITION &&
+             ByteOffset->u.HighPart == 0xffffffff))
+        {
+            /* a valid ByteOffset is required if asynch. op. */
+            if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
+            {
+                DPRINT1("NtReadFile: missing ByteOffset for asynch. op\n");
+                ObDereferenceObject(FileObject);
+                return STATUS_INVALID_PARAMETER;
+            }
+
+            /* Use the Current Byte OFfset */
+            ByteOffset = &FileObject->CurrentByteOffset;
+        }
     }
-  }
-  else if (HandleInformation.GrantedAccess & FILE_APPEND_DATA)
-  {
-    /* a valid ByteOffset is required if asynch. op. */
-    if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
+    else if (HandleInformation.GrantedAccess & FILE_APPEND_DATA)
     {
-      DPRINT1("NtWriteFile: missing ByteOffset for asynch. op\n");
-      ObDereferenceObject(FileObject);
-      return STATUS_INVALID_PARAMETER;
+        /* a valid ByteOffset is required if asynch. op. */
+        if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
+        {
+            DPRINT1("NtWriteFile: missing ByteOffset for asynch. op\n");
+            ObDereferenceObject(FileObject);
+            return STATUS_INVALID_PARAMETER;
+        }
+        
+        /* Give the drivers somethign to understand */
+        ByteOffset->u.LowPart = FILE_WRITE_TO_END_OF_FILE;
+        ByteOffset->u.HighPart = 0xffffffff;
     }
-
-    Offset.u.LowPart = FILE_WRITE_TO_END_OF_FILE;
-    Offset.u.HighPart = 0xffffffff;
-    ByteOffset = &Offset;
-  }
-
-  if (Event != NULL)
-  {
-    Status = ObReferenceObjectByHandle(Event,
-           SYNCHRONIZE,
-           ExEventObjectType,
-           PreviousMode,
-           (PVOID*)&EventObject,
-           NULL);
-    if (!NT_SUCCESS(Status))
+    
+    /* Check if we got an event */
+    if (Event)
     {
-      ObDereferenceObject(FileObject);
-      return Status;
+        /* Reference it */
+        Status = ObReferenceObjectByHandle(Event,
+                                           EVENT_MODIFY_STATE,
+                                           ExEventObjectType,
+                                           PreviousMode,
+                                           (PVOID*)&EventObject,
+                                           NULL);
+        if (!NT_SUCCESS(Status))
+        {
+            ObDereferenceObject(FileObject);
+            return Status;
+        }
+        KeClearEvent(EventObject);
     }
 
-    KeClearEvent(EventObject);
-  }
-
-  _SEH_TRY
-  {
-     Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
-            FileObject->DeviceObject,
-            Buffer,
-            Length,
-            ByteOffset,
-     EventObject,
-            IoStatusBlock);
-  }
-  _SEH_HANDLE
-  {
-     Status = _SEH_GetExceptionCode();
-  }
-  _SEH_END;
-
-  if (!NT_SUCCESS(Status) || Irp == NULL)
-  {
-     if (Event)
-     {
-        ObDereferenceObject(&EventObject);
-     }
-     ObDereferenceObject(FileObject);
-     if (Irp)
-     {
-        IoFreeIrp(Irp);
-     }
-     return NT_SUCCESS(Status) ? STATUS_INSUFFICIENT_RESOURCES : Status;
-  }
-
-  KeClearEvent(&FileObject->Event);
+    /* Check if this is a direct open or not */
+    if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
+    {
+        DeviceObject = IoGetAttachedDevice(FileObject->DeviceObject);
+    }
+    else
+    {
+        DeviceObject = IoGetRelatedDeviceObject(FileObject);
+    }
 
-  /* Trigger FileObject/Event dereferencing */
-  Irp->Tail.Overlay.OriginalFileObject = FileObject;
+    /* Check if we should use Sync IO or not */
+    if (FileObject->Flags & FO_SYNCHRONOUS_IO)
+    {
+        /* Use File Object event */
+        KeClearEvent(&FileObject->Event);
+    }
+    else
+    {
+        LocalEvent = TRUE;
+    }
+    
+    /* Build the IRP */
+    _SEH_TRY
+    {
+        Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
+                                           FileObject->DeviceObject,
+                                           Buffer,
+                                           Length,
+                                           ByteOffset,
+                                           EventObject,
+                                           IoStatusBlock);
+    }
+    _SEH_HANDLE
+    {
+        Status = _SEH_GetExceptionCode();
+    }
+    _SEH_END;
 
-  Irp->RequestorMode = PreviousMode;
+    /* Cleanup on failure */
+    if (!NT_SUCCESS(Status) || !Irp)
+    {
+        if (Event)
+        {
+            ObDereferenceObject(&EventObject);
+        }
+        ObDereferenceObject(FileObject);
+        if (Irp) IoFreeIrp(Irp);
+        return NT_SUCCESS(Status) ? STATUS_INSUFFICIENT_RESOURCES : Status;
+    }
 
-  Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
-  Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
+   /* Set up IRP Data */
+    Irp->Tail.Overlay.OriginalFileObject = FileObject;
+    Irp->RequestorMode = PreviousMode;
+    Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
+    Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
+    Irp->Flags |= IRP_WRITE_OPERATION;
+    if (FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING) Irp->Flags |= IRP_NOCACHE;
 
-  StackPtr = IoGetNextIrpStackLocation(Irp);
-  StackPtr->FileObject = FileObject;
-  StackPtr->Parameters.Write.Key = Key ? *Key : 0;
+    /* Setup Stack Data */
+    StackPtr = IoGetNextIrpStackLocation(Irp);
+    StackPtr->FileObject = FileObject;
+    StackPtr->Parameters.Write.Key = Key ? *Key : 0;
+    if (FileObject->Flags & FO_WRITE_THROUGH) StackPtr->Flags = SL_WRITE_THROUGH;
 
-  Status = IoCallDriver(FileObject->DeviceObject, Irp);
-  if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
-  {
-    Status = KeWaitForSingleObject(&FileObject->Event,
-       Executive,
-       PreviousMode,
-       FileObject->Flags & FO_ALERTABLE_IO,
-       NULL);
-    if (Status != STATUS_WAIT_0)
+    /* Call the Driver */
+    Status = IoCallDriver(DeviceObject, Irp);
+    if (Status == STATUS_PENDING)
     {
-      /* Wait failed. */
-      return Status;
+        if (!LocalEvent)
+        {
+            KeWaitForSingleObject(&FileObject->Event,
+                                  Executive,
+                                  PreviousMode,
+                                  FileObject->Flags & FO_ALERTABLE_IO,
+                                  NULL);
+            Status = FileObject->FinalStatus;
+        }
     }
 
-    Status = IoStatusBlock->Status;
-  }
-
-  return Status;
+    /* Return the Status */
+    return Status;
 }
 
 /*
  * NAME       EXPORTED
  * NtWriteFileGather
- *
+ * 
  * DESCRIPTION
  *
  * ARGUMENTS