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.

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