xref: /reactos/sdk/lib/cmlib/cmlib.h (revision ad9c634e)
1 /*
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>
7  */
8 
9 #ifndef _CMLIB_H_
10 #define _CMLIB_H_
11 
12 //
13 // Debug support switch
14 //
15 #define _CMLIB_DEBUG_ 1
16 
17 #ifdef CMLIB_HOST
18     #include <typedefs.h>
19     #include <stdio.h>
20     #include <string.h>
21 
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
28 
29     #define NTDDI_VERSION   NTDDI_WS03SP4 // This is the ReactOS NT kernel version
30 
31     /* C_ASSERT Definition */
32     #define C_ASSERT(expr) extern char (*c_assert(void)) [(expr) ? 1 : -1]
33 
34     #ifdef _WIN32
35     #define strncasecmp _strnicmp
36     #define strcasecmp _stricmp
37     #endif // _WIN32
38 
39     #if (!defined(_MSC_VER) || (_MSC_VER < 1500))
40     #define _In_
41     #define _Out_
42     #define _Inout_
43     #define _In_opt_
44     #define _In_range_(x, y)
45     #endif
46 
47     #define __drv_aliasesMem
48 
49     #ifndef min
50     #define min(a, b)  (((a) < (b)) ? (a) : (b))
51     #endif
52 
53     // #ifndef max
54     // #define max(a, b)  (((a) > (b)) ? (a) : (b))
55     // #endif
56 
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)
68 
69     #define REG_OPTION_VOLATILE              1
70     #define OBJ_CASE_INSENSITIVE             0x00000040L
71     #define USHORT_MAX                       USHRT_MAX
72 
73     #define OBJ_NAME_PATH_SEPARATOR          ((WCHAR)L'\\')
74     #define UNICODE_NULL                     ((WCHAR)0)
75 
76     VOID NTAPI
77     RtlInitUnicodeString(
78         IN OUT PUNICODE_STRING DestinationString,
79         IN PCWSTR SourceString);
80 
81     LONG NTAPI
82     RtlCompareUnicodeString(
83         IN PCUNICODE_STRING String1,
84         IN PCUNICODE_STRING String2,
85         IN BOOLEAN CaseInSensitive);
86 
87     // FIXME: DECLSPEC_NORETURN
88     VOID
89     NTAPI
90     KeBugCheckEx(
91         IN ULONG BugCheckCode,
92         IN ULONG_PTR BugCheckParameter1,
93         IN ULONG_PTR BugCheckParameter2,
94         IN ULONG_PTR BugCheckParameter3,
95         IN ULONG_PTR BugCheckParameter4);
96 
97     VOID NTAPI
98     KeQuerySystemTime(
99         OUT PLARGE_INTEGER CurrentTime);
100 
101     WCHAR NTAPI
102     RtlUpcaseUnicodeChar(
103         IN WCHAR Source);
104 
105     VOID NTAPI
106     RtlInitializeBitMap(
107         IN PRTL_BITMAP BitMapHeader,
108         IN PULONG BitMapBuffer,
109         IN ULONG SizeOfBitMap);
110 
111     ULONG NTAPI
112     RtlFindSetBits(
113         IN PRTL_BITMAP BitMapHeader,
114         IN ULONG NumberToFind,
115         IN ULONG HintIndex);
116 
117     VOID NTAPI
118     RtlSetBits(
119         IN PRTL_BITMAP BitMapHeader,
120         IN ULONG StartingIndex,
121         IN ULONG NumberToSet);
122 
123     VOID NTAPI
124     RtlSetAllBits(
125         IN PRTL_BITMAP BitMapHeader);
126 
127     VOID NTAPI
128     RtlClearAllBits(
129         IN PRTL_BITMAP BitMapHeader);
130 
131     #define RtlCheckBit(BMH,BP) (((((PLONG)(BMH)->Buffer)[(BP) / 32]) >> ((BP) % 32)) & 0x1)
132     #define UNREFERENCED_PARAMETER(P) ((void)(P))
133 
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
141 
142     // Definitions copied from <ntifs.h>
143     // We only want to include host headers, so we define them manually
144 
145     typedef USHORT SECURITY_DESCRIPTOR_CONTROL, *PSECURITY_DESCRIPTOR_CONTROL;
146 
147     typedef struct _SECURITY_DESCRIPTOR_RELATIVE
148     {
149         UCHAR Revision;
150         UCHAR Sbz1;
151         SECURITY_DESCRIPTOR_CONTROL Control;
152         ULONG Owner;
153         ULONG Group;
154         ULONG Sacl;
155         ULONG Dacl;
156     } SECURITY_DESCRIPTOR_RELATIVE, *PISECURITY_DESCRIPTOR_RELATIVE;
157 
158     #define CMLTRACE(x, ...)
159     #undef PAGED_CODE
160     #define PAGED_CODE()
161     #define REGISTRY_ERROR                   ((ULONG)0x00000051L)
162 
163 #else
164 
165     //
166     // Debug/Tracing support
167     //
168     #if _CMLIB_DEBUG_
169     #ifdef NEW_DEBUG_SYSTEM_IMPLEMENTED // enable when Debug Filters are implemented
170     #define CMLTRACE DbgPrintEx
171     #else
172     #define CMLTRACE(x, ...)                                 \
173     if (x & CmlibTraceLevel) DbgPrint(__VA_ARGS__)
174     #endif
175     #else
176     #define CMLTRACE(x, ...) DPRINT(__VA_ARGS__)
177     #endif
178 
179     #include <ntdef.h>
180     #include <ntifs.h>
181     #include <bugcodes.h>
182 
183     /* Prevent inclusion of Windows headers through <wine/unicode.h> */
184     #define _WINDEF_
185     #define _WINBASE_
186     #define _WINNLS_
187 #endif
188 
189 
190 //
191 // These define the Debug Masks Supported
192 //
193 #define CMLIB_HCELL_DEBUG       0x01
194 
195 #ifndef ROUND_UP
196 #define ROUND_UP(a,b)        ((((a)+(b)-1)/(b))*(b))
197 #define ROUND_DOWN(a,b)      (((a)/(b))*(b))
198 #endif
199 
200 //
201 // PAGE_SIZE definition
202 //
203 #ifndef PAGE_SIZE
204 #if defined(TARGET_i386) || defined(TARGET_amd64) || \
205     defined(TARGET_arm)  || defined(TARGET_arm64)
206 #define PAGE_SIZE 0x1000
207 #else
208 #error Local PAGE_SIZE definition required when built as host
209 #endif
210 #endif
211 
212 #define TAG_CM             '  MC'
213 #define TAG_KCB            'bkMC'
214 #define TAG_CMHIVE         'vHMC'
215 #define TAG_CMSD           'DSMC'
216 #define TAG_REGISTRY_STACK 'sRMC'
217 
218 #define CMAPI NTAPI
219 
220 //
221 // Check Registry status type definition
222 //
223 typedef ULONG CM_CHECK_REGISTRY_STATUS;
224 
225 //
226 // Check Registry flags
227 //
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
233 
234 //
235 // Check Registry status codes
236 //
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
277 
278 //
279 // Check Registry success macro
280 //
281 #define CM_CHECK_REGISTRY_SUCCESS(StatusCode) ((ULONG)(StatusCode) == CM_CHECK_REGISTRY_GOOD)
282 
283 #include <wine/unicode.h>
284 #include <wchar.h>
285 #include "hivedata.h"
286 #include "cmdata.h"
287 
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;
292 
293 // See ntoskrnl/include/internal/cm.h
294 #define CMP_SECURITY_HASH_LISTS     64
295 
296 //
297 // Use Count Log and Entry
298 //
299 typedef struct _CM_USE_COUNT_LOG_ENTRY
300 {
301     HCELL_INDEX Cell;
302     PVOID Stack[7];
303 } CM_USE_COUNT_LOG_ENTRY, *PCM_USE_COUNT_LOG_ENTRY;
304 
305 typedef struct _CM_USE_COUNT_LOG
306 {
307     USHORT Next;
308     USHORT Size;
309     CM_USE_COUNT_LOG_ENTRY Log[32];
310 } CM_USE_COUNT_LOG, *PCM_USE_COUNT_LOG;
311 
312 //
313 // Configuration Manager Hive Structure
314 //
315 typedef struct _CMHIVE
316 {
317     HHIVE Hive;
318     HANDLE FileHandles[HFILE_TYPE_MAX];
319     LIST_ENTRY NotifyList;
320     LIST_ENTRY HiveList;
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;
335     USHORT MappedViews;
336     USHORT PinnedViews;
337     ULONG UseCount;
338     ULONG SecurityCount;
339     ULONG SecurityCacheSize;
340     LONG SecurityHitHint;
341     PCM_KEY_SECURITY_CACHE_ENTRY SecurityCache;
342     LIST_ENTRY SecurityHash[CMP_SECURITY_HASH_LISTS];
343     PKEVENT UnloadEvent;
344     PCM_KEY_CONTROL_BLOCK RootKcb;
345     BOOLEAN Frozen;
346     PWORK_QUEUE_ITEM UnloadWorkItem;
347     BOOLEAN GrowOnlyMode;
348     ULONG GrowOffset;
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;
354     ULONG Flags;
355     LIST_ENTRY TrustClassEntry;
356     ULONG FlushCount;
357     BOOLEAN HiveIsLoading;
358     PKTHREAD CreatorOwner;
359 } CMHIVE, *PCMHIVE;
360 
361 typedef struct _HV_HIVE_CELL_PAIR
362 {
363     PHHIVE Hive;
364     HCELL_INDEX Cell;
365 } HV_HIVE_CELL_PAIR, *PHV_HIVE_CELL_PAIR;
366 
367 #define STATIC_CELL_PAIR_COUNT 4
368 typedef struct _HV_TRACK_CELL_REF
369 {
370     USHORT Count;
371     USHORT Max;
372     PHV_HIVE_CELL_PAIR CellArray;
373     HV_HIVE_CELL_PAIR StaticArray[STATIC_CELL_PAIR_COUNT];
374     USHORT StaticCount;
375 } HV_TRACK_CELL_REF, *PHV_TRACK_CELL_REF;
376 
377 extern ULONG CmlibTraceLevel;
378 
379 //
380 // Hack since big keys are not yet supported
381 //
382 #ifdef _BLDR_
383 #define ASSERT_VALUE_BIG(h, s) \
384     do { if (CmpIsKeyValueBig(h,s)) DbgPrint("Big keys aren't supported!\n"); } while (0)
385 #else
386 #define ASSERT_VALUE_BIG(h, s)  \
387     ASSERTMSG("Big keys not supported!\n", !CmpIsKeyValueBig(h, s));
388 #endif
389 
390 //
391 // Returns whether or not this is a small valued key
392 //
393 static inline
394 BOOLEAN
CmpIsKeyValueSmall(OUT PULONG RealLength,IN ULONG Length)395 CmpIsKeyValueSmall(OUT PULONG RealLength,
396                    IN ULONG Length)
397 {
398     /* Check if the length has the special size value */
399     if (Length >= CM_KEY_VALUE_SPECIAL_SIZE)
400     {
401         /* It does, so this is a small key: return the real length */
402         *RealLength = Length - CM_KEY_VALUE_SPECIAL_SIZE;
403         return TRUE;
404     }
405 
406     /* This is not a small key, return the length we read */
407     *RealLength = Length;
408     return FALSE;
409 }
410 
411 //
412 // Returns whether or not this is a big valued key
413 //
414 static inline
415 BOOLEAN
CmpIsKeyValueBig(IN PHHIVE Hive,IN ULONG Length)416 CmpIsKeyValueBig(IN PHHIVE Hive,
417                  IN ULONG Length)
418 {
419     /* Check if the hive is XP Beta 1 or newer */
420     if (Hive->Version >= HSYS_WHISTLER_BETA1)
421     {
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))
424         {
425             /* Yes, this value is big */
426             return TRUE;
427         }
428     }
429 
430     /* Not a big value key */
431     return FALSE;
432 }
433 
434 /*
435  * Public Hive functions.
436  */
437 NTSTATUS CMAPI
438 HvInitialize(
439     PHHIVE RegistryHive,
440     ULONG OperationType,
441     ULONG HiveFlags,
442     ULONG FileType,
443     PVOID HiveData OPTIONAL,
444     PALLOCATE_ROUTINE Allocate,
445     PFREE_ROUTINE Free,
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);
452 
453 VOID CMAPI
454 HvFree(
455    PHHIVE RegistryHive);
456 
457 #define HvGetCell(Hive, Cell)   \
458     (Hive)->GetCellRoutine(Hive, Cell)
459 
460 #define HvReleaseCell(Hive, Cell)               \
461 do {                                            \
462     if ((Hive)->ReleaseCellRoutine)             \
463         (Hive)->ReleaseCellRoutine(Hive, Cell); \
464 } while(0)
465 
466 LONG CMAPI
467 HvGetCellSize(
468    PHHIVE RegistryHive,
469    PVOID Cell);
470 
471 HCELL_INDEX CMAPI
472 HvAllocateCell(
473    PHHIVE RegistryHive,
474    ULONG Size,
475    HSTORAGE_TYPE Storage,
476    IN HCELL_INDEX Vicinity);
477 
478 BOOLEAN CMAPI
479 HvIsCellAllocated(
480     IN PHHIVE RegistryHive,
481     IN HCELL_INDEX CellIndex
482 );
483 
484 HCELL_INDEX CMAPI
485 HvReallocateCell(
486    PHHIVE RegistryHive,
487    HCELL_INDEX CellOffset,
488    ULONG Size);
489 
490 VOID CMAPI
491 HvFreeCell(
492    PHHIVE RegistryHive,
493    HCELL_INDEX CellOffset);
494 
495 BOOLEAN CMAPI
496 HvMarkCellDirty(
497    PHHIVE RegistryHive,
498    HCELL_INDEX CellOffset,
499    BOOLEAN HoldingLock);
500 
501 BOOLEAN CMAPI
502 HvIsCellDirty(
503     IN PHHIVE Hive,
504     IN HCELL_INDEX Cell
505 );
506 
507 BOOLEAN
508 CMAPI
509 HvHiveWillShrink(
510     IN PHHIVE RegistryHive
511 );
512 
513 BOOLEAN CMAPI
514 HvSyncHive(
515    PHHIVE RegistryHive);
516 
517 BOOLEAN CMAPI
518 HvWriteHive(
519    PHHIVE RegistryHive);
520 
521 BOOLEAN
522 CMAPI
523 HvWriteAlternateHive(
524     _In_ PHHIVE RegistryHive);
525 
526 BOOLEAN
527 CMAPI
528 HvSyncHiveFromRecover(
529     _In_ PHHIVE RegistryHive);
530 
531 BOOLEAN
532 CMAPI
533 HvTrackCellRef(
534     IN OUT PHV_TRACK_CELL_REF CellRef,
535     IN PHHIVE Hive,
536     IN HCELL_INDEX Cell
537 );
538 
539 VOID
540 CMAPI
541 HvReleaseFreeCellRefArray(
542     IN OUT PHV_TRACK_CELL_REF CellRef
543 );
544 
545 /*
546  * Private functions.
547  */
548 
549 PCELL_DATA CMAPI
550 HvpGetCellData(
551     _In_ PHHIVE Hive,
552     _In_ HCELL_INDEX CellIndex);
553 
554 PHBIN CMAPI
555 HvpAddBin(
556    PHHIVE RegistryHive,
557    ULONG Size,
558    HSTORAGE_TYPE Storage);
559 
560 NTSTATUS CMAPI
561 HvpCreateHiveFreeCellList(
562    PHHIVE Hive);
563 
564 ULONG CMAPI
565 HvpHiveHeaderChecksum(
566    PHBASE_BLOCK HiveHeader);
567 
568 BOOLEAN CMAPI
569 HvpVerifyHiveHeader(
570     _In_ PHBASE_BLOCK BaseBlock,
571     _In_ ULONG FileType);
572 
573 //
574 // Registry Self-Heal Routines
575 //
576 BOOLEAN
577 CMAPI
578 CmIsSelfHealEnabled(
579     _In_ BOOLEAN FixHive);
580 
581 BOOLEAN
582 CMAPI
583 CmpRepairParentKey(
584     _Inout_ PHHIVE Hive,
585     _In_ HCELL_INDEX TargetKey,
586     _In_ HCELL_INDEX ParentKey,
587     _In_ BOOLEAN FixHive);
588 
589 BOOLEAN
590 CMAPI
591 CmpRepairParentNode(
592     _Inout_ PHHIVE Hive,
593     _In_ HCELL_INDEX DirtyCell,
594     _In_ HCELL_INDEX ParentCell,
595     _Inout_ PCELL_DATA CellData,
596     _In_ BOOLEAN FixHive);
597 
598 BOOLEAN
599 CMAPI
600 CmpRepairKeyNodeSignature(
601     _Inout_ PHHIVE Hive,
602     _In_ HCELL_INDEX DirtyCell,
603     _Inout_ PCELL_DATA CellData,
604     _In_ BOOLEAN FixHive);
605 
606 BOOLEAN
607 CMAPI
608 CmpRepairClassOfNodeKey(
609     _Inout_ PHHIVE Hive,
610     _In_ HCELL_INDEX DirtyCell,
611     _Inout_ PCELL_DATA CellData,
612     _In_ BOOLEAN FixHive);
613 
614 BOOLEAN
615 CMAPI
616 CmpRepairValueList(
617     _Inout_ PHHIVE Hive,
618     _In_ HCELL_INDEX CurrentCell,
619     _In_ BOOLEAN FixHive);
620 
621 BOOLEAN
622 CMAPI
623 CmpRepairValueListCount(
624     _Inout_ PHHIVE Hive,
625     _In_ HCELL_INDEX CurrentCell,
626     _In_ ULONG ListCountIndex,
627     _Inout_ PCELL_DATA ValueListData,
628     _In_ BOOLEAN FixHive);
629 
630 BOOLEAN
631 CMAPI
632 CmpRepairSubKeyCounts(
633     _Inout_ PHHIVE Hive,
634     _In_ HCELL_INDEX CurrentCell,
635     _In_ ULONG Count,
636     _Inout_ PCELL_DATA CellData,
637     _In_ BOOLEAN FixHive);
638 
639 BOOLEAN
640 CMAPI
641 CmpRepairSubKeyList(
642     _Inout_ PHHIVE Hive,
643     _In_ HCELL_INDEX CurrentCell,
644     _Inout_ PCELL_DATA CellData,
645     _In_ BOOLEAN FixHive);
646 
647 /* Old-style Public "Cmlib" functions */
648 
649 BOOLEAN CMAPI
650 CmCreateRootNode(
651    PHHIVE Hive,
652    PCWSTR Name);
653 
654 /* NT-style Public Cm functions */
655 
656 //
657 // Check Registry Routines
658 //
659 CM_CHECK_REGISTRY_STATUS
660 NTAPI
661 HvValidateBin(
662     _In_ PHHIVE Hive,
663     _In_ PHBIN Bin);
664 
665 CM_CHECK_REGISTRY_STATUS
666 NTAPI
667 HvValidateHive(
668     _In_ PHHIVE Hive);
669 
670 CM_CHECK_REGISTRY_STATUS
671 NTAPI
672 CmCheckRegistry(
673     _In_ PCMHIVE RegistryHive,
674     _In_ ULONG Flags);
675 
676 //
677 // Cell Index Routines
678 //
679 HCELL_INDEX
680 NTAPI
681 CmpFindSubKeyByName(
682     IN PHHIVE Hive,
683     IN PCM_KEY_NODE Parent,
684     IN PCUNICODE_STRING SearchName
685 );
686 
687 HCELL_INDEX
688 NTAPI
689 CmpFindSubKeyByNumber(
690     IN PHHIVE Hive,
691     IN PCM_KEY_NODE Node,
692     IN ULONG Number
693 );
694 
695 ULONG
696 NTAPI
697 CmpComputeHashKey(
698     IN ULONG Hash,
699     IN PCUNICODE_STRING Name,
700     IN BOOLEAN AllowSeparators
701 );
702 
703 BOOLEAN
704 NTAPI
705 CmpAddSubKey(
706     IN PHHIVE Hive,
707     IN HCELL_INDEX Parent,
708     IN HCELL_INDEX Child
709 );
710 
711 BOOLEAN
712 NTAPI
713 CmpRemoveSubKey(
714     IN PHHIVE Hive,
715     IN HCELL_INDEX ParentKey,
716     IN HCELL_INDEX TargetKey
717 );
718 
719 BOOLEAN
720 NTAPI
721 CmpMarkIndexDirty(
722     IN PHHIVE Hive,
723     HCELL_INDEX ParentKey,
724     HCELL_INDEX TargetKey
725 );
726 
727 
728 //
729 // Name Functions
730 //
731 LONG
732 NTAPI
733 CmpCompareCompressedName(
734     IN PCUNICODE_STRING SearchName,
735     IN PWCHAR CompressedName,
736     IN ULONG NameLength
737 );
738 
739 USHORT
740 NTAPI
741 CmpNameSize(
742     IN PHHIVE Hive,
743     IN PCUNICODE_STRING Name
744 );
745 
746 USHORT
747 NTAPI
748 CmpCompressedNameSize(
749     IN PWCHAR Name,
750     IN ULONG Length
751 );
752 
753 USHORT
754 NTAPI
755 CmpCopyName(
756     IN PHHIVE Hive,
757     OUT PWCHAR Destination,
758     IN PCUNICODE_STRING Source
759 );
760 
761 VOID
762 NTAPI
763 CmpCopyCompressedName(
764     OUT PWCHAR Destination,
765     IN ULONG DestinationLength,
766     IN PWCHAR Source,
767     IN ULONG SourceLength
768 );
769 
770 BOOLEAN
771 NTAPI
772 CmpFindNameInList(
773     IN PHHIVE Hive,
774     IN PCHILD_LIST ChildList,
775     IN PCUNICODE_STRING Name,
776     OUT PULONG ChildIndex OPTIONAL,
777     OUT PHCELL_INDEX CellIndex
778 );
779 
780 
781 //
782 // Cell Value Routines
783 //
784 HCELL_INDEX
785 NTAPI
786 CmpFindValueByName(
787     IN PHHIVE Hive,
788     IN PCM_KEY_NODE KeyNode,
789     IN PCUNICODE_STRING Name
790 );
791 
792 PCELL_DATA
793 NTAPI
794 CmpValueToData(
795     IN PHHIVE Hive,
796     IN PCM_KEY_VALUE Value,
797     OUT PULONG Length
798 );
799 
800 NTSTATUS
801 NTAPI
802 CmpSetValueDataNew(
803     IN PHHIVE Hive,
804     IN PVOID Data,
805     IN ULONG DataSize,
806     IN HSTORAGE_TYPE StorageType,
807     IN HCELL_INDEX ValueCell,
808     OUT PHCELL_INDEX DataCell
809 );
810 
811 NTSTATUS
812 NTAPI
813 CmpAddValueToList(
814     IN PHHIVE Hive,
815     IN HCELL_INDEX ValueCell,
816     IN ULONG Index,
817     IN HSTORAGE_TYPE StorageType,
818     IN OUT PCHILD_LIST ChildList
819 );
820 
821 BOOLEAN
822 NTAPI
823 CmpFreeValue(
824     IN PHHIVE Hive,
825     IN HCELL_INDEX Cell
826 );
827 
828 BOOLEAN
829 NTAPI
830 CmpMarkValueDataDirty(
831     IN PHHIVE Hive,
832     IN PCM_KEY_VALUE Value
833 );
834 
835 BOOLEAN
836 NTAPI
837 CmpFreeValueData(
838     IN PHHIVE Hive,
839     IN HCELL_INDEX DataCell,
840     IN ULONG DataLength
841 );
842 
843 NTSTATUS
844 NTAPI
845 CmpRemoveValueFromList(
846     IN PHHIVE Hive,
847     IN ULONG Index,
848     IN OUT PCHILD_LIST ChildList
849 );
850 
851 BOOLEAN
852 NTAPI
853 CmpGetValueData(
854     IN PHHIVE Hive,
855     IN PCM_KEY_VALUE Value,
856     OUT PULONG Length,
857     OUT PVOID *Buffer,
858     OUT PBOOLEAN BufferAllocated,
859     OUT PHCELL_INDEX CellToRelease
860 );
861 
862 NTSTATUS
863 NTAPI
864 CmpCopyKeyValueList(
865     IN PHHIVE SourceHive,
866     IN PCHILD_LIST SrcValueList,
867     IN PHHIVE DestinationHive,
868     IN OUT PCHILD_LIST DestValueList,
869     IN HSTORAGE_TYPE StorageType
870 );
871 
872 NTSTATUS
873 NTAPI
874 CmpFreeKeyByCell(
875     IN PHHIVE Hive,
876     IN HCELL_INDEX Cell,
877     IN BOOLEAN Unlink
878 );
879 
880 VOID
881 NTAPI
882 CmpRemoveSecurityCellList(
883     IN PHHIVE Hive,
884     IN HCELL_INDEX SecurityCell
885 );
886 
887 VOID
888 NTAPI
889 CmpFreeSecurityDescriptor(
890     IN PHHIVE Hive,
891     IN HCELL_INDEX Cell
892 );
893 
894 /******************************************************************************/
895 
896 /* To be implemented by the user of this library */
897 PVOID
898 NTAPI
899 CmpAllocate(
900     IN SIZE_T Size,
901     IN BOOLEAN Paged,
902     IN ULONG Tag
903 );
904 
905 VOID
906 NTAPI
907 CmpFree(
908     IN PVOID Ptr,
909     IN ULONG Quota
910 );
911 
912 #endif /* _CMLIB_H_ */
913