1. WMI Architecture
To support WMI, your driver registers as a WMI
provider. A WMI provider is a Win32 dynamic-link library (DLL) that
handles WMI requests and supplies WMI instrumentation data.
After your driver is registered as a WMI provider, WMI consumers then request data or invoke methods exposed by providers.
Query requests travel from user mode consumers down to WMI kernel mode service, which in turn send IRP requests to your driver.
For instance, when a WMI client requests a given
data block, the WMI kernel component sends a query request to the
driver to retrieve or set data. Figure 1 shows this data flow.
2. Registering as a WMI Data Provider
A
driver that supports WMI must register as a WMI data provider to make
its data and event blocks available to WMI clients. A driver typically
registers with WMI when starting its device, after the device has been
initialized to the point that the driver can handle WMI IRPs. During
the registration process, the driver passes WMI a pointer to its device
object and information about the data and event blocks it supports.
A driver registers with WMI in two phases:
The driver calls IoWMIRegistrationControl with the action WMIREG_ACTION_REGISTER and a pointer to the device object passed to the driver’s AddDevice routine.
The driver handles the IRP_MN_REGINFO or IRP_MN_REGINFO_EX request that WMI sends in response to the driver’s IoWMIRegistrationControlParameters.WMI.DataPath member of the IRP is set to WMIREGISTER and Parameters.WMI.ProviderId
is set to the driver’s device object pointer. The driver supplies WMI
with registration information about data and event blocks, either by
using the WMI Library, or by handling the IRP_MN_REGINFO or IRP_MN_REGINFO_EX requests. call. The
3. Handling WMI Requests
All drivers must set a dispatch table entry point for a DispatchSystemControl
routine to handle WMI requests. If a driver registers as a WMI data
provider, it must handle all WMI requests. Otherwise, the driver must
forward all WMI requests to the next lower driver.
All WMI IRPs have the major code IRP_MJ_SYSTEM_CONTROL and one of the following minor codes:
IRP_MN_REGINFO or IRP_MN_REGINFO_EX— Queries or updates a driver’s registration information after the driver has called IoWMIRegistrationControl.
IRP_MN_QUERY_All_DATA or IRP_MN_QUERY_SINGLE_INSTANCE— Queries for all instances or a single instance of a given data block.
IRP_MN_CHANGE_SINGLE_ITEM, IRP_MN_CHANGE_SINGLE_INSTANCE— Requests the driver to change a single item or multiple items in an instance of a data block.
IRP_MN_ENABLE_COLLECTION, IRP_MN_DISABLE_COLLECTION— Requests the driver to start accumulating data for a block that the driver registered as expensive to collect, or to stop accumulating data for such a block.
IRP_MN_ENABLE_EVENTS, IRP_MN_DISABLE_EVENTS—
Requests the driver to start sending notification of a given event if
the event occurs while it is enabled, or to stop sending notification
of such an event.
IRP_MN_EXECUTE_METHOD— Requests the driver to execute a method associated with a data block.
The WMI kernel mode component sends WMI IRPs any
time following a driver’s successful registration as a WMI data
provider, typically when a user mode data consumer has requested WMI
information for a driver’s device. If a driver registers as a WMI data
provider by calling IoWMIRegistrationControl, it must handle each subsequent WMI request in one of the following ways:
Call the kernel mode WMI library routine WmiSystemControl
to handle requests concerning only blocks that do not use dynamic
instance names, and that base static instance names on a single base
name string or the device instance ID of a PDO.
In its DispatchSystemControl
routine, process and complete any such request tagged with the pointer
to its device object that the driver passed in its call to IoWMIRegistrationControl, and forward other IRP_MJ_SYSTEM_CONTROL requests to the next lower driver.