Sending custom IoControl requests to windows 8.1 sensor clx driver

I am writing a Windows 8.1 Sensor Framework driver using the Sensor CLX v2. I have a user mode configuration app that attempts to send an IoControl to the device to retrieve current configuration data. The code that sends the IoControl is below:

DWORD returned_bytes;

// Read existing config
GLS_CONFIG existing_config;
if (DeviceIoControl(dev_handle, IOCTL_GLS_READ_CONFIG, nullptr, 0, &existing_config, sizeof(GLS_CONFIG), &returned_bytes, nullptr))
{

}
else
{
std::cout << "Failed to read existing config: " << GetLastError() << “.” << std::endl;
}

The problem that I am experiencing is that the IoControl never reaches my driver. The call to CreateFile suceeds and returns a valid device handle. My driver supplies a valid OnIoControl callback to the sensor framework in the SENSOR_CONTROLLER_CONFIG passed to SensorsCxDeviceInitialize. I’ve set a breakpoint in my OnIoControl callback, as well as KdPrint a debug message. This code is never hit. GetLastError after DeviceIoControl returns error 1168 (ERROR_NOT_FOUND). When I call DeviceIoControl using overlapped IO twice, the second call hangs, making me think that the first request is still pending.

I’m wondering if the sensor framework installs a filter driver or otherwise is impeding my IoControl request. Can anyone see any potential issues with my code?

The code that registers the IoControl callback with the sensor framework:

// Register CLX callback function pointers
SENSOR_CONTROLLER_CONFIG_INIT(&SensorConfig);
SensorConfig.DriverIsPowerPolicyOwner = WdfUseDefault;

SensorConfig.EvtSensorStart = GeodeDevice::OnStart;
SensorConfig.EvtSensorStop = GeodeDevice::OnStop;
SensorConfig.EvtSensorGetSupportedDataFields = GeodeDevice::OnGetSupportedDataFields;
SensorConfig.EvtSensorGetDataInterval = GeodeDevice::OnGetDataInterval;
SensorConfig.EvtSensorSetDataInterval = GeodeDevice::OnSetDataInterval;
SensorConfig.EvtSensorGetDataFieldProperties = GeodeDevice::OnGetDataFieldProperties;
SensorConfig.EvtSensorGetDataThresholds = GeodeDevice::OnGetDataThresholds;
SensorConfig.EvtSensorSetDataThresholds = GeodeDevice::OnSetDataThresholds;
SensorConfig.EvtSensorGetProperties = GeodeDevice::OnGetProperties;
SensorConfig.EvtSensorDeviceIoControl = GeodeDevice::OnIoControl;

// Set up power capabilities and IO queues
Status = SensorsCxDeviceInitialize(Device, &SensorConfig);
My OnIoControl callback (never hit):

NTSTATUS GeodeDevice::OnIoControl(In SENSOROBJECT SensorInstance, In WDFREQUEST Request, In size_t OutputBufferLength, In size_t InputBufferLength, In ULONG IoControlCode)
{
UNREFERENCED_PARAMETER(OutputBufferLength);
UNREFERENCED_PARAMETER(InputBufferLength);

KdPrint((“Got IoControl Code: %x.\n”, IoControlCode));
DbgBreakPoint();

NTSTATUS status;
ULONG_PTR bytes = 0;
PGeodeDevice pDevice = GetSdoContextFromSensorInstance(SensorInstance);

KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, “GGNSS:OnIoControl Entry\n”));

switch (IoControlCode)
{
case IOCTL_GLS_READ_CONFIG:
status = pDevice->IoCtl_Gls_ReadConfig(Request, &bytes);
break;
case IOCTL_GLS_WRITE_CONFIG:
status = pDevice->IoCtl_Gls_WriteConfig(Request, &bytes);
break;
default:
status = STATUS_NOT_SUPPORTED;
break;
}

if (NT_SUCCESS(status))
{
WdfRequestCompleteWithInformation(Request, status, bytes);
}

KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, “GGNSS:OnIoControl Exit\n”));
return status;
}

Thanks,
Gregory Comer