Microsoft DirectX 8.1 (C++)

Obtaining the CA Manager (C++)

This topic applies to Windows XP Home Edition and Windows XP Professional only.

Conditional access is a Video Control feature. The feature object coclass is MSVidCAGSeg; this object aggregates the CA Manager object and exposes the ICAManager interface through it. The Video Control always activates this feature; when you set up the active features, you do not have to specify the CA feature explicitly, because the Video Control automatically adds it to the active features collection.

Always obtain the CA feature from the active features collection, never from the available features collection. Otherwise, you will obtain the wrong instance and not receive events correctly. However, this rule brings out a potential pitfall: If you do not specify any active features, the active features collection defaults to NULL. In that case, the Video Control creates a new features collection when the application builds or runs the filter graph. To avoid errors, obtain the CAManager after building the graph.

To locate the feature, iterate through the collection, and either query for ICAManager or call IMSVidDevice::get__ClassID to compare the CLSID, as shown in the following code example:

HRESULT MyControlContainer::FindCA()
{
    HRESULT hr = S_OK;
    CComPtr<IMSVidFeatures> pFeatures;
    CComQIPtr<ICAManager> pCAM;

    // Get the active features collection.
    hr = m_pVidControl->get_FeaturesActive(&pFeatures);
    if (SUCCEEDED(hr))
    {
        // Iterate through the collection.
        long lCount = 0;
        pFeatures->get_Count(&lCount);
        for (long ix = 0; ix < lCount; ix++)
        {
            CComPtr<IMSVidFeature> pFeature;
            CComVariant var(ix);
            hr =  pFeatures->get_Item(var, &pFeature);
            if (SUCCEEDED(hr))
            {
                pCAM = pFeature;  // Implicit QI.
                if (pCAM)
                {
                    // Found it. Store it in a class member variable.
                    m_pCAManager = pCAM;
                    break;
                }
                /* Or, you can search by CLSID:
                GUID clsid;
                hr = pFeature->get__ClassID(&clsid);
                if (clsid == __uuidof(MSVidCAGSeg))
                    pFeature.QueryInterface(&m_pCAManager); 
                */
            }
        }
    }
    return (pCAM ? S_OK : E_FAIL);
}