1 /* $Id: file.c,v 1.34 2004/08/21 20:51:26 tamlin Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/file.c
6 * PURPOSE: Graceful system shutdown if a bug is detected
7 * PROGRAMMER: David Welch (welch@mcmail.com)
12 /* INCLUDES *****************************************************************/
16 #include <internal/debug.h>
19 /* GLOBALS *******************************************************************/
21 #define TAG_SYSB TAG('S', 'Y', 'S', 'B')
24 /* FUNCTIONS *****************************************************************/
30 NtQueryInformationFile(HANDLE FileHandle
,
31 PIO_STATUS_BLOCK IoStatusBlock
,
32 PVOID FileInformation
,
34 FILE_INFORMATION_CLASS FileInformationClass
)
36 PFILE_OBJECT FileObject
;
39 PDEVICE_OBJECT DeviceObject
;
40 PIO_STACK_LOCATION StackPtr
;
42 KPROCESSOR_MODE PreviousMode
;
44 assert(IoStatusBlock
!= NULL
);
45 assert(FileInformation
!= NULL
);
47 DPRINT("NtQueryInformationFile(Handle %x StatBlk %x FileInfo %x Length %d "
48 "Class %d)\n", FileHandle
, IoStatusBlock
, FileInformation
,
49 Length
, FileInformationClass
);
51 PreviousMode
= ExGetPreviousMode();
53 Status
= ObReferenceObjectByHandle(FileHandle
,
59 if (!NT_SUCCESS(Status
))
63 DPRINT("FileObject %x\n", FileObject
);
65 DeviceObject
= FileObject
->DeviceObject
;
67 Irp
= IoAllocateIrp(DeviceObject
->StackSize
,
71 ObDereferenceObject(FileObject
);
72 return STATUS_INSUFFICIENT_RESOURCES
;
75 SystemBuffer
= ExAllocatePoolWithTag(NonPagedPool
,
78 if (SystemBuffer
== NULL
)
81 ObDereferenceObject(FileObject
);
82 return(STATUS_INSUFFICIENT_RESOURCES
);
85 /* Trigger FileObject/Event dereferencing */
86 Irp
->Tail
.Overlay
.OriginalFileObject
= FileObject
;
87 Irp
->RequestorMode
= PreviousMode
;
88 Irp
->AssociatedIrp
.SystemBuffer
= SystemBuffer
;
89 Irp
->UserIosb
= IoStatusBlock
;
90 Irp
->UserEvent
= &FileObject
->Event
;
91 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
92 KeResetEvent( &FileObject
->Event
);
94 StackPtr
= IoGetNextIrpStackLocation(Irp
);
95 StackPtr
->MajorFunction
= IRP_MJ_QUERY_INFORMATION
;
96 StackPtr
->MinorFunction
= 0;
98 StackPtr
->Control
= 0;
99 StackPtr
->DeviceObject
= DeviceObject
;
100 StackPtr
->FileObject
= FileObject
;
102 StackPtr
->Parameters
.QueryFile
.FileInformationClass
=
103 FileInformationClass
;
104 StackPtr
->Parameters
.QueryFile
.Length
= Length
;
106 Status
= IoCallDriver(FileObject
->DeviceObject
,
108 if (Status
== STATUS_PENDING
&& (FileObject
->Flags
& FO_SYNCHRONOUS_IO
))
110 KeWaitForSingleObject(&FileObject
->Event
,
113 FileObject
->Flags
& FO_ALERTABLE_IO
,
115 Status
= IoStatusBlock
->Status
;
118 if (NT_SUCCESS(Status
))
120 DPRINT("Information %lu\n", IoStatusBlock
->Information
);
121 MmSafeCopyToUser(FileInformation
,
123 IoStatusBlock
->Information
);
126 ExFreePool(SystemBuffer
);
136 NtQueryQuotaInformationFile(
137 IN HANDLE FileHandle
,
138 OUT PIO_STATUS_BLOCK IoStatusBlock
,
141 IN BOOLEAN ReturnSingleEntry
,
142 IN PVOID SidList OPTIONAL
,
143 IN ULONG SidListLength
,
144 IN PSID StartSid OPTIONAL
,
145 IN BOOLEAN RestartScan
149 return STATUS_NOT_IMPLEMENTED
;
157 NtSetQuotaInformationFile(
159 PIO_STATUS_BLOCK IoStatusBlock
,
160 PFILE_USER_QUOTA_INFORMATION Buffer
,
164 return STATUS_NOT_IMPLEMENTED
;
173 IoCheckQuerySetFileInformation(
174 IN FILE_INFORMATION_CLASS FileInformationClass
,
176 IN BOOLEAN SetOperation
180 return STATUS_NOT_IMPLEMENTED
;
188 IoCheckQuerySetVolumeInformation(
189 IN FS_INFORMATION_CLASS FsInformationClass
,
191 IN BOOLEAN SetOperation
195 return STATUS_NOT_IMPLEMENTED
;
203 IoCheckQuotaBufferValidity(
204 IN PFILE_QUOTA_INFORMATION QuotaBuffer
,
205 IN ULONG QuotaLength
,
206 OUT PULONG ErrorOffset
210 return STATUS_NOT_IMPLEMENTED
;
218 IoCreateFileSpecifyDeviceObjectHint(
219 OUT PHANDLE FileHandle
,
220 IN ACCESS_MASK DesiredAccess
,
221 IN POBJECT_ATTRIBUTES ObjectAttributes
,
222 OUT PIO_STATUS_BLOCK IoStatusBlock
,
223 IN PLARGE_INTEGER AllocationSize OPTIONAL
,
224 IN ULONG FileAttributes
,
225 IN ULONG ShareAccess
,
226 IN ULONG Disposition
,
227 IN ULONG CreateOptions
,
228 IN PVOID EaBuffer OPTIONAL
,
230 IN CREATE_FILE_TYPE CreateFileType
,
231 IN PVOID ExtraCreateParameters OPTIONAL
,
233 IN PVOID DeviceObject
237 return STATUS_NOT_IMPLEMENTED
;
245 IoCreateStreamFileObjectEx(
246 IN PFILE_OBJECT FileObject OPTIONAL
,
247 IN PDEVICE_OBJECT DeviceObject OPTIONAL
,
248 OUT PHANDLE FileObjectHandle OPTIONAL
259 IoCreateStreamFileObjectLite(
260 IN PFILE_OBJECT FileObject OPTIONAL
,
261 IN PDEVICE_OBJECT DeviceObject OPTIONAL
273 IoIsFileOriginRemote(
274 IN PFILE_OBJECT FileObject
286 IoQueryFileDosDeviceName(
287 IN PFILE_OBJECT FileObject
,
288 OUT POBJECT_NAME_INFORMATION
*ObjectNameInformation
292 return STATUS_NOT_IMPLEMENTED
;
299 IoQueryFileInformation(IN PFILE_OBJECT FileObject
,
300 IN FILE_INFORMATION_CLASS FileInformationClass
,
302 OUT PVOID FileInformation
,
303 OUT PULONG ReturnedLength
)
305 IO_STATUS_BLOCK IoStatusBlock
;
307 PDEVICE_OBJECT DeviceObject
;
308 PIO_STACK_LOCATION StackPtr
;
311 assert(FileInformation
!= NULL
)
313 Status
= ObReferenceObjectByPointer(FileObject
,
314 FILE_READ_ATTRIBUTES
,
317 if (!NT_SUCCESS(Status
))
322 DPRINT("FileObject %x\n", FileObject
);
324 DeviceObject
= FileObject
->DeviceObject
;
326 Irp
= IoAllocateIrp(DeviceObject
->StackSize
,
330 ObDereferenceObject(FileObject
);
331 return STATUS_INSUFFICIENT_RESOURCES
;
334 /* Trigger FileObject/Event dereferencing */
335 Irp
->Tail
.Overlay
.OriginalFileObject
= FileObject
;
336 Irp
->RequestorMode
= KernelMode
;
337 Irp
->AssociatedIrp
.SystemBuffer
= FileInformation
;
338 Irp
->UserIosb
= &IoStatusBlock
;
339 Irp
->UserEvent
= &FileObject
->Event
;
340 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
341 KeResetEvent( &FileObject
->Event
);
343 StackPtr
= IoGetNextIrpStackLocation(Irp
);
344 StackPtr
->MajorFunction
= IRP_MJ_QUERY_INFORMATION
;
345 StackPtr
->MinorFunction
= 0;
347 StackPtr
->Control
= 0;
348 StackPtr
->DeviceObject
= DeviceObject
;
349 StackPtr
->FileObject
= FileObject
;
351 StackPtr
->Parameters
.QueryFile
.FileInformationClass
=
352 FileInformationClass
;
353 StackPtr
->Parameters
.QueryFile
.Length
= Length
;
355 Status
= IoCallDriver(FileObject
->DeviceObject
,
357 if (Status
==STATUS_PENDING
&& (FileObject
->Flags
& FO_SYNCHRONOUS_IO
))
359 KeWaitForSingleObject(&FileObject
->Event
,
362 FileObject
->Flags
& FO_ALERTABLE_IO
,
364 Status
= IoStatusBlock
.Status
;
367 if (ReturnedLength
!= NULL
)
369 *ReturnedLength
= IoStatusBlock
.Information
;
381 NtSetInformationFile(HANDLE FileHandle
,
382 PIO_STATUS_BLOCK IoStatusBlock
,
383 PVOID FileInformation
,
385 FILE_INFORMATION_CLASS FileInformationClass
)
387 PIO_STACK_LOCATION StackPtr
;
388 PFILE_OBJECT FileObject
;
389 PDEVICE_OBJECT DeviceObject
;
393 KPROCESSOR_MODE PreviousMode
;
395 assert(IoStatusBlock
!= NULL
)
396 assert(FileInformation
!= NULL
)
398 DPRINT("NtSetInformationFile(Handle %x StatBlk %x FileInfo %x Length %d "
399 "Class %d)\n", FileHandle
, IoStatusBlock
, FileInformation
,
400 Length
, FileInformationClass
);
402 PreviousMode
= ExGetPreviousMode();
404 /* Get the file object from the file handle */
405 Status
= ObReferenceObjectByHandle(FileHandle
,
406 FILE_WRITE_ATTRIBUTES
,
409 (PVOID
*)&FileObject
,
411 if (!NT_SUCCESS(Status
))
416 DPRINT("FileObject %x\n", FileObject
);
418 /* io completion port? */
419 if (FileInformationClass
== FileCompletionInformation
)
423 if (Length
< sizeof(FILE_COMPLETION_INFORMATION
))
425 Status
= STATUS_INFO_LENGTH_MISMATCH
;
429 Status
= ObReferenceObjectByHandle(((PFILE_COMPLETION_INFORMATION
)FileInformation
)->IoCompletionHandle
,
430 IO_COMPLETION_MODIFY_STATE
,//???
435 if (NT_SUCCESS(Status
))
437 /* FIXME: maybe use lookaside list */
438 FileObject
->CompletionContext
= ExAllocatePool(NonPagedPool
, sizeof(IO_COMPLETION_CONTEXT
));
439 FileObject
->CompletionContext
->Key
= ((PFILE_COMPLETION_INFORMATION
)FileInformation
)->CompletionKey
;
440 FileObject
->CompletionContext
->Port
= Queue
;
442 ObDereferenceObject(Queue
);
446 ObDereferenceObject(FileObject
);
450 DeviceObject
= FileObject
->DeviceObject
;
452 Irp
= IoAllocateIrp(DeviceObject
->StackSize
,
456 ObDereferenceObject(FileObject
);
457 return STATUS_INSUFFICIENT_RESOURCES
;
460 SystemBuffer
= ExAllocatePoolWithTag(NonPagedPool
,
463 if (SystemBuffer
== NULL
)
466 ObDereferenceObject(FileObject
);
467 return(STATUS_INSUFFICIENT_RESOURCES
);
470 MmSafeCopyFromUser(SystemBuffer
,
474 /* Trigger FileObject/Event dereferencing */
475 Irp
->Tail
.Overlay
.OriginalFileObject
= FileObject
;
476 Irp
->RequestorMode
= PreviousMode
;
477 Irp
->AssociatedIrp
.SystemBuffer
= SystemBuffer
;
478 Irp
->UserIosb
= IoStatusBlock
;
479 Irp
->UserEvent
= &FileObject
->Event
;
480 KeResetEvent( &FileObject
->Event
);
481 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
483 StackPtr
= IoGetNextIrpStackLocation(Irp
);
484 StackPtr
->MajorFunction
= IRP_MJ_SET_INFORMATION
;
485 StackPtr
->MinorFunction
= 0;
487 StackPtr
->Control
= 0;
488 StackPtr
->DeviceObject
= DeviceObject
;
489 StackPtr
->FileObject
= FileObject
;
491 StackPtr
->Parameters
.SetFile
.FileInformationClass
=
492 FileInformationClass
;
493 StackPtr
->Parameters
.SetFile
.Length
= Length
;
496 * Pass the IRP to the FSD (and wait for
499 DPRINT("FileObject->DeviceObject %x\n", FileObject
->DeviceObject
);
500 Status
= IoCallDriver(FileObject
->DeviceObject
,
502 if (Status
== STATUS_PENDING
&& (FileObject
->Flags
& FO_SYNCHRONOUS_IO
))
504 KeWaitForSingleObject(&FileObject
->Event
,
507 FileObject
->Flags
& FO_ALERTABLE_IO
,
509 Status
= IoStatusBlock
->Status
;
512 ExFreePool(SystemBuffer
);
524 IN PFILE_OBJECT FileObject
,
529 return STATUS_NOT_IMPLEMENTED
;
533 NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes
,
534 OUT PFILE_BASIC_INFORMATION FileInformation
)
536 IO_STATUS_BLOCK IoStatusBlock
;
541 Status
= NtOpenFile (&FileHandle
,
542 SYNCHRONIZE
| FILE_READ_ATTRIBUTES
,
545 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
546 FILE_SYNCHRONOUS_IO_NONALERT
);
547 if (!NT_SUCCESS (Status
))
549 DPRINT ("NtOpenFile() failed (Status %lx)\n", Status
);
553 /* Get file attributes */
554 Status
= NtQueryInformationFile (FileHandle
,
557 sizeof(FILE_BASIC_INFORMATION
),
558 FileBasicInformation
);
559 NtClose (FileHandle
);
560 if (!NT_SUCCESS (Status
))
562 DPRINT ("NtQueryInformationFile() failed (Status %lx)\n", Status
);
570 NtQueryFullAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes
,
571 OUT PFILE_NETWORK_OPEN_INFORMATION FileInformation
)
573 IO_STATUS_BLOCK IoStatusBlock
;
578 Status
= NtOpenFile (&FileHandle
,
579 SYNCHRONIZE
| FILE_READ_ATTRIBUTES
,
582 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
583 FILE_SYNCHRONOUS_IO_NONALERT
);
584 if (!NT_SUCCESS (Status
))
586 DPRINT ("NtOpenFile() failed (Status %lx)\n", Status
);
590 /* Get file attributes */
591 Status
= NtQueryInformationFile (FileHandle
,
594 sizeof(FILE_NETWORK_OPEN_INFORMATION
),
595 FileNetworkOpenInformation
);
596 NtClose (FileHandle
);
597 if (!NT_SUCCESS (Status
))
599 DPRINT ("NtQueryInformationFile() failed (Status %lx)\n", Status
);
610 NtQueryEaFile(IN HANDLE FileHandle
,
611 OUT PIO_STATUS_BLOCK IoStatusBlock
,
614 IN BOOLEAN ReturnSingleEntry
,
615 IN PVOID EaList OPTIONAL
,
616 IN ULONG EaListLength
,
617 IN PULONG EaIndex OPTIONAL
,
618 IN BOOLEAN RestartScan
)
621 return STATUS_NOT_IMPLEMENTED
;
629 NtSetEaFile(IN HANDLE FileHandle
,
630 IN PIO_STATUS_BLOCK IoStatusBlock
,
632 IN ULONG EaBufferSize
)
635 return STATUS_NOT_IMPLEMENTED
;