e49bd384627ac9abba03a325f0364c55188b72cb
[reactos.git] / sdk / lib / cmlib / cmlib.h
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!", !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,
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 ULONG 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 ULONG Type,
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_ */