mirror of https://github.com/tongzx/nt5src
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
308 lines
7.1 KiB
/*++
|
|
|
|
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;
|
|
}
|