Cleanup isn't necessary after calling the driver in NtQueryDirectoryFile.
[reactos.git] / reactos / ntoskrnl / io / file.c
index a635f70..c8107ff 100644 (file)
@@ -50,10 +50,10 @@ IopCreateFile(PVOID ObjectBody,
   POBJECT_TYPE ParentObjectType;
   NTSTATUS Status;
 
-  DPRINT("IopCreateFile(ObjectBody %x, Parent %x, RemainingPath %S)\n",
-  ObjectBody,
-  Parent,
-  RemainingPath);
+  DPRINT("IopCreateFile(ObjectBody 0x%p, Parent 0x%p, RemainingPath %S)\n",
+         ObjectBody,
+         Parent,
+         RemainingPath);
 
   if (NULL == Parent)
     {
@@ -69,19 +69,19 @@ IopCreateFile(PVOID ObjectBody,
       ParentObjectType != IoFileObjectType)
     {
       DPRINT("Parent [%wZ] is a %S which is neither a file type nor a device type ; remaining path = %S\n",
-        &BODY_TO_HEADER(Parent)->NameInfo->Name,
-        BODY_TO_HEADER(Parent)->Type->Name.Buffer,
-        RemainingPath);
+             &HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(Parent))->Name,
+             BODY_TO_HEADER(Parent)->Type->Name.Buffer,
+             RemainingPath);
       return(STATUS_UNSUCCESSFUL);
     }
 
   Status = ObReferenceObjectByPointer(Parent,
-          STANDARD_RIGHTS_REQUIRED,
-          ParentObjectType,
-          UserMode);
+                                      STANDARD_RIGHTS_REQUIRED,
+                                      ParentObjectType,
+                                      UserMode);
   if (!NT_SUCCESS(Status))
     {
-      CPRINT("Failed to reference parent object %x\n", Parent);
+      CPRINT("Failed to reference parent object 0x%p\n", Parent);
       return(Status);
     }
 
@@ -89,75 +89,72 @@ IopCreateFile(PVOID ObjectBody,
     {
       /* Parent is a devce object */
       DeviceObject = IoGetAttachedDevice((PDEVICE_OBJECT)Parent);
-      DPRINT("DeviceObject %x\n", DeviceObject);
+      DPRINT("DeviceObject 0x%p\n", DeviceObject);
 
       if (RemainingPath == NULL)
- {
-   FileObject->Flags = FileObject->Flags | FO_DIRECT_DEVICE_OPEN;
-   FileObject->FileName.Buffer = 0;
-   FileObject->FileName.Length = FileObject->FileName.MaximumLength = 0;
- }
       {
+          FileObject->Flags = FileObject->Flags | FO_DIRECT_DEVICE_OPEN;
+          FileObject->FileName.Buffer = 0;
+          FileObject->FileName.Length = FileObject->FileName.MaximumLength = 0;
       }
       else
- {
-   if ((DeviceObject->DeviceType != FILE_DEVICE_FILE_SYSTEM)
-       && (DeviceObject->DeviceType != FILE_DEVICE_DISK)
-       && (DeviceObject->DeviceType != FILE_DEVICE_CD_ROM)
-       && (DeviceObject->DeviceType != FILE_DEVICE_TAPE)
-       && (DeviceObject->DeviceType != FILE_DEVICE_NETWORK)
-       && (DeviceObject->DeviceType != FILE_DEVICE_NAMED_PIPE)
-       && (DeviceObject->DeviceType != FILE_DEVICE_MAILSLOT))
-     {
-       CPRINT("Device was wrong type\n");
-       return(STATUS_UNSUCCESSFUL);
-     }
       {
+          if ((DeviceObject->DeviceType != FILE_DEVICE_FILE_SYSTEM)
+              && (DeviceObject->DeviceType != FILE_DEVICE_DISK)
+              && (DeviceObject->DeviceType != FILE_DEVICE_CD_ROM)
+              && (DeviceObject->DeviceType != FILE_DEVICE_TAPE)
+              && (DeviceObject->DeviceType != FILE_DEVICE_NETWORK)
+              && (DeviceObject->DeviceType != FILE_DEVICE_NAMED_PIPE)
+              && (DeviceObject->DeviceType != FILE_DEVICE_MAILSLOT))
+            {
+              CPRINT("Device was wrong type\n");
+              return(STATUS_UNSUCCESSFUL);
+            }
 
-   if (DeviceObject->DeviceType != FILE_DEVICE_NETWORK
-       && (DeviceObject->DeviceType != FILE_DEVICE_NAMED_PIPE)
-       && (DeviceObject->DeviceType != FILE_DEVICE_MAILSLOT))
-     {
-       if (!(DeviceObject->Vpb->Flags & VPB_MOUNTED))
-  {
-    DPRINT("Mount the logical volume\n");
-    Status = IoMountVolume(DeviceObject, FALSE);
-    DPRINT("Status %x\n", Status);
-    if (!NT_SUCCESS(Status))
-      {
-        CPRINT("Failed to mount logical volume (Status %x)\n",
-        Status);
-        return(Status);
-      }
-  }
-       DeviceObject = DeviceObject->Vpb->DeviceObject;
-       DPRINT("FsDeviceObject %lx\n", DeviceObject);
-     }
-   RtlpCreateUnicodeString(&(FileObject->FileName),
-             RemainingPath, NonPagedPool);
- }
+          if (DeviceObject->DeviceType != FILE_DEVICE_NETWORK
+              && (DeviceObject->DeviceType != FILE_DEVICE_NAMED_PIPE)
+              && (DeviceObject->DeviceType != FILE_DEVICE_MAILSLOT))
+            {
+              if (!(DeviceObject->Vpb->Flags & VPB_MOUNTED))
+                {
+                  DPRINT("Mount the logical volume\n");
+                  Status = IoMountVolume(DeviceObject, FALSE);
+                  DPRINT("Status %x\n", Status);
+                  if (!NT_SUCCESS(Status))
+                    {
+                      CPRINT("Failed to mount logical volume (Status %x)\n", Status);
+                      return(Status);
+                    }
+                }
+              DeviceObject = DeviceObject->Vpb->DeviceObject;
+              DPRINT("FsDeviceObject %lx\n", DeviceObject);
+            }
+          RtlCreateUnicodeString(&FileObject->FileName, RemainingPath);
+        }
     }
   else
     {
       /* Parent is a file object */
       if (RemainingPath == NULL)
- {
-   CPRINT("Device is unnamed\n");
-   return STATUS_UNSUCCESSFUL;
- }
       {
+          CPRINT("Device is unnamed\n");
+          return STATUS_UNSUCCESSFUL;
       }
 
       DeviceObject = ((PFILE_OBJECT)Parent)->DeviceObject;
-      DPRINT("DeviceObject %x\n", DeviceObject);
+      DPRINT("DeviceObject 0x%p\n", DeviceObject);
 
       FileObject->RelatedFileObject = (PFILE_OBJECT)Parent;
 
-      RtlpCreateUnicodeString(&(FileObject->FileName),
-              RemainingPath, NonPagedPool);
+      RtlCreateUnicodeString(&FileObject->FileName, RemainingPath);
     }
 
   DPRINT("FileObject->FileName %wZ\n",
-  &FileObject->FileName);
+         &FileObject->FileName);
   FileObject->DeviceObject = DeviceObject;
-  DPRINT("FileObject %x DeviceObject %x\n",
-  FileObject,
-  DeviceObject);
+  DPRINT("FileObject 0x%p DeviceObject 0x%p\n",
+         FileObject,
+         DeviceObject);
   FileObject->Vpb = DeviceObject->Vpb;
   FileObject->Type = IO_TYPE_FILE;
 
@@ -242,7 +239,10 @@ IopSecurityFile(PVOID ObjectBody,
                 SECURITY_OPERATION_CODE OperationCode,
                 SECURITY_INFORMATION SecurityInformation,
                 PSECURITY_DESCRIPTOR SecurityDescriptor,
-                PULONG BufferLength)
+                PULONG BufferLength,
+                PSECURITY_DESCRIPTOR *OldSecurityDescriptor,    
+                POOL_TYPE PoolType,
+                PGENERIC_MAPPING GenericMapping)
 {
     IO_STATUS_BLOCK IoStatusBlock;
     PIO_STACK_LOCATION StackPtr;
@@ -325,6 +325,7 @@ IopSecurityFile(PVOID ObjectBody,
 
     /* Set Stack Parameters */
     StackPtr = IoGetNextIrpStackLocation(Irp);
+    StackPtr->MajorFunction = MajorFunction;
     StackPtr->FileObject = FileObject;
 
     /* Set Parameters */
@@ -400,7 +401,7 @@ IopQueryNameFile(PVOID ObjectBody,
                  ULONG Length,
                  PULONG ReturnLength)
 {
-    PVOID LocalInfo;
+    POBJECT_NAME_INFORMATION LocalInfo;
     PFILE_OBJECT FileObject;
     ULONG LocalReturnLength;
     NTSTATUS Status;
@@ -429,7 +430,7 @@ IopQueryNameFile(PVOID ObjectBody,
     
     /* Write Device Path */
     Status = RtlAppendUnicodeStringToString(&ObjectNameInfo->Name,
-                                            &((POBJECT_NAME_INFORMATION)LocalInfo)->Name);
+                                            &(LocalInfo)->Name);
 
     /* Query the File name */
     Status = IoQueryFileInformation(FileObject,
@@ -532,10 +533,10 @@ IopDeviceFsIoControl(IN HANDLE DeviceHandle,
     BOOLEAN LocalEvent = FALSE;
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
 
-    DPRINT("IopDeviceFsIoControl(DeviceHandle %x Event %x UserApcRoutine %x "
-           "UserApcContext %x IoStatusBlock %x IoControlCode %x "
-           "InputBuffer %x InputBufferLength %x OutputBuffer %x "
-           "OutputBufferLength %x)\n",
+    DPRINT("IopDeviceFsIoControl(DeviceHandle 0x%p Event 0x%p UserApcRoutine 0x%p "
+           "UserApcContext 0x%p IoStatusBlock 0x%p IoControlCode %x "
+           "InputBuffer 0x%p InputBufferLength %x OutputBuffer 0x%p "
+           "OutputBufferLength 0x%p)\n",
            DeviceHandle,Event,UserApcRoutine,UserApcContext,IoStatusBlock,
            IoControlCode,InputBuffer,InputBufferLength,OutputBuffer,
            OutputBufferLength);
@@ -750,19 +751,20 @@ IoCreateFile(OUT PHANDLE  FileHandle,
    PFILE_OBJECT  FileObject = NULL;
    PDEVICE_OBJECT DeviceObject;
    PIRP   Irp;
-   PIO_STACK_LOCATION StackLoc;
+   PEXTENDED_IO_STACK_LOCATION StackLoc;
    IO_SECURITY_CONTEXT  SecurityContext;
    KPROCESSOR_MODE      AccessMode;
    HANDLE               LocalHandle;
-   IO_STATUS_BLOCK      LocalIoStatusBlock;
    LARGE_INTEGER        SafeAllocationSize;
    PVOID                SystemEaBuffer = NULL;
    NTSTATUS  Status = STATUS_SUCCESS;
+   AUX_DATA AuxData;
+   ACCESS_STATE AccessState;
 
-   DPRINT("IoCreateFile(FileHandle %x, DesiredAccess %x, "
-   "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
-   FileHandle,DesiredAccess,ObjectAttributes,
-   ObjectAttributes->ObjectName->Buffer);
+   DPRINT("IoCreateFile(FileHandle 0x%p, DesiredAccess %x, "
+          "ObjectAttributes 0x%p ObjectAttributes->ObjectName->Buffer %S)\n",
+          FileHandle,DesiredAccess,ObjectAttributes,
+          ObjectAttributes->ObjectName->Buffer);
 
    ASSERT_IRQL(PASSIVE_LEVEL);
 
@@ -780,18 +782,13 @@ IoCreateFile(OUT PHANDLE  FileHandle,
    {
      _SEH_TRY
      {
-       ProbeForWrite(FileHandle,
-                     sizeof(HANDLE),
-                     sizeof(ULONG));
+       ProbeForWriteHandle(FileHandle);
        ProbeForWrite(IoStatusBlock,
                      sizeof(IO_STATUS_BLOCK),
                      sizeof(ULONG));
        if(AllocationSize != NULL)
        {
-         ProbeForRead(AllocationSize,
-                      sizeof(LARGE_INTEGER),
-                      sizeof(ULONG));
-         SafeAllocationSize = *AllocationSize;
+         SafeAllocationSize = ProbeForReadLargeInteger(AllocationSize);
        }
        else
          SafeAllocationSize.QuadPart = 0;
@@ -845,102 +842,144 @@ IoCreateFile(OUT PHANDLE  FileHandle,
      DPRINT1("FIXME: IO_CHECK_CREATE_PARAMETERS not yet supported!\n");
    }
 
-   if (CreateDisposition == FILE_OPEN ||
-       CreateDisposition == FILE_OPEN_IF)
-   {
+   /* First try to open an existing named object */
+   Status = ObOpenObjectByName(ObjectAttributes,
+                               NULL,
+                               NULL,
+                               AccessMode,
+                               DesiredAccess,
+                               NULL,
+                               &LocalHandle);
 
-      Status = ObOpenObjectByName(ObjectAttributes,
-                           NULL,
-      NULL,
-      AccessMode,
-      DesiredAccess,
-      NULL,
-      &LocalHandle);
+   if (NT_SUCCESS(Status))
+   {
+      OBJECT_CREATE_INFORMATION ObjectCreateInfo;
+      OBJECT_ATTRIBUTES tmpObjectAttributes;
+      UNICODE_STRING ObjectName;
+
+      Status = ObReferenceObjectByHandle(LocalHandle,
+                                         DesiredAccess,
+                                         NULL,
+                                         AccessMode,
+                                         (PVOID*)&DeviceObject,
+                                         NULL);
+      ZwClose(LocalHandle);
+      if (!NT_SUCCESS(Status))
+      {
+         return Status;
+      }
+      if (BODY_TO_HEADER(DeviceObject)->Type != IoDeviceObjectType)
+      {
+         ObDereferenceObject (DeviceObject);
+         return STATUS_OBJECT_NAME_COLLISION;
+      }
 
-      if (NT_SUCCESS(Status))
+      Status = ObpCaptureObjectAttributes(ObjectAttributes,
+                                          AccessMode,
+                                          NULL,
+                                          &ObjectCreateInfo,
+                                          &ObjectName);
+      if (!NT_SUCCESS(Status))
       {
-         Status = ObReferenceObjectByHandle(LocalHandle,
-                                     DesiredAccess,
-         NULL,
-         AccessMode,
-         (PVOID*)&DeviceObject,
-         NULL);
-         ZwClose(LocalHandle);
-  if (!NT_SUCCESS(Status))
-  {
-     return Status;
-  }
-         if (BODY_TO_HEADER(DeviceObject)->Type != IoDeviceObjectType)
-  {
-     ObDereferenceObject (DeviceObject);
-     return STATUS_OBJECT_NAME_COLLISION;
-  }
-         /* FIXME: wt... */
-         FileObject = IoCreateStreamFileObject(NULL, DeviceObject);
-         /* HACK */
-         FileObject->Flags |= FO_DIRECT_DEVICE_OPEN;
-         DPRINT("%wZ\n", ObjectAttributes->ObjectName);
-
-  ObDereferenceObject (DeviceObject);
+         ObDereferenceObject (DeviceObject);
+         return Status;
       }
+         
+      InitializeObjectAttributes(&tmpObjectAttributes,
+                                 NULL,
+                                 ObjectCreateInfo.Attributes & OBJ_INHERIT,
+                                 0,
+                                 NULL);
+      ObpReleaseCapturedAttributes(&ObjectCreateInfo);
+      if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
+
+      
+      /* FIXME: wt... */
+      Status = ObCreateObject(KernelMode,
+                              IoFileObjectType,
+                              &tmpObjectAttributes,
+                              KernelMode,
+                              NULL,
+                              sizeof(FILE_OBJECT),
+                              0,
+                              0,
+                              (PVOID*)&FileObject);
+
+   
+      /* Set File Object Data */
+      FileObject->DeviceObject = IoGetAttachedDevice(DeviceObject); 
+      FileObject->Vpb = FileObject->DeviceObject->Vpb;
+
+      /* HACK */
+      FileObject->Flags |= FO_DIRECT_DEVICE_OPEN;
+      DPRINT("%wZ\n", ObjectAttributes->ObjectName);
+
+      ObDereferenceObject (DeviceObject);
    }
 
 
    if (FileObject == NULL)
    {
       Status = ObCreateObject(AccessMode,
-         IoFileObjectType,
-         ObjectAttributes,
-         AccessMode,
-         NULL,
-         sizeof(FILE_OBJECT),
-         0,
-         0,
-         (PVOID*)&FileObject);
+                              IoFileObjectType,
+                              ObjectAttributes,
+                              AccessMode,
+                              NULL,
+                              sizeof(FILE_OBJECT),
+                              0,
+                              0,
+                              (PVOID*)&FileObject);
       if (!NT_SUCCESS(Status))
       {
- DPRINT("ObCreateObject() failed! (Status %lx)\n", Status);
- return Status;
        DPRINT("ObCreateObject() failed! (Status %lx)\n", Status);
        return Status;
       }
    }
    RtlMapGenericMask(&DesiredAccess,
-                      &BODY_TO_HEADER(FileObject)->Type->TypeInfo.GenericMapping);
+                     &BODY_TO_HEADER(FileObject)->Type->TypeInfo.GenericMapping);
 
    Status = ObInsertObject ((PVOID)FileObject,
-       NULL,
-       DesiredAccess,
-       0,
-       NULL,
-       &LocalHandle);
+                            NULL,
+                            DesiredAccess,
+                            0,
+                            NULL,
+                            &LocalHandle);
    if (!NT_SUCCESS(Status))
      {
- DPRINT("ObInsertObject() failed! (Status %lx)\n", Status);
- ObDereferenceObject (FileObject);
- return Status;
+       DPRINT("ObInsertObject() failed! (Status %lx)\n", Status);
+       ObMakeTemporaryObject(FileObject);
+       ObDereferenceObject (FileObject);
+       return Status;
      }
 
    if (CreateOptions & FILE_SYNCHRONOUS_IO_ALERT)
      {
- FileObject->Flags |= (FO_ALERTABLE_IO | FO_SYNCHRONOUS_IO);
      FileObject->Flags |= (FO_ALERTABLE_IO | FO_SYNCHRONOUS_IO);
      }
    if (CreateOptions & FILE_SYNCHRONOUS_IO_NONALERT)
      {
- FileObject->Flags |= FO_SYNCHRONOUS_IO;
      FileObject->Flags |= FO_SYNCHRONOUS_IO;
      }
 
    if (CreateOptions & FILE_NO_INTERMEDIATE_BUFFERING)
      FileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
 
+    /* 
+     * FIXME: We should get the access state from Ob once this function becomes
+     * a parse routine once the Ob is refactored.
+     */
+   SeCreateAccessState(&AccessState, &AuxData, FILE_ALL_ACCESS, NULL);
+
    SecurityContext.SecurityQos = NULL; /* ?? */
-   SecurityContext.AccessState = NULL; /* ?? */
+   SecurityContext.AccessState = &AccessState;
    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);
+   DPRINT("FileObject 0x%p\n", FileObject);
+   DPRINT("FileObject->DeviceObject 0x%p\n", FileObject->DeviceObject);
    /*
     * Create a new IRP to hand to
     * the FS driver: this may fail
@@ -949,14 +988,14 @@ IoCreateFile(OUT PHANDLE  FileHandle,
    Irp = IoAllocateIrp(FileObject->DeviceObject->StackSize, FALSE);
    if (Irp == NULL)
      {
- ZwClose(LocalHandle);
- return STATUS_UNSUCCESSFUL;
      ZwClose(LocalHandle);
      return STATUS_UNSUCCESSFUL;
      }
 
    //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();
@@ -967,7 +1006,7 @@ IoCreateFile(OUT PHANDLE  FileHandle,
     * Get the stack location for the new
     * IRP and prepare it.
     */
-   StackLoc = IoGetNextIrpStackLocation(Irp);
+   StackLoc = (PEXTENDED_IO_STACK_LOCATION)IoGetNextIrpStackLocation(Irp);
    StackLoc->MinorFunction = 0;
    StackLoc->Flags = (UCHAR)Options;
    StackLoc->Control = 0;
@@ -976,34 +1015,34 @@ IoCreateFile(OUT PHANDLE  FileHandle,
 
    switch (CreateFileType)
      {
- default:
- case CreateFileTypeNone:
-   StackLoc->MajorFunction = IRP_MJ_CREATE;
-   StackLoc->Parameters.Create.SecurityContext = &SecurityContext;
-   StackLoc->Parameters.Create.Options = (CreateOptions & FILE_VALID_OPTION_FLAGS);
-   StackLoc->Parameters.Create.Options |= (CreateDisposition << 24);
-   StackLoc->Parameters.Create.FileAttributes = (USHORT)FileAttributes;
-   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;
-   StackLoc->Parameters.CreatePipe.Options = (CreateOptions & FILE_VALID_OPTION_FLAGS);
-   StackLoc->Parameters.CreatePipe.Options |= (CreateDisposition << 24);
-   StackLoc->Parameters.CreatePipe.ShareAccess = (USHORT)ShareAccess;
-   StackLoc->Parameters.CreatePipe.Parameters = ExtraCreateParameters;
-   break;
-
- case CreateFileTypeMailslot:
-   StackLoc->MajorFunction = IRP_MJ_CREATE_MAILSLOT;
-   StackLoc->Parameters.CreateMailslot.SecurityContext = &SecurityContext;
-   StackLoc->Parameters.CreateMailslot.Options = (CreateOptions & FILE_VALID_OPTION_FLAGS);
-   StackLoc->Parameters.CreateMailslot.Options |= (CreateDisposition << 24);
-   StackLoc->Parameters.CreateMailslot.ShareAccess = (USHORT)ShareAccess;
-   StackLoc->Parameters.CreateMailslot.Parameters = ExtraCreateParameters;
-   break;
      default:
      case CreateFileTypeNone:
+         StackLoc->MajorFunction = IRP_MJ_CREATE;
+         StackLoc->Parameters.Create.SecurityContext = &SecurityContext;
+         StackLoc->Parameters.Create.Options = (CreateOptions & FILE_VALID_OPTION_FLAGS);
+         StackLoc->Parameters.Create.Options |= (CreateDisposition << 24);
+         StackLoc->Parameters.Create.FileAttributes = (USHORT)FileAttributes;
+         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;
+        StackLoc->Parameters.CreatePipe.Options = (CreateOptions & FILE_VALID_OPTION_FLAGS);
+        StackLoc->Parameters.CreatePipe.Options |= (CreateDisposition << 24);
+        StackLoc->Parameters.CreatePipe.ShareAccess = (USHORT)ShareAccess;
+        StackLoc->Parameters.CreatePipe.Parameters = ExtraCreateParameters;
+        break;
+
     case CreateFileTypeMailslot:
+        StackLoc->MajorFunction = IRP_MJ_CREATE_MAILSLOT;
+        StackLoc->Parameters.CreateMailslot.SecurityContext = &SecurityContext;
+        StackLoc->Parameters.CreateMailslot.Options = (CreateOptions & FILE_VALID_OPTION_FLAGS);
+        StackLoc->Parameters.CreateMailslot.Options |= (CreateDisposition << 24);
+        StackLoc->Parameters.CreateMailslot.ShareAccess = (USHORT)ShareAccess;
+        StackLoc->Parameters.CreateMailslot.Parameters = ExtraCreateParameters;
+        break;
      }
 
    /*
@@ -1017,33 +1056,32 @@ IoCreateFile(OUT PHANDLE  FileHandle,
    
    if (Status == STATUS_PENDING)
      {
- KeWaitForSingleObject(&FileObject->Event,
-         Executive,
-         AccessMode,
-         FALSE,
-         NULL);
Status = LocalIoStatusBlock.Status;
      KeWaitForSingleObject(&FileObject->Event,
+                             Executive,
+                             AccessMode,
+                             FALSE,
+                             NULL);
      Status = IoStatusBlock->Status;
      }
    if (!NT_SUCCESS(Status))
      {
- DPRINT("Failing create request with status %x\n", Status);
-        FileObject->DeviceObject = NULL;
-        FileObject->Vpb = NULL;
      DPRINT("Failing create request with status %x\n", Status);
+       FileObject->DeviceObject = NULL;
+       FileObject->Vpb = NULL;
 
- ZwClose(LocalHandle);
      ZwClose(LocalHandle);
      }
    else
      {
-  _SEH_TRY
-    {
-       *FileHandle = LocalHandle;
-       *IoStatusBlock = LocalIoStatusBlock;
-    }
-  _SEH_HANDLE
-    {
-       Status = _SEH_GetExceptionCode();
-    }
-  _SEH_END;
+       _SEH_TRY
+         {
+           *FileHandle = LocalHandle;
+         }
+       _SEH_HANDLE
+         {
+           Status = _SEH_GetExceptionCode();
+         }
+       _SEH_END;
      }
 
    /* cleanup EABuffer if captured */
@@ -1054,7 +1092,7 @@ IoCreateFile(OUT PHANDLE  FileHandle,
 
    ASSERT_IRQL(PASSIVE_LEVEL);
 
-   DPRINT("Finished IoCreateFile() (*FileHandle) %x\n", (*FileHandle));
+   DPRINT("Finished IoCreateFile() (*FileHandle) 0x%p\n", (*FileHandle));
 
    return Status;
 }
@@ -1118,7 +1156,7 @@ IoCreateStreamFileObject(PFILE_OBJECT FileObject,
        reason. These hacks need to be removed.
     */
 
-    DPRINT("IoCreateStreamFileObject(FileObject %x, DeviceObject %x)\n",
+    DPRINT("IoCreateStreamFileObject(FileObject 0x%p, DeviceObject 0x%p)\n",
             FileObject, DeviceObject);
     PAGED_CODE();
 
@@ -1140,7 +1178,7 @@ IoCreateStreamFileObject(PFILE_OBJECT FileObject,
 
     /* Choose Device Object */
     if (FileObject) DeviceObject = FileObject->DeviceObject;
-    DPRINT("DeviceObject %x\n", DeviceObject);
+    DPRINT("DeviceObject 0x%p\n", DeviceObject);
     
     /* HACK */
     DeviceObject = IoGetAttachedDevice(DeviceObject);
@@ -1244,7 +1282,7 @@ IoQueryFileInformation(IN PFILE_OBJECT FileObject,
                                         KernelMode);
     if (!NT_SUCCESS(Status)) return(Status);
 
-    DPRINT("FileObject %x\n", FileObject);
+    DPRINT("FileObject 0x%p\n", FileObject);
 
     /* Get the Device Object */
     DeviceObject = IoGetRelatedDeviceObject(FileObject);
@@ -1348,21 +1386,41 @@ STDCALL
 NtCancelIoFile(IN HANDLE FileHandle,
                OUT PIO_STATUS_BLOCK IoStatusBlock)
 {
-   NTSTATUS Status;
    PFILE_OBJECT FileObject;
    PETHREAD Thread;
-   PLIST_ENTRY IrpEntry;
    PIRP Irp;
    KIRQL OldIrql;
    BOOLEAN OurIrpsInList = FALSE;
    LARGE_INTEGER Interval;
+   KPROCESSOR_MODE PreviousMode;
+   NTSTATUS Status = STATUS_SUCCESS;
+
+   PAGED_CODE();
 
-   if ((ULONG_PTR)IoStatusBlock >= MmUserProbeAddress &&
-       KeGetPreviousMode() == UserMode)
-      return STATUS_ACCESS_VIOLATION;
+   PreviousMode = KeGetPreviousMode();
 
-   Status = ObReferenceObjectByHandle(FileHandle, 0, IoFileObjectType,
-                                      KeGetPreviousMode(), (PVOID*)&FileObject,
+   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;
@@ -1376,11 +1434,9 @@ NtCancelIoFile(IN HANDLE FileHandle,
     */
 
    Thread = PsGetCurrentThread();
-   for (IrpEntry = Thread->IrpList.Flink;
-        IrpEntry != &Thread->IrpList;
-        IrpEntry = IrpEntry->Flink)
+
+   LIST_FOR_EACH(Irp, &Thread->IrpList, IRP, ThreadListEntry)
    {
-      Irp = CONTAINING_RECORD(IrpEntry, IRP, ThreadListEntry);
       if (Irp->Tail.Overlay.OriginalFileObject == FileObject)
       {
          IoCancelIrp(Irp);
@@ -1408,11 +1464,8 @@ NtCancelIoFile(IN HANDLE FileHandle,
        * forever.
        */
 
-      for (IrpEntry = Thread->IrpList.Flink;
-           IrpEntry != &Thread->IrpList;
-           IrpEntry = IrpEntry->Flink)
+      LIST_FOR_EACH(Irp, &Thread->IrpList, IRP, ThreadListEntry)           
       {
-         Irp = CONTAINING_RECORD(IrpEntry, IRP, ThreadListEntry);
          if (Irp->Tail.Overlay.OriginalFileObject == FileObject)
          {
             OurIrpsInList = TRUE;
@@ -1504,24 +1557,40 @@ NtCreateMailslotFile(OUT PHANDLE FileHandle,
 {
     MAILSLOT_CREATE_PARAMETERS Buffer;
 
-    DPRINT("NtCreateMailslotFile(FileHandle %x, DesiredAccess %x, "
-           "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
-           FileHandle,DesiredAccess,ObjectAttributes,
-           ObjectAttributes->ObjectName->Buffer);
+    DPRINT("NtCreateMailslotFile(FileHandle 0x%p, DesiredAccess %x, "
+           "ObjectAttributes 0x%p)\n",
+           FileHandle,DesiredAccess,ObjectAttributes);
+
     PAGED_CODE();
 
     /* Check for Timeout */
-    if (TimeOut)
+    if (TimeOut != NULL)
     {
-        /* Enable it */
-        Buffer.TimeoutSpecified = TRUE;
+        if (KeGetPreviousMode() != KernelMode)
+        {
+            NTSTATUS Status = STATUS_SUCCESS;
 
-        /* FIXME: Add SEH */
-        Buffer.ReadTimeout = *TimeOut;
+            _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;
     }
     else
     {
-        /* No timeout */
         Buffer.TimeoutSpecified = FALSE;
     }
 
@@ -1565,26 +1634,40 @@ NtCreateNamedPipeFile(PHANDLE FileHandle,
 {
     NAMED_PIPE_CREATE_PARAMETERS Buffer;
 
-    DPRINT("NtCreateNamedPipeFile(FileHandle %x, DesiredAccess %x, "
-           "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
-            FileHandle,DesiredAccess,ObjectAttributes,
-            ObjectAttributes->ObjectName->Buffer);
+    DPRINT("NtCreateNamedPipeFile(FileHandle 0x%p, DesiredAccess %x, "
+           "ObjectAttributes 0x%p)\n",
+            FileHandle,DesiredAccess,ObjectAttributes);
+
     PAGED_CODE();
 
     /* Check for Timeout */
-    if (DefaultTimeout)
+    if (DefaultTimeout != NULL)
     {
-        /* Enable it */
-        Buffer.TimeoutSpecified = TRUE;
+        if (KeGetPreviousMode() != KernelMode)
+        {
+            NTSTATUS Status = STATUS_SUCCESS;
 
-        /* FIXME: Add SEH */
-        Buffer.DefaultTimeout = *DefaultTimeout;
+            _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;
     }
     else
-    {
-        /* No timeout */
         Buffer.TimeoutSpecified = FALSE;
-    }
 
     /* Set Settings */
     Buffer.NamedPipeType = NamedPipeType;
@@ -1698,6 +1781,8 @@ NTSTATUS
 STDCALL
 NtFlushWriteBuffer(VOID)
 {
+    PAGED_CODE();
+
     KeFlushWriteBuffer();
     return STATUS_SUCCESS;
 }
@@ -1720,20 +1805,56 @@ NtFlushBuffersFile(IN  HANDLE FileHandle,
     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)
@@ -1875,8 +1996,8 @@ NtNotifyChangeDirectoryFile(IN HANDLE FileHandle,
    Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
    if (Irp==NULL)
      {
- ObDereferenceObject(FileObject);
- return STATUS_UNSUCCESSFUL;
      ObDereferenceObject(FileObject);
      return STATUS_UNSUCCESSFUL;
      }
 
    if (Event == NULL)
@@ -1906,7 +2027,7 @@ NtNotifyChangeDirectoryFile(IN HANDLE FileHandle,
 
    if (WatchTree)
      {
- IoStack->Flags = SL_WATCH_TREE;
      IoStack->Flags = SL_WATCH_TREE;
      }
 
    IoStack->Parameters.NotifyDirectory.CompletionFilter = CompletionFilter;
@@ -1931,7 +2052,7 @@ NtLockFile(IN HANDLE FileHandle,
            OUT PIO_STATUS_BLOCK IoStatusBlock,
            IN PLARGE_INTEGER ByteOffset,
            IN PLARGE_INTEGER Length,
-           IN PULONG  Key,
+           IN ULONG  Key,
            IN BOOLEAN FailImmediately,
            IN BOOLEAN ExclusiveLock)
 {
@@ -1942,12 +2063,17 @@ NtLockFile(IN HANDLE FileHandle,
     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,
@@ -1958,12 +2084,41 @@ NtLockFile(IN HANDLE FileHandle,
                                        &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 */
@@ -2017,7 +2172,7 @@ NtLockFile(IN HANDLE FileHandle,
         ObDereferenceObject(FileObject);
         return STATUS_INSUFFICIENT_RESOURCES;
     }
-    *LocalLength = *Length;
+    *LocalLength = CapturedLength;
     
     /* Set up the IRP */
     Irp->RequestorMode = PreviousMode;
@@ -2034,8 +2189,8 @@ NtLockFile(IN HANDLE FileHandle,
     
     /* 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;
@@ -2123,21 +2278,84 @@ NtOpenFile(PHANDLE FileHandle,
 }
 
 NTSTATUS
-STDCALL
-NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
-                      OUT PFILE_BASIC_INFORMATION FileInformation)
+IopQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
+                       IN FILE_INFORMATION_CLASS FileInformationClass,
+                       OUT PVOID FileInformation)
 {
     IO_STATUS_BLOCK IoStatusBlock;
     HANDLE FileHandle;
     NTSTATUS Status;
+    KPROCESSOR_MODE AccessMode;
+    UNICODE_STRING ObjectName;
+    OBJECT_CREATE_INFORMATION ObjectCreateInfo;
+    OBJECT_ATTRIBUTES LocalObjectAttributes;
+    ULONG BufferSize;
+    union
+    {
+        FILE_BASIC_INFORMATION BasicInformation;
+        FILE_NETWORK_OPEN_INFORMATION NetworkOpenInformation;
+    }LocalFileInformation;
+
+    if (FileInformationClass == FileBasicInformation)
+    {
+        BufferSize = sizeof(FILE_BASIC_INFORMATION);
+    }
+    else if (FileInformationClass == FileNetworkOpenInformation)
+    {
+        BufferSize = sizeof(FILE_NETWORK_OPEN_INFORMATION);
+    }
+    else
+    {
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    AccessMode = ExGetPreviousMode();
+
+    if (AccessMode != KernelMode)
+    {
+        Status = STATUS_SUCCESS;
+        _SEH_TRY
+        {
+            ProbeForWrite(FileInformation,
+                          BufferSize,
+                          sizeof(ULONG));
+        }
+        _SEH_HANDLE
+        {
+            Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+        if (NT_SUCCESS(Status))
+        {
+            Status = ObpCaptureObjectAttributes(ObjectAttributes,
+                                                AccessMode,
+                                                NULL,
+                                                &ObjectCreateInfo,
+                                                &ObjectName);
+        }
+        if (!NT_SUCCESS(Status))
+        {
+            return Status;
+        }
+        InitializeObjectAttributes(&LocalObjectAttributes,
+                                   &ObjectName,
+                                   ObjectCreateInfo.Attributes,
+                                   ObjectCreateInfo.RootDirectory,
+                                   ObjectCreateInfo.SecurityDescriptor);
+    }
 
     /* Open the file */
     Status = ZwOpenFile(&FileHandle,
                         SYNCHRONIZE | FILE_READ_ATTRIBUTES,
-                        ObjectAttributes,
+                        AccessMode == KernelMode ? ObjectAttributes : &LocalObjectAttributes,
                         &IoStatusBlock,
-                        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+                        0,
                         FILE_SYNCHRONOUS_IO_NONALERT);
+    if (AccessMode != KernelMode)
+    {
+        ObpReleaseCapturedAttributes(&ObjectCreateInfo);
+        ExFreePool(ObjectName.Buffer);
+    }
     if (!NT_SUCCESS (Status))
     {
         DPRINT ("ZwOpenFile() failed (Status %lx)\n", Status);
@@ -2147,18 +2365,55 @@ NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
     /* Get file attributes */
     Status = ZwQueryInformationFile(FileHandle,
                                     &IoStatusBlock,
-                                    FileInformation,
-                                    sizeof(FILE_BASIC_INFORMATION),
-                                    FileBasicInformation);
+                                    AccessMode == KernelMode ? FileInformation : &LocalFileInformation,
+                                    BufferSize,
+                                    FileInformationClass);
     if (!NT_SUCCESS (Status))
     {
         DPRINT ("ZwQueryInformationFile() failed (Status %lx)\n", Status);
     }
-
     ZwClose(FileHandle);
+
+    if (NT_SUCCESS(Status) && AccessMode != KernelMode)
+    {
+        _SEH_TRY
+        {
+            memcpy(FileInformation, &LocalFileInformation, BufferSize);
+        }
+        _SEH_HANDLE
+        {
+            Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+    }
     return Status;
 }
 
+NTSTATUS
+STDCALL
+NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
+                      OUT PFILE_BASIC_INFORMATION FileInformation)
+{
+    return IopQueryAttributesFile(ObjectAttributes,
+                                  FileBasicInformation,
+                                  FileInformation);
+}
+
+static NTSTATUS NTAPI
+IopQueryDirectoryFileCompletion(IN PDEVICE_OBJECT DeviceObject,
+                               IN PIRP Irp,
+                               IN PVOID Context)
+{
+    ASSERT (Context);
+
+    DPRINT("IopQueryDirectoryFileCompletion was called for \'%wZ\'\n", Context);
+
+    ExFreePool(Context);
+
+    return STATUS_SUCCESS;
+}
+
+
 /*
  * @implemented
  *
@@ -2203,12 +2458,13 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
 {
     PIRP Irp;
     PDEVICE_OBJECT DeviceObject;
-    PFILE_OBJECT FileObject;
+    PFILE_OBJECT FileObject = NULL;
     PIO_STACK_LOCATION StackPtr;
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
     NTSTATUS Status = STATUS_SUCCESS;
     BOOLEAN LocalEvent = FALSE;
     PKEVENT Event = NULL;
+    PUNICODE_STRING SearchPattern = NULL;
 
     DPRINT("NtQueryDirectoryFile()\n");
     PAGED_CODE();
@@ -2224,6 +2480,24 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
             ProbeForWrite(FileInformation,
                           Length,
                           sizeof(ULONG));
+            if (FileName)
+            {
+                UNICODE_STRING CapturedFileName;
+
+                CapturedFileName = ProbeForReadUnicodeString(FileName);
+                ProbeForRead(CapturedFileName.Buffer,
+                             CapturedFileName.MaximumLength,
+                             1);
+                SearchPattern = ExAllocatePool(NonPagedPool, CapturedFileName.Length + sizeof(WCHAR) + sizeof(UNICODE_STRING));
+                if (SearchPattern == NULL)
+                {
+                    Status = STATUS_INSUFFICIENT_RESOURCES;
+                    _SEH_LEAVE;
+                }
+                SearchPattern->Buffer = (PWCHAR)((ULONG_PTR)SearchPattern + sizeof(UNICODE_STRING));
+                SearchPattern->MaximumLength = CapturedFileName.Length + sizeof(WCHAR);
+                RtlCopyUnicodeString(SearchPattern, &CapturedFileName);
+            }
         }
         _SEH_HANDLE
         {
@@ -2231,7 +2505,10 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
         }
         _SEH_END;
 
-        if(!NT_SUCCESS(Status)) return Status;
+        if(!NT_SUCCESS(Status)) 
+        {
+            goto Cleanup;
+        }
     }
 
     /* Get File Object */
@@ -2241,7 +2518,10 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
                                        PreviousMode,
                                        (PVOID *)&FileObject,
                                        NULL);
-    if (Status != STATUS_SUCCESS) return(Status);
+    if (!NT_SUCCESS(Status))
+    {
+       goto Cleanup;
+    }
 
     /* Get Event Object */
     if (PEvent)
@@ -2252,7 +2532,11 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
                                            PreviousMode,
                                            (PVOID *)&Event,
                                            NULL);
-        if (Status != STATUS_SUCCESS) return(Status);
+        if (!NT_SUCCESS(Status)) 
+        {
+            goto Cleanup;
+        }
+
         KeClearEvent(Event);
     }
 
@@ -2280,8 +2564,8 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
     /* Allocate the IRP */
     if (!(Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE)))
     {
-        ObDereferenceObject(FileObject);
-        return STATUS_INSUFFICIENT_RESOURCES;
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto Cleanup;
     }
 
     /* Set up the IRP */
@@ -2302,13 +2586,23 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
 
     /* Set Parameters */
     StackPtr->Parameters.QueryDirectory.FileInformationClass = FileInformationClass;
-    StackPtr->Parameters.QueryDirectory.FileName = FileName;
+    StackPtr->Parameters.QueryDirectory.FileName = SearchPattern ? SearchPattern : FileName;
     StackPtr->Parameters.QueryDirectory.FileIndex = 0;
     StackPtr->Parameters.QueryDirectory.Length = Length;
     StackPtr->Flags = 0;
     if (RestartScan) StackPtr->Flags = SL_RESTART_SCAN;
     if (ReturnSingleEntry) StackPtr->Flags |= SL_RETURN_SINGLE_ENTRY;
 
+    if (SearchPattern)
+    {
+        IoSetCompletionRoutine(Irp,
+                               IopQueryDirectoryFileCompletion,
+                              SearchPattern,
+                              TRUE,
+                              TRUE,
+                              TRUE);
+    }
+
     /* Call the Driver */
     Status = IoCallDriver(DeviceObject, Irp);
     if (Status == STATUS_PENDING)
@@ -2324,6 +2618,23 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
         }
     }
 
+
+    return Status;
+
+Cleanup:
+    if (FileObject != NULL)
+    {
+        ObDereferenceObject(FileObject);
+    }
+    if (Event != NULL)
+    {
+        ObDereferenceObject(Event);
+    }
+    if (SearchPattern != NULL)
+    {
+        ExFreePool(SearchPattern);
+    }
+
     /* Return the Status */
     return Status;
 }
@@ -2351,36 +2662,9 @@ STDCALL
 NtQueryFullAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
                           OUT PFILE_NETWORK_OPEN_INFORMATION FileInformation)
 {
-    IO_STATUS_BLOCK IoStatusBlock;
-    HANDLE FileHandle;
-    NTSTATUS Status;
-
-    /* Open the file */
-    Status = ZwOpenFile(&FileHandle,
-                        SYNCHRONIZE | FILE_READ_ATTRIBUTES,
-                        ObjectAttributes,
-                        &IoStatusBlock,
-                        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
-                        FILE_SYNCHRONOUS_IO_NONALERT);
-    if (!NT_SUCCESS (Status))
-    {
-        DPRINT ("ZwOpenFile() failed (Status %lx)\n", Status);
-        return Status;
-    }
-
-    /* Get file attributes */
-    Status = ZwQueryInformationFile(FileHandle,
-                                    &IoStatusBlock,
-                                    FileInformation,
-                                    sizeof(FILE_NETWORK_OPEN_INFORMATION),
-                                    FileNetworkOpenInformation);
-    if (!NT_SUCCESS (Status))
-    {
-        DPRINT ("ZwQueryInformationFile() failed (Status %lx)\n", Status);
-    }
-
-    ZwClose (FileHandle);
-    return Status;
+  return IopQueryAttributesFile(ObjectAttributes,
+                                FileNetworkOpenInformation,
+                                FileInformation);
 }
 
 /*
@@ -2407,7 +2691,7 @@ NtQueryInformationFile(HANDLE FileHandle,
     ASSERT(IoStatusBlock != NULL);
     ASSERT(FileInformation != NULL);
 
-    DPRINT("NtQueryInformationFile(Handle %x StatBlk %x FileInfo %x Length %d "
+    DPRINT("NtQueryInformationFile(Handle 0x%p StatBlk 0x%p FileInfo 0x%p Length %d "
            "Class %d)\n", FileHandle, IoStatusBlock, FileInformation,
             Length, FileInformationClass);
 
@@ -2434,11 +2718,6 @@ NtQueryInformationFile(HANDLE FileHandle,
                 Failed = TRUE;
             break;
 
-        case FileAlignmentInformation:
-            if (!(FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING))
-                Failed = TRUE;
-            break;
-
         default:
             break;
     }
@@ -2450,7 +2729,31 @@ NtQueryInformationFile(HANDLE FileHandle,
         return STATUS_ACCESS_DENIED;
     }
 
-    DPRINT("FileObject %x\n", FileObject);
+    if (FileInformationClass == FilePositionInformation)
+    {
+       if (Length < sizeof(FILE_POSITION_INFORMATION))
+       {
+          Status = STATUS_BUFFER_OVERFLOW;
+       }
+       else
+       {
+          _SEH_TRY
+          {
+             ((PFILE_POSITION_INFORMATION)FileInformation)->CurrentByteOffset = FileObject->CurrentByteOffset;
+             IoStatusBlock->Information = sizeof(FILE_POSITION_INFORMATION);
+             Status = IoStatusBlock->Status = STATUS_SUCCESS;
+          }
+          _SEH_HANDLE
+          {
+             Status = _SEH_GetExceptionCode();
+          }
+          _SEH_END;
+       }
+       ObDereferenceObject(FileObject);
+       return Status;
+    }
+
+    DPRINT("FileObject 0x%p\n", FileObject);
 
     /* Check if this is a direct open or not */
     if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
@@ -2462,6 +2765,30 @@ NtQueryInformationFile(HANDLE FileHandle,
         DeviceObject = IoGetRelatedDeviceObject(FileObject);
     }
 
+    if (FileInformationClass == FileAlignmentInformation)
+    {
+       if (Length < sizeof(FILE_ALIGNMENT_INFORMATION))
+       {
+          Status = STATUS_BUFFER_OVERFLOW;
+       }
+       else
+       {
+          _SEH_TRY
+          {
+             ((PFILE_ALIGNMENT_INFORMATION)FileInformation)->AlignmentRequirement = DeviceObject->AlignmentRequirement;
+             IoStatusBlock->Information = sizeof(FILE_ALIGNMENT_INFORMATION);
+             Status = IoStatusBlock->Status = STATUS_SUCCESS;
+          }
+          _SEH_HANDLE
+          {
+             Status = _SEH_GetExceptionCode();
+          }
+          _SEH_END;
+       }
+       ObDereferenceObject(FileObject);
+       return Status;
+    }
+
     /* Check if we should use Sync IO or not */
     if (FileObject->Flags & FO_SYNCHRONOUS_IO)
     {
@@ -2581,7 +2908,7 @@ NtReadFile(IN HANDLE FileHandle,
            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;
@@ -2589,14 +2916,19 @@ NtReadFile(IN HANDLE FileHandle,
     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 %x Buffer %x Length %x ByteOffset %x, "
-           "IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset,
+    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)
@@ -2606,11 +2938,14 @@ NtReadFile(IN HANDLE FileHandle,
             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
         {
@@ -2620,6 +2955,13 @@ NtReadFile(IN HANDLE FileHandle,
 
         if(!NT_SUCCESS(Status)) return Status;
     }
+    else
+    {
+        if (ByteOffset != NULL)
+        {
+            CapturedByteOffset = *ByteOffset;
+        }
+    }
 
     /* Get File Object */
     Status = ObReferenceObjectByHandle(FileHandle,
@@ -2631,9 +2973,9 @@ NtReadFile(IN HANDLE FileHandle,
     if (!NT_SUCCESS(Status)) return Status;
 
     /* Check the Byte Offset */
-    if (!ByteOffset ||
-        (ByteOffset->u.LowPart == FILE_USE_FILE_POINTER_POSITION &&
-         ByteOffset->u.HighPart == 0xffffffff))
+    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))
@@ -2644,7 +2986,7 @@ NtReadFile(IN HANDLE FileHandle,
         }
 
         /* Use the Current Byte OFfset */
-        ByteOffset = &FileObject->CurrentByteOffset;
+        CapturedByteOffset = FileObject->CurrentByteOffset;
     }
 
     /* Check for event */
@@ -2693,7 +3035,7 @@ NtReadFile(IN HANDLE FileHandle,
                                            DeviceObject,
                                            Buffer,
                                            Length,
-                                           ByteOffset,
+                                           &CapturedByteOffset,
                                            EventObject,
                                            IoStatusBlock);
         if (Irp == NULL)
@@ -2815,13 +3157,45 @@ NtSetInformationFile(HANDLE FileHandle,
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
     BOOLEAN Failed = FALSE;
 
-    ASSERT(IoStatusBlock != NULL);
-    ASSERT(FileInformation != NULL);
-
-    DPRINT("NtSetInformationFile(Handle %x StatBlk %x FileInfo %x Length %d "
+    DPRINT("NtSetInformationFile(Handle 0x%p StatBlk 0x%p FileInfo 0x%p Length %d "
            "Class %d)\n", FileHandle, IoStatusBlock, FileInformation,
             Length, FileInformationClass);
 
+    if (PreviousMode != KernelMode)
+    {
+        _SEH_TRY
+        {
+            if (IoStatusBlock != NULL)
+            {
+                ProbeForWrite(IoStatusBlock,
+                              sizeof(IO_STATUS_BLOCK),
+                              sizeof(ULONG));
+            }
+            
+            if (Length != 0)
+            {
+                ProbeForRead(FileInformation,
+                             Length,
+                             1);
+            }
+        }
+        _SEH_HANDLE
+        {
+            Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+        
+        if (!NT_SUCCESS(Status))
+        {
+            return Status;
+        }
+    }
+    else
+    {
+        ASSERT(IoStatusBlock != NULL);
+        ASSERT(FileInformation != NULL);
+    }
+
     /* Get the file object from the file handle */
     Status = ObReferenceObjectByHandle(FileHandle,
                                        0,
@@ -2866,7 +3240,31 @@ NtSetInformationFile(HANDLE FileHandle,
         return STATUS_ACCESS_DENIED;
     }
 
-    DPRINT("FileObject %x\n", FileObject);
+    DPRINT("FileObject 0x%p\n", FileObject);
+
+    if (FileInformationClass == FilePositionInformation)
+    {
+       if (Length < sizeof(FILE_POSITION_INFORMATION))
+       {
+          Status = STATUS_BUFFER_OVERFLOW;
+       }
+       else
+       {
+          _SEH_TRY
+          {
+             FileObject->CurrentByteOffset = ((PFILE_POSITION_INFORMATION)FileInformation)->CurrentByteOffset;
+             IoStatusBlock->Information = 0;
+             Status = IoStatusBlock->Status = STATUS_SUCCESS;
+          }
+          _SEH_HANDLE
+          {
+             Status = _SEH_GetExceptionCode();
+          }
+          _SEH_END;
+       }
+       ObDereferenceObject(FileObject);
+       return Status;
+    }
 
     /* FIXME: Later, we can implement a lot of stuff here and avoid a driver call */
     /* Handle IO Completion Port quickly */
@@ -2875,34 +3273,57 @@ NtSetInformationFile(HANDLE FileHandle,
         PVOID Queue;
         PFILE_COMPLETION_INFORMATION CompletionInfo = FileInformation;
         PIO_COMPLETION_CONTEXT Context;
-
-        if (Length < sizeof(FILE_COMPLETION_INFORMATION))
+        
+        if (FileObject->Flags & FO_SYNCHRONOUS_IO || FileObject->CompletionContext != NULL)
         {
-            Status = STATUS_INFO_LENGTH_MISMATCH;
+            Status = STATUS_INVALID_PARAMETER;
         }
         else
         {
-            /* Reference the Port */
-            Status = ObReferenceObjectByHandle(CompletionInfo->IoCompletionHandle,
-                                               IO_COMPLETION_MODIFY_STATE,
-                                               IoCompletionType,
-                                               PreviousMode,
-                                               (PVOID*)&Queue,
-                                               NULL);
-            if (NT_SUCCESS(Status))
+            if (Length < sizeof(FILE_COMPLETION_INFORMATION))
+            {
+                Status = STATUS_INFO_LENGTH_MISMATCH;
+            }
+            else
             {
-                /* Allocate the Context */
-                Context = ExAllocatePoolWithTag(PagedPool,
-                                                sizeof(IO_COMPLETION_CONTEXT),
-                                                TAG('I', 'o', 'C', 'p'));
-
-                /* Set the Data */
-                Context->Key = CompletionInfo->CompletionKey;
-                Context->Port = Queue;
-                FileObject->CompletionContext = Context;
-
-                /* Dereference the Port now */
-                ObDereferenceObject(Queue);
+                /* Reference the Port */
+                Status = ObReferenceObjectByHandle(CompletionInfo->Port, /* FIXME - protect with SEH! */
+                                                   IO_COMPLETION_MODIFY_STATE,
+                                                   IoCompletionType,
+                                                   PreviousMode,
+                                                   (PVOID*)&Queue,
+                                                   NULL);
+                if (NT_SUCCESS(Status))
+                {
+                    /* Allocate the Context */
+                    Context = ExAllocatePoolWithTag(PagedPool,
+                                                    sizeof(IO_COMPLETION_CONTEXT),
+                                                    TAG('I', 'o', 'C', 'p'));
+
+                    if (Context != NULL)
+                    {
+                        /* Set the Data */
+                        Context->Key = CompletionInfo->Key; /* FIXME - protect with SEH! */
+                        Context->Port = Queue;
+                        
+                        if (InterlockedCompareExchangePointer(&FileObject->CompletionContext,
+                                                              Context,
+                                                              NULL) != NULL)
+                        {
+                            /* someone else set the completion port in the
+                               meanwhile, fail */
+                            ExFreePool(Context);
+                            ObDereferenceObject(Queue);
+                            Status = STATUS_INVALID_PARAMETER;
+                        }
+                    }
+                    else
+                    {
+                        /* Dereference the Port now */
+                        ObDereferenceObject(Queue);
+                        Status = STATUS_INSUFFICIENT_RESOURCES;
+                    }
+                }
             }
         }
 
@@ -2946,13 +3367,43 @@ NtSetInformationFile(HANDLE FileHandle,
                                                                   Length,
                                                                   TAG_SYSB)))
     {
-        IoFreeIrp(Irp);
-        ObDereferenceObject(FileObject);
-        return STATUS_INSUFFICIENT_RESOURCES;
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto failfreeirp;
     }
 
     /* Copy the data inside */
-    MmSafeCopyFromUser(Irp->AssociatedIrp.SystemBuffer, FileInformation, Length);
+    if (PreviousMode != KernelMode)
+    {
+        _SEH_TRY
+        {
+            /* no need to probe again */
+            RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
+                          FileInformation,
+                          Length);
+        }
+        _SEH_HANDLE
+        {
+            Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+        
+        if (!NT_SUCCESS(Status))
+        {
+            ExFreePoolWithTag(Irp->AssociatedIrp.SystemBuffer,
+                              TAG_SYSB);
+            Irp->AssociatedIrp.SystemBuffer = NULL;
+failfreeirp:
+            IoFreeIrp(Irp);
+            ObDereferenceObject(FileObject);
+            return Status;
+        }
+    }
+    else
+    {
+        RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
+                      FileInformation,
+                      Length);
+    }
 
     /* Set up the IRP */
     Irp->Tail.Overlay.OriginalFileObject = FileObject;
@@ -2983,7 +3434,15 @@ NtSetInformationFile(HANDLE FileHandle,
                                   PreviousMode,
                                   FileObject->Flags & FO_ALERTABLE_IO,
                                   NULL);
-            Status = IoStatusBlock->Status;
+            _SEH_TRY
+            {
+                Status = IoStatusBlock->Status;
+            }
+            _SEH_HANDLE
+            {
+                Status = _SEH_GetExceptionCode();
+            }
+            _SEH_END;
         }
         else
         {
@@ -2992,7 +3451,15 @@ NtSetInformationFile(HANDLE FileHandle,
                                   PreviousMode,
                                   FileObject->Flags & FO_ALERTABLE_IO,
                                   NULL);
-            Status = FileObject->FinalStatus;
+            _SEH_TRY
+            {
+                Status = FileObject->FinalStatus;
+            }
+            _SEH_HANDLE
+            {
+                Status = _SEH_GetExceptionCode();
+            }
+            _SEH_END;
         }
     }
 
@@ -3007,7 +3474,7 @@ NTSTATUS
 STDCALL
 NtSetQuotaInformationFile(HANDLE FileHandle,
                           PIO_STATUS_BLOCK IoStatusBlock,
-                          PFILE_USER_QUOTA_INFORMATION Buffer,
+                          PVOID Buffer,
                           ULONG BufferLength)
 {
     UNIMPLEMENTED;
@@ -3023,7 +3490,7 @@ NtUnlockFile(IN  HANDLE FileHandle,
              OUT PIO_STATUS_BLOCK IoStatusBlock,
              IN  PLARGE_INTEGER ByteOffset,
              IN  PLARGE_INTEGER Length,
-             OUT PULONG Key OPTIONAL)
+             IN  ULONG Key OPTIONAL)
 {
     PFILE_OBJECT FileObject = NULL;
     PLARGE_INTEGER LocalLength = NULL;
@@ -3032,12 +3499,17 @@ NtUnlockFile(IN  HANDLE FileHandle,
     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,
@@ -3048,12 +3520,41 @@ NtUnlockFile(IN  HANDLE FileHandle,
                                        &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 */
@@ -3096,7 +3597,7 @@ NtUnlockFile(IN  HANDLE FileHandle,
         ObDereferenceObject(FileObject);
         return STATUS_INSUFFICIENT_RESOURCES;
     }
-    *LocalLength = *Length;
+    *LocalLength = CapturedLength;
     
     /* Set up the IRP */
     Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;
@@ -3114,8 +3615,8 @@ NtUnlockFile(IN  HANDLE FileHandle,
     
     /* 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);
@@ -3171,34 +3672,49 @@ NtWriteFile (IN HANDLE FileHandle,
              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 %x Buffer %x Length %x ByteOffset %x, "
-            "IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset,
+    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
         {
@@ -3208,6 +3724,17 @@ NtWriteFile (IN HANDLE FileHandle,
 
         if(!NT_SUCCESS(Status)) return Status;
     }
+    else
+    {
+        if (ByteOffset != NULL)
+        {
+            CapturedByteOffset = *ByteOffset;
+        }
+        if (Key != NULL)
+        {
+            CapturedKey = *Key;
+        }
+    }
 
     /* Get File Object */
     Status = ObReferenceObjectByHandle(FileHandle,
@@ -3215,24 +3742,29 @@ NtWriteFile (IN HANDLE FileHandle,
                                        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 == 0xffffffff))
+        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))
@@ -3243,10 +3775,11 @@ NtWriteFile (IN HANDLE FileHandle,
             }
 
             /* 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))
@@ -3257,8 +3790,8 @@ NtWriteFile (IN HANDLE FileHandle,
         }
 
         /* 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 */
@@ -3307,7 +3840,7 @@ NtWriteFile (IN HANDLE FileHandle,
                                            DeviceObject,
                                            Buffer,
                                            Length,
-                                           ByteOffset,
+                                           &CapturedByteOffset,
                                            EventObject,
                                            IoStatusBlock);
         if (Irp == NULL)
@@ -3348,7 +3881,7 @@ NtWriteFile (IN HANDLE FileHandle,
     /* 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 */