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.

308 lines
7.1 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. rttrecpy.c
  5. Abstract:
  6. NT level registry api test program
  7. tree copy for the registry.
  8. rtdeltre <SourceKeyPath> <DestKeyPath>
  9. Will tree-copy the given registry subtree.
  10. Example:
  11. rttrecpy \REGISTRY\MACHINE\TEST\bigkey \registry\machine\test\bigcopy
  12. Author:
  13. John Vert (jvert) 22-Oct-1992
  14. Revision History:
  15. --*/
  16. #include "cmp.h"
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #define WORK_SIZE 1024
  21. void __cdecl main(int argc, char *);
  22. void processargs();
  23. void
  24. Copy(
  25. HANDLE Source,
  26. HANDLE Dest
  27. );
  28. UNICODE_STRING SourceName;
  29. UNICODE_STRING DestName;
  30. BOOLEAN CopySecurity;
  31. void
  32. __cdecl main(
  33. int argc,
  34. char *argv[]
  35. )
  36. {
  37. NTSTATUS Status;
  38. OBJECT_ATTRIBUTES ObjectAttributes;
  39. HANDLE SourceHandle;
  40. HANDLE DestHandle;
  41. //
  42. // Process args
  43. //
  44. processargs(argc, argv);
  45. //
  46. // Set up and open KeyPath
  47. //
  48. printf("rttrecpy: starting\n");
  49. InitializeObjectAttributes(
  50. &ObjectAttributes,
  51. &SourceName,
  52. OBJ_CASE_INSENSITIVE,
  53. (HANDLE)NULL,
  54. NULL
  55. );
  56. Status = NtOpenKey(
  57. &SourceHandle,
  58. KEY_READ,
  59. &ObjectAttributes
  60. );
  61. if (!NT_SUCCESS(Status)) {
  62. printf("rttrecpy: NtOpenKey %wS failed %08lx\n", &SourceName, Status);
  63. exit(1);
  64. }
  65. InitializeObjectAttributes(&ObjectAttributes,
  66. &DestName,
  67. OBJ_CASE_INSENSITIVE,
  68. NULL,
  69. NULL);
  70. Status = NtCreateKey(&DestHandle,
  71. KEY_WRITE,
  72. &ObjectAttributes,
  73. 0,
  74. NULL,
  75. 0,
  76. NULL);
  77. if (!NT_SUCCESS(Status)) {
  78. printf("rttrecpy: NtCreateKey %wS failed %08lx\n",DestName,Status);
  79. exit(1);
  80. }
  81. Copy(SourceHandle, DestHandle);
  82. }
  83. void
  84. Copy(
  85. HANDLE Source,
  86. HANDLE Dest
  87. )
  88. {
  89. NTSTATUS Status;
  90. PKEY_BASIC_INFORMATION KeyInformation;
  91. PKEY_VALUE_FULL_INFORMATION KeyValue;
  92. OBJECT_ATTRIBUTES ObjectAttributes;
  93. ULONG NamePos;
  94. ULONG index;
  95. STRING enumname;
  96. HANDLE SourceChild;
  97. HANDLE DestChild;
  98. ULONG ResultLength;
  99. static char buffer[WORK_SIZE];
  100. static char SecurityBuffer[WORK_SIZE];
  101. PSECURITY_DESCRIPTOR SecurityDescriptor;
  102. UNICODE_STRING ValueName;
  103. UNICODE_STRING KeyName;
  104. //
  105. // Enumerate source node's values and copy them to target node.
  106. //
  107. KeyValue = (PKEY_VALUE_FULL_INFORMATION)buffer;
  108. for (index = 0; TRUE; index++) {
  109. Status = NtEnumerateValueKey(Source,
  110. index,
  111. KeyValueFullInformation,
  112. buffer,
  113. WORK_SIZE,
  114. &ResultLength);
  115. if (!NT_SUCCESS(Status)) {
  116. if (Status == STATUS_NO_MORE_ENTRIES) {
  117. //
  118. // done with the values
  119. //
  120. break;
  121. } else {
  122. printf("rttrecpy: NtEnumerateValueKey failed %08lx\n",Status);
  123. break;
  124. }
  125. }
  126. ValueName.Buffer = KeyValue->Name;
  127. ValueName.Length = KeyValue->NameLength;
  128. Status = NtSetValueKey(Dest,
  129. &ValueName,
  130. KeyValue->TitleIndex,
  131. KeyValue->Type,
  132. buffer+KeyValue->DataOffset,
  133. KeyValue->DataLength);
  134. if (!NT_SUCCESS(Status)) {
  135. printf("rttrecpy: NtSetValueKey failed to set value %wS\n",&ValueName);
  136. }
  137. }
  138. //
  139. // Enumerate node's children and apply ourselves to each one
  140. //
  141. KeyInformation = (PKEY_BASIC_INFORMATION)buffer;
  142. if (CopySecurity) {
  143. SecurityDescriptor = SecurityBuffer;
  144. } else {
  145. SecurityDescriptor = NULL;
  146. }
  147. for (index = 0; TRUE; index++) {
  148. Status = NtEnumerateKey(Source,
  149. index,
  150. KeyBasicInformation,
  151. KeyInformation,
  152. WORK_SIZE,
  153. &ResultLength);
  154. if (Status == STATUS_NO_MORE_ENTRIES) {
  155. break;
  156. } else if (!NT_SUCCESS(Status)) {
  157. printf("rttrecpy: NtEnumerateKey failed Status = %08lx\n", Status);
  158. exit(1);
  159. }
  160. KeyName.Buffer = KeyInformation->Name;
  161. KeyName.Length = KeyInformation->NameLength;
  162. InitializeObjectAttributes(
  163. &ObjectAttributes,
  164. &KeyName,
  165. OBJ_CASE_INSENSITIVE,
  166. Source,
  167. NULL
  168. );
  169. Status = NtOpenKey(
  170. &SourceChild,
  171. KEY_READ,
  172. &ObjectAttributes
  173. );
  174. if (!NT_SUCCESS(Status)) {
  175. printf("rttrecpy: NtOpenKey %wS failed: %08lx\n", Status);
  176. exit(1);
  177. }
  178. if (CopySecurity) {
  179. Status = NtQuerySecurityObject(SourceChild,
  180. DACL_SECURITY_INFORMATION,
  181. SecurityDescriptor,
  182. WORK_SIZE,
  183. &ResultLength);
  184. if (!NT_SUCCESS(Status)) {
  185. printf("rttrecpy: NtQuerySecurityObject failed %08lx\n",Status);
  186. }
  187. }
  188. InitializeObjectAttributes(&ObjectAttributes,
  189. &KeyName,
  190. OBJ_CASE_INSENSITIVE,
  191. Dest,
  192. SecurityDescriptor);
  193. Status = NtCreateKey(&DestChild,
  194. KEY_READ | KEY_WRITE,
  195. &ObjectAttributes,
  196. 0,
  197. NULL,
  198. 0,
  199. NULL);
  200. if (!NT_SUCCESS(Status)) {
  201. printf("rttrecpy: NtCreateKey %wS failed %08lx\n",Status);
  202. exit(1);
  203. }
  204. Copy(SourceChild, DestChild);
  205. NtClose(SourceChild);
  206. NtClose(DestChild);
  207. }
  208. return;
  209. }
  210. void
  211. processargs(
  212. int argc,
  213. char *argv[]
  214. )
  215. {
  216. ANSI_STRING temp;
  217. char **p;
  218. if ( (argc > 4) || (argc < 3) )
  219. {
  220. printf("Usage: %s [-s] <SourceKey> <DestKey>\n",
  221. argv[0]);
  222. exit(1);
  223. }
  224. p=argv+1;
  225. if (_stricmp(*p,"-s")==0) {
  226. CopySecurity = TRUE;
  227. ++p;
  228. } else {
  229. CopySecurity = FALSE;
  230. }
  231. RtlInitAnsiString(
  232. &temp,
  233. *p
  234. );
  235. ++p;
  236. RtlAnsiStringToUnicodeString(
  237. &SourceName,
  238. &temp,
  239. TRUE
  240. );
  241. RtlInitAnsiString(&temp,
  242. *p);
  243. RtlAnsiStringToUnicodeString(&DestName,
  244. &temp,
  245. TRUE);
  246. return;
  247. }