Evaluating a Control Method That Takes Input Arguments
To synchronously evaluate a control method that takes input arguments, a driver for a device sends an IOCTL_ACPI_EVAL_METHOD request or an IOCTL_ACPI_EVAL_METHOD_EX request to the device. The general procedure for using both these requests is described in Evaluating ACPI Control Methods Synchronously. The specific difference between using these two requests is as follows:
If the control method is an immediate child object of the device, the driver sends an IOCTL_ACPI_EVAL_METHOD request and supplies one of the following input structures: ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER, ACPI_EVAL_INPUT_BUFFER_SIMPLE_STRING, or ACPI_EVAL_INPUT_BUFFER_COMPLEX.
If the control method is a child object in the ACPI namespace of the device, but is not an immediate child object of the device, the driver sends an IOCTL_ACPI_EVAL_METHOD_EX request and supplies one of the following input structures: ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER_EX, ACPI_EVAL_INPUT_BUFFER_SIMPLE_STRING_EX, or ACPI_EVAL_INPUT_BUFFER_COMPLEX_EX.
The example EvaluateABCDWithInputArgument function that is provided in this topic shows how a driver can use an IOCTL_ACPI_EVAL_METHOD request to evaluate a control method named 'ABCD' that takes a single integer input argument.
If the input argument was a string or an array of custom data instead of an integer, the required change to the example code is to supply a string input structure or a complex input structure instead of an integer input structure.
In addition, if the 'ABCD' control method was not an immediate child object, the required changes to the example code are as follows:
Send an IOCTL_ACPI_EVAL_METHOD_EX request instead of an IOCTL_ACPI_EVAL_METHOD request.
Supply the type of extended input structure that corresponds to the input argument type (simple integer, simple string, or complex).
EvaluateABCDWithInputArgument first allocates an ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER structure inputBuffer and then sets the MethodNameAsUlong member to the name of the control method, sets the IntegerArgument member to the input integer value, and sets the Signature member to ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER_SIGNATURE.
// Fill in the input data
inputBuffer.MethodNameAsUlong = (ULONG) ('DCBA');
inputBuffer.IntegerArgument = Argument1;
inputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER_SIGNATURE;
EvaluateABCDWithInputArgument also allocates an ACPI_EVAL_OUTPUT_BUFFER structure outputBuffer, but does not set any of the members of outputBuffer.
EvaluateABCDWithInputArgument then calls a driver-supplied function named SendDownStreamIrp that performs the following:
Calls IoBuildDeviceIoControlRequest to build the request.
Calls IoCallDriver to send the request down the device stack.
Waits for the I/O manager to signal the driver that the lower-level drivers have completed the request.
SendDownStreamIrp returns after the I/O manager signals that the lower-level drivers have completed the request.
Although not included in EvaluateABCDWithInputArgument, the driver should also perform the following additional operations after SendDownStreamIrp returns:
Check the status that SendDownStreamIrp returns. If SendDownStreamIrp does not return STATUS_SUCCESS, the driver should return without additional processing.
Check the validity of the output parameters. For the outputBuffer to contain valid output data, Signature must be set to ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE and Count must be set to greater than zero.
Process the output parameters that were passed back to the driver.
Call IoCompleteRequest to complete the IOCTL_ACPI_EVAL_METHOD request.
The ACPI data structures and constants used in the following example are defined in Acpiioct.h.
NTSTATUS
EvaluateABCDWithInputArgument(
IN PDEVICE_OBJECT Pdo,
IN ULONG Argument1,
OUT PULONG ReturnStatus
)
/*
Routine Description:
Called to evaluate the example 'ABCD' method with a single integer input argument
Parameters:
Pdo - For the device.
Argument1 - Input argument.
ReturnStatus - Pointer to where the status data is placed.
Return Value:
NT Status of the operation
*/
{
ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER inputBuffer;
ACPI_EVAL_OUTPUT_BUFFER outputBuffer;
NTSTATUS status;
PACPI_METHOD_ARGUMENT argument;
.
.
// Omitted: bounds checking on Argument1 value.
ASSERT( ReturnStatus != NULL );
*ReturnStatus = 0x0;
// Fill in the input data
inputBuffer.MethodNameAsUlong = (ULONG) ('DCBA');
inputBuffer.IntegerArgument = Argument1;
inputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER_SIGNATURE;
// Send the request along
status = SendDownStreamIrp(
Pdo,
IOCTL_ACPI_EVAL_METHOD,
&inputBuffer,
sizeof(ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER),
&outputBuffer,
sizeof(ACPI_EVAL_OUTPUT_BUFFER)
);
return status;
}