Share via

IoConnectInterruptEx() Fail

james 1 Reputation point
2021-11-08T10:29:26.92+00:00

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(&params, 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(&params);  
	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.

Windows for business | Windows Client for IT Pros | Devices and deployment | Other

1 answer

Sort by: Most helpful
  1. Harry 1 Reputation point
    2021-12-17T01:53:57.377+00:00

    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.

    Was this answer helpful?

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.