评估采用输入参数的控制方法
若要同步评估采用输入参数的控制方法,设备的驱动程序应向设备发送 IOCTL_ACPI_EVAL_METHOD 请求或 IOCTL_ACPI_EVAL_METHOD_EX 请求。 同步评估 ACPI 控制方法中介绍了使用这两个请求的常规过程。 使用以下两个请求之间的具体区别如下:
如果控制方法是设备的直接子对象,驱动程序会发送 IOCTL_ACPI_EVAL_METHOD 请求,并提供以下输入结构之一:ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER、ACPI_EVAL_INPUT_BUFFER_SIMPLE_STRING 或 ACPI_EVAL_INPUT_BUFFER_COMPLEX。
如果控制方法是设备 ACPI 命名空间中的子对象,但不是设备的直接子对象,驱动程序会发送 IOCTL_ACPI_EVAL_METHOD_EX 请求,并提供以下输入结构之一:ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER_EX、ACPI_EVAL_INPUT_BUFFER_SIMPLE_STRING_EX 或 ACPI_EVAL_INPUT_BUFFER_COMPLEX_EX。
本主题中提供的示例 EvaluateABCDWithInputArgument 函数演示如何使用 IOCTL_ACPI_EVAL_METHOD 请求,来评估采用单个整数输入参数的名为“ABCD”的控制方法。
如果输入参数是字符串或自定义数据数组而不是整数,则示例代码所需的更改是提供字符串输入结构或复杂输入结构,而不是整数输入结构。
此外,如果“ABCD”控制方法不是直接子对象,则示例代码所需的更改如下所示:
发送 IOCTL_ACPI_EVAL_METHOD_EX 请求,而不是 IOCTL_ACPI_EVAL_METHOD 请求。
提供与输入参数类型(简单整数、简单字符串或复杂)相对应的扩展输入结构的类型。
EvaluateABCDWithInputArgument 首先分配 ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER 结构 inputBuffer,然后将 MethodNameAsUlong 成员设置为控制方法的名称,将 IntegerArgument 成员设置为输入整数值,并将 Signature 成员设置为 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 还会分配 ACPI_EVAL_OUTPUT_BUFFER 结构 outputBuffer,但不会设置 outputBuffer 的任何成员。
然后,EvaluateABCDWithInputArgument 会调用名为 SendDownStreamIrp 的驱动程序提供的函数,该函数将执行以下操作:
调用 IoBuildDeviceIoControlRequest 来生成请求。
调用 IoCallDriver 来将请求发送到设备堆栈。
等待 I/O 管理器向驱动程序发出较低级别驱动程序已完成请求的信号。
SendDownStreamIrp 会在 I/O 管理器指示较低级别驱动程序已完成请求后返回。
尽管 EvaluateABCDWithInputArgument 中未包含,但在 SendDownStreamIrp 返回后,驱动程序还应执行以下附加操作:
检查 SendDownStreamIrp 返回的状态。 如果 SendDownStreamIrp 未返回 STATUS_SUCCESS,驱动程序应返回,而不进行其他处理。
检查输出参数的有效性。 若要使 outputBuffer 包含有效的输出数据,必须将 Signature 设置为 ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE,并且必须将 Count 设置为大于零。
处理传递回驱动程序的输出参数。
调用 IoCompleteRequest 以完成 IOCTL_ACPI_EVAL_METHOD 请求。
以下示例中使用的 ACPI 数据结构和常量已在 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;
}