winreg.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:17k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. #include "hxcom.h"
  36. #include "hxresult.h"
  37. #include "hxstring.h"
  38. #include "hxwinreg.h"
  39. #include "hxheap.h"
  40. #ifdef _DEBUG
  41. #undef HX_THIS_FILE
  42. static const char HX_THIS_FILE[] = __FILE__;
  43. #endif
  44. _CListOfCHXString_Node::_CListOfCHXString_Node()
  45.   : m_plocPrev(NULL)
  46.   , m_plocNext(NULL)
  47. {
  48. }
  49. _CListOfCHXString_Node::~_CListOfCHXString_Node()
  50. {
  51.     Remove();
  52. }
  53. void
  54. _CListOfCHXString_Node::Remove()
  55. {
  56.     if(m_plocPrev)
  57.     {
  58. m_plocPrev->next(m_plocNext);
  59.     }
  60.     if(m_plocNext)
  61.     {
  62. m_plocNext->prev(m_plocPrev);
  63.     }
  64. }
  65. void
  66. _CListOfCHXString_Node::Insert(_CListOfCHXString_Node& rlocnNew)
  67. {
  68.     rlocnNew.next(this);
  69.     rlocnNew.prev(m_plocPrev);
  70.     if(m_plocPrev)
  71.     {
  72. m_plocPrev->next(&rlocnNew);
  73.     }
  74.     m_plocPrev = &rlocnNew;
  75. }
  76. CHXString&
  77. _CListOfCHXString_Node::value()
  78. {
  79.     return m_clsValue;
  80. }
  81. const CHXString&
  82. _CListOfCHXString_Node::value() const
  83. {
  84.     return m_clsValue;
  85. }
  86. void
  87. _CListOfCHXString_Node::value(const CHXString& rclsNewValue)
  88. {
  89.     m_clsValue = rclsNewValue;
  90. }
  91. _CListOfCHXString_Node&
  92. _CListOfCHXString_Node::operator=(const CHXString& rclsNewValue)
  93. {
  94.     m_clsValue = rclsNewValue;
  95.     return *this;
  96. }
  97. _CListOfCHXString_Node*
  98. _CListOfCHXString_Node::next() const
  99. {
  100.     return m_plocNext;
  101. }
  102. void
  103. _CListOfCHXString_Node::next(_CListOfCHXString_Node* plocnNew)
  104. {
  105.     m_plocNext = plocnNew;
  106. }
  107. _CListOfCHXString_Node*
  108. _CListOfCHXString_Node::prev() const
  109. {
  110.     return m_plocPrev;
  111. }
  112. void
  113. _CListOfCHXString_Node::prev(_CListOfCHXString_Node* plocnNew)
  114. {
  115.     m_plocPrev = plocnNew;
  116. }
  117. _CListOfCHXString_::_CListOfCHXString_()
  118. {
  119.     m_locnREnd.next(&m_locnEnd);
  120.     m_locnEnd.prev(&m_locnREnd);
  121. }
  122. _CListOfCHXString_::_CListOfCHXString_(const _CListOfCHXString_& rlocOther)
  123. {
  124.     m_locnREnd.next(&m_locnEnd);
  125.     m_locnEnd.prev(&m_locnREnd);
  126.     _copy(rlocOther);
  127. }
  128. _CListOfCHXString_::~_CListOfCHXString_()
  129. {
  130.     empty();
  131. }
  132. _CListOfCHXString_&
  133. _CListOfCHXString_::operator=(const _CListOfCHXString_& rlocOther)
  134. {
  135.     empty();
  136.     _copy(rlocOther);
  137.     return *this;
  138. }
  139. void
  140. _CListOfCHXString_::_copy(const _CListOfCHXString_& rlocOther)
  141. {
  142.     iterator itOther;
  143.     for
  144.     (
  145. itOther = rlocOther.begin();
  146. itOther != rlocOther.end();
  147. ++itOther
  148.     )
  149.     {
  150. insert(end(), *itOther);
  151.     }
  152. }
  153. _CListOfCHXString_::iterator
  154. _CListOfCHXString_::begin()
  155. {
  156.     return iterator(*(m_locnREnd.next()));
  157. }
  158. const _CListOfCHXString_::iterator
  159. _CListOfCHXString_::begin() const
  160. {
  161.     return iterator(*(m_locnREnd.next()));
  162. }
  163. _CListOfCHXString_::iterator
  164. _CListOfCHXString_::end()
  165. {
  166.     return iterator(m_locnEnd);
  167. }
  168. const _CListOfCHXString_::iterator
  169. _CListOfCHXString_::end() const
  170. {
  171.     return iterator(m_locnEnd);
  172. }
  173. _CListOfCHXString_::reverse_iterator
  174. _CListOfCHXString_::rbegin()
  175. {
  176.     return reverse_iterator(*(m_locnEnd.prev()));
  177. }
  178. const _CListOfCHXString_::reverse_iterator 
  179. _CListOfCHXString_::rbegin() const
  180. {
  181.     return const_reverse_iterator(*(m_locnEnd.prev()));
  182. }
  183. _CListOfCHXString_::reverse_iterator
  184. _CListOfCHXString_::rend()
  185. {
  186.     return reverse_iterator(m_locnREnd);
  187. }
  188. const _CListOfCHXString_::reverse_iterator
  189. _CListOfCHXString_::rend() const
  190. {
  191.     return const_reverse_iterator(*((const _CListOfCHXString_Node *)&m_locnREnd));
  192. }
  193. _CListOfCHXString_::iterator
  194. _CListOfCHXString_::insert(iterator itBefore, const CHXString& rclsNew)
  195. {
  196.     _CListOfCHXString_Node* plocnNew = new _CListOfCHXString_Node;
  197.     HX_ASSERT(plocnNew);
  198.     *plocnNew = rclsNew;
  199.     itBefore.m_plocCurrent->Insert(*plocnNew);
  200.     return iterator(*plocnNew);
  201. }
  202. void
  203. _CListOfCHXString_::insert
  204. (
  205.     iterator itBefore,
  206.     const iterator itFirst,
  207.     const iterator itLast
  208. )
  209. {
  210.     iterator itOther;
  211.     _CListOfCHXString_Node* plocnNew;
  212.     for (itOther = itFirst; itOther != itLast; ++itOther)
  213.     {
  214. plocnNew = new _CListOfCHXString_Node;
  215. HX_ASSERT(plocnNew);
  216. *plocnNew = *itOther;
  217. itBefore.m_plocCurrent->Insert(*plocnNew);
  218.     }
  219. }
  220. void
  221. _CListOfCHXString_::remove(iterator itThis)
  222. {
  223.     if
  224.     (
  225. itThis.m_plocCurrent == &m_locnEnd ||
  226. itThis.m_plocCurrent == &m_locnREnd
  227.     )
  228.     {
  229. return;
  230.     }
  231.     _CListOfCHXString_Node* plocnOld;
  232.     plocnOld = itThis.m_plocCurrent;
  233.     ++itThis;
  234.     plocnOld->Remove();
  235.     delete plocnOld;
  236. }
  237. void
  238. _CListOfCHXString_::remove(iterator itFirst, iterator itLast)
  239. {
  240.     if
  241.     (
  242. itFirst.m_plocCurrent == &m_locnEnd ||
  243. itFirst.m_plocCurrent == &m_locnREnd
  244.     )
  245.     {
  246. return;
  247.     }
  248.     iterator itOther;
  249.     _CListOfCHXString_Node* plocnOld;
  250.     for (itOther = itFirst; itOther != itLast;)
  251.     {
  252. plocnOld = itOther.m_plocCurrent;
  253. ++itOther;
  254. plocnOld->Remove();
  255. delete plocnOld;
  256.     }
  257. }
  258. void
  259. _CListOfCHXString_::empty()
  260. {
  261.     remove(begin(), end());
  262. }
  263. _CListIteratorCHXString_::_CListIteratorCHXString_()
  264.   : m_plocCurrent(NULL)
  265. {
  266. }
  267. _CListIteratorCHXString_::_CListIteratorCHXString_
  268. (
  269.     const _CListOfCHXString_Node& rlocnNewLocation
  270. )
  271.   : m_plocCurrent((_CListOfCHXString_Node*)&rlocnNewLocation)
  272. {
  273. }
  274. _CListIteratorCHXString_::_CListIteratorCHXString_
  275. (
  276.     const _CListIteratorCHXString_& rliocOther
  277. )
  278.   : m_plocCurrent(rliocOther.m_plocCurrent)
  279. {
  280. }
  281. _CListIteratorCHXString_::~_CListIteratorCHXString_()
  282. {
  283. }
  284. _CListIteratorCHXString_&
  285. _CListIteratorCHXString_::operator=
  286. (
  287.     const _CListIteratorCHXString_& rliocOther
  288. )
  289. {
  290.     m_plocCurrent = rliocOther.m_plocCurrent;
  291.     return *this;
  292. }
  293. CHXString&
  294. _CListIteratorCHXString_::operator*()
  295. {
  296.     HX_ASSERT(m_plocCurrent);
  297.     return m_plocCurrent->value();
  298. }
  299. _CListIteratorCHXString_&
  300. _CListIteratorCHXString_::operator=(const CHXString& rclsNewValue)
  301. {
  302.     if(!m_plocCurrent)
  303. return *this;
  304.     m_plocCurrent->value(rclsNewValue);
  305.     return *this;
  306. }
  307. _CListIteratorCHXString_&
  308. _CListIteratorCHXString_::operator++()
  309. {
  310.     if(!m_plocCurrent)
  311. return *this;
  312.     m_plocCurrent = m_plocCurrent->next();
  313.     return *this;
  314. }
  315. const _CListIteratorCHXString_
  316. _CListIteratorCHXString_::operator++(int)
  317. {
  318.     _CListIteratorCHXString_ liocRet(*this);
  319.     ++(*this);
  320.     return liocRet;
  321. }
  322. _CListIteratorCHXString_&
  323. _CListIteratorCHXString_::operator--()
  324. {
  325.     if(!m_plocCurrent)
  326. return *this;
  327.     m_plocCurrent = m_plocCurrent->prev();
  328.     return *this;
  329. }
  330. const _CListIteratorCHXString_
  331. _CListIteratorCHXString_::operator--(int)
  332. {
  333.     _CListIteratorCHXString_ liocRet(*this);
  334.     --(*this);
  335.     return liocRet;
  336. }
  337. BOOL operator==
  338. (
  339.     const _CListIteratorCHXString_& rliocLeft,
  340.     const _CListIteratorCHXString_& rliocRight
  341. )
  342. {
  343.     return (rliocLeft.m_plocCurrent == rliocRight.m_plocCurrent);
  344. }
  345. BOOL operator!=
  346. (
  347.     const _CListIteratorCHXString_& rliocLeft,
  348.     const _CListIteratorCHXString_& rliocRight
  349. )
  350. {
  351.     return (rliocLeft.m_plocCurrent != rliocRight.m_plocCurrent);
  352. }
  353. _CListReverseIteratorCHXString_::_CListReverseIteratorCHXString_()
  354.   : m_plocCurrent(NULL)
  355. {
  356. }
  357. _CListReverseIteratorCHXString_::_CListReverseIteratorCHXString_
  358. (
  359.     const _CListOfCHXString_Node& rlocnNewLocation
  360. )
  361.   : m_plocCurrent((_CListOfCHXString_Node*)&rlocnNewLocation)
  362. {
  363. }
  364. _CListReverseIteratorCHXString_::_CListReverseIteratorCHXString_
  365. (
  366.     _CListReverseIteratorCHXString_& rlriocOther
  367. )
  368.   : m_plocCurrent(rlriocOther.m_plocCurrent)
  369. {
  370. }
  371. _CListReverseIteratorCHXString_::~_CListReverseIteratorCHXString_()
  372. {
  373. }
  374. _CListReverseIteratorCHXString_&
  375. _CListReverseIteratorCHXString_::operator=
  376. (
  377.     const _CListReverseIteratorCHXString_& rlriocOther
  378. )
  379. {
  380.     m_plocCurrent = rlriocOther.m_plocCurrent;
  381.     return *this;
  382. }
  383. CHXString&
  384. _CListReverseIteratorCHXString_::operator*()
  385. {
  386.     HX_ASSERT(m_plocCurrent);
  387.     return m_plocCurrent->value();
  388. }
  389. _CListReverseIteratorCHXString_&
  390. _CListReverseIteratorCHXString_::operator=(const CHXString& rclsNewValue)
  391. {
  392.     if(!m_plocCurrent)
  393. return *this;
  394.     m_plocCurrent->value(rclsNewValue);
  395.     return *this;
  396. }
  397. _CListReverseIteratorCHXString_&
  398. _CListReverseIteratorCHXString_::operator++()
  399. {
  400.     if(!m_plocCurrent)
  401. return *this;
  402.     m_plocCurrent = m_plocCurrent->prev();
  403.     return *this;
  404. }
  405. const _CListReverseIteratorCHXString_
  406. _CListReverseIteratorCHXString_::operator++(int)
  407. {
  408.     _CListReverseIteratorCHXString_ lriocRet(*this);
  409.     ++(*this);
  410.     return lriocRet;
  411. }
  412. _CListReverseIteratorCHXString_&
  413. _CListReverseIteratorCHXString_::operator--()
  414. {
  415.     if(!m_plocCurrent)
  416. return *this;
  417.     m_plocCurrent = m_plocCurrent->next();
  418.     return *this;
  419. }
  420. const _CListReverseIteratorCHXString_
  421. _CListReverseIteratorCHXString_::operator--(int)
  422. {
  423.     _CListReverseIteratorCHXString_ lriocRet(*this);
  424.     --(*this);
  425.     return lriocRet;
  426. }
  427. BOOL operator==
  428. (
  429.     const _CListReverseIteratorCHXString_& rlriocLeft,
  430.     const _CListReverseIteratorCHXString_& rlriocRight
  431. )
  432. {
  433.     return (rlriocLeft.m_plocCurrent == rlriocRight.m_plocCurrent);
  434. }
  435. BOOL operator!=
  436. (
  437.     const _CListReverseIteratorCHXString_& rlriocLeft,
  438.     const _CListReverseIteratorCHXString_& rlriocRight
  439. )
  440. {
  441.     return (rlriocLeft.m_plocCurrent != rlriocRight.m_plocCurrent);
  442. }
  443. CWinRegKey::CWinRegKey()
  444.     : m_hkRoot(NULL)
  445.     , m_hkThis(NULL)
  446.     , m_dwKeyEnumPos(0)
  447.     , m_dwValueEnumPos(0)
  448.     , m_rsAccess(KEY_READ)
  449.     , m_bOpen(FALSE)
  450. {
  451. }
  452. CWinRegKey::~CWinRegKey()
  453. {
  454.     Close();
  455. }
  456. HX_RESULT 
  457. CWinRegKey::Open()
  458. {
  459.     if(!m_hkRoot || m_sPath.IsEmpty())
  460.     {
  461. return HXR_UNEXPECTED;
  462.     }
  463.     Close();
  464.     HX_RESULT pnrRes = HXR_FAIL;
  465.     if
  466.     (
  467. SUCCEEDED
  468. (
  469.     pnrRes = HRESULT_FROM_WIN32
  470.     (
  471. RegOpenKeyEx
  472. (
  473.     m_hkRoot,
  474.     OS_STRING(m_sPath),
  475.     0,
  476.     m_rsAccess,
  477.     &m_hkThis
  478. )
  479.     )
  480. )
  481.     )
  482.     {
  483. m_bOpen = TRUE;
  484.     }
  485.     return pnrRes;
  486. }
  487. HX_RESULT 
  488. CWinRegKey::Create(const char* szClass, DWORD dwOptions)
  489. {
  490.     if(!m_hkRoot || m_sPath.IsEmpty())
  491.     {
  492. return HXR_UNEXPECTED;
  493.     }
  494.     Close();
  495.     DWORD dwIngnored;
  496.     if
  497.     (
  498. RegCreateKeyEx
  499. (
  500.     m_hkRoot,
  501.     OS_STRING(m_sPath),
  502.     0,
  503.     OS_STRING(szClass),
  504.     dwOptions,
  505.     m_rsAccess,
  506.     NULL,
  507.     &m_hkThis,
  508.     &dwIngnored
  509. )
  510. ==
  511. ERROR_SUCCESS
  512.     )
  513.     {
  514. m_bOpen = TRUE;
  515. return HXR_OK;
  516.     }
  517.     return HXR_FAIL;
  518. }
  519. HX_RESULT 
  520. CWinRegKey::Close()
  521. {
  522.     if(!m_bOpen)
  523.     {
  524. return HXR_UNEXPECTED;
  525.     }
  526.     if
  527.     (
  528. RegCloseKey(m_hkThis)
  529. ==
  530. ERROR_SUCCESS
  531.     )
  532.     {
  533. m_bOpen = FALSE;
  534. return HXR_OK;
  535.     }
  536.     return HXR_FAIL;
  537. }
  538. HX_RESULT 
  539. CWinRegKey::Flush()
  540. {
  541.     if(!m_bOpen)
  542.     {
  543. return HXR_UNEXPECTED;
  544.     }
  545.     if
  546.     (
  547. RegFlushKey(m_hkThis)
  548. ==
  549. ERROR_SUCCESS
  550.     )
  551.     {
  552. return HXR_OK;
  553.     }
  554.     return HXR_FAIL;
  555. }
  556. HX_RESULT 
  557. CWinRegKey::DeleteSubKey(const char* szName)
  558. {
  559.     if(!m_bOpen)
  560.     {
  561. return HXR_UNEXPECTED;
  562.     }
  563.     HX_RESULT pnrRes = HXR_FAIL;
  564.     CWinRegKey wrkExpired;
  565.     CWinRegKey wrkSub;
  566.     wrkExpired.SetRootKey(m_hkThis);
  567.     wrkExpired.SetRelativePath(szName);
  568.     wrkExpired.SetDesiredAccess(KEY_ENUMERATE_SUB_KEYS|KEY_CREATE_SUB_KEY);
  569.     if (SUCCEEDED(pnrRes = wrkExpired.Open()))
  570.     {
  571. wrkExpired.ResetKeyEnumerator();
  572. while(wrkExpired.GetNextKey(wrkSub))
  573. {
  574.     wrkExpired.DeleteSubKey(wrkSub.GetRelativePath());
  575.     wrkExpired.ResetKeyEnumerator();
  576. }
  577. wrkExpired.Close();
  578. pnrRes = HRESULT_FROM_WIN32(RegDeleteKey(m_hkThis, OS_STRING(szName)));
  579.     }
  580.     return pnrRes;
  581. }
  582. BOOL 
  583. CWinRegKey::DoesExist()
  584. {
  585.     if(m_bOpen)
  586.     {
  587. return TRUE;
  588.     }
  589.     if(SUCCEEDED(Open()))
  590.     {
  591. Close();
  592. return TRUE;
  593.     }
  594.     return FALSE;
  595. }
  596. BOOL 
  597. CWinRegKey::SetDesiredAccess(REGSAM rsNew)
  598. {
  599.     if(m_bOpen)
  600.     {
  601. return FALSE;
  602.     }
  603.     m_rsAccess = rsNew;
  604.     return TRUE;
  605. }
  606. REGSAM 
  607. CWinRegKey::GetDesiredAccess()
  608. {
  609.     return m_rsAccess;
  610. }
  611. BOOL 
  612. CWinRegKey::SetRootKey(HKEY hkRoot)
  613. {
  614.     if(m_bOpen)
  615.     {
  616. return FALSE;
  617.     }
  618.     m_hkRoot = hkRoot;
  619.     return TRUE;
  620. }
  621. HKEY 
  622. CWinRegKey::GetRootKey()
  623. {
  624.     return m_hkRoot;
  625. }
  626. HKEY 
  627. CWinRegKey::GetHandle()
  628. {
  629.     return m_hkThis;
  630. }
  631. // According to Article ID: Q117261
  632. //
  633. // A call to RegCreateKeyEx() is successful under Windows NT version 3.1 
  634. // and Windows 95, but the call fails with error 161 (ERROR_BAD_PATHNAME) 
  635. // under Windows NT version 3.5 and later. 
  636. //
  637. // This is by design. Windows NT version 3.1 and Windows 95 allow the 
  638. // subkey to begin with a backslash (""), however Windows NT version 3.5 
  639. // and later do not. The subkey is given as the second parameter to 
  640. // RegCreateKeyEx(). 
  641. //
  642. BOOL 
  643. CWinRegKey::SetRelativePath(const char* szPath)
  644. {
  645.     if(m_bOpen)
  646.     {
  647. return FALSE;
  648.     }
  649.     if (*szPath == '\')
  650.     {
  651. m_sPath = szPath+1;
  652.     }
  653.     else
  654.     {
  655. m_sPath = szPath;
  656.     }
  657.     return TRUE;
  658. }
  659. CHXString& 
  660. CWinRegKey::GetRelativePath()
  661. {
  662.     return m_sPath;
  663. }
  664. BOOL 
  665. CWinRegKey::GetValue
  666. (
  667.     const char* szName, 
  668.     AWinRegValue** ppwrvOut, 
  669.     UINT32 ulType
  670. )
  671. {
  672.     if
  673.     (
  674. !m_bOpen 
  675. || 
  676. !szName 
  677. || 
  678. !(*szName)
  679. ||
  680. !ppwrvOut
  681.     )
  682.     {
  683. return FALSE;
  684.     }
  685.     *ppwrvOut = NULL;
  686.     if (!ulType)
  687.     {
  688. if
  689. (
  690.     RegQueryValueEx
  691.     (
  692. m_hkThis,
  693. OS_STRING(szName),
  694. NULL,
  695. &ulType,
  696. NULL,
  697. NULL
  698.     )
  699.     !=
  700.     ERROR_SUCCESS
  701. )
  702. {
  703.     return FALSE;
  704. }
  705.     }
  706.     switch(ulType)
  707.     {
  708.     case REG_DWORD:
  709. {
  710.     *ppwrvOut = (AWinRegValue*)new CWinRegDWORDValue
  711.     (
  712. szName, 
  713. m_hkThis
  714.     );
  715. }
  716. break;
  717.     case REG_SZ:
  718. {
  719.     *ppwrvOut = (AWinRegValue*)new CWinRegStringValue
  720.     (
  721. szName, 
  722. m_hkThis
  723.     );
  724. }
  725. break;
  726.     case REG_MULTI_SZ:
  727. {
  728.     *ppwrvOut = (AWinRegValue*)new CWinRegStringArrayValue
  729.     (
  730. szName, 
  731. m_hkThis
  732.     );
  733. }
  734. break;
  735.     default:
  736. {
  737. }
  738. break;
  739.     };
  740.     
  741.     return (*ppwrvOut)?TRUE:FALSE;
  742. }
  743. void 
  744. CWinRegKey::FreeValue(AWinRegValue*& pwrvExpired)
  745. {
  746.     delete pwrvExpired;
  747.     pwrvExpired = NULL;
  748. }
  749. BOOL 
  750. CWinRegKey::ResetKeyEnumerator()
  751. {
  752.     if(!m_bOpen)
  753.     {
  754. return FALSE;
  755.     }
  756.     m_dwKeyEnumPos = 0;
  757.     return TRUE;
  758. }
  759. BOOL 
  760. CWinRegKey::GetNextKey(CWinRegKey& rwrkNext)
  761. {
  762.     if(!m_bOpen)
  763.     {
  764. return FALSE;
  765.     }
  766.     
  767.     char szName[128]; /* Flawfinder: ignore */
  768.     UINT32 ulSizeName=128;
  769.     char szClass[128]; /* Flawfinder: ignore */
  770.     UINT32 ulSizeClass=128;
  771.     FILETIME ftLastWrite;
  772.     if
  773.     (
  774. RegEnumKeyEx
  775. (
  776.     m_hkThis,
  777.     m_dwKeyEnumPos,
  778.     OS_STRING2(szName, ulSizeName),
  779.     &ulSizeName,
  780.     NULL,
  781.     OS_STRING2(szClass, ulSizeClass),
  782.     &ulSizeClass,
  783.     &ftLastWrite
  784. )
  785. ==
  786. ERROR_SUCCESS
  787.     )
  788.     {
  789. ++m_dwKeyEnumPos;
  790. rwrkNext.SetRootKey(m_hkThis);
  791. rwrkNext.SetRelativePath(szName);
  792. rwrkNext.SetDesiredAccess(m_rsAccess);
  793. return TRUE;
  794.     }
  795.     return FALSE;
  796. }
  797. BOOL 
  798. CWinRegKey::ResetValueEnumerator()
  799. {
  800.     if(!m_bOpen)
  801.     {
  802. return FALSE;
  803.     }
  804.     m_dwValueEnumPos = 0;
  805.     return TRUE;
  806. }
  807. BOOL 
  808. CWinRegKey::GetNextValue(AWinRegValue** ppwrvNext)
  809. {
  810.     if(!m_bOpen)
  811.     {
  812. return FALSE;
  813.     }
  814.     char szName[128]; /* Flawfinder: ignore */
  815.     UINT32 ulSizeName=128;
  816.     UINT32 ulType;
  817.     if
  818.     (
  819. RegEnumValue
  820. (
  821.     m_hkThis,
  822.     m_dwValueEnumPos,
  823.     OS_STRING2(szName, ulSizeName),
  824.     &ulSizeName,
  825.     NULL,
  826.     &ulType,
  827.     NULL,
  828.     NULL
  829. )
  830. ==
  831. ERROR_SUCCESS
  832.     )
  833.     {
  834. ++m_dwValueEnumPos;
  835. return GetValue(szName, ppwrvNext, ulType);
  836.     }
  837.     return FALSE;
  838. }