I am writing a driver for a usb device. My driver is based on the kmdf/osrusbfx2 sample. I added a very limited WMI support, adapted from the kmdf/serial example. The only purpose of the WMI code is to return the firmware revision of our device.
That firmware revision is normally displayed in the device manager, under the 'Detail's tab for the device when choosing 'Firmware Revision' in the drop down box. According to the WDK documentation, supporting the MSDeviceUI_FirmwareRevision_GUID should do the trick.
What actually happens is that the device manager displays the bcdDevice field of the usb device descriptor. My EvtWmiInstanceQueryInstance handler isn't even getting called. When I use the Windows Management Instrumentation Command-line (WMIC) application to query for that value, my event handler is invoked. However it still displays the bcdDevice field value instead of the value that the event handler returns.
You can see my WMI code below (it's quite short). MyDeviceWmiRegistration is invoked as the final step of the EvtDriverDeviceAdd. I also joined the logs of DebugView and the command line output of wmic. The Vid and Pid are the ones I assigned to my device.
Any insights about what I am doing wrong would be appreciated.
wmic output:
C:\Documents and Settings\yariv\Desktop>wmic /namespace:\root\wmi path MSDeviceUI_FirmwareRevision.InstanceName="USB\Vid_0547&Pid_1700\5&1603fd25&0&7_0"
Active FirmwareRevision InstanceName
TRUE 01.01 USB\Vid_0547&Pid_1700\5&1603fd25&0&7_0
DebugView (for one invocation of wmic):
=> EvtWmiQueryFirmwareRevision
BufferUsed 12
*OutBuffer = 53382
OutBufferSize = 1
WDF_WMI_BUFFER_APPEND_STRING returned 0xC0000023
<= EvtWmiQueryFirmwareRevision
=> EvtWmiQueryFirmwareRevision
BufferUsed 12
*OutBuffer = 10
OutBufferSize = 112
WDF_WMI_BUFFER_APPEND_STRING returned 0x00000000
<= EvtWmiQueryFirmwareRevision
Code:
NTSTATUS
MyDeviceWmiRegisterInstance(
WDFDEVICE Device,
const GUID* Guid,
ULONG MinInstanceBufferSize,
PFN_WDF_WMI_INSTANCE_QUERY_INSTANCE EvtWmiInstanceQueryInstance
)
{
WDF_WMI_PROVIDER_CONFIG providerConfig;
WDF_WMI_INSTANCE_CONFIG instanceConfig;
PAGED_CODE();
//
// Create and register WMI providers and instances blocks
//
WDF_WMI_PROVIDER_CONFIG_INIT(&providerConfig, Guid);
providerConfig.MinInstanceBufferSize = MinInstanceBufferSize;
WDF_WMI_INSTANCE_CONFIG_INIT_PROVIDER_CONFIG(&instanceConfig, &providerConfig);
instanceConfig.Register = TRUE;
instanceConfig.EvtWmiInstanceQueryInstance = EvtWmiInstanceQueryInstance;
return WdfWmiInstanceCreate(Device,
&instanceConfig,
WDF_NO_OBJECT_ATTRIBUTES,
WDF_NO_HANDLE);
}
NTSTATUS
MyDeviceWmiRegistration(
WDFDEVICE Device
)
/*++
Routine Description
Registers with WMI as a data provider for this
instance of the device
--*/
{
NTSTATUS status = STATUS_SUCCESS;
PAGED_CODE();
KdPrint(("=> MyDeviceWmiRegistration"));
status = MyDeviceWmiRegisterInstance(Device,
&MSDeviceUI_FirmwareRevision_GUID,
0, // variable sized buffers must set this field to 0
EvtWmiQueryFirmwareRevision);
if (!NT_SUCCESS(status)) {
KdPrint(("MyDeviceWmiRegistration failed"));
return status;
}
KdPrint(("<= MyDeviceWmiRegistration"));
return status;
}
#define DUMMY_FIRMWARE_REVISION L"05.12"
NTSTATUS
EvtWmiQueryFirmwareRevision(
IN WDFWMIINSTANCE WmiInstance,
IN ULONG OutBufferSize,
IN PVOID OutBuffer,
OUT PULONG BufferUsed
)
{
PDEVICE_CONTEXT pDevExt;
//UNICODE_STRING us;
NTSTATUS status;
DECLARE_CONST_UNICODE_STRING(us, DUMMY_FIRMWARE_REVISION);
UNREFERENCED_PARAMETER(OutBufferSize);
PAGED_CODE();
KdPrint(("=> EvtWmiQueryFirmwareRevision"));
pDevExt = GetDeviceContext (WdfWmiInstanceGetDevice(WmiInstance));
status = WDF_WMI_BUFFER_APPEND_STRING(
OutBuffer,
OutBufferSize,
&us,
BufferUsed
);
KdPrint(("BufferUsed %d\n", *BufferUsed));
KdPrint(("*OutBuffer = %d\n", *(USHORT*)OutBuffer));
KdPrint(("OutBufferSize = %d\n", OutBufferSize));
KdPrint(("WDF_WMI_BUFFER_APPEND_STRING returned 0x%08X\n", status));
KdPrint(("<= EvtWmiQueryFirmwareRevision"));
return status;
}