1 /* $Id: file.c,v 1.26 2003/07/11 01:23:14 royce 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 *****************************************************************/
14 #include <ddk/ntddk.h>
15 #include <internal/io.h>
16 #include <internal/mm.h>
19 #include <internal/debug.h>
22 /* GLOBALS *******************************************************************/
24 #define TAG_SYSB TAG('S', 'Y', 'S', 'B')
27 /* FUNCTIONS *****************************************************************/
33 NtQueryInformationFile(HANDLE FileHandle
,
34 PIO_STATUS_BLOCK IoStatusBlock
,
35 PVOID FileInformation
,
37 FILE_INFORMATION_CLASS FileInformationClass
)
39 PFILE_OBJECT FileObject
;
42 PDEVICE_OBJECT DeviceObject
;
43 PIO_STACK_LOCATION StackPtr
;
47 assert(IoStatusBlock
!= NULL
);
48 assert(FileInformation
!= NULL
);
50 DPRINT("NtQueryInformationFile(Handle %x StatBlk %x FileInfo %x Length %d "
51 "Class %d)\n", FileHandle
, IoStatusBlock
, FileInformation
,
52 Length
, FileInformationClass
);
54 Status
= ObReferenceObjectByHandle(FileHandle
,
60 if (!NT_SUCCESS(Status
))
64 DPRINT("FileObject %x\n", FileObject
);
66 DeviceObject
= FileObject
->DeviceObject
;
68 Irp
= IoAllocateIrp(DeviceObject
->StackSize
,
72 ObDereferenceObject(FileObject
);
73 return STATUS_INSUFFICIENT_RESOURCES
;
76 SystemBuffer
= ExAllocatePoolWithTag(NonPagedPool
,
79 if (SystemBuffer
== NULL
)
82 ObDereferenceObject(FileObject
);
83 return(STATUS_INSUFFICIENT_RESOURCES
);
86 //trigger FileObject/Event dereferencing
87 Irp
->Tail
.Overlay
.OriginalFileObject
= FileObject
;
89 Irp
->AssociatedIrp
.SystemBuffer
= SystemBuffer
;
90 Irp
->UserIosb
= &IoSB
;
91 Irp
->UserEvent
= &FileObject
->Event
;
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
,
115 Status
= IoSB
.Status
;
119 *IoStatusBlock
= IoSB
;
122 if (NT_SUCCESS(Status
))
124 DPRINT("Information %lu\n", IoStatusBlock
->Information
);
125 MmSafeCopyToUser(FileInformation
,
127 IoStatusBlock
->Information
);
130 ExFreePool(SystemBuffer
);
139 IoQueryFileInformation(IN PFILE_OBJECT FileObject
,
140 IN FILE_INFORMATION_CLASS FileInformationClass
,
142 OUT PVOID FileInformation
,
143 OUT PULONG ReturnedLength
)
145 IO_STATUS_BLOCK IoStatusBlock
;
147 PDEVICE_OBJECT DeviceObject
;
148 PIO_STACK_LOCATION StackPtr
;
151 assert(FileInformation
!= NULL
)
153 Status
= ObReferenceObjectByPointer(FileObject
,
154 FILE_READ_ATTRIBUTES
,
157 if (!NT_SUCCESS(Status
))
162 DPRINT("FileObject %x\n", FileObject
);
164 DeviceObject
= FileObject
->DeviceObject
;
166 Irp
= IoAllocateIrp(DeviceObject
->StackSize
,
170 ObDereferenceObject(FileObject
);
171 return STATUS_INSUFFICIENT_RESOURCES
;
174 //trigger FileObject/Event dereferencing
175 Irp
->Tail
.Overlay
.OriginalFileObject
= FileObject
;
177 Irp
->AssociatedIrp
.SystemBuffer
= FileInformation
;
178 Irp
->UserIosb
= &IoStatusBlock
;
179 Irp
->UserEvent
= &FileObject
->Event
;
180 KeResetEvent( &FileObject
->Event
);
182 StackPtr
= IoGetNextIrpStackLocation(Irp
);
183 StackPtr
->MajorFunction
= IRP_MJ_QUERY_INFORMATION
;
184 StackPtr
->MinorFunction
= 0;
186 StackPtr
->Control
= 0;
187 StackPtr
->DeviceObject
= DeviceObject
;
188 StackPtr
->FileObject
= FileObject
;
190 StackPtr
->Parameters
.QueryFile
.FileInformationClass
=
191 FileInformationClass
;
192 StackPtr
->Parameters
.QueryFile
.Length
= Length
;
194 Status
= IoCallDriver(FileObject
->DeviceObject
,
196 if (Status
==STATUS_PENDING
&& !(FileObject
->Flags
& FO_SYNCHRONOUS_IO
))
198 KeWaitForSingleObject(&FileObject
->Event
,
203 Status
= IoStatusBlock
.Status
;
206 if (ReturnedLength
!= NULL
)
208 *ReturnedLength
= IoStatusBlock
.Information
;
220 NtSetInformationFile(HANDLE FileHandle
,
221 PIO_STATUS_BLOCK IoStatusBlock
,
222 PVOID FileInformation
,
224 FILE_INFORMATION_CLASS FileInformationClass
)
226 PIO_STACK_LOCATION StackPtr
;
227 PFILE_OBJECT FileObject
;
228 PDEVICE_OBJECT DeviceObject
;
232 IO_STATUS_BLOCK IoSB
;
234 assert(IoStatusBlock
!= NULL
)
235 assert(FileInformation
!= NULL
)
237 DPRINT("NtSetInformationFile(Handle %x StatBlk %x FileInfo %x Length %d "
238 "Class %d)\n", FileHandle
, IoStatusBlock
, FileInformation
,
239 Length
, FileInformationClass
);
241 /* Get the file object from the file handle */
242 Status
= ObReferenceObjectByHandle(FileHandle
,
243 FILE_WRITE_ATTRIBUTES
,
246 (PVOID
*)&FileObject
,
248 if (!NT_SUCCESS(Status
))
253 DPRINT("FileObject %x\n", FileObject
);
255 //io completion port?
256 if (FileInformationClass
== FileCompletionInformation
)
260 if (Length
< sizeof(FILE_COMPLETION_INFORMATION
))
262 Status
= STATUS_INFO_LENGTH_MISMATCH
;
266 Status
= ObReferenceObjectByHandle(((PFILE_COMPLETION_INFORMATION
)FileInformation
)->IoCompletionHandle
,
267 IO_COMPLETION_MODIFY_STATE
,//???
272 if (NT_SUCCESS(Status
))
274 //FIXME: maybe use lookaside list
275 FileObject
->CompletionContext
= ExAllocatePool(NonPagedPool
, sizeof(IO_COMPLETION_CONTEXT
));
276 FileObject
->CompletionContext
->Key
= ((PFILE_COMPLETION_INFORMATION
)FileInformation
)->CompletionKey
;
277 FileObject
->CompletionContext
->Port
= Queue
;
279 ObDereferenceObject(Queue
);
283 ObDereferenceObject(FileObject
);
287 DeviceObject
= FileObject
->DeviceObject
;
289 Irp
= IoAllocateIrp(DeviceObject
->StackSize
,
293 ObDereferenceObject(FileObject
);
294 return STATUS_INSUFFICIENT_RESOURCES
;
297 SystemBuffer
= ExAllocatePoolWithTag(NonPagedPool
,
300 if (SystemBuffer
== NULL
)
303 ObDereferenceObject(FileObject
);
304 return(STATUS_INSUFFICIENT_RESOURCES
);
307 MmSafeCopyFromUser(SystemBuffer
,
311 //trigger FileObject/Event dereferencing
312 Irp
->Tail
.Overlay
.OriginalFileObject
= FileObject
;
314 Irp
->AssociatedIrp
.SystemBuffer
= SystemBuffer
;
315 Irp
->UserIosb
= &IoSB
;
316 Irp
->UserEvent
= &FileObject
->Event
;
317 KeResetEvent( &FileObject
->Event
);
319 StackPtr
= IoGetNextIrpStackLocation(Irp
);
320 StackPtr
->MajorFunction
= IRP_MJ_SET_INFORMATION
;
321 StackPtr
->MinorFunction
= 0;
323 StackPtr
->Control
= 0;
324 StackPtr
->DeviceObject
= DeviceObject
;
325 StackPtr
->FileObject
= FileObject
;
327 StackPtr
->Parameters
.SetFile
.FileInformationClass
=
328 FileInformationClass
;
329 StackPtr
->Parameters
.SetFile
.Length
= Length
;
332 * Pass the IRP to the FSD (and wait for
335 DPRINT("FileObject->DeviceObject %x\n", FileObject
->DeviceObject
);
336 Status
= IoCallDriver(FileObject
->DeviceObject
,
338 if (Status
== STATUS_PENDING
&& !(FileObject
->Flags
& FO_SYNCHRONOUS_IO
))
340 KeWaitForSingleObject(&FileObject
->Event
,
345 Status
= IoSB
.Status
;
349 *IoStatusBlock
= IoSB
;
351 ExFreePool(SystemBuffer
);
358 NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes
,
359 OUT PFILE_BASIC_INFORMATION FileInformation
)
361 IO_STATUS_BLOCK IoStatusBlock
;
366 Status
= NtOpenFile (&FileHandle
,
367 SYNCHRONIZE
| FILE_READ_ATTRIBUTES
,
370 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
371 FILE_SYNCHRONOUS_IO_NONALERT
);
372 if (!NT_SUCCESS (Status
))
374 DPRINT ("NtOpenFile() failed (Status %lx)\n", Status
);
378 /* Get file attributes */
379 Status
= NtQueryInformationFile (FileHandle
,
382 sizeof(FILE_BASIC_INFORMATION
),
383 FileBasicInformation
);
384 NtClose (FileHandle
);
385 if (!NT_SUCCESS (Status
))
387 DPRINT ("NtQueryInformationFile() failed (Status %lx)\n", Status
);
395 NtQueryFullAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes
,
396 OUT PFILE_NETWORK_OPEN_INFORMATION FileInformation
)
398 IO_STATUS_BLOCK IoStatusBlock
;
403 Status
= NtOpenFile (&FileHandle
,
404 SYNCHRONIZE
| FILE_READ_ATTRIBUTES
,
407 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
408 FILE_SYNCHRONOUS_IO_NONALERT
);
409 if (!NT_SUCCESS (Status
))
411 DPRINT ("NtOpenFile() failed (Status %lx)\n", Status
);
415 /* Get file attributes */
416 Status
= NtQueryInformationFile (FileHandle
,
419 sizeof(FILE_NETWORK_OPEN_INFORMATION
),
420 FileNetworkOpenInformation
);
421 NtClose (FileHandle
);
422 if (!NT_SUCCESS (Status
))
424 DPRINT ("NtQueryInformationFile() failed (Status %lx)\n", Status
);
435 NtQueryEaFile(IN HANDLE FileHandle
,
436 OUT PIO_STATUS_BLOCK IoStatusBlock
,
439 IN BOOLEAN ReturnSingleEntry
,
440 IN PVOID EaList OPTIONAL
,
441 IN ULONG EaListLength
,
442 IN PULONG EaIndex OPTIONAL
,
443 IN BOOLEAN RestartScan
)
446 return STATUS_NOT_IMPLEMENTED
;
454 NtSetEaFile(IN HANDLE FileHandle
,
455 IN PIO_STATUS_BLOCK IoStatusBlock
,
457 IN ULONG EaBufferSize
)
460 return STATUS_NOT_IMPLEMENTED
;