Author: ion Date: Sun Jul 2 20:41:49 2006 New Revision: 22771
URL: http://svn.reactos.org/svn/reactos?rev=22771&view=rev Log: - Same changes for IoSertInformation: Lock the FO, queue the IRP, support alerted I/O, etc...
Modified: trunk/reactos/ntoskrnl/io/iomgr/iofunc.c
Modified: trunk/reactos/ntoskrnl/io/iomgr/iofunc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/iofunc.c?... ============================================================================== --- trunk/reactos/ntoskrnl/io/iomgr/iofunc.c (original) +++ trunk/reactos/ntoskrnl/io/iomgr/iofunc.c Sun Jul 2 20:41:49 2006 @@ -635,59 +635,100 @@ PIRP Irp; PDEVICE_OBJECT DeviceObject; PIO_STACK_LOCATION StackPtr; + BOOLEAN LocalEvent = FALSE; + KEVENT Event; NTSTATUS Status; - - if (FileInformationClass == FileCompletionInformation) - { - return STATUS_NOT_IMPLEMENTED; - } - - Status = ObReferenceObjectByPointer(FileObject, - 0, /* FIXME - depends on the information class */ - IoFileObjectType, - KernelMode); - if (!NT_SUCCESS(Status)) return(Status); - - - DeviceObject = FileObject->DeviceObject; - - Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE); - if (!Irp) - { - ObDereferenceObject(FileObject); - return STATUS_INSUFFICIENT_RESOURCES; - } - - /* Trigger FileObject/Event dereferencing */ + PAGED_CODE(); + + /* Reference the object */ + ObReferenceObject(FileObject); + + /* Check if this is a file that was opened for Synch I/O */ + if (FileObject->Flags & FO_SYNCHRONOUS_IO) + { + /* Lock it */ + IopLockFileObject(FileObject); + + /* Use File Object event */ + KeClearEvent(&FileObject->Event); + } + else + { + /* Use local event */ + KeInitializeEvent(&Event, SynchronizationEvent, FALSE); + LocalEvent = TRUE; + } + + /* Get the Device Object */ + DeviceObject = IoGetRelatedDeviceObject(FileObject); + + /* Allocate the IRP */ + Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); + if (!Irp) return IopCleanupFailedIrp(FileObject, NULL); + + /* Set the IRP */ Irp->Tail.Overlay.OriginalFileObject = FileObject; Irp->RequestorMode = KernelMode; + Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL; + Irp->UserIosb = &IoStatusBlock; + Irp->UserEvent = (LocalEvent) ? &Event : NULL; + Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0; + Irp->Flags |= IRP_BUFFERED_IO; Irp->AssociatedIrp.SystemBuffer = FileInformation; - Irp->UserIosb = &IoStatusBlock; - Irp->UserEvent = &FileObject->Event; Irp->Tail.Overlay.Thread = PsGetCurrentThread(); - KeResetEvent( &FileObject->Event ); - + + /* Set the Stack Data */ StackPtr = IoGetNextIrpStackLocation(Irp); StackPtr->MajorFunction = IRP_MJ_SET_INFORMATION; - StackPtr->MinorFunction = 0; - StackPtr->Flags = 0; - StackPtr->Control = 0; - StackPtr->DeviceObject = DeviceObject; StackPtr->FileObject = FileObject; + + /* Set Parameters */ StackPtr->Parameters.SetFile.FileInformationClass = FileInformationClass; StackPtr->Parameters.SetFile.Length = Length;
+ /* Queue the IRP */ + IopQueueIrpToThread(Irp); + + /* Call the Driver */ Status = IoCallDriver(FileObject->DeviceObject, Irp); - if (Status==STATUS_PENDING) - { - KeWaitForSingleObject(&FileObject->Event, + + /* Check if this was synch I/O */ + if (!LocalEvent) + { + /* Check if the requet is pending */ + if (Status == STATUS_PENDING) + { + /* Wait on the file object */ + Status = KeWaitForSingleObject(&FileObject->Event, + Executive, + KernelMode, + FileObject->Flags & FO_ALERTABLE_IO, + NULL); + if (Status == STATUS_ALERTED) + { + /* Abort the operation */ + IopAbortInterruptedIrp(&FileObject->Event, Irp); + } + + /* Get the final status */ + Status = FileObject->FinalStatus; + } + + /* Release the file lock */ + IopUnlockFileObject(FileObject); + } + else if (Status == STATUS_PENDING) + { + /* Wait on the local event and get the final status */ + KeWaitForSingleObject(&Event, Executive, KernelMode, - FileObject->Flags & FO_ALERTABLE_IO, + FALSE, NULL); Status = IoStatusBlock.Status; }
+ /* Return the status */ return Status; }