3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/cm/import.c
6 * PURPOSE: Registry-Hive import functions
7 * PROGRAMMERS: Eric Kohl
10 /* INCLUDES *****************************************************************/
14 #include <internal/debug.h>
18 /* GLOBALS ******************************************************************/
20 static BOOLEAN CmiHardwareHiveImported
= FALSE
;
23 /* FUNCTIONS ****************************************************************/
26 CmImportBinaryHive (PCHAR ChunkBase
,
29 PREGISTRY_HIVE
*RegistryHive
)
36 if (strncmp (ChunkBase
, "regf", 4))
38 DPRINT1 ("Found invalid '%*s' magic\n", 4, ChunkBase
);
42 /* Create a new hive */
43 Hive
= ExAllocatePool (NonPagedPool
,
44 sizeof(REGISTRY_HIVE
));
50 sizeof(REGISTRY_HIVE
));
55 /* Allocate hive header */
56 Hive
->HiveHeader
= (PHIVE_HEADER
)ExAllocatePool (NonPagedPool
,
58 if (Hive
->HiveHeader
== NULL
)
60 DPRINT1 ("Allocating hive header failed\n");
65 /* Import the hive header */
66 RtlCopyMemory (Hive
->HiveHeader
,
70 /* Read update counter */
71 Hive
->UpdateCounter
= Hive
->HiveHeader
->UpdateCounter1
;
73 /* Set the hive's size */
74 Hive
->FileSize
= ChunkSize
;
76 /* Set the size of the block list */
77 Hive
->BlockListSize
= (Hive
->FileSize
/ 4096) - 1;
79 /* Allocate block list */
80 DPRINT("Space needed for block list describing hive: 0x%x\n",
81 Hive
->BlockListSize
* sizeof(BLOCK_LIST_ENTRY
));
82 Hive
->BlockList
= ExAllocatePool (NonPagedPool
,
83 Hive
->BlockListSize
* sizeof(BLOCK_LIST_ENTRY
));
84 if (Hive
->BlockList
== NULL
)
86 DPRINT1 ("Allocating block list failed\n");
87 ExFreePool (Hive
->HiveHeader
);
91 RtlZeroMemory (Hive
->BlockList
,
92 Hive
->BlockListSize
* sizeof(BLOCK_LIST_ENTRY
));
95 Status
= CmiImportHiveBins(Hive
,
96 (PUCHAR
)((ULONG_PTR
)ChunkBase
+ 4096));
97 if (!NT_SUCCESS(Status
))
99 DPRINT1 ("CmiImportHiveBins() failed (Status %lx)\n", Status
);
100 CmiFreeHiveBins (Hive
);
101 ExFreePool (Hive
->BlockList
);
102 ExFreePool (Hive
->HiveHeader
);
104 return (BOOLEAN
)Status
;
107 /* Initialize the free cell list */
108 Status
= CmiCreateHiveFreeCellList (Hive
);
109 if (!NT_SUCCESS(Status
))
111 DPRINT1 ("CmiCreateHiveFreeCellList() failed (Status %lx)\n", Status
);
112 CmiFreeHiveBins (Hive
);
113 ExFreePool (Hive
->BlockList
);
114 ExFreePool (Hive
->HiveHeader
);
117 return (BOOLEAN
)Status
;
120 if (!(Hive
->Flags
& HIVE_NO_FILE
))
122 /* Create the block bitmap */
123 Status
= CmiCreateHiveBitmap (Hive
);
124 if (!NT_SUCCESS(Status
))
126 DPRINT1 ("CmiCreateHiveBitmap() failed (Status %lx)\n", Status
);
127 CmiFreeHiveFreeCellList (Hive
);
128 CmiFreeHiveBins (Hive
);
129 ExFreePool (Hive
->BlockList
);
130 ExFreePool (Hive
->HiveHeader
);
133 return (BOOLEAN
)Status
;
137 /* Acquire hive list lock exclusively */
138 KeEnterCriticalRegion();
139 ExAcquireResourceExclusiveLite(&CmiRegistryLock
, TRUE
);
141 /* Add the new hive to the hive list */
142 InsertTailList(&CmiHiveListHead
, &Hive
->HiveList
);
144 /* Release hive list lock */
145 ExReleaseResourceLite(&CmiRegistryLock
);
146 KeLeaveCriticalRegion();
148 *RegistryHive
= Hive
;
154 BOOLEAN INIT_FUNCTION
155 CmImportSystemHive(PCHAR ChunkBase
,
158 OBJECT_ATTRIBUTES ObjectAttributes
;
159 PREGISTRY_HIVE RegistryHive
;
160 UNICODE_STRING KeyName
;
163 DPRINT ("CmImportSystemHive() called\n");
165 if (strncmp (ChunkBase
, "regf", 4))
167 DPRINT1 ("Found invalid '%.*s' magic\n", 4, ChunkBase
);
171 DPRINT ("Found '%.*s' magic\n", 4, ChunkBase
);
173 /* Import the binary system hive (non-volatile, offset-based, permanent) */
174 if (!CmImportBinaryHive (ChunkBase
, ChunkSize
, 0, &RegistryHive
))
176 DPRINT1 ("CmiImportBinaryHive() failed\n");
180 /* Attach it to the machine key */
181 RtlInitUnicodeString (&KeyName
,
182 REG_SYSTEM_KEY_NAME
);
183 InitializeObjectAttributes (&ObjectAttributes
,
185 OBJ_CASE_INSENSITIVE
,
188 Status
= CmiConnectHive (&ObjectAttributes
,
190 if (!NT_SUCCESS(Status
))
192 DPRINT1 ("CmiConnectHive(%wZ) failed (Status %lx)\n", &KeyName
, Status
);
193 // CmiRemoveRegistryHive(RegistryHive);
197 /* Set the hive filename */
198 RtlCreateUnicodeString (&RegistryHive
->HiveFileName
,
201 /* Set the log filename */
202 RtlCreateUnicodeString (&RegistryHive
->LogFileName
,
209 BOOLEAN INIT_FUNCTION
210 CmImportHardwareHive(PCHAR ChunkBase
,
213 OBJECT_ATTRIBUTES ObjectAttributes
;
214 PREGISTRY_HIVE RegistryHive
;
215 UNICODE_STRING KeyName
;
220 DPRINT ("CmImportHardwareHive() called\n");
222 if (CmiHardwareHiveImported
== TRUE
)
225 if (ChunkBase
== NULL
&&
228 /* Create '\Registry\Machine\HARDWARE' key. */
229 RtlInitUnicodeString (&KeyName
,
230 REG_HARDWARE_KEY_NAME
);
231 InitializeObjectAttributes (&ObjectAttributes
,
233 OBJ_CASE_INSENSITIVE
,
236 Status
= NtCreateKey (&HardwareKey
,
243 if (!NT_SUCCESS(Status
))
247 NtClose (HardwareKey
);
249 /* Create '\Registry\Machine\HARDWARE\DESCRIPTION' key. */
250 RtlInitUnicodeString(&KeyName
,
251 REG_DESCRIPTION_KEY_NAME
);
252 InitializeObjectAttributes (&ObjectAttributes
,
254 OBJ_CASE_INSENSITIVE
,
257 Status
= NtCreateKey (&HardwareKey
,
264 if (!NT_SUCCESS(Status
))
268 NtClose (HardwareKey
);
270 /* Create '\Registry\Machine\HARDWARE\DEVICEMAP' key. */
271 RtlInitUnicodeString (&KeyName
,
272 REG_DEVICEMAP_KEY_NAME
);
273 InitializeObjectAttributes (&ObjectAttributes
,
275 OBJ_CASE_INSENSITIVE
,
278 Status
= NtCreateKey (&HardwareKey
,
285 if (!NT_SUCCESS(Status
))
289 NtClose (HardwareKey
);
291 /* Create '\Registry\Machine\HARDWARE\RESOURCEMAP' key. */
292 RtlInitUnicodeString(&KeyName
,
293 REG_RESOURCEMAP_KEY_NAME
);
294 InitializeObjectAttributes (&ObjectAttributes
,
296 OBJ_CASE_INSENSITIVE
,
299 Status
= NtCreateKey (&HardwareKey
,
306 if (!NT_SUCCESS(Status
))
310 NtClose (HardwareKey
);
315 /* Check the hive magic */
316 if (strncmp (ChunkBase
, "regf", 4))
318 DPRINT1 ("Found invalid '%.*s' magic\n", 4, ChunkBase
);
322 DPRINT ("Found '%.*s' magic\n", 4, ChunkBase
);
323 DPRINT ("ChunkBase %lx ChunkSize %lu\n", ChunkBase
, ChunkSize
);
325 /* Import the binary system hive (volatile, offset-based, permanent) */
326 if (!CmImportBinaryHive (ChunkBase
, ChunkSize
, HIVE_NO_FILE
, &RegistryHive
))
328 DPRINT1 ("CmiImportBinaryHive() failed\n");
332 /* Attach it to the machine key */
333 RtlInitUnicodeString (&KeyName
,
334 REG_HARDWARE_KEY_NAME
);
335 InitializeObjectAttributes (&ObjectAttributes
,
337 OBJ_CASE_INSENSITIVE
,
340 Status
= CmiConnectHive (&ObjectAttributes
,
342 if (!NT_SUCCESS(Status
))
344 DPRINT1 ("CmiConnectHive(%wZ) failed (Status %lx)\n", &KeyName
, Status
);
345 // CmiRemoveRegistryHive(RegistryHive);
349 /* Set the hive filename */
350 RtlInitUnicodeString (&RegistryHive
->HiveFileName
,
353 /* Set the log filename */
354 RtlInitUnicodeString (&RegistryHive
->LogFileName
,
357 CmiHardwareHiveImported
= TRUE
;