~ubuntu-branches/debian/lenny/italc/lenny

« back to all changes in this revision

Viewing changes to ica/win32/src/VNCHooks/VNCHooks.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Patrick Winnertz
  • Date: 2008-06-17 13:46:54 UTC
  • mfrom: (1.2.1 upstream) (4.1.1 gutsy)
  • Revision ID: james.westby@ubuntu.com-20080617134654-cl0gi4u524cv1ici
Tags: 1:1.0.9~rc3-1
* Package new upstream version
  - upstream ported the code to qt4.4 (Closes: #481974)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//  Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
 
2
//
 
3
//  This file is part of the VNC system.
 
4
//
 
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.
 
9
//
 
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.
 
14
//
 
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,
 
18
//  USA.
 
19
//
 
20
// TightVNC distribution homepage on the Web: http://www.tightvnc.com/
 
21
//
 
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.
 
25
 
 
26
// VNCHooks.cpp : Defines the implementation of the DLL.
 
27
//
 
28
 
 
29
#include "VNCHooks.h"
 
30
 
 
31
#include <stdlib.h>
 
32
#include <stdio.h>
 
33
#include <crtdbg.h>
 
34
 
 
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.
 
39
 
 
40
#ifdef _MSC_VER
 
41
 
 
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!
 
44
 
 
45
#pragma data_seg(".SharedData")
 
46
HWND hVeneto = NULL;
 
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
 
63
 
 
64
#pragma data_seg( )
 
65
 
 
66
#else
 
67
 
 
68
#include "SharedData.h"
 
69
 
 
70
#endif // _MSC_VER
 
71
 
 
72
#ifndef LLMHF_INJECTED
 
73
/* from $prefix/include/wine/windows/winuser.h */
 
74
#define LLMHF_INJECTED 0x000000001
 
75
#endif
 
76
 
 
77
/////////////////////////////////////////////////////////////////////////////
 
78
// Per-instance DLL variables
 
79
 
 
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
 
89
 
 
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?
 
93
 
 
94
BOOL appHookedOK = FALSE;                                                       // Did InitInstance succeed?
 
95
 
 
96
/////////////////////////////////////////////////////////////////////////////
 
97
// Registered messages & atoms to be used by VNCHooks.DLL
 
98
 
 
99
// Messages
 
100
const UINT VNC_DEFERRED_UPDATE = RegisterWindowMessage("VNCHooks.Deferred.UpdateMessage");
 
101
 
 
102
// Atoms
 
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;
 
107
 
 
108
/////////////////////////////////////////////////////////////////////////////
 
109
// The DLL functions
 
110
 
 
111
// Forward definition of hook procedures
 
112
 
 
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);
 
123
 
 
124
// Forward definition of setup and shutdown procedures
 
125
BOOL InitInstance();
 
126
BOOL ExitInstance();
 
127
 
 
128
// The DLL's main procedure
 
129
extern "C" BOOL APIENTRY DllMain (HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
 
130
{
 
131
        // Find out why we're being called
 
132
        switch (ul_reason_for_call)
 
133
        {
 
134
 
 
135
        case DLL_PROCESS_ATTACH:
 
136
#ifdef _MSC_VER
 
137
                _RPT0(_CRT_WARN, "vncHooks : Hook DLL loaded\n");
 
138
#endif
 
139
 
 
140
                // Save the instance handle
 
141
                hInstance = (HINSTANCE)hInst;
 
142
                // Call the initialisation function
 
143
                appHookedOK = InitInstance();
 
144
 
 
145
                // ALWAYS return TRUE to avoid breaking unhookable applications!!!
 
146
                return TRUE;
 
147
 
 
148
        case DLL_PROCESS_DETACH:
 
149
#ifdef _MSC_VER
 
150
                _RPT0(_CRT_WARN, "vncHooks : Hook DLL unloaded\n");
 
151
#endif
 
152
                
 
153
                // Call the exit function
 
154
                // If the app failed to hook OK, ExitInstance will still operate OK (hopefully...)
 
155
                ExitInstance();
 
156
 
 
157
                return TRUE;
 
158
 
 
159
        default:
 
160
                return TRUE;
 
161
        }
 
162
}
 
163
 
 
164
// Add the new hook
 
165
 
 
166
DllExport BOOL SetHook(HWND hWnd, UINT UpdateMsg, UINT CopyMsg, UINT MouseMsg)
 
167
{
 
168
 
 
169
        // Don't add the hook if the window ID is NULL
 
170
        if (hWnd == NULL)
 
171
                return FALSE;
 
172
        
 
173
        // Don't add a hook if there is already one added
 
174
        if (hVeneto != NULL)
 
175
                return FALSE;
 
176
 
 
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
 
184
                                        );
 
185
 
 
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
 
193
                                        );
 
194
 
 
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
 
201
                                        );
 
202
 
 
203
        // Check that it worked
 
204
        if ((hCallWndHook != NULL) && (hGetMsgHook != NULL) && (hDialogMsgHook != NULL))
 
205
        {
 
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
 
211
                
 
212
#ifdef _MSC_VER
 
213
                _RPT1(_CRT_WARN, "Window : %d\n", hWnd);
 
214
#endif
 
215
                
 
216
                return TRUE;
 
217
        }
 
218
        else
 
219
        {
 
220
                // Stop the keyboard hook
 
221
                SetKeyboardFilterHook(FALSE);
 
222
                SetMouseFilterHook(FALSE);
 
223
 
 
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);
 
231
                hCallWndHook = NULL;
 
232
                hGetMsgHook = NULL;
 
233
                hDialogMsgHook = NULL;
 
234
        }
 
235
 
 
236
        // The hook failed, so return an error code
 
237
        return FALSE;
 
238
 
 
239
}
 
240
 
 
241
// EnumWindows procedure to remove the extra property we added
 
242
 
 
243
BOOL CALLBACK
 
244
KillPropsProc(HWND hwnd, LPARAM lParam)
 
245
{
 
246
        // Remove our custom property...
 
247
        RemoveProp(hwnd, (LPCTSTR) MAKEWORD(VNC_WINDOWPOS_ATOM, 0));
 
248
        RemoveProp(hwnd, (LPCTSTR) MAKEWORD(VNC_POPUPSELN_ATOM, 0));
 
249
        return TRUE;
 
250
}
 
251
 
 
252
// Remove the hook from the system
 
253
 
 
254
DllExport BOOL UnSetHook(HWND hWnd)
 
255
{
 
256
 
 
257
        BOOL unHooked = TRUE;
 
258
        
 
259
        // Remove the extra property value from all local windows
 
260
        EnumWindows((WNDENUMPROC) &KillPropsProc, (LPARAM) NULL);
 
261
 
 
262
        // Stop the keyboard & mouse hooks
 
263
        unHooked = unHooked && SetKeyboardFilterHook(FALSE);
 
264
        unHooked = unHooked && SetMouseFilterHook(FALSE);
 
265
 
 
266
        // Is the window handle valid?
 
267
        if (hWnd == NULL)
 
268
                MessageBox(NULL, "Window pointer is null", "Message", MB_OK);
 
269
 
 
270
        // Is the correct application calling UnSetHook?
 
271
        if (hWnd != hVeneto)
 
272
                return FALSE;
 
273
 
 
274
        // Unhook the procs
 
275
        if (hCallWndHook != NULL)
 
276
        {
 
277
                unHooked = unHooked && UnhookWindowsHookEx(hCallWndHook);
 
278
                hCallWndHook = NULL;
 
279
        }
 
280
 
 
281
        if (hGetMsgHook != NULL)
 
282
        {
 
283
                unHooked = unHooked && UnhookWindowsHookEx(hGetMsgHook);
 
284
                hGetMsgHook = NULL;
 
285
        }
 
286
 
 
287
        if (hDialogMsgHook != NULL)
 
288
        {
 
289
                unHooked = unHooked && UnhookWindowsHookEx(hDialogMsgHook);
 
290
                hDialogMsgHook = NULL;
 
291
        }
 
292
 
 
293
        // If we managed to unhook then reset
 
294
        if (unHooked)
 
295
        {
 
296
                hVeneto = NULL;
 
297
                HookMaster = FALSE;
 
298
        }
 
299
 
 
300
        return unHooked;
 
301
 
 
302
}
 
303
 
 
304
// Routine to start and stop local keyboard message filtering
 
305
DllExport BOOL SetKeyboardFilterHook(BOOL activate)
 
306
{
 
307
        if (activate)
 
308
        {
 
309
#ifdef WH_KEYBOARD_LL
 
310
                if (hLLKeyboardHook == NULL)
 
311
                {
 
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
 
318
                                        );
 
319
                        if (hLLKeyboardHook == NULL)
 
320
                                return FALSE;
 
321
                }
 
322
                return TRUE;
 
323
#else
 
324
#pragma message("warning:Low-Level Keyboard hook code omitted.")
 
325
                return FALSE;
 
326
#endif
 
327
        } else {
 
328
                if (hLLKeyboardHook != NULL)
 
329
                {
 
330
                        // Stop the hook...
 
331
                        if (!UnhookWindowsHookEx(hLLKeyboardHook))
 
332
                                return FALSE;
 
333
                        hLLKeyboardHook = NULL;
 
334
                }
 
335
                return TRUE;
 
336
        }
 
337
}
 
338
 
 
339
DllExport BOOL SetKeyboardPriorityLLHook(HWND hwnd, BOOL activate, UINT LocalKbdMsg)
 
340
{
 
341
        LocalKeyboardMessage = LocalKbdMsg;
 
342
        if (activate)
 
343
        {
 
344
#ifdef WH_KEYBOARD_LL
 
345
                if (hLLKeyboardPrHook == NULL)
 
346
                {
 
347
                        // save the window handle
 
348
                        hKeyboardPriorityWindow = hwnd;
 
349
                
 
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
 
356
                                        );
 
357
                        if (hLLKeyboardPrHook == NULL)
 
358
                                return FALSE;
 
359
                }
 
360
                return TRUE;
 
361
#else
 
362
#pragma message("warning:Low-Level Keyboard hook code omitted.")
 
363
                return FALSE;
 
364
#endif
 
365
        } else {
 
366
                if (hLLKeyboardPrHook != NULL)
 
367
                {
 
368
                        // Stop the hook...
 
369
                        if (!UnhookWindowsHookEx(hLLKeyboardPrHook))
 
370
                                return FALSE;
 
371
                                
 
372
                        // reset the hook and window handle
 
373
                        hKeyboardPriorityWindow = NULL;
 
374
                        hLLKeyboardPrHook = NULL;
 
375
                }
 
376
                return TRUE;
 
377
        }
 
378
}
 
379
 
 
380
// Routine to start and stop local mouse message filtering
 
381
DllExport BOOL SetMouseFilterHook(BOOL activate)
 
382
{
 
383
        if (activate)
 
384
        {
 
385
#ifdef WH_MOUSE_LL
 
386
                if (hLLMouseHook == NULL)
 
387
                {
 
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
 
394
                                        );
 
395
                        if (hLLMouseHook == NULL)
 
396
                                return FALSE;
 
397
                }
 
398
                return TRUE;
 
399
#else
 
400
#pragma message("warning:Low-Level Mouse hook code omitted.")
 
401
                return FALSE;
 
402
#endif
 
403
        } else {
 
404
                if (hLLMouseHook != NULL)
 
405
                {
 
406
                        // Stop the hook...
 
407
                        if (!UnhookWindowsHookEx(hLLMouseHook))
 
408
                                return FALSE;
 
409
                        hLLMouseHook = NULL;
 
410
                }
 
411
                return TRUE;
 
412
        }
 
413
}
 
414
 
 
415
DllExport BOOL SetMousePriorityLLHook(HWND hwnd, BOOL activate, UINT LocalMouseMsg)
 
416
{
 
417
        LocalMouseMessage = LocalMouseMsg;
 
418
        if (activate)
 
419
        {
 
420
#ifdef WH_MOUSE_LL
 
421
                if (hLLMousePrHook == NULL)
 
422
                {
 
423
                        // save the window handle
 
424
                        hMousePriorityWindow = hwnd;
 
425
                
 
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
 
432
                                        );
 
433
                        if (hLLMousePrHook == NULL)
 
434
                                return FALSE;
 
435
                }
 
436
                return TRUE;
 
437
#else
 
438
#pragma message("warning:Low-Level Mouse hook code omitted.")
 
439
                return FALSE;
 
440
#endif
 
441
        } else {
 
442
                if (hLLMousePrHook != NULL)
 
443
                {
 
444
                        // Stop the hook...
 
445
                        if (!UnhookWindowsHookEx(hLLMousePrHook))
 
446
                                return FALSE;
 
447
                                
 
448
                        // reset the hook and window handle
 
449
                        hMousePriorityWindow = NULL;
 
450
                        hLLMousePrHook = NULL;
 
451
                }
 
452
                return TRUE;
 
453
        }
 
454
}
 
455
 
 
456
 
 
457
// Routine to start and stop local keyboard message filtering
 
458
DllExport BOOL SetKeyboardPriorityHook(HWND hwnd, BOOL activate, UINT LocalKbdMsg)
 
459
{
 
460
        LocalKeyboardMessage = LocalKbdMsg;
 
461
        if (activate)
 
462
        {
 
463
                if (hKeyboardHook == NULL)
 
464
                {
 
465
                        // save the window handle
 
466
                        hKeyboardPriorityWindow = hwnd;
 
467
 
 
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
 
474
                                        );
 
475
                        if (hKeyboardHook == NULL)
 
476
                                return FALSE;
 
477
                }
 
478
                return TRUE;
 
479
        } else {
 
480
                if (hKeyboardHook != NULL)
 
481
                {
 
482
                        // Stop the hook...
 
483
                        if (!UnhookWindowsHookEx(hKeyboardHook))
 
484
                                return FALSE;
 
485
                        
 
486
                        // reset the hook and window handle
 
487
                        hKeyboardPriorityWindow = NULL;
 
488
                        hKeyboardHook = NULL;
 
489
                }
 
490
                return TRUE;
 
491
        }
 
492
}
 
493
 
 
494
 
 
495
// Routine to start and stop local mouse message filtering
 
496
DllExport BOOL SetMousePriorityHook(HWND hwnd, BOOL activate, UINT LocalMouseMsg)
 
497
{
 
498
        LocalMouseMessage = LocalMouseMsg;
 
499
        if (activate)
 
500
        {
 
501
                if (hMouseHook == NULL)
 
502
                {
 
503
                        // save the window handle
 
504
                        hMousePriorityWindow = hwnd;
 
505
                
 
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
 
512
                                        );
 
513
                        if (hMouseHook == NULL)
 
514
                                return FALSE;
 
515
                }
 
516
                return TRUE;
 
517
        } else {
 
518
                if (hMouseHook != NULL)
 
519
                {
 
520
                        // Stop the hook...
 
521
                        if (!UnhookWindowsHookEx(hMouseHook))
 
522
                                return FALSE;
 
523
                                
 
524
                        // reset the hook and window handle
 
525
                        hMousePriorityWindow = NULL;
 
526
                        hMouseHook = NULL;
 
527
                }
 
528
                return TRUE;
 
529
        }
 
530
}
 
531
 
 
532
 
 
533
 
 
534
// Routine to get the window's client rectangle, in screen coordinates
 
535
inline BOOL GetAbsoluteClientRect(HWND hwnd, RECT *rect)
 
536
{
 
537
        POINT topleft;
 
538
        topleft.x = 0;
 
539
        topleft.y = 0;
 
540
 
 
541
        // Get the client rectangle size
 
542
        if (!GetClientRect(hwnd, rect))
 
543
                return FALSE;
 
544
 
 
545
        // Get the client rectangle position
 
546
        if (!ClientToScreen(hwnd, &topleft))
 
547
                return FALSE;
 
548
 
 
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;
 
554
 
 
555
        return TRUE;
 
556
}
 
557
 
 
558
// Routine to send a CopyRect message to WinVNC
 
559
inline void SendCopyWindowRect(HWND hWnd)
 
560
{
 
561
        WPARAM vwParam;
 
562
 
 
563
        // All we send back is the handle of the window to be moved
 
564
        vwParam = (LPARAM) hWnd;
 
565
 
 
566
        // Send the update to Veneto
 
567
        PostMessage(
 
568
                hVeneto,
 
569
                CopyRectMessage,
 
570
                vwParam,
 
571
                0
 
572
                );
 
573
}
 
574
 
 
575
// Routine to send an UpdateRect message to Veneto
 
576
inline void SendUpdateRect(SHORT x, SHORT y, SHORT x2, SHORT y2)
 
577
{
 
578
        WPARAM vwParam;
 
579
        LPARAM vlParam;
 
580
 
 
581
        vwParam = MAKELONG(x, y);
 
582
        vlParam = MAKELONG(x2, y2);
 
583
 
 
584
        // Send the update to Veneto
 
585
        PostMessage(
 
586
                hVeneto,
 
587
                UpdateRectMessage,
 
588
                vwParam,
 
589
                vlParam
 
590
                );
 
591
}
 
592
 
 
593
// Send a window's position to Veneto
 
594
 
 
595
inline void SendWindowRect(HWND hWnd)
 
596
{
 
597
        RECT wrect;
 
598
 
 
599
        // Get the rectangle position
 
600
        if (GetWindowRect(hWnd, &wrect) && IsWindowVisible(hWnd))
 
601
        {
 
602
                // Send the position
 
603
                SendUpdateRect(
 
604
                        (SHORT) wrect.left,
 
605
                        (SHORT) wrect.top,
 
606
                        (SHORT) wrect.right,
 
607
                        (SHORT) wrect.bottom
 
608
                        );
 
609
        }
 
610
}
 
611
 
 
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
 
614
// handled
 
615
 
 
616
inline void SendDeferredUpdateRect(HWND hWnd, SHORT x, SHORT y, SHORT x2, SHORT y2)
 
617
{
 
618
        WPARAM vwParam;
 
619
        LPARAM vlParam;
 
620
 
 
621
        vwParam = MAKELONG(x, y);
 
622
        vlParam = MAKELONG(x2, y2);
 
623
 
 
624
        if (prf_use_Deferral)
 
625
        {
 
626
                // Send the update back to the window
 
627
                PostMessage(
 
628
                        hWnd,
 
629
                        VNC_DEFERRED_UPDATE,
 
630
                        vwParam,
 
631
                        vlParam
 
632
                        );
 
633
        }
 
634
        else
 
635
        {
 
636
                // Send the update to WinRFB
 
637
                PostMessage(
 
638
                        hVeneto,
 
639
                        UpdateRectMessage,
 
640
                        vwParam,
 
641
                        vlParam
 
642
                        );
 
643
        }
 
644
}
 
645
 
 
646
inline void SendDeferredWindowRect(HWND hWnd)
 
647
{
 
648
        RECT wrect;
 
649
 
 
650
        // Get the rectangle position
 
651
        if (::GetWindowRect(hWnd, &wrect) && ::IsWindowVisible(hWnd))
 
652
        {
 
653
                // Send the position
 
654
                SendDeferredUpdateRect(
 
655
                        hWnd,
 
656
                        (SHORT) wrect.left,
 
657
                        (SHORT) wrect.top,
 
658
                        (SHORT) wrect.right,
 
659
                        (SHORT) wrect.bottom
 
660
                        );
 
661
        }
 
662
}
 
663
 
 
664
inline void SendDeferredBorderRect(HWND hWnd)
 
665
{
 
666
        RECT wrect;
 
667
        RECT crect;
 
668
 
 
669
        // Get the rectangle position
 
670
        if (GetWindowRect(hWnd, &wrect) && ::IsWindowVisible(hWnd))
 
671
        {
 
672
                // Get the client rectangle position
 
673
                if (GetAbsoluteClientRect(hWnd, &crect))
 
674
                {
 
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);
 
680
                }
 
681
        }
 
682
}
 
683
 
 
684
// Generic hook-handler
 
685
 
 
686
inline BOOL HookHandle(UINT MessageId, HWND hWnd, WPARAM wParam, LPARAM lParam)
 
687
{
 
688
        ////////////////////////////////////////////////////////////////
 
689
        // *** HANDLE DEFERRED UPDATES ***
 
690
 
 
691
        // Is this a deferred-update message?
 
692
        if (MessageId == VNC_DEFERRED_UPDATE)
 
693
        {
 
694
 
 
695
                // NOTE : NEVER use the SendDeferred- routines to send updates
 
696
                //              from here, or you'll get an infinite loop....!
 
697
 
 
698
                // NB : The format of DEFERRED_UPDATE matches that of UpdateRectMessage,
 
699
                //              so just send the exact same message data to WinRFB:
 
700
 
 
701
                PostMessage(
 
702
                        hVeneto,
 
703
                        UpdateRectMessage,
 
704
                        wParam,
 
705
                        lParam
 
706
                        );
 
707
 
 
708
                return FALSE;
 
709
        }
 
710
 
 
711
        // *** Could use WM_COPYDATA to send data to WinVNC
 
712
 
 
713
/*
 
714
        if (GetClassLong(hWnd, GCW_ATOM) == 32768)
 
715
        {
 
716
                _RPT4(_CRT_WARN, "DBG : popup menu message (hwnd=%d, msg=%d, l=%d, w=%d)\n",
 
717
                hWnd, MessageId, lParam, wParam);
 
718
        }
 
719
*/
 
720
 
 
721
        ////////////////////////////////////////////////////////////////
 
722
        // *** UPDATE-TRIGGERING MESSAGES ***
 
723
 
 
724
        // Do something dependent upon message type
 
725
        switch (MessageId)
 
726
        {
 
727
                
 
728
                ////////////////////////////////////////////////////////////////
 
729
                // Messages indicating only a border repaint.
 
730
        case WM_NCPAINT:
 
731
        case WM_NCACTIVATE:
 
732
                SendDeferredBorderRect(hWnd);
 
733
                break;
 
734
 
 
735
                ////////////////////////////////////////////////////////////////
 
736
                // Messages indicating a client area repaint
 
737
        case WM_CHAR:
 
738
        case WM_KEYUP:                                                  // Handle key-presses
 
739
                if (prf_use_KeyPress)
 
740
                        SendDeferredWindowRect(hWnd);
 
741
                break;
 
742
 
 
743
        case WM_LBUTTONUP:                                              // Handle LMB clicks
 
744
                if (prf_use_LButtonUp)
 
745
                        SendDeferredWindowRect(hWnd);
 
746
                break;
 
747
 
 
748
        case WM_MBUTTONUP:                                              // Handle MMB clicks
 
749
                if (prf_use_MButtonUp)
 
750
                        SendDeferredWindowRect(hWnd);
 
751
                break;
 
752
 
 
753
        case WM_RBUTTONUP:                                              // Handle RMB clicks
 
754
                if (prf_use_RButtonUp)
 
755
                        SendDeferredWindowRect(hWnd);
 
756
                break;
 
757
 
 
758
        case WM_TIMER:
 
759
                if (prf_use_Timer)
 
760
                        SendDeferredWindowRect(hWnd);
 
761
                break;
 
762
 
 
763
        case WM_HSCROLL:
 
764
        case WM_VSCROLL:
 
765
                if (((int) LOWORD(wParam) == SB_THUMBTRACK) || ((int) LOWORD(wParam) == SB_ENDSCROLL))
 
766
                        SendDeferredWindowRect(hWnd);
 
767
                break;
 
768
 
 
769
        case 485:  // HACK to handle popup menus
 
770
                {
 
771
                        // Get the old popup menu selection value
 
772
                        HANDLE prop = GetProp(hWnd, (LPCTSTR) MAKELONG(VNC_POPUPSELN_ATOM, 0));
 
773
                        if (prop != (HANDLE) wParam)
 
774
                        {
 
775
                                // It did, so update the menu & the selection value
 
776
                                SendDeferredWindowRect(hWnd);
 
777
                                SetProp(hWnd,
 
778
                                        (LPCTSTR) MAKELONG(VNC_POPUPSELN_ATOM, 0),
 
779
                                        (HANDLE) wParam);
 
780
                        }
 
781
                }
 
782
                break;
 
783
 
 
784
                ////////////////////////////////////////////////////////////////
 
785
                // Messages indicating a full window update
 
786
        case WM_SYSCOLORCHANGE:
 
787
        case WM_PALETTECHANGED:
 
788
        case WM_SETTEXT:
 
789
        case WM_ENABLE:
 
790
        case BM_SETCHECK:
 
791
        case BM_SETSTATE:
 
792
        case EM_SETSEL:
 
793
        //case WM_MENUSELECT:
 
794
                SendDeferredWindowRect(hWnd);
 
795
                break;
 
796
 
 
797
                ////////////////////////////////////////////////////////////////
 
798
                // Messages indicating that an area of the window needs updating
 
799
                // Uses GetUpdateRect to find out which
 
800
        case WM_PAINT:
 
801
                if (prf_use_GetUpdateRect)
 
802
                {
 
803
                        HRGN region;
 
804
                        region = CreateRectRgn(0, 0, 0, 0);
 
805
 
 
806
                        // Get the affected region
 
807
                        if (GetUpdateRgn(hWnd, region, FALSE) != ERROR)
 
808
                        {
 
809
                                int buffsize;
 
810
                                UINT x;
 
811
                                RGNDATA *buff;
 
812
                                POINT TopLeft;
 
813
 
 
814
                                // Get the top-left point of the client area
 
815
                                TopLeft.x = 0;
 
816
                                TopLeft.y = 0;
 
817
                                if (!ClientToScreen(hWnd, &TopLeft))
 
818
                                        break;
 
819
 
 
820
                                // Get the size of buffer required
 
821
                                buffsize = GetRegionData(region, 0, 0);
 
822
                                if (buffsize != 0)
 
823
                                {
 
824
                                        buff = (RGNDATA *) new BYTE [buffsize];
 
825
                                        if (buff == NULL)
 
826
                                                break;
 
827
 
 
828
                                        // Now get the region data
 
829
                                        if(GetRegionData(region, buffsize, buff))
 
830
                                        {
 
831
                                                for (x=0; x<(buff->rdh.nCount); x++)
 
832
                                                {
 
833
                                                        // Obtain the rectangles from the list
 
834
                                                        RECT *urect = (RECT *) (((BYTE *) buff) + sizeof(RGNDATAHEADER) + (x * sizeof(RECT)));
 
835
                                                        SendDeferredUpdateRect(
 
836
                                                                hWnd,
 
837
                                                                (SHORT) (TopLeft.x + urect->left),
 
838
                                                                (SHORT) (TopLeft.y + urect->top),
 
839
                                                                (SHORT) (TopLeft.x + urect->right),
 
840
                                                                (SHORT) (TopLeft.y + urect->bottom)
 
841
                                                                );
 
842
                                                }
 
843
                                        }
 
844
 
 
845
                                        delete [] buff;
 
846
                                }
 
847
                        }
 
848
 
 
849
                        // Now free the region
 
850
                        if (region != NULL)
 
851
                                DeleteObject(region);
 
852
                }
 
853
                else
 
854
                        SendDeferredWindowRect(hWnd);
 
855
                break;
 
856
 
 
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);
 
863
                break;
 
864
 
 
865
        case WM_WINDOWPOSCHANGED:
 
866
                if (IsWindowVisible(hWnd))
 
867
                        SendDeferredWindowRect(hWnd);
 
868
                break;
 
869
 
 
870
                ////////////////////////////////////////////////////////////////
 
871
                // WinRFB also wants to know about mouse movement
 
872
        case WM_NCMOUSEMOVE:
 
873
        case WM_MOUSEMOVE:
 
874
                // Inform WinRFB that the mouse has moved and pass it the current cursor handle
 
875
                PostMessage(
 
876
                        hVeneto,
 
877
                        MouseMoveMessage,
 
878
                        (ULONG) GetCursor(),
 
879
                        0
 
880
                );
 
881
                break;
 
882
 
 
883
                ////////////////////////////////////////////////////////////////
 
884
                // VNCHOOKS PROPERTIES HANDLING WINDOWS
 
885
        case WM_DESTROY:
 
886
                RemoveProp(hWnd, (LPCTSTR) MAKEWORD(VNC_WINDOWPOS_ATOM, 0));
 
887
                RemoveProp(hWnd, (LPCTSTR) MAKEWORD(VNC_POPUPSELN_ATOM, 0));
 
888
                break;
 
889
 
 
890
        }
 
891
 
 
892
        return TRUE;
 
893
}
 
894
 
 
895
// Hook procedure for CallWindow hook
 
896
 
 
897
LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam)
 
898
{
 
899
        // Do we have to handle this message?
 
900
        if (nCode == HC_ACTION)
 
901
        {
 
902
                // Process the hook if the Veneto window handle is valid
 
903
                if (hVeneto != NULL)
 
904
                {
 
905
                        CWPSTRUCT *cwpStruct = (CWPSTRUCT *) lParam;
 
906
                        HookHandle(cwpStruct->message, cwpStruct->hwnd, cwpStruct->wParam, cwpStruct->lParam);
 
907
                }
 
908
        }
 
909
 
 
910
        // Call the next handler in the chain
 
911
    return CallNextHookEx (hCallWndHook, nCode, wParam, lParam);
 
912
}
 
913
 
 
914
// Hook procedure for GetMessageProc hook
 
915
 
 
916
LRESULT CALLBACK GetMessageProc(int nCode, WPARAM wParam, LPARAM lParam)
 
917
{
 
918
        // Do we have to handle this message?
 
919
        if (nCode == HC_ACTION)
 
920
        {
 
921
                // Process the hook only if the Veneto window is valid
 
922
                if (hVeneto != NULL)
 
923
                {
 
924
                        MSG *msg = (MSG *) lParam;
 
925
 
 
926
                        // Only handle application messages if they're being removed:
 
927
                        if (wParam & PM_REMOVE)
 
928
                        {
 
929
                                // Handle the message
 
930
                                HookHandle(msg->message, msg->hwnd, msg->wParam, msg->lParam);
 
931
                        }
 
932
                }
 
933
        }
 
934
 
 
935
        // Call the next handler in the chain
 
936
    return CallNextHookEx (hGetMsgHook, nCode, wParam, lParam);
 
937
}
 
938
 
 
939
// Hook procedure for DialogMessageProc hook
 
940
 
 
941
LRESULT CALLBACK DialogMessageProc(int nCode, WPARAM wParam, LPARAM lParam)
 
942
{
 
943
        // Do we have to handle this message?
 
944
        if (nCode >= 0)
 
945
        {
 
946
                // Process the hook only if the Veneto window is valid
 
947
                if (hVeneto != NULL)
 
948
                {
 
949
                        MSG *msg = (MSG *) lParam;
 
950
 
 
951
                        // Handle the message
 
952
                        HookHandle(msg->message, msg->hwnd, msg->wParam, msg->lParam);
 
953
                }
 
954
        }
 
955
 
 
956
        // Call the next handler in the chain
 
957
    return CallNextHookEx (hGetMsgHook, nCode, wParam, lParam);
 
958
}
 
959
 
 
960
// Hook procedure for LowLevel Keyboard filtering
 
961
 
 
962
#ifdef WH_KEYBOARD_LL
 
963
LRESULT CALLBACK LowLevelKeyboardFilterProc(int nCode, WPARAM wParam, LPARAM lParam)
 
964
{
 
965
        // Are we expected to handle this callback?
 
966
        if (nCode == HC_ACTION)
 
967
        {
 
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!
 
973
                        return TRUE;
 
974
                }
 
975
        }
 
976
 
 
977
        // Otherwise, pass on the message
 
978
        return CallNextHookEx(hLLKeyboardHook, nCode, wParam, lParam);
 
979
}
 
980
 
 
981
LRESULT CALLBACK LowLevelKeyboardPriorityProc(int nCode, WPARAM wParam, LPARAM lParam)
 
982
{
 
983
        // Are we expected to handle this callback?
 
984
        // do we have a target window handle?
 
985
        if (nCode == HC_ACTION && hKeyboardPriorityWindow != NULL)
 
986
        {
 
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
 
993
                        PostMessage(
 
994
                                hKeyboardPriorityWindow,
 
995
                                LocalKeyboardMessage,
 
996
                                0,
 
997
                                0
 
998
                                );
 
999
                }
 
1000
        }
 
1001
 
 
1002
        // Otherwise, pass on the message
 
1003
        return CallNextHookEx(hLLKeyboardPrHook, nCode, wParam, lParam);
 
1004
}
 
1005
 
 
1006
#endif
 
1007
 
 
1008
// Hook procedure for LowLevel Mouse filtering
 
1009
 
 
1010
#ifdef WH_MOUSE_LL
 
1011
LRESULT CALLBACK LowLevelMouseFilterProc(int nCode, WPARAM wParam, LPARAM lParam)
 
1012
{
 
1013
        // Are we expected to handle this callback?
 
1014
        if (nCode == HC_ACTION)
 
1015
        {
 
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) {
 
1020
 
 
1021
                        return TRUE;
 
1022
                }
 
1023
        }
 
1024
 
 
1025
        // Otherwise, pass on the message
 
1026
        return CallNextHookEx(hLLMouseHook, nCode, wParam, lParam);
 
1027
}
 
1028
 
 
1029
LRESULT CALLBACK LowLevelMousePriorityProc(int nCode, WPARAM wParam, LPARAM lParam)
 
1030
{
 
1031
        // Are we expected to handle this callback?
 
1032
        // do we have a target window handle?
 
1033
        if (nCode == HC_ACTION && hMousePriorityWindow != NULL)
 
1034
        {
 
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
 
1041
                        PostMessage(
 
1042
                                hMousePriorityWindow,
 
1043
                                LocalMouseMessage,
 
1044
                                0,
 
1045
                                0
 
1046
                                );
 
1047
                }
 
1048
        }
 
1049
 
 
1050
        // Otherwise, pass on the message
 
1051
        return CallNextHookEx(hLLMousePrHook, nCode, wParam, lParam);
 
1052
}
 
1053
 
 
1054
#endif
 
1055
 
 
1056
LRESULT CALLBACK KeyboardPriorityProc(int nCode, WPARAM wParam, LPARAM lParam)
 
1057
{
 
1058
        // Are we expected to handle this callback?
 
1059
        // do we have a target window handle?
 
1060
        if (nCode == HC_ACTION && hKeyboardPriorityWindow != NULL)
 
1061
        {
 
1062
                        PostMessage(
 
1063
                        hKeyboardPriorityWindow,
 
1064
                        LocalKeyboardMessage,
 
1065
                        0,
 
1066
                        0
 
1067
                        );
 
1068
                
 
1069
        }
 
1070
 
 
1071
        return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
 
1072
}
 
1073
 
 
1074
 
 
1075
LRESULT CALLBACK MousePriorityProc(int nCode, WPARAM wParam, LPARAM lParam)
 
1076
{
 
1077
        // Are we expected to handle this callback?
 
1078
        // do we have a target window handle?
 
1079
        if (nCode == HC_ACTION && hMousePriorityWindow != NULL)
 
1080
        {
 
1081
                if ( (wParam == WM_LBUTTONDOWN) || (wParam == WM_RBUTTONDOWN) || (wParam == WM_MBUTTONDOWN) || (wParam == WM_MOUSEMOVE) )
 
1082
                        PostMessage(
 
1083
                        hMousePriorityWindow,
 
1084
                        LocalMouseMessage,
 
1085
                        0,
 
1086
                        0
 
1087
                        );
 
1088
        }
 
1089
 
 
1090
        return CallNextHookEx(hMouseHook, nCode, wParam, lParam);
 
1091
}
 
1092
 
 
1093
 
 
1094
char * NameFromPath(const char *path)
 
1095
{
 
1096
        int x;
 
1097
        int l = strlen(path);
 
1098
        char *temp = NULL;
 
1099
        
 
1100
        // Find the file part of a filename
 
1101
        for (x=l-1; x>0; x--)
 
1102
        {
 
1103
                if (path[x] == '\\')
 
1104
                {
 
1105
                        temp = strdup(&(path[x+1]));
 
1106
                        break;
 
1107
                }
 
1108
        }
 
1109
 
 
1110
        // If we didn't fine a \ then just return a copy of the original
 
1111
        if (temp == NULL)
 
1112
                temp = strdup(path);
 
1113
 
 
1114
        return temp;
 
1115
}
 
1116
 
 
1117
/////////////////////////////////////////////////////////////////////////////
 
1118
// Initialise / Exit routines.
 
1119
// These functions handle the update settings for any apps used with WinVNC.
 
1120
 
 
1121
static const TCHAR szSoftware[] = "Software";
 
1122
static const TCHAR szCompany[] = "ORL";
 
1123
static const TCHAR szProfile[] = "VNCHooks";
 
1124
 
 
1125
HKEY GetRegistryKey()
 
1126
{
 
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)
 
1132
        {
 
1133
                DWORD dw;
 
1134
                if (RegCreateKeyEx(hSoftKey, szCompany, 0, REG_NONE,
 
1135
                        REG_OPTION_NON_VOLATILE, KEY_WRITE|KEY_READ, NULL,
 
1136
                        &hCompanyKey, &dw) == ERROR_SUCCESS)
 
1137
                {
 
1138
                        RegCreateKeyEx(hCompanyKey, szProfile, 0, REG_NONE,
 
1139
                                REG_OPTION_NON_VOLATILE, KEY_WRITE|KEY_READ, NULL,
 
1140
                                &hAppKey, &dw);
 
1141
                }
 
1142
        }
 
1143
        if (hSoftKey != NULL)
 
1144
                RegCloseKey(hSoftKey);
 
1145
        if (hCompanyKey != NULL)
 
1146
                RegCloseKey(hCompanyKey);
 
1147
 
 
1148
        return hAppKey;
 
1149
}
 
1150
 
 
1151
HKEY GetModuleKey(const char *proc_name)
 
1152
{
 
1153
        HKEY hModule = NULL;
 
1154
 
 
1155
        // Work out the registry key to save this under
 
1156
        sModulePrefs = (char *) malloc(strlen(sPrefSegment) + strlen(proc_name) + 1);
 
1157
        if (sModulePrefs == NULL)
 
1158
                return FALSE;
 
1159
        sprintf(sModulePrefs, "%s%s", sPrefSegment, proc_name);
 
1160
 
 
1161
        // Check whether the library's entry exists!
 
1162
        HKEY hAppKey = GetRegistryKey();
 
1163
        if (hAppKey == NULL)
 
1164
                return NULL;
 
1165
 
 
1166
        // Attempt to open the section for this application
 
1167
        if (RegOpenKeyEx(hAppKey,
 
1168
                                        sModulePrefs,
 
1169
                                        0, KEY_WRITE|KEY_READ,
 
1170
                                        &hModule
 
1171
                                        ) != ERROR_SUCCESS)
 
1172
        {
 
1173
                // Cut off the app directory and just use the name
 
1174
                char *file_name = NameFromPath(proc_name);
 
1175
 
 
1176
                if (file_name == NULL)
 
1177
                {
 
1178
                        RegCloseKey(hAppKey);
 
1179
                        return NULL;
 
1180
                }
 
1181
 
 
1182
                // Adjust the moduleprefs name
 
1183
                sprintf(sModulePrefs, "%s%s", sPrefSegment, file_name);
 
1184
                free(file_name);
 
1185
 
 
1186
                // Now get the module key again
 
1187
                DWORD dw;
 
1188
                if (RegCreateKeyEx(hAppKey,
 
1189
                                        sModulePrefs,
 
1190
                                        0, REG_NONE, REG_OPTION_NON_VOLATILE,
 
1191
                                        KEY_WRITE|KEY_READ,
 
1192
                                        NULL,
 
1193
                                        &hModule,
 
1194
                                        &dw) != ERROR_SUCCESS)
 
1195
                {
 
1196
                        // Couldn't find/create the key - fail!
 
1197
                        RegCloseKey(hAppKey);
 
1198
                        return NULL;
 
1199
                }
 
1200
        }
 
1201
 
 
1202
        // Close the application registry key
 
1203
        RegCloseKey(hAppKey);
 
1204
 
 
1205
        return hModule;
 
1206
}
 
1207
 
 
1208
int GetProfileInt(LPTSTR key, int def)
 
1209
{
 
1210
        DWORD type;
 
1211
        DWORD value;
 
1212
        ULONG size = sizeof(value);
 
1213
 
 
1214
        if (RegQueryValueEx(
 
1215
                hModuleKey,
 
1216
                key,
 
1217
                NULL,
 
1218
                &type,
 
1219
                (unsigned char *)&value,
 
1220
                &size) == ERROR_SUCCESS)
 
1221
        {
 
1222
                // Is the value of the right type?
 
1223
                if (type != REG_DWORD)
 
1224
                {
 
1225
                        return def;
 
1226
                }
 
1227
                else
 
1228
                {
 
1229
                        return value;
 
1230
                }
 
1231
        }
 
1232
        else
 
1233
        {
 
1234
                return def;
 
1235
        }
 
1236
}
 
1237
 
 
1238
void WriteProfileInt(LPTSTR key, int value)
 
1239
{
 
1240
        RegSetValueEx(
 
1241
                hModuleKey,
 
1242
                key,
 
1243
                0,
 
1244
                REG_DWORD,
 
1245
                (unsigned char *)&value,
 
1246
                sizeof(value));
 
1247
}
 
1248
 
 
1249
BOOL InitInstance() 
 
1250
{
 
1251
        // Create the global atoms
 
1252
        VNC_WINDOWPOS_ATOM = GlobalAddAtom(VNC_WINDOWPOS_ATOMNAME);
 
1253
        if (VNC_WINDOWPOS_ATOM == (ATOM) NULL)
 
1254
                return FALSE;
 
1255
        VNC_POPUPSELN_ATOM = GlobalAddAtom(VNC_POPUPSELN_ATOMNAME);
 
1256
        if (VNC_POPUPSELN_ATOM == (ATOM) NULL)
 
1257
                return FALSE;
 
1258
 
 
1259
        // Get the module name
 
1260
        char proc_name[_MAX_PATH];
 
1261
        DWORD size;
 
1262
 
 
1263
        // Attempt to get the program/module name
 
1264
        if ((size = GetModuleFileName(
 
1265
                GetModuleHandle(NULL),
 
1266
                (char *) &proc_name,
 
1267
                _MAX_PATH
 
1268
                )) == 0)
 
1269
                return FALSE;
 
1270
 
 
1271
        // Get the key for the module
 
1272
        hModuleKey = GetModuleKey(proc_name);
 
1273
        if (hModuleKey == NULL)
 
1274
                return FALSE;
 
1275
 
 
1276
        // Read in the prefs
 
1277
        prf_use_GetUpdateRect = GetProfileInt(
 
1278
                "use_GetUpdateRect",
 
1279
                TRUE
 
1280
                );
 
1281
 
 
1282
        prf_use_Timer = GetProfileInt(
 
1283
                "use_Timer",
 
1284
                FALSE
 
1285
                );
 
1286
        prf_use_KeyPress = GetProfileInt(
 
1287
                "use_KeyPress",
 
1288
                TRUE
 
1289
                );
 
1290
        prf_use_LButtonUp = GetProfileInt(
 
1291
                "use_LButtonUp",
 
1292
                TRUE
 
1293
                );
 
1294
        prf_use_MButtonUp = GetProfileInt(
 
1295
                "use_MButtonUp",
 
1296
                TRUE
 
1297
                );
 
1298
        prf_use_RButtonUp = GetProfileInt(
 
1299
                "use_RButtonUp",
 
1300
                TRUE
 
1301
                );
 
1302
        prf_use_Deferral = GetProfileInt(
 
1303
                "use_Deferral",
 
1304
#ifdef HORIZONLIVE
 
1305
                FALSE   // we use full screen polling anyway
 
1306
#else
 
1307
                TRUE
 
1308
#endif
 
1309
                );
 
1310
 
 
1311
        return TRUE;
 
1312
}
 
1313
 
 
1314
BOOL ExitInstance() 
 
1315
{
 
1316
        // Free the created atoms
 
1317
        if (VNC_WINDOWPOS_ATOM != (ATOM) NULL)
 
1318
        {
 
1319
                GlobalDeleteAtom(VNC_WINDOWPOS_ATOM);
 
1320
                VNC_WINDOWPOS_ATOM = (ATOM) NULL;
 
1321
        }
 
1322
        if (VNC_POPUPSELN_ATOM != (ATOM) NULL)
 
1323
        {
 
1324
                GlobalDeleteAtom(VNC_POPUPSELN_ATOM);
 
1325
                VNC_POPUPSELN_ATOM = (ATOM) NULL;
 
1326
        }
 
1327
 
 
1328
        // Write the module settings to disk
 
1329
        if (sModulePrefs != NULL)
 
1330
        {
 
1331
                WriteProfileInt(
 
1332
                        "use_GetUpdateRect",
 
1333
                        prf_use_GetUpdateRect
 
1334
                        );
 
1335
 
 
1336
                WriteProfileInt(
 
1337
                        "use_Timer",
 
1338
                        prf_use_Timer
 
1339
                        );
 
1340
 
 
1341
                WriteProfileInt(
 
1342
                        "use_KeyPress",
 
1343
                        prf_use_KeyPress
 
1344
                        );
 
1345
 
 
1346
                WriteProfileInt(
 
1347
                        "use_LButtonUp",
 
1348
                        prf_use_LButtonUp
 
1349
                        );
 
1350
 
 
1351
                WriteProfileInt(
 
1352
                        "use_MButtonUp",
 
1353
                        prf_use_MButtonUp
 
1354
                        );
 
1355
 
 
1356
                WriteProfileInt(
 
1357
                        "use_RButtonUp",
 
1358
                        prf_use_RButtonUp
 
1359
                        );
 
1360
 
 
1361
                WriteProfileInt(
 
1362
                        "use_Deferral",
 
1363
                        prf_use_Deferral
 
1364
                        );
 
1365
 
 
1366
                free(sModulePrefs);
 
1367
                sModulePrefs = NULL;
 
1368
        }
 
1369
 
 
1370
        // Close the registry key for this module
 
1371
        if (hModuleKey != NULL)
 
1372
                RegCloseKey(hModuleKey);
 
1373
 
 
1374
        return TRUE;
 
1375
}