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
));
171 List
= CreateGenericList();
175 if (!InfFindFirstLine (InfFile
, L
"Computer", NULL
, &Context
))
177 DestroyGenericList(List
, FALSE
);
183 if (!InfGetData (&Context
, &KeyName
, &KeyValue
))
185 /* FIXME: Handle error! */
186 DPRINT("InfGetData() failed\n");
190 UserData
= 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 (InfFindNextLine(&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
= 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 (!InfFindFirstLine(InfFile
, L
"Map.Display", NULL
, &Context
))
392 /* FIXME: error message */
398 if (!InfGetDataField(&Context
, 1, &KeyValue
))
400 /* FIXME: Handle error! */
401 DPRINT("InfGetDataField() failed\n");
405 DPRINT("KeyValue: %S\n", KeyValue
);
406 if (wcsstr(DisplayIdentifier
, KeyValue
))
408 if (!InfGetDataField(&Context
, 0, &KeyName
))
410 /* FIXME: Handle error! */
411 DPRINT("InfGetDataField() failed\n");
415 DPRINT("Display key: %S\n", KeyName
);
416 wcscpy(DisplayKey
, KeyName
);
419 while (InfFindNextLine(&Context
, &Context
));
422 List
= CreateGenericList();
426 if (!InfFindFirstLine (InfFile
, L
"Display", NULL
, &Context
))
428 DestroyGenericList(List
, FALSE
);
434 if (!InfGetDataField(&Context
, 0, &KeyName
))
436 DPRINT1("InfGetDataField() failed\n");
440 if (!InfGetDataField(&Context
, 1, &KeyValue
))
442 DPRINT1("InfGetDataField() failed\n");
446 UserData
= 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 (InfFindNextLine(&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
, Entry
->UserData
);
490 *AdditionalSectionName
= SectionName
;
497 ProcessDisplayRegistry(HINF InfFile
, PGENERIC_LIST List
)
499 PGENERIC_LIST_ENTRY Entry
;
505 DPRINT("ProcessDisplayRegistry() called\n");
507 Entry
= GetGenericListEntry(List
);
510 DPRINT("GetGenericListEntry() failed\n");
514 if (!InfFindFirstLine(InfFile
, L
"Display", Entry
->UserData
, &Context
))
516 DPRINT("InfFindFirstLine() failed\n");
520 if (!InfGetDataField(&Context
, 3, &ServiceName
))
522 DPRINT("InfGetDataField() failed\n");
526 DPRINT("Service name: %S\n", ServiceName
);
529 Status
= RtlWriteRegistryValue(RTL_REGISTRY_SERVICES
,
535 if (!NT_SUCCESS(Status
))
537 DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
541 DPRINT("ProcessDisplayRegistry() done\n");
548 CreateKeyboardDriverList(HINF InfFile
)
557 List
= CreateGenericList();
561 if (!InfFindFirstLine (InfFile
, L
"Keyboard", NULL
, &Context
))
563 DestroyGenericList(List
, FALSE
);
569 if (!InfGetData (&Context
, &KeyName
, &KeyValue
))
571 /* FIXME: Handle error! */
572 DPRINT("InfGetData() failed\n");
576 UserData
= RtlAllocateHeap(ProcessHeap
,
578 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
579 if (UserData
== NULL
)
581 /* FIXME: Handle error! */
584 wcscpy(UserData
, KeyName
);
586 sprintf(Buffer
, "%S", KeyValue
);
587 AppendGenericListEntry(List
, Buffer
, UserData
, FALSE
);
589 while (InfFindNextLine(&Context
, &Context
));
596 CreateKeyboardLayoutList(HINF InfFile
)
604 WCHAR DefaultLayout
[20];
606 /* Get default layout id */
607 if (!InfFindFirstLine (InfFile
, L
"NLS", L
"DefaultLayout", &Context
))
610 if (!InfGetData (&Context
, NULL
, &KeyValue
))
613 wcscpy(DefaultLayout
, KeyValue
);
615 List
= CreateGenericList();
619 if (!InfFindFirstLine (InfFile
, L
"KeyboardLayout", NULL
, &Context
))
621 DestroyGenericList(List
, FALSE
);
627 if (!InfGetData (&Context
, &KeyName
, &KeyValue
))
629 /* FIXME: Handle error! */
630 DPRINT("InfGetData() failed\n");
634 UserData
= RtlAllocateHeap(ProcessHeap
,
636 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
637 if (UserData
== NULL
)
639 /* FIXME: Handle error! */
642 wcscpy(UserData
, KeyName
);
644 sprintf(Buffer
, "%S", KeyValue
);
645 AppendGenericListEntry(List
,
648 _wcsicmp(KeyName
, DefaultLayout
) ? FALSE
: TRUE
);
650 while (InfFindNextLine(&Context
, &Context
));
657 ProcessKeyboardLayoutRegistry(PGENERIC_LIST List
)
659 PGENERIC_LIST_ENTRY Entry
;
661 OBJECT_ATTRIBUTES ObjectAttributes
;
662 UNICODE_STRING KeyName
;
663 UNICODE_STRING ValueName
;
667 Entry
= GetGenericListEntry(List
);
671 LanguageId
= (PWCHAR
)Entry
->UserData
;
672 if (LanguageId
== NULL
)
675 /* Open the nls language key */
676 RtlInitUnicodeString(&KeyName
,
677 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language");
678 InitializeObjectAttributes(&ObjectAttributes
,
680 OBJ_CASE_INSENSITIVE
,
683 Status
= NtOpenKey(&KeyHandle
,
686 if (!NT_SUCCESS(Status
))
688 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status
);
692 /* Set default language */
693 RtlInitUnicodeString(&ValueName
,
695 Status
= NtSetValueKey (KeyHandle
,
699 (PVOID
)(LanguageId
+ 4),
701 if (!NT_SUCCESS(Status
))
703 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
708 /* Set install language */
709 RtlInitUnicodeString(&ValueName
,
711 Status
= NtSetValueKey (KeyHandle
,
715 (PVOID
)(LanguageId
+ 4),
717 if (!NT_SUCCESS(Status
))
719 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
732 ProcessKeyboardLayoutFiles(PGENERIC_LIST List
)