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

Contents of /trunk/Src/wptClipboard.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: 7950 byte(s)


1 /* wptClipboard.cpp
2 * Copyright (C) 2001, 2002, 2003, 2005 Timo Schulz
3 * Copyright (C) 2005 g10 Code GmbH
4 *
5 * This file is part of WinPT.
6 *
7 * WinPT is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * WinPT is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with WinPT; if not, write to the Free Software Foundation,
19 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20 */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <windows.h>
27 #include <gpgme.h>
28
29 #include "wptW32API.h"
30 #include "wptCrypto.h"
31 #include "wptVersion.h"
32 #include "wptGPG.h"
33 #include "wptTypes.h"
34
35 /* Default buffer size. */
36 #define BUFSIZE 192
37
38 gpgme_error_t gpg_data_wrap_lines (gpgme_data_t *r_dh, size_t wraplen);
39
40 /* XXX: define clipboard errors. */
41
42 /* Check if the clipboard contains text. @r_val contains
43 one text data is available.
44 Return value: 0 on success. */
45 gpgme_error_t
46 gpg_clip_istext_avail (int *r_val)
47 {
48 HANDLE clipmem;
49 char *clipdata;
50
51 if (!r_val)
52 return gpg_error (GPG_ERR_INV_ARG);
53 if (OpenClipboard (NULL) == FALSE)
54 return gpg_error (GPG_ERR_NO_DATA);
55
56 *r_val = 0;
57 clipmem = GetClipboardData (CF_TEXT);
58 if (!clipmem)
59 goto leave;
60
61 clipdata = (char *) GlobalLock (clipmem);
62 if (!clipdata)
63 goto leave;
64 if (strlen (clipdata) > 0)
65 *r_val = 1;
66 GlobalUnlock (clipmem);
67
68 leave:
69 CloseClipboard ();
70 return 0;
71 }
72
73
74 /* Figure out what kind of PGP data is stored in @data.
75 @r_type contains the ORed types on success.
76 Return value: 0 on success. */
77 gpgme_error_t
78 gpg_clip_parse_pgpid (const char *data, int *r_type)
79 {
80 int type;
81
82 if (!data)
83 return gpg_error (GPG_ERR_INV_ARG);
84 if (strlen (data) < 19) {
85 *r_type = 0;
86 return 0;
87 }
88 type = 0;
89 if (strstr( data, "BEGIN PGP MESSAGE") )
90 type |= PGP_MESSAGE;
91 if (strstr (data, "BEGIN PGP SIGNED MESSAGE"))
92 type |= PGP_CLEARSIG;
93 if (strstr (data, "BEGIN PGP SIGNATURE"))
94 type |= PGP_SIG;
95 if (strstr (data, "BEGIN PGP PUBLIC KEY BLOCK"))
96 type |= PGP_PUBKEY;
97 if (strstr (data, "BEGIN PGP PRIVATE KEY BLOCK") ||
98 strstr (data, "BEGIN PGP SECRET KEY BLOCK"))
99 type |= PGP_SECKEY;
100 if (strstr (data, "- -----BEGIN"))
101 type |= PGP_DASH_ESCAPED;
102 *r_type = type;
103 return 0;
104 }
105
106
107 /* Check if the clipboard is already OpenPGP protected.
108 @r_type optional returns the type and @r_val contains
109 1 for yes.
110 Return value: 0 on success. */
111 gpgme_error_t
112 gpg_clip_is_secured (int *r_type, int *r_val)
113 {
114 int rc = 0;
115 HANDLE clipmem;
116 char *clipdata;
117
118 if (!r_val)
119 return gpg_error (GPG_ERR_INV_ARG);
120 if (OpenClipboard (NULL) == FALSE)
121 return gpg_error (GPG_ERR_INTERNAL);
122 clipmem = GetClipboardData (CF_TEXT);
123 if (!clipmem) {
124 *r_val = 0;
125 goto leave;
126 }
127 clipdata = (char *) GlobalLock (clipmem);
128 if (!clipdata) {
129 *r_val = 0;
130 goto leave;
131 }
132 if (strstr (clipdata, "-----BEGIN PGP")
133 && strstr (clipdata, "-----END PGP"))
134 *r_val = 1;
135 GlobalUnlock (clipmem);
136 gpg_clip_parse_pgpid (clipdata, r_type);
137
138 leave:
139 CloseClipboard ();
140 return rc;
141 }
142
143
144 /* Return the OpenPGP data format of the clipboard in @r_type.
145 Return 0 on success. */
146 gpgme_error_t
147 gpg_clip_get_pgptype (int *r_type)
148 {
149 gpgme_error_t rc = 0;
150 HANDLE clipmem;
151 char *clipdata;
152
153 if (OpenClipboard (NULL) == FALSE)
154 return gpg_error (GPG_ERR_INTERNAL);
155 clipmem = GetClipboardData (CF_TEXT);
156 if (!clipmem) {
157 rc = gpg_error (GPG_ERR_NO_DATA);
158 goto leave;
159 }
160 clipdata = (char *)GlobalLock( clipmem );
161 if (!clipdata) {
162 rc = gpg_error (GPG_ERR_NO_DATA);
163 goto leave;
164 }
165 gpg_clip_parse_pgpid (clipdata, r_type);
166 GlobalUnlock (clipmem);
167
168 leave:
169 CloseClipboard ();
170 return rc;
171 }
172
173
174 /* Retrieve the thext of the clipboard.
175 Return value: the text as a string, NULL otherwise. */
176 static char*
177 get_w32_clip_text (void)
178 {
179 char *private_clip = NULL;
180 char *clip = NULL;
181 size_t size;
182 HANDLE cb;
183
184 if (!OpenClipboard (NULL))
185 return NULL;
186 cb = GetClipboardData (CF_TEXT);
187 if (!cb)
188 goto leave;
189 private_clip = (char *)GlobalLock (cb);
190 if (!private_clip)
191 goto leave;
192 size = strlen (private_clip);
193 clip = (char*)malloc (size + 1);
194 if (!clip) {
195 GlobalUnlock (cb);
196 goto leave;
197 }
198 memcpy (clip, private_clip, size);
199 clip[size] = '\0';
200 GlobalUnlock(cb);
201
202 leave:
203 CloseClipboard ();
204 return clip;
205 }
206
207
208 /* Set the new clipboard data to @data. */
209 static void
210 set_w32_clip_text (const char *data, int size)
211 {
212 HANDLE cb;
213 char *private_data;
214
215 if (!OpenClipboard(NULL))
216 return;
217 EmptyClipboard ();
218 cb = GlobalAlloc (GHND, size+1);
219 if (!cb)
220 goto leave;
221 private_data = (char*)GlobalLock (cb);
222 if (!private_data)
223 goto leave;
224 memcpy (private_data, data, size);
225 private_data[size] = '\0';
226 SetClipboardData (CF_TEXT, cb);
227 GlobalUnlock (cb);
228
229 leave:
230 CloseClipboard ();
231 GlobalFree (cb);
232 }
233
234
235 /* Retrieve the clipboard data and create a new gpgme
236 data object @r_dh and return it. If @wraplen is > 0
237 wrap lines of the buffer.
238 Return value: 0 on success. */
239 gpgme_error_t
240 gpg_data_new_from_clipboard (gpgme_data_t *r_dh, int wraplen)
241 {
242 gpgme_error_t err = 0;
243 gpgme_data_t dh;
244 char *clip_text = NULL;
245
246 if (!r_dh)
247 return gpg_error (GPG_ERR_INV_ARG);
248 *r_dh = NULL;
249 clip_text = get_w32_clip_text ();
250 if (!clip_text)
251 return gpg_error (GPG_ERR_NO_DATA);
252 err = gpgme_data_new_from_mem (&dh, clip_text, strlen (clip_text), 1);
253 if (clip_text)
254 free (clip_text);
255 if (wraplen > 0)
256 gpg_data_wrap_lines (&dh, wraplen);
257
258 *r_dh = dh;
259 return err;
260 }
261
262
263 /* Search for the armor header 'Version:' in @r_dh and
264 add the WinPT version. On success @r_dh is replaced
265 with the modified data.
266 Return value: 0 on success. */
267 static gpgme_error_t
268 gpg_data_change_version (gpgme_data_t *r_dh)
269 {
270 gpgme_error_t err;
271 gpgme_data_t mdh;
272 const char *s;
273 char line[BUFSIZE+32];
274 int n;
275
276 if (!r_dh)
277 return gpg_error (GPG_ERR_INV_ARG);
278
279 err = gpgme_data_new (&mdh);
280 if (err)
281 return err;
282
283 /* Pattern we search for. */
284 s = "Version: GnuPG";
285 gpgme_data_rewind (*r_dh);
286 while ((n=gpg_data_readline (*r_dh, line, BUFSIZE-1)) > 0) {
287 if (strlen (line) > strlen (s) &&
288 !strncmp (line, s, strlen (s)) &&
289 !stristr (line, "WinPT "PGM_VERSION)) {
290 /* Do not assume a \r\n sequence. */
291 if (strstr (line, "\r\n"))
292 line[strlen (line) - 2] = '\0';
293 if (strstr (line, "\n"))
294 line[strlen (line)-1] = '\0';
295 strcat (line, " - WinPT "PGM_VERSION"\r\n");
296 }
297 gpgme_data_write (mdh, line, strlen (line));
298 }
299
300 gpgme_data_write (mdh, "", 1);
301 gpgme_data_rewind (mdh);
302 gpgme_data_release (*r_dh);
303 *r_dh = mdh;
304 return err;
305 }
306
307 /* Release a gpgme data object @dh and write the contents of
308 the object to the clipboard. If @chg_ver is set, modify the
309 Version: header and add WinPT information. */
310 void
311 gpg_data_release_and_set_clipboard (gpgme_data_t dh, int chg_ver)
312 {
313 gpgme_data_t in;
314 char *clip_text;
315 size_t n;
316
317 if (!dh)
318 return;
319
320 in = dh;
321 if (chg_ver)
322 gpg_data_change_version (&in);
323
324 clip_text = gpgme_data_release_and_get_mem (in, &n);
325 if (clip_text && *clip_text) {
326 set_w32_clip_text (clip_text, n);
327 wipememory (clip_text, n);
328 gpgme_free (clip_text);
329 }
330 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26