317 lines
6.2 KiB
C++
317 lines
6.2 KiB
C++
|
/***************************************************************************
|
||
|
*
|
||
|
* Copyright (C) 1998-2001 Microsoft Corporation. All Rights Reserved.
|
||
|
*
|
||
|
* File: dpnhupnpclassfac.cpp
|
||
|
*
|
||
|
* Content: a generic class factory.
|
||
|
*
|
||
|
*
|
||
|
* This is a generic C++ class factory. All you need to do is implement
|
||
|
* a function called DoCreateInstance that will create an instance of
|
||
|
* your object.
|
||
|
*
|
||
|
* GP_ stands for "General Purpose"
|
||
|
*
|
||
|
*
|
||
|
* History:
|
||
|
* Date By Reason
|
||
|
* ======== ======== =========
|
||
|
* 10/13/98 jwo Created it.
|
||
|
* 04/08/01 vanceo Converted to C++.
|
||
|
* 04/16/01 VanceO Split DPNATHLP into DPNHUPNP and DPNHPAST.
|
||
|
*
|
||
|
***************************************************************************/
|
||
|
|
||
|
|
||
|
#include "dpnhupnpi.h"
|
||
|
|
||
|
|
||
|
|
||
|
#ifdef __MWERKS__
|
||
|
#define EXP __declspec(dllexport)
|
||
|
#else
|
||
|
#define EXP
|
||
|
#endif
|
||
|
|
||
|
|
||
|
//**********************************************************************
|
||
|
// Constant definitions
|
||
|
//**********************************************************************
|
||
|
|
||
|
//**********************************************************************
|
||
|
// Macro definitions
|
||
|
//**********************************************************************
|
||
|
|
||
|
//**********************************************************************
|
||
|
// Structure definitions
|
||
|
//**********************************************************************
|
||
|
|
||
|
//
|
||
|
// class factory class definition
|
||
|
//
|
||
|
typedef class GPClassFactory:public IClassFactory
|
||
|
{
|
||
|
public:
|
||
|
GPClassFactory(const CLSID * pclsid) { m_dwRefCnt = 0; memcpy(&m_clsid, pclsid, sizeof(CLSID)); };
|
||
|
~GPClassFactory(void) {};
|
||
|
|
||
|
|
||
|
STDMETHODIMP QueryInterface(REFIID riid, LPVOID * ppvObj);
|
||
|
STDMETHODIMP_(ULONG) AddRef(void);
|
||
|
STDMETHODIMP_(ULONG) Release(void);
|
||
|
STDMETHODIMP CreateInstance(IUnknown * pUnkOuter, REFIID riid, void ** ppvObject);
|
||
|
STDMETHODIMP LockServer(BOOL fLock);
|
||
|
|
||
|
|
||
|
private:
|
||
|
DWORD m_dwRefCnt;
|
||
|
CLSID m_clsid;
|
||
|
} GPCLASSFACTORY, *LPGPCLASSFACTORY;
|
||
|
|
||
|
|
||
|
//
|
||
|
// function prototype for CoLockObjectExternal()
|
||
|
//
|
||
|
typedef HRESULT (WINAPI * PCOLOCKOBJECTEXTERNAL)(LPUNKNOWN, BOOL, BOOL );
|
||
|
|
||
|
//**********************************************************************
|
||
|
// Variable definitions
|
||
|
//**********************************************************************
|
||
|
|
||
|
//
|
||
|
// count of outstanding COM interfaces, defined in dpnathlpdllmain.cpp
|
||
|
//
|
||
|
extern volatile LONG g_lOutstandingInterfaceCount;
|
||
|
|
||
|
|
||
|
|
||
|
//**********************************************************************
|
||
|
// Function prototypes
|
||
|
//**********************************************************************
|
||
|
|
||
|
|
||
|
//**********************************************************************
|
||
|
// Function definitions
|
||
|
//**********************************************************************
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* GPClassFactory::QueryInterface
|
||
|
*/
|
||
|
STDMETHODIMP GPClassFactory::QueryInterface(
|
||
|
REFIID riid,
|
||
|
LPVOID *ppvObj )
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
|
||
|
*ppvObj = NULL;
|
||
|
|
||
|
|
||
|
if( IsEqualIID(riid, IID_IClassFactory) ||
|
||
|
IsEqualIID(riid, IID_IUnknown))
|
||
|
{
|
||
|
this->m_dwRefCnt++;
|
||
|
*ppvObj = this;
|
||
|
hr = S_OK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = E_NOINTERFACE;
|
||
|
}
|
||
|
|
||
|
|
||
|
return hr;
|
||
|
|
||
|
} /* GPClassFactory::QueryInterface */
|
||
|
|
||
|
|
||
|
/*
|
||
|
* GPClassFactory::AddRef
|
||
|
*/
|
||
|
STDMETHODIMP_(ULONG) GPClassFactory::AddRef( void )
|
||
|
{
|
||
|
this->m_dwRefCnt++;
|
||
|
return this->m_dwRefCnt;
|
||
|
} /* GPClassFactory::AddRef */
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* GPClassFactory::Release
|
||
|
*/
|
||
|
STDMETHODIMP_(ULONG) GPClassFactory::Release( void )
|
||
|
{
|
||
|
this->m_dwRefCnt--;
|
||
|
|
||
|
if( this->m_dwRefCnt != 0 )
|
||
|
{
|
||
|
return this->m_dwRefCnt;
|
||
|
}
|
||
|
|
||
|
delete this;
|
||
|
return 0;
|
||
|
|
||
|
} /* GPClassFactory::Release */
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* GPClassFactory::CreateInstance
|
||
|
*
|
||
|
* Creates an instance of the object
|
||
|
*/
|
||
|
STDMETHODIMP GPClassFactory::CreateInstance(
|
||
|
LPUNKNOWN pUnkOuter,
|
||
|
REFIID riid,
|
||
|
LPVOID *ppvObj
|
||
|
)
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
if( pUnkOuter != NULL )
|
||
|
{
|
||
|
return CLASS_E_NOAGGREGATION;
|
||
|
}
|
||
|
|
||
|
*ppvObj = NULL;
|
||
|
|
||
|
|
||
|
/*
|
||
|
* create the object by calling DoCreateInstance. This function
|
||
|
* must be implemented specifically for your COM object
|
||
|
*/
|
||
|
hr = DoCreateInstance(this, pUnkOuter, this->m_clsid, riid, ppvObj);
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
*ppvObj = NULL;
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
|
||
|
} /* GPClassFactory::CreateInstance */
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* GPClassFactory::LockServer
|
||
|
*
|
||
|
* Called to force our DLL to stayed loaded
|
||
|
*/
|
||
|
STDMETHODIMP GPClassFactory::LockServer(
|
||
|
BOOL fLock
|
||
|
)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
HINSTANCE hdll;
|
||
|
|
||
|
|
||
|
/*
|
||
|
* call CoLockObjectExternal
|
||
|
*/
|
||
|
hr = E_UNEXPECTED;
|
||
|
hdll = LoadLibrary( _T("OLE32.DLL") );
|
||
|
if( hdll != NULL )
|
||
|
{
|
||
|
PCOLOCKOBJECTEXTERNAL lpCoLockObjectExternal;
|
||
|
|
||
|
|
||
|
lpCoLockObjectExternal = reinterpret_cast<PCOLOCKOBJECTEXTERNAL>( GetProcAddress( hdll, _TWINCE("CoLockObjectExternal") ) );
|
||
|
if( lpCoLockObjectExternal != NULL )
|
||
|
{
|
||
|
hr = lpCoLockObjectExternal( (LPUNKNOWN) this, fLock, TRUE );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
|
||
|
} /* GPClassFactory::LockServer */
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* DllGetClassObject
|
||
|
*
|
||
|
* Entry point called by COM to get a ClassFactory pointer
|
||
|
*/
|
||
|
EXP STDAPI DllGetClassObject(
|
||
|
REFCLSID rclsid,
|
||
|
REFIID riid,
|
||
|
LPVOID *ppvObj )
|
||
|
{
|
||
|
LPGPCLASSFACTORY pcf;
|
||
|
HRESULT hr;
|
||
|
|
||
|
*ppvObj = NULL;
|
||
|
|
||
|
/*
|
||
|
* is this our class id?
|
||
|
*/
|
||
|
// you must implement GetClassID() for your specific COM object
|
||
|
if (!IsClassImplemented(rclsid))
|
||
|
{
|
||
|
return CLASS_E_CLASSNOTAVAILABLE;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* only allow IUnknown and IClassFactory
|
||
|
*/
|
||
|
if( !IsEqualIID( riid, IID_IUnknown ) &&
|
||
|
!IsEqualIID( riid, IID_IClassFactory ) )
|
||
|
{
|
||
|
return E_NOINTERFACE;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* create a class factory object
|
||
|
*/
|
||
|
pcf = new GPClassFactory(&rclsid);
|
||
|
if( NULL == pcf)
|
||
|
{
|
||
|
return E_OUTOFMEMORY;
|
||
|
}
|
||
|
|
||
|
hr = pcf->QueryInterface( riid, ppvObj );
|
||
|
if( FAILED( hr ) )
|
||
|
{
|
||
|
delete pcf;
|
||
|
*ppvObj = NULL;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
|
||
|
} /* DllGetClassObject */
|
||
|
|
||
|
/*
|
||
|
* DllCanUnloadNow
|
||
|
*
|
||
|
* Entry point called by COM to see if it is OK to free our DLL
|
||
|
*/
|
||
|
EXP STDAPI DllCanUnloadNow( void )
|
||
|
{
|
||
|
HRESULT hr = S_FALSE;
|
||
|
|
||
|
|
||
|
if ( g_lOutstandingInterfaceCount == 0 )
|
||
|
{
|
||
|
hr = S_OK;
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
|
||
|
} /* DllCanUnloadNow */
|
||
|
|