Testando se um driver gráfico dá suporte ao 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.]
O COPP (Protocolo de Proteção de Saída Certificado) permite que um aplicativo proteja o conteúdo do vídeo enquanto ele viaja do vídeo cartão para o dispositivo de exibição. Se um driver gráfico der suporte ao COPP, o driver conterá uma cadeia de certificados, assinada pela Microsoft, autenticando o driver. Os aplicativos de reprodução que usam COPP para impor a proteção de conteúdo devem validar a cadeia de certificados para garantir que o driver não tenha sido adulterado.
No entanto, talvez você queira marcar se um driver gráfico dá suporte ao COPP, sem validar o certificado. Por exemplo, quando um provedor de mídia digital emite uma licença drm (gerenciamento de direitos digitais), talvez ele queira marcar se o usuário tem um driver gráfico habilitado para COPP. O provedor não precisa impor o COPP no momento em que emite a licença; ele só precisa testar se o driver dá suporte ao COPP.
O código a seguir mostra como testar se um driver dá suporte ao COPP. O aplicativo deve passar o nome de um arquivo de vídeo que será usado para testar o driver. Isso é necessário porque o filtro Renderizador de Mixagem de Vídeo no Microsoft® DirectShow® não inicializa uma sessão COPP até que o filtro esteja conectado. Essa função pode ser incluída em um aplicativo cliente para marcar se o driver for capaz de executar o COPP.
Observação
Se o computador do usuário tiver duas placas gráficas, essa função testará o driver para os elementos gráficos primários cartão, mas não os elementos gráficos secundários cartão.
#include <dshow.h>
// Link to strmiids.lib
#define SAFE_RELEASE(p) if (NULL != (p)) { (p)->Release(); (p) = NULL; }
#define CHECK_HR(hr) if (FAILED(hr)) { goto done; }
enum COPPSupport
{
SUPPORTS_COPP,
DOES_NOT_SUPPORT_COPP,
CANNOT_DETERMINE_COPP_SUPPORT
};
//------------------------------------------------------------------------
// Name: IsDriverCoppEnabled
// Description: Test whether the user's graphics driver supports
// COPP.
// wszTestFile: Name of a video file to use for testing.
//
// If this method returns the value SUPPORTS_COPP, it does *not* guarantee
// that the driver is a valid COPP-enabled driver. If you want to use COPP
// to enforce video output protection, the application *must* validate
// the certificate returned by the KeyExchange method.
//
// The purpose of this function is only to test whether the driver
// claims to support COPP.
//------------------------------------------------------------------------
COPPSupport IsDriverCoppEnabled(const WCHAR *wszTestFile)
{
COPPSupport SupportResult = CANNOT_DETERMINE_COPP_SUPPORT;
IGraphBuilder *pGB = NULL;
IBaseFilter *pRenderer = NULL;
IAMCertifiedOutputProtection *pCOPPDevice = NULL;
BYTE *pbCertificate = NULL;
GUID RandomValue = GUID_NULL;
ULONG cbCertificateLength = NULL;
HRESULT hr = S_OK;
CHECK_HR(hr = CoInitializeEx(NULL, COINIT_MULTITHREADED));
// Create the Filter Graph Manager.
CHECK_HR(hr = CoCreateInstance(CLSID_FilterGraph, NULL,
CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&pGB));
// Create the VMR-9.
hr = CoCreateInstance(CLSID_VideoMixingRenderer9,
NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter,
(void**)&pRenderer
));
if (FAILED(hr))
{
// Try the VMR-7 instead.
CHECK_HR(hr = CoCreateInstance(CLSID_VideoMixingRenderer,
NULL, CLSCTX_INPROC, IID_IBaseFilter,
(void**)&pRenderer
));
}
// Add the VMR to the filter graph.
CHECK_HR(hr = pGB->AddFilter(pRenderer, L"Video Renderer"));
// Build a default playback graph.
CHECK_HR(hr = pGB->RenderFile(wszTestFile, NULL));
// Query for IAMCertifiedOutputProtection.
CHECK_HR(hr = pRenderer->QueryInterface(IID_IAMCertifiedOutputProtection,
(void**)&pCOPPDevice));
// Get the driver's COPP certificate.
hr = pCOPPDevice->KeyExchange(&RandomValue, &pbCertificate,
&cbCertificateLength);
if (SUCCEEDED(hr))
{
SupportResult = SUPPORTS_COPP;
}
else
{
SupportResult = DOES_NOT_SUPPORT_COPP;
}
done:
// Clean up.
CoTaskMemFree(pbCertificate);
SAFE_RELEASE(pCOPPDevice);
SAFE_RELEASE(pRenderer);
SAFE_RELEASE(pGB);
CoUninitialize();
return SupportResult;
}
Tópicos relacionados