发送 COPP 状态请求
[与此页面关联的功能 DirectShow 是一项旧功能。 它已被 MediaPlayer、 IMFMediaEngine 和 媒体基金会中的音频/视频捕获取代。 这些功能已针对Windows 10和Windows 11进行了优化。 Microsoft 强烈建议新代码尽可能使用 MediaPlayer、 IMFMediaEngine 和 Media Foundation 中的音频/视频捕获 ,而不是 DirectShow。 如果可能,Microsoft 建议重写使用旧 API 的现有代码以使用新 API。]
若要 (COPP) 状态请求发送认证输出保护协议,请使用请求数据填写 AMCOPPStatusInput 结构。 结构成员包括:
- rApp。 键入为 GUID 的 128 位随机数。 驱动程序的响应中返回相同的数字。 应在堆上分配随机数,然后将其复制到 结构中。 这可以防范攻击者修改 AMCOPPStatusInput 结构内容时的攻击。
- guidStatusRequestID。 标识请求的 GUID。 请参阅 COPP 查询参考。
- dwSequence。 状态序列号。 在每个状态请求之后递增此值。 (在 “启动 COPP 会话”部分中,此值在代码示例中显示为 uStatusSeq 。)
- cbSizeData。 请求所需的任何其他数据的大小(以字节为单位)。
- StatusData。 状态请求的数据。
将 AMCOPPStatusInput 结构传递给 IAMCertifiedOutputProtection::P rotectionStatus 方法。 例如,以下代码发送一个状态请求,用于查询可用的保护机制:
AMCOPPStatusInput input;
AMCOPPStatusOutput output;
// Create a 128-bit random number.
GUID *pGuid = new GUID();
if (pGuid == NULL)
{
// Handle out-of-memory condition.
}
CryptGenRandom(hCSP, sizeof(GUID), (BYTE*)pGuid);
// Copy the random number into the command structure.
memcpy(&input.rApp, pGuid, sizeof(GUID));
// Fill in the other data.
input.guidStatusRequestID = DXVA_COPPQueryProtectionType; // Request type.
input.dwSequence = uStatusSeq; // Status sequence number.
input.cbSizeData = 0 // No other data for this query.
// Send the request.
hr = pCOPP->ProtectionStatus(&input, &output);
// Increment the sequence number each time.
++uStatusSeq;
响应将写入 AMCOPPStatusOutput 结构的 COPPStatus 成员。 cbSizeData 成员中提供了响应中有效数据的大小。 为了确保消息的完整性,驱动程序使用 OMAC 1 算法 (MAC) 计算消息身份验证代码,并在结构的 macKDI 成员中返回此值。 应用程序应验证此值,如下所示:
- 计算出现在 AMCOPPStatusOutput 结构的 macKDI 成员之后的数据块的 OMAC 标记, (换句话说,即 cbSizeData 加 COPPStatus) 。
- 使用直接 memcmp 将此标记与 macKDI 中的值进行比较。
上详细介绍 https://www.nuee.nagoya-u.ac.jp/labs/tiwata/omac/omac.html了 OMAC 1 算法。 COPP 使用以下 OMAC-1 参数:
- E = AES
- t = 128 位
从状态请求返回的数据始终以两项开头:
- 应用程序传递的 rApp 值相同。 应验证此值是否与堆上存储的原始值匹配。
- 一个COPP_StatusFlags值,该值指示输出保护状态是否已更改。
由于连接可能会丢失或重新配置,因此应用程序应定期轮询驱动程序以获取当前状态。 如果设置了COPP_RenegotiationRequired标志,应用程序应尝试重置保护级别。 如果设置了COPP_LinkLost标志,应用程序应停止播放内容。 例如,由于用户断开了输出连接器的连接,因此可以返回COPP_LinkLost标志。 应用程序应释放 VMR 的当前实例,创建 VMR 的新实例,并建立新的 COPP 会话 (包括密钥交换和证书验证) 。
相关主题