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

Contents of /trunk/Src/wptMDSumDlg.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 271 - (show annotations)
Sun Nov 5 08:57:45 2006 UTC (18 years, 3 months ago) by twoaday
File size: 7346 byte(s)


1 /* wptMDSumDlg.cpp - Dialog to show hash values for files
2 * Copyright (C) 2003, 2005, 2006 Timo Schulz
3 *
4 * This file is part of WinPT.
5 *
6 * 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
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * WinPT is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with WinPT; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 */
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include <windows.h>
25 #include <stdio.h>
26
27 #include "resource.h"
28 #include "wptTypes.h"
29 #include "wptW32API.h"
30 #include "wptGPG.h"
31 #include "wptCommonCtl.h"
32 #include "wptContext.h"
33 #include "wptNLS.h"
34 #include "wptErrors.h"
35
36
37 /* maximum hash size in octets (sha256=32) */
38 #define MAX_HASHSIZE 32
39
40 /* Symbolic column IDs. */
41 enum md_col_t {COL_MD=0, COL_NAME};
42
43
44 /* A model which represents the contents of the list view. */
45 struct hashlist_model_s {
46 struct hashlist_model_s *next;
47 char *name;
48 BYTE *md;
49 DWORD mdlen;
50 };
51 typedef struct hashlist_model_s *hashlist_model_t;
52
53
54 /* Release the file list @hm. */
55 static void
56 hashmodel_release (hashlist_model_t hm)
57 {
58 hashlist_model_t t;
59
60 while (hm) {
61 t = hm->next;
62 free_if_alloc (hm->name);
63 free_if_alloc (hm->md);
64 free_if_alloc (hm);
65 hm = t;
66 }
67 }
68
69
70 /* Add a new file with the name @name to the list @hm. */
71 static hashlist_model_t
72 hashmodel_add_file (hashlist_model_t *hm, const char *name,
73 const BYTE *mdbuf, size_t mdlen)
74 {
75 hashlist_model_t t, n;
76
77 t = new hashlist_model_s;
78 if (!t)
79 BUG (NULL);
80 memset (t, 0, sizeof *t);
81 t->name = m_strdup (name);
82 t->mdlen = mdlen;
83 t->md = new BYTE[mdlen];
84 if (!t->md)
85 BUG (NULL);
86 memcpy (t->md, mdbuf, mdlen);
87 if (!*hm)
88 *hm = t;
89 else {
90 for (n = *hm; n->next; n=n->next)
91 ;
92 n->next = t;
93 }
94 return t;
95 }
96
97
98 /* Return a printable digest of the buffer @mdbuf. */
99 static const char*
100 printable_digest (BYTE *mdbuf, size_t n)
101 {
102 static char mdasc[4*MAX_HASHSIZE];
103 size_t i;
104
105 for (i = 0; i < n; i++)
106 sprintf (mdasc+2*i, "%02X", mdbuf[i]);
107 return mdasc;
108 }
109
110
111 static const char*
112 id2algo (gpgme_hash_algo_t mdalgo)
113 {
114 switch (mdalgo) {
115 case GPGME_MD_MD5: return "MD5";
116 case GPGME_MD_SHA1: return "SHA1";
117 case GPGME_MD_RMD160: return "RMD160";
118 case GPGME_MD_SHA256: return "SHA256";
119 case GPGME_MD_SHA384: return "SHA384";
120 case GPGME_MD_SHA512: return "SHA512";
121 default: break;
122 }
123 return "";
124 }
125
126
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 }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26