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.

1677 lines
48 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: N C R E G . C P P
  7. //
  8. // Contents: Common routines for dealing with the registry.
  9. //
  10. // Notes:
  11. //
  12. // Author: danielwe 24 Mar 1997
  13. //
  14. //----------------------------------------------------------------------------
  15. #include <pch.h>
  16. #pragma hdrstop
  17. #include "ncdebug.h"
  18. #include "ncreg.h"
  19. #include "ncstring.h"
  20. #include "ncperms.h"
  21. extern const WCHAR c_szAdapters[];
  22. extern const WCHAR c_szBackslash[];
  23. extern const WCHAR c_szParameters[];
  24. extern const WCHAR c_szRegKeyServices[];
  25. //+---------------------------------------------------------------------------
  26. //
  27. // Function: HrRegAddStringToMultiSz
  28. //
  29. // Purpose: Add a string into a REG_MULTI_SZ registry value
  30. //
  31. // Arguments:
  32. // pszAddString [in] The string to add to the multi-sz
  33. // hkeyRoot [in] An open registry key, or one of the
  34. // predefined hkey values (HKEY_LOCAL_MACHINE,
  35. // for instance)
  36. // pszKeySubPath [in] Name of the subkey to open.
  37. // pszValueName [in] Name of the registry value that we're going to
  38. // modify.
  39. // dwFlags [in] Can contain one or more of the following
  40. // values:
  41. //
  42. // STRING_FLAG_ALLOW_DUPLICATES
  43. // Don't remove duplicate values when adding
  44. // the string to the list. Default is to
  45. // remove all other instance of this string.
  46. // STRING_FLAG_ENSURE_AT_FRONT
  47. // Ensure the string is the first element of
  48. // the list. If the string is present and
  49. // duplicates aren't allowed, move the
  50. // string to the end.
  51. // STRING_FLAG_ENSURE_AT_END
  52. // Ensure the string is the last
  53. // element of the list. This can not be used
  54. // with STRING_FLAG_ENSURE_AT_FRONT. If the
  55. // string is present and duplicates aren't
  56. // allowed, move the string to the end.
  57. // STRING_FLAG_ENSURE_AT_INDEX
  58. // Ensure that the string is at dwStringIndex
  59. // in the multi-sz. If the index specified
  60. // is greater than the number of strings
  61. // in the multi-sz, the string will be
  62. // placed at the end.
  63. // STRING_FLAG_DONT_MODIFY_IF_PRESENT
  64. // If the string already exists in the
  65. // multi-sz then no modication will take
  66. // place. Note: This takes precedent
  67. // over the presence/non-presence of the
  68. // STRING_FLAG_ALLOW_DUPLICATES flag.
  69. // i.e nothing will be added or removed
  70. // if this flag is set and the string was
  71. // present in the multi-sz
  72. // dwIndex [in] If STRING_FLAG_ENSURE_AT_INDEX is specified,
  73. // this is the index for the string position.
  74. // Otherwise, this value is ignored.
  75. //
  76. // Returns: S_OK or an HRESULT_FROM_WIN32 error code.
  77. //
  78. // Author: jeffspr 27 Mar 1997
  79. //
  80. HRESULT
  81. HrRegAddStringToMultiSz (
  82. IN PCWSTR pszAddString,
  83. IN HKEY hkeyRoot,
  84. IN PCWSTR pszKeySubPath,
  85. IN PCWSTR pszValueName,
  86. IN DWORD dwFlags,
  87. IN DWORD dwIndex)
  88. {
  89. HRESULT hr = S_OK;
  90. DWORD dwRegType = 0; // Should be REG_MULTI_SZ
  91. HKEY hkeyOpen = NULL; // Return value from RegCreateKeyEx
  92. HKEY hkeyUse = NULL; // The key value that we'll actually use
  93. LPBYTE pbOrderOld = NULL; // Return buffer for order reg value
  94. LPBYTE pbOrderNew = NULL; // Build buffer for order swap
  95. // Check for valid parameters
  96. if (!pszAddString || !hkeyRoot || !pszValueName)
  97. {
  98. Assert(pszAddString);
  99. Assert(hkeyRoot);
  100. Assert(pszValueName);
  101. hr = E_INVALIDARG;
  102. goto Exit;
  103. }
  104. // Check to make sure that no "remove" flags are being used, and that
  105. // mutually exclusive flags aren't being used together
  106. //
  107. if ((dwFlags & STRING_FLAG_REMOVE_SINGLE) ||
  108. (dwFlags & STRING_FLAG_REMOVE_ALL) ||
  109. ((dwFlags & STRING_FLAG_ENSURE_AT_FRONT) &&
  110. (dwFlags & STRING_FLAG_ENSURE_AT_END)))
  111. {
  112. AssertSz(FALSE, "Invalid flags in HrRegAddStringToMultiSz");
  113. hr = E_INVALIDARG;
  114. goto Exit;
  115. }
  116. // If the user passed in a subkey string, then we should attempt to open
  117. // the subkey of the passed in root, else we'll just use the
  118. // pre-opened hkeyRoot
  119. //
  120. if (pszKeySubPath)
  121. {
  122. // Open the key, creating if necessary
  123. //
  124. hr = HrRegCreateKeyEx (
  125. hkeyRoot, // Base hive
  126. pszKeySubPath, // Our reg path
  127. 0, // dwOptions
  128. KEY_QUERY_VALUE | KEY_SET_VALUE, // samDesired
  129. NULL, // lpSecurityAttributes
  130. &hkeyOpen, // Our return hkey.
  131. NULL);
  132. if (FAILED(hr))
  133. {
  134. goto Exit;
  135. }
  136. hkeyUse = hkeyOpen;
  137. }
  138. else
  139. {
  140. // Use the passed in key for the Query.
  141. //
  142. hkeyUse = hkeyRoot;
  143. }
  144. // Retrieve the existing REG_MULTI_SZ
  145. //
  146. hr = HrRegQueryValueWithAlloc (
  147. hkeyUse,
  148. pszValueName,
  149. &dwRegType,
  150. &pbOrderOld,
  151. NULL);
  152. if (FAILED(hr))
  153. {
  154. if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
  155. {
  156. // This is OK. It just means that the value was missing, and we
  157. // should continue on, and create the value ourselves.
  158. hr = S_OK;
  159. }
  160. else
  161. {
  162. // Since there's an error that we didn't expect, drop out,
  163. // returning this error to the caller.
  164. //
  165. goto Exit;
  166. }
  167. }
  168. else
  169. {
  170. // If we did retrieve a value, then check to make sure that we're
  171. // dealing with a MULTI_SZ
  172. //
  173. if (dwRegType != REG_MULTI_SZ)
  174. {
  175. hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATATYPE);
  176. goto Exit;
  177. }
  178. }
  179. BOOL fChanged;
  180. hr = HrAddSzToMultiSz (pszAddString, (PCWSTR)pbOrderOld,
  181. dwFlags, dwIndex, (PWSTR*)&pbOrderNew, &fChanged);
  182. if ((S_OK == hr) && fChanged)
  183. {
  184. DWORD cbNew = CbOfMultiSzAndTermSafe ((PWSTR)pbOrderNew);
  185. // Save our string back into the registry
  186. //
  187. hr = HrRegSetValueEx (
  188. hkeyUse,
  189. pszValueName,
  190. REG_MULTI_SZ,
  191. (const BYTE *)pbOrderNew,
  192. cbNew);
  193. }
  194. Exit:
  195. // Close the key, if opened
  196. //
  197. RegSafeCloseKey (hkeyOpen);
  198. // Clean up the registry buffers
  199. //
  200. MemFree (pbOrderOld);
  201. MemFree (pbOrderNew);
  202. TraceError ("HrRegAddStringToMultiSz", hr);
  203. return hr;
  204. }
  205. //+---------------------------------------------------------------------------
  206. //
  207. // Function: HrRegAddStringToSz
  208. //
  209. // Purpose: Add a string into a REG_MULTI_SZ registry value
  210. //
  211. // Arguments:
  212. // pszAddString [in] The string to add to the multi-sz
  213. // hkeyRoot [in] An open registry key, or one of the
  214. // predefined hkey values (HKEY_LOCAL_MACHINE,
  215. // for instance)
  216. // pszKeySubPath [in] Name of the subkey to open.
  217. // pszValueName [in] Name of the registry value that we're going to
  218. // modify.
  219. // chDelimiter [in] The character to be used to delimit the
  220. // values. Most multi-valued REG_SZ strings are
  221. // delimited with either ',' or ' '. This will
  222. // be used to delimit the value that we add,
  223. // as well.
  224. // dwFlags [in] Can contain one or more of the following
  225. // values:
  226. //
  227. // STRING_FLAG_ALLOW_DUPLICATES
  228. // Don't remove duplicate values when adding
  229. // the string to the list. Default is to
  230. // remove all other instance of this string.
  231. // STRING_FLAG_ENSURE_AT_FRONT
  232. // Insert the string as the first element of
  233. // the list.
  234. // STRING_FLAG_ENSURE_AT_END
  235. // Insert the string as the last
  236. // element of the list. This can not be used
  237. // with STRING_FLAG_ENSURE_AT_FRONT.
  238. // STRING_FLAG_ENSURE_AT_INDEX
  239. // Ensure that the string is at dwStringIndex
  240. // in the sz. If the index specified
  241. // is greater than the number of strings
  242. // in the sz, the string will be
  243. // placed at the end.
  244. // dwStringIndex [in] If STRING_FLAG_ENSURE_AT_INDEX is specified,
  245. // this is the index for the string position.
  246. // Otherwise, this value is ignored.
  247. //
  248. // Returns: S_OK or an HRESULT_FROM_WIN32 error code.
  249. //
  250. // Author: jeffspr 27 Mar 1997
  251. //
  252. //
  253. // Note:
  254. // Might want to allow for the removal of leading/trailing spaces
  255. //
  256. HRESULT
  257. HrRegAddStringToSz (
  258. IN PCWSTR pszAddString,
  259. IN HKEY hkeyRoot,
  260. IN PCWSTR pszKeySubPath,
  261. IN PCWSTR pszValueName,
  262. IN WCHAR chDelimiter,
  263. IN DWORD dwFlags,
  264. IN DWORD dwStringIndex)
  265. {
  266. HRESULT hr = S_OK;
  267. DWORD dwRegType = 0; // Should be REG_MULTI_SZ
  268. HKEY hkeyOpen = NULL; // Open key to open
  269. PWSTR pszOrderOld = NULL; // Return buffer for order reg value
  270. PWSTR pszOrderNew = NULL; // Build buffer for order swap
  271. // Check for all of the required args
  272. //
  273. if (!pszAddString || !hkeyRoot || !pszValueName)
  274. {
  275. Assert(pszAddString);
  276. Assert(hkeyRoot);
  277. Assert(pszValueName);
  278. hr = E_INVALIDARG;
  279. goto Exit;
  280. }
  281. // Check to make sure that no "remove" flags are being used, and that
  282. // mutually exclusive flags aren't being used together
  283. //
  284. if ((dwFlags & STRING_FLAG_REMOVE_SINGLE) ||
  285. (dwFlags & STRING_FLAG_REMOVE_ALL))
  286. {
  287. AssertSz(FALSE, "Invalid flags in HrRegAddStringToSz");
  288. hr = E_INVALIDARG;
  289. goto Exit;
  290. }
  291. // Open the key, creating if necessary
  292. //
  293. hr = HrRegCreateKeyEx(
  294. hkeyRoot, // Base hive
  295. pszKeySubPath, // Our reg path
  296. 0, // dwOptions
  297. KEY_QUERY_VALUE | KEY_SET_VALUE, // samDesired
  298. NULL, // lpSecurityAttributes
  299. &hkeyOpen, // Our return hkey.
  300. NULL);
  301. if (FAILED(hr))
  302. {
  303. goto Exit;
  304. }
  305. // Retrieve the existing REG_SZ
  306. //
  307. hr = HrRegQueryValueWithAlloc(
  308. hkeyOpen,
  309. pszValueName,
  310. &dwRegType,
  311. (LPBYTE *) &pszOrderOld,
  312. NULL);
  313. if (FAILED(hr))
  314. {
  315. if (hr == HRESULT_FROM_WIN32 (ERROR_FILE_NOT_FOUND))
  316. {
  317. // This is OK. It just means that the value is missing. We
  318. // can handle this.
  319. hr = S_OK;
  320. }
  321. else
  322. {
  323. goto Exit;
  324. }
  325. }
  326. else
  327. {
  328. // If we did retrieve a value, then check to make sure that we're
  329. // dealing with a MULTI_SZ
  330. //
  331. if (dwRegType != REG_SZ)
  332. {
  333. hr = HRESULT_FROM_WIN32 (ERROR_INVALID_DATATYPE);
  334. goto Exit;
  335. }
  336. }
  337. hr = HrAddStringToDelimitedSz(pszAddString, pszOrderOld, chDelimiter,
  338. dwFlags, dwStringIndex, &pszOrderNew);
  339. if (S_OK == hr)
  340. {
  341. // Save our string back into the registry
  342. //
  343. hr = HrRegSetSz(hkeyOpen, pszValueName, pszOrderNew);
  344. if (FAILED(hr))
  345. {
  346. goto Exit;
  347. }
  348. }
  349. Exit:
  350. // Close the key, if open
  351. //
  352. RegSafeCloseKey (hkeyOpen);
  353. // Clean up the registry buffers
  354. //
  355. MemFree (pszOrderOld);
  356. MemFree (pszOrderNew);
  357. TraceError ("HrRegAddStringToSz", hr);
  358. return hr;
  359. }
  360. //+---------------------------------------------------------------------------
  361. //
  362. // Function: HrRegRemoveStringFromSz
  363. //
  364. // Purpose: Removes a string from a REG_SZ registry value
  365. //
  366. // Arguments:
  367. // pszRemoveString [in] The string to be removed from the multi-sz
  368. // hkeyRoot [in] An open registry key, or one of the
  369. // predefined hkey values (HKEY_LOCAL_MACHINE,
  370. // for instance)
  371. // pszKeySubPath [in] Name of the subkey to open.
  372. // pszValueName [in] Name of the registry value that we're going to
  373. // modify.
  374. // chDelimiter [in] The character to be used to delimit the
  375. // values. Most multi-valued REG_SZ strings are
  376. // delimited with either ',' or ' '.
  377. // dwFlags [in] Can contain one or more of the following
  378. // values:
  379. //
  380. // STRING_FLAG_REMOVE_SINGLE
  381. // Don't remove more than one value, if
  382. // multiple are present.
  383. // STRING_FLAG_REMOVE_ALL
  384. // If multiple matching values are present,
  385. // remove them all.
  386. //
  387. // Returns: S_OK or an HRESULT_FROM_WIN32 error code.
  388. //
  389. // Author: jeffspr 27 Mar 1997
  390. //
  391. //
  392. // Note:
  393. // Might want to allow for the removal of leading/trailing spaces
  394. //
  395. HRESULT
  396. HrRegRemoveStringFromSz (
  397. IN PCWSTR pszRemoveString,
  398. IN HKEY hkeyRoot,
  399. IN PCWSTR pszKeySubPath,
  400. IN PCWSTR pszValueName,
  401. IN WCHAR chDelimiter,
  402. IN DWORD dwFlags )
  403. {
  404. HRESULT hr = S_OK;
  405. DWORD dwRegType = 0; // Should be REG_MULTI_SZ
  406. HKEY hkeyOpen = NULL; // Open key to open
  407. PWSTR pszOrderOld = NULL; // Return buffer for order reg value
  408. PWSTR pszOrderNew = NULL; // Build buffer for order swap
  409. DWORD dwDataSize = 0;
  410. // Check for all of the required args
  411. //
  412. if (!pszRemoveString || !hkeyRoot || !pszValueName)
  413. {
  414. Assert(pszRemoveString);
  415. Assert(hkeyRoot);
  416. Assert(pszValueName);
  417. hr = E_INVALIDARG;
  418. goto Exit;
  419. }
  420. // Check to make sure that no "remove" flags are being used, and that
  421. // mutually exclusive flags aren't being used together
  422. //
  423. if ((dwFlags & STRING_FLAG_ENSURE_AT_FRONT) ||
  424. (dwFlags & STRING_FLAG_ENSURE_AT_END) ||
  425. ((dwFlags & STRING_FLAG_REMOVE_SINGLE) &&
  426. (dwFlags & STRING_FLAG_REMOVE_ALL)))
  427. {
  428. AssertSz(FALSE, "Invalid flags in HrRegAddStringToSz");
  429. hr = E_INVALIDARG;
  430. goto Exit;
  431. }
  432. // Open the key, creating if necessary
  433. //
  434. hr = HrRegOpenKeyEx (
  435. hkeyRoot, // Base hive
  436. pszKeySubPath, // Our reg path
  437. KEY_QUERY_VALUE | KEY_SET_VALUE, // samDesired
  438. &hkeyOpen); // Our return hkey
  439. if (FAILED(hr))
  440. {
  441. if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
  442. {
  443. hr = S_OK;
  444. }
  445. goto Exit;
  446. }
  447. // Retrieve the existing REG_SZ
  448. //
  449. hr = HrRegQueryValueWithAlloc (
  450. hkeyOpen,
  451. pszValueName,
  452. &dwRegType,
  453. (LPBYTE *) &pszOrderOld,
  454. &dwDataSize);
  455. if (FAILED(hr))
  456. {
  457. if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
  458. {
  459. // This is OK. It just means that the value is missing. We
  460. // can handle this.
  461. hr = S_OK;
  462. }
  463. goto Exit;
  464. }
  465. else
  466. {
  467. // If we did retrieve a value, then check to make sure that we're
  468. // dealing with a REG_SZ
  469. //
  470. if (dwRegType != REG_SZ)
  471. {
  472. hr = HRESULT_FROM_WIN32 (ERROR_INVALID_DATATYPE);
  473. goto Exit;
  474. }
  475. if (dwDataSize == 0)
  476. {
  477. // This is OK, but we're going to assert here anyway, because this is not
  478. // a case that I know about
  479. //
  480. AssertSz(dwDataSize > 0, "How did we retrieve something from the "
  481. "registry with 0 size?");
  482. hr = S_OK;
  483. goto Exit;
  484. }
  485. }
  486. hr = HrRemoveStringFromDelimitedSz (pszRemoveString, pszOrderOld,
  487. chDelimiter, dwFlags, &pszOrderNew);
  488. if (S_OK == hr)
  489. {
  490. // Save our string back into the registry
  491. //
  492. hr = HrRegSetSz (hkeyOpen, pszValueName, pszOrderNew);
  493. }
  494. Exit:
  495. // Close the key, if open
  496. //
  497. RegSafeCloseKey (hkeyOpen);
  498. // Clean up the registry buffers
  499. //
  500. MemFree (pszOrderOld);
  501. MemFree (pszOrderNew);
  502. TraceError("HrRegRemoveStringFromSz", hr);
  503. return hr;
  504. }
  505. //+---------------------------------------------------------------------------
  506. //
  507. // Function: HrRegRemoveStringFromMultiSz
  508. //
  509. // Purpose: Removes the specified string from a multi-sz, if it is present.
  510. //
  511. // Arguments:
  512. // pszRemoveString [in]
  513. // hkeyRoot [in]
  514. // pszKeySubPath [in]
  515. // pszValueName [in]
  516. // dwFlags [in] Can contain one or more of the following
  517. // values:
  518. //
  519. // STRING_FLAG_REMOVE_SINGLE
  520. // Don't remove more than one value, if
  521. // multiple are present.
  522. // [default] STRING_FLAG_REMOVE_ALL
  523. // If multiple matching values are present,
  524. // remove them all.
  525. //
  526. // Returns: S_OK or an HRESULT_FROM_WIN32 error code.
  527. //
  528. // Author: ScottBri 11-Apr-1997
  529. //
  530. // Notes:
  531. //
  532. HRESULT
  533. HrRegRemoveStringFromMultiSz (
  534. IN PCWSTR pszRemoveString,
  535. IN HKEY hkeyRoot,
  536. IN PCWSTR pszKeySubPath,
  537. IN PCWSTR pszValueName,
  538. IN DWORD dwFlags)
  539. {
  540. DWORD dwDataSize;
  541. DWORD dwRegType;
  542. HKEY hkey = NULL;
  543. HKEY hkeyUse = hkeyRoot;
  544. HRESULT hr;
  545. PWSTR psz = NULL;
  546. // Valid the input parameters
  547. if ((NULL == pszRemoveString) || (NULL == pszValueName) ||
  548. (NULL == hkeyRoot))
  549. {
  550. Assert(NULL != pszRemoveString);
  551. Assert(NULL != pszValueName);
  552. Assert(NULL != hkeyRoot);
  553. return E_INVALIDARG;
  554. }
  555. if ((STRING_FLAG_REMOVE_SINGLE & dwFlags) &&
  556. (STRING_FLAG_REMOVE_ALL & dwFlags))
  557. {
  558. AssertSz(FALSE, "Can't specify both 'remove all' and 'remove single'");
  559. return E_INVALIDARG;
  560. }
  561. if (NULL != pszKeySubPath)
  562. {
  563. hr = HrRegOpenKeyEx (hkeyRoot, pszKeySubPath, KEY_READ_WRITE, &hkey);
  564. if (S_OK != hr)
  565. {
  566. return hr;
  567. }
  568. hkeyUse = hkey;
  569. }
  570. // Retrieve the existing REG_SZ
  571. //
  572. hr = HrRegQueryValueWithAlloc (hkeyUse, pszValueName, &dwRegType,
  573. (LPBYTE *)&psz, &dwDataSize);
  574. if (FAILED(hr))
  575. {
  576. if (HRESULT_FROM_WIN32 (ERROR_FILE_NOT_FOUND) == hr)
  577. {
  578. // This is OK. It just means that the value is missing. We
  579. // can handle this.
  580. hr = S_OK;
  581. }
  582. goto Done;
  583. }
  584. else
  585. {
  586. // If we did retrieve a value, then check to make sure that we're
  587. // dealing with a MULTI_SZ
  588. //
  589. if (dwRegType != REG_MULTI_SZ)
  590. {
  591. hr = HRESULT_FROM_WIN32 (ERROR_INVALID_DATATYPE);
  592. goto Done;
  593. }
  594. }
  595. // Search for and extract the specified string if present
  596. Assert(psz);
  597. BOOL fRemoved;
  598. RemoveSzFromMultiSz (pszRemoveString, psz, dwFlags, &fRemoved);
  599. // Rewrite the registry value if it was changed
  600. if (fRemoved)
  601. {
  602. dwDataSize = CbOfMultiSzAndTermSafe (psz);
  603. hr = HrRegSetValueEx (hkeyUse, pszValueName, REG_MULTI_SZ,
  604. (const LPBYTE)psz, dwDataSize);
  605. }
  606. Done:
  607. RegSafeCloseKey (hkey);
  608. MemFree (psz);
  609. TraceError ("HrRegRemoveStringFromMultiSz", hr);
  610. return hr;
  611. }
  612. //+---------------------------------------------------------------------------
  613. //
  614. // Function: HrRegCopyHive
  615. //
  616. // Purpose: Copies the contents of one hive to another. It does this
  617. // by using RegSaveKey and RegRestoreKey to a temporary file.
  618. //
  619. // Arguments:
  620. // hkeySrc [in] The source key to copy from.
  621. // hkeyDst [in] The destination key to copy to.
  622. //
  623. // Returns: S_OK or an error
  624. //
  625. // Author: shaunco 12 Jan 1998
  626. //
  627. // Notes:
  628. //
  629. HRESULT
  630. HrRegCopyHive (
  631. IN HKEY hkeySrc,
  632. IN HKEY hkeyDst)
  633. {
  634. HRESULT hr;
  635. // Enable the needed privileges.
  636. //
  637. if ((S_OK == (hr = HrEnablePrivilege(SE_BACKUP_NAME))) &&
  638. (S_OK == (hr = HrEnablePrivilege(SE_RESTORE_NAME))))
  639. {
  640. // Create a temporary file name to save the source hive to.
  641. //
  642. static const WCHAR c_szPrefix [] = L"~ch";
  643. WCHAR szTempPath [MAX_PATH];
  644. WCHAR szTempFile [MAX_PATH];
  645. // If GetTempPath fails, we'd like to know about it (via the trace)
  646. // but it's not fatal as we'll just use the current directory
  647. // as the path.
  648. //
  649. if (!GetTempPath (celems(szTempPath), szTempPath))
  650. {
  651. TraceError ("HrRegCopyHive: GetTempPath failed (benign)",
  652. HrFromLastWin32Error ());
  653. *szTempFile = 0;
  654. }
  655. // Create the temporary filename and delete it because RegSaveKey
  656. // won't write to an existing file.
  657. //
  658. if (GetTempFileName (szTempPath, c_szPrefix, 0, szTempFile))
  659. {
  660. DeleteFile (szTempFile);
  661. // Save the source key to the temp file.
  662. //
  663. hr = HrRegSaveKey (hkeySrc, szTempFile, NULL);
  664. if (S_OK == hr)
  665. {
  666. // Restore the temp file to the destination key.
  667. //
  668. hr = HrRegRestoreKey (hkeyDst, szTempFile, NULL);
  669. }
  670. // We're done with the temp file so we delete it. We shoudln't
  671. // have any error doing this, but it will be nice to see it
  672. // should it occur.
  673. //
  674. if (!DeleteFile (szTempFile))
  675. {
  676. TraceError ("HrRegCopyHive: DeleteFile failed on the "
  677. "temporary file (benign)",
  678. HrFromLastWin32Error ());
  679. }
  680. }
  681. else
  682. {
  683. hr = HrFromLastWin32Error ();
  684. }
  685. }
  686. TraceError ("HrRegCopyHive", hr);
  687. return hr;
  688. }
  689. //+---------------------------------------------------------------------------
  690. //
  691. // Function: HrRegCreateKeyEx
  692. //
  693. // Purpose: Creates a registry key by calling RegCreateKeyEx.
  694. //
  695. // Arguments:
  696. // hkey [in]
  697. // pszSubkey [in]
  698. // dwOptions [in] See the Win32 documentation for the
  699. // samDesired [in] RegCreateKeyEx function.
  700. // lpSecurityAttributes [in]
  701. // phkResult [out]
  702. // pdwDisposition [out]
  703. //
  704. // Returns: S_OK or an HRESULT_FROM_WIN32 error code.
  705. //
  706. // Author: danielwe 25 Feb 1997
  707. //
  708. // Notes:
  709. //
  710. HRESULT
  711. HrRegCreateKeyEx (
  712. IN HKEY hkey,
  713. IN PCWSTR pszSubkey,
  714. IN DWORD dwOptions,
  715. IN REGSAM samDesired,
  716. IN LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  717. OUT PHKEY phkResult,
  718. OUT LPDWORD pdwDisposition)
  719. {
  720. Assert (hkey);
  721. Assert (pszSubkey);
  722. Assert (phkResult);
  723. LONG lr = RegCreateKeyExW (hkey, pszSubkey, 0, NULL, dwOptions, samDesired,
  724. lpSecurityAttributes, phkResult, pdwDisposition);
  725. HRESULT hr = HRESULT_FROM_WIN32 (lr);
  726. if (FAILED(hr))
  727. {
  728. *phkResult = NULL;
  729. }
  730. TraceError("HrRegCreateKeyEx", hr);
  731. return hr;
  732. }
  733. //+---------------------------------------------------------------------------
  734. //
  735. // Function: HrRegDeleteKey
  736. //
  737. // Purpose: Delete the specified registry key.
  738. //
  739. // Arguments:
  740. // hkey [in] See the Win32 documentation for the RegDeleteKey.
  741. // pszSubkey [in] function.
  742. //
  743. // Returns: S_OK or an HRESULT_FROM_WIN32 error code.
  744. //
  745. // Author: shaunco 1 Apr 1997
  746. //
  747. // Notes:
  748. //
  749. HRESULT
  750. HrRegDeleteKey (
  751. IN HKEY hkey,
  752. IN PCWSTR pszSubkey)
  753. {
  754. Assert (hkey);
  755. Assert (pszSubkey);
  756. LONG lr = RegDeleteKeyW (hkey, pszSubkey);
  757. HRESULT hr = HRESULT_FROM_WIN32 (lr);
  758. // Did we open the key with incorrect access?
  759. Assert(E_ACCESSDENIED != hr);
  760. TraceHr (ttidError, FAL, hr, ERROR_FILE_NOT_FOUND == lr,
  761. "HrRegDeleteKey");
  762. return hr;
  763. }
  764. //+---------------------------------------------------------------------------
  765. //
  766. // Function: HrRegDeleteKeyTree
  767. //
  768. // Purpose: Deletes an entire registry hive.
  769. //
  770. // Arguments:
  771. // hkeyParent [in] Handle to open key where the desired key resides.
  772. // pszRemoveKey [in] Name of key to delete.
  773. //
  774. // Returns: S_OK or an HRESULT_FROM_WIN32 error code.
  775. //
  776. // Author: danielwe 25 Feb 1997
  777. //
  778. // Notes: ckotze Changed to use KEY_READ_WRITE_DELETE as opposed to
  779. // KEY_ALL_ACCESS, which is far too much access for what is
  780. // required.
  781. //
  782. HRESULT
  783. HrRegDeleteKeyTree (
  784. IN HKEY hkeyParent,
  785. IN PCWSTR pszRemoveKey)
  786. {
  787. Assert (hkeyParent);
  788. Assert (pszRemoveKey);
  789. // Open the key we want to remove
  790. HKEY hkeyRemove;
  791. HRESULT hr = HrRegOpenKeyEx(hkeyParent, pszRemoveKey, KEY_READ_WRITE_DELETE,
  792. &hkeyRemove);
  793. // Did we open the key with incorrect access?
  794. Assert(E_ACCESSDENIED != hr);
  795. if (S_OK == hr)
  796. {
  797. WCHAR szValueName [MAX_PATH];
  798. DWORD cchBuffSize = MAX_PATH;
  799. FILETIME ft;
  800. LONG lr;
  801. // Enum the keys children, and remove those sub-trees
  802. while (ERROR_SUCCESS == (lr = RegEnumKeyExW (hkeyRemove,
  803. 0,
  804. szValueName,
  805. &cchBuffSize,
  806. NULL,
  807. NULL,
  808. NULL,
  809. &ft)))
  810. {
  811. HrRegDeleteKeyTree (hkeyRemove, szValueName);
  812. cchBuffSize = MAX_PATH;
  813. }
  814. RegCloseKey (hkeyRemove);
  815. if ((ERROR_SUCCESS == lr) || (ERROR_NO_MORE_ITEMS == lr))
  816. {
  817. lr = RegDeleteKeyW (hkeyParent, pszRemoveKey);
  818. }
  819. hr = HRESULT_FROM_WIN32 (lr);
  820. }
  821. TraceHr (ttidError, FAL, hr,
  822. HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr,
  823. "HrRegDeleteKeyTree");
  824. return hr;
  825. }
  826. //+---------------------------------------------------------------------------
  827. //
  828. // Function: HrRegDeleteValue
  829. //
  830. // Purpose: Deletes the given registry value.
  831. //
  832. // Arguments:
  833. // hkey [in] See the Win32 documentation for the RegDeleteValue
  834. // pszValueName [in] function.
  835. //
  836. // Returns: S_OK or an HRESULT_FROM_WIN32 error code.
  837. //
  838. // Author: danielwe 25 Feb 1997
  839. //
  840. // Notes:
  841. //
  842. HRESULT
  843. HrRegDeleteValue (
  844. IN HKEY hkey,
  845. IN PCWSTR pszValueName)
  846. {
  847. Assert (hkey);
  848. Assert (pszValueName);
  849. LONG lr = RegDeleteValueW (hkey, pszValueName);
  850. HRESULT hr = HRESULT_FROM_WIN32(lr);
  851. TraceErrorOptional("HrRegDeleteValue", hr, (ERROR_FILE_NOT_FOUND == lr));
  852. return hr;
  853. }
  854. //+---------------------------------------------------------------------------
  855. //
  856. // Function: HrRegEnumKey
  857. //
  858. // Purpose: Enumerates subkeys of the specified open registry key.
  859. //
  860. // Arguments:
  861. // hkey [in]
  862. // dwIndex [in] See the Win32 documentation for the
  863. // pszSubkeyName [out] RegEnumKeyEx function.
  864. // pcchSubkeyName [inout]
  865. //
  866. // Returns: S_OK or an HRESULT_FROM_WIN32 error code.
  867. //
  868. // Author: shaunco 30 Mar 1997
  869. //
  870. // Notes:
  871. //
  872. HRESULT
  873. HrRegEnumKey (
  874. IN HKEY hkey,
  875. IN DWORD dwIndex,
  876. OUT PWSTR pszSubkeyName,
  877. IN DWORD cchSubkeyName)
  878. {
  879. Assert (hkey);
  880. Assert (pszSubkeyName);
  881. Assert (cchSubkeyName);
  882. LONG lr = RegEnumKeyW (hkey, dwIndex, pszSubkeyName, cchSubkeyName);
  883. HRESULT hr = HRESULT_FROM_WIN32(lr);
  884. TraceHr (ttidError, FAL, hr, ERROR_NO_MORE_ITEMS == lr,
  885. "HrRegEnumKey");
  886. return hr;
  887. }
  888. //+---------------------------------------------------------------------------
  889. //
  890. // Function: HrRegEnumKeyEx
  891. //
  892. // Purpose: Enumerates subkeys of the specified open registry key.
  893. //
  894. // Arguments:
  895. // hkey [in]
  896. // dwIndex [in] See the Win32 documentation for the
  897. // pszSubkeyName [out] RegEnumKeyEx function.
  898. // pcchSubkeyName [inout]
  899. // pszClass [out]
  900. // pcchClass [inout]
  901. // pftLastWriteTime [out]
  902. //
  903. // Returns: S_OK or an HRESULT_FROM_WIN32 error code.
  904. //
  905. // Author: shaunco 30 Mar 1997
  906. //
  907. // Notes:
  908. //
  909. HRESULT
  910. HrRegEnumKeyEx (
  911. IN HKEY hkey,
  912. IN DWORD dwIndex,
  913. OUT PWSTR pszSubkeyName,
  914. IN OUT LPDWORD pcchSubkeyName,
  915. OUT PWSTR pszClass,
  916. IN OUT LPDWORD pcchClass,
  917. OUT FILETIME* pftLastWriteTime)
  918. {
  919. Assert (hkey);
  920. Assert (pszSubkeyName);
  921. Assert (pcchSubkeyName);
  922. Assert (pftLastWriteTime);
  923. LONG lr = RegEnumKeyExW (hkey, dwIndex, pszSubkeyName, pcchSubkeyName,
  924. NULL, pszClass, pcchClass, pftLastWriteTime);
  925. HRESULT hr = HRESULT_FROM_WIN32(lr);
  926. TraceHr (ttidError, FAL, hr, ERROR_NO_MORE_ITEMS == lr,
  927. "HrRegEnumKeyEx");
  928. return hr;
  929. }
  930. //+---------------------------------------------------------------------------
  931. //
  932. // Function: HrRegEnumValue
  933. //
  934. // Purpose: Enumerates the values for the specified open registry key.
  935. //
  936. // Arguments:
  937. // hkey [in]
  938. // dwIndex [in] See the Win32 documentation for the
  939. // pszValueName [out] RegEnumValue function.
  940. // pcbValueName [inout]
  941. // pdwType [out]
  942. // pbData [out]
  943. // pcbData [inout]
  944. //
  945. // Returns: S_OK or an HRESULT_FROM_WIN32 error code.
  946. //
  947. // Author: shaunco 30 Mar 1997
  948. //
  949. // Notes:
  950. //
  951. HRESULT
  952. HrRegEnumValue (
  953. IN HKEY hkey,
  954. IN DWORD dwIndex,
  955. OUT PWSTR pszValueName,
  956. IN OUT LPDWORD pcbValueName,
  957. OUT LPDWORD pdwType,
  958. OUT LPBYTE pbData,
  959. IN OUT LPDWORD pcbData)
  960. {
  961. Assert (hkey);
  962. Assert (pszValueName);
  963. Assert (pcbValueName);
  964. Assert (FImplies(pbData, pcbData));
  965. LONG lr = RegEnumValueW (hkey, dwIndex, pszValueName, pcbValueName,
  966. NULL, pdwType, pbData, pcbData);
  967. HRESULT hr = HRESULT_FROM_WIN32 (lr);
  968. TraceErrorOptional("HrRegEnumValue", hr, (ERROR_NO_MORE_ITEMS == lr));
  969. return hr;
  970. }
  971. //+---------------------------------------------------------------------------
  972. //
  973. // Function: HrRegOpenKeyEx
  974. //
  975. // Purpose: Opens a registry key by calling RegOpenKeyEx.
  976. //
  977. // Arguments:
  978. // hkey [in]
  979. // pszSubkey [in] See the Win32 documentation for the
  980. // samDesired [in] RegOpenKeyEx function.
  981. // phkResult [out]
  982. //
  983. // Returns: S_OK or an HRESULT_FROM_WIN32 error code.
  984. //
  985. // Author: danielwe 25 Feb 1997
  986. //
  987. // Notes:
  988. //
  989. HRESULT
  990. HrRegOpenKeyEx (
  991. IN HKEY hkey,
  992. IN PCWSTR pszSubkey,
  993. IN REGSAM samDesired,
  994. OUT PHKEY phkResult)
  995. {
  996. Assert (hkey);
  997. Assert (pszSubkey);
  998. Assert (phkResult);
  999. LONG lr = RegOpenKeyExW (hkey, pszSubkey, 0, samDesired, phkResult);
  1000. HRESULT hr = HRESULT_FROM_WIN32(lr);
  1001. if (FAILED(hr))
  1002. {
  1003. *phkResult = NULL;
  1004. TraceTag(ttidDefault, "Error Opening Key:%s hr: 0x%x", pszSubkey, hr);
  1005. }
  1006. TraceErrorOptional("HrRegOpenKeyEx", hr, (ERROR_FILE_NOT_FOUND == lr));
  1007. return hr;
  1008. }
  1009. //+---------------------------------------------------------------------------
  1010. //
  1011. // Function: HrRegOpenKeyBestAccess
  1012. //
  1013. // Purpose: Opens a registry key by calling RegOpenKeyEx with the highest
  1014. // access possible.
  1015. //
  1016. // Arguments:
  1017. // hkey [in]
  1018. // pszSubkey [in] See the Win32 documentation for the
  1019. // phkResult [out]
  1020. //
  1021. // Returns: S_OK or an HRESULT_FROM_WIN32 error code.
  1022. //
  1023. // Author: scottbri 31-Oct-1997
  1024. //
  1025. // Notes:
  1026. //
  1027. HRESULT
  1028. HrRegOpenKeyBestAccess (
  1029. IN HKEY hkey,
  1030. IN PCWSTR pszSubkey,
  1031. OUT PHKEY phkResult)
  1032. {
  1033. Assert (hkey);
  1034. Assert (pszSubkey);
  1035. Assert (phkResult);
  1036. TraceTag(ttidDefault, "Why do you call this function? Either you can write or you can't.");
  1037. LONG lr = RegOpenKeyExW (hkey, pszSubkey, 0, KEY_ALL_ACCESS, phkResult);
  1038. HRESULT hr = HRESULT_FROM_WIN32 (lr);
  1039. if (E_ACCESSDENIED == hr)
  1040. {
  1041. lr = RegOpenKeyExW (hkey, pszSubkey, 0, KEY_READ_WRITE_DELETE, phkResult);
  1042. hr = HRESULT_FROM_WIN32 (lr);
  1043. if (E_ACCESSDENIED == hr)
  1044. {
  1045. lr = RegOpenKeyExW (hkey, pszSubkey, 0, KEY_READ_WRITE, phkResult);
  1046. hr = HRESULT_FROM_WIN32 (lr);
  1047. if (E_ACCESSDENIED == hr)
  1048. {
  1049. lr = RegOpenKeyExW (hkey, pszSubkey, 0, KEY_READ, phkResult);
  1050. hr = HRESULT_FROM_WIN32 (lr);
  1051. if (E_ACCESSDENIED == hr)
  1052. {
  1053. lr = RegOpenKeyExW (hkey, pszSubkey, 0, STANDARD_RIGHTS_READ | KEY_QUERY_VALUE, phkResult);
  1054. hr = HRESULT_FROM_WIN32 (lr);
  1055. }
  1056. }
  1057. }
  1058. }
  1059. if (FAILED(hr))
  1060. {
  1061. *phkResult = NULL;
  1062. }
  1063. TraceErrorOptional("HrRegOpenKeyEx", hr, (ERROR_FILE_NOT_FOUND == lr));
  1064. return hr;
  1065. }
  1066. //+---------------------------------------------------------------------------
  1067. //
  1068. // Function: HrRegDuplicateKeyEx
  1069. //
  1070. // Purpose: Duplicates a registry key by calling RegOpenKeyEx.
  1071. //
  1072. // Arguments:
  1073. // hkey [in]
  1074. // samDesired [in] RegOpenKeyEx function.
  1075. // phkResult [out]
  1076. //
  1077. // Returns: S_OK or an HRESULT_FROM_WIN32 error code.
  1078. //
  1079. // Author: mikemi 09 Apr 1997
  1080. //
  1081. // Notes:
  1082. //
  1083. HRESULT
  1084. HrRegDuplicateKeyEx (
  1085. IN HKEY hkey,
  1086. IN REGSAM samDesired,
  1087. OUT PHKEY phkResult)
  1088. {
  1089. Assert (hkey);
  1090. Assert (phkResult);
  1091. LONG lr = RegOpenKeyExW (hkey, NULL, 0, samDesired, phkResult);
  1092. HRESULT hr = HRESULT_FROM_WIN32 (lr);
  1093. if (FAILED(hr))
  1094. {
  1095. *phkResult = NULL;
  1096. }
  1097. TraceError("HrRegDuplicateKeyEx", hr);
  1098. return hr;
  1099. }
  1100. HRESULT
  1101. HrRegSetBool (
  1102. IN HKEY hkey,
  1103. IN PCWSTR pszValueName,
  1104. IN BOOL fValue)
  1105. {
  1106. DWORD dwValue = !!fValue;
  1107. return HrRegSetValueEx (hkey, pszValueName,
  1108. REG_DWORD,
  1109. (LPBYTE)&dwValue, sizeof(DWORD));
  1110. }
  1111. HRESULT
  1112. HrRegSetDword (
  1113. IN HKEY hkey,
  1114. IN PCWSTR pszValueName,
  1115. IN DWORD dwValue)
  1116. {
  1117. return HrRegSetValueEx (hkey, pszValueName,
  1118. REG_DWORD,
  1119. (LPBYTE)&dwValue, sizeof(DWORD));
  1120. }
  1121. //+---------------------------------------------------------------------------
  1122. //
  1123. // Function: HrRegSetGuidAsSz
  1124. //
  1125. // Purpose: Converts a given guid to a string and sets the given registry
  1126. // value.
  1127. //
  1128. // Arguments:
  1129. // hkey [in]
  1130. // pszValueName [in]
  1131. // guid [in]
  1132. //
  1133. // Returns: S_OK or an HRESULT_FROM_WIN32 error code.
  1134. //
  1135. // Author: BillBe 21 Feb 1999
  1136. //
  1137. // Notes:
  1138. //
  1139. HRESULT
  1140. HrRegSetGuidAsSz (
  1141. IN HKEY hkey,
  1142. IN PCWSTR pszValueName,
  1143. IN const GUID& guid)
  1144. {
  1145. HRESULT hr;
  1146. INT cch;
  1147. WCHAR szGuid[c_cchGuidWithTerm];
  1148. Assert (hkey);
  1149. Assert (pszValueName && *pszValueName);
  1150. cch = StringFromGUID2 (guid, szGuid, c_cchGuidWithTerm);
  1151. Assert (c_cchGuidWithTerm == cch);
  1152. hr = HrRegSetSz (hkey, pszValueName, szGuid);
  1153. TraceHr (ttidError, FAL, hr, FALSE, "HrRegSetGuidAsSz");
  1154. return hr;
  1155. }
  1156. //+---------------------------------------------------------------------------
  1157. //
  1158. // Function: HrRegSetValueEx
  1159. //
  1160. // Purpose: Sets the data for the given registry value by calling the
  1161. // RegSetValueEx function.
  1162. //
  1163. // Arguments:
  1164. // hkey [in]
  1165. // pszValueName [in]
  1166. // dwType [in] See the Win32 documentation for the RegSetValueEx
  1167. // pbData [in] function.
  1168. // cbData [in]
  1169. //
  1170. // Returns: S_OK or an HRESULT_FROM_WIN32 error code.
  1171. //
  1172. // Author: danielwe 25 Feb 1997
  1173. //
  1174. // Notes:
  1175. //
  1176. HRESULT
  1177. HrRegSetValueEx (
  1178. IN HKEY hkey,
  1179. IN PCWSTR pszValueName,
  1180. IN DWORD dwType,
  1181. IN const BYTE *pbData,
  1182. IN DWORD cbData)
  1183. {
  1184. Assert (hkey);
  1185. Assert (FImplies (cbData > 0, pbData));
  1186. LONG lr = RegSetValueExW(hkey, pszValueName, 0, dwType, pbData, cbData);
  1187. HRESULT hr = HRESULT_FROM_WIN32 (lr);
  1188. // Did we open the key with incorrect access?
  1189. Assert(E_ACCESSDENIED != hr);
  1190. TraceError("HrRegSetValue", hr);
  1191. return hr;
  1192. }
  1193. //+---------------------------------------------------------------------------
  1194. //
  1195. // Function: RegSafeCloseKey
  1196. //
  1197. // Purpose: Closes the given registry key if it is non-NULL.
  1198. //
  1199. // Arguments:
  1200. // hkey [in] Key to be closed. Can be NULL.
  1201. //
  1202. // Returns: Nothing.
  1203. //
  1204. // Author: danielwe 25 Feb 1997
  1205. //
  1206. // Notes: If hkey is NULL this function does nothing.
  1207. //
  1208. VOID
  1209. RegSafeCloseKey (
  1210. IN HKEY hkey)
  1211. {
  1212. if (hkey)
  1213. {
  1214. RegCloseKey(hkey);
  1215. }
  1216. }
  1217. //+---------------------------------------------------------------------------
  1218. //
  1219. // Function: HrRegRestoreKey
  1220. //
  1221. // Purpose: Wrapper for RegRestoreKey
  1222. //
  1223. // Arguments:
  1224. // hkey [in] Parent key to restore into
  1225. // pszFileName [in] Name of file containing registry info
  1226. // dwFlags [in] Flags for restore
  1227. //
  1228. // Returns: Win32 HRESULT if failure, otherwise S_OK
  1229. //
  1230. // Author: danielwe 8 Aug 1997
  1231. //
  1232. // Notes: See docs for RegRestoreKey for more info
  1233. //
  1234. HRESULT
  1235. HrRegRestoreKey (
  1236. IN HKEY hkey,
  1237. IN PCWSTR pszFileName,
  1238. IN DWORD dwFlags)
  1239. {
  1240. HRESULT hr = S_OK;
  1241. LONG lres;
  1242. Assert(hkey);
  1243. Assert(pszFileName);
  1244. lres = RegRestoreKeyW(hkey, pszFileName, dwFlags);
  1245. hr = HRESULT_FROM_WIN32(lres);
  1246. // Did we open the key with incorrect access?
  1247. Assert(E_ACCESSDENIED != hr);
  1248. TraceError("HrRegRestoreKey", hr);
  1249. return hr;
  1250. }
  1251. //+---------------------------------------------------------------------------
  1252. //
  1253. // Function: HrRegSaveKey
  1254. //
  1255. // Purpose: Wrapper for RegSaveKey
  1256. //
  1257. // Arguments:
  1258. // hkey [in] Parent key to restore into
  1259. // pszFileName [in] Name of file containing registry info
  1260. // psa [in] Security attributes for the file
  1261. //
  1262. // Returns: Win32 HRESULT if failure, otherwise S_OK
  1263. //
  1264. // Author: BillBe 2 Jan 1998
  1265. //
  1266. // Notes: See docs for RegSaveKey for more info
  1267. //
  1268. HRESULT
  1269. HrRegSaveKey (
  1270. IN HKEY hkey,
  1271. IN PCWSTR pszFileName,
  1272. IN LPSECURITY_ATTRIBUTES psa)
  1273. {
  1274. HRESULT hr;
  1275. LONG lres;
  1276. Assert(hkey);
  1277. Assert(pszFileName);
  1278. lres = RegSaveKeyW (hkey, pszFileName, psa);
  1279. hr = HRESULT_FROM_WIN32(lres);
  1280. // Did we open the key with incorrect access?
  1281. Assert(E_ACCESSDENIED != hr);
  1282. TraceError("HrRegSaveKey", hr);
  1283. return hr;
  1284. }
  1285. //+---------------------------------------------------------------------------
  1286. //
  1287. // Function: HrRegGetKeySecurity
  1288. //
  1289. // Purpose: Retrieves the Security of a Key using RegGetKeySecurity
  1290. //
  1291. // Arguments:
  1292. // hkey [in]
  1293. // pszSubkey [in] See the Win32 documentation for the
  1294. // samDesired [in] RegOpenKeyEx function.
  1295. // phkResult [out]
  1296. //
  1297. // Returns: S_OK or an HRESULT_FROM_WIN32 error code.
  1298. //
  1299. // Author: ckotze 06 July 2000
  1300. //
  1301. // Notes:
  1302. //
  1303. HRESULT
  1304. HrRegGetKeySecurity(
  1305. HKEY hKey,
  1306. SECURITY_INFORMATION SecurityInformation,
  1307. PSECURITY_DESCRIPTOR pSecurityDescriptor,
  1308. LPDWORD lpcbSecurityDescriptor)
  1309. {
  1310. Assert (hKey);
  1311. Assert (SecurityInformation);
  1312. Assert (pSecurityDescriptor);
  1313. LONG lr = RegGetKeySecurity(hKey, SecurityInformation, pSecurityDescriptor, lpcbSecurityDescriptor);
  1314. HRESULT hr = HRESULT_FROM_WIN32(lr);
  1315. // Did we open the key with incorrect access?
  1316. Assert(E_ACCESSDENIED != hr);
  1317. if (FAILED(hr))
  1318. {
  1319. pSecurityDescriptor = NULL;
  1320. }
  1321. TraceErrorOptional("HrRegGetKeySecurity", hr, (lr != ERROR_INSUFFICIENT_BUFFER));
  1322. return hr;
  1323. }
  1324. //+---------------------------------------------------------------------------
  1325. //
  1326. // Function: HrRegOpenKeyEx
  1327. //
  1328. // Purpose: Opens a registry key by calling RegOpenKeyEx.
  1329. //
  1330. // Arguments:
  1331. // hkey [in]
  1332. // pszSubkey [in] See the Win32 documentation for the
  1333. // samDesired [in] RegOpenKeyEx function.
  1334. // phkResult [out]
  1335. //
  1336. // Returns: S_OK or an HRESULT_FROM_WIN32 error code.
  1337. //
  1338. // Author: danielwe 25 Feb 1997
  1339. //
  1340. // Notes:
  1341. //
  1342. HRESULT HrRegSetKeySecurity (
  1343. HKEY hKey,
  1344. SECURITY_INFORMATION SecurityInformation,
  1345. PSECURITY_DESCRIPTOR pSecurityDescriptor)
  1346. {
  1347. Assert (hKey);
  1348. Assert (SecurityInformation);
  1349. Assert (pSecurityDescriptor);
  1350. LONG lr = RegSetKeySecurity(hKey, SecurityInformation, pSecurityDescriptor);
  1351. HRESULT hr = HRESULT_FROM_WIN32(lr);
  1352. // Did we open the key with incorrect access?
  1353. Assert(E_ACCESSDENIED != hr);
  1354. TraceError("HrRegSetKeySecurity", hr);
  1355. return hr;
  1356. }
  1357. //+---------------------------------------------------------------------------
  1358. //
  1359. // Member: HrRegOpenAdapterKey
  1360. //
  1361. // Purpose: This creates or opens the Adapters subkey to a component
  1362. //
  1363. // Arguments:
  1364. // pszComponentName [in] The name of the component being
  1365. // fCreate [in] TRUE if the directory is to be created
  1366. // phkey [out] The handle to the Adapters subkey
  1367. //
  1368. // Returns: S_OK or an HRESULT_FROM_WIN32 error code.
  1369. //
  1370. // Author: CWill 06/11/97
  1371. //
  1372. // Notes: The handle has to be release by the calling app on SUCCESS
  1373. //
  1374. HRESULT
  1375. HrRegOpenAdapterKey (
  1376. IN PCWSTR pszComponentName,
  1377. IN BOOL fCreate,
  1378. OUT HKEY* phkey)
  1379. {
  1380. HRESULT hr = S_OK;
  1381. DWORD dwDisposition = 0x0;
  1382. tstring strKey;
  1383. // Build the registry path
  1384. strKey = c_szRegKeyServices;
  1385. strKey.append(c_szBackslash);
  1386. strKey.append(pszComponentName);
  1387. strKey.append(c_szBackslash);
  1388. strKey.append(c_szParameters);
  1389. strKey.append(c_szBackslash);
  1390. strKey.append(c_szAdapters);
  1391. // Create the key if we are asked
  1392. if (fCreate)
  1393. {
  1394. hr = HrRegCreateKeyEx(
  1395. HKEY_LOCAL_MACHINE,
  1396. strKey.c_str(),
  1397. REG_OPTION_NON_VOLATILE,
  1398. KEY_READ_WRITE_DELETE,
  1399. NULL,
  1400. phkey,
  1401. &dwDisposition);
  1402. }
  1403. else
  1404. {
  1405. hr = HrRegOpenKeyEx(
  1406. HKEY_LOCAL_MACHINE,
  1407. strKey.c_str(),
  1408. KEY_READ,
  1409. phkey);
  1410. }
  1411. TraceError("HrRegOpenAdapterKey", hr);
  1412. return hr;
  1413. }
  1414. //+---------------------------------------------------------------------------
  1415. //
  1416. // Function: HrRegQueryColString
  1417. //
  1418. // Purpose: Allocates strings and appends to collects as read from the registry.
  1419. //
  1420. // Arguments:
  1421. // hkey [in] The registry key.
  1422. // pszValueName [in] The name of the value to get.
  1423. // pcolstr [out] The returned collection of tstrings*. empty collection otherwise.
  1424. //
  1425. // Returns: S_OK or an HRESULT_FROM_WIN32 error code.
  1426. //
  1427. // Author: mikemi 30 Apr 1997
  1428. //
  1429. // Notes: If the function succeeds, you must call DeleteColString on the
  1430. // return parameter.
  1431. // This will empty and delete the collection passed in
  1432. //
  1433. //---------------------------------------------------------------------------
  1434. HRESULT
  1435. HrRegQueryColString (
  1436. IN HKEY hkey,
  1437. IN PCWSTR pszValueName,
  1438. OUT list<tstring*>* pcolstr )
  1439. {
  1440. WCHAR* pmsz;
  1441. HRESULT hr;
  1442. DeleteColString (pcolstr);
  1443. hr = HrRegQueryMultiSzWithAlloc (hkey, pszValueName, &pmsz);
  1444. if (S_OK == hr)
  1445. {
  1446. MultiSzToColString (pmsz, pcolstr);
  1447. MemFree (pmsz);
  1448. }
  1449. TraceHr (ttidError, FAL, hr,
  1450. HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr, "HrRegQueryColString");
  1451. return hr;
  1452. }
  1453. HRESULT
  1454. HrRegQueryColString (
  1455. IN HKEY hkey,
  1456. IN PCWSTR pszValueName,
  1457. OUT vector<tstring*>* pcolstr )
  1458. {
  1459. WCHAR* pmsz;
  1460. HRESULT hr;
  1461. DeleteColString (pcolstr);
  1462. hr = HrRegQueryMultiSzWithAlloc (hkey, pszValueName, &pmsz);
  1463. if (S_OK == hr)
  1464. {
  1465. MultiSzToColString (pmsz, pcolstr);
  1466. MemFree (pmsz);
  1467. }
  1468. TraceHr (ttidError, FAL, hr,
  1469. HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr, "HrRegQueryColString");
  1470. return hr;
  1471. }
  1472. //+---------------------------------------------------------------------------
  1473. //
  1474. // Function: HrRegSetColString
  1475. //
  1476. // Purpose: Sets a multi-sz in the registry using the collection of strings
  1477. //
  1478. // Arguments:
  1479. // hkey [in] The registry key.
  1480. // pszValueName [in] The name of the value to set.
  1481. // colstr [in] The collection of tstrings to set.
  1482. //
  1483. // Returns: S_OK or an HRESULT_FROM_WIN32 error code.
  1484. //
  1485. // Author: mikemi 30 Apr 1997
  1486. //
  1487. // Notes:
  1488. //
  1489. //---------------------------------------------------------------------------
  1490. HRESULT
  1491. HrRegSetColString (
  1492. IN HKEY hkey,
  1493. IN PCWSTR pszValueName,
  1494. IN const list<tstring*>& colstr)
  1495. {
  1496. WCHAR* pmsz;
  1497. HRESULT hr;
  1498. ColStringToMultiSz (colstr, &pmsz);
  1499. hr = HrRegSetMultiSz (hkey, pszValueName, (pmsz ? pmsz : c_szEmpty));
  1500. MemFree (pmsz);
  1501. TraceError ("HrRegSetColString", hr);
  1502. return hr;
  1503. }
  1504. HRESULT
  1505. HrRegSetColString (
  1506. IN HKEY hkey,
  1507. IN PCWSTR pszValueName,
  1508. IN const vector<tstring*>& colstr)
  1509. {
  1510. WCHAR* pmsz;
  1511. HRESULT hr;
  1512. ColStringToMultiSz (colstr, &pmsz);
  1513. hr = HrRegSetMultiSz (hkey, pszValueName, (pmsz ? pmsz : c_szEmpty));
  1514. MemFree (pmsz);
  1515. TraceError ("HrRegSetColString", hr);
  1516. return hr;
  1517. }