/*++ Copyright (c) 1991 Microsoft Corporation Module Name: rttrecpy.c Abstract: NT level registry api test program tree copy for the registry. rtdeltre Will tree-copy the given registry subtree. Example: rttrecpy \REGISTRY\MACHINE\TEST\bigkey \registry\machine\test\bigcopy Author: John Vert (jvert) 22-Oct-1992 Revision History: --*/ #include "cmp.h" #include #include #include #define WORK_SIZE 1024 void __cdecl main(int argc, char *); void processargs(); void Copy( HANDLE Source, HANDLE Dest ); UNICODE_STRING SourceName; UNICODE_STRING DestName; BOOLEAN CopySecurity; void __cdecl main( int argc, char *argv[] ) { NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE SourceHandle; HANDLE DestHandle; // // Process args // processargs(argc, argv); // // Set up and open KeyPath // printf("rttrecpy: starting\n"); InitializeObjectAttributes( &ObjectAttributes, &SourceName, OBJ_CASE_INSENSITIVE, (HANDLE)NULL, NULL ); Status = NtOpenKey( &SourceHandle, KEY_READ, &ObjectAttributes ); if (!NT_SUCCESS(Status)) { printf("rttrecpy: NtOpenKey %wS failed %08lx\n", &SourceName, Status); exit(1); } InitializeObjectAttributes(&ObjectAttributes, &DestName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtCreateKey(&DestHandle, KEY_WRITE, &ObjectAttributes, 0, NULL, 0, NULL); if (!NT_SUCCESS(Status)) { printf("rttrecpy: NtCreateKey %wS failed %08lx\n",DestName,Status); exit(1); } Copy(SourceHandle, DestHandle); } void Copy( HANDLE Source, HANDLE Dest ) { NTSTATUS Status; PKEY_BASIC_INFORMATION KeyInformation; PKEY_VALUE_FULL_INFORMATION KeyValue; OBJECT_ATTRIBUTES ObjectAttributes; ULONG NamePos; ULONG index; STRING enumname; HANDLE SourceChild; HANDLE DestChild; ULONG ResultLength; static char buffer[WORK_SIZE]; static char SecurityBuffer[WORK_SIZE]; PSECURITY_DESCRIPTOR SecurityDescriptor; UNICODE_STRING ValueName; UNICODE_STRING KeyName; // // Enumerate source node's values and copy them to target node. // KeyValue = (PKEY_VALUE_FULL_INFORMATION)buffer; for (index = 0; TRUE; index++) { Status = NtEnumerateValueKey(Source, index, KeyValueFullInformation, buffer, WORK_SIZE, &ResultLength); if (!NT_SUCCESS(Status)) { if (Status == STATUS_NO_MORE_ENTRIES) { // // done with the values // break; } else { printf("rttrecpy: NtEnumerateValueKey failed %08lx\n",Status); break; } } ValueName.Buffer = KeyValue->Name; ValueName.Length = KeyValue->NameLength; Status = NtSetValueKey(Dest, &ValueName, KeyValue->TitleIndex, KeyValue->Type, buffer+KeyValue->DataOffset, KeyValue->DataLength); if (!NT_SUCCESS(Status)) { printf("rttrecpy: NtSetValueKey failed to set value %wS\n",&ValueName); } } // // Enumerate node's children and apply ourselves to each one // KeyInformation = (PKEY_BASIC_INFORMATION)buffer; if (CopySecurity) { SecurityDescriptor = SecurityBuffer; } else { SecurityDescriptor = NULL; } for (index = 0; TRUE; index++) { Status = NtEnumerateKey(Source, index, KeyBasicInformation, KeyInformation, WORK_SIZE, &ResultLength); if (Status == STATUS_NO_MORE_ENTRIES) { break; } else if (!NT_SUCCESS(Status)) { printf("rttrecpy: NtEnumerateKey failed Status = %08lx\n", Status); exit(1); } KeyName.Buffer = KeyInformation->Name; KeyName.Length = KeyInformation->NameLength; InitializeObjectAttributes( &ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, Source, NULL ); Status = NtOpenKey( &SourceChild, KEY_READ, &ObjectAttributes ); if (!NT_SUCCESS(Status)) { printf("rttrecpy: NtOpenKey %wS failed: %08lx\n", Status); exit(1); } if (CopySecurity) { Status = NtQuerySecurityObject(SourceChild, DACL_SECURITY_INFORMATION, SecurityDescriptor, WORK_SIZE, &ResultLength); if (!NT_SUCCESS(Status)) { printf("rttrecpy: NtQuerySecurityObject failed %08lx\n",Status); } } InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, Dest, SecurityDescriptor); Status = NtCreateKey(&DestChild, KEY_READ | KEY_WRITE, &ObjectAttributes, 0, NULL, 0, NULL); if (!NT_SUCCESS(Status)) { printf("rttrecpy: NtCreateKey %wS failed %08lx\n",Status); exit(1); } Copy(SourceChild, DestChild); NtClose(SourceChild); NtClose(DestChild); } return; } void processargs( int argc, char *argv[] ) { ANSI_STRING temp; char **p; if ( (argc > 4) || (argc < 3) ) { printf("Usage: %s [-s] \n", argv[0]); exit(1); } p=argv+1; if (_stricmp(*p,"-s")==0) { CopySecurity = TRUE; ++p; } else { CopySecurity = FALSE; } RtlInitAnsiString( &temp, *p ); ++p; RtlAnsiStringToUnicodeString( &SourceName, &temp, TRUE ); RtlInitAnsiString(&temp, *p); RtlAnsiStringToUnicodeString(&DestName, &temp, TRUE); return; }