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.

420 lines
11 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1997 - 1999
  3. Module Name:
  4. csubchng.cxx
  5. Abstract:
  6. This file contains the implementation of the IEventObjectChange
  7. interface. We need to subscribe to this interface for publishing
  8. the DestinationReachable events of SENS's ISensNetwork interface.
  9. Author:
  10. Gopal Parupudi <GopalP>
  11. [Notes:]
  12. optional-notes
  13. Revision History:
  14. GopalP 1/26/1998 Start.
  15. --*/
  16. #include <precomp.hxx>
  17. //
  18. // Globals
  19. //
  20. LONG g_cSubChangeObj; // Count of active components
  21. LONG g_cSubChangeLock; // Count of Server locks
  22. extern LIST *gpReachList;
  23. //
  24. // Constructors and Destructors
  25. //
  26. CImpIEventObjectChange::CImpIEventObjectChange(
  27. void
  28. ) : m_cRef(1L) // Add a reference.
  29. {
  30. InterlockedIncrement(&g_cSubChangeObj);
  31. }
  32. CImpIEventObjectChange::~CImpIEventObjectChange(
  33. void
  34. )
  35. {
  36. InterlockedDecrement(&g_cSubChangeObj);
  37. }
  38. //
  39. // Standard QueryInterface
  40. //
  41. STDMETHODIMP
  42. CImpIEventObjectChange::QueryInterface(
  43. REFIID riid,
  44. LPVOID *ppv
  45. )
  46. {
  47. HRESULT hr;
  48. DebugTraceGuid("CImpIEventObjectChange:QueryInterface()", riid);
  49. hr = S_OK;
  50. *ppv = NULL;
  51. // IUnknown
  52. if (IsEqualIID(riid, IID_IUnknown))
  53. {
  54. *ppv = (ISensNetwork *) this;
  55. }
  56. else
  57. // IEventObjectChange
  58. if (IsEqualIID(riid, IID_IEventObjectChange))
  59. {
  60. *ppv = (ISensNetwork *) this;
  61. }
  62. else
  63. {
  64. hr = E_NOINTERFACE;
  65. }
  66. if (NULL != *ppv)
  67. {
  68. ((LPUNKNOWN)*ppv)->AddRef();
  69. }
  70. return hr;
  71. }
  72. //
  73. // Standard AddRef and Release
  74. //
  75. STDMETHODIMP_(ULONG)
  76. CImpIEventObjectChange::AddRef(
  77. void
  78. )
  79. {
  80. return InterlockedIncrement(&m_cRef);
  81. }
  82. STDMETHODIMP_(ULONG)
  83. CImpIEventObjectChange::Release(
  84. void
  85. )
  86. {
  87. LONG cRefT;
  88. SensPrint(SENS_INFO, (SENS_STRING("\t| CImpIEventObjectChange::Release(m_cRef = %d) called.\n"), m_cRef));
  89. cRefT = InterlockedDecrement((PLONG) &m_cRef);
  90. if (0 == m_cRef)
  91. {
  92. delete this;
  93. }
  94. return cRefT;
  95. }
  96. //
  97. // IEventObjectChange Implementation.
  98. //
  99. STDMETHODIMP
  100. CImpIEventObjectChange::ChangedSubscription(
  101. EOC_ChangeType changeType,
  102. BSTR bstrSubscriptionID
  103. )
  104. {
  105. HRESULT hr;
  106. NODE *pNode;
  107. DWORD dwStatus;
  108. BOOL bSuccess;
  109. BSTR bstrDestinationName;
  110. hr = S_OK;
  111. pNode = NULL;
  112. dwStatus = ERROR_SUCCESS;
  113. bSuccess = FALSE;
  114. bstrDestinationName = NULL;
  115. SensPrint(SENS_INFO, (SENS_STRING("---------------------------------------------------------\n")));
  116. SensPrint(SENS_INFO, (SENS_STRING("CImpIEventObjectChange::ChangedSubscription() called\n\n")));
  117. SensPrint(SENS_INFO, (SENS_STRING(" ChangeType - %d\n"), changeType));
  118. SensPrintW(SENS_INFO, (SENS_BSTR(" bstrSubscriptionID - %s\n"), bstrSubscriptionID));
  119. SensPrint(SENS_INFO, (SENS_STRING("---------------------------------------------------------\n")));
  120. hr = GetDestinationNameFromSubscription(
  121. bstrSubscriptionID,
  122. &bstrDestinationName
  123. );
  124. if (FAILED(hr))
  125. {
  126. SensPrint(SENS_ERR, (SENS_STRING("GetDestinationNameFromSubscription() returned 0x%x\n"), hr));
  127. if (HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION) == hr)
  128. {
  129. hr = S_OK; // Implies we got a non-DestinationReachability subscription.
  130. }
  131. goto Cleanup;
  132. }
  133. else
  134. if (bstrDestinationName == NULL)
  135. {
  136. SensPrintW(SENS_WARN, (SENS_BSTR("Destination is <NULL> !\n")));
  137. goto Cleanup;
  138. }
  139. else
  140. {
  141. SensPrintW(SENS_INFO, (SENS_BSTR("Destination is %s\n"), bstrDestinationName));
  142. }
  143. //
  144. // Deal with the changed subscription appropriately.
  145. //
  146. switch (changeType)
  147. {
  148. case EOC_NewObject:
  149. {
  150. if (wcslen(bstrDestinationName) > MAX_DESTINATION_LENGTH)
  151. {
  152. SensPrintW(SENS_ERR, (SENS_BSTR("Destination %s is too long.\n"), bstrDestinationName));
  153. break;
  154. }
  155. gpReachList->InsertByDest(bstrDestinationName);
  156. StartReachabilityEngine();
  157. break;
  158. }
  159. case EOC_DeletedObject:
  160. // Delete the node from the reachability list.
  161. bSuccess = gpReachList->DeleteByDest(bstrDestinationName);
  162. break;
  163. case EOC_ModifiedObject:
  164. default:
  165. // Nothing to do.
  166. break;;
  167. }
  168. Cleanup:
  169. //
  170. // Cleanup
  171. //
  172. if (bstrDestinationName)
  173. {
  174. ::SysFreeString(bstrDestinationName);
  175. }
  176. return hr;
  177. }
  178. STDMETHODIMP
  179. CImpIEventObjectChange::ChangedEventClass(
  180. EOC_ChangeType changeType,
  181. BSTR bstrSubscriptionID
  182. )
  183. {
  184. SensPrint(SENS_INFO, (SENS_STRING("---------------------------------------------------------\n")));
  185. SensPrint(SENS_INFO, (SENS_STRING("CImpIEventObjectChange::ChangedEventClass() called\n\n")));
  186. SensPrint(SENS_INFO, (SENS_STRING(" ChangeType - %d\n"), changeType));
  187. SensPrintW(SENS_INFO, (SENS_BSTR(" bstrSubscriptionID - %s\n"), bstrSubscriptionID));
  188. SensPrint(SENS_INFO, (SENS_STRING("---------------------------------------------------------\n")));
  189. return S_OK;
  190. }
  191. STDMETHODIMP
  192. CImpIEventObjectChange::ChangedPublisher(
  193. EOC_ChangeType changeType,
  194. BSTR bstrSubscriptionID
  195. )
  196. {
  197. SensPrint(SENS_INFO, (SENS_STRING("---------------------------------------------------------\n")));
  198. SensPrint(SENS_INFO, (SENS_STRING("CImpIEventObjectChange::ChangedPublisher() called\n\n")));
  199. SensPrint(SENS_INFO, (SENS_STRING(" ChangeType - %d\n"), changeType));
  200. SensPrintW(SENS_INFO, (SENS_BSTR(" bstrSubscriptionID - %s\n"), bstrSubscriptionID));
  201. SensPrint(SENS_INFO, (SENS_STRING("---------------------------------------------------------\n")));
  202. return S_OK;
  203. }
  204. HRESULT
  205. GetDestinationNameFromSubscription(
  206. BSTR bstrSubscriptionID,
  207. BSTR *pbstrDestinationName
  208. )
  209. {
  210. HRESULT hr;
  211. int errorIndex;
  212. BSTR bstrPropertyName;
  213. BSTR bstrMethodName;
  214. VARIANT variantPropertyValue;
  215. WCHAR wszQuery[MAX_QUERY_SIZE];
  216. LPOLESTR strDestinationName;
  217. IEventSystem *pIEventSystem;
  218. IEventSubscription *pIEventSubscription;
  219. IUnknown *pIUnkQueryResult;
  220. hr = S_OK;
  221. errorIndex = 0;
  222. strDestinationName = NULL;
  223. bstrPropertyName = NULL;
  224. bstrMethodName = NULL;
  225. *pbstrDestinationName = NULL;
  226. pIEventSystem = NULL;
  227. pIEventSubscription = NULL;
  228. pIUnkQueryResult = NULL;
  229. // Get a new IEventSystem object to play with.
  230. hr = CoCreateInstance(
  231. CLSID_CEventSystem,
  232. NULL,
  233. CLSCTX_SERVER,
  234. IID_IEventSystem,
  235. (LPVOID *) &pIEventSystem
  236. );
  237. if (FAILED(hr))
  238. {
  239. SensPrint(SENS_ERR, (SENS_STRING("GetDestinationNameFromSubscription(): failed to create ")
  240. SENS_STRING("IEventSystem - hr = <%x>\n"), hr));
  241. goto Cleanup;
  242. }
  243. // Form the query
  244. wcscpy(wszQuery, SENS_BSTR("SubscriptionID"));
  245. wcscat(wszQuery, SENS_BSTR("="));
  246. wcscat(wszQuery, bstrSubscriptionID);
  247. wcscat(wszQuery, SENS_BSTR(""));
  248. hr = pIEventSystem->Query(
  249. PROGID_EventSubscription,
  250. wszQuery,
  251. &errorIndex,
  252. &pIUnkQueryResult
  253. );
  254. if (hr != S_OK)
  255. {
  256. SensPrint(SENS_ERR, (SENS_STRING("GetDestinationNameFromSubscription(): failed to Query() ")
  257. SENS_STRING("- hr = <%x>\n"), hr));
  258. goto Cleanup;
  259. }
  260. hr = pIUnkQueryResult->QueryInterface(
  261. IID_IEventSubscription,
  262. (LPVOID *) &pIEventSubscription
  263. );
  264. if (FAILED(hr))
  265. {
  266. SensPrint(SENS_ERR, (SENS_STRING("GetDestinationNameFromSubscription(): QI for IEventSubscription")
  267. SENS_STRING(" failed - hr = <%x>\n"), hr));
  268. goto Cleanup;
  269. }
  270. //
  271. // See if it is a subscription for Destination Reachability event. If not,
  272. // return success. If yes, try to get the value for Publisher property -
  273. // bstrDestination.
  274. //
  275. hr = pIEventSubscription->get_MethodName(
  276. &bstrMethodName
  277. );
  278. if (hr != S_OK)
  279. {
  280. SensPrint(SENS_ERR, (SENS_STRING("GetDestinationNameFromSubscription(): get_MethodName()")
  281. SENS_STRING(" failed - hr = <%x>\n"), hr));
  282. goto Cleanup;
  283. }
  284. if ( (wcscmp(bstrMethodName, DESTINATION_REACHABLE_METHOD) != 0)
  285. && (wcscmp(bstrMethodName, DESTINATION_REACHABLE_NOQOC_METHOD) != 0))
  286. {
  287. hr = HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION);
  288. SensPrint(SENS_ERR, (SENS_STRING("GetDestinationNameFromSubscription(): Non-Reachability event")
  289. SENS_STRING(" subscription (%s). Returning - hr = <%x>\n"), bstrMethodName, hr));
  290. goto Cleanup;
  291. }
  292. //
  293. // Try to get the value for Publisher property - bstrDestination
  294. //
  295. VariantInit(&variantPropertyValue);
  296. AllocateBstrFromString(bstrPropertyName, PROPERTY_DESTINATION);
  297. hr = pIEventSubscription->GetPublisherProperty(
  298. bstrPropertyName,
  299. &variantPropertyValue
  300. );
  301. if (hr == S_OK)
  302. {
  303. *pbstrDestinationName = variantPropertyValue.bstrVal;
  304. // Found the property!
  305. goto Cleanup;
  306. }
  307. //
  308. // Now, try to get the value for Publisher property - bstrDestinationNoQOC
  309. //
  310. FreeBstr(bstrPropertyName);
  311. VariantInit(&variantPropertyValue);
  312. AllocateBstrFromString(bstrPropertyName, PROPERTY_DESTINATION_NOQOC);
  313. hr = pIEventSubscription->GetPublisherProperty(
  314. bstrPropertyName,
  315. &variantPropertyValue
  316. );
  317. if (hr == S_OK)
  318. {
  319. // Found the property!
  320. *pbstrDestinationName = variantPropertyValue.bstrVal;
  321. goto Cleanup;
  322. }
  323. SensPrint(SENS_ERR, (SENS_STRING("GetDestinationNameFromSubscription(): failed to get ")
  324. SENS_STRING("PublisherProperty - hr = <%x>\n"), hr));
  325. Cleanup:
  326. //
  327. // Cleanup
  328. //
  329. if (pIEventSystem)
  330. {
  331. pIEventSystem->Release();
  332. }
  333. if (pIEventSubscription)
  334. {
  335. pIEventSubscription->Release();
  336. }
  337. if (pIUnkQueryResult)
  338. {
  339. pIUnkQueryResult->Release();
  340. }
  341. FreeBstr(bstrPropertyName);
  342. FreeBstr(bstrMethodName);
  343. return (hr);
  344. }