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

Contents of /trunk/Src/wptKeyManagerDlg.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 130 - (show annotations)
Fri Dec 30 14:06:39 2005 UTC (19 years, 2 months ago) by twoaday
File size: 59693 byte(s)
2005-12-29  Timo Schulz  <ts@g10code.com>
  
        * wptKeygenDlg.cpp (keygen_dlg_proc): Request passphrase dynamically.
        (gpg_genkey_params): Simplified.
        * wptPreferencesDlg.cpp (prefs_dlg_proc): Fix problem with mutal
        exclusion of the dialog items.
        * wptAboutDlgs.cpp (about_winpt_dlg_proc): Allow to use ESC to
        quit the dialog.
        * wptKeyManagerDlg.cpp (keymanager_dlg_proc): Likewise.
        * wptMDSumDlg.cpp (mdsum_dlg_proc): Handle WM_SYSCOMMAND.
        (id2algo): New.

Prepare 0.11.4 release.


1 /* wptKeyManagerDlg.cpp - WinPT Key Manager
2 * Copyright (C) 2000-2005 Timo Schulz
3 * Copyright (C) 2004 Andreas Jobs
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 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24
25 #include <windows.h>
26 #include <commctrl.h>
27
28 #include "resource.h"
29 #include "wptTypes.h"
30 #include "wptGPG.h"
31 #include "wptCommonCtl.h"
32 #include "wptContext.h" /* for passphrase_s */
33 #include "wptDlgs.h"
34 #include "wptW32API.h"
35 #include "wptVersion.h"
36 #include "wptKeylist.h"
37 #include "wptNLS.h"
38 #include "wptErrors.h"
39 #include "wptHotkey.h"
40 #include "wptKeyManager.h"
41 #include "wptKeyserver.h"
42 #include "wptKeyEdit.h"
43 #include "wptRegistry.h"
44 #include "wptUTF8.h"
45
46 /* Name and ID of the separator window. */
47 #define KM_SEPARATOR_ID 10000
48 #define WINDOWCLASS_SEPARATOR_CHILD "WINPT_SEP_CHILD"
49
50 /* Virtual key codes. */
51 #ifndef VK_F
52 #define VK_F 70
53 #endif
54 #ifndef VK_A
55 #define VK_A 65
56 #endif
57 #ifndef VK_C
58 #define VK_C 67
59 #endif
60 #ifndef VK_P
61 #define VK_P 80
62 #endif
63
64 static subclass_s keylist_proc;
65
66 HIMAGELIST glob_imagelist;
67
68 struct km_info_s {
69 /* Window positions */
70 int pos_x, pos_y;
71 int ypos_sep;
72 int ypercent_sep;
73
74 HWND hwnd_sep;
75 HWND toolbar;
76 HWND statbar;
77
78 listview_ctrl_t lv;
79 int lv_idx;
80 int keylist_sortby;
81 };
82
83 /* Toolbar button structure. */
84 struct mybuttons {
85 long icon;
86 long command;
87 char *text;
88 };
89
90 struct mybuttons myb[] = {
91 {IMI_KEY_DELETE, ID_KEYMISC_DELETE, "Delete"},
92 {IMI_KEY_PROPS, ID_KEYMISC_PROPS, "Properties"},
93 {IMI_KEY_SIGN, ID_KEYMISC_SIGN, "Sign"},
94 {IMI_KEY_IMPORT, ID_KEYMISC_IMPORT, "Import"},
95 {IMI_KEY_EXPORT, ID_KEYMISC_EXPORT, "Export"},
96 };
97
98
99 /* Subclass the keylist listview control to allow extended commands. */
100 static BOOL CALLBACK
101 keylist_subclass_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
102 {
103 struct listview_ctrl_s lv;
104
105 switch (msg) {
106 case WM_LBUTTONDBLCLK:
107 send_cmd_id (keylist_proc.dlg, ID_KEYMISC_PROPS);
108 break;
109
110 case WM_KEYUP:
111 int virt_key = (int)wparam;
112 switch (virt_key) {
113 case VK_SPACE:
114 send_cmd_id (keylist_proc.dlg, ID_KEYMISC_PROPS);
115 break;
116
117 case VK_DELETE:
118 send_cmd_id (keylist_proc.dlg, ID_KEYMISC_DELETE);
119 break;
120
121 case VK_INSERT:
122 send_cmd_id (keylist_proc.dlg, ID_KEYMISC_PASTE);
123 break;
124
125 case VK_A:
126 if (GetAsyncKeyState (VK_CONTROL)) {
127 lv.ctrl = GetDlgItem (keylist_proc.dlg, IDC_KEYMISC_KEYLIST);
128 listview_select_all (&lv);
129 }
130 break;
131
132 case VK_C:
133 if (GetAsyncKeyState (VK_CONTROL)) {
134 lv.ctrl = GetDlgItem (keylist_proc.dlg, IDC_KEYMISC_KEYLIST);
135 km_clip_export (keylist_proc.dlg, &lv);
136 }
137 break;
138
139 case VK_P:
140 if (GetAsyncKeyState (VK_CONTROL))
141 km_clip_import (keylist_proc.dlg);
142 break;
143
144 case VK_F:
145 if (GetAsyncKeyState (VK_CONTROL)) {
146 lv.ctrl = GetDlgItem (keylist_proc.dlg, IDC_KEYMISC_KEYLIST);
147 km_find_key (dlg, &lv);
148 }
149 break;
150 }
151 break;
152 }
153
154 return CallWindowProc (keylist_proc.old, dlg, msg, wparam, lparam);
155 }
156
157
158 static HWND
159 load_toolbar (HWND dlg, struct km_info_s *kmi)
160 {
161 HWND tbwnd;
162 TBSAVEPARAMS tbsp;
163 TBBUTTON tb_buttons[] = {
164 /*{imagelist_getindex(IMI_EXIT), ID_KEYMISC_QUIT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0L, 0},*/
165 {imagelist_getindex(IMI_KEY_DELETE), ID_KEYMISC_DELETE, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, 0},
166 {imagelist_getindex(IMI_KEY_PROPS), ID_KEYMISC_PROPS, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, 0},
167 {imagelist_getindex(IMI_KEY_SIGN), ID_KEYMISC_SIGN, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, 0},
168 {0, 0, 0, TBSTYLE_SEP, {0}, 0L, 0},
169 {imagelist_getindex(IMI_KEY_IMPORT), ID_KEYMISC_IMPORT, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, 0},
170 {imagelist_getindex(IMI_KEY_EXPORT), ID_KEYMISC_EXPORT, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, 0},
171 };
172
173 tbwnd = CreateWindowEx (0, TOOLBARCLASSNAME, NULL,
174 WS_CHILD|TBSTYLE_TOOLTIPS|TBSTYLE_FLAT|CCS_ADJUSTABLE,
175 0, 0, 0, 0, dlg, (HMENU)IDR_WINPT_KMTB, glob_hinst, NULL);
176 if (tbwnd) {
177 SendMessage (tbwnd, TB_BUTTONSTRUCTSIZE, (WPARAM) sizeof(TBBUTTON), 0);
178 SendMessage (tbwnd, TB_SETIMAGELIST, 0, (LPARAM)glob_imagelist);
179 SendMessage (tbwnd, TB_AUTOSIZE, 0, 0);
180 ShowWindow (tbwnd, SW_SHOW);
181
182 /* Restore toolbar */
183 tbsp.hkr = HKEY_CURRENT_USER;
184 tbsp.pszSubKey = "Software\\WinPT";
185 tbsp.pszValueName = "KM_toolbar";
186 if (SendMessage(tbwnd, TB_SAVERESTORE, FALSE, (LPARAM)&tbsp ) == 0)
187 SendMessage (tbwnd, TB_ADDBUTTONS, sizeof(tb_buttons) / sizeof(tb_buttons[0]),
188 (LONG)&tb_buttons[0]);
189 }
190 return tbwnd;
191 }
192
193
194 /* Restore the width of the columns from the registry.
195 If no bitstring was found, the default size is used. */
196 int
197 restore_column_info (listview_ctrl_t hd)
198 {
199 WORD *buf;
200 HKEY root;
201 DWORD type;
202 DWORD size = hd->cols*sizeof (WORD), i;
203 LONG ec;
204
205 ec = RegOpenKeyEx (HKEY_CURRENT_USER, "Software\\WinPT", 0,
206 KEY_ALL_ACCESS, &root);
207 if (ec != ERROR_SUCCESS)
208 return -1;
209
210 buf = new WORD[size/2];
211 if (!buf)
212 BUG (NULL);
213 ec = RegQueryValueEx (root, "KMColumnSize", NULL, &type,
214 (BYTE*)buf, &size);
215 RegCloseKey (root);
216 if (ec != ERROR_SUCCESS) {
217 free_if_alloc (buf);
218 return -1;
219 }
220
221 /* check for garbled values. */
222 for (i=0; i < size/2; i++) {
223 if (buf[i] == 0 || buf[i] > 512) {
224 free_if_alloc (buf);
225 return -1;
226 }
227 }
228 for (i=0; i < size/2; i++) {
229 LVCOLUMN lvc;
230
231 memset (&lvc, 0, sizeof (lvc));
232 lvc.mask = LVCF_WIDTH;
233 lvc.cx = buf[i];
234 ListView_SetColumn (hd->ctrl, i, &lvc);
235 }
236 free_if_alloc (buf);
237 return 0;
238 }
239
240
241 /* Save the current column width to the registry. */
242 int
243 save_column_info (listview_ctrl_t hd)
244 {
245 WORD *buf;
246 HKEY root;
247 LONG ec;
248 int i;
249
250 buf = new WORD[hd->cols];
251 if (!buf)
252 BUG (NULL);
253 for (i=0; i < hd->cols; i++) {
254 LVCOLUMN lvc;
255
256 memset (&lvc, 0, sizeof (lvc));
257 lvc.mask = LVCF_WIDTH;
258 ListView_GetColumn (hd->ctrl, i, &lvc);
259 buf[i] = lvc.cx;
260 }
261
262 ec = RegOpenKeyEx (HKEY_CURRENT_USER, "Software\\WinPT", 0,
263 KEY_ALL_ACCESS, &root);
264 if (ec != ERROR_SUCCESS) {
265 free_if_alloc (buf);
266 return -1;
267 }
268
269 ec = RegSetValueEx (root, "KMColumnSize", 0, REG_BINARY,
270 (const BYTE*)buf, 2*hd->cols);
271 RegCloseKey (root);
272 free_if_alloc (buf);
273 return ec == ERROR_SUCCESS? 0 : -1;
274 }
275
276
277 /* Center window @dlg. */
278 static void
279 do_center_window (HWND dlg, struct km_info_s *kmi)
280 {
281 RECT rect;
282 char *p;
283 int pos_x = 0;
284 int pos_y = 0;
285
286 /* Find bottom of keylist */
287 GetWindowRect (GetDlgItem(dlg, IDC_KEYMISC_KEYLIST), &rect);
288 MapWindowPoints (NULL, dlg, (POINT*)&rect, 2);
289
290 kmi->ypos_sep = rect.bottom;
291
292 p = get_reg_entry (HKEY_CURRENT_USER, "Software\\WinPT", "KM_Pos_X");
293 if (p && !strcmp (p, " ")) {
294 free_if_alloc (p);
295 center_window (dlg, NULL);
296 return;
297 }
298 else if (p)
299 pos_x = atol (p);
300
301 p = get_reg_entry (HKEY_CURRENT_USER, "Software\\WinPT", "KM_Pos_Y");
302 if (p && !strcmp (p, " ")) {
303 free_if_alloc (p);
304 center_window (dlg, NULL);
305 return;
306 }
307 else if (p)
308 pos_y = atol (p);
309
310 if (!pos_y && !pos_x) {
311 center_window (dlg, NULL);
312 return;
313 }
314
315 if (pos_x < 0 || pos_y < 0)
316 pos_x = pos_y = 0;
317 if (pos_x > GetSystemMetrics (SM_CXSCREEN)
318 || pos_y > GetSystemMetrics (SM_CYSCREEN)) {
319 pos_x = pos_y = 0;
320 }
321 GetClientRect (dlg, &rect);
322 MoveWindow (dlg, pos_x, pos_y, rect.right, rect.bottom, TRUE);
323 }
324
325
326 /* Resize the key manager window with the information from @kmi. */
327 static void
328 do_resize_window (HWND dlg, struct km_info_s *kmi)
329 {
330 HWND h;
331 RECT rclient, rect;
332 BOOL bRepaint = FALSE;
333
334 /* Get rect of client area and make life easier */
335 GetClientRect (dlg, &rclient);
336
337 /* Move toolbar to the top of the window */
338 if (kmi->toolbar) {
339 GetWindowRect (kmi->toolbar, &rect);
340 ScreenToClient (dlg, (POINT*)&rect);
341 ScreenToClient (dlg, (POINT*)&(rect.right));
342
343 rclient.top += rect.bottom - rect.top;
344 MoveWindow (kmi->toolbar, 0, 0, rclient.right - rclient.left,
345 rect.bottom - rect.top, bRepaint);
346 }
347
348 /* Move statusbar to the bottom of the window */
349 if (kmi->statbar) {
350 GetWindowRect (kmi->statbar, &rect);
351 ScreenToClient (dlg, (POINT*)&rect);
352 ScreenToClient (dlg, (POINT*)&(rect.right));
353
354 rclient.bottom -= rect.bottom - rect.top;
355 MoveWindow (kmi->statbar, 0, rclient.bottom,
356 rclient.right - rclient.left,
357 rect.bottom - rect.top, bRepaint);
358 }
359
360 /* Obtain separator information and move it to the desired posistion */
361 if (kmi->ypercent_sep)
362 kmi->ypos_sep = (rclient.bottom - rclient.top) * kmi->ypercent_sep / 100;
363 else
364 kmi->ypercent_sep = kmi->ypos_sep * 100 / (rclient.bottom - rclient.top);
365
366 /* Don't move away */
367 if (kmi->ypos_sep+5 > rclient.bottom)
368 kmi->ypos_sep = rclient.bottom - 5;
369 if (kmi->ypos_sep < rclient.top)
370 kmi->ypos_sep = rclient.top;
371 MoveWindow (kmi->hwnd_sep, 0, kmi->ypos_sep,
372 (rclient.right - rclient.left), 5, bRepaint);
373
374 /* Place the keylist above the separator */
375 h = GetDlgItem (dlg, IDC_KEYMISC_KEYLIST);
376 MoveWindow (h, rclient.left, rclient.top, rclient.right - rclient.left,
377 kmi->ypos_sep - rclient.top, bRepaint);
378 rclient.top = kmi->ypos_sep + 5 + 8;
379
380 /* Place the group text and the group box below the separator */
381 h = GetDlgItem (dlg, IDC_KEYMISC_GTEXT);
382 MoveWindow (h, rclient.left, rclient.top, 100, 14, bRepaint);
383 rclient.top += 18;
384
385 h = GetDlgItem (dlg, IDC_KEYMISC_GROUP);
386 MoveWindow (h, rclient.left, rclient.top, rclient.right - rclient.left,
387 (rclient.bottom < rclient.top) ?
388 0 : rclient.bottom - rclient.top, bRepaint);
389
390 /* Repaint the whole thing */
391 InvalidateRect (dlg, NULL, TRUE);
392 }
393
394
395 /* Return true if the clipboard contains an OpenPGP key. */
396 static bool
397 clip_contains_pgpkey (void)
398 {
399 char *ctxt;
400 bool val = false;
401
402 ctxt = get_clip_text (NULL);
403 if (!ctxt || strlen (ctxt) < 512)
404 val = false;
405 else if (strstr (ctxt, "BEGIN PGP") && strstr (ctxt, "KEY BLOCK") &&
406 strstr (ctxt, "END PGP"))
407 val = true;
408 free_if_alloc (ctxt);
409 return val;
410 }
411
412
413 /* Show a mini popup menu to import keys. */
414 static void
415 do_create_minpopup (HWND dlg)
416 {
417 HMENU hm;
418 MENUITEMINFO mi;
419 char * s;
420 POINT p;
421
422 if (gpg_read_only || !clip_contains_pgpkey ())
423 return;
424 hm = CreatePopupMenu ();
425 if (!hm)
426 BUG( NULL );
427 memset (&mi, 0, sizeof mi);
428 mi.cbSize = sizeof mi;
429 s = (char *)_("Paste Key from Clipboard");
430 mi.fType = MF_STRING;
431 mi.dwTypeData = s;
432 mi.cch = strlen (s);
433 mi.fMask = MIIM_DATA | MIIM_ID | MIIM_TYPE;
434 mi.wID = ID_KEYCTX_PASTE;
435 InsertMenuItem (hm, 0, FALSE, &mi);
436 GetCursorPos (&p);
437 TrackPopupMenu (hm, 0, p.x, p.y, 0, dlg, NULL);
438 DestroyMenu (hm);
439 }
440
441
442 /* Update the default key entry in the status bar for dialog @dlg. */
443 void
444 update_default_key_str (HWND dlg)
445 {
446 const char *fmt;
447 char *keyid;
448 char defkeyinf[128];
449
450 /* XXX: also show the name? */
451 keyid = get_gnupg_default_key ();
452 if (!keyid)
453 return;
454 if ((keyid[0] >= 'A' && keyid[0] <= 'Z') ||
455 (keyid[0] >= 'a' && keyid[0] <= 'z') ||
456 (keyid[0] == '0' && keyid[1] == 'x'))
457 fmt = _("Default Key: %s");
458 else
459 fmt = _("Default Key: 0x%s");
460 _snprintf (defkeyinf, sizeof (defkeyinf) - 1, fmt, keyid);
461 SendMessage (dlg, SB_SETTEXT, 0, (LPARAM)defkeyinf);
462 free_if_alloc (keyid);
463 }
464
465
466 /* Count all keys and show from @lv results in the status bar @sb. */
467 void
468 update_status_bar (HWND sb, listview_ctrl_t lv)
469 {
470 char txt_sec[128], txt_pub[128];
471 int nkeys = 0, nsec = 0;
472 int i;
473
474 nkeys = listview_count_items (lv, 0);
475 for (i = 0; i < nkeys; i++) {
476 if (km_check_for_seckey (lv, i, NULL))
477 nsec++;
478 }
479 _snprintf (txt_sec, sizeof (txt_sec)-1, _("%d secret keys"), nsec);
480 _snprintf (txt_pub, sizeof (txt_pub)-1, _("%d keys"), nkeys);
481 SendMessage (sb, SB_SETTEXT, 1, (LPARAM)txt_sec);
482 SendMessage (sb, SB_SETTEXT, 2, (LPARAM)txt_pub);
483 }
484
485
486
487 /* Reload the key cache if requested. */
488 static void
489 do_check_cache (listview_ctrl_t lv, HWND dlg, HWND sb)
490 {
491 gpg_keycache_t cache;
492
493 if (keycache_get_reload ()) {
494 keycache_reload (dlg);
495 keycache_set_reload (0);
496 cache = keycache_get_ctx (1);
497 if (!cache)
498 BUG (dlg);
499 keylist_reload (lv, cache, KEYLIST_LIST, KEY_SORT_USERID);
500 update_status_bar (sb, lv);
501 }
502 }
503
504
505 long CALLBACK
506 separator_wnd_proc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
507 {
508 static POINT last_mouse_pos;
509
510 if (msg == WM_CREATE)
511 SetWindowLong (hwnd, GWL_USERDATA,
512 (long)(((CREATESTRUCT*)lparam)->lpCreateParams));
513
514 switch (msg) {
515 case WM_PAINT:
516 PAINTSTRUCT ps;
517 RECT rect;
518 HPEN hpen;
519
520 GetClientRect (hwnd, &rect);
521 BeginPaint (hwnd, &ps);
522
523 /* Background */
524 FillRect (ps.hdc, &rect, (HBRUSH)(COLOR_3DFACE+1));
525
526 /* The lines from the light into the dark */
527 MoveToEx(ps.hdc, 0,0, NULL);
528 if ((hpen = CreatePen (PS_SOLID, 0, GetSysColor(COLOR_3DHILIGHT))) != NULL) {
529 SelectObject (ps.hdc, (LPVOID)hpen);
530 LineTo (ps.hdc, rect.right, 0);
531 DeleteObject (hpen);
532 }
533 MoveToEx(ps.hdc, 0, 1, NULL);
534 if ((hpen = CreatePen (PS_SOLID, 0, GetSysColor(COLOR_3DLIGHT))) != NULL) {
535 SelectObject (ps.hdc, (LPVOID)hpen);
536 LineTo (ps.hdc, rect.right, rect.bottom);
537 DeleteObject (hpen);
538 }
539
540 MoveToEx(ps.hdc, 0, rect.bottom-1, NULL);
541 if ((hpen = CreatePen (PS_SOLID, 0, GetSysColor(COLOR_3DSHADOW))) != NULL) {
542 SelectObject (ps.hdc, (LPVOID)hpen);
543 LineTo (ps.hdc, rect.right, rect.bottom-1);
544 DeleteObject (hpen);
545 }
546 MoveToEx(ps.hdc, 0, rect.bottom, NULL);
547 if ((hpen = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_3DDKSHADOW))) != NULL) {
548 SelectObject (ps.hdc, (LPVOID)hpen);
549 LineTo (ps.hdc, rect.right, rect.bottom);
550 DeleteObject (hpen);
551 }
552
553 EndPaint (hwnd, &ps);
554 return 0;
555
556 case WM_LBUTTONDOWN:
557 last_mouse_pos.x = LOWORD (lparam);
558 last_mouse_pos.y = HIWORD (lparam);
559 ClientToScreen (hwnd, &last_mouse_pos);
560 SetCapture (hwnd);
561 return 0;
562
563 case WM_LBUTTONUP:
564 ReleaseCapture ();
565 return 0;
566
567 case WM_MOUSEMOVE:
568 if (wparam == MK_LBUTTON) {
569 struct km_info_s *kmi;
570 POINT p;
571 RECT r;
572
573 kmi = (struct km_info_s *)GetWindowLong (hwnd, GWL_USERDATA);
574 if (kmi == NULL)
575 break;
576
577 /* Calculate mouse movement */
578 p.x = LOWORD(lparam);
579 p.y = HIWORD(lparam);
580 ClientToScreen (hwnd, &p);
581
582 GetWindowRect (hwnd, &r);
583 r.top += (short)(p.y - last_mouse_pos.y);
584 r.bottom += (short)(p.y - last_mouse_pos.y);
585
586 last_mouse_pos.y = p.y;
587
588 /* Apply mouse movement to window. Beware the MoveWindow is relaive
589 to parent NOT screen */
590 MapWindowPoints (NULL, GetParent(hwnd), (POINT*)&r, 2);
591 kmi->ypos_sep = r.top;
592 kmi->ypercent_sep = 0; /* This forces do_resize_window to use abs. position */
593 do_resize_window (GetParent(hwnd), kmi);
594 return 0;
595 }
596 }
597
598 return DefWindowProc (hwnd, msg, wparam, lparam);
599 }
600
601
602 /* Register the separator window with @dlg as the parent window. */
603 static HWND
604 regist_sep_wnd (HWND dlg, struct km_info_s *kmi)
605 {
606 WNDCLASS wndclass;
607 HWND h;
608
609 wndclass.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
610 wndclass.lpfnWndProc = separator_wnd_proc;
611 wndclass.cbClsExtra = 0;
612 wndclass.cbWndExtra = sizeof (long);
613 wndclass.hInstance = glob_hinst;
614 wndclass.hIcon = NULL;
615 wndclass.hCursor = LoadCursor (NULL, IDC_SIZENS);
616 wndclass.hbrBackground = (HBRUSH) GetStockObject (LTGRAY_BRUSH);
617 wndclass.lpszMenuName = 0;
618 wndclass.lpszClassName = WINDOWCLASS_SEPARATOR_CHILD;
619 RegisterClass (&wndclass);
620
621 h = CreateWindowEx (WS_EX_WINDOWEDGE, WINDOWCLASS_SEPARATOR_CHILD, NULL,
622 WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE,
623 0, 400, 2000, 5, dlg, (HMENU) 0, glob_hinst, kmi);
624 ShowWindow (h, SW_SHOW);
625 return h;
626 }
627
628
629 #define enable_button(hwnd, cid) \
630 SendMessage ((hwnd), TB_ENABLEBUTTON, (cid), MAKELONG (key_selected, 0))
631
632
633 /* Interactive modification of the dialog item which depend if an item
634 is selected or not and what kind of item. @lv is the list view with
635 the items. */
636 void
637 update_ui_items (HWND hwnd, listview_ctrl_t lv)
638 {
639 HWND hwnd_child;
640 HMENU hmenu;
641 int key_selected = 0;
642 int key_has_sec = 0;
643 int key_inv = 0;
644 int mult_resids[] = {ID_KEYMISC_PROPS, ID_KEYMISC_SIGN, ID_KEYMISC_EDITKEY,
645 ID_KEYMISC_CHECKSIGS, ID_KEYMISC_REVCERT, 0};
646 int i, state=0;
647
648 /* Get some states */
649 key_selected = SendMessage (GetDlgItem (hwnd, IDC_KEYMISC_KEYLIST),
650 LVM_GETSELECTEDCOUNT, 0, 0)
651 ? TRUE : FALSE;
652 key_has_sec = FALSE;
653 if (key_selected) {
654 i = listview_get_curr_pos (lv);
655 key_has_sec = km_check_for_seckey (lv, i, NULL) ? TRUE : FALSE;
656 key_inv = km_get_key_status (lv, i) & KM_FLAG_REVOKED ||
657 km_get_key_status (lv, i) & KM_FLAG_EXPIRED;
658 }
659
660 /* Enable / disable toolbar buttons */
661 hwnd_child = GetDlgItem (hwnd, IDR_WINPT_KMTB);
662 enable_button (hwnd_child, ID_KEYMISC_DELETE);
663 enable_button (hwnd_child, ID_KEYMISC_PROPS);
664 enable_button (hwnd_child, ID_KEYMISC_SIGN);
665 enable_button (hwnd_child, ID_KEYMISC_EXPORT);
666
667 /* Enable / disable menu items */
668 state = key_selected? MF_ENABLED : MF_DISABLED|MF_GRAYED;
669 hmenu = GetMenu (hwnd);
670 set_menu_state (hmenu, ID_KEYMISC_EXPORT, state);
671 set_menu_state (hmenu, ID_KEYMISC_DELETE, state);
672 set_menu_state (hmenu, ID_KEYMISC_PROPS, state);
673 set_menu_state (hmenu, ID_KEYMISC_EDITKEY, state);
674 set_menu_state (hmenu, ID_KEYMISC_CHECKSIGS, state);
675 set_menu_state (hmenu, ID_KEYMISC_SIGN,
676 key_selected && !key_inv ? MF_ENABLED : MF_GRAYED);
677 set_menu_state (hmenu, ID_KEYMISC_EXPORT_PRIVKEY,
678 key_selected && key_has_sec? MF_ENABLED : MF_GRAYED);
679 set_menu_state (hmenu, ID_KEYMISC_REVCERT,
680 key_selected && key_has_sec? MF_ENABLED : MF_GRAYED);
681
682 /* Disable some menu items when multiple keys are selected. */
683 if (listview_count_items (lv, 1) > 1) {
684 for (i=0; mult_resids[i] != 0; i++)
685 set_menu_state (hmenu, mult_resids[i], MF_GRAYED);
686 }
687 }
688
689
690 /* Disable some context menu items when multiple keys are selected. */
691 static void
692 popup_multiple (HWND dlg, HMENU hm)
693 {
694 int resids[] = {
695 ID_KEYCTX_EDIT,
696 ID_KEYCTX_SIGN,
697 ID_KEYCTX_REV,
698 ID_KEYCTX_ENABLE,
699 ID_KEYCTX_DISABLE,
700 ID_KEYCTX_ADDKEY,
701 ID_KEYCTX_ADDPHOTO,
702 ID_KEYCTX_ADDUID,
703 ID_KEYCTX_ADDREV,
704 ID_KEYCTX_LISTSIGS,
705 ID_KEYCTX_MAXTRUST,
706 ID_KEYCTX_PROPS,
707 ID_KEYCTX_SENDMAIL,
708 0};
709 int i;
710 for (i=0; i < resids[i] != 0; i++)
711 set_menu_state (hm, resids[i], MF_GRAYED);
712 }
713
714
715 /* The items which are shown when GPG is in read-only mode. */
716 static void
717 popup_gpg_readonly (HWND dlg, HMENU hm)
718 {
719 int resids[] = {
720 ID_KEYCTX_PASTE,
721 ID_KEYCTX_EDIT,
722 ID_KEYCTX_SIGN,
723 ID_KEYCTX_REV,
724 ID_KEYCTX_DEL,
725 ID_KEYCTX_ENABLE,
726 ID_KEYCTX_DISABLE,
727 ID_KEYCTX_RECVFROM,
728 ID_KEYCTX_ADDKEY,
729 ID_KEYCTX_ADDPHOTO,
730 ID_KEYCTX_ADDUID,
731 ID_KEYCTX_ADDREV,
732 0
733 };
734 int i;
735
736 if (gpg_read_only == 0)
737 return;
738 for (i=0; resids[i] != 0; i++)
739 set_menu_state (hm, resids[i], MF_GRAYED);
740 }
741
742
743 /* Change the 'Edit' menu based on the current state. */
744 static void
745 change_edit_menu (listview_ctrl_t lv, HMENU hm, int id)
746 {
747 enum item { EDIT_MENU = 1 };
748 int no_sel;
749
750 if (id != EDIT_MENU)
751 return;
752
753 if (!clip_contains_pgpkey ())
754 set_menu_state (hm, ID_KEYMISC_PASTE, MF_GRAYED);
755 else
756 set_menu_state (hm, ID_KEYMISC_PASTE, MF_ENABLED);
757 no_sel = listview_get_curr_pos (lv) == -1? 1 : 0;
758 set_menu_state (hm, ID_KEYMISC_DELETE2, no_sel? MF_GRAYED: MF_ENABLED);
759 set_menu_state (hm, ID_KEYMISC_COPY, no_sel? MF_GRAYED : MF_ENABLED);
760 }
761
762
763
764 /* Show limited key menu entries when GPG is in read-only mode. */
765 static void
766 change_key_menu (HMENU hm, int id)
767 {
768 int key_resids[] = {
769 ID_KEYMISC_SIGN,
770 ID_KEYMISC_DELETE,
771 ID_KEYMISC_REVCERT,
772 ID_KEYMISC_IMPORT_HTTP,
773 ID_KEYMISC_IMPORT,
774 ID_KEYMISC_REFRESH_KEYS,
775 ID_KEYMISC_REBUILD,
776 ID_KEYMISC_KEYWIZARD,
777 ID_KEYMISC_CARDNEW,
778 ID_KEYMISC_NEWKEY,
779 0,
780 };
781 int edit_resids[] = {
782 ID_KEYMISC_PASTE,
783 ID_KEYMISC_OT,
784 ID_KEYMISC_EDITKEY,
785 0
786 };
787 int *resids;
788 int i;
789
790
791 if (gpg_read_only == 0)
792 return;
793 switch (id) {
794 case 0: return;
795 case 3: resids = key_resids; break;
796 case 1: resids = edit_resids;break;
797 default:resids = edit_resids; break;
798 }
799
800 for (i=0; resids[i] != 0; i++)
801 set_menu_state (hm, resids[i], MF_GRAYED);
802 }
803
804
805 /* Reload a single key in the cache. */
806 static void
807 update_key (listview_ctrl_t lv, int pos, const char *keyid, int keypair)
808 {
809 gpgme_key_t key;
810
811 keycache_update (0, keyid);
812 if (keypair)
813 keycache_update (1, keyid);
814
815 /* because we replaced the key item, we need to update the
816 address of the pointer in the ListView control. */
817 get_pubkey (keyid, &key);
818 keylist_upd_key (lv, pos, key);
819 }
820
821
822 /* Setup status bar for the main window @dlg. */
823 static HWND
824 setup_status_bar (HWND dlg, listview_ctrl_t lv)
825 {
826 HWND statbar;
827 RECT r;
828 int partpos[3];
829 int i;
830
831 GetClientRect (dlg, &r);
832 for (i=1; i <= 3; i++)
833 partpos[i-1] = r.right/3*i;
834 statbar = CreateStatusWindow (WS_CHILD | WS_VISIBLE | CCS_BOTTOM,
835 "status bar", dlg, KM_SEPARATOR_ID);
836
837 ShowWindow (statbar, SW_SHOW);
838 SendMessage (statbar, SB_SETPARTS, (WPARAM)3, (LPARAM)partpos);
839
840 update_default_key_str (statbar);
841 update_status_bar (statbar, lv);
842
843 return statbar;
844 }
845
846
847 /* Remove or add columns which depends on the state of @checked. */
848 void
849 modify_listview_columns (km_info_s *kmi, UINT m_uid, BOOL checked)
850 {
851 UINT resids[] = {
852 0,
853 ID_KEYMISC_VIEWKEYID,
854 ID_KEYMISC_VIEWTYPE,
855 0,
856 ID_KEYMISC_VIEWCIPHER,
857 0,
858 0,
859 ID_KEYMISC_VIEWCREAT,
860 -1
861 };
862 listview_column_s cols[] = {
863 {0, 240, (char *)_("User ID")},
864 {1, 78, (char *)_("Key ID")},
865 {2, 52, (char *)_("Type")},
866 {3, 66, (char *)_("Size")},
867 {4, 60, (char *)_("Cipher")},
868 {5, 66, (char *)_("Validity")},
869 {6, 58, (char *)_("Trust")},
870 {7, 72, (char *)_("Creation")},
871 {0, 0, NULL}
872 };
873 UINT pos;
874
875 for (pos=0; resids[pos] != -1; pos++) {
876 if (m_uid == resids[pos])
877 break;
878 }
879 if (!checked)
880 listview_del_column (kmi->lv, (int)pos);
881 else {
882 listview_add_column (kmi->lv, &cols[pos]);
883 keylist_upd_col (kmi->lv, pos);
884 }
885 }
886
887
888 /* Helper to handle the help file. If @check is 1
889 the existence of the file is checked.
890 Otherwise the help file will be loaded. */
891 static bool
892 start_help (HWND dlg, int check)
893 {
894 DWORD n;
895 char path[MAX_PATH+1+32];
896
897 n = GetModuleFileName (NULL, path, sizeof (path)-1-32);
898 if (!n)
899 return false;
900 path[n] = 0;
901 while (n-- && path[n] != '\\')
902 ;
903 path[n+1] = 0;
904 strcat (path, "winpt.chm");
905 if (!check)
906 ShellExecute (dlg, "open", path, NULL, NULL, SW_SHOW);
907 return file_exist_check (path) == 0? true : false;
908 }
909
910 /* Translate all menu strings. */
911 static void
912 translate_menu_strings (HWND dlg)
913 {
914 HMENU menu;
915
916 menu = LoadMenu (glob_hinst, (LPCSTR)IDR_WINPT_KEYMISC);
917 set_menu_text_bypos (menu, 0, _("File"));
918 set_menu_text_bypos (menu, 1, _("Edit"));
919 set_menu_text_bypos (menu, 2, _("View"));
920 set_menu_text_bypos (menu, 3, _("Key"));
921 set_menu_text_bypos (menu, 4, _("Groups"));
922
923 set_menu_text (menu, ID_KEYMISC_EDITKEY, _("Edit"));
924 set_menu_text (menu, ID_KEYMISC_MAIL, _("Send Mail..."));
925 set_menu_text (menu, ID_KEYMISC_OT, _("Ownertrust")); /* XXX */
926 set_menu_text (menu, ID_KEYMISC_COPY, _("&Copy\tCtrl+C"));
927 set_menu_text (menu, ID_KEYMISC_PASTE, _("&Paste\tCtrl+V"));
928 set_menu_text (menu, ID_KEYMISC_FIND, _("Search...\tCtrl+F"));
929 set_menu_text (menu, ID_KEYMISC_SELALL, _("Select All\tCtrl+A"));
930 set_menu_text (menu, ID_KEYMISC_QUIT, _("&Quit"));
931 set_menu_text (menu, ID_KEYMISC_UID, _("User ID"));
932 set_menu_text (menu, ID_KEYMISC_NEWKEY, _("&Expert"));
933 set_menu_text (menu, ID_KEYMISC_KEYWIZARD, _("&Normal"));
934 set_menu_text (menu, ID_KEYMISC_EDIT, _("Edit"));
935 set_menu_text (menu, ID_KEYMISC_SIGN, _("&Sign"));
936 set_menu_text (menu, ID_KEYMISC_DELETE, _("&Delete"));
937 set_menu_text (menu, ID_KEYMISC_DELETE2, _("&Delete"));
938 set_menu_text (menu, ID_KEYMISC_REVCERT, _("&Revoke Cert"));
939 set_menu_text (menu, ID_KEYMISC_CHECKSIGS, _("&List Signatures"));
940 set_menu_text (menu, ID_KEYMISC_TRUSTPATH, _("List Trust Path"));
941 set_menu_text (menu, ID_KEYMISC_EXPORT, _("&Export..."));
942 set_menu_text (menu, ID_KEYMISC_IMPORT, _("&Import..."));
943 set_menu_text (menu, ID_KEYMISC_PROPS, _("&Properties"));
944 set_menu_text (menu, ID_KEYMISC_GPGOPT, _("Options"));
945 set_menu_text (menu, ID_KEYMISC_GPGPREFS, _("Preferences"));
946 set_menu_text (menu, ID_KEYMISC_SENDRECV, _("Keyserver") );
947 set_menu_text (menu, ID_KEYMISC_EXPORT_PRIVKEY, _("E&xport Secret Key"));
948 set_menu_text (menu, ID_KEYMISC_RECACHE, _("Re&load Key Cache"));
949 set_menu_text (menu, ID_KEYMISC_REBUILD, _("R&everify Signatures"));
950 set_menu_text (menu, ID_KEYMISC_REFRESH_KEYS, _("Refresh &Keys (Keyserver)"));
951 set_menu_text (menu, ID_KEYMISC_INFO, _("Info") );
952 set_menu_text (menu, ID_KEYMISC_HELP, _("&Help"));
953
954 set_menu_text (menu, ID_KEYMISC_VIEWKEYID, _("Key ID"));
955 set_menu_text (menu, ID_KEYMISC_VIEWCIPHER, _("Cipher"));
956 set_menu_text (menu, ID_KEYMISC_VIEWTYPE, _("Type"));
957 set_menu_text (menu, ID_KEYMISC_VIEWCREAT, _("Creation"));
958
959 if (!start_help (NULL, 1))
960 set_menu_state (menu, ID_KEYMISC_HELP, MF_GRAYED);
961
962 SetMenu (dlg, menu);
963 }
964
965
966 /* Translate popup menu strings. */
967 static void
968 translate_popupmenu_strings (HMENU popup)
969 {
970 set_menu_text (popup, ID_KEYCTX_UID_COPY, _("Copy User ID to Clipboard"));
971 set_menu_text (popup, ID_KEYCTX_KEYID_COPY, _("Copy Key ID to Clipboard"));
972 set_menu_text (popup, ID_KEYCTX_FPR_COPY, _("Copy Fingerprint to Clipboard"));
973 set_menu_text (popup, ID_KEYCTX_KINFO_COPY, _("Copy Key Info to Clipboard"));
974 set_menu_text (popup, ID_KEYCTX_COPY, _("Copy Key to Clipboard"));
975 set_menu_text (popup, ID_KEYCTX_PASTE, _("Paste Key from Clipboard"));
976 set_menu_text (popup, ID_KEYCTX_RECVFROM, _("Refresh from Keyserver"));
977 set_menu_text (popup, ID_KEYCTX_MAXTRUST, _("Set Implicit &Trust"));
978 set_menu_text (popup, ID_KEYCTX_LISTSIGS, _("&List Signatures"));
979 set_menu_text (popup, ID_KEYCTX_PROPS, _("&Properties"));
980 set_menu_text (popup, ID_KEYCTX_EDIT, _("Key Edit"));
981 set_menu_text (popup, ID_KEYCTX_DEL, _("&Delete"));
982 set_menu_text (popup, ID_KEYCTX_REV, _("&Revoke Cert"));
983 set_menu_text (popup, ID_KEYCTX_SIGN, _("&Sign"));
984 set_menu_text (popup, ID_KEYCTX_ENABLE, _("&Enable"));
985 set_menu_text (popup, ID_KEYCTX_DISABLE, _("&Disable"));
986 set_menu_text (popup, ID_KEYCTX_RECVFROM, _("Re&fresh from Keyserver"));
987 set_menu_text (popup, ID_KEYCTX_SETPREFKS, _("Set preferred Keyserver URL"));
988 set_menu_text (popup, ID_KEYCTX_SENDMAIL, _("Send Key to Mail Recipient"));
989 set_menu_text (popup, ID_KEYCTX_SETDEFKEY, _("Set as Default Key"));
990
991 set_menu_text (popup, ID_KEYCTX_ADDKEY, _("Key..."));
992 set_menu_text (popup, ID_KEYCTX_ADDUID, _("User ID..."));
993 set_menu_text (popup, ID_KEYCTX_ADDPHOTO, _("Photo ID..."));
994 set_menu_text (popup, ID_KEYCTX_ADDREV, _("Revoker..."));
995
996 /* change popup texts */
997 set_menu_text_bypos (popup, 0, _("Key Attributes"));
998 set_menu_text_bypos (popup, 6, _("Add"));
999 set_menu_text_bypos (popup, 19, _("Send to Keyserver"));
1000 }
1001
1002
1003
1004 /* Dialog box procedure for the Key Manager. */
1005 BOOL CALLBACK
1006 keymanager_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
1007 {
1008 struct km_info_s *kmi;
1009 static int refresh_keys = 0;
1010 INITCOMMONCONTROLSEX icex;
1011 HWND kl;
1012 HMENU hm;
1013 gpg_keycache_t c;
1014 gpgme_key_t key;
1015 struct genkey_s genkey;
1016 struct winpt_key_s k = {0};
1017 struct URL_ctx_s *url;
1018 refresh_cache_s rcs = {0};
1019 char type[32], *name;
1020 const char *t, *host;
1021 WORD port = 0;
1022 int l_idx = 0, i=0, rc;
1023
1024 if ((msg != WM_INITDIALOG)
1025 && ((kmi = (struct km_info_s*)GetWindowLong (dlg, GWL_USERDATA)) == NULL))
1026 return FALSE;
1027
1028 switch (msg) {
1029 case WM_INITDIALOG:
1030 kmi = new struct km_info_s;
1031 memset (kmi, 0, sizeof (struct km_info_s));
1032 kmi->lv_idx = -1;
1033 icex.dwSize = sizeof (INITCOMMONCONTROLSEX);
1034 icex.dwICC = ICC_BAR_CLASSES;
1035 InitCommonControlsEx (&icex);
1036 kmi->hwnd_sep = regist_sep_wnd (dlg, kmi);
1037 imagelist_load (dlg);
1038 translate_menu_strings (dlg);
1039 SetWindowText (dlg, _("Key Manager"));
1040
1041 if (keyring_check_last_access ())
1042 keycache_set_reload (1);
1043 if (keycache_get_reload ())
1044 keycache_reload (dlg);
1045 c = keycache_get_ctx (KEYCACHE_PUB);
1046 if (!c)
1047 BUG (NULL);
1048 kl = GetDlgItem (dlg, IDC_KEYMISC_KEYLIST);
1049 kmi->keylist_sortby = KEY_SORT_USERID;
1050 Header_SetImageList(ListView_GetHeader (kl), glob_imagelist);
1051 kmi->lv = keylist_load (GetDlgItem (dlg, IDC_KEYMISC_KEYLIST), c,
1052 NULL, KEYLIST_LIST, kmi->keylist_sortby);
1053 /* init subclassing for the listview */
1054 keylist_proc.dlg = dlg;
1055 keylist_proc.current = (WNDPROC)keylist_subclass_proc;
1056 keylist_proc.old = (WNDPROC)GetWindowLong(kl, GWL_WNDPROC);
1057 if (keylist_proc.old) {
1058 if( !SetWindowLong (kl, GWL_WNDPROC, (LONG)keylist_proc.current)) {
1059 msg_box (dlg, _("Could not set keylist window procedure."),
1060 _("Key Manager"), MB_ERR);
1061 BUG (NULL);
1062 }
1063 }
1064 kmi->statbar = setup_status_bar (dlg, kmi->lv);
1065 SetWindowLong (dlg, GWL_USERDATA, (LONG)kmi);
1066 kmi->toolbar = load_toolbar (dlg, kmi);
1067
1068 do_center_window (dlg, kmi);
1069 do_resize_window (dlg, kmi);
1070 update_ui_items (dlg, kmi->lv);
1071 restore_column_info (kmi->lv);
1072
1073 SetDlgItemText (dlg, IDC_KEYMISC_GTEXT, _("Groups"));
1074 SetClassLong (dlg, GCL_HICON, (LONG)LoadIcon (glob_hinst,
1075 (LPCTSTR)IDI_WINPT));
1076 SetForegroundWindow (dlg);
1077 force_foreground_window (dlg, 1000);
1078 return TRUE;
1079
1080 case WM_DESTROY:
1081 save_column_info (kmi->lv);
1082 if (kmi->lv) {
1083 keylist_delete (kmi->lv);
1084 kmi->lv = NULL;
1085 }
1086 imagelist_destroy ();
1087
1088 ltoa (kmi->pos_x, type, 10);
1089 set_reg_entry (HKEY_CURRENT_USER, "Software\\WinPT", "KM_Pos_X", type);
1090 ltoa (kmi->pos_y, type, 10);
1091 set_reg_entry (HKEY_CURRENT_USER, "Software\\WinPT", "KM_Pos_Y", type);
1092
1093 /* Remove runtime information. This should be the last action taken here. */
1094 delete kmi; kmi = NULL;
1095 SetWindowLong (dlg, GWL_USERDATA, 0);
1096 keycache_set_reload (refresh_keys);
1097 return FALSE;
1098
1099 case WM_MOVE:
1100 RECT r;
1101 GetWindowRect (dlg, &r);
1102 kmi->pos_x = r.left;
1103 kmi->pos_y = r.top;
1104 break;
1105
1106
1107 case WM_RBUTTONUP:
1108 do_create_minpopup (dlg);
1109 break;
1110
1111 case WM_NOTIFY:
1112 NMHDR *notify;
1113 POINT p;
1114 HMENU popup;
1115
1116 notify = (NMHDR *)lparam;
1117 if (!notify)
1118 break;
1119 switch (notify->code) {
1120 case TBN_QUERYDELETE:
1121 SetWindowLong (dlg, DWL_MSGRESULT, TRUE);
1122 return TRUE;
1123
1124 case TBN_QUERYINSERT:
1125 SetWindowLong (dlg, DWL_MSGRESULT, TRUE);
1126 return TRUE;
1127
1128 case TBN_GETBUTTONINFO:
1129 LPTBNOTIFY lpTbNotify;
1130 lpTbNotify = (LPTBNOTIFY)lparam;
1131 if (lpTbNotify->iItem < (sizeof(myb) / sizeof(mybuttons))) {
1132 lpTbNotify->tbButton.iBitmap = imagelist_getindex(myb[lpTbNotify->iItem].icon);
1133 lpTbNotify->tbButton.idCommand = myb[lpTbNotify->iItem].command;
1134 lpTbNotify->tbButton.fsState = TBSTATE_ENABLED;
1135 lpTbNotify->tbButton.fsStyle = TBSTYLE_BUTTON;
1136 lpTbNotify->tbButton.iString = 0;
1137 strncpy (lpTbNotify->pszText, myb[lpTbNotify->iItem].text, lpTbNotify->cchText);
1138 SetWindowLong(dlg, DWL_MSGRESULT, TRUE);
1139 }
1140 return TRUE;
1141
1142 case TBN_RESET: /* Restore last saved toolbar status */
1143 TBSAVEPARAMS tbsp;
1144
1145 tbsp.hkr = HKEY_CURRENT_USER;
1146 tbsp.pszSubKey = "Software\\WinPT";
1147 tbsp.pszValueName = "KM_toolbar";
1148 SendMessage (notify->hwndFrom, TB_SAVERESTORE, FALSE, (LPARAM)&tbsp);
1149 break;
1150
1151 case TBN_BEGINADJUST: /* User is about to change the toolbar. Save it */
1152 tbsp.hkr = HKEY_CURRENT_USER;
1153 tbsp.pszSubKey = "Software\\WinPT";
1154 tbsp.pszValueName = "KM_toolbar";
1155 SendMessage (notify->hwndFrom, TB_SAVERESTORE, TRUE, (LPARAM)&tbsp);
1156 break;
1157
1158 case TBN_ENDADJUST: /* User has finished customizing the toolbar. Save it. */
1159 tbsp.hkr = HKEY_CURRENT_USER;
1160 tbsp.pszSubKey = "Software\\WinPT";
1161 tbsp.pszValueName = "KM_toolbar";
1162 SendMessage (notify->hwndFrom, TB_SAVERESTORE, TRUE, (LPARAM)&tbsp);
1163 break;
1164
1165 case TTN_GETDISPINFO:
1166 LPTOOLTIPTEXT lpttt;
1167 lpttt = (LPTOOLTIPTEXT)lparam;
1168
1169 lpttt->hinst = NULL;
1170 switch (lpttt->hdr.idFrom) {
1171 case ID_KEYMISC_DELETE:
1172 lpttt->lpszText = (char *)_("Delete key from keyring");
1173 break;
1174
1175 case ID_KEYMISC_PROPS:
1176 lpttt->lpszText = (char *)_("Show key properties");
1177 break;
1178
1179 case ID_KEYMISC_SIGN:
1180 lpttt->lpszText = (char *)_("Sign key");
1181 break;
1182
1183 case ID_KEYMISC_IMPORT:
1184 lpttt->lpszText = (char *)_("Import key to keyring");
1185 break;
1186
1187 case ID_KEYMISC_EXPORT:
1188 lpttt->lpszText = (char *)_("Export key to a file");
1189 break;
1190 }
1191 return TRUE;
1192
1193 case LVN_ITEMCHANGED:
1194 if (((LPNMLISTVIEW)lparam)->uNewState) { /* item selected? */
1195 kmi->lv_idx = listview_get_curr_pos (kmi->lv);
1196 update_ui_items (dlg, kmi->lv);
1197 return TRUE;
1198 }
1199 break;
1200
1201 case NM_RCLICK:
1202 if (notify->idFrom == IDC_KEYMISC_KEYLIST) {
1203 l_idx =listview_get_curr_pos (kmi->lv);
1204 if (l_idx == -1)
1205 return TRUE; /* Popup only when a item was selected */
1206 do_check_cache (kmi->lv, dlg, kmi->statbar);
1207 GetCursorPos (&p);
1208 hm = LoadMenu (glob_hinst, MAKEINTRESOURCE (IDR_WINPT_KEYMISC_CTX));
1209 popup = GetSubMenu (hm, 0);
1210 translate_popupmenu_strings (popup);
1211
1212 if (km_check_for_seckey (kmi->lv, l_idx, &i))
1213 set_menu_state (popup, ID_KEYCTX_SETDEFKEY, MF_ENABLED);
1214 if (i == 0)
1215 set_menu_state (popup, ID_KEYCTX_MAXTRUST, MF_ENABLED);
1216 if (!km_check_for_seckey (kmi->lv, l_idx, NULL)) {
1217 set_menu_state (popup, ID_KEYCTX_REV, MF_DISABLED|MF_GRAYED);
1218 set_menu_state (popup, ID_KEYCTX_ADDKEY, MF_DISABLED|MF_GRAYED);
1219 set_menu_state (popup, ID_KEYCTX_ADDUID, MF_DISABLED|MF_GRAYED);
1220 set_menu_state (popup, ID_KEYCTX_ADDREV, MF_DISABLED|MF_GRAYED);
1221 set_menu_state (popup, ID_KEYCTX_ADDPHOTO, MF_DISABLED|MF_GRAYED );
1222 set_menu_state (popup, ID_KEYCTX_SETPREFKS, MF_DISABLED|MF_GRAYED);
1223 }
1224 else if (km_check_for_seckey (kmi->lv, l_idx, NULL) &&
1225 km_key_is_v3 (kmi->lv, l_idx)) {
1226 /* PGP 2 keys, version 3 have no no support for photo-id's,
1227 designated revokers and secondary keys. */
1228 set_menu_state (popup, ID_KEYCTX_ADDKEY, MF_DISABLED|MF_GRAYED);
1229 set_menu_state (popup, ID_KEYCTX_ADDREV, MF_DISABLED|MF_GRAYED);
1230 set_menu_state (popup, ID_KEYCTX_ADDPHOTO, MF_DISABLED|MF_GRAYED);
1231 }
1232 if (km_get_key_status( kmi->lv, l_idx ) & KM_FLAG_DISABLED)
1233 set_menu_state (popup, ID_KEYCTX_DISABLE, MF_DISABLED|MF_GRAYED);
1234 else
1235 set_menu_state (popup, ID_KEYCTX_ENABLE, MF_DISABLED|MF_GRAYED);
1236 if (km_get_key_status (kmi->lv, l_idx) & KM_FLAG_REVOKED ||
1237 km_get_key_status (kmi->lv, l_idx) & KM_FLAG_EXPIRED)
1238 set_menu_state (popup, ID_KEYCTX_SIGN, MF_DISABLED|MF_GRAYED);
1239 if (!clip_contains_pgpkey ())
1240 set_menu_state (popup, ID_KEYCTX_PASTE, MF_DISABLED|MF_GRAYED);
1241 if (mapi_init ())
1242 set_menu_state (popup, ID_KEYCTX_SENDMAIL, MF_DISABLED|MF_GRAYED);
1243 /* Override 'Default Keyserver' with the actual name. */
1244 host = kserver_get_hostname (0, -1, &port);
1245 set_menu_text (popup, ID_KEYCTX_KS_DEFAULT, host);
1246 popup_gpg_readonly (dlg, popup);
1247 if (listview_count_items (kmi->lv, 1) > 1)
1248 popup_multiple (dlg, popup);
1249 TrackPopupMenu (popup, TPM_RIGHTALIGN, p.x, p.y, 0, dlg, NULL);
1250 DestroyMenu (popup);
1251 DestroyMenu (hm);
1252 return TRUE;
1253 }
1254 break;
1255
1256 case LVN_COLUMNCLICK:
1257 if (notify->idFrom == IDC_KEYMISC_KEYLIST) {
1258 NMLISTVIEW *nft = (LPNMLISTVIEW) lparam;
1259 int sortby = 0;
1260 switch (nft->iSubItem) {
1261 case 0: sortby = KEY_SORT_USERID; break;
1262 case 1: sortby = KEY_SORT_KEYID; break;
1263 case 2: sortby = KEY_SORT_IS_SECRET; break;
1264 case 3: sortby = KEY_SORT_LEN; break;
1265 case 5: sortby = KEY_SORT_VALIDITY; break;
1266 case 6: sortby = KEY_SORT_OTRUST; break;
1267 case 7: sortby = KEY_SORT_CREATED; break;
1268 case 8: sortby = KEY_SORT_ALGO; break;
1269 default: return TRUE; //sortby = KEY_SORT_USERID; break;
1270 }
1271
1272 if ((kmi->keylist_sortby & ~KEYLIST_SORT_DESC) == sortby)
1273 kmi->keylist_sortby ^= KEYLIST_SORT_DESC;
1274 else
1275 kmi->keylist_sortby = sortby;
1276 keylist_sort (kmi->lv, kmi->keylist_sortby);
1277 return TRUE;
1278 }
1279 break;
1280 }
1281 break;
1282
1283 case WM_WINDOWPOSCHANGING:
1284 if (((WINDOWPOS*)lparam)->cx < 400)
1285 ((WINDOWPOS*)lparam)->cx = 400;
1286 if (((WINDOWPOS*)lparam)->cy < 200)
1287 ((WINDOWPOS*)lparam)->cy = 200;
1288 return TRUE;
1289
1290 case WM_SIZE:
1291 do_resize_window (dlg, kmi);
1292 return TRUE;
1293
1294 case WM_SYSCOMMAND:
1295 if (LOWORD (wparam) == SC_CLOSE)
1296 EndDialog (dlg, TRUE);
1297 return FALSE;
1298
1299 case WM_MENUSELECT:
1300 change_edit_menu (kmi->lv, (HMENU)lparam, LOWORD (wparam));
1301 change_key_menu ((HMENU)lparam, LOWORD (wparam));
1302 break;
1303
1304 case WM_INITMENUPOPUP:
1305 if ((UINT)LOWORD (lparam) == 3) {
1306 HMENU h = (HMENU)wparam;
1307 set_menu_text_bypos (h, 0, _("New"));
1308 }
1309 return FALSE;
1310
1311 case WM_COMMAND:
1312 /* Allow at least 'Exit' in such a case. */
1313 if (gnupg_access_keyring (1) && LOWORD (wparam) != ID_KEYMISC_QUIT) {
1314 msg_box (dlg, _("Could not access public keyring"),
1315 _("Key Manager"), MB_ERR);
1316 return FALSE;
1317 }
1318 do_check_cache (kmi->lv, dlg, kmi->statbar);
1319 switch( LOWORD (wparam)) {
1320 case ID_KEYMISC_QUIT:
1321 EndDialog (dlg, TRUE);
1322 return TRUE;
1323
1324 case ID_KEYMISC_MAIL:
1325 /* XXX
1326 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_MAIL, GetDesktopWindow (),
1327 winpt_mail_proc, NULL);*/
1328 break;
1329
1330 case ID_KEYMISC_FIND:
1331 km_find_key (dlg, kmi->lv);
1332 break;
1333
1334 case ID_KEYMISC_DELETE:
1335 case ID_KEYMISC_DELETE2:
1336 if (!km_delete_keys (kmi->lv, dlg))
1337 update_status_bar (kmi->statbar, kmi->lv);
1338 return TRUE;
1339
1340 case ID_KEYMISC_SIGN:
1341 if (kmi->lv_idx == -1) {
1342 msg_box (dlg, _("Please select a key."),
1343 _("Key Manager"), MB_ERR);
1344 return TRUE;
1345 }
1346 if (km_check_key_status (kmi->lv, kmi->lv_idx))
1347 return TRUE;
1348 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1349 memset (&k, 0, sizeof (k));
1350 k.ctx = key;
1351 k.keyid = key->subkeys->keyid;
1352 dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_KEYSIGN, dlg,
1353 keysign_dlg_proc, (LPARAM)&k,
1354 _("Key Signing"), IDS_WINPT_KEYSIGN);
1355 if (k.update)
1356 update_key (kmi->lv, kmi->lv_idx, k.keyid, 0);
1357 return TRUE;
1358
1359 case ID_KEYMISC_REVCERT:
1360 if (kmi->lv_idx == -1) {
1361 msg_box (dlg, _("Please select a key."), _("Key Manager"), MB_ERR);
1362 return TRUE;
1363 }
1364 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1365 if (!key)
1366 BUG (NULL);
1367 if (!km_check_for_seckey (kmi->lv, kmi->lv_idx, NULL)) {
1368 msg_box (dlg, _("There is no secret key available!"),
1369 _("Key Manager"), MB_ERR);
1370 return TRUE;
1371 }
1372
1373 {
1374 char state[64];
1375 listview_get_item_text (kmi->lv, kmi->lv_idx, 5,
1376 state, sizeof (state) -1);
1377 if (strchr (state, 'R' )) {
1378 msg_box (dlg, _("Key already revoked!"),
1379 _("Key Manager"), MB_INFO);
1380 return TRUE;
1381 }
1382 }
1383
1384 memset (&k, 0, sizeof (k));
1385 k.key_pair = 1;
1386 k.keyid = key->subkeys->keyid+8;
1387 k.is_protected = km_check_if_protected (kmi->lv, kmi->lv_idx);
1388 dialog_box_param(glob_hinst, (LPCSTR)IDD_WINPT_KEYREVOKE, dlg,
1389 key_revoke_dlg_proc, (LPARAM)&k,
1390 _("Key Revocation Cert"), IDS_WINPT_KEYREVOKE);
1391 return TRUE;
1392
1393 case ID_KEYMISC_TRUSTPATH:
1394 if (kmi->lv_idx == -1) {
1395 msg_box (dlg, _("Please select a key."), _("Key Manager"), MB_ERR);
1396 return TRUE;
1397 }
1398 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1399 if (km_check_for_seckey (kmi->lv, kmi->lv_idx, NULL)) {
1400 msg_box (dlg, _("It does not make any sense with a key pair!"),
1401 _("Key Manager"), MB_ERR);
1402 return TRUE;
1403 }
1404 memset (&k, 0, sizeof (k));
1405 k.keyid = key->subkeys->keyid+8;
1406 k.uid = key->uids->uid;
1407 dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_KEYTRUST, dlg,
1408 keytrust_dlg_proc, (LPARAM)&k,
1409 _("List Trust Path"), IDS_WINPT_KEYTRUST);
1410 return TRUE;
1411
1412 case ID_KEYMISC_CHECKSIGS:
1413 if (kmi->lv_idx == -1) {
1414 msg_box (dlg, _("Please select a key."), _("Key Manager"), MB_ERR);
1415 return TRUE;
1416 }
1417 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1418 if (!key)
1419 BUG (NULL);
1420 memset (&k, 0, sizeof (k));
1421 k.keyid = key->subkeys->keyid+8;
1422 k.uid = key->uids->uid;
1423 k.ctx = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1424 dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_KEYSIG, dlg,
1425 keysig_dlg_proc, (LPARAM)&k,
1426 _("Key Signature List" ), IDS_WINPT_KEYSIG);
1427 return TRUE;
1428
1429 case ID_KEYMISC_PROPS:
1430 if (kmi->lv_idx == -1) {
1431 msg_box( dlg, _("Please select a key."), _("Key Manager"), MB_ERR );
1432 return TRUE;
1433 }
1434 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1435 if (!key)
1436 BUG (NULL);
1437 memset (&k, 0, sizeof (k));
1438 k.key_pair = km_check_for_seckey (kmi->lv, kmi->lv_idx, NULL)? 1 : 0;
1439 k.keyid = key->subkeys->keyid+8;
1440 k.callback.ctl = kmi->lv;
1441 k.callback.idx = kmi->lv_idx;
1442 k.is_v3 = km_key_is_v3 (kmi->lv, kmi->lv_idx);
1443 dialog_box_param( glob_hinst, (LPCSTR)IDD_WINPT_KEYPROPS, dlg,
1444 keyprops_dlg_proc, (LPARAM)&k,
1445 _("Key Properties"), IDS_WINPT_KEYPROPS );
1446 if (k.callback.new_val != 0) {
1447 t = get_key_trust_str (k.callback.new_val);
1448 listview_add_sub_item (kmi->lv, kmi->lv_idx, 6, t);
1449 }
1450 return TRUE;
1451
1452 case ID_KEYMISC_RECACHE:
1453 /* If there is already a reload request,
1454 don't bother the user with a message. */
1455 if (keycache_get_reload() == 1)
1456 l_idx = IDYES;
1457 else {
1458 char inf[256];
1459 _snprintf (inf, sizeof (inf) -1,
1460 _("This is only useful when the keyring has been "
1461 "modified (sign a key...).\n"
1462 "Do you really want to reload the keycache?"));
1463 l_idx = msg_box (dlg, inf, _("Key Manager"), MB_YESNO);
1464 }
1465 if (l_idx == IDYES) {
1466 rcs.kr_reload = rcs.kr_update = 1;
1467 rcs.tr_update = 0;
1468 DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_KEYCACHE, dlg,
1469 keycache_dlg_proc, (LPARAM)&rcs);
1470 c = keycache_get_ctx (1);
1471 if (!c)
1472 BUG (dlg);
1473 keylist_reload (kmi->lv, c, KEYLIST_LIST, KEY_SORT_USERID);
1474 refresh_keys = 0;
1475 }
1476 return TRUE;
1477
1478 case ID_KEYMISC_REBUILD:
1479 name = NULL;
1480 gpg_rebuild_cache (&name);
1481 if (name != NULL) {
1482 char *line = strchr (name, '\n');
1483 show_msg (dlg, 2000, line? name + (line-name)+1 : name);
1484 safe_free (name);
1485 }
1486 return TRUE;
1487
1488 case ID_KEYMISC_NEWKEY:
1489 memset (&genkey, 0, sizeof (genkey));
1490 dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_KEYGEN, dlg,
1491 keygen_dlg_proc, (LPARAM)&genkey, _("Key Generation"),
1492 IDS_WINPT_KEYGEN);
1493 if (genkey.newkey != NULL) {
1494 keylist_add_key (kmi->lv, KEYLIST_LIST, genkey.newkey);
1495 keylist_sort (kmi->lv, KEY_SORT_USERID);
1496 }
1497 return TRUE;
1498
1499 case ID_KEYMISC_CARDNEW:
1500 if (!scard_support) {
1501 msg_box (dlg, _("Smart Card support is not available."),
1502 _("Key Manager"), MB_INFO);
1503 return TRUE;
1504 }
1505 dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_CARD_KEYGEN, dlg,
1506 card_keygen_dlg_proc, 0, _("Card Key Generation"),
1507 IDS_WINPT_CARD_KEYGEN);
1508 /* XXX: use new code */
1509 if (keycache_get_reload ())
1510 send_cmd_id (dlg, ID_KEYMISC_RECACHE);
1511 return TRUE;
1512
1513 case ID_KEYMISC_KEYWIZARD:
1514 memset (&genkey, 0, sizeof (genkey));
1515 dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_KEYWIZARD, dlg,
1516 keygen_wizard_dlg_proc, (LPARAM)&genkey,
1517 _("Key Generation Wizard"),
1518 IDS_WINPT_KEYWIZARD);
1519 if (genkey.newkey != NULL) {
1520 keylist_add_key (kmi->lv, KEYLIST_LIST, genkey.newkey);
1521 keylist_sort (kmi->lv, KEY_SORT_USERID);
1522 }
1523 return TRUE;
1524
1525 case ID_KEYMISC_SENDRECV:
1526 memset (&genkey, 0, sizeof (genkey));
1527 dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_KEYSERVER, dlg,
1528 keyserver_dlg_proc, (LPARAM)&genkey, _("Keyserver Access"),
1529 IDS_WINPT_KEYSERVER);
1530 if (genkey.newkey != NULL) {
1531 keylist_add_key (kmi->lv, KEYLIST_LIST, genkey.newkey);
1532 keylist_sort (kmi->lv, KEY_SORT_USERID);
1533 }
1534 return TRUE;
1535
1536 case ID_KEYMISC_GPGPREFS:
1537 dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_GPGPREFS, dlg,
1538 gpgprefs_dlg_proc, 0, _("GnuPG Preferences"),
1539 IDS_WINPT_GPGPREFS);
1540 return TRUE;
1541
1542 case ID_KEYMISC_GPGOPT:
1543 dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_GPGOPT, dlg,
1544 gpgopt_dlg_proc, 0, _("GnuPG Options"),
1545 IDS_WINPT_GPGOPT);
1546 return TRUE;
1547
1548 case ID_KEYMISC_IMPORT:
1549 t = get_fileopen_dlg (dlg, _("Choose Name of the Key File"),
1550 NULL, NULL);
1551 if (t)
1552 km_file_import (dlg, t);
1553 return TRUE;
1554
1555 case ID_KEYMISC_IMPORT_HTTP:
1556 url = (struct URL_ctx_s*)get_http_file_dlg (dlg);
1557 if (url->cancel == 0)
1558 km_http_import (dlg, url->url);
1559 delete url; url=NULL;
1560 break;
1561
1562 case ID_KEYMISC_EXPORT:
1563 if (kmi->lv_idx == -1) {
1564 msg_box (dlg, _("Please select a key."),
1565 _("Key Manager"), MB_ERR);
1566 return TRUE;
1567 }
1568 if (listview_count_items (kmi->lv, 1) > 1)
1569 name = m_strdup ("Exported_GPG_Keys.asc");
1570 else {
1571 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1572 name = km_gen_export_filename (key->subkeys->keyid+8, 0);
1573 }
1574 t = get_filesave_dlg (dlg, _("Choose Name for Key File"), NULL, name);
1575 free_if_alloc (name);
1576 if (t == NULL)
1577 return TRUE;
1578 km_file_export (dlg, kmi->lv, t);
1579 return TRUE;
1580
1581 case ID_KEYMISC_EXPORT_PRIVKEY:
1582 if (kmi->lv_idx == -1) {
1583 msg_box (dlg, _("Please select a key."), _("Key Manager"), MB_ERR);
1584 return TRUE;
1585 }
1586 if( !km_check_for_seckey( kmi->lv, kmi->lv_idx, NULL ) ) {
1587 msg_box (dlg, _("There is no corresponding secret key for this key."),
1588 _("Key Manager"), MB_ERR);
1589 return TRUE;
1590 }
1591 if (listview_count_items (kmi->lv, 1) > 1) {
1592 msg_box (dlg, _("You can only export one secret key."),
1593 _("Key Manager"), MB_ERR);
1594 return TRUE;
1595 }
1596 i = msg_box (dlg,
1597 _("This operation will export your *SECRET* key!\n\n"
1598 "Never send this key to ANYONE, it should be available\n"
1599 "ONLY on your machine and you may use this function\n"
1600 "to copy the key to a safe place.\n\n"
1601 "Do you really want to export the key?"),
1602 _("WARNING"), MB_INFO|MB_YESNO);
1603 if (i == IDYES) {
1604 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1605 if (!key)
1606 BUG (NULL);
1607 name = km_gen_export_filename (key->subkeys->keyid+8, 1);
1608 t = get_filesave_dlg (dlg, _("Choose Name for Key File"), NULL, name);
1609 if (t != NULL)
1610 km_privkey_export (dlg, kmi->lv, t);
1611 }
1612 return TRUE;
1613
1614 case ID_KEYMISC_INFO:
1615 dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_ABOUT, glob_hwnd,
1616 about_winpt_dlg_proc, 0, _("About WinPT"),
1617 IDS_WINPT_ABOUT);
1618 break;
1619
1620 case ID_KEYMISC_WEBSITE:
1621 ShellExecute (dlg, "open", "http://www.winpt.org",
1622 NULL, NULL, SW_SHOW);
1623 break;
1624
1625 case ID_KEYMISC_HELP:
1626 start_help (dlg, 0);
1627 break;
1628
1629 case ID_KEYMISC_OT:
1630 dialog_box_param (glob_hinst, (LPCTSTR)IDD_WINPT_OWNERTRUST,
1631 glob_hwnd, ownertrust_dlg_proc, 0,
1632 _("Ownertrust"), IDS_WINPT_OWNERTRUST);
1633 break;
1634
1635 case ID_KEYMISC_EDITKEY:
1636 if (kmi->lv_idx == -1)
1637 break;
1638 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1639 if (!key)
1640 BUG (NULL);
1641 /* XXX: pub/crd = secret key does not work */
1642 memset (&k, 0, sizeof (k));
1643 k.is_protected = km_check_if_protected (kmi->lv, kmi->lv_idx);
1644 k.key_pair = km_check_for_seckey (kmi->lv, kmi->lv_idx, NULL);
1645 k.keyid = key->subkeys->keyid+8;
1646 k.is_v3 = km_key_is_v3 (kmi->lv, kmi->lv_idx);
1647 k.flags = km_get_key_status (kmi->lv, kmi->lv_idx);
1648 dialog_box_param (glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT, dlg,
1649 keyedit_main_dlg_proc, (LPARAM)&k,
1650 _("Key Edit"), IDS_KEYCTX_EDIT);
1651 if (k.update)
1652 update_key (kmi->lv, kmi->lv_idx, k.keyid, 1);
1653 break;
1654
1655 case ID_KEYMISC_COPY:
1656 km_clip_export (dlg, kmi->lv);
1657 break;
1658
1659 case ID_KEYMISC_SELALL:
1660 listview_select_all (kmi->lv);
1661 break;
1662
1663 case ID_KEYMISC_PASTE:
1664 km_clip_import (dlg);
1665 break;
1666
1667 case ID_KEYCTX_SETPREFKS:
1668 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1669 if (!key)
1670 BUG (NULL);
1671 memset (&k, 0, sizeof (k));
1672 k.keyid = key->subkeys->keyid+8;
1673 keyedit_set_pref_keyserver (&k, dlg);
1674 break;
1675
1676 case ID_KEYMISC_REFRESH_KEYS:
1677 if (listview_count_items (kmi->lv, 1) == 0) {
1678 msg_box (dlg, _("No key was selected, select all by default."),
1679 _("Key Manager"), MB_INFO);
1680 listview_select_all (kmi->lv);
1681 }
1682 km_refresh_from_keyserver (kmi->lv, dlg);
1683 break;
1684
1685 /** Context menu **/
1686 case ID_KEYCTX_EDIT:
1687 send_cmd_id( dlg, ID_KEYMISC_EDITKEY );
1688 break;
1689
1690 case ID_KEYCTX_PROPS:
1691 send_cmd_id( dlg, ID_KEYMISC_PROPS );
1692 break;
1693
1694 case ID_KEYCTX_UIDS:
1695 send_cmd_id( dlg, ID_KEYMISC_UID );
1696 break;
1697
1698 case ID_KEYCTX_SIGN:
1699 send_cmd_id( dlg, ID_KEYMISC_SIGN );
1700 break;
1701
1702 case ID_KEYCTX_DEL:
1703 send_cmd_id (dlg, ID_KEYMISC_DELETE);
1704 break;
1705
1706 case ID_KEYCTX_REV:
1707 send_cmd_id( dlg, ID_KEYMISC_REVCERT );
1708 break;
1709
1710 case ID_KEYCTX_SENDMAIL:
1711 km_send_to_mail_recipient (kmi->lv, dlg);
1712 break;
1713
1714 case ID_KEYCTX_KS_DEFAULT:
1715 host = kserver_get_hostname (0, -1, &port);
1716 km_send_to_keyserver (kmi->lv, dlg, host, port);
1717 break;
1718
1719 case ID_KEYCTX_ADDKEY:
1720 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1721 if (!key)
1722 BUG (NULL);
1723 memset (&k, 0, sizeof (k));
1724 k.key_pair = km_check_for_seckey (kmi->lv, kmi->lv_idx, NULL);
1725 k.is_protected = km_check_if_protected (kmi->lv, kmi->lv_idx);
1726 k.keyid = key->subkeys->keyid+8;
1727 keyedit_add_subkey (&k, dlg, NULL);
1728 if (k.update)
1729 update_key (kmi->lv, kmi->lv_idx, k.keyid, 1);
1730 break;
1731
1732 case ID_KEYCTX_ADDUID:
1733 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1734 if (!key)
1735 BUG (NULL);
1736 memset (&k, 0, sizeof (k));
1737 k.key_pair = km_check_for_seckey (kmi->lv, kmi->lv_idx, NULL);
1738 k.is_protected = km_check_if_protected (kmi->lv, kmi->lv_idx);
1739 k.keyid = key->subkeys->keyid+8;
1740 keyedit_add_userid (&k, dlg, NULL);
1741 if (k.update)
1742 update_key (kmi->lv, kmi->lv_idx, k.keyid, 1);
1743 break;
1744
1745 case ID_KEYCTX_ADDREV:
1746 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1747 if (!key)
1748 BUG (NULL);
1749 memset (&k, 0, sizeof (k));
1750 k.keyid = key->subkeys->keyid+8;
1751 k.is_protected = km_check_if_protected (kmi->lv, kmi->lv_idx);
1752 k.key_pair = km_check_for_seckey (kmi->lv, kmi->lv_idx, NULL);
1753 keyedit_add_revoker (&k, dlg);
1754 if (k.update)
1755 update_key (kmi->lv, kmi->lv_idx, k.keyid, 1);
1756 break;
1757
1758 case ID_KEYCTX_ADDPHOTO:
1759 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1760 if (!key)
1761 BUG (NULL);
1762 memset (&k, 0, sizeof (k));
1763 k.keyid = key->subkeys->keyid+8;
1764 k.is_protected = km_check_if_protected (kmi->lv, kmi->lv_idx);
1765 k.key_pair = km_check_for_seckey (kmi->lv, kmi->lv_idx, NULL);
1766 keyedit_add_photo (&k, dlg);
1767 if (k.update)
1768 update_key (kmi->lv, kmi->lv_idx, k.keyid, 1);
1769 break;
1770
1771 case ID_KEYCTX_KS_NL:
1772 case ID_KEYCTX_KS_PL:
1773 case ID_KEYCTX_KS_AT:
1774 case ID_KEYCTX_KS_DE:
1775 case ID_KEYCTX_KS_DK:
1776 case ID_KEYCTX_KS_CZ:
1777 case ID_KEYCTX_KS_ES:
1778 case ID_KEYCTX_KS_UK:
1779 host = kserver_get_hostname (LOWORD (wparam) - 40107, 0, &port);
1780 km_send_to_keyserver (kmi->lv, dlg, host, port);
1781 break;
1782
1783 case ID_KEYCTX_RECVFROM:
1784 km_refresh_from_keyserver (kmi->lv, dlg);
1785 break;
1786
1787 case ID_KEYCTX_UID_COPY:
1788 /* XXX: add generic function to support multiple selection
1789 with a callback */
1790 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1791 name = utf8_to_wincp2 (key->uids->uid);
1792 set_clip_text (NULL, name, strlen (name));
1793 safe_free (name);
1794 break;
1795
1796 case ID_KEYCTX_KEYID_COPY:
1797 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1798 set_clip_text (NULL, key->subkeys->keyid+8,
1799 strlen (key->subkeys->keyid+8));
1800 break;
1801
1802 case ID_KEYCTX_FPR_COPY:
1803 key = (gpgme_key_t) listview_get_item2 (kmi->lv, kmi->lv_idx);
1804 //t = get_key_fpr (key);
1805 t = key->subkeys->fpr;
1806 set_clip_text (NULL, t? t : "", t? strlen (t): 0);
1807 break;
1808
1809 case ID_KEYCTX_KINFO_COPY:
1810 key = (gpgme_key_t) listview_get_item2 (kmi->lv, kmi->lv_idx);
1811 if (!key)
1812 BUG (NULL);
1813 km_set_clip_info (key->subkeys->keyid+8);
1814 break;
1815
1816 case ID_KEYCTX_COPY:
1817 km_clip_export (dlg, kmi->lv);
1818 break;
1819
1820 case ID_KEYCTX_PASTE:
1821 km_clip_import (dlg);
1822 break;
1823
1824 case ID_KEYCTX_DISABLE:
1825 case ID_KEYCTX_ENABLE:
1826 i = LOWORD (wparam) == ID_KEYCTX_ENABLE? 1 : 0;
1827 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1828 if (!key)
1829 BUG (NULL);
1830 rc = km_enable_disable_key (kmi->lv, dlg, kmi->lv_idx, i);
1831 if (!rc)
1832 update_key (kmi->lv, kmi->lv_idx, key->subkeys->keyid+8, 0);
1833 /* XXX: switching a key from disabled -> enabled. does not
1834 change the validity field in the KM. */
1835 break;
1836
1837 case ID_KEYCTX_LISTSIGS:
1838 send_cmd_id (dlg, ID_KEYMISC_CHECKSIGS);
1839 break;
1840
1841 case ID_KEYCTX_MAXTRUST:
1842 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1843 if (!key)
1844 BUG (NULL);
1845 rc = km_set_implicit_trust (dlg, kmi->lv, kmi->lv_idx);
1846 if (!rc)
1847 update_key (kmi->lv, kmi->lv_idx, key->subkeys->keyid+8, 0);
1848 break;
1849
1850 case ID_KEYCTX_SETDEFKEY:
1851 if (!km_check_key_status (kmi->lv, kmi->lv_idx)) {
1852 key = (gpgme_key_t)listview_get_item2 (kmi->lv, kmi->lv_idx);
1853 rc = set_gnupg_default_key (key->subkeys->keyid+8);
1854 if (rc)
1855 msg_box (dlg, winpt_strerror (rc), _("Key Manager"), MB_ERR);
1856 update_default_key_str (kmi->statbar);
1857 }
1858 break;
1859
1860 case ID_KEYMISC_VIEWKEYID:
1861 case ID_KEYMISC_VIEWCIPHER:
1862 case ID_KEYMISC_VIEWTYPE:
1863 case ID_KEYMISC_VIEWCREAT:
1864 DWORD n;
1865
1866 hm = GetMenu (dlg);
1867 n = get_menu_state (hm, LOWORD (wparam));
1868 set_menu_state (hm, LOWORD (wparam),
1869 n & MFS_CHECKED? MFS_UNCHECKED : MFS_CHECKED);
1870 modify_listview_columns (kmi, LOWORD (wparam), !(n & MFS_CHECKED));
1871 break;
1872
1873 case ID_GROUP_NEW:
1874 case ID_GROUP_PASTE:
1875 case ID_GROUP_DELETE:
1876 /* XXX: Implement group manager. */
1877 return TRUE;
1878
1879 case IDCANCEL:
1880 EndDialog (dlg, TRUE);
1881 return TRUE;
1882 }
1883
1884 break;
1885 }
1886
1887 return FALSE;
1888 }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26