- if a file object is a named pipe don't allow the FILE_APPEND_DATA access right as it equals FILE_CREATE_PIPE_INSTANCE (NtFlushBuffersFile and NtWriteFile)
- add more parameters probing and capturing code
Modified: trunk/reactos/ntoskrnl/io/file.c

Modified: trunk/reactos/ntoskrnl/io/file.c
--- trunk/reactos/ntoskrnl/io/file.c	2005-11-01 14:46:34 UTC (rev 18931)
+++ trunk/reactos/ntoskrnl/io/file.c	2005-11-01 16:17:25 UTC (rev 18932)
@@ -755,7 +755,6 @@
    IO_SECURITY_CONTEXT  SecurityContext;
    KPROCESSOR_MODE      AccessMode;
    HANDLE               LocalHandle;
-   IO_STATUS_BLOCK      LocalIoStatusBlock;
    LARGE_INTEGER        SafeAllocationSize;
    PVOID                SystemEaBuffer = NULL;
    NTSTATUS  Status = STATUS_SUCCESS;
@@ -988,7 +987,7 @@
    //trigger FileObject/Event dereferencing
    Irp->Tail.Overlay.OriginalFileObject = FileObject;
    Irp->RequestorMode = AccessMode;
-   Irp->UserIosb = &LocalIoStatusBlock;
+   Irp->UserIosb = IoStatusBlock;
    Irp->AssociatedIrp.SystemBuffer = SystemEaBuffer;
    Irp->Tail.Overlay.AuxiliaryBuffer = NULL;
    Irp->Tail.Overlay.Thread = PsGetCurrentThread();
@@ -1054,7 +1053,7 @@
                              AccessMode,
                              FALSE,
                              NULL);
-       Status = LocalIoStatusBlock.Status;
+       Status = IoStatusBlock->Status;
      }
    if (!NT_SUCCESS(Status))
      {
@@ -1069,7 +1068,6 @@
        _SEH_TRY
          {
            *FileHandle = LocalHandle;
-           *IoStatusBlock = LocalIoStatusBlock;
          }
        _SEH_HANDLE
          {
@@ -1380,20 +1378,41 @@
 NtCancelIoFile(IN HANDLE FileHandle,
                OUT PIO_STATUS_BLOCK IoStatusBlock)
 {
-   NTSTATUS Status;
    PFILE_OBJECT FileObject;
    PETHREAD Thread;
    PIRP Irp;
    KIRQL OldIrql;
    BOOLEAN OurIrpsInList = FALSE;
    LARGE_INTEGER Interval;
+   KPROCESSOR_MODE PreviousMode;
+   NTSTATUS Status = STATUS_SUCCESS;
 
-   if ((ULONG_PTR)IoStatusBlock >= (ULONG_PTR)MmUserProbeAddress &&
-       KeGetPreviousMode() != KernelMode)
-      return STATUS_ACCESS_VIOLATION;
+   PAGED_CODE();
 
-   Status = ObReferenceObjectByHandle(FileHandle, 0, IoFileObjectType,
-                                      KeGetPreviousMode(), (PVOID*)&FileObject,
+   PreviousMode = KeGetPreviousMode();
+
+   if (PreviousMode != KernelMode)
+   {
+      _SEH_TRY
+      {
+         ProbeForWrite(IoStatusBlock,
+                       sizeof(IO_STATUS_BLOCK),
+                       sizeof(ULONG));
+      }
+      _SEH_HANDLE
+      {
+         Status = _SEH_GetExceptionCode();
+      }
+      _SEH_END;
+
+      if (!NT_SUCCESS(Status)) return Status;
+   }
+
+   Status = ObReferenceObjectByHandle(FileHandle,
+                                      0,
+                                      IoFileObjectType,
+                                      PreviousMode,
+                                      (PVOID*)&FileObject,
                                       NULL);
    if (!NT_SUCCESS(Status))
       return Status;
@@ -1531,23 +1550,39 @@
     MAILSLOT_CREATE_PARAMETERS Buffer;
 
     DPRINT("NtCreateMailslotFile(FileHandle 0x%p, DesiredAccess %x, "
-           "ObjectAttributes 0x%p ObjectAttributes->ObjectName->Buffer %S)\n",
-           FileHandle,DesiredAccess,ObjectAttributes,
-           ObjectAttributes->ObjectName->Buffer);
+           "ObjectAttributes 0x%p)\n",
+           FileHandle,DesiredAccess,ObjectAttributes);
+
     PAGED_CODE();
 
     /* Check for Timeout */
-    if (TimeOut)
+    if (TimeOut != NULL)
     {
-        /* Enable it */
+        if (KeGetPreviousMode() != KernelMode)
+        {
+            NTSTATUS Status = STATUS_SUCCESS;
+
+            _SEH_TRY
+            {
+                Buffer.ReadTimeout = ProbeForReadLargeInteger(TimeOut);
+            }
+            _SEH_HANDLE
+            {
+                Status = _SEH_GetExceptionCode();
+            }
+            _SEH_END;
+
+            if (!NT_SUCCESS(Status)) return Status;
+        }
+        else
+        {
+            Buffer.ReadTimeout = *TimeOut;
+        }
+
         Buffer.TimeoutSpecified = TRUE;
-
-        /* FIXME: Add SEH */
-        Buffer.ReadTimeout = *TimeOut;
     }
     else
     {
-        /* No timeout */
         Buffer.TimeoutSpecified = FALSE;
     }
 
@@ -1592,25 +1627,39 @@
     NAMED_PIPE_CREATE_PARAMETERS Buffer;
 
     DPRINT("NtCreateNamedPipeFile(FileHandle 0x%p, DesiredAccess %x, "
-           "ObjectAttributes 0x%p ObjectAttributes->ObjectName->Buffer %S)\n",
-            FileHandle,DesiredAccess,ObjectAttributes,
-            ObjectAttributes->ObjectName->Buffer);
+           "ObjectAttributes 0x%p)\n",
+            FileHandle,DesiredAccess,ObjectAttributes);
+
     PAGED_CODE();
 
     /* Check for Timeout */
-    if (DefaultTimeout)
+    if (DefaultTimeout != NULL)
     {
-        /* Enable it */
+        if (KeGetPreviousMode() != KernelMode)
+        {
+            NTSTATUS Status = STATUS_SUCCESS;
+
+            _SEH_TRY
+            {
+                Buffer.DefaultTimeout = ProbeForReadLargeInteger(DefaultTimeout);
+            }
+            _SEH_HANDLE
+            {
+                Status = _SEH_GetExceptionCode();
+            }
+            _SEH_END;
+
+            if (!NT_SUCCESS(Status)) return Status;
+        }
+        else
+        {
+            Buffer.DefaultTimeout = *DefaultTimeout;
+        }
+
         Buffer.TimeoutSpecified = TRUE;
-
-        /* FIXME: Add SEH */
-        Buffer.DefaultTimeout = *DefaultTimeout;
     }
     else
-    {
-        /* No timeout */
         Buffer.TimeoutSpecified = FALSE;
-    }
 
     /* Set Settings */
     Buffer.NamedPipeType = NamedPipeType;
@@ -1724,6 +1773,8 @@
 STDCALL
 NtFlushWriteBuffer(VOID)
 {
+    PAGED_CODE();
+
     KeFlushWriteBuffer();
     return STATUS_SUCCESS;
 }
@@ -1746,21 +1797,57 @@
     PFILE_OBJECT FileObject = NULL;
     PIRP Irp;
     PIO_STACK_LOCATION StackPtr;
-    NTSTATUS Status;
+    NTSTATUS Status = STATUS_SUCCESS;
     PDEVICE_OBJECT DeviceObject;
     KEVENT Event;
     BOOLEAN LocalEvent = FALSE;
-    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    ACCESS_MASK DesiredAccess = FILE_WRITE_DATA;
+    OBJECT_HANDLE_INFORMATION ObjectHandleInfo;
+    KPROCESSOR_MODE PreviousMode;
 
+    PAGED_CODE();
+
+    PreviousMode = KeGetPreviousMode();
+
+    if (PreviousMode != KernelMode)
+    {
+        _SEH_TRY
+        {
+            ProbeForWrite(IoStatusBlock,
+                          sizeof(IO_STATUS_BLOCK),
+                          sizeof(ULONG));
+        }
+        _SEH_HANDLE
+        {
+            Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+
+        if (!NT_SUCCESS(Status)) return Status;
+    }
+
     /* Get the File Object */
     Status = ObReferenceObjectByHandle(FileHandle,
-                                       FILE_WRITE_DATA,
-                                       NULL,
+                                       0,
+                                       IoFileObjectType,
                                        PreviousMode,
                                        (PVOID*)&FileObject,
-                                       NULL);
-    if (Status != STATUS_SUCCESS) return(Status);
+                                       &ObjectHandleInfo);
+    if (!NT_SUCCESS(Status)) return(Status);
 
+    /* check if the handle has either FILE_WRITE_DATA or FILE_APPEND_DATA was
+       granted. However, if this is a named pipe, make sure we don't ask for
+       FILE_APPEND_DATA as it interferes with the FILE_CREATE_PIPE_INSTANCE
+       access right! */
+    if (!(FileObject->Flags & FO_NAMED_PIPE))
+        DesiredAccess |= FILE_APPEND_DATA;
+    if (!RtlAreAnyAccessesGranted(ObjectHandleInfo.GrantedAccess,
+                                  DesiredAccess))
+    {
+        ObDereferenceObject(FileObject);
+        return STATUS_ACCESS_DENIED;
+    }
+
     /* Check if this is a direct open or not */
     if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
     {
@@ -1968,13 +2055,18 @@
     PDEVICE_OBJECT DeviceObject;
     PKEVENT Event = NULL;
     BOOLEAN LocalEvent = FALSE;
-    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    KPROCESSOR_MODE PreviousMode;
+    LARGE_INTEGER CapturedByteOffset, CapturedLength;
     NTSTATUS Status = STATUS_SUCCESS;
     OBJECT_HANDLE_INFORMATION HandleInformation;
-     
-    /* FIXME: instead of this, use SEH */
-    if (!Length || !ByteOffset) return STATUS_INVALID_PARAMETER;
 
+    PAGED_CODE();
+
+    PreviousMode = KeGetPreviousMode();
+
+    CapturedByteOffset.QuadPart = 0;
+    CapturedLength.QuadPart = 0;
+
     /* Get File Object */
     Status = ObReferenceObjectByHandle(FileHandle,
                                        0,
@@ -1984,13 +2076,42 @@
                                        &HandleInformation);
     if (!NT_SUCCESS(Status)) return Status;
 
-    /* Must have FILE_READ_DATA | FILE_WRITE_DATA access */
-    if (!(HandleInformation.GrantedAccess & (FILE_WRITE_DATA | FILE_READ_DATA)))
+    if (PreviousMode != KernelMode)
     {
-        DPRINT1("Invalid access rights\n");
-        ObDereferenceObject(FileObject);
-        return STATUS_ACCESS_DENIED;
+        /* 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)))
+        {
+            DPRINT1("Invalid access rights\n");
+            ObDereferenceObject(FileObject);
+            return STATUS_ACCESS_DENIED;
+        }
+
+        _SEH_TRY
+        {
+            ProbeForWrite(IoStatusBlock,
+                          sizeof(IO_STATUS_BLOCK),
+                          sizeof(ULONG));
+            CapturedByteOffset = ProbeForReadLargeInteger(ByteOffset);
+            CapturedLength = ProbeForReadLargeInteger(Length);
+        }
+        _SEH_HANDLE
+        {
+            Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+
+        if (!NT_SUCCESS(Status))
+        {
+            ObDereferenceObject(FileObject);
+            return Status;
+        }
     }
+    else
+    {
+        CapturedByteOffset = *ByteOffset;
+        CapturedLength = *Length;
+    }
 
     /* Get Event Object */
     if (EventHandle)
@@ -2043,7 +2164,7 @@
         ObDereferenceObject(FileObject);
         return STATUS_INSUFFICIENT_RESOURCES;
     }
-    *LocalLength = *Length;
+    *LocalLength = CapturedLength;
     
     /* Set up the IRP */
     Irp->RequestorMode = PreviousMode;
@@ -2060,8 +2181,8 @@
     
     /* Set Parameters */
     StackPtr->Parameters.LockControl.Length = LocalLength;
-    StackPtr->Parameters.LockControl.ByteOffset = *ByteOffset;
-    StackPtr->Parameters.LockControl.Key = Key ? Key : 0;
+    StackPtr->Parameters.LockControl.ByteOffset = CapturedByteOffset;
+    StackPtr->Parameters.LockControl.Key = Key;
 
     /* Set Flags */
     if (FailImmediately) StackPtr->Flags = SL_FAIL_IMMEDIATELY;
@@ -2709,7 +2830,7 @@
            OUT PIO_STATUS_BLOCK IoStatusBlock,
            OUT PVOID Buffer,
            IN ULONG Length,
-           IN PLARGE_INTEGER ByteOffset OPTIONAL, /* NOT optional for asynch. operations! */
+           IN PLARGE_INTEGER ByteOffset OPTIONAL,
            IN PULONG Key OPTIONAL)
 {
     NTSTATUS Status = STATUS_SUCCESS;
@@ -2717,14 +2838,19 @@
     PIRP Irp = NULL;
     PDEVICE_OBJECT DeviceObject;
     PIO_STACK_LOCATION StackPtr;
-    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    KPROCESSOR_MODE PreviousMode;
     BOOLEAN LocalEvent = FALSE;
     PKEVENT EventObject = NULL;
+    LARGE_INTEGER CapturedByteOffset;
 
     DPRINT("NtReadFile(FileHandle 0x%p Buffer 0x%p Length %x ByteOffset 0x%p, "
            "IoStatusBlock 0x%p)\n", FileHandle, Buffer, Length, ByteOffset,
             IoStatusBlock);
+
     PAGED_CODE();
+    
+    PreviousMode = KeGetPreviousMode();
+    CapturedByteOffset.QuadPart = 0;
 
     /* Validate User-Mode Buffers */
     if(PreviousMode != KernelMode)
@@ -2734,11 +2860,14 @@
             ProbeForWrite(IoStatusBlock,
                           sizeof(IO_STATUS_BLOCK),
                           sizeof(ULONG));
-            #if 0
             ProbeForWrite(Buffer,
                           Length,
-                          sizeof(ULONG));
-            #endif
+                          1);
+            if (ByteOffset != NULL)
+            {
+                CapturedByteOffset = ProbeForReadLargeInteger(ByteOffset);
+            }
+            /* FIXME - probe other pointers and capture information */
         }
         _SEH_HANDLE
         {
@@ -2748,6 +2877,13 @@
 
         if(!NT_SUCCESS(Status)) return Status;
     }
+    else
+    {
+        if (ByteOffset != NULL)
+        {
+            CapturedByteOffset = *ByteOffset;
+        }
+    }
 
     /* Get File Object */
     Status = ObReferenceObjectByHandle(FileHandle,
@@ -2759,9 +2895,9 @@
     if (!NT_SUCCESS(Status)) return Status;
 
     /* Check the Byte Offset */
-    if (!ByteOffset ||
-        (ByteOffset->u.LowPart == FILE_USE_FILE_POINTER_POSITION &&
-         ByteOffset->u.HighPart == -1))
+    if (ByteOffset == NULL ||
+        (CapturedByteOffset.u.LowPart == FILE_USE_FILE_POINTER_POSITION &&
+         CapturedByteOffset.u.HighPart == -1))
     {
         /* a valid ByteOffset is required if asynch. op. */
         if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
@@ -2772,7 +2908,7 @@
         }
 
         /* Use the Current Byte OFfset */
-        ByteOffset = &FileObject->CurrentByteOffset;
+        CapturedByteOffset = FileObject->CurrentByteOffset;
     }
 
     /* Check for event */
@@ -2821,7 +2957,7 @@
                                            DeviceObject,
                                            Buffer,
                                            Length,
-                                           ByteOffset,
+                                           &CapturedByteOffset,
                                            EventObject,
                                            IoStatusBlock);
         if (Irp == NULL)
@@ -3276,7 +3412,7 @@
              OUT PIO_STATUS_BLOCK IoStatusBlock,
              IN  PLARGE_INTEGER ByteOffset,
              IN  PLARGE_INTEGER Length,
-             OUT ULONG Key OPTIONAL)
+             IN  ULONG Key OPTIONAL)
 {
     PFILE_OBJECT FileObject = NULL;
     PLARGE_INTEGER LocalLength = NULL;
@@ -3285,13 +3421,18 @@
     PDEVICE_OBJECT DeviceObject;
     KEVENT Event;
     BOOLEAN LocalEvent = FALSE;
-    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    KPROCESSOR_MODE PreviousMode;
     NTSTATUS Status = STATUS_SUCCESS;
+    LARGE_INTEGER CapturedByteOffset, CapturedLength;
     OBJECT_HANDLE_INFORMATION HandleInformation;
-     
-    /* FIXME: instead of this, use SEH */
-    if (!Length || !ByteOffset) return STATUS_INVALID_PARAMETER;
 
+    PAGED_CODE();
+
+    PreviousMode = KeGetPreviousMode();
+
+    CapturedByteOffset.QuadPart = 0;
+    CapturedLength.QuadPart = 0;
+
     /* Get File Object */
     Status = ObReferenceObjectByHandle(FileHandle,
                                        0,
@@ -3301,13 +3442,42 @@
                                        &HandleInformation);
     if (!NT_SUCCESS(Status)) return Status;
 
-    /* Must have FILE_READ_DATA | FILE_WRITE_DATA access */
-    if (!(HandleInformation.GrantedAccess & (FILE_WRITE_DATA | FILE_READ_DATA)))
+    if (PreviousMode != KernelMode)
     {
-        DPRINT1("Invalid access rights\n");
-        ObDereferenceObject(FileObject);
-        return STATUS_ACCESS_DENIED;
+        /* 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)))
+        {
+            DPRINT1("Invalid access rights\n");
+            ObDereferenceObject(FileObject);
+            return STATUS_ACCESS_DENIED;
+        }
+
+        _SEH_TRY
+        {
+            ProbeForWrite(IoStatusBlock,
+                          sizeof(IO_STATUS_BLOCK),
+                          sizeof(ULONG));
+            CapturedByteOffset = ProbeForReadLargeInteger(ByteOffset);
+            CapturedLength = ProbeForReadLargeInteger(Length);
+        }
+        _SEH_HANDLE
+        {
+            Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+
+        if (!NT_SUCCESS(Status))
+        {
+            ObDereferenceObject(FileObject);
+            return Status;
+        }
     }
+    else
+    {
+        CapturedByteOffset = *ByteOffset;
+        CapturedLength = *Length;
+    }
 
     /* Check if this is a direct open or not */
     if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
@@ -3349,7 +3519,7 @@
         ObDereferenceObject(FileObject);
         return STATUS_INSUFFICIENT_RESOURCES;
     }
-    *LocalLength = *Length;
+    *LocalLength = CapturedLength;
     
     /* Set up the IRP */
     Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;
@@ -3367,8 +3537,8 @@
     
     /* Set Parameters */
     StackPtr->Parameters.LockControl.Length = LocalLength;
-    StackPtr->Parameters.LockControl.ByteOffset = *ByteOffset;
-    StackPtr->Parameters.LockControl.Key = Key ? Key : 0;
+    StackPtr->Parameters.LockControl.ByteOffset = CapturedByteOffset;
+    StackPtr->Parameters.LockControl.Key = Key;
 
     /* Call the Driver */
     Status = IoCallDriver(DeviceObject, Irp);
@@ -3424,34 +3594,49 @@
              IN PLARGE_INTEGER ByteOffset OPTIONAL, /* NOT optional for asynch. operations! */
              IN PULONG Key OPTIONAL)
 {
-    OBJECT_HANDLE_INFORMATION HandleInformation;
+    OBJECT_HANDLE_INFORMATION ObjectHandleInfo;
     NTSTATUS Status = STATUS_SUCCESS;
     PFILE_OBJECT FileObject;
     PIRP Irp = NULL;
     PDEVICE_OBJECT DeviceObject;
     PIO_STACK_LOCATION StackPtr;
-    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    KPROCESSOR_MODE PreviousMode;
     BOOLEAN LocalEvent = FALSE;
     PKEVENT EventObject = NULL;
+    LARGE_INTEGER CapturedByteOffset;
+    ULONG CapturedKey = 0;
+    ACCESS_MASK DesiredAccess = FILE_WRITE_DATA;
 
     DPRINT("NtWriteFile(FileHandle 0x%p Buffer 0x%p Length %x ByteOffset 0x%p, "
             "IoStatusBlock 0x%p)\n", FileHandle, Buffer, Length, ByteOffset,
             IoStatusBlock);
 
+    PAGED_CODE();
+
+    PreviousMode = KeGetPreviousMode();
+    CapturedByteOffset.QuadPart = 0;
+
     /* Validate User-Mode Buffers */
     if(PreviousMode != KernelMode)
     {
         _SEH_TRY
         {
-            #if 0
             ProbeForWrite(IoStatusBlock,
                           sizeof(IO_STATUS_BLOCK),
                           sizeof(ULONG));
 
             ProbeForRead(Buffer,
                          Length,
-                         sizeof(ULONG));
-            #endif
+                         1);
+            if (ByteOffset != NULL)
+            {
+                CapturedByteOffset = ProbeForReadLargeInteger(ByteOffset);
+            }
+
+            if (Key != NULL)
+            {
+                CapturedKey = ProbeForReadUlong(Key);
+            }
         }
         _SEH_HANDLE
         {
@@ -3461,6 +3646,17 @@
 
         if(!NT_SUCCESS(Status)) return Status;
     }
+    else
+    {
+        if (ByteOffset != NULL)
+        {
+            CapturedByteOffset = *ByteOffset;
+        }
+        if (Key != NULL)
+        {
+            CapturedKey = *Key;
+        }
+    }
 
     /* Get File Object */
     Status = ObReferenceObjectByHandle(FileHandle,
@@ -3468,24 +3664,29 @@
                                        IoFileObjectType,
                                        PreviousMode,
                                        (PVOID*)&FileObject,
-                                       &HandleInformation);
+                                       &ObjectHandleInfo);
     if (!NT_SUCCESS(Status)) return Status;
 
-    /* Must have FILE_WRITE_DATA | FILE_APPEND_DATA access */
-    if (!(HandleInformation.GrantedAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA)))
+    /* check if the handle has either FILE_WRITE_DATA or FILE_APPEND_DATA was
+       granted. However, if this is a named pipe, make sure we don't ask for
+       FILE_APPEND_DATA as it interferes with the FILE_CREATE_PIPE_INSTANCE
+       access right! */
+    if (!(FileObject->Flags & FO_NAMED_PIPE))
+        DesiredAccess |= FILE_APPEND_DATA;
+    if (!RtlAreAnyAccessesGranted(ObjectHandleInfo.GrantedAccess,
+                                  DesiredAccess))
     {
-        DPRINT1("Invalid access rights\n");
         ObDereferenceObject(FileObject);
         return STATUS_ACCESS_DENIED;
     }
 
     /* Check if we got write Access */
-    if (HandleInformation.GrantedAccess & FILE_WRITE_DATA)
+    if (ObjectHandleInfo.GrantedAccess & FILE_WRITE_DATA)
     {
         /* Check the Byte Offset */
-        if (!ByteOffset ||
-            (ByteOffset->u.LowPart == FILE_USE_FILE_POINTER_POSITION &&
-             ByteOffset->u.HighPart == -1))
+        if (ByteOffset == NULL ||
+            (CapturedByteOffset.u.LowPart == FILE_USE_FILE_POINTER_POSITION &&
+             CapturedByteOffset.u.HighPart == -1))
         {
             /* a valid ByteOffset is required if asynch. op. */
             if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
@@ -3496,10 +3697,11 @@
             }
 
             /* Use the Current Byte OFfset */
-            ByteOffset = &FileObject->CurrentByteOffset;
+            CapturedByteOffset = FileObject->CurrentByteOffset;
         }
     }
-    else if (HandleInformation.GrantedAccess & FILE_APPEND_DATA)
+    else if ((ObjectHandleInfo.GrantedAccess & FILE_APPEND_DATA) &&
+             !(FileObject->Flags & FO_NAMED_PIPE))
     {
         /* a valid ByteOffset is required if asynch. op. */
         if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
@@ -3510,8 +3712,8 @@
         }
 
         /* Give the drivers somethign to understand */
-        ByteOffset->u.LowPart = FILE_WRITE_TO_END_OF_FILE;
-        ByteOffset->u.HighPart = 0xffffffff;
+        CapturedByteOffset.u.LowPart = FILE_WRITE_TO_END_OF_FILE;
+        CapturedByteOffset.u.HighPart = 0xffffffff;
     }
 
     /* Check if we got an event */
@@ -3560,7 +3762,7 @@
                                            DeviceObject,
                                            Buffer,
                                            Length,
-                                           ByteOffset,
+                                           &CapturedByteOffset,
                                            EventObject,
                                            IoStatusBlock);
         if (Irp == NULL)
@@ -3601,7 +3803,7 @@
     /* Setup Stack Data */
     StackPtr = IoGetNextIrpStackLocation(Irp);
     StackPtr->FileObject = FileObject;
-    StackPtr->Parameters.Write.Key = Key ? *Key : 0;
+    StackPtr->Parameters.Write.Key = CapturedKey;
     if (FileObject->Flags & FO_WRITE_THROUGH) StackPtr->Flags = SL_WRITE_THROUGH;
 
     /* Call the Driver */