Fix NtQueryInformationFile. Use right device object in case of
FO_DIRECT_DEVICE_OPEN, use local event, set proper flags so that the I/O
manager does the copying and freeing of the buffers, respect syyncronous
I/O. Same kind of fixes for IoQueryFileInformation
Modified: trunk/reactos/ntoskrnl/io/file.c
_____
Modified: trunk/reactos/ntoskrnl/io/file.c
--- trunk/reactos/ntoskrnl/io/file.c 2005-05-01 23:19:48 UTC (rev
14940)
+++ trunk/reactos/ntoskrnl/io/file.c 2005-05-02 05:15:20 UTC (rev
14941)
@@ -1131,75 +1131,90 @@
OUT PVOID FileInformation,
OUT PULONG ReturnedLength)
{
- IO_STATUS_BLOCK IoStatusBlock;
- PIRP Irp;
- PDEVICE_OBJECT DeviceObject;
- PIO_STACK_LOCATION StackPtr;
- NTSTATUS Status;
+ IO_STATUS_BLOCK IoStatusBlock;
+ PIRP Irp;
+ PDEVICE_OBJECT DeviceObject;
+ PIO_STACK_LOCATION StackPtr;
+ BOOLEAN LocalEvent = FALSE;
+ KEVENT Event;
+ NTSTATUS Status;
- ASSERT(FileInformation != NULL);
+ ASSERT(FileInformation != NULL);
- Status = ObReferenceObjectByPointer(FileObject,
- FILE_READ_ATTRIBUTES,
- IoFileObjectType,
- KernelMode);
- if (!NT_SUCCESS(Status))
- {
- return(Status);
- }
+ Status = ObReferenceObjectByPointer(FileObject,
+ FILE_READ_ATTRIBUTES,
+ IoFileObjectType,
+ KernelMode);
+ if (!NT_SUCCESS(Status)) return(Status);
- DPRINT("FileObject %x\n", FileObject);
+ DPRINT("FileObject %x\n", FileObject);
- DeviceObject = FileObject->DeviceObject;
+ /* Get the Device Object */
+ DeviceObject = IoGetRelatedDeviceObject(FileObject);
+
+ /* Check if we should use Sync IO or not */
+ if (FileObject->Flags & FO_SYNCHRONOUS_IO)
+ {
+ /* Use File Object event */
+ KeClearEvent(&FileObject->Event);
+ }
+ else
+ {
+ /* Use local event */
+ KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
+ LocalEvent = TRUE;
+ }
- Irp = IoAllocateIrp(DeviceObject->StackSize,
- TRUE);
- if (Irp == NULL)
- {
- ObDereferenceObject(FileObject);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* Trigger FileObject/Event dereferencing */
- Irp->Tail.Overlay.OriginalFileObject = FileObject;
- Irp->RequestorMode = KernelMode;
- Irp->AssociatedIrp.SystemBuffer = FileInformation;
- Irp->UserIosb = &IoStatusBlock;
- Irp->UserEvent = &FileObject->Event;
- Irp->Tail.Overlay.Thread = PsGetCurrentThread();
- KeResetEvent( &FileObject->Event );
+ /* Allocate the IRP */
+ Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
+
+ /* Set the IRP */
+ Irp->Tail.Overlay.OriginalFileObject = FileObject;
+ Irp->RequestorMode = KernelMode;
+ Irp->AssociatedIrp.SystemBuffer = FileInformation;
+ Irp->UserIosb = &IoStatusBlock;
+ Irp->UserEvent = (LocalEvent) ? &Event : NULL;
+ Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;
+ Irp->Tail.Overlay.Thread = PsGetCurrentThread();
- StackPtr = IoGetNextIrpStackLocation(Irp);
- StackPtr->MajorFunction = IRP_MJ_QUERY_INFORMATION;
- StackPtr->MinorFunction = 0;
- StackPtr->Flags = 0;
- StackPtr->Control = 0;
- StackPtr->DeviceObject = DeviceObject;
- StackPtr->FileObject = FileObject;
+ /* Set the Stack Data */
+ StackPtr = IoGetNextIrpStackLocation(Irp);
+ StackPtr->MajorFunction = IRP_MJ_QUERY_INFORMATION;
+ StackPtr->FileObject = FileObject;
- StackPtr->Parameters.QueryFile.FileInformationClass =
- FileInformationClass;
- StackPtr->Parameters.QueryFile.Length = Length;
+ /* Set Parameters */
+ 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,
- FileObject->Flags & FO_ALERTABLE_IO,
- NULL);
- Status = IoStatusBlock.Status;
- }
+ /* Call the Driver */
+ Status = IoCallDriver(FileObject->DeviceObject, Irp);
+
+ if (Status == STATUS_PENDING)
+ {
+ if (LocalEvent)
+ {
+ KeWaitForSingleObject(&Event,
+ Executive,
+ KernelMode,
+ FileObject->Flags & FO_ALERTABLE_IO,
+ NULL);
+ Status = IoStatusBlock.Status;
+ }
+ else
+ {
+ KeWaitForSingleObject(&FileObject->Event,
+ Executive,
+ KernelMode,
+ FileObject->Flags & FO_ALERTABLE_IO,
+ NULL);
+ Status = FileObject->FinalStatus;
+ }
+ }
+
- if (ReturnedLength != NULL)
- {
- *ReturnedLength = IoStatusBlock.Information;
- }
-
-
- return Status;
+ /* Return the Length and Status. ReturnedLength is NOT optional */
+ *ReturnedLength = IoStatusBlock.Information;
+ return Status;
}
/*
@@ -2170,132 +2185,150 @@
ULONG Length,
FILE_INFORMATION_CLASS FileInformationClass)
{
- OBJECT_HANDLE_INFORMATION HandleInformation;
- PFILE_OBJECT FileObject;
- NTSTATUS Status;
- PIRP Irp;
- PDEVICE_OBJECT DeviceObject;
- PIO_STACK_LOCATION StackPtr;
- PVOID SystemBuffer;
- KPROCESSOR_MODE PreviousMode;
- BOOLEAN Failed = FALSE;
+ OBJECT_HANDLE_INFORMATION HandleInformation;
+ PFILE_OBJECT FileObject;
+ NTSTATUS Status;
+ PIRP Irp;
+ PDEVICE_OBJECT DeviceObject;
+ PIO_STACK_LOCATION StackPtr;
+ KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+ KEVENT Event;
+ BOOLEAN LocalEvent = FALSE;
+ BOOLEAN Failed = FALSE;
- ASSERT(IoStatusBlock != NULL);
- ASSERT(FileInformation != NULL);
+ ASSERT(IoStatusBlock != NULL);
+ ASSERT(FileInformation != NULL);
- DPRINT("NtQueryInformationFile(Handle %x StatBlk %x FileInfo %x
Length %d "
- "Class %d)\n", FileHandle, IoStatusBlock, FileInformation,
- Length, FileInformationClass);
+ DPRINT("NtQueryInformationFile(Handle %x StatBlk %x FileInfo %x
Length %d "
+ "Class %d)\n", FileHandle, IoStatusBlock, FileInformation,
+ Length, FileInformationClass);
- PreviousMode = ExGetPreviousMode();
+ /* Reference the Handle */
+ Status = ObReferenceObjectByHandle(FileHandle,
+ 0,
+ IoFileObjectType,
+ PreviousMode,
+ (PVOID *)&FileObject,
+ &HandleInformation);
+ if (!NT_SUCCESS(Status)) return Status;
- Status = ObReferenceObjectByHandle(FileHandle,
- 0,
- IoFileObjectType,
- PreviousMode,
- (PVOID *)&FileObject,
- &HandleInformation);
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
+ /* Check information class specific access rights */
+ switch (FileInformationClass)
+ {
+ case FileBasicInformation:
+ if (!(HandleInformation.GrantedAccess &
FILE_READ_ATTRIBUTES))
+ Failed = TRUE;
+ break;
- /* Check information class specific access rights */
- switch (FileInformationClass)
- {
- case FileBasicInformation:
- if (!(HandleInformation.GrantedAccess & FILE_READ_ATTRIBUTES))
- Failed = TRUE;
- break;
+ case FilePositionInformation:
+ if (!(HandleInformation.GrantedAccess & (FILE_READ_DATA |
FILE_WRITE_DATA)) ||
+ !(FileObject->Flags & FO_SYNCHRONOUS_IO))
+ Failed = TRUE;
+ break;
- case FilePositionInformation:
- if (!(HandleInformation.GrantedAccess & (FILE_READ_DATA |
FILE_WRITE_DATA)) ||
- !(FileObject->Flags & FO_SYNCHRONOUS_IO))
- Failed = TRUE;
- break;
+ case FileAlignmentInformation:
+ if (!(FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING))
+ Failed = TRUE;
+ break;
- case FileAlignmentInformation:
- if (!(FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING))
- Failed = TRUE;
- break;
+ default:
+ break;
+ }
- default:
- break;
- }
+ if (Failed)
+ {
+ DPRINT1("NtQueryInformationFile() returns
STATUS_ACCESS_DENIED!\n");
+ ObDereferenceObject(FileObject);
+ return STATUS_ACCESS_DENIED;
+ }
- if (Failed)
- {
- DPRINT1("NtQueryInformationFile() returns
STATUS_ACCESS_DENIED!\n");
- ObDereferenceObject(FileObject);
- return STATUS_ACCESS_DENIED;
- }
+ DPRINT("FileObject %x\n", FileObject);
+
+ /* Check if this is a direct open or not */
+ if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
+ {
+ DeviceObject = IoGetAttachedDevice(FileObject->DeviceObject);
+ }
+ else
+ {
+ DeviceObject = IoGetRelatedDeviceObject(FileObject);
+ }
+
+ /* Check if we should use Sync IO or not */
+ if (FileObject->Flags & FO_SYNCHRONOUS_IO)
+ {
+ /* Use File Object event */
+ KeClearEvent(&FileObject->Event);
+ }
+ else
+ {
+ /* Use local event */
+ KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
+ LocalEvent = TRUE;
+ }
- DPRINT("FileObject %x\n", FileObject);
+ /* Allocate the IRP */
+ if (!(Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE)))
+ {
+ ObDereferenceObject(FileObject);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* Allocate the System Buffer */
+ if (!(Irp->AssociatedIrp.SystemBuffer =
ExAllocatePoolWithTag(NonPagedPool,
+
Length,
+
TAG_SYSB)))
+ {
+ IoFreeIrp(Irp);
+ ObDereferenceObject(FileObject);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
- DeviceObject = FileObject->DeviceObject;
+ /* Set up the IRP */
+ Irp->Tail.Overlay.OriginalFileObject = FileObject;
+ Irp->RequestorMode = PreviousMode;
+ Irp->UserIosb = IoStatusBlock;
+ Irp->UserEvent = (LocalEvent) ? &Event : NULL;
+ Irp->UserBuffer = FileInformation;
+ Irp->Tail.Overlay.Thread = PsGetCurrentThread();
+ Irp->Flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER |
IRP_INPUT_OPERATION;
+ Irp->Flags |= (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;
+
+ /* Set up Stack Data */
+ StackPtr = IoGetNextIrpStackLocation(Irp);
+ StackPtr->MajorFunction = IRP_MJ_QUERY_INFORMATION;
+ StackPtr->FileObject = FileObject;
- Irp = IoAllocateIrp(DeviceObject->StackSize,
- TRUE);
- if (Irp == NULL)
- {
- ObDereferenceObject(FileObject);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
+ /* Set the Parameters */
+ StackPtr->Parameters.QueryFile.FileInformationClass =
FileInformationClass;
+ StackPtr->Parameters.QueryFile.Length = Length;
+
+ /* Call the Driver */
+ Status = IoCallDriver(DeviceObject, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ if (LocalEvent)
+ {
+ KeWaitForSingleObject(&Event,
+ Executive,
+ PreviousMode,
+ FileObject->Flags & FO_ALERTABLE_IO,
+ NULL);
+ Status = IoStatusBlock->Status;
+ }
+ else
+ {
+ KeWaitForSingleObject(&FileObject->Event,
+ Executive,
+ PreviousMode,
+ FileObject->Flags & FO_ALERTABLE_IO,
+ NULL);
+ Status = FileObject->FinalStatus;
+ }
+ }
- SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
- Length,
- TAG_SYSB);
- if (SystemBuffer == NULL)
- {
- IoFreeIrp(Irp);
- ObDereferenceObject(FileObject);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* Trigger FileObject/Event dereferencing */
- Irp->Tail.Overlay.OriginalFileObject = FileObject;
- Irp->RequestorMode = PreviousMode;
- Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
- Irp->UserIosb = IoStatusBlock;
- Irp->UserEvent = &FileObject->Event;
- Irp->Tail.Overlay.Thread = PsGetCurrentThread();
- 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,
- PreviousMode,
- FileObject->Flags & FO_ALERTABLE_IO,
- NULL);
- Status = IoStatusBlock->Status;
- }
-
- if (NT_SUCCESS(Status))
- {
- DPRINT("Information %lu\n", IoStatusBlock->Information);
- MmSafeCopyToUser(FileInformation,
- SystemBuffer,
- IoStatusBlock->Information);
- }
-
- ExFreePool(SystemBuffer);
-
- return Status;
+ /* Return the Status */
+ return Status;
}
/*