xref: /reactos/sdk/lib/cmlib/cmlib.h (revision 57b9c6b2)
1 /*
2  * PROJECT:   Registry manipulation library
3  * LICENSE:   GPL - See COPYING in the top level directory
4  * COPYRIGHT: Copyright 2005 Filip Navara <navaraf@reactos.org>
5  *            Copyright 2001 - 2005 Eric Kohl
6  */
7 
8 #ifndef _CMLIB_H_
9 #define _CMLIB_H_
10 
11 //
12 // Debug support switch
13 //
14 #define _CMLIB_DEBUG_ 1
15 
16 #ifdef CMLIB_HOST
17     #include <typedefs.h>
18     #include <stdio.h>
19     #include <string.h>
20 
21     // NTDDI_xxx versions we allude to in the library (see psdk/sdkddkver.h)
22     #define NTDDI_WS03SP4                       0x05020400
23     #define NTDDI_WIN6                          0x06000000
24     #define NTDDI_LONGHORN                      NTDDI_WIN6
25     #define NTDDI_VISTA                         NTDDI_WIN6
26     #define NTDDI_WIN7                          0x06010000
27 
28     #define NTDDI_VERSION   NTDDI_WS03SP4 // This is the ReactOS NT kernel version
29 
30     /* C_ASSERT Definition */
31     #define C_ASSERT(expr) extern char (*c_assert(void)) [(expr) ? 1 : -1]
32 
33     #ifdef _WIN32
34     #define strncasecmp _strnicmp
35     #define strcasecmp _stricmp
36     #endif // _WIN32
37 
38     #if (!defined(_MSC_VER) || (_MSC_VER < 1500))
39     #define _In_
40     #define _Out_
41     #define _Inout_
42     #define _In_opt_
43     #define _In_range_(x, y)
44     #endif
45 
46     #define __drv_aliasesMem
47 
48     #ifndef min
49     #define min(a, b)  (((a) < (b)) ? (a) : (b))
50     #endif
51 
52     // #ifndef max
53     // #define max(a, b)  (((a) > (b)) ? (a) : (b))
54     // #endif
55 
56     // Definitions copied from <ntstatus.h>
57     // We only want to include host headers, so we define them manually
58     #define STATUS_SUCCESS                   ((NTSTATUS)0x00000000)
59     #define STATUS_NOT_IMPLEMENTED           ((NTSTATUS)0xC0000002)
60     #define STATUS_NO_MEMORY                 ((NTSTATUS)0xC0000017)
61     #define STATUS_INSUFFICIENT_RESOURCES    ((NTSTATUS)0xC000009A)
62     #define STATUS_REGISTRY_CORRUPT          ((NTSTATUS)0xC000014C)
63     #define STATUS_NOT_REGISTRY_FILE         ((NTSTATUS)0xC000015C)
64     #define STATUS_REGISTRY_RECOVERED        ((NTSTATUS)0x40000009)
65 
66     #define REG_OPTION_VOLATILE              1
67     #define OBJ_CASE_INSENSITIVE             0x00000040L
68     #define USHORT_MAX                       USHRT_MAX
69 
70     #define OBJ_NAME_PATH_SEPARATOR          ((WCHAR)L'\\')
71     #define UNICODE_NULL                     ((WCHAR)0)
72 
73     VOID NTAPI
74     RtlInitUnicodeString(
75         IN OUT PUNICODE_STRING DestinationString,
76         IN PCWSTR SourceString);
77 
78     LONG NTAPI
79     RtlCompareUnicodeString(
80         IN PCUNICODE_STRING String1,
81         IN PCUNICODE_STRING String2,
82         IN BOOLEAN CaseInSensitive);
83 
84     // FIXME: DECLSPEC_NORETURN
85     VOID
86     NTAPI
87     KeBugCheckEx(
88         IN ULONG BugCheckCode,
89         IN ULONG_PTR BugCheckParameter1,
90         IN ULONG_PTR BugCheckParameter2,
91         IN ULONG_PTR BugCheckParameter3,
92         IN ULONG_PTR BugCheckParameter4);
93 
94     VOID NTAPI
95     KeQuerySystemTime(
96         OUT PLARGE_INTEGER CurrentTime);
97 
98     WCHAR NTAPI
99     RtlUpcaseUnicodeChar(
100         IN WCHAR Source);
101 
102     VOID NTAPI
103     RtlInitializeBitMap(
104         IN PRTL_BITMAP BitMapHeader,
105         IN PULONG BitMapBuffer,
106         IN ULONG SizeOfBitMap);
107 
108     ULONG NTAPI
109     RtlFindSetBits(
110         IN PRTL_BITMAP BitMapHeader,
111         IN ULONG NumberToFind,
112         IN ULONG HintIndex);
113 
114     VOID NTAPI
115     RtlSetBits(
116         IN PRTL_BITMAP BitMapHeader,
117         IN ULONG StartingIndex,
118         IN ULONG NumberToSet);
119 
120     VOID NTAPI
121     RtlClearAllBits(
122         IN PRTL_BITMAP BitMapHeader);
123 
124     #define RtlCheckBit(BMH,BP) (((((PLONG)(BMH)->Buffer)[(BP) / 32]) >> ((BP) % 32)) & 0x1)
125     #define UNREFERENCED_PARAMETER(P) {(P)=(P);}
126 
127     #define PKTHREAD PVOID
128     #define PKGUARDED_MUTEX PVOID
129     #define PERESOURCE PVOID
130     #define PFILE_OBJECT PVOID
131     #define PKEVENT PVOID
132     #define PWORK_QUEUE_ITEM PVOID
133     #define EX_PUSH_LOCK PULONG_PTR
134 
135     // Definitions copied from <ntifs.h>
136     // We only want to include host headers, so we define them manually
137 
138     typedef USHORT SECURITY_DESCRIPTOR_CONTROL, *PSECURITY_DESCRIPTOR_CONTROL;
139 
140     typedef struct _SECURITY_DESCRIPTOR_RELATIVE
141     {
142         UCHAR Revision;
143         UCHAR Sbz1;
144         SECURITY_DESCRIPTOR_CONTROL Control;
145         ULONG Owner;
146         ULONG Group;
147         ULONG Sacl;
148         ULONG Dacl;
149     } SECURITY_DESCRIPTOR_RELATIVE, *PISECURITY_DESCRIPTOR_RELATIVE;
150 
151     #define CMLTRACE(x, ...)
152     #undef PAGED_CODE
153     #define PAGED_CODE()
154     #define REGISTRY_ERROR                   ((ULONG)0x00000051L)
155 #else
156     //
157     // Debug/Tracing support
158     //
159     #if _CMLIB_DEBUG_
160     #ifdef NEW_DEBUG_SYSTEM_IMPLEMENTED // enable when Debug Filters are implemented
161     #define CMLTRACE DbgPrintEx
162     #else
163     #define CMLTRACE(x, ...)                                 \
164     if (x & CmlibTraceLevel) DbgPrint(__VA_ARGS__)
165     #endif
166     #else
167     #define CMLTRACE(x, ...) DPRINT(__VA_ARGS__)
168     #endif
169 
170     #include <ntdef.h>
171     #include <ntifs.h>
172     #include <bugcodes.h>
173     #undef PAGED_CODE
174     #define PAGED_CODE()
175 
176     /* Prevent inclusion of Windows headers through <wine/unicode.h> */
177     #define _WINDEF_
178     #define _WINBASE_
179     #define _WINNLS_
180 #endif
181 
182 
183 //
184 // These define the Debug Masks Supported
185 //
186 #define CMLIB_HCELL_DEBUG       0x01
187 
188 #ifndef ROUND_UP
189 #define ROUND_UP(a,b)        ((((a)+(b)-1)/(b))*(b))
190 #define ROUND_DOWN(a,b)      (((a)/(b))*(b))
191 #endif
192 
193 //
194 // PAGE_SIZE definition
195 //
196 #ifndef PAGE_SIZE
197 #if defined(TARGET_i386) || defined(TARGET_amd64) || \
198     defined(TARGET_arm)  || defined(TARGET_arm64)
199 #define PAGE_SIZE 0x1000
200 #else
201 #error Local PAGE_SIZE definition required when built as host
202 #endif
203 #endif
204 
205 #define TAG_CM     '  MC'
206 #define TAG_KCB    'bkMC'
207 #define TAG_CMHIVE 'vHMC'
208 #define TAG_CMSD   'DSMC'
209 
210 #define CMAPI NTAPI
211 
212 #include <wine/unicode.h>
213 #include <wchar.h>
214 #include "hivedata.h"
215 #include "cmdata.h"
216 
217 #if defined(_TYPEDEFS_HOST_H) || defined(_BLDR_)
218 
219 #define PCM_KEY_SECURITY_CACHE_ENTRY    PVOID
220 #define PCM_KEY_CONTROL_BLOCK           PVOID
221 #define PCM_CELL_REMAP_BLOCK            PVOID
222 
223 // See also ntoskrnl/include/internal/cm.h
224 #define CMP_SECURITY_HASH_LISTS         64
225 
226 // #endif // Commented out until one finds a way to properly include
227           // this header in the bootloader and in ntoskrnl.
228 
229 //
230 // Use Count Log and Entry
231 //
232 typedef struct _CM_USE_COUNT_LOG_ENTRY
233 {
234     HCELL_INDEX Cell;
235     PVOID Stack[7];
236 } CM_USE_COUNT_LOG_ENTRY, *PCM_USE_COUNT_LOG_ENTRY;
237 
238 typedef struct _CM_USE_COUNT_LOG
239 {
240     USHORT Next;
241     USHORT Size;
242     CM_USE_COUNT_LOG_ENTRY Log[32];
243 } CM_USE_COUNT_LOG, *PCM_USE_COUNT_LOG;
244 
245 //
246 // Configuration Manager Hive Structure
247 //
248 typedef struct _CMHIVE
249 {
250     HHIVE Hive;
251     HANDLE FileHandles[HFILE_TYPE_MAX];
252     LIST_ENTRY NotifyList;
253     LIST_ENTRY HiveList;
254     EX_PUSH_LOCK HiveLock;
255     PKTHREAD HiveLockOwner;
256     PKGUARDED_MUTEX ViewLock;
257     PKTHREAD ViewLockOwner;
258     EX_PUSH_LOCK WriterLock;
259     PKTHREAD WriterLockOwner;
260     PERESOURCE FlusherLock;
261     EX_PUSH_LOCK SecurityLock;
262     PKTHREAD HiveSecurityLockOwner;
263     LIST_ENTRY LRUViewListHead;
264     LIST_ENTRY PinViewListHead;
265     PFILE_OBJECT FileObject;
266     UNICODE_STRING FileFullPath;
267     UNICODE_STRING FileUserName;
268     USHORT MappedViews;
269     USHORT PinnedViews;
270     ULONG UseCount;
271     ULONG SecurityCount;
272     ULONG SecurityCacheSize;
273     LONG SecurityHitHint;
274     PCM_KEY_SECURITY_CACHE_ENTRY SecurityCache;
275     LIST_ENTRY SecurityHash[CMP_SECURITY_HASH_LISTS];
276     PKEVENT UnloadEvent;
277     PCM_KEY_CONTROL_BLOCK RootKcb;
278     BOOLEAN Frozen;
279     PWORK_QUEUE_ITEM UnloadWorkItem;
280     BOOLEAN GrowOnlyMode;
281     ULONG GrowOffset;
282     LIST_ENTRY KcbConvertListHead;
283     LIST_ENTRY KnodeConvertListHead;
284     PCM_CELL_REMAP_BLOCK CellRemapArray;
285     CM_USE_COUNT_LOG UseCountLog;
286     CM_USE_COUNT_LOG LockHiveLog;
287     ULONG Flags;
288     LIST_ENTRY TrustClassEntry;
289     ULONG FlushCount;
290     BOOLEAN HiveIsLoading;
291     PKTHREAD CreatorOwner;
292 } CMHIVE, *PCMHIVE;
293 
294 #endif // See comment above
295 
296 typedef struct _HV_HIVE_CELL_PAIR
297 {
298     PHHIVE Hive;
299     HCELL_INDEX Cell;
300 } HV_HIVE_CELL_PAIR, *PHV_HIVE_CELL_PAIR;
301 
302 #define STATIC_CELL_PAIR_COUNT 4
303 typedef struct _HV_TRACK_CELL_REF
304 {
305     USHORT Count;
306     USHORT Max;
307     PHV_HIVE_CELL_PAIR CellArray;
308     HV_HIVE_CELL_PAIR StaticArray[STATIC_CELL_PAIR_COUNT];
309     USHORT StaticCount;
310 } HV_TRACK_CELL_REF, *PHV_TRACK_CELL_REF;
311 
312 extern ULONG CmlibTraceLevel;
313 
314 //
315 // Hack since bigkeys are not yet supported
316 //
317 #define ASSERT_VALUE_BIG(h, s)                          \
318     ASSERTMSG("Big keys not supported!\n", !CmpIsKeyValueBig(h, s));
319 
320 //
321 // Returns whether or not this is a small valued key
322 //
323 static inline
324 BOOLEAN
325 CmpIsKeyValueSmall(OUT PULONG RealLength,
326                    IN ULONG Length)
327 {
328     /* Check if the length has the special size value */
329     if (Length >= CM_KEY_VALUE_SPECIAL_SIZE)
330     {
331         /* It does, so this is a small key: return the real length */
332         *RealLength = Length - CM_KEY_VALUE_SPECIAL_SIZE;
333         return TRUE;
334     }
335 
336     /* This is not a small key, return the length we read */
337     *RealLength = Length;
338     return FALSE;
339 }
340 
341 //
342 // Returns whether or not this is a big valued key
343 //
344 static inline
345 BOOLEAN
346 CmpIsKeyValueBig(IN PHHIVE Hive,
347                  IN ULONG Length)
348 {
349     /* Check if the hive is XP Beta 1 or newer */
350     if (Hive->Version >= HSYS_WHISTLER_BETA1)
351     {
352         /* Check if the key length is valid for a big value key */
353         if ((Length < CM_KEY_VALUE_SPECIAL_SIZE) && (Length > CM_KEY_VALUE_BIG))
354         {
355             /* Yes, this value is big */
356             return TRUE;
357         }
358     }
359 
360     /* Not a big value key */
361     return FALSE;
362 }
363 
364 /*
365  * Public Hive functions.
366  */
367 NTSTATUS CMAPI
368 HvInitialize(
369     PHHIVE RegistryHive,
370     ULONG OperationType,
371     ULONG HiveFlags,
372     ULONG FileType,
373     PVOID HiveData OPTIONAL,
374     PALLOCATE_ROUTINE Allocate,
375     PFREE_ROUTINE Free,
376     PFILE_SET_SIZE_ROUTINE FileSetSize,
377     PFILE_WRITE_ROUTINE FileWrite,
378     PFILE_READ_ROUTINE FileRead,
379     PFILE_FLUSH_ROUTINE FileFlush,
380     ULONG Cluster OPTIONAL,
381     PCUNICODE_STRING FileName OPTIONAL);
382 
383 VOID CMAPI
384 HvFree(
385    PHHIVE RegistryHive);
386 
387 #define HvGetCell(Hive, Cell)   \
388     (Hive)->GetCellRoutine(Hive, Cell)
389 
390 #define HvReleaseCell(Hive, Cell)               \
391 do {                                            \
392     if ((Hive)->ReleaseCellRoutine)             \
393         (Hive)->ReleaseCellRoutine(Hive, Cell); \
394 } while(0)
395 
396 LONG CMAPI
397 HvGetCellSize(
398    PHHIVE RegistryHive,
399    PVOID Cell);
400 
401 HCELL_INDEX CMAPI
402 HvAllocateCell(
403    PHHIVE RegistryHive,
404    ULONG Size,
405    HSTORAGE_TYPE Storage,
406    IN HCELL_INDEX Vicinity);
407 
408 BOOLEAN CMAPI
409 HvIsCellAllocated(
410     IN PHHIVE RegistryHive,
411     IN HCELL_INDEX CellIndex
412 );
413 
414 HCELL_INDEX CMAPI
415 HvReallocateCell(
416    PHHIVE RegistryHive,
417    HCELL_INDEX CellOffset,
418    ULONG Size);
419 
420 VOID CMAPI
421 HvFreeCell(
422    PHHIVE RegistryHive,
423    HCELL_INDEX CellOffset);
424 
425 BOOLEAN CMAPI
426 HvMarkCellDirty(
427    PHHIVE RegistryHive,
428    HCELL_INDEX CellOffset,
429    BOOLEAN HoldingLock);
430 
431 BOOLEAN CMAPI
432 HvIsCellDirty(
433     IN PHHIVE Hive,
434     IN HCELL_INDEX Cell
435 );
436 
437 BOOLEAN
438 CMAPI
439 HvHiveWillShrink(
440     IN PHHIVE RegistryHive
441 );
442 
443 BOOLEAN CMAPI
444 HvSyncHive(
445    PHHIVE RegistryHive);
446 
447 BOOLEAN CMAPI
448 HvWriteHive(
449    PHHIVE RegistryHive);
450 
451 BOOLEAN
452 CMAPI
453 HvTrackCellRef(
454     IN OUT PHV_TRACK_CELL_REF CellRef,
455     IN PHHIVE Hive,
456     IN HCELL_INDEX Cell
457 );
458 
459 VOID
460 CMAPI
461 HvReleaseFreeCellRefArray(
462     IN OUT PHV_TRACK_CELL_REF CellRef
463 );
464 
465 /*
466  * Private functions.
467  */
468 
469 PCELL_DATA CMAPI
470 HvpGetCellData(
471     _In_ PHHIVE Hive,
472     _In_ HCELL_INDEX CellIndex);
473 
474 PHBIN CMAPI
475 HvpAddBin(
476    PHHIVE RegistryHive,
477    ULONG Size,
478    HSTORAGE_TYPE Storage);
479 
480 NTSTATUS CMAPI
481 HvpCreateHiveFreeCellList(
482    PHHIVE Hive);
483 
484 ULONG CMAPI
485 HvpHiveHeaderChecksum(
486    PHBASE_BLOCK HiveHeader);
487 
488 
489 /* Old-style Public "Cmlib" functions */
490 
491 BOOLEAN CMAPI
492 CmCreateRootNode(
493    PHHIVE Hive,
494    PCWSTR Name);
495 
496 VOID CMAPI
497 CmPrepareHive(
498    PHHIVE RegistryHive);
499 
500 
501 /* NT-style Public Cm functions */
502 
503 //
504 // Cell Index Routines
505 //
506 HCELL_INDEX
507 NTAPI
508 CmpFindSubKeyByName(
509     IN PHHIVE Hive,
510     IN PCM_KEY_NODE Parent,
511     IN PCUNICODE_STRING SearchName
512 );
513 
514 HCELL_INDEX
515 NTAPI
516 CmpFindSubKeyByNumber(
517     IN PHHIVE Hive,
518     IN PCM_KEY_NODE Node,
519     IN ULONG Number
520 );
521 
522 ULONG
523 NTAPI
524 CmpComputeHashKey(
525     IN ULONG Hash,
526     IN PCUNICODE_STRING Name,
527     IN BOOLEAN AllowSeparators
528 );
529 
530 BOOLEAN
531 NTAPI
532 CmpAddSubKey(
533     IN PHHIVE Hive,
534     IN HCELL_INDEX Parent,
535     IN HCELL_INDEX Child
536 );
537 
538 BOOLEAN
539 NTAPI
540 CmpRemoveSubKey(
541     IN PHHIVE Hive,
542     IN HCELL_INDEX ParentKey,
543     IN HCELL_INDEX TargetKey
544 );
545 
546 BOOLEAN
547 NTAPI
548 CmpMarkIndexDirty(
549     IN PHHIVE Hive,
550     HCELL_INDEX ParentKey,
551     HCELL_INDEX TargetKey
552 );
553 
554 
555 //
556 // Name Functions
557 //
558 LONG
559 NTAPI
560 CmpCompareCompressedName(
561     IN PCUNICODE_STRING SearchName,
562     IN PWCHAR CompressedName,
563     IN ULONG NameLength
564 );
565 
566 USHORT
567 NTAPI
568 CmpNameSize(
569     IN PHHIVE Hive,
570     IN PCUNICODE_STRING Name
571 );
572 
573 USHORT
574 NTAPI
575 CmpCompressedNameSize(
576     IN PWCHAR Name,
577     IN ULONG Length
578 );
579 
580 USHORT
581 NTAPI
582 CmpCopyName(
583     IN PHHIVE Hive,
584     OUT PWCHAR Destination,
585     IN PCUNICODE_STRING Source
586 );
587 
588 VOID
589 NTAPI
590 CmpCopyCompressedName(
591     OUT PWCHAR Destination,
592     IN ULONG DestinationLength,
593     IN PWCHAR Source,
594     IN ULONG SourceLength
595 );
596 
597 BOOLEAN
598 NTAPI
599 CmpFindNameInList(
600     IN PHHIVE Hive,
601     IN PCHILD_LIST ChildList,
602     IN PCUNICODE_STRING Name,
603     OUT PULONG ChildIndex OPTIONAL,
604     OUT PHCELL_INDEX CellIndex
605 );
606 
607 
608 //
609 // Cell Value Routines
610 //
611 HCELL_INDEX
612 NTAPI
613 CmpFindValueByName(
614     IN PHHIVE Hive,
615     IN PCM_KEY_NODE KeyNode,
616     IN PCUNICODE_STRING Name
617 );
618 
619 PCELL_DATA
620 NTAPI
621 CmpValueToData(
622     IN PHHIVE Hive,
623     IN PCM_KEY_VALUE Value,
624     OUT PULONG Length
625 );
626 
627 NTSTATUS
628 NTAPI
629 CmpSetValueDataNew(
630     IN PHHIVE Hive,
631     IN PVOID Data,
632     IN ULONG DataSize,
633     IN HSTORAGE_TYPE StorageType,
634     IN HCELL_INDEX ValueCell,
635     OUT PHCELL_INDEX DataCell
636 );
637 
638 NTSTATUS
639 NTAPI
640 CmpAddValueToList(
641     IN PHHIVE Hive,
642     IN HCELL_INDEX ValueCell,
643     IN ULONG Index,
644     IN HSTORAGE_TYPE StorageType,
645     IN OUT PCHILD_LIST ChildList
646 );
647 
648 BOOLEAN
649 NTAPI
650 CmpFreeValue(
651     IN PHHIVE Hive,
652     IN HCELL_INDEX Cell
653 );
654 
655 BOOLEAN
656 NTAPI
657 CmpMarkValueDataDirty(
658     IN PHHIVE Hive,
659     IN PCM_KEY_VALUE Value
660 );
661 
662 BOOLEAN
663 NTAPI
664 CmpFreeValueData(
665     IN PHHIVE Hive,
666     IN HCELL_INDEX DataCell,
667     IN ULONG DataLength
668 );
669 
670 NTSTATUS
671 NTAPI
672 CmpRemoveValueFromList(
673     IN PHHIVE Hive,
674     IN ULONG Index,
675     IN OUT PCHILD_LIST ChildList
676 );
677 
678 BOOLEAN
679 NTAPI
680 CmpGetValueData(
681     IN PHHIVE Hive,
682     IN PCM_KEY_VALUE Value,
683     OUT PULONG Length,
684     OUT PVOID *Buffer,
685     OUT PBOOLEAN BufferAllocated,
686     OUT PHCELL_INDEX CellToRelease
687 );
688 
689 NTSTATUS
690 NTAPI
691 CmpCopyKeyValueList(
692     IN PHHIVE SourceHive,
693     IN PCHILD_LIST SrcValueList,
694     IN PHHIVE DestinationHive,
695     IN OUT PCHILD_LIST DestValueList,
696     IN HSTORAGE_TYPE StorageType
697 );
698 
699 NTSTATUS
700 NTAPI
701 CmpFreeKeyByCell(
702     IN PHHIVE Hive,
703     IN HCELL_INDEX Cell,
704     IN BOOLEAN Unlink
705 );
706 
707 VOID
708 NTAPI
709 CmpRemoveSecurityCellList(
710     IN PHHIVE Hive,
711     IN HCELL_INDEX SecurityCell
712 );
713 
714 VOID
715 NTAPI
716 CmpFreeSecurityDescriptor(
717     IN PHHIVE Hive,
718     IN HCELL_INDEX Cell
719 );
720 
721 /******************************************************************************/
722 
723 /* To be implemented by the user of this library */
724 PVOID
725 NTAPI
726 CmpAllocate(
727     IN SIZE_T Size,
728     IN BOOLEAN Paged,
729     IN ULONG Tag
730 );
731 
732 VOID
733 NTAPI
734 CmpFree(
735     IN PVOID Ptr,
736     IN ULONG Quota
737 );
738 
739 #endif /* _CMLIB_H_ */
740