Fixed a typo.
[reactos.git] / reactos / ntoskrnl / io / create.c
index ba37f16..af9fdd1 100644 (file)
-/*
+/* $Id: create.c,v 1.54 2002/04/01 22:18:01 hbirr Exp $
+ *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/io/create.c
  * PURPOSE:         Handling file create/open apis
- * PROGRAMMER:      David Welch (welch@cwcom.net) 
+ * PROGRAMMER:      David Welch (welch@cwcom.net)
  * UPDATE HISTORY:
  *                  24/05/98: Created
  */
 
 /* INCLUDES ***************************************************************/
 
-#include <wchar.h>
 #include <ddk/ntddk.h>
 #include <internal/ob.h>
 #include <internal/io.h>
 #include <internal/id.h>
-#include <internal/string.h>
+#include <internal/pool.h>
 
 #define NDEBUG
 #include <internal/debug.h>
 
+/* GLOBALS *******************************************************************/
+
+#define TAG_FILE_NAME     TAG('F', 'N', 'A', 'M')
+
 /* FUNCTIONS *************************************************************/
 
-NTSTATUS
-STDCALL
-NtDeleteFile (
-       IN      POBJECT_ATTRIBUTES      ObjectAttributes
-       )
+/**********************************************************************
+ * NAME                                                        EXPORTED
+ *     NtDeleteFile@4
+ *     
+ * DESCRIPTION
+ *     
+ * ARGUMENTS
+ *     ObjectAttributes
+ *             ?
+ *
+ * RETURN VALUE
+ *
+ * REVISIONS
+ * 
+ */
+NTSTATUS STDCALL
+NtDeleteFile(IN POBJECT_ATTRIBUTES ObjectAttributes)
 {
-       UNIMPLEMENTED;
+   UNIMPLEMENTED;
 }
 
 
-NTSTATUS IopCreateFile(PVOID ObjectBody,
-                      PVOID Parent,
-                      PWSTR RemainingPath,
-                      POBJECT_ATTRIBUTES ObjectAttributes)
+/**********************************************************************
+ * NAME                                                        INTERNAL
+ *     IopCreateFile
+ *     
+ * DESCRIPTION
+ *     
+ * ARGUMENTS
+ *             
+ * RETURN VALUE
+ *
+ * REVISIONS
+ * 
+ */
+NTSTATUS STDCALL
+IopCreateFile(PVOID                    ObjectBody,
+             PVOID                     Parent,
+             PWSTR                     RemainingPath,
+             POBJECT_ATTRIBUTES        ObjectAttributes)
 {
-   PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)Parent;
-   PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
-   NTSTATUS Status;
+   PDEVICE_OBJECT      DeviceObject = (PDEVICE_OBJECT) Parent;
+   PFILE_OBJECT        FileObject = (PFILE_OBJECT) ObjectBody;
+   NTSTATUS    Status;
    
-   DPRINT("IopCreateFile(ObjectBody %x, Parent %x, RemainingPath %w)\n",
-         ObjectBody,Parent,RemainingPath);
+   DPRINT("IopCreateFile(ObjectBody %x, Parent %x, RemainingPath %S)\n",
+         ObjectBody,
+         Parent,
+         RemainingPath);
    
-   if (DeviceObject == NULL)
+   if (NULL == DeviceObject)
      {
-       return(STATUS_SUCCESS);
+       /* This is probably an attempt to create a meta fileobject (eg. for FAT)
+          for the cache manager, so return STATUS_SUCCESS */
+       DPRINT("DeviceObject was NULL\n");
+       return (STATUS_SUCCESS);
      }
-   
-   Status = ObReferenceObjectByPointer(DeviceObject,
-                                      STANDARD_RIGHTS_REQUIRED,
-                                      IoDeviceType,
-                                      UserMode);
-   if (Status != STATUS_SUCCESS)
+   if (IoDeviceObjectType != BODY_TO_HEADER(Parent)->ObjectType)
+     {
+       CPRINT("Parent is a %S which is not a device type\n",
+              BODY_TO_HEADER(Parent)->ObjectType->TypeName.Buffer);
+       return (STATUS_UNSUCCESSFUL);
+     }
+   Status = ObReferenceObjectByPointer (DeviceObject,
+                                       STANDARD_RIGHTS_REQUIRED,
+                                       IoDeviceObjectType,
+                                       UserMode);
+   if (STATUS_SUCCESS != Status)
      {
-       CHECKPOINT;
-       return(Status);
+       CHECKPOINT1;
+       return (Status);
      }
    
-   DeviceObject = IoGetAttachedDevice(DeviceObject);
+   DeviceObject = IoGetAttachedDevice (DeviceObject);
    
-   DPRINT("DeviceObject %x\n",DeviceObject);
+   DPRINT("DeviceObject %x\n", DeviceObject);
    
-   if (RemainingPath == NULL)
+   if (NULL == RemainingPath)
      {
        FileObject->Flags = FileObject->Flags | FO_DIRECT_DEVICE_OPEN;
-       FileObject->FileName.Buffer = ExAllocatePool(NonPagedPool,
-                                  (ObjectAttributes->ObjectName->Length+1)*2);
+       FileObject->FileName.Buffer = 
+         ExAllocatePoolWithTag(NonPagedPool,
+                               (ObjectAttributes->ObjectName->Length+1)*sizeof(WCHAR),
+                               TAG_FILE_NAME);
        FileObject->FileName.Length = ObjectAttributes->ObjectName->Length;
        FileObject->FileName.MaximumLength = 
-          ObjectAttributes->ObjectName->MaximumLength;
+         ObjectAttributes->ObjectName->MaximumLength;
        RtlCopyUnicodeString(&(FileObject->FileName),
                             ObjectAttributes->ObjectName);
      }
    else
      {
-       if (DeviceObject->DeviceType != FILE_DEVICE_FILE_SYSTEM &&
-           DeviceObject->DeviceType != FILE_DEVICE_DISK)
+       if ((DeviceObject->DeviceType != FILE_DEVICE_FILE_SYSTEM)
+           && (DeviceObject->DeviceType != FILE_DEVICE_DISK)
+           && (DeviceObject->DeviceType != FILE_DEVICE_NETWORK)
+           && (DeviceObject->DeviceType != FILE_DEVICE_NAMED_PIPE)
+           && (DeviceObject->DeviceType != FILE_DEVICE_MAILSLOT))
          {
-            return(STATUS_UNSUCCESSFUL);
+            CPRINT ("Device was wrong type\n");
+            return (STATUS_UNSUCCESSFUL);
          }
-       if (!(DeviceObject->Vpb->Flags & VPB_MOUNTED))
+
+       if (DeviceObject->DeviceType != FILE_DEVICE_NETWORK
+           && (DeviceObject->DeviceType != FILE_DEVICE_NAMED_PIPE)
+           && (DeviceObject->DeviceType != FILE_DEVICE_MAILSLOT))
          {
-            Status = IoTryToMountStorageDevice(DeviceObject);
-            if (Status!=STATUS_SUCCESS)
+            if (!(DeviceObject->Vpb->Flags & VPB_MOUNTED))
               {
-                 return(Status);
+                 DPRINT("Trying to mount storage device\n");
+                 Status = IoTryToMountStorageDevice (DeviceObject);
+                 DPRINT("Status %x\n", Status);
+                 if (!NT_SUCCESS(Status))
+                   {
+                      CPRINT("Failed to mount storage device (status %x)\n",
+                             Status);
+                      return (Status);
+                   }
+                 DeviceObject = IoGetAttachedDevice(DeviceObject);
               }
-            DeviceObject = IoGetAttachedDevice(DeviceObject);
          }
-       RtlInitUnicodeString(&(FileObject->FileName),wcsdup(RemainingPath));
+       RtlCreateUnicodeString(&(FileObject->FileName),
+                              RemainingPath);
      }
-   DPRINT("FileObject->FileName.Buffer %w\n",FileObject->FileName.Buffer);
+   DPRINT("FileObject->FileName.Buffer %S\n",
+         FileObject->FileName.Buffer);
    FileObject->DeviceObject = DeviceObject;
+   DPRINT("FileObject %x DeviceObject %x\n",
+         FileObject,
+         DeviceObject);
    FileObject->Vpb = DeviceObject->Vpb;
-   FileObject->Type = ID_FILE_OBJECT;
-     
-   return(STATUS_SUCCESS);
+   FileObject->Type = InternalFileType;
+   
+   return (STATUS_SUCCESS);
 }
 
-PFILE_OBJECT IoCreateStreamFileObject(PFILE_OBJECT FileObject,
-                                     PDEVICE_OBJECT DeviceObject)
+
+/**********************************************************************
+ * NAME                                                        EXPORTED
+ *     IoCreateStreamFileObject@8
+ *     
+ * DESCRIPTION
+ *     
+ * ARGUMENTS
+ *     FileObject
+ *             ?
+ *             
+ *     DeviceObject
+ *             ?
+ *             
+ * RETURN VALUE
+ *
+ * NOTE
+ *     
+ * REVISIONS
+ * 
+ */
+PFILE_OBJECT STDCALL
+IoCreateStreamFileObject(PFILE_OBJECT FileObject,
+                        PDEVICE_OBJECT DeviceObject)
 {
-   HANDLE FileHandle;
-   PFILE_OBJECT CreatedFileObject;
-   
-   DbgPrint("IoCreateStreamFileObject(FileObject %x, DeviceObject %x)\n",
-           FileObject, DeviceObject);
-   
-   assert_irql(PASSIVE_LEVEL);
-   
-   CreatedFileObject = ObCreateObject(&FileHandle,
-                                     STANDARD_RIGHTS_REQUIRED,
-                                     NULL,
-                                     IoFileType);
-   if (CreatedFileObject == NULL)
-     {
-       return(NULL);
-     }
-   
-   if (FileObject != NULL)
-     {
-       DeviceObject = FileObject->DeviceObject;
-     }
-   DeviceObject = IoGetAttachedDevice(DeviceObject);
-   CreatedFileObject->DeviceObject = DeviceObject;
-   CreatedFileObject->Vpb = DeviceObject->Vpb;
-   CreatedFileObject->Type = ID_FILE_OBJECT;   
-   CreatedFileObject->Flags = CreatedFileObject->Flags | FO_DIRECT_DEVICE_OPEN;
-   
-   ZwClose(FileHandle);
+  HANDLE               FileHandle;
+  PFILE_OBJECT CreatedFileObject;
+  NTSTATUS Status;
+
+  DPRINT("IoCreateStreamFileObject(FileObject %x, DeviceObject %x)\n",
+          FileObject, DeviceObject);
    
-   return(CreatedFileObject);
+  assert_irql (PASSIVE_LEVEL);
+
+  Status = ObCreateObject (&FileHandle,
+                          STANDARD_RIGHTS_REQUIRED,
+                          NULL,
+                          IoFileObjectType,
+                          (PVOID*)&CreatedFileObject);
+  if (!NT_SUCCESS(Status))
+    {
+      DPRINT("Could not create FileObject\n");
+      return (NULL);
+    }
+  
+  if (FileObject != NULL)
+    {
+      DeviceObject = FileObject->DeviceObject;
+    }
+  DeviceObject = IoGetAttachedDevice(DeviceObject);
+
+  DPRINT("DeviceObject %x\n", DeviceObject);
+
+  CreatedFileObject->DeviceObject = DeviceObject;
+  CreatedFileObject->Vpb = DeviceObject->Vpb;
+  CreatedFileObject->Type = InternalFileType;
+  CreatedFileObject->Flags |= FO_DIRECT_DEVICE_OPEN;
+  
+  ZwClose (FileHandle);
+  
+  return (CreatedFileObject);
 }
 
-NTSTATUS
-STDCALL
-NtCreateFile (
-       PHANDLE                 FileHandle,
-       ACCESS_MASK             DesiredAccess,
-       POBJECT_ATTRIBUTES      ObjectAttributes,
-       PIO_STATUS_BLOCK        IoStatusBlock,
-       PLARGE_INTEGER          AllocateSize,
-       ULONG                   FileAttributes,
-       ULONG                   ShareAccess,
-       ULONG                   CreateDisposition,
-       ULONG                   CreateOptions,
-       PVOID                   EaBuffer,
-       ULONG                   EaLength
-       )
-/*
- * FUNCTION: Either causes a new file or directory to be created, or it opens
- * an existing file, device, directory or volume, giving the caller a handle
- * for the file object. This handle can be used by subsequent calls to
- * manipulate data within the file or the file object's state of attributes.
- * ARGUMENTS:
- *        FileHandle (OUT) = Points to a variable which receives the file
- *                           handle on return
- *        DesiredAccess = Desired access to the file
- *        ObjectAttributes = Structure describing the file
- *        IoStatusBlock (OUT) = Receives information about the operation on
- *                              return
- *        AllocationSize = Initial size of the file in bytes
- *        FileAttributes = Attributes to create the file with
- *        ShareAccess = Type of shared access the caller would like to the file
- *        CreateDisposition = Specifies what to do, depending on whether the
- *                            file already exists
- *        CreateOptions = Options for creating a new file
- *        EaBuffer = Undocumented
- *        EaLength = Undocumented
- * RETURNS: Status
+
+/**********************************************************************
+ * NAME                                                        EXPORTED
+ *     IoCreateFile@56
+ *     
+ * DESCRIPTION
+ *     Either causes a new file or directory to be created, or it
+ *     opens an existing file, device, directory or volume, giving
+ *     the caller a handle for the file object. This handle can be
+ *     used by subsequent calls to manipulate data within the file
+ *     or the file object's state of attributes.
+ *     
+ * ARGUMENTS
+ *     FileHandle (OUT)
+ *             Points to a variable which receives the file handle
+ *             on return;
+ *             
+ *     DesiredAccess
+ *             Desired access to the file;
+ *             
+ *     ObjectAttributes
+ *             Structure describing the file;
+ *             
+ *     IoStatusBlock (OUT)
+ *             Receives information about the operation on return;
+ *             
+ *     AllocationSize [OPTIONAL]
+ *             Initial size of the file in bytes;
+ *             
+ *     FileAttributes
+ *             Attributes to create the file with;
+ *             
+ *     ShareAccess
+ *             Type of shared access the caller would like to the
+ *             file;
+ *             
+ *     CreateDisposition
+ *             Specifies what to do, depending on whether the
+ *             file already exists;
+ *             
+ *     CreateOptions
+ *             Options for creating a new file;
+ *             
+ *     EaBuffer [OPTIONAL]
+ *             Undocumented;
+ *             
+ *     EaLength
+ *             Undocumented;
+ *             
+ *     CreateFileType
+ *             Type of file (normal, named pipe, mailslot) to create;
+ *             
+ *     ExtraCreateParameters [OPTIONAL]
+ *             Additional creation data for named pipe and mailsots;
+ *             
+ *     Options
+ *             Undocumented.
+ *             
+ * RETURN VALUE
+ *     Status
+ *
+ * NOTE
+ *     Prototype taken from Bo Branten's ntifs.h v15.
+ *     Description taken from old NtCreateFile's which is
+ *     now a wrapper of this call.
+ *     
+ * REVISIONS
+ * 
  */
+NTSTATUS STDCALL
+IoCreateFile(OUT       PHANDLE                 FileHandle,
+            IN ACCESS_MASK             DesiredAccess,
+            IN POBJECT_ATTRIBUTES      ObjectAttributes,
+            OUT        PIO_STATUS_BLOCK        IoStatusBlock,
+            IN PLARGE_INTEGER          AllocationSize          OPTIONAL,
+            IN ULONG                   FileAttributes,
+            IN ULONG                   ShareAccess,
+            IN ULONG                   CreateDisposition,
+            IN ULONG                   CreateOptions,
+            IN PVOID                   EaBuffer                OPTIONAL,
+            IN ULONG                   EaLength,
+            IN CREATE_FILE_TYPE        CreateFileType,
+            IN PVOID                   ExtraCreateParameters   OPTIONAL,
+            IN ULONG                   Options)
 {
-   PFILE_OBJECT FileObject;
-   NTSTATUS Status;
-   PIRP Irp;
-   KEVENT Event;
-   PIO_STACK_LOCATION StackLoc;
+   PFILE_OBJECT                FileObject;
+   NTSTATUS            Status;
+   PIRP                        Irp;
+   KEVENT              Event;
+   PIO_STACK_LOCATION  StackLoc;
+   IO_STATUS_BLOCK      IoSB;
+   IO_SECURITY_CONTEXT  SecurityContext;
    
-   DPRINT("NtCreateFile(FileHandle %x, DesiredAccess %x, "
-           "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %w)\n",
-           FileHandle,DesiredAccess,ObjectAttributes,
-           ObjectAttributes->ObjectName->Buffer);   
+   DPRINT("IoCreateFile(FileHandle %x, DesiredAccess %x, "
+         "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
+         FileHandle,DesiredAccess,ObjectAttributes,
+         ObjectAttributes->ObjectName->Buffer);
    
    assert_irql(PASSIVE_LEVEL);
    
-   *FileHandle=0;
+   *FileHandle = 0;
 
-   FileObject = ObCreateObject(FileHandle,
-                              DesiredAccess,
-                              ObjectAttributes,
-                              IoFileType);
-   if (FileObject == NULL)
+   Status = ObCreateObject(FileHandle,
+                          DesiredAccess,
+                          ObjectAttributes,
+                          IoFileObjectType,
+                          (PVOID*)&FileObject);
+   if (!NT_SUCCESS(Status))
      {
-       return(STATUS_UNSUCCESSFUL);
+       DPRINT("ObCreateObject() failed!\n");
+       return (Status);
      }
-   
    if (CreateOptions & FILE_SYNCHRONOUS_IO_ALERT)
      {
-       FileObject->Flags = FileObject->Flags | FO_ALERTABLE_IO;
-       FileObject->Flags = FileObject->Flags | FO_SYNCHRONOUS_IO;
+       FileObject->Flags |= (FO_ALERTABLE_IO | FO_SYNCHRONOUS_IO);
      }
    if (CreateOptions & FILE_SYNCHRONOUS_IO_NONALERT)
      {
-       FileObject->Flags = FileObject->Flags | FO_SYNCHRONOUS_IO;
+       FileObject->Flags |= FO_SYNCHRONOUS_IO;
      }
-      
+
+   if( CreateOptions & FILE_NO_INTERMEDIATE_BUFFERING )
+     FileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
+
+   SecurityContext.SecurityQos = NULL; /* ?? */
+   SecurityContext.AccessState = NULL; /* ?? */
+   SecurityContext.DesiredAccess = DesiredAccess;
+   SecurityContext.FullCreateOptions = 0; /* ?? */
+   
+   KeInitializeEvent(&FileObject->Lock, NotificationEvent, TRUE);
    KeInitializeEvent(&Event, NotificationEvent, FALSE);
    
+   DPRINT("FileObject %x\n", FileObject);
+   DPRINT("FileObject->DeviceObject %x\n", FileObject->DeviceObject);
+   /*
+    * Create a new IRP to hand to
+    * the FS driver: this may fail
+    * due to resource shortage.
+    */
    Irp = IoAllocateIrp(FileObject->DeviceObject->StackSize, FALSE);
-   if (Irp==NULL)
+   if (Irp == NULL)
      {
-       return(STATUS_UNSUCCESSFUL);
+       ZwClose(*FileHandle);
+       return (STATUS_UNSUCCESSFUL);
      }
+     
+   Irp->UserIosb = &IoSB;   //return iostatus
+   Irp->AssociatedIrp.SystemBuffer = EaBuffer;
+   Irp->Tail.Overlay.AuxiliaryBuffer = (PCHAR)ExtraCreateParameters;
+   Irp->Tail.Overlay.Thread = PsGetCurrentThread();
+   Irp->UserEvent = &Event;
    
+   /*
+    * Get the stack location for the new
+    * IRP and prepare it.
+    */
    StackLoc = IoGetNextIrpStackLocation(Irp);
-   StackLoc->MajorFunction = IRP_MJ_CREATE;
+   switch (CreateFileType)
+     {
+       default:
+       case CreateFileTypeNone:
+         StackLoc->MajorFunction = IRP_MJ_CREATE;
+         break;
+       
+       case CreateFileTypeNamedPipe:
+         StackLoc->MajorFunction = IRP_MJ_CREATE_NAMED_PIPE;
+         break;
+
+       case CreateFileTypeMailslot:
+         StackLoc->MajorFunction = IRP_MJ_CREATE_MAILSLOT;
+         break;
+     }
    StackLoc->MinorFunction = 0;
-   StackLoc->Flags = 0;
+   StackLoc->Flags = Options;
    StackLoc->Control = 0;
    StackLoc->DeviceObject = FileObject->DeviceObject;
    StackLoc->FileObject = FileObject;
-   StackLoc->Parameters.Create.Options = CreateOptions&FILE_VALID_OPTION_FLAGS;
-   StackLoc->Parameters.Create.Options |= CreateDisposition<<24;
+   StackLoc->Parameters.Create.SecurityContext = &SecurityContext;
+   StackLoc->Parameters.Create.Options = (CreateOptions & FILE_VALID_OPTION_FLAGS);
+   StackLoc->Parameters.Create.Options |= (CreateDisposition << 24);
+   StackLoc->Parameters.Create.FileAttributes = FileAttributes;
+   StackLoc->Parameters.Create.ShareAccess = ShareAccess;
+   StackLoc->Parameters.Create.EaLength = EaLength;
+   
+   /*
+    * Now call the driver and 
+    * possibly wait if it can
+    * not complete the request
+    * immediately.
+    */
+   Status = IofCallDriver(FileObject->DeviceObject, Irp );
    
-   Status = IoCallDriver(FileObject->DeviceObject,Irp);
    if (Status == STATUS_PENDING)
      {
-       KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL);
-       Status = IoStatusBlock->Status;
+       KeWaitForSingleObject(&Event,
+                             Executive,
+                             KernelMode,
+                             FALSE,
+                             NULL);
+       Status = IoSB.Status;
      }
-   
    if (!NT_SUCCESS(Status))
      {
-       DPRINT("Failing create request with status %x\n",Status);
+       DPRINT("Failing create request with status %x\n", Status);
        ZwClose(*FileHandle);
-       (*FileHandle) = 0;
      }
-   
+   if (IoStatusBlock)
+     {
+       *IoStatusBlock = IoSB;
+     }
    assert_irql(PASSIVE_LEVEL);
-   DPRINT("Finished NtCreateFile() (*FileHandle) %x\n",(*FileHandle));
-   return(Status);
+
+   DPRINT("Finished IoCreateFile() (*FileHandle) %x\n", (*FileHandle));
+
+   return (Status);
 }
 
 
-NTSTATUS
-STDCALL
-NtOpenFile (
-       PHANDLE                 FileHandle,
-       ACCESS_MASK             DesiredAccess,
-       POBJECT_ATTRIBUTES      ObjectAttributes,
-       PIO_STATUS_BLOCK        IoStatusBlock,
-       ULONG                   ShareAccess,
-       ULONG                   OpenOptions
-       )
-/*
- * FUNCTION: Opens a file (simpler than ZwCreateFile)
- * ARGUMENTS:
- *       FileHandle (OUT) = Variable that receives the file handle on return
- *       DesiredAccess = Access desired by the caller to the file
- *       ObjectAttributes = Structue describing the file to be opened
- *       IoStatusBlock (OUT) = Receives details about the result of the
- *                             operation
- *       ShareAccess = Type of shared access the caller requires
- *       OpenOptions = Options for the file open
- * RETURNS: Status
- * NOTE: Undocumented
+/**********************************************************************
+ * NAME                                                        EXPORTED
+ *     NtCreateFile@44
+ * 
+ * DESCRIPTION
+ *     Entry point to call IoCreateFile with
+ *     default parameters.
+ *
+ * ARGUMENTS
+ *     See IoCreateFile.
+ * 
+ * RETURN VALUE
+ *     See IoCreateFile.
+ *
+ * REVISIONS
+ *     2000-03-25 (ea)
+ *             Code originally in NtCreateFile moved in IoCreateFile.
  */
+NTSTATUS STDCALL
+NtCreateFile(PHANDLE FileHandle,
+            ACCESS_MASK DesiredAccess,
+            POBJECT_ATTRIBUTES ObjectAttributes,
+            PIO_STATUS_BLOCK IoStatusBlock,
+            PLARGE_INTEGER AllocateSize,
+            ULONG FileAttributes,
+            ULONG ShareAccess,
+            ULONG CreateDisposition,
+            ULONG CreateOptions,
+            PVOID EaBuffer,
+            ULONG EaLength)
 {
-   return(ZwCreateFile(
-               FileHandle,
-               DesiredAccess,
-               ObjectAttributes,
-               IoStatusBlock,
-               NULL,
-               0,
-               ShareAccess,
-               FILE_OPEN,
-               OpenOptions,
-               NULL,
-               0));
+   return IoCreateFile(FileHandle,
+                      DesiredAccess,
+                      ObjectAttributes,
+                      IoStatusBlock,
+                      AllocateSize,
+                      FileAttributes,
+                      ShareAccess,
+                      CreateDisposition,
+                      CreateOptions,
+                      EaBuffer,
+                      EaLength,
+                      CreateFileTypeNone,
+                      NULL,
+                      0);
 }
 
 
+/**********************************************************************
+ * NAME                                                        EXPORTED
+ *     NtOpenFile@24
+ *     
+ * DESCRIPTION
+ *     Opens an existing file (simpler than NtCreateFile).
+ *
+ * ARGUMENTS
+ *     FileHandle (OUT)
+ *             Variable that receives the file handle on return;
+ *             
+ *     DesiredAccess
+ *             Access desired by the caller to the file;
+ *             
+ *     ObjectAttributes
+ *             Structue describing the file to be opened;
+ *             
+ *     IoStatusBlock (OUT)
+ *             Receives details about the result of the
+ *             operation;
+ *             
+ *     ShareAccess
+ *             Type of shared access the caller requires;
+ *             
+ *     OpenOptions
+ *             Options for the file open.
+ *
+ * RETURN VALUE
+ *     Status.
+ *     
+ * NOTE
+ *     Undocumented.
+ */
+NTSTATUS STDCALL
+NtOpenFile(PHANDLE FileHandle,
+          ACCESS_MASK DesiredAccess,
+          POBJECT_ATTRIBUTES ObjectAttributes,
+          PIO_STATUS_BLOCK IoStatusBlock,
+          ULONG ShareAccess,
+          ULONG OpenOptions)
+{
+   return IoCreateFile(FileHandle,
+                      DesiredAccess,
+                      ObjectAttributes,
+                      IoStatusBlock,
+                      NULL,
+                      0,
+                      ShareAccess,
+                      FILE_OPEN,
+                      OpenOptions,
+                      NULL,
+                      0,
+                      CreateFileTypeNone,
+                      NULL,
+                      0);
+}
+
+/* EOF */