Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

871 lines
20 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1997.
  5. //
  6. // File: cdispmgr.cxx
  7. //
  8. // Contents: The dispatch manager -- a class to manage
  9. // multiple IDispatch-callable interfaces.
  10. //
  11. // Classes: CAggregateeDispMgr
  12. //
  13. // Functions: None external.
  14. //
  15. // History: ??-???-?? KrishnaG created
  16. // 07-Sep-97 t-blakej Commented, cleaned up, made
  17. // independent of ADSI.
  18. //
  19. // See cdispmgr.hxx for a more thorough description of the dispatch manager.
  20. //
  21. //----------------------------------------------------------------------------
  22. //
  23. // Since this class is useful outside of ADSI, some work has been taken to
  24. // make it not depend on any ADSI-specific code. It needs two ADSI header
  25. // files (cdispmgr.hxx and iprops.hxx), but they only depend on definitions
  26. // from standard system header files.
  27. //
  28. // To accomodate the current building method in ADSI, the precompiled
  29. // header "procs.hxx" is included; this includes all the necessary ADSI
  30. // header files and definitions. But for use outside of ADSI, the few
  31. // necessary header files are explicitly included below; see the comment by
  32. // "#ifndef ADsAssert".
  33. //
  34. // So if not compiling for ADSI, comment the following two lines out.
  35. //
  36. #include "cadsxml.hxx"
  37. extern "C" {
  38. #include <stdio.h>
  39. #include <stddef.h>
  40. }
  41. //////////////////////////////////////////////////////////////////////////////
  42. //
  43. // General helper definitions, routines, and inclusions:
  44. // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Begin Non-ADSI compile stuff
  45. //
  46. // This macro is defined by the precompiled header file, so the following
  47. // will only be included if not compiling for ADSI.
  48. //
  49. #ifndef ADsAssert
  50. //
  51. // Necessary system headers.
  52. //
  53. #define UNICODE
  54. #define _UNICODE
  55. #define _OLEAUT32_
  56. #define INC_OLE2
  57. #include <windows.h>
  58. #include <stdio.h>
  59. //
  60. // Necessary class definitions used by the dispatch manager.
  61. // Edit these paths if necessary.
  62. //
  63. #include "cdispmgr.hxx"
  64. #include "iprops.hxx"
  65. #endif // ADsAssert
  66. // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- End Non-ADSI compile stuff
  67. //
  68. // A simple assert function.
  69. //
  70. #if DBG == 1
  71. //+---------------------------------------------------------------------------
  72. //
  73. // Function: AssertEx
  74. //
  75. // Synopsis: Display assertion information.
  76. //
  77. // Effects: Called when an assertion is hit.
  78. //
  79. // History: Simplified from Win4AssertEx, to make this dispatch manager
  80. // not depend on other files.
  81. //
  82. //----------------------------------------------------------------------------
  83. static void
  84. AssertEx(char const *szFile, int iLine, char const *szMessage)
  85. {
  86. static char szAssertCaption[199];
  87. DWORD dwCount = strlen("File: %s line %u, thread id %d");
  88. if (szFile) {
  89. dwCount += strlen(szFile);
  90. }
  91. dwCount += 15; // for the line number and thread id
  92. if (dwCount > 199) {
  93. sprintf(szAssertCaption, "Error, could not get more infomration");
  94. }
  95. else {
  96. sprintf(szAssertCaption, "File: %s line %u, thread id %d",
  97. szFile, iLine, GetCurrentThreadId());
  98. }
  99. if (IDCANCEL == MessageBoxA(
  100. NULL,
  101. (char *) szMessage,
  102. (LPSTR) szAssertCaption,
  103. MB_SETFOREGROUND |
  104. MB_TASKMODAL | MB_ICONEXCLAMATION | MB_OKCANCEL
  105. ))
  106. {
  107. DebugBreak();
  108. }
  109. }
  110. # define DispMgrAssert(x) (void)((x) || (AssertEx(__FILE__, __LINE__, #x),0))
  111. #else
  112. # define AssertEx(f,l,m)
  113. # define DispMgrAssert(x)
  114. #endif
  115. //////////////////////////////////////////////////////////////////////////////
  116. //
  117. // Inline routines:
  118. static inline LONG
  119. getDispMgrId(DISPID InputDispId)
  120. {
  121. return (InputDispId & 0x7f000000) >> 24;
  122. }
  123. static inline LONG
  124. getTypeInfoId(DISPID InputDispId)
  125. {
  126. return (InputDispId & 0x00ff0000) >> 16;
  127. }
  128. static inline LONG
  129. getDispId(DISPID InputDispId)
  130. {
  131. return (InputDispId & 0x0000ffff);
  132. }
  133. static inline void
  134. MakeDISPID(
  135. LONG ExtensionId,
  136. LONG TypeInfoId,
  137. LONG DispId,
  138. DISPID *pResult
  139. )
  140. {
  141. if (DispId == DISPID_UNKNOWN){
  142. *pResult = DispId;
  143. }else if (TypeInfoId < 0 || TypeInfoId >= 0x100 ||
  144. DispId < 0 || DispId >= 0x10000){
  145. //
  146. // Might happen if some object has very large dispid's.
  147. // But we can't handle it if it does.
  148. //
  149. *pResult = DISPID_UNKNOWN;
  150. }
  151. else{
  152. *pResult = ((ExtensionId & 0xff) << 24) |((TypeInfoId & 0xff) << 16) | (DispId & 0xffff);
  153. }
  154. }
  155. static inline void
  156. MakeDISPIDs(
  157. LONG ExtensionId,
  158. LONG TypeInfoId,
  159. DISPID *rgdispid,
  160. unsigned int cNames
  161. )
  162. {
  163. for (unsigned int i = 0; i < cNames; i++)
  164. {
  165. MakeDISPID(ExtensionId, TypeInfoId, rgdispid[i], &rgdispid[i]);
  166. }
  167. }
  168. //
  169. // Struct Def
  170. //
  171. typedef struct _typeinfotable
  172. {
  173. GUID iid;
  174. ITypeInfo * pTypeInfo;
  175. struct _typeinfotable *pNext;
  176. }TYPEINFO_TABLE, *PTYPEINFO_TABLE;
  177. CRITICAL_SECTION g_ExtTypeInfoCritSect;
  178. #define ENTER_EXT_TYPEINFO_CRITSECT() EnterCriticalSection(&g_ExtTypeInfoCritSect)
  179. #define LEAVE_EXT_TYPEINFO_CRITSECT() LeaveCriticalSection(&g_ExtTypeInfoCritSect)
  180. LONG glnMSEXTObjCount = 0;
  181. LONG glnMSEXTTypesOfInfo = 0;
  182. PTYPEINFO_TABLE gpAggregateeTypeInfoTable = NULL;
  183. //////////////////////////////////////////////////////////////////////////////
  184. //
  185. // Public methods:
  186. CAggregateeDispMgr::CAggregateeDispMgr()
  187. {
  188. _pTypeInfoEntry = NULL;
  189. _pDispidNewEnum = NULL;
  190. _dwTypeInfoId = 0;
  191. _pDispidValue = NULL;
  192. _pPropertyCache = NULL;
  193. _dwPropCacheID = 0;
  194. _dwExtensionID = 0;
  195. }
  196. CAggregateeDispMgr::~CAggregateeDispMgr()
  197. {
  198. PTYPEINFOENTRY pTypeInfoEntry = NULL;
  199. PTYPEINFOENTRY pTemp = NULL;
  200. ITypeInfo *pTypeInfo = NULL;
  201. pTypeInfoEntry = _pTypeInfoEntry;
  202. while (pTypeInfoEntry) {
  203. pTemp = pTypeInfoEntry;
  204. pTypeInfo = (ITypeInfo *)pTypeInfoEntry->ptypeinfo;
  205. pTypeInfo->Release();
  206. InterlockedDecrement(&glnMSEXTObjCount);
  207. pTypeInfoEntry = pTemp->pNext;
  208. LocalFree(pTemp);
  209. }
  210. ENTER_EXT_TYPEINFO_CRITSECT();
  211. if (glnMSEXTObjCount == glnMSEXTTypesOfInfo) {
  212. //
  213. // We need to clean up the list
  214. //
  215. AggregateeFreeTypeInfoTable();
  216. gpAggregateeTypeInfoTable = NULL;
  217. glnMSEXTObjCount = glnMSEXTTypesOfInfo = 0;
  218. }
  219. LEAVE_EXT_TYPEINFO_CRITSECT();
  220. }
  221. void
  222. CAggregateeDispMgr::RegisterPropertyCache(IPropertyCache *pPropertyCache)
  223. {
  224. _pPropertyCache = pPropertyCache;
  225. _dwPropCacheID = gentypeinfoid();
  226. }
  227. STDMETHODIMP
  228. CAggregateeDispMgr::GetTypeInfoCount(unsigned int *pctinfo)
  229. {
  230. return E_NOTIMPL;
  231. }
  232. STDMETHODIMP
  233. CAggregateeDispMgr::GetTypeInfo(unsigned int itinfo, LCID lcid, ITypeInfo **pptinfo)
  234. {
  235. return E_NOTIMPL;
  236. }
  237. STDMETHODIMP
  238. CAggregateeDispMgr::GetIDsOfNames(REFIID iid, LPWSTR *rgszNames,
  239. unsigned int cNames, LCID lcid, DISPID *rgdispid)
  240. {
  241. PTYPEINFOENTRY pTypeInfo = NULL;
  242. HRESULT hr = DISP_E_UNKNOWNNAME;
  243. //
  244. // Try our list of TypeInfos.
  245. //
  246. pTypeInfo = _pTypeInfoEntry;
  247. while (pTypeInfo) {
  248. hr = DispGetIDsOfNames(((ITypeInfo *)pTypeInfo->ptypeinfo),
  249. rgszNames,
  250. cNames,
  251. rgdispid
  252. );
  253. if (SUCCEEDED(hr)) {
  254. //
  255. // aggregatee no longer needs to include extension id
  256. // in dispid.
  257. //
  258. MakeDISPIDs(0, pTypeInfo->TypeInfoId, rgdispid, cNames);
  259. return hr;
  260. }
  261. pTypeInfo = pTypeInfo->pNext;
  262. }
  263. //
  264. // Try our property cache.
  265. //
  266. if (FAILED(hr) && _pPropertyCache) {
  267. hr = S_OK;
  268. for (DWORD dw = 0; dw < cNames; dw++) {
  269. if (FAILED(_pPropertyCache->locateproperty(rgszNames[dw],
  270. (PDWORD)(rgdispid + dw)))) {
  271. hr = DISP_E_UNKNOWNNAME;
  272. rgdispid[dw] = DISPID_UNKNOWN;
  273. }
  274. }
  275. if (SUCCEEDED(hr)) {
  276. //
  277. // aggregatee no longer needs to include extension id
  278. // in dispid.
  279. //
  280. MakeDISPIDs(0, _dwPropCacheID, rgdispid, cNames);
  281. }
  282. }
  283. return hr;
  284. }
  285. STDMETHODIMP
  286. CAggregateeDispMgr::Invoke(DISPID dispidMember, REFIID iid, LCID lcid,
  287. unsigned short wFlags, DISPPARAMS *pdispparams, VARIANT *pvarResult,
  288. EXCEPINFO *pexcepinfo, unsigned int *puArgErr)
  289. {
  290. //
  291. // Clear the error object before we call invoke.
  292. //
  293. SetErrorInfo(0, NULL);
  294. return TypeInfoInvoke(dispidMember,
  295. iid,
  296. lcid,
  297. wFlags,
  298. pdispparams,
  299. pvarResult,
  300. pexcepinfo,
  301. puArgErr
  302. );
  303. }
  304. //////////////////////////////////////////////////////////////////////////////
  305. //
  306. // Private methods and helper functions:
  307. void *
  308. CAggregateeDispMgr::getInterfacePtr(LONG TypeInfoId)
  309. {
  310. PTYPEINFOENTRY pTypeInfoEntry = FindTypeInfoEntry(TypeInfoId);
  311. return (pTypeInfoEntry ? pTypeInfoEntry->pInterfacePointer : NULL);
  312. }
  313. ITypeInfo *
  314. CAggregateeDispMgr::getTypeInfo(LONG TypeInfoId)
  315. {
  316. PTYPEINFOENTRY pTypeInfoEntry = FindTypeInfoEntry(TypeInfoId);
  317. return (ITypeInfo *)(pTypeInfoEntry ? pTypeInfoEntry->ptypeinfo : NULL);
  318. }
  319. PTYPEINFOENTRY
  320. CAggregateeDispMgr::FindTypeInfoEntry(LONG TypeInfoId)
  321. {
  322. PTYPEINFOENTRY pTypeInfoEntry;
  323. pTypeInfoEntry = _pTypeInfoEntry;
  324. while (pTypeInfoEntry) {
  325. if (pTypeInfoEntry->TypeInfoId == TypeInfoId) {
  326. return pTypeInfoEntry;
  327. }
  328. pTypeInfoEntry = pTypeInfoEntry->pNext;
  329. }
  330. return NULL;
  331. }
  332. PTYPEINFOENTRY
  333. CAggregateeDispMgr::FindTypeInfo(void *pTypeInfo)
  334. {
  335. PTYPEINFOENTRY pTypeInfoEntry;
  336. pTypeInfoEntry = _pTypeInfoEntry;
  337. while (pTypeInfoEntry) {
  338. if (pTypeInfoEntry->ptypeinfo == pTypeInfo) {
  339. return pTypeInfoEntry;
  340. }
  341. pTypeInfoEntry = pTypeInfoEntry->pNext;
  342. }
  343. return NULL;
  344. }
  345. HRESULT
  346. CAggregateeDispMgr::AddTypeInfo(void *ptypeinfo, void *pIntfptr)
  347. {
  348. PTYPEINFOENTRY pTypeInfoEntry = NULL;
  349. HRESULT hr;
  350. if (FindTypeInfo(ptypeinfo)) {
  351. return E_FAIL;
  352. }
  353. pTypeInfoEntry = (PTYPEINFOENTRY)LocalAlloc(LPTR,sizeof(TYPEINFOENTRY));
  354. if (!pTypeInfoEntry) {
  355. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  356. }
  357. pTypeInfoEntry->ptypeinfo = ptypeinfo;
  358. pTypeInfoEntry->TypeInfoId = gentypeinfoid();
  359. pTypeInfoEntry->pInterfacePointer = pIntfptr;
  360. pTypeInfoEntry->pNext = _pTypeInfoEntry;
  361. _pTypeInfoEntry = pTypeInfoEntry;
  362. return S_OK;
  363. error:
  364. return hr;
  365. }
  366. STDMETHODIMP
  367. CAggregateeDispMgr::TypeInfoInvoke(DISPID dispidMember, REFIID iid, LCID lcid,
  368. unsigned short wFlags, DISPPARAMS *pdispparams, VARIANT *pvarResult,
  369. EXCEPINFO *pexcepinfo, unsigned int *puArgErr)
  370. {
  371. void *pInterfacePtr = NULL;
  372. DISPID dispid = 0;
  373. DISPID typeinfoid = 0;
  374. ITypeInfo *pTypeInfo = NULL;
  375. HRESULT hr = S_OK;
  376. if (dispidMember <= 0) {
  377. //
  378. // One of the special DISPIDs.
  379. //
  380. // If we have an interface pointer for it, use that.
  381. // If we don't, and we have a base IDispatch pointer,
  382. // pass it to the base pointer's Invoke() method.
  383. // If we don't, and we don't have a base IDispatch pointer,
  384. // return failure.
  385. //
  386. dispid = dispidMember;
  387. switch (dispid) {
  388. case DISPID_VALUE:
  389. if (_pDispidValue) {
  390. pTypeInfo = (ITypeInfo *)_pDispidValue->ptypeinfo;
  391. pInterfacePtr = _pDispidValue->pInterfacePointer;
  392. }
  393. break;
  394. case DISPID_NEWENUM:
  395. if (_pDispidNewEnum) {
  396. pTypeInfo = (ITypeInfo *)_pDispidNewEnum->ptypeinfo;
  397. pInterfacePtr = _pDispidNewEnum->pInterfacePointer;
  398. }
  399. break;
  400. default:
  401. break;
  402. }
  403. if (!pInterfacePtr) {
  404. BAIL_ON_FAILURE(hr = DISP_E_MEMBERNOTFOUND);
  405. }else {
  406. //
  407. // Fill in the special case scenarios here
  408. //
  409. hr = DispInvoke(
  410. pInterfacePtr,
  411. pTypeInfo,
  412. dispid,
  413. wFlags,
  414. pdispparams,
  415. pvarResult,
  416. pexcepinfo,
  417. puArgErr
  418. );
  419. return(hr);
  420. }
  421. } else {
  422. //
  423. // A regular DISPID of ours.
  424. //
  425. typeinfoid = getTypeInfoId(dispidMember);
  426. dispid = getDispId(dispidMember);
  427. if ((_pPropertyCache == NULL) || (typeinfoid != _dwPropCacheID)) {
  428. pInterfacePtr = getInterfacePtr(typeinfoid);
  429. pTypeInfo = getTypeInfo(typeinfoid);
  430. if (!pTypeInfo)
  431. //
  432. // Shouldn't happen.
  433. //
  434. BAIL_ON_FAILURE(hr = DISP_E_MEMBERNOTFOUND);
  435. }
  436. if ((_pPropertyCache == NULL) || (typeinfoid != _dwPropCacheID)) {
  437. //
  438. // A regular interface.
  439. //
  440. hr = DispInvoke(
  441. pInterfacePtr,
  442. pTypeInfo,
  443. dispid,
  444. wFlags,
  445. pdispparams,
  446. pvarResult,
  447. pexcepinfo,
  448. puArgErr
  449. );
  450. }else {
  451. //
  452. // A "dynamic DISPID", for the property cache.
  453. //
  454. hr = AggregateeDynamicDispidInvoke(
  455. _pPropertyCache,
  456. dispid,
  457. wFlags,
  458. pdispparams,
  459. pvarResult
  460. );
  461. }
  462. }
  463. error:
  464. return hr;
  465. }
  466. HRESULT
  467. AggregateeDynamicDispidInvoke(
  468. IPropertyCache * pPropertyCache,
  469. DISPID dispid,
  470. unsigned short wFlags,
  471. DISPPARAMS *pdispparams,
  472. VARIANT * pvarResult
  473. )
  474. {
  475. HRESULT hr = S_OK;
  476. if (!pPropertyCache) {
  477. return(E_INVALIDARG);
  478. }
  479. if (wFlags & DISPATCH_PROPERTYGET) {
  480. if (!pvarResult) {
  481. BAIL_ON_FAILURE(hr = E_INVALIDARG);
  482. }
  483. hr = pPropertyCache->getproperty((DWORD)dispid,pvarResult);
  484. if (FAILED(hr)) {
  485. #if 1
  486. // This lets us return S_OK and a VT_EMPTY variant if
  487. // there's no data. #if this out to disable it.
  488. V_VT(pvarResult) = VT_EMPTY;
  489. hr = S_OK;
  490. #else
  491. V_VT(pvarResult) = VT_ERROR;
  492. #endif
  493. }
  494. }else if (wFlags & DISPATCH_PROPERTYPUT) {
  495. if (pdispparams[0].cArgs != 1){
  496. hr = DISP_E_BADPARAMCOUNT;
  497. }
  498. else {
  499. hr = pPropertyCache->putproperty(
  500. (DWORD)dispid,
  501. pdispparams[0].rgvarg[0]
  502. );
  503. }
  504. }else {
  505. hr = E_INVALIDARG;
  506. }
  507. error:
  508. return(hr);
  509. }
  510. HRESULT
  511. CAggregateeDispMgr::MarkAsNewEnum(void *pTypeInfo)
  512. {
  513. PTYPEINFOENTRY pTypeInfoEntry;
  514. if (!pTypeInfo) {
  515. return E_FAIL;
  516. }
  517. if (!(pTypeInfoEntry = FindTypeInfo(pTypeInfo))) {
  518. return E_FAIL;
  519. }
  520. _pDispidNewEnum = pTypeInfoEntry;
  521. return S_OK;
  522. }
  523. HRESULT
  524. CAggregateeDispMgr::MarkAsItem(void *pTypeInfo)
  525. {
  526. PTYPEINFOENTRY pTypeInfoEntry;
  527. if (!pTypeInfo) {
  528. return E_FAIL;
  529. }
  530. if (!(pTypeInfoEntry = FindTypeInfo(pTypeInfo))) {
  531. return E_FAIL;
  532. }
  533. _pDispidValue = pTypeInfoEntry;
  534. return S_OK;
  535. }
  536. LONG
  537. CAggregateeDispMgr::gentypeinfoid()
  538. {
  539. //
  540. // This would mean we've registered 65536 IDispatch methods
  541. // in this object's dispatch manager. We lose.
  542. //
  543. DispMgrAssert(_dwTypeInfoId < 0xffff);
  544. return (_dwTypeInfoId++);
  545. }
  546. ITypeInfo *
  547. AggregateeFindTypeInfo(
  548. PTYPEINFO_TABLE pTypeInfoTable,
  549. REFIID iid
  550. )
  551. {
  552. PTYPEINFO_TABLE pTemp = NULL;
  553. pTemp = pTypeInfoTable;
  554. while (pTemp) {
  555. if (IsEqualIID(iid, pTemp->iid)) {
  556. return pTemp->pTypeInfo;
  557. }
  558. pTemp = pTemp->pNext;
  559. }
  560. return NULL;
  561. }
  562. PTYPEINFO_TABLE
  563. AggregateeAddTypeInfo(
  564. PTYPEINFO_TABLE pTypeInfoTable,
  565. REFIID iid,
  566. ITypeInfo * pTypeInfo
  567. )
  568. {
  569. PTYPEINFO_TABLE pTemp = NULL;
  570. pTemp = (PTYPEINFO_TABLE)LocalAlloc(LPTR, sizeof(TYPEINFO_TABLE));
  571. if (!pTemp) {
  572. return NULL;
  573. }
  574. memcpy(&pTemp->iid, &iid, sizeof(GUID));
  575. pTemp->pTypeInfo = pTypeInfo;
  576. pTemp->pNext = pTypeInfoTable;
  577. return pTemp;
  578. }
  579. //+------------------------------------------------------------------------
  580. //
  581. // Function: LoadTypeInfo
  582. //
  583. // Synopsis: Loads a typeinfo from a registered typelib.
  584. //
  585. // Arguments: [clsidTL] -- TypeLib GUID
  586. // [clsidTI] -- TypeInfo GUID
  587. // [ppTI] -- Resulting typeInfo
  588. //
  589. // Returns: HRESULT
  590. //
  591. //-------------------------------------------------------------------------
  592. HRESULT
  593. AggregateeLoadTypeInfo(CLSID clsidTL, CLSID clsidTI, LPTYPEINFO *ppTI)
  594. {
  595. HRESULT hr;
  596. ITypeLib * pTL;
  597. DispMgrAssert(ppTI);
  598. *ppTI = NULL;
  599. hr = LoadRegTypeLib(clsidTL, 1, 0, LOCALE_SYSTEM_DEFAULT, &pTL);
  600. if (!SUCCEEDED(hr))
  601. return hr;
  602. hr = pTL->GetTypeInfoOfGuid(clsidTI, ppTI);
  603. pTL->Release();
  604. return hr;
  605. }
  606. HRESULT
  607. CAggregateeDispMgr::LoadTypeInfoEntry(
  608. REFIID libid,
  609. REFIID iid,
  610. void * pIntf,
  611. DISPID SpecialId
  612. )
  613. {
  614. ITypeInfo * pTypeInfo = NULL;
  615. HRESULT hr;
  616. ENTER_EXT_TYPEINFO_CRITSECT();
  617. pTypeInfo = ::AggregateeFindTypeInfo(gpAggregateeTypeInfoTable, iid);
  618. if (!pTypeInfo) {
  619. LEAVE_EXT_TYPEINFO_CRITSECT();
  620. hr = AggregateeLoadTypeInfo(libid, iid, &pTypeInfo);
  621. BAIL_ON_FAILURE(hr);
  622. ENTER_EXT_TYPEINFO_CRITSECT();
  623. gpAggregateeTypeInfoTable = ::AggregateeAddTypeInfo(
  624. gpAggregateeTypeInfoTable,
  625. iid,
  626. pTypeInfo
  627. );
  628. if (!gpAggregateeTypeInfoTable) {
  629. LEAVE_EXT_TYPEINFO_CRITSECT();
  630. BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(GetLastError()));
  631. }
  632. //
  633. // Increment the global list of the types of type info's.
  634. //
  635. InterlockedIncrement(&glnMSEXTTypesOfInfo);
  636. InterlockedIncrement(&glnMSEXTObjCount);
  637. }
  638. pTypeInfo->AddRef();
  639. hr = AddTypeInfo(pTypeInfo, pIntf);
  640. BAIL_ON_FAILURE(hr);
  641. //
  642. // We have a ref on the object as add was succesful
  643. //
  644. InterlockedIncrement(&glnMSEXTObjCount);
  645. LEAVE_EXT_TYPEINFO_CRITSECT();
  646. if (SpecialId == -4) {
  647. hr = MarkAsNewEnum(pTypeInfo);
  648. } else if (SpecialId == DISPID_VALUE) {
  649. hr = MarkAsItem(pTypeInfo);
  650. }
  651. return S_OK;
  652. error:
  653. if (pTypeInfo)
  654. pTypeInfo->Release();
  655. return hr;
  656. }
  657. //
  658. // Kept for backwards compatibility.
  659. //
  660. HRESULT
  661. LoadTypeInfoEntry(
  662. CAggregateeDispMgr *pDispMgr,
  663. REFIID libid,
  664. REFIID iid,
  665. void * pIntf,
  666. DISPID SpecialId
  667. )
  668. {
  669. return pDispMgr->LoadTypeInfoEntry(libid, iid, pIntf, SpecialId);
  670. }
  671. void
  672. AggregateeFreeTypeInfoTable()
  673. {
  674. PTYPEINFO_TABLE pTypeInfoTable = NULL;
  675. PTYPEINFO_TABLE pTemp = NULL;
  676. ITypeInfo * pTypeInfo = NULL;
  677. pTypeInfoTable = gpAggregateeTypeInfoTable;
  678. while (pTypeInfoTable) {
  679. pTypeInfo = pTypeInfoTable->pTypeInfo;
  680. pTypeInfo->Release();
  681. pTemp = pTypeInfoTable;
  682. pTypeInfoTable = pTypeInfoTable->pNext;
  683. LocalFree(pTemp);
  684. }
  685. }
  686. HRESULT
  687. CAggregateeDispMgr::InitializeDispMgr(
  688. DWORD dwExtensionID
  689. )
  690. {
  691. if (dwExtensionID > 255) {
  692. return(E_FAIL);
  693. }
  694. _dwExtensionID = dwExtensionID;
  695. return(S_OK);
  696. }
  697. BOOL
  698. AggregateeDllCanUnload()
  699. {
  700. BOOL retVal = FALSE;
  701. ENTER_EXT_TYPEINFO_CRITSECT();
  702. retVal = (glnMSEXTObjCount == 0);
  703. LEAVE_EXT_TYPEINFO_CRITSECT();
  704. return retVal;
  705. }