如果用户模式显示驱动程序支持上述每个必需的内容保护 DDI 函数,则仅报告内容保护功能。 Direct3D 运行时使用以下 D3DDDICAPS_TYPE 值来检索有关用户模式显示驱动程序支持的内容保护功能的信息。 当运行时调用 GetCaps 时,运行时在驱动程序的 GetCaps 函数的 pData 参数指向的 D3DDDIARG_GETCAPS 结构的 Type 成员中设置这些D3DDDICAPS_TYPE值。
D3DDDICAPS_GETCONTENTPROTECTIONCAPS
运行时为驱动程序应使用的特定加密和解码组合提供指向 DDICONTENTPROTECTIONCAPS 结构的指针。 驱动程序返回指向填充的 D3DCONTENTPROTECTIONCAPS 结构的指针,该结构描述驱动程序用于加密和解码组合的内容保护功能。 有关 D3DCONTENTPROTECTIONCAPS 的详细信息,请参阅 DirectX SDK 文档。
D3DDDICAPS_GETCERTIFICATESIZE
驱动程序提供指向数字的指针,该数字指定用于通道或加密类型的驱动程序证书的大小(以字节为单位)。 然后,Direct3D 运行时使用此大小分配缓冲区,以保存运行时使用 D3DDDICAPS_GETCERTIFICATE 调用 GetCaps 时运行时收到的证书信息。
D3DDDICAPS_GETCERTIFICATE
运行时提供指向 DDICERTIFICATEINFO 结构的指针,该结构描述驱动程序应检索的证书。
对于经过身份验证的通道,驱动程序使用现有的 OPM 证书,该证书是由 Microsoft 签名的 X.509 证书。
应用程序可以查询驱动程序的证书以确定以下信息:
- 驱动程序是否受信任。
- 是否撤销了驱动程序。
- 驱动程序的公钥。 应用程序使用驱动程序的公钥为用于身份验证的经过身份验证的通道建立会话密钥。
如果为经过 Direct3D 9 身份验证的通道调用,则调用具有 D3DDDICAPS_GETCERTIFICATE 集的 GetCaps 会失败,因为此通道不支持证书或身份验证。
对于加密会话,驱动程序返回给定加密类型的证书。 根据所使用的加密类型和密钥交换,证书可能使用,也可能不使用证书。 不同的加密类型也可能使用不同的证书。
1. 能力查询框架结构
1.1 基础处理流程
HRESULT APIENTRY GetCaps(
D3DDDIARG_GETCAPS* pData)
{
switch (pData->Type) {
case D3DDDICAPS_GETCONTENTPROTECTIONCAPS:
return GetContentProtectionCaps(pData);
case D3DDDICAPS_GETCERTIFICATESIZE:
return GetCertificateSize(pData);
case D3DDDICAPS_GETCERTIFICATE:
return GetCertificate(pData);
default:
return E_NOTIMPL;
}
}
2. 内容保护能力报告 (D3DDDICAPS_GETCONTENTPROTECTIONCAPS)
2.1 数据结构填充
HRESULT GetContentProtectionCaps(D3DDDIARG_GETCAPS* pData)
{
DDICONTENTPROTECTIONCAPS* pInCaps =
(DDICONTENTPROTECTIONCAPS*)pData->pData;
D3DCONTENTPROTECTIONCAPS* pOutCaps =
(D3DCONTENTPROTECTIONCAPS*)pData->pData;
// 验证输入结构
if (pData->DataSize < sizeof(D3DCONTENTPROTECTIONCAPS)) {
return E_INVALIDARG;
}
// 根据加密类型返回能力
switch (pInCaps->CryptoType) {
case D3DCRYPTOTYPE_AES128:
pOutCaps->Caps =
D3DCPCAPS_SOFTWARE |
D3DCPCAPS_HARDWARE;
pOutCaps->KeyExchangeType =
D3DKEYEXCHANGE_RSAES_OAEP;
pOutCaps->ProtectedMemorySize =
GPU_GetSecureMemorySize();
break;
case D3DCRYPTOTYPE_PROPRIETARY:
// 处理厂商特定加密方案
break;
default:
return D3DDDIERR_UNSUPPORTEDCRYPTO;
}
return S_OK;
}
2.2 能力标志详解
能力标志 | 含义 |
---|---|
D3DCPCAPS_SOFTWARE | 支持软件加密 |
D3DCPCAPS_HARDWARE | 支持硬件加速 |
D3DCPCAPS_PROTECTED_MEMORY | 有专用保护内存 |
3. 证书大小查询 (D3DDDICAPS_GETCERTIFICATESIZE)
3.1 实现代码
HRESULT GetCertificateSize(D3DDDIARG_GETCAPS* pData)
{
UINT* pCertSize = (UINT*)pData->pData;
if (pData->Info == D3DDDICERTTYPE_AUTHCHANNEL) {
// 认证通道使用OPM证书
*pCertSize = sizeof(OPM_CERTIFICATE);
}
else if (pData->Info == D3DDDICERTTYPE_CRYPTOSESSION) {
// 加密会话证书
*pCertSize = GetCryptoSessionCertSize(
(D3DCRYPTOTYPE)pData->Info);
}
else {
return E_INVALIDARG;
}
return S_OK;
}
3.2 证书类型处理
UINT GetCryptoSessionCertSize(D3DCRYPTOTYPE CryptoType)
{
switch (CryptoType) {
case D3DCRYPTOTYPE_AES128:
return 1024; // RSA-1024证书
case D3DCRYPTOTYPE_ECC:
return 256; // ECC P-256证书
default:
return 0;
}
}
4. 证书获取 (D3DDDICAPS_GETCERTIFICATE)
4.1 核心实现
HRESULT GetCertificate(D3DDDIARG_GETCAPS* pData)
{
DDICERTIFICATEINFO* pCertInfo =
(DDICERTIFICATEINFO*)pData->pData;
// 验证缓冲区大小
if (pData->DataSize < pCertInfo->CertificateSize) {
return E_INVALIDARG;
}
// 处理不同类型证书
switch (pCertInfo->CertificateType) {
case D3DDDICERTTYPE_AUTHCHANNEL:
return GetOPMCertificate(pCertInfo);
case D3DDDICERTTYPE_CRYPTOSESSION:
return GetCryptoSessionCertificate(
pCertInfo,
(D3DCRYPTOTYPE)pCertInfo->CryptoType);
default:
return E_INVALIDARG;
}
}
4.2 OPM证书获取
HRESULT GetOPMCertificate(DDICERTIFICATEINFO* pCertInfo)
{
// 从安全存储加载微软签名的证书
BYTE* pCert = GetSecureStorage()->GetOPMCert();
if (!pCert || pCertInfo->CertificateSize < OPM_CERT_SIZE) {
return E_FAIL;
}
memcpy(pCertInfo->pCertificate, pCert, OPM_CERT_SIZE);
pCertInfo->CertificateSize = OPM_CERT_SIZE;
return S_OK;
}
4.3 加密会话证书
HRESULT GetCryptoSessionCertificate(
DDICERTIFICATEINFO* pCertInfo,
D3DCRYPTOTYPE CryptoType)
{
CERT_STORE* pStore = GetCryptoCertStore();
switch (CryptoType) {
case D3DCRYPTOTYPE_AES128:
if (!pStore->GetRSACert(
pCertInfo->pCertificate,
&pCertInfo->CertificateSize)) {
return E_FAIL;
}
break;
case D3DCRYPTOTYPE_ECC:
if (!pStore->GetECCCert(
pCertInfo->pCertificate,
&pCertInfo->CertificateSize)) {
return E_FAIL;
}
break;
default:
return D3DDDIERR_UNSUPPORTEDCRYPTO;
}
return S_OK;
}
5. 安全证书管理
5.1 证书存储方案

5.2 证书验证流程
bool ValidateDriverCertificate(const BYTE* pCert, UINT size)
{
// 1. 检查微软签名
if (!VerifyMicrosoftSignature(pCert, size)) {
return false;
}
// 2. 检查CRL列表
if (CheckRevocationList(pCert)) {
return false;
}
// 3. 验证证书链
return VerifyCertChain(pCert);
}
6. 错误处理规范
错误码 | 触发条件 |
---|---|
E_INVALIDARG | 参数或缓冲区大小无效 |
D3DDDIERR_UNSUPPORTEDCRYPTO | 不支持的加密类型 |
E_ACCESSDENIED | 证书访问被拒绝 |
HRESULT_FROM_WIN32(ERROR_NOT_FOUND) | 证书不存在 |
7. 性能优化建议
证书缓存:
class CertCache {
std::map<D3DCRYPTOTYPE, CachedCert> m_cache;
SRWLOCK m_lock;
bool GetCert(D3DCRYPTOTYPE type, BYTE** ppCert);
};
异步加载
void PreloadCertificates()
{
std::thread([] {
LoadCertificate(D3DCRYPTOTYPE_AES128);
LoadCertificate(D3DCRYPTOTYPE_ECC);
}).detach();
}