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