ReactOS  0.4.15-dev-5142-g967f5b9
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 
13 static LAYOUT_LIST_NODE*
14 LayoutList_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 
25  pNew = (LAYOUT_LIST_NODE*)malloc(sizeof(LAYOUT_LIST_NODE));
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 
66 VOID
68 {
69  LAYOUT_LIST_NODE *pCurrent;
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 
85  _LayoutList = NULL;
86 }
87 
89 
90 /* FIXME: Use shlwapi!SHLoadRegUIStringW instead when it is fully implemented */
92 {
93 #if 1
95  WCHAR szDllPath[MAX_PATH];
96  DWORD dwSize;
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 
146 static BOOL
147 LayoutList_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 
214 VOID
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,
234  NULL, NULL) != ERROR_SUCCESS)
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 
246  RegCloseKey(hKey);
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 IS_SPECIAL_HKL(hKL)
Definition: input.h:89
#define HRESULT
Definition: msvc.h:7
Definition: pdh_main.c:93
VOID GetSystemLibraryPath(LPWSTR pszPath, INT cchPath, LPCWSTR pszFileName)
Definition: input_list.c:42
#define KL_NAMELENGTH
Definition: winuser.h:122
static WCHAR szFilePath[]
Definition: qotd.c:14
#define ERROR_SUCCESS
Definition: deptool.c:10
HRESULT hr
Definition: shlfolder.c:183
#define IS_IME_KLID(dwKLID)
Definition: input.h:92
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
HINSTANCE hDllInst
Definition: system.c:45
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159
#define KEY_READ
Definition: nt_native.h:1023
#define TRUE
Definition: types.h:120
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
HRESULT FakeSHLoadRegUIStringW(HKEY hkey, LPCWSTR value, LPWSTR buf, DWORD size)
Definition: layout_list.c:91
_Check_return_ _CRTIMP int __cdecl _wtoi(_In_z_ const wchar_t *_Str)
#define free
Definition: debug_ros.c:5
VOID LayoutList_Create(VOID)
Definition: layout_list.c:215
LAYOUT_LIST_NODE * LayoutList_GetFirst(VOID)
Definition: layout_list.c:293
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define ZeroMemory
Definition: winbase.h:1667
uint16_t * PWCHAR
Definition: typedefs.h:56
int32_t INT_PTR
Definition: typedefs.h:64
static LAYOUT_LIST_NODE * LayoutList_AppendNode(DWORD dwKLID, WORD wSpecialId, LPCWSTR pszFile, LPCWSTR pszName, LPCWSTR pszImeFile)
Definition: layout_list.c:14
#define E_FAIL
Definition: ddrawi.h:102
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
#define DWORD
Definition: nt_native.h:44
int32_t INT
Definition: typedefs.h:58
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define L(x)
Definition: ntvdm.h:50
unsigned char * LPBYTE
Definition: typedefs.h:53
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:652
#define LoadLibraryW(x)
Definition: compat.h:606
PVOID pBuffer
static LAYOUT_LIST_NODE * _LayoutList
Definition: layout_list.c:11
static BOOL LayoutList_ReadLayout(HKEY hLayoutKey, LPCWSTR szKLID, LPCWSTR szSystemDirectory)
Definition: layout_list.c:147
const char * LPCSTR
Definition: xmlstorage.h:183
LAYOUT_LIST_NODE * LayoutList_GetByHkl(HKL hkl)
Definition: layout_list.c:251
struct _LAYOUT_LIST_NODE * pNext
Definition: layout_list.h:14
#define FreeLibrary(x)
Definition: compat.h:607
GLsizeiptr size
Definition: glext.h:5919
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4120
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:79
#define UlongToHandle(ul)
Definition: basetsd.h:97
#define MAX_PATH
Definition: compat.h:34
#define WINAPI
Definition: msvc.h:6
unsigned short WORD
Definition: ntddk_ex.h:93
#define SPECIALIDFROMHKL(hKL)
Definition: input.h:90
unsigned long DWORD
Definition: ntddk_ex.h:95
VOID LayoutList_Destroy(VOID)
Definition: layout_list.c:67
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
UINT_PTR HKL
Definition: msctf.idl:101
#define S_OK
Definition: intsafe.h:52
HKL hkl
Definition: msctf.idl:611
#define IS_IME_HKL(hKL)
Definition: input.h:88
_Out_ PULONG _Out_ PULONG pIndex
Definition: ndis.h:4564
FxAutoRegKey hKey
LPCWSTR szPath
Definition: env.c:37
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2313
#define NULL
Definition: types.h:112
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
HRESULT(WINAPI * FN_SHLoadRegUIStringW)(HKEY, LPCWSTR, LPWSTR, DWORD)
Definition: layout_list.c:88
static DWORD DWORDfromString(const WCHAR *pszString)
Definition: input.h:77
struct _LAYOUT_LIST_NODE * pPrev
Definition: layout_list.h:13
struct _INPUT_LIST_NODE * pNext
Definition: input_list.h:44
#define HIWORD(l)
Definition: typedefs.h:247
HANDLE HKEY
Definition: registry.h:26
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3356
#define GetProcAddress(x, y)
Definition: compat.h:612
#define malloc
Definition: debug_ros.c:4
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
WCHAR * LPWSTR
Definition: xmlstorage.h:184
_Check_return_ _CRTIMP wchar_t *__cdecl _wcsdup(_In_z_ const wchar_t *_Str)
#define LOWORD(l)
Definition: pedump.c:82
#define RegCloseKey(hKey)
Definition: registry.h:47
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12