Calling WmiSystemControl to Handle WMI IRPs
WMI library routines simplify handling of WMI requests because instead of processing each such request, a driver calls WmiSystemControl. In the WmiSystemControl call, the driver passes an initialized WMILIB_CONTEXT structure that contains entry points to the driver's WMI library callback routines (DpWmiXxx routines) and information about the driver's data blocks and event blocks.
Because the WMI library provides no mechanism for passing dynamic instance names or a static instance name list, a driver can use the WMI library to handle requests involving only data blocks with static instance names based on a PDO or a single base name string. For more information about static and dynamic instance names, see Defining WMI Instance Names. Nothing prevents a driver from using the WMI library to handle requests for such blocks and processing requests for other blocks in its DispatchSystemControl routine. For more information, see Processing WMI IRPs in a DispatchSystemControl Routine.
To handle WMI IRPs by calling WmiSystemControl, a driver must implement certain required DpWmiXxx callback routines, and might implement additional optional DpWmiXxx callback routines:
DpWmiQueryReginfo—(Required) Provides information about the data and event blocks being registered by the driver. WMI calls a driver's DpWmiQueryReginfo routine to process an IRP_MN_REGINFO or IRP_MN_REGINFO_EX request. For more information, see Using the WMI Library to Register Blocks.
DpWmiQueryDataBlock—(Required) Returns either a single instance or all instances of a data block. WMI calls a driver's DpWmiQueryDataBlock routine to process an IRP_MN_QUERY_SINGLE_INSTANCE or IRP_MN_QUERY_ALL_DATA request.
DpWmiSetDataBlock—(Optional) Changes all data items in a single instance of a data block. WMI calls a driver's DpWmiSetDataBlock routine to process an IRP_MN_CHANGE_SINGLE_INSTANCE request.
DpWmiSetDataItem—(Optional) Changes a single data item in an instance of a data block. WMI calls a driver's DpWmiSetDataItem routine to process an IRP_MN_CHANGE_SINGLE_ITEM request.
DpWmiFunctionControl—(Optional) Enables and disables event notification and data collection for blocks registered as expensive to collect. WMI calls a driver's DpWmiFunctionControl routine to process an IRP_MN_ENABLE_COLLECTION, IRP_MN_DISABLE_COLLECTION, IRP_MN_ENABLE_EVENTS, or IRP_MN_DISABLE_EVENTS request.
DpWmiExecuteMethod—(Optional) Executes a method associated with a data block. WMI calls a driver's DpWmiExecuteMethod routine to process an IRP_MN_EXECUTE_METHOD request.
A driver's DpWmiXxx routines can have any names chosen by the driver writer.
Before calling WmiSystemControl, the driver must initialize a WMILIB_CONTEXT structure with entry points to its DpWmiXxx routines and information about its data blocks and event blocks.
When the driver receives a WMI request:
The driver calls WmiSystemControl with a pointer to its initialized WMILIB_CONTEXT structure, a pointer to its device object, and a pointer to the IRP.
WMI validates the IRP parameters and calls the driver's DpWmiXxx routine that processes the request. If the driver set no entry point in its WMILIB_CONTEXT for an optional DpWmiXxx routine, WMI completes the IRP with default values and status.
In its DpWmiXxx routine, the driver processes the request and writes any output to the caller-supplied buffer. For example, a driver's DpWmiQueryDataBlock routine would write the requested instance(s) of the specified block to the buffer.
In all DpWmiXxx routines except DpWmiQueryReginfo, the driver calls WmiCompleteRequest to complete the request, or returns STATUS_PENDING to postpone completion, as for any IRP.
WMI performs any necessary postprocessing, packages any output in an appropriate WNODE_XXX structure, and passes the output and status to the data consumer.