ReactOS  0.4.15-dev-1187-g119f102
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 
42 static
43 ULONG
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 
69 BOOLEAN
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 
87 PCWSTR
89  IN PCWSTR LanguageId)
90 {
91  ULONG lngIndex = max(FindLanguageIndex(LanguageId), 0);
92  return MUILanguageList[lngIndex].MuiLayouts[0].LayoutID;
93 }
94 
95 PCWSTR
97  IN PCWSTR LanguageId)
98 {
99  ULONG lngIndex = max(FindLanguageIndex(LanguageId), 0);
100  return MUILanguageList[lngIndex].OEMCPage;
101 }
102 
103 PCWSTR
105  IN PCWSTR LanguageId)
106 {
107  ULONG lngIndex = max(FindLanguageIndex(LanguageId), 0);
108  return MUILanguageList[lngIndex].GeoID;
109 }
110 
111 const MUI_LAYOUTS*
113  IN PCWSTR LanguageId)
114 {
115  ULONG lngIndex = max(FindLanguageIndex(LanguageId), 0);
116  return MUILanguageList[lngIndex].MuiLayouts;
117 }
118 
119 
120 static
121 BOOLEAN
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 
207 BOOLEAN
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);
248  Status = RtlAppendUnicodeToString(&KeyName, L"\\Preload");
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 
340  RtlInitUnicodeString(&ValueName, szLangID);
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 
372 BOOLEAN
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 
391 static
392 BOOLEAN
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
437  RtlInitUnicodeString(&ValueName, L"OEMCP");
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
452  RtlInitUnicodeString(&ValueName, L"MACCP");
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 
471 static
472 BOOLEAN
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 
534 BOOLEAN
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 */
564 BOOL
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:
585  if (SUBLANGID(LangID) == SUBLANG_CHINESE_SIMPLIFIED)
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 */
#define HKEY_USERS
Definition: winreg.h:13
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define IN
Definition: typedefs.h:39
#define max(a, b)
Definition: svc.c:63
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
#define KEY_SET_VALUE
Definition: nt_native.h:1017
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
BOOLEAN AddKeyboardLayouts(IN PCWSTR LanguageId)
Definition: mui.c:373
MUI_SUBFONT TraditionalChineseFontFixup[]
Definition: muifonts.h:418
#define TRUE
Definition: types.h:120
MUI_SUBFONT FontFixupMSMINCHO[]
Definition: muifonts.h:475
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
PCWSTR GeoID
Definition: mui.h:22
LONG NTSTATUS
Definition: precomp.h:26
MUI_SUBFONT FontFixupGULIM[]
Definition: muifonts.h:484
BOOL bFoundFontMINGLIU
Definition: substset.h:5
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
WORD LANGID
Definition: typedefs.h:81
Definition: mui.h:3
static BOOLEAN AddHotkeySettings(IN PCWSTR Hotkey, IN PCWSTR LangHotkey, IN PCWSTR LayoutHotkey)
Definition: mui.c:122
BOOL bFoundFontGULIM
Definition: substset.h:10
PCWSTR MUIGetOEMCodePage(IN PCWSTR LanguageId)
Definition: mui.c:96
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:50
static BOOLEAN AddFontsSettingsToRegistry(IN const MUI_SUBFONT *MuiSubFonts)
Definition: mui.c:473
PCWSTR OEMCPage
Definition: mui.h:19
MUI_SUBFONT FontFixupSIMSUN[]
Definition: muifonts.h:448
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
BOOL bFoundFontMSMINCHO
Definition: substset.h:9
PCWSTR MUIGetGeoID(IN PCWSTR LanguageId)
Definition: mui.c:104
MUI_SUBFONT FontFixupBATANG[]
Definition: muifonts.h:493
PCWSTR MUIDefaultKeyboardLayout(IN PCWSTR LanguageId)
Definition: mui.c:88
#define LANG_JAPANESE
Definition: nls.h:76
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned char BOOLEAN
const MUI_LAYOUTS * MUIGetLayoutsList(IN PCWSTR LanguageId)
Definition: mui.c:112
smooth NULL
Definition: ftsmooth.c:416
NTSYSAPI NTSTATUS NTAPI NtDeleteValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName)
Definition: ntapi.c:1014
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define KEY_WRITE
Definition: nt_native.h:1031
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static BOOLEAN AddCodepageToRegistry(IN PCWSTR ACPage, IN PCWSTR OEMCPage, IN PCWSTR MACCPage)
Definition: mui.c:393
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ PNDIS_STRING _Out_ PNDIS_HANDLE SubKeyHandle
Definition: ndis.h:4723
Status
Definition: gdiplustypes.h:24
const MUI_LAYOUTS * MuiLayouts
Definition: mui.h:24
static const WCHAR L[]
Definition: oid.c:1250
BOOL bFoundFontBATANG
Definition: substset.h:11
#define SUBLANG_CHINESE_SIMPLIFIED
Definition: nls.h:209
MUI_SUBFONT SimplifiedChineseFontFixup[]
Definition: muifonts.h:411
HANDLE GetRootKeyByPredefKey(IN HANDLE KeyHandle, OUT PCWSTR *RootKeyMountPoint OPTIONAL)
Definition: registry.c:90
MUI_SUBFONT KoreanFontFixup[]
Definition: muifonts.h:432
const MUI_LANGUAGE MUILanguageList[]
Definition: muilanguages.h:412
BOOL bFoundFontMSGOTHIC
Definition: substset.h:8
MUI_SUBFONT FontFixupMSSONG[]
Definition: muifonts.h:458
static ULONG FindLanguageIndex(IN PCWSTR LanguageId)
Definition: mui.c:44
MUI_SUBFONT FontFixupMSGOTHIC[]
Definition: muifonts.h:465
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
BOOLEAN IsLanguageAvailable(IN PCWSTR LanguageId)
Definition: mui.c:70
BOOLEAN AddKbLayoutsToRegistry(IN const MUI_LAYOUTS *MuiLayouts)
Definition: mui.c:208
#define DPRINT1
Definition: precomp.h:8
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
#define LANG_CHINESE
Definition: nls.h:42
BOOL DoRegistryFontFixup(PFONTSUBSTSETTINGS pSettings, LANGID LangID)
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define LANG_KOREAN
Definition: nls.h:84
MUI_SUBFONT JapaneseFontFixup[]
Definition: muifonts.h:425
PCWSTR LayoutID
Definition: mui.h:12
BOOLEAN AddCodePage(IN PCWSTR LanguageId)
Definition: mui.c:535
Definition: mui.h:9
BOOL bFoundFontSIMSUN
Definition: substset.h:6
#define KEY_CREATE_SUB_KEY
Definition: nt_native.h:1018
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
BOOL bFoundFontMSSONG
Definition: substset.h:7
MUI_SUBFONT FontFixupMINGLIU[]
Definition: muifonts.h:439
#define PRIMARYLANGID(l)
Definition: nls.h:16
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define REG_SZ
Definition: layer.c:22
#define SUBLANGID(l)
Definition: nls.h:17