1370b324cSopenharmony_ci// HashCalc.h 2370b324cSopenharmony_ci 3370b324cSopenharmony_ci#ifndef ZIP7_INC_HASH_CALC_H 4370b324cSopenharmony_ci#define ZIP7_INC_HASH_CALC_H 5370b324cSopenharmony_ci 6370b324cSopenharmony_ci#include "../../../Common/UTFConvert.h" 7370b324cSopenharmony_ci#include "../../../Common/Wildcard.h" 8370b324cSopenharmony_ci 9370b324cSopenharmony_ci#include "../../Common/CreateCoder.h" 10370b324cSopenharmony_ci#include "../../Common/MethodProps.h" 11370b324cSopenharmony_ci 12370b324cSopenharmony_ci#include "DirItem.h" 13370b324cSopenharmony_ci#include "IFileExtractCallback.h" 14370b324cSopenharmony_ci 15370b324cSopenharmony_ciconst unsigned k_HashCalc_DigestSize_Max = 64; 16370b324cSopenharmony_ciconst unsigned k_HashCalc_ExtraSize = 8; 17370b324cSopenharmony_ciconst unsigned k_HashCalc_NumGroups = 4; 18370b324cSopenharmony_ci 19370b324cSopenharmony_ci/* 20370b324cSopenharmony_ci if (size <= 8) : upper case : reversed byte order : it shows 32-bit/64-bit number, if data contains little-endian number 21370b324cSopenharmony_ci if (size > 8) : lower case : original byte order (as big-endian byte sequence) 22370b324cSopenharmony_ci*/ 23370b324cSopenharmony_civoid HashHexToString(char *dest, const Byte *data, UInt32 size); 24370b324cSopenharmony_ci 25370b324cSopenharmony_cienum 26370b324cSopenharmony_ci{ 27370b324cSopenharmony_ci k_HashCalc_Index_Current, 28370b324cSopenharmony_ci k_HashCalc_Index_DataSum, 29370b324cSopenharmony_ci k_HashCalc_Index_NamesSum, 30370b324cSopenharmony_ci k_HashCalc_Index_StreamsSum 31370b324cSopenharmony_ci}; 32370b324cSopenharmony_ci 33370b324cSopenharmony_cistruct CHasherState 34370b324cSopenharmony_ci{ 35370b324cSopenharmony_ci CMyComPtr<IHasher> Hasher; 36370b324cSopenharmony_ci AString Name; 37370b324cSopenharmony_ci UInt32 DigestSize; 38370b324cSopenharmony_ci UInt64 NumSums[k_HashCalc_NumGroups]; 39370b324cSopenharmony_ci Byte Digests[k_HashCalc_NumGroups][k_HashCalc_DigestSize_Max + k_HashCalc_ExtraSize]; 40370b324cSopenharmony_ci 41370b324cSopenharmony_ci void InitDigestGroup(unsigned groupIndex) 42370b324cSopenharmony_ci { 43370b324cSopenharmony_ci NumSums[groupIndex] = 0; 44370b324cSopenharmony_ci memset(Digests[groupIndex], 0, sizeof(Digests[groupIndex])); 45370b324cSopenharmony_ci } 46370b324cSopenharmony_ci 47370b324cSopenharmony_ci const Byte *GetExtraData_for_Group(unsigned groupIndex) const 48370b324cSopenharmony_ci { 49370b324cSopenharmony_ci return Digests[groupIndex] + k_HashCalc_DigestSize_Max; 50370b324cSopenharmony_ci } 51370b324cSopenharmony_ci 52370b324cSopenharmony_ci unsigned GetNumExtraBytes_for_Group(unsigned groupIndex) const 53370b324cSopenharmony_ci { 54370b324cSopenharmony_ci const Byte *p = GetExtraData_for_Group(groupIndex); 55370b324cSopenharmony_ci // we use little-endian to read extra bytes 56370b324cSopenharmony_ci for (unsigned i = k_HashCalc_ExtraSize; i != 0; i--) 57370b324cSopenharmony_ci if (p[i - 1] != 0) 58370b324cSopenharmony_ci return i; 59370b324cSopenharmony_ci return 0; 60370b324cSopenharmony_ci } 61370b324cSopenharmony_ci 62370b324cSopenharmony_ci void AddDigest(unsigned groupIndex, const Byte *data); 63370b324cSopenharmony_ci 64370b324cSopenharmony_ci void WriteToString(unsigned digestIndex, char *s) const; 65370b324cSopenharmony_ci}; 66370b324cSopenharmony_ci 67370b324cSopenharmony_ci 68370b324cSopenharmony_ciZ7_PURE_INTERFACES_BEGIN 69370b324cSopenharmony_ci 70370b324cSopenharmony_ci 71370b324cSopenharmony_ciDECLARE_INTERFACE(IHashCalc) 72370b324cSopenharmony_ci{ 73370b324cSopenharmony_ci virtual void InitForNewFile() = 0; 74370b324cSopenharmony_ci virtual void Update(const void *data, UInt32 size) = 0; 75370b324cSopenharmony_ci virtual void SetSize(UInt64 size) = 0; 76370b324cSopenharmony_ci virtual void Final(bool isDir, bool isAltStream, const UString &path) = 0; 77370b324cSopenharmony_ci}; 78370b324cSopenharmony_ci 79370b324cSopenharmony_ciZ7_PURE_INTERFACES_END 80370b324cSopenharmony_ci 81370b324cSopenharmony_cistruct CHashBundle Z7_final: public IHashCalc 82370b324cSopenharmony_ci{ 83370b324cSopenharmony_ci CObjectVector<CHasherState> Hashers; 84370b324cSopenharmony_ci 85370b324cSopenharmony_ci UInt64 NumDirs; 86370b324cSopenharmony_ci UInt64 NumFiles; 87370b324cSopenharmony_ci UInt64 NumAltStreams; 88370b324cSopenharmony_ci UInt64 FilesSize; 89370b324cSopenharmony_ci UInt64 AltStreamsSize; 90370b324cSopenharmony_ci UInt64 NumErrors; 91370b324cSopenharmony_ci 92370b324cSopenharmony_ci UInt64 CurSize; 93370b324cSopenharmony_ci 94370b324cSopenharmony_ci UString MainName; 95370b324cSopenharmony_ci UString FirstFileName; 96370b324cSopenharmony_ci 97370b324cSopenharmony_ci HRESULT SetMethods(DECL_EXTERNAL_CODECS_LOC_VARS const UStringVector &methods); 98370b324cSopenharmony_ci 99370b324cSopenharmony_ci // void Init() {} 100370b324cSopenharmony_ci CHashBundle() 101370b324cSopenharmony_ci { 102370b324cSopenharmony_ci NumDirs = NumFiles = NumAltStreams = FilesSize = AltStreamsSize = NumErrors = 0; 103370b324cSopenharmony_ci } 104370b324cSopenharmony_ci 105370b324cSopenharmony_ci void InitForNewFile() Z7_override; 106370b324cSopenharmony_ci void Update(const void *data, UInt32 size) Z7_override; 107370b324cSopenharmony_ci void SetSize(UInt64 size) Z7_override; 108370b324cSopenharmony_ci void Final(bool isDir, bool isAltStream, const UString &path) Z7_override; 109370b324cSopenharmony_ci}; 110370b324cSopenharmony_ci 111370b324cSopenharmony_ciZ7_PURE_INTERFACES_BEGIN 112370b324cSopenharmony_ci 113370b324cSopenharmony_ci// INTERFACE_IDirItemsCallback(x) 114370b324cSopenharmony_ci 115370b324cSopenharmony_ci#define Z7_IFACEN_IHashCallbackUI(x) \ 116370b324cSopenharmony_ci virtual HRESULT StartScanning() x \ 117370b324cSopenharmony_ci virtual HRESULT FinishScanning(const CDirItemsStat &st) x \ 118370b324cSopenharmony_ci virtual HRESULT SetNumFiles(UInt64 numFiles) x \ 119370b324cSopenharmony_ci virtual HRESULT SetTotal(UInt64 size) x \ 120370b324cSopenharmony_ci virtual HRESULT SetCompleted(const UInt64 *completeValue) x \ 121370b324cSopenharmony_ci virtual HRESULT CheckBreak() x \ 122370b324cSopenharmony_ci virtual HRESULT BeforeFirstFile(const CHashBundle &hb) x \ 123370b324cSopenharmony_ci virtual HRESULT GetStream(const wchar_t *name, bool isFolder) x \ 124370b324cSopenharmony_ci virtual HRESULT OpenFileError(const FString &path, DWORD systemError) x \ 125370b324cSopenharmony_ci virtual HRESULT SetOperationResult(UInt64 fileSize, const CHashBundle &hb, bool showHash) x \ 126370b324cSopenharmony_ci virtual HRESULT AfterLastFile(CHashBundle &hb) x \ 127370b324cSopenharmony_ci 128370b324cSopenharmony_ciZ7_IFACE_DECL_PURE_(IHashCallbackUI, IDirItemsCallback) 129370b324cSopenharmony_ci 130370b324cSopenharmony_ciZ7_PURE_INTERFACES_END 131370b324cSopenharmony_ci 132370b324cSopenharmony_ci 133370b324cSopenharmony_cistruct CHashOptionsLocal 134370b324cSopenharmony_ci{ 135370b324cSopenharmony_ci CBoolPair HashMode_Zero; 136370b324cSopenharmony_ci CBoolPair HashMode_Tag; 137370b324cSopenharmony_ci CBoolPair HashMode_Dirs; 138370b324cSopenharmony_ci CBoolPair HashMode_OnlyHash; 139370b324cSopenharmony_ci 140370b324cSopenharmony_ci void Init_HashOptionsLocal() 141370b324cSopenharmony_ci { 142370b324cSopenharmony_ci HashMode_Zero.Init(); 143370b324cSopenharmony_ci HashMode_Tag.Init(); 144370b324cSopenharmony_ci HashMode_Dirs.Init(); 145370b324cSopenharmony_ci HashMode_OnlyHash.Init(); 146370b324cSopenharmony_ci // HashMode_Dirs = true; // for debug 147370b324cSopenharmony_ci } 148370b324cSopenharmony_ci 149370b324cSopenharmony_ci CHashOptionsLocal() 150370b324cSopenharmony_ci { 151370b324cSopenharmony_ci Init_HashOptionsLocal(); 152370b324cSopenharmony_ci } 153370b324cSopenharmony_ci 154370b324cSopenharmony_ci bool ParseFlagCharOption(wchar_t c, bool val) 155370b324cSopenharmony_ci { 156370b324cSopenharmony_ci c = MyCharLower_Ascii(c); 157370b324cSopenharmony_ci if (c == 'z') HashMode_Zero.SetVal_as_Defined(val); 158370b324cSopenharmony_ci else if (c == 't') HashMode_Tag.SetVal_as_Defined(val); 159370b324cSopenharmony_ci else if (c == 'd') HashMode_Dirs.SetVal_as_Defined(val); 160370b324cSopenharmony_ci else if (c == 'h') HashMode_OnlyHash.SetVal_as_Defined(val); 161370b324cSopenharmony_ci else return false; 162370b324cSopenharmony_ci return true; 163370b324cSopenharmony_ci } 164370b324cSopenharmony_ci 165370b324cSopenharmony_ci bool ParseString(const UString &s) 166370b324cSopenharmony_ci { 167370b324cSopenharmony_ci for (unsigned i = 0; i < s.Len();) 168370b324cSopenharmony_ci { 169370b324cSopenharmony_ci const wchar_t c = s[i++]; 170370b324cSopenharmony_ci bool val = true; 171370b324cSopenharmony_ci if (i < s.Len()) 172370b324cSopenharmony_ci { 173370b324cSopenharmony_ci const wchar_t next = s[i]; 174370b324cSopenharmony_ci if (next == '-') 175370b324cSopenharmony_ci { 176370b324cSopenharmony_ci val = false; 177370b324cSopenharmony_ci i++; 178370b324cSopenharmony_ci } 179370b324cSopenharmony_ci } 180370b324cSopenharmony_ci if (!ParseFlagCharOption(c, val)) 181370b324cSopenharmony_ci return false; 182370b324cSopenharmony_ci } 183370b324cSopenharmony_ci return true; 184370b324cSopenharmony_ci } 185370b324cSopenharmony_ci}; 186370b324cSopenharmony_ci 187370b324cSopenharmony_ci 188370b324cSopenharmony_cistruct CHashOptions 189370b324cSopenharmony_ci // : public CHashOptionsLocal 190370b324cSopenharmony_ci{ 191370b324cSopenharmony_ci UStringVector Methods; 192370b324cSopenharmony_ci // UString HashFilePath; 193370b324cSopenharmony_ci 194370b324cSopenharmony_ci bool PreserveATime; 195370b324cSopenharmony_ci bool OpenShareForWrite; 196370b324cSopenharmony_ci bool StdInMode; 197370b324cSopenharmony_ci bool AltStreamsMode; 198370b324cSopenharmony_ci CBoolPair SymLinks; 199370b324cSopenharmony_ci 200370b324cSopenharmony_ci NWildcard::ECensorPathMode PathMode; 201370b324cSopenharmony_ci 202370b324cSopenharmony_ci CHashOptions(): 203370b324cSopenharmony_ci PreserveATime(false), 204370b324cSopenharmony_ci OpenShareForWrite(false), 205370b324cSopenharmony_ci StdInMode(false), 206370b324cSopenharmony_ci AltStreamsMode(false), 207370b324cSopenharmony_ci PathMode(NWildcard::k_RelatPath) {} 208370b324cSopenharmony_ci}; 209370b324cSopenharmony_ci 210370b324cSopenharmony_ci 211370b324cSopenharmony_ciHRESULT HashCalc( 212370b324cSopenharmony_ci DECL_EXTERNAL_CODECS_LOC_VARS 213370b324cSopenharmony_ci const NWildcard::CCensor &censor, 214370b324cSopenharmony_ci const CHashOptions &options, 215370b324cSopenharmony_ci AString &errorInfo, 216370b324cSopenharmony_ci IHashCallbackUI *callback); 217370b324cSopenharmony_ci 218370b324cSopenharmony_ci 219370b324cSopenharmony_ci 220370b324cSopenharmony_ci#ifndef Z7_SFX 221370b324cSopenharmony_ci 222370b324cSopenharmony_cinamespace NHash { 223370b324cSopenharmony_ci 224370b324cSopenharmony_cistruct CHashPair 225370b324cSopenharmony_ci{ 226370b324cSopenharmony_ci CByteBuffer Hash; 227370b324cSopenharmony_ci char Mode; 228370b324cSopenharmony_ci bool IsBSD; 229370b324cSopenharmony_ci bool Size_from_Arc_Defined; 230370b324cSopenharmony_ci bool Size_from_Disk_Defined; 231370b324cSopenharmony_ci AString Method; 232370b324cSopenharmony_ci AString Name; 233370b324cSopenharmony_ci 234370b324cSopenharmony_ci AString FullLine; 235370b324cSopenharmony_ci AString HashString; 236370b324cSopenharmony_ci // unsigned HashLengthInBits; 237370b324cSopenharmony_ci 238370b324cSopenharmony_ci // AString MethodName; 239370b324cSopenharmony_ci UInt64 Size_from_Arc; 240370b324cSopenharmony_ci UInt64 Size_from_Disk; 241370b324cSopenharmony_ci 242370b324cSopenharmony_ci bool IsDir() const; 243370b324cSopenharmony_ci 244370b324cSopenharmony_ci void Get_UString_Path(UString &path) const 245370b324cSopenharmony_ci { 246370b324cSopenharmony_ci path.Empty(); 247370b324cSopenharmony_ci if (!ConvertUTF8ToUnicode(Name, path)) 248370b324cSopenharmony_ci return; 249370b324cSopenharmony_ci } 250370b324cSopenharmony_ci 251370b324cSopenharmony_ci bool ParseCksum(const char *s); 252370b324cSopenharmony_ci bool Parse(const char *s); 253370b324cSopenharmony_ci 254370b324cSopenharmony_ci bool IsSupportedMode() const 255370b324cSopenharmony_ci { 256370b324cSopenharmony_ci return Mode != 'U' && Mode != '^'; 257370b324cSopenharmony_ci } 258370b324cSopenharmony_ci 259370b324cSopenharmony_ci CHashPair(): 260370b324cSopenharmony_ci Mode(0) 261370b324cSopenharmony_ci , IsBSD(false) 262370b324cSopenharmony_ci , Size_from_Arc_Defined(false) 263370b324cSopenharmony_ci , Size_from_Disk_Defined(false) 264370b324cSopenharmony_ci // , HashLengthInBits(0) 265370b324cSopenharmony_ci , Size_from_Arc(0) 266370b324cSopenharmony_ci , Size_from_Disk(0) 267370b324cSopenharmony_ci {} 268370b324cSopenharmony_ci}; 269370b324cSopenharmony_ci 270370b324cSopenharmony_ci 271370b324cSopenharmony_ciZ7_CLASS_IMP_CHandler_IInArchive_3( 272370b324cSopenharmony_ci IArchiveGetRawProps, 273370b324cSopenharmony_ci /* public IGetArchiveHashHandler, */ 274370b324cSopenharmony_ci IOutArchive, 275370b324cSopenharmony_ci ISetProperties 276370b324cSopenharmony_ci) 277370b324cSopenharmony_ci bool _isArc; 278370b324cSopenharmony_ci UInt64 _phySize; 279370b324cSopenharmony_ci CObjectVector<CHashPair> HashPairs; 280370b324cSopenharmony_ci UString _nameExtenstion; 281370b324cSopenharmony_ci // UString _method_fromName; 282370b324cSopenharmony_ci AString _pgpMethod; 283370b324cSopenharmony_ci bool _is_CksumMode; 284370b324cSopenharmony_ci bool _is_PgpMethod; 285370b324cSopenharmony_ci bool _is_ZeroMode; 286370b324cSopenharmony_ci bool _are_there_Tags; 287370b324cSopenharmony_ci bool _are_there_Dirs; 288370b324cSopenharmony_ci bool _hashSize_Defined; 289370b324cSopenharmony_ci unsigned _hashSize; 290370b324cSopenharmony_ci 291370b324cSopenharmony_ci bool _crcSize_WasSet; 292370b324cSopenharmony_ci UInt32 _crcSize; 293370b324cSopenharmony_ci UStringVector _methods; 294370b324cSopenharmony_ci 295370b324cSopenharmony_ci void ClearVars(); 296370b324cSopenharmony_ci 297370b324cSopenharmony_ci void InitProps() 298370b324cSopenharmony_ci { 299370b324cSopenharmony_ci _crcSize_WasSet = false; 300370b324cSopenharmony_ci _crcSize = 4; 301370b324cSopenharmony_ci _methods.Clear(); 302370b324cSopenharmony_ci _options.Init_HashOptionsLocal(); 303370b324cSopenharmony_ci } 304370b324cSopenharmony_ci 305370b324cSopenharmony_ci CHashOptionsLocal _options; 306370b324cSopenharmony_ci 307370b324cSopenharmony_ci bool CanUpdate() const 308370b324cSopenharmony_ci { 309370b324cSopenharmony_ci if (!_isArc || _is_PgpMethod || _is_CksumMode) 310370b324cSopenharmony_ci return false; 311370b324cSopenharmony_ci return true; 312370b324cSopenharmony_ci 313370b324cSopenharmony_ci } 314370b324cSopenharmony_ci 315370b324cSopenharmony_ci HRESULT SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value); 316370b324cSopenharmony_ci 317370b324cSopenharmony_cipublic: 318370b324cSopenharmony_ci CHandler(); 319370b324cSopenharmony_ci}; 320370b324cSopenharmony_ci 321370b324cSopenharmony_ci} 322370b324cSopenharmony_ci 323370b324cSopenharmony_civoid Codecs_AddHashArcHandler(CCodecs *codecs); 324370b324cSopenharmony_ci 325370b324cSopenharmony_ci#endif 326370b324cSopenharmony_ci 327370b324cSopenharmony_ci 328370b324cSopenharmony_ci#endif 329