diff options
Diffstat (limited to 'CPP/7zip/UI/FileManager/ExtractCallback.h')
-rw-r--r--[-rwxr-xr-x] | CPP/7zip/UI/FileManager/ExtractCallback.h | 217 |
1 files changed, 204 insertions, 13 deletions
diff --git a/CPP/7zip/UI/FileManager/ExtractCallback.h b/CPP/7zip/UI/FileManager/ExtractCallback.h index 19c29e77..71e48e5e 100755..100644 --- a/CPP/7zip/UI/FileManager/ExtractCallback.h +++ b/CPP/7zip/UI/FileManager/ExtractCallback.h @@ -3,18 +3,25 @@ #ifndef __EXTRACT_CALLBACK_H #define __EXTRACT_CALLBACK_H -#include "Common/MyCom.h" +#include "../../../../C/Alloc.h" -#include "Windows/ResourceString.h" +#include "../../../Common/MyCom.h" +#include "../../../Common/StringConvert.h" +#ifndef _SFX #include "../Agent/IFolderArchive.h" +#endif + +#include "../Common/ArchiveExtractCallback.h" #include "../Common/ArchiveOpenCallback.h" #ifndef _NO_CRYPTO #include "../../IPassword.h" #endif +#ifndef _SFX #include "IFolder.h" +#endif #include "ProgressDialog2.h" @@ -22,12 +29,145 @@ #include "LangUtils.h" #endif +#ifndef _SFX + +class CGrowBuf +{ + Byte *_items; + size_t _size; + + CGrowBuf(const CGrowBuf &buffer); + void operator=(const CGrowBuf &buffer); + +public: + bool ReAlloc_KeepData(size_t newSize, size_t keepSize) + { + void *buf = MyAlloc(newSize); + if (!buf) + return false; + memcpy(buf, _items, keepSize); + MyFree(_items); + _items = (Byte *)buf; + _size = newSize; + return true; + } + + CGrowBuf(): _items(0), _size(0) {} + ~CGrowBuf() { MyFree(_items); } + + operator Byte *() { return _items; }; + operator const Byte *() const { return _items; }; + size_t Size() const { return _size; } +}; + +struct CVirtFile +{ + CGrowBuf Data; + + UInt64 Size; // real size + UInt64 ExpectedSize; // the size from props request. 0 if unknown + + UString Name; + + bool CTimeDefined; + bool ATimeDefined; + bool MTimeDefined; + bool AttribDefined; + + bool IsDir; + bool IsAltStream; + + DWORD Attrib; + + FILETIME CTime; + FILETIME ATime; + FILETIME MTime; + + CVirtFile(): + CTimeDefined(false), + ATimeDefined(false), + MTimeDefined(false), + AttribDefined(false), + IsDir(false), + IsAltStream(false) {} +}; + +class CVirtFileSystem: + public ISequentialOutStream, + public CMyUnknownImp +{ + UInt64 _totalAllocSize; + + size_t _pos; + unsigned _numFlushed; + bool _fileIsOpen; + bool _fileMode; + COutFileStream *_outFileStreamSpec; + CMyComPtr<ISequentialOutStream> _outFileStream; +public: + CObjectVector<CVirtFile> Files; + UInt64 MaxTotalAllocSize; + FString DirPrefix; + + CVirtFile &AddNewFile() + { + if (!Files.IsEmpty()) + { + MaxTotalAllocSize -= Files.Back().Data.Size(); + } + return Files.AddNew(); + } + HRESULT CloseMemFile() + { + if (_fileMode) + { + return FlushToDisk(true); + } + CVirtFile &file = Files.Back(); + if (file.Data.Size() != file.Size) + { + file.Data.ReAlloc_KeepData((size_t)file.Size, (size_t)file.Size); + } + return S_OK; + } + + bool IsStreamInMem() const + { + if (_fileMode) + return false; + if (Files.Size() < 1 || Files[0].IsAltStream || Files[0].IsDir) + return false; + return true; + } + size_t GetMemStreamWrittenSize() const { return _pos; } + + CVirtFileSystem(): _outFileStreamSpec(NULL), MaxTotalAllocSize((UInt64)0 - 1) {} + + void Init() + { + _totalAllocSize = 0; + _fileMode = false; + _pos = 0; + _numFlushed = 0; + _fileIsOpen = false; + } + + HRESULT CloseFile(const FString &path); + HRESULT FlushToDisk(bool closeLast); + size_t GetPos() const { return _pos; } + + MY_UNKNOWN_IMP + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +#endif + class CExtractCallbackImp: - public IExtractCallbackUI, + public IExtractCallbackUI, // it includes IFolderArchiveExtractCallback public IOpenCallbackUI, - public IFolderOperationsExtractCallback, - // public IFolderArchiveExtractCallback, // mkultiple from IProgress #ifndef _SFX + public IFolderOperationsExtractCallback, + public IFolderExtractToStreamCallback, public ICompressProgressInfo, #endif #ifndef _NO_CRYPTO @@ -37,9 +177,10 @@ class CExtractCallbackImp: { HRESULT MessageError(const char *message, const FString &path); public: - MY_QUERYINTERFACE_BEGIN2(IFolderOperationsExtractCallback) - MY_QUERYINTERFACE_ENTRY(IFolderArchiveExtractCallback) + MY_QUERYINTERFACE_BEGIN2(IFolderArchiveExtractCallback) #ifndef _SFX + MY_QUERYINTERFACE_ENTRY(IFolderOperationsExtractCallback) + MY_QUERYINTERFACE_ENTRY(IFolderExtractToStreamCallback) MY_QUERYINTERFACE_ENTRY(ICompressProgressInfo) #endif #ifndef _NO_CRYPTO @@ -48,10 +189,6 @@ public: MY_QUERYINTERFACE_END MY_ADDREF_RELEASE - #ifndef _SFX - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); - #endif - INTERFACE_IProgress(;) INTERFACE_IOpenCallbackUI(;) @@ -71,13 +208,18 @@ public: HRESULT BeforeOpen(const wchar_t *name); HRESULT OpenResult(const wchar_t *name, HRESULT result, bool encrypted); + HRESULT SetError(int level, const wchar_t *name, + UInt32 errorFlags, const wchar_t *errors, + UInt32 warningFlags, const wchar_t *warnings); HRESULT ThereAreNoFiles(); HRESULT ExtractResult(HRESULT result); + HRESULT OpenTypeWarning(const wchar_t *name, const wchar_t *okType, const wchar_t *errorType); #ifndef _NO_CRYPTO HRESULT SetPassword(const UString &password); #endif + #ifndef _SFX // IFolderOperationsExtractCallback STDMETHOD(AskWrite)( const wchar_t *srcPath, @@ -90,6 +232,9 @@ public: STDMETHOD(ShowMessage)(const wchar_t *message); STDMETHOD(SetCurrentFilePath)(const wchar_t *filePath); STDMETHOD(SetNumFiles)(UInt64 numFiles); + INTERFACE_IFolderExtractToStreamCallback(;) + STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); + #endif // ICryptoGetTextPassword #ifndef _NO_CRYPTO @@ -103,9 +248,37 @@ private: UString _currentFilePath; bool _isFolder; + bool _isAltStream; + UInt64 _curSize; + bool _curSizeDefined; + UString _filePath; + // bool _extractMode; + // bool _testMode; + bool _newVirtFileWasAdded; + bool _needUpdateStat; + + HRESULT SetCurrentFilePath2(const wchar_t *filePath); - void AddErrorMessage(LPCWSTR message); + void AddError_Message(LPCWSTR message); + + #ifndef _SFX + bool _hashStreamWasUsed; + COutStreamWithHash *_hashStreamSpec; + CMyComPtr<ISequentialOutStream> _hashStream; + IHashCalc *_hashCalc; // it's for stat in Test operation + #endif + public: + + #ifndef _SFX + CVirtFileSystem *VirtFileSystemSpec; + CMyComPtr<ISequentialOutStream> VirtFileSystem; + #endif + + bool ProcessAltStreams; + + bool StreamMode; + CProgressDialog *ProgressDialog; #ifndef _SFX UInt64 NumFolders; @@ -127,12 +300,30 @@ public: PasswordIsDefined(false), PasswordWasAsked(false), #endif - OverwriteMode(NExtract::NOverwriteMode::kAskBefore) + OverwriteMode(NExtract::NOverwriteMode::kAsk), + StreamMode(false), + ProcessAltStreams(true) + #ifndef _SFX + , _hashCalc(NULL) + #endif {} ~CExtractCallbackImp(); void Init(); + #ifndef _SFX + void SetHashCalc(IHashCalc *hashCalc) { _hashCalc = hashCalc; } + + void SetHashMethods(IHashCalc *hash) + { + if (!hash) + return; + _hashStreamSpec = new COutStreamWithHash; + _hashStream = _hashStreamSpec; + _hashStreamSpec->_hash = hash; + } + #endif + bool IsOK() const { return NumArchiveErrors == 0 && !ThereAreMessageErrors; } }; |