xref: /reactos/sdk/lib/cmlib/cmlib.h (revision 09dde2cf)
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) ((void)(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 
156 #else
157 
158     //
159     // Debug/Tracing support
160     //
161     #if _CMLIB_DEBUG_
162     #ifdef NEW_DEBUG_SYSTEM_IMPLEMENTED // enable when Debug Filters are implemented
163     #define CMLTRACE DbgPrintEx
164     #else
165     #define CMLTRACE(x, ...)                                 \
166     if (x & CmlibTraceLevel) DbgPrint(__VA_ARGS__)
167     #endif
168     #else
169     #define CMLTRACE(x, ...) DPRINT(__VA_ARGS__)
170     #endif
171 
172     #include <ntdef.h>
173     #include <ntifs.h>
174     #include <bugcodes.h>
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 /* Forward declarations */
218 typedef struct _CM_KEY_SECURITY_CACHE_ENTRY *PCM_KEY_SECURITY_CACHE_ENTRY;
219 typedef struct _CM_KEY_CONTROL_BLOCK *PCM_KEY_CONTROL_BLOCK;
220 typedef struct _CM_CELL_REMAP_BLOCK *PCM_CELL_REMAP_BLOCK;
221 
222 // See ntoskrnl/include/internal/cm.h
223 #define CMP_SECURITY_HASH_LISTS     64
224 
225 //
226 // Use Count Log and Entry
227 //
228 typedef struct _CM_USE_COUNT_LOG_ENTRY
229 {
230     HCELL_INDEX Cell;
231     PVOID Stack[7];
232 } CM_USE_COUNT_LOG_ENTRY, *PCM_USE_COUNT_LOG_ENTRY;
233 
234 typedef struct _CM_USE_COUNT_LOG
235 {
236     USHORT Next;
237     USHORT Size;
238     CM_USE_COUNT_LOG_ENTRY Log[32];
239 } CM_USE_COUNT_LOG, *PCM_USE_COUNT_LOG;
240 
241 //
242 // Configuration Manager Hive Structure
243 //
244 typedef struct _CMHIVE
245 {
246     HHIVE Hive;
247     HANDLE FileHandles[HFILE_TYPE_MAX];
248     LIST_ENTRY NotifyList;
249     LIST_ENTRY HiveList;
250     EX_PUSH_LOCK HiveLock;
251     PKTHREAD HiveLockOwner;
252     PKGUARDED_MUTEX ViewLock;
253     PKTHREAD ViewLockOwner;
254     EX_PUSH_LOCK WriterLock;
255     PKTHREAD WriterLockOwner;
256     PERESOURCE FlusherLock;
257     EX_PUSH_LOCK SecurityLock;
258     PKTHREAD HiveSecurityLockOwner;
259     LIST_ENTRY LRUViewListHead;
260     LIST_ENTRY PinViewListHead;
261     PFILE_OBJECT FileObject;
262     UNICODE_STRING FileFullPath;
263     UNICODE_STRING FileUserName;
264     USHORT MappedViews;
265     USHORT PinnedViews;
266     ULONG UseCount;
267     ULONG SecurityCount;
268     ULONG SecurityCacheSize;
269     LONG SecurityHitHint;
270     PCM_KEY_SECURITY_CACHE_ENTRY SecurityCache;
271     LIST_ENTRY SecurityHash[CMP_SECURITY_HASH_LISTS];
272     PKEVENT UnloadEvent;
273     PCM_KEY_CONTROL_BLOCK RootKcb;
274     BOOLEAN Frozen;
275     PWORK_QUEUE_ITEM UnloadWorkItem;
276     BOOLEAN GrowOnlyMode;
277     ULONG GrowOffset;
278     LIST_ENTRY KcbConvertListHead;
279     LIST_ENTRY KnodeConvertListHead;
280     PCM_CELL_REMAP_BLOCK CellRemapArray;
281     CM_USE_COUNT_LOG UseCountLog;
282     CM_USE_COUNT_LOG LockHiveLog;
283     ULONG Flags;
284     LIST_ENTRY TrustClassEntry;
285     ULONG FlushCount;
286     BOOLEAN HiveIsLoading;
287     PKTHREAD CreatorOwner;
288 } CMHIVE, *PCMHIVE;
289 
290 typedef struct _HV_HIVE_CELL_PAIR
291 {
292     PHHIVE Hive;
293     HCELL_INDEX Cell;
294 } HV_HIVE_CELL_PAIR, *PHV_HIVE_CELL_PAIR;
295 
296 #define STATIC_CELL_PAIR_COUNT 4
297 typedef struct _HV_TRACK_CELL_REF
298 {
299     USHORT Count;
300     USHORT Max;
301     PHV_HIVE_CELL_PAIR CellArray;
302     HV_HIVE_CELL_PAIR StaticArray[STATIC_CELL_PAIR_COUNT];
303     USHORT StaticCount;
304 } HV_TRACK_CELL_REF, *PHV_TRACK_CELL_REF;
305 
306 extern ULONG CmlibTraceLevel;
307 
308 //
309 // Hack since big keys are not yet supported
310 //
311 #define ASSERT_VALUE_BIG(h, s)  \
312     ASSERTMSG("Big keys not supported!\n", !CmpIsKeyValueBig(h, s));
313 
314 //
315 // Returns whether or not this is a small valued key
316 //
317 static inline
318 BOOLEAN
319 CmpIsKeyValueSmall(OUT PULONG RealLength,
320                    IN ULONG Length)
321 {
322     /* Check if the length has the special size value */
323     if (Length >= CM_KEY_VALUE_SPECIAL_SIZE)
324     {
325         /* It does, so this is a small key: return the real length */
326         *RealLength = Length - CM_KEY_VALUE_SPECIAL_SIZE;
327         return TRUE;
328     }
329 
330     /* This is not a small key, return the length we read */
331     *RealLength = Length;
332     return FALSE;
333 }
334 
335 //
336 // Returns whether or not this is a big valued key
337 //
338 static inline
339 BOOLEAN
340 CmpIsKeyValueBig(IN PHHIVE Hive,
341                  IN ULONG Length)
342 {
343     /* Check if the hive is XP Beta 1 or newer */
344     if (Hive->Version >= HSYS_WHISTLER_BETA1)
345     {
346         /* Check if the key length is valid for a big value key */
347         if ((Length < CM_KEY_VALUE_SPECIAL_SIZE) && (Length > CM_KEY_VALUE_BIG))
348         {
349             /* Yes, this value is big */
350             return TRUE;
351         }
352     }
353 
354     /* Not a big value key */
355     return FALSE;
356 }
357 
358 /*
359  * Public Hive functions.
360  */
361 NTSTATUS CMAPI
362 HvInitialize(
363     PHHIVE RegistryHive,
364     ULONG OperationType,
365     ULONG HiveFlags,
366     ULONG FileType,
367     PVOID HiveData OPTIONAL,
368     PALLOCATE_ROUTINE Allocate,
369     PFREE_ROUTINE Free,
370     PFILE_SET_SIZE_ROUTINE FileSetSize,
371     PFILE_WRITE_ROUTINE FileWrite,
372     PFILE_READ_ROUTINE FileRead,
373     PFILE_FLUSH_ROUTINE FileFlush,
374     ULONG Cluster OPTIONAL,
375     PCUNICODE_STRING FileName OPTIONAL);
376 
377 VOID CMAPI
378 HvFree(
379    PHHIVE RegistryHive);
380 
381 #define HvGetCell(Hive, Cell)   \
382     (Hive)->GetCellRoutine(Hive, Cell)
383 
384 #define HvReleaseCell(Hive, Cell)               \
385 do {                                            \
386     if ((Hive)->ReleaseCellRoutine)             \
387         (Hive)->ReleaseCellRoutine(Hive, Cell); \
388 } while(0)
389 
390 LONG CMAPI
391 HvGetCellSize(
392    PHHIVE RegistryHive,
393    PVOID Cell);
394 
395 HCELL_INDEX CMAPI
396 HvAllocateCell(
397    PHHIVE RegistryHive,
398    ULONG Size,
399    HSTORAGE_TYPE Storage,
400    IN HCELL_INDEX Vicinity);
401 
402 BOOLEAN CMAPI
403 HvIsCellAllocated(
404     IN PHHIVE RegistryHive,
405     IN HCELL_INDEX CellIndex
406 );
407 
408 HCELL_INDEX CMAPI
409 HvReallocateCell(
410    PHHIVE RegistryHive,
411    HCELL_INDEX CellOffset,
412    ULONG Size);
413 
414 VOID CMAPI
415 HvFreeCell(
416    PHHIVE RegistryHive,
417    HCELL_INDEX CellOffset);
418 
419 BOOLEAN CMAPI
420 HvMarkCellDirty(
421    PHHIVE RegistryHive,
422    HCELL_INDEX CellOffset,
423    BOOLEAN HoldingLock);
424 
425 BOOLEAN CMAPI
426 HvIsCellDirty(
427     IN PHHIVE Hive,
428     IN HCELL_INDEX Cell
429 );
430 
431 BOOLEAN
432 CMAPI
433 HvHiveWillShrink(
434     IN PHHIVE RegistryHive
435 );
436 
437 BOOLEAN CMAPI
438 HvSyncHive(
439    PHHIVE RegistryHive);
440 
441 BOOLEAN CMAPI
442 HvWriteHive(
443    PHHIVE RegistryHive);
444 
445 BOOLEAN
446 CMAPI
447 HvTrackCellRef(
448     IN OUT PHV_TRACK_CELL_REF CellRef,
449     IN PHHIVE Hive,
450     IN HCELL_INDEX Cell
451 );
452 
453 VOID
454 CMAPI
455 HvReleaseFreeCellRefArray(
456     IN OUT PHV_TRACK_CELL_REF CellRef
457 );
458 
459 /*
460  * Private functions.
461  */
462 
463 PCELL_DATA CMAPI
464 HvpGetCellData(
465     _In_ PHHIVE Hive,
466     _In_ HCELL_INDEX CellIndex);
467 
468 PHBIN CMAPI
469 HvpAddBin(
470    PHHIVE RegistryHive,
471    ULONG Size,
472    HSTORAGE_TYPE Storage);
473 
474 NTSTATUS CMAPI
475 HvpCreateHiveFreeCellList(
476    PHHIVE Hive);
477 
478 ULONG CMAPI
479 HvpHiveHeaderChecksum(
480    PHBASE_BLOCK HiveHeader);
481 
482 
483 /* Old-style Public "Cmlib" functions */
484 
485 BOOLEAN CMAPI
486 CmCreateRootNode(
487    PHHIVE Hive,
488    PCWSTR Name);
489 
490 VOID CMAPI
491 CmPrepareHive(
492    PHHIVE RegistryHive);
493 
494 
495 /* NT-style Public Cm functions */
496 
497 //
498 // Cell Index Routines
499 //
500 HCELL_INDEX
501 NTAPI
502 CmpFindSubKeyByName(
503     IN PHHIVE Hive,
504     IN PCM_KEY_NODE Parent,
505     IN PCUNICODE_STRING SearchName
506 );
507 
508 HCELL_INDEX
509 NTAPI
510 CmpFindSubKeyByNumber(
511     IN PHHIVE Hive,
512     IN PCM_KEY_NODE Node,
513     IN ULONG Number
514 );
515 
516 ULONG
517 NTAPI
518 CmpComputeHashKey(
519     IN ULONG Hash,
520     IN PCUNICODE_STRING Name,
521     IN BOOLEAN AllowSeparators
522 );
523 
524 BOOLEAN
525 NTAPI
526 CmpAddSubKey(
527     IN PHHIVE Hive,
528     IN HCELL_INDEX Parent,
529     IN HCELL_INDEX Child
530 );
531 
532 BOOLEAN
533 NTAPI
534 CmpRemoveSubKey(
535     IN PHHIVE Hive,
536     IN HCELL_INDEX ParentKey,
537     IN HCELL_INDEX TargetKey
538 );
539 
540 BOOLEAN
541 NTAPI
542 CmpMarkIndexDirty(
543     IN PHHIVE Hive,
544     HCELL_INDEX ParentKey,
545     HCELL_INDEX TargetKey
546 );
547 
548 
549 //
550 // Name Functions
551 //
552 LONG
553 NTAPI
554 CmpCompareCompressedName(
555     IN PCUNICODE_STRING SearchName,
556     IN PWCHAR CompressedName,
557     IN ULONG NameLength
558 );
559 
560 USHORT
561 NTAPI
562 CmpNameSize(
563     IN PHHIVE Hive,
564     IN PCUNICODE_STRING Name
565 );
566 
567 USHORT
568 NTAPI
569 CmpCompressedNameSize(
570     IN PWCHAR Name,
571     IN ULONG Length
572 );
573 
574 USHORT
575 NTAPI
576 CmpCopyName(
577     IN PHHIVE Hive,
578     OUT PWCHAR Destination,
579     IN PCUNICODE_STRING Source
580 );
581 
582 VOID
583 NTAPI
584 CmpCopyCompressedName(
585     OUT PWCHAR Destination,
586     IN ULONG DestinationLength,
587     IN PWCHAR Source,
588     IN ULONG SourceLength
589 );
590 
591 BOOLEAN
592 NTAPI
593 CmpFindNameInList(
594     IN PHHIVE Hive,
595     IN PCHILD_LIST ChildList,
596     IN PCUNICODE_STRING Name,
597     OUT PULONG ChildIndex OPTIONAL,
598     OUT PHCELL_INDEX CellIndex
599 );
600 
601 
602 //
603 // Cell Value Routines
604 //
605 HCELL_INDEX
606 NTAPI
607 CmpFindValueByName(
608     IN PHHIVE Hive,
609     IN PCM_KEY_NODE KeyNode,
610     IN PCUNICODE_STRING Name
611 );
612 
613 PCELL_DATA
614 NTAPI
615 CmpValueToData(
616     IN PHHIVE Hive,
617     IN PCM_KEY_VALUE Value,
618     OUT PULONG Length
619 );
620 
621 NTSTATUS
622 NTAPI
623 CmpSetValueDataNew(
624     IN PHHIVE Hive,
625     IN PVOID Data,
626     IN ULONG DataSize,
627     IN HSTORAGE_TYPE StorageType,
628     IN HCELL_INDEX ValueCell,
629     OUT PHCELL_INDEX DataCell
630 );
631 
632 NTSTATUS
633 NTAPI
634 CmpAddValueToList(
635     IN PHHIVE Hive,
636     IN HCELL_INDEX ValueCell,
637     IN ULONG Index,
638     IN HSTORAGE_TYPE StorageType,
639     IN OUT PCHILD_LIST ChildList
640 );
641 
642 BOOLEAN
643 NTAPI
644 CmpFreeValue(
645     IN PHHIVE Hive,
646     IN HCELL_INDEX Cell
647 );
648 
649 BOOLEAN
650 NTAPI
651 CmpMarkValueDataDirty(
652     IN PHHIVE Hive,
653     IN PCM_KEY_VALUE Value
654 );
655 
656 BOOLEAN
657 NTAPI
658 CmpFreeValueData(
659     IN PHHIVE Hive,
660     IN HCELL_INDEX DataCell,
661     IN ULONG DataLength
662 );
663 
664 NTSTATUS
665 NTAPI
666 CmpRemoveValueFromList(
667     IN PHHIVE Hive,
668     IN ULONG Index,
669     IN OUT PCHILD_LIST ChildList
670 );
671 
672 BOOLEAN
673 NTAPI
674 CmpGetValueData(
675     IN PHHIVE Hive,
676     IN PCM_KEY_VALUE Value,
677     OUT PULONG Length,
678     OUT PVOID *Buffer,
679     OUT PBOOLEAN BufferAllocated,
680     OUT PHCELL_INDEX CellToRelease
681 );
682 
683 NTSTATUS
684 NTAPI
685 CmpCopyKeyValueList(
686     IN PHHIVE SourceHive,
687     IN PCHILD_LIST SrcValueList,
688     IN PHHIVE DestinationHive,
689     IN OUT PCHILD_LIST DestValueList,
690     IN HSTORAGE_TYPE StorageType
691 );
692 
693 NTSTATUS
694 NTAPI
695 CmpFreeKeyByCell(
696     IN PHHIVE Hive,
697     IN HCELL_INDEX Cell,
698     IN BOOLEAN Unlink
699 );
700 
701 VOID
702 NTAPI
703 CmpRemoveSecurityCellList(
704     IN PHHIVE Hive,
705     IN HCELL_INDEX SecurityCell
706 );
707 
708 VOID
709 NTAPI
710 CmpFreeSecurityDescriptor(
711     IN PHHIVE Hive,
712     IN HCELL_INDEX Cell
713 );
714 
715 /******************************************************************************/
716 
717 /* To be implemented by the user of this library */
718 PVOID
719 NTAPI
720 CmpAllocate(
721     IN SIZE_T Size,
722     IN BOOLEAN Paged,
723     IN ULONG Tag
724 );
725 
726 VOID
727 NTAPI
728 CmpFree(
729     IN PVOID Ptr,
730     IN ULONG Quota
731 );
732 
733 #endif /* _CMLIB_H_ */
734