2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/io/create.c
5 * PURPOSE: Handling file create/open apis
6 * PROGRAMMER: David Welch (welch@cwcom.net)
11 /* INCLUDES ***************************************************************/
13 #include <ddk/ntddk.h>
14 #include <internal/ob.h>
15 #include <internal/io.h>
16 #include <internal/id.h>
17 #include <internal/string.h>
20 #include <internal/debug.h>
22 /* FUNCTIONS *************************************************************/
24 NTSTATUS STDCALL
NtDeleteFile(IN POBJECT_ATTRIBUTES ObjectAttributes
)
33 OUT PHANDLE FileHandle
,
34 IN ACCESS_MASK DesiredAccess
,
35 IN POBJECT_ATTRIBUTES ObjectAttributes
,
36 OUT PIO_STATUS_BLOCK IoStatusBlock
,
37 IN PLARGE_INTEGER AllocationSize OPTIONAL
,
38 IN ULONG FileAttributes
,
40 IN ULONG CreateDisposition
,
41 IN ULONG CreateOptions
,
42 IN PVOID EaBuffer OPTIONAL
,
44 IN CREATE_FILE_TYPE CreateFileType
,
45 IN ULONG ExtraCreateParameters
,
53 NTSTATUS
IopCreateFile(PVOID ObjectBody
,
56 POBJECT_ATTRIBUTES ObjectAttributes
)
58 PDEVICE_OBJECT DeviceObject
= (PDEVICE_OBJECT
)Parent
;
59 PFILE_OBJECT FileObject
= (PFILE_OBJECT
)ObjectBody
;
62 DPRINT("IopCreateFile(ObjectBody %x, Parent %x, RemainingPath %S)\n",
63 ObjectBody
,Parent
,RemainingPath
);
65 if (DeviceObject
== NULL
)
67 DPRINT("DeviceObject was NULL\n");
68 return(STATUS_SUCCESS
);
70 if( BODY_TO_HEADER( Parent
)->ObjectType
!= IoDeviceType
)
72 DPRINT( "Parent is not a device type\n" );
73 return STATUS_UNSUCCESSFUL
;
75 Status
= ObReferenceObjectByPointer(DeviceObject
,
76 STANDARD_RIGHTS_REQUIRED
,
79 if (Status
!= STATUS_SUCCESS
)
85 DeviceObject
= IoGetAttachedDevice(DeviceObject
);
87 DPRINT("DeviceObject %x\n",DeviceObject
);
89 if (RemainingPath
== NULL
)
91 FileObject
->Flags
= FileObject
->Flags
| FO_DIRECT_DEVICE_OPEN
;
92 FileObject
->FileName
.Buffer
= ExAllocatePool(NonPagedPool
,
93 (ObjectAttributes
->ObjectName
->Length
+1)*2);
94 FileObject
->FileName
.Length
= ObjectAttributes
->ObjectName
->Length
;
95 FileObject
->FileName
.MaximumLength
=
96 ObjectAttributes
->ObjectName
->MaximumLength
;
97 RtlCopyUnicodeString(&(FileObject
->FileName
),
98 ObjectAttributes
->ObjectName
);
102 if (DeviceObject
->DeviceType
!= FILE_DEVICE_FILE_SYSTEM
&&
103 DeviceObject
->DeviceType
!= FILE_DEVICE_DISK
)
105 DPRINT("Device was wrong type\n");
106 return(STATUS_UNSUCCESSFUL
);
108 if (!(DeviceObject
->Vpb
->Flags
& VPB_MOUNTED
))
110 DPRINT("Trying to mount storage device\n");
111 Status
= IoTryToMountStorageDevice(DeviceObject
);
112 DPRINT("Status %x\n", Status
);
113 if (!NT_SUCCESS(Status
))
115 DPRINT("Failed to mount storage device (statux %x)\n",
119 DeviceObject
= IoGetAttachedDevice(DeviceObject
);
121 RtlInitUnicodeString(&(FileObject
->FileName
),wcsdup(RemainingPath
));
123 DPRINT("FileObject->FileName.Buffer %S\n",FileObject
->FileName
.Buffer
);
124 FileObject
->DeviceObject
= DeviceObject
;
125 DPRINT("FileObject %x DeviceObject %x\n", FileObject
, DeviceObject
);
126 FileObject
->Vpb
= DeviceObject
->Vpb
;
127 FileObject
->Type
= InternalFileType
;
129 return(STATUS_SUCCESS
);
132 PFILE_OBJECT
IoCreateStreamFileObject(PFILE_OBJECT FileObject
,
133 PDEVICE_OBJECT DeviceObject
)
136 PFILE_OBJECT CreatedFileObject
;
138 DbgPrint("IoCreateStreamFileObject(FileObject %x, DeviceObject %x)\n",
139 FileObject
, DeviceObject
);
141 assert_irql(PASSIVE_LEVEL
);
143 CreatedFileObject
= ObCreateObject(&FileHandle
,
144 STANDARD_RIGHTS_REQUIRED
,
147 if (CreatedFileObject
== NULL
)
152 if (FileObject
!= NULL
)
154 DeviceObject
= FileObject
->DeviceObject
;
156 DeviceObject
= IoGetAttachedDevice(DeviceObject
);
157 CreatedFileObject
->DeviceObject
= DeviceObject
;
158 CreatedFileObject
->Vpb
= DeviceObject
->Vpb
;
159 CreatedFileObject
->Type
= InternalFileType
;
160 CreatedFileObject
->Flags
= CreatedFileObject
->Flags
| FO_DIRECT_DEVICE_OPEN
;
164 return(CreatedFileObject
);
171 ACCESS_MASK DesiredAccess
,
172 POBJECT_ATTRIBUTES ObjectAttributes
,
173 PIO_STATUS_BLOCK IoStatusBlock
,
174 PLARGE_INTEGER AllocateSize
,
175 ULONG FileAttributes
,
177 ULONG CreateDisposition
,
183 * FUNCTION: Either causes a new file or directory to be created, or it opens
184 * an existing file, device, directory or volume, giving the caller a handle
185 * for the file object. This handle can be used by subsequent calls to
186 * manipulate data within the file or the file object's state of attributes.
188 * FileHandle (OUT) = Points to a variable which receives the file
190 * DesiredAccess = Desired access to the file
191 * ObjectAttributes = Structure describing the file
192 * IoStatusBlock (OUT) = Receives information about the operation on
194 * AllocationSize = Initial size of the file in bytes
195 * FileAttributes = Attributes to create the file with
196 * ShareAccess = Type of shared access the caller would like to the file
197 * CreateDisposition = Specifies what to do, depending on whether the
198 * file already exists
199 * CreateOptions = Options for creating a new file
200 * EaBuffer = Undocumented
201 * EaLength = Undocumented
205 PFILE_OBJECT FileObject
;
209 PIO_STACK_LOCATION StackLoc
;
211 DPRINT("NtCreateFile(FileHandle %x, DesiredAccess %x, "
212 "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
213 FileHandle
,DesiredAccess
,ObjectAttributes
,
214 ObjectAttributes
->ObjectName
->Buffer
);
216 assert_irql(PASSIVE_LEVEL
);
220 FileObject
= ObCreateObject(FileHandle
,
224 if (FileObject
== NULL
)
226 return(STATUS_UNSUCCESSFUL
);
229 if (CreateOptions
& FILE_SYNCHRONOUS_IO_ALERT
)
231 FileObject
->Flags
= FileObject
->Flags
| FO_ALERTABLE_IO
;
232 FileObject
->Flags
= FileObject
->Flags
| FO_SYNCHRONOUS_IO
;
234 if (CreateOptions
& FILE_SYNCHRONOUS_IO_NONALERT
)
236 FileObject
->Flags
= FileObject
->Flags
| FO_SYNCHRONOUS_IO
;
239 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
241 DPRINT("FileObject %x\n", FileObject
);
242 DPRINT("FileObject->DeviceObject %x\n", FileObject
->DeviceObject
);
243 Irp
= IoAllocateIrp(FileObject
->DeviceObject
->StackSize
, FALSE
);
246 return(STATUS_UNSUCCESSFUL
);
249 StackLoc
= IoGetNextIrpStackLocation(Irp
);
250 StackLoc
->MajorFunction
= IRP_MJ_CREATE
;
251 StackLoc
->MinorFunction
= 0;
253 StackLoc
->Control
= 0;
254 StackLoc
->DeviceObject
= FileObject
->DeviceObject
;
255 StackLoc
->FileObject
= FileObject
;
256 StackLoc
->Parameters
.Create
.Options
= CreateOptions
&FILE_VALID_OPTION_FLAGS
;
257 StackLoc
->Parameters
.Create
.Options
|= CreateDisposition
<<24;
259 Status
= IoCallDriver(FileObject
->DeviceObject
,Irp
);
260 if (Status
== STATUS_PENDING
)
262 KeWaitForSingleObject(&Event
,Executive
,KernelMode
,FALSE
,NULL
);
263 Status
= IoStatusBlock
->Status
;
266 if (!NT_SUCCESS(Status
))
268 DPRINT("Failing create request with status %x\n",Status
);
269 ZwClose(*FileHandle
);
273 assert_irql(PASSIVE_LEVEL
);
274 DPRINT("Finished NtCreateFile() (*FileHandle) %x\n",(*FileHandle
));
279 NTSTATUS STDCALL
NtOpenFile(PHANDLE FileHandle
,
280 ACCESS_MASK DesiredAccess
,
281 POBJECT_ATTRIBUTES ObjectAttributes
,
282 PIO_STATUS_BLOCK IoStatusBlock
,
286 * FUNCTION: Opens a file (simpler than ZwCreateFile)
288 * FileHandle (OUT) = Variable that receives the file handle on return
289 * DesiredAccess = Access desired by the caller to the file
290 * ObjectAttributes = Structue describing the file to be opened
291 * IoStatusBlock (OUT) = Receives details about the result of the
293 * ShareAccess = Type of shared access the caller requires
294 * OpenOptions = Options for the file open
299 return(ZwCreateFile(FileHandle
,