1 /* $Id: import.c,v 1.6 2002/05/24 07:42:19 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
== ':')
237 else if (strncmp (regChunk
, "expand", 6) == 0)
239 strcpy (dataFormat
, "expand");
240 *keyValueType
= REG_EXPAND_SZ
;
242 if (*regChunk
== ':')
250 return *regChunk
? regChunk
: 0;
254 computeKeyValueDataSize (PCHAR regChunk
, PCHAR dataFormat
)
258 if (strcmp (dataFormat
, "string") == 0)
261 while (*regChunk
!= 0 && *regChunk
!= '\"')
270 else if (strcmp (dataFormat
, "hex") == 0)
272 while (*regChunk
!= 0 && isxdigit(*regChunk
))
277 if (*regChunk
== ',')
280 if (*regChunk
== '\\')
283 regChunk
= skipWhitespaceInChunk (regChunk
);
288 else if (strcmp (dataFormat
, "dword") == 0)
290 dataSize
= sizeof(DWORD
);
291 while (*regChunk
!= 0 && isxdigit(*regChunk
))
296 else if (strcmp (dataFormat
, "multi") == 0)
298 while (*regChunk
== '\"')
301 while (*regChunk
!= 0 && *regChunk
!= '\"')
310 if (*regChunk
== ',')
313 regChunk
= skipWhitespaceInChunk (regChunk
);
314 if (*regChunk
== '\\')
317 regChunk
= skipWhitespaceInChunk (regChunk
);
326 else if (strcmp (dataFormat
, "expand") == 0)
329 while (*regChunk
!= 0 && *regChunk
!= '\"')
347 allocateDataBuffer (PVOID
* data
, int * dataBufferSize
, int dataSize
)
349 if (*dataBufferSize
< dataSize
)
351 if (*dataBufferSize
> 0)
353 *data
= ExAllocatePool (NonPagedPool
, dataSize
);
354 *dataBufferSize
= dataSize
;
361 getKeyValueDataFromChunk (PCHAR regChunk
, PCHAR dataFormat
, PCHAR data
)
367 if (strcmp (dataFormat
, "string") == 0)
369 /* convert quoted string to zero-terminated Unicode string */
372 while (*regChunk
!= 0 && *regChunk
!= '\"')
374 *ptr
++ = (WCHAR
)*regChunk
++;
379 else if (strcmp (dataFormat
, "hex") == 0)
381 while (*regChunk
!= 0 && isxdigit (*regChunk
))
383 dataValue
= (isdigit (*regChunk
) ? *regChunk
- '0' :
384 tolower(*regChunk
) - 'a') << 4;
386 dataValue
+= (isdigit (*regChunk
) ? *regChunk
- '0' :
387 tolower(*regChunk
) - 'a');
390 if (*regChunk
== ',')
393 if (*regChunk
== '\\')
396 regChunk
= skipWhitespaceInChunk (regChunk
);
401 else if (strcmp (dataFormat
, "dword") == 0)
404 while (*regChunk
!= 0 && isxdigit(*regChunk
))
406 dataValue
= (isdigit (*regChunk
) ? *regChunk
- '0' :
407 tolower(*regChunk
) - 'a');
408 ulValue
= (ulValue
<< 4) + dataValue
;
411 memcpy(data
, &ulValue
, sizeof(ULONG
));
413 else if (strcmp (dataFormat
, "multi") == 0)
416 while (*regChunk
== '\"')
419 while (*regChunk
!= 0 && *regChunk
!= '\"')
421 *ptr
++ = (WCHAR
)*regChunk
++;
425 if (*regChunk
== ',')
428 regChunk
= skipWhitespaceInChunk (regChunk
);
429 if (*regChunk
== '\\')
432 regChunk
= skipWhitespaceInChunk (regChunk
);
440 else if (strcmp (dataFormat
, "expand") == 0)
442 /* convert quoted string to zero-terminated Unicode string */
445 while (*regChunk
!= 0 && *regChunk
!= '\"')
447 *ptr
++ = (WCHAR
)*regChunk
++;
457 return *regChunk
? regChunk
: 0;
461 setKeyValue (HANDLE currentKey
,
462 PUNICODE_STRING newValueName
,
469 DPRINT ("Adding value (%wZ) to current key, with data type %d size %d\n",
473 status
= NtSetValueKey (currentKey
,
479 if (!NT_SUCCESS(status
))
481 CPRINT ("could not set key value, rc:%08x\n", status
);
489 CmImportHive(PCHAR ChunkBase
,
492 HANDLE currentKey
= INVALID_HANDLE_VALUE
;
494 UNICODE_STRING newKeyName
= {0, 0, 0};
495 char dataFormat
[10];
498 int dataBufferSize
= 0;
502 DPRINT("ChunkBase %p ChunkSize %lx\n", ChunkBase
, ChunkSize
);
504 regChunk
= checkAndSkipMagic (ChunkBase
);
508 while (regChunk
!= 0 && *regChunk
!= 0 && (((ULONG
)regChunk
-(ULONG
)ChunkBase
) < ChunkSize
))
510 regChunk
= skipWhitespaceInChunk (regChunk
);
514 if (*regChunk
== '[')
516 if (currentKey
!= INVALID_HANDLE_VALUE
)
518 DPRINT("Closing current key: 0x%lx\n", currentKey
);
519 NtClose (currentKey
);
520 currentKey
= INVALID_HANDLE_VALUE
;
525 newKeySize
= computeKeyNameSize (regChunk
);
526 if (!allocateKeyName (&newKeyName
, newKeySize
))
532 regChunk
= getKeyNameFromChunk (regChunk
, &newKeyName
);
536 currentKey
= createNewKey (&newKeyName
);
537 if (currentKey
== INVALID_HANDLE_VALUE
)
539 regChunk
= skipToNextKeyInChunk (regChunk
);
547 if (currentKey
== INVALID_HANDLE_VALUE
)
549 regChunk
= skipToNextKeyInChunk (regChunk
);
553 newKeySize
= computeKeyValueNameSize (regChunk
);
554 if (!allocateKeyName (&newKeyName
, newKeySize
))
560 regChunk
= getKeyValueNameFromChunk (regChunk
, &newKeyName
);
564 if (*regChunk
!= '=')
566 regChunk
= skipToNextKeyValueInChunk (regChunk
);
571 regChunk
= getKeyValueTypeFromChunk (regChunk
, dataFormat
, &keyValueType
);
575 dataSize
= computeKeyValueDataSize (regChunk
, dataFormat
);
576 if (!allocateDataBuffer (&data
, &dataBufferSize
, dataSize
))
582 regChunk
= getKeyValueDataFromChunk (regChunk
, dataFormat
, data
);
586 if (!setKeyValue (currentKey
, &newKeyName
, keyValueType
, data
, dataSize
))
594 if (currentKey
!= INVALID_HANDLE_VALUE
)
596 NtClose (currentKey
);
598 if (newKeyName
.Buffer
!= 0)
600 ExFreePool (newKeyName
.Buffer
);