Leaked source code of windows server 2003
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.

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