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.

575 lines
13 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. registry.cpp
  5. Abstract:
  6. SIS Groveler/registry interface
  7. Authors:
  8. John Douceur, 1998
  9. Environment:
  10. User Mode
  11. Revision History:
  12. --*/
  13. #include "all.hxx"
  14. _TCHAR Registry::id_buffer[id_buffer_length];
  15. bool
  16. Registry::read(
  17. HKEY base_key,
  18. const _TCHAR *path,
  19. int num_entries,
  20. EntrySpec *entries)
  21. {
  22. ASSERT(base_key == HKEY_CLASSES_ROOT
  23. || base_key == HKEY_CURRENT_CONFIG
  24. || base_key == HKEY_CURRENT_USER
  25. || base_key == HKEY_LOCAL_MACHINE
  26. || base_key == HKEY_USERS);
  27. ASSERT(path != 0);
  28. ASSERT(num_entries > 0);
  29. ASSERT(entries != 0);
  30. for (int index = 0; index < num_entries; index++)
  31. {
  32. load_string_into_value(entries[index].type,
  33. entries[index].default_value, entries[index].pointer);
  34. }
  35. HKEY path_key;
  36. long result = RegOpenKeyEx(base_key, path, 0, KEY_ALL_ACCESS, &path_key);
  37. if (result != ERROR_SUCCESS)
  38. {
  39. return false;
  40. }
  41. ASSERT(path_key != 0);
  42. for (index = 0; index < num_entries; index++)
  43. {
  44. DWORD data_type;
  45. DWORD data_length = id_buffer_length;
  46. result = RegQueryValueEx(path_key, entries[index].identifier, 0,
  47. &data_type, (BYTE *)id_buffer, &data_length);
  48. if (result == ERROR_SUCCESS && data_type == REG_SZ)
  49. {
  50. load_string_into_value(entries[index].type, id_buffer,
  51. entries[index].pointer);
  52. }
  53. }
  54. ASSERT(path_key != 0);
  55. RegCloseKey(path_key);
  56. path_key = 0;
  57. return true;
  58. }
  59. bool
  60. Registry::write(
  61. HKEY base_key,
  62. const _TCHAR *path,
  63. int num_entries,
  64. EntrySpec *entries)
  65. {
  66. ASSERT(base_key == HKEY_CLASSES_ROOT
  67. || base_key == HKEY_CURRENT_CONFIG
  68. || base_key == HKEY_CURRENT_USER
  69. || base_key == HKEY_LOCAL_MACHINE
  70. || base_key == HKEY_USERS);
  71. ASSERT(path != 0);
  72. ASSERT(num_entries > 0);
  73. ASSERT(entries != 0);
  74. HKEY path_key;
  75. DWORD disposition;
  76. long result = RegCreateKeyEx(base_key, path, 0, 0, REG_OPTION_NON_VOLATILE,
  77. KEY_ALL_ACCESS, 0, &path_key, &disposition);
  78. if (result != ERROR_SUCCESS)
  79. {
  80. PRINT_DEBUG_MSG((_T("GROVELER: RegCreateKeyEx() failed with error %d\n"),
  81. result));
  82. return false;
  83. }
  84. ASSERT(path_key != 0);
  85. for (int index = 0; index < num_entries; index++)
  86. {
  87. DWORD data_type;
  88. DWORD data_length = id_buffer_length;
  89. result = RegQueryValueEx(path_key, entries[index].identifier, 0,
  90. &data_type, (BYTE *)id_buffer, &data_length);
  91. if (result != ERROR_SUCCESS || data_type != REG_SZ)
  92. {
  93. store_value_in_string(entries[index].type, entries[index].pointer,
  94. id_buffer);
  95. result =
  96. RegSetValueEx(path_key, entries[index].identifier, 0, REG_SZ,
  97. (BYTE *)id_buffer, (_tcslen(id_buffer) + 1) * sizeof(_TCHAR));
  98. if (result != ERROR_SUCCESS)
  99. {
  100. PRINT_DEBUG_MSG((_T("GROVELER: RegSetValueEx() failed with error %d\n"),
  101. result));
  102. }
  103. }
  104. }
  105. ASSERT(path_key != 0);
  106. RegCloseKey(path_key);
  107. path_key = 0;
  108. return true;
  109. }
  110. bool
  111. Registry::overwrite(
  112. HKEY base_key,
  113. const _TCHAR *path,
  114. int num_entries,
  115. EntrySpec *entries)
  116. {
  117. ASSERT(base_key == HKEY_CLASSES_ROOT
  118. || base_key == HKEY_CURRENT_CONFIG
  119. || base_key == HKEY_CURRENT_USER
  120. || base_key == HKEY_LOCAL_MACHINE
  121. || base_key == HKEY_USERS);
  122. ASSERT(path != 0);
  123. ASSERT(num_entries > 0);
  124. ASSERT(entries != 0);
  125. HKEY path_key;
  126. DWORD disposition;
  127. long result = RegCreateKeyEx(base_key, path, 0, 0, REG_OPTION_NON_VOLATILE,
  128. KEY_ALL_ACCESS, 0, &path_key, &disposition);
  129. if (result != ERROR_SUCCESS)
  130. {
  131. PRINT_DEBUG_MSG((_T("GROVELER: RegCreateKeyEx() failed with error %d\n"),
  132. result));
  133. return false;
  134. }
  135. ASSERT(path_key != 0);
  136. for (int index = 0; index < num_entries; index++)
  137. {
  138. store_value_in_string(entries[index].type, entries[index].pointer,
  139. id_buffer);
  140. result =
  141. RegSetValueEx(path_key, entries[index].identifier, 0, REG_SZ,
  142. (BYTE *)id_buffer, (_tcslen(id_buffer) + 1) * sizeof(_TCHAR));
  143. if (result != ERROR_SUCCESS)
  144. {
  145. PRINT_DEBUG_MSG((_T("GROVELER: RegSetValueEx() failed with error %d\n"),
  146. result));
  147. }
  148. }
  149. ASSERT(path_key != 0);
  150. RegCloseKey(path_key);
  151. path_key = 0;
  152. return true;
  153. }
  154. bool
  155. Registry::write_defaults(
  156. HKEY base_key,
  157. const _TCHAR *path,
  158. int num_entries,
  159. EntrySpec *entries)
  160. {
  161. ASSERT(base_key == HKEY_CLASSES_ROOT
  162. || base_key == HKEY_CURRENT_CONFIG
  163. || base_key == HKEY_CURRENT_USER
  164. || base_key == HKEY_LOCAL_MACHINE
  165. || base_key == HKEY_USERS);
  166. ASSERT(path != 0);
  167. ASSERT(num_entries > 0);
  168. ASSERT(entries != 0);
  169. HKEY path_key;
  170. DWORD disposition;
  171. long result = RegCreateKeyEx(base_key, path, 0, 0, REG_OPTION_NON_VOLATILE,
  172. KEY_ALL_ACCESS, 0, &path_key, &disposition);
  173. if (result != ERROR_SUCCESS)
  174. {
  175. PRINT_DEBUG_MSG((_T("GROVELER: RegCreateKeyEx() failed with error %d\n"),
  176. result));
  177. return false;
  178. }
  179. ASSERT(path_key != 0);
  180. for (int index = 0; index < num_entries; index++)
  181. {
  182. DWORD data_type;
  183. DWORD data_length = id_buffer_length;
  184. result = RegQueryValueEx(path_key, entries[index].identifier, 0,
  185. &data_type, (BYTE *)id_buffer, &data_length);
  186. if (result != ERROR_SUCCESS)
  187. {
  188. result = RegSetValueEx(path_key, entries[index].identifier, 0,
  189. REG_SZ, (BYTE *)entries[index].default_value,
  190. (_tcslen(entries[index].default_value) + 1) * sizeof(_TCHAR));
  191. if (result != ERROR_SUCCESS)
  192. {
  193. PRINT_DEBUG_MSG((_T("GROVELER: RegSetValueEx() failed with error %d\n"),
  194. result));
  195. }
  196. }
  197. }
  198. ASSERT(path_key != 0);
  199. RegCloseKey(path_key);
  200. path_key = 0;
  201. return true;
  202. }
  203. bool
  204. Registry::overwrite_defaults(
  205. HKEY base_key,
  206. const _TCHAR *path,
  207. int num_entries,
  208. EntrySpec *entries)
  209. {
  210. ASSERT(base_key == HKEY_CLASSES_ROOT
  211. || base_key == HKEY_CURRENT_CONFIG
  212. || base_key == HKEY_CURRENT_USER
  213. || base_key == HKEY_LOCAL_MACHINE
  214. || base_key == HKEY_USERS);
  215. ASSERT(path != 0);
  216. ASSERT(num_entries > 0);
  217. ASSERT(entries != 0);
  218. HKEY path_key;
  219. DWORD disposition;
  220. long result = RegCreateKeyEx(base_key, path, 0, 0, REG_OPTION_NON_VOLATILE,
  221. KEY_ALL_ACCESS, 0, &path_key, &disposition);
  222. if (result != ERROR_SUCCESS)
  223. {
  224. PRINT_DEBUG_MSG((_T("GROVELER: RegCreateKeyEx() failed with error %d\n"),
  225. result));
  226. return false;
  227. }
  228. ASSERT(path_key != 0);
  229. for (int index = 0; index < num_entries; index++)
  230. {
  231. result = RegSetValueEx(path_key, entries[index].identifier, 0, REG_SZ,
  232. (BYTE *)entries[index].default_value,
  233. (_tcslen(entries[index].default_value) + 1) * sizeof(_TCHAR));
  234. if (result != ERROR_SUCCESS)
  235. {
  236. PRINT_DEBUG_MSG((_T("GROVELER: RegSetValueEx() failed with error %d\n"),
  237. result));
  238. }
  239. }
  240. ASSERT(path_key != 0);
  241. RegCloseKey(path_key);
  242. path_key = 0;
  243. return true;
  244. }
  245. bool
  246. Registry::read_string_set(
  247. HKEY base_key,
  248. const _TCHAR *path,
  249. int *num_strings,
  250. _TCHAR ***strings,
  251. BYTE **buffer)
  252. {
  253. ASSERT(base_key == HKEY_CLASSES_ROOT
  254. || base_key == HKEY_CURRENT_CONFIG
  255. || base_key == HKEY_CURRENT_USER
  256. || base_key == HKEY_LOCAL_MACHINE
  257. || base_key == HKEY_USERS);
  258. ASSERT(path != 0);
  259. ASSERT(num_strings != 0);
  260. ASSERT(strings != 0);
  261. ASSERT(buffer != 0);
  262. HKEY path_key;
  263. *num_strings = 0;
  264. *strings = 0;
  265. *buffer = 0;
  266. long result = RegOpenKeyEx(base_key, path, 0, KEY_ALL_ACCESS, &path_key);
  267. if (result != ERROR_SUCCESS)
  268. {
  269. return false;
  270. }
  271. unsigned long num_values;
  272. unsigned long max_value_length;
  273. unsigned long max_string_length;
  274. result = RegQueryInfoKey(path_key, 0, 0, 0, 0, 0, 0,
  275. &num_values, &max_value_length, &max_string_length, 0, 0);
  276. if (result != ERROR_SUCCESS || num_values == 0)
  277. {
  278. return true;
  279. }
  280. _TCHAR *value = new _TCHAR[max_value_length + 1];
  281. _TCHAR **string_set = new _TCHAR *[num_values];
  282. BYTE *string_buffer =
  283. new BYTE[num_values * max_string_length * sizeof(_TCHAR)];
  284. int string_index = 0;
  285. int buffer_offset = 0;
  286. for (unsigned int index = 0; index < num_values; index++)
  287. {
  288. DWORD value_length = max_value_length + 1;
  289. DWORD string_length = max_string_length;
  290. DWORD data_type;
  291. result = RegEnumValue(path_key, index, value, &value_length, 0,
  292. &data_type, &string_buffer[buffer_offset], &string_length);
  293. if (result == ERROR_SUCCESS && data_type == REG_SZ)
  294. {
  295. ASSERT(unsigned(string_index) < num_values);
  296. string_set[string_index] = (_TCHAR *)&string_buffer[buffer_offset];
  297. string_index++;
  298. buffer_offset += string_length;
  299. }
  300. }
  301. *num_strings = string_index;
  302. ASSERT(value != 0);
  303. delete[] value;
  304. value = 0;
  305. *strings = string_set;
  306. *buffer = string_buffer;
  307. ASSERT(path_key != 0);
  308. RegCloseKey(path_key);
  309. path_key = 0;
  310. return true;
  311. }
  312. bool
  313. Registry::write_string_set(
  314. HKEY base_key,
  315. const _TCHAR *path,
  316. int num_strings,
  317. _TCHAR **strings,
  318. _TCHAR **identifiers)
  319. {
  320. ASSERT(base_key == HKEY_CLASSES_ROOT
  321. || base_key == HKEY_CURRENT_CONFIG
  322. || base_key == HKEY_CURRENT_USER
  323. || base_key == HKEY_LOCAL_MACHINE
  324. || base_key == HKEY_USERS);
  325. ASSERT(path != 0);
  326. ASSERT(num_strings > 0);
  327. ASSERT(strings != 0);
  328. ASSERT(identifiers != 0);
  329. HKEY path_key;
  330. DWORD disposition;
  331. long result = RegCreateKeyEx(base_key, path, 0, 0, REG_OPTION_NON_VOLATILE,
  332. KEY_ALL_ACCESS, 0, &path_key, &disposition);
  333. if (result != ERROR_SUCCESS)
  334. {
  335. PRINT_DEBUG_MSG((_T("GROVELER: RegCreateKeyEx() failed with error %d\n"),
  336. result));
  337. return false;
  338. }
  339. ASSERT(path_key != 0);
  340. for (int index = 0; index < num_strings; index++)
  341. {
  342. DWORD data_type;
  343. DWORD data_length = id_buffer_length;
  344. result = RegQueryValueEx(path_key, identifiers[index], 0,
  345. &data_type, (BYTE *)id_buffer, &data_length);
  346. if (result != ERROR_SUCCESS || data_type != REG_SZ)
  347. {
  348. result = RegSetValueEx(
  349. path_key, identifiers[index], 0, REG_SZ, (BYTE *)strings[index],
  350. (_tcslen(strings[index]) + 1) * sizeof(_TCHAR));
  351. if (result != ERROR_SUCCESS)
  352. {
  353. PRINT_DEBUG_MSG((_T("GROVELER: RegSetValueEx() failed with error %d\n"),
  354. result));
  355. }
  356. }
  357. }
  358. ASSERT(path_key != 0);
  359. RegCloseKey(path_key);
  360. path_key = 0;
  361. return true;
  362. }
  363. bool
  364. Registry::overwrite_string_set(
  365. HKEY base_key,
  366. const _TCHAR *path,
  367. int num_strings,
  368. _TCHAR **strings,
  369. _TCHAR **identifiers)
  370. {
  371. ASSERT(base_key == HKEY_CLASSES_ROOT
  372. || base_key == HKEY_CURRENT_CONFIG
  373. || base_key == HKEY_CURRENT_USER
  374. || base_key == HKEY_LOCAL_MACHINE
  375. || base_key == HKEY_USERS);
  376. ASSERT(path != 0);
  377. ASSERT(num_strings > 0);
  378. ASSERT(strings != 0);
  379. ASSERT(identifiers != 0);
  380. HKEY path_key;
  381. DWORD disposition;
  382. long result = RegCreateKeyEx(base_key, path, 0, 0, REG_OPTION_NON_VOLATILE,
  383. KEY_ALL_ACCESS, 0, &path_key, &disposition);
  384. if (result != ERROR_SUCCESS)
  385. {
  386. PRINT_DEBUG_MSG((_T("GROVELER: RegCreateKeyEx() failed with error %d\n"),
  387. result));
  388. return false;
  389. }
  390. ASSERT(path_key != 0);
  391. for (int index = 0; index < num_strings; index++)
  392. {
  393. result = RegSetValueEx(
  394. path_key, identifiers[index], 0, REG_SZ, (BYTE *)strings[index],
  395. (_tcslen(strings[index]) + 1) * sizeof(_TCHAR));
  396. if (result != ERROR_SUCCESS)
  397. {
  398. PRINT_DEBUG_MSG((_T("GROVELER: RegSetValueEx() failed with error %d\n"),
  399. result));
  400. }
  401. }
  402. ASSERT(path_key != 0);
  403. RegCloseKey(path_key);
  404. path_key = 0;
  405. return true;
  406. }
  407. void
  408. Registry::create_key_ex(
  409. HKEY hKey,
  410. LPCTSTR lpSubKey,
  411. DWORD Reserved,
  412. LPTSTR lpClass,
  413. DWORD dwOptions,
  414. REGSAM samDesired,
  415. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  416. PHKEY phkResult,
  417. LPDWORD lpdwDisposition)
  418. {
  419. DWORD result = RegCreateKeyEx(hKey, lpSubKey, Reserved, lpClass, dwOptions,
  420. samDesired, lpSecurityAttributes, phkResult, lpdwDisposition);
  421. if (result != ERROR_SUCCESS)
  422. {
  423. PRINT_DEBUG_MSG((_T("GROVELER: RegCreateKeyEx() failed with error %d\n"),
  424. result));
  425. throw result;
  426. }
  427. }
  428. void
  429. Registry::open_key_ex(
  430. HKEY hKey,
  431. LPCTSTR lpSubKey,
  432. DWORD ulOptions,
  433. REGSAM samDesired,
  434. PHKEY phkResult)
  435. {
  436. DWORD result =
  437. RegOpenKeyEx(hKey, lpSubKey, ulOptions, samDesired, phkResult);
  438. if (result != ERROR_SUCCESS)
  439. {
  440. throw result;
  441. }
  442. }
  443. void
  444. Registry::close_key(
  445. HKEY hKey)
  446. {
  447. DWORD result = RegCloseKey(hKey);
  448. if (result != ERROR_SUCCESS)
  449. {
  450. PRINT_DEBUG_MSG((_T("GROVELER: RegCloseKey() failed with error %d\n"), result));
  451. throw result;
  452. }
  453. }
  454. void
  455. Registry::query_value_ex(
  456. HKEY hKey,
  457. LPCTSTR lpValueName,
  458. LPDWORD lpReserved,
  459. LPDWORD lpType,
  460. LPBYTE lpData,
  461. LPDWORD lpcbData)
  462. {
  463. DWORD result = RegQueryValueEx(hKey, lpValueName,
  464. lpReserved, lpType, lpData, lpcbData);
  465. if (result != ERROR_SUCCESS)
  466. {
  467. throw result;
  468. }
  469. }
  470. void
  471. Registry::set_value_ex(
  472. HKEY hKey,
  473. LPCTSTR lpValueName,
  474. DWORD Reserved,
  475. DWORD dwType,
  476. CONST BYTE *lpData,
  477. DWORD cbData)
  478. {
  479. DWORD result =
  480. RegSetValueEx(hKey, lpValueName, Reserved, dwType, lpData, cbData);
  481. if (result != ERROR_SUCCESS)
  482. {
  483. PRINT_DEBUG_MSG((_T("GROVELER: RegSetValueEx() failed with error %d\n"), result));
  484. throw result;
  485. }
  486. }
  487. void
  488. Registry::load_string_into_value(
  489. EntryType type,
  490. const _TCHAR *string,
  491. void *value)
  492. {
  493. ASSERT(string != 0);
  494. ASSERT(value != 0);
  495. switch (type)
  496. {
  497. case entry_bool:
  498. *((bool *)value) = _ttoi(string) != 0;
  499. break;
  500. case entry_char:
  501. *((_TCHAR *)value) = string[0];
  502. break;
  503. case entry_int:
  504. _stscanf(string, _T("%d"), (int *)value);
  505. break;
  506. case entry_int64:
  507. _stscanf(string, _T("%I64d"), (__int64 *)value);
  508. break;
  509. case entry_double:
  510. _stscanf(string, _T("%lf"), (double *)value);
  511. break;
  512. default:
  513. ASSERT(false);
  514. }
  515. }
  516. void
  517. Registry::store_value_in_string(
  518. EntryType type,
  519. void *value,
  520. _TCHAR *string)
  521. {
  522. ASSERT(string != 0);
  523. ASSERT(value != 0);
  524. switch (type)
  525. {
  526. case entry_bool:
  527. _stprintf(string, *((bool *)value) ? _T("1") : _T("0"));
  528. break;
  529. case entry_char:
  530. _stprintf(string, _T("%c"), *((_TCHAR *)value));
  531. break;
  532. case entry_int:
  533. _stprintf(string, _T("%d"), *((int *)value));
  534. break;
  535. case entry_int64:
  536. _stprintf(string, _T("%I64d"), *((__int64 *)value));
  537. break;
  538. case entry_double:
  539. _stprintf(string, _T("%g"), *((double *)value));
  540. break;
  541. default:
  542. ASSERT(false);
  543. }
  544. }