Dela via


Utvärdera en kontrollmetod utan indataargument

För att synkront utvärdera en kontrollmetod som inte tar indataargument skickar en drivrutin för en enhet en IOCTL_ACPI_EVAL_METHOD begäran eller en IOCTL_ACPI_EVAL_METHOD_EX begäran till enheten. Den allmänna proceduren för att använda båda dessa begäranden beskrivs i Utvärdera ACPI-kontrollmetoder synkront. Den specifika skillnaden mellan att använda dessa två begäranden är följande:

  • Om kontrollmetoden är ett omedelbart underordnat objekt för enheten skickar drivrutinen en IOCTL_ACPI_EVAL_METHOD begäran och tillhandahåller en ACPI_EVAL_INPUT_BUFFER indatastruktur.

  • Om kontrollmetoden är ett underordnat objekt i ACPI-namnområdet för enheten, men inte är ett omedelbart underordnat objekt för enheten, skickar drivrutinen en IOCTL_ACPI_EVAL_METHOD_EX begäran och tillhandahåller en ACPI_EVAL_INPUT_BUFFER_EX struktur.

Exempelfunktionen GetAbcData som finns i det här avsnittet visar hur en drivrutin för en enhet kan använda en IOCTL_ACPI_EVAL_METHOD begäran för att utvärdera en kontrollmetod med namnet "ABCD" som enheten stöder. Kontrollmetoden "ABCD" är direkt underordnad enheten i ACPI-namnområdet och tar inte emot indataargument och returnerar inte utdataargument.

Om kontrollmetoden "ABCD" inte var ett omedelbart underordnat objekt är de nödvändiga ändringarna i den här exempelkoden följande:

  • Skicka en IOCTL_ACPI_EVAL_METHOD_EX begäran i stället för en IOCTL_ACPI_EVAL_METHOD begäran.

  • Ange en ACPI_EVAL_INPUT_BUFFER_EX struktur i stället för en ACPI_EVAL_INPUT_BUFFER struktur.

GetAbcData allokerar först en ACPI_EVAL_INPUT_BUFFER-struktur inputBuffer och ställer in MethodNameAsUlong-medlemmen till namnet på kontrollmetoden och ställer in Signatur-medlemmen till ACPI_EVAL_INPUT_BUFFER_SIGNATURE.

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

GetAbcData allokerar också en ACPI_EVAL_OUTPUT_BUFFER struktur outputBuffer, men angiver inte någon av medlemmarna i outputBuffer.

GetAbcData anropar sedan en funktion som tillhandahålls av drivrutinen med namnet SendDownStreamIrp som utför följande:

  1. Anropar IoBuildDeviceIoControlRequest för att skapa begäran.

  2. Anropar IoCallDriver för att skicka begäran nedåt i enhetsstacken.

  3. Väntar på att I/O-hanteraren ska signalera drivrutinerna att de underordnade drivrutinerna har slutfört begäran.

SendDownStreamIrp returnerar efter att I/O-hanteraren signalerat att drivrutinerna på lägre nivå har slutfört begäran. Kodexemplet som nämndes tidigare utför sedan följande:

  1. Kontrollerar statusen för begäran och återgår utan ytterligare bearbetning om underliggande mjukvarudrivrutiner inte returnerade STATUS_SUCCESS.

  2. Kontrollerar giltigheten för utdataargumenten. För att outputBuffer ska innehålla giltiga utdata måste Signatur anges till ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE och Antal måste anges till större än noll.

  3. Bearbetar de utdataargument som ACPI-drivrutinen skickade tillbaka till drivrutinen.

Även om det här steget inte ingår i exempelkoden bör drivrutinen även anropa IoCompleteRequest efter att ha bearbetat utdata för att slutföra den väntande IOCTL_ACPI_EVAL_METHOD begäran eller IOCTL_ACPI_EVAL_METHOD begäran som drivrutinen skickade för att utvärdera en kontrollmetod.

DE ACPI-datastrukturer och konstanter som används i följande exempel definieras i 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;
}