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.
 
 
 
 
 
 

885 lines
21 KiB

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
Regsrkey.c
Abstract:
This module contains the client side wrappers for the Win32 Registry
save/restore key APIs, that is:
- RegRestoreKeyA
- RegRestoreKeyW
- RegSaveKeyA
- RegSaveKeyW
Author:
David J. Gilman (davegi) 23-Jan-1992
Notes:
The RegSaveKey and RegRestoreKey APIs involve up to 3 machines:
1.- CLIENT: The machine where the API is invoked.
2.- SERVER: The machine where the Registry resides.
3.- TARGET: The machine of the specified file.
Note that both the client and the server will be running Windows NT,
but that the target machine might not.
Even though the target might be accessible from the client, it might
not be accessible from the server (e.g. the share is protected).
Revision History:
25-Mar-1992 Ramon J. San Andres (ramonsa)
Changed to use RPC.
--*/
#include <rpc.h>
#include "regrpc.h"
#include "client.h"
LONG
APIENTRY
RegRestoreKeyA (
HKEY hKey,
LPCSTR lpFile,
DWORD dwFlags
)
/*++
Routine Description:
Win32 Ansi API for restoring a key.
--*/
{
PUNICODE_STRING FileName;
ANSI_STRING AnsiString;
NTSTATUS Status;
LONG Error;
HKEY TempHandle = NULL;
#if DBG
if ( BreakPointOnEntry ) {
DbgBreakPoint();
}
#endif
ASSERT( lpFile != NULL );
//
// Limit the capabilities associated with HKEY_PERFORMANCE_DATA.
//
if( hKey == HKEY_PERFORMANCE_DATA ) {
return ERROR_INVALID_HANDLE;
}
hKey = MapPredefinedHandle( hKey, &TempHandle );
if( hKey == NULL ) {
Error = ERROR_INVALID_HANDLE;
goto ExitCleanup;
}
//
// Convert the file name to a counted Unicode string using the static
// Unicode string in the TEB.
//
FileName = &NtCurrentTeb( )->StaticUnicodeString;
ASSERT( FileName != NULL );
RtlInitAnsiString( &AnsiString, lpFile );
Status = RtlAnsiStringToUnicodeString(
FileName,
&AnsiString,
FALSE
);
//
// If the file name could not be converted, map the results and return.
//
if( ! NT_SUCCESS( Status )) {
Error = RtlNtStatusToDosError( Status );
goto ExitCleanup;
}
//
// Add the NULL to the length so that RPC will transmit the entire
// thing
//
if ( FileName->Length > 0 ) {
FileName->Length += sizeof( UNICODE_NULL );
}
if( IsLocalHandle( hKey )) {
Error = (LONG)LocalBaseRegRestoreKey(
hKey,
FileName,
dwFlags
);
} else {
Error = (LONG)BaseRegRestoreKey(
DereferenceRemoteHandle( hKey ),
FileName,
dwFlags
);
}
ExitCleanup:
CLOSE_LOCAL_HANDLE(TempHandle);
return Error;
}
LONG
APIENTRY
RegRestoreKeyW (
HKEY hKey,
LPCWSTR lpFile,
DWORD dwFlags
)
/*++
Routine Description:
Restore the tree in the supplied file onto the key referenced by the
supplied key handle. The restored tree will overwrite all of the
contents of the supplied hKey except for its name. Pictorially, if
the file contains:
A
/ \
/ \
B C
and the supplied key refers to a key name X, the resultant tree would
look like:
X
/ \
/ \
B C
Arguments:
hKey - Supplies a handle to the key where the file is to be restored.
lpFile - Supplies a pointer to an existing file name whose contents was
created with RegSaveKey.
dwFlags - Supplies an optional flag argument which can be:
- REG_WHOLE_HIVE_VOLATILE
If specified this flag causes a new, volatile
(i.e. memory only) hive to be created. In this case
the hKey can only refer to a child of HKEY_USERS or
HKEY_LOCAL_MACHINE.
If not specified, hKey can refer to any key in the
Registry.
Return Value:
Returns ERROR_SUCCESS (0) for success; error-code for failure.
--*/
{
UNICODE_STRING FileName;
LONG Error;
HKEY TempHandle = NULL;
NTSTATUS Status;
#if DBG
if ( BreakPointOnEntry ) {
DbgBreakPoint();
}
#endif
ASSERT( lpFile != NULL );
//
// Limit the capabilities associated with HKEY_PERFORMANCE_DATA.
//
if( hKey == HKEY_PERFORMANCE_DATA ) {
return ERROR_INVALID_HANDLE;
}
hKey = MapPredefinedHandle( hKey, &TempHandle );
if( hKey == NULL ) {
Error = ERROR_INVALID_HANDLE;
goto ExitCleanup;
}
Status = RtlInitUnicodeStringEx(&FileName, lpFile);
if( !NT_SUCCESS(Status) ) {
Error = RtlNtStatusToDosError( Status );
goto ExitCleanup;
}
//
// Add the NULL to the length so that RPC will transmit the entire
// thing
//
if ( FileName.Length > 0 ) {
FileName.Length += sizeof( UNICODE_NULL );
}
if( IsLocalHandle( hKey )) {
Error = (LONG)LocalBaseRegRestoreKey(
hKey,
&FileName,
dwFlags
);
} else {
Error = (LONG)BaseRegRestoreKey(
DereferenceRemoteHandle( hKey ),
&FileName,
dwFlags
);
}
ExitCleanup:
CLOSE_LOCAL_HANDLE(TempHandle);
return Error;
}
LONG
APIENTRY
RegSaveKeyA (
HKEY hKey,
LPCSTR lpFile,
LPSECURITY_ATTRIBUTES lpSecurityAttributes
)
/*++
Routine Description:
Win32 ANSI wrapper to RegSaveKeyW.
Save the key (and all of its decsendants) to the non-existant file
named by the supplied string.
Arguments:
hKey - Supplies a handle to the key where the save operation is to
begin.
lpFile - Supplies a pointer to a non-existant file name where the tree
rooted at the supplied key handle will be saved.
lpSecurityAttributes - Supplies an optional pointer to a
SECURITY_ATTRIBUTES structure for the newly created file.
Return Value:
Returns ERROR_SUCCESS (0) for success; error-code for failure.
--*/
{
PUNICODE_STRING FileName;
ANSI_STRING AnsiString;
NTSTATUS Status;
PRPC_SECURITY_ATTRIBUTES pRpcSA;
RPC_SECURITY_ATTRIBUTES RpcSA;
LONG Error;
HKEY TempHandle = NULL;
#if DBG
if ( BreakPointOnEntry ) {
DbgBreakPoint();
}
#endif
ASSERT( lpFile != NULL );
//
// Limit the capabilities associated with HKEY_PERFORMANCE_DATA.
//
if( hKey == HKEY_PERFORMANCE_DATA ) {
return ERROR_INVALID_HANDLE;
}
//
// Note that we must map the handle here even though RegSaveKeyW
// will map it again. This is so that the second map will not
// overwrite the static Unicode string in the TEB that will
// contain the file name.
//
hKey = MapPredefinedHandle( hKey, &TempHandle );
if( hKey == NULL ) {
Error = ERROR_INVALID_HANDLE;
goto ExitCleanup;
}
//
// Convert the file name to a counted Unicode string using the static
// Unicode string in the TEB.
//
FileName = &NtCurrentTeb( )->StaticUnicodeString;
ASSERT( FileName != NULL );
RtlInitAnsiString( &AnsiString, lpFile );
Status = RtlAnsiStringToUnicodeString(
FileName,
&AnsiString,
FALSE
);
//
// If the file name could not be converted, map the results and return.
//
if( ! NT_SUCCESS( Status )) {
Error = RtlNtStatusToDosError( Status );
goto ExitCleanup;
}
//
// Add the NULL to the length so that RPC will transmit the entire
// thing
//
if ( FileName->Length > 0 ) {
FileName->Length += sizeof( UNICODE_NULL );
}
//
// If the caller supplied a LPSECURITY_ATTRIBUTES argument, map
// it to the RPCable version.
//
if( ARGUMENT_PRESENT( lpSecurityAttributes )) {
pRpcSA = &RpcSA;
Error = MapSAToRpcSA( lpSecurityAttributes, pRpcSA );
if( Error != ERROR_SUCCESS ) {
goto ExitCleanup;
}
} else {
//
// No PSECURITY_ATTRIBUTES argument, therefore no mapping was done.
//
pRpcSA = NULL;
}
if( IsLocalHandle( hKey )) {
Error = (LONG)LocalBaseRegSaveKey(
hKey,
FileName,
pRpcSA
);
} else {
Error = (LONG)BaseRegSaveKey(
DereferenceRemoteHandle( hKey ),
FileName,
pRpcSA
);
}
//
// Free the RPC_SECURITY_DESCRIPTOR buffer and return the
//
if( pRpcSA != NULL ) {
RtlFreeHeap(
RtlProcessHeap( ), 0,
pRpcSA->RpcSecurityDescriptor.lpSecurityDescriptor
);
}
ExitCleanup:
CLOSE_LOCAL_HANDLE(TempHandle);
return Error;
}
LONG
APIENTRY
RegSaveKeyW (
HKEY hKey,
LPCWSTR lpFile,
LPSECURITY_ATTRIBUTES lpSecurityAttributes
)
/*++
Routine Description:
Save the key (and all of its decsendants) to the non-existant file
named by the supplied string.
Arguments:
hKey - Supplies a handle to the key where the save operation is to
begin.
lpFile - Supplies a pointer to a non-existant file name where the tree
rooted at the supplied key handle will be saved.
lpSecurityAttributes - Supplies an optional pointer to a
SECURITY_ATTRIBUTES structure for the newly created file.
Return Value:
Returns ERROR_SUCCESS (0) for success; error-code for failure.
--*/
{
UNICODE_STRING FileName;
PRPC_SECURITY_ATTRIBUTES pRpcSA;
RPC_SECURITY_ATTRIBUTES RpcSA;
LONG Error;
HKEY TempHandle = NULL;
NTSTATUS Status;
#if DBG
if ( BreakPointOnEntry ) {
DbgBreakPoint();
}
#endif
ASSERT( lpFile != NULL );
//
// Limit the capabilities associated with HKEY_PERFORMANCE_DATA.
//
if( hKey == HKEY_PERFORMANCE_DATA ) {
return ERROR_INVALID_HANDLE;
}
//
// Note that we must map the handle here even though RegSaveKeyW
// will map it again. This is so that the second map will not
// overwrite the static Unicode string in the TEB that will
// contain the file name.
//
hKey = MapPredefinedHandle( hKey, &TempHandle );
if( hKey == NULL ) {
Error = ERROR_INVALID_HANDLE;
goto ExitCleanup;
}
Status = RtlInitUnicodeStringEx(&FileName, lpFile);
if( !NT_SUCCESS(Status) ) {
Error = RtlNtStatusToDosError( Status );
goto ExitCleanup;
}
//
// Add the NULL to the length so that RPC will transmit the entire
// thing
//
if ( FileName.Length > 0 ) {
FileName.Length += sizeof( UNICODE_NULL );
}
//
// If the caller supplied a LPSECURITY_ATTRIBUTES argument, map
// it to the RPCable version.
//
if( ARGUMENT_PRESENT( lpSecurityAttributes )) {
pRpcSA = &RpcSA;
Error = MapSAToRpcSA( lpSecurityAttributes, pRpcSA );
if( Error != ERROR_SUCCESS ) {
goto ExitCleanup;
}
} else {
//
// No PSECURITY_ATTRIBUTES argument, therefore no mapping was done.
//
pRpcSA = NULL;
}
if( IsLocalHandle( hKey )) {
Error = (LONG)LocalBaseRegSaveKey(
hKey,
&FileName,
pRpcSA
);
} else {
Error = (LONG)BaseRegSaveKey(
DereferenceRemoteHandle( hKey ),
&FileName,
pRpcSA
);
}
//
// Free the RPC_SECURITY_DESCRIPTOR buffer and return the
//
if( pRpcSA != NULL ) {
RtlFreeHeap(
RtlProcessHeap( ), 0,
pRpcSA->RpcSecurityDescriptor.lpSecurityDescriptor
);
}
ExitCleanup:
CLOSE_LOCAL_HANDLE(TempHandle);
return Error;
}
LONG
APIENTRY
RegSaveKeyExA (
HKEY hKey,
LPCSTR lpFile,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD Flags
)
/*++
Routine Description:
Win32 ANSI wrapper to RegSaveKeyExW.
Save the key (and all of its decsendants) to the non-existant file
named by the supplied string.
Arguments:
hKey - Supplies a handle to the key where the save operation is to
begin.
lpFile - Supplies a pointer to a non-existant file name where the tree
rooted at the supplied key handle will be saved.
lpSecurityAttributes - Supplies an optional pointer to a
SECURITY_ATTRIBUTES structure for the newly created file.
Return Value:
Returns ERROR_SUCCESS (0) for success; error-code for failure.
--*/
{
PUNICODE_STRING FileName;
ANSI_STRING AnsiString;
NTSTATUS Status;
PRPC_SECURITY_ATTRIBUTES pRpcSA;
RPC_SECURITY_ATTRIBUTES RpcSA;
LONG Error;
HKEY TempHandle = NULL;
#if DBG
if ( BreakPointOnEntry ) {
DbgBreakPoint();
}
#endif
ASSERT( lpFile != NULL );
//
// Limit the capabilities associated with HKEY_PERFORMANCE_DATA.
//
if( hKey == HKEY_PERFORMANCE_DATA ) {
return ERROR_INVALID_HANDLE;
}
//
// Note that we must map the handle here even though RegSaveKeyW
// will map it again. This is so that the second map will not
// overwrite the static Unicode string in the TEB that will
// contain the file name.
//
hKey = MapPredefinedHandle( hKey, &TempHandle );
if( hKey == NULL ) {
Error = ERROR_INVALID_HANDLE;
goto ExitCleanup;
}
//
// Convert the file name to a counted Unicode string using the static
// Unicode string in the TEB.
//
FileName = &NtCurrentTeb( )->StaticUnicodeString;
ASSERT( FileName != NULL );
RtlInitAnsiString( &AnsiString, lpFile );
Status = RtlAnsiStringToUnicodeString(
FileName,
&AnsiString,
FALSE
);
//
// If the file name could not be converted, map the results and return.
//
if( ! NT_SUCCESS( Status )) {
Error = RtlNtStatusToDosError( Status );
goto ExitCleanup;
}
//
// Add the NULL to the length so that RPC will transmit the entire
// thing
//
if ( FileName->Length > 0 ) {
FileName->Length += sizeof( UNICODE_NULL );
}
//
// If the caller supplied a LPSECURITY_ATTRIBUTES argument, map
// it to the RPCable version.
//
if( ARGUMENT_PRESENT( lpSecurityAttributes )) {
pRpcSA = &RpcSA;
Error = MapSAToRpcSA( lpSecurityAttributes, pRpcSA );
if( Error != ERROR_SUCCESS ) {
goto ExitCleanup;
}
} else {
//
// No PSECURITY_ATTRIBUTES argument, therefore no mapping was done.
//
pRpcSA = NULL;
}
if( IsLocalHandle( hKey )) {
Error = (LONG)LocalBaseRegSaveKeyEx(
hKey,
FileName,
pRpcSA,
Flags
);
} else {
Error = (LONG)BaseRegSaveKeyEx(
DereferenceRemoteHandle( hKey ),
FileName,
pRpcSA,
Flags
);
}
//
// Free the RPC_SECURITY_DESCRIPTOR buffer and return the
//
if( pRpcSA != NULL ) {
RtlFreeHeap(
RtlProcessHeap( ), 0,
pRpcSA->RpcSecurityDescriptor.lpSecurityDescriptor
);
}
ExitCleanup:
CLOSE_LOCAL_HANDLE(TempHandle);
return Error;
}
LONG
APIENTRY
RegSaveKeyExW (
HKEY hKey,
LPCWSTR lpFile,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD Flags
)
/*++
Routine Description:
Save the key (and all of its decsendants) to the non-existant file
named by the supplied string.
This variant is used by setup in order to create a hive in the latest
format. Helps creating hives in %systemroot%\system32\config in the
latest (presumably the best) format, and allows RegSaveKey to use the
standard format (bacward compatible) for roaming profiles and tools
using registry hives on downlevel OSes.
Arguments:
hKey - Supplies a handle to the key where the save operation is to
begin.
lpFile - Supplies a pointer to a non-existant file name where the tree
rooted at the supplied key handle will be saved.
lpSecurityAttributes - Supplies an optional pointer to a
SECURITY_ATTRIBUTES structure for the newly created file.
Flags - [REG_STANDARD_FORMAT] - roaming format
[REG_LATEST_FORMAT] - latest format
[REG_NO_COMPRESSION] - no hive compression : faster
Return Value:
Returns ERROR_SUCCESS (0) for success; error-code for failure.
--*/
{
UNICODE_STRING FileName;
PRPC_SECURITY_ATTRIBUTES pRpcSA;
RPC_SECURITY_ATTRIBUTES RpcSA;
LONG Error;
HKEY TempHandle = NULL;
NTSTATUS Status;
#if DBG
if ( BreakPointOnEntry ) {
DbgBreakPoint();
}
#endif
ASSERT( lpFile != NULL );
//
// Limit the capabilities associated with HKEY_PERFORMANCE_DATA.
//
if( hKey == HKEY_PERFORMANCE_DATA ) {
return ERROR_INVALID_HANDLE;
}
//
// Note that we must map the handle here even though RegSaveKeyW
// will map it again. This is so that the second map will not
// overwrite the static Unicode string in the TEB that will
// contain the file name.
//
hKey = MapPredefinedHandle( hKey, &TempHandle );
if( hKey == NULL ) {
Error = ERROR_INVALID_HANDLE;
goto ExitCleanup;
}
Status = RtlInitUnicodeStringEx(&FileName, lpFile);
if( !NT_SUCCESS(Status) ) {
Error = RtlNtStatusToDosError( Status );
goto ExitCleanup;
}
//
// Add the NULL to the length so that RPC will transmit the entire
// thing
//
if ( FileName.Length > 0 ) {
FileName.Length += sizeof( UNICODE_NULL );
}
//
// If the caller supplied a LPSECURITY_ATTRIBUTES argument, map
// it to the RPCable version.
//
if( ARGUMENT_PRESENT( lpSecurityAttributes )) {
pRpcSA = &RpcSA;
Error = MapSAToRpcSA( lpSecurityAttributes, pRpcSA );
if( Error != ERROR_SUCCESS ) {
goto ExitCleanup;
}
} else {
//
// No PSECURITY_ATTRIBUTES argument, therefore no mapping was done.
//
pRpcSA = NULL;
}
if( IsLocalHandle( hKey )) {
Error = (LONG)LocalBaseRegSaveKeyEx(
hKey,
&FileName,
pRpcSA,
Flags
);
} else {
Error = (LONG)BaseRegSaveKeyEx(
DereferenceRemoteHandle( hKey ),
&FileName,
pRpcSA,
Flags
);
}
//
// Free the RPC_SECURITY_DESCRIPTOR buffer and return the
//
if( pRpcSA != NULL ) {
RtlFreeHeap(
RtlProcessHeap( ), 0,
pRpcSA->RpcSecurityDescriptor.lpSecurityDescriptor
);
}
ExitCleanup:
CLOSE_LOCAL_HANDLE(TempHandle);
return Error;
}