All drivers that support methods within data blocks must handle this IRP. A driver can handle WMI IRPs either by calling WmiSystemControl or by handling the IRP itself, as described in Handling WMI Requests.
WMI sends this IRP to execute a method associated with a data block.
WMI sends this IRP at IRQL = PASSIVE_LEVEL in an arbitrary thread context.
WMI will send an IRP_MN_QUERY_SINGLE_INSTANCE prior to sending an IRP_MN_EXECUTE_METHOD. If a driver supports IRP_MN_EXECUTE_METHOD it must have a IRP_MN_QUERY_SINGLE_INSTANCE handler for the same data block whose method is being executed.
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 points to a GUID that identifies the data block associated with the method to execute.
Parameters.WMI.BufferSize indicates the size of the nonpaged buffer at Parameters.WMI.Buffer which must be >= sizeof(WNODE_METHOD_ITEM) plus the size of any output data for the method.
Parameters.WMI.Buffer points to a WNODE_METHOD_ITEM structure in which MethodID indicates the identifier of the method to execute and DataBlockOffset indicates the offset in bytes from the beginning of the structure to the first byte of input data, if any. Parameters.WMI.Buffer->SizeDataBlock indicates the size in bytes of the input WNODE_METHOD_ITEM including input data, or zero if there is no input.
Otherwise, the driver fills in the WNODE_METHOD_ITEM structure that Parameters.WMI.Buffer points to as follows:
Updates WnodeHeader.BufferSize with the size of the output WNODE_METHOD_ITEM, including any output data.
Updates SizeDataBlock with the size of the output data, or zero if there is no output data.
Checks Parameters.WMI.Buffersize to determine whether the buffer is large enough to receive the output WNODE_METHOD_ITEM including any output data. If the buffer is not large enough, the driver fills in the needed size in a WNODE_TOO_SMALL structure pointed to by Parameters.WMI.Buffer. If the buffer is smaller than sizeof(WNODE_TOO_SMALL), the driver fails the IRP and returns STATUS_BUFFER_TOO_SMALL.
Writes output data, if any, over input data starting at DataBlockOffset. The driver must not change the input value of DataBlockOffset.
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 WMI IRPs by calling WmiSystemControl, that routine calls the driver's DpWmiExecuteMethod routine, or returns STATUS_INVALID_DEVICE_REQUEST if the driver does not define the routine.
If a driver handles an IRP_MN_EXECUTE_METHOD request itself, it must 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.
The driver is responsible for validating all input values. Specifically, the driver must do the following if it handles the IRP request itself:
For static names, verify that the InstanceIndex member of the WNODE_METHOD_ITEM structure is within the range of instance indexes supported by the driver for the data block.
For dynamic names, verify that the instance name string identifies a data block instance supported by the driver.
Verify that the MethodId member of the WNODE_METHOD_ITEM structure is within the range of method identifiers supported by the driver for the data block, and that the caller is allowed to execute the method.
Verify that the DataBlockOffset and SizeDataBlock members of the WNODE_METHOD_ITEM structure describe a buffer that is large enough to contain the specified method's parameters, and that the parameters are valid for the method.
Verify that Parameters.WMI.Buffersize specifies a buffer that is large enough to receive the WNODE_METHOD_ITEM structure after it has been updated with output data.
Do not assume the thread context is that of the initiating user-mode application — a higher-level driver might have changed it.
Before handling the request, the driver must determine whether Parameters.WMI.DataPath points to a GUID supported by the driver. If not, the driver must fail the IRP and return STATUS_WMI_GUID_NOT_FOUND.
If the driver supports the data block, it checks the input WNODE_METHOD_ITEM at Parameters.WMI.Buffer for the instance name, as follows:
If WNODE_FLAG_STATIC_INSTANCE_NAMES is set in WnodeHeader.Flags, the driver uses InstanceIndex as an index into the driver's list of static instance names for that block. WMI obtains the index from registration data that was provided by the driver when it registered the block.
If WNODE_FLAG_STATIC_INSTANCE_NAMES is clear in WnodeHeader.Flags, the driver uses the offset at OffsetInstanceName to locate the instance name string in the input WNODE_METHOD_ITEM. OffsetInstanceName is the offset in bytes from the beginning of the structure to a USHORT which is the length of the instance name string in bytes (not characters), including the terminating null if present, followed by the instance name string in Unicode.
If the driver cannot locate the specified instance, it must fail the IRP and return STATUS_WMI_INSTANCE_NOT_FOUND. For an instance with a dynamic instance name, this status indicates that the driver does not support the instance. WMI can therefore continue to query other data providers, and return an appropriate error to the data consumer if another provider finds the instance but cannot handle the request for some other reason.
The driver then checks the method ID in the input WNODE_METHOD_ITEM to determine whether it is a valid method for that data block. If not, the driver fails the IRP and returns STATUS_WMI_ITEMID_NOT_FOUND.
If the method generates output, the driver should check the size of the output buffer in Parameters.WMI.BufferSize before performing any operation that might have side effects or that should not be performed twice. For example, if a method returns the values of a group of counters and then resets the counters, the driver should check the buffer size (and fail the IRP if the buffer is too small) before resetting the counters. This ensures that WMI can safely resend the request with a larger buffer.
If the instance and method ID are valid and the buffer is adequate in size, the driver executes the method. If SizeDataBlock in the input WNODE_METHOD_ITEM is nonzero, the driver uses the data starting at DataBlockOffset as input for the method.
If the method generates output, the driver writes the output data to the buffer starting at DataBlockOffset and sets SizeDataBlock in the output WNODE_METHOD_ITEM to the number of bytes of output data. If the method has no output data, the driver sets SizeDataBlock to zero. The driver must not change the input value of DataBlockOffset.
If the instance is valid but the driver cannot handle the request, it can return any appropriate error status.
|Wdm.h (include Wdm.h, Ntddk.h, or Ntifs.h)|