4 * Copyright (C) 2001, 2002 Eric Kohl
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
33 RegInitializeRegistry (VOID
)
40 RootKey
= (HKEY
) MmAllocateMemory (sizeof(KEY
));
42 InitializeListHead (&RootKey
->SubKeyList
);
43 InitializeListHead (&RootKey
->ValueList
);
44 InitializeListHead (&RootKey
->KeyList
);
46 RootKey
->SubKeyCount
= 0;
47 RootKey
->ValueCount
= 0;
49 RootKey
->NameSize
= 2;
50 RootKey
->Name
= (PUCHAR
)MmAllocateMemory (2);
51 strcpy (RootKey
->Name
, "\\");
53 RootKey
->DataType
= 0;
54 RootKey
->DataSize
= 0;
57 /* Create 'SYSTEM' key */
58 RegCreateKey (RootKey
,
59 "Registry\\Machine\\SYSTEM",
62 /* Create 'HARDWARE' key */
63 RegCreateKey (RootKey
,
64 "Registry\\Machine\\HARDWARE",
67 /* Create 'HARDWARE\DESCRIPTION' key */
68 RegCreateKey (RootKey
,
69 "Registry\\Machine\\HARDWARE\\DESCRIPTION",
72 /* Create 'HARDWARE\DEVICEMAP' key */
73 RegCreateKey (RootKey
,
74 "Registry\\Machine\\HARDWARE\\DEVICEMAP",
77 /* Create 'HARDWARE\RESOURCEMAP' key */
78 RegCreateKey (RootKey
,
79 "Registry\\Machine\\HARDWARE\\RESOURCEMAP",
84 RegCreateKey (RootKey
,
85 "Registry\\Machine\\HARDWARE\\DESCRIPTION\\TestKey",
98 RegInitCurrentControlSet(BOOL LastKnownGood
)
100 CHAR ControlSetKeyName
[80];
107 U32 LastKnownGoodSet
= 0;
111 Error
= RegOpenKey(NULL
,
112 "\\Registry\\Machine\\SYSTEM\\Select",
114 if (Error
!= ERROR_SUCCESS
)
116 DbgPrint((DPRINT_REGISTRY
, "RegOpenKey() failed (Error %u)\n", (int)Error
));
120 DataSize
= sizeof(U32
);
121 Error
= RegQueryValue(SelectKey
,
126 if (Error
!= ERROR_SUCCESS
)
128 DbgPrint((DPRINT_REGISTRY
, "RegQueryValue('Default') failed (Error %u)\n", (int)Error
));
132 DataSize
= sizeof(U32
);
133 Error
= RegQueryValue(SelectKey
,
136 (PUCHAR
)&LastKnownGoodSet
,
138 if (Error
!= ERROR_SUCCESS
)
140 DbgPrint((DPRINT_REGISTRY
, "RegQueryValue('Default') failed (Error %u)\n", (int)Error
));
144 CurrentSet
= (LastKnownGood
== TRUE
) ? LastKnownGoodSet
: DefaultSet
;
145 strcpy(ControlSetKeyName
, "ControlSet");
149 strcat(ControlSetKeyName
, "001");
152 strcat(ControlSetKeyName
, "002");
155 strcat(ControlSetKeyName
, "003");
158 strcat(ControlSetKeyName
, "004");
161 strcat(ControlSetKeyName
, "005");
165 Error
= RegOpenKey(NULL
,
166 "\\Registry\\Machine\\SYSTEM",
168 if (Error
!= ERROR_SUCCESS
)
170 DbgPrint((DPRINT_REGISTRY
, "RegOpenKey(SystemKey) failed (Error %u)\n", (int)Error
));
174 Error
= RegOpenKey(SystemKey
,
177 if (Error
!= ERROR_SUCCESS
)
179 DbgPrint((DPRINT_REGISTRY
, "RegOpenKey(ControlSetKey) failed (Error %u)\n", (int)Error
));
183 Error
= RegCreateKey(SystemKey
,
186 if (Error
!= ERROR_SUCCESS
)
188 DbgPrint((DPRINT_REGISTRY
, "RegCreateKey(LinkKey) failed (Error %u)\n", (int)Error
));
192 Error
= RegSetValue(LinkKey
,
195 (PUCHAR
)&ControlSetKey
,
197 if (Error
!= ERROR_SUCCESS
)
199 DbgPrint((DPRINT_REGISTRY
, "RegSetValue(LinkKey) failed (Error %u)\n", (int)Error
));
203 return(ERROR_SUCCESS
);
208 RegCreateKey(HKEY ParentKey
,
213 HKEY SearchKey
= INVALID_HANDLE_VALUE
;
221 DbgPrint((DPRINT_REGISTRY
, "KeyName '%s'\n", KeyName
));
223 if (*KeyName
== '\\')
226 CurrentKey
= RootKey
;
228 else if (ParentKey
== NULL
)
230 CurrentKey
= RootKey
;
234 CurrentKey
= ParentKey
;
237 /* Check whether current key is a link */
238 if (CurrentKey
->DataType
== REG_LINK
)
240 CurrentKey
= (HKEY
)CurrentKey
->Data
;
243 while (*KeyName
!= 0)
245 DbgPrint((DPRINT_REGISTRY
, "KeyName '%s'\n", KeyName
));
247 if (*KeyName
== '\\')
249 p
= strchr(KeyName
, '\\');
250 if ((p
!= NULL
) && (p
!= KeyName
))
252 subkeyLength
= p
- KeyName
;
253 stringLength
= subkeyLength
+ 1;
258 subkeyLength
= strlen(KeyName
);
259 stringLength
= subkeyLength
;
263 Ptr
= CurrentKey
->SubKeyList
.Flink
;
264 while (Ptr
!= &CurrentKey
->SubKeyList
)
266 DbgPrint((DPRINT_REGISTRY
, "Ptr 0x%x\n", Ptr
));
268 SearchKey
= CONTAINING_RECORD(Ptr
,
271 DbgPrint((DPRINT_REGISTRY
, "SearchKey 0x%x\n", SearchKey
));
272 DbgPrint((DPRINT_REGISTRY
, "Searching '%s'\n", SearchKey
->Name
));
273 if (strnicmp(SearchKey
->Name
, name
, subkeyLength
) == 0)
279 if (Ptr
== &CurrentKey
->SubKeyList
)
281 /* no key found -> create new subkey */
282 NewKey
= (HKEY
)MmAllocateMemory(sizeof(KEY
));
284 return(ERROR_OUTOFMEMORY
);
286 InitializeListHead(&NewKey
->SubKeyList
);
287 InitializeListHead(&NewKey
->ValueList
);
289 NewKey
->SubKeyCount
= 0;
290 NewKey
->ValueCount
= 0;
292 NewKey
->DataType
= 0;
293 NewKey
->DataSize
= 0;
296 InsertTailList(&CurrentKey
->SubKeyList
, &NewKey
->KeyList
);
297 CurrentKey
->SubKeyCount
++;
299 NewKey
->NameSize
= subkeyLength
+ 1;
300 NewKey
->Name
= (PCHAR
)MmAllocateMemory(NewKey
->NameSize
);
301 if (NewKey
->Name
== NULL
)
302 return(ERROR_OUTOFMEMORY
);
303 memcpy(NewKey
->Name
, name
, subkeyLength
);
304 NewKey
->Name
[subkeyLength
] = 0;
306 DbgPrint((DPRINT_REGISTRY
, "NewKey 0x%x\n", NewKey
));
307 DbgPrint((DPRINT_REGISTRY
, "NewKey '%s' Length %d\n", NewKey
->Name
, NewKey
->NameSize
));
313 CurrentKey
= SearchKey
;
315 /* Check whether current key is a link */
316 if (CurrentKey
->DataType
== REG_LINK
)
318 CurrentKey
= (HKEY
)CurrentKey
->Data
;
322 KeyName
= KeyName
+ stringLength
;
328 return(ERROR_SUCCESS
);
333 RegDeleteKey(HKEY Key
,
338 if (strchr(Name
, '\\') != NULL
)
339 return(ERROR_INVALID_PARAMETER
);
343 return(ERROR_SUCCESS
);
358 Ptr
= Key
->SubKeyList
.Flink
;
359 while (Ptr
!= &Key
->SubKeyList
)
368 if (Ptr
== &Key
->SubKeyList
)
369 return(ERROR_NO_MORE_ITEMS
);
371 SearchKey
= CONTAINING_RECORD(Ptr
,
375 DbgPrint((DPRINT_REGISTRY
, "Name '%s' Length %d\n", SearchKey
->Name
, SearchKey
->NameSize
));
377 Size
= min(SearchKey
->NameSize
, *NameSize
);
379 memcpy(Name
, SearchKey
->Name
, Size
);
381 return(ERROR_SUCCESS
);
386 RegOpenKey(HKEY ParentKey
,
391 HKEY SearchKey
= INVALID_HANDLE_VALUE
;
398 DbgPrint((DPRINT_REGISTRY
, "KeyName '%s'\n", KeyName
));
402 if (*KeyName
== '\\')
405 CurrentKey
= RootKey
;
407 else if (ParentKey
== NULL
)
409 CurrentKey
= RootKey
;
413 CurrentKey
= ParentKey
;
416 /* Check whether current key is a link */
417 if (CurrentKey
->DataType
== REG_LINK
)
419 CurrentKey
= (HKEY
)CurrentKey
->Data
;
422 while (*KeyName
!= 0)
424 DbgPrint((DPRINT_REGISTRY
, "KeyName '%s'\n", KeyName
));
426 if (*KeyName
== '\\')
428 p
= strchr(KeyName
, '\\');
429 if ((p
!= NULL
) && (p
!= KeyName
))
431 subkeyLength
= p
- KeyName
;
432 stringLength
= subkeyLength
+ 1;
437 subkeyLength
= strlen(KeyName
);
438 stringLength
= subkeyLength
;
442 Ptr
= CurrentKey
->SubKeyList
.Flink
;
443 while (Ptr
!= &CurrentKey
->SubKeyList
)
445 DbgPrint((DPRINT_REGISTRY
, "Ptr 0x%x\n", Ptr
));
447 SearchKey
= CONTAINING_RECORD(Ptr
,
451 DbgPrint((DPRINT_REGISTRY
, "SearchKey 0x%x\n", SearchKey
));
452 DbgPrint((DPRINT_REGISTRY
, "Searching '%s'\n", SearchKey
->Name
));
454 if (strnicmp(SearchKey
->Name
, name
, subkeyLength
) == 0)
460 if (Ptr
== &CurrentKey
->SubKeyList
)
462 return(ERROR_PATH_NOT_FOUND
);
466 CurrentKey
= SearchKey
;
468 /* Check whether current key is a link */
469 if (CurrentKey
->DataType
== REG_LINK
)
471 CurrentKey
= (HKEY
)CurrentKey
->Data
;
475 KeyName
= KeyName
+ stringLength
;
481 return(ERROR_SUCCESS
);
486 RegSetValue(HKEY Key
,
495 DbgPrint((DPRINT_REGISTRY
, "Key 0x%x, ValueName '%s', Type %d, Data 0x%x, DataSize %d\n",
496 (int)Key
, ValueName
, (int)Type
, (int)Data
, (int)DataSize
));
498 if ((ValueName
== NULL
) || (*ValueName
== 0))
500 /* set default value */
501 if ((Key
->Data
!= NULL
) && (Key
->DataSize
> sizeof(PUCHAR
)))
503 MmFreeMemory(Key
->Data
);
506 if (DataSize
<= sizeof(PUCHAR
))
508 Key
->DataSize
= DataSize
;
509 Key
->DataType
= Type
;
510 memcpy(&Key
->Data
, Data
, DataSize
);
514 Key
->Data
= (PUCHAR
)MmAllocateMemory(DataSize
);
515 Key
->DataSize
= DataSize
;
516 Key
->DataType
= Type
;
517 memcpy(Key
->Data
, Data
, DataSize
);
522 /* set non-default value */
523 Ptr
= Key
->ValueList
.Flink
;
524 while (Ptr
!= &Key
->ValueList
)
526 Value
= CONTAINING_RECORD(Ptr
,
530 DbgPrint((DPRINT_REGISTRY
, "Value->Name '%s'\n", Value
->Name
));
532 if (stricmp(Value
->Name
, ValueName
) == 0)
538 if (Ptr
== &Key
->ValueList
)
541 DbgPrint((DPRINT_REGISTRY
, "No value found - adding new value\n"));
543 Value
= (PVALUE
)MmAllocateMemory(sizeof(VALUE
));
545 return(ERROR_OUTOFMEMORY
);
547 InsertTailList(&Key
->ValueList
, &Value
->ValueList
);
550 Value
->NameSize
= strlen(ValueName
)+1;
551 Value
->Name
= (PCHAR
)MmAllocateMemory(Value
->NameSize
);
552 if (Value
->Name
== NULL
)
553 return(ERROR_OUTOFMEMORY
);
554 strcpy(Value
->Name
, ValueName
);
555 Value
->DataType
= REG_NONE
;
561 if ((Value
->Data
!= NULL
) && (Value
->DataSize
> sizeof(PUCHAR
)))
563 MmFreeMemory(Value
->Data
);
566 if (DataSize
<= sizeof(PUCHAR
))
568 Value
->DataSize
= DataSize
;
569 Value
->DataType
= Type
;
570 memcpy(&Value
->Data
, Data
, DataSize
);
574 Value
->Data
= (PUCHAR
)MmAllocateMemory(DataSize
);
575 if (Value
->Data
== NULL
)
576 return(ERROR_OUTOFMEMORY
);
577 Value
->DataType
= Type
;
578 Value
->DataSize
= DataSize
;
579 memcpy(Value
->Data
, Data
, DataSize
);
582 return(ERROR_SUCCESS
);
587 RegQueryValue(HKEY Key
,
597 if ((ValueName
== NULL
) || (*ValueName
== 0))
599 /* query default value */
600 if (Key
->Data
== NULL
)
601 return(ERROR_INVALID_PARAMETER
);
604 *Type
= Key
->DataType
;
605 if ((Data
!= NULL
) && (DataSize
!= NULL
))
607 if (Key
->DataSize
<= sizeof(PUCHAR
))
609 Size
= min(Key
->DataSize
, *DataSize
);
610 memcpy(Data
, &Key
->Data
, Size
);
615 Size
= min(Key
->DataSize
, *DataSize
);
616 memcpy(Data
, Key
->Data
, Size
);
620 else if ((Data
== NULL
) && (DataSize
!= NULL
))
622 *DataSize
= Key
->DataSize
;
627 /* query non-default value */
628 Ptr
= Key
->ValueList
.Flink
;
629 while (Ptr
!= &Key
->ValueList
)
631 Value
= CONTAINING_RECORD(Ptr
,
635 DbgPrint((DPRINT_REGISTRY
, "Searching for '%s'. Value name '%s'\n", ValueName
, Value
->Name
));
637 if (stricmp(Value
->Name
, ValueName
) == 0)
643 if (Ptr
== &Key
->ValueList
)
644 return(ERROR_INVALID_PARAMETER
);
647 *Type
= Value
->DataType
;
648 if ((Data
!= NULL
) && (DataSize
!= NULL
))
650 if (Value
->DataSize
<= sizeof(PUCHAR
))
652 Size
= min(Value
->DataSize
, *DataSize
);
653 memcpy(Data
, &Value
->Data
, Size
);
658 Size
= min(Value
->DataSize
, *DataSize
);
659 memcpy(Data
, Value
->Data
, Size
);
663 else if ((Data
== NULL
) && (DataSize
!= NULL
))
665 *DataSize
= Value
->DataSize
;
669 return(ERROR_SUCCESS
);
674 RegDeleteValue(HKEY Key
,
680 if ((ValueName
== NULL
) || (*ValueName
== 0))
682 /* delete default value */
683 if (Key
->Data
!= NULL
)
684 MmFreeMemory(Key
->Data
);
691 /* delete non-default value */
692 Ptr
= Key
->ValueList
.Flink
;
693 while (Ptr
!= &Key
->ValueList
)
695 Value
= CONTAINING_RECORD(Ptr
,
698 if (stricmp(Value
->Name
, ValueName
) == 0)
704 if (Ptr
== &Key
->ValueList
)
705 return(ERROR_INVALID_PARAMETER
);
709 if (Value
->Name
!= NULL
)
710 MmFreeMemory(Value
->Name
);
714 if (Value
->DataSize
> sizeof(PUCHAR
))
716 if (Value
->Data
!= NULL
)
717 MmFreeMemory(Value
->Data
);
723 RemoveEntryList(&Value
->ValueList
);
726 return(ERROR_SUCCESS
);
731 RegEnumValue(HKEY Key
,
743 if (Key
->Data
!= NULL
)
751 /* enumerate default value */
752 if (ValueName
!= NULL
)
755 *Type
= Key
->DataType
;
758 if (Key
->DataSize
<= sizeof(PUCHAR
))
760 memcpy(Data
, &Key
->Data
, min(Key
->DataSize
, *DataSize
));
764 memcpy(Data
, Key
->Data
, min(Key
->DataSize
, *DataSize
));
767 if (DataSize
!= NULL
)
768 *DataSize
= min(Key
->DataSize
, *DataSize
);
770 return(ERROR_SUCCESS
);
774 Ptr
= Key
->ValueList
.Flink
;
775 while (Ptr
!= &Key
->ValueList
)
784 if (Ptr
== &Key
->ValueList
)
785 return(ERROR_NO_MORE_ITEMS
);
787 Value
= CONTAINING_RECORD(Ptr
,
791 /* enumerate non-default value */
792 if (ValueName
!= NULL
)
793 memcpy(ValueName
, Value
->Name
, min(Value
->NameSize
, *NameSize
));
795 *Type
= Value
->DataType
;
799 if (Value
->DataSize
<= sizeof(PUCHAR
))
801 memcpy(Data
, &Value
->Data
, min(Value
->DataSize
, *DataSize
));
805 memcpy(Data
, Value
->Data
, min(Value
->DataSize
, *DataSize
));
809 if (DataSize
!= NULL
)
810 *DataSize
= min(Value
->DataSize
, *DataSize
);
812 return(ERROR_SUCCESS
);
817 RegGetSubKeyCount (HKEY Key
)
819 return Key
->SubKeyCount
;
824 RegGetValueCount (HKEY Key
)
826 if (Key
->DataSize
!= 0)
827 return Key
->ValueCount
+ 1;
829 return Key
->ValueCount
;