📄 ksplugin.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 "KsPlugin.h"
/**
* This is the factory that is called by KsProxy when it sees a driver
* publish the interface that we've "latched" on to.
*
* @param p_unknown IUnknown* passed by KsProxy
* @param p_hr pointer to hold result
*
* @return pointer to new instance created by this factory
*/
CUnknown*
WINAPI
CKsPlugin::CreateInstance(IUnknown* p_unknown, HRESULT* p_hr)
{
CKsPlugin* p_plugin = new CKsPlugin(p_unknown, p_hr);
if (p_plugin == 0)
{
*p_hr = E_OUTOFMEMORY;
}
return p_plugin;
}
//**********************************************************************
CKsPlugin::CKsPlugin(LPUNKNOWN p_unknown, HRESULT* p_hr):
CUnknown(TEXT("CpNotify"),p_unknown),
_p_unknown(p_unknown),
_thread_handle(0),
_p_base_filter(0),
_ref_count(0)
{
DbgLog((LOG_TRACE, 0, TEXT("Constructing copy protection notification filter"))) ;
ASSERT(p_hr != 0);
_event_handle = CreateEvent(
NULL, // no security attributes
FALSE, // auto reset
FALSE, // initial state not signaled
NULL // no object name
);
*p_hr = NOERROR;
}
//**********************************************************************
CKsPlugin::~CKsPlugin()
{
DbgLog((LOG_TRACE, 0, TEXT("Destroying copy protection notification filter"))) ;
if (_p_base_filter)
{
_p_base_filter->Release();
}
}
//**********************************************************************
HRESULT
CKsPlugin::createThread()
{
HRESULT hr = NOERROR;
if (_thread_handle == 0)
{
_p_cp_notify = new CCopyProtection(_p_base_filter);
if(!_p_cp_notify)
{
return E_OUTOFMEMORY;
}
_p_cp_notify->createFilterList();
_thread_handle = ::CreateThread (0,0,threadFunctionWrapper, this,0,0);
if (_thread_handle == NULL)
{
delete _p_cp_notify;
_p_cp_notify = 0;
hr = HRESULT_FROM_WIN32 (GetLastError());
return hr;
}
}
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CKsPlugin::threadFunction (
void
)
{
HRESULT hr = NOERROR;
while(true)
{
_p_cp_notify->broadcastStatus();
// The following will wait for up to the timeout specified in ms
// or until the event is signaled
DWORD wake_reason = WaitForSingleObject(_event_handle, 500);
if (wake_reason != WAIT_TIMEOUT)
{
// Event was signalled or destroyed. Either way, gotta go.
break;
}
}
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////
DWORD
WINAPI
CKsPlugin::threadFunctionWrapper (
LPVOID p_param
)
{
CKsPlugin* pThread;
pThread = reinterpret_cast<CKsPlugin*>(p_param);
return pThread->threadFunction ();
}
////////////////////////////////////////////////////////////////////////////////////////////
void
CKsPlugin::exitThread(
)
{
SetEvent(_event_handle);
WaitForSingleObject(_thread_handle, INFINITE);
::CloseHandle(_thread_handle);
_thread_handle = 0;
if(_p_cp_notify)
{
_p_cp_notify->destroyFilterList();
delete _p_cp_notify;
_p_cp_notify = 0;
}
}
void DumpGuid(REFIID riid)
{
DbgLog((LOG_TRACE,
0,
TEXT("GUID {%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x}"),
riid.Data1,
riid.Data2,
riid.Data3,
riid.Data4[0],
riid.Data4[1],
riid.Data4[2],
riid.Data4[3],
riid.Data4[4],
riid.Data4[5],
riid.Data4[6],
riid.Data4[7]
)) ;
}
HRESULT STDMETHODCALLTYPE CKsPlugin::NonDelegatingQueryInterface(REFIID riid, void** ppv)
{
CheckPointer(ppv,E_POINTER);
// Uncomment to see what interfaces we're being asked about.
// It's how I found out about IDistributorNotify :)
//DumpGuid(riid);
if (riid == IID_IDistributorNotify) {
return GetInterface(static_cast<IDistributorNotify*>(this), ppv);
}
return CUnknown::NonDelegatingQueryInterface(riid, ppv);
}
ULONG STDMETHODCALLTYPE CKsPlugin::NonDelegatingAddRef()
{
_ref_count++;
DbgLog((LOG_TRACE, 0, TEXT("AddRef ... {%d}"), _ref_count)) ;
return CUnknown::NonDelegatingAddRef();
}
ULONG STDMETHODCALLTYPE CKsPlugin::NonDelegatingRelease()
{
_ref_count--;
DbgLog((LOG_TRACE, 0, TEXT("Release ... {%d}"), _ref_count)) ;
return CUnknown::NonDelegatingRelease();
}
HRESULT
CKsPlugin::Run (
REFERENCE_TIME start_time
)
{
HRESULT hr = _p_unknown->QueryInterface(
IID_IBaseFilter,
reinterpret_cast<PVOID*>(&_p_base_filter)
);
if(_p_base_filter==0)
{
// interface accessed before base filter was initialized
return hr;
}
// start thread here and stop it in Stop
createThread();
return hr;
}
HRESULT
CKsPlugin::Stop (
void
)
{
HRESULT hr = NOERROR;
if(_p_base_filter==0)
{
// interface accessed before base filter was initialized
return hr;
}
exitThread();
_p_base_filter->Release();
_p_base_filter = 0;
return hr;
}
HRESULT
CKsPlugin::NotifyGraphChange (
void
)
{
return NOERROR;
}
HRESULT
CKsPlugin::Pause (
void
)
{
return NOERROR;
}
HRESULT
CKsPlugin::SetSyncSource (
IReferenceClock* p_clock
)
{
return NOERROR;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -