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

Diff of /trunk/Src/wptKeyPropsDlg.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 34 by twoaday, Wed Oct 26 11:20:09 2005 UTC revision 73 by twoaday, Tue Nov 8 07:15:13 2005 UTC
# Line 1  Line 1 
1  /* wptKeyPropsDlg.cpp - WinPT key properties dialog  /* wptKeyPropsDlg.cpp - WinPT key properties dialog
2   *      Copyright (C) 2000, 2001, 2002, 2003, 2005 Timo Schulz   *      Copyright (C) 2000, 2001, 2002, 2003, 2005 Timo Schulz
3   *   *
4   * This file is part of WinPT.   * This file is part of WinPT.
5   *   *
6   * WinPT is free software; you can redistribute it and/or modify   * 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   * 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   * the Free Software Foundation; either version 2 of the License, or
9   * (at your option) any later version.   * (at your option) any later version.
10   *   *
11   * WinPT is distributed in the hope that it will be useful,   * WinPT is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU General Public License for more details.   * GNU General Public License for more details.
15   *   *
16   * You should have received a copy of the GNU General Public License   * You should have received a copy of the GNU General Public License
17   * along with WinPT; if not, write to the Free Software Foundation,   * along with WinPT; if not, write to the Free Software Foundation,
18   * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA   * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19   */   */
20    
21  #include <windows.h>  #ifdef HAVE_CONFIG_H
22    #include <config.h>
23  #include "../resource.h"  #endif
24  #include "wptErrors.h"  
25  #include "wptGPG.h"  #include <windows.h>
26  #include "wptCommonCtl.h"  
27  #include "wptContext.h" /* for passphrase_s */  #include "resource.h"
28  #include "wptNLS.h"  #include "wptErrors.h"
29  #include "wptDlgs.h"  #include "wptGPG.h"
30  #include "wptTypes.h"  #include "wptCommonCtl.h"
31  #include "wptKeylist.h"  #include "wptContext.h" /* for passphrase_s */
32  #include "wptW32API.h"  #include "wptNLS.h"
33  #include "wptVersion.h"  #include "wptDlgs.h"
34  #include "wptKeyEdit.h"  #include "wptTypes.h"
35    #include "wptKeylist.h"
36  static void  #include "wptW32API.h"
37  do_change_ownertrust (winpt_key_t k, const char *s)  #include "wptVersion.h"
38  {  #include "wptKeyEdit.h"
39      char ot[64];  
40        
41      if( strstr( s, "ultimate" ) ) {  /* Check that the key is not expired or revoked. */
42          listview_get_item_text (k->callback.ctl, k->callback.idx, 5, ot, DIM (ot)-1);  static int
43          strcpy (ot, "Ultimate");  do_check_key (gpgme_key_t key)
44          listview_add_sub_item (k->callback.ctl, k->callback.idx, 5, ot);  {
45          /* fixme: If we switch back from Ultimate to a lower level */      int okay = 0;
46      }      okay = key->expired;
47  }      if (!okay)
48            okay = key->revoked;
49        return okay;
50  /* Check that the key is not expired or revoked. */  }
51  static int  
52  do_check_key (gpgme_key_t key)  
53  {  /* Convert a trust integer into a string representation. */
54      int okay = 0;  static const char*
55      okay = key->expired;  ownertrust_to_string (int val)
56      if (!okay)  {
57          okay = key->revoked;      const char *inf;
58      return okay;      int id = val;
59  }  
60        switch (id) {
61        case 1: inf = _("Don't know");         break;
62  /* Convert a trust integer into a string representation. */      case 2: inf = _("I do NOT trust");     break;
63  static const char*      case 3: inf = _("I trust marginally"); break;
64  ownertrust_to_string (int val)      case 4: inf = _("I trust fully");      break;
65  {      case 5:
66      const char * inf;      case 6: inf = _("I trust ultimately"); break;
67      int id = val;      default:inf = _("Unknown");            break;
68      switch (id) {      }
69      case 1: inf = _("Don't know");         break;      
70      case 2: inf = _("I do NOT trust");     break;      return inf;
71      case 3: inf = _("I trust marginally"); break;  }
72      case 4: inf = _("I trust fully");      break;  
73      case 5:  
74      case 6: inf = _("I trust ultimately"); break;  /* Generate a unique temp name for the photo which
75      default:inf = _("Unknown");            break;     depends on the dialog handle and return it. */
76      }  static const char*
77        get_photo_tmpname (HWND dlg)
78      return inf;  {
79  }      static char buf[64];
80    
81        _snprintf (buf, sizeof (buf)-1, "winpt_photo_%08lX.tmp", (DWORD)dlg);
82  /* Generate a unique temp name for the photo which      return buf;
83     depends on the dialog handle and return it. */  }
84  static const char*  
85  get_photo_tmpname (HWND dlg)  
86  {  /* Load the photo from the key @key */
87      static char buf[64];  static int
88    keyprops_load_photo (HWND dlg, gpgme_key_t key, gpgme_validity_t *r_valid)
89      _snprintf (buf, sizeof (buf)-1, "winpt_photo_%08lX.tmp", (DWORD)dlg);  {
90      return buf;      winpt_key_s k;
91  }      FILE *f;
92        const BYTE *img;
93        DWORD imglen = 0;
94  /* Load the photo from the key @key */      int pos=0;
95  static int  
96  keyprops_load_photo (HWND dlg, gpgme_key_t key, gpgme_validity_t *r_valid)      winpt_get_pubkey (key->subkeys->keyid, &k);
97  {      img = k.ext->attrib.d;
98      winpt_key_s k;      imglen = k.ext->attrib.len;
99      FILE *f;      if (!k.ext->attrib.validity)
100      const BYTE *img;          get_uat_validity (key->subkeys->keyid, &k.ext->attrib.validity);
101      DWORD imglen = 0;      *r_valid = k.ext->attrib.validity;
102      int pos=0;  
103        if (!img || !imglen)
104      winpt_get_pubkey (key->subkeys->keyid, &k);          return -1;
105      img = k.ext->attrib.d;      f = fopen (get_photo_tmpname (dlg), "wb");
106      imglen = k.ext->attrib.len;      if (f) {
107      if (!k.ext->attrib.validity)          for (pos = 0; img[pos] != 0x10; pos++)
108          get_uat_validity (key->subkeys->keyid, &k.ext->attrib.validity);                  ;
109      *r_valid = k.ext->attrib.validity;          pos += 16;
110            fwrite (img + pos, 1, imglen - pos, f);
111      if (!img || !imglen)          fwrite (img, 1, imglen, f);
112          return -1;          fclose (f);
113      f = fopen (get_photo_tmpname (dlg), "wb");      }
114      if (f) {      return 0;
115          for (pos = 0; img[pos] != 0x10; pos++)  }
116                  ;  
117          pos += 16;  
118          fwrite (img + pos, 1, imglen - pos, f);  /* Display the photo in the image control in the dialog @dlg. */
119          fwrite (img, 1, imglen, f);  static int
120          fclose (f);  keyprops_show_photo (HWND dlg)
121      }  {
122      return 0;      RECT r;    
123  }      POINT p;
124        HWND h;
125    
126  /* Display the photo in the image control in the dialog @dlg. */      h = GetDlgItem (dlg, IDC_KEYPROPS_IMG);
127  static int      GetWindowRect (h, &r);
128  keyprops_show_photo (HWND dlg)      p.x = r.left + 5;
129  {      p.y = r.top - 2;
130      RECT r;          memset (&p, 0, sizeof (p));
131      POINT p;      PTD_jpg_show (h, &p, get_photo_tmpname (dlg));
132      HWND h;      
133        return 0;
134      h = GetDlgItem (dlg, IDC_KEYPROPS_IMG);  }
135      GetWindowRect (h, &r);  
136      p.x = r.left + 5;  
137      p.y = r.top - 2;  /* Return string representation of the key validity. @key. */
138      memset (&p, 0, sizeof (p));  static const char*
139      PTD_jpg_show (h, &p, get_photo_tmpname (dlg));  get_validity (gpgme_key_t key)
140        {
141      return 0;      int val;
142  }      val = key->expired;
143        if (val)
144            return _("Expired");    
145  /* Return string representation of the key validity. @key. */      val = key->revoked;
146  static const char*      if (val)
147  get_validity (gpgme_key_t key)          return _("Revoked");
148  {      val = key->disabled;
149      int val;      if (val)
150      val = key->expired;          return _("Disabled");
151      if (val)      return get_key_trust2 (NULL, key->uids->validity, 0, 0);
152          return _("Expired");      }
153      val = key->revoked;  
154      if (val)  
155          return _("Revoked");  /* Return the preferred sym. algorithm from @key as a string. */
156      return get_key_trust2 (NULL, key->uids->validity, 0, 0);  static const char*
157  }  get_pref_cipher (winpt_key_t k)
158    {
159        if (k->is_v3)
160  /* Return the preferred sym. algorithm from @key as a string. */          return "IDEA";
161  static const char*      if (!k->ext->sym_prefs)
162  get_pref_cipher (winpt_key_t k)          return "3DES";
163  {      switch (*k->ext->sym_prefs) {
164      const char *sym_prefs=NULL;          case 1: return "IDEA";
165        case 2: return "3DES";
166      if (k->is_v3)      case 3: return "CAST5";
167          return "IDEA";      case 4: return "Blowfish";
168      if (!k->ext->sym_prefs)      case 7:
169          return "3DES";      case 8:
170      switch (*k->ext->sym_prefs) {      case 9: return "AES";
171      case 1: return "IDEA";      case 10:return "Twofish";
172      case 2: return "3DES";      }
173      case 3: return "CAST5";      return "Unknown";
174      case 4: return "Blowfish";  }
175      case 7:  
176      case 8:  
177      case 9: return "AES";  /* Return true if the key has designated revokers. */
178      case 10:return "Twofish";  static bool
179      }  check_for_desig_rev (gpgme_key_t key)
180      return "Unknown";  {
181  }      winpt_key_s k;
182        memset (&k, 0, sizeof (k));
183        if (!winpt_get_pubkey (key->subkeys->keyid, &k))
184  /* Return true if the key has designated revokers. */          return k.ext->gloflags.has_desig_rev? true : false;
185  static bool      return false;
186  check_for_desig_rev (gpgme_key_t key)  }
187  {  
188      winpt_key_s k;  
189      memset (&k, 0, sizeof (k));  /* Print information (name) of the smart card. */
190      if (!winpt_get_pubkey (key->subkeys->keyid, &k))  static const char*
191          return k.ext->gloflags.has_desig_rev? true : false;  get_card_type (winpt_key_t k)
192      return false;  {    
193  }      static char buf[64];
194    
195        if (!k->ext->card_type)
196  /* Print information (name) of the smart card. */          return "";
197  static const char*      _snprintf (buf, sizeof (buf)-1, _("Card-Type: %s\r\n"), k->ext->card_type);
198  get_card_type (winpt_key_t k)      return buf;
199  {      }
200      static char buf[64];  
201    
202      if (!k->ext->card_type)  /* Display the key information for key @k.
203          return "";     Return value: gpgme key on success. */
204      _snprintf (buf, sizeof (buf)-1, _("Card-Type: %s\r\n"), k->ext->card_type);  static void
205      return buf;  display_key_info (HWND dlg, winpt_key_t k, gpgme_key_t *r_key)
206  }  {
207        struct winpt_key_s k2;
208        gpgme_key_t sk, key;
209  /* Display the key information for key @k.      char info[512];
210     Return value: gpgme key on success. */      const char *inf;
211  static void      u32 created, expires;    
212  display_key_info (HWND dlg, winpt_key_t k, gpgme_key_t *r_key)  
213  {      memset (&k2, 0, sizeof (k2));      
214      struct winpt_key_s k2;      if (k->key_pair)
215      gpgme_key_t sk, key;          winpt_get_seckey (k->keyid, &k2);
216      char info[512];      else    
217      const char *inf;          winpt_get_pubkey (k->keyid, &k2);
218      u32 created, expires;          sk = k2.ctx;        
219        if (sk)
220      memset (&k2, 0, sizeof (k2));                k->is_protected = k2.is_protected;
221      if (k->key_pair)      if (get_pubkey (k->keyid, &key))
222          winpt_get_seckey (k->keyid, &k2);          BUG (0);    
223      else          created = key->subkeys->timestamp;  
224          winpt_get_pubkey (k->keyid, &k2);      expires = key->subkeys->expires;    
225      sk = k2.ctx;              _snprintf (info, DIM (info)-1,
226      if (sk)                 _("Type: %s\r\n"
227          k->is_protected = k2.is_protected;                 "Key ID: %s\r\n"
228      if (get_pubkey (k->keyid, &key))                 "Algorithm: %s\r\n"
229          BUG (0);                     "Size: %s\r\n"
230      created = key->subkeys->timestamp;                   "Created: %s\r\n"
231      expires = key->subkeys->expires;                     "Expires: %s\r\n"
232      _snprintf (info, DIM (info)-1,                 "Validity: %s\r\n"
233                 _("Type: %s\r\n"                 "Cipher: %s\r\n"
234                 "Key ID: %s\r\n"                 "%s\r\n"),
235                 "Algorithm: %s\r\n"                 get_key_type (key),
236                 "Size: %s\r\n"                 k->keyid,
237                 "Created: %s\r\n"                 get_key_algo (key, 0),
238                 "Expires: %s\r\n"                 get_key_size (key, 0),
239                 "Validity: %s\r\n"                 get_key_created (created),
240                 "Cipher: %s\r\n"                 get_key_expire_date (expires),
241                 "%s\r\n"),                 get_validity (key),
242                 get_key_type (key),                 get_pref_cipher (&k2),
243                 k->keyid,                 get_card_type (&k2));
244                 get_key_algo (key, 0),  
245                 get_key_size (key, 0),      SetDlgItemText (dlg, IDC_KEYPROPS_INFO, info);
246                 get_key_created (created),      SetDlgItemText (dlg, IDC_KEYPROPS_FPR, get_key_fpr (key));  
247                 get_key_expire_date (expires),      inf = ownertrust_to_string (key->owner_trust);
248                 get_validity (key),      SetDlgItemText (dlg, IDC_KEYPROPS_OT, inf);
249                 get_pref_cipher (&k2),  
250                 get_card_type (&k2));      *r_key = key;
251    }
252      SetDlgItemText (dlg, IDC_KEYPROPS_INFO, info);  
253      SetDlgItemText (dlg, IDC_KEYPROPS_FPR, get_key_fpr (key));    
254      inf = ownertrust_to_string (key->owner_trust);  /* Dialog box procedure to show the key properties. */
255      SetDlgItemText (dlg, IDC_KEYPROPS_OT, inf);  BOOL CALLBACK
256    keyprops_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
257      *r_key = key;  {
258  }      static winpt_key_t k;
259        static gpgme_key_t key;
260        gpgme_validity_t valid;
261  /* Dialog box procedure to show the key properties. */      refresh_cache_s rcs = {0};
262  BOOL CALLBACK      const char *inf;
263  keyprops_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)      int rc;
264  {      
265      static winpt_key_t k;      /* XXX: static variable (k) prevent that the dialog can
266      static gpgme_key_t key;              be opened twice. */
267      gpgme_validity_t valid;      switch (msg) {
268      refresh_cache_s rcs = {0};      case WM_INITDIALOG:
269      const char *inf;          if (!lparam)
270      int cancel = 0;              dlg_fatal_error (dlg, "Could not get dialog param!");
271      int rc;          k = (winpt_key_t)lparam;
272                #ifndef LANG_DE
273      /* XXX: static variable (k) prevent that the dialog can          SetWindowText (dlg, _("Key Properties"));
274              be opened twice. */          SetDlgItemText (dlg, IDC_KEYPROPS_OT_CHANGE, _("&Change"));
275      switch (msg) {          SetDlgItemText (dlg, IDC_KEYPROPS_REVOKERS, _("&Revokers"));
276      case WM_INITDIALOG:          SetDlgItemText (dlg, IDC_KEYPROPS_CHANGE_PWD, _("Change &Passwd"));
277          if (!lparam)          SetDlgItemText (dlg, IDC_KEYPROPS_OTINF, _("Ownertrust"));
278              dlg_fatal_error (dlg, "Could not get dialog param!");          #endif  
279          k = (winpt_key_t)lparam;  
280          #ifndef LANG_DE          display_key_info (dlg, k, &key);
281          SetWindowText (dlg, _("Key Properties"));          if (!keyprops_load_photo (dlg, key, &valid)) {
282          SetDlgItemText (dlg, IDC_KEYPROPS_OT_CHANGE, _("&Change"));              k->has_photo = 1;  
283          SetDlgItemText (dlg, IDC_KEYPROPS_REVOKERS, _("&Revokers"));              if (valid < GPGME_VALIDITY_MARGINAL)
284          SetDlgItemText (dlg, IDC_KEYPROPS_CHANGE_PWD, _("Change &Passwd"));                  SetDlgItemText (dlg, IDC_KEYPROPS_IMGINF, _("Photo-ID not validated."));
285          SetDlgItemText (dlg, IDC_KEYPROPS_OTINF, _("Ownertrust"));          }
286          #endif            if (k->key_pair)
287                EnableWindow (GetDlgItem (dlg, IDC_KEYPROPS_CHANGE_PWD), TRUE);
288          display_key_info (dlg, k, &key);          if (check_for_desig_rev (key))
289          if (!keyprops_load_photo (dlg, key, &valid)) {              EnableWindow (GetDlgItem (dlg, IDC_KEYPROPS_REVOKERS), TRUE);
290              k->has_photo = 1;            center_window (dlg, NULL);
291              if (valid < GPGME_VALIDITY_MARGINAL)          SetForegroundWindow (dlg);      
292                  SetDlgItemText (dlg, IDC_KEYPROPS_IMGINF, _("Photo-ID not validated."));          return TRUE;
293          }  
294          if (k->key_pair)      case WM_DESTROY:
295              EnableWindow (GetDlgItem (dlg, IDC_KEYPROPS_CHANGE_PWD), TRUE);          remove (get_photo_tmpname (dlg));
296          if (check_for_desig_rev (key))          break;
297              EnableWindow (GetDlgItem (dlg, IDC_KEYPROPS_REVOKERS), TRUE);        
298          center_window (dlg, NULL);      case WM_PAINT:
299          SetForegroundWindow (dlg);                if (k->has_photo)
300          return TRUE;              keyprops_show_photo (dlg);
301            break;
302      case WM_DESTROY:  
303          unlink (get_photo_tmpname (dlg));      case WM_SYSCOMMAND:
304          break;          if (LOWORD (wparam) == SC_CLOSE)
305                      EndDialog (dlg, TRUE);
306      case WM_PAINT:          return FALSE;
307          if (k->has_photo)          
308              keyprops_show_photo (dlg);      case WM_COMMAND:
309          break;          switch (LOWORD (wparam)) {
310            case IDOK:
311      case WM_SYSCOMMAND:              EndDialog (dlg, TRUE);
312          if (LOWORD (wparam) == SC_CLOSE)              return TRUE;
313              EndDialog (dlg, TRUE);              
314          return FALSE;          case IDC_KEYPROPS_OT_CHANGE:
315                        if (do_check_key (key)) {
316      case WM_COMMAND:                  msg_box (dlg, _("The status of this key is 'revoked' or 'expired'.\n"
317          switch (LOWORD (wparam)) {                                  "You cannot change the ownertrust of such keys."),
318          case IDOK:                                  _("WinPT Warning"), MB_ERR);
319              EndDialog (dlg, TRUE);                  return TRUE;
320              return TRUE;              }
321                            if( !k->key_pair && key->uids->validity < 3 ) {
322          case IDC_KEYPROPS_OT_CHANGE:                  rc = msg_box( dlg, _("This is a non-valid key.\n"
323              if (do_check_key (key)) {                                       "Modifying the ownertrust has no effect on such keys.\n\n"
324                  msg_box (dlg, _("The status of this key is 'revoked' or 'expired'.\n"                                       "Do you really want to continue?"),
325                                  "You cannot change the ownertrust of such keys."),                                       _("WinPT Warning"), MB_ICONWARNING|MB_YESNO );
326                                  _("WinPT Warning"), MB_ERR);                  if (rc == IDNO)
327                  return TRUE;                      return TRUE;
328              }              }
329              if( !k->key_pair && key->uids->validity < 3 ) {              //GetDlgItemText (dlg, IDC_KEYPROPS_OT, info, sizeof info -1);
330                  rc = msg_box( dlg, _("This is a non-valid key.\n"              dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_KEYEDIT_OWNERTRUST,
331                                       "Modifying the ownertrust has no effect on such keys.\n\n"                                dlg, (DLGPROC)keyedit_ownertrust_dlg_proc,
332                                       "Do you really want to continue?"),                                (LPARAM)k, _("Change Ownertrust"),
333                                       _("WinPT Warning"), MB_ICONWARNING|MB_YESNO );                                IDS_WINPT_KEYEDIT_OWNERTRUST);
334                  if (rc == IDNO)              if (k->callback.new_val == -1) { /* Cancel */
335                      return TRUE;                  EndDialog (dlg, FALSE);
336              }                  break;
337              //GetDlgItemText (dlg, IDC_KEYPROPS_OT, info, sizeof info -1);              }
338              dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_KEYEDIT_OWNERTRUST,  
339                                dlg, (DLGPROC)keyedit_ownertrust_dlg_proc,              inf = ownertrust_to_string (k->callback.new_val);
340                                (LPARAM)k, _("Change Ownertrust"),              SetDlgItemText (dlg, IDC_KEYPROPS_OT, inf);
341                                IDS_WINPT_KEYEDIT_OWNERTRUST);              msg_box (dlg, _("Ownertrust successfully changed."),
342              if (k->callback.new_val == -1) { /* Cancel */                       _("GnuPG Status"), MB_OK);
343                  EndDialog (dlg, FALSE);              
344                  break;              /* XXX: modified ownertrust values can effect the entire
345              }                      WoT so we reload the cache. But this is very slow. */
346                memset (&rcs, 0, sizeof (rcs));
347              inf = ownertrust_to_string (k->callback.new_val);              rcs.kr_reload = 1; rcs.kr_update = 1; /* reload only keylist */
348              do_change_ownertrust (k, inf);              DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_KEYCACHE, dlg,
349              SetDlgItemText (dlg, IDC_KEYPROPS_OT, inf);                              keycache_dlg_proc, (LPARAM)&rcs);
350              msg_box (dlg, _("Ownertrust successfully changed."),              return TRUE;
351                       _("GnuPG Status"), MB_OK);              
352                        case IDC_KEYPROPS_CHANGE_PWD:
353              /* reload only the keylist */              keyedit_change_passwd (k, dlg);        
354              rcs.kr_reload = 1; rcs.kr_update = 1;              return TRUE;
355              rcs.tr_update = 0;  
356              DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_KEYCACHE, dlg,          case IDC_KEYPROPS_REVOKERS:
357                              keycache_dlg_proc, (LPARAM)&rcs);              dialog_box_param (glob_hinst, (LPCTSTR)IDD_WINPT_KEYREVOKERS, dlg,
358              return TRUE;                                key_revokers_dlg_proc, (LPARAM)key,
359                                              _("Key Revokers"), IDS_WINPT_KEY_REVOKERS);
360          case IDC_KEYPROPS_CHANGE_PWD:              break;
361              keyedit_change_passwd (k, dlg);                  }
362              return TRUE;      }
363        
364          case IDC_KEYPROPS_REVOKERS:      return FALSE;
365              dialog_box_param (glob_hinst, (LPCTSTR)IDD_WINPT_KEYREVOKERS, dlg,  }
                               key_revokers_dlg_proc, (LPARAM)key, _("Key Revokers"),  
                               IDS_WINPT_KEY_REVOKERS);  
             break;  
         }  
     }  
       
     return FALSE;  
 }  

Legend:
Removed from v.34  
changed lines
  Added in v.73

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26