Properly setup the I/O stack location in IopSecurityFile.
[reactos.git] / reactos / ntoskrnl / io / file.c
index 6f04adc..0c21f63 100644 (file)
 
 /* GLOBALS *******************************************************************/
 
-#define TAG_SYSB        TAG('S', 'Y', 'S', 'B')
-#define TAG_LOCK        TAG('F','l','c','k')
-#define TAG_FILE_NAME   TAG('F', 'N', 'A', 'M')
-
 extern GENERIC_MAPPING IopFileMapping;
 
 NTSTATUS
@@ -47,17 +43,17 @@ STDCALL
 IopCreateFile(PVOID ObjectBody,
               PVOID Parent,
               PWSTR RemainingPath,
-              POBJECT_ATTRIBUTES ObjectAttributes)
+              POBJECT_CREATE_INFORMATION ObjectCreateInfo)
 {
   PDEVICE_OBJECT DeviceObject;
   PFILE_OBJECT FileObject = (PFILE_OBJECT) 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)
     {
@@ -67,25 +63,25 @@ IopCreateFile(PVOID ObjectBody,
       return(STATUS_SUCCESS);
     }
 
-  ParentObjectType = BODY_TO_HEADER(Parent)->ObjectType;
+  ParentObjectType = BODY_TO_HEADER(Parent)->Type;
 
   if (ParentObjectType != IoDeviceObjectType &&
       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)->Name,
-        BODY_TO_HEADER(Parent)->ObjectType->TypeName.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);
     }
 
@@ -93,75 +89,74 @@ 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);
+            }
+          RtlpCreateUnicodeString(&(FileObject->FileName),
+                                  RemainingPath, NonPagedPool);
+        }
     }
   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);
+                              RemainingPath, NonPagedPool);
     }
 
   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;
 
@@ -278,7 +273,7 @@ IopSecurityFile(PVOID ObjectBody,
         if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
         {
             /* Get the Device Object */
-            DPRINT1("here\n");
+            DPRINT("here\n");
             DeviceObject = IoGetAttachedDevice(FileObject->DeviceObject);
 
             /* Assign the Security Descriptor */
@@ -329,6 +324,7 @@ IopSecurityFile(PVOID ObjectBody,
 
     /* Set Stack Parameters */
     StackPtr = IoGetNextIrpStackLocation(Irp);
+    StackPtr->MajorFunction = MajorFunction;
     StackPtr->FileObject = FileObject;
 
     /* Set Parameters */
@@ -344,6 +340,8 @@ IopSecurityFile(PVOID ObjectBody,
         StackPtr->Parameters.SetSecurity.SecurityDescriptor = SecurityDescriptor;
     }
 
+    ObReferenceObject(FileObject);
+
     /* Call the Driver */
     Status = IoCallDriver(FileObject->DeviceObject, Irp);
 
@@ -402,7 +400,7 @@ IopQueryNameFile(PVOID ObjectBody,
                  ULONG Length,
                  PULONG ReturnLength)
 {
-    PVOID LocalInfo;
+    POBJECT_NAME_INFORMATION LocalInfo;
     PFILE_OBJECT FileObject;
     ULONG LocalReturnLength;
     NTSTATUS Status;
@@ -431,7 +429,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,
@@ -511,6 +509,130 @@ IopCloseFile(PVOID ObjectBody,
     IoFreeIrp(Irp);
 }
 
+NTSTATUS 
+STDCALL
+IopDeviceFsIoControl(IN HANDLE DeviceHandle,
+                     IN HANDLE Event OPTIONAL,
+                     IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL,
+                     IN PVOID UserApcContext OPTIONAL,
+                     OUT PIO_STATUS_BLOCK IoStatusBlock,
+                     IN ULONG IoControlCode,
+                     IN PVOID InputBuffer,
+                     IN ULONG InputBufferLength OPTIONAL,
+                     OUT PVOID OutputBuffer,
+                     IN ULONG OutputBufferLength OPTIONAL,
+                     BOOLEAN IsDevIoCtl)
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+    PFILE_OBJECT FileObject;
+    PDEVICE_OBJECT DeviceObject;
+    PIRP Irp;
+    PIO_STACK_LOCATION StackPtr;
+    PKEVENT EventObject = NULL;
+    BOOLEAN LocalEvent = FALSE;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+
+    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);
+
+    if (IoStatusBlock == NULL) return STATUS_ACCESS_VIOLATION;
+
+    /* Check granted access against the access rights from IoContolCode */
+    Status = ObReferenceObjectByHandle(DeviceHandle,
+                                       (IoControlCode >> 14) & 0x3,
+                                       IoFileObjectType,
+                                       PreviousMode,
+                                       (PVOID *) &FileObject,
+                                       NULL);
+    if (!NT_SUCCESS(Status)) return Status;
+
+    /* Check for an event */
+    if (Event)
+    {
+        /* Reference it */
+        Status = ObReferenceObjectByHandle(Event,
+                                           EVENT_MODIFY_STATE,
+                                           ExEventObjectType,
+                                           PreviousMode,
+                                           (PVOID*)&EventObject,
+                                           NULL);
+        if (!NT_SUCCESS(Status))
+        {
+            ObDereferenceObject (FileObject);
+            return Status;
+        }
+        
+        /* Clear it */
+        KeClearEvent(EventObject);
+    }
+
+    /* Check if this is a direct open or not */
+    if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
+    {
+        DeviceObject = IoGetAttachedDevice(FileObject->DeviceObject);
+    }
+    else
+    {
+        DeviceObject = IoGetRelatedDeviceObject(FileObject);
+    }
+
+    /* Check if we should use Sync IO or not */
+    if (FileObject->Flags & FO_SYNCHRONOUS_IO)
+    {
+        /* Use File Object event */
+        KeClearEvent(&FileObject->Event);
+    }
+    else
+    {
+        /* Use local event */
+        LocalEvent = TRUE;
+    }
+
+    /* Build the IRP */
+    Irp = IoBuildDeviceIoControlRequest(IoControlCode,
+                                        DeviceObject,
+                                        InputBuffer,
+                                        InputBufferLength,
+                                        OutputBuffer,
+                                        OutputBufferLength,
+                                        FALSE,
+                                        EventObject,
+                                        IoStatusBlock);
+
+    /* Set some extra settings */
+    Irp->Tail.Overlay.OriginalFileObject = FileObject;
+    Irp->RequestorMode = PreviousMode;
+    Irp->Overlay.AsynchronousParameters.UserApcRoutine = UserApcRoutine;
+    Irp->Overlay.AsynchronousParameters.UserApcContext = UserApcContext;
+    StackPtr = IoGetNextIrpStackLocation(Irp);
+    StackPtr->FileObject = FileObject;
+    StackPtr->MajorFunction = IsDevIoCtl ? 
+                              IRP_MJ_DEVICE_CONTROL : IRP_MJ_FILE_SYSTEM_CONTROL;
+    
+    /* Call the Driver */
+    Status = IoCallDriver(DeviceObject, Irp);
+    if (Status == STATUS_PENDING)
+    {
+        if (!LocalEvent)
+        {
+            KeWaitForSingleObject(&FileObject->Event,
+                                  Executive,
+                                  PreviousMode,
+                                  FileObject->Flags & FO_ALERTABLE_IO,
+                                  NULL);
+            Status = FileObject->FinalStatus;
+        }
+    }
+
+    /* Return the Status */
+    return Status;
+}
+                      
 /* FUNCTIONS *****************************************************************/
 
 /*
@@ -637,10 +759,10 @@ IoCreateFile(OUT PHANDLE  FileHandle,
    PVOID                SystemEaBuffer = NULL;
    NTSTATUS  Status = STATUS_SUCCESS;
 
-   DPRINT("IoCreateFile(FileHandle %x, DesiredAccess %x, "
-   "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
-   FileHandle,DesiredAccess,ObjectAttributes,
-   ObjectAttributes->ObjectName->Buffer);
+   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);
 
@@ -723,81 +845,82 @@ IoCreateFile(OUT PHANDLE  FileHandle,
      DPRINT1("FIXME: IO_CHECK_CREATE_PARAMETERS not yet supported!\n");
    }
 
-   if (CreateDisposition == FILE_OPEN ||
-       CreateDisposition == FILE_OPEN_IF)
+   Status = ObOpenObjectByName(ObjectAttributes,
+                               NULL,
+                               NULL,
+                               AccessMode,
+                               DesiredAccess,
+                               NULL,
+                               &LocalHandle);
+
+   if (NT_SUCCESS(Status))
    {
-      Status = ObOpenObjectByName(ObjectAttributes,
-                           NULL,
-      NULL,
-      AccessMode,
-      DesiredAccess,
-      NULL,
-      &LocalHandle);
-      if (NT_SUCCESS(Status))
+      Status = ObReferenceObjectByHandle(LocalHandle,
+                                         DesiredAccess,
+                                         NULL,
+                                         AccessMode,
+                                         (PVOID*)&DeviceObject,
+                                         NULL);
+      ZwClose(LocalHandle);
+      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)->ObjectType != IoDeviceObjectType)
-  {
-     ObDereferenceObject (DeviceObject);
-     return STATUS_OBJECT_NAME_COLLISION;
-  }
-         /* FIXME: wt... */
-         FileObject = IoCreateStreamFileObject(NULL, DeviceObject);
-  ObDereferenceObject (DeviceObject);
+         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);
    }
 
 
    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)->ObjectType->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);
      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)
@@ -811,8 +934,8 @@ IoCreateFile(OUT PHANDLE  FileHandle,
    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
@@ -821,8 +944,8 @@ 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
@@ -848,34 +971,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;
      }
 
    /*
@@ -886,36 +1009,36 @@ IoCreateFile(OUT PHANDLE  FileHandle,
     */
    Status = IofCallDriver(FileObject->DeviceObject, Irp );
    DPRINT("Status :%x\n", Status);
-
+   
    if (Status == STATUS_PENDING)
      {
- KeWaitForSingleObject(&FileObject->Event,
-         Executive,
-         AccessMode,
-         FALSE,
-         NULL);
- Status = LocalIoStatusBlock.Status;
      KeWaitForSingleObject(&FileObject->Event,
+                             Executive,
+                             AccessMode,
+                             FALSE,
+                             NULL);
      Status = LocalIoStatusBlock.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;
+           *IoStatusBlock = LocalIoStatusBlock;
+         }
+       _SEH_HANDLE
+         {
+           Status = _SEH_GetExceptionCode();
+         }
+       _SEH_END;
      }
 
    /* cleanup EABuffer if captured */
@@ -926,7 +1049,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;
 }
@@ -990,7 +1113,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();
 
@@ -1012,7 +1135,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);
@@ -1021,9 +1144,7 @@ IoCreateStreamFileObject(PFILE_OBJECT FileObject,
     CreatedFileObject->DeviceObject = DeviceObject; 
     CreatedFileObject->Vpb = DeviceObject->Vpb;
     CreatedFileObject->Type = IO_TYPE_FILE;
-    /* HACK */
-    CreatedFileObject->Flags |= FO_DIRECT_DEVICE_OPEN;
-    //CreatedFileObject->Flags = FO_STREAM_FILE;
+    CreatedFileObject->Flags |= FO_STREAM_FILE;
 
     /* Initialize Lock and Event */
     KeInitializeEvent(&CreatedFileObject->Event, NotificationEvent, FALSE);
@@ -1118,7 +1239,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);
@@ -1231,7 +1352,7 @@ NtCancelIoFile(IN HANDLE FileHandle,
    BOOLEAN OurIrpsInList = FALSE;
    LARGE_INTEGER Interval;
 
-   if ((ULONG_PTR)IoStatusBlock >= MmUserProbeAddress &&
+   if ((ULONG_PTR)IoStatusBlock >= (ULONG_PTR)MmUserProbeAddress &&
        KeGetPreviousMode() == UserMode)
       return STATUS_ACCESS_VIOLATION;
 
@@ -1378,8 +1499,8 @@ NtCreateMailslotFile(OUT PHANDLE FileHandle,
 {
     MAILSLOT_CREATE_PARAMETERS Buffer;
 
-    DPRINT("NtCreateMailslotFile(FileHandle %x, DesiredAccess %x, "
-           "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
+    DPRINT("NtCreateMailslotFile(FileHandle 0x%p, DesiredAccess %x, "
+           "ObjectAttributes 0x%p ObjectAttributes->ObjectName->Buffer %S)\n",
            FileHandle,DesiredAccess,ObjectAttributes,
            ObjectAttributes->ObjectName->Buffer);
     PAGED_CODE();
@@ -1439,8 +1560,8 @@ NtCreateNamedPipeFile(PHANDLE FileHandle,
 {
     NAMED_PIPE_CREATE_PARAMETERS Buffer;
 
-    DPRINT("NtCreateNamedPipeFile(FileHandle %x, DesiredAccess %x, "
-           "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
+    DPRINT("NtCreateNamedPipeFile(FileHandle 0x%p, DesiredAccess %x, "
+           "ObjectAttributes 0x%p ObjectAttributes->ObjectName->Buffer %S)\n",
             FileHandle,DesiredAccess,ObjectAttributes,
             ObjectAttributes->ObjectName->Buffer);
     PAGED_CODE();
@@ -1509,6 +1630,65 @@ NtDeleteFile(IN POBJECT_ATTRIBUTES ObjectAttributes)
     return(STATUS_NOT_IMPLEMENTED);
 }
 
+/*
+ * @implemented
+ */
+NTSTATUS 
+STDCALL
+NtDeviceIoControlFile(IN HANDLE DeviceHandle,
+                      IN HANDLE Event OPTIONAL,
+                      IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL,
+                      IN PVOID UserApcContext OPTIONAL,
+                      OUT PIO_STATUS_BLOCK IoStatusBlock,
+                      IN ULONG IoControlCode,
+                      IN PVOID InputBuffer,
+                      IN ULONG InputBufferLength OPTIONAL,
+                      OUT PVOID OutputBuffer,
+                      IN ULONG OutputBufferLength OPTIONAL)
+{
+    /* Call the Generic Function */
+    return IopDeviceFsIoControl(DeviceHandle,
+                                Event,
+                                UserApcRoutine,
+                                UserApcContext,
+                                IoStatusBlock,
+                                IoControlCode,
+                                InputBuffer,
+                                InputBufferLength,
+                                OutputBuffer,
+                                OutputBufferLength,
+                                TRUE);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS 
+STDCALL
+NtFsControlFile(IN HANDLE DeviceHandle,
+                IN HANDLE Event OPTIONAL,
+                IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL,
+                IN PVOID UserApcContext OPTIONAL,
+                OUT PIO_STATUS_BLOCK IoStatusBlock,
+                IN ULONG IoControlCode,
+                IN PVOID InputBuffer,
+                IN ULONG InputBufferLength OPTIONAL,
+                OUT PVOID OutputBuffer,
+                IN ULONG OutputBufferLength OPTIONAL)
+{
+    return IopDeviceFsIoControl(DeviceHandle,
+                                Event,
+                                UserApcRoutine,
+                                UserApcContext,
+                                IoStatusBlock,
+                                IoControlCode,
+                                InputBuffer,
+                                InputBufferLength,
+                                OutputBuffer,
+                                OutputBufferLength,
+                                FALSE);
+}
+
 NTSTATUS
 STDCALL
 NtFlushWriteBuffer(VOID)
@@ -1690,8 +1870,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)
@@ -1721,7 +1901,7 @@ NtNotifyChangeDirectoryFile(IN HANDLE FileHandle,
 
    if (WatchTree)
      {
- IoStack->Flags = SL_WATCH_TREE;
      IoStack->Flags = SL_WATCH_TREE;
      }
 
    IoStack->Parameters.NotifyDirectory.CompletionFilter = CompletionFilter;
@@ -2222,7 +2402,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);
 
@@ -2265,7 +2445,7 @@ NtQueryInformationFile(HANDLE FileHandle,
         return STATUS_ACCESS_DENIED;
     }
 
-    DPRINT("FileObject %x\n", FileObject);
+    DPRINT("FileObject 0x%p\n", FileObject);
 
     /* Check if this is a direct open or not */
     if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
@@ -2408,8 +2588,8 @@ NtReadFile(IN HANDLE FileHandle,
     BOOLEAN LocalEvent = FALSE;
     PKEVENT EventObject = NULL;
 
-    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();
 
@@ -2448,7 +2628,7 @@ NtReadFile(IN HANDLE FileHandle,
     /* Check the Byte Offset */
     if (!ByteOffset ||
         (ByteOffset->u.LowPart == FILE_USE_FILE_POINTER_POSITION &&
-         ByteOffset->u.HighPart == 0xffffffff))
+         ByteOffset->u.HighPart == -1))
     {
         /* a valid ByteOffset is required if asynch. op. */
         if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
@@ -2536,7 +2716,12 @@ NtReadFile(IN HANDLE FileHandle,
     Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
     Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
     Irp->Flags |= IRP_READ_OPERATION;
+#if 0
+    /* FIXME:
+     *    Vfat doesn't handle non cached files correctly.
+     */     
     if (FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING) Irp->Flags |= IRP_NOCACHE;
+#endif      
 
     /* Setup Stack Data */
     StackPtr = IoGetNextIrpStackLocation(Irp);
@@ -2625,13 +2810,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,
@@ -2676,7 +2893,7 @@ NtSetInformationFile(HANDLE FileHandle,
         return STATUS_ACCESS_DENIED;
     }
 
-    DPRINT("FileObject %x\n", FileObject);
+    DPRINT("FileObject 0x%p\n", FileObject);
 
     /* FIXME: Later, we can implement a lot of stuff here and avoid a driver call */
     /* Handle IO Completion Port quickly */
@@ -2693,7 +2910,7 @@ NtSetInformationFile(HANDLE FileHandle,
         else
         {
             /* Reference the Port */
-            Status = ObReferenceObjectByHandle(CompletionInfo->IoCompletionHandle,
+            Status = ObReferenceObjectByHandle(CompletionInfo->Port,
                                                IO_COMPLETION_MODIFY_STATE,
                                                IoCompletionType,
                                                PreviousMode,
@@ -2707,7 +2924,7 @@ NtSetInformationFile(HANDLE FileHandle,
                                                 TAG('I', 'o', 'C', 'p'));
 
                 /* Set the Data */
-                Context->Key = CompletionInfo->CompletionKey;
+                Context->Key = CompletionInfo->Key;
                 Context->Port = Queue;
                 FileObject->CompletionContext = Context;
 
@@ -2756,13 +2973,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;
@@ -2793,7 +3040,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
         {
@@ -2802,7 +3057,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;
         }
     }
 
@@ -2817,7 +3080,7 @@ NTSTATUS
 STDCALL
 NtSetQuotaInformationFile(HANDLE FileHandle,
                           PIO_STATUS_BLOCK IoStatusBlock,
-                          PFILE_USER_QUOTA_INFORMATION Buffer,
+                          PFILE_QUOTA_INFORMATION Buffer,
                           ULONG BufferLength)
 {
     UNIMPLEMENTED;
@@ -2991,8 +3254,8 @@ NtWriteFile (IN HANDLE FileHandle,
     BOOLEAN LocalEvent = FALSE;
     PKEVENT EventObject = NULL;
 
-    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);
 
     /* Validate User-Mode Buffers */
@@ -3042,7 +3305,7 @@ NtWriteFile (IN HANDLE FileHandle,
         /* Check the Byte Offset */
         if (!ByteOffset ||
             (ByteOffset->u.LowPart == FILE_USE_FILE_POINTER_POSITION &&
-             ByteOffset->u.HighPart == 0xffffffff))
+             ByteOffset->u.HighPart == -1))
         {
             /* a valid ByteOffset is required if asynch. op. */
             if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
@@ -3114,7 +3377,7 @@ NtWriteFile (IN HANDLE FileHandle,
     _SEH_TRY
     {
         Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
-                                           FileObject->DeviceObject,
+                                           DeviceObject,
                                            Buffer,
                                            Length,
                                            ByteOffset,
@@ -3148,7 +3411,12 @@ NtWriteFile (IN HANDLE FileHandle,
     Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
     Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
     Irp->Flags |= IRP_WRITE_OPERATION;
+#if 0    
+    /* FIXME:
+     *    Vfat doesn't handle non cached files correctly.
+     */     
     if (FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING) Irp->Flags |= IRP_NOCACHE;
+#endif    
 
     /* Setup Stack Data */
     StackPtr = IoGetNextIrpStackLocation(Irp);