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

696 lines
15 KiB
C

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
memdbex.c
Abstract:
Extensions to use the memdb tree like a relational database
Author:
Jim Schmidt (jimschm) 2-Dec-1996
Revision History:
jimschm 23-Sep-1998 Expanded user flags to 24 bits (from
12 bits), removed AnsiFromUnicode
jimschm 21-Oct-1997 Cleaned up a little
marcw 09-Apr-1997 Added MemDbGetOffset* functions.
jimschm 17-Jan-1997 All string params can be NULL now
jimschm 18-Dec-1996 Added GetEndpointValue functions
--*/
#include "pch.h"
#include "memdbp.h"
VOID
MemDbBuildKeyA (
OUT PSTR Buffer,
IN PCSTR Category,
IN PCSTR Item,
IN PCSTR Field,
IN PCSTR Data
)
{
PSTR p;
static CHAR Wack[] = "\\";
p = Buffer;
*p = 0;
if (Category)
p = _mbsappend (p, Category);
if (Item) {
if (p != Buffer)
p = _mbsappend (p, Wack);
p = _mbsappend (p, Item);
}
if (Field) {
if (p != Buffer)
p = _mbsappend (p, Wack);
p = _mbsappend (p, Field);
}
if (Data) {
if (p != Buffer)
p = _mbsappend (p, Wack);
p = _mbsappend (p, Data);
}
}
VOID
MemDbBuildKeyW (
OUT PWSTR Buffer,
IN PCWSTR Category,
IN PCWSTR Item,
IN PCWSTR Field,
IN PCWSTR Data
)
{
PWSTR p;
static WCHAR Wack[] = L"\\";
p = Buffer;
*p = 0;
if (Category)
p = _wcsappend (p, Category);
if (Item) {
if (p != Buffer)
p = _wcsappend (p, Wack);
p = _wcsappend (p, Item);
}
if (Field) {
if (p != Buffer)
p = _wcsappend (p, Wack);
p = _wcsappend (p, Field);
}
if (Data) {
if (p != Buffer)
p = _wcsappend (p, Wack);
p = _wcsappend (p, Data);
}
}
BOOL
MemDbSetValueExA (
IN PCSTR Category,
IN PCSTR Item, OPTIONAL
IN PCSTR Field, OPTIONAL
IN PCSTR Data, OPTIONAL
IN DWORD Val,
OUT PDWORD Offset OPTIONAL
)
{
CHAR Key[MEMDB_MAX];
MemDbBuildKeyA (Key, Category, Item, Field, Data);
return PrivateMemDbSetValueA (Key, Val, 0, 0, Offset);
}
BOOL
MemDbSetValueExW (
IN PCWSTR Category,
IN PCWSTR Item, OPTIONAL
IN PCWSTR Field, OPTIONAL
IN PCWSTR Data, OPTIONAL
IN DWORD Val,
OUT PDWORD Offset OPTIONAL
)
{
WCHAR Key[MEMDB_MAX];
MemDbBuildKeyW (Key, Category, Item, Field, Data);
return PrivateMemDbSetValueW (Key, Val, 0, 0, Offset);
}
BOOL
MemDbSetBinaryValueExA (
IN PCSTR Category,
IN PCSTR Item, OPTIONAL
IN PCSTR Field, OPTIONAL
IN PCBYTE BinaryData,
IN DWORD DataSize,
OUT PDWORD Offset OPTIONAL
)
{
CHAR Key[MEMDB_MAX];
MemDbBuildKeyA (Key, Category, Item, Field, NULL);
return PrivateMemDbSetBinaryValueA (Key, BinaryData, DataSize, Offset);
}
BOOL
MemDbSetBinaryValueExW (
IN PCWSTR Category,
IN PCWSTR Item, OPTIONAL
IN PCWSTR Field, OPTIONAL
IN PCBYTE BinaryData,
IN DWORD DataSize,
OUT PDWORD Offset OPTIONAL
)
{
WCHAR Key[MEMDB_MAX];
MemDbBuildKeyW (Key, Category, Item, Field, NULL);
return PrivateMemDbSetBinaryValueW (Key, BinaryData, DataSize, Offset);
}
/*++
Routine Description:
MemDbBuildKeyFromOffset and MemDbBuildKeyFromOffsetEx create a key
string given the offset to the key, copying the string into the
supplied buffer. If a value pointer or user flag pointer is
provided, it is filled with the value or flag stored at the offset.
These functions also allow trimming from the beginning of the string.
By specifying a start level, the function will skip a number of
levels before building the string. For example, if an offset points
to the string mycat\foo\bar, and StartLevel is 1, the function will
return foo\bar in Buffer.
Arguments:
Offset - Specifies the offset to the key as returned by MemDbSetValueEx.
Buffer - Specifies a MEMDB_MAX buffer.
StartLevel - Specifies a zero-based starting level, where zero represents
the complete string, one represents the string starting after
the first backslash, and so on.
ValPtr - Specifies a variable that receives the value stored for the key
Return Value:
TRUE if the offset is valid and the function completed successfully, or
FALSE if the offset is not valid or an internal memory corruption was detected.
--*/
BOOL
MemDbBuildKeyFromOffsetA (
IN DWORD Offset,
OUT PSTR Buffer, OPTIONAL
IN DWORD StartLevel,
OUT PDWORD ValPtr OPTIONAL
)
{
WCHAR WideBuffer[MEMDB_MAX];
BOOL b;
b = MemDbBuildKeyFromOffsetW (
Offset,
WideBuffer,
StartLevel,
ValPtr
);
if (b) {
KnownSizeWtoA (Buffer, WideBuffer);
}
return b;
}
BOOL
MemDbBuildKeyFromOffsetW (
IN DWORD Offset,
OUT PWSTR Buffer, OPTIONAL
IN DWORD StartLevel,
OUT PDWORD ValPtr OPTIONAL
)
{
return MemDbBuildKeyFromOffsetExW (
Offset,
Buffer,
NULL,
StartLevel,
ValPtr,
NULL
);
}
/*++
Routine Description:
MemDbBuildKeyFromOffset and MemDbBuildKeyFromOffsetEx create a key
string given the offset to the key, copying the string into the
supplied buffer. If a value pointer or user flag pointer is
provided, it is filled with the value or flag stored at the offset.
These functions also allow trimming from the beginning of the string.
By specifying a start level, the function will skip a number of
levels before building the string. For example, if an offset points
to the string mycat\foo\bar, and StartLevel is 1, the function will
return foo\bar in Buffer.
Arguments:
Offset - Specifies the offset to the key as returned by MemDbSetValueEx.
Buffer - Specifies a MEMDB_MAX buffer.
BufferLen - Receives the length of the string in characters, excluding the
terminating nul. If caller is using this for buffer allocation
size, double BufferLen.
StartLevel - Specifies a zero-based starting level, where zero represents
the complete string, one represents the string starting after
the first backslash, and so on.
ValPtr - Specifies a variable that receives the value stored for the key
UserFlagPtr - Specifies a variable that receives the user flags stored for the
key
Return Value:
TRUE if the offset is valid and the function completed successfully, or
FALSE if the offset is not valid or an internal memory corruption was detected.
--*/
BOOL
MemDbBuildKeyFromOffsetExA (
IN DWORD Offset,
OUT PSTR Buffer, OPTIONAL
OUT PDWORD BufferLen, OPTIONAL
IN DWORD StartLevel,
OUT PDWORD ValPtr, OPTIONAL
OUT PDWORD UserFlagPtr OPTIONAL
)
{
WCHAR WideBuffer[MEMDB_MAX];
BOOL b;
b = MemDbBuildKeyFromOffsetExW (
Offset,
WideBuffer,
BufferLen,
StartLevel,
ValPtr,
UserFlagPtr
);
if (b) {
KnownSizeWtoA (Buffer, WideBuffer);
}
return b;
}
BOOL
MemDbBuildKeyFromOffsetExW (
IN DWORD Offset,
OUT PWSTR Buffer, OPTIONAL
OUT PDWORD BufferLen, OPTIONAL
IN DWORD StartLevel,
OUT PDWORD ValPtr, OPTIONAL
OUT PDWORD UserFlagPtr OPTIONAL
)
{
PWSTR p,s;
BYTE newDb = (BYTE) (Offset >> RESERVED_BITS);
if (Offset == INVALID_OFFSET) {
return FALSE;
}
SelectDatabase (newDb);
p = Buffer;
if (newDb != 0) {
if (StartLevel == 0) {
if (Buffer) {
s = g_db->Hive;
while (*s) {
*p++ = *s++;
}
*p++ = L'\\';
}
}
else {
StartLevel --;
}
}
return PrivateBuildKeyFromOffset (
StartLevel,
Offset & OFFSET_MASK,
p,
ValPtr,
UserFlagPtr,
BufferLen
);
}
BOOL
MemDbEnumItemsA (
OUT PMEMDB_ENUMA pEnum,
IN PCSTR Category
)
{
CHAR Pattern[MEMDB_MAX];
if (!Category)
return FALSE;
wsprintfA (Pattern, "%s\\*", Category);
return MemDbEnumFirstValueA (pEnum, Pattern, MEMDB_THIS_LEVEL_ONLY, NO_FLAGS);
}
BOOL
MemDbEnumItemsW (
OUT PMEMDB_ENUMW pEnum,
IN PCWSTR Category
)
{
WCHAR Pattern[MEMDB_MAX];
if (!Category)
return FALSE;
wsprintfW (Pattern, L"%s\\*", Category);
return MemDbEnumFirstValueW (pEnum, Pattern, MEMDB_THIS_LEVEL_ONLY, NO_FLAGS);
}
BOOL
MemDbEnumFieldsA (
OUT PMEMDB_ENUMA pEnum,
IN PCSTR Category,
IN PCSTR Item OPTIONAL
)
{
CHAR Pattern[MEMDB_MAX];
if (!Category)
return MemDbEnumItemsA (pEnum, Item);
if (!Item)
return MemDbEnumItemsA (pEnum, Category);
wsprintfA (Pattern, "%s\\%s\\*", Category, Item);
return MemDbEnumFirstValueA (pEnum, Pattern, MEMDB_THIS_LEVEL_ONLY, NO_FLAGS);
}
BOOL
MemDbEnumFieldsW (
OUT PMEMDB_ENUMW pEnum,
IN PCWSTR Category,
IN PCWSTR Item OPTIONAL
)
{
WCHAR Pattern[MEMDB_MAX];
if (!Category)
return MemDbEnumItemsW (pEnum, Item);
if (!Item)
return MemDbEnumItemsW (pEnum, Category);
wsprintfW (Pattern, L"%s\\%s\\*", Category, Item);
return MemDbEnumFirstValueW (pEnum, Pattern, MEMDB_THIS_LEVEL_ONLY, NO_FLAGS);
}
BOOL
MemDbGetValueExA (
OUT PMEMDB_ENUMA pEnum,
IN PCSTR Category,
IN PCSTR Item, OPTIONAL
IN PCSTR Field OPTIONAL
)
{
CHAR Pattern[MEMDB_MAX];
MemDbBuildKeyA (Pattern, Category, Item, Field, NULL);
if (*Pattern) {
AppendWackA (Pattern);
}
StringCatA (Pattern, "*");
return MemDbEnumFirstValueA (pEnum, Pattern, MEMDB_ALL_SUBLEVELS, MEMDB_ENDPOINTS_ONLY);
}
BOOL
MemDbGetValueExW (
OUT PMEMDB_ENUMW pEnum,
IN PCWSTR Category,
IN PCWSTR Item, OPTIONAL
IN PCWSTR Field OPTIONAL
)
{
WCHAR Pattern[MEMDB_MAX];
MemDbBuildKeyW (Pattern, Category, Item, Field, NULL);
if (*Pattern) {
AppendWackW (Pattern);
}
StringCatW (Pattern, L"*");
return MemDbEnumFirstValueW (pEnum, Pattern, MEMDB_ALL_SUBLEVELS, MEMDB_ENDPOINTS_ONLY);
}
BOOL
MemDbGetEndpointValueA (
IN PCSTR Pattern,
IN PCSTR Item, OPTIONAL // used as the first variable arg to wsprintfA
OUT PSTR Buffer
)
{
CHAR Path[MEMDB_MAX];
MEMDB_ENUMA memdb_enum;
if (!Pattern) {
if (!Item)
return FALSE;
StringCopyA (Path, Item);
}
else {
if (!Item)
StringCopyA (Path, Pattern);
else
wsprintfA (Path, Pattern, Item);
}
if (!MemDbEnumFirstValueA (&memdb_enum, Path,
MEMDB_ALL_SUBLEVELS, MEMDB_ENDPOINTS_ONLY)) {
Buffer[0] = 0;
return FALSE;
}
StringCopyA (Buffer, memdb_enum.szName);
return TRUE;
}
BOOL
MemDbGetEndpointValueW (
IN PCWSTR Pattern,
IN PCWSTR Item, OPTIONAL
OUT PWSTR Buffer
)
{
WCHAR Path[MEMDB_MAX];
MEMDB_ENUMW memdb_enum;
if (!Pattern) {
if (!Item)
return FALSE;
StringCopyW (Path, Item);
}
else {
if (!Item)
StringCopyW (Path, Pattern);
else
wsprintfW (Path, Pattern, Item);
}
if (!MemDbEnumFirstValueW (&memdb_enum, Path,
MEMDB_ALL_SUBLEVELS, MEMDB_ENDPOINTS_ONLY)) {
Buffer[0] = 0;
return FALSE;
}
StringCopyW (Buffer, memdb_enum.szName);
return TRUE;
}
BOOL
MemDbGetEndpointValueExA (
IN PCSTR Category,
IN PCSTR Item, OPTIONAL
IN PCSTR Field, OPTIONAL
OUT PSTR Buffer
)
{
CHAR Path[MEMDB_MAX];
MEMDB_ENUMA memdb_enum;
MemDbBuildKeyA (Path, Category, Item, Field, NULL);
if (*Path) {
AppendWackA (Path);
}
StringCatA (Path, "*");
if (!MemDbEnumFirstValueA (&memdb_enum, Path,
MEMDB_ALL_SUBLEVELS, MEMDB_ENDPOINTS_ONLY)) {
Buffer[0] = 0;
return FALSE;
}
strcpy (Buffer, memdb_enum.szName);
return TRUE;
}
BOOL
MemDbGetEndpointValueExW (
IN PCWSTR Category,
IN PCWSTR Item, OPTIONAL
IN PCWSTR Field, OPTIONAL
OUT PWSTR Buffer
)
{
WCHAR Path[MEMDB_MAX];
MEMDB_ENUMW memdb_enum;
MemDbBuildKeyW (Path, Category, Item, Field, NULL);
if (*Path) {
AppendWackW (Path);
}
StringCatW (Path, L"*");
if (!MemDbEnumFirstValueW (&memdb_enum, Path,
MEMDB_ALL_SUBLEVELS, MEMDB_ENDPOINTS_ONLY)) {
Buffer[0] = 0;
return FALSE;
}
StringCopyW (Buffer, memdb_enum.szName);
return TRUE;
}
BOOL
MemDbGetOffsetW(
IN PCWSTR Key,
OUT PDWORD Offset
)
{
BOOL b;
DWORD keyOffset;
keyOffset = FindKey (Key);
if (keyOffset == INVALID_OFFSET) {
b = FALSE;
}
else {
b = TRUE;
*Offset = keyOffset;
}
return b;
}
BOOL
MemDbGetOffsetA (
IN PCSTR Key,
OUT PDWORD Offset
)
{
PCWSTR wstr;
BOOL b;
wstr = ConvertAtoW (Key);
if (wstr) {
b = MemDbGetOffsetW (wstr,Offset);
FreeConvertedStr (wstr);
}
else {
b = FALSE;
}
return b;
}
BOOL
MemDbGetOffsetExW (
IN PCWSTR Category,
IN PCWSTR Item, OPTIONAL
IN PCWSTR Field, OPTIONAL
IN PCWSTR Data, OPTIONAL
OUT PDWORD Offset OPTIONAL
)
{
WCHAR Key[MEMDB_MAX];
MemDbBuildKeyW(Key,Category,Item,Field,Data);
return MemDbGetOffsetW(Key,Offset);
}
BOOL
MemDbGetOffsetExA (
IN PCSTR Category,
IN PCSTR Item, OPTIONAL
IN PCSTR Field, OPTIONAL
IN PCSTR Data, OPTIONAL
OUT PDWORD Offset OPTIONAL
)
{
CHAR Key[MEMDB_MAX];
MemDbBuildKeyA(Key,Category,Item,Field,Data);
return MemDbGetOffsetA(Key,Offset);
}