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