Fixed a typo.
[reactos.git] / reactos / ntoskrnl / io / create.c
index 248ade4..af9fdd1 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: create.c,v 1.35 2001/01/08 02:14:05 dwelch Exp $
+/* $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
  */
 #include <internal/ob.h>
 #include <internal/io.h>
 #include <internal/id.h>
+#include <internal/pool.h>
 
 #define NDEBUG
 #include <internal/debug.h>
 
+/* GLOBALS *******************************************************************/
+
+#define TAG_FILE_NAME     TAG('F', 'N', 'A', 'M')
+
 /* FUNCTIONS *************************************************************/
 
 /**********************************************************************
@@ -37,7 +42,7 @@
  * 
  */
 NTSTATUS STDCALL
-NtDeleteFile (IN       POBJECT_ATTRIBUTES      ObjectAttributes)
+NtDeleteFile(IN POBJECT_ATTRIBUTES ObjectAttributes)
 {
    UNIMPLEMENTED;
 }
@@ -56,11 +61,11 @@ NtDeleteFile (IN    POBJECT_ATTRIBUTES      ObjectAttributes)
  * REVISIONS
  * 
  */
-NTSTATUS
-IopCreateFile (PVOID                   ObjectBody,
-              PVOID                    Parent,
-              PWSTR                    RemainingPath,
-              POBJECT_ATTRIBUTES       ObjectAttributes)
+NTSTATUS STDCALL
+IopCreateFile(PVOID                    ObjectBody,
+             PVOID                     Parent,
+             PWSTR                     RemainingPath,
+             POBJECT_ATTRIBUTES        ObjectAttributes)
 {
    PDEVICE_OBJECT      DeviceObject = (PDEVICE_OBJECT) Parent;
    PFILE_OBJECT        FileObject = (PFILE_OBJECT) ObjectBody;
@@ -73,12 +78,15 @@ IopCreateFile (PVOID                        ObjectBody,
    
    if (NULL == DeviceObject)
      {
+       /* 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);
      }
    if (IoDeviceObjectType != BODY_TO_HEADER(Parent)->ObjectType)
      {
-       DPRINT ("Parent is not a device type\n");
+       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,
@@ -87,46 +95,56 @@ IopCreateFile (PVOID                        ObjectBody,
                                        UserMode);
    if (STATUS_SUCCESS != Status)
      {
-       CHECKPOINT;
+       CHECKPOINT1;
        return (Status);
      }
    
    DeviceObject = IoGetAttachedDevice (DeviceObject);
    
-   DPRINT ("DeviceObject %x\n", DeviceObject);
+   DPRINT("DeviceObject %x\n", DeviceObject);
    
    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)
+       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))
          {
-            DPRINT ("Device was wrong type\n");
+            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))
          {
-            DPRINT("Trying to mount storage device\n");
-            Status = IoTryToMountStorageDevice (DeviceObject);
-            DPRINT("Status %x\n", Status);
-            if (!NT_SUCCESS(Status))
+            if (!(DeviceObject->Vpb->Flags & VPB_MOUNTED))
               {
-                 DPRINT("Failed to mount storage device (statux %x)\n",
-                        Status);
-                 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);
          }
        RtlCreateUnicodeString(&(FileObject->FileName),
                               RemainingPath);
@@ -165,23 +183,26 @@ IopCreateFile (PVOID                      ObjectBody,
  * 
  */
 PFILE_OBJECT STDCALL
-IoCreateStreamFileObject (PFILE_OBJECT FileObject,
-                         PDEVICE_OBJECT        DeviceObject)
+IoCreateStreamFileObject(PFILE_OBJECT FileObject,
+                        PDEVICE_OBJECT DeviceObject)
 {
   HANDLE               FileHandle;
   PFILE_OBJECT CreatedFileObject;
-  
-  DbgPrint("IoCreateStreamFileObject(FileObject %x, DeviceObject %x)\n",
+  NTSTATUS Status;
+
+  DPRINT("IoCreateStreamFileObject(FileObject %x, DeviceObject %x)\n",
           FileObject, DeviceObject);
    
   assert_irql (PASSIVE_LEVEL);
-  
-  CreatedFileObject = ObCreateObject (&FileHandle,
-                                     STANDARD_RIGHTS_REQUIRED,
-                                     NULL,
-                                     IoFileObjectType);
-  if (NULL == CreatedFileObject)
+
+  Status = ObCreateObject (&FileHandle,
+                          STANDARD_RIGHTS_REQUIRED,
+                          NULL,
+                          IoFileObjectType,
+                          (PVOID*)&CreatedFileObject);
+  if (!NT_SUCCESS(Status))
     {
+      DPRINT("Could not create FileObject\n");
       return (NULL);
     }
   
@@ -190,6 +211,9 @@ IoCreateStreamFileObject (PFILE_OBJECT      FileObject,
       DeviceObject = FileObject->DeviceObject;
     }
   DeviceObject = IoGetAttachedDevice(DeviceObject);
+
+  DPRINT("DeviceObject %x\n", DeviceObject);
+
   CreatedFileObject->DeviceObject = DeviceObject;
   CreatedFileObject->Vpb = DeviceObject->Vpb;
   CreatedFileObject->Type = InternalFileType;
@@ -250,10 +274,10 @@ IoCreateStreamFileObject (PFILE_OBJECT    FileObject,
  *             Undocumented;
  *             
  *     CreateFileType
- *             Undocumented;
+ *             Type of file (normal, named pipe, mailslot) to create;
  *             
- *     ExtraCreateParameters
- *             Undocumented;
+ *     ExtraCreateParameters [OPTIONAL]
+ *             Additional creation data for named pipe and mailsots;
  *             
  *     Options
  *             Undocumented.
@@ -269,118 +293,152 @@ IoCreateStreamFileObject (PFILE_OBJECT  FileObject,
  * 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
-       )
+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("IoCreateFile(FileHandle %x, DesiredAccess %x, "
-           "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\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);
+   assert_irql(PASSIVE_LEVEL);
    
-       *FileHandle = 0;
+   *FileHandle = 0;
+
+   Status = ObCreateObject(FileHandle,
+                          DesiredAccess,
+                          ObjectAttributes,
+                          IoFileObjectType,
+                          (PVOID*)&FileObject);
+   if (!NT_SUCCESS(Status))
+     {
+       DPRINT("ObCreateObject() failed!\n");
+       return (Status);
+     }
+   if (CreateOptions & FILE_SYNCHRONOUS_IO_ALERT)
+     {
+       FileObject->Flags |= (FO_ALERTABLE_IO | FO_SYNCHRONOUS_IO);
+     }
+   if (CreateOptions & FILE_SYNCHRONOUS_IO_NONALERT)
+     {
+       FileObject->Flags |= FO_SYNCHRONOUS_IO;
+     }
 
-       FileObject = ObCreateObject (FileHandle,
-                                    DesiredAccess,
-                                    ObjectAttributes,
-                                    IoFileObjectType);
-       if (FileObject == NULL)
-       {
-               return (STATUS_UNSUCCESSFUL);
-       }
-       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;
-       }
-       KeInitializeEvent (&Event, NotificationEvent, FALSE);
+   if( CreateOptions & FILE_NO_INTERMEDIATE_BUFFERING )
+     FileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
+
+   SecurityContext.SecurityQos = NULL; /* ?? */
+   SecurityContext.AccessState = NULL; /* ?? */
+   SecurityContext.DesiredAccess = DesiredAccess;
+   SecurityContext.FullCreateOptions = 0; /* ?? */
    
-       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)
-       {
-               return (STATUS_UNSUCCESSFUL);
-       }
+   KeInitializeEvent(&FileObject->Lock, NotificationEvent, TRUE);
+   KeInitializeEvent(&Event, NotificationEvent, FALSE);
    
-        Irp->AssociatedIrp.SystemBuffer = EaBuffer;
+   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)
+     {
+       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;
-       StackLoc->MinorFunction = 0;
-       StackLoc->Flags = 0;
-       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);
+   /*
+    * Get the stack location for the new
+    * IRP and prepare it.
+    */
+   StackLoc = IoGetNextIrpStackLocation(Irp);
+   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 = Options;
+   StackLoc->Control = 0;
+   StackLoc->DeviceObject = FileObject->DeviceObject;
+   StackLoc->FileObject = FileObject;
+   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 );
-       if (Status == STATUS_PENDING)
-       {
-               KeWaitForSingleObject (&Event,
-                                      Executive,
-                                      KernelMode,
-                                      FALSE,
-                                      NULL);
-               Status = IoStatusBlock->Status;
-       }
-       if (!NT_SUCCESS(Status))
-       {
-               DPRINT("Failing create request with status %x\n", Status);
-               ZwClose (*FileHandle);
-               (*FileHandle) = 0;
-       }
+   /*
+    * Now call the driver and 
+    * possibly wait if it can
+    * not complete the request
+    * immediately.
+    */
+   Status = IofCallDriver(FileObject->DeviceObject, Irp );
    
-       assert_irql(PASSIVE_LEVEL);
+   if (Status == STATUS_PENDING)
+     {
+       KeWaitForSingleObject(&Event,
+                             Executive,
+                             KernelMode,
+                             FALSE,
+                             NULL);
+       Status = IoSB.Status;
+     }
+   if (!NT_SUCCESS(Status))
+     {
+       DPRINT("Failing create request with status %x\n", Status);
+       ZwClose(*FileHandle);
+     }
+   if (IoStatusBlock)
+     {
+       *IoStatusBlock = IoSB;
+     }
+   assert_irql(PASSIVE_LEVEL);
 
-       DPRINT("Finished IoCreateFile() (*FileHandle) %x\n", (*FileHandle));
-               
-       return (Status);
+   DPRINT("Finished IoCreateFile() (*FileHandle) %x\n", (*FileHandle));
+
+   return (Status);
 }
 
 
@@ -402,39 +460,33 @@ IoCreateFile (
  *     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
-       )
+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 IoCreateFile (
-                       FileHandle,
-                       DesiredAccess,
-                       ObjectAttributes,
-                       IoStatusBlock,
-                       AllocateSize,
-                       FileAttributes,
-                       ShareAccess,
-                       CreateDisposition,
-                       CreateOptions,
-                       EaBuffer,
-                       EaLength,
-                       0,      /* CreateFileType */
-                       NULL,   /* ExtraCreateParameters */
-                       0       /* Options */
-                       );
-
+   return IoCreateFile(FileHandle,
+                      DesiredAccess,
+                      ObjectAttributes,
+                      IoStatusBlock,
+                      AllocateSize,
+                      FileAttributes,
+                      ShareAccess,
+                      CreateDisposition,
+                      CreateOptions,
+                      EaBuffer,
+                      EaLength,
+                      CreateFileTypeNone,
+                      NULL,
+                      0);
 }
 
 
@@ -443,7 +495,7 @@ NtCreateFile (
  *     NtOpenFile@24
  *     
  * DESCRIPTION
- *     Opens a file (simpler than NtCreateFile).
+ *     Opens an existing file (simpler than NtCreateFile).
  *
  * ARGUMENTS
  *     FileHandle (OUT)
@@ -464,41 +516,35 @@ NtCreateFile (
  *             
  *     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
-       )
+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,
-                       0,      /* CreateFileType */
-                       NULL,   /* ExtraCreateParameters */
-                       0       /* Options */
-                       );
+   return IoCreateFile(FileHandle,
+                      DesiredAccess,
+                      ObjectAttributes,
+                      IoStatusBlock,
+                      NULL,
+                      0,
+                      ShareAccess,
+                      FILE_OPEN,
+                      OpenOptions,
+                      NULL,
+                      0,
+                      CreateFileTypeNone,
+                      NULL,
+                      0);
 }
 
-
 /* EOF */