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.

413 lines
10 KiB

  1. /*******************************************************************
  2. *
  3. * Copyright (c) 1999 Microsoft Corporation
  4. *
  5. * DESCRIPTION: an extension to dump the contents of registry keys and values
  6. *
  7. * AUTHOR:
  8. * Based on Code by : danielwe (Dan Weisman)
  9. * ntsd addition by : kksharma (Kshitiz K. Sharma)
  10. *
  11. * DATE:4/20/1999
  12. *
  13. *******************************************************************/
  14. #ifndef KERNEL
  15. #ifndef Print
  16. #define Print dprintf
  17. #endif
  18. #define OFLAG(l) (1L << ((DWORD)#@l - (DWORD)'a'))
  19. #define LINE_NUMBER 0
  20. #define NUM_ASCII_CHARS 16
  21. #define NUM_HEX_CHARS (NUM_ASCII_CHARS * 3)
  22. #define SPACE 7
  23. #define PB_BUFFER_SIZE (NUM_ASCII_CHARS * 50)
  24. VOID dregHelp() {
  25. dprintf("!dreg -[d|w] <keyPath>[![<valueName> | *]] - Dumps registry information\n");
  26. dprintf("!dreg -d ... - Prints binary values as DWORDs\n");
  27. dprintf("!dreg -w ... - Prints binary values as WORDs\n");
  28. dprintf("!dreg <keyPath>!* - Prints all values under <keyPath>\n");
  29. dprintf("!dreg <keyPath> - Prints all subkeys of <keyPath>\n");
  30. dprintf("\n");
  31. dprintf("<keypath> can begin with any of the following:\n");
  32. dprintf("\thklm - HKEY_LOCAL_MACHINE\n");
  33. dprintf("\thkcu - HKEY_CURRENT_USER\n");
  34. dprintf("\thkcr - HKEY_CLASSES_ROOT\n");
  35. dprintf("\thku - HKEY_USERS\n");
  36. dprintf("\tif absent, hklm is assumed\n");
  37. dprintf("\n");
  38. dprintf("Ex:\n");
  39. dprintf("!dreg hkcu\\Software\\Microsoft\n");
  40. dprintf("!dreg System\\CurrentControlSet\\Services\\Tcpip!*\n");
  41. dprintf("!dreg System\\CurrentControlSet\\Services\\Tcpip!Start\n");
  42. }
  43. VOID PrintBinary(PBYTE pbData, DWORD cbData, USHORT uWidth)
  44. {
  45. CHAR line[80];
  46. INT i;
  47. INT ascii = 0;
  48. PBYTE temp = pbData;
  49. BOOL fDone = FALSE;
  50. DWORD cbCount = 0;
  51. CHAR hex_digits[] = "0123456789ABCDEF";
  52. while (!fDone)
  53. {
  54. DWORD cb;
  55. memset(line, 0x20, sizeof(line));
  56. Print("%04X: ", cbCount);
  57. for (ascii = 0,i = LINE_NUMBER, cb = 0;
  58. ascii < NUM_ASCII_CHARS;
  59. ascii++, temp++)
  60. {
  61. if ((DWORD)(temp - pbData) >= cbData)
  62. {
  63. if (cbData < PB_BUFFER_SIZE)
  64. {
  65. fDone = TRUE;
  66. break;
  67. }
  68. else
  69. return;
  70. }
  71. line[i] = hex_digits[(*temp & 0xF0) >> 4];
  72. line[i + 1] = hex_digits[(*temp & 0x0F)];
  73. cb++;
  74. if ((ascii + 1) % uWidth == 0)
  75. {
  76. line[i + 2] = 0x20;
  77. i++;
  78. if (uWidth > 1)
  79. {
  80. line[i + 3] = 0x20;
  81. i++;
  82. }
  83. else if (uWidth == 1 && (!(cb % 4)))
  84. {
  85. line[i + 3] = 0x20;
  86. line[i + 4] = 0x20;
  87. i += 2;
  88. }
  89. }
  90. i += 2;
  91. line[ascii + NUM_HEX_CHARS + SPACE + LINE_NUMBER] =
  92. (isprint(*temp) ? *temp : '.');
  93. cbCount++;
  94. }
  95. line[79] = 0;
  96. Print("%s\n", line);
  97. }
  98. }
  99. VOID PrintMultiSz(PBYTE pbData)
  100. {
  101. LPSTR sz = (LPSTR)pbData;
  102. DWORD csz = 0;
  103. while (*sz)
  104. {
  105. Print("%d: \"%s\"\n", csz, *sz ? sz : "<empty>");
  106. csz++;
  107. sz += lstrlenA(sz) + 1;
  108. }
  109. }
  110. VOID PrintRegistryValue(DWORD dwType, PBYTE pbData, DWORD cbData, USHORT uWidth)
  111. {
  112. switch (dwType)
  113. {
  114. case REG_SZ:
  115. Print("REG_SZ: \"%s\"\n", *pbData ? pbData : "<empty>");
  116. break;
  117. case REG_EXPAND_SZ:
  118. {
  119. CHAR szExpanded[MAX_PATH + 1];
  120. Print("REG_EXPAND_SZ: \"%s\"\n", pbData);
  121. ExpandEnvironmentStringsA((LPCSTR)pbData, (LPSTR)&szExpanded,
  122. MAX_PATH);
  123. Print("expanded = \"%s\"\n", szExpanded);
  124. break;
  125. }
  126. case REG_DWORD:
  127. {
  128. DWORD dwData = * ((DWORD *)pbData);
  129. Print("REG_DWORD: %lu = 0x%08X\n", dwData, dwData);
  130. break;
  131. }
  132. case REG_BINARY:
  133. {
  134. Print("REG_BINARY:\n");
  135. PrintBinary(pbData, cbData, uWidth);
  136. break;
  137. }
  138. case REG_MULTI_SZ:
  139. {
  140. Print("REG_MULTI_SZ:\n");
  141. PrintMultiSz(pbData);
  142. break;
  143. }
  144. }
  145. }
  146. VOID EnumSubKeys(HKEY hkeyRoot, LPSTR szKey)
  147. {
  148. HKEY hkey;
  149. LONG l;
  150. BOOL fFound = FALSE;
  151. l = RegOpenKeyExA(hkeyRoot, szKey, 0, KEY_READ, &hkey);
  152. if (ERROR_SUCCESS == l)
  153. {
  154. FILETIME ft;
  155. DWORD cbName;
  156. CHAR szName[MAX_PATH + 1];
  157. DWORD dwIndex;
  158. for (dwIndex = 0; l == ERROR_SUCCESS; dwIndex++)
  159. {
  160. cbName = MAX_PATH;
  161. l = RegEnumKeyExA(hkey, dwIndex, szName, &cbName, NULL,
  162. NULL, NULL,&ft);
  163. if (ERROR_SUCCESS == l)
  164. {
  165. Print("Subkey: %s\n", szName);
  166. fFound = TRUE;
  167. }
  168. }
  169. RegCloseKey(hkey);
  170. }
  171. else
  172. {
  173. Print("Could not open subkey %s. Error (%d).\n", szKey, l);
  174. }
  175. if (!fFound)
  176. {
  177. Print("No subkeys\n");
  178. }
  179. }
  180. VOID EnumValues(HKEY hkeyRoot, LPSTR szKey, USHORT uWidth)
  181. {
  182. HKEY hkey;
  183. LONG l;
  184. BOOL fFound = FALSE;
  185. l = RegOpenKeyExA(hkeyRoot, szKey, 0, KEY_READ, &hkey);
  186. if (ERROR_SUCCESS == l)
  187. {
  188. DWORD cbMax;
  189. l = RegQueryInfoKeyA(hkey, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  190. NULL, &cbMax, NULL, NULL);
  191. if (ERROR_SUCCESS == l)
  192. {
  193. DWORD cbName;
  194. CHAR szName[MAX_PATH + 1];
  195. DWORD dwIndex;
  196. PBYTE pbData;
  197. DWORD dwType;
  198. DWORD cbData;
  199. pbData = (PBYTE)LocalAlloc(LPTR, cbMax);
  200. if (pbData)
  201. {
  202. for (dwIndex = 0; l == ERROR_SUCCESS; dwIndex++)
  203. {
  204. cbName = MAX_PATH;
  205. cbData = cbMax;
  206. l = RegEnumValueA(hkey, dwIndex, szName, &cbName, NULL,
  207. &dwType, pbData, &cbData);
  208. if (ERROR_SUCCESS == l)
  209. {
  210. Print("Value: \"%s\" - ", szName);
  211. PrintRegistryValue(dwType, pbData, cbData, uWidth);
  212. Print("------------------------------------------------------------------------\n");
  213. fFound = TRUE;
  214. }
  215. }
  216. LocalFree(pbData);
  217. }
  218. }
  219. RegCloseKey(hkey);
  220. }
  221. else
  222. {
  223. Print("Could not open subkey %s. Error (%d).\n", szKey, l);
  224. }
  225. if (!fFound)
  226. {
  227. Print("No values\n");
  228. }
  229. }
  230. /************************************************************************\
  231. * Procedure: Idreg
  232. *
  233. * Description: Dumps registry value
  234. *
  235. * Returns: fSuccess
  236. *
  237. * 4/14/1999 Created DanielWe
  238. *
  239. \************************************************************************/
  240. BOOL Idreg(
  241. DWORD opts,
  242. LPCSTR InString)
  243. {
  244. LONG l;
  245. HKEY hkey;
  246. DWORD cbData = 0;
  247. DWORD dwType;
  248. LPBYTE pbData = NULL;
  249. LPSTR szKey = NULL;
  250. LPSTR szValue = NULL;
  251. CHAR String[512];
  252. LPTSTR lpas = String;
  253. LPTSTR lpasOrig = String;
  254. HKEY hkeyRoot;
  255. strcpy(String, InString);
  256. // Eat leading spaces first
  257. while (*lpas && *lpas == ' ')
  258. {
  259. lpas++;
  260. }
  261. while (*lpas && *lpas != '\\')
  262. {
  263. lpas++;
  264. }
  265. if (!*lpas)
  266. {
  267. // Corner case.. no backslash at all. Assume HKLM and start over
  268. hkeyRoot = HKEY_LOCAL_MACHINE;
  269. lpas = lpasOrig;
  270. }
  271. else
  272. {
  273. // Figure out which hive they want to open
  274. *lpas = 0;
  275. if (!lstrcmpiA(lpasOrig, "hkcu"))
  276. {
  277. hkeyRoot = HKEY_CURRENT_USER;
  278. lpas++;
  279. }
  280. else if (!lstrcmpiA(lpasOrig, "hklm"))
  281. {
  282. hkeyRoot = HKEY_LOCAL_MACHINE;
  283. lpas++;
  284. }
  285. else if (!lstrcmpiA(lpasOrig, "hku"))
  286. {
  287. hkeyRoot = HKEY_USERS;
  288. lpas++;
  289. }
  290. else if (!lstrcmpiA(lpasOrig, "hkcr"))
  291. {
  292. hkeyRoot = HKEY_CLASSES_ROOT;
  293. lpas++;
  294. }
  295. else if (!lstrcmpiA(lpasOrig, "help"))
  296. {
  297. dregHelp();
  298. return FALSE;
  299. }
  300. else
  301. {
  302. hkeyRoot = HKEY_LOCAL_MACHINE;
  303. // Restore the backslash because we assume if they don't use these
  304. // keywords, then they want HKLM
  305. *lpas = '\\';
  306. lpas = lpasOrig;
  307. }
  308. }
  309. szKey = (LPSTR)lpas;
  310. while (*lpas && *lpas != '!')
  311. {
  312. lpas++;
  313. }
  314. if (*lpas)
  315. {
  316. // Null terminate the !
  317. *lpas++ = 0;
  318. // mark beginning of new string
  319. szValue = (LPSTR)lpas;
  320. }
  321. if (szKey == NULL || *szKey == 0)
  322. {
  323. Print("Expected subkey name\n");
  324. dregHelp();
  325. return FALSE;
  326. }
  327. if (szValue == NULL || *szValue == 0)
  328. {
  329. EnumSubKeys(hkeyRoot, szKey);
  330. }
  331. else if (!lstrcmpA(szValue, "*"))
  332. {
  333. EnumValues(hkeyRoot, szKey, (USHORT)opts);
  334. }
  335. else
  336. {
  337. l = RegOpenKeyExA(hkeyRoot, (LPCSTR)szKey, 0, KEY_READ, &hkey);
  338. if (ERROR_SUCCESS == l)
  339. {
  340. l = RegQueryValueExA(hkey, (LPCSTR)szValue, NULL, &dwType, NULL,
  341. &cbData);
  342. if (ERROR_SUCCESS == l)
  343. {
  344. pbData = (LPBYTE)LocalAlloc(LPTR, cbData);
  345. l = RegQueryValueExA(hkey, (LPCSTR)szValue, NULL, &dwType, pbData,
  346. &cbData);
  347. if (ERROR_SUCCESS == l)
  348. {
  349. PrintRegistryValue(dwType, pbData, cbData, (USHORT)opts);
  350. }
  351. LocalFree(pbData);
  352. }
  353. else
  354. {
  355. Print("Could not query value %s!%s. Error (%d).\n", szKey, szValue, l);
  356. }
  357. RegCloseKey(hkey);
  358. }
  359. else
  360. {
  361. Print("Could not open subkey %s. Error (%d).\n", szKey, l);
  362. }
  363. }
  364. return TRUE;
  365. }
  366. #endif // !KERNEL