KMDF WMI query for firmware revision

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;
}

It looks like the usbhub driver already registers for this guid on each PDO which means you cannot override the data it reports. Having never heard of this wmi guid before, I cannot comment if this is the right or wrong behavior. I am poking around to see how device manager comes up with the firmware property that it displays

thx
d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@hotmail.com
Sent: Sunday, April 13, 2008 9:37 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] KMDF WMI query for firmware revision

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;
}


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:

To unsubscribe, visit the List Server section of OSR Online at ListServer/Forum

Thanks for the reply.

Any news on the subject?
I still haven’t found a solution.

If anyone can help, I’d be grateful.
Yariv

Device manager in vista does not show this property anymore (by design). As for the hub driver, I don’t think there is anything you can do to override its behavior and override the data reported by it. If you register for the same GUID in your FDO, there should be 2 instances (_0 and _1 of the same guid. My guess is that Device manager pre vista hard coded the _0 instance (it does this for the wait wake and idle WMI guids), while wmic is completely generic and just queries all instances.

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@hotmail.com
Sent: Sunday, April 27, 2008 7:37 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] KMDF WMI query for firmware revision

Thanks for the reply.

Any news on the subject?
I still haven’t found a solution.

If anyone can help, I’d be grateful.
Yariv


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer