次の方法で共有


Windows Media Format SDK のロック解除

Windows Media Format SDK Version 7 または 7.1 にアクセスするには、アプリケーションは実行時にソフトウェア証明書 (キーとも呼ばれる) を提供しなければならない。このキーは、アプリケーションがビルド時にリンクされる静的ライブラリ wmstub.lib に含まれている。個別キーは DRM で保護されたファイルの読み書きにのみ必要となる。非 DRM ファイルは Windows Media Format SDK に付属する静的ライブラリを使って作成される。DRM キーの入手方法については、Windows Media Format SDK を参照すること。DirectShow アプリケーションは、フィルタ グラフに追加されるときに WM ASF ライタに証明書を提供する。アプリケーションは、COM の IServiceProvider および IObjectWithSite インターフェイスを使って、キー プロバイダとして登録しなければならない。この手法を用いて、アプリケーションは IServiceProvider から派生されたキー プロバイダ クラスを実装する。このクラスは、COM の 3 つの標準メソッドである AddRefQueryInterface、および Release と共に、フィルタ グラフ マネージャから呼び出される追加メソッド QueryService を実装する。QueryService は、Windows Media Format SDK の WMCreateCertificate メソッドを呼び出し、作成した証明書へのポインタをフィルタ グラフ マネージャに返す。証明書が有効な場合、フィルタ グラフ マネージャはグラフの作成を進めることを許可する。

アプリケーションを作成するには、WMCreateCertificate のプロトタイプ用に Wmsdkidl.h をインクルードし、Wmstub.lib ライブラリにリンクする。

次のサンプル コードに、この処理の基本的な手順を示す。

// IServiceProvider から派生したキー プロバイダ クラスを宣言し、実装する。

class CKeyProvider : public IServiceProvider {
public:
    // IUnknown インターフェイス。
    STDMETHODIMP QueryInterface(REFIID riid, void ** ppv);
    STDMETHODIMP_(ULONG) AddRef();
    STDMETHODIMP_(ULONG) Release();

    CKeyProvider();

    // IServiceProvider
    STDMETHODIMP QueryService(REFIID siid, REFIID riid, void **ppv);
    
private:
    ULONG m_cRef;
};

CKeyProvider::CKeyProvider() : m_cRef(0)
{
}

// IUnknown メソッド。
ULONG CKeyProvider::AddRef()
{
    return InterlockedIncrement(&m_cRef);
}

ULONG CKeyProvider::Release()
{
    ASSERT(m_cRef > 0);

    ULONG lCount = InterlockedDecrement(&m_cRef);
    if (m_cRef == 0) 
    {
        delete this;
        return (ULONG)0;
    }
    return (ULONG)lCount;
}

// IUnknown および IServiceProvider のみサポートする。
HRESULT CKeyProvider::QueryInterface(REFIID riid, void ** ppv)
{
    if (!ppv) return E_POINTER;

    if (riid == IID_IUnknown) 
    {
        *ppv = (void *) static_cast<IUnknown *>(this);
        AddRef();
        return S_OK;
    }
    if (riid == IID_IServiceProvider) 
    {
        *ppv = (void *) static_cast<IServiceProvider *>(this);
        AddRef();
        return S_OK;
    }

    return E_NOINTERFACE;
}

STDMETHODIMP CKeyProvider::QueryService(REFIID siid, REFIID riid, void **ppv)
{
    if (!ppv) return E_POINTER;

    if (siid == __uuidof(IWMReader) && riid == IID_IUnknown) 
    {
        IUnknown *punkCert;
        HRESULT hr = WMCreateCertificate(&punkCert);
        if (SUCCEEDED(hr)) 
        {
            *ppv = (void *) punkCert;
        }
        return hr;
    }
    return E_NOINTERFACE;
}

////////////////////////////////////////////////////////////////////
//
// 以下の例では、アプリケーションにおける一連のメソッド呼び出しを示す。
// 簡潔にするため、エラー チェックは省略した。
//
///////////////////////////////////////////////////////////////////

//フィルタ グラフ マネージャを作成するが、フィルタは追加しない。
IGraphBuilder *pGraph;
hr = CreateFilterGraph(&pGraph);

...

// キー プロバイダ クラスをインスタンス化し、COM が静的オブジェクトを
// 解放しないように AddRef する。

CKeyProvider prov;
prov.AddRef();  // COM により静的オブジェクトが解放されないようにする。

// コールバックと QueryService のために IObjectWithSite ポインタをグラフに与える。
IObjectWithSite* pObjectWithSite = NULL;

hr = pGraph->QueryInterface(IID_IObjectWithSite, (void**)&pObjectWithSite);
if (SUCCEEDED(hr))
{
    // IObjectWithSite ポインタを使ってキー プロバイダ オブジェクトを指定する。
    // フィルタ グラフ マネージャはこのポインタを使って QueryService を呼び出し、
    // ロックを解除する。
    // ロック解除が成功すると、グラフを作成できる。

    pObjectWithSite->SetSite((IUnknown *) (IServiceProvider *) &prov);
    pObjectWithSite->Release();
}

// グラフを作成する。