⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 copyprotection.cpp

📁 完整的基于Conxant平台的USB电视棒的WIN驱动程序。
💻 CPP
字号:
/*+++ *******************************************************************\ 
* 
*  Copyright and Disclaimer: 
*  
*     --------------------------------------------------------------- 
*     This software is provided "AS IS" without warranty of any kind, 
*     either expressed or implied, including but not limited to the 
*     implied warranties of noninfringement, merchantability and/or 
*     fitness for a particular purpose.
*     --------------------------------------------------------------- 
*   
*     Copyright (c) 2004 Conexant Systems, Inc. 
*     All rights reserved. 
*
\******************************************************************* ---*/ 

#include "CopyProtection.h"
#include <dvdmedia.h>

/**
 * Constructor
 *
 * @param p_base_filter
 *               IBaseFilter* for a filter in the graph we want to notify
 */
CCopyProtection::CCopyProtection(IBaseFilter* p_base_filter) :
                    _p_filter(p_base_filter),
                    _prev_cp_bits(0),
                    _provider(NULL)
{
    ASSERT(p_base_filter != 0);
    _provider = new CProvider();
    _provider->initialize(_p_filter);
}


CCopyProtection::~CCopyProtection()
{
    delete _provider;
}


/**
 * Create a list of filters that support notification of copy
 * protection status so that the copy protection values can
 * be distributed to them.  We check for 'Set' supported on
 * AM_KSPROPSETID_CopyProt, AM_PROPERTY_COPY_MACROVISION
 *
 * @return standard HRESULT, check with SUCCEEDED(hr) or FAILED(hr)
 */

HRESULT
CCopyProtection::createFilterList()
{
    HRESULT  hr = NOERROR;

    FILTER_INFO  base_filter_info;

    hr = _p_filter->QueryFilterInfo(&base_filter_info);

    if (FAILED(hr))
    {
        DbgLog((LOG_ERROR, 0, TEXT("ERROR: QueryFilterInfo() failed!!")));
        return hr;
    }

    if (base_filter_info.pGraph == NULL)
    {
        DbgLog((LOG_ERROR, 0, TEXT("ERROR: Filter is not in a graph!!")));
        return E_UNEXPECTED;
    }

    if (base_filter_info.pGraph)
    {
        //
        // Enumerate all the filters in the graph and look for those
        // supporting IKsPropertySet interface. We also look for the
        // filters that support IBasicVideo/IVideoWindow as they may
        // be the Video Renderer.
        //

        DumpGraph(base_filter_info.pGraph, 0);

        IEnumFilters* p_enum_filters;
        hr = base_filter_info.pGraph->EnumFilters(&p_enum_filters);

        if (SUCCEEDED(hr) && (p_enum_filters != 0))
        {
            ULONG           num_fetched = 0;
            IBaseFilter*    p_filter = 0;
            ULONG           support_type = 0;

            while ((S_OK == p_enum_filters->Next(1, &p_filter, &num_fetched)) &&
                   (1 == num_fetched))
            {
                FILTER_INFO     curr_filter_info;
                p_filter->QueryFilterInfo(&curr_filter_info);

                DbgLog((LOG_TRACE,
                        0,
                        TEXT("Processing Filter '%ls'"),
                        curr_filter_info.achName
                        ));

                //
                // We first want to see if the pins of this filter supports
                // IKsPropertySet.  If it does, we want to keep the pin(s)
                // on the list rather than the filter.
                //
                IEnumPins* p_enum_pins = 0;
                hr = p_filter->EnumPins(&p_enum_pins);

                BOOL pin_suports_ks_ps = FALSE;

                if (SUCCEEDED(hr))
                {
                    IPin* p_pin = 0;
                    while ((S_OK == p_enum_pins->Next(1, &p_pin, &num_fetched)) &&
                           (1 == num_fetched))
                    {
                        PIN_INFO pin_info;
                        p_pin->QueryPinInfo(&pin_info);

                        IKsPropertySet* p_ks_ps = 0;
                        hr = p_pin->QueryInterface(IID_IKsPropertySet, reinterpret_cast<LPVOID*>(&p_ks_ps));
                        if (SUCCEEDED(hr))
                        {
                            hr = p_ks_ps->QuerySupported(
                                AM_KSPROPSETID_CopyProt,
                                AM_PROPERTY_COPY_MACROVISION, &support_type
                                );

                            if (SUCCEEDED(hr) && (support_type & KSPROPERTY_SUPPORT_SET))
                            {
                                DbgLog((LOG_TRACE,
                                        0,
                                        TEXT("Pin '%ls' observes copy protection"),
                                        pin_info.achName
                                        ));

                                // add the pin to list
                                p_ks_ps->AddRef();
                                _observers.push_back(p_ks_ps);
                                pin_suports_ks_ps = TRUE;
                            }
                            else
                            {
                                DbgLog((LOG_TRACE,
                                        1,
                                        TEXT("Pin '%ls' does not observe copy protection"),
                                        pin_info.achName
                                        ));
                            }

                            p_ks_ps->Release();
                            p_ks_ps = 0;
                        }
                        else
                        {
                            // The pin didn't even support IID_IKsPropertySet
                            DbgLog((LOG_TRACE,
                                    1,
                                    TEXT("Pin '%ls' does not observe copy protection"),
                                    pin_info.achName
                                    ));
                        }
                        pin_info.pFilter->Release();
                        p_pin->Release();  // let the pin go now
                        p_pin = 0;
                    }
                    p_enum_pins->Release();
                    p_enum_pins = 0;
                }

                if (!pin_suports_ks_ps)
                {
                    // check if filter support property set
                    IKsPropertySet* p_ks_ps = 0;
                    if (SUCCEEDED(p_filter->QueryInterface(IID_IKsPropertySet, (LPVOID*)&p_ks_ps)))
                    {
                        if ( S_OK == p_ks_ps->QuerySupported(AM_KSPROPSETID_CopyProt,
                            AM_PROPERTY_COPY_MACROVISION, &support_type) &&
                            (support_type & KSPROPERTY_SUPPORT_SET) )
                        {
                            DbgLog((LOG_TRACE,
                                    0,
                                    TEXT("Filter '%ls' observes copy protection"),
                                    curr_filter_info.achName
                                    ));

                            // add the pin to list
                            p_ks_ps->AddRef();
                            _observers.push_back(p_ks_ps);
                        }
                        else
                        {
                            DbgLog((LOG_TRACE,
                                    1,
                                    TEXT("Filter '%ls' does not observe copy protection"),
                                    curr_filter_info.achName
                                    ));
                        }

                        p_ks_ps->Release();
                        p_ks_ps = 0;
                    }
                    else
                    {
                        // Filter didn't support IID_IKsPropertySet
                        DbgLog((LOG_TRACE,
                                1,
                                TEXT("Filter '%ls' does not observe copy protection"),
                                curr_filter_info.achName));
                    }
                }

                curr_filter_info.pGraph->Release();
                p_filter->Release();
                p_filter = 0;
            }

            p_enum_filters->Release();
            p_enum_filters = 0;
        }
        else
        {
            DbgLog((LOG_ERROR,
                    0,
                    TEXT("ERROR: EnumFilters() failed (Error 0x%lx)"),
                    hr));
            hr = E_UNEXPECTED;
        }

        base_filter_info.pGraph->Release();  // else we'll leak
    }
    else
    {
        DbgLog((LOG_ERROR, 0, TEXT("ERROR: Filter can't find graph!!")));
        hr = E_UNEXPECTED;
    }

    return hr;
}


//
// Empty the list and release the interfaces
//
HRESULT
CCopyProtection::destroyFilterList()
{
    //
    // Remove the filters from the distribution list and release them
    //

    for (std::vector<IKsPropertySet*>::iterator i = _observers.begin();
         i != _observers.end();
         i++)
    {
        IKsPropertySet* p_ks_ps = *i;
        p_ks_ps->Release();
    }
    _observers.clear();

    return NOERROR;  // success
}

//
// Query driver to get copy protection status.
//

DWORD
CCopyProtection::detectStatus()
{
    // MV detect status
    // 00 = no MV detected
    // 01 = PSP detected
    // 10 = PSP and color striping detected
    // 11 = PSP, color striping and type 3 color
    // striping detected
    DWORD status = _provider->getStatus();
    return status;
}

//
// Send copy protection values to all the enumerated filters.
//
HRESULT
CCopyProtection::broadcastStatus()
{
    DWORD copy_protect_encoding = detectStatus();
    DbgLog((LOG_TRACE, 0, TEXT("Copy protection status = %d"), copy_protect_encoding));

    HRESULT  hr_final = NOERROR;
    HRESULT  hr = NOERROR;

    for (std::vector<IKsPropertySet*>::iterator i = _observers.begin();
         i != _observers.end();
         i++)
    {
        IKsPropertySet* p_ks_ps = *i;

        hr = p_ks_ps->Set(AM_KSPROPSETID_CopyProt, AM_PROPERTY_COPY_MACROVISION,
                        NULL, 0, &copy_protect_encoding, sizeof(copy_protect_encoding));
        if (FAILED(hr))
        {
            DbgLog((LOG_ERROR, 0, TEXT("ERROR: failed IKsPropertySet::Set()")));
            DbgLog((LOG_ERROR, 0, TEXT("       AM_KSPROPSETID_CopyProt")));
            DbgLog((LOG_ERROR, 0, TEXT("       AM_PROPERTY_COPY_MACROVISION")));
            DbgLog((LOG_ERROR, 0, TEXT("       Error(0x%lx)"), hr));
            hr_final = hr;
        }
    }

    if (SUCCEEDED(hr_final))
    {
        _prev_cp_bits = copy_protect_encoding;
    }
    else
    {
        // any bits set next time should be re-sent, including to the filter(s)
        // that appearantly failed this time.
        _prev_cp_bits = 0;
    }

    return hr_final;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -