Freigeben über


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:

  1. Ruft IoBuildDeviceIoControlRequest auf, um die Anforderung zu erstellen.

  2. Ruft IoCallDriver auf, um die Anforderung auf dem Gerätestapel zu senden.

  3. 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:

  1. Ü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.

  2. Ü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.

  3. 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;
}