/* $Id$ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: ntoskrnl/io/file.c * PURPOSE: Graceful system shutdown if a bug is detected * PROGRAMMER: David Welch (welch@mcmail.com) * UPDATE HISTORY: * Created 22/05/98 */ /* INCLUDES *****************************************************************/ #include #include #include #define NDEBUG #include /* GLOBALS *******************************************************************/ #define TAG_SYSB TAG('S', 'Y', 'S', 'B') /* FUNCTIONS *****************************************************************/ NTSTATUS STDCALL NtQueryInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass) { PFILE_OBJECT FileObject; NTSTATUS Status; PIRP Irp; PDEVICE_OBJECT DeviceObject; PIO_STACK_LOCATION StackPtr; PVOID SystemBuffer; IO_STATUS_BLOCK IoSB; assert(IoStatusBlock != NULL); assert(FileInformation != NULL); DPRINT("NtQueryInformationFile(Handle %x StatBlk %x FileInfo %x Length %d " "Class %d)\n", FileHandle, IoStatusBlock, FileInformation, Length, FileInformationClass); Status = ObReferenceObjectByHandle(FileHandle, FILE_READ_ATTRIBUTES, IoFileObjectType, UserMode, (PVOID *)&FileObject, NULL); if (!NT_SUCCESS(Status)) { return(Status); } DPRINT("FileObject %x\n", FileObject); DeviceObject = FileObject->DeviceObject; Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE); if (Irp == NULL) { ObDereferenceObject(FileObject); return STATUS_INSUFFICIENT_RESOURCES; } SystemBuffer = ExAllocatePoolWithTag(NonPagedPool, Length, TAG_SYSB); if (SystemBuffer == NULL) { IoFreeIrp(Irp); ObDereferenceObject(FileObject); return(STATUS_INSUFFICIENT_RESOURCES); } Irp->AssociatedIrp.SystemBuffer = SystemBuffer; Irp->UserIosb = &IoSB; Irp->UserEvent = &FileObject->Event; KeResetEvent( &FileObject->Event ); StackPtr = IoGetNextIrpStackLocation(Irp); StackPtr->MajorFunction = IRP_MJ_QUERY_INFORMATION; StackPtr->MinorFunction = 0; StackPtr->Flags = 0; StackPtr->Control = 0; StackPtr->DeviceObject = DeviceObject; StackPtr->FileObject = FileObject; StackPtr->Parameters.QueryFile.FileInformationClass = FileInformationClass; StackPtr->Parameters.QueryFile.Length = Length; Status = IoCallDriver(FileObject->DeviceObject, Irp); if (Status==STATUS_PENDING && !(FileObject->Flags & FO_SYNCHRONOUS_IO)) { KeWaitForSingleObject(&FileObject->Event, Executive, KernelMode, FALSE, NULL); Status = IoSB.Status; } if (IoStatusBlock) { *IoStatusBlock = IoSB; } if (NT_SUCCESS(Status)) { DPRINT("Information %lu\n", IoStatusBlock->Information); MmSafeCopyToUser(FileInformation, SystemBuffer, IoStatusBlock->Information); } ExFreePool(SystemBuffer); return(Status); } #ifndef LIBCAPTIVE NTSTATUS STDCALL IoQueryFileInformation(IN PFILE_OBJECT FileObject, IN FILE_INFORMATION_CLASS FileInformationClass, IN ULONG Length, OUT PVOID FileInformation, OUT PULONG ReturnedLength) { IO_STATUS_BLOCK IoStatusBlock; PIRP Irp; PDEVICE_OBJECT DeviceObject; PIO_STACK_LOCATION StackPtr; NTSTATUS Status; assert(FileInformation != NULL) Status = ObReferenceObjectByPointer(FileObject, FILE_READ_ATTRIBUTES, IoFileObjectType, KernelMode); if (!NT_SUCCESS(Status)) { return(Status); } DPRINT("FileObject %x\n", FileObject); DeviceObject = FileObject->DeviceObject; Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE); if (Irp == NULL) { ObDereferenceObject(FileObject); return STATUS_INSUFFICIENT_RESOURCES; } Irp->AssociatedIrp.SystemBuffer = FileInformation; Irp->UserIosb = &IoStatusBlock; Irp->UserEvent = &FileObject->Event; KeResetEvent( &FileObject->Event ); StackPtr = IoGetNextIrpStackLocation(Irp); StackPtr->MajorFunction = IRP_MJ_QUERY_INFORMATION; StackPtr->MinorFunction = 0; StackPtr->Flags = 0; StackPtr->Control = 0; StackPtr->DeviceObject = DeviceObject; StackPtr->FileObject = FileObject; StackPtr->Parameters.QueryFile.FileInformationClass = FileInformationClass; StackPtr->Parameters.QueryFile.Length = Length; Status = IoCallDriver(FileObject->DeviceObject, Irp); if (Status==STATUS_PENDING && !(FileObject->Flags & FO_SYNCHRONOUS_IO)) { KeWaitForSingleObject(&FileObject->Event, Executive, KernelMode, FALSE, NULL); Status = IoStatusBlock.Status; } if (ReturnedLength != NULL) { *ReturnedLength = IoStatusBlock.Information; } return Status; } #endif /* LIBCAPTIVE */ #define OBJ_KERNEL_HANDLE 0x00000200 #define IO_FORCE_ACCESS_CHECK 0x1 #define IO_NO_PARAMETER_CHECKING 0x100 NTSTATUS STDCALL NtSetInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass) { PIO_STACK_LOCATION StackPtr; PFILE_OBJECT FileObject; PDEVICE_OBJECT DeviceObject; PIRP Irp; NTSTATUS Status; PVOID SystemBuffer; IO_STATUS_BLOCK IoSB; FILE_OBJECT *RootDir_FileObject = NULL; HANDLE RootDir_FileHandle; assert(IoStatusBlock != NULL) assert(FileInformation != NULL) DPRINT("NtSetInformationFile(Handle %x StatBlk %x FileInfo %x Length %d " "Class %d)\n", FileHandle, IoStatusBlock, FileInformation, Length, FileInformationClass); /* Get the file object from the file handle */ Status = ObReferenceObjectByHandle(FileHandle, FILE_WRITE_ATTRIBUTES, IoFileObjectType, UserMode, (PVOID *)&FileObject, NULL); if (!NT_SUCCESS(Status)) { return Status; } DPRINT("FileObject %x\n", FileObject); DeviceObject = FileObject->DeviceObject; Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE); if (Irp == NULL) { ObDereferenceObject(FileObject); return STATUS_INSUFFICIENT_RESOURCES; } SystemBuffer = ExAllocatePoolWithTag(NonPagedPool, Length, TAG_SYSB); if (SystemBuffer == NULL) { IoFreeIrp(Irp); ObDereferenceObject(FileObject); return(STATUS_INSUFFICIENT_RESOURCES); } MmSafeCopyFromUser(SystemBuffer, FileInformation, Length); Irp->AssociatedIrp.SystemBuffer = SystemBuffer; Irp->UserIosb = &IoSB; Irp->UserEvent = &FileObject->Event; KeResetEvent( &FileObject->Event ); StackPtr = IoGetNextIrpStackLocation(Irp); StackPtr->MajorFunction = IRP_MJ_SET_INFORMATION; StackPtr->MinorFunction = 0; StackPtr->Flags = 0; StackPtr->Control = 0; StackPtr->DeviceObject = DeviceObject; StackPtr->FileObject = FileObject; StackPtr->Parameters.SetFile.Length = Length; StackPtr->Parameters.SetFile.FileInformationClass = FileInformationClass; switch (FileInformationClass) { case FileRenameInformation: { FILE_RENAME_INFORMATION *RenameInformation=(FILE_RENAME_INFORMATION *)FileInformation; OBJECT_ATTRIBUTES file_ObjectAttributes; UNICODE_STRING file_ObjectAttributes_ObjectName_UnicodeString; IO_STATUS_BLOCK file_IoStatusBlock; /* Create target 'StackPtr->Parameters.SetFile.FileObject' * by a special way below to open the target directory * from the given full pathname by 'SL_OPEN_TARGET_DIRECTORY'. */ RtlInitUnicodeString(&file_ObjectAttributes_ObjectName_UnicodeString, RenameInformation->FileName); InitializeObjectAttributes( &file_ObjectAttributes, /* InitializedAttributes */ &file_ObjectAttributes_ObjectName_UnicodeString, /* ObjectName */ OBJ_KERNEL_HANDLE | (0/* FIXME: when to use it? */ ? 0x2000/* FIXME: meaning? */ : 0), /* Attributes */ RenameInformation->RootDir, /* RootDirectory */ NULL); /* SecurityDescriptor; ignored */ Status=IoCreateFile( &RootDir_FileHandle, /* FileHandle */ FILE_ADD_FILE | 0x100000/* FIXME: meaning? */, /* DesiredAccess */ &file_ObjectAttributes, /* ObjectAttributes */ &file_IoStatusBlock, /* IoStatusBlock */ NULL, /* AllocationSize; ignored for open */ 0, /* FileAttributes; ignored for open */ FILE_SHARE_READ|FILE_SHARE_WRITE, /* ShareAccess; 0 means exclusive */ FILE_OPEN, /* CreateDisposition */ FILE_OPEN_FOR_BACKUP_INTENT/* FIXME: why? meaning? */, /* CreateOptions */ NULL, /* EaBuffer */ 0, /* EaLength */ CreateFileTypeNone, /* CreateFileType */ NULL, /* ExtraCreateParameters */ IO_NO_PARAMETER_CHECKING|IO_FORCE_ACCESS_CHECK|SL_OPEN_TARGET_DIRECTORY); /* Options */ if (!NT_SUCCESS(Status)) { return Status; } /* Get the file object from the file handle */ Status = ObReferenceObjectByHandle(RootDir_FileHandle, (FILE_ADD_FILE | (0/* FIXME: when? */ ? FILE_ADD_SUBDIRECTORY : 0)), IoFileObjectType, KernelMode, (PVOID *)&RootDir_FileObject, NULL); if (!NT_SUCCESS(Status)) { NtClose(RootDir_FileHandle); /* errors ignored */ return Status; } /* 'StackPtr->FileObject' should be the source file, * 'StackPtr->Parameters.SetFile.FileObject' should be the target directory. */ StackPtr->Parameters.SetFile.FileObject=RootDir_FileObject; StackPtr->Parameters.SetFile.u.d.ReplaceIfExists=RenameInformation->Replace; StackPtr->Parameters.SetFile.u.d.AdvanceOnly=FALSE; } break; default:; } /* * Pass the IRP to the FSD (and wait for * it if required) */ DPRINT("FileObject->DeviceObject %x\n", FileObject->DeviceObject); Status = IoCallDriver(FileObject->DeviceObject, Irp); if (Status == STATUS_PENDING && !(FileObject->Flags & FO_SYNCHRONOUS_IO)) { KeWaitForSingleObject(&FileObject->Event, Executive, KernelMode, FALSE, NULL); Status = IoSB.Status; } if (IoStatusBlock) { *IoStatusBlock = IoSB; } if (RootDir_FileObject != NULL) { NtClose(RootDir_FileHandle); /* errors ignored */ ObDereferenceObject(RootDir_FileObject); } ExFreePool(SystemBuffer); return Status; } #ifndef LIBCAPTIVE NTSTATUS STDCALL NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PFILE_BASIC_INFORMATION FileInformation) { UNIMPLEMENTED; return STATUS_NOT_IMPLEMENTED; } NTSTATUS STDCALL NtQueryFullAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PFILE_NETWORK_OPEN_INFORMATION FileInformation) { UNIMPLEMENTED; return STATUS_NOT_IMPLEMENTED; } NTSTATUS STDCALL NtQueryEaFile(IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID Buffer, IN ULONG Length, IN BOOLEAN ReturnSingleEntry, IN PVOID EaList OPTIONAL, IN ULONG EaListLength, IN PULONG EaIndex OPTIONAL, IN BOOLEAN RestartScan) { UNIMPLEMENTED; return STATUS_NOT_IMPLEMENTED; } NTSTATUS STDCALL NtSetEaFile(IN HANDLE FileHandle, IN PIO_STATUS_BLOCK IoStatusBlock, IN PVOID EaBuffer, IN ULONG EaBufferSize) { UNIMPLEMENTED; return STATUS_NOT_IMPLEMENTED; } #endif /* LIBCAPTIVE */ /* EOF */