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
相关推荐
芯片设计-曾工2 天前
当精准脉冲遇上清晰视界——CH2205E模块与YL1621的“黄金搭档“
驱动开发·stm32·单片机·51单片机·硬件工程
平凡的小蚂蚁3 天前
Exynos4412-POP-7inLCD裸机开发完整教程(STM32 库风格)
驱动开发·stm32·单片机·嵌入式硬件·嵌入式·硬件工程
小此方3 天前
Re:Linux系统篇(五十二)线程篇 · 五:直击 Linux 内核底层:TCB 与 LWP 一体两面全解析(附自定义线程封装)
linux·运维·驱动开发
胡八一4 天前
虚拟串口com0com安装教程
驱动开发·stm32·单片机
智者知已应修善业4 天前
【三位数字显示计时定时器设计-同步方式】2025-6-30
驱动开发·经验分享·笔记·硬件架构·硬件工程
zhangfeng11334 天前
AI编程范式:从Vibe Coding(氛围编程)向SDD规范驱动开发演进全解析
人工智能·驱动开发·ai编程
JNX_SEMI4 天前
Hi5000Q/H 6.5~75V宽输入——与H5227A完全对等,无缝适配现有电源方案-聚能芯-智芯官方授权一级代理
驱动开发·单片机·嵌入式硬件·物联网·硬件工程
芯片设计-曾工5 天前
远乐YL1628 SSOP28驱动芯片详解
驱动开发·单片机·51单片机·硬件工程
zhangfeng11336 天前
CodeBuddy 是否支持 SDD(Spec-Driven Development 规范驱动开发
人工智能·驱动开发
dok126 天前
Johannes 《Linux内核模块与设备驱动开发:编写Linux驱动程序》 (11)kmalloc 动态内存分配和struct file中的私有数据
linux·驱动开发·算法