2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/config/cmhvlist.c
5 * PURPOSE: Configuration Manager - Hives file list management
6 * PROGRAMMERS: Hermes BELUSCA - MAITO
9 /* INCLUDES *******************************************************************/
15 /* GLOBALS ********************************************************************/
17 UNICODE_STRING HiveListValueName
= RTL_CONSTANT_STRING(L
"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Control\\hivelist");
19 /* FUNCTIONS ******************************************************************/
21 /* Note: the caller is expected to free the HiveName string buffer */
24 CmpGetHiveName(IN PCMHIVE Hive
,
25 OUT PUNICODE_STRING HiveName
)
27 HCELL_INDEX RootCell
, LinkCell
;
28 PCELL_DATA RootData
, LinkData
, ParentData
;
29 ULONG ParentNameSize
, LinkNameSize
;
32 UNICODE_STRING RegistryName
= RTL_CONSTANT_STRING(L
"\\REGISTRY\\");
34 /* Get the root cell of this hive */
35 RootCell
= Hive
->Hive
.BaseBlock
->RootCell
;
36 RootData
= HvGetCell(&Hive
->Hive
, RootCell
);
37 if (!RootData
) return FALSE
;
39 /* Get the cell index at which this hive is linked to, and its parent */
40 LinkCell
= RootData
->u
.KeyNode
.Parent
;
41 HvReleaseCell(&Hive
->Hive
, RootCell
);
44 ASSERT((&CmiVolatileHive
->Hive
)->ReleaseCellRoutine
== NULL
);
46 /* Get the cell data for link and parent */
47 LinkData
= HvGetCell(&CmiVolatileHive
->Hive
, LinkCell
);
48 if (!LinkData
) return FALSE
;
49 ParentData
= HvGetCell(&CmiVolatileHive
->Hive
, LinkData
->u
.KeyNode
.Parent
);
50 if (!ParentData
) return FALSE
;
52 /* Get the size of the parent name */
53 if (ParentData
->u
.KeyNode
.Flags
& KEY_COMP_NAME
)
55 ParentNameSize
= CmpCompressedNameSize(ParentData
->u
.KeyNode
.Name
,
56 ParentData
->u
.KeyNode
.NameLength
);
60 ParentNameSize
= ParentData
->u
.KeyNode
.NameLength
;
63 /* Get the size of the link name */
64 if (LinkData
->u
.KeyNode
.Flags
& KEY_COMP_NAME
)
66 LinkNameSize
= CmpCompressedNameSize(LinkData
->u
.KeyNode
.Name
,
67 LinkData
->u
.KeyNode
.NameLength
);
71 LinkNameSize
= LinkData
->u
.KeyNode
.NameLength
;
74 /* No need to account for terminal NULL character since we deal with counted UNICODE strings */
75 NameSize
= RegistryName
.Length
+ ParentNameSize
+ sizeof(WCHAR
) + LinkNameSize
;
77 /* Allocate the memory */
78 HiveName
->Buffer
= ExAllocatePoolWithTag(PagedPool
, NameSize
, TAG_CM
);
79 if (!HiveName
->Buffer
)
82 DPRINT1("CmpGetHiveName: Unable to allocate memory\n");
86 /* Build the string for it */
87 HiveName
->Length
= HiveName
->MaximumLength
= (USHORT
)NameSize
;
90 /* Copy the parent name */
91 RtlCopyMemory(p
, RegistryName
.Buffer
, RegistryName
.Length
);
92 p
+= RegistryName
.Length
/ sizeof(WCHAR
);
93 if (ParentData
->u
.KeyNode
.Flags
& KEY_COMP_NAME
)
95 CmpCopyCompressedName(p
,
97 ParentData
->u
.KeyNode
.Name
,
98 ParentData
->u
.KeyNode
.NameLength
);
102 RtlCopyMemory(p
, ParentData
->u
.KeyNode
.Name
, ParentNameSize
);
105 /* Add a path separator between parent and link */
106 p
+= ParentNameSize
/ sizeof(WCHAR
);
107 *p
= OBJ_NAME_PATH_SEPARATOR
;
110 /* Now copy the link name */
111 if (LinkData
->u
.KeyNode
.Flags
& KEY_COMP_NAME
)
113 CmpCopyCompressedName(p
,
115 LinkData
->u
.KeyNode
.Name
,
116 LinkData
->u
.KeyNode
.NameLength
);
121 RtlCopyMemory(p
, LinkData
->u
.KeyNode
.Name
, LinkNameSize
);
130 CmpAddToHiveFileList(IN PCMHIVE Hive
)
133 OBJECT_ATTRIBUTES ObjectAttributes
;
135 UNICODE_STRING HivePath
;
137 CHAR Buffer
[sizeof(OBJECT_NAME_INFORMATION
) + 512 * sizeof(WCHAR
)];
138 ULONG Length
= sizeof(Buffer
);
139 POBJECT_NAME_INFORMATION LocalNameInfo
= (POBJECT_NAME_INFORMATION
)&Buffer
;
140 HivePath
.Buffer
= NULL
;
142 /* Create or open the hive list key */
143 InitializeObjectAttributes(&ObjectAttributes
,
145 OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
,
148 Status
= ZwCreateKey(&KeyHandle
,
149 KEY_READ
| KEY_WRITE
,
155 if (!NT_SUCCESS(Status
))
158 DPRINT1("CmpAddToHiveFileList: Creation or opening of the hive list failed, status = %08lx\n", Status
);
162 /* Retrieve the name of the hive */
163 if (!CmpGetHiveName(Hive
, &HivePath
))
166 DPRINT1("CmpAddToHiveFileList: Unable to retrieve the hive name\n");
167 Status
= STATUS_NO_MEMORY
;
171 /* Get the name of the corresponding file */
172 if (!(Hive
->Hive
.HiveFlags
& HIVE_VOLATILE
))
174 /* Try to get the value */
175 Status
= ZwQueryObject(Hive
->FileHandles
[HFILE_TYPE_PRIMARY
],
176 ObjectNameInformation
,
180 if (NT_SUCCESS(Status
))
182 /* Null-terminate and add the length of the terminator */
183 Length
-= sizeof(OBJECT_NAME_INFORMATION
);
184 FilePath
= LocalNameInfo
->Name
.Buffer
;
185 FilePath
[Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
186 Length
+= sizeof(UNICODE_NULL
);
191 DPRINT1("CmpAddToHiveFileList: Hive file name query failed, status = %08lx\n", Status
);
199 Length
= sizeof(UNICODE_NULL
);
202 /* Set the entry in the hive list */
203 Status
= ZwSetValueKey(KeyHandle
,
209 if (!NT_SUCCESS(Status
))
212 DPRINT1("CmpAddToHiveFileList: Setting of entry in the hive list failed, status = %08lx\n", Status
);
216 /* Cleanup and return status */
217 if (HivePath
.Buffer
) ExFreePoolWithTag(HivePath
.Buffer
, TAG_CM
);
218 ObCloseHandle(KeyHandle
, KernelMode
);
224 CmpRemoveFromHiveFileList(IN PCMHIVE Hive
)
227 OBJECT_ATTRIBUTES ObjectAttributes
;
229 UNICODE_STRING HivePath
;
231 /* Open the hive list key */
232 InitializeObjectAttributes(&ObjectAttributes
,
234 OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
,
237 Status
= ZwOpenKey(&KeyHandle
,
238 KEY_READ
| KEY_WRITE
,
240 if (!NT_SUCCESS(Status
))
243 DPRINT1("CmpRemoveFromHiveFileList: Opening of the hive list failed, status = %08lx\n", Status
);
247 /* Get the hive path name */
248 CmpGetHiveName(Hive
, &HivePath
);
250 /* Delete the hive path name from the list */
251 ZwDeleteValueKey(KeyHandle
, &HivePath
);
253 /* Cleanup allocation and handle */
254 ExFreePoolWithTag(HivePath
.Buffer
, TAG_CM
);
255 ObCloseHandle(KeyHandle
, KernelMode
);