Оценка метода управления, принимающего входные аргументы
Чтобы синхронно оценить метод управления, который принимает входные аргументы, драйвер устройства отправляет на устройство запрос IOCTL_ACPI_EVAL_METHOD или запрос IOCTL_ACPI_EVAL_METHOD_EX . Общая процедура использования обоих этих запросов описана в статье Синхронная оценка методов управления ACPI. Ниже приведена конкретная разница между использованием этих двух запросов.
Если метод управления является непосредственным дочерним объектом устройства, драйвер отправляет запрос IOCTL_ACPI_EVAL_METHOD и предоставляет одну из следующих входных структур: ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER, ACPI_EVAL_INPUT_BUFFER_SIMPLE_STRING или ACPI_EVAL_INPUT_BUFFER_COMPLEX.
Если метод управления является дочерним объектом в пространстве имен ACPI устройства, но не является непосредственным дочерним объектом устройства, драйвер отправляет запрос IOCTL_ACPI_EVAL_METHOD_EX и предоставляет одну из следующих входных структур: ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER_EX, ACPI_EVAL_INPUT_BUFFER_SIMPLE_STRING_EX. или ACPI_EVAL_INPUT_BUFFER_COMPLEX_EX.
В примере функции EvaluateABCDWithInputArgument , приведенной в этом разделе, показано, как драйвер может использовать IOCTL_ACPI_EVAL_METHOD запрос для вычисления метода управления с именем "ABCD", который принимает один целочисленный входной аргумент.
Если входной аргумент был строкой или массивом пользовательских данных, а не целым числом, необходимо изменить пример кода, указав строковую входную структуру или сложную входную структуру вместо целочисленной входной структуры.
Кроме того, если метод элемента управления "ABCD" не был непосредственным дочерним объектом, необходимые изменения в примере кода будут следующими:
Отправьте запрос IOCTL_ACPI_EVAL_METHOD_EX вместо запроса IOCTL_ACPI_EVAL_METHOD.
Укажите тип расширенной входной структуры, соответствующий типу входного аргумента (простое целое число, простая строка или сложный).
EvaluateABCDWithInputArgument сначала выделяет ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER структуру inputBuffer , а затем задает для элемента MethodNameAsUlong имя метода элемента управления, задает для элемента IntegerArgument значение входного целого числа и задает для элемента Signature значение 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 также выделяет ACPI_EVAL_OUTPUT_BUFFER структуру outputBuffer, но не задает ни один из членов outputBuffer.
Затем EvaluateABCDWithInputArgument вызывает предоставленную драйвером функцию с именем SendDownStreamIrp , которая выполняет следующие действия:
Вызывает IoBuildDeviceIoControlRequest для построения запроса.
Вызывает IoCallDriver для отправки запроса в стеке устройств.
Ожидает, пока диспетчер ввода-вывода сообщит драйверу о том, что драйверы нижнего уровня выполнили запрос.
SendDownStreamIrp возвращается после того, как диспетчер ввода-вывода сообщит о том, что драйверы нижнего уровня выполнили запрос.
Несмотря на то, что драйвер не включен в EvaluateABCDWithInputArgument, он также должен выполнять следующие дополнительные операции после возврата SendDownStreamIrp :
Проверьте состояние, которое возвращает SendDownStreamIrp . Если SendDownStreamIrp не возвращает STATUS_SUCCESS, драйвер должен вернуться без дополнительной обработки.
Проверьте допустимость выходных параметров. Чтобы outputBuffer содержал допустимые выходные данные, параметру Signature должно быть присвоено значение ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE а параметру Count — значение больше нуля.
Обработайте выходные параметры, которые были переданы драйверу.
Вызовите IoCompleteRequest для выполнения запроса IOCTL_ACPI_EVAL_METHOD.
Структуры данных и константы ACPI, используемые в следующем примере, определяются в 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;
}