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.

1051 lines
24 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. seolib.cpp
  5. Abstract:
  6. This module contains the implementations for various
  7. utility classes and functions of the Server Extension
  8. Object system.
  9. Author:
  10. Don Dumitru (dondu@microsoft.com)
  11. Revision History:
  12. dondu 05/20/97 Created.
  13. --*/
  14. #include <stdio.h>
  15. #include <windows.h>
  16. #include <mailmsg.h>
  17. #include <dbgtrace.h>
  18. #include <cpool.h>
  19. #include <filehc.h>
  20. #define _ATL_NO_DEBUG_CRT
  21. #define _ATL_STATIC_REGISTRY 1
  22. #define _ASSERTE _ASSERT
  23. #define _WINDLL
  24. #include "atlbase.h"
  25. extern CComModule _Module;
  26. #include "atlcom.h"
  27. #undef _WINDLL
  28. #include "seo.h"
  29. #include "seolib.h"
  30. CEventBaseDispatcher::CEventBaseDispatcher() {
  31. // nothing
  32. }
  33. CEventBaseDispatcher::~CEventBaseDispatcher() {
  34. // nothing
  35. }
  36. CEventBaseDispatcher::CBinding::CBinding() {
  37. m_bIsValid = FALSE;
  38. }
  39. CEventBaseDispatcher::CBinding::~CBinding() {
  40. // nothing
  41. }
  42. HRESULT CEventBaseDispatcher::CBinding::Init(IEventBinding *piBinding) {
  43. HRESULT hrRes;
  44. CComPtr<IEventPropertyBag> pProps;
  45. CComVariant varValue;
  46. if (!piBinding) {
  47. return (E_POINTER);
  48. }
  49. varValue.vt = VT_BOOL;
  50. hrRes = piBinding->get_Enabled(&varValue.boolVal);
  51. if (!SUCCEEDED(hrRes)) {
  52. return (hrRes);
  53. }
  54. m_bIsValid = varValue.boolVal ? TRUE: FALSE;
  55. varValue.Clear();
  56. m_dwPriority = (DWORD) PRIO_DEFAULT;
  57. m_bExclusive = FALSE;
  58. m_piBinding = piBinding;
  59. hrRes = piBinding->get_SourceProperties(&pProps);
  60. if (!SUCCEEDED(hrRes)) {
  61. return (hrRes);
  62. }
  63. hrRes = pProps->Item(&CComVariant(L"Priority"),&varValue);
  64. if (SUCCEEDED(hrRes) && (hrRes != S_FALSE)) {
  65. hrRes = varValue.ChangeType(VT_I4);
  66. if (SUCCEEDED(hrRes)) {
  67. if (varValue.lVal < PRIO_MIN) {
  68. varValue.lVal = PRIO_MIN;
  69. } else if (varValue.lVal > PRIO_MAX) {
  70. varValue.lVal = PRIO_MAX;
  71. }
  72. m_dwPriority = (DWORD) varValue.lVal;
  73. } else {
  74. hrRes = varValue.ChangeType(VT_BSTR);
  75. if (SUCCEEDED(hrRes)) {
  76. static struct {
  77. LPCWSTR pszString;
  78. DWORD dwValue;
  79. } sConvert[] = {{PRIO_HIGHEST_STR,PRIO_HIGHEST},
  80. {PRIO_HIGH_STR,PRIO_HIGH},
  81. {PRIO_MEDIUM_STR,PRIO_MEDIUM},
  82. {PRIO_LOW_STR,PRIO_LOW},
  83. {PRIO_LOWEST_STR,PRIO_LOWEST},
  84. {PRIO_DEFAULT_STR,PRIO_DEFAULT},
  85. {NULL,0}};
  86. for (DWORD dwIdx=0;sConvert[dwIdx].pszString;dwIdx++) {
  87. if (_wcsicmp(varValue.bstrVal,sConvert[dwIdx].pszString) == 0) {
  88. m_dwPriority = sConvert[dwIdx].dwValue;
  89. break;
  90. }
  91. }
  92. }
  93. }
  94. }
  95. varValue.Clear();
  96. hrRes = pProps->Item(&CComVariant(L"Exclusive"),&varValue);
  97. if (SUCCEEDED(hrRes) && (hrRes != S_FALSE)) {
  98. hrRes = varValue.ChangeType(VT_BOOL);
  99. if (SUCCEEDED(hrRes)) {
  100. m_bExclusive = (varValue.boolVal ? TRUE : FALSE);
  101. }
  102. }
  103. hrRes = InitRuleEngine();
  104. // ignore result
  105. return (S_OK);
  106. }
  107. int CEventBaseDispatcher::CBinding::Compare(const CBinding& b) const {
  108. #if 0
  109. if (!m_bIsValid || !b.m_bIsValid) {
  110. if (m_bIsValid == b.m_bIsValid) {
  111. return (0);
  112. }
  113. if (!b.m_bIsValid) {
  114. return (-1);
  115. }
  116. return (1);
  117. }
  118. #endif
  119. if (m_dwPriority == b.m_dwPriority) {
  120. return (0);
  121. }
  122. if (m_dwPriority < b.m_dwPriority) {
  123. return (-1);
  124. }
  125. return (1);
  126. }
  127. HRESULT CEventBaseDispatcher::CBinding::InitRuleEngine(IEventBinding *piBinding, REFIID iidDesired, IUnknown **ppUnkRuleEngine) {
  128. HRESULT hrRes;
  129. CComPtr<IEventPropertyBag> pProperties;
  130. CComVariant varValue;
  131. CStringGUID objGuid;
  132. if (ppUnkRuleEngine) {
  133. *ppUnkRuleEngine = NULL;
  134. }
  135. if (!piBinding || !ppUnkRuleEngine) {
  136. return (E_POINTER);
  137. }
  138. hrRes = piBinding->get_SourceProperties(&pProperties);
  139. if (!SUCCEEDED(hrRes)) {
  140. return (hrRes);
  141. }
  142. hrRes = pProperties->Item(&CComVariant(L"RuleEngine"),&varValue);
  143. if (!SUCCEEDED(hrRes) || (hrRes == S_FALSE)) {
  144. return (hrRes);
  145. }
  146. hrRes = SEOCreateObject(&varValue,piBinding,pProperties,iidDesired,ppUnkRuleEngine);
  147. return (SUCCEEDED(hrRes)?S_OK:S_FALSE);
  148. }
  149. HRESULT CEventBaseDispatcher::CBinding::InitRuleEngine() {
  150. // default is to not to try to load a rule engine
  151. return (S_OK);
  152. }
  153. int CEventBaseDispatcher::CBindingList::Compare(CBinding* p1, CBinding* p2) {
  154. return (p1->Compare(*p2));
  155. };
  156. HRESULT CEventBaseDispatcher::CParams::CheckRule(CBinding& b) {
  157. // default behavior is to not pay attention to any "rules"
  158. return (S_OK);
  159. }
  160. HRESULT CEventBaseDispatcher::CParams::CallObject(IEventManager *piManager, CBinding& bBinding) {
  161. HRESULT hrRes;
  162. CComPtr<IUnknown> pUnkSink;
  163. if (!piManager) {
  164. return (E_POINTER);
  165. }
  166. hrRes = piManager->CreateSink(bBinding.m_piBinding,NULL,&pUnkSink);
  167. if (!SUCCEEDED(hrRes)) {
  168. return (hrRes);
  169. }
  170. return (CallObject(bBinding,pUnkSink));
  171. }
  172. HRESULT CEventBaseDispatcher::CParams::CallObject(CBinding& bBinding, IUnknown *pUnkSink) {
  173. HRESULT hrRes;
  174. CComQIPtr<IEventSinkNotify,&IID_IEventSinkNotify> pSink;
  175. CComQIPtr<IDispatch,&IID_IEventSinkNotifyDisp> pSinkDisp;
  176. DISPPARAMS dpNoArgs = {NULL,NULL,0,0};
  177. // Default behavior is to call IEventSinkNotify::OnEvent, or to call
  178. // IEventSinkNotifyDisp::Invoke passing DISPID_VALUE (which maps to OnEvent).
  179. //
  180. // This means that the base dispatcher is able to invoke simple COM objects. If you
  181. // provide your own CallObject() routine, your routine call delegate this this base
  182. // implementation if you want to "inherit" this functionality.
  183. if (!pUnkSink) {
  184. return (E_POINTER);
  185. }
  186. pSink = pUnkSink;
  187. if (!pSink) {
  188. pSinkDisp = pUnkSink;
  189. }
  190. if (!pSink && !pSinkDisp) {
  191. return (E_NOINTERFACE);
  192. }
  193. if (pSink) {
  194. hrRes = pSink->OnEvent();
  195. return (S_OK);
  196. }
  197. hrRes = pSinkDisp->Invoke(DISPID_VALUE,
  198. IID_NULL,
  199. GetUserDefaultLCID(),
  200. DISPATCH_METHOD,
  201. &dpNoArgs,
  202. NULL,
  203. NULL,
  204. NULL);
  205. if (!SUCCEEDED(hrRes)) {
  206. return (hrRes);
  207. }
  208. return (S_OK);
  209. }
  210. HRESULT CEventBaseDispatcher::CParams::Abort() {
  211. return (S_FALSE);
  212. }
  213. HRESULT CEventBaseDispatcher::Dispatcher(REFGUID rguidEventType, CParams *pParams) {
  214. HRESULT hrRes;
  215. CETData *petdData;
  216. BOOL bObjectCalled = FALSE;
  217. petdData = m_Data.Find(rguidEventType);
  218. if (!petdData) {
  219. return (S_FALSE);
  220. }
  221. for (DWORD dwIdx=0;dwIdx<petdData->Count();dwIdx++) {
  222. if (!petdData->Index(dwIdx)->m_bIsValid) {
  223. continue;
  224. }
  225. if (bObjectCalled && petdData->Index(dwIdx)->m_bExclusive) {
  226. continue;
  227. }
  228. if (pParams->Abort() == S_OK) {
  229. break;
  230. }
  231. hrRes = pParams->CheckRule(*petdData->Index(dwIdx));
  232. if (hrRes == S_OK) {
  233. if (pParams->Abort() == S_OK) {
  234. break;
  235. }
  236. hrRes = pParams->CallObject(m_piEventManager,*petdData->Index(dwIdx));
  237. if (!SUCCEEDED(hrRes)) {
  238. continue;
  239. }
  240. bObjectCalled = TRUE;
  241. if ((hrRes == S_FALSE) || petdData->Index(dwIdx)->m_bExclusive) {
  242. break;
  243. }
  244. }
  245. }
  246. return (bObjectCalled?S_OK:S_FALSE);
  247. }
  248. HRESULT CEventBaseDispatcher::SetContext(REFGUID rguidEventType, IEventRouter *piRouter, IEventBindings *piBindings) {
  249. CETData* petData;
  250. HRESULT hrRes;
  251. CComPtr<IUnknown> pUnkEnum;
  252. CComQIPtr<IEnumVARIANT,&IID_IEnumVARIANT> pEnum;
  253. if (!piRouter || !piBindings) {
  254. return (E_POINTER);
  255. }
  256. if (!m_piEventManager) {
  257. hrRes = CoCreateInstance(CLSID_CEventManager,
  258. NULL,
  259. CLSCTX_ALL,
  260. IID_IEventManager,
  261. (LPVOID *) &m_piEventManager);
  262. if (!SUCCEEDED(hrRes)) {
  263. return (hrRes);
  264. }
  265. m_piRouter = piRouter;
  266. }
  267. petData = m_Data.Find(rguidEventType);
  268. if (!petData) {
  269. hrRes = AllocETData(rguidEventType,piBindings,&petData);
  270. if (!SUCCEEDED(hrRes)) {
  271. return (hrRes);
  272. }
  273. petData->m_guidEventType = rguidEventType;
  274. hrRes = m_Data.Add(petData);
  275. if (!SUCCEEDED(hrRes)) {
  276. delete petData;
  277. return (hrRes);
  278. }
  279. }
  280. petData->RemoveAll();
  281. hrRes = piBindings->get__NewEnum(&pUnkEnum);
  282. if (!SUCCEEDED(hrRes)) {
  283. return (hrRes);
  284. }
  285. pEnum = pUnkEnum;
  286. if (!pEnum) {
  287. return (E_NOINTERFACE);
  288. }
  289. while (1) {
  290. CComVariant varValue;
  291. CComQIPtr<IEventBinding,&IID_IEventBinding> pBinding;
  292. CBinding *pNewBinding;
  293. varValue.Clear();
  294. hrRes = pEnum->Next(1,&varValue,NULL);
  295. if (!SUCCEEDED(hrRes)) {
  296. return (hrRes);
  297. }
  298. if (hrRes == S_FALSE) {
  299. break;
  300. }
  301. hrRes = varValue.ChangeType(VT_UNKNOWN);
  302. if (!SUCCEEDED(hrRes)) {
  303. _ASSERTE(FALSE);
  304. continue;
  305. }
  306. pBinding = varValue.punkVal;
  307. if (!pBinding) {
  308. _ASSERTE(FALSE);
  309. continue;
  310. }
  311. hrRes = AllocBinding(rguidEventType,pBinding,&pNewBinding);
  312. if (!SUCCEEDED(hrRes)) {
  313. return (hrRes);
  314. }
  315. hrRes = pNewBinding->Init(pBinding);
  316. if (!SUCCEEDED(hrRes)) {
  317. return (hrRes);
  318. }
  319. hrRes = petData->Add(pNewBinding);
  320. if (!SUCCEEDED(hrRes)) {
  321. delete pNewBinding;
  322. return (hrRes);
  323. }
  324. }
  325. return (S_OK);
  326. }
  327. CEventBaseDispatcher::CETData::CETData() {
  328. // nothing
  329. }
  330. CEventBaseDispatcher::CETData::~CETData() {
  331. // nothing
  332. }
  333. CEventBaseDispatcher::CETData* CEventBaseDispatcher::CETDataList::Find(REFGUID guidEventType) {
  334. // tbd - optimize
  335. for (DWORD dwIdx=0;dwIdx<Count();dwIdx++) {
  336. if (Index(dwIdx)->m_guidEventType == guidEventType) {
  337. return (Index(dwIdx));
  338. }
  339. }
  340. return (NULL);
  341. }
  342. HRESULT CEventBaseDispatcher::AllocBinding(REFGUID rguidEventType,
  343. IEventBinding *piBinding,
  344. CBinding **ppNewBinding) {
  345. if (ppNewBinding) {
  346. *ppNewBinding = NULL;
  347. }
  348. if (!piBinding || !ppNewBinding) {
  349. return (E_POINTER);
  350. }
  351. *ppNewBinding = new CBinding;
  352. if (!*ppNewBinding) {
  353. return (E_OUTOFMEMORY);
  354. }
  355. return (S_OK);
  356. }
  357. HRESULT CEventBaseDispatcher::AllocETData(REFGUID guidEventType,
  358. IEventBindings *piBindings,
  359. CETData **ppNewETData) {
  360. if (ppNewETData) {
  361. *ppNewETData = NULL;
  362. }
  363. if (!piBindings || !ppNewETData) {
  364. return (E_POINTER);
  365. }
  366. *ppNewETData = new CETData;
  367. if (!*ppNewETData) {
  368. return (E_OUTOFMEMORY);
  369. }
  370. return (S_OK);
  371. }
  372. static HRESULT SEOGetSources(REFGUID rguidSourceType, IEventSources **ppSources) {
  373. HRESULT hrRes;
  374. CComPtr<IEventManager> pManager;
  375. CComPtr<IEventSourceTypes> pSourceTypes;
  376. CComPtr<IEventSourceType> pSourceType;
  377. CComPtr<IEventSources> pSources;
  378. if (ppSources) {
  379. *ppSources = NULL;
  380. }
  381. if (!ppSources) {
  382. hrRes = E_POINTER;
  383. goto error;
  384. }
  385. hrRes = CoCreateInstance(CLSID_CEventManager,NULL,CLSCTX_ALL,IID_IEventManager,(LPVOID *) &pManager);
  386. if (!SUCCEEDED(hrRes)) {
  387. goto error;
  388. }
  389. hrRes = pManager->get_SourceTypes(&pSourceTypes);
  390. if (!SUCCEEDED(hrRes)) {
  391. goto error;
  392. }
  393. hrRes = pSourceTypes->Item(&CComVariant((LPCOLESTR) CStringGUID(rguidSourceType)),&pSourceType);
  394. if (!SUCCEEDED(hrRes)) {
  395. goto error;
  396. }
  397. if (!pSourceType) {
  398. hrRes = S_FALSE;
  399. goto error;
  400. }
  401. hrRes = pSourceType->get_Sources(ppSources);
  402. error:
  403. return (hrRes);
  404. }
  405. static HRESULT SEOGetSourcesEnum(REFGUID rguidSourceType, IEnumVARIANT **ppEnum) {
  406. HRESULT hrRes;
  407. CComPtr<IEventSources> pSources;
  408. CComPtr<IUnknown> pUnkEnum;
  409. if (ppEnum) {
  410. *ppEnum = NULL;
  411. }
  412. if (!ppEnum) {
  413. hrRes = E_POINTER;
  414. goto error;
  415. }
  416. hrRes = SEOGetSources(rguidSourceType,&pSources);
  417. if (!SUCCEEDED(hrRes)) {
  418. goto error;
  419. }
  420. if (!pSources) {
  421. hrRes = S_FALSE;
  422. goto error;
  423. }
  424. hrRes = pSources->get__NewEnum(&pUnkEnum);
  425. if (!SUCCEEDED(hrRes)) {
  426. goto error;
  427. }
  428. hrRes = pUnkEnum->QueryInterface(IID_IEnumVARIANT,(LPVOID *) ppEnum);
  429. error:
  430. return (hrRes);
  431. }
  432. STDMETHODIMP SEOGetSource(REFGUID rguidSourceType, REFGUID rguidSource, IEventSource **ppSource) {
  433. HRESULT hrRes;
  434. CComPtr<IEventSources> pSources;
  435. if (ppSource) {
  436. *ppSource = NULL;
  437. }
  438. if (!ppSource) {
  439. hrRes = E_POINTER;
  440. goto error;
  441. }
  442. hrRes = SEOGetSources(rguidSourceType,&pSources);
  443. if (!SUCCEEDED(hrRes)) {
  444. goto error;
  445. }
  446. if (!pSources) {
  447. hrRes = S_FALSE;
  448. goto error;
  449. }
  450. hrRes = pSources->Item(&CComVariant((LPCOLESTR) CStringGUID(rguidSource)),ppSource);
  451. error:
  452. return (hrRes);
  453. }
  454. STDMETHODIMP SEOGetSource(REFGUID rguidSourceType, REFGUID rguidSourceBase, DWORD dwSourceIndex, IEventSource **ppSource) {
  455. return (SEOGetSource(rguidSourceType,(REFGUID) CStringGUID(rguidSourceBase,dwSourceIndex),ppSource));
  456. }
  457. STDMETHODIMP SEOGetSource(REFGUID rguidSourceType, LPCSTR pszDisplayName, IEventSource **ppSource) {
  458. HRESULT hrRes;
  459. CComPtr<IEnumVARIANT> pEnum;
  460. CComVariant varValue;
  461. CComQIPtr<IEventSource,&IID_IEventSource> pSource;
  462. CComBSTR strDisplayName;
  463. CComBSTR strDesiredName;
  464. if (ppSource) {
  465. *ppSource = NULL;
  466. }
  467. if (!ppSource || !pszDisplayName) {
  468. hrRes = E_POINTER;
  469. goto error;
  470. }
  471. hrRes = SEOGetSourcesEnum(rguidSourceType,&pEnum);
  472. if (!SUCCEEDED(hrRes)) {
  473. goto error;
  474. }
  475. if (!pEnum) {
  476. hrRes = S_FALSE;
  477. goto error;
  478. }
  479. strDesiredName = pszDisplayName;
  480. while (1) {
  481. varValue.Clear();
  482. hrRes = pEnum->Next(1,&varValue,NULL);
  483. if (!SUCCEEDED(hrRes)) {
  484. goto error;
  485. }
  486. if (hrRes == S_FALSE) {
  487. break;
  488. }
  489. hrRes = varValue.ChangeType(VT_UNKNOWN);
  490. if (!SUCCEEDED(hrRes)) {
  491. goto error;
  492. }
  493. pSource = varValue.punkVal;
  494. if (!pSource) {
  495. hrRes = E_NOINTERFACE;
  496. goto error;
  497. }
  498. strDisplayName.Empty();
  499. hrRes = pSource->get_DisplayName(&strDisplayName);
  500. if (!SUCCEEDED(hrRes)) {
  501. goto error;
  502. }
  503. if (wcscmp(strDisplayName,strDesiredName) == 0) {
  504. *ppSource = pSource;
  505. (*ppSource)->AddRef();
  506. hrRes = S_OK;
  507. break;
  508. }
  509. }
  510. error:
  511. return (hrRes);
  512. }
  513. class CValueBase {
  514. public:
  515. virtual BOOL Match(VARIANT *pValue) = 0;
  516. };
  517. static HRESULT SEOGetSource(REFGUID rguidSourceType, LPCSTR pszProperty, CValueBase *pValue, IEventSource **ppSource) {
  518. HRESULT hrRes;
  519. CComPtr<IEnumVARIANT> pEnum;
  520. CComVariant varValue;
  521. CComQIPtr<IEventSource,&IID_IEventSource> pSource;
  522. CComVariant varProperty;
  523. CComPtr<IEventPropertyBag> pProperties;
  524. if (ppSource) {
  525. *ppSource = NULL;
  526. }
  527. if (!ppSource || !pszProperty) {
  528. hrRes = E_POINTER;
  529. goto error;
  530. }
  531. hrRes = SEOGetSourcesEnum(rguidSourceType,&pEnum);
  532. if (!SUCCEEDED(hrRes)) {
  533. goto error;
  534. }
  535. if (!pEnum) {
  536. hrRes = S_FALSE;
  537. goto error;
  538. }
  539. varProperty = pszProperty;
  540. while (1) {
  541. varValue.Clear();
  542. hrRes = pEnum->Next(1,&varValue,NULL);
  543. if (!SUCCEEDED(hrRes)) {
  544. goto error;
  545. }
  546. if (hrRes == S_FALSE) {
  547. break;
  548. }
  549. hrRes = varValue.ChangeType(VT_UNKNOWN);
  550. if (!SUCCEEDED(hrRes)) {
  551. goto error;
  552. }
  553. pSource = varValue.punkVal;
  554. if (!pSource) {
  555. hrRes = E_NOINTERFACE;
  556. goto error;
  557. }
  558. pProperties.Release();
  559. hrRes = pSource->get_Properties(&pProperties);
  560. if (!SUCCEEDED(hrRes)) {
  561. goto error;
  562. }
  563. varValue.Clear();
  564. hrRes = pProperties->Item(&varProperty,&varValue);
  565. if (!SUCCEEDED(hrRes)) {
  566. goto error;
  567. }
  568. if (hrRes == S_FALSE) {
  569. continue;
  570. }
  571. if (pValue->Match(&varValue)) {
  572. *ppSource = pSource;
  573. (*ppSource)->AddRef();
  574. hrRes = S_OK;
  575. break;
  576. }
  577. }
  578. error:
  579. return (hrRes);
  580. }
  581. class CValueDWORD : public CValueBase {
  582. public:
  583. CValueDWORD(DWORD dwValue) {
  584. m_dwValue = dwValue;
  585. };
  586. virtual BOOL Match(VARIANT *pValue) {
  587. HRESULT hrRes = VariantChangeType(pValue,pValue,0,VT_I4);
  588. if (!SUCCEEDED(hrRes)) {
  589. return (FALSE);
  590. }
  591. if ((DWORD) pValue->lVal != m_dwValue) {
  592. return (FALSE);
  593. }
  594. return (TRUE);
  595. };
  596. private:
  597. DWORD m_dwValue;
  598. };
  599. STDMETHODIMP SEOGetSource(REFGUID rguidSourceType, LPCSTR pszProperty, DWORD dwValue, IEventSource **ppSource) {
  600. return (SEOGetSource(rguidSourceType,pszProperty,&CValueDWORD(dwValue),ppSource));
  601. }
  602. class CValueBSTR : public CValueBase {
  603. public:
  604. CValueBSTR(LPCWSTR pszValue) {
  605. m_strValue = SysAllocString(pszValue);
  606. };
  607. CValueBSTR(LPCSTR pszValue) {
  608. USES_CONVERSION;
  609. m_strValue = SysAllocString(A2W(pszValue));
  610. };
  611. ~CValueBSTR() {
  612. SysFreeString(m_strValue);
  613. };
  614. virtual BOOL Match(VARIANT *pValue) {
  615. HRESULT hrRes = VariantChangeType(pValue,pValue,0,VT_BSTR);
  616. if (!SUCCEEDED(hrRes)) {
  617. return (FALSE);
  618. }
  619. if (wcscmp(pValue->bstrVal,m_strValue) != 0) {
  620. return (FALSE);
  621. }
  622. return (TRUE);
  623. };
  624. private:
  625. BSTR m_strValue;
  626. };
  627. STDMETHODIMP SEOGetSource(REFGUID rguidSourceType, LPCSTR pszProperty, LPCSTR pszValue, IEventSource **ppSource) {
  628. return (SEOGetSource(rguidSourceType,pszProperty,&CValueBSTR(pszValue),ppSource));
  629. }
  630. static HRESULT SEOGetRouter(IEventSource *pSource, IEventRouter **ppRouter) {
  631. HRESULT hrRes;
  632. CComPtr<IEventBindingManager> pManager;
  633. CComPtr<IEventRouter> pRouter;
  634. if (ppRouter) {
  635. *ppRouter = NULL;
  636. }
  637. if (!pSource || !ppRouter) {
  638. hrRes = E_POINTER;
  639. goto error;
  640. }
  641. hrRes = pSource->GetBindingManager(&pManager);
  642. if (!SUCCEEDED(hrRes)) {
  643. goto error;
  644. }
  645. hrRes = CoCreateInstance(CLSID_CEventRouter,NULL,CLSCTX_ALL,IID_IEventRouter,(LPVOID *) &pRouter);
  646. if (!SUCCEEDED(hrRes)) {
  647. goto error;
  648. }
  649. hrRes = pRouter->put_Database(pManager);
  650. if (!SUCCEEDED(hrRes)) {
  651. goto error;
  652. }
  653. *ppRouter = pRouter;
  654. (*ppRouter)->AddRef();
  655. error:
  656. return (hrRes);
  657. }
  658. STDMETHODIMP SEOGetRouter(REFGUID rguidSourceType, REFGUID rguidSource, IEventRouter **ppRouter) {
  659. HRESULT hrRes;
  660. CComPtr<IEventSource> pSource;
  661. if (ppRouter) {
  662. *ppRouter = NULL;
  663. }
  664. if (!ppRouter) {
  665. hrRes = E_POINTER;
  666. goto error;
  667. }
  668. hrRes = SEOGetSource(rguidSourceType,rguidSource,&pSource);
  669. if (!SUCCEEDED(hrRes)) {
  670. goto error;
  671. }
  672. if (!pSource) {
  673. hrRes = S_FALSE;
  674. goto error;
  675. }
  676. hrRes = SEOGetRouter(pSource,ppRouter);
  677. error:
  678. return (hrRes);
  679. }
  680. STDMETHODIMP SEOGetRouter(REFGUID rguidSourceType, REFGUID rguidSourceBase, DWORD dwSourceIndex, IEventRouter **ppRouter) {
  681. return (SEOGetRouter(rguidSourceType,(REFGUID) CStringGUID(rguidSourceBase,dwSourceIndex),ppRouter));
  682. }
  683. STDMETHODIMP SEOGetRouter(REFGUID rguidSourceType, LPCSTR pszDisplayName, IEventRouter **ppRouter) {
  684. HRESULT hrRes;
  685. CComPtr<IEventSource> pSource;
  686. if (ppRouter) {
  687. *ppRouter = NULL;
  688. }
  689. if (!ppRouter) {
  690. hrRes = E_POINTER;
  691. goto error;
  692. }
  693. hrRes = SEOGetSource(rguidSourceType,pszDisplayName,&pSource);
  694. if (!SUCCEEDED(hrRes)) {
  695. goto error;
  696. }
  697. if (!pSource) {
  698. hrRes = S_FALSE;
  699. goto error;
  700. }
  701. hrRes = SEOGetRouter(pSource,ppRouter);
  702. error:
  703. return (hrRes);
  704. }
  705. STDMETHODIMP SEOGetRouter(REFGUID rguidSourceType, LPCSTR pszProperty, DWORD dwValue, IEventRouter **ppRouter) {
  706. HRESULT hrRes;
  707. CComPtr<IEventSource> pSource;
  708. if (ppRouter) {
  709. *ppRouter = NULL;
  710. }
  711. if (!ppRouter) {
  712. hrRes = E_POINTER;
  713. goto error;
  714. }
  715. hrRes = SEOGetSource(rguidSourceType,pszProperty,dwValue,&pSource);
  716. if (!SUCCEEDED(hrRes)) {
  717. goto error;
  718. }
  719. if (!pSource) {
  720. hrRes = S_FALSE;
  721. goto error;
  722. }
  723. hrRes = SEOGetRouter(pSource,ppRouter);
  724. error:
  725. return (hrRes);
  726. }
  727. STDMETHODIMP SEOGetRouter(REFGUID rguidSourceType, LPCSTR pszProperty, LPCSTR pszValue, IEventRouter **ppRouter) {
  728. HRESULT hrRes;
  729. CComPtr<IEventSource> pSource;
  730. if (ppRouter) {
  731. *ppRouter = NULL;
  732. }
  733. if (!ppRouter) {
  734. hrRes = E_POINTER;
  735. goto error;
  736. }
  737. hrRes = SEOGetSource(rguidSourceType,pszProperty,pszValue,&pSource);
  738. if (!SUCCEEDED(hrRes)) {
  739. goto error;
  740. }
  741. if (!pSource) {
  742. hrRes = S_FALSE;
  743. goto error;
  744. }
  745. hrRes = SEOGetRouter(pSource,ppRouter);
  746. error:
  747. return (hrRes);
  748. }
  749. #include <initguid.h>
  750. // This CLSID must match the one in SEO.DLL.
  751. // {A4BE1350-1051-11d1-AA1E-00AA006BC80B}
  752. DEFINE_GUID(CLSID_CEventServiceObject,
  753. 0xa4be1350, 0x1051, 0x11d1, 0xaa, 0x1e, 0x0, 0xaa, 0x0, 0x6b, 0xc8, 0xb);
  754. STDMETHODIMP SEOGetServiceHandle(IUnknown **ppUnkHandle) {
  755. return (CoCreateInstance(CLSID_CEventServiceObject,
  756. NULL,
  757. CLSCTX_ALL,
  758. IID_IUnknown,
  759. (LPVOID *) ppUnkHandle));
  760. }
  761. STDMETHODIMP SEOCreateObject(VARIANT *pvarClass,
  762. IEventBinding *pBinding,
  763. IUnknown *pInitProperties,
  764. REFIID iidDesired,
  765. IUnknown **ppUnkObject) {
  766. return (SEOCreateObjectEx(pvarClass,pBinding,pInitProperties,iidDesired,NULL,ppUnkObject));
  767. }
  768. STDMETHODIMP SEOCreateObjectEx(VARIANT *pvarClass,
  769. IEventBinding *pBinding,
  770. IUnknown *pInitProperties,
  771. REFIID iidDesired,
  772. IUnknown *pUnkCreateOptions,
  773. IUnknown **ppUnkObject) {
  774. HRESULT hrRes;
  775. CStringGUID objGuid;
  776. BSTR strClass;
  777. CComQIPtr<IEventCreateOptions,&IID_IEventCreateOptions> pOpt;
  778. if (ppUnkObject) {
  779. *ppUnkObject = NULL;
  780. }
  781. if (!pvarClass || !ppUnkObject) {
  782. return (E_POINTER);
  783. }
  784. if (pUnkCreateOptions) {
  785. pOpt = pUnkCreateOptions;
  786. }
  787. if (pvarClass->vt == VT_BSTR) {
  788. strClass = pvarClass->bstrVal;
  789. } else if (pvarClass->vt == (VT_BYREF|VT_BSTR)) {
  790. strClass = *pvarClass->pbstrVal;
  791. } else {
  792. hrRes = VariantChangeType(pvarClass,pvarClass,0,VT_BSTR);
  793. if (!SUCCEEDED(hrRes)) {
  794. return (hrRes);
  795. }
  796. strClass = pvarClass->bstrVal;
  797. }
  798. objGuid.CalcFromProgID(strClass);
  799. if (!objGuid) {
  800. objGuid = strClass;
  801. if (!objGuid) {
  802. CComPtr<IBindCtx> pBindCtx;
  803. CComPtr<IMoniker> pMoniker;
  804. DWORD dwEaten;
  805. if (!pOpt || ((hrRes=pOpt->CreateBindCtx(0,&pBindCtx))==E_NOTIMPL)) {
  806. hrRes = CreateBindCtx(0,&pBindCtx);
  807. }
  808. _ASSERTE(SUCCEEDED(hrRes));
  809. if (SUCCEEDED(hrRes)) {
  810. if (!pOpt || ((hrRes=pOpt->MkParseDisplayName(pBindCtx,
  811. strClass,
  812. &dwEaten,
  813. &pMoniker))==E_NOTIMPL)) {
  814. hrRes = MkParseDisplayName(pBindCtx,strClass,&dwEaten,&pMoniker);
  815. }
  816. }
  817. _ASSERTE(!SUCCEEDED(hrRes)||pMoniker);
  818. if (!SUCCEEDED(hrRes)) {
  819. #if 0 // tbd - We try both the normal and the Ex versions of MkParseDisplayName. Just use one.
  820. pBindCtx.Release();
  821. hrRes = CreateBindCtx(0,&pBindCtx);
  822. _ASSERTE(SUCCEEDED(hrRes));
  823. if (!SUCCEEDED(hrRes)) {
  824. return (hrRes);
  825. }
  826. if (!pOpt||((hrRes=pOpt->MkParseDisplayNameEx(pBindCtx,
  827. strClass,
  828. &dwEaten,
  829. &pMoniker))==E_NOTIMPL) {
  830. hrRes = MkParseDisplayNameEx(pBindCtx,strClass,&dwEaten,&pMoniker);
  831. }
  832. _ASSERTE(!SUCCEEDED(hrRes)||pMoniker);
  833. if (!SUCCEEDED(hrRes)) {
  834. return (hrRes);
  835. }
  836. #else
  837. return (hrRes);
  838. #endif
  839. }
  840. pBindCtx.Release();
  841. if (!pOpt || ((hrRes=pOpt->CreateBindCtx(0,&pBindCtx))==E_NOTIMPL)) {
  842. hrRes = CreateBindCtx(0,&pBindCtx);
  843. }
  844. if (!SUCCEEDED(hrRes)) {
  845. _ASSERTE(FALSE);
  846. return (hrRes);
  847. }
  848. if (!pOpt || ((hrRes=pOpt->BindToObject(pMoniker,
  849. pBindCtx,
  850. NULL,
  851. iidDesired,
  852. (LPVOID *) ppUnkObject))==E_NOTIMPL)) {
  853. hrRes = pMoniker->BindToObject(pBindCtx,NULL,iidDesired,(LPVOID *) ppUnkObject);
  854. }
  855. _ASSERTE(!SUCCEEDED(hrRes)||!*ppUnkObject);
  856. // Fall through
  857. }
  858. }
  859. // At this point, objGuid will only be TRUE if either CalcFromProgID or
  860. // operator =(LPCOLESTR) succeeded. If both of these failed, then it will
  861. // be FALSE and we will have attempted to interpret the SinkClass as a
  862. // moniker.
  863. if (!!objGuid) { // Use !! to hack-past ambiguous-conversion issues...
  864. if (!pOpt || ((hrRes=pOpt->CoCreateInstance(objGuid,
  865. NULL,
  866. CLSCTX_ALL,
  867. iidDesired,
  868. (LPVOID *) ppUnkObject))==E_NOTIMPL)) {
  869. hrRes = CoCreateInstance(objGuid,NULL,CLSCTX_ALL,iidDesired,(LPVOID *) ppUnkObject);
  870. }
  871. _ASSERTE(!SUCCEEDED(hrRes)||*ppUnkObject);
  872. }
  873. // At this point, hrRes has the result either from pMoniker->BindToObject or
  874. // CoCreateInstance.
  875. if (SUCCEEDED(hrRes)) {
  876. if (!pOpt || ((hrRes=pOpt->Init(iidDesired,ppUnkObject,pBinding,pInitProperties))==E_NOTIMPL)) {
  877. hrRes = S_OK;
  878. CComQIPtr<IEventPersistBinding,&IID_IEventPersistBinding> pBindingInit;
  879. if (pBinding) {
  880. pBindingInit = *ppUnkObject;
  881. }
  882. if (pBindingInit) {
  883. HRESULT hrResTmp;
  884. hrResTmp = pBindingInit->Load(pBinding);
  885. _ASSERTE(SUCCEEDED(hrResTmp));
  886. } else {
  887. CComQIPtr<IPersistPropertyBag,&IID_IPersistPropertyBag> pInit;
  888. if (pInitProperties) {
  889. pInit = *ppUnkObject;
  890. }
  891. if (pInit) {
  892. HRESULT hrResTmp;
  893. CComQIPtr<IPropertyBag,&IID_IPropertyBag> pProps;
  894. pProps = pInitProperties;
  895. _ASSERTE(pProps);
  896. if (pProps) {
  897. hrResTmp = pInit->InitNew();
  898. _ASSERTE(SUCCEEDED(hrResTmp));
  899. if (SUCCEEDED(hrResTmp)) {
  900. hrResTmp = pInit->Load(pProps,NULL); // tbd - pass an IErrorLog object
  901. _ASSERTE(SUCCEEDED(hrResTmp));
  902. }
  903. }
  904. }
  905. }
  906. }
  907. if (!SUCCEEDED(hrRes)) {
  908. (*ppUnkObject)->Release();
  909. *ppUnkObject = NULL;
  910. }
  911. }
  912. return (hrRes);
  913. }