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.

357 lines
7.5 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. rtdmp.c
  5. Abstract:
  6. NT level registry api test program #3, basic non-error paths.
  7. Dump out a sub-tree of the registry.
  8. rtdmp <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. It assumes data values are null terminated strings.
  12. Example:
  13. rtdmp \REGISTRY\MACHINE\TEST\bigkey
  14. \REGISTRY\MACHINE\TEST\bigkey::
  15. ValueTest1_01 type=0 ti=1
  16. "This is a test string"
  17. ValueTest1_01 type=0 ti=2
  18. "This is a test string"
  19. \REGISTRY\MACHCINE\TEST\bigkey\child_key_1::
  20. ValueTest1_01 type=0 ti=1
  21. "This is a test string"
  22. ValueTest1_01 type=0 ti=2
  23. "This is a test string"
  24. Author:
  25. Bryan Willman (bryanwi) 10-Dec-91
  26. Revision History:
  27. --*/
  28. #include "cmp.h"
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #define WORK_SIZE 16384
  33. void __cdecl main(int, char *);
  34. void processargs();
  35. void print(PUNICODE_STRING);
  36. void
  37. DumpValues(
  38. HANDLE Handle
  39. );
  40. void
  41. Dump(
  42. HANDLE Handle
  43. );
  44. UNICODE_STRING WorkName;
  45. WCHAR workbuffer[WORK_SIZE];
  46. void
  47. __cdecl main(
  48. int argc,
  49. char *argv[]
  50. )
  51. {
  52. NTSTATUS status;
  53. OBJECT_ATTRIBUTES ObjectAttributes;
  54. HANDLE BaseHandle;
  55. //
  56. // Process args
  57. //
  58. WorkName.MaximumLength = WORK_SIZE;
  59. WorkName.Length = 0L;
  60. WorkName.Buffer = &(workbuffer[0]);
  61. processargs(argc, argv);
  62. //
  63. // Set up and open KeyPath
  64. //
  65. printf("rtdmp: starting\n");
  66. InitializeObjectAttributes(
  67. &ObjectAttributes,
  68. &WorkName,
  69. 0,
  70. (HANDLE)NULL,
  71. NULL
  72. );
  73. ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;
  74. status = NtOpenKey(
  75. &BaseHandle,
  76. MAXIMUM_ALLOWED,
  77. &ObjectAttributes
  78. );
  79. if (!NT_SUCCESS(status)) {
  80. printf("rtdmp: t0: %08lx\n", status);
  81. exit(1);
  82. }
  83. Dump(BaseHandle);
  84. }
  85. void
  86. Dump(
  87. HANDLE Handle
  88. )
  89. {
  90. NTSTATUS status;
  91. PKEY_BASIC_INFORMATION KeyInformation;
  92. OBJECT_ATTRIBUTES ObjectAttributes;
  93. ULONG NamePos;
  94. ULONG index;
  95. STRING enumname;
  96. HANDLE WorkHandle;
  97. ULONG ResultLength;
  98. static char buffer[WORK_SIZE];
  99. PUCHAR p;
  100. KeyInformation = (PKEY_BASIC_INFORMATION)buffer;
  101. NamePos = WorkName.Length;
  102. //
  103. // Print name of node we are about to dump out
  104. //
  105. print(&WorkName);
  106. printf("::\n\n");
  107. //
  108. // Print out node's values
  109. //
  110. DumpValues(Handle);
  111. //
  112. // Enumerate node's children and apply ourselves to each one
  113. //
  114. for (index = 0; TRUE; index++) {
  115. RtlZeroMemory(KeyInformation, WORK_SIZE);
  116. status = NtEnumerateKey(
  117. Handle,
  118. index,
  119. KeyBasicInformation,
  120. KeyInformation,
  121. WORK_SIZE,
  122. &ResultLength
  123. );
  124. if (status == STATUS_NO_MORE_ENTRIES) {
  125. WorkName.Length = NamePos;
  126. return;
  127. } else if (!NT_SUCCESS(status)) {
  128. printf("rtdmp: dump1: status = %08lx\n", status);
  129. exit(1);
  130. }
  131. enumname.Buffer = &(KeyInformation->Name[0]);
  132. enumname.Length = KeyInformation->NameLength;
  133. enumname.MaximumLength = KeyInformation->NameLength;
  134. p = WorkName.Buffer;
  135. p += WorkName.Length;
  136. *p = '\\';
  137. p++;
  138. *p = '\0';
  139. WorkName.Length += 2;
  140. RtlAppendStringToString((PSTRING)&WorkName, (PSTRING)&enumname);
  141. InitializeObjectAttributes(
  142. &ObjectAttributes,
  143. &enumname,
  144. 0,
  145. Handle,
  146. NULL
  147. );
  148. ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;
  149. status = NtOpenKey(
  150. &WorkHandle,
  151. MAXIMUM_ALLOWED,
  152. &ObjectAttributes
  153. );
  154. if (!NT_SUCCESS(status)) {
  155. printf("rtdmp: dump2: %08lx\n", status);
  156. exit(1);
  157. }
  158. Dump(WorkHandle);
  159. NtClose(WorkHandle);
  160. WorkName.Length = NamePos;
  161. }
  162. }
  163. void
  164. DumpValues(
  165. HANDLE Handle
  166. )
  167. {
  168. NTSTATUS status;
  169. static char tempbuffer[WORK_SIZE];
  170. PKEY_VALUE_FULL_INFORMATION KeyValueInformation;
  171. ULONG index;
  172. ULONG ResultLength;
  173. PULONG p;
  174. ULONG i;
  175. UNICODE_STRING valname;
  176. KeyValueInformation = (PKEY_VALUE_FULL_INFORMATION)tempbuffer;
  177. for (index = 0; TRUE; index++) {
  178. RtlZeroMemory(KeyValueInformation, WORK_SIZE);
  179. status = NtEnumerateValueKey(
  180. Handle,
  181. index,
  182. KeyValueFullInformation,
  183. KeyValueInformation,
  184. WORK_SIZE,
  185. &ResultLength
  186. );
  187. if (status == STATUS_NO_MORE_ENTRIES) {
  188. return;
  189. } else if (!NT_SUCCESS(status)) {
  190. printf("rtdmp: dumpvalues: status = %08lx\n", status);
  191. exit(1);
  192. }
  193. printf("\t");
  194. valname.Length = KeyValueInformation->NameLength;
  195. valname.MaximumLength = KeyValueInformation->NameLength;
  196. valname.Buffer = (PWSTR)&(KeyValueInformation->Name[0]);
  197. printf("'");
  198. print(&valname);
  199. printf("'\n");
  200. printf(
  201. "\ttitle index = %d\ttype = ",
  202. KeyValueInformation->TitleIndex
  203. );
  204. switch( KeyValueInformation->Type ) {
  205. case REG_NONE:
  206. printf("NONE\n\tValue = 0x%x",
  207. *((PULONG)KeyValueInformation + KeyValueInformation->DataOffset));
  208. break;
  209. case REG_SZ:
  210. printf("REG_SZ\n\tValue = '%ws'",
  211. ((PUCHAR)KeyValueInformation + KeyValueInformation->DataOffset));
  212. break;
  213. case REG_BINARY:
  214. printf("REG_BINARY\n\tValue = (%lx)\n", KeyValueInformation->DataLength);
  215. p = (PULONG)KeyValueInformation + KeyValueInformation->DataOffset;
  216. i = 1;
  217. while (i <= KeyValueInformation->DataLength) {
  218. printf( " %08lx", *p++ );
  219. if ((i % 8) == 0) {
  220. printf( "\n" );
  221. }
  222. i += sizeof( ULONG );
  223. }
  224. break;
  225. // case REG_DWORD:
  226. case REG_DWORD_LITTLE_ENDIAN:
  227. printf("REG_DWORD\n\tValue = 0x%lx",
  228. *((PULONG)KeyValueInformation + KeyValueInformation->DataOffset));
  229. break;
  230. case REG_DWORD_BIG_ENDIAN:
  231. printf("REG_DWORD_BIG_ENDIAN\n\tValue = 0x%lx",
  232. *((PULONG)KeyValueInformation + KeyValueInformation->DataOffset));
  233. break;
  234. }
  235. printf("\n\n");
  236. }
  237. }
  238. void
  239. print(
  240. PUNICODE_STRING String
  241. )
  242. {
  243. static ANSI_STRING temp;
  244. static char tempbuffer[WORK_SIZE];
  245. temp.MaximumLength = WORK_SIZE;
  246. temp.Length = 0L;
  247. temp.Buffer = tempbuffer;
  248. RtlUnicodeStringToAnsiString(&temp, String, FALSE);
  249. printf("%s", temp.Buffer);
  250. return;
  251. }
  252. void
  253. processargs(
  254. int argc,
  255. char *argv[]
  256. )
  257. {
  258. ANSI_STRING temp;
  259. if ( (argc != 2) )
  260. {
  261. printf("Usage: %s <KeyPath>\n",
  262. argv[0]);
  263. exit(1);
  264. }
  265. RtlInitAnsiString(
  266. &temp,
  267. argv[1]
  268. );
  269. RtlAnsiStringToUnicodeString(
  270. &WorkName,
  271. &temp,
  272. FALSE
  273. );
  274. return;
  275. }