/* * PROJECT: Registry manipulation library * LICENSE: GPL - See COPYING in the top level directory * COPYRIGHT: Copyright 2005 Filip Navara * Copyright 2001 - 2005 Eric Kohl */ #ifndef _CMLIB_H_ #define _CMLIB_H_ // // Debug support switch // #define _CMLIB_DEBUG_ 1 #ifdef CMLIB_HOST #include #include #include // NTDDI_xxx versions we allude to in the library (see psdk/sdkddkver.h) #define NTDDI_WS03SP4 0x05020400 #define NTDDI_WIN6 0x06000000 #define NTDDI_LONGHORN NTDDI_WIN6 #define NTDDI_VISTA NTDDI_WIN6 #define NTDDI_WIN7 0x06010000 #define NTDDI_VERSION NTDDI_WS03SP4 // This is the ReactOS NT kernel version /* C_ASSERT Definition */ #define C_ASSERT(expr) extern char (*c_assert(void)) [(expr) ? 1 : -1] #ifdef _WIN32 #define strncasecmp _strnicmp #define strcasecmp _stricmp #endif // _WIN32 #if (!defined(_MSC_VER) || (_MSC_VER < 1500)) #define _In_ #define _Out_ #define _Inout_ #define _In_opt_ #define _In_range_(x, y) #endif #define __drv_aliasesMem #ifndef min #define min(a, b) (((a) < (b)) ? (a) : (b)) #endif // #ifndef max // #define max(a, b) (((a) > (b)) ? (a) : (b)) // #endif // Definitions copied from // We only want to include host headers, so we define them manually #define STATUS_SUCCESS ((NTSTATUS)0x00000000) #define STATUS_NOT_IMPLEMENTED ((NTSTATUS)0xC0000002) #define STATUS_NO_MEMORY ((NTSTATUS)0xC0000017) #define STATUS_INSUFFICIENT_RESOURCES ((NTSTATUS)0xC000009A) #define STATUS_REGISTRY_CORRUPT ((NTSTATUS)0xC000014C) #define STATUS_NOT_REGISTRY_FILE ((NTSTATUS)0xC000015C) #define STATUS_REGISTRY_RECOVERED ((NTSTATUS)0x40000009) #define REG_OPTION_VOLATILE 1 #define OBJ_CASE_INSENSITIVE 0x00000040L #define USHORT_MAX USHRT_MAX #define OBJ_NAME_PATH_SEPARATOR ((WCHAR)L'\\') #define UNICODE_NULL ((WCHAR)0) VOID NTAPI RtlInitUnicodeString( IN OUT PUNICODE_STRING DestinationString, IN PCWSTR SourceString); LONG NTAPI RtlCompareUnicodeString( IN PCUNICODE_STRING String1, IN PCUNICODE_STRING String2, IN BOOLEAN CaseInSensitive); VOID NTAPI KeBugCheckEx( IN ULONG BugCheckCode, IN ULONG_PTR BugCheckParameter1, IN ULONG_PTR BugCheckParameter2, IN ULONG_PTR BugCheckParameter3, IN ULONG_PTR BugCheckParameter4); VOID NTAPI KeQuerySystemTime( OUT PLARGE_INTEGER CurrentTime); WCHAR NTAPI RtlUpcaseUnicodeChar( IN WCHAR Source); VOID NTAPI RtlInitializeBitMap( IN PRTL_BITMAP BitMapHeader, IN PULONG BitMapBuffer, IN ULONG SizeOfBitMap); ULONG NTAPI RtlFindSetBits( IN PRTL_BITMAP BitMapHeader, IN ULONG NumberToFind, IN ULONG HintIndex); VOID NTAPI RtlSetBits( IN PRTL_BITMAP BitMapHeader, IN ULONG StartingIndex, IN ULONG NumberToSet); VOID NTAPI RtlClearAllBits( IN PRTL_BITMAP BitMapHeader); #define RtlCheckBit(BMH,BP) (((((PLONG)(BMH)->Buffer)[(BP) / 32]) >> ((BP) % 32)) & 0x1) #define UNREFERENCED_PARAMETER(P) {(P)=(P);} #define PKTHREAD PVOID #define PKGUARDED_MUTEX PVOID #define PERESOURCE PVOID #define PFILE_OBJECT PVOID #define PKEVENT PVOID #define PWORK_QUEUE_ITEM PVOID #define EX_PUSH_LOCK PULONG_PTR // Definitions copied from // We only want to include host headers, so we define them manually typedef USHORT SECURITY_DESCRIPTOR_CONTROL, *PSECURITY_DESCRIPTOR_CONTROL; typedef struct _SECURITY_DESCRIPTOR_RELATIVE { UCHAR Revision; UCHAR Sbz1; SECURITY_DESCRIPTOR_CONTROL Control; ULONG Owner; ULONG Group; ULONG Sacl; ULONG Dacl; } SECURITY_DESCRIPTOR_RELATIVE, *PISECURITY_DESCRIPTOR_RELATIVE; #define CMLTRACE(x, ...) #undef PAGED_CODE #define PAGED_CODE() #define REGISTRY_ERROR ((ULONG)0x00000051L) #else // // Debug/Tracing support // #if _CMLIB_DEBUG_ #ifdef NEW_DEBUG_SYSTEM_IMPLEMENTED // enable when Debug Filters are implemented #define CMLTRACE DbgPrintEx #else #define CMLTRACE(x, ...) \ if (x & CmlibTraceLevel) DbgPrint(__VA_ARGS__) #endif #else #define CMLTRACE(x, ...) DPRINT(__VA_ARGS__) #endif #include #include #include #undef PAGED_CODE #define PAGED_CODE() /* Prevent inclusion of Windows headers through */ #define _WINDEF_ #define _WINBASE_ #define _WINNLS_ #endif // // These define the Debug Masks Supported // #define CMLIB_HCELL_DEBUG 0x01 #ifndef ROUND_UP #define ROUND_UP(a,b) ((((a)+(b)-1)/(b))*(b)) #define ROUND_DOWN(a,b) (((a)/(b))*(b)) #endif // // PAGE_SIZE definition // #ifndef PAGE_SIZE #if defined(TARGET_i386) || defined(TARGET_amd64) || defined(TARGET_arm) #define PAGE_SIZE 0x1000 #else #error Local PAGE_SIZE definition required when built as host #endif #endif #define TAG_CM ' MC' #define TAG_KCB 'bkMC' #define TAG_CMHIVE 'vHMC' #define TAG_CMSD 'DSMC' #define CMAPI NTAPI #include #include #include "hivedata.h" #include "cmdata.h" #if defined(_TYPEDEFS_HOST_H) || defined(__FREELDR_H) // || defined(_BLDR_) #define PCM_KEY_SECURITY_CACHE_ENTRY PVOID #define PCM_KEY_CONTROL_BLOCK PVOID #define PCM_CELL_REMAP_BLOCK PVOID // See also ntoskrnl/include/internal/cm.h #define CMP_SECURITY_HASH_LISTS 64 // #endif // Commented out until one finds a way to properly include // this header in freeldr and in ntoskrnl. // // Use Count Log and Entry // typedef struct _CM_USE_COUNT_LOG_ENTRY { HCELL_INDEX Cell; PVOID Stack[7]; } CM_USE_COUNT_LOG_ENTRY, *PCM_USE_COUNT_LOG_ENTRY; typedef struct _CM_USE_COUNT_LOG { USHORT Next; USHORT Size; CM_USE_COUNT_LOG_ENTRY Log[32]; } CM_USE_COUNT_LOG, *PCM_USE_COUNT_LOG; // // Configuration Manager Hive Structure // typedef struct _CMHIVE { HHIVE Hive; HANDLE FileHandles[HFILE_TYPE_MAX]; LIST_ENTRY NotifyList; LIST_ENTRY HiveList; EX_PUSH_LOCK HiveLock; PKTHREAD HiveLockOwner; PKGUARDED_MUTEX ViewLock; PKTHREAD ViewLockOwner; EX_PUSH_LOCK WriterLock; PKTHREAD WriterLockOwner; PERESOURCE FlusherLock; EX_PUSH_LOCK SecurityLock; PKTHREAD HiveSecurityLockOwner; LIST_ENTRY LRUViewListHead; LIST_ENTRY PinViewListHead; PFILE_OBJECT FileObject; UNICODE_STRING FileFullPath; UNICODE_STRING FileUserName; USHORT MappedViews; USHORT PinnedViews; ULONG UseCount; ULONG SecurityCount; ULONG SecurityCacheSize; LONG SecurityHitHint; PCM_KEY_SECURITY_CACHE_ENTRY SecurityCache; LIST_ENTRY SecurityHash[CMP_SECURITY_HASH_LISTS]; PKEVENT UnloadEvent; PCM_KEY_CONTROL_BLOCK RootKcb; BOOLEAN Frozen; PWORK_QUEUE_ITEM UnloadWorkItem; BOOLEAN GrowOnlyMode; ULONG GrowOffset; LIST_ENTRY KcbConvertListHead; LIST_ENTRY KnodeConvertListHead; PCM_CELL_REMAP_BLOCK CellRemapArray; CM_USE_COUNT_LOG UseCountLog; CM_USE_COUNT_LOG LockHiveLog; ULONG Flags; LIST_ENTRY TrustClassEntry; ULONG FlushCount; BOOLEAN HiveIsLoading; PKTHREAD CreatorOwner; } CMHIVE, *PCMHIVE; #endif // See comment above typedef struct _HV_HIVE_CELL_PAIR { PHHIVE Hive; HCELL_INDEX Cell; } HV_HIVE_CELL_PAIR, *PHV_HIVE_CELL_PAIR; #define STATIC_CELL_PAIR_COUNT 4 typedef struct _HV_TRACK_CELL_REF { USHORT Count; USHORT Max; PHV_HIVE_CELL_PAIR CellArray; HV_HIVE_CELL_PAIR StaticArray[STATIC_CELL_PAIR_COUNT]; USHORT StaticCount; } HV_TRACK_CELL_REF, *PHV_TRACK_CELL_REF; extern ULONG CmlibTraceLevel; // // Hack since bigkeys are not yet supported // #define ASSERT_VALUE_BIG(h, s) \ ASSERTMSG("Big keys not supported!\n", !CmpIsKeyValueBig(h, s)); // // Returns whether or not this is a small valued key // static inline BOOLEAN CmpIsKeyValueSmall(OUT PULONG RealLength, IN ULONG Length) { /* Check if the length has the special size value */ if (Length >= CM_KEY_VALUE_SPECIAL_SIZE) { /* It does, so this is a small key: return the real length */ *RealLength = Length - CM_KEY_VALUE_SPECIAL_SIZE; return TRUE; } /* This is not a small key, return the length we read */ *RealLength = Length; return FALSE; } // // Returns whether or not this is a big valued key // static inline BOOLEAN CmpIsKeyValueBig(IN PHHIVE Hive, IN ULONG Length) { /* Check if the hive is XP Beta 1 or newer */ if (Hive->Version >= HSYS_WHISTLER_BETA1) { /* Check if the key length is valid for a big value key */ if ((Length < CM_KEY_VALUE_SPECIAL_SIZE) && (Length > CM_KEY_VALUE_BIG)) { /* Yes, this value is big */ return TRUE; } } /* Not a big value key */ return FALSE; } /* * Public Hive functions. */ NTSTATUS CMAPI HvInitialize( PHHIVE RegistryHive, ULONG OperationType, ULONG HiveFlags, ULONG FileType, PVOID HiveData OPTIONAL, PALLOCATE_ROUTINE Allocate, PFREE_ROUTINE Free, PFILE_SET_SIZE_ROUTINE FileSetSize, PFILE_WRITE_ROUTINE FileWrite, PFILE_READ_ROUTINE FileRead, PFILE_FLUSH_ROUTINE FileFlush, ULONG Cluster OPTIONAL, PCUNICODE_STRING FileName OPTIONAL); VOID CMAPI HvFree( PHHIVE RegistryHive); PVOID CMAPI HvGetCell( PHHIVE RegistryHive, HCELL_INDEX CellOffset); #define HvReleaseCell(h, c) \ do { \ if ((h)->ReleaseCellRoutine) \ (h)->ReleaseCellRoutine(h, c); \ } while(0) LONG CMAPI HvGetCellSize( PHHIVE RegistryHive, PVOID Cell); HCELL_INDEX CMAPI HvAllocateCell( PHHIVE RegistryHive, ULONG Size, HSTORAGE_TYPE Storage, IN HCELL_INDEX Vicinity); BOOLEAN CMAPI HvIsCellAllocated( IN PHHIVE RegistryHive, IN HCELL_INDEX CellIndex ); HCELL_INDEX CMAPI HvReallocateCell( PHHIVE RegistryHive, HCELL_INDEX CellOffset, ULONG Size); VOID CMAPI HvFreeCell( PHHIVE RegistryHive, HCELL_INDEX CellOffset); BOOLEAN CMAPI HvMarkCellDirty( PHHIVE RegistryHive, HCELL_INDEX CellOffset, BOOLEAN HoldingLock); BOOLEAN CMAPI HvIsCellDirty( IN PHHIVE Hive, IN HCELL_INDEX Cell ); BOOLEAN CMAPI HvHiveWillShrink( IN PHHIVE RegistryHive ); BOOLEAN CMAPI HvSyncHive( PHHIVE RegistryHive); BOOLEAN CMAPI HvWriteHive( PHHIVE RegistryHive); BOOLEAN CMAPI HvTrackCellRef( IN OUT PHV_TRACK_CELL_REF CellRef, IN PHHIVE Hive, IN HCELL_INDEX Cell ); VOID CMAPI HvReleaseFreeCellRefArray( IN OUT PHV_TRACK_CELL_REF CellRef ); /* * Private functions. */ PHBIN CMAPI HvpAddBin( PHHIVE RegistryHive, ULONG Size, HSTORAGE_TYPE Storage); NTSTATUS CMAPI HvpCreateHiveFreeCellList( PHHIVE Hive); ULONG CMAPI HvpHiveHeaderChecksum( PHBASE_BLOCK HiveHeader); /* Old-style Public "Cmlib" functions */ BOOLEAN CMAPI CmCreateRootNode( PHHIVE Hive, PCWSTR Name); VOID CMAPI CmPrepareHive( PHHIVE RegistryHive); /* NT-style Public Cm functions */ // // Cell Index Routines // HCELL_INDEX NTAPI CmpFindSubKeyByName( IN PHHIVE Hive, IN PCM_KEY_NODE Parent, IN PCUNICODE_STRING SearchName ); HCELL_INDEX NTAPI CmpFindSubKeyByNumber( IN PHHIVE Hive, IN PCM_KEY_NODE Node, IN ULONG Number ); ULONG NTAPI CmpComputeHashKey( IN ULONG Hash, IN PCUNICODE_STRING Name, IN BOOLEAN AllowSeparators ); BOOLEAN NTAPI CmpAddSubKey( IN PHHIVE Hive, IN HCELL_INDEX Parent, IN HCELL_INDEX Child ); BOOLEAN NTAPI CmpRemoveSubKey( IN PHHIVE Hive, IN HCELL_INDEX ParentKey, IN HCELL_INDEX TargetKey ); BOOLEAN NTAPI CmpMarkIndexDirty( IN PHHIVE Hive, HCELL_INDEX ParentKey, HCELL_INDEX TargetKey ); // // Name Functions // LONG NTAPI CmpCompareCompressedName( IN PCUNICODE_STRING SearchName, IN PWCHAR CompressedName, IN ULONG NameLength ); USHORT NTAPI CmpNameSize( IN PHHIVE Hive, IN PUNICODE_STRING Name ); USHORT NTAPI CmpCompressedNameSize( IN PWCHAR Name, IN ULONG Length ); USHORT NTAPI CmpCopyName( IN PHHIVE Hive, OUT PWCHAR Destination, IN PUNICODE_STRING Source ); VOID NTAPI CmpCopyCompressedName( OUT PWCHAR Destination, IN ULONG DestinationLength, IN PWCHAR Source, IN ULONG SourceLength ); BOOLEAN NTAPI CmpFindNameInList( IN PHHIVE Hive, IN PCHILD_LIST ChildList, IN PUNICODE_STRING Name, OUT PULONG ChildIndex OPTIONAL, OUT PHCELL_INDEX CellIndex ); // // Cell Value Routines // HCELL_INDEX NTAPI CmpFindValueByName( IN PHHIVE Hive, IN PCM_KEY_NODE KeyNode, IN PUNICODE_STRING Name ); PCELL_DATA NTAPI CmpValueToData( IN PHHIVE Hive, IN PCM_KEY_VALUE Value, OUT PULONG Length ); NTSTATUS NTAPI CmpSetValueDataNew( IN PHHIVE Hive, IN PVOID Data, IN ULONG DataSize, IN HSTORAGE_TYPE StorageType, IN HCELL_INDEX ValueCell, OUT PHCELL_INDEX DataCell ); NTSTATUS NTAPI CmpAddValueToList( IN PHHIVE Hive, IN HCELL_INDEX ValueCell, IN ULONG Index, IN HSTORAGE_TYPE StorageType, IN OUT PCHILD_LIST ChildList ); BOOLEAN NTAPI CmpFreeValue( IN PHHIVE Hive, IN HCELL_INDEX Cell ); BOOLEAN NTAPI CmpMarkValueDataDirty( IN PHHIVE Hive, IN PCM_KEY_VALUE Value ); BOOLEAN NTAPI CmpFreeValueData( IN PHHIVE Hive, IN HCELL_INDEX DataCell, IN ULONG DataLength ); NTSTATUS NTAPI CmpRemoveValueFromList( IN PHHIVE Hive, IN ULONG Index, IN OUT PCHILD_LIST ChildList ); BOOLEAN NTAPI CmpGetValueData( IN PHHIVE Hive, IN PCM_KEY_VALUE Value, OUT PULONG Length, OUT PVOID *Buffer, OUT PBOOLEAN BufferAllocated, OUT PHCELL_INDEX CellToRelease ); NTSTATUS NTAPI CmpCopyKeyValueList( IN PHHIVE SourceHive, IN PCHILD_LIST SrcValueList, IN PHHIVE DestinationHive, IN OUT PCHILD_LIST DestValueList, IN HSTORAGE_TYPE StorageType ); NTSTATUS NTAPI CmpFreeKeyByCell( IN PHHIVE Hive, IN HCELL_INDEX Cell, IN BOOLEAN Unlink ); VOID NTAPI CmpRemoveSecurityCellList( IN PHHIVE Hive, IN HCELL_INDEX SecurityCell ); VOID NTAPI CmpFreeSecurityDescriptor( IN PHHIVE Hive, IN HCELL_INDEX Cell ); /******************************************************************************/ /* To be implemented by the user of this library */ PVOID NTAPI CmpAllocate( IN SIZE_T Size, IN BOOLEAN Paged, IN ULONG Tag ); VOID NTAPI CmpFree( IN PVOID Ptr, IN ULONG Quota ); #endif /* _CMLIB_H_ */