Partager via


Évaluation d’une méthode de contrôle sans arguments d’entrée

Pour évaluer de manière synchrone une méthode de contrôle qui ne prend pas d’arguments d’entrée, un pilote pour un appareil envoie une demande de IOCTL_ACPI_EVAL_METHOD ou une demande de IOCTL_ACPI_EVAL_METHOD_EX à l’appareil. La procédure générale d’utilisation de ces deux requêtes est décrite dans Évaluation synchrone des méthodes de contrôle ACPI. La différence spécifique entre l’utilisation de ces deux requêtes est la suivante :

  • Si la méthode de contrôle est un objet enfant immédiat du périphérique, le pilote envoie une requête IOCTL_ACPI_EVAL_METHOD et fournit une structure d’entrée ACPI_EVAL_INPUT_BUFFER .

  • Si la méthode de contrôle est un objet enfant dans l’espace de noms ACPI de l’appareil, mais n’est pas un objet enfant immédiat de l’appareil, le pilote envoie une requête IOCTL_ACPI_EVAL_METHOD_EX et fournit une structure ACPI_EVAL_INPUT_BUFFER_EX .

L’exemple de fonction GetAbcData fourni dans cette rubrique montre comment un pilote pour un appareil peut utiliser une demande de IOCTL_ACPI_EVAL_METHOD pour évaluer une méthode de contrôle nommée « ABCD » prise en charge par l’appareil. La méthode de contrôle « ABCD » est un enfant immédiat de l’appareil dans l’espace de noms ACPI et ne prend pas d’arguments d’entrée ou ne retourne pas d’arguments de sortie.

Si la méthode de contrôle « ABCD » n’était pas un objet enfant immédiat, les modifications requises pour cet exemple de code sont les suivantes :

  • Envoyez une demande IOCTL_ACPI_EVAL_METHOD_EX au lieu d’une demande de IOCTL_ACPI_EVAL_METHOD.

  • Fournissez une structure ACPI_EVAL_INPUT_BUFFER_EX au lieu d’une structure de ACPI_EVAL_INPUT_BUFFER.

GetAbcData alloue d’abord un ACPI_EVAL_INPUT_BUFFER structure inputBuffer et définit le membre MethodNameAsUlong sur le nom de la méthode de contrôle et définit le membre Signature sur ACPI_EVAL_INPUT_BUFFER_SIGNATURE.

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

GetAbcData alloue également un ACPI_EVAL_OUTPUT_BUFFER structure outputBuffer, mais ne définit aucun des membres de outputBuffer.

GetAbcData appelle ensuite une fonction fournie par le pilote nommée SendDownStreamIrp qui effectue les opérations suivantes :

  1. Appelle IoBuildDeviceIoControlRequest pour générer la requête.

  2. Appelle IoCallDriver pour envoyer la demande dans la pile de l’appareil.

  3. Attend que le gestionnaire d’E/S signale au pilote que les pilotes de niveau inférieur ont terminé la demande.

SendDownStreamIrp retourne une fois que le gestionnaire d’E/S signale que les pilotes de niveau inférieur ont terminé la demande. L’exemple de code mentionné précédemment effectue les opérations suivantes :

  1. Vérifie la status de la demande et retourne sans traitement supplémentaire si les pilotes de niveau inférieur n’ont pas retourné STATUS_SUCCESS.

  2. Vérifie la validité des arguments de sortie. Pour que l’objet outputBuffer contienne des données de sortie valides, Signature doit être défini sur ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE et Count doit être défini sur supérieur à zéro.

  3. Traite les arguments de sortie que le pilote ACPI a repassés au pilote.

Bien que cette étape ne soit pas incluse dans l’exemple de code, le pilote doit également appeler IoCompleteRequest après avoir traité les données de sortie pour terminer la demande de IOCTL_ACPI_EVAL_METHOD en attente ou IOCTL_ACPI_EVAL_METHOD demande que le pilote a envoyée pour évaluer une méthode de contrôle.

Les structures et constantes de données ACPI utilisées dans l’exemple suivant sont définies dans 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;
}