309 lines
7.1 KiB
C
309 lines
7.1 KiB
C
/*++
|
||
|
||
Copyright (c) 1991 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
rttrecpy.c
|
||
|
||
Abstract:
|
||
|
||
NT level registry api test program
|
||
|
||
tree copy for the registry.
|
||
|
||
rtdeltre <SourceKeyPath> <DestKeyPath>
|
||
|
||
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 <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
|
||
#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] <SourceKey> <DestKey>\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;
|
||
}
|