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
8 * PROGRAMMERS: Eric Kohl
11 /* INCLUDES *****************************************************************/
15 #include <internal/debug.h>
19 #if defined (ALLOC_PRAGMA)
20 #pragma alloc_text(INIT, CmImportHardwareHive)
23 /* GLOBALS ******************************************************************/
25 static BOOLEAN CmiHardwareHiveImported
= FALSE
;
28 /* FUNCTIONS ****************************************************************/
31 CmImportBinaryHive (PCHAR ChunkBase
,
34 PREGISTRY_HIVE
*RegistryHive
)
41 if (strncmp (ChunkBase
, "regf", 4))
43 DPRINT1 ("Found invalid '%*s' magic\n", 4, ChunkBase
);
47 /* Create a new hive */
48 Hive
= ExAllocatePool (NonPagedPool
,
49 sizeof(REGISTRY_HIVE
));
55 sizeof(REGISTRY_HIVE
));
60 /* Allocate hive header */
61 Hive
->HiveHeader
= (PHIVE_HEADER
)ExAllocatePool (NonPagedPool
,
63 if (Hive
->HiveHeader
== NULL
)
65 DPRINT1 ("Allocating hive header failed\n");
70 /* Import the hive header */
71 RtlCopyMemory (Hive
->HiveHeader
,
75 /* Read update counter */
76 Hive
->UpdateCounter
= Hive
->HiveHeader
->UpdateCounter1
;
78 /* Set the hive's size */
79 Hive
->FileSize
= ChunkSize
;
81 /* Set the size of the block list */
82 Hive
->BlockListSize
= (Hive
->FileSize
/ 4096) - 1;
84 /* Allocate block list */
85 DPRINT("Space needed for block list describing hive: 0x%x\n",
86 Hive
->BlockListSize
* sizeof(BLOCK_LIST_ENTRY
));
87 Hive
->BlockList
= ExAllocatePool (NonPagedPool
,
88 Hive
->BlockListSize
* sizeof(BLOCK_LIST_ENTRY
));
89 if (Hive
->BlockList
== NULL
)
91 DPRINT1 ("Allocating block list failed\n");
92 ExFreePool (Hive
->HiveHeader
);
96 RtlZeroMemory (Hive
->BlockList
,
97 Hive
->BlockListSize
* sizeof(BLOCK_LIST_ENTRY
));
100 Status
= CmiImportHiveBins(Hive
,
101 (PUCHAR
)((ULONG_PTR
)ChunkBase
+ 4096));
102 if (!NT_SUCCESS(Status
))
104 DPRINT1 ("CmiImportHiveBins() failed (Status %lx)\n", Status
);
105 CmiFreeHiveBins (Hive
);
106 ExFreePool (Hive
->BlockList
);
107 ExFreePool (Hive
->HiveHeader
);
109 return (BOOLEAN
)Status
;
112 /* Initialize the free cell list */
113 Status
= CmiCreateHiveFreeCellList (Hive
);
114 if (!NT_SUCCESS(Status
))
116 DPRINT1 ("CmiCreateHiveFreeCellList() failed (Status %lx)\n", Status
);
117 CmiFreeHiveBins (Hive
);
118 ExFreePool (Hive
->BlockList
);
119 ExFreePool (Hive
->HiveHeader
);
122 return (BOOLEAN
)Status
;
125 if (!(Hive
->Flags
& HIVE_NO_FILE
))
127 /* Create the block bitmap */
128 Status
= CmiCreateHiveBitmap (Hive
);
129 if (!NT_SUCCESS(Status
))
131 DPRINT1 ("CmiCreateHiveBitmap() failed (Status %lx)\n", Status
);
132 CmiFreeHiveFreeCellList (Hive
);
133 CmiFreeHiveBins (Hive
);
134 ExFreePool (Hive
->BlockList
);
135 ExFreePool (Hive
->HiveHeader
);
138 return (BOOLEAN
)Status
;
142 /* Acquire hive list lock exclusively */
143 KeEnterCriticalRegion();
144 ExAcquireResourceExclusiveLite(&CmiRegistryLock
, TRUE
);
146 /* Add the new hive to the hive list */
147 InsertTailList(&CmiHiveListHead
, &Hive
->HiveList
);
149 /* Release hive list lock */
150 ExReleaseResourceLite(&CmiRegistryLock
);
151 KeLeaveCriticalRegion();
153 *RegistryHive
= Hive
;
159 BOOLEAN INIT_FUNCTION
160 CmImportSystemHive(PCHAR ChunkBase
,
163 OBJECT_ATTRIBUTES ObjectAttributes
;
164 PREGISTRY_HIVE RegistryHive
;
165 UNICODE_STRING KeyName
;
168 DPRINT ("CmImportSystemHive() called\n");
170 if (strncmp (ChunkBase
, "regf", 4))
172 DPRINT1 ("Found invalid '%.*s' magic\n", 4, ChunkBase
);
176 DPRINT ("Found '%.*s' magic\n", 4, ChunkBase
);
178 /* Import the binary system hive (non-volatile, offset-based, permanent) */
179 if (!CmImportBinaryHive (ChunkBase
, ChunkSize
, 0, &RegistryHive
))
181 DPRINT1 ("CmiImportBinaryHive() failed\n");
185 /* Attach it to the machine key */
186 RtlInitUnicodeString (&KeyName
,
187 REG_SYSTEM_KEY_NAME
);
188 InitializeObjectAttributes (&ObjectAttributes
,
190 OBJ_CASE_INSENSITIVE
,
193 Status
= CmiConnectHive (&ObjectAttributes
,
195 if (!NT_SUCCESS(Status
))
197 DPRINT1 ("CmiConnectHive(%wZ) failed (Status %lx)\n", &KeyName
, Status
);
198 // CmiRemoveRegistryHive(RegistryHive);
202 /* Set the hive filename */
203 RtlCreateUnicodeString (&RegistryHive
->HiveFileName
,
206 /* Set the log filename */
207 RtlCreateUnicodeString (&RegistryHive
->LogFileName
,
214 BOOLEAN INIT_FUNCTION
215 CmImportHardwareHive(PCHAR ChunkBase
,
218 OBJECT_ATTRIBUTES ObjectAttributes
;
219 PREGISTRY_HIVE RegistryHive
;
220 UNICODE_STRING KeyName
;
225 DPRINT ("CmImportHardwareHive() called\n");
227 if (CmiHardwareHiveImported
== TRUE
)
230 if (ChunkBase
== NULL
&&
233 /* Create '\Registry\Machine\HARDWARE' key. */
234 RtlInitUnicodeString (&KeyName
,
235 REG_HARDWARE_KEY_NAME
);
236 InitializeObjectAttributes (&ObjectAttributes
,
238 OBJ_CASE_INSENSITIVE
,
241 Status
= ZwCreateKey (&HardwareKey
,
248 if (!NT_SUCCESS(Status
))
250 DPRINT1("NtCreateKey() failed, status: 0x%x\n", Status
);
253 ZwClose (HardwareKey
);
255 /* Create '\Registry\Machine\HARDWARE\DESCRIPTION' key. */
256 RtlInitUnicodeString(&KeyName
,
257 REG_DESCRIPTION_KEY_NAME
);
258 InitializeObjectAttributes (&ObjectAttributes
,
260 OBJ_CASE_INSENSITIVE
,
263 Status
= ZwCreateKey (&HardwareKey
,
270 if (!NT_SUCCESS(Status
))
272 DPRINT1("NtCreateKey() failed, status: 0x%x\n", Status
);
275 ZwClose (HardwareKey
);
277 /* Create '\Registry\Machine\HARDWARE\DEVICEMAP' key. */
278 RtlInitUnicodeString (&KeyName
,
279 REG_DEVICEMAP_KEY_NAME
);
280 InitializeObjectAttributes (&ObjectAttributes
,
282 OBJ_CASE_INSENSITIVE
,
285 Status
= ZwCreateKey (&HardwareKey
,
292 if (!NT_SUCCESS(Status
))
294 DPRINT1("NtCreateKey() failed, status: 0x%x\n", Status
);
297 ZwClose (HardwareKey
);
299 /* Create '\Registry\Machine\HARDWARE\RESOURCEMAP' key. */
300 RtlInitUnicodeString(&KeyName
,
301 REG_RESOURCEMAP_KEY_NAME
);
302 InitializeObjectAttributes (&ObjectAttributes
,
304 OBJ_CASE_INSENSITIVE
,
307 Status
= ZwCreateKey (&HardwareKey
,
314 if (!NT_SUCCESS(Status
))
316 DPRINT1("NtCreateKey() failed, status: 0x%x\n", Status
);
319 ZwClose (HardwareKey
);
324 /* Check the hive magic */
325 if (strncmp (ChunkBase
, "regf", 4))
327 DPRINT1 ("Found invalid '%.*s' magic\n", 4, ChunkBase
);
331 DPRINT ("Found '%.*s' magic\n", 4, ChunkBase
);
332 DPRINT ("ChunkBase %lx ChunkSize %lu\n", ChunkBase
, ChunkSize
);
334 /* Import the binary system hive (volatile, offset-based, permanent) */
335 if (!CmImportBinaryHive (ChunkBase
, ChunkSize
, HIVE_NO_FILE
, &RegistryHive
))
337 DPRINT1 ("CmiImportBinaryHive() failed\n");
341 /* Attach it to the machine key */
342 RtlInitUnicodeString (&KeyName
,
343 REG_HARDWARE_KEY_NAME
);
344 InitializeObjectAttributes (&ObjectAttributes
,
346 OBJ_CASE_INSENSITIVE
,
349 Status
= CmiConnectHive (&ObjectAttributes
,
351 if (!NT_SUCCESS(Status
))
353 DPRINT1 ("CmiConnectHive(%wZ) failed (Status %lx)\n", &KeyName
, Status
);
354 // CmiRemoveRegistryHive(RegistryHive);
358 /* Set the hive filename */
359 RtlInitUnicodeString (&RegistryHive
->HiveFileName
,
362 /* Set the log filename */
363 RtlInitUnicodeString (&RegistryHive
->LogFileName
,
366 CmiHardwareHiveImported
= TRUE
;