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: Eric Kohl
27 /* INCLUDES *****************************************************************/
34 /* GLOBALS ******************************************************************/
36 ULONG DefaultLanguageIndex
= 0;
38 /* FUNCTIONS ****************************************************************/
44 UNICODE_STRING MultiKeyPathU
= RTL_CONSTANT_STRING(L
"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter");
45 UNICODE_STRING IdentifierU
= RTL_CONSTANT_STRING(L
"Identifier");
46 UNICODE_STRING AcpiBiosIdentifier
= RTL_CONSTANT_STRING(L
"ACPI BIOS");
47 OBJECT_ATTRIBUTES ObjectAttributes
;
48 PKEY_BASIC_INFORMATION pDeviceInformation
= NULL
;
49 ULONG DeviceInfoLength
= sizeof(KEY_BASIC_INFORMATION
) + 50 * sizeof(WCHAR
);
50 PKEY_VALUE_PARTIAL_INFORMATION pValueInformation
= NULL
;
51 ULONG ValueInfoLength
= sizeof(KEY_VALUE_PARTIAL_INFORMATION
) + 50 * sizeof(WCHAR
);
53 ULONG IndexDevice
= 0;
54 UNICODE_STRING DeviceName
, ValueName
;
55 HANDLE hDevicesKey
= NULL
;
56 HANDLE hDeviceKey
= NULL
;
60 InitializeObjectAttributes(&ObjectAttributes
,
65 Status
= NtOpenKey(&hDevicesKey
,
66 KEY_ENUMERATE_SUB_KEYS
,
68 if (!NT_SUCCESS(Status
))
70 DPRINT("NtOpenKey() failed with status 0x%08lx\n", Status
);
74 pDeviceInformation
= RtlAllocateHeap(RtlGetProcessHeap(), 0, DeviceInfoLength
);
75 if (!pDeviceInformation
)
77 DPRINT("RtlAllocateHeap() failed\n");
78 Status
= STATUS_NO_MEMORY
;
82 pValueInformation
= RtlAllocateHeap(RtlGetProcessHeap(), 0, ValueInfoLength
);
83 if (!pValueInformation
)
85 DPRINT("RtlAllocateHeap() failed\n");
86 Status
= STATUS_NO_MEMORY
;
92 Status
= NtEnumerateKey(hDevicesKey
, IndexDevice
, KeyBasicInformation
, pDeviceInformation
, DeviceInfoLength
, &RequiredSize
);
93 if (Status
== STATUS_NO_MORE_ENTRIES
)
95 else if (Status
== STATUS_BUFFER_OVERFLOW
|| Status
== STATUS_BUFFER_TOO_SMALL
)
97 RtlFreeHeap(RtlGetProcessHeap(), 0, pDeviceInformation
);
98 DeviceInfoLength
= RequiredSize
;
99 pDeviceInformation
= RtlAllocateHeap(RtlGetProcessHeap(), 0, DeviceInfoLength
);
100 if (!pDeviceInformation
)
102 DPRINT("RtlAllocateHeap() failed\n");
103 Status
= STATUS_NO_MEMORY
;
106 Status
= NtEnumerateKey(hDevicesKey
, IndexDevice
, KeyBasicInformation
, pDeviceInformation
, DeviceInfoLength
, &RequiredSize
);
108 if (!NT_SUCCESS(Status
))
110 DPRINT("NtEnumerateKey() failed with status 0x%08lx\n", Status
);
115 /* Open device key */
116 DeviceName
.Length
= DeviceName
.MaximumLength
= pDeviceInformation
->NameLength
;
117 DeviceName
.Buffer
= pDeviceInformation
->Name
;
118 InitializeObjectAttributes(&ObjectAttributes
, &DeviceName
, OBJ_CASE_INSENSITIVE
, hDevicesKey
, NULL
);
123 if (!NT_SUCCESS(Status
))
125 DPRINT("NtOpenKey() failed with status 0x%08lx\n", Status
);
129 /* Read identifier */
130 Status
= NtQueryValueKey(hDeviceKey
, &IdentifierU
, KeyValuePartialInformation
, pValueInformation
, ValueInfoLength
, &RequiredSize
);
131 if (Status
== STATUS_BUFFER_OVERFLOW
|| Status
== STATUS_BUFFER_TOO_SMALL
)
133 RtlFreeHeap(RtlGetProcessHeap(), 0, pValueInformation
);
134 ValueInfoLength
= RequiredSize
;
135 pValueInformation
= RtlAllocateHeap(RtlGetProcessHeap(), 0, ValueInfoLength
);
136 if (!pValueInformation
)
138 DPRINT("RtlAllocateHeap() failed\n");
139 Status
= STATUS_NO_MEMORY
;
142 Status
= NtQueryValueKey(hDeviceKey
, &IdentifierU
, KeyValuePartialInformation
, pValueInformation
, ValueInfoLength
, &RequiredSize
);
144 if (!NT_SUCCESS(Status
))
146 DPRINT("NtQueryValueKey() failed with status 0x%08lx\n", Status
);
149 else if (pValueInformation
->Type
!= REG_SZ
)
151 DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation
->Type
, REG_SZ
);
155 ValueName
.Length
= ValueName
.MaximumLength
= pValueInformation
->DataLength
;
156 ValueName
.Buffer
= (PWCHAR
)pValueInformation
->Data
;
157 if (ValueName
.Length
>= sizeof(WCHAR
) && ValueName
.Buffer
[ValueName
.Length
/ sizeof(WCHAR
) - 1] == UNICODE_NULL
)
158 ValueName
.Length
-= sizeof(WCHAR
);
159 if (RtlCompareUnicodeString(&ValueName
, &AcpiBiosIdentifier
, FALSE
) == 0)
161 DPRINT("Found ACPI BIOS\n");
172 if (pDeviceInformation
)
173 RtlFreeHeap(RtlGetProcessHeap(), 0, pDeviceInformation
);
174 if (pValueInformation
)
175 RtlFreeHeap(RtlGetProcessHeap(), 0, pValueInformation
);
177 NtClose(hDevicesKey
);
186 GetComputerIdentifier(
188 ULONG IdentifierLength
)
190 OBJECT_ATTRIBUTES ObjectAttributes
;
191 UNICODE_STRING KeyName
;
192 LPCWSTR ComputerIdentifier
;
193 HANDLE ProcessorsKey
;
194 PKEY_FULL_INFORMATION pFullInfo
;
195 ULONG Size
, SizeNeeded
;
198 DPRINT("GetComputerIdentifier() called\n");
200 Size
= sizeof(KEY_FULL_INFORMATION
);
201 pFullInfo
= (PKEY_FULL_INFORMATION
)RtlAllocateHeap(RtlGetProcessHeap(), 0, Size
);
204 DPRINT("RtlAllocateHeap() failed\n");
208 /* Open the processors key */
209 RtlInitUnicodeString(&KeyName
,
210 L
"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor");
211 InitializeObjectAttributes(&ObjectAttributes
,
213 OBJ_CASE_INSENSITIVE
,
217 Status
= NtOpenKey(&ProcessorsKey
,
220 if (!NT_SUCCESS(Status
))
222 DPRINT("NtOpenKey() failed (Status 0x%lx)\n", Status
);
223 RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo
);
227 /* Get number of subkeys */
228 Status
= NtQueryKey(ProcessorsKey
,
233 NtClose(ProcessorsKey
);
234 if (!NT_SUCCESS(Status
) && Status
!= STATUS_BUFFER_OVERFLOW
)
236 DPRINT("NtQueryKey() failed (Status 0x%lx)\n", Status
);
237 RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo
);
241 /* Find computer identifier */
242 if (pFullInfo
->SubKeys
== 0)
244 /* Something strange happened. No processor detected */
245 RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo
);
249 if (IsAcpiComputer())
251 if (pFullInfo
->SubKeys
== 1)
253 /* Computer is mono-CPU */
254 ComputerIdentifier
= L
"ACPI UP";
258 /* Computer is multi-CPUs */
259 ComputerIdentifier
= L
"ACPI MP";
264 if (pFullInfo
->SubKeys
== 1)
266 /* Computer is mono-CPU */
267 ComputerIdentifier
= L
"PC UP";
271 /* Computer is multi-CPUs */
272 ComputerIdentifier
= L
"PC MP";
276 RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo
);
278 /* Copy computer identifier to return buffer */
279 SizeNeeded
= (wcslen(ComputerIdentifier
) + 1) * sizeof(WCHAR
);
280 if (SizeNeeded
> IdentifierLength
)
283 RtlCopyMemory(Identifier
, ComputerIdentifier
, SizeNeeded
);
290 CreateComputerTypeList(
299 WCHAR ComputerIdentifier
[128];
300 WCHAR ComputerKey
[32];
302 /* Get the computer identification */
303 if (!GetComputerIdentifier(ComputerIdentifier
, 128))
305 ComputerIdentifier
[0] = 0;
308 DPRINT("Computer identifier: '%S'\n", ComputerIdentifier
);
310 /* Search for matching device identifier */
311 if (!SetupFindFirstLineW(InfFile
, L
"Map.Computer", NULL
, &Context
))
313 /* FIXME: error message */
319 if (!INF_GetDataField(&Context
, 1, &KeyValue
))
321 /* FIXME: Handle error! */
322 DPRINT("INF_GetDataField() failed\n");
326 DPRINT("KeyValue: %S\n", KeyValue
);
327 if (wcsstr(ComputerIdentifier
, KeyValue
))
329 if (!INF_GetDataField(&Context
, 0, &KeyName
))
331 /* FIXME: Handle error! */
332 DPRINT("INF_GetDataField() failed\n");
336 DPRINT("Computer key: %S\n", KeyName
);
337 wcscpy(ComputerKey
, KeyName
);
339 } while (SetupFindNextLine(&Context
, &Context
));
341 List
= CreateGenericList();
345 if (!SetupFindFirstLineW (InfFile
, L
"Computer", NULL
, &Context
))
347 DestroyGenericList(List
, FALSE
);
353 if (!INF_GetData (&Context
, &KeyName
, &KeyValue
))
355 /* FIXME: Handle error! */
356 DPRINT("INF_GetData() failed\n");
360 UserData
= (WCHAR
*) RtlAllocateHeap(ProcessHeap
,
362 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
363 if (UserData
== NULL
)
365 /* FIXME: Handle error! */
368 wcscpy(UserData
, KeyName
);
370 sprintf(Buffer
, "%S", KeyValue
);
371 AppendGenericListEntry(List
, Buffer
, UserData
,
372 _wcsicmp(KeyName
, ComputerKey
) ? FALSE
: TRUE
);
373 } while (SetupFindNextLine(&Context
, &Context
));
381 GetDisplayIdentifier(
383 ULONG IdentifierLength
)
385 OBJECT_ATTRIBUTES ObjectAttributes
;
386 UNICODE_STRING KeyName
;
389 HANDLE BusInstanceKey
;
390 HANDLE ControllerKey
;
391 HANDLE ControllerInstanceKey
;
393 ULONG ControllerInstance
;
395 ULONG ReturnedLength
;
396 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
;
399 DPRINT("GetDisplayIdentifier() called\n");
401 /* Open the bus key */
402 RtlInitUnicodeString(&KeyName
,
403 L
"\\Registry\\Machine\\HARDWARE\\Description\\System\\MultifunctionAdapter");
404 InitializeObjectAttributes(&ObjectAttributes
,
406 OBJ_CASE_INSENSITIVE
,
410 Status
= NtOpenKey(&BusKey
,
411 KEY_ENUMERATE_SUB_KEYS
,
413 if (!NT_SUCCESS(Status
))
415 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
422 swprintf(Buffer
, L
"%lu", BusInstance
);
423 RtlInitUnicodeString(&KeyName
,
425 InitializeObjectAttributes(&ObjectAttributes
,
427 OBJ_CASE_INSENSITIVE
,
431 Status
= NtOpenKey(&BusInstanceKey
,
432 KEY_ENUMERATE_SUB_KEYS
,
434 if (!NT_SUCCESS(Status
))
436 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
441 /* Open the controller type key */
442 RtlInitUnicodeString(&KeyName
,
443 L
"DisplayController");
444 InitializeObjectAttributes(&ObjectAttributes
,
446 OBJ_CASE_INSENSITIVE
,
450 Status
= NtOpenKey(&ControllerKey
,
451 KEY_ENUMERATE_SUB_KEYS
,
453 if (NT_SUCCESS(Status
))
455 ControllerInstance
= 0;
459 /* Open the pointer controller instance key */
460 swprintf(Buffer
, L
"%lu", ControllerInstance
);
461 RtlInitUnicodeString(&KeyName
,
463 InitializeObjectAttributes(&ObjectAttributes
,
465 OBJ_CASE_INSENSITIVE
,
469 Status
= NtOpenKey(&ControllerInstanceKey
,
472 if (!NT_SUCCESS(Status
))
474 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
475 NtClose(ControllerKey
);
476 NtClose(BusInstanceKey
);
481 /* Get controller identifier */
482 RtlInitUnicodeString(&KeyName
,
485 BufferLength
= sizeof(KEY_VALUE_PARTIAL_INFORMATION
) +
487 ValueInfo
= (KEY_VALUE_PARTIAL_INFORMATION
*) RtlAllocateHeap(RtlGetProcessHeap(),
490 if (ValueInfo
== NULL
)
492 DPRINT("RtlAllocateHeap() failed\n");
493 NtClose(ControllerInstanceKey
);
494 NtClose(ControllerKey
);
495 NtClose(BusInstanceKey
);
500 Status
= NtQueryValueKey(ControllerInstanceKey
,
502 KeyValuePartialInformation
,
506 if (NT_SUCCESS(Status
))
508 DPRINT("Identifier: %S\n", (PWSTR
)ValueInfo
->Data
);
510 BufferLength
= min(ValueInfo
->DataLength
/ sizeof(WCHAR
), IdentifierLength
);
511 RtlCopyMemory (Identifier
,
513 BufferLength
* sizeof(WCHAR
));
514 Identifier
[BufferLength
] = 0;
516 RtlFreeHeap(RtlGetProcessHeap(),
520 NtClose(ControllerInstanceKey
);
521 NtClose(ControllerKey
);
522 NtClose(BusInstanceKey
);
527 NtClose(ControllerInstanceKey
);
529 ControllerInstance
++;
532 NtClose(ControllerKey
);
535 NtClose(BusInstanceKey
);
547 CreateDisplayDriverList(
556 WCHAR DisplayIdentifier
[128];
557 WCHAR DisplayKey
[32];
559 /* Get the display identification */
560 if (!GetDisplayIdentifier(DisplayIdentifier
, 128))
562 DisplayIdentifier
[0] = 0;
565 DPRINT("Display identifier: '%S'\n", DisplayIdentifier
);
567 /* Search for matching device identifier */
568 if (!SetupFindFirstLineW(InfFile
, L
"Map.Display", NULL
, &Context
))
570 /* FIXME: error message */
576 if (!INF_GetDataField(&Context
, 1, &KeyValue
))
578 /* FIXME: Handle error! */
579 DPRINT("INF_GetDataField() failed\n");
583 DPRINT("KeyValue: %S\n", KeyValue
);
584 if (wcsstr(DisplayIdentifier
, KeyValue
))
586 if (!INF_GetDataField(&Context
, 0, &KeyName
))
588 /* FIXME: Handle error! */
589 DPRINT("INF_GetDataField() failed\n");
593 DPRINT("Display key: %S\n", KeyName
);
594 wcscpy(DisplayKey
, KeyName
);
596 } while (SetupFindNextLine(&Context
, &Context
));
598 List
= CreateGenericList();
602 if (!SetupFindFirstLineW (InfFile
, L
"Display", NULL
, &Context
))
604 DestroyGenericList(List
, FALSE
);
610 if (!INF_GetDataField(&Context
, 0, &KeyName
))
612 DPRINT1("INF_GetDataField() failed\n");
616 if (!INF_GetDataField(&Context
, 1, &KeyValue
))
618 DPRINT1("INF_GetDataField() failed\n");
622 UserData
= (WCHAR
*) RtlAllocateHeap(ProcessHeap
,
624 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
625 if (UserData
== NULL
)
627 DPRINT1("RtlAllocateHeap() failed\n");
628 DestroyGenericList(List
, TRUE
);
632 wcscpy(UserData
, KeyName
);
634 sprintf(Buffer
, "%S", KeyValue
);
635 AppendGenericListEntry(List
,
638 _wcsicmp(KeyName
, DisplayKey
) ? FALSE
: TRUE
);
639 } while (SetupFindNextLine(&Context
, &Context
));
642 AppendGenericListEntry(List
, "Other display driver", NULL
, TRUE
);
650 ProcessComputerFiles(
653 PWCHAR
*AdditionalSectionName
)
655 PGENERIC_LIST_ENTRY Entry
;
656 static WCHAR SectionName
[128];
658 DPRINT("ProcessComputerFiles() called\n");
660 Entry
= GetCurrentListEntry(List
);
663 DPRINT("GetCurrentListEntry() failed\n");
667 wcscpy(SectionName
, L
"Files.");
668 wcscat(SectionName
, (const wchar_t*)GetListEntryUserData(Entry
));
669 *AdditionalSectionName
= SectionName
;
676 ProcessDisplayRegistry(
680 PGENERIC_LIST_ENTRY Entry
;
687 ULONG Width
, Height
, Bpp
;
689 DPRINT("ProcessDisplayRegistry() called\n");
691 Entry
= GetCurrentListEntry(List
);
694 DPRINT1("GetCurrentListEntry() failed\n");
698 if (!SetupFindFirstLineW(InfFile
, L
"Display", (WCHAR
*)GetListEntryUserData(Entry
), &Context
))
700 DPRINT1("SetupFindFirstLineW() failed\n");
704 /* Enable the right driver */
705 if (!INF_GetDataField(&Context
, 3, &ServiceName
))
707 DPRINT1("INF_GetDataField() failed\n");
711 ASSERT(wcslen(ServiceName
) < 10);
712 DPRINT("Service name: %S\n", ServiceName
);
715 Status
= RtlWriteRegistryValue(RTL_REGISTRY_SERVICES
,
721 if (!NT_SUCCESS(Status
))
723 DPRINT1("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
727 /* Set the resolution */
728 swprintf(RegPath
, L
"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Services\\%s\\Device0", ServiceName
);
730 if (!INF_GetDataField(&Context
, 4, &Buffer
))
732 DPRINT1("INF_GetDataField() failed\n");
736 Width
= wcstoul(Buffer
, NULL
, 10);
737 Status
= RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE
,
739 L
"DefaultSettings.XResolution",
743 if (!NT_SUCCESS(Status
))
745 DPRINT1("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
749 if (!INF_GetDataField(&Context
, 5, &Buffer
))
751 DPRINT1("INF_GetDataField() failed\n");
755 Height
= wcstoul(Buffer
, 0, 0);
756 Status
= RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE
,
758 L
"DefaultSettings.YResolution",
762 if (!NT_SUCCESS(Status
))
764 DPRINT1("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
768 if (!INF_GetDataField(&Context
, 6, &Buffer
))
770 DPRINT1("INF_GetDataField() failed\n");
774 Bpp
= wcstoul(Buffer
, 0, 0);
775 Status
= RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE
,
777 L
"DefaultSettings.BitsPerPel",
781 if (!NT_SUCCESS(Status
))
783 DPRINT1("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
787 DPRINT("ProcessDisplayRegistry() done\n");
794 ProcessLocaleRegistry(
797 PGENERIC_LIST_ENTRY Entry
;
799 OBJECT_ATTRIBUTES ObjectAttributes
;
800 UNICODE_STRING KeyName
;
801 UNICODE_STRING ValueName
;
806 Entry
= GetCurrentListEntry(List
);
810 LanguageId
= (PWCHAR
)GetListEntryUserData(Entry
);
811 if (LanguageId
== NULL
)
814 DPRINT("LanguageId: %S\n", LanguageId
);
816 /* Open the default users locale key */
817 RtlInitUnicodeString(&KeyName
,
818 L
"\\Registry\\User\\.DEFAULT\\Control Panel\\International");
820 InitializeObjectAttributes(&ObjectAttributes
,
822 OBJ_CASE_INSENSITIVE
,
826 Status
= NtOpenKey(&KeyHandle
,
829 if (!NT_SUCCESS(Status
))
831 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status
);
835 /* Set default user locale */
836 RtlInitUnicodeString(&ValueName
,
838 Status
= NtSetValueKey(KeyHandle
,
843 (wcslen(LanguageId
) + 1) * sizeof(WCHAR
));
845 if (!NT_SUCCESS(Status
))
847 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
851 /* Skip first 4 zeroes */
852 if (wcslen(LanguageId
) >= 4)
855 /* Open the NLS language key */
856 RtlInitUnicodeString(&KeyName
,
857 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language");
859 InitializeObjectAttributes(&ObjectAttributes
,
861 OBJ_CASE_INSENSITIVE
,
865 Status
= NtOpenKey(&KeyHandle
,
868 if (!NT_SUCCESS(Status
))
870 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status
);
874 /* Set default language */
875 RtlInitUnicodeString(&ValueName
,
877 Status
= NtSetValueKey(KeyHandle
,
882 (wcslen(LanguageId
) + 1) * sizeof(WCHAR
));
883 if (!NT_SUCCESS(Status
))
885 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
890 /* Set install language */
891 RtlInitUnicodeString(&ValueName
,
893 Status
= NtSetValueKey (KeyHandle
,
898 (wcslen(LanguageId
) + 1) * sizeof(WCHAR
));
900 if (!NT_SUCCESS(Status
))
902 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
911 CreateKeyboardDriverList(
921 List
= CreateGenericList();
925 if (!SetupFindFirstLineW (InfFile
, L
"Keyboard", NULL
, &Context
))
927 DestroyGenericList(List
, FALSE
);
933 if (!INF_GetData (&Context
, &KeyName
, &KeyValue
))
935 /* FIXME: Handle error! */
936 DPRINT("INF_GetData() failed\n");
940 UserData
= (WCHAR
*)RtlAllocateHeap(ProcessHeap
,
942 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
943 if (UserData
== NULL
)
945 /* FIXME: Handle error! */
948 wcscpy(UserData
, KeyName
);
950 sprintf(Buffer
, "%S", KeyValue
);
951 AppendGenericListEntry(List
, Buffer
, UserData
, FALSE
);
952 } while (SetupFindNextLine(&Context
, &Context
));
959 GetDefaultLanguageIndex(VOID
)
961 return DefaultLanguageIndex
;
968 WCHAR
*DefaultLanguage
)
975 PWCHAR UserData
= NULL
;
978 /* Get default language id */
979 if (!SetupFindFirstLineW (InfFile
, L
"NLS", L
"DefaultLanguage", &Context
))
982 if (!INF_GetData (&Context
, NULL
, &KeyValue
))
985 wcscpy(DefaultLanguage
, KeyValue
);
987 SelectedLanguageId
= KeyValue
;
989 List
= CreateGenericList();
993 if (!SetupFindFirstLineW (InfFile
, L
"Language", NULL
, &Context
))
995 DestroyGenericList(List
, FALSE
);
1001 if (!INF_GetData (&Context
, &KeyName
, &KeyValue
))
1003 /* FIXME: Handle error! */
1004 DPRINT("INF_GetData() failed\n");
1008 if (IsLanguageAvailable(KeyName
))
1011 UserData
= (WCHAR
*) RtlAllocateHeap(ProcessHeap
,
1013 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
1014 if (UserData
== NULL
)
1016 /* FIXME: Handle error! */
1019 wcscpy(UserData
, KeyName
);
1021 if (!_wcsicmp(KeyName
, DefaultLanguage
))
1022 DefaultLanguageIndex
= uIndex
;
1024 sprintf(Buffer
, "%S", KeyValue
);
1025 AppendGenericListEntry(List
,
1031 } while (SetupFindNextLine(&Context
, &Context
));
1033 /* Only one language available, make it the default one */
1034 if(uIndex
== 1 && UserData
!= NULL
)
1036 DefaultLanguageIndex
= 0;
1037 wcscpy(DefaultLanguage
, UserData
);
1045 CreateKeyboardLayoutList(
1047 WCHAR
*DefaultKBLayout
)
1055 const MUI_LAYOUTS
* LayoutsList
;
1057 BOOL KeyboardLayoutsFound
= FALSE
;
1059 /* Get default layout id */
1060 if (!SetupFindFirstLineW (InfFile
, L
"NLS", L
"DefaultLayout", &Context
))
1063 if (!INF_GetData (&Context
, NULL
, &KeyValue
))
1066 wcscpy(DefaultKBLayout
, KeyValue
);
1068 List
= CreateGenericList();
1072 LayoutsList
= MUIGetLayoutsList();
1076 if (!SetupFindFirstLineW(InfFile
, L
"KeyboardLayout", NULL
, &Context
))
1078 DestroyGenericList(List
, FALSE
);
1084 if (!INF_GetData (&Context
, &KeyName
, &KeyValue
))
1086 /* FIXME: Handle error! */
1087 DPRINT("INF_GetData() failed\n");
1088 DestroyGenericList(List
, FALSE
);
1093 UserData
= (WCHAR
*)RtlAllocateHeap(ProcessHeap
,
1095 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
1096 if (UserData
== NULL
)
1098 /* FIXME: Handle error! */
1099 DPRINT("RtlAllocateHeap() failed\n");
1100 DestroyGenericList(List
, FALSE
);
1104 wcscpy(UserData
, KeyName
);
1106 sprintf(Buffer
, "%S", KeyValue
);
1107 AppendGenericListEntry(List
,
1110 _wcsicmp(KeyName
, DefaultKBLayout
) ? FALSE
: TRUE
);
1111 KeyboardLayoutsFound
= TRUE
;
1114 } while (SetupFindNextLine(&Context
, &Context
));
1118 } while (LayoutsList
[uIndex
].LangID
!= NULL
);
1120 /* FIXME: Handle this case */
1121 if (!KeyboardLayoutsFound
)
1123 DPRINT1("No keyboard layouts have been found\n");
1124 DestroyGenericList(List
, FALSE
);
1133 ProcessKeyboardLayoutRegistry(
1136 PGENERIC_LIST_ENTRY Entry
;
1138 const MUI_LAYOUTS
* LayoutsList
;
1139 MUI_LAYOUTS NewLayoutsList
[20];
1143 Entry
= GetCurrentListEntry(List
);
1147 LayoutId
= (PWCHAR
)GetListEntryUserData(Entry
);
1148 if (LayoutId
== NULL
)
1151 LayoutsList
= MUIGetLayoutsList();
1153 if (_wcsicmp(LayoutsList
[0].LayoutID
, LayoutId
) != 0)
1155 for (uIndex
= 1; LayoutsList
[uIndex
].LangID
!= NULL
; uIndex
++)
1157 if (_wcsicmp(LayoutsList
[uIndex
].LayoutID
, LayoutId
) == 0)
1163 NewLayoutsList
[uIndex
].LangID
= LayoutsList
[uIndex
].LangID
;
1164 NewLayoutsList
[uIndex
].LayoutID
= LayoutsList
[uIndex
].LayoutID
;
1167 NewLayoutsList
[uIndex
].LangID
= NULL
;
1168 NewLayoutsList
[uIndex
].LayoutID
= NULL
;
1169 NewLayoutsList
[uOldPos
].LangID
= LayoutsList
[0].LangID
;
1170 NewLayoutsList
[uOldPos
].LayoutID
= LayoutsList
[0].LayoutID
;
1171 NewLayoutsList
[0].LangID
= LayoutsList
[uOldPos
].LangID
;
1172 NewLayoutsList
[0].LayoutID
= LayoutsList
[uOldPos
].LayoutID
;
1174 return AddKbLayoutsToRegistry(NewLayoutsList
);
1183 ProcessKeyboardLayoutFiles(
1195 OBJECT_ATTRIBUTES ObjectAttributes
;
1196 UNICODE_STRING KeyName
;
1197 UNICODE_STRING ValueName
;
1199 WCHAR szKeyName
[] = L
"\\Registry\\User\\.DEFAULT\\Control Panel\\International\\Geo";
1200 WCHAR szValueName
[] = L
"Nation";
1203 RtlInitUnicodeString(&KeyName
,
1205 InitializeObjectAttributes(&ObjectAttributes
,
1207 OBJ_CASE_INSENSITIVE
,
1211 Status
= NtOpenKey(&KeyHandle
,
1214 if(!NT_SUCCESS(Status
))
1216 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status
);
1220 RtlInitUnicodeString(&ValueName
, szValueName
);
1221 Status
= NtSetValueKey(KeyHandle
,
1226 (wcslen(Id
) + 1) * sizeof(WCHAR
));
1228 if (!NT_SUCCESS(Status
))
1230 DPRINT1("NtSetValueKey() failed (Status = %lx)\n", Status
);