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.

541 lines
13 KiB

  1. /*
  2. File: regprint.c
  3. 'ras diag' sub context
  4. 08/21/01
  5. */
  6. #include "precomp.h"
  7. //
  8. // const's only used in this obj
  9. //
  10. static CONST WCHAR g_wszLParen = L'(';
  11. static CONST WCHAR g_wszRParen = L')';
  12. static CONST WCHAR g_wszAmp = L'@';
  13. static CONST WCHAR g_wszEqual = L'=';
  14. static CONST WCHAR g_wszQuote = L'\"';
  15. static CONST WCHAR g_wszColon = L':';
  16. static CONST WCHAR g_wszComma = L',';
  17. static CONST WCHAR g_wszZero = L'0';
  18. static CONST WCHAR g_pwszDword[] = L"dword:";
  19. static CONST WCHAR g_pwszHex[] = L"hex";
  20. static CONST WCHAR g_HexConversion[16] = {L'0', L'1', L'2', L'3', L'4', L'5',
  21. L'6', L'7', L'8', L'9', L'a', L'b',
  22. L'c', L'd', L'e', L'f'};
  23. static CONST REGISTRYROOT g_RegRoots[] =
  24. {
  25. L"HKEY_ROOT", 9, HKEY_ROOT,
  26. L"HKEY_LOCAL_MACHINE", 18, HKEY_LOCAL_MACHINE,
  27. L"HKEY_USERS", 10, HKEY_USERS,
  28. L"HKEY_CURRENT_USER", 17, HKEY_CURRENT_USER,
  29. L"HKEY_CURRENT_CONFIG", 19, HKEY_CURRENT_CONFIG,
  30. L"HKEY_CLASSES_ROOT", 17, HKEY_CLASSES_ROOT,
  31. L"HKEY_DYN_DATA", 13, HKEY_DYN_DATA,
  32. };
  33. static CONST UINT g_ulNumRegRoots = sizeof(g_RegRoots) / sizeof(REGISTRYROOT);
  34. static CONST PWCHAR g_pwszRegKeys[] =
  35. {
  36. RASREGCHK01, RASREGCHK02, RASREGCHK03, RASREGCHK04, RASREGCHK05,
  37. RASREGCHK06, RASREGCHK07, RASREGCHK08, RASREGCHK09, RASREGCHK10,
  38. RASREGCHK11, RASREGCHK12, RASREGCHK13, RASREGCHK14, RASREGCHK15,
  39. RASREGCHK16, RASREGCHK17, RASREGCHK18, RASREGCHK19, RASREGCHK20,
  40. RASREGCHK21, RASREGCHK22, RASREGCHK23, RASREGCHK24, RASREGCHK25,
  41. RASREGCHK26, RASREGCHK27, RASREGCHK28, RASREGCHK29, RASREGCHK30,
  42. RASREGCHK31, RASREGCHK32, RASREGCHK33, RASREGCHK34, RASREGCHK35,
  43. RASREGCHK36, RASREGCHK37, RASREGCHK38, RASREGCHK39, RASREGCHK40,
  44. RASREGCHK41, RASREGCHK42, RASREGCHK43, RASREGCHK44, RASREGCHK45,
  45. RASREGCHK46
  46. };
  47. static CONST UINT g_ulNumRegKeys = sizeof(g_pwszRegKeys) / sizeof(PWCHAR);
  48. //
  49. // This count is used to control how many places over to the right that we
  50. // print before going to the next line
  51. //
  52. UINT g_ulCharCount = 0;
  53. BOOL
  54. RegPrintSubtree(
  55. IN BUFFER_WRITE_FILE* pBuff,
  56. IN LPCWSTR pwszFullKeyName);
  57. HKEY
  58. ConvertRootStringToKey(
  59. IN CONST PWCHAR pwszFullKeyName);
  60. DWORD
  61. PutBranch(
  62. IN BUFFER_WRITE_FILE* pBuff,
  63. IN HKEY hKey,
  64. IN LPCWSTR pwszFullKeyName);
  65. VOID
  66. PutString(
  67. IN BUFFER_WRITE_FILE* pBuff,
  68. IN PWCHAR pwszString);
  69. VOID
  70. PutDword(
  71. IN BUFFER_WRITE_FILE* pBuff,
  72. IN DWORD Dword,
  73. IN BOOL fLeadingZeroes);
  74. VOID
  75. PutBinary(
  76. IN BUFFER_WRITE_FILE* pBuff,
  77. IN CONST BYTE FAR* lpBuffer,
  78. IN DWORD Type,
  79. IN DWORD cbBytes);
  80. VOID
  81. PrintRasRegistryKeys(
  82. IN BUFFER_WRITE_FILE* pBuff)
  83. {
  84. UINT i;
  85. BOOL bAtleastOneFail = FALSE;
  86. LPBYTE pFailed = NULL;
  87. do
  88. {
  89. pFailed = RutlAlloc(g_ulNumRegKeys * sizeof(BYTE), TRUE);
  90. if (!pFailed)
  91. {
  92. break;
  93. }
  94. for (i = 0; i < g_ulNumRegKeys; i++)
  95. {
  96. if (RegPrintSubtree(pBuff, g_pwszRegKeys[i]))
  97. {
  98. pFailed[i] = TRUE;
  99. bAtleastOneFail = TRUE;
  100. }
  101. }
  102. //
  103. // Print all failures at the end
  104. //
  105. if (bAtleastOneFail)
  106. {
  107. BufferWriteMessage(
  108. pBuff,
  109. g_hModule,
  110. MSG_RASDIAG_SHOW_RASCHK_REG_NOT_FOUND);
  111. for (i = 0; i < g_ulNumRegKeys; i++)
  112. {
  113. if (pFailed[i])
  114. {
  115. BufferWriteFileStrW(pBuff, g_pwszRegKeys[i]);
  116. WriteNewLine(pBuff);
  117. }
  118. }
  119. }
  120. } while (FALSE);
  121. //
  122. // Clean up
  123. //
  124. RutlFree(pFailed);
  125. return;
  126. }
  127. BOOL
  128. RegPrintSubtree(
  129. IN BUFFER_WRITE_FILE* pBuff,
  130. IN LPCWSTR pwszFullKeyName)
  131. {
  132. HKEY hKey = NULL;
  133. BOOL bReturn = TRUE;
  134. DWORD dwErr = ERROR_SUCCESS;
  135. do
  136. {
  137. hKey = ConvertRootStringToKey((PWCHAR)pwszFullKeyName);
  138. if (!hKey)
  139. {
  140. break;
  141. }
  142. if (PutBranch(pBuff, hKey, pwszFullKeyName))
  143. {
  144. break;
  145. }
  146. //
  147. // Success
  148. //
  149. bReturn = FALSE;
  150. } while (FALSE);
  151. //
  152. // Clean up
  153. //
  154. if (hKey)
  155. {
  156. RegCloseKey(hKey);
  157. }
  158. return bReturn;
  159. }
  160. HKEY
  161. ConvertRootStringToKey(
  162. IN CONST PWCHAR pwszFullKeyName)
  163. {
  164. HKEY hKey = NULL;
  165. UINT i;
  166. PWCHAR pwszKey = NULL;
  167. for (i = 0; i < g_ulNumRegRoots; i++)
  168. {
  169. if (RutlStrNCmp(
  170. pwszFullKeyName,
  171. g_RegRoots[i].RootText,
  172. g_RegRoots[i].TextLength))
  173. {
  174. continue;
  175. }
  176. if (pwszFullKeyName[g_RegRoots[i].TextLength] != g_pwszBackSlash)
  177. {
  178. continue;
  179. }
  180. pwszKey = pwszFullKeyName + g_RegRoots[i].TextLength + 1;
  181. if (RegOpenKeyEx(
  182. g_RegRoots[i].RootKey,
  183. pwszKey,
  184. 0,
  185. KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE,
  186. &hKey)
  187. )
  188. {
  189. hKey = NULL;
  190. break;
  191. }
  192. }
  193. return hKey;
  194. }
  195. DWORD
  196. PutBranch(
  197. IN BUFFER_WRITE_FILE* pBuff,
  198. IN HKEY hKey,
  199. IN LPCWSTR pwszFullKeyName)
  200. {
  201. HKEY hSubKey = NULL;
  202. DWORD dwErr = NO_ERROR;
  203. UINT ulLenFullKey = 0;
  204. PBYTE pbValueData = NULL;
  205. DWORD EnumIndex = 0, cchValueName = 0, cbValueData = 0, Type = 0;
  206. WCHAR szValueNameBuffer[MAX_PATH];
  207. LPTSTR lpSubKeyName = NULL, lpTempFullKeyName = NULL;
  208. do
  209. {
  210. //
  211. // Write out the section header.
  212. //
  213. BufferWriteFileCharW(pBuff, g_pwszLBracket);
  214. BufferWriteFileStrW(pBuff, pwszFullKeyName);
  215. BufferWriteFileCharW(pBuff, g_pwszRBracket);
  216. WriteNewLine(pBuff);
  217. //
  218. // Write out all of the value names and their data.
  219. //
  220. for (;;)
  221. {
  222. cchValueName = ARRAYSIZE(szValueNameBuffer);
  223. //
  224. // VALUE DATA
  225. // Query for data size
  226. //
  227. dwErr = RegEnumValue(
  228. hKey,
  229. EnumIndex++,
  230. szValueNameBuffer,
  231. &cchValueName,
  232. NULL,
  233. &Type,
  234. NULL,
  235. &cbValueData);
  236. BREAK_ON_DWERR(dwErr);
  237. //
  238. // allocate memory for data
  239. //
  240. pbValueData = LocalAlloc(LPTR, cbValueData + ExtraAllocLen(Type));
  241. if (!pbValueData)
  242. {
  243. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  244. break;
  245. }
  246. dwErr = RegQueryValueEx(
  247. hKey,
  248. szValueNameBuffer,
  249. NULL,
  250. &Type,
  251. pbValueData,
  252. &cbValueData);
  253. BREAK_ON_DWERR(dwErr);
  254. //
  255. // If cbValueName is zero, then this is the default value of
  256. // the key, or the Windows 3.1 compatible key value.
  257. //
  258. g_ulCharCount = 0;
  259. if (cchValueName)
  260. {
  261. PutString(pBuff, szValueNameBuffer);
  262. }
  263. else
  264. {
  265. BufferWriteFileCharW(pBuff, g_wszAmp);
  266. g_ulCharCount = 1;
  267. }
  268. BufferWriteFileCharW(pBuff, g_wszEqual);
  269. g_ulCharCount++;
  270. switch (Type)
  271. {
  272. case REG_SZ:
  273. PutString(pBuff, (PWCHAR)pbValueData);
  274. break;
  275. case REG_DWORD:
  276. if (cbValueData == sizeof(DWORD))
  277. {
  278. BufferWriteFileStrW(pBuff, g_pwszDword);
  279. PutDword(pBuff, *((LPDWORD) pbValueData), TRUE);
  280. break;
  281. }
  282. //
  283. // FALL THROUGH
  284. //
  285. case REG_BINARY:
  286. default:
  287. PutBinary(pBuff, (LPBYTE) pbValueData, Type, cbValueData);
  288. break;
  289. }
  290. WriteNewLine(pBuff);
  291. LocalFree(pbValueData);
  292. pbValueData = NULL;
  293. }
  294. WriteNewLine(pBuff);
  295. if (dwErr == ERROR_NO_MORE_ITEMS)
  296. {
  297. dwErr = NO_ERROR;
  298. }
  299. else
  300. {
  301. break;
  302. }
  303. //
  304. // Write out all of the subkeys and recurse into them.
  305. //
  306. // copy the existing key into a new buffer with enough room for the next key
  307. //
  308. ulLenFullKey = lstrlen(pwszFullKeyName);
  309. lpTempFullKeyName = LocalAlloc(
  310. LPTR,
  311. (ulLenFullKey + MAX_PATH) * sizeof(WCHAR));
  312. if (!lpTempFullKeyName)
  313. {
  314. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  315. break;
  316. }
  317. lstrcpy(lpTempFullKeyName, pwszFullKeyName);
  318. lpSubKeyName = lpTempFullKeyName + ulLenFullKey;
  319. *lpSubKeyName++ = g_pwszBackSlash;
  320. *lpSubKeyName = 0;
  321. EnumIndex = 0;
  322. for (;;)
  323. {
  324. dwErr = RegEnumKey(hKey, EnumIndex++, lpSubKeyName, MAX_PATH - 1);
  325. BREAK_ON_DWERR(dwErr);
  326. dwErr = RegOpenKeyEx(
  327. hKey,
  328. lpSubKeyName,
  329. 0,
  330. KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE,
  331. &hSubKey);
  332. BREAK_ON_DWERR(dwErr);
  333. dwErr = PutBranch(pBuff, hSubKey, lpTempFullKeyName);
  334. BREAK_ON_DWERR(dwErr);
  335. RegCloseKey(hSubKey);
  336. hSubKey = NULL;
  337. }
  338. if (dwErr == ERROR_NO_MORE_ITEMS)
  339. {
  340. dwErr = NO_ERROR;
  341. }
  342. } while (FALSE);
  343. //
  344. // Clean up
  345. //
  346. if (hSubKey)
  347. {
  348. RegCloseKey(hSubKey);
  349. hSubKey = NULL;
  350. }
  351. if (lpTempFullKeyName)
  352. {
  353. LocalFree(lpTempFullKeyName);
  354. lpTempFullKeyName = NULL;
  355. }
  356. if (pbValueData)
  357. {
  358. LocalFree(pbValueData);
  359. pbValueData = NULL;
  360. }
  361. return dwErr;
  362. }
  363. VOID
  364. PutString(
  365. IN BUFFER_WRITE_FILE* pBuff,
  366. IN PWCHAR pwszString)
  367. {
  368. WCHAR Char;
  369. BufferWriteFileCharW(pBuff, g_wszQuote);
  370. g_ulCharCount++;
  371. while ((Char = *pwszString++) != 0)
  372. {
  373. switch (Char)
  374. {
  375. case L'\\':
  376. case L'"':
  377. BufferWriteFileCharW(pBuff, g_pwszBackSlash);
  378. g_ulCharCount++;
  379. //
  380. // FALL THROUGH
  381. //
  382. default:
  383. BufferWriteFileCharW(pBuff, Char);
  384. g_ulCharCount++;
  385. break;
  386. }
  387. }
  388. BufferWriteFileCharW(pBuff, g_wszQuote);
  389. g_ulCharCount++;
  390. return;
  391. }
  392. VOID
  393. PutDword(
  394. IN BUFFER_WRITE_FILE* pBuff,
  395. IN DWORD Dword,
  396. IN BOOL fLeadingZeroes)
  397. {
  398. INT CurrentNibble;
  399. BOOL fWroteNonleadingChar = fLeadingZeroes;
  400. WCHAR Char;
  401. for (CurrentNibble = 7; CurrentNibble >= 0; CurrentNibble--)
  402. {
  403. Char = g_HexConversion[(Dword >> (CurrentNibble * 4)) & 0x0F];
  404. if (fWroteNonleadingChar || Char != g_wszZero)
  405. {
  406. BufferWriteFileCharW(pBuff, Char);
  407. g_ulCharCount++;
  408. fWroteNonleadingChar = TRUE;
  409. }
  410. }
  411. //
  412. // We need to write at least one character, so if we haven't written
  413. // anything yet, just spit out one zero.
  414. //
  415. if (!fWroteNonleadingChar)
  416. {
  417. BufferWriteFileCharW(pBuff, g_wszZero);
  418. g_ulCharCount++;
  419. }
  420. return;
  421. }
  422. VOID
  423. PutBinary(
  424. IN BUFFER_WRITE_FILE* pBuff,
  425. IN CONST BYTE FAR* lpBuffer,
  426. IN DWORD Type,
  427. IN DWORD cbBytes)
  428. {
  429. BOOL fFirstByteOnLine;
  430. BYTE Byte;
  431. BufferWriteFileStrW(pBuff, g_pwszHex);
  432. g_ulCharCount += 3;
  433. if (Type != REG_BINARY)
  434. {
  435. BufferWriteFileCharW(pBuff, g_wszLParen);
  436. PutDword(pBuff, Type, FALSE);
  437. BufferWriteFileCharW(pBuff, g_wszRParen);
  438. g_ulCharCount += 2;
  439. }
  440. BufferWriteFileCharW(pBuff, g_wszColon);
  441. g_ulCharCount++;
  442. fFirstByteOnLine = TRUE;
  443. while (cbBytes--)
  444. {
  445. if (g_ulCharCount > 75 && !fFirstByteOnLine)
  446. {
  447. BufferWriteFileCharW(pBuff, g_wszComma);
  448. BufferWriteFileCharW(pBuff, g_pwszBackSlash);
  449. WriteNewLine(pBuff);
  450. BufferWriteFileStrW(pBuff, g_pwszSpace);
  451. BufferWriteFileStrW(pBuff, g_pwszSpace);
  452. fFirstByteOnLine = TRUE;
  453. g_ulCharCount = 3;
  454. }
  455. if (!fFirstByteOnLine)
  456. {
  457. BufferWriteFileCharW(pBuff, g_wszComma);
  458. g_ulCharCount++;
  459. }
  460. Byte = *lpBuffer++;
  461. BufferWriteFileCharW(pBuff, g_HexConversion[Byte >> 4]);
  462. BufferWriteFileCharW(pBuff, g_HexConversion[Byte & 0x0F]);
  463. g_ulCharCount += 2;
  464. fFirstByteOnLine = FALSE;
  465. }
  466. return;
  467. }