windows-nt/Source/XPSP1/NT/windows/winstate/cobra/utils/reg/tree.c
2020-09-26 16:20:57 +08:00

453 lines
9 KiB
C

/*++
Copyright (c) 1999 Microsoft Corporation
Module Name:
tree.c
Abstract:
Implements routines that do operations on entire trees
Author:
Jim Schmidt (jimschm) 08-Mar-2000
Revision History:
<alias> <date> <comments>
--*/
#include "pch.h"
//
// Includes
//
// None
#define DBG_TREE "Tree"
//
// Strings
//
// None
//
// Constants
//
// None
//
// Macros
//
// None
//
// Types
//
// None
//
// Globals
//
// None
//
// Macro expansion list
//
// None
//
// Private function prototypes
//
// None
//
// Macro expansion definition
//
// None
//
// Code
//
BOOL
RgRemoveAllValuesInKeyA (
IN PCSTR KeyToRemove
)
{
REGTREE_ENUMA e;
PCSTR pattern;
BOOL result = TRUE;
HKEY deleteHandle;
REGSAM prevMode;
LONG rc;
pattern = ObsBuildEncodedObjectStringExA (KeyToRemove, "*", FALSE);
if (EnumFirstRegObjectInTreeExA (
&e,
pattern,
FALSE, // no key names
TRUE, // ignored in this case
TRUE, // values first
TRUE, // depth first
REGENUM_ALL_SUBLEVELS,
TRUE, // use exclusions
FALSE, // ReadValueData
NULL
)) {
do {
MYASSERT (!(e.Attributes & REG_ATTRIBUTE_KEY));
prevMode = SetRegOpenAccessMode (KEY_ALL_ACCESS);
deleteHandle = OpenRegKeyStrA (e.Location);
if (deleteHandle) {
rc = RegDeleteValueA (deleteHandle, e.Name);
CloseRegKey (deleteHandle);
SetRegOpenAccessMode (prevMode);
if (rc != ERROR_SUCCESS && rc != ERROR_FILE_NOT_FOUND) {
SetLastError (rc);
AbortRegObjectInTreeEnumA (&e);
ObsFreeA (pattern);
return FALSE;
}
} else {
SetRegOpenAccessMode (prevMode);
AbortRegObjectInTreeEnumA (&e);
ObsFreeA (pattern);
return FALSE;
}
} while (EnumNextRegObjectInTreeA (&e));
}
ObsFreeA (pattern);
return result;
}
BOOL
RgRemoveAllValuesInKeyW (
IN PCWSTR KeyToRemove
)
{
REGTREE_ENUMW e;
PCWSTR pattern;
BOOL result = TRUE;
HKEY deleteHandle;
REGSAM prevMode;
LONG rc;
pattern = ObsBuildEncodedObjectStringExW (KeyToRemove, L"*", FALSE);
if (EnumFirstRegObjectInTreeExW (
&e,
pattern,
FALSE, // no key names
TRUE, // ignored in this case
TRUE, // values first
TRUE, // depth first
REGENUM_ALL_SUBLEVELS,
TRUE, // use exclusions
FALSE, // ReadValueData
NULL
)) {
do {
MYASSERT (!(e.Attributes & REG_ATTRIBUTE_KEY));
prevMode = SetRegOpenAccessMode (KEY_ALL_ACCESS);
deleteHandle = OpenRegKeyStrW (e.Location);
if (deleteHandle) {
rc = RegDeleteValueW (deleteHandle, e.Name);
CloseRegKey (deleteHandle);
SetRegOpenAccessMode (prevMode);
if (rc != ERROR_SUCCESS && rc != ERROR_FILE_NOT_FOUND) {
SetLastError (rc);
AbortRegObjectInTreeEnumW (&e);
ObsFreeW (pattern);
return FALSE;
}
} else {
SetRegOpenAccessMode (prevMode);
AbortRegObjectInTreeEnumW (&e);
ObsFreeW (pattern);
return FALSE;
}
} while (EnumNextRegObjectInTreeW (&e));
}
ObsFreeW (pattern);
return result;
}
BOOL
pDeleteKeyStrA (
IN OUT PSTR *DeleteKey
)
{
PSTR p;
HKEY key;
LONG rc;
if (*DeleteKey == NULL) {
return TRUE;
}
p = (PSTR) FindLastWackA (*DeleteKey);
if (p) {
*p = 0;
p++;
key = OpenRegKeyStrA (*DeleteKey);
if (key) {
rc = RegDeleteKeyA (key, p);
CloseRegKey (key);
} else {
rc = GetLastError();
}
if (rc == ERROR_FILE_NOT_FOUND) {
rc = ERROR_SUCCESS;
}
} else {
rc = ERROR_SUCCESS;
}
FreeTextA (*DeleteKey);
*DeleteKey = NULL;
SetLastError (rc);
return rc == ERROR_SUCCESS;
}
BOOL
pDeleteKeyStrW (
IN OUT PWSTR *DeleteKey
)
{
PWSTR p;
HKEY key;
LONG rc;
if (*DeleteKey == NULL) {
return TRUE;
}
p = (PWSTR) FindLastWackW (*DeleteKey);
if (p) {
*p = 0;
p++;
key = OpenRegKeyStrW (*DeleteKey);
if (key) {
rc = RegDeleteKeyW (key, p);
CloseRegKey (key);
} else {
rc = GetLastError();
}
if (rc == ERROR_FILE_NOT_FOUND) {
rc = ERROR_SUCCESS;
}
} else {
rc = ERROR_SUCCESS;
}
FreeTextW (*DeleteKey);
*DeleteKey = NULL;
SetLastError (rc);
return rc == ERROR_SUCCESS;
}
BOOL
RgRemoveKeyA (
IN PCSTR KeyToRemove
)
{
REGTREE_ENUMA e;
PCSTR pattern;
BOOL result = TRUE;
PSTR deleteKey = NULL;
PSTR encodedKey;
encodedKey = AllocTextA (ByteCountA (KeyToRemove) * 2 + 2 * sizeof (CHAR));
ObsEncodeStringA (encodedKey, KeyToRemove);
StringCatA (encodedKey, "\\*");
pattern = ObsBuildEncodedObjectStringExA (encodedKey, NULL, FALSE);
FreeTextA (encodedKey);
if (EnumFirstRegObjectInTreeExA (
&e,
pattern,
TRUE, // key names
FALSE, // containers last
TRUE, // values first
TRUE, // depth first
REGENUM_ALL_SUBLEVELS,
TRUE, // use exclusions
FALSE, // ReadValueData
NULL
)) {
do {
if (!pDeleteKeyStrA (&deleteKey)) {
result = FALSE;
break;
}
MYASSERT (e.Attributes & REG_ATTRIBUTE_KEY);
if (!RgRemoveAllValuesInKeyA (e.NativeFullName)) {
result = FALSE;
break;
}
//
// The reg enum wrappers hold on to a key handle, which prevents
// us from deleting the key now. We need to hold on to the key
// name, then continue on to the next item. At that time, we can
// delete the key.
//
deleteKey = DuplicateTextA (e.NativeFullName);
} while (EnumNextRegObjectInTreeA (&e));
}
ObsFreeA (pattern);
if (result) {
result = pDeleteKeyStrA (&deleteKey);
result = result && RgRemoveAllValuesInKeyA (KeyToRemove);
if (result) {
deleteKey = DuplicateTextA (KeyToRemove);
result = pDeleteKeyStrA (&deleteKey);
}
} else {
AbortRegObjectInTreeEnumA (&e);
if (deleteKey) {
FreeTextA (deleteKey);
INVALID_POINTER (deleteKey);
}
}
return result;
}
BOOL
RgRemoveKeyW (
IN PCWSTR KeyToRemove
)
{
REGTREE_ENUMW e;
PCWSTR pattern;
BOOL result = TRUE;
PWSTR deleteKey = NULL;
PWSTR encodedKey;
encodedKey = AllocTextW (ByteCountW (KeyToRemove) * 2 + 2 * sizeof (WCHAR));
ObsEncodeStringW (encodedKey, KeyToRemove);
StringCatW (encodedKey, L"\\*");
pattern = ObsBuildEncodedObjectStringExW (encodedKey, NULL, FALSE);
FreeTextW (encodedKey);
if (EnumFirstRegObjectInTreeExW (
&e,
pattern,
TRUE, // key names
FALSE, // containers last
TRUE, // values first
TRUE, // depth first
REGENUM_ALL_SUBLEVELS,
TRUE, // use exclusions
FALSE, // ReadValueData
NULL
)) {
do {
if (!pDeleteKeyStrW (&deleteKey)) {
result = FALSE;
break;
}
MYASSERT (e.Attributes & REG_ATTRIBUTE_KEY);
if (!RgRemoveAllValuesInKeyW (e.NativeFullName)) {
result = FALSE;
break;
}
//
// The reg enum wrappers hold on to a key handle, which prevents
// us from deleting the key now. We need to hold on to the key
// name, then continue on to the next item. At that time, we can
// delete the key.
//
deleteKey = DuplicateTextW (e.NativeFullName);
} while (EnumNextRegObjectInTreeW (&e));
}
ObsFreeW (pattern);
if (result) {
result = pDeleteKeyStrW (&deleteKey);
result = result && RgRemoveAllValuesInKeyW (KeyToRemove);
if (result) {
deleteKey = DuplicateTextW (KeyToRemove);
result = pDeleteKeyStrW (&deleteKey);
}
} else {
AbortRegObjectInTreeEnumW (&e);
if (deleteKey) {
FreeTextW (deleteKey);
INVALID_POINTER (deleteKey);
}
}
return result;
}