Hello,
I have PCIe device for which we have written a NDIS miniport driver which also interacts with a user application for some data exchange. To enable this we have creating a symbolic link which user can use in CreateFile call by registering a device using NdisRegisterDeviceEx.
The user app sends IOCTL to the driver which we handle in the DeviceIoControl dispatch routine .For data exchange we want to use pended IRP method so that the receipt of interrupt from the device can be indicated to the application. When the DeviceIoControl Receives the specific IOCTL it pends it and stores the IRP pointer in DeviceExtension received after NdisRegisterDeviceEx call as follows:
case XXX_CHECK_EVENT:
{
DbgPrint(“CHECK EVENT\n”);
NdisAcquireSpinLock(&pXXXDrvInstance->m_PendingIrpLock);
pXXXDrvInstance->m_pPendingIrp = Irp_p;
if(!Irp_p->Cancel)
{
IoMarkIrpPending(Irp_p);
IoSetCancelRoutine(Irp_p, XXXCancelIrp);
}
else
{
NdisReleaseSpinLock(&pXXXDrvInstance->m_PendingIrpLock);
Status = STATUS_CANCELLED;
break;
}
NdisReleaseSpinLock(&pHpmnDrvInstance->m_PendingIrpLock);
Status = STATUS_PENDING;
break;
}
default:
Status = STATUS_UNSUCCESSFUL;
break;
}
if (Status != STATUS_PENDING)
{
//
// complete the Irp
//
DbgPrint(“Complete \n”);
Irp_p->IoStatus.Status = Status;
IoCompleteRequest(Irp_p, IO_NO_INCREMENT);
}
The device uses MSI for signalling the receipt of data. In my driver’s DPCforISR I retreive the Pended Irp pointer copy the information in the IRP buffer and then complete it as follows:
VOID
HpmnNdisDpc(
__in NDIS_HANDLE MiniportInterruptContext_p,
__in ULONG MessageId_p,
__in PVOID MiniportDpcContext_p,
__in PULONG NdisReserved1_p,
__in PULONG NdisReserved2_p
)
{
PIRP pIrp = NULL;
BYTE bMode;
PVOID pBuff;
NTSTATUS Status = STATUS_SUCCESS;
do
{
bMode = XXXGetMode();
NdisDprAcquireSpinLock(&XXXnDrvInstance_l->m_PendingIrpLock);
if(XXXDrvInstance_l->m_pPendingIrp != NULL)
{
DbgPrint(" Mode : %x\n",bMode);
pIrp = XXXDrvInstance_l->m_pPendingIrp;
if(pIrp->Cancel)
{
Status = STATUS_CANCELLED;
break;
}
else
{
pBuff = pIrp->AssociatedIrp.SystemBuffer;
DbgPrint(" Copying \n");
NdisMoveMemory(pBuff,&bMode,sizeof(bMode));
Status = STATUS_SUCCESS;
}
}
}
while(FALSE);
NdisDprReleaseSpinLock(&XXXDrvInstance_l->m_PendingIrpLock);
if(pIrp != NULL)
{
DbgPrint(“completing the IRP\n”);
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
XXXDrvInstance_l->m_pPendingIrp = NULL;
}
}
when i call the user application with the XXX_CHECK_EVENT control code it results in a APPCRASH :
Problem Event Name: APPCRASH
Application Name: demo_App.exe
Application Version: 0.0.0.0
Application Timestamp: 502f64cd
Fault Module Name: KERNELBASE.dll
Fault Module Version: 6.1.7601.17651
Fault Module Timestamp: 4e21213c
Exception Code: c0000005
Exception Offset: 000000000000a292
OS Version: 6.1.7601.2.1.0.256.48
Locale ID: 1033
Additional Information 1: b046
Additional Information 2: b0463d6163e1702cfe7937c497a94fef
Additional Information 3: 3ca0
Additional Information 4: 3ca0db409703bf7afef063aa94280bf5
I havent used a internal queue for storring the pended IRP is that necessary? Please someone help.
Thanks in advance