📄 copyprotection.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, ©_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 + -