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 (!InfFindFirstLine(InfFile
, L
"Map.Computer", NULL
, &Context
))
142 /* FIXME: error message */
148 if (!InfGetDataField(Context
, 1, &KeyValue
))
150 /* FIXME: Handle error! */
151 DPRINT("InfGetDataField() failed\n");
155 DPRINT("KeyValue: %S\n", KeyValue
);
156 if (wcsstr(ComputerIdentifier
, KeyValue
))
158 if (!InfGetDataField(Context
, 0, &KeyName
))
160 /* FIXME: Handle error! */
161 DPRINT("InfGetDataField() failed\n");
165 DPRINT("Computer key: %S\n", KeyName
);
166 wcscpy(ComputerKey
, KeyName
);
169 while (InfFindNextLine(Context
, Context
));
170 InfFreeContext(Context
);
172 List
= CreateGenericList();
176 if (!InfFindFirstLine (InfFile
, L
"Computer", NULL
, &Context
))
178 DestroyGenericList(List
, FALSE
);
184 if (!InfGetData (Context
, &KeyName
, &KeyValue
))
186 /* FIXME: Handle error! */
187 DPRINT("InfGetData() failed\n");
191 UserData
= RtlAllocateHeap(ProcessHeap
,
193 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
194 if (UserData
== NULL
)
196 /* FIXME: Handle error! */
199 wcscpy(UserData
, KeyName
);
201 sprintf(Buffer
, "%S", KeyValue
);
202 AppendGenericListEntry(List
, Buffer
, UserData
,
203 _wcsicmp(KeyName
, ComputerKey
) ? FALSE
: TRUE
);
205 while (InfFindNextLine(Context
, Context
));
206 InfFreeContext(Context
);
213 GetDisplayIdentifier(PWSTR Identifier
,
214 ULONG IdentifierLength
)
216 OBJECT_ATTRIBUTES ObjectAttributes
;
217 UNICODE_STRING KeyName
;
220 HANDLE BusInstanceKey
;
221 HANDLE ControllerKey
;
222 HANDLE ControllerInstanceKey
;
224 ULONG ControllerInstance
;
226 ULONG ReturnedLength
;
227 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
;
230 DPRINT("GetDisplayIdentifier() called\n");
232 /* Open the bus key */
233 RtlInitUnicodeString(&KeyName
,
234 L
"\\Registry\\Machine\\HARDWARE\\Description\\System\\MultifunctionAdapter");
235 InitializeObjectAttributes(&ObjectAttributes
,
237 OBJ_CASE_INSENSITIVE
,
240 Status
= NtOpenKey(&BusKey
,
243 if (!NT_SUCCESS(Status
))
245 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
252 swprintf(Buffer
, L
"%lu", BusInstance
);
253 RtlInitUnicodeString(&KeyName
,
255 InitializeObjectAttributes(&ObjectAttributes
,
257 OBJ_CASE_INSENSITIVE
,
260 Status
= NtOpenKey(&BusInstanceKey
,
263 if (!NT_SUCCESS(Status
))
265 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
270 /* Open the controller type key */
271 RtlInitUnicodeString(&KeyName
,
272 L
"DisplayController");
273 InitializeObjectAttributes(&ObjectAttributes
,
275 OBJ_CASE_INSENSITIVE
,
278 Status
= NtOpenKey(&ControllerKey
,
281 if (NT_SUCCESS(Status
))
283 ControllerInstance
= 0;
286 /* Open the pointer controller instance key */
287 swprintf(Buffer
, L
"%lu", ControllerInstance
);
288 RtlInitUnicodeString(&KeyName
,
290 InitializeObjectAttributes(&ObjectAttributes
,
292 OBJ_CASE_INSENSITIVE
,
295 Status
= NtOpenKey(&ControllerInstanceKey
,
298 if (!NT_SUCCESS(Status
))
300 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
301 NtClose(ControllerKey
);
302 NtClose(BusInstanceKey
);
307 /* Get controller identifier */
308 RtlInitUnicodeString(&KeyName
,
311 BufferLength
= sizeof(KEY_VALUE_PARTIAL_INFORMATION
) +
313 ValueInfo
= RtlAllocateHeap(RtlGetProcessHeap(),
316 if (ValueInfo
== NULL
)
318 DPRINT("RtlAllocateHeap() failed\n");
319 NtClose(ControllerInstanceKey
);
320 NtClose(ControllerKey
);
321 NtClose(BusInstanceKey
);
326 Status
= NtQueryValueKey(ControllerInstanceKey
,
328 KeyValuePartialInformation
,
332 if (NT_SUCCESS(Status
))
334 DPRINT("Identifier: %S\n", (PWSTR
)ValueInfo
->Data
);
336 BufferLength
= min(ValueInfo
->DataLength
/ sizeof(WCHAR
), IdentifierLength
);
337 RtlCopyMemory (Identifier
,
339 BufferLength
* sizeof(WCHAR
));
340 Identifier
[BufferLength
] = 0;
342 RtlFreeHeap(RtlGetProcessHeap(),
345 NtClose(ControllerInstanceKey
);
346 NtClose(ControllerKey
);
347 NtClose(BusInstanceKey
);
352 NtClose(ControllerInstanceKey
);
354 ControllerInstance
++;
357 NtClose(ControllerKey
);
360 NtClose(BusInstanceKey
);
372 CreateDisplayDriverList(HINF InfFile
)
380 WCHAR DisplayIdentifier
[128];
381 WCHAR DisplayKey
[32];
383 /* Get the display identification */
384 if (!GetDisplayIdentifier(DisplayIdentifier
, 128))
386 DisplayIdentifier
[0] = 0;
389 DPRINT("Display identifier: '%S'\n", DisplayIdentifier
);
391 /* Search for matching device identifier */
392 if (!InfFindFirstLine(InfFile
, L
"Map.Display", NULL
, &Context
))
394 /* FIXME: error message */
400 if (!InfGetDataField(Context
, 1, &KeyValue
))
402 /* FIXME: Handle error! */
403 DPRINT("InfGetDataField() failed\n");
407 DPRINT("KeyValue: %S\n", KeyValue
);
408 if (wcsstr(DisplayIdentifier
, KeyValue
))
410 if (!InfGetDataField(Context
, 0, &KeyName
))
412 /* FIXME: Handle error! */
413 DPRINT("InfGetDataField() failed\n");
417 DPRINT("Display key: %S\n", KeyName
);
418 wcscpy(DisplayKey
, KeyName
);
421 while (InfFindNextLine(Context
, Context
));
422 InfFreeContext(Context
);
425 List
= CreateGenericList();
429 if (!InfFindFirstLine (InfFile
, L
"Display", NULL
, &Context
))
431 DestroyGenericList(List
, FALSE
);
437 if (!InfGetDataField(Context
, 0, &KeyName
))
439 DPRINT1("InfGetDataField() failed\n");
443 if (!InfGetDataField(Context
, 1, &KeyValue
))
445 DPRINT1("InfGetDataField() failed\n");
449 UserData
= RtlAllocateHeap(ProcessHeap
,
451 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
452 if (UserData
== NULL
)
454 DPRINT1("RtlAllocateHeap() failed\n");
455 DestroyGenericList(List
, TRUE
);
459 wcscpy(UserData
, KeyName
);
461 sprintf(Buffer
, "%S", KeyValue
);
462 AppendGenericListEntry(List
,
465 _wcsicmp(KeyName
, DisplayKey
) ? FALSE
: TRUE
);
467 while (InfFindNextLine(Context
, Context
));
468 InfFreeContext(Context
);
471 AppendGenericListEntry(List
, "Other display driver", NULL
, TRUE
);
478 ProcessComputerFiles(HINF InfFile
, PGENERIC_LIST List
, PWCHAR
* AdditionalSectionName
)
480 PGENERIC_LIST_ENTRY Entry
;
481 static WCHAR SectionName
[128];
483 DPRINT("ProcessComputerFiles() called\n");
485 Entry
= GetGenericListEntry(List
);
488 DPRINT("GetGenericListEntry() failed\n");
492 wcscpy(SectionName
, L
"Files.");
493 wcscat(SectionName
, Entry
->UserData
);
494 *AdditionalSectionName
= SectionName
;
501 ProcessDisplayRegistry(HINF InfFile
, PGENERIC_LIST List
)
503 PGENERIC_LIST_ENTRY Entry
;
510 ULONG Width
, Hight
, Bpp
;
512 DPRINT("ProcessDisplayRegistry() called\n");
514 Entry
= GetGenericListEntry(List
);
517 DPRINT("GetGenericListEntry() failed\n");
521 if (!InfFindFirstLine(InfFile
, L
"Display", Entry
->UserData
, &Context
))
523 DPRINT("InfFindFirstLine() failed\n");
527 /* Enable the right driver */
528 if (!InfGetDataField(Context
, 3, &ServiceName
))
530 DPRINT("InfGetDataField() failed\n");
534 ASSERT(wcslen(ServiceName
) < 10);
535 DPRINT("Service name: %S\n", ServiceName
);
538 Status
= RtlWriteRegistryValue(RTL_REGISTRY_SERVICES
,
545 if (!NT_SUCCESS(Status
))
547 DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
551 /* Set the resolution */
552 swprintf(RegPath
, L
"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Services\\%s\\Device0", ServiceName
);
554 if (!InfGetDataField(Context
, 4, &Buffer
))
556 DPRINT("InfGetDataField() failed\n");
559 Width
= wcstoul(Buffer
, NULL
, 10);
560 Status
= RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE
,
562 L
"DefaultSettings.XResolution",
566 if (!NT_SUCCESS(Status
))
568 DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
573 if (!InfGetDataField(Context
, 5, &Buffer
))
575 DPRINT("InfGetDataField() failed\n");
578 Hight
= wcstoul(Buffer
, 0, 0);
579 Status
= RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE
,
581 L
"DefaultSettings.YResolution",
585 if (!NT_SUCCESS(Status
))
587 DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
591 if (!InfGetDataField(Context
, 6, &Buffer
))
593 DPRINT("InfGetDataField() failed\n");
596 Bpp
= wcstoul(Buffer
, 0, 0);
597 Status
= RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE
,
599 L
"DefaultSettings.BitsPerPel",
603 if (!NT_SUCCESS(Status
))
605 DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
609 InfFreeContext(Context
);
611 DPRINT("ProcessDisplayRegistry() done\n");
618 CreateKeyboardDriverList(HINF InfFile
)
627 List
= CreateGenericList();
631 if (!InfFindFirstLine (InfFile
, L
"Keyboard", NULL
, &Context
))
633 DestroyGenericList(List
, FALSE
);
639 if (!InfGetData (Context
, &KeyName
, &KeyValue
))
641 /* FIXME: Handle error! */
642 DPRINT("InfGetData() failed\n");
646 UserData
= RtlAllocateHeap(ProcessHeap
,
648 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
649 if (UserData
== NULL
)
651 /* FIXME: Handle error! */
654 wcscpy(UserData
, KeyName
);
656 sprintf(Buffer
, "%S", KeyValue
);
657 AppendGenericListEntry(List
, Buffer
, UserData
, FALSE
);
659 while (InfFindNextLine(Context
, Context
));
660 InfFreeContext(Context
);
667 CreateKeyboardLayoutList(HINF InfFile
)
675 WCHAR DefaultLayout
[20];
677 /* Get default layout id */
678 if (!InfFindFirstLine (InfFile
, L
"NLS", L
"DefaultLayout", &Context
))
681 if (!InfGetData (Context
, NULL
, &KeyValue
))
683 InfFreeContext(Context
);
687 wcscpy(DefaultLayout
, KeyValue
);
688 InfFreeContext(Context
);
690 List
= CreateGenericList();
694 if (!InfFindFirstLine (InfFile
, L
"KeyboardLayout", NULL
, &Context
))
696 DestroyGenericList(List
, FALSE
);
697 InfFreeContext(Context
);
703 if (!InfGetData (Context
, &KeyName
, &KeyValue
))
705 /* FIXME: Handle error! */
706 DPRINT("InfGetData() failed\n");
710 UserData
= RtlAllocateHeap(ProcessHeap
,
712 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
713 if (UserData
== NULL
)
715 /* FIXME: Handle error! */
718 wcscpy(UserData
, KeyName
);
720 sprintf(Buffer
, "%S", KeyValue
);
721 AppendGenericListEntry(List
,
724 _wcsicmp(KeyName
, DefaultLayout
) ? FALSE
: TRUE
);
726 while (InfFindNextLine(Context
, Context
));
727 InfFreeContext(Context
);
734 ProcessKeyboardLayoutRegistry(PGENERIC_LIST List
)
736 PGENERIC_LIST_ENTRY Entry
;
738 OBJECT_ATTRIBUTES ObjectAttributes
;
739 UNICODE_STRING KeyName
;
740 UNICODE_STRING ValueName
;
744 Entry
= GetGenericListEntry(List
);
748 LanguageId
= (PWCHAR
)Entry
->UserData
;
749 if (LanguageId
== NULL
)
752 /* Open the nls language key */
753 RtlInitUnicodeString(&KeyName
,
754 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language");
755 InitializeObjectAttributes(&ObjectAttributes
,
757 OBJ_CASE_INSENSITIVE
,
760 Status
= NtOpenKey(&KeyHandle
,
763 if (!NT_SUCCESS(Status
))
765 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status
);
769 /* Set default language */
770 RtlInitUnicodeString(&ValueName
,
772 Status
= NtSetValueKey (KeyHandle
,
776 (PVOID
)(LanguageId
+ 4),
778 if (!NT_SUCCESS(Status
))
780 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
785 /* Set install language */
786 RtlInitUnicodeString(&ValueName
,
788 Status
= NtSetValueKey (KeyHandle
,
792 (PVOID
)(LanguageId
+ 4),
794 if (!NT_SUCCESS(Status
))
796 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
809 ProcessKeyboardLayoutFiles(PGENERIC_LIST List
)