// // PCH.H // // Copyright (C) Microsoft Corporation, 1995 // #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 #include #ifdef VXD #include #include #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))) #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; 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 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) #include #include "regkylst.h" #include "regdblk.h" #include "regknode.h" #include "regnckey.h" #include "regfsio.h" #include "regmem.h" #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 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 ); int INTERNAL RgLookupValueByName( 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 RgCopyFromValueRecord( HKEY hKey, LPVALUE_RECORD lpValueRecord, LPSTR lpValueName, LPDWORD lpcbValueName, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData ); 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 RgDeleteKey( HKEY hKey ); DWORD INTERNAL RgChecksum( LPVOID lpBuffer, UINT ByteCount ); DWORD INTERNAL RgHashString( LPCSTR lpString, UINT Length ); 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_