Fix NtQueryDirectoryFile to wait on right status, to actually use the event that the user gives, to select the right device and sync/async wait mode and always use FileIndex = 0 since nothing else can be used for this API. Modified: trunk/reactos/ntoskrnl/io/file.c _____
Modified: trunk/reactos/ntoskrnl/io/file.c --- trunk/reactos/ntoskrnl/io/file.c 2005-05-08 20:15:54 UTC (rev 15150) +++ trunk/reactos/ntoskrnl/io/file.c 2005-05-08 20:20:14 UTC (rev 15151) @@ -2050,116 +2050,133 @@
IN FILE_INFORMATION_CLASS FileInformationClass, IN BOOLEAN ReturnSingleEntry, IN PUNICODE_STRING FileName OPTIONAL, - IN BOOLEAN RestartScan - ) - + IN BOOLEAN RestartScan) { - PIRP Irp; - PDEVICE_OBJECT DeviceObject; - PFILE_OBJECT FileObject; - PIO_STACK_LOCATION IoStack; - KPROCESSOR_MODE PreviousMode; - NTSTATUS Status = STATUS_SUCCESS; + PIRP Irp; + PDEVICE_OBJECT DeviceObject; + PFILE_OBJECT FileObject; + PIO_STACK_LOCATION StackPtr; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + NTSTATUS Status = STATUS_SUCCESS; + BOOLEAN LocalEvent; + PKEVENT Event = NULL;
- DPRINT("NtQueryDirectoryFile()\n"); - - PAGED_CODE(); + DPRINT("NtQueryDirectoryFile()\n"); + PAGED_CODE(); + + /* Validate User-Mode Buffers */ + if(PreviousMode != KernelMode) + { + _SEH_TRY + { + ProbeForWrite(IoStatusBlock, + sizeof(IO_STATUS_BLOCK), + sizeof(ULONG)); + ProbeForWrite(FileInformation, + Length, + sizeof(ULONG)); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END;
- PreviousMode = ExGetPreviousMode(); - - if(PreviousMode != KernelMode) - { - _SEH_TRY - { - ProbeForWrite(IoStatusBlock, - sizeof(IO_STATUS_BLOCK), - sizeof(ULONG)); - ProbeForWrite(FileInformation, - Length, - sizeof(ULONG)); - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; + if(!NT_SUCCESS(Status)) return Status; + }
- if(!NT_SUCCESS(Status)) - { - return Status; - } - } + /* Get File Object */ + Status = ObReferenceObjectByHandle(FileHandle, + FILE_LIST_DIRECTORY, + IoFileObjectType, + PreviousMode, + (PVOID *)&FileObject, + NULL); + if (Status != STATUS_SUCCESS) return(Status); + + /* Get Event Object */ + if (PEvent) + { + Status = ObReferenceObjectByHandle(PEvent, + EVENT_MODIFY_STATE, + ExEventObjectType, + PreviousMode, + (PVOID *)&Event, + NULL); + if (Status != STATUS_SUCCESS) return(Status); + KeClearEvent(Event); + }
- Status = ObReferenceObjectByHandle(FileHandle, - FILE_LIST_DIRECTORY, - IoFileObjectType, - PreviousMode, - (PVOID *)&FileObject, - NULL); + /* Check if this is a direct open or not */ + if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN) + { + DeviceObject = IoGetAttachedDevice(FileObject->DeviceObject); + } + else + { + DeviceObject = IoGetRelatedDeviceObject(FileObject); + }
- if (Status != STATUS_SUCCESS) - { - return(Status); - } - DeviceObject = FileObject->DeviceObject; + /* Check if we should use Sync IO or not */ + if (FileObject->Flags & FO_SYNCHRONOUS_IO) + { + /* Use File Object event */ + KeClearEvent(&FileObject->Event); + } + else + { + LocalEvent = TRUE; + }
- Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE); - if (Irp==NULL) - { - ObDereferenceObject(FileObject); - return STATUS_UNSUCCESSFUL; - } + /* Allocate the IRP */ + if (!(Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE))) + { + ObDereferenceObject(FileObject); + return STATUS_INSUFFICIENT_RESOURCES; + }
- /* Trigger FileObject/Event dereferencing */ - Irp->Tail.Overlay.OriginalFileObject = FileObject; - Irp->RequestorMode = PreviousMode; - Irp->UserIosb = IoStatusBlock; - Irp->UserEvent = &FileObject->Event; - Irp->Tail.Overlay.Thread = PsGetCurrentThread(); - KeResetEvent( &FileObject->Event ); - Irp->UserBuffer=FileInformation; - Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine; - Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext; + /* Set up the IRP */ + Irp->RequestorMode = PreviousMode; + Irp->UserIosb = IoStatusBlock; + Irp->UserEvent = Event; + Irp->Tail.Overlay.Thread = PsGetCurrentThread(); + Irp->Tail.Overlay.OriginalFileObject = FileObject; + Irp->UserBuffer = FileInformation; + Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine; + Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
- IoStack = IoGetNextIrpStackLocation(Irp); + /* Set up Stack Data */ + StackPtr = IoGetNextIrpStackLocation(Irp); + StackPtr->FileObject = FileObject; + StackPtr->MajorFunction = IRP_MJ_DIRECTORY_CONTROL; + StackPtr->MinorFunction = IRP_MN_QUERY_DIRECTORY;
- IoStack->MajorFunction = IRP_MJ_DIRECTORY_CONTROL; - IoStack->MinorFunction = IRP_MN_QUERY_DIRECTORY; - IoStack->Flags = 0; - IoStack->Control = 0; - IoStack->DeviceObject = DeviceObject; - IoStack->FileObject = FileObject; + /* Set Parameters */ + StackPtr->Parameters.QueryDirectory.FileInformationClass = FileInformationClass; + StackPtr->Parameters.QueryDirectory.FileName = FileName; + StackPtr->Parameters.QueryDirectory.FileIndex = 0; + StackPtr->Parameters.QueryDirectory.Length = Length; + StackPtr->Flags = 0; + if (RestartScan) StackPtr->Flags = SL_RESTART_SCAN; + if (ReturnSingleEntry) StackPtr->Flags |= SL_RETURN_SINGLE_ENTRY;
- if (RestartScan) - { - IoStack->Flags = IoStack->Flags | SL_RESTART_SCAN; - } - if (ReturnSingleEntry) - { - IoStack->Flags = IoStack->Flags | SL_RETURN_SINGLE_ENTRY; - } - if (((PFILE_DIRECTORY_INFORMATION)FileInformation)->FileIndex != 0) - { - IoStack->Flags = IoStack->Flags | SL_INDEX_SPECIFIED; - } + /* Call the Driver */ + Status = IoCallDriver(DeviceObject, Irp); + if (Status == STATUS_PENDING) + { + if (!LocalEvent) + { + KeWaitForSingleObject(&FileObject->Event, + Executive, + PreviousMode, + FileObject->Flags & FO_ALERTABLE_IO, + NULL); + Status = FileObject->FinalStatus; + } + }
- IoStack->Parameters.QueryDirectory.FileInformationClass = - FileInformationClass; - IoStack->Parameters.QueryDirectory.FileName = FileName; - IoStack->Parameters.QueryDirectory.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; - } - - return(Status); + /* Return the Status */ + return Status; }
/*