Leaked source code of windows server 2003
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.
 
 
 
 
 
 

348 lines
8.7 KiB

/*++
Copyright (c) 1998 Microsoft Corporation
Module Name:
regcopy.c
Abstract:
This is for supporting copying and munging the registry files.
Author:
Sean Selitrennikoff - 4/5/98
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
typedef BOOL (*PFNGETPROFILESDIRECTORYW)(LPWSTR lpProfile, LPDWORD dwSize);
HKEY HiveRoot;
REG_CONTEXT RegistryContext;
PWSTR MachineName;
PWSTR HiveFileName;
PWSTR HiveRootName;
DWORD
DoFullRegBackup(
PWCHAR MirrorRoot
)
/*++
Routine Description:
This routine copies all the registries to the given server path.
Arguments:
None.
Return Value:
NO_ERROR if everything was backed up properly, else the appropriate error code.
--*/
{
PWSTR w;
LONG Error;
HKEY HiveListKey;
PWSTR KeyName;
PWSTR FileName;
PWSTR Name;
DWORD ValueIndex;
DWORD ValueType;
DWORD ValueNameLength;
DWORD ValueDataLength;
WCHAR ConfigPath[ MAX_PATH ];
WCHAR HiveName[ MAX_PATH ];
WCHAR HivePath[ MAX_PATH ];
WCHAR DirectoryPath[ MAX_PATH ];
WCHAR FilePath[ MAX_PATH ];
HANDLE hInstDll;
PFNGETPROFILESDIRECTORYW pfnGetProfilesDirectory;
NTSTATUS Status;
BOOLEAN savedBackup;
//
// First try and give ourselves enough priviledge
//
if (!RTEnableBackupRestorePrivilege()) {
return(GetLastError());
}
//
// Now attach to the registry
//
Error = RTConnectToRegistry(MachineName,
HiveFileName,
HiveRootName,
NULL,
&RegistryContext
);
if (Error != NO_ERROR) {
RTDisableBackupRestorePrivilege();
return Error;
}
//
// Get handle to hivelist key
//
KeyName = L"HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Hivelist";
Error = RTOpenKey(&RegistryContext,
NULL,
KeyName,
MAXIMUM_ALLOWED,
0,
&HiveListKey
);
if (Error != NO_ERROR) {
RTDisconnectFromRegistry(&RegistryContext);
return Error;
}
//
// get path data for system hive, which will allow us to compute
// path name to config dir in form that hivelist uses.
// (an NT internal form of path) this is NOT the way the path to
// the config directory should generally be computed.
//
ValueDataLength = sizeof(ConfigPath);
Error = RTQueryValueKey(&RegistryContext,
HiveListKey,
L"\\Registry\\Machine\\System",
&ValueType,
&ValueDataLength,
ConfigPath
);
if (Error != NO_ERROR) {
RTDisconnectFromRegistry(&RegistryContext);
return Error;
}
w = wcsrchr(ConfigPath, L'\\');
*w = UNICODE_NULL;
//
// ennumerate entries in hivelist. for each entry, find it's hive file
// path then save it.
//
for (ValueIndex = 0; TRUE; ValueIndex++) {
savedBackup = FALSE;
ValueType = REG_NONE;
ValueNameLength = ARRAYSIZE( HiveName );
ValueDataLength = sizeof( HivePath );
Error = RTEnumerateValueKey(&RegistryContext,
HiveListKey,
ValueIndex,
&ValueType,
&ValueNameLength,
HiveName,
&ValueDataLength,
HivePath
);
if (Error == ERROR_NO_MORE_ITEMS) {
break;
} else if (Error != NO_ERROR) {
RTDisconnectFromRegistry(&RegistryContext);
return Error;
}
//printf("HiveName='%ws', HivePath='%ws'\n", HiveName, HivePath);
if ((ValueType == REG_SZ) && (ValueDataLength > sizeof(UNICODE_NULL))) {
//
// there's a file, compute it's path, hive branch, etc
//
if (w = wcsrchr( HivePath, L'\\' )) {
*w++ = UNICODE_NULL;
}
FileName = w;
if (w = wcsrchr( HiveName, L'\\' )) {
*w++ = UNICODE_NULL;
}
Name = w;
HiveRoot = NULL;
if (w = wcsrchr( HiveName, L'\\' )) {
w += 1;
if (!_wcsicmp( w, L"MACHINE" )) {
HiveRoot = HKEY_LOCAL_MACHINE;
} else if (!_wcsicmp( w, L"USER" )) {
HiveRoot = HKEY_USERS;
} else {
printf("Unexpected hive with hive name %ws skipped\n", HiveName);
continue;
}
}
if (FileName != NULL && Name != NULL && HiveRoot != NULL) {
//
// Extract the path name from HivePath
//
if (_wcsicmp(HivePath, L"\\Device")) {
w = HivePath + 1;
w = wcsstr(w, L"\\");
w++;
w = wcsstr(w, L"\\");
w++;
} else if (*(HivePath + 1) == L':') {
w = HivePath + 2;
} else {
printf("Unexpected hive with file name %ws skipped\n", HivePath);
continue;
}
//
// Do the save
//
swprintf( DirectoryPath, L"%ws\\%ws", MirrorRoot, w );
swprintf( FilePath, L"%ws\\%ws\\%ws", MirrorRoot, w, FileName );
printf("Now copying hive %ws\\%ws to %ws\n", HiveName, Name, FilePath);
#if 1
Error = DoSpecificRegBackup(DirectoryPath,
FilePath,
HiveRoot,
Name
);
#else
Error = NO_ERROR;
#endif
if (Error != NO_ERROR) {
printf("Error %d copying hive\n", Error);
//return Error;
}
}
}
}
RTDisconnectFromRegistry(&RegistryContext);
return NO_ERROR;
}
DWORD
CreateHiveDirectory (
PWSTR HiveDirectory
)
{
PWSTR p;
p = wcschr( HiveDirectory, L'\\' );
if ( (p == HiveDirectory) ||
((p != HiveDirectory) && (*(p-1) == L':')) ) {
p = wcschr( p + 1, L'\\' );
}
while ( p != NULL ) {
*p = 0;
CreateDirectory( HiveDirectory, NULL );
*p = L'\\';
p = wcschr( p + 1, L'\\' );
}
CreateDirectory( HiveDirectory, NULL );
return 0;
}
DWORD
DeleteHiveFile (
PWSTR HiveDirectoryAndFile
)
{
SetFileAttributes( HiveDirectoryAndFile, FILE_ATTRIBUTE_NORMAL );
DeleteFile( HiveDirectoryAndFile );
return 0;
}
DWORD
DoSpecificRegBackup(
PWSTR HiveDirectory,
PWSTR HiveDirectoryAndFile,
HKEY HiveRoot,
PWSTR HiveName
)
/*++
Routine Description:
This routine copies all the registries to the given server path.
Arguments:
HiveDirectory - name of directory for hive file
HiveDirectoryAndFile - file name to pass directly to OS
HiveRoot - HKEY_LOCAL_MACHINE or HKEY_USERS
HiveName - 1st level subkey under machine or users
Return Value:
NO_ERROR if everything was backed up properly, else the appropriate error code.
--*/
{
HKEY HiveKey;
ULONG Disposition;
LONG Error;
char *Reason;
//
// get a handle to the hive. use special create call what will
// use privileges
//
Reason = "accessing";
Error = RTCreateKey(&RegistryContext,
HiveRoot,
HiveName,
KEY_READ,
REG_OPTION_BACKUP_RESTORE,
NULL,
&HiveKey,
&Disposition
);
if (Error == NO_ERROR) {
Reason = "saving";
CreateHiveDirectory(HiveDirectory);
DeleteHiveFile(HiveDirectoryAndFile);
Error = RegSaveKey(HiveKey, HiveDirectoryAndFile, NULL);
RTCloseKey(&RegistryContext, HiveKey);
}
return Error;
}