1 /* $Id: create.c,v 1.30 2000/03/29 13:11:53 dwelch Exp $
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/string.h>
21 #include <internal/debug.h>
23 /* FUNCTIONS *************************************************************/
25 /**********************************************************************
43 IN POBJECT_ATTRIBUTES ObjectAttributes
50 /**********************************************************************
68 POBJECT_ATTRIBUTES ObjectAttributes
71 PDEVICE_OBJECT DeviceObject
= (PDEVICE_OBJECT
) Parent
;
72 PFILE_OBJECT FileObject
= (PFILE_OBJECT
) ObjectBody
;
76 "IopCreateFile(ObjectBody %x, Parent %x, RemainingPath %S)\n",
82 if (NULL
== DeviceObject
)
84 DPRINT("DeviceObject was NULL\n");
85 return (STATUS_SUCCESS
);
87 if (IoDeviceObjectType
!= BODY_TO_HEADER(Parent
)->ObjectType
)
89 DPRINT ("Parent is not a device type\n");
90 return (STATUS_UNSUCCESSFUL
);
92 Status
= ObReferenceObjectByPointer (
94 STANDARD_RIGHTS_REQUIRED
,
98 if (STATUS_SUCCESS
!= Status
)
104 DeviceObject
= IoGetAttachedDevice (DeviceObject
);
106 DPRINT ("DeviceObject %x\n", DeviceObject
);
108 if (NULL
== RemainingPath
)
110 FileObject
->Flags
= FileObject
->Flags
| FO_DIRECT_DEVICE_OPEN
;
111 FileObject
->FileName
.Buffer
= ExAllocatePool(NonPagedPool
,
112 (ObjectAttributes
->ObjectName
->Length
+1)*2);
113 FileObject
->FileName
.Length
= ObjectAttributes
->ObjectName
->Length
;
114 FileObject
->FileName
.MaximumLength
=
115 ObjectAttributes
->ObjectName
->MaximumLength
;
116 RtlCopyUnicodeString(&(FileObject
->FileName
),
117 ObjectAttributes
->ObjectName
);
121 if ( (DeviceObject
->DeviceType
!= FILE_DEVICE_FILE_SYSTEM
)
122 && (DeviceObject
->DeviceType
!= FILE_DEVICE_DISK
)
125 DPRINT ("Device was wrong type\n");
126 return (STATUS_UNSUCCESSFUL
);
128 if (!(DeviceObject
->Vpb
->Flags
& VPB_MOUNTED
))
130 DPRINT("Trying to mount storage device\n");
131 Status
= IoTryToMountStorageDevice (DeviceObject
);
132 DPRINT("Status %x\n", Status
);
133 if (!NT_SUCCESS(Status
))
136 "Failed to mount storage device (statux %x)\n",
141 DeviceObject
= IoGetAttachedDevice(DeviceObject
);
143 RtlInitUnicodeString (
144 & (FileObject
->FileName
),
145 wcsdup (RemainingPath
)
149 "FileObject->FileName.Buffer %S\n",
150 FileObject
->FileName
.Buffer
152 FileObject
->DeviceObject
= DeviceObject
;
154 "FileObject %x DeviceObject %x\n",
158 FileObject
->Vpb
= DeviceObject
->Vpb
;
159 FileObject
->Type
= InternalFileType
;
161 return (STATUS_SUCCESS
);
165 /**********************************************************************
167 * IoCreateStreamFileObject@8
187 IoCreateStreamFileObject (
188 PFILE_OBJECT FileObject
,
189 PDEVICE_OBJECT DeviceObject
193 PFILE_OBJECT CreatedFileObject
;
195 DbgPrint("IoCreateStreamFileObject(FileObject %x, DeviceObject %x)\n",
200 assert_irql (PASSIVE_LEVEL
);
202 CreatedFileObject
= ObCreateObject (
204 STANDARD_RIGHTS_REQUIRED
,
208 if (NULL
== CreatedFileObject
)
213 if (FileObject
!= NULL
)
215 DeviceObject
= FileObject
->DeviceObject
;
217 DeviceObject
= IoGetAttachedDevice(DeviceObject
);
218 CreatedFileObject
->DeviceObject
= DeviceObject
;
219 CreatedFileObject
->Vpb
= DeviceObject
->Vpb
;
220 CreatedFileObject
->Type
= InternalFileType
;
221 //CreatedFileObject->Flags = CreatedFileObject->Flags | FO_DIRECT_DEVICE_OPEN;
222 CreatedFileObject
->Flags
|= FO_DIRECT_DEVICE_OPEN
;
224 ZwClose (FileHandle
);
226 return (CreatedFileObject
);
230 /**********************************************************************
235 * Either causes a new file or directory to be created, or it
236 * opens an existing file, device, directory or volume, giving
237 * the caller a handle for the file object. This handle can be
238 * used by subsequent calls to manipulate data within the file
239 * or the file object's state of attributes.
243 * Points to a variable which receives the file handle
247 * Desired access to the file;
250 * Structure describing the file;
252 * IoStatusBlock (OUT)
253 * Receives information about the operation on return;
255 * AllocationSize [OPTIONAL]
256 * Initial size of the file in bytes;
259 * Attributes to create the file with;
262 * Type of shared access the caller would like to the
266 * Specifies what to do, depending on whether the
267 * file already exists;
270 * Options for creating a new file;
272 * EaBuffer [OPTIONAL]
281 * ExtraCreateParameters
291 * Prototype taken from Bo Branten's ntifs.h v15.
292 * Description taken from old NtCreateFile's which is
293 * now a wrapper of this call.
301 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
,
317 PFILE_OBJECT FileObject
;
321 PIO_STACK_LOCATION StackLoc
;
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 FileObject
= ObCreateObject (
338 if (NULL
== FileObject
)
340 return (STATUS_UNSUCCESSFUL
);
342 if (CreateOptions
& FILE_SYNCHRONOUS_IO_ALERT
)
344 //FileObject->Flags = FileObject->Flags | FO_ALERTABLE_IO;
345 //FileObject->Flags = FileObject->Flags | FO_SYNCHRONOUS_IO;
346 FileObject
->Flags
|= ( FO_ALERTABLE_IO
350 if (CreateOptions
& FILE_SYNCHRONOUS_IO_NONALERT
)
352 //FileObject->Flags |= FileObject->Flags | FO_SYNCHRONOUS_IO;
353 FileObject
->Flags
|= FO_SYNCHRONOUS_IO
;
360 DPRINT("FileObject %x\n", FileObject
);
361 DPRINT("FileObject->DeviceObject %x\n", FileObject
->DeviceObject
);
363 * Create a new IRP to hand to
364 * the FS driver: this may fail
365 * due to resource shortage.
367 Irp
= IoAllocateIrp (
368 FileObject
->DeviceObject
->StackSize
,
373 return (STATUS_UNSUCCESSFUL
);
376 * Get the stack location for the new
377 * IRP and prepare it.
379 StackLoc
= IoGetNextIrpStackLocation (Irp
);
380 StackLoc
->MajorFunction
= IRP_MJ_CREATE
;
381 StackLoc
->MinorFunction
= 0;
383 StackLoc
->Control
= 0;
384 StackLoc
->DeviceObject
= FileObject
->DeviceObject
;
385 StackLoc
->FileObject
= FileObject
;
386 StackLoc
->Parameters
.Create
.Options
= (CreateOptions
& FILE_VALID_OPTION_FLAGS
);
387 StackLoc
->Parameters
.Create
.Options
|= (CreateDisposition
<< 24);
389 * Now call the driver and
390 * possibly wait if it can
391 * not complete the request
394 Status
= IofCallDriver (
395 FileObject
->DeviceObject
,
398 if (STATUS_PENDING
== Status
)
400 KeWaitForSingleObject (
407 Status
= IoStatusBlock
->Status
;
409 if (!NT_SUCCESS(Status
))
411 DPRINT("Failing create request with status %x\n", Status
);
412 ZwClose (*FileHandle
);
416 assert_irql(PASSIVE_LEVEL
);
418 DPRINT("Finished IoCreateFile() (*FileHandle) %x\n", (*FileHandle
));
424 /**********************************************************************
429 * Entry point to call IoCreateFile with
430 * default parameters.
440 * Code originally in NtCreateFile moved in IoCreateFile.
446 ACCESS_MASK DesiredAccess
,
447 POBJECT_ATTRIBUTES ObjectAttributes
,
448 PIO_STATUS_BLOCK IoStatusBlock
,
449 PLARGE_INTEGER AllocateSize
,
450 ULONG FileAttributes
,
452 ULONG CreateDisposition
,
458 return IoCreateFile (
470 0, /* CreateFileType */
471 NULL
, /* ExtraCreateParameters */
478 /**********************************************************************
483 * Opens a file (simpler than NtCreateFile).
487 * Variable that receives the file handle on return;
490 * Access desired by the caller to the file;
493 * Structue describing the file to be opened;
495 * IoStatusBlock (OUT)
496 * Receives details about the result of the
500 * Type of shared access the caller requires;
503 * Options for the file open.
515 ACCESS_MASK DesiredAccess
,
516 POBJECT_ATTRIBUTES ObjectAttributes
,
517 PIO_STATUS_BLOCK IoStatusBlock
,
522 return IoCreateFile (
534 0, /* CreateFileType */
535 NULL
, /* ExtraCreateParameters */