Iocsq’s are for IRPs that will be canceled. This is an irp you created yourself, no one will be canceling it so there is no need to go with the complexity of a csq with a cancel routine. A simple LIST_ENTRY queue heahd and using Tail.Overlay.ListEntry to enqueue the irp on it will be good enough.
Your problem is that the IoCSQ marks the irp as pending with a call to IoMarkIrpPending. IoMarkIrpPending uses the currents tack location
FORCEINLINE
VOID
IoMarkIrpPending(
__inout PIRP Irp
)
/*++
Routine Description:
This routine marks the specified I/O Request Packet (IRP) to indicate
that an initial status of STATUS_PENDING was returned to the caller.
This is used so that I/O completion can determine whether or not to
fully complete the I/O operation requested by the packet.
Arguments:
Irp - Pointer to the I/O Request Packet to be marked pending.
Return Value:
None.
–*/
{
IoGetCurrentIrpStackLocation( (Irp) )->Control |= SL_PENDING_RETURNED;
}
For self allocated IRPs, there is *NO CURRENT STACK LOCATION* (it is invalid). Stack locations are allocated after the IRP itself and grow backwards so the current stack location is one past the end of the IRP allocation. This means that you are touching memory that does not belong to you that is immediate after the irp.
Remove the csq from the equation and you are good to go until your next bug shows up 
d
-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@yahoo.com
Sent: Tuesday, March 24, 2009 12:15 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Virtual Storport Miniport :: Bugcheck C2 - d
Hi guys,
I am a colleague of Charansing and am working with him on this project. We are investigating this bug together. After few investigation we have come to a conclusion that the IRP which we form, for TCP communication using TDI API call “TdiBuildInternalDeviceControlIrp” is getting corrupted somewhere. This IRP is freed by the IO manager during which we were getting the above bug check.
Now i made some changes to code and the bug has changed from C2 to 7E. Following is the abstract of code where i am building the IRP to be sent and queuing it.
pMemVars = (PMEM_C)ExAllocatePoolWithTag(NonPagedPool,sizeof(MEM_C),‘memp’);
pTdiDeviceObj = IoGetRelatedDeviceObject(pConnFileObj);
pMemVars->pStatusBlk = pStatusBlock = (PIO_STATUS_BLOCK)ExAllocatePoolWithTag(NonPagedPool,sizeof(IO_STATUS_BLOCK),‘stbk’);
RtlZeroMemory(pStatusBlock,sizeof(IO_STATUS_BLOCK));
pSendIrp = TdiBuildInternalDeviceControlIrp(TDI_SEND,
pTdiDeviceObj,
pConnFileObj,
&pConnCntx->SendQueue.IoComplete,
pStatusBlock);
if(!pSendIrp)
{
DbgPrint(“IRP Allocation Failed!”);
return STATUS_INSUFFICIENT_RESOURCES;
}
if(pCmdCntx->CommandCode == NBD_CMD_WRITE)
{
pMemVars->pPacket = pPacketData = ExAllocatePoolWithTag(PagedPool,PacketLength + pCmdCntx->Length,‘dnes’);
PacketLength += pCmdCntx->Length;
}
else
{
pMemVars->pPacket = pPacketData = ExAllocatePoolWithTag(PagedPool,PacketLength,‘dnes’);
}
//check if packet data was allocated properly or not
if(!pPacketData)
{
DbgPrint(“Packet Data Allocation Failed!”);
return STATUS_INSUFFICIENT_RESOURCES;
}
pSendMdl = IoAllocateMdl(pPacketData, PacketLength, NULL, FALSE, pSendIrp);
if(!pSendMdl)
{
NBDProtErrDbgPrint(“MDL Allocation Failed!”);
return STATUS_INSUFFICIENT_RESOURCES;
}
__try
{
MmProbeAndLockPages(pSendMdl, KernelMode, IoModifyAccess);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
IoFreeMdl(pSendMdl);
pSendMdl = NULL;
}
PNBD_REQ_PACKET reqpacket = (PNBD_REQ_PACKET)pPacketData;
pCmdCntx->ExpectedSequenceNumber = reqpacket->Handle = pConnCntx->CurrentSequenceNumber;
pConnCntx->CurrentSequenceNumber++;
reqpacket->Length = Length;
reqpacket->offset = Offset;
reqpacket->magic = NBD_REQUEST_MAGIC;
reqpacket->OperationType = Command;
if(!pData)
{
DbgPrint(“Data Buffer Received is Empty!”);
return STATUS_INSUFFICIENT_RESOURCES;
}
if (NBD_CMD_WRITE == Command)
{
RtlCopyMemory((PVOID)((char*)pPacketData+sizeof(NBD_REQ_PACKET)),
(PVOID)((char*)pData+sizeof(SCSI_REQ)),
SwapEndianness(Length));
}
pCmdCntx->pPacketBuffer = pPacketData;
TdiBuildSend(pSendIrp, pTdiDeviceObj, pConnFileObj, NULL, NULL,
pSendMdl, 0, PacketLength);
if(NULL == pCmdCntx)
{
DbgPrint(“Null context!!!”);
NBDPROTASSERT(0);
}
KeAcquireSpinLock(&pConnCntx->SendLock,&OldIrql);
IoCsqInsertIrp(&pConnCntx->SendQueue.CancelSafeQueue,pSendIrp,NULL);
ExInterlockedInsertTailList(&pConnCntx->MemoryFreeList,pMemVars,&pConnCntx->MemoryLock);
ExInterlockedInsertTailList(&pConnCntx->ContextList,pCmdCntx,&pConnCntx->ContextLock);
KeSetEvent(&pConnCntx->SendQueue.NBDQueueEvent,0,FALSE);
KeReleaseSpinLock(&pConnCntx->SendLock,OldIrql);
The following thread removes the IRPs from the queue and sends it to TCP
do
{
ServiceIrp = IoCsqRemoveNextIrp(&pConnCntx->SendQueue.CancelSafeQueue,NULL);
if(ServiceIrp != NULL)
{
ntStatus = IoCallDriver(NbdDeviceObj, ServiceIrp);
if(STATUS_PENDING ==(ntStatus))
{
KeWaitForSingleObject(&pConnCntx->SendQueue.IoComplete, Executive, KernelMode, FALSE,NULL);
if((pMemToFree = (PMEM_C)ExInterlockedRemoveHeadList(&pConnCntx->MemoryFreeList,&pConnCntx->MemoryLock))!=NULL)
{
ExFreePoolWithTag(pMemToFree->pPacket,‘dnes’);
ExFreePoolWithTag(pMemToFree->pStatusBlk,‘stbk’);
ExFreePoolWithTag(pMemToFree,‘memp’);
}
}
}
}while(ServiceIrp != NULL);
The following is the analysis of the bugcheck that i receive. The analysis points to a part in code, but I dont think it has much relevance. The bug only occurs when verifier is off. With verifier on everything work fine. And it seems to appear for windows 2003 only. The driver works flawlessly for windows XP.
SYSTEM_THREAD_EXCEPTION_NOT_HANDLED (7e)
This is a very common bugcheck. Usually the exception address pinpoints
the driver/function that caused the problem. Always note this address
as well as the link date of the driver/image that contains this address.
Arguments:
Arg1: c0000005, The exception code that was not handled
Arg2: 8088c753, The address that the exception occurred at
Arg3: f8a93b50, Exception Record Address
Arg4: f8a9384c, Context Record Address
Debugging Details:
EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at “0x%08lx” referenced memory at “0x%08lx”. The memory could not be “%s”.
FAULTING_IP:
nt!ExFreePoolWithTag+41d
8088c753 803803 cmp byte ptr [eax],3
EXCEPTION_RECORD: f8a93b50 – (.exr 0xfffffffff8a93b50)
ExceptionAddress: 8088c753 (nt!ExFreePoolWithTag+0x0000041d)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 00000000
Parameter[1]: 01000000
Attempt to read from address 01000000
CONTEXT: f8a9384c – (.cxr 0xfffffffff8a9384c)
eax=01000000 ebx=808a7bc0 ecx=000317b0 edx=00000e0e esi=ffbcc798 edi=00000014
eip=8088c753 esp=f8a93c18 ebp=f8a93c60 iopl=0 nv up ei pl nz na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010206
nt!ExFreePoolWithTag+0x41d:
8088c753 803803 cmp byte ptr [eax],3 ds:0023:01000000=??
Resetting default scope
DEFAULT_BUCKET_ID: DRIVER_FAULT
PROCESS_NAME: System
CURRENT_IRQL: 1
ERROR_CODE: (NTSTATUS) 0xc0000005 - The instruction at “0x%08lx” referenced memory at “0x%08lx”. The memory could not be “%s”.
READ_ADDRESS: 01000000
BUGCHECK_STR: 0x7E
IRP_ADDRESS: ffbcc7a0
LAST_CONTROL_TRANSFER: from 8081bab1 to 8088c753
STACK_TEXT:
f8a93c60 8081bab1 ffbcc7a0 00000000 00000000 nt!ExFreePoolWithTag+0x41d
f8a93c7c 80820ef3 ffbcc7a0 ffbcc7e0 817f45e8 nt!IopFreeIrp+0xe9
f8a93ccc 8082c34e ffbcc7e0 f8a93d18 f8a93d0c nt!IopCompleteRequest+0x3db
f8a93d1c 8082ffd3 00000000 00000000 00000000 nt!KiDeliverApc+0xb8
f8a93d40 808287b4 00000000 817f45e8 00000000 nt!KiSwapThread+0x9f
f8a93d84 f921085d ffaffcf0 00000000 00000000 nt!KeWaitForSingleObject+0x2e0
f8a93dac 809418f4 ffaffccc 00000000 00000000 DISK!RunThread+0x1d [l:\vdi\client\windows\nbddisk\DISK\DISK.cpp @ 161]
f8a93ddc 80887f4a f9210840 ffaffccc 00000000 nt!PspSystemThreadStartup+0x2e
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16
FOLLOWUP_IP:
STOR_NBD!RunThread+1d [l:\vdi\client\windows\nbddisk\DISK\DISK.cpp @ 161]
f921085d 8b5508 mov edx,dword ptr [ebp+8]
FAULTING_SOURCE_CODE:
157: KeWaitForSingleObject(&AdaVx->RunThreadEvent, Executive, KernelMode, FALSE, NULL);
158:
159: SRB_VX *SrbVx;
160:
161: while((SrbVx = (SRB_VX *)ExInterlockedRemoveHeadList(&AdaVx->RunQueue, &AdaVx->RunQueueLock)) != NULL)
162: StartSRB(AdaVx, SrbVx->LunVx, SrbVx->Srb);
163:
164: }while(!AdaVx->RunThreadExit);
165:
166: /*------------------------------------*/
SYMBOL_STACK_INDEX: 6
SYMBOL_NAME: DISK!RunThread+1d
FOLLOWUP_NAME: MachineOwner
MODULE_NAME: DISK
IMAGE_NAME: DISK.sys
DEBUG_FLR_IMAGE_TIMESTAMP: 49c75c98
STACK_COMMAND: .cxr 0xfffffffff8a9384c ; kb
FAILURE_BUCKET_ID: 0x7E_DISK!RunThread+1d
BUCKET_ID: 0x7E_DISK!RunThread+1d
Followup: MachineOwner
NTDEV is sponsored by OSR
For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars
To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer