評估沒有輸入引數的控制項方法

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

  • 如果控制項方法是裝置的立即子物件,驅動程式會傳送IOCTL_ACPI_EVAL_METHOD要求,並提供 ACPI_EVAL_INPUT_BUFFER 輸入結構。

  • 如果控制項方法是裝置 ACPI 命名空間中的子物件,但不是裝置的立即子物件,驅動程式會傳送IOCTL_ACPI_EVAL_METHOD_EX要求並提供 ACPI_EVAL_INPUT_BUFFER_EX 結構。

本主題中提供的 GetAbcData 函式範例會示範裝置的驅動程式如何使用IOCTL_ACPI_EVAL_METHOD要求來評估裝置支援的 'ABCD' 控制項方法。 'ABCD' 控制方法是 ACPI 命名空間中裝置的立即子系,不會採用輸入引數或傳回輸出引數。

如果 'ABCD' 控制項方法不是立即的子物件,則此範例程式碼的必要變更如下:

  • 傳送IOCTL_ACPI_EVAL_METHOD_EX要求,而不是IOCTL_ACPI_EVAL_METHOD要求。

  • 提供ACPI_EVAL_INPUT_BUFFER_EX結構,而不是ACPI_EVAL_INPUT_BUFFER結構。

GetAbcData 會先配置ACPI_EVAL_INPUT_BUFFER結構 inputBuffer ,並將 MethodNameAsUlong 成員設定為控制項方法的名稱,並將 Signature 成員設定為ACPI_EVAL_INPUT_BUFFER_SIGNATURE。

    // Fill in the input data
    inputBuffer.MethodNameAsUlong = (ULONG) ('DCBA');
    inputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;

GetAbcData 也會配置 ACPI_EVAL_OUTPUT_BUFFER 結構 outputBuffer,但不會設定 outputBuffer的任何成員。

GetAbcData 接著會呼叫名為 SendDownStreamIrp 的驅動程式提供函式,以執行下列動作:

  1. 呼叫 IoBuildDeviceIoControlRequest 來建置要求。

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

  3. 等候 I/O 管理員向驅動程式表示較低層級驅動程式已完成要求。

SendDownStreamIrp 會在 I/O 管理員發出訊號之後傳回,指出較低層級的驅動程式已完成要求。 稍早所述的程式碼範例會執行下列動作:

  1. 檢查要求的狀態,如果較低層級驅動程式未傳回STATUS_SUCCESS,則會傳回而不進行其他處理。

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

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

雖然這個步驟不包含在範例程式碼中,但驅動程式也應該在處理輸出資料之後呼叫 IoCompleteRequest ,以完成擱置IOCTL_ACPI_EVAL_METHOD要求,或IOCTL_ACPI_EVAL_METHOD要求驅動程式傳送來評估控制方法。

下列範例中使用的 ACPI 資料結構和常數定義于 Acpiioct.h中。

NTSTATUS
GetAbcdData(
    IN PDEVICE_OBJECT   Pdo,
    OUT PULONG          ReturnStatus
    )
/*++

Routine Description:
    Evaluates the ABCD method on the device in the ACPI namespace referenced by Pdo

Parameters
    Pdo             - PDO for the device
    ReturnStatus    - Pointer to where the status data is placed

Return Value:
    NT Status of the operation

--*/
{
    ACPI_EVAL_INPUT_BUFFER  inputBuffer;
    ACPI_EVAL_OUTPUT_BUFFER outputBuffer;
    NTSTATUS                status;
    PACPI_METHOD_ARGUMENT   argument;

    .
    .

    ASSERT( ReturnStatus != NULL );
    *ReturnStatus = 0x0;

    // Fill in the input data
    inputBuffer.MethodNameAsUlong = (ULONG) ('DCBA');
    inputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;

    // Send the request along
    status = SendDownStreamIrp(
       Pdo,
       IOCTL_ACPI_EVAL_METHOD,
       &inputBuffer,
       sizeof(ACPI_EVAL_INPUT_BUFFER),
       &outputBuffer,
       sizeof(ACPI_EVAL_OUTPUT_BUFFER)
       );

    if (!NT_SUCCESS(status)) {
       return status;
    }

    // Verify the data
    if (outputBuffer != NULL) {
        if ( ( (PACPI_EVAL_OUTPUT_BUFFER) outputBuffer->Signature != 
            ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE ||
            ( (PACPI_EVAL_OUTPUT_BUFFER) outputBuffer->Count == 0) {
            return STATUS_ACPI_INVALID_DATA;
        } 
}

    // Retrieve the output argument
    argument = outputBuffer.Argument;
 
// Process the output argument
 .
.
.
 
    return status;
}