📄 nscstiu.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 + -