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;