Hi,
I'm practicing Internal IOCTL implementation for WDF.
I currently have a PCI hardware that uses a WDF bus driver and generates four ports. I want to call the bus driver's function on the port driver through internal ioctl.
At present, I know that two different drivers must communicate through the Interface, so I established an interface on the bus.
==============================================
typedef struct _PORT_DRIVER_INTERFACE {
INTERFACE InterfaceHeader;
EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL *EvtIoDeviceControl;
} PORT_DRIVER_INTERFACE, * PPORT_DRIVER_INTERFACE;
==============================================
RtlZeroMemory(&PortInterface, sizeof(PORT_DRIVER_INTERFACE));
PortInterface.InterfaceHeader.Size = sizeof(PORT_DRIVER_INTERFACE);
PortInterface.InterfaceHeader.Version = 1;
PortInterface.InterfaceHeader.Context = (PVOID)hChild;
PortInterface.InterfaceHeader.InterfaceReference =
WdfDeviceInterfaceReferenceNoOp;
PortInterface.InterfaceHeader.InterfaceDereference =
WdfDeviceInterfaceDereferenceNoOp;
PortInterface.EvtIoDeviceControl = Bus_EvtIoDeviceControl;
WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig,
(PINTERFACE)&PortInterface,
&GUID_PORT_DRIVER_INTERFACE,
WDF_NO_EVENT_CALLBACK);
status = WdfDeviceAddQueryInterface(hChild, &qiConfig);
if (!NT_SUCCESS(status)) {
KdPrint(("WdfDeviceAddQueryInterface failed 0x%0x\n", status));
goto Cleanup;
}
==============================================
On the port driver, I tried to use the following function to use the ioctl in EvtIoDeviceControl but could not correctly enter the IOCTL.
(This function will be used in the preparehardware phase to get some hwresource information from the bus driver)
As a result of the execution, the computer will get stuck in this function and cannot end it.
I have read some queryInterface articles, but because I haven’t seen the implementation related to internal ioctl, I am still a little confused. I would like to ask how I can modify it to achieve my goal.
Is the reason for the failure related to my misunderstanding of iotarget, or does the use of Interface need to be adjusted?
NTSTATUS GetBusPropertyValue(WDFDEVICE device, PDEVICE_SETTINGS *pSettings)
{
WDFIOTARGET ioTarget = NULL;
WDF_IO_TARGET_OPEN_PARAMS openParams;
NTSTATUS status = STATUS_SUCCESS;
PPORT_DRIVER_INTERFACE PortInterface;
// UNICODE_STRING deviceName;
// Generate IO target
status = WdfIoTargetCreate(device, WDF_NO_OBJECT_ATTRIBUTES, &ioTarget);
if (!NT_SUCCESS(status)) {
KdPrint(("WdfIoTargetCreate failed 0x%x\n", status));
return(status);
}
WDF_IO_TARGET_OPEN_PARAMS_INIT_EXISTING_DEVICE(&openParams, WdfDeviceWdmGetDeviceObject(device));
//ioTarget = WdfDeviceGetIoTarget(device);
status = WdfIoTargetOpen(ioTarget,
&openParams);
if (!NT_SUCCESS(status)) {
KdPrint(("WdfIoTargetOpen failed 0x%x\n", status));
return(status);
}
status = WdfFdoQueryForInterface(device,
&GUID_PORT_DRIVER_INTERFACE,
(PINTERFACE)&PortInterface,
sizeof(PORT_DRIVER_INTERFACE),
1, // version
NULL);
if (!NT_SUCCESS(status)) {
KdPrint(("WdfFdoQueryForInterface failed 0x%0x\n", status));
return(status);
}
DEVICE_SETTINGS* outputSettings = (DEVICE_SETTINGS*)ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_SETTINGS), 'Sett');
if (outputSettings == NULL) {
return STATUS_INSUFFICIENT_RESOURCES;
}
WDF_MEMORY_DESCRIPTOR outputDescriptor;
WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&outputDescriptor, outputSettings, sizeof(DEVICE_SETTINGS));
KdPrint(("WdfIoTargetSendInternalIoctlOthersSynchronously\n"));
status = WdfIoTargetSendInternalIoctlOthersSynchronously(
ioTarget,
NULL,
IOCTL_TEST_INTERNAL_BASIC_SETTINGS,
NULL,
&outputDescriptor,
NULL,
NULL,
NULL
);
if (NT_SUCCESS(status)) {
*pSettings = outputSettings;
KdPrint(("Controller: %x\n", (*pSettings)->Controller));
KdPrint(("PortIndex: %x\n", (*pSettings)->PortIndex));
}
else {
ExFreePoolWithTag(outputSettings, 'Sett');
}
WdfIoTargetClose(ioTarget);
WdfObjectDelete(ioTarget);
return status;
}
Many thanks.
Luke Chen