xref: /aosp_15_r20/external/lzma/CPP/7zip/UI/Common/HashCalc.h (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1 // HashCalc.h
2 
3 #ifndef ZIP7_INC_HASH_CALC_H
4 #define ZIP7_INC_HASH_CALC_H
5 
6 #include "../../../Common/UTFConvert.h"
7 #include "../../../Common/Wildcard.h"
8 
9 #include "../../Common/CreateCoder.h"
10 #include "../../Common/MethodProps.h"
11 
12 #include "DirItem.h"
13 #include "IFileExtractCallback.h"
14 
15 const unsigned k_HashCalc_DigestSize_Max = 64;
16 const unsigned k_HashCalc_ExtraSize = 8;
17 const unsigned k_HashCalc_NumGroups = 4;
18 
19 /*
20   if (size <= 8) : upper case : reversed byte order : it shows 32-bit/64-bit number, if data contains little-endian number
21   if (size >  8) : lower case : original byte order (as big-endian byte sequence)
22 */
23 void HashHexToString(char *dest, const Byte *data, size_t size);
24 
25 enum
26 {
27   k_HashCalc_Index_Current,
28   k_HashCalc_Index_DataSum,
29   k_HashCalc_Index_NamesSum,
30   k_HashCalc_Index_StreamsSum
31 };
32 
33 struct CHasherState
34 {
35   CMyComPtr<IHasher> Hasher;
36   AString Name;
37   UInt32 DigestSize;
38   UInt64 NumSums[k_HashCalc_NumGroups];
39   Byte Digests[k_HashCalc_NumGroups][k_HashCalc_DigestSize_Max + k_HashCalc_ExtraSize];
40 
InitDigestGroupCHasherState41   void InitDigestGroup(unsigned groupIndex)
42   {
43     NumSums[groupIndex] = 0;
44     memset(Digests[groupIndex], 0, sizeof(Digests[groupIndex]));
45   }
46 
GetExtraData_for_GroupCHasherState47   const Byte *GetExtraData_for_Group(unsigned groupIndex) const
48   {
49     return Digests[groupIndex] + k_HashCalc_DigestSize_Max;
50   }
51 
GetNumExtraBytes_for_GroupCHasherState52   unsigned GetNumExtraBytes_for_Group(unsigned groupIndex) const
53   {
54     const Byte *p = GetExtraData_for_Group(groupIndex);
55     // we use little-endian to read extra bytes
56     for (unsigned i = k_HashCalc_ExtraSize; i != 0; i--)
57       if (p[i - 1] != 0)
58         return i;
59     return 0;
60   }
61 
62   void AddDigest(unsigned groupIndex, const Byte *data);
63 
64   void WriteToString(unsigned digestIndex, char *s) const;
65 };
66 
67 
68 Z7_PURE_INTERFACES_BEGIN
69 
70 
DECLARE_INTERFACE(IHashCalc)71 DECLARE_INTERFACE(IHashCalc)
72 {
73   virtual void InitForNewFile() = 0;
74   virtual void Update(const void *data, UInt32 size) = 0;
75   virtual void SetSize(UInt64 size) = 0;
76   virtual void Final(bool isDir, bool isAltStream, const UString &path) = 0;
77 };
78 
79 Z7_PURE_INTERFACES_END
80 
81 struct CHashBundle Z7_final: public IHashCalc
82 {
83   CObjectVector<CHasherState> Hashers;
84 
85   UInt64 NumDirs;
86   UInt64 NumFiles;
87   UInt64 NumAltStreams;
88   UInt64 FilesSize;
89   UInt64 AltStreamsSize;
90   UInt64 NumErrors;
91 
92   UInt64 CurSize;
93 
94   UString MainName;
95   UString FirstFileName;
96 
97   HRESULT SetMethods(DECL_EXTERNAL_CODECS_LOC_VARS const UStringVector &methods);
98 
99   // void Init() {}
CHashBundleZ7_final100   CHashBundle()
101   {
102     NumDirs = NumFiles = NumAltStreams = FilesSize = AltStreamsSize = NumErrors = 0;
103   }
104 
105   void InitForNewFile() Z7_override;
106   void Update(const void *data, UInt32 size) Z7_override;
107   void SetSize(UInt64 size) Z7_override;
108   void Final(bool isDir, bool isAltStream, const UString &path) Z7_override;
109 };
110 
111 Z7_PURE_INTERFACES_BEGIN
112 
113 // INTERFACE_IDirItemsCallback(x)
114 
115 #define Z7_IFACEN_IHashCallbackUI(x) \
116   virtual HRESULT StartScanning() x \
117   virtual HRESULT FinishScanning(const CDirItemsStat &st) x \
118   virtual HRESULT SetNumFiles(UInt64 numFiles) x \
119   virtual HRESULT SetTotal(UInt64 size) x \
120   virtual HRESULT SetCompleted(const UInt64 *completeValue) x \
121   virtual HRESULT CheckBreak() x \
122   virtual HRESULT BeforeFirstFile(const CHashBundle &hb) x \
123   virtual HRESULT GetStream(const wchar_t *name, bool isFolder) x \
124   virtual HRESULT OpenFileError(const FString &path, DWORD systemError) x \
125   virtual HRESULT SetOperationResult(UInt64 fileSize, const CHashBundle &hb, bool showHash) x \
126   virtual HRESULT AfterLastFile(CHashBundle &hb) x \
127 
128 Z7_IFACE_DECL_PURE_(IHashCallbackUI, IDirItemsCallback)
129 
130 Z7_PURE_INTERFACES_END
131 
132 
133 struct CHashOptionsLocal
134 {
135   CBoolPair HashMode_Zero;
136   CBoolPair HashMode_Tag;
137   CBoolPair HashMode_Dirs;
138   CBoolPair HashMode_OnlyHash;
139 
Init_HashOptionsLocalCHashOptionsLocal140   void Init_HashOptionsLocal()
141   {
142     HashMode_Zero.Init();
143     HashMode_Tag.Init();
144     HashMode_Dirs.Init();
145     HashMode_OnlyHash.Init();
146     // HashMode_Dirs = true; // for debug
147   }
148 
CHashOptionsLocalCHashOptionsLocal149   CHashOptionsLocal()
150   {
151     Init_HashOptionsLocal();
152   }
153 
ParseFlagCharOptionCHashOptionsLocal154   bool ParseFlagCharOption(wchar_t c, bool val)
155   {
156     c = MyCharLower_Ascii(c);
157          if (c == 'z') HashMode_Zero.SetVal_as_Defined(val);
158     else if (c == 't') HashMode_Tag.SetVal_as_Defined(val);
159     else if (c == 'd') HashMode_Dirs.SetVal_as_Defined(val);
160     else if (c == 'h') HashMode_OnlyHash.SetVal_as_Defined(val);
161     else return false;
162     return true;
163   }
164 
ParseStringCHashOptionsLocal165   bool ParseString(const UString &s)
166   {
167     for (unsigned i = 0; i < s.Len();)
168     {
169       const wchar_t c = s[i++];
170       bool val = true;
171       if (i < s.Len())
172       {
173         const wchar_t next  = s[i];
174         if (next == '-')
175         {
176           val = false;
177           i++;
178         }
179       }
180       if (!ParseFlagCharOption(c, val))
181         return false;
182     }
183     return true;
184   }
185 };
186 
187 
188 struct CHashOptions
189   // : public CHashOptionsLocal
190 {
191   UStringVector Methods;
192   // UString HashFilePath;
193 
194   bool PreserveATime;
195   bool OpenShareForWrite;
196   bool StdInMode;
197   bool AltStreamsMode;
198   CBoolPair SymLinks;
199 
200   NWildcard::ECensorPathMode PathMode;
201 
CHashOptionsCHashOptions202   CHashOptions():
203       PreserveATime(false),
204       OpenShareForWrite(false),
205       StdInMode(false),
206       AltStreamsMode(false),
207       PathMode(NWildcard::k_RelatPath) {}
208 };
209 
210 
211 HRESULT HashCalc(
212     DECL_EXTERNAL_CODECS_LOC_VARS
213     const NWildcard::CCensor &censor,
214     const CHashOptions &options,
215     AString &errorInfo,
216     IHashCallbackUI *callback);
217 
218 
219 
220 #ifndef Z7_SFX
221 
222 namespace NHash {
223 
224 struct CHashPair
225 {
226   CByteBuffer Hash;
227   char Mode;
228   bool IsBSD;
229   bool Escape;
230   bool Size_from_Arc_Defined;
231   bool Size_from_Disk_Defined;
232   AString Method;
233   AString Name;
234 
235   AString FullLine;
236   AString HashString;
237   // unsigned HashLengthInBits;
238 
239   // AString MethodName;
240   UInt64 Size_from_Arc;
241   UInt64 Size_from_Disk;
242 
243   bool IsDir() const;
244 
Get_UString_PathCHashPair245   void Get_UString_Path(UString &path) const
246   {
247     path.Empty();
248     if (!ConvertUTF8ToUnicode(Name, path))
249       return;
250   }
251 
252   bool ParseCksum(const char *s);
253   bool Parse(const char *s);
254 
IsSupportedModeCHashPair255   bool IsSupportedMode() const
256   {
257     return Mode != 'U' && Mode != '^';
258   }
259 
CHashPairCHashPair260   CHashPair():
261       Mode(0)
262       , IsBSD(false)
263       , Escape(false)
264       , Size_from_Arc_Defined(false)
265       , Size_from_Disk_Defined(false)
266       // , HashLengthInBits(0)
267       , Size_from_Arc(0)
268       , Size_from_Disk(0)
269     {}
270 };
271 
272 
273 Z7_CLASS_IMP_CHandler_IInArchive_3(
274     IArchiveGetRawProps,
275     /* public IGetArchiveHashHandler, */
276     IOutArchive,
277     ISetProperties
278 )
279   bool _isArc;
280   bool _supportWindowsBackslash;
281   bool _crcSize_WasSet;
282   UInt64 _phySize;
283   CObjectVector<CHashPair> HashPairs;
284   UString _nameExtenstion;
285   // UString _method_fromName;
286   AString _pgpMethod;
287   bool _is_CksumMode;
288   bool _is_PgpMethod;
289   bool _is_ZeroMode;
290   bool _are_there_Tags;
291   bool _are_there_Dirs;
292   bool _hashSize_Defined;
293   unsigned _hashSize;
294   UInt32 _crcSize;
295   UStringVector _methods;
296   CHashOptionsLocal _options;
297 
298   void ClearVars();
299 
InitProps()300   void InitProps()
301   {
302     _supportWindowsBackslash = true;
303     _crcSize_WasSet = false;
304     _crcSize = 4;
305     _methods.Clear();
306     _options.Init_HashOptionsLocal();
307   }
308 
CanUpdate()309   bool CanUpdate() const
310   {
311     if (!_isArc || _is_PgpMethod || _is_CksumMode)
312       return false;
313     return true;
314   }
315 
316   HRESULT SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value);
317 
318 public:
319   CHandler();
320 };
321 
322 }
323 
324 void Codecs_AddHashArcHandler(CCodecs *codecs);
325 
326 #endif
327 
328 
329 #endif
330