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.
26 static FRLDRHKEY RootKey
;
30 RegInitializeRegistry (VOID
)
37 RootKey
= (FRLDRHKEY
) MmAllocateMemory (sizeof(KEY
));
39 InitializeListHead (&RootKey
->SubKeyList
);
40 InitializeListHead (&RootKey
->ValueList
);
41 InitializeListHead (&RootKey
->KeyList
);
43 RootKey
->SubKeyCount
= 0;
44 RootKey
->ValueCount
= 0;
46 RootKey
->NameSize
= 2;
47 RootKey
->Name
= MmAllocateMemory (2);
48 strcpy (RootKey
->Name
, "\\");
50 RootKey
->DataType
= 0;
51 RootKey
->DataSize
= 0;
54 /* Create 'SYSTEM' key */
55 RegCreateKey (RootKey
,
56 "Registry\\Machine\\SYSTEM",
59 /* Create 'HARDWARE' key */
60 RegCreateKey (RootKey
,
61 "Registry\\Machine\\HARDWARE",
64 /* Create 'HARDWARE\DESCRIPTION' key */
65 RegCreateKey (RootKey
,
66 "Registry\\Machine\\HARDWARE\\DESCRIPTION",
69 /* Create 'HARDWARE\DEVICEMAP' key */
70 RegCreateKey (RootKey
,
71 "Registry\\Machine\\HARDWARE\\DEVICEMAP",
74 /* Create 'HARDWARE\RESOURCEMAP' key */
75 RegCreateKey (RootKey
,
76 "Registry\\Machine\\HARDWARE\\RESOURCEMAP",
81 RegCreateKey (RootKey
,
82 "Registry\\Machine\\HARDWARE\\DESCRIPTION\\TestKey",
95 RegInitCurrentControlSet(BOOL LastKnownGood
)
97 CHAR ControlSetKeyName
[80];
100 FRLDRHKEY ControlSetKey
;
102 ULONG CurrentSet
= 0;
103 ULONG DefaultSet
= 0;
104 ULONG LastKnownGoodSet
= 0;
108 Error
= RegOpenKey(NULL
,
109 "\\Registry\\Machine\\SYSTEM\\Select",
111 if (Error
!= ERROR_SUCCESS
)
113 DbgPrint((DPRINT_REGISTRY
, "RegOpenKey() failed (Error %u)\n", (int)Error
));
117 DataSize
= sizeof(ULONG
);
118 Error
= RegQueryValue(SelectKey
,
123 if (Error
!= ERROR_SUCCESS
)
125 DbgPrint((DPRINT_REGISTRY
, "RegQueryValue('Default') failed (Error %u)\n", (int)Error
));
129 DataSize
= sizeof(ULONG
);
130 Error
= RegQueryValue(SelectKey
,
133 (PUCHAR
)&LastKnownGoodSet
,
135 if (Error
!= ERROR_SUCCESS
)
137 DbgPrint((DPRINT_REGISTRY
, "RegQueryValue('Default') failed (Error %u)\n", (int)Error
));
141 CurrentSet
= (LastKnownGood
== TRUE
) ? LastKnownGoodSet
: DefaultSet
;
142 strcpy(ControlSetKeyName
, "ControlSet");
146 strcat(ControlSetKeyName
, "001");
149 strcat(ControlSetKeyName
, "002");
152 strcat(ControlSetKeyName
, "003");
155 strcat(ControlSetKeyName
, "004");
158 strcat(ControlSetKeyName
, "005");
162 Error
= RegOpenKey(NULL
,
163 "\\Registry\\Machine\\SYSTEM",
165 if (Error
!= ERROR_SUCCESS
)
167 DbgPrint((DPRINT_REGISTRY
, "RegOpenKey(SystemKey) failed (Error %u)\n", (int)Error
));
171 Error
= RegOpenKey(SystemKey
,
174 if (Error
!= ERROR_SUCCESS
)
176 DbgPrint((DPRINT_REGISTRY
, "RegOpenKey(ControlSetKey) failed (Error %u)\n", (int)Error
));
180 Error
= RegCreateKey(SystemKey
,
183 if (Error
!= ERROR_SUCCESS
)
185 DbgPrint((DPRINT_REGISTRY
, "RegCreateKey(LinkKey) failed (Error %u)\n", (int)Error
));
189 Error
= RegSetValue(LinkKey
,
192 (PCHAR
)&ControlSetKey
,
194 if (Error
!= ERROR_SUCCESS
)
196 DbgPrint((DPRINT_REGISTRY
, "RegSetValue(LinkKey) failed (Error %u)\n", (int)Error
));
200 return(ERROR_SUCCESS
);
205 RegCreateKey(FRLDRHKEY ParentKey
,
210 FRLDRHKEY SearchKey
= NULL
;
211 FRLDRHKEY CurrentKey
;
218 DbgPrint((DPRINT_REGISTRY
, "KeyName '%s'\n", KeyName
));
220 if (*KeyName
== '\\')
223 CurrentKey
= RootKey
;
225 else if (ParentKey
== NULL
)
227 CurrentKey
= RootKey
;
231 CurrentKey
= ParentKey
;
234 /* Check whether current key is a link */
235 if (CurrentKey
->DataType
== REG_LINK
)
237 CurrentKey
= (FRLDRHKEY
)CurrentKey
->Data
;
240 while (*KeyName
!= 0)
242 DbgPrint((DPRINT_REGISTRY
, "KeyName '%s'\n", KeyName
));
244 if (*KeyName
== '\\')
246 p
= strchr(KeyName
, '\\');
247 if ((p
!= NULL
) && (p
!= KeyName
))
249 subkeyLength
= p
- KeyName
;
250 stringLength
= subkeyLength
+ 1;
255 subkeyLength
= strlen(KeyName
);
256 stringLength
= subkeyLength
;
260 Ptr
= CurrentKey
->SubKeyList
.Flink
;
261 while (Ptr
!= &CurrentKey
->SubKeyList
)
263 DbgPrint((DPRINT_REGISTRY
, "Ptr 0x%x\n", Ptr
));
265 SearchKey
= CONTAINING_RECORD(Ptr
,
268 DbgPrint((DPRINT_REGISTRY
, "SearchKey 0x%x\n", SearchKey
));
269 DbgPrint((DPRINT_REGISTRY
, "Searching '%s'\n", SearchKey
->Name
));
270 if (strnicmp(SearchKey
->Name
, name
, subkeyLength
) == 0)
276 if (Ptr
== &CurrentKey
->SubKeyList
)
278 /* no key found -> create new subkey */
279 NewKey
= (FRLDRHKEY
)MmAllocateMemory(sizeof(KEY
));
281 return(ERROR_OUTOFMEMORY
);
283 InitializeListHead(&NewKey
->SubKeyList
);
284 InitializeListHead(&NewKey
->ValueList
);
286 NewKey
->SubKeyCount
= 0;
287 NewKey
->ValueCount
= 0;
289 NewKey
->DataType
= 0;
290 NewKey
->DataSize
= 0;
293 InsertTailList(&CurrentKey
->SubKeyList
, &NewKey
->KeyList
);
294 CurrentKey
->SubKeyCount
++;
296 NewKey
->NameSize
= subkeyLength
+ 1;
297 NewKey
->Name
= (PCHAR
)MmAllocateMemory(NewKey
->NameSize
);
298 if (NewKey
->Name
== NULL
)
299 return(ERROR_OUTOFMEMORY
);
300 memcpy(NewKey
->Name
, name
, subkeyLength
);
301 NewKey
->Name
[subkeyLength
] = 0;
303 DbgPrint((DPRINT_REGISTRY
, "NewKey 0x%x\n", NewKey
));
304 DbgPrint((DPRINT_REGISTRY
, "NewKey '%s' Length %d\n", NewKey
->Name
, NewKey
->NameSize
));
310 CurrentKey
= SearchKey
;
312 /* Check whether current key is a link */
313 if (CurrentKey
->DataType
== REG_LINK
)
315 CurrentKey
= (FRLDRHKEY
)CurrentKey
->Data
;
319 KeyName
= KeyName
+ stringLength
;
325 return(ERROR_SUCCESS
);
330 RegDeleteKey(FRLDRHKEY Key
,
335 if (strchr(Name
, '\\') != NULL
)
336 return(ERROR_INVALID_PARAMETER
);
340 return(ERROR_SUCCESS
);
345 RegEnumKey(FRLDRHKEY Key
,
355 Ptr
= Key
->SubKeyList
.Flink
;
356 while (Ptr
!= &Key
->SubKeyList
)
365 if (Ptr
== &Key
->SubKeyList
)
366 return(ERROR_NO_MORE_ITEMS
);
368 SearchKey
= CONTAINING_RECORD(Ptr
,
372 DbgPrint((DPRINT_REGISTRY
, "Name '%s' Length %d\n", SearchKey
->Name
, SearchKey
->NameSize
));
374 Size
= min(SearchKey
->NameSize
, *NameSize
);
376 memcpy(Name
, SearchKey
->Name
, Size
);
378 return(ERROR_SUCCESS
);
383 RegOpenKey(FRLDRHKEY ParentKey
,
388 FRLDRHKEY SearchKey
= NULL
;
389 FRLDRHKEY CurrentKey
;
395 DbgPrint((DPRINT_REGISTRY
, "KeyName '%s'\n", KeyName
));
399 if (*KeyName
== '\\')
402 CurrentKey
= RootKey
;
404 else if (ParentKey
== NULL
)
406 CurrentKey
= RootKey
;
410 CurrentKey
= ParentKey
;
413 /* Check whether current key is a link */
414 if (CurrentKey
->DataType
== REG_LINK
)
416 CurrentKey
= (FRLDRHKEY
)CurrentKey
->Data
;
419 while (*KeyName
!= 0)
421 DbgPrint((DPRINT_REGISTRY
, "KeyName '%s'\n", KeyName
));
423 if (*KeyName
== '\\')
425 p
= strchr(KeyName
, '\\');
426 if ((p
!= NULL
) && (p
!= KeyName
))
428 subkeyLength
= p
- KeyName
;
429 stringLength
= subkeyLength
+ 1;
434 subkeyLength
= strlen(KeyName
);
435 stringLength
= subkeyLength
;
439 Ptr
= CurrentKey
->SubKeyList
.Flink
;
440 while (Ptr
!= &CurrentKey
->SubKeyList
)
442 DbgPrint((DPRINT_REGISTRY
, "Ptr 0x%x\n", Ptr
));
444 SearchKey
= CONTAINING_RECORD(Ptr
,
448 DbgPrint((DPRINT_REGISTRY
, "SearchKey 0x%x\n", SearchKey
));
449 DbgPrint((DPRINT_REGISTRY
, "Searching '%s'\n", SearchKey
->Name
));
451 if (strnicmp(SearchKey
->Name
, name
, subkeyLength
) == 0)
457 if (Ptr
== &CurrentKey
->SubKeyList
)
459 return(ERROR_PATH_NOT_FOUND
);
463 CurrentKey
= SearchKey
;
465 /* Check whether current key is a link */
466 if (CurrentKey
->DataType
== REG_LINK
)
468 CurrentKey
= (FRLDRHKEY
)CurrentKey
->Data
;
472 KeyName
= KeyName
+ stringLength
;
478 return(ERROR_SUCCESS
);
483 RegSetValue(FRLDRHKEY Key
,
492 DbgPrint((DPRINT_REGISTRY
, "Key 0x%x, ValueName '%s', Type %d, Data 0x%x, DataSize %d\n",
493 (int)Key
, ValueName
, (int)Type
, (int)Data
, (int)DataSize
));
495 if ((ValueName
== NULL
) || (*ValueName
== 0))
497 /* set default value */
498 if ((Key
->Data
!= NULL
) && (Key
->DataSize
> sizeof(PUCHAR
)))
500 MmFreeMemory(Key
->Data
);
503 if (DataSize
<= sizeof(PUCHAR
))
505 Key
->DataSize
= DataSize
;
506 Key
->DataType
= Type
;
507 memcpy(&Key
->Data
, Data
, DataSize
);
511 Key
->Data
= MmAllocateMemory(DataSize
);
512 Key
->DataSize
= DataSize
;
513 Key
->DataType
= Type
;
514 memcpy(Key
->Data
, Data
, DataSize
);
519 /* set non-default value */
520 Ptr
= Key
->ValueList
.Flink
;
521 while (Ptr
!= &Key
->ValueList
)
523 Value
= CONTAINING_RECORD(Ptr
,
527 DbgPrint((DPRINT_REGISTRY
, "Value->Name '%s'\n", Value
->Name
));
529 if (stricmp(Value
->Name
, ValueName
) == 0)
535 if (Ptr
== &Key
->ValueList
)
538 DbgPrint((DPRINT_REGISTRY
, "No value found - adding new value\n"));
540 Value
= (PVALUE
)MmAllocateMemory(sizeof(VALUE
));
542 return(ERROR_OUTOFMEMORY
);
544 InsertTailList(&Key
->ValueList
, &Value
->ValueList
);
547 Value
->NameSize
= strlen(ValueName
)+1;
548 Value
->Name
= (PCHAR
)MmAllocateMemory(Value
->NameSize
);
549 if (Value
->Name
== NULL
)
550 return(ERROR_OUTOFMEMORY
);
551 strcpy(Value
->Name
, ValueName
);
552 Value
->DataType
= REG_NONE
;
558 if ((Value
->Data
!= NULL
) && (Value
->DataSize
> sizeof(PUCHAR
)))
560 MmFreeMemory(Value
->Data
);
563 if (DataSize
<= sizeof(PUCHAR
))
565 Value
->DataSize
= DataSize
;
566 Value
->DataType
= Type
;
567 memcpy(&Value
->Data
, Data
, DataSize
);
571 Value
->Data
= MmAllocateMemory(DataSize
);
572 if (Value
->Data
== NULL
)
573 return(ERROR_OUTOFMEMORY
);
574 Value
->DataType
= Type
;
575 Value
->DataSize
= DataSize
;
576 memcpy(Value
->Data
, Data
, DataSize
);
579 return(ERROR_SUCCESS
);
584 RegQueryValue(FRLDRHKEY Key
,
594 if ((ValueName
== NULL
) || (*ValueName
== 0))
596 /* query default value */
597 if (Key
->Data
== NULL
)
598 return(ERROR_INVALID_PARAMETER
);
601 *Type
= Key
->DataType
;
602 if ((Data
!= NULL
) && (DataSize
!= NULL
))
604 if (Key
->DataSize
<= sizeof(PUCHAR
))
606 Size
= min(Key
->DataSize
, *DataSize
);
607 memcpy(Data
, &Key
->Data
, Size
);
612 Size
= min(Key
->DataSize
, *DataSize
);
613 memcpy(Data
, Key
->Data
, Size
);
617 else if ((Data
== NULL
) && (DataSize
!= NULL
))
619 *DataSize
= Key
->DataSize
;
624 /* query non-default value */
625 Ptr
= Key
->ValueList
.Flink
;
626 while (Ptr
!= &Key
->ValueList
)
628 Value
= CONTAINING_RECORD(Ptr
,
632 DbgPrint((DPRINT_REGISTRY
, "Searching for '%s'. Value name '%s'\n", ValueName
, Value
->Name
));
634 if (stricmp(Value
->Name
, ValueName
) == 0)
640 if (Ptr
== &Key
->ValueList
)
641 return(ERROR_INVALID_PARAMETER
);
644 *Type
= Value
->DataType
;
645 if ((Data
!= NULL
) && (DataSize
!= NULL
))
647 if (Value
->DataSize
<= sizeof(PUCHAR
))
649 Size
= min(Value
->DataSize
, *DataSize
);
650 memcpy(Data
, &Value
->Data
, Size
);
655 Size
= min(Value
->DataSize
, *DataSize
);
656 memcpy(Data
, Value
->Data
, Size
);
660 else if ((Data
== NULL
) && (DataSize
!= NULL
))
662 *DataSize
= Value
->DataSize
;
666 return(ERROR_SUCCESS
);
671 RegDeleteValue(FRLDRHKEY Key
,
677 if ((ValueName
== NULL
) || (*ValueName
== 0))
679 /* delete default value */
680 if (Key
->Data
!= NULL
)
681 MmFreeMemory(Key
->Data
);
688 /* delete non-default value */
689 Ptr
= Key
->ValueList
.Flink
;
690 while (Ptr
!= &Key
->ValueList
)
692 Value
= CONTAINING_RECORD(Ptr
,
695 if (stricmp(Value
->Name
, ValueName
) == 0)
701 if (Ptr
== &Key
->ValueList
)
702 return(ERROR_INVALID_PARAMETER
);
706 if (Value
->Name
!= NULL
)
707 MmFreeMemory(Value
->Name
);
711 if (Value
->DataSize
> sizeof(PUCHAR
))
713 if (Value
->Data
!= NULL
)
714 MmFreeMemory(Value
->Data
);
720 RemoveEntryList(&Value
->ValueList
);
723 return(ERROR_SUCCESS
);
728 RegEnumValue(FRLDRHKEY Key
,
740 if (Key
->Data
!= NULL
)
748 /* enumerate default value */
749 if (ValueName
!= NULL
)
752 *Type
= Key
->DataType
;
755 if (Key
->DataSize
<= sizeof(PUCHAR
))
757 memcpy(Data
, &Key
->Data
, min(Key
->DataSize
, *DataSize
));
761 memcpy(Data
, Key
->Data
, min(Key
->DataSize
, *DataSize
));
764 if (DataSize
!= NULL
)
765 *DataSize
= min(Key
->DataSize
, *DataSize
);
767 return(ERROR_SUCCESS
);
771 Ptr
= Key
->ValueList
.Flink
;
772 while (Ptr
!= &Key
->ValueList
)
781 if (Ptr
== &Key
->ValueList
)
782 return(ERROR_NO_MORE_ITEMS
);
784 Value
= CONTAINING_RECORD(Ptr
,
788 /* enumerate non-default value */
789 if (ValueName
!= NULL
)
790 memcpy(ValueName
, Value
->Name
, min(Value
->NameSize
, *NameSize
));
792 *Type
= Value
->DataType
;
796 if (Value
->DataSize
<= sizeof(PUCHAR
))
798 memcpy(Data
, &Value
->Data
, min(Value
->DataSize
, *DataSize
));
802 memcpy(Data
, Value
->Data
, min(Value
->DataSize
, *DataSize
));
806 if (DataSize
!= NULL
)
807 *DataSize
= min(Value
->DataSize
, *DataSize
);
809 return(ERROR_SUCCESS
);
814 RegGetSubKeyCount (FRLDRHKEY Key
)
816 return Key
->SubKeyCount
;
821 RegGetValueCount (FRLDRHKEY Key
)
823 if (Key
->DataSize
!= 0)
824 return Key
->ValueCount
+ 1;
826 return Key
->ValueCount
;