xref: /reactos/sdk/lib/cmlib/cmlib.h (revision d6002f94)
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(__FREELDR_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 freeldr 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 PVOID CMAPI
388 HvGetCell(
389    PHHIVE RegistryHive,
390    HCELL_INDEX CellOffset);
391 
392 #define HvReleaseCell(h, c)             \
393 do {                                    \
394     if ((h)->ReleaseCellRoutine)        \
395         (h)->ReleaseCellRoutine(h, c);  \
396 } while(0)
397 
398 LONG CMAPI
399 HvGetCellSize(
400    PHHIVE RegistryHive,
401    PVOID Cell);
402 
403 HCELL_INDEX CMAPI
404 HvAllocateCell(
405    PHHIVE RegistryHive,
406    ULONG Size,
407    HSTORAGE_TYPE Storage,
408    IN HCELL_INDEX Vicinity);
409 
410 BOOLEAN CMAPI
411 HvIsCellAllocated(
412     IN PHHIVE RegistryHive,
413     IN HCELL_INDEX CellIndex
414 );
415 
416 HCELL_INDEX CMAPI
417 HvReallocateCell(
418    PHHIVE RegistryHive,
419    HCELL_INDEX CellOffset,
420    ULONG Size);
421 
422 VOID CMAPI
423 HvFreeCell(
424    PHHIVE RegistryHive,
425    HCELL_INDEX CellOffset);
426 
427 BOOLEAN CMAPI
428 HvMarkCellDirty(
429    PHHIVE RegistryHive,
430    HCELL_INDEX CellOffset,
431    BOOLEAN HoldingLock);
432 
433 BOOLEAN CMAPI
434 HvIsCellDirty(
435     IN PHHIVE Hive,
436     IN HCELL_INDEX Cell
437 );
438 
439 BOOLEAN
440 CMAPI
441 HvHiveWillShrink(
442     IN PHHIVE RegistryHive
443 );
444 
445 BOOLEAN CMAPI
446 HvSyncHive(
447    PHHIVE RegistryHive);
448 
449 BOOLEAN CMAPI
450 HvWriteHive(
451    PHHIVE RegistryHive);
452 
453 BOOLEAN
454 CMAPI
455 HvTrackCellRef(
456     IN OUT PHV_TRACK_CELL_REF CellRef,
457     IN PHHIVE Hive,
458     IN HCELL_INDEX Cell
459 );
460 
461 VOID
462 CMAPI
463 HvReleaseFreeCellRefArray(
464     IN OUT PHV_TRACK_CELL_REF CellRef
465 );
466 
467 /*
468  * Private functions.
469  */
470 
471 PHBIN CMAPI
472 HvpAddBin(
473    PHHIVE RegistryHive,
474    ULONG Size,
475    HSTORAGE_TYPE Storage);
476 
477 NTSTATUS CMAPI
478 HvpCreateHiveFreeCellList(
479    PHHIVE Hive);
480 
481 ULONG CMAPI
482 HvpHiveHeaderChecksum(
483    PHBASE_BLOCK HiveHeader);
484 
485 
486 /* Old-style Public "Cmlib" functions */
487 
488 BOOLEAN CMAPI
489 CmCreateRootNode(
490    PHHIVE Hive,
491    PCWSTR Name);
492 
493 VOID CMAPI
494 CmPrepareHive(
495    PHHIVE RegistryHive);
496 
497 
498 /* NT-style Public Cm functions */
499 
500 //
501 // Cell Index Routines
502 //
503 HCELL_INDEX
504 NTAPI
505 CmpFindSubKeyByName(
506     IN PHHIVE Hive,
507     IN PCM_KEY_NODE Parent,
508     IN PCUNICODE_STRING SearchName
509 );
510 
511 HCELL_INDEX
512 NTAPI
513 CmpFindSubKeyByNumber(
514     IN PHHIVE Hive,
515     IN PCM_KEY_NODE Node,
516     IN ULONG Number
517 );
518 
519 ULONG
520 NTAPI
521 CmpComputeHashKey(
522     IN ULONG Hash,
523     IN PCUNICODE_STRING Name,
524     IN BOOLEAN AllowSeparators
525 );
526 
527 BOOLEAN
528 NTAPI
529 CmpAddSubKey(
530     IN PHHIVE Hive,
531     IN HCELL_INDEX Parent,
532     IN HCELL_INDEX Child
533 );
534 
535 BOOLEAN
536 NTAPI
537 CmpRemoveSubKey(
538     IN PHHIVE Hive,
539     IN HCELL_INDEX ParentKey,
540     IN HCELL_INDEX TargetKey
541 );
542 
543 BOOLEAN
544 NTAPI
545 CmpMarkIndexDirty(
546     IN PHHIVE Hive,
547     HCELL_INDEX ParentKey,
548     HCELL_INDEX TargetKey
549 );
550 
551 
552 //
553 // Name Functions
554 //
555 LONG
556 NTAPI
557 CmpCompareCompressedName(
558     IN PCUNICODE_STRING SearchName,
559     IN PWCHAR CompressedName,
560     IN ULONG NameLength
561 );
562 
563 USHORT
564 NTAPI
565 CmpNameSize(
566     IN PHHIVE Hive,
567     IN PUNICODE_STRING Name
568 );
569 
570 USHORT
571 NTAPI
572 CmpCompressedNameSize(
573     IN PWCHAR Name,
574     IN ULONG Length
575 );
576 
577 USHORT
578 NTAPI
579 CmpCopyName(
580     IN PHHIVE Hive,
581     OUT PWCHAR Destination,
582     IN PUNICODE_STRING Source
583 );
584 
585 VOID
586 NTAPI
587 CmpCopyCompressedName(
588     OUT PWCHAR Destination,
589     IN ULONG DestinationLength,
590     IN PWCHAR Source,
591     IN ULONG SourceLength
592 );
593 
594 BOOLEAN
595 NTAPI
596 CmpFindNameInList(
597     IN PHHIVE Hive,
598     IN PCHILD_LIST ChildList,
599     IN PUNICODE_STRING Name,
600     OUT PULONG ChildIndex OPTIONAL,
601     OUT PHCELL_INDEX CellIndex
602 );
603 
604 
605 //
606 // Cell Value Routines
607 //
608 HCELL_INDEX
609 NTAPI
610 CmpFindValueByName(
611     IN PHHIVE Hive,
612     IN PCM_KEY_NODE KeyNode,
613     IN PUNICODE_STRING Name
614 );
615 
616 PCELL_DATA
617 NTAPI
618 CmpValueToData(
619     IN PHHIVE Hive,
620     IN PCM_KEY_VALUE Value,
621     OUT PULONG Length
622 );
623 
624 NTSTATUS
625 NTAPI
626 CmpSetValueDataNew(
627     IN PHHIVE Hive,
628     IN PVOID Data,
629     IN ULONG DataSize,
630     IN HSTORAGE_TYPE StorageType,
631     IN HCELL_INDEX ValueCell,
632     OUT PHCELL_INDEX DataCell
633 );
634 
635 NTSTATUS
636 NTAPI
637 CmpAddValueToList(
638     IN PHHIVE Hive,
639     IN HCELL_INDEX ValueCell,
640     IN ULONG Index,
641     IN HSTORAGE_TYPE StorageType,
642     IN OUT PCHILD_LIST ChildList
643 );
644 
645 BOOLEAN
646 NTAPI
647 CmpFreeValue(
648     IN PHHIVE Hive,
649     IN HCELL_INDEX Cell
650 );
651 
652 BOOLEAN
653 NTAPI
654 CmpMarkValueDataDirty(
655     IN PHHIVE Hive,
656     IN PCM_KEY_VALUE Value
657 );
658 
659 BOOLEAN
660 NTAPI
661 CmpFreeValueData(
662     IN PHHIVE Hive,
663     IN HCELL_INDEX DataCell,
664     IN ULONG DataLength
665 );
666 
667 NTSTATUS
668 NTAPI
669 CmpRemoveValueFromList(
670     IN PHHIVE Hive,
671     IN ULONG Index,
672     IN OUT PCHILD_LIST ChildList
673 );
674 
675 BOOLEAN
676 NTAPI
677 CmpGetValueData(
678     IN PHHIVE Hive,
679     IN PCM_KEY_VALUE Value,
680     OUT PULONG Length,
681     OUT PVOID *Buffer,
682     OUT PBOOLEAN BufferAllocated,
683     OUT PHCELL_INDEX CellToRelease
684 );
685 
686 NTSTATUS
687 NTAPI
688 CmpCopyKeyValueList(
689     IN PHHIVE SourceHive,
690     IN PCHILD_LIST SrcValueList,
691     IN PHHIVE DestinationHive,
692     IN OUT PCHILD_LIST DestValueList,
693     IN HSTORAGE_TYPE StorageType
694 );
695 
696 NTSTATUS
697 NTAPI
698 CmpFreeKeyByCell(
699     IN PHHIVE Hive,
700     IN HCELL_INDEX Cell,
701     IN BOOLEAN Unlink
702 );
703 
704 VOID
705 NTAPI
706 CmpRemoveSecurityCellList(
707     IN PHHIVE Hive,
708     IN HCELL_INDEX SecurityCell
709 );
710 
711 VOID
712 NTAPI
713 CmpFreeSecurityDescriptor(
714     IN PHHIVE Hive,
715     IN HCELL_INDEX Cell
716 );
717 
718 /******************************************************************************/
719 
720 /* To be implemented by the user of this library */
721 PVOID
722 NTAPI
723 CmpAllocate(
724     IN SIZE_T Size,
725     IN BOOLEAN Paged,
726     IN ULONG Tag
727 );
728 
729 VOID
730 NTAPI
731 CmpFree(
732     IN PVOID Ptr,
733     IN ULONG Quota
734 );
735 
736 #endif /* _CMLIB_H_ */
737