PIRP Irp;\r
PDEVICE_OBJECT DeviceObject;\r
PIO_STACK_LOCATION StackPtr;\r
+ BOOLEAN LocalEvent = FALSE;\r
+ KEVENT Event;\r
NTSTATUS Status;\r
+ PAGED_CODE();\r
\r
- if (FileInformationClass == FileCompletionInformation)\r
- {\r
- return STATUS_NOT_IMPLEMENTED;\r
- }\r
-\r
- Status = ObReferenceObjectByPointer(FileObject,\r
- 0, /* FIXME - depends on the information class */\r
- IoFileObjectType,\r
- KernelMode);\r
- if (!NT_SUCCESS(Status)) return(Status);\r
-\r
+ /* Reference the object */\r
+ ObReferenceObject(FileObject);\r
\r
- DeviceObject = FileObject->DeviceObject;\r
+ /* Check if this is a file that was opened for Synch I/O */\r
+ if (FileObject->Flags & FO_SYNCHRONOUS_IO)\r
+ {\r
+ /* Lock it */\r
+ IopLockFileObject(FileObject);\r
\r
- Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);\r
- if (!Irp)\r
+ /* Use File Object event */\r
+ KeClearEvent(&FileObject->Event);\r
+ }\r
+ else\r
{\r
- ObDereferenceObject(FileObject);\r
- return STATUS_INSUFFICIENT_RESOURCES;\r
+ /* Use local event */\r
+ KeInitializeEvent(&Event, SynchronizationEvent, FALSE);\r
+ LocalEvent = TRUE;\r
}\r
\r
- /* Trigger FileObject/Event dereferencing */\r
+ /* Get the Device Object */\r
+ DeviceObject = IoGetRelatedDeviceObject(FileObject);\r
+\r
+ /* Allocate the IRP */\r
+ Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);\r
+ if (!Irp) return IopCleanupFailedIrp(FileObject, NULL);\r
+\r
+ /* Set the IRP */\r
Irp->Tail.Overlay.OriginalFileObject = FileObject;\r
Irp->RequestorMode = KernelMode;\r
- Irp->AssociatedIrp.SystemBuffer = FileInformation;\r
+ Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;\r
Irp->UserIosb = &IoStatusBlock;\r
- Irp->UserEvent = &FileObject->Event;\r
+ Irp->UserEvent = (LocalEvent) ? &Event : NULL;\r
+ Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;\r
+ Irp->Flags |= IRP_BUFFERED_IO;\r
+ Irp->AssociatedIrp.SystemBuffer = FileInformation;\r
Irp->Tail.Overlay.Thread = PsGetCurrentThread();\r
- KeResetEvent( &FileObject->Event );\r
\r
+ /* Set the Stack Data */\r
StackPtr = IoGetNextIrpStackLocation(Irp);\r
StackPtr->MajorFunction = IRP_MJ_SET_INFORMATION;\r
- StackPtr->MinorFunction = 0;\r
- StackPtr->Flags = 0;\r
- StackPtr->Control = 0;\r
- StackPtr->DeviceObject = DeviceObject;\r
StackPtr->FileObject = FileObject;\r
+\r
+ /* Set Parameters */\r
StackPtr->Parameters.SetFile.FileInformationClass = FileInformationClass;\r
StackPtr->Parameters.SetFile.Length = Length;\r
\r
+ /* Queue the IRP */\r
+ IopQueueIrpToThread(Irp);\r
+\r
+ /* Call the Driver */\r
Status = IoCallDriver(FileObject->DeviceObject, Irp);\r
- if (Status==STATUS_PENDING)\r
+\r
+ /* Check if this was synch I/O */\r
+ if (!LocalEvent)\r
{\r
- KeWaitForSingleObject(&FileObject->Event,\r
+ /* Check if the requet is pending */\r
+ if (Status == STATUS_PENDING)\r
+ {\r
+ /* Wait on the file object */\r
+ Status = KeWaitForSingleObject(&FileObject->Event,\r
+ Executive,\r
+ KernelMode,\r
+ FileObject->Flags & FO_ALERTABLE_IO,\r
+ NULL);\r
+ if (Status == STATUS_ALERTED)\r
+ {\r
+ /* Abort the operation */\r
+ IopAbortInterruptedIrp(&FileObject->Event, Irp);\r
+ }\r
+\r
+ /* Get the final status */\r
+ Status = FileObject->FinalStatus;\r
+ }\r
+\r
+ /* Release the file lock */\r
+ IopUnlockFileObject(FileObject);\r
+ }\r
+ else if (Status == STATUS_PENDING)\r
+ {\r
+ /* Wait on the local event and get the final status */\r
+ KeWaitForSingleObject(&Event,\r
Executive,\r
KernelMode,\r
- FileObject->Flags & FO_ALERTABLE_IO,\r
+ FALSE,\r
NULL);\r
Status = IoStatusBlock.Status;\r
}\r
\r
+ /* Return the status */\r
return Status;\r
}\r
\r