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

Diff of /trunk/Src/wptMDSumDlg.cpp

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

revision 23 by twoaday, Fri Sep 30 10:10:16 2005 UTC revision 271 by twoaday, Sun Nov 5 08:57:45 2006 UTC
# Line 1  Line 1 
1  /* wptMDSumDlg.cpp  /* wptMDSumDlg.cpp - Dialog to show hash values for files
2   *      Copyright (C) 2003, 2005 Timo Schulz   *      Copyright (C) 2003, 2005, 2006 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    #ifdef HAVE_CONFIG_H
21    #include <config.h>
22  #include <windows.h>  #endif
23  #include <stdio.h>  
24  #include "../resource.h"  #include <windows.h>
25    #include <stdio.h>
26  #include "wptTypes.h"  
27  #include "wptW32API.h"  #include "resource.h"
28  #include "wptGPG.h"  #include "wptTypes.h"
29  #include "wptCommonCtl.h"  #include "wptW32API.h"
30  #include "wptContext.h"  #include "wptGPG.h"
31  #include "wptNLS.h"  #include "wptCommonCtl.h"
32  #include "wptErrors.h"  #include "wptContext.h"
33    #include "wptNLS.h"
34    #include "wptErrors.h"
35  static const char *  
36  printable_digest( byte *mdbuf, size_t n )  
37  {  /* maximum hash size in octets (sha256=32) */
38      static char mdasc[64];  #define MAX_HASHSIZE 32
39      size_t i;  
40      for( i = 0; i < n; i++ )  /* Symbolic column IDs. */
41          sprintf( mdasc+2*i, "%02X", mdbuf[i] );  enum md_col_t {COL_MD=0, COL_NAME};
42      return mdasc;  
43  } /* printable_digest */  
44    /* A model which represents the contents of the list view. */
45    struct hashlist_model_s {
46  BOOL CALLBACK      struct hashlist_model_s *next;
47  mdsum_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)      char *name;
48  {      BYTE *md;
49      static listview_ctrl_t lv;      DWORD mdlen;
50      static struct md_file_s * md;  };
51      struct listview_column_s cols[] = {  typedef struct hashlist_model_s *hashlist_model_t;
52          {0, 264, (char *)_("Digest")},  
53          {1, 128, (char *)_("Name")},  
54          {0, 0, 0}  /* Release the file list @hm. */
55      };  static void
56      gpgme_data_t sumlist;  hashmodel_release (hashlist_model_t hm)
57      char fname[300], mdasc[64];  {
58      byte mdbuf[20];      hashlist_model_t t;
59      int i;  
60      size_t n;      while (hm) {
61            t = hm->next;
62      switch( msg ) {          free_if_alloc (hm->name);
63      case WM_INITDIALOG:          free_if_alloc (hm->md);
64          md = (md_file_s *)lparam;          free_if_alloc (hm);
65          if( !md )          hm = t;
66              BUG( NULL );              }
67          if( listview_new( &lv ) )  }
68              BUG( NULL );  
69          lv->ctrl = GetDlgItem( dlg, IDC_MDSUM_LIST );  
70          for( i = 0; i < cols[i].width; i++ )  /* Add a new file with the name @name to the list @hm. */
71              listview_add_column( lv, &cols[i] );  static hashlist_model_t
72          for( i = 0; i < listview_count_items( md->lv, 0 ); i++ ) {  hashmodel_add_file (hashlist_model_t *hm, const char *name,
73              if( listview_get_item_state( md->lv, i ) ) {                      const BYTE *mdbuf, size_t mdlen)
74                  listview_get_item_text( md->lv, i, 1, fname, sizeof (fname)-1 );  {
75                  if( !gpg_md_hash_file( md->mdalgo, fname, mdbuf, &n ) ) {      hashlist_model_t t, n;
76                      listview_add_item( lv, "" );  
77                      listview_add_sub_item( lv, 0, 0, printable_digest( mdbuf, n ) );      t = new hashlist_model_s;
78                      listview_add_sub_item( lv, 0, 1, fname );      if (!t)
79                  }          BUG (NULL);
80              }      memset (t, 0, sizeof *t);
81          }      t->name = m_strdup (name);
82          SetForegroundWindow( dlg );      t->mdlen = mdlen;
83          break;      t->md = new BYTE[mdlen];
84        if (!t->md)
85      case WM_DESTROY:          BUG (NULL);
86          if( lv ) {      memcpy (t->md, mdbuf, mdlen);
87              listview_release( lv );      if (!*hm)
88              lv = NULL;          *hm = t;
89          }      else {
90          break;          for (n = *hm; n->next; n=n->next)
91                ;
92      case WM_COMMAND:          n->next = t;
93          switch (LOWORD (wparam)) {      }
94          case IDOK:      return t;
95              EndDialog (dlg, TRUE);  }
96              break;  
97    
98          case IDC_MDSUM_COPY:  /* Return a printable digest of the buffer @mdbuf. */
99              if (gpgme_data_new (&sumlist))  static const char*
100                  BUG(0);  printable_digest (BYTE *mdbuf, size_t n)
101              if (md->mdalgo == 3) {/* rmd160 */  {
102                  const char *s = "# warning rmd160sum is not yet available\r\n";      static char mdasc[4*MAX_HASHSIZE];
103                  gpgme_data_write (sumlist, s, strlen (s));      size_t i;
104              }  
105              for (i = 0; i < listview_count_items (lv, 0); i++) {      for (i = 0; i < n; i++)
106                  listview_get_item_text (lv, i, 0, mdasc, DIM (mdasc)-1);          sprintf (mdasc+2*i, "%02X", mdbuf[i]);
107                  listview_get_item_text (lv, i, 1, fname, DIM (fname)-1);      return mdasc;
108                    }
109                  gpgme_data_write (sumlist, mdasc, strlen (mdasc));  
110                  gpgme_data_write (sumlist, " ", 1);  
111                  gpgme_data_write (sumlist, fname, strlen (fname));  static const char*
112                  gpgme_data_write (sumlist, "\r\n", 2);  id2algo (gpgme_hash_algo_t mdalgo)
113              }  {
114              const char *name = get_filename_dlg (dlg, 1, _("Select file to save checksums"), NULL, NULL);      switch (mdalgo) {
115              if (name && *name) {      case GPGME_MD_MD5:      return "MD5";
116                  gpg_data_release_and_set_file (sumlist, name);      case GPGME_MD_SHA1:     return "SHA1";
117                  log_box (_("File Manager"), MB_OK, "Checksums successfully saved in '%s'", name);      case GPGME_MD_RMD160:   return "RMD160";
118              }      case GPGME_MD_SHA256:   return "SHA256";
119              else      case GPGME_MD_SHA384:   return "SHA384";
120                  gpgme_data_release (sumlist);      case GPGME_MD_SHA512:   return "SHA512";
121              break;      default:                break;
122          }      }
123          break;      return "";
124      }  }
125      return FALSE;  
126  } /* mdsum_dlg_proc */  
127    /* Hash the selected file from the FM listview control in @md.
128       Add the results to the listview @lv. */
129    static void
130    hash_selected_files (md_file_s *md, listview_ctrl_t lv, hashlist_model_t *r_fl)
131    {
132        hashlist_model_t item;
133        BYTE mdbuf[MAX_HASHSIZE];
134        char fname[MAX_PATH+1];
135        size_t n;
136        int i;
137    
138        for (i = 0; i < listview_count_items (md->lv, 0); i++) {
139            if (!listview_get_item_state (md->lv, i))
140                continue;
141            listview_get_item_text (md->lv, i, 1, fname, DIM (fname)-1);
142            if (!gpg_md_hash_file (md->mdalgo, fname, mdbuf, &n)) {
143                item = hashmodel_add_file (r_fl, fname, mdbuf, n);
144                listview_add_item2 (lv, "", (void*)item);
145                listview_add_sub_item (lv, 0, COL_MD, printable_digest (mdbuf, n));
146                listview_add_sub_item (lv, 0, COL_NAME, fname);
147            }      
148        }
149    }
150    
151    
152    /* Return 1 if there is a tool available to check the file.
153       (sha1sum, md5sum). */
154    static int
155    tool_avail (gpgme_hash_algo_t mdalgo)
156    {
157        if (mdalgo == GPGME_MD_SHA1 || mdalgo == GPGME_MD_MD5)
158            return 1;
159        return 0;
160    }
161    
162    
163    /* Sorting callback. */
164    static int CALLBACK
165    sort_cb (LPARAM first, LPARAM second, LPARAM param)
166    {
167        hashlist_model_t a, b;
168        int sortby = (int)param;
169        int cmpres = 0;
170    
171        a = (hashlist_model_t)first;
172        b = (hashlist_model_t)second;
173        if (sortby == COL_NAME)
174            cmpres = stricmp (a->name, b->name);
175        else
176            cmpres = memcmp (a->md, b->md, a->mdlen);
177        return cmpres;
178    }
179    
180    
181    /* Dialog box procedure to show and calculate file digests. */
182    BOOL CALLBACK
183    mdsum_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
184    {
185        static listview_ctrl_t lv;
186        static struct md_file_s *md;
187        static hashlist_model_t hm = NULL;
188        struct listview_column_s cols[] = {
189            {0, 264, (char *)_("Digest")},
190            {1, 160, (char *)_("Name")},
191            {0, 0, 0}
192        };
193        gpgme_data_t sumlist = NULL;
194        const char *name, *algname;
195        char fname[MAX_PATH+64], mdasc[MAX_HASHSIZE*4];
196        int i;
197    
198        switch (msg) {
199        case WM_INITDIALOG:
200            md = (md_file_s *)lparam;
201            if (!md)
202                BUG (NULL);
203            listview_new (&lv, GetDlgItem (dlg, IDC_MDSUM_LIST));
204            for (i = 0; i < cols[i].width; i++)
205                listview_add_column (lv, &cols[i]);
206            hash_selected_files (md, lv, &hm);
207            SetDlgItemText (dlg, IDC_MDSUM_COPY, _("&Save..."));
208            SetDlgItemText (dlg, IDOK, _("&Close"));
209            SetDlgItemText (dlg, IDC_MDSUM_TOCLIP, _("Save to clipboard"));
210            SetWindowText (dlg, _("Print Message Digest"));
211            SetForegroundWindow (dlg);
212            break;
213    
214        case WM_DESTROY:
215            if (lv) {
216                listview_release (lv);
217                lv = NULL;
218            }
219            if (hm) {
220                hashmodel_release (hm);
221                hm = NULL;
222            }
223            break;
224    
225        case WM_NOTIFY:
226            if (((NMHDR *)lparam)->code == LVN_COLUMNCLICK) {
227                NMLISTVIEW *nft = (LPNMLISTVIEW) lparam;
228                ListView_SortItems (lv->ctrl, sort_cb, nft->iSubItem);
229            }
230            break;
231    
232        case WM_COMMAND:
233            switch (LOWORD (wparam)) {
234            case IDOK:
235                EndDialog (dlg, TRUE);
236                break;
237    
238            case IDCANCEL:
239                EndDialog (dlg, FALSE);
240                break;
241    
242            case IDC_MDSUM_COPY:
243                algname = id2algo ((gpgme_hash_algo_t)md->mdalgo);
244                if (gpgme_data_new (&sumlist))
245                    BUG(0);
246                if (!tool_avail ((gpgme_hash_algo_t)md->mdalgo)) {
247                    const char *s;
248    
249                    s = "#warning '";
250                    gpgme_data_write (sumlist, s, strlen (s));
251                    gpgme_data_write (sumlist, algname, strlen (algname));
252                    s = " ' sum is not yet available\r\n";
253                    gpgme_data_write (sumlist, s, strlen (s));
254                }
255                for (i = 0; i < listview_count_items (lv, 0); i++) {
256                    listview_get_item_text (lv, i, COL_MD, mdasc, DIM (mdasc)-1);
257                    listview_get_item_text (lv, i, COL_NAME, fname, DIM (fname)-1);
258                    
259                    gpgme_data_write (sumlist, mdasc, strlen (mdasc));
260                    gpgme_data_write (sumlist, " ", 1);
261                    gpgme_data_write (sumlist, fname, strlen (fname));
262                    gpgme_data_write (sumlist, "\r\n", 2);
263                }
264                if (IsDlgButtonChecked (dlg, IDC_MDSUM_TOCLIP)) {
265                    gpg_data_release_and_set_clipboard (sumlist, 0);
266                    break;
267                }
268                _snprintf (fname, DIM (fname)-1, "%s_sums.txt", algname);
269                name = get_filesave_dlg (dlg, _("Select File to Save Checksums"),
270                                         NULL, fname);
271                if (name && *name) {
272                    gpgme_error_t err;
273    
274                    err = gpg_data_release_and_set_file (sumlist, name);
275                    if (!err) {
276                        log_box (_("File Manager"), MB_OK,
277                                 _("Checksums successfully saved in '%s'"), name);
278                        sumlist = NULL;
279                    }
280                    else
281                        msg_box (dlg, gpgme_strerror (err), _("File Manager"), MB_ERR);
282                }
283                if (sumlist)
284                    gpgme_data_release (sumlist);
285                break;
286            }
287            break;
288        }
289        return FALSE;
290    }

Legend:
Removed from v.23  
changed lines
  Added in v.271

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26