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

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


1 twoaday 121 /* 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 twoaday 271 #include "wptTypes.h"
34 twoaday 121
35 twoaday 271 /* Default buffer size. */
36     #define BUFSIZE 192
37    
38 twoaday 121 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 twoaday 226 if (strstr (data, "BEGIN PGP PRIVATE KEY BLOCK") ||
98     strstr (data, "BEGIN PGP SECRET KEY BLOCK"))
99 twoaday 121 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 twoaday 271 if (OpenClipboard (NULL) == FALSE)
121 twoaday 121 return gpg_error (GPG_ERR_INTERNAL);
122 twoaday 271 clipmem = GetClipboardData (CF_TEXT);
123     if (!clipmem) {
124 twoaday 121 *r_val = 0;
125     goto leave;
126     }
127 twoaday 271 clipdata = (char *) GlobalLock (clipmem);
128 twoaday 121 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 twoaday 271 /* Return the OpenPGP data format of the clipboard in @r_type.
145     Return 0 on success. */
146 twoaday 121 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 twoaday 271 gpgme_error_t err;
271 twoaday 121 gpgme_data_t mdh;
272 twoaday 271 const char *s;
273     char line[BUFSIZE+32];
274 twoaday 121 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 twoaday 271 /* Pattern we search for. */
284     s = "Version: GnuPG";
285 twoaday 121 gpgme_data_rewind (*r_dh);
286 twoaday 271 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 twoaday 121 }
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 twoaday 271 wipememory (clip_text, n);
328 twoaday 121 gpgme_free (clip_text);
329     }
330     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26