ReactOS 0.4.15-dev-5896-g3f5bcf5
layout_list.c
Go to the documentation of this file.
1/*
2 * PROJECT: input.dll
3 * FILE: dll/cpl/input/layout_list.c
4 * PURPOSE: input.dll
5 * PROGRAMMER: Dmitry Chapyshev (dmitry@reactos.org)
6 * Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
7 */
8
9#include "layout_list.h"
10
12
13static LAYOUT_LIST_NODE*
14LayoutList_AppendNode(DWORD dwKLID, WORD wSpecialId, LPCWSTR pszFile, LPCWSTR pszName,
15 LPCWSTR pszImeFile)
16{
17 LAYOUT_LIST_NODE *pCurrent;
18 LAYOUT_LIST_NODE *pNew;
19
20 if (pszName == NULL)
21 return NULL;
22
23 pCurrent = _LayoutList;
24
26 if (pNew == NULL)
27 return NULL;
28
29 ZeroMemory(pNew, sizeof(LAYOUT_LIST_NODE));
30
31 pNew->dwKLID = dwKLID;
32 pNew->wSpecialId = wSpecialId;
33
34 pNew->pszName = _wcsdup(pszName);
35 pNew->pszFile = _wcsdup(pszFile);
36 pNew->pszImeFile = _wcsdup(pszImeFile);
37 if (pNew->pszName == NULL || pNew->pszFile == NULL ||
38 (pszImeFile && pNew->pszImeFile == NULL))
39 {
40 free(pNew->pszName);
41 free(pNew->pszFile);
42 free(pNew->pszImeFile);
43 free(pNew);
44 return NULL;
45 }
46
47 if (pCurrent == NULL)
48 {
49 _LayoutList = pNew;
50 }
51 else
52 {
53 while (pCurrent->pNext != NULL)
54 {
55 pCurrent = pCurrent->pNext;
56 }
57
58 pNew->pPrev = pCurrent;
59 pCurrent->pNext = pNew;
60 }
61
62 return pNew;
63}
64
65
66VOID
68{
69 LAYOUT_LIST_NODE *pCurrent;
70 LAYOUT_LIST_NODE *pNext;
71
72 if (_LayoutList == NULL)
73 return;
74
75 for (pCurrent = _LayoutList; pCurrent; pCurrent = pNext)
76 {
77 pNext = pCurrent->pNext;
78
79 free(pCurrent->pszName);
80 free(pCurrent->pszFile);
81 free(pCurrent->pszImeFile);
82 free(pCurrent);
83 }
84
86}
87
89
90/* FIXME: Use shlwapi!SHLoadRegUIStringW instead when it is fully implemented */
92{
93#if 1
95 WCHAR szDllPath[MAX_PATH];
98 INT iIndex, iLength;
99
100 dwSize = size * sizeof(WCHAR);
102 return E_FAIL;
103
104 if (buf[0] != L'@')
105 return S_OK;
106
107 /* Move to the position after the character "@" */
108 pBuffer = buf + 1;
109
110 /* Get a pointer to the beginning ",-" */
111 pIndex = wcsstr(pBuffer, L",-");
112 if (!pIndex)
113 return E_FAIL;
114
115 /* Convert the number in the string after the ",-" */
116 iIndex = _wtoi(pIndex + 2);
117
118 *pIndex = 0; /* Cut the string */
119
120 if (ExpandEnvironmentStringsW(pBuffer, szDllPath, ARRAYSIZE(szDllPath)) == 0)
121 return E_FAIL;
122
123 hDllInst = LoadLibraryW(szDllPath);
124 if (!hDllInst)
125 return E_FAIL;
126
127 iLength = LoadStringW(hDllInst, iIndex, buf, size);
129
130 if (iLength <= 0)
131 return E_FAIL;
132
133 return S_OK;
134#else
135 HRESULT hr = E_FAIL;
136 HINSTANCE hSHLWAPI = LoadLibraryW(L"shlwapi");
139 if (fn)
140 hr = fn(hkey, value, buf, size);
141 FreeLibrary(hSHLWAPI);
142 return hr;
143#endif
144}
145
146static BOOL
147LayoutList_ReadLayout(HKEY hLayoutKey, LPCWSTR szKLID, LPCWSTR szSystemDirectory)
148{
149 WCHAR szFile[80], szImeFile[80], szBuffer[MAX_PATH], szFilePath[MAX_PATH];
150 DWORD dwSize, dwKLID = DWORDfromString(szKLID);
151 WORD wSpecialId = 0;
152 LPWSTR pszImeFile = NULL;
153
154 dwSize = sizeof(szFile);
155 if (RegQueryValueExW(hLayoutKey, L"Layout File", NULL, NULL,
156 (LPBYTE)szFile, &dwSize) != ERROR_SUCCESS)
157 {
158 return FALSE; /* No "Layout File" value */
159 }
160
161 if (IS_IME_KLID(dwKLID))
162 {
164 dwSize = sizeof(szImeFile);
165 if (RegQueryValueExW(hLayoutKey, L"IME File", NULL, NULL,
166 (LPBYTE)szImeFile, &dwSize) != ERROR_SUCCESS)
167 {
168 return FALSE; /* No "IME File" value */
169 }
170
171 if (wcschr(szImeFile, L'\\') != NULL)
172 return FALSE; /* Invalid character */
173
176 return FALSE; /* Does not exist */
177
178 pszImeFile = szImeFile;
179 }
180
181 /* Build the "Layout File" full path and check existence */
182 StringCchPrintfW(szFilePath, ARRAYSIZE(szFilePath), L"%s\\%s", szSystemDirectory, szFile);
184 return FALSE; /* No layout file found */
185
186 /* Get the special ID */
187 dwSize = sizeof(szBuffer);
188 if (RegQueryValueExW(hLayoutKey, L"Layout Id", NULL, NULL,
189 (LPBYTE)szBuffer, &dwSize) == ERROR_SUCCESS)
190 {
191 wSpecialId = LOWORD(DWORDfromString(szBuffer));
192 }
193
194 /* If there is a valid "Layout Display Name", then use it as the entry name */
195 if (FakeSHLoadRegUIStringW(hLayoutKey, L"Layout Display Name",
196 szBuffer, ARRAYSIZE(szBuffer)) == S_OK)
197 {
198 LayoutList_AppendNode(dwKLID, wSpecialId, szFile, szBuffer, pszImeFile);
199 return TRUE;
200 }
201
202 /* Otherwise, use "Layout Text" value as the entry name */
203 dwSize = sizeof(szBuffer);
204 if (RegQueryValueExW(hLayoutKey, L"Layout Text", NULL, NULL,
205 (LPBYTE)szBuffer, &dwSize) == ERROR_SUCCESS)
206 {
207 LayoutList_AppendNode(dwKLID, wSpecialId, szFile, szBuffer, pszImeFile);
208 return TRUE;
209 }
210
211 return FALSE;
212}
213
214VOID
216{
217 WCHAR szSystemDirectory[MAX_PATH], szKLID[KL_NAMELENGTH];
218 DWORD dwSize, dwIndex;
219 HKEY hKey, hLayoutKey;
220
221 if (!GetSystemDirectoryW(szSystemDirectory, ARRAYSIZE(szSystemDirectory)))
222 return;
223
224 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts",
225 0, KEY_READ, &hKey) != ERROR_SUCCESS)
226 {
227 return;
228 }
229
230 for (dwIndex = 0; ; ++dwIndex)
231 {
232 dwSize = ARRAYSIZE(szKLID);
233 if (RegEnumKeyExW(hKey, dwIndex, szKLID, &dwSize, NULL, NULL,
235 {
236 break;
237 }
238
239 if (RegOpenKeyExW(hKey, szKLID, 0, KEY_QUERY_VALUE, &hLayoutKey) == ERROR_SUCCESS)
240 {
241 LayoutList_ReadLayout(hLayoutKey, szKLID, szSystemDirectory);
242 RegCloseKey(hLayoutKey);
243 }
244 }
245
247}
248
249
252{
253 LAYOUT_LIST_NODE *pCurrent;
254
255 if (IS_SPECIAL_HKL(hkl))
256 {
257 WORD wSpecialId = SPECIALIDFROMHKL(hkl);
258
259 for (pCurrent = _LayoutList; pCurrent != NULL; pCurrent = pCurrent->pNext)
260 {
261 if (wSpecialId == pCurrent->wSpecialId)
262 {
263 return pCurrent;
264 }
265 }
266 }
267 else if (IS_IME_HKL(hkl))
268 {
269 for (pCurrent = _LayoutList; pCurrent != NULL; pCurrent = pCurrent->pNext)
270 {
271 if (hkl == UlongToHandle(pCurrent->dwKLID))
272 {
273 return pCurrent;
274 }
275 }
276 }
277 else
278 {
279 for (pCurrent = _LayoutList; pCurrent != NULL; pCurrent = pCurrent->pNext)
280 {
281 if (HIWORD(hkl) == LOWORD(pCurrent->dwKLID))
282 {
283 return pCurrent;
284 }
285 }
286 }
287
288 return NULL;
289}
290
291
294{
295 return _LayoutList;
296}
#define UlongToHandle(ul)
Definition: basetsd.h:97
HANDLE HKEY
Definition: registry.h:26
#define RegCloseKey(hKey)
Definition: registry.h:47
#define E_FAIL
Definition: ddrawi.h:102
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#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
static DWORD DWORDfromString(const WCHAR *pszString)
Definition: input.h:77
#define SPECIALIDFROMHKL(hKL)
Definition: input.h:90
#define IS_SPECIAL_HKL(hKL)
Definition: input.h:89
#define IS_IME_KLID(dwKLID)
Definition: input.h:92
#define IS_IME_HKL(hKL)
Definition: input.h:88
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3356
LONG WINAPI RegEnumKeyExW(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPWSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2527
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4121
#define wcschr
Definition: compat.h:17
#define GetProcAddress(x, y)
Definition: compat.h:753
#define FreeLibrary(x)
Definition: compat.h:748
#define MAX_PATH
Definition: compat.h:34
#define LoadLibraryW(x)
Definition: compat.h:747
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:652
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2313
HINSTANCE hDllInst
Definition: system.c:45
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
FxAutoRegKey hKey
GLsizeiptr size
Definition: glext.h:5919
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
_Check_return_ _CRTIMP int __cdecl _wtoi(_In_z_ const wchar_t *_Str)
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
#define S_OK
Definition: intsafe.h:52
static BOOL GetSystemLibraryPath(LPTSTR szPath, SIZE_T cchPath, LPCTSTR FileName)
Definition: kbswitch.c:85
VOID LayoutList_Create(VOID)
Definition: layout_list.c:215
VOID LayoutList_Destroy(VOID)
Definition: layout_list.c:67
LAYOUT_LIST_NODE * LayoutList_GetByHkl(HKL hkl)
Definition: layout_list.c:251
static LAYOUT_LIST_NODE * _LayoutList
Definition: layout_list.c:11
HRESULT FakeSHLoadRegUIStringW(HKEY hkey, LPCWSTR value, LPWSTR buf, DWORD size)
Definition: layout_list.c:91
LAYOUT_LIST_NODE * LayoutList_GetFirst(VOID)
Definition: layout_list.c:293
static LAYOUT_LIST_NODE * LayoutList_AppendNode(DWORD dwKLID, WORD wSpecialId, LPCWSTR pszFile, LPCWSTR pszName, LPCWSTR pszImeFile)
Definition: layout_list.c:14
static BOOL LayoutList_ReadLayout(HKEY hLayoutKey, LPCWSTR szKLID, LPCWSTR szSystemDirectory)
Definition: layout_list.c:147
HRESULT(WINAPI * FN_SHLoadRegUIStringW)(HKEY, LPCWSTR, LPWSTR, DWORD)
Definition: layout_list.c:88
LPCWSTR szPath
Definition: env.c:37
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
HKL hkl
Definition: msctf.idl:611
UINT_PTR HKL
Definition: msctf.idl:104
_Out_ PULONG _Out_ PULONG pIndex
Definition: ndis.h:4565
#define KEY_READ
Definition: nt_native.h:1023
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define DWORD
Definition: nt_native.h:44
#define L(x)
Definition: ntvdm.h:50
#define LOWORD(l)
Definition: pedump.c:82
static WCHAR szFilePath[]
Definition: qotd.c:14
PVOID pBuffer
_Check_return_ _CRTIMP wchar_t *__cdecl _wcsdup(_In_z_ const wchar_t *_Str)
HRESULT hr
Definition: shlfolder.c:183
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
struct _LAYOUT_LIST_NODE * pPrev
Definition: layout_list.h:13
struct _LAYOUT_LIST_NODE * pNext
Definition: layout_list.h:14
int32_t INT_PTR
Definition: typedefs.h:64
unsigned char * LPBYTE
Definition: typedefs.h:53
int32_t INT
Definition: typedefs.h:58
uint16_t * PWCHAR
Definition: typedefs.h:56
#define HIWORD(l)
Definition: typedefs.h:247
Definition: pdh_main.c:94
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159
#define ZeroMemory
Definition: winbase.h:1670
#define HRESULT
Definition: msvc.h:7
#define WINAPI
Definition: msvc.h:6
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define KL_NAMELENGTH
Definition: winuser.h:122
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185