입력 인수 없이 컨트롤 메서드 평가

입력 인수를 사용하지 않는 제어 메서드를 동기적으로 평가하기 위해 디바이스의 드라이버는 디바이스에 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 요청 대신 IOCTL_ACPI_EVAL_METHOD_EX 요청을 보냅니다.

  • ACPI_EVAL_INPUT_BUFFER 구조 대신 ACPI_EVAL_INPUT_BUFFER_EX 구조를 입력합니다.

GetAbcData 는 먼저 ACPI_EVAL_INPUT_BUFFER 구조 체 inputBuffer 를 할당하고 MethodNameAsUlong 멤버를 컨트롤 메서드의 이름으로 설정하고 Signature 멤버를 ACPI_EVAL_INPUT_BUFFER_SIGNATURE 설정합니다.

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

또한 GetAbcDataACPI_EVAL_OUTPUT_BUFFER 구조 출력 버퍼를 할당하지만 outputBuffer의 멤버는 설정하지 않습니다.

그런 다음 GetAbcData 는 다음을 수행하는 SendDownStreamIrp 라는 드라이버 제공 함수를 호출합니다.

  1. IoBuildDeviceIoControlRequest를 호출하여 요청을 빌드합니다.

  2. IoCallDriver를 호출하여 디바이스 스택 아래로 요청을 보냅니다.

  3. I/O 관리자가 하위 수준 드라이버가 요청을 완료했음을 드라이버에 알릴 때까지 기다립니다.

SendDownStreamIrp 은 I/O 관리자가 하위 수준 드라이버가 요청을 완료했음을 알린 후 를 반환합니다. 앞에서 언급한 코드 예제는 다음을 수행합니다.

  1. 요청의 상태 확인하고 하위 수준 드라이버가 STATUS_SUCCESS 반환하지 않은 경우 추가 처리 없이 를 반환합니다.

  2. 출력 인수의 유효성을 확인합니다. outputBuffer가 유효한 출력 데이터를 포함하려면 서명을 ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE 설정해야 하며 Count는 0보다 커야 합니다.

  3. 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;
}