解除鎖定 Windows 媒體格式 SDK
[與此頁面 相關的功能 DirectShow是舊版功能。 它已被 MediaPlayer、 IMFMediaEngine和 Media Foundation 中的音訊/視訊擷取取代。 這些功能已針對Windows 10和Windows 11進行優化。 Microsoft 強烈建議新程式碼盡可能使用 MediaPlayer、 IMFMediaEngine 和 音訊/視訊擷取 ,而不是 DirectShow。 Microsoft 建議盡可能重寫使用舊版 API 的現有程式碼,以使用新的 API。]
若要存取 Windows Media Format SDK 7 或 7.1 版,應用程式必須在執行時間提供軟體憑證,也稱為金鑰。 此金鑰包含在名為 wmstub.lib 的靜態程式庫中,應用程式會在建置時連結至此程式庫。 只有建立或讀取 DRM 保護的檔案時,才需要個別的金鑰。 您可以使用 Windows 媒體格式 SDK 所提供的靜態程式庫來建立非 DRM 檔案。 如需取得 DRM 金鑰的詳細資訊,請參閱 Windows 媒體格式 SDK。 DirectShow 應用程式會在將憑證新增至篩選圖形時,將其憑證提供給 WM ASF 寫入器。 應用程式必須使用 COM IServiceProvider 和 IObjectWithSite 介面註冊為金鑰提供者。 使用這項技術,應用程式會實作衍生自 IServiceProvider的金鑰提供者類別。 這個類別會實作三個標準 COM 方法:AddRef、 QueryInterface和 Release,以及一個由篩選圖形管理員呼叫的額外方法 QueryService。 QueryService 會呼叫 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.
相關主題