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 *************************************************************/
29 /**********************************************************************
45 NtDeleteFile(IN POBJECT_ATTRIBUTES ObjectAttributes)
51 /**********************************************************************
65 IopCreateFile(PVOID ObjectBody,
68 POBJECT_ATTRIBUTES ObjectAttributes)
70 PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT) Parent;
71 PFILE_OBJECT FileObject = (PFILE_OBJECT) ObjectBody;
74 DPRINT("IopCreateFile(ObjectBody %x, Parent %x, RemainingPath %S)\n",
79 if (NULL == DeviceObject)
81 /* This is probably an attempt to create a meta fileobject (eg. for FAT)
82 for the cache manager, so return STATUS_SUCCESS */
83 DPRINT("DeviceObject was NULL\n");
84 return(STATUS_SUCCESS);
87 if (IoDeviceObjectType != BODY_TO_HEADER(Parent)->ObjectType)
89 CPRINT("Parent is a %S which is not a device type\n",
90 BODY_TO_HEADER(Parent)->ObjectType->TypeName.Buffer);
91 return(STATUS_UNSUCCESSFUL);
94 Status = ObReferenceObjectByPointer(DeviceObject,
95 STANDARD_RIGHTS_REQUIRED,
98 if (!NT_SUCCESS(Status))
100 CPRINT("Failed to reference device object %x\n", DeviceObject);
104 DeviceObject = IoGetAttachedDevice(DeviceObject);
105 DPRINT("DeviceObject %x\n", DeviceObject);
107 if (NULL == RemainingPath)
109 FileObject->Flags = FileObject->Flags | FO_DIRECT_DEVICE_OPEN;
110 FileObject->FileName.Buffer = 0;
111 FileObject->FileName.Length = FileObject->FileName.MaximumLength = 0;
115 if ((DeviceObject->DeviceType != FILE_DEVICE_FILE_SYSTEM)
116 && (DeviceObject->DeviceType != FILE_DEVICE_DISK)
117 && (DeviceObject->DeviceType != FILE_DEVICE_CD_ROM)
118 && (DeviceObject->DeviceType != FILE_DEVICE_TAPE)
119 && (DeviceObject->DeviceType != FILE_DEVICE_NETWORK)
120 && (DeviceObject->DeviceType != FILE_DEVICE_NAMED_PIPE)
121 && (DeviceObject->DeviceType != FILE_DEVICE_MAILSLOT))
123 CPRINT("Device was wrong type\n");
124 return(STATUS_UNSUCCESSFUL);
127 if (DeviceObject->DeviceType != FILE_DEVICE_NETWORK
128 && (DeviceObject->DeviceType != FILE_DEVICE_NAMED_PIPE)
129 && (DeviceObject->DeviceType != FILE_DEVICE_MAILSLOT))
131 if (!(DeviceObject->Vpb->Flags & VPB_MOUNTED))
133 DPRINT("Mount the logical volume\n");
134 Status = IoMountVolume(DeviceObject, FALSE);
135 DPRINT("Status %x\n", Status);
136 if (!NT_SUCCESS(Status))
138 CPRINT("Failed to mount logical volume (Status %x)\n",
143 DeviceObject = DeviceObject->Vpb->DeviceObject;
144 DPRINT("FsDeviceObject %lx\n", DeviceObject);
146 RtlCreateUnicodeString(&(FileObject->FileName),
150 DPRINT("FileObject->FileName %wZ\n",
151 &FileObject->FileName);
152 FileObject->DeviceObject = DeviceObject;
153 DPRINT("FileObject %x DeviceObject %x\n",
156 FileObject->Vpb = DeviceObject->Vpb;
157 FileObject->Type = InternalFileType;
159 return(STATUS_SUCCESS);
163 /**********************************************************************
165 * IoCreateStreamFileObject@8
184 IoCreateStreamFileObject(PFILE_OBJECT FileObject,
185 PDEVICE_OBJECT DeviceObject)
188 PFILE_OBJECT CreatedFileObject;
191 DPRINT("IoCreateStreamFileObject(FileObject %x, DeviceObject %x)\n",
192 FileObject, DeviceObject);
194 assert_irql(PASSIVE_LEVEL);
196 Status = ObCreateObject(&FileHandle,
197 STANDARD_RIGHTS_REQUIRED,
200 (PVOID*)&CreatedFileObject);
201 if (!NT_SUCCESS(Status))
203 DPRINT("Could not create FileObject\n");
207 if (FileObject != NULL)
209 DeviceObject = FileObject->DeviceObject;
211 DeviceObject = IoGetAttachedDevice(DeviceObject);
213 DPRINT("DeviceObject %x\n", DeviceObject);
215 CreatedFileObject->DeviceObject = DeviceObject->Vpb->DeviceObject;
216 CreatedFileObject->Vpb = DeviceObject->Vpb;
217 CreatedFileObject->Type = InternalFileType;
218 CreatedFileObject->Flags |= FO_DIRECT_DEVICE_OPEN;
220 // shouldn't we initialize the lock event, and several other things here too?
221 KeInitializeEvent(&CreatedFileObject->Event, NotificationEvent, FALSE);
225 return(CreatedFileObject);
229 /**********************************************************************
234 * Either causes a new file or directory to be created, or it
235 * opens an existing file, device, directory or volume, giving
236 * the caller a handle for the file object. This handle can be
237 * used by subsequent calls to manipulate data within the file
238 * or the file object's state of attributes.
242 * Points to a variable which receives the file handle
246 * Desired access to the file;
249 * Structure describing the file;
251 * IoStatusBlock (OUT)
252 * Receives information about the operation on return;
254 * AllocationSize [OPTIONAL]
255 * Initial size of the file in bytes;
258 * Attributes to create the file with;
261 * Type of shared access the caller would like to the
265 * Specifies what to do, depending on whether the
266 * file already exists;
269 * Options for creating a new file;
271 * EaBuffer [OPTIONAL]
278 * Type of file (normal, named pipe, mailslot) to create;
280 * ExtraCreateParameters [OPTIONAL]
281 * Additional creation data for named pipe and mailsots;
290 * Prototype taken from Bo Branten's ntifs.h v15.
291 * Description taken from old NtCreateFile's which is
292 * now a wrapper of this call.
298 IoCreateFile(OUT PHANDLE FileHandle,
299 IN ACCESS_MASK DesiredAccess,
300 IN POBJECT_ATTRIBUTES ObjectAttributes,
301 OUT PIO_STATUS_BLOCK IoStatusBlock,
302 IN PLARGE_INTEGER AllocationSize OPTIONAL,
303 IN ULONG FileAttributes,
304 IN ULONG ShareAccess,
305 IN ULONG CreateDisposition,
306 IN ULONG CreateOptions,
307 IN PVOID EaBuffer OPTIONAL,
309 IN CREATE_FILE_TYPE CreateFileType,
310 IN PVOID ExtraCreateParameters OPTIONAL,
313 PFILE_OBJECT FileObject;
316 PIO_STACK_LOCATION StackLoc;
317 IO_STATUS_BLOCK IoSB;
318 IO_SECURITY_CONTEXT SecurityContext;
320 DPRINT("IoCreateFile(FileHandle %x, DesiredAccess %x, "
321 "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
322 FileHandle,DesiredAccess,ObjectAttributes,
323 ObjectAttributes->ObjectName->Buffer);
325 assert_irql(PASSIVE_LEVEL);
329 Status = ObCreateObject(FileHandle,
333 (PVOID*)&FileObject);
334 if (!NT_SUCCESS(Status))
336 DPRINT("ObCreateObject() failed! (Status %lx)\n", Status);
339 if (CreateOptions & FILE_SYNCHRONOUS_IO_ALERT)
341 FileObject->Flags |= (FO_ALERTABLE_IO | FO_SYNCHRONOUS_IO);
343 if (CreateOptions & FILE_SYNCHRONOUS_IO_NONALERT)
345 FileObject->Flags |= FO_SYNCHRONOUS_IO;
348 if( CreateOptions & FILE_NO_INTERMEDIATE_BUFFERING )
349 FileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
351 SecurityContext.SecurityQos = NULL; /* ?? */
352 SecurityContext.AccessState = NULL; /* ?? */
353 SecurityContext.DesiredAccess = DesiredAccess;
354 SecurityContext.FullCreateOptions = 0; /* ?? */
356 KeInitializeEvent(&FileObject->Lock, NotificationEvent, TRUE);
357 KeInitializeEvent(&FileObject->Event, NotificationEvent, FALSE);
359 DPRINT("FileObject %x\n", FileObject);
360 DPRINT("FileObject->DeviceObject %x\n", FileObject->DeviceObject);
362 * Create a new IRP to hand to
363 * the FS driver: this may fail
364 * due to resource shortage.
366 Irp = IoAllocateIrp(FileObject->DeviceObject->StackSize, FALSE);
369 ZwClose(*FileHandle);
370 return (STATUS_UNSUCCESSFUL);
373 Irp->UserIosb = &IoSB; //return iostatus
374 Irp->AssociatedIrp.SystemBuffer = EaBuffer;
375 Irp->Tail.Overlay.AuxiliaryBuffer = (PCHAR)ExtraCreateParameters;
376 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
377 Irp->UserEvent = &FileObject->Event;
380 Irp->Overlay.AllocationSize = *AllocationSize;
384 * Get the stack location for the new
385 * IRP and prepare it.
387 StackLoc = IoGetNextIrpStackLocation(Irp);
388 switch (CreateFileType)
391 case CreateFileTypeNone:
392 StackLoc->MajorFunction = IRP_MJ_CREATE;
395 case CreateFileTypeNamedPipe:
396 StackLoc->MajorFunction = IRP_MJ_CREATE_NAMED_PIPE;
399 case CreateFileTypeMailslot:
400 StackLoc->MajorFunction = IRP_MJ_CREATE_MAILSLOT;
403 StackLoc->MinorFunction = 0;
404 StackLoc->Flags = Options;
405 StackLoc->Control = 0;
406 StackLoc->DeviceObject = FileObject->DeviceObject;
407 StackLoc->FileObject = FileObject;
408 StackLoc->Parameters.Create.SecurityContext = &SecurityContext;
409 StackLoc->Parameters.Create.Options = (CreateOptions & FILE_VALID_OPTION_FLAGS);
410 StackLoc->Parameters.Create.Options |= (CreateDisposition << 24);
411 StackLoc->Parameters.Create.FileAttributes = FileAttributes;
412 StackLoc->Parameters.Create.ShareAccess = ShareAccess;
413 StackLoc->Parameters.Create.EaLength = EaLength;
416 * Now call the driver and
417 * possibly wait if it can
418 * not complete the request
421 Status = IofCallDriver(FileObject->DeviceObject, Irp );
423 if (Status == STATUS_PENDING)
425 KeWaitForSingleObject(&FileObject->Event,
430 Status = IoSB.Status;
432 if (!NT_SUCCESS(Status))
434 DPRINT("Failing create request with status %x\n", Status);
435 ZwClose(*FileHandle);
439 *IoStatusBlock = IoSB;
441 assert_irql(PASSIVE_LEVEL);
443 DPRINT("Finished IoCreateFile() (*FileHandle) %x\n", (*FileHandle));
449 /**********************************************************************
454 * Entry point to call IoCreateFile with
455 * default parameters.
465 * Code originally in NtCreateFile moved in IoCreateFile.
468 NtCreateFile(PHANDLE FileHandle,
469 ACCESS_MASK DesiredAccess,
470 POBJECT_ATTRIBUTES ObjectAttributes,
471 PIO_STATUS_BLOCK IoStatusBlock,
472 PLARGE_INTEGER AllocateSize,
473 ULONG FileAttributes,
475 ULONG CreateDisposition,
480 return IoCreateFile(FileHandle,
497 /**********************************************************************
502 * Opens an existing file (simpler than NtCreateFile).
506 * Variable that receives the file handle on return;
509 * Access desired by the caller to the file;
512 * Structue describing the file to be opened;
514 * IoStatusBlock (OUT)
515 * Receives details about the result of the
519 * Type of shared access the caller requires;
522 * Options for the file open.
531 NtOpenFile(PHANDLE FileHandle,
532 ACCESS_MASK DesiredAccess,
533 POBJECT_ATTRIBUTES ObjectAttributes,
534 PIO_STATUS_BLOCK IoStatusBlock,
538 return IoCreateFile(FileHandle,