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

📄 nscstiu.cpp

📁 美国国家半导体公司的扫描仪芯片LM9833的驱动程序。
💻 CPP
字号:
/*******************************************************************************
 *	@doc
 *
 *  @module NSCSTIU.cpp | 
 *
 *	This module contains 
 *		- DLL level entry point and helper functions 
 *		- The <o UsdNSCClassFactory> COM object defintion & implementation
 *		- The IUnknown methods of the <o UsdNSCDevice> object
 *
 *  Copyright (c) National Semiconductor Corporation 1999-2000
 *  All rights reserved
 *
 ******************************************************************************/

#define INITGUID

#include "NSCSTIU.h"
#include "NscDevice.h"
#include "resource.h"

//------------------------------------------------------------------------------
//	Global Variables 
//------------------------------------------------------------------------------

// Reference counter for the whole library used to implement 
// DLL/COM server wide reference counting 
DWORD       g_cRef;

// DLL module instance - passed into the entry point method
HINSTANCE   g_hInst;

// Critical section used for DLL wide, low level syncronization
CRITICAL_SECTION g_crstDll;



/*****************************************************************************
 *
 *  @doc    INTERNAL
 *
 *  @func   void | DllAddRef |
 *
 *          Increment the reference count on the DLL.
 *
 *****************************************************************************/

void
DllAddRef(void)
{
    InterlockedIncrement((LPLONG)&g_cRef);
}

/*****************************************************************************
 *
 *  @doc    INTERNAL
 *
 *  @func   void | DllRelease |
 *
 *          Decrement the reference count on the DLL.
 *
 *****************************************************************************/

void
DllRelease(void)
{
    InterlockedDecrement((LPLONG)&g_cRef);
}


//
// 
//   @object UsdNSCClassFactory | 
// 
//

class UsdNSCClassFactory : public IClassFactory
{
private:
    ULONG   m_cRef;

public:
    STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv);
    STDMETHODIMP_(ULONG) AddRef(void);
    STDMETHODIMP_(ULONG) Release(void);

    STDMETHODIMP CreateInstance(
            /* [unique][in] */ IUnknown __RPC_FAR *pUnkOuter,
            /* [in] */ REFIID riid,
            /* [out] */ void __RPC_FAR *__RPC_FAR *ppvObject);

    STDMETHODIMP LockServer(
            /* [in] */ BOOL fLock);

    UsdNSCClassFactory();
};

UsdNSCClassFactory::UsdNSCClassFactory()
{
    // Constructor logic
    m_cRef = 0;
}


STDMETHODIMP UsdNSCClassFactory::QueryInterface(
    /* [in] */ REFIID riid,
    /* [out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
{
    *ppvObject = NULL;

    if (IsEqualIID(riid, IID_IUnknown) ||
        IsEqualIID(riid, IID_IClassFactory)) {
        *ppvObject = (LPVOID)this;
        AddRef();
        return NOERROR;
    }
    return ResultFromScode(E_NOINTERFACE);
}


STDMETHODIMP_(ULONG) UsdNSCClassFactory::AddRef(void)
{
    DllAddRef();
    return ++m_cRef;
}


STDMETHODIMP_(ULONG) UsdNSCClassFactory::Release(void)
{
    DllRelease();
    if (--m_cRef == 0) {
        delete this;
        return 0;
    }
    return m_cRef;
}


STDMETHODIMP UsdNSCClassFactory::CreateInstance(
    /* [unique][in] */ IUnknown __RPC_FAR *punkOuter,
    /* [in] */ REFIID riid,
    /* [out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
{

    if (!IsEqualIID(riid, IID_IStiUSD) &&
        !IsEqualIID(riid, IID_IUnknown)) {
        return STIERR_NOINTERFACE;
    }

    // When created for aggregation, only IUnknown can be requested, so fail
    // call if not.
    if (punkOuter && !IsEqualIID(riid, IID_IUnknown)) {
        return CLASS_E_NOAGGREGATION;
    }

    UsdNSCDevice    *pDev = NULL;
    HRESULT         hres;

    pDev = new UsdNSCDevice(punkOuter);
    if (!pDev) {
        return STIERR_OUTOFMEMORY;
    }

    //
    // Move to the requested interface
    //
    hres = pDev->NonDelegatingQueryInterface(riid,ppvObject);
    pDev->NonDelegatingRelease();

    return hres;
}


STDMETHODIMP UsdNSCClassFactory::LockServer(
    /* [in] */ BOOL fLock)
{
    if (fLock) {
        DllAddRef();
    } else {
        DllRelease();
    }

    return NOERROR;
}

/*****************************************************************************
 *
 *  @class UsdNSCDevice | INonDelegatingUnknown
 *
 *****************************************************************************/
STDMETHODIMP UsdNSCDevice::NonDelegatingQueryInterface( REFIID riid, LPVOID* ppvObj )
{
    HRESULT hres;

    if( !IsValid() || !ppvObj )
    {
        return STIERR_INVALID_PARAM;
    }

    *ppvObj = NULL;

    if( IsEqualIID( riid, IID_IUnknown ))
    {
        *ppvObj = static_cast<INonDelegatingUnknown*>(this);
        hres = S_OK;
    }
    else if( IsEqualIID( riid, IID_IStiUSD ))
    {
        *ppvObj = static_cast<IStiUSD*>(this);
        hres = S_OK;
    }
    else
    {
        hres =  STIERR_NOINTERFACE;
    }

    if (SUCCEEDED(hres)) {
        (reinterpret_cast<IUnknown*>(*ppvObj))->AddRef();
    }

    return hres;
}


STDMETHODIMP_(ULONG) UsdNSCDevice::NonDelegatingAddRef( VOID )
{
    ULONG ulRef;
    ulRef = InterlockedIncrement((LPLONG)&m_cRef);
    return ulRef;
}

STDMETHODIMP_(ULONG) UsdNSCDevice::NonDelegatingRelease( VOID )
{
    ULONG ulRef;
    ulRef = InterlockedDecrement((LPLONG)&m_cRef);

    if(!ulRef)
    {
        delete this;
    }

    return ulRef;
}

/*****************************************************************************
 *
 *  @class UsdNSCDevice | IUnknown (Delegating)
 *
 *         Delegating unknown methods.
 *
 *****************************************************************************/

STDMETHODIMP UsdNSCDevice::QueryInterface( REFIID riid, LPVOID* ppvObj )
{
    return m_punkOuter->QueryInterface(riid,ppvObj);
}


STDMETHODIMP_(ULONG) UsdNSCDevice::AddRef( VOID )
{
    return m_punkOuter->AddRef();
}

STDMETHODIMP_(ULONG) UsdNSCDevice::Release( VOID )
{
    return m_punkOuter->Release();
}


/*****************************************************************************
 *  @func   Called to notify the DLL whenever a process or thead attaches 
 			to this dll
 *
 *
 *  @rdesc
 *
 *          Returns <c TRUE> to allow the DLL to load.
 *	@comm
*          We are not interested in thread attaches and detaches,
 *          so we disable thread notifications for performance reasons.
 
 *****************************************************************************/


extern "C" DLLEXPORT BOOL APIENTRY DllEntryPoint(
HINSTANCE hinst,	// @parm The instance handle of this DLL.
DWORD dwReason,		// @parm The context notification code which 
					// lets us know why this function is being called 
LPVOID lpReserved	// @parm Not used 
)
{
    switch (dwReason) {
        case DLL_PROCESS_ATTACH:

        g_hInst = hinst;

        // Disable thread library calls to avoid
        // deadlock when we spin up the worker thread

        DisableThreadLibraryCalls(hinst);
        InitializeCriticalSection(&g_crstDll);

        // Set global flags
        // g_NoUnicodePlatform = !OSUtil_IsPlatformUnicode();

        break;

    case DLL_PROCESS_DETACH:
        if (g_cRef) {
            // DPRINTF("NSStiUSD: Unloaded before all objects Release()d! Crash soon!\r\n");
        }

        // Free COM libraries if connected to them
        // DllUnInitializeCOM();

        break;
    }

    return 1;
}


extern "C"
DLLEXPORT
BOOL WINAPI
DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID lpReserved)
{
    return DllEntryPoint(hinst, dwReason, lpReserved);
}

/*****************************************************************************
 *
 *  @doc    INTERNAL
 *
 *  @func   HRESULT | DllCanUnloadNow |
 *
 *          Determine whether the DLL has any outstanding interfaces.
 *
 *  @rdesc
 *
 *          Returns <c S_OK> if the DLL can unload, <c S_FALSE> if
 *          it is not safe to unload.
 *
 *****************************************************************************/
extern "C"
STDMETHODIMP
DllCanUnloadNow(void)
{
    HRESULT hres;

    hres = g_cRef ? S_FALSE : S_OK;

    return hres;
}

/*****************************************************************************
 *
 *  @doc    INTERNAL
 *
 *  @func   HRESULT | DllGetClassObject |
 *
 *          Create an <i IClassFactory> instance for this DLL.
 *
 *  @parm   REFCLSID | rclsid |
 *
 *          The object being requested.
 *
 *  @parm   RIID | riid |
 *
 *          The desired interface on the object.
 *
 *  @parm   PPV | ppvOut |
 *
 *          Output pointer.
 *
 *  @comm
 *          We support only one class of objects , so this function does not need
 *          to go through table of supported classes , looking for proper constructor
 *
 *
 *****************************************************************************/
extern "C"
STDAPI DllGetClassObject(
    REFCLSID    rclsid,
    REFIID      riid,
    LPVOID      *ppv)
{

    if (!ppv) {
        return ResultFromScode(E_FAIL);
    }

    if (!IsEqualCLSID(rclsid, CLSID_NSCStiUObj) ) {
        return ResultFromScode(E_FAIL);
    }

    if (!IsEqualIID(riid, IID_IUnknown) &&
        !IsEqualIID(riid, IID_IClassFactory)) {
        return ResultFromScode(E_NOINTERFACE);
    }

    if (IsEqualCLSID(rclsid, CLSID_NSCStiUObj)) {
        UsdNSCClassFactory *pcf = new UsdNSCClassFactory;
        if (pcf) {
            *ppv = (LPVOID)pcf;
        }
    }

    return NOERROR;
}




⌨️ 快捷键说明

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