| // HashCalc.h |
| |
| #ifndef ZIP7_INC_HASH_CALC_H |
| #define ZIP7_INC_HASH_CALC_H |
| |
| #include "../../../Common/UTFConvert.h" |
| #include "../../../Common/Wildcard.h" |
| |
| #include "../../Common/CreateCoder.h" |
| #include "../../Common/MethodProps.h" |
| |
| #include "DirItem.h" |
| #include "IFileExtractCallback.h" |
| |
| const unsigned k_HashCalc_DigestSize_Max = 64; |
| const unsigned k_HashCalc_ExtraSize = 8; |
| const unsigned k_HashCalc_NumGroups = 4; |
| |
| /* |
| if (size <= 8) : upper case : reversed byte order : it shows 32-bit/64-bit number, if data contains little-endian number |
| if (size > 8) : lower case : original byte order (as big-endian byte sequence) |
| */ |
| void HashHexToString(char *dest, const Byte *data, UInt32 size); |
| |
| enum |
| { |
| k_HashCalc_Index_Current, |
| k_HashCalc_Index_DataSum, |
| k_HashCalc_Index_NamesSum, |
| k_HashCalc_Index_StreamsSum |
| }; |
| |
| struct CHasherState |
| { |
| CMyComPtr<IHasher> Hasher; |
| AString Name; |
| UInt32 DigestSize; |
| UInt64 NumSums[k_HashCalc_NumGroups]; |
| Byte Digests[k_HashCalc_NumGroups][k_HashCalc_DigestSize_Max + k_HashCalc_ExtraSize]; |
| |
| void InitDigestGroup(unsigned groupIndex) |
| { |
| NumSums[groupIndex] = 0; |
| memset(Digests[groupIndex], 0, sizeof(Digests[groupIndex])); |
| } |
| |
| const Byte *GetExtraData_for_Group(unsigned groupIndex) const |
| { |
| return Digests[groupIndex] + k_HashCalc_DigestSize_Max; |
| } |
| |
| unsigned GetNumExtraBytes_for_Group(unsigned groupIndex) const |
| { |
| const Byte *p = GetExtraData_for_Group(groupIndex); |
| // we use little-endian to read extra bytes |
| for (unsigned i = k_HashCalc_ExtraSize; i != 0; i--) |
| if (p[i - 1] != 0) |
| return i; |
| return 0; |
| } |
| |
| void AddDigest(unsigned groupIndex, const Byte *data); |
| |
| void WriteToString(unsigned digestIndex, char *s) const; |
| }; |
| |
| |
| Z7_PURE_INTERFACES_BEGIN |
| |
| |
| DECLARE_INTERFACE(IHashCalc) |
| { |
| virtual void InitForNewFile() = 0; |
| virtual void Update(const void *data, UInt32 size) = 0; |
| virtual void SetSize(UInt64 size) = 0; |
| virtual void Final(bool isDir, bool isAltStream, const UString &path) = 0; |
| }; |
| |
| Z7_PURE_INTERFACES_END |
| |
| struct CHashBundle Z7_final: public IHashCalc |
| { |
| CObjectVector<CHasherState> Hashers; |
| |
| UInt64 NumDirs; |
| UInt64 NumFiles; |
| UInt64 NumAltStreams; |
| UInt64 FilesSize; |
| UInt64 AltStreamsSize; |
| UInt64 NumErrors; |
| |
| UInt64 CurSize; |
| |
| UString MainName; |
| UString FirstFileName; |
| |
| HRESULT SetMethods(DECL_EXTERNAL_CODECS_LOC_VARS const UStringVector &methods); |
| |
| // void Init() {} |
| CHashBundle() |
| { |
| NumDirs = NumFiles = NumAltStreams = FilesSize = AltStreamsSize = NumErrors = 0; |
| } |
| |
| void InitForNewFile() Z7_override; |
| void Update(const void *data, UInt32 size) Z7_override; |
| void SetSize(UInt64 size) Z7_override; |
| void Final(bool isDir, bool isAltStream, const UString &path) Z7_override; |
| }; |
| |
| Z7_PURE_INTERFACES_BEGIN |
| |
| // INTERFACE_IDirItemsCallback(x) |
| |
| #define Z7_IFACEN_IHashCallbackUI(x) \ |
| virtual HRESULT StartScanning() x \ |
| virtual HRESULT FinishScanning(const CDirItemsStat &st) x \ |
| virtual HRESULT SetNumFiles(UInt64 numFiles) x \ |
| virtual HRESULT SetTotal(UInt64 size) x \ |
| virtual HRESULT SetCompleted(const UInt64 *completeValue) x \ |
| virtual HRESULT CheckBreak() x \ |
| virtual HRESULT BeforeFirstFile(const CHashBundle &hb) x \ |
| virtual HRESULT GetStream(const wchar_t *name, bool isFolder) x \ |
| virtual HRESULT OpenFileError(const FString &path, DWORD systemError) x \ |
| virtual HRESULT SetOperationResult(UInt64 fileSize, const CHashBundle &hb, bool showHash) x \ |
| virtual HRESULT AfterLastFile(CHashBundle &hb) x \ |
| |
| Z7_IFACE_DECL_PURE_(IHashCallbackUI, IDirItemsCallback) |
| |
| Z7_PURE_INTERFACES_END |
| |
| |
| struct CHashOptionsLocal |
| { |
| CBoolPair HashMode_Zero; |
| CBoolPair HashMode_Tag; |
| CBoolPair HashMode_Dirs; |
| CBoolPair HashMode_OnlyHash; |
| |
| void Init_HashOptionsLocal() |
| { |
| HashMode_Zero.Init(); |
| HashMode_Tag.Init(); |
| HashMode_Dirs.Init(); |
| HashMode_OnlyHash.Init(); |
| // HashMode_Dirs = true; // for debug |
| } |
| |
| CHashOptionsLocal() |
| { |
| Init_HashOptionsLocal(); |
| } |
| |
| bool ParseFlagCharOption(wchar_t c, bool val) |
| { |
| c = MyCharLower_Ascii(c); |
| if (c == 'z') HashMode_Zero.SetVal_as_Defined(val); |
| else if (c == 't') HashMode_Tag.SetVal_as_Defined(val); |
| else if (c == 'd') HashMode_Dirs.SetVal_as_Defined(val); |
| else if (c == 'h') HashMode_OnlyHash.SetVal_as_Defined(val); |
| else return false; |
| return true; |
| } |
| |
| bool ParseString(const UString &s) |
| { |
| for (unsigned i = 0; i < s.Len();) |
| { |
| const wchar_t c = s[i++]; |
| bool val = true; |
| if (i < s.Len()) |
| { |
| const wchar_t next = s[i]; |
| if (next == '-') |
| { |
| val = false; |
| i++; |
| } |
| } |
| if (!ParseFlagCharOption(c, val)) |
| return false; |
| } |
| return true; |
| } |
| }; |
| |
| |
| struct CHashOptions |
| // : public CHashOptionsLocal |
| { |
| UStringVector Methods; |
| // UString HashFilePath; |
| |
| bool PreserveATime; |
| bool OpenShareForWrite; |
| bool StdInMode; |
| bool AltStreamsMode; |
| CBoolPair SymLinks; |
| |
| NWildcard::ECensorPathMode PathMode; |
| |
| CHashOptions(): |
| PreserveATime(false), |
| OpenShareForWrite(false), |
| StdInMode(false), |
| AltStreamsMode(false), |
| PathMode(NWildcard::k_RelatPath) {} |
| }; |
| |
| |
| HRESULT HashCalc( |
| DECL_EXTERNAL_CODECS_LOC_VARS |
| const NWildcard::CCensor &censor, |
| const CHashOptions &options, |
| AString &errorInfo, |
| IHashCallbackUI *callback); |
| |
| |
| |
| #ifndef Z7_SFX |
| |
| namespace NHash { |
| |
| struct CHashPair |
| { |
| CByteBuffer Hash; |
| char Mode; |
| bool IsBSD; |
| bool Size_from_Arc_Defined; |
| bool Size_from_Disk_Defined; |
| AString Method; |
| AString Name; |
| |
| AString FullLine; |
| AString HashString; |
| // unsigned HashLengthInBits; |
| |
| // AString MethodName; |
| UInt64 Size_from_Arc; |
| UInt64 Size_from_Disk; |
| |
| bool IsDir() const; |
| |
| void Get_UString_Path(UString &path) const |
| { |
| path.Empty(); |
| if (!ConvertUTF8ToUnicode(Name, path)) |
| return; |
| } |
| |
| bool ParseCksum(const char *s); |
| bool Parse(const char *s); |
| |
| bool IsSupportedMode() const |
| { |
| return Mode != 'U' && Mode != '^'; |
| } |
| |
| CHashPair(): |
| Mode(0) |
| , IsBSD(false) |
| , Size_from_Arc_Defined(false) |
| , Size_from_Disk_Defined(false) |
| // , HashLengthInBits(0) |
| , Size_from_Arc(0) |
| , Size_from_Disk(0) |
| {} |
| }; |
| |
| |
| Z7_CLASS_IMP_CHandler_IInArchive_3( |
| IArchiveGetRawProps, |
| /* public IGetArchiveHashHandler, */ |
| IOutArchive, |
| ISetProperties |
| ) |
| bool _isArc; |
| UInt64 _phySize; |
| CObjectVector<CHashPair> HashPairs; |
| UString _nameExtenstion; |
| // UString _method_fromName; |
| AString _pgpMethod; |
| bool _is_CksumMode; |
| bool _is_PgpMethod; |
| bool _is_ZeroMode; |
| bool _are_there_Tags; |
| bool _are_there_Dirs; |
| bool _hashSize_Defined; |
| unsigned _hashSize; |
| |
| bool _crcSize_WasSet; |
| UInt32 _crcSize; |
| UStringVector _methods; |
| |
| void ClearVars(); |
| |
| void InitProps() |
| { |
| _crcSize_WasSet = false; |
| _crcSize = 4; |
| _methods.Clear(); |
| _options.Init_HashOptionsLocal(); |
| } |
| |
| CHashOptionsLocal _options; |
| |
| bool CanUpdate() const |
| { |
| if (!_isArc || _is_PgpMethod || _is_CksumMode) |
| return false; |
| return true; |
| |
| } |
| |
| HRESULT SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value); |
| |
| public: |
| CHandler(); |
| }; |
| |
| } |
| |
| void Codecs_AddHashArcHandler(CCodecs *codecs); |
| |
| #endif |
| |
| |
| #endif |