@Doron_Holan said:
Did you install EvtIoDeviceControl and EvtIoDefault on the child or the parent device? You can either process these requests directly in the child device or you can forward the request so that it is processed in the parent device…see WdfPdoInitAllowForwardingRequestToParent , WdfRequestForwardToParentDeviceIoQueue
I installed it on the parent device.
The idea is to send these IRP’s from the child device, to the parent device.
The functions you are refering to, aren’t they supposed to be used in the device driver for the child device? i.e. the WDM device driver I already have and want to touch as little as possible. And as this is working with the old WDM parent driver I’m porting, I think it should be possible to get it working with the KMDF driver as well.
I now tried installing a queue with EvtIoDeviceControl and EvtIoDefault from the parent driver, after creating the child device, before calling WdfFdoAddStaticChild. But that causes the entire driver to not work properly, so I guess you aren’t supposed to do that…
This is the function I’m using to create the child device:
`NTSTATUS
Bus_CreatePdo(
In WDFDEVICE Device,
In PWSTR HardwareId,
ULONG DeviceType
)
{
PWDFDEVICE_INIT pDeviceInit = NULL;
NTSTATUS status;
DECLARE_UNICODE_STRING_SIZE(deviceId, 100);
UNICODE_STRING compatId;
WDFDEVICE hChild = NULL;
WDF_DEVICE_PNP_CAPABILITIES pnpCaps;
WDF_DEVICE_POWER_CAPABILITIES powerCaps;
PAGED_CODE();
pDeviceInit = WdfPdoInitAllocate(Device);
if (pDeviceInit == NULL) {
status = STATUS_INSUFFICIENT_RESOURCES;
return status;
}
//
// Set DeviceType
//
WdfDeviceInitSetDeviceType(pDeviceInit, DeviceType);
RtlUnicodeStringPrintf(&deviceId, L"DosDevices\\%s", HardwareId);
status = WdfPdoInitAssignDeviceID(pDeviceInit, &deviceId);
if (!NT_SUCCESS(status)) {
goto Cleanup;
}
status = WdfPdoInitAddHardwareID(pDeviceInit, &deviceId);
if (!NT_SUCCESS(status)) {
goto Cleanup;
}
RtlInitUnicodeString(&compatId, HardwareId);
status = WdfPdoInitAddCompatibleID(pDeviceInit, &compatId);
if (!NT_SUCCESS(status)) {
goto Cleanup;
}
status = WdfDeviceCreate(&pDeviceInit, WDF_NO_OBJECT_ATTRIBUTES, &hChild);
if (!NT_SUCCESS(status)) {
WdfDeviceInitFree(pDeviceInit);
pDeviceInit = NULL;
goto Cleanup;
}
WDF_DEVICE_PNP_CAPABILITIES_INIT(&pnpCaps);
pnpCaps.Removable = WdfFalse;
pnpCaps.EjectSupported = WdfFalse;
pnpCaps.SurpriseRemovalOK = WdfFalse;
pnpCaps.UINumber = 0xFFFFFFFF;
WdfDeviceSetPnpCapabilities(hChild, &pnpCaps);
WDF_DEVICE_POWER_CAPABILITIES_INIT(&powerCaps);
powerCaps.DeviceD1 = WdfFalse;
powerCaps.DeviceD2 = WdfFalse;
powerCaps.WakeFromD0 = WdfFalse;
powerCaps.WakeFromD1 = WdfFalse;
powerCaps.WakeFromD2 = WdfFalse;
powerCaps.WakeFromD3 = WdfFalse;
powerCaps.DeviceWake = PowerDeviceMaximum;
powerCaps.DeviceState[PowerSystemWorking] = PowerDeviceD0;
powerCaps.DeviceState[PowerSystemSleeping1] = PowerDeviceD3;
powerCaps.DeviceState[PowerSystemSleeping2] = PowerDeviceD3;
powerCaps.DeviceState[PowerSystemSleeping3] = PowerDeviceD3;
powerCaps.DeviceState[PowerSystemHibernate] = PowerDeviceD3;
powerCaps.DeviceState[PowerSystemShutdown] = PowerDeviceD3;
WdfDeviceSetPowerCapabilities(hChild, &powerCaps);
status = WdfFdoAddStaticChild(Device, hChild);
if (!NT_SUCCESS(status)) {
WdfObjectDelete(hChild);
goto Cleanup;
}
Cleanup:
return status;
}`