1 /* $Id: import.c,v 1.5 2002/04/27 19:00:14 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
== ':')
221 else if (strncmp (regChunk
, "dword", 5) == 0)
223 strcpy (dataFormat
, "dword");
224 *keyValueType
= REG_DWORD
;
226 if (*regChunk
== ':')
229 else if (strncmp (regChunk
, "multi", 5) == 0)
231 strcpy (dataFormat
, "multi");
232 *keyValueType
= REG_MULTI_SZ
;
234 if (*regChunk
== ':')
242 return *regChunk
? regChunk
: 0;
246 computeKeyValueDataSize (PCHAR regChunk
, PCHAR dataFormat
)
250 if (strcmp (dataFormat
, "string") == 0)
253 while (*regChunk
!= 0 && *regChunk
!= '\"')
262 else if (strcmp (dataFormat
, "hex") == 0)
264 while (*regChunk
!= 0 && isxdigit(*regChunk
))
269 if (*regChunk
== ',')
272 if (*regChunk
== '\\')
275 regChunk
= skipWhitespaceInChunk (regChunk
);
280 else if (strcmp (dataFormat
, "dword") == 0)
282 dataSize
= sizeof(DWORD
);
283 while (*regChunk
!= 0 && isxdigit(*regChunk
))
288 else if (strcmp (dataFormat
, "multi") == 0)
290 while (*regChunk
== '\"')
293 while (*regChunk
!= 0 && *regChunk
!= '\"')
302 if (*regChunk
== ',')
305 regChunk
= skipWhitespaceInChunk (regChunk
);
306 if (*regChunk
== '\\')
309 regChunk
= skipWhitespaceInChunk (regChunk
);
327 allocateDataBuffer (PVOID
* data
, int * dataBufferSize
, int dataSize
)
329 if (*dataBufferSize
< dataSize
)
331 if (*dataBufferSize
> 0)
333 *data
= ExAllocatePool (NonPagedPool
, dataSize
);
334 *dataBufferSize
= dataSize
;
341 getKeyValueDataFromChunk (PCHAR regChunk
, PCHAR dataFormat
, PCHAR data
)
347 if (strcmp (dataFormat
, "string") == 0)
349 /* convert quoted string to zero-terminated Unicode string */
352 while (*regChunk
!= 0 && *regChunk
!= '\"')
354 *ptr
++ = (WCHAR
)*regChunk
++;
359 else if (strcmp (dataFormat
, "hex") == 0)
361 while (*regChunk
!= 0 && isxdigit (*regChunk
))
363 dataValue
= (isdigit (*regChunk
) ? *regChunk
- '0' :
364 tolower(*regChunk
) - 'a') << 4;
366 dataValue
+= (isdigit (*regChunk
) ? *regChunk
- '0' :
367 tolower(*regChunk
) - 'a');
370 if (*regChunk
== ',')
373 if (*regChunk
== '\\')
376 regChunk
= skipWhitespaceInChunk (regChunk
);
381 else if (strcmp (dataFormat
, "dword") == 0)
384 while (*regChunk
!= 0 && isxdigit(*regChunk
))
386 dataValue
= (isdigit (*regChunk
) ? *regChunk
- '0' :
387 tolower(*regChunk
) - 'a');
388 ulValue
= (ulValue
<< 4) + dataValue
;
391 memcpy(data
, &ulValue
, sizeof(ULONG
));
393 else if (strcmp (dataFormat
, "multi") == 0)
396 while (*regChunk
== '\"')
399 while (*regChunk
!= 0 && *regChunk
!= '\"')
401 *ptr
++ = (WCHAR
)*regChunk
++;
405 if (*regChunk
== ',')
408 regChunk
= skipWhitespaceInChunk (regChunk
);
409 if (*regChunk
== '\\')
412 regChunk
= skipWhitespaceInChunk (regChunk
);
425 return *regChunk
? regChunk
: 0;
429 setKeyValue (HANDLE currentKey
,
430 PUNICODE_STRING newValueName
,
437 DPRINT ("Adding value (%wZ) to current key, with data type %d size %d\n",
441 status
= NtSetValueKey (currentKey
,
447 if (!NT_SUCCESS(status
))
449 CPRINT ("could not set key value, rc:%08x\n", status
);
457 CmImportHive(PCHAR ChunkBase
,
460 HANDLE currentKey
= INVALID_HANDLE_VALUE
;
462 UNICODE_STRING newKeyName
= {0, 0, 0};
463 char dataFormat
[10];
466 int dataBufferSize
= 0;
470 DPRINT("ChunkBase %p ChunkSize %lx\n", ChunkBase
, ChunkSize
);
472 regChunk
= checkAndSkipMagic (ChunkBase
);
476 while (regChunk
!= 0 && *regChunk
!= 0 && (((ULONG
)regChunk
-(ULONG
)ChunkBase
) < ChunkSize
))
478 regChunk
= skipWhitespaceInChunk (regChunk
);
482 if (*regChunk
== '[')
484 if (currentKey
!= INVALID_HANDLE_VALUE
)
486 DPRINT("Closing current key: 0x%lx\n", currentKey
);
487 NtClose (currentKey
);
488 currentKey
= INVALID_HANDLE_VALUE
;
493 newKeySize
= computeKeyNameSize (regChunk
);
494 if (!allocateKeyName (&newKeyName
, newKeySize
))
500 regChunk
= getKeyNameFromChunk (regChunk
, &newKeyName
);
504 currentKey
= createNewKey (&newKeyName
);
505 if (currentKey
== INVALID_HANDLE_VALUE
)
507 regChunk
= skipToNextKeyInChunk (regChunk
);
515 if (currentKey
== INVALID_HANDLE_VALUE
)
517 regChunk
= skipToNextKeyInChunk (regChunk
);
521 newKeySize
= computeKeyValueNameSize (regChunk
);
522 if (!allocateKeyName (&newKeyName
, newKeySize
))
528 regChunk
= getKeyValueNameFromChunk (regChunk
, &newKeyName
);
532 if (*regChunk
!= '=')
534 regChunk
= skipToNextKeyValueInChunk (regChunk
);
539 regChunk
= getKeyValueTypeFromChunk (regChunk
, dataFormat
, &keyValueType
);
543 dataSize
= computeKeyValueDataSize (regChunk
, dataFormat
);
544 if (!allocateDataBuffer (&data
, &dataBufferSize
, dataSize
))
550 regChunk
= getKeyValueDataFromChunk (regChunk
, dataFormat
, data
);
554 if (!setKeyValue (currentKey
, &newKeyName
, keyValueType
, data
, dataSize
))
562 if (currentKey
!= INVALID_HANDLE_VALUE
)
564 NtClose (currentKey
);
566 if (newKeyName
.Buffer
!= 0)
568 ExFreePool (newKeyName
.Buffer
);