3 * Copyright (C) 2008 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS text-mode setup
22 * FILE: subsys/system/usetup/mui.c
23 * PURPOSE: Text-mode setup
28 #include "interface/consup.h"
29 #include "errorcode.h"
35 #include "lang/bg-BG.h"
36 #include "lang/cs-CZ.h"
37 #include "lang/en-US.h"
38 #include "lang/de-DE.h"
39 #include "lang/el-GR.h"
40 #include "lang/es-ES.h"
41 #include "lang/fr-FR.h"
42 #include "lang/it-IT.h"
43 #include "lang/pl-PL.h"
44 #include "lang/ru-RU.h"
45 #include "lang/sk-SK.h"
46 #include "lang/sv-SE.h"
47 #include "lang/uk-UA.h"
48 #include "lang/lt-LT.h"
50 static const MUI_LANGUAGE LanguageList
[] =
52 /* Lang ID, DefKbdLayout, SecKbLayout, ANSI CP, OEM CP, MAC CP, Language Name, page strgs,error strings, other strings */
53 {L
"00000409", L
"00000409", NULL
, L
"1252", L
"437", L
"10000", L
"English", enUSPages
, enUSErrorEntries
, enUSStrings
},
54 {L
"0000041C", L
"0000041C", L
"00000409", L
"1250", L
"852", L
"10029", L
"Albanian", enUSPages
, enUSErrorEntries
, enUSStrings
},
55 {L
"00000401", L
"00000401", L
"00000409", L
"1256", L
"720", L
"10004", L
"Arabic", enUSPages
, enUSErrorEntries
, enUSStrings
},
56 {L
"0000042B", L
"0000042B", L
"00000409", L
"0", L
"1", L
"2", L
"Armenian Eastern", enUSPages
, enUSErrorEntries
, enUSStrings
},
57 {L
"0000082C", L
"0000082C", L
"00000409", L
"1251", L
"866", L
"10007", L
"Azeri Cyrillic", enUSPages
, enUSErrorEntries
, enUSStrings
},
58 {L
"0000042C", L
"0000042C", L
"00000409", L
"1254", L
"857", L
"10081", L
"Azeri Latin", enUSPages
, enUSErrorEntries
, enUSStrings
},
59 {L
"00000423", L
"00000423", L
"00000409", L
"1251", L
"866", L
"10007", L
"Belarusian", enUSPages
, enUSErrorEntries
, enUSStrings
},
60 {L
"00000813", L
"00000813", L
"00000409", L
"1252", L
"850", L
"10000", L
"Belgian (Dutch)", enUSPages
, enUSErrorEntries
, enUSStrings
},
61 {L
"0000080C", L
"0000080C", L
"00000409", L
"1252", L
"850", L
"10000", L
"Belgian (French)", enUSPages
, enUSErrorEntries
, enUSStrings
},
62 {L
"00000416", L
"00010416", L
"00000409", L
"1252", L
"850", L
"10000", L
"Brazilian", enUSPages
, enUSErrorEntries
, enUSStrings
},
63 {L
"00000402", L
"00000402", L
"00000409", L
"1251", L
"866", L
"10007", L
"Bulgarian", bgBGPages
, bgBGErrorEntries
, bgBGStrings
},
64 {L
"00000455", L
"00000455", L
"00000409", L
"0", L
"1", L
"2", L
"Burmese", enUSPages
, enUSErrorEntries
, enUSStrings
},// Unicode only
65 {L
"00000C0C", L
"00000C0C", L
"00000409", L
"1252", L
"850", L
"10000", L
"Canadian (French)", enUSPages
, enUSErrorEntries
, enUSStrings
},
66 {L
"00000403", L
"0000040A", L
"00000409", L
"1252", L
"850", L
"10000", L
"Catalan", enUSPages
, enUSErrorEntries
, enUSStrings
},
67 {L
"00000804", L
"00000804", L
"00000409", L
"936", L
"936", L
"10008", L
"Chinese (PRC)", enUSPages
, enUSErrorEntries
, enUSStrings
},
68 {L
"00000405", L
"00000405", L
"00000409", L
"1250", L
"852", L
"10029", L
"Czech", csCZPages
, csCZErrorEntries
, csCZStrings
},
69 {L
"00000406", L
"00000406", L
"00000409", L
"1252", L
"850", L
"10000", L
"Danish", enUSPages
, enUSErrorEntries
, enUSStrings
},
70 {L
"00000407", L
"00000407", L
"00000409", L
"1252", L
"850", L
"10000", L
"Deutsch", deDEPages
, deDEErrorEntries
, deDEStrings
},
71 {L
"00000413", L
"00000813", L
"00000409", L
"1252", L
"850", L
"10000", L
"Dutch", enUSPages
, enUSErrorEntries
, enUSStrings
},
72 {L
"00000425", L
"00000425", L
"00000409", L
"1257", L
"775", L
"10029", L
"Estonian", enUSPages
, enUSErrorEntries
, enUSStrings
},
73 {L
"0000040B", L
"0000040B", L
"00000409", L
"1252", L
"850", L
"10000", L
"Finnish", enUSPages
, enUSErrorEntries
, enUSStrings
},
74 {L
"0000040C", L
"0000040C", L
"00000409", L
"1252", L
"850", L
"10000", L
"French", frFRPages
, frFRErrorEntries
, frFRStrings
},
75 {L
"00000437", L
"00000437", L
"00000409", L
"0", L
"1", L
"2", L
"Georgian", enUSPages
, enUSErrorEntries
, enUSStrings
},// Unicode only
76 {L
"00000408", L
"00000408", L
"00000409", L
"1253", L
"737", L
"10006", L
"Greek", elGRPages
, elGRErrorEntries
, elGRStrings
},
77 {L
"0000040D", L
"0000040D", L
"00000409", L
"1255", L
"862", L
"10005", L
"Hebrew", enUSPages
, enUSErrorEntries
, enUSStrings
},
78 {L
"0000040E", L
"0000040E", L
"00000409", L
"1250", L
"852", L
"10029", L
"Hungarian", enUSPages
, enUSErrorEntries
, enUSStrings
},
79 {L
"0000040F", L
"0000040F", L
"00000409", L
"1252", L
"850", L
"10079", L
"Icelandic", enUSPages
, enUSErrorEntries
, enUSStrings
},
80 {L
"00000410", L
"00000410", L
"00000409", L
"1252", L
"850", L
"10000", L
"Italian", itITPages
, itITErrorEntries
, itITStrings
},
81 {L
"00000411", L
"00000411", L
"00000409", L
"932", L
"932", L
"10001", L
"Japanese", enUSPages
, enUSErrorEntries
, enUSStrings
},
82 {L
"0000043F", L
"0000043F", L
"00000409", L
"1251", L
"866", L
"10007", L
"Kazakh", enUSPages
, enUSErrorEntries
, enUSStrings
},
83 {L
"00000412", L
"00000412", L
"00000409", L
"949", L
"949", L
"10003", L
"Korean", enUSPages
, enUSErrorEntries
, enUSStrings
},
84 {L
"00000426", L
"00000426", L
"00000409", L
"1257", L
"775", L
"10029", L
"Latvian", enUSPages
, enUSErrorEntries
, enUSStrings
},
85 {L
"00000427", L
"00000427", L
"00000409", L
"1257", L
"775", L
"10029", L
"Lithuanian", ltLTPages
, ltLTErrorEntries
, ltLTStrings
},
86 {L
"0000042F", L
"0000042F", L
"00000409", L
"1251", L
"866", L
"10007", L
"Macedonian", enUSPages
, enUSErrorEntries
, enUSStrings
},
87 {L
"00000414", L
"00000414", L
"00000409", L
"1252", L
"850", L
"10000", L
"Norwegian", enUSPages
, enUSErrorEntries
, enUSStrings
},
88 {L
"00000418", L
"00000418", L
"00000409", L
"1250", L
"852", L
"10029", L
"Romanian", enUSPages
, enUSErrorEntries
, enUSStrings
},
89 {L
"00000419", L
"00000419", L
"00000409", L
"1251", L
"866", L
"10007", L
"Russkij", ruRUPages
, ruRUErrorEntries
, ruRUStrings
},
90 {L
"00000415", L
"00000415", L
"00000409", L
"1250", L
"852", L
"10029", L
"Polski", plPLPages
, plPLErrorEntries
, plPLStrings
},
91 {L
"00000816", L
"00000816", L
"00000409", L
"1252", L
"850", L
"10000", L
"Portuguese", enUSPages
, enUSErrorEntries
, enUSStrings
},
92 {L
"00000C1A", L
"00000C1A", L
"00000409", L
"1251", L
"855", L
"10007", L
"Serbian (Cyrillic)",enUSPages
, enUSErrorEntries
, enUSStrings
},
93 {L
"0000081A", L
"0000081A", L
"00000409", L
"1250", L
"852", L
"10029", L
"Serbian (Latin)", enUSPages
, enUSErrorEntries
, enUSStrings
},
94 {L
"0000041B", L
"0000041B", L
"00000409", L
"1250", L
"852", L
"10029", L
"Slovak", skSKPages
, skSKErrorEntries
, skSKStrings
},
95 {L
"0000040A", L
"0000040A", L
"00000409", L
"1252", L
"850", L
"10000", L
"Spanish", esESPages
, esESErrorEntries
, esESStrings
},
96 {L
"00000807", L
"00000807", L
"00000409", L
"1252", L
"850", L
"10000", L
"Swiss (German)", enUSPages
, enUSErrorEntries
, enUSStrings
},
97 {L
"0000041D", L
"0000041D", L
"00000409", L
"1252", L
"850", L
"10000", L
"Swedish", svSEPages
, svSEErrorEntries
, svSEStrings
},
98 {L
"00000444", L
"00000444", L
"00000409", L
"1251", L
"866", L
"10007", L
"Tatar", enUSPages
, enUSErrorEntries
, enUSStrings
},
99 {L
"0000041E", L
"0000041E", L
"00000409", L
"874", L
"874", L
"10021", L
"Thai", enUSPages
, enUSErrorEntries
, enUSStrings
},
100 {L
"0000041F", L
"0000041F", L
"00000409", L
"1254", L
"857", L
"10081", L
"Turkish", enUSPages
, enUSErrorEntries
, enUSStrings
},
101 {L
"00000422", L
"00000422", L
"00000409", L
"1251", L
"866", L
"10017", L
"Ukrainian", ukUAPages
, ukUAErrorEntries
, ukUAStrings
},
102 {L
"00000809", L
"00000809", L
"00000409", L
"1252", L
"850", L
"10000", L
"United Kingdom", enUSPages
, enUSErrorEntries
, enUSStrings
},
103 {L
"00000843", L
"00000843", L
"00000409", L
"1251", L
"866", L
"10007", L
"Uzbek", enUSPages
, enUSErrorEntries
, enUSStrings
},
104 {L
"0000042A", L
"0000042A", L
"00000409", L
"1258", L
"1258",L
"10000", L
"Vietnamese", enUSPages
, enUSErrorEntries
, enUSStrings
},
105 {NULL
, NULL
, NULL
, NULL
, NULL
, NULL
}
110 PopupError(IN PCCH Text
,
121 if (SelectedLanguageId
== NULL
)
123 /* default to english */
129 if (_wcsicmp(LanguageList
[lngIndex
].LanguageID
, SelectedLanguageId
) == 0)
135 }while (LanguageList
[lngIndex
].MuiPages
!= NULL
);
143 FindMUIEntriesOfPage(IN ULONG PageNumber
)
147 const MUI_PAGE
* Pages
= NULL
;
149 lngIndex
= max(FindLanguageIndex(), 0);
150 Pages
= LanguageList
[lngIndex
].MuiPages
;
154 if (Pages
[muiIndex
].Number
== PageNumber
)
155 return Pages
[muiIndex
].MuiEntry
;
158 }while (Pages
[muiIndex
].MuiEntry
!= NULL
);
165 FindMUIErrorEntries(VOID
)
167 ULONG lngIndex
= max(FindLanguageIndex(), 0);
168 return LanguageList
[lngIndex
].MuiErrors
;
173 FindMUIStringEntries(VOID
)
175 ULONG lngIndex
= max(FindLanguageIndex(), 0);
176 return LanguageList
[lngIndex
].MuiStrings
;
180 MUIDefaultKeyboardLayout(VOID
)
182 ULONG lngIndex
= max(FindLanguageIndex(), 0);
183 return LanguageList
[lngIndex
].LanguageKeyboardLayoutID
;
187 MUIDisplayPage(IN ULONG page
)
189 const MUI_ENTRY
* entry
;
192 entry
= FindMUIEntriesOfPage(page
);
195 PopupError("Error: Failed to find translated page",
205 CONSOLE_SetStyledText (
209 entry
[index
].Buffer
);
213 while (entry
[index
].Buffer
!= NULL
);
217 MUIDisplayError(IN ULONG ErrorNum
, OUT PINPUT_RECORD Ir
, IN ULONG WaitEvent
)
219 const MUI_ERROR
* entry
;
221 if (ErrorNum
>= ERROR_LAST_ERROR_CODE
)
223 PopupError("Invalid error number provided",
224 "Press ENTER to continue",
231 entry
= FindMUIErrorEntries();
234 PopupError("Error: Failed to find translated error message",
241 PopupError(entry
[ErrorNum
].ErrorText
,
242 entry
[ErrorNum
].ErrorStatus
,
248 MUIGetString(ULONG Number
)
251 const MUI_STRING
* entry
;
254 entry
= FindMUIStringEntries();
257 for (i
= 0; entry
[i
].Number
!= 0; i
++)
259 if (entry
[i
].Number
== Number
)
261 return entry
[i
].String
;
266 sprintf(szErr
, "Error: failed find string id %lu for language index %lu\n", Number
, FindLanguageIndex());
277 AddKbLayoutsToRegistry(IN LPCWSTR DefKbLayout
, IN LPCWSTR SecKbLayout
)
279 OBJECT_ATTRIBUTES ObjectAttributes
;
280 UNICODE_STRING KeyName
;
281 UNICODE_STRING ValueName
;
285 WCHAR szKeyName
[48] = L
"\\Registry\\User\\.DEFAULT\\Keyboard Layout";
287 // Open the keyboard layout key
288 RtlInitUnicodeString(&KeyName
,
290 InitializeObjectAttributes(&ObjectAttributes
,
292 OBJ_CASE_INSENSITIVE
,
296 Status
= NtCreateKey(&KeyHandle
,
304 if(NT_SUCCESS(Status
))
308 DPRINT1("NtCreateKey() failed (Status %lx)\n", Status
);
312 KeyName
.MaximumLength
= sizeof(szKeyName
);
313 Status
= RtlAppendUnicodeToString(&KeyName
, L
"\\Preload");
315 if(!NT_SUCCESS(Status
))
317 DPRINT1("RtlAppend failed! (%lx)\n", Status
);
318 DPRINT1("String is %wZ\n", &KeyName
);
322 InitializeObjectAttributes(&ObjectAttributes
,
324 OBJ_CASE_INSENSITIVE
,
328 Status
= NtCreateKey(&KeyHandle
,
336 if (!NT_SUCCESS(Status
))
338 DPRINT1("NtCreateKey() failed (Status %lx)\n", Status
);
342 /* Set def keyboard layout */
343 RtlInitUnicodeString(&ValueName
,
346 Status
= NtSetValueKey(KeyHandle
,
351 (8 + 1) * sizeof(WCHAR
));
352 if (!NT_SUCCESS(Status
))
354 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
359 if (SecKbLayout
!= NULL
)
361 /* Set second keyboard layout */
362 RtlInitUnicodeString(&ValueName
,
365 Status
= NtSetValueKey(KeyHandle
,
370 (8 + 1) * sizeof(WCHAR
));
371 if (!NT_SUCCESS(Status
))
373 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
384 AddKeyboardLayouts(VOID
)
389 if (_wcsicmp(LanguageList
[lngIndex
].LanguageID
, SelectedLanguageId
) == 0)
391 return AddKbLayoutsToRegistry(LanguageList
[lngIndex
].LanguageKeyboardLayoutID
,
392 LanguageList
[lngIndex
].SecondLangKbLayoutID
);
397 while (LanguageList
[lngIndex
].MuiPages
!= NULL
);
403 AddCodepageToRegistry(IN LPCWSTR ACPage
, IN LPCWSTR OEMCPage
, IN LPCWSTR MACCPage
)
405 OBJECT_ATTRIBUTES ObjectAttributes
;
406 UNICODE_STRING KeyName
;
407 UNICODE_STRING ValueName
;
411 // Open the nls codepage key
412 RtlInitUnicodeString(&KeyName
,
413 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage");
414 InitializeObjectAttributes(&ObjectAttributes
,
416 OBJ_CASE_INSENSITIVE
,
419 Status
= NtOpenKey(&KeyHandle
,
422 if (!NT_SUCCESS(Status
))
424 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status
);
429 RtlInitUnicodeString(&ValueName
, L
"ACP");
430 Status
= NtSetValueKey(KeyHandle
,
435 wcslen(ACPage
) * sizeof(PWCHAR
));
436 if (!NT_SUCCESS(Status
))
438 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
444 RtlInitUnicodeString(&ValueName
, L
"OEMCP");
445 Status
= NtSetValueKey(KeyHandle
,
450 wcslen(OEMCPage
) * sizeof(PWCHAR
));
451 if (!NT_SUCCESS(Status
))
453 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
459 RtlInitUnicodeString(&ValueName
, L
"MACCP");
460 Status
= NtSetValueKey(KeyHandle
,
465 wcslen(MACCPage
) * sizeof(PWCHAR
));
466 if (!NT_SUCCESS(Status
))
468 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
484 if (_wcsicmp(LanguageList
[lngIndex
].LanguageID
, SelectedLanguageId
) == 0)
486 return AddCodepageToRegistry(LanguageList
[lngIndex
].ACPage
,
487 LanguageList
[lngIndex
].OEMCPage
,
488 LanguageList
[lngIndex
].MACCPage
);
493 while (LanguageList
[lngIndex
].MuiPages
!= NULL
);
499 SetConsoleCodePage(VOID
)
506 if (_wcsicmp(LanguageList
[lngIndex
].LanguageID
, SelectedLanguageId
) == 0)
508 wCodePage
= (UINT
) wcstoul(LanguageList
[lngIndex
].OEMCPage
, NULL
, 10);
509 SetConsoleOutputCP(wCodePage
);
515 while (LanguageList
[lngIndex
].MuiPages
!= NULL
);