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.

1039 lines
26 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1998 <company name>
  4. //
  5. // Module Name:
  6. // RegExt.cpp
  7. //
  8. // Abstract:
  9. // Implementation of routines for extension registration.
  10. //
  11. // Author:
  12. // <name> (<e-mail name>) Mmmm DD, 1998
  13. //
  14. // Revision History:
  15. //
  16. // Notes:
  17. //
  18. /////////////////////////////////////////////////////////////////////////////
  19. #include "stdafx.h"
  20. #include <ole2.h>
  21. #ifdef _DEBUG
  22. #define new DEBUG_NEW
  23. #undef THIS_FILE
  24. static char THIS_FILE[] = __FILE__;
  25. #endif
  26. #define REG_VALUE_ADMIN_EXTENSIONS L"AdminExtensions"
  27. /////////////////////////////////////////////////////////////////////////////
  28. // Static Function Prototypes
  29. /////////////////////////////////////////////////////////////////////////////
  30. static HRESULT RegisterAnyCluAdminExtension(
  31. IN HCLUSTER hCluster,
  32. IN LPCWSTR pwszKeyName,
  33. IN const CLSID * pClsid
  34. );
  35. static HRESULT RegisterAnyCluAdminExtension(
  36. IN HKEY hkey,
  37. IN const CLSID * pClsid
  38. );
  39. static HRESULT UnregisterAnyCluAdminExtension(
  40. IN HCLUSTER hCluster,
  41. IN LPCWSTR pwszKeyName,
  42. IN const CLSID * pClsid
  43. );
  44. static HRESULT UnregisterAnyCluAdminExtension(
  45. IN HKEY hkey,
  46. IN const CLSID * pClsid
  47. );
  48. static DWORD ReadValue(
  49. IN HKEY hkey,
  50. IN LPCWSTR pwszValueName,
  51. OUT LPWSTR * ppwszValue,
  52. OUT DWORD * pcbSize
  53. );
  54. /////////////////////////////////////////////////////////////////////////////
  55. //++
  56. //
  57. // RegisterCluAdminClusterExtension
  58. //
  59. // Routine Description:
  60. // Register with the cluster database a Cluster Administrator Extension
  61. // DLL that extends the cluster object.
  62. //
  63. // Arguments:
  64. // hCluster [IN] Handle to the cluster to modify.
  65. // pClsid [IN] Extension's CLSID.
  66. //
  67. // Return Value:
  68. // S_OK Extension registered successfully.
  69. // Win32 error code if another failure occurred.
  70. //
  71. //--
  72. /////////////////////////////////////////////////////////////////////////////
  73. STDAPI RegisterCluAdminClusterExtension(
  74. IN HCLUSTER hCluster,
  75. IN const CLSID * pClsid
  76. )
  77. {
  78. HRESULT hr;
  79. HKEY hkey;
  80. // Get the cluster registry key.
  81. hkey = GetClusterKey(hCluster, KEY_ALL_ACCESS);
  82. if (hkey == NULL)
  83. hr = GetLastError();
  84. else
  85. {
  86. // Register the extension.
  87. hr = RegisterAnyCluAdminExtension(hkey, pClsid);
  88. ClusterRegCloseKey(hkey);
  89. } // else: GetClusterKey succeeded
  90. return hr;
  91. } //*** RegisterCluAdminClusterExtension()
  92. /////////////////////////////////////////////////////////////////////////////
  93. //++
  94. //
  95. // RegisterCluAdminAllNodesExtension
  96. //
  97. // Routine Description:
  98. // Register with the cluster database a Cluster Administrator Extension
  99. // DLL that extends all nodes.
  100. //
  101. // Arguments:
  102. // hCluster [IN] Handle to the cluster to modify.
  103. // pClsid [IN] Extension's CLSID.
  104. //
  105. // Return Value:
  106. // S_OK Extension registered successfully.
  107. // Win32 error code if another failure occurred.
  108. //
  109. //--
  110. /////////////////////////////////////////////////////////////////////////////
  111. STDAPI RegisterCluAdminAllNodesExtension(
  112. IN HCLUSTER hCluster,
  113. IN const CLSID * pClsid
  114. )
  115. {
  116. HRESULT hr;
  117. hr = RegisterAnyCluAdminExtension(hCluster, L"Nodes", pClsid);
  118. return hr;
  119. } //*** RegisterCluAdminAllNodesExtension()
  120. /////////////////////////////////////////////////////////////////////////////
  121. //++
  122. //
  123. // RegisterCluAdminAllGroupsExtension
  124. //
  125. // Routine Description:
  126. // Register with the cluster database a Cluster Administrator Extension
  127. // DLL that extends all groups.
  128. //
  129. // Arguments:
  130. // hCluster [IN] Handle to the cluster to modify.
  131. // pClsid [IN] Extension's CLSID.
  132. //
  133. // Return Value:
  134. // S_OK Extension registered successfully.
  135. // Win32 error code if another failure occurred.
  136. //
  137. //--
  138. /////////////////////////////////////////////////////////////////////////////
  139. STDAPI RegisterCluAdminAllGroupsExtension(
  140. IN HCLUSTER hCluster,
  141. IN const CLSID * pClsid
  142. )
  143. {
  144. HRESULT hr;
  145. hr = RegisterAnyCluAdminExtension(hCluster, L"Groups", pClsid);
  146. return hr;
  147. } //*** RegisterCluAdminAllGroupsExtension()
  148. /////////////////////////////////////////////////////////////////////////////
  149. //++
  150. //
  151. // RegisterCluAdminAllResourcesExtension
  152. //
  153. // Routine Description:
  154. // Register with the cluster database a Cluster Administrator Extension
  155. // DLL that extends all resources.
  156. //
  157. // Arguments:
  158. // hCluster [IN] Handle to the cluster to modify.
  159. // pClsid [IN] Extension's CLSID.
  160. //
  161. // Return Value:
  162. // S_OK Extension registered successfully.
  163. // Win32 error code if another failure occurred.
  164. //
  165. //--
  166. /////////////////////////////////////////////////////////////////////////////
  167. STDAPI RegisterCluAdminAllResourcesExtension(
  168. IN HCLUSTER hCluster,
  169. IN const CLSID * pClsid
  170. )
  171. {
  172. HRESULT hr;
  173. hr = RegisterAnyCluAdminExtension(hCluster, L"Resources", pClsid);
  174. return hr;
  175. } //*** RegisterCluAdminAllResourcesExtension()
  176. /////////////////////////////////////////////////////////////////////////////
  177. //++
  178. //
  179. // RegisterCluAdminAllResourceTypesExtension
  180. //
  181. // Routine Description:
  182. // Register with the cluster database a Cluster Administrator Extension
  183. // DLL that extends all resource types.
  184. //
  185. // Arguments:
  186. // hCluster [IN] Handle to the cluster to modify.
  187. // pClsid [IN] Extension's CLSID.
  188. //
  189. // Return Value:
  190. // S_OK Extension registered successfully.
  191. // Win32 error code if another failure occurred.
  192. //
  193. //--
  194. /////////////////////////////////////////////////////////////////////////////
  195. STDAPI RegisterCluAdminAllResourceTypesExtension(
  196. IN HCLUSTER hCluster,
  197. IN const CLSID * pClsid
  198. )
  199. {
  200. HRESULT hr;
  201. hr = RegisterAnyCluAdminExtension(hCluster, L"ResourceTypes", pClsid);
  202. return hr;
  203. } //*** RegisterCluAdminAllResourceTypesExtension()
  204. /////////////////////////////////////////////////////////////////////////////
  205. //++
  206. //
  207. // RegisterCluAdminAllNetworksExtension
  208. //
  209. // Routine Description:
  210. // Register with the cluster database a Cluster Administrator Extension
  211. // DLL that extends all networks.
  212. //
  213. // Arguments:
  214. // hCluster [IN] Handle to the cluster to modify.
  215. // pClsid [IN] Extension's CLSID.
  216. //
  217. // Return Value:
  218. // S_OK Extension registered successfully.
  219. // Win32 error code if another failure occurred.
  220. //
  221. //--
  222. /////////////////////////////////////////////////////////////////////////////
  223. STDAPI RegisterCluAdminAllNetworksExtension(
  224. IN HCLUSTER hCluster,
  225. IN const CLSID * pClsid
  226. )
  227. {
  228. HRESULT hr;
  229. hr = RegisterAnyCluAdminExtension(hCluster, L"Networks", pClsid);
  230. return hr;
  231. } //*** RegisterCluAdminAllNetworksExtension()
  232. /////////////////////////////////////////////////////////////////////////////
  233. //++
  234. //
  235. // RegisterCluAdminAllNetInterfacesExtension
  236. //
  237. // Routine Description:
  238. // Register with the cluster database a Cluster Administrator Extension
  239. // DLL that extends all network interfaces.
  240. //
  241. // Arguments:
  242. // hCluster [IN] Handle to the cluster to modify.
  243. // pClsid [IN] Extension's CLSID.
  244. //
  245. // Return Value:
  246. // S_OK Extension registered successfully.
  247. // Win32 error code if another failure occurred.
  248. //
  249. //--
  250. /////////////////////////////////////////////////////////////////////////////
  251. STDAPI RegisterCluAdminAllNetInterfacesExtension(
  252. IN HCLUSTER hCluster,
  253. IN const CLSID * pClsid
  254. )
  255. {
  256. HRESULT hr;
  257. hr = RegisterAnyCluAdminExtension(hCluster, L"NetInterfaces", pClsid);
  258. return hr;
  259. } //*** RegisterCluAdminAllNetInterfacesExtension()
  260. /////////////////////////////////////////////////////////////////////////////
  261. //++
  262. //
  263. // RegisterCluAdminResourceTypeExtension
  264. //
  265. // Routine Description:
  266. // Register with the cluster database a Cluster Administrator Extension
  267. // DLL that extends resources of a specific type, or the resource type
  268. // itself.
  269. //
  270. // Arguments:
  271. // hCluster [IN] Handle to the cluster to modify.
  272. // pwszResourceType [IN] Resource type name.
  273. // pClsid [IN] Extension's CLSID.
  274. //
  275. // Return Value:
  276. // S_OK Extension registered successfully.
  277. // Win32 error code if another failure occurred.
  278. //
  279. //--
  280. /////////////////////////////////////////////////////////////////////////////
  281. STDAPI RegisterCluAdminResourceTypeExtension(
  282. IN HCLUSTER hCluster,
  283. IN LPCWSTR pwszResourceType,
  284. IN const CLSID * pClsid
  285. )
  286. {
  287. HRESULT hr;
  288. HKEY hkey;
  289. // Get the resource type registry key.
  290. hkey = GetClusterResourceTypeKey(hCluster, pwszResourceType, KEY_ALL_ACCESS);
  291. if (hkey == NULL)
  292. hr = GetLastError();
  293. else
  294. {
  295. // Register the extension.
  296. hr = RegisterAnyCluAdminExtension(hkey, pClsid);
  297. ClusterRegCloseKey(hkey);
  298. } // else: GetClusterResourceTypeKey succeeded
  299. return hr;
  300. } //*** RegisterCluAdminResourceTypeExtension()
  301. /////////////////////////////////////////////////////////////////////////////
  302. //++
  303. //
  304. // UnregisterCluAdminClusterExtension
  305. //
  306. // Routine Description:
  307. // Unregister with the cluster database a Cluster Administrator Extension
  308. // DLL that extends the cluster object.
  309. //
  310. // Arguments:
  311. // hCluster [IN] Handle to the cluster to modify.
  312. // pClsid [IN] Extension's CLSID.
  313. //
  314. // Return Value:
  315. // S_OK Extension registered successfully.
  316. // Win32 error code if another failure occurred.
  317. //
  318. //--
  319. /////////////////////////////////////////////////////////////////////////////
  320. STDAPI UnregisterCluAdminClusterExtension(
  321. IN HCLUSTER hCluster,
  322. IN const CLSID * pClsid
  323. )
  324. {
  325. HRESULT hr;
  326. HKEY hkey;
  327. // Get the cluster registry key.
  328. hkey = GetClusterKey(hCluster, KEY_ALL_ACCESS);
  329. if (hkey == NULL)
  330. hr = GetLastError();
  331. else
  332. {
  333. // Unregister the extension.
  334. hr = UnregisterAnyCluAdminExtension(hkey, pClsid);
  335. ClusterRegCloseKey(hkey);
  336. } // else: GetClusterKey succeeded
  337. return hr;
  338. } //*** UnregisterCluAdminClusterExtension()
  339. /////////////////////////////////////////////////////////////////////////////
  340. //++
  341. //
  342. // UnregisterCluAdminAllNodesExtension
  343. //
  344. // Routine Description:
  345. // Unregister with the cluster database a Cluster Administrator Extension
  346. // DLL that extends all nodes.
  347. //
  348. // Arguments:
  349. // hCluster [IN] Handle to the cluster to modify.
  350. // pClsid [IN] Extension's CLSID.
  351. //
  352. // Return Value:
  353. // S_OK Extension unregistered successfully.
  354. // Win32 error code if another failure occurred.
  355. //
  356. //--
  357. /////////////////////////////////////////////////////////////////////////////
  358. STDAPI UnregisterCluAdminAllNodesExtension(
  359. IN HCLUSTER hCluster,
  360. IN const CLSID * pClsid
  361. )
  362. {
  363. HRESULT hr;
  364. hr = UnregisterAnyCluAdminExtension(hCluster, L"Nodes", pClsid);
  365. return hr;
  366. } //*** UnregisterCluAdminAllNodesExtension()
  367. /////////////////////////////////////////////////////////////////////////////
  368. //++
  369. //
  370. // UnregisterCluAdminAllGroupsExtension
  371. //
  372. // Routine Description:
  373. // Unregister with the cluster database a Cluster Administrator Extension
  374. // DLL that extends all groups.
  375. //
  376. // Arguments:
  377. // hCluster [IN] Handle to the cluster to modify.
  378. // pClsid [IN] Extension's CLSID.
  379. //
  380. // Return Value:
  381. // S_OK Extension unregistered successfully.
  382. // Win32 error code if another failure occurred.
  383. //
  384. //--
  385. /////////////////////////////////////////////////////////////////////////////
  386. STDAPI UnregisterCluAdminAllGroupsExtension(
  387. IN HCLUSTER hCluster,
  388. IN const CLSID * pClsid
  389. )
  390. {
  391. HRESULT hr;
  392. hr = UnregisterAnyCluAdminExtension(hCluster, L"Groups", pClsid);
  393. return hr;
  394. } //*** UnregisterCluAdminAllGroupsExtension()
  395. /////////////////////////////////////////////////////////////////////////////
  396. //++
  397. //
  398. // UnregisterCluAdminAllResourcesExtension
  399. //
  400. // Routine Description:
  401. // Unregister with the cluster database a Cluster Administrator Extension
  402. // DLL that extends all resources.
  403. //
  404. // Arguments:
  405. // hCluster [IN] Handle to the cluster to modify.
  406. // pClsid [IN] Extension's CLSID.
  407. //
  408. // Return Value:
  409. // S_OK Extension unregistered successfully.
  410. // Win32 error code if another failure occurred.
  411. //
  412. //--
  413. /////////////////////////////////////////////////////////////////////////////
  414. STDAPI UnregisterCluAdminAllResourcesExtension(
  415. IN HCLUSTER hCluster,
  416. IN const CLSID * pClsid
  417. )
  418. {
  419. HRESULT hr;
  420. hr = UnregisterAnyCluAdminExtension(hCluster, L"Resources", pClsid);
  421. return hr;
  422. } //*** UnregisterCluAdminAllResourcesExtension()
  423. /////////////////////////////////////////////////////////////////////////////
  424. //++
  425. //
  426. // UnregisterCluAdminAllResourceTypesExtension
  427. //
  428. // Routine Description:
  429. // Unregister with the cluster database a Cluster Administrator Extension
  430. // DLL that extends all resource types.
  431. //
  432. // Arguments:
  433. // hCluster [IN] Handle to the cluster to modify.
  434. // pClsid [IN] Extension's CLSID.
  435. //
  436. // Return Value:
  437. // S_OK Extension unregistered successfully.
  438. // Win32 error code if another failure occurred.
  439. //
  440. //--
  441. /////////////////////////////////////////////////////////////////////////////
  442. STDAPI UnregisterCluAdminAllResourceTypesExtension(
  443. IN HCLUSTER hCluster,
  444. IN const CLSID * pClsid
  445. )
  446. {
  447. HRESULT hr;
  448. hr = UnregisterAnyCluAdminExtension(hCluster, L"ResourceTypes", pClsid);
  449. return hr;
  450. } //*** UnregisterCluAdminAllResourceTypesExtension()
  451. /////////////////////////////////////////////////////////////////////////////
  452. //++
  453. //
  454. // UnregisterCluAdminAllNetworksExtension
  455. //
  456. // Routine Description:
  457. // Unregister with the cluster database a Cluster Administrator Extension
  458. // DLL that extends all networks.
  459. //
  460. // Arguments:
  461. // hCluster [IN] Handle to the cluster to modify.
  462. // pClsid [IN] Extension's CLSID.
  463. //
  464. // Return Value:
  465. // S_OK Extension unregistered successfully.
  466. // Win32 error code if another failure occurred.
  467. //
  468. //--
  469. /////////////////////////////////////////////////////////////////////////////
  470. STDAPI UnregisterCluAdminAllNetworksExtension(
  471. IN HCLUSTER hCluster,
  472. IN const CLSID * pClsid
  473. )
  474. {
  475. HRESULT hr;
  476. hr = UnregisterAnyCluAdminExtension(hCluster, L"Networks", pClsid);
  477. return hr;
  478. } //*** UnregisterCluAdminAllNetworksExtension()
  479. /////////////////////////////////////////////////////////////////////////////
  480. //++
  481. //
  482. // UnregisterCluAdminAllNetInterfacesExtension
  483. //
  484. // Routine Description:
  485. // Unregister with the cluster database a Cluster Administrator Extension
  486. // DLL that extends all network interfaces.
  487. //
  488. // Arguments:
  489. // hCluster [IN] Handle to the cluster to modify.
  490. // pClsid [IN] Extension's CLSID.
  491. //
  492. // Return Value:
  493. // S_OK Extension unregistered successfully.
  494. // Win32 error code if another failure occurred.
  495. //
  496. //--
  497. /////////////////////////////////////////////////////////////////////////////
  498. STDAPI UnregisterCluAdminAllNetInterfacesExtension(
  499. IN HCLUSTER hCluster,
  500. IN const CLSID * pClsid
  501. )
  502. {
  503. HRESULT hr;
  504. hr = UnregisterAnyCluAdminExtension(hCluster, L"NetInterfaces", pClsid);
  505. return hr;
  506. } //*** UnregisterCluAdminAllNetInterfacesExtension()
  507. /////////////////////////////////////////////////////////////////////////////
  508. //++
  509. //
  510. // UnregisterCluAdminResourceTypeExtension
  511. //
  512. // Routine Description:
  513. // Unregister with the cluster database a Cluster Administrator Extension
  514. // DLL that extends resources of a specific type, or the resource type
  515. // itself.
  516. //
  517. // Arguments:
  518. // hCluster [IN] Handle to the cluster to modify.
  519. // pwszResourceType [IN] Resource type name.
  520. // pClsid [IN] Extension's CLSID.
  521. //
  522. // Return Value:
  523. // S_OK Extension unregistered successfully.
  524. // Win32 error code if another failure occurred.
  525. //
  526. //--
  527. /////////////////////////////////////////////////////////////////////////////
  528. STDAPI UnregisterCluAdminResourceTypeExtension(
  529. IN HCLUSTER hCluster,
  530. IN LPCWSTR pwszResourceType,
  531. IN const CLSID * pClsid
  532. )
  533. {
  534. HRESULT hr;
  535. HKEY hkey;
  536. // Get the resource type registry key.
  537. hkey = GetClusterResourceTypeKey(hCluster, pwszResourceType, KEY_ALL_ACCESS);
  538. if (hkey == NULL)
  539. hr = GetLastError();
  540. else
  541. {
  542. // Unregister the extension.
  543. hr = UnregisterAnyCluAdminExtension(hkey, pClsid);
  544. ClusterRegCloseKey(hkey);
  545. } // else: GetClusterResourceTypeKey succeeded
  546. return hr;
  547. } //*** UnregisterCluAdminResourceTypeExtension()
  548. /////////////////////////////////////////////////////////////////////////////
  549. //++
  550. //
  551. // RegisterAnyCluAdminExtension
  552. //
  553. // Routine Description:
  554. // Register any Cluster Administrator Extension DLL with the cluster
  555. // database.
  556. //
  557. // Arguments:
  558. // hCluster [IN] Handle to the cluster to modify.
  559. // pwszKeyName [IN] Key name.
  560. // pClsid [IN] Extension's CLSID.
  561. //
  562. // Return Value:
  563. // S_OK Extension registered successfully.
  564. // Win32 error code if another failure occurred.
  565. //
  566. //--
  567. /////////////////////////////////////////////////////////////////////////////
  568. static HRESULT RegisterAnyCluAdminExtension(
  569. IN HCLUSTER hCluster,
  570. IN LPCWSTR pwszKeyName,
  571. IN const CLSID * pClsid
  572. )
  573. {
  574. HRESULT hr;
  575. HKEY hkeyCluster;
  576. HKEY hkey;
  577. // Get the cluster key.
  578. hkeyCluster = GetClusterKey(hCluster, KEY_ALL_ACCESS);
  579. if (hkeyCluster == NULL)
  580. hr = GetLastError();
  581. else
  582. {
  583. // Get the specified key.
  584. hr = ClusterRegOpenKey(hkeyCluster, pwszKeyName, KEY_ALL_ACCESS, &hkey);
  585. if (hr == ERROR_SUCCESS)
  586. {
  587. // Register the extension.
  588. hr = RegisterAnyCluAdminExtension(hkey, pClsid);
  589. ClusterRegCloseKey(hkey);
  590. } // else: GetClusterResourceTypeKey succeeded
  591. ClusterRegCloseKey(hkeyCluster);
  592. } // if: CLSID converted to a string successfully
  593. return hr;
  594. } //*** RegisterAnyCluAdminExtension()
  595. /////////////////////////////////////////////////////////////////////////////
  596. //++
  597. //
  598. // RegisterAnyCluAdminExtension
  599. //
  600. // Routine Description:
  601. // Register any Cluster Administrator Extension DLL with the cluster
  602. // database.
  603. //
  604. // Arguments:
  605. // hkey [IN] Cluster database key.
  606. // pClsid [IN] Extension's CLSID.
  607. //
  608. // Return Value:
  609. // S_OK Extension registered successfully.
  610. // Win32 error code if another failure occurred.
  611. //
  612. //--
  613. /////////////////////////////////////////////////////////////////////////////
  614. static HRESULT RegisterAnyCluAdminExtension(
  615. IN HKEY hkey,
  616. IN const CLSID * pClsid
  617. )
  618. {
  619. HRESULT hr;
  620. LPOLESTR pwszClsid;
  621. DWORD cbSize;
  622. DWORD cbNewSize;
  623. LPWSTR pwszValue;
  624. LPWSTR pwszNewValue;
  625. BOOL bAlreadyRegistered;
  626. // Convert the CLSID to a string.
  627. hr = StringFromCLSID(*pClsid, &pwszClsid);
  628. if (hr == S_OK)
  629. {
  630. // Read the current value.
  631. hr = ReadValue(hkey, REG_VALUE_ADMIN_EXTENSIONS, &pwszValue, &cbSize);
  632. if (hr == S_OK)
  633. {
  634. // Check to see if the extension has been registered yet.
  635. if (pwszValue == NULL)
  636. bAlreadyRegistered = FALSE;
  637. else
  638. {
  639. LPCWSTR pwszValueBuf = pwszValue;
  640. while (*pwszValueBuf != L'\0')
  641. {
  642. if (lstrcmpiW(pwszClsid, pwszValueBuf) == 0)
  643. break;
  644. pwszValueBuf += lstrlenW(pwszValueBuf) + 1;
  645. } // while: more strings in the extension list
  646. bAlreadyRegistered = (*pwszValueBuf != L'\0');
  647. } // else: extension value exists
  648. // Register the extension.
  649. if (!bAlreadyRegistered)
  650. {
  651. // Allocate a new buffer.
  652. cbNewSize = cbSize + (lstrlenW(pwszClsid) + 1) * sizeof(WCHAR);
  653. if (cbSize == 0) // Add size of final NULL if first entry.
  654. cbNewSize += sizeof(WCHAR);
  655. pwszNewValue = (LPWSTR) LocalAlloc(LMEM_FIXED, cbNewSize);
  656. if (pwszNewValue == NULL)
  657. hr = GetLastError();
  658. else
  659. {
  660. LPCWSTR pwszValueBuf = pwszValue;
  661. LPWSTR pwszNewValueBuf = pwszNewValue;
  662. DWORD cch;
  663. DWORD dwType;
  664. // Copy the existing extensions to the new buffer.
  665. if (pwszValue != NULL)
  666. {
  667. while (*pwszValueBuf != L'\0')
  668. {
  669. lstrcpyW(pwszNewValueBuf, pwszValueBuf);
  670. cch = lstrlenW(pwszValueBuf);
  671. pwszValueBuf += cch + 1;
  672. pwszNewValueBuf += cch + 1;
  673. } // while: more strings in the extension list
  674. } // if: previous value buffer existed
  675. // Add the new CLSID to the list.
  676. lstrcpyW(pwszNewValueBuf, pwszClsid);
  677. pwszNewValueBuf += lstrlenW(pwszClsid) + 1;
  678. *pwszNewValueBuf = L'\0';
  679. // Write the value to the cluster database.
  680. dwType = REG_MULTI_SZ;
  681. hr = ClusterRegSetValue(
  682. hkey,
  683. REG_VALUE_ADMIN_EXTENSIONS,
  684. dwType,
  685. (LPBYTE) pwszNewValue,
  686. cbNewSize
  687. );
  688. LocalFree(pwszNewValue);
  689. } // else: new buffer allocated successfully
  690. } // if: extension not registered yet
  691. LocalFree(pwszValue);
  692. } // if: value read successfully
  693. CoTaskMemFree(pwszClsid);
  694. } // if: CLSID converted to a string successfully
  695. return hr;
  696. } //*** RegisterAnyCluAdminExtension()
  697. /////////////////////////////////////////////////////////////////////////////
  698. //++
  699. //
  700. // UnregisterAnyCluAdminExtension
  701. //
  702. // Routine Description:
  703. // Unregister any Cluster Administrator Extension DLL with the cluster
  704. // database.
  705. //
  706. // Arguments:
  707. // hCluster [IN] Handle to the cluster to modify.
  708. // pwszKeyName [IN] Key name.
  709. // pClsid [IN] Extension's CLSID.
  710. //
  711. // Return Value:
  712. // S_OK Extension unregistered successfully.
  713. // Win32 error code if another failure occurred.
  714. //
  715. //--
  716. /////////////////////////////////////////////////////////////////////////////
  717. static HRESULT UnregisterAnyCluAdminExtension(
  718. IN HCLUSTER hCluster,
  719. IN LPCWSTR pwszKeyName,
  720. IN const CLSID * pClsid
  721. )
  722. {
  723. HRESULT hr;
  724. HKEY hkeyCluster;
  725. HKEY hkey;
  726. // Get the cluster key.
  727. hkeyCluster = GetClusterKey(hCluster, KEY_ALL_ACCESS);
  728. if (hkeyCluster == NULL)
  729. hr = GetLastError();
  730. else
  731. {
  732. // Get the specified key.
  733. hr = ClusterRegOpenKey(hkeyCluster, pwszKeyName, KEY_ALL_ACCESS, &hkey);
  734. if (hr == ERROR_SUCCESS)
  735. {
  736. // Unregister the extension.
  737. hr = UnregisterAnyCluAdminExtension(hkey, pClsid);
  738. ClusterRegCloseKey(hkey);
  739. } // else: GetClusterResourceTypeKey succeeded
  740. ClusterRegCloseKey(hkeyCluster);
  741. } // if: CLSID converted to a string successfully
  742. return hr;
  743. } //*** UnregisterAnyCluAdminExtension()
  744. /////////////////////////////////////////////////////////////////////////////
  745. //++
  746. //
  747. // UnregisterAnyCluAdminExtension
  748. //
  749. // Routine Description:
  750. // Unregister any Cluster Administrator Extension DLL with the cluster
  751. // database.
  752. //
  753. // Arguments:
  754. // hkey [IN] Cluster database key.
  755. // pClsid [IN] Extension's CLSID.
  756. //
  757. // Return Value:
  758. // S_OK Extension unregistered successfully.
  759. // Win32 error code if another failure occurred.
  760. //
  761. //--
  762. /////////////////////////////////////////////////////////////////////////////
  763. static HRESULT UnregisterAnyCluAdminExtension(
  764. IN HKEY hkey,
  765. IN const CLSID * pClsid
  766. )
  767. {
  768. HRESULT hr;
  769. LPOLESTR pwszClsid;
  770. DWORD cbSize;
  771. DWORD cbNewSize;
  772. LPWSTR pwszValue;
  773. LPWSTR pwszNewValue;
  774. BOOL bAlreadyUnregistered;
  775. // Convert the CLSID to a string.
  776. hr = StringFromCLSID(*pClsid, &pwszClsid);
  777. if (hr == S_OK)
  778. {
  779. // Read the current value.
  780. hr = ReadValue(hkey, REG_VALUE_ADMIN_EXTENSIONS, &pwszValue, &cbSize);
  781. if (hr == S_OK)
  782. {
  783. // Check to see if the extension has been unregistered yet.
  784. if (pwszValue == NULL)
  785. bAlreadyUnregistered = TRUE;
  786. else
  787. {
  788. LPCWSTR pwszValueBuf = pwszValue;
  789. while (*pwszValueBuf != L'\0')
  790. {
  791. if (lstrcmpiW(pwszClsid, pwszValueBuf) == 0)
  792. break;
  793. pwszValueBuf += lstrlenW(pwszValueBuf) + 1;
  794. } // while: more strings in the extension list
  795. bAlreadyUnregistered = (*pwszValueBuf == L'\0');
  796. } // else: extension value exists
  797. // Unregister the extension.
  798. if (!bAlreadyUnregistered)
  799. {
  800. // Allocate a new buffer.
  801. cbNewSize = cbSize - (lstrlenW(pwszClsid) + 1) * sizeof(WCHAR);
  802. if (cbNewSize == sizeof(WCHAR))
  803. cbNewSize = 0;
  804. pwszNewValue = (LPWSTR) LocalAlloc(LMEM_FIXED, cbNewSize);
  805. if (pwszNewValue == NULL)
  806. hr = GetLastError();
  807. else
  808. {
  809. LPCWSTR pwszValueBuf = pwszValue;
  810. LPWSTR pwszNewValueBuf = pwszNewValue;
  811. DWORD dwType;
  812. // Copy the existing extensions to the new buffer.
  813. if ((cbNewSize > 0) && (pwszValue != NULL))
  814. {
  815. while (*pwszValueBuf != L'\0')
  816. {
  817. if (lstrcmpiW(pwszClsid, pwszValueBuf) != 0)
  818. {
  819. lstrcpyW(pwszNewValueBuf, pwszValueBuf);
  820. pwszNewValueBuf += lstrlenW(pwszNewValueBuf) + 1;
  821. } // if: not CLSID being removed
  822. pwszValueBuf += lstrlenW(pwszValueBuf) + 1;
  823. } // while: more strings in the extension list
  824. *pwszNewValueBuf = L'\0';
  825. } // if: previous value buffer existed
  826. // Write the value to the cluster database.
  827. dwType = REG_MULTI_SZ;
  828. hr = ClusterRegSetValue(
  829. hkey,
  830. REG_VALUE_ADMIN_EXTENSIONS,
  831. dwType,
  832. (LPBYTE) pwszNewValue,
  833. cbNewSize
  834. );
  835. LocalFree(pwszNewValue);
  836. } // else: new buffer allocated successfully
  837. } // if: extension not unregistered yet
  838. LocalFree(pwszValue);
  839. } // if: value read successfully
  840. CoTaskMemFree(pwszClsid);
  841. } // if: CLSID converted to a string successfully
  842. return hr;
  843. } //*** UnregisterAnyCluAdminExtension()
  844. /////////////////////////////////////////////////////////////////////////////
  845. //++
  846. //
  847. // ReadValue
  848. //
  849. // Routine Description:
  850. // Reads a value from the cluster database.
  851. //
  852. // Arguments:
  853. // hkey [IN] Handle for the key to read from.
  854. // pwszValueName [IN] Name of value to read.
  855. // ppwszValue [OUT] Address of pointer in which to return data.
  856. // The string is allocated using LocalAlloc and must
  857. // be deallocated by the calling LocalFree.
  858. // pcbSize [OUT] Size in bytes of the allocated value buffer.
  859. //
  860. // Return Value:
  861. // Any return values from ClusterRegQueryValue or errors from new.
  862. //
  863. //--
  864. /////////////////////////////////////////////////////////////////////////////
  865. static DWORD ReadValue(
  866. IN HKEY hkey,
  867. IN LPCWSTR pwszValueName,
  868. OUT LPWSTR * ppwszValue,
  869. OUT DWORD * pcbSize
  870. )
  871. {
  872. DWORD dwStatus;
  873. DWORD cbSize;
  874. DWORD dwType;
  875. LPWSTR pwszValue;
  876. *ppwszValue = NULL;
  877. *pcbSize = 0;
  878. // Get the length of the value.
  879. dwStatus = ClusterRegQueryValue(
  880. hkey,
  881. pwszValueName,
  882. &dwType,
  883. NULL,
  884. &cbSize
  885. );
  886. if ( (dwStatus != ERROR_SUCCESS)
  887. && (dwStatus != ERROR_MORE_DATA))
  888. {
  889. if (dwStatus == ERROR_FILE_NOT_FOUND)
  890. dwStatus = ERROR_SUCCESS;
  891. return dwStatus;
  892. } // if: error occurred
  893. if (cbSize > 0)
  894. {
  895. // Allocate a value string.
  896. pwszValue = (LPWSTR) LocalAlloc(LMEM_FIXED, cbSize);
  897. if (pwszValue == NULL)
  898. {
  899. dwStatus = GetLastError();
  900. return dwStatus;
  901. } // if: error allocating memory
  902. // Read the the value.
  903. dwStatus = ClusterRegQueryValue(
  904. hkey,
  905. pwszValueName,
  906. &dwType,
  907. (LPBYTE) pwszValue,
  908. &cbSize
  909. );
  910. if (dwStatus != ERROR_SUCCESS)
  911. {
  912. LocalFree(pwszValue);
  913. pwszValue = NULL;
  914. cbSize = 0;
  915. } // if: error occurred
  916. *ppwszValue = pwszValue;
  917. *pcbSize = cbSize;
  918. } // if: value is not empty
  919. return dwStatus;
  920. } //*** ReadValue()