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.

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