評估接受輸入引數的控制項方法

若要同步評估採用輸入引數的控制方法,裝置的驅動程式會將 IOCTL_ACPI_EVAL_METHOD 要求或 IOCTL_ACPI_EVAL_METHOD_EX 要求傳送至裝置。 使用這兩個要求的一般程式說明為 同步評估 ACPI 控制方法。 使用這兩個要求之間的特定差異如下:

本主題中提供的 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 的驅動程式提供函式,以執行下列動作:

  1. 呼叫 IoBuildDeviceIoControlRequest 來建置要求。

  2. 呼叫 IoCallDriver 以將要求向下傳送到裝置堆疊。

  3. 等候 I/O 管理員向驅動程式發出訊號,指出較低層級的驅動程式已完成要求。

SendDownStreamIrp 會在 I/O 管理員發出訊號之後傳回,指出較低層級的驅動程式已完成要求。

雖然 未包含在 EvaluateABCDWithInputArgument中,但在 SendDownStreamIrp 傳回之後,驅動程式也應該執行下列額外作業:

  1. 檢查 SendDownStreamIrp 傳回的狀態。 如果 SendDownStreamIrp 未傳回STATUS_SUCCESS,驅動程式應該會傳回,而不需額外處理。

  2. 檢查輸出參數的有效性。 若要讓 outputBuffer 包含有效的輸出資料, 簽章 必須設定為 ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE 且 Count 必須設定為大於零。

  3. 處理傳回給驅動程式的輸出參數。

  4. 呼叫 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;
}