home *** CD-ROM | disk | FTP | other *** search
- // This is a part of the Microsoft Foundation Classes C++ library.
- // Copyright (C) 1992-1998 Microsoft Corporation
- // All rights reserved.
- //
- // This source code is only intended as a supplement to the
- // Microsoft Foundation Classes Reference and related
- // electronic documentation provided with the library.
- // See these sources for detailed information regarding the
- // Microsoft Foundation Classes product.
-
- #include "stdafx.h"
-
- #ifdef AFX_OLE3_SEG
- #pragma code_seg(AFX_OLE3_SEG)
- #endif
-
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
-
- #define new DEBUG_NEW
-
- /////////////////////////////////////////////////////////////////////////////
- // COleObjectFactory implementation
-
- BEGIN_INTERFACE_MAP(COleObjectFactory, CCmdTarget)
- INTERFACE_PART(COleObjectFactory, IID_IClassFactory, ClassFactory)
- INTERFACE_PART(COleObjectFactory, IID_IClassFactory2, ClassFactory)
- END_INTERFACE_MAP()
-
- #ifdef AFX_INIT_SEG
- #pragma code_seg(AFX_INIT_SEG)
- #endif
-
- COleObjectFactory::COleObjectFactory(REFCLSID clsid,
- CRuntimeClass* pRuntimeClass, BOOL bMultiInstance, LPCTSTR lpszProgID)
- {
- ASSERT(pRuntimeClass == NULL ||
- pRuntimeClass->IsDerivedFrom(RUNTIME_CLASS(CCmdTarget)));
- ASSERT(AfxIsValidAddress(&clsid, sizeof(CLSID), FALSE));
- ASSERT(lpszProgID == NULL || AfxIsValidString(lpszProgID));
-
- // initialize to unregistered state
- m_dwRegister = 0; // not registered yet
- m_bRegistered = FALSE;
- m_clsid = clsid;
- m_pRuntimeClass = pRuntimeClass;
- m_bMultiInstance = bMultiInstance;
- m_lpszProgID = lpszProgID;
- m_bOAT = (BYTE) OAT_UNKNOWN;
-
- // licensing information
- m_bLicenseChecked = FALSE;
- m_bLicenseValid = FALSE;
-
- // add this factory to the list of factories
- m_pNextFactory = NULL;
- AFX_MODULE_STATE* pModuleState = _AFX_CMDTARGET_GETSTATE();
- AfxLockGlobals(CRIT_OBJECTFACTORYLIST);
- pModuleState->m_factoryList.AddHead(this);
- AfxUnlockGlobals(CRIT_OBJECTFACTORYLIST);
-
- ASSERT_VALID(this);
- }
-
- #ifdef AFX_TERM_SEG
- #pragma code_seg(AFX_TERM_SEG)
- #endif
-
- COleObjectFactory::~COleObjectFactory()
- {
- ASSERT_VALID(this);
-
- #ifdef _AFXDLL
- if (m_pModuleState == NULL)
- return;
- #endif
-
- // deregister this class factory
- Revoke();
-
- // remove this class factory from the list of active class factories
- #ifdef _AFXDLL
- AFX_MODULE_STATE* pModuleState = m_pModuleState;
- #else
- AFX_MODULE_STATE* pModuleState = _AFX_CMDTARGET_GETSTATE();
- #endif
- AfxLockGlobals(CRIT_OBJECTFACTORYLIST);
- BOOL bResult = pModuleState->m_factoryList.Remove(this);
- AfxUnlockGlobals(CRIT_OBJECTFACTORYLIST);
- if (bResult)
- return;
-
- // check CDynLinkLibrary objects in case it was transfered during init
- #ifdef _AFXDLL
- AfxLockGlobals(CRIT_DYNLINKLIST);
- for (CDynLinkLibrary* pDLL = pModuleState->m_libraryList; pDLL != NULL;
- pDLL = pDLL->m_pNextDLL)
- {
- if (pDLL->m_factoryList.Remove(this))
- {
- AfxUnlockGlobals(CRIT_DYNLINKLIST);
- return;
- }
- }
- AfxUnlockGlobals(CRIT_DYNLINKLIST);
- #endif
- }
-
- #ifdef AFX_INIT_SEG
- #pragma code_seg(AFX_INIT_SEG)
- #endif
-
- BOOL COleObjectFactory::Unregister()
- {
- return TRUE;
- }
-
- BOOL COleObjectFactory::Register()
- {
- ASSERT_VALID(this);
- ASSERT(!m_bRegistered); // registering server/factory twice?
- ASSERT(m_clsid != CLSID_NULL);
-
- if (!afxContextIsDLL)
- {
- // In the application variants, the IClassFactory is registered
- // with the OLE DLLs.
-
- SCODE sc = ::CoRegisterClassObject(m_clsid, &m_xClassFactory,
- CLSCTX_LOCAL_SERVER,
- m_bMultiInstance ? REGCLS_SINGLEUSE : REGCLS_MULTIPLEUSE,
- &m_dwRegister);
- if (sc != S_OK)
- {
- #ifdef _DEBUG
- TRACE1("Warning: CoRegisterClassObject failed scode = %s.\n",
- ::AfxGetFullScodeString(sc));
- #endif
- // registration failed.
- return FALSE;
- }
- ASSERT(m_dwRegister != 0);
- }
-
- ++m_bRegistered;
- return TRUE;
- }
-
- BOOL PASCAL COleObjectFactory::UnregisterAll()
- {
- BOOL bResult = TRUE;
- // register application factories
- AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
- AfxLockGlobals(CRIT_OBJECTFACTORYLIST);
- for (COleObjectFactory* pFactory = pModuleState->m_factoryList;
- pFactory != NULL; pFactory = pFactory->m_pNextFactory)
- {
- // unregister any registered, non-doctemplate factories
- if (pFactory->IsRegistered() && !pFactory->Unregister())
- {
- bResult = FALSE;
- }
- }
- AfxUnlockGlobals(CRIT_OBJECTFACTORYLIST);
- return bResult;
- }
-
- BOOL PASCAL COleObjectFactory::RegisterAll()
- {
- BOOL bResult = TRUE;
- // register application factories
- AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
- AfxLockGlobals(CRIT_OBJECTFACTORYLIST);
- for (COleObjectFactory* pFactory = pModuleState->m_factoryList;
- pFactory != NULL; pFactory = pFactory->m_pNextFactory)
- {
- // register any non-registered, non-doctemplate factories
- if (!pFactory->IsRegistered() &&
- pFactory->m_clsid != CLSID_NULL && !pFactory->Register())
- {
- bResult = FALSE;
- }
- }
- AfxUnlockGlobals(CRIT_OBJECTFACTORYLIST);
- #ifdef _AFXDLL
- // register extension DLL factories
- AfxLockGlobals(CRIT_DYNLINKLIST);
- for (CDynLinkLibrary* pDLL = pModuleState->m_libraryList; pDLL != NULL;
- pDLL = pDLL->m_pNextDLL)
- {
- for (pFactory = pDLL->m_factoryList;
- pFactory != NULL; pFactory = pFactory->m_pNextFactory)
- {
- // register any non-registered, non-doctemplate factories
- if (!pFactory->IsRegistered() &&
- pFactory->m_clsid != CLSID_NULL && !pFactory->Register())
- {
- bResult = FALSE;
- }
- }
- }
- AfxUnlockGlobals(CRIT_DYNLINKLIST);
- #endif
- return bResult;
- }
-
- #ifdef AFX_TERM_SEG
- #pragma code_seg(AFX_TERM_SEG)
- #endif
-
- void COleObjectFactory::Revoke()
- {
- ASSERT_VALID(this);
-
- if (m_bRegistered)
- {
- // revoke the registration of the class itself
- if (m_dwRegister != 0)
- {
- ::CoRevokeClassObject(m_dwRegister);
- m_dwRegister = 0;
- }
- m_bRegistered = FALSE;
- }
- }
-
- void PASCAL COleObjectFactory::RevokeAll()
- {
- AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
- AfxLockGlobals(CRIT_OBJECTFACTORYLIST);
- for (COleObjectFactory* pFactory = pModuleState->m_factoryList;
- pFactory != NULL; pFactory = pFactory->m_pNextFactory)
- {
- pFactory->Revoke();
- }
- AfxUnlockGlobals(CRIT_OBJECTFACTORYLIST);
- #ifdef _AFXDLL
- AfxLockGlobals(CRIT_DYNLINKLIST);
- // register extension DLL factories
- for (CDynLinkLibrary* pDLL = pModuleState->m_libraryList; pDLL != NULL;
- pDLL = pDLL->m_pNextDLL)
- {
- for (pFactory = pDLL->m_factoryList;
- pFactory != NULL; pFactory = pFactory->m_pNextFactory)
- {
- pFactory->Revoke();
- }
- }
- AfxUnlockGlobals(CRIT_DYNLINKLIST);
- #endif
- }
-
- #ifdef AFX_OLE3_SEG
- #pragma code_seg(AFX_OLE3_SEG)
- #endif
-
- void COleObjectFactory::UpdateRegistry(LPCTSTR lpszProgID)
- {
- ASSERT_VALID(this);
- ASSERT(lpszProgID == NULL || AfxIsValidString(lpszProgID));
-
- // use default prog-id if specific prog-id not given
- if (lpszProgID == NULL)
- {
- lpszProgID = m_lpszProgID;
- if (lpszProgID == NULL) // still no valid progID?
- return;
- }
-
- // call global helper to modify system registry
- // (progid, shortname, and long name are all equal in this case)
- AfxOleRegisterServerClass(m_clsid, lpszProgID, lpszProgID, lpszProgID,
- OAT_DISPATCH_OBJECT);
- }
-
- BOOL PASCAL COleObjectFactory::UpdateRegistryAll(BOOL bRegister)
- {
- AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
- AfxLockGlobals(CRIT_OBJECTFACTORYLIST);
- for (COleObjectFactory* pFactory = pModuleState->m_factoryList;
- pFactory != NULL; pFactory = pFactory->m_pNextFactory)
- {
- if (!pFactory->UpdateRegistry(bRegister))
- {
- AfxUnlockGlobals(CRIT_OBJECTFACTORYLIST);
- return FALSE;
- }
- }
- AfxUnlockGlobals(CRIT_OBJECTFACTORYLIST);
- #ifdef _AFXDLL
- AfxLockGlobals(CRIT_DYNLINKLIST);
- // register extension DLL factories
- for (CDynLinkLibrary* pDLL = pModuleState->m_libraryList; pDLL != NULL;
- pDLL = pDLL->m_pNextDLL)
- {
- for (pFactory = pDLL->m_factoryList;
- pFactory != NULL; pFactory = pFactory->m_pNextFactory)
- {
- if (!pFactory->UpdateRegistry(bRegister))
- {
- AfxUnlockGlobals(CRIT_DYNLINKLIST);
- return FALSE;
- }
- }
- }
- AfxUnlockGlobals(CRIT_DYNLINKLIST);
- #endif
-
- return TRUE;
- }
-
- CCmdTarget* COleObjectFactory::OnCreateObject()
- {
- ASSERT_VALID(this);
- ASSERT(AfxIsValidAddress(m_pRuntimeClass, sizeof(CRuntimeClass), FALSE));
- // this implementation needs a runtime class
-
- // allocate object, throw exception on failure
- CCmdTarget* pTarget = (CCmdTarget*)m_pRuntimeClass->CreateObject();
- if (pTarget == NULL)
- AfxThrowMemoryException();
-
- // make sure it is a CCmdTarget
- ASSERT_KINDOF(CCmdTarget, pTarget);
- ASSERT_VALID(pTarget);
-
- // return the new CCmdTarget object
- return pTarget;
- }
-
- BOOL COleObjectFactory::IsLicenseValid()
- {
- if (!m_bLicenseChecked)
- {
- m_bLicenseValid = (BYTE)VerifyUserLicense();
- m_bLicenseChecked = TRUE;
- }
- return m_bLicenseValid;
- }
-
- BOOL COleObjectFactory::UpdateRegistry(BOOL bRegister)
- {
- if (bRegister)
- UpdateRegistry(); // will register with default m_lpszProgID
-
- return TRUE;
- }
-
- BOOL COleObjectFactory::VerifyUserLicense()
- {
- // May be overridden by subclass
- return TRUE;
- }
-
- BOOL COleObjectFactory::GetLicenseKey(DWORD, BSTR*)
- {
- // May be overridden by subclass
- return FALSE;
- }
-
- BOOL COleObjectFactory::VerifyLicenseKey(BSTR bstrKey)
- {
- // May be overridden by subclass
-
- BOOL bLicensed = FALSE;
- BSTR bstr = NULL;
-
- if ((bstrKey != NULL) && GetLicenseKey(0, &bstr))
- {
- ASSERT(bstr != NULL);
-
- // if length and content match, it's good!
-
- UINT cch = SysStringByteLen(bstr);
- if ((cch == SysStringByteLen(bstrKey)) &&
- (memcmp(bstr, bstrKey, cch) == 0))
- {
- bLicensed = TRUE;
- }
-
- SysFreeString(bstr);
- }
-
- return bLicensed;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // Implementation of COleObjectFactory::IClassFactory interface
-
- STDMETHODIMP_(ULONG) COleObjectFactory::XClassFactory::AddRef()
- {
- METHOD_PROLOGUE_EX_(COleObjectFactory, ClassFactory)
- return pThis->InternalAddRef();
- }
-
- STDMETHODIMP_(ULONG) COleObjectFactory::XClassFactory::Release()
- {
- METHOD_PROLOGUE_EX_(COleObjectFactory, ClassFactory)
- return pThis->InternalRelease();
- }
-
- STDMETHODIMP COleObjectFactory::XClassFactory::QueryInterface(
- REFIID iid, LPVOID* ppvObj)
- {
- METHOD_PROLOGUE_EX_(COleObjectFactory, ClassFactory)
- return pThis->InternalQueryInterface(&iid, ppvObj);
- }
-
- STDMETHODIMP COleObjectFactory::XClassFactory::CreateInstance(
- IUnknown* pUnkOuter, REFIID riid, LPVOID* ppvObject)
- {
- return CreateInstanceLic(pUnkOuter, NULL, riid, NULL, ppvObject);
- }
-
- STDMETHODIMP COleObjectFactory::XClassFactory::LockServer(BOOL fLock)
- {
- METHOD_PROLOGUE_EX(COleObjectFactory, ClassFactory)
- ASSERT_VALID(pThis);
-
- SCODE sc = E_UNEXPECTED;
- TRY
- {
- if (fLock)
- AfxOleLockApp();
- else
- AfxOleUnlockApp();
- sc = S_OK;
- }
- END_TRY
-
- return sc;
- }
-
- STDMETHODIMP COleObjectFactory::XClassFactory::GetLicInfo(
- LPLICINFO pLicInfo)
- {
- METHOD_PROLOGUE_EX(COleObjectFactory, ClassFactory)
- ASSERT_VALID(pThis);
-
- BSTR bstr = NULL;
- pLicInfo->fLicVerified = pThis->IsLicenseValid();
- pLicInfo->fRuntimeKeyAvail = pThis->GetLicenseKey(0, &bstr);
- if (bstr != NULL)
- SysFreeString(bstr);
-
- return S_OK;
- }
-
- STDMETHODIMP COleObjectFactory::XClassFactory::RequestLicKey(
- DWORD dwReserved, BSTR* pbstrKey)
- {
- METHOD_PROLOGUE_EX(COleObjectFactory, ClassFactory)
- ASSERT_VALID(pThis);
-
- ASSERT(pbstrKey != NULL);
-
- *pbstrKey = NULL;
-
- if (pThis->IsLicenseValid())
- {
- if (pThis->GetLicenseKey(dwReserved, pbstrKey))
- return S_OK;
- else
- return E_FAIL;
- }
- else
- return CLASS_E_NOTLICENSED;
- }
-
- STDMETHODIMP COleObjectFactory::XClassFactory::CreateInstanceLic(
- LPUNKNOWN pUnkOuter, LPUNKNOWN /* pUnkReserved */, REFIID riid,
- BSTR bstrKey, LPVOID* ppvObject)
- {
- METHOD_PROLOGUE_EX(COleObjectFactory, ClassFactory)
- ASSERT_VALID(pThis);
-
- if (ppvObject == NULL)
- return E_POINTER;
- *ppvObject = NULL;
-
- if (((bstrKey != NULL) && !pThis->VerifyLicenseKey(bstrKey)) ||
- ((bstrKey == NULL) && !pThis->IsLicenseValid()))
- return CLASS_E_NOTLICENSED;
-
- // outer objects must ask for IUnknown only
- ASSERT(pUnkOuter == NULL || riid == IID_IUnknown);
-
- // attempt to create the object
- CCmdTarget* pTarget = NULL;
- SCODE sc = E_OUTOFMEMORY;
- TRY
- {
- // attempt to create the object
- pTarget = pThis->OnCreateObject();
- if (pTarget != NULL)
- {
- // check for aggregation on object not supporting it
- sc = CLASS_E_NOAGGREGATION;
- if (pUnkOuter == NULL || pTarget->m_xInnerUnknown != 0)
- {
- // create aggregates used by the object
- pTarget->m_pOuterUnknown = pUnkOuter;
- sc = E_OUTOFMEMORY;
- if (pTarget->OnCreateAggregates())
- sc = S_OK;
- }
- }
- }
- END_TRY
-
- // finish creation
- if (sc == S_OK)
- {
- DWORD dwRef = 1;
- if (pUnkOuter != NULL)
- {
- // return inner unknown instead of IUnknown
- *ppvObject = &pTarget->m_xInnerUnknown;
- }
- else
- {
- // query for requested interface
- sc = pTarget->InternalQueryInterface(&riid, ppvObject);
- if (sc == S_OK)
- {
- dwRef = pTarget->InternalRelease();
- ASSERT(dwRef != 0);
- }
- }
- if (dwRef != 1)
- TRACE1("Warning: object created with reference of %ld\n", dwRef);
- }
-
- // cleanup in case of errors
- if (sc != S_OK)
- delete pTarget;
-
- return sc;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- // Diagnostics
-
- #ifdef _DEBUG
- void COleObjectFactory::AssertValid() const
- {
- CCmdTarget::AssertValid();
- ASSERT(m_lpszProgID == NULL || AfxIsValidString(m_lpszProgID));
- ASSERT(m_pRuntimeClass == NULL ||
- AfxIsValidAddress(m_pRuntimeClass, sizeof(CRuntimeClass), FALSE));
- ASSERT(m_pNextFactory == NULL ||
- AfxIsValidAddress(m_pNextFactory, sizeof(COleObjectFactory)));
- }
-
- void COleObjectFactory::Dump(CDumpContext& dc) const
- {
- USES_CONVERSION;
-
- CCmdTarget::Dump(dc);
-
- dc << "m_pNextFactory = " << (void*)m_pNextFactory;
- dc << "\nm_dwRegister = " << m_dwRegister;
- dc << "\nm_bRegistered = " << m_bRegistered;
- LPOLESTR lpszClassID = NULL;
- if (StringFromCLSID(m_clsid, &lpszClassID) == S_OK)
- {
- dc << "\nm_clsid = " << OLE2CT(lpszClassID);
- CoTaskMemFree(lpszClassID);
- }
- dc << "\nm_pRuntimeClass = " << m_pRuntimeClass;
- dc << "\nm_bMultiInstance = " << m_bMultiInstance;
- dc << "\nm_lpszProgID = " << m_lpszProgID;
- dc << "\nm_bLicenseChecked = " << m_bLicenseChecked;
- dc << "\nm_bLicenseValid = " << m_bLicenseValid;
-
- dc << "\n";
- }
- #endif //_DEBUG
-
- #ifdef AFX_INIT_SEG
- #pragma code_seg(AFX_INIT_SEG)
- #endif
-
- IMPLEMENT_DYNAMIC(COleObjectFactory, CCmdTarget)
-
- /////////////////////////////////////////////////////////////////////////////
-