ada49a23d4f646bb04be1b109f5108d80f5779d1
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
= 4;
47 RootKey
->Name
= MmAllocateMemory (4);
48 wcscpy (RootKey
->Name
, L
"\\");
50 RootKey
->DataType
= 0;
51 RootKey
->DataSize
= 0;
54 /* Create 'SYSTEM' key */
55 RegCreateKey (RootKey
,
56 L
"Registry\\Machine\\SYSTEM",
59 /* Create 'HARDWARE' key */
60 RegCreateKey (RootKey
,
61 L
"Registry\\Machine\\HARDWARE",
64 /* Create 'HARDWARE\DESCRIPTION' key */
65 RegCreateKey (RootKey
,
66 L
"Registry\\Machine\\HARDWARE\\DESCRIPTION",
69 /* Create 'HARDWARE\DEVICEMAP' key */
70 RegCreateKey (RootKey
,
71 L
"Registry\\Machine\\HARDWARE\\DEVICEMAP",
74 /* Create 'HARDWARE\RESOURCEMAP' key */
75 RegCreateKey (RootKey
,
76 L
"Registry\\Machine\\HARDWARE\\RESOURCEMAP",
81 RegCreateKey (RootKey
,
82 L
"Registry\\Machine\\HARDWARE\\DESCRIPTION\\TestKey",
95 RegInitCurrentControlSet(BOOL LastKnownGood
)
97 WCHAR ControlSetKeyName
[80];
100 FRLDRHKEY ControlSetKey
;
102 ULONG CurrentSet
= 0;
103 ULONG DefaultSet
= 0;
104 ULONG LastKnownGoodSet
= 0;
108 Error
= RegOpenKey(NULL
,
109 L
"\\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 wcscpy(ControlSetKeyName
, L
"ControlSet");
146 wcscat(ControlSetKeyName
, L
"001");
149 wcscat(ControlSetKeyName
, L
"002");
152 wcscat(ControlSetKeyName
, L
"003");
155 wcscat(ControlSetKeyName
, L
"004");
158 wcscat(ControlSetKeyName
, L
"005");
162 Error
= RegOpenKey(NULL
,
163 L
"\\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
,
181 L
"CurrentControlSet",
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
;
219 DbgPrint((DPRINT_REGISTRY
, "KeyName '%S'\n", KeyName
));
221 if (*KeyName
== L
'\\')
224 CurrentKey
= RootKey
;
226 else if (ParentKey
== NULL
)
228 CurrentKey
= RootKey
;
232 CurrentKey
= ParentKey
;
235 /* Check whether current key is a link */
236 if (CurrentKey
->DataType
== REG_LINK
)
238 CurrentKey
= (FRLDRHKEY
)CurrentKey
->Data
;
241 while (*KeyName
!= 0)
243 DbgPrint((DPRINT_REGISTRY
, "KeyName '%S'\n", KeyName
));
245 if (*KeyName
== L
'\\')
247 p
= wcschr(KeyName
, L
'\\');
248 if ((p
!= NULL
) && (p
!= KeyName
))
250 subkeyLength
= p
- KeyName
;
251 stringLength
= subkeyLength
+ 1;
256 subkeyLength
= wcslen(KeyName
);
257 stringLength
= subkeyLength
;
260 NameSize
= (subkeyLength
+ 1) * sizeof(WCHAR
);
262 Ptr
= CurrentKey
->SubKeyList
.Flink
;
263 while (Ptr
!= &CurrentKey
->SubKeyList
)
265 DbgPrint((DPRINT_REGISTRY
, "Ptr 0x%x\n", Ptr
));
267 SearchKey
= CONTAINING_RECORD(Ptr
,
270 DbgPrint((DPRINT_REGISTRY
, "SearchKey 0x%x\n", SearchKey
));
271 DbgPrint((DPRINT_REGISTRY
, "Searching '%S'\n", SearchKey
->Name
));
272 if (SearchKey
->NameSize
== NameSize
&&
273 _wcsnicmp(SearchKey
->Name
, name
, subkeyLength
) == 0)
279 if (Ptr
== &CurrentKey
->SubKeyList
)
281 /* no key found -> create new subkey */
282 NewKey
= (FRLDRHKEY
)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
= NameSize
;
300 NewKey
->Name
= (PWCHAR
)MmAllocateMemory(NewKey
->NameSize
);
301 if (NewKey
->Name
== NULL
)
302 return(ERROR_OUTOFMEMORY
);
303 memcpy(NewKey
->Name
, name
, NewKey
->NameSize
- sizeof(WCHAR
));
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
= (FRLDRHKEY
)CurrentKey
->Data
;
322 KeyName
= KeyName
+ stringLength
;
328 return(ERROR_SUCCESS
);
333 RegDeleteKey(FRLDRHKEY Key
,
338 if (wcschr(Name
, L
'\\') != NULL
)
339 return(ERROR_INVALID_PARAMETER
);
343 return(ERROR_SUCCESS
);
348 RegEnumKey(FRLDRHKEY Key
,
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(FRLDRHKEY ParentKey
,
391 FRLDRHKEY SearchKey
= NULL
;
392 FRLDRHKEY CurrentKey
;
399 DbgPrint((DPRINT_REGISTRY
, "KeyName '%S'\n", KeyName
));
403 if (*KeyName
== L
'\\')
406 CurrentKey
= RootKey
;
408 else if (ParentKey
== NULL
)
410 CurrentKey
= RootKey
;
414 CurrentKey
= ParentKey
;
417 /* Check whether current key is a link */
418 if (CurrentKey
->DataType
== REG_LINK
)
420 CurrentKey
= (FRLDRHKEY
)CurrentKey
->Data
;
423 while (*KeyName
!= 0)
425 DbgPrint((DPRINT_REGISTRY
, "KeyName '%S'\n", KeyName
));
427 if (*KeyName
== L
'\\')
429 p
= wcschr(KeyName
, L
'\\');
430 if ((p
!= NULL
) && (p
!= KeyName
))
432 subkeyLength
= p
- KeyName
;
433 stringLength
= subkeyLength
+ 1;
438 subkeyLength
= wcslen(KeyName
);
439 stringLength
= subkeyLength
;
442 NameSize
= (subkeyLength
+ 1) * sizeof(WCHAR
);
444 Ptr
= CurrentKey
->SubKeyList
.Flink
;
445 while (Ptr
!= &CurrentKey
->SubKeyList
)
447 DbgPrint((DPRINT_REGISTRY
, "Ptr 0x%x\n", Ptr
));
449 SearchKey
= CONTAINING_RECORD(Ptr
,
453 DbgPrint((DPRINT_REGISTRY
, "SearchKey 0x%x\n", SearchKey
));
454 DbgPrint((DPRINT_REGISTRY
, "Searching '%S'\n", SearchKey
->Name
));
456 if (SearchKey
->NameSize
== NameSize
&&
457 _wcsnicmp(SearchKey
->Name
, name
, subkeyLength
) == 0)
463 if (Ptr
== &CurrentKey
->SubKeyList
)
465 return(ERROR_PATH_NOT_FOUND
);
469 CurrentKey
= SearchKey
;
471 /* Check whether current key is a link */
472 if (CurrentKey
->DataType
== REG_LINK
)
474 CurrentKey
= (FRLDRHKEY
)CurrentKey
->Data
;
478 KeyName
= KeyName
+ stringLength
;
484 return(ERROR_SUCCESS
);
489 RegSetValue(FRLDRHKEY Key
,
498 DbgPrint((DPRINT_REGISTRY
, "Key 0x%x, ValueName '%S', Type %d, Data 0x%x, DataSize %d\n",
499 (int)Key
, ValueName
, (int)Type
, (int)Data
, (int)DataSize
));
501 if ((ValueName
== NULL
) || (*ValueName
== 0))
503 /* set default value */
504 if ((Key
->Data
!= NULL
) && (Key
->DataSize
> sizeof(PUCHAR
)))
506 MmFreeMemory(Key
->Data
);
509 if (DataSize
<= sizeof(PUCHAR
))
511 Key
->DataSize
= DataSize
;
512 Key
->DataType
= Type
;
513 memcpy(&Key
->Data
, Data
, DataSize
);
517 Key
->Data
= MmAllocateMemory(DataSize
);
518 Key
->DataSize
= DataSize
;
519 Key
->DataType
= Type
;
520 memcpy(Key
->Data
, Data
, DataSize
);
525 /* set non-default value */
526 Ptr
= Key
->ValueList
.Flink
;
527 while (Ptr
!= &Key
->ValueList
)
529 Value
= CONTAINING_RECORD(Ptr
,
533 DbgPrint((DPRINT_REGISTRY
, "Value->Name '%S'\n", Value
->Name
));
535 if (_wcsicmp(Value
->Name
, ValueName
) == 0)
541 if (Ptr
== &Key
->ValueList
)
544 DbgPrint((DPRINT_REGISTRY
, "No value found - adding new value\n"));
546 Value
= (PVALUE
)MmAllocateMemory(sizeof(VALUE
));
548 return(ERROR_OUTOFMEMORY
);
550 InsertTailList(&Key
->ValueList
, &Value
->ValueList
);
553 Value
->NameSize
= (wcslen(ValueName
)+1)*sizeof(WCHAR
);
554 Value
->Name
= (PWCHAR
)MmAllocateMemory(Value
->NameSize
);
555 if (Value
->Name
== NULL
)
556 return(ERROR_OUTOFMEMORY
);
557 wcscpy(Value
->Name
, ValueName
);
558 Value
->DataType
= REG_NONE
;
564 if ((Value
->Data
!= NULL
) && (Value
->DataSize
> sizeof(PUCHAR
)))
566 MmFreeMemory(Value
->Data
);
569 if (DataSize
<= sizeof(PUCHAR
))
571 Value
->DataSize
= DataSize
;
572 Value
->DataType
= Type
;
573 memcpy(&Value
->Data
, Data
, DataSize
);
577 Value
->Data
= MmAllocateMemory(DataSize
);
578 if (Value
->Data
== NULL
)
579 return(ERROR_OUTOFMEMORY
);
580 Value
->DataType
= Type
;
581 Value
->DataSize
= DataSize
;
582 memcpy(Value
->Data
, Data
, DataSize
);
585 return(ERROR_SUCCESS
);
590 RegQueryValue(FRLDRHKEY Key
,
600 if ((ValueName
== NULL
) || (*ValueName
== 0))
602 /* query default value */
603 if (Key
->Data
== NULL
)
604 return(ERROR_INVALID_PARAMETER
);
607 *Type
= Key
->DataType
;
608 if ((Data
!= NULL
) && (DataSize
!= NULL
))
610 if (Key
->DataSize
<= sizeof(PUCHAR
))
612 Size
= min(Key
->DataSize
, *DataSize
);
613 memcpy(Data
, &Key
->Data
, Size
);
618 Size
= min(Key
->DataSize
, *DataSize
);
619 memcpy(Data
, Key
->Data
, Size
);
623 else if ((Data
== NULL
) && (DataSize
!= NULL
))
625 *DataSize
= Key
->DataSize
;
630 /* query non-default value */
631 Ptr
= Key
->ValueList
.Flink
;
632 while (Ptr
!= &Key
->ValueList
)
634 Value
= CONTAINING_RECORD(Ptr
,
638 DbgPrint((DPRINT_REGISTRY
, "Searching for '%S'. Value name '%S'\n", ValueName
, Value
->Name
));
640 if (_wcsicmp(Value
->Name
, ValueName
) == 0)
646 if (Ptr
== &Key
->ValueList
)
647 return(ERROR_INVALID_PARAMETER
);
650 *Type
= Value
->DataType
;
651 if ((Data
!= NULL
) && (DataSize
!= NULL
))
653 if (Value
->DataSize
<= sizeof(PUCHAR
))
655 Size
= min(Value
->DataSize
, *DataSize
);
656 memcpy(Data
, &Value
->Data
, Size
);
661 Size
= min(Value
->DataSize
, *DataSize
);
662 memcpy(Data
, Value
->Data
, Size
);
666 else if ((Data
== NULL
) && (DataSize
!= NULL
))
668 *DataSize
= Value
->DataSize
;
672 return(ERROR_SUCCESS
);
677 RegDeleteValue(FRLDRHKEY Key
,
683 if ((ValueName
== NULL
) || (*ValueName
== 0))
685 /* delete default value */
686 if (Key
->Data
!= NULL
)
687 MmFreeMemory(Key
->Data
);
694 /* delete non-default value */
695 Ptr
= Key
->ValueList
.Flink
;
696 while (Ptr
!= &Key
->ValueList
)
698 Value
= CONTAINING_RECORD(Ptr
,
701 if (_wcsicmp(Value
->Name
, ValueName
) == 0)
707 if (Ptr
== &Key
->ValueList
)
708 return(ERROR_INVALID_PARAMETER
);
712 if (Value
->Name
!= NULL
)
713 MmFreeMemory(Value
->Name
);
717 if (Value
->DataSize
> sizeof(PUCHAR
))
719 if (Value
->Data
!= NULL
)
720 MmFreeMemory(Value
->Data
);
726 RemoveEntryList(&Value
->ValueList
);
729 return(ERROR_SUCCESS
);
734 RegEnumValue(FRLDRHKEY Key
,
746 if (Key
->Data
!= NULL
)
754 /* enumerate default value */
755 if (ValueName
!= NULL
)
758 *Type
= Key
->DataType
;
761 if (Key
->DataSize
<= sizeof(PUCHAR
))
763 memcpy(Data
, &Key
->Data
, min(Key
->DataSize
, *DataSize
));
767 memcpy(Data
, Key
->Data
, min(Key
->DataSize
, *DataSize
));
770 if (DataSize
!= NULL
)
771 *DataSize
= min(Key
->DataSize
, *DataSize
);
773 return(ERROR_SUCCESS
);
777 Ptr
= Key
->ValueList
.Flink
;
778 while (Ptr
!= &Key
->ValueList
)
787 if (Ptr
== &Key
->ValueList
)
788 return(ERROR_NO_MORE_ITEMS
);
790 Value
= CONTAINING_RECORD(Ptr
,
794 /* enumerate non-default value */
795 if (ValueName
!= NULL
)
796 memcpy(ValueName
, Value
->Name
, min(Value
->NameSize
, *NameSize
));
798 *Type
= Value
->DataType
;
802 if (Value
->DataSize
<= sizeof(PUCHAR
))
804 memcpy(Data
, &Value
->Data
, min(Value
->DataSize
, *DataSize
));
808 memcpy(Data
, Value
->Data
, min(Value
->DataSize
, *DataSize
));
812 if (DataSize
!= NULL
)
813 *DataSize
= min(Value
->DataSize
, *DataSize
);
815 return(ERROR_SUCCESS
);
820 RegGetSubKeyCount (FRLDRHKEY Key
)
822 return Key
->SubKeyCount
;
827 RegGetValueCount (FRLDRHKEY Key
)
829 if (Key
->DataSize
!= 0)
830 return Key
->ValueCount
+ 1;
832 return Key
->ValueCount
;