发送 COPP 状态请求

[与此页面关联的功能 DirectShow 是一项旧功能。 它已被 MediaPlayerIMFMediaEngine媒体基金会中的音频/视频捕获取代。 这些功能已针对Windows 10和Windows 11进行了优化。 Microsoft 强烈建议新代码尽可能使用 MediaPlayerIMFMediaEngineMedia 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 成员中返回此值。 应用程序应验证此值,如下所示:

  1. 计算出现在 AMCOPPStatusOutput 结构的 macKDI 成员之后的数据块的 OMAC 标记, (换句话说,即 cbSizeDataCOPPStatus) 。
  2. 使用直接 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 会话 (包括密钥交换和证书验证) 。

使用认证输出保护协议 (COPP)