DXGKCB_EVAL_ACPI_METHOD回调函数 (dispmprt.h)
DxgkCbEvalAcpiMethod 函数在显示适配器或显示适配器的子设备上评估指定的 ACPI 方法。
语法
DXGKCB_EVAL_ACPI_METHOD DxgkcbEvalAcpiMethod;
NTSTATUS DxgkcbEvalAcpiMethod(
[in] HANDLE DeviceHandle,
[in] ULONG DeviceUid,
[in] PACPI_EVAL_INPUT_BUFFER_COMPLEX AcpiInputBuffer,
[in] ULONG AcpiInputSize,
[out] PACPI_EVAL_OUTPUT_BUFFER AcpiOutputBuffer,
[in] ULONG AcpiOutputSize
)
{...}
参数
[in] DeviceHandle
表示显示适配器的句柄。 显示微型端口驱动程序以前在 传递给 dxgkDdiStartDevice的 DXGKRNL_INTERFACE 结构的 DeviceHandle 成员中获取此句柄。
[in] DeviceUid
将对其计算方法的 ACPI 设备的唯一标识符。 如果 ACPI 设备是显示适配器的子级,则这是显示微型端口驱动程序在 DxgkDdiQueryChildRelations期间填充的 DXGK_CHILD_DESCRIPTOR 结构的 ChildUid 成员。 如果 ACPI 设备是显示适配器本身,则必须将此参数设置为DISPLAY_ADAPTER_HW_ID。
[in] AcpiInputBuffer
指向 ACPI_EVAL_INPUT_BUFFER_COMPLEX 结构的指针(在 Acpiioct.h中定义)由显示微型端口驱动程序分配和填充。 该结构包含 ACPI 方法所需的参数。 有关详细信息,请参阅以下“备注”部分。
[in] AcpiInputSize
AcpiInputBuffer指向的缓冲区的总大小(以字节为单位)。
[out] AcpiOutputBuffer
指向接收 ACPI 方法返回值的ACPI_EVAL_OUTPUT_BUFFER结构的指针(在 Acpiioct.h中定义)。 此参数可以 NULL。
[in] AcpiOutputSize
AcpiOutputBuffer指向的缓冲区的总大小(以字节为单位)。
返回值
DxgkCbEvalAcpiMethod 如果成功,则返回STATUS_SUCCESS。 否则,它将返回 Ntstatus.h中定义的错误代码之一。
言论
若要评估 ACPI 设备上的 ACPI 方法,设备本身必须位于 ACPI 命名空间中。 此外,显示微型端口驱动程序必须为显示微型端口驱动程序向 ACPI 报告的标识符报告的任何 ACPI 子设备的 ChildUid 值设置较低的 16 位。
在返回之前,DxgkCbEvalAcpiMethod 将 ACPI_EVAL_INPUT_BUFFER_COMPLEX 结构的 签名 成员重置为ACPI_EVAL_INPUT_BUFFER_COMPLEX_SIGNATURE。 在具有 Service Pack 1(SP1)、Windows Server 2008 及更高版本的 Windows作系统的 Windows Vista 中,如果显示微型端口驱动程序具有子设备,则它应在调用 DxgkCbEvalAcpiMethod 之前将签名 设置为DXGK_ACPI_PASS_ARGS_TO_CHILDREN。
例子
下面的代码示例演示如何评估 ACPI 方法。
if (HwDeviceExtension->AcpiChildren != NULL) {
ULONG ChildIndex;
PACPI_METHOD_ARGUMENT AcpiChildrenArray =
&(((PACPI_EVAL_OUTPUT_BUFFER)HwDeviceExtension->AcpiChildren)
->Argument[0]);
ULONG ChildCount = ((PACPI_EVAL_OUTPUT_BUFFER)
(HwDeviceExtension->AcpiChildren))->Count;
ULONG ChildUid;
ACPI_EVAL_INPUT_BUFFER_COMPLEX AcpiInputBuffer = {'\0'};
ACPI_EVAL_OUTPUT_BUFFER AcpiOutputBuffer;
pDesiredStatus = ExAllocatePoolWithTag(PagedPool,
sizeof(DESIRED_CHILD_STATUS) * ChildCount,
ATI_TAG);
if (pDesiredStatus == NULL) {
Status = STATUS_NO_MEMORY;
goto cleanup;
}
RtlZeroMemory(pDesiredStatus, sizeof(DESIRED_CHILD_STATUS) * ChildCount);
for (ChildIndex = 0; ChildIndex < ChildCount; ChildIndex++) {
// If not a video output child, go to the next child.
if (AcpiChildrenArray[ChildIndex].Argument
& ACPI_NON_VIDEO_OUTPUT_DEVICE) {
continue;
}
// A video output child so the ChildUid is the VidPnTargetId.
ChildUid = (AcpiChildrenArray[ChildIndex].Argument
& ACPI_HARDWARE_ID) | HW_ID_DISPLAY_CHILD;
// Query ACPI for the required state.
//
// Beginning with Windows Vista SP1 and Windows Server 2008,
// use DXGK_ACPI_PASS_ARGS_TO_CHILDREN.
#if (NTDDI_VERSION >= NTDDI_WIN6SP1)
AcpiInputBuffer.Signature =
DXGK_ACPI_PASS_ARGS_TO_CHILDREN;
#else
AcpiInputBuffer.Signature =
ACPI_EVAL_INPUT_BUFFER_COMPLEX_SIGNATURE;
#endif
AcpiInputBuffer.MethodNameAsUlong =
ACPI_METHOD_OUTPUT_DGS;
Status = DxgkCbEvalAcpiMethod(HwDeviceExtension->DeviceHandle,
ChildUid,
&AcpiInputBuffer,
sizeof(ACPI_EVAL_INPUT_BUFFER_COMPLEX),
&AcpiOutputBuffer,
sizeof(ACPI_EVAL_OUTPUT_BUFFER));
if (!NT_SUCCESS(Status)) {
// Something really wrong
goto cleanup;
}
// Determine what the new VidPn should be and
// allow RecommendFunctionalVidPn to return it.
// AcpiOutputBuffer.Argument[0].Argument == 1 indicates active
// AcpiOutputBuffer.Argument[0].Argument == 0
// indicates not active
pDesiredStatus[ChildIndex].bActive =
(AcpiOutputBuffer.Argument[0].Argument == 1) ? TRUE : FALSE;
// Always use the first source because this is a keyboard shortcut.
pDesiredStatus[ChildIndex].ulSourceId = 0;
pDesiredStatus[ChildIndex].ulTargetId = ChildUid;
}
Status = InvalidateVidPnForHotKey(HwDeviceExtension, pDesiredStatus);
}
要求
要求 | 价值 |
---|---|
最低支持的客户端 | Windows Vista |
目标平台 | 桌面 |
标头 | dispmprt.h (包括 Dispmprt.h) |
IRQL | PASSIVE_LEVEL |