Compartir a través de


Evaluación de un método de control sin argumentos de entrada

Para evaluar de forma sincrónica un método de control que no toma argumentos de entrada, un controlador para 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:

  • Si el método de control es un objeto secundario inmediato del dispositivo, el controlador envía una solicitud de IOCTL_ACPI_EVAL_METHOD y proporciona una estructura de entrada ACPI_EVAL_INPUT_BUFFER .

  • Si el método de control es un objeto secundario en el espacio de nombres ACPI del dispositivo, pero no es un objeto secundario inmediato del dispositivo, el controlador envía una solicitud de IOCTL_ACPI_EVAL_METHOD_EX y proporciona una estructura ACPI_EVAL_INPUT_BUFFER_EX .

La función GetAbcData de ejemplo que se proporciona en este tema muestra cómo un controlador de un dispositivo puede usar una solicitud de IOCTL_ACPI_EVAL_METHOD para evaluar un método de control denominado "ABCD" que admite el dispositivo. El método de control 'ABCD' es un elemento secundario inmediato del dispositivo en el espacio de nombres ACPI y no toma argumentos de entrada ni devuelve argumentos de salida.

Si el método de control "ABCD" no era un objeto secundario inmediato, los cambios necesarios en este 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 una estructura de ACPI_EVAL_INPUT_BUFFER_EX en lugar de una estructura de ACPI_EVAL_INPUT_BUFFER.

GetAbcData asigna primero un ACPI_EVAL_INPUT_BUFFER estructura inputBuffer y establece el miembro MethodNameAsUlong en el nombre del método de control y establece el miembro Signature en ACPI_EVAL_INPUT_BUFFER_SIGNATURE.

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

GetAbcData también asigna una estructura ACPI_EVAL_OUTPUT_BUFFERoutputBuffer, pero no establece ninguno de los miembros de outputBuffer.

GetAbcData 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 completaron la solicitud.

SendDownStreamIrp devuelve después de que el administrador de E/S indique que los controladores de nivel inferior han completado la solicitud. El ejemplo de código mencionado anteriormente realiza lo siguiente:

  1. Comprueba el estado de la solicitud y devuelve sin procesamiento adicional si los controladores de nivel inferior no devolvieron STATUS_SUCCESS.

  2. Comprueba la validez de los argumentos 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. Procesa los argumentos de salida que el controlador ACPI ha devuelto al controlador.

Aunque este paso no se incluye en el código de ejemplo, el controlador también debe llamar a IoCompleteRequest después de procesar los datos de salida para completar la solicitud de IOCTL_ACPI_EVAL_METHOD pendiente o IOCTL_ACPI_EVAL_METHOD solicitud que el controlador envió para evaluar un método de control.

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