/[winpt]/trunk/Src/wptSafeEditCtrl.cpp
ViewVC logotype

Annotation of /trunk/Src/wptSafeEditCtrl.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 271 - (hide annotations)
Sun Nov 5 08:57:45 2006 UTC (18 years, 3 months ago) by twoaday
File size: 6317 byte(s)


1 twoaday 181 /* wptSafeEditCtrl.cpp - Safe edit control for passwords
2     * Copyright (C) 2006 Timo Schulz, g10 Code GmbH
3     *
4     * This file is part of WinPT.
5     *
6     * WinPT is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * WinPT is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with WinPT; if not, write to the Free Software Foundation,
18     * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19     */
20 twoaday 271 #ifdef HAVE_CONFIG_H
21     #include <config.h>
22     #endif
23 twoaday 181
24     #include <windows.h>
25     #include <stdio.h>
26     #include <richedit.h>
27     #include "resource.h"
28    
29     #include "wptTypes.h"
30     #include "wptW32API.h"
31    
32     /* New message to retrieve text. */
33     #define WM_SAFE_GETTEXT (WM_USER+11)
34    
35     /* Hook context. */
36     struct hook_ctx_s {
37     HHOOK keyb; /* handle for the keyboard. */
38     HHOOK cbt; /* handle for computer based training (CBT) */
39     };
40     typedef struct hook_ctx_s *hook_ctx_t;
41    
42     /* Subclassing context. */
43     struct subclass_ctx_s {
44     WNDPROC new_wnd_fnc; /* old window procedure. */
45     WNDPROC old_wnd_fnc; /* new window procedure. */
46     HWND wnd; /* window handle that is subclassed. */
47     void *opaque;
48     };
49     typedef struct subclass_ctx_s *subclass_ctx_t;
50    
51    
52     /* Dummy hook procedure to avoid channing. */
53     static LRESULT CALLBACK
54     dummy_hook_proc (int code, WPARAM wparam, LPARAM lparam)
55     {
56     return FALSE;
57     }
58    
59    
60     /* Set dummy hooks to prevent that the control is monitored
61     by some external hook functions. */
62     static hook_ctx_t
63     install_dummy_hooks (void)
64     {
65     hook_ctx_t hc;
66    
67     hc = (hook_ctx_t)calloc (1, sizeof *hc);
68     if (!hc)
69     return NULL;
70     hc->cbt = SetWindowsHookEx (WH_CBT, dummy_hook_proc,
71     GetModuleHandle (NULL), 0);
72     if (hc->cbt == NULL) {
73     free (hc);
74     return NULL;
75     }
76     hc->keyb = SetWindowsHookEx (WH_KEYBOARD, dummy_hook_proc,
77     GetModuleHandle (NULL), 0);
78     if (hc->keyb == NULL) {
79     free (hc);
80     return NULL;
81     }
82     return hc;
83     }
84    
85    
86     /* Remove dummy hooks and free memory. */
87     static void
88     deinstall_dummy_hooks (hook_ctx_t hc)
89     {
90     UnhookWindowsHookEx (hc->cbt);
91     UnhookWindowsHookEx (hc->keyb);
92     free (hc);
93     }
94    
95    
96     /* Filtered window procedure for the passphrase edit control. */
97     static LRESULT CALLBACK
98     safe_edit_dlg_proc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
99     {
100     static subclass_ctx_t ctx = NULL;
101    
102     /* XXX: filter all messages which were not send from
103     the current process. */
104    
105     if (ctx == NULL)
106     ctx = (subclass_ctx_t)GetWindowLong (hwnd, GWL_USERDATA);
107    
108     switch (msg) {
109     case WM_CUT:
110     case WM_COPY:
111     case WM_PASTE:
112     /* do not allow to copy or paste the inserted text. */
113     return TRUE;
114    
115     case WM_KEYUP:
116     case WM_KEYDOWN:
117     /* XXX: maybe in a future release, we might want to provide
118     our own buffer implementation. */
119    
120     /* ignore 'end' and 'home' to make text selection more difficult. */
121     if ((int)wparam == VK_END || (int)wparam == VK_HOME)
122     return TRUE;
123     break;
124    
125     case WM_GETTEXT:
126     /* disallow normal gettext message. */
127     return TRUE;
128    
129     case WM_SAFE_GETTEXT:
130     { /* transform WM_GETTEXT request into EM_GETLINE request. */
131     char *buffer = (char*)wparam;
132     int n;
133     buffer[0] = (char)lparam;
134     n = SendMessage (hwnd, EM_GETLINE, 0, wparam);
135     buffer[n] = 0;
136     }
137     break;
138    
139     case EM_GETLINE:
140     break;
141    
142     case WM_LBUTTONDBLCLK:
143     case WM_RBUTTONUP:
144     case WM_RBUTTONDOWN:
145     /* prevent that the popup menu is displayed. */
146     return TRUE;
147    
148     case EM_SETSEL:
149     case EM_SCROLLCARET:
150     case EM_FINDTEXT:
151     case EM_FINDTEXTEX:
152     case EM_GETSELTEXT:
153     case EM_PASTESPECIAL:
154     case EM_GETTEXTRANGE:
155     case EM_STREAMIN:
156     case EM_STREAMOUT:
157     /* disallow message which could be used to copy the text. */
158     return TRUE;
159     }
160    
161     return CallWindowProc (ctx->old_wnd_fnc, hwnd, msg, wparam, lparam);
162     }
163    
164    
165     /* Sublclass the window in the dialog @dlg with the id @ctrlid.
166     @new_wnd_fnc is the new window procedure. */
167     static int
168     subclass_window (HWND dlg, int ctrlid, WNDPROC new_wnd_fnc,
169     subclass_ctx_t *r_ctx)
170     {
171     subclass_ctx_t ctx;
172    
173     *r_ctx = NULL;
174     ctx = (subclass_ctx_t)calloc (1, sizeof *ctx);
175     if (!ctx)
176     return -1;
177     ctx->wnd = GetDlgItem (dlg, ctrlid);
178     ctx->new_wnd_fnc = new_wnd_fnc;
179     ctx->old_wnd_fnc = (WNDPROC)GetWindowLong (ctx->wnd, GWL_WNDPROC);
180     if (!ctx->old_wnd_fnc) {
181     free (ctx);
182     return -1;
183     }
184     SetLastError (0);
185     SetWindowLong (ctx->wnd, GWL_WNDPROC, (LONG)new_wnd_fnc);
186     if (GetLastError () != 0) {
187     free (ctx);
188     return -1;
189     }
190     SetLastError (0);
191     SetWindowLong (ctx->wnd, GWL_USERDATA, (LONG)ctx);
192     if (GetLastError () != 0) {
193     free (ctx);
194     return -1;
195     }
196     if (r_ctx)
197     *r_ctx = ctx;
198     return 0;
199     }
200    
201    
202     /* Restore the old window procedure for the subclassed control
203     and free the memory. */
204     static void
205     subclass_free_memory (HWND dlg, int ctrlid)
206     {
207     subclass_ctx_t ctx;
208     HWND wnd;
209    
210     wnd = GetDlgItem (dlg, ctrlid);
211     ctx = (subclass_ctx_t)GetWindowLong (wnd, GWL_USERDATA);
212     SetWindowLong (ctx->wnd, GWL_WNDPROC, (LONG)ctx->old_wnd_fnc);
213     if (ctx != NULL)
214     free (ctx);
215     }
216    
217    
218     /* Init subclassing to provide a safer edit control
219     for the dialog @dlg control @ctlid. */
220     void
221     safe_edit_control_init (HWND dlg, int ctlid)
222     {
223     subclass_ctx_t ctx;
224    
225     subclass_window (dlg, ctlid, safe_edit_dlg_proc, &ctx);
226     if (ctx != NULL)
227     ctx->opaque = install_dummy_hooks ();
228     }
229    
230    
231     /* Reset subclassing for the edit control @ctlid. */
232     void
233     safe_edit_control_free (HWND dlg, int ctlid)
234     {
235     subclass_ctx_t ctx;
236     HWND wnd;
237    
238     wnd = GetDlgItem (dlg, ctlid);
239     ctx = (subclass_ctx_t)GetWindowLong (wnd, GWL_USERDATA);
240     if (ctx != NULL && ctx->opaque != NULL)
241     deinstall_dummy_hooks ((hook_ctx_t)ctx->opaque);
242     subclass_free_memory (dlg, ctlid);
243     }
244    
245    
246     UINT
247     SafeGetDlgItemText (HWND dlg, int id, char *buf, int buflen)
248     {
249 twoaday 193 memset (buf, 0, buflen);
250 twoaday 181 SendDlgItemMessage (dlg, id, WM_SAFE_GETTEXT, (WPARAM)buf, (LPARAM)buflen);
251     return strlen (buf);
252     }
253 twoaday 229
254    

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26