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.

1434 lines
37 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1997 - 1999
  3. Module Name:
  4. senscfg.cxx
  5. Abstract:
  6. Code to do the configuration (install/uninstall) for SENS.
  7. Author:
  8. Gopal Parupudi <GopalP>
  9. [Notes:]
  10. optional-notes
  11. Revision History:
  12. GopalP 11/11/1997 Start.
  13. --*/
  14. #define INITGUID
  15. #include <common.hxx>
  16. #include <objbase.h>
  17. #include <coguid.h>
  18. #include <eventsys.h>
  19. #include <sensevts.h>
  20. #include <sens.h>
  21. #include <wininet.h>
  22. #include <winineti.h>
  23. #include "senscfg.hxx"
  24. #include "sensinfo.hxx"
  25. #include "memfunc.hxx"
  26. #define MAJOR_VER 1
  27. #define MINOR_VER 0
  28. #define DEFAULT_LCID 0x0
  29. #define MAX_QUERY_SIZE 512
  30. #define SENS_SETUP "SENSCFG: "
  31. #define SENS_SERVICEA "SENS"
  32. #define SENS_SETUPW SENS_BSTR("SENSCFG: ")
  33. #define SENS_SERVICE SENS_STRING("SENS")
  34. #define SENS_DISPLAY_NAME SENS_STRING("System Event Notification")
  35. #define SENS_SERVICE_GROUP SENS_STRING("Network")
  36. #define EVENTSYSTEM_REMOVE SENS_STRING("esserver /remove")
  37. #define EVENTSYSTEM_INSTALL SENS_STRING("esserver /install")
  38. #define SENS_WINLOGON_DLL SENS_STRING("senslogn.dll")
  39. #define GUID_STR_SIZE sizeof("{12345678-1234-1234-1234-123456789012}")
  40. #define EVENTSYSTEM_KEY SENS_STRING("SOFTWARE\\Microsoft\\EventSystem")
  41. #define WINLOGON_NOTIFY_KEY SENS_STRING("SOFTWARE\\Microsoft\\Windows NT\\") \
  42. SENS_STRING("CurrentVersion\\Winlogon\\Notify\\") \
  43. SENS_STRING("senslogn")
  44. #define WININET_SENS_EVENTS INETEVT_RAS_CONNECT | \
  45. INETEVT_RAS_DISCONNECT | \
  46. INETEVT_LOGON | \
  47. INETEVT_LOGOFF
  48. //
  49. // DLL vs EXE dependent constants
  50. //
  51. #if defined(SENS_NT4)
  52. #define SENS_TLBA "SENS.EXE"
  53. #define SENS_BINARYA "SENS.EXE"
  54. #define SENS_TLB SENS_STRING("SENS.EXE")
  55. #define SENS_BINARY SENS_STRING("SENS.EXE")
  56. #else // SENS_NT4
  57. #define SENS_TLBA "SENS.DLL"
  58. #define SENS_BINARYA "SENS.DLL"
  59. #define SENS_TLB SENS_STRING("SENS.DLL")
  60. #define SENS_BINARY SENS_STRING("SENS.DLL")
  61. #endif // SENS_NT4
  62. //
  63. // Misc debugging constants
  64. //
  65. #ifdef STRICT_HRESULT_CHECKS
  66. #ifdef SUCCEEDED
  67. #undef SUCCEEDED
  68. #define SUCCEEDED(_HR_) (_HR_ == S_OK)
  69. #endif // SUCCEEDED
  70. #ifdef FAILED
  71. #undef FAILED
  72. #define FAILED(_HR_) (_HR_ != S_OK)
  73. #endif // FAILED
  74. #endif // STRICT_HRESULT_CHECKS
  75. //
  76. // Globals
  77. //
  78. IEventSystem *gpIEventSystem;
  79. ITypeLib *gpITypeLib;
  80. #ifdef DBG
  81. DWORD gdwDebugOutputLevel;
  82. #endif // DBG
  83. HRESULT APIENTRY
  84. SensRegister(
  85. void
  86. )
  87. /*++
  88. Routine Description:
  89. Register SENS.
  90. Arguments:
  91. None.
  92. Return Value:
  93. HRESULT returned from SensConfigurationHelper()
  94. --*/
  95. {
  96. return (SensConfigurationHelper(FALSE));
  97. }
  98. HRESULT APIENTRY
  99. SensUnregister(
  100. void
  101. )
  102. /*++
  103. Routine Description:
  104. Unregister SENS.
  105. Arguments:
  106. None.
  107. Return Value:
  108. HRESULT returned from SensConfigurationHelper()
  109. --*/
  110. {
  111. return (SensConfigurationHelper(TRUE));
  112. }
  113. HRESULT
  114. SensConfigurationHelper(
  115. BOOL bUnregister
  116. )
  117. /*++
  118. Routine Description:
  119. Main entry into the SENS configuration utility.
  120. Arguments:
  121. bUnregister - If TRUE, then unregister SENS as a publisher.
  122. Return Value:
  123. S_OK, if successful
  124. hr, otherwise
  125. --*/
  126. {
  127. HRESULT hr;
  128. hr = S_OK;
  129. gpIEventSystem = NULL;
  130. gpITypeLib = NULL;
  131. #ifdef DBG
  132. EnableDebugOutputIfNecessary();
  133. #endif // DBG
  134. //
  135. // Configure EventSystem first during an install and last during an uninstall.
  136. //
  137. if (FALSE == bUnregister)
  138. {
  139. hr = SensConfigureEventSystem(FALSE);
  140. if (FAILED(hr))
  141. {
  142. SensPrintA(SENS_ERR, (SENS_SETUP "Failed to configure EventSystem, HRESULT=%x\n", hr));
  143. goto Cleanup;
  144. }
  145. SensPrintA(SENS_INFO, (SENS_SETUP "Successfully configured EventSystem\n"));
  146. }
  147. //
  148. // Instantiate the Event System
  149. //
  150. hr = CoCreateInstance(
  151. CLSID_CEventSystem,
  152. NULL,
  153. CLSCTX_SERVER,
  154. IID_IEventSystem,
  155. (LPVOID *) &gpIEventSystem
  156. );
  157. if (FAILED(hr))
  158. {
  159. SensPrintA(SENS_ERR, (SENS_SETUP "Failed to create CEventSystem, HRESULT=%x\n", hr));
  160. goto Cleanup;
  161. }
  162. SensPrintA(SENS_INFO, (SENS_SETUP "Successfully created CEventSystem\n"));
  163. //
  164. // Register Event Classes (and hence, indirectly events) published by SENS.
  165. //
  166. hr = RegisterSensEventClasses(bUnregister);
  167. if (FAILED(hr))
  168. {
  169. SensPrintA(SENS_ERR, (SENS_SETUP "Failed to %sregister SENS Events"
  170. " - hr = <%x>\n", bUnregister ? "un" : "", hr));
  171. goto Cleanup;
  172. }
  173. SensPrintA(SENS_INFO, (SENS_SETUP "%segistered SENS Publisher Events.\n",
  174. bUnregister ? "Unr" : "R", hr));
  175. //
  176. // Register the subscriptions of SENS.
  177. //
  178. hr = RegisterSensSubscriptions(bUnregister);
  179. if (FAILED(hr))
  180. {
  181. SensPrintA(SENS_ERR, (SENS_SETUP "Failed to %sregister SENS Subscriptions"
  182. " - hr = <%x>\n", bUnregister ? "un" : "", hr));
  183. goto Cleanup;
  184. }
  185. SensPrintA(SENS_ERR, (SENS_SETUP "%segistered SENS Subscriptions.\n",
  186. bUnregister ? "Unr" : "R", hr));
  187. //
  188. // Register the SENS TypeLibs.
  189. //
  190. hr = RegisterSensTypeLibraries(bUnregister);
  191. if (FAILED(hr))
  192. {
  193. SensPrintA(SENS_ERR, (SENS_SETUP "Failed to %sregister SENS Type Libraries"
  194. " - hr = <%x>\n", bUnregister ? "un" : "", hr));
  195. // Abort only during the Install phase...
  196. if (bUnregister == FALSE)
  197. {
  198. goto Cleanup;
  199. }
  200. }
  201. SensPrintA(SENS_INFO, (SENS_SETUP "%segistered SENS Type Libraries.\n",
  202. bUnregister ? "Unr" : "R", hr));
  203. //
  204. // Configure EventSystem first during an install and last during an uninstall.
  205. //
  206. if (TRUE == bUnregister)
  207. {
  208. hr = SensConfigureEventSystem(TRUE);
  209. if (FAILED(hr))
  210. {
  211. SensPrintA(SENS_ERR, (SENS_SETUP "Failed to configure EventSystem, HRESULT=%x\n", hr));
  212. goto Cleanup;
  213. }
  214. SensPrintA(SENS_INFO, (SENS_SETUP "Successfully configured EventSystem\n"));
  215. }
  216. //
  217. // Register SENS CLSID in the registry.
  218. //
  219. hr = RegisterSensCLSID(
  220. SENSGUID_SUBSCRIBER_LCE,
  221. SENS_SUBSCRIBER_NAME_EVENTOBJECTCHANGE,
  222. bUnregister
  223. );
  224. if (FAILED(hr))
  225. {
  226. SensPrintA(SENS_ERR, (SENS_SETUP "Failed to %sregister SENS CLSID"
  227. " - hr = <%x>\n", bUnregister ? "un" : "", hr));
  228. goto Cleanup;
  229. }
  230. SensPrintA(SENS_INFO, (SENS_SETUP "%segistered SENS CLSID.\n",
  231. bUnregister ? "Unr" : "R", hr));
  232. //
  233. // Update Configured value
  234. //
  235. hr = SensUpdateVersion(bUnregister);
  236. if (FAILED(hr))
  237. {
  238. SensPrintA(SENS_ERR, (SENS_SETUP "Failed to update SENS version"
  239. " - hr = <%x>\n", hr));
  240. goto Cleanup;
  241. }
  242. SensPrintA(SENS_INFO, (SENS_SETUP "Updated SENS version.\n"));
  243. Cleanup:
  244. //
  245. // Cleanup
  246. //
  247. if (gpIEventSystem)
  248. {
  249. gpIEventSystem->Release();
  250. }
  251. if (gpITypeLib)
  252. {
  253. gpITypeLib->Release();
  254. }
  255. SensPrintA(SENS_ERR, ("\n" SENS_SETUP "SENS Configuration %s.\n",
  256. SUCCEEDED(hr) ? "successful" : "failed"));
  257. return (hr);
  258. }
  259. HRESULT
  260. RegisterSensEventClasses(
  261. BOOL bUnregister
  262. )
  263. /*++
  264. Routine Description:
  265. Register/Unregister all the Events published by SENS.
  266. Arguments:
  267. bUnregister - If TRUE, then unregister all SENS Events.
  268. Return Value:
  269. S_OK, if successful
  270. hr, otherwise
  271. --*/
  272. {
  273. int i;
  274. int errorIndex;
  275. HRESULT hr;
  276. LPOLESTR strGuid;
  277. LPOLESTR strEventClassID;
  278. WCHAR szQuery[MAX_QUERY_SIZE];
  279. BSTR bstrEventClassID;
  280. BSTR bstrEventClassName;
  281. BSTR bstrFiringInterface;
  282. IEventClass *pIEventClass;
  283. hr = S_OK;
  284. strGuid = NULL;
  285. errorIndex = 0;
  286. strEventClassID = NULL;
  287. bstrEventClassID = NULL;
  288. bstrEventClassName = NULL;
  289. bstrFiringInterface = NULL;
  290. pIEventClass = NULL;
  291. for (i = 0; i < SENS_PUBLISHER_EVENTCLASS_COUNT; i++)
  292. {
  293. // Get a new IEventClass.
  294. hr = CoCreateInstance(
  295. CLSID_CEventClass,
  296. NULL,
  297. CLSCTX_SERVER,
  298. IID_IEventClass,
  299. (LPVOID *) &pIEventClass
  300. );
  301. if (FAILED(hr))
  302. {
  303. SensPrintA(SENS_ERR, (SENS_SETUP "RegisterSensEventClasses() failed to create "
  304. "IEventClass - hr = <%x>\n", hr));
  305. goto Cleanup;
  306. }
  307. if (bUnregister)
  308. {
  309. // Form the query
  310. StringCchCopy(szQuery, MAX_QUERY_SIZE, SENS_BSTR("EventClassID="));
  311. AllocateStrFromGuid(strEventClassID, *(gSensEventClasses[i].pEventClassID));
  312. StringCchCat(szQuery, MAX_QUERY_SIZE, strEventClassID);
  313. hr = gpIEventSystem->Remove(
  314. PROGID_EventClass,
  315. szQuery,
  316. &errorIndex
  317. );
  318. FreeStr(strEventClassID);
  319. if (FAILED(hr))
  320. {
  321. SensPrintA(SENS_ERR, (SENS_SETUP "RegisterSensEventClasses(%d) failed to Store"
  322. " - hr = <%x>\n", i, hr));
  323. goto Cleanup;
  324. }
  325. pIEventClass->Release();
  326. pIEventClass = NULL;
  327. continue;
  328. }
  329. AllocateBstrFromGuid(bstrEventClassID, *(gSensEventClasses[i].pEventClassID));
  330. hr = pIEventClass->put_EventClassID(bstrEventClassID);
  331. ASSERT(SUCCEEDED(hr));
  332. AllocateBstrFromString(bstrEventClassName, gSensEventClasses[i].strEventClassName);
  333. hr = pIEventClass->put_EventClassName(bstrEventClassName);
  334. ASSERT(SUCCEEDED(hr));
  335. AllocateBstrFromGuid(bstrFiringInterface, *(gSensEventClasses[i].pFiringInterfaceGUID));
  336. hr = pIEventClass->put_FiringInterfaceID(bstrFiringInterface);
  337. ASSERT(SUCCEEDED(hr));
  338. FreeBstr(bstrEventClassID);
  339. FreeBstr(bstrEventClassName);
  340. FreeBstr(bstrFiringInterface);
  341. hr = gpIEventSystem->Store(PROGID_EventClass, pIEventClass);
  342. if (FAILED(hr))
  343. {
  344. SensPrintA(SENS_ERR, (SENS_SETUP "RegisterSensEventClasses(%d) failed to Store"
  345. " - hr = <%x>\n", i, hr));
  346. goto Cleanup;
  347. }
  348. pIEventClass->Release();
  349. pIEventClass = NULL;
  350. } // for loop
  351. Cleanup:
  352. //
  353. // Cleanup
  354. //
  355. if (pIEventClass)
  356. {
  357. pIEventClass->Release();
  358. }
  359. FreeStr(strGuid);
  360. return (hr);
  361. }
  362. HRESULT
  363. RegisterSensSubscriptions(
  364. BOOL bUnregister
  365. )
  366. /*++
  367. Routine Description:
  368. Register/Unregister the Event subscriptions of SENS.
  369. Arguments:
  370. bUnregister - If TRUE, then unregister all subscriptions of SENS.
  371. Return Value:
  372. S_OK, if successful
  373. hr, otherwise
  374. --*/
  375. {
  376. int i;
  377. int errorIndex;
  378. HRESULT hr;
  379. LPOLESTR strGuid;
  380. LPOLESTR strSubscriptionID;
  381. LPOLESTR strEventClassID;
  382. WCHAR szQuery[MAX_QUERY_SIZE];
  383. BSTR bstrEventClassID;
  384. BSTR bstrInterfaceID;
  385. BSTR bstrPublisherID;
  386. BSTR bstrSubscriptionID;
  387. BSTR bstrSubscriptionName;
  388. BSTR bstrSubscriberCLSID;
  389. BSTR bstrMethodName;
  390. BSTR bstrPublisherPropertyName;
  391. BSTR bstrPublisherPropertyValue;
  392. VARIANT variantPublisherPropertyValue;
  393. BSTR bstrPROGID_EventSubscription;
  394. IEventSubscription *pIEventSubscription;
  395. hr = S_OK;
  396. strGuid = NULL;
  397. errorIndex = 0;
  398. strEventClassID = NULL;
  399. bstrEventClassID = NULL;
  400. bstrInterfaceID = NULL;
  401. bstrPublisherID = NULL;
  402. strSubscriptionID = NULL;
  403. bstrSubscriptionID = NULL;
  404. bstrSubscriberCLSID = NULL;
  405. bstrSubscriptionName = NULL;
  406. bstrMethodName = NULL;
  407. bstrPublisherPropertyName = NULL;
  408. bstrPublisherPropertyValue = NULL;
  409. bstrPROGID_EventSubscription = NULL;
  410. pIEventSubscription = NULL;
  411. AllocateBstrFromGuid(bstrPublisherID, SENSGUID_PUBLISHER);
  412. AllocateBstrFromGuid(bstrSubscriberCLSID, SENSGUID_SUBSCRIBER_LCE);
  413. AllocateBstrFromString(bstrPROGID_EventSubscription, PROGID_EventSubscription);
  414. for (i = 0; i < SENS_SUBSCRIPTIONS_COUNT; i++)
  415. {
  416. if (bUnregister)
  417. {
  418. // Form the query
  419. StringCchCopy(szQuery, MAX_QUERY_SIZE, SENS_BSTR("SubscriptionID="));
  420. AllocateStrFromGuid(strSubscriptionID, *(gSensSubscriptions[i].pSubscriptionID));
  421. StringCchCat(szQuery, MAX_QUERY_SIZE, strSubscriptionID);
  422. hr = gpIEventSystem->Remove(
  423. PROGID_EventSubscription,
  424. szQuery,
  425. &errorIndex
  426. );
  427. FreeStr(strSubscriptionID);
  428. if (FAILED(hr))
  429. {
  430. SensPrintA(SENS_ERR, (SENS_SETUP "RegisterSensSubscriptionis(%d) failed to Remove"
  431. " - hr = <%x>\n", i, hr));
  432. goto Cleanup;
  433. }
  434. continue;
  435. }
  436. // Get a new IEventSubscription object to play with.
  437. hr = CoCreateInstance(
  438. CLSID_CEventSubscription,
  439. NULL,
  440. CLSCTX_SERVER,
  441. IID_IEventSubscription,
  442. (LPVOID *) &pIEventSubscription
  443. );
  444. if (FAILED(hr))
  445. {
  446. SensPrintA(SENS_ERR, (SENS_SETUP "RegisterSensSubscriptions(%d) failed to create "
  447. "IEventSubscriptions - hr = <%x>\n", i, hr));
  448. goto Cleanup;
  449. }
  450. AllocateBstrFromGuid(bstrSubscriptionID, *(gSensSubscriptions[i].pSubscriptionID));
  451. hr = pIEventSubscription->put_SubscriptionID(bstrSubscriptionID);
  452. ASSERT(SUCCEEDED(hr));
  453. hr = pIEventSubscription->put_PublisherID(bstrPublisherID);
  454. ASSERT(SUCCEEDED(hr));
  455. hr = pIEventSubscription->put_SubscriberCLSID(bstrSubscriberCLSID);
  456. ASSERT(SUCCEEDED(hr));
  457. AllocateBstrFromString(bstrSubscriptionName, gSensSubscriptions[i].strSubscriptionName);
  458. hr = pIEventSubscription->put_SubscriptionName(bstrSubscriptionName);
  459. ASSERT(SUCCEEDED(hr));
  460. AllocateBstrFromString(bstrMethodName, gSensSubscriptions[i].strMethodName);
  461. hr = pIEventSubscription->put_MethodName(bstrMethodName);
  462. ASSERT(SUCCEEDED(hr));
  463. AllocateBstrFromGuid(bstrEventClassID, *(gSensSubscriptions[i].pEventClassID));
  464. hr = pIEventSubscription->put_EventClassID(bstrEventClassID);
  465. ASSERT(SUCCEEDED(hr));
  466. AllocateBstrFromGuid(bstrInterfaceID, *(gSensSubscriptions[i].pInterfaceID));
  467. hr = pIEventSubscription->put_InterfaceID(bstrInterfaceID);
  468. ASSERT(SUCCEEDED(hr));
  469. if (gSensSubscriptions[i].bPublisherPropertyPresent == TRUE)
  470. {
  471. if (NULL != (gSensSubscriptions[i].pPropertyEventClassIDValue))
  472. {
  473. // Create the Query string.
  474. StringCchCopy(szQuery, MAX_QUERY_SIZE, gSensSubscriptions[i].strPropertyEventClassID);
  475. StringCchCat(szQuery, MAX_QUERY_SIZE, SENS_BSTR("="));
  476. AllocateStrFromGuid(strEventClassID, *(gSensSubscriptions[i].pPropertyEventClassIDValue));
  477. StringCchCat(szQuery, MAX_QUERY_SIZE, strEventClassID);
  478. StringCchCat(szQuery, MAX_QUERY_SIZE, SENS_BSTR(" AND "));
  479. StringCchCat(szQuery, MAX_QUERY_SIZE, gSensSubscriptions[i].strPropertyMethodName);
  480. StringCchCat(szQuery, MAX_QUERY_SIZE, SENS_BSTR("=\'"));
  481. StringCchCat(szQuery, MAX_QUERY_SIZE, gSensSubscriptions[i].strPropertyMethodNameValue);
  482. StringCchCat(szQuery, MAX_QUERY_SIZE, SENS_BSTR("\'"));
  483. AllocateBstrFromString(bstrPublisherPropertyName, SENS_BSTR("Criteria"));
  484. AllocateBstrFromString(bstrPublisherPropertyValue, szQuery);
  485. InitializeBstrVariant(&variantPublisherPropertyValue, bstrPublisherPropertyValue);
  486. hr = pIEventSubscription->PutPublisherProperty(
  487. bstrPublisherPropertyName,
  488. &variantPublisherPropertyValue
  489. );
  490. ASSERT(SUCCEEDED(hr));
  491. SensPrintA(SENS_INFO, (SENS_SETUP "PutPublisherProperty(Criteria) returned 0x%x\n", hr));
  492. FreeStr(strEventClassID);
  493. FreeBstr(bstrPublisherPropertyName);
  494. FreeBstr(bstrPublisherPropertyValue);
  495. }
  496. else
  497. {
  498. //
  499. // We are dealing with the "ANY" subscription of SENS.
  500. //
  501. // Create the Query string.
  502. StringCchCopy(szQuery, MAX_QUERY_SIZE, gSensSubscriptions[i].strPropertyEventClassID);
  503. StringCchCat(szQuery, MAX_QUERY_SIZE, SENS_BSTR("="));
  504. AllocateStrFromGuid(strEventClassID, SENSGUID_EVENTCLASS_NETWORK);
  505. StringCchCat(szQuery, MAX_QUERY_SIZE, strEventClassID);
  506. StringCchCat(szQuery, MAX_QUERY_SIZE, SENS_BSTR(" OR "));
  507. FreeStr(strEventClassID);
  508. StringCchCat(szQuery, MAX_QUERY_SIZE, gSensSubscriptions[i].strPropertyEventClassID);
  509. StringCchCat(szQuery, MAX_QUERY_SIZE, SENS_BSTR("="));
  510. AllocateStrFromGuid(strEventClassID, SENSGUID_EVENTCLASS_LOGON);
  511. StringCchCat(szQuery, MAX_QUERY_SIZE, strEventClassID);
  512. StringCchCat(szQuery, MAX_QUERY_SIZE, SENS_BSTR(" OR "));
  513. FreeStr(strEventClassID);
  514. StringCchCat(szQuery, MAX_QUERY_SIZE, gSensSubscriptions[i].strPropertyEventClassID);
  515. StringCchCat(szQuery, MAX_QUERY_SIZE, SENS_BSTR("="));
  516. AllocateStrFromGuid(strEventClassID, SENSGUID_EVENTCLASS_ONNOW);
  517. StringCchCat(szQuery, MAX_QUERY_SIZE, strEventClassID);
  518. FreeStr(strEventClassID);
  519. AllocateBstrFromString(bstrPublisherPropertyName, SENS_BSTR("Criteria"));
  520. AllocateBstrFromString(bstrPublisherPropertyValue, szQuery);
  521. InitializeBstrVariant(&variantPublisherPropertyValue, bstrPublisherPropertyValue);
  522. hr = pIEventSubscription->PutPublisherProperty(
  523. bstrPublisherPropertyName,
  524. &variantPublisherPropertyValue
  525. );
  526. ASSERT(SUCCEEDED(hr));
  527. SensPrintA(SENS_INFO, (SENS_SETUP "PutPublisherProperty(Criteria) returned 0x%x\n", hr));
  528. FreeBstr(bstrPublisherPropertyName);
  529. FreeBstr(bstrPublisherPropertyValue);
  530. }
  531. }
  532. FreeBstr(bstrSubscriptionID);
  533. FreeBstr(bstrSubscriptionName);
  534. FreeBstr(bstrMethodName);
  535. FreeBstr(bstrEventClassID);
  536. FreeBstr(bstrInterfaceID);
  537. hr = gpIEventSystem->Store(bstrPROGID_EventSubscription, pIEventSubscription);
  538. if (FAILED(hr))
  539. {
  540. SensPrintA(SENS_ERR, (SENS_SETUP "RegisterSensSubscriptions(%d) failed to Store"
  541. " - hr = <%x>\n", i, hr));
  542. goto Cleanup;
  543. }
  544. pIEventSubscription->Release();
  545. pIEventSubscription = NULL;
  546. } // for loop
  547. Cleanup:
  548. //
  549. // Cleanup
  550. //
  551. if (pIEventSubscription)
  552. {
  553. pIEventSubscription->Release();
  554. }
  555. FreeBstr(bstrPublisherID);
  556. FreeBstr(bstrSubscriberCLSID);
  557. FreeBstr(bstrPROGID_EventSubscription);
  558. FreeStr(strGuid);
  559. return (hr);
  560. }
  561. HRESULT
  562. RegisterSensTypeLibraries(
  563. BOOL bUnregister
  564. )
  565. /*++
  566. Routine Description:
  567. Register/Unregister the Type Libraries of SENS.
  568. Arguments:
  569. bUnregister - If TRUE, then unregister all subscriptions of SENS.
  570. Return Value:
  571. S_OK, if successful
  572. hr, otherwise
  573. --*/
  574. {
  575. HRESULT hr;
  576. UINT uiLength;
  577. TCHAR buffer[MAX_PATH+1+sizeof(SENS_BINARYA)+1]; // +1 for '\'
  578. hr = S_OK;
  579. uiLength = 0;
  580. //
  581. // Get the Full path name to the SENS TLB (which is a resource in SENS.EXE)
  582. //
  583. uiLength = GetSystemDirectory(
  584. buffer,
  585. MAX_PATH
  586. );
  587. if (uiLength == 0)
  588. {
  589. hr = HRESULT_FROM_WIN32(GetLastError());
  590. SensPrintA(SENS_ERR, (SENS_SETUP "GetSystemDirectory(%s) failed - hr = <%x>\n",
  591. SENS_TLBA, hr));
  592. goto Cleanup;
  593. }
  594. StringCbCat(buffer, sizeof(buffer), SENS_STRING("\\") SENS_TLB);
  595. hr = LoadTypeLibEx(
  596. buffer,
  597. REGKIND_NONE,
  598. &gpITypeLib
  599. );
  600. if (FAILED(hr))
  601. {
  602. SensPrintA(SENS_ERR, (SENS_SETUP "LoadTypeLib(%s) failed "
  603. " - hr = <%x>\n", SENS_TLBA, hr));
  604. goto Cleanup;
  605. }
  606. //
  607. // Ensure that the TypeLib is (un)registered
  608. //
  609. if (bUnregister)
  610. {
  611. hr = UnRegisterTypeLib(
  612. LIBID_SensEvents,
  613. MAJOR_VER,
  614. MINOR_VER,
  615. DEFAULT_LCID,
  616. SYS_WIN32
  617. );
  618. }
  619. else
  620. {
  621. hr = RegisterTypeLib(
  622. gpITypeLib,
  623. buffer,
  624. NULL
  625. );
  626. }
  627. if (FAILED(hr))
  628. {
  629. SensPrintA(SENS_ERR, (SENS_SETUP "%sRegisterTypeLib(%s) failed "
  630. " - hr = <%x>\n", (bUnregister ? "Un" : ""), SENS_TLBA, hr));
  631. }
  632. Cleanup:
  633. //
  634. // Cleanup
  635. //
  636. return (hr);
  637. }
  638. HRESULT
  639. RegisterSensCLSID(
  640. REFIID clsid,
  641. TCHAR* strSubscriberName,
  642. BOOL bUnregister
  643. )
  644. /*++
  645. Routine Description:
  646. Register/Unregister the CLSID of SENS.
  647. Arguments:
  648. clsid - CLSID of the Subscriber for LCE events.
  649. strSubscriberName - Name of the Subscriber.
  650. bUnregister - If TRUE, then unregister the CLSID of SENS.
  651. Notes:
  652. This function also registers SENS to receive IE5's WININET events.
  653. Return Value:
  654. S_OK, if successful
  655. hr, otherwise
  656. --*/
  657. {
  658. HRESULT hr;
  659. HMODULE hModule;
  660. HKEY appidKey;
  661. HKEY clsidKey;
  662. HKEY serverKey;
  663. WCHAR *szCLSID;
  664. WCHAR *szCLSID2;
  665. WCHAR *szLIBID;
  666. TCHAR *szCLSID_t;
  667. TCHAR *szCLSID2_t;
  668. TCHAR *szLIBID_t;
  669. TCHAR *szFriendlyName;
  670. TCHAR szPath[MAX_PATH+1+sizeof(SENS_BINARYA)+1]; // +1 for '\'
  671. UINT uiLength;
  672. DWORD dwDisposition;
  673. LONG lResult;
  674. hr = S_OK;
  675. appidKey = NULL;
  676. clsidKey = NULL;
  677. serverKey = NULL;
  678. szCLSID = NULL;
  679. szCLSID2 = NULL;
  680. szLIBID = NULL;
  681. szCLSID_t = NULL;
  682. szCLSID2_t = NULL;
  683. szLIBID_t = NULL;
  684. uiLength = 0;
  685. dwDisposition = 0x0;
  686. szFriendlyName = strSubscriberName;
  687. //
  688. // Get the Full path name to the SENS executable
  689. //
  690. uiLength = GetSystemDirectory(
  691. szPath,
  692. MAX_PATH
  693. );
  694. if (uiLength == 0)
  695. {
  696. hr = HRESULT_FROM_WIN32(GetLastError());
  697. SensPrintA(SENS_ERR, (SENS_SETUP "GetSystemDirectory(%s) failed - hr = <%x>\n",
  698. SENS_BINARYA, hr));
  699. goto Cleanup;
  700. }
  701. StringCbCat(szPath, sizeof(szPath), SENS_STRING("\\") SENS_BINARY);
  702. //
  703. // Convert the CLSID into a WCHAR.
  704. //
  705. hr = StringFromCLSID(clsid, &szCLSID);
  706. if (FAILED(hr))
  707. {
  708. goto Cleanup;
  709. }
  710. if (bUnregister == FALSE)
  711. {
  712. hr = StringFromCLSID(LIBID_SensEvents, &szLIBID);
  713. if (FAILED(hr))
  714. {
  715. goto Cleanup;
  716. }
  717. }
  718. szCLSID_t = szCLSID;
  719. szLIBID_t = szLIBID;
  720. // Build the key CLSID\\{clsid}
  721. TCHAR clsidKeyName[sizeof "CLSID\\{12345678-1234-1234-1234-123456789012}"];
  722. StringCbCopy(clsidKeyName, sizeof(clsidKeyName), SENS_STRING("CLSID\\"));
  723. StringCbCat(clsidKeyName, sizeof(clsidKeyName), szCLSID_t);
  724. // Build the key AppID\\{clsid}
  725. TCHAR appidKeyName[sizeof "AppID\\{12345678-1234-1234-1234-123456789012}"];
  726. StringCbCopy(appidKeyName, sizeof(appidKeyName), SENS_STRING("AppID\\"));
  727. StringCbCat(appidKeyName, sizeof(appidKeyName), szCLSID_t);
  728. if (bUnregister)
  729. {
  730. hr = RecursiveDeleteKey(HKEY_CLASSES_ROOT, clsidKeyName);
  731. if (FAILED(hr))
  732. {
  733. goto Cleanup;
  734. }
  735. hr = RecursiveDeleteKey(HKEY_CLASSES_ROOT, appidKeyName);
  736. goto Cleanup;
  737. }
  738. // Create the CLSID\\{clsid} key
  739. hr = CreateKey(
  740. HKEY_CLASSES_ROOT,
  741. clsidKeyName,
  742. szFriendlyName,
  743. &clsidKey
  744. );
  745. if (FAILED(hr))
  746. {
  747. goto Cleanup;
  748. }
  749. //
  750. // Under the CLSID\\{clsid} key, create a named value
  751. // AppID = {clsid}
  752. hr = CreateNamedValue(clsidKey, SENS_STRING("AppID"), szCLSID_t);
  753. if (FAILED(hr))
  754. {
  755. goto Cleanup;
  756. }
  757. //
  758. // Create the appropriate server key beneath the clsid key.
  759. // For servers, this is CLSID\\{clsid}\\LocalServer32.
  760. // In both cases, the default value is the module path name.
  761. //
  762. hr = CreateKey(
  763. clsidKey,
  764. SENS_STRING("LocalServer32"),
  765. szPath,
  766. &serverKey
  767. );
  768. if (FAILED(hr))
  769. {
  770. goto Cleanup;
  771. }
  772. RegCloseKey(serverKey);
  773. //
  774. // Create CLSID\\{clsid}\\TypeLib subkey with a default value of
  775. // the LIBID of the TypeLib
  776. //
  777. hr = CreateKey(
  778. clsidKey,
  779. SENS_STRING("TypeLib"),
  780. szLIBID_t,
  781. &serverKey
  782. );
  783. if (FAILED(hr))
  784. {
  785. goto Cleanup;
  786. }
  787. RegCloseKey(serverKey);
  788. // Register APPID.
  789. hr = CreateKey(
  790. HKEY_CLASSES_ROOT,
  791. appidKeyName,
  792. szFriendlyName,
  793. &appidKey
  794. );
  795. if (FAILED(hr))
  796. {
  797. goto Cleanup;
  798. }
  799. // Under AppId\{clsid} key, create a named value [LocalService = "SENS"]
  800. hr = CreateNamedValue(appidKey, SENS_STRING("LocalService"), SENS_STRING("SENS"));
  801. if (FAILED(hr))
  802. {
  803. goto Cleanup;
  804. }
  805. Cleanup:
  806. //
  807. // Cleanup
  808. //
  809. CoTaskMemFree(szCLSID);
  810. CoTaskMemFree(szLIBID);
  811. if (clsidKey != NULL)
  812. {
  813. RegCloseKey(clsidKey);
  814. }
  815. if (appidKey != NULL)
  816. {
  817. RegCloseKey(appidKey);
  818. }
  819. return hr;
  820. }
  821. HRESULT
  822. CreateKey(
  823. HKEY hParentKey,
  824. const TCHAR* KeyName,
  825. const TCHAR* defaultValue,
  826. HKEY* hKey
  827. )
  828. /*++
  829. Routine Description:
  830. Create a key (with an optional default value). The handle to the key is
  831. returned as an [out] parameter. If NULL is passed as the key parameter,
  832. the key is created in the registry, then closed.
  833. Arguments:
  834. hParentKey - Handle to the parent Key.
  835. KeyName - Name of the key to create.
  836. defaultValue - The default value for the key to create.
  837. hKey - OUT Handle to key that was created.
  838. Return Value:
  839. S_OK, if successful
  840. hr, otherwise
  841. --*/
  842. {
  843. HKEY hTempKey;
  844. LONG lResult;
  845. hTempKey = NULL;
  846. lResult = RegCreateKeyEx(
  847. hParentKey, // Handle to open key
  848. KeyName, // Subkey name
  849. 0, // Reserved
  850. NULL, // Class string
  851. REG_OPTION_NON_VOLATILE, // Options Flag
  852. KEY_ALL_ACCESS, // Desired Security access
  853. NULL, // Pointer to Security Attributes structure
  854. &hTempKey, // Handle of the opened/created key
  855. NULL // Disposition value
  856. );
  857. if (lResult != ERROR_SUCCESS)
  858. {
  859. return HRESULT_FROM_WIN32(lResult);
  860. }
  861. // Set the default value for the key
  862. if (defaultValue != NULL)
  863. {
  864. lResult = RegSetValueEx(
  865. hTempKey, // Key to set Value for.
  866. NULL, // Value to set
  867. 0, // Reserved
  868. REG_SZ, // Value Type
  869. (BYTE*) defaultValue, // Address of Value data
  870. sizeof(TCHAR) * (_tcslen(defaultValue)+1) // Size of Value
  871. );
  872. if (lResult != ERROR_SUCCESS)
  873. {
  874. RegCloseKey(hTempKey);
  875. return HRESULT_FROM_WIN32(lResult);
  876. }
  877. }
  878. if (hKey == NULL)
  879. {
  880. RegCloseKey(hTempKey);
  881. }
  882. else
  883. {
  884. *hKey = hTempKey;
  885. }
  886. return S_OK;
  887. }
  888. HRESULT
  889. CreateNamedValue(
  890. HKEY hKey,
  891. const TCHAR* title,
  892. const TCHAR* value
  893. )
  894. /*++
  895. Routine Description:
  896. Create a named value under a key
  897. Arguments:
  898. hKey - Handle to the parent Key.
  899. title - Name of the Value to create.
  900. value - The data for the Value under the Key.
  901. Return Value:
  902. S_OK, if successful
  903. hr, otherwise
  904. --*/
  905. {
  906. HRESULT hr;
  907. LONG lResult;
  908. hr = S_OK;
  909. lResult = RegSetValueEx(
  910. hKey, // Key to set Value for.
  911. title, // Value to set
  912. 0, // Reserved
  913. REG_SZ, // Value Type
  914. (BYTE*) value, // Address of Value data
  915. sizeof(TCHAR) * (_tcslen(value)+1) // Size of Value
  916. );
  917. if (lResult != ERROR_SUCCESS)
  918. {
  919. hr = HRESULT_FROM_WIN32(lResult);
  920. }
  921. return hr;
  922. }
  923. HRESULT
  924. CreateNamedDwordValue(
  925. HKEY hKey,
  926. const TCHAR* title,
  927. DWORD dwValue
  928. )
  929. /*++
  930. Routine Description:
  931. Create a named DWORD value under a key
  932. Arguments:
  933. hKey - Handle to the parent Key.
  934. title - Name of the Value to create.
  935. dwValue - The data for the Value under the Key.
  936. Return Value:
  937. S_OK, if successful
  938. hr, otherwise
  939. --*/
  940. {
  941. HRESULT hr;
  942. LONG lResult;
  943. hr = S_OK;
  944. lResult = RegSetValueEx(
  945. hKey, // Key to set Value for.
  946. title, // Value to set
  947. 0, // Reserved
  948. REG_DWORD, // Value Type
  949. (BYTE*) &dwValue, // Address of Value data
  950. sizeof(DWORD) // Size of Value
  951. );
  952. if (lResult != ERROR_SUCCESS)
  953. {
  954. hr = HRESULT_FROM_WIN32(lResult);
  955. }
  956. return hr;
  957. }
  958. HRESULT
  959. RecursiveDeleteKey(
  960. HKEY hKeyParent,
  961. const TCHAR* lpszKeyChild
  962. )
  963. /*++
  964. Routine Description:
  965. Delete a key and all of its descendents.
  966. Arguments:
  967. hKeyParent - Handle to the parent Key.
  968. lpszKeyChild - The data for the Value under the Key.
  969. Return Value:
  970. S_OK, if successful
  971. hr, otherwise
  972. --*/
  973. {
  974. HKEY hKeyChild;
  975. LONG lResult;
  976. //
  977. // Open the child.
  978. //
  979. lResult = RegOpenKeyEx(
  980. hKeyParent, // Handle to the Parent
  981. lpszKeyChild, // Name of the child key
  982. 0, // Reserved
  983. KEY_ALL_ACCESS, // Security Access Mask
  984. &hKeyChild // Handle to the opened key
  985. );
  986. if (lResult != ERROR_SUCCESS)
  987. {
  988. return HRESULT_FROM_WIN32(lResult);
  989. }
  990. //
  991. // Enumerate all of the decendents of this child.
  992. //
  993. FILETIME time;
  994. TCHAR szBuffer[MAX_PATH+1];
  995. const DWORD bufSize = sizeof szBuffer / sizeof szBuffer[0];
  996. DWORD dwSize = bufSize;
  997. while (TRUE)
  998. {
  999. lResult = RegEnumKeyEx(
  1000. hKeyChild, // Handle of the key to enumerate
  1001. 0, // Index of the subkey to retrieve
  1002. szBuffer, // OUT Name of the subkey
  1003. &dwSize, // OUT Size of the buffer for name of subkey
  1004. NULL, // Reserved
  1005. NULL, // OUT Class of the enumerated subkey
  1006. NULL, // OUT Size of the class of the subkey
  1007. &time // OUT Last time the subkey was written to
  1008. );
  1009. if (lResult != ERROR_SUCCESS)
  1010. {
  1011. break;
  1012. }
  1013. // Delete the decendents of this child.
  1014. lResult = RecursiveDeleteKey(hKeyChild, szBuffer);
  1015. if (lResult != ERROR_SUCCESS)
  1016. {
  1017. // Cleanup before exiting.
  1018. RegCloseKey(hKeyChild);
  1019. return HRESULT_FROM_WIN32(lResult);
  1020. }
  1021. dwSize = bufSize;
  1022. } // while
  1023. // Close the child.
  1024. RegCloseKey(hKeyChild);
  1025. // Delete this child.
  1026. lResult = RegDeleteKey(hKeyParent, lpszKeyChild);
  1027. return HRESULT_FROM_WIN32(lResult);
  1028. }
  1029. HRESULT
  1030. SensConfigureEventSystem(
  1031. BOOL bUnregister
  1032. )
  1033. /*++
  1034. Routine Description:
  1035. As of NTbuild 1750, EventSystem is not auto-configured. So, SENS does
  1036. the work of configuring EventSystem.
  1037. Arguments:
  1038. bUnregister - If TRUE, then install EventSystem.
  1039. Notes:
  1040. o This is a dummy call on NT4 because we don't need to configure
  1041. EventSystem on NT4. IE5 setup (Webcheck.dll) configures LCE.
  1042. Return Value:
  1043. S_OK, if successful
  1044. hr, otherwise
  1045. --*/
  1046. {
  1047. return S_OK;
  1048. }
  1049. HRESULT
  1050. SensUpdateVersion(
  1051. BOOL bUnregister
  1052. )
  1053. /*++
  1054. Routine Description:
  1055. Update the version of SENS in the registry.
  1056. Arguments:
  1057. bUnregister - usual.
  1058. Return Value:
  1059. S_OK, if successful
  1060. hr, otherwise
  1061. --*/
  1062. {
  1063. HRESULT hr;
  1064. HKEY hKeySens;
  1065. LONG RegStatus;
  1066. DWORD dwConfigured;
  1067. hr = S_OK;
  1068. hKeySens = NULL;
  1069. RegStatus = ERROR_SUCCESS;
  1070. RegStatus = RegOpenKeyEx(
  1071. HKEY_LOCAL_MACHINE, // Handle of the key
  1072. SENS_REGISTRY_KEY, // String which represents the sub-key to open
  1073. 0, // Reserved (MBZ)
  1074. KEY_ALL_ACCESS, // Security Access mask
  1075. &hKeySens // Returned HKEY
  1076. );
  1077. if (RegStatus != ERROR_SUCCESS)
  1078. {
  1079. SensPrintA(SENS_ERR, (SENS_SETUP "RegOpenKeyEx(Sens) returned %d.\n", RegStatus));
  1080. hr = HRESULT_FROM_WIN32(RegStatus);
  1081. goto Cleanup;
  1082. }
  1083. if (TRUE == bUnregister)
  1084. {
  1085. dwConfigured = CONFIG_VERSION_NONE;
  1086. }
  1087. else
  1088. {
  1089. dwConfigured = CONFIG_VERSION_CURRENT;
  1090. }
  1091. // Update registry to reflect that SENS is now configured.
  1092. RegStatus = RegSetValueEx(
  1093. hKeySens, // Key to set Value for.
  1094. IS_SENS_CONFIGURED, // Value to set
  1095. 0, // Reserved
  1096. REG_DWORD, // Value Type
  1097. (BYTE*) &dwConfigured,// Address of Value data
  1098. sizeof(DWORD) // Size of Value
  1099. );
  1100. if (RegStatus != ERROR_SUCCESS)
  1101. {
  1102. SensPrintA(SENS_ERR, (SENS_SETUP "RegSetValueEx(IS_SENS_CONFIGURED) failed with 0x%x\n", RegStatus));
  1103. hr = HRESULT_FROM_WIN32(RegStatus);
  1104. goto Cleanup;
  1105. }
  1106. SensPrintA(SENS_INFO, (SENS_SETUP "SENS is now configured successfully. "
  1107. "Registry updated to 0x%x.\n", dwConfigured));
  1108. Cleanup:
  1109. //
  1110. // Cleanup
  1111. //
  1112. if (hKeySens)
  1113. {
  1114. RegCloseKey(hKeySens);
  1115. }
  1116. return hr;
  1117. }