入力引数を受け取る制御メソッドを評価する
入力引数を受け取る制御メソッドを同期的に評価するために、デバイスのドライバーは IOCTL_ACPI_EVAL_METHOD 要求または IOCTL_ACPI_EVAL_METHOD_EX 要求をデバイスに送信します。 これらの両方の要求を使用する一般的な手順については、「ACPI 制御メソッドを同期的に評価する」を参照してください。 これら 2 つの要求を使用する具体的な違いは次のとおりです。
制御メソッドがデバイスの直接の子オブジェクトである場合、ドライバーは 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 要求を使用して、1 つの整数入力引数を受け取る 'ABCD' という名前の制御メソッドを評価する方法を示します。
入力引数が整数ではなく文字列またはカスタム データの配列である場合、コード例に必要な変更は、整数入力構造体ではなく文字列入力構造体または複雑な入力構造体を指定することです。
さらに、"ABCD" 制御メソッドが直接の子オブジェクトでない場合、コード例に対して必要な変更は次のようになります。
IOCTL_ACPI_EVAL_METHOD 要求ではなく、IOCTL_ACPI_EVAL_METHOD_EX 要求を送信します。
入力引数の型 (単純整数、単純文字列、または複合) に対応する拡張入力構造体の型を指定します。
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 を 0 より大きい値にする必要があります。
ドライバーに返された出力パラメーターを処理します。
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;
}