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

Contents of /trunk/Src/wptSafeEditCtrl.cpp

Parent Directory Parent Directory | Revision Log Revision Log


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


1 /* 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 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
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 memset (buf, 0, buflen);
250 SendDlgItemMessage (dlg, id, WM_SAFE_GETTEXT, (WPARAM)buf, (LPARAM)buflen);
251 return strlen (buf);
252 }
253
254

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26