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.

833 lines
26 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 1992, Microsoft Corporation.
  4. //
  5. // File: registry.cxx
  6. //
  7. // Contents: implementations for CMyRegKey member Members
  8. //
  9. // Members: CMyRegKey::CMyRegKey - constructor for registry key object
  10. // CMyRegKey::CMyRegKey - constructor for registry key object
  11. // CMyRegKey::CreateKey - real worker for constructors
  12. // CMyRegKey::~CMyRegKey - destructor for registry key object
  13. // CMyRegKey::Delete - delete a registry key
  14. // CMyRegKey::EnumValues - enumerate values of a registry key
  15. // CMyRegKey::EnumKeys - enumerate subkeys of a registry key
  16. // CMyRegKey::NotifyChange - setup change notification for a key
  17. //
  18. // CRegValue::GetValue - sets a registry value
  19. // CRegValue::SetValue - retrieves a registry value
  20. // CRegValue::Delete - deletes a registry value
  21. // CRegValue::GetTypeCode - returns the type code of the value
  22. //
  23. // CRegMSZ::SetStrings - sets a multi-string registry value
  24. // CRegMSZ::GetStrings - retrieves a multi-string registry value
  25. //
  26. // History: 09/30/92 Rickhi Created
  27. //
  28. // 09/22/93 AlokS Took out exception throwing code
  29. // and added proper return code for
  30. // each method.
  31. //
  32. // 07/26/94 AlokS Made it real light weight for simple
  33. // registry set/get operations
  34. //
  35. // 12/09/07 Milans Ported it over to Exchange
  36. //
  37. // Notes: see notes in registry.h
  38. //
  39. //----------------------------------------------------------------------------
  40. #include <stdlib.h>
  41. #include <windows.h>
  42. #include "registry.h"
  43. //+-------------------------------------------------------------------------
  44. //
  45. // Member: CMyRegKey::CMyRegKey
  46. //
  47. // Synopsis: Constructor for registry key object, using HKEY for parent
  48. //
  49. // Arguments: [hkParent] - handle to parent key
  50. // [pszPath] - pathname to key
  51. // [samDesiredAccess] - desired access rights to the key
  52. // [pszClass] - class for the key
  53. // [dwOptions] - options for the key eg volatile or not
  54. // [pdwDisposition] - to find out if key was opened or created
  55. // [pSecurityAttributes] - used only if the key is created
  56. // [fThrowExceptionOnError] - Constructor throw exception on error
  57. //
  58. // Signals: Internal error state is set if construction fails.
  59. //
  60. // Returns: -none-
  61. //
  62. // History: 09/30/92 Rickhi Created
  63. //
  64. // Notes: All except the hkParent and pszPath are optional parameters.
  65. //
  66. //--------------------------------------------------------------------------
  67. CMyRegKey::CMyRegKey (
  68. HKEY hkParent,
  69. LPCSTR pszPath,
  70. REGSAM samDesiredAccess,
  71. LPCSTR pszClass,
  72. DWORD dwOptions,
  73. DWORD *pdwDisposition,
  74. const LPSECURITY_ATTRIBUTES pSecurityAttributes )
  75. :_hkParent(hkParent),
  76. _hkThis(NULL),
  77. _dwErr (ERROR_SUCCESS)
  78. {
  79. _dwErr = CreateKey( _hkParent,
  80. pszPath,
  81. samDesiredAccess,
  82. pszClass,
  83. dwOptions,
  84. pdwDisposition,
  85. pSecurityAttributes );
  86. }
  87. //+-------------------------------------------------------------------------
  88. //
  89. // Member: CMyRegKey::CMyRegKey
  90. //
  91. // Synopsis: Constructor for registry key object, using CMyRegKey for parent
  92. //
  93. // Arguments: [prkParent] - ptr to Parent CMyRegKey
  94. // [pszPath] - pathname to key
  95. // [samDesiredAccess] - desired access rights to the key
  96. // [pszClass] - class for the key
  97. // [dwOptions] - options for the key eg volatile or not
  98. // [pdwDisposition] - to find out if key was opened or created
  99. // [pSecurityAttributes] - used only if the key is created
  100. // [fThrowExceptionOnError] - Constructor throw exception on error
  101. //
  102. // Signals: Internal Error state is set if error occures during construction.
  103. //
  104. // Returns: nothing
  105. //
  106. // History: 09/30/92 Rickhi Created
  107. //
  108. // Notes: All except the prkParent and pszPath are optional parameters.
  109. //
  110. //--------------------------------------------------------------------------
  111. CMyRegKey::CMyRegKey (
  112. const CMyRegKey &crkParent,
  113. LPCSTR pszPath,
  114. REGSAM samDesiredAccess,
  115. LPCSTR pszClass,
  116. DWORD dwOptions,
  117. DWORD *pdwDisposition,
  118. const LPSECURITY_ATTRIBUTES pSecurityAttributes )
  119. :_hkParent(crkParent.GetHandle()),
  120. _hkThis(NULL),
  121. _dwErr(ERROR_SUCCESS)
  122. {
  123. _dwErr = CreateKey ( _hkParent,
  124. pszPath,
  125. samDesiredAccess,
  126. pszClass,
  127. dwOptions,
  128. pdwDisposition,
  129. pSecurityAttributes );
  130. }
  131. //+-------------------------------------------------------------------------
  132. //
  133. // Member: CMyRegKey::CMyRegKey
  134. //
  135. // Synopsis: Constructor for registry key object, using HKEY for parent
  136. // Merely opens the key, if exist
  137. //
  138. // Arguments: [hkParent] - HKEY to Parent
  139. // [dwErr] - Error code returned here
  140. // [pszPath] - pathname to key
  141. // [samDesiredAccess] - desired access rights to the key
  142. //
  143. // Signals: Internal Error state is set if error occures during construction
  144. //
  145. // Returns: nothing
  146. //
  147. // History: 09/22/93 AlokS Created
  148. //
  149. // Notes: Check error status to determine if constructor succeeded
  150. //
  151. //--------------------------------------------------------------------------
  152. CMyRegKey::CMyRegKey (
  153. HKEY hkParent,
  154. DWORD *pdwErr,
  155. LPCSTR pszPath,
  156. REGSAM samDesiredAccess )
  157. :_hkParent(hkParent),
  158. _hkThis(NULL),
  159. _dwErr(ERROR_SUCCESS)
  160. {
  161. *pdwErr = _dwErr = OpenKey ( _hkParent, pszPath, samDesiredAccess );
  162. }
  163. //+-------------------------------------------------------------------------
  164. //
  165. // Member: CMyRegKey::CMyRegKey
  166. //
  167. // Synopsis: Constructor for registry key object, using CMyRegKey for parent
  168. // Merely opens the key, if exist
  169. //
  170. // Arguments: [prkParent] - ptr to Parent CMyRegKey
  171. // [dwErr] - Error code returned here.
  172. // [pszPath] - pathname to key
  173. // [samDesiredAccess] - desired access rights to the key
  174. //
  175. // Signals: Internal Error state is set if error occures during construction
  176. //
  177. // Returns: nothing
  178. //
  179. // History: 09/22/93 AlokS Created
  180. //
  181. // Notes: Check error status to determine if constructor succeeded
  182. //
  183. //--------------------------------------------------------------------------
  184. CMyRegKey::CMyRegKey (
  185. const CMyRegKey &crkParent,
  186. DWORD *pdwErr,
  187. LPCSTR pszPath,
  188. REGSAM samDesiredAccess )
  189. :_hkParent(crkParent.GetHandle()),
  190. _hkThis(NULL),
  191. _dwErr(ERROR_SUCCESS)
  192. {
  193. *pdwErr = _dwErr = OpenKey ( _hkParent, pszPath, samDesiredAccess );
  194. }
  195. //+-------------------------------------------------------------------------
  196. //
  197. // Member: CMyRegKey::~CMyRegKey, public
  198. //
  199. // Synopsis: Destructor for registry key object
  200. //
  201. // Arguments: none
  202. //
  203. // Signals: nothing
  204. //
  205. // Returns: nothing
  206. //
  207. // History: 09/30/92 Rickhi Created
  208. //
  209. // Notes:
  210. //
  211. //--------------------------------------------------------------------------
  212. CMyRegKey::~CMyRegKey()
  213. {
  214. if (_hkThis != NULL)
  215. RegCloseKey(_hkThis);
  216. }
  217. //+-------------------------------------------------------------------------
  218. //
  219. // Member: CMyRegKey::CreateKey, private
  220. //
  221. // Synopsis: This method does the real work of the constructors.
  222. //
  223. // Arguments: [hkParent] - handle to parent key
  224. // [pszPath] - pathname to key
  225. // [samDesiredAccess] - desired access rights to the key
  226. // [pszClass] - class for the key
  227. // [dwOptions] - options for the key eg volatile or not
  228. // [pdwDisposition] - to find out if key was opened or created
  229. // [pSecurityAttributes] - used only if the key is created
  230. //
  231. // Signals: -none-
  232. //
  233. // Returns: ERROR_SUCCESS on success. Else error from either Registry APIs
  234. // or from Memory allocation
  235. //
  236. // History: 09/30/92 Rickhi Created
  237. //
  238. // Notes: All parameters are required.
  239. //
  240. //--------------------------------------------------------------------------
  241. DWORD CMyRegKey::CreateKey (
  242. HKEY hkParent,
  243. LPCSTR pszPath,
  244. REGSAM samDesiredAccess,
  245. LPCSTR pszClass,
  246. DWORD dwOptions,
  247. DWORD *pdwDisposition,
  248. const LPSECURITY_ATTRIBUTES pSecurityAttributes )
  249. {
  250. DWORD dwDisposition;
  251. DWORD dwRc;
  252. DWORD dwErr = ERROR_SUCCESS;
  253. LPSECURITY_ATTRIBUTES lpsec = pSecurityAttributes;
  254. // create/open the key
  255. if ((dwRc = RegCreateKeyEx(hkParent,
  256. (LPSTR) pszPath, // path to key
  257. 0, // title index
  258. (LPSTR) pszClass, // class of key
  259. dwOptions, // key options
  260. samDesiredAccess, // desired access
  261. lpsec, // if created
  262. &_hkThis, // handle
  263. &dwDisposition) // opened/created
  264. )==ERROR_SUCCESS)
  265. {
  266. // save away the name
  267. _cszName.Set((PCHAR) pszPath);
  268. // setup the return parameters
  269. if (pdwDisposition != NULL)
  270. *pdwDisposition = dwDisposition;
  271. }
  272. else
  273. dwErr = Creg_ERROR(dwRc);
  274. return(dwErr);
  275. }
  276. //+-------------------------------------------------------------------------
  277. //
  278. // Member: CMyRegKey::OpenKey, private
  279. //
  280. // Synopsis: This method does the real work of the constructors.
  281. //
  282. // Arguments: [hkParent] - handle to parent key
  283. // [pszPath] - pathname to key
  284. // [samDesiredAccess] - desired access rights to the key
  285. //
  286. // Signals: -none-
  287. //
  288. // Returns: ERROR_SUCCESS on success. Else error from either Registry APIs
  289. // or from Memory allocation
  290. //
  291. // History: 09/22/93 AlokS Created
  292. //
  293. // Notes: All parameters are required.
  294. //
  295. //--------------------------------------------------------------------------
  296. DWORD CMyRegKey::OpenKey (
  297. HKEY hkParent,
  298. LPCSTR pszPath,
  299. REGSAM samDesiredAccess )
  300. {
  301. DWORD dwRc;
  302. DWORD dwErr = ERROR_SUCCESS;
  303. // open the key
  304. if ((dwRc = RegOpenKeyEx(hkParent,
  305. pszPath, // path to key
  306. 0, // reserved
  307. samDesiredAccess, // desired access
  308. &_hkThis // handle
  309. ))==ERROR_SUCCESS)
  310. {
  311. // save away the name
  312. _cszName.Set((PCHAR) pszPath);
  313. }
  314. else
  315. dwErr = Creg_ERROR(dwRc);
  316. return(dwErr);
  317. }
  318. //+-------------------------------------------------------------------------
  319. //
  320. // Member: CMyRegKey::Delete, public
  321. //
  322. // Synopsis: Deletes an existing key from the registry. Note that
  323. // the key object still exists, the destructor must be
  324. // called seperately.
  325. //
  326. // Arguments: none
  327. //
  328. // Signals: -none-
  329. //
  330. // Returns: ERROR_SUCCESS on success. Else error from either Registry APIs
  331. // or from Memory allocation
  332. //
  333. // History: 09/30/92 Rickhi Created
  334. //
  335. // Notes:
  336. //
  337. //--------------------------------------------------------------------------
  338. DWORD CMyRegKey::Delete(void)
  339. {
  340. DWORD dwErr = ERROR_SUCCESS;
  341. DWORD dwRc;
  342. SRegKeySet *pChildren;
  343. dwErr = this->EnumKeys(&pChildren);
  344. if (dwErr == ERROR_SUCCESS) {
  345. ULONG i;
  346. DWORD dwErrDelete = ERROR_SUCCESS;
  347. for(i = 0; i < pChildren->cKeys; i++) {
  348. dwErr = pChildren->aprkKey[i]->Delete();
  349. if (dwErr != ERROR_SUCCESS) {
  350. dwErrDelete = dwErr;
  351. }
  352. delete pChildren->aprkKey[i];
  353. }
  354. if (dwErrDelete == ERROR_SUCCESS) {
  355. if (( dwRc= RegDeleteKey(_hkThis, NULL))!=ERROR_SUCCESS) {
  356. dwErr = Creg_ERROR(dwRc);
  357. }
  358. } else {
  359. dwErr = dwErrDelete;
  360. }
  361. delete pChildren;
  362. }
  363. return(dwErr);
  364. }
  365. //+-------------------------------------------------------------------------
  366. //
  367. // Member: CMyRegKey::EnumValues, public
  368. //
  369. // Synopsis: Enumerates the values stored in an open registry key.
  370. //
  371. // Arguments: [pprvs] - SRegValueSet allocated and returned by this
  372. // method. The caller is responsible for releasing
  373. // the allocated CRegValue objects via delete and the
  374. // SRegValueSet structure via CMyRegKey::MemFree.
  375. //
  376. // Signals: none
  377. //
  378. // Returns: ERROR_SUCCESS on success. Else error from either Registry APIs
  379. // or from Memory allocation
  380. //
  381. // History: 09/30/92 Rickhi Created
  382. //
  383. // Notes: The data associated with each Value is not returned. The
  384. // caller may invoke the GetValue method of each CRegValue
  385. // returned to get it's associated data.
  386. //
  387. //--------------------------------------------------------------------------
  388. DWORD CMyRegKey::EnumValues(SRegValueSet **pprvs)
  389. {
  390. DWORD dwErr = ERROR_SUCCESS;
  391. // figure out how many values are currently stored in this key
  392. // and allocate a buffer to hold the return results.
  393. CHAR szClass[MAX_PATH];
  394. ULONG cbClass = sizeof(szClass);
  395. ULONG cSubKeys, cbMaxSubKeyLen, cbMaxClassLen;
  396. ULONG cValues, cbMaxValueIDLen, cbMaxValueLen;
  397. SECURITY_DESCRIPTOR SecDescriptor;
  398. FILETIME ft;
  399. DWORD dwRc = RegQueryInfoKey(_hkThis,
  400. szClass,
  401. &cbClass,
  402. NULL,
  403. &cSubKeys,
  404. &cbMaxSubKeyLen,
  405. &cbMaxClassLen,
  406. &cValues,
  407. &cbMaxValueIDLen,
  408. &cbMaxValueLen,
  409. (DWORD *)&SecDescriptor,
  410. &ft );
  411. if ( dwRc == ERROR_SUCCESS )
  412. {
  413. *pprvs = (SRegValueSet *) new BYTE [ sizeof(SRegValueSet)+
  414. cValues*sizeof(CRegValue *) ];
  415. if ( *pprvs == NULL )
  416. {
  417. dwErr = ERROR_OUTOFMEMORY;
  418. }
  419. }
  420. else
  421. {
  422. // QueryInfo failed.
  423. dwErr = Creg_ERROR(dwRc);
  424. }
  425. if (dwErr != ERROR_SUCCESS)
  426. {
  427. return(dwErr);
  428. }
  429. // loop enumerating and creating a RegValue object for each value
  430. DWORD dwIndex=0;
  431. do
  432. {
  433. CHAR szValueID[MAX_PATH];
  434. ULONG cbValueID = sizeof(szValueID);
  435. DWORD dwTypeCode;
  436. CRegValue *pRegVal;
  437. if ((dwRc = RegEnumValue(_hkThis, // handle
  438. dwIndex, // index
  439. szValueID, // value id
  440. &cbValueID, // length of value name
  441. NULL, // title index
  442. &dwTypeCode, // data type
  443. NULL, // data buffer
  444. NULL // size of data buffer
  445. ))==ERROR_SUCCESS)
  446. {
  447. // create the appropriate class of value object
  448. switch (dwTypeCode)
  449. {
  450. case REG_SZ:
  451. pRegVal = (CRegValue *) new CRegSZ((const CMyRegKey &)*this, szValueID);
  452. break;
  453. case REG_DWORD:
  454. pRegVal = (CRegValue *) new CRegDWORD((const CMyRegKey &)*this, szValueID);
  455. break;
  456. case REG_BINARY:
  457. pRegVal = (CRegValue *) new CRegBINARY((const CMyRegKey &)*this, szValueID);
  458. break;
  459. default:
  460. pRegVal = (CRegValue *) new CRegBINARY((const CMyRegKey &)*this, szValueID);
  461. break;
  462. }
  463. if (pRegVal == NULL) {
  464. dwRc = ERROR_OUTOFMEMORY;
  465. break;
  466. }
  467. // save ptr to value object and count another entry
  468. (*pprvs)->aprvValue[dwIndex++] = pRegVal;
  469. }
  470. else
  471. {
  472. // error, we're done with the enumeration
  473. break;
  474. }
  475. } while (dwIndex < cValues);
  476. // finished the enumeration, check the results
  477. if (dwRc == ERROR_NO_MORE_ITEMS || dwRc == ERROR_SUCCESS)
  478. {
  479. // set the return count
  480. (*pprvs)->cValues = dwIndex;
  481. }
  482. else
  483. {
  484. // Cleanup and return an error
  485. while (dwIndex)
  486. {
  487. if ((*pprvs)->aprvValue[--dwIndex])
  488. delete (*pprvs)->aprvValue[--dwIndex];
  489. }
  490. delete [] *pprvs;
  491. dwErr = Creg_ERROR(dwRc);
  492. }
  493. return(dwErr);
  494. }
  495. //+-------------------------------------------------------------------------
  496. //
  497. // Member: CMyRegKey::EnumKeys, public
  498. //
  499. // Synopsis: Enumerates the subkeys of an open registry key.
  500. //
  501. // Arguments: [pprks] - SRegKeySet allocated and returned by this method.
  502. // The caller is responsible for releasing all the
  503. // allocated CMyRegKey objects and the SRegKeySet
  504. // structure.
  505. //
  506. // Signals: none
  507. //
  508. // Returns: ERROR_SUCCESS on success. Else error from either Registry APIs
  509. // or from Memory allocation
  510. //
  511. // History: 09/30/92 Rickhi Created
  512. //
  513. // Notes:
  514. //
  515. //--------------------------------------------------------------------------
  516. DWORD CMyRegKey::EnumKeys(SRegKeySet **pprks)
  517. {
  518. // figure out how many keys are currently stored in this key
  519. // and allocate a buffer to hold the return results.
  520. CHAR szClass[MAX_PATH];
  521. ULONG cbClass = sizeof(szClass);
  522. ULONG cSubKeys, cbMaxSubKeyLen, cbMaxClassLen;
  523. ULONG cValues, cbMaxValueIDLen, cbMaxValueLen;
  524. SECURITY_DESCRIPTOR SecDescriptor;
  525. FILETIME ft;
  526. DWORD dwErr = ERROR_SUCCESS; // Error to return
  527. DWORD dwRc = ERROR_SUCCESS; // Error from registry APIs
  528. dwRc = RegQueryInfoKey(_hkThis,
  529. szClass,
  530. &cbClass,
  531. NULL,
  532. &cSubKeys,
  533. &cbMaxSubKeyLen,
  534. &cbMaxClassLen,
  535. &cValues,
  536. &cbMaxValueIDLen,
  537. &cbMaxValueLen,
  538. (DWORD *)&SecDescriptor,
  539. &ft);
  540. if ( dwRc == ERROR_SUCCESS )
  541. {
  542. *pprks = (SRegKeySet*) new BYTE [sizeof(SRegKeySet)+cSubKeys*sizeof(CMyRegKey *)];
  543. if ( *pprks == NULL )
  544. {
  545. dwErr = ERROR_OUTOFMEMORY;
  546. }
  547. }
  548. else
  549. {
  550. // QueryInfo failed..
  551. dwErr = Creg_ERROR(dwRc);
  552. }
  553. if (dwErr != ERROR_SUCCESS)
  554. {
  555. return(dwErr);
  556. }
  557. // loop enumerating and creating a RegKey object for each subkey
  558. DWORD dwIndex=0;
  559. do
  560. {
  561. CHAR szKeyName[MAX_PATH];
  562. ULONG cbKeyName = sizeof(szKeyName);
  563. CHAR szClass[MAX_PATH];
  564. ULONG cbClass = sizeof(szClass);
  565. FILETIME ft;
  566. if ((dwRc = RegEnumKeyEx(_hkThis, // handle
  567. dwIndex, // index
  568. szKeyName, // key name
  569. &cbKeyName, // length of key name
  570. NULL, // title index
  571. szClass, // class
  572. &cbClass, // length of class
  573. &ft // last write time
  574. ))==ERROR_SUCCESS)
  575. {
  576. // Create a CMyRegKey object for the subkey
  577. CMyRegKey *pRegKey = (CMyRegKey *) new CMyRegKey((const CMyRegKey &)*this, szKeyName);
  578. if(pRegKey == NULL) {
  579. dwErr = ERROR_OUTOFMEMORY;
  580. break;
  581. }
  582. if (ERROR_SUCCESS != (dwErr = pRegKey->QueryErrorStatus()))
  583. {
  584. break;
  585. }
  586. (*pprks)->aprkKey[dwIndex++] = pRegKey;
  587. }
  588. else
  589. {
  590. // error, we're done with the enumeration
  591. break;
  592. }
  593. } while (dwIndex < cSubKeys);
  594. // finished the enumeration, check the results
  595. if ((dwErr == ERROR_SUCCESS) &&
  596. ((dwRc == ERROR_NO_MORE_ITEMS || dwRc == ERROR_SUCCESS)))
  597. {
  598. // set the return count
  599. (*pprks)->cKeys = dwIndex;
  600. }
  601. else
  602. {
  603. // Cleanup and return an error
  604. while (dwIndex)
  605. {
  606. delete (*pprks)->aprkKey[--dwIndex];
  607. }
  608. delete [] *pprks;
  609. //
  610. // If there was a failure in a registry API call, return that error code
  611. // Otherwise dwErr must have been set to a failure code (for a non-registry failure)
  612. //
  613. if(dwRc != ERROR_SUCCESS)
  614. dwErr = Creg_ERROR(dwRc);
  615. }
  616. return(dwErr);
  617. }
  618. //+-------------------------------------------------------------------------
  619. //
  620. // Member: CRegValue::GetValue, public
  621. //
  622. // Purpose: Returns the data associated with a registry value.
  623. //
  624. // Arguements: [pbData] - ptr to buffer supplied by caller.
  625. // [cbData] - size of data buffer supplied.
  626. // [pdwTypeCode] - type of data returned.
  627. //
  628. // Signals:
  629. //
  630. // Returns: ERROR_SUCCESS on success. Else error from either Registry APIs
  631. // or from Memory allocation
  632. //
  633. // History: 09/30/92 Rickhi Created
  634. //
  635. // Notes:
  636. //
  637. //
  638. //
  639. //--------------------------------------------------------------------------
  640. DWORD CRegValue::GetValue(LPBYTE pbData, ULONG* pcbData, DWORD *pdwTypeCode)
  641. {
  642. DWORD dwRc = RegQueryValueEx(GetParentHandle(),
  643. (LPSTR)_cszValueID, // value id
  644. NULL, // title index
  645. pdwTypeCode, // type of data returned
  646. pbData, // data
  647. pcbData); // size of data
  648. return(dwRc);
  649. }
  650. //+-------------------------------------------------------------------------
  651. //
  652. // Member: CRegValue::SetValue
  653. //
  654. // Purpose: Writes the data associated with a registry value.
  655. //
  656. // Arguements: [pbData] - ptr to data to write.
  657. // [cbData] - size of data to write.
  658. // [dwTypeCode] - type of data to write.
  659. //
  660. // Signals: -none-
  661. //
  662. // Returns: ERROR_SUCCESS on success. Else error from either Registry APIs
  663. // or from Memory allocation
  664. //
  665. // History: 09/30/92 Rickhi Created
  666. //
  667. // Notes:
  668. //
  669. //--------------------------------------------------------------------------
  670. DWORD CRegValue::SetValue(const LPBYTE pbData, ULONG cbData, DWORD dwTypeCode)
  671. {
  672. DWORD dwRc;
  673. DWORD dwErr = ERROR_SUCCESS;
  674. if ((dwRc = RegSetValueEx(GetParentHandle(), // key handle
  675. (LPSTR)_cszValueID, // value id
  676. NULL, // title index
  677. dwTypeCode, // type of info in buffer
  678. pbData, // data
  679. cbData) // size of data
  680. )!= ERROR_SUCCESS)
  681. {
  682. dwErr = Creg_ERROR(dwRc);
  683. }
  684. return(dwErr);
  685. }
  686. //+-------------------------------------------------------------------------
  687. //
  688. // Function: DelRegKeyTree
  689. //
  690. // Purpose: Deletes a key and any of it's children. This is like
  691. // delnode for registry
  692. //
  693. // Arguements: [hParent] - Handle to Parent Key
  694. // [lpszKeyPath] - Path (relative to Parent) of the key
  695. //
  696. // Signals:
  697. //
  698. // Returns: ERROR_SUCCESS on success. Else error from either Registry APIs
  699. // or from Memory allocation
  700. //
  701. // History: 09/30/93 AlokS Created
  702. //
  703. // Notes:
  704. //
  705. //--------------------------------------------------------------------------
  706. DWORD DelRegKeyTree ( HKEY hParent, LPSTR lpszKeyPath)
  707. {
  708. DWORD dwErr = ERROR_SUCCESS;
  709. CMyRegKey cregKey ( hParent,
  710. lpszKeyPath
  711. );
  712. if (ERROR_SUCCESS != (dwErr = cregKey.QueryErrorStatus()))
  713. {
  714. return(dwErr);
  715. }
  716. // Enumerate the children of the key. We will
  717. // not propogate to the caller errors from enumeration
  718. SRegKeySet *pRegKeySet = NULL;
  719. if (ERROR_SUCCESS == (dwErr = cregKey.EnumKeys ( & pRegKeySet)))
  720. {
  721. // Now we have set of Keys which need to be deleted in depth
  722. // first manner
  723. for (ULONG i = 0; i < pRegKeySet->cKeys; i++ )
  724. {
  725. dwErr = DelRegKeyTree ( cregKey.GetHandle(),
  726. (LPSTR) pRegKeySet->aprkKey[i]->GetName()
  727. );
  728. // Delete the key itself
  729. delete pRegKeySet->aprkKey[i];
  730. }
  731. // Delete the enumerator structure
  732. delete pRegKeySet;
  733. }
  734. // Finally delete this key
  735. dwErr = cregKey.Delete();
  736. return(dwErr);
  737. }