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.

302 lines
8.0 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. regdmp.c
  5. Abstract:
  6. Utility to display all or part of the registry in a format that
  7. is suitable for input to the REGINI program.
  8. REGDMP [KeyPath]
  9. Will ennumerate and dump out the subkeys and values of KeyPath,
  10. and then apply itself recursively to each subkey it finds.
  11. Handles all value types (e.g. REG_???) defined in ntregapi.h
  12. Default KeyPath if none specified is \Registry
  13. Author:
  14. Steve Wood (stevewo) 12-Mar-92
  15. Revision History:
  16. --*/
  17. #include "regutil.h"
  18. BOOL
  19. DumpValues(
  20. HKEY KeyHandle,
  21. PWSTR KeyName,
  22. ULONG Depth
  23. );
  24. void
  25. DumpKeys(
  26. HKEY ParentKeyHandle,
  27. PWSTR KeyName,
  28. PWSTR FullPath,
  29. ULONG Depth
  30. );
  31. BOOLEAN SummaryOutput;
  32. BOOL
  33. CtrlCHandler(
  34. IN ULONG CtrlType
  35. )
  36. {
  37. RTDisconnectFromRegistry( &RegistryContext );
  38. return FALSE;
  39. }
  40. int
  41. __cdecl
  42. main(
  43. int argc,
  44. char *argv[]
  45. )
  46. {
  47. ULONG n;
  48. char *s;
  49. LONG Error;
  50. PWSTR RegistryPath;
  51. InitCommonCode( CtrlCHandler,
  52. "REGDMP",
  53. "[-s] [-o outputWidth] registryPath",
  54. "-s specifies summary output. Value names, type and first line of data\n"
  55. "\n"
  56. "registryPath specifies where to start dumping.\n"
  57. "\n"
  58. "If REGDMP detects any REG_SZ or REG_EXPAND_SZ that is missing the\n"
  59. "trailing null character, it will prefix the value string with the\n"
  60. "following text: (*** MISSING TRAILING NULL CHARACTER ***)\n"
  61. "The REGFIND tool can be used to clean these up, as this is a common\n"
  62. "programming error.\n"
  63. );
  64. RegistryPath = NULL;
  65. while (--argc) {
  66. s = *++argv;
  67. if (*s == '-' || *s == '/') {
  68. while (*++s) {
  69. switch( tolower( *s ) ) {
  70. case 'f':
  71. FullPathOutput = TRUE;
  72. break;
  73. case 's':
  74. SummaryOutput = TRUE;
  75. break;
  76. default:
  77. CommonSwitchProcessing( &argc, &argv, *s );
  78. break;
  79. }
  80. }
  81. }
  82. else
  83. if (RegistryPath == NULL) {
  84. RegistryPath = GetArgAsUnicode( s );
  85. }
  86. else {
  87. Usage( "May only specify one registry path to dump", 0 );
  88. }
  89. }
  90. Error = RTConnectToRegistry( MachineName,
  91. HiveFileName,
  92. HiveRootName,
  93. Win95Path,
  94. Win95UserPath,
  95. &RegistryPath,
  96. &RegistryContext
  97. );
  98. if (Error != NO_ERROR) {
  99. FatalError( "Unable to access registry specifed (%u)", Error, 0 );
  100. }
  101. DumpKeys( RegistryContext.HiveRootHandle, RegistryPath, RegistryPath, 0 );
  102. RTDisconnectFromRegistry( &RegistryContext );
  103. return 0;
  104. }
  105. void
  106. DumpKeys(
  107. HKEY ParentKeyHandle,
  108. PWSTR KeyName,
  109. PWSTR FullPath,
  110. ULONG Depth
  111. )
  112. {
  113. LONG Error;
  114. HKEY KeyHandle;
  115. ULONG SubKeyIndex;
  116. WCHAR SubKeyName[ MAX_PATH ];
  117. ULONG SubKeyNameLength;
  118. WCHAR ComputeFullPath[ MAX_PATH ];
  119. FILETIME LastWriteTime;
  120. BOOL AnyValues;
  121. Error = RTOpenKey( &RegistryContext,
  122. ParentKeyHandle,
  123. KeyName,
  124. MAXIMUM_ALLOWED,
  125. REG_OPTION_OPEN_LINK,
  126. &KeyHandle
  127. );
  128. if (Error != NO_ERROR) {
  129. if (Depth == 0) {
  130. FatalError( "Unable to open key '%ws' (%u)\n",
  131. (ULONG_PTR)KeyName,
  132. (ULONG)Error
  133. );
  134. }
  135. return;
  136. }
  137. //
  138. // Print name of node we are about to dump out
  139. //
  140. if (!FullPathOutput) {
  141. RTFormatKeyName( (PREG_OUTPUT_ROUTINE)fprintf, stdout, Depth * IndentMultiple, KeyName );
  142. RTFormatKeySecurity( (PREG_OUTPUT_ROUTINE)fprintf, stdout, KeyHandle, NULL );
  143. printf( "\n" );
  144. }
  145. //
  146. // Print out node's values
  147. //
  148. if (FullPathOutput)
  149. AnyValues = DumpValues( KeyHandle, FullPath, 0 );
  150. else
  151. DumpValues( KeyHandle, KeyName, Depth + 1 );
  152. //
  153. // Enumerate node's children and apply ourselves to each one
  154. //
  155. for (SubKeyIndex = 0; TRUE; SubKeyIndex++) {
  156. SubKeyNameLength = sizeof( SubKeyName ) / sizeof(WCHAR);
  157. Error = RTEnumerateKey( &RegistryContext,
  158. KeyHandle,
  159. SubKeyIndex,
  160. &LastWriteTime,
  161. &SubKeyNameLength,
  162. SubKeyName
  163. );
  164. if (Error != NO_ERROR) {
  165. if (Error != ERROR_NO_MORE_ITEMS && Error != ERROR_ACCESS_DENIED) {
  166. fprintf( stderr,
  167. "RTEnumerateKey( %ws ) failed (%u), skipping\n",
  168. KeyName,
  169. Error
  170. );
  171. }
  172. break;
  173. }
  174. if (FullPathOutput) {
  175. wcscpy(ComputeFullPath, FullPath);
  176. wcscat(ComputeFullPath, L"\\");
  177. wcscat(ComputeFullPath, SubKeyName);
  178. }
  179. DumpKeys( KeyHandle, SubKeyName, ComputeFullPath, Depth + 1 );
  180. }
  181. if (FullPathOutput) {
  182. if (SubKeyIndex == 0) {
  183. if (!AnyValues) {
  184. fprintf(stdout, "%ws\n", FullPath );
  185. }
  186. }
  187. }
  188. RTCloseKey( &RegistryContext, KeyHandle );
  189. return;
  190. }
  191. BOOL
  192. DumpValues(
  193. HKEY KeyHandle,
  194. PWSTR KeyName,
  195. ULONG Depth
  196. )
  197. {
  198. LONG Error;
  199. DWORD ValueIndex;
  200. DWORD ValueType;
  201. DWORD ValueNameLength;
  202. WCHAR ValueName[ MAX_PATH ];
  203. DWORD ValueDataLength;
  204. for (ValueIndex = 0; TRUE; ValueIndex++) {
  205. ValueType = REG_NONE;
  206. ValueNameLength = sizeof( ValueName ) / sizeof( WCHAR );
  207. ValueDataLength = OldValueBufferSize;
  208. Error = RTEnumerateValueKey( &RegistryContext,
  209. KeyHandle,
  210. ValueIndex,
  211. &ValueType,
  212. &ValueNameLength,
  213. ValueName,
  214. &ValueDataLength,
  215. OldValueBuffer
  216. );
  217. if (Error == NO_ERROR) {
  218. if (FullPathOutput) {
  219. fprintf(stdout, "%ws -> ", KeyName );
  220. }
  221. RTFormatKeyValue( OutputWidth,
  222. (PREG_OUTPUT_ROUTINE)fprintf,
  223. stdout,
  224. SummaryOutput,
  225. Depth * IndentMultiple,
  226. ValueName,
  227. ValueDataLength,
  228. ValueType,
  229. OldValueBuffer
  230. );
  231. }
  232. else
  233. if (Error == ERROR_NO_MORE_ITEMS) {
  234. if (ValueIndex == 0) {
  235. return FALSE;
  236. }
  237. else {
  238. return TRUE;
  239. }
  240. }
  241. else {
  242. if (DebugOutput) {
  243. fprintf( stderr,
  244. "RTEnumerateValueKey( %ws ) failed (%u)\n",
  245. KeyName,
  246. Error
  247. );
  248. }
  249. return FALSE;
  250. }
  251. }
  252. }