Removed the assertion
[reactos.git] / reactos / ntoskrnl / io / create.c
1 /* $Id: create.c,v 1.42 2001/05/13 13:35:37 chorns Exp $
2 *
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)
8 * UPDATE HISTORY:
9 * 24/05/98: Created
10 */
11
12 /* INCLUDES ***************************************************************/
13
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>
19
20 #define NDEBUG
21 #include <internal/debug.h>
22
23 /* GLOBALS *******************************************************************/
24
25 #define TAG_FILE_NAME TAG('F', 'N', 'A', 'M')
26
27 /* FUNCTIONS *************************************************************/
28
29 /**********************************************************************
30 * NAME EXPORTED
31 * NtDeleteFile@4
32 *
33 * DESCRIPTION
34 *
35 * ARGUMENTS
36 * ObjectAttributes
37 * ?
38 *
39 * RETURN VALUE
40 *
41 * REVISIONS
42 *
43 */
44 NTSTATUS STDCALL
45 NtDeleteFile (IN POBJECT_ATTRIBUTES ObjectAttributes)
46 {
47 UNIMPLEMENTED;
48 }
49
50
51 /**********************************************************************
52 * NAME INTERNAL
53 * IopCreateFile
54 *
55 * DESCRIPTION
56 *
57 * ARGUMENTS
58 *
59 * RETURN VALUE
60 *
61 * REVISIONS
62 *
63 */
64 NTSTATUS
65 IopCreateFile (PVOID ObjectBody,
66 PVOID Parent,
67 PWSTR RemainingPath,
68 POBJECT_ATTRIBUTES ObjectAttributes)
69 {
70 PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT) Parent;
71 PFILE_OBJECT FileObject = (PFILE_OBJECT) ObjectBody;
72 NTSTATUS Status;
73
74 DPRINT("IopCreateFile(ObjectBody %x, Parent %x, RemainingPath %S)\n",
75 ObjectBody,
76 Parent,
77 RemainingPath);
78
79 if (NULL == DeviceObject)
80 {
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);
85 }
86 if (IoDeviceObjectType != BODY_TO_HEADER(Parent)->ObjectType)
87 {
88 CPRINT("Parent is a %S which not a device type\n",
89 BODY_TO_HEADER(Parent)->ObjectType->TypeName.Buffer);
90 return (STATUS_UNSUCCESSFUL);
91 }
92 Status = ObReferenceObjectByPointer (DeviceObject,
93 STANDARD_RIGHTS_REQUIRED,
94 IoDeviceObjectType,
95 UserMode);
96 if (STATUS_SUCCESS != Status)
97 {
98 CHECKPOINT1;
99 return (Status);
100 }
101
102 DeviceObject = IoGetAttachedDevice (DeviceObject);
103
104 DPRINT("DeviceObject %x\n", DeviceObject);
105
106 if (NULL == RemainingPath)
107 {
108 FileObject->Flags = FileObject->Flags | FO_DIRECT_DEVICE_OPEN;
109 FileObject->FileName.Buffer =
110 ExAllocatePoolWithTag(NonPagedPool,
111 (ObjectAttributes->ObjectName->Length+1)*2,
112 TAG_FILE_NAME);
113 FileObject->FileName.Length = ObjectAttributes->ObjectName->Length;
114 FileObject->FileName.MaximumLength =
115 ObjectAttributes->ObjectName->MaximumLength;
116 RtlCopyUnicodeString(&(FileObject->FileName),
117 ObjectAttributes->ObjectName);
118 }
119 else
120 {
121 if ((DeviceObject->DeviceType != FILE_DEVICE_FILE_SYSTEM)
122 && (DeviceObject->DeviceType != FILE_DEVICE_DISK)
123 && (DeviceObject->DeviceType != FILE_DEVICE_NETWORK)
124 && (DeviceObject->DeviceType != FILE_DEVICE_NAMED_PIPE)
125 && (DeviceObject->DeviceType != FILE_DEVICE_MAILSLOT))
126 {
127 CPRINT ("Device was wrong type\n");
128 assert(FALSE);
129 return (STATUS_UNSUCCESSFUL);
130 }
131
132 if (DeviceObject->DeviceType != FILE_DEVICE_NETWORK
133 && (DeviceObject->DeviceType != FILE_DEVICE_NAMED_PIPE)
134 && (DeviceObject->DeviceType != FILE_DEVICE_MAILSLOT))
135 {
136 if (!(DeviceObject->Vpb->Flags & VPB_MOUNTED))
137 {
138 DPRINT("Trying to mount storage device\n");
139 Status = IoTryToMountStorageDevice (DeviceObject);
140 DPRINT("Status %x\n", Status);
141 if (!NT_SUCCESS(Status))
142 {
143 CPRINT("Failed to mount storage device (statux %x)\n",
144 Status);
145 return (Status);
146 }
147 DeviceObject = IoGetAttachedDevice(DeviceObject);
148 }
149 }
150 RtlCreateUnicodeString(&(FileObject->FileName),
151 RemainingPath);
152 }
153 DPRINT("FileObject->FileName.Buffer %S\n",
154 FileObject->FileName.Buffer);
155 FileObject->DeviceObject = DeviceObject;
156 DPRINT("FileObject %x DeviceObject %x\n",
157 FileObject,
158 DeviceObject);
159 FileObject->Vpb = DeviceObject->Vpb;
160 FileObject->Type = InternalFileType;
161
162 return (STATUS_SUCCESS);
163 }
164
165
166 /**********************************************************************
167 * NAME EXPORTED
168 * IoCreateStreamFileObject@8
169 *
170 * DESCRIPTION
171 *
172 * ARGUMENTS
173 * FileObject
174 * ?
175 *
176 * DeviceObject
177 * ?
178 *
179 * RETURN VALUE
180 *
181 * NOTE
182 *
183 * REVISIONS
184 *
185 */
186 PFILE_OBJECT STDCALL
187 IoCreateStreamFileObject(PFILE_OBJECT FileObject,
188 PDEVICE_OBJECT DeviceObject)
189 {
190 HANDLE FileHandle;
191 PFILE_OBJECT CreatedFileObject;
192
193 DPRINT("IoCreateStreamFileObject(FileObject %x, DeviceObject %x)\n",
194 FileObject, DeviceObject);
195
196 assert_irql (PASSIVE_LEVEL);
197
198 CreatedFileObject = ObCreateObject (&FileHandle,
199 STANDARD_RIGHTS_REQUIRED,
200 NULL,
201 IoFileObjectType);
202 if (NULL == CreatedFileObject)
203 {
204 DPRINT("Could not create FileObject\n");
205 return (NULL);
206 }
207
208 if (FileObject != NULL)
209 {
210 DeviceObject = FileObject->DeviceObject;
211 }
212 DeviceObject = IoGetAttachedDevice(DeviceObject);
213
214 DPRINT("DeviceObject %x\n", DeviceObject);
215
216 CreatedFileObject->DeviceObject = DeviceObject;
217 CreatedFileObject->Vpb = DeviceObject->Vpb;
218 CreatedFileObject->Type = InternalFileType;
219 CreatedFileObject->Flags |= FO_DIRECT_DEVICE_OPEN;
220
221 ZwClose (FileHandle);
222
223 return (CreatedFileObject);
224 }
225
226
227 /**********************************************************************
228 * NAME EXPORTED
229 * IoCreateFile@56
230 *
231 * DESCRIPTION
232 * Either causes a new file or directory to be created, or it
233 * opens an existing file, device, directory or volume, giving
234 * the caller a handle for the file object. This handle can be
235 * used by subsequent calls to manipulate data within the file
236 * or the file object's state of attributes.
237 *
238 * ARGUMENTS
239 * FileHandle (OUT)
240 * Points to a variable which receives the file handle
241 * on return;
242 *
243 * DesiredAccess
244 * Desired access to the file;
245 *
246 * ObjectAttributes
247 * Structure describing the file;
248 *
249 * IoStatusBlock (OUT)
250 * Receives information about the operation on return;
251 *
252 * AllocationSize [OPTIONAL]
253 * Initial size of the file in bytes;
254 *
255 * FileAttributes
256 * Attributes to create the file with;
257 *
258 * ShareAccess
259 * Type of shared access the caller would like to the
260 * file;
261 *
262 * CreateDisposition
263 * Specifies what to do, depending on whether the
264 * file already exists;
265 *
266 * CreateOptions
267 * Options for creating a new file;
268 *
269 * EaBuffer [OPTIONAL]
270 * Undocumented;
271 *
272 * EaLength
273 * Undocumented;
274 *
275 * CreateFileType
276 * Type of file (normal, named pipe, mailslot) to create;
277 *
278 * ExtraCreateParameters [OPTIONAL]
279 * Additional creation data for named pipe and mailsots;
280 *
281 * Options
282 * Undocumented.
283 *
284 * RETURN VALUE
285 * Status
286 *
287 * NOTE
288 * Prototype taken from Bo Branten's ntifs.h v15.
289 * Description taken from old NtCreateFile's which is
290 * now a wrapper of this call.
291 *
292 * REVISIONS
293 *
294 */
295 NTSTATUS STDCALL
296 IoCreateFile(
297 OUT PHANDLE FileHandle,
298 IN ACCESS_MASK DesiredAccess,
299 IN POBJECT_ATTRIBUTES ObjectAttributes,
300 OUT PIO_STATUS_BLOCK IoStatusBlock,
301 IN PLARGE_INTEGER AllocationSize OPTIONAL,
302 IN ULONG FileAttributes,
303 IN ULONG ShareAccess,
304 IN ULONG CreateDisposition,
305 IN ULONG CreateOptions,
306 IN PVOID EaBuffer OPTIONAL,
307 IN ULONG EaLength,
308 IN CREATE_FILE_TYPE CreateFileType,
309 IN PVOID ExtraCreateParameters OPTIONAL,
310 IN ULONG Options)
311 {
312 PFILE_OBJECT FileObject;
313 NTSTATUS Status;
314 PIRP Irp;
315 KEVENT Event;
316 PIO_STACK_LOCATION StackLoc;
317
318 DPRINT("IoCreateFile(FileHandle %x, DesiredAccess %x, "
319 "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
320 FileHandle,DesiredAccess,ObjectAttributes,
321 ObjectAttributes->ObjectName->Buffer);
322
323 assert_irql(PASSIVE_LEVEL);
324
325 *FileHandle = 0;
326
327 FileObject = ObCreateObject(FileHandle,
328 DesiredAccess,
329 ObjectAttributes,
330 IoFileObjectType);
331 if (FileObject == NULL)
332 {
333 DPRINT1("ObCreateObject() failed!\n");
334 return (STATUS_UNSUCCESSFUL);
335 }
336 if (CreateOptions & FILE_SYNCHRONOUS_IO_ALERT)
337 {
338 FileObject->Flags |= (FO_ALERTABLE_IO | FO_SYNCHRONOUS_IO);
339 }
340 if (CreateOptions & FILE_SYNCHRONOUS_IO_NONALERT)
341 {
342 FileObject->Flags |= FO_SYNCHRONOUS_IO;
343 }
344 KeInitializeEvent(&FileObject->Lock, NotificationEvent, TRUE);
345 KeInitializeEvent(&Event, NotificationEvent, FALSE);
346
347 DPRINT("FileObject %x\n", FileObject);
348 DPRINT("FileObject->DeviceObject %x\n", FileObject->DeviceObject);
349 /*
350 * Create a new IRP to hand to
351 * the FS driver: this may fail
352 * due to resource shortage.
353 */
354 Irp = IoAllocateIrp(FileObject->DeviceObject->StackSize, FALSE);
355 if (Irp == NULL)
356 {
357 return (STATUS_UNSUCCESSFUL);
358 }
359
360 Irp->AssociatedIrp.SystemBuffer = EaBuffer;
361 Irp->Tail.Overlay.AuxiliaryBuffer = (PCHAR)ExtraCreateParameters;
362
363 /*
364 * Get the stack location for the new
365 * IRP and prepare it.
366 */
367 StackLoc = IoGetNextIrpStackLocation(Irp);
368 switch (CreateFileType)
369 {
370 default:
371 case CreateFileTypeNone:
372 StackLoc->MajorFunction = IRP_MJ_CREATE;
373 break;
374
375 case CreateFileTypeNamedPipe:
376 StackLoc->MajorFunction = IRP_MJ_CREATE_NAMED_PIPE;
377 break;
378
379 case CreateFileTypeMailslot:
380 StackLoc->MajorFunction = IRP_MJ_CREATE_MAILSLOT;
381 break;
382 }
383 StackLoc->MinorFunction = 0;
384 StackLoc->Flags = 0;
385 StackLoc->Control = 0;
386 StackLoc->DeviceObject = FileObject->DeviceObject;
387 StackLoc->FileObject = FileObject;
388 StackLoc->Parameters.Create.Options = (CreateOptions & FILE_VALID_OPTION_FLAGS);
389 StackLoc->Parameters.Create.Options |= (CreateDisposition << 24);
390
391 /*
392 * Now call the driver and
393 * possibly wait if it can
394 * not complete the request
395 * immediately.
396 */
397 Status = IofCallDriver(FileObject->DeviceObject, Irp );
398 if (Status == STATUS_PENDING)
399 {
400 KeWaitForSingleObject(&Event,
401 Executive,
402 KernelMode,
403 FALSE,
404 NULL);
405 Status = IoStatusBlock->Status;
406 }
407 if (!NT_SUCCESS(Status))
408 {
409 DPRINT1("Failing create request with status %x\n", Status);
410 ZwClose(*FileHandle);
411 (*FileHandle) = 0;
412 }
413
414 assert_irql(PASSIVE_LEVEL);
415
416 DPRINT("Finished IoCreateFile() (*FileHandle) %x\n", (*FileHandle));
417
418 return (Status);
419 }
420
421
422 /**********************************************************************
423 * NAME EXPORTED
424 * NtCreateFile@44
425 *
426 * DESCRIPTION
427 * Entry point to call IoCreateFile with
428 * default parameters.
429 *
430 * ARGUMENTS
431 * See IoCreateFile.
432 *
433 * RETURN VALUE
434 * See IoCreateFile.
435 *
436 * REVISIONS
437 * 2000-03-25 (ea)
438 * Code originally in NtCreateFile moved in IoCreateFile.
439 */
440 NTSTATUS STDCALL
441 NtCreateFile(PHANDLE FileHandle,
442 ACCESS_MASK DesiredAccess,
443 POBJECT_ATTRIBUTES ObjectAttributes,
444 PIO_STATUS_BLOCK IoStatusBlock,
445 PLARGE_INTEGER AllocateSize,
446 ULONG FileAttributes,
447 ULONG ShareAccess,
448 ULONG CreateDisposition,
449 ULONG CreateOptions,
450 PVOID EaBuffer,
451 ULONG EaLength)
452 {
453 return IoCreateFile(FileHandle,
454 DesiredAccess,
455 ObjectAttributes,
456 IoStatusBlock,
457 AllocateSize,
458 FileAttributes,
459 ShareAccess,
460 CreateDisposition,
461 CreateOptions,
462 EaBuffer,
463 EaLength,
464 CreateFileTypeNone,
465 NULL,
466 0);
467 }
468
469
470 /**********************************************************************
471 * NAME EXPORTED
472 * NtOpenFile@24
473 *
474 * DESCRIPTION
475 * Opens an existing file (simpler than NtCreateFile).
476 *
477 * ARGUMENTS
478 * FileHandle (OUT)
479 * Variable that receives the file handle on return;
480 *
481 * DesiredAccess
482 * Access desired by the caller to the file;
483 *
484 * ObjectAttributes
485 * Structue describing the file to be opened;
486 *
487 * IoStatusBlock (OUT)
488 * Receives details about the result of the
489 * operation;
490 *
491 * ShareAccess
492 * Type of shared access the caller requires;
493 *
494 * OpenOptions
495 * Options for the file open.
496 *
497 * RETURN VALUE
498 * Status.
499 *
500 * NOTE
501 * Undocumented.
502 */
503 NTSTATUS STDCALL
504 NtOpenFile(PHANDLE FileHandle,
505 ACCESS_MASK DesiredAccess,
506 POBJECT_ATTRIBUTES ObjectAttributes,
507 PIO_STATUS_BLOCK IoStatusBlock,
508 ULONG ShareAccess,
509 ULONG OpenOptions)
510 {
511 return IoCreateFile(FileHandle,
512 DesiredAccess,
513 ObjectAttributes,
514 IoStatusBlock,
515 NULL,
516 0,
517 ShareAccess,
518 FILE_OPEN,
519 OpenOptions,
520 NULL,
521 0,
522 CreateFileTypeNone,
523 NULL,
524 0);
525 }
526
527 /* EOF */