Partilhar via


Enviando solicitações de status copp

[O recurso associado a esta página, DirectShow, é um recurso herdado. Ele foi substituído por MediaPlayer, IMFMediaEngine e Captura de Áudio/Vídeo na Media Foundation. Esses recursos foram otimizados para Windows 10 e Windows 11. A Microsoft recomenda fortemente que o novo código use MediaPlayer, IMFMediaEngine e Captura de Áudio/Vídeo no Media Foundation em vez de DirectShow, quando possível. A Microsoft sugere que o código existente que usa as APIs herdadas seja reescrito para usar as novas APIs, se possível.]

Para enviar uma solicitação de status do COPP (Certified Output Protection Protocol), preencha uma estrutura AMCOPPStatusInput com os dados de solicitação. Os membros da estrutura são:

  • rApp. Um número aleatório de 128 bits, digitado como GUID. O mesmo número é retornado na resposta do driver. Você deve alocar o número aleatório no heap e, em seguida, copiá-lo para a estrutura. Isso protege contra ataques em que o invasor modifica o conteúdo da estrutura AMCOPPStatusInput .
  • guidStatusRequestID. Um GUID que identifica a solicitação. Consulte Referência de consulta COPP.
  • dwSequence. O status número de sequência. Incremente esse valor após cada solicitação de status. (Na seção Iniciando uma sessão COPP, esse valor é mostrado como uStatusSeq nos exemplos de código.)
  • cbSizeData. O tamanho, em bytes, de todos os dados adicionais necessários para a solicitação.
  • StatusData. Dados da solicitação de status.

Passe a estrutura AMCOPPStatusInput para o método IAMCertifiedOutputProtection::P rotectionStatus . Por exemplo, o código a seguir envia uma solicitação status que consulta quais mecanismos de proteção estão disponíveis:

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;

A resposta é gravada no membro COPPStatus da estrutura AMCOPPStatusOutput . O tamanho dos dados válidos na resposta é fornecido no membro cbSizeData . Para garantir a integridade da mensagem, o driver calcula um MAC (código de autenticação de mensagem) usando o algoritmo OMAC 1 e retorna esse valor no membro macKDI da estrutura. O aplicativo deve verificar esse valor da seguinte maneira:

  1. Calcule a marca OMAC para o bloco de dados que aparece após o membro macKDI da estrutura AMCOPPStatusOutput (em outras palavras, cbSizeData mais COPPStatus).
  2. Compare essa marca com o valor em macKDI, usando um memcmp reto.

O algoritmo OMAC 1 é descrito em detalhes em https://www.nuee.nagoya-u.ac.jp/labs/tiwata/omac/omac.html. O COPP usa os seguintes parâmetros OMAC-1:

  • E = AES
  • t = 128 bits

Os dados retornados da solicitação status sempre começam com dois itens:

  • O mesmo valor de rApp que foi passado pelo aplicativo. Você deve verificar se esse valor corresponde ao valor original armazenado no heap.
  • Um valor COPP_StatusFlags que indica se a status de proteção de saída foi alterada.

Como a conexão pode ser perdida ou reconfigurada, o aplicativo deve sondar periodicamente o driver para o status atual. Se o sinalizador COPP_RenegotiationRequired estiver definido, o aplicativo deverá tentar redefinir o nível de proteção. Se o sinalizador COPP_LinkLost estiver definido, o aplicativo deverá parar de reproduzir o conteúdo. Por exemplo, o sinalizador COPP_LinkLost pode ser retornado porque o usuário desconectou o conector de saída. O aplicativo deve liberar a instância atual da VMR, criar uma nova instância da VMR e estabelecer uma nova sessão COPP (incluindo troca de chaves e validação de certificado).

Usando o COPP (Certified Output Protection Protocol)