3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/create.c
6 * PURPOSE: Handling file create/open apis
7 * PROGRAMMER: David Welch (welch@cwcom.net)
12 /* INCLUDES ***************************************************************/
14 #include <ddk/ntddk.h>
15 #include <internal/ob.h>
16 #include <internal/io.h>
17 #include <internal/id.h>
18 #include <internal/pool.h>
21 #include <internal/debug.h>
23 /* GLOBALS *******************************************************************/
25 #define TAG_FILE_NAME TAG('F', 'N', 'A', 'M')
27 /* FUNCTIONS *************************************************************/
31 /**********************************************************************
47 NtDeleteFile(IN POBJECT_ATTRIBUTES ObjectAttributes)
52 #endif /* LIBCAPTIVE */
54 /**********************************************************************
68 IopCreateFile(PVOID ObjectBody,
71 POBJECT_ATTRIBUTES ObjectAttributes)
73 PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT) Parent;
74 PFILE_OBJECT FileObject = (PFILE_OBJECT) ObjectBody;
77 DPRINT("IopCreateFile(ObjectBody %x, Parent %x, RemainingPath %S)\n",
82 if (NULL == DeviceObject)
84 /* This is probably an attempt to create a meta fileobject (eg. for FAT)
85 for the cache manager, so return STATUS_SUCCESS */
86 DPRINT("DeviceObject was NULL\n");
87 return(STATUS_SUCCESS);
90 if (IoDeviceObjectType != BODY_TO_HEADER(Parent)->ObjectType)
92 CPRINT("Parent is a %S which is not a device type\n",
93 BODY_TO_HEADER(Parent)->ObjectType->TypeName.Buffer);
94 return(STATUS_UNSUCCESSFUL);
97 Status = ObReferenceObjectByPointer(DeviceObject,
98 STANDARD_RIGHTS_REQUIRED,
101 if (!NT_SUCCESS(Status))
103 CPRINT("Failed to reference device object %x\n", DeviceObject);
107 DeviceObject = IoGetAttachedDevice(DeviceObject);
108 DPRINT("DeviceObject %x\n", DeviceObject);
110 if (NULL == RemainingPath)
112 FileObject->Flags = FileObject->Flags | FO_DIRECT_DEVICE_OPEN;
113 FileObject->FileName.Buffer = 0;
114 FileObject->FileName.Length = FileObject->FileName.MaximumLength = 0;
118 if ((DeviceObject->DeviceType != FILE_DEVICE_FILE_SYSTEM)
119 && (DeviceObject->DeviceType != FILE_DEVICE_DISK)
120 && (DeviceObject->DeviceType != FILE_DEVICE_CD_ROM)
121 && (DeviceObject->DeviceType != FILE_DEVICE_TAPE)
122 && (DeviceObject->DeviceType != FILE_DEVICE_NETWORK)
123 && (DeviceObject->DeviceType != FILE_DEVICE_NAMED_PIPE)
124 && (DeviceObject->DeviceType != FILE_DEVICE_MAILSLOT))
126 CPRINT("Device was wrong type\n");
127 return(STATUS_UNSUCCESSFUL);
130 if (DeviceObject->DeviceType != FILE_DEVICE_NETWORK
131 && (DeviceObject->DeviceType != FILE_DEVICE_NAMED_PIPE)
132 && (DeviceObject->DeviceType != FILE_DEVICE_MAILSLOT))
134 if (!(DeviceObject->Vpb->Flags & VPB_MOUNTED))
136 DPRINT("Mount the logical volume\n");
137 Status = IoMountVolume(DeviceObject, FALSE);
138 DPRINT("Status %x\n", Status);
139 if (!NT_SUCCESS(Status))
141 CPRINT("Failed to mount logical volume (Status %x)\n",
146 DeviceObject = DeviceObject->Vpb->DeviceObject;
147 DPRINT("FsDeviceObject %lx\n", DeviceObject);
149 RtlCreateUnicodeString(&(FileObject->FileName),
153 DPRINT("FileObject->FileName %wZ\n",
154 &FileObject->FileName);
155 FileObject->DeviceObject = DeviceObject;
156 DPRINT("FileObject %x DeviceObject %x\n",
159 FileObject->Vpb = DeviceObject->Vpb;
160 FileObject->Type = InternalFileType;
162 return(STATUS_SUCCESS);
167 /**********************************************************************
169 * IoCreateStreamFileObject@8
188 IoCreateStreamFileObject(PFILE_OBJECT FileObject,
189 PDEVICE_OBJECT DeviceObject)
192 PFILE_OBJECT CreatedFileObject;
195 DPRINT("IoCreateStreamFileObject(FileObject %x, DeviceObject %x)\n",
196 FileObject, DeviceObject);
198 assert_irql(PASSIVE_LEVEL);
200 Status = ObCreateObject(&FileHandle,
201 STANDARD_RIGHTS_REQUIRED,
204 (PVOID*)&CreatedFileObject);
205 if (!NT_SUCCESS(Status))
207 DPRINT("Could not create FileObject\n");
211 if (FileObject != NULL)
213 DeviceObject = FileObject->DeviceObject;
215 DeviceObject = IoGetAttachedDevice(DeviceObject);
217 DPRINT("DeviceObject %x\n", DeviceObject);
219 CreatedFileObject->DeviceObject = DeviceObject->Vpb->DeviceObject;
220 CreatedFileObject->Vpb = DeviceObject->Vpb;
221 CreatedFileObject->Type = InternalFileType;
222 CreatedFileObject->Flags |= FO_DIRECT_DEVICE_OPEN;
224 // shouldn't we initialize the lock event, and several other things here too?
225 KeInitializeEvent(&CreatedFileObject->Event, NotificationEvent, FALSE);
229 return(CreatedFileObject);
232 #endif /* LIBCAPTIVE */
234 /**********************************************************************
239 * Either causes a new file or directory to be created, or it
240 * opens an existing file, device, directory or volume, giving
241 * the caller a handle for the file object. This handle can be
242 * used by subsequent calls to manipulate data within the file
243 * or the file object's state of attributes.
247 * Points to a variable which receives the file handle
251 * Desired access to the file;
254 * Structure describing the file;
256 * IoStatusBlock (OUT)
257 * Receives information about the operation on return;
259 * AllocationSize [OPTIONAL]
260 * Initial size of the file in bytes;
263 * Attributes to create the file with;
266 * Type of shared access the caller would like to the
270 * Specifies what to do, depending on whether the
271 * file already exists;
274 * Options for creating a new file;
276 * EaBuffer [OPTIONAL]
283 * Type of file (normal, named pipe, mailslot) to create;
285 * ExtraCreateParameters [OPTIONAL]
286 * Additional creation data for named pipe and mailsots;
295 * Prototype taken from Bo Branten's ntifs.h v15.
296 * Description taken from old NtCreateFile's which is
297 * now a wrapper of this call.
303 IoCreateFile(OUT PHANDLE FileHandle,
304 IN ACCESS_MASK DesiredAccess,
305 IN POBJECT_ATTRIBUTES ObjectAttributes,
306 OUT PIO_STATUS_BLOCK IoStatusBlock,
307 IN PLARGE_INTEGER AllocationSize OPTIONAL,
308 IN ULONG FileAttributes,
309 IN ULONG ShareAccess,
310 IN ULONG CreateDisposition,
311 IN ULONG CreateOptions,
312 IN PVOID EaBuffer OPTIONAL,
314 IN CREATE_FILE_TYPE CreateFileType,
315 IN PVOID ExtraCreateParameters OPTIONAL,
318 PFILE_OBJECT FileObject;
321 PIO_STACK_LOCATION StackLoc;
322 IO_STATUS_BLOCK IoSB;
323 IO_SECURITY_CONTEXT SecurityContext;
325 DPRINT("IoCreateFile(FileHandle %x, DesiredAccess %x, "
326 "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
327 FileHandle,DesiredAccess,ObjectAttributes,
328 ObjectAttributes->ObjectName->Buffer);
330 assert_irql(PASSIVE_LEVEL);
334 Status = ObCreateObject(FileHandle,
338 (PVOID*)&FileObject);
339 if (!NT_SUCCESS(Status))
341 DPRINT("ObCreateObject() failed! (Status %lx)\n", Status);
344 if (CreateOptions & FILE_SYNCHRONOUS_IO_ALERT)
346 FileObject->Flags |= (FO_ALERTABLE_IO | FO_SYNCHRONOUS_IO);
348 if (CreateOptions & FILE_SYNCHRONOUS_IO_NONALERT)
350 FileObject->Flags |= FO_SYNCHRONOUS_IO;
353 if( CreateOptions & FILE_NO_INTERMEDIATE_BUFFERING )
354 FileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
356 SecurityContext.SecurityQos = NULL; /* ?? */
357 SecurityContext.AccessState = NULL; /* ?? */
358 SecurityContext.DesiredAccess = DesiredAccess;
359 SecurityContext.FullCreateOptions = 0; /* ?? */
361 KeInitializeEvent(&FileObject->Lock, NotificationEvent, TRUE);
362 KeInitializeEvent(&FileObject->Event, NotificationEvent, FALSE);
364 DPRINT("FileObject %x\n", FileObject);
365 DPRINT("FileObject->DeviceObject %x\n", FileObject->DeviceObject);
367 * Create a new IRP to hand to
368 * the FS driver: this may fail
369 * due to resource shortage.
371 Irp = IoAllocateIrp(FileObject->DeviceObject->StackSize, FALSE);
374 ZwClose(*FileHandle);
375 return (STATUS_UNSUCCESSFUL);
378 Irp->UserIosb = &IoSB; //return iostatus
379 Irp->AssociatedIrp.SystemBuffer = EaBuffer;
380 Irp->Tail.Overlay.AuxiliaryBuffer = (PCHAR)ExtraCreateParameters;
381 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
382 Irp->UserEvent = &FileObject->Event;
385 Irp->Overlay.AllocationSize = *AllocationSize;
389 * Get the stack location for the new
390 * IRP and prepare it.
392 StackLoc = IoGetNextIrpStackLocation(Irp);
393 switch (CreateFileType)
396 case CreateFileTypeNone:
397 StackLoc->MajorFunction = IRP_MJ_CREATE;
400 case CreateFileTypeNamedPipe:
401 StackLoc->MajorFunction = IRP_MJ_CREATE_NAMED_PIPE;
404 case CreateFileTypeMailslot:
405 StackLoc->MajorFunction = IRP_MJ_CREATE_MAILSLOT;
408 StackLoc->MinorFunction = 0;
409 StackLoc->Flags = Options;
410 StackLoc->Control = 0;
411 StackLoc->DeviceObject = FileObject->DeviceObject;
412 StackLoc->FileObject = FileObject;
413 StackLoc->Parameters.Create.SecurityContext = &SecurityContext;
414 StackLoc->Parameters.Create.Options = (CreateOptions & FILE_VALID_OPTION_FLAGS);
415 StackLoc->Parameters.Create.Options |= (CreateDisposition << 24);
416 StackLoc->Parameters.Create.FileAttributes = FileAttributes;
417 StackLoc->Parameters.Create.ShareAccess = ShareAccess;
418 StackLoc->Parameters.Create.EaLength = EaLength;
421 * Now call the driver and
422 * possibly wait if it can
423 * not complete the request
426 Status = IofCallDriver(FileObject->DeviceObject, Irp );
428 if (Status == STATUS_PENDING)
430 KeWaitForSingleObject(&FileObject->Event,
435 Status = IoSB.Status;
437 if (!NT_SUCCESS(Status))
439 DPRINT("Failing create request with status %x\n", Status);
440 ZwClose(*FileHandle);
444 *IoStatusBlock = IoSB;
446 assert_irql(PASSIVE_LEVEL);
448 DPRINT("Finished IoCreateFile() (*FileHandle) %x\n", (*FileHandle));
455 /**********************************************************************
460 * Entry point to call IoCreateFile with
461 * default parameters.
471 * Code originally in NtCreateFile moved in IoCreateFile.
474 NtCreateFile(PHANDLE FileHandle,
475 ACCESS_MASK DesiredAccess,
476 POBJECT_ATTRIBUTES ObjectAttributes,
477 PIO_STATUS_BLOCK IoStatusBlock,
478 PLARGE_INTEGER AllocateSize,
479 ULONG FileAttributes,
481 ULONG CreateDisposition,
486 return IoCreateFile(FileHandle,
503 /**********************************************************************
508 * Opens an existing file (simpler than NtCreateFile).
512 * Variable that receives the file handle on return;
515 * Access desired by the caller to the file;
518 * Structue describing the file to be opened;
520 * IoStatusBlock (OUT)
521 * Receives details about the result of the
525 * Type of shared access the caller requires;
528 * Options for the file open.
537 NtOpenFile(PHANDLE FileHandle,
538 ACCESS_MASK DesiredAccess,
539 POBJECT_ATTRIBUTES ObjectAttributes,
540 PIO_STATUS_BLOCK IoStatusBlock,
544 return IoCreateFile(FileHandle,
560 #endif /* LIBCAPTIVE */