windows-nt/Source/XPSP1/NT/base/ntsetup/win95upg/common/regw32d/pch.h
2020-09-26 16:20:57 +08:00

552 lines
16 KiB
C

//
// PCH.H
//
// Copyright (C) Microsoft Corporation, 1995-1996
//
#ifndef _REGPRIV_
#define _REGPRIV_
// Conditional enable registry "features" based on the target model.
//
// WANT_STATIC_KEYS: Allocates key handles from a memory pool allocated
// during library initialization. Especially useful for real-mode to reduce
// the memory fragmentation caused by allocating several small fixed objects.
//
// WANT_FULL_MEMORY_CLEANUP: When detaching, free every memory block. Not
// necessary for the ring zero version where "detach" means system shutdown.
//
// WANT_HIVE_SUPPORT: RegLoadKey, RegUnLoadKey, RegSaveKey, RegReplaceKey
// APIs plus support code.
//
// WANT_DYNKEY_SUPPORT: RegCreateDynKey plus HKEY_DYN_DATA support.
//
// WANT_NOTIFY_CHANGE_SUPPORT: RegNotifyChangeKeyValue plus support code.
#ifndef IS_32
#define WANT_STATIC_KEYS
#endif
#ifndef VXD
#define WANT_FULL_MEMORY_CLEANUP
#endif
#ifndef REALMODE
#define WANT_HIVE_SUPPORT
#endif
#ifdef VXD
#define WANT_REGREPLACEKEY
#define WANT_DYNKEY_SUPPORT
#define WANT_NOTIFY_CHANGE_SUPPORT
#endif
// Map any other header's definitions of these to unused types.
#define HKEY __UNUSED_HKEY
#define LPHKEY __UNUSED_LPHKEY
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#define NORESOURCE // prevent RT_* definitions from vmmsys.h
#include <windows.h>
#include <string.h>
#ifdef VXD
#error "Cannot compile with VXD defined"
// #include <vmmsys.h>
// #include <thrdsys.h>
#endif
#ifndef UNALIGNED
#define UNALIGNED // defined in standard headers for RISC
#endif
#ifndef ANYSIZE_ARRAY
#define ANYSIZE_ARRAY 1
#endif
#ifdef VXD
// By default, all registry code and data is pageable.
#pragma VMM_PAGEABLE_CODE_SEG
#pragma VMM_PAGEABLE_DATA_SEG
#endif
#define UNREFERENCED_PARAMETER(P) (P)
#define INTERNAL PASCAL NEAR
#define INTERNALV CDECL NEAR
// Undefine any constants that we're about to define ourselves.
#undef HKEY
#undef LPHKEY
#undef HKEY_CLASSES_ROOT
#undef HKEY_CURRENT_USER
#undef HKEY_LOCAL_MACHINE
#undef HKEY_USERS
#undef HKEY_PERFORMANCE_DATA
#undef HKEY_CURRENT_CONFIG
#undef HKEY_DYN_DATA
typedef struct _KEY FAR* HKEY; // Forward reference
#include "regdebug.h"
#include "regffmt.h"
#include "regfinfo.h"
// Many file structures in the registry are declared as DWORDs, the HIWORD is
// always zero. Use SmallDword to access such DWORDs for optimal access in
// 16-bit or 32-bit code.
#if defined(IS_32)
#define SmallDword(dw) ((UINT) (dw))
#else
#define SmallDword(dw) ((UINT) LOWORD((dw)))
#endif
#if defined(WIN16)
#define IsNullPtr(ptr) (SELECTOROF((ptr)) == NULL)
#else
#define IsNullPtr(ptr) ((ptr) == NULL)
#endif
// In either mode, the resulting code uses an instrinsic version of the memcmp
// function.
#if defined(IS_32)
#define CompareMemory memcmp
#else
#define CompareMemory _fmemcmp
#endif
#if defined(WIN16) || defined(WIN32)
#define StrCpy(lpd, lps) (lstrcpy((lpd), (lps)))
#define StrCpyN(lpd, lps, cb) (lstrcpyn((lpd), (lps), (cb)))
#define StrLen(lpstr) (lstrlen((lpstr)))
#define ToUpper(ch) ((int) (DWORD) AnsiUpper((LPSTR)((BYTE)(ch))))
#define RgCreateFile(lpfn) ((HFILE) _lcreat((lpfn), 0))
#define RgOpenFile(lpfn, mode) ((HFILE) _lopen((lpfn), (mode)))
#define RgCloseFile(h) ((VOID) _lclose(h))
#if defined(WIN32)
#define RgDeleteFile(lpv) (DeleteFile((lpv)))
#define RgRenameFile(lpv1, lpv2) (MoveFile((lpv1), (lpv2)))
#define RgGetFileAttributes(lpv) (GetFileAttributes((lpv)))
#define RgSetFileAttributes(lpv, a) (SetFileAttributes((lpv), (a)))
#define RgCommitFile(h) (FlushFileBuffers((HANDLE)h))
#ifdef USEHEAP
extern HANDLE g_RgHeap; // Low memory heap for testing
#define AllocBytes(cb) ((LPVOID) HeapAlloc(g_RgHeap, 0, (cb)))
#define FreeBytes(lpv) ((VOID) HeapFree(g_RgHeap, 0, (lpv)))
#define ReAllocBytes(lpv, cb) ((LPVOID) HeapReAlloc(g_RgHeap, 0, (lpv), (cb)))
#define MemorySize(lpv) ((UINT) HeapSize(g_RgHeap, 0, (lpv)))
#else
#define AllocBytes(cb) ((LPVOID) LocalAlloc(LMEM_FIXED, (cb)))
#define FreeBytes(lpv) ((VOID) LocalFree((HLOCAL) (lpv)))
#define ReAllocBytes(lpv, cb) ((LPVOID) LocalReAlloc((HLOCAL) (lpv), (cb), LMEM_MOVEABLE))
#define MemorySize(lpv) ((UINT) LocalSize((lpv)))
#endif // USEHEAP
#else
#define AllocBytes(cb) ((LPVOID) MAKELP(GlobalAlloc(GMEM_FIXED, (cb)), 0))
#define FreeBytes(lpv) ((VOID) GlobalFree((HGLOBAL) SELECTOROF((lpv))))
#define ReAllocBytes(lpv, cb) ((LPVOID) MAKELP(GlobalReAlloc((HGLOBAL) SELECTOROF((lpv)), (cb), GMEM_MOVEABLE), 0))
#define MemorySize(lpv) ((UINT) GlobalSize((HGLOBAL) SELECTOROF((lpv))))
// WIN16's ZeroMemory/MoveMemory: SETUPX is the only target WIN16 environment
// and they already use _fmemset and _fmemmove, so just use their versions.
#define ZeroMemory(lpv, cb) (_fmemset((lpv), 0, (cb)))
#define MoveMemory(lpd, lps, cb) (_fmemmove((lpd), (lps), (cb)))
#endif // WIN16 || WIN32
#elif defined(REALMODE)
#define IsBadStringPtr(lpv, cb) (FALSE)
#define IsBadHugeWritePtr(lpv, cb) (FALSE)
#define IsBadHugeReadPtr(lpv, cb) (FALSE)
#define StrCpy(lpd, lps) (_fstrcpy((lpd), (lps)))
#define StrCpyN(lpd, lps, cb) (_fstrcpyn((lpd), (lps), (cb)))
#define StrLen(lpstr) (_fstrlen((lpstr)))
#define ToUpper(ch) ((int)(((ch>='a')&&(ch<='z'))?(ch-'a'+'A'):ch))
LPVOID INTERNAL AllocBytes(UINT);
VOID INTERNAL FreeBytes(LPVOID);
LPVOID INTERNAL ReAllocBytes(LPVOID, UINT);
UINT INTERNAL MemorySize(LPVOID);
VOID INTERNAL ZeroMemory(LPVOID, UINT);
VOID INTERNAL MoveMemory(LPVOID, const VOID FAR*, UINT);
#elif defined(VXD)
#undef IsBadStringPtr // Conflicts with windows.h
#undef ZeroMemory // Conflicts with windows.h
#undef MoveMemory // Conflicts with windows.h
BOOL INTERNAL RgIsBadStringPtr(const VOID FAR*, UINT);
BOOL INTERNAL RgIsBadOptionalStringPtr(const VOID FAR*, UINT);
BOOL INTERNAL RgIsBadHugeWritePtr(const VOID FAR*, UINT);
BOOL INTERNAL RgIsBadHugeOptionalWritePtr(const VOID FAR*, UINT);
BOOL INTERNAL RgIsBadHugeReadPtr(const VOID FAR*, UINT);
#define IsBadStringPtr(lpv, cb) (RgIsBadStringPtr((lpv), (cb)))
#define IsBadOptionalStringPtr(lpv, cb) (RgIsBadOptionalStringPtr((lpv), (cb)))
#define IsBadHugeWritePtr(lpv, cb) (RgIsBadHugeWritePtr((lpv), (cb)))
#define IsBadHugeOptionalWritePtr(lpv, cb) (RgIsBadHugeOptionalWritePtr((lpv), (cb)))
#define IsBadHugeReadPtr(lpv, cb) (RgIsBadHugeReadPtr((lpv), (cb)))
#define StrCpy(lpd, lps) (_lstrcpyn((PCHAR)(lpd), (PCHAR)(lps), (ULONG)(-1)))
#define StrCpyN(lpd, lps, cb) (_lstrcpyn((PCHAR)(lpd), (PCHAR)(lps), (ULONG)(cb)))
#define StrLen(lpstr) (_lstrlen((PCHAR)(lpstr)))
extern UCHAR UpperCaseTable[256];
#define ToUpper(ch) ((int)(UpperCaseTable[(UCHAR)(ch)]))
VOID INTERNAL RgSetAndReleaseEvent(HANDLE hEvent);
#define RgGetCurrentThreadId() ((DWORD)pthcbCur)
#define AllocBytes(cb) ((LPVOID) _HeapAllocate((cb), HEAPSWAP))
#define FreeBytes(lpv) ((VOID) _HeapFree((lpv), 0))
#define ReAllocBytes(lpv, cb) ((LPVOID) _HeapReAllocate((lpv), (cb), HEAPSWAP))
#define MemorySize(lpv) ((UINT) _HeapGetSize((lpv), 0))
#define AllocPages(cp) ((LPVOID) _PageAllocate((cp), PG_SYS, 0, 0, 0, 0, NULL, 0))
#define FreePages(lpv) ((VOID) _PageFree((ULONG) (lpv), 0))
#define ReAllocPages(lpv, cp) ((LPVOID) _PageReAllocate((ULONG) (lpv), (cp), 0))
VOID INTERNAL RgZeroMemory(LPVOID, UINT);
VOID INTERNAL RgMoveMemory(LPVOID, const VOID FAR*, UINT);
#define ZeroMemory RgZeroMemory
#define MoveMemory RgMoveMemory
#else
#error Must define REALMODE, VXD, WIN16, or WIN32.
#endif
// The IsBadHugeOptional*Ptr macros are used to validate pointers that may be
// NULL. By wrapping this "predicate", we can generate smaller code in some
// environments, specifically VMM...
#if !defined(VXD)
#define IsBadOptionalStringPtr(lpv, cb) \
(!IsNullPtr((lpv)) && IsBadStringPtr((lpv), (cb)))
#define IsBadHugeOptionalWritePtr(lpv, cb) \
(!IsNullPtr((lpv)) && IsBadHugeWritePtr((lpv), (cb)))
#endif
// The IsEnumIndexTooBig macro is used to check if a DWORD sized index can fit
// into a UINT sized variable. Only useful for validation of RegEnumKey or
// RegEnumValue to make small code in both 16 and 32 bit environments.
#if defined(IS_32)
#define IsEnumIndexTooBig(index) (FALSE)
#else
#define IsEnumIndexTooBig(index) (HIWORD(index) > 0)
#endif
#if defined(VXD)
BOOL INTERNAL RgLockRegistry(VOID);
VOID INTERNAL RgUnlockRegistry(VOID);
VOID INTERNAL RgDelayFlush(VOID);
VOID INTERNAL RgYield(VOID);
#else
#define RgLockRegistry() (TRUE)
#define RgUnlockRegistry() (TRUE)
#define RgDelayFlush() (TRUE)
#define RgYield() (TRUE)
#endif
// Eliminate the need for #ifdef DBCS by using macros and letting the compiler
// optimize out the DBCS code on SBCS systems.
#ifdef DBCS
#if !defined(WIN16) && !defined(WIN32)
BOOL INTERNAL RgIsDBCSLeadByte(BYTE TestChar);
#define IsDBCSLeadByte(ch) RgIsDBCSLeadByte(ch)
#endif
#else
#define IsDBCSLeadByte(ch) ((ch), FALSE)
#endif // DBCS
#ifdef WANT_DYNKEY_SUPPORT
// Internally used for maintaining dynamic key information; only keeps the
// fields that we actually need from the REG_PROVIDER structure given to
// VMMRegCreateDynKey.
typedef struct _INTERNAL_PROVIDER {
PQUERYHANDLER ipi_R0_1val;
PQUERYHANDLER ipi_R0_allvals;
LPVOID ipi_key_context;
} INTERNAL_PROVIDER, FAR* PINTERNAL_PROVIDER;
#endif
typedef struct _KEY {
WORD Signature; // KEY_SIGNATURE
WORD Flags; // KEYF_* bits
UINT ReferenceCount;
LPFILE_INFO lpFileInfo;
DWORD KeynodeIndex;
DWORD ChildKeynodeIndex;
WORD BlockIndex;
WORD BigKeyLockedBlockIndex; // If a bigkey function locked a datablock, this is its index
BYTE KeyRecordIndex;
BYTE PredefinedKeyIndex;
struct _KEY FAR* lpNext;
struct _KEY FAR* lpPrev;
UINT LastEnumKeyIndex;
DWORD LastEnumKeyKeynodeIndex;
#ifdef WANT_DYNKEY_SUPPORT
PINTERNAL_PROVIDER pProvider;
#endif
} KEY;
#define KEY_SIGNATURE 0x4B48 // "HK"
#define KEYF_PREDEFINED 0x01 // Represents one of HKEY_*
#define KEYF_DELETED 0x02 //
#define KEYF_INVALID 0x04 //
#define KEYF_STATIC 0x08 // Allocated from static pool
#define KEYF_ENUMKEYCACHED 0x10 // LastEnumKey* values valid
#define KEYF_HIVESALLOWED 0x20 //
#define KEYF_PROVIDERHASVALUELENGTH 0x40 // PROVIDER_KEEPS_VALUE_LENGTH
#define KEYF_NEVERDELETE 0x80 // Reference count overflow
#define KEYF_BIGKEYROOT 0x100 // This key handle is for a big key
#define KEYF_ENUMEXTENTCACHED 0x200 // LastEnumKey* is for a big key extent
#define INDEX_CLASSES_ROOT 0
#define INDEX_CURRENT_USER 1
#define INDEX_LOCAL_MACHINE 2
#define INDEX_USERS 3
#define INDEX_PERFORMANCE_DATA 4
#define INDEX_CURRENT_CONFIG 5
#define INDEX_DYN_DATA 6
// Returns TRUE if the KEY references the root of a hive, such as
// HKEY_LOCAL_MACHINE, HKEY_USERS, or any hive loaded by RegLoadKey.
#define IsKeyRootOfHive(hkey) \
((hkey)-> KeynodeIndex == (hkey)-> lpFileInfo-> KeynodeHeader.RootIndex)
// Returns TRUE if the KEY is a subkey of HKEY_DYN_DATA.
#ifdef WANT_DYNKEY_SUPPORT
#define IsDynDataKey(hkey) \
((hkey)-> PredefinedKeyIndex == INDEX_DYN_DATA)
#else
#define IsDynDataKey(hkey) (FALSE)
#endif
#include <regapix.h>
#include "regkylst.h"
#include "regdblk.h"
#include "regknode.h"
#include "regnckey.h"
#include "regfsio.h"
#include "regmem.h"
#define ERROR_BIGKEY_NEEDED 1025L // Internal error, the data won't fit in a normal key
#ifdef VXD
extern BYTE g_RgPostCriticalInit;
extern BYTE g_RgFileAccessDisabled;
#define IsPostCriticalInit() (g_RgPostCriticalInit)
#define IsFileAccessDisabled() (g_RgFileAccessDisabled)
#else
#define IsPostCriticalInit() (TRUE)
#define IsFileAccessDisabled() (FALSE)
#endif
// g_RgWorkBuffer: one buffer is always available of size SIZEOF_WORK_BUFFER.
// These macros wrap access to this buffer for to verify only one routine is
// attempting to use it at any time.
extern LPVOID g_RgWorkBuffer;
#ifdef DEBUG
extern BOOL g_RgWorkBufferBusy;
#define RgLockWorkBuffer() \
(ASSERT(!g_RgWorkBufferBusy), g_RgWorkBufferBusy = TRUE, (LPVOID) g_RgWorkBuffer)
#define RgUnlockWorkBuffer(lpv) \
(VOID) (ASSERT((lpv) == g_RgWorkBuffer), g_RgWorkBufferBusy = FALSE)
#else
#define RgLockWorkBuffer() ((LPVOID) g_RgWorkBuffer)
#define RgUnlockWorkBuffer(lpv)
#endif
#define SIZEOF_WORK_BUFFER (sizeof(W95KEYNODE_BLOCK))
#define IsKeyRecordFree(lpkr) \
(((lpkr)-> DatablockAddress) == REG_NULL)
BOOL
INTERNAL
RgIsBadSubKey(
LPCSTR lpSubKey
);
UINT
INTERNAL
RgGetNextSubSubKey(
LPCSTR lpSubKey,
LPCSTR FAR* lplpSubSubKey,
UINT FAR* lpSubSubKeyLength
);
#define LK_OPEN 0x0000 // Open key only
#define LK_CREATE 0x0001 // Create or open key
#define LK_CREATEDYNDATA 0x0002 // HKEY_DYN_DATA may create
#define LK_BIGKEYEXT 0x0004 // Search only for big key extents
int
INTERNAL
RgLookupKey(
HKEY hKey,
LPCSTR lpSubKey,
LPHKEY lphSubKey,
UINT Flags
);
int
INTERNAL
RgCreateOrOpenKey(
HKEY hKey,
LPCSTR lpSubKey,
LPHKEY lphKey,
UINT Flags
);
int
INTERNAL
RgLookupKeyByIndex(
HKEY hKey,
UINT Index,
LPSTR lpKeyName,
LPDWORD lpcbKeyName,
UINT Flags
);
int
INTERNAL
RgLookupValueByName(
HKEY hKey,
LPCSTR lpValueName,
LPKEY_RECORD FAR* lplpKeyRecord,
LPVALUE_RECORD FAR* lplpValueRecord
);
int
INTERNAL
RgLookupValueByNameStd(
HKEY hKey,
LPCSTR lpValueName,
LPKEY_RECORD FAR* lplpKeyRecord,
LPVALUE_RECORD FAR* lplpValueRecord
);
int
INTERNAL
RgLookupValueByIndex(
HKEY hKey,
UINT Index,
LPVALUE_RECORD FAR* lplpValueRecord
);
int
INTERNAL
RgLookupValueByIndexStd(
HKEY hKey,
UINT Index,
LPVALUE_RECORD FAR* lplpValueRecord,
UINT FAR* lpValueCount
);
int
INTERNAL
RgCopyFromValueRecord(
HKEY hKey,
LPVALUE_RECORD lpValueRecord,
LPSTR lpValueName,
LPDWORD lpcbValueName,
LPDWORD lpType,
LPBYTE lpData,
LPDWORD lpcbData
);
VOID
INTERNAL
RgDeleteValueRecord(
LPKEY_RECORD lpKeyRecord,
LPVALUE_RECORD lpValueRecord
);
int
INTERNAL
RgReAllocKeyRecord(
HKEY hKey,
DWORD Length,
LPKEY_RECORD FAR* lplpKeyRecord
);
int
INTERNAL
RgSetValue(
HKEY hKey,
LPCSTR lpValueName,
DWORD Type,
LPBYTE lpData,
UINT cbData
);
int
INTERNAL
RgSetValueStd(
HKEY hKey,
LPCSTR lpValueName,
DWORD Type,
LPBYTE lpData,
UINT cbData,
BOOL fBigKeyExtent
);
int
INTERNAL
RgDeleteKey(
HKEY hKey
);
DWORD
INTERNAL
RgChecksum(
LPVOID lpBuffer,
UINT ByteCount
);
DWORD
INTERNAL
RgHashString(
LPCSTR lpString,
UINT Length
);
WORD
INTERNAL
RgAtoW(
LPCSTR lpDec
);
VOID
INTERNAL
RgWtoA(
WORD Dec,
LPSTR lpDec
);
int
INTERNAL
RgStrCmpNI(
LPCSTR lpString1,
LPCSTR lpString2,
UINT Length
);
int
INTERNAL
RgCopyFileBytes(
HFILE hSourceFile,
LONG SourceOffset,
HFILE hDestinationFile,
LONG DestinationOffset,
DWORD cbSize
);
BOOL
INTERNAL
RgGenerateAltFileName(
LPCSTR lpFileName,
LPSTR lpAltFileName,
char ExtensionChar
);
int
INTERNAL
RgCopyFile(
LPCSTR lpSourceFile,
LPCSTR lpDestinationFile
);
int
INTERNAL
RgReplaceFileInfo(
LPFILE_INFO lpFileInfo
);
#endif // _REGPRIV_