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.6 2004/11/15 14:41:25 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 *****************************************************************/
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
);
592 ProcessKeyboardLayoutFiles(PGENERIC_LIST List
)
600 GetMouseIdentifier(PWSTR ControllerType
,
602 ULONG IdentifierLength
)
604 OBJECT_ATTRIBUTES ObjectAttributes
;
605 UNICODE_STRING KeyName
;
608 HANDLE BusInstanceKey
;
609 HANDLE ControllerKey
;
610 HANDLE ControllerInstanceKey
;
611 HANDLE PeripheralKey
;
612 HANDLE PeripheralInstanceKey
;
614 ULONG ControllerInstance
;
615 ULONG PeripheralInstance
;
617 ULONG ReturnedLength
;
618 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
;
621 DPRINT("GetMouseIdentifier() called\n");
623 /* Open the bus key */
624 RtlInitUnicodeString(&KeyName
,
625 L
"\\Registry\\Machine\\HARDWARE\\Description\\System\\MultifunctionAdapter");
626 InitializeObjectAttributes(&ObjectAttributes
,
628 OBJ_CASE_INSENSITIVE
,
631 Status
= NtOpenKey(&BusKey
,
634 if (!NT_SUCCESS(Status
))
636 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
643 swprintf(Buffer
, L
"%lu", BusInstance
);
644 RtlInitUnicodeString(&KeyName
,
646 InitializeObjectAttributes(&ObjectAttributes
,
648 OBJ_CASE_INSENSITIVE
,
651 Status
= NtOpenKey(&BusInstanceKey
,
654 if (!NT_SUCCESS(Status
))
656 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
661 /* Open the controller type key */
662 RtlInitUnicodeString(&KeyName
,
664 InitializeObjectAttributes(&ObjectAttributes
,
666 OBJ_CASE_INSENSITIVE
,
669 Status
= NtOpenKey(&ControllerKey
,
672 if (NT_SUCCESS(Status
))
674 ControllerInstance
= 0;
677 /* Open the pointer controller instance key */
678 swprintf(Buffer
, L
"%lu", ControllerInstance
);
679 RtlInitUnicodeString(&KeyName
,
681 InitializeObjectAttributes(&ObjectAttributes
,
683 OBJ_CASE_INSENSITIVE
,
686 Status
= NtOpenKey(&ControllerInstanceKey
,
689 if (!NT_SUCCESS(Status
))
691 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
692 NtClose(ControllerKey
);
693 NtClose(BusInstanceKey
);
698 /* Open the 'PointerPeripheral' key */
699 RtlInitUnicodeString(&KeyName
,
700 L
"PointerPeripheral");
701 InitializeObjectAttributes(&ObjectAttributes
,
703 OBJ_CASE_INSENSITIVE
,
704 ControllerInstanceKey
,
706 Status
= NtOpenKey(&PeripheralKey
,
709 if (NT_SUCCESS(Status
))
711 PeripheralInstance
= 0;
714 /* Open the pointer peripheral instance key */
715 swprintf(Buffer
, L
"%lu", PeripheralInstance
);
716 RtlInitUnicodeString(&KeyName
,
718 InitializeObjectAttributes(&ObjectAttributes
,
720 OBJ_CASE_INSENSITIVE
,
723 Status
= NtOpenKey(&PeripheralInstanceKey
,
726 if (!NT_SUCCESS(Status
))
728 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
729 NtClose(PeripheralKey
);
730 NtClose(ControllerInstanceKey
);
731 NtClose(ControllerKey
);
732 NtClose(BusInstanceKey
);
737 /* Get peripheral identifier */
738 RtlInitUnicodeString(&KeyName
,
741 BufferLength
= sizeof(KEY_VALUE_PARTIAL_INFORMATION
) +
743 ValueInfo
= RtlAllocateHeap(RtlGetProcessHeap(),
746 if (ValueInfo
== NULL
)
748 DPRINT("RtlAllocateHeap() failed\n");
749 NtClose(PeripheralInstanceKey
);
750 NtClose(PeripheralKey
);
751 NtClose(ControllerInstanceKey
);
752 NtClose(ControllerKey
);
753 NtClose(BusInstanceKey
);
758 Status
= NtQueryValueKey(PeripheralInstanceKey
,
760 KeyValuePartialInformation
,
764 if (NT_SUCCESS(Status
))
766 DPRINT("Identifier: %S\n", (PWSTR
)ValueInfo
->Data
);
768 BufferLength
= min(ValueInfo
->DataLength
/ sizeof(WCHAR
), IdentifierLength
);
769 RtlCopyMemory (Identifier
,
771 BufferLength
* sizeof(WCHAR
));
772 Identifier
[BufferLength
] = 0;
774 RtlFreeHeap(RtlGetProcessHeap(),
777 NtClose(PeripheralInstanceKey
);
778 NtClose(PeripheralKey
);
779 NtClose(ControllerInstanceKey
);
780 NtClose(ControllerKey
);
781 NtClose(BusInstanceKey
);
786 RtlFreeHeap(RtlGetProcessHeap(),
790 NtClose(PeripheralInstanceKey
);
792 PeripheralInstance
++;
795 NtClose(PeripheralKey
);
798 NtClose(ControllerInstanceKey
);
800 ControllerInstance
++;
803 NtClose(ControllerKey
);
806 NtClose(BusInstanceKey
);
818 CreateMouseDriverList(HINF InfFile
)
826 WCHAR MouseIdentifier
[128];
829 /* Get the mouse identification */
830 if (!GetMouseIdentifier(L
"SerialController", MouseIdentifier
, 128))
832 if (!GetMouseIdentifier(L
"PointerController", MouseIdentifier
, 128))
834 wcscpy (MouseIdentifier
, L
"NO MOUSE");
838 DPRINT("Mouse identifier: '%S'\n", MouseIdentifier
);
840 /* Search for matching device identifier */
841 if (!InfFindFirstLine(InfFile
, L
"Map.Mouse", NULL
, &Context
))
843 /* FIXME: error message */
849 if (!InfGetDataField(&Context
, 1, &KeyValue
))
851 /* FIXME: Handle error! */
852 DPRINT("InfGetDataField() failed\n");
856 DPRINT("KeyValue: %S\n", KeyValue
);
857 if (wcsstr(MouseIdentifier
, KeyValue
))
859 if (!InfGetDataField(&Context
, 0, &KeyName
))
861 /* FIXME: Handle error! */
862 DPRINT("InfGetDataField() failed\n");
866 DPRINT("Mouse key: %S\n", KeyName
);
867 wcscpy(MouseKey
, KeyName
);
870 while (InfFindNextLine(&Context
, &Context
));
873 List
= CreateGenericList();
877 if (!InfFindFirstLine(InfFile
, L
"Mouse", NULL
, &Context
))
879 DestroyGenericList(List
, FALSE
);
885 if (!InfGetDataField(&Context
, 0, &KeyName
))
887 DPRINT1("InfGetDataField() failed\n");
891 if (!InfGetDataField(&Context
, 1, &KeyValue
))
893 DPRINT1("InfGetDataField() failed\n");
897 UserData
= RtlAllocateHeap(ProcessHeap
,
899 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
900 if (UserData
== NULL
)
902 DPRINT1("RtlAllocateHeap() failed\n");
903 DestroyGenericList(List
, TRUE
);
907 wcscpy(UserData
, KeyName
);
909 sprintf(Buffer
, "%S", KeyValue
);
910 AppendGenericListEntry(List
,
913 _wcsicmp(KeyName
, MouseKey
) ? FALSE
: TRUE
);
915 while (InfFindNextLine(&Context
, &Context
));
922 ProcessMouseRegistry(HINF InfFile
, PGENERIC_LIST List
)
924 PGENERIC_LIST_ENTRY Entry
;
930 DPRINT("ProcessMouseRegistry() called\n");
932 Entry
= GetGenericListEntry(List
);
935 DPRINT("GetGenericListEntry() failed\n");
939 if (!InfFindFirstLine(InfFile
, L
"Mouse", Entry
->UserData
, &Context
))
941 DPRINT("InfFindFirstLine() failed\n");
945 if (!InfGetDataField(&Context
, 3, &ServiceName
))
947 DPRINT("InfGetDataField() failed\n");
951 DPRINT("Service name: %S\n", ServiceName
);
954 Status
= RtlWriteRegistryValue(RTL_REGISTRY_SERVICES
,
960 if (!NT_SUCCESS(Status
))
962 DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
966 DPRINT("ProcessMouseRegistry() done\n");
974 ProcessMouseFiles(PGENERIC_LIST List
)