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