ReactOS 0.4.15-dev-7788-g1ad9096
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 */
18static BOOL
19IsLayoutExists(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;
27
28 if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Keyboard Layout\\Preload",
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 {
39 return FALSE;
40 }
41
42 langid = (LANGID)wcstoul(szPreload, NULL, 16);
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);
63 return TRUE;
64 }
65 }
66 }
67 else
68 {
69 if ((wcscmp(szPreload, szLayoutID) == 0) && (IsLangExists))
70 {
72 return TRUE;
73 }
74 }
75
76 IsLangExists = FALSE;
77 dwSize = sizeof(szLayoutNum);
78 dwIndex++;
79 }
80
82 }
83
84 return FALSE;
85}
86
87static 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",
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
115 }
116
117 return Count;
118}
119
120/* szLayoutID like 00000409, szLangID like 00000409 */
121static BOOL
122AddNewLayout(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 {
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 {
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);
168 return FALSE;
169 }
170 RegCloseKey(hSubKey);
171 }
172 lstrcpy(szLayoutID, SubPath);
173 }
174
176 NewLayout,
177 0,
178 REG_SZ,
179 (LPBYTE)szLayoutID,
180 (DWORD)((CCH_LAYOUT_ID + 1) * sizeof(WCHAR)));
181 }
183 }
184
185 return TRUE;
186}
187
188VOID
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}
char szTmp[518]
#define RegCloseKey(hKey)
Definition: registry.h:49
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
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:1096
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3362
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:4911
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:2859
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4132
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define MAX_PATH
Definition: compat.h:34
HINF WINAPI SetupOpenInfFileW(PCWSTR name, PCWSTR class, DWORD style, UINT *error)
Definition: parser.c:1229
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
GLsizei GLenum const GLvoid GLsizei GLenum 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 const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum 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 const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define MAX_STR_SIZE
Definition: hdwwiz.h:21
_Check_return_ unsigned long __cdecl wcstoul(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
_CRTIMP wchar_t *__cdecl _ultow(_In_ unsigned long _Value, _Pre_notnull_ _Post_z_ wchar_t *_Dest, _In_ int _Radix)
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define INF_STYLE_WIN4
Definition: infsupp.h:41
#define CCH_LAYOUT_ID
Definition: kblayouts.c:11
VOID AddNewKbLayoutsByLcid(LCID Lcid)
Definition: kblayouts.c:189
static BOOL IsLayoutExists(PWSTR szLayoutID, PWSTR szLangID)
Definition: kblayouts.c:19
static BOOL AddNewLayout(PWSTR szLayoutID, PWSTR szLangID)
Definition: kblayouts.c:122
static INT GetLayoutCount(PWSTR szLang)
Definition: kblayouts.c:88
#define CCH_ULONG_DEC
Definition: kblayouts.c:14
INT WINAPI GetLocaleInfoW(LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len)
Definition: lang.c:1108
#define REG_SZ
Definition: layer.c:22
USHORT LANGID
Definition: mui.h:9
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
LANGID langid
Definition: msctf.idl:644
unsigned int UINT
Definition: ndis.h:50
int Count
Definition: noreturn.cpp:7
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define SORT_DEFAULT
#define MAKELCID(lgid, srtid)
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
DWORD LCID
Definition: nls.h:13
#define SetupFindFirstLine
Definition: setupapi.h:2624
#define SetupGetStringField
Definition: setupapi.h:2639
#define SetupGetLineCount
Definition: setupapi.h:2633
#define SetupOpenAppendInfFile
Definition: setupapi.h:2651
uint16_t * PWSTR
Definition: typedefs.h:56
unsigned char * LPBYTE
Definition: typedefs.h:53
int32_t INT
Definition: typedefs.h:58
ULONG WINAPI SetupGetFieldCount(IN PINFCONTEXT Context)
Definition: infsupp.c:93
VOID WINAPI SetupCloseInfFile(IN HINF InfHandle)
Definition: infsupp.c:45
_In_ WDFCOLLECTION _In_ ULONG Index
_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 lstrcpy
Definition: winbase.h:3809
#define LOCALE_ILANGUAGE
Definition: winnls.h:25
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define RegEnumValue
Definition: winreg.h:511
#define RegQueryInfoKey
Definition: winreg.h:521
#define wsprintf
Definition: winuser.h:5865
_In_ CONST DEVPROPKEY _In_ LCID Lcid
Definition: iofuncs.h:2415
__wchar_t WCHAR
Definition: xmlstorage.h:180