Author: dchapyshev Date: Sat Aug 6 20:48:33 2016 New Revision: 72143
URL: http://svn.reactos.org/svn/reactos?rev=72143&view=rev Log: [KBSWITCH] - Use strsafe functions - Use Shell Hooks in dll for detecting keyboard layout switching - Fix bug in loading kbsdll
* Detection switch keyboard layout is now working in Windovs, but does not work in ReactOS (WH_SHELL not work in win32k)
Modified: trunk/reactos/base/applications/kbswitch/kbsdll/kbsdll.c trunk/reactos/base/applications/kbswitch/kbswitch.c trunk/reactos/base/applications/kbswitch/kbswitch.h
Modified: trunk/reactos/base/applications/kbswitch/kbsdll/kbsdll.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/kbswitch/... ============================================================================== --- trunk/reactos/base/applications/kbswitch/kbsdll/kbsdll.c [iso-8859-1] (original) +++ trunk/reactos/base/applications/kbswitch/kbsdll/kbsdll.c [iso-8859-1] Sat Aug 6 20:48:33 2016 @@ -7,48 +7,15 @@
#include "../kbswitch.h"
-HHOOK hKeyboardHook, hLangHook, hWinHook; -HINSTANCE hInstance; -HWND hKbSwitchWnd; +HHOOK hWinHook = NULL; +HHOOK hShellHook = NULL; +HINSTANCE hInstance = NULL; +HWND hKbSwitchWnd = NULL;
static VOID SendMessageToMainWnd(UINT Msg, WPARAM wParam, LPARAM lParam) { PostMessage(hKbSwitchWnd, Msg, wParam, lParam); -} - -/* Not used yet */ -LRESULT CALLBACK -KeyboardHookProc(int code, WPARAM wParam, LPARAM lParam) -{ - return CallNextHookEx(hKeyboardHook, code, wParam, lParam); -} - -LRESULT CALLBACK -LangHookProc(int code, WPARAM wParam, LPARAM lParam) -{ - PMSG msg; - msg = (PMSG) lParam; - - switch (msg->message) - { - case WM_INPUTLANGCHANGEREQUEST: - { - SendMessageToMainWnd(WM_LANG_CHANGED, wParam, msg->lParam); - } - break; - - case WM_HOTKEY: - { - if (msg->hwnd) - { - SendMessageToMainWnd(WM_LOAD_LAYOUT, (WPARAM)msg->hwnd, msg->lParam); - } - } - break; - } - - return CallNextHookEx(hLangHook, code, wParam, lParam); }
LRESULT CALLBACK @@ -69,18 +36,6 @@ } } break; - - case HCBT_CREATEWND: - { - RegisterHotKey((HWND)wParam, id, MOD_ALT, VK_F10); - } - break; - - case HCBT_DESTROYWND: - { - UnregisterHotKey((HWND)wParam, id); - } - break; }
GlobalDeleteAtom(id); @@ -88,25 +43,40 @@ return CallNextHookEx(hWinHook, code, wParam, lParam); }
+LRESULT CALLBACK +ShellHookProc(int code, WPARAM wParam, LPARAM lParam) +{ + switch (code) + { + case HSHELL_LANGUAGE: + { + SendMessageToMainWnd(WM_LANG_CHANGED, wParam, lParam); + } + break; + } + + return CallNextHookEx(hShellHook, code, wParam, lParam); +} + BOOL WINAPI KbSwitchSetHooks(VOID) { - hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardHookProc, hInstance, 0); - hLangHook = SetWindowsHookEx(WH_GETMESSAGE, LangHookProc, hInstance, 0); hWinHook = SetWindowsHookEx(WH_CBT, WinHookProc, hInstance, 0); + hShellHook = SetWindowsHookEx(WH_SHELL, ShellHookProc, hInstance, 0);
- if ((hKeyboardHook)&&(hLangHook)&&(hWinHook)) - return TRUE; - else + if (!hWinHook || !hShellHook) + { return FALSE; + } + + return TRUE; }
VOID WINAPI KbSwitchDeleteHooks(VOID) { - if (hKeyboardHook) UnhookWindowsHookEx(hKeyboardHook); - if (hLangHook) UnhookWindowsHookEx(hLangHook); if (hWinHook) UnhookWindowsHookEx(hWinHook); + if (hShellHook) UnhookWindowsHookEx(hShellHook); }
BOOL WINAPI @@ -117,10 +87,15 @@ switch (dwReason) { case DLL_PROCESS_ATTACH: + { hInstance = hinstDLL; hKbSwitchWnd = FindWindow(szKbSwitcherName, NULL); - if (!hKbSwitchWnd) return FALSE; - break; + if (!hKbSwitchWnd) + { + return FALSE; + } + } + break; }
return TRUE;
Modified: trunk/reactos/base/applications/kbswitch/kbswitch.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/kbswitch/... ============================================================================== --- trunk/reactos/base/applications/kbswitch/kbswitch.c [iso-8859-1] (original) +++ trunk/reactos/base/applications/kbswitch/kbswitch.c [iso-8859-1] Sat Aug 6 20:48:33 2016 @@ -10,15 +10,15 @@
#define WM_NOTIFYICONMSG (WM_USER + 248)
-PROC KbSwitchSetHooks = NULL; -PROC KbSwitchDeleteHooks = NULL; +PKBSWITCHSETHOOKS KbSwitchSetHooks = NULL; +PKBSWITCHDELETEHOOKS KbSwitchDeleteHooks = NULL;
static BOOL -GetLayoutID(LPTSTR szLayoutNum, LPTSTR szLCID); +GetLayoutID(LPTSTR szLayoutNum, LPTSTR szLCID, SIZE_T LCIDLength);
static BOOL -GetLayoutName(LPTSTR szLayoutNum, LPTSTR szName); +GetLayoutName(LPTSTR szLayoutNum, LPTSTR szName, SIZE_T NameLength);
HINSTANCE hInst; HANDLE hProcessHeap; @@ -41,9 +41,9 @@ if (GetLocaleInfo(lId, LOCALE_SISO639LANGNAME, szBuf, - sizeof(szBuf) / sizeof(TCHAR)) == 0) - { - lstrcpy(szBuf, _T("??")); + ARRAYSIZE(szBuf)) == 0) + { + StringCchCopy(szBuf, ARRAYSIZE(szBuf), _T("??")); }
hdcsrc = GetDC(NULL); @@ -103,9 +103,10 @@ TCHAR szLCID[CCH_LAYOUT_ID + 1]; TCHAR szName[MAX_PATH];
- GetLayoutID(_T("1"), szLCID); - GetLayoutName(_T("1"), szName); - + GetLayoutID(_T("1"), szLCID, ARRAYSIZE(szLCID)); + GetLayoutName(_T("1"), szName, ARRAYSIZE(szName)); + + memset(&tnid, 0, sizeof(tnid)); tnid.cbSize = sizeof(NOTIFYICONDATA); tnid.hWnd = hwnd; tnid.uID = 1; @@ -113,7 +114,7 @@ tnid.uCallbackMessage = WM_NOTIFYICONMSG; tnid.hIcon = CreateTrayIcon(szLCID);
- lstrcpyn(tnid.szTip, szName, sizeof(tnid.szTip) / sizeof(TCHAR)); + StringCchCopy(tnid.szTip, ARRAYSIZE(tnid.szTip), szName);
Shell_NotifyIcon(NIM_ADD, &tnid); } @@ -123,6 +124,7 @@ { NOTIFYICONDATA tnid;
+ memset(&tnid, 0, sizeof(tnid)); tnid.cbSize = sizeof(NOTIFYICONDATA); tnid.hWnd = hwnd; tnid.uID = 1; @@ -135,6 +137,7 @@ { NOTIFYICONDATA tnid;
+ memset(&tnid, 0, sizeof(tnid)); tnid.cbSize = sizeof(NOTIFYICONDATA); tnid.hWnd = hwnd; tnid.uID = 1; @@ -142,13 +145,13 @@ tnid.uCallbackMessage = WM_NOTIFYICONMSG; tnid.hIcon = CreateTrayIcon(szLCID);
- lstrcpyn(tnid.szTip, szName, sizeof(tnid.szTip) / sizeof(TCHAR)); + StringCchCopy(tnid.szTip, ARRAYSIZE(tnid.szTip), szName);
Shell_NotifyIcon(NIM_MODIFY, &tnid); }
static BOOL -GetLayoutID(LPTSTR szLayoutNum, LPTSTR szLCID) +GetLayoutID(LPTSTR szLayoutNum, LPTSTR szLCID, SIZE_T LCIDLength) { DWORD dwBufLen; DWORD dwRes; @@ -178,7 +181,7 @@ if (RegQueryValueEx(hKey, szTempLCID, NULL, NULL, (LPBYTE)szLCID, &dwBufLen) != ERROR_SUCCESS) { // No substitute found, then use the old LCID - lstrcpy(szLCID, szTempLCID); + StringCchCopy(szLCID, LCIDLength, szTempLCID); }
RegCloseKey(hKey); @@ -186,24 +189,24 @@ else { // Substitutes key couldn't be opened, so use the old LCID - lstrcpy(szLCID, szTempLCID); + StringCchCopy(szLCID, LCIDLength, szTempLCID); }
return TRUE; }
VOID -GetLayoutIDByHkl(HKL hKl, LPTSTR szLayoutID) +GetLayoutIDByHkl(HKL hKl, LPTSTR szLayoutID, SIZE_T LayoutIDLength) { /* FIXME!!! This way of getting layout ID incorrect! This will not work correctly for 0001040a, 00010410, etc */ - wsprintf(szLayoutID, _T("%08x"), LOWORD(hKl)); + StringCchPrintf(szLayoutID, LayoutIDLength, _T("%08x"), LOWORD(hKl)); }
static BOOL -GetLayoutName(LPTSTR szLayoutNum, LPTSTR szName) +GetLayoutName(LPTSTR szLayoutNum, LPTSTR szName, SIZE_T NameLength) { HKEY hKey; DWORD dwBufLen; @@ -212,20 +215,22 @@ HANDLE hLib; UINT i, j, k;
- if(!GetLayoutID(szLayoutNum, szLCID)) + if (!GetLayoutID(szLayoutNum, szLCID, ARRAYSIZE(szLCID))) return FALSE;
- wsprintf(szBuf, _T("SYSTEM\CurrentControlSet\Control\Keyboard Layouts\%s"), szLCID); + StringCchPrintf(szBuf, ARRAYSIZE(szBuf), _T("SYSTEM\CurrentControlSet\Control\Keyboard Layouts\%s"), szLCID);
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR)szBuf, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) { - dwBufLen = sizeof(szBuf); + dwBufLen = sizeof(szDispName);
if (RegQueryValueEx(hKey, _T("Layout Display Name"), NULL, NULL, (LPBYTE)szDispName, &dwBufLen) == ERROR_SUCCESS) { if (szDispName[0] == '@') { - for (i = 0; i < _tcslen(szDispName); i++) + size_t len = _tcslen(szDispName); + + for (i = 0; i < len; i++) { if ((szDispName[i] == ',') && (szDispName[i + 1] == '-')) { @@ -239,14 +244,14 @@ else szDispName[i] = szDispName[i + 1]; }
- if (ExpandEnvironmentStrings(szDispName, szPath, MAX_PATH)) + if (ExpandEnvironmentStrings(szDispName, szPath, ARRAYSIZE(szPath))) { hLib = LoadLibrary(szPath); if (hLib) { - if (LoadString(hLib, _ttoi(szIndex), szPath, sizeof(szPath) / sizeof(TCHAR)) != 0) + if (LoadString(hLib, _ttoi(szIndex), szPath, ARRAYSIZE(szPath)) != 0) { - _tcscpy(szName, szPath); + StringCchCopy(szName, NameLength, szPath); RegCloseKey(hKey); FreeLibrary(hLib); return TRUE; @@ -257,7 +262,7 @@ } }
- dwBufLen = sizeof(szBuf); + dwBufLen = NameLength * sizeof(TCHAR);
if (RegQueryValueEx(hKey, _T("Layout Text"), NULL, NULL, (LPBYTE)szName, &dwBufLen) == ERROR_SUCCESS) { @@ -287,10 +292,10 @@ TCHAR szLangName[MAX_PATH];
_ultot(uLayoutNum, szLayoutNum, 10); - GetLayoutID(szLayoutNum, szLCID); + GetLayoutID(szLayoutNum, szLCID, ARRAYSIZE(szLCID));
// Switch to the new keyboard layout - GetLocaleInfo((LANGID)_tcstoul(szLCID, NULL, 16), LOCALE_SLANGUAGE, (LPTSTR)szLangName, sizeof(szLangName) / sizeof(TCHAR)); + GetLocaleInfo((LANGID)_tcstoul(szLCID, NULL, 16), LOCALE_SLANGUAGE, (LPTSTR)szLangName, ARRAYSIZE(szLangName)); UpdateTrayIcon(hwnd, szLCID, szLangName); hKl = LoadKeyboardLayout(szLCID, KLF_ACTIVATE);
@@ -313,19 +318,19 @@ // Add the keyboard layouts to the popup menu if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\Preload"), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) { - for(dwIndex = 0; ; dwIndex++) + for (dwIndex = 0; ; dwIndex++) { dwSize = sizeof(szLayoutNum); - if(RegEnumValue(hKey, dwIndex, szLayoutNum, &dwSize, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) + if (RegEnumValue(hKey, dwIndex, szLayoutNum, &dwSize, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) break;
- if(!GetLayoutName(szLayoutNum, szName)) + if (!GetLayoutName(szLayoutNum, szName, ARRAYSIZE(szName))) break;
AppendMenu(hMenu, MF_STRING, _ttoi(szLayoutNum), szName); }
- (void)CheckMenuItem(hMenu, ulCurrentLayoutNum, MF_CHECKED); + CheckMenuItem(hMenu, ulCurrentLayoutNum, MF_CHECKED);
RegCloseKey(hKey); } @@ -337,13 +342,18 @@ SetHooks(VOID) { hDllLib = LoadLibrary(_T("kbsdll.dll")); - if (!hDllLib) return FALSE; - - KbSwitchSetHooks = (PROC) GetProcAddress(hDllLib, MAKEINTRESOURCEA(1)); - KbSwitchDeleteHooks = (PROC) GetProcAddress(hDllLib, MAKEINTRESOURCEA(2)); - - if ((KbSwitchSetHooks == NULL)||(KbSwitchDeleteHooks == NULL)) + if (!hDllLib) + { return FALSE; + } + + KbSwitchSetHooks = (PKBSWITCHSETHOOKS) GetProcAddress(hDllLib, "KbSwitchSetHooks"); + KbSwitchDeleteHooks = (PKBSWITCHDELETEHOOKS) GetProcAddress(hDllLib, "KbSwitchDeleteHooks"); + + if (KbSwitchSetHooks == NULL || KbSwitchDeleteHooks == NULL) + { + return FALSE; + }
return KbSwitchSetHooks(); } @@ -362,21 +372,21 @@ ULONG Ret = ulCurrentLayoutNum;
_ultot(ulCurrentLayoutNum, szLayoutNum, 10); - if (!GetLayoutID(szLayoutNum, szLayoutID)) + if (!GetLayoutID(szLayoutNum, szLayoutID, ARRAYSIZE(szLayoutID))) { return -1; }
_ultot(Ret + 1, szLayoutNum, 10);
- if (GetLayoutID(szLayoutNum, szLayoutID)) + if (GetLayoutID(szLayoutNum, szLayoutID, ARRAYSIZE(szLayoutID))) { return (Ret + 1); } else { _ultot(Ret - 1, szLayoutNum, 10); - if (GetLayoutID(szLayoutNum, szLayoutID)) + if (GetLayoutID(szLayoutNum, szLayoutID, ARRAYSIZE(szLayoutID))) return (Ret - 1); else return -1; @@ -408,8 +418,8 @@
case WM_LANG_CHANGED: { - GetLayoutIDByHkl((HKL)lParam, szLCID); - GetLocaleInfo((LANGID)_tcstoul(szLCID, NULL, 16), LOCALE_SLANGUAGE, (LPTSTR)szLangName, sizeof(szLangName) / sizeof(TCHAR)); + GetLayoutIDByHkl((HKL)lParam, szLCID, ARRAYSIZE(szLCID)); + GetLocaleInfo((LANGID)_tcstoul(szLCID, NULL, 16), LOCALE_SLANGUAGE, (LPTSTR)szLangName, ARRAYSIZE(szLangName)); UpdateTrayIcon(hwnd, szLCID, szLangName);
return 0; @@ -424,8 +434,8 @@
case WM_WINDOW_ACTIVATE: { - GetLayoutIDByHkl(GetKeyboardLayout(GetWindowThreadProcessId((HWND)wParam, 0)), szLCID); - GetLocaleInfo((LANGID)_tcstoul(szLCID, NULL, 16), LOCALE_SLANGUAGE, (LPTSTR)szLangName, sizeof(szLangName) / sizeof(TCHAR)); + GetLayoutIDByHkl(GetKeyboardLayout(GetWindowThreadProcessId((HWND)wParam, 0)), szLCID, ARRAYSIZE(szLCID)); + GetLocaleInfo((LANGID)_tcstoul(szLCID, NULL, 16), LOCALE_SLANGUAGE, (LPTSTR)szLangName, ARRAYSIZE(szLangName)); UpdateTrayIcon(hwnd, szLCID, szLangName);
return 0; @@ -526,11 +536,11 @@
switch (GetUserDefaultUILanguage()) { - case MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT): - SetProcessDefaultLayout(LAYOUT_RTL); - break; - default: - break; + case MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT): + SetProcessDefaultLayout(LAYOUT_RTL); + break; + default: + break; }
hMutex = CreateMutex(NULL, FALSE, szKbSwitcherName);
Modified: trunk/reactos/base/applications/kbswitch/kbswitch.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/kbswitch/... ============================================================================== --- trunk/reactos/base/applications/kbswitch/kbswitch.h [iso-8859-1] (original) +++ trunk/reactos/base/applications/kbswitch/kbswitch.h [iso-8859-1] Sat Aug 6 20:48:33 2016 @@ -1,3 +1,5 @@ +#pragma once + #include <stdarg.h> #include <windef.h> #include <winbase.h> @@ -7,6 +9,7 @@ #include <wingdi.h> #include <shellapi.h> #include <tchar.h> +#include <strsafe.h>
#include "resource.h"
@@ -21,4 +24,7 @@ #define WM_WINDOW_ACTIVATE (WM_USER + 10300) #define WM_LOAD_LAYOUT (WM_USER + 10400)
+typedef BOOL (WINAPI *PKBSWITCHSETHOOKS) (VOID); +typedef VOID (WINAPI *PKBSWITCHDELETEHOOKS) (VOID); + TCHAR szKbSwitcherName[] = _T("kbswitcher");