mirror of
https://github.com/reactos/reactos.git
synced 2025-01-01 12:04:51 +00:00
- Guard the copying to the IOSB.
- Do the main processing on success or if previous STATUS_PENDING was returned. Do not use some of the IRP and FO flags at this point. - Set all results before signaling the events. - Signal the FO event previous the user event. - Made the code a little bit shorter. svn path=/trunk/; revision=14988
This commit is contained in:
parent
e80efe27d7
commit
4200c75f3b
1 changed files with 85 additions and 132 deletions
|
@ -1222,6 +1222,8 @@ IoSecondStageCompletion(PKAPC Apc,
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
PIRP Irp;
|
PIRP Irp;
|
||||||
PMDL Mdl, NextMdl;
|
PMDL Mdl, NextMdl;
|
||||||
|
PKEVENT UserEvent;
|
||||||
|
BOOLEAN SyncIrp;
|
||||||
|
|
||||||
if (Apc) DPRINT("IoSecondStageCompletition with APC: %x\n", Apc);
|
if (Apc) DPRINT("IoSecondStageCompletition with APC: %x\n", Apc);
|
||||||
|
|
||||||
|
@ -1230,6 +1232,9 @@ IoSecondStageCompletion(PKAPC Apc,
|
||||||
Irp = CONTAINING_RECORD(Apc, IRP, Tail.Apc);
|
Irp = CONTAINING_RECORD(Apc, IRP, Tail.Apc);
|
||||||
DPRINT("IoSecondStageCompletition, %x\n", Irp);
|
DPRINT("IoSecondStageCompletition, %x\n", Irp);
|
||||||
|
|
||||||
|
UserEvent = Irp->UserEvent;
|
||||||
|
SyncIrp = Irp->Flags & IRP_SYNCHRONOUS_API ? TRUE : FALSE;
|
||||||
|
|
||||||
/* Handle Buffered case first */
|
/* Handle Buffered case first */
|
||||||
if (Irp->Flags & IRP_BUFFERED_IO)
|
if (Irp->Flags & IRP_BUFFERED_IO)
|
||||||
{
|
{
|
||||||
|
@ -1265,58 +1270,44 @@ IoSecondStageCompletion(PKAPC Apc,
|
||||||
}
|
}
|
||||||
Irp->MdlAddress = NULL;
|
Irp->MdlAddress = NULL;
|
||||||
|
|
||||||
if (Irp->UserIosb)
|
/* Remove the IRP from the list of Thread Pending IRPs */
|
||||||
|
RemoveEntryList(&Irp->ThreadListEntry);
|
||||||
|
InitializeListHead(&Irp->ThreadListEntry);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Irp->IoStatus.Status) || Irp->PendingReturned)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
{
|
{
|
||||||
/* Save the IOSB Information */
|
/* Save the IOSB Information */
|
||||||
*Irp->UserIosb = Irp->IoStatus;
|
*Irp->UserIosb = Irp->IoStatus;
|
||||||
}
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
/* Check for Success but allow failure for Async IRPs */
|
|
||||||
if (NT_SUCCESS(Irp->IoStatus.Status) ||
|
|
||||||
(Irp->PendingReturned &&
|
|
||||||
!(Irp->Flags & IRP_SYNCHRONOUS_API) &&
|
|
||||||
(FileObject == NULL || FileObject->Flags & FO_SYNCHRONOUS_IO)))
|
|
||||||
{
|
{
|
||||||
|
/* Ignore any error */
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
/* Check if there's an event */
|
|
||||||
if (Irp->UserEvent)
|
|
||||||
{
|
|
||||||
/* Signal the Event */
|
|
||||||
KeSetEvent(Irp->UserEvent, 0, FALSE);
|
|
||||||
|
|
||||||
/* Check if we should signal the File Object Event as well */
|
|
||||||
if (FileObject)
|
if (FileObject)
|
||||||
{
|
{
|
||||||
/* Dereference the Event if this is an ASYNC IRP */
|
|
||||||
if (!Irp->Flags & IRP_SYNCHRONOUS_API)
|
|
||||||
{
|
|
||||||
ObDereferenceObject(Irp->UserEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If the File Object is SYNC, then we need to signal its event too */
|
|
||||||
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
|
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
|
||||||
|
{
|
||||||
|
/* Set the Status */
|
||||||
|
FileObject->FinalStatus = Irp->IoStatus.Status;
|
||||||
|
|
||||||
|
if (UserEvent != &FileObject->Event)
|
||||||
{
|
{
|
||||||
/* Signal Event */
|
/* Signal Event */
|
||||||
KeSetEvent(&FileObject->Event, 0, FALSE);
|
KeSetEvent(&FileObject->Event, 0, FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Set the Status */
|
/* Signal the user event, if one exist */
|
||||||
FileObject->FinalStatus = Irp->IoStatus.Status;
|
if (UserEvent)
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (FileObject)
|
|
||||||
{
|
{
|
||||||
/* Signal the File Object Instead */
|
KeSetEvent(UserEvent, 0, FALSE);
|
||||||
KeSetEvent(&FileObject->Event, 0, FALSE);
|
|
||||||
|
|
||||||
/* Set the Status */
|
|
||||||
FileObject->FinalStatus = Irp->IoStatus.Status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove the IRP from the list of Thread Pending IRPs */
|
|
||||||
RemoveEntryList(&Irp->ThreadListEntry);
|
|
||||||
InitializeListHead(&Irp->ThreadListEntry);
|
|
||||||
|
|
||||||
/* Now call the User APC if one was requested */
|
/* Now call the User APC if one was requested */
|
||||||
if (Irp->Overlay.AsynchronousParameters.UserApcRoutine != NULL)
|
if (Irp->Overlay.AsynchronousParameters.UserApcRoutine != NULL)
|
||||||
{
|
{
|
||||||
|
@ -1333,6 +1324,7 @@ IoSecondStageCompletion(PKAPC Apc,
|
||||||
Irp->UserIosb,
|
Irp->UserIosb,
|
||||||
NULL,
|
NULL,
|
||||||
2);
|
2);
|
||||||
|
Irp = NULL;
|
||||||
}
|
}
|
||||||
else if (FileObject && FileObject->CompletionContext)
|
else if (FileObject && FileObject->CompletionContext)
|
||||||
{
|
{
|
||||||
|
@ -1343,64 +1335,25 @@ IoSecondStageCompletion(PKAPC Apc,
|
||||||
Irp->IoStatus.Status,
|
Irp->IoStatus.Status,
|
||||||
Irp->IoStatus.Information,
|
Irp->IoStatus.Information,
|
||||||
FALSE);
|
FALSE);
|
||||||
|
Irp = NULL;
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
|
||||||
|
if (Irp)
|
||||||
{
|
{
|
||||||
/* Don't have anything, free it */
|
|
||||||
IoFreeIrp(Irp);
|
IoFreeIrp(Irp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dereference the File Object */
|
if (FileObject)
|
||||||
if (FileObject) ObDereferenceObject(FileObject);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
/* Remove the IRP from the list of Thread Pending IRPs */
|
/* Dereference the user event, if it is an event object */
|
||||||
RemoveEntryList(&Irp->ThreadListEntry);
|
if (UserEvent && !SyncIrp && UserEvent != &FileObject->Event)
|
||||||
InitializeListHead(&Irp->ThreadListEntry);
|
|
||||||
|
|
||||||
/* Signal the Events only if PendingReturned and we have a File Object */
|
|
||||||
if (FileObject && Irp->PendingReturned)
|
|
||||||
{
|
{
|
||||||
/* Check for SYNC IRP */
|
ObDereferenceObject(UserEvent);
|
||||||
if (Irp->Flags & IRP_SYNCHRONOUS_API)
|
|
||||||
{
|
|
||||||
|
|
||||||
/* Signal our event if we have one */
|
|
||||||
if (Irp->UserEvent)
|
|
||||||
{
|
|
||||||
KeSetEvent(Irp->UserEvent, 0, FALSE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Signal the File's Event instead */
|
|
||||||
KeSetEvent(&FileObject->Event, 0, FALSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* 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 (Irp->UserEvent && !(Irp->Flags & IRP_SYNCHRONOUS_API) && FileObject)
|
|
||||||
{
|
|
||||||
if (Irp->UserEvent != &FileObject->Event)
|
|
||||||
{
|
|
||||||
ObDereferenceObject(Irp->UserEvent);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dereference the File Object */
|
/* Dereference the File Object */
|
||||||
if (FileObject) ObDereferenceObject(FileObject);
|
ObDereferenceObject(FileObject);
|
||||||
|
|
||||||
/* Free the IRP */
|
|
||||||
IoFreeIrp(Irp);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue