f0bd7eec933200fd1440a6fc8427e6fe0239aad2
[reactos.git] / reactos / ntoskrnl / io / create.c
1 /*
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)
7 * UPDATE HISTORY:
8 * 24/05/98: Created
9 */
10
11 /* INCLUDES ***************************************************************/
12
13 #include <wchar.h>
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>
19
20 #define NDEBUG
21 #include <internal/debug.h>
22
23 /* FUNCTIONS *************************************************************/
24
25 NTSTATUS STDCALL NtDeleteFile(IN POBJECT_ATTRIBUTES ObjectAttributes)
26 {
27 return(ZwDeleteFile(ObjectAttributes));
28 }
29
30 NTSTATUS STDCALL ZwDeleteFile(IN POBJECT_ATTRIBUTES ObjectAttributes)
31 {
32 UNIMPLEMENTED;
33 }
34
35 NTSTATUS STDCALL NtCreateFile(PHANDLE FileHandle,
36 ACCESS_MASK DesiredAccess,
37 POBJECT_ATTRIBUTES ObjectAttributes,
38 PIO_STATUS_BLOCK IoStatusBlock,
39 PLARGE_INTEGER AllocateSize,
40 ULONG FileAttributes,
41 ULONG ShareAccess,
42 ULONG CreateDisposition,
43 ULONG CreateOptions,
44 PVOID EaBuffer,
45 ULONG EaLength)
46 {
47 return(ZwCreateFile(FileHandle,
48 DesiredAccess,
49 ObjectAttributes,
50 IoStatusBlock,
51 AllocateSize,
52 FileAttributes,
53 ShareAccess,
54 CreateDisposition,
55 CreateOptions,
56 EaBuffer,
57 EaLength));
58 }
59
60 NTSTATUS IopCreateFile(PVOID ObjectBody,
61 PVOID Parent,
62 PWSTR RemainingPath,
63 POBJECT_ATTRIBUTES ObjectAttributes)
64 {
65 PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)Parent;
66 PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
67 NTSTATUS Status;
68
69 DPRINT("IopCreateFile(ObjectBody %x, Parent %x, RemainingPath %w)\n",
70 ObjectBody,Parent,RemainingPath);
71
72 if (DeviceObject == NULL)
73 {
74 return(STATUS_SUCCESS);
75 }
76
77 Status = ObReferenceObjectByPointer(DeviceObject,
78 STANDARD_RIGHTS_REQUIRED,
79 IoDeviceType,
80 UserMode);
81 if (Status != STATUS_SUCCESS)
82 {
83 CHECKPOINT;
84 return(Status);
85 }
86
87 DeviceObject = IoGetAttachedDevice(DeviceObject);
88
89 DPRINT("DeviceObject %x\n",DeviceObject);
90
91 if (RemainingPath == NULL)
92 {
93 FileObject->Flags = FileObject->Flags | FO_DIRECT_DEVICE_OPEN;
94 FileObject->FileName.Buffer = ExAllocatePool(NonPagedPool,
95 (ObjectAttributes->ObjectName->Length+1)*2);
96 FileObject->FileName.Length = ObjectAttributes->ObjectName->Length;
97 FileObject->FileName.MaximumLength =
98 ObjectAttributes->ObjectName->MaximumLength;
99 RtlCopyUnicodeString(&(FileObject->FileName),
100 ObjectAttributes->ObjectName);
101 }
102 else
103 {
104 if (DeviceObject->DeviceType != FILE_DEVICE_FILE_SYSTEM &&
105 DeviceObject->DeviceType != FILE_DEVICE_DISK)
106 {
107 return(STATUS_UNSUCCESSFUL);
108 }
109 if (!(DeviceObject->Vpb->Flags & VPB_MOUNTED))
110 {
111 Status = IoTryToMountStorageDevice(DeviceObject);
112 if (Status!=STATUS_SUCCESS)
113 {
114 return(Status);
115 }
116 DeviceObject = IoGetAttachedDevice(DeviceObject);
117 }
118 RtlInitUnicodeString(&(FileObject->FileName),wcsdup(RemainingPath));
119 }
120 DPRINT("FileObject->FileName.Buffer %w\n",FileObject->FileName.Buffer);
121 FileObject->DeviceObject = DeviceObject;
122 FileObject->Vpb = DeviceObject->Vpb;
123 FileObject->Type = ID_FILE_OBJECT;
124
125 return(STATUS_SUCCESS);
126 }
127
128 PFILE_OBJECT IoCreateStreamFileObject(PFILE_OBJECT FileObject,
129 PDEVICE_OBJECT DeviceObject)
130 {
131 HANDLE FileHandle;
132 PFILE_OBJECT CreatedFileObject;
133
134 DbgPrint("IoCreateStreamFileObject(FileObject %x, DeviceObject %x)\n",
135 FileObject, DeviceObject);
136
137 assert_irql(PASSIVE_LEVEL);
138
139 CreatedFileObject = ObCreateObject(&FileHandle,
140 STANDARD_RIGHTS_REQUIRED,
141 NULL,
142 IoFileType);
143 if (CreatedFileObject == NULL)
144 {
145 return(NULL);
146 }
147
148 if (FileObject != NULL)
149 {
150 DeviceObject = FileObject->DeviceObject;
151 }
152 DeviceObject = IoGetAttachedDevice(DeviceObject);
153 CreatedFileObject->DeviceObject = DeviceObject;
154 CreatedFileObject->Vpb = DeviceObject->Vpb;
155 CreatedFileObject->Type = ID_FILE_OBJECT;
156 CreatedFileObject->Flags = CreatedFileObject->Flags | FO_DIRECT_DEVICE_OPEN;
157
158 ZwClose(FileHandle);
159
160 return(CreatedFileObject);
161 }
162
163 NTSTATUS STDCALL ZwCreateFile(PHANDLE FileHandle,
164 ACCESS_MASK DesiredAccess,
165 POBJECT_ATTRIBUTES ObjectAttributes,
166 PIO_STATUS_BLOCK IoStatusBlock,
167 PLARGE_INTEGER AllocateSize,
168 ULONG FileAttributes,
169 ULONG ShareAccess,
170 ULONG CreateDisposition,
171 ULONG CreateOptions,
172 PVOID EaBuffer,
173 ULONG EaLength)
174 /*
175 * FUNCTION: Either causes a new file or directory to be created, or it opens
176 * an existing file, device, directory or volume, giving the caller a handle
177 * for the file object. This handle can be used by subsequent calls to
178 * manipulate data within the file or the file object's state of attributes.
179 * ARGUMENTS:
180 * FileHandle (OUT) = Points to a variable which receives the file
181 * handle on return
182 * DesiredAccess = Desired access to the file
183 * ObjectAttributes = Structure describing the file
184 * IoStatusBlock (OUT) = Receives information about the operation on
185 * return
186 * AllocationSize = Initial size of the file in bytes
187 * FileAttributes = Attributes to create the file with
188 * ShareAccess = Type of shared access the caller would like to the file
189 * CreateDisposition = Specifies what to do, depending on whether the
190 * file already exists
191 * CreateOptions = Options for creating a new file
192 * EaBuffer = Undocumented
193 * EaLength = Undocumented
194 * RETURNS: Status
195 */
196 {
197 PFILE_OBJECT FileObject;
198 NTSTATUS Status;
199 PIRP Irp;
200 KEVENT Event;
201 PIO_STACK_LOCATION StackLoc;
202
203 DPRINT("ZwCreateFile(FileHandle %x, DesiredAccess %x, "
204 "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %w)\n",
205 FileHandle,DesiredAccess,ObjectAttributes,
206 ObjectAttributes->ObjectName->Buffer);
207
208 assert_irql(PASSIVE_LEVEL);
209
210 *FileHandle=0;
211
212 FileObject = ObCreateObject(FileHandle,
213 DesiredAccess,
214 ObjectAttributes,
215 IoFileType);
216 if (FileObject == NULL)
217 {
218 return(STATUS_UNSUCCESSFUL);
219 }
220
221 if (CreateOptions & FILE_SYNCHRONOUS_IO_ALERT)
222 {
223 FileObject->Flags = FileObject->Flags | FO_ALERTABLE_IO;
224 FileObject->Flags = FileObject->Flags | FO_SYNCHRONOUS_IO;
225 }
226 if (CreateOptions & FILE_SYNCHRONOUS_IO_NONALERT)
227 {
228 FileObject->Flags = FileObject->Flags | FO_SYNCHRONOUS_IO;
229 }
230
231 KeInitializeEvent(&Event, NotificationEvent, FALSE);
232
233 Irp = IoAllocateIrp(FileObject->DeviceObject->StackSize, FALSE);
234 if (Irp==NULL)
235 {
236 return(STATUS_UNSUCCESSFUL);
237 }
238
239 StackLoc = IoGetNextIrpStackLocation(Irp);
240 StackLoc->MajorFunction = IRP_MJ_CREATE;
241 StackLoc->MinorFunction = 0;
242 StackLoc->Flags = 0;
243 StackLoc->Control = 0;
244 StackLoc->DeviceObject = FileObject->DeviceObject;
245 StackLoc->FileObject = FileObject;
246 StackLoc->Parameters.Create.Options = CreateOptions&FILE_VALID_OPTION_FLAGS;
247 StackLoc->Parameters.Create.Options |= CreateDisposition<<24;
248
249 Status = IoCallDriver(FileObject->DeviceObject,Irp);
250 if (Status == STATUS_PENDING)
251 {
252 KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL);
253 Status = IoStatusBlock->Status;
254 }
255
256 if (!NT_SUCCESS(Status))
257 {
258 DPRINT("Failing create request with status %x\n",Status);
259 ZwClose(*FileHandle);
260 (*FileHandle) = 0;
261 }
262
263 assert_irql(PASSIVE_LEVEL);
264 DPRINT("Finished ZwCreateFile() (*FileHandle) %x\n",(*FileHandle));
265 return(Status);
266 }
267
268 NTSTATUS STDCALL NtOpenFile(PHANDLE FileHandle,
269 ACCESS_MASK DesiredAccess,
270 POBJECT_ATTRIBUTES ObjectAttributes,
271 PIO_STATUS_BLOCK IoStatusBlock,
272 ULONG ShareAccess,
273 ULONG OpenOptions)
274 {
275 return(ZwOpenFile(FileHandle,
276 DesiredAccess,
277 ObjectAttributes,
278 IoStatusBlock,
279 ShareAccess,
280 OpenOptions));
281 }
282
283 NTSTATUS STDCALL ZwOpenFile(PHANDLE FileHandle,
284 ACCESS_MASK DesiredAccess,
285 POBJECT_ATTRIBUTES ObjectAttributes,
286 PIO_STATUS_BLOCK IoStatusBlock,
287 ULONG ShareAccess,
288 ULONG OpenOptions)
289 /*
290 * FUNCTION: Opens a file (simpler than ZwCreateFile)
291 * ARGUMENTS:
292 * FileHandle (OUT) = Variable that receives the file handle on return
293 * DesiredAccess = Access desired by the caller to the file
294 * ObjectAttributes = Structue describing the file to be opened
295 * IoStatusBlock (OUT) = Receives details about the result of the
296 * operation
297 * ShareAccess = Type of shared access the caller requires
298 * OpenOptions = Options for the file open
299 * RETURNS: Status
300 * NOTE: Undocumented
301 */
302 {
303 return(ZwCreateFile(FileHandle,
304 DesiredAccess,
305 ObjectAttributes,
306 IoStatusBlock,
307 NULL,
308 0,
309 ShareAccess,
310 FILE_OPEN,
311 OpenOptions,
312 NULL,
313 0));
314 }
315
316