Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

118 lines
4.5 KiB

/*-------------------------------------------------------------------
| waitmask.c -
3-30-99 - fix cancel event operation(race-condition) to avoid
potential bug-check on queued eventwait cancel.
11-24-98 - update event kdprint debug messages - kpb
Copyright 1993-99 Comtrol Corporation. All rights reserved.
|--------------------------------------------------------------------*/
#include "precomp.h"
/*------------------------------------------------------------------
SerialCancelWait - (setup in ioctl.c currently, 3-28-98, kpb)
This routine is used to cancel a irp that is waiting on a comm event.
|-------------------------------------------------------------------*/
VOID SerialCancelWait(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
PSERIAL_DEVICE_EXTENSION Extension = DeviceObject->DeviceExtension;
MyKdPrint(D_Ioctl,("CancelWait\n"))
// take out, 3-30-99, kpb... Extension->IrpMaskLocation = NULL;
if (Extension->CurrentWaitIrp)
{
PIRP Irp_tmp;
MyKdPrint(D_Ioctl,("Cancel a Wait\n"))
//***** add, 3-30-99, kpb, cause crash on read thread in dos box without
// grab from ISR timer or interrupt routine.
SyncUp(Driver.InterruptObject,
&Driver.TimerLock,
SerialGrabWaitFromIsr,
Extension);
//***** end add, 3-30-99
// ExtTrace(Extension,D_Ioctl, "Cancel Event");
Extension->CurrentWaitIrp->IoStatus.Information = 0;
Extension->CurrentWaitIrp->IoStatus.Status = STATUS_CANCELLED;
Irp_tmp = Extension->CurrentWaitIrp;
IoSetCancelRoutine(Irp_tmp, NULL); // add 9-15-97, kpb
Extension->CurrentWaitIrp = 0;
IoReleaseCancelSpinLock(Irp->CancelIrql);
SerialCompleteRequest(Extension, Irp_tmp, IO_SERIAL_INCREMENT);
}
else
{
IoReleaseCancelSpinLock(Irp->CancelIrql);
ExtTrace(Extension,D_Ioctl, "Err Cancel Event!");
MyKdPrint(D_Ioctl,("No Wait to Cancel\n"))
}
}
/*------------------------------------------------------------------
SerialCompleteWait - called by isr.c via CommWaitDpc. It nulls out
IrpMaskLocation to signal control passed back to us.
|-------------------------------------------------------------------*/
VOID SerialCompleteWait(IN PKDPC Dpc,IN PVOID DeferredContext,
IN PVOID SystemContext1, IN PVOID SystemContext2)
{
PSERIAL_DEVICE_EXTENSION Extension = DeferredContext;
KIRQL OldIrql;
PIRP Irp_tmp;
UNREFERENCED_PARAMETER(Dpc);
UNREFERENCED_PARAMETER(SystemContext1);
UNREFERENCED_PARAMETER(SystemContext2);
MyKdPrint(D_Ioctl,("Complete Wait\n"))
IoAcquireCancelSpinLock(&OldIrql);
if (Extension->CurrentWaitIrp != 0)
{
MyKdPrint(D_Ioctl,("Complete a Wait\n"))
ExtTrace2(Extension,D_Ioctl, "Event Done Got:%xH Mask:%xH",
*(ULONG *) Extension->CurrentWaitIrp->AssociatedIrp.SystemBuffer,
Extension->IsrWaitMask);
Extension->WaitIsISRs = 0;
Extension->IrpMaskLocation = &Extension->DummyIrpMaskLoc;
// caller sets the ULONG bit flags indicating event at .SystemBuffer
//*(ULONG *)Extension->CurrentWaitIrp->AssociatedIrp.SystemBuffer = 0;
Extension->CurrentWaitIrp->IoStatus.Status = STATUS_SUCCESS;
Extension->CurrentWaitIrp->IoStatus.Information = sizeof(ULONG);
Irp_tmp = Extension->CurrentWaitIrp;
IoSetCancelRoutine(Irp_tmp, NULL); // add 9-15-97, kpb
Extension->CurrentWaitIrp = 0;
IoReleaseCancelSpinLock(OldIrql);
SerialCompleteRequest(Extension, Irp_tmp, IO_SERIAL_INCREMENT);
}
else
{
MyKdPrint(D_Ioctl,("No wait to complete\n"))
IoReleaseCancelSpinLock(OldIrql);
}
}
/*------------------------------------------------------------------
SerialGrabWaitFromIsr - Take back the wait packet from the ISR by
reseting IrpMaskLocation in extension. Need to use a sync with
isr/timer routine to avoid contention in multiprocessor environments.
Called from sync routine or with timer spinlock held.
App - Can set IrpMaskLocation to give read-irp handling to the ISR without
syncing to ISR.
ISR - Can reset ReadPending to give wait-irp handling back to app-time.
If App wants to grab control of read-irp handling back from ISR, then
it must sync-up with the isr/timer routine which has control.
|-------------------------------------------------------------------*/
BOOLEAN SerialGrabWaitFromIsr(PSERIAL_DEVICE_EXTENSION Extension)
{
Extension->WaitIsISRs = 0;
Extension->IrpMaskLocation = &Extension->DummyIrpMaskLoc;
return FALSE;
}