1 /* $Id: import.c,v 1.1 2001/08/29 05:06:31 rex 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>
13 #include <internal/config.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
!= '\"')
243 else if (strcmp (dataFormat
, "hex") == 0)
245 while (*regChunk
!= 0 && isxdigit(*regChunk
))
250 if (*regChunk
== ',')
253 if (*regChunk
== '\\')
255 regChunk
= skipWhitespaceInChunk (regChunk
);
269 allocateDataBuffer (PVOID
* data
, int * dataBufferSize
, int dataSize
)
271 if (*dataBufferSize
< dataSize
)
273 if (*dataBufferSize
> 0)
275 *data
= ExAllocatePool (NonPagedPool
, dataSize
);
276 *dataBufferSize
= dataSize
;
283 getKeyValueDataFromChunk (PCHAR regChunk
, PCHAR dataFormat
, PCHAR data
)
287 if (strcmp (dataFormat
, "string") == 0)
290 while (*regChunk
!= 0 && *regChunk
!= '\"')
292 *data
++ = *regChunk
++;
295 else if (strcmp (dataFormat
, "hex") == 0)
297 while (*regChunk
!= 0 && isxdigit (*regChunk
))
299 dataValue
= (isdigit (*regChunk
) ? *regChunk
- '0' :
300 tolower(*regChunk
) - 'a') << 4;
302 dataValue
+= (isdigit (*regChunk
) ? *regChunk
- '0' :
303 tolower(*regChunk
) - 'a');
306 if (*regChunk
== ',')
309 if (*regChunk
== '\\')
311 regChunk
= skipWhitespaceInChunk (regChunk
);
321 return *regChunk
? regChunk
: 0;
325 setKeyValue (HANDLE currentKey
,
326 PUNICODE_STRING newValueName
,
333 DPRINT ("Adding value (%wZ) to current key, with data type %d size %d\n",
337 status
= NtSetValueKey (currentKey
,
343 if (!NT_SUCCESS(status
))
345 CPRINT ("could not set key value, rc:%08x\n", status
);
353 CmImportHive(PCHAR regChunk
)
355 HANDLE currentKey
= INVALID_HANDLE_VALUE
;
357 UNICODE_STRING newKeyName
= {0, 0, 0};
358 char dataFormat
[10];
361 int dataBufferSize
= 0;
364 regChunk
= checkAndSkipMagic (regChunk
);
368 while (regChunk
!= 0 && *regChunk
!= 0)
370 regChunk
= skipWhitespaceInChunk (regChunk
);
374 if (*regChunk
== '[')
376 if (currentKey
!= INVALID_HANDLE_VALUE
)
378 NtClose (currentKey
);
379 currentKey
= INVALID_HANDLE_VALUE
;
384 newKeySize
= computeKeyNameSize (regChunk
);
385 if (!allocateKeyName (&newKeyName
, newKeySize
))
391 regChunk
= getKeyNameFromChunk (regChunk
, &newKeyName
);
395 currentKey
= createNewKey (&newKeyName
);
396 if (currentKey
== INVALID_HANDLE_VALUE
)
398 regChunk
= skipToNextKeyInChunk (regChunk
);
406 if (currentKey
== INVALID_HANDLE_VALUE
)
408 regChunk
= skipToNextKeyInChunk (regChunk
);
412 newKeySize
= computeKeyValueNameSize (regChunk
);
413 if (!allocateKeyName (&newKeyName
, newKeySize
))
419 regChunk
= getKeyValueNameFromChunk (regChunk
, &newKeyName
);
423 if (*regChunk
!= '=')
425 regChunk
= skipToNextKeyValueInChunk (regChunk
);
430 regChunk
= getKeyValueTypeFromChunk (regChunk
, dataFormat
, &keyValueType
);
434 dataSize
= computeKeyValueDataSize (regChunk
, dataFormat
);
435 if (!allocateDataBuffer (&data
, &dataBufferSize
, dataSize
))
441 regChunk
= getKeyValueDataFromChunk (regChunk
, dataFormat
, data
);
445 if (!setKeyValue (currentKey
, &newKeyName
, keyValueType
, data
, dataSize
))
453 if (currentKey
!= INVALID_HANDLE_VALUE
)
455 NtClose (currentKey
);
457 if (newKeyName
.Buffer
!= 0)
459 ExFreePool (newKeyName
.Buffer
);