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");