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 *****************************************************************/
39 /* GLOBALS ******************************************************************/
41 static ULONG DefaultLanguageIndex
= 0;
43 /* FUNCTIONS ****************************************************************/
49 UNICODE_STRING MultiKeyPathU
= RTL_CONSTANT_STRING(L
"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter");
50 UNICODE_STRING IdentifierU
= RTL_CONSTANT_STRING(L
"Identifier");
51 UNICODE_STRING AcpiBiosIdentifier
= RTL_CONSTANT_STRING(L
"ACPI BIOS");
52 OBJECT_ATTRIBUTES ObjectAttributes
;
53 PKEY_BASIC_INFORMATION pDeviceInformation
= NULL
;
54 ULONG DeviceInfoLength
= sizeof(KEY_BASIC_INFORMATION
) + 50 * sizeof(WCHAR
);
55 PKEY_VALUE_PARTIAL_INFORMATION pValueInformation
= NULL
;
56 ULONG ValueInfoLength
= sizeof(KEY_VALUE_PARTIAL_INFORMATION
) + 50 * sizeof(WCHAR
);
58 ULONG IndexDevice
= 0;
59 UNICODE_STRING DeviceName
, ValueName
;
60 HANDLE hDevicesKey
= NULL
;
61 HANDLE hDeviceKey
= NULL
;
65 InitializeObjectAttributes(&ObjectAttributes
,
70 Status
= NtOpenKey(&hDevicesKey
,
71 KEY_ENUMERATE_SUB_KEYS
,
73 if (!NT_SUCCESS(Status
))
75 DPRINT("NtOpenKey() failed with status 0x%08lx\n", Status
);
79 pDeviceInformation
= RtlAllocateHeap(RtlGetProcessHeap(), 0, DeviceInfoLength
);
80 if (!pDeviceInformation
)
82 DPRINT("RtlAllocateHeap() failed\n");
83 Status
= STATUS_NO_MEMORY
;
87 pValueInformation
= RtlAllocateHeap(RtlGetProcessHeap(), 0, ValueInfoLength
);
88 if (!pValueInformation
)
90 DPRINT("RtlAllocateHeap() failed\n");
91 Status
= STATUS_NO_MEMORY
;
97 Status
= NtEnumerateKey(hDevicesKey
,
103 if (Status
== STATUS_NO_MORE_ENTRIES
)
105 else if (Status
== STATUS_BUFFER_OVERFLOW
|| Status
== STATUS_BUFFER_TOO_SMALL
)
107 RtlFreeHeap(RtlGetProcessHeap(), 0, pDeviceInformation
);
108 DeviceInfoLength
= RequiredSize
;
109 pDeviceInformation
= RtlAllocateHeap(RtlGetProcessHeap(), 0, DeviceInfoLength
);
110 if (!pDeviceInformation
)
112 DPRINT("RtlAllocateHeap() failed\n");
113 Status
= STATUS_NO_MEMORY
;
116 Status
= NtEnumerateKey(hDevicesKey
,
123 if (!NT_SUCCESS(Status
))
125 DPRINT("NtEnumerateKey() failed with status 0x%08lx\n", Status
);
130 /* Open device key */
131 DeviceName
.Length
= DeviceName
.MaximumLength
= pDeviceInformation
->NameLength
;
132 DeviceName
.Buffer
= pDeviceInformation
->Name
;
133 InitializeObjectAttributes(&ObjectAttributes
,
135 OBJ_CASE_INSENSITIVE
,
138 Status
= NtOpenKey(&hDeviceKey
,
141 if (!NT_SUCCESS(Status
))
143 DPRINT("NtOpenKey() failed with status 0x%08lx\n", Status
);
147 /* Read identifier */
148 Status
= NtQueryValueKey(hDeviceKey
,
150 KeyValuePartialInformation
,
154 if (Status
== STATUS_BUFFER_OVERFLOW
|| Status
== STATUS_BUFFER_TOO_SMALL
)
156 RtlFreeHeap(RtlGetProcessHeap(), 0, pValueInformation
);
157 ValueInfoLength
= RequiredSize
;
158 pValueInformation
= RtlAllocateHeap(RtlGetProcessHeap(), 0, ValueInfoLength
);
159 if (!pValueInformation
)
161 DPRINT("RtlAllocateHeap() failed\n");
162 Status
= STATUS_NO_MEMORY
;
165 Status
= NtQueryValueKey(hDeviceKey
,
167 KeyValuePartialInformation
,
172 if (!NT_SUCCESS(Status
))
174 DPRINT("NtQueryValueKey() failed with status 0x%08lx\n", Status
);
177 else if (pValueInformation
->Type
!= REG_SZ
)
179 DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation
->Type
, REG_SZ
);
183 ValueName
.Length
= ValueName
.MaximumLength
= pValueInformation
->DataLength
;
184 ValueName
.Buffer
= (PWCHAR
)pValueInformation
->Data
;
185 if (ValueName
.Length
>= sizeof(WCHAR
) && ValueName
.Buffer
[ValueName
.Length
/ sizeof(WCHAR
) - 1] == UNICODE_NULL
)
186 ValueName
.Length
-= sizeof(WCHAR
);
187 if (RtlEqualUnicodeString(&ValueName
, &AcpiBiosIdentifier
, FALSE
))
189 DPRINT("Found ACPI BIOS\n");
200 if (pDeviceInformation
)
201 RtlFreeHeap(RtlGetProcessHeap(), 0, pDeviceInformation
);
202 if (pValueInformation
)
203 RtlFreeHeap(RtlGetProcessHeap(), 0, pValueInformation
);
205 NtClose(hDevicesKey
);
213 GetComputerIdentifier(
214 OUT PWSTR Identifier
,
215 IN ULONG IdentifierLength
)
217 OBJECT_ATTRIBUTES ObjectAttributes
;
218 UNICODE_STRING KeyName
;
219 LPCWSTR ComputerIdentifier
;
220 HANDLE ProcessorsKey
;
221 PKEY_FULL_INFORMATION pFullInfo
;
222 ULONG Size
, SizeNeeded
;
225 DPRINT("GetComputerIdentifier() called\n");
227 Size
= sizeof(KEY_FULL_INFORMATION
);
228 pFullInfo
= (PKEY_FULL_INFORMATION
)RtlAllocateHeap(RtlGetProcessHeap(), 0, Size
);
231 DPRINT("RtlAllocateHeap() failed\n");
235 /* Open the processors key */
236 RtlInitUnicodeString(&KeyName
,
237 L
"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor");
238 InitializeObjectAttributes(&ObjectAttributes
,
240 OBJ_CASE_INSENSITIVE
,
244 Status
= NtOpenKey(&ProcessorsKey
,
247 if (!NT_SUCCESS(Status
))
249 DPRINT("NtOpenKey() failed (Status 0x%lx)\n", Status
);
250 RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo
);
254 /* Get number of subkeys */
255 Status
= NtQueryKey(ProcessorsKey
,
260 NtClose(ProcessorsKey
);
261 if (!NT_SUCCESS(Status
) && Status
!= STATUS_BUFFER_OVERFLOW
)
263 DPRINT("NtQueryKey() failed (Status 0x%lx)\n", Status
);
264 RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo
);
268 /* Find computer identifier */
269 if (pFullInfo
->SubKeys
== 0)
271 /* Something strange happened. No processor detected */
272 RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo
);
276 if (IsAcpiComputer())
278 if (pFullInfo
->SubKeys
== 1)
280 /* Computer is mono-CPU */
281 ComputerIdentifier
= L
"ACPI UP";
285 /* Computer is multi-CPUs */
286 ComputerIdentifier
= L
"ACPI MP";
291 if (pFullInfo
->SubKeys
== 1)
293 /* Computer is mono-CPU */
294 ComputerIdentifier
= L
"PC UP";
298 /* Computer is multi-CPUs */
299 ComputerIdentifier
= L
"PC MP";
303 RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo
);
305 /* Copy computer identifier to return buffer */
306 SizeNeeded
= (wcslen(ComputerIdentifier
) + 1) * sizeof(WCHAR
);
307 if (SizeNeeded
> IdentifierLength
)
310 RtlCopyMemory(Identifier
, ComputerIdentifier
, SizeNeeded
);
318 * 0x00: Failure, stop the enumeration;
319 * 0x01: Add the entry and continue the enumeration;
320 * 0x02: Skip the entry but continue the enumeration.
323 (NTAPI
*PPROCESS_ENTRY_ROUTINE
)(
327 OUT PBOOLEAN Current
,
328 IN PVOID Parameter OPTIONAL
);
331 AddEntriesFromInfSection(
332 IN OUT PGENERIC_LIST List
,
334 IN PCWSTR SectionName
,
335 IN PINFCONTEXT pContext
,
336 IN PPROCESS_ENTRY_ROUTINE ProcessEntry
,
337 IN PVOID Parameter OPTIONAL
)
346 if (!SpInfFindFirstLine(InfFile
, SectionName
, NULL
, pContext
))
352 * NOTE: Do not use INF_GetData() as it expects INF entries of exactly
353 * two fields ("key = value"); however we expect to be able to deal with
354 * entries having more than two fields, the only requirement being that
355 * the second field (field number 1) contains the field description.
357 if (!INF_GetDataField(pContext
, 0, &KeyName
))
359 DPRINT("INF_GetDataField() failed\n");
363 if (!INF_GetDataField(pContext
, 1, &KeyValue
))
365 DPRINT("INF_GetDataField() failed\n");
366 INF_FreeData(KeyName
);
372 RetVal
= ProcessEntry(KeyName
,
377 INF_FreeData(KeyName
);
378 INF_FreeData(KeyValue
);
382 DPRINT("ProcessEntry() failed\n");
385 else if (RetVal
== 1)
387 AppendGenericListEntry(List
, UserData
, Current
);
390 // else if (RetVal == 2), skip the entry.
392 } while (SpInfFindNextLine(pContext
, pContext
));
403 OUT PBOOLEAN Current
,
404 IN PVOID Parameter OPTIONAL
)
406 PWSTR CompareKey
= (PWSTR
)Parameter
;
409 SIZE_T IdSize
, ValueSize
;
411 IdSize
= (wcslen(KeyName
) + 1) * sizeof(WCHAR
);
412 ValueSize
= (wcslen(KeyValue
) + 1) * sizeof(WCHAR
);
414 GenEntry
= RtlAllocateHeap(ProcessHeap
, 0,
415 sizeof(*GenEntry
) + IdSize
+ ValueSize
);
416 if (GenEntry
== NULL
)
418 /* Failure, stop enumeration */
419 DPRINT1("RtlAllocateHeap() failed\n");
423 GenEntry
->Id
= (PCWSTR
)((ULONG_PTR
)GenEntry
+ sizeof(*GenEntry
));
424 GenEntry
->Value
= (PCWSTR
)((ULONG_PTR
)GenEntry
+ sizeof(*GenEntry
) + IdSize
);
425 RtlStringCbCopyW((PWSTR
)GenEntry
->Id
, IdSize
, KeyName
);
426 RtlStringCbCopyW((PWSTR
)GenEntry
->Value
, ValueSize
, KeyValue
);
428 *UserData
= GenEntry
;
429 *Current
= (CompareKey
? !_wcsicmp(KeyName
, CompareKey
) : FALSE
);
437 CreateComputerTypeList(
444 WCHAR ComputerIdentifier
[128];
445 WCHAR ComputerKey
[32];
447 /* Get the computer identification */
448 if (!GetComputerIdentifier(ComputerIdentifier
, 128))
450 ComputerIdentifier
[0] = 0;
453 DPRINT("Computer identifier: '%S'\n", ComputerIdentifier
);
455 /* Search for matching device identifier */
456 if (!SpInfFindFirstLine(InfFile
, L
"Map.Computer", NULL
, &Context
))
458 /* FIXME: error message */
466 if (!INF_GetDataField(&Context
, 1, &KeyValue
))
468 /* FIXME: Handle error! */
469 DPRINT("INF_GetDataField() failed\n");
473 DPRINT("KeyValue: %S\n", KeyValue
);
474 FoundId
= !!wcsstr(ComputerIdentifier
, KeyValue
);
475 INF_FreeData(KeyValue
);
480 if (!INF_GetDataField(&Context
, 0, &KeyName
))
482 /* FIXME: Handle error! */
483 DPRINT("INF_GetDataField() failed\n");
487 DPRINT("Computer key: %S\n", KeyName
);
488 RtlStringCchCopyW(ComputerKey
, ARRAYSIZE(ComputerKey
), KeyName
);
489 INF_FreeData(KeyName
);
490 } while (SpInfFindNextLine(&Context
, &Context
));
492 List
= CreateGenericList();
496 if (AddEntriesFromInfSection(List
,
503 DestroyGenericList(List
, TRUE
);
512 GetDisplayIdentifier(
513 OUT PWSTR Identifier
,
514 IN ULONG IdentifierLength
)
516 OBJECT_ATTRIBUTES ObjectAttributes
;
517 UNICODE_STRING KeyName
;
520 HANDLE BusInstanceKey
;
521 HANDLE ControllerKey
;
522 HANDLE ControllerInstanceKey
;
524 ULONG ControllerInstance
;
526 ULONG ReturnedLength
;
527 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
;
530 DPRINT("GetDisplayIdentifier() called\n");
532 /* Open the bus key */
533 RtlInitUnicodeString(&KeyName
,
534 L
"\\Registry\\Machine\\HARDWARE\\Description\\System\\MultifunctionAdapter");
535 InitializeObjectAttributes(&ObjectAttributes
,
537 OBJ_CASE_INSENSITIVE
,
541 Status
= NtOpenKey(&BusKey
,
542 KEY_ENUMERATE_SUB_KEYS
,
544 if (!NT_SUCCESS(Status
))
546 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
553 RtlStringCchPrintfW(Buffer
, ARRAYSIZE(Buffer
), L
"%lu", BusInstance
);
554 RtlInitUnicodeString(&KeyName
, Buffer
);
555 InitializeObjectAttributes(&ObjectAttributes
,
557 OBJ_CASE_INSENSITIVE
,
561 Status
= NtOpenKey(&BusInstanceKey
,
562 KEY_ENUMERATE_SUB_KEYS
,
564 if (!NT_SUCCESS(Status
))
566 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
571 /* Open the controller type key */
572 RtlInitUnicodeString(&KeyName
, L
"DisplayController");
573 InitializeObjectAttributes(&ObjectAttributes
,
575 OBJ_CASE_INSENSITIVE
,
579 Status
= NtOpenKey(&ControllerKey
,
580 KEY_ENUMERATE_SUB_KEYS
,
582 if (NT_SUCCESS(Status
))
584 ControllerInstance
= 0;
588 /* Open the pointer controller instance key */
589 RtlStringCchPrintfW(Buffer
, ARRAYSIZE(Buffer
), L
"%lu", ControllerInstance
);
590 RtlInitUnicodeString(&KeyName
, Buffer
);
591 InitializeObjectAttributes(&ObjectAttributes
,
593 OBJ_CASE_INSENSITIVE
,
597 Status
= NtOpenKey(&ControllerInstanceKey
,
600 if (!NT_SUCCESS(Status
))
602 DPRINT("NtOpenKey() failed (Status %lx)\n", Status
);
603 NtClose(ControllerKey
);
604 NtClose(BusInstanceKey
);
609 /* Get controller identifier */
610 RtlInitUnicodeString(&KeyName
, L
"Identifier");
612 BufferLength
= sizeof(KEY_VALUE_PARTIAL_INFORMATION
) +
614 ValueInfo
= (KEY_VALUE_PARTIAL_INFORMATION
*) RtlAllocateHeap(RtlGetProcessHeap(),
617 if (ValueInfo
== NULL
)
619 DPRINT("RtlAllocateHeap() failed\n");
620 NtClose(ControllerInstanceKey
);
621 NtClose(ControllerKey
);
622 NtClose(BusInstanceKey
);
627 Status
= NtQueryValueKey(ControllerInstanceKey
,
629 KeyValuePartialInformation
,
633 if (NT_SUCCESS(Status
))
635 DPRINT("Identifier: %S\n", (PWSTR
)ValueInfo
->Data
);
637 BufferLength
= min(ValueInfo
->DataLength
/ sizeof(WCHAR
), IdentifierLength
);
638 RtlCopyMemory(Identifier
,
640 BufferLength
* sizeof(WCHAR
));
641 Identifier
[BufferLength
] = 0;
643 RtlFreeHeap(RtlGetProcessHeap(),
647 NtClose(ControllerInstanceKey
);
648 NtClose(ControllerKey
);
649 NtClose(BusInstanceKey
);
654 NtClose(ControllerInstanceKey
);
656 ControllerInstance
++;
659 NtClose(ControllerKey
);
662 NtClose(BusInstanceKey
);
673 CreateDisplayDriverList(
680 WCHAR DisplayIdentifier
[128];
681 WCHAR DisplayKey
[32];
683 /* Get the display identification */
684 if (!GetDisplayIdentifier(DisplayIdentifier
, 128))
686 DisplayIdentifier
[0] = 0;
689 DPRINT("Display identifier: '%S'\n", DisplayIdentifier
);
691 /* Search for matching device identifier */
692 if (!SpInfFindFirstLine(InfFile
, L
"Map.Display", NULL
, &Context
))
694 /* FIXME: error message */
702 if (!INF_GetDataField(&Context
, 1, &KeyValue
))
704 /* FIXME: Handle error! */
705 DPRINT("INF_GetDataField() failed\n");
709 DPRINT("KeyValue: %S\n", KeyValue
);
710 FoundId
= !!wcsstr(DisplayIdentifier
, KeyValue
);
711 INF_FreeData(KeyValue
);
716 if (!INF_GetDataField(&Context
, 0, &KeyName
))
718 /* FIXME: Handle error! */
719 DPRINT("INF_GetDataField() failed\n");
723 DPRINT("Display key: %S\n", KeyName
);
724 RtlStringCchCopyW(DisplayKey
, ARRAYSIZE(DisplayKey
), KeyName
);
725 INF_FreeData(KeyName
);
726 } while (SpInfFindNextLine(&Context
, &Context
));
728 List
= CreateGenericList();
732 if (AddEntriesFromInfSection(List
,
739 DestroyGenericList(List
, TRUE
);
744 AppendGenericListEntry(List
, L
"Other display driver", NULL
, TRUE
);
752 ProcessComputerFiles(
754 IN PGENERIC_LIST List
,
755 OUT PWSTR
* AdditionalSectionName
)
757 PGENERIC_LIST_ENTRY Entry
;
758 static WCHAR SectionName
[128];
760 DPRINT("ProcessComputerFiles() called\n");
762 Entry
= GetCurrentListEntry(List
);
766 RtlStringCchPrintfW(SectionName
, ARRAYSIZE(SectionName
),
767 L
"Files.%s", ((PGENENTRY
)GetListEntryData(Entry
))->Id
);
768 *AdditionalSectionName
= SectionName
;
774 ProcessDisplayRegistry(
776 IN PGENERIC_LIST List
)
779 PGENERIC_LIST_ENTRY Entry
;
784 ULONG Width
, Height
, Bpp
;
785 OBJECT_ATTRIBUTES ObjectAttributes
;
786 UNICODE_STRING KeyName
;
790 DPRINT("ProcessDisplayRegistry() called\n");
792 Entry
= GetCurrentListEntry(List
);
796 if (!SpInfFindFirstLine(InfFile
, L
"Display",
797 ((PGENENTRY
)GetListEntryData(Entry
))->Id
,
800 DPRINT1("SpInfFindFirstLine() failed\n");
804 /* Enable the correct driver */
805 if (!INF_GetDataField(&Context
, 3, &ServiceName
))
807 DPRINT1("INF_GetDataField() failed\n");
811 ASSERT(wcslen(ServiceName
) < 10);
812 DPRINT("Service name: '%S'\n", ServiceName
);
814 RtlStringCchPrintfW(RegPath
, ARRAYSIZE(RegPath
),
815 L
"System\\CurrentControlSet\\Services\\%s",
817 RtlInitUnicodeString(&KeyName
, RegPath
);
818 InitializeObjectAttributes(&ObjectAttributes
,
820 OBJ_CASE_INSENSITIVE
,
821 GetRootKeyByPredefKey(HKEY_LOCAL_MACHINE
, NULL
),
823 Status
= NtOpenKey(&KeyHandle
,
826 if (!NT_SUCCESS(Status
))
828 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status
);
833 Status
= RtlWriteRegistryValue(RTL_REGISTRY_HANDLE
, KeyHandle
,
839 if (!NT_SUCCESS(Status
))
841 DPRINT1("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
845 /* Set the resolution */
847 if (!INF_GetDataField(&Context
, 4, &Buffer
))
849 DPRINT1("INF_GetDataField() failed\n");
853 RtlStringCchPrintfW(RegPath
, ARRAYSIZE(RegPath
),
854 L
"System\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Services\\%s\\Device0",
856 DPRINT("RegPath: '%S'\n", RegPath
);
857 RtlInitUnicodeString(&KeyName
, RegPath
);
858 InitializeObjectAttributes(&ObjectAttributes
,
860 OBJ_CASE_INSENSITIVE
,
861 GetRootKeyByPredefKey(HKEY_LOCAL_MACHINE
, NULL
),
863 Status
= NtOpenKey(&KeyHandle
,
866 if (!NT_SUCCESS(Status
))
868 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status
);
872 Width
= wcstoul(Buffer
, NULL
, 10);
873 Status
= RtlWriteRegistryValue(RTL_REGISTRY_HANDLE
, KeyHandle
,
874 L
"DefaultSettings.XResolution",
878 if (!NT_SUCCESS(Status
))
880 DPRINT1("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
885 if (!INF_GetDataField(&Context
, 5, &Buffer
))
887 DPRINT1("INF_GetDataField() failed\n");
892 Height
= wcstoul(Buffer
, 0, 0);
893 Status
= RtlWriteRegistryValue(RTL_REGISTRY_HANDLE
, KeyHandle
,
894 L
"DefaultSettings.YResolution",
898 if (!NT_SUCCESS(Status
))
900 DPRINT1("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
905 if (!INF_GetDataField(&Context
, 6, &Buffer
))
907 DPRINT1("INF_GetDataField() failed\n");
912 Bpp
= wcstoul(Buffer
, 0, 0);
913 Status
= RtlWriteRegistryValue(RTL_REGISTRY_HANDLE
, KeyHandle
,
914 L
"DefaultSettings.BitsPerPel",
918 if (!NT_SUCCESS(Status
))
920 DPRINT1("RtlWriteRegistryValue() failed (Status %lx)\n", Status
);
927 DPRINT("ProcessDisplayRegistry() done\n");
933 ProcessLocaleRegistry(
934 IN PGENERIC_LIST List
)
936 PGENERIC_LIST_ENTRY Entry
;
938 OBJECT_ATTRIBUTES ObjectAttributes
;
939 UNICODE_STRING KeyName
;
940 UNICODE_STRING ValueName
;
945 Entry
= GetCurrentListEntry(List
);
949 LanguageId
= ((PGENENTRY
)GetListEntryData(Entry
))->Id
;
950 if (LanguageId
== NULL
)
953 DPRINT("LanguageId: %S\n", LanguageId
);
955 /* Open the default users locale key */
956 RtlInitUnicodeString(&KeyName
,
957 L
".DEFAULT\\Control Panel\\International");
959 InitializeObjectAttributes(&ObjectAttributes
,
961 OBJ_CASE_INSENSITIVE
,
962 GetRootKeyByPredefKey(HKEY_USERS
, NULL
),
965 Status
= NtOpenKey(&KeyHandle
,
968 if (!NT_SUCCESS(Status
))
970 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status
);
974 /* Set default user locale */
975 RtlInitUnicodeString(&ValueName
, L
"Locale");
976 Status
= NtSetValueKey(KeyHandle
,
981 (wcslen(LanguageId
) + 1) * sizeof(WCHAR
));
983 if (!NT_SUCCESS(Status
))
985 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
989 /* Skip first 4 zeroes */
990 if (wcslen(LanguageId
) >= 4)
993 /* Open the NLS language key */
994 RtlInitUnicodeString(&KeyName
,
995 L
"SYSTEM\\CurrentControlSet\\Control\\NLS\\Language");
997 InitializeObjectAttributes(&ObjectAttributes
,
999 OBJ_CASE_INSENSITIVE
,
1000 GetRootKeyByPredefKey(HKEY_LOCAL_MACHINE
, NULL
),
1003 Status
= NtOpenKey(&KeyHandle
,
1006 if (!NT_SUCCESS(Status
))
1008 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status
);
1012 /* Set default language */
1013 RtlInitUnicodeString(&ValueName
, L
"Default");
1014 Status
= NtSetValueKey(KeyHandle
,
1019 (wcslen(LanguageId
) + 1) * sizeof(WCHAR
));
1020 if (!NT_SUCCESS(Status
))
1022 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
1027 /* Set install language */
1028 RtlInitUnicodeString(&ValueName
, L
"InstallLanguage");
1029 Status
= NtSetValueKey(KeyHandle
,
1034 (wcslen(LanguageId
) + 1) * sizeof(WCHAR
));
1036 if (!NT_SUCCESS(Status
))
1038 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
1047 CreateKeyboardDriverList(
1053 List
= CreateGenericList();
1057 if (AddEntriesFromInfSection(List
,
1061 DefaultProcessEntry
,
1064 DestroyGenericList(List
, TRUE
);
1073 GetDefaultLanguageIndex(VOID
)
1075 return DefaultLanguageIndex
;
1078 typedef struct _LANG_ENTRY_PARAM
1081 PWCHAR DefaultLanguage
;
1082 } LANG_ENTRY_PARAM
, *PLANG_ENTRY_PARAM
;
1089 OUT PVOID
* UserData
,
1090 OUT PBOOLEAN Current
,
1091 IN PVOID Parameter OPTIONAL
)
1093 PLANG_ENTRY_PARAM LangEntryParam
= (PLANG_ENTRY_PARAM
)Parameter
;
1096 SIZE_T IdSize
, ValueSize
;
1098 if (!IsLanguageAvailable(KeyName
))
1100 /* The specified language is unavailable, skip the entry */
1104 IdSize
= (wcslen(KeyName
) + 1) * sizeof(WCHAR
);
1105 ValueSize
= (wcslen(KeyValue
) + 1) * sizeof(WCHAR
);
1107 GenEntry
= RtlAllocateHeap(ProcessHeap
, 0,
1108 sizeof(*GenEntry
) + IdSize
+ ValueSize
);
1109 if (GenEntry
== NULL
)
1111 /* Failure, stop enumeration */
1112 DPRINT1("RtlAllocateHeap() failed\n");
1116 GenEntry
->Id
= (PCWSTR
)((ULONG_PTR
)GenEntry
+ sizeof(*GenEntry
));
1117 GenEntry
->Value
= (PCWSTR
)((ULONG_PTR
)GenEntry
+ sizeof(*GenEntry
) + IdSize
);
1118 RtlStringCbCopyW((PWSTR
)GenEntry
->Id
, IdSize
, KeyName
);
1119 RtlStringCbCopyW((PWSTR
)GenEntry
->Value
, ValueSize
, KeyValue
);
1121 *UserData
= GenEntry
;
1124 if (!_wcsicmp(KeyName
, LangEntryParam
->DefaultLanguage
))
1125 DefaultLanguageIndex
= LangEntryParam
->uIndex
;
1127 LangEntryParam
->uIndex
++;
1136 OUT PWSTR DefaultLanguage
)
1142 LANG_ENTRY_PARAM LangEntryParam
;
1144 LangEntryParam
.uIndex
= 0;
1145 LangEntryParam
.DefaultLanguage
= DefaultLanguage
;
1147 /* Get default language id */
1148 if (!SpInfFindFirstLine(InfFile
, L
"NLS", L
"DefaultLanguage", &Context
))
1151 if (!INF_GetData(&Context
, NULL
, &KeyValue
))
1154 wcscpy(DefaultLanguage
, KeyValue
);
1156 List
= CreateGenericList();
1160 if (AddEntriesFromInfSection(List
,
1165 &LangEntryParam
) == -1)
1167 DestroyGenericList(List
, TRUE
);
1171 /* Only one language available, make it the default one */
1172 if (LangEntryParam
.uIndex
== 1)
1174 DefaultLanguageIndex
= 0;
1175 wcscpy(DefaultLanguage
,
1176 ((PGENENTRY
)GetListEntryData(GetFirstListEntry(List
)))->Id
);
1184 CreateKeyboardLayoutList(
1186 IN PCWSTR LanguageId
,
1187 OUT PWSTR DefaultKBLayout
)
1192 const MUI_LAYOUTS
* LayoutsList
;
1195 /* Get default layout id */
1196 if (!SpInfFindFirstLine(InfFile
, L
"NLS", L
"DefaultLayout", &Context
))
1199 if (!INF_GetData(&Context
, NULL
, &KeyValue
))
1202 wcscpy(DefaultKBLayout
, KeyValue
);
1204 List
= CreateGenericList();
1208 LayoutsList
= MUIGetLayoutsList(LanguageId
);
1212 // NOTE: See https://svn.reactos.org/svn/reactos?view=revision&revision=68354
1213 if (AddEntriesFromInfSection(List
,
1217 DefaultProcessEntry
,
1218 DefaultKBLayout
) == -1)
1220 DestroyGenericList(List
, TRUE
);
1226 } while (LayoutsList
[uIndex
].LangID
!= NULL
);
1228 /* Check whether some keyboard layouts have been found */
1229 /* FIXME: Handle this case */
1230 if (GetNumberOfListEntries(List
) == 0)
1232 DPRINT1("No keyboard layouts have been found\n");
1233 DestroyGenericList(List
, TRUE
);
1242 ProcessKeyboardLayoutRegistry(
1243 IN PGENERIC_LIST List
,
1244 IN PCWSTR LanguageId
)
1246 PGENERIC_LIST_ENTRY Entry
;
1248 const MUI_LAYOUTS
* LayoutsList
;
1249 MUI_LAYOUTS NewLayoutsList
[20];
1253 Entry
= GetCurrentListEntry(List
);
1257 LayoutId
= ((PGENENTRY
)GetListEntryData(Entry
))->Id
;
1258 if (LayoutId
== NULL
)
1261 LayoutsList
= MUIGetLayoutsList(LanguageId
);
1263 if (_wcsicmp(LayoutsList
[0].LayoutID
, LayoutId
) == 0)
1266 for (uIndex
= 1; LayoutsList
[uIndex
].LangID
!= NULL
; uIndex
++)
1268 if (_wcsicmp(LayoutsList
[uIndex
].LayoutID
, LayoutId
) == 0)
1274 NewLayoutsList
[uIndex
].LangID
= LayoutsList
[uIndex
].LangID
;
1275 NewLayoutsList
[uIndex
].LayoutID
= LayoutsList
[uIndex
].LayoutID
;
1278 NewLayoutsList
[uIndex
].LangID
= NULL
;
1279 NewLayoutsList
[uIndex
].LayoutID
= NULL
;
1280 NewLayoutsList
[uOldPos
].LangID
= LayoutsList
[0].LangID
;
1281 NewLayoutsList
[uOldPos
].LayoutID
= LayoutsList
[0].LayoutID
;
1282 NewLayoutsList
[0].LangID
= LayoutsList
[uOldPos
].LangID
;
1283 NewLayoutsList
[0].LayoutID
= LayoutsList
[uOldPos
].LayoutID
;
1285 return AddKbLayoutsToRegistry(NewLayoutsList
);
1290 ProcessKeyboardLayoutFiles(
1291 IN PGENERIC_LIST List
)
1302 OBJECT_ATTRIBUTES ObjectAttributes
;
1303 UNICODE_STRING Name
;
1306 RtlInitUnicodeString(&Name
,
1307 L
".DEFAULT\\Control Panel\\International\\Geo");
1308 InitializeObjectAttributes(&ObjectAttributes
,
1310 OBJ_CASE_INSENSITIVE
,
1311 GetRootKeyByPredefKey(HKEY_USERS
, NULL
),
1313 Status
= NtOpenKey(&KeyHandle
,
1316 if (!NT_SUCCESS(Status
))
1318 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status
);
1322 RtlInitUnicodeString(&Name
, L
"Nation");
1323 Status
= NtSetValueKey(KeyHandle
,
1328 (wcslen(Id
) + 1) * sizeof(WCHAR
));
1330 if (!NT_SUCCESS(Status
))
1332 DPRINT1("NtSetValueKey() failed (Status = %lx)\n", Status
);
1346 OBJECT_ATTRIBUTES ObjectAttributes
;
1347 UNICODE_STRING KeyName
= RTL_CONSTANT_STRING(L
"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management");
1348 UNICODE_STRING ValueName
= RTL_CONSTANT_STRING(L
"PagingFiles");
1349 WCHAR ValueBuffer
[] = L
"?:\\pagefile.sys 0 0\0";
1351 InitializeObjectAttributes(&ObjectAttributes
,
1353 OBJ_CASE_INSENSITIVE
,
1354 GetRootKeyByPredefKey(HKEY_LOCAL_MACHINE
, NULL
),
1356 Status
= NtOpenKey(&KeyHandle
,
1359 if (!NT_SUCCESS(Status
))
1362 ValueBuffer
[0] = Drive
;
1364 NtSetValueKey(KeyHandle
,
1368 (PVOID
)&ValueBuffer
,
1369 sizeof(ValueBuffer
));