对服务提供商进行身份验证

若要从 Windows Media 设备管理器进行访问,服务提供商必须继承并实现 IComponentAuthenticate 接口。

为了对自身进行身份验证,服务提供商执行以下步骤:

  1. 在实例化时,它会创建一个新的全局 CSecureChannelServer 对象,并设置其密钥文件中的证书和密钥值。
  2. 它只需将参数传递到其全局 CSecureChannelServer 成员即可实现 IComponentAuthenticate::SACAuth 和 IComponentAuthenticate::SACGetProtocols 方法。
  3. 在处理任何已实现的 Windows Media 设备管理器方法之前,服务提供商必须通过调用 CSecureChannelServer::fIsAuthenticated 来验证调用方身份验证,如果调用方未进行身份验证,则失败。

以下步骤显示在以下 C++ 示例中。

创建 CSecureChannelServer 对象

CMyServiceProvider::CMyServiceProvider()
{
    HRESULT hr = S_OK;

    // Create the persistent SAC object.
    g_pSAC = new CSecureChannelServer();

    // Set the SAC certificate.
    if (g_pSAC)
    {
        hr = g_pSAC->SetCertificate(
             SAC_CERT_V1,
            (BYTE*)abCert, sizeof(abCert), // SP's certificate.
            (BYTE*)abPVK, sizeof(abPVK)    // SP's key.
        );
    }   
    if (FAILED(hr)) return hr;

    //... Perform other class initialization here ...

    return hr;
}

实现 IComponentAuthenticate 方法

STDMETHODIMP CMDServiceProvider::SACAuth(
    DWORD   dwProtocolID,
    DWORD   dwPass,
    BYTE   *pbDataIn,
    DWORD   dwDataInLen,
    BYTE  **ppbDataOut,
    DWORD  *pdwDataOutLen)
{
    HRESULT hr = S_OK;

    // Verify that the global CSecureChannelServer member still exists.
    if (!g_pSAC)
        return E_FAIL;

    // Just pass the call to the global SAC member.
    hr = g_pSAC->SACAuth(
        dwProtocolID,
        dwPass,
        pbDataIn, dwDataInLen,
        ppbDataOut, pdwDataOutLen
    );
    return hr;
}

STDMETHODIMP CMDServiceProvider::SACGetProtocols(
    DWORD **ppdwProtocols,
    DWORD  *pdwProtocolCount)
{
    HRESULT hr = E_FAIL;

    if (!g_pSAC)
        return hr;

    hr = g_pSAC->SACGetProtocols(
        ppdwProtocols,
        pdwProtocolCount
    );
    return hr;
}

验证调用方身份验证

下面的代码示例演示服务提供商在 IMDServiceProvider 接口实现过程中检查调用方身份验证。

STDMETHODIMP CMyServiceProvider::GetDeviceCount(DWORD * pdwCount)
{
    HRESULT hr = S_OK;
    if (!g_pSAC)
        return E_FAIL;

    if (!(g_pSAC->fIsAuthenticated()))
        return WMDM_E_NOTCERTIFIED;

    *pdwCount = m_DeviceCount;

    return hr;
}

创建服务提供程序