Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253/* * PROJECT: input.dll * FILE: dll/cpl/input/layout_list.c * PURPOSE: input.dll * PROGRAMMER: Dmitry Chapyshev (dmitry@reactos.org) * Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) */
#include "layout_list.h"
static LAYOUT_LIST_NODE *_LayoutList = NULL;
static LAYOUT_LIST_NODE*LayoutList_AppendNode(DWORD dwKLID, WORD wSpecialId, LPCWSTR pszFile, LPCWSTR pszName, LPCWSTR pszImeFile){ LAYOUT_LIST_NODE *pCurrent; LAYOUT_LIST_NODE *pNew;
if (pszName == NULL) return NULL;
pCurrent = _LayoutList;
pNew = (LAYOUT_LIST_NODE*)malloc(sizeof(LAYOUT_LIST_NODE)); if (pNew == NULL) return NULL;
ZeroMemory(pNew, sizeof(LAYOUT_LIST_NODE));
pNew->dwKLID = dwKLID; pNew->wSpecialId = wSpecialId;
pNew->pszName = _wcsdup(pszName); pNew->pszFile = _wcsdup(pszFile); pNew->pszImeFile = _wcsdup(pszImeFile); if (pNew->pszName == NULL || pNew->pszFile == NULL || (pszImeFile && pNew->pszImeFile == NULL)) { free(pNew->pszName); free(pNew->pszFile); free(pNew->pszImeFile); free(pNew); return NULL; }
if (pCurrent == NULL) { _LayoutList = pNew; } else { while (pCurrent->pNext != NULL) { pCurrent = pCurrent->pNext; }
pNew->pPrev = pCurrent; pCurrent->pNext = pNew; }
return pNew;}
VOIDLayoutList_Destroy(VOID){ LAYOUT_LIST_NODE *pCurrent; LAYOUT_LIST_NODE *pNext;
if (_LayoutList == NULL) return;
for (pCurrent = _LayoutList; pCurrent; pCurrent = pNext) { pNext = pCurrent->pNext;
free(pCurrent->pszName); free(pCurrent->pszFile); free(pCurrent->pszImeFile); free(pCurrent); }
_LayoutList = NULL;}
typedef HRESULT (WINAPI *FN_SHLoadRegUIStringW)(HKEY, LPCWSTR, LPWSTR, DWORD);
HRESULT FakeSHLoadRegUIStringW(HKEY hkey, LPCWSTR value, LPWSTR buf, DWORD size){ HRESULT hr = E_FAIL; HINSTANCE hSHLWAPI = LoadLibraryW(L"shlwapi"); FN_SHLoadRegUIStringW fn; fn = (FN_SHLoadRegUIStringW)GetProcAddress(hSHLWAPI, (LPCSTR)(INT_PTR)439); if (fn) hr = fn(hkey, value, buf, size); FreeLibrary(hSHLWAPI); return hr;}
static BOOLLayoutList_ReadLayout(HKEY hLayoutKey, LPCWSTR szKLID, LPCWSTR szSystemDirectory){ WCHAR szFile[80], szImeFile[80], szBuffer[MAX_PATH], szFilePath[MAX_PATH]; DWORD dwSize, dwKLID = DWORDfromString(szKLID); WORD wSpecialId = 0; LPWSTR pszImeFile = NULL;
dwSize = sizeof(szFile); if (RegQueryValueExW(hLayoutKey, L"Layout File", NULL, NULL, (LPBYTE)szFile, &dwSize) != ERROR_SUCCESS) { return FALSE; /* No "Layout File" value */ }
if (IS_IME_KLID(dwKLID)) { WCHAR szPath[MAX_PATH]; dwSize = sizeof(szImeFile); if (RegQueryValueExW(hLayoutKey, L"IME File", NULL, NULL, (LPBYTE)szImeFile, &dwSize) != ERROR_SUCCESS) { return FALSE; /* No "IME File" value */ }
if (wcschr(szImeFile, L'\\') != NULL) return FALSE; /* Invalid character */
GetSystemLibraryPath(szPath, ARRAYSIZE(szPath), szImeFile); if (GetFileAttributesW(szPath) == INVALID_FILE_ATTRIBUTES) return FALSE; /* Does not exist */
pszImeFile = szImeFile; }
/* Build the "Layout File" full path and check existence */ StringCchPrintfW(szFilePath, ARRAYSIZE(szFilePath), L"%s\\%s", szSystemDirectory, szFile); if (GetFileAttributesW(szFilePath) == INVALID_FILE_ATTRIBUTES) return FALSE; /* No layout file found */
/* Get the special ID */ dwSize = sizeof(szBuffer); if (RegQueryValueExW(hLayoutKey, L"Layout Id", NULL, NULL, (LPBYTE)szBuffer, &dwSize) == ERROR_SUCCESS) { wSpecialId = LOWORD(DWORDfromString(szBuffer)); }
/* If there is a valid "Layout Display Name", then use it as the entry name */ if (FakeSHLoadRegUIStringW(hLayoutKey, L"Layout Display Name", szBuffer, ARRAYSIZE(szBuffer)) == S_OK) { LayoutList_AppendNode(dwKLID, wSpecialId, szFile, szBuffer, pszImeFile); return TRUE; }
/* Otherwise, use "Layout Text" value as the entry name */ dwSize = sizeof(szBuffer); if (RegQueryValueExW(hLayoutKey, L"Layout Text", NULL, NULL, (LPBYTE)szBuffer, &dwSize) == ERROR_SUCCESS) { LayoutList_AppendNode(dwKLID, wSpecialId, szFile, szBuffer, pszImeFile); return TRUE; }
return FALSE;}
VOIDLayoutList_Create(VOID){ WCHAR szSystemDirectory[MAX_PATH], szKLID[KL_NAMELENGTH]; DWORD dwSize, dwIndex; HKEY hKey, hLayoutKey;
if (!GetSystemDirectoryW(szSystemDirectory, ARRAYSIZE(szSystemDirectory))) return;
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts", 0, KEY_READ, &hKey) != ERROR_SUCCESS) { return; }
for (dwIndex = 0; ; ++dwIndex) { dwSize = ARRAYSIZE(szKLID); if (RegEnumKeyExW(hKey, dwIndex, szKLID, &dwSize, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) { break; }
if (RegOpenKeyExW(hKey, szKLID, 0, KEY_QUERY_VALUE, &hLayoutKey) == ERROR_SUCCESS) { LayoutList_ReadLayout(hLayoutKey, szKLID, szSystemDirectory); RegCloseKey(hLayoutKey); } }
RegCloseKey(hKey);}
LAYOUT_LIST_NODE*LayoutList_GetByHkl(HKL hkl){ LAYOUT_LIST_NODE *pCurrent;
if (IS_SPECIAL_HKL(hkl)) { WORD wSpecialId = SPECIALIDFROMHKL(hkl);
for (pCurrent = _LayoutList; pCurrent != NULL; pCurrent = pCurrent->pNext) { if (wSpecialId == pCurrent->wSpecialId) { return pCurrent; } } } else if (IS_IME_HKL(hkl)) { for (pCurrent = _LayoutList; pCurrent != NULL; pCurrent = pCurrent->pNext) { if (hkl == UlongToHandle(pCurrent->dwKLID)) { return pCurrent; } } } else { for (pCurrent = _LayoutList; pCurrent != NULL; pCurrent = pCurrent->pNext) { if (HIWORD(hkl) == LOWORD(pCurrent->dwKLID)) { return pCurrent; } } }
return NULL;}
LAYOUT_LIST_NODE*LayoutList_GetFirst(VOID){ return _LayoutList;}