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.

1111 lines
32 KiB

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