測試圖形驅動程式是否支援 COPP
[與此頁面 相關的功能 DirectShow是舊版功能。 它已被 MediaPlayer、 IMFMediaEngine和 Media Foundation 中的音訊/視訊擷取取代。 這些功能已針對Windows 10和Windows 11進行優化。 Microsoft 強烈建議新程式碼盡可能使用 MediaPlayer、 IMFMediaEngine 和 音訊/視訊擷取 ,而不是 DirectShow。 Microsoft 建議盡可能重寫使用舊版 API 的現有程式碼,以使用新的 API。]
認證輸出保護通訊協定 (COPP) 可讓應用程式在影片內容從視訊卡傳送到顯示裝置時保護視訊內容。 如果圖形驅動程式支援 COPP,驅動程式會保存由 Microsoft 簽署的憑證鏈結,並驗證驅動程式。 使用 COPP 強制執行內容保護的播放應用程式必須驗證憑證鏈結,以確保驅動程式未遭到竄改。
不過,您可能想要檢查圖形驅動程式是否支援 COPP,而不驗證憑證。 例如,當數位媒體提供者發出數位版權管理 (DRM) 授權時,可能會想要檢查使用者是否有已啟用 COPP 的圖形驅動程式。 提供者不需要在發出授權時強制執行 COPP;它只需要測試驅動程式是否支援 COPP。
下列程式碼示範如何測試驅動程式是否支援 COPP。 應用程式必須傳入將用來測試驅動程式的視訊檔案名。 這是必要專案,因為 Microsoft® DirectShow® 中的影片混合轉譯器篩選器在連線篩選之前不會初始化 COPP 會話。 此函式可以包含在用戶端應用程式中,以檢查驅動程式是否能夠執行 COPP。
注意
如果使用者的電腦有兩張圖形卡,此函式會測試主要圖形卡的驅動程式,但不會測試次要圖形卡。
#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;
}
相關主題