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 UCHAR Buffer
[sizeof(OBJECT_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
)];
138 ULONG Length
= sizeof(Buffer
);
139 POBJECT_NAME_INFORMATION FileNameInfo
= (POBJECT_NAME_INFORMATION
)Buffer
;
141 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 /* Try to get the value */
176 Status
= ZwQueryObject(Hive
->FileHandles
[HFILE_TYPE_PRIMARY
],
177 ObjectNameInformation
,
181 if (NT_SUCCESS(Status
))
183 /* Null-terminate and add the length of the terminator */
184 Length
-= sizeof(OBJECT_NAME_INFORMATION
);
185 FilePath
= FileNameInfo
->Name
.Buffer
;
186 FilePath
[Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
187 Length
+= sizeof(UNICODE_NULL
);
192 DPRINT1("CmpAddToHiveFileList: Hive file name query failed, status = 0x%08lx\n", Status
);
200 Length
= sizeof(UNICODE_NULL
);
203 /* Set the entry in the hive list */
204 Status
= ZwSetValueKey(KeyHandle
,
210 if (!NT_SUCCESS(Status
))
213 DPRINT1("CmpAddToHiveFileList: Setting of entry in the hive list failed, status = 0x%08lx\n", Status
);
217 /* Cleanup and return status */
218 if (HivePath
.Buffer
) ExFreePoolWithTag(HivePath
.Buffer
, TAG_CM
);
219 ObCloseHandle(KeyHandle
, KernelMode
);
225 CmpRemoveFromHiveFileList(IN PCMHIVE Hive
)
228 OBJECT_ATTRIBUTES ObjectAttributes
;
230 UNICODE_STRING HivePath
;
232 /* Open the hive list key */
233 InitializeObjectAttributes(&ObjectAttributes
,
235 OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
,
238 Status
= ZwOpenKey(&KeyHandle
,
239 KEY_READ
| KEY_WRITE
,
241 if (!NT_SUCCESS(Status
))
244 DPRINT1("CmpRemoveFromHiveFileList: Opening of the hive list failed, status = 0x%08lx\n", Status
);
248 /* Get the hive path name */
249 CmpGetHiveName(Hive
, &HivePath
);
251 /* Delete the hive path name from the list */
252 ZwDeleteValueKey(KeyHandle
, &HivePath
);
254 /* Cleanup allocation and handle */
255 ExFreePoolWithTag(HivePath
.Buffer
, TAG_CM
);
256 ObCloseHandle(KeyHandle
, KernelMode
);