📄 vnchooks.cpp
字号:
// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
//
// This file is part of the VNC system.
//
// The VNC system 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.
//
// This program 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 this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
//
// TightVNC distribution homepage on the Web: http://www.tightvnc.com/
//
// If the source code for the VNC system is not available from the place
// whence you received this file, check http://www.uk.research.att.com/vnc or contact
// the authors on vnc@uk.research.att.com for information on obtaining it.
// VNCHooks.cpp : Defines the implementation of the DLL.
//
#include "VNCHooks.h"
#include <stdlib.h>
#include <stdio.h>
#include <crtdbg.h>
/////////////////////////////////////////////////////////////////////////////
// Storage for the global data in the DLL
// Note: For Borland C++ compilers, this data segment is defined in a
// separate file, SharedData.cpp.
#ifdef _MSC_VER
// MSVC is bugged - if a default value is missed off from one of the following
// variables then that variable is process-specific for some reason!
#pragma data_seg(".SharedData")
HWND hVeneto = NULL;
HWND hKeyboardPriorityWindow = NULL;
HWND hMousePriorityWindow = NULL;
UINT UpdateRectMessage = 0;
UINT CopyRectMessage = 0;
UINT MouseMoveMessage = 0;
UINT LocalMouseMessage = 0;
UINT LocalKeyboardMessage = 0;
HHOOK hCallWndHook = NULL; // Handle to the CallWnd hook
HHOOK hGetMsgHook = NULL; // Handle to the GetMsg hook
HHOOK hDialogMsgHook = NULL; // Handle to the DialogMsg hook
HHOOK hLLKeyboardHook = NULL; // Handle to LowLevel kbd hook
HHOOK hLLMouseHook = NULL; // Handle to LowLevel mouse hook
HHOOK hLLKeyboardPrHook = NULL; // Handle to LowLevel kbd hook for local event priority
HHOOK hLLMousePrHook = NULL; // Handle to LowLevel mouse hook for local event priority
HHOOK hKeyboardHook = NULL; // Handle to kbd hook
HHOOK hMouseHook = NULL; // Handle to mouse hook
#pragma data_seg( )
#else
#include "SharedData.h"
#endif // _MSC_VER
/////////////////////////////////////////////////////////////////////////////
// Per-instance DLL variables
const char sPrefSegment[] = "Application_Prefs\\";
char *sModulePrefs = NULL; // Name of the module that created us
BOOL prf_use_GetUpdateRect = FALSE; // Use the GetUpdateRect paint mode
BOOL prf_use_Timer = FALSE; // Use Timer events to trigger updates
BOOL prf_use_KeyPress = FALSE; // Use keyboard events
BOOL prf_use_LButtonUp = TRUE; // Use left mouse button up events
BOOL prf_use_MButtonUp = FALSE; // Use middle mouse button up events
BOOL prf_use_RButtonUp = FALSE; // Use right mouse button up events
BOOL prf_use_Deferral = FALSE; // Use deferred updates
HKEY hModuleKey = NULL; // Key used to save settings
HINSTANCE hInstance = NULL; // This instance of the DLL
BOOL HookMaster = FALSE; // Is this instance veneto itself?
BOOL appHookedOK = FALSE; // Did InitInstance succeed?
/////////////////////////////////////////////////////////////////////////////
// Registered messages & atoms to be used by VNCHooks.DLL
// Messages
const UINT VNC_DEFERRED_UPDATE = RegisterWindowMessage("VNCHooks.Deferred.UpdateMessage");
// Atoms
const char *VNC_WINDOWPOS_ATOMNAME = "VNCHooks.CopyRect.WindowPos";
const char *VNC_POPUPSELN_ATOMNAME = "VNCHooks.PopUpMenu.Selected";
ATOM VNC_WINDOWPOS_ATOM = NULL;
ATOM VNC_POPUPSELN_ATOM = NULL;
/////////////////////////////////////////////////////////////////////////////
// The DLL functions
// Forward definition of hook procedures
BOOL HookHandle(UINT msg, HWND hWnd, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK CallWndProc (int nCode, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK GetMessageProc(int nCode, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK DialogMessageProc(int nCode, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK LowLevelKeyboardFilterProc(int nCode, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK LowLevelMouseFilterProc(int nCode, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK LowLevelKeyboardPriorityProc(int nCode, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK LowLevelMousePriorityProc(int nCode, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK KeyboardPriorityProc(int nCode, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK MousePriorityProc(int nCode, WPARAM wParam, LPARAM lParam);
// Forward definition of setup and shutdown procedures
BOOL InitInstance();
BOOL ExitInstance();
// The DLL's main procedure
BOOL WINAPI DllMain (HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
// Find out why we're being called
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
#ifdef _MSC_VER
_RPT0(_CRT_WARN, "vncHooks : Hook DLL loaded\n");
#endif
// Save the instance handle
hInstance = (HINSTANCE)hInst;
// Call the initialisation function
appHookedOK = InitInstance();
// ALWAYS return TRUE to avoid breaking unhookable applications!!!
return TRUE;
case DLL_PROCESS_DETACH:
#ifdef _MSC_VER
_RPT0(_CRT_WARN, "vncHooks : Hook DLL unloaded\n");
#endif
// Call the exit function
// If the app failed to hook OK, ExitInstance will still operate OK (hopefully...)
ExitInstance();
return TRUE;
default:
return TRUE;
}
}
// Add the new hook
DllExport BOOL SetHook(HWND hWnd, UINT UpdateMsg, UINT CopyMsg, UINT MouseMsg)
{
// Don't add the hook if the window ID is NULL
if (hWnd == NULL)
return FALSE;
// Don't add a hook if there is already one added
if (hVeneto != NULL)
return FALSE;
// Add the CallWnd hook
hCallWndHook = SetWindowsHookEx(
WH_CALLWNDPROC, // Hook in before msg reaches app
(HOOKPROC) CallWndProc, // Hook procedure
hInstance, // This DLL instance
0L // Hook in to all apps
// GetCurrentThreadId() // DEBUG : HOOK ONLY WinVNC
);
// Add the GetMessage hook
hGetMsgHook = SetWindowsHookEx(
WH_GETMESSAGE, // Hook in before msg reaches app
(HOOKPROC) GetMessageProc, // Hook procedure
hInstance, // This DLL instance
0L // Hook in to all apps
// GetCurrentThreadId() // DEBUG : HOOK ONLY WinVNC
);
// Add the GetMessage hook
hDialogMsgHook = SetWindowsHookEx(
WH_SYSMSGFILTER, // Hook in dialogs, menus and scrollbars
(HOOKPROC) DialogMessageProc, // Hook procedure
hInstance, // This DLL instance
0L // Hook in to all apps
);
// Check that it worked
if ((hCallWndHook != NULL) && (hGetMsgHook != NULL) && (hDialogMsgHook != NULL))
{
hVeneto = hWnd; // Save the WinRFB window handle
UpdateRectMessage = UpdateMsg; // Save the message ID to use for rectangle updates
CopyRectMessage = CopyMsg; // Save the message ID to use for copyrect
MouseMoveMessage = MouseMsg; // Save the message ID to send when mouse moves
HookMaster = TRUE; // Set the HookMaster flag for this instance
#ifdef _MSC_VER
_RPT1(_CRT_WARN, "Window : %d\n", hWnd);
#endif
return TRUE;
}
else
{
// Stop the keyboard hook
SetKeyboardFilterHook(FALSE);
SetMouseFilterHook(FALSE);
// Kill the main hooks
if (hCallWndHook != NULL)
UnhookWindowsHookEx(hCallWndHook);
if (hGetMsgHook != NULL)
UnhookWindowsHookEx(hGetMsgHook);
if (hDialogMsgHook != NULL)
UnhookWindowsHookEx(hDialogMsgHook);
hCallWndHook = NULL;
hGetMsgHook = NULL;
hDialogMsgHook = NULL;
}
// The hook failed, so return an error code
return FALSE;
}
// EnumWindows procedure to remove the extra property we added
BOOL CALLBACK
KillPropsProc(HWND hwnd, LPARAM lParam)
{
// Remove our custom property...
RemoveProp(hwnd, (LPCTSTR) MAKEWORD(VNC_WINDOWPOS_ATOM, 0));
RemoveProp(hwnd, (LPCTSTR) MAKEWORD(VNC_POPUPSELN_ATOM, 0));
return TRUE;
}
// Remove the hook from the system
DllExport BOOL UnSetHook(HWND hWnd)
{
BOOL unHooked = TRUE;
// Remove the extra property value from all local windows
EnumWindows((WNDENUMPROC) &KillPropsProc, NULL);
// Stop the keyboard & mouse hooks
unHooked = unHooked && SetKeyboardFilterHook(FALSE);
unHooked = unHooked && SetMouseFilterHook(FALSE);
// Is the window handle valid?
if (hWnd == NULL)
MessageBox(NULL, "Window pointer is null", "Message", MB_OK);
// Is the correct application calling UnSetHook?
if (hWnd != hVeneto)
return FALSE;
// Unhook the procs
if (hCallWndHook != NULL)
{
unHooked = unHooked && UnhookWindowsHookEx(hCallWndHook);
hCallWndHook = NULL;
}
if (hGetMsgHook != NULL)
{
unHooked = unHooked && UnhookWindowsHookEx(hGetMsgHook);
hGetMsgHook = NULL;
}
if (hDialogMsgHook != NULL)
{
unHooked = unHooked && UnhookWindowsHookEx(hDialogMsgHook);
hDialogMsgHook = NULL;
}
// If we managed to unhook then reset
if (unHooked)
{
hVeneto = NULL;
HookMaster = FALSE;
}
return unHooked;
}
// Routine to start and stop local keyboard message filtering
DllExport BOOL SetKeyboardFilterHook(BOOL activate)
{
if (activate)
{
#ifdef WH_KEYBOARD_LL
if (hLLKeyboardHook == NULL)
{
// Start up the hook...
hLLKeyboardHook = SetWindowsHookEx(
WH_KEYBOARD_LL, // Hook in before msg reaches app
(HOOKPROC) LowLevelKeyboardFilterProc, // Hook procedure
hInstance, // This DLL instance
0L // Hook in to all apps
);
if (hLLKeyboardHook == NULL)
return FALSE;
}
return TRUE;
#else
#pragma message("warning:Low-Level Keyboard hook code omitted.")
return FALSE;
#endif
} else {
if (hLLKeyboardHook != NULL)
{
// Stop the hook...
if (!UnhookWindowsHookEx(hLLKeyboardHook))
return FALSE;
hLLKeyboardHook = NULL;
}
return TRUE;
}
}
DllExport BOOL SetKeyboardPriorityLLHook(HWND hwnd, BOOL activate, UINT LocalKbdMsg)
{
LocalKeyboardMessage = LocalKbdMsg;
if (activate)
{
#ifdef WH_KEYBOARD_LL
if (hLLKeyboardPrHook == NULL)
{
// save the window handle
hKeyboardPriorityWindow = hwnd;
// Start up the hook...
hLLKeyboardPrHook = SetWindowsHookEx(
WH_KEYBOARD_LL, // Hook in before msg reaches app
(HOOKPROC) LowLevelKeyboardPriorityProc, // Hook procedure
hInstance, // This DLL instance
0L // Hook in to all apps
);
if (hLLKeyboardPrHook == NULL)
return FALSE;
}
return TRUE;
#else
#pragma message("warning:Low-Level Keyboard hook code omitted.")
return FALSE;
#endif
} else {
if (hLLKeyboardPrHook != NULL)
{
// Stop the hook...
if (!UnhookWindowsHookEx(hLLKeyboardPrHook))
return FALSE;
// reset the hook and window handle
hKeyboardPriorityWindow = NULL;
hLLKeyboardPrHook = NULL;
}
return TRUE;
}
}
// Routine to start and stop local mouse message filtering
DllExport BOOL SetMouseFilterHook(BOOL activate)
{
if (activate)
{
#ifdef WH_MOUSE_LL
if (hLLMouseHook == NULL)
{
// Start up the hook...
hLLMouseHook = SetWindowsHookEx(
WH_MOUSE_LL, // Hook in before msg reaches app
(HOOKPROC) LowLevelMouseFilterProc, // Hook procedure
hInstance, // This DLL instance
0L // Hook in to all apps
);
if (hLLMouseHook == NULL)
return FALSE;
}
return TRUE;
#else
#pragma message("warning:Low-Level Mouse hook code omitted.")
return FALSE;
#endif
} else {
if (hLLMouseHook != NULL)
{
// Stop the hook...
if (!UnhookWindowsHookEx(hLLMouseHook))
return FALSE;
hLLMouseHook = NULL;
}
return TRUE;
}
}
DllExport BOOL SetMousePriorityLLHook(HWND hwnd, BOOL activate, UINT LocalMouseMsg)
{
LocalMouseMessage = LocalMouseMsg;
if (activate)
{
#ifdef WH_MOUSE_LL
if (hLLMousePrHook == NULL)
{
// save the window handle
hMousePriorityWindow = hwnd;
// Start up the hook...
hLLMousePrHook = SetWindowsHookEx(
WH_MOUSE_LL, // Hook in before msg reaches app
(HOOKPROC) LowLevelMousePriorityProc, // Hook procedure
hInstance, // This DLL instance
0L // Hook in to all apps
);
if (hLLMousePrHook == NULL)
return FALSE;
}
return TRUE;
#else
#pragma message("warning:Low-Level Mouse hook code omitted.")
return FALSE;
#endif
} else {
if (hLLMousePrHook != NULL)
{
// Stop the hook...
if (!UnhookWindowsHookEx(hLLMousePrHook))
return FALSE;
// reset the hook and window handle
hMousePriorityWindow = NULL;
hLLMousePrHook = NULL;
}
return TRUE;
}
}
// Routine to start and stop local keyboard message filtering
DllExport BOOL SetKeyboardPriorityHook(HWND hwnd, BOOL activate, UINT LocalKbdMsg)
{
LocalKeyboardMessage = LocalKbdMsg;
if (activate)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -