Compartilhar via


Avaliando um método de controle que usa argumentos de entrada

Para avaliar de forma síncrona um método de controle que usa argumentos de entrada, um driver para um dispositivo envia uma solicitação IOCTL_ACPI_EVAL_METHOD ou uma solicitação de IOCTL_ACPI_EVAL_METHOD_EX para o dispositivo. O procedimento geral para usar essas duas solicitações é descrito em Avaliando métodos de controle ACPI de forma síncrona. A diferença específica entre o uso dessas duas solicitações é a seguinte:

A função EvaluateABCDWithInputArgument de exemplo fornecida neste tópico mostra como um driver pode usar uma solicitação IOCTL_ACPI_EVAL_METHOD para avaliar um método de controle chamado 'ABCD' que usa um único argumento de entrada inteiro.

Se o argumento de entrada fosse uma cadeia de caracteres ou uma matriz de dados personalizados em vez de um inteiro, a alteração necessária para o código de exemplo será fornecer uma estrutura de entrada de cadeia de caracteres ou uma estrutura de entrada complexa em vez de uma estrutura de entrada de inteiro.

Além disso, se o método de controle 'ABCD' não for um objeto filho imediato, as alterações necessárias no código de exemplo serão as seguintes:

  • Envie uma solicitação de IOCTL_ACPI_EVAL_METHOD_EX em vez de uma solicitação de IOCTL_ACPI_EVAL_METHOD.

  • Forneça o tipo de estrutura de entrada estendida que corresponde ao tipo de argumento de entrada (inteiro simples, cadeia de caracteres simples ou complexo).

EvaluateABCDWithInputArgument primeiro aloca um ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER inputBuffer da estrutura e, em seguida, define o membro MethodNameAsUlong como o nome do método de controle, define o membro IntegerArgument como o valor inteiro de entrada e define o membro Signature como 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 também aloca um ACPI_EVAL_OUTPUT_BUFFERestrutura outputBuffer, mas não define nenhum dos membros do outputBuffer.

EvaluateABCDWithInputArgument chama uma função fornecida pelo driver chamada SendDownStreamIrp que executa o seguinte:

  1. Chama IoBuildDeviceIoControlRequest para compilar a solicitação.

  2. Chama IoCallDriver para enviar a solicitação para baixo na pilha do dispositivo.

  3. Aguarda o gerente de E/S sinalizar ao driver que os drivers de nível inferior concluíram a solicitação.

SendDownStreamIrp retorna depois que o gerente de E/S sinaliza que os drivers de nível inferior concluíram a solicitação.

Embora não esteja incluído em EvaluateABCDWithInputArgument, o driver também deve executar as seguintes operações adicionais depois que SendDownStreamIrp retornar:

  1. Verifique o status que SendDownStreamIrp retorna. Se SendDownStreamIrp não retornar STATUS_SUCCESS, o driver deverá retornar sem processamento adicional.

  2. Verifique a validade dos parâmetros de saída. Para que o outputBuffer contenha dados de saída válidos, a assinatura deve ser definida como ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE e Count deve ser definida como maior que zero.

  3. Processe os parâmetros de saída que foram passados de volta para o driver.

  4. Chame IoCompleteRequest para concluir a solicitação de IOCTL_ACPI_EVAL_METHOD.

As estruturas de dados e as constantes de ACPI usadas no exemplo a seguir são definidas em 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;
}