mirror of
https://github.com/holub/mame
synced 2025-06-26 06:14:12 +03:00
329 lines
7.0 KiB
C++
329 lines
7.0 KiB
C++
// 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
|