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.

683 lines
14 KiB

  1. #include "stdafx.h"
  2. // open an existing key
  3. CRegKey :: CRegKey (
  4. HKEY hKeyBase,
  5. LPCTSTR pchSubKey,
  6. REGSAM regSam )
  7. : m_hKey( NULL ),
  8. m_dwDisposition( 0 )
  9. {
  10. LONG err = ERROR_SUCCESS ;
  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)
  18. ::RegCloseKey(m_hKey);
  19. m_hKey = NULL ;
  20. }
  21. }
  22. // Constructor creating a new key/opening a key if already exist, and set value if specified
  23. CRegKey :: CRegKey (
  24. LPCTSTR lpSubKey,
  25. HKEY hKeyBase,
  26. LPCTSTR lpValueName,
  27. DWORD dwType,
  28. LPBYTE lpValueData,
  29. DWORD cbValueData)
  30. : m_hKey( NULL ),
  31. m_dwDisposition( 0 )
  32. {
  33. LONG err = ERROR_SUCCESS;
  34. err = ::RegCreateKeyEx( hKeyBase, lpSubKey, 0, _T(""), REG_OPTION_NON_VOLATILE,
  35. KEY_ALL_ACCESS, NULL, & m_hKey, & m_dwDisposition ) ;
  36. if ( err != ERROR_SUCCESS) {
  37. if ( m_hKey )
  38. ::RegCloseKey( m_hKey ) ;
  39. m_hKey = NULL ;
  40. } else {
  41. if (lpValueName)
  42. ::RegSetValueEx(m_hKey, lpValueName, 0, dwType, (const LPBYTE)lpValueData, cbValueData);
  43. }
  44. }
  45. CRegKey :: ~ CRegKey ()
  46. {
  47. if ( m_hKey )
  48. ::RegCloseKey( m_hKey ) ;
  49. }
  50. // Prepare to read a value by finding the value's size.
  51. LONG CRegKey :: PrepareValue (
  52. LPCTSTR pchValueName,
  53. DWORD * pdwType,
  54. DWORD * pcbSize,
  55. BYTE ** ppbData )
  56. {
  57. LONG err = 0 ;
  58. BYTE chDummy[2] ;
  59. DWORD cbData = 0 ;
  60. do
  61. {
  62. // Set the resulting buffer size to 0.
  63. *pcbSize = 0 ;
  64. *ppbData = NULL ;
  65. err = ::RegQueryValueEx( *this,
  66. (TCHAR *) pchValueName,
  67. 0, pdwType,
  68. chDummy, & cbData ) ;
  69. // The only error we should get here is ERROR_MORE_DATA, but
  70. // we may get no error if the value has no data.
  71. if ( err == 0 )
  72. {
  73. cbData = sizeof (LONG) ; // Just a fudgy number
  74. }
  75. else
  76. if ( err != ERROR_MORE_DATA )
  77. break ;
  78. // Allocate a buffer large enough for the data.
  79. *ppbData = new BYTE [ (*pcbSize = cbData) + sizeof (LONG) ] ;
  80. if ( *ppbData == NULL )
  81. {
  82. err = ERROR_NOT_ENOUGH_MEMORY ;
  83. break ;
  84. }
  85. // Now that have a buffer, re-fetch the value.
  86. err = ::RegQueryValueEx( *this,
  87. (TCHAR *) pchValueName,
  88. 0, pdwType,
  89. *ppbData, pcbSize ) ;
  90. } while ( FALSE ) ;
  91. if ( err )
  92. {
  93. delete [] *ppbData ;
  94. }
  95. return err ;
  96. }
  97. // Overloaded value query members; each returns ERROR_INVALID_PARAMETER
  98. // if data exists but not in correct form to deliver into result object.
  99. LONG CRegKey :: QueryValue ( LPCTSTR pchValueName, CString & strResult )
  100. {
  101. LONG err = 0 ;
  102. DWORD dwType ;
  103. DWORD cbData ;
  104. BYTE * pabData = NULL ;
  105. do
  106. {
  107. if ( err = PrepareValue( pchValueName, & dwType, & cbData, & pabData ) )
  108. break ;
  109. if (( dwType != REG_SZ ) && ( dwType != REG_EXPAND_SZ ))
  110. {
  111. err = ERROR_INVALID_PARAMETER ;
  112. break ;
  113. }
  114. // Guarantee that the data looks like a string
  115. pabData[cbData] = 0 ;
  116. // Catch exceptions trying to assign to the caller's string
  117. TRY
  118. {
  119. strResult = (TCHAR *) pabData ;
  120. }
  121. CATCH_ALL(e)
  122. {
  123. err = ERROR_NOT_ENOUGH_MEMORY ;
  124. }
  125. END_CATCH_ALL
  126. }
  127. while ( FALSE ) ;
  128. // Memory leak....
  129. //if ( err )
  130. //{
  131. delete [] pabData ;
  132. //}
  133. return err ;
  134. }
  135. LONG CRegKey :: QueryValue ( LPCTSTR pchValueName, DWORD & dwResult )
  136. {
  137. LONG err = 0 ;
  138. DWORD dwType ;
  139. DWORD cbData ;
  140. BYTE * pabData = NULL ;
  141. do
  142. {
  143. if ( err = PrepareValue( pchValueName, & dwType, & cbData, & pabData ) )
  144. break ;
  145. if ( dwType != REG_DWORD || cbData != sizeof dwResult )
  146. {
  147. err = ERROR_INVALID_PARAMETER ;
  148. break ;
  149. }
  150. dwResult = *((DWORD *) pabData) ;
  151. }
  152. while ( FALSE ) ;
  153. // Memory leak...
  154. //if ( err )
  155. //{
  156. delete [] pabData ;
  157. //}
  158. return err ;
  159. }
  160. LONG CRegKey :: QueryValue ( LPCTSTR pchValueName, CByteArray & abResult )
  161. {
  162. LONG err = 0 ;
  163. DWORD dwType ;
  164. DWORD cbData ;
  165. BYTE * pabData = NULL ;
  166. do
  167. {
  168. if ( err = PrepareValue( pchValueName, & dwType, & cbData, & pabData ) )
  169. break ;
  170. if ( dwType != REG_BINARY )
  171. {
  172. err = ERROR_INVALID_PARAMETER ;
  173. break ;
  174. }
  175. // Catch exceptions trying to grow the result array
  176. TRY
  177. {
  178. abResult.SetSize( cbData ) ;
  179. }
  180. CATCH_ALL(e)
  181. {
  182. err = ERROR_NOT_ENOUGH_MEMORY ;
  183. }
  184. END_CATCH_ALL
  185. if ( err )
  186. break ;
  187. // Move the data to the result array.
  188. for ( DWORD i = 0 ; i < cbData ; i++ )
  189. {
  190. abResult[i] = pabData[i] ;
  191. }
  192. }
  193. while ( FALSE ) ;
  194. // Memory leak....
  195. //if ( err )
  196. //{
  197. delete [] pabData ;
  198. //}
  199. return err ;
  200. }
  201. LONG CRegKey :: QueryValue ( LPCTSTR pchValueName, void * pvResult, DWORD cbSize )
  202. {
  203. LONG err = 0 ;
  204. DWORD dwType ;
  205. DWORD cbData ;
  206. BYTE * pabData = NULL ;
  207. do
  208. {
  209. if ( err = PrepareValue( pchValueName, & dwType, & cbData, & pabData ) )
  210. break ;
  211. if ( dwType != REG_BINARY )
  212. {
  213. err = ERROR_INVALID_PARAMETER ;
  214. break ;
  215. }
  216. if ( cbSize < cbData )
  217. {
  218. err = ERROR_MORE_DATA;
  219. break;
  220. }
  221. ::memcpy(pvResult, pabData, cbData);
  222. }
  223. while ( FALSE ) ;
  224. // Memory leak....
  225. //if ( err )
  226. //{
  227. delete [] pabData ;
  228. //}
  229. return err ;
  230. }
  231. LONG CRegKey :: QueryValue ( LPCTSTR pchValueName, LPTSTR szMultiSz, DWORD dwSize )
  232. {
  233. LONG err = 0 ;
  234. DWORD dwType ;
  235. DWORD cbData ;
  236. BYTE * pabData = NULL ;
  237. do
  238. {
  239. if ( err = PrepareValue( pchValueName, & dwType, & cbData, & pabData ) )
  240. break ;
  241. if ( dwType != REG_MULTI_SZ )
  242. {
  243. err = ERROR_INVALID_PARAMETER ;
  244. break ;
  245. }
  246. if ( dwSize < cbData )
  247. {
  248. err = ERROR_MORE_DATA;
  249. break;
  250. }
  251. ::memcpy(szMultiSz, pabData, cbData);
  252. }
  253. while ( FALSE ) ;
  254. delete [] pabData ;
  255. return err ;
  256. }
  257. // Overloaded value setting members.
  258. LONG CRegKey :: SetValue ( LPCTSTR pchValueName, LPCTSTR szResult, BOOL fExpand )
  259. {
  260. LONG err = 0;
  261. err = ::RegSetValueEx( *this,
  262. pchValueName,
  263. 0,
  264. fExpand ? REG_EXPAND_SZ : REG_SZ,
  265. (const BYTE *) szResult,
  266. (_tcsclen(szResult) + 1) * sizeof(_TCHAR) ) ;
  267. return err ;
  268. }
  269. LONG CRegKey :: SetValue ( LPCTSTR pchValueName, DWORD dwResult )
  270. {
  271. LONG err = 0;
  272. err = ::RegSetValueEx( *this,
  273. pchValueName,
  274. 0,
  275. REG_DWORD,
  276. (const BYTE *) & dwResult,
  277. sizeof dwResult ) ;
  278. return err ;
  279. }
  280. LONG CRegKey :: SetValue ( LPCTSTR pchValueName, CByteArray & abResult )
  281. {
  282. LONG err = 0;
  283. DWORD cbSize ;
  284. BYTE * pbData = NULL ;
  285. err = FlattenValue( abResult, & cbSize, & pbData ) ;
  286. if ( ( err == 0 ) && pbData)
  287. {
  288. err = ::RegSetValueEx( *this,
  289. pchValueName,
  290. 0,
  291. REG_BINARY,
  292. pbData,
  293. cbSize ) ;
  294. }
  295. delete pbData ;
  296. return err ;
  297. }
  298. LONG CRegKey :: SetValue ( LPCTSTR pchValueName, void * pvResult, DWORD cbSize )
  299. {
  300. LONG err = 0;
  301. err = ::RegSetValueEx( *this,
  302. pchValueName,
  303. 0,
  304. REG_BINARY,
  305. (const BYTE *)pvResult,
  306. cbSize ) ;
  307. return err ;
  308. }
  309. LONG CRegKey :: SetValue ( LPCTSTR pchValueName, LPCTSTR szMultiSz, DWORD dwSize )
  310. {
  311. LONG err = 0;
  312. err = ::RegSetValueEx( *this,
  313. pchValueName,
  314. 0,
  315. REG_MULTI_SZ,
  316. (const BYTE *)szMultiSz,
  317. dwSize ) ;
  318. return err ;
  319. }
  320. LONG CRegKey::DeleteValue( LPCTSTR pchKeyName )
  321. {
  322. LONG err = 0;
  323. err = ::RegDeleteValue( *this, pchKeyName );
  324. return(err);
  325. }
  326. LONG CRegKey::DeleteTree( LPCTSTR pchKeyName )
  327. {
  328. LONG err = 0;
  329. CRegKey regSubKey( *this, pchKeyName );
  330. if ( NULL != (HKEY) regSubKey )
  331. {
  332. CString strName;
  333. CTime cTime;
  334. while (TRUE)
  335. {
  336. CRegKeyIter regEnum( regSubKey );
  337. if ( regEnum.Next( &strName, &cTime ) != ERROR_SUCCESS )
  338. {
  339. break;
  340. }
  341. regSubKey.DeleteTree( strName );
  342. }
  343. // delete myself
  344. err = ::RegDeleteKey( *this, pchKeyName );
  345. }
  346. return(err);
  347. }
  348. LONG CRegKey :: FlattenValue (
  349. CByteArray & abData,
  350. DWORD * pcbSize,
  351. BYTE ** ppbData )
  352. {
  353. LONG err = 0 ;
  354. DWORD i ;
  355. // Allocate and fill a temporary buffer
  356. if (*pcbSize = DWORD(abData.GetSize()))
  357. {
  358. TRY
  359. {
  360. *ppbData = new BYTE[*pcbSize] ;
  361. for ( i = 0 ; i < *pcbSize ; i++ )
  362. {
  363. (*ppbData)[i] = abData[i] ;
  364. }
  365. }
  366. CATCH_ALL(e)
  367. {
  368. err = ERROR_NOT_ENOUGH_MEMORY ;
  369. }
  370. END_CATCH_ALL
  371. }
  372. else
  373. {
  374. *ppbData = NULL;
  375. }
  376. return err ;
  377. }
  378. LONG CRegKey :: QueryKeyInfo ( CREGKEY_KEY_INFO * pRegKeyInfo )
  379. {
  380. LONG err = 0 ;
  381. pRegKeyInfo->dwClassNameSize = sizeof pRegKeyInfo->chBuff - 1 ;
  382. err = ::RegQueryInfoKey( *this,
  383. pRegKeyInfo->chBuff,
  384. & pRegKeyInfo->dwClassNameSize,
  385. NULL,
  386. & pRegKeyInfo->dwNumSubKeys,
  387. & pRegKeyInfo->dwMaxSubKey,
  388. & pRegKeyInfo->dwMaxClass,
  389. & pRegKeyInfo->dwMaxValues,
  390. & pRegKeyInfo->dwMaxValueName,
  391. & pRegKeyInfo->dwMaxValueData,
  392. & pRegKeyInfo->dwSecDesc,
  393. & pRegKeyInfo->ftKey ) ;
  394. return err ;
  395. }
  396. CRegKeyIter :: CRegKeyIter ( CRegKey & regKey )
  397. : m_rk_iter( regKey ),
  398. m_p_buffer( NULL ),
  399. m_cb_buffer( 0 )
  400. {
  401. LONG err = 0 ;
  402. CRegKey::CREGKEY_KEY_INFO regKeyInfo ;
  403. Reset() ;
  404. err = regKey.QueryKeyInfo( & regKeyInfo ) ;
  405. if ( err == 0 )
  406. {
  407. TRY
  408. {
  409. m_cb_buffer = regKeyInfo.dwMaxSubKey + sizeof (DWORD) ;
  410. m_p_buffer = new TCHAR [ m_cb_buffer ] ;
  411. }
  412. CATCH_ALL(e)
  413. {
  414. err = ERROR_NOT_ENOUGH_MEMORY ;
  415. }
  416. END_CATCH_ALL
  417. }
  418. if ( err )
  419. {
  420. //ReportError( err ) ;
  421. }
  422. }
  423. CRegKeyIter :: ~ CRegKeyIter ()
  424. {
  425. delete [] m_p_buffer ;
  426. }
  427. // Get the name (and optional last write time) of the next key.
  428. LONG CRegKeyIter :: Next ( CString * pstrName, CTime * pTime )
  429. {
  430. LONG err = 0;
  431. FILETIME ftDummy ;
  432. DWORD dwNameSize = m_cb_buffer ;
  433. err = ::RegEnumKeyEx( m_rk_iter,
  434. m_dw_index,
  435. m_p_buffer,
  436. & dwNameSize,
  437. NULL,
  438. NULL,
  439. NULL,
  440. & ftDummy ) ;
  441. if ( err == 0 )
  442. {
  443. m_dw_index++ ;
  444. if ( pTime )
  445. {
  446. *pTime = ftDummy ;
  447. }
  448. TRY
  449. {
  450. *pstrName = m_p_buffer ;
  451. }
  452. CATCH_ALL(e)
  453. {
  454. err = ERROR_NOT_ENOUGH_MEMORY ;
  455. }
  456. END_CATCH_ALL
  457. }
  458. return err ;
  459. }
  460. CRegValueIter :: CRegValueIter ( CRegKey & regKey )
  461. : m_rk_iter( regKey ),
  462. m_p_buffer( NULL ),
  463. m_cb_buffer( 0 )
  464. {
  465. LONG err = 0 ;
  466. CRegKey::CREGKEY_KEY_INFO regKeyInfo ;
  467. Reset() ;
  468. err = regKey.QueryKeyInfo( & regKeyInfo ) ;
  469. if ( err == 0 )
  470. {
  471. TRY
  472. {
  473. m_cb_buffer = regKeyInfo.dwMaxValueName + sizeof (DWORD) ;
  474. m_p_buffer = new TCHAR [ m_cb_buffer ] ;
  475. }
  476. CATCH_ALL(e)
  477. {
  478. err = ERROR_NOT_ENOUGH_MEMORY ;
  479. }
  480. END_CATCH_ALL
  481. }
  482. if ( err )
  483. {
  484. //ReportError( err ) ;
  485. }
  486. }
  487. CRegValueIter :: ~ CRegValueIter ()
  488. {
  489. delete [] m_p_buffer ;
  490. }
  491. LONG CRegValueIter :: Next ( CString * pstrName, DWORD * pdwType )
  492. {
  493. LONG err = 0 ;
  494. DWORD dwNameLength = m_cb_buffer ;
  495. err = ::RegEnumValue( m_rk_iter,
  496. m_dw_index,
  497. m_p_buffer,
  498. & dwNameLength,
  499. NULL,
  500. pdwType,
  501. NULL,
  502. NULL ) ;
  503. if ( err == 0 )
  504. {
  505. m_dw_index++ ;
  506. TRY
  507. {
  508. *pstrName = m_p_buffer ;
  509. }
  510. CATCH_ALL(e)
  511. {
  512. err = ERROR_NOT_ENOUGH_MEMORY ;
  513. }
  514. END_CATCH_ALL
  515. }
  516. return err ;
  517. }
  518. LONG CRegValueIter :: Next ( CString * pstrName, CString * pstrValue )
  519. {
  520. LONG err = 0 ;
  521. DWORD dwNameLength = m_cb_buffer ;
  522. TCHAR szValue[_MAX_PATH];
  523. DWORD dwValue = _MAX_PATH * sizeof(TCHAR);
  524. err = ::RegEnumValue( m_rk_iter,
  525. m_dw_index,
  526. m_p_buffer,
  527. & dwNameLength,
  528. NULL,
  529. NULL,
  530. (LPBYTE)szValue,
  531. &dwValue ) ;
  532. if ( err == 0 )
  533. {
  534. m_dw_index++ ;
  535. TRY
  536. {
  537. *pstrName = m_p_buffer ;
  538. *pstrValue = szValue;
  539. }
  540. CATCH_ALL(e)
  541. {
  542. err = ERROR_NOT_ENOUGH_MEMORY ;
  543. }
  544. END_CATCH_ALL
  545. }
  546. return err ;
  547. }