Share via


Évaluation d’une méthode de contrôle qui prend des arguments d’entrée

Pour évaluer de manière synchrone une méthode de contrôle qui prend des arguments d’entrée, un pilote pour un appareil envoie une demande de IOCTL_ACPI_EVAL_METHOD ou une requête IOCTL_ACPI_EVAL_METHOD_EX à l’appareil. La procédure générale d’utilisation de ces deux demandes 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 :

L’exemple de fonction EvaluateABCDWithInputArgument fourni dans cette rubrique montre comment un pilote peut utiliser une requête de IOCTL_ACPI_EVAL_METHOD pour évaluer une méthode de contrôle nommée « ABCD » qui prend un argument d’entrée entier unique.

Si l’argument d’entrée était une chaîne ou un tableau de données personnalisées au lieu d’un entier, la modification requise de l’exemple de code consiste à fournir une structure d’entrée de chaîne ou une structure d’entrée complexe au lieu d’une structure d’entrée entière.

En outre, si la méthode de contrôle « ABCD » n’était pas un objet enfant immédiat, les modifications requises apportées à l’exemple de code sont les suivantes :

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

  • Fournissez le type de structure d’entrée étendue qui correspond au type d’argument d’entrée (entier simple, chaîne simple ou complexe).

EvaluateABCDWithInputArgument alloue d’abord une ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER structure inputBuffer , puis définit le membre MethodNameAsUlong sur le nom de la méthode de contrôle, définit le membre IntegerArgument sur la valeur entière d’entrée et définit le membre Signature sur ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER_SIGNATURE.

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

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

EvaluateABCDWithInputArgument 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 des appareils.

  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.

Bien qu’il ne soit pas inclus dans EvaluateABCDWithInputArgument, le pilote doit également effectuer les opérations supplémentaires suivantes après le retour de SendDownStreamIrp :

  1. Vérifiez le status retourné par SendDownStreamIrp. Si SendDownStreamIrp ne retourne pas STATUS_SUCCESS, le pilote doit retourner sans traitement supplémentaire.

  2. Vérifiez la validité des paramètres de sortie. Pour que le 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. Traitez les paramètres de sortie qui ont été renvoyés au pilote.

  4. Appelez IoCompleteRequest pour terminer la demande de IOCTL_ACPI_EVAL_METHOD.

Les structures et constantes de données ACPI utilisées dans l’exemple suivant sont définies dans Acpiioct.h.

NTSTATUS
EvaluateABCDWithInputArgument(
    IN PDEVICE_OBJECT   Pdo,
    IN ULONG            Argument1,
    OUT PULONG          ReturnStatus
    )
/*
Routine Description:
    Called to evaluate the example 'ABCD' method with a single integer input argument

Parameters:
    Pdo             - For the device.
    Argument1       - Input argument.
    ReturnStatus    - Pointer to where the status data is placed.

Return Value:
    NT Status of the operation
*/
{
 ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER  inputBuffer;
    ACPI_EVAL_OUTPUT_BUFFER                outputBuffer; 
    NTSTATUS                               status;
    PACPI_METHOD_ARGUMENT                  argument;

    .
    .
    // Omitted: bounds checking on Argument1 value.


    ASSERT( ReturnStatus != NULL );
    *ReturnStatus = 0x0;

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

    // Send the request along
    status = SendDownStreamIrp(
       Pdo,
       IOCTL_ACPI_EVAL_METHOD,
       &inputBuffer,
       sizeof(ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER),
       &outputBuffer,
       sizeof(ACPI_EVAL_OUTPUT_BUFFER)
       );

    return status;
}