xref: /reactos/sdk/lib/cmlib/cminit.c (revision b5218987)
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 #include "cmlib.h"
9 #define NDEBUG
10 #include <debug.h>
11 
12 ULONG CmlibTraceLevel = 0;
13 
14 // FIXME: This function must be replaced by CmpCreateRootNode from ntoskrnl/config/cmsysini.c
15 // (and CmpCreateRootNode be moved there).
16 BOOLEAN CMAPI
17 CmCreateRootNode(
18     PHHIVE Hive,
19     PCWSTR Name)
20 {
21     UNICODE_STRING KeyName;
22     PCM_KEY_NODE KeyCell;
23     HCELL_INDEX RootCellIndex;
24 
25     /* Initialize the node name and allocate it */
26     RtlInitUnicodeString(&KeyName, Name);
27     RootCellIndex = HvAllocateCell(Hive,
28                                    FIELD_OFFSET(CM_KEY_NODE, Name) +
29                                    CmpNameSize(Hive, &KeyName),
30                                    Stable,
31                                    HCELL_NIL);
32     if (RootCellIndex == HCELL_NIL) return FALSE;
33 
34     /* Seutp the base block */
35     Hive->BaseBlock->RootCell = RootCellIndex;
36     Hive->BaseBlock->CheckSum = HvpHiveHeaderChecksum(Hive->BaseBlock);
37 
38     /* Get the key cell */
39     KeyCell = (PCM_KEY_NODE)HvGetCell(Hive, RootCellIndex);
40     if (!KeyCell)
41     {
42         HvFreeCell(Hive, RootCellIndex);
43         return FALSE;
44     }
45 
46     /* Setup the cell */
47     KeyCell->Signature = CM_KEY_NODE_SIGNATURE;
48     KeyCell->Flags = KEY_HIVE_ENTRY | KEY_NO_DELETE;
49     // KeQuerySystemTime(&KeyCell->LastWriteTime);
50     KeyCell->LastWriteTime.QuadPart = 0ULL;
51     KeyCell->Parent = HCELL_NIL;
52     KeyCell->SubKeyCounts[Stable] = 0;
53     KeyCell->SubKeyCounts[Volatile] = 0;
54     KeyCell->SubKeyLists[Stable] = HCELL_NIL;
55     KeyCell->SubKeyLists[Volatile] = HCELL_NIL;
56     KeyCell->ValueList.Count = 0;
57     KeyCell->ValueList.List = HCELL_NIL;
58     KeyCell->Security = HCELL_NIL;
59     KeyCell->Class = HCELL_NIL;
60     KeyCell->ClassLength = 0;
61     KeyCell->MaxNameLen = 0;
62     KeyCell->MaxClassLen = 0;
63     KeyCell->MaxValueNameLen = 0;
64     KeyCell->MaxValueDataLen = 0;
65     KeyCell->NameLength = CmpCopyName(Hive, KeyCell->Name, &KeyName);
66     if (KeyCell->NameLength < KeyName.Length) KeyCell->Flags |= KEY_COMP_NAME;
67 
68     /* Return success */
69     HvReleaseCell(Hive, RootCellIndex);
70     return TRUE;
71 }
72 
73 static VOID CMAPI
74 CmpPrepareKey(
75     PHHIVE RegistryHive,
76     PCM_KEY_NODE KeyCell);
77 
78 static VOID CMAPI
79 CmpPrepareIndexOfKeys(
80     PHHIVE RegistryHive,
81     PCM_KEY_INDEX IndexCell)
82 {
83     ULONG i;
84 
85     if (IndexCell->Signature == CM_KEY_INDEX_ROOT ||
86         IndexCell->Signature == CM_KEY_INDEX_LEAF)
87     {
88         for (i = 0; i < IndexCell->Count; i++)
89         {
90             PCM_KEY_INDEX SubIndexCell = HvGetCell(RegistryHive, IndexCell->List[i]);
91             if (SubIndexCell->Signature == CM_KEY_NODE_SIGNATURE)
92                 CmpPrepareKey(RegistryHive, (PCM_KEY_NODE)SubIndexCell);
93             else
94                 CmpPrepareIndexOfKeys(RegistryHive, SubIndexCell);
95         }
96    }
97     else if (IndexCell->Signature == CM_KEY_FAST_LEAF ||
98              IndexCell->Signature == CM_KEY_HASH_LEAF)
99     {
100         PCM_KEY_FAST_INDEX HashCell = (PCM_KEY_FAST_INDEX)IndexCell;
101         for (i = 0; i < HashCell->Count; i++)
102         {
103             PCM_KEY_NODE SubKeyCell = HvGetCell(RegistryHive, HashCell->List[i].Cell);
104             CmpPrepareKey(RegistryHive, SubKeyCell);
105         }
106     }
107     else
108     {
109         DPRINT1("IndexCell->Signature %x\n", IndexCell->Signature);
110         ASSERT(FALSE);
111     }
112 }
113 
114 static VOID CMAPI
115 CmpPrepareKey(
116     PHHIVE RegistryHive,
117     PCM_KEY_NODE KeyCell)
118 {
119     PCM_KEY_INDEX IndexCell;
120 
121     ASSERT(KeyCell->Signature == CM_KEY_NODE_SIGNATURE);
122 
123     KeyCell->SubKeyCounts[Volatile] = 0;
124     // KeyCell->SubKeyLists[Volatile] = HCELL_NIL; // FIXME! Done only on Windows < XP.
125 
126     /* Enumerate and add subkeys */
127     if (KeyCell->SubKeyCounts[Stable] > 0)
128     {
129         IndexCell = HvGetCell(RegistryHive, KeyCell->SubKeyLists[Stable]);
130         CmpPrepareIndexOfKeys(RegistryHive, IndexCell);
131     }
132 }
133 
134 VOID CMAPI
135 CmPrepareHive(
136     PHHIVE RegistryHive)
137 {
138     PCM_KEY_NODE RootCell;
139 
140     RootCell = HvGetCell(RegistryHive, RegistryHive->BaseBlock->RootCell);
141     CmpPrepareKey(RegistryHive, RootCell);
142 }
143