📄 waitmask.c
字号:
NewIrp);
}
}
}
} while (NewIrp);
return FirstStatus;
}
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.
--*/
{
PSERIAL_DEVICE_EXTENSION Extension = Context;
SERIAL_LOCKED_PAGED_CODE();
SerialDbgPrintEx(SERDIAG3, "In SerialGrabWaitFromIsr\n");
if (Extension->IrpMaskLocation) {
SerialDbgPrintEx(SERDIAG4, "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.
--*/
{
PSERIAL_DEVICE_EXTENSION Extension = Context;
SERIAL_LOCKED_PAGED_CODE();
SerialDbgPrintEx(SERDIAG3, "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) {
SerialDbgPrintEx(SERDIAG4, "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;
//
// Record where the "completion mask" should be set.
//
Extension->IrpMaskLocation =
Extension->CurrentWaitIrp->AssociatedIrp.SystemBuffer;
SerialDbgPrintEx( SERDIAG4, "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 {
SerialDbgPrintEx(SERDIAG4, "%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
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.
--*/
{
PSERIAL_DEVICE_EXTENSION Extension = Context;
SERIAL_LOCKED_PAGED_CODE();
SerialDbgPrintEx(SERDIAG3, "In SerialFinishOldWait\n");
if (Extension->IrpMaskLocation) {
SerialDbgPrintEx(SERDIAG4, "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);
SerialDbgPrintEx( SERDIAG4, "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.
--*/
{
PSERIAL_DEVICE_EXTENSION Extension = DeviceObject->DeviceExtension;
SERIAL_LOCKED_PAGED_CODE();
SerialDbgPrintEx(SERDIAG3, "In SerialCancelWait\n");
SerialDbgPrintEx(SERDIAG4, "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
)
{
PSERIAL_DEVICE_EXTENSION Extension = DeferredContext;
KIRQL OldIrql;
SerialDbgPrintEx(DPFLTR_TRACE_LEVEL, ">SerialCompleteWait(%X)\n",
Extension);
SerialDbgPrintEx(SERDIAG3, "In SerialCompleteWait\n");
UNREFERENCED_PARAMETER(SystemContext1);
UNREFERENCED_PARAMETER(SystemContext2);
IoAcquireCancelSpinLock(&OldIrql);
SerialDbgPrintEx(SERDIAG4, "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);
SerialDbgPrintEx(DPFLTR_TRACE_LEVEL, "<SerialCompleteWait\n");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -