1
// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
3
// This file is part of the VNC system.
5
// The VNC system is free software; you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation; either version 2 of the License, or
8
// (at your option) any later version.
10
// This program is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
// GNU General Public License for more details.
15
// You should have received a copy of the GNU General Public License
16
// along with this program; if not, write to the Free Software
17
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20
// TightVNC distribution homepage on the Web: http://www.tightvnc.com/
22
// If the source code for the VNC system is not available from the place
23
// whence you received this file, check http://www.uk.research.att.com/vnc or contact
24
// the authors on vnc@uk.research.att.com for information on obtaining it.
26
// VNCHooks.cpp : Defines the implementation of the DLL.
35
/////////////////////////////////////////////////////////////////////////////
36
// Storage for the global data in the DLL
37
// Note: For Borland C++ compilers, this data segment is defined in a
38
// separate file, SharedData.cpp.
42
// MSVC is bugged - if a default value is missed off from one of the following
43
// variables then that variable is process-specific for some reason!
45
#pragma data_seg(".SharedData")
47
HWND hKeyboardPriorityWindow = NULL;
48
HWND hMousePriorityWindow = NULL;
49
UINT UpdateRectMessage = 0;
50
UINT CopyRectMessage = 0;
51
UINT MouseMoveMessage = 0;
52
UINT LocalMouseMessage = 0;
53
UINT LocalKeyboardMessage = 0;
54
HHOOK hCallWndHook = NULL; // Handle to the CallWnd hook
55
HHOOK hGetMsgHook = NULL; // Handle to the GetMsg hook
56
HHOOK hDialogMsgHook = NULL; // Handle to the DialogMsg hook
57
HHOOK hLLKeyboardHook = NULL; // Handle to LowLevel kbd hook
58
HHOOK hLLMouseHook = NULL; // Handle to LowLevel mouse hook
59
HHOOK hLLKeyboardPrHook = NULL; // Handle to LowLevel kbd hook for local event priority
60
HHOOK hLLMousePrHook = NULL; // Handle to LowLevel mouse hook for local event priority
61
HHOOK hKeyboardHook = NULL; // Handle to kbd hook
62
HHOOK hMouseHook = NULL; // Handle to mouse hook
68
#include "SharedData.h"
72
#ifndef LLMHF_INJECTED
73
/* from $prefix/include/wine/windows/winuser.h */
74
#define LLMHF_INJECTED 0x000000001
77
/////////////////////////////////////////////////////////////////////////////
78
// Per-instance DLL variables
80
const char sPrefSegment[] = "Application_Prefs\\";
81
char *sModulePrefs = NULL; // Name of the module that created us
82
BOOL prf_use_GetUpdateRect = FALSE; // Use the GetUpdateRect paint mode
83
BOOL prf_use_Timer = FALSE; // Use Timer events to trigger updates
84
BOOL prf_use_KeyPress = FALSE; // Use keyboard events
85
BOOL prf_use_LButtonUp = TRUE; // Use left mouse button up events
86
BOOL prf_use_MButtonUp = FALSE; // Use middle mouse button up events
87
BOOL prf_use_RButtonUp = FALSE; // Use right mouse button up events
88
BOOL prf_use_Deferral = FALSE; // Use deferred updates
90
HKEY hModuleKey = NULL; // Key used to save settings
91
HINSTANCE hInstance = NULL; // This instance of the DLL
92
BOOL HookMaster = FALSE; // Is this instance veneto itself?
94
BOOL appHookedOK = FALSE; // Did InitInstance succeed?
96
/////////////////////////////////////////////////////////////////////////////
97
// Registered messages & atoms to be used by VNCHooks.DLL
100
const UINT VNC_DEFERRED_UPDATE = RegisterWindowMessage("VNCHooks.Deferred.UpdateMessage");
103
const char *VNC_WINDOWPOS_ATOMNAME = "VNCHooks.CopyRect.WindowPos";
104
const char *VNC_POPUPSELN_ATOMNAME = "VNCHooks.PopUpMenu.Selected";
105
ATOM VNC_WINDOWPOS_ATOM = (ATOM) NULL;
106
ATOM VNC_POPUPSELN_ATOM = (ATOM) NULL;
108
/////////////////////////////////////////////////////////////////////////////
111
// Forward definition of hook procedures
113
BOOL HookHandle(UINT msg, HWND hWnd, WPARAM wParam, LPARAM lParam);
114
LRESULT CALLBACK CallWndProc (int nCode, WPARAM wParam, LPARAM lParam);
115
LRESULT CALLBACK GetMessageProc(int nCode, WPARAM wParam, LPARAM lParam);
116
LRESULT CALLBACK DialogMessageProc(int nCode, WPARAM wParam, LPARAM lParam);
117
LRESULT CALLBACK LowLevelKeyboardFilterProc(int nCode, WPARAM wParam, LPARAM lParam);
118
LRESULT CALLBACK LowLevelMouseFilterProc(int nCode, WPARAM wParam, LPARAM lParam);
119
LRESULT CALLBACK LowLevelKeyboardPriorityProc(int nCode, WPARAM wParam, LPARAM lParam);
120
LRESULT CALLBACK LowLevelMousePriorityProc(int nCode, WPARAM wParam, LPARAM lParam);
121
LRESULT CALLBACK KeyboardPriorityProc(int nCode, WPARAM wParam, LPARAM lParam);
122
LRESULT CALLBACK MousePriorityProc(int nCode, WPARAM wParam, LPARAM lParam);
124
// Forward definition of setup and shutdown procedures
128
// The DLL's main procedure
129
extern "C" BOOL APIENTRY DllMain (HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
131
// Find out why we're being called
132
switch (ul_reason_for_call)
135
case DLL_PROCESS_ATTACH:
137
_RPT0(_CRT_WARN, "vncHooks : Hook DLL loaded\n");
140
// Save the instance handle
141
hInstance = (HINSTANCE)hInst;
142
// Call the initialisation function
143
appHookedOK = InitInstance();
145
// ALWAYS return TRUE to avoid breaking unhookable applications!!!
148
case DLL_PROCESS_DETACH:
150
_RPT0(_CRT_WARN, "vncHooks : Hook DLL unloaded\n");
153
// Call the exit function
154
// If the app failed to hook OK, ExitInstance will still operate OK (hopefully...)
166
DllExport BOOL SetHook(HWND hWnd, UINT UpdateMsg, UINT CopyMsg, UINT MouseMsg)
169
// Don't add the hook if the window ID is NULL
173
// Don't add a hook if there is already one added
177
// Add the CallWnd hook
178
hCallWndHook = SetWindowsHookEx(
179
WH_CALLWNDPROC, // Hook in before msg reaches app
180
(HOOKPROC) CallWndProc, // Hook procedure
181
hInstance, // This DLL instance
182
0L // Hook in to all apps
183
// GetCurrentThreadId() // DEBUG : HOOK ONLY WinVNC
186
// Add the GetMessage hook
187
hGetMsgHook = SetWindowsHookEx(
188
WH_GETMESSAGE, // Hook in before msg reaches app
189
(HOOKPROC) GetMessageProc, // Hook procedure
190
hInstance, // This DLL instance
191
0L // Hook in to all apps
192
// GetCurrentThreadId() // DEBUG : HOOK ONLY WinVNC
195
// Add the GetMessage hook
196
hDialogMsgHook = SetWindowsHookEx(
197
WH_SYSMSGFILTER, // Hook in dialogs, menus and scrollbars
198
(HOOKPROC) DialogMessageProc, // Hook procedure
199
hInstance, // This DLL instance
200
0L // Hook in to all apps
203
// Check that it worked
204
if ((hCallWndHook != NULL) && (hGetMsgHook != NULL) && (hDialogMsgHook != NULL))
206
hVeneto = hWnd; // Save the WinRFB window handle
207
UpdateRectMessage = UpdateMsg; // Save the message ID to use for rectangle updates
208
CopyRectMessage = CopyMsg; // Save the message ID to use for copyrect
209
MouseMoveMessage = MouseMsg; // Save the message ID to send when mouse moves
210
HookMaster = TRUE; // Set the HookMaster flag for this instance
213
_RPT1(_CRT_WARN, "Window : %d\n", hWnd);
220
// Stop the keyboard hook
221
SetKeyboardFilterHook(FALSE);
222
SetMouseFilterHook(FALSE);
224
// Kill the main hooks
225
if (hCallWndHook != NULL)
226
UnhookWindowsHookEx(hCallWndHook);
227
if (hGetMsgHook != NULL)
228
UnhookWindowsHookEx(hGetMsgHook);
229
if (hDialogMsgHook != NULL)
230
UnhookWindowsHookEx(hDialogMsgHook);
233
hDialogMsgHook = NULL;
236
// The hook failed, so return an error code
241
// EnumWindows procedure to remove the extra property we added
244
KillPropsProc(HWND hwnd, LPARAM lParam)
246
// Remove our custom property...
247
RemoveProp(hwnd, (LPCTSTR) MAKEWORD(VNC_WINDOWPOS_ATOM, 0));
248
RemoveProp(hwnd, (LPCTSTR) MAKEWORD(VNC_POPUPSELN_ATOM, 0));
252
// Remove the hook from the system
254
DllExport BOOL UnSetHook(HWND hWnd)
257
BOOL unHooked = TRUE;
259
// Remove the extra property value from all local windows
260
EnumWindows((WNDENUMPROC) &KillPropsProc, (LPARAM) NULL);
262
// Stop the keyboard & mouse hooks
263
unHooked = unHooked && SetKeyboardFilterHook(FALSE);
264
unHooked = unHooked && SetMouseFilterHook(FALSE);
266
// Is the window handle valid?
268
MessageBox(NULL, "Window pointer is null", "Message", MB_OK);
270
// Is the correct application calling UnSetHook?
275
if (hCallWndHook != NULL)
277
unHooked = unHooked && UnhookWindowsHookEx(hCallWndHook);
281
if (hGetMsgHook != NULL)
283
unHooked = unHooked && UnhookWindowsHookEx(hGetMsgHook);
287
if (hDialogMsgHook != NULL)
289
unHooked = unHooked && UnhookWindowsHookEx(hDialogMsgHook);
290
hDialogMsgHook = NULL;
293
// If we managed to unhook then reset
304
// Routine to start and stop local keyboard message filtering
305
DllExport BOOL SetKeyboardFilterHook(BOOL activate)
309
#ifdef WH_KEYBOARD_LL
310
if (hLLKeyboardHook == NULL)
312
// Start up the hook...
313
hLLKeyboardHook = SetWindowsHookEx(
314
WH_KEYBOARD_LL, // Hook in before msg reaches app
315
(HOOKPROC) LowLevelKeyboardFilterProc, // Hook procedure
316
hInstance, // This DLL instance
317
0L // Hook in to all apps
319
if (hLLKeyboardHook == NULL)
324
#pragma message("warning:Low-Level Keyboard hook code omitted.")
328
if (hLLKeyboardHook != NULL)
331
if (!UnhookWindowsHookEx(hLLKeyboardHook))
333
hLLKeyboardHook = NULL;
339
DllExport BOOL SetKeyboardPriorityLLHook(HWND hwnd, BOOL activate, UINT LocalKbdMsg)
341
LocalKeyboardMessage = LocalKbdMsg;
344
#ifdef WH_KEYBOARD_LL
345
if (hLLKeyboardPrHook == NULL)
347
// save the window handle
348
hKeyboardPriorityWindow = hwnd;
350
// Start up the hook...
351
hLLKeyboardPrHook = SetWindowsHookEx(
352
WH_KEYBOARD_LL, // Hook in before msg reaches app
353
(HOOKPROC) LowLevelKeyboardPriorityProc, // Hook procedure
354
hInstance, // This DLL instance
355
0L // Hook in to all apps
357
if (hLLKeyboardPrHook == NULL)
362
#pragma message("warning:Low-Level Keyboard hook code omitted.")
366
if (hLLKeyboardPrHook != NULL)
369
if (!UnhookWindowsHookEx(hLLKeyboardPrHook))
372
// reset the hook and window handle
373
hKeyboardPriorityWindow = NULL;
374
hLLKeyboardPrHook = NULL;
380
// Routine to start and stop local mouse message filtering
381
DllExport BOOL SetMouseFilterHook(BOOL activate)
386
if (hLLMouseHook == NULL)
388
// Start up the hook...
389
hLLMouseHook = SetWindowsHookEx(
390
WH_MOUSE_LL, // Hook in before msg reaches app
391
(HOOKPROC) LowLevelMouseFilterProc, // Hook procedure
392
hInstance, // This DLL instance
393
0L // Hook in to all apps
395
if (hLLMouseHook == NULL)
400
#pragma message("warning:Low-Level Mouse hook code omitted.")
404
if (hLLMouseHook != NULL)
407
if (!UnhookWindowsHookEx(hLLMouseHook))
415
DllExport BOOL SetMousePriorityLLHook(HWND hwnd, BOOL activate, UINT LocalMouseMsg)
417
LocalMouseMessage = LocalMouseMsg;
421
if (hLLMousePrHook == NULL)
423
// save the window handle
424
hMousePriorityWindow = hwnd;
426
// Start up the hook...
427
hLLMousePrHook = SetWindowsHookEx(
428
WH_MOUSE_LL, // Hook in before msg reaches app
429
(HOOKPROC) LowLevelMousePriorityProc, // Hook procedure
430
hInstance, // This DLL instance
431
0L // Hook in to all apps
433
if (hLLMousePrHook == NULL)
438
#pragma message("warning:Low-Level Mouse hook code omitted.")
442
if (hLLMousePrHook != NULL)
445
if (!UnhookWindowsHookEx(hLLMousePrHook))
448
// reset the hook and window handle
449
hMousePriorityWindow = NULL;
450
hLLMousePrHook = NULL;
457
// Routine to start and stop local keyboard message filtering
458
DllExport BOOL SetKeyboardPriorityHook(HWND hwnd, BOOL activate, UINT LocalKbdMsg)
460
LocalKeyboardMessage = LocalKbdMsg;
463
if (hKeyboardHook == NULL)
465
// save the window handle
466
hKeyboardPriorityWindow = hwnd;
468
// Start up the hook...
469
hKeyboardHook = SetWindowsHookEx(
470
WH_KEYBOARD, // Hook in before msg reaches app
471
(HOOKPROC) KeyboardPriorityProc,// Hook procedure
472
hInstance, // This DLL instance
473
0L // Hook in to all apps
475
if (hKeyboardHook == NULL)
480
if (hKeyboardHook != NULL)
483
if (!UnhookWindowsHookEx(hKeyboardHook))
486
// reset the hook and window handle
487
hKeyboardPriorityWindow = NULL;
488
hKeyboardHook = NULL;
495
// Routine to start and stop local mouse message filtering
496
DllExport BOOL SetMousePriorityHook(HWND hwnd, BOOL activate, UINT LocalMouseMsg)
498
LocalMouseMessage = LocalMouseMsg;
501
if (hMouseHook == NULL)
503
// save the window handle
504
hMousePriorityWindow = hwnd;
506
// Start up the hook...
507
hMouseHook = SetWindowsHookEx(
508
WH_MOUSE, // Hook in before msg reaches app
509
(HOOKPROC) MousePriorityProc, // Hook procedure
510
hInstance, // This DLL instance
511
0L // Hook in to all apps
513
if (hMouseHook == NULL)
518
if (hMouseHook != NULL)
521
if (!UnhookWindowsHookEx(hMouseHook))
524
// reset the hook and window handle
525
hMousePriorityWindow = NULL;
534
// Routine to get the window's client rectangle, in screen coordinates
535
inline BOOL GetAbsoluteClientRect(HWND hwnd, RECT *rect)
541
// Get the client rectangle size
542
if (!GetClientRect(hwnd, rect))
545
// Get the client rectangle position
546
if (!ClientToScreen(hwnd, &topleft))
549
// Now adjust the window rectangle
550
rect->left += topleft.x;
551
rect->top += topleft.y;
552
rect->right += topleft.x;
553
rect->bottom += topleft.y;
558
// Routine to send a CopyRect message to WinVNC
559
inline void SendCopyWindowRect(HWND hWnd)
563
// All we send back is the handle of the window to be moved
564
vwParam = (LPARAM) hWnd;
566
// Send the update to Veneto
575
// Routine to send an UpdateRect message to Veneto
576
inline void SendUpdateRect(SHORT x, SHORT y, SHORT x2, SHORT y2)
581
vwParam = MAKELONG(x, y);
582
vlParam = MAKELONG(x2, y2);
584
// Send the update to Veneto
593
// Send a window's position to Veneto
595
inline void SendWindowRect(HWND hWnd)
599
// Get the rectangle position
600
if (GetWindowRect(hWnd, &wrect) && IsWindowVisible(hWnd))
612
// Send a deferred message into this Window's message queue, so that
613
// we'll intercept it again only after the message that triggered it has been
616
inline void SendDeferredUpdateRect(HWND hWnd, SHORT x, SHORT y, SHORT x2, SHORT y2)
621
vwParam = MAKELONG(x, y);
622
vlParam = MAKELONG(x2, y2);
624
if (prf_use_Deferral)
626
// Send the update back to the window
636
// Send the update to WinRFB
646
inline void SendDeferredWindowRect(HWND hWnd)
650
// Get the rectangle position
651
if (::GetWindowRect(hWnd, &wrect) && ::IsWindowVisible(hWnd))
654
SendDeferredUpdateRect(
664
inline void SendDeferredBorderRect(HWND hWnd)
669
// Get the rectangle position
670
if (GetWindowRect(hWnd, &wrect) && ::IsWindowVisible(hWnd))
672
// Get the client rectangle position
673
if (GetAbsoluteClientRect(hWnd, &crect))
675
// Send the four border rectangles
676
SendDeferredUpdateRect(hWnd, (SHORT) wrect.left, (SHORT) wrect.top, (SHORT) wrect.right, (SHORT) crect.top);
677
SendDeferredUpdateRect(hWnd, (SHORT) wrect.left, (SHORT) wrect.top, (SHORT) crect.left, (SHORT) wrect.bottom);
678
SendDeferredUpdateRect(hWnd, (SHORT) wrect.left, (SHORT) crect.bottom, (SHORT) wrect.right, (SHORT) wrect.bottom);
679
SendDeferredUpdateRect(hWnd, (SHORT) crect.right, (SHORT) wrect.top, (SHORT) wrect.right, (SHORT) wrect.bottom);
684
// Generic hook-handler
686
inline BOOL HookHandle(UINT MessageId, HWND hWnd, WPARAM wParam, LPARAM lParam)
688
////////////////////////////////////////////////////////////////
689
// *** HANDLE DEFERRED UPDATES ***
691
// Is this a deferred-update message?
692
if (MessageId == VNC_DEFERRED_UPDATE)
695
// NOTE : NEVER use the SendDeferred- routines to send updates
696
// from here, or you'll get an infinite loop....!
698
// NB : The format of DEFERRED_UPDATE matches that of UpdateRectMessage,
699
// so just send the exact same message data to WinRFB:
711
// *** Could use WM_COPYDATA to send data to WinVNC
714
if (GetClassLong(hWnd, GCW_ATOM) == 32768)
716
_RPT4(_CRT_WARN, "DBG : popup menu message (hwnd=%d, msg=%d, l=%d, w=%d)\n",
717
hWnd, MessageId, lParam, wParam);
721
////////////////////////////////////////////////////////////////
722
// *** UPDATE-TRIGGERING MESSAGES ***
724
// Do something dependent upon message type
728
////////////////////////////////////////////////////////////////
729
// Messages indicating only a border repaint.
732
SendDeferredBorderRect(hWnd);
735
////////////////////////////////////////////////////////////////
736
// Messages indicating a client area repaint
738
case WM_KEYUP: // Handle key-presses
739
if (prf_use_KeyPress)
740
SendDeferredWindowRect(hWnd);
743
case WM_LBUTTONUP: // Handle LMB clicks
744
if (prf_use_LButtonUp)
745
SendDeferredWindowRect(hWnd);
748
case WM_MBUTTONUP: // Handle MMB clicks
749
if (prf_use_MButtonUp)
750
SendDeferredWindowRect(hWnd);
753
case WM_RBUTTONUP: // Handle RMB clicks
754
if (prf_use_RButtonUp)
755
SendDeferredWindowRect(hWnd);
760
SendDeferredWindowRect(hWnd);
765
if (((int) LOWORD(wParam) == SB_THUMBTRACK) || ((int) LOWORD(wParam) == SB_ENDSCROLL))
766
SendDeferredWindowRect(hWnd);
769
case 485: // HACK to handle popup menus
771
// Get the old popup menu selection value
772
HANDLE prop = GetProp(hWnd, (LPCTSTR) MAKELONG(VNC_POPUPSELN_ATOM, 0));
773
if (prop != (HANDLE) wParam)
775
// It did, so update the menu & the selection value
776
SendDeferredWindowRect(hWnd);
778
(LPCTSTR) MAKELONG(VNC_POPUPSELN_ATOM, 0),
784
////////////////////////////////////////////////////////////////
785
// Messages indicating a full window update
786
case WM_SYSCOLORCHANGE:
787
case WM_PALETTECHANGED:
793
//case WM_MENUSELECT:
794
SendDeferredWindowRect(hWnd);
797
////////////////////////////////////////////////////////////////
798
// Messages indicating that an area of the window needs updating
799
// Uses GetUpdateRect to find out which
801
if (prf_use_GetUpdateRect)
804
region = CreateRectRgn(0, 0, 0, 0);
806
// Get the affected region
807
if (GetUpdateRgn(hWnd, region, FALSE) != ERROR)
814
// Get the top-left point of the client area
817
if (!ClientToScreen(hWnd, &TopLeft))
820
// Get the size of buffer required
821
buffsize = GetRegionData(region, 0, 0);
824
buff = (RGNDATA *) new BYTE [buffsize];
828
// Now get the region data
829
if(GetRegionData(region, buffsize, buff))
831
for (x=0; x<(buff->rdh.nCount); x++)
833
// Obtain the rectangles from the list
834
RECT *urect = (RECT *) (((BYTE *) buff) + sizeof(RGNDATAHEADER) + (x * sizeof(RECT)));
835
SendDeferredUpdateRect(
837
(SHORT) (TopLeft.x + urect->left),
838
(SHORT) (TopLeft.y + urect->top),
839
(SHORT) (TopLeft.x + urect->right),
840
(SHORT) (TopLeft.y + urect->bottom)
849
// Now free the region
851
DeleteObject(region);
854
SendDeferredWindowRect(hWnd);
857
////////////////////////////////////////////////////////////////
858
// Messages indicating full repaint of this and a different window
859
// Send the new position of the window
860
case WM_WINDOWPOSCHANGING:
861
if (IsWindowVisible(hWnd))
862
SendWindowRect(hWnd);
865
case WM_WINDOWPOSCHANGED:
866
if (IsWindowVisible(hWnd))
867
SendDeferredWindowRect(hWnd);
870
////////////////////////////////////////////////////////////////
871
// WinRFB also wants to know about mouse movement
874
// Inform WinRFB that the mouse has moved and pass it the current cursor handle
883
////////////////////////////////////////////////////////////////
884
// VNCHOOKS PROPERTIES HANDLING WINDOWS
886
RemoveProp(hWnd, (LPCTSTR) MAKEWORD(VNC_WINDOWPOS_ATOM, 0));
887
RemoveProp(hWnd, (LPCTSTR) MAKEWORD(VNC_POPUPSELN_ATOM, 0));
895
// Hook procedure for CallWindow hook
897
LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam)
899
// Do we have to handle this message?
900
if (nCode == HC_ACTION)
902
// Process the hook if the Veneto window handle is valid
905
CWPSTRUCT *cwpStruct = (CWPSTRUCT *) lParam;
906
HookHandle(cwpStruct->message, cwpStruct->hwnd, cwpStruct->wParam, cwpStruct->lParam);
910
// Call the next handler in the chain
911
return CallNextHookEx (hCallWndHook, nCode, wParam, lParam);
914
// Hook procedure for GetMessageProc hook
916
LRESULT CALLBACK GetMessageProc(int nCode, WPARAM wParam, LPARAM lParam)
918
// Do we have to handle this message?
919
if (nCode == HC_ACTION)
921
// Process the hook only if the Veneto window is valid
924
MSG *msg = (MSG *) lParam;
926
// Only handle application messages if they're being removed:
927
if (wParam & PM_REMOVE)
929
// Handle the message
930
HookHandle(msg->message, msg->hwnd, msg->wParam, msg->lParam);
935
// Call the next handler in the chain
936
return CallNextHookEx (hGetMsgHook, nCode, wParam, lParam);
939
// Hook procedure for DialogMessageProc hook
941
LRESULT CALLBACK DialogMessageProc(int nCode, WPARAM wParam, LPARAM lParam)
943
// Do we have to handle this message?
946
// Process the hook only if the Veneto window is valid
949
MSG *msg = (MSG *) lParam;
951
// Handle the message
952
HookHandle(msg->message, msg->hwnd, msg->wParam, msg->lParam);
956
// Call the next handler in the chain
957
return CallNextHookEx (hGetMsgHook, nCode, wParam, lParam);
960
// Hook procedure for LowLevel Keyboard filtering
962
#ifdef WH_KEYBOARD_LL
963
LRESULT CALLBACK LowLevelKeyboardFilterProc(int nCode, WPARAM wParam, LPARAM lParam)
965
// Are we expected to handle this callback?
966
if (nCode == HC_ACTION)
968
// Is this keyboard event "real" or "injected"
969
// i.e. hardware or software-produced?
970
KBDLLHOOKSTRUCT *hookStruct = (KBDLLHOOKSTRUCT*)lParam;
971
if (!(hookStruct->flags & LLKHF_INJECTED) && __localInputsDisabled) {
972
// Message was not injected - reject it!
977
// Otherwise, pass on the message
978
return CallNextHookEx(hLLKeyboardHook, nCode, wParam, lParam);
981
LRESULT CALLBACK LowLevelKeyboardPriorityProc(int nCode, WPARAM wParam, LPARAM lParam)
983
// Are we expected to handle this callback?
984
// do we have a target window handle?
985
if (nCode == HC_ACTION && hKeyboardPriorityWindow != NULL)
987
// Is this keyboard event "real" or "injected"
988
// i.e. hardware or software-produced?
989
KBDLLHOOKSTRUCT *hookStruct = (KBDLLHOOKSTRUCT*)lParam;
990
if (!(hookStruct->flags & LLKHF_INJECTED)) {
991
// Message was not injected - send RFB_LOCAL_KEYBOARD msg!
992
// Remote event will be blocked
994
hKeyboardPriorityWindow,
995
LocalKeyboardMessage,
1002
// Otherwise, pass on the message
1003
return CallNextHookEx(hLLKeyboardPrHook, nCode, wParam, lParam);
1008
// Hook procedure for LowLevel Mouse filtering
1011
LRESULT CALLBACK LowLevelMouseFilterProc(int nCode, WPARAM wParam, LPARAM lParam)
1013
// Are we expected to handle this callback?
1014
if (nCode == HC_ACTION)
1016
// Is this mouse event "real" or "injected"
1017
// i.e. hardware or software-produced?
1018
MSLLHOOKSTRUCT *hookStruct = (MSLLHOOKSTRUCT*)lParam;
1019
if (!(hookStruct->flags & LLMHF_INJECTED) && __localInputsDisabled) {
1025
// Otherwise, pass on the message
1026
return CallNextHookEx(hLLMouseHook, nCode, wParam, lParam);
1029
LRESULT CALLBACK LowLevelMousePriorityProc(int nCode, WPARAM wParam, LPARAM lParam)
1031
// Are we expected to handle this callback?
1032
// do we have a target window handle?
1033
if (nCode == HC_ACTION && hMousePriorityWindow != NULL)
1035
// Is this mouse event "real" or "injected"
1036
// i.e. hardware or software-produced?
1037
MSLLHOOKSTRUCT *hookStruct = (MSLLHOOKSTRUCT*)lParam;
1038
if (!(hookStruct->flags & LLMHF_INJECTED)) {
1039
// Message was not injected - send RFB_LOCAL_MOUSE msg!
1040
// Remote event will be blocked
1042
hMousePriorityWindow,
1050
// Otherwise, pass on the message
1051
return CallNextHookEx(hLLMousePrHook, nCode, wParam, lParam);
1056
LRESULT CALLBACK KeyboardPriorityProc(int nCode, WPARAM wParam, LPARAM lParam)
1058
// Are we expected to handle this callback?
1059
// do we have a target window handle?
1060
if (nCode == HC_ACTION && hKeyboardPriorityWindow != NULL)
1063
hKeyboardPriorityWindow,
1064
LocalKeyboardMessage,
1071
return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
1075
LRESULT CALLBACK MousePriorityProc(int nCode, WPARAM wParam, LPARAM lParam)
1077
// Are we expected to handle this callback?
1078
// do we have a target window handle?
1079
if (nCode == HC_ACTION && hMousePriorityWindow != NULL)
1081
if ( (wParam == WM_LBUTTONDOWN) || (wParam == WM_RBUTTONDOWN) || (wParam == WM_MBUTTONDOWN) || (wParam == WM_MOUSEMOVE) )
1083
hMousePriorityWindow,
1090
return CallNextHookEx(hMouseHook, nCode, wParam, lParam);
1094
char * NameFromPath(const char *path)
1097
int l = strlen(path);
1100
// Find the file part of a filename
1101
for (x=l-1; x>0; x--)
1103
if (path[x] == '\\')
1105
temp = strdup(&(path[x+1]));
1110
// If we didn't fine a \ then just return a copy of the original
1112
temp = strdup(path);
1117
/////////////////////////////////////////////////////////////////////////////
1118
// Initialise / Exit routines.
1119
// These functions handle the update settings for any apps used with WinVNC.
1121
static const TCHAR szSoftware[] = "Software";
1122
static const TCHAR szCompany[] = "ORL";
1123
static const TCHAR szProfile[] = "VNCHooks";
1125
HKEY GetRegistryKey()
1127
HKEY hAppKey = NULL;
1128
HKEY hSoftKey = NULL;
1129
HKEY hCompanyKey = NULL;
1130
if (RegOpenKeyEx(HKEY_CURRENT_USER, szSoftware, 0, KEY_WRITE|KEY_READ,
1131
&hSoftKey) == ERROR_SUCCESS)
1134
if (RegCreateKeyEx(hSoftKey, szCompany, 0, REG_NONE,
1135
REG_OPTION_NON_VOLATILE, KEY_WRITE|KEY_READ, NULL,
1136
&hCompanyKey, &dw) == ERROR_SUCCESS)
1138
RegCreateKeyEx(hCompanyKey, szProfile, 0, REG_NONE,
1139
REG_OPTION_NON_VOLATILE, KEY_WRITE|KEY_READ, NULL,
1143
if (hSoftKey != NULL)
1144
RegCloseKey(hSoftKey);
1145
if (hCompanyKey != NULL)
1146
RegCloseKey(hCompanyKey);
1151
HKEY GetModuleKey(const char *proc_name)
1153
HKEY hModule = NULL;
1155
// Work out the registry key to save this under
1156
sModulePrefs = (char *) malloc(strlen(sPrefSegment) + strlen(proc_name) + 1);
1157
if (sModulePrefs == NULL)
1159
sprintf(sModulePrefs, "%s%s", sPrefSegment, proc_name);
1161
// Check whether the library's entry exists!
1162
HKEY hAppKey = GetRegistryKey();
1163
if (hAppKey == NULL)
1166
// Attempt to open the section for this application
1167
if (RegOpenKeyEx(hAppKey,
1169
0, KEY_WRITE|KEY_READ,
1173
// Cut off the app directory and just use the name
1174
char *file_name = NameFromPath(proc_name);
1176
if (file_name == NULL)
1178
RegCloseKey(hAppKey);
1182
// Adjust the moduleprefs name
1183
sprintf(sModulePrefs, "%s%s", sPrefSegment, file_name);
1186
// Now get the module key again
1188
if (RegCreateKeyEx(hAppKey,
1190
0, REG_NONE, REG_OPTION_NON_VOLATILE,
1194
&dw) != ERROR_SUCCESS)
1196
// Couldn't find/create the key - fail!
1197
RegCloseKey(hAppKey);
1202
// Close the application registry key
1203
RegCloseKey(hAppKey);
1208
int GetProfileInt(LPTSTR key, int def)
1212
ULONG size = sizeof(value);
1214
if (RegQueryValueEx(
1219
(unsigned char *)&value,
1220
&size) == ERROR_SUCCESS)
1222
// Is the value of the right type?
1223
if (type != REG_DWORD)
1238
void WriteProfileInt(LPTSTR key, int value)
1245
(unsigned char *)&value,
1251
// Create the global atoms
1252
VNC_WINDOWPOS_ATOM = GlobalAddAtom(VNC_WINDOWPOS_ATOMNAME);
1253
if (VNC_WINDOWPOS_ATOM == (ATOM) NULL)
1255
VNC_POPUPSELN_ATOM = GlobalAddAtom(VNC_POPUPSELN_ATOMNAME);
1256
if (VNC_POPUPSELN_ATOM == (ATOM) NULL)
1259
// Get the module name
1260
char proc_name[_MAX_PATH];
1263
// Attempt to get the program/module name
1264
if ((size = GetModuleFileName(
1265
GetModuleHandle(NULL),
1266
(char *) &proc_name,
1271
// Get the key for the module
1272
hModuleKey = GetModuleKey(proc_name);
1273
if (hModuleKey == NULL)
1276
// Read in the prefs
1277
prf_use_GetUpdateRect = GetProfileInt(
1278
"use_GetUpdateRect",
1282
prf_use_Timer = GetProfileInt(
1286
prf_use_KeyPress = GetProfileInt(
1290
prf_use_LButtonUp = GetProfileInt(
1294
prf_use_MButtonUp = GetProfileInt(
1298
prf_use_RButtonUp = GetProfileInt(
1302
prf_use_Deferral = GetProfileInt(
1305
FALSE // we use full screen polling anyway
1316
// Free the created atoms
1317
if (VNC_WINDOWPOS_ATOM != (ATOM) NULL)
1319
GlobalDeleteAtom(VNC_WINDOWPOS_ATOM);
1320
VNC_WINDOWPOS_ATOM = (ATOM) NULL;
1322
if (VNC_POPUPSELN_ATOM != (ATOM) NULL)
1324
GlobalDeleteAtom(VNC_POPUPSELN_ATOM);
1325
VNC_POPUPSELN_ATOM = (ATOM) NULL;
1328
// Write the module settings to disk
1329
if (sModulePrefs != NULL)
1332
"use_GetUpdateRect",
1333
prf_use_GetUpdateRect
1367
sModulePrefs = NULL;
1370
// Close the registry key for this module
1371
if (hModuleKey != NULL)
1372
RegCloseKey(hModuleKey);