3 * Copyright (C) 2003 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 /* $Id: registry.c,v 1.1 2003/04/14 17:18:48 ekohl Exp $
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS hive maker
22 * FILE: tools/mkhive/registry.c
23 * PURPOSE: Registry code
24 * PROGRAMMER: Eric Kohl
29 * - Implement RegDeleteKey().
30 * - Implement RegQueryMultipleValue().
31 * - Fix RegEnumValue().
45 RegInitializeRegistry(VOID
)
48 RootKey
= (HKEY
)malloc(sizeof(KEY
));
50 InitializeListHead(&RootKey
->SubKeyList
);
51 InitializeListHead(&RootKey
->ValueList
);
52 InitializeListHead(&RootKey
->KeyList
);
54 RootKey
->NameSize
= 2;
55 RootKey
->Name
= (PUCHAR
)malloc(2);
56 strcpy(RootKey
->Name
, "\\");
58 RootKey
->DataType
= 0;
59 RootKey
->DataSize
= 0;
62 /* Create SYSTEM key */
64 "Registry\\Machine\\SYSTEM",
67 /* Create HARDWARE key */
69 "Registry\\Machine\\HARDWARE",
75 RegCreateKey(HKEY ParentKey
,
80 HKEY SearchKey
= INVALID_HANDLE_VALUE
;
88 DPRINT ("KeyName '%s'\n", KeyName
);
95 else if (ParentKey
== NULL
)
101 CurrentKey
= ParentKey
;
104 /* Check whether current key is a link */
105 if (CurrentKey
->DataType
== REG_LINK
)
107 CurrentKey
= (HKEY
)CurrentKey
->Data
;
110 while (*KeyName
!= 0)
112 DPRINT ("KeyName '%s'\n", KeyName
);
114 if (*KeyName
== '\\')
116 p
= strchr (KeyName
, '\\');
117 if ((p
!= NULL
) && (p
!= KeyName
))
119 subkeyLength
= p
- KeyName
;
120 stringLength
= subkeyLength
+ 1;
125 subkeyLength
= strlen (KeyName
);
126 stringLength
= subkeyLength
;
130 Ptr
= CurrentKey
->SubKeyList
.Flink
;
131 while (Ptr
!= &CurrentKey
->SubKeyList
)
133 DPRINT ("Ptr 0x%x\n", Ptr
);
135 SearchKey
= CONTAINING_RECORD(Ptr
,
138 DPRINT ("SearchKey 0x%x\n", SearchKey
);
139 DPRINT ("Searching '%s'\n", SearchKey
->Name
);
140 if (strncmp (SearchKey
->Name
, name
, subkeyLength
) == 0)
146 if (Ptr
== &CurrentKey
->SubKeyList
)
148 /* no key found -> create new subkey */
149 NewKey
= (HKEY
)malloc (sizeof(KEY
));
151 return ERROR_OUTOFMEMORY
;
153 InitializeListHead (&NewKey
->SubKeyList
);
154 InitializeListHead (&NewKey
->ValueList
);
156 NewKey
->DataType
= 0;
157 NewKey
->DataSize
= 0;
160 InsertTailList (&CurrentKey
->SubKeyList
, &NewKey
->KeyList
);
161 NewKey
->NameSize
= subkeyLength
+ 1;
162 NewKey
->Name
= (PCHAR
)malloc (NewKey
->NameSize
);
163 if (NewKey
->Name
== NULL
)
164 return(ERROR_OUTOFMEMORY
);
165 memcpy(NewKey
->Name
, name
, subkeyLength
);
166 NewKey
->Name
[subkeyLength
] = 0;
168 DPRINT ("NewKey 0x%x\n", NewKey
);
169 DPRINT ("NewKey '%s' Length %d\n", NewKey
->Name
, NewKey
->NameSize
);
175 CurrentKey
= SearchKey
;
177 /* Check whether current key is a link */
178 if (CurrentKey
->DataType
== REG_LINK
)
180 CurrentKey
= (HKEY
)CurrentKey
->Data
;
184 KeyName
= KeyName
+ stringLength
;
190 return ERROR_SUCCESS
;
195 RegDeleteKey(HKEY Key
,
200 if (strchr(Name
, '\\') != NULL
)
201 return(ERROR_INVALID_PARAMETER
);
205 return(ERROR_SUCCESS
);
220 Ptr
= Key
->SubKeyList
.Flink
;
221 while (Ptr
!= &Key
->SubKeyList
)
230 if (Ptr
== &Key
->SubKeyList
)
231 return(ERROR_NO_MORE_ITEMS
);
233 SearchKey
= CONTAINING_RECORD(Ptr
,
237 DPRINT ("Name '%s' Length %d\n", SearchKey
->Name
, SearchKey
->NameSize
);
239 Size
= min(SearchKey
->NameSize
, *NameSize
);
241 memcpy(Name
, SearchKey
->Name
, Size
);
243 return(ERROR_SUCCESS
);
248 RegOpenKey(HKEY ParentKey
,
253 HKEY SearchKey
= INVALID_HANDLE_VALUE
;
260 DPRINT("KeyName '%s'\n", KeyName
);
264 if (*KeyName
== '\\')
267 CurrentKey
= RootKey
;
269 else if (ParentKey
== NULL
)
271 CurrentKey
= RootKey
;
275 CurrentKey
= ParentKey
;
278 /* Check whether current key is a link */
279 if (CurrentKey
->DataType
== REG_LINK
)
281 CurrentKey
= (HKEY
)CurrentKey
->Data
;
284 while (*KeyName
!= 0)
286 DPRINT ("KeyName '%s'\n", KeyName
);
288 if (*KeyName
== '\\')
290 p
= strchr(KeyName
, '\\');
291 if ((p
!= NULL
) && (p
!= KeyName
))
293 subkeyLength
= p
- KeyName
;
294 stringLength
= subkeyLength
+ 1;
299 subkeyLength
= strlen(KeyName
);
300 stringLength
= subkeyLength
;
304 Ptr
= CurrentKey
->SubKeyList
.Flink
;
305 while (Ptr
!= &CurrentKey
->SubKeyList
)
307 DPRINT ("Ptr 0x%x\n", Ptr
);
309 SearchKey
= CONTAINING_RECORD(Ptr
,
313 DPRINT ("SearchKey 0x%x\n", SearchKey
);
314 DPRINT ("Searching '%s'\n", SearchKey
->Name
);
316 if (strncmp(SearchKey
->Name
, name
, subkeyLength
) == 0)
322 if (Ptr
== &CurrentKey
->SubKeyList
)
324 return(ERROR_PATH_NOT_FOUND
);
328 CurrentKey
= SearchKey
;
330 /* Check whether current key is a link */
331 if (CurrentKey
->DataType
== REG_LINK
)
333 CurrentKey
= (HKEY
)CurrentKey
->Data
;
337 KeyName
= KeyName
+ stringLength
;
343 return(ERROR_SUCCESS
);
348 RegSetValue(HKEY Key
,
357 DPRINT ("Key 0x%x, ValueName '%s', Type %d, Data 0x%x, DataSize %d\n",
358 (int)Key
, ValueName
, (int)Type
, (int)Data
, (int)DataSize
);
360 if ((ValueName
== NULL
) || (*ValueName
== 0))
362 /* set default value */
363 if ((Key
->Data
!= NULL
) && (Key
->DataSize
> sizeof(PUCHAR
)))
368 if (DataSize
<= sizeof(PUCHAR
))
370 Key
->DataSize
= DataSize
;
371 Key
->DataType
= Type
;
372 memcpy(&Key
->Data
, Data
, DataSize
);
376 Key
->Data
= (PUCHAR
)malloc(DataSize
);
377 Key
->DataSize
= DataSize
;
378 Key
->DataType
= Type
;
379 memcpy(Key
->Data
, Data
, DataSize
);
384 /* set non-default value */
385 Ptr
= Key
->ValueList
.Flink
;
386 while (Ptr
!= &Key
->ValueList
)
388 Value
= CONTAINING_RECORD(Ptr
,
392 DPRINT ("Value->Name '%s'\n", Value
->Name
);
394 if (stricmp(Value
->Name
, ValueName
) == 0)
400 if (Ptr
== &Key
->ValueList
)
403 DPRINT("No value found - adding new value\n");
405 Value
= (PVALUE
)malloc(sizeof(VALUE
));
407 return(ERROR_OUTOFMEMORY
);
408 InsertTailList(&Key
->ValueList
, &Value
->ValueList
);
409 Value
->NameSize
= strlen(ValueName
)+1;
410 Value
->Name
= (PCHAR
)malloc(Value
->NameSize
);
411 if (Value
->Name
== NULL
)
412 return(ERROR_OUTOFMEMORY
);
413 strcpy(Value
->Name
, ValueName
);
414 Value
->DataType
= REG_NONE
;
420 if ((Value
->Data
!= NULL
) && (Value
->DataSize
> sizeof(PUCHAR
)))
425 if (DataSize
<= sizeof(PUCHAR
))
427 Value
->DataSize
= DataSize
;
428 Value
->DataType
= Type
;
429 memcpy(&Value
->Data
, Data
, DataSize
);
433 Value
->Data
= (PUCHAR
)malloc(DataSize
);
434 if (Value
->Data
== NULL
)
435 return(ERROR_OUTOFMEMORY
);
436 Value
->DataType
= Type
;
437 Value
->DataSize
= DataSize
;
438 memcpy(Value
->Data
, Data
, DataSize
);
441 return(ERROR_SUCCESS
);
446 RegQueryValue(HKEY Key
,
456 if ((ValueName
== NULL
) || (*ValueName
== 0))
458 /* query default value */
459 if (Key
->Data
== NULL
)
460 return(ERROR_INVALID_PARAMETER
);
463 *Type
= Key
->DataType
;
464 if ((Data
!= NULL
) && (DataSize
!= NULL
))
466 if (Key
->DataSize
<= sizeof(PUCHAR
))
468 Size
= min(Key
->DataSize
, *DataSize
);
469 memcpy(Data
, &Key
->Data
, Size
);
474 Size
= min(Key
->DataSize
, *DataSize
);
475 memcpy(Data
, Key
->Data
, Size
);
479 else if ((Data
== NULL
) && (DataSize
!= NULL
))
481 *DataSize
= Key
->DataSize
;
486 /* query non-default value */
487 Ptr
= Key
->ValueList
.Flink
;
488 while (Ptr
!= &Key
->ValueList
)
490 Value
= CONTAINING_RECORD(Ptr
,
494 DPRINT("Searching for '%s'. Value name '%s'\n", ValueName
, Value
->Name
);
496 if (stricmp(Value
->Name
, ValueName
) == 0)
502 if (Ptr
== &Key
->ValueList
)
503 return(ERROR_INVALID_PARAMETER
);
506 *Type
= Value
->DataType
;
507 if ((Data
!= NULL
) && (DataSize
!= NULL
))
509 if (Value
->DataSize
<= sizeof(PUCHAR
))
511 Size
= min(Value
->DataSize
, *DataSize
);
512 memcpy(Data
, &Value
->Data
, Size
);
517 Size
= min(Value
->DataSize
, *DataSize
);
518 memcpy(Data
, Value
->Data
, Size
);
522 else if ((Data
== NULL
) && (DataSize
!= NULL
))
524 *DataSize
= Value
->DataSize
;
528 return(ERROR_SUCCESS
);
533 RegDeleteValue(HKEY Key
,
539 if ((ValueName
== NULL
) || (*ValueName
== 0))
541 /* delete default value */
542 if (Key
->Data
!= NULL
)
550 /* delete non-default value */
551 Ptr
= Key
->ValueList
.Flink
;
552 while (Ptr
!= &Key
->ValueList
)
554 Value
= CONTAINING_RECORD(Ptr
,
557 if (strcmp(Value
->Name
, ValueName
) == 0)
563 if (Ptr
== &Key
->ValueList
)
564 return(ERROR_INVALID_PARAMETER
);
567 if (Value
->Name
!= NULL
)
572 if (Value
->DataSize
> sizeof(PUCHAR
))
574 if (Value
->Data
!= NULL
)
581 RemoveEntryList(&Value
->ValueList
);
584 return(ERROR_SUCCESS
);
589 RegEnumValue(HKEY Key
,
601 if (Key
->Data
!= NULL
)
609 /* enumerate default value */
610 if (ValueName
!= NULL
)
613 *Type
= Key
->DataType
;
614 if (DataSize
!= NULL
)
615 *DataSize
= Key
->DataSize
;
617 /* FIXME: return more values */
621 Ptr
= Key
->ValueList
.Flink
;
622 while (Ptr
!= &Key
->ValueList
)
631 if (Ptr
== &Key
->ValueList
)
632 return(ERROR_NO_MORE_ITEMS
);
634 Value
= CONTAINING_RECORD(Ptr
,
638 /* FIXME: return values */
640 return(ERROR_SUCCESS
);
646 RegQueryMultipleValue(HKEY Key
,
649 return(ERROR_SUCCESS
);