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
;
509 DPRINT("ProcessDisplayRegistry() called\n");
511 Entry
= GetGenericListEntry(List
);
514 DPRINT("GetGenericListEntry() failed\n");
518 if (!InfFindFirstLine(InfFile
, L
"Display", Entry
->UserData
, &Context
))
520 DPRINT("InfFindFirstLine() failed\n");
524 /* Enable the right driver */
525 if (!InfGetDataField(Context
, 3, &ServiceName
))
527 DPRINT("InfGetDataField() failed\n");
531 ASSERT(wcslen(ServiceName
) < 10);
532 DPRINT("Service name: %S\n", ServiceName
);
535 Status
= RtlWriteRegistryValue(RTL_REGISTRY_SERVICES
,
542 if (!NT_SUCCESS(Status
))
544 DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
548 /* Set the resolution */
550 swprintf(RegPath
, L
"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Services\\%s\\Device0", ServiceName
);
553 if (!InfGetDataField(Context
, 4, &Buffer
))
555 DPRINT("InfGetDataField() failed\n");
558 ULONG Width
= wcstoul(Buffer
, NULL
, 10);
559 Status
= RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE
,
561 L
"DefaultSettings.XResolution",
565 if (!NT_SUCCESS(Status
))
567 DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
572 if (!InfGetDataField(Context
, 5, &Buffer
))
574 DPRINT("InfGetDataField() failed\n");
577 ULONG Hight
= wcstoul(Buffer
, 0, 0);
578 Status
= RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE
,
580 L
"DefaultSettings.YResolution",
584 if (!NT_SUCCESS(Status
))
586 DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
590 if (!InfGetDataField(Context
, 6, &Buffer
))
592 DPRINT("InfGetDataField() failed\n");
595 ULONG Bpp
= wcstoul(Buffer
, 0, 0);
596 Status
= RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE
,
598 L
"DefaultSettings.BitsPerPel",
602 if (!NT_SUCCESS(Status
))
604 DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
608 InfFreeContext(Context
);
610 DPRINT("ProcessDisplayRegistry() done\n");
617 CreateKeyboardDriverList(HINF InfFile
)
626 List
= CreateGenericList();
630 if (!InfFindFirstLine (InfFile
, L
"Keyboard", NULL
, &Context
))
632 DestroyGenericList(List
, FALSE
);
638 if (!InfGetData (Context
, &KeyName
, &KeyValue
))
640 /* FIXME: Handle error! */
641 DPRINT("InfGetData() failed\n");
645 UserData
= RtlAllocateHeap(ProcessHeap
,
647 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
648 if (UserData
== NULL
)
650 /* FIXME: Handle error! */
653 wcscpy(UserData
, KeyName
);
655 sprintf(Buffer
, "%S", KeyValue
);
656 AppendGenericListEntry(List
, Buffer
, UserData
, FALSE
);
658 while (InfFindNextLine(Context
, Context
));
659 InfFreeContext(Context
);
666 CreateKeyboardLayoutList(HINF InfFile
)
674 WCHAR DefaultLayout
[20];
676 /* Get default layout id */
677 if (!InfFindFirstLine (InfFile
, L
"NLS", L
"DefaultLayout", &Context
))
680 if (!InfGetData (Context
, NULL
, &KeyValue
))
682 InfFreeContext(Context
);
686 wcscpy(DefaultLayout
, KeyValue
);
687 InfFreeContext(Context
);
689 List
= CreateGenericList();
693 if (!InfFindFirstLine (InfFile
, L
"KeyboardLayout", NULL
, &Context
))
695 DestroyGenericList(List
, FALSE
);
696 InfFreeContext(Context
);
702 if (!InfGetData (Context
, &KeyName
, &KeyValue
))
704 /* FIXME: Handle error! */
705 DPRINT("InfGetData() failed\n");
709 UserData
= RtlAllocateHeap(ProcessHeap
,
711 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
712 if (UserData
== NULL
)
714 /* FIXME: Handle error! */
717 wcscpy(UserData
, KeyName
);
719 sprintf(Buffer
, "%S", KeyValue
);
720 AppendGenericListEntry(List
,
723 _wcsicmp(KeyName
, DefaultLayout
) ? FALSE
: TRUE
);
725 while (InfFindNextLine(Context
, Context
));
726 InfFreeContext(Context
);
733 ProcessKeyboardLayoutRegistry(PGENERIC_LIST List
)
735 PGENERIC_LIST_ENTRY Entry
;
737 OBJECT_ATTRIBUTES ObjectAttributes
;
738 UNICODE_STRING KeyName
;
739 UNICODE_STRING ValueName
;
743 Entry
= GetGenericListEntry(List
);
747 LanguageId
= (PWCHAR
)Entry
->UserData
;
748 if (LanguageId
== NULL
)
751 /* Open the nls language key */
752 RtlInitUnicodeString(&KeyName
,
753 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language");
754 InitializeObjectAttributes(&ObjectAttributes
,
756 OBJ_CASE_INSENSITIVE
,
759 Status
= NtOpenKey(&KeyHandle
,
762 if (!NT_SUCCESS(Status
))
764 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status
);
768 /* Set default language */
769 RtlInitUnicodeString(&ValueName
,
771 Status
= NtSetValueKey (KeyHandle
,
775 (PVOID
)(LanguageId
+ 4),
777 if (!NT_SUCCESS(Status
))
779 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
784 /* Set install language */
785 RtlInitUnicodeString(&ValueName
,
787 Status
= NtSetValueKey (KeyHandle
,
791 (PVOID
)(LanguageId
+ 4),
793 if (!NT_SUCCESS(Status
))
795 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
808 ProcessKeyboardLayoutFiles(PGENERIC_LIST List
)