共用方式為


解除鎖定 Windows 媒體格式 SDK

[與此頁面 相關的功能 DirectShow是舊版功能。 它已被 MediaPlayerIMFMediaEngineMedia Foundation 中的音訊/視訊擷取取代。 這些功能已針對Windows 10和Windows 11進行優化。 Microsoft 強烈建議新程式碼盡可能使用 MediaPlayerIMFMediaEngine音訊/視訊擷取 ,而不是 DirectShow。 Microsoft 建議盡可能重寫使用舊版 API 的現有程式碼,以使用新的 API。]

若要存取 Windows Media Format SDK 7 或 7.1 版,應用程式必須在執行時間提供軟體憑證,也稱為金鑰。 此金鑰包含在名為 wmstub.lib 的靜態程式庫中,應用程式會在建置時連結至此程式庫。 只有建立或讀取 DRM 保護的檔案時,才需要個別的金鑰。 您可以使用 Windows 媒體格式 SDK 所提供的靜態程式庫來建立非 DRM 檔案。 如需取得 DRM 金鑰的詳細資訊,請參閱 Windows 媒體格式 SDK。 DirectShow 應用程式會在將憑證新增至篩選圖形時,將其憑證提供給 WM ASF 寫入器。 應用程式必須使用 COM IServiceProviderIObjectWithSite 介面註冊為金鑰提供者。 使用這項技術,應用程式會實作衍生自 IServiceProvider的金鑰提供者類別。 這個類別會實作三個標準 COM 方法:AddRefQueryInterfaceRelease,以及一個由篩選圖形管理員呼叫的額外方法 QueryServiceQueryService 會呼叫 Windows Media Format SDK 方法 WMCreateCertificate ,並傳回篩選圖形管理員所建立憑證的指標。 如果憑證有效,篩選圖形管理員可讓圖形建置程式繼續進行。

注意

若要建置應用程式,請包含 WMCreateCertificate原型的 Wmsdkidl.h,並連結至 Wmstub.lib 程式庫。

 

下列程式碼範例說明此程式的基本步驟:

// Declare and implement a key provider class derived from IServiceProvider.

class CKeyProvider : public IServiceProvider {
public:
    // IUnknown interface
    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 methods
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;
}

// We only support IUnknown and 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;
}

////////////////////////////////////////////////////////////////////
//
// These examples illustrate the sequence of method calls
// in your application. Error checking is omitted for brevity.
//
///////////////////////////////////////////////////////////////////

// Create the filter graph manager, but don't add any filters.
IGraphBuilder *pGraph;
hr = CreateFilterGraph(&pGraph);

...

// Instantiate the key provider class, and AddRef it
// so that COM doesn't try to free our static object.

CKeyProvider prov;
prov.AddRef();  // Don't let COM try to free our static object.

// Give the graph an IObjectWithSite pointer for callbacks and QueryService.
IObjectWithSite* pObjectWithSite = NULL;

hr = pGraph->QueryInterface(IID_IObjectWithSite, (void**)&pObjectWithSite);
if (SUCCEEDED(hr))
{
    // Use the IObjectWithSite pointer to specify our key provider object.
    // The filter graph manager will use this pointer to call
    // QueryService to do the unlocking.
    // If the unlocking succeeds, then we can build our graph.

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

// Now build the graph.

在 DirectShow 中建立 ASF 檔案