xref: /reactos/ntoskrnl/include/internal/cm.h (revision 10e7643c)
1 /*
2  * PROJECT:         ReactOS Kernel
3  * LICENSE:         GPL - See COPYING in the top level directory
4  * FILE:            ntoskrnl/include/internal/cm.h
5  * PURPOSE:         Internal header for the Configuration Manager
6  * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
7  */
8 
9 #pragma once
10 
11 #include <cmlib.h>
12 #include <cmreslist.h>
13 #include "cmboot.h"
14 
15 //
16 // Define this if you want debugging support
17 //
18 #define _CM_DEBUG_                                      0x00
19 
20 //
21 // These define the Debug Masks Supported
22 //
23 #define CM_HANDLE_DEBUG                                 0x01
24 #define CM_NAMESPACE_DEBUG                              0x02
25 #define CM_SECURITY_DEBUG                               0x04
26 #define CM_REFERENCE_DEBUG                              0x08
27 #define CM_CALLBACK_DEBUG                               0x10
28 
29 //
30 // Debug/Tracing support
31 //
32 #if _CM_DEBUG_
33 #ifdef NEW_DEBUG_SYSTEM_IMPLEMENTED // enable when Debug Filters are implemented
34 #define CMTRACE DbgPrintEx
35 #else
36 #define CMTRACE(x, ...)                                 \
37     if (x & CmpTraceLevel) DbgPrint(__VA_ARGS__)
38 #endif
39 #else
40 #define CMTRACE(x, fmt, ...) DPRINT(fmt, ##__VA_ARGS__)
41 #endif
42 
43 //
44 // CM_KEY_CONTROL_BLOCK Signatures
45 //
46 #define CM_KCB_SIGNATURE                                'bKmC'
47 #define CM_KCB_INVALID_SIGNATURE                        '4FmC'
48 
49 //
50 // CM_KEY_CONTROL_BLOCK ExtFlags
51 //
52 #define CM_KCB_NO_SUBKEY                                0x01
53 #define CM_KCB_SUBKEY_ONE                               0x02
54 #define CM_KCB_SUBKEY_HINT                              0x04
55 #define CM_KCB_SYM_LINK_FOUND                           0x08
56 #define CM_KCB_KEY_NON_EXIST                            0x10
57 #define CM_KCB_NO_DELAY_CLOSE                           0x20
58 #define CM_KCB_INVALID_CACHED_INFO                      0x40
59 #define CM_KCB_READ_ONLY_KEY                            0x80
60 
61 //
62 // CM_KEY_BODY Types
63 //
64 #define CM_KEY_BODY_TYPE                                0x6B793032  // 'ky02'
65 
66 //
67 // Number of various lists and hashes
68 //
69 #if 0 // See sdk/lib/cmlib/cmlib.h
70 #define CMP_SECURITY_HASH_LISTS                         64
71 #endif
72 #define CMP_MAX_CALLBACKS                               100
73 
74 //
75 // Hashing Constants
76 //
77 #define CMP_HASH_IRRATIONAL                             314159269
78 #define CMP_HASH_PRIME                                  1000000007
79 
80 //
81 // CmpCreateKeyControlBlock Flags
82 //
83 #define CMP_CREATE_FAKE_KCB                             0x1
84 #define CMP_LOCK_HASHES_FOR_KCB                         0x2
85 
86 //
87 // CmpDoCreate and CmpDoOpen flags
88 //
89 #define CMP_CREATE_KCB_KCB_LOCKED                       0x2
90 #define CMP_OPEN_KCB_NO_CREATE                          0x4
91 
92 //
93 // EnlistKeyBodyWithKCB Flags
94 //
95 #define CMP_ENLIST_KCB_LOCKED_SHARED                    0x1
96 #define CMP_ENLIST_KCB_LOCKED_EXCLUSIVE                 0x2
97 
98 //
99 // CmpBuildAndLockKcbArray & CmpLockKcbArray Flags
100 //
101 #define CMP_LOCK_KCB_ARRAY_EXCLUSIVE                    0x1
102 #define CMP_LOCK_KCB_ARRAY_SHARED                       0x2
103 
104 //
105 // Unload Flags
106 //
107 #define CMP_UNLOCK_KCB_LOCKED                    0x1
108 #define CMP_UNLOCK_REGISTRY_LOCKED               0x2
109 
110 //
111 // Maximum size of Value Cache
112 //
113 #define MAXIMUM_CACHED_DATA                             (2 * PAGE_SIZE)
114 
115 //
116 // Hives to load on startup
117 //
118 #define CM_NUMBER_OF_MACHINE_HIVES                      6
119 
120 //
121 // Number of items that can fit inside an Allocation Page
122 //
123 #define CM_KCBS_PER_PAGE                                \
124     ((PAGE_SIZE - FIELD_OFFSET(CM_ALLOC_PAGE, AllocPage)) / sizeof(CM_KEY_CONTROL_BLOCK))
125 #define CM_DELAYS_PER_PAGE                              \
126     ((PAGE_SIZE - FIELD_OFFSET(CM_ALLOC_PAGE, AllocPage)) / sizeof(CM_DELAY_ALLOC))
127 
128 //
129 // Cache Lookup & KCB Array constructs
130 //
131 #define CMP_SUBKEY_LEVELS_DEPTH_LIMIT   32
132 #define CMP_KCBS_IN_ARRAY_LIMIT         (CMP_SUBKEY_LEVELS_DEPTH_LIMIT + 2)
133 
134 //
135 // Value Search Results
136 //
137 typedef enum _VALUE_SEARCH_RETURN_TYPE
138 {
139     SearchSuccess,
140     SearchNeedExclusiveLock,
141     SearchFail
142 } VALUE_SEARCH_RETURN_TYPE;
143 
144 //
145 // Key Hash
146 //
147 typedef struct _CM_KEY_HASH
148 {
149     ULONG ConvKey;
150     struct _CM_KEY_HASH *NextHash;
151     PHHIVE KeyHive;
152     HCELL_INDEX KeyCell;
153 } CM_KEY_HASH, *PCM_KEY_HASH;
154 
155 //
156 // Key Hash Table Entry
157 //
158 typedef struct _CM_KEY_HASH_TABLE_ENTRY
159 {
160     EX_PUSH_LOCK Lock;
161     PKTHREAD Owner;
162     PCM_KEY_HASH Entry;
163 } CM_KEY_HASH_TABLE_ENTRY, *PCM_KEY_HASH_TABLE_ENTRY;
164 
165 //
166 // Name Hash
167 //
168 typedef struct _CM_NAME_HASH
169 {
170     ULONG ConvKey;
171     struct _CM_NAME_HASH *NextHash;
172     USHORT NameLength;
173     WCHAR Name[ANYSIZE_ARRAY];
174 } CM_NAME_HASH, *PCM_NAME_HASH;
175 
176 //
177 // Name Hash Table Entry
178 //
179 typedef struct _CM_NAME_HASH_TABLE_ENTRY
180 {
181     EX_PUSH_LOCK Lock;
182     PCM_NAME_HASH Entry;
183 } CM_NAME_HASH_TABLE_ENTRY, *PCM_NAME_HASH_TABLE_ENTRY;
184 
185 //
186 // Key Security Cache
187 //
188 typedef struct _CM_KEY_SECURITY_CACHE
189 {
190     HCELL_INDEX Cell;
191     ULONG ConvKey;
192     LIST_ENTRY List;
193     ULONG DescriptorLength;
194     SECURITY_DESCRIPTOR_RELATIVE Descriptor;
195 } CM_KEY_SECURITY_CACHE, *PCM_KEY_SECURITY_CACHE;
196 
197 //
198 // Key Security Cache Entry
199 //
200 typedef struct _CM_KEY_SECURITY_CACHE_ENTRY
201 {
202     HCELL_INDEX Cell;
203     PCM_KEY_SECURITY_CACHE CachedSecurity;
204 } CM_KEY_SECURITY_CACHE_ENTRY, *PCM_KEY_SECURITY_CACHE_ENTRY;
205 
206 //
207 // Cached Child List
208 //
209 typedef struct _CACHED_CHILD_LIST
210 {
211     ULONG Count;
212     union
213     {
214         ULONG ValueList;
215         struct _CM_KEY_CONTROL_BLOCK *RealKcb;
216     };
217 } CACHED_CHILD_LIST, *PCACHED_CHILD_LIST;
218 
219 //
220 // Index Hint Block
221 //
222 typedef struct _CM_INDEX_HINT_BLOCK
223 {
224     ULONG Count;
225     ULONG HashKey[ANYSIZE_ARRAY];
226 } CM_INDEX_HINT_BLOCK, *PCM_INDEX_HINT_BLOCK;
227 
228 //
229 // Key Body
230 //
231 typedef struct _CM_KEY_BODY
232 {
233     ULONG Type;
234     struct _CM_KEY_CONTROL_BLOCK *KeyControlBlock;
235     struct _CM_NOTIFY_BLOCK *NotifyBlock;
236     HANDLE ProcessID;
237     LIST_ENTRY KeyBodyList;
238 
239     /* ReactOS specific -- boolean flag to avoid recursive locking of the KCB */
240     BOOLEAN KcbLocked;
241 } CM_KEY_BODY, *PCM_KEY_BODY;
242 
243 //
244 // Name Control Block (NCB)
245 //
246 typedef struct _CM_NAME_CONTROL_BLOCK
247 {
248     BOOLEAN Compressed;
249     USHORT RefCount;
250     union
251     {
252         CM_NAME_HASH NameHash;
253         struct
254         {
255             ULONG ConvKey;
256             PCM_KEY_HASH NextHash;
257             USHORT NameLength;
258             WCHAR Name[ANYSIZE_ARRAY];
259         };
260     };
261 } CM_NAME_CONTROL_BLOCK, *PCM_NAME_CONTROL_BLOCK;
262 
263 //
264 // Key Control Block (KCB)
265 //
266 typedef struct _CM_KEY_CONTROL_BLOCK
267 {
268     ULONG Signature;
269     ULONG RefCount;
270     struct
271     {
272         ULONG ExtFlags:8;
273         ULONG PrivateAlloc:1;
274         ULONG Delete:1;
275         ULONG DelayedCloseIndex:12;
276         ULONG TotalLevels:10;
277     };
278     union
279     {
280         CM_KEY_HASH KeyHash;
281         struct
282         {
283             ULONG ConvKey;
284             PCM_KEY_HASH NextHash;
285             PHHIVE KeyHive;
286             HCELL_INDEX KeyCell;
287         };
288     };
289     struct _CM_KEY_CONTROL_BLOCK *ParentKcb;
290     PCM_NAME_CONTROL_BLOCK NameBlock;
291     PCM_KEY_SECURITY_CACHE CachedSecurity;
292     CACHED_CHILD_LIST ValueCache;
293     union
294     {
295         PCM_INDEX_HINT_BLOCK IndexHint;
296         ULONG HashKey;
297         ULONG SubKeyCount;
298     };
299     union
300     {
301         LIST_ENTRY KeyBodyListHead;
302         LIST_ENTRY FreeListEntry;
303     };
304     PCM_KEY_BODY KeyBodyArray[4];
305     PVOID DelayCloseEntry;
306     LARGE_INTEGER KcbLastWriteTime;
307     USHORT KcbMaxNameLen;
308     USHORT KcbMaxValueNameLen;
309     ULONG KcbMaxValueDataLen;
310     struct
311     {
312          ULONG KcbUserFlags : 4;
313          ULONG KcbVirtControlFlags : 4;
314          ULONG KcbDebug : 8;
315          ULONG Flags : 16;
316     };
317     ULONG InDelayClose;
318 } CM_KEY_CONTROL_BLOCK, *PCM_KEY_CONTROL_BLOCK;
319 
320 //
321 // Notify Block
322 //
323 typedef struct _CM_NOTIFY_BLOCK
324 {
325     LIST_ENTRY HiveList;
326     LIST_ENTRY PostList;
327     PCM_KEY_CONTROL_BLOCK KeyControlBlock;
328     PCM_KEY_BODY KeyBody;
329     ULONG Filter:29;
330     ULONG WatchTree:30;
331     ULONG NotifyPending:31;
332 } CM_NOTIFY_BLOCK, *PCM_NOTIFY_BLOCK;
333 
334 //
335 // Re-map Block
336 //
337 typedef struct _CM_CELL_REMAP_BLOCK
338 {
339     HCELL_INDEX OldCell;
340     HCELL_INDEX NewCell;
341 } CM_CELL_REMAP_BLOCK, *PCM_CELL_REMAP_BLOCK;
342 
343 //
344 // Allocation Page
345 //
346 typedef struct _CM_ALLOC_PAGE
347 {
348     ULONG FreeCount;
349     ULONG Reserved;
350     PVOID AllocPage;
351 } CM_ALLOC_PAGE, *PCM_ALLOC_PAGE;
352 
353 //
354 // Allocation Page Entry
355 //
356 typedef struct _CM_DELAY_ALLOC
357 {
358     LIST_ENTRY ListEntry;
359     PCM_KEY_CONTROL_BLOCK Kcb;
360 } CM_DELAY_ALLOC, *PCM_DELAY_ALLOC;
361 
362 //
363 // Delayed Close Entry
364 //
365 typedef struct _CM_DELAYED_CLOSE_ENTRY
366 {
367     LIST_ENTRY DelayedLRUList;
368     PCM_KEY_CONTROL_BLOCK KeyControlBlock;
369 } CM_DELAYED_CLOSE_ENTRY, *PCM_DELAYED_CLOSE_ENTRY;
370 
371 //
372 // Delayed KCB Dereference Entry
373 //
374 typedef struct _CM_DELAY_DEREF_KCB_ITEM
375 {
376     LIST_ENTRY ListEntry;
377     PCM_KEY_CONTROL_BLOCK Kcb;
378 } CM_DELAY_DEREF_KCB_ITEM, *PCM_DELAY_DEREF_KCB_ITEM;
379 
380 //
381 // Cached Value Index
382 //
383 typedef struct _CM_CACHED_VALUE_INDEX
384 {
385     HCELL_INDEX CellIndex;
386     union
387     {
388         CELL_DATA CellData;
389         ULONG_PTR List[ANYSIZE_ARRAY];
390     } Data;
391 } CM_CACHED_VALUE_INDEX, *PCM_CACHED_VALUE_INDEX;
392 
393 //
394 // Cached Value
395 //
396 typedef struct _CM_CACHED_VALUE
397 {
398     USHORT DataCacheType;
399     USHORT ValueKeySize;
400     ULONG HashKey;
401     CM_KEY_VALUE KeyValue;
402 } CM_CACHED_VALUE, *PCM_CACHED_VALUE;
403 
404 //
405 // Hive List Entry
406 //
407 typedef struct _HIVE_LIST_ENTRY
408 {
409     PWSTR Name;
410     PWSTR BaseName;
411     PCMHIVE CmHive;
412     ULONG HHiveFlags;
413     ULONG CmHiveFlags;
414     PCMHIVE CmHive2;
415     BOOLEAN ThreadFinished;
416     BOOLEAN ThreadStarted;
417     BOOLEAN Allocate;
418 } HIVE_LIST_ENTRY, *PHIVE_LIST_ENTRY;
419 
420 //
421 // Hash Cache Stack
422 //
423 typedef struct _CM_HASH_CACHE_STACK
424 {
425     UNICODE_STRING NameOfKey;
426     ULONG ConvKey;
427 } CM_HASH_CACHE_STACK, *PCM_HASH_CACHE_STACK;
428 
429 //
430 // Parse context for Key Object
431 //
432 typedef struct _CM_PARSE_CONTEXT
433 {
434     ULONG TitleIndex;
435     UNICODE_STRING Class;
436     ULONG CreateOptions;
437     ULONG Disposition;
438     CM_KEY_REFERENCE ChildHive;
439     HANDLE PredefinedHandle;
440     BOOLEAN CreateLink;
441     BOOLEAN CreateOperation;
442     PCMHIVE OriginatingPoint;
443 } CM_PARSE_CONTEXT, *PCM_PARSE_CONTEXT;
444 
445 //
446 // MultiFunction Adapter Recognizer Structure
447 //
448 typedef struct _CMP_MF_TYPE
449 {
450     PCHAR Identifier;
451     USHORT InterfaceType;
452     USHORT Count;
453 } CMP_MF_TYPE, *PCMP_MF_TYPE;
454 
455 //
456 // System Control Vector
457 //
458 typedef struct _CM_SYSTEM_CONTROL_VECTOR
459 {
460     PWCHAR KeyPath;
461     PWCHAR ValueName;
462     PVOID Buffer;
463     PULONG BufferLength;
464     PULONG Type;
465 } CM_SYSTEM_CONTROL_VECTOR, *PCM_SYSTEM_CONTROL_VECTOR;
466 
467 //
468 // Structure for CmpQueryValueDataFromCache
469 //
470 typedef struct _KEY_VALUE_INFORMATION
471 {
472     union
473     {
474         KEY_VALUE_BASIC_INFORMATION KeyValueBasicInformation;
475         KEY_VALUE_FULL_INFORMATION KeyValueFullInformation;
476         KEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInformation;
477         KEY_VALUE_PARTIAL_INFORMATION_ALIGN64 KeyValuePartialInformationAlign64;
478     };
479 } KEY_VALUE_INFORMATION, *PKEY_VALUE_INFORMATION;
480 
481 typedef struct _KEY_INFORMATION
482 {
483     union
484     {
485         KEY_BASIC_INFORMATION KeyBasicInformation;
486         KEY_FULL_INFORMATION KeyFullInformation;
487         KEY_NODE_INFORMATION KeyNodeInformation;
488     };
489 } KEY_INFORMATION, *PKEY_INFORMATION;
490 
491 ///////////////////////////////////////////////////////////////////////////////
492 //
493 // BUGBUG Old Hive Stuff for Temporary Support
494 //
495 NTSTATUS CmiCallRegisteredCallbacks(IN REG_NOTIFY_CLASS Argument1, IN PVOID Argument2);
496 ///////////////////////////////////////////////////////////////////////////////
497 
498 //
499 // Mapped View Hive Functions
500 //
501 VOID
502 NTAPI
503 CmpInitHiveViewList(
504     IN PCMHIVE Hive
505 );
506 
507 VOID
508 NTAPI
509 CmpDestroyHiveViewList(
510     IN PCMHIVE Hive
511 );
512 
513 //
514 // Security Management Functions
515 //
516 NTSTATUS
517 CmpAssignSecurityDescriptor(
518     IN PCM_KEY_CONTROL_BLOCK Kcb,
519     IN PSECURITY_DESCRIPTOR SecurityDescriptor
520 );
521 
522 //
523 // Security Cache Functions
524 //
525 VOID
526 NTAPI
527 CmpInitSecurityCache(
528     IN PCMHIVE Hive
529 );
530 
531 VOID
532 NTAPI
533 CmpDestroySecurityCache(
534     IN PCMHIVE Hive
535 );
536 
537 //
538 // Value Cache Functions
539 //
540 VALUE_SEARCH_RETURN_TYPE
541 NTAPI
542 CmpFindValueByNameFromCache(
543     IN PCM_KEY_CONTROL_BLOCK Kcb,
544     IN PCUNICODE_STRING Name,
545     OUT PCM_CACHED_VALUE **CachedValue,
546     OUT ULONG *Index,
547     OUT PCM_KEY_VALUE *Value,
548     OUT BOOLEAN *ValueIsCached,
549     OUT PHCELL_INDEX CellToRelease
550 );
551 
552 VALUE_SEARCH_RETURN_TYPE
553 NTAPI
554 CmpQueryKeyValueData(
555     IN PCM_KEY_CONTROL_BLOCK Kcb,
556     IN PCM_CACHED_VALUE *CachedValue,
557     IN PCM_KEY_VALUE ValueKey,
558     IN BOOLEAN ValueIsCached,
559     IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
560     IN PVOID KeyValueInformation,
561     IN ULONG Length,
562     OUT PULONG ResultLength,
563     OUT PNTSTATUS Status
564 );
565 
566 VALUE_SEARCH_RETURN_TYPE
567 NTAPI
568 CmpGetValueListFromCache(
569     IN PCM_KEY_CONTROL_BLOCK Kcb,
570     OUT PCELL_DATA *CellData,
571     OUT BOOLEAN *IndexIsCached,
572     OUT PHCELL_INDEX ValueListToRelease
573 );
574 
575 VALUE_SEARCH_RETURN_TYPE
576 NTAPI
577 CmpGetValueKeyFromCache(
578     IN PCM_KEY_CONTROL_BLOCK Kcb,
579     IN PCELL_DATA CellData,
580     IN ULONG Index,
581     OUT PCM_CACHED_VALUE **CachedValue,
582     OUT PCM_KEY_VALUE *Value,
583     IN BOOLEAN IndexIsCached,
584     OUT BOOLEAN *ValueIsCached,
585     OUT PHCELL_INDEX CellToRelease
586 );
587 
588 VALUE_SEARCH_RETURN_TYPE
589 NTAPI
590 CmpCompareNewValueDataAgainstKCBCache(
591     IN PCM_KEY_CONTROL_BLOCK Kcb,
592     IN PUNICODE_STRING ValueName,
593     IN ULONG Type,
594     IN PVOID Data,
595     IN ULONG DataSize
596 );
597 
598 //
599 // Registry Validation Functions
600 //
601 ULONG
602 NTAPI
603 CmCheckRegistry(
604     IN PCMHIVE Hive,
605     IN ULONG Flags
606 );
607 
608 //
609 // Hive List Routines
610 //
611 BOOLEAN
612 NTAPI
613 CmpGetHiveName(
614     IN  PCMHIVE Hive,
615     OUT PUNICODE_STRING HiveName
616 );
617 
618 NTSTATUS
619 NTAPI
620 CmpAddToHiveFileList(
621     IN PCMHIVE Hive
622 );
623 
624 VOID
625 NTAPI
626 CmpRemoveFromHiveFileList(
627     IN PCMHIVE Hive
628 );
629 
630 //
631 // Quota Routines
632 //
633 VOID
634 NTAPI
635 CmpSetGlobalQuotaAllowed(
636     VOID
637 );
638 
639 //
640 // Notification Routines
641 //
642 VOID
643 NTAPI
644 CmpReportNotify(
645     IN PCM_KEY_CONTROL_BLOCK Kcb,
646     IN PHHIVE Hive,
647     IN HCELL_INDEX Cell,
648     IN ULONG Filter
649 );
650 
651 VOID
652 NTAPI
653 CmpFlushNotify(
654     IN PCM_KEY_BODY KeyBody,
655     IN BOOLEAN LockHeld
656 );
657 
658 CODE_SEG("INIT")
659 VOID
660 NTAPI
661 CmpInitCallback(
662     VOID
663 );
664 
665 //
666 // KCB Cache/Delay Routines
667 //
668 CODE_SEG("INIT")
669 VOID
670 NTAPI
671 CmpInitializeCache(
672     VOID
673 );
674 
675 CODE_SEG("INIT")
676 VOID
677 NTAPI
678 CmpInitCmPrivateDelayAlloc(
679     VOID
680 );
681 
682 CODE_SEG("INIT")
683 VOID
684 NTAPI
685 CmpInitCmPrivateAlloc(
686     VOID
687 );
688 
689 CODE_SEG("INIT")
690 VOID
691 NTAPI
692 CmpInitDelayDerefKCBEngine(
693     VOID
694 );
695 
696 //
697 // Key Object Routines
698 //
699 VOID
700 NTAPI
701 CmpCloseKeyObject(
702     IN PEPROCESS Process OPTIONAL,
703     IN PVOID Object,
704     IN ACCESS_MASK GrantedAccess,
705     IN ULONG ProcessHandleCount,
706     IN ULONG SystemHandleCount
707 );
708 
709 VOID
710 NTAPI
711 CmpDeleteKeyObject(
712     IN PVOID Object
713 );
714 
715 NTSTATUS
716 NTAPI
717 CmpParseKey(
718     IN PVOID ParseObject,
719     IN PVOID ObjectType,
720     IN OUT PACCESS_STATE AccessState,
721     IN KPROCESSOR_MODE AccessMode,
722     IN ULONG Attributes,
723     IN OUT PUNICODE_STRING CompleteName,
724     IN OUT PUNICODE_STRING RemainingName,
725     IN OUT PVOID Context OPTIONAL,
726     IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
727     OUT PVOID *Object
728 );
729 
730 NTSTATUS
731 NTAPI
732 CmpSecurityMethod(
733     IN PVOID Object,
734     IN SECURITY_OPERATION_CODE OperationType,
735     IN PSECURITY_INFORMATION SecurityInformation,
736     IN PSECURITY_DESCRIPTOR SecurityDescriptor,
737     IN OUT PULONG CapturedLength,
738     IN OUT PSECURITY_DESCRIPTOR *ObjectSecurityDescriptor,
739     IN POOL_TYPE PoolType,
740     IN PGENERIC_MAPPING GenericMapping
741 );
742 
743 NTSTATUS
744 NTAPI
745 CmpQueryKeyName(
746     IN PVOID Object,
747     IN BOOLEAN HasObjectName,
748     OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
749     IN ULONG Length,
750     OUT PULONG ReturnLength,
751     IN KPROCESSOR_MODE AccessMode
752 );
753 
754 //
755 // Hive Routines
756 //
757 NTSTATUS
758 NTAPI
759 CmpInitializeHive(
760     OUT PCMHIVE *CmHive,
761     IN ULONG OperationType,
762     IN ULONG HiveFlags,
763     IN ULONG FileType,
764     IN PVOID HiveData OPTIONAL,
765     IN HANDLE Primary,
766     IN HANDLE Log,
767     IN HANDLE External,
768     IN PCUNICODE_STRING FileName OPTIONAL,
769     IN ULONG CheckFlags
770 );
771 
772 NTSTATUS
773 NTAPI
774 CmpDestroyHive(
775     IN PCMHIVE CmHive
776 );
777 
778 PSECURITY_DESCRIPTOR
779 NTAPI
780 CmpHiveRootSecurityDescriptor(
781     VOID
782 );
783 
784 NTSTATUS
785 NTAPI
786 CmpLinkHiveToMaster(
787     IN PUNICODE_STRING LinkName,
788     IN HANDLE RootDirectory,
789     IN PCMHIVE CmHive,
790     IN BOOLEAN Allocate,
791     IN PSECURITY_DESCRIPTOR SecurityDescriptor
792 );
793 
794 NTSTATUS
795 NTAPI
796 CmpOpenHiveFiles(
797     IN PCUNICODE_STRING BaseName,
798     IN PCWSTR Extension OPTIONAL,
799     OUT PHANDLE Primary,
800     OUT PHANDLE Log,
801     OUT PULONG PrimaryDisposition,
802     OUT PULONG LogDisposition,
803     IN BOOLEAN CreateAllowed,
804     IN BOOLEAN MarkAsSystemHive,
805     IN BOOLEAN NoBuffering,
806     OUT PULONG ClusterSize OPTIONAL
807 );
808 
809 VOID
810 NTAPI
811 CmpCloseHiveFiles(
812     IN PCMHIVE Hive
813 );
814 
815 NTSTATUS
816 NTAPI
817 CmpInitHiveFromFile(
818     IN PCUNICODE_STRING HiveName,
819     IN ULONG HiveFlags,
820     OUT PCMHIVE *Hive,
821     IN OUT PBOOLEAN New,
822     IN ULONG CheckFlags
823 );
824 
825 VOID
826 NTAPI
827 CmpInitializeHiveList(
828     VOID
829 );
830 
831 //
832 // Registry Utility Functions
833 //
834 BOOLEAN
835 NTAPI
836 CmpTestRegistryLockExclusive(
837     VOID
838 );
839 
840 BOOLEAN
841 NTAPI
842 CmpTestRegistryLock(
843     VOID
844 );
845 
846 VOID
847 NTAPI
848 CmpLockRegistryExclusive(
849     VOID
850 );
851 
852 VOID
853 NTAPI
854 CmpLockRegistry(
855     VOID
856 );
857 
858 VOID
859 NTAPI
860 CmpUnlockRegistry(
861     VOID
862 );
863 
864 VOID
865 NTAPI
866 CmpLockHiveFlusherExclusive(
867     IN PCMHIVE Hive
868 );
869 
870 VOID
871 NTAPI
872 CmpLockHiveFlusherShared(
873     IN PCMHIVE Hive
874 );
875 
876 BOOLEAN
877 NTAPI
878 CmpTestHiveFlusherLockExclusive(
879     IN PCMHIVE Hive
880 );
881 
882 BOOLEAN
883 NTAPI
884 CmpTestHiveFlusherLockShared(
885     IN PCMHIVE Hive
886 );
887 
888 VOID
889 NTAPI
890 CmpUnlockHiveFlusher(
891     IN PCMHIVE Hive
892 );
893 
894 //
895 // Delay Functions
896 //
897 PVOID
898 NTAPI
899 CmpAllocateDelayItem(
900     VOID
901 );
902 
903 VOID
904 NTAPI
905 CmpFreeDelayItem(
906     PVOID Entry
907 );
908 
909 VOID
910 NTAPI
911 CmpDelayDerefKeyControlBlock(
912     IN PCM_KEY_CONTROL_BLOCK Kcb
913 );
914 
915 VOID
916 NTAPI
917 CmpAddToDelayedClose(
918     IN PCM_KEY_CONTROL_BLOCK Kcb,
919     IN BOOLEAN LockHeldExclusively
920 );
921 
922 VOID
923 NTAPI
924 CmpArmDelayedCloseTimer(
925     VOID
926 );
927 
928 VOID
929 NTAPI
930 CmpRemoveFromDelayedClose(IN PCM_KEY_CONTROL_BLOCK Kcb);
931 
932 CODE_SEG("INIT")
933 VOID
934 NTAPI
935 CmpInitializeDelayedCloseTable(
936     VOID
937 );
938 
939 //
940 // KCB Functions
941 //
942 PCM_KEY_CONTROL_BLOCK
943 NTAPI
944 CmpCreateKeyControlBlock(
945     IN PHHIVE Hive,
946     IN HCELL_INDEX Index,
947     IN PCM_KEY_NODE Node,
948     IN PCM_KEY_CONTROL_BLOCK Parent,
949     IN ULONG Flags,
950     IN PUNICODE_STRING KeyName
951 );
952 
953 PCM_KEY_CONTROL_BLOCK
954 NTAPI
955 CmpAllocateKeyControlBlock(
956     VOID
957 );
958 
959 VOID
960 NTAPI
961 CmpFreeKeyControlBlock(
962     IN PCM_KEY_CONTROL_BLOCK Kcb
963 );
964 
965 VOID
966 NTAPI
967 CmpRemoveKeyControlBlock(
968     IN PCM_KEY_CONTROL_BLOCK Kcb
969 );
970 
971 VOID
972 NTAPI
973 CmpCleanUpKcbValueCache(
974     IN PCM_KEY_CONTROL_BLOCK Kcb
975 );
976 
977 VOID
978 NTAPI
979 CmpCleanUpKcbCacheWithLock(
980     IN PCM_KEY_CONTROL_BLOCK Kcb,
981     IN BOOLEAN LockHeldExclusively
982 );
983 
984 VOID
985 NTAPI
986 CmpCleanUpSubKeyInfo(
987     IN PCM_KEY_CONTROL_BLOCK Kcb
988 );
989 
990 PUNICODE_STRING
991 NTAPI
992 CmpConstructName(
993     IN PCM_KEY_CONTROL_BLOCK Kcb
994 );
995 
996 BOOLEAN
997 NTAPI
998 CmpReferenceKeyControlBlock(
999     IN PCM_KEY_CONTROL_BLOCK Kcb
1000 );
1001 
1002 VOID
1003 NTAPI
1004 CmpDereferenceKeyControlBlockWithLock(
1005     IN PCM_KEY_CONTROL_BLOCK Kcb,
1006     IN BOOLEAN LockHeldExclusively
1007 );
1008 
1009 VOID
1010 NTAPI
1011 CmpDereferenceKeyControlBlock(
1012     IN PCM_KEY_CONTROL_BLOCK Kcb
1013 );
1014 
1015 VOID
1016 NTAPI
1017 EnlistKeyBodyWithKCB(
1018     IN PCM_KEY_BODY KeyObject,
1019     IN ULONG Flags
1020 );
1021 
1022 VOID
1023 NTAPI
1024 DelistKeyBodyFromKCB(
1025     IN PCM_KEY_BODY KeyBody,
1026     IN BOOLEAN LockHeld
1027 );
1028 
1029 VOID
1030 CmpUnLockKcbArray(
1031     _In_ PULONG LockedKcbs
1032 );
1033 
1034 PULONG
1035 NTAPI
1036 CmpBuildAndLockKcbArray(
1037     _In_ PCM_HASH_CACHE_STACK HashCacheStack,
1038     _In_ ULONG KcbLockFlags,
1039     _In_ PCM_KEY_CONTROL_BLOCK Kcb,
1040     _Inout_ PULONG OuterStackArray,
1041     _In_ ULONG TotalRemainingSubkeys,
1042     _In_ ULONG MatchRemainSubkeyLevel
1043 );
1044 
1045 VOID
1046 NTAPI
1047 CmpAcquireTwoKcbLocksExclusiveByKey(
1048     IN ULONG ConvKey1,
1049     IN ULONG ConvKey2
1050 );
1051 
1052 VOID
1053 NTAPI
1054 CmpReleaseTwoKcbLockByKey(
1055     IN ULONG ConvKey1,
1056     IN ULONG ConvKey2
1057 );
1058 
1059 VOID
1060 NTAPI
1061 CmpFlushNotifiesOnKeyBodyList(
1062     IN PCM_KEY_CONTROL_BLOCK Kcb,
1063     IN BOOLEAN LockHeld
1064 );
1065 
1066 //
1067 // Parse Routines
1068 //
1069 BOOLEAN
1070 NTAPI
1071 CmpGetNextName(
1072     IN OUT PUNICODE_STRING RemainingName,
1073     OUT PUNICODE_STRING NextName,
1074     OUT PBOOLEAN LastName
1075 );
1076 
1077 //
1078 // Command Routines (Flush, Open, Close, Init);
1079 //
1080 BOOLEAN
1081 NTAPI
1082 CmpDoFlushAll(
1083     IN BOOLEAN ForceFlush
1084 );
1085 
1086 VOID
1087 NTAPI
1088 CmpShutdownWorkers(
1089     VOID
1090 );
1091 
1092 VOID
1093 NTAPI
1094 CmpCmdInit(
1095     IN BOOLEAN SetupBoot
1096 );
1097 
1098 NTSTATUS
1099 NTAPI
1100 CmpCmdHiveOpen(
1101     IN POBJECT_ATTRIBUTES FileAttributes,
1102     IN PSECURITY_CLIENT_CONTEXT ImpersonationContext,
1103     IN OUT PBOOLEAN Allocate,
1104     OUT PCMHIVE *NewHive,
1105     IN ULONG CheckFlags
1106 );
1107 
1108 VOID
1109 NTAPI
1110 CmpLazyFlush(
1111     VOID
1112 );
1113 
1114 //
1115 // Open/Create Routines
1116 //
1117 NTSTATUS
1118 NTAPI
1119 CmpDoCreate(
1120     IN PHHIVE Hive,
1121     IN HCELL_INDEX Cell,
1122     IN PACCESS_STATE AccessState,
1123     IN PUNICODE_STRING Name,
1124     IN KPROCESSOR_MODE AccessMode,
1125     IN PCM_PARSE_CONTEXT Context,
1126     IN PCM_KEY_CONTROL_BLOCK ParentKcb,
1127     OUT PVOID *Object
1128 );
1129 
1130 NTSTATUS
1131 NTAPI
1132 CmpCreateLinkNode(
1133     IN PHHIVE Hive,
1134     IN HCELL_INDEX Cell,
1135     IN PACCESS_STATE AccessState,
1136     IN UNICODE_STRING Name,
1137     IN KPROCESSOR_MODE AccessMode,
1138     IN ULONG CreateOptions,
1139     IN PCM_PARSE_CONTEXT Context,
1140     IN PCM_KEY_CONTROL_BLOCK ParentKcb,
1141     IN PULONG KcbsLocked,
1142     OUT PVOID *Object
1143 );
1144 
1145 //
1146 // Boot Routines
1147 //
1148 CODE_SEG("INIT")
1149 VOID
1150 NTAPI
1151 CmGetSystemControlValues(
1152     IN PVOID SystemHiveData,
1153     IN PCM_SYSTEM_CONTROL_VECTOR ControlVector
1154 );
1155 
1156 NTSTATUS
1157 NTAPI
1158 CmpSaveBootControlSet(
1159     IN USHORT ControlSet
1160 );
1161 
1162 //
1163 // Hardware Configuration Routines
1164 //
1165 CODE_SEG("INIT")
1166 NTSTATUS
1167 NTAPI
1168 CmpInitializeRegistryNode(
1169     IN PCONFIGURATION_COMPONENT_DATA CurrentEntry,
1170     IN HANDLE NodeHandle,
1171     OUT PHANDLE NewHandle,
1172     IN INTERFACE_TYPE InterfaceType,
1173     IN ULONG BusNumber,
1174     IN PUSHORT DeviceIndexTable
1175 );
1176 
1177 NTSTATUS
1178 NTAPI
1179 CmpInitializeMachineDependentConfiguration(
1180     IN PLOADER_PARAMETER_BLOCK LoaderBlock
1181 );
1182 
1183 CODE_SEG("INIT")
1184 NTSTATUS
1185 NTAPI
1186 CmpInitializeHardwareConfiguration(
1187     IN PLOADER_PARAMETER_BLOCK LoaderBlock
1188 );
1189 
1190 //
1191 // Wrapper Routines
1192 //
1193 NTSTATUS
1194 NTAPI
1195 CmpCreateEvent(
1196     IN EVENT_TYPE EventType,
1197     OUT PHANDLE EventHandle,
1198     OUT PKEVENT *Event
1199 );
1200 
1201 PVOID
1202 NTAPI
1203 CmpAllocate(
1204     IN SIZE_T Size,
1205     IN BOOLEAN Paged,
1206     IN ULONG Tag
1207 );
1208 
1209 VOID
1210 NTAPI
1211 CmpFree(
1212     IN PVOID Ptr,
1213     IN ULONG Quota
1214 );
1215 
1216 BOOLEAN
1217 NTAPI
1218 CmpFileRead(
1219     IN PHHIVE RegistryHive,
1220     IN ULONG FileType,
1221     IN OUT PULONG FileOffset,
1222     OUT PVOID Buffer,
1223     IN SIZE_T BufferLength
1224 );
1225 
1226 BOOLEAN
1227 NTAPI
1228 CmpFileWrite(
1229     IN PHHIVE RegistryHive,
1230     IN ULONG FileType,
1231     IN OUT PULONG FileOffset,
1232     IN PVOID Buffer,
1233     IN SIZE_T BufferLength
1234 );
1235 
1236 BOOLEAN
1237 NTAPI
1238 CmpFileSetSize(
1239     IN PHHIVE RegistryHive,
1240     IN ULONG FileType,
1241     IN ULONG FileSize,
1242     IN ULONG OldFileSize
1243 );
1244 
1245 BOOLEAN
1246 NTAPI
1247 CmpFileFlush(
1248    IN PHHIVE RegistryHive,
1249    IN ULONG FileType,
1250    IN OUT PLARGE_INTEGER FileOffset,
1251    IN ULONG Length
1252 );
1253 
1254 //
1255 // Configuration Manager side of Registry System Calls
1256 //
1257 NTSTATUS
1258 NTAPI
1259 CmEnumerateValueKey(
1260     IN PCM_KEY_CONTROL_BLOCK Kcb,
1261     IN ULONG Index,
1262     IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
1263     IN PVOID KeyValueInformation,
1264     IN ULONG Length,
1265     IN PULONG ResultLength);
1266 
1267 NTSTATUS
1268 NTAPI
1269 CmSetValueKey(
1270     IN PCM_KEY_CONTROL_BLOCK Kcb,
1271     IN PUNICODE_STRING ValueName,
1272     IN ULONG Type,
1273     IN PVOID Data,
1274     IN ULONG DataSize);
1275 
1276 NTSTATUS
1277 NTAPI
1278 CmQueryKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
1279     IN KEY_INFORMATION_CLASS KeyInformationClass,
1280     IN PVOID KeyInformation,
1281     IN ULONG Length,
1282     IN PULONG ResultLength
1283 );
1284 
1285 NTSTATUS
1286 NTAPI
1287 CmEnumerateKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
1288     IN ULONG Index,
1289     IN KEY_INFORMATION_CLASS KeyInformationClass,
1290     IN PVOID KeyInformation,
1291     IN ULONG Length,
1292     IN PULONG ResultLength
1293 );
1294 
1295 NTSTATUS
1296 NTAPI
1297 CmDeleteKey(
1298     IN PCM_KEY_BODY KeyBody
1299 );
1300 
1301 NTSTATUS
1302 NTAPI
1303 CmFlushKey(
1304     IN PCM_KEY_CONTROL_BLOCK Kcb,
1305     IN BOOLEAN EclusiveLock
1306 );
1307 
1308 NTSTATUS
1309 NTAPI
1310 CmDeleteValueKey(
1311     IN PCM_KEY_CONTROL_BLOCK Kcb,
1312     IN UNICODE_STRING ValueName
1313 );
1314 
1315 NTSTATUS
1316 NTAPI
1317 CmQueryValueKey(
1318     IN PCM_KEY_CONTROL_BLOCK Kcb,
1319     IN UNICODE_STRING ValueName,
1320     IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
1321     IN PVOID KeyValueInformation,
1322     IN ULONG Length,
1323     IN PULONG ResultLength
1324 );
1325 
1326 NTSTATUS
1327 NTAPI
1328 CmLoadKey(
1329     IN POBJECT_ATTRIBUTES TargetKey,
1330     IN POBJECT_ATTRIBUTES SourceFile,
1331     IN ULONG Flags,
1332     IN PCM_KEY_BODY KeyBody
1333 );
1334 
1335 NTSTATUS
1336 NTAPI
1337 CmUnloadKey(
1338     IN PCM_KEY_CONTROL_BLOCK Kcb,
1339     IN ULONG Flags
1340 );
1341 
1342 ULONG
1343 NTAPI
1344 CmpEnumerateOpenSubKeys(
1345     IN PCM_KEY_CONTROL_BLOCK RootKcb,
1346     IN BOOLEAN RemoveEmptyCacheEntries,
1347     IN BOOLEAN DereferenceOpenedEntries
1348 );
1349 
1350 HCELL_INDEX
1351 NTAPI
1352 CmpCopyCell(
1353     IN PHHIVE SourceHive,
1354     IN HCELL_INDEX SourceCell,
1355     IN PHHIVE DestinationHive,
1356     IN HSTORAGE_TYPE StorageType
1357 );
1358 
1359 NTSTATUS
1360 NTAPI
1361 CmpDeepCopyKey(
1362     IN PHHIVE SourceHive,
1363     IN HCELL_INDEX SrcKeyCell,
1364     IN PHHIVE DestinationHive,
1365     IN HSTORAGE_TYPE StorageType,
1366     OUT PHCELL_INDEX DestKeyCell OPTIONAL
1367 );
1368 
1369 NTSTATUS
1370 NTAPI
1371 CmSaveKey(
1372     IN PCM_KEY_CONTROL_BLOCK Kcb,
1373     IN HANDLE FileHandle,
1374     IN ULONG Flags
1375 );
1376 
1377 NTSTATUS
1378 NTAPI
1379 CmSaveMergedKeys(
1380     IN PCM_KEY_CONTROL_BLOCK HighKcb,
1381     IN PCM_KEY_CONTROL_BLOCK LowKcb,
1382     IN HANDLE FileHandle
1383 );
1384 
1385 //
1386 // Startup and Shutdown
1387 //
1388 CODE_SEG("INIT")
1389 BOOLEAN
1390 NTAPI
1391 CmInitSystem1(
1392     VOID
1393 );
1394 
1395 VOID
1396 NTAPI
1397 CmShutdownSystem(
1398     VOID
1399 );
1400 
1401 VOID
1402 NTAPI
1403 CmSetLazyFlushState(
1404     IN BOOLEAN Enable
1405 );
1406 
1407 VOID
1408 NTAPI
1409 CmpSetVersionData(
1410     VOID
1411 );
1412 
1413 //
1414 // Driver List Routines
1415 //
1416 CODE_SEG("INIT")
1417 PUNICODE_STRING*
1418 NTAPI
1419 CmGetSystemDriverList(
1420     VOID
1421 );
1422 
1423 //
1424 // Global variables accessible from all of Cm
1425 //
1426 extern ULONG CmpTraceLevel;
1427 extern BOOLEAN CmpSpecialBootCondition;
1428 extern BOOLEAN CmpFlushOnLockRelease;
1429 extern BOOLEAN CmpShareSystemHives;
1430 extern BOOLEAN CmpMiniNTBoot;
1431 extern BOOLEAN CmpNoVolatileCreates;
1432 extern EX_PUSH_LOCK CmpHiveListHeadLock, CmpLoadHiveLock;
1433 extern LIST_ENTRY CmpHiveListHead;
1434 extern POBJECT_TYPE CmpKeyObjectType;
1435 extern ERESOURCE CmpRegistryLock;
1436 extern PCM_KEY_HASH_TABLE_ENTRY CmpCacheTable;
1437 extern PCM_NAME_HASH_TABLE_ENTRY CmpNameCacheTable;
1438 extern KGUARDED_MUTEX CmpDelayedCloseTableLock;
1439 extern CMHIVE CmControlHive;
1440 extern WCHAR CmDefaultLanguageId[];
1441 extern ULONG CmDefaultLanguageIdLength;
1442 extern ULONG CmDefaultLanguageIdType;
1443 extern WCHAR CmInstallUILanguageId[];
1444 extern ULONG CmInstallUILanguageIdLength;
1445 extern ULONG CmInstallUILanguageIdType;
1446 extern ULONG CmNtGlobalFlag;
1447 extern LANGID PsInstallUILanguageId;
1448 extern LANGID PsDefaultUILanguageId;
1449 extern CM_SYSTEM_CONTROL_VECTOR CmControlVector[];
1450 extern ULONG CmpConfigurationAreaSize;
1451 extern PCM_FULL_RESOURCE_DESCRIPTOR CmpConfigurationData;
1452 extern UNICODE_STRING CmTypeName[];
1453 extern UNICODE_STRING CmClassName[];
1454 extern CMP_MF_TYPE CmpMultifunctionTypes[];
1455 extern USHORT CmpUnknownBusCount;
1456 extern ULONG CmpTypeCount[MaximumType + 1];
1457 extern HIVE_LIST_ENTRY CmpMachineHiveList[];
1458 extern UNICODE_STRING CmSymbolicLinkValueName;
1459 extern UNICODE_STRING CmpSystemStartOptions;
1460 extern UNICODE_STRING CmpLoadOptions;
1461 extern BOOLEAN CmSelfHeal;
1462 extern BOOLEAN CmpSelfHeal;
1463 extern ULONG CmpBootType;
1464 extern HANDLE CmpRegistryRootHandle;
1465 extern BOOLEAN ExpInTextModeSetup;
1466 extern BOOLEAN InitIsWinPEMode;
1467 extern ULONG CmpHashTableSize;
1468 extern ULONG CmpDelayedCloseSize, CmpDelayedCloseIndex;
1469 extern BOOLEAN CmpNoWrite;
1470 extern BOOLEAN CmpForceForceFlush;
1471 extern BOOLEAN CmpWasSetupBoot;
1472 extern BOOLEAN CmpProfileLoaded;
1473 extern PCMHIVE CmiVolatileHive;
1474 extern LIST_ENTRY CmiKeyObjectListHead;
1475 extern BOOLEAN CmpHoldLazyFlush;
1476 
1477 //
1478 // Inlined functions
1479 //
1480 #include "cm_x.h"
1481