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.

843 lines
21 KiB

  1. #include "stdafx.h"
  2. // defined with iisrtl2.lib
  3. //DEBUG_PRINTS * g_pDebug;
  4. // open an existing key
  5. // if failure, return NULL pointer and put error into SetLastError();
  6. CRegKey :: CRegKey (HKEY hKeyBase, LPCTSTR pchSubKey,REGSAM regSam ) : m_hKey( NULL ), m_dwDisposition( 0 )
  7. {
  8. LONG err = ERROR_SUCCESS ;
  9. SetLastError(ERROR_SUCCESS);
  10. m_iDisplayWarnings = TRUE;
  11. if ( pchSubKey )
  12. {err = ::RegOpenKeyEx( hKeyBase, pchSubKey, 0, regSam, & m_hKey ) ;}
  13. else
  14. {m_hKey = hKeyBase ;}
  15. if ( err != ERROR_SUCCESS )
  16. {
  17. if (m_hKey) {::RegCloseKey(m_hKey);}
  18. m_hKey = NULL ;
  19. // Check if the error is because it simply doesn't exist.
  20. // if this is the case then don't say failed. Say WARNING.
  21. if ( err == ERROR_FILE_NOT_FOUND )
  22. {
  23. if (m_iDisplayWarnings)
  24. {iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("CRegKey:CRegKey() %s Key doesn't exist. WARNING. Code=0x%x\n"), pchSubKey, err));}
  25. }
  26. else
  27. {
  28. iisDebugOut((LOG_TYPE_ERROR, _T("CRegKey:CRegKey() %s FAILED. Err=0x%x\n"), pchSubKey, err));
  29. }
  30. SetLastError(err);
  31. }
  32. }
  33. // Constructor creating a new key/opening a key if already exist, and set value if specified
  34. CRegKey :: CRegKey (LPCTSTR lpSubKey,HKEY hKeyBase,LPCTSTR lpValueName,DWORD dwType,LPBYTE lpValueData,DWORD cbValueData): m_hKey( NULL ),m_dwDisposition( 0 )
  35. {
  36. LONG err = ERROR_SUCCESS;
  37. SetLastError(ERROR_SUCCESS);
  38. m_iDisplayWarnings = TRUE;
  39. err = ::RegCreateKeyEx( hKeyBase, lpSubKey, 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, & m_hKey, & m_dwDisposition ) ;
  40. if ( err != ERROR_SUCCESS)
  41. {
  42. if ( m_hKey ) {::RegCloseKey( m_hKey ) ;}
  43. m_hKey = NULL ;
  44. // Check if the error is because it simply doesn't exist.
  45. // if this is the case then don't say failed. Say WARNING.
  46. if ( err == ERROR_FILE_NOT_FOUND )
  47. {
  48. if (m_iDisplayWarnings)
  49. {iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("CRegKey:CRegKey() %s Key doesn't exist. WARNING. Code=0x%x\n"), lpSubKey, err));}
  50. }
  51. else
  52. {
  53. iisDebugOut((LOG_TYPE_ERROR, _T("CRegKey::CRegKey() Open %s FAILED. err=0x%x\n"), lpSubKey, err));
  54. }
  55. SetLastError(err);
  56. }
  57. else
  58. {
  59. if (lpValueName)
  60. {
  61. ::RegSetValueEx(m_hKey, lpValueName, 0, dwType, (const LPBYTE)lpValueData, cbValueData);
  62. if ( err != ERROR_SUCCESS)
  63. {
  64. iisDebugOut((LOG_TYPE_ERROR, _T("CRegKey::CRegKey() RegSetValueEx %s, %s FAILED. err=0x%x\n"), lpSubKey,lpValueName, err));
  65. SetLastError(err);
  66. }
  67. }
  68. }
  69. }
  70. CRegKey :: ~ CRegKey ()
  71. {
  72. if (m_hKey) {::RegCloseKey( m_hKey );}
  73. }
  74. // Prepare to read a value by finding the value's size.
  75. LONG CRegKey :: PrepareValue (LPCTSTR pchValueName, DWORD * pdwType,DWORD * pcbSize,BYTE ** ppbData )
  76. {
  77. LONG err = 0 ;
  78. BYTE chDummy[2] ;
  79. DWORD cbData = 0 ;
  80. do
  81. {
  82. // Set the resulting buffer size to 0.
  83. *pcbSize = 0 ;
  84. *ppbData = NULL ;
  85. err = ::RegQueryValueEx( *this, (TCHAR *) pchValueName, 0, pdwType, chDummy, & cbData ) ;
  86. // The only error we should get here is ERROR_MORE_DATA, but
  87. // we may get no error if the value has no data.
  88. if ( err == 0 )
  89. {
  90. cbData = sizeof (LONG) ; // Just a fudgy number
  91. }
  92. else
  93. if ( err != ERROR_MORE_DATA )
  94. break ;
  95. // Allocate a buffer large enough for the data.
  96. *ppbData = new BYTE [ (*pcbSize = cbData) + sizeof (LONG) ] ;
  97. if ( *ppbData == NULL )
  98. {
  99. err = ERROR_NOT_ENOUGH_MEMORY ;
  100. break ;
  101. }
  102. // Now that have a buffer, re-fetch the value.
  103. err = ::RegQueryValueEx( *this, (TCHAR *) pchValueName, 0, pdwType, *ppbData, pcbSize ) ;
  104. } while ( FALSE ) ;
  105. if ( err ) {delete [] *ppbData ;}
  106. return err ;
  107. }
  108. // Overloaded value query members; each returns ERROR_INVALID_PARAMETER
  109. // if data exists but not in correct form to deliver into result object.
  110. LONG CRegKey :: QueryValue ( LPCTSTR pchValueName, CString & strResult )
  111. {
  112. LONG err = 0 ;
  113. DWORD dwType ;
  114. DWORD cbData ;
  115. BYTE * pabData = NULL ;
  116. do
  117. {
  118. err = PrepareValue( pchValueName, & dwType, & cbData, & pabData );
  119. if ( err )
  120. {
  121. break;
  122. }
  123. if (( dwType != REG_SZ ) && ( dwType != REG_EXPAND_SZ ))
  124. {
  125. err = ERROR_INVALID_PARAMETER ;
  126. break ;
  127. }
  128. // Guarantee that the data looks like a string
  129. pabData[cbData] = 0 ;
  130. // Catch exceptions trying to assign to the caller's string
  131. TRY
  132. {
  133. strResult = (TCHAR *) pabData ;
  134. }
  135. CATCH_ALL(e)
  136. {
  137. err = ERROR_NOT_ENOUGH_MEMORY ;
  138. }
  139. END_CATCH_ALL
  140. }
  141. while ( FALSE ) ;
  142. // Memory leak....
  143. //if ( err )
  144. //{
  145. delete [] pabData ;
  146. //}
  147. if (err)
  148. {
  149. if ( err == ERROR_FILE_NOT_FOUND )
  150. {
  151. if (m_iDisplayWarnings)
  152. {iisDebugOut((LOG_TYPE_WARN, _T("CRegKey::QueryValue(): %s Not found. WARNING. code=0x%x\n"), pchValueName, err));}
  153. }
  154. else
  155. {
  156. if (err != ERROR_INVALID_PARAMETER)
  157. {
  158. iisDebugOut((LOG_TYPE_ERROR, _T("CRegKey::QueryValue(): %s FAILED. err=0x%x\n"), pchValueName, err));
  159. }
  160. }
  161. }
  162. return err ;
  163. }
  164. LONG CRegKey :: QueryValue ( LPCTSTR pchValueName, CStringList & strList )
  165. {
  166. LONG err = 0 ;
  167. DWORD dwType ;
  168. DWORD cbData ;
  169. BYTE * pabData = NULL ;
  170. TCHAR * pbTemp, * pbTempLimit ;
  171. do
  172. {
  173. err = PrepareValue( pchValueName, & dwType, & cbData, & pabData );
  174. if ( err != 0 )
  175. {
  176. break ;
  177. }
  178. if ( dwType != REG_MULTI_SZ )
  179. {
  180. err = ERROR_INVALID_PARAMETER ;
  181. break ;
  182. }
  183. // Guarantee that the trailing data looks like a string
  184. pabData[cbData] = 0 ;
  185. pbTemp = (TCHAR *) pabData ;
  186. pbTempLimit = (TCHAR *) (& pabData[cbData]) ;
  187. // Catch exceptions trying to build the list
  188. TRY
  189. {
  190. for ( ; pbTemp < pbTempLimit ; )
  191. {
  192. strList.AddTail( pbTemp ) ;
  193. pbTemp += ::_tcslen( pbTemp ) + 1 ;
  194. }
  195. }
  196. CATCH_ALL(e)
  197. {
  198. err = ERROR_NOT_ENOUGH_MEMORY ;
  199. }
  200. END_CATCH_ALL
  201. }
  202. while ( FALSE ) ;
  203. delete [] pabData ;
  204. if (err)
  205. {
  206. if ( err == ERROR_FILE_NOT_FOUND )
  207. {
  208. if (m_iDisplayWarnings)
  209. {iisDebugOut((LOG_TYPE_WARN, _T("CRegKey::QueryValue(): %s Not found. WARNING. code=0x%x\n"), pchValueName, err));}
  210. }
  211. else
  212. {
  213. if (err != ERROR_INVALID_PARAMETER)
  214. {
  215. iisDebugOut((LOG_TYPE_ERROR, _T("CRegKey::QueryValue(): %s FAILED. err=0x%x.\n"), pchValueName, err));
  216. }
  217. }
  218. }
  219. return err ;
  220. }
  221. LONG CRegKey :: QueryValue ( LPCTSTR pchValueName, DWORD & dwResult )
  222. {
  223. LONG err = 0 ;
  224. DWORD dwType ;
  225. DWORD cbData ;
  226. BYTE * pabData = NULL ;
  227. do
  228. {
  229. err = PrepareValue( pchValueName, & dwType, & cbData, & pabData );
  230. if ( err != 0 )
  231. break ;
  232. if ( dwType != REG_DWORD || cbData != sizeof dwResult )
  233. {
  234. err = ERROR_INVALID_PARAMETER ;
  235. break ;
  236. }
  237. dwResult = *((DWORD *) pabData) ;
  238. }
  239. while ( FALSE ) ;
  240. // Memory leak...
  241. //if ( err )
  242. //{
  243. delete [] pabData ;
  244. //}
  245. if (err)
  246. {
  247. if ( err == ERROR_FILE_NOT_FOUND )
  248. {
  249. if (m_iDisplayWarnings)
  250. {iisDebugOut((LOG_TYPE_WARN, _T("CRegKey::QueryValue(): %s Not found. WARNING. code=0x%x\n"), pchValueName, err));}
  251. }
  252. else
  253. {
  254. if (err != ERROR_INVALID_PARAMETER)
  255. {
  256. iisDebugOut((LOG_TYPE_ERROR, _T("CRegKey::QueryValue(): %s FAILED. err=0x%x.\n"), pchValueName, err));
  257. }
  258. }
  259. }
  260. return err ;
  261. }
  262. LONG CRegKey :: QueryValue ( LPCTSTR pchValueName, CByteArray & abResult )
  263. {
  264. LONG err = 0 ;
  265. DWORD dwType ;
  266. DWORD cbData ;
  267. BYTE * pabData = NULL ;
  268. do
  269. {
  270. err = PrepareValue( pchValueName, & dwType, & cbData, & pabData );
  271. if ( err != 0 )
  272. {
  273. break ;
  274. }
  275. if ( dwType != REG_BINARY )
  276. {
  277. err = ERROR_INVALID_PARAMETER ;
  278. break ;
  279. }
  280. // Catch exceptions trying to grow the result array
  281. TRY
  282. {
  283. abResult.SetSize( cbData ) ;
  284. }
  285. CATCH_ALL(e)
  286. {
  287. err = ERROR_NOT_ENOUGH_MEMORY ;
  288. }
  289. END_CATCH_ALL
  290. if ( err )
  291. break ;
  292. // Move the data to the result array.
  293. for ( DWORD i = 0 ; i < cbData ; i++ )
  294. {
  295. abResult[i] = pabData[i] ;
  296. }
  297. }
  298. while ( FALSE ) ;
  299. // Memory leak....
  300. //if ( err )
  301. //{
  302. delete [] pabData ;
  303. //}
  304. if (err)
  305. {
  306. if ( err == ERROR_FILE_NOT_FOUND )
  307. {
  308. if (m_iDisplayWarnings)
  309. {iisDebugOut((LOG_TYPE_WARN, _T("CRegKey::QueryValue(): %s Not found. WARNING. code=0x%x\n"), pchValueName, err));}
  310. }
  311. else
  312. {
  313. if (err != ERROR_INVALID_PARAMETER)
  314. {
  315. iisDebugOut((LOG_TYPE_ERROR, _T("CRegKey::QueryValue(): %s FAILED. err=0x%x.\n"), pchValueName, err));
  316. }
  317. }
  318. }
  319. return err ;
  320. }
  321. LONG CRegKey :: QueryValue ( LPCTSTR pchValueName, void * pvResult, DWORD cbSize )
  322. {
  323. LONG err = 0 ;
  324. DWORD dwType ;
  325. DWORD cbData ;
  326. BYTE * pabData = NULL ;
  327. do
  328. {
  329. err = PrepareValue( pchValueName, & dwType, & cbData, & pabData );
  330. if ( err != 0 )
  331. {
  332. break ;
  333. }
  334. if ( dwType != REG_BINARY )
  335. {
  336. err = ERROR_INVALID_PARAMETER ;
  337. break ;
  338. }
  339. if ( cbSize < cbData )
  340. {
  341. err = ERROR_MORE_DATA;
  342. break;
  343. }
  344. ::memcpy(pvResult, pabData, cbData);
  345. }
  346. while ( FALSE ) ;
  347. // Memory leak....
  348. //if ( err )
  349. //{
  350. delete [] pabData ;
  351. //}
  352. if (err)
  353. {
  354. if ( err == ERROR_FILE_NOT_FOUND )
  355. {
  356. if (m_iDisplayWarnings)
  357. {iisDebugOut((LOG_TYPE_WARN, _T("CRegKey::QueryValue(): %s Not found. WARNING. code=0x%x\n"), pchValueName, err));}
  358. }
  359. else
  360. {
  361. if (err != ERROR_INVALID_PARAMETER)
  362. {
  363. iisDebugOut((LOG_TYPE_ERROR, _T("CRegKey::QueryValue(): %s FAILED. err=0x%x.\n"), pchValueName, err));
  364. }
  365. }
  366. }
  367. return err ;
  368. }
  369. // Overloaded value setting members.
  370. LONG CRegKey :: SetValue ( LPCTSTR pchValueName, LPCTSTR szResult, BOOL fExpand )
  371. {
  372. LONG err = 0;
  373. err = ::RegSetValueEx( *this, pchValueName,0,fExpand ? REG_EXPAND_SZ : REG_SZ,(const BYTE *) szResult,(_tcsclen(szResult) + 1) * sizeof(_TCHAR) ) ;
  374. if (err != ERROR_SUCCESS) {iisDebugOut((LOG_TYPE_ERROR, _T("CRegKey::SetValue(): %s FAILED, err=0x%x\n"), pchValueName,err));}
  375. return err ;
  376. }
  377. LONG CRegKey :: SetValue ( LPCTSTR pchValueName, CStringList & strList )
  378. {
  379. LONG err = 0;
  380. DWORD cbSize ;
  381. BYTE * pbData = NULL ;
  382. err = FlattenValue( strList, & cbSize, & pbData ) ;
  383. if ( err == 0 )
  384. {
  385. err = ::RegSetValueEx( *this, pchValueName,0,REG_MULTI_SZ,pbData, cbSize ) ;
  386. if (err != ERROR_SUCCESS) {iisDebugOut((LOG_TYPE_ERROR, _T("CRegKey::SetValue(): %s FAILED, err=0x%x\n"), pchValueName,err));}
  387. }
  388. delete [] pbData ;
  389. return err ;
  390. }
  391. LONG CRegKey :: SetValue ( LPCTSTR pchValueName, DWORD dwResult )
  392. {
  393. LONG err = 0;
  394. err = ::RegSetValueEx( *this, pchValueName,0,REG_DWORD,(const BYTE *) & dwResult,sizeof dwResult ) ;
  395. if (err != ERROR_SUCCESS) {iisDebugOut((LOG_TYPE_ERROR, _T("CRegKey::SetValue(): %s FAILED, err=0x%x\n"), pchValueName,err));}
  396. return err ;
  397. }
  398. LONG CRegKey :: SetValue ( LPCTSTR pchValueName, CByteArray & abResult )
  399. {
  400. LONG err = 0;
  401. DWORD cbSize ;
  402. BYTE * pbData = NULL ;
  403. err = FlattenValue( abResult, & cbSize, & pbData ) ;
  404. if ( err == 0 )
  405. {
  406. err = ::RegSetValueEx( *this, pchValueName,0,REG_BINARY,pbData, cbSize ) ;
  407. if (err != ERROR_SUCCESS) {iisDebugOut((LOG_TYPE_ERROR, _T("CRegKey::SetValue(): %s FAILED, err=0x%x\n"), pchValueName,err));}
  408. }
  409. delete pbData ;
  410. return err ;
  411. }
  412. LONG CRegKey :: SetValue ( LPCTSTR pchValueName, void * pvResult, DWORD cbSize )
  413. {
  414. LONG err = 0;
  415. err = ::RegSetValueEx( *this, pchValueName,0,REG_BINARY,(const BYTE *)pvResult, cbSize ) ;
  416. if (err != ERROR_SUCCESS) {iisDebugOut((LOG_TYPE_ERROR, _T("CRegKey::SetValue(): %s FAILED, err=0x%x\n"), pchValueName,err));}
  417. return err ;
  418. }
  419. LONG CRegKey::DeleteValue( LPCTSTR pchKeyName )
  420. {
  421. LONG err = 0;
  422. err = ::RegDeleteValue( *this, pchKeyName );
  423. if (err != ERROR_SUCCESS)
  424. {
  425. if ( err != ERROR_FILE_NOT_FOUND )
  426. {
  427. if (m_iDisplayWarnings)
  428. iisDebugOut((LOG_TYPE_WARN, _T("CRegKey::DeleteValue(): %s FAILED, err=0x%x\n"), pchKeyName,err));
  429. }
  430. }
  431. return(err);
  432. }
  433. LONG CRegKey::DeleteTree( LPCTSTR pchKeyName )
  434. {
  435. LONG err = 0;
  436. CRegKey regSubKey( *this, pchKeyName );
  437. if ( NULL != (HKEY) regSubKey )
  438. {
  439. CString strName;
  440. CTime cTime;
  441. while (TRUE)
  442. {
  443. CRegKeyIter regEnum( regSubKey );
  444. if ( regEnum.Next( &strName, &cTime ) != ERROR_SUCCESS )
  445. {
  446. break;
  447. }
  448. regSubKey.DeleteTree( strName );
  449. }
  450. // delete myself
  451. err = ::RegDeleteKey( *this, pchKeyName );
  452. }
  453. return(err);
  454. }
  455. LONG CRegKey :: FlattenValue ( CStringList & strList, DWORD * pcbSize, BYTE ** ppbData )
  456. {
  457. LONG err = 0 ;
  458. POSITION pos ;
  459. CString * pstr ;
  460. int cbTotal = 0 ;
  461. // Walk the list accumulating sizes
  462. for ( pos = strList.GetHeadPosition() ;
  463. ( pos != NULL ) && ( ( pstr = & strList.GetNext( pos ) ) != NULL ) ;
  464. )
  465. {
  466. cbTotal += ((pstr->GetLength() + 1)*sizeof(TCHAR));
  467. }
  468. // Allocate and fill a temporary buffer
  469. *pcbSize = cbTotal;
  470. if ( *pcbSize )
  471. {
  472. TRY
  473. {
  474. *ppbData = new BYTE[ *pcbSize ] ;
  475. if (*ppbData)
  476. {
  477. BYTE * pbData = *ppbData ;
  478. // Populate the buffer with the strings.
  479. for ( pos = strList.GetHeadPosition() ;
  480. ( pos != NULL ) && ( ( pstr = & strList.GetNext( pos ) ) != NULL );
  481. )
  482. {
  483. int cb = (pstr->GetLength() + 1)*sizeof(TCHAR) ;
  484. ::memcpy( pbData, (LPCTSTR) *pstr, cb ) ;
  485. pbData += cb ;
  486. }
  487. }
  488. else
  489. {
  490. err = ERROR_NOT_ENOUGH_MEMORY ;
  491. }
  492. }
  493. CATCH_ALL(e)
  494. {
  495. err = ERROR_NOT_ENOUGH_MEMORY ;
  496. }
  497. END_CATCH_ALL
  498. }
  499. else
  500. {
  501. *ppbData = NULL;
  502. }
  503. if (err)
  504. {
  505. iisDebugOut((LOG_TYPE_WARN, _T("CRegKey::FlattenValue(): %s FAILED. err=0x%x.\n"), strList, err));
  506. }
  507. return err ;
  508. }
  509. LONG CRegKey :: FlattenValue ( CByteArray & abData,DWORD * pcbSize,BYTE ** ppbData )
  510. {
  511. LONG err = 0 ;
  512. DWORD i ;
  513. // Allocate and fill a temporary buffer
  514. *pcbSize = (DWORD)abData.GetSize();
  515. if ( *pcbSize )
  516. {
  517. TRY
  518. {
  519. *ppbData = new BYTE[*pcbSize] ;
  520. if (*ppbData)
  521. {
  522. for ( i = 0 ; i < *pcbSize ; i++ )
  523. {
  524. (*ppbData)[i] = abData[i] ;
  525. }
  526. }
  527. else
  528. {
  529. err = ERROR_NOT_ENOUGH_MEMORY ;
  530. }
  531. }
  532. CATCH_ALL(e)
  533. {
  534. err = ERROR_NOT_ENOUGH_MEMORY ;
  535. }
  536. END_CATCH_ALL
  537. }
  538. else
  539. {
  540. *ppbData = NULL;
  541. }
  542. if (err)
  543. {
  544. iisDebugOut((LOG_TYPE_WARN, _T("CRegKey::FlattenValue(): FAILED. err=0x%x.\n"), err));
  545. }
  546. return err ;
  547. }
  548. LONG CRegKey :: QueryKeyInfo ( CREGKEY_KEY_INFO * pRegKeyInfo )
  549. {
  550. LONG err = 0 ;
  551. pRegKeyInfo->dwClassNameSize = sizeof pRegKeyInfo->chBuff - 1 ;
  552. err = ::RegQueryInfoKey( *this,pRegKeyInfo->chBuff,& pRegKeyInfo->dwClassNameSize,NULL,& pRegKeyInfo->dwNumSubKeys,& pRegKeyInfo->dwMaxSubKey,& pRegKeyInfo->dwMaxClass,& pRegKeyInfo->dwMaxValues,& pRegKeyInfo->dwMaxValueName,& pRegKeyInfo->dwMaxValueData,& pRegKeyInfo->dwSecDesc,& pRegKeyInfo->ftKey ) ;
  553. if (err != ERROR_SUCCESS) {iisDebugOut((LOG_TYPE_ERROR, _T("CRegKey::QueryKeyInfo(): FAILED. err=0x%x.\n"), err));}
  554. return err ;
  555. }
  556. CRegKeyIter :: CRegKeyIter ( CRegKey & regKey ) : m_rk_iter( regKey ),m_p_buffer( NULL ),m_cb_buffer( 0 )
  557. {
  558. LONG err = 0 ;
  559. CRegKey::CREGKEY_KEY_INFO regKeyInfo ;
  560. Reset() ;
  561. err = regKey.QueryKeyInfo( & regKeyInfo ) ;
  562. if ( err == 0 )
  563. {
  564. TRY
  565. {
  566. m_cb_buffer = regKeyInfo.dwMaxSubKey + sizeof (DWORD) ;
  567. m_p_buffer = new TCHAR [ m_cb_buffer ] ;
  568. }
  569. CATCH_ALL(e)
  570. {
  571. err = ERROR_NOT_ENOUGH_MEMORY ;
  572. }
  573. END_CATCH_ALL
  574. }
  575. if (err)
  576. {
  577. if (ERROR_NO_MORE_ITEMS != err)
  578. {
  579. iisDebugOut((LOG_TYPE_ERROR, _T("CRegKeyIter::CRegKeyIter(): FAILED. err=0x%x.\n"), err));
  580. }
  581. }
  582. }
  583. CRegKeyIter :: ~ CRegKeyIter ()
  584. {
  585. delete [] m_p_buffer ;
  586. }
  587. // Get the name (and optional last write time) of the next key.
  588. LONG CRegKeyIter :: Next ( CString * pstrName, CTime * pTime )
  589. {
  590. LONG err = 0;
  591. FILETIME ftDummy ;
  592. DWORD dwNameSize = m_cb_buffer ;
  593. err = ::RegEnumKeyEx( m_rk_iter, m_dw_index, m_p_buffer,& dwNameSize, NULL,NULL,NULL,& ftDummy ) ;
  594. if ( err == 0 )
  595. {
  596. m_dw_index++ ;
  597. if ( pTime )
  598. {
  599. *pTime = ftDummy ;
  600. }
  601. TRY
  602. {
  603. *pstrName = m_p_buffer ;
  604. }
  605. CATCH_ALL(e)
  606. {
  607. err = ERROR_NOT_ENOUGH_MEMORY ;
  608. }
  609. END_CATCH_ALL
  610. }
  611. if (err)
  612. {
  613. if (ERROR_NO_MORE_ITEMS != err)
  614. {
  615. iisDebugOut((LOG_TYPE_ERROR, _T("CRegKeyIter::Next(): FAILED. err=0x%x.\n"), err));
  616. }
  617. }
  618. return err ;
  619. }
  620. CRegValueIter :: CRegValueIter ( CRegKey & regKey )
  621. : m_rk_iter( regKey ),
  622. m_p_buffer( NULL ),
  623. m_cb_buffer( 0 )
  624. {
  625. LONG err = 0 ;
  626. CRegKey::CREGKEY_KEY_INFO regKeyInfo ;
  627. Reset() ;
  628. err = regKey.QueryKeyInfo( & regKeyInfo ) ;
  629. if ( err == 0 )
  630. {
  631. TRY
  632. {
  633. m_cb_buffer = regKeyInfo.dwMaxValueName + sizeof (DWORD) ;
  634. m_p_buffer = new TCHAR [ m_cb_buffer ] ;
  635. }
  636. CATCH_ALL(e)
  637. {
  638. err = ERROR_NOT_ENOUGH_MEMORY ;
  639. }
  640. END_CATCH_ALL
  641. }
  642. if (err)
  643. {
  644. if (ERROR_NO_MORE_ITEMS != err)
  645. {
  646. iisDebugOut((LOG_TYPE_ERROR, _T("CRegValueIter::CRegValueIter(): FAILED. err=0x%x.\n"), err));
  647. }
  648. }
  649. }
  650. CRegValueIter :: ~ CRegValueIter ()
  651. {
  652. delete [] m_p_buffer ;
  653. }
  654. LONG CRegValueIter :: Next ( CString * pstrName, DWORD * pdwType )
  655. {
  656. LONG err = 0 ;
  657. DWORD dwNameLength = m_cb_buffer ;
  658. err = ::RegEnumValue( m_rk_iter,m_dw_index,m_p_buffer,& dwNameLength,NULL,pdwType,NULL,NULL ) ;
  659. if ( err == 0 )
  660. {
  661. m_dw_index++ ;
  662. TRY
  663. {
  664. *pstrName = m_p_buffer ;
  665. }
  666. CATCH_ALL(e)
  667. {
  668. err = ERROR_NOT_ENOUGH_MEMORY ;
  669. }
  670. END_CATCH_ALL
  671. }
  672. if (err)
  673. {
  674. if (ERROR_NO_MORE_ITEMS != err)
  675. {
  676. iisDebugOut((LOG_TYPE_ERROR, _T("CRegValueIter::Next(): FAILED. err=0x%x.\n"), err));
  677. }
  678. }
  679. return err ;
  680. }
  681. LONG CRegValueIter :: Next ( CString * pstrName, CString * pstrValue )
  682. {
  683. LONG err = 0 ;
  684. DWORD dwNameLength = m_cb_buffer ;
  685. TCHAR szValue[_MAX_PATH];
  686. DWORD dwValue = _MAX_PATH * sizeof(TCHAR);
  687. err = ::RegEnumValue( m_rk_iter,m_dw_index,m_p_buffer,& dwNameLength,NULL,NULL,(LPBYTE)szValue,&dwValue ) ;
  688. if ( err == 0 )
  689. {
  690. m_dw_index++ ;
  691. TRY
  692. {
  693. *pstrName = m_p_buffer ;
  694. *pstrValue = szValue;
  695. }
  696. CATCH_ALL(e)
  697. {
  698. err = ERROR_NOT_ENOUGH_MEMORY ;
  699. }
  700. END_CATCH_ALL
  701. }
  702. if (err)
  703. {
  704. if (ERROR_NO_MORE_ITEMS != err)
  705. {
  706. iisDebugOut((LOG_TYPE_ERROR, _T("CRegValueIter::Next(): FAILED. err=0x%x.\n"), err));
  707. }
  708. }
  709. return err ;
  710. }