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:
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 de las siguientes estructuras de entrada: ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER, ACPI_EVAL_INPUT_BUFFER_SIMPLE_STRING o ACPI_EVAL_INPUT_BUFFER_COMPLEX.
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 de las siguientes estructuras de entrada: ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER_EX, ACPI_EVAL_INPUT_BUFFER_SIMPLE_STRING_EX, o ACPI_EVAL_INPUT_BUFFER_COMPLEX_EX.
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:
Llama a IoBuildDeviceIoControlRequest para compilar la solicitud.
Llama a IoCallDriver para enviar la solicitud a la pila del dispositivo.
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:
Compruebe el estado que devuelve SendDownStreamIrp . Si SendDownStreamIrp no devuelve STATUS_SUCCESS, el controlador debe devolver sin procesamiento adicional.
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.
Procese los parámetros de salida que se han pasado al controlador.
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;
}