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 <ddk/ntddk.h>
16 #include <internal/ob.h>
19 #include <internal/pool.h>
20 #include <internal/registry.h>
21 #include <internal/ntoskrnl.h>
24 #include <internal/debug.h>
28 /* GLOBALS ******************************************************************/
30 static BOOLEAN CmiHardwareHiveImported = FALSE;
33 /* FUNCTIONS ****************************************************************/
36 CmImportBinaryHive (PCHAR ChunkBase,
39 PREGISTRY_HIVE *RegistryHive)
46 if (strncmp (ChunkBase, "regf", 4))
48 DPRINT1 ("Found invalid '%*s' magic\n", 4, ChunkBase);
52 /* Create a new hive */
53 Hive = ExAllocatePool (NonPagedPool,
54 sizeof(REGISTRY_HIVE));
60 sizeof(REGISTRY_HIVE));
65 /* Allocate hive header */
66 Hive->HiveHeader = (PHIVE_HEADER)ExAllocatePool (NonPagedPool,
68 if (Hive->HiveHeader == NULL)
70 DPRINT1 ("Allocating hive header failed\n");
75 /* Import the hive header */
76 RtlCopyMemory (Hive->HiveHeader,
80 /* Read update counter */
81 Hive->UpdateCounter = Hive->HiveHeader->UpdateCounter1;
83 /* Set the hive's size */
84 Hive->FileSize = ChunkSize;
86 /* Set the size of the block list */
87 Hive->BlockListSize = (Hive->FileSize / 4096) - 1;
89 /* Allocate block list */
90 DPRINT("Space needed for block list describing hive: 0x%x\n",
91 Hive->BlockListSize * sizeof(PHBIN *));
92 Hive->BlockList = ExAllocatePool (NonPagedPool,
93 Hive->BlockListSize * sizeof(PHBIN *));
94 if (Hive->BlockList == NULL)
96 DPRINT1 ("Allocating block list failed\n");
97 ExFreePool (Hive->HiveHeader);
101 RtlZeroMemory (Hive->BlockList,
102 Hive->BlockListSize * sizeof(PHBIN *));
104 /* Import the bins */
105 Status = CmiImportHiveBins(Hive,
106 (PUCHAR)((ULONG_PTR)ChunkBase + 4096));
107 if (!NT_SUCCESS(Status))
109 DPRINT1 ("CmiImportHiveBins() failed (Status %lx)\n", Status);
110 CmiFreeHiveBins (Hive);
111 ExFreePool (Hive->BlockList);
112 ExFreePool (Hive->HiveHeader);
117 /* Initialize the free cell list */
118 Status = CmiCreateHiveFreeCellList (Hive);
119 if (!NT_SUCCESS(Status))
121 DPRINT1 ("CmiCreateHiveFreeCellList() failed (Status %lx)\n", Status);
122 CmiFreeHiveBins (Hive);
123 ExFreePool (Hive->BlockList);
124 ExFreePool (Hive->HiveHeader);
130 if (!(Hive->Flags & HIVE_NO_FILE))
132 /* Create the block bitmap */
133 Status = CmiCreateHiveBitmap (Hive);
134 if (!NT_SUCCESS(Status))
136 DPRINT1 ("CmiCreateHiveBitmap() failed (Status %lx)\n", Status);
137 CmiFreeHiveFreeCellList (Hive);
138 CmiFreeHiveBins (Hive);
139 ExFreePool (Hive->BlockList);
140 ExFreePool (Hive->HiveHeader);
147 /* Initialize the hive's executive resource */
148 ExInitializeResourceLite(&Hive->HiveResource);
150 /* Acquire hive list lock exclusively */
151 ExAcquireResourceExclusiveLite(&CmiHiveListLock, TRUE);
153 /* Add the new hive to the hive list */
154 InsertTailList(&CmiHiveListHead, &Hive->HiveList);
156 /* Release hive list lock */
157 ExReleaseResourceLite(&CmiHiveListLock);
159 *RegistryHive = Hive;
166 CmImportSystemHive(PCHAR ChunkBase,
169 OBJECT_ATTRIBUTES ObjectAttributes;
170 PREGISTRY_HIVE RegistryHive;
171 UNICODE_STRING KeyName;
174 DPRINT ("CmImportSystemHive() called\n");
176 if (strncmp (ChunkBase, "regf", 4))
178 DPRINT1 ("Found invalid '%.*s' magic\n", 4, ChunkBase);
182 DPRINT ("Found '%.*s' magic\n", 4, ChunkBase);
184 /* Import the binary system hive (non-volatile, offset-based, permanent) */
185 if (!CmImportBinaryHive (ChunkBase, ChunkSize, 0, &RegistryHive))
187 DPRINT1 ("CmiImportBinaryHive() failed\n", Status);
191 /* Attach it to the machine key */
192 RtlInitUnicodeString (&KeyName,
193 L"\\Registry\\Machine\\System");
194 InitializeObjectAttributes (&ObjectAttributes,
196 OBJ_CASE_INSENSITIVE,
199 Status = CmiConnectHive (&ObjectAttributes,
201 if (!NT_SUCCESS(Status))
203 DPRINT1 ("CmiConnectHive() failed (Status %lx)\n", Status);
204 // CmiRemoveRegistryHive(RegistryHive);
208 /* Set the hive filename */
209 RtlCreateUnicodeString (&RegistryHive->HiveFileName,
212 /* Set the log filename */
213 RtlCreateUnicodeString (&RegistryHive->LogFileName,
221 CmImportHardwareHive(PCHAR ChunkBase,
224 OBJECT_ATTRIBUTES ObjectAttributes;
225 PREGISTRY_HIVE RegistryHive;
226 UNICODE_STRING KeyName;
231 DPRINT ("CmImportHardwareHive() called\n");
233 if (CmiHardwareHiveImported == TRUE)
236 if (ChunkBase == NULL &&
239 /* Create '\Registry\Machine\HARDWARE' key. */
240 RtlInitUnicodeString (&KeyName,
241 L"\\Registry\\Machine\\HARDWARE");
242 InitializeObjectAttributes (&ObjectAttributes,
244 OBJ_CASE_INSENSITIVE,
247 Status = NtCreateKey (&HardwareKey,
254 if (!NT_SUCCESS(Status))
258 NtClose (HardwareKey);
260 /* Create '\Registry\Machine\HARDWARE\DESCRIPTION' key. */
261 RtlInitUnicodeString(&KeyName,
262 L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION");
263 InitializeObjectAttributes (&ObjectAttributes,
265 OBJ_CASE_INSENSITIVE,
268 Status = NtCreateKey (&HardwareKey,
275 if (!NT_SUCCESS(Status))
279 NtClose (HardwareKey);
281 /* Create '\Registry\Machine\HARDWARE\DEVICEMAP' key. */
282 RtlInitUnicodeString (&KeyName,
283 L"\\Registry\\Machine\\HARDWARE\\DEVICEMAP");
284 InitializeObjectAttributes (&ObjectAttributes,
286 OBJ_CASE_INSENSITIVE,
289 Status = NtCreateKey (&HardwareKey,
296 if (!NT_SUCCESS(Status))
300 NtClose (HardwareKey);
302 /* Create '\Registry\Machine\HARDWARE\RESOURCEMAP' key. */
303 RtlInitUnicodeString(&KeyName,
304 L"\\Registry\\Machine\\HARDWARE\\RESOURCEMAP");
305 InitializeObjectAttributes (&ObjectAttributes,
307 OBJ_CASE_INSENSITIVE,
310 Status = NtCreateKey (&HardwareKey,
317 if (!NT_SUCCESS(Status))
321 NtClose (HardwareKey);
326 /* Check the hive magic */
327 if (strncmp (ChunkBase, "regf", 4))
329 DPRINT1 ("Found invalid '%.*s' magic\n", 4, ChunkBase);
333 DPRINT ("Found '%.*s' magic\n", 4, ChunkBase);
334 DPRINT ("ChunkBase %lx ChunkSize %lu\n", ChunkBase, ChunkSize);
336 /* Import the binary system hive (volatile, offset-based, permanent) */
337 if (!CmImportBinaryHive (ChunkBase, ChunkSize, HIVE_NO_FILE, &RegistryHive))
339 DPRINT1 ("CmiImportBinaryHive() failed\n", Status);
343 /* Attach it to the machine key */
344 RtlInitUnicodeString (&KeyName,
345 L"\\Registry\\Machine\\HARDWARE");
346 InitializeObjectAttributes (&ObjectAttributes,
348 OBJ_CASE_INSENSITIVE,
351 Status = CmiConnectHive (&ObjectAttributes,
353 if (!NT_SUCCESS(Status))
355 DPRINT1 ("CmiConnectHive() failed (Status %lx)\n", Status);
356 // CmiRemoveRegistryHive(RegistryHive);
360 /* Set the hive filename */
361 RtlInitUnicodeString (&RegistryHive->HiveFileName,
364 /* Set the log filename */
365 RtlInitUnicodeString (&RegistryHive->LogFileName,
368 CmiHardwareHiveImported = TRUE;