mirror of
https://github.com/reactos/reactos.git
synced 2024-07-05 12:15:46 +00:00
- Changed IopCompleteRequest back to the old schematics (rev 14933) with some minor corrections.
- The status results are always set before an event is signaled. - Some checks for ASYNC irp's were wrong (missing brackets, now replaced with SyncIrp). - Don't signal the FO event if it is the same as the UserEvent. - Set the IOSB on error for async irp's with a sync FO (fix bug #609). IMHO, the old schematics is wrong, because on error it is possible that an event isn't signaled if the driver has previous returned STATUS_PENDING. In this case, the caller will wait forever. svn path=/trunk/; revision=15117
This commit is contained in:
parent
35deccffea
commit
83fb8b7c7c
|
@ -117,6 +117,162 @@ IopCompleteRequest(PKAPC Apc,
|
||||||
RemoveEntryList(&Irp->ThreadListEntry);
|
RemoveEntryList(&Irp->ThreadListEntry);
|
||||||
InitializeListHead(&Irp->ThreadListEntry);
|
InitializeListHead(&Irp->ThreadListEntry);
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
/* Check for Success but allow failure for Async IRPs */
|
||||||
|
if (NT_SUCCESS(Irp->IoStatus.Status) ||
|
||||||
|
(Irp->PendingReturned &&
|
||||||
|
!SyncIrp &&
|
||||||
|
(FileObject == NULL || FileObject->Flags & FO_SYNCHRONOUS_IO)))
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
/* Save the IOSB Information */
|
||||||
|
*Irp->UserIosb = Irp->IoStatus;
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
/* Ignore any error */
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
/* Check if there's an event */
|
||||||
|
if (UserEvent)
|
||||||
|
{
|
||||||
|
/* Check if we should signal the File Object Event as well */
|
||||||
|
if (FileObject)
|
||||||
|
{
|
||||||
|
/* If the File Object is SYNC, then we need to signal its event too */
|
||||||
|
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
|
||||||
|
{
|
||||||
|
/* Set the Status */
|
||||||
|
FileObject->FinalStatus = Irp->IoStatus.Status;
|
||||||
|
|
||||||
|
/* Signal Event */
|
||||||
|
KeSetEvent(&FileObject->Event, 0, FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Signal the Event */
|
||||||
|
KeSetEvent(UserEvent, 0, FALSE);
|
||||||
|
|
||||||
|
/* Dereference the Event if this is an ASYNC IRP */
|
||||||
|
if (FileObject && !SyncIrp && UserEvent != &FileObject->Event)
|
||||||
|
{
|
||||||
|
ObDereferenceObject(UserEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (FileObject)
|
||||||
|
{
|
||||||
|
/* Set the Status */
|
||||||
|
FileObject->FinalStatus = Irp->IoStatus.Status;
|
||||||
|
|
||||||
|
/* Signal the File Object Instead */
|
||||||
|
KeSetEvent(&FileObject->Event, 0, FALSE);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now call the User APC if one was requested */
|
||||||
|
if (Irp->Overlay.AsynchronousParameters.UserApcRoutine != NULL)
|
||||||
|
{
|
||||||
|
KeInitializeApc(&Irp->Tail.Apc,
|
||||||
|
KeGetCurrentThread(),
|
||||||
|
CurrentApcEnvironment,
|
||||||
|
IopFreeIrpKernelApc,
|
||||||
|
IopAbortIrpKernelApc,
|
||||||
|
(PKNORMAL_ROUTINE)Irp->Overlay.AsynchronousParameters.UserApcRoutine,
|
||||||
|
Irp->RequestorMode,
|
||||||
|
Irp->Overlay.AsynchronousParameters.UserApcContext);
|
||||||
|
|
||||||
|
KeInsertQueueApc(&Irp->Tail.Apc,
|
||||||
|
Irp->UserIosb,
|
||||||
|
NULL,
|
||||||
|
2);
|
||||||
|
Irp = NULL;
|
||||||
|
}
|
||||||
|
else if (FileObject && FileObject->CompletionContext)
|
||||||
|
{
|
||||||
|
/* Call the IO Completion Port if we have one, instead */
|
||||||
|
IoSetIoCompletion(FileObject->CompletionContext->Port,
|
||||||
|
FileObject->CompletionContext->Key,
|
||||||
|
Irp->Overlay.AsynchronousParameters.UserApcContext,
|
||||||
|
Irp->IoStatus.Status,
|
||||||
|
Irp->IoStatus.Information,
|
||||||
|
FALSE);
|
||||||
|
Irp = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Signal the Events only if PendingReturned and we have a File Object */
|
||||||
|
if (FileObject && Irp->PendingReturned)
|
||||||
|
{
|
||||||
|
/* Check for SYNC IRP */
|
||||||
|
if (SyncIrp)
|
||||||
|
{
|
||||||
|
/* Set the status in this case only */
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
*Irp->UserIosb = Irp->IoStatus;
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
/* Ignore any error */
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
/* Signal our event if we have one */
|
||||||
|
if (UserEvent)
|
||||||
|
{
|
||||||
|
KeSetEvent(UserEvent, 0, FALSE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Signal the File's Event instead */
|
||||||
|
KeSetEvent(&FileObject->Event, 0, FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if 1
|
||||||
|
/* FIXME: This is necessary to fix bug #609 */
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
*Irp->UserIosb = Irp->IoStatus;
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
/* Ignore any error */
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
#endif
|
||||||
|
/* We'll report the Status to the File Object, not the IRP */
|
||||||
|
FileObject->FinalStatus = Irp->IoStatus.Status;
|
||||||
|
|
||||||
|
/* Signal the File Object ONLY if this was Async */
|
||||||
|
KeSetEvent(&FileObject->Event, 0, FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dereference the Event if it's an ASYNC IRP on a File Object */
|
||||||
|
if (UserEvent && !SyncIrp && FileObject)
|
||||||
|
{
|
||||||
|
if (UserEvent != &FileObject->Event)
|
||||||
|
{
|
||||||
|
ObDereferenceObject(UserEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dereference the File Object */
|
||||||
|
if (FileObject) ObDereferenceObject(FileObject);
|
||||||
|
|
||||||
|
if (Irp)
|
||||||
|
{
|
||||||
|
/* Free the IRP */
|
||||||
|
IoFreeIrp(Irp);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
if (NT_SUCCESS(Irp->IoStatus.Status) || Irp->PendingReturned)
|
if (NT_SUCCESS(Irp->IoStatus.Status) || Irp->PendingReturned)
|
||||||
{
|
{
|
||||||
_SEH_TRY
|
_SEH_TRY
|
||||||
|
@ -198,6 +354,7 @@ IopCompleteRequest(PKAPC Apc,
|
||||||
/* Dereference the File Object */
|
/* Dereference the File Object */
|
||||||
ObDereferenceObject(FileObject);
|
ObDereferenceObject(FileObject);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
Loading…
Reference in a new issue