Source code of Windows XP (NT5)
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.

635 lines
17 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // File: simreg.h
  4. //
  5. // Contents: CRegFile
  6. //
  7. // Simple Win32/Win16 registry manipulation class
  8. // Copyright (c)1996, Shaun Ivory
  9. // All rights reserved
  10. // Used with permission from Shaun hisself (shauniv)
  11. //
  12. // History: Sep-26-96 Davepl Created
  13. //
  14. //--------------------------------------------------------------------------
  15. #include "shtl.h"
  16. #include "simreg.h"
  17. #if defined(SIMREG_WIN32)
  18. #include <winreg.h>
  19. #endif
  20. #ifndef HKEY_CURRENT_USER
  21. #define HKEY_CURRENT_USER (( HKEY ) 0x80000001 )
  22. #endif
  23. #ifndef HKEY_LOCAL_MACHINE
  24. #define HKEY_LOCAL_MACHINE (( HKEY ) 0x80000002 )
  25. #endif
  26. #ifndef HKEY_USERS
  27. #define HKEY_USERS (( HKEY ) 0x80000003 )
  28. #endif
  29. #ifndef HKEY_PERFORMANCE_DATA
  30. #define HKEY_PERFORMANCE_DATA (( HKEY ) 0x80000004 )
  31. #endif
  32. #ifndef HKEY_CURRENT_CONFIG
  33. #define HKEY_CURRENT_CONFIG (( HKEY ) 0x80000005 )
  34. #endif
  35. #ifndef HKEY_DYN_DATA
  36. #define HKEY_DYN_DATA (( HKEY ) 0x80000006 )
  37. #endif
  38. #if defined(SIMREG_WIN32)
  39. __DATL_INLINE CSimpleReg::CSimpleReg( HKEY keyRoot, const tstring &szRoot, unsigned char forceCreate, LPSECURITY_ATTRIBUTES lpsa)
  40. : m_hSubKey(0), m_hKeyRoot(0), m_bCreate(forceCreate != 0),m_lpsaSecurityAttributes(lpsa), m_bOpenSuccess(FALSE)
  41. { // Normal constructor
  42. SetRoot( keyRoot, szRoot );
  43. }
  44. #else
  45. __DATL_INLINE CSimpleReg::CSimpleReg( HKEY keyRoot, const tstring &szRoot, unsigned char forceCreate)
  46. : m_hSubKey(0), m_hKeyRoot(0), m_bCreate(forceCreate != 0)
  47. { // Normal constructor
  48. SetRoot( keyRoot, szRoot );
  49. }
  50. #endif
  51. __DATL_INLINE unsigned char CSimpleReg::Assign( const CSimpleReg &other )
  52. {
  53. #if defined(SIMREG_WIN32)
  54. SecurityAttributes(other.SecurityAttributes());
  55. #endif
  56. m_bCreate = other.ForceCreate();
  57. SetRoot( other.GetRootKey(), other.SubKeyName() );
  58. return m_bOpenSuccess;
  59. }
  60. __DATL_INLINE CSimpleReg::CSimpleReg( const CSimpleReg &other )
  61. : m_hSubKey(0), m_hKeyRoot(0), m_bOpenSuccess(FALSE)
  62. {
  63. Assign( other );
  64. }
  65. __DATL_INLINE CSimpleReg::CSimpleReg(void)
  66. : m_bOpenSuccess(0), m_hSubKey(0), m_hKeyRoot(0)
  67. {
  68. #if defined(SIMREG_WIN32)
  69. m_lpsaSecurityAttributes = NULL;
  70. #endif
  71. }
  72. __DATL_INLINE CSimpleReg& CSimpleReg::operator=(const CSimpleReg& other)
  73. { // Assignment operator
  74. Assign(other);
  75. return (*this);
  76. }
  77. __DATL_INLINE CSimpleReg::~CSimpleReg(void)
  78. { // Destructor
  79. Close();
  80. }
  81. __DATL_INLINE unsigned char CSimpleReg::ForceCreate( unsigned char create )
  82. { // Force creation of a key, if it doesn't exist
  83. unsigned char Old = m_bCreate;
  84. m_bCreate = (create != 0);
  85. Open();
  86. return (Old);
  87. }
  88. __DATL_INLINE unsigned long CSimpleReg::Size( const tstring &key )
  89. {
  90. if (!*this)
  91. return (0);
  92. DWORD dwType = REG_SZ;
  93. DWORD dwSize = 0;
  94. LONG Ret;
  95. #if defined(SIMREG_WIN32)
  96. Ret = RegQueryValueEx( m_hSubKey, Totstring(key), NULL, &dwType, NULL, &dwSize);
  97. #else
  98. Ret = RegQueryValue( m_hSubKey, Totstring(key), NULL, (LONG FAR *)&dwSize);
  99. #endif
  100. if (Ret==ERROR_SUCCESS)
  101. {
  102. #if defined(UNICODE) || defined(_UNICODE)
  103. if (dwType == REG_SZ || dwType == REG_EXPAND_SZ || dwType == REG_MULTI_SZ || dwType == REG_LINK || dwType == REG_RESOURCE_LIST)
  104. return (dwSize / 2);
  105. #else
  106. return (dwSize);
  107. #endif
  108. }
  109. return (0);
  110. }
  111. __DATL_INLINE unsigned long CSimpleReg::Type( const tstring &key )
  112. {
  113. if (!*this)
  114. return (0);
  115. DWORD dwType = REG_SZ;
  116. DWORD dwSize = 0;
  117. LONG Ret;
  118. #if defined(SIMREG_WIN32)
  119. Ret = RegQueryValueEx( m_hSubKey, Totstring(key), NULL, &dwType, NULL, &dwSize);
  120. #else
  121. Ret = RegQueryValue( m_hSubKey, Totstring(key), NULL, (LONG FAR *)&dwSize);
  122. #endif
  123. if (Ret==ERROR_SUCCESS)
  124. {
  125. return (dwType);
  126. }
  127. return (0);
  128. }
  129. __DATL_INLINE unsigned char CSimpleReg::Query( const tstring &key, LPTSTR szValue, unsigned short maxLen )
  130. {
  131. if (!*this)
  132. return (0);
  133. DWORD dwType = REG_SZ;
  134. DWORD dwSize = maxLen;
  135. LONG Ret;
  136. #if defined(SIMREG_WIN32)
  137. Ret = RegQueryValueEx( m_hSubKey, Totstring(key), NULL, &dwType, (LPBYTE)szValue, &dwSize);
  138. #else
  139. Ret = RegQueryValue( m_hSubKey, Totstring(key), szValue, (LONG FAR *)&dwSize);
  140. #endif
  141. return (Ret==ERROR_SUCCESS);
  142. }
  143. __DATL_INLINE unsigned char CSimpleReg::Query( const tstring &key, tstring &value, unsigned short maxLen )
  144. { // Get a REG_SZ (string) from the specified sub-key
  145. if (!*this)
  146. return (0);
  147. if (!maxLen)
  148. maxLen = (unsigned short)(Size( key ) + 1);
  149. if (!maxLen)
  150. maxLen = 1;
  151. LPTSTR Buffer = new TCHAR[maxLen];
  152. DWORD dwType = REG_SZ;
  153. DWORD dwSize = maxLen;
  154. LONG Ret;
  155. #if defined(SIMREG_WIN32)
  156. Ret = RegQueryValueEx( m_hSubKey, Totstring(key), NULL, &dwType, (LPBYTE)Buffer, &dwSize);
  157. #else
  158. Ret = RegQueryValue( m_hSubKey, Totstring(key), Buffer, (LONG FAR *)&dwSize);
  159. #endif
  160. if (Ret==ERROR_SUCCESS)
  161. {
  162. value = tstring(Buffer);
  163. }
  164. delete[] Buffer;
  165. return (Ret==ERROR_SUCCESS);
  166. }
  167. __DATL_INLINE unsigned char CSimpleReg::Query( const tstring &key, DWORD &value )
  168. { // Get a REG_DWORD (unsigned long int) from the specified sub-key
  169. if (!*this)
  170. return (0);
  171. #if defined(SIMREG_WIN32)
  172. DWORD Value;
  173. DWORD dwType = REG_DWORD;
  174. DWORD dwSize = sizeof(DWORD);
  175. LONG Ret;
  176. Ret = RegQueryValueEx( m_hSubKey, Totstring(key), NULL, &dwType, (LPBYTE)&Value, &dwSize);
  177. if (Ret==ERROR_SUCCESS)
  178. {
  179. value = Value;
  180. }
  181. return (Ret==ERROR_SUCCESS);
  182. #else
  183. DWORD temp = value;
  184. if (QueryBin( key, &temp, sizeof(temp)))
  185. {
  186. value = temp;
  187. return (TRUE);
  188. }
  189. return (FALSE);
  190. #endif
  191. }
  192. __DATL_INLINE unsigned char CSimpleReg::Query( const tstring &key, int &value )
  193. { // Get a REG_DWORD (unsigned long int) from the specified sub-key
  194. DWORD Temp;
  195. if (Query(key,Temp))
  196. {
  197. value = (int)Temp;
  198. return (TRUE);
  199. }
  200. return (FALSE);
  201. }
  202. __DATL_INLINE unsigned char CSimpleReg::Query( const tstring &key, LONG &value )
  203. { // Get a REG_DWORD (unsigned long int) from the specified sub-key
  204. DWORD Temp;
  205. if (Query(key,Temp))
  206. {
  207. value = (LONG)Temp;
  208. return (TRUE);
  209. }
  210. return (FALSE);
  211. }
  212. __DATL_INLINE unsigned char CSimpleReg::Query( const tstring &key, WORD &value )
  213. { // Get a REG_DWORD (unsigned long int) from the specified sub-key
  214. DWORD Temp;
  215. if (Query(key,Temp))
  216. {
  217. value = (WORD)Temp;
  218. return (TRUE);
  219. }
  220. return (FALSE);
  221. }
  222. __DATL_INLINE unsigned char CSimpleReg::Query( const tstring &key, BYTE &value )
  223. { // Get a REG_DWORD (unsigned long int) from the specified sub-key
  224. DWORD Temp;
  225. if (Query(key,Temp))
  226. {
  227. value = (BYTE)Temp;
  228. return (TRUE);
  229. }
  230. return (FALSE);
  231. }
  232. #ifdef SIMREG_WIN32
  233. __DATL_INLINE unsigned char CSimpleReg::SetBin( const tstring &key, void *value, DWORD size )
  234. {
  235. if (!*this)
  236. return (0);
  237. LONG Ret;
  238. Ret = RegSetValueEx( m_hSubKey, Totstring(key), 0, REG_BINARY, (LPBYTE)value, size );
  239. return (Ret==ERROR_SUCCESS);
  240. }
  241. __DATL_INLINE unsigned char CSimpleReg::QueryBin( const tstring &key, void *value, DWORD size )
  242. {
  243. if (!*this)
  244. return (0);
  245. DWORD dwType = REG_BINARY;
  246. DWORD dwSize = size;
  247. LONG Ret;
  248. char *Value = new char[size];
  249. Ret = RegQueryValueEx( m_hSubKey, Totstring(key), NULL, &dwType, (LPBYTE)Value, &dwSize);
  250. if (dwType != REG_BINARY)
  251. {
  252. delete[] Value;
  253. return (0);
  254. }
  255. if (dwSize != size)
  256. {
  257. delete[] Value;
  258. return (0);
  259. }
  260. if (Ret==ERROR_SUCCESS)
  261. {
  262. memcpy( value, Value, size );
  263. }
  264. delete[] Value;
  265. return (Ret==ERROR_SUCCESS);
  266. }
  267. #else
  268. __DATL_INLINE unsigned char CSimpleReg::SetBin( const tstring &key, void *value, DWORD size )
  269. {
  270. if (!*this)
  271. return (0);
  272. unsigned char *Value = (unsigned char*)value;
  273. tstring Str;
  274. char Byte[4];
  275. for (DWORD i=0;i<size;i++)
  276. {
  277. wsprintf( Byte, "%02X ", Value[i] );
  278. Str = Str + Byte;
  279. }
  280. return (Set( key, Str ));
  281. }
  282. __DATL_INLINE unsigned char CSimpleReg::QueryBin( const tstring &key, void *value, DWORD size )
  283. {
  284. if (!*this)
  285. return (0);
  286. unsigned char *Value = (unsigned char *)value;
  287. tstring Str;
  288. if ((unsigned char)Query( key, Str, (unsigned short)(size * 3 + 1))==0)
  289. {
  290. return (FALSE);
  291. }
  292. if (strlen((const char *)Str) != size * 3)
  293. {
  294. return (FALSE);
  295. }
  296. tstring Temp;
  297. while (Str.length())
  298. {
  299. Temp = Str.Left( 3 );
  300. Str = Str.Right( strlen((const char *)Str) - 3 );
  301. *Value = (unsigned char)strtoul((const char *)Temp,NULL,16);
  302. Value++;
  303. }
  304. return (TRUE);
  305. }
  306. #endif
  307. __DATL_INLINE unsigned char CSimpleReg::Set( const tstring &key, const tstring &value )
  308. { // Set a REG_SZ value for the specified key.
  309. if (!*this)
  310. return (0);
  311. LONG Ret;
  312. #if defined(SIMREG_WIN32)
  313. Ret = RegSetValueEx( m_hSubKey, Totstring(key), 0, REG_SZ, (LPBYTE)Totstring(value), value.length()+1 );
  314. #else
  315. Ret = RegSetValue( m_hSubKey, (LPCSTR)Totstring(key), REG_SZ, (LPCSTR)Totstring(value), value.length()+1 );
  316. #endif
  317. return (Ret==ERROR_SUCCESS);
  318. }
  319. __DATL_INLINE unsigned char CSimpleReg::Set( const tstring &key, DWORD value )
  320. { // Set a REG_SZ value for the specified key.
  321. if (!*this)
  322. return (0);
  323. #if defined(SIMREG_WIN32)
  324. LONG Ret;
  325. Ret = RegSetValueEx( m_hSubKey, Totstring(key), 0, REG_DWORD, (LPBYTE)&value, sizeof(DWORD) );
  326. return (Ret==ERROR_SUCCESS);
  327. #else
  328. return (SetBin( key, &value, sizeof(DWORD)));
  329. #endif
  330. }
  331. __DATL_INLINE unsigned char CSimpleReg::Open(void)
  332. { // Open the specified sub key of the open root.
  333. HKEY hKey;
  334. LONG Ret;
  335. Close();
  336. if (m_bCreate)
  337. {
  338. #if defined(SIMREG_WIN32)
  339. DWORD CreatedNewKey;
  340. if ((Ret = RegCreateKeyEx( m_hKeyRoot, Totstring(m_SubKeyName), 0, TEXT(""), REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, SecurityAttributes(), &hKey, &CreatedNewKey )) == ERROR_SUCCESS)
  341. #else
  342. if ((Ret = RegCreateKey( m_hKeyRoot, Totstring(m_SubKeyName), &hKey )) == ERROR_SUCCESS)
  343. #endif
  344. {
  345. m_hSubKey = hKey;
  346. m_bOpenSuccess = 1;
  347. }
  348. }
  349. else
  350. {
  351. #if defined(SIMREG_WIN32)
  352. if ((Ret = RegOpenKeyEx( m_hKeyRoot, Totstring(m_SubKeyName), 0, KEY_ALL_ACCESS, &hKey )) == ERROR_SUCCESS)
  353. #else
  354. if ((Ret = RegOpenKey( m_hKeyRoot, Totstring(m_SubKeyName), &hKey )) == ERROR_SUCCESS)
  355. #endif
  356. {
  357. m_hSubKey = hKey;
  358. m_bOpenSuccess = 1;
  359. }
  360. }
  361. return (m_bOpenSuccess);
  362. }
  363. __DATL_INLINE unsigned char CSimpleReg::Close(void)
  364. { // If open, close key.
  365. if (m_bOpenSuccess)
  366. RegCloseKey(m_hSubKey);
  367. m_bOpenSuccess = 0;
  368. return (1);
  369. }
  370. __DATL_INLINE unsigned char CSimpleReg::SetRoot( HKEY keyClass, const tstring &newRoot )
  371. { // Set the root class and key, open.
  372. m_hKeyRoot = GetWin16HKey(keyClass);
  373. m_SubKeyName = newRoot;
  374. return (Open());
  375. }
  376. __DATL_INLINE unsigned char CSimpleReg::Delete( HKEY root, const tstring &key )
  377. {
  378. return (RegDeleteKey(GetWin16HKey(root), Totstring(key)) == ERROR_SUCCESS);
  379. }
  380. __DATL_INLINE DWORD CSimpleReg::CountKeys(void)
  381. {
  382. #if defined(SIMREG_WIN32)
  383. TCHAR Class[256]=TEXT("");
  384. DWORD ClassSize = sizeof(Class)/sizeof(Class[0]);
  385. DWORD subKeyCount=0;
  386. RegQueryInfoKey(GetSubKey(),Class,&ClassSize,NULL,&subKeyCount,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
  387. return (subKeyCount);
  388. #else
  389. char Name[256];
  390. DWORD NameSize;
  391. DWORD subKeyCount=0;
  392. for (int i=0;;i++)
  393. {
  394. NameSize = sizeof(Name) / sizeof(Name[0]);
  395. if (RegEnumKey(GetSubKey(),i,Name,NameSize) != ERROR_SUCCESS)
  396. break;
  397. subKeyCount++;
  398. }
  399. return (subKeyCount);
  400. #endif
  401. }
  402. __DATL_INLINE int CSimpleReg::DoRecurseKeys( HKEY key, const tstring &root, SimRegKeyEnumProc enumProc, void *extraInfo, int level, int recurseOrder, int failOnOpenError )
  403. {
  404. TCHAR Name[256]=TEXT("");
  405. DWORD NameSize;
  406. #if defined(SIMREG_WIN32)
  407. TCHAR Class[256]=TEXT("");
  408. DWORD ClassSize;
  409. FILETIME FileTime;
  410. #endif
  411. CSimpleReg reg(key,root);
  412. LONG res;
  413. if (!reg.OK())
  414. {
  415. return (failOnOpenError ? 0 : 1);
  416. }
  417. DWORD subKeyCount = reg.CountKeys();
  418. for (DWORD i=subKeyCount;i>0;i--)
  419. {
  420. NameSize = sizeof(Name)/sizeof(Name[0]);
  421. #if defined(SIMREG_WIN32)
  422. ClassSize = sizeof(Class)/sizeof(Class[0]);
  423. if ((res=RegEnumKeyEx(reg.GetSubKey(),i-1,Name,&NameSize,NULL,Class,&ClassSize,&FileTime)) != ERROR_SUCCESS)
  424. #else
  425. if ((res=RegEnumKey(reg.GetSubKey(),i-1,Name,NameSize)) != ERROR_SUCCESS)
  426. #endif
  427. {
  428. break;
  429. }
  430. CKeyEnumInfo EnumInfo;
  431. EnumInfo.Name = Name;
  432. EnumInfo.Root = reg.GetSubKey();
  433. EnumInfo.Level = level;
  434. EnumInfo.ExtraData = extraInfo;
  435. if (enumProc && recurseOrder==PreOrder)
  436. if (!enumProc(EnumInfo))
  437. return (0);
  438. if (!DoRecurseKeys(reg.GetSubKey(),Name,enumProc,extraInfo,level+1,recurseOrder, failOnOpenError))
  439. return (0);
  440. if (enumProc && recurseOrder==PostOrder)
  441. if (!enumProc(EnumInfo))
  442. return (0);
  443. }
  444. return (1);
  445. }
  446. __DATL_INLINE int CSimpleReg::DoEnumKeys( HKEY key, const tstring &root, SimRegKeyEnumProc enumProc, void *extraInfo, int failOnOpenError )
  447. {
  448. TCHAR Name[256]=TEXT("");
  449. DWORD NameSize;
  450. #if defined(SIMREG_WIN32)
  451. TCHAR Class[256]=TEXT("");
  452. DWORD ClassSize;
  453. FILETIME FileTime;
  454. #endif
  455. CSimpleReg reg(key,root);
  456. LONG res;
  457. if (!reg.OK())
  458. {
  459. return (failOnOpenError ? 0 : 1);
  460. }
  461. DWORD subKeyCount = reg.CountKeys();
  462. for (DWORD i=subKeyCount;i>0;i--)
  463. {
  464. NameSize = sizeof(Name)/sizeof(Name[0]);
  465. #if defined(SIMREG_WIN32)
  466. ClassSize = sizeof(Class)/sizeof(Class[0]);
  467. if ((res=RegEnumKeyEx(reg.GetSubKey(),i-1,Name,&NameSize,NULL,Class,&ClassSize,&FileTime)) != ERROR_SUCCESS)
  468. #else
  469. if ((res=RegEnumKey(reg.GetSubKey(),i-1,Name,NameSize)) != ERROR_SUCCESS)
  470. #endif
  471. {
  472. break;
  473. }
  474. CKeyEnumInfo EnumInfo;
  475. EnumInfo.Name = Name;
  476. EnumInfo.Root = reg.GetSubKey();
  477. EnumInfo.Level = 0;
  478. EnumInfo.ExtraData = extraInfo;
  479. if (!enumProc(EnumInfo))
  480. return (0);
  481. }
  482. return (1);
  483. }
  484. __DATL_INLINE int CSimpleReg::RecurseKeys( SimRegKeyEnumProc enumProc, void *extraInfo, int recurseOrder, int failOnOpenError )
  485. {
  486. return (DoRecurseKeys(GetSubKey(), TEXT(""), enumProc, extraInfo, 0, recurseOrder, failOnOpenError ));
  487. }
  488. __DATL_INLINE int CSimpleReg::EnumKeys( SimRegKeyEnumProc enumProc, void *extraInfo, int failOnOpenError )
  489. {
  490. return (DoEnumKeys(GetSubKey(), TEXT(""), enumProc, extraInfo, failOnOpenError ));
  491. }
  492. __DATL_INLINE HKEY CSimpleReg::GetHkeyFromName( const tstring &Name )
  493. {
  494. static struct
  495. {
  496. LPCTSTR Name;
  497. HKEY Key;
  498. } KeyNames[] =
  499. {
  500. { TEXT("HKEY_CLASSES_ROOT"), HKEY_CLASSES_ROOT},
  501. { TEXT("HKEY_CURRENT_USER"), HKEY_CURRENT_USER},
  502. { TEXT("HKEY_LOCAL_MACHINE"), HKEY_LOCAL_MACHINE},
  503. { TEXT("HKEY_USERS"), HKEY_USERS},
  504. { TEXT("HKEY_CURRENT_CONFIG"), HKEY_CURRENT_CONFIG},
  505. { TEXT("HKEY_DYN_DATA"), HKEY_DYN_DATA},
  506. { TEXT("HKCR"), HKEY_CLASSES_ROOT},
  507. { TEXT("HKCU"), HKEY_CURRENT_USER},
  508. { TEXT("HKLM"), HKEY_LOCAL_MACHINE},
  509. { TEXT("HKU"), HKEY_USERS},
  510. { TEXT("HKCC"), HKEY_CURRENT_CONFIG},
  511. { TEXT("HKDD"), HKEY_DYN_DATA},
  512. { NULL, NULL}
  513. };
  514. for (int i=0;KeyNames[i].Name;i++)
  515. {
  516. if (!lstrcmpi(Totstring(Name),KeyNames[i].Name))
  517. return (KeyNames[i].Key);
  518. }
  519. return (INVALID_HKEY);
  520. }
  521. __DATL_INLINE int CSimpleReg::DeleteEnumKeyProc( CSimpleReg::CKeyEnumInfo &enumInfo )
  522. {
  523. return (CSimpleReg::Delete( enumInfo.Root, enumInfo.Name ));
  524. }
  525. __DATL_INLINE int CSimpleReg::DeleteRecursively( HKEY root, const tstring &name )
  526. {
  527. if (CSimpleReg( root, name ).RecurseKeys( DeleteEnumKeyProc, NULL, CSimpleReg::PostOrder ))
  528. return (CSimpleReg::Delete( root, name ));
  529. return (0);
  530. }
  531. __DATL_INLINE HKEY CSimpleReg::GetWin16HKey( HKEY key )
  532. {
  533. #if !defined(SIMREG_WIN32)
  534. if (key == HKEY_CURRENT_USER ||
  535. key == HKEY_LOCAL_MACHINE ||
  536. key == HKEY_USERS ||
  537. key == HKEY_CURRENT_CONFIG ||
  538. key == HKEY_DYN_DATA)
  539. return (HKEY_CLASSES_ROOT);
  540. #endif
  541. return (key);
  542. }
  543. __DATL_INLINE int CSimpleReg::EnumValues( SimRegValueEnumProc enumProc, void *extraInfo )
  544. {
  545. TCHAR Name[256];
  546. DWORD Size;
  547. DWORD Type;
  548. int Result = 1;
  549. for (int i=0;;i++)
  550. {
  551. Size = sizeof(Name) / sizeof(Name[0]);
  552. if (RegEnumValue(GetSubKey(),i,Name,&Size,NULL,&Type,NULL,NULL) != ERROR_SUCCESS)
  553. break;
  554. CValueEnumInfo info;
  555. info.Name = Name;
  556. info.Type = Type;
  557. info.Size = Size;
  558. info.ExtraData = extraInfo;
  559. if (enumProc)
  560. {
  561. if (!enumProc(info))
  562. {
  563. Result = 0;
  564. break;
  565. }
  566. }
  567. }
  568. return (Result);
  569. }