Compartir a través de


Evaluación de un método de control que toma argumentos de entrada

Para evaluar de forma sincrónica un método de control que toma argumentos de entrada, un controlador de un dispositivo envía una solicitud de IOCTL_ACPI_EVAL_METHOD o una solicitud de IOCTL_ACPI_EVAL_METHOD_EX al dispositivo. El procedimiento general para usar ambas solicitudes se describe en Evaluación de métodos de control ACPI de forma sincrónica. La diferencia específica entre el uso de estas dos solicitudes es la siguiente:

En el ejemplo , la función EvaluateABCDWithInputArgument que se proporciona en este tema muestra cómo un controlador puede usar una solicitud de IOCTL_ACPI_EVAL_METHOD para evaluar un método de control denominado "ABCD" que toma un único argumento de entrada entero.

Si el argumento de entrada era una cadena o una matriz de datos personalizados en lugar de un entero, el cambio necesario en el código de ejemplo es proporcionar una estructura de entrada de cadena o una estructura de entrada compleja en lugar de una estructura de entrada entera.

Además, si el método de control "ABCD" no era un objeto secundario inmediato, los cambios necesarios en el código de ejemplo son los siguientes:

  • Envíe una solicitud de IOCTL_ACPI_EVAL_METHOD_EX en lugar de una solicitud de IOCTL_ACPI_EVAL_METHOD.

  • Proporcione el tipo de estructura de entrada extendida que corresponde al tipo de argumento de entrada (entero simple, cadena simple o complejo).

EvaluateABCDWithInputArgument asigna primero una estructura de ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER inputBuffer y, a continuación, establece el miembro MethodNameAsUlong en el nombre del método de control, establece el miembro IntegerArgument en el valor entero de entrada y establece el miembro Signature en 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 también asigna una estructura ACPI_EVAL_OUTPUT_BUFFERoutputBuffer, pero no establece ninguno de los miembros de outputBuffer.

EvaluateABCDWithInputArgument llama a una función proporcionada por el controlador denominada SendDownStreamIrp que realiza lo siguiente:

  1. Llama a IoBuildDeviceIoControlRequest para compilar la solicitud.

  2. Llama a IoCallDriver para enviar la solicitud a la pila del dispositivo.

  3. Espera a que el administrador de E/S indique al controlador que los controladores de nivel inferior han completado la solicitud.

SendDownStreamIrp devuelve después de que el administrador de E/S indique que los controladores de nivel inferior han completado la solicitud.

Aunque no se incluye en EvaluateABCDWithInputArgument, el controlador también debe realizar las siguientes operaciones adicionales después de que SendDownStreamIrp devuelva:

  1. Compruebe el estado que devuelve SendDownStreamIrp . Si SendDownStreamIrp no devuelve STATUS_SUCCESS, el controlador debe devolver sin procesamiento adicional.

  2. Compruebe la validez de los parámetros de salida. Para que outputBuffer contenga datos de salida válidos, Signature debe establecerse en ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE y Count debe establecerse en mayor que cero.

  3. Procese los parámetros de salida que se han pasado al controlador.

  4. Llame a IoCompleteRequest para completar la solicitud de IOCTL_ACPI_EVAL_METHOD.

Las estructuras y constantes de datos ACPI usadas en el ejemplo siguiente se definen en 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;
}