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