評估沒有輸入引數的控制項方法
若要同步評估不接受輸入引數的控制方法,裝置的驅動程式會將 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 的驅動程式提供函式,以執行下列動作:
呼叫 IoBuildDeviceIoControlRequest 來建置要求。
呼叫 IoCallDriver 以將要求向下傳送到裝置堆疊。
等候 I/O 管理員向驅動程式表示較低層級驅動程式已完成要求。
SendDownStreamIrp 會在 I/O 管理員發出訊號之後傳回,指出較低層級的驅動程式已完成要求。 稍早所述的程式碼範例會執行下列動作:
檢查要求的狀態,如果較低層級驅動程式未傳回STATUS_SUCCESS,則會傳回而不進行其他處理。
檢查輸出引數的有效性。 若要讓 outputBuffer 包含有效的輸出資料, 簽章 必須設定為 ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE 且 Count 必須設定為大於零。
處理 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;
}