グラフィックス ドライバーが COPP をサポートしているかどうかをテストする
[このページに関連付けられている機能 DirectShow は、従来の機能です。 MediaPlayer、IMFMediaEngine、および Media Foundation のオーディオ/ビデオ キャプチャに置き換わりました。 これらの機能は、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、DirectShow ではなく Media Foundation で MediaPlayer、IMFMediaEngine、Audio/Video Capture を使用することを強くお勧めします。 Microsoft は、従来の API を使用する既存のコードを、可能であれば新しい API を使用するように書き直すよう提案しています。]
認定出力保護プロトコル (COPP) を使用すると、アプリケーションは、ビデオ カードからディスプレイ デバイスに移動する際に、ビデオ コンテンツを保護できます。 グラフィックス ドライバーが COPP をサポートしている場合、ドライバーは Microsoft によって署名された証明書チェーンを保持し、ドライバーを認証します。 COPP を使用してコンテンツ保護を適用する再生アプリケーションでは、証明書チェーンを検証して、ドライバーが改ざんされていないことを確認する必要があります。
ただし、証明書を検証せずに、グラフィックス ドライバーが COPP をサポートしているかどうかをチェックすることもできます。 たとえば、デジタル メディア プロバイダーがデジタル著作権管理 (DRM) ライセンスを発行する場合、ユーザーが COPP 対応グラフィックス ドライバーを持っているかどうかをチェックしたい場合があります。 プロバイダーは、ライセンスの発行時に COPP を適用する必要はありません。ドライバーが COPP をサポートしているかどうかをテストするだけで済みます。
次のコードは、ドライバーが COPP をサポートしているかどうかをテストする方法を示しています。 アプリケーションは、ドライバーのテストに使用されるビデオ ファイルの名前を渡す必要があります。 これは、Microsoft® DirectShow® の Video Mixing Renderer フィルターが、フィルターが接続されるまで COPP セッションを初期化しないために必要です。 この関数は、ドライバーが COPP を実行できる場合にチェックするクライアント アプリケーションに含めることができます。
注意
ユーザーのコンピューターに 2 つのグラフィックス カードがある場合、この関数はプライマリ グラフィックス カードのドライバーをテストしますが、セカンダリ グラフィックス カードはテストしません。
#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;
}
関連トピック