ReactOS  r76032
kblayouts.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS International Control Panel
3  * FILE: dll/cpl/intl/kblayouts.c
4  * PURPOSE: Functions for manipulation with keyboard layouts
5  * PROGRAMMER: Dmitry Chapyshev (dmitry@reactos.org)
6  */
7 
8 #include "intl.h"
9 
10 /* Character Count of a layout ID like "00000409" */
11 #define CCH_LAYOUT_ID 8
12 
13 /* Maximum Character Count of a ULONG in decimal */
14 #define CCH_ULONG_DEC 10
15 
16 
17 /* szLayoutID like 00000409, szLangID like 00000409 */
18 static BOOL
19 IsLayoutExists(PWSTR szLayoutID, PWSTR szLangID)
20 {
21  HKEY hKey, hSubKey;
22  WCHAR szPreload[CCH_LAYOUT_ID + 1], szLayoutNum[3 + 1],
23  szTmp[CCH_LAYOUT_ID + 1], szOldLangID[CCH_LAYOUT_ID + 1];
24  DWORD dwIndex = 0, dwType, dwSize;
25  BOOL IsLangExists = FALSE;
26  LANGID langid;
27 
28  if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Keyboard Layout\\Preload",
29  0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
30  {
31  dwSize = sizeof(szLayoutNum);
32 
33  while (RegEnumValueW(hKey, dwIndex, szLayoutNum, &dwSize, NULL, &dwType, NULL, NULL) == ERROR_SUCCESS)
34  {
35  dwSize = sizeof(szPreload);
36  if (RegQueryValueExW(hKey, szLayoutNum, NULL, NULL, (LPBYTE)szPreload, &dwSize) != ERROR_SUCCESS)
37  {
38  RegCloseKey(hKey);
39  return FALSE;
40  }
41 
42  langid = (LANGID)wcstoul(szPreload, NULL, 16);
43  GetLocaleInfoW(langid, LOCALE_ILANGUAGE, szTmp, sizeof(szTmp) / sizeof(WCHAR));
44  wsprintf(szOldLangID, L"0000%s", szTmp);
45 
46  if (wcscmp(szOldLangID, szLangID) == 0)
47  IsLangExists = TRUE;
48  else
49  IsLangExists = FALSE;
50 
51  if (szPreload[0] == 'd')
52  {
53  if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Keyboard Layout\\Substitutes",
54  0, KEY_QUERY_VALUE, &hSubKey) == ERROR_SUCCESS)
55  {
56  dwSize = sizeof(szTmp);
57  RegQueryValueExW(hSubKey, szPreload, NULL, NULL, (LPBYTE)szTmp, &dwSize);
58 
59  if ((wcscmp(szTmp, szLayoutID) == 0)&&(IsLangExists))
60  {
61  RegCloseKey(hSubKey);
62  RegCloseKey(hKey);
63  return TRUE;
64  }
65  }
66  }
67  else
68  {
69  if ((wcscmp(szPreload, szLayoutID) == 0) && (IsLangExists))
70  {
71  RegCloseKey(hKey);
72  return TRUE;
73  }
74  }
75 
76  IsLangExists = FALSE;
77  dwSize = sizeof(szLayoutNum);
78  dwIndex++;
79  }
80 
81  RegCloseKey(hKey);
82  }
83 
84  return FALSE;
85 }
86 
87 static INT
89 {
90  HKEY hKey;
91  WCHAR szLayoutID[3 + 1], szPreload[CCH_LAYOUT_ID + 1], szLOLang[MAX_PATH];
92  DWORD dwIndex = 0, dwType, dwSize;
93  UINT Count = 0, i, j;
94 
95  if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Keyboard Layout\\Preload",
96  0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
97  {
98  dwSize = sizeof(szLayoutID);
99 
100  while (RegEnumValue(hKey, dwIndex, szLayoutID, &dwSize, NULL, &dwType, NULL, NULL) == ERROR_SUCCESS)
101  {
102  dwSize = sizeof(szPreload);
103  RegQueryValueExW(hKey, szLayoutID, NULL, NULL, (LPBYTE)szPreload, &dwSize);
104 
105  for (i = 4, j = 0; i < wcslen(szPreload)+1; i++, j++)
106  szLOLang[j] = szPreload[i];
107 
108  if (wcscmp(szLOLang, szLang) == 0) Count += 1;
109 
110  dwSize = sizeof(szLayoutID);
111  dwIndex++;
112  }
113 
114  RegCloseKey(hKey);
115  }
116 
117  return Count;
118 }
119 
120 /* szLayoutID like 00000409, szLangID like 00000409 */
121 static BOOL
122 AddNewLayout(PWSTR szLayoutID, PWSTR szLangID)
123 {
124  WCHAR NewLayout[CCH_ULONG_DEC + 1], Lang[MAX_PATH],
125  LangID[CCH_LAYOUT_ID + 1], SubPath[CCH_LAYOUT_ID + 1];
126  HKEY hKey, hSubKey;
127  DWORD cValues;
128  LCID lcid;
129 
130  if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Keyboard Layout\\Preload", 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
131  {
132  if (RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &cValues, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
133  {
134  _ultow(cValues + 1, NewLayout, 10);
135 
136  lcid = wcstoul(szLangID, NULL, 16);
137 
138  GetLocaleInfoW(MAKELCID(lcid, SORT_DEFAULT), LOCALE_ILANGUAGE, Lang, sizeof(Lang) / sizeof(WCHAR));
139  wsprintf(LangID, L"0000%s", Lang);
140 
141  if (IsLayoutExists(szLayoutID, LangID))
142  {
143  RegCloseKey(hKey);
144  return FALSE;
145  }
146 
147  if (GetLayoutCount(Lang) >= 1)
148  {
149  wsprintf(SubPath, L"d%03d%s", GetLayoutCount(Lang), Lang);
150  }
151  else if ((wcscmp(LangID, szLayoutID) != 0) && (GetLayoutCount(Lang) == 0))
152  {
153  wsprintf(SubPath, L"d%03d%s", 0, Lang);
154  }
155  else SubPath[0] = L'\0';
156 
157  if (wcslen(SubPath) != 0)
158  {
159  if (RegCreateKeyExW(HKEY_CURRENT_USER, L"Keyboard Layout\\Substitutes", 0, NULL,
161  NULL, &hSubKey, NULL) == ERROR_SUCCESS)
162  {
163  if (RegSetValueExW(hSubKey, SubPath, 0, REG_SZ, (LPBYTE)szLayoutID,
164  (DWORD)((CCH_LAYOUT_ID + 1) * sizeof(WCHAR))) != ERROR_SUCCESS)
165  {
166  RegCloseKey(hSubKey);
167  RegCloseKey(hKey);
168  return FALSE;
169  }
170  RegCloseKey(hSubKey);
171  }
172  lstrcpy(szLayoutID, SubPath);
173  }
174 
175  RegSetValueExW(hKey,
176  NewLayout,
177  0,
178  REG_SZ,
179  (LPBYTE)szLayoutID,
180  (DWORD)((CCH_LAYOUT_ID + 1) * sizeof(WCHAR)));
181  }
182  RegCloseKey(hKey);
183  }
184 
185  return TRUE;
186 }
187 
188 VOID
190 {
191  HINF hIntlInf;
192  WCHAR szLang[CCH_LAYOUT_ID + 1], szLangID[CCH_LAYOUT_ID + 1];
193  WCHAR szLangStr[MAX_STR_SIZE], szLayoutStr[MAX_STR_SIZE], szStr[MAX_STR_SIZE];
194  INFCONTEXT InfContext;
195  LONG Count;
196  DWORD FieldCount, Index;
197 
198  GetLocaleInfoW(MAKELCID(Lcid, SORT_DEFAULT), LOCALE_ILANGUAGE, szLang, sizeof(szLang) / sizeof(WCHAR));
199  wsprintf(szLangID, L"0000%s", szLang);
200 
201  hIntlInf = SetupOpenInfFileW(L"intl.inf", NULL, INF_STYLE_WIN4, NULL);
202 
203  if (hIntlInf == INVALID_HANDLE_VALUE)
204  return;
205 
206  if (!SetupOpenAppendInfFile(NULL, hIntlInf, NULL))
207  {
208  SetupCloseInfFile(hIntlInf);
209  hIntlInf = NULL;
210  return;
211  }
212 
213  Count = SetupGetLineCount(hIntlInf, L"Locales");
214  if (Count <= 0) return;
215 
216  if (SetupFindFirstLine(hIntlInf, L"Locales", szLangID, &InfContext))
217  {
218  FieldCount = SetupGetFieldCount(&InfContext);
219 
220  if (FieldCount != 0)
221  {
222  for (Index = 5; Index <= FieldCount; Index++)
223  {
224  if (SetupGetStringField(&InfContext, Index, szStr, MAX_STR_SIZE, NULL))
225  {
226  INT i, j;
227 
228  if (wcslen(szStr) != 13) continue;
229 
230  wsprintf(szLangStr, L"0000%s", szStr);
231  szLangStr[8] = L'\0';
232 
233  for (i = 5, j = 0; i <= wcslen(szStr); i++, j++)
234  szLayoutStr[j] = szStr[i];
235 
236  AddNewLayout(szLayoutStr, szLangStr);
237  }
238  }
239  }
240  }
241  SetupCloseInfFile(hIntlInf);
242 }
#define MAKELCID(lgid, srtid)
_CRTIMP wchar_t *__cdecl _ultow(_In_ unsigned long _Value, _Pre_notnull_ _Post_z_ wchar_t *_Dest, _In_ int _Radix)
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint j
Definition: glfuncs.h:98
#define TRUE
Definition: types.h:120
#define RegQueryInfoKey
Definition: winreg.h:521
#define ERROR_SUCCESS
Definition: deptool.c:10
_In_ CONST DEVPROPKEY _In_ LCID Lcid
Definition: iofuncs.h:2408
#define SetupOpenAppendInfFile
Definition: setupapi.h:2645
Definition: bidi.c:75
#define SetupFindFirstLine
Definition: setupapi.h:2618
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define HKEY_CURRENT_USER
Definition: winreg.h:11
unsigned char * LPBYTE
Definition: typedefs.h:52
PVOID *typedef PWSTR
Definition: winlogon.h:57
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
#define CCH_LAYOUT_ID
Definition: kblayouts.c:11
DWORD LCID
Definition: nls.h:13
WORD LANGID
Definition: typedefs.h:79
#define LOCALE_ILANGUAGE
Definition: winnls.h:25
_Check_return_ unsigned long __cdecl wcstoul(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
_Must_inspect_result_ _In_ ULONG Index
Definition: fltkernel.h:1824
HINF WINAPI SetupOpenInfFileW(PCWSTR name, PCWSTR class, DWORD style, UINT *error)
Definition: parser.c:1229
LANGID langid
Definition: msctf.idl:605
int32_t INT
Definition: typedefs.h:56
DWORD DWORD
Definition: winlogon.h:75
static BOOL IsLayoutExists(PWSTR szLayoutID, PWSTR szLangID)
Definition: kblayouts.c:19
static BOOL AddNewLayout(PWSTR szLayoutID, PWSTR szLangID)
Definition: kblayouts.c:122
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1094
#define CCH_ULONG_DEC
Definition: kblayouts.c:14
#define INF_STYLE_WIN4
Definition: setupapi.h:440
INT WINAPI GetLocaleInfoW(LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len)
Definition: lang.c:807
GLenum GLclampf GLint i
Definition: glfuncs.h:14
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
DWORD WINAPI SetupGetFieldCount(PINFCONTEXT context)
Definition: parser.c:1858
LONG WINAPI RegEnumValueW(_In_ HKEY hKey, _In_ DWORD index, _Out_ LPWSTR value, _Inout_ PDWORD val_count, _Reserved_ PDWORD reserved, _Out_opt_ PDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ PDWORD count)
Definition: reg.c:2867
smooth NULL
Definition: ftsmooth.c:557
#define MAX_STR_SIZE
Definition: hdwwiz.h:21
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4917
unsigned int BOOL
Definition: ntddk_ex.h:94
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4134
#define SORT_DEFAULT
HANDLE HKEY
Definition: registry.h:24
#define MAX_PATH
Definition: compat.h:26
#define SetupGetStringField
Definition: setupapi.h:2633
char szTmp[512]
PULONG HINF
Definition: inffile.h:37
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define lstrcpy
Definition: winbase.h:3636
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
unsigned int UINT
Definition: ndis.h:50
#define SetupGetLineCount
Definition: setupapi.h:2627
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3381
LONG RegEnumValue(HKEY Key, ULONG Index, PWCHAR ValueName, ULONG *NameSize, ULONG *Type, PUCHAR Data, ULONG *DataSize)
#define wsprintf
Definition: winuser.h:5710
VOID AddNewKbLayoutsByLcid(LCID Lcid)
Definition: kblayouts.c:189
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
void WINAPI SetupCloseInfFile(HINF hinf)
Definition: parser.c:1393
static INT GetLayoutCount(PWSTR szLang)
Definition: kblayouts.c:88
#define REG_SZ
Definition: layer.c:22
DWORD dwSize
Definition: wglext.h:734