window显示驱动开发—内容保护的资源

以下 D3DDDI_RESOURCEFLAGS 标志由 Direct3D 运行时用于受保护内容。 运行时在D3DDDIARG_CREATERESOURCE结构的Flags 成员中设置这些 D3DDDI_RESOURCEFLAGS标志,当运行时调用 CreateResource 时,驱动程序的 CreateResource 函数的 pResource 参数指向这些标志。

RestrictedContent

资源可能包含受保护的内容。 在应用程序创建资源之前,应用程序可能已显式启用内容保护,也可能未显式启用内容保护。 驱动程序应确保运行时将资源的分配置于可以保护的内存池中。 驱动程序应允许创建可锁定的受保护资源。 但是,在启用内容保护时,驱动程序应显式失败对其 Lock 函数的调用以锁定这些图面。

RestrictSharedAccess

应仅允许特定进程访问共享资源。

驱动程序应限制对此资源的共享访问。 运行时只能调用驱动程序的 OpenResource 函数,以使用创建资源的进程中的显示设备 (hDevice) 打开此资源,或者由那些通过经过身份验证的通道显式授予访问权限的设备打开此资源。

1. 受保护资源标志处理

1.1 CreateResource 中的标志解析

复制代码
HRESULT APIENTRY CreateResource(
    D3DDDIARG_CREATERESOURCE* pResource)
{
    // 检查受保护内容标志
    const BOOL bProtected = pResource->Flags.RestrictedContent;
    const BOOL bRestrictShared = pResource->Flags.RestrictSharedAccess;
    
    // 验证标志组合有效性
    if (bRestrictShared && !bProtected) {
        return E_INVALIDARG; // 仅限制共享必须配合保护内容
    }
    
    // 分配受保护内存
    if (bProtected) {
        return CreateProtectedResource(pResource);
    }
    
    // 普通资源创建流程
    return CreateStandardResource(pResource);
}

2. 受保护资源创建实现

2.1 安全内存分配

复制代码
HRESULT CreateProtectedResource(D3DDDIARG_CREATERESOURCE* pResource)
{
    PROTECTED_RESOURCE_CTX* pCtx = new PROTECTED_RESOURCE_CTX;
    
    // 设置安全内存属性
    D3DKMT_ALLOCATIONPROPERTIES allocProps = {0};
    allocProps.Protected = TRUE;
    allocProps.RestrictSharedAccess = pResource->Flags.RestrictSharedAccess;
    
    // 调用KMD接口
    NTSTATUS status = D3DKMTCreateAllocation(
        &allocProps,
        &pCtx->hAllocation);
    
    if (!NT_SUCCESS(status)) {
        delete pCtx;
        return E_FAIL;
    }
    
    // 标记为可锁定但实际锁定会失败
    pCtx->bLockable = pResource->Flags.Dynamic;
    
    // 存储到资源表
    pResource->hResource = (HANDLE)pCtx;
    return S_OK;
}

3. 资源锁定保护机制

3.1 Lock 函数特殊处理

复制代码
HRESULT APIENTRY Lock(D3DDDIARG_LOCK* pLock)
{
    PROTECTED_RESOURCE_CTX* pCtx = 
        (PROTECTED_RESOURCE_CTX*)pLock->hResource;
    
    // 检查保护状态
    if (IsResourceProtected(pCtx)) {
        // 动态资源在未启用保护时可锁定
        if (pCtx->bLockable && !IsContentProtectionActive()) {
            return StandardLock(pLock);
        }
        return D3DDDIERR_LOCKEDPROTECTEDRESOURCE;
    }
    
    return StandardLock(pLock);
}

保护规则矩阵:

资源类型 RestrictedContent Lock行为
静态纹理 TRUE 始终失败
动态纹理 TRUE 保护激活时失败
任何缓冲区 FALSE 正常锁定

4. 共享访问控制

4.1 OpenResource 访问检查

复制代码
HRESULT APIENTRY OpenResource(
    D3DDDIARG_OPENRESOURCE* pOpenResource)
{
    PROTECTED_RESOURCE_CTX* pOriginal = 
        (PROTECTED_RESOURCE_CTX*)pOpenResource->hResource;
    
    // 检查共享限制
    if (pOriginal->Flags.RestrictSharedAccess) {
        // 验证调用进程权限
        if (!CheckAccessRights(
                pOpenResource->hDevice,
                pOriginal->hAllocation)) {
            return E_ACCESSDENIED;
        }
    }
    
    // 标准打开流程
    return StandardOpenResource(pOpenResource);
}

4.2 访问验证逻辑

复制代码
BOOL CheckAccessRights(
    HANDLE hDevice, 
    D3DKMT_HANDLE hAllocation)
{
    // 1. 检查是否同一进程
    if (IsCreatorProcess(hDevice, hAllocation))
        return TRUE;
    
    // 2. 检查认证通道授权
    if (HasAuthenticatedAccess(hDevice, hAllocation))
        return TRUE;
    
    return FALSE;
}

5. 安全架构设计

5.1 资源元数据结构

复制代码
typedef struct _PROTECTED_RESOURCE_CTX {
    D3DKMT_HANDLE hAllocation;      // 内核分配句柄
    D3DDDI_RESOURCEFLAGS Flags;      // 原始标志
    BOOL bLockable;                  // 动态资源标记
    SECURITY_DESCRIPTOR* pSD;        // 安全描述符(可选)
} PROTECTED_RESOURCE_CTX;

5.2 内存保护实现

6. 错误处理规范

错误码 触发条件
D3DDDIERR_LOCKEDPROTECTEDRESOURCE 尝试锁定受保护资源
E_ACCESSDENIED 非法共享访问尝试
E_INVALIDARG 无效的标志组合

7. 性能优化建议

保护内存池管理:

复制代码
class SecureMemoryPool {
public:
    void* Alloc(size_t size) {
        return VirtualAlloc(NULL, size, 
            MEM_RESERVE | MEM_COMMIT, 
            PAGE_READWRITE | PAGE_GUARD);
    }
};

批量资源创建:

复制代码
void CreateMultipleResources(
    D3DDDIARG_CREATERESOURCE* pResources, 
    UINT count)
{
    if (AllProtected(pResources, count)) {
        HW_BulkCreateSecureResources(pResources);
    }
}

8. 认证测试要求

WHQL测试项目:

  • 保护资源锁定负向测试
  • 跨进程共享测试
  • 标志组合有效性测试

安全测试用例:

复制代码
# 伪代码:尝试突破共享限制
def test_shared_violation():
    hRes = create_protected_resource()
    try:
        open_from_other_process(hRes)
        assert False # 应抛出访问拒绝
    except AccessDeniedError:
        pass

9. 向后兼容性

复制代码
#if (D3D_UMD_INTERFACE_VERSION >= D3D_UMD_INTERFACE_VERSION_WIN7)
    // 完整实现保护标志
#else
    // 忽略保护标志,仅记录警告
    if (pResource->Flags.RestrictedContent)
        DebugPrint("保护内容需要Win7+驱动模型");
#endif
相关推荐
fatfishccc5 小时前
(七)API 重构的艺术:打造优雅、可维护的 API
java·驱动开发·intellij-idea·软件研发·后端开发·代码重构·api重构
小狗爱吃黄桃罐头1 天前
正点原子【第四期】Linux之驱动开发学习笔记-6.1 pinctrl和gpio子系统
linux·驱动开发·学习
每天更新1 天前
linux驱动开发笔记
linux·驱动开发·笔记
sheepwjl2 天前
《嵌入式驱动(二):驱动开发基本概念》
arm开发·驱动开发·单片机·嵌入式硬件·imx6ull·驱动·裸机
fatfishccc2 天前
(四)优雅重构:洞悉“搬移特性”的艺术与实践
java·驱动开发·intellij-idea·软件研发·后端开发·代码重构·搬移
CoderBob2 天前
【easy_tools】一个跨平台裸机工具库,包含任务/堆栈/消息/定时器/日志等实现
c语言·驱动开发·单片机·嵌入式硬件
与你诗画3 天前
为什么单片机的外接晶振要并连两个电容?
c语言·驱动开发·单片机·嵌入式硬件·硬件架构·硬件工程
飞奔的猫3 天前
驱动开发---双机调试搭建支持win11(2025)
驱动开发
zly88653723 天前
驱动开发,为什么需要映射?
驱动开发
cxr82812 天前
SPARC方法论在Claude Code基于规则驱动开发中的应用
人工智能·驱动开发·claude·智能体