From 1962a3c337f07283324a9bd25af6f0fed8e411f0 Mon Sep 17 00:00:00 2001 From: TomCh Date: Wed, 9 Jun 2021 21:48:24 +0100 Subject: [PATCH] Switch to a static hook filter (#962, PR #964) Remove the HookFilter.dll which had a dependency on VCRUNTIME140.dll --- AppleWinExpress2019.sln | 15 -- AppleWinExpress2019.vcxproj | 2 + AppleWinExpress2019.vcxproj.filters | 6 + HookFilter/HookFilter-vs2019.vcxproj | 173 ---------------- HookFilter/HookFilter-vs2019.vcxproj.filters | 14 -- HookFilter/HookFilter.cpp | 81 -------- HookFilter/HookFilter.vcproj | 181 ----------------- source/Windows/AppleWin.cpp | 117 +---------- source/Windows/AppleWin.h | 1 + source/Windows/HookFilter.cpp | 203 +++++++++++++++++++ source/Windows/HookFilter.h | 38 ++++ 11 files changed, 258 insertions(+), 573 deletions(-) delete mode 100644 HookFilter/HookFilter-vs2019.vcxproj delete mode 100644 HookFilter/HookFilter-vs2019.vcxproj.filters delete mode 100644 HookFilter/HookFilter.cpp delete mode 100644 HookFilter/HookFilter.vcproj create mode 100644 source/Windows/HookFilter.cpp create mode 100644 source/Windows/HookFilter.h diff --git a/AppleWinExpress2019.sln b/AppleWinExpress2019.sln index 31f25485..dc75082e 100644 --- a/AppleWinExpress2019.sln +++ b/AppleWinExpress2019.sln @@ -5,7 +5,6 @@ VisualStudioVersion = 16.0.29201.188 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AppleWin", "AppleWinExpress2019.vcxproj", "{0A960136-A00A-4D4B-805F-664D9950D2CA}" ProjectSection(ProjectDependencies) = postProject - {AA5854AD-2BC7-4EFD-9790-349ADB35E35A} = {AA5854AD-2BC7-4EFD-9790-349ADB35E35A} {CF5A49BF-62A5-41BB-B10C-F34D556A7A45} = {CF5A49BF-62A5-41BB-B10C-F34D556A7A45} {0212E0DF-06DA-4080-BD1D-F3B01599F70F} = {0212E0DF-06DA-4080-BD1D-F3B01599F70F} {509739E7-0AF3-4C09-A1A9-F0B1BC31B39D} = {509739E7-0AF3-4C09-A1A9-F0B1BC31B39D} @@ -20,8 +19,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yaml", "libyaml\win32\yaml2 EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestCPU6502", "test\TestCPU6502\TestCPU6502-vs2019.vcxproj", "{CF5A49BF-62A5-41BB-B10C-F34D556A7A45}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HookFilter", "HookFilter\HookFilter-vs2019.vcxproj", "{AA5854AD-2BC7-4EFD-9790-349ADB35E35A}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug NoDX|Win32 = Debug NoDX|Win32 @@ -92,18 +89,6 @@ Global {CF5A49BF-62A5-41BB-B10C-F34D556A7A45}.Release v141_xp|Win32.Build.0 = Release v141_xp|Win32 {CF5A49BF-62A5-41BB-B10C-F34D556A7A45}.Release|Win32.ActiveCfg = Release|Win32 {CF5A49BF-62A5-41BB-B10C-F34D556A7A45}.Release|Win32.Build.0 = Release|Win32 - {AA5854AD-2BC7-4EFD-9790-349ADB35E35A}.Debug NoDX|Win32.ActiveCfg = Debug|Win32 - {AA5854AD-2BC7-4EFD-9790-349ADB35E35A}.Debug NoDX|Win32.Build.0 = Debug|Win32 - {AA5854AD-2BC7-4EFD-9790-349ADB35E35A}.Debug v141_xp|Win32.ActiveCfg = Debug v141_xp|Win32 - {AA5854AD-2BC7-4EFD-9790-349ADB35E35A}.Debug v141_xp|Win32.Build.0 = Debug v141_xp|Win32 - {AA5854AD-2BC7-4EFD-9790-349ADB35E35A}.Debug|Win32.ActiveCfg = Debug|Win32 - {AA5854AD-2BC7-4EFD-9790-349ADB35E35A}.Debug|Win32.Build.0 = Debug|Win32 - {AA5854AD-2BC7-4EFD-9790-349ADB35E35A}.Release NoDX|Win32.ActiveCfg = Release|Win32 - {AA5854AD-2BC7-4EFD-9790-349ADB35E35A}.Release NoDX|Win32.Build.0 = Release|Win32 - {AA5854AD-2BC7-4EFD-9790-349ADB35E35A}.Release v141_xp|Win32.ActiveCfg = Release v141_xp|Win32 - {AA5854AD-2BC7-4EFD-9790-349ADB35E35A}.Release v141_xp|Win32.Build.0 = Release v141_xp|Win32 - {AA5854AD-2BC7-4EFD-9790-349ADB35E35A}.Release|Win32.ActiveCfg = Release|Win32 - {AA5854AD-2BC7-4EFD-9790-349ADB35E35A}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/AppleWinExpress2019.vcxproj b/AppleWinExpress2019.vcxproj index c066e8a2..e99f20a7 100644 --- a/AppleWinExpress2019.vcxproj +++ b/AppleWinExpress2019.vcxproj @@ -123,6 +123,7 @@ + @@ -245,6 +246,7 @@ + diff --git a/AppleWinExpress2019.vcxproj.filters b/AppleWinExpress2019.vcxproj.filters index dafa7493..5b45ee53 100644 --- a/AppleWinExpress2019.vcxproj.filters +++ b/AppleWinExpress2019.vcxproj.filters @@ -229,6 +229,9 @@ Source Files\Debugger + + Source Files\Windows + @@ -540,6 +543,9 @@ Source Files\Debugger + + Source Files\Windows + diff --git a/HookFilter/HookFilter-vs2019.vcxproj b/HookFilter/HookFilter-vs2019.vcxproj deleted file mode 100644 index ea9912b2..00000000 --- a/HookFilter/HookFilter-vs2019.vcxproj +++ /dev/null @@ -1,173 +0,0 @@ - - - - - Debug v141_xp - Win32 - - - Debug - Win32 - - - Release v141_xp - Win32 - - - Release - Win32 - - - - HookFilter - {AA5854AD-2BC7-4EFD-9790-349ADB35E35A} - HookFilter - Win32Proj - 10.0 - - - - DynamicLibrary - v142 - Unicode - true - - - DynamicLibrary - v141_xp - Unicode - true - - - DynamicLibrary - v142 - Unicode - - - DynamicLibrary - v141_xp - Unicode - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26419.1 - - - $(SolutionDir)$(Configuration)\ - $(Configuration)\ - true - - - $(SolutionDir)$(Configuration)\ - $(Configuration)\ - true - - - $(SolutionDir)$(Configuration)\ - $(Configuration)\ - false - - - $(SolutionDir)$(Configuration)\ - $(Configuration)\ - false - - - - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;HOOKFILTER_EXPORTS;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebugDLL - - Level3 - EditAndContinue - - - true - Windows - MachineX86 - - - - - - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;HOOKFILTER_EXPORTS;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebugDLL - - - Level3 - EditAndContinue - - - true - Windows - MachineX86 - - - - - - - MaxSpeed - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;HOOKFILTER_EXPORTS;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - Level3 - ProgramDatabase - - - true - Windows - true - true - MachineX86 - - - - - MaxSpeed - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;HOOKFILTER_EXPORTS;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - - - true - Windows - true - true - MachineX86 - - - - - - - - - \ No newline at end of file diff --git a/HookFilter/HookFilter-vs2019.vcxproj.filters b/HookFilter/HookFilter-vs2019.vcxproj.filters deleted file mode 100644 index 7d5dd6b4..00000000 --- a/HookFilter/HookFilter-vs2019.vcxproj.filters +++ /dev/null @@ -1,14 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - Source Files - - - \ No newline at end of file diff --git a/HookFilter/HookFilter.cpp b/HookFilter/HookFilter.cpp deleted file mode 100644 index ebaf358c..00000000 --- a/HookFilter/HookFilter.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#include - -static HWND g_hFrameWindow = (HWND)0; -static bool g_bHookAltTab = false; -static bool g_bHookAltGrControl = false; - -// NB. __stdcall (or WINAPI) and extern "C": -// . symbol is decorated as _@bytes -// . so use the #pragma to create an undecorated alias for our symbol -extern "C" __declspec(dllexport) LRESULT CALLBACK LowLevelKeyboardProc( - _In_ int nCode, - _In_ WPARAM wParam, - _In_ LPARAM lParam) -{ -#ifndef _WIN64 - #pragma comment(linker, "/EXPORT:" __FUNCTION__ "=" __FUNCDNAME__) -#endif - - if (nCode == HC_ACTION) - { - bool suppress = false; - - PKBDLLHOOKSTRUCT pKbdLlHookStruct = (PKBDLLHOOKSTRUCT) lParam; - UINT newMsg = pKbdLlHookStruct->flags & LLKHF_UP ? WM_KEYUP : WM_KEYDOWN; - LPARAM newlParam = newMsg == WM_KEYUP ? 3<<30 : 0; // b31:transition state, b30:previous key state - - // - - // NB. Alt Gr (Right-Alt): this normally send 2 WM_KEYDOWN messages for: VK_LCONTROL, then VK_RMENU - // Keyboard scanCodes: LCONTROL=0x1D, LCONTROL_from_RMENU=0x21D - // . For: Microsoft PS/2/Win7-64, VAIO laptop/Win7-64, Microsoft USB/Win10-64 - // NB. WM_KEYDOWN also includes a 9/10-bit? scanCode: LCONTROL=0x1D, RCONTROL=0x11D, RMENU=0x1D(not 0x21D) - // . Can't suppress in app, since scanCode is not >= 0x200 - if (g_bHookAltGrControl && pKbdLlHookStruct->vkCode == VK_LCONTROL && pKbdLlHookStruct->scanCode >= 0x200) // GH#558 - { - suppress = true; - } - - // Suppress alt-tab - if (g_bHookAltTab && pKbdLlHookStruct->vkCode == VK_TAB && (pKbdLlHookStruct->flags & LLKHF_ALTDOWN)) - { - PostMessage(g_hFrameWindow, newMsg, VK_TAB, newlParam); - suppress = true; - } - - // Suppress alt-escape - if (pKbdLlHookStruct->vkCode == VK_ESCAPE && (pKbdLlHookStruct->flags & LLKHF_ALTDOWN)) - { - PostMessage(g_hFrameWindow, newMsg, VK_ESCAPE, newlParam); - suppress = true; - } - - // Suppress alt-space - if (pKbdLlHookStruct->vkCode == VK_SPACE && (pKbdLlHookStruct->flags & LLKHF_ALTDOWN)) - { - PostMessage(g_hFrameWindow, newMsg, VK_SPACE, newlParam); - suppress = true; - } - - // Suppress ctrl-escape - if (pKbdLlHookStruct->vkCode == VK_ESCAPE) - { - // But don't suppress CTRL+SHIFT+ESC - if (GetKeyState(VK_CONTROL) < 0 && GetKeyState(VK_SHIFT) >= 0) - suppress = true; - } - - // Suppress keys by returning 1 - if (suppress) - return 1; - } - - return CallNextHookEx(0/*parameter is ignored*/, nCode, wParam, lParam); -} - -extern "C" __declspec(dllexport) void __cdecl RegisterHWND(HWND hWnd, bool bHookAltTab, bool bHookAltGrControl) -{ - g_hFrameWindow = hWnd; - g_bHookAltTab = bHookAltTab; - g_bHookAltGrControl = bHookAltGrControl; -} diff --git a/HookFilter/HookFilter.vcproj b/HookFilter/HookFilter.vcproj deleted file mode 100644 index 61bb8edb..00000000 --- a/HookFilter/HookFilter.vcproj +++ /dev/null @@ -1,181 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/source/Windows/AppleWin.cpp b/source/Windows/AppleWin.cpp index 3a8c0dd5..03c5a6f8 100644 --- a/source/Windows/AppleWin.cpp +++ b/source/Windows/AppleWin.cpp @@ -29,6 +29,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "StdAfx.h" #include "Windows/AppleWin.h" +#include "Windows/HookFilter.h" #include "Interface.h" #include "Utilities.h" #include "CmdLine.h" @@ -73,6 +74,11 @@ void Win32Frame::SetLoadedSaveStateFlag(const bool bFlag) g_bLoadedSaveState = bFlag; } +bool GetHookAltTab(void) +{ + return g_bHookAltTab; +} + bool GetHookAltGrControl(void) { return g_bHookAltGrControl; @@ -490,113 +496,6 @@ static void RegisterHotKeys(void) //--------------------------------------------------------------------------- -static HINSTANCE g_hinstDLL = 0; -static HHOOK g_hhook = 0; - -static HANDLE g_hHookThread = NULL; -static DWORD g_HookThreadId = 0; - -// Pre: g_hFrameWindow must be valid -static bool HookFilterForKeyboard() -{ - g_hinstDLL = LoadLibrary(TEXT("HookFilter.dll")); - - _ASSERT(GetFrame().g_hFrameWindow); - - typedef void (*RegisterHWNDProc)(HWND, bool, bool); - RegisterHWNDProc RegisterHWND = (RegisterHWNDProc) GetProcAddress(g_hinstDLL, "RegisterHWND"); - if (RegisterHWND) - RegisterHWND(GetFrame().g_hFrameWindow, g_bHookAltTab, g_bHookAltGrControl); - - HOOKPROC hkprcLowLevelKeyboardProc = (HOOKPROC) GetProcAddress(g_hinstDLL, "LowLevelKeyboardProc"); - - g_hhook = SetWindowsHookEx( - WH_KEYBOARD_LL, - hkprcLowLevelKeyboardProc, - g_hinstDLL, - 0); - - if (g_hhook != 0 && GetFrame().g_hFrameWindow != 0) - return true; - - std::string msg("Failed to install hook filter for system keys"); - - DWORD dwErr = GetLastError(); - GetFrame().FrameMessageBox(msg.c_str(), "Warning", MB_ICONASTERISK | MB_OK); - - msg += "\n"; - LogFileOutput(msg.c_str()); - return false; -} - -static void UnhookFilterForKeyboard() -{ - UnhookWindowsHookEx(g_hhook); - FreeLibrary(g_hinstDLL); -} - -static DWORD WINAPI HookThread(LPVOID lpParameter) -{ - if (!HookFilterForKeyboard()) - return -1; - - MSG msg; - while(GetMessage(&msg, NULL, 0, 0) > 0) - { - if (msg.message == WM_QUIT) - break; - - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - UnhookFilterForKeyboard(); - return 0; -} - -static bool InitHookThread() -{ - g_hHookThread = CreateThread(NULL, // lpThreadAttributes - 0, // dwStackSize - (LPTHREAD_START_ROUTINE) HookThread, - 0, // lpParameter - 0, // dwCreationFlags : 0 = Run immediately - &g_HookThreadId); // lpThreadId - if (g_hHookThread == NULL) - return false; - - return true; -} - -static void UninitHookThread() -{ - if (g_hHookThread) - { - if (!PostThreadMessage(g_HookThreadId, WM_QUIT, 0, 0)) - { - _ASSERT(0); - return; - } - - do - { - DWORD dwExitCode; - if (GetExitCodeThread(g_hHookThread, &dwExitCode)) - { - if(dwExitCode == STILL_ACTIVE) - Sleep(10); - else - break; - } - } - while(1); - - CloseHandle(g_hHookThread); - g_hHookThread = NULL; - g_HookThreadId = 0; - } -} - static void ExceptionHandler(const char* pError) { GetFrame().FrameMessageBox( @@ -666,7 +565,7 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int) if (g_bHookSystemKey) { - UninitHookThread(); + GetHookFilter().UninitHookThread(); LogFileOutput("Main: UnhookFilterForKeyboard()\n"); } } @@ -915,7 +814,7 @@ static void RepeatInitialization(void) if (g_bHookSystemKey) { - if (InitHookThread()) // needs valid g_hFrameWindow (for message pump) + if (GetHookFilter().InitHookThread()) // needs valid g_hFrameWindow (for message pump) LogFileOutput("Main: HookFilterForKeyboard()\n"); } diff --git a/source/Windows/AppleWin.h b/source/Windows/AppleWin.h index 0042829e..2e60ab95 100644 --- a/source/Windows/AppleWin.h +++ b/source/Windows/AppleWin.h @@ -6,6 +6,7 @@ void SingleStep(bool bReinit); // Win32 bool GetLoadedSaveStateFlag(void); +bool GetHookAltTab(void); bool GetHookAltGrControl(void); extern bool g_bRestartFullScreen; diff --git a/source/Windows/HookFilter.cpp b/source/Windows/HookFilter.cpp new file mode 100644 index 00000000..b9f7a9e8 --- /dev/null +++ b/source/Windows/HookFilter.cpp @@ -0,0 +1,203 @@ +/* +AppleWin : An Apple //e emulator for Windows + +Copyright (C) 1994-1996, Michael O'Brien +Copyright (C) 1999-2001, Oliver Schmidt +Copyright (C) 2002-2005, Tom Charlesworth +Copyright (C) 2006-2021, Tom Charlesworth, Michael Pohoreski + +AppleWin is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +AppleWin is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with AppleWin; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* Description: HookFilter + * + * Author: Various + */ + +#include "StdAfx.h" + +#include "HookFilter.h" + +#include "AppleWin.h" +#include "Interface.h" +#include "Log.h" + +HookFilter& GetHookFilter(void) +{ + static HookFilter hookFilter; + return hookFilter; +} + +LRESULT CALLBACK HookFilter::LowLevelKeyboardProc(_In_ int nCode, _In_ WPARAM wParam, _In_ LPARAM lParam) +{ + if (nCode == HC_ACTION) + { + bool suppress = false; + + PKBDLLHOOKSTRUCT pKbdLlHookStruct = (PKBDLLHOOKSTRUCT) lParam; + UINT newMsg = pKbdLlHookStruct->flags & LLKHF_UP ? WM_KEYUP : WM_KEYDOWN; + LPARAM newlParam = newMsg == WM_KEYUP ? 3<<30 : 0; // b31:transition state, b30:previous key state + + // + + // NB. Alt Gr (Right-Alt): this normally send 2 WM_KEYDOWN messages for: VK_LCONTROL, then VK_RMENU + // Keyboard scanCodes: LCONTROL=0x1D, LCONTROL_from_RMENU=0x21D + // . For: Microsoft PS/2/Win7-64, VAIO laptop/Win7-64, Microsoft USB/Win10-64 + // NB. WM_KEYDOWN also includes a 9/10-bit? scanCode: LCONTROL=0x1D, RCONTROL=0x11D, RMENU=0x1D(not 0x21D) + // . Can't suppress in app, since scanCode is not >= 0x200 + if (GetHookFilter().m_bHookAltGrControl && pKbdLlHookStruct->vkCode == VK_LCONTROL && pKbdLlHookStruct->scanCode >= 0x200) // GH#558 + { + suppress = true; + } + + // Suppress alt-tab + if (GetHookFilter().m_bHookAltTab && pKbdLlHookStruct->vkCode == VK_TAB && (pKbdLlHookStruct->flags & LLKHF_ALTDOWN)) + { + PostMessage(GetHookFilter().m_hFrameWindow, newMsg, VK_TAB, newlParam); + suppress = true; + } + + // Suppress alt-escape + if (pKbdLlHookStruct->vkCode == VK_ESCAPE && (pKbdLlHookStruct->flags & LLKHF_ALTDOWN)) + { + PostMessage(GetHookFilter().m_hFrameWindow, newMsg, VK_ESCAPE, newlParam); + suppress = true; + } + + // Suppress alt-space + if (pKbdLlHookStruct->vkCode == VK_SPACE && (pKbdLlHookStruct->flags & LLKHF_ALTDOWN)) + { + PostMessage(GetHookFilter().m_hFrameWindow, newMsg, VK_SPACE, newlParam); + suppress = true; + } + + // Suppress ctrl-escape + if (pKbdLlHookStruct->vkCode == VK_ESCAPE) + { + // But don't suppress CTRL+SHIFT+ESC + if (GetKeyState(VK_CONTROL) < 0 && GetKeyState(VK_SHIFT) >= 0) + suppress = true; + } + + // Suppress keys by returning 1 + if (suppress) + return 1; + } + + return CallNextHookEx(0/*parameter is ignored*/, nCode, wParam, lParam); +} + +//--------------------------------------------------------------------------- + +// The hook filter code can be static (within the application) rather than in a DLL. +// Pre: g_hFrameWindow must be valid +bool HookFilter::HookFilterForKeyboard(void) +{ + _ASSERT(GetFrame().g_hFrameWindow); + + m_hFrameWindow = GetFrame().g_hFrameWindow; + m_bHookAltTab = GetHookAltTab(); + m_bHookAltGrControl = GetHookAltGrControl(); + + // Since no DLL gets injected anyway for low-level hooks, we can use, for example, GetModuleHandle("kernel32.dll") + HINSTANCE hinstDLL = GetModuleHandle("kernel32.dll"); + + m_hhook = SetWindowsHookEx( + WH_KEYBOARD_LL, + LowLevelKeyboardProc, + hinstDLL, + 0); + + if (m_hhook != 0 && GetFrame().g_hFrameWindow != 0) + return true; + + std::string msg("Failed to install hook filter for system keys"); + + DWORD dwErr = GetLastError(); + GetFrame().FrameMessageBox(msg.c_str(), "Warning", MB_ICONASTERISK | MB_OK); + + msg += "\n"; + LogFileOutput(msg.c_str()); + return false; +} + +void HookFilter::UnhookFilterForKeyboard(void) +{ + UnhookWindowsHookEx(m_hhook); +} + +DWORD WINAPI HookFilter::HookThread(LPVOID lpParameter) +{ + HookFilter* hf = (HookFilter*)lpParameter; + + if (!hf->HookFilterForKeyboard()) + return -1; + + MSG msg; + while (GetMessage(&msg, NULL, 0, 0) > 0) + { + if (msg.message == WM_QUIT) + break; + + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + hf->UnhookFilterForKeyboard(); + return 0; +} + +bool HookFilter::InitHookThread(void) +{ + m_hHookThread = CreateThread(NULL, // lpThreadAttributes + 0, // dwStackSize + (LPTHREAD_START_ROUTINE)HookThread, + this, // lpParameter + 0, // dwCreationFlags : 0 = Run immediately + &m_HookThreadId); // lpThreadId + + if (m_hHookThread == NULL) + return false; + + return true; +} + +void HookFilter::UninitHookThread(void) +{ + if (m_hHookThread) + { + if (!PostThreadMessage(m_HookThreadId, WM_QUIT, 0, 0)) + { + _ASSERT(0); + return; + } + + do + { + DWORD dwExitCode; + if (GetExitCodeThread(m_hHookThread, &dwExitCode)) + { + if (dwExitCode == STILL_ACTIVE) + Sleep(10); + else + break; + } + } while (1); + + CloseHandle(m_hHookThread); + m_hHookThread = NULL; + m_HookThreadId = 0; + } +} diff --git a/source/Windows/HookFilter.h b/source/Windows/HookFilter.h new file mode 100644 index 00000000..809f1483 --- /dev/null +++ b/source/Windows/HookFilter.h @@ -0,0 +1,38 @@ +#pragma once + +class HookFilter +{ +public: + HookFilter() + { + m_hFrameWindow = (HWND)0; + m_bHookAltTab = false; + m_bHookAltGrControl = false; + + m_hhook = 0; + m_hHookThread = NULL; + m_HookThreadId = 0; + } + ~HookFilter() + { + } + + bool InitHookThread(void); + void UninitHookThread(void); + +private: + static LRESULT CALLBACK LowLevelKeyboardProc(_In_ int nCode, _In_ WPARAM wParam, _In_ LPARAM lParam); + bool HookFilterForKeyboard(void); + void UnhookFilterForKeyboard(void); + static DWORD WINAPI HookThread(LPVOID lpParameter); + + HWND m_hFrameWindow; + bool m_bHookAltTab; + bool m_bHookAltGrControl; + + HHOOK m_hhook; + HANDLE m_hHookThread; + DWORD m_HookThreadId; +}; + +HookFilter& GetHookFilter(void);