1 // HashGUI.cpp
2
3 #include "StdAfx.h"
4
5 #include "../../../Common/IntToString.h"
6 #include "../../../Common/StringConvert.h"
7
8 #include "../../../Windows/ErrorMsg.h"
9
10 #include "../FileManager/FormatUtils.h"
11 #include "../FileManager/LangUtils.h"
12 #include "../FileManager/ListViewDialog.h"
13 #include "../FileManager/OverwriteDialogRes.h"
14 #include "../FileManager/ProgressDialog2.h"
15 #include "../FileManager/ProgressDialog2Res.h"
16 #include "../FileManager/PropertyNameRes.h"
17 #include "../FileManager/resourceGui.h"
18
19 #include "HashGUI.h"
20
21 using namespace NWindows;
22
23
24
25 class CHashCallbackGUI: public CProgressThreadVirt, public IHashCallbackUI
26 {
27 UInt64 NumFiles;
28 bool _curIsFolder;
29 UString FirstFileName;
30 // UString MainPath;
31
32 CPropNameValPairs PropNameValPairs;
33
34 HRESULT ProcessVirt();
35 virtual void ProcessWasFinished_GuiVirt();
36
37 public:
38 const NWildcard::CCensor *censor;
39 const CHashOptions *options;
40
41 DECL_EXTERNAL_CODECS_LOC_VARS2;
42
CHashCallbackGUI()43 CHashCallbackGUI() {}
~CHashCallbackGUI()44 ~CHashCallbackGUI() { }
45
46 INTERFACE_IHashCallbackUI(;)
47
AddErrorMessage(DWORD systemError,const wchar_t * name)48 void AddErrorMessage(DWORD systemError, const wchar_t *name)
49 {
50 Sync.AddError_Code_Name(systemError, name);
51 }
52 };
53
54
AddValuePair(CPropNameValPairs & pairs,UINT resourceID,UInt64 value)55 void AddValuePair(CPropNameValPairs &pairs, UINT resourceID, UInt64 value)
56 {
57 CProperty &pair = pairs.AddNew();
58 AddLangString(pair.Name, resourceID);
59 char sz[32];
60 ConvertUInt64ToString(value, sz);
61 pair.Value = sz;
62 }
63
64
AddSizeValue(UString & s,UInt64 value)65 void AddSizeValue(UString &s, UInt64 value)
66 {
67 {
68 wchar_t sz[32];
69 ConvertUInt64ToString(value, sz);
70 s += MyFormatNew(IDS_FILE_SIZE, sz);
71 }
72 if (value >= (1 << 10))
73 {
74 char c;
75 if (value >= ((UInt64)10 << 30)) { value >>= 30; c = 'G'; }
76 else if (value >= (10 << 20)) { value >>= 20; c = 'M'; }
77 else { value >>= 10; c = 'K'; }
78
79 s += " (";
80 s.Add_UInt64(value);
81 s.Add_Space();
82 s += (wchar_t)c;
83 s += "iB)";
84 }
85 }
86
AddSizeValuePair(CPropNameValPairs & pairs,UINT resourceID,UInt64 value)87 void AddSizeValuePair(CPropNameValPairs &pairs, UINT resourceID, UInt64 value)
88 {
89 CProperty &pair = pairs.AddNew();
90 LangString(resourceID, pair.Name);
91 AddSizeValue(pair.Value, value);
92 }
93
94
StartScanning()95 HRESULT CHashCallbackGUI::StartScanning()
96 {
97 CProgressSync &sync = Sync;
98 sync.Set_Status(LangString(IDS_SCANNING));
99 return CheckBreak();
100 }
101
ScanProgress(const CDirItemsStat & st,const FString & path,bool isDir)102 HRESULT CHashCallbackGUI::ScanProgress(const CDirItemsStat &st, const FString &path, bool isDir)
103 {
104 return Sync.ScanProgress(st.NumFiles, st.GetTotalBytes(), path, isDir);
105 }
106
ScanError(const FString & path,DWORD systemError)107 HRESULT CHashCallbackGUI::ScanError(const FString &path, DWORD systemError)
108 {
109 AddErrorMessage(systemError, fs2us(path));
110 return CheckBreak();
111 }
112
FinishScanning(const CDirItemsStat & st)113 HRESULT CHashCallbackGUI::FinishScanning(const CDirItemsStat &st)
114 {
115 return ScanProgress(st, FString(), false);
116 }
117
CheckBreak()118 HRESULT CHashCallbackGUI::CheckBreak()
119 {
120 return Sync.CheckStop();
121 }
122
SetNumFiles(UInt64 numFiles)123 HRESULT CHashCallbackGUI::SetNumFiles(UInt64 numFiles)
124 {
125 CProgressSync &sync = Sync;
126 sync.Set_NumFilesTotal(numFiles);
127 return CheckBreak();
128 }
129
SetTotal(UInt64 size)130 HRESULT CHashCallbackGUI::SetTotal(UInt64 size)
131 {
132 CProgressSync &sync = Sync;
133 sync.Set_NumBytesTotal(size);
134 return CheckBreak();
135 }
136
SetCompleted(const UInt64 * completed)137 HRESULT CHashCallbackGUI::SetCompleted(const UInt64 *completed)
138 {
139 return Sync.Set_NumBytesCur(completed);
140 }
141
BeforeFirstFile(const CHashBundle &)142 HRESULT CHashCallbackGUI::BeforeFirstFile(const CHashBundle & /* hb */)
143 {
144 return S_OK;
145 }
146
GetStream(const wchar_t * name,bool isFolder)147 HRESULT CHashCallbackGUI::GetStream(const wchar_t *name, bool isFolder)
148 {
149 if (NumFiles == 0)
150 FirstFileName = name;
151 _curIsFolder = isFolder;
152 CProgressSync &sync = Sync;
153 sync.Set_FilePath(name, isFolder);
154 return CheckBreak();
155 }
156
OpenFileError(const FString & path,DWORD systemError)157 HRESULT CHashCallbackGUI::OpenFileError(const FString &path, DWORD systemError)
158 {
159 // if (systemError == ERROR_SHARING_VIOLATION)
160 {
161 AddErrorMessage(systemError, fs2us(path));
162 return S_FALSE;
163 }
164 // return systemError;
165 }
166
SetOperationResult(UInt64,const CHashBundle &,bool)167 HRESULT CHashCallbackGUI::SetOperationResult(UInt64 /* fileSize */, const CHashBundle & /* hb */, bool /* showHash */)
168 {
169 CProgressSync &sync = Sync;
170 if (!_curIsFolder)
171 NumFiles++;
172 sync.Set_NumFilesCur(NumFiles);
173 return CheckBreak();
174 }
175
176 static const unsigned k_DigestStringSize = k_HashCalc_DigestSize_Max * 2 + k_HashCalc_ExtraSize * 2 + 16;
177
AddHashString(CProperty & s,const CHasherState & h,unsigned digestIndex)178 static void AddHashString(CProperty &s, const CHasherState &h, unsigned digestIndex)
179 {
180 char temp[k_DigestStringSize];
181 h.WriteToString(digestIndex, temp);
182 s.Value = temp;
183 }
184
AddHashResString(CPropNameValPairs & s,const CHasherState & h,unsigned digestIndex,UInt32 resID)185 static void AddHashResString(CPropNameValPairs &s, const CHasherState &h, unsigned digestIndex, UInt32 resID)
186 {
187 CProperty &pair = s.AddNew();
188 UString &s2 = pair.Name;
189 LangString(resID, s2);
190 UString name (h.Name);
191 s2.Replace(L"CRC", name);
192 s2.Replace(L":", L"");
193 AddHashString(pair, h, digestIndex);
194 }
195
196
AddHashBundleRes(CPropNameValPairs & s,const CHashBundle & hb)197 void AddHashBundleRes(CPropNameValPairs &s, const CHashBundle &hb)
198 {
199 if (hb.NumErrors != 0)
200 AddValuePair(s, IDS_PROP_NUM_ERRORS, hb.NumErrors);
201
202 if (hb.NumFiles == 1 && hb.NumDirs == 0 && !hb.FirstFileName.IsEmpty())
203 {
204 CProperty &pair = s.AddNew();
205 LangString(IDS_PROP_NAME, pair.Name);
206 pair.Value = hb.FirstFileName;
207 }
208 else
209 {
210 if (!hb.MainName.IsEmpty())
211 {
212 CProperty &pair = s.AddNew();
213 LangString(IDS_PROP_NAME, pair.Name);
214 pair.Value = hb.MainName;
215 }
216 if (hb.NumDirs != 0)
217 AddValuePair(s, IDS_PROP_FOLDERS, hb.NumDirs);
218 AddValuePair(s, IDS_PROP_FILES, hb.NumFiles);
219 }
220
221 AddSizeValuePair(s, IDS_PROP_SIZE, hb.FilesSize);
222
223 if (hb.NumAltStreams != 0)
224 {
225 AddValuePair(s, IDS_PROP_NUM_ALT_STREAMS, hb.NumAltStreams);
226 AddSizeValuePair(s, IDS_PROP_ALT_STREAMS_SIZE, hb.AltStreamsSize);
227 }
228
229 FOR_VECTOR (i, hb.Hashers)
230 {
231 const CHasherState &h = hb.Hashers[i];
232 if (hb.NumFiles == 1 && hb.NumDirs == 0)
233 {
234 CProperty &pair = s.AddNew();
235 pair.Name += h.Name;
236 AddHashString(pair, h, k_HashCalc_Index_DataSum);
237 }
238 else
239 {
240 AddHashResString(s, h, k_HashCalc_Index_DataSum, IDS_CHECKSUM_CRC_DATA);
241 AddHashResString(s, h, k_HashCalc_Index_NamesSum, IDS_CHECKSUM_CRC_DATA_NAMES);
242 }
243 if (hb.NumAltStreams != 0)
244 {
245 AddHashResString(s, h, k_HashCalc_Index_StreamsSum, IDS_CHECKSUM_CRC_STREAMS_NAMES);
246 }
247 }
248 }
249
250
AddHashBundleRes(UString & s,const CHashBundle & hb)251 void AddHashBundleRes(UString &s, const CHashBundle &hb)
252 {
253 CPropNameValPairs pairs;
254 AddHashBundleRes(pairs, hb);
255
256 FOR_VECTOR (i, pairs)
257 {
258 const CProperty &pair = pairs[i];
259 s += pair.Name;
260 s += ": ";
261 s += pair.Value;
262 s.Add_LF();
263 }
264
265 if (hb.NumErrors == 0 && hb.Hashers.IsEmpty())
266 {
267 s.Add_LF();
268 AddLangString(s, IDS_MESSAGE_NO_ERRORS);
269 s.Add_LF();
270 }
271 }
272
273
AfterLastFile(CHashBundle & hb)274 HRESULT CHashCallbackGUI::AfterLastFile(CHashBundle &hb)
275 {
276 hb.FirstFileName = FirstFileName;
277 // MainPath
278 AddHashBundleRes(PropNameValPairs, hb);
279
280 CProgressSync &sync = Sync;
281 sync.Set_NumFilesCur(hb.NumFiles);
282
283 // CProgressMessageBoxPair &pair = GetMessagePair(hb.NumErrors != 0);
284 // pair.Message = s;
285 // LangString(IDS_CHECKSUM_INFORMATION, pair.Title);
286
287 return S_OK;
288 }
289
290
ProcessVirt()291 HRESULT CHashCallbackGUI::ProcessVirt()
292 {
293 NumFiles = 0;
294 AString errorInfo;
295 HRESULT res = HashCalc(EXTERNAL_CODECS_LOC_VARS
296 *censor, *options, errorInfo, this);
297 return res;
298 }
299
300
HashCalcGUI(DECL_EXTERNAL_CODECS_LOC_VARS const NWildcard::CCensor & censor,const CHashOptions & options,bool & messageWasDisplayed)301 HRESULT HashCalcGUI(
302 DECL_EXTERNAL_CODECS_LOC_VARS
303 const NWildcard::CCensor &censor,
304 const CHashOptions &options,
305 bool &messageWasDisplayed)
306 {
307 CHashCallbackGUI t;
308 #ifdef EXTERNAL_CODECS
309 t.__externalCodecs = __externalCodecs;
310 #endif
311 t.censor = &censor;
312 t.options = &options;
313
314 t.ShowCompressionInfo = false;
315
316 const UString title = LangString(IDS_CHECKSUM_CALCULATING);
317
318 t.MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE);
319 t.MainAddTitle = title;
320 t.MainAddTitle.Add_Space();
321
322 RINOK(t.Create(title));
323 messageWasDisplayed = t.ThreadFinishedOK && t.MessagesDisplayed;
324 return S_OK;
325 }
326
327
ShowHashResults(const CPropNameValPairs & propPairs,HWND hwnd)328 void ShowHashResults(const CPropNameValPairs &propPairs, HWND hwnd)
329 {
330 CListViewDialog lv;
331
332 FOR_VECTOR (i, propPairs)
333 {
334 const CProperty &pair = propPairs[i];
335 lv.Strings.Add(pair.Name);
336 lv.Values.Add(pair.Value);
337 }
338
339 lv.Title = LangString(IDS_CHECKSUM_INFORMATION);
340 lv.DeleteIsAllowed = true;
341 lv.SelectFirst = false;
342 lv.NumColumns = 2;
343
344 lv.Create(hwnd);
345 }
346
347
ShowHashResults(const CHashBundle & hb,HWND hwnd)348 void ShowHashResults(const CHashBundle &hb, HWND hwnd)
349 {
350 CPropNameValPairs propPairs;
351 AddHashBundleRes(propPairs, hb);
352 ShowHashResults(propPairs, hwnd);
353 }
354
355
ProcessWasFinished_GuiVirt()356 void CHashCallbackGUI::ProcessWasFinished_GuiVirt()
357 {
358 ShowHashResults(PropNameValPairs, *this);
359 }
360