Auswerten einer Steuerelementmethode ohne Eingabeargumente
Um eine Steuerungsmethode, die keine Eingabeargumente akzeptiert, synchron auszuwerten, sendet ein Treiber für ein Gerät eine IOCTL_ACPI_EVAL_METHOD-Anforderung oder eine IOCTL_ACPI_EVAL_METHOD_EX-Anforderung an das Gerät. Das allgemeine Verfahren für die Verwendung dieser beiden Anforderungen wird unter Synchrones Auswerten von ACPI-Steuerungsmethoden beschrieben. Der spezifische Unterschied zwischen der Verwendung dieser beiden Anforderungen ist wie folgt:
Wenn die Steuerungsmethode ein unmittelbar untergeordnetes Objekt des Geräts ist, sendet der Treiber eine IOCTL_ACPI_EVAL_METHOD-Anforderung und stellt eine ACPI_EVAL_INPUT_BUFFER Eingabestruktur bereit.
Wenn die Steuerelementmethode ein untergeordnetes Objekt im ACPI-Namespace des Geräts, aber kein unmittelbar untergeordnetes Objekt des Geräts ist, sendet der Treiber eine IOCTL_ACPI_EVAL_METHOD_EX Anforderung und stellt eine ACPI_EVAL_INPUT_BUFFER_EX-Struktur bereit.
Die Beispielfunktion GetAbcData , die in diesem Thema bereitgestellt wird, zeigt, wie ein Treiber für ein Gerät eine IOCTL_ACPI_EVAL_METHOD-Anforderung verwenden kann, um eine Steuerungsmethode namens "ABCD" auszuwerten, die vom Gerät unterstützt wird. Die Steuerungsmethode "ABCD" ist ein unmittelbar untergeordnetes Element des Geräts im ACPI-Namespace und akzeptiert keine Eingabeargumente oder gibt Ausgabeargumente zurück.
Wenn die "ABCD"-Steuerelementmethode kein unmittelbar untergeordnetes Objekt war, sind die erforderlichen Änderungen an diesem Beispielcode wie folgt:
Senden Sie eine IOCTL_ACPI_EVAL_METHOD_EX-Anforderung anstelle einer IOCTL_ACPI_EVAL_METHOD-Anforderung.
Geben Sie eine ACPI_EVAL_INPUT_BUFFER_EX-Struktur anstelle einer ACPI_EVAL_INPUT_BUFFER-Struktur an.
GetAbcData weist zuerst einen ACPI_EVAL_INPUT_BUFFER Structure inputBuffer zu, legt das MethodNameAsUlong-Element auf den Namen der Steuerelementmethode fest und legt das Signature-Element auf ACPI_EVAL_INPUT_BUFFER_SIGNATURE fest.
// Fill in the input data
inputBuffer.MethodNameAsUlong = (ULONG) ('DCBA');
inputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
GetAbcData weist auch einen ACPI_EVAL_OUTPUT_BUFFER structure outputBuffer zu, legt jedoch keines der Member von outputBuffer fest.
GetAbcData ruft dann eine vom Treiber bereitgestellte Funktion namens SendDownStreamIrp auf, die Folgendes ausführt:
Ruft IoBuildDeviceIoControlRequest auf, um die Anforderung zu erstellen.
Ruft IoCallDriver auf, um die Anforderung auf dem Gerätestapel zu senden.
Wartet darauf, dass der E/A-Manager dem Treiber signalisiert, dass die Anforderung der treiber unteren Ebene abgeschlossen wurde.
SendDownStreamIrp wird zurückgegeben, nachdem der E/A-Manager signalisiert hat, dass die Untergeordneten Treiber die Anforderung abgeschlossen haben. Das zuvor erwähnte Codebeispiel führt dann Folgendes aus:
Überprüft die status der Anforderung und gibt ohne zusätzliche Verarbeitung zurück, wenn die Treiber der niedrigeren Ebene nicht STATUS_SUCCESS zurückgegeben haben.
Überprüft die Gültigkeit der Ausgabeargumente. Damit der outputBuffer gültige Ausgabedaten enthält, muss Signature auf ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE und Count auf größer als 0 (Null) festgelegt werden.
Verarbeitet die Ausgabeargumente, die der ACPI-Treiber zurück an den Treiber übergeben hat.
Obwohl dieser Schritt nicht im Beispielcode enthalten ist, sollte der Treiber auch IoCompleteRequest aufrufen, nachdem die Ausgabedaten verarbeitet wurden, um die ausstehende IOCTL_ACPI_EVAL_METHOD- oder IOCTL_ACPI_EVAL_METHOD Anforderung abzuschließen, die der Treiber zum Auswerten einer Steuerungsmethode gesendet hat.
Die im folgenden Beispiel verwendeten ACPI-Datenstrukturen und Konstanten sind in Acpiioct.h definiert.
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;
}