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.

1076 lines
32 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2002 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // RegExt.cpp
  7. //
  8. // Description:
  9. // Implementation of routines for extension registration.
  10. //
  11. // Author:
  12. // <name> (<e-mail name>) Mmmm DD, 2002
  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. // 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. {
  84. hr = GetLastError();
  85. } // if: error getting cluster key
  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. // 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. // 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. // 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. // 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. // 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. // 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"NetInterfaces", pClsid );
  260. return hr;
  261. } //*** RegisterCluAdminAllNetInterfacesExtension()
  262. /////////////////////////////////////////////////////////////////////////////
  263. //++
  264. //
  265. // RegisterCluAdminResourceTypeExtension
  266. //
  267. // 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. {
  295. hr = GetLastError();
  296. } // if: error getting resource type key
  297. else
  298. {
  299. // Register the extension.
  300. hr = RegisterAnyCluAdminExtension( hkey, pClsid );
  301. ClusterRegCloseKey( hkey );
  302. } // else: GetClusterResourceTypeKey succeeded
  303. return hr;
  304. } //*** RegisterCluAdminResourceTypeExtension()
  305. /////////////////////////////////////////////////////////////////////////////
  306. //++
  307. //
  308. // UnregisterCluAdminClusterExtension
  309. //
  310. // Description:
  311. // Unregister with the cluster database a Cluster Administrator Extension
  312. // DLL that extends the cluster object.
  313. //
  314. // Arguments:
  315. // hCluster [IN] Handle to the cluster to modify.
  316. // pClsid [IN] Extension's CLSID.
  317. //
  318. // Return Value:
  319. // S_OK Extension registered successfully.
  320. // Win32 error code if another failure occurred.
  321. //
  322. //--
  323. /////////////////////////////////////////////////////////////////////////////
  324. STDAPI UnregisterCluAdminClusterExtension(
  325. IN HCLUSTER hCluster,
  326. IN const CLSID * pClsid
  327. )
  328. {
  329. HRESULT hr;
  330. HKEY hkey;
  331. // Get the cluster registry key.
  332. hkey = GetClusterKey( hCluster, KEY_ALL_ACCESS );
  333. if ( hkey == NULL )
  334. {
  335. hr = GetLastError();
  336. } // if: error getting cluster key
  337. else
  338. {
  339. // Unregister the extension.
  340. hr = UnregisterAnyCluAdminExtension( hkey, pClsid );
  341. ClusterRegCloseKey( hkey );
  342. } // else: GetClusterKey succeeded
  343. return hr;
  344. } //*** UnregisterCluAdminClusterExtension()
  345. /////////////////////////////////////////////////////////////////////////////
  346. //++
  347. //
  348. // UnregisterCluAdminAllNodesExtension
  349. //
  350. // Description:
  351. // Unregister with the cluster database a Cluster Administrator Extension
  352. // DLL that extends all nodes.
  353. //
  354. // Arguments:
  355. // hCluster [IN] Handle to the cluster to modify.
  356. // pClsid [IN] Extension's CLSID.
  357. //
  358. // Return Value:
  359. // S_OK Extension unregistered successfully.
  360. // Win32 error code if another failure occurred.
  361. //
  362. //--
  363. /////////////////////////////////////////////////////////////////////////////
  364. STDAPI UnregisterCluAdminAllNodesExtension(
  365. IN HCLUSTER hCluster,
  366. IN const CLSID * pClsid
  367. )
  368. {
  369. HRESULT hr;
  370. hr = UnregisterAnyCluAdminExtension( hCluster, L"Nodes", pClsid );
  371. return hr;
  372. } //*** UnregisterCluAdminAllNodesExtension()
  373. /////////////////////////////////////////////////////////////////////////////
  374. //++
  375. //
  376. // UnregisterCluAdminAllGroupsExtension
  377. //
  378. // Description:
  379. // Unregister with the cluster database a Cluster Administrator Extension
  380. // DLL that extends all groups.
  381. //
  382. // Arguments:
  383. // hCluster [IN] Handle to the cluster to modify.
  384. // pClsid [IN] Extension's CLSID.
  385. //
  386. // Return Value:
  387. // S_OK Extension unregistered successfully.
  388. // Win32 error code if another failure occurred.
  389. //
  390. //--
  391. /////////////////////////////////////////////////////////////////////////////
  392. STDAPI UnregisterCluAdminAllGroupsExtension(
  393. IN HCLUSTER hCluster,
  394. IN const CLSID * pClsid
  395. )
  396. {
  397. HRESULT hr;
  398. hr = UnregisterAnyCluAdminExtension( hCluster, L"Groups", pClsid );
  399. return hr;
  400. } //*** UnregisterCluAdminAllGroupsExtension()
  401. /////////////////////////////////////////////////////////////////////////////
  402. //++
  403. //
  404. // UnregisterCluAdminAllResourcesExtension
  405. //
  406. // Description:
  407. // Unregister with the cluster database a Cluster Administrator Extension
  408. // DLL that extends all resources.
  409. //
  410. // Arguments:
  411. // hCluster [IN] Handle to the cluster to modify.
  412. // pClsid [IN] Extension's CLSID.
  413. //
  414. // Return Value:
  415. // S_OK Extension unregistered successfully.
  416. // Win32 error code if another failure occurred.
  417. //
  418. //--
  419. /////////////////////////////////////////////////////////////////////////////
  420. STDAPI UnregisterCluAdminAllResourcesExtension(
  421. IN HCLUSTER hCluster,
  422. IN const CLSID * pClsid
  423. )
  424. {
  425. HRESULT hr;
  426. hr = UnregisterAnyCluAdminExtension( hCluster, L"Resources", pClsid );
  427. return hr;
  428. } //*** UnregisterCluAdminAllResourcesExtension()
  429. /////////////////////////////////////////////////////////////////////////////
  430. //++
  431. //
  432. // UnregisterCluAdminAllResourceTypesExtension
  433. //
  434. // Description:
  435. // Unregister with the cluster database a Cluster Administrator Extension
  436. // DLL that extends all resource types.
  437. //
  438. // Arguments:
  439. // hCluster [IN] Handle to the cluster to modify.
  440. // pClsid [IN] Extension's CLSID.
  441. //
  442. // Return Value:
  443. // S_OK Extension unregistered successfully.
  444. // Win32 error code if another failure occurred.
  445. //
  446. //--
  447. /////////////////////////////////////////////////////////////////////////////
  448. STDAPI UnregisterCluAdminAllResourceTypesExtension(
  449. IN HCLUSTER hCluster,
  450. IN const CLSID * pClsid
  451. )
  452. {
  453. HRESULT hr;
  454. hr = UnregisterAnyCluAdminExtension( hCluster, L"ResourceTypes", pClsid );
  455. return hr;
  456. } //*** UnregisterCluAdminAllResourceTypesExtension()
  457. /////////////////////////////////////////////////////////////////////////////
  458. //++
  459. //
  460. // UnregisterCluAdminAllNetworksExtension
  461. //
  462. // Description:
  463. // Unregister with the cluster database a Cluster Administrator Extension
  464. // DLL that extends all networks.
  465. //
  466. // Arguments:
  467. // hCluster [IN] Handle to the cluster to modify.
  468. // pClsid [IN] Extension's CLSID.
  469. //
  470. // Return Value:
  471. // S_OK Extension unregistered successfully.
  472. // Win32 error code if another failure occurred.
  473. //
  474. //--
  475. /////////////////////////////////////////////////////////////////////////////
  476. STDAPI UnregisterCluAdminAllNetworksExtension(
  477. IN HCLUSTER hCluster,
  478. IN const CLSID * pClsid
  479. )
  480. {
  481. HRESULT hr;
  482. hr = UnregisterAnyCluAdminExtension( hCluster, L"Networks", pClsid );
  483. return hr;
  484. } //*** UnregisterCluAdminAllNetworksExtension()
  485. /////////////////////////////////////////////////////////////////////////////
  486. //++
  487. //
  488. // UnregisterCluAdminAllNetInterfacesExtension
  489. //
  490. // Description:
  491. // Unregister with the cluster database a Cluster Administrator Extension
  492. // DLL that extends all network interfaces.
  493. //
  494. // Arguments:
  495. // hCluster [IN] Handle to the cluster to modify.
  496. // pClsid [IN] Extension's CLSID.
  497. //
  498. // Return Value:
  499. // S_OK Extension unregistered successfully.
  500. // Win32 error code if another failure occurred.
  501. //
  502. //--
  503. /////////////////////////////////////////////////////////////////////////////
  504. STDAPI UnregisterCluAdminAllNetInterfacesExtension(
  505. IN HCLUSTER hCluster,
  506. IN const CLSID * pClsid
  507. )
  508. {
  509. HRESULT hr;
  510. hr = UnregisterAnyCluAdminExtension( hCluster, L"NetInterfaces", pClsid );
  511. return hr;
  512. } //*** UnregisterCluAdminAllNetInterfacesExtension()
  513. /////////////////////////////////////////////////////////////////////////////
  514. //++
  515. //
  516. // UnregisterCluAdminResourceTypeExtension
  517. //
  518. // Description:
  519. // Unregister with the cluster database a Cluster Administrator Extension
  520. // DLL that extends resources of a specific type, or the resource type
  521. // itself.
  522. //
  523. // Arguments:
  524. // hCluster [IN] Handle to the cluster to modify.
  525. // pwszResourceType [IN] Resource type name.
  526. // pClsid [IN] Extension's CLSID.
  527. //
  528. // Return Value:
  529. // S_OK Extension unregistered successfully.
  530. // Win32 error code if another failure occurred.
  531. //
  532. //--
  533. /////////////////////////////////////////////////////////////////////////////
  534. STDAPI UnregisterCluAdminResourceTypeExtension(
  535. IN HCLUSTER hCluster,
  536. IN LPCWSTR pwszResourceType,
  537. IN const CLSID * pClsid
  538. )
  539. {
  540. HRESULT hr;
  541. HKEY hkey;
  542. // Get the resource type registry key.
  543. hkey = GetClusterResourceTypeKey( hCluster, pwszResourceType, KEY_ALL_ACCESS );
  544. if ( hkey == NULL )
  545. {
  546. hr = GetLastError();
  547. } // if: error getting resource type key
  548. else
  549. {
  550. // Unregister the extension.
  551. hr = UnregisterAnyCluAdminExtension( hkey, pClsid );
  552. ClusterRegCloseKey( hkey );
  553. } // else: GetClusterResourceTypeKey succeeded
  554. return hr;
  555. } //*** UnregisterCluAdminResourceTypeExtension()
  556. /////////////////////////////////////////////////////////////////////////////
  557. //++
  558. //
  559. // RegisterAnyCluAdminExtension
  560. //
  561. // Description:
  562. // Register any Cluster Administrator Extension DLL with the cluster
  563. // database.
  564. //
  565. // Arguments:
  566. // hCluster [IN] Handle to the cluster to modify.
  567. // pwszKeyName [IN] Key name.
  568. // pClsid [IN] Extension's CLSID.
  569. //
  570. // Return Value:
  571. // S_OK Extension registered successfully.
  572. // Win32 error code if another failure occurred.
  573. //
  574. //--
  575. /////////////////////////////////////////////////////////////////////////////
  576. static HRESULT RegisterAnyCluAdminExtension(
  577. IN HCLUSTER hCluster,
  578. IN LPCWSTR pwszKeyName,
  579. IN const CLSID * pClsid
  580. )
  581. {
  582. HRESULT hr;
  583. HKEY hkeyCluster;
  584. HKEY hkey;
  585. // Get the cluster key.
  586. hkeyCluster = GetClusterKey( hCluster, KEY_ALL_ACCESS );
  587. if ( hkeyCluster == NULL )
  588. {
  589. hr = GetLastError();
  590. } // if: error getting cluster key
  591. else
  592. {
  593. // Get the specified key.
  594. hr = ClusterRegOpenKey( hkeyCluster, pwszKeyName, KEY_ALL_ACCESS, &hkey );
  595. if ( hr == ERROR_SUCCESS )
  596. {
  597. // Register the extension.
  598. hr = RegisterAnyCluAdminExtension( hkey, pClsid );
  599. ClusterRegCloseKey( hkey );
  600. } // else: GetClusterResourceTypeKey succeeded
  601. ClusterRegCloseKey( hkeyCluster );
  602. } // if: cluster key retrieved successfully
  603. return hr;
  604. } //*** RegisterAnyCluAdminExtension()
  605. /////////////////////////////////////////////////////////////////////////////
  606. //++
  607. //
  608. // RegisterAnyCluAdminExtension
  609. //
  610. // Description:
  611. // Register any Cluster Administrator Extension DLL with the cluster
  612. // database.
  613. //
  614. // Arguments:
  615. // hkey [IN] Cluster database key.
  616. // pClsid [IN] Extension's CLSID.
  617. //
  618. // Return Value:
  619. // S_OK Extension registered successfully.
  620. // Win32 error code if another failure occurred.
  621. //
  622. //--
  623. /////////////////////////////////////////////////////////////////////////////
  624. static HRESULT RegisterAnyCluAdminExtension(
  625. IN HKEY hkey,
  626. IN const CLSID * pClsid
  627. )
  628. {
  629. HRESULT hr;
  630. LPOLESTR pwszClsid;
  631. DWORD cbSize;
  632. DWORD cbNewSize;
  633. LPWSTR pwszValue;
  634. LPWSTR pwszNewValue;
  635. BOOL bAlreadyRegistered;
  636. // Convert the CLSID to a string.
  637. hr = StringFromCLSID( *pClsid, &pwszClsid );
  638. if ( hr == S_OK )
  639. {
  640. // Read the current value.
  641. hr = ReadValue( hkey, REG_VALUE_ADMIN_EXTENSIONS, &pwszValue, &cbSize );
  642. if (hr == S_OK)
  643. {
  644. // Check to see if the extension has been registered yet.
  645. if ( pwszValue == NULL )
  646. {
  647. bAlreadyRegistered = FALSE;
  648. } // if: empty value found
  649. else
  650. {
  651. LPCWSTR pwszValueBuf = pwszValue;
  652. while ( *pwszValueBuf != L'\0' )
  653. {
  654. if ( lstrcmpiW( pwszClsid, pwszValueBuf ) == 0 )
  655. {
  656. break;
  657. } // if: CLSID for this extension already in list
  658. pwszValueBuf += lstrlenW(pwszValueBuf) + 1;
  659. } // while: more strings in the extension list
  660. bAlreadyRegistered = (*pwszValueBuf != L'\0');
  661. } // else: extension value exists
  662. // Register the extension.
  663. if ( ! bAlreadyRegistered )
  664. {
  665. // Allocate a new buffer.
  666. cbNewSize = cbSize + (lstrlenW( pwszClsid ) + 1) * sizeof( WCHAR );
  667. if ( cbSize == 0 ) // Add size of final NULL if first entry.
  668. {
  669. cbNewSize += sizeof( WCHAR );
  670. } // if: no previous value
  671. pwszNewValue = reinterpret_cast< LPWSTR >( LocalAlloc( LMEM_FIXED, cbNewSize ) );
  672. if ( pwszNewValue == NULL )
  673. {
  674. hr = GetLastError();
  675. } // if: error allocating memory
  676. else
  677. {
  678. LPCWSTR pwszValueBuf = pwszValue;
  679. LPWSTR pwszNewValueBuf = pwszNewValue;
  680. DWORD cch;
  681. DWORD dwType;
  682. // Copy the existing extensions to the new buffer.
  683. if ( pwszValue != NULL)
  684. {
  685. while ( *pwszValueBuf != L'\0' )
  686. {
  687. lstrcpyW( pwszNewValueBuf, pwszValueBuf );
  688. cch = lstrlenW( pwszValueBuf );
  689. pwszValueBuf += cch + 1;
  690. pwszNewValueBuf += cch + 1;
  691. } // while: more strings in the extension list
  692. } // if: previous value buffer existed
  693. // Add the new CLSID to the list.
  694. lstrcpyW( pwszNewValueBuf, pwszClsid );
  695. pwszNewValueBuf += lstrlenW( pwszClsid ) + 1;
  696. *pwszNewValueBuf = L'\0';
  697. // Write the value to the cluster database.
  698. dwType = REG_MULTI_SZ;
  699. hr = ClusterRegSetValue(
  700. hkey,
  701. REG_VALUE_ADMIN_EXTENSIONS,
  702. dwType,
  703. reinterpret_cast< LPBYTE >( pwszNewValue ),
  704. cbNewSize
  705. );
  706. LocalFree( pwszNewValue );
  707. } // else: new buffer allocated successfully
  708. } // if: extension not registered yet
  709. LocalFree( pwszValue );
  710. } // if: value read successfully
  711. CoTaskMemFree( pwszClsid );
  712. } // if: CLSID converted to a string successfully
  713. return hr;
  714. } //*** RegisterAnyCluAdminExtension()
  715. /////////////////////////////////////////////////////////////////////////////
  716. //++
  717. //
  718. // UnregisterAnyCluAdminExtension
  719. //
  720. // Description:
  721. // Unregister any Cluster Administrator Extension DLL with the cluster
  722. // database.
  723. //
  724. // Arguments:
  725. // hCluster [IN] Handle to the cluster to modify.
  726. // pwszKeyName [IN] Key name.
  727. // pClsid [IN] Extension's CLSID.
  728. //
  729. // Return Value:
  730. // S_OK Extension unregistered successfully.
  731. // Win32 error code if another failure occurred.
  732. //
  733. //--
  734. /////////////////////////////////////////////////////////////////////////////
  735. static HRESULT UnregisterAnyCluAdminExtension(
  736. IN HCLUSTER hCluster,
  737. IN LPCWSTR pwszKeyName,
  738. IN const CLSID * pClsid
  739. )
  740. {
  741. HRESULT hr;
  742. HKEY hkeyCluster;
  743. HKEY hkey;
  744. // Get the cluster key.
  745. hkeyCluster = GetClusterKey( hCluster, KEY_ALL_ACCESS );
  746. if ( hkeyCluster == NULL )
  747. {
  748. hr = GetLastError();
  749. } // if: error getting cluster key
  750. else
  751. {
  752. // Get the specified key.
  753. hr = ClusterRegOpenKey( hkeyCluster, pwszKeyName, KEY_ALL_ACCESS, &hkey );
  754. if ( hr == ERROR_SUCCESS )
  755. {
  756. // Unregister the extension.
  757. hr = UnregisterAnyCluAdminExtension( hkey, pClsid );
  758. ClusterRegCloseKey( hkey );
  759. } // else: GetClusterResourceTypeKey succeeded
  760. ClusterRegCloseKey( hkeyCluster );
  761. } // if: cluster key retrieved successfully
  762. return hr;
  763. } //*** UnregisterAnyCluAdminExtension()
  764. /////////////////////////////////////////////////////////////////////////////
  765. //++
  766. //
  767. // UnregisterAnyCluAdminExtension
  768. //
  769. // Description:
  770. // Unregister any Cluster Administrator Extension DLL with the cluster
  771. // database.
  772. //
  773. // Arguments:
  774. // hkey [IN] Cluster database key.
  775. // pClsid [IN] Extension's CLSID.
  776. //
  777. // Return Value:
  778. // S_OK Extension unregistered successfully.
  779. // Win32 error code if another failure occurred.
  780. //
  781. //--
  782. /////////////////////////////////////////////////////////////////////////////
  783. static HRESULT UnregisterAnyCluAdminExtension(
  784. IN HKEY hkey,
  785. IN const CLSID * pClsid
  786. )
  787. {
  788. HRESULT hr;
  789. LPOLESTR pwszClsid;
  790. DWORD cbSize;
  791. DWORD cbNewSize;
  792. LPWSTR pwszValue;
  793. LPWSTR pwszNewValue;
  794. BOOL bAlreadyUnregistered;
  795. // Convert the CLSID to a string.
  796. hr = StringFromCLSID( *pClsid, &pwszClsid );
  797. if ( hr == S_OK )
  798. {
  799. // Read the current value.
  800. hr = ReadValue( hkey, REG_VALUE_ADMIN_EXTENSIONS, &pwszValue, &cbSize );
  801. if ( hr == S_OK )
  802. {
  803. // Check to see if the extension has been unregistered yet.
  804. if ( pwszValue == NULL )
  805. {
  806. bAlreadyUnregistered = TRUE;
  807. } // if: empty value found
  808. else
  809. {
  810. LPCWSTR pwszValueBuf = pwszValue;
  811. while ( *pwszValueBuf != L'\0' )
  812. {
  813. if ( lstrcmpiW( pwszClsid, pwszValueBuf ) == 0 )
  814. {
  815. break;
  816. } // if: CLSID for this extension found in list
  817. pwszValueBuf += lstrlenW( pwszValueBuf ) + 1;
  818. } // while: more strings in the extension list
  819. bAlreadyUnregistered = (*pwszValueBuf == L'\0');
  820. } // else: extension value exists
  821. // Unregister the extension.
  822. if ( ! bAlreadyUnregistered )
  823. {
  824. // Allocate a new buffer.
  825. cbNewSize = cbSize - (lstrlenW( pwszClsid ) + 1) * sizeof( WCHAR );
  826. if ( cbNewSize == sizeof( WCHAR ) )
  827. {
  828. cbNewSize = 0;
  829. } // if: no previous value
  830. pwszNewValue = reinterpret_cast< LPWSTR >( LocalAlloc( LMEM_FIXED, cbNewSize ) );
  831. if ( pwszNewValue == NULL )
  832. {
  833. hr = GetLastError();
  834. } // if: error allocating memory
  835. else
  836. {
  837. LPCWSTR pwszValueBuf = pwszValue;
  838. LPWSTR pwszNewValueBuf = pwszNewValue;
  839. DWORD dwType;
  840. // Copy the existing extensions to the new buffer.
  841. if ( (cbNewSize > 0) && (pwszValue != NULL) )
  842. {
  843. while ( *pwszValueBuf != L'\0' )
  844. {
  845. if ( lstrcmpiW( pwszClsid, pwszValueBuf ) != 0 )
  846. {
  847. lstrcpyW( pwszNewValueBuf, pwszValueBuf );
  848. pwszNewValueBuf += lstrlenW( pwszNewValueBuf ) + 1;
  849. } // if: not CLSID being removed
  850. pwszValueBuf += lstrlenW( pwszValueBuf ) + 1;
  851. } // while: more strings in the extension list
  852. *pwszNewValueBuf = L'\0';
  853. } // if: previous value buffer existed
  854. // Write the value to the cluster database.
  855. dwType = REG_MULTI_SZ;
  856. hr = ClusterRegSetValue(
  857. hkey,
  858. REG_VALUE_ADMIN_EXTENSIONS,
  859. dwType,
  860. reinterpret_cast< LPBYTE >( pwszNewValue ),
  861. cbNewSize
  862. );
  863. LocalFree( pwszNewValue );
  864. } // else: new buffer allocated successfully
  865. } // if: extension not unregistered yet
  866. LocalFree( pwszValue );
  867. } // if: value read successfully
  868. CoTaskMemFree( pwszClsid );
  869. } // if: CLSID converted to a string successfully
  870. return hr;
  871. } //*** UnregisterAnyCluAdminExtension()
  872. /////////////////////////////////////////////////////////////////////////////
  873. //++
  874. //
  875. // ReadValue
  876. //
  877. // Description:
  878. // Reads a value from the cluster database.
  879. //
  880. // Arguments:
  881. // hkey [IN]
  882. // Handle for the key to read from.
  883. //
  884. // pwszValueName [IN]
  885. // Name of value to read.
  886. //
  887. // ppwszValue [OUT]
  888. // Address of pointer in which to return data. The string is
  889. // allocated using LocalAlloc and must be deallocated by the calling
  890. // LocalFree.
  891. //
  892. // pcbSize [OUT]
  893. // Size in bytes of the allocated value buffer.
  894. //
  895. // Return Value:
  896. // Any return values from ClusterRegQueryValue or errors from new.
  897. //
  898. //--
  899. /////////////////////////////////////////////////////////////////////////////
  900. static DWORD ReadValue(
  901. IN HKEY hkey,
  902. IN LPCWSTR pwszValueName,
  903. OUT LPWSTR * ppwszValue,
  904. OUT DWORD * pcbSize
  905. )
  906. {
  907. DWORD dwStatus;
  908. DWORD cbSize;
  909. DWORD dwType;
  910. LPWSTR pwszValue;
  911. *ppwszValue = NULL;
  912. *pcbSize = 0;
  913. // Get the length of the value.
  914. dwStatus = ClusterRegQueryValue(
  915. hkey,
  916. pwszValueName,
  917. &dwType,
  918. NULL,
  919. &cbSize
  920. );
  921. if ( (dwStatus != ERROR_SUCCESS)
  922. && (dwStatus != ERROR_MORE_DATA) )
  923. {
  924. if ( dwStatus == ERROR_FILE_NOT_FOUND )
  925. {
  926. dwStatus = ERROR_SUCCESS;
  927. } // if: value not found
  928. return dwStatus;
  929. } // if: error occurred
  930. if ( cbSize > 0 )
  931. {
  932. // Allocate a value string.
  933. pwszValue = reinterpret_cast< LPWSTR >( LocalAlloc( LMEM_FIXED, cbSize ) );
  934. if ( pwszValue == NULL )
  935. {
  936. dwStatus = GetLastError();
  937. return dwStatus;
  938. } // if: error allocating memory
  939. // Read the the value.
  940. dwStatus = ClusterRegQueryValue(
  941. hkey,
  942. pwszValueName,
  943. &dwType,
  944. reinterpret_cast< LPBYTE >( pwszValue ),
  945. &cbSize
  946. );
  947. if ( dwStatus != ERROR_SUCCESS )
  948. {
  949. LocalFree( pwszValue );
  950. pwszValue = NULL;
  951. cbSize = 0;
  952. } // if: error occurred
  953. *ppwszValue = pwszValue;
  954. *pcbSize = cbSize;
  955. } // if: value is not empty
  956. return dwStatus;
  957. } //*** ReadValue()