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.

902 lines
23 KiB

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