2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Configuration Manager Library - CMLIB header
5 * COPYRIGHT: Copyright 2001 - 2005 Eric Kohl
6 * Copyright 2022 George Bișoc <george.bisoc@reactos.org>
13 // Debug support switch
15 #define _CMLIB_DEBUG_ 1
22 // NTDDI_xxx versions we allude to in the library (see psdk/sdkddkver.h)
23 #define NTDDI_WS03SP4 0x05020400
24 #define NTDDI_WIN6 0x06000000
25 #define NTDDI_LONGHORN NTDDI_WIN6
26 #define NTDDI_VISTA NTDDI_WIN6
27 #define NTDDI_WIN7 0x06010000
29 #define NTDDI_VERSION NTDDI_WS03SP4 // This is the ReactOS NT kernel version
31 /* C_ASSERT Definition */
32 #define C_ASSERT(expr) extern char (*c_assert(void)) [(expr) ? 1 : -1]
35 #define strncasecmp _strnicmp
36 #define strcasecmp _stricmp
39 #if (!defined(_MSC_VER) || (_MSC_VER < 1500))
44 #define _In_range_(x, y)
47 #define __drv_aliasesMem
50 #define min(a, b) (((a) < (b)) ? (a) : (b))
54 // #define max(a, b) (((a) > (b)) ? (a) : (b))
57 // Definitions copied from <ntstatus.h>
58 // We only want to include host headers, so we define them manually
59 #define STATUS_SUCCESS ((NTSTATUS)0x00000000)
60 #define STATUS_NOT_IMPLEMENTED ((NTSTATUS)0xC0000002)
61 #define STATUS_NO_MEMORY ((NTSTATUS)0xC0000017)
62 #define STATUS_INSUFFICIENT_RESOURCES ((NTSTATUS)0xC000009A)
63 #define STATUS_INVALID_PARAMETER ((NTSTATUS)0xC000000D)
64 #define STATUS_REGISTRY_CORRUPT ((NTSTATUS)0xC000014C)
65 #define STATUS_REGISTRY_IO_FAILED ((NTSTATUS)0xC000014D)
66 #define STATUS_NOT_REGISTRY_FILE ((NTSTATUS)0xC000015C)
67 #define STATUS_REGISTRY_RECOVERED ((NTSTATUS)0x40000009)
69 #define REG_OPTION_VOLATILE 1
70 #define OBJ_CASE_INSENSITIVE 0x00000040L
71 #define USHORT_MAX USHRT_MAX
73 #define OBJ_NAME_PATH_SEPARATOR ((WCHAR)L'\\')
74 #define UNICODE_NULL ((WCHAR)0)
78 IN OUT PUNICODE_STRING DestinationString
,
79 IN PCWSTR SourceString
);
82 RtlCompareUnicodeString(
83 IN PCUNICODE_STRING String1
,
84 IN PCUNICODE_STRING String2
,
85 IN BOOLEAN CaseInSensitive
);
87 // FIXME: DECLSPEC_NORETURN
91 IN ULONG BugCheckCode
,
92 IN ULONG_PTR BugCheckParameter1
,
93 IN ULONG_PTR BugCheckParameter2
,
94 IN ULONG_PTR BugCheckParameter3
,
95 IN ULONG_PTR BugCheckParameter4
);
99 OUT PLARGE_INTEGER CurrentTime
);
102 RtlUpcaseUnicodeChar(
107 IN PRTL_BITMAP BitMapHeader
,
108 IN PULONG BitMapBuffer
,
109 IN ULONG SizeOfBitMap
);
113 IN PRTL_BITMAP BitMapHeader
,
114 IN ULONG NumberToFind
,
119 IN PRTL_BITMAP BitMapHeader
,
120 IN ULONG StartingIndex
,
121 IN ULONG NumberToSet
);
125 IN PRTL_BITMAP BitMapHeader
);
129 IN PRTL_BITMAP BitMapHeader
);
131 #define RtlCheckBit(BMH,BP) (((((PLONG)(BMH)->Buffer)[(BP) / 32]) >> ((BP) % 32)) & 0x1)
132 #define UNREFERENCED_PARAMETER(P) ((void)(P))
134 #define PKTHREAD PVOID
135 #define PKGUARDED_MUTEX PVOID
136 #define PERESOURCE PVOID
137 #define PFILE_OBJECT PVOID
138 #define PKEVENT PVOID
139 #define PWORK_QUEUE_ITEM PVOID
140 #define EX_PUSH_LOCK PULONG_PTR
142 // Definitions copied from <ntifs.h>
143 // We only want to include host headers, so we define them manually
145 typedef USHORT SECURITY_DESCRIPTOR_CONTROL
, *PSECURITY_DESCRIPTOR_CONTROL
;
147 typedef struct _SECURITY_DESCRIPTOR_RELATIVE
151 SECURITY_DESCRIPTOR_CONTROL Control
;
156 } SECURITY_DESCRIPTOR_RELATIVE
, *PISECURITY_DESCRIPTOR_RELATIVE
;
158 #define CMLTRACE(x, ...)
161 #define REGISTRY_ERROR ((ULONG)0x00000051L)
166 // Debug/Tracing support
169 #ifdef NEW_DEBUG_SYSTEM_IMPLEMENTED // enable when Debug Filters are implemented
170 #define CMLTRACE DbgPrintEx
172 #define CMLTRACE(x, ...) \
173 if (x & CmlibTraceLevel) DbgPrint(__VA_ARGS__)
176 #define CMLTRACE(x, ...) DPRINT(__VA_ARGS__)
181 #include <bugcodes.h>
183 /* Prevent inclusion of Windows headers through <wine/unicode.h> */
191 // These define the Debug Masks Supported
193 #define CMLIB_HCELL_DEBUG 0x01
196 #define ROUND_UP(a,b) ((((a)+(b)-1)/(b))*(b))
197 #define ROUND_DOWN(a,b) (((a)/(b))*(b))
201 // PAGE_SIZE definition
204 #if defined(TARGET_i386) || defined(TARGET_amd64) || \
205 defined(TARGET_arm) || defined(TARGET_arm64)
206 #define PAGE_SIZE 0x1000
208 #error Local PAGE_SIZE definition required when built as host
213 #define TAG_KCB 'bkMC'
214 #define TAG_CMHIVE 'vHMC'
215 #define TAG_CMSD 'DSMC'
216 #define TAG_REGISTRY_STACK 'sRMC'
221 // Check Registry status type definition
223 typedef ULONG CM_CHECK_REGISTRY_STATUS
;
226 // Check Registry flags
228 #define CM_CHECK_REGISTRY_DONT_PURGE_VOLATILES 0x0
229 #define CM_CHECK_REGISTRY_PURGE_VOLATILES 0x2
230 #define CM_CHECK_REGISTRY_BOOTLOADER_PURGE_VOLATILES 0x4
231 #define CM_CHECK_REGISTRY_VALIDATE_HIVE 0x8
232 #define CM_CHECK_REGISTRY_FIX_HIVE 0x10
235 // Check Registry status codes
237 #define CM_CHECK_REGISTRY_GOOD 0
238 #define CM_CHECK_REGISTRY_INVALID_PARAMETER 1
239 #define CM_CHECK_REGISTRY_SD_INVALID 2
240 #define CM_CHECK_REGISTRY_HIVE_CORRUPT_SIGNATURE 3
241 #define CM_CHECK_REGISTRY_BIN_SIZE_OR_OFFSET_CORRUPT 4
242 #define CM_CHECK_REGISTRY_BIN_SIGNATURE_HEADER_CORRUPT 5
243 #define CM_CHECK_REGISTRY_BAD_FREE_CELL 6
244 #define CM_CHECK_REGISTRY_BAD_ALLOC_CELL 7
245 #define CM_CHECK_REGISTRY_ALLOCATE_MEM_STACK_FAIL 8
246 #define CM_CHECK_REGISTRY_ROOT_CELL_NOT_FOUND 9
247 #define CM_CHECK_REGISTRY_BAD_LEXICOGRAPHICAL_ORDER 10
248 #define CM_CHECK_REGISTRY_NODE_NOT_FOUND 11
249 #define CM_CHECK_REGISTRY_SUBKEY_NOT_FOUND 12
250 #define CM_CHECK_REGISTRY_TREE_TOO_MANY_LEVELS 13
251 #define CM_CHECK_REGISTRY_KEY_CELL_NOT_ALLOCATED 14
252 #define CM_CHECK_REGISTRY_CELL_DATA_NOT_FOUND 15
253 #define CM_CHECK_REGISTRY_CELL_SIZE_NOT_SANE 16
254 #define CM_CHECK_REGISTRY_KEY_NAME_LENGTH_ZERO 17
255 #define CM_CHECK_REGISTRY_KEY_TOO_BIG_THAN_CELL 18
256 #define CM_CHECK_REGISTRY_BAD_KEY_NODE_PARENT 19
257 #define CM_CHECK_REGISTRY_BAD_KEY_NODE_SIGNATURE 20
258 #define CM_CHECK_REGISTRY_KEY_CLASS_UNALLOCATED 21
259 #define CM_CHECK_REGISTRY_VALUE_LIST_UNALLOCATED 22
260 #define CM_CHECK_REGISTRY_VALUE_LIST_DATA_NOT_FOUND 23
261 #define CM_CHECK_REGISTRY_VALUE_LIST_SIZE_NOT_SANE 24
262 #define CM_CHECK_REGISTRY_VALUE_CELL_NIL 25
263 #define CM_CHECK_REGISTRY_VALUE_CELL_UNALLOCATED 26
264 #define CM_CHECK_REGISTRY_VALUE_CELL_DATA_NOT_FOUND 27
265 #define CM_CHECK_REGISTRY_VALUE_CELL_SIZE_NOT_SANE 28
266 #define CM_CHECK_REGISTRY_CORRUPT_VALUE_DATA 29
267 #define CM_CHECK_REGISTRY_DATA_CELL_NOT_ALLOCATED 30
268 #define CM_CHECK_REGISTRY_BAD_KEY_VALUE_SIGNATURE 31
269 #define CM_CHECK_REGISTRY_STABLE_KEYS_ON_VOLATILE 32
270 #define CM_CHECK_REGISTRY_SUBKEYS_LIST_UNALLOCATED 33
271 #define CM_CHECK_REGISTRY_CORRUPT_SUBKEYS_INDEX 34
272 #define CM_CHECK_REGISTRY_BAD_SUBKEY_COUNT 35
273 #define CM_CHECK_REGISTRY_KEY_INDEX_CELL_UNALLOCATED 36
274 #define CM_CHECK_REGISTRY_CORRUPT_LEAF_ON_ROOT 37
275 #define CM_CHECK_REGISTRY_CORRUPT_LEAF_SIGNATURE 38
276 #define CM_CHECK_REGISTRY_CORRUPT_KEY_INDEX_SIGNATURE 39
279 // Check Registry success macro
281 #define CM_CHECK_REGISTRY_SUCCESS(StatusCode) ((ULONG)(StatusCode) == CM_CHECK_REGISTRY_GOOD)
283 #include <wine/unicode.h>
285 #include "hivedata.h"
288 /* Forward declarations */
289 typedef struct _CM_KEY_SECURITY_CACHE_ENTRY
*PCM_KEY_SECURITY_CACHE_ENTRY
;
290 typedef struct _CM_KEY_CONTROL_BLOCK
*PCM_KEY_CONTROL_BLOCK
;
291 typedef struct _CM_CELL_REMAP_BLOCK
*PCM_CELL_REMAP_BLOCK
;
293 // See ntoskrnl/include/internal/cm.h
294 #define CMP_SECURITY_HASH_LISTS 64
297 // Use Count Log and Entry
299 typedef struct _CM_USE_COUNT_LOG_ENTRY
303 } CM_USE_COUNT_LOG_ENTRY
, *PCM_USE_COUNT_LOG_ENTRY
;
305 typedef struct _CM_USE_COUNT_LOG
309 CM_USE_COUNT_LOG_ENTRY Log
[32];
310 } CM_USE_COUNT_LOG
, *PCM_USE_COUNT_LOG
;
313 // Configuration Manager Hive Structure
315 typedef struct _CMHIVE
318 HANDLE FileHandles
[HFILE_TYPE_MAX
];
319 LIST_ENTRY NotifyList
;
321 EX_PUSH_LOCK HiveLock
;
322 PKTHREAD HiveLockOwner
;
323 PKGUARDED_MUTEX ViewLock
;
324 PKTHREAD ViewLockOwner
;
325 EX_PUSH_LOCK WriterLock
;
326 PKTHREAD WriterLockOwner
;
327 PERESOURCE FlusherLock
;
328 EX_PUSH_LOCK SecurityLock
;
329 PKTHREAD HiveSecurityLockOwner
;
330 LIST_ENTRY LRUViewListHead
;
331 LIST_ENTRY PinViewListHead
;
332 PFILE_OBJECT FileObject
;
333 UNICODE_STRING FileFullPath
;
334 UNICODE_STRING FileUserName
;
339 ULONG SecurityCacheSize
;
340 LONG SecurityHitHint
;
341 PCM_KEY_SECURITY_CACHE_ENTRY SecurityCache
;
342 LIST_ENTRY SecurityHash
[CMP_SECURITY_HASH_LISTS
];
344 PCM_KEY_CONTROL_BLOCK RootKcb
;
346 PWORK_QUEUE_ITEM UnloadWorkItem
;
347 BOOLEAN GrowOnlyMode
;
349 LIST_ENTRY KcbConvertListHead
;
350 LIST_ENTRY KnodeConvertListHead
;
351 PCM_CELL_REMAP_BLOCK CellRemapArray
;
352 CM_USE_COUNT_LOG UseCountLog
;
353 CM_USE_COUNT_LOG LockHiveLog
;
355 LIST_ENTRY TrustClassEntry
;
357 BOOLEAN HiveIsLoading
;
358 PKTHREAD CreatorOwner
;
361 typedef struct _HV_HIVE_CELL_PAIR
365 } HV_HIVE_CELL_PAIR
, *PHV_HIVE_CELL_PAIR
;
367 #define STATIC_CELL_PAIR_COUNT 4
368 typedef struct _HV_TRACK_CELL_REF
372 PHV_HIVE_CELL_PAIR CellArray
;
373 HV_HIVE_CELL_PAIR StaticArray
[STATIC_CELL_PAIR_COUNT
];
375 } HV_TRACK_CELL_REF
, *PHV_TRACK_CELL_REF
;
377 extern ULONG CmlibTraceLevel
;
380 // Hack since big keys are not yet supported
383 #define ASSERT_VALUE_BIG(h, s) \
384 do { if (CmpIsKeyValueBig(h,s)) DbgPrint("Big keys aren't supported!\n"); } while (0)
386 #define ASSERT_VALUE_BIG(h, s) \
387 ASSERTMSG("Big keys not supported!\n", !CmpIsKeyValueBig(h, s));
391 // Returns whether or not this is a small valued key
395 CmpIsKeyValueSmall(OUT PULONG RealLength
,
398 /* Check if the length has the special size value */
399 if (Length
>= CM_KEY_VALUE_SPECIAL_SIZE
)
401 /* It does, so this is a small key: return the real length */
402 *RealLength
= Length
- CM_KEY_VALUE_SPECIAL_SIZE
;
406 /* This is not a small key, return the length we read */
407 *RealLength
= Length
;
412 // Returns whether or not this is a big valued key
416 CmpIsKeyValueBig(IN PHHIVE Hive
,
419 /* Check if the hive is XP Beta 1 or newer */
420 if (Hive
->Version
>= HSYS_WHISTLER_BETA1
)
422 /* Check if the key length is valid for a big value key */
423 if ((Length
< CM_KEY_VALUE_SPECIAL_SIZE
) && (Length
> CM_KEY_VALUE_BIG
))
425 /* Yes, this value is big */
430 /* Not a big value key */
435 * Public Hive functions.
443 PVOID HiveData OPTIONAL
,
444 PALLOCATE_ROUTINE Allocate
,
446 PFILE_SET_SIZE_ROUTINE FileSetSize
,
447 PFILE_WRITE_ROUTINE FileWrite
,
448 PFILE_READ_ROUTINE FileRead
,
449 PFILE_FLUSH_ROUTINE FileFlush
,
450 ULONG Cluster OPTIONAL
,
451 PCUNICODE_STRING FileName OPTIONAL
);
455 PHHIVE RegistryHive
);
457 #define HvGetCell(Hive, Cell) \
458 (Hive)->GetCellRoutine(Hive, Cell)
460 #define HvReleaseCell(Hive, Cell) \
462 if ((Hive)->ReleaseCellRoutine) \
463 (Hive)->ReleaseCellRoutine(Hive, Cell); \
475 HSTORAGE_TYPE Storage
,
476 IN HCELL_INDEX Vicinity
);
480 IN PHHIVE RegistryHive
,
481 IN HCELL_INDEX CellIndex
487 HCELL_INDEX CellOffset
,
493 HCELL_INDEX CellOffset
);
498 HCELL_INDEX CellOffset
,
499 BOOLEAN HoldingLock
);
510 IN PHHIVE RegistryHive
515 PHHIVE RegistryHive
);
519 PHHIVE RegistryHive
);
523 HvWriteAlternateHive(
524 _In_ PHHIVE RegistryHive
);
528 HvSyncHiveFromRecover(
529 _In_ PHHIVE RegistryHive
);
534 IN OUT PHV_TRACK_CELL_REF CellRef
,
541 HvReleaseFreeCellRefArray(
542 IN OUT PHV_TRACK_CELL_REF CellRef
552 _In_ HCELL_INDEX CellIndex
);
558 HSTORAGE_TYPE Storage
);
561 HvpCreateHiveFreeCellList(
565 HvpHiveHeaderChecksum(
566 PHBASE_BLOCK HiveHeader
);
570 _In_ PHBASE_BLOCK BaseBlock
,
571 _In_ ULONG FileType
);
574 // Registry Self-Heal Routines
579 _In_ BOOLEAN FixHive
);
585 _In_ HCELL_INDEX TargetKey
,
586 _In_ HCELL_INDEX ParentKey
,
587 _In_ BOOLEAN FixHive
);
593 _In_ HCELL_INDEX DirtyCell
,
594 _In_ HCELL_INDEX ParentCell
,
595 _Inout_ PCELL_DATA CellData
,
596 _In_ BOOLEAN FixHive
);
600 CmpRepairKeyNodeSignature(
602 _In_ HCELL_INDEX DirtyCell
,
603 _Inout_ PCELL_DATA CellData
,
604 _In_ BOOLEAN FixHive
);
608 CmpRepairClassOfNodeKey(
610 _In_ HCELL_INDEX DirtyCell
,
611 _Inout_ PCELL_DATA CellData
,
612 _In_ BOOLEAN FixHive
);
618 _In_ HCELL_INDEX CurrentCell
,
619 _In_ BOOLEAN FixHive
);
623 CmpRepairValueListCount(
625 _In_ HCELL_INDEX CurrentCell
,
626 _In_ ULONG ListCountIndex
,
627 _Inout_ PCELL_DATA ValueListData
,
628 _In_ BOOLEAN FixHive
);
632 CmpRepairSubKeyCounts(
634 _In_ HCELL_INDEX CurrentCell
,
636 _Inout_ PCELL_DATA CellData
,
637 _In_ BOOLEAN FixHive
);
643 _In_ HCELL_INDEX CurrentCell
,
644 _Inout_ PCELL_DATA CellData
,
645 _In_ BOOLEAN FixHive
);
647 /* Old-style Public "Cmlib" functions */
654 /* NT-style Public Cm functions */
657 // Check Registry Routines
659 CM_CHECK_REGISTRY_STATUS
665 CM_CHECK_REGISTRY_STATUS
670 CM_CHECK_REGISTRY_STATUS
673 _In_ PCMHIVE RegistryHive
,
677 // Cell Index Routines
683 IN PCM_KEY_NODE Parent
,
684 IN PCUNICODE_STRING SearchName
689 CmpFindSubKeyByNumber(
691 IN PCM_KEY_NODE Node
,
699 IN PCUNICODE_STRING Name
,
700 IN BOOLEAN AllowSeparators
707 IN HCELL_INDEX Parent
,
715 IN HCELL_INDEX ParentKey
,
716 IN HCELL_INDEX TargetKey
723 HCELL_INDEX ParentKey
,
724 HCELL_INDEX TargetKey
733 CmpCompareCompressedName(
734 IN PCUNICODE_STRING SearchName
,
735 IN PWCHAR CompressedName
,
743 IN PCUNICODE_STRING Name
748 CmpCompressedNameSize(
757 OUT PWCHAR Destination
,
758 IN PCUNICODE_STRING Source
763 CmpCopyCompressedName(
764 OUT PWCHAR Destination
,
765 IN ULONG DestinationLength
,
767 IN ULONG SourceLength
774 IN PCHILD_LIST ChildList
,
775 IN PCUNICODE_STRING Name
,
776 OUT PULONG ChildIndex OPTIONAL
,
777 OUT PHCELL_INDEX CellIndex
782 // Cell Value Routines
788 IN PCM_KEY_NODE KeyNode
,
789 IN PCUNICODE_STRING Name
796 IN PCM_KEY_VALUE Value
,
806 IN HSTORAGE_TYPE StorageType
,
807 IN HCELL_INDEX ValueCell
,
808 OUT PHCELL_INDEX DataCell
815 IN HCELL_INDEX ValueCell
,
817 IN HSTORAGE_TYPE StorageType
,
818 IN OUT PCHILD_LIST ChildList
830 CmpMarkValueDataDirty(
832 IN PCM_KEY_VALUE Value
839 IN HCELL_INDEX DataCell
,
845 CmpRemoveValueFromList(
848 IN OUT PCHILD_LIST ChildList
855 IN PCM_KEY_VALUE Value
,
858 OUT PBOOLEAN BufferAllocated
,
859 OUT PHCELL_INDEX CellToRelease
865 IN PHHIVE SourceHive
,
866 IN PCHILD_LIST SrcValueList
,
867 IN PHHIVE DestinationHive
,
868 IN OUT PCHILD_LIST DestValueList
,
869 IN HSTORAGE_TYPE StorageType
882 CmpRemoveSecurityCellList(
884 IN HCELL_INDEX SecurityCell
889 CmpFreeSecurityDescriptor(
894 /******************************************************************************/
896 /* To be implemented by the user of this library */
912 #endif /* _CMLIB_H_ */