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
;
138 POBJECT_NAME_INFORMATION FileNameInfo
;
140 HivePath
.Buffer
= NULL
;
143 /* Create or open the hive list key */
144 InitializeObjectAttributes(&ObjectAttributes
,
146 OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
,
149 Status
= ZwCreateKey(&KeyHandle
,
150 KEY_READ
| KEY_WRITE
,
156 if (!NT_SUCCESS(Status
))
159 DPRINT1("CmpAddToHiveFileList: Creation or opening of the hive list failed, status = 0x%08lx\n", Status
);
163 /* Retrieve the name of the hive */
164 if (!CmpGetHiveName(Hive
, &HivePath
))
167 DPRINT1("CmpAddToHiveFileList: Unable to retrieve the hive name\n");
168 Status
= STATUS_NO_MEMORY
;
172 /* Get the name of the corresponding file */
173 if (!(Hive
->Hive
.HiveFlags
& HIVE_VOLATILE
))
175 /* Determine the right buffer size and allocate */
176 Status
= ZwQueryObject(Hive
->FileHandles
[HFILE_TYPE_PRIMARY
],
177 ObjectNameInformation
,
181 if (Status
!= STATUS_INFO_LENGTH_MISMATCH
)
183 DPRINT1("CmpAddToHiveFileList: Hive file name size query failed, status = 0x%08lx\n", Status
);
187 FileNameInfo
= ExAllocatePoolWithTag(PagedPool
,
188 Length
+ sizeof(UNICODE_NULL
),
190 if (FileNameInfo
== NULL
)
192 Status
= STATUS_INSUFFICIENT_RESOURCES
;
196 /* Try to get the value */
197 Status
= ZwQueryObject(Hive
->FileHandles
[HFILE_TYPE_PRIMARY
],
198 ObjectNameInformation
,
202 if (NT_SUCCESS(Status
))
204 /* Null-terminate and add the length of the terminator */
205 Length
-= sizeof(OBJECT_NAME_INFORMATION
);
206 FilePath
= FileNameInfo
->Name
.Buffer
;
207 FilePath
[Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
208 Length
+= sizeof(UNICODE_NULL
);
213 DPRINT1("CmpAddToHiveFileList: Hive file name query failed, status = 0x%08lx\n", Status
);
221 Length
= sizeof(UNICODE_NULL
);
224 /* Set the entry in the hive list */
225 Status
= ZwSetValueKey(KeyHandle
,
231 if (!NT_SUCCESS(Status
))
234 DPRINT1("CmpAddToHiveFileList: Setting of entry in the hive list failed, status = 0x%08lx\n", Status
);
238 /* Cleanup and return status */
241 ExFreePoolWithTag(HivePath
.Buffer
, TAG_CM
);
245 ExFreePoolWithTag(FileNameInfo
, TAG_CM
);
247 ObCloseHandle(KeyHandle
, KernelMode
);
253 CmpRemoveFromHiveFileList(IN PCMHIVE Hive
)
256 OBJECT_ATTRIBUTES ObjectAttributes
;
258 UNICODE_STRING HivePath
;
260 /* Open the hive list key */
261 InitializeObjectAttributes(&ObjectAttributes
,
263 OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
,
266 Status
= ZwOpenKey(&KeyHandle
,
267 KEY_READ
| KEY_WRITE
,
269 if (!NT_SUCCESS(Status
))
272 DPRINT1("CmpRemoveFromHiveFileList: Opening of the hive list failed, status = 0x%08lx\n", Status
);
276 /* Get the hive path name */
277 CmpGetHiveName(Hive
, &HivePath
);
279 /* Delete the hive path name from the list */
280 ZwDeleteValueKey(KeyHandle
, &HivePath
);
282 /* Cleanup allocation and handle */
283 ExFreePoolWithTag(HivePath
.Buffer
, TAG_CM
);
284 ObCloseHandle(KeyHandle
, KernelMode
);