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: subsys/system/usetup/settings.c
22 * PURPOSE: Device settings support functions
23 * PROGRAMMERS: Eric Kohl
27 /* INCLUDES *****************************************************************/
34 /* FUNCTIONS ****************************************************************/
39 UNICODE_STRING MultiKeyPathU
= RTL_CONSTANT_STRING(L
"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter");
40 UNICODE_STRING IdentifierU
= RTL_CONSTANT_STRING(L
"Identifier");
41 UNICODE_STRING AcpiBiosIdentifier
= RTL_CONSTANT_STRING(L
"ACPI BIOS");
42 OBJECT_ATTRIBUTES ObjectAttributes
;
43 PKEY_BASIC_INFORMATION pDeviceInformation
= NULL
;
44 ULONG DeviceInfoLength
= sizeof(KEY_BASIC_INFORMATION
) + 50 * sizeof(WCHAR
);
45 PKEY_VALUE_PARTIAL_INFORMATION pValueInformation
= NULL
;
46 ULONG ValueInfoLength
= sizeof(KEY_VALUE_PARTIAL_INFORMATION
) + 50 * sizeof(WCHAR
);
48 ULONG IndexDevice
= 0;
49 UNICODE_STRING DeviceName
, ValueName
;
50 HANDLE hDevicesKey
= NULL
;
51 HANDLE hDeviceKey
= NULL
;
55 InitializeObjectAttributes(&ObjectAttributes
, &MultiKeyPathU
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
56 Status
= NtOpenKey(&hDevicesKey
, KEY_ENUMERATE_SUB_KEYS
, &ObjectAttributes
);
57 if (!NT_SUCCESS(Status
))
59 DPRINT("NtOpenKey() failed with status 0x%08lx\n", Status
);
63 pDeviceInformation
= RtlAllocateHeap(RtlGetProcessHeap(), 0, DeviceInfoLength
);
64 if (!pDeviceInformation
)
66 DPRINT("RtlAllocateHeap() failed\n");
67 Status
= STATUS_NO_MEMORY
;
71 pValueInformation
= RtlAllocateHeap(RtlGetProcessHeap(), 0, ValueInfoLength
);
72 if (!pDeviceInformation
)
74 DPRINT("RtlAllocateHeap() failed\n");
75 Status
= STATUS_NO_MEMORY
;
81 Status
= NtEnumerateKey(hDevicesKey
, IndexDevice
, KeyBasicInformation
, pDeviceInformation
, DeviceInfoLength
, &RequiredSize
);
82 if (Status
== STATUS_NO_MORE_ENTRIES
)
84 else if (Status
== STATUS_BUFFER_OVERFLOW
|| Status
== STATUS_BUFFER_TOO_SMALL
)
86 RtlFreeHeap(RtlGetProcessHeap(), 0, pDeviceInformation
);
87 DeviceInfoLength
= RequiredSize
;
88 pDeviceInformation
= RtlAllocateHeap(RtlGetProcessHeap(), 0, DeviceInfoLength
);
89 if (!pDeviceInformation
)
91 DPRINT("RtlAllocateHeap() failed\n");
92 Status
= STATUS_NO_MEMORY
;
95 Status
= NtEnumerateKey(hDevicesKey
, IndexDevice
, KeyBasicInformation
, pDeviceInformation
, DeviceInfoLength
, &RequiredSize
);
97 if (!NT_SUCCESS(Status
))
99 DPRINT("NtEnumerateKey() failed with status 0x%08lx\n", Status
);
104 /* Open device key */
105 DeviceName
.Length
= DeviceName
.MaximumLength
= pDeviceInformation
->NameLength
;
106 DeviceName
.Buffer
= pDeviceInformation
->Name
;
107 InitializeObjectAttributes(&ObjectAttributes
, &DeviceName
, OBJ_CASE_INSENSITIVE
, hDevicesKey
, NULL
);
112 if (!NT_SUCCESS(Status
))
114 DPRINT("NtOpenKey() failed with status 0x%08lx\n", Status
);
118 /* Read identifier */
119 Status
= NtQueryValueKey(hDeviceKey
, &IdentifierU
, KeyValuePartialInformation
, pValueInformation
, ValueInfoLength
, &RequiredSize
);
120 if (Status
== STATUS_BUFFER_OVERFLOW
|| Status
== STATUS_BUFFER_TOO_SMALL
)
122 RtlFreeHeap(RtlGetProcessHeap(), 0, pValueInformation
);
123 ValueInfoLength
= RequiredSize
;
124 pValueInformation
= RtlAllocateHeap(RtlGetProcessHeap(), 0, ValueInfoLength
);
125 if (!pValueInformation
)
127 DPRINT("RtlAllocateHeap() failed\n");
128 Status
= STATUS_NO_MEMORY
;
131 Status
= NtQueryValueKey(hDeviceKey
, &IdentifierU
, KeyValuePartialInformation
, pValueInformation
, ValueInfoLength
, &RequiredSize
);
133 if (!NT_SUCCESS(Status
))
135 DPRINT("NtQueryValueKey() failed with status 0x%08lx\n", Status
);
138 else if (pValueInformation
->Type
!= REG_SZ
)
140 DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation
->Type
, REG_SZ
);
144 ValueName
.Length
= ValueName
.MaximumLength
= pValueInformation
->DataLength
;
145 ValueName
.Buffer
= (PWCHAR
)pValueInformation
->Data
;
146 if (ValueName
.Length
>= sizeof(WCHAR
) && ValueName
.Buffer
[ValueName
.Length
/ sizeof(WCHAR
) - 1] == UNICODE_NULL
)
147 ValueName
.Length
-= sizeof(WCHAR
);
148 if (RtlCompareUnicodeString(&ValueName
, &AcpiBiosIdentifier
, FALSE
) == 0)
150 DPRINT("Found ACPI BIOS\n");
161 if (pDeviceInformation
)
162 RtlFreeHeap(RtlGetProcessHeap(), 0, pDeviceInformation
);
163 if (pValueInformation
)
164 RtlFreeHeap(RtlGetProcessHeap(), 0, pValueInformation
);
166 NtClose(hDevicesKey
);
174 GetComputerIdentifier(PWSTR Identifier
,
175 ULONG IdentifierLength
)
177 OBJECT_ATTRIBUTES ObjectAttributes
;
178 UNICODE_STRING KeyName
;
179 LPCWSTR ComputerIdentifier
;
180 HANDLE ProcessorsKey
;
181 PKEY_FULL_INFORMATION pFullInfo
;
182 ULONG Size
, SizeNeeded
;
185 DPRINT("GetComputerIdentifier() called\n");
187 Size
= sizeof(KEY_FULL_INFORMATION
);
188 pFullInfo
= (PKEY_FULL_INFORMATION
)RtlAllocateHeap(RtlGetProcessHeap(), 0, Size
);
191 DPRINT("RtlAllocateHeap() failed\n");
195 /* Open the processors key */
196 RtlInitUnicodeString(&KeyName
,
197 L
"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor");
198 InitializeObjectAttributes(&ObjectAttributes
,
200 OBJ_CASE_INSENSITIVE
,
204 Status
= NtOpenKey(&ProcessorsKey
,
207 if (!NT_SUCCESS(Status
))
209 DPRINT("NtOpenKey() failed (Status 0x%lx)\n", Status
);
210 RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo
);
214 /* Get number of subkeys */
221 NtClose(ProcessorsKey
);
223 if (!NT_SUCCESS(Status
) && Status
!= STATUS_BUFFER_OVERFLOW
)
225 DPRINT("NtQueryKey() failed (Status 0x%lx)\n", Status
);
226 RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo
);
230 /* Find computer identifier */
231 if (pFullInfo
->SubKeys
== 0)
233 /* Something strange happened. No processor detected */
234 RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo
);
238 if (IsAcpiComputer())
240 if (pFullInfo
->SubKeys
== 1)
242 /* Computer is mono-CPU */
243 ComputerIdentifier
= L
"ACPI UP";
247 /* Computer is multi-CPUs */
248 ComputerIdentifier
= L
"ACPI MP";
253 if (pFullInfo
->SubKeys
== 1)
255 /* Computer is mono-CPU */
256 ComputerIdentifier
= L
"PC UP";
260 /* Computer is multi-CPUs */
261 ComputerIdentifier
= L
"PC MP";
265 RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo
);
267 /* Copy computer identifier to return buffer */
268 SizeNeeded
= (wcslen(ComputerIdentifier
) + 1) * sizeof(WCHAR
);
269 if (SizeNeeded
> IdentifierLength
)
272 RtlCopyMemory(Identifier
, ComputerIdentifier
, SizeNeeded
);
279 CreateComputerTypeList(HINF InfFile
)
287 WCHAR ComputerIdentifier
[128];
288 WCHAR ComputerKey
[32];
290 /* Get the computer identification */
291 if (!GetComputerIdentifier(ComputerIdentifier
, 128))
293 ComputerIdentifier
[0] = 0;
296 DPRINT("Computer identifier: '%S'\n", ComputerIdentifier
);
298 /* Search for matching device identifier */
299 if (!SetupFindFirstLineW(InfFile
, L
"Map.Computer", NULL
, &Context
))
301 /* FIXME: error message */
307 if (!INF_GetDataField(&Context
, 1, &KeyValue
))
309 /* FIXME: Handle error! */
310 DPRINT("INF_GetDataField() failed\n");
314 DPRINT("KeyValue: %S\n", KeyValue
);
315 if (wcsstr(ComputerIdentifier
, KeyValue
))
317 if (!INF_GetDataField(&Context
, 0, &KeyName
))
319 /* FIXME: Handle error! */
320 DPRINT("INF_GetDataField() failed\n");
324 DPRINT("Computer key: %S\n", KeyName
);
325 wcscpy(ComputerKey
, KeyName
);
327 } while (SetupFindNextLine(&Context
, &Context
));
329 List
= CreateGenericList();
333 if (!SetupFindFirstLineW (InfFile
, L
"Computer", NULL
, &Context
))
335 DestroyGenericList(List
, FALSE
);
341 if (!INF_GetData (&Context
, &KeyName
, &KeyValue
))
343 /* FIXME: Handle error! */
344 DPRINT("INF_GetData() failed\n");
348 UserData
= (WCHAR
*) RtlAllocateHeap(ProcessHeap
,
350 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
351 if (UserData
== NULL
)
353 /* FIXME: Handle error! */
356 wcscpy(UserData
, KeyName
);
358 sprintf(Buffer
, "%S", KeyValue
);
359 AppendGenericListEntry(List
, Buffer
, UserData
,
360 _wcsicmp(KeyName
, ComputerKey
) ? FALSE
: TRUE
);
361 } while (SetupFindNextLine(&Context
, &Context
));
368 GetDisplayIdentifier(PWSTR Identifier
,
369 ULONG IdentifierLength
)
371 OBJECT_ATTRIBUTES ObjectAttributes
;
372 UNICODE_STRING KeyName
;
375 HANDLE BusInstanceKey
;
376 HANDLE ControllerKey
;
377 HANDLE ControllerInstanceKey
;
379 ULONG ControllerInstance
;
381 ULONG ReturnedLength
;
382 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
;
385 DPRINT("GetDisplayIdentifier() called\n");
387 /* Open the bus key */
388 RtlInitUnicodeString(&KeyName
,
389 L
"\\Registry\\Machine\\HARDWARE\\Description\\System\\MultifunctionAdapter");
390 InitializeObjectAttributes(&ObjectAttributes
,
392 OBJ_CASE_INSENSITIVE
,
396 Status
= NtOpenKey(&BusKey
,
397 KEY_ENUMERATE_SUB_KEYS
,
399 if (!NT_SUCCESS(Status
))
401 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
408 swprintf(Buffer
, L
"%lu", BusInstance
);
409 RtlInitUnicodeString(&KeyName
,
411 InitializeObjectAttributes(&ObjectAttributes
,
413 OBJ_CASE_INSENSITIVE
,
417 Status
= NtOpenKey(&BusInstanceKey
,
418 KEY_ENUMERATE_SUB_KEYS
,
420 if (!NT_SUCCESS(Status
))
422 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
427 /* Open the controller type key */
428 RtlInitUnicodeString(&KeyName
,
429 L
"DisplayController");
430 InitializeObjectAttributes(&ObjectAttributes
,
432 OBJ_CASE_INSENSITIVE
,
436 Status
= NtOpenKey(&ControllerKey
,
437 KEY_ENUMERATE_SUB_KEYS
,
439 if (NT_SUCCESS(Status
))
441 ControllerInstance
= 0;
445 /* Open the pointer controller instance key */
446 swprintf(Buffer
, L
"%lu", ControllerInstance
);
447 RtlInitUnicodeString(&KeyName
,
449 InitializeObjectAttributes(&ObjectAttributes
,
451 OBJ_CASE_INSENSITIVE
,
455 Status
= NtOpenKey(&ControllerInstanceKey
,
458 if (!NT_SUCCESS(Status
))
460 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
461 NtClose(ControllerKey
);
462 NtClose(BusInstanceKey
);
467 /* Get controller identifier */
468 RtlInitUnicodeString(&KeyName
,
471 BufferLength
= sizeof(KEY_VALUE_PARTIAL_INFORMATION
) +
473 ValueInfo
= (KEY_VALUE_PARTIAL_INFORMATION
*) RtlAllocateHeap(RtlGetProcessHeap(),
476 if (ValueInfo
== NULL
)
478 DPRINT("RtlAllocateHeap() failed\n");
479 NtClose(ControllerInstanceKey
);
480 NtClose(ControllerKey
);
481 NtClose(BusInstanceKey
);
486 Status
= NtQueryValueKey(ControllerInstanceKey
,
488 KeyValuePartialInformation
,
492 if (NT_SUCCESS(Status
))
494 DPRINT("Identifier: %S\n", (PWSTR
)ValueInfo
->Data
);
496 BufferLength
= min(ValueInfo
->DataLength
/ sizeof(WCHAR
), IdentifierLength
);
497 RtlCopyMemory (Identifier
,
499 BufferLength
* sizeof(WCHAR
));
500 Identifier
[BufferLength
] = 0;
502 RtlFreeHeap(RtlGetProcessHeap(),
506 NtClose(ControllerInstanceKey
);
507 NtClose(ControllerKey
);
508 NtClose(BusInstanceKey
);
513 NtClose(ControllerInstanceKey
);
515 ControllerInstance
++;
518 NtClose(ControllerKey
);
521 NtClose(BusInstanceKey
);
533 CreateDisplayDriverList(HINF InfFile
)
541 WCHAR DisplayIdentifier
[128];
542 WCHAR DisplayKey
[32];
544 /* Get the display identification */
545 if (!GetDisplayIdentifier(DisplayIdentifier
, 128))
547 DisplayIdentifier
[0] = 0;
550 DPRINT("Display identifier: '%S'\n", DisplayIdentifier
);
552 /* Search for matching device identifier */
553 if (!SetupFindFirstLineW(InfFile
, L
"Map.Display", NULL
, &Context
))
555 /* FIXME: error message */
561 if (!INF_GetDataField(&Context
, 1, &KeyValue
))
563 /* FIXME: Handle error! */
564 DPRINT("INF_GetDataField() failed\n");
568 DPRINT("KeyValue: %S\n", KeyValue
);
569 if (wcsstr(DisplayIdentifier
, KeyValue
))
571 if (!INF_GetDataField(&Context
, 0, &KeyName
))
573 /* FIXME: Handle error! */
574 DPRINT("INF_GetDataField() failed\n");
578 DPRINT("Display key: %S\n", KeyName
);
579 wcscpy(DisplayKey
, KeyName
);
581 } while (SetupFindNextLine(&Context
, &Context
));
583 List
= CreateGenericList();
587 if (!SetupFindFirstLineW (InfFile
, L
"Display", NULL
, &Context
))
589 DestroyGenericList(List
, FALSE
);
595 if (!INF_GetDataField(&Context
, 0, &KeyName
))
597 DPRINT1("INF_GetDataField() failed\n");
601 if (!INF_GetDataField(&Context
, 1, &KeyValue
))
603 DPRINT1("INF_GetDataField() failed\n");
607 UserData
= (WCHAR
*) RtlAllocateHeap(ProcessHeap
,
609 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
610 if (UserData
== NULL
)
612 DPRINT1("RtlAllocateHeap() failed\n");
613 DestroyGenericList(List
, TRUE
);
617 wcscpy(UserData
, KeyName
);
619 sprintf(Buffer
, "%S", KeyValue
);
620 AppendGenericListEntry(List
,
623 _wcsicmp(KeyName
, DisplayKey
) ? FALSE
: TRUE
);
624 } while (SetupFindNextLine(&Context
, &Context
));
627 AppendGenericListEntry(List
, "Other display driver", NULL
, TRUE
);
634 ProcessComputerFiles(HINF InfFile
, PGENERIC_LIST List
, PWCHAR
* AdditionalSectionName
)
636 PGENERIC_LIST_ENTRY Entry
;
637 static WCHAR SectionName
[128];
639 DPRINT("ProcessComputerFiles() called\n");
641 Entry
= GetCurrentListEntry(List
);
644 DPRINT("GetCurrentListEntry() failed\n");
648 wcscpy(SectionName
, L
"Files.");
649 wcscat(SectionName
, (const wchar_t*)GetListEntryUserData(Entry
));
650 *AdditionalSectionName
= SectionName
;
657 ProcessDisplayRegistry(HINF InfFile
, PGENERIC_LIST List
)
659 PGENERIC_LIST_ENTRY Entry
;
666 ULONG Width
, Height
, Bpp
;
668 DPRINT("ProcessDisplayRegistry() called\n");
670 Entry
= GetCurrentListEntry(List
);
673 DPRINT("GetCurrentListEntry() failed\n");
677 if (!SetupFindFirstLineW(InfFile
, L
"Display", (WCHAR
*)GetListEntryUserData(Entry
), &Context
))
679 DPRINT("SetupFindFirstLineW() failed\n");
683 /* Enable the right driver */
684 if (!INF_GetDataField(&Context
, 3, &ServiceName
))
686 DPRINT("INF_GetDataField() failed\n");
690 ASSERT(wcslen(ServiceName
) < 10);
691 DPRINT("Service name: %S\n", ServiceName
);
694 Status
= RtlWriteRegistryValue(RTL_REGISTRY_SERVICES
,
701 if (!NT_SUCCESS(Status
))
703 DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
707 /* Set the resolution */
708 swprintf(RegPath
, L
"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Services\\%s\\Device0", ServiceName
);
710 if (!INF_GetDataField(&Context
, 4, &Buffer
))
712 DPRINT("INF_GetDataField() failed\n");
716 Width
= wcstoul(Buffer
, NULL
, 10);
717 Status
= RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE
,
719 L
"DefaultSettings.XResolution",
723 if (!NT_SUCCESS(Status
))
725 DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
729 if (!INF_GetDataField(&Context
, 5, &Buffer
))
731 DPRINT("INF_GetDataField() failed\n");
735 Height
= wcstoul(Buffer
, 0, 0);
736 Status
= RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE
,
738 L
"DefaultSettings.YResolution",
742 if (!NT_SUCCESS(Status
))
744 DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
748 if (!INF_GetDataField(&Context
, 6, &Buffer
))
750 DPRINT("INF_GetDataField() failed\n");
754 Bpp
= wcstoul(Buffer
, 0, 0);
755 Status
= RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE
,
757 L
"DefaultSettings.BitsPerPel",
761 if (!NT_SUCCESS(Status
))
763 DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
767 DPRINT("ProcessDisplayRegistry() done\n");
774 ProcessLocaleRegistry(PGENERIC_LIST List
)
776 PGENERIC_LIST_ENTRY Entry
;
778 OBJECT_ATTRIBUTES ObjectAttributes
;
779 UNICODE_STRING KeyName
;
780 UNICODE_STRING ValueName
;
785 Entry
= GetCurrentListEntry(List
);
789 LanguageId
= (PWCHAR
)GetListEntryUserData(Entry
);
790 if (LanguageId
== NULL
)
793 /* Skip first 4 zeroes */
794 if (wcslen(LanguageId
) >= 4)
797 /* Open the NLS language key */
798 RtlInitUnicodeString(&KeyName
,
799 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language");
801 InitializeObjectAttributes(&ObjectAttributes
,
803 OBJ_CASE_INSENSITIVE
,
807 Status
= NtOpenKey(&KeyHandle
,
811 if (!NT_SUCCESS(Status
))
813 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status
);
817 /* Set default language */
818 RtlInitUnicodeString(&ValueName
,
820 Status
= NtSetValueKey(KeyHandle
,
825 (wcslen(LanguageId
) + 1) * sizeof(WCHAR
));
826 if (!NT_SUCCESS(Status
))
828 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
833 /* Set install language */
834 RtlInitUnicodeString(&ValueName
,
836 Status
= NtSetValueKey (KeyHandle
,
841 (wcslen(LanguageId
) + 1) * sizeof(WCHAR
));
843 if (!NT_SUCCESS(Status
))
845 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
854 CreateKeyboardDriverList(HINF InfFile
)
863 List
= CreateGenericList();
867 if (!SetupFindFirstLineW (InfFile
, L
"Keyboard", NULL
, &Context
))
869 DestroyGenericList(List
, FALSE
);
875 if (!INF_GetData (&Context
, &KeyName
, &KeyValue
))
877 /* FIXME: Handle error! */
878 DPRINT("INF_GetData() failed\n");
882 UserData
= (WCHAR
*) RtlAllocateHeap(ProcessHeap
,
884 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
885 if (UserData
== NULL
)
887 /* FIXME: Handle error! */
890 wcscpy(UserData
, KeyName
);
892 sprintf(Buffer
, "%S", KeyValue
);
893 AppendGenericListEntry(List
, Buffer
, UserData
, FALSE
);
894 } while (SetupFindNextLine(&Context
, &Context
));
899 ULONG DefaultLanguageIndex
= 0;
902 GetDefaultLanguageIndex(VOID
)
904 return DefaultLanguageIndex
;
908 CreateLanguageList(HINF InfFile
, WCHAR
* DefaultLanguage
)
915 PWCHAR UserData
= NULL
;
918 /* Get default language id */
919 if (!SetupFindFirstLineW (InfFile
, L
"NLS", L
"DefaultLanguage", &Context
))
922 if (!INF_GetData (&Context
, NULL
, &KeyValue
))
925 wcscpy(DefaultLanguage
, KeyValue
);
927 SelectedLanguageId
= KeyValue
;
929 List
= CreateGenericList();
933 if (!SetupFindFirstLineW (InfFile
, L
"Language", NULL
, &Context
))
935 DestroyGenericList(List
, FALSE
);
941 if (!INF_GetData (&Context
, &KeyName
, &KeyValue
))
943 /* FIXME: Handle error! */
944 DPRINT("INF_GetData() failed\n");
948 if (IsLanguageAvailable(KeyName
))
951 UserData
= (WCHAR
*) RtlAllocateHeap(ProcessHeap
,
953 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
954 if (UserData
== NULL
)
956 /* FIXME: Handle error! */
959 wcscpy(UserData
, KeyName
);
961 if (!_wcsicmp(KeyName
, DefaultLanguage
))
962 DefaultLanguageIndex
= uIndex
;
964 sprintf(Buffer
, "%S", KeyValue
);
965 AppendGenericListEntry(List
,
971 } while (SetupFindNextLine(&Context
, &Context
));
973 /* Only one language available, make it the default one */
974 if(uIndex
== 1 && UserData
!= NULL
)
976 DefaultLanguageIndex
= 0;
977 wcscpy(DefaultLanguage
, UserData
);
984 CreateKeyboardLayoutList(HINF InfFile
, WCHAR
* DefaultKBLayout
)
992 const MUI_LAYOUTS
* LayoutsList
;
994 BOOL KeyboardLayoutsFound
= FALSE
;
996 /* Get default layout id */
997 if (!SetupFindFirstLineW (InfFile
, L
"NLS", L
"DefaultLayout", &Context
))
1000 if (!INF_GetData (&Context
, NULL
, &KeyValue
))
1003 wcscpy(DefaultKBLayout
, KeyValue
);
1005 List
= CreateGenericList();
1009 LayoutsList
= MUIGetLayoutsList();
1013 if (!SetupFindFirstLineW(InfFile
, L
"KeyboardLayout", NULL
, &Context
))
1015 DestroyGenericList(List
, FALSE
);
1021 if (!INF_GetData (&Context
, &KeyName
, &KeyValue
))
1023 /* FIXME: Handle error! */
1024 DPRINT("INF_GetData() failed\n");
1025 DestroyGenericList(List
, FALSE
);
1029 if (_wcsicmp(LayoutsList
[uIndex
].LayoutID
, KeyName
) == 0)
1031 UserData
= (WCHAR
*) RtlAllocateHeap(ProcessHeap
,
1033 (wcslen(KeyName
) + 1) * sizeof(WCHAR
));
1035 if (UserData
== NULL
)
1037 /* FIXME: Handle error! */
1038 DPRINT("RtlAllocateHeap() failed\n");
1039 DestroyGenericList(List
, FALSE
);
1043 wcscpy(UserData
, KeyName
);
1045 sprintf(Buffer
, "%S", KeyValue
);
1046 AppendGenericListEntry(List
,
1049 _wcsicmp(KeyName
, DefaultKBLayout
) ? FALSE
: TRUE
);
1050 KeyboardLayoutsFound
= TRUE
;
1053 } while (SetupFindNextLine(&Context
, &Context
));
1057 } while (LayoutsList
[uIndex
].LangID
!= NULL
);
1059 /* FIXME: Handle this case */
1060 if (!KeyboardLayoutsFound
)
1062 DPRINT1("No keyboard layouts have been found\n");
1063 DestroyGenericList(List
, FALSE
);
1071 ProcessKeyboardLayoutRegistry(PGENERIC_LIST List
)
1073 PGENERIC_LIST_ENTRY Entry
;
1075 const MUI_LAYOUTS
* LayoutsList
;
1076 MUI_LAYOUTS NewLayoutsList
[20];
1080 Entry
= GetCurrentListEntry(List
);
1084 LayoutId
= (PWCHAR
)GetListEntryUserData(Entry
);
1085 if (LayoutId
== NULL
)
1088 LayoutsList
= MUIGetLayoutsList();
1090 if (_wcsicmp(LayoutsList
[0].LayoutID
, LayoutId
) != 0)
1092 for (uIndex
= 1; LayoutsList
[uIndex
].LangID
!= NULL
; uIndex
++)
1094 if (_wcsicmp(LayoutsList
[uIndex
].LayoutID
, LayoutId
) == 0)
1100 NewLayoutsList
[uIndex
].LangID
= LayoutsList
[uIndex
].LangID
;
1101 NewLayoutsList
[uIndex
].LayoutID
= LayoutsList
[uIndex
].LayoutID
;
1104 NewLayoutsList
[uIndex
].LangID
= NULL
;
1105 NewLayoutsList
[uIndex
].LayoutID
= NULL
;
1106 NewLayoutsList
[uOldPos
].LangID
= LayoutsList
[0].LangID
;
1107 NewLayoutsList
[uOldPos
].LayoutID
= LayoutsList
[0].LayoutID
;
1108 NewLayoutsList
[0].LangID
= LayoutsList
[uOldPos
].LangID
;
1109 NewLayoutsList
[0].LayoutID
= LayoutsList
[uOldPos
].LayoutID
;
1111 return AddKbLayoutsToRegistry(NewLayoutsList
);
1120 ProcessKeyboardLayoutFiles(PGENERIC_LIST List
)
1129 OBJECT_ATTRIBUTES ObjectAttributes
;
1130 UNICODE_STRING KeyName
;
1131 UNICODE_STRING ValueName
;
1133 WCHAR szKeyName
[] = L
"\\Registry\\User\\.DEFAULT\\Control Panel\\International\\Geo";
1134 WCHAR szValueName
[] = L
"Nation";
1136 RtlInitUnicodeString(&KeyName
,
1138 InitializeObjectAttributes(&ObjectAttributes
,
1140 OBJ_CASE_INSENSITIVE
,
1144 Status
= NtOpenKey(&KeyHandle
,
1147 if(!NT_SUCCESS(Status
))
1149 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status
);
1152 RtlInitUnicodeString(&ValueName
, szValueName
);
1153 Status
= NtSetValueKey(KeyHandle
,
1158 (wcslen(Id
) + 1) * sizeof(WCHAR
));
1160 if (!NT_SUCCESS(Status
))
1162 DPRINT1("NtSetValueKey() failed (Status = %lx)\n", Status
);