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 if (!InfGetDataField(Context
, 3, &ServiceName
))
526 DPRINT("InfGetDataField() failed\n");
530 DPRINT("Service name: %S\n", ServiceName
);
533 Status
= RtlWriteRegistryValue(RTL_REGISTRY_SERVICES
,
539 InfFreeContext(Context
);
540 if (!NT_SUCCESS(Status
))
542 DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
546 DPRINT("ProcessDisplayRegistry() done\n");
553 CreateKeyboardDriverList(HINF InfFile
)
562 List
= CreateGenericList();
566 if (!InfFindFirstLine (InfFile
, L
"Keyboard", NULL
, &Context
))
568 DestroyGenericList(List
, FALSE
);
574 if (!InfGetData (Context
, &KeyName
, &KeyValue
))
576 /* FIXME: Handle error! */
577 DPRINT("InfGetData() failed\n");
581 UserData
= RtlAllocateHeap(ProcessHeap
,
583 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
584 if (UserData
== NULL
)
586 /* FIXME: Handle error! */
589 wcscpy(UserData
, KeyName
);
591 sprintf(Buffer
, "%S", KeyValue
);
592 AppendGenericListEntry(List
, Buffer
, UserData
, FALSE
);
594 while (InfFindNextLine(Context
, Context
));
595 InfFreeContext(Context
);
602 CreateKeyboardLayoutList(HINF InfFile
)
610 WCHAR DefaultLayout
[20];
612 /* Get default layout id */
613 if (!InfFindFirstLine (InfFile
, L
"NLS", L
"DefaultLayout", &Context
))
616 if (!InfGetData (Context
, NULL
, &KeyValue
))
618 InfFreeContext(Context
);
622 wcscpy(DefaultLayout
, KeyValue
);
623 InfFreeContext(Context
);
625 List
= CreateGenericList();
629 if (!InfFindFirstLine (InfFile
, L
"KeyboardLayout", NULL
, &Context
))
631 DestroyGenericList(List
, FALSE
);
632 InfFreeContext(Context
);
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
,
659 _wcsicmp(KeyName
, DefaultLayout
) ? FALSE
: TRUE
);
661 while (InfFindNextLine(Context
, Context
));
662 InfFreeContext(Context
);
669 ProcessKeyboardLayoutRegistry(PGENERIC_LIST List
)
671 PGENERIC_LIST_ENTRY Entry
;
673 OBJECT_ATTRIBUTES ObjectAttributes
;
674 UNICODE_STRING KeyName
;
675 UNICODE_STRING ValueName
;
679 Entry
= GetGenericListEntry(List
);
683 LanguageId
= (PWCHAR
)Entry
->UserData
;
684 if (LanguageId
== NULL
)
687 /* Open the nls language key */
688 RtlInitUnicodeString(&KeyName
,
689 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language");
690 InitializeObjectAttributes(&ObjectAttributes
,
692 OBJ_CASE_INSENSITIVE
,
695 Status
= NtOpenKey(&KeyHandle
,
698 if (!NT_SUCCESS(Status
))
700 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status
);
704 /* Set default language */
705 RtlInitUnicodeString(&ValueName
,
707 Status
= NtSetValueKey (KeyHandle
,
711 (PVOID
)(LanguageId
+ 4),
713 if (!NT_SUCCESS(Status
))
715 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
720 /* Set install language */
721 RtlInitUnicodeString(&ValueName
,
723 Status
= NtSetValueKey (KeyHandle
,
727 (PVOID
)(LanguageId
+ 4),
729 if (!NT_SUCCESS(Status
))
731 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
744 ProcessKeyboardLayoutFiles(PGENERIC_LIST List
)