ReactOS 0.4.15-dev-6057-gd708c79
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
89 IN PCWSTR LanguageId)
90{
91 ULONG lngIndex = max(FindLanguageIndex(LanguageId), 0);
92 return MUILanguageList[lngIndex].MuiLayouts[0].LayoutID;
93}
94
97 IN PCWSTR LanguageId)
98{
99 ULONG lngIndex = max(FindLanguageIndex(LanguageId), 0);
100 return MUILanguageList[lngIndex].OEMCPage;
101}
102
103PCWSTR
105 IN PCWSTR LanguageId)
106{
107 ULONG lngIndex = max(FindLanguageIndex(LanguageId), 0);
108 return MUILanguageList[lngIndex].GeoID;
109}
110
111const MUI_LAYOUTS*
113 IN PCWSTR LanguageId)
114{
115 ULONG lngIndex = max(FindLanguageIndex(LanguageId), 0);
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 = 0;
219 ULONG uCount = 0;
220 WCHAR szKeyName[48] = L".DEFAULT\\Keyboard Layout";
221 WCHAR szValueName[3 + 1];
222 WCHAR szLangID[8 + 1];
223
224 // Open the keyboard layout key
225 RtlInitUnicodeString(&KeyName, szKeyName);
227 &KeyName,
230 NULL);
231
235 0,
236 NULL,
238 &Disposition);
239 if (!NT_SUCCESS(Status))
240 {
241 DPRINT1("NtCreateKey() failed (Status %lx)\n", Status);
242 return FALSE;
243 }
244
246
247 KeyName.MaximumLength = sizeof(szKeyName);
249
250 if (!NT_SUCCESS(Status))
251 {
252 DPRINT1("RtlAppend failed! (%lx)\n", Status);
253 DPRINT1("String is %wZ\n", &KeyName);
254 return FALSE;
255 }
256
258 &KeyName,
261 NULL);
262
266 0,
267 NULL,
269 &Disposition);
270 if (!NT_SUCCESS(Status))
271 {
272 DPRINT1("NtCreateKey() failed (Status %lx)\n", Status);
273 return FALSE;
274 }
275
276 RtlInitUnicodeString(&KeyName, L".DEFAULT\\Keyboard Layout\\Substitutes");
278 &KeyName,
281 NULL);
282
286 0,
287 NULL,
289 &Disposition);
290 if (!NT_SUCCESS(Status))
291 {
292 DPRINT1("NtCreateKey() failed (Status %lx)\n", Status);
295 return FALSE;
296 }
297
298 while (MuiLayouts[uIndex].LangID != NULL)
299 {
300 if (uIndex > 19) break;
301
302 RtlStringCchPrintfW(szValueName, ARRAYSIZE(szValueName), L"%u", uIndex + 1);
303 RtlInitUnicodeString(&ValueName, szValueName);
304
305 RtlStringCchPrintfW(szLangID, ARRAYSIZE(szLangID), L"0000%s", MuiLayouts[uIndex].LangID);
306
307 if (_wcsicmp(szLangID, MuiLayouts[uIndex].LayoutID) == 0)
308 {
310 &ValueName,
311 0,
312 REG_SZ,
313 (PVOID)MuiLayouts[uIndex].LayoutID,
314 (wcslen(MuiLayouts[uIndex].LayoutID)+1) * sizeof(WCHAR));
315 if (!NT_SUCCESS(Status))
316 {
317 DPRINT1("NtSetValueKey() failed (Status = %lx, uIndex = %d)\n", Status, uIndex);
320 return FALSE;
321 }
322 }
323 else
324 {
325 RtlStringCchPrintfW(szLangID, ARRAYSIZE(szLangID), L"d%03lu%s", uCount, MuiLayouts[uIndex].LangID);
327 &ValueName,
328 0,
329 REG_SZ,
330 (PVOID)szLangID,
331 (wcslen(szLangID)+1) * sizeof(WCHAR));
332 if (!NT_SUCCESS(Status))
333 {
334 DPRINT1("NtSetValueKey() failed (Status = %lx, uIndex = %d)\n", Status, uIndex);
337 return FALSE;
338 }
339
341
343 &ValueName,
344 0,
345 REG_SZ,
346 (PVOID)MuiLayouts[uIndex].LayoutID,
347 (wcslen(MuiLayouts[uIndex].LayoutID)+1) * sizeof(WCHAR));
348 if (!NT_SUCCESS(Status))
349 {
350 DPRINT1("NtSetValueKey() failed (Status = %lx, uIndex = %u)\n", Status, uIndex);
353 return FALSE;
354 }
355
356 uCount++;
357 }
358
359 uIndex++;
360 }
361
362 if (uIndex > 1)
363 AddHotkeySettings(L"2", L"2", L"1");
364 else
365 AddHotkeySettings(L"3", L"3", L"3");
366
369 return TRUE;
370}
371
374 IN PCWSTR LanguageId)
375{
376 ULONG lngIndex = 0;
377
378 while (MUILanguageList[lngIndex].LanguageID != NULL)
379 {
380 if (_wcsicmp(MUILanguageList[lngIndex].LanguageID, LanguageId) == 0)
381 {
382 return AddKbLayoutsToRegistry(MUILanguageList[lngIndex].MuiLayouts);
383 }
384
385 lngIndex++;
386 }
387
388 return FALSE;
389}
390
391static
394 IN PCWSTR ACPage,
395 IN PCWSTR OEMCPage,
396 IN PCWSTR MACCPage)
397{
403
404 // Open the nls codepage key
406 L"SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage");
408 &KeyName,
411 NULL);
413 KEY_WRITE,
415 if (!NT_SUCCESS(Status))
416 {
417 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status);
418 return FALSE;
419 }
420
421 // Set ANSI codepage
424 &ValueName,
425 0,
426 REG_SZ,
427 (PVOID)ACPage,
428 (wcslen(ACPage)+1) * sizeof(WCHAR));
429 if (!NT_SUCCESS(Status))
430 {
431 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
433 return FALSE;
434 }
435
436 // Set OEM codepage
439 &ValueName,
440 0,
441 REG_SZ,
442 (PVOID)OEMCPage,
443 (wcslen(OEMCPage)+1) * sizeof(WCHAR));
444 if (!NT_SUCCESS(Status))
445 {
446 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
448 return FALSE;
449 }
450
451 // Set MAC codepage
454 &ValueName,
455 0,
456 REG_SZ,
457 (PVOID)MACCPage,
458 (wcslen(MACCPage)+1) * sizeof(WCHAR));
459 if (!NT_SUCCESS(Status))
460 {
461 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
463 return FALSE;
464 }
465
467
468 return TRUE;
469}
470
471static
474 IN const MUI_SUBFONT * MuiSubFonts)
475{
481 ULONG uIndex = 0;
482
484 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes");
486 &KeyName,
489 NULL);
491 KEY_WRITE,
493 if (!NT_SUCCESS(Status))
494 {
495 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status);
496 return FALSE;
497 }
498
499 while (MuiSubFonts[uIndex].FontName != NULL)
500 {
501 RtlInitUnicodeString(&ValueName, MuiSubFonts[uIndex].FontName);
502 if (MuiSubFonts[uIndex].SubFontName)
503 {
505 &ValueName,
506 0,
507 REG_SZ,
508 (PVOID)MuiSubFonts[uIndex].SubFontName,
509 (wcslen(MuiSubFonts[uIndex].SubFontName)+1) * sizeof(WCHAR));
510 if (!NT_SUCCESS(Status))
511 {
512 DPRINT1("NtSetValueKey() failed (Status = %lx, uIndex = %d)\n", Status, uIndex);
514 return FALSE;
515 }
516 }
517 else
518 {
520 if (!NT_SUCCESS(Status))
521 {
522 DPRINT1("NtDeleteValueKey failed, Status = %lx\n", Status);
523 }
524 }
525
526 uIndex++;
527 }
528
530
531 return TRUE;
532}
533
536 IN PCWSTR LanguageId)
537{
538 ULONG lngIndex = 0;
539
540 while (MUILanguageList[lngIndex].LanguageID != NULL)
541 {
542 if (_wcsicmp(MUILanguageList[lngIndex].LanguageID, LanguageId) == 0)
543 {
544 if (AddCodepageToRegistry(MUILanguageList[lngIndex].ACPage,
545 MUILanguageList[lngIndex].OEMCPage,
546 MUILanguageList[lngIndex].MACCPage) &&
547 AddFontsSettingsToRegistry(MUILanguageList[lngIndex].MuiSubFonts))
548 {
549 return TRUE;
550 }
551 else
552 {
553 return FALSE;
554 }
555 }
556
557 lngIndex++;
558 }
559
560 return FALSE;
561}
562
563#ifdef __REACTOS__ /* HACK */
564BOOL
566{
567 if (pSettings->bFoundFontMINGLIU)
569 if (pSettings->bFoundFontSIMSUN)
571 if (pSettings->bFoundFontMSSONG)
573 if (pSettings->bFoundFontMSGOTHIC)
575 if (pSettings->bFoundFontMSMINCHO)
577 if (pSettings->bFoundFontGULIM)
579 if (pSettings->bFoundFontBATANG)
581
582 switch (PRIMARYLANGID(LangID))
583 {
584 case LANG_CHINESE:
586 {
587 if (pSettings->bFoundFontSIMSUN)
589 }
590 else
591 {
592 if (pSettings->bFoundFontMINGLIU)
594 }
595 break;
596
597 case LANG_JAPANESE:
598 if (pSettings->bFoundFontMSGOTHIC)
600 break;
601
602 case LANG_KOREAN:
603 if (pSettings->bFoundFontBATANG)
605 break;
606 }
607
608 return TRUE;
609}
610#endif /* HACK */
611
612/* EOF */
unsigned char BOOLEAN
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
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
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
PCWSTR MUIGetGeoID(IN PCWSTR LanguageId)
Definition: mui.c:104
const MUI_LAYOUTS * MUIGetLayoutsList(IN PCWSTR LanguageId)
Definition: mui.c:112
PCWSTR MUIDefaultKeyboardLayout(IN PCWSTR LanguageId)
Definition: mui.c:88
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:535
PCWSTR MUIGetOEMCodePage(IN PCWSTR LanguageId)
Definition: mui.c:96
static BOOLEAN AddFontsSettingsToRegistry(IN const MUI_SUBFONT *MuiSubFonts)
Definition: mui.c:473
BOOLEAN AddKeyboardLayouts(IN PCWSTR LanguageId)
Definition: mui.c:373
static BOOLEAN AddCodepageToRegistry(IN PCWSTR ACPage, IN PCWSTR OEMCPage, IN PCWSTR MACCPage)
Definition: mui.c:393
BOOLEAN IsLanguageAvailable(IN PCWSTR LanguageId)
Definition: mui.c:70
BOOLEAN AddKbLayoutsToRegistry(IN const MUI_LAYOUTS *MuiLayouts)
Definition: mui.c:208
const MUI_LANGUAGE MUILanguageList[]
Definition: muilanguages.h:412
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
MUI_SUBFONT FontFixupMSGOTHIC[]
Definition: muifonts.h:452
MUI_SUBFONT KoreanFontFixup[]
Definition: muifonts.h:419
MUI_SUBFONT FontFixupMINGLIU[]
Definition: muifonts.h:426
MUI_SUBFONT SimplifiedChineseFontFixup[]
Definition: muifonts.h:398
MUI_SUBFONT TraditionalChineseFontFixup[]
Definition: muifonts.h:405
MUI_SUBFONT JapaneseFontFixup[]
Definition: muifonts.h:412
MUI_SUBFONT FontFixupGULIM[]
Definition: muifonts.h:471
MUI_SUBFONT FontFixupSIMSUN[]
Definition: muifonts.h:435
MUI_SUBFONT FontFixupMSMINCHO[]
Definition: muifonts.h:462
MUI_SUBFONT FontFixupBATANG[]
Definition: muifonts.h:480
MUI_SUBFONT FontFixupMSSONG[]
Definition: muifonts.h:445
_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
_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
PCWSTR OEMCPage
Definition: mui.h:19
PCWSTR GeoID
Definition: mui.h:22
const MUI_LAYOUTS * MuiLayouts
Definition: mui.h:24
PCWSTR LayoutID
Definition: mui.h:12
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)
#define max(a, b)
Definition: svc.c:63
WORD LANGID
Definition: typedefs.h:81
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_ 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