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 *****************************************************************/
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;
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 Status = ObReferenceObjectByHandle(FileHandle,
57 if (!NT_SUCCESS(Status))
61 DPRINT("FileObject %x\n", FileObject);
63 DeviceObject = FileObject->DeviceObject;
65 Irp = IoAllocateIrp(DeviceObject->StackSize,
69 ObDereferenceObject(FileObject);
70 return STATUS_INSUFFICIENT_RESOURCES;
73 SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
76 if (SystemBuffer == NULL)
79 ObDereferenceObject(FileObject);
80 return(STATUS_INSUFFICIENT_RESOURCES);
83 Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
84 Irp->UserIosb = &IoSB;
85 Irp->UserEvent = &FileObject->Event;
86 KeResetEvent( &FileObject->Event );
88 StackPtr = IoGetNextIrpStackLocation(Irp);
89 StackPtr->MajorFunction = IRP_MJ_QUERY_INFORMATION;
90 StackPtr->MinorFunction = 0;
92 StackPtr->Control = 0;
93 StackPtr->DeviceObject = DeviceObject;
94 StackPtr->FileObject = FileObject;
96 StackPtr->Parameters.QueryFile.FileInformationClass =
98 StackPtr->Parameters.QueryFile.Length = Length;
100 Status = IoCallDriver(FileObject->DeviceObject,
102 if (Status==STATUS_PENDING && !(FileObject->Flags & FO_SYNCHRONOUS_IO))
104 KeWaitForSingleObject(&FileObject->Event,
109 Status = IoSB.Status;
113 *IoStatusBlock = IoSB;
116 if (NT_SUCCESS(Status))
118 DPRINT("Information %lu\n", IoStatusBlock->Information);
119 MmSafeCopyToUser(FileInformation,
121 IoStatusBlock->Information);
124 ExFreePool(SystemBuffer);
131 IoQueryFileInformation(IN PFILE_OBJECT FileObject,
132 IN FILE_INFORMATION_CLASS FileInformationClass,
134 OUT PVOID FileInformation,
135 OUT PULONG ReturnedLength)
137 IO_STATUS_BLOCK IoStatusBlock;
139 PDEVICE_OBJECT DeviceObject;
140 PIO_STACK_LOCATION StackPtr;
143 assert(FileInformation != NULL)
145 Status = ObReferenceObjectByPointer(FileObject,
146 FILE_READ_ATTRIBUTES,
149 if (!NT_SUCCESS(Status))
154 DPRINT("FileObject %x\n", FileObject);
156 DeviceObject = FileObject->DeviceObject;
158 Irp = IoAllocateIrp(DeviceObject->StackSize,
162 ObDereferenceObject(FileObject);
163 return STATUS_INSUFFICIENT_RESOURCES;
166 Irp->AssociatedIrp.SystemBuffer = FileInformation;
167 Irp->UserIosb = &IoStatusBlock;
168 Irp->UserEvent = &FileObject->Event;
169 KeResetEvent( &FileObject->Event );
171 StackPtr = IoGetNextIrpStackLocation(Irp);
172 StackPtr->MajorFunction = IRP_MJ_QUERY_INFORMATION;
173 StackPtr->MinorFunction = 0;
175 StackPtr->Control = 0;
176 StackPtr->DeviceObject = DeviceObject;
177 StackPtr->FileObject = FileObject;
179 StackPtr->Parameters.QueryFile.FileInformationClass =
180 FileInformationClass;
181 StackPtr->Parameters.QueryFile.Length = Length;
183 Status = IoCallDriver(FileObject->DeviceObject,
185 if (Status==STATUS_PENDING && !(FileObject->Flags & FO_SYNCHRONOUS_IO))
187 KeWaitForSingleObject(&FileObject->Event,
192 Status = IoStatusBlock.Status;
195 if (ReturnedLength != NULL)
197 *ReturnedLength = IoStatusBlock.Information;
204 #endif /* LIBCAPTIVE */
206 #define OBJ_KERNEL_HANDLE 0x00000200
207 #define IO_FORCE_ACCESS_CHECK 0x1
208 #define IO_NO_PARAMETER_CHECKING 0x100
211 NtSetInformationFile(HANDLE FileHandle,
212 PIO_STATUS_BLOCK IoStatusBlock,
213 PVOID FileInformation,
215 FILE_INFORMATION_CLASS FileInformationClass)
217 PIO_STACK_LOCATION StackPtr;
218 PFILE_OBJECT FileObject;
219 PDEVICE_OBJECT DeviceObject;
223 IO_STATUS_BLOCK IoSB;
224 FILE_OBJECT *RootDir_FileObject = NULL;
225 HANDLE RootDir_FileHandle;
227 assert(IoStatusBlock != NULL)
228 assert(FileInformation != NULL)
230 DPRINT("NtSetInformationFile(Handle %x StatBlk %x FileInfo %x Length %d "
231 "Class %d)\n", FileHandle, IoStatusBlock, FileInformation,
232 Length, FileInformationClass);
234 /* Get the file object from the file handle */
235 Status = ObReferenceObjectByHandle(FileHandle,
236 FILE_WRITE_ATTRIBUTES,
239 (PVOID *)&FileObject,
241 if (!NT_SUCCESS(Status))
246 DPRINT("FileObject %x\n", FileObject);
248 DeviceObject = FileObject->DeviceObject;
250 Irp = IoAllocateIrp(DeviceObject->StackSize,
254 ObDereferenceObject(FileObject);
255 return STATUS_INSUFFICIENT_RESOURCES;
258 SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
261 if (SystemBuffer == NULL)
264 ObDereferenceObject(FileObject);
265 return(STATUS_INSUFFICIENT_RESOURCES);
268 MmSafeCopyFromUser(SystemBuffer,
272 Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
273 Irp->UserIosb = &IoSB;
274 Irp->UserEvent = &FileObject->Event;
275 KeResetEvent( &FileObject->Event );
277 StackPtr = IoGetNextIrpStackLocation(Irp);
278 StackPtr->MajorFunction = IRP_MJ_SET_INFORMATION;
279 StackPtr->MinorFunction = 0;
281 StackPtr->Control = 0;
282 StackPtr->DeviceObject = DeviceObject;
283 StackPtr->FileObject = FileObject;
285 StackPtr->Parameters.SetFile.Length = Length;
286 StackPtr->Parameters.SetFile.FileInformationClass =
287 FileInformationClass;
288 switch (FileInformationClass)
290 case FileRenameInformation: {
291 FILE_RENAME_INFORMATION *RenameInformation=(FILE_RENAME_INFORMATION *)FileInformation;
292 OBJECT_ATTRIBUTES file_ObjectAttributes;
293 UNICODE_STRING file_ObjectAttributes_ObjectName_UnicodeString;
294 IO_STATUS_BLOCK file_IoStatusBlock;
296 /* Create target 'StackPtr->Parameters.SetFile.FileObject'
297 * by a special way below to open the target directory
298 * from the given full pathname by 'SL_OPEN_TARGET_DIRECTORY'.
300 RtlInitUnicodeString(&file_ObjectAttributes_ObjectName_UnicodeString, RenameInformation->FileName);
301 InitializeObjectAttributes(
302 &file_ObjectAttributes, /* InitializedAttributes */
303 &file_ObjectAttributes_ObjectName_UnicodeString, /* ObjectName */
304 OBJ_KERNEL_HANDLE | (0/* FIXME: when to use it? */ ? 0x2000/* FIXME: meaning? */ : 0), /* Attributes */
305 RenameInformation->RootDir, /* RootDirectory */
306 NULL); /* SecurityDescriptor; ignored */
308 &RootDir_FileHandle, /* FileHandle */
309 FILE_ADD_FILE | 0x100000/* FIXME: meaning? */, /* DesiredAccess */
310 &file_ObjectAttributes, /* ObjectAttributes */
311 &file_IoStatusBlock, /* IoStatusBlock */
312 NULL, /* AllocationSize; ignored for open */
313 0, /* FileAttributes; ignored for open */
314 FILE_SHARE_READ|FILE_SHARE_WRITE, /* ShareAccess; 0 means exclusive */
315 FILE_OPEN, /* CreateDisposition */
316 FILE_OPEN_FOR_BACKUP_INTENT/* FIXME: why? meaning? */, /* CreateOptions */
319 CreateFileTypeNone, /* CreateFileType */
320 NULL, /* ExtraCreateParameters */
321 IO_NO_PARAMETER_CHECKING|IO_FORCE_ACCESS_CHECK|SL_OPEN_TARGET_DIRECTORY); /* Options */
322 if (!NT_SUCCESS(Status))
327 /* Get the file object from the file handle */
328 Status = ObReferenceObjectByHandle(RootDir_FileHandle,
329 (FILE_ADD_FILE | (0/* FIXME: when? */ ? FILE_ADD_SUBDIRECTORY : 0)),
332 (PVOID *)&RootDir_FileObject,
334 if (!NT_SUCCESS(Status))
336 NtClose(RootDir_FileHandle); /* errors ignored */
339 /* 'StackPtr->FileObject' should be the source file,
340 * 'StackPtr->Parameters.SetFile.FileObject' should be the target directory.
342 StackPtr->Parameters.SetFile.FileObject=RootDir_FileObject;
343 StackPtr->Parameters.SetFile.u.d.ReplaceIfExists=RenameInformation->Replace;
344 StackPtr->Parameters.SetFile.u.d.AdvanceOnly=FALSE;
350 * Pass the IRP to the FSD (and wait for
353 DPRINT("FileObject->DeviceObject %x\n", FileObject->DeviceObject);
354 Status = IoCallDriver(FileObject->DeviceObject,
356 if (Status == STATUS_PENDING && !(FileObject->Flags & FO_SYNCHRONOUS_IO))
358 KeWaitForSingleObject(&FileObject->Event,
363 Status = IoSB.Status;
367 *IoStatusBlock = IoSB;
369 if (RootDir_FileObject != NULL)
371 NtClose(RootDir_FileHandle); /* errors ignored */
372 ObDereferenceObject(RootDir_FileObject);
374 ExFreePool(SystemBuffer);
382 NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
383 OUT PFILE_BASIC_INFORMATION FileInformation)
386 return STATUS_NOT_IMPLEMENTED;
391 NtQueryFullAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
392 OUT PFILE_NETWORK_OPEN_INFORMATION FileInformation)
395 return STATUS_NOT_IMPLEMENTED;
400 NtQueryEaFile(IN HANDLE FileHandle,
401 OUT PIO_STATUS_BLOCK IoStatusBlock,
404 IN BOOLEAN ReturnSingleEntry,
405 IN PVOID EaList OPTIONAL,
406 IN ULONG EaListLength,
407 IN PULONG EaIndex OPTIONAL,
408 IN BOOLEAN RestartScan)
411 return STATUS_NOT_IMPLEMENTED;
416 NtSetEaFile(IN HANDLE FileHandle,
417 IN PIO_STATUS_BLOCK IoStatusBlock,
419 IN ULONG EaBufferSize)
422 return STATUS_NOT_IMPLEMENTED;
425 #endif /* LIBCAPTIVE */