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.
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>
32 #include <rosrtl/string.h>
43 /* FUNCTIONS ****************************************************************/
46 CreateComputerTypeList(HINF InfFile
)
55 List
= CreateGenericList();
59 if (!InfFindFirstLine (InfFile
, L
"Computer", NULL
, &Context
))
61 DestroyGenericList(List
, FALSE
);
67 if (!InfGetData (&Context
, &KeyName
, &KeyValue
))
69 /* FIXME: Handle error! */
70 DPRINT("InfGetData() failed\n");
74 UserData
= RtlAllocateHeap(ProcessHeap
,
76 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
79 /* FIXME: Handle error! */
82 wcscpy(UserData
, KeyName
);
84 sprintf(Buffer
, "%S", KeyValue
);
85 AppendGenericListEntry(List
, Buffer
, UserData
, FALSE
);
87 while (InfFindNextLine(&Context
, &Context
));
94 GetDisplayIdentifier(PWSTR Identifier
,
95 ULONG IdentifierLength
)
97 OBJECT_ATTRIBUTES ObjectAttributes
;
98 UNICODE_STRING KeyName
;
101 HANDLE BusInstanceKey
;
102 HANDLE ControllerKey
;
103 HANDLE ControllerInstanceKey
;
105 ULONG ControllerInstance
;
107 ULONG ReturnedLength
;
108 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
;
111 DPRINT("GetDisplayIdentifier() called\n");
113 /* Open the bus key */
114 RtlInitUnicodeString(&KeyName
,
115 L
"\\Registry\\Machine\\HARDWARE\\Description\\System\\MultifunctionAdapter");
116 InitializeObjectAttributes(&ObjectAttributes
,
118 OBJ_CASE_INSENSITIVE
,
121 Status
= NtOpenKey(&BusKey
,
124 if (!NT_SUCCESS(Status
))
126 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
133 swprintf(Buffer
, L
"%lu", BusInstance
);
134 RtlInitUnicodeString(&KeyName
,
136 InitializeObjectAttributes(&ObjectAttributes
,
138 OBJ_CASE_INSENSITIVE
,
141 Status
= NtOpenKey(&BusInstanceKey
,
144 if (!NT_SUCCESS(Status
))
146 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
151 /* Open the controller type key */
152 RtlInitUnicodeString(&KeyName
,
153 L
"DisplayController");
154 InitializeObjectAttributes(&ObjectAttributes
,
156 OBJ_CASE_INSENSITIVE
,
159 Status
= NtOpenKey(&ControllerKey
,
162 if (NT_SUCCESS(Status
))
164 ControllerInstance
= 0;
167 /* Open the pointer controller instance key */
168 swprintf(Buffer
, L
"%lu", ControllerInstance
);
169 RtlInitUnicodeString(&KeyName
,
171 InitializeObjectAttributes(&ObjectAttributes
,
173 OBJ_CASE_INSENSITIVE
,
176 Status
= NtOpenKey(&ControllerInstanceKey
,
179 if (!NT_SUCCESS(Status
))
181 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
182 NtClose(ControllerKey
);
183 NtClose(BusInstanceKey
);
188 /* Get controller identifier */
189 RtlInitUnicodeString(&KeyName
,
192 BufferLength
= sizeof(KEY_VALUE_PARTIAL_INFORMATION
) +
194 ValueInfo
= RtlAllocateHeap(RtlGetProcessHeap(),
197 if (ValueInfo
== NULL
)
199 DPRINT("RtlAllocateHeap() failed\n");
200 NtClose(ControllerInstanceKey
);
201 NtClose(ControllerKey
);
202 NtClose(BusInstanceKey
);
207 Status
= NtQueryValueKey(ControllerInstanceKey
,
209 KeyValuePartialInformation
,
213 if (NT_SUCCESS(Status
))
215 DPRINT("Identifier: %S\n", (PWSTR
)ValueInfo
->Data
);
217 BufferLength
= min(ValueInfo
->DataLength
/ sizeof(WCHAR
), IdentifierLength
);
218 RtlCopyMemory (Identifier
,
220 BufferLength
* sizeof(WCHAR
));
221 Identifier
[BufferLength
] = 0;
223 RtlFreeHeap(RtlGetProcessHeap(),
226 NtClose(ControllerInstanceKey
);
227 NtClose(ControllerKey
);
228 NtClose(BusInstanceKey
);
233 NtClose(ControllerInstanceKey
);
235 ControllerInstance
++;
238 NtClose(ControllerKey
);
241 NtClose(BusInstanceKey
);
253 CreateDisplayDriverList(HINF InfFile
)
261 WCHAR DisplayIdentifier
[128];
262 WCHAR DisplayKey
[32];
264 /* Get the display identification */
265 if (!GetDisplayIdentifier(DisplayIdentifier
, 128))
267 DisplayIdentifier
[0] = 0;
270 DPRINT("Display identifier: '%S'\n", DisplayIdentifier
);
272 /* Search for matching device identifier */
273 if (!InfFindFirstLine(InfFile
, L
"Map.Display", NULL
, &Context
))
275 /* FIXME: error message */
281 if (!InfGetDataField(&Context
, 1, &KeyValue
))
283 /* FIXME: Handle error! */
284 DPRINT("InfGetDataField() failed\n");
288 DPRINT("KeyValue: %S\n", KeyValue
);
289 if (wcsstr(DisplayIdentifier
, KeyValue
))
291 if (!InfGetDataField(&Context
, 0, &KeyName
))
293 /* FIXME: Handle error! */
294 DPRINT("InfGetDataField() failed\n");
298 DPRINT("Display key: %S\n", KeyName
);
299 wcscpy(DisplayKey
, KeyName
);
302 while (InfFindNextLine(&Context
, &Context
));
305 List
= CreateGenericList();
309 if (!InfFindFirstLine (InfFile
, L
"Display", NULL
, &Context
))
311 DestroyGenericList(List
, FALSE
);
317 if (!InfGetDataField(&Context
, 0, &KeyName
))
319 DPRINT1("InfGetDataField() failed\n");
323 if (!InfGetDataField(&Context
, 1, &KeyValue
))
325 DPRINT1("InfGetDataField() failed\n");
329 UserData
= RtlAllocateHeap(ProcessHeap
,
331 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
332 if (UserData
== NULL
)
334 DPRINT1("RtlAllocateHeap() failed\n");
335 DestroyGenericList(List
, TRUE
);
339 wcscpy(UserData
, KeyName
);
341 sprintf(Buffer
, "%S", KeyValue
);
342 AppendGenericListEntry(List
,
345 _wcsicmp(KeyName
, DisplayKey
) ? FALSE
: TRUE
);
347 while (InfFindNextLine(&Context
, &Context
));
350 AppendGenericListEntry(List
, "Other display driver", NULL
, TRUE
);
357 ProcessComputerFiles(HINF InfFile
, PGENERIC_LIST List
, PWCHAR
* AdditionalSectionName
)
359 PGENERIC_LIST_ENTRY Entry
;
360 static WCHAR SectionName
[128];
362 DPRINT("ProcessComputerFiles() called\n");
364 Entry
= GetGenericListEntry(List
);
367 DPRINT("GetGenericListEntry() failed\n");
371 wcscpy(SectionName
, L
"Files.");
372 wcscat(SectionName
, Entry
->UserData
);
373 *AdditionalSectionName
= SectionName
;
380 ProcessDisplayRegistry(HINF InfFile
, PGENERIC_LIST List
)
382 PGENERIC_LIST_ENTRY Entry
;
388 DPRINT("ProcessDisplayRegistry() called\n");
390 Entry
= GetGenericListEntry(List
);
393 DPRINT("GetGenericListEntry() failed\n");
397 if (!InfFindFirstLine(InfFile
, L
"Display", Entry
->UserData
, &Context
))
399 DPRINT("InfFindFirstLine() failed\n");
403 if (!InfGetDataField(&Context
, 3, &ServiceName
))
405 DPRINT("InfGetDataField() failed\n");
409 DPRINT("Service name: %S\n", ServiceName
);
412 Status
= RtlWriteRegistryValue(RTL_REGISTRY_SERVICES
,
418 if (!NT_SUCCESS(Status
))
420 DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
424 DPRINT("ProcessDisplayRegistry() done\n");
431 CreateKeyboardDriverList(HINF InfFile
)
440 List
= CreateGenericList();
444 if (!InfFindFirstLine (InfFile
, L
"Keyboard", NULL
, &Context
))
446 DestroyGenericList(List
, FALSE
);
452 if (!InfGetData (&Context
, &KeyName
, &KeyValue
))
454 /* FIXME: Handle error! */
455 DPRINT("InfGetData() failed\n");
459 UserData
= RtlAllocateHeap(ProcessHeap
,
461 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
462 if (UserData
== NULL
)
464 /* FIXME: Handle error! */
467 wcscpy(UserData
, KeyName
);
469 sprintf(Buffer
, "%S", KeyValue
);
470 AppendGenericListEntry(List
, Buffer
, UserData
, FALSE
);
472 while (InfFindNextLine(&Context
, &Context
));
479 CreateKeyboardLayoutList(HINF InfFile
)
487 WCHAR DefaultLayout
[20];
489 /* Get default layout id */
490 if (!InfFindFirstLine (InfFile
, L
"NLS", L
"DefaultLayout", &Context
))
493 if (!InfGetData (&Context
, NULL
, &KeyValue
))
496 wcscpy(DefaultLayout
, KeyValue
);
498 List
= CreateGenericList();
502 if (!InfFindFirstLine (InfFile
, L
"KeyboardLayout", NULL
, &Context
))
504 DestroyGenericList(List
, FALSE
);
510 if (!InfGetData (&Context
, &KeyName
, &KeyValue
))
512 /* FIXME: Handle error! */
513 DPRINT("InfGetData() failed\n");
517 UserData
= RtlAllocateHeap(ProcessHeap
,
519 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
520 if (UserData
== NULL
)
522 /* FIXME: Handle error! */
525 wcscpy(UserData
, KeyName
);
527 sprintf(Buffer
, "%S", KeyValue
);
528 AppendGenericListEntry(List
,
531 _wcsicmp(KeyName
, DefaultLayout
) ? FALSE
: TRUE
);
533 while (InfFindNextLine(&Context
, &Context
));
540 ProcessKeyboardLayoutRegistry(PGENERIC_LIST List
)
542 PGENERIC_LIST_ENTRY Entry
;
544 OBJECT_ATTRIBUTES ObjectAttributes
;
545 UNICODE_STRING KeyName
;
546 UNICODE_STRING ValueName
;
550 Entry
= GetGenericListEntry(List
);
554 LanguageId
= (PWCHAR
)Entry
->UserData
;
555 if (LanguageId
== NULL
)
558 /* Open the nls language key */
559 RtlInitUnicodeString(&KeyName
,
560 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language");
561 InitializeObjectAttributes(&ObjectAttributes
,
563 OBJ_CASE_INSENSITIVE
,
566 Status
= NtOpenKey(&KeyHandle
,
569 if (!NT_SUCCESS(Status
))
571 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status
);
575 /* Set default language */
576 RtlInitUnicodeString(&ValueName
,
578 Status
= NtSetValueKey (KeyHandle
,
582 (PVOID
)(LanguageId
+ 4),
584 if (!NT_SUCCESS(Status
))
586 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
591 /* Set install language */
592 RtlInitUnicodeString(&ValueName
,
594 Status
= NtSetValueKey (KeyHandle
,
598 (PVOID
)(LanguageId
+ 4),
600 if (!NT_SUCCESS(Status
))
602 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
615 ProcessKeyboardLayoutFiles(PGENERIC_LIST List
)
623 GetMouseIdentifier(PWSTR ControllerType
,
625 ULONG IdentifierLength
)
627 OBJECT_ATTRIBUTES ObjectAttributes
;
628 UNICODE_STRING KeyName
;
631 HANDLE BusInstanceKey
;
632 HANDLE ControllerKey
;
633 HANDLE ControllerInstanceKey
;
634 HANDLE PeripheralKey
;
635 HANDLE PeripheralInstanceKey
;
637 ULONG ControllerInstance
;
638 ULONG PeripheralInstance
;
640 ULONG ReturnedLength
;
641 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
;
644 DPRINT("GetMouseIdentifier() called\n");
646 /* Open the bus key */
647 RtlInitUnicodeString(&KeyName
,
648 L
"\\Registry\\Machine\\HARDWARE\\Description\\System\\MultifunctionAdapter");
649 InitializeObjectAttributes(&ObjectAttributes
,
651 OBJ_CASE_INSENSITIVE
,
654 Status
= NtOpenKey(&BusKey
,
657 if (!NT_SUCCESS(Status
))
659 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
666 swprintf(Buffer
, L
"%lu", BusInstance
);
667 RtlInitUnicodeString(&KeyName
,
669 InitializeObjectAttributes(&ObjectAttributes
,
671 OBJ_CASE_INSENSITIVE
,
674 Status
= NtOpenKey(&BusInstanceKey
,
677 if (!NT_SUCCESS(Status
))
679 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
684 /* Open the controller type key */
685 RtlInitUnicodeString(&KeyName
,
687 InitializeObjectAttributes(&ObjectAttributes
,
689 OBJ_CASE_INSENSITIVE
,
692 Status
= NtOpenKey(&ControllerKey
,
695 if (NT_SUCCESS(Status
))
697 ControllerInstance
= 0;
700 /* Open the pointer controller instance key */
701 swprintf(Buffer
, L
"%lu", ControllerInstance
);
702 RtlInitUnicodeString(&KeyName
,
704 InitializeObjectAttributes(&ObjectAttributes
,
706 OBJ_CASE_INSENSITIVE
,
709 Status
= NtOpenKey(&ControllerInstanceKey
,
712 if (!NT_SUCCESS(Status
))
714 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
715 NtClose(ControllerKey
);
716 NtClose(BusInstanceKey
);
721 /* Open the 'PointerPeripheral' key */
722 RtlInitUnicodeString(&KeyName
,
723 L
"PointerPeripheral");
724 InitializeObjectAttributes(&ObjectAttributes
,
726 OBJ_CASE_INSENSITIVE
,
727 ControllerInstanceKey
,
729 Status
= NtOpenKey(&PeripheralKey
,
732 if (NT_SUCCESS(Status
))
734 PeripheralInstance
= 0;
737 /* Open the pointer peripheral instance key */
738 swprintf(Buffer
, L
"%lu", PeripheralInstance
);
739 RtlInitUnicodeString(&KeyName
,
741 InitializeObjectAttributes(&ObjectAttributes
,
743 OBJ_CASE_INSENSITIVE
,
746 Status
= NtOpenKey(&PeripheralInstanceKey
,
749 if (!NT_SUCCESS(Status
))
751 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
752 NtClose(PeripheralKey
);
753 NtClose(ControllerInstanceKey
);
754 NtClose(ControllerKey
);
755 NtClose(BusInstanceKey
);
760 /* Get peripheral identifier */
761 RtlInitUnicodeString(&KeyName
,
764 BufferLength
= sizeof(KEY_VALUE_PARTIAL_INFORMATION
) +
766 ValueInfo
= RtlAllocateHeap(RtlGetProcessHeap(),
769 if (ValueInfo
== NULL
)
771 DPRINT("RtlAllocateHeap() failed\n");
772 NtClose(PeripheralInstanceKey
);
773 NtClose(PeripheralKey
);
774 NtClose(ControllerInstanceKey
);
775 NtClose(ControllerKey
);
776 NtClose(BusInstanceKey
);
781 Status
= NtQueryValueKey(PeripheralInstanceKey
,
783 KeyValuePartialInformation
,
787 if (NT_SUCCESS(Status
))
789 DPRINT("Identifier: %S\n", (PWSTR
)ValueInfo
->Data
);
791 BufferLength
= min(ValueInfo
->DataLength
/ sizeof(WCHAR
), IdentifierLength
);
792 RtlCopyMemory (Identifier
,
794 BufferLength
* sizeof(WCHAR
));
795 Identifier
[BufferLength
] = 0;
797 RtlFreeHeap(RtlGetProcessHeap(),
800 NtClose(PeripheralInstanceKey
);
801 NtClose(PeripheralKey
);
802 NtClose(ControllerInstanceKey
);
803 NtClose(ControllerKey
);
804 NtClose(BusInstanceKey
);
809 RtlFreeHeap(RtlGetProcessHeap(),
813 NtClose(PeripheralInstanceKey
);
815 PeripheralInstance
++;
818 NtClose(PeripheralKey
);
821 NtClose(ControllerInstanceKey
);
823 ControllerInstance
++;
826 NtClose(ControllerKey
);
829 NtClose(BusInstanceKey
);
841 CreateMouseDriverList(HINF InfFile
)
849 WCHAR MouseIdentifier
[128];
852 /* Get the mouse identification */
853 if (!GetMouseIdentifier(L
"SerialController", MouseIdentifier
, 128))
855 if (!GetMouseIdentifier(L
"PointerController", MouseIdentifier
, 128))
857 wcscpy (MouseIdentifier
, L
"NO MOUSE");
861 DPRINT("Mouse identifier: '%S'\n", MouseIdentifier
);
863 /* Search for matching device identifier */
864 if (!InfFindFirstLine(InfFile
, L
"Map.Mouse", NULL
, &Context
))
866 /* FIXME: error message */
872 if (!InfGetDataField(&Context
, 1, &KeyValue
))
874 /* FIXME: Handle error! */
875 DPRINT("InfGetDataField() failed\n");
879 DPRINT("KeyValue: %S\n", KeyValue
);
880 if (wcsstr(MouseIdentifier
, KeyValue
))
882 if (!InfGetDataField(&Context
, 0, &KeyName
))
884 /* FIXME: Handle error! */
885 DPRINT("InfGetDataField() failed\n");
889 DPRINT("Mouse key: %S\n", KeyName
);
890 wcscpy(MouseKey
, KeyName
);
893 while (InfFindNextLine(&Context
, &Context
));
896 List
= CreateGenericList();
900 if (!InfFindFirstLine(InfFile
, L
"Mouse", NULL
, &Context
))
902 DestroyGenericList(List
, FALSE
);
908 if (!InfGetDataField(&Context
, 0, &KeyName
))
910 DPRINT1("InfGetDataField() failed\n");
914 if (!InfGetDataField(&Context
, 1, &KeyValue
))
916 DPRINT1("InfGetDataField() failed\n");
920 UserData
= RtlAllocateHeap(ProcessHeap
,
922 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
923 if (UserData
== NULL
)
925 DPRINT1("RtlAllocateHeap() failed\n");
926 DestroyGenericList(List
, TRUE
);
930 wcscpy(UserData
, KeyName
);
932 sprintf(Buffer
, "%S", KeyValue
);
933 AppendGenericListEntry(List
,
936 _wcsicmp(KeyName
, MouseKey
) ? FALSE
: TRUE
);
938 while (InfFindNextLine(&Context
, &Context
));
945 ProcessMouseRegistry(HINF InfFile
, PGENERIC_LIST List
)
947 PGENERIC_LIST_ENTRY Entry
;
953 DPRINT("ProcessMouseRegistry() called\n");
955 Entry
= GetGenericListEntry(List
);
958 DPRINT("GetGenericListEntry() failed\n");
962 if (!InfFindFirstLine(InfFile
, L
"Mouse", Entry
->UserData
, &Context
))
964 DPRINT("InfFindFirstLine() failed\n");
968 if (!InfGetDataField(&Context
, 3, &ServiceName
))
970 DPRINT("InfGetDataField() failed\n");
974 DPRINT("Service name: %S\n", ServiceName
);
977 Status
= RtlWriteRegistryValue(RTL_REGISTRY_SERVICES
,
983 if (!NT_SUCCESS(Status
))
985 DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
989 DPRINT("ProcessMouseRegistry() done\n");
997 ProcessMouseFiles(PGENERIC_LIST List
)