olefact.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588
  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10. #include "stdafx.h"
  11. #ifdef AFX_OLE3_SEG
  12. #pragma code_seg(AFX_OLE3_SEG)
  13. #endif
  14. #ifdef _DEBUG
  15. #undef THIS_FILE
  16. static char THIS_FILE[] = __FILE__;
  17. #endif
  18. #define new DEBUG_NEW
  19. /////////////////////////////////////////////////////////////////////////////
  20. // COleObjectFactory implementation
  21. BEGIN_INTERFACE_MAP(COleObjectFactory, CCmdTarget)
  22. INTERFACE_PART(COleObjectFactory, IID_IClassFactory, ClassFactory)
  23. INTERFACE_PART(COleObjectFactory, IID_IClassFactory2, ClassFactory)
  24. END_INTERFACE_MAP()
  25. #ifdef AFX_INIT_SEG
  26. #pragma code_seg(AFX_INIT_SEG)
  27. #endif
  28. COleObjectFactory::COleObjectFactory(REFCLSID clsid,
  29. CRuntimeClass* pRuntimeClass, BOOL bMultiInstance, LPCTSTR lpszProgID)
  30. {
  31. ASSERT(pRuntimeClass == NULL ||
  32. pRuntimeClass->IsDerivedFrom(RUNTIME_CLASS(CCmdTarget)));
  33. ASSERT(AfxIsValidAddress(&clsid, sizeof(CLSID), FALSE));
  34. ASSERT(lpszProgID == NULL || AfxIsValidString(lpszProgID));
  35. // initialize to unregistered state
  36. m_dwRegister = 0; // not registered yet
  37. m_bRegistered = FALSE;
  38. m_clsid = clsid;
  39. m_pRuntimeClass = pRuntimeClass;
  40. m_bMultiInstance = bMultiInstance;
  41. m_lpszProgID = lpszProgID;
  42. m_bOAT = (BYTE) OAT_UNKNOWN;
  43. // licensing information
  44. m_bLicenseChecked = FALSE;
  45. m_bLicenseValid = FALSE;
  46. // add this factory to the list of factories
  47. m_pNextFactory = NULL;
  48. AFX_MODULE_STATE* pModuleState = _AFX_CMDTARGET_GETSTATE();
  49. AfxLockGlobals(CRIT_OBJECTFACTORYLIST);
  50. pModuleState->m_factoryList.AddHead(this);
  51. AfxUnlockGlobals(CRIT_OBJECTFACTORYLIST);
  52. ASSERT_VALID(this);
  53. }
  54. #ifdef AFX_TERM_SEG
  55. #pragma code_seg(AFX_TERM_SEG)
  56. #endif
  57. COleObjectFactory::~COleObjectFactory()
  58. {
  59. ASSERT_VALID(this);
  60. #ifdef _AFXDLL
  61. if (m_pModuleState == NULL)
  62. return;
  63. #endif
  64. // deregister this class factory
  65. Revoke();
  66. // remove this class factory from the list of active class factories
  67. #ifdef _AFXDLL
  68. AFX_MODULE_STATE* pModuleState = m_pModuleState;
  69. #else
  70. AFX_MODULE_STATE* pModuleState = _AFX_CMDTARGET_GETSTATE();
  71. #endif
  72. AfxLockGlobals(CRIT_OBJECTFACTORYLIST);
  73. BOOL bResult = pModuleState->m_factoryList.Remove(this);
  74. AfxUnlockGlobals(CRIT_OBJECTFACTORYLIST);
  75. if (bResult)
  76. return;
  77. // check CDynLinkLibrary objects in case it was transfered during init
  78. #ifdef _AFXDLL
  79. AfxLockGlobals(CRIT_DYNLINKLIST);
  80. for (CDynLinkLibrary* pDLL = pModuleState->m_libraryList; pDLL != NULL;
  81. pDLL = pDLL->m_pNextDLL)
  82. {
  83. if (pDLL->m_factoryList.Remove(this))
  84. {
  85. AfxUnlockGlobals(CRIT_DYNLINKLIST);
  86. return;
  87. }
  88. }
  89. AfxUnlockGlobals(CRIT_DYNLINKLIST);
  90. #endif
  91. }
  92. #ifdef AFX_INIT_SEG
  93. #pragma code_seg(AFX_INIT_SEG)
  94. #endif
  95. BOOL COleObjectFactory::Unregister()
  96. {
  97. return TRUE;
  98. }
  99. BOOL COleObjectFactory::Register()
  100. {
  101. ASSERT_VALID(this);
  102. ASSERT(!m_bRegistered); // registering server/factory twice?
  103. ASSERT(m_clsid != CLSID_NULL);
  104. if (!afxContextIsDLL)
  105. {
  106. // In the application variants, the IClassFactory is registered
  107. // with the OLE DLLs.
  108. SCODE sc = ::CoRegisterClassObject(m_clsid, &m_xClassFactory,
  109. CLSCTX_LOCAL_SERVER,
  110. m_bMultiInstance ? REGCLS_SINGLEUSE : REGCLS_MULTIPLEUSE,
  111. &m_dwRegister);
  112. if (sc != S_OK)
  113. {
  114. #ifdef _DEBUG
  115. TRACE1("Warning: CoRegisterClassObject failed scode = %s.\n",
  116. ::AfxGetFullScodeString(sc));
  117. #endif
  118. // registration failed.
  119. return FALSE;
  120. }
  121. ASSERT(m_dwRegister != 0);
  122. }
  123. ++m_bRegistered;
  124. return TRUE;
  125. }
  126. BOOL PASCAL COleObjectFactory::UnregisterAll()
  127. {
  128. BOOL bResult = TRUE;
  129. // register application factories
  130. AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
  131. AfxLockGlobals(CRIT_OBJECTFACTORYLIST);
  132. for (COleObjectFactory* pFactory = pModuleState->m_factoryList;
  133. pFactory != NULL; pFactory = pFactory->m_pNextFactory)
  134. {
  135. // unregister any registered, non-doctemplate factories
  136. if (pFactory->IsRegistered() && !pFactory->Unregister())
  137. {
  138. bResult = FALSE;
  139. }
  140. }
  141. AfxUnlockGlobals(CRIT_OBJECTFACTORYLIST);
  142. return bResult;
  143. }
  144. BOOL PASCAL COleObjectFactory::RegisterAll()
  145. {
  146. BOOL bResult = TRUE;
  147. // register application factories
  148. AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
  149. AfxLockGlobals(CRIT_OBJECTFACTORYLIST);
  150. for (COleObjectFactory* pFactory = pModuleState->m_factoryList;
  151. pFactory != NULL; pFactory = pFactory->m_pNextFactory)
  152. {
  153. // register any non-registered, non-doctemplate factories
  154. if (!pFactory->IsRegistered() &&
  155. pFactory->m_clsid != CLSID_NULL && !pFactory->Register())
  156. {
  157. bResult = FALSE;
  158. }
  159. }
  160. AfxUnlockGlobals(CRIT_OBJECTFACTORYLIST);
  161. #ifdef _AFXDLL
  162. // register extension DLL factories
  163. AfxLockGlobals(CRIT_DYNLINKLIST);
  164. for (CDynLinkLibrary* pDLL = pModuleState->m_libraryList; pDLL != NULL;
  165. pDLL = pDLL->m_pNextDLL)
  166. {
  167. for (pFactory = pDLL->m_factoryList;
  168. pFactory != NULL; pFactory = pFactory->m_pNextFactory)
  169. {
  170. // register any non-registered, non-doctemplate factories
  171. if (!pFactory->IsRegistered() &&
  172. pFactory->m_clsid != CLSID_NULL && !pFactory->Register())
  173. {
  174. bResult = FALSE;
  175. }
  176. }
  177. }
  178. AfxUnlockGlobals(CRIT_DYNLINKLIST);
  179. #endif
  180. return bResult;
  181. }
  182. #ifdef AFX_TERM_SEG
  183. #pragma code_seg(AFX_TERM_SEG)
  184. #endif
  185. void COleObjectFactory::Revoke()
  186. {
  187. ASSERT_VALID(this);
  188. if (m_bRegistered)
  189. {
  190. // revoke the registration of the class itself
  191. if (m_dwRegister != 0)
  192. {
  193. ::CoRevokeClassObject(m_dwRegister);
  194. m_dwRegister = 0;
  195. }
  196. m_bRegistered = FALSE;
  197. }
  198. }
  199. void PASCAL COleObjectFactory::RevokeAll()
  200. {
  201. AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
  202. AfxLockGlobals(CRIT_OBJECTFACTORYLIST);
  203. for (COleObjectFactory* pFactory = pModuleState->m_factoryList;
  204. pFactory != NULL; pFactory = pFactory->m_pNextFactory)
  205. {
  206. pFactory->Revoke();
  207. }
  208. AfxUnlockGlobals(CRIT_OBJECTFACTORYLIST);
  209. #ifdef _AFXDLL
  210. AfxLockGlobals(CRIT_DYNLINKLIST);
  211. // register extension DLL factories
  212. for (CDynLinkLibrary* pDLL = pModuleState->m_libraryList; pDLL != NULL;
  213. pDLL = pDLL->m_pNextDLL)
  214. {
  215. for (pFactory = pDLL->m_factoryList;
  216. pFactory != NULL; pFactory = pFactory->m_pNextFactory)
  217. {
  218. pFactory->Revoke();
  219. }
  220. }
  221. AfxUnlockGlobals(CRIT_DYNLINKLIST);
  222. #endif
  223. }
  224. #ifdef AFX_OLE3_SEG
  225. #pragma code_seg(AFX_OLE3_SEG)
  226. #endif
  227. void COleObjectFactory::UpdateRegistry(LPCTSTR lpszProgID)
  228. {
  229. ASSERT_VALID(this);
  230. ASSERT(lpszProgID == NULL || AfxIsValidString(lpszProgID));
  231. // use default prog-id if specific prog-id not given
  232. if (lpszProgID == NULL)
  233. {
  234. lpszProgID = m_lpszProgID;
  235. if (lpszProgID == NULL) // still no valid progID?
  236. return;
  237. }
  238. // call global helper to modify system registry
  239. // (progid, shortname, and long name are all equal in this case)
  240. AfxOleRegisterServerClass(m_clsid, lpszProgID, lpszProgID, lpszProgID,
  241. OAT_DISPATCH_OBJECT);
  242. }
  243. BOOL PASCAL COleObjectFactory::UpdateRegistryAll(BOOL bRegister)
  244. {
  245. AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
  246. AfxLockGlobals(CRIT_OBJECTFACTORYLIST);
  247. for (COleObjectFactory* pFactory = pModuleState->m_factoryList;
  248. pFactory != NULL; pFactory = pFactory->m_pNextFactory)
  249. {
  250. if (!pFactory->UpdateRegistry(bRegister))
  251. {
  252. AfxUnlockGlobals(CRIT_OBJECTFACTORYLIST);
  253. return FALSE;
  254. }
  255. }
  256. AfxUnlockGlobals(CRIT_OBJECTFACTORYLIST);
  257. #ifdef _AFXDLL
  258. AfxLockGlobals(CRIT_DYNLINKLIST);
  259. // register extension DLL factories
  260. for (CDynLinkLibrary* pDLL = pModuleState->m_libraryList; pDLL != NULL;
  261. pDLL = pDLL->m_pNextDLL)
  262. {
  263. for (pFactory = pDLL->m_factoryList;
  264. pFactory != NULL; pFactory = pFactory->m_pNextFactory)
  265. {
  266. if (!pFactory->UpdateRegistry(bRegister))
  267. {
  268. AfxUnlockGlobals(CRIT_DYNLINKLIST);
  269. return FALSE;
  270. }
  271. }
  272. }
  273. AfxUnlockGlobals(CRIT_DYNLINKLIST);
  274. #endif
  275. return TRUE;
  276. }
  277. CCmdTarget* COleObjectFactory::OnCreateObject()
  278. {
  279. ASSERT_VALID(this);
  280. ASSERT(AfxIsValidAddress(m_pRuntimeClass, sizeof(CRuntimeClass), FALSE));
  281. // this implementation needs a runtime class
  282. // allocate object, throw exception on failure
  283. CCmdTarget* pTarget = (CCmdTarget*)m_pRuntimeClass->CreateObject();
  284. if (pTarget == NULL)
  285. AfxThrowMemoryException();
  286. // make sure it is a CCmdTarget
  287. ASSERT_KINDOF(CCmdTarget, pTarget);
  288. ASSERT_VALID(pTarget);
  289. // return the new CCmdTarget object
  290. return pTarget;
  291. }
  292. BOOL COleObjectFactory::IsLicenseValid()
  293. {
  294. if (!m_bLicenseChecked)
  295. {
  296. m_bLicenseValid = (BYTE)VerifyUserLicense();
  297. m_bLicenseChecked = TRUE;
  298. }
  299. return m_bLicenseValid;
  300. }
  301. BOOL COleObjectFactory::UpdateRegistry(BOOL bRegister)
  302. {
  303. if (bRegister)
  304. UpdateRegistry(); // will register with default m_lpszProgID
  305. return TRUE;
  306. }
  307. BOOL COleObjectFactory::VerifyUserLicense()
  308. {
  309. // May be overridden by subclass
  310. return TRUE;
  311. }
  312. BOOL COleObjectFactory::GetLicenseKey(DWORD, BSTR*)
  313. {
  314. // May be overridden by subclass
  315. return FALSE;
  316. }
  317. BOOL COleObjectFactory::VerifyLicenseKey(BSTR bstrKey)
  318. {
  319. // May be overridden by subclass
  320. BOOL bLicensed = FALSE;
  321. BSTR bstr = NULL;
  322. if ((bstrKey != NULL) && GetLicenseKey(0, &bstr))
  323. {
  324. ASSERT(bstr != NULL);
  325. // if length and content match, it's good!
  326. UINT cch = SysStringByteLen(bstr);
  327. if ((cch == SysStringByteLen(bstrKey)) &&
  328. (memcmp(bstr, bstrKey, cch) == 0))
  329. {
  330. bLicensed = TRUE;
  331. }
  332. SysFreeString(bstr);
  333. }
  334. return bLicensed;
  335. }
  336. /////////////////////////////////////////////////////////////////////////////
  337. // Implementation of COleObjectFactory::IClassFactory interface
  338. STDMETHODIMP_(ULONG) COleObjectFactory::XClassFactory::AddRef()
  339. {
  340. METHOD_PROLOGUE_EX_(COleObjectFactory, ClassFactory)
  341. return pThis->InternalAddRef();
  342. }
  343. STDMETHODIMP_(ULONG) COleObjectFactory::XClassFactory::Release()
  344. {
  345. METHOD_PROLOGUE_EX_(COleObjectFactory, ClassFactory)
  346. return pThis->InternalRelease();
  347. }
  348. STDMETHODIMP COleObjectFactory::XClassFactory::QueryInterface(
  349. REFIID iid, LPVOID* ppvObj)
  350. {
  351. METHOD_PROLOGUE_EX_(COleObjectFactory, ClassFactory)
  352. return pThis->InternalQueryInterface(&iid, ppvObj);
  353. }
  354. STDMETHODIMP COleObjectFactory::XClassFactory::CreateInstance(
  355. IUnknown* pUnkOuter, REFIID riid, LPVOID* ppvObject)
  356. {
  357. return CreateInstanceLic(pUnkOuter, NULL, riid, NULL, ppvObject);
  358. }
  359. STDMETHODIMP COleObjectFactory::XClassFactory::LockServer(BOOL fLock)
  360. {
  361. METHOD_PROLOGUE_EX(COleObjectFactory, ClassFactory)
  362. ASSERT_VALID(pThis);
  363. SCODE sc = E_UNEXPECTED;
  364. TRY
  365. {
  366. if (fLock)
  367. AfxOleLockApp();
  368. else
  369. AfxOleUnlockApp();
  370. sc = S_OK;
  371. }
  372. END_TRY
  373. return sc;
  374. }
  375. STDMETHODIMP COleObjectFactory::XClassFactory::GetLicInfo(
  376. LPLICINFO pLicInfo)
  377. {
  378. METHOD_PROLOGUE_EX(COleObjectFactory, ClassFactory)
  379. ASSERT_VALID(pThis);
  380. BSTR bstr = NULL;
  381. pLicInfo->fLicVerified = pThis->IsLicenseValid();
  382. pLicInfo->fRuntimeKeyAvail = pThis->GetLicenseKey(0, &bstr);
  383. if (bstr != NULL)
  384. SysFreeString(bstr);
  385. return S_OK;
  386. }
  387. STDMETHODIMP COleObjectFactory::XClassFactory::RequestLicKey(
  388. DWORD dwReserved, BSTR* pbstrKey)
  389. {
  390. METHOD_PROLOGUE_EX(COleObjectFactory, ClassFactory)
  391. ASSERT_VALID(pThis);
  392. ASSERT(pbstrKey != NULL);
  393. *pbstrKey = NULL;
  394. if (pThis->IsLicenseValid())
  395. {
  396. if (pThis->GetLicenseKey(dwReserved, pbstrKey))
  397. return S_OK;
  398. else
  399. return E_FAIL;
  400. }
  401. else
  402. return CLASS_E_NOTLICENSED;
  403. }
  404. STDMETHODIMP COleObjectFactory::XClassFactory::CreateInstanceLic(
  405. LPUNKNOWN pUnkOuter, LPUNKNOWN /* pUnkReserved */, REFIID riid,
  406. BSTR bstrKey, LPVOID* ppvObject)
  407. {
  408. METHOD_PROLOGUE_EX(COleObjectFactory, ClassFactory)
  409. ASSERT_VALID(pThis);
  410. if (ppvObject == NULL)
  411. return E_POINTER;
  412. *ppvObject = NULL;
  413. if (((bstrKey != NULL) && !pThis->VerifyLicenseKey(bstrKey)) ||
  414. ((bstrKey == NULL) && !pThis->IsLicenseValid()))
  415. return CLASS_E_NOTLICENSED;
  416. // outer objects must ask for IUnknown only
  417. ASSERT(pUnkOuter == NULL || riid == IID_IUnknown);
  418. // attempt to create the object
  419. CCmdTarget* pTarget = NULL;
  420. SCODE sc = E_OUTOFMEMORY;
  421. TRY
  422. {
  423. // attempt to create the object
  424. pTarget = pThis->OnCreateObject();
  425. if (pTarget != NULL)
  426. {
  427. // check for aggregation on object not supporting it
  428. sc = CLASS_E_NOAGGREGATION;
  429. if (pUnkOuter == NULL || pTarget->m_xInnerUnknown != 0)
  430. {
  431. // create aggregates used by the object
  432. pTarget->m_pOuterUnknown = pUnkOuter;
  433. sc = E_OUTOFMEMORY;
  434. if (pTarget->OnCreateAggregates())
  435. sc = S_OK;
  436. }
  437. }
  438. }
  439. END_TRY
  440. // finish creation
  441. if (sc == S_OK)
  442. {
  443. DWORD dwRef = 1;
  444. if (pUnkOuter != NULL)
  445. {
  446. // return inner unknown instead of IUnknown
  447. *ppvObject = &pTarget->m_xInnerUnknown;
  448. }
  449. else
  450. {
  451. // query for requested interface
  452. sc = pTarget->InternalQueryInterface(&riid, ppvObject);
  453. if (sc == S_OK)
  454. {
  455. dwRef = pTarget->InternalRelease();
  456. ASSERT(dwRef != 0);
  457. }
  458. }
  459. if (dwRef != 1)
  460. TRACE1("Warning: object created with reference of %ld\n", dwRef);
  461. }
  462. // cleanup in case of errors
  463. if (sc != S_OK)
  464. delete pTarget;
  465. return sc;
  466. }
  467. //////////////////////////////////////////////////////////////////////////////
  468. // Diagnostics
  469. #ifdef _DEBUG
  470. void COleObjectFactory::AssertValid() const
  471. {
  472. CCmdTarget::AssertValid();
  473. ASSERT(m_lpszProgID == NULL || AfxIsValidString(m_lpszProgID));
  474. ASSERT(m_pRuntimeClass == NULL ||
  475. AfxIsValidAddress(m_pRuntimeClass, sizeof(CRuntimeClass), FALSE));
  476. ASSERT(m_pNextFactory == NULL ||
  477. AfxIsValidAddress(m_pNextFactory, sizeof(COleObjectFactory)));
  478. }
  479. void COleObjectFactory::Dump(CDumpContext& dc) const
  480. {
  481. USES_CONVERSION;
  482. CCmdTarget::Dump(dc);
  483. dc << "m_pNextFactory = " << (void*)m_pNextFactory;
  484. dc << "\nm_dwRegister = " << m_dwRegister;
  485. dc << "\nm_bRegistered = " << m_bRegistered;
  486. LPOLESTR lpszClassID = NULL;
  487. if (StringFromCLSID(m_clsid, &lpszClassID) == S_OK)
  488. {
  489. dc << "\nm_clsid = " << OLE2CT(lpszClassID);
  490. CoTaskMemFree(lpszClassID);
  491. }
  492. dc << "\nm_pRuntimeClass = " << m_pRuntimeClass;
  493. dc << "\nm_bMultiInstance = " << m_bMultiInstance;
  494. dc << "\nm_lpszProgID = " << m_lpszProgID;
  495. dc << "\nm_bLicenseChecked = " << m_bLicenseChecked;
  496. dc << "\nm_bLicenseValid = " << m_bLicenseValid;
  497. dc << "\n";
  498. }
  499. #endif //_DEBUG
  500. #ifdef AFX_INIT_SEG
  501. #pragma code_seg(AFX_INIT_SEG)
  502. #endif
  503. IMPLEMENT_DYNAMIC(COleObjectFactory, CCmdTarget)
  504. /////////////////////////////////////////////////////////////////////////////