Freigeben über


Senden von COPP-Statusanforderungen

[Das dieser Seite zugeordnete Feature DirectShow ist ein Legacyfeature. Es wurde durch MediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation ersetzt. Diese Features wurden für Windows 10 und Windows 11 optimiert. Microsoft empfiehlt dringend, dass neuer Code nach Möglichkeit MediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation anstelle von DirectShow verwendet. Microsoft schlägt vor, vorhandenen Code, der die Legacy-APIs verwendet, um nach Möglichkeit die neuen APIs zu verwenden.]

Um eine COPP-Anforderung (Certified Output Protection Protocol) status zu senden, füllen Sie eine AMCOPPStatusInput-Struktur mit den Anforderungsdaten aus. Die Strukturmitglieder sind:

  • rApp. Eine 128-Bit-Zufallszahl, die als GUID eingegeben wird. Die gleiche Zahl wird in der Antwort des Treibers zurückgegeben. Sie sollten die Zufallszahl auf dem Heap zuordnen und dann in die Struktur kopieren. Dies schützt vor Angriffen, bei denen der Angreifer den Inhalt der AMCOPPStatusInput-Struktur ändert.
  • guidStatusRequestID. Eine GUID, die die Anforderung identifiziert. Weitere Informationen finden Sie unter COPP-Abfragereferenz.
  • dwSequence. Die status Sequenznummer. Erhöhen Sie diesen Wert nach jeder status Anforderung. (Im Abschnitt Initiieren einer COPP-Sitzung wird dieser Wert in den Codebeispielen als uStatusSeq angezeigt.)
  • cbSizeData. Die Größe aller zusätzlichen Daten, die für die Anforderung benötigt werden, in Bytes.
  • StatusData. Daten für die status Anforderung.

Übergeben Sie die AMCOPPStatusInput-Struktur an die IAMCertifiedOutputProtection::P rotectionStatus-Methode . Der folgende Code sendet beispielsweise eine status-Anforderung, die fragt, welche Schutzmechanismen verfügbar sind:

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;

Die Antwort wird in das COPPStatus-Member der AMCOPPStatusOutput-Struktur geschrieben. Die Größe der gültigen Daten in der Antwort wird im element cbSizeData angegeben. Um die Integrität der Nachricht sicherzustellen, berechnet der Treiber mithilfe des OMAC 1-Algorithmus einen Nachrichtenauthentifizierungscode (MAC) und gibt diesen Wert im macKDI-Element der Struktur zurück. Die Anwendung sollte diesen Wert wie folgt überprüfen:

  1. Berechnen Sie das OMAC-Tag für den Datenblock, der nach dem macKDI-Member der AMCOPPStatusOutput-Struktur (mit anderen Worten cbSizeData plus COPPStatus) angezeigt wird.
  2. Vergleichen Sie dieses Tag mit dem Wert in macKDI, indem Sie einen geraden Memcmp verwenden.

Der OMAC 1-Algorithmus wird unter ausführlich https://www.nuee.nagoya-u.ac.jp/labs/tiwata/omac/omac.htmlbeschrieben. COPP verwendet die folgenden OMAC-1-Parameter:

  • E = AES
  • t = 128 Bits

Die von der status Anforderung zurückgegebenen Daten beginnen immer mit zwei Elementen:

  • Der gleiche Wert von rApp , der von der Anwendung übergeben wurde. Überprüfen Sie, ob dieser Wert mit dem ursprünglichen Wert übereinstimmt, der auf dem Heap gespeichert ist.
  • Ein COPP_StatusFlags Wert, der angibt, ob sich der Ausgabeschutz status geändert hat.

Da die Verbindung verloren geht oder neu konfiguriert werden kann, sollte die Anwendung den Treiber regelmäßig nach dem aktuellen status abfragen. Wenn das COPP_RenegotiationRequired-Flag festgelegt ist, sollte die Anwendung versuchen, die Schutzstufe zurückzusetzen. Wenn das COPP_LinkLost-Flag festgelegt ist, sollte die Anwendung die Wiedergabe des Inhalts beenden. Beispielsweise kann das COPP_LinkLost-Flag zurückgegeben werden, weil der Benutzer die Verbindung mit dem Ausgabeconnector getrennt hat. Die Anwendung sollte den aktuellen instance der VMR freigeben, eine neue instance der VMR erstellen und eine neue COPP-Sitzung einrichten (einschließlich Schlüsselaustausch und Zertifikatüberprüfung).

Verwenden des Certified Output Protection Protocol (COPP)