xref: /reactos/sdk/lib/cmlib/cmlib.h (revision bf8a7d2d)
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     VOID
85     NTAPI
86     KeBugCheckEx(
87         IN ULONG BugCheckCode,
88         IN ULONG_PTR BugCheckParameter1,
89         IN ULONG_PTR BugCheckParameter2,
90         IN ULONG_PTR BugCheckParameter3,
91         IN ULONG_PTR BugCheckParameter4);
92 
93     VOID NTAPI
94     KeQuerySystemTime(
95         OUT PLARGE_INTEGER CurrentTime);
96 
97     WCHAR NTAPI
98     RtlUpcaseUnicodeChar(
99         IN WCHAR Source);
100 
101     VOID NTAPI
102     RtlInitializeBitMap(
103         IN PRTL_BITMAP BitMapHeader,
104         IN PULONG BitMapBuffer,
105         IN ULONG SizeOfBitMap);
106 
107     ULONG NTAPI
108     RtlFindSetBits(
109         IN PRTL_BITMAP BitMapHeader,
110         IN ULONG NumberToFind,
111         IN ULONG HintIndex);
112 
113     VOID NTAPI
114     RtlSetBits(
115         IN PRTL_BITMAP BitMapHeader,
116         IN ULONG StartingIndex,
117         IN ULONG NumberToSet);
118 
119     VOID NTAPI
120     RtlClearAllBits(
121         IN PRTL_BITMAP BitMapHeader);
122 
123     #define RtlCheckBit(BMH,BP) (((((PLONG)(BMH)->Buffer)[(BP) / 32]) >> ((BP) % 32)) & 0x1)
124     #define UNREFERENCED_PARAMETER(P) {(P)=(P);}
125 
126     #define PKTHREAD PVOID
127     #define PKGUARDED_MUTEX PVOID
128     #define PERESOURCE PVOID
129     #define PFILE_OBJECT PVOID
130     #define PKEVENT PVOID
131     #define PWORK_QUEUE_ITEM PVOID
132     #define EX_PUSH_LOCK PULONG_PTR
133 
134     // Definitions copied from <ntifs.h>
135     // We only want to include host headers, so we define them manually
136 
137     typedef USHORT SECURITY_DESCRIPTOR_CONTROL, *PSECURITY_DESCRIPTOR_CONTROL;
138 
139     typedef struct _SECURITY_DESCRIPTOR_RELATIVE
140     {
141         UCHAR Revision;
142         UCHAR Sbz1;
143         SECURITY_DESCRIPTOR_CONTROL Control;
144         ULONG Owner;
145         ULONG Group;
146         ULONG Sacl;
147         ULONG Dacl;
148     } SECURITY_DESCRIPTOR_RELATIVE, *PISECURITY_DESCRIPTOR_RELATIVE;
149 
150     #define CMLTRACE(x, ...)
151     #undef PAGED_CODE
152     #define PAGED_CODE()
153     #define REGISTRY_ERROR                   ((ULONG)0x00000051L)
154 #else
155     //
156     // Debug/Tracing support
157     //
158     #if _CMLIB_DEBUG_
159     #ifdef NEW_DEBUG_SYSTEM_IMPLEMENTED // enable when Debug Filters are implemented
160     #define CMLTRACE DbgPrintEx
161     #else
162     #define CMLTRACE(x, ...)                                 \
163     if (x & CmlibTraceLevel) DbgPrint(__VA_ARGS__)
164     #endif
165     #else
166     #define CMLTRACE(x, ...) DPRINT(__VA_ARGS__)
167     #endif
168 
169     #include <ntdef.h>
170     #include <ntifs.h>
171     #include <bugcodes.h>
172     #undef PAGED_CODE
173     #define PAGED_CODE()
174 
175     /* Prevent inclusion of Windows headers through <wine/unicode.h> */
176     #define _WINDEF_
177     #define _WINBASE_
178     #define _WINNLS_
179 #endif
180 
181 
182 //
183 // These define the Debug Masks Supported
184 //
185 #define CMLIB_HCELL_DEBUG       0x01
186 
187 #ifndef ROUND_UP
188 #define ROUND_UP(a,b)        ((((a)+(b)-1)/(b))*(b))
189 #define ROUND_DOWN(a,b)      (((a)/(b))*(b))
190 #endif
191 
192 //
193 // PAGE_SIZE definition
194 //
195 #ifndef PAGE_SIZE
196 #if defined(TARGET_i386) || defined(TARGET_amd64) || defined(TARGET_arm)
197 #define PAGE_SIZE 0x1000
198 #else
199 #error Local PAGE_SIZE definition required when built as host
200 #endif
201 #endif
202 
203 #define TAG_CM     '  MC'
204 #define TAG_KCB    'bkMC'
205 #define TAG_CMHIVE 'vHMC'
206 #define TAG_CMSD   'DSMC'
207 
208 #define CMAPI NTAPI
209 
210 #include <wine/unicode.h>
211 #include <wchar.h>
212 #include "hivedata.h"
213 #include "cmdata.h"
214 
215 #if defined(_TYPEDEFS_HOST_H) || defined(__FREELDR_H) // || defined(_BLDR_)
216 
217 #define PCM_KEY_SECURITY_CACHE_ENTRY    PVOID
218 #define PCM_KEY_CONTROL_BLOCK           PVOID
219 #define PCM_CELL_REMAP_BLOCK            PVOID
220 
221 // See also ntoskrnl/include/internal/cm.h
222 #define CMP_SECURITY_HASH_LISTS         64
223 
224 // #endif // Commented out until one finds a way to properly include
225           // this header in freeldr and in ntoskrnl.
226 
227 //
228 // Use Count Log and Entry
229 //
230 typedef struct _CM_USE_COUNT_LOG_ENTRY
231 {
232     HCELL_INDEX Cell;
233     PVOID Stack[7];
234 } CM_USE_COUNT_LOG_ENTRY, *PCM_USE_COUNT_LOG_ENTRY;
235 
236 typedef struct _CM_USE_COUNT_LOG
237 {
238     USHORT Next;
239     USHORT Size;
240     CM_USE_COUNT_LOG_ENTRY Log[32];
241 } CM_USE_COUNT_LOG, *PCM_USE_COUNT_LOG;
242 
243 //
244 // Configuration Manager Hive Structure
245 //
246 typedef struct _CMHIVE
247 {
248     HHIVE Hive;
249     HANDLE FileHandles[HFILE_TYPE_MAX];
250     LIST_ENTRY NotifyList;
251     LIST_ENTRY HiveList;
252     EX_PUSH_LOCK HiveLock;
253     PKTHREAD HiveLockOwner;
254     PKGUARDED_MUTEX ViewLock;
255     PKTHREAD ViewLockOwner;
256     EX_PUSH_LOCK WriterLock;
257     PKTHREAD WriterLockOwner;
258     PERESOURCE FlusherLock;
259     EX_PUSH_LOCK SecurityLock;
260     PKTHREAD HiveSecurityLockOwner;
261     LIST_ENTRY LRUViewListHead;
262     LIST_ENTRY PinViewListHead;
263     PFILE_OBJECT FileObject;
264     UNICODE_STRING FileFullPath;
265     UNICODE_STRING FileUserName;
266     USHORT MappedViews;
267     USHORT PinnedViews;
268     ULONG UseCount;
269     ULONG SecurityCount;
270     ULONG SecurityCacheSize;
271     LONG SecurityHitHint;
272     PCM_KEY_SECURITY_CACHE_ENTRY SecurityCache;
273     LIST_ENTRY SecurityHash[CMP_SECURITY_HASH_LISTS];
274     PKEVENT UnloadEvent;
275     PCM_KEY_CONTROL_BLOCK RootKcb;
276     BOOLEAN Frozen;
277     PWORK_QUEUE_ITEM UnloadWorkItem;
278     BOOLEAN GrowOnlyMode;
279     ULONG GrowOffset;
280     LIST_ENTRY KcbConvertListHead;
281     LIST_ENTRY KnodeConvertListHead;
282     PCM_CELL_REMAP_BLOCK CellRemapArray;
283     CM_USE_COUNT_LOG UseCountLog;
284     CM_USE_COUNT_LOG LockHiveLog;
285     ULONG Flags;
286     LIST_ENTRY TrustClassEntry;
287     ULONG FlushCount;
288     BOOLEAN HiveIsLoading;
289     PKTHREAD CreatorOwner;
290 } CMHIVE, *PCMHIVE;
291 
292 #endif // See comment above
293 
294 typedef struct _HV_HIVE_CELL_PAIR
295 {
296     PHHIVE Hive;
297     HCELL_INDEX Cell;
298 } HV_HIVE_CELL_PAIR, *PHV_HIVE_CELL_PAIR;
299 
300 #define STATIC_CELL_PAIR_COUNT 4
301 typedef struct _HV_TRACK_CELL_REF
302 {
303     USHORT Count;
304     USHORT Max;
305     PHV_HIVE_CELL_PAIR CellArray;
306     HV_HIVE_CELL_PAIR StaticArray[STATIC_CELL_PAIR_COUNT];
307     USHORT StaticCount;
308 } HV_TRACK_CELL_REF, *PHV_TRACK_CELL_REF;
309 
310 extern ULONG CmlibTraceLevel;
311 
312 //
313 // Hack since bigkeys are not yet supported
314 //
315 #define ASSERT_VALUE_BIG(h, s)                          \
316     ASSERTMSG("Big keys not supported!\n", !CmpIsKeyValueBig(h, s));
317 
318 //
319 // Returns whether or not this is a small valued key
320 //
321 static inline
322 BOOLEAN
323 CmpIsKeyValueSmall(OUT PULONG RealLength,
324                    IN ULONG Length)
325 {
326     /* Check if the length has the special size value */
327     if (Length >= CM_KEY_VALUE_SPECIAL_SIZE)
328     {
329         /* It does, so this is a small key: return the real length */
330         *RealLength = Length - CM_KEY_VALUE_SPECIAL_SIZE;
331         return TRUE;
332     }
333 
334     /* This is not a small key, return the length we read */
335     *RealLength = Length;
336     return FALSE;
337 }
338 
339 //
340 // Returns whether or not this is a big valued key
341 //
342 static inline
343 BOOLEAN
344 CmpIsKeyValueBig(IN PHHIVE Hive,
345                  IN ULONG Length)
346 {
347     /* Check if the hive is XP Beta 1 or newer */
348     if (Hive->Version >= HSYS_WHISTLER_BETA1)
349     {
350         /* Check if the key length is valid for a big value key */
351         if ((Length < CM_KEY_VALUE_SPECIAL_SIZE) && (Length > CM_KEY_VALUE_BIG))
352         {
353             /* Yes, this value is big */
354             return TRUE;
355         }
356     }
357 
358     /* Not a big value key */
359     return FALSE;
360 }
361 
362 /*
363  * Public Hive functions.
364  */
365 NTSTATUS CMAPI
366 HvInitialize(
367     PHHIVE RegistryHive,
368     ULONG OperationType,
369     ULONG HiveFlags,
370     ULONG FileType,
371     PVOID HiveData OPTIONAL,
372     PALLOCATE_ROUTINE Allocate,
373     PFREE_ROUTINE Free,
374     PFILE_SET_SIZE_ROUTINE FileSetSize,
375     PFILE_WRITE_ROUTINE FileWrite,
376     PFILE_READ_ROUTINE FileRead,
377     PFILE_FLUSH_ROUTINE FileFlush,
378     ULONG Cluster OPTIONAL,
379     PCUNICODE_STRING FileName OPTIONAL);
380 
381 VOID CMAPI
382 HvFree(
383    PHHIVE RegistryHive);
384 
385 PVOID CMAPI
386 HvGetCell(
387    PHHIVE RegistryHive,
388    HCELL_INDEX CellOffset);
389 
390 #define HvReleaseCell(h, c)             \
391 do {                                    \
392     if ((h)->ReleaseCellRoutine)        \
393         (h)->ReleaseCellRoutine(h, c);  \
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 PHBIN CMAPI
470 HvpAddBin(
471    PHHIVE RegistryHive,
472    ULONG Size,
473    HSTORAGE_TYPE Storage);
474 
475 NTSTATUS CMAPI
476 HvpCreateHiveFreeCellList(
477    PHHIVE Hive);
478 
479 ULONG CMAPI
480 HvpHiveHeaderChecksum(
481    PHBASE_BLOCK HiveHeader);
482 
483 
484 /* Old-style Public "Cmlib" functions */
485 
486 BOOLEAN CMAPI
487 CmCreateRootNode(
488    PHHIVE Hive,
489    PCWSTR Name);
490 
491 VOID CMAPI
492 CmPrepareHive(
493    PHHIVE RegistryHive);
494 
495 
496 /* NT-style Public Cm functions */
497 
498 //
499 // Cell Index Routines
500 //
501 HCELL_INDEX
502 NTAPI
503 CmpFindSubKeyByName(
504     IN PHHIVE Hive,
505     IN PCM_KEY_NODE Parent,
506     IN PCUNICODE_STRING SearchName
507 );
508 
509 HCELL_INDEX
510 NTAPI
511 CmpFindSubKeyByNumber(
512     IN PHHIVE Hive,
513     IN PCM_KEY_NODE Node,
514     IN ULONG Number
515 );
516 
517 ULONG
518 NTAPI
519 CmpComputeHashKey(
520     IN ULONG Hash,
521     IN PCUNICODE_STRING Name,
522     IN BOOLEAN AllowSeparators
523 );
524 
525 BOOLEAN
526 NTAPI
527 CmpAddSubKey(
528     IN PHHIVE Hive,
529     IN HCELL_INDEX Parent,
530     IN HCELL_INDEX Child
531 );
532 
533 BOOLEAN
534 NTAPI
535 CmpRemoveSubKey(
536     IN PHHIVE Hive,
537     IN HCELL_INDEX ParentKey,
538     IN HCELL_INDEX TargetKey
539 );
540 
541 BOOLEAN
542 NTAPI
543 CmpMarkIndexDirty(
544     IN PHHIVE Hive,
545     HCELL_INDEX ParentKey,
546     HCELL_INDEX TargetKey
547 );
548 
549 
550 //
551 // Name Functions
552 //
553 LONG
554 NTAPI
555 CmpCompareCompressedName(
556     IN PCUNICODE_STRING SearchName,
557     IN PWCHAR CompressedName,
558     IN ULONG NameLength
559 );
560 
561 USHORT
562 NTAPI
563 CmpNameSize(
564     IN PHHIVE Hive,
565     IN PUNICODE_STRING Name
566 );
567 
568 USHORT
569 NTAPI
570 CmpCompressedNameSize(
571     IN PWCHAR Name,
572     IN ULONG Length
573 );
574 
575 USHORT
576 NTAPI
577 CmpCopyName(
578     IN PHHIVE Hive,
579     OUT PWCHAR Destination,
580     IN PUNICODE_STRING Source
581 );
582 
583 VOID
584 NTAPI
585 CmpCopyCompressedName(
586     OUT PWCHAR Destination,
587     IN ULONG DestinationLength,
588     IN PWCHAR Source,
589     IN ULONG SourceLength
590 );
591 
592 BOOLEAN
593 NTAPI
594 CmpFindNameInList(
595     IN PHHIVE Hive,
596     IN PCHILD_LIST ChildList,
597     IN PUNICODE_STRING Name,
598     OUT PULONG ChildIndex OPTIONAL,
599     OUT PHCELL_INDEX CellIndex
600 );
601 
602 
603 //
604 // Cell Value Routines
605 //
606 HCELL_INDEX
607 NTAPI
608 CmpFindValueByName(
609     IN PHHIVE Hive,
610     IN PCM_KEY_NODE KeyNode,
611     IN PUNICODE_STRING Name
612 );
613 
614 PCELL_DATA
615 NTAPI
616 CmpValueToData(
617     IN PHHIVE Hive,
618     IN PCM_KEY_VALUE Value,
619     OUT PULONG Length
620 );
621 
622 NTSTATUS
623 NTAPI
624 CmpSetValueDataNew(
625     IN PHHIVE Hive,
626     IN PVOID Data,
627     IN ULONG DataSize,
628     IN HSTORAGE_TYPE StorageType,
629     IN HCELL_INDEX ValueCell,
630     OUT PHCELL_INDEX DataCell
631 );
632 
633 NTSTATUS
634 NTAPI
635 CmpAddValueToList(
636     IN PHHIVE Hive,
637     IN HCELL_INDEX ValueCell,
638     IN ULONG Index,
639     IN HSTORAGE_TYPE StorageType,
640     IN OUT PCHILD_LIST ChildList
641 );
642 
643 BOOLEAN
644 NTAPI
645 CmpFreeValue(
646     IN PHHIVE Hive,
647     IN HCELL_INDEX Cell
648 );
649 
650 BOOLEAN
651 NTAPI
652 CmpMarkValueDataDirty(
653     IN PHHIVE Hive,
654     IN PCM_KEY_VALUE Value
655 );
656 
657 BOOLEAN
658 NTAPI
659 CmpFreeValueData(
660     IN PHHIVE Hive,
661     IN HCELL_INDEX DataCell,
662     IN ULONG DataLength
663 );
664 
665 NTSTATUS
666 NTAPI
667 CmpRemoveValueFromList(
668     IN PHHIVE Hive,
669     IN ULONG Index,
670     IN OUT PCHILD_LIST ChildList
671 );
672 
673 BOOLEAN
674 NTAPI
675 CmpGetValueData(
676     IN PHHIVE Hive,
677     IN PCM_KEY_VALUE Value,
678     OUT PULONG Length,
679     OUT PVOID *Buffer,
680     OUT PBOOLEAN BufferAllocated,
681     OUT PHCELL_INDEX CellToRelease
682 );
683 
684 NTSTATUS
685 NTAPI
686 CmpCopyKeyValueList(
687     IN PHHIVE SourceHive,
688     IN PCHILD_LIST SrcValueList,
689     IN PHHIVE DestinationHive,
690     IN OUT PCHILD_LIST DestValueList,
691     IN HSTORAGE_TYPE StorageType
692 );
693 
694 NTSTATUS
695 NTAPI
696 CmpFreeKeyByCell(
697     IN PHHIVE Hive,
698     IN HCELL_INDEX Cell,
699     IN BOOLEAN Unlink
700 );
701 
702 VOID
703 NTAPI
704 CmpRemoveSecurityCellList(
705     IN PHHIVE Hive,
706     IN HCELL_INDEX SecurityCell
707 );
708 
709 VOID
710 NTAPI
711 CmpFreeSecurityDescriptor(
712     IN PHHIVE Hive,
713     IN HCELL_INDEX Cell
714 );
715 
716 /******************************************************************************/
717 
718 /* To be implemented by the user of this library */
719 PVOID
720 NTAPI
721 CmpAllocate(
722     IN SIZE_T Size,
723     IN BOOLEAN Paged,
724     IN ULONG Tag
725 );
726 
727 VOID
728 NTAPI
729 CmpFree(
730     IN PVOID Ptr,
731     IN ULONG Quota
732 );
733 
734 #endif /* _CMLIB_H_ */
735