WDDM 子设备关状态
2021-06-30
288
0
WDDM中使用来DxgkDdiQueryChildStatus查询子设备的状态
InitialData.DxgkDdiQueryChildStatus = BddDdiQueryChildStatus;
和其它的回调函数一样,最终的处理函数其实是BASIC_DISPLAY_DRIVER的成员函数QueryChildStatus。
子设备的状态一般有连接状态、旋转状态和无线投屏三种,所以其分别对应不同的数据结构体。
在BddDdiQueryChildStatus的参数INOUT_PDXGK_CHILD_STATUS 结构体中,包含一个三个状态的公用体。
typedef struct _DXGK_CHILD_STATUS {
DXGK_CHILD_STATUS_TYPE Type;
ULONG ChildUid;
union {
struct {
BOOLEAN Connected;
} HotPlug;
struct {
UCHAR Angle;
} Rotation;
struct {
BOOLEAN Connected;
D3DKMDT_VIDEO_OUTPUT_TECHNOLOGY MiracastMonitorType;
} Miracast;
};
} DXGK_CHILD_STATUS, *PDXGK_CHILD_STATUS;
- ChildUid:ChildUid用于标识是获取那个设备。
- DXGK_CHILD_STATUS_TYPE:用于标识是查询什么类型的状态,这是一个枚举量,包含 三种类型:
typedef enum _DXGK_CHILD_STATUS_TYPE { StatusUninitialized, StatusConnection, StatusRotation, StatusMiracastConnection } DXGK_CHILD_STATUS_TYPE, *PDXGK_CHILD_STATUS_TYPE;
由于我们的子设备是TypeVideoOutput类型,并且不支持旋转,所以只支持设备插拔的状态。
无线投屏是WDDM1.3所支持的,这里我们不考虑。
最终代码如下:
NTSTATUS BASIC_DISPLAY_DRIVER::QueryChildStatus(_Inout_ DXGK_CHILD_STATUS* pChildStatus,
_In_ BOOLEAN NonDestructiveOnly)
{
PAGED_CODE();
UNREFERENCED_PARAMETER(NonDestructiveOnly);
BDD_ASSERT(pChildStatus != NULL);
BDD_ASSERT(pChildStatus->ChildUid < MAX_CHILDREN);
switch (pChildStatus->Type)
{
case StatusConnection:
{
// HpdAwarenessInterruptible was reported since HpdAwarenessNone is deprecated.
// However, BDD has no knowledge of HotPlug events, so just always return connected.
pChildStatus->HotPlug.Connected = IsDriverActive();
return STATUS_SUCCESS;
}
case StatusRotation:
{
// D3DKMDT_MOA_NONE was reported, so this should never be called
BDD_LOG_ERROR0("Child status being queried for StatusRotation even though D3DKMDT_MOA_NONE was reported");
return STATUS_INVALID_PARAMETER;
}
default:
{
BDD_LOG_WARNING1("Unknown pChildStatus->Type (0x%I64x) requested.", pChildStatus->Type);
return STATUS_NOT_SUPPORTED;
}
}
}