3 * Copyright (C) 2004 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: settings.c,v 1.4 2004/06/20 12:14:23 ekohl Exp $
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS text-mode setup
22 * FILE: subsys/system/usetup/settings.c
23 * PURPOSE: Device settings support functions
24 * PROGRAMMER: Eric Kohl
27 /* INCLUDES *****************************************************************/
29 #include <ddk/ntddk.h>
30 #include <ntdll/rtl.h>
31 #include <ntos/minmax.h>
42 /* FUNCTIONS ****************************************************************/
45 CreateComputerTypeList(HINF InfFile
)
54 List
= CreateGenericList();
58 if (!InfFindFirstLine (InfFile
, L
"Computer", NULL
, &Context
))
60 DestroyGenericList(List
, FALSE
);
66 if (!InfGetData (&Context
, &KeyName
, &KeyValue
))
68 /* FIXME: Handle error! */
69 DPRINT("InfGetData() failed\n");
73 UserData
= RtlAllocateHeap(ProcessHeap
,
75 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
78 /* FIXME: Handle error! */
81 wcscpy(UserData
, KeyName
);
83 sprintf(Buffer
, "%S", KeyValue
);
84 AppendGenericListEntry(List
, Buffer
, UserData
, FALSE
);
86 while (InfFindNextLine(&Context
, &Context
));
93 GetDisplayIdentifier(PWSTR Identifier
,
94 ULONG IdentifierLength
)
96 OBJECT_ATTRIBUTES ObjectAttributes
;
97 UNICODE_STRING KeyName
;
100 HANDLE BusInstanceKey
;
101 HANDLE ControllerKey
;
102 HANDLE ControllerInstanceKey
;
104 ULONG ControllerInstance
;
106 ULONG ReturnedLength
;
107 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
;
110 DPRINT("GetDisplayIdentifier() called\n");
112 /* Open the bus key */
113 RtlInitUnicodeString(&KeyName
,
114 L
"\\Registry\\Machine\\HARDWARE\\Description\\System\\MultifunctionAdapter");
115 InitializeObjectAttributes(&ObjectAttributes
,
117 OBJ_CASE_INSENSITIVE
,
120 Status
= NtOpenKey(&BusKey
,
123 if (!NT_SUCCESS(Status
))
125 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
132 swprintf(Buffer
, L
"%lu", BusInstance
);
133 RtlInitUnicodeString(&KeyName
,
135 InitializeObjectAttributes(&ObjectAttributes
,
137 OBJ_CASE_INSENSITIVE
,
140 Status
= NtOpenKey(&BusInstanceKey
,
143 if (!NT_SUCCESS(Status
))
145 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
150 /* Open the controller type key */
151 RtlInitUnicodeString(&KeyName
,
152 L
"DisplayController");
153 InitializeObjectAttributes(&ObjectAttributes
,
155 OBJ_CASE_INSENSITIVE
,
158 Status
= NtOpenKey(&ControllerKey
,
161 if (NT_SUCCESS(Status
))
163 ControllerInstance
= 0;
166 /* Open the pointer controller instance key */
167 swprintf(Buffer
, L
"%lu", ControllerInstance
);
168 RtlInitUnicodeString(&KeyName
,
170 InitializeObjectAttributes(&ObjectAttributes
,
172 OBJ_CASE_INSENSITIVE
,
175 Status
= NtOpenKey(&ControllerInstanceKey
,
178 if (!NT_SUCCESS(Status
))
180 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
181 NtClose(ControllerKey
);
182 NtClose(BusInstanceKey
);
187 /* Get controller identifier */
188 RtlInitUnicodeString(&KeyName
,
191 BufferLength
= sizeof(KEY_VALUE_PARTIAL_INFORMATION
) +
193 ValueInfo
= RtlAllocateHeap(RtlGetProcessHeap(),
196 if (ValueInfo
== NULL
)
198 DPRINT("RtlAllocateHeap() failed\n");
199 NtClose(ControllerInstanceKey
);
200 NtClose(ControllerKey
);
201 NtClose(BusInstanceKey
);
206 Status
= NtQueryValueKey(ControllerInstanceKey
,
208 KeyValuePartialInformation
,
212 if (NT_SUCCESS(Status
))
214 DPRINT("Identifier: %S\n", (PWSTR
)ValueInfo
->Data
);
216 BufferLength
= min(ValueInfo
->DataLength
/ sizeof(WCHAR
), IdentifierLength
);
217 RtlCopyMemory (Identifier
,
219 BufferLength
* sizeof(WCHAR
));
220 Identifier
[BufferLength
] = 0;
222 RtlFreeHeap(RtlGetProcessHeap(),
225 NtClose(ControllerInstanceKey
);
226 NtClose(ControllerKey
);
227 NtClose(BusInstanceKey
);
232 NtClose(ControllerInstanceKey
);
234 ControllerInstance
++;
237 NtClose(ControllerKey
);
240 NtClose(BusInstanceKey
);
252 CreateDisplayDriverList(HINF InfFile
)
260 WCHAR DisplayIdentifier
[128];
261 WCHAR DisplayKey
[32];
263 /* Get the display identification */
264 if (!GetDisplayIdentifier(DisplayIdentifier
, 128))
266 DisplayIdentifier
[0] = 0;
269 DPRINT("Display identifier: '%S'\n", DisplayIdentifier
);
271 /* Search for matching device identifier */
272 if (!InfFindFirstLine(InfFile
, L
"Map.Display", NULL
, &Context
))
274 /* FIXME: error message */
280 if (!InfGetDataField(&Context
, 1, &KeyValue
))
282 /* FIXME: Handle error! */
283 DPRINT("InfGetDataField() failed\n");
287 DPRINT("KeyValue: %S\n", KeyValue
);
288 if (wcsstr(DisplayIdentifier
, KeyValue
))
290 if (!InfGetDataField(&Context
, 0, &KeyName
))
292 /* FIXME: Handle error! */
293 DPRINT("InfGetDataField() failed\n");
297 DPRINT("Display key: %S\n", KeyName
);
298 wcscpy(DisplayKey
, KeyName
);
301 while (InfFindNextLine(&Context
, &Context
));
304 List
= CreateGenericList();
308 if (!InfFindFirstLine (InfFile
, L
"Display", NULL
, &Context
))
310 DestroyGenericList(List
, FALSE
);
316 if (!InfGetDataField(&Context
, 0, &KeyName
))
318 DPRINT1("InfGetDataField() failed\n");
322 if (!InfGetDataField(&Context
, 1, &KeyValue
))
324 DPRINT1("InfGetDataField() failed\n");
328 UserData
= RtlAllocateHeap(ProcessHeap
,
330 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
331 if (UserData
== NULL
)
333 DPRINT1("RtlAllocateHeap() failed\n");
334 DestroyGenericList(List
, TRUE
);
338 wcscpy(UserData
, KeyName
);
340 sprintf(Buffer
, "%S", KeyValue
);
341 AppendGenericListEntry(List
,
344 _wcsicmp(KeyName
, DisplayKey
) ? FALSE
: TRUE
);
346 while (InfFindNextLine(&Context
, &Context
));
349 AppendGenericListEntry(List
, "Other display driver", NULL
, TRUE
);
357 ProcessDisplayRegistry(HINF InfFile
, PGENERIC_LIST List
)
359 PGENERIC_LIST_ENTRY Entry
;
365 DPRINT("ProcessDisplayRegistry() called\n");
367 Entry
= GetGenericListEntry(List
);
370 DPRINT("GetGenericListEntry() failed\n");
374 if (!InfFindFirstLine(InfFile
, L
"Display", Entry
->UserData
, &Context
))
376 DPRINT("InfFindFirstLine() failed\n");
380 if (!InfGetDataField(&Context
, 3, &ServiceName
))
382 DPRINT("InfGetDataField() failed\n");
386 DPRINT("Service name: %S\n", ServiceName
);
389 Status
= RtlWriteRegistryValue(RTL_REGISTRY_SERVICES
,
395 if (!NT_SUCCESS(Status
))
397 DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
401 DPRINT("ProcessDisplayRegistry() done\n");
408 CreateKeyboardDriverList(HINF InfFile
)
417 List
= CreateGenericList();
421 if (!InfFindFirstLine (InfFile
, L
"Keyboard", NULL
, &Context
))
423 DestroyGenericList(List
, FALSE
);
429 if (!InfGetData (&Context
, &KeyName
, &KeyValue
))
431 /* FIXME: Handle error! */
432 DPRINT("InfGetData() failed\n");
436 UserData
= RtlAllocateHeap(ProcessHeap
,
438 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
439 if (UserData
== NULL
)
441 /* FIXME: Handle error! */
444 wcscpy(UserData
, KeyName
);
446 sprintf(Buffer
, "%S", KeyValue
);
447 AppendGenericListEntry(List
, Buffer
, UserData
, FALSE
);
449 while (InfFindNextLine(&Context
, &Context
));
456 CreateKeyboardLayoutList(HINF InfFile
)
464 WCHAR DefaultLayout
[20];
466 /* Get default layout id */
467 if (!InfFindFirstLine (InfFile
, L
"NLS", L
"DefaultLayout", &Context
))
470 if (!InfGetData (&Context
, NULL
, &KeyValue
))
473 wcscpy(DefaultLayout
, KeyValue
);
475 List
= CreateGenericList();
479 if (!InfFindFirstLine (InfFile
, L
"KeyboardLayout", NULL
, &Context
))
481 DestroyGenericList(List
, FALSE
);
487 if (!InfGetData (&Context
, &KeyName
, &KeyValue
))
489 /* FIXME: Handle error! */
490 DPRINT("InfGetData() failed\n");
494 UserData
= RtlAllocateHeap(ProcessHeap
,
496 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
497 if (UserData
== NULL
)
499 /* FIXME: Handle error! */
502 wcscpy(UserData
, KeyName
);
504 sprintf(Buffer
, "%S", KeyValue
);
505 AppendGenericListEntry(List
,
508 _wcsicmp(KeyName
, DefaultLayout
) ? FALSE
: TRUE
);
510 while (InfFindNextLine(&Context
, &Context
));
517 ProcessKeyboardLayoutRegistry(PGENERIC_LIST List
)
519 PGENERIC_LIST_ENTRY Entry
;
521 OBJECT_ATTRIBUTES ObjectAttributes
;
522 UNICODE_STRING KeyName
;
523 UNICODE_STRING ValueName
;
527 Entry
= GetGenericListEntry(List
);
531 LanguageId
= (PWCHAR
)Entry
->UserData
;
532 if (LanguageId
== NULL
)
535 /* Open the nls language key */
536 RtlInitUnicodeString(&KeyName
,
537 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language");
538 InitializeObjectAttributes(&ObjectAttributes
,
540 OBJ_CASE_INSENSITIVE
,
543 Status
= NtOpenKey(&KeyHandle
,
546 if (!NT_SUCCESS(Status
))
548 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status
);
552 /* Set default language */
553 RtlInitUnicodeString(&ValueName
,
555 Status
= NtSetValueKey (KeyHandle
,
559 (PVOID
)(LanguageId
+ 4),
561 if (!NT_SUCCESS(Status
))
563 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
568 /* Set install language */
569 RtlInitUnicodeString(&ValueName
,
571 Status
= NtSetValueKey (KeyHandle
,
575 (PVOID
)(LanguageId
+ 4),
577 if (!NT_SUCCESS(Status
))
579 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
586 /* Open the nls locale key */
587 RtlInitUnicodeString(&KeyName
,
588 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Locale");
589 InitializeObjectAttributes(&ObjectAttributes
,
591 OBJ_CASE_INSENSITIVE
,
594 Status
= NtOpenKey(&KeyHandle
,
597 if (!NT_SUCCESS(Status
))
599 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status
);
603 /* Set default locale */
604 RtlInitUnicodeString(&ValueName
,
606 Status
= NtSetValueKey (KeyHandle
,
612 if (!NT_SUCCESS(Status
))
614 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
627 ProcessKeyboardLayoutFiles(PGENERIC_LIST List
)
635 GetMouseIdentifier(PWSTR ControllerType
,
637 ULONG IdentifierLength
)
639 OBJECT_ATTRIBUTES ObjectAttributes
;
640 UNICODE_STRING KeyName
;
643 HANDLE BusInstanceKey
;
644 HANDLE ControllerKey
;
645 HANDLE ControllerInstanceKey
;
646 HANDLE PeripheralKey
;
647 HANDLE PeripheralInstanceKey
;
649 ULONG ControllerInstance
;
650 ULONG PeripheralInstance
;
652 ULONG ReturnedLength
;
653 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
;
656 DPRINT("GetMouseIdentifier() called\n");
658 /* Open the bus key */
659 RtlInitUnicodeString(&KeyName
,
660 L
"\\Registry\\Machine\\HARDWARE\\Description\\System\\MultifunctionAdapter");
661 InitializeObjectAttributes(&ObjectAttributes
,
663 OBJ_CASE_INSENSITIVE
,
666 Status
= NtOpenKey(&BusKey
,
669 if (!NT_SUCCESS(Status
))
671 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
678 swprintf(Buffer
, L
"%lu", BusInstance
);
679 RtlInitUnicodeString(&KeyName
,
681 InitializeObjectAttributes(&ObjectAttributes
,
683 OBJ_CASE_INSENSITIVE
,
686 Status
= NtOpenKey(&BusInstanceKey
,
689 if (!NT_SUCCESS(Status
))
691 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
696 /* Open the controller type key */
697 RtlInitUnicodeString(&KeyName
,
699 InitializeObjectAttributes(&ObjectAttributes
,
701 OBJ_CASE_INSENSITIVE
,
704 Status
= NtOpenKey(&ControllerKey
,
707 if (NT_SUCCESS(Status
))
709 ControllerInstance
= 0;
712 /* Open the pointer controller instance key */
713 swprintf(Buffer
, L
"%lu", ControllerInstance
);
714 RtlInitUnicodeString(&KeyName
,
716 InitializeObjectAttributes(&ObjectAttributes
,
718 OBJ_CASE_INSENSITIVE
,
721 Status
= NtOpenKey(&ControllerInstanceKey
,
724 if (!NT_SUCCESS(Status
))
726 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
727 NtClose(ControllerKey
);
728 NtClose(BusInstanceKey
);
733 /* Open the 'PointerPeripheral' key */
734 RtlInitUnicodeString(&KeyName
,
735 L
"PointerPeripheral");
736 InitializeObjectAttributes(&ObjectAttributes
,
738 OBJ_CASE_INSENSITIVE
,
739 ControllerInstanceKey
,
741 Status
= NtOpenKey(&PeripheralKey
,
744 if (NT_SUCCESS(Status
))
746 PeripheralInstance
= 0;
749 /* Open the pointer peripheral instance key */
750 swprintf(Buffer
, L
"%lu", PeripheralInstance
);
751 RtlInitUnicodeString(&KeyName
,
753 InitializeObjectAttributes(&ObjectAttributes
,
755 OBJ_CASE_INSENSITIVE
,
758 Status
= NtOpenKey(&PeripheralInstanceKey
,
761 if (!NT_SUCCESS(Status
))
763 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
764 NtClose(PeripheralKey
);
765 NtClose(ControllerInstanceKey
);
766 NtClose(ControllerKey
);
767 NtClose(BusInstanceKey
);
772 /* Get peripheral identifier */
773 RtlInitUnicodeString(&KeyName
,
776 BufferLength
= sizeof(KEY_VALUE_PARTIAL_INFORMATION
) +
778 ValueInfo
= RtlAllocateHeap(RtlGetProcessHeap(),
781 if (ValueInfo
== NULL
)
783 DPRINT("RtlAllocateHeap() failed\n");
784 NtClose(PeripheralInstanceKey
);
785 NtClose(PeripheralKey
);
786 NtClose(ControllerInstanceKey
);
787 NtClose(ControllerKey
);
788 NtClose(BusInstanceKey
);
793 Status
= NtQueryValueKey(PeripheralInstanceKey
,
795 KeyValuePartialInformation
,
799 if (NT_SUCCESS(Status
))
801 DPRINT("Identifier: %S\n", (PWSTR
)ValueInfo
->Data
);
803 BufferLength
= min(ValueInfo
->DataLength
/ sizeof(WCHAR
), IdentifierLength
);
804 RtlCopyMemory (Identifier
,
806 BufferLength
* sizeof(WCHAR
));
807 Identifier
[BufferLength
] = 0;
809 RtlFreeHeap(RtlGetProcessHeap(),
812 NtClose(PeripheralInstanceKey
);
813 NtClose(PeripheralKey
);
814 NtClose(ControllerInstanceKey
);
815 NtClose(ControllerKey
);
816 NtClose(BusInstanceKey
);
821 RtlFreeHeap(RtlGetProcessHeap(),
825 NtClose(PeripheralInstanceKey
);
827 PeripheralInstance
++;
830 NtClose(PeripheralKey
);
833 NtClose(ControllerInstanceKey
);
835 ControllerInstance
++;
838 NtClose(ControllerKey
);
841 NtClose(BusInstanceKey
);
853 CreateMouseDriverList(HINF InfFile
)
861 WCHAR MouseIdentifier
[128];
864 /* Get the mouse identification */
865 if (!GetMouseIdentifier(L
"SerialController", MouseIdentifier
, 128))
867 if (!GetMouseIdentifier(L
"PointerController", MouseIdentifier
, 128))
869 wcscpy (MouseIdentifier
, L
"NO MOUSE");
873 DPRINT("Mouse identifier: '%S'\n", MouseIdentifier
);
875 /* Search for matching device identifier */
876 if (!InfFindFirstLine(InfFile
, L
"Map.Mouse", NULL
, &Context
))
878 /* FIXME: error message */
884 if (!InfGetDataField(&Context
, 1, &KeyValue
))
886 /* FIXME: Handle error! */
887 DPRINT("InfGetDataField() failed\n");
891 DPRINT("KeyValue: %S\n", KeyValue
);
892 if (wcsstr(MouseIdentifier
, KeyValue
))
894 if (!InfGetDataField(&Context
, 0, &KeyName
))
896 /* FIXME: Handle error! */
897 DPRINT("InfGetDataField() failed\n");
901 DPRINT("Mouse key: %S\n", KeyName
);
902 wcscpy(MouseKey
, KeyName
);
905 while (InfFindNextLine(&Context
, &Context
));
908 List
= CreateGenericList();
912 if (!InfFindFirstLine(InfFile
, L
"Mouse", NULL
, &Context
))
914 DestroyGenericList(List
, FALSE
);
920 if (!InfGetDataField(&Context
, 0, &KeyName
))
922 DPRINT1("InfGetDataField() failed\n");
926 if (!InfGetDataField(&Context
, 1, &KeyValue
))
928 DPRINT1("InfGetDataField() failed\n");
932 UserData
= RtlAllocateHeap(ProcessHeap
,
934 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
935 if (UserData
== NULL
)
937 DPRINT1("RtlAllocateHeap() failed\n");
938 DestroyGenericList(List
, TRUE
);
942 wcscpy(UserData
, KeyName
);
944 sprintf(Buffer
, "%S", KeyValue
);
945 AppendGenericListEntry(List
,
948 _wcsicmp(KeyName
, MouseKey
) ? FALSE
: TRUE
);
950 while (InfFindNextLine(&Context
, &Context
));
957 ProcessMouseRegistry(HINF InfFile
, PGENERIC_LIST List
)
959 PGENERIC_LIST_ENTRY Entry
;
965 DPRINT("ProcessMouseRegistry() called\n");
967 Entry
= GetGenericListEntry(List
);
970 DPRINT("GetGenericListEntry() failed\n");
974 if (!InfFindFirstLine(InfFile
, L
"Mouse", Entry
->UserData
, &Context
))
976 DPRINT("InfFindFirstLine() failed\n");
980 if (!InfGetDataField(&Context
, 3, &ServiceName
))
982 DPRINT("InfGetDataField() failed\n");
986 DPRINT("Service name: %S\n", ServiceName
);
989 Status
= RtlWriteRegistryValue(RTL_REGISTRY_SERVICES
,
995 if (!NT_SUCCESS(Status
))
997 DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
1001 DPRINT("ProcessMouseRegistry() done\n");
1009 ProcessMouseFiles(PGENERIC_LIST List
)