Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Чтобы синхронно оценить метод управления, который не принимает входные аргументы, драйвер для устройства отправляет запрос IOCTL_ACPI_EVAL_METHOD или запрос IOCTL_ACPI_EVAL_METHOD_EX на устройство. Общая процедура использования обоих запросов описана в статье "Оценка методов управления ACPI синхронно". Конкретная разница между использованием этих двух запросов выглядит следующим образом:
Если метод управления является непосредственным дочерним объектом устройства, драйвер отправляет запрос IOCTL_ACPI_EVAL_METHOD и предоставляет ACPI_EVAL_INPUT_BUFFER входную структуру.
Если метод управления является дочерним объектом в пространстве имен ACPI устройства, но не является непосредственным дочерним объектом устройства, драйвер отправляет запрос IOCTL_ACPI_EVAL_METHOD_EX и предоставляет структуру ACPI_EVAL_INPUT_BUFFER_EX .
В примере функции GetAbcData , предоставленной в этом разделе, показано, как драйвер для устройства может использовать запрос IOCTL_ACPI_EVAL_METHOD для оценки метода управления с именем ABCD, который поддерживает устройство. Метод управления ABCD является непосредственным дочерним элементом устройства в пространстве имен ACPI и не принимает входные аргументы или возвращает выходные аргументы.
Если метод управления ABCD не был непосредственным дочерним объектом, необходимые изменения в этом примере кода приведены следующим образом:
Отправьте запрос IOCTL_ACPI_EVAL_METHOD_EX вместо запроса IOCTL_ACPI_EVAL_METHOD.
Укажите структуру ACPI_EVAL_INPUT_BUFFER_EX вместо структуры ACPI_EVAL_INPUT_BUFFER.
GetAbcData сначала выделяет структуру inputBuffer типа ACPI_EVAL_INPUT_BUFFER и устанавливает элемент MethodNameAsUlong в имя метода управления, а элемент Signature в ACPI_EVAL_INPUT_BUFFER_SIGNATURE.
// Fill in the input data
inputBuffer.MethodNameAsUlong = (ULONG) ('DCBA');
inputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
GetAbcData также выделяет структуру ACPI_EVAL_OUTPUT_BUFFERoutputBuffer, но не задает ни одного из элементов outputBuffer.
Затем GetAbcData вызывает предоставленную драйвером функцию с именем SendDownStreamIrp , которая выполняет следующие действия:
Вызывает IoBuildDeviceIoControlRequest для создания запроса.
Вызывает IoCallDriver, чтобы отправить запрос вниз по стеку устройств.
Ожидает, пока диспетчер ввода-вывода сигнализирует драйверу о том, что драйверы нижнего уровня завершили запрос.
SendDownStreamIrp возвращается после того, как диспетчер ввода-вывода сигнализирует о том, что драйверы нижнего уровня завершили запрос. Приведенный ранее пример кода выполняет следующие действия:
Проверяет состояние запроса и возвращает без дополнительной обработки, если драйверы нижнего уровня не возвращали STATUS_SUCCESS.
Проверяет допустимость выходных аргументов. Чтобы outputBuffer содержал допустимые выходные данные, Signature должна быть установлена в ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE, а Count должен быть больше нуля.
Обрабатывает выходные аргументы, которые драйвер ACPI передал обратно драйверу.
Хотя этот шаг не включен в пример кода, драйвер также должен вызвать IoCompleteRequest после обработки выходных данных, чтобы завершить ожидающий запрос IOCTL_ACPI_EVAL_METHOD или IOCTL_ACPI_EVAL_METHOD запрос, который драйвер отправил для оценки метода управления.
Структуры и константы данных ACPI, используемые в следующем примере, определяются в 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;
}