📄 waitmask.c
字号:
}
BOOLEAN
SerialGrabWaitFromIsr(
IN PVOID Context
)
/*++
Routine Description:
This routine will check to see if the ISR still knows about
a wait irp by checking to see if the IrpMaskLocation is non-null.
If it is then it will zero the Irpmasklocation (which in effect
grabs the irp away from the isr). This routine is only called
buy the cancel code for the wait.
NOTE: This is called by KeSynchronizeExecution.
Arguments:
Context - A pointer to the device extension
Return Value:
Always FALSE.
--*/
{
PDEVICE_EXTENSION Extension = Context;
// SERIAL_LOCKED_PAGED_CODE();
SerialDump(
SERDIAG3,
("SERIAL: In SerialGrabWaitFromIsr\n")
);
if (Extension->IrpMaskLocation) {
SerialDump(
SERDIAG4,
("SERIAL: The isr still owns the irp %x, mask location is %x\n"
"------- and system buffer is %x\n",
Extension->CurrentWaitIrp,Extension->IrpMaskLocation,
Extension->CurrentWaitIrp->AssociatedIrp.SystemBuffer)
);
//
// The isr still "owns" the irp.
//
*Extension->IrpMaskLocation = 0;
Extension->IrpMaskLocation = NULL;
Extension->CurrentWaitIrp->IoStatus.Information = sizeof(ULONG);
//
// Since the isr no longer references the irp we need to
// decrement the reference count.
//
SERIAL_CLEAR_REFERENCE(
Extension->CurrentWaitIrp,
SERIAL_REF_ISR
);
}
return FALSE;
}
BOOLEAN
SerialGiveWaitToIsr(
IN PVOID Context
)
/*++
Routine Description:
This routine simply sets a variable in the device extension
so that the isr knows that we have a wait irp.
NOTE: This is called by KeSynchronizeExecution.
NOTE: This routine assumes that it is called with the
cancel spinlock held.
Arguments:
Context - Simply a pointer to the device extension.
Return Value:
Always FALSE.
--*/
{
PDEVICE_EXTENSION Extension = Context;
// SERIAL_LOCKED_PAGED_CODE();
SerialDump(
SERDIAG3,
("SERIAL: In SerialGiveWaitToIsr\n")
);
//
// There certainly shouldn't be a current mask location at
// this point since we have a new current wait irp.
//
ASSERT(!Extension->IrpMaskLocation);
//
// The isr may or may not actually reference this irp. It
// won't if the wait can be satisfied immediately. However,
// since it will then go through the normal completion sequence,
// we need to have an incremented reference count anyway.
//
SERIAL_SET_REFERENCE(
Extension->CurrentWaitIrp,
SERIAL_REF_ISR
);
if (!Extension->HistoryMask) {
SerialDump(
SERDIAG4,
("SERIAL: No events occured prior to the wait call\n")
);
//
// Although this wait might not be for empty transmit
// queue, it doesn't hurt anything to set it to false.
//
// Extension->EmptiedTransmit = FALSE; henry
//
// Record where the "completion mask" should be set.
//
Extension->IrpMaskLocation =
Extension->CurrentWaitIrp->AssociatedIrp.SystemBuffer;
SerialDump(
SERDIAG4,
("SERIAL: The isr owns the irp %x, mask location is %x\n"
"------- and system buffer is %x\n",
Extension->CurrentWaitIrp,Extension->IrpMaskLocation,
Extension->CurrentWaitIrp->AssociatedIrp.SystemBuffer)
);
} else {
SerialDump(
SERDIAG4,
("SERIAL: %x occurred prior to the wait - starting the\n"
"------- completion code for %x\n",
Extension->HistoryMask,Extension->CurrentWaitIrp)
);
*((ULONG *)Extension->CurrentWaitIrp->AssociatedIrp.SystemBuffer) =
Extension->HistoryMask;
Extension->HistoryMask = 0;
Extension->CurrentWaitIrp->IoStatus.Information = sizeof(ULONG);
Extension->CurrentWaitIrp->IoStatus.Status = STATUS_SUCCESS;
SerialInsertQueueDpc(
&Extension->CommWaitDpc,
NULL,
NULL,
Extension
);
}
return FALSE;
}
BOOLEAN
SerialFinishOldWait(
IN PVOID Context
)
/*++
Routine Description:
This routine will check to see if the ISR still knows about
a wait irp by checking to see if the Irpmasklocation is non-null.
If it is then it will zero the Irpmasklocation (which in effect
grabs the irp away from the isr). This routine is only called
by the cancel code for the wait.
NOTE: This is called by KeSynchronizeExecution.
Arguments:
Context - A pointer to the device extension
Return Value:
Always FALSE.
--*/
{
// PSERIAL_DEVICE_EXTENSION Extension = Context;
// SERIAL_LOCKED_PAGED_CODE();
PDEVICE_EXTENSION Extension = Context;
SerialDump(
SERDIAG3,
("SERIAL: In SerialFinishOldWait\n")
);
if (Extension->IrpMaskLocation) {
SerialDump(
SERDIAG4,
("SERIAL: The isr still owns the irp %x, mask location is %x\n"
"------- and system buffer is %x\n",
Extension->CurrentWaitIrp,Extension->IrpMaskLocation,
Extension->CurrentWaitIrp->AssociatedIrp.SystemBuffer)
);
//
// The isr still "owns" the irp.
//
*Extension->IrpMaskLocation = 0;
Extension->IrpMaskLocation = NULL;
Extension->CurrentWaitIrp->IoStatus.Information = sizeof(ULONG);
//
// We don't decrement the reference since the completion routine
// will do that.
//
SerialInsertQueueDpc(
&Extension->CommWaitDpc,
NULL,
NULL,
Extension
);
}
//
// Don't wipe out any historical data we are still interested in.
//
Extension->HistoryMask &= *((ULONG *)Extension->CurrentMaskIrp->
AssociatedIrp.SystemBuffer);
Extension->IsrWaitMask = *((ULONG *)Extension->CurrentMaskIrp->
AssociatedIrp.SystemBuffer);
SerialDump(
SERDIAG4,
("SERIAL: Set mask location of %x, in irp %x, with system buffer of %x\n",
Extension->IrpMaskLocation,
Extension->CurrentMaskIrp,Extension->CurrentMaskIrp->AssociatedIrp.SystemBuffer)
);
return FALSE;
}
VOID
SerialCancelWait(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine is used to cancel a irp that is waiting on
a comm event.
Arguments:
DeviceObject - Pointer to the device object for this device
Irp - Pointer to the IRP for the current request
Return Value:
None.
--*/
{
PDEVICE_EXTENSION Extension = DeviceObject->DeviceExtension;
// SERIAL_LOCKED_PAGED_CODE();
SerialDump(
SERDIAG3,
("SERIAL: In SerialCancelWait\n")
);
SerialDump(
SERDIAG4,
("SERIAL: Canceling wait for irp %x\n",Extension->CurrentWaitIrp)
);
SerialTryToCompleteCurrent(
Extension,
SerialGrabWaitFromIsr,
Irp->CancelIrql,
STATUS_CANCELLED,
&Extension->CurrentWaitIrp,
NULL,
NULL,
NULL,
NULL,
NULL,
SERIAL_REF_CANCEL
);
}
VOID
SerialCompleteWait(
IN PKDPC Dpc,
IN PVOID DeferredContext,
IN PVOID SystemContext1,
IN PVOID SystemContext2
)
{
PDEVICE_EXTENSION Extension = DeferredContext;
KIRQL OldIrql;
SerialDump(SERTRACECALLS, ("SERIAL: SerialCompleteWait\n"));
SerialDump(
SERDIAG3,
("SERIAL: In SerialCompleteWait\n")
);
UNREFERENCED_PARAMETER(SystemContext1);
UNREFERENCED_PARAMETER(SystemContext2);
IoAcquireCancelSpinLock(&OldIrql);
SerialDump(
SERDIAG4,
("SERIAL: Completing wait for irp %x\n",Extension->CurrentWaitIrp)
);
SerialTryToCompleteCurrent(
Extension,
NULL,
OldIrql,
STATUS_SUCCESS,
&Extension->CurrentWaitIrp,
NULL,
NULL,
NULL,
NULL,
NULL,
SERIAL_REF_ISR
);
SerialDpcEpilogue(Extension, Dpc);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -