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 /* COPYRIGHT: See COPYING in the top level directory
20 * PROJECT: ReactOS text-mode setup
21 * FILE: subsys/system/usetup/settings.c
22 * PURPOSE: Device settings support functions
23 * PROGRAMMER: Eric Kohl
26 /* INCLUDES *****************************************************************/
33 /* FUNCTIONS ****************************************************************/
36 GetComputerIdentifier(PWSTR Identifier
,
37 ULONG IdentifierLength
)
39 OBJECT_ATTRIBUTES ObjectAttributes
;
40 UNICODE_STRING KeyName
;
41 LPCWSTR ComputerIdentifier
;
43 PKEY_FULL_INFORMATION pFullInfo
;
44 ULONG Size
, SizeNeeded
;
47 DPRINT("GetComputerIdentifier() called\n");
49 Size
= sizeof(KEY_FULL_INFORMATION
);
50 pFullInfo
= (PKEY_FULL_INFORMATION
)RtlAllocateHeap(RtlGetProcessHeap(), 0, Size
);
53 DPRINT("RtlAllocateHeap() failed\n");
57 /* Open the processors key */
58 RtlInitUnicodeString(&KeyName
,
59 L
"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor");
60 InitializeObjectAttributes(&ObjectAttributes
,
65 Status
= NtOpenKey(&ProcessorsKey
,
68 if (!NT_SUCCESS(Status
))
70 DPRINT("NtOpenKey() failed (Status 0x%lx)\n", Status
);
71 RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo
);
75 /* Get number of subkeys */
82 NtClose(ProcessorsKey
);
83 if (!NT_SUCCESS(Status
) && Status
!= STATUS_BUFFER_OVERFLOW
)
85 DPRINT("NtQueryKey() failed (Status 0x%lx)\n", Status
);
86 RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo
);
90 /* Find computer identifier */
91 if (pFullInfo
->SubKeys
== 0)
93 /* Something strange happened. No processor detected */
94 RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo
);
98 if (pFullInfo
->SubKeys
== 1)
100 /* Computer is mono-CPU */
101 ComputerIdentifier
= L
"PC UP";
105 /* Computer is multi-CPUs */
106 ComputerIdentifier
= L
"PC MP";
108 RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo
);
110 /* Copy computer identifier to return buffer */
111 SizeNeeded
= (wcslen(ComputerIdentifier
) + 1) * sizeof(WCHAR
);
112 if (SizeNeeded
> IdentifierLength
)
114 RtlCopyMemory(Identifier
, ComputerIdentifier
, SizeNeeded
);
120 CreateComputerTypeList(HINF InfFile
)
128 WCHAR ComputerIdentifier
[128];
129 WCHAR ComputerKey
[32];
131 /* Get the computer identification */
132 if (!GetComputerIdentifier(ComputerIdentifier
, 128))
134 ComputerIdentifier
[0] = 0;
137 DPRINT("Computer identifier: '%S'\n", ComputerIdentifier
);
139 /* Search for matching device identifier */
140 if (!SetupFindFirstLineW(InfFile
, L
"Map.Computer", NULL
, &Context
))
142 /* FIXME: error message */
148 if (!INF_GetDataField(&Context
, 1, &KeyValue
))
150 /* FIXME: Handle error! */
151 DPRINT("INF_GetDataField() failed\n");
155 DPRINT("KeyValue: %S\n", KeyValue
);
156 if (wcsstr(ComputerIdentifier
, KeyValue
))
158 if (!INF_GetDataField(&Context
, 0, &KeyName
))
160 /* FIXME: Handle error! */
161 DPRINT("INF_GetDataField() failed\n");
165 DPRINT("Computer key: %S\n", KeyName
);
166 wcscpy(ComputerKey
, KeyName
);
169 while (SetupFindNextLine(&Context
, &Context
));
171 List
= CreateGenericList();
175 if (!SetupFindFirstLineW (InfFile
, L
"Computer", NULL
, &Context
))
177 DestroyGenericList(List
, FALSE
);
183 if (!INF_GetData (&Context
, &KeyName
, &KeyValue
))
185 /* FIXME: Handle error! */
186 DPRINT("INF_GetData() failed\n");
190 UserData
= (WCHAR
*) RtlAllocateHeap(ProcessHeap
,
192 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
193 if (UserData
== NULL
)
195 /* FIXME: Handle error! */
198 wcscpy(UserData
, KeyName
);
200 sprintf(Buffer
, "%S", KeyValue
);
201 AppendGenericListEntry(List
, Buffer
, UserData
,
202 _wcsicmp(KeyName
, ComputerKey
) ? FALSE
: TRUE
);
204 while (SetupFindNextLine(&Context
, &Context
));
211 GetDisplayIdentifier(PWSTR Identifier
,
212 ULONG IdentifierLength
)
214 OBJECT_ATTRIBUTES ObjectAttributes
;
215 UNICODE_STRING KeyName
;
218 HANDLE BusInstanceKey
;
219 HANDLE ControllerKey
;
220 HANDLE ControllerInstanceKey
;
222 ULONG ControllerInstance
;
224 ULONG ReturnedLength
;
225 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
;
228 DPRINT("GetDisplayIdentifier() called\n");
230 /* Open the bus key */
231 RtlInitUnicodeString(&KeyName
,
232 L
"\\Registry\\Machine\\HARDWARE\\Description\\System\\MultifunctionAdapter");
233 InitializeObjectAttributes(&ObjectAttributes
,
235 OBJ_CASE_INSENSITIVE
,
238 Status
= NtOpenKey(&BusKey
,
241 if (!NT_SUCCESS(Status
))
243 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
250 swprintf(Buffer
, L
"%lu", BusInstance
);
251 RtlInitUnicodeString(&KeyName
,
253 InitializeObjectAttributes(&ObjectAttributes
,
255 OBJ_CASE_INSENSITIVE
,
258 Status
= NtOpenKey(&BusInstanceKey
,
261 if (!NT_SUCCESS(Status
))
263 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
268 /* Open the controller type key */
269 RtlInitUnicodeString(&KeyName
,
270 L
"DisplayController");
271 InitializeObjectAttributes(&ObjectAttributes
,
273 OBJ_CASE_INSENSITIVE
,
276 Status
= NtOpenKey(&ControllerKey
,
279 if (NT_SUCCESS(Status
))
281 ControllerInstance
= 0;
284 /* Open the pointer controller instance key */
285 swprintf(Buffer
, L
"%lu", ControllerInstance
);
286 RtlInitUnicodeString(&KeyName
,
288 InitializeObjectAttributes(&ObjectAttributes
,
290 OBJ_CASE_INSENSITIVE
,
293 Status
= NtOpenKey(&ControllerInstanceKey
,
296 if (!NT_SUCCESS(Status
))
298 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
299 NtClose(ControllerKey
);
300 NtClose(BusInstanceKey
);
305 /* Get controller identifier */
306 RtlInitUnicodeString(&KeyName
,
309 BufferLength
= sizeof(KEY_VALUE_PARTIAL_INFORMATION
) +
311 ValueInfo
= (KEY_VALUE_PARTIAL_INFORMATION
*) RtlAllocateHeap(RtlGetProcessHeap(),
314 if (ValueInfo
== NULL
)
316 DPRINT("RtlAllocateHeap() failed\n");
317 NtClose(ControllerInstanceKey
);
318 NtClose(ControllerKey
);
319 NtClose(BusInstanceKey
);
324 Status
= NtQueryValueKey(ControllerInstanceKey
,
326 KeyValuePartialInformation
,
330 if (NT_SUCCESS(Status
))
332 DPRINT("Identifier: %S\n", (PWSTR
)ValueInfo
->Data
);
334 BufferLength
= min(ValueInfo
->DataLength
/ sizeof(WCHAR
), IdentifierLength
);
335 RtlCopyMemory (Identifier
,
337 BufferLength
* sizeof(WCHAR
));
338 Identifier
[BufferLength
] = 0;
340 RtlFreeHeap(RtlGetProcessHeap(),
343 NtClose(ControllerInstanceKey
);
344 NtClose(ControllerKey
);
345 NtClose(BusInstanceKey
);
350 NtClose(ControllerInstanceKey
);
352 ControllerInstance
++;
355 NtClose(ControllerKey
);
358 NtClose(BusInstanceKey
);
370 CreateDisplayDriverList(HINF InfFile
)
378 WCHAR DisplayIdentifier
[128];
379 WCHAR DisplayKey
[32];
381 /* Get the display identification */
382 if (!GetDisplayIdentifier(DisplayIdentifier
, 128))
384 DisplayIdentifier
[0] = 0;
387 DPRINT("Display identifier: '%S'\n", DisplayIdentifier
);
389 /* Search for matching device identifier */
390 if (!SetupFindFirstLineW(InfFile
, L
"Map.Display", NULL
, &Context
))
392 /* FIXME: error message */
398 if (!INF_GetDataField(&Context
, 1, &KeyValue
))
400 /* FIXME: Handle error! */
401 DPRINT("INF_GetDataField() failed\n");
405 DPRINT("KeyValue: %S\n", KeyValue
);
406 if (wcsstr(DisplayIdentifier
, KeyValue
))
408 if (!INF_GetDataField(&Context
, 0, &KeyName
))
410 /* FIXME: Handle error! */
411 DPRINT("INF_GetDataField() failed\n");
415 DPRINT("Display key: %S\n", KeyName
);
416 wcscpy(DisplayKey
, KeyName
);
419 while (SetupFindNextLine(&Context
, &Context
));
422 List
= CreateGenericList();
426 if (!SetupFindFirstLineW (InfFile
, L
"Display", NULL
, &Context
))
428 DestroyGenericList(List
, FALSE
);
434 if (!INF_GetDataField(&Context
, 0, &KeyName
))
436 DPRINT1("INF_GetDataField() failed\n");
440 if (!INF_GetDataField(&Context
, 1, &KeyValue
))
442 DPRINT1("INF_GetDataField() failed\n");
446 UserData
= (WCHAR
*) RtlAllocateHeap(ProcessHeap
,
448 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
449 if (UserData
== NULL
)
451 DPRINT1("RtlAllocateHeap() failed\n");
452 DestroyGenericList(List
, TRUE
);
456 wcscpy(UserData
, KeyName
);
458 sprintf(Buffer
, "%S", KeyValue
);
459 AppendGenericListEntry(List
,
462 _wcsicmp(KeyName
, DisplayKey
) ? FALSE
: TRUE
);
464 while (SetupFindNextLine(&Context
, &Context
));
467 AppendGenericListEntry(List
, "Other display driver", NULL
, TRUE
);
474 ProcessComputerFiles(HINF InfFile
, PGENERIC_LIST List
, PWCHAR
* AdditionalSectionName
)
476 PGENERIC_LIST_ENTRY Entry
;
477 static WCHAR SectionName
[128];
479 DPRINT("ProcessComputerFiles() called\n");
481 Entry
= GetGenericListEntry(List
);
484 DPRINT("GetGenericListEntry() failed\n");
488 wcscpy(SectionName
, L
"Files.");
489 wcscat(SectionName
, (const wchar_t*) Entry
->UserData
);
490 *AdditionalSectionName
= SectionName
;
497 ProcessDisplayRegistry(HINF InfFile
, PGENERIC_LIST List
)
499 PGENERIC_LIST_ENTRY Entry
;
506 ULONG Width
, Hight
, Bpp
;
508 DPRINT("ProcessDisplayRegistry() called\n");
510 Entry
= GetGenericListEntry(List
);
513 DPRINT("GetGenericListEntry() failed\n");
517 if (!SetupFindFirstLineW(InfFile
, L
"Display", (WCHAR
*) Entry
->UserData
, &Context
))
519 DPRINT("SetupFindFirstLineW() failed\n");
523 /* Enable the right driver */
524 if (!INF_GetDataField(&Context
, 3, &ServiceName
))
526 DPRINT("INF_GetDataField() failed\n");
530 ASSERT(wcslen(ServiceName
) < 10);
531 DPRINT("Service name: %S\n", ServiceName
);
534 Status
= RtlWriteRegistryValue(RTL_REGISTRY_SERVICES
,
541 if (!NT_SUCCESS(Status
))
543 DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
547 /* Set the resolution */
548 swprintf(RegPath
, L
"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Services\\%s\\Device0", ServiceName
);
550 if (!INF_GetDataField(&Context
, 4, &Buffer
))
552 DPRINT("INF_GetDataField() failed\n");
555 Width
= wcstoul(Buffer
, NULL
, 10);
556 Status
= RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE
,
558 L
"DefaultSettings.XResolution",
562 if (!NT_SUCCESS(Status
))
564 DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
569 if (!INF_GetDataField(&Context
, 5, &Buffer
))
571 DPRINT("INF_GetDataField() failed\n");
574 Hight
= wcstoul(Buffer
, 0, 0);
575 Status
= RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE
,
577 L
"DefaultSettings.YResolution",
581 if (!NT_SUCCESS(Status
))
583 DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
587 if (!INF_GetDataField(&Context
, 6, &Buffer
))
589 DPRINT("INF_GetDataField() failed\n");
592 Bpp
= wcstoul(Buffer
, 0, 0);
593 Status
= RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE
,
595 L
"DefaultSettings.BitsPerPel",
599 if (!NT_SUCCESS(Status
))
601 DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
605 DPRINT("ProcessDisplayRegistry() done\n");
612 CreateKeyboardDriverList(HINF InfFile
)
621 List
= CreateGenericList();
625 if (!SetupFindFirstLineW (InfFile
, L
"Keyboard", NULL
, &Context
))
627 DestroyGenericList(List
, FALSE
);
633 if (!INF_GetData (&Context
, &KeyName
, &KeyValue
))
635 /* FIXME: Handle error! */
636 DPRINT("INF_GetData() failed\n");
640 UserData
= (WCHAR
*) RtlAllocateHeap(ProcessHeap
,
642 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
643 if (UserData
== NULL
)
645 /* FIXME: Handle error! */
648 wcscpy(UserData
, KeyName
);
650 sprintf(Buffer
, "%S", KeyValue
);
651 AppendGenericListEntry(List
, Buffer
, UserData
, FALSE
);
653 while (SetupFindNextLine(&Context
, &Context
));
659 CreateLanguageList(HINF InfFile
, WCHAR
* DefaultLanguage
)
668 /* Get default language id */
669 if (!SetupFindFirstLineW (InfFile
, L
"NLS", L
"DefaultLanguage", &Context
))
672 if (!INF_GetData (&Context
, NULL
, &KeyValue
))
675 wcscpy(DefaultLanguage
, KeyValue
);
677 SelectedLanguageId
= KeyValue
;
679 List
= CreateGenericList();
683 if (!SetupFindFirstLineW (InfFile
, L
"Language", NULL
, &Context
))
685 DestroyGenericList(List
, FALSE
);
691 if (!INF_GetData (&Context
, &KeyName
, &KeyValue
))
693 /* FIXME: Handle error! */
694 DPRINT("INF_GetData() failed\n");
698 UserData
= (WCHAR
*) RtlAllocateHeap(ProcessHeap
,
700 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
701 if (UserData
== NULL
)
703 /* FIXME: Handle error! */
706 wcscpy(UserData
, KeyName
);
708 sprintf(Buffer
, "%S", KeyValue
);
709 AppendGenericListEntry(List
,
712 _wcsicmp(KeyName
, DefaultLanguage
) ? FALSE
: TRUE
);
714 while (SetupFindNextLine(&Context
, &Context
));
720 CreateKeyboardLayoutList(HINF InfFile
, WCHAR
* DefaultKBLayout
)
729 /* Get default layout id */
730 if (!SetupFindFirstLineW (InfFile
, L
"NLS", L
"DefaultLayout", &Context
))
733 if (!INF_GetData (&Context
, NULL
, &KeyValue
))
736 wcscpy(DefaultKBLayout
, KeyValue
);
738 List
= CreateGenericList();
742 if (!SetupFindFirstLineW (InfFile
, L
"KeyboardLayout", NULL
, &Context
))
744 DestroyGenericList(List
, FALSE
);
750 if (!INF_GetData (&Context
, &KeyName
, &KeyValue
))
752 /* FIXME: Handle error! */
753 DPRINT("INF_GetData() failed\n");
754 DestroyGenericList(List
, FALSE
);
758 UserData
= (WCHAR
*) RtlAllocateHeap(ProcessHeap
,
760 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
761 if (UserData
== NULL
)
763 /* FIXME: Handle error! */
766 wcscpy(UserData
, KeyName
);
768 sprintf(Buffer
, "%S", KeyValue
);
769 AppendGenericListEntry(List
,
772 _wcsicmp(KeyName
, DefaultKBLayout
) ? FALSE
: TRUE
);
774 while (SetupFindNextLine(&Context
, &Context
));
781 ProcessKeyboardLayoutRegistry(PGENERIC_LIST List
)
783 PGENERIC_LIST_ENTRY Entry
;
785 OBJECT_ATTRIBUTES ObjectAttributes
;
786 UNICODE_STRING KeyName
;
787 UNICODE_STRING ValueName
;
791 Entry
= GetGenericListEntry(List
);
795 LanguageId
= (PWCHAR
)Entry
->UserData
;
796 if (LanguageId
== NULL
)
799 /* Open the nls language key */
800 RtlInitUnicodeString(&KeyName
,
801 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language");
802 InitializeObjectAttributes(&ObjectAttributes
,
804 OBJ_CASE_INSENSITIVE
,
807 Status
= NtOpenKey(&KeyHandle
,
810 if (!NT_SUCCESS(Status
))
812 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status
);
816 /* Set default language */
817 RtlInitUnicodeString(&ValueName
,
819 Status
= NtSetValueKey (KeyHandle
,
823 (PVOID
)(LanguageId
+ 4),
825 if (!NT_SUCCESS(Status
))
827 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
832 /* Set install language */
833 RtlInitUnicodeString(&ValueName
,
835 Status
= NtSetValueKey (KeyHandle
,
839 (PVOID
)(LanguageId
+ 4),
841 if (!NT_SUCCESS(Status
))
843 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
856 ProcessKeyboardLayoutFiles(PGENERIC_LIST List
)