xref: /aosp_15_r20/external/lzma/CPP/7zip/UI/GUI/HashGUI.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
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