ReactOS 0.4.15-dev-7907-g95bf896
mui.c
Go to the documentation of this file.
1/*
2 * ReactOS kernel
3 * Copyright (C) 2008 ReactOS Team
4 *
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.
9 *
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.
14 *
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.
18 */
19/*
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS text-mode setup
22 * FILE: base/setup/usetup/mui.c
23 * PURPOSE: Text-mode setup
24 * PROGRAMMER:
25 */
26
27/* INCLUDES *****************************************************************/
28
29#include "precomp.h"
30#include "mui.h"
31#include "muifonts.h"
32#include "muilanguages.h"
33#include "registry.h"
34#include "substset.h"
35
36#define NDEBUG
37#include <debug.h>
38
39
40/* FUNCTIONS ****************************************************************/
41
42static
45 IN PCWSTR LanguageId)
46{
47 ULONG lngIndex = 0;
48
49 if (LanguageId == NULL)
50 {
51 /* Default to en-US */
52 // return 0; // FIXME!!
53 LanguageId = L"00000409";
54 }
55
56 while (MUILanguageList[lngIndex].LanguageID != NULL)
57 {
58 if (_wcsicmp(MUILanguageList[lngIndex].LanguageID, LanguageId) == 0)
59 {
60 return lngIndex;
61 }
62
63 lngIndex++;
64 }
65
66 return 0;
67}
68
71 IN PCWSTR LanguageId)
72{
73 ULONG lngIndex = 0;
74
75 while (MUILanguageList[lngIndex].LanguageID != NULL)
76 {
77 if (_wcsicmp(MUILanguageList[lngIndex].LanguageID, LanguageId) == 0)
78 return TRUE;
79
80 lngIndex++;
81 }
82
83 return FALSE;
84}
85
86
87KLID
89 IN PCWSTR LanguageId)
90{
91 ULONG lngIndex = FindLanguageIndex(LanguageId);
92 return MUILanguageList[lngIndex].MuiLayouts[0].LayoutID;
93}
94
95UINT
97 IN PCWSTR LanguageId)
98{
99 ULONG lngIndex = FindLanguageIndex(LanguageId);
100 return MUILanguageList[lngIndex].OEMCPage;
101}
102
103GEOID
105 IN PCWSTR LanguageId)
106{
107 ULONG lngIndex = FindLanguageIndex(LanguageId);
108 return MUILanguageList[lngIndex].GeoID;
109}
110
111const MUI_LAYOUTS*
113 IN PCWSTR LanguageId)
114{
115 ULONG lngIndex = FindLanguageIndex(LanguageId);
116 return MUILanguageList[lngIndex].MuiLayouts;
117}
118
119
120static
123 IN PCWSTR Hotkey,
124 IN PCWSTR LangHotkey,
125 IN PCWSTR LayoutHotkey)
126{
133
135 L".DEFAULT\\Keyboard Layout\\Toggle");
137 &KeyName,
140 NULL);
141
145 0,
146 NULL,
148 &Disposition);
149 if (!NT_SUCCESS(Status))
150 {
151 DPRINT1("NtCreateKey() failed (Status %lx)\n", Status);
152 return FALSE;
153 }
154
156 L"Hotkey");
157
159 &ValueName,
160 0,
161 REG_SZ,
162 (PVOID)Hotkey,
163 (1 + 1) * sizeof(WCHAR));
164 if (!NT_SUCCESS(Status))
165 {
166 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
168 return FALSE;
169 }
170
172 L"Language Hotkey");
173
175 &ValueName,
176 0,
177 REG_SZ,
178 (PVOID)LangHotkey,
179 (1 + 1) * sizeof(WCHAR));
180 if (!NT_SUCCESS(Status))
181 {
182 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
184 return FALSE;
185 }
186
188 L"Layout Hotkey");
189
191 &ValueName,
192 0,
193 REG_SZ,
194 (PVOID)LayoutHotkey,
195 (1 + 1) * sizeof(WCHAR));
196 if (!NT_SUCCESS(Status))
197 {
198 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
200 return FALSE;
201 }
202
204 return TRUE;
205}
206
209 _In_ const MUI_LAYOUTS* MuiLayouts)
210{
218 ULONG uIndex;
219 ULONG uCount;
220 WCHAR szKeyName[48] = L".DEFAULT\\Keyboard Layout";
221 WCHAR szValueName[3 + 1];
222 WCHAR szSubstID[8 + 1];
223 WCHAR szLayoutID[8 + 1];
224
225 /* Open the keyboard layout key */
226 RtlInitUnicodeString(&KeyName, szKeyName);
228 &KeyName,
231 NULL);
232
236 0,
237 NULL,
239 &Disposition);
240 if (!NT_SUCCESS(Status))
241 {
242 DPRINT1("NtCreateKey() failed (Status %lx)\n", Status);
243 return FALSE;
244 }
245
247
248 KeyName.MaximumLength = sizeof(szKeyName);
250 if (!NT_SUCCESS(Status))
251 {
252 DPRINT1("RtlAppend() failed (%lx), string is '%wZ'\n", Status, &KeyName);
253 return FALSE;
254 }
255
257 &KeyName,
260 NULL);
261
265 0,
266 NULL,
268 &Disposition);
269 if (!NT_SUCCESS(Status))
270 {
271 DPRINT1("NtCreateKey() failed (Status %lx)\n", Status);
272 return FALSE;
273 }
274
275 RtlInitUnicodeString(&KeyName, L".DEFAULT\\Keyboard Layout\\Substitutes");
277 &KeyName,
280 NULL);
281
285 0,
286 NULL,
288 &Disposition);
289 if (!NT_SUCCESS(Status))
290 {
291 DPRINT1("NtCreateKey() failed (Status %lx)\n", Status);
292 goto Quit;
293 }
294
295 uCount = 0;
296 for (uIndex = 0; (uIndex <= 19) && (MuiLayouts[uIndex].LangID != 0); ++uIndex)
297 {
298 RtlStringCchPrintfW(szValueName, _countof(szValueName), L"%u", uIndex + 1);
299 RtlInitUnicodeString(&ValueName, szValueName);
300
301 RtlStringCchPrintfW(szLayoutID, _countof(szLayoutID), L"%08lx", MuiLayouts[uIndex].LayoutID);
302
303 if ((KLID)MuiLayouts[uIndex].LangID == MuiLayouts[uIndex].LayoutID)
304 {
305 /* Main keyboard layout */
307 &ValueName,
308 0,
309 REG_SZ,
310 (PVOID)szLayoutID,
311 (wcslen(szLayoutID)+1) * sizeof(WCHAR));
312 if (!NT_SUCCESS(Status))
313 {
314 DPRINT1("NtSetValueKey() failed (Status = %lx, uIndex = %u)\n", Status, uIndex);
315 goto Quit;
316 }
317 }
318 else
319 {
320 /* Generate a substitute keyboard layout ID */
321 RtlStringCchPrintfW(szSubstID, _countof(szSubstID), L"%08lx",
322 (0xD0000000/*SUBST_MASK*/ | ((USHORT)uCount << 4) | MuiLayouts[uIndex].LangID));
324 &ValueName,
325 0,
326 REG_SZ,
327 (PVOID)szSubstID,
328 (wcslen(szSubstID)+1) * sizeof(WCHAR));
329 if (!NT_SUCCESS(Status))
330 {
331 DPRINT1("NtSetValueKey() failed (Status = %lx, uIndex = %u)\n", Status, uIndex);
332 goto Quit;
333 }
334
335 /* Link the substitute layout with the original one */
336 RtlInitUnicodeString(&ValueName, szSubstID);
338 &ValueName,
339 0,
340 REG_SZ,
341 (PVOID)szLayoutID,
342 (wcslen(szLayoutID)+1) * sizeof(WCHAR));
343 if (!NT_SUCCESS(Status))
344 {
345 DPRINT1("NtSetValueKey() failed (Status = %lx, uIndex = %u)\n", Status, uIndex);
346 goto Quit;
347 }
348
349 ++uCount;
350 }
351 }
352
353 AddHotkeySettings(L"1", L"1", L"2");
354
355Quit:
358 return NT_SUCCESS(Status);
359}
360
363 IN PCWSTR LanguageId)
364{
365 ULONG lngIndex = 0;
366
367 while (MUILanguageList[lngIndex].LanguageID != NULL)
368 {
369 if (_wcsicmp(MUILanguageList[lngIndex].LanguageID, LanguageId) == 0)
370 {
371 return AddKbLayoutsToRegistry(MUILanguageList[lngIndex].MuiLayouts);
372 }
373
374 lngIndex++;
375 }
376
377 return FALSE;
378}
379
380static
383 _In_ UINT ACPage,
384 _In_ UINT OEMCPage,
385 _In_ UINT MACCPage)
386{
391 /*
392 * Buffer big enough to hold the NULL-terminated string L"4294967295",
393 * corresponding to the literal 0xFFFFFFFF (MAXULONG) in decimal.
394 */
395 WCHAR Value[sizeof("4294967295")];
396
397 /* Open the NLS CodePage key */
399 L"SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage");
401 &Name,
404 NULL);
406 KEY_WRITE,
408 if (!NT_SUCCESS(Status))
409 {
410 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status);
411 return FALSE;
412 }
413
414 /* Set ANSI codepage */
415 Status = RtlStringCchPrintfW(Value, _countof(Value), L"%lu", ACPage);
417
420 &Name,
421 0,
422 REG_SZ,
423 (PVOID)Value,
424 (wcslen(Value)+1) * sizeof(WCHAR));
425 if (!NT_SUCCESS(Status))
426 {
427 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
428 goto Quit;
429 }
430
431 /* Set OEM codepage */
432 Status = RtlStringCchPrintfW(Value, _countof(Value), L"%lu", OEMCPage);
434
435 RtlInitUnicodeString(&Name, L"OEMCP");
437 &Name,
438 0,
439 REG_SZ,
440 (PVOID)Value,
441 (wcslen(Value)+1) * sizeof(WCHAR));
442 if (!NT_SUCCESS(Status))
443 {
444 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
445 goto Quit;
446 }
447
448 /* Set MAC codepage */
449 Status = RtlStringCchPrintfW(Value, _countof(Value), L"%lu", MACCPage);
451
452 RtlInitUnicodeString(&Name, L"MACCP");
454 &Name,
455 0,
456 REG_SZ,
457 (PVOID)Value,
458 (wcslen(Value)+1) * sizeof(WCHAR));
459 if (!NT_SUCCESS(Status))
460 {
461 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
462 goto Quit;
463 }
464
465Quit:
467 return NT_SUCCESS(Status);
468}
469
470static
473 IN const MUI_SUBFONT * MuiSubFonts)
474{
480 ULONG uIndex = 0;
481
483 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes");
485 &KeyName,
488 NULL);
490 KEY_WRITE,
492 if (!NT_SUCCESS(Status))
493 {
494 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status);
495 return FALSE;
496 }
497
498 while (MuiSubFonts[uIndex].FontName != NULL)
499 {
500 RtlInitUnicodeString(&ValueName, MuiSubFonts[uIndex].FontName);
501 if (MuiSubFonts[uIndex].SubFontName)
502 {
504 &ValueName,
505 0,
506 REG_SZ,
507 (PVOID)MuiSubFonts[uIndex].SubFontName,
508 (wcslen(MuiSubFonts[uIndex].SubFontName)+1) * sizeof(WCHAR));
509 if (!NT_SUCCESS(Status))
510 {
511 DPRINT1("NtSetValueKey() failed (Status = %lx, uIndex = %d)\n", Status, uIndex);
513 return FALSE;
514 }
515 }
516 else
517 {
519 if (!NT_SUCCESS(Status))
520 {
521 DPRINT1("NtDeleteValueKey failed, Status = %lx\n", Status);
522 }
523 }
524
525 uIndex++;
526 }
527
529
530 return TRUE;
531}
532
535 IN PCWSTR LanguageId)
536{
537 ULONG lngIndex = 0;
538
539 while (MUILanguageList[lngIndex].LanguageID != NULL)
540 {
541 if (_wcsicmp(MUILanguageList[lngIndex].LanguageID, LanguageId) == 0)
542 {
543 if (AddCodepageToRegistry(MUILanguageList[lngIndex].ACPage,
544 MUILanguageList[lngIndex].OEMCPage,
545 MUILanguageList[lngIndex].MACCPage) &&
546 AddFontsSettingsToRegistry(MUILanguageList[lngIndex].MuiSubFonts))
547 {
548 return TRUE;
549 }
550 else
551 {
552 return FALSE;
553 }
554 }
555
556 lngIndex++;
557 }
558
559 return FALSE;
560}
561
562#ifdef __REACTOS__ /* HACK */
563BOOL
565{
566 if (pSettings->bFoundFontMINGLIU)
568 if (pSettings->bFoundFontSIMSUN)
570 if (pSettings->bFoundFontMSSONG)
572 if (pSettings->bFoundFontMSGOTHIC)
574 if (pSettings->bFoundFontMSMINCHO)
576 if (pSettings->bFoundFontGULIM)
578 if (pSettings->bFoundFontBATANG)
580
581 switch (PRIMARYLANGID(LangID))
582 {
583 case LANG_CHINESE:
585 {
586 if (pSettings->bFoundFontSIMSUN)
588 }
589 else
590 {
591 if (pSettings->bFoundFontMINGLIU)
593 }
594 break;
595
596 case LANG_JAPANESE:
597 if (pSettings->bFoundFontMSGOTHIC)
599 break;
600
601 case LANG_KOREAN:
602 if (pSettings->bFoundFontBATANG)
604 break;
605 }
606
607 return TRUE;
608}
609#endif /* HACK */
610
611/* EOF */
unsigned char BOOLEAN
struct NameRec_ * Name
Definition: cdprocs.h:460
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
HANDLE GetRootKeyByPredefKey(IN HANDLE KeyHandle, OUT PCWSTR *RootKeyMountPoint OPTIONAL)
Definition: registry.c:90
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
unsigned int BOOL
Definition: ntddk_ex.h:94
Status
Definition: gdiplustypes.h:25
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define REG_SZ
Definition: layer.c:22
KLID MUIDefaultKeyboardLayout(IN PCWSTR LanguageId)
Definition: mui.c:88
BOOLEAN AddKbLayoutsToRegistry(_In_ const MUI_LAYOUTS *MuiLayouts)
Definition: mui.c:208
const MUI_LAYOUTS * MUIGetLayoutsList(IN PCWSTR LanguageId)
Definition: mui.c:112
GEOID MUIGetGeoID(IN PCWSTR LanguageId)
Definition: mui.c:104
static ULONG FindLanguageIndex(IN PCWSTR LanguageId)
Definition: mui.c:44
static BOOLEAN AddHotkeySettings(IN PCWSTR Hotkey, IN PCWSTR LangHotkey, IN PCWSTR LayoutHotkey)
Definition: mui.c:122
BOOLEAN AddCodePage(IN PCWSTR LanguageId)
Definition: mui.c:534
static BOOLEAN AddFontsSettingsToRegistry(IN const MUI_SUBFONT *MuiSubFonts)
Definition: mui.c:472
static BOOLEAN AddCodepageToRegistry(_In_ UINT ACPage, _In_ UINT OEMCPage, _In_ UINT MACCPage)
Definition: mui.c:382
BOOLEAN AddKeyboardLayouts(IN PCWSTR LanguageId)
Definition: mui.c:362
BOOLEAN IsLanguageAvailable(IN PCWSTR LanguageId)
Definition: mui.c:70
UINT MUIGetOEMCodePage(IN PCWSTR LanguageId)
Definition: mui.c:96
USHORT LANGID
Definition: mui.h:9
ULONG KLID
Definition: mui.h:10
ULONG GEOID
Definition: mui.h:28
const MUI_LANGUAGE MUILanguageList[]
Definition: muilanguages.h:412
#define ASSERT(a)
Definition: mode.c:44
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define _In_
Definition: ms_sal.h:308
MUI_SUBFONT FontFixupMSGOTHIC[]
Definition: muifonts.h:462
MUI_SUBFONT KoreanFontFixup[]
Definition: muifonts.h:429
MUI_SUBFONT FontFixupMINGLIU[]
Definition: muifonts.h:436
MUI_SUBFONT SimplifiedChineseFontFixup[]
Definition: muifonts.h:408
MUI_SUBFONT TraditionalChineseFontFixup[]
Definition: muifonts.h:415
MUI_SUBFONT JapaneseFontFixup[]
Definition: muifonts.h:422
MUI_SUBFONT FontFixupGULIM[]
Definition: muifonts.h:481
MUI_SUBFONT FontFixupSIMSUN[]
Definition: muifonts.h:445
MUI_SUBFONT FontFixupMSMINCHO[]
Definition: muifonts.h:472
MUI_SUBFONT FontFixupBATANG[]
Definition: muifonts.h:490
MUI_SUBFONT FontFixupMSSONG[]
Definition: muifonts.h:455
unsigned int UINT
Definition: ndis.h:50
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ PNDIS_STRING _Out_ PNDIS_HANDLE SubKeyHandle
Definition: ndis.h:4726
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:56
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
NTSYSAPI NTSTATUS NTAPI NtSetValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN ULONG TitleIndex OPTIONAL, IN ULONG Type, IN PVOID Data, IN ULONG DataSize)
Definition: ntapi.c:859
NTSYSAPI NTSTATUS NTAPI NtDeleteValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName)
Definition: ntapi.c:1014
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define KEY_CREATE_SUB_KEY
Definition: nt_native.h:1018
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define KEY_WRITE
Definition: nt_native.h:1031
#define KEY_SET_VALUE
Definition: nt_native.h:1017
NTSTATUS NTAPI NtCreateKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG TitleIndex, IN PUNICODE_STRING Class OPTIONAL, IN ULONG CreateOptions, OUT PULONG Disposition OPTIONAL)
Definition: ntapi.c:240
NTSTRSAFEVAPI RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1110
#define L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define SUBLANGID(l)
Definition: nls.h:17
#define SUBLANG_CHINESE_SIMPLIFIED
Definition: nls.h:209
#define LANG_CHINESE
Definition: nls.h:42
#define LANG_JAPANESE
Definition: nls.h:76
#define PRIMARYLANGID(l)
Definition: nls.h:16
#define LANG_KOREAN
Definition: nls.h:84
#define _countof(array)
Definition: sndvol32.h:68
GEOID GeoID
Definition: mui.h:37
UINT OEMCPage
Definition: mui.h:34
const MUI_LAYOUTS * MuiLayouts
Definition: mui.h:39
KLID LayoutID
Definition: mui.h:25
Definition: mui.h:4
BOOL bFoundFontMINGLIU
Definition: substset.h:5
BOOL bFoundFontGULIM
Definition: substset.h:10
BOOL bFoundFontMSGOTHIC
Definition: substset.h:8
BOOL bFoundFontMSSONG
Definition: substset.h:7
BOOL bFoundFontSIMSUN
Definition: substset.h:6
BOOL bFoundFontBATANG
Definition: substset.h:11
BOOL bFoundFontMSMINCHO
Definition: substset.h:9
BOOL DoRegistryFontFixup(PFONTSUBSTSETTINGS pSettings, LANGID LangID)
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_writes_opt_ NumCharacters PUSHORT _Inout_ PUSHORT _In_ UCHAR _In_opt_ USHORT LangID
Definition: wdfusb.h:1083
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_USERS
Definition: winreg.h:13
__wchar_t WCHAR
Definition: xmlstorage.h:180