Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

753 lines
13 KiB

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
memdbp.h
Abstract:
internal functions for memdb operations
Author:
Matthew Vanderzee (mvander) 13-Aug-1999
Revision History:
--*/
//
// Constants
//
#define INVALID_OFFSET (~((UINT)0))
//
// database types
//
#define DB_NOTHING 0x00
#define DB_PERMANENT 0x01
#define DB_TEMPORARY 0x02
#ifdef DEBUG
#define PTR_WAS_INVALIDATED(x) (x=NULL)
#else
#define PTR_WAS_INVALIDATED(x)
#endif
//
// signatures for different memory structures.
//
#define KEYSTRUCT_SIGNATURE ('K'+('E'<<8)+('E'<<16)+('Y'<<24))
#define DATABLOCK_SIGNATURE ('B'+('L'<<8)+('O'<<16)+('K'<<24))
#define NODESTRUCT_SIGNATURE ('N'+('O'<<8)+('D'<<16)+('E'<<24))
#define BINTREE_SIGNATURE ('T'+('R'<<8)+('E'<<16)+('E'<<24))
#define LISTELEM_SIGNATURE ('L'+('I'<<8)+('S'<<16)+('T'<<24))
#define MEMDB_VERBOSE 0
//
// KEYSTRUCT flags
//
#define KSF_ENDPOINT 0x01
#define KSF_DATABLOCK 0x02
//
// we only need this flag for easier checking
// of keys, in FindKeyStructInDatabase()
//
#ifdef DEBUG
#define KSF_DELETED 0x04
#endif
//
// database allocation parameters
//
#define ALLOC_TOLERANCE 32
#define MAX_HIVE_NAME 64
//
// Typedefs
//
typedef struct {
UINT Size;
UINT End;
UINT FreeHead;
PBYTE Buf;
} MEMDBHASH, *PMEMDBHASH;
//
//
// The DATABASE structure holds all pieces of information necessary
// to maintain a portion of the overall memory database. There are
// two DATABASE structures, a permanent and a temporary one.
//
typedef struct {
UINT AllocSize;
UINT End;
UINT FirstLevelTree;
UINT FirstKeyDeleted; // this stores the Offset of the key, not the Index
UINT FirstBinTreeDeleted;
UINT FirstBinTreeNodeDeleted;
UINT FirstBinTreeListElemDeleted;
BOOL AllocFailed;
PMEMDBHASH HashTable;
GROWBUFFER OffsetBuffer;
UINT OffsetBufferFirstDeletedIndex;
BYTE Buf[];
} DATABASE, *PDATABASE;
//
// Globals - defined in database.c
//
extern PDATABASE g_CurrentDatabase;
extern BYTE g_CurrentDatabaseIndex;
extern CRITICAL_SECTION g_MemDbCs;
#ifdef DEBUG
extern BOOL g_UseDebugStructs;
#endif
#define OFFSET_TO_PTR(Offset) (g_CurrentDatabase->Buf+(Offset))
#define PTR_TO_OFFSET(Ptr) (UINT)((UBINT)(Ptr)-(UBINT)(g_CurrentDatabase->Buf))
//
// GET_EXTERNAL_INDEX converts an internal index and converts it to a key or data handle (has database number as top byte).
// GET_DATABASE takes a key or data handle and returns the database number byte
// GET_INDEX takes a key or data handle and returns the index without the database number
//
#define GET_EXTERNAL_INDEX(Index) ((Index) | ((UINT)(g_CurrentDatabaseIndex) << (8*sizeof(UINT)-8)))
#define GET_DATABASE(Index) ((BYTE)((Index) >> (8*sizeof(UINT)-8)))
#define GET_INDEX(Index) ((Index) & (INVALID_OFFSET>>8))
//
// a KEYSTRUCT holds each piece of a memdb entry. A single KEYSTRUCT
// holds a portion of a key (delimited by a backslash), and the
// KEYSTRUCTs are organized into a binary tree. Each KEYSTRUCT
// can also contain additional binary trees. This is what makes
// memdb so versatile--many relationships can be established by
// formatting key strings in various ways.
//
// when changing offset of KeyName in KEYSTRUCT (by adding new members
// or resizing or reordering, etc) be sure to change constant in
// GetDataStr macro below (currently (3*sizeof(UINT)+4)).
typedef struct {
#ifdef DEBUG
DWORD Signature;
#endif
union {
UINT Value; // value of key
UINT DataSize; // size of the actual data (if this is a data structure
UINT NextDeleted; // for deleted items, we keep a list of free blocks
};
UINT Flags; // key flags
UINT DataStructIndex; // offset of Data structure holding the binary data
UINT NextLevelTree; // offset of bintree holding next level keystructs
UINT PrevLevelIndex; // index of previous level keystruct
UINT Size; // size of block (maybe not all of it is used)
BYTE KeyFlags;
BYTE DataFlags;
union {
WCHAR KeyName[]; // name of key (just this level, not full key)
BYTE Data[]; // Binary data stored in this keystruct
};
} KEYSTRUCT, *PKEYSTRUCT;
#define KEYSTRUCT_SIZE_MAIN ((WORD)(5*sizeof(UINT) + sizeof(UINT) + 2*sizeof(BYTE)))
#ifdef DEBUG
#define KEYSTRUCT_HEADER_SIZE sizeof(DWORD)
#define KEYSTRUCT_SIZE (KEYSTRUCT_SIZE_MAIN + \
(WORD)(g_UseDebugStructs ? KEYSTRUCT_HEADER_SIZE : 0))
#else
#define KEYSTRUCT_SIZE KEYSTRUCT_SIZE_MAIN
#endif
//
// GetDataStr is used by the bintree.c functions to get
// the data string inside a data element, to be used for
// ordering in the tree. For us, the data type is
// a KeyStruct.
//
#define GetDataStr(DataIndex) ((PWSTR)(OFFSET_TO_PTR(KeyIndexToOffset(DataIndex)+KEYSTRUCT_SIZE)))
//
// hash.c routines
//
PMEMDBHASH
CreateHashBlock (
VOID
);
VOID
FreeHashBlock (
IN PMEMDBHASH pHashTable
);
BOOL
ReadHashBlock (
IN PMEMDBHASH pHashTable,
IN OUT PBYTE *Buf
);
BOOL
WriteHashBlock (
IN PMEMDBHASH pHashTable,
IN OUT PBYTE *Buf
);
UINT
GetHashTableBlockSize (
IN PMEMDBHASH pHashTable
);
BOOL
AddHashTableEntry (
IN PMEMDBHASH pHashTable,
IN PCWSTR FullString,
IN UINT Offset
);
UINT
FindStringInHashTable (
IN PMEMDBHASH pHashTable,
IN PCWSTR FullString
);
BOOL
RemoveHashTableEntry (
IN PMEMDBHASH pHashTable,
IN PCWSTR FullString
);
//
// memdbfile.c
//
BOOL
SetSizeOfFile (
HANDLE hFile,
LONGLONG Size
);
PBYTE
MapFileFromHandle (
HANDLE hFile,
PHANDLE hMap
);
#define UnmapFileFromHandle(Buf, hMap) UnmapFile(Buf, hMap, INVALID_HANDLE_VALUE)
//
// database.c
//
BOOL
DatabasesInitializeA (
IN PCSTR DatabasePath OPTIONAL
);
BOOL
DatabasesInitializeW (
IN PCWSTR DatabasePath OPTIONAL
);
PCSTR
DatabasesGetBasePath (
VOID
);
VOID
DatabasesTerminate (
IN BOOL EraseDatabasePath
);
BOOL
SizeDatabaseBuffer (
IN BYTE DatabaseIndex,
IN UINT NewSize
);
UINT
DatabaseAllocBlock (
IN UINT Size
);
BOOL
SelectDatabase (
IN BYTE DatabaseIndex
);
PCWSTR
SelectHiveW (
IN PCWSTR FullKeyStr
);
BYTE
GetCurrentDatabaseIndex (
VOID
);
#ifdef DEBUG
BOOL
CheckDatabase (
IN UINT Level
);
#endif
//
// offsetbuf.c
//
VOID
RedirectKeyIndex (
IN UINT Index,
IN UINT TargetIndex
);
UINT
KeyIndexToOffset (
IN UINT Index
);
UINT
AddKeyOffsetToBuffer(
IN UINT Offset
);
VOID
RemoveKeyOffsetFromBuffer(
IN UINT Index
);
VOID
MarkIndexList (
PUINT IndexList,
UINT IndexListSize
);
BOOL
ReadOffsetBlock (
OUT PGROWBUFFER pOffsetBuffer,
IN OUT PBYTE *Buf
);
BOOL
WriteOffsetBlock (
IN PGROWBUFFER pOffsetBuffer,
IN OUT PBYTE *Buf
);
UINT GetOffsetBufferBlockSize (
IN PGROWBUFFER pOffsetBuffer
);
//
// pastring.c
// Pascal-style string: wide characters, first char
// is number of characters, no null-termination
//
typedef WCHAR * PPASTR;
typedef WCHAR const * PCPASTR;
//
// these convert a WSTR in place from null-terminated
// to Pascal-style strings
//
PPASTR StringPasConvertTo (PWSTR str);
PWSTR StringPasConvertFrom (PPASTR str);
//
// these convert a WSTR from null-terminated
// to Pascal-style strings in new string buffer
//
PPASTR StringPasCopyConvertTo (PPASTR str1, PCWSTR str2);
PWSTR StringPasCopyConvertFrom (PWSTR str1, PCPASTR str2);
PPASTR StringPasCopy (PPASTR str1, PCPASTR str2);
UINT StringPasCharCount (PCPASTR str);
INT StringPasCompare (PCPASTR str1, PCPASTR str2);
BOOL StringPasMatch (PCPASTR str1, PCPASTR str2);
INT StringPasICompare (PCPASTR str1, PCPASTR str2);
BOOL StringPasIMatch (PCPASTR str1, PCPASTR str2);
//
// keystrct.c
//
#ifdef DEBUG
PKEYSTRUCT
GetKeyStructFromOffset (
UINT Offset
);
PKEYSTRUCT
GetKeyStruct (
UINT Index
);
#else
#define GetKeyStructFromOffset(Offset) ((Offset==INVALID_OFFSET) ? \
NULL : \
(PKEYSTRUCT)OFFSET_TO_PTR(Offset))
#define GetKeyStruct(Index) ((Index==INVALID_OFFSET) ? \
NULL : \
GetKeyStructFromOffset(KeyIndexToOffset(Index)))
#endif
UINT
GetFirstIndex (
IN UINT TreeOffset,
OUT PUINT pTreeEnum
);
UINT
GetNextIndex (
IN OUT PUINT pTreeEnum
);
UINT
NewKey (
IN PCWSTR KeyStr
);
UINT
NewEmptyKey (
IN PCWSTR KeyStr
);
BOOL
PrivateDeleteKeyByIndex (
IN UINT Index
);
BOOL
DeleteKey (
IN PCWSTR KeyStr,
IN UINT TreeOffset,
IN BOOL MustMatch
);
BOOL
PrivateBuildKeyFromIndex (
IN UINT StartLevel, // zero-based
IN UINT TailIndex,
OUT PWSTR Buffer, OPTIONAL
OUT PUINT ValPtr, OPTIONAL
OUT PUINT UserFlagsPtr, OPTIONAL
OUT PUINT SizeInChars OPTIONAL
);
BOOL
KeyStructSetInsertionOrdered (
IN PKEYSTRUCT Key
);
UINT KeyStructGetChildCount (
IN PKEYSTRUCT pKey
);
UINT
FindKeyStructInTree (
IN UINT TreeOffset,
IN PWSTR KeyName,
IN BOOL IsPascalString
);
#ifdef DEBUG
BOOL
CheckLevel(UINT TreeOffset,
UINT PrevLevelIndex
);
#endif
//
// keyfind.c
//
UINT
FindKeyStruct(
IN PCWSTR Key
);
UINT
FindKey (
IN PCWSTR FullKeyPath
);
UINT
FindKeyStructUsingTreeOffset (
IN UINT TreeOffset,
IN OUT PUINT pTreeEnum,
IN PCWSTR KeyStr
);
#ifdef DEBUG
BOOL
FindKeyStructInDatabase(
UINT KeyOffset
);
#endif
//
// keydata.c
//
BOOL
KeyStructSetValue (
IN UINT KeyIndex,
IN UINT Value
);
BOOL
KeyStructSetFlags (
IN UINT KeyIndex,
IN BOOL ReplaceFlags,
IN UINT SetFlags,
IN UINT ClearFlags
);
UINT
KeyStructAddBinaryData (
IN UINT KeyIndex,
IN BYTE Type,
IN BYTE Instance,
IN PCBYTE Data,
IN UINT DataSize
);
UINT
KeyStructGrowBinaryData (
IN UINT KeyIndex,
IN BYTE Type,
IN BYTE Instance,
IN PCBYTE Data,
IN UINT DataSize
);
UINT
KeyStructGrowBinaryDataByIndex (
IN UINT OldIndex,
IN PCBYTE Data,
IN UINT DataSize
);
BOOL
KeyStructDeleteBinaryData (
IN UINT KeyIndex,
IN BYTE Type,
IN BYTE Instance
);
BOOL
KeyStructDeleteBinaryDataByIndex (
IN UINT DataIndex
);
UINT
KeyStructReplaceBinaryDataByIndex (
IN UINT OldIndex,
IN PCBYTE Data,
IN UINT DataSize
);
PBYTE
KeyStructGetBinaryData (
IN UINT KeyIndex,
IN BYTE Type,
IN BYTE Instance,
OUT PUINT DataSize,
OUT PUINT DataIndex //OPTIONAL
);
PBYTE
KeyStructGetBinaryDataByIndex (
IN UINT DataIndex,
OUT PUINT DataSize
);
UINT
KeyStructGetDataIndex (
IN UINT KeyIndex,
IN BYTE Type,
IN BYTE Instance
);
DATAHANDLE
KeyStructAddLinkage (
IN UINT KeyIndex,
IN BYTE Type,
IN BYTE Instance,
IN UINT Linkage,
IN BOOL AllowDuplicates
);
DATAHANDLE
KeyStructAddLinkageByIndex (
IN UINT DataIndex,
IN UINT Linkage,
IN BOOL AllowDuplicates
);
BOOL
KeyStructDeleteLinkage (
IN UINT KeyIndex,
IN BYTE Type,
IN BYTE Instance,
IN UINT Linkage,
IN BOOL FirstOnly
);
BOOL
KeyStructDeleteLinkageByIndex (
IN UINT DataIndex,
IN UINT Linkage,
IN BOOL FirstOnly
);
BOOL
KeyStructTestLinkage (
IN UINT KeyIndex,
IN BYTE Type,
IN BYTE Instance,
IN KEYHANDLE Linkage
);
BOOL
KeyStructTestLinkageByIndex (
IN UINT DataIndex,
IN UINT Linkage
);
BOOL
KeyStructGetValue (
IN PKEYSTRUCT KeyStruct,
OUT PUINT Value
);
BOOL
KeyStructGetFlags (
IN PKEYSTRUCT KeyStruct,
OUT PUINT Flags
);
VOID
KeyStructFreeAllData (
PKEYSTRUCT KeyStruct
);
//
// bintree.c
//
#ifdef DEBUG
//
// violating code hiding for easier debugging.
// (only database.c should see bintree functions)
//
UINT
BinTreeGetSizeOfStruct(
DWORD Signature
);
BOOL
BinTreeFindStructInDatabase(
DWORD Sig,
UINT Offset
);
#endif