379 lines
9.1 KiB
C
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;
|
|
}
|
|
|
|
|
|
|
|
|
|
|