Anyone can tell me why CONTAINING_RECORD cann’t work.
typedef struct _ReadIRPEntry
{
//LIST_ENTRY listEntry;
PIRP Irp;
LARGE_INTEGER readIRPTimeout;
BOOLEAN bCanceled;//if this IRP is canceled, then it is true;
} ReadIRPEntry, *PReadIRPEntry;
I keep an queue for every read IRP with an entry of the above structure ReadIRPEntry.
And I set a cancel routine for every enqueued read Irp.
VOID ReadCancelRoutine(IN PDEVICE_OBJECT pFdo,
IN PIRP Irp)
{
PDEVICE_EXTENSION pdx= (PDEVICE_EXTENSION)pFdo->DeviceExtension;
NTSTATUS status=STATUS_UNSUCCESSFUL;
KIRQL OldIrql;
PReadIRPEntry pReadIrpEntry =NULL;
LIST_ENTRY listEntry;
PKLIST_NODE pListNode;
BOOLEAN bDelete;
pReadIrpEntry=CONTAINING_RECORD(&Irp,ReadIRPEntry,Irp);
bDelete = pReadIrpEntry->bCanceled;
if (bDelete)
{
ExFreePool(pReadIrpEntry);
}
else
{
pListNode=CONTAINING_RECORD(&pReadIrpEntry,KLIST_NODE,m_pvData);
RemoveNode(&pdx->ReadIRPQueue, pListNode, TRUE);
}
IoReleaseCancelSpinLock(Irp->CancelIrql);
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_CANCELLED;
IoCompleteRequest( Irp, IO_NO_INCREMENT);
lPendingIRPCountDecrement(pdx);
return;
}
in IRP_MJ_DEVICE_CONTROL dispatch routine, I called IoCancelIrp as the following.
pReadIrpEntry = RemoveHead(&pdx->ReadIRPQueue, FALSE);
if (pReadIrpEntry!=NULL && pReadIrpEntry->Irp!=NULL)
{
pReadIrpEntry->bCanceled = TRUE;
IoCancelIrp(pReadIrpEntry->Irp);
}
The error is pReadIrpEntry’s address in IRP_MJ_DEVICE_CONTROL dispatch routine is different to pReadIrpEntry’s in Cancel IRP routine(or to pReadIrpEntry=CONTAINING_RECORD(&Irp,ReadIRPEntry,Irp);).
Why?
thank you very much!