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)
53 /**********************************************************************
67 IopCreateFile(PVOID ObjectBody,
70 POBJECT_ATTRIBUTES ObjectAttributes)
72 PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT) Parent;
73 PFILE_OBJECT FileObject = (PFILE_OBJECT) ObjectBody;
76 DPRINT("IopCreateFile(ObjectBody %x, Parent %x, RemainingPath %S)\n",
81 if (NULL == DeviceObject)
83 /* This is probably an attempt to create a meta fileobject (eg. for FAT)
84 for the cache manager, so return STATUS_SUCCESS */
85 DPRINT("DeviceObject was NULL\n");
86 return(STATUS_SUCCESS);
89 if (IoDeviceObjectType != BODY_TO_HEADER(Parent)->ObjectType)
91 CPRINT("Parent is a %S which is not a device type\n",
92 BODY_TO_HEADER(Parent)->ObjectType->TypeName.Buffer);
93 return(STATUS_UNSUCCESSFUL);
96 Status = ObReferenceObjectByPointer(DeviceObject,
97 STANDARD_RIGHTS_REQUIRED,
100 if (!NT_SUCCESS(Status))
102 CPRINT("Failed to reference device object %x\n", DeviceObject);
106 DeviceObject = IoGetAttachedDevice(DeviceObject);
107 DPRINT("DeviceObject %x\n", DeviceObject);
109 if (NULL == RemainingPath)
111 FileObject->Flags = FileObject->Flags | FO_DIRECT_DEVICE_OPEN;
112 FileObject->FileName.Buffer = 0;
113 FileObject->FileName.Length = FileObject->FileName.MaximumLength = 0;
117 if ((DeviceObject->DeviceType != FILE_DEVICE_FILE_SYSTEM)
118 && (DeviceObject->DeviceType != FILE_DEVICE_DISK)
119 && (DeviceObject->DeviceType != FILE_DEVICE_CD_ROM)
120 && (DeviceObject->DeviceType != FILE_DEVICE_TAPE)
121 && (DeviceObject->DeviceType != FILE_DEVICE_NETWORK)
122 && (DeviceObject->DeviceType != FILE_DEVICE_NAMED_PIPE)
123 && (DeviceObject->DeviceType != FILE_DEVICE_MAILSLOT))
125 CPRINT("Device was wrong type\n");
126 return(STATUS_UNSUCCESSFUL);
129 if (DeviceObject->DeviceType != FILE_DEVICE_NETWORK
130 && (DeviceObject->DeviceType != FILE_DEVICE_NAMED_PIPE)
131 && (DeviceObject->DeviceType != FILE_DEVICE_MAILSLOT))
133 if (!(DeviceObject->Vpb->Flags & VPB_MOUNTED))
135 DPRINT("Mount the logical volume\n");
136 Status = IoMountVolume(DeviceObject, FALSE);
137 DPRINT("Status %x\n", Status);
138 if (!NT_SUCCESS(Status))
140 CPRINT("Failed to mount logical volume (Status %x)\n",
145 DeviceObject = DeviceObject->Vpb->DeviceObject;
146 DPRINT("FsDeviceObject %lx\n", DeviceObject);
148 RtlCreateUnicodeString(&(FileObject->FileName),
152 DPRINT("FileObject->FileName %wZ\n",
153 &FileObject->FileName);
154 FileObject->DeviceObject = DeviceObject;
155 DPRINT("FileObject %x DeviceObject %x\n",
158 FileObject->Vpb = DeviceObject->Vpb;
159 FileObject->Type = InternalFileType;
161 return(STATUS_SUCCESS);
165 /**********************************************************************
167 * IoCreateStreamFileObject@8
186 IoCreateStreamFileObject(PFILE_OBJECT FileObject,
187 PDEVICE_OBJECT DeviceObject)
190 PFILE_OBJECT CreatedFileObject;
193 DPRINT("IoCreateStreamFileObject(FileObject %x, DeviceObject %x)\n",
194 FileObject, DeviceObject);
196 assert_irql(PASSIVE_LEVEL);
198 Status = ObCreateObject(&FileHandle,
199 STANDARD_RIGHTS_REQUIRED,
202 (PVOID*)&CreatedFileObject);
203 if (!NT_SUCCESS(Status))
205 DPRINT("Could not create FileObject\n");
209 if (FileObject != NULL)
211 DeviceObject = FileObject->DeviceObject;
213 DeviceObject = IoGetAttachedDevice(DeviceObject);
215 DPRINT("DeviceObject %x\n", DeviceObject);
217 CreatedFileObject->DeviceObject = DeviceObject->Vpb->DeviceObject;
218 CreatedFileObject->Vpb = DeviceObject->Vpb;
219 CreatedFileObject->Type = InternalFileType;
220 CreatedFileObject->Flags |= FO_DIRECT_DEVICE_OPEN;
222 // shouldn't we initialize the lock event, and several other things here too?
223 KeInitializeEvent(&CreatedFileObject->Event, NotificationEvent, FALSE);
227 return(CreatedFileObject);
230 #endif /* LIBCAPTIVE */
232 /**********************************************************************
237 * Either causes a new file or directory to be created, or it
238 * opens an existing file, device, directory or volume, giving
239 * the caller a handle for the file object. This handle can be
240 * used by subsequent calls to manipulate data within the file
241 * or the file object's state of attributes.
245 * Points to a variable which receives the file handle
249 * Desired access to the file;
252 * Structure describing the file;
254 * IoStatusBlock (OUT)
255 * Receives information about the operation on return;
257 * AllocationSize [OPTIONAL]
258 * Initial size of the file in bytes;
261 * Attributes to create the file with;
264 * Type of shared access the caller would like to the
268 * Specifies what to do, depending on whether the
269 * file already exists;
272 * Options for creating a new file;
274 * EaBuffer [OPTIONAL]
281 * Type of file (normal, named pipe, mailslot) to create;
283 * ExtraCreateParameters [OPTIONAL]
284 * Additional creation data for named pipe and mailsots;
293 * Prototype taken from Bo Branten's ntifs.h v15.
294 * Description taken from old NtCreateFile's which is
295 * now a wrapper of this call.
301 IoCreateFile(OUT PHANDLE FileHandle,
302 IN ACCESS_MASK DesiredAccess,
303 IN POBJECT_ATTRIBUTES ObjectAttributes,
304 OUT PIO_STATUS_BLOCK IoStatusBlock,
305 IN PLARGE_INTEGER AllocationSize OPTIONAL,
306 IN ULONG FileAttributes,
307 IN ULONG ShareAccess,
308 IN ULONG CreateDisposition,
309 IN ULONG CreateOptions,
310 IN PVOID EaBuffer OPTIONAL,
312 IN CREATE_FILE_TYPE CreateFileType,
313 IN PVOID ExtraCreateParameters OPTIONAL,
316 PFILE_OBJECT FileObject;
319 PIO_STACK_LOCATION StackLoc;
320 IO_STATUS_BLOCK IoSB;
321 IO_SECURITY_CONTEXT SecurityContext;
323 DPRINT("IoCreateFile(FileHandle %x, DesiredAccess %x, "
324 "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
325 FileHandle,DesiredAccess,ObjectAttributes,
326 ObjectAttributes->ObjectName->Buffer);
328 assert_irql(PASSIVE_LEVEL);
332 Status = ObCreateObject(FileHandle,
336 (PVOID*)&FileObject);
337 if (!NT_SUCCESS(Status))
339 DPRINT("ObCreateObject() failed! (Status %lx)\n", Status);
342 if (CreateOptions & FILE_SYNCHRONOUS_IO_ALERT)
344 FileObject->Flags |= (FO_ALERTABLE_IO | FO_SYNCHRONOUS_IO);
346 if (CreateOptions & FILE_SYNCHRONOUS_IO_NONALERT)
348 FileObject->Flags |= FO_SYNCHRONOUS_IO;
351 if( CreateOptions & FILE_NO_INTERMEDIATE_BUFFERING )
352 FileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
354 SecurityContext.SecurityQos = NULL; /* ?? */
355 SecurityContext.AccessState = NULL; /* ?? */
356 SecurityContext.DesiredAccess = DesiredAccess;
357 SecurityContext.FullCreateOptions = 0; /* ?? */
359 KeInitializeEvent(&FileObject->Lock, NotificationEvent, TRUE);
360 KeInitializeEvent(&FileObject->Event, NotificationEvent, FALSE);
362 DPRINT("FileObject %x\n", FileObject);
363 DPRINT("FileObject->DeviceObject %x\n", FileObject->DeviceObject);
365 * Create a new IRP to hand to
366 * the FS driver: this may fail
367 * due to resource shortage.
369 Irp = IoAllocateIrp(FileObject->DeviceObject->StackSize, FALSE);
372 ZwClose(*FileHandle);
373 return (STATUS_UNSUCCESSFUL);
376 Irp->UserIosb = &IoSB; //return iostatus
377 Irp->AssociatedIrp.SystemBuffer = EaBuffer;
378 Irp->Tail.Overlay.AuxiliaryBuffer = (PCHAR)ExtraCreateParameters;
379 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
380 Irp->UserEvent = &FileObject->Event;
383 Irp->Overlay.AllocationSize = *AllocationSize;
387 * Get the stack location for the new
388 * IRP and prepare it.
390 StackLoc = IoGetNextIrpStackLocation(Irp);
391 switch (CreateFileType)
394 case CreateFileTypeNone:
395 StackLoc->MajorFunction = IRP_MJ_CREATE;
398 case CreateFileTypeNamedPipe:
399 StackLoc->MajorFunction = IRP_MJ_CREATE_NAMED_PIPE;
402 case CreateFileTypeMailslot:
403 StackLoc->MajorFunction = IRP_MJ_CREATE_MAILSLOT;
406 StackLoc->MinorFunction = 0;
407 StackLoc->Flags = Options;
408 StackLoc->Control = 0;
409 StackLoc->DeviceObject = FileObject->DeviceObject;
410 StackLoc->FileObject = FileObject;
411 StackLoc->Parameters.Create.SecurityContext = &SecurityContext;
412 StackLoc->Parameters.Create.Options = (CreateOptions & FILE_VALID_OPTION_FLAGS);
413 StackLoc->Parameters.Create.Options |= (CreateDisposition << 24);
414 StackLoc->Parameters.Create.FileAttributes = FileAttributes;
415 StackLoc->Parameters.Create.ShareAccess = ShareAccess;
416 StackLoc->Parameters.Create.EaLength = EaLength;
419 * Now call the driver and
420 * possibly wait if it can
421 * not complete the request
424 Status = IofCallDriver(FileObject->DeviceObject, Irp );
426 if (Status == STATUS_PENDING)
428 KeWaitForSingleObject(&FileObject->Event,
433 Status = IoSB.Status;
435 if (!NT_SUCCESS(Status))
437 DPRINT("Failing create request with status %x\n", Status);
438 ZwClose(*FileHandle);
442 *IoStatusBlock = IoSB;
444 assert_irql(PASSIVE_LEVEL);
446 DPRINT("Finished IoCreateFile() (*FileHandle) %x\n", (*FileHandle));
453 /**********************************************************************
458 * Entry point to call IoCreateFile with
459 * default parameters.
469 * Code originally in NtCreateFile moved in IoCreateFile.
472 NtCreateFile(PHANDLE FileHandle,
473 ACCESS_MASK DesiredAccess,
474 POBJECT_ATTRIBUTES ObjectAttributes,
475 PIO_STATUS_BLOCK IoStatusBlock,
476 PLARGE_INTEGER AllocateSize,
477 ULONG FileAttributes,
479 ULONG CreateDisposition,
484 return IoCreateFile(FileHandle,
501 /**********************************************************************
506 * Opens an existing file (simpler than NtCreateFile).
510 * Variable that receives the file handle on return;
513 * Access desired by the caller to the file;
516 * Structue describing the file to be opened;
518 * IoStatusBlock (OUT)
519 * Receives details about the result of the
523 * Type of shared access the caller requires;
526 * Options for the file open.
535 NtOpenFile(PHANDLE FileHandle,
536 ACCESS_MASK DesiredAccess,
537 POBJECT_ATTRIBUTES ObjectAttributes,
538 PIO_STATUS_BLOCK IoStatusBlock,
542 return IoCreateFile(FileHandle,
558 #endif /* LIBCAPTIVE */