WMI sends this IRP to query or update a driver's registration information after the driver has called IoWMIRegistrationControl. A driver can handle WMI IRPs either by calling WmiSystemControl or by handling the IRP itself, as described in Handling WMI Requests.
On Microsoft Windows XP and later operating systems, drivers that support WMI must handle this IRP. Drivers that support Microsoft Windows 98 and Windows 2000 must also handle IRP_MN_REGINFO.
On Windows XP and later, WMI sends this IRP to query or update a driver's registration information after the driver has called IoWMIRegistrationControl. On Windows 98 and Windows 2000, WMI sends the IRP_MN_REGINFO request instead.
WMI sends this IRP at IRQL = PASSIVE_LEVEL in the context of a system thread.
Parameters.WMI.ProviderId points to the device object of the driver that should respond to the request. This pointer is located in the driver's I/O stack location in the IRP.
Parameters.WMI.DataPath is set to WMIREGISTER to query registration information or WMIUPDATE to update it.
Parameters.WMI.BufferSize indicates the maximum size of the nonpaged buffer at Parameters.WMI.Buffer. The size must be greater than or equal to the total of (sizeof(WMIREGINFO) + (GuidCount * sizeof(WMIREGGUID)), where GuidCount is the number of data blocks and event blocks being registered by the driver, plus space for static instance names, if any.
If the driver handles WMI IRPs by calling WmiSystemControl, WMI gets registration information for a driver's data blocks by calling its DpWmiQueryReginfo routine.
Otherwise, the driver fills in a WMIREGINFO structure at Parameters.WMI.Buffer as follows:
Sets BufferSize to the size in bytes of the WMIREGINFO structure plus associated registration data.
If the driver handles WMI requests on behalf of another driver, sets NextWmiRegInfo to the offset in bytes from the beginning of this WMIREGINFO to the beginning of another WMIREGINFO structure that contains registration information from the other driver.
Sets RegistryPath to the registry path that was passed to the driver's DriverEntry routine.
If Parameters.WMI.Datapath is set to WMIREGISTER, sets MofResourceName to the offset from the beginning of this WMIREGINFO to a counted Unicode string that contains the name of the driver's MOF resource in its image file.
Sets GuidCount to the number of data blocks and event blocks to register or update.
Writes an array of WMIREGGUID structures, one for each data block or event block exposed by the driver, at WmiRegGuid.
The driver fills in each WMIREGGUID structure as follows:
Sets Guid to the GUID that identifies the block.
Sets Flags to provide information about instance names and other characteristics of the block. For example, if a block is being registered with static instance names, the driver sets Flags with the appropriate WMIREG_FLAG_INSTANCE_XXX flag.
If the block is being registered with static instance names, the driver:
Sets InstanceCount to the number of instances.
Sets one of the following members to an offset in bytes to static instance name data for the block:
If the driver sets Flags with WMIREG_FLAG_INSTANCE_LIST, it sets InstanceNameList to an offset to a list of static instance name strings. WMI specifies instances in subsequent requests by index into this list.
If the driver sets Flags with WMIREG_FLAG_INSTANCE_BASENAME, it sets BaseNameOffset to an offset to a base name string. WMI uses this string to generate static instance names for the block.
If the driver sets Flags with WMIREG_FLAG_INSTANCE_PDO, it sets Pdo to an offset to a pointer to the PDO passed to the driver's AddDevice routine. WMI uses the device instance path of the PDO to generate static instance names for the block. Drivers must call ObReferenceObject on the physical device object passed in Pdo. The system will automatically call ObDereferenceObject to dereference the object; the driver must not do so. (Drivers that use WmiSystemControl to handle IRPs do not need to call ObReferenceObject. WMI automatically does so before calling the driver's DpWmiQueryReginfo routine.)
Writes the instance name strings, the base name string, or a pointer to the PDO at the offset indicated by InstanceNameList, BaseName, or Pdo, respectively.
If the driver handles WMI registration on behalf of another driver (such as a miniclass or miniport driver), it fills in another WMIREGINFO structure with the other driver's registration information and writes it at NextWmiRegInfo in the previous structure.
If the buffer at Parameters.WMI.Buffer is too small to receive all of the data, a driver writes the needed size in bytes as a ULONG to Parameters.WMI.Buffer and fails the IRP and returns STATUS_BUFFER_TOO_SMALL.
I/O Status Block
If the driver handles the IRP by calling WmiSystemControl, WMI sets Irp->IoStatus.Status and Irp->IoStatus.Information in the I/O status block.
Otherwise, the driver sets Irp->IoStatus.Status to STATUS_SUCCESS or to an appropriate error status such as the following:
On success, a driver sets Irp->IoStatus.Information to the number of bytes written to the buffer at Parameters.WMI.Buffer.
If a driver handles an IRP_MN_REGINFO_EX request itself, it should do so only if Parameters.WMI.ProviderId points to the same device object as the pointer that the driver passed to IoWMIRegistrationControl. Otherwise, the driver must forward the request to the next-lower driver.
Before handling the request, the driver must check Parameters.WMI.DataPath to determine whether WMI is querying registration information (WMIREGISTER) or requesting an update (WMIUPDATE).
WMI sends this IRP with WMIREGISTER after a driver calls IoWMIRegistrationControl with WMIREG_ACTION_REGISTER or WMIREG_ACTION_REREGISTER. In response, a driver should fill in the buffer at Parameters.WMI.Buffer with the following:
A WMIREGINFO structure that indicates the driver's registry path, the name of its MOF resource, and the number of blocks to register.
One WMIREGGUID structure for each block to register. If a block is to be registered with static instance names, the driver sets the appropriate WMIREG_FLAG_INSTANCE_XXX flag in the WMIREGGUID structure for that block.
Any strings WMI needs to generate static instance names.
WMI sends this IRP with WMIUPDATE after a driver calls IoWmiRegistrationControl with WMIREG_ACTION_UPDATE_GUIDS. In response, a driver should fill in the buffer at Parameters.WMI.Buffer with a WMIREGINFO structure as follows:
To remove a block, the driver sets WMIREG_FLAG_REMOVE_GUID in its WMIREGGUID structure.
To add or update a block (for example, to change its static instance names), the driver clears WMIREG_FLAG_REMOVE_GUID and provides new or updated registration values for the block.
To register a new or existing block with static instance names, the driver sets the appropriate WMIREG_FLAG_INSTANCE_XXX and supplies any strings WMI needs to generate static instance names.
A driver can use the same WMIREGINFO structures to remove, add, or update blocks as it used initially to register all of its blocks, changing only the flags and data for the blocks to be updated. If a WMIREGGUID in such a WMIREGINFO structure matches exactly the WMIREGGUID passed by the driver when it first registered that block, WMI skips the processing involved in updating the block.
WMI does not send an IRP_MN_REGINFO_EX request after a driver calls IoWMIRegistrationControl with WMIREG_ACTION_DEREGISTER, because WMI requires no further information from the driver. A driver typically deregisters its blocks in response to an IRP_MN_REMOVE_DEVICE request.