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.

1122 lines
34 KiB

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