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

📄 ksplugin.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 "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 + -