You need to post all your code in order to diagnose this issue. For example, did you save the PDO from IoCreateDevice in device extension? No way to know from the code snippet you posted.
IoConnectInterruptEx() Fail
I am trying to register an MSI interrupt handling routine with wdm.
However, calling the IoConnectInterruptEx() function causes a BSOD (PNP_DETECTED_FATAL_ERROR).
May I know what am I doing wrong?
I wrote the code like this:
StartDevice(
PDEVICE_OBJECT fdo,
PCM_PARTIAL_RESOURCE_LIST ResourceListRaw,
PCM_PARTIAL_RESOURCE_LIST ResourceList
)
{
U32 vector;
KIRQL IrqL;
KAFFINITY affinity;
KINTERRUPT_MODE mode;
DEVICE_EXTENSION* pdx;
PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceRaw;
PCM_PARTIAL_RESOURCE_DESCRIPTOR Resource;
....
pdx = fdo->DeviceExtension;
for (i = 0; i < ResourceListRaw->Count; ++i, ++Resource, ++ResourceRaw)
{
KdPrint((" Resource %02d\n", i));
switch (ResourceRaw->Type)
{
case CmResourceTypeInterrupt:
if (ResourceRaw->Flags & CM_RESOURCE_INTERRUPT_MESSAGE)
{
MSIIntPresent = TRUE;
IrqL = (KIRQL)Resource->u.MessageInterrupt.Translated.Level;
vector = Resource->u.MessageInterrupt.Translated.Vector;
affinity = Resource->u.MessageInterrupt.Translated.Affinity;
ShareVector = (BOOLEAN)(Resource->ShareDisposition == CmResourceShareShared);
KdPrint((" Type : Message Interrupt\n"
" Vector : (Translated = 0x%02x)\n"
" IRQL : (Translated = 0x%02x)\n",
" ShareVector : (Translated = 0x%02x)\n",
vector, IrqL, ShareVector));
}
...
if (MSIIntPresent)
{
IO_CONNECT_INTERRUPT_PARAMETERS params;
RtlZeroMemory(¶ms, sizeof(IO_CONNECT_INTERRUPT_PARAMETERS));
KdPrint(("MSIIntPresent\n"));
KdPrint(("Vector=%d IrqL=%d affinity=%d ShareVector=%d,\n", vector, IrqL, affinity, ShareVector));
params.Version = CONNECT_FULLY_SPECIFIED;
params.FullySpecified.PhysicalDeviceObject = pdx->pPhysicalDeviceObject;
params.FullySpecified.InterruptObject = &pdx->pInterruptObject;
params.FullySpecified.ServiceRoutine = OnInterrupt;
params.FullySpecified.ServiceContext = fdo;
params.FullySpecified.SpinLock = NULL;
params.FullySpecified.Vector = vector;
params.FullySpecified.Irql = IrqL;
params.FullySpecified.SynchronizeIrql = IrqL;
params.FullySpecified.InterruptMode = mode;
params.FullySpecified.ShareVector = ShareVector;
params.FullySpecified.ProcessorEnableMask = affinity;
params.FullySpecified.FloatingSave = FALSE;
status = IoConnectInterruptEx(¶ms);
if (!NT_SUCCESS(status))
{
KdPrint((DBG_NAME "ERROR - IoConnectInterrupt() failed, status = 0x%08x\n", status));
if (status == STATUS_NOT_SUPPORTED)
{
KdPrint(("STATUS_NOT_SUPPORTED\n"));
}
pdx->pInterruptObject = NULL;
}
else {
KdPrint((DBG_NAME "Connected to interrupt vector\n"));
}
}
Is there something wrong with specifying PhysicalDeviceObject or ServiceContext?
I've read the documentation provided by microsoft, but I don't quite understand.
(https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/using-the-connect-fully-specified-version-of-ioconnectinterruptex)
Any advice would be appreciated.