windows-nt/Source/XPSP1/NT/base/ntsetup/win95upg/common/memdb/regops.c
2020-09-26 16:20:57 +08:00

379 lines
9.1 KiB
C

/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
regops.c
Abstract:
Routines that manage the merging of registry keys. Given a key
and a value, these functions allow the user to perform the same
types of actions as those specified in usermig.inf and wkstamig.inf
(i.e.: Copying, Suppressing, and Forcing various registry keys to be
merged into the NT registry.)
Routines:
Author:
Marc R. Whitten (marcw) 01-Aug-1997
Revision History:
Jim Schmidt (jimschm) 25-Mar-1998 Updated to properly support
tree notation, fixed value suppression
bug.
--*/
#include "pch.h"
#include "memdbp.h"
#include "merge.h"
#define DBG_REGOPS "RegOps"
/*++
Routine Description:
IsRegObjectMarkedForOperation builds an encoded key, escaping multi-byte
characters and syntax characters, and then performs a MemDb lookup to see
if the object is marked with the bit specified by OperationMask. A set of
macros are built on top of this routine in regops.h.
Arguments:
Key - Specifies the unencoded registry key, with abriviated roots
(i.e., HKLM\Software\Foo)
Value - Specifies the registry key value name
TreeState - Specifies KEY_ONLY to query against the key and optional
value, KEY_TREE to query against the key with a star at the
end, or TREE_OPTIONAL to query both.
OperationMask - Specifies an operation mask. See merge.h.
Return Value:
TRUE if the key is in MemDb, or FALSE if it is not.
--*/
BOOL
IsRegObjectMarkedForOperationA (
IN PCSTR Key,
IN PCSTR Value, OPTIONAL
IN TREE_STATE TreeState,
IN DWORD OperationMask
)
{
PCSTR regObject;
BOOL rIsMarked = FALSE;
DWORD value;
MYASSERT (TreeState != KEY_TREE || !Value);
if (TreeState == KEY_ONLY || TreeState == TREE_OPTIONAL) {
regObject = CreateEncodedRegistryStringExA(Key,Value,FALSE);
if (MemDbGetStoredEndPatternValueA(regObject,&value)) {
rIsMarked = (value & OperationMask) == OperationMask;
}
FreeEncodedRegistryStringA(regObject);
}
if (!rIsMarked && TreeState == KEY_TREE || TreeState == TREE_OPTIONAL && !Value) {
regObject = CreateEncodedRegistryStringExA(Key,Value,TRUE);
if (MemDbGetStoredEndPatternValueA(regObject,&value)) {
rIsMarked = (value & OperationMask) == OperationMask;
}
FreeEncodedRegistryStringA(regObject);
}
return rIsMarked;
}
BOOL
IsRegObjectMarkedForOperationW (
IN PCWSTR Key,
IN PCWSTR Value, OPTIONAL
IN TREE_STATE TreeState,
IN DWORD OperationMask
)
{
PCWSTR regObject;
BOOL rIsMarked = FALSE;
DWORD value;
MYASSERT (TreeState != KEY_TREE || !Value);
if (TreeState == KEY_ONLY || TreeState == TREE_OPTIONAL) {
regObject = CreateEncodedRegistryStringExW(Key,Value,FALSE);
if (MemDbGetStoredEndPatternValueW(regObject,&value)) {
rIsMarked = (value & OperationMask) == OperationMask;
}
FreeEncodedRegistryStringW(regObject);
}
if (!rIsMarked && TreeState == KEY_TREE || TreeState == TREE_OPTIONAL && !Value) {
regObject = CreateEncodedRegistryStringExW(Key,Value,TRUE);
if (MemDbGetStoredEndPatternValueW(regObject,&value)) {
rIsMarked = (value & OperationMask) == OperationMask;
}
FreeEncodedRegistryStringW(regObject);
}
return rIsMarked;
}
/*++
Routine Description:
MarkRegObjectForOperation creates an encoded string and sets the operation
bit in memdb. This routine is used to suppress operations from occurring
on a registry key, registry value, or registry key tree.
Arguments:
Key - Specifies an unencoded registry key, with abriviated root
(i.e., HKLM\Software\Foo).
Value - Specifies the registry key value name.
Tree - Specifies TRUE if Key specifies an entire registry key tree
(in which case Value must be NULL), or FALSE if Key
specifies a key that has different behavior for its subkeys.
OperationMask - Specifies the suppression operation. See merge.h.
Return Value:
TRUE if the set was successful.
--*/
BOOL
MarkRegObjectForOperationA (
IN PCSTR Key,
IN PCSTR Value, OPTIONAL
IN BOOL Tree,
IN DWORD OperationMask
)
{
PCSTR regObject;
BOOL rSuccess = TRUE;
if (Tree && Value) {
Tree = FALSE;
}
regObject = CreateEncodedRegistryStringExA(Key,Value,Tree);
rSuccess = MarkObjectForOperationA (regObject, OperationMask);
FreeEncodedRegistryStringA(regObject);
return rSuccess;
}
BOOL
MarkRegObjectForOperationW (
IN PCWSTR Key,
IN PCWSTR Value, OPTIONAL
IN BOOL Tree,
IN DWORD OperationMask
)
{
PCWSTR regObject;
BOOL rSuccess = TRUE;
if (Tree && Value) {
Tree = FALSE;
}
regObject = CreateEncodedRegistryStringExW(Key,Value,Tree);
rSuccess = MarkObjectForOperationW (regObject, OperationMask);
FreeEncodedRegistryStringW(regObject);
return rSuccess;
}
/*++
Routine Description:
MarkObjectForOperation sets operation bits on a specified registry object,
unless operation bits have already been specified.
Arguments:
Object - Specifies the encoded registry object. See memdbdef.h for
syntax (the HKLM or HKR categories).
OperationMask - Specifies the suppression operation for the particular
object.
Return Value:
TRUE if the set operation was successful, or FALSE if an operation was
already specified.
--*/
BOOL
MarkObjectForOperationA (
IN PCSTR Object,
IN DWORD OperationMask
)
{
DWORD Value;
if (MemDbGetValueA (Object, &Value)) {
DEBUGMSG_IF ((
Value == OperationMask,
DBG_REGOPS,
"%hs is already in memdb.",
Object
));
DEBUGMSG_IF ((
Value != OperationMask,
DBG_REGOPS,
"%hs is already in memdb with different flags %u. New flags ignored: %u.",
Object,
Value,
OperationMask
));
return FALSE;
}
return MemDbSetValueA (Object, OperationMask);
}
BOOL
MarkObjectForOperationW (
IN PCWSTR Object,
IN DWORD OperationMask
)
{
DWORD Value;
if (MemDbGetValueW (Object, &Value)) {
DEBUGMSG_IF ((
Value == OperationMask,
DBG_REGOPS,
"%ls is already in memdb.",
Object
));
DEBUGMSG_IF ((
Value != OperationMask,
DBG_REGOPS,
"%ls is already in memdb with different flags %u. New flags ignored: %u.",
Object,
Value,
OperationMask
));
return FALSE;
}
return MemDbSetValueW (Object, OperationMask);
}
BOOL
ForceWin9xSettingA (
IN PCSTR SourceKey,
IN PCSTR SourceValue,
IN BOOL SourceTree,
IN PCSTR DestinationKey,
IN PCSTR DestinationValue,
IN BOOL DestinationTree
)
{
PCSTR regSource;
CHAR keySource[MEMDB_MAX];
PCSTR regDestination;
CHAR keyDestination[MEMDB_MAX];
DWORD offset = 0;
BOOL rSuccess = TRUE;
regSource = CreateEncodedRegistryStringExA (SourceKey, SourceValue, SourceTree);
MemDbBuildKeyA (keySource, MEMDB_CATEGORY_FORCECOPYA, regSource, NULL, NULL);
regDestination = CreateEncodedRegistryStringExA (DestinationKey, DestinationValue, DestinationTree);
MemDbBuildKeyA (keyDestination, MEMDB_CATEGORY_FORCECOPYA, regDestination, NULL, NULL);
rSuccess = MemDbSetValueExA (keyDestination, NULL, NULL, NULL, 0, &offset);
if (rSuccess) {
rSuccess = MemDbSetValueA (keySource, offset);
}
FreeEncodedRegistryStringA (regDestination);
FreeEncodedRegistryStringA (regSource);
return rSuccess;
}
BOOL
ForceWin9xSettingW (
IN PCWSTR SourceKey,
IN PCWSTR SourceValue,
IN BOOL SourceTree,
IN PCWSTR DestinationKey,
IN PCWSTR DestinationValue,
IN BOOL DestinationTree
)
{
PCWSTR regSource;
WCHAR keySource[MEMDB_MAX];
PCWSTR regDestination;
WCHAR keyDestination[MEMDB_MAX];
DWORD offset = 0;
BOOL rSuccess = TRUE;
regSource = CreateEncodedRegistryStringExW (SourceKey, SourceValue, SourceTree);
MemDbBuildKeyW (keySource, MEMDB_CATEGORY_FORCECOPYW, regSource, NULL, NULL);
regDestination = CreateEncodedRegistryStringExW (DestinationKey, DestinationValue, DestinationTree);
MemDbBuildKeyW (keyDestination, MEMDB_CATEGORY_FORCECOPYW, regDestination, NULL, NULL);
rSuccess = MemDbSetValueExW (keyDestination, NULL, NULL, NULL, 0, &offset);
if (rSuccess) {
rSuccess = MemDbSetValueW (keySource, offset);
}
FreeEncodedRegistryStringW (regDestination);
FreeEncodedRegistryStringW (regSource);
return rSuccess;
}