Hi Everyone,
I have a WDF bus driver that is attached directly to a PCI hw device. The bus driver creates 4 different devices. Which I then attach various other drivers to.
The bus driver creates a custom INTERFACE type, and then registers that interface using WdfDeviceAddQueryInterface. That interface contains a couple of function pointer callbacks.
All of my child device drivers that I create are WDF drivers except for one. From the WDF drivers I can query the interface created by the bus driver without any issues. My problem child (pun intended) is an old serial driver that is written in WDM. We’re trying to convert it over to use our new bus driver.
From the WDM serial driver, I am unable to query the bus driver interface. From my reading it looks like I need to generate an IRP and pass that along to the bus driver, but when I do I always receive STATUS_NOT_SUPPORTED back from the IoCallDriver function.
I feel like i’m trying to talk to a device which doesn’t support my INTERFACE, and i’m likely using the wrong device object to build my IRP, but I can’t figure out how to retrieve the device object of my bus driver. I’ve tried the following functions to retrieve the device object with the same outcome (IoCallDriver returns STATUS_NOT_SUPPORTED)
- IoGetAttachedDeviceReference
- IoGetDeviceAttachmentBaseRef
- IoGetLowerDeviceObject
Anyways, any suggestions or directions to go would be much appreciated!
IRP generation code is pasted below
NTSTATUS get_bus_interface(IN PDEVICE_OBJECT PDevObj)
{
PIRP irp = NULL;
KEVENT event;
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_OBJECT pvmf_device = NULL;
IO_STATUS_BLOCK ioStatus = { 0 };
PIO_STACK_LOCATION irpStack = NULL;
PVMF_BUS_INTERFACE bus_interface;
pvmf_device = IoGetAttachedDeviceReference(PDevObj);
irp = IoBuildSynchronousFsdRequest(
IRP_MJ_PNP,
pvmf_device,
NULL,
0,
0,
&event,
&ioStatus);
if (irp == NULL)
{
goto cleanup;
}
irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
irp->IoStatus.Information = 0;
irpStack = IoGetNextIrpStackLocation(irp);
irpStack->MinorFunction = IRP_MN_QUERY_INTERFACE;
irpStack->Parameters.QueryInterface.InterfaceType = (LPGUID)&GUID_SEL_PVMF_BUS_INTERFACE;
irpStack->Parameters.QueryInterface.Size = sizeof(PVMF_BUS_INTERFACE);
irpStack->Parameters.QueryInterface.Version = SEL_PVMF_BUS_INTERFACE_VERSION;
irpStack->Parameters.QueryInterface.Interface = (PINTERFACE)&bus_interface;
irpStack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
status = IoCallDriver(pvmf_device, irp);
if (status == STATUS_PENDING)
{
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
status = ioStatus.Status;
}
if (!NT_SUCCESS(status))
{
goto cleanup;
}
cleanup:
ObDereferenceObject(pvmf_device);
return status;
}
Thanks!
Ryan