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.

1237 lines
32 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1997 - 1999
  3. Module Name:
  4. senssink.cxx
  5. Abstract:
  6. Main entry point for the Sample SENS Subscriber.
  7. Author:
  8. Gopal Parupudi <GopalP>
  9. [Notes:]
  10. optional-notes
  11. Revision History:
  12. GopalP 11/17/1997 Start.
  13. --*/
  14. // Define this once and only once per exe.
  15. #define INITGUIDS
  16. #include <common.hxx>
  17. #include <objbase.h>
  18. #include <windows.h>
  19. #include <ole2ver.h>
  20. #include <initguid.h>
  21. #include <eventsys.h>
  22. #include <sensevts.h>
  23. #include <sens.h>
  24. #include "sinkcomn.hxx"
  25. #include "sinkguid.hxx"
  26. #include "senssink.hxx"
  27. #include "cfacnet.hxx"
  28. #include "cfaclogn.hxx"
  29. #include "cfacpwr.hxx"
  30. #if defined(SENS_NT4)
  31. #define SENS_TLB SENS_BSTR("SENS.EXE")
  32. #else // SENS_NT4
  33. #define SENS_TLB SENS_BSTR("SENS.DLL")
  34. #endif // SENS_NT4
  35. #define SUBSCRIBER SENS_STRING("SENS_SUBSCRIBER: ")
  36. #define MAX_QUERY_SIZE 512
  37. #define MAJOR_VER 1
  38. #define MINOR_VER 0
  39. #define DEFAULT_LCID 0x0
  40. //
  41. // Globals
  42. //
  43. IEventSystem *gpIEventSystem;
  44. ITypeInfo *gpITypeInfoNetwork;
  45. ITypeInfo *gpITypeInfoLogon;
  46. ITypeInfo *gpITypeInfoLogon2;
  47. ITypeInfo *gpITypeInfoOnNow;
  48. DWORD gTid;
  49. HANDLE ghEvent;
  50. #if defined(SENS_CHICAGO)
  51. #ifdef DBG
  52. DWORD gdwDebugOutputLevel;
  53. #endif // DBG
  54. #endif // SENS_CHICAGO
  55. int __cdecl
  56. main(
  57. int argc,
  58. char ** argv
  59. )
  60. {
  61. HRESULT hr;
  62. DWORD dwVer;
  63. DWORD dwRegCO;
  64. DWORD dwWaitStatus;
  65. BOOL fInitialized;
  66. BOOL bUnregister;
  67. BOOL bSetupPhase;
  68. MSG msg;
  69. LPCLASSFACTORY pNetCF;
  70. LPCLASSFACTORY pLogonCF;
  71. LPCLASSFACTORY pLogon2CF;
  72. LPCLASSFACTORY pPowerCF;
  73. ITypeLib *pITypeLib;
  74. hr = S_OK;
  75. dwRegCO = 0x0;
  76. bUnregister = FALSE;
  77. bSetupPhase = FALSE;
  78. fInitialized = FALSE;
  79. pNetCF = NULL;
  80. pLogonCF = NULL;
  81. pLogon2CF = NULL;
  82. pPowerCF = NULL;
  83. gpIEventSystem = NULL;
  84. pITypeLib = NULL;
  85. gpITypeInfoNetwork = NULL;
  86. gpITypeInfoLogon = NULL;
  87. gpITypeInfoLogon2 = NULL;
  88. gpITypeInfoOnNow = NULL;
  89. dwVer = CoBuildVersion();
  90. if (rmm != HIWORD(dwVer))
  91. {
  92. SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("CoBuildVersion() returned incompatible version.\n")));
  93. return -1;
  94. }
  95. if (FAILED(hr = CoInitializeEx(NULL, COINIT_MULTITHREADED)))
  96. {
  97. SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("CoInitializeEx() returned 0x%x.\n"), hr));
  98. goto Cleanup;
  99. }
  100. fInitialized = TRUE;
  101. //
  102. // Check the command-line args
  103. //
  104. if ( ((argc == 2) && ((argv[1][0] != '-') && (argv[1][0] != '/')))
  105. || (argc > 2))
  106. {
  107. Usage();
  108. return (-1);
  109. }
  110. if (argc == 2)
  111. {
  112. switch (argv[1][1])
  113. {
  114. case 'i':
  115. case 'I':
  116. bSetupPhase = TRUE;
  117. bUnregister = FALSE;
  118. break;
  119. case 'u':
  120. case 'U':
  121. bSetupPhase = TRUE;
  122. bUnregister = TRUE;
  123. break;
  124. case 'e':
  125. case 'E':
  126. // SCM calls me with /Embedding flag
  127. break;
  128. default:
  129. Usage();
  130. return (-1);
  131. }
  132. }
  133. if (bSetupPhase == TRUE)
  134. {
  135. hr = RegisterWithES(bUnregister);
  136. if (FAILED(hr))
  137. {
  138. goto Cleanup;
  139. }
  140. // Network Subscriber
  141. hr = RegisterSubscriberCLSID(
  142. CLSID_SensTestSubscriberNetwork,
  143. TEST_SUBSCRIBER_NAME_NETWORK,
  144. bUnregister
  145. );
  146. if (FAILED(hr))
  147. {
  148. SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("Failed to %sregister Test Subscriber Network CLSID")
  149. SENS_STRING(" - hr = <%x>\n"), bUnregister ? SENS_STRING("un") : SENS_STRING(""), hr));
  150. }
  151. else
  152. {
  153. SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("%segistered Test Subscriber Network CLSID.\n"),
  154. bUnregister ? SENS_STRING("Unr") : SENS_STRING("R")));
  155. }
  156. // Logon Subscriber
  157. hr = RegisterSubscriberCLSID(
  158. CLSID_SensTestSubscriberLogon,
  159. TEST_SUBSCRIBER_NAME_LOGON,
  160. bUnregister
  161. );
  162. if (FAILED(hr))
  163. {
  164. SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("Failed to %sregister Test Subscriber Logon CLSID")
  165. SENS_STRING(" - hr = <%x>\n"), bUnregister ? SENS_STRING("un") : SENS_STRING(""), hr));
  166. }
  167. else
  168. {
  169. SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("%segistered Test Subscriber Logon CLSID.\n"),
  170. bUnregister ? SENS_STRING("Unr") : SENS_STRING("R")));
  171. }
  172. // Logon2 Subscriber
  173. hr = RegisterSubscriberCLSID(
  174. CLSID_SensTestSubscriberLogon2,
  175. TEST_SUBSCRIBER_NAME_LOGON2,
  176. bUnregister
  177. );
  178. if (FAILED(hr))
  179. {
  180. SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("Failed to %sregister Test Subscriber Logon2 CLSID")
  181. SENS_STRING(" - hr = <%x>\n"), bUnregister ? SENS_STRING("un") : SENS_STRING(""), hr));
  182. }
  183. else
  184. {
  185. SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("%segistered Test Subscriber Logon2 CLSID.\n"),
  186. bUnregister ? SENS_STRING("Unr") : SENS_STRING("R")));
  187. }
  188. // Power Subscriber
  189. hr = RegisterSubscriberCLSID(
  190. CLSID_SensTestSubscriberOnNow,
  191. TEST_SUBSCRIBER_NAME_POWER,
  192. bUnregister
  193. );
  194. if (FAILED(hr))
  195. {
  196. SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("Failed to %sregister Test Subscriber Power CLSID")
  197. SENS_STRING(" - hr = <%x>\n"), bUnregister ? SENS_STRING("un") : SENS_STRING(""), hr));
  198. }
  199. else
  200. {
  201. SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("%segistered Test Subscriber Power CLSID.\n"),
  202. bUnregister ? SENS_STRING("Unr") : SENS_STRING("R")));
  203. }
  204. goto Cleanup;
  205. }
  206. //
  207. // Get the ITypeInfo pointer.
  208. //
  209. hr = LoadRegTypeLib(
  210. LIBID_SensEvents,
  211. MAJOR_VER,
  212. MINOR_VER,
  213. DEFAULT_LCID,
  214. &pITypeLib
  215. );
  216. SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("LoadRegTypeLib() returned 0x%x\n"), hr));
  217. if (FAILED(hr))
  218. {
  219. hr = LoadTypeLib(
  220. SENS_TLB,
  221. &pITypeLib
  222. );
  223. SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("LoadTypeLib() returned 0x%x\n"), hr));
  224. if (FAILED(hr))
  225. {
  226. SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("Exiting...\n")));
  227. goto Cleanup;
  228. }
  229. }
  230. // Get type information for the ISensNetwork interface.
  231. hr = pITypeLib->GetTypeInfoOfGuid(
  232. IID_ISensNetwork,
  233. &gpITypeInfoNetwork
  234. );
  235. SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("ITypeLib::GetTypeInfoOfGuid(ISensNetwork) returned 0x%x\n"), hr));
  236. if (FAILED(hr))
  237. {
  238. SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("Exiting...\n")));
  239. goto Cleanup;
  240. }
  241. // Get type information for the ISensLogon interface.
  242. hr = pITypeLib->GetTypeInfoOfGuid(
  243. IID_ISensLogon,
  244. &gpITypeInfoLogon
  245. );
  246. SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("ITypeLib::GetTypeInfoOfGuid(ISensLogon) returned 0x%x\n"), hr));
  247. if (FAILED(hr))
  248. {
  249. SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("Exiting...\n")));
  250. goto Cleanup;
  251. }
  252. // Get type information for the ISensLogon2 interface.
  253. hr = pITypeLib->GetTypeInfoOfGuid(
  254. IID_ISensLogon2,
  255. &gpITypeInfoLogon2
  256. );
  257. SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("ITypeLib::GetTypeInfoOfGuid(ISensLogon2) returned 0x%x\n"), hr));
  258. if (FAILED(hr))
  259. {
  260. SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("Exiting...\n")));
  261. goto Cleanup;
  262. }
  263. // Get type information for the ISensOnNow interface.
  264. hr = pITypeLib->GetTypeInfoOfGuid(
  265. IID_ISensOnNow,
  266. &gpITypeInfoOnNow
  267. );
  268. SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("ITypeLib::GetTypeInfoOfGuid(ISensOnNow) returned 0x%x\n"), hr));
  269. if (FAILED(hr))
  270. {
  271. SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("Exiting...\n")));
  272. goto Cleanup;
  273. }
  274. //
  275. // Create the event
  276. //
  277. ghEvent = CreateEvent(
  278. NULL, // Security Attributes
  279. FALSE, // bManualReset
  280. FALSE, // Initial state
  281. SENS_STRING("SENS Test Subscriber Quit Event")
  282. );
  283. if (ghEvent == NULL)
  284. {
  285. SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("CreateEvent() failed.\n")));
  286. goto Cleanup;
  287. }
  288. //
  289. // Create the Network ClassFactory and register it with COM.
  290. //
  291. pNetCF = new CISensNetworkCF;
  292. if (NULL == pNetCF)
  293. {
  294. goto Cleanup;
  295. }
  296. pNetCF->AddRef(); // Because we hold on to it.
  297. SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("ClassFactory created successfully.\n")));
  298. // Register the CLSID
  299. hr = CoRegisterClassObject(
  300. CLSID_SensTestSubscriberNetwork,
  301. (LPUNKNOWN) pNetCF,
  302. CLSCTX_LOCAL_SERVER,
  303. REGCLS_MULTIPLEUSE,
  304. &dwRegCO
  305. );
  306. if (FAILED(hr))
  307. {
  308. SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("CoRegisterClassObject(Network) returned 0x%x.\n"), hr));
  309. }
  310. else
  311. {
  312. SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("Successfully registered the ISensNetwork Class Factory.\n")));
  313. }
  314. //
  315. // Create the Logon ClassFactory and register it with COM.
  316. //
  317. pLogonCF = new CISensLogonCF;
  318. if (NULL == pLogonCF)
  319. {
  320. goto Cleanup;
  321. }
  322. pLogonCF->AddRef(); // Because we hold on to it.
  323. SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("ClassFactory created successfully.\n")));
  324. hr = CoRegisterClassObject(
  325. CLSID_SensTestSubscriberLogon,
  326. (LPUNKNOWN) pLogonCF,
  327. CLSCTX_LOCAL_SERVER,
  328. REGCLS_MULTIPLEUSE,
  329. &dwRegCO
  330. );
  331. if (FAILED(hr))
  332. {
  333. SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("CoRegisterClassObject(Logon) returned 0x%x.\n"), hr));
  334. }
  335. else
  336. {
  337. SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("Successfully registered the ISensLogon Class Factory.\n")));
  338. }
  339. //
  340. // Create the Logon2 ClassFactory and register it with COM.
  341. //
  342. pLogon2CF = new CISensLogon2CF;
  343. if (NULL == pLogon2CF)
  344. {
  345. goto Cleanup;
  346. }
  347. pLogon2CF->AddRef(); // Because we hold on to it.
  348. SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("ClassFactory created successfully.\n")));
  349. hr = CoRegisterClassObject(
  350. CLSID_SensTestSubscriberLogon2,
  351. (LPUNKNOWN) pLogon2CF,
  352. CLSCTX_LOCAL_SERVER,
  353. REGCLS_MULTIPLEUSE,
  354. &dwRegCO
  355. );
  356. if (FAILED(hr))
  357. {
  358. SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("CoRegisterClassObject(Logon2) returned 0x%x.\n"), hr));
  359. }
  360. else
  361. {
  362. SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("Successfully registered the ISensLogon2 Class Factory.\n")));
  363. }
  364. //
  365. // Create the Power ClassFactory and register it with COM.
  366. //
  367. pPowerCF = new CISensOnNowCF;
  368. if (NULL == pPowerCF)
  369. {
  370. goto Cleanup;
  371. }
  372. pPowerCF->AddRef(); // Because we hold on to it.
  373. SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("ClassFactory created successfully.\n")));
  374. hr = CoRegisterClassObject(
  375. CLSID_SensTestSubscriberOnNow,
  376. (LPUNKNOWN) pPowerCF,
  377. CLSCTX_LOCAL_SERVER,
  378. REGCLS_MULTIPLEUSE,
  379. &dwRegCO
  380. );
  381. if (FAILED(hr))
  382. {
  383. SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("CoRegisterClassObject(Power) returned 0x%x.\n"), hr));
  384. }
  385. else
  386. {
  387. SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("Successfully registered the ISensOnNow Class Factory.\n")));
  388. }
  389. //
  390. // Wait to quit.
  391. //
  392. dwWaitStatus = WaitForSingleObject(ghEvent, INFINITE);
  393. SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("WaitForSingleObject returned %d\n"), dwWaitStatus));
  394. //
  395. // Cleanup
  396. //
  397. Cleanup:
  398. if ( (0L != dwRegCO)
  399. && (bSetupPhase == TRUE)
  400. && (bUnregister == TRUE))
  401. {
  402. CoRevokeClassObject(dwRegCO);
  403. SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("CoRevokeClassObject() returned 0x%x.\n"), hr));
  404. }
  405. if (bSetupPhase == TRUE)
  406. {
  407. SensPrint(SENS_INFO, (SENS_STRING("\n") SUBSCRIBER SENS_STRING("Sens Test Subscriber Configuration %s.\n"),
  408. FAILED(hr) ? SENS_STRING("failed") : SENS_STRING("successful")));
  409. }
  410. if (NULL != pNetCF)
  411. {
  412. pNetCF->Release();
  413. }
  414. if (NULL != pLogonCF)
  415. {
  416. pLogonCF->Release();
  417. }
  418. if (NULL != pLogon2CF)
  419. {
  420. pLogon2CF->Release();
  421. }
  422. if (NULL != pPowerCF)
  423. {
  424. pPowerCF->Release();
  425. }
  426. if (NULL != pITypeLib)
  427. {
  428. pITypeLib->Release();
  429. }
  430. if (NULL != gpITypeInfoNetwork)
  431. {
  432. gpITypeInfoNetwork->Release();
  433. }
  434. if (NULL != gpITypeInfoLogon)
  435. {
  436. gpITypeInfoLogon->Release();
  437. }
  438. if (NULL != gpITypeInfoLogon2)
  439. {
  440. gpITypeInfoLogon2->Release();
  441. }
  442. if (NULL != gpITypeInfoOnNow)
  443. {
  444. gpITypeInfoOnNow->Release();
  445. }
  446. if (fInitialized)
  447. {
  448. CoUninitialize();
  449. }
  450. return 0;
  451. }
  452. HRESULT
  453. RegisterWithES(
  454. BOOL bUnregister
  455. )
  456. {
  457. HRESULT hr;
  458. hr = S_OK;
  459. //
  460. // Instantiate the Event System
  461. //
  462. hr = CoCreateInstance(
  463. CLSID_CEventSystem,
  464. NULL,
  465. CLSCTX_SERVER,
  466. IID_IEventSystem,
  467. (LPVOID *) &gpIEventSystem
  468. );
  469. if (FAILED(hr))
  470. {
  471. SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("Failed to create CEventSystem, HRESULT=%x\n"), hr));
  472. goto Cleanup;
  473. }
  474. SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("Successfully created CEventSystem\n")));
  475. #if 0
  476. //
  477. // Test to see if we can get the MachineName
  478. //
  479. BSTR bstrMachineName;
  480. hr = gpIEventQuery->get_MachineName(&bstrMachineName);
  481. if (SUCCEEDED(hr))
  482. SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("Configuring Test Subscriber on %s...\n"), bstrMachineName));
  483. else
  484. SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("get_MachineName failed, hr = %x\n"), hr));
  485. #endif // 0
  486. //
  487. // Register my Subscriber's subscriptions with SENS.
  488. //
  489. hr = RegisterSubscriptions(bUnregister);
  490. if (FAILED(hr))
  491. {
  492. SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("Failed to %sregister SensSink Subscriptions")
  493. SENS_STRING(" - hr = <%x>\n"), bUnregister ? SENS_STRING("un") : SENS_STRING(""), hr));
  494. goto Cleanup;
  495. }
  496. SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("%segistered SensSink Subscriptions.\n"),
  497. bUnregister ? SENS_STRING("Unr") : SENS_STRING("R")));
  498. Cleanup:
  499. //
  500. // Cleanup
  501. //
  502. if (gpIEventSystem)
  503. {
  504. gpIEventSystem->Release();
  505. }
  506. return hr;
  507. }
  508. HRESULT
  509. RegisterSubscriptions(
  510. BOOL bUnregister
  511. )
  512. {
  513. int i;
  514. int errorIndex;
  515. HRESULT hr;
  516. LPOLESTR strGuid;
  517. LPOLESTR strSubscriptionID;
  518. WCHAR szQuery[MAX_QUERY_SIZE];
  519. BSTR bstrEventClassID;
  520. BSTR bstrInterfaceID;
  521. BSTR bstrSubscriberCLSID;
  522. BSTR bstrPublisherID;
  523. BSTR bstrSubscriptionID;
  524. BSTR bstrSubscriptionName;
  525. BSTR bstrMethodName;
  526. BSTR bstrPropertyName;
  527. BSTR bstrPropertyValue;
  528. ULONG ulPropertyValue;
  529. VARIANT variantPropertyValue;
  530. BSTR bstrPROGID_EventSubscription;
  531. IEventSubscription *pIEventSubscription;
  532. hr = S_OK;
  533. strGuid = NULL;
  534. errorIndex = 0;
  535. strSubscriptionID = NULL;
  536. bstrEventClassID = NULL;
  537. bstrInterfaceID = NULL;
  538. bstrSubscriberCLSID = NULL;
  539. bstrPublisherID = NULL;
  540. bstrSubscriptionID = NULL;
  541. bstrSubscriptionName = NULL;
  542. bstrMethodName = NULL;
  543. bstrPropertyName = NULL;
  544. bstrPropertyValue = NULL;
  545. ulPropertyValue = 0x0;
  546. bstrPROGID_EventSubscription = NULL;
  547. pIEventSubscription = NULL;
  548. //
  549. // Build a Subscriber
  550. //
  551. AllocateBstrFromGuid(bstrPublisherID, SENSGUID_PUBLISHER);
  552. AllocateBstrFromString(bstrPROGID_EventSubscription, PROGID_EventSubscription);
  553. for (i = 0; i < TEST_SUBSCRIPTIONS_COUNT; i++)
  554. {
  555. if (bUnregister)
  556. {
  557. // Form the query
  558. wcscpy(szQuery, SENS_BSTR("SubscriptionID"));
  559. wcscat(szQuery, SENS_BSTR("="));
  560. AllocateStrFromGuid(strSubscriptionID, *(gTestSubscriptions[i].pSubscriptionID));
  561. wcscat(szQuery, strSubscriptionID);
  562. hr = gpIEventSystem->Remove(
  563. PROGID_EventSubscription,
  564. szQuery,
  565. &errorIndex
  566. );
  567. FreeStr(strSubscriptionID);
  568. if (FAILED(hr))
  569. {
  570. SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("RegisterSubscriptions(%d) failed to unregister")
  571. SENS_STRING(" - hr = <%x>\n"), i, hr));
  572. goto Cleanup;
  573. }
  574. continue;
  575. }
  576. // Get a new IEventSubscription object to play with.
  577. hr = CoCreateInstance(
  578. CLSID_CEventSubscription,
  579. NULL,
  580. CLSCTX_SERVER,
  581. IID_IEventSubscription,
  582. (LPVOID *) &pIEventSubscription
  583. );
  584. if (FAILED(hr))
  585. {
  586. SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("RegisterSubscriptions(%d) failed to create ")
  587. SENS_STRING("IEventSubscriptions - hr = <%x>\n"), i, hr));
  588. goto Cleanup;
  589. }
  590. AllocateBstrFromGuid(bstrSubscriptionID, *(gTestSubscriptions[i].pSubscriptionID));
  591. hr = pIEventSubscription->put_SubscriptionID(bstrSubscriptionID);
  592. ASSERT(SUCCEEDED(hr));
  593. AllocateBstrFromGuid(bstrSubscriberCLSID, *(gTestSubscriptions[i].pSubscriberCLSID));
  594. hr = pIEventSubscription->put_SubscriberCLSID(bstrSubscriberCLSID);
  595. ASSERT(SUCCEEDED(hr));
  596. hr = pIEventSubscription->put_PublisherID(bstrPublisherID);
  597. ASSERT(SUCCEEDED(hr));
  598. hr = pIEventSubscription->put_SubscriptionID(bstrSubscriptionID);
  599. ASSERT(SUCCEEDED(hr));
  600. AllocateBstrFromString(bstrSubscriptionName, gTestSubscriptions[i].strSubscriptionName);
  601. hr = pIEventSubscription->put_SubscriptionName(bstrSubscriptionName);
  602. ASSERT(SUCCEEDED(hr));
  603. AllocateBstrFromString(bstrMethodName, gTestSubscriptions[i].strMethodName);
  604. hr = pIEventSubscription->put_MethodName(bstrMethodName);
  605. ASSERT(SUCCEEDED(hr));
  606. AllocateBstrFromGuid(bstrEventClassID, *(gTestSubscriptions[i].pEventClassID));
  607. hr = pIEventSubscription->put_EventClassID(bstrEventClassID);
  608. ASSERT(SUCCEEDED(hr));
  609. AllocateBstrFromGuid(bstrInterfaceID, *(gTestSubscriptions[i].pInterfaceID));
  610. hr = pIEventSubscription->put_InterfaceID(bstrInterfaceID);
  611. ASSERT(SUCCEEDED(hr));
  612. if (wcscmp(gTestSubscriptions[i].strMethodName, SENS_BSTR("ConnectionMadeNoQOCInfo")) == 0)
  613. {
  614. AllocateBstrFromString(bstrPropertyName, SENS_BSTR("ulConnectionMadeTypeNoQOC"));
  615. ulPropertyValue = CONNECTION_LAN;
  616. InitializeDwordVariant(&variantPropertyValue, ulPropertyValue);
  617. hr = pIEventSubscription->PutPublisherProperty(
  618. bstrPropertyName,
  619. &variantPropertyValue
  620. );
  621. ASSERT(SUCCEEDED(hr));
  622. SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("PutPublisherProperty(WAN/LAN) returned 0x%x\n"), hr));
  623. FreeBstr(bstrPropertyName);
  624. ulPropertyValue = 0x0;
  625. }
  626. else
  627. if ( (wcscmp(gTestSubscriptions[i].strMethodName, SENS_BSTR("DestinationReachable")) == 0)
  628. || (wcscmp(gTestSubscriptions[i].strMethodName, SENS_BSTR("DestinationReachableNoQOCInfo")) == 0))
  629. {
  630. // Set the DestinationName for which we want to be notified for.
  631. AllocateBstrFromString(bstrPropertyName, gTestSubscriptions[i].strPropertyMethodName);
  632. AllocateBstrFromString(bstrPropertyValue, gTestSubscriptions[i].strPropertyMethodNameValue);
  633. InitializeBstrVariant(&variantPropertyValue, bstrPropertyValue);
  634. hr = pIEventSubscription->PutPublisherProperty(
  635. bstrPropertyName,
  636. &variantPropertyValue
  637. );
  638. ASSERT(SUCCEEDED(hr));
  639. SensPrint(SENS_INFO, (SUBSCRIBER SENS_STRING("PutPublisherProperty(DestinationName) returned 0x%x\n"), hr));
  640. FreeBstr(bstrPropertyName);
  641. FreeBstr(bstrPropertyValue);
  642. }
  643. FreeBstr(bstrSubscriptionID);
  644. FreeBstr(bstrSubscriberCLSID);
  645. FreeBstr(bstrEventClassID);
  646. FreeBstr(bstrInterfaceID);
  647. FreeBstr(bstrSubscriptionName);
  648. FreeBstr(bstrMethodName);
  649. hr = gpIEventSystem->Store(bstrPROGID_EventSubscription, pIEventSubscription);
  650. if (FAILED(hr))
  651. {
  652. SensPrint(SENS_ERR, (SUBSCRIBER SENS_STRING("RegisterSubscriptions(%d) failed to commit")
  653. SENS_STRING(" - hr = <%x>\n"), i, hr));
  654. goto Cleanup;
  655. }
  656. pIEventSubscription->Release();
  657. pIEventSubscription = NULL;
  658. } // for loop
  659. Cleanup:
  660. //
  661. // Cleanup
  662. //
  663. if (pIEventSubscription)
  664. {
  665. pIEventSubscription->Release();
  666. }
  667. FreeBstr(bstrPublisherID);
  668. FreeBstr(bstrSubscriberCLSID);
  669. FreeStr(strGuid);
  670. return (hr);
  671. }
  672. HRESULT
  673. RegisterSubscriberCLSID(
  674. REFIID clsid,
  675. TCHAR* strSubscriberName,
  676. BOOL bUnregister
  677. )
  678. /*++
  679. Routine Description:
  680. Register/Unregister the CLSID of the Test subscriber.
  681. Arguments:
  682. clsid - CLSID of the Subscriber.
  683. strSubscriberName - Name of the Subscriber.
  684. bUnregister - If TRUE, then unregister all subscriptions of SENS Test subscriber.
  685. Return Value:
  686. S_OK, if successful
  687. hr, otherwise
  688. --*/
  689. {
  690. HRESULT hr;
  691. HMODULE hModule;
  692. HKEY appidKey = 0;
  693. HKEY clsidKey = 0;
  694. HKEY serverKey = 0;
  695. TCHAR szModule[MAX_PATH+1];
  696. WCHAR *szCLSID = 0;
  697. WCHAR *szLIBID = 0;
  698. TCHAR *szCLSID_t = 0;
  699. TCHAR *szLIBID_t = 0;
  700. TCHAR *szFriendlyName = strSubscriberName;
  701. hr = S_OK;
  702. // Convert the CLSID into a TCHAR.
  703. hr = StringFromCLSID(clsid, &szCLSID);
  704. if (FAILED(hr))
  705. {
  706. goto Cleanup;
  707. }
  708. if (bUnregister == FALSE)
  709. {
  710. hr = StringFromCLSID(LIBID_SensEvents, &szLIBID);
  711. if (FAILED(hr))
  712. {
  713. goto Cleanup;
  714. }
  715. hModule = GetModuleHandle(0);
  716. // Get Subscriber location.
  717. const size_t moduleBufSize = sizeof szModule / sizeof szModule[0];
  718. DWORD dwResult = GetModuleFileName(hModule, szModule, moduleBufSize);
  719. if (dwResult == 0)
  720. {
  721. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  722. goto Cleanup;
  723. }
  724. }
  725. //
  726. // Convert UNICODE strings into ANSI, if necessary
  727. //
  728. #if !defined(SENS_CHICAGO)
  729. szCLSID_t = szCLSID;
  730. szLIBID_t = szLIBID;
  731. #else // SENS_CHICAGO
  732. szCLSID_t = SensUnicodeStringToAnsi(szCLSID);
  733. szLIBID_t = SensUnicodeStringToAnsi(szLIBID);
  734. if ( (NULL == szCLSID_t)
  735. || (NULL == szLIBID_t))
  736. {
  737. goto Cleanup;
  738. }
  739. #endif // SENS_CHICAGO
  740. // Build the key CLSID\\{clsid}
  741. TCHAR clsidKeyName[sizeof "CLSID\\{12345678-1234-1234-1234-123456789012}"];
  742. _tcscpy(clsidKeyName, SENS_STRING("CLSID\\"));
  743. _tcscat(clsidKeyName, szCLSID_t);
  744. // Build the key AppID\\{clsid}
  745. TCHAR appidKeyName[sizeof "AppID\\{12345678-1234-1234-1234-123456789012}"];
  746. _tcscpy(appidKeyName, SENS_STRING("AppID\\"));
  747. _tcscat(appidKeyName, szCLSID_t);
  748. if (bUnregister)
  749. {
  750. hr = RecursiveDeleteKey(HKEY_CLASSES_ROOT, clsidKeyName);
  751. if (FAILED(hr))
  752. {
  753. goto Cleanup;
  754. }
  755. hr = RecursiveDeleteKey(HKEY_CLASSES_ROOT, appidKeyName);
  756. goto Cleanup;
  757. }
  758. // Create the CLSID\\{clsid} key
  759. hr = CreateKey(
  760. HKEY_CLASSES_ROOT,
  761. clsidKeyName,
  762. szFriendlyName,
  763. &clsidKey
  764. );
  765. if (FAILED(hr))
  766. {
  767. goto Cleanup;
  768. }
  769. //
  770. // Under the CLSID\\{clsid} key, create a named value
  771. // AppID = {clsid}
  772. hr = CreateNamedValue(clsidKey, SENS_STRING("AppID"), szCLSID_t);
  773. if (FAILED(hr))
  774. {
  775. goto Cleanup;
  776. }
  777. //
  778. // Create the appropriate server key beneath the clsid key.
  779. // For servers, this is CLSID\\{clsid}\\LocalServer32.
  780. // In both cases, the default value is the module path name.
  781. //
  782. hr = CreateKey(
  783. clsidKey,
  784. SENS_STRING("LocalServer32"),
  785. szModule,
  786. &serverKey
  787. );
  788. if (FAILED(hr))
  789. {
  790. goto Cleanup;
  791. }
  792. RegCloseKey(serverKey);
  793. //
  794. // Create CLSID\\{clsid}\\TypeLib subkey with a default value of
  795. // the LIBID of the TypeLib
  796. //
  797. hr = CreateKey(
  798. clsidKey,
  799. SENS_STRING("TypeLib"),
  800. szLIBID_t,
  801. &serverKey
  802. );
  803. if (FAILED(hr))
  804. {
  805. goto Cleanup;
  806. }
  807. RegCloseKey(serverKey);
  808. // We're finished with the CLSID\\{clsid} key
  809. RegCloseKey(clsidKey);
  810. // Register APPID.
  811. hr = CreateKey(
  812. HKEY_CLASSES_ROOT,
  813. appidKeyName,
  814. szFriendlyName,
  815. &appidKey
  816. );
  817. if (FAILED(hr))
  818. {
  819. goto Cleanup;
  820. }
  821. // Under AppId\{clsid} key, create a named value [RunAs = "Interactive User"]
  822. hr = CreateNamedValue(appidKey, SENS_STRING("RunAs"), SENS_STRING("Interactive User"));
  823. if (FAILED(hr))
  824. {
  825. goto Cleanup;
  826. }
  827. RegCloseKey(appidKey);
  828. Cleanup:
  829. //
  830. // Cleanup
  831. //
  832. CoTaskMemFree(szCLSID);
  833. CoTaskMemFree(szLIBID);
  834. #if defined(SENS_CHICAGO)
  835. if (szCLSID_t != NULL)
  836. {
  837. delete szCLSID_t;
  838. }
  839. if (szLIBID_t != NULL)
  840. {
  841. delete szLIBID_t;
  842. }
  843. #endif // SENS_CHICAGO
  844. return hr;
  845. }
  846. HRESULT
  847. CreateKey(
  848. HKEY hParentKey,
  849. const TCHAR* KeyName,
  850. const TCHAR* defaultValue,
  851. HKEY* hKey
  852. )
  853. /*++
  854. Routine Description:
  855. Create a key (with an optional default value). The handle to the key is
  856. returned as an [out] parameter. If NULL is passed as the key parameter,
  857. the key is created in the registry, then closed.
  858. Arguments:
  859. hParentKey - Handle to the parent Key.
  860. KeyName - Name of the key to create.
  861. defaultValue - The default value for the key to create.
  862. hKey - OUT Handle to key that was created.
  863. Return Value:
  864. S_OK, if successful
  865. hr, otherwise
  866. --*/
  867. {
  868. HKEY hTempKey;
  869. LONG lResult;
  870. hTempKey = NULL;
  871. lResult = RegCreateKeyEx(
  872. hParentKey, // Handle to open key
  873. KeyName, // Subkey name
  874. 0, // Reserved
  875. NULL, // Class string
  876. REG_OPTION_NON_VOLATILE, // Options Flag
  877. KEY_ALL_ACCESS, // Desired Security access
  878. NULL, // Pointer to Security Attributes structure
  879. &hTempKey, // Handle of the opened/created key
  880. NULL // Disposition value
  881. );
  882. if (lResult != ERROR_SUCCESS)
  883. {
  884. return HRESULT_FROM_WIN32(lResult);
  885. }
  886. // Set the default value for the key
  887. if (defaultValue != NULL)
  888. {
  889. lResult = RegSetValueEx(
  890. hTempKey, // Key to set Value for.
  891. NULL, // Value to set
  892. 0, // Reserved
  893. REG_SZ, // Value Type
  894. (BYTE*) defaultValue, // Address of Value data
  895. sizeof(TCHAR) * (_tcslen(defaultValue)+1) // Size of Value
  896. );
  897. if (lResult != ERROR_SUCCESS)
  898. {
  899. RegCloseKey(hTempKey);
  900. return HRESULT_FROM_WIN32(lResult);
  901. }
  902. }
  903. if (hKey == NULL)
  904. {
  905. RegCloseKey(hTempKey);
  906. }
  907. else
  908. {
  909. *hKey = hTempKey;
  910. }
  911. return S_OK;
  912. }
  913. HRESULT
  914. CreateNamedValue(
  915. HKEY hKey,
  916. const TCHAR* title,
  917. const TCHAR* value
  918. )
  919. /*++
  920. Routine Description:
  921. Create a named value under a key
  922. Arguments:
  923. hKey - Handle to the parent Key.
  924. title - Name of the Value to create.
  925. value - The data for the Value under the Key.
  926. Return Value:
  927. S_OK, if successful
  928. hr, otherwise
  929. --*/
  930. {
  931. HRESULT hr;
  932. LONG lResult;
  933. hr = S_OK;
  934. lResult = RegSetValueEx(
  935. hKey, // Key to set Value for.
  936. title, // Value to set
  937. 0, // Reserved
  938. REG_SZ, // Value Type
  939. (BYTE*) value, // Address of Value data
  940. sizeof(TCHAR) * (_tcslen(value)+1) // Size of Value
  941. );
  942. if (lResult != ERROR_SUCCESS)
  943. {
  944. hr = HRESULT_FROM_WIN32(lResult);
  945. }
  946. return hr;
  947. }
  948. HRESULT
  949. RecursiveDeleteKey(
  950. HKEY hKeyParent,
  951. const TCHAR* lpszKeyChild
  952. )
  953. /*++
  954. Routine Description:
  955. Delete a key and all of its descendents.
  956. Arguments:
  957. hKeyParent - Handle to the parent Key.
  958. lpszKeyChild - The data for the Value under the Key.
  959. Return Value:
  960. S_OK, if successful
  961. hr, otherwise
  962. --*/
  963. {
  964. HKEY hKeyChild;
  965. LONG lResult;
  966. //
  967. // Open the child.
  968. //
  969. lResult = RegOpenKeyEx(
  970. hKeyParent, // Handle to the Parent
  971. lpszKeyChild, // Name of the child key
  972. 0, // Reserved
  973. KEY_ALL_ACCESS, // Security Access Mask
  974. &hKeyChild // Handle to the opened key
  975. );
  976. if (lResult != ERROR_SUCCESS)
  977. {
  978. return HRESULT_FROM_WIN32(lResult);
  979. }
  980. //
  981. // Enumerate all of the decendents of this child.
  982. //
  983. FILETIME time;
  984. TCHAR szBuffer[MAX_PATH+1];
  985. const DWORD bufSize = sizeof szBuffer / sizeof szBuffer[0];
  986. DWORD dwSize = bufSize;
  987. while (TRUE)
  988. {
  989. lResult = RegEnumKeyEx(
  990. hKeyChild, // Handle of the key to enumerate
  991. 0, // Index of the subkey to retrieve
  992. szBuffer, // OUT Name of the subkey
  993. &dwSize, // OUT Size of the buffer for name of subkey
  994. NULL, // Reserved
  995. NULL, // OUT Class of the enumerated subkey
  996. NULL, // OUT Size of the class of the subkey
  997. &time // OUT Last time the subkey was written to
  998. );
  999. if (lResult != ERROR_SUCCESS)
  1000. {
  1001. break;
  1002. }
  1003. // Delete the decendents of this child.
  1004. lResult = RecursiveDeleteKey(hKeyChild, szBuffer);
  1005. if (lResult != ERROR_SUCCESS)
  1006. {
  1007. // Cleanup before exiting.
  1008. RegCloseKey(hKeyChild);
  1009. return HRESULT_FROM_WIN32(lResult);
  1010. }
  1011. dwSize = bufSize;
  1012. } // while
  1013. // Close the child.
  1014. RegCloseKey(hKeyChild);
  1015. // Delete this child.
  1016. lResult = RegDeleteKey(hKeyParent, lpszKeyChild);
  1017. return HRESULT_FROM_WIN32(lResult);
  1018. }