1 /* $Id: import.c,v 1.3 2001/09/04 21:05:26 ekohl Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/cm/import.c
6 * PURPOSE: Registry functions
7 * PROGRAMMERS: Rex Jolliff
12 #include <ddk/ntddk.h>
14 #include <internal/ob.h>
17 #include <internal/pool.h>
18 #include <internal/registry.h>
21 #include <internal/debug.h>
26 checkAndSkipMagic (PCHAR regChunk
)
28 if (strncmp (regChunk
,
30 strlen (REGISTRY_FILE_MAGIC
)) != 0)
32 CPRINT ("incorrect magic number in registry chunk. expected: %s got:%.*s\n",
34 strlen (REGISTRY_FILE_MAGIC
),
38 regChunk
+= strlen (REGISTRY_FILE_MAGIC
);
39 DPRINT ("Found regsitry chunk magic value\n");
45 skipWhitespaceInChunk (PCHAR regChunk
)
47 while (*regChunk
&& isspace (*regChunk
))
50 return *regChunk
? regChunk
: 0;
54 computeKeyNameSize (PCHAR regChunk
)
58 while (*regChunk
!= 0 && *regChunk
!= ']')
68 allocateKeyName (PUNICODE_STRING newKeyName
, int newKeySize
)
70 if (newKeyName
->MaximumLength
< (newKeySize
+ 1) * sizeof (WCHAR
))
72 if (newKeyName
->Buffer
!= 0)
73 ExFreePool (newKeyName
->Buffer
);
74 newKeyName
->Length
= 0;
75 newKeyName
->MaximumLength
= (newKeySize
+ 1) * sizeof (WCHAR
);
76 newKeyName
->Buffer
= ExAllocatePool (NonPagedPool
, newKeyName
->MaximumLength
);
77 if (newKeyName
->Buffer
== 0)
79 CPRINT ("Could not allocate space for key name\n");
82 newKeyName
->Buffer
[0] = 0;
86 newKeyName
->Length
= 0;
87 newKeyName
->Buffer
[0] = 0;
94 skipToNextKeyInChunk (PCHAR regChunk
)
96 while (*regChunk
!= 0 && *regChunk
!= '[')
98 while (*regChunk
!= 0 && *regChunk
!= '\n')
105 return *regChunk
? regChunk
: 0;
109 getKeyNameFromChunk (PCHAR regChunk
, PUNICODE_STRING newKeyName
)
113 while (*regChunk
!= 0 && *regChunk
!= ']')
115 newKeyName
->Buffer
[index
++] = *regChunk
++;
117 newKeyName
->Buffer
[index
] = '\0';
118 newKeyName
->Length
= index
* sizeof (WCHAR
);
120 return *regChunk
? regChunk
: 0;
124 createNewKey (PUNICODE_STRING newKeyName
)
127 OBJECT_ATTRIBUTES attributes
;
128 HANDLE handleToReturn
;
130 DPRINT ("Creating key (%wZ)\n", newKeyName
);
131 InitializeObjectAttributes (&attributes
,
136 status
= NtCreateKey (&handleToReturn
,
143 if (!NT_SUCCESS(status
))
145 CPRINT ("Could not crete key (%wZ)\n", newKeyName
);
146 return INVALID_HANDLE_VALUE
;
149 return handleToReturn
;
153 skipToNextKeyValueInChunk (PCHAR regChunk
)
155 while (*regChunk
!= 0 && *regChunk
!= '\n')
157 regChunk
= skipWhitespaceInChunk (regChunk
);
163 computeKeyValueNameSize (PCHAR regChunk
)
167 if (*regChunk
!= '\"')
170 while (*regChunk
!= 0 && *regChunk
!= '\"')
176 return regChunk
? size
: 0;
180 getKeyValueNameFromChunk (PCHAR regChunk
, PUNICODE_STRING newKeyName
)
185 while (*regChunk
!= 0 && *regChunk
!= '\"')
187 newKeyName
->Buffer
[index
++] = *regChunk
++;
189 newKeyName
->Buffer
[index
] = '\0';
190 newKeyName
->Length
= index
* sizeof (WCHAR
);
193 return *regChunk
? regChunk
: 0;
197 getKeyValueTypeFromChunk (PCHAR regChunk
, PCHAR dataFormat
, int *keyValueType
)
199 if (*regChunk
== '\"')
201 strcpy (dataFormat
, "string");
202 *keyValueType
= REG_SZ
;
204 else if (strncmp (regChunk
, "hex", 3) == 0)
206 strcpy (dataFormat
, "hex");
208 if (*regChunk
== '(')
211 *keyValueType
= atoi (regChunk
);
212 while (*regChunk
!= 0 && *regChunk
!= ')')
217 *keyValueType
= REG_BINARY
;
218 if (*regChunk
== ':')
226 return *regChunk
? regChunk
: 0;
230 computeKeyValueDataSize (PCHAR regChunk
, PCHAR dataFormat
)
234 if (strcmp (dataFormat
, "string") == 0)
237 while (*regChunk
!= 0 && *regChunk
!= '\"')
246 else if (strcmp (dataFormat
, "hex") == 0)
248 while (*regChunk
!= 0 && isxdigit(*regChunk
))
253 if (*regChunk
== ',')
256 if (*regChunk
== '\\')
259 regChunk
= skipWhitespaceInChunk (regChunk
);
273 allocateDataBuffer (PVOID
* data
, int * dataBufferSize
, int dataSize
)
275 if (*dataBufferSize
< dataSize
)
277 if (*dataBufferSize
> 0)
279 *data
= ExAllocatePool (NonPagedPool
, dataSize
);
280 *dataBufferSize
= dataSize
;
287 getKeyValueDataFromChunk (PCHAR regChunk
, PCHAR dataFormat
, PCHAR data
)
292 if (strcmp (dataFormat
, "string") == 0)
294 /* convert quoted string to zero-terminated Unicode string */
297 while (*regChunk
!= 0 && *regChunk
!= '\"')
299 *ptr
++ = (WCHAR
)*regChunk
++;
304 else if (strcmp (dataFormat
, "hex") == 0)
306 while (*regChunk
!= 0 && isxdigit (*regChunk
))
308 dataValue
= (isdigit (*regChunk
) ? *regChunk
- '0' :
309 tolower(*regChunk
) - 'a') << 4;
311 dataValue
+= (isdigit (*regChunk
) ? *regChunk
- '0' :
312 tolower(*regChunk
) - 'a');
315 if (*regChunk
== ',')
318 if (*regChunk
== '\\')
321 regChunk
= skipWhitespaceInChunk (regChunk
);
331 return *regChunk
? regChunk
: 0;
335 setKeyValue (HANDLE currentKey
,
336 PUNICODE_STRING newValueName
,
343 DPRINT ("Adding value (%wZ) to current key, with data type %d size %d\n",
347 status
= NtSetValueKey (currentKey
,
353 if (!NT_SUCCESS(status
))
355 CPRINT ("could not set key value, rc:%08x\n", status
);
363 CmImportHive(PCHAR ChunkBase
,
366 HANDLE currentKey
= INVALID_HANDLE_VALUE
;
368 UNICODE_STRING newKeyName
= {0, 0, 0};
369 char dataFormat
[10];
372 int dataBufferSize
= 0;
376 DPRINT("ChunkBase %p ChunkSize %lx\n", ChunkBase
, ChunkSize
);
378 regChunk
= checkAndSkipMagic (ChunkBase
);
382 while (regChunk
!= 0 && *regChunk
!= 0 && (((ULONG
)regChunk
-(ULONG
)ChunkBase
) < ChunkSize
))
384 regChunk
= skipWhitespaceInChunk (regChunk
);
388 if (*regChunk
== '[')
390 if (currentKey
!= INVALID_HANDLE_VALUE
)
392 DPRINT("Closing current key: 0x%lx\n", currentKey
);
393 NtClose (currentKey
);
394 currentKey
= INVALID_HANDLE_VALUE
;
399 newKeySize
= computeKeyNameSize (regChunk
);
400 if (!allocateKeyName (&newKeyName
, newKeySize
))
406 regChunk
= getKeyNameFromChunk (regChunk
, &newKeyName
);
410 currentKey
= createNewKey (&newKeyName
);
411 if (currentKey
== INVALID_HANDLE_VALUE
)
413 regChunk
= skipToNextKeyInChunk (regChunk
);
421 if (currentKey
== INVALID_HANDLE_VALUE
)
423 regChunk
= skipToNextKeyInChunk (regChunk
);
427 newKeySize
= computeKeyValueNameSize (regChunk
);
428 if (!allocateKeyName (&newKeyName
, newKeySize
))
434 regChunk
= getKeyValueNameFromChunk (regChunk
, &newKeyName
);
438 if (*regChunk
!= '=')
440 regChunk
= skipToNextKeyValueInChunk (regChunk
);
445 regChunk
= getKeyValueTypeFromChunk (regChunk
, dataFormat
, &keyValueType
);
449 dataSize
= computeKeyValueDataSize (regChunk
, dataFormat
);
450 if (!allocateDataBuffer (&data
, &dataBufferSize
, dataSize
))
456 regChunk
= getKeyValueDataFromChunk (regChunk
, dataFormat
, data
);
460 if (!setKeyValue (currentKey
, &newKeyName
, keyValueType
, data
, dataSize
))
468 if (currentKey
!= INVALID_HANDLE_VALUE
)
470 NtClose (currentKey
);
472 if (newKeyName
.Buffer
!= 0)
474 ExFreePool (newKeyName
.Buffer
);