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.

337 lines
8.6 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. hivedmp.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. HIVEDMP [-r] -f filename
  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. -r forces ALL value type to be output in RAW (hex) form.
  13. Default KeyPath if none specified is \Registry
  14. Author:
  15. Steve Wood (stevewo) 12-Mar-92
  16. Revision History:
  17. 30-Nov-92 bryanwi Add -r switch
  18. --*/
  19. #include "regutil.h"
  20. #include "edithive.h"
  21. void
  22. DumpValues(
  23. HANDLE HiveHandle,
  24. HANDLE KeyHandle,
  25. ULONG IndentLevel
  26. );
  27. void
  28. DumpKeys(
  29. HANDLE HiveHandle,
  30. HANDLE KeyHandle,
  31. PUNICODE_STRING KeyName,
  32. ULONG IndentLevel
  33. );
  34. void
  35. RegDumpKeyValueR(
  36. FILE *fh,
  37. PKEY_VALUE_FULL_INFORMATION KeyValueInformation,
  38. ULONG IndentLevel
  39. );
  40. PVOID ValueBuffer;
  41. ULONG ValueBufferSize;
  42. BOOLEAN RawOutput = FALSE;
  43. void
  44. Usage( void )
  45. {
  46. fprintf( stderr, "usage: HIVEDMP [-f hivefile]\n" );
  47. exit( 1 );
  48. }
  49. void
  50. __cdecl main(
  51. int argc,
  52. char *argv[]
  53. )
  54. {
  55. char *s;
  56. ANSI_STRING AnsiString;
  57. UNICODE_STRING KeyName;
  58. UNICODE_STRING DosName;
  59. UNICODE_STRING FileName;
  60. UNICODE_STRING RootName;
  61. HANDLE HiveHandle = NULL;
  62. HANDLE RootKey = NULL;
  63. BOOLEAN ArgumentSeen;
  64. LPSTR HiveFile=NULL;
  65. ValueBufferSize = VALUE_BUFFER_SIZE;
  66. ValueBuffer = VirtualAlloc( NULL, ValueBufferSize, MEM_COMMIT, PAGE_READWRITE );
  67. if (ValueBuffer == NULL) {
  68. fprintf( stderr, "REGDMP: Unable to allocate value buffer.\n" );
  69. exit( 1 );
  70. }
  71. ArgumentSeen = FALSE;
  72. while (--argc) {
  73. s = *++argv;
  74. if (*s == '-' || *s == '/') {
  75. while (*++s) {
  76. switch( tolower( *s ) ) {
  77. case 'd':
  78. DebugOutput = TRUE;
  79. break;
  80. case 's':
  81. SummaryOutput = TRUE;
  82. break;
  83. case 'r':
  84. RawOutput = TRUE;
  85. break;
  86. case 'f':
  87. if (argc--) {
  88. RtlInitString( &AnsiString, *++argv );
  89. RtlAnsiStringToUnicodeString( &DosName,
  90. &AnsiString,
  91. TRUE );
  92. RtlDosPathNameToNtPathName_U( DosName.Buffer,
  93. &FileName,
  94. NULL,
  95. NULL );
  96. HiveHandle = EhOpenHive( &FileName,
  97. &RootKey,
  98. &RootName,
  99. TYPE_SIMPLE );
  100. ArgumentSeen = TRUE;
  101. break;
  102. }
  103. default: Usage();
  104. }
  105. }
  106. }
  107. #if 0
  108. else {
  109. RtlInitString( &AnsiString, s );
  110. RtlAnsiStringToUnicodeString( &KeyName, &AnsiString, TRUE );
  111. DumpKeys( HiveHandle, RootKey, &KeyName, 0 );
  112. ArgumentSeen = TRUE;
  113. }
  114. #endif
  115. }
  116. if (ArgumentSeen) {
  117. if (HiveHandle != NULL) {
  118. DumpKeys( HiveHandle, RootKey, &RootName, 0 );
  119. } else {
  120. fprintf(stderr, "Couldn't open hive file %wZ\n",&DosName);
  121. }
  122. } else {
  123. Usage();
  124. }
  125. exit( 0 );
  126. }
  127. void
  128. DumpKeys(
  129. HANDLE HiveHandle,
  130. HANDLE KeyHandle,
  131. PUNICODE_STRING KeyName,
  132. ULONG IndentLevel
  133. )
  134. {
  135. NTSTATUS Status;
  136. HANDLE SubKeyHandle;
  137. WCHAR KeyBuffer[ 512 ];
  138. PKEY_BASIC_INFORMATION KeyInformation;
  139. OBJECT_ATTRIBUTES ObjectAttributes;
  140. ULONG SubKeyIndex;
  141. UNICODE_STRING SubKeyName;
  142. ULONG ResultLength;
  143. //
  144. // Print name of node we are about to dump out
  145. //
  146. printf( "%.*s%wZ\n",
  147. IndentLevel,
  148. " ",
  149. KeyName
  150. );
  151. //
  152. // Print out node's values
  153. //
  154. DumpValues( HiveHandle, KeyHandle, IndentLevel+4 );
  155. //
  156. // Enumerate node's children and apply ourselves to each one
  157. //
  158. KeyInformation = (PKEY_BASIC_INFORMATION)KeyBuffer;
  159. for (SubKeyIndex = 0; TRUE; SubKeyIndex++) {
  160. Status = EhEnumerateKey( HiveHandle,
  161. KeyHandle,
  162. SubKeyIndex,
  163. KeyBasicInformation,
  164. KeyInformation,
  165. sizeof( KeyBuffer ),
  166. &ResultLength
  167. );
  168. if (Status == STATUS_NO_MORE_ENTRIES) {
  169. return;
  170. }
  171. else
  172. if (!NT_SUCCESS( Status )) {
  173. fprintf( stderr,
  174. "REGDMP: NtEnumerateKey failed - Status ==%08lx\n",
  175. Status
  176. );
  177. exit( 1 );
  178. }
  179. SubKeyName.Buffer = (PWSTR)&(KeyInformation->Name[0]);
  180. SubKeyName.Length = (USHORT)KeyInformation->NameLength;
  181. SubKeyName.MaximumLength = (USHORT)KeyInformation->NameLength;
  182. Status = EhOpenChildByName( HiveHandle,
  183. KeyHandle,
  184. &SubKeyName,
  185. &SubKeyHandle );
  186. if (NT_SUCCESS(Status)) {
  187. DumpKeys( HiveHandle, SubKeyHandle, &SubKeyName, IndentLevel+4 );
  188. }
  189. }
  190. }
  191. void
  192. DumpValues(
  193. HANDLE HiveHandle,
  194. HANDLE KeyHandle,
  195. ULONG IndentLevel
  196. )
  197. {
  198. NTSTATUS Status;
  199. PKEY_VALUE_FULL_INFORMATION KeyValueInformation;
  200. ULONG ValueIndex;
  201. ULONG ResultLength;
  202. KeyValueInformation = (PKEY_VALUE_FULL_INFORMATION)ValueBuffer;
  203. for (ValueIndex = 0; TRUE; ValueIndex++) {
  204. Status = EhEnumerateValueKey( HiveHandle,
  205. KeyHandle,
  206. ValueIndex,
  207. KeyValueFullInformation,
  208. KeyValueInformation,
  209. ValueBufferSize,
  210. &ResultLength
  211. );
  212. if (Status == STATUS_NO_MORE_ENTRIES) {
  213. return;
  214. } else if (!NT_SUCCESS( Status )) {
  215. fprintf( stderr,
  216. "REGDMP: NtEnumerateValueKey failed - Status == %08lx\n",
  217. Status
  218. );
  219. exit( 1 );
  220. }
  221. if (RawOutput == TRUE) {
  222. RegDumpKeyValueR( stdout, KeyValueInformation, IndentLevel );
  223. } else {
  224. RegDumpKeyValue( stdout, KeyValueInformation, IndentLevel );
  225. }
  226. }
  227. }
  228. void
  229. RegDumpKeyValueR(
  230. FILE *fh,
  231. PKEY_VALUE_FULL_INFORMATION KeyValueInformation,
  232. ULONG IndentLevel
  233. )
  234. {
  235. PULONG p;
  236. PWSTR pw, pw1;
  237. ULONG i, j, k, m, cbPrefix;
  238. UNICODE_STRING ValueName;
  239. PUCHAR pbyte;
  240. cbPrefix = fprintf( fh, "%.*s",
  241. IndentLevel,
  242. " "
  243. );
  244. ValueName.Buffer = (PWSTR)&(KeyValueInformation->Name[0]);
  245. ValueName.Length = (USHORT)KeyValueInformation->NameLength;
  246. ValueName.MaximumLength = (USHORT)KeyValueInformation->NameLength;
  247. if (ValueName.Length) {
  248. cbPrefix += fprintf( fh, "%wS ", &ValueName );
  249. }
  250. cbPrefix += fprintf( fh, "= " );
  251. if (KeyValueInformation->DataLength == 0) {
  252. fprintf( fh, " [no data] \n");
  253. return;
  254. }
  255. fprintf( fh, "REG_BINARY 0x%08lx", KeyValueInformation->DataLength );
  256. p = (PULONG)((PCHAR)KeyValueInformation + KeyValueInformation->DataOffset);
  257. i = (KeyValueInformation->DataLength + 3) / sizeof( ULONG );
  258. for (j=0; j<i; j++) {
  259. if ((j % 8) == 0) {
  260. fprintf( fh, "\n%.*s",
  261. IndentLevel+4,
  262. " "
  263. );
  264. }
  265. fprintf( fh, "0x%08lx ", *p++ );
  266. }
  267. fprintf( fh, "\n" );
  268. fprintf( fh, "\n" );
  269. return;
  270. }