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 along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 /* COPYRIGHT: See COPYING in the top level directory
20 * PROJECT: ReactOS text-mode setup
21 * FILE: base/setup/usetup/settings.c
22 * PURPOSE: Device settings support functions
23 * PROGRAMMERS: Colin Finck
26 /* INCLUDES *****************************************************************/
33 /* GLOBALS ******************************************************************/
35 ULONG DefaultLanguageIndex
= 0;
37 /* FUNCTIONS ****************************************************************/
43 UNICODE_STRING MultiKeyPathU
= RTL_CONSTANT_STRING(L
"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter");
44 UNICODE_STRING IdentifierU
= RTL_CONSTANT_STRING(L
"Identifier");
45 UNICODE_STRING AcpiBiosIdentifier
= RTL_CONSTANT_STRING(L
"ACPI BIOS");
46 OBJECT_ATTRIBUTES ObjectAttributes
;
47 PKEY_BASIC_INFORMATION pDeviceInformation
= NULL
;
48 ULONG DeviceInfoLength
= sizeof(KEY_BASIC_INFORMATION
) + 50 * sizeof(WCHAR
);
49 PKEY_VALUE_PARTIAL_INFORMATION pValueInformation
= NULL
;
50 ULONG ValueInfoLength
= sizeof(KEY_VALUE_PARTIAL_INFORMATION
) + 50 * sizeof(WCHAR
);
52 ULONG IndexDevice
= 0;
53 UNICODE_STRING DeviceName
, ValueName
;
54 HANDLE hDevicesKey
= NULL
;
55 HANDLE hDeviceKey
= NULL
;
59 InitializeObjectAttributes(&ObjectAttributes
,
64 Status
= NtOpenKey(&hDevicesKey
,
65 KEY_ENUMERATE_SUB_KEYS
,
67 if (!NT_SUCCESS(Status
))
69 DPRINT("NtOpenKey() failed with status 0x%08lx\n", Status
);
73 pDeviceInformation
= RtlAllocateHeap(RtlGetProcessHeap(), 0, DeviceInfoLength
);
74 if (!pDeviceInformation
)
76 DPRINT("RtlAllocateHeap() failed\n");
77 Status
= STATUS_NO_MEMORY
;
81 pValueInformation
= RtlAllocateHeap(RtlGetProcessHeap(), 0, ValueInfoLength
);
82 if (!pValueInformation
)
84 DPRINT("RtlAllocateHeap() failed\n");
85 Status
= STATUS_NO_MEMORY
;
91 Status
= NtEnumerateKey(hDevicesKey
, IndexDevice
, KeyBasicInformation
, pDeviceInformation
, DeviceInfoLength
, &RequiredSize
);
92 if (Status
== STATUS_NO_MORE_ENTRIES
)
94 else if (Status
== STATUS_BUFFER_OVERFLOW
|| Status
== STATUS_BUFFER_TOO_SMALL
)
96 RtlFreeHeap(RtlGetProcessHeap(), 0, pDeviceInformation
);
97 DeviceInfoLength
= RequiredSize
;
98 pDeviceInformation
= RtlAllocateHeap(RtlGetProcessHeap(), 0, DeviceInfoLength
);
99 if (!pDeviceInformation
)
101 DPRINT("RtlAllocateHeap() failed\n");
102 Status
= STATUS_NO_MEMORY
;
105 Status
= NtEnumerateKey(hDevicesKey
, IndexDevice
, KeyBasicInformation
, pDeviceInformation
, DeviceInfoLength
, &RequiredSize
);
107 if (!NT_SUCCESS(Status
))
109 DPRINT("NtEnumerateKey() failed with status 0x%08lx\n", Status
);
114 /* Open device key */
115 DeviceName
.Length
= DeviceName
.MaximumLength
= pDeviceInformation
->NameLength
;
116 DeviceName
.Buffer
= pDeviceInformation
->Name
;
117 InitializeObjectAttributes(&ObjectAttributes
, &DeviceName
, OBJ_CASE_INSENSITIVE
, hDevicesKey
, NULL
);
122 if (!NT_SUCCESS(Status
))
124 DPRINT("NtOpenKey() failed with status 0x%08lx\n", Status
);
128 /* Read identifier */
129 Status
= NtQueryValueKey(hDeviceKey
, &IdentifierU
, KeyValuePartialInformation
, pValueInformation
, ValueInfoLength
, &RequiredSize
);
130 if (Status
== STATUS_BUFFER_OVERFLOW
|| Status
== STATUS_BUFFER_TOO_SMALL
)
132 RtlFreeHeap(RtlGetProcessHeap(), 0, pValueInformation
);
133 ValueInfoLength
= RequiredSize
;
134 pValueInformation
= RtlAllocateHeap(RtlGetProcessHeap(), 0, ValueInfoLength
);
135 if (!pValueInformation
)
137 DPRINT("RtlAllocateHeap() failed\n");
138 Status
= STATUS_NO_MEMORY
;
141 Status
= NtQueryValueKey(hDeviceKey
, &IdentifierU
, KeyValuePartialInformation
, pValueInformation
, ValueInfoLength
, &RequiredSize
);
143 if (!NT_SUCCESS(Status
))
145 DPRINT("NtQueryValueKey() failed with status 0x%08lx\n", Status
);
148 else if (pValueInformation
->Type
!= REG_SZ
)
150 DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation
->Type
, REG_SZ
);
154 ValueName
.Length
= ValueName
.MaximumLength
= pValueInformation
->DataLength
;
155 ValueName
.Buffer
= (PWCHAR
)pValueInformation
->Data
;
156 if (ValueName
.Length
>= sizeof(WCHAR
) && ValueName
.Buffer
[ValueName
.Length
/ sizeof(WCHAR
) - 1] == UNICODE_NULL
)
157 ValueName
.Length
-= sizeof(WCHAR
);
158 if (RtlCompareUnicodeString(&ValueName
, &AcpiBiosIdentifier
, FALSE
) == 0)
160 DPRINT("Found ACPI BIOS\n");
171 if (pDeviceInformation
)
172 RtlFreeHeap(RtlGetProcessHeap(), 0, pDeviceInformation
);
173 if (pValueInformation
)
174 RtlFreeHeap(RtlGetProcessHeap(), 0, pValueInformation
);
176 NtClose(hDevicesKey
);
185 GetComputerIdentifier(
187 ULONG IdentifierLength
)
189 OBJECT_ATTRIBUTES ObjectAttributes
;
190 UNICODE_STRING KeyName
;
191 LPCWSTR ComputerIdentifier
;
192 HANDLE ProcessorsKey
;
193 PKEY_FULL_INFORMATION pFullInfo
;
194 ULONG Size
, SizeNeeded
;
197 DPRINT("GetComputerIdentifier() called\n");
199 Size
= sizeof(KEY_FULL_INFORMATION
);
200 pFullInfo
= (PKEY_FULL_INFORMATION
)RtlAllocateHeap(RtlGetProcessHeap(), 0, Size
);
203 DPRINT("RtlAllocateHeap() failed\n");
207 /* Open the processors key */
208 RtlInitUnicodeString(&KeyName
,
209 L
"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor");
210 InitializeObjectAttributes(&ObjectAttributes
,
212 OBJ_CASE_INSENSITIVE
,
216 Status
= NtOpenKey(&ProcessorsKey
,
219 if (!NT_SUCCESS(Status
))
221 DPRINT("NtOpenKey() failed (Status 0x%lx)\n", Status
);
222 RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo
);
226 /* Get number of subkeys */
227 Status
= NtQueryKey(ProcessorsKey
,
232 NtClose(ProcessorsKey
);
233 if (!NT_SUCCESS(Status
) && Status
!= STATUS_BUFFER_OVERFLOW
)
235 DPRINT("NtQueryKey() failed (Status 0x%lx)\n", Status
);
236 RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo
);
240 /* Find computer identifier */
241 if (pFullInfo
->SubKeys
== 0)
243 /* Something strange happened. No processor detected */
244 RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo
);
248 if (IsAcpiComputer())
250 if (pFullInfo
->SubKeys
== 1)
252 /* Computer is mono-CPU */
253 ComputerIdentifier
= L
"ACPI UP";
257 /* Computer is multi-CPUs */
258 ComputerIdentifier
= L
"ACPI MP";
263 if (pFullInfo
->SubKeys
== 1)
265 /* Computer is mono-CPU */
266 ComputerIdentifier
= L
"PC UP";
270 /* Computer is multi-CPUs */
271 ComputerIdentifier
= L
"PC MP";
275 RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo
);
277 /* Copy computer identifier to return buffer */
278 SizeNeeded
= (wcslen(ComputerIdentifier
) + 1) * sizeof(WCHAR
);
279 if (SizeNeeded
> IdentifierLength
)
282 RtlCopyMemory(Identifier
, ComputerIdentifier
, SizeNeeded
);
289 CreateComputerTypeList(
298 WCHAR ComputerIdentifier
[128];
299 WCHAR ComputerKey
[32];
301 /* Get the computer identification */
302 if (!GetComputerIdentifier(ComputerIdentifier
, 128))
304 ComputerIdentifier
[0] = 0;
307 DPRINT("Computer identifier: '%S'\n", ComputerIdentifier
);
309 /* Search for matching device identifier */
310 if (!SetupFindFirstLineW(InfFile
, L
"Map.Computer", NULL
, &Context
))
312 /* FIXME: error message */
318 if (!INF_GetDataField(&Context
, 1, &KeyValue
))
320 /* FIXME: Handle error! */
321 DPRINT("INF_GetDataField() failed\n");
325 DPRINT("KeyValue: %S\n", KeyValue
);
326 if (wcsstr(ComputerIdentifier
, KeyValue
))
328 if (!INF_GetDataField(&Context
, 0, &KeyName
))
330 /* FIXME: Handle error! */
331 DPRINT("INF_GetDataField() failed\n");
335 DPRINT("Computer key: %S\n", KeyName
);
336 wcscpy(ComputerKey
, KeyName
);
338 } while (SetupFindNextLine(&Context
, &Context
));
340 List
= CreateGenericList();
344 if (!SetupFindFirstLineW (InfFile
, L
"Computer", NULL
, &Context
))
346 DestroyGenericList(List
, FALSE
);
352 if (!INF_GetData (&Context
, &KeyName
, &KeyValue
))
354 /* FIXME: Handle error! */
355 DPRINT("INF_GetData() failed\n");
359 UserData
= (WCHAR
*) RtlAllocateHeap(ProcessHeap
,
361 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
362 if (UserData
== NULL
)
364 /* FIXME: Handle error! */
367 wcscpy(UserData
, KeyName
);
369 sprintf(Buffer
, "%S", KeyValue
);
370 AppendGenericListEntry(List
, Buffer
, UserData
,
371 _wcsicmp(KeyName
, ComputerKey
) ? FALSE
: TRUE
);
372 } while (SetupFindNextLine(&Context
, &Context
));
380 GetDisplayIdentifier(
382 ULONG IdentifierLength
)
384 OBJECT_ATTRIBUTES ObjectAttributes
;
385 UNICODE_STRING KeyName
;
388 HANDLE BusInstanceKey
;
389 HANDLE ControllerKey
;
390 HANDLE ControllerInstanceKey
;
392 ULONG ControllerInstance
;
394 ULONG ReturnedLength
;
395 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
;
398 DPRINT("GetDisplayIdentifier() called\n");
400 /* Open the bus key */
401 RtlInitUnicodeString(&KeyName
,
402 L
"\\Registry\\Machine\\HARDWARE\\Description\\System\\MultifunctionAdapter");
403 InitializeObjectAttributes(&ObjectAttributes
,
405 OBJ_CASE_INSENSITIVE
,
409 Status
= NtOpenKey(&BusKey
,
410 KEY_ENUMERATE_SUB_KEYS
,
412 if (!NT_SUCCESS(Status
))
414 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
421 swprintf(Buffer
, L
"%lu", BusInstance
);
422 RtlInitUnicodeString(&KeyName
,
424 InitializeObjectAttributes(&ObjectAttributes
,
426 OBJ_CASE_INSENSITIVE
,
430 Status
= NtOpenKey(&BusInstanceKey
,
431 KEY_ENUMERATE_SUB_KEYS
,
433 if (!NT_SUCCESS(Status
))
435 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
440 /* Open the controller type key */
441 RtlInitUnicodeString(&KeyName
,
442 L
"DisplayController");
443 InitializeObjectAttributes(&ObjectAttributes
,
445 OBJ_CASE_INSENSITIVE
,
449 Status
= NtOpenKey(&ControllerKey
,
450 KEY_ENUMERATE_SUB_KEYS
,
452 if (NT_SUCCESS(Status
))
454 ControllerInstance
= 0;
458 /* Open the pointer controller instance key */
459 swprintf(Buffer
, L
"%lu", ControllerInstance
);
460 RtlInitUnicodeString(&KeyName
,
462 InitializeObjectAttributes(&ObjectAttributes
,
464 OBJ_CASE_INSENSITIVE
,
468 Status
= NtOpenKey(&ControllerInstanceKey
,
471 if (!NT_SUCCESS(Status
))
473 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
474 NtClose(ControllerKey
);
475 NtClose(BusInstanceKey
);
480 /* Get controller identifier */
481 RtlInitUnicodeString(&KeyName
,
484 BufferLength
= sizeof(KEY_VALUE_PARTIAL_INFORMATION
) +
486 ValueInfo
= (KEY_VALUE_PARTIAL_INFORMATION
*) RtlAllocateHeap(RtlGetProcessHeap(),
489 if (ValueInfo
== NULL
)
491 DPRINT("RtlAllocateHeap() failed\n");
492 NtClose(ControllerInstanceKey
);
493 NtClose(ControllerKey
);
494 NtClose(BusInstanceKey
);
499 Status
= NtQueryValueKey(ControllerInstanceKey
,
501 KeyValuePartialInformation
,
505 if (NT_SUCCESS(Status
))
507 DPRINT("Identifier: %S\n", (PWSTR
)ValueInfo
->Data
);
509 BufferLength
= min(ValueInfo
->DataLength
/ sizeof(WCHAR
), IdentifierLength
);
510 RtlCopyMemory (Identifier
,
512 BufferLength
* sizeof(WCHAR
));
513 Identifier
[BufferLength
] = 0;
515 RtlFreeHeap(RtlGetProcessHeap(),
519 NtClose(ControllerInstanceKey
);
520 NtClose(ControllerKey
);
521 NtClose(BusInstanceKey
);
526 NtClose(ControllerInstanceKey
);
528 ControllerInstance
++;
531 NtClose(ControllerKey
);
534 NtClose(BusInstanceKey
);
546 CreateDisplayDriverList(
555 WCHAR DisplayIdentifier
[128];
556 WCHAR DisplayKey
[32];
558 /* Get the display identification */
559 if (!GetDisplayIdentifier(DisplayIdentifier
, 128))
561 DisplayIdentifier
[0] = 0;
564 DPRINT("Display identifier: '%S'\n", DisplayIdentifier
);
566 /* Search for matching device identifier */
567 if (!SetupFindFirstLineW(InfFile
, L
"Map.Display", NULL
, &Context
))
569 /* FIXME: error message */
575 if (!INF_GetDataField(&Context
, 1, &KeyValue
))
577 /* FIXME: Handle error! */
578 DPRINT("INF_GetDataField() failed\n");
582 DPRINT("KeyValue: %S\n", KeyValue
);
583 if (wcsstr(DisplayIdentifier
, KeyValue
))
585 if (!INF_GetDataField(&Context
, 0, &KeyName
))
587 /* FIXME: Handle error! */
588 DPRINT("INF_GetDataField() failed\n");
592 DPRINT("Display key: %S\n", KeyName
);
593 wcscpy(DisplayKey
, KeyName
);
595 } while (SetupFindNextLine(&Context
, &Context
));
597 List
= CreateGenericList();
601 if (!SetupFindFirstLineW (InfFile
, L
"Display", NULL
, &Context
))
603 DestroyGenericList(List
, FALSE
);
609 if (!INF_GetDataField(&Context
, 0, &KeyName
))
611 DPRINT1("INF_GetDataField() failed\n");
615 if (!INF_GetDataField(&Context
, 1, &KeyValue
))
617 DPRINT1("INF_GetDataField() failed\n");
621 UserData
= (WCHAR
*) RtlAllocateHeap(ProcessHeap
,
623 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
624 if (UserData
== NULL
)
626 DPRINT1("RtlAllocateHeap() failed\n");
627 DestroyGenericList(List
, TRUE
);
631 wcscpy(UserData
, KeyName
);
633 sprintf(Buffer
, "%S", KeyValue
);
634 AppendGenericListEntry(List
,
637 _wcsicmp(KeyName
, DisplayKey
) ? FALSE
: TRUE
);
638 } while (SetupFindNextLine(&Context
, &Context
));
641 AppendGenericListEntry(List
, "Other display driver", NULL
, TRUE
);
649 ProcessComputerFiles(
652 PWCHAR
*AdditionalSectionName
)
654 PGENERIC_LIST_ENTRY Entry
;
655 static WCHAR SectionName
[128];
657 DPRINT("ProcessComputerFiles() called\n");
659 Entry
= GetCurrentListEntry(List
);
662 DPRINT("GetCurrentListEntry() failed\n");
666 wcscpy(SectionName
, L
"Files.");
667 wcscat(SectionName
, (const wchar_t*)GetListEntryUserData(Entry
));
668 *AdditionalSectionName
= SectionName
;
675 ProcessDisplayRegistry(
679 PGENERIC_LIST_ENTRY Entry
;
686 ULONG Width
, Height
, Bpp
;
688 DPRINT("ProcessDisplayRegistry() called\n");
690 Entry
= GetCurrentListEntry(List
);
693 DPRINT1("GetCurrentListEntry() failed\n");
697 if (!SetupFindFirstLineW(InfFile
, L
"Display", (WCHAR
*)GetListEntryUserData(Entry
), &Context
))
699 DPRINT1("SetupFindFirstLineW() failed\n");
703 /* Enable the right driver */
704 if (!INF_GetDataField(&Context
, 3, &ServiceName
))
706 DPRINT1("INF_GetDataField() failed\n");
710 ASSERT(wcslen(ServiceName
) < 10);
711 DPRINT("Service name: %S\n", ServiceName
);
714 Status
= RtlWriteRegistryValue(RTL_REGISTRY_SERVICES
,
720 if (!NT_SUCCESS(Status
))
722 DPRINT1("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
726 /* Set the resolution */
727 swprintf(RegPath
, L
"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Services\\%s\\Device0", ServiceName
);
729 if (!INF_GetDataField(&Context
, 4, &Buffer
))
731 DPRINT1("INF_GetDataField() failed\n");
735 Width
= wcstoul(Buffer
, NULL
, 10);
736 Status
= RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE
,
738 L
"DefaultSettings.XResolution",
742 if (!NT_SUCCESS(Status
))
744 DPRINT1("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
748 if (!INF_GetDataField(&Context
, 5, &Buffer
))
750 DPRINT1("INF_GetDataField() failed\n");
754 Height
= wcstoul(Buffer
, 0, 0);
755 Status
= RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE
,
757 L
"DefaultSettings.YResolution",
761 if (!NT_SUCCESS(Status
))
763 DPRINT1("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
767 if (!INF_GetDataField(&Context
, 6, &Buffer
))
769 DPRINT1("INF_GetDataField() failed\n");
773 Bpp
= wcstoul(Buffer
, 0, 0);
774 Status
= RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE
,
776 L
"DefaultSettings.BitsPerPel",
780 if (!NT_SUCCESS(Status
))
782 DPRINT1("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
786 DPRINT("ProcessDisplayRegistry() done\n");
793 ProcessLocaleRegistry(
796 PGENERIC_LIST_ENTRY Entry
;
798 OBJECT_ATTRIBUTES ObjectAttributes
;
799 UNICODE_STRING KeyName
;
800 UNICODE_STRING ValueName
;
805 Entry
= GetCurrentListEntry(List
);
809 LanguageId
= (PWCHAR
)GetListEntryUserData(Entry
);
810 if (LanguageId
== NULL
)
813 DPRINT("LanguageId: %S\n", LanguageId
);
815 /* Open the default users locale key */
816 RtlInitUnicodeString(&KeyName
,
817 L
"\\Registry\\User\\.DEFAULT\\Control Panel\\International");
819 InitializeObjectAttributes(&ObjectAttributes
,
821 OBJ_CASE_INSENSITIVE
,
825 Status
= NtOpenKey(&KeyHandle
,
828 if (!NT_SUCCESS(Status
))
830 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status
);
834 /* Set default user locale */
835 RtlInitUnicodeString(&ValueName
,
837 Status
= NtSetValueKey(KeyHandle
,
842 (wcslen(LanguageId
) + 1) * sizeof(WCHAR
));
844 if (!NT_SUCCESS(Status
))
846 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
850 /* Skip first 4 zeroes */
851 if (wcslen(LanguageId
) >= 4)
854 /* Open the NLS language key */
855 RtlInitUnicodeString(&KeyName
,
856 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language");
858 InitializeObjectAttributes(&ObjectAttributes
,
860 OBJ_CASE_INSENSITIVE
,
864 Status
= NtOpenKey(&KeyHandle
,
867 if (!NT_SUCCESS(Status
))
869 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status
);
873 /* Set default language */
874 RtlInitUnicodeString(&ValueName
,
876 Status
= NtSetValueKey(KeyHandle
,
881 (wcslen(LanguageId
) + 1) * sizeof(WCHAR
));
882 if (!NT_SUCCESS(Status
))
884 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
889 /* Set install language */
890 RtlInitUnicodeString(&ValueName
,
892 Status
= NtSetValueKey (KeyHandle
,
897 (wcslen(LanguageId
) + 1) * sizeof(WCHAR
));
899 if (!NT_SUCCESS(Status
))
901 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
910 CreateKeyboardDriverList(
920 List
= CreateGenericList();
924 if (!SetupFindFirstLineW (InfFile
, L
"Keyboard", NULL
, &Context
))
926 DestroyGenericList(List
, FALSE
);
932 if (!INF_GetData (&Context
, &KeyName
, &KeyValue
))
934 /* FIXME: Handle error! */
935 DPRINT("INF_GetData() failed\n");
939 UserData
= (WCHAR
*)RtlAllocateHeap(ProcessHeap
,
941 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
942 if (UserData
== NULL
)
944 /* FIXME: Handle error! */
947 wcscpy(UserData
, KeyName
);
949 sprintf(Buffer
, "%S", KeyValue
);
950 AppendGenericListEntry(List
, Buffer
, UserData
, FALSE
);
951 } while (SetupFindNextLine(&Context
, &Context
));
958 GetDefaultLanguageIndex(VOID
)
960 return DefaultLanguageIndex
;
967 WCHAR
*DefaultLanguage
)
974 PWCHAR UserData
= NULL
;
977 /* Get default language id */
978 if (!SetupFindFirstLineW (InfFile
, L
"NLS", L
"DefaultLanguage", &Context
))
981 if (!INF_GetData (&Context
, NULL
, &KeyValue
))
984 wcscpy(DefaultLanguage
, KeyValue
);
986 SelectedLanguageId
= KeyValue
;
988 List
= CreateGenericList();
992 if (!SetupFindFirstLineW (InfFile
, L
"Language", NULL
, &Context
))
994 DestroyGenericList(List
, FALSE
);
1000 if (!INF_GetData (&Context
, &KeyName
, &KeyValue
))
1002 /* FIXME: Handle error! */
1003 DPRINT("INF_GetData() failed\n");
1007 if (IsLanguageAvailable(KeyName
))
1010 UserData
= (WCHAR
*) RtlAllocateHeap(ProcessHeap
,
1012 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
1013 if (UserData
== NULL
)
1015 /* FIXME: Handle error! */
1018 wcscpy(UserData
, KeyName
);
1020 if (!_wcsicmp(KeyName
, DefaultLanguage
))
1021 DefaultLanguageIndex
= uIndex
;
1023 sprintf(Buffer
, "%S", KeyValue
);
1024 AppendGenericListEntry(List
,
1030 } while (SetupFindNextLine(&Context
, &Context
));
1032 /* Only one language available, make it the default one */
1033 if(uIndex
== 1 && UserData
!= NULL
)
1035 DefaultLanguageIndex
= 0;
1036 wcscpy(DefaultLanguage
, UserData
);
1044 CreateKeyboardLayoutList(
1046 WCHAR
*DefaultKBLayout
)
1054 const MUI_LAYOUTS
* LayoutsList
;
1056 BOOL KeyboardLayoutsFound
= FALSE
;
1058 /* Get default layout id */
1059 if (!SetupFindFirstLineW (InfFile
, L
"NLS", L
"DefaultLayout", &Context
))
1062 if (!INF_GetData (&Context
, NULL
, &KeyValue
))
1065 wcscpy(DefaultKBLayout
, KeyValue
);
1067 List
= CreateGenericList();
1071 LayoutsList
= MUIGetLayoutsList();
1075 if (!SetupFindFirstLineW(InfFile
, L
"KeyboardLayout", NULL
, &Context
))
1077 DestroyGenericList(List
, FALSE
);
1083 if (!INF_GetData (&Context
, &KeyName
, &KeyValue
))
1085 /* FIXME: Handle error! */
1086 DPRINT("INF_GetData() failed\n");
1087 DestroyGenericList(List
, FALSE
);
1092 UserData
= (WCHAR
*)RtlAllocateHeap(ProcessHeap
,
1094 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
1095 if (UserData
== NULL
)
1097 /* FIXME: Handle error! */
1098 DPRINT("RtlAllocateHeap() failed\n");
1099 DestroyGenericList(List
, FALSE
);
1103 wcscpy(UserData
, KeyName
);
1105 sprintf(Buffer
, "%S", KeyValue
);
1106 AppendGenericListEntry(List
,
1109 _wcsicmp(KeyName
, DefaultKBLayout
) ? FALSE
: TRUE
);
1110 KeyboardLayoutsFound
= TRUE
;
1113 } while (SetupFindNextLine(&Context
, &Context
));
1117 } while (LayoutsList
[uIndex
].LangID
!= NULL
);
1119 /* FIXME: Handle this case */
1120 if (!KeyboardLayoutsFound
)
1122 DPRINT1("No keyboard layouts have been found\n");
1123 DestroyGenericList(List
, FALSE
);
1132 ProcessKeyboardLayoutRegistry(
1135 PGENERIC_LIST_ENTRY Entry
;
1137 const MUI_LAYOUTS
* LayoutsList
;
1138 MUI_LAYOUTS NewLayoutsList
[20];
1142 Entry
= GetCurrentListEntry(List
);
1146 LayoutId
= (PWCHAR
)GetListEntryUserData(Entry
);
1147 if (LayoutId
== NULL
)
1150 LayoutsList
= MUIGetLayoutsList();
1152 if (_wcsicmp(LayoutsList
[0].LayoutID
, LayoutId
) != 0)
1154 for (uIndex
= 1; LayoutsList
[uIndex
].LangID
!= NULL
; uIndex
++)
1156 if (_wcsicmp(LayoutsList
[uIndex
].LayoutID
, LayoutId
) == 0)
1162 NewLayoutsList
[uIndex
].LangID
= LayoutsList
[uIndex
].LangID
;
1163 NewLayoutsList
[uIndex
].LayoutID
= LayoutsList
[uIndex
].LayoutID
;
1166 NewLayoutsList
[uIndex
].LangID
= NULL
;
1167 NewLayoutsList
[uIndex
].LayoutID
= NULL
;
1168 NewLayoutsList
[uOldPos
].LangID
= LayoutsList
[0].LangID
;
1169 NewLayoutsList
[uOldPos
].LayoutID
= LayoutsList
[0].LayoutID
;
1170 NewLayoutsList
[0].LangID
= LayoutsList
[uOldPos
].LangID
;
1171 NewLayoutsList
[0].LayoutID
= LayoutsList
[uOldPos
].LayoutID
;
1173 return AddKbLayoutsToRegistry(NewLayoutsList
);
1182 ProcessKeyboardLayoutFiles(
1194 OBJECT_ATTRIBUTES ObjectAttributes
;
1195 UNICODE_STRING KeyName
;
1196 UNICODE_STRING ValueName
;
1198 WCHAR szKeyName
[] = L
"\\Registry\\User\\.DEFAULT\\Control Panel\\International\\Geo";
1199 WCHAR szValueName
[] = L
"Nation";
1202 RtlInitUnicodeString(&KeyName
,
1204 InitializeObjectAttributes(&ObjectAttributes
,
1206 OBJ_CASE_INSENSITIVE
,
1210 Status
= NtOpenKey(&KeyHandle
,
1213 if(!NT_SUCCESS(Status
))
1215 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status
);
1219 RtlInitUnicodeString(&ValueName
, szValueName
);
1220 Status
= NtSetValueKey(KeyHandle
,
1225 (wcslen(Id
) + 1) * sizeof(WCHAR
));
1227 if (!NT_SUCCESS(Status
))
1229 DPRINT1("NtSetValueKey() failed (Status = %lx)\n", Status
);