diff options
Diffstat (limited to 'CPP/7zip/UI/Common/HashCalc.h')
-rw-r--r-- | CPP/7zip/UI/Common/HashCalc.h | 222 |
1 files changed, 218 insertions, 4 deletions
diff --git a/CPP/7zip/UI/Common/HashCalc.h b/CPP/7zip/UI/Common/HashCalc.h index b6d320b5..80a55653 100644 --- a/CPP/7zip/UI/Common/HashCalc.h +++ b/CPP/7zip/UI/Common/HashCalc.h @@ -3,15 +3,17 @@ #ifndef __HASH_CALC_H #define __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; enum @@ -27,9 +29,37 @@ struct CHasherState CMyComPtr<IHasher> Hasher; AString Name; UInt32 DigestSize; - Byte Digests[k_HashCalc_NumGroups][k_HashCalc_DigestSize_Max]; + 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; }; + + struct IHashCalc { virtual void InitForNewFile() = 0; @@ -89,9 +119,68 @@ struct IHashCallbackUI: public IDirItemsCallback INTERFACE_IHashCallbackUI(=0) }; + +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; @@ -99,7 +188,7 @@ struct CHashOptions CBoolPair SymLinks; NWildcard::ECensorPathMode PathMode; - + CHashOptions(): PreserveATime(false), OpenShareForWrite(false), @@ -108,6 +197,7 @@ struct CHashOptions PathMode(NWildcard::k_RelatPath) {}; }; + HRESULT HashCalc( DECL_EXTERNAL_CODECS_LOC_VARS const NWildcard::CCensor &censor, @@ -115,6 +205,130 @@ HRESULT HashCalc( AString &errorInfo, IHashCallbackUI *callback); -void AddHashHexToString(char *dest, const Byte *data, UInt32 size); + + +#ifndef _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) + {} +}; + + +class CHandler: + public IInArchive, + public IArchiveGetRawProps, + // public IGetArchiveHashHandler, + public IOutArchive, + public ISetProperties, + public CMyUnknownImp +{ + 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(); + + MY_UNKNOWN_IMP4( + IInArchive, + IArchiveGetRawProps, + IOutArchive, + ISetProperties + /*, IGetArchiveHashHandler */ + ) + INTERFACE_IInArchive(;) + INTERFACE_IOutArchive(;) + INTERFACE_IArchiveGetRawProps(;) + // STDMETHOD(GetArchiveHashHandler)(CHandler **handler); + STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps); +}; + +} + +void Codecs_AddHashArcHandler(CCodecs *codecs); + +#endif + #endif |