Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Untuk mengevaluasi metode kontrol yang tidak mengambil argumen input secara sinkron, driver untuk perangkat mengirim permintaan IOCTL_ACPI_EVAL_METHOD atau permintaan IOCTL_ACPI_EVAL_METHOD_EX ke perangkat. Prosedur umum untuk menggunakan kedua permintaan ini dijelaskan dalam Mengevaluasi Metode Kontrol ACPI Secara Sinkron. Perbedaan spesifik antara menggunakan kedua permintaan ini adalah sebagai berikut:
Jika metode kontrol adalah objek turunan langsung dari perangkat, driver akan mengirimkan permintaan IOCTL_ACPI_EVAL_METHOD dan menyediakan struktur input ACPI_EVAL_INPUT_BUFFER.
Jika metode kontrol adalah objek turunan dalam namespace ACPI dari perangkat, tetapi bukan objek turunan langsung dari perangkat, driver mengirim permintaan IOCTL_ACPI_EVAL_METHOD_EX dan menyediakan struktur ACPI_EVAL_INPUT_BUFFER_EX.
Contoh fungsi GetAbcData yang disediakan dalam topik ini menunjukkan bagaimana driver untuk perangkat dapat menggunakan permintaan IOCTL_ACPI_EVAL_METHOD untuk mengevaluasi metode kontrol bernama 'ABCD' yang didukung perangkat. Metode kontrol 'ABCD' adalah turunan langsung perangkat di namespace ACPI dan tidak mengambil argumen input atau mengembalikan argumen output.
Jika metode kontrol 'ABCD' bukan objek turunan langsung, perubahan yang diperlukan pada kode contoh ini adalah sebagai berikut:
Kirim permintaan IOCTL_ACPI_EVAL_METHOD_EX alih-alih permintaan IOCTL_ACPI_EVAL_METHOD.
Berikan struktur ACPI_EVAL_INPUT_BUFFER_EX alih-alih struktur ACPI_EVAL_INPUT_BUFFER.
GetAbcData pertama-tama mengalokasikan struktur input ACPI_EVAL_INPUT_BUFFER inputBuffer dan mengatur anggota MethodNameAsUlong ke nama metode kontrol dan mengatur anggota Signature ke ACPI_EVAL_INPUT_BUFFER_SIGNATURE.
// Fill in the input data
inputBuffer.MethodNameAsUlong = (ULONG) ('DCBA');
inputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
GetAbcData juga mengalokasikan sebuah struktur ACPI_EVAL_OUTPUT_BUFFERoutputBuffer, tetapi tidak menyetel salah satu anggota dari outputBuffer.
GetAbcData kemudian memanggil fungsi yang disediakan driver bernama SendDownStreamIrp yang melakukan hal berikut:
Memanggil IoBuildDeviceIoControlRequest untuk membangun permintaan.
Memanggil IoCallDriver untuk mengirim permintaan ke tumpukan perangkat.
Menunggu manajer I/O memberi sinyal kepada driver bahwa driver tingkat bawah menyelesaikan permintaan.
SendDownStreamIrp kembali setelah manajer I/O memberi sinyal bahwa driver tingkat bawah telah menyelesaikan permintaan. Contoh kode yang disebutkan sebelumnya kemudian melakukan hal berikut:
Memeriksa status permintaan dan mengembalikan tanpa pemrosesan tambahan jika driver tingkat bawah tidak mengembalikan STATUS_SUCCESS.
Memeriksa validitas argumen output. Agar outputBuffer berisi data output yang valid, Tanda tangan harus diatur ke ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE dan Hitungan harus diatur ke lebih besar dari nol.
Memproses argumen keluaran yang diteruskan kembali oleh driver ACPI ke driver lain.
Meskipun langkah ini tidak termasuk dalam kode sampel, driver juga harus memanggil IoCompleteRequest setelah memproses data output untuk menyelesaikan permintaan IOCTL_ACPI_EVAL_METHOD yang tertunda atau permintaan IOCTL_ACPI_EVAL_METHOD yang dikirim driver untuk mengevaluasi metode kontrol.
Struktur dan konstanta data ACPI yang digunakan dalam contoh berikut didefinisikan dalam 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;
}