WMI & KMD

Hi guys,

Is it possible to make a KMD as a WMI provider? All available samples
are for WDM…

I’m trying to do this on a simple KMD but always fail to get instances
of device in JavaScript. However, the whole code works fine on WDM
drivers. I just change WMIREG_FLAG_INSTANCE_PDO to
WMIREG_FLAG_INSTANCE_BASENAME

Thanks for any ideas.

Cheers,
R. Yang

  • Windows Kernel Developer [Custom Dev and Consulting]

By KMD, do you mean KMDF? KMDF does support being a WMI provider (with the appropriately named WDFWMIPROVIDER object); KMDF currently only supports WMIREG_FLAG_INSTANCE_PDO as a way to register a name, does your javascript use a hard coded instance name? can you post your script? What OS is this on?

d

Hi,

KMD is kernel mode driver (service) which has no PnP stuff. Do we call
it in this name?

My driver just creates a DO in DriverEntry and is very simple. I add
some WMI code to this driver with WMIREG_FLAG_INSTANCE_BASENAME and
copy a UNICODE name to InstanceName as required by DDK.

The following code is in driver part:

NTSTATUS ScutumWmiQueryReginfo(
IN PDEVICE_OBJECT DeviceObject,
OUT PULONG RegFlags,
OUT PUNICODE_STRING InstanceName,
OUT PUNICODE_STRING* RegistryPath,
OUT PUNICODE_STRING MofResourceName,
OUT PDEVICE_OBJECT* Pdo
)
{
PSCUTUM_DEVICE_EXTENSION deviceExtension;

ODS(DBG_WMI, DBG_TRACE, FUNCTION"++");

deviceExtension =
(PSCUTUM_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

*RegFlags = WMIREG_FLAG_INSTANCE_BASENAME;
*RegistryPath = &g_Data.RegistryPath;

#define INSTANCENAME L"ScutumDriver"
InstanceName->Buffer = (PWCH)ExAllocatePool(
PagedPool,
sizeof(INSTANCENAME)
);
if(InstanceName->Buffer)
{
InstanceName->Length = InstanceName->MaximumLength =
sizeof(INSTANCENAME);
RtlCopyMemory(
InstanceName->Buffer,
INSTANCENAME,
sizeof(INSTANCENAME)
);
}

RtlInitUnicodeString(MofResourceName, L"MofResource");
*Pdo = NULL;

ODS(DBG_WMI, DBG_TRACE, FUNCTION"–");

return STATUS_SUCCESS;
}

And JavaScript:

Scutum Device Information

CLASSID=“CLSID:75718C9A-F029-11d1-A1AC-00C04FB6C223”>


onClick="Prev()">
onClick="Update()">
onClick="Submit()">
onClick="Next()">

|
Instance Path: |
|

|
DriverVersion: |
|

|
DriverDescription: |
|


ScutumEventNotification Message:

READONLY>

And mof:

[Dynamic,
Provider(“WMIProv”),
WMI,
Description(“Scutum driver information”),
guid(“{1BC528BD-26D3-4C3D-A67F-1C9BD2936836}”),
locale(“MS\0x409”)]
class ScutumDeviceInformation
{
[
key,
read
]
string InstanceName;

[
read
]
boolean Active;

[
WmiDataId(1),
read,
write,
Description(“Scutum DriverVersion property”)
]
uint64 DriverVersion;

[
WmiDataId(2),
read,
write,
Description(“Scutum DriverDescription property”)
]
string DriverDescription;
};
[Dynamic,
Provider(“WMIProv”),
WMI,
Description(“Scutum EventNotification event”),
guid(“{2F4F262B-C352-4152-848C-5977C5010C2C}”),
locale(“MS\0x409”)]
class ScutumEventNotification : WMIEvent
{
[
key,
read
]
string InstanceName;

[
read
]
boolean Active;

[
WmiDataId(1),
read,
Description(“Informational Message”)
]
string Message;
};

Sorry that the code looks too long. :slight_smile:

The problem occurs on this line in JavaScript:
var Collection = new
Enumerator(Service.InstancesOf(“ScutumDeviceInformation”));

Any hints?

On Mon, 7 May 2007 00:55:07 -0400 (EDT), xxxxx@Microsoft.com
wrote:

By KMD, do you mean KMDF? KMDF does support being a WMI provider (with the appropriately named WDFWMIPROVIDER object); KMDF currently only supports WMIREG_FLAG_INSTANCE_PDO as a way to register a name, does your javascript use a hard coded instance name? can you post your script? What OS is this on?

d

Sorry that I forgot to say it’s on XP SP2, on which another simple WDM
driver with WMIREG_FLAG_INSTANCE_PDO works fine.

Just to be clear, WMIREG_FLAG_INSTANCE_PDO only works for pnp device
stacks. WMIREG_FLAG_INSTANCE_PDO to requires a PDO, something that you
don’t have when you create a device object in DriverEntry() (which is an
older style, legacy driver, but both WDM and this style are still kernel
mode drivers).

I think your problem is that you are including the NULL for the string
in the buffer’s length, which means that the NULL character is a part of
the name itself and not a terminator.

Instead of this
InstanceName->Length = InstanceName->MaximumLength =
sizeof(INSTANCENAME);

Try this
InstanceName->Length = sizeof(INSTANCENAME) - sizeof(UNICODE_NULL);
InstanceName->MaximumLength = sizeof(INSTANCENAME);

On failure to allocate InstanceName->Buffer you should be returning a
!NT_SUCCESS value, probably STATUS_INSUFFICIENT_RESOURCES.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of R.Yang
Sent: Sunday, May 06, 2007 10:54 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] WMI & KMD

Hi,

KMD is kernel mode driver (service) which has no PnP stuff. Do we call
it in this name?

My driver just creates a DO in DriverEntry and is very simple. I add
some WMI code to this driver with WMIREG_FLAG_INSTANCE_BASENAME and
copy a UNICODE name to InstanceName as required by DDK.

The following code is in driver part:

NTSTATUS ScutumWmiQueryReginfo(
IN PDEVICE_OBJECT DeviceObject,
OUT PULONG RegFlags,
OUT PUNICODE_STRING InstanceName,
OUT PUNICODE_STRING* RegistryPath,
OUT PUNICODE_STRING MofResourceName,
OUT PDEVICE_OBJECT* Pdo
)
{
PSCUTUM_DEVICE_EXTENSION deviceExtension;

ODS(DBG_WMI, DBG_TRACE, FUNCTION"++");

deviceExtension =
(PSCUTUM_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

*RegFlags = WMIREG_FLAG_INSTANCE_BASENAME;
*RegistryPath = &g_Data.RegistryPath;

#define INSTANCENAME L"ScutumDriver"
InstanceName->Buffer = (PWCH)ExAllocatePool(
PagedPool,
sizeof(INSTANCENAME)
);
if(InstanceName->Buffer)
{
InstanceName->Length = InstanceName->MaximumLength =
sizeof(INSTANCENAME);
RtlCopyMemory(
InstanceName->Buffer,
INSTANCENAME,
sizeof(INSTANCENAME)
);
}

RtlInitUnicodeString(MofResourceName, L"MofResource");
*Pdo = NULL;

ODS(DBG_WMI, DBG_TRACE, FUNCTION"–");

return STATUS_SUCCESS;
}

And JavaScript:

Scutum Device Information

CLASSID=“CLSID:75718C9A-F029-11d1-A1AC-00C04FB6C223”>


onClick="Prev()">
onClick="Update()">
onClick="Submit()">
onClick="Next()">

|
Instance Path: |
|

|
DriverVersion: |
|

|
DriverDescription: |
|


ScutumEventNotification Message:

READONLY>

And mof:

[Dynamic,
Provider(“WMIProv”),
WMI,
Description(“Scutum driver information”),
guid(“{1BC528BD-26D3-4C3D-A67F-1C9BD2936836}”),
locale(“MS\0x409”)]
class ScutumDeviceInformation
{
[
key,
read
]
string InstanceName;

[
read
]
boolean Active;

[
WmiDataId(1),
read,
write,
Description(“Scutum DriverVersion property”)
]
uint64 DriverVersion;

[
WmiDataId(2),
read,
write,
Description(“Scutum DriverDescription property”)
]
string DriverDescription;
};
[Dynamic,
Provider(“WMIProv”),
WMI,
Description(“Scutum EventNotification event”),
guid(“{2F4F262B-C352-4152-848C-5977C5010C2C}”),
locale(“MS\0x409”)]
class ScutumEventNotification : WMIEvent
{
[
key,
read
]
string InstanceName;

[
read
]
boolean Active;

[
WmiDataId(1),
read,
Description(“Informational Message”)
]
string Message;
};

Sorry that the code looks too long. :slight_smile:

The problem occurs on this line in JavaScript:
var Collection = new
Enumerator(Service.InstancesOf(“ScutumDeviceInformation”));

Any hints?

On Mon, 7 May 2007 00:55:07 -0400 (EDT), xxxxx@Microsoft.com
wrote:

By KMD, do you mean KMDF? KMDF does support being a WMI provider (with
the appropriately named WDFWMIPROVIDER object); KMDF currently only
supports WMIREG_FLAG_INSTANCE_PDO as a way to register a name, does
your javascript use a hard coded instance name? can you post your
script? What OS is this on?

d


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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

It still doesn’t work.

The PnP driver works fine even if I use WMIREG_FLAG_INSTANCE_BASENAME
and InstanceName->Length = InstanceName->MaximumLength =
sizeof(INSTANCENAME);

Since the only difference between these 2 drivers are PnP and non-PnP,
I really want to know if WMI is not supported in a non-PnP driver.

Doran, do you have any non-PnP sample which supports WMI? I can not
find it in DDK or web. Thanks.

Absolutely, it is supported. I have a non-pnp driver that supports WMI and
uses WMIREG_FLAG_INSTANCE_BASENAME flag.

Have you tried using wbemtest.exe to get to your WMI class instances? You
can also find useful WMI troubleshooting information at this link:
http://msdn2.microsoft.com/en-us/library/ms799801.aspx

  • kumar

“R. Yang” wrote in message news:xxxxx@ntdev…
> It still doesn’t work.
>
> The PnP driver works fine even if I use WMIREG_FLAG_INSTANCE_BASENAME
> and InstanceName->Length = InstanceName->MaximumLength =
> sizeof(INSTANCENAME);
>
> Since the only difference between these 2 drivers are PnP and non-PnP,
> I really want to know if WMI is not supported in a non-PnP driver.
>
> Doran, do you have any non-PnP sample which supports WMI? I can not
> find it in DDK or web. Thanks.
>

Thanks.

There must be something wrong in my driver. I’ll go ahead…

On Mon, 7 May 2007 17:01:15 -0700, “Kumar Rajeev”
wrote:

>Absolutely, it is supported. I have a non-pnp driver that supports WMI and
>uses WMIREG_FLAG_INSTANCE_BASENAME flag.
>
>Have you tried using wbemtest.exe to get to your WMI class instances? You
>can also find useful WMI troubleshooting information at this link:
>http://msdn2.microsoft.com/en-us/library/ms799801.aspx
>
>- kumar
>
>“R. Yang” wrote in message news:xxxxx@ntdev…
>> It still doesn’t work.
>>
>> The PnP driver works fine even if I use WMIREG_FLAG_INSTANCE_BASENAME
>> and InstanceName->Length = InstanceName->MaximumLength =
>> sizeof(INSTANCENAME);
>>
>> Since the only difference between these 2 drivers are PnP and non-PnP,
>> I really want to know if WMI is not supported in a non-PnP driver.
>>
>> Doran, do you have any non-PnP sample which supports WMI? I can not
>> find it in DDK or web. Thanks.
>>

> KMDF does support being a WMI provider (with

the appropriately named WDFWMIPROVIDER object); KMDF currently only
supports WMIREG_FLAG_INSTANCE_PDO as a way to register a name,

That would probably be a problem for the driver I’m working on. Ideally, I
would need dynamic string named WMI instances. Does KMDF support dynamic WMI
naming or only static WMI naming?

  • Jan

Neither static nor dynamic, just WMIREG_FLAG_INSTANCE_PDO which is a
fixed name based on the device instance path. If you need to use static
or dynamic based names, you could always preprocess the WDM WMI irps on
your own and handle the buffers yourself. Why do you require dynamic
instances names, e.g. why is WMIREG_FLAG_INSTANCE_PDO not good enough?

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Jan Bottorff
Sent: Monday, May 07, 2007 9:40 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] WMI & KMD

KMDF does support being a WMI provider (with
the appropriately named WDFWMIPROVIDER object); KMDF currently only
supports WMIREG_FLAG_INSTANCE_PDO as a way to register a name,

That would probably be a problem for the driver I’m working on. Ideally,
I
would need dynamic string named WMI instances. Does KMDF support dynamic
WMI
naming or only static WMI naming?

  • Jan

Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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

> Why do you require dynamic

instances names, e.g. why is WMIREG_FLAG_INSTANCE_PDO not good enough?

An issue with any of the static names is synchronization. If you have WMI
records that dynamically are created/removed there is a time lag between
when you ask for the static table refresh and when it happens. If you get
WMI data access irps in that gap, your data does not match what the old
static instance table says.

I found wmilib to be inadequate too, so wrote a bunch of C++ classes that
generically handle WMI operations. I just make subclasses and the lowest
level data type specific operations pass to the subclass via virtual
function calls. It would have been nice if Microsoft wrote all that generic
WMI code, but it doesn’t sound like KMDF currently would come close to
replacing what I have now.

For drivers that just create a few WMI records at driver start time,
INSTANCE_PDO named data probably works just fine.

  • Jan

My WMI unit test driver dynamically creates and destroys 100s of WMI
instances (or as you call them, record) at runtime w/out any issues. If
static names are better for you, use the WDM IRPs and do not register
anything with KMDF itself. We are looking to add static and dynamic
naming of instances to a future version of KMDF.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Jan Bottorff
Sent: Tuesday, May 08, 2007 5:40 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] WMI & KMD

Why do you require dynamic
instances names, e.g. why is WMIREG_FLAG_INSTANCE_PDO not good enough?

An issue with any of the static names is synchronization. If you have
WMI
records that dynamically are created/removed there is a time lag between
when you ask for the static table refresh and when it happens. If you
get
WMI data access irps in that gap, your data does not match what the old
static instance table says.

I found wmilib to be inadequate too, so wrote a bunch of C++ classes
that
generically handle WMI operations. I just make subclasses and the lowest
level data type specific operations pass to the subclass via virtual
function calls. It would have been nice if Microsoft wrote all that
generic
WMI code, but it doesn’t sound like KMDF currently would come close to
replacing what I have now.

For drivers that just create a few WMI records at driver start time,
INSTANCE_PDO named data probably works just fine.

  • Jan

Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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

> My WMI unit test driver dynamically creates and destroys 100s of WMI

instances (or as you call them, record) at runtime w/out any issues. If
static names are better for you, use the WDM IRPs and do not register
anything with KMDF itself. We are looking to add static and dynamic
naming of instances to a future version of KMDF.

But do you also have user mode code that’s constantly accessing them? And if
user mode code has the key to a WMI record in the driver, can it access
single instances (via IRP_MN_QUERY_SINGLE_INSTANCE or IRP_MN_EXECUTE_METHOD
or IRP_MN_CHANGE_SINGLE_INSTANCE) and have the key not change, even though
instances are coming and going?

If you’re using INSTANCE_PDO names, and you delete an instance, all the
following instances will have their key change (but not until you process
the IRP_MN_REGINFO_EX). In between the time you call
IoWMIRegistrationControl(pdo, WMI_ACTION_REREGISTER) and you receive
IRP_MN_REGINFO_EX, do you have a way to make sure incoming access requests
don’t reference the wrong instance? The issue is that instance index N,
refers to an instance named by the old version of the WMIREGINFO structure,
even though the new version of the WMIREGINFO structure may have a different
index for that instance.

It’s not real clear to me what (if any) the WMI subsystem locking semantics
of WMI irps are, but believe there is nothing that prevents access irps from
coming in while the WMIREGINFO structure is essentially stale. Blocking the
access irps in between WMI_ACTION_REREGISTER and IRP_MN_REGINFO_EX doesn’t
help, as the instance index has already been looked up in the old stale
instance table, and if you then let the irp process, its instance index is
still wrong.

Dynamic instance names are the only way I know to fully get this right. This
way the name lookup occurs in the driver, with the ability to correctly lock
updates.

Hope this answers WHY static INSTANCE_PDO named instances are inadequate.

Jan

You are correct, instances named on the PDO have weak indexing. This is
by design. An instance’s identity is not its index. If you need the
instance using the PDO as a name to have identity, you must embed that
identity in the instance’s data rather then its name.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Jan Bottorff
Sent: Tuesday, May 08, 2007 1:51 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] WMI & KMD

My WMI unit test driver dynamically creates and destroys 100s of WMI
instances (or as you call them, record) at runtime w/out any issues.
If
static names are better for you, use the WDM IRPs and do not register
anything with KMDF itself. We are looking to add static and dynamic
naming of instances to a future version of KMDF.

But do you also have user mode code that’s constantly accessing them?
And if
user mode code has the key to a WMI record in the driver, can it access
single instances (via IRP_MN_QUERY_SINGLE_INSTANCE or
IRP_MN_EXECUTE_METHOD
or IRP_MN_CHANGE_SINGLE_INSTANCE) and have the key not change, even
though
instances are coming and going?

If you’re using INSTANCE_PDO names, and you delete an instance, all the
following instances will have their key change (but not until you
process
the IRP_MN_REGINFO_EX). In between the time you call
IoWMIRegistrationControl(pdo, WMI_ACTION_REREGISTER) and you receive
IRP_MN_REGINFO_EX, do you have a way to make sure incoming access
requests
don’t reference the wrong instance? The issue is that instance index N,
refers to an instance named by the old version of the WMIREGINFO
structure,
even though the new version of the WMIREGINFO structure may have a
different
index for that instance.

It’s not real clear to me what (if any) the WMI subsystem locking
semantics
of WMI irps are, but believe there is nothing that prevents access irps
from
coming in while the WMIREGINFO structure is essentially stale. Blocking
the
access irps in between WMI_ACTION_REREGISTER and IRP_MN_REGINFO_EX
doesn’t
help, as the instance index has already been looked up in the old stale
instance table, and if you then let the irp process, its instance index
is
still wrong.

Dynamic instance names are the only way I know to fully get this right.
This
way the name lookup occurs in the driver, with the ability to correctly
lock
updates.

Hope this answers WHY static INSTANCE_PDO named instances are
inadequate.

Jan


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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

> You are correct, instances named on the PDO have weak indexing. This is

by design. An instance’s identity is not its index. If you need the
instance using the PDO as a name to have identity, you must embed that
identity in the instance’s data rather then its name.

It seems like that only works for read-only WMI instances or cases where the
instances never change dynamically. If you want to update an instance or
call a method on an instance that was dynamically added, using INSTANCE_PDO
names means the same key can get reassigned to a different instance at any
moment, and you may then update an instance different than the one you
originally read?

It doesn’t seem like embedding the identity value in the data helps if the
key value can change. Or are you saying that for instance updates, if you
embed the identity in the data, when you go to update the record or call the
method you could validate the identity field is what’s expected and fail the
request if it’s not. This places the burden of fixing the problem on the
application making the WMI call. It would have to reselect the correct WMI
instance and try the operation again. A little detail also is for method
calls, you don’t get the instance data, you get the method parameters and
the instance index mapped from the key value. Are you saying one of the
method parameters would have to be the instance identity value?

Dynamic WMI instance naming suddenly is looking easy compared to handling
all the ugly failure cases if you don’t use dynamic naming.

Jan

> Is it possible to make a KMD as a WMI provider?

This is well-documented on MSDN.

For NDIS drivers, it’s much simpler - you just define the mapping of WMI
requests to your OIDs.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com