diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2005-05-30 04:00:00 +0400 |
---|---|---|
committer | Kornel LesiĆski <kornel@geekhood.net> | 2016-05-28 02:15:41 +0300 |
commit | 3c510ba80b0bc99e4e97dc1fab24c99b94fbd4a4 (patch) | |
tree | 1312b94fb69dda8cf4e2ee7baa61f5a02c7fec50 | |
parent | 8c1b5c7b7e74c45011ed0c4084ad6b37a35e5a03 (diff) |
4.204.20
926 files changed, 40268 insertions, 23228 deletions
diff --git a/7zip/Archive/7z/7z.dsp b/7zip/Archive/7z/7z.dsp index 1199a0a1..c24ab86b 100755 --- a/7zip/Archive/7z/7z.dsp +++ b/7zip/Archive/7z/7z.dsp @@ -43,7 +43,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 1 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /c -# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /Yu"StdAfx.h" /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "NDEBUG" @@ -70,7 +70,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 1 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "_DEBUG" @@ -282,6 +282,14 @@ SOURCE=..\..\PropID.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\Buffer.h # End Source File # Begin Source File @@ -294,6 +302,10 @@ SOURCE=..\..\..\Common\CRC.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\DynamicBuffer.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\IntToString.cpp # End Source File # Begin Source File @@ -302,6 +314,14 @@ SOURCE=..\..\..\Common\IntToString.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\String.cpp # End Source File # Begin Source File @@ -346,6 +366,10 @@ SOURCE=..\Common\CodecsPath.h # End Source File # Begin Source File +SOURCE=..\Common\CoderLoader.cpp +# End Source File +# Begin Source File + SOURCE=..\Common\CoderLoader.h # End Source File # Begin Source File @@ -358,6 +382,14 @@ SOURCE=..\Common\CoderMixer2.h # End Source File # Begin Source File +SOURCE=..\Common\CoderMixer2MT.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\CoderMixer2MT.h +# End Source File +# Begin Source File + SOURCE=..\Common\CrossThreadProgress.cpp # End Source File # Begin Source File @@ -366,6 +398,14 @@ SOURCE=..\Common\CrossThreadProgress.h # End Source File # Begin Source File +SOURCE=..\Common\FilterCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\FilterCoder.h +# End Source File +# Begin Source File + SOURCE=..\Common\InStreamWithCRC.cpp # End Source File # Begin Source File @@ -382,6 +422,14 @@ SOURCE=..\Common\ItemNameUtils.h # End Source File # Begin Source File +SOURCE=..\Common\MultiStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\MultiStream.h +# End Source File +# Begin Source File + SOURCE=..\Common\OutStreamWithCRC.cpp # End Source File # Begin Source File @@ -410,11 +458,11 @@ SOURCE=..\..\Common\LimitedStreams.h # End Source File # Begin Source File -SOURCE=..\..\Common\MultiStream.cpp +SOURCE=..\..\Common\LockedStream.cpp # End Source File # Begin Source File -SOURCE=..\..\Common\MultiStream.h +SOURCE=..\..\Common\LockedStream.h # End Source File # Begin Source File diff --git a/7zip/Archive/7z/7zCompressionMode.h b/7zip/Archive/7z/7zCompressionMode.h index 400344b8..1df324b6 100755 --- a/7zip/Archive/7z/7zCompressionMode.h +++ b/7zip/Archive/7z/7zCompressionMode.h @@ -1,7 +1,5 @@ // 7zCompressionMode.h -#pragma once - #ifndef __7Z_COMPRESSION_MODE_H #define __7Z_COMPRESSION_MODE_H @@ -21,8 +19,8 @@ struct CProperty struct CMethodFull { CMethodID MethodID; - UINT32 NumInStreams; - UINT32 NumOutStreams; + UInt32 NumInStreams; + UInt32 NumOutStreams; bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); } @@ -37,10 +35,10 @@ struct CMethodFull struct CBind { - UINT32 InCoder; - UINT32 InStream; - UINT32 OutCoder; - UINT32 OutStream; + UInt32 InCoder; + UInt32 InStream; + UInt32 OutCoder; + UInt32 OutStream; }; struct CCompressionMethodMode diff --git a/7zip/Archive/7z/7zDecode.cpp b/7zip/Archive/7z/7zDecode.cpp index 13bcb444..8e1c26ea 100755 --- a/7zip/Archive/7z/7zDecode.cpp +++ b/7zip/Archive/7z/7zDecode.cpp @@ -4,16 +4,15 @@ #include "7zDecode.h" -#include "../../Common/MultiStream.h" +#include "../../IPassword.h" +#include "../../Common/LockedStream.h" #include "../../Common/StreamObjects.h" #include "../../Common/ProgressUtils.h" #include "../../Common/LimitedStreams.h" +#include "../Common/FilterCoder.h" #include "7zMethods.h" -#include "../../IPassword.h" - - #ifdef COMPRESS_LZMA #include "../../Compress/LZMA/LZMADecoder.h" static NArchive::N7z::CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 }; @@ -35,11 +34,23 @@ static NArchive::N7z::CMethodID k_BCJ2 = { { 0x3, 0x3, 0x1, 0x1B }, 4 }; #endif #ifdef COMPRESS_DEFLATE +#ifndef COMPRESS_DEFLATE_DECODER +#define COMPRESS_DEFLATE_DECODER +#endif +#endif + +#ifdef COMPRESS_DEFLATE_DECODER #include "../../Compress/Deflate/DeflateDecoder.h" static NArchive::N7z::CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 }; #endif #ifdef COMPRESS_BZIP2 +#ifndef COMPRESS_BZIP2_DECODER +#define COMPRESS_BZIP2_DECODER +#endif +#endif + +#ifdef COMPRESS_BZIP2_DECODER #include "../../Compress/BZip2/BZip2Decoder.h" static NArchive::N7z::CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 }; #endif @@ -60,35 +71,31 @@ namespace N7z { static void ConvertFolderItemInfoToBindInfo(const CFolder &folder, CBindInfoEx &bindInfo) { - bindInfo.Coders.Clear(); - bindInfo.CoderMethodIDs.Clear(); - bindInfo.OutStreams.Clear(); - bindInfo.InStreams.Clear(); - bindInfo.BindPairs.Clear(); + bindInfo.Clear(); int i; for (i = 0; i < folder.BindPairs.Size(); i++) { NCoderMixer2::CBindPair bindPair; - bindPair.InIndex = (UINT32)folder.BindPairs[i].InIndex; - bindPair.OutIndex = (UINT32)folder.BindPairs[i].OutIndex; + bindPair.InIndex = (UInt32)folder.BindPairs[i].InIndex; + bindPair.OutIndex = (UInt32)folder.BindPairs[i].OutIndex; bindInfo.BindPairs.Add(bindPair); } - UINT32 outStreamIndex = 0; + UInt32 outStreamIndex = 0; for (i = 0; i < folder.Coders.Size(); i++) { NCoderMixer2::CCoderStreamsInfo coderStreamsInfo; const CCoderInfo &coderInfo = folder.Coders[i]; - coderStreamsInfo.NumInStreams = (UINT32)coderInfo.NumInStreams; - coderStreamsInfo.NumOutStreams = (UINT32)coderInfo.NumOutStreams; + coderStreamsInfo.NumInStreams = (UInt32)coderInfo.NumInStreams; + coderStreamsInfo.NumOutStreams = (UInt32)coderInfo.NumOutStreams; bindInfo.Coders.Add(coderStreamsInfo); const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front(); bindInfo.CoderMethodIDs.Add(altCoderInfo.MethodID); - for (UINT32 j = 0; j < coderStreamsInfo.NumOutStreams; j++, outStreamIndex++) + for (UInt32 j = 0; j < coderStreamsInfo.NumOutStreams; j++, outStreamIndex++) if (folder.FindBindPairForOutStream(outStreamIndex) < 0) bindInfo.OutStreams.Add(outStreamIndex); } for (i = 0; i < folder.PackStreams.Size(); i++) - bindInfo.InStreams.Add((UINT32)folder.PackStreams[i].Index); + bindInfo.InStreams.Add((UInt32)folder.PackStreams[i]); } static bool AreCodersEqual(const NCoderMixer2::CCoderStreamsInfo &a1, @@ -127,8 +134,12 @@ static bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2) return true; } -CDecoder::CDecoder() +CDecoder::CDecoder(bool multiThread) { + _multiThread = true; + #ifdef _ST_MODE + _multiThread = multiThread; + #endif _bindInfoExPrevIsDefinded = false; #ifndef EXCLUDE_COM LoadMethodMap(); @@ -136,8 +147,8 @@ CDecoder::CDecoder() } HRESULT CDecoder::Decode(IInStream *inStream, - UINT64 startPos, - const UINT64 *packSizes, + UInt64 startPos, + const UInt64 *packSizes, const CFolder &folderInfo, ISequentialOutStream *outStream, ICompressProgressInfo *compressProgress @@ -182,11 +193,23 @@ HRESULT CDecoder::Decode(IInStream *inStream, // _decoders2.Clear(); _mixerCoder.Release(); + + if (_multiThread) + { + _mixerCoderMTSpec = new NCoderMixer2::CCoderMixer2MT; + _mixerCoder = _mixerCoderMTSpec; + _mixerCoderCommon = _mixerCoderMTSpec; + } + else + { + #ifdef _ST_MODE + _mixerCoderSTSpec = new NCoderMixer2::CCoderMixer2ST; + _mixerCoder = _mixerCoderSTSpec; + _mixerCoderCommon = _mixerCoderSTSpec; + #endif + } + _mixerCoderCommon->SetBindInfo(bindInfo); - _mixerCoderSpec = new NCoderMixer2::CCoderMixer2; - _mixerCoder = _mixerCoderSpec; - - _mixerCoderSpec->SetBindInfo(bindInfo); for (i = 0; i < numCoders; i++) { const CCoderInfo &coderInfo = folderInfo.Coders[i]; @@ -200,6 +223,7 @@ HRESULT CDecoder::Decode(IInStream *inStream, if (coderInfo.IsSimpleCoder()) { CMyComPtr<ICompressCoder> decoder; + CMyComPtr<ICompressFilter> filter; #ifdef COMPRESS_LZMA if (altCoderInfo.MethodID == k_LZMA) @@ -213,15 +237,15 @@ HRESULT CDecoder::Decode(IInStream *inStream, #ifdef COMPRESS_BCJ_X86 if (altCoderInfo.MethodID == k_BCJ_X86) - decoder = new CBCJ_x86_Decoder; + filter = new CBCJ_x86_Decoder; #endif - #ifdef COMPRESS_DEFLATE + #ifdef COMPRESS_DEFLATE_DECODER if (altCoderInfo.MethodID == k_Deflate) decoder = new NCompress::NDeflate::NDecoder::CCOMCoder; #endif - #ifdef COMPRESS_BZIP2 + #ifdef COMPRESS_BZIP2_DECODER if (altCoderInfo.MethodID == k_BZip2) decoder = new NCompress::NBZip2::CDecoder; #endif @@ -233,13 +257,19 @@ HRESULT CDecoder::Decode(IInStream *inStream, #ifdef CRYPTO_7ZAES if (altCoderInfo.MethodID == k_7zAES) - decoder = new NCrypto::NSevenZ::CDecoder; + filter = new NCrypto::NSevenZ::CDecoder; #endif + if (filter) + { + CFilterCoder *coderSpec = new CFilterCoder; + decoder = coderSpec; + coderSpec->Filter = filter; + } #ifndef EXCLUDE_COM if (decoder == 0) { - RINOK(_libraries.CreateCoder(methodInfo.FilePath, + RINOK(_libraries.CreateCoderSpec(methodInfo.FilePath, methodInfo.Decoder, &decoder)); } #endif @@ -249,7 +279,12 @@ HRESULT CDecoder::Decode(IInStream *inStream, _decoders.Add((IUnknown *)decoder); - _mixerCoderSpec->AddCoder(decoder); + if (_multiThread) + _mixerCoderMTSpec->AddCoder(decoder); + #ifdef _ST_MODE + else + _mixerCoderSTSpec->AddCoder(decoder, false); + #endif } else { @@ -272,37 +307,39 @@ HRESULT CDecoder::Decode(IInStream *inStream, return E_NOTIMPL; _decoders.Add((IUnknown *)decoder); - _mixerCoderSpec->AddCoder2(decoder); + if (_multiThread) + _mixerCoderMTSpec->AddCoder2(decoder); + #ifdef _ST_MODE + else + _mixerCoderSTSpec->AddCoder2(decoder, false); + #endif } } _bindInfoExPrev = bindInfo; _bindInfoExPrevIsDefinded = true; } int i; - _mixerCoderSpec->ReInit(); + _mixerCoderCommon->ReInit(); - UINT32 packStreamIndex = 0, unPackStreamIndex = 0; - UINT32 coderIndex = 0; - // UINT32 coder2Index = 0; + UInt32 packStreamIndex = 0, unPackStreamIndex = 0; + UInt32 coderIndex = 0; + // UInt32 coder2Index = 0; for (i = 0; i < numCoders; i++) { const CCoderInfo &coderInfo = folderInfo.Coders[i]; const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front(); - CMyComPtr<ICompressSetDecoderProperties> compressSetDecoderProperties; + CMyComPtr<ICompressSetDecoderProperties2> compressSetDecoderProperties; HRESULT result = _decoders[coderIndex].QueryInterface( - IID_ICompressSetDecoderProperties, &compressSetDecoderProperties); + IID_ICompressSetDecoderProperties2, &compressSetDecoderProperties); if (result == S_OK) { const CByteBuffer &properties = altCoderInfo.Properties; - UINT32 size = properties.GetCapacity(); + UInt32 size = properties.GetCapacity(); if (size > 0) { - CSequentialInStreamImp *inStreamSpec = new CSequentialInStreamImp; - CMyComPtr<ISequentialInStream> inStream(inStreamSpec); - inStreamSpec->Init((const BYTE *)properties, size); - RINOK(compressSetDecoderProperties->SetDecoderProperties(inStream)); + RINOK(compressSetDecoderProperties->SetDecoderProperties2((const Byte *)properties, size)); } } else if (result != E_NOINTERFACE) @@ -319,10 +356,18 @@ HRESULT CDecoder::Decode(IInStream *inStream, return E_FAIL; CMyComBSTR password; RINOK(getTextPassword->CryptoGetTextPassword(&password)); + CByteBuffer buffer; UString unicodePassword(password); + const UInt32 sizeInBytes = unicodePassword.Length() * 2; + buffer.SetCapacity(sizeInBytes); + for (int i = 0; i < unicodePassword.Length(); i++) + { + wchar_t c = unicodePassword[i]; + ((Byte *)buffer)[i * 2] = (Byte)c; + ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8); + } RINOK(cryptoSetPassword->CryptoSetPassword( - (const BYTE *)(const wchar_t *)unicodePassword, - unicodePassword.Length() * sizeof(wchar_t))); + (const Byte *)buffer, sizeInBytes)); } else if (result != E_NOINTERFACE) return result; @@ -330,13 +375,13 @@ HRESULT CDecoder::Decode(IInStream *inStream, coderIndex++; - UINT32 numInStreams = (UINT32)coderInfo.NumInStreams; - UINT32 numOutStreams = (UINT32)coderInfo.NumOutStreams; - CRecordVector<const UINT64 *> packSizesPointers; - CRecordVector<const UINT64 *> unPackSizesPointers; + UInt32 numInStreams = (UInt32)coderInfo.NumInStreams; + UInt32 numOutStreams = (UInt32)coderInfo.NumOutStreams; + CRecordVector<const UInt64 *> packSizesPointers; + CRecordVector<const UInt64 *> unPackSizesPointers; packSizesPointers.Reserve(numInStreams); unPackSizesPointers.Reserve(numOutStreams); - UINT32 j; + UInt32 j; for (j = 0; j < numOutStreams; j++, unPackStreamIndex++) unPackSizesPointers.Add(&folderInfo.UnPackSizes[unPackStreamIndex]); @@ -345,7 +390,7 @@ HRESULT CDecoder::Decode(IInStream *inStream, int bindPairIndex = folderInfo.FindBindPairForInStream(packStreamIndex); if (bindPairIndex >= 0) packSizesPointers.Add( - &folderInfo.UnPackSizes[(UINT32)folderInfo.BindPairs[bindPairIndex].OutIndex]); + &folderInfo.UnPackSizes[(UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex]); else { int index = folderInfo.FindPackStreamArrayIndex(packStreamIndex); @@ -355,13 +400,19 @@ HRESULT CDecoder::Decode(IInStream *inStream, } } - _mixerCoderSpec->SetCoderInfo(i, - &packSizesPointers.Front(), - &unPackSizesPointers.Front()); + _mixerCoderCommon->SetCoderInfo(i, + &packSizesPointers.Front(), + &unPackSizesPointers.Front()); } - UINT32 mainCoder, temp; + UInt32 mainCoder, temp; bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp); - _mixerCoderSpec->SetProgressCoderIndex(mainCoder); + + if (_multiThread) + _mixerCoderMTSpec->SetProgressCoderIndex(mainCoder); + /* + else + _mixerCoderSTSpec->SetProgressCoderIndex(mainCoder);; + */ if (numCoders == 0) return 0; @@ -370,7 +421,7 @@ HRESULT CDecoder::Decode(IInStream *inStream, for (i = 0; i < inStreams.Size(); i++) inStreamPointers.Add(inStreams[i]); ISequentialOutStream *outStreamPointer = outStream; - return _mixerCoderSpec->Code(&inStreamPointers.Front(), NULL, + return _mixerCoder->Code(&inStreamPointers.Front(), NULL, inStreams.Size(), &outStreamPointer, NULL, 1, compressProgress); } diff --git a/7zip/Archive/7z/7zDecode.h b/7zip/Archive/7z/7zDecode.h index f46eeb38..352f89f9 100755 --- a/7zip/Archive/7z/7zDecode.h +++ b/7zip/Archive/7z/7zDecode.h @@ -1,7 +1,5 @@ // 7zDecode.h -#pragma once - #ifndef __7Z_DECODE_H #define __7Z_DECODE_H @@ -9,6 +7,10 @@ #include "../../IPassword.h" #include "../Common/CoderMixer2.h" +#include "../Common/CoderMixer2MT.h" +#ifdef _ST_MODE +#include "../Common/CoderMixer2ST.h" +#endif #ifndef EXCLUDE_COM #include "../Common/CoderLoader.h" #endif @@ -21,6 +23,11 @@ namespace N7z { struct CBindInfoEx: public NCoderMixer2::CBindInfo { CRecordVector<CMethodID> CoderMethodIDs; + void Clear() + { + CBindInfo::Clear(); + CoderMethodIDs.Clear(); + } }; class CDecoder @@ -31,15 +38,22 @@ class CDecoder bool _bindInfoExPrevIsDefinded; CBindInfoEx _bindInfoExPrev; - NCoderMixer2::CCoderMixer2 *_mixerCoderSpec; + + bool _multiThread; + #ifdef _ST_MODE + NCoderMixer2::CCoderMixer2ST *_mixerCoderSTSpec; + #endif + NCoderMixer2::CCoderMixer2MT *_mixerCoderMTSpec; + NCoderMixer2::CCoderMixer2 *_mixerCoderCommon; + CMyComPtr<ICompressCoder2> _mixerCoder; CObjectVector<CMyComPtr<IUnknown> > _decoders; // CObjectVector<CMyComPtr<ICompressCoder2> > _decoders2; public: - CDecoder(); + CDecoder(bool multiThread); HRESULT Decode(IInStream *inStream, - UINT64 startPos, - const UINT64 *packSizes, + UInt64 startPos, + const UInt64 *packSizes, const CFolder &folder, ISequentialOutStream *outStream, ICompressProgressInfo *compressProgress diff --git a/7zip/Archive/7z/7zEncode.cpp b/7zip/Archive/7z/7zEncode.cpp index ebec98ac..050c7e95 100755 --- a/7zip/Archive/7z/7zEncode.cpp +++ b/7zip/Archive/7z/7zEncode.cpp @@ -11,6 +11,7 @@ #include "../../Common/LimitedStreams.h" #include "../../Common/InOutTempBuffer.h" #include "../../Common/StreamObjects.h" +#include "../Common/FilterCoder.h" #ifdef COMPRESS_COPY static NArchive::N7z::CMethodID k_Copy = { { 0x0 }, 1 }; @@ -38,11 +39,23 @@ static NArchive::N7z::CMethodID k_BCJ2 = { { 0x3, 0x3, 0x1, 0x1B }, 4 }; #endif #ifdef COMPRESS_DEFLATE +#ifndef COMPRESS_DEFLATE_ENCODER +#define COMPRESS_DEFLATE_ENCODER +#endif +#endif + +#ifdef COMPRESS_DEFLATE_ENCODER #include "../../Compress/Deflate/DeflateEncoder.h" static NArchive::N7z::CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 }; #endif #ifdef COMPRESS_BZIP2 +#ifndef COMPRESS_BZIP2_ENCODER +#define COMPRESS_BZIP2_ENCODER +#endif +#endif + +#ifdef COMPRESS_BZIP2_ENCODER #include "../../Compress/BZip2/BZip2Encoder.h" static NArchive::N7z::CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 }; #endif @@ -98,16 +111,12 @@ static void ConvertBindInfoToFolderItemInfo(const NCoderMixer2::CBindInfo &bindI folder.Coders.Add(coderInfo); } for (i = 0; i < bindInfo.InStreams.Size(); i++) - { - CPackStreamInfo packStreamInfo; - packStreamInfo.Index = bindInfo.InStreams[i]; - folder.PackStreams.Add(packStreamInfo); - } + folder.PackStreams.Add(bindInfo.InStreams[i]); } HRESULT CEncoder::CreateMixerCoder() { - _mixerCoderSpec = new NCoderMixer2::CCoderMixer2; + _mixerCoderSpec = new NCoderMixer2::CCoderMixer2MT; _mixerCoder = _mixerCoderSpec; _mixerCoderSpec->SetBindInfo(_bindInfo); for (int i = 0; i < _options.Methods.Size(); i++) @@ -116,6 +125,7 @@ HRESULT CEncoder::CreateMixerCoder() _codersInfo.Add(CCoderInfo()); CCoderInfo &encodingInfo = _codersInfo.Back(); CMyComPtr<ICompressCoder> encoder; + CMyComPtr<ICompressFilter> filter; CMyComPtr<ICompressCoder2> encoder2; if (methodFull.IsSimpleCoder()) @@ -132,7 +142,7 @@ HRESULT CEncoder::CreateMixerCoder() #ifdef COMPRESS_BCJ_X86 if (methodFull.MethodID == k_BCJ_X86) - encoder = new CBCJ_x86_Encoder; + filter = new CBCJ_x86_Encoder; #endif #ifdef COMPRESS_COPY @@ -140,25 +150,32 @@ HRESULT CEncoder::CreateMixerCoder() encoder = new NCompress::CCopyCoder; #endif - #ifdef COMPRESS_BZIP2 + #ifdef COMPRESS_BZIP2_ENCODER if (methodFull.MethodID == k_BZip2) encoder = new NCompress::NBZip2::CEncoder; #endif - #ifdef COMPRESS_DEFLATE + #ifdef COMPRESS_DEFLATE_ENCODER if (methodFull.MethodID == k_Deflate) encoder = new NCompress::NDeflate::NEncoder::CCOMCoder; #endif #ifdef CRYPTO_7ZAES if (methodFull.MethodID == k_AES) - encoder = new NCrypto::NSevenZ::CEncoder; + filter = new NCrypto::NSevenZ::CEncoder; #endif + if (filter) + { + CFilterCoder *coderSpec = new CFilterCoder; + encoder = coderSpec; + coderSpec->Filter = filter; + } + #ifndef EXCLUDE_COM if (encoder == 0) { - RINOK(_libraries.CreateCoder(methodFull.FilePath, + RINOK(_libraries.CreateCoderSpec(methodFull.FilePath, methodFull.EncoderClassID, &encoder)); } #endif @@ -189,29 +206,36 @@ HRESULT CEncoder::CreateMixerCoder() if (methodFull.CoderProperties.Size() > 0) { - std::vector<NWindows::NCOM::CPropVariant> properties; - std::vector<PROPID> propIDs; - INT32 numProperties = methodFull.CoderProperties.Size(); - for (int i = 0; i < numProperties; i++) - { - const CProperty &property = methodFull.CoderProperties[i]; - propIDs.push_back(property.PropID); - properties.push_back(property.Value); - } - CMyComPtr<ICompressSetCoderProperties> setCoderProperties; - if (methodFull.IsSimpleCoder()) + CRecordVector<PROPID> propIDs; + int numProperties = methodFull.CoderProperties.Size(); + NWindows::NCOM::CPropVariant *values = new NWindows::NCOM::CPropVariant[numProperties]; + try { - RINOK(encoder.QueryInterface(IID_ICompressSetCoderProperties, + for (int i = 0; i < numProperties; i++) + { + const CProperty &property = methodFull.CoderProperties[i]; + propIDs.Add(property.PropID); + values[i] = property.Value; + } + CMyComPtr<ICompressSetCoderProperties> setCoderProperties; + if (methodFull.IsSimpleCoder()) + { + RINOK(encoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties)); + } + else + { + RINOK(encoder2.QueryInterface(IID_ICompressSetCoderProperties, + &setCoderProperties)); + } + RINOK(setCoderProperties->SetCoderProperties(&propIDs.Front(), values, numProperties)); } - else + catch(...) { - RINOK(encoder2.QueryInterface(IID_ICompressSetCoderProperties, - &setCoderProperties)); + delete []values; + throw; } - - RINOK(setCoderProperties->SetCoderProperties(&propIDs.front(), - &properties.front(), numProperties)); + delete []values; } CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties; @@ -234,7 +258,7 @@ HRESULT CEncoder::CreateMixerCoder() outStreamSpec->Init(); writeCoderProperties->WriteCoderProperties(outStream); - UINT32 size = outStreamSpec->GetSize(); + UInt32 size = outStreamSpec->GetSize(); // encodingInfo.Properties.SetCapacity(size); if (encodingInfo.AltCoders.Size() == 0) @@ -257,9 +281,17 @@ HRESULT CEncoder::CreateMixerCoder() if (cryptoSetPassword) { + CByteBuffer buffer; + const UInt32 sizeInBytes = _options.Password.Length() * 2; + buffer.SetCapacity(sizeInBytes); + for (int i = 0; i < _options.Password.Length(); i++) + { + wchar_t c = _options.Password[i]; + ((Byte *)buffer)[i * 2] = (Byte)c; + ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8); + } RINOK(cryptoSetPassword->CryptoSetPassword( - (const BYTE *)(const wchar_t *)_options.Password, - _options.Password.Length() * sizeof(wchar_t))); + (const Byte *)buffer, sizeInBytes)); } // public ICompressWriteCoderProperties, @@ -276,10 +308,10 @@ HRESULT CEncoder::CreateMixerCoder() } HRESULT CEncoder::Encode(ISequentialInStream *inStream, - const UINT64 *inStreamSize, + const UInt64 *inStreamSize, CFolder &folderItem, ISequentialOutStream *outStream, - CRecordVector<UINT64> &packSizes, + CRecordVector<UInt64> &packSizes, ICompressProgressInfo *compressProgress) { if (_mixerCoderSpec == NULL) @@ -315,13 +347,13 @@ HRESULT CEncoder::Encode(ISequentialInStream *inStream, if (_bindInfo.InStreams.IsEmpty()) return E_FAIL; - UINT32 mainCoderIndex, mainStreamIndex; + UInt32 mainCoderIndex, mainStreamIndex; _bindInfo.FindInStream(_bindInfo.InStreams[0], mainCoderIndex, mainStreamIndex); _mixerCoderSpec->SetProgressCoderIndex(mainCoderIndex); if (inStreamSize != NULL) { - CRecordVector<const UINT64 *> sizePointers; - for (int i = 0; i < _bindInfo.Coders[mainCoderIndex].NumInStreams; i++) + CRecordVector<const UInt64 *> sizePointers; + for (UInt32 i = 0; i < _bindInfo.Coders[mainCoderIndex].NumInStreams; i++) if (i == mainStreamIndex) sizePointers.Add(inStreamSize); else @@ -330,7 +362,7 @@ HRESULT CEncoder::Encode(ISequentialInStream *inStream, } - // UINT64 outStreamStartPos; + // UInt64 outStreamStartPos; // RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos)); CSequentialInStreamSizeCount2 *inStreamSizeCountSpec = @@ -367,11 +399,11 @@ HRESULT CEncoder::Encode(ISequentialInStream *inStream, packSizes.Add(inOutTempBuffer.GetDataSize()); } - for (i = 0; i < _bindReverseConverter->NumSrcInStreams; i++) + for (i = 0; i < (int)_bindReverseConverter->NumSrcInStreams; i++) { int binder = _bindInfo.FindBinderForInStream( _bindReverseConverter->DestOutToSrcInMap[i]); - UINT64 streamSize; + UInt64 streamSize; if (binder < 0) streamSize = inStreamSizeCountSpec->GetSize(); else @@ -433,7 +465,7 @@ CEncoder::CEncoder(const CCompressionMethodMode &options): else { - UINT32 numInStreams = 0, numOutStreams = 0; + UInt32 numInStreams = 0, numOutStreams = 0; int i; for (i = 0; i < options.Methods.Size(); i++) { @@ -452,7 +484,7 @@ CEncoder::CEncoder(const CCompressionMethodMode &options): } else _bindInfo.OutStreams.Insert(0, numOutStreams); - for (UINT32 j = 1; j < coderStreamsInfo.NumOutStreams; j++) + for (UInt32 j = 1; j < coderStreamsInfo.NumOutStreams; j++) _bindInfo.OutStreams.Add(numOutStreams + j); } @@ -464,7 +496,7 @@ CEncoder::CEncoder(const CCompressionMethodMode &options): if (!options.Binds.IsEmpty()) { - for (int i = 0; i < options.Binds.Size(); i++) + for (i = 0; i < options.Binds.Size(); i++) { NCoderMixer2::CBindPair bindPair; const CBind &bind = options.Binds[i]; @@ -472,12 +504,12 @@ CEncoder::CEncoder(const CCompressionMethodMode &options): bindPair.OutIndex = _bindInfo.GetCoderOutStreamIndex(bind.OutCoder) + bind.OutStream; _bindInfo.BindPairs.Add(bindPair); } - for (i = 0; i < numOutStreams; i++) + for (i = 0; i < (int)numOutStreams; i++) if (_bindInfo.FindBinderForOutStream(i) == -1) _bindInfo.OutStreams.Add(i); } - for (i = 0; i < numInStreams; i++) + for (i = 0; i < (int)numInStreams; i++) if (_bindInfo.FindBinderForInStream(i) == -1) _bindInfo.InStreams.Add(i); @@ -488,9 +520,9 @@ CEncoder::CEncoder(const CCompressionMethodMode &options): int inIndex = _bindInfo.InStreams[0]; while (true) { - UINT32 coderIndex, coderStreamIndex; + UInt32 coderIndex, coderStreamIndex; _bindInfo.FindInStream(inIndex, coderIndex, coderStreamIndex); - UINT32 outIndex = _bindInfo.GetCoderStartOutStream(coderIndex); + UInt32 outIndex = _bindInfo.GetCoderOutStreamIndex(coderIndex); int binder = _bindInfo.FindBinderForOutStream(outIndex); if (binder >= 0) { diff --git a/7zip/Archive/7z/7zEncode.h b/7zip/Archive/7z/7zEncode.h index ee523a14..14ef9394 100755 --- a/7zip/Archive/7z/7zEncode.h +++ b/7zip/Archive/7z/7zEncode.h @@ -1,7 +1,5 @@ // 7zEncode.h -#pragma once - #ifndef __7Z_ENCODE_H #define __7Z_ENCODE_H @@ -10,6 +8,8 @@ #include "7zCompressionMode.h" #include "../Common/CoderMixer2.h" +#include "../Common/CoderMixer2MT.h" +#include "../Common/CoderMixer2ST.h" #ifndef EXCLUDE_COM #include "../Common/CoderLoader.h" #endif @@ -27,7 +27,7 @@ class CEncoder CCoderLibraries _libraries; #endif - NCoderMixer2::CCoderMixer2 *_mixerCoderSpec; + NCoderMixer2::CCoderMixer2MT *_mixerCoderSpec; CMyComPtr<ICompressCoder2> _mixerCoder; CObjectVector<CCoderInfo> _codersInfo; @@ -44,10 +44,10 @@ public: CEncoder(const CCompressionMethodMode &options); ~CEncoder(); HRESULT Encode(ISequentialInStream *inStream, - const UINT64 *inStreamSize, + const UInt64 *inStreamSize, CFolder &folderItem, ISequentialOutStream *outStream, - CRecordVector<UINT64> &packSizes, + CRecordVector<UInt64> &packSizes, ICompressProgressInfo *compressProgress); }; diff --git a/7zip/Archive/7z/7zExtract.cpp b/7zip/Archive/7z/7zExtract.cpp index 14347d29..1fcccfd7 100755 --- a/7zip/Archive/7z/7zExtract.cpp +++ b/7zip/Archive/7z/7zExtract.cpp @@ -6,9 +6,9 @@ #include "7zFolderOutStream.h" #include "7zMethods.h" #include "7zDecode.h" +// #include "7z1Decode.h" #include "../../../Common/ComTry.h" -#include "../../Common/MultiStream.h" #include "../../Common/StreamObjects.h" #include "../../Common/ProgressUtils.h" #include "../../Common/LimitedStreams.h" @@ -18,16 +18,26 @@ namespace N7z { struct CExtractFolderInfo { - int FileIndex; - int FolderIndex; + #ifdef _7Z_VOL + int VolumeIndex; + #endif + CNum FileIndex; + CNum FolderIndex; CBoolVector ExtractStatuses; - UINT64 UnPackSize; - CExtractFolderInfo(int fileIndex, int folderIndex): + UInt64 UnPackSize; + CExtractFolderInfo( + #ifdef _7Z_VOL + int volumeIndex, + #endif + CNum fileIndex, CNum folderIndex): + #ifdef _7Z_VOL + VolumeIndex(volumeIndex), + #endif FileIndex(fileIndex), FolderIndex(folderIndex), UnPackSize(0) { - if (fileIndex >= 0) + if (fileIndex != kNumNoIndex) { ExtractStatuses.Reserve(1); ExtractStatuses.Add(true); @@ -35,116 +45,150 @@ struct CExtractFolderInfo }; }; -STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, - INT32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec) +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec) { COM_TRY_BEGIN bool testMode = (testModeSpec != 0); CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec; - UINT64 importantTotalUnPacked = 0; - UINT64 censoredTotalUnPacked = 0, censoredTotalPacked = 0; + UInt64 importantTotalUnPacked = 0; + UInt64 censoredTotalUnPacked = 0, censoredTotalPacked = 0; - bool allFilesMode = (numItems == UINT32(-1)); + bool allFilesMode = (numItems == UInt32(-1)); if (allFilesMode) - numItems = _database.Files.Size(); + numItems = + #ifdef _7Z_VOL + _refs.Size(); + #else + _database.Files.Size(); + #endif if(numItems == 0) return S_OK; + /* + if(_volumes.Size() != 1) + return E_FAIL; + const CVolume &volume = _volumes.Front(); + const CArchiveDatabaseEx &_database = volume.Database; + IInStream *_inStream = volume.Stream; + */ + CObjectVector<CExtractFolderInfo> extractFolderInfoVector; - for(UINT32 indexIndex = 0; indexIndex < numItems; indexIndex++) + for(UInt32 ii = 0; ii < numItems; ii++) { - int fileIndex = allFilesMode ? indexIndex : indices[indexIndex]; - int folderIndex = _database.FileIndexToFolderIndexMap[fileIndex]; - if (folderIndex < 0) - { - extractFolderInfoVector.Add(CExtractFolderInfo(fileIndex, -1)); - continue; - } - if (extractFolderInfoVector.IsEmpty() || - folderIndex != extractFolderInfoVector.Back().FolderIndex) - { - extractFolderInfoVector.Add(CExtractFolderInfo(-1, folderIndex)); - const CFolder &folderInfo = _database.Folders[folderIndex]; - // Count full_folder_size - UINT64 unPackSize = folderInfo.GetUnPackSize(); - importantTotalUnPacked += unPackSize; - extractFolderInfoVector.Back().UnPackSize = unPackSize; - } + // UInt32 fileIndex = allFilesMode ? indexIndex : indices[indexIndex]; + UInt32 ref2Index = allFilesMode ? ii : indices[ii]; + // const CRef2 &ref2 = _refs[ref2Index]; - CExtractFolderInfo &extractFolderInfo = extractFolderInfoVector.Back(); - - // const CFolderInfo &folderInfo = m_dam_Folders[folderIndex]; - UINT32 startIndex = (UINT32)_database.FolderStartFileIndex[folderIndex]; - for (UINT32 index = extractFolderInfo.ExtractStatuses.Size(); - index <= fileIndex - startIndex; index++) + // for(UInt32 ri = 0; ri < ref2.Refs.Size(); ri++) { - UINT64 unPackSize = _database.Files[startIndex + index].UnPackSize; - // Count partial_folder_size - // extractFolderInfo.UnPackSize += unPackSize; - // importantTotalUnPacked += unPackSize; - extractFolderInfo.ExtractStatuses.Add(index == fileIndex - startIndex); + #ifdef _7Z_VOL + // const CRef &ref = ref2.Refs[ri]; + const CRef &ref = _refs[ref2Index]; + + int volumeIndex = ref.VolumeIndex; + const CVolume &volume = _volumes[volumeIndex]; + const CArchiveDatabaseEx &database = volume.Database; + UInt32 fileIndex = ref.ItemIndex; + #else + const CArchiveDatabaseEx &database = _database; + UInt32 fileIndex = ref2Index; + #endif + + CNum folderIndex = database.FileIndexToFolderIndexMap[fileIndex]; + if (folderIndex == kNumNoIndex) + { + extractFolderInfoVector.Add(CExtractFolderInfo( + #ifdef _7Z_VOL + volumeIndex, + #endif + fileIndex, kNumNoIndex)); + continue; + } + if (extractFolderInfoVector.IsEmpty() || + folderIndex != extractFolderInfoVector.Back().FolderIndex + #ifdef _7Z_VOL + || volumeIndex != extractFolderInfoVector.Back().VolumeIndex + #endif + ) + { + extractFolderInfoVector.Add(CExtractFolderInfo( + #ifdef _7Z_VOL + volumeIndex, + #endif + kNumNoIndex, folderIndex)); + const CFolder &folderInfo = database.Folders[folderIndex]; + UInt64 unPackSize = folderInfo.GetUnPackSize(); + importantTotalUnPacked += unPackSize; + extractFolderInfoVector.Back().UnPackSize = unPackSize; + } + + CExtractFolderInfo &efi = extractFolderInfoVector.Back(); + + // const CFolderInfo &folderInfo = m_dam_Folders[folderIndex]; + CNum startIndex = database.FolderStartFileIndex[folderIndex]; + for (CNum index = efi.ExtractStatuses.Size(); + index <= fileIndex - startIndex; index++) + { + // UInt64 unPackSize = _database.Files[startIndex + index].UnPackSize; + // Count partial_folder_size + // efi.UnPackSize += unPackSize; + // importantTotalUnPacked += unPackSize; + efi.ExtractStatuses.Add(index == fileIndex - startIndex); + } } } extractCallback->SetTotal(importantTotalUnPacked); - CDecoder decoder; + CDecoder decoder(true); + // CDecoder1 decoder; - UINT64 currentImportantTotalUnPacked = 0; - UINT64 totalFolderUnPacked; + UInt64 currentImportantTotalUnPacked = 0; + UInt64 totalFolderUnPacked; for(int i = 0; i < extractFolderInfoVector.Size(); i++, currentImportantTotalUnPacked += totalFolderUnPacked) { - CExtractFolderInfo &extractFolderInfo = extractFolderInfoVector[i]; - totalFolderUnPacked = extractFolderInfo.UnPackSize; + const CExtractFolderInfo &efi = extractFolderInfoVector[i]; + totalFolderUnPacked = efi.UnPackSize; RINOK(extractCallback->SetCompleted(¤tImportantTotalUnPacked)); CFolderOutStream *folderOutStream = new CFolderOutStream; CMyComPtr<ISequentialOutStream> outStream(folderOutStream); - UINT32 startIndex; - if (extractFolderInfo.FileIndex >= 0) - startIndex = extractFolderInfo.FileIndex; - else - startIndex = (UINT32)_database.FolderStartFileIndex[extractFolderInfo.FolderIndex]; - - - RINOK(folderOutStream->Init(&_database, startIndex, - &extractFolderInfo.ExtractStatuses, extractCallback, testMode)); + #ifdef _7Z_VOL + const CVolume &volume = _volumes[efi.VolumeIndex]; + const CArchiveDatabaseEx &database = volume.Database; + #else + const CArchiveDatabaseEx &database = _database; + #endif - if (extractFolderInfo.FileIndex >= 0) - continue; + CNum startIndex; + if (efi.FileIndex != kNumNoIndex) + startIndex = efi.FileIndex; + else + startIndex = database.FolderStartFileIndex[efi.FolderIndex]; - UINT32 folderIndex = extractFolderInfo.FolderIndex; - const CFolder &folderInfo = _database.Folders[folderIndex]; - CObjectVector< CMyComPtr<ISequentialInStream> > inStreams; + HRESULT result = folderOutStream->Init(&database, + #ifdef _7Z_VOL + volume.StartRef2Index, + #else + 0, + #endif + startIndex, + &efi.ExtractStatuses, extractCallback, testMode); - CLockedInStream lockedInStream; - lockedInStream.Init(_inStream); + RINOK(result); + if (efi.FileIndex != kNumNoIndex) + continue; - UINT64 folderStartPackStreamIndex = _database.FolderStartPackStreamIndex[folderIndex]; - - for (int j = 0; j < folderInfo.PackStreams.Size(); j++) - { - const CPackStreamInfo &packStreamInfo = folderInfo.PackStreams[j]; - CLockedSequentialInStreamImp *lockedStreamImpSpec = new - CLockedSequentialInStreamImp; - CMyComPtr<ISequentialInStream> lockedStreamImp = lockedStreamImpSpec; - UINT64 streamStartPos = _database.GetFolderStreamPos(folderIndex, j); - lockedStreamImpSpec->Init(&lockedInStream, streamStartPos); - - CLimitedSequentialInStream *streamSpec = new - CLimitedSequentialInStream; - CMyComPtr<ISequentialInStream> inStream = streamSpec; - streamSpec->Init(lockedStreamImp, - _database.PackSizes[(UINT32)folderStartPackStreamIndex + j]); - inStreams.Add(inStream); - } + CNum folderIndex = efi.FolderIndex; + const CFolder &folderInfo = database.Folders[folderIndex]; CLocalProgress *localProgressSpec = new CLocalProgress; CMyComPtr<ICompressProgressInfo> progress = localProgressSpec; @@ -155,8 +199,8 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec; localCompressProgressSpec->Init(progress, NULL, ¤tImportantTotalUnPacked); - UINT32 packStreamIndex = _database.FolderStartPackStreamIndex[folderIndex]; - UINT64 folderStartPackPos = _database.GetFolderStreamPos(folderIndex, 0); + CNum packStreamIndex = database.FolderStartPackStreamIndex[folderIndex]; + UInt64 folderStartPackPos = database.GetFolderStreamPos(folderIndex, 0); #ifndef _NO_CRYPTO CMyComPtr<ICryptoGetTextPassword> getTextPassword; @@ -166,9 +210,14 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, try { - HRESULT result = decoder.Decode(_inStream, + HRESULT result = decoder.Decode( + #ifdef _7Z_VOL + volume.Stream, + #else + _inStream, + #endif folderStartPackPos, - &_database.PackSizes[packStreamIndex], + &database.PackSizes[packStreamIndex], folderInfo, outStream, compressProgress @@ -189,7 +238,11 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, } if (result != S_OK) return result; - RINOK(folderOutStream->WasWritingFinished()); + if (folderOutStream->WasWritingFinished() != S_OK) + { + RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError)); + continue; + } } catch(...) { diff --git a/7zip/Archive/7z/7zFolderInStream.cpp b/7zip/Archive/7z/7zFolderInStream.cpp index a438c1bd..63f45a07 100755 --- a/7zip/Archive/7z/7zFolderInStream.cpp +++ b/7zip/Archive/7z/7zFolderInStream.cpp @@ -9,17 +9,18 @@ namespace N7z { CFolderInStream::CFolderInStream() { - _inStreamWithHashSpec = new CInStreamWithCRC; + _inStreamWithHashSpec = new CSequentialInStreamWithCRC; _inStreamWithHash = _inStreamWithHashSpec; } void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback, - const UINT32 *fileIndices, UINT32 numFiles) + const UInt32 *fileIndices, UInt32 numFiles) { _updateCallback = updateCallback; _numFiles = numFiles; _fileIndex = 0; _fileIndices = fileIndices; + Processed.Clear(); CRCs.Clear(); Sizes.Clear(); _fileIsOpen = false; @@ -32,14 +33,17 @@ HRESULT CFolderInStream::OpenStream() while (_fileIndex < _numFiles) { _currentSizeIsDefined = false; - CMyComPtr<IInStream> stream; - RINOK(_updateCallback->GetStream(_fileIndices[_fileIndex], &stream)); + CMyComPtr<ISequentialInStream> stream; + HRESULT result = _updateCallback->GetStream(_fileIndices[_fileIndex], &stream); + if (result != S_OK && result != S_FALSE) + return result; _fileIndex++; _inStreamWithHashSpec->Init(stream); if (!stream) { RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); Sizes.Add(0); + Processed.Add(result == S_OK); AddDigest(); continue; } @@ -69,21 +73,22 @@ HRESULT CFolderInStream::CloseStream() RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); _inStreamWithHashSpec->ReleaseStream(); _fileIsOpen = false; + Processed.Add(true); Sizes.Add(_filePos); AddDigest(); return S_OK; } -STDMETHODIMP CFolderInStream::ReadPart(void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CFolderInStream::ReadPart(void *data, UInt32 size, UInt32 *processedSize) { - UINT32 realProcessedSize = 0; + UInt32 realProcessedSize = 0; while ((_fileIndex < _numFiles || _fileIsOpen) && size > 0) { if (_fileIsOpen) { - UINT32 localProcessedSize; - RINOK(_inStreamWithHash->Read( - ((BYTE *)data) + realProcessedSize, size, &localProcessedSize)); + UInt32 localProcessedSize; + RINOK(_inStreamWithHash->ReadPart( + ((Byte *)data) + realProcessedSize, size, &localProcessedSize)); if (localProcessedSize == 0) { RINOK(CloseStream()); @@ -104,13 +109,13 @@ STDMETHODIMP CFolderInStream::ReadPart(void *data, UINT32 size, UINT32 *processe return S_OK; } -STDMETHODIMP CFolderInStream::Read(void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize) { - UINT32 realProcessedSize = 0; + UInt32 realProcessedSize = 0; while (size > 0) { - UINT32 localProcessedSize; - RINOK(ReadPart(((BYTE *)data) + realProcessedSize, size, &localProcessedSize)); + UInt32 localProcessedSize; + RINOK(ReadPart(((Byte *)data) + realProcessedSize, size, &localProcessedSize)); if (localProcessedSize == 0) break; size -= localProcessedSize; @@ -122,12 +127,12 @@ STDMETHODIMP CFolderInStream::Read(void *data, UINT32 size, UINT32 *processedSiz } -STDMETHODIMP CFolderInStream::GetSubStreamSize(UINT64 subStream, UINT64 *value) +STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value) { *value = 0; if (subStream < Sizes.Size()) { - *value= Sizes[subStream]; + *value= Sizes[(size_t)subStream]; return S_OK; } if (subStream > Sizes.Size()) diff --git a/7zip/Archive/7z/7zFolderInStream.h b/7zip/Archive/7z/7zFolderInStream.h index 265559a6..12a2ac07 100755 --- a/7zip/Archive/7z/7zFolderInStream.h +++ b/7zip/Archive/7z/7zFolderInStream.h @@ -1,7 +1,5 @@ // 7z/FolderInStream.h -#pragma once - #ifndef __7Z_FOLDERINSTREAM_H #define __7Z_FOLDERINSTREAM_H @@ -27,36 +25,37 @@ public: CFolderInStream(); - STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize); - STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize); + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(GetSubStreamSize)(UINT64 subStream, UINT64 *value); + STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value); private: - CInStreamWithCRC *_inStreamWithHashSpec; + CSequentialInStreamWithCRC *_inStreamWithHashSpec; CMyComPtr<ISequentialInStream> _inStreamWithHash; CMyComPtr<IArchiveUpdateCallback> _updateCallback; bool _currentSizeIsDefined; - UINT64 _currentSize; + UInt64 _currentSize; bool _fileIsOpen; - UINT64 _filePos; + UInt64 _filePos; - const UINT32 *_fileIndices; - UINT32 _numFiles; - UINT32 _fileIndex; + const UInt32 *_fileIndices; + UInt32 _numFiles; + UInt32 _fileIndex; HRESULT OpenStream(); HRESULT CloseStream(); void AddDigest(); public: void Init(IArchiveUpdateCallback *updateCallback, - const UINT32 *fileIndices, UINT32 numFiles); - CRecordVector<UINT32> CRCs; - CRecordVector<UINT64> Sizes; - UINT64 GetFullSize() const + const UInt32 *fileIndices, UInt32 numFiles); + CRecordVector<bool> Processed; + CRecordVector<UInt32> CRCs; + CRecordVector<UInt64> Sizes; + UInt64 GetFullSize() const { - UINT64 size = 0; + UInt64 size = 0; for (int i = 0; i < Sizes.Size(); i++) size += Sizes[i]; return size; diff --git a/7zip/Archive/7z/7zFolderOutStream.cpp b/7zip/Archive/7z/7zFolderOutStream.cpp index 12abafd5..c09271f5 100755 --- a/7zip/Archive/7z/7zFolderOutStream.cpp +++ b/7zip/Archive/7z/7zFolderOutStream.cpp @@ -14,13 +14,15 @@ CFolderOutStream::CFolderOutStream() } HRESULT CFolderOutStream::Init( - CArchiveDatabaseEx *archiveDatabase, - UINT32 startIndex, + const CArchiveDatabaseEx *archiveDatabase, + UInt32 ref2Offset, + UInt32 startIndex, const CBoolVector *extractStatuses, IArchiveExtractCallback *extractCallback, bool testMode) { _archiveDatabase = archiveDatabase; + _ref2Offset = ref2Offset; _startIndex = startIndex; _extractStatuses = extractStatuses; @@ -34,7 +36,7 @@ HRESULT CFolderOutStream::Init( HRESULT CFolderOutStream::OpenFile() { - INT32 askMode; + Int32 askMode; if((*_extractStatuses)[_currentIndex]) askMode = _testMode ? NArchive::NExtract::NAskMode::kTest : @@ -43,14 +45,13 @@ HRESULT CFolderOutStream::OpenFile() askMode = NArchive::NExtract::NAskMode::kSkip; CMyComPtr<ISequentialOutStream> realOutStream; - UINT32 index = _startIndex + _currentIndex; - RINOK(_extractCallback->GetStream(index, &realOutStream, askMode)); + UInt32 index = _startIndex + _currentIndex; + RINOK(_extractCallback->GetStream(_ref2Offset + index, &realOutStream, askMode)); _outStreamWithHashSpec->Init(realOutStream); if (askMode == NArchive::NExtract::NAskMode::kExtract && (!realOutStream)) { - UINT32 index = _startIndex + _currentIndex; const CFileItem &fileInfo = _archiveDatabase->Files[index]; if (!fileInfo.IsAnti && !fileInfo.IsDirectory) askMode = NArchive::NExtract::NAskMode::kSkip; @@ -62,7 +63,7 @@ HRESULT CFolderOutStream::WriteEmptyFiles() { for(;_currentIndex < _extractStatuses->Size(); _currentIndex++) { - UINT32 index = _startIndex + _currentIndex; + UInt32 index = _startIndex + _currentIndex; const CFileItem &fileInfo = _archiveDatabase->Files[index]; if (!fileInfo.IsAnti && !fileInfo.IsDirectory && fileInfo.UnPackSize != 0) return S_OK; @@ -75,29 +76,29 @@ HRESULT CFolderOutStream::WriteEmptyFiles() } STDMETHODIMP CFolderOutStream::Write(const void *data, - UINT32 size, UINT32 *processedSize) + UInt32 size, UInt32 *processedSize) { - UINT32 realProcessedSize = 0; + UInt32 realProcessedSize = 0; while(_currentIndex < _extractStatuses->Size()) { if (_fileIsOpen) { - UINT32 index = _startIndex + _currentIndex; + UInt32 index = _startIndex + _currentIndex; const CFileItem &fileInfo = _archiveDatabase->Files[index]; - UINT64 fileSize = fileInfo.UnPackSize; + UInt64 fileSize = fileInfo.UnPackSize; - UINT32 numBytesToWrite = (UINT32)MyMin(fileSize - _filePos, - UINT64(size - realProcessedSize)); + UInt32 numBytesToWrite = (UInt32)MyMin(fileSize - _filePos, + UInt64(size - realProcessedSize)); - UINT32 processedSizeLocal; - RINOK(_outStreamWithHash->Write((const BYTE *)data + realProcessedSize, numBytesToWrite, &processedSizeLocal)); + UInt32 processedSizeLocal; + RINOK(_outStreamWithHash->Write((const Byte *)data + realProcessedSize, numBytesToWrite, &processedSizeLocal)); _filePos += processedSizeLocal; realProcessedSize += processedSizeLocal; if (_filePos == fileSize) { bool digestsAreEqual; - if (fileInfo.FileCRCIsDefined) + if (fileInfo.IsFileCRCDefined) digestsAreEqual = fileInfo.FileCRC == _outStreamWithHashSpec->GetCRC(); else digestsAreEqual = true; @@ -130,12 +131,12 @@ STDMETHODIMP CFolderOutStream::Write(const void *data, } STDMETHODIMP CFolderOutStream::WritePart(const void *data, - UINT32 size, UINT32 *processedSize) + UInt32 size, UInt32 *processedSize) { return Write(data, size, processedSize); } -HRESULT CFolderOutStream::FlushCorrupted(INT32 resultEOperationResult) +HRESULT CFolderOutStream::FlushCorrupted(Int32 resultEOperationResult) { while(_currentIndex < _extractStatuses->Size()) { diff --git a/7zip/Archive/7z/7zFolderOutStream.h b/7zip/Archive/7z/7zFolderOutStream.h index c5dcf157..9153070e 100755 --- a/7zip/Archive/7z/7zFolderOutStream.h +++ b/7zip/Archive/7z/7zFolderOutStream.h @@ -1,7 +1,5 @@ // 7zFolderOutStream.h -#pragma once - #ifndef __7Z_FOLDEROUTSTREAM_H #define __7Z_FOLDEROUTSTREAM_H @@ -23,33 +21,35 @@ public: CFolderOutStream(); - STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize); - STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize); + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); private: COutStreamWithCRC *_outStreamWithHashSpec; CMyComPtr<ISequentialOutStream> _outStreamWithHash; - CArchiveDatabaseEx *_archiveDatabase; + const CArchiveDatabaseEx *_archiveDatabase; const CBoolVector *_extractStatuses; - UINT32 _startIndex; + UInt32 _startIndex; + UInt32 _ref2Offset; int _currentIndex; - // UINT64 _currentDataPos; + // UInt64 _currentDataPos; CMyComPtr<IArchiveExtractCallback> _extractCallback; bool _testMode; bool _fileIsOpen; - UINT64 _filePos; + UInt64 _filePos; HRESULT OpenFile(); HRESULT WriteEmptyFiles(); public: HRESULT Init( - CArchiveDatabaseEx *archiveDatabase, - UINT32 startIndex, + const CArchiveDatabaseEx *archiveDatabase, + UInt32 ref2Offset, + UInt32 startIndex, const CBoolVector *extractStatuses, IArchiveExtractCallback *extractCallback, bool testMode); - HRESULT FlushCorrupted(INT32 resultEOperationResult); + HRESULT FlushCorrupted(Int32 resultEOperationResult); HRESULT WasWritingFinished(); }; diff --git a/7zip/Archive/7z/7zHandler.cpp b/7zip/Archive/7z/7zHandler.cpp index 5eaff836..45ca1abe 100755 --- a/7zip/Archive/7z/7zHandler.cpp +++ b/7zip/Archive/7z/7zHandler.cpp @@ -1,4 +1,4 @@ -// 7z/Handler.cpp +// 7zHandler.cpp #include "StdAfx.h" @@ -6,14 +6,15 @@ #include "7zProperties.h" #include "../../../Common/IntToString.h" -// #include "../../../Common/StringConvert.h" #include "../../../Common/ComTry.h" - #include "../../../Windows/Defs.h" #include "../Common/ItemNameUtils.h" +#ifdef _7Z_VOL +#include "../Common/MultiStream.h" +#endif -// #include "7zMethods.h" +using namespace NWindows; namespace NArchive { namespace N7z { @@ -28,31 +29,15 @@ CHandler::CHandler() #endif } -/* -STDMETHODIMP CHandler::EnumProperties(IEnumSTATPROPSTG **enumerator) +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) { - #ifndef _SFX COM_TRY_BEGIN - CComObjectNoLock<CEnumArchiveItemProperty> *enumeratorSpec = - new CComObjectNoLock<CEnumArchiveItemProperty>; - if (enumeratorSpec == NULL) - return E_OUTOFMEMORY; - CMyComPtr<IEnumSTATPROPSTG> tempEnumerator(enumeratorSpec); - enumeratorSpec->Init(_database.ArchiveInfo.FileInfoPopIDs); - *enumerator = tempEnumerator.Detach(); - return S_OK; - // return tempEnumerator->QueryInterface(IID_IEnumSTATPROPSTG, (LPVOID*)enumerator); - COM_TRY_END + *numItems = + #ifdef _7Z_VOL + _refs.Size(); #else - return E_NOTIMPL; - #endif -} -*/ - -STDMETHODIMP CHandler::GetNumberOfItems(UINT32 *numItems) -{ - COM_TRY_BEGIN *numItems = _database.Files.Size(); + #endif return S_OK; COM_TRY_END } @@ -65,12 +50,12 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) #ifdef _SFX -STDMETHODIMP CHandler::GetNumberOfProperties(UINT32 *numProperties) +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) { return E_NOTIMPL; } -STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index, +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) { return E_NOTIMPL; @@ -79,13 +64,13 @@ STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index, #endif -STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UINT32 *numProperties) +STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) { *numProperties = 0; return S_OK; } -STDMETHODIMP CHandler::GetArchivePropertyInfo(UINT32 index, +STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) { return E_NOTIMPL; @@ -95,30 +80,22 @@ STDMETHODIMP CHandler::GetArchivePropertyInfo(UINT32 index, static void MySetFileTime(bool timeDefined, FILETIME unixTime, NWindows::NCOM::CPropVariant &propVariant) { - // FILETIME fileTime; if (timeDefined) propVariant = unixTime; - // NTime::UnixTimeToFileTime((time_t)unixTime, fileTime); - else - { - return; - // fileTime.dwHighDateTime = fileTime.dwLowDateTime = 0; - } - // propVariant = fileTime; } /* -inline static wchar_t GetHex(BYTE value) +inline static wchar_t GetHex(Byte value) { return (value < 10) ? ('0' + value) : ('A' + (value - 10)); } -static UString ConvertBytesToHexString(const BYTE *data, UINT32 size) +static UString ConvertBytesToHexString(const Byte *data, UInt32 size) { UString result; - for (UINT32 i = 0; i < size; i++) + for (UInt32 i = 0; i < size; i++) { - BYTE b = data[i]; + Byte b = data[i]; result += GetHex(b >> 4); result += GetHex(b & 0xF); } @@ -129,32 +106,32 @@ static UString ConvertBytesToHexString(const BYTE *data, UINT32 size) #ifndef _SFX -static UString ConvertUINT32ToString(UINT32 value) +static UString ConvertUInt32ToString(UInt32 value) { wchar_t buffer[32]; - ConvertUINT64ToString(value, buffer); + ConvertUInt64ToString(value, buffer); return buffer; } -static UString GetStringForSizeValue(UINT32 value) +static UString GetStringForSizeValue(UInt32 value) { for (int i = 31; i >= 0; i--) - if ((UINT32(1) << i) == value) - return ConvertUINT32ToString(i); + if ((UInt32(1) << i) == value) + return ConvertUInt32ToString(i); UString result; if (value % (1 << 20) == 0) { - result += ConvertUINT32ToString(value >> 20); + result += ConvertUInt32ToString(value >> 20); result += L"m"; } else if (value % (1 << 10) == 0) { - result += ConvertUINT32ToString(value >> 10); + result += ConvertUInt32ToString(value >> 10); result += L"k"; } else { - result += ConvertUINT32ToString(value); + result += ConvertUInt32ToString(value); result += L"b"; } return result; @@ -168,11 +145,11 @@ static CMethodID k_PPMD = { { 0x3, 0x4, 0x1 }, 3 }; static CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 }; static CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 }; -static inline char GetHex(BYTE value) +static inline char GetHex(Byte value) { return (value < 10) ? ('0' + value) : ('A' + (value - 10)); } -static inline UString GetHex2(BYTE value) +static inline UString GetHex2(Byte value) { UString result; result += GetHex(value >> 4); @@ -182,39 +159,78 @@ static inline UString GetHex2(BYTE value) #endif -STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value) +static inline UInt32 GetUInt32FromMemLE(const Byte *p) +{ + return p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24); +} + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant propVariant; + + /* + const CRef2 &ref2 = _refs[index]; + if (ref2.Refs.IsEmpty()) + return E_FAIL; + const CRef &ref = ref2.Refs.Front(); + */ + + #ifdef _7Z_VOL + const CRef &ref = _refs[index]; + const CVolume &volume = _volumes[ref.VolumeIndex]; + const CArchiveDatabaseEx &_database = volume.Database; + UInt32 index2 = ref.ItemIndex; + const CFileItem &item = _database.Files[index2]; + #else const CFileItem &item = _database.Files[index]; + UInt32 index2 = index; + #endif switch(propID) { case kpidPath: { - propVariant = NArchive::NItemName::GetOSName(item.Name); + if (!item.Name.IsEmpty()) + propVariant = NItemName::GetOSName(item.Name); break; } case kpidIsFolder: propVariant = item.IsDirectory; break; case kpidSize: + { propVariant = item.UnPackSize; + // propVariant = ref2.UnPackSize; + break; + } + case kpidPosition: + { + /* + if (ref2.Refs.Size() > 1) + propVariant = ref2.StartPos; + else + */ + if (item.IsStartPosDefined) + propVariant = item.StartPos; break; + } case kpidPackedSize: { + // propVariant = ref2.PackSize; { - int folderIndex = _database.FileIndexToFolderIndexMap[index]; - if (folderIndex >= 0) + CNum folderIndex = _database.FileIndexToFolderIndexMap[index2]; + if (folderIndex != kNumNoIndex) { - const CFolder &folderInfo = _database.Folders[folderIndex]; - if (_database.FolderStartFileIndex[folderIndex] == index) + if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2) propVariant = _database.GetFolderFullPackSize(folderIndex); + /* else - propVariant = UINT64(0); + propVariant = UInt64(0); + */ } else - propVariant = UINT64(0); + propVariant = UInt64(0); } break; } @@ -232,14 +248,14 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va propVariant = item.Attributes; break; case kpidCRC: - if (item.FileCRCIsDefined) + if (item.IsFileCRCDefined) propVariant = item.FileCRC; break; #ifndef _SFX case kpidMethod: { - int folderIndex = _database.FileIndexToFolderIndexMap[index]; - if (folderIndex >= 0) + CNum folderIndex = _database.FileIndexToFolderIndexMap[index2]; + if (folderIndex != kNumNoIndex) { const CFolder &folderInfo = _database.Folders[folderIndex]; UString methodsString; @@ -292,24 +308,24 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va methodsString += methodName; if (altCoderInfo.MethodID == k_LZMA) { - if (altCoderInfo.Properties.GetCapacity() == 5) + if (altCoderInfo.Properties.GetCapacity() >= 5) { methodsString += L":"; - UINT32 dicSize = *(const UINT32 *) - ((const BYTE *)altCoderInfo.Properties + 1); + UInt32 dicSize = GetUInt32FromMemLE( + ((const Byte *)altCoderInfo.Properties + 1)); methodsString += GetStringForSizeValue(dicSize); } } else if (altCoderInfo.MethodID == k_PPMD) { - if (altCoderInfo.Properties.GetCapacity() == 5) + if (altCoderInfo.Properties.GetCapacity() >= 5) { - BYTE order = *(const BYTE *)altCoderInfo.Properties; + Byte order = *(const Byte *)altCoderInfo.Properties; methodsString += L":o"; - methodsString += ConvertUINT32ToString(order); + methodsString += ConvertUInt32ToString(order); methodsString += L":mem"; - UINT32 dicSize = *(const UINT32 *) - ((const BYTE *)altCoderInfo.Properties + 1); + UInt32 dicSize = GetUInt32FromMemLE( + ((const Byte *)altCoderInfo.Properties + 1)); methodsString += GetStringForSizeValue(dicSize); } } @@ -318,7 +334,7 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va if (altCoderInfo.Properties.GetCapacity() > 0) { methodsString += L":["; - for (int bi = 0; bi < altCoderInfo.Properties.GetCapacity(); bi++) + for (size_t bi = 0; bi < altCoderInfo.Properties.GetCapacity(); bi++) { if (bi > 2 && bi + 1 < altCoderInfo.Properties.GetCapacity()) { @@ -344,9 +360,9 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va break; case kpidBlock: { - int folderIndex = _database.FileIndexToFolderIndexMap[index]; - if (folderIndex >= 0) - propVariant = (UINT32)folderIndex; + CNum folderIndex = _database.FileIndexToFolderIndexMap[index2]; + if (folderIndex != kNumNoIndex) + propVariant = (UInt32)folderIndex; } break; case kpidPackedSize0: @@ -355,20 +371,20 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va case kpidPackedSize3: case kpidPackedSize4: { - int folderIndex = _database.FileIndexToFolderIndexMap[index]; - if (folderIndex >= 0) + CNum folderIndex = _database.FileIndexToFolderIndexMap[index2]; + if (folderIndex != kNumNoIndex) { const CFolder &folderInfo = _database.Folders[folderIndex]; - if (_database.FolderStartFileIndex[folderIndex] == index && - folderInfo.PackStreams.Size() > propID - kpidPackedSize0) + if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2 && + folderInfo.PackStreams.Size() > (int)(propID - kpidPackedSize0)) { propVariant = _database.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0); } else - propVariant = UINT64(0); + propVariant = UInt64(0); } else - propVariant = UINT64(0); + propVariant = UInt64(0); } break; #endif @@ -381,49 +397,238 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va COM_TRY_END } +static const wchar_t *kExt = L"7z"; +static const wchar_t *kAfterPart = L".7z"; + +#ifdef _7Z_VOL + +class CVolumeName +{ + bool _first; + UString _unchangedPart; + UString _changedPart; + UString _afterPart; +public: + bool InitName(const UString &name) + { + _first = true; + int dotPos = name.ReverseFind('.'); + UString basePart = name; + if (dotPos >= 0) + { + UString ext = name.Mid(dotPos + 1); + if (ext.CompareNoCase(kExt)==0 || + ext.CompareNoCase(L"EXE") == 0) + { + _afterPart = kAfterPart; + basePart = name.Left(dotPos); + } + } + + int numLetters = 1; + bool splitStyle = false; + if (basePart.Right(numLetters) == L"1") + { + while (numLetters < basePart.Length()) + { + if (basePart[basePart.Length() - numLetters - 1] != '0') + break; + numLetters++; + } + } + else + return false; + _unchangedPart = basePart.Left(basePart.Length() - numLetters); + _changedPart = basePart.Right(numLetters); + return true; + } + + UString GetNextName() + { + UString newName; + // if (_newStyle || !_first) + { + int i; + int numLetters = _changedPart.Length(); + for (i = numLetters - 1; i >= 0; i--) + { + wchar_t c = _changedPart[i]; + if (c == L'9') + { + c = L'0'; + newName = c + newName; + if (i == 0) + newName = UString(L'1') + newName; + continue; + } + c++; + newName = UString(c) + newName; + i--; + for (; i >= 0; i--) + newName = _changedPart[i] + newName; + break; + } + _changedPart = newName; + } + _first = false; + return _unchangedPart + _changedPart + _afterPart; + } +}; + +#endif + STDMETHODIMP CHandler::Open(IInStream *stream, - const UINT64 *maxCheckStartPosition, + const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) { COM_TRY_BEGIN - _inStream.Release(); - _database.Clear(); + Close(); #ifndef _SFX _fileInfoPopIDs.Clear(); #endif try { - CInArchive archive; - RINOK(archive.Open(stream, maxCheckStartPosition)); + CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = openArchiveCallback; + #ifdef _7Z_VOL + CVolumeName seqName; + + CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback; + #endif #ifndef _NO_CRYPTO CMyComPtr<ICryptoGetTextPassword> getTextPassword; if (openArchiveCallback) { - CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = openArchiveCallback; openArchiveCallbackTemp.QueryInterface( IID_ICryptoGetTextPassword, &getTextPassword); } #endif + #ifdef _7Z_VOL + if (openArchiveCallback) + { + openArchiveCallbackTemp.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback); + } + while(true) + { + CMyComPtr<IInStream> inStream; + if (!_volumes.IsEmpty()) + { + if (!openVolumeCallback) + break; + if(_volumes.Size() == 1) + { + UString baseName; + { + NCOM::CPropVariant propVariant; + RINOK(openVolumeCallback->GetProperty(kpidName, &propVariant)); + if (propVariant.vt != VT_BSTR) + break; + baseName = propVariant.bstrVal; + } + seqName.InitName(baseName); + } + UString fullName = seqName.GetNextName(); + HRESULT result = openVolumeCallback->GetStream(fullName, &inStream); + if (result == S_FALSE) + break; + if (result != S_OK) + return result; + if (!stream) + break; + } + else + inStream = stream; + + CInArchive archive; + RINOK(archive.Open(inStream, maxCheckStartPosition)); + + _volumes.Add(CVolume()); + CVolume &volume = _volumes.Back(); + CArchiveDatabaseEx &database = volume.Database; + volume.Stream = inStream; + volume.StartRef2Index = _refs.Size(); + + HRESULT result = archive.ReadDatabase(database + #ifndef _NO_CRYPTO + , getTextPassword + #endif + ); + if (result != S_OK) + { + _volumes.Clear(); + return result; + } + database.Fill(); + for(int i = 0; i < database.Files.Size(); i++) + { + CRef refNew; + refNew.VolumeIndex = _volumes.Size() - 1; + refNew.ItemIndex = i; + _refs.Add(refNew); + /* + const CFileItem &file = database.Files[i]; + int j; + */ + /* + for (j = _refs.Size() - 1; j >= 0; j--) + { + CRef2 &ref2 = _refs[j]; + const CRef &ref = ref2.Refs.Back(); + const CVolume &volume2 = _volumes[ref.VolumeIndex]; + const CArchiveDatabaseEx &database2 = volume2.Database; + const CFileItem &file2 = database2.Files[ref.ItemIndex]; + if (file2.Name.CompareNoCase(file.Name) == 0) + { + if (!file.IsStartPosDefined) + continue; + if (file.StartPos != ref2.StartPos + ref2.UnPackSize) + continue; + ref2.Refs.Add(refNew); + break; + } + } + */ + /* + j = -1; + if (j < 0) + { + CRef2 ref2New; + ref2New.Refs.Add(refNew); + j = _refs.Add(ref2New); + } + CRef2 &ref2 = _refs[j]; + ref2.UnPackSize += file.UnPackSize; + ref2.PackSize += database.GetFilePackSize(i); + if (ref2.Refs.Size() == 1 && file.IsStartPosDefined) + ref2.StartPos = file.StartPos; + */ + } + if (database.Files.Size() != 1) + break; + const CFileItem &file = database.Files.Front(); + if (!file.IsStartPosDefined) + break; + } + #else + CInArchive archive; + RINOK(archive.Open(stream, maxCheckStartPosition)); HRESULT result = archive.ReadDatabase(_database #ifndef _NO_CRYPTO , getTextPassword #endif ); RINOK(result); - result = archive.CheckIntegrity(); - if (result != S_OK) - return E_FAIL; - _database.FillFolderStartPackStream(); - _database.FillStartPos(); - _database.FillFolderStartFileIndex(); + _database.Fill(); + _inStream = stream; + #endif } catch(...) { + Close(); return S_FALSE; } - _inStream = stream; + // _inStream = stream; #ifndef _SFX FillPopIDs(); #endif @@ -434,9 +639,73 @@ STDMETHODIMP CHandler::Open(IInStream *stream, STDMETHODIMP CHandler::Close() { COM_TRY_BEGIN + #ifdef _7Z_VOL + _volumes.Clear(); + _refs.Clear(); + #else _inStream.Release(); + _database.Clear(); + #endif return S_OK; COM_TRY_END } +#ifdef _7Z_VOL +STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +{ + if (index != 0) + return E_INVALIDARG; + *stream = 0; + CMultiStream *streamSpec = new CMultiStream; + CMyComPtr<ISequentialInStream> streamTemp = streamSpec; + + UInt64 pos = 0; + const UString *fileName; + for (int i = 0; i < _refs.Size(); i++) + { + const CRef &ref = _refs[i]; + const CVolume &volume = _volumes[ref.VolumeIndex]; + const CArchiveDatabaseEx &database = volume.Database; + const CFileItem &file = database.Files[ref.ItemIndex]; + if (i == 0) + fileName = &file.Name; + else + if (fileName->Compare(file.Name) != 0) + return S_FALSE; + if (!file.IsStartPosDefined) + return S_FALSE; + if (file.StartPos != pos) + return S_FALSE; + CNum folderIndex = database.FileIndexToFolderIndexMap[ref.ItemIndex]; + if (folderIndex == kNumNoIndex) + { + if (file.UnPackSize != 0) + return E_FAIL; + continue; + } + if (database.NumUnPackStreamsVector[folderIndex] != 1) + return S_FALSE; + const CFolder &folder = database.Folders[folderIndex]; + if (folder.Coders.Size() != 1) + return S_FALSE; + const CCoderInfo &coder = folder.Coders.Front(); + if (coder.NumInStreams != 1 || coder.NumOutStreams != 1) + return S_FALSE; + const CAltCoderInfo &altCoder = coder.AltCoders.Front(); + if (altCoder.MethodID.IDSize != 1 || altCoder.MethodID.ID[0] != 0) + return S_FALSE; + + pos += file.UnPackSize; + CMultiStream::CSubStreamInfo subStreamInfo; + subStreamInfo.Stream = volume.Stream; + subStreamInfo.Pos = database.GetFolderStreamPos(folderIndex, 0); + subStreamInfo.Size = file.UnPackSize; + streamSpec->Streams.Add(subStreamInfo); + } + streamSpec->Init(); + *stream = streamTemp.Detach(); + return S_OK; +} +#endif + }} diff --git a/7zip/Archive/7z/7zHandler.h b/7zip/Archive/7z/7zHandler.h index a2c2e472..7966b86c 100755 --- a/7zip/Archive/7z/7zHandler.h +++ b/7zip/Archive/7z/7zHandler.h @@ -1,12 +1,9 @@ // 7z/Handler.h -#pragma once - #ifndef __7Z_HANDLER_H #define __7Z_HANDLER_H #include "../IArchive.h" -// #include "../../../Compress/Interface/CompressInterface.h" #include "7zIn.h" #include "7zCompressionMode.h" @@ -18,6 +15,32 @@ namespace NArchive { namespace N7z { +#ifdef _7Z_VOL +struct CRef +{ + int VolumeIndex; + int ItemIndex; +}; + +/* +struct CRef2 +{ + CRecordVector<CRef> Refs; + UInt64 UnPackSize; + UInt64 PackSize; + UInt64 StartPos; + CRef2(): UnPackSize(0), PackSize(0), StartPos(0) {} +}; +*/ + +struct CVolume +{ + int StartRef2Index; + CMyComPtr<IInStream> Stream; + CArchiveDatabaseEx Database; +}; +#endif + #ifndef EXTRACT_ONLY struct COneMethodInfo @@ -33,6 +56,9 @@ DEFINE_GUID(CLSID_CFormat7z, class CHandler: public IInArchive, + #ifdef _7Z_VOL + public IInArchiveGetStream, + #endif #ifndef EXTRACT_ONLY public IOutArchive, public ISetProperties, @@ -40,46 +66,50 @@ class CHandler: public CMyUnknownImp { public: - #ifdef EXTRACT_ONLY - MY_UNKNOWN_IMP - #else - MY_UNKNOWN_IMP3( - IInArchive, - IOutArchive, - ISetProperties - ) + MY_QUERYINTERFACE_BEGIN + #ifdef _7Z_VOL + MY_QUERYINTERFACE_ENTRY(IInArchiveGetStream) + #endif + #ifndef EXTRACT_ONLY + MY_QUERYINTERFACE_ENTRY(IOutArchive) + MY_QUERYINTERFACE_ENTRY(ISetProperties) #endif + MY_QUERYINTERFACE_END + MY_ADDREF_RELEASE STDMETHOD(Open)(IInStream *stream, - const UINT64 *maxCheckStartPosition, + const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback); STDMETHOD(Close)(); - STDMETHOD(GetNumberOfItems)(UINT32 *numItems); - STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(Extract)(const UINT32* indices, UINT32 numItems, - INT32 testMode, IArchiveExtractCallback *extractCallback); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback); STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); - STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties); - STDMETHOD(GetPropertyInfo)(UINT32 index, + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType); - STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties); - STDMETHOD(GetArchivePropertyInfo)(UINT32 index, + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType); + #ifdef _7Z_VOL + STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); + #endif #ifndef EXTRACT_ONLY // IOutArchiveHandler - STDMETHOD(UpdateItems)(IOutStream *outStream, UINT32 numItems, + STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback); - STDMETHOD(GetFileTimeType)(UINT32 *type); + STDMETHOD(GetFileTimeType)(UInt32 *type); // ISetProperties - STDMETHOD(SetProperties)(const BSTR *names, const PROPVARIANT *values, INT32 numProperties); + STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties); HRESULT SetSolidSettings(const UString &s); HRESULT SetSolidSettings(const PROPVARIANT &value); @@ -88,16 +118,20 @@ public: CHandler(); private: + #ifdef _7Z_VOL + CObjectVector<CVolume> _volumes; + CObjectVector<CRef> _refs; + #else CMyComPtr<IInStream> _inStream; - NArchive::N7z::CArchiveDatabaseEx _database; + #endif #ifndef EXTRACT_ONLY CObjectVector<COneMethodInfo> _methods; CRecordVector<CBind> _binds; bool _removeSfxBlock; - UINT64 _numSolidFiles; - UINT64 _numSolidBytes; + UInt64 _numSolidFiles; + UInt64 _numSolidBytes; bool _numSolidBytesDefined; bool _solidExtension; @@ -106,13 +140,17 @@ private: bool _encryptHeaders; bool _copyMode; - UINT32 _defaultDicSize; - UINT32 _defaultAlgorithm; - UINT32 _defaultFastBytes; + UInt32 _defaultDicSize; + UInt32 _defaultAlgorithm; + UInt32 _defaultFastBytes; UString _defaultMatchFinder; + UInt32 _defaultBZip2Passes; bool _autoFilter; bool _multiThread; - UINT32 _level; + UInt32 _level; + + bool _volumeMode; + HRESULT SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value); HRESULT SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString); @@ -132,25 +170,15 @@ private: #ifndef _SFX - CRecordVector<UINT64> _fileInfoPopIDs; + CRecordVector<UInt64> _fileInfoPopIDs; void FillPopIDs(); #endif #ifndef EXTRACT_ONLY - UINT64 GetUINT64MAX() const - { - return - #if (__GNUC__) - 0xFFFFFFFFFFFFFFFFLL - #else - 0xFFFFFFFFFFFFFFFF - #endif - ; - } - void InitSolidFiles() { _numSolidFiles = GetUINT64MAX(); } - void InitSolidSize() { _numSolidBytes = GetUINT64MAX(); } + void InitSolidFiles() { _numSolidFiles = UInt64(Int64(-1)); } + void InitSolidSize() { _numSolidBytes = UInt64(Int64(-1)); } void InitSolid() { InitSolidFiles(); @@ -167,8 +195,8 @@ private: */ void SetSolidBytesLimit() { - _numSolidBytes = ((UINT64)_defaultDicSize) << 7; - const UINT64 kMinSize = (1<<24); + _numSolidBytes = ((UInt64)_defaultDicSize) << 7; + const UInt64 kMinSize = (1<<24); if (_numSolidBytes < kMinSize) _numSolidBytes = kMinSize; } @@ -192,11 +220,13 @@ private: _multiThread = false; _copyMode = false; _defaultDicSize = (1 << 21); + _defaultBZip2Passes = 1; _defaultAlgorithm = 1; _defaultFastBytes = 32; _defaultMatchFinder = L"BT4"; _level = 5; _autoFilter = true; + _volumeMode = false; InitSolid(); SetSolidBytesLimit(); } diff --git a/7zip/Archive/7z/7zHandlerOut.cpp b/7zip/Archive/7z/7zHandlerOut.cpp index f29d9959..d8fe58fb 100755 --- a/7zip/Archive/7z/7zHandlerOut.cpp +++ b/7zip/Archive/7z/7zHandlerOut.cpp @@ -41,41 +41,57 @@ static CMethodID k_Copy = { { 0x0 }, 1 }; #endif #ifdef COMPRESS_DEFLATE +#ifndef COMPRESS_DEFLATE_ENCODER +#define COMPRESS_DEFLATE_ENCODER +#endif +#endif + +#ifdef COMPRESS_DEFLATE_ENCODER static CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 }; #endif #ifdef COMPRESS_BZIP2 +#ifndef COMPRESS_BZIP2_ENCODER +#define COMPRESS_BZIP2_ENCODER +#endif +#endif + +#ifdef COMPRESS_BZIP2_ENCODER static CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 }; #endif const wchar_t *kCopyMethod = L"Copy"; const wchar_t *kLZMAMethodName = L"LZMA"; +const wchar_t *kBZip2MethodName = L"BZip2"; -const UINT32 kAlgorithmForX7 = 2; -const UINT32 kDicSizeForX7 = 1 << 23; -const UINT32 kFastBytesForX7 = 64; +const UInt32 kAlgorithmForX7 = 2; +const UInt32 kDicSizeForX7 = 1 << 23; +const UInt32 kFastBytesForX7 = 64; -const UINT32 kAlgorithmForX9 = 2; -const UINT32 kDicSizeForX9 = 1 << 25; -const UINT32 kFastBytesForX9 = 64; +const UInt32 kAlgorithmForX9 = 2; +const UInt32 kDicSizeForX9 = 1 << 25; +const UInt32 kFastBytesForX9 = 64; static const wchar_t *kMatchFinderForX9 = L"BT4b"; -const UINT32 kAlgorithmForFast = 0; -const UINT32 kDicSizeForFast = 1 << 15; +const UInt32 kAlgorithmForFast = 0; +const UInt32 kDicSizeForFast = 1 << 15; static const wchar_t *kMatchFinderForFast = L"HC3"; const wchar_t *kDefaultMethodName = kLZMAMethodName; static const wchar_t *kMatchFinderForHeaders = L"BT2"; -static const UINT32 kDictionaryForHeaders = 1 << 20; -static const UINT32 kNumFastBytesForHeaders = 254; +static const UInt32 kDictionaryForHeaders = 1 << 20; +static const UInt32 kNumFastBytesForHeaders = 254; static bool IsLZMAMethod(const UString &methodName) { return (methodName.CompareNoCase(kLZMAMethodName) == 0); } static bool IsLZMethod(const UString &methodName) { return IsLZMAMethod(methodName); } -STDMETHODIMP CHandler::GetFileTimeType(UINT32 *type) +static bool IsBZip2Method(const UString &methodName) + { return (methodName.CompareNoCase(kBZip2MethodName) == 0); } + +STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type) { *type = NFileTimeType::kWindows; return S_OK; @@ -94,7 +110,7 @@ HRESULT CHandler::SetPassword(CCompressionMethodMode &methodMode, if (getTextPassword) { CMyComBSTR password; - INT32 passwordIsDefined; + Int32 passwordIsDefined; RINOK(getTextPassword->CryptoGetTextPassword2( &passwordIsDefined, &password)); if (methodMode.PasswordIsDefined = IntToBool(passwordIsDefined)) @@ -105,52 +121,6 @@ HRESULT CHandler::SetPassword(CCompressionMethodMode &methodMode, return S_OK; } -// it's work only for non-solid archives -/* -STDMETHODIMP CHandler::DeleteItems(IOutStream *outStream, - const UINT32* indices, UINT32 numItems, IUpdateCallback *updateCallback) -{ - COM_TRY_BEGIN - CRecordVector<bool> compressStatuses; - CRecordVector<UINT32> copyIndices; - int index = 0; - int i; - for(i = 0; i < _database.NumUnPackStreamsVector.Size(); i++) - { - if (_database.NumUnPackStreamsVector[i] != 1) - return E_NOTIMPL; - } - for(i = 0; i < _database.Files.Size(); i++) - { - // bool copyMode = true; - if(index < numItems && i == indices[index]) - index++; - else - { - compressStatuses.Add(false); - copyIndices.Add(i); - } - } - CCompressionMethodMode methodMode, headerMethod; - RINOK(SetCompressionMethod(methodMode, headerMethod)); - methodMode.MultiThread = _multiThread; - methodMode.MultiThreadMult = _multiThreadMult; - - headerMethod.MultiThread = false; - bool useAdditionalHeaderStreams = true; - bool compressMainHeader = false; - - // headerMethod.MultiThreadMult = _multiThreadMult; - - return UpdateMain(_database, compressStatuses, - CObjectVector<CUpdateItem>(), copyIndices, - outStream, _inStream, &_database.ArchiveInfo, - NULL, (_compressHeaders ? &headerMethod: 0), - useAdditionalHeaderStreams, compressMainHeader, - updateCallback, false, _removeSfxBlock); - COM_TRY_END -} -*/ struct CNameToPropID { PROPID PropID; @@ -184,10 +154,10 @@ bool ConvertProperty(PROPVARIANT srcProp, VARTYPE varType, { if(srcProp.vt == VT_UI4) { - UINT32 value = srcProp.ulVal; + UInt32 value = srcProp.ulVal; if (value > 0xFF) return false; - destProp = BYTE(value); + destProp = Byte(value); return true; } } @@ -235,13 +205,13 @@ HRESULT CHandler::SetCompressionMethod( { CProperty property; property.PropID = NCoderPropID::kNumFastBytes; - property.Value = UINT32(kNumFastBytesForHeaders); + property.Value = UInt32(kNumFastBytesForHeaders); oneMethodInfo.CoderProperties.Add(property); } { CProperty property; property.PropID = NCoderPropID::kDictionarySize; - property.Value = UINT32(kDictionaryForHeaders); + property.Value = UInt32(kDictionaryForHeaders); oneMethodInfo.CoderProperties.Add(property); } headerMethodInfoVector.Add(oneMethodInfo); @@ -309,6 +279,13 @@ HRESULT CHandler::SetCompressionMethod( NCoderPropID::kMultiThread, true); } } + else if (IsBZip2Method(oneMethodInfo.MethodName)) + { + SetOneMethodProp(oneMethodInfo, + NCoderPropID::kNumPasses, _defaultBZip2Passes); + } + + CMethodFull methodFull; methodFull.NumInStreams = 1; methodFull.NumOutStreams = 1; @@ -349,7 +326,7 @@ HRESULT CHandler::SetCompressionMethod( } #endif - #ifdef COMPRESS_DEFLATE + #ifdef COMPRESS_DEFLATE_ENCODER if (oneMethodInfo.MethodName.CompareNoCase(L"Deflate") == 0) { defined = true; @@ -357,7 +334,7 @@ HRESULT CHandler::SetCompressionMethod( } #endif - #ifdef COMPRESS_BZIP2 + #ifdef COMPRESS_BZIP2_ENCODER if (oneMethodInfo.MethodName.CompareNoCase(L"BZip2") == 0) { defined = true; @@ -410,24 +387,39 @@ HRESULT CHandler::SetCompressionMethod( return S_OK; } -STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems, +STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback) { COM_TRY_BEGIN + const CArchiveDatabaseEx *database = 0; + #ifdef _7Z_VOL + if(_volumes.Size() > 1) + return E_FAIL; + const CVolume *volume = 0; + if (_volumes.Size() == 1) + { + volume = &_volumes.Front(); + database = &volume->Database; + } + #else + if (_inStream != 0) + database = &_database; + #endif + // CRecordVector<bool> compressStatuses; CObjectVector<CUpdateItem> updateItems; - // CRecordVector<UINT32> copyIndices; + // CRecordVector<UInt32> copyIndices; // CMyComPtr<IUpdateCallback2> updateCallback2; // updateCallback->QueryInterface(&updateCallback2); int index = 0; - for(int i = 0; i < numItems; i++) + for(UInt32 i = 0; i < numItems; i++) { - INT32 newData; - INT32 newProperties; - UINT32 indexInArchive; + Int32 newData; + Int32 newProperties; + UInt32 indexInArchive; if (!updateCallback) return E_FAIL; RINOK(updateCallback->GetUpdateItemInfo(i, @@ -442,7 +434,7 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems, if (updateItem.IndexInArchive != -1) { - const CFileItem &fileItem = _database.Files[updateItem.IndexInArchive]; + const CFileItem &fileItem = database->Files[updateItem.IndexInArchive]; updateItem.Name = fileItem.Name; updateItem.IsDirectory = fileItem.IsDirectory; updateItem.Size = fileItem.UnPackSize; @@ -550,7 +542,7 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems, RINOK(updateCallback->GetProperty(i, kpidSize, &propVariant)); if (propVariant.vt != VT_UI8) return E_INVALIDARG; - updateItem.Size = *(const UINT64 *)(&propVariant.uhVal); + updateItem.Size = (UInt64)propVariant.uhVal.QuadPart; if (updateItem.Size != 0 && updateItem.IsAnti) return E_INVALIDARG; } @@ -605,40 +597,43 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems, if (numItems < 2) compressMainHeader = false; - CInArchiveInfo *inArchiveInfo; - if (!_inStream) - inArchiveInfo = 0; - else - inArchiveInfo = &_database.ArchiveInfo; - - return Update(_database, - // compressStatuses, - updateItems, - // copyIndices, - outStream, _inStream, inArchiveInfo, - methodMode, - (_compressHeaders || - (methodMode.PasswordIsDefined && _encryptHeaders)) ? - &headerMethod : 0, - _level != 0 && _autoFilter, // useFilters - _level >= 8, // maxFilter - useAdditionalHeaderStreams, compressMainHeader, - updateCallback, _numSolidFiles, _numSolidBytes, _solidExtension, - _removeSfxBlock); + CUpdateOptions options; + options.Method = &methodMode; + options.HeaderMethod = (_compressHeaders || + (methodMode.PasswordIsDefined && _encryptHeaders)) ? + &headerMethod : 0; + options.UseFilters = _level != 0 && _autoFilter; + options.MaxFilter = _level >= 8; + options.UseAdditionalHeaderStreams = useAdditionalHeaderStreams; + options.CompressMainHeader = compressMainHeader; + options.NumSolidFiles = _numSolidFiles; + options.NumSolidBytes = _numSolidBytes; + options.SolidExtension = _solidExtension; + options.RemoveSfxBlock = _removeSfxBlock; + options.VolumeMode = _volumeMode; + return Update( + #ifdef _7Z_VOL + volume ? volume->Stream: 0, + volume ? database: 0, + #else + _inStream, + database, + #endif + updateItems, outStream, updateCallback, options); COM_TRY_END } -static int ParseStringToUINT32(const UString &srcString, UINT32 &number) +static int ParseStringToUInt32(const UString &srcString, UInt32 &number) { const wchar_t *start = srcString; const wchar_t *end; - UINT64 number64 = ConvertStringToUINT64(start, &end); - if (number64 >= (UINT64(1) << 32)) + UInt64 number64 = ConvertStringToUInt64(start, &end); + if (number64 > 0xFFFFFFFF) { number = 0; return 0; } - number = number64; + number = (UInt32)number64; return end - start; } @@ -647,14 +642,14 @@ static const char kByteSymbol = 'B'; static const char kKiloByteSymbol = 'K'; static const char kMegaByteSymbol = 'M'; -HRESULT ParseDictionaryValues(const UString &srcStringSpec, UINT32 &dicSize) +HRESULT ParseDictionaryValues(const UString &srcStringSpec, UInt32 &dicSize) { UString srcString = srcStringSpec; srcString.MakeUpper(); const wchar_t *start = srcString; const wchar_t *end; - UINT64 number = ConvertStringToUINT64(start, &end); + UInt64 number = ConvertStringToUInt64(start, &end); int numDigits = end - start; if (numDigits == 0 || srcString.Length() > numDigits + 1) return E_INVALIDARG; @@ -662,25 +657,25 @@ HRESULT ParseDictionaryValues(const UString &srcStringSpec, UINT32 &dicSize) { if (number >= kLogarithmicSizeLimit) return E_INVALIDARG; - dicSize = (UINT32)1 << number; + dicSize = (UInt32)1 << (int)number; return S_OK; } switch (srcString[numDigits]) { case kByteSymbol: - if (number >= ((UINT64)1 << kLogarithmicSizeLimit)) + if (number >= ((UInt64)1 << kLogarithmicSizeLimit)) return E_INVALIDARG; - dicSize = (UINT32)number; + dicSize = (UInt32)number; break; case kKiloByteSymbol: - if (number >= ((UINT64)1 << (kLogarithmicSizeLimit - 10))) + if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 10))) return E_INVALIDARG; - dicSize = UINT32(number << 10); + dicSize = UInt32(number << 10); break; case kMegaByteSymbol: - if (number >= ((UINT64)1 << (kLogarithmicSizeLimit - 20))) + if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 20))) return E_INVALIDARG; - dicSize = UINT32(number << 20); + dicSize = UInt32(number << 20); break; default: return E_INVALIDARG; @@ -724,7 +719,7 @@ static HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value) } /* -static HRESULT SetComplexProperty(bool &boolStatus, UINT32 &number, +static HRESULT SetComplexProperty(bool &boolStatus, UInt32 &number, const PROPVARIANT &value) { switch(value.vt) @@ -746,17 +741,17 @@ static HRESULT SetComplexProperty(bool &boolStatus, UINT32 &number, } */ -static HRESULT GetBindInfoPart(UString &srcString, UINT32 &coder, UINT32 &stream) +static HRESULT GetBindInfoPart(UString &srcString, UInt32 &coder, UInt32 &stream) { stream = 0; - int index = ParseStringToUINT32(srcString, coder); + int index = ParseStringToUInt32(srcString, coder); if (index == 0) return E_INVALIDARG; srcString.Delete(0, index); if (srcString[0] == 'S') { srcString.Delete(0); - int index = ParseStringToUINT32(srcString, stream); + int index = ParseStringToUInt32(srcString, stream); if (index == 0) return E_INVALIDARG; srcString.Delete(0, index); @@ -824,7 +819,7 @@ HRESULT CHandler::SetParam(COneMethodInfo &oneMethodInfo, const UString &name, c CProperty property; if (name.CompareNoCase(L"D") == 0 || name.CompareNoCase(L"MEM") == 0) { - UINT32 dicSize; + UInt32 dicSize; RINOK(ParseDictionaryValues(value, dicSize)); if (name.CompareNoCase(L"D") == 0) property.PropID = NCoderPropID::kDictionarySize; @@ -849,8 +844,8 @@ HRESULT CHandler::SetParam(COneMethodInfo &oneMethodInfo, const UString &name, c propValue = value; else { - UINT32 number; - if (ParseStringToUINT32(value, number) == value.Length()) + UInt32 number; + if (ParseStringToUInt32(value, number) == value.Length()) propValue = number; else propValue = value; @@ -898,7 +893,7 @@ HRESULT CHandler::SetSolidSettings(const UString &s) { const wchar_t *start = ((const wchar_t *)s2) + i; const wchar_t *end; - UINT64 v = ConvertStringToUINT64(start, &end); + UInt64 v = ConvertStringToUInt64(start, &end); if (start == end) { if (s2[i++] != 'E') @@ -954,14 +949,14 @@ HRESULT CHandler::SetSolidSettings(const PROPVARIANT &value) } } -STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *values, INT32 numProperties) +STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) { UINT codePage = GetCurrentFileCodePage(); COM_TRY_BEGIN _methods.Clear(); _binds.Clear(); Init(); - int minNumber = 0; + UInt32 minNumber = 0; for (int i = 0; i < numProperties; i++) { @@ -986,7 +981,7 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value { if(!name.IsEmpty()) { - int index = ParseStringToUINT32(name, _level); + int index = ParseStringToUInt32(name, _level); if (index != name.Length()) return E_INVALIDARG; } @@ -996,15 +991,18 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value if (_level == 0) { _copyMode = true; + _defaultBZip2Passes = 1; } else if (_level < 5) { _defaultAlgorithm = kAlgorithmForFast; _defaultDicSize = kDicSizeForFast; _defaultMatchFinder = kMatchFinderForFast; + _defaultBZip2Passes = 1; } else if (_level < 7) { + _defaultBZip2Passes = 1; // normal; } else if(_level < 9) @@ -1012,6 +1010,7 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value _defaultAlgorithm = kAlgorithmForX7; _defaultDicSize = kDicSizeForX7; _defaultFastBytes = kFastBytesForX7; + _defaultBZip2Passes = 2; } else { @@ -1019,6 +1018,7 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value _defaultDicSize = kDicSizeForX9; _defaultFastBytes = kFastBytesForX9; _defaultMatchFinder = kMatchFinderForX9; + _defaultBZip2Passes = 7; } continue; } @@ -1047,8 +1047,8 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value } - UINT32 number; - int index = ParseStringToUINT32(name, number); + UInt32 number; + int index = ParseStringToUInt32(name, number); UString realName = name.Mid(index); if (index == 0) { @@ -1057,7 +1057,7 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value RINOK(SetBoolProperty(_removeSfxBlock, value)); continue; } - if (name.CompareNoCase(L"F") == 0) + else if (name.CompareNoCase(L"F") == 0) { RINOK(SetBoolProperty(_autoFilter, value)); continue; @@ -1084,16 +1084,19 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value // RINOK(SetComplexProperty(MultiThread, _multiThreadMult, value)); continue; } + else if (name.CompareNoCase(L"V") == 0) + { + RINOK(SetBoolProperty(_volumeMode, value)); + continue; + } number = 0; } - if (number > 100) + if (number > 10000) return E_FAIL; if (number < minNumber) - { return E_INVALIDARG; - } number -= minNumber; - for(int j = _methods.Size(); j <= number; j++) + for(int j = _methods.Size(); j <= (int)number; j++) { COneMethodInfo oneMethodInfo; _methods.Add(oneMethodInfo); @@ -1114,13 +1117,13 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value CProperty property; if (realName.CompareNoCase(L"D") == 0 || realName.CompareNoCase(L"MEM") == 0) { - UINT32 dicSize; + UInt32 dicSize; if (value.vt == VT_UI4) { - UINT32 logDicSize = value.ulVal; + UInt32 logDicSize = value.ulVal; if (logDicSize >= 32) return E_INVALIDARG; - dicSize = (UINT32)1 << logDicSize; + dicSize = (UInt32)1 << logDicSize; } else if (value.vt == VT_BSTR) { diff --git a/7zip/Archive/7z/7zHeader.cpp b/7zip/Archive/7z/7zHeader.cpp index 037e5c45..cff4d121 100755 --- a/7zip/Archive/7z/7zHeader.cpp +++ b/7zip/Archive/7z/7zHeader.cpp @@ -6,12 +6,13 @@ namespace NArchive { namespace N7z { -BYTE kSignature[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C}; +Byte kSignature[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C}; +Byte kFinishSignature[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C + 1}; class SignatureInitializer { public: - SignatureInitializer() { kSignature[0]--; }; + SignatureInitializer() { kSignature[0]--; kFinishSignature[0]--;}; } g_SignatureInitializer; }} diff --git a/7zip/Archive/7z/7zHeader.h b/7zip/Archive/7z/7zHeader.h index 7830cdc8..59bc7fe5 100755 --- a/7zip/Archive/7z/7zHeader.h +++ b/7zip/Archive/7z/7zHeader.h @@ -1,37 +1,53 @@ -// 7z/Header.h - -#pragma once +// 7z/7zHeader.h #ifndef __7Z_HEADER_H #define __7Z_HEADER_H -// #include "Common/Types.h" -// #include "../../../Common/CRC.h" - #include "7zMethodID.h" namespace NArchive { namespace N7z { -#pragma pack( push, Pragma7zHeaders) -#pragma pack( push, 1) - const int kSignatureSize = 6; -extern BYTE kSignature[kSignatureSize]; +extern Byte kSignature[kSignatureSize]; + +// #define _7Z_VOL +// 7z-MultiVolume is not finished yet. +// It can work already, but I still do not like some +// things of that new multivolume format. +// So please keep it commented. + +#ifdef _7Z_VOL +extern Byte kFinishSignature[kSignatureSize]; +#endif struct CArchiveVersion { - BYTE Major; - BYTE Minor; + Byte Major; + Byte Minor; }; +const Byte kMajorVersion = 0; + struct CStartHeader { - UINT64 NextHeaderOffset; - UINT64 NextHeaderSize; - UINT32 NextHeaderCRC; + UInt64 NextHeaderOffset; + UInt64 NextHeaderSize; + UInt32 NextHeaderCRC; +}; + +const UInt32 kStartHeaderSize = 20; + +#ifdef _7Z_VOL +struct CFinishHeader: public CStartHeader +{ + UInt64 ArchiveStartOffset; // data offset from end if that struct + UInt64 AdditionalStartBlockSize; // start signature & start header size }; +const UInt32 kFinishHeaderSize = kStartHeaderSize + 16; +#endif + namespace NID { enum EEnum @@ -70,16 +86,11 @@ namespace NID kComment, kEncodedHeader, + + kStartPos }; } - -#pragma pack(pop) -#pragma pack(pop, Pragma7zHeaders) - -const BYTE kMajorVersion = 0; - }} - #endif diff --git a/7zip/Archive/7z/7zIn.cpp b/7zip/Archive/7z/7zIn.cpp index cb4690d9..74d26f53 100755 --- a/7zip/Archive/7z/7zIn.cpp +++ b/7zip/Archive/7z/7zIn.cpp @@ -19,7 +19,7 @@ public: CStreamSwitch(): _needRemove(false) {} ~CStreamSwitch() { Remove(); } void Remove(); - void Set(CInArchive *archive, const BYTE *data, UINT32 size); + void Set(CInArchive *archive, const Byte *data, size_t size); void Set(CInArchive *archive, const CByteBuffer &byteBuffer); HRESULT Set(CInArchive *archive, const CObjectVector<CByteBuffer> *dataVector); }; @@ -33,7 +33,7 @@ void CStreamSwitch::Remove() } } -void CStreamSwitch::Set(CInArchive *archive, const BYTE *data, UINT32 size) +void CStreamSwitch::Set(CInArchive *archive, const Byte *data, size_t size) { Remove(); _archive = archive; @@ -49,13 +49,13 @@ void CStreamSwitch::Set(CInArchive *archive, const CByteBuffer &byteBuffer) HRESULT CStreamSwitch::Set(CInArchive *archive, const CObjectVector<CByteBuffer> *dataVector) { Remove(); - BYTE external; - RINOK(archive->SafeReadByte2(external)); + Byte external; + RINOK(archive->ReadByte(external)); if (external != 0) { - UINT64 dataIndex; - RINOK(archive->ReadNumber(dataIndex)); - Set(archive, (*dataVector)[(UINT32)dataIndex]); + CNum dataIndex; + RINOK(archive->ReadNum(dataIndex)); + Set(archive, (*dataVector)[dataIndex]); } return S_OK; } @@ -65,10 +65,10 @@ CInArchiveException::CInArchiveException(CCauseType cause): Cause(cause) {} -HRESULT CInArchive::ReadBytes(IInStream *stream, void *data, UINT32 size, - UINT32 *processedSize) +HRESULT CInArchive::ReadDirect(IInStream *stream, void *data, UInt32 size, + UInt32 *processedSize) { - UINT32 realProcessedSize; + UInt32 realProcessedSize; HRESULT result = stream->Read(data, size, &realProcessedSize); if(processedSize != NULL) *processedSize = realProcessedSize; @@ -76,81 +76,155 @@ HRESULT CInArchive::ReadBytes(IInStream *stream, void *data, UINT32 size, return result; } -HRESULT CInArchive::ReadBytes(void *data, UINT32 size, UINT32 *processedSize) +HRESULT CInArchive::ReadDirect(void *data, UInt32 size, UInt32 *processedSize) { - return ReadBytes(_stream, data, size, processedSize); + return ReadDirect(_stream, data, size, processedSize); } -HRESULT CInArchive::SafeReadBytes(void *data, UINT32 size) +HRESULT CInArchive::SafeReadDirect(void *data, UInt32 size) { - UINT32 realProcessedSize; - RINOK(ReadBytes(data, size, &realProcessedSize)); + UInt32 realProcessedSize; + RINOK(ReadDirect(data, size, &realProcessedSize)); if (realProcessedSize != size) throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive); return S_OK; } -HRESULT CInArchive::ReadNumber(UINT64 &value) +HRESULT CInArchive::SafeReadDirectByte(Byte &b) { - BYTE firstByte; - RINOK(SafeReadByte2(firstByte)); - BYTE mask = 0x80; + return SafeReadDirect(&b, 1); +} + +HRESULT CInArchive::SafeReadDirectUInt32(UInt32 &value) +{ + value = 0; + for (int i = 0; i < 4; i++) + { + Byte b; + RINOK(SafeReadDirectByte(b)); + value |= (UInt32(b) << (8 * i)); + } + return S_OK; +} + +HRESULT CInArchive::SafeReadDirectUInt64(UInt64 &value) +{ + value = 0; + for (int i = 0; i < 8; i++) + { + Byte b; + RINOK(SafeReadDirectByte(b)); + value |= (UInt64(b) << (8 * i)); + } + return S_OK; +} + +HRESULT CInArchive::ReadNumber(UInt64 &value) +{ + Byte firstByte; + RINOK(ReadByte(firstByte)); + Byte mask = 0x80; + value = 0; for (int i = 0; i < 8; i++) { if ((firstByte & mask) == 0) { - value = 0; - RINOK(SafeReadBytes2(&value, i)); - UINT64 highPart = firstByte & (mask - 1); + UInt64 highPart = firstByte & (mask - 1); value += (highPart << (i * 8)); return S_OK; } + Byte b; + RINOK(ReadByte(b)); + value |= (UInt64(b) << (8 * i)); mask >>= 1; } - return SafeReadBytes2(&value, 8); + return S_OK; +} + +HRESULT CInArchive::ReadNum(CNum &value) +{ + UInt64 value64; + RINOK(ReadNumber(value64)); + if (value64 > kNumMax) + return E_FAIL; + value = (CNum)value64; + return S_OK; +} + +HRESULT CInArchive::ReadUInt32(UInt32 &value) +{ + value = 0; + for (int i = 0; i < 4; i++) + { + Byte b; + RINOK(ReadByte(b)); + value |= (UInt32(b) << (8 * i)); + } + return S_OK; +} + +HRESULT CInArchive::ReadUInt64(UInt64 &value) +{ + value = 0; + for (int i = 0; i < 8; i++) + { + Byte b; + RINOK(ReadByte(b)); + value |= (UInt64(b) << (8 * i)); + } + return S_OK; } static inline bool TestSignatureCandidate(const void *testBytes) { - // return (memcmp(testBytes, kSignature, kSignatureSize) == 0); - for (UINT32 i = 0; i < kSignatureSize; i++) - if (((const BYTE *)testBytes)[i] != kSignature[i]) + for (int i = 0; i < kSignatureSize; i++) + if (((const Byte *)testBytes)[i] != kSignature[i]) + return false; + return true; +} + +#ifdef _7Z_VOL +static inline bool TestFinishSignatureCandidate(const void *testBytes) +{ + for (int i = 0; i < kSignatureSize; i++) + if (((const Byte *)testBytes)[i] != kFinishSignature[i]) return false; return true; } +#endif -HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UINT64 *searchHeaderSizeLimit) +HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit) { _position = _arhiveBeginStreamPosition; RINOK(stream->Seek(_arhiveBeginStreamPosition, STREAM_SEEK_SET, NULL)); - BYTE signature[kSignatureSize]; - UINT32 processedSize; - RINOK(ReadBytes(stream, signature, kSignatureSize, &processedSize)); + Byte signature[kSignatureSize]; + UInt32 processedSize; + RINOK(ReadDirect(stream, signature, kSignatureSize, &processedSize)); if(processedSize != kSignatureSize) return S_FALSE; if (TestSignatureCandidate(signature)) return S_OK; CByteBuffer byteBuffer; - static const UINT32 kSearchSignatureBufferSize = 0x10000; - byteBuffer.SetCapacity(kSearchSignatureBufferSize); - BYTE *buffer = byteBuffer; - UINT32 numBytesPrev = kSignatureSize - 1; - memmove(buffer, signature + 1, numBytesPrev); - UINT64 curTestPos = _arhiveBeginStreamPosition + 1; + const UInt32 kBufferSize = (1 << 16); + byteBuffer.SetCapacity(kBufferSize); + Byte *buffer = byteBuffer; + UInt32 numPrevBytes = kSignatureSize - 1; + memmove(buffer, signature + 1, numPrevBytes); + UInt64 curTestPos = _arhiveBeginStreamPosition + 1; while(true) { if (searchHeaderSizeLimit != NULL) if (curTestPos - _arhiveBeginStreamPosition > *searchHeaderSizeLimit) - return false; - UINT32 numReadBytes = kSearchSignatureBufferSize - numBytesPrev; - RINOK(ReadBytes(stream, buffer + numBytesPrev, numReadBytes, &processedSize)); - UINT32 numBytesInBuffer = numBytesPrev + processedSize; + return S_FALSE; + UInt32 numReadBytes = kBufferSize - numPrevBytes; + RINOK(ReadDirect(stream, buffer + numPrevBytes, numReadBytes, &processedSize)); + UInt32 numBytesInBuffer = numPrevBytes + processedSize; if (numBytesInBuffer < kSignatureSize) return S_FALSE; - UINT32 numTests = numBytesInBuffer - kSignatureSize + 1; - for(UINT32 pos = 0; pos < numTests; pos++, curTestPos++) + UInt32 numTests = numBytesInBuffer - kSignatureSize + 1; + for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++) { if (TestSignatureCandidate(buffer + pos)) { @@ -159,18 +233,81 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UINT64 *search return stream->Seek(_position, STREAM_SEEK_SET, NULL); } } - numBytesPrev = numBytesInBuffer - numTests; - memmove(buffer, buffer + numTests, numBytesPrev); + numPrevBytes = numBytesInBuffer - numTests; + memmove(buffer, buffer + numTests, numPrevBytes); } } +// Out: _position must point to end of signature + +#ifdef _7Z_VOL +HRESULT CInArchive::FindFinishSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit) +{ + RINOK(stream->Seek(0, STREAM_SEEK_END, &_position)); + if (_position < kSignatureSize) + return S_FALSE; + + CByteBuffer byteBuffer; + const UInt32 kBufferSize = (1 << 18); + byteBuffer.SetCapacity(kBufferSize); + Byte *buffer = byteBuffer; + UInt32 numPrevBytes = 0; + UInt64 limitPos = 0; + if (searchHeaderSizeLimit != NULL) + if (*searchHeaderSizeLimit < _position) + limitPos = _position - *searchHeaderSizeLimit; + + while(_position >= limitPos) + { + UInt32 numReadBytes = kBufferSize - numPrevBytes; + if (numReadBytes > _position) + numReadBytes = (UInt32)_position; + UInt32 numBytesInBuffer = numPrevBytes + numReadBytes; + if (numBytesInBuffer < kSignatureSize) + return S_FALSE; + _position -= numReadBytes; + RINOK(stream->Seek(_position, STREAM_SEEK_SET, &_position)); + UInt32 startPos = kBufferSize - numBytesInBuffer; + UInt32 processedSize; + RINOK(ReadDirect(stream, buffer + startPos, numReadBytes, &processedSize)); + if (processedSize != numReadBytes) + return S_FALSE; + _position -= processedSize; + for(UInt32 pos = kBufferSize; pos >= startPos + kSignatureSize; pos--) + { + if (TestFinishSignatureCandidate(buffer + pos - kSignatureSize)) + { + _position += pos - startPos; + return stream->Seek(_position, STREAM_SEEK_SET, NULL); + } + } + numPrevBytes = kSignatureSize - 1; + memmove(buffer + kBufferSize - numPrevBytes, buffer + startPos + 1, numPrevBytes); + } + return S_FALSE; +} +#endif + // S_FALSE means that file is not archive -HRESULT CInArchive::Open(IInStream *stream, const UINT64 *searchHeaderSizeLimit) +HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit) { Close(); RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_arhiveBeginStreamPosition)) _position = _arhiveBeginStreamPosition; + #ifdef _7Z_VOL + HRESULT result = FindFinishSignature(stream, searchHeaderSizeLimit); + if (result == S_OK) + _finishSignature = true; + else + { + if (result != S_FALSE) + return result; + _finishSignature = false; + RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit)); + } + #else RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit)); + #endif _stream = stream; return S_OK; } @@ -180,19 +317,19 @@ void CInArchive::Close() _stream.Release(); } -HRESULT CInArchive::SkeepData(UINT64 size) +HRESULT CInArchive::SkeepData(UInt64 size) { - for (UINT64 i = 0; i < size; i++) + for (UInt64 i = 0; i < size; i++) { - BYTE temp; - RINOK(SafeReadByte2(temp)); + Byte temp; + RINOK(ReadByte(temp)); } return S_OK; } HRESULT CInArchive::SkeepData() { - UINT64 size; + UInt64 size; RINOK(ReadNumber(size)); return SkeepData(size); } @@ -201,7 +338,7 @@ HRESULT CInArchive::ReadArchiveProperties(CInArchiveInfo &archiveInfo) { while(true) { - UINT64 type; + UInt64 type; RINOK(ReadID(type)); if (type == NID::kEnd) break; @@ -212,99 +349,91 @@ HRESULT CInArchive::ReadArchiveProperties(CInArchiveInfo &archiveInfo) HRESULT CInArchive::GetNextFolderItem(CFolder &folder) { - UINT64 numCoders; - RINOK(ReadNumber(numCoders)); + CNum numCoders; + RINOK(ReadNum(numCoders)); folder.Coders.Clear(); folder.Coders.Reserve((int)numCoders); - UINT32 numInStreams = 0; - UINT32 numOutStreams = 0; - UINT32 i; + CNum numInStreams = 0; + CNum numOutStreams = 0; + CNum i; for (i = 0; i < numCoders; i++) { folder.Coders.Add(CCoderInfo()); - CCoderInfo &coderInfo = folder.Coders.Back(); + CCoderInfo &coder = folder.Coders.Back(); while (true) { - coderInfo.AltCoders.Add(CAltCoderInfo()); - CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Back(); - BYTE mainByte; - RINOK(SafeReadByte2(mainByte)); - altCoderInfo.MethodID.IDSize = mainByte & 0xF; - bool isComplex = (mainByte & 0x10) != 0; - bool tereAreProperties = (mainByte & 0x20) != 0; - RINOK(SafeReadBytes2(&altCoderInfo.MethodID.ID[0], - altCoderInfo.MethodID.IDSize)); - if (isComplex) + coder.AltCoders.Add(CAltCoderInfo()); + CAltCoderInfo &altCoder = coder.AltCoders.Back(); + Byte mainByte; + RINOK(ReadByte(mainByte)); + altCoder.MethodID.IDSize = mainByte & 0xF; + RINOK(ReadBytes(altCoder.MethodID.ID, altCoder.MethodID.IDSize)); + if ((mainByte & 0x10) != 0) { - RINOK(ReadNumber(coderInfo.NumInStreams)); - RINOK(ReadNumber(coderInfo.NumOutStreams)); + RINOK(ReadNum(coder.NumInStreams)); + RINOK(ReadNum(coder.NumOutStreams)); } else { - coderInfo.NumInStreams = 1; - coderInfo.NumOutStreams = 1; + coder.NumInStreams = 1; + coder.NumOutStreams = 1; } - UINT64 propertiesSize = 0; - if (tereAreProperties) + if ((mainByte & 0x20) != 0) { - RINOK(ReadNumber(propertiesSize)); + CNum propertiesSize = 0; + RINOK(ReadNum(propertiesSize)); + altCoder.Properties.SetCapacity((size_t)propertiesSize); + RINOK(ReadBytes((Byte *)altCoder.Properties, (size_t)propertiesSize)); } - altCoderInfo.Properties.SetCapacity((UINT32)propertiesSize); - RINOK(SafeReadBytes2((BYTE *)altCoderInfo.Properties, - (UINT32)propertiesSize)); - - // coderInfo.AltCoders.Add(coderInfo.AltCoders.Back()); if ((mainByte & 0x80) == 0) break; } - numInStreams += (UINT32)coderInfo.NumInStreams; - numOutStreams += (UINT32)coderInfo.NumOutStreams; + numInStreams += coder.NumInStreams; + numOutStreams += coder.NumOutStreams; } - UINT64 numBindPairs; + CNum numBindPairs; // RINOK(ReadNumber(numBindPairs)); numBindPairs = numOutStreams - 1; folder.BindPairs.Clear(); - folder.BindPairs.Reserve((UINT32)numBindPairs); + folder.BindPairs.Reserve(numBindPairs); for (i = 0; i < numBindPairs; i++) { CBindPair bindPair; - RINOK(ReadNumber(bindPair.InIndex)); - RINOK(ReadNumber(bindPair.OutIndex)); + RINOK(ReadNum(bindPair.InIndex)); + RINOK(ReadNum(bindPair.OutIndex)); folder.BindPairs.Add(bindPair); } - UINT32 numPackedStreams = numInStreams - (UINT32)numBindPairs; + CNum numPackedStreams = numInStreams - numBindPairs; folder.PackStreams.Reserve(numPackedStreams); if (numPackedStreams == 1) { - for (UINT32 j = 0; j < numInStreams; j++) + for (CNum j = 0; j < numInStreams; j++) if (folder.FindBindPairForInStream(j) < 0) { - CPackStreamInfo packStreamInfo; - packStreamInfo.Index = j; - folder.PackStreams.Add(packStreamInfo); + folder.PackStreams.Add(j); break; } } else for(i = 0; i < numPackedStreams; i++) { - CPackStreamInfo packStreamInfo; - RINOK(ReadNumber(packStreamInfo.Index)); + CNum packStreamInfo; + RINOK(ReadNum(packStreamInfo)); folder.PackStreams.Add(packStreamInfo); } return S_OK; } -HRESULT CInArchive::WaitAttribute(UINT64 attribute) +HRESULT CInArchive::WaitAttribute(UInt64 attribute) { while(true) { - UINT64 type; + UInt64 type; RINOK(ReadID(type)); if (type == attribute) return S_OK; @@ -316,42 +445,42 @@ HRESULT CInArchive::WaitAttribute(UINT64 attribute) HRESULT CInArchive::ReadHashDigests(int numItems, CRecordVector<bool> &digestsDefined, - CRecordVector<UINT32> &digests) + CRecordVector<UInt32> &digests) { RINOK(ReadBoolVector2(numItems, digestsDefined)); digests.Clear(); digests.Reserve(numItems); for(int i = 0; i < numItems; i++) { - UINT32 crc; + UInt32 crc; if (digestsDefined[i]) - RINOK(SafeReadBytes2(&crc, sizeof(crc))); + RINOK(ReadUInt32(crc)); digests.Add(crc); } return S_OK; } HRESULT CInArchive::ReadPackInfo( - UINT64 &dataOffset, - CRecordVector<UINT64> &packSizes, + UInt64 &dataOffset, + CRecordVector<UInt64> &packSizes, CRecordVector<bool> &packCRCsDefined, - CRecordVector<UINT32> &packCRCs) + CRecordVector<UInt32> &packCRCs) { RINOK(ReadNumber(dataOffset)); - UINT64 numPackStreams; - RINOK(ReadNumber(numPackStreams)); + CNum numPackStreams; + RINOK(ReadNum(numPackStreams)); RINOK(WaitAttribute(NID::kSize)); packSizes.Clear(); - packSizes.Reserve((UINT32)numPackStreams); - for(UINT64 i = 0; i < numPackStreams; i++) + packSizes.Reserve(numPackStreams); + for(CNum i = 0; i < numPackStreams; i++) { - UINT64 size; + UInt64 size; RINOK(ReadNumber(size)); packSizes.Add(size); } - UINT64 type; + UInt64 type; while(true) { RINOK(ReadID(type)); @@ -359,19 +488,18 @@ HRESULT CInArchive::ReadPackInfo( break; if (type == NID::kCRC) { - RINOK(ReadHashDigests( - (UINT32)numPackStreams, packCRCsDefined, packCRCs)); + RINOK(ReadHashDigests(numPackStreams, packCRCsDefined, packCRCs)); continue; } RINOK(SkeepData()); } if (packCRCsDefined.IsEmpty()) { - packCRCsDefined.Reserve((UINT32)numPackStreams); + packCRCsDefined.Reserve(numPackStreams); packCRCsDefined.Clear(); - packCRCs.Reserve((UINT32)numPackStreams); + packCRCs.Reserve(numPackStreams); packCRCs.Clear(); - for(UINT64 i = 0; i < numPackStreams; i++) + for(CNum i = 0; i < numPackStreams; i++) { packCRCsDefined.Add(false); packCRCs.Add(0); @@ -385,15 +513,15 @@ HRESULT CInArchive::ReadUnPackInfo( CObjectVector<CFolder> &folders) { RINOK(WaitAttribute(NID::kFolder)); - UINT64 numFolders; - RINOK(ReadNumber(numFolders)); + CNum numFolders; + RINOK(ReadNum(numFolders)); { CStreamSwitch streamSwitch; RINOK(streamSwitch.Set(this, dataVector)); folders.Clear(); - folders.Reserve((UINT32)numFolders); - for(UINT64 i = 0; i < numFolders; i++) + folders.Reserve((UInt32)numFolders); + for(CNum i = 0; i < numFolders; i++) { folders.Add(CFolder()); RINOK(GetNextFolderItem(folders.Back())); @@ -402,15 +530,15 @@ HRESULT CInArchive::ReadUnPackInfo( RINOK(WaitAttribute(NID::kCodersUnPackSize)); - UINT32 i; + CNum i; for(i = 0; i < numFolders; i++) { CFolder &folder = folders[i]; - UINT32 numOutStreams = (UINT32)folder.GetNumOutStreams(); + CNum numOutStreams = folder.GetNumOutStreams(); folder.UnPackSizes.Reserve(numOutStreams); - for(UINT32 j = 0; j < numOutStreams; j++) + for(CNum j = 0; j < numOutStreams; j++) { - UINT64 unPackSize; + UInt64 unPackSize; RINOK(ReadNumber(unPackSize)); folder.UnPackSizes.Add(unPackSize); } @@ -418,15 +546,15 @@ HRESULT CInArchive::ReadUnPackInfo( while(true) { - UINT64 type; + UInt64 type; RINOK(ReadID(type)); if (type == NID::kEnd) return S_OK; if (type == NID::kCRC) { CRecordVector<bool> crcsDefined; - CRecordVector<UINT32> crcs; - RINOK(ReadHashDigests((UINT32)numFolders, crcsDefined, crcs)); + CRecordVector<UInt32> crcs; + RINOK(ReadHashDigests(numFolders, crcsDefined, crcs)); for(i = 0; i < numFolders; i++) { CFolder &folder = folders[i]; @@ -441,14 +569,14 @@ HRESULT CInArchive::ReadUnPackInfo( HRESULT CInArchive::ReadSubStreamsInfo( const CObjectVector<CFolder> &folders, - CRecordVector<UINT64> &numUnPackStreamsInFolders, - CRecordVector<UINT64> &unPackSizes, + CRecordVector<CNum> &numUnPackStreamsInFolders, + CRecordVector<UInt64> &unPackSizes, CRecordVector<bool> &digestsDefined, - CRecordVector<UINT32> &digests) + CRecordVector<UInt32> &digests) { numUnPackStreamsInFolders.Clear(); numUnPackStreamsInFolders.Reserve(folders.Size()); - UINT64 type; + UInt64 type; while(true) { RINOK(ReadID(type)); @@ -456,8 +584,8 @@ HRESULT CInArchive::ReadSubStreamsInfo( { for(int i = 0; i < folders.Size(); i++) { - UINT64 value; - RINOK(ReadNumber(value)); + CNum value; + RINOK(ReadNum(value)); numUnPackStreamsInFolders.Add(value); } continue; @@ -476,10 +604,15 @@ HRESULT CInArchive::ReadSubStreamsInfo( int i; for(i = 0; i < numUnPackStreamsInFolders.Size(); i++) { - UINT64 sum = 0; - for (UINT64 j = 1; j < numUnPackStreamsInFolders[i]; j++) + // v3.13 incorrectly worked with empty folders + // v4.07: we check that folder is empty + CNum numSubstreams = numUnPackStreamsInFolders[i]; + if (numSubstreams == 0) + continue; + UInt64 sum = 0; + for (CNum j = 1; j < numSubstreams; j++) { - UINT64 size; + UInt64 size; if (type == NID::kSize) { RINOK(ReadNumber(size)); @@ -498,7 +631,7 @@ HRESULT CInArchive::ReadSubStreamsInfo( int numDigestsTotal = 0; for(i = 0; i < folders.Size(); i++) { - UINT32 numSubstreams = (UINT32)numUnPackStreamsInFolders[i]; + CNum numSubstreams = numUnPackStreamsInFolders[i]; if (numSubstreams != 1 || !folders[i].UnPackCRCDefined) numDigests += numSubstreams; numDigestsTotal += numSubstreams; @@ -509,12 +642,12 @@ HRESULT CInArchive::ReadSubStreamsInfo( if (type == NID::kCRC) { CRecordVector<bool> digestsDefined2; - CRecordVector<UINT32> digests2; + CRecordVector<UInt32> digests2; RINOK(ReadHashDigests(numDigests, digestsDefined2, digests2)); int digestIndex = 0; for (i = 0; i < folders.Size(); i++) { - int numSubstreams = (UINT32)numUnPackStreamsInFolders[i]; + CNum numSubstreams = numUnPackStreamsInFolders[i]; const CFolder &folder = folders[i]; if (numSubstreams == 1 && folder.UnPackCRCDefined) { @@ -522,7 +655,7 @@ HRESULT CInArchive::ReadSubStreamsInfo( digests.Add(folder.UnPackCRC); } else - for (int j = 0; j < numSubstreams; j++, digestIndex++) + for (CNum j = 0; j < numSubstreams; j++, digestIndex++) { digestsDefined.Add(digestsDefined2[digestIndex]); digests.Add(digests2[digestIndex]); @@ -551,22 +684,21 @@ HRESULT CInArchive::ReadSubStreamsInfo( } } - HRESULT CInArchive::ReadStreamsInfo( const CObjectVector<CByteBuffer> *dataVector, - UINT64 &dataOffset, - CRecordVector<UINT64> &packSizes, + UInt64 &dataOffset, + CRecordVector<UInt64> &packSizes, CRecordVector<bool> &packCRCsDefined, - CRecordVector<UINT32> &packCRCs, + CRecordVector<UInt32> &packCRCs, CObjectVector<CFolder> &folders, - CRecordVector<UINT64> &numUnPackStreamsInFolders, - CRecordVector<UINT64> &unPackSizes, + CRecordVector<CNum> &numUnPackStreamsInFolders, + CRecordVector<UInt64> &unPackSizes, CRecordVector<bool> &digestsDefined, - CRecordVector<UINT32> &digests) + CRecordVector<UInt32> &digests) { while(true) { - UINT64 type; + UInt64 type; RINOK(ReadID(type)); switch(type) { @@ -593,71 +725,58 @@ HRESULT CInArchive::ReadStreamsInfo( } } - HRESULT CInArchive::ReadFileNames(CObjectVector<CFileItem> &files) { - // UINT32 pos = 0; for(int i = 0; i < files.Size(); i++) { UString &name = files[i].Name; name.Empty(); while (true) { - // if (pos >= size) - // return S_FALSE; wchar_t c; - RINOK(SafeReadWideCharLE(c)); - // pos++; - if (c == '\0') + RINOK(ReadWideCharLE(c)); + if (c == L'\0') break; name += c; } } - // if (pos != size) - // return S_FALSE; return S_OK; } -HRESULT CInArchive::CheckIntegrity() +HRESULT CInArchive::ReadBoolVector(int numItems, CBoolVector &v) { - return S_OK; -} - - -HRESULT CInArchive::ReadBoolVector(UINT32 numItems, CBoolVector &vector) -{ - vector.Clear(); - vector.Reserve(numItems); - BYTE b; - BYTE mask = 0; - for(UINT32 i = 0; i < numItems; i++) + v.Clear(); + v.Reserve(numItems); + Byte b; + Byte mask = 0; + for(int i = 0; i < numItems; i++) { if (mask == 0) { - RINOK(SafeReadBytes2(&b, 1)); + RINOK(ReadByte(b)); mask = 0x80; } - vector.Add((b & mask) != 0); + v.Add((b & mask) != 0); mask >>= 1; } return S_OK; } -HRESULT CInArchive::ReadBoolVector2(UINT32 numItems, CBoolVector &vector) +HRESULT CInArchive::ReadBoolVector2(int numItems, CBoolVector &v) { - BYTE allAreDefinedFlag; - RINOK(SafeReadByte2(allAreDefinedFlag)); - if (allAreDefinedFlag == 0) - return ReadBoolVector(numItems, vector); - vector.Clear(); - vector.Reserve(numItems); - for (UINT32 j = 0; j < numItems; j++) - vector.Add(true); + Byte allAreDefined; + RINOK(ReadByte(allAreDefined)); + if (allAreDefined == 0) + return ReadBoolVector(numItems, v); + v.Clear(); + v.Reserve(numItems); + for (int i = 0; i < numItems; i++) + v.Add(true); return S_OK; } HRESULT CInArchive::ReadTime(const CObjectVector<CByteBuffer> &dataVector, - CObjectVector<CFileItem> &files, UINT64 type) + CObjectVector<CFileItem> &files, UInt64 type) { CBoolVector boolVector; RINOK(ReadBoolVector2(files.Size(), boolVector)) @@ -672,12 +791,16 @@ HRESULT CInArchive::ReadTime(const CObjectVector<CByteBuffer> &dataVector, bool defined = boolVector[i]; if (defined) { - RINOK(SafeReadBytes2(&fileTime, sizeof(fileTime))); + UInt32 low, high; + RINOK(ReadUInt32(low)); + RINOK(ReadUInt32(high)); + fileTime.dwLowDateTime = low; + fileTime.dwHighDateTime = high; } switch(type) { case NID::kCreationTime: - file.IsCreationTimeDefined= defined; + file.IsCreationTimeDefined = defined; if (defined) file.CreationTime = fileTime; break; @@ -696,22 +819,22 @@ HRESULT CInArchive::ReadTime(const CObjectVector<CByteBuffer> &dataVector, return S_OK; } -HRESULT CInArchive::ReadAndDecodePackedStreams(UINT64 baseOffset, - UINT64 &dataOffset, CObjectVector<CByteBuffer> &dataVector +HRESULT CInArchive::ReadAndDecodePackedStreams(UInt64 baseOffset, + UInt64 &dataOffset, CObjectVector<CByteBuffer> &dataVector #ifndef _NO_CRYPTO , ICryptoGetTextPassword *getTextPassword #endif ) { - CRecordVector<UINT64> packSizes; + CRecordVector<UInt64> packSizes; CRecordVector<bool> packCRCsDefined; - CRecordVector<UINT32> packCRCs; + CRecordVector<UInt32> packCRCs; CObjectVector<CFolder> folders; - CRecordVector<UINT64> numUnPackStreamsInFolders; - CRecordVector<UINT64> unPackSizes; + CRecordVector<CNum> numUnPackStreamsInFolders; + CRecordVector<UInt64> unPackSizes; CRecordVector<bool> digestsDefined; - CRecordVector<UINT32> digests; + CRecordVector<UInt32> digests; RINOK(ReadStreamsInfo(NULL, dataOffset, @@ -726,20 +849,24 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(UINT64 baseOffset, // database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader; - UINT32 packIndex = 0; - CDecoder decoder; - UINT64 dataStartPos = baseOffset + dataOffset; + CNum packIndex = 0; + CDecoder decoder(false); + UInt64 dataStartPos = baseOffset + dataOffset; for(int i = 0; i < folders.Size(); i++) { const CFolder &folder = folders[i]; dataVector.Add(CByteBuffer()); CByteBuffer &data = dataVector.Back(); - UINT64 unPackSize = folder.GetUnPackSize(); - data.SetCapacity((UINT32)unPackSize); + UInt64 unPackSize = folder.GetUnPackSize(); + if (unPackSize > kNumMax) + return E_FAIL; + if (unPackSize > 0xFFFFFFFF) + return E_FAIL; + data.SetCapacity((size_t)unPackSize); CSequentialOutStreamImp2 *outStreamSpec = new CSequentialOutStreamImp2; CMyComPtr<ISequentialOutStream> outStream = outStreamSpec; - outStreamSpec->Init(data, (UINT32)unPackSize); + outStreamSpec->Init(data, (size_t)unPackSize); HRESULT result = decoder.Decode(_stream, dataStartPos, &packSizes[packIndex], folder, outStream, NULL @@ -750,7 +877,7 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(UINT64 baseOffset, RINOK(result); if (folder.UnPackCRCDefined) - if (!CCRC::VerifyDigest(folder.UnPackCRC, data, (UINT32)unPackSize)) + if (!CCRC::VerifyDigest(folder.UnPackCRC, data, (UInt32)unPackSize)) throw CInArchiveException(CInArchiveException::kIncorrectHeader); for (int j = 0; j < folder.PackStreams.Size(); j++) dataStartPos += packSizes[packIndex++]; @@ -764,9 +891,7 @@ HRESULT CInArchive::ReadHeader(CArchiveDatabaseEx &database #endif ) { - // database.Clear(); - - UINT64 type; + UInt64 type; RINOK(ReadID(type)); if (type == NID::kArchiveProperties) @@ -779,56 +904,6 @@ HRESULT CInArchive::ReadHeader(CArchiveDatabaseEx &database if (type == NID::kAdditionalStreamsInfo) { - /* - CRecordVector<UINT64> packSizes; - CRecordVector<bool> packCRCsDefined; - CRecordVector<UINT32> packCRCs; - CObjectVector<CFolder> folders; - - CRecordVector<UINT64> numUnPackStreamsInFolders; - CRecordVector<UINT64> unPackSizes; - CRecordVector<bool> digestsDefined; - CRecordVector<UINT32> digests; - - RINOK(ReadStreamsInfo(NULL, - database.ArchiveInfo.DataStartPosition2, - packSizes, - packCRCsDefined, - packCRCs, - folders, - numUnPackStreamsInFolders, - unPackSizes, - digestsDefined, - digests)); - - database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader; - - UINT32 packIndex = 0; - CDecoder decoder; - UINT64 dataStartPos = database.ArchiveInfo.DataStartPosition2; - for(int i = 0; i < folders.Size(); i++) - { - const CFolder &folder = folders[i]; - dataVector.Add(CByteBuffer()); - CByteBuffer &data = dataVector.Back(); - UINT64 unPackSize = folder.GetUnPackSize(); - data.SetCapacity(unPackSize); - - CComObjectNoLock<CSequentialOutStreamImp2> *outStreamSpec = - new CComObjectNoLock<CSequentialOutStreamImp2>; - CMyComPtr<ISequentialOutStream> outStream = outStreamSpec; - outStreamSpec->Init(data, unPackSize); - - RINOK(decoder.Decode(_stream, dataStartPos, - &packSizes[packIndex], folder, outStream, NULL, getTextPassword)); - - if (folder.UnPackCRCDefined) - if (!CCRC::VerifyDigest(folder.UnPackCRC, data, unPackSize)) - throw CInArchiveException(CInArchiveException::kIncorrectHeader); - for (int j = 0; j < folder.PackStreams.Size(); j++) - dataStartPos += packSizes[packIndex++]; - } - */ HRESULT result = ReadAndDecodePackedStreams( database.ArchiveInfo.StartPositionAfterHeader, database.ArchiveInfo.DataStartPosition2, @@ -838,14 +913,13 @@ HRESULT CInArchive::ReadHeader(CArchiveDatabaseEx &database #endif ); RINOK(result); - database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader; RINOK(ReadID(type)); } - CRecordVector<UINT64> unPackSizes; + CRecordVector<UInt64> unPackSizes; CRecordVector<bool> digestsDefined; - CRecordVector<UINT32> digests; + CRecordVector<UInt32> digests; if (type == NID::kMainStreamsInfo) { @@ -874,8 +948,6 @@ HRESULT CInArchive::ReadHeader(CArchiveDatabaseEx &database } } - UINT64 numUnPackStreamsTotal = 0; - database.Files.Clear(); if (type == NID::kEnd) @@ -883,26 +955,18 @@ HRESULT CInArchive::ReadHeader(CArchiveDatabaseEx &database if (type != NID::kFilesInfo) throw CInArchiveException(CInArchiveException::kIncorrectHeader); - UINT64 numFiles; - RINOK(ReadNumber(numFiles)); - database.Files.Reserve((size_t)numFiles); - UINT64 i; + CNum numFiles; + RINOK(ReadNum(numFiles)); + database.Files.Reserve(numFiles); + CNum i; for(i = 0; i < numFiles; i++) database.Files.Add(CFileItem()); - // int sizePrev = -1; - // int posPrev = 0; - database.ArchiveInfo.FileInfoPopIDs.Add(NID::kSize); if (!database.PackSizes.IsEmpty()) database.ArchiveInfo.FileInfoPopIDs.Add(NID::kPackInfo); - if (numFiles > 0) - { - if (!digests.IsEmpty()) - { - database.ArchiveInfo.FileInfoPopIDs.Add(NID::kCRC); - } - } + if (numFiles > 0 && !digests.IsEmpty()) + database.ArchiveInfo.FileInfoPopIDs.Add(NID::kCRC); CBoolVector emptyStreamVector; emptyStreamVector.Reserve((size_t)numFiles); @@ -910,7 +974,10 @@ HRESULT CInArchive::ReadHeader(CArchiveDatabaseEx &database emptyStreamVector.Add(false); CBoolVector emptyFileVector; CBoolVector antiFileVector; - UINT32 numEmptyStreams = 0; + CNum numEmptyStreams = 0; + + // int sizePrev = -1; + // int posPrev = 0; while(true) { @@ -919,11 +986,11 @@ HRESULT CInArchive::ReadHeader(CArchiveDatabaseEx &database if (sizePrev != _inByteBack->GetProcessedSize() - posPrev) throw 2; */ - UINT64 type; + UInt64 type; RINOK(ReadID(type)); if (type == NID::kEnd) break; - UINT64 size; + UInt64 size; RINOK(ReadNumber(size)); // sizePrev = size; @@ -947,20 +1014,34 @@ HRESULT CInArchive::ReadHeader(CArchiveDatabaseEx &database RINOK(streamSwitch.Set(this, &dataVector)); for(i = 0; i < numFiles; i++) { - CFileItem &file = database.Files[(UINT32)i]; - if (file.AreAttributesDefined = boolVector[(UINT32)i]) + CFileItem &file = database.Files[i]; + if (file.AreAttributesDefined = boolVector[i]) + { + RINOK(ReadUInt32(file.Attributes)); + } + } + break; + } + case NID::kStartPos: + { + CBoolVector boolVector; + RINOK(ReadBoolVector2(database.Files.Size(), boolVector)) + CStreamSwitch streamSwitch; + RINOK(streamSwitch.Set(this, &dataVector)); + for(i = 0; i < numFiles; i++) + { + CFileItem &file = database.Files[i]; + if (file.IsStartPosDefined = boolVector[i]) { - RINOK(SafeReadBytes2(&file.Attributes, - sizeof(file.Attributes))); + RINOK(ReadUInt64(file.StartPos)); } } break; } case NID::kEmptyStream: { - RINOK(ReadBoolVector((UINT32)numFiles, emptyStreamVector)) - UINT32 i; - for (i = 0; i < (UINT32)emptyStreamVector.Size(); i++) + RINOK(ReadBoolVector(numFiles, emptyStreamVector)) + for (i = 0; i < (CNum)emptyStreamVector.Size(); i++) if (emptyStreamVector[i]) numEmptyStreams++; emptyFileVector.Reserve(numEmptyStreams); @@ -997,19 +1078,19 @@ HRESULT CInArchive::ReadHeader(CArchiveDatabaseEx &database } } - UINT32 emptyFileIndex = 0; - UINT32 sizeIndex = 0; + CNum emptyFileIndex = 0; + CNum sizeIndex = 0; for(i = 0; i < numFiles; i++) { - CFileItem &file = database.Files[(UINT32)i]; - file.HasStream = !emptyStreamVector[(UINT32)i]; + CFileItem &file = database.Files[i]; + file.HasStream = !emptyStreamVector[i]; if(file.HasStream) { file.IsDirectory = false; file.IsAnti = false; file.UnPackSize = unPackSizes[sizeIndex]; file.FileCRC = digests[sizeIndex]; - file.FileCRCIsDefined = digestsDefined[sizeIndex]; + file.IsFileCRCDefined = digestsDefined[sizeIndex]; sizeIndex++; } else @@ -1018,7 +1099,7 @@ HRESULT CInArchive::ReadHeader(CArchiveDatabaseEx &database file.IsAnti = antiFileVector[emptyFileIndex]; emptyFileIndex++; file.UnPackSize = 0; - file.FileCRCIsDefined = false; + file.IsFileCRCDefined = false; } } return S_OK; @@ -1029,11 +1110,11 @@ void CArchiveDatabaseEx::FillFolderStartPackStream() { FolderStartPackStreamIndex.Clear(); FolderStartPackStreamIndex.Reserve(Folders.Size()); - UINT64 startPos = 0; - for(UINT64 i = 0; i < Folders.Size(); i++) + CNum startPos = 0; + for(int i = 0; i < Folders.Size(); i++) { - FolderStartPackStreamIndex.Add((UINT32)startPos); - startPos += Folders[(UINT32)i].PackStreams.Size(); + FolderStartPackStreamIndex.Add(startPos); + startPos += (CNum)Folders[i].PackStreams.Size(); } } @@ -1041,11 +1122,11 @@ void CArchiveDatabaseEx::FillStartPos() { PackStreamStartPositions.Clear(); PackStreamStartPositions.Reserve(PackSizes.Size()); - UINT64 startPos = 0; - for(UINT64 i = 0; i < PackSizes.Size(); i++) + UInt64 startPos = 0; + for(int i = 0; i < PackSizes.Size(); i++) { PackStreamStartPositions.Add(startPos); - startPos += PackSizes[(UINT32)i]; + startPos += PackSizes[i]; } } @@ -1057,21 +1138,29 @@ void CArchiveDatabaseEx::FillFolderStartFileIndex() FileIndexToFolderIndexMap.Reserve(Files.Size()); int folderIndex = 0; - int indexInFolder = 0; + CNum indexInFolder = 0; for (int i = 0; i < Files.Size(); i++) { const CFileItem &file = Files[i]; bool emptyStream = !file.HasStream; if (emptyStream && indexInFolder == 0) { - FileIndexToFolderIndexMap.Add(-1); + FileIndexToFolderIndexMap.Add(kNumNoIndex); continue; } if (indexInFolder == 0) { - if (folderIndex >= Folders.Size()) - throw CInArchiveException(CInArchiveException::kIncorrectHeader); - FolderStartFileIndex.Add(i); + // v3.13 incorrectly worked with empty folders + // v4.07: Loop for skipping empty folders + while(true) + { + if (folderIndex >= Folders.Size()) + throw CInArchiveException(CInArchiveException::kIncorrectHeader); + FolderStartFileIndex.Add(i); // check it + if (NumUnPackStreamsVector[folderIndex] != 0) + break; + folderIndex++; + } } FileIndexToFolderIndexMap.Add(folderIndex); if (emptyStream) @@ -1093,29 +1182,66 @@ HRESULT CInArchive::ReadDatabase(CArchiveDatabaseEx &database { database.Clear(); database.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition; - RINOK(SafeReadBytes(&database.ArchiveInfo.Version, - sizeof(database.ArchiveInfo.Version))); + + + RINOK(SafeReadDirect(&database.ArchiveInfo.Version.Major, 1)); + RINOK(SafeReadDirect(&database.ArchiveInfo.Version.Minor, 1)); if (database.ArchiveInfo.Version.Major != kMajorVersion) throw CInArchiveException(CInArchiveException::kUnsupportedVersion); - UINT32 crcFromArchive; - RINOK(SafeReadBytes(&crcFromArchive, sizeof(crcFromArchive))); - CStartHeader startHeader; - RINOK(SafeReadBytes(&startHeader, sizeof(startHeader))); - if (!CCRC::VerifyDigest(crcFromArchive, &startHeader, sizeof(startHeader))) + #ifdef _7Z_VOL + if (_finishSignature) + { + RINOK(_stream->Seek(_position - (4 + kFinishHeaderSize) - + (kSignatureSize + 2), STREAM_SEEK_SET, &_position)); + } + #endif + + UInt32 crcFromArchive; + RINOK(SafeReadDirectUInt32(crcFromArchive)); + + UInt64 nextHeaderOffset; + UInt64 nextHeaderSize; + UInt32 nextHeaderCRC; + CCRC crc; + RINOK(SafeReadDirectUInt64(nextHeaderOffset)); + crc.UpdateUInt64(nextHeaderOffset); + RINOK(SafeReadDirectUInt64(nextHeaderSize)); + crc.UpdateUInt64(nextHeaderSize); + RINOK(SafeReadDirectUInt32(nextHeaderCRC)); + crc.UpdateUInt32(nextHeaderCRC); + + #ifdef _7Z_VOL + UInt64 archiveStartOffset; // data offset from end if that struct + UInt64 additionalStartBlockSize; // start signature & start header size + if (_finishSignature) + { + RINOK(SafeReadDirectUInt64(archiveStartOffset)); + crc.UpdateUInt64(archiveStartOffset); + RINOK(SafeReadDirectUInt64(additionalStartBlockSize)); + crc.UpdateUInt64(additionalStartBlockSize); + database.ArchiveInfo.StartPositionAfterHeader = _position + archiveStartOffset; + } + else + #endif + { + database.ArchiveInfo.StartPositionAfterHeader = _position; + } + if (crc.GetDigest() != crcFromArchive) throw CInArchiveException(CInArchiveException::kIncorrectHeader); - database.ArchiveInfo.StartPositionAfterHeader = _position; - - if (startHeader.NextHeaderSize == 0) + if (nextHeaderSize == 0) return S_OK; - RINOK(_stream->Seek(startHeader.NextHeaderOffset, STREAM_SEEK_CUR, &_position)); + if (nextHeaderSize >= 0xFFFFFFFF) + return E_FAIL; + + RINOK(_stream->Seek(nextHeaderOffset, STREAM_SEEK_CUR, &_position)); CByteBuffer buffer2; - buffer2.SetCapacity((size_t)startHeader.NextHeaderSize); - RINOK(SafeReadBytes(buffer2, (UINT32)startHeader.NextHeaderSize)); - if (!CCRC::VerifyDigest(startHeader.NextHeaderCRC, buffer2, (UINT32)startHeader.NextHeaderSize)) + buffer2.SetCapacity((size_t)nextHeaderSize); + RINOK(SafeReadDirect(buffer2, (UInt32)nextHeaderSize)); + if (!CCRC::VerifyDigest(nextHeaderCRC, buffer2, (UInt32)nextHeaderSize)) throw CInArchiveException(CInArchiveException::kIncorrectHeader); CStreamSwitch streamSwitch; @@ -1125,7 +1251,7 @@ HRESULT CInArchive::ReadDatabase(CArchiveDatabaseEx &database while (true) { - UINT64 type; + UInt64 type; RINOK(ReadID(type)); if (type == NID::kHeader) break; diff --git a/7zip/Archive/7z/7zIn.h b/7zip/Archive/7z/7zIn.h index 0a835ac0..c3bec123 100755 --- a/7zip/Archive/7z/7zIn.h +++ b/7zip/Archive/7z/7zIn.h @@ -1,7 +1,5 @@ // 7zIn.h -#pragma once - #ifndef __7Z_IN_H #define __7Z_IN_H @@ -31,11 +29,11 @@ public: struct CInArchiveInfo { CArchiveVersion Version; - UINT64 StartPosition; - UINT64 StartPositionAfterHeader; - UINT64 DataStartPosition; - UINT64 DataStartPosition2; - CRecordVector<UINT64> FileInfoPopIDs; + UInt64 StartPosition; + UInt64 StartPositionAfterHeader; + UInt64 DataStartPosition; + UInt64 DataStartPosition2; + CRecordVector<UInt64> FileInfoPopIDs; void Clear() { FileInfoPopIDs.Clear(); @@ -46,10 +44,10 @@ struct CInArchiveInfo struct CArchiveDatabaseEx: public CArchiveDatabase { CInArchiveInfo ArchiveInfo; - CRecordVector<UINT64> PackStreamStartPositions; - CRecordVector<UINT32> FolderStartPackStreamIndex; - CRecordVector<UINT64> FolderStartFileIndex; - CRecordVector<int> FileIndexToFolderIndexMap; + CRecordVector<UInt64> PackStreamStartPositions; + CRecordVector<CNum> FolderStartPackStreamIndex; + CRecordVector<CNum> FolderStartFileIndex; + CRecordVector<CNum> FileIndexToFolderIndexMap; void Clear() { @@ -58,69 +56,88 @@ struct CArchiveDatabaseEx: public CArchiveDatabase PackStreamStartPositions.Clear(); FolderStartPackStreamIndex.Clear(); FolderStartFileIndex.Clear(); - FolderStartFileIndex.Clear(); + FileIndexToFolderIndexMap.Clear(); } void FillFolderStartPackStream(); void FillStartPos(); void FillFolderStartFileIndex(); + + void Fill() + { + FillFolderStartPackStream(); + FillStartPos(); + FillFolderStartFileIndex(); + } - UINT64 GetFolderStreamPos(int folderIndex, int indexInFolder) const + UInt64 GetFolderStreamPos(int folderIndex, int indexInFolder) const { return ArchiveInfo.DataStartPosition + PackStreamStartPositions[FolderStartPackStreamIndex[folderIndex] + indexInFolder]; } - UINT64 GetFolderFullPackSize(int folderIndex) const + UInt64 GetFolderFullPackSize(int folderIndex) const { - UINT32 packStreamIndex = FolderStartPackStreamIndex[folderIndex]; + CNum packStreamIndex = FolderStartPackStreamIndex[folderIndex]; const CFolder &folder = Folders[folderIndex]; - UINT64 size = 0; + UInt64 size = 0; for (int i = 0; i < folder.PackStreams.Size(); i++) size += PackSizes[packStreamIndex + i]; return size; } - UINT64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const + UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const { return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex]; } + + UInt64 GetFilePackSize(CNum fileIndex) const + { + CNum folderIndex = FileIndexToFolderIndexMap[fileIndex]; + if (folderIndex >= 0) + { + const CFolder &folderInfo = Folders[folderIndex]; + if (FolderStartFileIndex[folderIndex] == fileIndex) + return GetFolderFullPackSize(folderIndex); + } + return 0; + } }; class CInByte2 { - const BYTE *_buffer; - UINT32 _size; - UINT32 _pos; + const Byte *_buffer; + size_t _size; + size_t _pos; public: - void Init(const BYTE *buffer, UINT32 size) + void Init(const Byte *buffer, size_t size) { _buffer = buffer; _size = size; _pos = 0; } - bool ReadByte(BYTE &b) + bool ReadByte(Byte &b) { if(_pos >= _size) return false; b = _buffer[_pos++]; return true; } - void ReadBytes(void *data, UINT32 size, UINT32 &processedSize) + void ReadBytes(void *data, size_t size, size_t &processedSize) { for(processedSize = 0; processedSize < size && _pos < _size; processedSize++) - ((BYTE *)data)[processedSize] = _buffer[_pos++]; + ((Byte *)data)[processedSize] = _buffer[_pos++]; } - bool ReadBytes(void *data, UINT32 size) + bool ReadBytes(void *data, size_t size) { - UINT32 processedSize; + size_t processedSize; ReadBytes(data, size, processedSize); return (processedSize == size); } - UINT32 GetProcessedSize() const { return _pos; } + size_t GetProcessedSize() const { return _pos; } }; class CStreamSwitch; @@ -129,14 +146,17 @@ class CInArchive friend class CStreamSwitch; CMyComPtr<IInStream> _stream; + #ifdef _7Z_VOL + bool _finishSignature; + #endif CObjectVector<CInByte2> _inByteVector; CInByte2 *_inByteBack; - UINT64 _arhiveBeginStreamPosition; - UINT64 _position; + UInt64 _arhiveBeginStreamPosition; + UInt64 _position; - void AddByteStream(const BYTE *buffer, UINT32 size) + void AddByteStream(const Byte *buffer, size_t size) { _inByteVector.Add(CInByte2()); _inByteBack = &_inByteVector.Back(); @@ -151,62 +171,67 @@ class CInArchive } private: - HRESULT FindAndReadSignature(IInStream *stream, const UINT64 *searchHeaderSizeLimit); // S_FALSE means is not archive + HRESULT FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive + #ifdef _7Z_VOL + HRESULT FindFinishSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive + #endif HRESULT ReadFileNames(CObjectVector<CFileItem> &files); - HRESULT ReadBytes(IInStream *stream, void *data, UINT32 size, - UINT32 *processedSize); - HRESULT ReadBytes(void *data, UINT32 size, UINT32 *processedSize); - HRESULT SafeReadBytes(void *data, UINT32 size); + HRESULT ReadDirect(IInStream *stream, void *data, UInt32 size, + UInt32 *processedSize); + HRESULT ReadDirect(void *data, UInt32 size, UInt32 *processedSize); + HRESULT SafeReadDirect(void *data, UInt32 size); + HRESULT SafeReadDirectByte(Byte &b); + HRESULT SafeReadDirectUInt32(UInt32 &value); + HRESULT SafeReadDirectUInt64(UInt64 &value); - HRESULT SafeReadBytes2(void *data, UINT32 size) + HRESULT ReadBytes(void *data, size_t size) { if (!_inByteBack->ReadBytes(data, size)) return E_FAIL; return S_OK; } - HRESULT SafeReadByte2(BYTE &b) + HRESULT ReadByte(Byte &b) { if (!_inByteBack->ReadByte(b)) return E_FAIL; return S_OK; } - HRESULT SafeReadWideCharLE(wchar_t &c) + HRESULT ReadWideCharLE(wchar_t &c) { - BYTE b1; + Byte b1; if (!_inByteBack->ReadByte(b1)) return E_FAIL; - BYTE b2; + Byte b2; if (!_inByteBack->ReadByte(b2)) return E_FAIL; - c = (int(b2) << 8) + b1; + c = (wchar_t(b2) << 8) + b1; return S_OK; } - HRESULT ReadNumber(UINT64 &value); - - HRESULT ReadID(UINT64 &value) - { - return ReadNumber(value); - } + HRESULT ReadNumber(UInt64 &value); + HRESULT ReadNum(CNum &value); + HRESULT ReadID(UInt64 &value) { return ReadNumber(value); } + HRESULT ReadUInt32(UInt32 &value); + HRESULT ReadUInt64(UInt64 &value); - HRESULT SkeepData(UINT64 size); + HRESULT SkeepData(UInt64 size); HRESULT SkeepData(); - HRESULT WaitAttribute(UINT64 attribute); + HRESULT WaitAttribute(UInt64 attribute); HRESULT ReadArchiveProperties(CInArchiveInfo &archiveInfo); HRESULT GetNextFolderItem(CFolder &itemInfo); HRESULT ReadHashDigests(int numItems, - CRecordVector<bool> &digestsDefined, CRecordVector<UINT32> &digests); + CRecordVector<bool> &digestsDefined, CRecordVector<UInt32> &digests); HRESULT ReadPackInfo( - UINT64 &dataOffset, - CRecordVector<UINT64> &packSizes, + UInt64 &dataOffset, + CRecordVector<UInt64> &packSizes, CRecordVector<bool> &packCRCsDefined, - CRecordVector<UINT32> &packCRCs); + CRecordVector<UInt32> &packCRCs); HRESULT ReadUnPackInfo( const CObjectVector<CByteBuffer> *dataVector, @@ -214,31 +239,30 @@ private: HRESULT ReadSubStreamsInfo( const CObjectVector<CFolder> &folders, - CRecordVector<UINT64> &numUnPackStreamsInFolders, - CRecordVector<UINT64> &unPackSizes, + CRecordVector<CNum> &numUnPackStreamsInFolders, + CRecordVector<UInt64> &unPackSizes, CRecordVector<bool> &digestsDefined, - CRecordVector<UINT32> &digests); + CRecordVector<UInt32> &digests); HRESULT CInArchive::ReadStreamsInfo( const CObjectVector<CByteBuffer> *dataVector, - UINT64 &dataOffset, - CRecordVector<UINT64> &packSizes, + UInt64 &dataOffset, + CRecordVector<UInt64> &packSizes, CRecordVector<bool> &packCRCsDefined, - CRecordVector<UINT32> &packCRCs, + CRecordVector<UInt32> &packCRCs, CObjectVector<CFolder> &folders, - CRecordVector<UINT64> &numUnPackStreamsInFolders, - CRecordVector<UINT64> &unPackSizes, + CRecordVector<CNum> &numUnPackStreamsInFolders, + CRecordVector<UInt64> &unPackSizes, CRecordVector<bool> &digestsDefined, - CRecordVector<UINT32> &digests); - + CRecordVector<UInt32> &digests); HRESULT GetNextFileItem(CFileItem &itemInfo); - HRESULT ReadBoolVector(UINT32 numItems, CBoolVector &vector); - HRESULT ReadBoolVector2(UINT32 numItems, CBoolVector &vector); + HRESULT ReadBoolVector(int numItems, CBoolVector &v); + HRESULT ReadBoolVector2(int numItems, CBoolVector &v); HRESULT ReadTime(const CObjectVector<CByteBuffer> &dataVector, - CObjectVector<CFileItem> &files, UINT64 type); - HRESULT ReadAndDecodePackedStreams(UINT64 baseOffset, UINT64 &dataOffset, + CObjectVector<CFileItem> &files, UInt64 type); + HRESULT ReadAndDecodePackedStreams(UInt64 baseOffset, UInt64 &dataOffset, CObjectVector<CByteBuffer> &dataVector #ifndef _NO_CRYPTO , ICryptoGetTextPassword *getTextPassword @@ -250,7 +274,7 @@ private: #endif ); public: - HRESULT Open(IInStream *stream, const UINT64 *searchHeaderSizeLimit); // S_FALSE means is not archive + HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive void Close(); HRESULT ReadDatabase(CArchiveDatabaseEx &database @@ -258,7 +282,6 @@ public: ,ICryptoGetTextPassword *getTextPassword #endif ); - HRESULT CheckIntegrity(); }; }} diff --git a/7zip/Archive/7z/7zItem.h b/7zip/Archive/7z/7zItem.h index da1eaefc..08ea61f4 100755 --- a/7zip/Archive/7z/7zItem.h +++ b/7zip/Archive/7z/7zItem.h @@ -1,7 +1,5 @@ // 7zItem.h -#pragma once - #ifndef __7Z_ITEM_H #define __7Z_ITEM_H @@ -18,38 +16,36 @@ struct CAltCoderInfo CByteBuffer Properties; }; +typedef UInt32 CNum; +const CNum kNumMax = 0x7FFFFFFF; +const CNum kNumNoIndex = 0xFFFFFFFF; + struct CCoderInfo { - UINT64 NumInStreams; - UINT64 NumOutStreams; + CNum NumInStreams; + CNum NumOutStreams; CObjectVector<CAltCoderInfo> AltCoders; - bool IsSimpleCoder() const - { return (NumInStreams == 1) && (NumOutStreams == 1); } -}; - -struct CPackStreamInfo -{ - UINT64 Index; + bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); } }; struct CBindPair { - UINT64 InIndex; - UINT64 OutIndex; + CNum InIndex; + CNum OutIndex; }; struct CFolder { CObjectVector<CCoderInfo> Coders; CRecordVector<CBindPair> BindPairs; - CRecordVector<CPackStreamInfo> PackStreams; - CRecordVector<UINT64> UnPackSizes; + CRecordVector<CNum> PackStreams; + CRecordVector<UInt64> UnPackSizes; + UInt32 UnPackCRC; bool UnPackCRCDefined; - UINT32 UnPackCRC; CFolder(): UnPackCRCDefined(false) {} - UINT64 GetUnPackSize() const // test it + UInt64 GetUnPackSize() const // test it { if (UnPackSizes.IsEmpty()) return 0; @@ -58,33 +54,33 @@ struct CFolder return UnPackSizes[i]; throw 1; } - UINT64 GetNumOutStreams() const + + CNum GetNumOutStreams() const { - UINT64 result = 0; + CNum result = 0; for (int i = 0; i < Coders.Size(); i++) result += Coders[i].NumOutStreams; return result; } - - int FindBindPairForInStream(int inStreamIndex) const + int FindBindPairForInStream(CNum inStreamIndex) const { for(int i = 0; i < BindPairs.Size(); i++) if (BindPairs[i].InIndex == inStreamIndex) return i; return -1; } - int FindBindPairForOutStream(int outStreamIndex) const + int FindBindPairForOutStream(CNum outStreamIndex) const { for(int i = 0; i < BindPairs.Size(); i++) if (BindPairs[i].OutIndex == outStreamIndex) return i; return -1; } - int FindPackStreamArrayIndex(int inStreamIndex) const + int FindPackStreamArrayIndex(CNum inStreamIndex) const { for(int i = 0; i < PackStreams.Size(); i++) - if (PackStreams[i].Index == inStreamIndex) + if (PackStreams[i] == inStreamIndex) return i; return -1; } @@ -98,51 +94,54 @@ public: CArchiveFileTime CreationTime; CArchiveFileTime LastWriteTime; CArchiveFileTime LastAccessTime; - UINT64 UnPackSize; - UINT32 Attributes; - UINT32 FileCRC; + UInt64 UnPackSize; + UInt64 StartPos; + UInt32 Attributes; + UInt32 FileCRC; UString Name; bool HasStream; // Test it !!! it means that there is // stream in some folder. It can be empty stream bool IsDirectory; bool IsAnti; - bool FileCRCIsDefined; + bool IsFileCRCDefined; bool AreAttributesDefined; bool IsCreationTimeDefined; bool IsLastWriteTimeDefined; bool IsLastAccessTimeDefined; + bool IsStartPosDefined; /* const bool HasStream() const { return !IsDirectory && !IsAnti && UnPackSize != 0; } */ CFileItem(): + HasStream(true), + IsDirectory(false), + IsAnti(false), + IsFileCRCDefined(false), AreAttributesDefined(false), IsCreationTimeDefined(false), IsLastWriteTimeDefined(false), IsLastAccessTimeDefined(false), - IsDirectory(false), - FileCRCIsDefined(false), - IsAnti(false), - HasStream(true) + IsStartPosDefined(false) {} - void SetAttributes(UINT32 attributes) + void SetAttributes(UInt32 attributes) { AreAttributesDefined = true; Attributes = attributes; } - void SetCreationTime(CArchiveFileTime creationTime) + void SetCreationTime(const CArchiveFileTime &creationTime) { IsCreationTimeDefined = true; CreationTime = creationTime; } - void SetLastWriteTime(CArchiveFileTime lastWriteTime) + void SetLastWriteTime(const CArchiveFileTime &lastWriteTime) { IsLastWriteTimeDefined = true; LastWriteTime = lastWriteTime; } - void SetLastAccessTime(CArchiveFileTime lastAccessTime) + void SetLastAccessTime(const CArchiveFileTime &lastAccessTime) { IsLastAccessTimeDefined = true; LastAccessTime = lastAccessTime; @@ -151,11 +150,11 @@ public: struct CArchiveDatabase { - CRecordVector<UINT64> PackSizes; + CRecordVector<UInt64> PackSizes; CRecordVector<bool> PackCRCsDefined; - CRecordVector<UINT32> PackCRCs; + CRecordVector<UInt32> PackCRCs; CObjectVector<CFolder> Folders; - CRecordVector<UINT64> NumUnPackStreamsVector; + CRecordVector<CNum> NumUnPackStreamsVector; CObjectVector<CFileItem> Files; void Clear() { @@ -177,19 +176,6 @@ struct CArchiveDatabase } }; -struct CArchiveHeaderDatabase -{ - CRecordVector<UINT64> PackSizes; - CObjectVector<CFolder> Folders; - CRecordVector<UINT32> CRCs; - void Clear() - { - PackSizes.Clear(); - Folders.Clear(); - CRCs.Clear(); - } -}; - }} #endif diff --git a/7zip/Archive/7z/7zMethodID.cpp b/7zip/Archive/7z/7zMethodID.cpp index f1ffc75f..d5b78f05 100755 --- a/7zip/Archive/7z/7zMethodID.cpp +++ b/7zip/Archive/7z/7zMethodID.cpp @@ -7,12 +7,12 @@ namespace NArchive { namespace N7z { -static inline wchar_t GetHex(BYTE value) +static wchar_t GetHex(Byte value) { return (value < 10) ? ('0' + value) : ('A' + (value - 10)); } -static bool HexCharToInt(wchar_t value, BYTE &result) +static bool HexCharToInt(wchar_t value, Byte &result) { if (value >= '0' && value <= '9') result = value - '0'; @@ -25,9 +25,9 @@ static bool HexCharToInt(wchar_t value, BYTE &result) return true; } -static bool TwoHexCharsToInt(wchar_t valueHigh, wchar_t valueLow, BYTE &result) +static bool TwoHexCharsToInt(wchar_t valueHigh, wchar_t valueLow, Byte &result) { - BYTE resultHigh, resultLow; + Byte resultHigh, resultLow; if (!HexCharToInt(valueHigh, resultHigh)) return false; if (!HexCharToInt(valueLow, resultLow)) @@ -41,7 +41,7 @@ UString CMethodID::ConvertToString() const UString result; for (int i = 0; i < IDSize; i++) { - BYTE b = ID[i]; + Byte b = ID[i]; result += GetHex(b >> 4); result += GetHex(b & 0xF); } @@ -51,18 +51,26 @@ UString CMethodID::ConvertToString() const bool CMethodID::ConvertFromString(const UString &srcString) { int length = srcString.Length(); - if ((length & 1) != 0) + if ((length & 1) != 0 || (length >> 1) > kMethodIDSize) return false; IDSize = length / 2; - if (IDSize > kMethodIDSize) - return false; - UINT32 i; + UInt32 i; for(i = 0; i < IDSize; i++) if (!TwoHexCharsToInt(srcString[i * 2], srcString[i * 2 + 1], ID[i])) return false; - for(i = IDSize; i < kMethodIDSize; i++) + for(; i < kMethodIDSize; i++) ID[i] = 0; return true; } +bool operator==(const CMethodID &a1, const CMethodID &a2) +{ + if (a1.IDSize != a2.IDSize) + return false; + for (UInt32 i = 0; i < a1.IDSize; i++) + if (a1.ID[i] != a2.ID[i]) + return false; + return true; +} + }} diff --git a/7zip/Archive/7z/7zMethodID.h b/7zip/Archive/7z/7zMethodID.h index 9f30e665..54561054 100755 --- a/7zip/Archive/7z/7zMethodID.h +++ b/7zip/Archive/7z/7zMethodID.h @@ -1,34 +1,25 @@ // 7zMethodID.h -#pragma once - #ifndef __7Z_METHOD_ID_H #define __7Z_METHOD_ID_H #include "../../../Common/String.h" +#include "../../../Common/Types.h" namespace NArchive { namespace N7z { -const int kMethodIDSize = 16; +const int kMethodIDSize = 15; struct CMethodID { - BYTE ID[kMethodIDSize]; - UINT32 IDSize; + Byte ID[kMethodIDSize]; + Byte IDSize; UString ConvertToString() const; bool ConvertFromString(const UString &srcString); }; -inline bool operator==(const CMethodID &a1, const CMethodID &a2) -{ - if (a1.IDSize != a2.IDSize) - return false; - for (UINT32 i = 0; i < a1.IDSize; i++) - if (a1.ID[i] != a2.ID[i]) - return false; - return true; -} +bool operator==(const CMethodID &a1, const CMethodID &a2); inline bool operator!=(const CMethodID &a1, const CMethodID &a2) { return !(a1 == a2); } diff --git a/7zip/Archive/7z/7zMethods.cpp b/7zip/Archive/7z/7zMethods.cpp index 29531234..f899d0e9 100755 --- a/7zip/Archive/7z/7zMethods.cpp +++ b/7zip/Archive/7z/7zMethods.cpp @@ -20,10 +20,10 @@ namespace N7z { static CObjectVector<CMethodInfo2> g_Methods; static bool g_Loaded = false; -typedef UINT32 (WINAPI *GetNumberOfMethodsFunc)(UINT32 *numMethods); +typedef UInt32 (WINAPI *GetNumberOfMethodsFunc)(UInt32 *numMethods); -typedef UINT32 (WINAPI *GetMethodPropertyFunc)( - UINT32 index, PROPID propID, PROPVARIANT *value); +typedef UInt32 (WINAPI *GetMethodPropertyFunc)( + UInt32 index, PROPID propID, PROPVARIANT *value); static void Load(const CSysString &folderPrefix) { @@ -47,14 +47,14 @@ static void Load(const CSysString &folderPrefix) if (getMethodProperty == NULL) continue; - UINT32 numMethods = 1; + UInt32 numMethods = 1; GetNumberOfMethodsFunc getNumberOfMethodsFunc = (GetNumberOfMethodsFunc) library.GetProcAddress("GetNumberOfMethods"); if (getNumberOfMethodsFunc != NULL) if (getNumberOfMethodsFunc(&numMethods) != S_OK) continue; - for(UINT32 i = 0; i < numMethods; i++) + for(UInt32 i = 0; i < numMethods; i++) { CMethodInfo2 info; info.FilePath = filePath; diff --git a/7zip/Archive/7z/7zMethods.h b/7zip/Archive/7z/7zMethods.h index 64b67df8..231f3183 100755 --- a/7zip/Archive/7z/7zMethods.h +++ b/7zip/Archive/7z/7zMethods.h @@ -13,8 +13,8 @@ struct CMethodInfo UString Name; bool EncoderIsAssigned; bool DecoderIsAssigned; - UINT32 NumInStreams; - UINT32 NumOutStreams; + UInt32 NumInStreams; + UInt32 NumOutStreams; CLSID Encoder; CLSID Decoder; // UString Description; diff --git a/7zip/Archive/7z/7zOut.cpp b/7zip/Archive/7z/7zOut.cpp index 45cd94fa..b2ba2db3 100755 --- a/7zip/Archive/7z/7zOut.cpp +++ b/7zip/Archive/7z/7zOut.cpp @@ -2,51 +2,155 @@ #include "StdAfx.h" -#include "7zOut.h" +#include "../../../Common/AutoPtr.h" #include "../../Common/StreamObjects.h" -static HRESULT WriteBytes(IOutStream *stream, const void *data, UINT32 size) +#include "7zOut.h" + +static HRESULT WriteBytes(ISequentialOutStream *stream, const void *data, size_t size) { - UINT32 processedSize; - RINOK(stream->Write(data, size, &processedSize)); - if(processedSize != size) - return E_FAIL; + while (size > 0) + { + UInt32 curSize = (UInt32)(MyMin(size, (size_t)0xFFFFFFFF)); + UInt32 processedSize; + RINOK(stream->WritePart(data, curSize, &processedSize)); + if(processedSize == 0 || processedSize > curSize) + return E_FAIL; + data = (const void *)((const Byte *)data + processedSize); + size -= processedSize; + } return S_OK; } namespace NArchive { namespace N7z { -HRESULT COutArchive::Create(IOutStream *stream) +HRESULT COutArchive::WriteDirect(const void *data, UInt32 size) { - Close(); - RINOK(::WriteBytes(stream, kSignature, kSignatureSize)); - CArchiveVersion archiveVersion; - archiveVersion.Major = kMajorVersion; - archiveVersion.Minor = 2; - RINOK(::WriteBytes(stream, &archiveVersion, sizeof(archiveVersion))); - RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_prefixHeaderPos)); - Stream = stream; + return ::WriteBytes(SeqStream, data, size); +} + +HRESULT COutArchive::WriteDirectUInt32(UInt32 value) +{ + for (int i = 0; i < 4; i++) + { + RINOK(WriteDirectByte((Byte)value)); + value >>= 8; + } return S_OK; } -void COutArchive::Close() +HRESULT COutArchive::WriteDirectUInt64(UInt64 value) { - Stream.Release(); + for (int i = 0; i < 8; i++) + { + RINOK(WriteDirectByte((Byte)value)); + value >>= 8; + } + return S_OK; } -HRESULT COutArchive::SkeepPrefixArchiveHeader() +HRESULT COutArchive::WriteSignature() { - return Stream->Seek(sizeof(CStartHeader) + sizeof(UINT32), STREAM_SEEK_CUR, NULL); + RINOK(WriteDirect(kSignature, kSignatureSize)); + RINOK(WriteDirectByte(kMajorVersion)); + return WriteDirectByte(2); +} + +#ifdef _7Z_VOL +HRESULT COutArchive::WriteFinishSignature() +{ + RINOK(WriteDirect(kFinishSignature, kSignatureSize)); + CArchiveVersion av; + av.Major = kMajorVersion; + av.Minor = 2; + RINOK(WriteDirectByte(av.Major)); + return WriteDirectByte(av.Minor); +} +#endif + +HRESULT COutArchive::WriteStartHeader(const CStartHeader &h) +{ + CCRC crc; + crc.UpdateUInt64(h.NextHeaderOffset); + crc.UpdateUInt64(h.NextHeaderSize); + crc.UpdateUInt32(h.NextHeaderCRC); + RINOK(WriteDirectUInt32(crc.GetDigest())); + RINOK(WriteDirectUInt64(h.NextHeaderOffset)); + RINOK(WriteDirectUInt64(h.NextHeaderSize)); + return WriteDirectUInt32(h.NextHeaderCRC); +} + +#ifdef _7Z_VOL +HRESULT COutArchive::WriteFinishHeader(const CFinishHeader &h) +{ + CCRC crc; + crc.UpdateUInt64(h.NextHeaderOffset); + crc.UpdateUInt64(h.NextHeaderSize); + crc.UpdateUInt32(h.NextHeaderCRC); + crc.UpdateUInt64(h.ArchiveStartOffset); + crc.UpdateUInt64(h.AdditionalStartBlockSize); + RINOK(WriteDirectUInt32(crc.GetDigest())); + RINOK(WriteDirectUInt64(h.NextHeaderOffset)); + RINOK(WriteDirectUInt64(h.NextHeaderSize)); + RINOK(WriteDirectUInt32(h.NextHeaderCRC)); + RINOK(WriteDirectUInt64(h.ArchiveStartOffset)); + return WriteDirectUInt64(h.AdditionalStartBlockSize); +} +#endif + +HRESULT COutArchive::Create(ISequentialOutStream *stream, bool endMarker) +{ + Close(); + #ifdef _7Z_VOL + // endMarker = false; + _endMarker = endMarker; + #endif + SeqStream = stream; + if (!endMarker) + { + SeqStream.QueryInterface(IID_IOutStream, &Stream); + if (!Stream) + endMarker = true; + } + #ifdef _7Z_VOL + if (endMarker) + { + /* + CStartHeader sh; + sh.NextHeaderOffset = (UInt32)(Int32)-1; + sh.NextHeaderSize = (UInt32)(Int32)-1; + sh.NextHeaderCRC = 0; + WriteStartHeader(sh); + */ + } + else + #endif + { + if (!Stream) + return E_FAIL; + WriteSignature(); + RINOK(Stream->Seek(0, STREAM_SEEK_CUR, &_prefixHeaderPos)); + } + return S_OK; } -HRESULT COutArchive::WriteBytes(const void *data, UINT32 size) +void COutArchive::Close() { - return ::WriteBytes(Stream, data, size); + SeqStream.Release(); + Stream.Release(); } +HRESULT COutArchive::SkeepPrefixArchiveHeader() +{ + #ifdef _7Z_VOL + if (_endMarker) + return S_OK; + #endif + return Stream->Seek(24, STREAM_SEEK_CUR, NULL); +} -HRESULT COutArchive::WriteBytes2(const void *data, UINT32 size) +HRESULT COutArchive::WriteBytes(const void *data, size_t size) { if (_mainMode) { @@ -66,97 +170,143 @@ HRESULT COutArchive::WriteBytes2(const void *data, UINT32 size) return S_OK; } -HRESULT COutArchive::WriteBytes2(const CByteBuffer &data) +HRESULT COutArchive::WriteBytes(const CByteBuffer &data) { - return WriteBytes2(data, data.GetCapacity()); + return WriteBytes(data, data.GetCapacity()); } -HRESULT COutArchive::WriteByte2(BYTE b) +HRESULT COutArchive::WriteByte(Byte b) { - return WriteBytes2(&b, 1); + return WriteBytes(&b, 1); } -HRESULT COutArchive::WriteNumber(UINT64 value) +HRESULT COutArchive::WriteUInt32(UInt32 value) { - BYTE firstByte = 0; - BYTE mask = 0x80; + for (int i = 0; i < 4; i++) + { + RINOK(WriteByte((Byte)value)); + value >>= 8; + } + return S_OK; +} + +HRESULT COutArchive::WriteNumber(UInt64 value) +{ + Byte firstByte = 0; + Byte mask = 0x80; int i; for (i = 0; i < 8; i++) { - if (value < ((UINT64(1) << ( 7 * (i + 1))))) + if (value < ((UInt64(1) << ( 7 * (i + 1))))) { - firstByte |= BYTE(value >> (8 * i)); + firstByte |= Byte(value >> (8 * i)); break; } firstByte |= mask; mask >>= 1; } - RINOK(WriteByte2(firstByte)); - return WriteBytes2(&value, i); + RINOK(WriteByte(firstByte)); + for (;i > 0; i--) + { + RINOK(WriteByte((Byte)value)); + value >>= 8; + } + return S_OK; } -static UINT32 GetBigNumberSize(UINT64 value) +static UInt32 GetBigNumberSize(UInt64 value) { int i; for (i = 0; i < 8; i++) - if (value < ((UINT64(1) << ( 7 * (i + 1))))) + if (value < ((UInt64(1) << ( 7 * (i + 1))))) break; return 1 + i; } -HRESULT COutArchive::WriteFolderHeader(const CFolder &itemInfo) +#ifdef _7Z_VOL +UInt32 COutArchive::GetVolHeadersSize(UInt64 dataSize, int nameLength, bool props) +{ + UInt32 result = GetBigNumberSize(dataSize) * 2 + 41; + if (nameLength != 0) + { + nameLength = (nameLength + 1) * 2; + result += nameLength + GetBigNumberSize(nameLength) + 2; + } + if (props) + { + result += 20; + } + if (result >= 128) + result++; + result += kSignatureSize + 2 + kFinishHeaderSize; + return result; +} + +UInt64 COutArchive::GetVolPureSize(UInt64 volSize, int nameLength, bool props) +{ + UInt32 headersSizeBase = COutArchive::GetVolHeadersSize(1, nameLength, props); + int testSize; + if (volSize > headersSizeBase) + testSize = volSize - headersSizeBase; + else + testSize = 1; + UInt32 headersSize = COutArchive::GetVolHeadersSize(testSize, nameLength, props); + UInt64 pureSize = 1; + if (volSize > headersSize) + pureSize = volSize - headersSize; + return pureSize; +} +#endif + +HRESULT COutArchive::WriteFolder(const CFolder &folder) { - RINOK(WriteNumber(itemInfo.Coders.Size())); + RINOK(WriteNumber(folder.Coders.Size())); int i; - for (i = 0; i < itemInfo.Coders.Size(); i++) + for (i = 0; i < folder.Coders.Size(); i++) { - const CCoderInfo &coderInfo = itemInfo.Coders[i]; - for (int j = 0; j < coderInfo.AltCoders.Size(); j++) + const CCoderInfo &coder = folder.Coders[i]; + for (int j = 0; j < coder.AltCoders.Size(); j++) { - const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders[j]; - UINT64 propertiesSize = altCoderInfo.Properties.GetCapacity(); + const CAltCoderInfo &altCoder = coder.AltCoders[j]; + size_t propertiesSize = altCoder.Properties.GetCapacity(); - BYTE b; - b = altCoderInfo.MethodID.IDSize & 0xF; - bool isComplex = (coderInfo.NumInStreams != 1) || - (coderInfo.NumOutStreams != 1); + Byte b; + b = altCoder.MethodID.IDSize & 0xF; + bool isComplex = !coder.IsSimpleCoder(); b |= (isComplex ? 0x10 : 0); b |= ((propertiesSize != 0) ? 0x20 : 0 ); - b |= ((j == coderInfo.AltCoders.Size() - 1) ? 0 : 0x80 ); - RINOK(WriteByte2(b)); - RINOK(WriteBytes2(&altCoderInfo.MethodID.ID[0], - altCoderInfo.MethodID.IDSize)); + b |= ((j == coder.AltCoders.Size() - 1) ? 0 : 0x80 ); + RINOK(WriteByte(b)); + RINOK(WriteBytes(altCoder.MethodID.ID, altCoder.MethodID.IDSize)); if (isComplex) { - RINOK(WriteNumber(coderInfo.NumInStreams)); - RINOK(WriteNumber(coderInfo.NumOutStreams)); + RINOK(WriteNumber(coder.NumInStreams)); + RINOK(WriteNumber(coder.NumOutStreams)); } if (propertiesSize == 0) continue; RINOK(WriteNumber(propertiesSize)); - RINOK(WriteBytes2(altCoderInfo.Properties, (UINT32)propertiesSize)); + RINOK(WriteBytes(altCoder.Properties, propertiesSize)); } } - // RINOK(WriteNumber(itemInfo.BindPairs.Size())); - for (i = 0; i < itemInfo.BindPairs.Size(); i++) + for (i = 0; i < folder.BindPairs.Size(); i++) { - const CBindPair &bindPair = itemInfo.BindPairs[i]; + const CBindPair &bindPair = folder.BindPairs[i]; RINOK(WriteNumber(bindPair.InIndex)); RINOK(WriteNumber(bindPair.OutIndex)); } - if (itemInfo.PackStreams.Size() > 1) - for (i = 0; i < itemInfo.PackStreams.Size(); i++) + if (folder.PackStreams.Size() > 1) + for (i = 0; i < folder.PackStreams.Size(); i++) { - const CPackStreamInfo &packStreamInfo = itemInfo.PackStreams[i]; - RINOK(WriteNumber(packStreamInfo.Index)); + RINOK(WriteNumber(folder.PackStreams[i])); } return S_OK; } HRESULT COutArchive::WriteBoolVector(const CBoolVector &boolVector) { - BYTE b = 0; - BYTE mask = 0x80; + Byte b = 0; + Byte mask = 0x80; for(int i = 0; i < boolVector.Size(); i++) { if (boolVector[i]) @@ -164,14 +314,14 @@ HRESULT COutArchive::WriteBoolVector(const CBoolVector &boolVector) mask >>= 1; if (mask == 0) { - RINOK(WriteBytes2(&b, 1)); + RINOK(WriteByte(b)); mask = 0x80; b = 0; } } if (mask != 0x80) { - RINOK(WriteBytes2(&b, 1)); + RINOK(WriteByte(b)); } return S_OK; } @@ -179,7 +329,7 @@ HRESULT COutArchive::WriteBoolVector(const CBoolVector &boolVector) HRESULT COutArchive::WriteHashDigests( const CRecordVector<bool> &digestsDefined, - const CRecordVector<UINT32> &digests) + const CRecordVector<UInt32> &digests) { int numDefined = 0; int i; @@ -189,69 +339,69 @@ HRESULT COutArchive::WriteHashDigests( if (numDefined == 0) return S_OK; - RINOK(WriteByte2(NID::kCRC)); + RINOK(WriteByte(NID::kCRC)); if (numDefined == digestsDefined.Size()) { - RINOK(WriteByte2(1)); + RINOK(WriteByte(1)); } else { - RINOK(WriteByte2(0)); + RINOK(WriteByte(0)); RINOK(WriteBoolVector(digestsDefined)); } for(i = 0; i < digests.Size(); i++) { if(digestsDefined[i]) - RINOK(WriteBytes2(&digests[i], sizeof(digests[i]))); + RINOK(WriteUInt32(digests[i])); } return S_OK; } HRESULT COutArchive::WritePackInfo( - UINT64 dataOffset, - const CRecordVector<UINT64> &packSizes, + UInt64 dataOffset, + const CRecordVector<UInt64> &packSizes, const CRecordVector<bool> &packCRCsDefined, - const CRecordVector<UINT32> &packCRCs) + const CRecordVector<UInt32> &packCRCs) { if (packSizes.IsEmpty()) return S_OK; - RINOK(WriteByte2(NID::kPackInfo)); + RINOK(WriteByte(NID::kPackInfo)); RINOK(WriteNumber(dataOffset)); RINOK(WriteNumber(packSizes.Size())); - RINOK(WriteByte2(NID::kSize)); + RINOK(WriteByte(NID::kSize)); for(int i = 0; i < packSizes.Size(); i++) RINOK(WriteNumber(packSizes[i])); RINOK(WriteHashDigests(packCRCsDefined, packCRCs)); - return WriteByte2(NID::kEnd); + return WriteByte(NID::kEnd); } HRESULT COutArchive::WriteUnPackInfo( bool externalFolders, - UINT64 externalFoldersStreamIndex, + CNum externalFoldersStreamIndex, const CObjectVector<CFolder> &folders) { if (folders.IsEmpty()) return S_OK; - RINOK(WriteByte2(NID::kUnPackInfo)); + RINOK(WriteByte(NID::kUnPackInfo)); - RINOK(WriteByte2(NID::kFolder)); + RINOK(WriteByte(NID::kFolder)); RINOK(WriteNumber(folders.Size())); if (externalFolders) { - RINOK(WriteByte2(1)); + RINOK(WriteByte(1)); RINOK(WriteNumber(externalFoldersStreamIndex)); } else { - RINOK(WriteByte2(0)); + RINOK(WriteByte(0)); for(int i = 0; i < folders.Size(); i++) - RINOK(WriteFolderHeader(folders[i])); + RINOK(WriteFolder(folders[i])); } - RINOK(WriteByte2(NID::kCodersUnPackSize)); + RINOK(WriteByte(NID::kCodersUnPackSize)); int i; for(i = 0; i < folders.Size(); i++) { @@ -261,7 +411,7 @@ HRESULT COutArchive::WriteUnPackInfo( } CRecordVector<bool> unPackCRCsDefined; - CRecordVector<UINT32> unPackCRCs; + CRecordVector<UInt32> unPackCRCs; for(i = 0; i < folders.Size(); i++) { const CFolder &folder = folders[i]; @@ -270,24 +420,24 @@ HRESULT COutArchive::WriteUnPackInfo( } RINOK(WriteHashDigests(unPackCRCsDefined, unPackCRCs)); - return WriteByte2(NID::kEnd); + return WriteByte(NID::kEnd); } HRESULT COutArchive::WriteSubStreamsInfo( const CObjectVector<CFolder> &folders, - const CRecordVector<UINT64> &numUnPackStreamsInFolders, - const CRecordVector<UINT64> &unPackSizes, + const CRecordVector<CNum> &numUnPackStreamsInFolders, + const CRecordVector<UInt64> &unPackSizes, const CRecordVector<bool> &digestsDefined, - const CRecordVector<UINT32> &digests) + const CRecordVector<UInt32> &digests) { - RINOK(WriteByte2(NID::kSubStreamsInfo)); + RINOK(WriteByte(NID::kSubStreamsInfo)); int i; for(i = 0; i < numUnPackStreamsInFolders.Size(); i++) { if (numUnPackStreamsInFolders[i] != 1) { - RINOK(WriteByte2(NID::kNumUnPackStream)); + RINOK(WriteByte(NID::kNumUnPackStream)); for(i = 0; i < numUnPackStreamsInFolders.Size(); i++) RINOK(WriteNumber(numUnPackStreamsInFolders[i])); break; @@ -295,15 +445,15 @@ HRESULT COutArchive::WriteSubStreamsInfo( } - UINT32 needFlag = true; - UINT32 index = 0; + bool needFlag = true; + CNum index = 0; for(i = 0; i < numUnPackStreamsInFolders.Size(); i++) - for (UINT32 j = 0; j < numUnPackStreamsInFolders[i]; j++) + for (CNum j = 0; j < numUnPackStreamsInFolders[i]; j++) { if (j + 1 != numUnPackStreamsInFolders[i]) { if (needFlag) - RINOK(WriteByte2(NID::kSize)); + RINOK(WriteByte(NID::kSize)); needFlag = false; RINOK(WriteNumber(unPackSizes[index])); } @@ -311,7 +461,7 @@ HRESULT COutArchive::WriteSubStreamsInfo( } CRecordVector<bool> digestsDefined2; - CRecordVector<UINT32> digests2; + CRecordVector<UInt32> digests2; int digestIndex = 0; for (i = 0; i < folders.Size(); i++) @@ -327,12 +477,12 @@ HRESULT COutArchive::WriteSubStreamsInfo( } } RINOK(WriteHashDigests(digestsDefined2, digests2)); - return WriteByte2(NID::kEnd); + return WriteByte(NID::kEnd); } HRESULT COutArchive::WriteTime( - const CObjectVector<CFileItem> &files, BYTE type, - bool isExternal, int externalDataIndex) + const CObjectVector<CFileItem> &files, Byte type, + bool isExternal, CNum externalDataIndex) { ///////////////////////////////////////////////// // CreationTime @@ -365,30 +515,30 @@ HRESULT COutArchive::WriteTime( } if (!thereAreDefined) return S_OK; - RINOK(WriteByte2(type)); - UINT32 dataSize = 1 + 1; + RINOK(WriteByte(type)); + size_t dataSize = 1 + 1; if (isExternal) dataSize += GetBigNumberSize(externalDataIndex); else - dataSize += files.Size() * sizeof(CArchiveFileTime); + dataSize += files.Size() * 8; if (allDefined) { RINOK(WriteNumber(dataSize)); - WriteByte2(1); + WriteByte(1); } else { RINOK(WriteNumber(1 + (boolVector.Size() + 7) / 8 + dataSize)); - WriteByte2(0); + WriteByte(0); RINOK(WriteBoolVector(boolVector)); } if (isExternal) { - RINOK(WriteByte2(1)); + RINOK(WriteByte(1)); RINOK(WriteNumber(externalDataIndex)); return S_OK; } - RINOK(WriteByte2(0)); + RINOK(WriteByte(0)); for(i = 0; i < files.Size(); i++) { if (boolVector[i]) @@ -407,14 +557,15 @@ HRESULT COutArchive::WriteTime( timeValue = item.LastAccessTime; break; } - RINOK(WriteBytes2(&timeValue, sizeof(timeValue))); + RINOK(WriteUInt32(timeValue.dwLowDateTime)); + RINOK(WriteUInt32(timeValue.dwHighDateTime)); } } return S_OK; } -HRESULT COutArchive::EncodeStream(CEncoder &encoder, const BYTE *data, UINT32 dataSize, - CRecordVector<UINT64> &packSizes, CObjectVector<CFolder> &folders) +HRESULT COutArchive::EncodeStream(CEncoder &encoder, const Byte *data, size_t dataSize, + CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders) { CSequentialInStreamImp *streamSpec = new CSequentialInStreamImp; CMyComPtr<ISequentialInStream> stream = streamSpec; @@ -422,39 +573,59 @@ HRESULT COutArchive::EncodeStream(CEncoder &encoder, const BYTE *data, UINT32 da CFolder folderItem; folderItem.UnPackCRCDefined = true; folderItem.UnPackCRC = CCRC::CalculateDigest(data, dataSize); - RINOK(encoder.Encode(stream, NULL, - folderItem, Stream, + RINOK(encoder.Encode(stream, NULL, folderItem, SeqStream, packSizes, NULL)); folders.Add(folderItem); return S_OK; } HRESULT COutArchive::EncodeStream(CEncoder &encoder, const CByteBuffer &data, - CRecordVector<UINT64> &packSizes, CObjectVector<CFolder> &folders) + CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders) { return EncodeStream(encoder, data, data.GetCapacity(), packSizes, folders); } +static void WriteUInt32ToBuffer(Byte *data, UInt32 value) +{ + for (int i = 0; i < 4; i++) + { + *data++ = (Byte)value; + value >>= 8; + } +} + +static void WriteUInt64ToBuffer(Byte *data, UInt64 value) +{ + for (int i = 0; i < 8; i++) + { + *data++ = (Byte)value; + value >>= 8; + } +} HRESULT COutArchive::WriteHeader(const CArchiveDatabase &database, - const CCompressionMethodMode *options, UINT64 &headerOffset) + const CCompressionMethodMode *options, UInt64 &headerOffset) { CObjectVector<CFolder> folders; bool compressHeaders = (options != NULL); - std::auto_ptr<CEncoder> encoder; + CMyAutoPtr<CEncoder> encoder; if (compressHeaders) - encoder = std::auto_ptr<CEncoder>(new CEncoder(*options)); + { + // it's for gcc2.95.2 + CMyAutoPtr<CEncoder> tmp(new CEncoder(*options)); + encoder = tmp; + } - CRecordVector<UINT64> packSizes; + CRecordVector<UInt64> packSizes; - UINT64 dataIndex = 0; + CNum dataIndex = 0; ////////////////////////// // Folders - UINT64 externalFoldersStreamIndex; + CNum externalFoldersStreamIndex; bool externalFolders = (compressHeaders && database.Folders.Size() > 8); if (externalFolders) { @@ -464,7 +635,7 @@ HRESULT COutArchive::WriteHeader(const CArchiveDatabase &database, int i; for(i = 0; i < database.Folders.Size(); i++) { - RINOK(WriteFolderHeader(database.Folders[i])); + RINOK(WriteFolder(database.Folders[i])); } _countMode = false; @@ -475,7 +646,7 @@ HRESULT COutArchive::WriteHeader(const CArchiveDatabase &database, for(i = 0; i < database.Folders.Size(); i++) { - RINOK(WriteFolderHeader(database.Folders[i])); + RINOK(WriteFolder(database.Folders[i])); } { @@ -485,25 +656,37 @@ HRESULT COutArchive::WriteHeader(const CArchiveDatabase &database, } + int i; + ///////////////////////////////// // Names + CNum numDefinedNames = 0; + size_t namesDataSize = 0; + for(i = 0; i < database.Files.Size(); i++) + { + const UString &name = database.Files[i].Name; + if (!name.IsEmpty()) + numDefinedNames++; + namesDataSize += (name.Length() + 1) * 2; + } + CByteBuffer namesData; - UINT64 externalNamesStreamIndex; + CNum externalNamesStreamIndex; bool externalNames = (compressHeaders && database.Files.Size() > 8); + if (numDefinedNames > 0) { - UINT64 namesDataSize = 0; - int i; - for(i = 0; i < database.Files.Size(); i++) - namesDataSize += (database.Files[i].Name.Length() + 1) * sizeof(wchar_t); - namesData.SetCapacity(namesDataSize); - UINT32 pos = 0; - for(i = 0; i < database.Files.Size(); i++) + namesData.SetCapacity((size_t)namesDataSize); + size_t pos = 0; + for(int i = 0; i < database.Files.Size(); i++) { const UString &name = database.Files[i].Name; - int length = name.Length() * sizeof(wchar_t); - memmove(namesData + pos, name, length); - pos += length; + for (int t = 0; t < name.Length(); t++) + { + wchar_t c = name[t]; + namesData[pos++] = Byte(c); + namesData[pos++] = Byte(c >> 8); + } namesData[pos++] = 0; namesData[pos++] = 0; } @@ -519,8 +702,7 @@ HRESULT COutArchive::WriteHeader(const CArchiveDatabase &database, // Write Attributes CBoolVector attributesBoolVector; attributesBoolVector.Reserve(database.Files.Size()); - UINT32 numDefinedAttributes = 0; - int i; + int numDefinedAttributes = 0; for(i = 0; i < database.Files.Size(); i++) { bool defined = database.Files[i].AreAttributesDefined; @@ -530,19 +712,19 @@ HRESULT COutArchive::WriteHeader(const CArchiveDatabase &database, } CByteBuffer attributesData; - UINT64 externalAttributesStreamIndex; + CNum externalAttributesStreamIndex; bool externalAttributes = (compressHeaders && numDefinedAttributes > 8); if (numDefinedAttributes > 0) { - attributesData.SetCapacity(numDefinedAttributes * sizeof(UINT32)); - UINT32 pos = 0; + attributesData.SetCapacity(numDefinedAttributes * 4); + size_t pos = 0; for(i = 0; i < database.Files.Size(); i++) { const CFileItem &file = database.Files[i]; if (file.AreAttributesDefined) { - memmove(attributesData + pos, &database.Files[i].Attributes, sizeof(UINT32)); - pos += sizeof(UINT32); + WriteUInt32ToBuffer(attributesData + pos, file.Attributes); + pos += 4; } } if (externalAttributes) @@ -551,13 +733,49 @@ HRESULT COutArchive::WriteHeader(const CArchiveDatabase &database, RINOK(EncodeStream(*encoder, attributesData, packSizes, folders)); } } + + ///////////////////////////////// + // Write StartPos + CBoolVector startsBoolVector; + startsBoolVector.Reserve(database.Files.Size()); + int numDefinedStarts = 0; + for(i = 0; i < database.Files.Size(); i++) + { + bool defined = database.Files[i].IsStartPosDefined; + startsBoolVector.Add(defined); + if (defined) + numDefinedStarts++; + } + + CByteBuffer startsData; + CNum externalStartStreamIndex; + bool externalStarts = (compressHeaders && numDefinedStarts > 8); + if (numDefinedStarts > 0) + { + startsData.SetCapacity(numDefinedStarts * 8); + size_t pos = 0; + for(i = 0; i < database.Files.Size(); i++) + { + const CFileItem &file = database.Files[i]; + if (file.IsStartPosDefined) + { + WriteUInt64ToBuffer(startsData + pos, file.StartPos); + pos += 8; + } + } + if (externalStarts) + { + externalStartStreamIndex = dataIndex++; + RINOK(EncodeStream(*encoder, startsData, packSizes, folders)); + } + } ///////////////////////////////// // Write Last Write Time - UINT64 externalLastWriteTimeStreamIndex; + CNum externalLastWriteTimeStreamIndex; bool externalLastWriteTime = false; // /* - UINT32 numDefinedLastWriteTimes = 0; + CNum numDefinedLastWriteTimes = 0; for(i = 0; i < database.Files.Size(); i++) if (database.Files[i].IsLastWriteTimeDefined) numDefinedLastWriteTimes++; @@ -566,15 +784,17 @@ HRESULT COutArchive::WriteHeader(const CArchiveDatabase &database, if (numDefinedLastWriteTimes > 0) { CByteBuffer lastWriteTimeData; - lastWriteTimeData.SetCapacity(numDefinedLastWriteTimes * sizeof(CArchiveFileTime)); - UINT32 pos = 0; + lastWriteTimeData.SetCapacity(numDefinedLastWriteTimes * 8); + size_t pos = 0; for(i = 0; i < database.Files.Size(); i++) { const CFileItem &file = database.Files[i]; if (file.IsLastWriteTimeDefined) { - memmove(lastWriteTimeData + pos, &database.Files[i].LastWriteTime, sizeof(CArchiveFileTime)); - pos += sizeof(CArchiveFileTime); + WriteUInt32ToBuffer(lastWriteTimeData + pos, file.LastWriteTime.dwLowDateTime); + pos += 4; + WriteUInt32ToBuffer(lastWriteTimeData + pos, file.LastWriteTime.dwHighDateTime); + pos += 4; } } if (externalLastWriteTime) @@ -586,10 +806,10 @@ HRESULT COutArchive::WriteHeader(const CArchiveDatabase &database, // */ - UINT64 packedSize = 0; + UInt64 packedSize = 0; for(i = 0; i < database.PackSizes.Size(); i++) packedSize += database.PackSizes[i]; - UINT64 headerPackSize = 0; + UInt64 headerPackSize = 0; for (i = 0; i < packSizes.Size(); i++) headerPackSize += packSizes[i]; @@ -597,45 +817,45 @@ HRESULT COutArchive::WriteHeader(const CArchiveDatabase &database, _mainMode = true; - _outByte.Init(Stream); + _outByte.SetStream(SeqStream); + _outByte.Init(); _crc.Init(); - RINOK(WriteByte2(NID::kHeader)); + RINOK(WriteByte(NID::kHeader)); // Archive Properties if (folders.Size() > 0) { - RINOK(WriteByte2(NID::kAdditionalStreamsInfo)); + RINOK(WriteByte(NID::kAdditionalStreamsInfo)); RINOK(WritePackInfo(packedSize, packSizes, - CRecordVector<bool>(), CRecordVector<UINT32>())); + CRecordVector<bool>(), CRecordVector<UInt32>())); RINOK(WriteUnPackInfo(false, 0, folders)); - RINOK(WriteByte2(NID::kEnd)); + RINOK(WriteByte(NID::kEnd)); } //////////////////////////////////////////////////// if (database.Folders.Size() > 0) { - RINOK(WriteByte2(NID::kMainStreamsInfo)); + RINOK(WriteByte(NID::kMainStreamsInfo)); RINOK(WritePackInfo(0, database.PackSizes, database.PackCRCsDefined, database.PackCRCs)); - RINOK(WriteUnPackInfo( - externalFolders, externalFoldersStreamIndex, database.Folders)); + RINOK(WriteUnPackInfo(externalFolders, externalFoldersStreamIndex, database.Folders)); - CRecordVector<UINT64> unPackSizes; + CRecordVector<UInt64> unPackSizes; CRecordVector<bool> digestsDefined; - CRecordVector<UINT32> digests; + CRecordVector<UInt32> digests; for (i = 0; i < database.Files.Size(); i++) { const CFileItem &file = database.Files[i]; if (!file.HasStream) continue; unPackSizes.Add(file.UnPackSize); - digestsDefined.Add(file.FileCRCIsDefined); + digestsDefined.Add(file.IsFileCRCDefined); digests.Add(file.FileCRC); } @@ -645,21 +865,21 @@ HRESULT COutArchive::WriteHeader(const CArchiveDatabase &database, unPackSizes, digestsDefined, digests)); - RINOK(WriteByte2(NID::kEnd)); + RINOK(WriteByte(NID::kEnd)); } if (database.Files.IsEmpty()) { - RINOK(WriteByte2(NID::kEnd)); + RINOK(WriteByte(NID::kEnd)); return _outByte.Flush(); } - RINOK(WriteByte2(NID::kFilesInfo)); + RINOK(WriteByte(NID::kFilesInfo)); RINOK(WriteNumber(database.Files.Size())); CBoolVector emptyStreamVector; emptyStreamVector.Reserve(database.Files.Size()); - UINT64 numEmptyStreams = 0; + int numEmptyStreams = 0; for(i = 0; i < database.Files.Size(); i++) if (database.Files[i].HasStream) emptyStreamVector.Add(false); @@ -670,14 +890,14 @@ HRESULT COutArchive::WriteHeader(const CArchiveDatabase &database, } if (numEmptyStreams > 0) { - RINOK(WriteByte2(NID::kEmptyStream)); + RINOK(WriteByte(NID::kEmptyStream)); RINOK(WriteNumber((emptyStreamVector.Size() + 7) / 8)); RINOK(WriteBoolVector(emptyStreamVector)); CBoolVector emptyFileVector, antiVector; emptyFileVector.Reserve(numEmptyStreams); antiVector.Reserve(numEmptyStreams); - UINT64 numEmptyFiles = 0, numAntiItems = 0; + CNum numEmptyFiles = 0, numAntiItems = 0; for(i = 0; i < database.Files.Size(); i++) { const CFileItem &file = database.Files[i]; @@ -694,34 +914,34 @@ HRESULT COutArchive::WriteHeader(const CArchiveDatabase &database, if (numEmptyFiles > 0) { - RINOK(WriteByte2(NID::kEmptyFile)); + RINOK(WriteByte(NID::kEmptyFile)); RINOK(WriteNumber((emptyFileVector.Size() + 7) / 8)); RINOK(WriteBoolVector(emptyFileVector)); } if (numAntiItems > 0) { - RINOK(WriteByte2(NID::kAnti)); + RINOK(WriteByte(NID::kAnti)); RINOK(WriteNumber((antiVector.Size() + 7) / 8)); RINOK(WriteBoolVector(antiVector)); } } + if (numDefinedNames > 0) { ///////////////////////////////////////////////// - RINOK(WriteByte2(NID::kName)); + RINOK(WriteByte(NID::kName)); if (externalNames) { - RINOK(WriteNumber(1 + - GetBigNumberSize(externalNamesStreamIndex))); - RINOK(WriteByte2(1)); + RINOK(WriteNumber(1 + GetBigNumberSize(externalNamesStreamIndex))); + RINOK(WriteByte(1)); RINOK(WriteNumber(externalNamesStreamIndex)); } else { RINOK(WriteNumber(1 + namesData.GetCapacity())); - RINOK(WriteByte2(0)); - RINOK(WriteBytes2(namesData)); + RINOK(WriteByte(0)); + RINOK(WriteBytes(namesData)); } } @@ -734,9 +954,8 @@ HRESULT COutArchive::WriteHeader(const CArchiveDatabase &database, if (numDefinedAttributes > 0) { - ///////////////////////////////////////////////// - RINOK(WriteByte2(NID::kWinAttributes)); - UINT32 size = 2; + RINOK(WriteByte(NID::kWinAttributes)); + size_t size = 2; if (numDefinedAttributes != database.Files.Size()) size += (attributesBoolVector.Size() + 7) / 8 + 1; if (externalAttributes) @@ -747,28 +966,62 @@ HRESULT COutArchive::WriteHeader(const CArchiveDatabase &database, RINOK(WriteNumber(size)); if (numDefinedAttributes == database.Files.Size()) { - RINOK(WriteByte2(1)); + RINOK(WriteByte(1)); } else { - RINOK(WriteByte2(0)); + RINOK(WriteByte(0)); RINOK(WriteBoolVector(attributesBoolVector)); } if (externalAttributes) { - RINOK(WriteByte2(1)); + RINOK(WriteByte(1)); RINOK(WriteNumber(externalAttributesStreamIndex)); } else { - RINOK(WriteByte2(0)); - RINOK(WriteBytes2(attributesData)); + RINOK(WriteByte(0)); + RINOK(WriteBytes(attributesData)); + } + } + + if (numDefinedStarts > 0) + { + RINOK(WriteByte(NID::kStartPos)); + size_t size = 2; + if (numDefinedStarts != database.Files.Size()) + size += (startsBoolVector.Size() + 7) / 8 + 1; + if (externalStarts) + size += GetBigNumberSize(externalStartStreamIndex); + else + size += startsData.GetCapacity(); + + RINOK(WriteNumber(size)); + if (numDefinedStarts == database.Files.Size()) + { + RINOK(WriteByte(1)); + } + else + { + RINOK(WriteByte(0)); + RINOK(WriteBoolVector(startsBoolVector)); + } + + if (externalAttributes) + { + RINOK(WriteByte(1)); + RINOK(WriteNumber(externalStartStreamIndex)); + } + else + { + RINOK(WriteByte(0)); + RINOK(WriteBytes(startsData)); } } - RINOK(WriteByte2(NID::kEnd)); // for files - RINOK(WriteByte2(NID::kEnd)); // for headers + RINOK(WriteByte(NID::kEnd)); // for files + RINOK(WriteByte(NID::kEnd)); // for headers return _outByte.Flush(); } @@ -777,9 +1030,9 @@ HRESULT COutArchive::WriteDatabase(const CArchiveDatabase &database, const CCompressionMethodMode *options, bool useAdditionalStreams, bool compressMainHeader) { - UINT64 headerOffset; - UINT32 headerCRC; - UINT64 headerSize; + UInt64 headerOffset; + UInt32 headerCRC; + UInt64 headerSize; if (database.IsEmpty()) { headerSize = 0; @@ -811,16 +1064,16 @@ HRESULT COutArchive::WriteDatabase(const CArchiveDatabase &database, CCompressionMethodMode encryptOptions; encryptOptions.PasswordIsDefined = options->PasswordIsDefined; encryptOptions.Password = options->Password; - CEncoder encoder(compressMainHeader ? - *options : encryptOptions); - CRecordVector<UINT64> packSizes; + CEncoder encoder(compressMainHeader ? *options : encryptOptions); + CRecordVector<UInt64> packSizes; CObjectVector<CFolder> folders; RINOK(EncodeStream(encoder, _dynamicBuffer, _dynamicBuffer.GetSize(), packSizes, folders)); _dynamicMode = false; _mainMode = true; - _outByte.Init(Stream); + _outByte.SetStream(SeqStream); + _outByte.Init(); _crc.Init(); if (folders.Size() == 0) @@ -828,9 +1081,9 @@ HRESULT COutArchive::WriteDatabase(const CArchiveDatabase &database, RINOK(WriteID(NID::kEncodedHeader)); RINOK(WritePackInfo(headerOffset, packSizes, - CRecordVector<bool>(), CRecordVector<UINT32>())); + CRecordVector<bool>(), CRecordVector<UInt32>())); RINOK(WriteUnPackInfo(false, 0, folders)); - RINOK(WriteByte2(NID::kEnd)); + RINOK(WriteByte(NID::kEnd)); for (int i = 0; i < packSizes.Size(); i++) headerOffset += packSizes[i]; RINOK(_outByte.Flush()); @@ -838,16 +1091,30 @@ HRESULT COutArchive::WriteDatabase(const CArchiveDatabase &database, headerCRC = _crc.GetDigest(); headerSize = _outByte.GetProcessedSize(); } - RINOK(Stream->Seek(_prefixHeaderPos, STREAM_SEEK_SET, NULL)); - - CStartHeader startHeader; - startHeader.NextHeaderOffset = headerOffset; - startHeader.NextHeaderSize = headerSize; - startHeader.NextHeaderCRC = headerCRC; - - UINT32 crc = CCRC::CalculateDigest(&startHeader, sizeof(startHeader)); - RINOK(WriteBytes(&crc, sizeof(crc))); - return WriteBytes(&startHeader, sizeof(startHeader)); + #ifdef _7Z_VOL + if (_endMarker) + { + CFinishHeader h; + h.NextHeaderSize = headerSize; + h.NextHeaderCRC = headerCRC; + h.NextHeaderOffset = + UInt64(0) - (headerSize + + 4 + kFinishHeaderSize); + h.ArchiveStartOffset = h.NextHeaderOffset - headerOffset; + h.AdditionalStartBlockSize = 0; + RINOK(WriteFinishHeader(h)); + return WriteFinishSignature(); + } + else + #endif + { + CStartHeader h; + h.NextHeaderSize = headerSize; + h.NextHeaderCRC = headerCRC; + h.NextHeaderOffset = headerOffset; + RINOK(Stream->Seek(_prefixHeaderPos, STREAM_SEEK_SET, NULL)); + return WriteStartHeader(h); + } } }} diff --git a/7zip/Archive/7z/7zOut.h b/7zip/Archive/7z/7zOut.h index 1742dd41..ede61381 100755 --- a/7zip/Archive/7z/7zOut.h +++ b/7zip/Archive/7z/7zOut.h @@ -1,7 +1,5 @@ // 7z/Out.h -#pragma once - #ifndef __7Z_OUT_H #define __7Z_OUT_H @@ -19,18 +17,18 @@ namespace N7z { class CWriteBufferLoc { - BYTE *_data; - UINT32 _size; - UINT32 _pos; + Byte *_data; + size_t _size; + size_t _pos; public: CWriteBufferLoc(): _size(0), _pos(0) {} - void Init(BYTE *data, UINT32 size) + void Init(Byte *data, size_t size) { _pos = 0; _data = data; _size = size; } - HRESULT Write(const void *data, UINT32 size) + HRESULT Write(const void *data, size_t size) { if (_pos + size > _size) return E_FAIL; @@ -43,110 +41,135 @@ public: class CWriteDynamicBuffer { CByteDynamicBuffer _buffer; - UINT32 _pos; + size_t _pos; public: CWriteDynamicBuffer(): _pos(0) {} void Init() { _pos = 0; } - void Write(const void *data, UINT32 size) + void Write(const void *data, size_t size) { if (_pos + size > _buffer.GetCapacity()) _buffer.EnsureCapacity(_pos + size); - memmove(((BYTE *)_buffer) +_pos, data, size); + memmove(((Byte *)_buffer) +_pos, data, size); _pos += size; } - operator BYTE *() { return (BYTE *)_buffer; }; - operator const BYTE *() const { return (const BYTE *)_buffer; }; - UINT32 GetSize() const { return _pos; } + operator Byte *() { return (Byte *)_buffer; }; + operator const Byte *() const { return (const Byte *)_buffer; }; + size_t GetSize() const { return _pos; } }; class COutArchive { - UINT64 _prefixHeaderPos; - - HRESULT WriteBytes(const void *data, UINT32 size); - HRESULT WriteBytes2(const void *data, UINT32 size); - HRESULT WriteBytes2(const CByteBuffer &data); - HRESULT WriteByte2(BYTE b); - HRESULT WriteNumber(UINT64 value); - HRESULT WriteID(UINT64 value) - { - return WriteNumber(value); - } + UInt64 _prefixHeaderPos; - HRESULT WriteFolderHeader(const CFolder &itemInfo); + HRESULT WriteDirect(const void *data, UInt32 size); + HRESULT WriteDirectByte(Byte b) { return WriteDirect(&b, 1); } + HRESULT WriteDirectUInt32(UInt32 value); + HRESULT WriteDirectUInt64(UInt64 value); + + HRESULT WriteBytes(const void *data, size_t size); + HRESULT WriteBytes(const CByteBuffer &data); + HRESULT WriteByte(Byte b); + HRESULT WriteUInt32(UInt32 value); + HRESULT WriteNumber(UInt64 value); + HRESULT WriteID(UInt64 value) { return WriteNumber(value); } + + HRESULT WriteFolder(const CFolder &folder); HRESULT WriteFileHeader(const CFileItem &itemInfo); HRESULT WriteBoolVector(const CBoolVector &boolVector); HRESULT WriteHashDigests( const CRecordVector<bool> &digestsDefined, - const CRecordVector<UINT32> &hashDigests); + const CRecordVector<UInt32> &hashDigests); HRESULT WritePackInfo( - UINT64 dataOffset, - const CRecordVector<UINT64> &packSizes, + UInt64 dataOffset, + const CRecordVector<UInt64> &packSizes, const CRecordVector<bool> &packCRCsDefined, - const CRecordVector<UINT32> &packCRCs); + const CRecordVector<UInt32> &packCRCs); HRESULT WriteUnPackInfo( bool externalFolders, - UINT64 externalFoldersStreamIndex, + CNum externalFoldersStreamIndex, const CObjectVector<CFolder> &folders); HRESULT WriteSubStreamsInfo( const CObjectVector<CFolder> &folders, - const CRecordVector<UINT64> &numUnPackStreamsInFolders, - const CRecordVector<UINT64> &unPackSizes, + const CRecordVector<CNum> &numUnPackStreamsInFolders, + const CRecordVector<UInt64> &unPackSizes, const CRecordVector<bool> &digestsDefined, - const CRecordVector<UINT32> &hashDigests); + const CRecordVector<UInt32> &hashDigests); + /* HRESULT WriteStreamsInfo( - UINT64 dataOffset, - const CRecordVector<UINT64> &packSizes, + UInt64 dataOffset, + const CRecordVector<UInt64> &packSizes, const CRecordVector<bool> &packCRCsDefined, - const CRecordVector<UINT32> &packCRCs, + const CRecordVector<UInt32> &packCRCs, bool externalFolders, - UINT64 externalFoldersStreamIndex, + UInt64 externalFoldersStreamIndex, const CObjectVector<CFolder> &folders, - const CRecordVector<UINT64> &numUnPackStreamsInFolders, - const CRecordVector<UINT64> &unPackSizes, + const CRecordVector<CNum> &numUnPackStreamsInFolders, + const CRecordVector<UInt64> &unPackSizes, const CRecordVector<bool> &digestsDefined, - const CRecordVector<UINT32> &hashDigests); + const CRecordVector<UInt32> &hashDigests); + */ - HRESULT WriteTime(const CObjectVector<CFileItem> &files, BYTE type, - bool isExternal, int externalDataIndex); + HRESULT WriteTime(const CObjectVector<CFileItem> &files, Byte type, + bool isExternal, CNum externalDataIndex); - HRESULT EncodeStream(CEncoder &encoder, const BYTE *data, UINT32 dataSize, - CRecordVector<UINT64> &packSizes, CObjectVector<CFolder> &folders); + HRESULT EncodeStream(CEncoder &encoder, const Byte *data, size_t dataSize, + CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders); HRESULT EncodeStream(CEncoder &encoder, const CByteBuffer &data, - CRecordVector<UINT64> &packSizes, CObjectVector<CFolder> &folders); + CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders); HRESULT WriteHeader(const CArchiveDatabase &database, const CCompressionMethodMode *options, - UINT64 &headerOffset); + UInt64 &headerOffset); bool _mainMode; bool _dynamicMode; bool _countMode; - UINT32 _countSize; + size_t _countSize; COutBuffer _outByte; CWriteBufferLoc _outByte2; CWriteDynamicBuffer _dynamicBuffer; CCRC _crc; -public: + #ifdef _7Z_VOL + bool _endMarker; + #endif + + HRESULT WriteSignature(); + #ifdef _7Z_VOL + HRESULT WriteFinishSignature(); + #endif + HRESULT WriteStartHeader(const CStartHeader &h); + #ifdef _7Z_VOL + HRESULT WriteFinishHeader(const CFinishHeader &h); + #endif CMyComPtr<IOutStream> Stream; - HRESULT Create(IOutStream *stream); +public: + + COutArchive() { _outByte.Create(1 << 16); } + CMyComPtr<ISequentialOutStream> SeqStream; + HRESULT Create(ISequentialOutStream *stream, bool endMarker); void Close(); HRESULT SkeepPrefixArchiveHeader(); HRESULT WriteDatabase(const CArchiveDatabase &database, const CCompressionMethodMode *options, bool useAdditionalHeaderStreams, bool compressMainHeader); + + #ifdef _7Z_VOL + static UInt32 GetVolHeadersSize(UInt64 dataSize, int nameLength = 0, bool props = false); + static UInt64 GetVolPureSize(UInt64 volSize, int nameLength = 0, bool props = false); + #endif + }; }} diff --git a/7zip/Archive/7z/7zProperties.cpp b/7zip/Archive/7z/7zProperties.cpp index 84363b60..316f4f09 100755 --- a/7zip/Archive/7z/7zProperties.cpp +++ b/7zip/Archive/7z/7zProperties.cpp @@ -13,7 +13,7 @@ namespace N7z { struct CPropMap { - UINT64 FilePropID; + UInt64 FilePropID; STATPROPSTG StatPROPSTG; }; @@ -35,6 +35,7 @@ CPropMap kPropMap[] = { NID::kLastWriteTime, NULL, kpidLastWriteTime, VT_FILETIME}, { NID::kLastAccessTime, NULL, kpidLastAccessTime, VT_FILETIME}, { NID::kWinAttributes, NULL, kpidAttributes, VT_UI4}, + { NID::kStartPos, NULL, kpidPosition, VT_UI4}, { NID::kCRC, NULL, kpidCRC, VT_UI4}, @@ -52,7 +53,7 @@ CPropMap kPropMap[] = static const int kPropMapSize = sizeof(kPropMap) / sizeof(kPropMap[0]); -static int FindPropInMap(UINT64 filePropID) +static int FindPropInMap(UInt64 filePropID) { for (int i = 0; i < kPropMapSize; i++) if (kPropMap[i].FilePropID == filePropID) @@ -60,8 +61,8 @@ static int FindPropInMap(UINT64 filePropID) return -1; } -static void CopyOneItem(CRecordVector<UINT64> &src, - CRecordVector<UINT64> &dest, UINT32 item) +static void CopyOneItem(CRecordVector<UInt64> &src, + CRecordVector<UInt64> &dest, UInt32 item) { for (int i = 0; i < src.Size(); i++) if (src[i] == item) @@ -72,7 +73,7 @@ static void CopyOneItem(CRecordVector<UINT64> &src, } } -static void RemoveOneItem(CRecordVector<UINT64> &src, UINT32 item) +static void RemoveOneItem(CRecordVector<UInt64> &src, UInt32 item) { for (int i = 0; i < src.Size(); i++) if (src[i] == item) @@ -82,7 +83,7 @@ static void RemoveOneItem(CRecordVector<UINT64> &src, UINT32 item) } } -static void InsertToHead(CRecordVector<UINT64> &dest, UINT32 item) +static void InsertToHead(CRecordVector<UInt64> &dest, UInt32 item) { for (int i = 0; i < dest.Size(); i++) if (dest[i] == item) @@ -96,7 +97,15 @@ static void InsertToHead(CRecordVector<UINT64> &dest, UINT32 item) void CHandler::FillPopIDs() { _fileInfoPopIDs.Clear(); - CRecordVector<UINT64> fileInfoPopIDs = _database.ArchiveInfo.FileInfoPopIDs; + + #ifdef _7Z_VOL + if(_volumes.Size() < 1) + return; + const CVolume &volume = _volumes.Front(); + const CArchiveDatabaseEx &_database = volume.Database; + #endif + + CRecordVector<UInt64> fileInfoPopIDs = _database.ArchiveInfo.FileInfoPopIDs; RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream); RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile); @@ -133,16 +142,16 @@ void CHandler::FillPopIDs() #endif } -STDMETHODIMP CHandler::GetNumberOfProperties(UINT32 *numProperties) +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) { *numProperties = _fileInfoPopIDs.Size(); return S_OK; } -STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index, +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) { - if(index >= _fileInfoPopIDs.Size()) + if((int)index >= _fileInfoPopIDs.Size()) return E_INVALIDARG; int indexInMap = FindPropInMap(_fileInfoPopIDs[index]); if (indexInMap == -1) diff --git a/7zip/Archive/7z/7zProperties.h b/7zip/Archive/7z/7zProperties.h index 0b85b5e9..a09839bb 100755 --- a/7zip/Archive/7z/7zProperties.h +++ b/7zip/Archive/7z/7zProperties.h @@ -1,7 +1,5 @@ // 7zProperties.h -#pragma once - #ifndef __7Z_PROPERTIES_H #define __7Z_PROPERTIES_H @@ -19,33 +17,6 @@ enum // PropID kpidPackedSize4, }; -/* -class CEnumArchiveItemProperty: - public IEnumSTATPROPSTG, - public CComObjectRoot -{ - CRecordVector<UINT32> _fileInfoPopIDs; - int _index; -public: - - BEGIN_COM_MAP(CEnumArchiveItemProperty) - COM_INTERFACE_ENTRY(IEnumSTATPROPSTG) - END_COM_MAP() - - DECLARE_NOT_AGGREGATABLE(CEnumArchiveItemProperty) - - DECLARE_NO_REGISTRY() -public: - CEnumArchiveItemProperty(): _index(0) {}; - void Init(const CRecordVector<UINT32> &fileInfoPopIDs); - - STDMETHOD(Next) (ULONG numItems, STATPROPSTG *items, ULONG *numFetched); - STDMETHOD(Skip) (ULONG numItems); - STDMETHOD(Reset) (); - STDMETHOD(Clone) (IEnumSTATPROPSTG **enumerator); -}; -*/ - }} #endif diff --git a/7zip/Archive/7z/7zSpecStream.cpp b/7zip/Archive/7z/7zSpecStream.cpp index 4ff7b5c0..fb42d98c 100755 --- a/7zip/Archive/7z/7zSpecStream.cpp +++ b/7zip/Archive/7z/7zSpecStream.cpp @@ -4,9 +4,9 @@ #include "7zSpecStream.h" -STDMETHODIMP CSequentialInStreamSizeCount2::Read(void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CSequentialInStreamSizeCount2::Read(void *data, UInt32 size, UInt32 *processedSize) { - UINT32 realProcessedSize; + UInt32 realProcessedSize; HRESULT result = _stream->Read(data, size, &realProcessedSize); _size += realProcessedSize; if (processedSize != 0) @@ -14,9 +14,9 @@ STDMETHODIMP CSequentialInStreamSizeCount2::Read(void *data, UINT32 size, UINT32 return result; } -STDMETHODIMP CSequentialInStreamSizeCount2::ReadPart(void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CSequentialInStreamSizeCount2::ReadPart(void *data, UInt32 size, UInt32 *processedSize) { - UINT32 realProcessedSize; + UInt32 realProcessedSize; HRESULT result = _stream->ReadPart(data, size, &realProcessedSize); _size += realProcessedSize; if (processedSize != 0) @@ -25,7 +25,7 @@ STDMETHODIMP CSequentialInStreamSizeCount2::ReadPart(void *data, UINT32 size, UI } STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize( - UINT64 subStream, UINT64 *value) + UInt64 subStream, UInt64 *value) { if (_getSubStreamSize == NULL) return E_NOTIMPL; diff --git a/7zip/Archive/7z/7zSpecStream.h b/7zip/Archive/7z/7zSpecStream.h index 92019fff..7d3cf538 100755 --- a/7zip/Archive/7z/7zSpecStream.h +++ b/7zip/Archive/7z/7zSpecStream.h @@ -1,7 +1,5 @@ // 7zSpecStream.h -#pragma once - #ifndef __7Z_SPEC_STREAM_H #define __7Z_SPEC_STREAM_H @@ -16,7 +14,7 @@ class CSequentialInStreamSizeCount2: { CMyComPtr<ISequentialInStream> _stream; CMyComPtr<ICompressGetSubStreamSize> _getSubStreamSize; - UINT64 _size; + UInt64 _size; public: void Init(ISequentialInStream *stream) { @@ -25,14 +23,14 @@ public: _stream.QueryInterface(IID_ICompressGetSubStreamSize, &_getSubStreamSize); _size = 0; } - UINT64 GetSize() const { return _size; } + UInt64 GetSize() const { return _size; } MY_UNKNOWN_IMP1(ICompressGetSubStreamSize) - STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize); - STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize); + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(GetSubStreamSize)(UINT64 subStream, UINT64 *value); + STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value); }; #endif diff --git a/7zip/Archive/7z/7zUpdate.cpp b/7zip/Archive/7z/7zUpdate.cpp index 6633f92f..e2bb9c3f 100755 --- a/7zip/Archive/7z/7zUpdate.cpp +++ b/7zip/Archive/7z/7zUpdate.cpp @@ -22,9 +22,9 @@ namespace NArchive { namespace N7z { static const wchar_t *kMatchFinderForBCJ2_LZMA = L"BT2"; -static const UINT32 kDictionaryForBCJ2_LZMA = 1 << 20; -const UINT32 kAlgorithmForBCJ2_LZMA = 2; -const UINT32 kNumFastBytesForBCJ2_LZMA = 64; +static const UInt32 kDictionaryForBCJ2_LZMA = 1 << 20; +static const UInt32 kAlgorithmForBCJ2_LZMA = 2; +static const UInt32 kNumFastBytesForBCJ2_LZMA = 64; static HRESULT CopyBlock(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress) @@ -33,19 +33,17 @@ static HRESULT CopyBlock(ISequentialInStream *inStream, return copyCoder->Code(inStream, outStream, NULL, NULL, progress); } -static HRESULT WriteRange(IInStream *inStream, +static HRESULT WriteRange( + ISequentialInStream *inStream, ISequentialOutStream *outStream, - const CUpdateRange &range, + UInt64 size, IProgress *progress, - UINT64 ¤tComplexity) + UInt64 ¤tComplexity) { - UINT64 position; - inStream->Seek(range.Position, STREAM_SEEK_SET, &position); - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; CMyComPtr<CLimitedSequentialInStream> inStreamLimited(streamSpec); - streamSpec->Init(inStream, range.Size); + streamSpec->Init(inStream, size); CLocalProgress *localProgressSpec = new CLocalProgress; CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec; @@ -58,10 +56,23 @@ static HRESULT WriteRange(IInStream *inStream, localCompressProgressSpec->Init(localProgress, ¤tComplexity, ¤tComplexity); HRESULT result = CopyBlock(inStreamLimited, outStream, compressProgress); - currentComplexity += range.Size; + currentComplexity += size; return result; } + +static HRESULT WriteRange(IInStream *inStream, + ISequentialOutStream *outStream, + UInt64 position, + UInt64 size, + IProgress *progress, + UInt64 ¤tComplexity) +{ + inStream->Seek(position, STREAM_SEEK_SET, 0); + return WriteRange(inStream, outStream, + size, progress, currentComplexity); +} + int CUpdateItem::GetExtensionPos() const { int slash1Pos = Name.ReverseFind(L'\\'); @@ -163,8 +174,8 @@ static int __cdecl CompareFolderRefs(const void *p1, const void *p2) if (d1.NumUnPackStreamsVector[a1.FolderIndex] == 0) return 0; return CompareFiles( - d1.Files[d1.FolderStartFileIndex[a1.FolderIndex]], - d2.Files[d2.FolderStartFileIndex[a2.FolderIndex]]); + d1.Files[(size_t)d1.FolderStartFileIndex[a1.FolderIndex]], + d2.Files[(size_t)d2.FolderStartFileIndex[a2.FolderIndex]]); } //////////////////////////////////////////////////////////// @@ -193,12 +204,12 @@ static int __cdecl CompareEmptyItems(const void *p1, const void *p2) struct CRefItem { - UINT32 Index; + UInt32 Index; const CUpdateItem *UpdateItem; - UINT32 ExtensionPos; - UINT32 NamePos; + UInt32 ExtensionPos; + UInt32 NamePos; bool SortByType; - CRefItem(UINT32 index, const CUpdateItem &updateItem, bool sortByType): + CRefItem(UInt32 index, const CUpdateItem &updateItem, bool sortByType): SortByType(sortByType), Index(index), UpdateItem(&updateItem), @@ -257,7 +268,7 @@ static int __cdecl CompareUpdateItems(const void *p1, const void *p2) struct CSolidGroup { CCompressionMethodMode Method; - CRecordVector<UINT32> Indices; + CRecordVector<UInt32> Indices; }; static wchar_t *g_ExeExts[] = @@ -282,7 +293,7 @@ static CMethodID k_BCJ2 = { { 0x3, 0x3, 0x1, 0x1B }, 4 }; static CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 }; static bool GetMethodFull(const CMethodID &methodID, - UINT32 numInStreams, CMethodFull &methodResult) + UInt32 numInStreams, CMethodFull &methodResult) { methodResult.MethodID = methodID; methodResult.NumInStreams = numInStreams; @@ -441,40 +452,43 @@ static void FromUpdateItemToFileItem(const CUpdateItem &updateItem, file.HasStream = updateItem.HasStream(); } -HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database, - CObjectVector<CUpdateItem> &updateItems, - IOutStream *outStream, +static HRESULT Update2( IInStream *inStream, - NArchive::N7z::CInArchiveInfo *inArchiveInfo, - const CCompressionMethodMode &method, - const CCompressionMethodMode *headerMethod, - bool useFilters, - bool maxFilter, - bool useAdditionalHeaderStreams, - bool compressMainHeader, + const CArchiveDatabaseEx *database, + CObjectVector<CUpdateItem> &updateItems, + ISequentialOutStream *seqOutStream, IArchiveUpdateCallback *updateCallback, - UINT64 numSolidFiles, UINT64 numSolidBytes, bool solidExtension, - bool removeSfxBlock) + const CUpdateOptions &options) { + UInt64 numSolidFiles = options.NumSolidFiles; if (numSolidFiles == 0) numSolidFiles = 1; - - UINT64 startBlockSize = inArchiveInfo != 0 ? - inArchiveInfo->StartPosition: 0; - if (startBlockSize > 0 && !removeSfxBlock) + /* + CMyComPtr<IOutStream> outStream; + RINOK(seqOutStream->QueryInterface(IID_IOutStream, (void **)&outStream)); + if (!outStream) + return E_NOTIMPL; + */ + + UInt64 startBlockSize = database != 0 ? + database->ArchiveInfo.StartPosition: 0; + if (startBlockSize > 0 && !options.RemoveSfxBlock) { CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; CMyComPtr<ISequentialInStream> limitedStream(streamSpec); RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL)); streamSpec->Init(inStream, startBlockSize); - RINOK(CopyBlock(limitedStream, outStream, NULL)); + RINOK(CopyBlock(limitedStream, seqOutStream, NULL)); } CRecordVector<int> fileIndexToUpdateIndexMap; - fileIndexToUpdateIndexMap.Reserve(database.Files.Size()); + if (database != 0) + { + fileIndexToUpdateIndexMap.Reserve(database->Files.Size()); + for (int i = 0; i < database->Files.Size(); i++) + fileIndexToUpdateIndexMap.Add(-1); + } int i; - for (i = 0; i < database.Files.Size(); i++) - fileIndexToUpdateIndexMap.Add(-1); for(i = 0; i < updateItems.Size(); i++) { int index = updateItems[i].IndexInArchive; @@ -483,15 +497,17 @@ HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database, } CRecordVector<CFolderRef> folderRefs; - for(i = 0; i < database.Folders.Size(); i++) + if (database != 0) { - UINT64 indexInFolder = 0; - UINT64 numCopyItems = 0; - UINT64 numUnPackStreams = database.NumUnPackStreamsVector[i]; - for (int fileIndex = database.FolderStartFileIndex[i]; + for(i = 0; i < database->Folders.Size(); i++) + { + CNum indexInFolder = 0; + CNum numCopyItems = 0; + CNum numUnPackStreams = database->NumUnPackStreamsVector[i]; + for (CNum fileIndex = database->FolderStartFileIndex[i]; indexInFolder < numUnPackStreams; fileIndex++) { - if (database.Files[fileIndex].HasStream) + if (database->Files[fileIndex].HasStream) { indexInFolder++; int updateIndex = fileIndexToUpdateIndexMap[fileIndex]; @@ -505,13 +521,14 @@ HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database, if (numCopyItems > 0) { CFolderRef folderRef; - folderRef.Database = &database; + folderRef.Database = database; folderRef.FolderIndex = i; folderRefs.Add(folderRef); } } qsort(&folderRefs.Front(), folderRefs.Size(), sizeof(folderRefs[0]), CompareFolderRefs); + } CArchiveDatabase newDatabase; @@ -529,7 +546,7 @@ HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database, } else if (updateItem.IndexInArchive != -1) - if (database.Files[updateItem.IndexInArchive].HasStream) + if (database->Files[updateItem.IndexInArchive].HasStream) continue; emptyRefs.Add(&updateItem); } @@ -542,18 +559,18 @@ HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database, if (updateItem.NewProperties) FromUpdateItemToFileItem(updateItem, file); else - file = database.Files[updateItem.IndexInArchive]; + file = database->Files[updateItem.IndexInArchive]; newDatabase.Files.Add(file); } //////////////////////////// COutArchive archive; - archive.Create(outStream); + archive.Create(seqOutStream, false); RINOK(archive.SkeepPrefixArchiveHeader()); - UINT64 complexity = 0; + UInt64 complexity = 0; for(i = 0; i < folderRefs.Size(); i++) - complexity += database.GetFolderFullPackSize(folderRefs[i].FolderIndex); + complexity += database->GetFolderFullPackSize(folderRefs[i].FolderIndex); for(i = 0; i < updateItems.Size(); i++) { const CUpdateItem &updateItem = updateItems[i]; @@ -571,34 +588,33 @@ HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database, { int folderIndex = folderRefs[i].FolderIndex; - RINOK(WriteRange(inStream, archive.Stream, - CUpdateRange(database.GetFolderStreamPos(folderIndex, 0), - database.GetFolderFullPackSize(folderIndex)), + RINOK(WriteRange(inStream, archive.SeqStream, + database->GetFolderStreamPos(folderIndex, 0), + database->GetFolderFullPackSize(folderIndex), updateCallback, complexity)); - const CFolder &folder = database.Folders[folderIndex]; - UINT32 startIndex = database.FolderStartPackStreamIndex[folderIndex]; - int j; - for (j = 0; j < folder.PackStreams.Size(); j++) + const CFolder &folder = database->Folders[folderIndex]; + CNum startIndex = database->FolderStartPackStreamIndex[folderIndex]; + for (int j = 0; j < folder.PackStreams.Size(); j++) { - newDatabase.PackSizes.Add(database.PackSizes[startIndex + j]); + newDatabase.PackSizes.Add(database->PackSizes[startIndex + j]); // newDatabase.PackCRCsDefined.Add(database.PackCRCsDefined[startIndex + j]); // newDatabase.PackCRCs.Add(database.PackCRCs[startIndex + j]); } newDatabase.Folders.Add(folder); - UINT64 numUnPackStreams = database.NumUnPackStreamsVector[folderIndex]; + CNum numUnPackStreams = database->NumUnPackStreamsVector[folderIndex]; newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams); - UINT64 indexInFolder = 0; - for (j = database.FolderStartFileIndex[folderIndex]; - indexInFolder < numUnPackStreams; j++) + CNum indexInFolder = 0; + for (CNum fi = database->FolderStartFileIndex[folderIndex]; + indexInFolder < numUnPackStreams; fi++) { - CFileItem file = database.Files[j]; + CFileItem file = database->Files[fi]; if (file.HasStream) { indexInFolder++; - int updateIndex = fileIndexToUpdateIndexMap[j]; + int updateIndex = fileIndexToUpdateIndexMap[fi]; if (updateIndex >= 0) { const CUpdateItem &updateItem = updateItems[updateIndex]; @@ -608,7 +624,7 @@ HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database, FromUpdateItemToFileItem(updateItem, file2); file2.UnPackSize = file.UnPackSize; file2.FileCRC = file.FileCRC; - file2.FileCRCIsDefined = file.FileCRCIsDefined; + file2.IsFileCRCDefined = file.IsFileCRCDefined; file2.HasStream = file.HasStream; file = file2; } @@ -622,7 +638,8 @@ HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database, // Compress New Files CObjectVector<CSolidGroup> groups; - SplitFilesToGroups(method, useFilters, maxFilter, updateItems, groups); + SplitFilesToGroups(*options.Method, options.UseFilters, options.MaxFilter, + updateItems, groups); for (int groupIndex = 0; groupIndex < groups.Size(); groupIndex++) { @@ -637,14 +654,14 @@ HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database, updateItems[group.Indices[i]], numSolidFiles > 1)); qsort(&refItems.Front(), refItems.Size(), sizeof(refItems[0]), CompareUpdateItems); - CRecordVector<UINT32> indices; + CRecordVector<UInt32> indices; indices.Reserve(numFiles); - int startFileIndexInDatabase = newDatabase.Files.Size(); for (i = 0; i < numFiles; i++) { - UINT32 index = refItems[i].Index; + UInt32 index = refItems[i].Index; indices.Add(index); + /* const CUpdateItem &updateItem = updateItems[index]; CFileItem file; if (updateItem.NewProperties) @@ -654,13 +671,14 @@ HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database, if (file.IsAnti || file.IsDirectory) return E_FAIL; newDatabase.Files.Add(file); + */ } CEncoder encoder(group.Method); for (i = 0; i < numFiles;) { - UINT64 totalSize = 0; + UInt64 totalSize = 0; int numSubFiles; UString prevExtension; for (numSubFiles = 0; i + numSubFiles < numFiles && @@ -668,9 +686,9 @@ HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database, { const CUpdateItem &updateItem = updateItems[indices[i + numSubFiles]]; totalSize += updateItem.Size; - if (totalSize > numSolidBytes) + if (totalSize > options.NumSolidBytes) break; - if (solidExtension) + if (options.SolidExtension) { UString ext = updateItem.GetExtension(); if (numSubFiles == 0) @@ -696,42 +714,296 @@ HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database, localCompressProgressSpec->Init(localProgress, &complexity, NULL); RINOK(encoder.Encode(solidInStream, NULL, folderItem, - archive.Stream, newDatabase.PackSizes, compressProgress)); + archive.SeqStream, newDatabase.PackSizes, compressProgress)); // for() // newDatabase.PackCRCsDefined.Add(false); // newDatabase.PackCRCs.Add(0); newDatabase.Folders.Add(folderItem); - UINT32 numUnPackStreams = 0; + CNum numUnPackStreams = 0; for (int subIndex = 0; subIndex < numSubFiles; subIndex++) { + const CUpdateItem &updateItem = updateItems[indices[i + subIndex]]; + CFileItem file; + if (updateItem.NewProperties) + FromUpdateItemToFileItem(updateItem, file); + else + file = database->Files[updateItem.IndexInArchive]; + if (file.IsAnti || file.IsDirectory) + return E_FAIL; + + /* CFileItem &file = newDatabase.Files[ - startFileIndexInDatabase + i + subIndex]; + startFileIndexInDatabase + i + subIndex]; + */ + if (!inStreamSpec->Processed[subIndex]) + { + continue; + // file.Name += L".locked"; + } + file.FileCRC = inStreamSpec->CRCs[subIndex]; file.UnPackSize = inStreamSpec->Sizes[subIndex]; if (file.UnPackSize != 0) { - file.FileCRCIsDefined = true; + file.IsFileCRCDefined = true; file.HasStream = true; numUnPackStreams++; complexity += file.UnPackSize; } else { - file.FileCRCIsDefined = false; + file.IsFileCRCDefined = false; file.HasStream = false; } + newDatabase.Files.Add(file); } + // numUnPackStreams = 0 is very bad case for locked files + // v3.13 doesn't understand it. newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams); i += numSubFiles; } } + /* if (newDatabase.Files.Size() != updateItems.Size()) return E_FAIL; + */ + + return archive.WriteDatabase(newDatabase, options.HeaderMethod, + options.UseAdditionalHeaderStreams, options.CompressMainHeader); +} + +static HRESULT WriteVolumeHeader(COutArchive &archive, CFileItem &file, const CUpdateOptions &options) +{ + CAltCoderInfo altCoder; + altCoder.MethodID.IDSize = 1; + altCoder.MethodID.ID[0] = 0; + CCoderInfo coder; + coder.NumInStreams = coder.NumOutStreams = 1; + coder.AltCoders.Add(altCoder); + + CFolder folder; + folder.Coders.Add(coder); + folder.PackStreams.Add(0); + + CNum numUnPackStreams = 0; + if (file.UnPackSize != 0) + { + file.IsFileCRCDefined = true; + file.HasStream = true; + numUnPackStreams++; + } + else + { + throw 1; + file.IsFileCRCDefined = false; + file.HasStream = false; + } + folder.UnPackSizes.Add(file.UnPackSize); + + CArchiveDatabase newDatabase; + newDatabase.Files.Add(file); + newDatabase.Folders.Add(folder); + newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams); + newDatabase.PackSizes.Add(file.UnPackSize); + newDatabase.PackCRCsDefined.Add(false); + newDatabase.PackCRCs.Add(file.FileCRC); + + return archive.WriteDatabase(newDatabase, + options.HeaderMethod, + false, + false); +} + +#ifdef _7Z_VOL +HRESULT UpdateVolume( + IInStream *inStream, + const CArchiveDatabaseEx *database, + CObjectVector<CUpdateItem> &updateItems, + ISequentialOutStream *seqOutStream, + IArchiveUpdateCallback *updateCallback, + const CUpdateOptions &options) +{ + if (updateItems.Size() != 1) + return E_NOTIMPL; + + CMyComPtr<IArchiveUpdateCallback2> volumeCallback; + RINOK(updateCallback->QueryInterface(IID_IArchiveUpdateCallback2, (void **)&volumeCallback)); + if (!volumeCallback) + return E_NOTIMPL; + + CMyComPtr<ISequentialInStream> fileStream; + HRESULT result = updateCallback->GetStream(0, &fileStream); + if (result != S_OK && result != S_FALSE) + return result; + if (result == S_FALSE) + return E_FAIL; + + CFileItem file; + + const CUpdateItem &updateItem = updateItems[0]; + if (updateItem.NewProperties) + FromUpdateItemToFileItem(updateItem, file); + else + file = database->Files[updateItem.IndexInArchive]; + if (file.IsAnti || file.IsDirectory) + return E_FAIL; + + UInt64 complexity = 0; + file.IsStartPosDefined = true; + file.StartPos = 0; + for (UInt64 volumeIndex = 0; true; volumeIndex++) + { + UInt64 volSize; + RINOK(volumeCallback->GetVolumeSize(volumeIndex, &volSize)); + UInt64 pureSize = COutArchive::GetVolPureSize(volSize, file.Name.Length(), true); + CMyComPtr<ISequentialOutStream> volumeStream; + RINOK(volumeCallback->GetVolumeStream(volumeIndex, &volumeStream)); + + COutArchive archive; + archive.Create(volumeStream, true); + RINOK(archive.SkeepPrefixArchiveHeader()); + + CSequentialInStreamWithCRC *inCrcStreamSpec = new CSequentialInStreamWithCRC; + CMyComPtr<ISequentialInStream> inCrcStream = inCrcStreamSpec; + inCrcStreamSpec->Init(fileStream); + + RINOK(WriteRange(inCrcStream, volumeStream, pureSize, + updateCallback, complexity)); + file.UnPackSize = inCrcStreamSpec->GetSize(); + if (file.UnPackSize == 0) + break; + file.FileCRC = inCrcStreamSpec->GetCRC(); + RINOK(WriteVolumeHeader(archive, file, options)); + file.StartPos += file.UnPackSize; + if (file.UnPackSize < pureSize) + break; + } + return S_OK; +} + +class COutVolumeStream: + public ISequentialOutStream, + public CMyUnknownImp +{ + int _volIndex; + UInt64 _volSize; + UInt64 _curPos; + CMyComPtr<ISequentialOutStream> _volumeStream; + COutArchive _archive; + CCRC _crc; + +public: + MY_UNKNOWN_IMP + + CFileItem _file; + CUpdateOptions _options; + CMyComPtr<IArchiveUpdateCallback2> VolumeCallback; + void Init(IArchiveUpdateCallback2 *volumeCallback, + const UString &name) + { + _file.Name = name; + _file.IsStartPosDefined = true; + _file.StartPos = 0; + + VolumeCallback = volumeCallback; + _volIndex = 0; + _volSize = 0; + } + + HRESULT Flush(); + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +HRESULT COutVolumeStream::Flush() +{ + if (_volumeStream) + { + _file.UnPackSize = _curPos; + _file.FileCRC = _crc.GetDigest(); + RINOK(WriteVolumeHeader(_archive, _file, _options)); + _archive.Close(); + _volumeStream.Release(); + _file.StartPos += _file.UnPackSize; + } + return S_OK; +} - return archive.WriteDatabase(newDatabase, headerMethod, - useAdditionalHeaderStreams, compressMainHeader); +STDMETHODIMP COutVolumeStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + if(processedSize != NULL) + *processedSize = 0; + while(size > 0) + { + if (!_volumeStream) + { + RINOK(VolumeCallback->GetVolumeSize(_volIndex, &_volSize)); + RINOK(VolumeCallback->GetVolumeStream(_volIndex, &_volumeStream)); + _volIndex++; + _curPos = 0; + _archive.Create(_volumeStream, true); + RINOK(_archive.SkeepPrefixArchiveHeader()); + _crc.Init(); + continue; + } + UInt64 pureSize = COutArchive::GetVolPureSize(_volSize, _file.Name.Length()); + UInt32 curSize = (UInt32)MyMin(UInt64(size), pureSize - _curPos); + + _crc.Update(data, curSize); + UInt32 realProcessed; + RINOK(_volumeStream->Write(data, curSize, &realProcessed)) + data = (void *)((Byte *)data + realProcessed); + size -= realProcessed; + if(processedSize != NULL) + *processedSize += realProcessed; + _curPos += realProcessed; + if (realProcessed != curSize) + return E_FAIL; + if (_curPos == pureSize) + { + RINOK(Flush()); + } + } + return S_OK; +} + +STDMETHODIMP COutVolumeStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize) +{ + return Write(data, size, processedSize); +} +#endif + +HRESULT Update( + IInStream *inStream, + const CArchiveDatabaseEx *database, + CObjectVector<CUpdateItem> &updateItems, + ISequentialOutStream *seqOutStream, + IArchiveUpdateCallback *updateCallback, + const CUpdateOptions &options) +{ + #ifdef _7Z_VOL + if (seqOutStream) + #endif + return Update2(inStream, database, updateItems, + seqOutStream, updateCallback, options); + #ifdef _7Z_VOL + if (options.VolumeMode) + return UpdateVolume(inStream, database, updateItems, + seqOutStream, updateCallback, options); + COutVolumeStream *volStreamSpec = new COutVolumeStream; + CMyComPtr<ISequentialOutStream> volStream = volStreamSpec; + CMyComPtr<IArchiveUpdateCallback2> volumeCallback; + RINOK(updateCallback->QueryInterface(IID_IArchiveUpdateCallback2, (void **)&volumeCallback)); + if (!volumeCallback) + return E_NOTIMPL; + volStreamSpec->Init(volumeCallback, L"a.7z"); + volStreamSpec->_options = options; + RINOK(Update2(inStream, database, updateItems, + volStream, updateCallback, options)); + return volStreamSpec->Flush(); + #endif } }} diff --git a/7zip/Archive/7z/7zUpdate.h b/7zip/Archive/7z/7zUpdate.h index d4561559..ab6cff4f 100755 --- a/7zip/Archive/7z/7zUpdate.h +++ b/7zip/Archive/7z/7zUpdate.h @@ -1,7 +1,5 @@ // 7zUpdate.h -#pragma once - #ifndef __7Z_UPDATE_H #define __7Z_UPDATE_H @@ -13,14 +11,6 @@ namespace NArchive { namespace N7z { -struct CUpdateRange -{ - UINT64 Position; - UINT64 Size; - CUpdateRange() {}; - CUpdateRange(UINT64 position, UINT64 size): Position(position), Size(size) {}; -}; - struct CUpdateItem { bool NewData; @@ -28,11 +18,11 @@ struct CUpdateItem int IndexInArchive; int IndexInClient; - UINT32 Attributes; + UInt32 Attributes; FILETIME CreationTime; FILETIME LastWriteTime; - UINT64 Size; + UInt64 Size; UString Name; bool IsAnti; @@ -52,21 +42,28 @@ struct CUpdateItem UString GetExtension() const; }; -HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database, - CObjectVector<CUpdateItem> &updateItems, - IOutStream *outStream, +struct CUpdateOptions +{ + const CCompressionMethodMode *Method; + const CCompressionMethodMode *HeaderMethod; + bool UseFilters; + bool MaxFilter; + bool UseAdditionalHeaderStreams; + bool CompressMainHeader; + UInt64 NumSolidFiles; + UInt64 NumSolidBytes; + bool SolidExtension; + bool RemoveSfxBlock; + bool VolumeMode; +}; + +HRESULT Update( IInStream *inStream, - CInArchiveInfo *inArchiveInfo, - const CCompressionMethodMode &method, - const CCompressionMethodMode *headerMethod, - bool useFilters, - bool maxFilter, - bool useAdditionalHeaderStreams, - bool compressMainHeader, + const CArchiveDatabaseEx *database, + CObjectVector<CUpdateItem> &updateItems, + ISequentialOutStream *seqOutStream, IArchiveUpdateCallback *updateCallback, - UINT64 numSolidFiles, UINT64 numSolidBytes, bool solidExtension, - bool removeSfxBlock); - + const CUpdateOptions &options); }} #endif diff --git a/7zip/Archive/7z/DllExports.cpp b/7zip/Archive/7z/DllExports.cpp index 881443a9..812d19d3 100755 --- a/7zip/Archive/7z/DllExports.cpp +++ b/7zip/Archive/7z/DllExports.cpp @@ -2,13 +2,12 @@ #include "StdAfx.h" -#include <initguid.h> +#include "../../../Common/MyInitGuid.h" +#include "../../../Common/ComTry.h" -#include "7zHandler.h" #include "../../ICoder.h" -#include "../../IPassword.h" -#include "../../../Common/NewHandler.h" -#include "../../../Common/ComTry.h" + +#include "7zHandler.h" #ifndef EXCLUDE_COM // {23170F69-40C1-278B-06F1-070100000100} @@ -38,22 +37,18 @@ STDAPI CreateObject( *outObject = 0; if (*classID != NArchive::N7z::CLSID_CFormat7z) return CLASS_E_CLASSNOTAVAILABLE; - int needIn = *interfaceID == IID_IInArchive; - int needOut = *interfaceID == IID_IOutArchive; - if (needIn || needOut) + if (*interfaceID == IID_IInArchive) { - NArchive::N7z::CHandler *temp = new NArchive::N7z::CHandler; - if (needIn) - { - CMyComPtr<IInArchive> inArchive = (IInArchive *)temp; - *outObject = inArchive.Detach(); - } - else - { - CMyComPtr<IOutArchive> outArchive = (IOutArchive *)temp; - *outObject = outArchive.Detach(); - } + CMyComPtr<IInArchive> inArchive = new NArchive::N7z::CHandler; + *outObject = inArchive.Detach(); + } + #ifndef EXTRACT_ONLY + else if (*interfaceID == IID_IOutArchive) + { + CMyComPtr<IOutArchive> outArchive = new NArchive::N7z::CHandler; + *outObject = outArchive.Detach(); } + #endif else return E_NOINTERFACE; COM_TRY_END @@ -84,6 +79,13 @@ STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) case NArchive::kKeepName: propVariant = false; break; + case NArchive::kStartSignature: + { + if ((value->bstrVal = ::SysAllocStringByteLen((const char *)NArchive::N7z::kSignature, + NArchive::N7z::kSignatureSize)) != 0) + value->vt = VT_BSTR; + return S_OK; + } } propVariant.Detach(value); return S_OK; diff --git a/7zip/Archive/7z/StdAfx.cpp b/7zip/Archive/7z/StdAfx.cpp index 2550270c..d0feea85 100755 --- a/7zip/Archive/7z/StdAfx.cpp +++ b/7zip/Archive/7z/StdAfx.cpp @@ -1,3 +1,3 @@ // StdAfx.cpp -#include "stdafx.h" +#include "StdAfx.h" diff --git a/7zip/Archive/7z/StdAfx.h b/7zip/Archive/7z/StdAfx.h index 32888020..e7fb6986 100755 --- a/7zip/Archive/7z/StdAfx.h +++ b/7zip/Archive/7z/StdAfx.h @@ -1,23 +1,8 @@ -// stdafx.h - +// StdAfx.h + #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> - -/* -#include <stdio.h> -#include <tchar.h> -#include <atlcom.h> -#include <shlobj.h> -#include <shlguid.h> - -#include <memory> -#include <new.h> - -#include <time.h> -*/ -#include <vector> -#include <memory> +#include "../../../Common/MyWindows.h" -#endif +#endif diff --git a/7zip/Archive/7z/resource.rc b/7zip/Archive/7z/resource.rc index 2317ad53..a6598c57 100755 --- a/7zip/Archive/7z/resource.rc +++ b/7zip/Archive/7z/resource.rc @@ -75,8 +75,8 @@ IDI_ICON1 ICON DISCARDABLE "7z.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,12,0,0 - PRODUCTVERSION 3,12,0,0 + FILEVERSION 4,20,0,0 + PRODUCTVERSION 4,20,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -94,14 +94,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Igor Pavlov\0" VALUE "FileDescription", "7z Plugin for 7-Zip\0" - VALUE "FileVersion", "3, 12, 0, 0\0" + VALUE "FileVersion", "4, 20, 0, 0\0" VALUE "InternalName", "7z\0" - VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "7z.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "7-Zip\0" - VALUE "ProductVersion", "3, 12, 0, 0\0" + VALUE "ProductVersion", "4, 20, 0, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/7zip/Archive/7z_C/7zAlloc.c b/7zip/Archive/7z_C/7zAlloc.c new file mode 100755 index 00000000..91c749ad --- /dev/null +++ b/7zip/Archive/7z_C/7zAlloc.c @@ -0,0 +1,55 @@ +/* 7zAlloc.c */ + +#include <stdlib.h> +#include "7zAlloc.h" + +/* #define _SZ_ALLOC_DEBUG */ +/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */ + +#ifdef _SZ_ALLOC_DEBUG +#include <stdio.h> +int g_allocCount = 0; +int g_allocCountTemp = 0; +#endif + +void *SzAlloc(size_t size) +{ + #ifdef _SZ_ALLOC_DEBUG + fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount); + g_allocCount++; + #endif + return malloc(size); +} + +void SzFree(void *address) +{ + #ifdef _SZ_ALLOC_DEBUG + if (address != 0) + { + g_allocCount--; + fprintf(stderr, "\nFree; count = %10d", g_allocCount); + } + #endif + free(address); +} + +void *SzAllocTemp(size_t size) +{ + #ifdef _SZ_ALLOC_DEBUG + fprintf(stderr, "\nAlloc_temp %10d bytes; count = %10d", size, g_allocCountTemp); + g_allocCountTemp++; + #endif + return malloc(size); +} + +void SzFreeTemp(void *address) +{ + #ifdef _SZ_ALLOC_DEBUG + if (address != 0) + { + g_allocCountTemp--; + fprintf(stderr, "\nFree_temp; count = %10d", g_allocCountTemp); + } + #endif + free(address); +} diff --git a/7zip/Archive/7z_C/7zAlloc.h b/7zip/Archive/7z_C/7zAlloc.h new file mode 100755 index 00000000..4ca4170c --- /dev/null +++ b/7zip/Archive/7z_C/7zAlloc.h @@ -0,0 +1,20 @@ +/* 7zAlloc.h */ + +#ifndef __7Z_ALLOC_H +#define __7Z_ALLOC_H + +#include <stddef.h> + +typedef struct _ISzAlloc +{ + void *(*Alloc)(size_t size); + void (*Free)(void *address); /* address can be 0 */ +} ISzAlloc; + +void *SzAlloc(size_t size); +void SzFree(void *address); + +void *SzAllocTemp(size_t size); +void SzFreeTemp(void *address); + +#endif diff --git a/7zip/Archive/7z_C/7zBuffer.c b/7zip/Archive/7z_C/7zBuffer.c new file mode 100755 index 00000000..365fb646 --- /dev/null +++ b/7zip/Archive/7z_C/7zBuffer.c @@ -0,0 +1,24 @@ +/* 7zBuffer.c */ + +#include "7zBuffer.h" +#include "7zAlloc.h" + +void SzByteBufferInit(CSzByteBuffer *buffer) +{ + buffer->Capacity = 0; + buffer->Items = 0; +} + +int SzByteBufferCreate(CSzByteBuffer *buffer, size_t newCapacity, void * (*allocFunc)(size_t size)) +{ + buffer->Capacity = newCapacity; + buffer->Items = (Byte *)allocFunc(newCapacity); + return (buffer->Items != 0); +} + +void SzByteBufferFree(CSzByteBuffer *buffer, void (*freeFunc)(void *)) +{ + freeFunc(buffer->Items); + buffer->Items = 0; + buffer->Capacity = 0; +} diff --git a/7zip/Archive/7z_C/7zBuffer.h b/7zip/Archive/7z_C/7zBuffer.h new file mode 100755 index 00000000..17e59060 --- /dev/null +++ b/7zip/Archive/7z_C/7zBuffer.h @@ -0,0 +1,19 @@ +/* 7zBuffer.h */ + +#ifndef __7Z_BUFFER_H +#define __7Z_BUFFER_H + +#include <stddef.h> +#include "7zTypes.h" + +typedef struct _CSzByteBuffer +{ + size_t Capacity; + Byte *Items; +}CSzByteBuffer; + +void SzByteBufferInit(CSzByteBuffer *buffer); +int SzByteBufferCreate(CSzByteBuffer *buffer, size_t newCapacity, void * (*allocFunc)(size_t size)); +void SzByteBufferFree(CSzByteBuffer *buffer, void (*freeFunc)(void *)); + +#endif diff --git a/7zip/Archive/7z_C/7zCrc.c b/7zip/Archive/7z_C/7zCrc.c new file mode 100755 index 00000000..97738404 --- /dev/null +++ b/7zip/Archive/7z_C/7zCrc.c @@ -0,0 +1,76 @@ +/* 7zCrc.c */ + +#include "7zCrc.h" + +#define kCrcPoly 0xEDB88320 + +UInt32 g_CrcTable[256]; + +void InitCrcTable() +{ + UInt32 i; + for (i = 0; i < 256; i++) + { + UInt32 r = i; + int j; + for (j = 0; j < 8; j++) + if (r & 1) + r = (r >> 1) ^ kCrcPoly; + else + r >>= 1; + g_CrcTable[i] = r; + } +} + +void CrcInit(UInt32 *crc) { *crc = 0xFFFFFFFF; } +UInt32 CrcGetDigest(UInt32 *crc) { return *crc ^ 0xFFFFFFFF; } + +void CrcUpdateByte(UInt32 *crc, Byte b) +{ + *crc = g_CrcTable[((Byte)(*crc)) ^ b] ^ (*crc >> 8); +} + +void CrcUpdateUInt16(UInt32 *crc, UInt16 v) +{ + CrcUpdateByte(crc, (Byte)v); + CrcUpdateByte(crc, (Byte)(v >> 8)); +} + +void CrcUpdateUInt32(UInt32 *crc, UInt32 v) +{ + int i; + for (i = 0; i < 4; i++) + CrcUpdateByte(crc, (Byte)(v >> (8 * i))); +} + +void CrcUpdateUInt64(UInt32 *crc, UInt64 v) +{ + int i; + for (i = 0; i < 8; i++) + { + CrcUpdateByte(crc, (Byte)(v)); + v >>= 8; + } +} + +void CrcUpdate(UInt32 *crc, const void *data, size_t size) +{ + UInt32 v = *crc; + const Byte *p = (const Byte *)data; + for (; size > 0 ; size--, p++) + v = g_CrcTable[((Byte)(v)) ^ *p] ^ (v >> 8); + *crc = v; +} + +UInt32 CrcCalculateDigest(const void *data, size_t size) +{ + UInt32 crc; + CrcInit(&crc); + CrcUpdate(&crc, data, size); + return CrcGetDigest(&crc); +} + +int CrcVerifyDigest(UInt32 digest, const void *data, size_t size) +{ + return (CrcCalculateDigest(data, size) == digest); +} diff --git a/7zip/Archive/7z_C/7zCrc.h b/7zip/Archive/7z_C/7zCrc.h new file mode 100755 index 00000000..adcc563a --- /dev/null +++ b/7zip/Archive/7z_C/7zCrc.h @@ -0,0 +1,24 @@ +/* 7zCrc.h */ + +#ifndef __7Z_CRC_H +#define __7Z_CRC_H + +#include <stddef.h> + +#include "7zTypes.h" + +extern UInt32 g_CrcTable[256]; +void InitCrcTable(); + +void CrcInit(UInt32 *crc); +UInt32 CrcGetDigest(UInt32 *crc); +void CrcUpdateByte(UInt32 *crc, Byte v); +void CrcUpdateUInt16(UInt32 *crc, UInt16 v); +void CrcUpdateUInt32(UInt32 *crc, UInt32 v); +void CrcUpdateUInt64(UInt32 *crc, UInt64 v); +void CrcUpdate(UInt32 *crc, const void *data, size_t size); + +UInt32 CrcCalculateDigest(const void *data, size_t size); +int CrcVerifyDigest(UInt32 digest, const void *data, size_t size); + +#endif diff --git a/7zip/Archive/7z_C/7zDecode.c b/7zip/Archive/7z_C/7zDecode.c new file mode 100755 index 00000000..23c23f82 --- /dev/null +++ b/7zip/Archive/7z_C/7zDecode.c @@ -0,0 +1,144 @@ +/* 7zDecode.c */ + +#include "7zDecode.h" +#ifdef _SZ_ONE_DIRECTORY +#include "LzmaDecode.h" +#else +#include "../../Compress/LZMA_C/LzmaDecode.h" +#endif + +CMethodID k_Copy = { { 0x0 }, 1 }; +CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 }; + +#ifdef _LZMA_IN_CB + +typedef struct _CLzmaInCallbackImp +{ + ILzmaInCallback InCallback; + ISzInStream *InStream; + size_t Size; +} CLzmaInCallbackImp; + +int LzmaReadImp(void *object, unsigned char **buffer, UInt32 *size) +{ + CLzmaInCallbackImp *cb = (CLzmaInCallbackImp *)object; + size_t processedSize; + SZ_RESULT res; + *size = 0; + res = cb->InStream->Read((void *)cb->InStream, (void **)buffer, cb->Size, &processedSize); + *size = (UInt32)processedSize; + if (processedSize > cb->Size) + return (int)SZE_FAIL; + cb->Size -= processedSize; + if (res == SZ_OK) + return 0; + return (int)res; +} + +#endif + +SZ_RESULT SzDecode(CFileSize *packSizes, CFolder *folder, + #ifdef _LZMA_IN_CB + ISzInStream *inStream, + #else + Byte *inBuffer, + #endif + Byte *outBuffer, size_t outSize, + size_t *outSizeProcessed, ISzAlloc *allocMain) +{ + UInt32 si; + size_t inSize = 0; + CCoderInfo *coder; + if (folder->NumPackStreams != 1) + return SZE_NOTIMPL; + if (folder->NumCoders != 1) + return SZE_NOTIMPL; + coder = folder->Coders; + *outSizeProcessed = 0; + + for (si = 0; si < folder->NumPackStreams; si++) + inSize += (size_t)packSizes[si]; + + if (AreMethodsEqual(&coder->MethodID, &k_Copy)) + { + size_t i; + if (inSize != outSize) + return SZE_DATA_ERROR; + #ifdef _LZMA_IN_CB + for (i = 0; i < inSize;) + { + size_t j; + Byte *inBuffer; + size_t bufferSize; + RINOK(inStream->Read((void *)inStream, (void **)&inBuffer, inSize - i, &bufferSize)); + if (bufferSize == 0) + return SZE_DATA_ERROR; + if (bufferSize > inSize - i) + return SZE_FAIL; + *outSizeProcessed += bufferSize; + for (j = 0; j < bufferSize && i < inSize; j++, i++) + outBuffer[i] = inBuffer[j]; + } + #else + for (i = 0; i < inSize; i++) + outBuffer[i] = inBuffer[i]; + *outSizeProcessed = inSize; + #endif + return SZ_OK; + } + + if (AreMethodsEqual(&coder->MethodID, &k_LZMA)) + { + #ifdef _LZMA_IN_CB + CLzmaInCallbackImp lzmaCallback; + #endif + + int lc, lp, pb; + size_t lzmaInternalSize; + void *lzmaInternalData; + int result; + UInt32 outSizeProcessedLoc; + + #ifdef _LZMA_IN_CB + lzmaCallback.Size = inSize; + lzmaCallback.InStream = inStream; + lzmaCallback.InCallback.Read = LzmaReadImp; + #endif + + if (coder->Properties.Capacity < 5) + return SZE_FAIL; + lc = (unsigned char)coder->Properties.Items[0]; + if (lc >= (9 * 5 * 5)) + return SZE_FAIL; + for (pb = 0; lc >= (9 * 5); pb++, lc -= (9 * 5)); + for (lp = 0; lc >= 9; lp++, lc -= 9); + + lzmaInternalSize = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp))) * sizeof(CProb); + lzmaInternalData = allocMain->Alloc(lzmaInternalSize); + if (lzmaInternalData == 0) + return SZE_OUTOFMEMORY; + + result = LzmaDecode((Byte *)lzmaInternalData, (UInt32)lzmaInternalSize, + lc, lp, pb, + #ifdef _LZMA_IN_CB + &lzmaCallback.InCallback, + #else + inBuffer, (UInt32)inSize, + #endif + outBuffer, (UInt32)outSize, + &outSizeProcessedLoc); + *outSizeProcessed = (size_t)outSizeProcessedLoc; + allocMain->Free(lzmaInternalData); + /* + NOT_ENOUGH_MEM error is impossible for this code + if (result = LZMA_RESULT_NOT_ENOUGH_MEM) + return SZE_OUTOFMEMORY; + */ + if (result == LZMA_RESULT_DATA_ERROR) + return SZE_DATA_ERROR; + if (result != LZMA_RESULT_OK) + return SZE_FAIL; + return SZ_OK; + } + return SZE_NOTIMPL; +} diff --git a/7zip/Archive/7z_C/7zDecode.h b/7zip/Archive/7z_C/7zDecode.h new file mode 100755 index 00000000..d88129e8 --- /dev/null +++ b/7zip/Archive/7z_C/7zDecode.h @@ -0,0 +1,21 @@ +/* 7zDecode.h */ + +#ifndef __7Z_DECODE_H +#define __7Z_DECODE_H + +#include "7zItem.h" +#include "7zAlloc.h" +#ifdef _LZMA_IN_CB +#include "7zIn.h" +#endif + +SZ_RESULT SzDecode(CFileSize *packSizes, CFolder *folder, + #ifdef _LZMA_IN_CB + ISzInStream *stream, + #else + Byte *inBuffer, + #endif + Byte *outBuffer, size_t outSize, + size_t *outSizeProcessed, ISzAlloc *allocMain); + +#endif diff --git a/7zip/Archive/7z_C/7zExtract.c b/7zip/Archive/7z_C/7zExtract.c new file mode 100755 index 00000000..b269b15c --- /dev/null +++ b/7zip/Archive/7z_C/7zExtract.c @@ -0,0 +1,110 @@ +/* 7zExtract.c */ + +#include "7zExtract.h" +#include "7zDecode.h" +#include "7zCrc.h" + +SZ_RESULT SzExtract( + ISzInStream *inStream, + CArchiveDatabaseEx *db, + UInt32 fileIndex, + UInt32 *blockIndex, + Byte **outBuffer, + size_t *outBufferSize, + size_t *offset, + size_t *outSizeProcessed, + ISzAlloc *allocMain, + ISzAlloc *allocTemp) +{ + UInt32 folderIndex = db->FileIndexToFolderIndexMap[fileIndex]; + SZ_RESULT res = SZ_OK; + *offset = 0; + *outSizeProcessed = 0; + if (folderIndex == (UInt32)-1) + { + allocMain->Free(*outBuffer); + *blockIndex = folderIndex; + *outBuffer = 0; + *outBufferSize = 0; + return SZ_OK; + } + + if (*outBuffer == 0 || *blockIndex != folderIndex) + { + CFolder *folder = db->Database.Folders + folderIndex; + CFileSize unPackSize = SzFolderGetUnPackSize(folder); + #ifndef _LZMA_IN_CB + CFileSize packSize = SzArDbGetFolderFullPackSize(db, folderIndex); + Byte *inBuffer = 0; + size_t processedSize; + #endif + *blockIndex = folderIndex; + allocMain->Free(*outBuffer); + *outBuffer = 0; + + RINOK(inStream->Seek(inStream, SzArDbGetFolderStreamPos(db, folderIndex, 0))); + + #ifndef _LZMA_IN_CB + inBuffer = (Byte *)allocTemp->Alloc((size_t)packSize); + if (inBuffer == 0) + return SZE_OUTOFMEMORY; + res = inStream->Read(inStream, inBuffer, (size_t)packSize, &processedSize); + if (res == SZ_OK && processedSize != (size_t)packSize) + res = SZE_FAIL; + #endif + if (res == SZ_OK) + { + *outBuffer = (Byte *)allocMain->Alloc((size_t)unPackSize); + *outBufferSize = (size_t)unPackSize; + if (*outBuffer != 0) + { + size_t outRealSize; + res = SzDecode(db->Database.PackSizes + + db->FolderStartPackStreamIndex[folderIndex], folder, + #ifdef _LZMA_IN_CB + inStream, + #else + inBuffer, + #endif + *outBuffer, (size_t)unPackSize, &outRealSize, allocTemp); + if (res == SZ_OK) + { + if (outRealSize == (size_t)unPackSize) + { + if (folder->UnPackCRCDefined) + { + if (!CrcVerifyDigest(folder->UnPackCRC, *outBuffer, (size_t)unPackSize)) + res = SZE_FAIL; + } + } + else + res = SZE_FAIL; + } + } + else + res = SZE_OUTOFMEMORY; + } + #ifndef _LZMA_IN_CB + allocTemp->Free(inBuffer); + #endif + } + if (res == SZ_OK) + { + UInt32 i; + CFileItem *fileItem = db->Database.Files + fileIndex; + *offset = 0; + for(i = db->FolderStartFileIndex[folderIndex]; i < fileIndex; i++) + *offset += (UInt32)db->Database.Files[i].Size; + *outSizeProcessed = (size_t)fileItem->Size; + if (*offset + *outSizeProcessed > *outBufferSize) + return SZE_FAIL; + { + if (fileItem->IsFileCRCDefined) + { + if (!CrcVerifyDigest(fileItem->FileCRC, *outBuffer + *offset, *outSizeProcessed)) + res = SZE_FAIL; + } + } + } + return res; +} diff --git a/7zip/Archive/7z_C/7zExtract.h b/7zip/Archive/7z_C/7zExtract.h new file mode 100755 index 00000000..0dcec690 --- /dev/null +++ b/7zip/Archive/7z_C/7zExtract.h @@ -0,0 +1,20 @@ +/* 7zExtract.h */ + +#ifndef __7Z_EXTRACT_H +#define __7Z_EXTRACT_H + +#include "7zIn.h" + +SZ_RESULT SzExtract( + ISzInStream *inStream, + CArchiveDatabaseEx *db, + UInt32 fileIndex, /* index of file */ + UInt32 *blockIndex, /* index of solid block */ + Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */ + size_t *outBufferSize, /* buffer size for output buffer */ + size_t *offset, /* offset of stream for required file in *outBuffer */ + size_t *outSizeProcessed, /* size of file in *outBuffer */ + ISzAlloc *allocMain, + ISzAlloc *allocTemp); + +#endif diff --git a/7zip/Archive/7z_C/7zHeader.c b/7zip/Archive/7z_C/7zHeader.c new file mode 100755 index 00000000..3be4bc27 --- /dev/null +++ b/7zip/Archive/7z_C/7zHeader.c @@ -0,0 +1,5 @@ +/* 7zHeader.c */ + +#include "7zHeader.h" + +Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; diff --git a/7zip/Archive/7z_C/7zHeader.h b/7zip/Archive/7z_C/7zHeader.h new file mode 100755 index 00000000..0356aaa6 --- /dev/null +++ b/7zip/Archive/7z_C/7zHeader.h @@ -0,0 +1,55 @@ +/* 7zHeader.h */ + +#ifndef __7Z_HEADER_H +#define __7Z_HEADER_H + +#include "7zTypes.h" + +#define k7zSignatureSize 6 +extern Byte k7zSignature[k7zSignatureSize]; + +#define k7zMajorVersion 0 + +#define k7zStartHeaderSize 0x20 + +enum EIdEnum +{ + k7zIdEnd, + + k7zIdHeader, + + k7zIdArchiveProperties, + + k7zIdAdditionalStreamsInfo, + k7zIdMainStreamsInfo, + k7zIdFilesInfo, + + k7zIdPackInfo, + k7zIdUnPackInfo, + k7zIdSubStreamsInfo, + + k7zIdSize, + k7zIdCRC, + + k7zIdFolder, + + k7zIdCodersUnPackSize, + k7zIdNumUnPackStream, + + k7zIdEmptyStream, + k7zIdEmptyFile, + k7zIdAnti, + + k7zIdName, + k7zIdCreationTime, + k7zIdLastAccessTime, + k7zIdLastWriteTime, + k7zIdWinAttributes, + k7zIdComment, + + k7zIdEncodedHeader, + + k7zIdStartPos +}; + +#endif diff --git a/7zip/Archive/7z_C/7zIn.c b/7zip/Archive/7z_C/7zIn.c new file mode 100755 index 00000000..cc03ea40 --- /dev/null +++ b/7zip/Archive/7z_C/7zIn.c @@ -0,0 +1,1300 @@ +/* 7zIn.c */ + +#include "7zIn.h" +#include "7zCrc.h" +#include "7zDecode.h" + +#define RINOM(x) { if((x) == 0) return SZE_OUTOFMEMORY; } + +void SzArDbExInit(CArchiveDatabaseEx *db) +{ + SzArchiveDatabaseInit(&db->Database); + db->FolderStartPackStreamIndex = 0; + db->PackStreamStartPositions = 0; + db->FolderStartFileIndex = 0; + db->FileIndexToFolderIndexMap = 0; +} + +void SzArDbExFree(CArchiveDatabaseEx *db, void (*freeFunc)(void *)) +{ + freeFunc(db->FolderStartPackStreamIndex); + freeFunc(db->PackStreamStartPositions); + freeFunc(db->FolderStartFileIndex); + freeFunc(db->FileIndexToFolderIndexMap); + SzArchiveDatabaseFree(&db->Database, freeFunc); + SzArDbExInit(db); +} + +/* +CFileSize GetFolderPackStreamSize(int folderIndex, int streamIndex) const +{ + return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex]; +} + +CFileSize GetFilePackSize(int fileIndex) const +{ + int folderIndex = FileIndexToFolderIndexMap[fileIndex]; + if (folderIndex >= 0) + { + const CFolder &folderInfo = Folders[folderIndex]; + if (FolderStartFileIndex[folderIndex] == fileIndex) + return GetFolderFullPackSize(folderIndex); + } + return 0; +} +*/ + + +SZ_RESULT SzArDbExFill(CArchiveDatabaseEx *db, void * (*allocFunc)(size_t size)) +{ + UInt32 startPos = 0; + CFileSize startPosSize = 0; + UInt32 i; + UInt32 folderIndex = 0; + UInt32 indexInFolder = 0; + db->FolderStartPackStreamIndex = (UInt32 *)allocFunc(db->Database.NumFolders * sizeof(UInt32)); + RINOM(db->FolderStartPackStreamIndex); + for(i = 0; i < db->Database.NumFolders; i++) + { + db->FolderStartPackStreamIndex[i] = startPos; + startPos += db->Database.Folders[i].NumPackStreams; + } + + db->PackStreamStartPositions = (CFileSize *)allocFunc(db->Database.NumPackStreams * sizeof(CFileSize)); + RINOM(db->PackStreamStartPositions); + + for(i = 0; i < db->Database.NumPackStreams; i++) + { + db->PackStreamStartPositions[i] = startPosSize; + startPosSize += db->Database.PackSizes[i]; + } + + db->FolderStartFileIndex = (UInt32 *)allocFunc(db->Database.NumFolders * sizeof(UInt32)); + RINOM(db->FolderStartFileIndex); + + db->FileIndexToFolderIndexMap = (UInt32 *)allocFunc(db->Database.NumFiles * sizeof(UInt32)); + RINOM(db->FileIndexToFolderIndexMap); + + for (i = 0; i < db->Database.NumFiles; i++) + { + CFileItem *file = db->Database.Files + i; + int emptyStream = !file->HasStream; + if (emptyStream && indexInFolder == 0) + { + db->FileIndexToFolderIndexMap[i] = (UInt32)-1; + continue; + } + if (indexInFolder == 0) + { + /* + v3.13 incorrectly worked with empty folders + v4.07: Loop for skipping empty folders + */ + while(1) + { + if (folderIndex >= db->Database.NumFolders) + return SZE_ARCHIVE_ERROR; + db->FolderStartFileIndex[folderIndex] = i; + if (db->Database.Folders[folderIndex].NumUnPackStreams != 0) + break; + folderIndex++; + } + } + db->FileIndexToFolderIndexMap[i] = folderIndex; + if (emptyStream) + continue; + indexInFolder++; + if (indexInFolder >= db->Database.Folders[folderIndex].NumUnPackStreams) + { + folderIndex++; + indexInFolder = 0; + } + } + return SZ_OK; +} + + +CFileSize SzArDbGetFolderStreamPos(CArchiveDatabaseEx *db, UInt32 folderIndex, UInt32 indexInFolder) +{ + return db->ArchiveInfo.DataStartPosition + + db->PackStreamStartPositions[db->FolderStartPackStreamIndex[folderIndex] + indexInFolder]; +} + +CFileSize SzArDbGetFolderFullPackSize(CArchiveDatabaseEx *db, UInt32 folderIndex) +{ + UInt32 packStreamIndex = db->FolderStartPackStreamIndex[folderIndex]; + CFolder *folder = db->Database.Folders + folderIndex; + CFileSize size = 0; + UInt32 i; + for (i = 0; i < folder->NumPackStreams; i++) + size += db->Database.PackSizes[packStreamIndex + i]; + return size; +} + + +/* +SZ_RESULT SzReadTime(const CObjectVector<CSzByteBuffer> &dataVector, + CObjectVector<CFileItem> &files, UInt64 type) +{ + CBoolVector boolVector; + RINOK(ReadBoolVector2(files.Size(), boolVector)) + + CStreamSwitch streamSwitch; + RINOK(streamSwitch.Set(this, &dataVector)); + + for(int i = 0; i < files.Size(); i++) + { + CFileItem &file = files[i]; + CArchiveFileTime fileTime; + bool defined = boolVector[i]; + if (defined) + { + UInt32 low, high; + RINOK(SzReadUInt32(low)); + RINOK(SzReadUInt32(high)); + fileTime.dwLowDateTime = low; + fileTime.dwHighDateTime = high; + } + switch(type) + { + case k7zIdCreationTime: + file.IsCreationTimeDefined = defined; + if (defined) + file.CreationTime = fileTime; + break; + case k7zIdLastWriteTime: + file.IsLastWriteTimeDefined = defined; + if (defined) + file.LastWriteTime = fileTime; + break; + case k7zIdLastAccessTime: + file.IsLastAccessTimeDefined = defined; + if (defined) + file.LastAccessTime = fileTime; + break; + } + } + return SZ_OK; +} +*/ + +SZ_RESULT SafeReadDirect(ISzInStream *inStream, Byte *data, size_t size) +{ + #ifdef _LZMA_IN_CB + while (size > 0) + { + Byte *inBuffer; + size_t processedSize; + RINOK(inStream->Read(inStream, &inBuffer, size, &processedSize)); + if (processedSize == 0 || processedSize > size) + return SZE_FAIL; + size -= processedSize; + do + { + *data++ = *inBuffer++; + } + while (--processedSize != 0); + } + #else + size_t processedSize; + RINOK(inStream->Read(inStream, data, size, &processedSize)); + if (processedSize != size) + return SZE_FAIL; + #endif + return SZ_OK; +} + +SZ_RESULT SafeReadDirectByte(ISzInStream *inStream, Byte *data) +{ + return SafeReadDirect(inStream, data, 1); +} + +SZ_RESULT SafeReadDirectUInt32(ISzInStream *inStream, UInt32 *value) +{ + int i; + *value = 0; + for (i = 0; i < 4; i++) + { + Byte b; + RINOK(SafeReadDirectByte(inStream, &b)); + *value |= ((UInt32)b << (8 * i)); + } + return SZ_OK; +} + +SZ_RESULT SafeReadDirectUInt64(ISzInStream *inStream, UInt64 *value) +{ + int i; + *value = 0; + for (i = 0; i < 8; i++) + { + Byte b; + RINOK(SafeReadDirectByte(inStream, &b)); + *value |= ((UInt32)b << (8 * i)); + } + return SZ_OK; +} + +int TestSignatureCandidate(Byte *testBytes) +{ + size_t i; + for (i = 0; i < k7zSignatureSize; i++) + if (testBytes[i] != k7zSignature[i]) + return 0; + return 1; +} + +typedef struct _CSzState +{ + Byte *Data; + size_t Size; +}CSzData; + +SZ_RESULT SzReadByte(CSzData *sd, Byte *b) +{ + if (sd->Size == 0) + return SZE_ARCHIVE_ERROR; + sd->Size--; + *b = *sd->Data++; + return SZ_OK; +} + +SZ_RESULT SzReadBytes(CSzData *sd, Byte *data, size_t size) +{ + size_t i; + for (i = 0; i < size; i++) + { + RINOK(SzReadByte(sd, data + i)); + } + return SZ_OK; +} + +SZ_RESULT SzReadUInt32(CSzData *sd, UInt32 *value) +{ + int i; + *value = 0; + for (i = 0; i < 4; i++) + { + Byte b; + RINOK(SzReadByte(sd, &b)); + *value |= ((UInt32)(b) << (8 * i)); + } + return SZ_OK; +} + +SZ_RESULT SzReadNumber(CSzData *sd, UInt64 *value) +{ + Byte firstByte; + Byte mask = 0x80; + int i; + RINOK(SzReadByte(sd, &firstByte)); + *value = 0; + for (i = 0; i < 8; i++) + { + Byte b; + if ((firstByte & mask) == 0) + { + UInt64 highPart = firstByte & (mask - 1); + *value += (highPart << (8 * i)); + return SZ_OK; + } + RINOK(SzReadByte(sd, &b)); + *value |= ((UInt64)b << (8 * i)); + mask >>= 1; + } + return SZ_OK; +} + +SZ_RESULT SzReadSize(CSzData *sd, CFileSize *value) +{ + UInt64 value64; + RINOK(SzReadNumber(sd, &value64)); + *value = (CFileSize)value64; + return SZ_OK; +} + +SZ_RESULT SzReadNumber32(CSzData *sd, UInt32 *value) +{ + UInt64 value64; + RINOK(SzReadNumber(sd, &value64)); + if (value64 >= 0x80000000) + return SZE_NOTIMPL; + if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 2))) + return SZE_NOTIMPL; + *value = (UInt32)value64; + return SZ_OK; +} + +SZ_RESULT SzReadID(CSzData *sd, UInt64 *value) +{ + return SzReadNumber(sd, value); +} + +SZ_RESULT SzSkeepDataSize(CSzData *sd, UInt64 size) +{ + if (size > sd->Size) + return SZE_ARCHIVE_ERROR; + sd->Size -= (size_t)size; + sd->Data += (size_t)size; + return SZ_OK; +} + +SZ_RESULT SzSkeepData(CSzData *sd) +{ + UInt64 size; + RINOK(SzReadNumber(sd, &size)); + return SzSkeepDataSize(sd, size); +} + +SZ_RESULT SzReadArchiveProperties(CSzData *sd) +{ + while(1) + { + UInt64 type; + RINOK(SzReadID(sd, &type)); + if (type == k7zIdEnd) + break; + SzSkeepData(sd); + } + return SZ_OK; +} + +SZ_RESULT SzWaitAttribute(CSzData *sd, UInt64 attribute) +{ + while(1) + { + UInt64 type; + RINOK(SzReadID(sd, &type)); + if (type == attribute) + return SZ_OK; + if (type == k7zIdEnd) + return SZE_ARCHIVE_ERROR; + RINOK(SzSkeepData(sd)); + } +} + +SZ_RESULT SzReadBoolVector(CSzData *sd, size_t numItems, int **v, void * (*allocFunc)(size_t size)) +{ + Byte b = 0; + Byte mask = 0; + size_t i; + *v = (int *)allocFunc(numItems * sizeof(int)); + RINOM(*v); + for(i = 0; i < numItems; i++) + { + if (mask == 0) + { + RINOK(SzReadByte(sd, &b)); + mask = 0x80; + } + (*v)[i] = ((b & mask) != 0); + mask >>= 1; + } + return SZ_OK; +} + +SZ_RESULT SzReadBoolVector2(CSzData *sd, size_t numItems, int **v, void * (*allocFunc)(size_t size)) +{ + Byte allAreDefined; + size_t i; + RINOK(SzReadByte(sd, &allAreDefined)); + if (allAreDefined == 0) + return SzReadBoolVector(sd, numItems, v, allocFunc); + *v = (int *)allocFunc(numItems * sizeof(int)); + RINOM(*v); + for(i = 0; i < numItems; i++) + (*v)[i] = 1; + return SZ_OK; +} + +SZ_RESULT SzReadHashDigests( + CSzData *sd, + size_t numItems, + int **digestsDefined, + UInt32 **digests, + void * (*allocFunc)(size_t size)) +{ + size_t i; + RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, allocFunc)); + *digests = (UInt32 *)allocFunc(numItems * sizeof(UInt32)); + RINOM(*digests); + for(i = 0; i < numItems; i++) + if ((*digestsDefined)[i]) + { + RINOK(SzReadUInt32(sd, (*digests) + i)); + } + return SZ_OK; +} + +SZ_RESULT SzReadPackInfo( + CSzData *sd, + CFileSize *dataOffset, + UInt32 *numPackStreams, + CFileSize **packSizes, + int **packCRCsDefined, + UInt32 **packCRCs, + void * (*allocFunc)(size_t size)) +{ + UInt32 i; + RINOK(SzReadSize(sd, dataOffset)); + RINOK(SzReadNumber32(sd, numPackStreams)); + + RINOK(SzWaitAttribute(sd, k7zIdSize)); + *packSizes = (CFileSize *)allocFunc((size_t)*numPackStreams * sizeof(CFileSize)); + RINOM(*packSizes); + + for(i = 0; i < *numPackStreams; i++) + { + RINOK(SzReadSize(sd, (*packSizes) + i)); + } + + while(1) + { + UInt64 type; + RINOK(SzReadID(sd, &type)); + if (type == k7zIdEnd) + break; + if (type == k7zIdCRC) + { + RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, allocFunc)); + continue; + } + RINOK(SzSkeepData(sd)); + } + if (*packCRCsDefined == 0) + { + *packCRCsDefined = (int *)allocFunc((size_t)*numPackStreams * sizeof(int)); + RINOM(*packCRCsDefined); + *packCRCs = (UInt32 *)allocFunc((size_t)*numPackStreams * sizeof(UInt32)); + RINOM(*packCRCs); + for(i = 0; i < *numPackStreams; i++) + { + (*packCRCsDefined)[i] = 0; + (*packCRCs)[i] = 0; + } + } + return SZ_OK; +} + +SZ_RESULT SzReadSwitch(CSzData *sd) +{ + Byte external; + RINOK(SzReadByte(sd, &external)); + return (external == 0) ? SZ_OK: SZE_ARCHIVE_ERROR; +} + +SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)(size_t size)) +{ + UInt32 numCoders; + UInt32 numBindPairs; + UInt32 numPackedStreams; + UInt32 i; + UInt32 numInStreams = 0; + UInt32 numOutStreams = 0; + RINOK(SzReadNumber32(sd, &numCoders)); + folder->NumCoders = numCoders; + + folder->Coders = (CCoderInfo *)allocFunc((size_t)numCoders * sizeof(CCoderInfo)); + RINOM(folder->Coders); + for (i = 0; i < numCoders; i++) + SzCoderInfoInit(folder->Coders + i); + + for (i = 0; i < numCoders; i++) + { + Byte mainByte; + CCoderInfo *coder = folder->Coders + i; + { + RINOK(SzReadByte(sd, &mainByte)); + coder->MethodID.IDSize = (Byte)(mainByte & 0xF); + RINOK(SzReadBytes(sd, coder->MethodID.ID, coder->MethodID.IDSize)); + if ((mainByte & 0x10) != 0) + { + RINOK(SzReadNumber32(sd, &coder->NumInStreams)); + RINOK(SzReadNumber32(sd, &coder->NumOutStreams)); + } + else + { + coder->NumInStreams = 1; + coder->NumOutStreams = 1; + } + if ((mainByte & 0x20) != 0) + { + UInt64 propertiesSize = 0; + RINOK(SzReadNumber(sd, &propertiesSize)); + if (!SzByteBufferCreate(&coder->Properties, (size_t)propertiesSize, allocFunc)) + return SZE_OUTOFMEMORY; + RINOK(SzReadBytes(sd, coder->Properties.Items, (size_t)propertiesSize)); + } + } + while ((mainByte & 0x80) != 0) + { + RINOK(SzReadByte(sd, &mainByte)); + RINOK(SzSkeepDataSize(sd, (mainByte & 0xF))); + if ((mainByte & 0x10) != 0) + { + UInt32 n; + RINOK(SzReadNumber32(sd, &n)); + RINOK(SzReadNumber32(sd, &n)); + } + if ((mainByte & 0x20) != 0) + { + UInt64 propertiesSize = 0; + RINOK(SzReadNumber(sd, &propertiesSize)); + RINOK(SzSkeepDataSize(sd, propertiesSize)); + } + } + numInStreams += (UInt32)coder->NumInStreams; + numOutStreams += (UInt32)coder->NumOutStreams; + } + + numBindPairs = numOutStreams - 1; + folder->NumBindPairs = numBindPairs; + + folder->BindPairs = (CBindPair *)allocFunc((size_t)numBindPairs * sizeof(CBindPair)); + RINOM(folder->BindPairs); + + for (i = 0; i < numBindPairs; i++) + { + CBindPair *bindPair = folder->BindPairs + i;; + RINOK(SzReadNumber32(sd, &bindPair->InIndex)); + RINOK(SzReadNumber32(sd, &bindPair->OutIndex)); + } + + numPackedStreams = numInStreams - (UInt32)numBindPairs; + + folder->NumPackStreams = numPackedStreams; + folder->PackStreams = (UInt32 *)allocFunc((size_t)numPackedStreams * sizeof(UInt32)); + RINOM(folder->PackStreams); + + if (numPackedStreams == 1) + { + UInt32 j; + UInt32 pi = 0; + for (j = 0; j < numInStreams; j++) + if (SzFolderFindBindPairForInStream(folder, j) < 0) + { + folder->PackStreams[pi++] = j; + break; + } + } + else + for(i = 0; i < numPackedStreams; i++) + { + RINOK(SzReadNumber32(sd, folder->PackStreams + i)); + } + return SZ_OK; +} + +SZ_RESULT SzReadUnPackInfo( + CSzData *sd, + UInt32 *numFolders, + CFolder **folders, + void * (*allocFunc)(size_t size), + ISzAlloc *allocTemp) +{ + UInt32 i; + RINOK(SzWaitAttribute(sd, k7zIdFolder)); + RINOK(SzReadNumber32(sd, numFolders)); + { + RINOK(SzReadSwitch(sd)); + + *folders = (CFolder *)allocFunc((size_t)*numFolders * sizeof(CFolder)); + RINOM(*folders); + for(i = 0; i < *numFolders; i++) + SzFolderInit((*folders) + i); + + for(i = 0; i < *numFolders; i++) + { + RINOK(SzGetNextFolderItem(sd, (*folders) + i, allocFunc)); + } + } + + RINOK(SzWaitAttribute(sd, k7zIdCodersUnPackSize)); + + for(i = 0; i < *numFolders; i++) + { + UInt32 j; + CFolder *folder = (*folders) + i; + UInt32 numOutStreams = SzFolderGetNumOutStreams(folder); + + folder->UnPackSizes = (CFileSize *)allocFunc((size_t)numOutStreams * sizeof(CFileSize)); + RINOM(folder->UnPackSizes); + + for(j = 0; j < numOutStreams; j++) + { + RINOK(SzReadSize(sd, folder->UnPackSizes + j)); + } + } + + while(1) + { + UInt64 type; + RINOK(SzReadID(sd, &type)); + if (type == k7zIdEnd) + return SZ_OK; + if (type == k7zIdCRC) + { + SZ_RESULT res; + int *crcsDefined = 0; + UInt32 *crcs = 0; + res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp->Alloc); + if (res == SZ_OK) + { + for(i = 0; i < *numFolders; i++) + { + CFolder *folder = (*folders) + i; + folder->UnPackCRCDefined = crcsDefined[i]; + folder->UnPackCRC = crcs[i]; + } + } + allocTemp->Free(crcs); + allocTemp->Free(crcsDefined); + RINOK(res); + continue; + } + RINOK(SzSkeepData(sd)); + } +} + +SZ_RESULT SzReadSubStreamsInfo( + CSzData *sd, + UInt32 numFolders, + CFolder *folders, + UInt32 *numUnPackStreams, + CFileSize **unPackSizes, + int **digestsDefined, + UInt32 **digests, + void * (*allocFunc)(size_t size), + ISzAlloc *allocTemp) +{ + UInt64 type = 0; + UInt32 i; + UInt32 si = 0; + UInt32 numDigests = 0; + + for(i = 0; i < numFolders; i++) + folders[i].NumUnPackStreams = 1; + *numUnPackStreams = numFolders; + + while(1) + { + RINOK(SzReadID(sd, &type)); + if (type == k7zIdNumUnPackStream) + { + *numUnPackStreams = 0; + for(i = 0; i < numFolders; i++) + { + UInt32 numStreams; + RINOK(SzReadNumber32(sd, &numStreams)); + folders[i].NumUnPackStreams = numStreams; + *numUnPackStreams += numStreams; + } + continue; + } + if (type == k7zIdCRC || type == k7zIdSize) + break; + if (type == k7zIdEnd) + break; + RINOK(SzSkeepData(sd)); + } + + *unPackSizes = (CFileSize *)allocFunc((size_t)*numUnPackStreams * sizeof(CFileSize)); + RINOM(*unPackSizes); + + *digestsDefined = (int *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(int)); + RINOM(*digestsDefined); + + *digests = (UInt32 *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(UInt32)); + RINOM(*digests); + + for(i = 0; i < numFolders; i++) + { + /* + v3.13 incorrectly worked with empty folders + v4.07: we check that folder is empty + */ + CFileSize sum = 0; + UInt32 j; + UInt32 numSubstreams = folders[i].NumUnPackStreams; + if (numSubstreams == 0) + continue; + if (type == k7zIdSize) + for (j = 1; j < numSubstreams; j++) + { + CFileSize size; + RINOK(SzReadSize(sd, &size)); + (*unPackSizes)[si++] = size; + sum += size; + } + (*unPackSizes)[si++] = SzFolderGetUnPackSize(folders + i) - sum; + } + if (type == k7zIdSize) + { + RINOK(SzReadID(sd, &type)); + } + + for(i = 0; i < *numUnPackStreams; i++) + { + (*digestsDefined)[i] = 0; + (*digests)[i] = 0; + } + + + for(i = 0; i < numFolders; i++) + { + UInt32 numSubstreams = folders[i].NumUnPackStreams; + if (numSubstreams != 1 || !folders[i].UnPackCRCDefined) + numDigests += numSubstreams; + } + + + si = 0; + while(1) + { + if (type == k7zIdCRC) + { + int digestIndex = 0; + int *digestsDefined2 = 0; + UInt32 *digests2 = 0; + SZ_RESULT res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp->Alloc); + if (res == SZ_OK) + { + for (i = 0; i < numFolders; i++) + { + CFolder *folder = folders + i; + UInt32 numSubstreams = folder->NumUnPackStreams; + if (numSubstreams == 1 && folder->UnPackCRCDefined) + { + (*digestsDefined)[si] = 1; + (*digests)[si] = folder->UnPackCRC; + si++; + } + else + { + UInt32 j; + for (j = 0; j < numSubstreams; j++, digestIndex++) + { + (*digestsDefined)[si] = digestsDefined2[digestIndex]; + (*digests)[si] = digests2[digestIndex]; + si++; + } + } + } + } + allocTemp->Free(digestsDefined2); + allocTemp->Free(digests2); + RINOK(res); + } + else if (type == k7zIdEnd) + return SZ_OK; + else + { + RINOK(SzSkeepData(sd)); + } + RINOK(SzReadID(sd, &type)); + } +} + + +SZ_RESULT SzReadStreamsInfo( + CSzData *sd, + CFileSize *dataOffset, + CArchiveDatabase *db, + UInt32 *numUnPackStreams, + CFileSize **unPackSizes, + int **digestsDefined, + UInt32 **digests, + void * (*allocFunc)(size_t size), + ISzAlloc *allocTemp) +{ + while(1) + { + UInt64 type; + RINOK(SzReadID(sd, &type)); + switch(type) + { + case k7zIdEnd: + return SZ_OK; + case k7zIdPackInfo: + { + RINOK(SzReadPackInfo(sd, dataOffset, &db->NumPackStreams, + &db->PackSizes, &db->PackCRCsDefined, &db->PackCRCs, allocFunc)); + break; + } + case k7zIdUnPackInfo: + { + RINOK(SzReadUnPackInfo(sd, &db->NumFolders, &db->Folders, allocFunc, allocTemp)); + break; + } + case k7zIdSubStreamsInfo: + { + RINOK(SzReadSubStreamsInfo(sd, db->NumFolders, db->Folders, + numUnPackStreams, unPackSizes, digestsDefined, digests, allocFunc, allocTemp)); + break; + } + default: + return SZE_FAIL; + } + } +} + +Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; + +SZ_RESULT SzReadFileNames(CSzData *sd, UInt32 numFiles, CFileItem *files, + void * (*allocFunc)(size_t size)) +{ + UInt32 i; + for(i = 0; i < numFiles; i++) + { + UInt32 len = 0; + UInt32 pos = 0; + CFileItem *file = files + i; + while(pos + 2 <= sd->Size) + { + int numAdds; + UInt32 value = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8)); + pos += 2; + len++; + if (value == 0) + break; + if (value < 0x80) + continue; + if (value >= 0xD800 && value < 0xE000) + { + UInt32 c2; + if (value >= 0xDC00) + return SZE_ARCHIVE_ERROR; + if (pos + 2 > sd->Size) + return SZE_ARCHIVE_ERROR; + c2 = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8)); + pos += 2; + if (c2 < 0xDC00 || c2 >= 0xE000) + return SZE_ARCHIVE_ERROR; + value = ((value - 0xD800) << 10) | (c2 - 0xDC00); + } + for (numAdds = 1; numAdds < 5; numAdds++) + if (value < (((UInt32)1) << (numAdds * 5 + 6))) + break; + len += numAdds; + } + + file->Name = (char *)allocFunc((size_t)len * sizeof(char)); + RINOM(file->Name); + + len = 0; + while(2 <= sd->Size) + { + int numAdds; + UInt32 value = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8)); + SzSkeepDataSize(sd, 2); + if (value < 0x80) + { + file->Name[len++] = (char)value; + if (value == 0) + break; + continue; + } + if (value >= 0xD800 && value < 0xE000) + { + UInt32 c2 = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8)); + SzSkeepDataSize(sd, 2); + value = ((value - 0xD800) << 10) | (c2 - 0xDC00); + } + for (numAdds = 1; numAdds < 5; numAdds++) + if (value < (((UInt32)1) << (numAdds * 5 + 6))) + break; + file->Name[len++] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds))); + do + { + numAdds--; + file->Name[len++] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F)); + } + while(numAdds > 0); + + len += numAdds; + } + } + return SZ_OK; +} + +SZ_RESULT SzReadHeader2( + CSzData *sd, + CArchiveDatabaseEx *db, + CFileSize **unPackSizes, + int **digestsDefined, + UInt32 **digests, + ISzAlloc *allocMain, + ISzAlloc *allocTemp) +{ + UInt64 type; + UInt32 numUnPackStreams = 0; + UInt32 numFiles = 0; + CFileItem *files = 0; + UInt32 i; + + RINOK(SzReadID(sd, &type)); + + if (type == k7zIdArchiveProperties) + { + RINOK(SzReadArchiveProperties(sd)); + RINOK(SzReadID(sd, &type)); + } + + + if (type == k7zIdMainStreamsInfo) + { + RINOK(SzReadStreamsInfo(sd, + &db->ArchiveInfo.DataStartPosition, + &db->Database, + &numUnPackStreams, + unPackSizes, + digestsDefined, + digests, allocMain->Alloc, allocTemp)); + db->ArchiveInfo.DataStartPosition += db->ArchiveInfo.StartPositionAfterHeader; + RINOK(SzReadID(sd, &type)); + } + else + { + return SZE_NOTIMPL; + } + + if (type == k7zIdEnd) + return SZ_OK; + if (type != k7zIdFilesInfo) + return SZE_ARCHIVE_ERROR; + + RINOK(SzReadNumber32(sd, &numFiles)); + db->Database.NumFiles = numFiles; + + files = (CFileItem *)allocTemp->Alloc((size_t)numFiles * sizeof(CFileItem)); + RINOM(files); + db->Database.Files = files; + for(i = 0; i < numFiles; i++) + SzFileInit(files + i); + + /* + CBoolVector emptyStreamVector; + emptyStreamVector.Reserve((size_t)numFiles); + for(i = 0; i < numFiles; i++) + emptyStreamVector.Add(false); + CBoolVector emptyFileVector; + UInt32 numEmptyStreams = 0; + */ + + while(1) + { + UInt64 type; + UInt64 size; + RINOK(SzReadID(sd, &type)); + if (type == k7zIdEnd) + break; + RINOK(SzReadNumber(sd, &size)); + + switch(type) + { + case k7zIdName: + { + RINOK(SzReadSwitch(sd)); + RINOK(SzReadFileNames(sd, numFiles, files, allocMain->Alloc)) + break; + } + case k7zIdEmptyStream: + { + /* + RINOK(ReadBoolVector((UInt32)numFiles, emptyStreamVector)) + UInt32 i; + for (i = 0; i < (UInt32)emptyStreamVector.Size(); i++) + if (emptyStreamVector[i]) + numEmptyStreams++; + emptyFileVector.Reserve(numEmptyStreams); + antiFileVector.Reserve(numEmptyStreams); + for (i = 0; i < numEmptyStreams; i++) + { + emptyFileVector.Add(false); + antiFileVector.Add(false); + } + break; + */ + return SZE_NOTIMPL; + } + case k7zIdEmptyFile: + { + /* + RINOK(ReadBoolVector(numEmptyStreams, emptyFileVector)) + break; + */ + return SZE_NOTIMPL; + } + default: + { + RINOK(SzSkeepDataSize(sd, size)); + } + } + } + + /* + UInt32 emptyFileIndex = 0; + UInt32 sizeIndex = 0; + for(i = 0; i < numFiles; i++) + { + CFileItem *file = files + i; + file.HasStream = !emptyStreamVector[(UInt32)i]; + if(file.HasStream) + { + file.IsDirectory = false; + file.IsAnti = false; + file.UnPackSize = unPackSizes[sizeIndex]; + file.FileCRC = digests[sizeIndex]; + file.IsFileCRCDefined = digestsDefined[sizeIndex]; + sizeIndex++; + } + else + { + file.IsDirectory = !emptyFileVector[emptyFileIndex]; + file.IsAnti = antiFileVector[emptyFileIndex]; + emptyFileIndex++; + file.UnPackSize = 0; + file.IsFileCRCDefined = false; + } + } + */ + for(i = 0; i < numFiles; i++) + { + CFileItem *file = files + i; + file->Size = (*unPackSizes)[i]; + file->FileCRC = (*digests)[i]; + file->IsFileCRCDefined = (Byte)(*digestsDefined)[i]; + } + return SzArDbExFill(db, allocMain->Alloc); +} + +SZ_RESULT SzReadHeader( + CSzData *sd, + CArchiveDatabaseEx *db, + ISzAlloc *allocMain, + ISzAlloc *allocTemp) +{ + CFileSize *unPackSizes = 0; + int *digestsDefined = 0; + UInt32 *digests = 0; + SZ_RESULT res = SzReadHeader2(sd, db, + &unPackSizes, &digestsDefined, &digests, + allocMain, allocTemp); + allocTemp->Free(unPackSizes); + allocTemp->Free(digestsDefined); + allocTemp->Free(digests); + return res; +} + +SZ_RESULT SzReadAndDecodePackedStreams2( + ISzInStream *inStream, + CSzData *sd, + CSzByteBuffer *outBuffer, + CFileSize baseOffset, + CArchiveDatabase *db, + CFileSize **unPackSizes, + int **digestsDefined, + UInt32 **digests, + #ifndef _LZMA_IN_CB + Byte **inBuffer, + #endif + ISzAlloc *allocTemp) +{ + + UInt32 numUnPackStreams = 0; + CFileSize dataStartPos; + CFolder *folder; + #ifndef _LZMA_IN_CB + CFileSize packSize = 0; + UInt32 i = 0; + #endif + CFileSize unPackSize; + size_t outRealSize; + SZ_RESULT res; + + RINOK(SzReadStreamsInfo(sd, &dataStartPos, db, + &numUnPackStreams, unPackSizes, digestsDefined, digests, + allocTemp->Alloc, allocTemp)); + + dataStartPos += baseOffset; + if (db->NumFolders != 1) + return SZE_ARCHIVE_ERROR; + + folder = db->Folders; + unPackSize = SzFolderGetUnPackSize(folder); + + RINOK(inStream->Seek(inStream, dataStartPos)); + + #ifndef _LZMA_IN_CB + for (i = 0; i < db->NumPackStreams; i++) + packSize += db->PackSizes[i]; + + *inBuffer = (Byte *)allocTemp->Alloc((size_t)packSize); + RINOM(*inBuffer); + + RINOK(SafeReadDirect(inStream, *inBuffer, (size_t)packSize)); + #endif + + if (!SzByteBufferCreate(outBuffer, (size_t)unPackSize, allocTemp->Alloc)) + return SZE_OUTOFMEMORY; + + res = SzDecode(db->PackSizes, folder, + #ifdef _LZMA_IN_CB + inStream, + #else + *inBuffer, + #endif + outBuffer->Items, (size_t)unPackSize, + &outRealSize, allocTemp); + RINOK(res) + if (outRealSize != (UInt32)unPackSize) + return SZE_FAIL; + if (folder->UnPackCRCDefined) + if (!CrcVerifyDigest(folder->UnPackCRC, outBuffer->Items, (size_t)unPackSize)) + return SZE_FAIL; + return SZ_OK; +} + +SZ_RESULT SzReadAndDecodePackedStreams( + ISzInStream *inStream, + CSzData *sd, + CSzByteBuffer *outBuffer, + CFileSize baseOffset, + ISzAlloc *allocTemp) +{ + CArchiveDatabase db; + CFileSize *unPackSizes = 0; + int *digestsDefined = 0; + UInt32 *digests = 0; + #ifndef _LZMA_IN_CB + Byte *inBuffer = 0; + #endif + SZ_RESULT res; + SzArchiveDatabaseInit(&db); + res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset, + &db, &unPackSizes, &digestsDefined, &digests, + #ifndef _LZMA_IN_CB + &inBuffer, + #endif + allocTemp); + SzArchiveDatabaseFree(&db, allocTemp->Free); + allocTemp->Free(unPackSizes); + allocTemp->Free(digestsDefined); + allocTemp->Free(digests); + #ifndef _LZMA_IN_CB + allocTemp->Free(inBuffer); + #endif + return res; +} + +SZ_RESULT SzArchiveOpen2( + ISzInStream *inStream, + CArchiveDatabaseEx *db, + ISzAlloc *allocMain, + ISzAlloc *allocTemp) +{ + Byte signature[k7zSignatureSize]; + Byte version; + UInt32 crcFromArchive; + UInt64 nextHeaderOffset; + UInt64 nextHeaderSize; + UInt32 nextHeaderCRC; + UInt32 crc; + CFileSize pos = 0; + CSzByteBuffer buffer; + CSzData sd; + SZ_RESULT res; + + RINOK(SafeReadDirect(inStream, signature, k7zSignatureSize)); + + if (!TestSignatureCandidate(signature)) + return SZE_ARCHIVE_ERROR; + + /* + db.Clear(); + db.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition; + */ + RINOK(SafeReadDirectByte(inStream, &version)); + if (version != k7zMajorVersion) + return SZE_ARCHIVE_ERROR; + RINOK(SafeReadDirectByte(inStream, &version)); + + RINOK(SafeReadDirectUInt32(inStream, &crcFromArchive)); + + CrcInit(&crc); + RINOK(SafeReadDirectUInt64(inStream, &nextHeaderOffset)); + CrcUpdateUInt64(&crc, nextHeaderOffset); + RINOK(SafeReadDirectUInt64(inStream, &nextHeaderSize)); + CrcUpdateUInt64(&crc, nextHeaderSize); + RINOK(SafeReadDirectUInt32(inStream, &nextHeaderCRC)); + CrcUpdateUInt32(&crc, nextHeaderCRC); + + pos = k7zStartHeaderSize; + db->ArchiveInfo.StartPositionAfterHeader = pos; + + if (CrcGetDigest(&crc) != crcFromArchive) + return SZE_ARCHIVE_ERROR; + + if (nextHeaderSize == 0) + return SZ_OK; + + RINOK(inStream->Seek(inStream, (CFileSize)(pos + nextHeaderOffset))); + + if (!SzByteBufferCreate(&buffer, (size_t)nextHeaderSize, allocTemp->Alloc)) + return SZE_OUTOFMEMORY; + + res = SafeReadDirect(inStream, buffer.Items, (size_t)nextHeaderSize); + if (res == SZ_OK) + { + if (CrcVerifyDigest(nextHeaderCRC, buffer.Items, (UInt32)nextHeaderSize)) + { + while (1) + { + UInt64 type; + sd.Data = buffer.Items; + sd.Size = buffer.Capacity; + res = SzReadID(&sd, &type); + if (res != SZ_OK) + break; + if (type == k7zIdHeader) + { + res = SzReadHeader(&sd, db, allocMain, allocTemp); + break; + } + if (type != k7zIdEncodedHeader) + { + res = SZE_ARCHIVE_ERROR; + break; + } + { + CSzByteBuffer outBuffer; + res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer, + db->ArchiveInfo.StartPositionAfterHeader, + allocTemp); + if (res != SZ_OK) + { + SzByteBufferFree(&outBuffer, allocTemp->Free); + break; + } + SzByteBufferFree(&buffer, allocTemp->Free); + buffer.Items = outBuffer.Items; + buffer.Capacity = outBuffer.Capacity; + } + } + } + } + SzByteBufferFree(&buffer, allocTemp->Free); + return res; +} + +SZ_RESULT SzArchiveOpen( + ISzInStream *inStream, + CArchiveDatabaseEx *db, + ISzAlloc *allocMain, + ISzAlloc *allocTemp) +{ + SZ_RESULT res = SzArchiveOpen2(inStream, db, allocMain, allocTemp); + if (res != SZ_OK) + SzArDbExFree(db, allocMain->Free); + return res; +} diff --git a/7zip/Archive/7z_C/7zIn.h b/7zip/Archive/7z_C/7zIn.h new file mode 100755 index 00000000..6bfa2a70 --- /dev/null +++ b/7zip/Archive/7z_C/7zIn.h @@ -0,0 +1,55 @@ +/* 7zIn.h */ + +#ifndef __7Z_IN_H +#define __7Z_IN_H + +#include "7zHeader.h" +#include "7zItem.h" +#include "7zAlloc.h" + +typedef struct _CInArchiveInfo +{ + CFileSize StartPositionAfterHeader; + CFileSize DataStartPosition; +}CInArchiveInfo; + +typedef struct _CArchiveDatabaseEx +{ + CArchiveDatabase Database; + CInArchiveInfo ArchiveInfo; + UInt32 *FolderStartPackStreamIndex; + CFileSize *PackStreamStartPositions; + UInt32 *FolderStartFileIndex; + UInt32 *FileIndexToFolderIndexMap; +}CArchiveDatabaseEx; + +void SzArDbExInit(CArchiveDatabaseEx *db); +void SzArDbExFree(CArchiveDatabaseEx *db, void (*freeFunc)(void *)); +CFileSize SzArDbGetFolderStreamPos(CArchiveDatabaseEx *db, UInt32 folderIndex, UInt32 indexInFolder); +CFileSize SzArDbGetFolderFullPackSize(CArchiveDatabaseEx *db, UInt32 folderIndex); + +typedef struct _ISzInStream +{ + #ifdef _LZMA_IN_CB + SZ_RESULT (*Read)( + void *object, /* pointer to ISzInStream itself */ + void **buffer, /* out: pointer to buffer with data */ + size_t maxRequiredSize, /* max required size to read */ + size_t *processedSize); /* real processed size. + processedSize can be less than maxRequiredSize. + If processedSize == 0, then there are no more + bytes in stream. */ + #else + SZ_RESULT (*Read)(void *object, void *buffer, size_t size, size_t *processedSize); + #endif + SZ_RESULT (*Seek)(void *object, CFileSize pos); +} ISzInStream; + + +int SzArchiveOpen( + ISzInStream *inStream, + CArchiveDatabaseEx *db, + ISzAlloc *allocMain, + ISzAlloc *allocTemp); + +#endif diff --git a/7zip/Archive/7z_C/7zItem.c b/7zip/Archive/7z_C/7zItem.c new file mode 100755 index 00000000..2a408050 --- /dev/null +++ b/7zip/Archive/7z_C/7zItem.c @@ -0,0 +1,133 @@ +/* 7zItem.c */ + +#include "7zItem.h" +#include "7zAlloc.h" + +void SzCoderInfoInit(CCoderInfo *coder) +{ + SzByteBufferInit(&coder->Properties); +} + +void SzCoderInfoFree(CCoderInfo *coder, void (*freeFunc)(void *p)) +{ + SzByteBufferFree(&coder->Properties, freeFunc); + SzCoderInfoInit(coder); +} + +void SzFolderInit(CFolder *folder) +{ + folder->NumCoders = 0; + folder->Coders = 0; + folder->NumBindPairs = 0; + folder->BindPairs = 0; + folder->NumPackStreams = 0; + folder->PackStreams = 0; + folder->UnPackSizes = 0; + folder->UnPackCRCDefined = 0; + folder->UnPackCRC = 0; + folder->NumUnPackStreams = 0; +} + +void SzFolderFree(CFolder *folder, void (*freeFunc)(void *p)) +{ + UInt32 i; + for (i = 0; i < folder->NumCoders; i++) + SzCoderInfoFree(&folder->Coders[i], freeFunc); + freeFunc(folder->Coders); + freeFunc(folder->BindPairs); + freeFunc(folder->PackStreams); + freeFunc(folder->UnPackSizes); + SzFolderInit(folder); +} + +UInt32 SzFolderGetNumOutStreams(CFolder *folder) +{ + UInt32 result = 0; + UInt32 i; + for (i = 0; i < folder->NumCoders; i++) + result += folder->Coders[i].NumOutStreams; + return result; +} + +int SzFolderFindBindPairForInStream(CFolder *folder, UInt32 inStreamIndex) +{ + UInt32 i; + for(i = 0; i < folder->NumBindPairs; i++) + if (folder->BindPairs[i].InIndex == inStreamIndex) + return i; + return -1; +} + + +int SzFolderFindBindPairForOutStream(CFolder *folder, UInt32 outStreamIndex) +{ + UInt32 i; + for(i = 0; i < folder->NumBindPairs; i++) + if (folder->BindPairs[i].OutIndex == outStreamIndex) + return i; + return -1; +} + +CFileSize SzFolderGetUnPackSize(CFolder *folder) +{ + int i = (int)SzFolderGetNumOutStreams(folder); + if (i == 0) + return 0; + for (i--; i >= 0; i--) + if (SzFolderFindBindPairForOutStream(folder, i) < 0) + return folder->UnPackSizes[i]; + /* throw 1; */ + return 0; +} + +/* +int FindPackStreamArrayIndex(int inStreamIndex) const +{ + for(int i = 0; i < PackStreams.Size(); i++) + if (PackStreams[i] == inStreamIndex) + return i; + return -1; +} +*/ + +void SzFileInit(CFileItem *fileItem) +{ + fileItem->IsFileCRCDefined = 0; + fileItem->HasStream = 1; + fileItem->IsDirectory = 0; + fileItem->IsAnti = 0; + fileItem->Name = 0; +} + +void SzFileFree(CFileItem *fileItem, void (*freeFunc)(void *p)) +{ + freeFunc(fileItem->Name); + SzFileInit(fileItem); +} + +void SzArchiveDatabaseInit(CArchiveDatabase *db) +{ + db->NumPackStreams = 0; + db->PackSizes = 0; + db->PackCRCsDefined = 0; + db->PackCRCs = 0; + db->NumFolders = 0; + db->Folders = 0; + db->NumFiles = 0; + db->Files = 0; +} + +void SzArchiveDatabaseFree(CArchiveDatabase *db, void (*freeFunc)(void *)) +{ + UInt32 i; + for (i = 0; i < db->NumFolders; i++) + SzFolderFree(&db->Folders[i], freeFunc); + for (i = 0; i < db->NumFiles; i++) + SzFileFree(&db->Files[i], freeFunc); + freeFunc(db->PackSizes); + freeFunc(db->PackCRCsDefined); + freeFunc(db->PackCRCs); + freeFunc(db->Folders); + freeFunc(db->Files); + SzArchiveDatabaseInit(db); +} diff --git a/7zip/Archive/7z_C/7zItem.h b/7zip/Archive/7z_C/7zItem.h new file mode 100755 index 00000000..8a212cdb --- /dev/null +++ b/7zip/Archive/7z_C/7zItem.h @@ -0,0 +1,90 @@ +/* 7zItem.h */ + +#ifndef __7Z_ITEM_H +#define __7Z_ITEM_H + +#include "7zMethodID.h" +#include "7zHeader.h" +#include "7zBuffer.h" + +typedef struct _CCoderInfo +{ + UInt32 NumInStreams; + UInt32 NumOutStreams; + CMethodID MethodID; + CSzByteBuffer Properties; +}CCoderInfo; + +void SzCoderInfoInit(CCoderInfo *coder); +void SzCoderInfoFree(CCoderInfo *coder, void (*freeFunc)(void *p)); + +typedef struct _CBindPair +{ + UInt32 InIndex; + UInt32 OutIndex; +}CBindPair; + +typedef struct _CFolder +{ + UInt32 NumCoders; + CCoderInfo *Coders; + UInt32 NumBindPairs; + CBindPair *BindPairs; + UInt32 NumPackStreams; + UInt32 *PackStreams; + CFileSize *UnPackSizes; + int UnPackCRCDefined; + UInt32 UnPackCRC; + + UInt32 NumUnPackStreams; +}CFolder; + +void SzFolderInit(CFolder *folder); +CFileSize SzFolderGetUnPackSize(CFolder *folder); +int SzFolderFindBindPairForInStream(CFolder *folder, UInt32 inStreamIndex); +UInt32 SzFolderGetNumOutStreams(CFolder *folder); +CFileSize SzFolderGetUnPackSize(CFolder *folder); + +/* #define CArchiveFileTime UInt64 */ + +typedef struct _CFileItem +{ + /* + CArchiveFileTime LastWriteTime; + CFileSize StartPos; + UInt32 Attributes; + */ + CFileSize Size; + UInt32 FileCRC; + char *Name; + + Byte IsFileCRCDefined; + Byte HasStream; + Byte IsDirectory; + Byte IsAnti; + /* + int AreAttributesDefined; + int IsLastWriteTimeDefined; + int IsStartPosDefined; + */ +}CFileItem; + +void SzFileInit(CFileItem *fileItem); + +typedef struct _CArchiveDatabase +{ + UInt32 NumPackStreams; + CFileSize *PackSizes; + int *PackCRCsDefined; + UInt32 *PackCRCs; + UInt32 NumFolders; + CFolder *Folders; + UInt32 NumFiles; + CFileItem *Files; +}CArchiveDatabase; + +void SzArchiveDatabaseInit(CArchiveDatabase *db); +void SzArchiveDatabaseFree(CArchiveDatabase *db, void (*freeFunc)(void *)); + + +#endif diff --git a/7zip/Archive/7z_C/7zMain.c b/7zip/Archive/7z_C/7zMain.c new file mode 100755 index 00000000..390ce8f4 --- /dev/null +++ b/7zip/Archive/7z_C/7zMain.c @@ -0,0 +1,211 @@ +/* +7zMain.c +Test application for 7z Decoder +LZMA SDK 4.16 Copyright (c) 1999-2005 Igor Pavlov (2005-09-24) +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "7zCrc.h" +#include "7zIn.h" +#include "7zExtract.h" + +typedef struct _CFileInStream +{ + ISzInStream InStream; + FILE *File; +} CFileInStream; + +#ifdef _LZMA_IN_CB + +#define kBufferSize (1 << 12) +Byte g_Buffer[kBufferSize]; + +SZ_RESULT SzFileReadImp(void *object, void **buffer, size_t maxRequiredSize, size_t *processedSize) +{ + CFileInStream *s = (CFileInStream *)object; + size_t processedSizeLoc; + if (maxRequiredSize > kBufferSize) + maxRequiredSize = kBufferSize; + processedSizeLoc = fread(g_Buffer, 1, maxRequiredSize, s->File); + *buffer = g_Buffer; + if (processedSize != 0) + *processedSize = processedSizeLoc; + return SZ_OK; +} + +#else + +SZ_RESULT SzFileReadImp(void *object, void *buffer, size_t size, size_t *processedSize) +{ + CFileInStream *s = (CFileInStream *)object; + size_t processedSizeLoc = fread(buffer, 1, size, s->File); + if (processedSize != 0) + *processedSize = processedSizeLoc; + return SZ_OK; +} + +#endif + +SZ_RESULT SzFileSeekImp(void *object, CFileSize pos) +{ + CFileInStream *s = (CFileInStream *)object; + int res = fseek(s->File, (long)pos, SEEK_SET); + if (res == 0) + return SZ_OK; + return SZE_FAIL; +} + +void PrintError(char *sz) +{ + printf("\nERROR: %s\n", sz); +} + +int main(int numargs, char *args[]) +{ + CFileInStream archiveStream; + CArchiveDatabaseEx db; + SZ_RESULT res; + ISzAlloc allocImp; + ISzAlloc allocTempImp; + + printf("\n7z ANSI-C Decoder 4.16 Copyright (c) 1999-2005 Igor Pavlov 2005-03-29\n"); + if (numargs == 1) + { + printf( + "\nUsage: 7zDec <command> <archive_name>\n\n" + "<Commands>\n" + " e: Extract files from archive\n" + " l: List contents of archive\n" + " t: Test integrity of archive\n"); + return 0; + } + if (numargs < 3) + { + PrintError("incorrect command"); + return 1; + } + + archiveStream.File = fopen(args[2], "rb"); + if (archiveStream.File == 0) + { + PrintError("can not open input file"); + return 1; + } + + archiveStream.InStream.Read = SzFileReadImp; + archiveStream.InStream.Seek = SzFileSeekImp; + + allocImp.Alloc = SzAlloc; + allocImp.Free = SzFree; + + allocTempImp.Alloc = SzAllocTemp; + allocTempImp.Free = SzFreeTemp; + + InitCrcTable(); + SzArDbExInit(&db); + res = SzArchiveOpen(&archiveStream.InStream, &db, &allocImp, &allocTempImp); + if (res == SZ_OK) + { + char *command = args[1]; + int listCommand = 0; + int testCommand = 0; + int extractCommand = 0; + if (strcmp(command, "l") == 0) + listCommand = 1; + if (strcmp(command, "t") == 0) + testCommand = 1; + else if (strcmp(command, "e") == 0) + extractCommand = 1; + + if (listCommand) + { + UInt32 i; + for (i = 0; i < db.Database.NumFiles; i++) + { + CFileItem *f = db.Database.Files + i; + printf("%10d %s\n", (int)f->Size, f->Name); + } + } + else if (testCommand || extractCommand) + { + UInt32 i; + UInt32 blockIndex; + Byte *outBuffer = 0; + size_t outBufferSize; + printf("\n"); + for (i = 0; i < db.Database.NumFiles; i++) + { + size_t offset; + size_t outSizeProcessed; + CFileItem *f = db.Database.Files + i; + printf(testCommand ? + "Tesing ": + "Extracting"); + printf(" %s", f->Name); + res = SzExtract(&archiveStream.InStream, &db, i, + &blockIndex, &outBuffer, &outBufferSize, + &offset, &outSizeProcessed, + &allocImp, &allocTempImp); + if (res != SZ_OK) + break; + if (!testCommand) + { + FILE *outputHandle; + UInt32 processedSize; + char *fileName = f->Name; + size_t nameLen = strlen(f->Name); + for (; nameLen > 0; nameLen--) + if (f->Name[nameLen - 1] == '/') + { + fileName = f->Name + nameLen; + break; + } + + outputHandle = fopen(fileName, "wb+"); + if (outputHandle == 0) + { + PrintError("can not open output file"); + res = SZE_FAIL; + break; + } + processedSize = fwrite(outBuffer + offset, 1, outSizeProcessed, outputHandle); + if (processedSize != outSizeProcessed) + { + PrintError("can not write output file"); + res = SZE_FAIL; + break; + } + if (fclose(outputHandle)) + { + PrintError("can not close output file"); + res = SZE_FAIL; + break; + } + } + printf("\n"); + } + allocImp.Free(outBuffer); + } + else + { + PrintError("incorrect command"); + res = SZE_FAIL; + } + } + SzArDbExFree(&db, allocImp.Free); + + fclose(archiveStream.File); + if (res == SZ_OK) + { + printf("\nEverything is Ok\n"); + return 0; + } + if (res == SZE_OUTOFMEMORY) + PrintError("can not allocate memory"); + else + printf("\nERROR #%d\n", res); + return 1; +} diff --git a/7zip/Archive/7z_C/7zMethodID.c b/7zip/Archive/7z_C/7zMethodID.c new file mode 100755 index 00000000..5047359f --- /dev/null +++ b/7zip/Archive/7z_C/7zMethodID.c @@ -0,0 +1,14 @@ +/* 7zMethodID.c */ + +#include "7zMethodID.h" + +int AreMethodsEqual(CMethodID *a1, CMethodID *a2) +{ + int i; + if (a1->IDSize != a2->IDSize) + return 0; + for (i = 0; i < a1->IDSize; i++) + if (a1->ID[i] != a2->ID[i]) + return 0; + return 1; +} diff --git a/7zip/Archive/7z_C/7zMethodID.h b/7zip/Archive/7z_C/7zMethodID.h new file mode 100755 index 00000000..162fcd15 --- /dev/null +++ b/7zip/Archive/7z_C/7zMethodID.h @@ -0,0 +1,18 @@ +/* 7zMethodID.h */ + +#ifndef __7Z_METHOD_ID_H +#define __7Z_METHOD_ID_H + +#include "7zTypes.h" + +#define kMethodIDSize 15 + +typedef struct _CMethodID +{ + Byte ID[kMethodIDSize]; + Byte IDSize; +} CMethodID; + +int AreMethodsEqual(CMethodID *a1, CMethodID *a2); + +#endif diff --git a/7zip/Archive/7z_C/7zTypes.h b/7zip/Archive/7z_C/7zTypes.h new file mode 100755 index 00000000..fdef1458 --- /dev/null +++ b/7zip/Archive/7z_C/7zTypes.h @@ -0,0 +1,61 @@ +/* 7zTypes.h */ + +#ifndef __COMMON_TYPES_H +#define __COMMON_TYPES_H + +#ifndef UInt32 +#ifdef _LZMA_UINT32_IS_ULONG +#define UInt32 unsigned long +#else +#define UInt32 unsigned int +#endif +#endif + +#ifndef Byte +#define Byte unsigned char +#endif + +#ifndef UInt16 +#define UInt16 unsigned short +#endif + +/* #define _SZ_NO_INT_64 */ +/* define it your compiler doesn't support long long int */ + +#ifdef _SZ_NO_INT_64 +#define UInt64 unsigned long +#else +#ifdef _MSC_VER +#define UInt64 unsigned __int64 +#else +#define UInt64 unsigned long long int +#endif +#endif + + +/* #define _SZ_FILE_SIZE_64 */ +/* Use _SZ_FILE_SIZE_64 if you need support for files larger than 4 GB*/ + +#ifndef CFileSize +#ifdef _SZ_FILE_SIZE_64 +#define CFileSize UInt64 +#else +#define CFileSize UInt32 +#endif +#endif + +#define SZ_RESULT int + +#define SZ_OK (0) +#define SZE_DATA_ERROR (1) +#define SZE_OUTOFMEMORY (2) +#define SZE_CRC_ERROR (3) + +#define SZE_NOTIMPL (4) +#define SZE_FAIL (5) + +#define SZE_ARCHIVE_ERROR (6) + +#define RINOK(x) { int __result_ = (x); if(__result_ != 0) return __result_; } + +#endif diff --git a/7zip/Archive/7z_C/7z_C.dsp b/7zip/Archive/7z_C/7z_C.dsp new file mode 100755 index 00000000..1e871520 --- /dev/null +++ b/7zip/Archive/7z_C/7z_C.dsp @@ -0,0 +1,178 @@ +# Microsoft Developer Studio Project File - Name="7z_C" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=7z_C - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "7z_C.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "7z_C.mak" CFG="7z_C - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "7z_C - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "7z_C - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "7z_C - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W4 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_LZMA_PROB32" /D "_LZMA_IN_CB" /YX /FD /c +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"Release/7zDec.exe" + +!ELSEIF "$(CFG)" == "7z_C - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_LZMA_PROB32" /D "_LZMA_IN_CB" /YX /FD /GZ /c +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/7zDec.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "7z_C - Win32 Release" +# Name "7z_C - Win32 Debug" +# Begin Group "LZMA" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\LZMA_C\LzmaDecode.c +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZMA_C\LzmaDecode.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\7zAlloc.c +# End Source File +# Begin Source File + +SOURCE=.\7zAlloc.h +# End Source File +# Begin Source File + +SOURCE=.\7zBuffer.c +# End Source File +# Begin Source File + +SOURCE=.\7zBuffer.h +# End Source File +# Begin Source File + +SOURCE=.\7zCrc.c +# End Source File +# Begin Source File + +SOURCE=.\7zCrc.h +# End Source File +# Begin Source File + +SOURCE=.\7zDecode.c +# End Source File +# Begin Source File + +SOURCE=.\7zDecode.h +# End Source File +# Begin Source File + +SOURCE=.\7zExtract.c +# End Source File +# Begin Source File + +SOURCE=.\7zExtract.h +# End Source File +# Begin Source File + +SOURCE=.\7zHeader.c +# End Source File +# Begin Source File + +SOURCE=.\7zHeader.h +# End Source File +# Begin Source File + +SOURCE=.\7zIn.c +# End Source File +# Begin Source File + +SOURCE=.\7zIn.h +# End Source File +# Begin Source File + +SOURCE=.\7zItem.c +# End Source File +# Begin Source File + +SOURCE=.\7zItem.h +# End Source File +# Begin Source File + +SOURCE=.\7zMain.c +# End Source File +# Begin Source File + +SOURCE=.\7zMethodID.c +# End Source File +# Begin Source File + +SOURCE=.\7zMethodID.h +# End Source File +# Begin Source File + +SOURCE=.\7zTypes.h +# End Source File +# End Target +# End Project diff --git a/7zip/Archive/7z_C/7z_C.dsw b/7zip/Archive/7z_C/7z_C.dsw new file mode 100755 index 00000000..6fd39621 --- /dev/null +++ b/7zip/Archive/7z_C/7z_C.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "7z_C"=.\7z_C.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/7zip/Archive/7z_C/makefile b/7zip/Archive/7z_C/makefile new file mode 100755 index 00000000..83dc0335 --- /dev/null +++ b/7zip/Archive/7z_C/makefile @@ -0,0 +1,50 @@ +PROG = 7zDec +CXX = g++ -O2 -Wall +LIB = +RM = rm -f +CFLAGS = -c + +OBJS = 7zAlloc.o 7zBuffer.o 7zCrc.o 7zDecode.o 7zExtract.o 7zHeader.o 7zIn.o 7zItem.o 7zMain.o 7zMethodID.o LzmaDecode.o + +all: $(PROG) + +$(PROG): $(OBJS) + $(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB) + +7zAlloc.o: 7zAlloc.c + $(CXX) $(CFLAGS) 7zAlloc.c + +7zBuffer.o: 7zBuffer.c + $(CXX) $(CFLAGS) 7zBuffer.c + +7zCrc.o: 7zCrc.c + $(CXX) $(CFLAGS) 7zCrc.c + +7zDecode.o: 7zDecode.c + $(CXX) $(CFLAGS) 7zDecode.c + +7zExtract.o: 7zExtract.c + $(CXX) $(CFLAGS) 7zExtract.c + +7zHeader.o: 7zHeader.c + $(CXX) $(CFLAGS) 7zHeader.c + +7zIn.o: 7zIn.c + $(CXX) $(CFLAGS) 7zIn.c + +7zItem.o: 7zItem.c + $(CXX) $(CFLAGS) 7zItem.c + +7zMain.o: 7zMain.c + $(CXX) $(CFLAGS) 7zMain.c + +7zMethodID.o: 7zMethodID.c + $(CXX) $(CFLAGS) 7zMethodID.c + +LzmaDecode.o: ../../Compress/LZMA_C/LzmaDecode.c + $(CXX) $(CFLAGS) ../../Compress/LZMA_C/LzmaDecode.c + + +clean: + -$(RM) $(PROG) $(OBJS) + diff --git a/7zip/Archive/Arj/Arj.dsp b/7zip/Archive/Arj/Arj.dsp index d6365185..1a231157 100755 --- a/7zip/Archive/Arj/Arj.dsp +++ b/7zip/Archive/Arj/Arj.dsp @@ -122,6 +122,14 @@ SOURCE=.\StdAfx.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\CRC.cpp # End Source File # Begin Source File @@ -201,10 +209,6 @@ SOURCE=.\ArjIn.h SOURCE=.\ArjItem.h # End Source File # End Group -# Begin Group "Compression" - -# PROP Default_Filter "" -# End Group # Begin Group "Compress" # PROP Default_Filter "" @@ -274,6 +278,10 @@ SOURCE=..\..\Common\LimitedStreams.h # End Source File # Begin Source File +SOURCE=..\..\Common\MSBFDecoder.h +# End Source File +# Begin Source File + SOURCE=..\..\Common\ProgressUtils.cpp # End Source File # Begin Source File diff --git a/7zip/Archive/Arj/ArjHandler.cpp b/7zip/Archive/Arj/ArjHandler.cpp index 2a5718b1..7701da3b 100755 --- a/7zip/Archive/Arj/ArjHandler.cpp +++ b/7zip/Archive/Arj/ArjHandler.cpp @@ -93,13 +93,13 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) return S_OK; } -STDMETHODIMP CHandler::GetNumberOfProperties(UINT32 *numProperties) +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) { *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); return S_OK; } -STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index, +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) { if(index >= sizeof(kProperties) / sizeof(kProperties[0])) @@ -111,25 +111,25 @@ STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index, return S_OK; } -STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UINT32 *numProperties) +STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) { *numProperties = 0; return S_OK; } -STDMETHODIMP CHandler::GetArchivePropertyInfo(UINT32 index, +STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) { return E_NOTIMPL; } -STDMETHODIMP CHandler::GetNumberOfItems(UINT32 *numItems) +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) { *numItems = _items.Size(); return S_OK; } -STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value) +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant propVariant; @@ -193,24 +193,24 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va COM_TRY_END } +/* class CPropgressImp: public CProgressVirt { - CMyComPtr<IArchiveOpenCallback> m_OpenArchiveCallBack; public: - STDMETHOD(SetCompleted)(const UINT64 *numFiles); - void Init(IArchiveOpenCallback *openArchiveCallback) - { m_OpenArchiveCallBack = openArchiveCallback; } + CMyComPtr<IArchiveOpenCallback> Callback; + STDMETHOD(SetCompleted)(const UInt64 *numFiles); }; -STDMETHODIMP CPropgressImp::SetCompleted(const UINT64 *numFiles) +STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles) { - if (m_OpenArchiveCallBack) - return m_OpenArchiveCallBack->SetCompleted(numFiles, NULL); + if (Callback) + return Callback->SetCompleted(numFiles, NULL); return S_OK; } +*/ STDMETHODIMP CHandler::Open(IInStream *inStream, - const UINT64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) + const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback) { COM_TRY_BEGIN try @@ -219,11 +219,11 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, CInArchive archive; if(!archive.Open(inStream, maxCheckStartPosition)) return S_FALSE; - if (openArchiveCallback != NULL) + if (callback != NULL) { - RINOK(openArchiveCallback->SetTotal(NULL, NULL)); - UINT64 numFiles = _items.Size(); - RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); + RINOK(callback->SetTotal(NULL, NULL)); + UInt64 numFiles = _items.Size(); + RINOK(callback->SetCompleted(&numFiles, NULL)); } while(true) { @@ -238,10 +238,10 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, break; _items.Add(itemInfo); archive.IncreaseRealPosition(itemInfo.PackSize); - if (openArchiveCallback != NULL) + if (callback != NULL) { - UINT64 numFiles = _items.Size(); - RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); + UInt64 numFiles = _items.Size(); + RINOK(callback->SetCompleted(&numFiles, NULL)); } } _stream = inStream; @@ -265,18 +265,18 @@ STDMETHODIMP CHandler::Close() ////////////////////////////////////// // CHandler::DecompressItems -STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, - INT32 testModeSpec, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 testModeSpec, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN bool testMode = (testModeSpec != 0); - UINT64 totalUnPacked = 0, totalPacked = 0; - bool allFilesMode = (numItems == UINT32(-1)); + UInt64 totalUnPacked = 0, totalPacked = 0; + bool allFilesMode = (numItems == UInt32(-1)); if (allFilesMode) numItems = _items.Size(); if(numItems == 0) return S_OK; - UINT32 i; + UInt32 i; for(i = 0; i < numItems; i++) { const CItemEx &itemInfo = _items[allFilesMode ? i : indices[i]]; @@ -285,8 +285,8 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, } extractCallback->SetTotal(totalUnPacked); - UINT64 currentTotalUnPacked = 0, currentTotalPacked = 0; - UINT64 currentItemUnPacked, currentItemPacked; + UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0; + UInt64 currentItemUnPacked, currentItemPacked; CMyComPtr<ICompressCoder> arj1Decoder; CMyComPtr<ICompressCoder> arj2Decoder; @@ -300,10 +300,10 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, RINOK(extractCallback->SetCompleted(¤tTotalUnPacked)); CMyComPtr<ISequentialOutStream> realOutStream; - INT32 askMode; + Int32 askMode; askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract; - INT32 index = allFilesMode ? i : indices[i]; + Int32 index = allFilesMode ? i : indices[i]; const CItemEx &itemInfo = _items[index]; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); @@ -333,7 +333,7 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; CMyComPtr<ISequentialInStream> inStream(streamSpec); - UINT64 pos; + UInt64 pos; _stream->Seek(itemInfo.DataPosition, STREAM_SEEK_SET, &pos); streamSpec->Init(_stream, itemInfo.PackSize); diff --git a/7zip/Archive/Arj/ArjHandler.h b/7zip/Archive/Arj/ArjHandler.h index a449fd95..a1e69ba6 100755 --- a/7zip/Archive/Arj/ArjHandler.h +++ b/7zip/Archive/Arj/ArjHandler.h @@ -1,7 +1,5 @@ // ArjHandler.h -#pragma once - #ifndef __ARJ_HANDLER_H #define __ARJ_HANDLER_H @@ -19,23 +17,23 @@ class CHandler: public: MY_UNKNOWN_IMP - STDMETHOD(Open)(IInStream *aStream, - const UINT64 *aMaxCheckStartPosition, - IArchiveOpenCallback *anOpenArchiveCallback); + STDMETHOD(Open)(IInStream *inStream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *callback); STDMETHOD(Close)(); - STDMETHOD(GetNumberOfItems)(UINT32 *numItems); - STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(Extract)(const UINT32* indices, UINT32 numItems, - INT32 testMode, IArchiveExtractCallback *anExtractCallback); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *anExtractCallback); STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); - STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties); - STDMETHOD(GetPropertyInfo)(UINT32 index, + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType); - STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties); - STDMETHOD(GetArchivePropertyInfo)(UINT32 index, + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType); CHandler(); @@ -46,4 +44,4 @@ private: }} -#endif
\ No newline at end of file +#endif diff --git a/7zip/Archive/Arj/ArjHeader.h b/7zip/Archive/Arj/ArjHeader.h index 3537246c..58ee8c27 100755 --- a/7zip/Archive/Arj/ArjHeader.h +++ b/7zip/Archive/Arj/ArjHeader.h @@ -1,7 +1,5 @@ // Archive/Arj/Header.h -#pragma once - #ifndef __ARCHIVE_ARJ_HEADER_H #define __ARCHIVE_ARJ_HEADER_H @@ -14,33 +12,32 @@ const int kMaxBlockSize = 2600; namespace NSignature { - const BYTE kSig0 = 0x60; - const BYTE kSig1 = 0xEA; + const Byte kSig0 = 0x60; + const Byte kSig1 = 0xEA; } -#pragma pack( push, Pragma_Arj_Headers) -#pragma pack( push, 1) - +/* struct CArchiveHeader { - // UINT16 BasicHeaderSize; - BYTE FirstHeaderSize; - BYTE Version; - BYTE ExtractVersion; - BYTE HostOS; - BYTE Flags; - BYTE SecuryVersion; - BYTE FileType; - BYTE Reserved; - UINT32 CreatedTime; - UINT32 ModifiedTime; - UINT32 ArchiveSize; - UINT32 SecurityEnvelopeFilePosition; - UINT16 FilespecPositionInFilename; - UINT16 LengthOfSecurityEnvelopeSata; - BYTE EncryptionVersion; - BYTE LastChapter; + // UInt16 BasicHeaderSize; + Byte FirstHeaderSize; + Byte Version; + Byte ExtractVersion; + Byte HostOS; + Byte Flags; + Byte SecuryVersion; + Byte FileType; + Byte Reserved; + UInt32 CreatedTime; + UInt32 ModifiedTime; + UInt32 ArchiveSize; + UInt32 SecurityEnvelopeFilePosition; + UInt16 FilespecPositionInFilename; + UInt16 LengthOfSecurityEnvelopeSata; + Byte EncryptionVersion; + Byte LastChapter; }; +*/ namespace NFileHeader { @@ -70,32 +67,35 @@ namespace NFileHeader } namespace NFlags { - const BYTE kGarbled = 1; - const BYTE kVolume = 4; - const BYTE kExtFile = 8; - const BYTE kPathSym = 0x10; - const BYTE kBackup= 0x20; + const Byte kGarbled = 1; + const Byte kVolume = 4; + const Byte kExtFile = 8; + const Byte kPathSym = 0x10; + const Byte kBackup= 0x20; } + /* struct CHeader { - BYTE FirstHeaderSize; - BYTE Version; - BYTE ExtractVersion; - BYTE HostOS; - BYTE Flags; - BYTE Method; - BYTE FileType; - BYTE Reserved; - UINT32 ModifiedTime; - UINT32 PackSize; - UINT32 Size; - UINT32 FileCRC; - UINT16 FilespecPositionInFilename; - UINT16 FileAccessMode; - BYTE FirstChapter; - BYTE LastChapter; + Byte FirstHeaderSize; + Byte Version; + Byte ExtractVersion; + Byte HostOS; + Byte Flags; + Byte Method; + Byte FileType; + Byte Reserved; + UInt32 ModifiedTime; + UInt32 PackSize; + UInt32 Size; + UInt32 FileCRC; + UInt16 FilespecPositionInFilename; + UInt16 FileAccessMode; + Byte FirstChapter; + Byte LastChapter; }; + */ + namespace NHostOS { enum EEnum @@ -116,9 +116,6 @@ namespace NFileHeader } } -#pragma pack(pop) -#pragma pack(pop, Pragma_Arj_Headers) - }} #endif diff --git a/7zip/Archive/Arj/ArjIn.cpp b/7zip/Archive/Arj/ArjIn.cpp index 49a6b3f4..c019055c 100755 --- a/7zip/Archive/Arj/ArjIn.cpp +++ b/7zip/Archive/Arj/ArjIn.cpp @@ -6,20 +6,14 @@ #include "Common/Buffer.h" #include "Common/CRC.h" -#include "Windows/Defs.h" - #include "ArjIn.h" namespace NArchive { namespace NArj { -CInArchiveException::CInArchiveException(CCauseType cause): - Cause(cause) -{} - -HRESULT CInArchive::ReadBytes(void *data, UINT32 size, UINT32 *processedSize) +HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize) { - UINT32 realProcessedSize; + UInt32 realProcessedSize; HRESULT result = _stream->Read(data, size, &realProcessedSize); if(processedSize != NULL) *processedSize = realProcessedSize; @@ -27,39 +21,49 @@ HRESULT CInArchive::ReadBytes(void *data, UINT32 size, UINT32 *processedSize) return result; } -inline bool TestMarkerCandidate(const void *testBytes, UINT32 maxSize) +static inline UInt16 GetUInt16FromMemLE(const Byte *p) +{ + return p[0] | (((UInt32)p[1]) << 8); +} + +static inline UInt32 GetUInt32FromMemLE(const Byte *p) +{ + return p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24); +} + +inline bool TestMarkerCandidate(const void *testBytes, UInt32 maxSize) { if (maxSize < 2 + 2 + 4) return false; - const BYTE *block = ((const BYTE *)(testBytes)); + const Byte *block = ((const Byte *)(testBytes)); if (block[0] != NSignature::kSig0 || block[1] != NSignature::kSig1) return false; - UINT32 blockSize = *((const UINT16 *)(block + 2)); + UInt32 blockSize = GetUInt16FromMemLE(block + 2); if (maxSize < 2 + 2 + blockSize + 4) return false; block += 4; if (blockSize == 0 || blockSize > 2600) return false; - UINT32 crcFromFile = *(const UINT32 *)(block + blockSize); + UInt32 crcFromFile = GetUInt32FromMemLE(block + blockSize); return (CCRC::VerifyDigest(crcFromFile, block, blockSize)); } -bool CInArchive::FindAndReadMarker(const UINT64 *searchHeaderSizeLimit) +bool CInArchive::FindAndReadMarker(const UInt64 *searchHeaderSizeLimit) { // _archiveInfo.StartPosition = 0; _position = _streamStartPosition; if(_stream->Seek(_streamStartPosition, STREAM_SEEK_SET, NULL) != S_OK) return false; - const int kMarkerSizeMax = 2 + 2 + kMaxBlockSize + sizeof(UINT32); + const int kMarkerSizeMax = 2 + 2 + kMaxBlockSize + 4; CByteBuffer byteBuffer; - static const UINT32 kSearchMarkerBufferSize = 0x10000; + static const UInt32 kSearchMarkerBufferSize = 0x10000; byteBuffer.SetCapacity(kSearchMarkerBufferSize); - BYTE *buffer = byteBuffer; + Byte *buffer = byteBuffer; - UINT32 processedSize; - ReadBytes(buffer, 2 + 2 + kMaxBlockSize + sizeof(UINT32), &processedSize); + UInt32 processedSize; + ReadBytes(buffer, kMarkerSizeMax, &processedSize); if (processedSize == 0) return false; if (TestMarkerCandidate(buffer, processedSize)) @@ -70,21 +74,21 @@ bool CInArchive::FindAndReadMarker(const UINT64 *searchHeaderSizeLimit) return true; } - UINT32 numBytesPrev = processedSize - 1; + UInt32 numBytesPrev = processedSize - 1; memmove(buffer, buffer + 1, numBytesPrev); - UINT64 curTestPos = _streamStartPosition + 1; + UInt64 curTestPos = _streamStartPosition + 1; while(true) { if (searchHeaderSizeLimit != NULL) if (curTestPos - _streamStartPosition > *searchHeaderSizeLimit) return false; - UINT32 numReadBytes = kSearchMarkerBufferSize - numBytesPrev; + UInt32 numReadBytes = kSearchMarkerBufferSize - numBytesPrev; ReadBytes(buffer + numBytesPrev, numReadBytes, &processedSize); - UINT32 numBytesInBuffer = numBytesPrev + processedSize; + UInt32 numBytesInBuffer = numBytesPrev + processedSize; if (numBytesInBuffer < 1) return false; - UINT32 numTests = numBytesInBuffer; - for(UINT32 pos = 0; pos < numTests; pos++, curTestPos++) + UInt32 numTests = numBytesInBuffer; + for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++) { if (TestMarkerCandidate(buffer + pos, numBytesInBuffer - pos)) { @@ -100,39 +104,68 @@ bool CInArchive::FindAndReadMarker(const UINT64 *searchHeaderSizeLimit) } } -void CInArchive::IncreasePositionValue(UINT64 addValue) +void CInArchive::IncreasePositionValue(UInt64 addValue) { _position += addValue; } -void CInArchive::IncreaseRealPosition(UINT64 addValue) +void CInArchive::IncreaseRealPosition(UInt64 addValue) { if(_stream->Seek(addValue, STREAM_SEEK_CUR, &_position) != S_OK) throw CInArchiveException(CInArchiveException::kSeekStreamError); } -bool CInArchive::ReadBytesAndTestSize(void *data, UINT32 size) +bool CInArchive::ReadBytesAndTestSize(void *data, UInt32 size) { - UINT32 realProcessedSize; + UInt32 realProcessedSize; if(ReadBytes(data, size, &realProcessedSize) != S_OK) throw CInArchiveException(CInArchiveException::kReadStreamError); return (realProcessedSize == size); } -void CInArchive::SafeReadBytes(void *data, UINT32 size) +void CInArchive::SafeReadBytes(void *data, UInt32 size) { if(!ReadBytesAndTestSize(data, size)) throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive); } +Byte CInArchive::SafeReadByte() +{ + Byte b; + SafeReadBytes(&b, 1); + return b; +} + +UInt16 CInArchive::SafeReadUInt16() +{ + UInt16 value = 0; + for (int i = 0; i < 2; i++) + { + Byte b = SafeReadByte(); + value |= (UInt16(b) << (8 * i)); + } + return value; +} + +UInt32 CInArchive::SafeReadUInt32() +{ + UInt32 value = 0; + for (int i = 0; i < 4; i++) + { + Byte b = SafeReadByte(); + value |= (UInt32(b) << (8 * i)); + } + return value; +} + bool CInArchive::ReadBlock() { - SafeReadBytes(&_blockSize, sizeof(_blockSize)); + _blockPos = 0; + _blockSize = SafeReadUInt16(); if (_blockSize == 0) return false; SafeReadBytes(_block, _blockSize); - UINT32 crcFromFile; - ReadBytesAndTestSize(&crcFromFile, sizeof(crcFromFile)); + UInt32 crcFromFile = SafeReadUInt32(); if (!CCRC::VerifyDigest(crcFromFile, _block, _blockSize)) throw CInArchiveException(CInArchiveException::kCRCError); return true; @@ -140,14 +173,14 @@ bool CInArchive::ReadBlock() bool CInArchive::ReadBlock2() { - BYTE id[2]; + Byte id[2]; ReadBytesAndTestSize(id, 2); if (id[0] != NSignature::kSig0 || id[1] != NSignature::kSig1) throw CInArchiveException(CInArchiveException::kIncorrectArchive); return ReadBlock(); } -bool CInArchive::Open(IInStream *inStream, const UINT64 *searchHeaderSizeLimit) +bool CInArchive::Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit) { _stream = inStream; if(_stream->Seek(0, STREAM_SEEK_CUR, &_streamStartPosition) != S_OK) @@ -173,40 +206,67 @@ void CInArchive::ThrowIncorrectArchiveException() throw CInArchiveException(CInArchiveException::kIncorrectArchive); } +Byte CInArchive::ReadByte() +{ + if (_blockPos >= _blockSize) + ThrowIncorrectArchiveException(); + return _block[_blockPos++]; +} + +UInt16 CInArchive::ReadUInt16() +{ + UInt16 value = 0; + for (int i = 0; i < 2; i++) + { + Byte b = ReadByte(); + value |= (UInt16(b) << (8 * i)); + } + return value; +} + +UInt32 CInArchive::ReadUInt32() +{ + UInt32 value = 0; + for (int i = 0; i < 4; i++) + { + Byte b = ReadByte(); + value |= (UInt32(b) << (8 * i)); + } + return value; +} + HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item) { filled = false; if (!ReadBlock2()) return S_OK; - const NFileHeader::CHeader &header = *(const NFileHeader::CHeader *)_block; - - item.Version = header.Version; - item.ExtractVersion = header.ExtractVersion; - item.HostOS = header.HostOS; - item.Flags = header.Flags; - item.Method = header.Method; - item.FileType = header.FileType; - item.ModifiedTime = header.ModifiedTime; - item.PackSize = header.PackSize; - item.Size = header.Size; - item.FileCRC = header.FileCRC; - item.FileAccessMode = header.FileAccessMode; + Byte firstHeaderSize = ReadByte(); + item.Version = ReadByte(); + item.ExtractVersion = ReadByte(); + item.HostOS = ReadByte(); + item.Flags = ReadByte(); + item.Method = ReadByte(); + item.FileType = ReadByte(); + ReadByte(); // Reserved + item.ModifiedTime = ReadUInt32(); + item.PackSize = ReadUInt32(); + item.Size = ReadUInt32(); + item.FileCRC = ReadUInt32(); + ReadUInt16(); // FilespecPositionInFilename + item.FileAccessMode = ReadUInt16(); + ReadByte(); // FirstChapter + ReadByte(); // LastChapter /* - UINT32 extraData; + UInt32 extraData; if ((header.Flags & NFileHeader::NFlags::kExtFile) != 0) - extraData = *(const UINT32 *)(_block + pos); + extraData = GetUInt32FromMemLE(_block + pos); */ - int pos = header.FirstHeaderSize; + _blockPos = firstHeaderSize; - for (; pos < _blockSize; pos++) - { - char aByte = _block[pos]; - if (aByte == 0) - break; - item.Name += aByte; - } + for (; _blockPos < _blockSize;) + item.Name += (char)ReadByte(); while(true) if (!ReadBlock()) diff --git a/7zip/Archive/Arj/ArjIn.h b/7zip/Archive/Arj/ArjIn.h index cdf495e8..b73d7dba 100755 --- a/7zip/Archive/Arj/ArjIn.h +++ b/7zip/Archive/Arj/ArjIn.h @@ -1,15 +1,11 @@ // Archive/ArjIn.h -#pragma once - #ifndef __ARCHIVE_ARJIN_H #define __ARCHIVE_ARJIN_H -#include "Common/Exception.h" #include "Common/MyCom.h" #include "../../IStream.h" -#include "Header.h" #include "ArjItem.h" namespace NArchive { @@ -27,42 +23,51 @@ public: kSeekStreamError } Cause; - CInArchiveException(CCauseType cause); + CInArchiveException(CCauseType cause): Cause(cause) {}; }; class CProgressVirt { public: - STDMETHOD(SetCompleted)(const UINT64 *numFiles) PURE; + STDMETHOD(SetCompleted)(const UInt64 *numFiles) PURE; }; class CInArchive { CMyComPtr<IInStream> _stream; - UINT64 _streamStartPosition; - UINT64 _position; - UINT16 _blockSize; - BYTE _block[kMaxBlockSize]; + UInt64 _streamStartPosition; + UInt64 _position; + UInt16 _blockSize; + Byte _block[kMaxBlockSize]; + UInt32 _blockPos; + - bool FindAndReadMarker(const UINT64 *searchHeaderSizeLimit); + bool FindAndReadMarker(const UInt64 *searchHeaderSizeLimit); bool ReadBlock(); bool ReadBlock2(); - HRESULT ReadBytes(void *data, UINT32 size, UINT32 *processedSize); - bool ReadBytesAndTestSize(void *data, UINT32 size); - void SafeReadBytes(void *data, UINT32 size); - - void IncreasePositionValue(UINT64 addValue); + Byte ReadByte(); + UInt16 ReadUInt16(); + UInt32 ReadUInt32(); + + HRESULT ReadBytes(void *data, UInt32 size, UInt32 *processedSize); + bool ReadBytesAndTestSize(void *data, UInt32 size); + void SafeReadBytes(void *data, UInt32 size); + Byte SafeReadByte(); + UInt16 SafeReadUInt16(); + UInt32 SafeReadUInt32(); + + void IncreasePositionValue(UInt64 addValue); void ThrowIncorrectArchiveException(); public: HRESULT GetNextItem(bool &filled, CItemEx &item); - bool Open(IInStream *inStream, const UINT64 *searchHeaderSizeLimit); + bool Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit); void Close(); - void IncreaseRealPosition(UINT64 addValue); + void IncreaseRealPosition(UInt64 addValue); }; }} diff --git a/7zip/Archive/Arj/ArjItem.h b/7zip/Archive/Arj/ArjItem.h index a1d0786c..d48fe38d 100755 --- a/7zip/Archive/Arj/ArjItem.h +++ b/7zip/Archive/Arj/ArjItem.h @@ -1,9 +1,7 @@ -// Archive/Arj/ItemInfo.h +// Archive/ArjItem.h -#pragma once - -#ifndef __ARCHIVE_ARJ_ITEMINFO_H -#define __ARCHIVE_ARJ_ITEMINFO_H +#ifndef __ARCHIVE_ARJ_ITEM_H +#define __ARCHIVE_ARJ_ITEM_H #include "Common/Types.h" #include "Common/String.h" @@ -14,8 +12,8 @@ namespace NArj { struct CVersion { - BYTE Version; - BYTE HostOS; + Byte Version; + Byte HostOS; }; inline bool operator==(const CVersion &v1, const CVersion &v2) @@ -26,29 +24,29 @@ inline bool operator!=(const CVersion &v1, const CVersion &v2) class CItem { public: - BYTE Version; - BYTE ExtractVersion; - BYTE HostOS; - BYTE Flags; - BYTE Method; - BYTE FileType; - UINT32 ModifiedTime; - UINT32 PackSize; - UINT32 Size; - UINT32 FileCRC; + Byte Version; + Byte ExtractVersion; + Byte HostOS; + Byte Flags; + Byte Method; + Byte FileType; + UInt32 ModifiedTime; + UInt32 PackSize; + UInt32 Size; + UInt32 FileCRC; - // UINT16 FilespecPositionInFilename; - UINT16 FileAccessMode; - // BYTE FirstChapter; - // BYTE LastChapter; + // UInt16 FilespecPositionInFilename; + UInt16 FileAccessMode; + // Byte FirstChapter; + // Byte LastChapter; AString Name; bool IsEncrypted() const { return (Flags & NFileHeader::NFlags::kGarbled) != 0; } bool IsDirectory() const { return (FileType == NFileHeader::NFileType::kDirectory); } - UINT32 GetWinAttributes() const + UInt32 GetWinAttributes() const { - DWORD winAtrributes; + UInt32 winAtrributes; switch(HostOS) { case NFileHeader::NHostOS::kMSDOS: @@ -67,7 +65,7 @@ public: class CItemEx: public CItem { public: - UINT64 DataPosition; + UInt64 DataPosition; }; }} diff --git a/7zip/Archive/Arj/DllExports.cpp b/7zip/Archive/Arj/DllExports.cpp index 8845ce06..abedc1f7 100755 --- a/7zip/Archive/Arj/DllExports.cpp +++ b/7zip/Archive/Arj/DllExports.cpp @@ -2,8 +2,7 @@ #include "StdAfx.h" -#include <initguid.h> - +#include "Common/MyInitGuid.h" #include "Common/ComTry.h" #include "Windows/PropVariant.h" #include "../../ICoder.h" @@ -63,6 +62,13 @@ STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) case NArchive::kKeepName: propVariant = false; break; + case NArchive::kStartSignature: + { + const unsigned char sig[] = { 0x60, 0xEA }; + if ((value->bstrVal = ::SysAllocStringByteLen((const char *)sig, 2)) != 0) + value->vt = VT_BSTR; + return S_OK; + } } propVariant.Detach(value); return S_OK; diff --git a/7zip/Archive/Arj/StdAfx.cpp b/7zip/Archive/Arj/StdAfx.cpp index 2550270c..d0feea85 100755 --- a/7zip/Archive/Arj/StdAfx.cpp +++ b/7zip/Archive/Arj/StdAfx.cpp @@ -1,3 +1,3 @@ // StdAfx.cpp -#include "stdafx.h" +#include "StdAfx.h" diff --git a/7zip/Archive/Arj/StdAfx.h b/7zip/Archive/Arj/StdAfx.h index 47001ee8..e7fb6986 100755 --- a/7zip/Archive/Arj/StdAfx.h +++ b/7zip/Archive/Arj/StdAfx.h @@ -1,9 +1,8 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> -#include <limits.h> +#include "../../../Common/MyWindows.h" -#endif +#endif diff --git a/7zip/Archive/Arj/resource.rc b/7zip/Archive/Arj/resource.rc index b90eaf91..b7943ad2 100755 --- a/7zip/Archive/Arj/resource.rc +++ b/7zip/Archive/Arj/resource.rc @@ -75,8 +75,8 @@ IDI_ICON1 ICON DISCARDABLE "arj.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,9,2,0 - PRODUCTVERSION 3,9,2,0 + FILEVERSION 4,13,0,0 + PRODUCTVERSION 4,13,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -94,14 +94,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Igor Pavlov\0" VALUE "FileDescription", "Arj Plugin for 7-Zip\0" - VALUE "FileVersion", "3, 9, 2, 0\0" + VALUE "FileVersion", "4, 13, 0, 0\0" VALUE "InternalName", "arj\0" - VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2004 Igor Pavlov\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "arj.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "7-Zip\0" - VALUE "ProductVersion", "3, 9, 2, 0\0" + VALUE "ProductVersion", "4, 13, 0, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/7zip/Archive/BZip2/BZip2.dsp b/7zip/Archive/BZip2/BZip2.dsp index c56ce1d6..9c1ac5e0 100755 --- a/7zip/Archive/BZip2/BZip2.dsp +++ b/7zip/Archive/BZip2/BZip2.dsp @@ -126,6 +126,14 @@ SOURCE=.\StdAfx.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\NewHandler.cpp # End Source File # Begin Source File @@ -134,12 +142,28 @@ SOURCE=..\..\..\Common\NewHandler.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\StringConvert.cpp # End Source File # Begin Source File SOURCE=..\..\..\Common\StringConvert.h # End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File # End Group # Begin Group "Windows" @@ -186,6 +210,10 @@ SOURCE=..\Common\CodecsPath.h # End Source File # Begin Source File +SOURCE=..\Common\CoderLoader.h +# End Source File +# Begin Source File + SOURCE=..\Common\DummyOutStream.cpp # End Source File # Begin Source File diff --git a/7zip/Archive/BZip2/BZip2Handler.cpp b/7zip/Archive/BZip2/BZip2Handler.cpp index 455add19..97ea155c 100755 --- a/7zip/Archive/BZip2/BZip2Handler.cpp +++ b/7zip/Archive/BZip2/BZip2Handler.cpp @@ -44,13 +44,13 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) return S_OK; } -STDMETHODIMP CHandler::GetNumberOfProperties(UINT32 *numProperties) +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) { *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); return S_OK; } -STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index, +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) { if(index >= sizeof(kProperties) / sizeof(kProperties[0])) @@ -62,25 +62,25 @@ STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index, return S_OK; } -STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UINT32 *numProperties) +STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) { *numProperties = 0; return S_OK; } -STDMETHODIMP CHandler::GetArchivePropertyInfo(UINT32 index, +STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) { return E_INVALIDARG; } -STDMETHODIMP CHandler::GetNumberOfItems(UINT32 *numItems) +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) { *numItems = 1; return S_OK; } -STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value) +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant propVariant; @@ -101,7 +101,7 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va } STDMETHODIMP CHandler::Open(IInStream *stream, - const UINT64 *maxCheckStartPosition, + const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) { COM_TRY_BEGIN @@ -109,15 +109,15 @@ STDMETHODIMP CHandler::Open(IInStream *stream, { RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_streamStartPosition)); const int kSignatureSize = 3; - BYTE buffer[kSignatureSize]; - UINT32 processedSize; + Byte buffer[kSignatureSize]; + UInt32 processedSize; RINOK(stream->Read(buffer, kSignatureSize, &processedSize)); if (processedSize != kSignatureSize) return S_FALSE; if (buffer[0] != 'B' || buffer[1] != 'Z' || buffer[2] != 'h') return S_FALSE; - UINT64 endPosition; + UInt64 endPosition; RINOK(stream->Seek(0, STREAM_SEEK_END, &endPosition)); _item.PackSize = endPosition - _streamStartPosition; @@ -138,11 +138,11 @@ STDMETHODIMP CHandler::Close() } -STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, - INT32 testModeSpec, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 testModeSpec, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - bool allFilesMode = (numItems == UINT32(-1)); + bool allFilesMode = (numItems == UInt32(-1)); if (!allFilesMode) { if (numItems == 0) @@ -157,12 +157,12 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, extractCallback->SetTotal(_item.PackSize); - UINT64 currentTotalPacked = 0; + UInt64 currentTotalPacked = 0, currentTotalUnPacked = 0; RINOK(extractCallback->SetCompleted(¤tTotalPacked)); CMyComPtr<ISequentialOutStream> realOutStream; - INT32 askMode; + Int32 askMode; askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract; @@ -171,8 +171,27 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, if(!testMode && !realOutStream) return S_OK; + extractCallback->PrepareOperation(askMode); + #ifndef COMPRESS_BZIP2 + CCoderLibrary lib; + #endif + CMyComPtr<ICompressCoder> decoder; + #ifdef COMPRESS_BZIP2 + decoder = new NCompress::NBZip2::CDecoder; + #else + HRESULT loadResult = lib.LoadAndCreateCoder( + GetBZip2CodecPath(), + CLSID_CCompressBZip2Decoder, &decoder); + if (loadResult != S_OK) + { + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + return S_OK; + } + #endif + + CDummyOutStream *outStreamSpec = new CDummyOutStream; CMyComPtr<ISequentialOutStream> outStream(outStreamSpec); outStreamSpec->Init(realOutStream); @@ -182,31 +201,72 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, CLocalProgress *localProgressSpec = new CLocalProgress; CMyComPtr<ICompressProgressInfo> progress = localProgressSpec; localProgressSpec->Init(extractCallback, true); + + CLocalCompressProgressInfo *localCompressProgressSpec = + new CLocalCompressProgressInfo; + CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec; RINOK(_stream->Seek(_streamStartPosition, STREAM_SEEK_SET, NULL)); - #ifndef COMPRESS_BZIP2 - CCoderLibrary lib; - #endif - CMyComPtr<ICompressCoder> decoder; - #ifdef COMPRESS_BZIP2 - decoder = new NCompress::NBZip2::CDecoder; - #else - RINOK(lib.LoadAndCreateCoder( - GetBZip2CodecPath(), - CLSID_CCompressBZip2Decoder, &decoder)); - #endif - HRESULT result = decoder->Code(_stream, outStream, NULL, NULL, progress); + HRESULT result; + + bool firstItem = true; + while(true) + { + localCompressProgressSpec->Init(progress, + ¤tTotalPacked, + ¤tTotalUnPacked); + + const int kSignatureSize = 3; + Byte buffer[kSignatureSize]; + UInt32 processedSize; + RINOK(_stream->Read(buffer, kSignatureSize, &processedSize)); + if (processedSize < kSignatureSize) + { + if (firstItem) + return E_FAIL; + break; + } + if (buffer[0] != 'B' || buffer[1] != 'Z' || buffer[2] != 'h') + { + if (firstItem) + return E_FAIL; + outStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)) + return S_OK; + } + firstItem = false; + + UInt64 dataStartPos; + RINOK(_stream->Seek((UInt64)(Int64)(-3), STREAM_SEEK_CUR, &dataStartPos)); + + result = decoder->Code(_stream, outStream, NULL, NULL, compressProgress); + + if (result != S_OK) + break; + + CMyComPtr<ICompressGetInStreamProcessedSize> getInStreamProcessedSize; + decoder.QueryInterface(IID_ICompressGetInStreamProcessedSize, + &getInStreamProcessedSize); + if (!getInStreamProcessedSize) + break; + + UInt64 packSize; + RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&packSize)); + UInt64 pos; + RINOK(_stream->Seek(dataStartPos + packSize, STREAM_SEEK_SET, &pos)); + currentTotalPacked = pos - _streamStartPosition; + } outStream.Release(); - if (result == S_FALSE) - RINOK(extractCallback->SetOperationResult( - NArchive::NExtract::NOperationResult::kDataError)) - else if (result == S_OK) - RINOK(extractCallback->SetOperationResult( - NArchive::NExtract::NOperationResult::kOK)) + + int retResult; + if (result == S_OK) + retResult = NArchive::NExtract::NOperationResult::kOK; else - return result; + retResult = NArchive::NExtract::NOperationResult::kDataError; + + RINOK(extractCallback->SetOperationResult(retResult)); return S_OK; COM_TRY_END diff --git a/7zip/Archive/BZip2/BZip2Handler.h b/7zip/Archive/BZip2/BZip2Handler.h index 0859fd44..8577d039 100755 --- a/7zip/Archive/BZip2/BZip2Handler.h +++ b/7zip/Archive/BZip2/BZip2Handler.h @@ -1,7 +1,5 @@ // BZip2/Handler.h -#pragma once - #ifndef __BZIP2_HANDLER_H #define __BZIP2_HANDLER_H @@ -15,45 +13,52 @@ namespace NBZip2 { class CHandler: public IInArchive, public IOutArchive, + public ISetProperties, public CMyUnknownImp { + CMyComPtr<IInStream> _stream; + NArchive::NBZip2::CItem _item; + UInt64 _streamStartPosition; + + UInt32 _numPasses; + void InitMethodProperties() { _numPasses = 1; } + public: - MY_UNKNOWN_IMP2( + MY_UNKNOWN_IMP3( IInArchive, - IOutArchive + IOutArchive, + ISetProperties ) STDMETHOD(Open)(IInStream *stream, - const UINT64 *maxCheckStartPosition, + const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback); STDMETHOD(Close)(); - STDMETHOD(GetNumberOfItems)(UINT32 *numItems); - STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(Extract)(const UINT32* indices, UINT32 numItems, - INT32 testMode, IArchiveExtractCallback *extractCallback); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback); STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); - STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties); - STDMETHOD(GetPropertyInfo)(UINT32 index, + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType); - STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties); - STDMETHOD(GetArchivePropertyInfo)(UINT32 index, + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType); - // IOutArchiveHandler - STDMETHOD(UpdateItems)(IOutStream *outStream, UINT32 numItems, + STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback); + STDMETHOD(GetFileTimeType)(UInt32 *type); - STDMETHOD(GetFileTimeType)(UINT32 *type); + // ISetProperties + STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties); -private: - CMyComPtr<IInStream> _stream; - NArchive::NBZip2::CItem _item; - UINT64 _streamStartPosition; + CHandler() { InitMethodProperties(); } }; }} diff --git a/7zip/Archive/BZip2/BZip2HandlerOut.cpp b/7zip/Archive/BZip2/BZip2HandlerOut.cpp index d1703e86..509b82a6 100755 --- a/7zip/Archive/BZip2/BZip2HandlerOut.cpp +++ b/7zip/Archive/BZip2/BZip2HandlerOut.cpp @@ -5,41 +5,40 @@ #include "BZip2Handler.h" #include "BZip2Update.h" -#include "Windows/FileFind.h" -#include "Windows/Defs.h" +#include "Common/Defs.h" +#include "Common/String.h" +#include "Common/StringToInt.h" #include "Windows/PropVariant.h" #include "../../Compress/Copy/CopyCoder.h" using namespace NWindows; -static const int kNumItemInArchive = 1; - namespace NArchive { namespace NBZip2 { -STDMETHODIMP CHandler::GetFileTimeType(UINT32 *type) +STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type) { *type = NFileTimeType::kUnix; return S_OK; } -static HRESULT CopyStreams(IInStream *inStream, IOutStream *outStream, - IArchiveUpdateCallback *updateCallback) +static HRESULT CopyStreams(ISequentialInStream *inStream, + ISequentialOutStream *outStream, IArchiveUpdateCallback *updateCallback) { CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder; return copyCoder->Code(inStream, outStream, NULL, NULL, NULL); } -STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems, +STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback) { if (numItems != 1) return E_INVALIDARG; - INT32 newData; - INT32 newProperties; - UINT32 indexInArchive; + Int32 newData; + Int32 newProperties; + UInt32 indexInArchive; if (!updateCallback) return E_FAIL; RINOK(updateCallback->GetUpdateItemInfo(0, @@ -49,17 +48,6 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems, { { NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(0, kpidAttributes, &propVariant)); - if (propVariant.vt == VT_UI4) - { - if (NFile::NFind::NAttributes::IsDirectory(propVariant.ulVal)) - return E_INVALIDARG; - } - else if (propVariant.vt != VT_EMPTY) - return E_INVALIDARG; - } - { - NCOM::CPropVariant propVariant; RINOK(updateCallback->GetProperty(0, kpidIsFolder, &propVariant)); if (propVariant.vt == VT_BOOL) { @@ -73,15 +61,15 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems, if (IntToBool(newData)) { - UINT64 size; + UInt64 size; { NCOM::CPropVariant propVariant; RINOK(updateCallback->GetProperty(0, kpidSize, &propVariant)); if (propVariant.vt != VT_UI8) return E_INVALIDARG; - size = *(UINT64 *)(&propVariant.uhVal); + size = propVariant.uhVal.QuadPart; } - return UpdateArchive(size, outStream, 0, updateCallback); + return UpdateArchive(size, outStream, 0, _numPasses, updateCallback); } if (indexInArchive != 0) return E_INVALIDARG; @@ -89,4 +77,83 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems, return CopyStreams(_stream, outStream, updateCallback); } +STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) +{ + InitMethodProperties(); + for (int i = 0; i < numProperties; i++) + { + UString name = UString(names[i]); + name.MakeUpper(); + if (name.IsEmpty()) + return E_INVALIDARG; + + const PROPVARIANT &value = values[i]; + + if (name[0] == 'X') + { + name.Delete(0); + UInt32 level = 9; + if (value.vt == VT_UI4) + { + if (!name.IsEmpty()) + return E_INVALIDARG; + level = value.ulVal; + } + else if (value.vt == VT_EMPTY) + { + if(!name.IsEmpty()) + { + const wchar_t *start = name; + const wchar_t *end; + UInt64 v = ConvertStringToUInt64(start, &end); + if (end - start != name.Length()) + return E_INVALIDARG; + level = (UInt32)v; + } + } + else + return E_INVALIDARG; + if (level < 7) + _numPasses = 1; + else if (level < 9) + _numPasses = 2; + else + _numPasses = 7; + continue; + } + else if (name.Left(4) == L"PASS") + { + name.Delete(0, 4); + UInt32 numPasses = 1; + if (value.vt == VT_UI4) + { + if (!name.IsEmpty()) + return E_INVALIDARG; + numPasses = value.ulVal; + } + else if (value.vt == VT_EMPTY) + { + if(!name.IsEmpty()) + { + const wchar_t *start = name; + const wchar_t *end; + UInt64 v = ConvertStringToUInt64(start, &end); + if (end - start != name.Length()) + return E_INVALIDARG; + numPasses = (UInt32)v; + } + } + else + return E_INVALIDARG; + + if (numPasses < 1 || numPasses > 10) + return E_INVALIDARG; + _numPasses = numPasses; + continue; + } + return E_INVALIDARG; + } + return S_OK; +} + }} diff --git a/7zip/Archive/BZip2/BZip2Item.h b/7zip/Archive/BZip2/BZip2Item.h index 604adee8..d7508ab9 100755 --- a/7zip/Archive/BZip2/BZip2Item.h +++ b/7zip/Archive/BZip2/BZip2Item.h @@ -1,7 +1,5 @@ // Archive/BZip2Item.h -#pragma once - #ifndef __ARCHIVE_BZIP2_ITEM_H #define __ARCHIVE_BZIP2_ITEM_H @@ -10,8 +8,8 @@ namespace NBZip2 { struct CItem { - UINT64 PackSize; - UINT64 UnPackSize; + UInt64 PackSize; + UInt64 UnPackSize; }; }} diff --git a/7zip/Archive/BZip2/BZip2Update.cpp b/7zip/Archive/BZip2/BZip2Update.cpp index 908140e5..114c79d1 100755 --- a/7zip/Archive/BZip2/BZip2Update.cpp +++ b/7zip/Archive/BZip2/BZip2Update.cpp @@ -2,9 +2,8 @@ #include "StdAfx.h" -#include "Common/Defs.h" -#include "Windows/Defs.h" #include "../../Common/ProgressUtils.h" +#include "Windows/PropVariant.h" #include "BZip2Update.h" @@ -21,17 +20,17 @@ extern CSysString GetBZip2CodecPath(); namespace NArchive { namespace NBZip2 { -HRESULT UpdateArchive(UINT64 unpackSize, - IOutStream *outStream, +HRESULT UpdateArchive(UInt64 unpackSize, + ISequentialOutStream *outStream, int indexInClient, + UInt32 numPasses, IArchiveUpdateCallback *updateCallback) { RINOK(updateCallback->SetTotal(unpackSize)); - - UINT64 complexity = 0; + UInt64 complexity = 0; RINOK(updateCallback->SetCompleted(&complexity)); - CMyComPtr<IInStream> fileInStream; + CMyComPtr<ISequentialInStream> fileInStream; RINOK(updateCallback->GetStream(indexInClient, &fileInStream)); @@ -49,6 +48,27 @@ HRESULT UpdateArchive(UINT64 unpackSize, RINOK(lib.LoadAndCreateCoder(GetBZip2CodecPath(), CLSID_CCompressBZip2Encoder, &encoder)); #endif + + CMyComPtr<ICompressSetCoderProperties> setCoderProperties; + encoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties); + if (setCoderProperties) + { + /* + NWindows::NCOM::CPropVariant properties[2] = + { + dictionary, numPasses + }; + PROPID propIDs[2] = + { + NCoderPropID::kDictionarySize, + NCoderPropID::kNumPasses, + }; + RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, 2)); + */ + NWindows::NCOM::CPropVariant property = numPasses; + PROPID propID = NCoderPropID::kNumPasses; + RINOK(setCoderProperties->SetCoderProperties(&propID, &property, 1)); + } RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, localProgress)); diff --git a/7zip/Archive/BZip2/BZip2Update.h b/7zip/Archive/BZip2/BZip2Update.h index 2ccdf492..5f40d752 100755 --- a/7zip/Archive/BZip2/BZip2Update.h +++ b/7zip/Archive/BZip2/BZip2Update.h @@ -1,21 +1,18 @@ // BZip2Update.h -#pragma once - #ifndef __BZIP2_UPDATE_H #define __BZIP2_UPDATE_H -#include "Common/Types.h" - #include "../IArchive.h" namespace NArchive { namespace NBZip2 { HRESULT UpdateArchive( - UINT64 unpackSize, - IOutStream *outStream, + UInt64 unpackSize, + ISequentialOutStream *outStream, int indexInClient, + UInt32 numPasses, IArchiveUpdateCallback *updateCallback); }} diff --git a/7zip/Archive/BZip2/DllExports.cpp b/7zip/Archive/BZip2/DllExports.cpp index 7a63ddfb..52e9cca4 100755 --- a/7zip/Archive/BZip2/DllExports.cpp +++ b/7zip/Archive/BZip2/DllExports.cpp @@ -2,10 +2,8 @@ #include "StdAfx.h" -#define INITGUID - +#include "Common/MyInitGuid.h" #include "Common/ComTry.h" -#include "Common/String.h" #include "Windows/PropVariant.h" #include "BZip2Handler.h" #include "../../ICoder.h" @@ -99,6 +97,14 @@ STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) case NArchive::kKeepName: propVariant = true; break; + case NArchive::kStartSignature: + { + const char sig[] = { 'B', 'Z', 'h' }; + if ((value->bstrVal = ::SysAllocStringByteLen(sig, 3)) != 0) + value->vt = VT_BSTR; + return S_OK; + } + } propVariant.Detach(value); return S_OK; diff --git a/7zip/Archive/BZip2/StdAfx.cpp b/7zip/Archive/BZip2/StdAfx.cpp index 2550270c..d0feea85 100755 --- a/7zip/Archive/BZip2/StdAfx.cpp +++ b/7zip/Archive/BZip2/StdAfx.cpp @@ -1,3 +1,3 @@ // StdAfx.cpp -#include "stdafx.h" +#include "StdAfx.h" diff --git a/7zip/Archive/BZip2/StdAfx.h b/7zip/Archive/BZip2/StdAfx.h index a32fbed6..e7fb6986 100755 --- a/7zip/Archive/BZip2/StdAfx.h +++ b/7zip/Archive/BZip2/StdAfx.h @@ -1,8 +1,8 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> +#include "../../../Common/MyWindows.h" -#endif +#endif diff --git a/7zip/Archive/BZip2/resource.rc b/7zip/Archive/BZip2/resource.rc index 3dba3fe0..48ee6c60 100755 --- a/7zip/Archive/BZip2/resource.rc +++ b/7zip/Archive/BZip2/resource.rc @@ -75,8 +75,8 @@ IDI_ICON1 ICON DISCARDABLE "bz2.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,12,0,0 - PRODUCTVERSION 3,12,0,0 + FILEVERSION 4,19,0,0 + PRODUCTVERSION 4,19,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -94,14 +94,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Igor Pavlov\0" VALUE "FileDescription", "BZip2 Plugin for 7-Zip\0" - VALUE "FileVersion", "3, 12, 0, 0\0" + VALUE "FileVersion", "4, 19, 0, 0\0" VALUE "InternalName", "bz2\0" - VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalTrademarks", "\0" - VALUE "OriginalFilename", "bz.dll\0" + VALUE "OriginalFilename", "bz2.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "7-Zip\0" - VALUE "ProductVersion", "3, 12, 0, 0\0" + VALUE "ProductVersion", "4, 19, 0, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/7zip/Archive/Cab/Cab.dsp b/7zip/Archive/Cab/Cab.dsp index 23ea022c..e025dcff 100755 --- a/7zip/Archive/Cab/Cab.dsp +++ b/7zip/Archive/Cab/Cab.dsp @@ -122,6 +122,22 @@ SOURCE=.\StdAfx.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\NewHandler.cpp # End Source File # Begin Source File @@ -319,6 +335,10 @@ SOURCE=..\..\Compress\LZ\LZOutWindow.h # End Group # Begin Source File +SOURCE=.\bitmap1.bmp +# End Source File +# Begin Source File + SOURCE=.\cab.ico # End Source File # End Target diff --git a/7zip/Archive/Cab/CabCopyDecoder.cpp b/7zip/Archive/Cab/CabCopyDecoder.cpp index 7e9c7ac8..541d4d93 100755 --- a/7zip/Archive/Cab/CabCopyDecoder.cpp +++ b/7zip/Archive/Cab/CabCopyDecoder.cpp @@ -9,51 +9,57 @@ namespace NArchive { namespace NCab { -static const UINT32 kBufferSize = 1 << 17; +static const UInt32 kBufferSize = 1 << 17; -/* void CCopyDecoder::ReleaseStreams() { m_InStream.ReleaseStream(); m_OutStream.ReleaseStream(); } -*/ + class CCopyDecoderFlusher { CCopyDecoder *m_Decoder; public: - CCopyDecoderFlusher(CCopyDecoder *aDecoder): m_Decoder(aDecoder) {} + CCopyDecoderFlusher(CCopyDecoder *decoder): m_Decoder(decoder) {} ~CCopyDecoderFlusher() { m_Decoder->Flush(); - // m_Decoder->ReleaseStreams(); + m_Decoder->ReleaseStreams(); } }; STDMETHODIMP CCopyDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UINT64 *inSize, const UINT64 *outSize, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { if (outSize == NULL) return E_INVALIDARG; - UINT64 size = *outSize; + UInt64 size = *outSize; + + if (!m_OutStream.Create(1 << 20)) + return E_OUTOFMEMORY; + if (!m_InStream.Create(1 << 20)) + return E_OUTOFMEMORY; - m_InStream.Init(inStream, m_ReservedSize, m_NumInDataBlocks); - m_OutStream.Init(outStream); + m_InStream.SetStream(inStream); + m_InStream.Init(m_ReservedSize, m_NumInDataBlocks); + m_OutStream.SetStream(outStream); + m_OutStream.Init(); CCopyDecoderFlusher decoderFlusher(this); - UINT64 nowPos64 = 0; + UInt64 nowPos64 = 0; while(nowPos64 < size) { - UINT32 blockSize; + UInt32 blockSize; bool dataAreCorrect; RINOK(m_InStream.ReadBlock(blockSize, dataAreCorrect)); if (!dataAreCorrect) { throw 123456; } - for (UINT32 i = 0; i < blockSize; i++) + for (UInt32 i = 0; i < blockSize; i++) m_OutStream.WriteByte(m_InStream.ReadByte()); nowPos64 += blockSize; if (progress != NULL) diff --git a/7zip/Archive/Cab/CabCopyDecoder.h b/7zip/Archive/Cab/CabCopyDecoder.h index d12cec95..21545d39 100755 --- a/7zip/Archive/Cab/CabCopyDecoder.h +++ b/7zip/Archive/Cab/CabCopyDecoder.h @@ -3,8 +3,6 @@ #ifndef __ARCHIVE_CAB_COPY_DECODER_H #define __ARCHIVE_CAB_COPY_DECODER_H -#pragma once - #include "Common/MyCom.h" #include "../../ICoder.h" #include "../../Common/OutBuffer.h" @@ -19,18 +17,18 @@ class CCopyDecoder: { CInBuffer m_InStream; COutBuffer m_OutStream; - BYTE m_ReservedSize; - UINT32 m_NumInDataBlocks; + Byte m_ReservedSize; + UInt32 m_NumInDataBlocks; public: MY_UNKNOWN_IMP STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UINT64 *inSize, const UINT64 *outSize, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - // void ReleaseStreams(); + void ReleaseStreams(); HRESULT Flush() { return m_OutStream.Flush(); } - void SetParams(BYTE reservedSize, UINT32 numInDataBlocks) + void SetParams(Byte reservedSize, UInt32 numInDataBlocks) { m_ReservedSize = reservedSize; m_NumInDataBlocks = numInDataBlocks; diff --git a/7zip/Archive/Cab/CabHandler.cpp b/7zip/Archive/Cab/CabHandler.cpp index 038f108a..669de218 100755 --- a/7zip/Archive/Cab/CabHandler.cpp +++ b/7zip/Archive/Cab/CabHandler.cpp @@ -1,18 +1,19 @@ // Cab/Handler.cpp -#include "stdafx.h" +#include "StdAfx.h" #include "Common/StringConvert.h" #include "Common/Defs.h" #include "Common/UTFConvert.h" #include "Common/ComTry.h" +#include "Common/IntToString.h" #include "Windows/PropVariant.h" #include "Windows/Time.h" #include "CabCopyDecoder.h" #include "LZXDecoder.h" -#include "MSZIPDecoder.h" +#include "MSZipDecoder.h" #include "CabHandler.h" @@ -57,13 +58,13 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) return S_OK; } -STDMETHODIMP CHandler::GetNumberOfProperties(UINT32 *numProperties) +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) { *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); return S_OK; } -STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index, +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) { if(index >= sizeof(kProperties) / sizeof(kProperties[0])) @@ -75,19 +76,19 @@ STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index, return S_OK; } -STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UINT32 *numProperties) +STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) { *numProperties = 0; return S_OK; } -STDMETHODIMP CHandler::GetArchivePropertyInfo(UINT32 index, +STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) { return E_INVALIDARG; } -STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value) +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant propVariant; @@ -107,7 +108,7 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va propVariant = MultiByteToUnicodeString(fileInfo.Name, CP_ACP); break; case kpidIsFolder: - propVariant = false; + propVariant = fileInfo.IsDirectory(); break; case kpidSize: propVariant = fileInfo.UnPackSize; @@ -131,7 +132,7 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va case kpidMethod: { - UINT16 realFolderIndex = NHeader::NFolderIndex::GetRealFolderIndex( + UInt16 realFolderIndex = NHeader::NFolderIndex::GetRealFolderIndex( m_Folders.Size(), fileInfo.FolderIndex); const NHeader::CFolder &folder = m_Folders[realFolderIndex]; UString method; @@ -144,14 +145,14 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va { method += L":"; wchar_t temp[32]; - _itow (folder.CompressionTypeMinor, temp, 10); + ConvertUInt64ToString(folder.CompressionTypeMinor, temp); method += temp; } propVariant = method; break; } case kpidBlock: - propVariant = UINT32(fileInfo.FolderIndex); + propVariant = UInt32(fileInfo.FolderIndex); break; } propVariant.Detach(value); @@ -163,20 +164,20 @@ class CPropgressImp: public CProgressVirt { CMyComPtr<IArchiveOpenCallback> m_OpenArchiveCallback; public: - STDMETHOD(SetTotal)(const UINT64 *numFiles); - STDMETHOD(SetCompleted)(const UINT64 *numFiles); + STDMETHOD(SetTotal)(const UInt64 *numFiles); + STDMETHOD(SetCompleted)(const UInt64 *numFiles); void Init(IArchiveOpenCallback *openArchiveCallback) { m_OpenArchiveCallback = openArchiveCallback; } }; -STDMETHODIMP CPropgressImp::SetTotal(const UINT64 *numFiles) +STDMETHODIMP CPropgressImp::SetTotal(const UInt64 *numFiles) { if (m_OpenArchiveCallback) return m_OpenArchiveCallback->SetCompleted(numFiles, NULL); return S_OK; } -STDMETHODIMP CPropgressImp::SetCompleted(const UINT64 *numFiles) +STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles) { if (m_OpenArchiveCallback) return m_OpenArchiveCallback->SetCompleted(numFiles, NULL); @@ -184,7 +185,7 @@ STDMETHODIMP CPropgressImp::SetCompleted(const UINT64 *numFiles) } STDMETHODIMP CHandler::Open(IInStream *inStream, - const UINT64 *maxCheckStartPosition, + const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) { COM_TRY_BEGIN @@ -222,8 +223,8 @@ class CCabFolderOutStream: public: MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize); - STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize); + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); private: const CObjectVector<NHeader::CFolder> *m_Folders; const CObjectVector<CItem> *m_Files; @@ -232,17 +233,17 @@ private: int m_StartIndex; int m_CurrentIndex; int m_NumFiles; - UINT64 m_CurrentDataPos; + UInt64 m_CurrentDataPos; CMyComPtr<IArchiveExtractCallback> m_ExtractCallback; bool m_TestMode; bool m_FileIsOpen; CMyComPtr<ISequentialOutStream> realOutStream; - UINT64 m_FilePos; + UInt64 m_FilePos; HRESULT OpenFile(int indexIndex, ISequentialOutStream **realOutStream); HRESULT WriteEmptyFiles(); - UINT64 m_StartImportantTotalUnPacked; + UInt64 m_StartImportantTotalUnPacked; public: void Init( const CObjectVector<NHeader::CFolder> *folders, @@ -252,7 +253,7 @@ public: int startIndex, int numFiles, IArchiveExtractCallback *extractCallback, - UINT64 startImportantTotalUnPacked, + UInt64 startImportantTotalUnPacked, bool testMode); HRESULT FlushCorrupted(); HRESULT Unsupported(); @@ -266,7 +267,7 @@ void CCabFolderOutStream::Init( int startIndex, int numFiles, IArchiveExtractCallback *extractCallback, - UINT64 startImportantTotalUnPacked, + UInt64 startImportantTotalUnPacked, bool testMode) { m_Folders = folders; @@ -289,7 +290,7 @@ HRESULT CCabFolderOutStream::OpenFile(int indexIndex, ISequentialOutStream **rea int fullIndex = m_StartIndex + indexIndex; - INT32 askMode; + Int32 askMode; if((*m_ExtractStatuses)[fullIndex]) askMode = m_TestMode ? NArchive::NExtract::NAskMode::kTest : @@ -299,12 +300,12 @@ HRESULT CCabFolderOutStream::OpenFile(int indexIndex, ISequentialOutStream **rea int index = (*m_FileIndexes)[fullIndex]; const CItem &fileInfo = (*m_Files)[index]; - UINT16 realFolderIndex = NHeader::NFolderIndex::GetRealFolderIndex( + UInt16 realFolderIndex = NHeader::NFolderIndex::GetRealFolderIndex( m_Folders->Size(), fileInfo.FolderIndex); RINOK(m_ExtractCallback->GetStream(index, realOutStream, askMode)); - UINT64 currentUnPackSize = fileInfo.UnPackSize; + UInt64 currentUnPackSize = fileInfo.UnPackSize; bool mustBeProcessedAnywhere = (indexIndex < m_NumFiles - 1); @@ -345,28 +346,28 @@ HRESULT CCabFolderOutStream::WriteEmptyFiles() } STDMETHODIMP CCabFolderOutStream::Write(const void *data, - UINT32 size, UINT32 *processedSize) + UInt32 size, UInt32 *processedSize) { - UINT32 processedSizeReal = 0; + UInt32 processedSizeReal = 0; while(m_CurrentIndex < m_NumFiles) { if (m_FileIsOpen) { int index = (*m_FileIndexes)[m_StartIndex + m_CurrentIndex]; const CItem &fileInfo = (*m_Files)[index]; - UINT64 fileSize = fileInfo.UnPackSize; + UInt64 fileSize = fileInfo.UnPackSize; - UINT32 numBytesToWrite = (UINT32)MyMin(fileSize - m_FilePos, - UINT64(size - processedSizeReal)); + UInt32 numBytesToWrite = (UInt32)MyMin(fileSize - m_FilePos, + UInt64(size - processedSizeReal)); - UINT32 processedSizeLocal; + UInt32 processedSizeLocal; if (!realOutStream) { processedSizeLocal = numBytesToWrite; } else { - RINOK(realOutStream->Write((const BYTE *)data + processedSizeReal, numBytesToWrite, &processedSizeLocal)); + RINOK(realOutStream->Write((const Byte *)data + processedSizeReal, numBytesToWrite, &processedSizeLocal)); } m_FilePos += processedSizeLocal; processedSizeReal += processedSizeLocal; @@ -401,14 +402,14 @@ STDMETHODIMP CCabFolderOutStream::Write(const void *data, HRESULT CCabFolderOutStream::FlushCorrupted() { - // UINT32 processedSizeReal = 0; + // UInt32 processedSizeReal = 0; while(m_CurrentIndex < m_NumFiles) { if (m_FileIsOpen) { int index = (*m_FileIndexes)[m_StartIndex + m_CurrentIndex]; const CItem &fileInfo = (*m_Files)[index]; - UINT64 fileSize = fileInfo.UnPackSize; + UInt64 fileSize = fileInfo.UnPackSize; realOutStream.Release(); RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kCRCError)); @@ -441,29 +442,29 @@ HRESULT CCabFolderOutStream::Unsupported() } STDMETHODIMP CCabFolderOutStream::WritePart(const void *data, - UINT32 size, UINT32 *processedSize) + UInt32 size, UInt32 *processedSize) { return Write(data, size, processedSize); } -STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, - INT32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - bool allFilesMode = (numItems == UINT32(-1)); + bool allFilesMode = (numItems == UInt32(-1)); if (allFilesMode) numItems = m_Files.Size(); if(numItems == 0) return S_OK; bool testMode = (_aTestMode != 0); - UINT64 censoredTotalUnPacked = 0, importantTotalUnPacked = 0; + UInt64 censoredTotalUnPacked = 0, importantTotalUnPacked = 0; int lastIndex = 0; CRecordVector<int> folderIndexes; CRecordVector<int> importantIndices; CRecordVector<bool> extractStatuses; - UINT32 i; + UInt32 i; for(i = 0; i < numItems; i++) { int index = allFilesMode ? i : indices[i]; @@ -479,7 +480,8 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, folderIndexes.Add(folderIndex); } - for(int j = index - 1; j >= lastIndex; j--) + int j; + for(j = index - 1; j >= lastIndex; j--) if(m_Files[j].FolderIndex != folderIndex) break; for(j++; j <= index; j++) @@ -493,8 +495,8 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, } extractCallback->SetTotal(importantTotalUnPacked); - UINT64 currentImportantTotalUnPacked = 0; - UINT64 currentImportantTotalPacked = 0; + UInt64 currentImportantTotalUnPacked = 0; + UInt64 currentImportantTotalPacked = 0; CCopyDecoder *storeDecoderSpec = NULL; CMyComPtr<ICompressCoder> storeDecoder; @@ -507,16 +509,17 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, int curImportantIndexIndex = 0; - UINT64 totalFolderUnPacked; - for(i = 0; i < (UINT32)folderIndexes.Size(); i++, currentImportantTotalUnPacked += totalFolderUnPacked) + UInt64 totalFolderUnPacked; + for(i = 0; i < (UInt32)folderIndexes.Size(); i++, currentImportantTotalUnPacked += totalFolderUnPacked) { int folderIndex = folderIndexes[i]; - UINT16 realFolderIndex = NHeader::NFolderIndex::GetRealFolderIndex( + UInt16 realFolderIndex = NHeader::NFolderIndex::GetRealFolderIndex( m_Folders.Size(), folderIndex); RINOK(extractCallback->SetCompleted(¤tImportantTotalUnPacked)); totalFolderUnPacked = 0; - for (int j = curImportantIndexIndex; j < importantIndices.Size(); j++) + int j; + for (j = curImportantIndexIndex; j < importantIndices.Size(); j++) { const CItem &fileInfo = m_Files[importantIndices[j]]; if (fileInfo.FolderIndex != folderIndex) @@ -537,7 +540,7 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, curImportantIndexIndex = j; - UINT64 pos = folder.DataStart; // test it (+ archiveStart) + UInt64 pos = folder.DataStart; // test it (+ archiveStart) RINOK(m_Stream->Seek(pos, STREAM_SEEK_SET, NULL)); CLocalProgress *localProgressSpec = new CLocalProgress; @@ -550,7 +553,7 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, localCompressProgressSpec->Init(progress, NULL, ¤tImportantTotalUnPacked); - BYTE reservedSize = m_ArchiveInfo.ReserveBlockPresent() ? + Byte reservedSize = m_ArchiveInfo.ReserveBlockPresent() ? m_ArchiveInfo.PerDataSizes.PerDatablockAreaSize : 0; switch(folder.GetCompressionMethod()) @@ -625,7 +628,7 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, COM_TRY_END } -STDMETHODIMP CHandler::GetNumberOfItems(UINT32 *numItems) +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) { COM_TRY_BEGIN *numItems = m_Files.Size(); diff --git a/7zip/Archive/Cab/CabHandler.h b/7zip/Archive/Cab/CabHandler.h index dad44eb4..584dadf8 100755 --- a/7zip/Archive/Cab/CabHandler.h +++ b/7zip/Archive/Cab/CabHandler.h @@ -1,7 +1,5 @@ // CabHandler.h -#pragma once - #ifndef __CAB_HANDLER_H #define __CAB_HANDLER_H @@ -20,22 +18,22 @@ public: MY_UNKNOWN_IMP STDMETHOD(Open)(IInStream *stream, - const UINT64 *maxCheckStartPosition, + const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback); STDMETHOD(Close)(); - STDMETHOD(GetNumberOfItems)(UINT32 *numItems); - STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(Extract)(const UINT32* indices, UINT32 numItems, - INT32 testMode, IArchiveExtractCallback *extractCallback); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback); STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); - STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties); - STDMETHOD(GetPropertyInfo)(UINT32 index, + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType); - STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties); - STDMETHOD(GetArchivePropertyInfo)(UINT32 index, + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType); private: diff --git a/7zip/Archive/Cab/CabHeader.cpp b/7zip/Archive/Cab/CabHeader.cpp index 01cdc9ee..d6d304eb 100755 --- a/7zip/Archive/Cab/CabHeader.cpp +++ b/7zip/Archive/Cab/CabHeader.cpp @@ -10,7 +10,7 @@ namespace NHeader{ namespace NArchive { -UINT32 kSignature = 0x4643534d + 1; +UInt32 kSignature = 0x4643534d + 1; static class CSignatureInitializer { public: CSignatureInitializer() { kSignature--; }} g_SignatureInitializer; diff --git a/7zip/Archive/Cab/CabHeader.h b/7zip/Archive/Cab/CabHeader.h index f9904a0a..2eac96bf 100755 --- a/7zip/Archive/Cab/CabHeader.h +++ b/7zip/Archive/Cab/CabHeader.h @@ -1,22 +1,17 @@ // Archive/Cab/Header.h -#pragma once - #ifndef __ARCHIVE_CAB_HEADER_H #define __ARCHIVE_CAB_HEADER_H #include "Common/Types.h" -#pragma pack(push, PragmaCabHeaders) -#pragma pack(push, 1) - namespace NArchive { namespace NCab { namespace NHeader{ namespace NArchive { - extern UINT32 kSignature; + extern UInt32 kSignature; namespace NFlags { @@ -25,55 +20,61 @@ namespace NArchive { const int kReservePresent = 0x0004; } + const UInt32 kArchiveHeaderSize = 36; + /* struct CBlock { - UINT32 Signature; /* cabinet file signature */ - UINT32 Reserved1; /* reserved */ - UINT32 Size; /* size of this cabinet file in bytes */ - UINT32 Reserved2; /* reserved */ - UINT32 FileOffset; /* offset of the first CFFILE entry */ - UINT32 Reserved3; /* reserved */ - BYTE VersionMinor; /* cabinet file format version, minor */ - BYTE VersionMajor; /* cabinet file format version, major */ - UINT16 NumFolders; /* number of CFFOLDER entries in this cabinet */ - UINT16 NumFiles; /* number of CFFILE entries in this cabinet */ - UINT16 Flags; /* cabinet file option indicators */ - UINT16 SetID; /* must be the same for all cabinets in a set */ - UINT16 CabinetNumber; /* number of this cabinet file in a set */ + UInt32 Signature; // cabinet file signature + UInt32 Reserved1; // reserved + UInt32 Size; // size of this cabinet file in bytes + UInt32 Reserved2; // reserved + UInt32 FileOffset; // offset of the first CFFILE entry + UInt32 Reserved3; // reserved + Byte VersionMinor; // cabinet file format version, minor + Byte VersionMajor; // cabinet file format version, major + UInt16 NumFolders; // number of CFFOLDER entries in this cabinet + UInt16 NumFiles; // number of CFFILE entries in this cabinet + UInt16 Flags; // cabinet file option indicators + UInt16 SetID; // must be the same for all cabinets in a set + UInt16 CabinetNumber; // number of this cabinet file in a set }; + */ + + const UInt32 kPerDataSizesHeaderSize = 4; struct CPerDataSizes { - UINT16 PerCabinetAreaSize; /* (optional) size of per-cabinet reserved area */ - BYTE PerFolderAreaSize; /* (optional) size of per-folder reserved area */ - BYTE PerDatablockAreaSize; /* (optional) size of per-datablock reserved area */ + UInt16 PerCabinetAreaSize; // (optional) size of per-cabinet reserved area + Byte PerFolderAreaSize; // (optional) size of per-folder reserved area + Byte PerDatablockAreaSize; // (optional) size of per-datablock reserved area }; /* - BYTE abReserve[]; // (optional) per-cabinet reserved area - BYTE szCabinetPrev[]; // (optional) name of previous cabinet file - BYTE szDiskPrev[]; // (optional) name of previous disk - BYTE szCabinetNext[]; // (optional) name of next cabinet file - BYTE szDiskNext[]; // (optional) name of next disk + Byte abReserve[]; // (optional) per-cabinet reserved area + Byte szCabinetPrev[]; // (optional) name of previous cabinet file + Byte szDiskPrev[]; // (optional) name of previous disk + Byte szCabinetNext[]; // (optional) name of next cabinet file + Byte szDiskNext[]; // (optional) name of next disk */ } namespace NCompressionMethodMajor { - const BYTE kNone = 0; - const BYTE kMSZip = 1; - const BYTE kQuantum = 2; - const BYTE kLZX = 3; + const Byte kNone = 0; + const Byte kMSZip = 1; + const Byte kQuantum = 2; + const Byte kLZX = 3; } +const UInt32 kFolderHeaderSize = 8; struct CFolder { - UINT32 DataStart; // offset of the first CFDATA block in this folder - UINT16 NumDataBlocks; // number of CFDATA blocks in this folder - BYTE CompressionTypeMajor; - BYTE CompressionTypeMinor; - // BYTE abReserve[]; // (optional) per-folder reserved area - BYTE GetCompressionMethod() const { return CompressionTypeMajor & 0xF; } + UInt32 DataStart; // offset of the first CFDATA block in this folder + UInt16 NumDataBlocks; // number of CFDATA blocks in this folder + Byte CompressionTypeMajor; + Byte CompressionTypeMinor; + // Byte abReserve[]; // (optional) per-folder reserved area + Byte GetCompressionMethod() const { return CompressionTypeMajor & 0xF; } }; const int kFileNameIsUTFAttributeMask = 0x80; @@ -83,7 +84,7 @@ namespace NFolderIndex const int kContinuedFromPrev = 0xFFFD; const int kContinuedToNext = 0xFFFE; const int kContinuedPrevAndNext = 0xFFFF; - inline UINT16 GetRealFolderIndex(UINT16 aNumFolders, UINT16 aFolderIndex) + inline UInt16 GetRealFolderIndex(UInt16 aNumFolders, UInt16 aFolderIndex) { switch(aFolderIndex) { @@ -98,20 +99,19 @@ namespace NFolderIndex } } +const UInt32 kFileHeaderSize = 16; +/* struct CFile { - UINT32 UnPackSize; /* uncompressed size of this file in bytes */ - UINT32 UnPackOffset; /* uncompressed offset of this file in the folder */ - UINT16 FolderIndex; /* index into the CFFOLDER area */ - UINT16 PureDate; - UINT16 PureTime; /* Time */ - UINT16 Attributes; /* attribute flags for this file */ - //BYTE szName[]; /* name of this file */ + UInt32 UnPackSize; // uncompressed size of this file in bytes + UInt32 UnPackOffset; // uncompressed offset of this file in the folder + UInt16 FolderIndex; // index into the CFFOLDER area + UInt16 PureDate; + UInt16 PureTime; // Time + UInt16 Attributes; // attribute flags for this file + Byte szName[]; // name of this file }; - +*/ }}} -#pragma pack(pop) -#pragma pack(pop, PragmaCabHeaders) - #endif diff --git a/7zip/Archive/Cab/CabIn.cpp b/7zip/Archive/Cab/CabIn.cpp index fcde9f4d..750b55c2 100755 --- a/7zip/Archive/Cab/CabIn.cpp +++ b/7zip/Archive/Cab/CabIn.cpp @@ -11,38 +11,38 @@ namespace NArchive{ namespace NCab{ -static HRESULT ReadBytes(IInStream *inStream, void *data, UINT32 size) +static HRESULT ReadBytes(IInStream *inStream, void *data, UInt32 size) { - UINT32 realProcessedSize; + UInt32 realProcessedSize; RINOK(inStream->Read(data, size, &realProcessedSize)); if(realProcessedSize != size) return S_FALSE; return S_OK; } -static HRESULT SafeRead(IInStream *inStream, void *data, UINT32 size) +static HRESULT SafeRead(IInStream *inStream, void *data, UInt32 size) { - UINT32 realProcessedSize; + UInt32 realProcessedSize; RINOK(inStream->Read(data, size, &realProcessedSize)); if(realProcessedSize != size) throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive); return S_OK; } -static void SafeInByteRead(CInBuffer &inBuffer, void *data, UINT32 size) +static void SafeInByteRead(::CInBuffer &inBuffer, void *data, UInt32 size) { - UINT32 realProcessedSize; + UInt32 realProcessedSize; inBuffer.ReadBytes(data, size, realProcessedSize); if(realProcessedSize != size) throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive); } -static void SafeReadName(CInBuffer &inBuffer, AString &name) +static void SafeReadName(::CInBuffer &inBuffer, AString &name) { name.Empty(); while(true) { - BYTE b; + Byte b; if (!inBuffer.ReadByte(b)) throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive); if (b == 0) @@ -51,31 +51,63 @@ static void SafeReadName(CInBuffer &inBuffer, AString &name) } } +Byte CInArchive::ReadByte() +{ + if (_blockPos >= _blockSize) + throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive); + return _block[_blockPos++]; +} + +UInt16 CInArchive::ReadUInt16() +{ + UInt16 value = 0; + for (int i = 0; i < 2; i++) + { + Byte b = ReadByte(); + value |= (UInt16(b) << (8 * i)); + } + return value; +} + +UInt32 CInArchive::ReadUInt32() +{ + UInt32 value = 0; + for (int i = 0; i < 4; i++) + { + Byte b = ReadByte(); + value |= (UInt32(b) << (8 * i)); + } + return value; +} + HRESULT CInArchive::Open(IInStream *inStream, - const UINT64 *searchHeaderSizeLimit, + const UInt64 *searchHeaderSizeLimit, CInArchiveInfo &inArchiveInfo, CObjectVector<NHeader::CFolder> &folders, CObjectVector<CItem> &files, CProgressVirt *progressVirt) { - UINT64 startPosition; + UInt64 startPosition; RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &startPosition)); - NHeader::NArchive::CBlock archiveHeader; + // NHeader::NArchive::CBlock archiveHeader; { - CInBuffer inBuffer; - inBuffer.Init(inStream); - UINT64 value = 0; - const int kSignatureSize = sizeof(value); - UINT64 kSignature64 = NHeader::NArchive::kSignature; + ::CInBuffer inBuffer; + if (!inBuffer.Create(1 << 17)) + return E_OUTOFMEMORY; + inBuffer.SetStream(inStream); + inBuffer.Init(); + UInt64 value = 0; + const int kSignatureSize = 8; + UInt64 kSignature64 = NHeader::NArchive::kSignature; while(true) { - BYTE b; + Byte b; if (!inBuffer.ReadByte(b)) return S_FALSE; value >>= 8; - value |= ((UINT64)b) << ((kSignatureSize - 1) * 8); + value |= ((UInt64)b) << ((kSignatureSize - 1) * 8); if (inBuffer.GetProcessedSize() >= kSignatureSize) { if (value == kSignature64) @@ -88,40 +120,59 @@ HRESULT CInArchive::Open(IInStream *inStream, startPosition += inBuffer.GetProcessedSize() - kSignatureSize; } RINOK(inStream->Seek(startPosition, STREAM_SEEK_SET, NULL)); - RINOK(ReadBytes(inStream, &archiveHeader, sizeof(archiveHeader))); + + RINOK(ReadBytes(inStream, _block, NHeader::NArchive::kArchiveHeaderSize)); + _blockSize = NHeader::NArchive::kArchiveHeaderSize; + _blockPos = 0; + + ReadUInt32(); // Signature; // cabinet file signature // if (archiveHeader.Signature != NHeader::NArchive::kSignature) // return S_FALSE; - - if (archiveHeader.Reserved1 != 0 || - archiveHeader.Reserved2 != 0 || - archiveHeader.Reserved3 != 0) - throw CInArchiveException(CInArchiveException::kUnsupported); - inArchiveInfo.VersionMinor = archiveHeader.VersionMinor; - inArchiveInfo.VersionMajor = archiveHeader.VersionMajor; - inArchiveInfo.NumFolders = archiveHeader.NumFolders; - inArchiveInfo.NumFiles = archiveHeader.NumFiles; - inArchiveInfo.Flags = archiveHeader.Flags; + UInt32 reserved1 = ReadUInt32(); + UInt32 size = ReadUInt32(); // size of this cabinet file in bytes + UInt32 reserved2 = ReadUInt32(); + UInt32 fileOffset = ReadUInt32(); // offset of the first CFFILE entry + UInt32 reserved3 = ReadUInt32(); + + inArchiveInfo.VersionMinor = ReadByte(); // cabinet file format version, minor + inArchiveInfo.VersionMajor = ReadByte(); // cabinet file format version, major + inArchiveInfo.NumFolders = ReadUInt16(); // number of CFFOLDER entries in this cabinet + inArchiveInfo.NumFiles = ReadUInt16(); // number of CFFILE entries in this cabinet + inArchiveInfo.Flags = ReadUInt16(); // number of CFFILE entries in this cabinet + UInt16 setID = ReadUInt16(); // must be the same for all cabinets in a set + UInt16 cabinetNumber = ReadUInt16(); // number of this cabinet file in a set + + if (reserved1 != 0 || reserved2 != 0 || reserved3 != 0) + throw CInArchiveException(CInArchiveException::kUnsupported); if (inArchiveInfo.ReserveBlockPresent()) { - RINOK(SafeRead(inStream, &inArchiveInfo.PerDataSizes, - sizeof(inArchiveInfo.PerDataSizes))); + RINOK(SafeRead(inStream, _block, NHeader::NArchive::kPerDataSizesHeaderSize)); + _blockSize = NHeader::NArchive::kPerDataSizesHeaderSize; + _blockPos = 0; + + inArchiveInfo.PerDataSizes.PerCabinetAreaSize = ReadUInt16(); // (optional) size of per-cabinet reserved area + inArchiveInfo.PerDataSizes.PerFolderAreaSize = ReadByte(); // (optional) size of per-folder reserved area + inArchiveInfo.PerDataSizes.PerDatablockAreaSize = ReadByte(); // (optional) size of per-datablock reserved area RINOK(inStream->Seek(inArchiveInfo.PerDataSizes.PerCabinetAreaSize, STREAM_SEEK_CUR, NULL)); } { - UINT64 foldersStartPosition; + UInt64 foldersStartPosition; RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &foldersStartPosition)); - CInBuffer inBuffer; - inBuffer.Init(inStream); - if ((archiveHeader.Flags & NHeader::NArchive::NFlags::kPrevCabinet) != 0) + ::CInBuffer inBuffer; + if (!inBuffer.Create(1 << 17)) + return E_OUTOFMEMORY; + inBuffer.SetStream(inStream); + inBuffer.Init(); + if ((inArchiveInfo.Flags & NHeader::NArchive::NFlags::kPrevCabinet) != 0) { SafeReadName(inBuffer, inArchiveInfo.PreviousCabinetName); SafeReadName(inBuffer, inArchiveInfo.PreviousDiskName); } - if ((archiveHeader.Flags & NHeader::NArchive::NFlags::kNextCabinet) != 0) + if ((inArchiveInfo.Flags & NHeader::NArchive::NFlags::kNextCabinet) != 0) { SafeReadName(inBuffer, inArchiveInfo.NextCabinetName); SafeReadName(inBuffer, inArchiveInfo.NextDiskName); @@ -132,54 +183,69 @@ HRESULT CInArchive::Open(IInStream *inStream, if (progressVirt != NULL) { - UINT64 numFiles = archiveHeader.NumFiles; + UInt64 numFiles = inArchiveInfo.NumFiles; RINOK(progressVirt->SetTotal(&numFiles)); } folders.Clear(); - for(int i = 0; i < archiveHeader.NumFolders; i++) + int i; + for(i = 0; i < inArchiveInfo.NumFolders; i++) { if (progressVirt != NULL) { - UINT64 numFiles = 0; + UInt64 numFiles = 0; RINOK(progressVirt->SetCompleted(&numFiles)); } NHeader::CFolder folder; - RINOK(SafeRead(inStream, &folder, sizeof(folder))); + RINOK(SafeRead(inStream, _block, NHeader::kFolderHeaderSize)); + _blockSize = NHeader::kFolderHeaderSize; + _blockPos = 0; + + folder.DataStart = ReadUInt32(); + folder.NumDataBlocks = ReadUInt16(); + folder.CompressionTypeMajor = ReadByte(); + folder.CompressionTypeMinor = ReadByte(); + if (inArchiveInfo.ReserveBlockPresent()) { RINOK(inStream->Seek( inArchiveInfo.PerDataSizes.PerFolderAreaSize, STREAM_SEEK_CUR, NULL)); } - folder.DataStart += (UINT32)startPosition; + folder.DataStart += (UInt32)startPosition; folders.Add(folder); } - RINOK(inStream->Seek(startPosition + archiveHeader.FileOffset, + RINOK(inStream->Seek(startPosition + fileOffset, STREAM_SEEK_SET, NULL)); - CInBuffer inBuffer; - inBuffer.Init(inStream); + ::CInBuffer inBuffer; + if (!inBuffer.Create(1 << 17)) + return E_OUTOFMEMORY; + inBuffer.SetStream(inStream); + inBuffer.Init(); files.Clear(); if (progressVirt != NULL) { - UINT64 numFiles = files.Size(); + UInt64 numFiles = files.Size(); RINOK(progressVirt->SetCompleted(&numFiles)); } - for(i = 0; i < archiveHeader.NumFiles; i++) + for(i = 0; i < inArchiveInfo.NumFiles; i++) { - NHeader::CFile fileHeader; - SafeInByteRead(inBuffer, &fileHeader, sizeof(fileHeader)); + SafeInByteRead(inBuffer, _block, NHeader::kFileHeaderSize); + _blockSize = NHeader::kFileHeaderSize; + _blockPos = 0; CItem item; - item.UnPackSize = fileHeader.UnPackSize; - item.UnPackOffset = fileHeader.UnPackOffset; - item.FolderIndex = fileHeader.FolderIndex; - item.Time = ((UINT32(fileHeader.PureDate) << 16)) | fileHeader.PureTime; - item.Attributes = fileHeader.Attributes; + item.UnPackSize = ReadUInt32(); + item.UnPackOffset = ReadUInt32(); + item.FolderIndex = ReadUInt16(); + UInt16 pureDate = ReadUInt16(); + UInt16 pureTime = ReadUInt16(); + item.Time = ((UInt32(pureDate) << 16)) | pureTime; + item.Attributes = ReadUInt16(); SafeReadName(inBuffer, item.Name); files.Add(item); if (progressVirt != NULL) { - UINT64 numFiles = files.Size(); + UInt64 numFiles = files.Size(); RINOK(progressVirt->SetCompleted(&numFiles)); } } diff --git a/7zip/Archive/Cab/CabIn.h b/7zip/Archive/Cab/CabIn.h index 4c6db9cb..82a9ea0d 100755 --- a/7zip/Archive/Cab/CabIn.h +++ b/7zip/Archive/Cab/CabIn.h @@ -1,7 +1,5 @@ // Archive/CabIn.h -#pragma once - #ifndef __ARCHIVE_CAB_IN_H #define __ARCHIVE_CAB_IN_H @@ -27,14 +25,14 @@ public: class CInArchiveInfo { public: - UINT32 Size; /* size of this cabinet file in bytes */ - BYTE VersionMinor; /* cabinet file format version, minor */ - BYTE VersionMajor; /* cabinet file format version, major */ - UINT16 NumFolders; /* number of CFFOLDER entries in this cabinet */ - UINT16 NumFiles; /* number of CFFILE entries in this cabinet */ - UINT16 Flags; /* cabinet file option indicators */ - UINT16 SetID; /* must be the same for all cabinets in a set */ - UINT16 CabinetNumber; /* number of this cabinet file in a set */ + UInt32 Size; /* size of this cabinet file in bytes */ + Byte VersionMinor; /* cabinet file format version, minor */ + Byte VersionMajor; /* cabinet file format version, major */ + UInt16 NumFolders; /* number of CFFOLDER entries in this cabinet */ + UInt16 NumFiles; /* number of CFFILE entries in this cabinet */ + UInt16 Flags; /* cabinet file option indicators */ + UInt16 SetID; /* must be the same for all cabinets in a set */ + UInt16 CabinetNumber; /* number of this cabinet file in a set */ bool ReserveBlockPresent() const { return (Flags & NHeader::NArchive::NFlags::kReservePresent) != 0; } NHeader::NArchive::CPerDataSizes PerDataSizes; @@ -48,19 +46,28 @@ public: class CProgressVirt { public: - STDMETHOD(SetTotal)(const UINT64 *numFiles) PURE; - STDMETHOD(SetCompleted)(const UINT64 *numFiles) PURE; + STDMETHOD(SetTotal)(const UInt64 *numFiles) PURE; + STDMETHOD(SetCompleted)(const UInt64 *numFiles) PURE; }; +const UInt32 kMaxBlockSize = NHeader::NArchive::kArchiveHeaderSize; + class CInArchive { + UInt16 _blockSize; + Byte _block[kMaxBlockSize]; + UInt32 _blockPos; + + Byte ReadByte(); + UInt16 ReadUInt16(); + UInt32 ReadUInt32(); public: HRESULT Open(IInStream *inStream, - const UINT64 *searchHeaderSizeLimit, + const UInt64 *searchHeaderSizeLimit, CInArchiveInfo &inArchiveInfo, CObjectVector<NHeader::CFolder> &folders, - CObjectVector<CItem> &aFiles, - CProgressVirt *aProgressVirt); + CObjectVector<CItem> &files, + CProgressVirt *progressVirt); }; }} diff --git a/7zip/Archive/Cab/CabInBuffer.cpp b/7zip/Archive/Cab/CabInBuffer.cpp index ba924115..de759a58 100755 --- a/7zip/Archive/Cab/CabInBuffer.cpp +++ b/7zip/Archive/Cab/CabInBuffer.cpp @@ -1,153 +1,175 @@ // Archive/CabInBuffer.cpp -#include "stdafx.h" +#include "StdAfx.h" -#include "Common/Types.h" -#include "Common/MyCom.h" -#include "Windows/Defs.h" +#include "../../../Common/Alloc.h" +#include "../../../Common/MyCom.h" +#include "../../../Windows/Defs.h" #include "CabInBuffer.h" namespace NArchive { namespace NCab { -#pragma pack(push, PragmaCabDataHeader) -#pragma pack(push, 1) - +static const UInt32 kDataBlockHeaderSize = 8; +/* struct CDataBlockHeader { - UINT32 CheckSum; /* checksum of this CFDATA entry */ - UINT16 PackSize; /* number of compressed bytes in this block */ - UINT16 UnPackSize; /* number of uncompressed bytes in this block */ - // BYTE abReserve[]; /* (optional) per-datablock reserved area */ - // BYTE ab[cbData]; /* compressed data bytes */ + UInt32 CheckSum; // checksum of this CFDATA entry + UInt16 PackSize; // number of compressed bytes in this block + UInt16 UnPackSize; // number of uncompressed bytes in this block + // Byte abReserve[]; // (optional) per-datablock reserved area + // Byte ab[cbData]; // compressed data bytes }; +*/ -#pragma pack(pop) -#pragma pack(pop, PragmaCabDataHeader) +class CTempCabInBuffer +{ +public: + Byte *Buffer; + UInt32 Size; + UInt32 Pos; + Byte ReadByte() + { + if (Pos >= Size) + throw "overflow"; + return Buffer[Pos++]; + } + UInt32 ReadUInt32() + { + UInt32 value = 0; + for (int i = 0; i < 4; i++) + value |= (((UInt32)ReadByte()) << (8 * i)); + return value; + } + UInt16 ReadUInt16() + { + UInt16 value = 0; + for (int i = 0; i < 2; i++) + value |= (((UInt16)ReadByte()) << (8 * i)); + return value; + } +}; -CInBuffer::CInBuffer(UINT32 bufferSize): - m_BufferSize(bufferSize), - m_Stream(0) +bool CInBuffer::Create(UInt32 bufferSize) { - m_Buffer = new BYTE[m_BufferSize]; + const UInt32 kMinBlockSize = 1; + if (bufferSize < kMinBlockSize) + bufferSize = kMinBlockSize; + if (m_Buffer != 0 && m_BufferSize == bufferSize) + return true; + Free(); + m_BufferSize = bufferSize; + m_Buffer = (Byte *)::BigAlloc(bufferSize); + return (m_Buffer != 0); } -CInBuffer::~CInBuffer() +void CInBuffer::Free() { - delete []m_Buffer; - // ReleaseStream(); + BigFree(m_Buffer); + m_Buffer = 0; } -void CInBuffer::Init(ISequentialInStream *inStream, BYTE reservedSize, UINT32 numBlocks) +void CInBuffer::Init(Byte reservedSize, UInt32 numBlocks) { m_ReservedSize = reservedSize; m_NumBlocks = numBlocks; m_CurrentBlockIndex = 0; - // ReleaseStream(); - m_Stream = inStream; - // m_Stream->AddRef(); m_ProcessedSize = 0; m_Pos = 0; m_NumReadBytesInBuffer = 0; } -/* -void CInBuffer::ReleaseStream() -{ - if(m_Stream != 0) - { - m_Stream->Release(); - m_Stream = 0; - } -} -*/ - class CCheckSum { - UINT32 m_Value; + UInt32 m_Value; public: CCheckSum(): m_Value(0){}; void Init() { m_Value = 0; } - void Update(const void *data, UINT32 size); - UINT32 GetResult() const { return m_Value; } + void Update(const void *data, UInt32 size); + void UpdateUInt32(UInt32 v) { m_Value ^= v; } + UInt32 GetResult() const { return m_Value; } }; -void CCheckSum::Update(const void *data, UINT32 size) +void CCheckSum::Update(const void *data, UInt32 size) { - UINT32 checkSum = m_Value; - const BYTE *aDataPointer = (const BYTE *)data; - int numUINT32Words = size / 4; // Number of ULONGs + UInt32 checkSum = m_Value; + const Byte *dataPointer = (const Byte *)data; + int numUINT32Words = size / 4; // Number of ULONGs - // dataPointer += numUINT32Words * 4; - - UINT32 temp; - const UINT32 *aDataPointer32 = (const UINT32 *)data; + UInt32 temp; while (numUINT32Words-- > 0) { - // temp ^= *aDataPointer32++; - temp = *aDataPointer++; // Get low-order byte - temp |= (((ULONG)(*aDataPointer++)) << 8); // Add 2nd byte - temp |= (((ULONG)(*aDataPointer++)) << 16); // Add 3nd byte - temp |= (((ULONG)(*aDataPointer++)) << 24); // Add 4th byte - checkSum ^= temp; // Update checksum + temp = *dataPointer++; + temp |= (((UInt32)(*dataPointer++)) << 8); + temp |= (((UInt32)(*dataPointer++)) << 16); + temp |= (((UInt32)(*dataPointer++)) << 24); + checkSum ^= temp; } temp = 0; - switch (size % 4) - { - case 3: - temp |= (((ULONG)(*aDataPointer++)) << 16); // Add 3nd byte - case 2: - temp |= (((ULONG)(*aDataPointer++)) << 8); // Add 2nd byte - case 1: - temp |= *aDataPointer++; // Get low-order byte - default: - break; - } + int rem = (size & 3); + if (rem >= 3) + temp |= (((UInt32)(*dataPointer++)) << 16); + if (rem >= 2) + temp |= (((UInt32)(*dataPointer++)) << 8); + if (rem >= 1) + temp |= *dataPointer++; checkSum ^= temp; m_Value = checkSum; } -HRESULT CInBuffer::ReadBlock(UINT32 &uncompressedSize, bool &dataAreCorrect) + +HRESULT CInBuffer::ReadBlock(UInt32 &uncompressedSize, bool &dataAreCorrect) { if (m_CurrentBlockIndex >= m_NumBlocks) throw "there is no more data blocks"; m_ProcessedSize += m_NumReadBytesInBuffer; - CDataBlockHeader dataBlockHeader; - UINT32 numProcessedBytes; - RINOK(m_Stream->Read(&dataBlockHeader, sizeof(dataBlockHeader), &numProcessedBytes)); - if (numProcessedBytes != sizeof(dataBlockHeader)) + Byte buffer[kDataBlockHeaderSize]; + UInt32 numProcessedBytes; + RINOK(m_Stream->Read(buffer, kDataBlockHeaderSize, &numProcessedBytes)); + if (numProcessedBytes != kDataBlockHeaderSize) throw "bad block"; + CTempCabInBuffer inBuffer; + inBuffer.Size = kDataBlockHeaderSize; + inBuffer.Buffer = (Byte *)buffer; + inBuffer.Pos = 0; + + UInt32 checkSum = inBuffer.ReadUInt32(); // checksum of this CFDATA entry + UInt16 packSize = inBuffer.ReadUInt16(); // number of compressed bytes in this block + UInt16 unPackSize = inBuffer.ReadUInt16(); // number of uncompressed bytes in this block + if (m_ReservedSize != 0) { - BYTE reservedArea[256]; + Byte reservedArea[256]; RINOK(m_Stream->Read(reservedArea, m_ReservedSize, &numProcessedBytes)); if (numProcessedBytes != m_ReservedSize) throw "bad block"; } - RINOK(m_Stream->Read(m_Buffer, dataBlockHeader.PackSize, &m_NumReadBytesInBuffer)); - if (m_NumReadBytesInBuffer != dataBlockHeader.PackSize) + RINOK(m_Stream->Read(m_Buffer, packSize, &m_NumReadBytesInBuffer)); + if (m_NumReadBytesInBuffer != packSize) throw "bad block"; - if (dataBlockHeader.CheckSum == 0) + // Now I don't remember why (checkSum == 0) check is disbaled + // Cab specification: + // checkSum: May be set to zero if the checksum is not supplied. + // but seems it's stupid rule. + if (checkSum == 0) dataAreCorrect = true; { - CCheckSum checkSum; - checkSum.Update(m_Buffer, dataBlockHeader.PackSize); - checkSum.Update(&dataBlockHeader.PackSize, - sizeof(dataBlockHeader) - sizeof(dataBlockHeader.CheckSum)); - dataAreCorrect = (checkSum.GetResult() == dataBlockHeader.CheckSum); + CCheckSum checkSumCalc; + checkSumCalc.Update(m_Buffer, packSize); + checkSumCalc.UpdateUInt32(packSize | (((UInt32)unPackSize) << 16)); + dataAreCorrect = (checkSumCalc.GetResult() == checkSum); } m_Pos = 0; - uncompressedSize = dataBlockHeader.UnPackSize; + uncompressedSize = unPackSize; m_CurrentBlockIndex++; return S_OK; } - }} diff --git a/7zip/Archive/Cab/CabInBuffer.h b/7zip/Archive/Cab/CabInBuffer.h index 233a0f84..1b94f77f 100755 --- a/7zip/Archive/Cab/CabInBuffer.h +++ b/7zip/Archive/Cab/CabInBuffer.h @@ -1,60 +1,64 @@ // Archive/CabInBuffer.h -#pragma once - #ifndef __ARCHIVE_CAB_INBUFFER_H #define __ARCHIVE_CAB_INBUFFER_H #include "../../IStream.h" +#include "../../../Common/MyCom.h" namespace NArchive { namespace NCab { class CInBuffer { - UINT64 m_ProcessedSize; - UINT32 m_Pos; - UINT32 m_NumReadBytesInBuffer; - BYTE *m_Buffer; - ISequentialInStream *m_Stream; - UINT32 m_BufferSize; + UInt64 m_ProcessedSize; + UInt32 m_Pos; + UInt32 m_NumReadBytesInBuffer; + Byte *m_Buffer; + CMyComPtr<ISequentialInStream> m_Stream; + UInt32 m_BufferSize; - UINT32 m_NumBlocks; - UINT32 m_CurrentBlockIndex; - UINT32 m_ReservedSize; + UInt32 m_NumBlocks; + UInt32 m_CurrentBlockIndex; + UInt32 m_ReservedSize; public: - CInBuffer(UINT32 bufferSize = 0x20000); - ~CInBuffer(); + CInBuffer(): m_Buffer(0) {} + ~CInBuffer() { Free(); } + bool Create(UInt32 bufferSize); + void Free(); - void Init(ISequentialInStream *inStream, BYTE reservedSize, UINT32 numBlocks); - // void ReleaseStream(); + void SetStream(ISequentialInStream *inStream) { m_Stream = inStream; } + void ReleaseStream() { m_Stream.Release(); } + + void Init(Byte reservedSize, UInt32 numBlocks); + void Init() {} - bool ReadByte(BYTE &b) + bool ReadByte(Byte &b) { if(m_Pos >= m_NumReadBytesInBuffer) return false; b = m_Buffer[m_Pos++]; return true; } - BYTE ReadByte() + Byte ReadByte() { if(m_Pos >= m_NumReadBytesInBuffer) return 0; return m_Buffer[m_Pos++]; } /* - void ReadBytes(void *data, UINT32 size, UINT32 &aProcessedSize) + void ReadBytes(void *data, UInt32 size, UInt32 &aProcessedSize) { - BYTE *aDataPointer = (BYTE *)data; + Byte *aDataPointer = (Byte *)data; for(int i = 0; i < size; i++) if (!ReadByte(aDataPointer[i])) break; aProcessedSize = i; } */ - HRESULT ReadBlock(UINT32 &uncompressedSize, bool &dataAreCorrect); - UINT64 GetProcessedSize() const { return m_ProcessedSize + m_Pos; } + HRESULT ReadBlock(UInt32 &uncompressedSize, bool &dataAreCorrect); + UInt64 GetProcessedSize() const { return m_ProcessedSize + m_Pos; } }; }} diff --git a/7zip/Archive/Cab/CabItem.h b/7zip/Archive/Cab/CabItem.h index 1b4add81..b1ebeb60 100755 --- a/7zip/Archive/Cab/CabItem.h +++ b/7zip/Archive/Cab/CabItem.h @@ -1,7 +1,5 @@ // Archive/Cab/ItemInfo.h -#pragma once - #ifndef __ARCHIVE_RAR_ITEMINFO_H #define __ARCHIVE_RAR_ITEMINFO_H @@ -15,14 +13,15 @@ namespace NCab { class CItem { public: - UINT16 Flags; - UINT64 UnPackSize; - UINT32 UnPackOffset; - UINT16 FolderIndex; - UINT32 Time; - UINT16 Attributes; - UINT32 GetWinAttributes() const { return Attributes & (Attributes & ~NHeader::kFileNameIsUTFAttributeMask); } + UInt16 Flags; + UInt64 UnPackSize; + UInt32 UnPackOffset; + UInt16 FolderIndex; + UInt32 Time; + UInt16 Attributes; + UInt32 GetWinAttributes() const { return Attributes & (Attributes & ~NHeader::kFileNameIsUTFAttributeMask); } bool IsNameUTF() const { return (Attributes & NHeader::kFileNameIsUTFAttributeMask) != 0; } + bool IsDirectory() const { return (Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; } AString Name; }; diff --git a/7zip/Archive/Cab/DllExports.cpp b/7zip/Archive/Cab/DllExports.cpp index 8b345452..b92504fd 100755 --- a/7zip/Archive/Cab/DllExports.cpp +++ b/7zip/Archive/Cab/DllExports.cpp @@ -2,8 +2,7 @@ #include "StdAfx.h" -#define INITGUID - +#include "Common/MyInitGuid.h" #include "Common/ComTry.h" #include "Windows/PropVariant.h" #include "CabHandler.h" @@ -60,6 +59,13 @@ STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) case NArchive::kKeepName: propVariant = false; break; + case NArchive::kStartSignature: + { + const char sig[] = { 0x4D, 0x53, 0x43, 0x46 }; + if ((value->bstrVal = ::SysAllocStringByteLen(sig, 4)) != 0) + value->vt = VT_BSTR; + return S_OK; + } } propVariant.Detach(value); return S_OK; diff --git a/7zip/Archive/Cab/LZXBitDecoder.h b/7zip/Archive/Cab/LZXBitDecoder.h index ec01ed87..51737135 100755 --- a/7zip/Archive/Cab/LZXBitDecoder.h +++ b/7zip/Archive/Cab/LZXBitDecoder.h @@ -19,21 +19,20 @@ class CDecoder { protected: CInBuffer m_Stream; - UINT32 m_BitPos; - UINT32 m_Value; + UInt32 m_BitPos; + UInt32 m_Value; public: - void InitStream(ISequentialInStream *aStream, BYTE aReservedSize, UINT32 aNumBlocks) - { - m_Stream.Init(aStream, aReservedSize, aNumBlocks); - } - /* - void ReleaseStream() - { m_Stream.ReleaseStream(); } - */ - UINT64 GetProcessedSize() const + bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); } + void SetStream(ISequentialInStream *s) { m_Stream.SetStream(s); } + void ReleaseStream() { m_Stream.ReleaseStream(); } + void Init(Byte reservedSize, UInt32 numBlocks) + { + m_Stream.Init(reservedSize, numBlocks); + } + UInt64 GetProcessedSize() const { return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; } - UINT32 GetBitPosition() const - { return UINT32(m_Stream.GetProcessedSize() * 8 - (kNumBigValueBits - m_BitPos)); } + UInt32 GetBitPosition() const + { return UInt32(m_Stream.GetProcessedSize() * 8 - (kNumBigValueBits - m_BitPos)); } void Init() { @@ -45,65 +44,65 @@ public: { for (;m_BitPos >= 16; m_BitPos -= 16) { - BYTE aByte0 = m_Stream.ReadByte(); - BYTE aByte1 = m_Stream.ReadByte(); - m_Value = (m_Value << 8) | aByte1; - m_Value = (m_Value << 8) | aByte0; + Byte b0 = m_Stream.ReadByte(); + Byte b1 = m_Stream.ReadByte(); + m_Value = (m_Value << 8) | b1; + m_Value = (m_Value << 8) | b0; } } - UINT32 GetValue(UINT32 aNumBits) + UInt32 GetValue(UInt32 numBits) { return ((m_Value >> ((32 - kNumValueBits) - m_BitPos)) & kBitDecoderValueMask) >> - (kNumValueBits - aNumBits); + (kNumValueBits - numBits); } - void MovePos(UINT32 aNumBits) + void MovePos(UInt32 numBits) { - m_BitPos += aNumBits; + m_BitPos += numBits; Normalize(); } - UINT32 ReadBits(UINT32 aNumBits) + UInt32 ReadBits(UInt32 numBits) { - UINT32 aRes = GetValue(aNumBits); - MovePos(aNumBits); - return aRes; + UInt32 res = GetValue(numBits); + MovePos(numBits); + return res; } - UINT32 ReadBitsBig(UINT32 aNumBits) + UInt32 ReadBitsBig(UInt32 numBits) { - UINT32 aNumBits0 = aNumBits / 2; - UINT32 aNumBits1 = aNumBits - aNumBits0; - UINT32 aRes = ReadBits(aNumBits0) << aNumBits1; - return aRes + ReadBits(aNumBits1); + UInt32 numBits0 = numBits / 2; + UInt32 numBits1 = numBits - numBits0; + UInt32 res = ReadBits(numBits0) << numBits1; + return res + ReadBits(numBits1); } - BYTE DirectReadByte() + Byte DirectReadByte() { if (m_BitPos == kNumBigValueBits) return m_Stream.ReadByte(); - BYTE aRes; + Byte res; switch(m_BitPos) { case 0: - aRes = BYTE(m_Value >> 16); + res = Byte(m_Value >> 16); break; case 8: - aRes = BYTE(m_Value >> 24); + res = Byte(m_Value >> 24); break; case 16: - aRes = BYTE(m_Value); + res = Byte(m_Value); break; case 24: - aRes = BYTE(m_Value >> 8); + res = Byte(m_Value >> 8); break; } m_BitPos += 8; - return aRes; + return res; } - HRESULT ReadBlock(UINT32 &anUncompressedSize, bool &aDataAreCorrect) - { return m_Stream.ReadBlock(anUncompressedSize, aDataAreCorrect); } + HRESULT ReadBlock(UInt32 &uncompressedSize, bool &dataAreCorrect) + { return m_Stream.ReadBlock(uncompressedSize, dataAreCorrect); } }; diff --git a/7zip/Archive/Cab/LZXConst.h b/7zip/Archive/Cab/LZXConst.h index b996f904..f4648024 100755 --- a/7zip/Archive/Cab/LZXConst.h +++ b/7zip/Archive/Cab/LZXConst.h @@ -9,7 +9,6 @@ namespace NArchive { namespace NCab { namespace NLZX { - namespace NBlockType { const int kNumBits = 3; @@ -23,9 +22,9 @@ namespace NBlockType const int kUncompressedBlockSizeNumBits = 24; -const UINT32 kLevelTableSize = 20; +const UInt32 kLevelTableSize = 20; -const UINT32 kNumBitsForPreTreeLevel = 4; +const UInt32 kNumBitsForPreTreeLevel = 4; const int kLevelSymbolZeros = 17; const int kLevelSymbolZerosBig = 18; @@ -43,38 +42,38 @@ const int kNumBitsForAlignLevel = 3; const int kLevelSymbolSameNumBits = 1; const int kLevelSymbolSameStartValue = 4; -// const UINT32 kMainTableSize = 256 + kNumPosLenSlots + 1; +// const UInt32 kMainTableSize = 256 + kNumPosLenSlots + 1; /* -const UINT32 kLenTableSize = 28; +const UInt32 kLenTableSize = 28; -const UINT32 kLenTableStart = kMainTableSize; -const UINT32 kAlignTableStart = kLenTableStart + kLenTableSize; +const UInt32 kLenTableStart = kMainTableSize; +const UInt32 kAlignTableStart = kLenTableStart + kLenTableSize; -const UINT32 kHeapTablesSizesSum = kMainTableSize + kLenTableSize + kAlignTableSize; +const UInt32 kHeapTablesSizesSum = kMainTableSize + kLenTableSize + kAlignTableSize; -const UINT32 kMaxTableSize = kHeapTablesSizesSum; +const UInt32 kMaxTableSize = kHeapTablesSizesSum; -const UINT32 kTableDirectLevels = 16; -const UINT32 kTableLevelRepNumber = kTableDirectLevels; -const UINT32 kTableLevel0Number = kTableLevelRepNumber + 1; -const UINT32 kTableLevel0Number2 = kTableLevel0Number + 1; +const UInt32 kTableDirectLevels = 16; +const UInt32 kTableLevelRepNumber = kTableDirectLevels; +const UInt32 kTableLevel0Number = kTableLevelRepNumber + 1; +const UInt32 kTableLevel0Number2 = kTableLevel0Number + 1; -const UINT32 kLevelMask = 0xF; +const UInt32 kLevelMask = 0xF; -const UINT32 kPosLenNumber = 256; -const UINT32 kReadTableNumber = 256 + kNumPosLenSlots; +const UInt32 kPosLenNumber = 256; +const UInt32 kReadTableNumber = 256 + kNumPosLenSlots; -//const UINT32 kMatchNumber = kReadTableNumber + 1; +//const UInt32 kMatchNumber = kReadTableNumber + 1; -const BYTE kLenStart[kLenTableSize] = +const Byte kLenStart[kLenTableSize] = {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224}; -const BYTE kLenDirectBits[kLenTableSize] = +const Byte kLenDirectBits[kLenTableSize] = {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5}; */ -const UINT32 kDistStart[] = +const UInt32 kDistStart[] = { 0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024, 1536,2048,3072,4096,6144,8192,12288,16384,24576,32768,49152,65536,98304,131072,196608, 0x40000, @@ -93,7 +92,7 @@ const UINT32 kDistStart[] = 0x1C0000, 0x1E0000 }; -const BYTE kDistDirectBits[] = +const Byte kDistDirectBits[] = { 0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,16,16, 17, 17, 17, 17, 17, 17, @@ -101,12 +100,11 @@ const BYTE kDistDirectBits[] = }; /* -const BYTE kLevelDirectBits[kLevelTableSize] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7}; +const Byte kLevelDirectBits[kLevelTableSize] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7}; -const UINT32 kDistLimit2 = 0x101 - 1; +const UInt32 kDistLimit2 = 0x101 - 1; */ - }}} -#endif
\ No newline at end of file +#endif diff --git a/7zip/Archive/Cab/LZXDecoder.cpp b/7zip/Archive/Cab/LZXDecoder.cpp index ffa7e1fc..17a37b55 100755 --- a/7zip/Archive/Cab/LZXDecoder.cpp +++ b/7zip/Archive/Cab/LZXDecoder.cpp @@ -4,7 +4,6 @@ #include "LZXDecoder.h" -#include "LZXConst.h" #include "Common/Defs.h" #include "Windows/Defs.h" @@ -12,17 +11,10 @@ namespace NArchive { namespace NCab { namespace NLZX { -static const UINT32 kHistorySize = (1 << 21); +static const UInt32 kHistorySize = (1 << 21); -const int kMainTableSize = 256 + kNumPosSlotLenSlotSymbols; - -CDecoder::CDecoder(): - m_MainDecoder(kMainTableSize), - m_LenDecoder(kNumLenSymbols), - m_AlignDecoder(kAlignTableSize), - m_LevelDecoder(kLevelTableSize) +CDecoder::CDecoder() { - m_OutWindowStream.Create(kHistorySize); m_i86TranslationOutStreamSpec = new Ci86TranslationOutStream; m_i86TranslationOutStream = m_i86TranslationOutStreamSpec; } @@ -40,18 +32,18 @@ STDMETHODIMP CDecoder::Flush() return m_i86TranslationOutStreamSpec->Flush(); } -void CDecoder::ReadTable(BYTE *lastLevels, BYTE *newLevels, UINT32 numSymbols) +void CDecoder::ReadTable(Byte *lastLevels, Byte *newLevels, UInt32 numSymbols) { - BYTE levelLevels[kLevelTableSize]; - UINT32 i; + Byte levelLevels[kLevelTableSize]; + UInt32 i; for (i = 0; i < kLevelTableSize; i++) - levelLevels[i] = BYTE(m_InBitStream.ReadBits(kNumBitsForPreTreeLevel)); + levelLevels[i] = Byte(m_InBitStream.ReadBits(kNumBitsForPreTreeLevel)); m_LevelDecoder.SetCodeLengths(levelLevels); for (i = 0; i < numSymbols;) { - UINT32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream); + UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream); if (number <= kNumHuffmanBits) - newLevels[i++] = BYTE((17 + lastLevels[i] - number) % (kNumHuffmanBits + 1)); + newLevels[i++] = Byte((17 + lastLevels[i] - number) % (kNumHuffmanBits + 1)); else if (number == kLevelSymbolZeros || number == kLevelSymbolZerosBig) { int num; @@ -67,10 +59,10 @@ void CDecoder::ReadTable(BYTE *lastLevels, BYTE *newLevels, UINT32 numSymbols) else if (number == kLevelSymbolSame) { int num = kLevelSymbolSameStartValue + m_InBitStream.ReadBits(kLevelSymbolSameNumBits); - UINT32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream); + UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream); if (number > kNumHuffmanBits) throw "bad data"; - BYTE symbol = BYTE((17 + lastLevels[i] - number) % (kNumHuffmanBits + 1)); + Byte symbol = Byte((17 + lastLevels[i] - number) % (kNumHuffmanBits + 1)); for (; num > 0 && i < numSymbols; num--, i++) newLevels[i] = symbol; } @@ -94,7 +86,7 @@ void CDecoder::ReadTables(void) if (blockType == NBlockType::kUncompressed) { m_UncompressedBlock = true; - UINT32 bitPos = m_InBitStream.GetBitPosition() % 16; + UInt32 bitPos = m_InBitStream.GetBitPosition() % 16; m_InBitStream.ReadBits(16 - bitPos); for (int i = 0; i < kNumRepDistances; i++) { @@ -110,7 +102,7 @@ void CDecoder::ReadTables(void) m_AlignIsUsed = (blockType == NBlockType::kAligned); - BYTE newLevels[kMaxTableSize]; + Byte newLevels[kMaxTableSize]; if (m_AlignIsUsed) { @@ -153,27 +145,34 @@ void CDecoder::ClearPrevLeveles() STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UINT64 *inSize, const UINT64 *outSize, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { if (outSize == NULL) return E_INVALIDARG; - UINT64 size = *outSize; + UInt64 size = *outSize; + + if (!m_OutWindowStream.Create(kHistorySize)) + return E_OUTOFMEMORY; + if (!m_InBitStream.Create(1 << 20)) + return E_OUTOFMEMORY; + m_OutWindowStream.SetStream(m_i86TranslationOutStream); + m_OutWindowStream.Init(); - m_OutWindowStream.Init(m_i86TranslationOutStream); - m_InBitStream.InitStream(inStream, m_ReservedSize, m_NumInDataBlocks); + m_InBitStream.SetStream(inStream); + m_InBitStream.Init(m_ReservedSize, m_NumInDataBlocks); CDecoderFlusher flusher(this); - UINT32 uncompressedCFDataBlockSize; + UInt32 uncompressedCFDataBlockSize; bool dataAreCorrect; RINOK(m_InBitStream.ReadBlock(uncompressedCFDataBlockSize, dataAreCorrect)); if (!dataAreCorrect) { throw "Data Error"; } - UINT32 uncompressedCFDataCurrentValue = 0; + UInt32 uncompressedCFDataCurrentValue = 0; m_InBitStream.Init(); ClearPrevLeveles(); @@ -182,7 +181,7 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, m_i86TranslationOutStreamSpec->Init(outStream, false, 0); else { - UINT32 i86TranslationSize = m_InBitStream.ReadBits(16) << 16; + UInt32 i86TranslationSize = m_InBitStream.ReadBits(16) << 16; i86TranslationSize |= m_InBitStream.ReadBits(16); m_i86TranslationOutStreamSpec->Init(outStream, true , i86TranslationSize); } @@ -190,7 +189,7 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, for(int i = 0 ; i < kNumRepDistances; i++) m_RepDistances[i] = 0; - UINT64 nowPos64 = 0; + UInt64 nowPos64 = 0; while(nowPos64 < size) { if (uncompressedCFDataCurrentValue == uncompressedCFDataBlockSize) @@ -205,13 +204,13 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, uncompressedCFDataCurrentValue = 0; } ReadTables(); - UINT32 nowPos = 0; - UINT32 next = (UINT32)MyMin((UINT64)m_UnCompressedBlockSize, size - nowPos64); + UInt32 nowPos = 0; + UInt32 next = (UInt32)MyMin((UInt64)m_UnCompressedBlockSize, size - nowPos64); if (m_UncompressedBlock) { while(nowPos < next) { - m_OutWindowStream.PutOneByte(m_InBitStream.DirectReadByte()); + m_OutWindowStream.PutByte(m_InBitStream.DirectReadByte()); nowPos++; uncompressedCFDataCurrentValue++; if (uncompressedCFDataCurrentValue == uncompressedCFDataBlockSize) @@ -245,27 +244,27 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, m_InBitStream.Init(); uncompressedCFDataCurrentValue = 0; } - UINT32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream); + UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream); if (number < 256) { - m_OutWindowStream.PutOneByte(BYTE(number)); + m_OutWindowStream.PutByte(Byte(number)); nowPos++; uncompressedCFDataCurrentValue++; // continue; } else if (number < 256 + m_NumPosLenSlots) { - UINT32 posLenSlot = number - 256; - UINT32 posSlot = posLenSlot / kNumLenSlots; - UINT32 lenSlot = posLenSlot % kNumLenSlots; - UINT32 length = 2 + lenSlot; + UInt32 posLenSlot = number - 256; + UInt32 posSlot = posLenSlot / kNumLenSlots; + UInt32 lenSlot = posLenSlot % kNumLenSlots; + UInt32 length = 2 + lenSlot; if (lenSlot == kNumLenSlots - 1) length += m_LenDecoder.DecodeSymbol(&m_InBitStream); if (posSlot < kNumRepDistances) { - UINT32 distance = m_RepDistances[posSlot]; - m_OutWindowStream.CopyBackBlock(distance, length); + UInt32 distance = m_RepDistances[posSlot]; + m_OutWindowStream.CopyBlock(distance, length); if (posSlot != 0) { m_RepDistances[posSlot] = m_RepDistances[0]; @@ -274,8 +273,8 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, } else { - UINT32 pos = kDistStart[posSlot]; - UINT32 posDirectBits = kDistDirectBits[posSlot]; + UInt32 pos = kDistStart[posSlot]; + UInt32 posDirectBits = kDistDirectBits[posSlot]; if (m_AlignIsUsed && posDirectBits >= kNumAlignBits) { pos += (m_InBitStream.ReadBits(posDirectBits - kNumAlignBits) << kNumAlignBits); @@ -283,10 +282,10 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, } else pos += m_InBitStream.ReadBits(posDirectBits); - UINT32 distance = pos - kNumRepDistances; + UInt32 distance = pos - kNumRepDistances; if (distance >= nowPos64 + nowPos) throw 777123; - m_OutWindowStream.CopyBackBlock(distance, length); + m_OutWindowStream.CopyBlock(distance, length); m_RepDistances[2] = m_RepDistances[1]; m_RepDistances[1] = m_RepDistances[0]; m_RepDistances[0] = distance; @@ -299,8 +298,8 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, } if (progress != NULL) { - UINT64 inSize = m_InBitStream.GetProcessedSize(); - UINT64 outSize = nowPos64 + nowPos; + UInt64 inSize = m_InBitStream.GetProcessedSize(); + UInt64 outSize = nowPos64 + nowPos; RINOK(progress->SetRatioInfo(&inSize, &outSize)); } nowPos64 += nowPos; diff --git a/7zip/Archive/Cab/LZXDecoder.h b/7zip/Archive/Cab/LZXDecoder.h index 00c2e9c4..257de7b9 100755 --- a/7zip/Archive/Cab/LZXDecoder.h +++ b/7zip/Archive/Cab/LZXDecoder.h @@ -1,7 +1,5 @@ // Archive/Cab/LZXDecoder.h -#pragma once - #ifndef __ARCHIVE_CAB_LZXDECODER_H #define __ARCHIVE_CAB_LZXDECODER_H @@ -14,14 +12,13 @@ #include "LZXBitDecoder.h" #include "LZXi86Converter.h" - -// #include "../../../Projects/CompressInterface/CompressInterface.h" +#include "LZXConst.h" namespace NArchive { namespace NCab { namespace NLZX { -typedef NCompress::NHuffman::CDecoder<kNumHuffmanBits> CMSBFHuffmanDecoder; +const int kMainTableSize = 256 + kNumPosSlotLenSlotSymbols; class CDecoder : public ICompressCoder, @@ -30,36 +27,36 @@ class CDecoder : CLZOutWindow m_OutWindowStream; NBitStream::CDecoder m_InBitStream; - CMSBFHuffmanDecoder m_MainDecoder; - CMSBFHuffmanDecoder m_LenDecoder; // for matches with repeated offsets - CMSBFHuffmanDecoder m_AlignDecoder; // for matches with repeated offsets - CMSBFHuffmanDecoder m_LevelDecoder; // table for decoding other tables; + NCompress::NHuffman::CDecoder<kNumHuffmanBits, kMainTableSize> m_MainDecoder; + NCompress::NHuffman::CDecoder<kNumHuffmanBits, kNumLenSymbols> m_LenDecoder; + NCompress::NHuffman::CDecoder<kNumHuffmanBits, kAlignTableSize> m_AlignDecoder; + NCompress::NHuffman::CDecoder<kNumHuffmanBits, kLevelTableSize> m_LevelDecoder; - UINT32 m_RepDistances[kNumRepDistances]; + UInt32 m_RepDistances[kNumRepDistances]; - BYTE m_LastByteLevels[256]; - BYTE m_LastPosLenLevels[kNumPosSlotLenSlotSymbols]; - BYTE m_LastLenLevels[kNumLenSymbols]; + Byte m_LastByteLevels[256]; + Byte m_LastPosLenLevels[kNumPosSlotLenSlotSymbols]; + Byte m_LastLenLevels[kNumLenSymbols]; - UINT32 m_DictionarySizePowerOf2; - UINT32 m_NumPosSlots; - UINT32 m_NumPosLenSlots; + UInt32 m_DictionarySizePowerOf2; + UInt32 m_NumPosSlots; + UInt32 m_NumPosLenSlots; // bool m_i86PreprocessingUsed; - // UINT32 m_i86TranslationSize; + // UInt32 m_i86TranslationSize; bool m_UncompressedBlock; bool m_AlignIsUsed; - UINT32 m_UnCompressedBlockSize; + UInt32 m_UnCompressedBlockSize; Ci86TranslationOutStream *m_i86TranslationOutStreamSpec; CMyComPtr<ISequentialOutStream> m_i86TranslationOutStream; - BYTE m_ReservedSize; - UINT32 m_NumInDataBlocks; + Byte m_ReservedSize; + UInt32 m_NumInDataBlocks; - void ReadTable(BYTE *lastLevels, BYTE *newLevels, UINT32 numSymbols); + void ReadTable(Byte *lastLevels, Byte *newLevels, UInt32 numSymbols); void ReadTables(); void ClearPrevLeveles(); @@ -74,11 +71,11 @@ public: // ICompressCoder interface STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UINT64 *inSize, const UINT64 *outSize, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - void SetParams(BYTE reservedSize, UINT32 numInDataBlocks, - UINT32 dictionarySizePowerOf2) + void SetParams(Byte reservedSize, UInt32 numInDataBlocks, + UInt32 dictionarySizePowerOf2) { m_ReservedSize = reservedSize; m_NumInDataBlocks = numInDataBlocks; diff --git a/7zip/Archive/Cab/LZXExtConst.h b/7zip/Archive/Cab/LZXExtConst.h index c00dfbd9..df2ef6cf 100755 --- a/7zip/Archive/Cab/LZXExtConst.h +++ b/7zip/Archive/Cab/LZXExtConst.h @@ -7,17 +7,17 @@ namespace NArchive { namespace NCab { namespace NLZX { -const UINT32 kNumRepDistances = 3; +const UInt32 kNumRepDistances = 3; -const UINT32 kNumLenSlots = 8; -const UINT32 kMatchMinLen = 2; -const UINT32 kNumLenSymbols = 249; -const UINT32 kMatchMaxLen = kMatchMinLen + (kNumLenSlots - 1) + kNumLenSymbols - 1; +const UInt32 kNumLenSlots = 8; +const UInt32 kMatchMinLen = 2; +const UInt32 kNumLenSymbols = 249; +const UInt32 kMatchMaxLen = kMatchMinLen + (kNumLenSlots - 1) + kNumLenSymbols - 1; -const BYTE kNumAlignBits = 3; -const UINT32 kAlignTableSize = 1 << kNumAlignBits; +const Byte kNumAlignBits = 3; +const UInt32 kAlignTableSize = 1 << kNumAlignBits; -const UINT32 kNumHuffmanBits = 16; +const UInt32 kNumHuffmanBits = 16; const int kNumPosSlotSymbols = 50; const int kNumPosSlotLenSlotSymbols = kNumPosSlotSymbols * kNumLenSlots; @@ -25,7 +25,6 @@ const int kNumPosSlotLenSlotSymbols = kNumPosSlotSymbols * kNumLenSlots; const int kMaxTableSize = 256 + kNumPosSlotLenSlotSymbols; - }}} -#endif;
\ No newline at end of file +#endif diff --git a/7zip/Archive/Cab/LZXi86Converter.cpp b/7zip/Archive/Cab/LZXi86Converter.cpp index 5e3e4809..ec70a211 100755 --- a/7zip/Archive/Cab/LZXi86Converter.cpp +++ b/7zip/Archive/Cab/LZXi86Converter.cpp @@ -5,71 +5,42 @@ #include "Common/Defs.h" #include "LZXi86Converter.h" -#include "Windows/Defs.h" namespace NArchive { namespace NCab { namespace NLZX { -Ci86TranslationOutStream::Ci86TranslationOutStream(): - m_Pos(0) -{ -} - -Ci86TranslationOutStream::~Ci86TranslationOutStream() -{ - Flush(); -} - -void Ci86TranslationOutStream::Init(ISequentialOutStream *aStream, - bool aTranslationMode, UINT32 aTranslationSize) -{ - m_Stream = aStream; - m_TranslationMode = aTranslationMode; - m_TranslationSize = aTranslationSize; - m_ProcessedSize = 0; - m_Pos = 0; -} - -void Ci86TranslationOutStream::ReleaseStream() -{ - m_Stream.Release(); -} - -inline INT32 Ci86TranslationOutStream::ConvertAbsoluteToOffset(INT32 aPos, INT32 anAbsoluteValue) -{ -} - static const int kResidue = 6 + 4; void Ci86TranslationOutStream::MakeTranslation() { if (m_Pos <= kResidue) return; - UINT32 aNumBytes = m_Pos - kResidue; - for (UINT32 i = 0; i < aNumBytes;) + UInt32 numBytes = m_Pos - kResidue; + for (UInt32 i = 0; i < numBytes;) { if (m_Buffer[i] == 0xE8) { i++; - INT32 anAbsoluteValue = 0; - for(int j = 0; j < 4; j++) - anAbsoluteValue += UINT32(m_Buffer[i + j]) << (j * 8); - - INT32 aPos = m_ProcessedSize + i - 1; - UINT32 anOffset; - if (anAbsoluteValue < -aPos || anAbsoluteValue >= INT32(m_TranslationSize)) + Int32 absValue = 0; + int j; + for(j = 0; j < 4; j++) + absValue += UInt32(m_Buffer[i + j]) << (j * 8); + + Int32 pos = m_ProcessedSize + i - 1; + UInt32 offset; + if (absValue < -pos || absValue >= Int32(m_TranslationSize)) { } else { - anOffset = (anAbsoluteValue >= 0) ? - anAbsoluteValue - aPos : - anAbsoluteValue + m_TranslationSize; + offset = (absValue >= 0) ? + absValue - pos : + absValue + m_TranslationSize; for(j = 0; j < 4; j++) { - m_Buffer[i + j] = BYTE(anOffset & 0xFF); - anOffset >>= 8; + m_Buffer[i + j] = Byte(offset & 0xFF); + offset >>= 8; } } i += 4; @@ -79,32 +50,32 @@ void Ci86TranslationOutStream::MakeTranslation() } } -STDMETHODIMP Ci86TranslationOutStream::Write(const void *aData, UINT32 aSize, UINT32 *aProcessedSize) +STDMETHODIMP Ci86TranslationOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) { if (!m_TranslationMode) - return m_Stream->Write(aData, aSize, aProcessedSize); + return m_Stream->Write(data, size, processedSize); - UINT32 aProcessedSizeReal = 0; + UInt32 realProcessedSize = 0; - while (aProcessedSizeReal < aSize) + while (realProcessedSize < size) { - UINT32 aWriteSize = MyMin(aSize - aProcessedSizeReal, kUncompressedBlockSize - m_Pos); - memmove(m_Buffer + m_Pos, (const BYTE *)aData + aProcessedSizeReal, aWriteSize); - m_Pos += aWriteSize; - aProcessedSizeReal += aWriteSize; + UInt32 writeSize = MyMin(size - realProcessedSize, kUncompressedBlockSize - m_Pos); + memmove(m_Buffer + m_Pos, (const Byte *)data + realProcessedSize, writeSize); + m_Pos += writeSize; + realProcessedSize += writeSize; if (m_Pos == kUncompressedBlockSize) { RINOK(Flush()); } } - if (aProcessedSize != NULL) - *aProcessedSize = aProcessedSizeReal; + if (processedSize != NULL) + *processedSize = realProcessedSize; return S_OK; } -STDMETHODIMP Ci86TranslationOutStream::WritePart(const void *aData, UINT32 aSize, UINT32 *aProcessedSize) +STDMETHODIMP Ci86TranslationOutStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize) { - return Write(aData, aSize, aProcessedSize); + return Write(data, size, processedSize); } HRESULT Ci86TranslationOutStream::Flush() @@ -119,6 +90,4 @@ HRESULT Ci86TranslationOutStream::Flush() return S_OK; } - }}} - diff --git a/7zip/Archive/Cab/LZXi86Converter.h b/7zip/Archive/Cab/LZXi86Converter.h index 10507cdb..625fa506 100755 --- a/7zip/Archive/Cab/LZXi86Converter.h +++ b/7zip/Archive/Cab/LZXi86Converter.h @@ -1,7 +1,5 @@ // Archive/Cab/LZXi86Converter.h -#pragma once - #ifndef __ARCHIVE_CAB_LZXI86CONVERTER_H #define __ARCHIVE_CAB_LZXI86CONVERTER_H @@ -20,27 +18,33 @@ class Ci86TranslationOutStream: { bool m_TranslationMode; CMyComPtr<ISequentialOutStream> m_Stream; - UINT32 m_ProcessedSize; - BYTE m_Buffer[kUncompressedBlockSize]; - UINT32 m_Pos; - UINT32 m_TranslationSize; + UInt32 m_ProcessedSize; + Byte m_Buffer[kUncompressedBlockSize]; + UInt32 m_Pos; + UInt32 m_TranslationSize; - INT32 ConvertAbsoluteToOffset(INT32 aPos, INT32 anAbsoluteValue); void MakeTranslation(); public: - Ci86TranslationOutStream(); - ~Ci86TranslationOutStream(); + Ci86TranslationOutStream(): m_Pos(0) {} + ~Ci86TranslationOutStream() { Flush(); } MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *aData, UINT32 aSize, UINT32 *aProcessedSize); - STDMETHOD(WritePart)(const void *aData, UINT32 aSize, UINT32 *aProcessedSize); + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); public: - void Init(ISequentialOutStream *aStream, bool aTranslationMode, UINT32 aTranslationSize); + void Init(ISequentialOutStream *outStream, bool translationMode, UInt32 translationSize) + { + m_Stream = outStream; + m_TranslationMode = translationMode; + m_TranslationSize = translationSize; + m_ProcessedSize = 0; + m_Pos = 0; + } + void ReleaseStream() { m_Stream.Release(); } HRESULT Flush(); - void ReleaseStream(); }; }}} -#endif
\ No newline at end of file +#endif diff --git a/7zip/Archive/Cab/MSZipConst.h b/7zip/Archive/Cab/MSZipConst.h index 1a72cfe2..f2dfda86 100755 --- a/7zip/Archive/Cab/MSZipConst.h +++ b/7zip/Archive/Cab/MSZipConst.h @@ -1,7 +1,5 @@ // MSZipConst.h -#pragma once - #ifndef __MSZIP_CONST_H #define __MSZIP_CONST_H @@ -11,46 +9,46 @@ namespace NArchive { namespace NCab { namespace NMSZip { -const UINT32 kLenTableSize = 29; +const UInt32 kLenTableSize = 29; -const UINT32 kStaticDistTableSize = 32; -const UINT32 kStaticLenTableSize = 31; +const UInt32 kStaticDistTableSize = 32; +const UInt32 kStaticLenTableSize = 31; -const UINT32 kReadTableNumber = 0x100; -const UINT32 kMatchNumber = kReadTableNumber + 1; +const UInt32 kReadTableNumber = 0x100; +const UInt32 kMatchNumber = kReadTableNumber + 1; -const UINT32 kMainTableSize = kMatchNumber + kLenTableSize; //298; -const UINT32 kStaticMainTableSize = kMatchNumber + kStaticLenTableSize; //298; +const UInt32 kMainTableSize = kMatchNumber + kLenTableSize; //298; +const UInt32 kStaticMainTableSize = kMatchNumber + kStaticLenTableSize; //298; -const UINT32 kDistTableStart = kMainTableSize; +const UInt32 kDistTableStart = kMainTableSize; -const UINT32 kHeapTablesSizesSum = kMainTableSize + kDistTableSize; +const UInt32 kHeapTablesSizesSum = kMainTableSize + kDistTableSize; -const UINT32 kLevelTableSize = 19; +const UInt32 kLevelTableSize = 19; -const UINT32 kMaxTableSize = kHeapTablesSizesSum; // test it -const UINT32 kStaticMaxTableSize = kStaticMainTableSize + kStaticDistTableSize; +const UInt32 kMaxTableSize = kHeapTablesSizesSum; // test it +const UInt32 kStaticMaxTableSize = kStaticMainTableSize + kStaticDistTableSize; -const UINT32 kTableDirectLevels = 16; -const UINT32 kTableLevelRepNumber = kTableDirectLevels; -const UINT32 kTableLevel0Number = kTableLevelRepNumber + 1; -const UINT32 kTableLevel0Number2 = kTableLevel0Number + 1; +const UInt32 kTableDirectLevels = 16; +const UInt32 kTableLevelRepNumber = kTableDirectLevels; +const UInt32 kTableLevel0Number = kTableLevelRepNumber + 1; +const UInt32 kTableLevel0Number2 = kTableLevel0Number + 1; -const UINT32 kLevelMask = 0xF; +const UInt32 kLevelMask = 0xF; -const BYTE kLenStart[kLenTableSize] = {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224, 255}; -const BYTE kLenDirectBits[kLenTableSize] = {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0}; +const Byte kLenStart[kLenTableSize] = {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224, 255}; +const Byte kLenDirectBits[kLenTableSize] = {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0}; -const UINT32 kDistStart[kDistTableSize] = {0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576}; -const BYTE kDistDirectBits[kDistTableSize] = {0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; +const UInt32 kDistStart[kDistTableSize] = {0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576}; +const Byte kDistDirectBits[kDistTableSize] = {0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; -const BYTE kLevelDirectBits[kLevelTableSize] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7}; +const Byte kLevelDirectBits[kLevelTableSize] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7}; -const BYTE kCodeLengthAlphabetOrder[kLevelTableSize] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; +const Byte kCodeLengthAlphabetOrder[kLevelTableSize] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; -const UINT32 kMatchMinLen = 3; -const UINT32 kMatchMaxLen = kNumLenCombinations + kMatchMinLen - 1; //255 + 2; test it +const UInt32 kMatchMinLen = 3; +const UInt32 kMatchMaxLen = kNumLenCombinations + kMatchMinLen - 1; //255 + 2; test it const int kFinalBlockFieldSize = 1; @@ -76,18 +74,18 @@ namespace NBlockType }; } -const UINT32 kDeflateNumberOfLengthCodesFieldSize = 5; -const UINT32 kDeflateNumberOfDistanceCodesFieldSize = 5; -const UINT32 kDeflateNumberOfLevelCodesFieldSize = 4; +const UInt32 kDeflateNumberOfLengthCodesFieldSize = 5; +const UInt32 kDeflateNumberOfDistanceCodesFieldSize = 5; +const UInt32 kDeflateNumberOfLevelCodesFieldSize = 4; -const UINT32 kDeflateNumberOfLitLenCodesMin = 257; +const UInt32 kDeflateNumberOfLitLenCodesMin = 257; -const UINT32 kDeflateNumberOfDistanceCodesMin = 1; -const UINT32 kDeflateNumberOfLevelCodesMin = 4; +const UInt32 kDeflateNumberOfDistanceCodesMin = 1; +const UInt32 kDeflateNumberOfLevelCodesMin = 4; -const UINT32 kDeflateLevelCodeFieldSize = 3; +const UInt32 kDeflateLevelCodeFieldSize = 3; -const UINT32 kDeflateStoredBlockLengthFieldSizeSize = 16; +const UInt32 kDeflateStoredBlockLengthFieldSizeSize = 16; }}} diff --git a/7zip/Archive/Cab/MSZipDecoder.cpp b/7zip/Archive/Cab/MSZipDecoder.cpp index 92326e32..d9fb9f82 100755 --- a/7zip/Archive/Cab/MSZipDecoder.cpp +++ b/7zip/Archive/Cab/MSZipDecoder.cpp @@ -3,7 +3,6 @@ #include "StdAfx.h" #include "MSZipDecoder.h" -#include "MSZipConst.h" #include "Windows/Defs.h" @@ -11,13 +10,7 @@ namespace NArchive { namespace NCab { namespace NMSZip { -CDecoder::CDecoder(): - m_MainDecoder(kStaticMainTableSize), - m_DistDecoder(kStaticDistTableSize), - m_LevelDecoder(kLevelTableSize) -{ - m_OutWindowStream.Create(kHistorySize); -} +CDecoder::CDecoder(){} HRESULT CDecoder::Flush() { @@ -32,14 +25,14 @@ void CDecoder::ReleaseStreams() } */ -void CDecoder::DeCodeLevelTable(BYTE *newLevels, int numLevels) +void CDecoder::DeCodeLevelTable(Byte *newLevels, int numLevels) { int i = 0; while (i < numLevels) { - UINT32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream); + UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream); if (number < kTableDirectLevels) - newLevels[i++] = BYTE(number); + newLevels[i++] = Byte(number); else { if (number == kTableLevelRepNumber) @@ -76,8 +69,8 @@ void CDecoder::ReadTables(void) case NBlockType::kStored: { m_StoredMode = true; - UINT32 currentBitPosition = m_InBitStream.GetBitPosition(); - UINT32 numBitsForAlign = currentBitPosition > 0 ? (8 - currentBitPosition): 0; + UInt32 currentBitPosition = m_InBitStream.GetBitPosition(); + UInt32 numBitsForAlign = currentBitPosition > 0 ? (8 - currentBitPosition): 0; if (numBitsForAlign > 0) m_InBitStream.ReadBits(numBitsForAlign); m_StoredBlockSize = m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize); @@ -90,8 +83,8 @@ void CDecoder::ReadTables(void) case NBlockType::kDynamicHuffman: { m_StoredMode = false; - BYTE litLenLevels[kStaticMainTableSize]; - BYTE distLevels[kStaticDistTableSize]; + Byte litLenLevels[kStaticMainTableSize]; + Byte distLevels[kStaticDistTableSize]; if (blockType == NBlockType::kFixedHuffman) { int i; @@ -122,13 +115,13 @@ void CDecoder::ReadTables(void) int numLevels; numLevels = kHeapTablesSizesSum; - BYTE levelLevels[kLevelTableSize]; + Byte levelLevels[kLevelTableSize]; int i; for (i = 0; i < kLevelTableSize; i++) { int position = kCodeLengthAlphabetOrder[i]; if(i < numLevelCodes) - levelLevels[position] = BYTE(m_InBitStream.ReadBits(kDeflateLevelCodeFieldSize)); + levelLevels[position] = Byte(m_InBitStream.ReadBits(kDeflateLevelCodeFieldSize)); else levelLevels[position] = 0; } @@ -142,7 +135,7 @@ void CDecoder::ReadTables(void) throw CDecoderException(CDecoderException::kData); } - BYTE tmpLevels[kStaticMaxTableSize]; + Byte tmpLevels[kStaticMaxTableSize]; DeCodeLevelTable(tmpLevels, numLitLenLevels + numDistLevels); memmove(litLenLevels, tmpLevels, numLitLenLevels); @@ -181,26 +174,34 @@ public: }; STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { if (outSize == NULL) return E_INVALIDARG; - UINT64 size = *outSize; + UInt64 size = *outSize; + + if (!m_OutWindowStream.Create(kHistorySize)) + return E_OUTOFMEMORY; + if (!m_InBitStream.Create(1 << 20)) + return E_OUTOFMEMORY; - m_OutWindowStream.Init(outStream, false); - m_InBitStream.InitMain(inStream, m_ReservedSize, m_NumInDataBlocks); + m_OutWindowStream.SetStream(outStream); + m_OutWindowStream.Init(false); + + m_InBitStream.SetStream(inStream); + m_InBitStream.InitMain(m_ReservedSize, m_NumInDataBlocks); CCoderReleaser coderReleaser(this); - UINT64 nowPos = 0; + UInt64 nowPos = 0; while(nowPos < size) { if (progress != NULL) { - UINT64 packSize = m_InBitStream.GetProcessedSize(); + UInt64 packSize = m_InBitStream.GetProcessedSize(); RINOK(progress->SetRatioInfo(&packSize, &nowPos)); } - UINT32 uncompressedCFDataBlockSize; + UInt32 uncompressedCFDataBlockSize; bool dataAreCorrect; RINOK(m_InBitStream.ReadBlock(uncompressedCFDataBlockSize, dataAreCorrect)); if (!dataAreCorrect) @@ -212,26 +213,26 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, throw CDecoderException(CDecoderException::kData); if (m_InBitStream.ReadBits(8) != 0x4B) throw CDecoderException(CDecoderException::kData); - UINT32 uncompressedCFDataCurrentValue = 0; + UInt32 uncompressedCFDataCurrentValue = 0; m_FinalBlock = false; while (uncompressedCFDataCurrentValue < uncompressedCFDataBlockSize) { ReadTables(); if(m_StoredMode) { - for (UINT32 i = 0; i < m_StoredBlockSize; i++) - m_OutWindowStream.PutOneByte(BYTE(m_InBitStream.ReadBits(8))); + for (UInt32 i = 0; i < m_StoredBlockSize; i++) + m_OutWindowStream.PutByte(Byte(m_InBitStream.ReadBits(8))); nowPos += m_StoredBlockSize; uncompressedCFDataCurrentValue += m_StoredBlockSize; continue; } while(true) { - UINT32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream); + UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream); if (number < 256) { - m_OutWindowStream.PutOneByte(BYTE(number)); + m_OutWindowStream.PutByte(Byte(number)); nowPos++; uncompressedCFDataCurrentValue++; continue; @@ -239,18 +240,18 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, else if (number >= kMatchNumber) { number -= kMatchNumber; - UINT32 length = UINT32(kLenStart[number]) + kMatchMinLen; - UINT32 numBits; + UInt32 length = UInt32(kLenStart[number]) + kMatchMinLen; + UInt32 numBits; if ((numBits = kLenDirectBits[number]) > 0) length += m_InBitStream.ReadBits(numBits); number = m_DistDecoder.DecodeSymbol(&m_InBitStream); - UINT32 distance = kDistStart[number] + m_InBitStream.ReadBits(kDistDirectBits[number]); + UInt32 distance = kDistStart[number] + m_InBitStream.ReadBits(kDistDirectBits[number]); /* if (distance >= nowPos) throw "data error"; */ - m_OutWindowStream.CopyBackBlock(distance, length); + m_OutWindowStream.CopyBlock(distance, length); nowPos += length; uncompressedCFDataCurrentValue += length; } diff --git a/7zip/Archive/Cab/MSZipDecoder.h b/7zip/Archive/Cab/MSZipDecoder.h index 2fa40df0..166befbb 100755 --- a/7zip/Archive/Cab/MSZipDecoder.h +++ b/7zip/Archive/Cab/MSZipDecoder.h @@ -1,7 +1,5 @@ // Archive/Cab/MSZipDecoder.h -#pragma once - #ifndef __ARCHIVE_CAB_DECODER_H #define __ARCHIVE_CAB_DECODER_H @@ -13,6 +11,7 @@ #include "CabInBuffer.h" #include "MSZipExtConst.h" +#include "MSZipConst.h" namespace NArchive { namespace NCab { @@ -31,37 +30,35 @@ public: class CMSZipBitDecoder: public NStream::NLSBF::CDecoder<NCab::CInBuffer> { public: - void InitMain(ISequentialInStream *aStream, BYTE aReservedSize, UINT32 aNumBlocks) + void InitMain(Byte reservedSize, UInt32 aNumBlocks) { - m_Stream.Init(aStream, aReservedSize, aNumBlocks); + m_Stream.Init(reservedSize, aNumBlocks); Init(); } - HRESULT ReadBlock(UINT32 &anUncompressedSize, bool &aDataAreCorrect) + HRESULT ReadBlock(UInt32 &uncompressedSize, bool &dataAreCorrect) { - return m_Stream.ReadBlock(anUncompressedSize, aDataAreCorrect); + return m_Stream.ReadBlock(uncompressedSize, dataAreCorrect); } }; -typedef NCompress::NHuffman::CDecoder<kNumHuffmanBits> CHuffmanDecoder; - class CDecoder : public ICompressCoder, public CMyUnknownImp { CLZOutWindow m_OutWindowStream; CMSZipBitDecoder m_InBitStream; - CHuffmanDecoder m_MainDecoder; - CHuffmanDecoder m_DistDecoder; - CHuffmanDecoder m_LevelDecoder; // table for decoding other tables; + NCompress::NHuffman::CDecoder<kNumHuffmanBits, kStaticMainTableSize> m_MainDecoder; + NCompress::NHuffman::CDecoder<kNumHuffmanBits, kStaticDistTableSize> m_DistDecoder; + NCompress::NHuffman::CDecoder<kNumHuffmanBits, kLevelTableSize> m_LevelDecoder; bool m_FinalBlock; bool m_StoredMode; - UINT32 m_StoredBlockSize; + UInt32 m_StoredBlockSize; - BYTE m_ReservedSize; - UINT32 m_NumInDataBlocks; + Byte m_ReservedSize; + UInt32 m_NumInDataBlocks; - void DeCodeLevelTable(BYTE *newLevels, int numLevels); + void DeCodeLevelTable(Byte *newLevels, int numLevels); void ReadTables(); public: CDecoder(); @@ -72,13 +69,13 @@ public: // void ReleaseStreams(); STDMETHOD(Code)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - void SetParams(BYTE aReservedSize, UINT32 aNumInDataBlocks) + void SetParams(Byte reservedSize, UInt32 numInDataBlocks) { - m_ReservedSize = aReservedSize; - m_NumInDataBlocks = aNumInDataBlocks; + m_ReservedSize = reservedSize; + m_NumInDataBlocks = numInDataBlocks; } }; diff --git a/7zip/Archive/Cab/MSZipExtConst.h b/7zip/Archive/Cab/MSZipExtConst.h index 864d9eda..f51eebb8 100755 --- a/7zip/Archive/Cab/MSZipExtConst.h +++ b/7zip/Archive/Cab/MSZipExtConst.h @@ -1,7 +1,5 @@ // DeflateExtConst.h -#pragma once - #ifndef __DEFLATEEXTCONST_H #define __DEFLATEEXTCONST_H @@ -11,11 +9,11 @@ namespace NArchive { namespace NCab { namespace NMSZip { - const UINT32 kDistTableSize = 30; - const UINT32 kHistorySize = 0x8000; - const UINT32 kNumLenCombinations = 256; + const UInt32 kDistTableSize = 30; + const UInt32 kHistorySize = 0x8000; + const UInt32 kNumLenCombinations = 256; - const UINT32 kNumHuffmanBits = 15; + const UInt32 kNumHuffmanBits = 15; }}} diff --git a/7zip/Archive/Cab/StdAfx.cpp b/7zip/Archive/Cab/StdAfx.cpp index 2550270c..d0feea85 100755 --- a/7zip/Archive/Cab/StdAfx.cpp +++ b/7zip/Archive/Cab/StdAfx.cpp @@ -1,3 +1,3 @@ // StdAfx.cpp -#include "stdafx.h" +#include "StdAfx.h" diff --git a/7zip/Archive/Cab/StdAfx.h b/7zip/Archive/Cab/StdAfx.h index 6075e527..e7fb6986 100755 --- a/7zip/Archive/Cab/StdAfx.h +++ b/7zip/Archive/Cab/StdAfx.h @@ -1,9 +1,8 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> -#include <time.h> +#include "../../../Common/MyWindows.h" -#endif +#endif diff --git a/7zip/Archive/Cab/resource.rc b/7zip/Archive/Cab/resource.rc index 872aa57d..7def097a 100755 --- a/7zip/Archive/Cab/resource.rc +++ b/7zip/Archive/Cab/resource.rc @@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,12,0,0 - PRODUCTVERSION 3,12,0,0 + FILEVERSION 4,19,0,0 + PRODUCTVERSION 4,19,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -85,14 +85,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Igor Pavlov \0" VALUE "FileDescription", "Cab Plugin for 7-Zip\0" - VALUE "FileVersion", "3, 12, 0, 0\0" + VALUE "FileVersion", "4, 19, 0, 0\0" VALUE "InternalName", "cab\0" - VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "cab.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "7-Zip\0" - VALUE "ProductVersion", "3, 12, 0, 0\0" + VALUE "ProductVersion", "4, 19, 0, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/7zip/Archive/Common/CodecsPath.h b/7zip/Archive/Common/CodecsPath.h index d0fe7351..11145a03 100755 --- a/7zip/Archive/Common/CodecsPath.h +++ b/7zip/Archive/Common/CodecsPath.h @@ -1,7 +1,5 @@ // CodecsPath.h -#pragma once - #ifndef __CODECSPATH_H #define __CODECSPATH_H diff --git a/7zip/Archive/Common/CoderLoader.cpp b/7zip/Archive/Common/CoderLoader.cpp new file mode 100755 index 00000000..bf54f6e0 --- /dev/null +++ b/7zip/Archive/Common/CoderLoader.cpp @@ -0,0 +1,31 @@ +// CoderLoader.cpp + +#include "StdAfx.h" + +#include "CoderLoader.h" +#include "FilterCoder.h" + +HRESULT CCoderLibrary::CreateCoderSpec(REFGUID clsID, ICompressCoder **coder) +{ + HRESULT result = CreateObject(clsID, IID_ICompressCoder, (void **)coder); + if (result == S_OK || result != E_NOINTERFACE) + return result; + CMyComPtr<ICompressFilter> filter; + RINOK(CreateObject(clsID, IID_ICompressFilter, (void **)&filter)); + CFilterCoder *filterCoderSpec = new CFilterCoder; + CMyComPtr<ICompressCoder> filterCoder = filterCoderSpec; + filterCoderSpec->Filter = filter; + *coder = filterCoder.Detach(); + return S_OK; +} + + +HRESULT CCoderLibrary::LoadAndCreateCoderSpec(LPCTSTR filePath, REFGUID clsID, ICompressCoder **coder) +{ + CCoderLibrary libTemp; + if (!libTemp.Load(filePath)) + return GetLastError(); + RINOK(libTemp.CreateCoderSpec(clsID, coder)); + Attach(libTemp.Detach()); + return S_OK; +} diff --git a/7zip/Archive/Common/CoderLoader.h b/7zip/Archive/Common/CoderLoader.h index 397c4798..1679a96f 100755 --- a/7zip/Archive/Common/CoderLoader.h +++ b/7zip/Archive/Common/CoderLoader.h @@ -1,16 +1,14 @@ // CoderLoader.h -#pragma once - #ifndef __CODERLOADER_H #define __CODERLOADER_H #include "../../../Common/String.h" +#include "../../../Common/MyCom.h" #include "../../../Windows/DLL.h" -// #include "../../../Windows/Defs.h" #include "../../ICoder.h" -typedef UINT32 (WINAPI * CreateObjectPointer)( +typedef UInt32 (WINAPI * CreateObjectPointer)( const GUID *clsID, const GUID *interfaceID, void **outObject); @@ -18,14 +16,38 @@ typedef UINT32 (WINAPI * CreateObjectPointer)( class CCoderLibrary: public NWindows::NDLL::CLibrary { public: - HRESULT CreateCoder(REFGUID clsID, ICompressCoder **coder) + HRESULT CreateObject(REFGUID clsID, REFGUID iid, void **obj) { CreateObjectPointer createObject = (CreateObjectPointer) - GetProcAddress("CreateObject"); + GetProcAddress("CreateObject"); if (createObject == NULL) return GetLastError(); - return createObject(&clsID, &IID_ICompressCoder, (void **)coder); + return createObject(&clsID, &iid, obj); + } + + HRESULT CreateFilter(REFGUID clsID, ICompressFilter **filter) + { + return CreateObject(clsID, IID_ICompressFilter, (void **)filter); + } + + HRESULT CreateCoder(REFGUID clsID, ICompressCoder **coder) + { + return CreateObject(clsID, IID_ICompressCoder, (void **)coder); + } + + HRESULT CreateCoderSpec(REFGUID clsID, ICompressCoder **coder); + + HRESULT LoadAndCreateFilter(LPCTSTR filePath, REFGUID clsID, ICompressFilter **filter) + { + CCoderLibrary libTemp; + if (!libTemp.Load(filePath)) + return GetLastError(); + RINOK(libTemp.CreateFilter(clsID, filter)); + Attach(libTemp.Detach()); + return S_OK; } + + HRESULT LoadAndCreateCoder(LPCTSTR filePath, REFGUID clsID, ICompressCoder **coder) { CCoderLibrary libTemp; @@ -35,6 +57,8 @@ public: Attach(libTemp.Detach()); return S_OK; } + + HRESULT LoadAndCreateCoderSpec(LPCTSTR filePath, REFGUID clsID, ICompressCoder **coder); HRESULT CreateCoder2(REFGUID clsID, ICompressCoder2 **coder) { CreateObjectPointer createObject = (CreateObjectPointer) @@ -87,6 +111,21 @@ public: return Pairs[index].Libary.CreateCoder(clsID, coder); } + HRESULT CreateCoderSpec(LPCTSTR filePath, REFGUID clsID, ICompressCoder **coder) + { + int index = FindPath(filePath); + if (index < 0) + { + CPathToLibraryPair pair; + RINOK(pair.Libary.LoadAndCreateCoderSpec(filePath, clsID, coder)); + pair.Path = filePath; + Pairs.Add(pair); + pair.Libary.Detach(); + return S_OK; + } + return Pairs[index].Libary.CreateCoderSpec(clsID, coder); + } + HRESULT CreateCoder2(LPCTSTR filePath, REFGUID clsID, ICompressCoder2 **coder) { int index = FindPath(filePath); diff --git a/7zip/Archive/Common/CoderMixer.cpp b/7zip/Archive/Common/CoderMixer.cpp deleted file mode 100755 index f18feafd..00000000 --- a/7zip/Archive/Common/CoderMixer.cpp +++ /dev/null @@ -1,238 +0,0 @@ -// CoderMixer.cpp - -#include "StdAfx.h" - -#include "CoderMixer.h" -#include "Common/Defs.h" -#include "CrossThreadProgress.h" - -using namespace NWindows; -using namespace NSynchronization; - -////////////////////////// -// CThreadCoderInfo - -void CThreadCoderInfo::CreateEvents() -{ - CompressEvent = new CAutoResetEvent(false); - CompressionCompletedEvent = new CAutoResetEvent(false); -} - -CThreadCoderInfo::~CThreadCoderInfo() -{ - if (CompressEvent != NULL) - delete CompressEvent; - if (CompressionCompletedEvent != NULL) - delete CompressionCompletedEvent; -} - -class CCoderInfoFlusher -{ - CThreadCoderInfo *m_CoderInfo; -public: - CCoderInfoFlusher(CThreadCoderInfo *coderInfo): m_CoderInfo(coderInfo) {} - ~CCoderInfoFlusher() - { - m_CoderInfo->InStream.Release(); - m_CoderInfo->OutStream.Release(); - m_CoderInfo->CompressionCompletedEvent->Set(); - } -}; - -bool CThreadCoderInfo::WaitAndCode() -{ - HANDLE events[2] = { ExitEvent, *CompressEvent }; - DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE); - if (waitResult == WAIT_OBJECT_0 + 0) - return false; - - { - CCoderInfoFlusher coderInfoFlusher(this); - Result = Coder->Code(InStream, OutStream, - InSizeAssigned ? &InSizeValue : NULL, - OutSizeAssigned ? &OutSizeValue : NULL, - Progress); - } - return true; -} - - -DWORD WINAPI CoderThread(void *threadCoderInfo) -{ - while(true) - { - if (!((CThreadCoderInfo *)threadCoderInfo)->WaitAndCode()) - return 0; - } -} - -////////////////////////// -// CCoderMixer - -static DWORD WINAPI MainCoderThread(void *threadCoderInfo) -{ - while(true) - { - if (!((CCoderMixer *)threadCoderInfo)->MyCode()) - return 0; - } -} - -CCoderMixer::CCoderMixer() -{ - if (!m_MainThread.Create(MainCoderThread, this)) - throw 271825; -} - -CCoderMixer::~CCoderMixer() -{ - ExitEvent.Set(); - ::WaitForSingleObject(m_MainThread, INFINITE); - DWORD result = ::WaitForMultipleObjects(m_Threads.Size(), - &m_Threads.Front(), TRUE, INFINITE); - for(int i = 0; i < m_Threads.Size(); i++) - ::CloseHandle(m_Threads[i]); -} - - -void CCoderMixer::AddCoder(ICompressCoder *coder) -{ - CThreadCoderInfo threadCoderInfo; - threadCoderInfo.Coder = coder; - m_CoderInfoVector.Add(threadCoderInfo); - m_CoderInfoVector.Back().CreateEvents(); - m_CoderInfoVector.Back().ExitEvent = ExitEvent; - m_CompressingCompletedEvents.Add(*m_CoderInfoVector.Back().CompressionCompletedEvent); -} - -void CCoderMixer::FinishAddingCoders() -{ - for(int i = 0; i < m_CoderInfoVector.Size(); i++) - { - DWORD id; - HANDLE newThread = ::CreateThread(NULL, 0, CoderThread, - &m_CoderInfoVector[i], 0, &id); - if (newThread == 0) - throw 271824; - m_Threads.Add(newThread); - if (i >= 1) - { - CStreamBinder streamBinder; - m_StreamBinders.Add(streamBinder); - m_StreamBinders.Back().CreateEvents(); - } - } -} - -void CCoderMixer::ReInit() -{ - int i; - for(i = 0; i < m_CoderInfoVector.Size(); i++) - { - CThreadCoderInfo &coderInfo = m_CoderInfoVector[i]; - coderInfo.InSizeAssigned = false; - coderInfo.OutSizeAssigned = false; - coderInfo.Progress = NULL; - } - for(i = 0; i < m_StreamBinders.Size(); i++) - { - m_StreamBinders[i].ReInit(); - } -} - -void CCoderMixer::SetCoderInfo(UINT32 coderIndex, const UINT64 *inSize, - const UINT64 *outSize) -{ - CThreadCoderInfo &coderInfo = m_CoderInfoVector[coderIndex]; - - coderInfo.InSizeAssigned = (inSize != NULL); - if (coderInfo.InSizeAssigned) - coderInfo.InSizeValue = *inSize; - - coderInfo.OutSizeAssigned = (outSize != NULL); - if (coderInfo.OutSizeAssigned) - coderInfo.OutSizeValue = *outSize; - - coderInfo.Progress = NULL; -} - -STDMETHODIMP CCoderMixer::Init(ISequentialInStream *inStreamMain, - ISequentialOutStream *outStreamMain) -{ - m_CoderInfoVector.Front().InStream = inStreamMain; - for(int i = 0; i < m_StreamBinders.Size(); i++) - m_StreamBinders[i].CreateStreams(&m_CoderInfoVector[i+1].InStream, - &m_CoderInfoVector[i].OutStream); - m_CoderInfoVector.Back().OutStream = outStreamMain; - - return S_OK; -} - -bool CCoderMixer::MyCode() -{ - HANDLE events[2] = { ExitEvent, m_StartCompressingEvent }; - DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE); - if (waitResult == WAIT_OBJECT_0 + 0) - return false; - - for(int i = 0; i < m_CoderInfoVector.Size(); i++) - m_CoderInfoVector[i].CompressEvent->Set(); - DWORD result = ::WaitForMultipleObjects(m_CompressingCompletedEvents.Size(), - &m_CompressingCompletedEvents.Front(), TRUE, INFINITE); - - m_CompressingFinishedEvent.Set(); - - return true; -} - -STDMETHODIMP CCoderMixer::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, - const UINT64 *inSize, const UINT64 *outSize, - ICompressProgressInfo *progress) -{ - Init(inStream, outStream); - - m_CompressingFinishedEvent.Reset(); // ? - - CCrossThreadProgress *progressSpec = new CCrossThreadProgress; - CMyComPtr<ICompressProgressInfo> crossProgress = progressSpec; - progressSpec->Init(); - m_CoderInfoVector[m_ProgressCoderIndex].Progress = crossProgress; - - m_StartCompressingEvent.Set(); - - while (true) - { - HANDLE events[2] = {m_CompressingFinishedEvent, progressSpec->ProgressEvent }; - DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE); - if (waitResult == WAIT_OBJECT_0 + 0) - break; - if (progress != NULL) - progressSpec->Result = progress->SetRatioInfo(progressSpec->InSize, - progressSpec->OutSize); - else - progressSpec->Result = S_OK; - progressSpec->WaitEvent.Set(); - } - - int i; - for(i = 0; i < m_CoderInfoVector.Size(); i++) - { - HRESULT result = m_CoderInfoVector[i].Result; - if (result == S_FALSE) - return result; - } - for(i = 0; i < m_CoderInfoVector.Size(); i++) - { - HRESULT result = m_CoderInfoVector[i].Result; - if (result != S_OK) - return result; - } - return S_OK; -} - -UINT64 CCoderMixer::GetWriteProcessedSize(UINT32 coderIndex) -{ - return m_StreamBinders[coderIndex].ProcessedSize; -} - diff --git a/7zip/Archive/Common/CoderMixer.h b/7zip/Archive/Common/CoderMixer.h deleted file mode 100755 index 7851206c..00000000 --- a/7zip/Archive/Common/CoderMixer.h +++ /dev/null @@ -1,87 +0,0 @@ -// CoderMixer.h - -#pragma once - -#ifndef __CODERMIXER_H -#define __CODERMIXER_H - -#include "Common/Vector.h" -#include "Common/MyCom.h" -#include "Windows/Thread.h" -#include "../../Common/StreamBinder.h" -#include "../../ICoder.h" - -struct CThreadCoderInfo -{ - NWindows::NSynchronization::CAutoResetEvent *CompressEvent; - HANDLE ExitEvent; - NWindows::NSynchronization::CAutoResetEvent *CompressionCompletedEvent; - - CMyComPtr<ICompressCoder> Coder; - CMyComPtr<ISequentialInStream> InStream; - CMyComPtr<ISequentialOutStream> OutStream; - UINT64 InSizeValue; - UINT64 OutSizeValue; - bool InSizeAssigned; - bool OutSizeAssigned; - ICompressProgressInfo *Progress; - HRESULT Result; - - CThreadCoderInfo(): ExitEvent(NULL), CompressEvent(NULL), - CompressionCompletedEvent(NULL), - InSizeAssigned(false), - OutSizeAssigned(false), Progress(NULL){} - ~CThreadCoderInfo(); - bool WaitAndCode(); - void CreateEvents(); -}; - - -class CCoderMixer: - public ICompressCoder, - public CMyUnknownImp -{ - MY_UNKNOWN_IMP - -public: - STDMETHOD(Init)(ISequentialInStream *inStream, - ISequentialOutStream *outStream); - // STDMETHOD(ReleaseStreams)(); - // STDMETHOD(Code)(UINT32 size, UINT32 &processedSize); - // STDMETHOD(Flush)(); - - STDMETHOD(Code)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, - const UINT64 *inSize, const UINT64 *outSize, - ICompressProgressInfo *progress); - - - CCoderMixer(); - ~CCoderMixer(); - void AddCoder(ICompressCoder *aCoder); - void FinishAddingCoders(); - - void ReInit(); - void SetCoderInfo(UINT32 coderIndex, - const UINT64 *inSize, const UINT64 *outSize); - void SetProgressCoderIndex(UINT32 coderIndex) - { m_ProgressCoderIndex = coderIndex; } - UINT64 GetWriteProcessedSize(UINT32 coderIndex); - - bool MyCode(); -private: - CObjectVector<CStreamBinder> m_StreamBinders; - CObjectVector<CThreadCoderInfo> m_CoderInfoVector; - CRecordVector<HANDLE> m_Threads; - NWindows::CThread m_MainThread; - - NWindows::NSynchronization::CAutoResetEvent m_StartCompressingEvent; - CRecordVector<HANDLE> m_CompressingCompletedEvents; - NWindows::NSynchronization::CAutoResetEvent m_CompressingFinishedEvent; - - NWindows::NSynchronization::CManualResetEvent ExitEvent; - UINT32 m_ProgressCoderIndex; -}; - -#endif - diff --git a/7zip/Archive/Common/CoderMixer2.cpp b/7zip/Archive/Common/CoderMixer2.cpp index 6bd57375..8f46e985 100755 --- a/7zip/Archive/Common/CoderMixer2.cpp +++ b/7zip/Archive/Common/CoderMixer2.cpp @@ -3,13 +3,6 @@ #include "StdAfx.h" #include "CoderMixer2.h" -#include "CrossThreadProgress.h" - -using namespace NWindows; -using namespace NSynchronization; - -////////////////////////// -// CThreadCoderInfo2 namespace NCoderMixer2 { @@ -18,7 +11,7 @@ CBindReverseConverter::CBindReverseConverter(const CBindInfo &srcBindInfo): { srcBindInfo.GetNumStreams(NumSrcInStreams, _numSrcOutStreams); - UINT32 j; + UInt32 j; for (j = 0; j < NumSrcInStreams; j++) { _srcInToDestOutMap.Add(0); @@ -30,10 +23,10 @@ CBindReverseConverter::CBindReverseConverter(const CBindInfo &srcBindInfo): _destInToSrcOutMap.Add(0); } - UINT32 destInOffset = 0; - UINT32 destOutOffset = 0; - UINT32 srcInOffset = NumSrcInStreams; - UINT32 srcOutOffset = _numSrcOutStreams; + UInt32 destInOffset = 0; + UInt32 destOutOffset = 0; + UInt32 srcInOffset = NumSrcInStreams; + UInt32 srcOutOffset = _numSrcOutStreams; for (int i = srcBindInfo.Coders.Size() - 1; i >= 0; i--) { @@ -42,16 +35,16 @@ CBindReverseConverter::CBindReverseConverter(const CBindInfo &srcBindInfo): srcInOffset -= srcCoderInfo.NumInStreams; srcOutOffset -= srcCoderInfo.NumOutStreams; - UINT32 j; + UInt32 j; for (j = 0; j < srcCoderInfo.NumInStreams; j++, destOutOffset++) { - UINT32 index = srcInOffset + j; + UInt32 index = srcInOffset + j; _srcInToDestOutMap[index] = destOutOffset; DestOutToSrcInMap[destOutOffset] = index; } for (j = 0; j < srcCoderInfo.NumOutStreams; j++, destInOffset++) { - UINT32 index = srcOutOffset + j; + UInt32 index = srcOutOffset + j; _srcOutToDestInMap[index] = destInOffset; _destInToSrcOutMap[destInOffset] = index; } @@ -88,102 +81,22 @@ void CBindReverseConverter::CreateReverseBindInfo(CBindInfo &destBindInfo) destBindInfo.InStreams.Add(_srcOutToDestInMap[_srcBindInfo.OutStreams[i]]); } - -CThreadCoderInfo2::CThreadCoderInfo2(UINT32 numInStreams, UINT32 numOutStreams): - ExitEvent(NULL), - CompressEvent(NULL), - CompressionCompletedEvent(NULL), +CCoderInfo::CCoderInfo(UInt32 numInStreams, UInt32 numOutStreams): NumInStreams(numInStreams), NumOutStreams(numOutStreams) { - InStreams.Reserve(NumInStreams); - InStreamPointers.Reserve(NumInStreams); InSizes.Reserve(NumInStreams); InSizePointers.Reserve(NumInStreams); - OutStreams.Reserve(NumOutStreams); - OutStreamPointers.Reserve(NumOutStreams); - OutSizes.Reserve(NumOutStreams); + OutSizePointers.Reserve(NumOutStreams); OutSizePointers.Reserve(NumOutStreams); } -void CThreadCoderInfo2::CreateEvents() -{ - CompressEvent = new CAutoResetEvent(false); - CompressionCompletedEvent = new CAutoResetEvent(false); -} - -CThreadCoderInfo2::~CThreadCoderInfo2() -{ - if (CompressEvent != NULL) - delete CompressEvent; - if (CompressionCompletedEvent != NULL) - delete CompressionCompletedEvent; -} - -class CCoderInfoFlusher2 -{ - CThreadCoderInfo2 *m_CoderInfo; -public: - CCoderInfoFlusher2(CThreadCoderInfo2 *coderInfo): m_CoderInfo(coderInfo) {} - ~CCoderInfoFlusher2() - { - int i; - for (i = 0; i < m_CoderInfo->InStreams.Size(); i++) - m_CoderInfo->InStreams[i].Release(); - for (i = 0; i < m_CoderInfo->OutStreams.Size(); i++) - m_CoderInfo->OutStreams[i].Release(); - m_CoderInfo->CompressionCompletedEvent->Set(); - } -}; - -bool CThreadCoderInfo2::WaitAndCode() -{ - HANDLE events[2] = { ExitEvent, *CompressEvent }; - DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE); - if (waitResult == WAIT_OBJECT_0 + 0) - return false; - - { - InStreamPointers.Clear(); - OutStreamPointers.Clear(); - UINT32 i; - for (i = 0; i < NumInStreams; i++) - { - if (InSizePointers[i] != NULL) - InSizePointers[i] = &InSizes[i]; - InStreamPointers.Add(InStreams[i]); - } - for (i = 0; i < NumOutStreams; i++) - { - if (OutSizePointers[i] != NULL) - OutSizePointers[i] = &OutSizes[i]; - OutStreamPointers.Add(OutStreams[i]); - } - CCoderInfoFlusher2 coderInfoFlusher(this); - if (CompressorIsCoder2) - Result = Coder2->Code(&InStreamPointers.Front(), - &InSizePointers.Front(), - NumInStreams, - &OutStreamPointers.Front(), - &OutSizePointers.Front(), - NumOutStreams, - Progress); - else - Result = Coder->Code(InStreamPointers[0], - OutStreamPointers[0], - InSizePointers[0], - OutSizePointers[0], - Progress); - } - return true; -} - -void SetSizes(const UINT64 **srcSizes, CRecordVector<UINT64> &sizes, - CRecordVector<const UINT64 *> &sizePointers, UINT32 numItems) +static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes, + CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems) { sizes.Clear(); sizePointers.Clear(); - for(UINT32 i = 0; i < numItems; i++) + for(UInt32 i = 0; i < numItems; i++) { if (srcSizes == 0 || srcSizes[i] == NULL) { @@ -198,251 +111,11 @@ void SetSizes(const UINT64 **srcSizes, CRecordVector<UINT64> &sizes, } } - -void CThreadCoderInfo2::SetCoderInfo(const UINT64 **inSizes, - const UINT64 **outSizes, ICompressProgressInfo *progress) +void CCoderInfo::SetCoderInfo(const UInt64 **inSizes, + const UInt64 **outSizes) { - Progress = progress; SetSizes(inSizes, InSizes, InSizePointers, NumInStreams); SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams); } -static DWORD WINAPI CoderThread(void *threadCoderInfo) -{ - while(true) - { - if (!((CThreadCoderInfo2 *)threadCoderInfo)->WaitAndCode()) - return 0; - } -} - -////////////////////////////////////// -// CCoderMixer2 - -static DWORD WINAPI MainCoderThread(void *threadCoderInfo) -{ - while(true) - { - if (!((CCoderMixer2 *)threadCoderInfo)->MyCode()) - return 0; - } -} - -CCoderMixer2::CCoderMixer2() -{ - if (!_mainThread.Create(MainCoderThread, this)) - throw 271825; -} - -CCoderMixer2::~CCoderMixer2() -{ - _exitEvent.Set(); - - ::WaitForSingleObject(_mainThread, INFINITE); - DWORD result = ::WaitForMultipleObjects(_threads.Size(), - &_threads.Front(), TRUE, INFINITE); - for(int i = 0; i < _threads.Size(); i++) - ::CloseHandle(_threads[i]); -} - -void CCoderMixer2::SetBindInfo(const CBindInfo &bindInfo) -{ - _bindInfo = bindInfo; - _streamBinders.Clear(); - for(int i = 0; i < _bindInfo.BindPairs.Size(); i++) - { - _streamBinders.Add(CStreamBinder()); - _streamBinders.Back().CreateEvents(); - } -} - -void CCoderMixer2::AddCoderCommon() -{ - int index = _coderInfoVector.Size(); - const CCoderStreamsInfo &CoderStreamsInfo = _bindInfo.Coders[index]; - - CThreadCoderInfo2 threadCoderInfo(CoderStreamsInfo.NumInStreams, - CoderStreamsInfo.NumOutStreams); - _coderInfoVector.Add(threadCoderInfo); - _coderInfoVector.Back().CreateEvents(); - _coderInfoVector.Back().ExitEvent = _exitEvent; - _compressingCompletedEvents.Add(*_coderInfoVector.Back().CompressionCompletedEvent); - - DWORD id; - HANDLE newThread = ::CreateThread(NULL, 0, CoderThread, - &_coderInfoVector.Back(), 0, &id); - if (newThread == 0) - throw 271824; - _threads.Add(newThread); -} - -void CCoderMixer2::AddCoder(ICompressCoder *coder) -{ - AddCoderCommon(); - _coderInfoVector.Back().CompressorIsCoder2 = false; - _coderInfoVector.Back().Coder = coder; -} - -void CCoderMixer2::AddCoder2(ICompressCoder2 *coder) -{ - AddCoderCommon(); - _coderInfoVector.Back().CompressorIsCoder2 = true; - _coderInfoVector.Back().Coder2 = coder; -} - -/* -void CCoderMixer2::FinishAddingCoders() -{ - for(int i = 0; i < _coderInfoVector.Size(); i++) - { - DWORD id; - HANDLE newThread = ::CreateThread(NULL, 0, CoderThread, - &_coderInfoVector[i], 0, &id); - if (newThread == 0) - throw 271824; - _threads.Add(newThread); - } -} -*/ - -void CCoderMixer2::ReInit() -{ - for(int i = 0; i < _streamBinders.Size(); i++) - _streamBinders[i].ReInit(); -} - - -STDMETHODIMP CCoderMixer2::Init(ISequentialInStream **inStreams, - ISequentialOutStream **outStreams) -{ - if (_coderInfoVector.Size() != _bindInfo.Coders.Size()) - throw 0; - UINT32 numInStreams = 0, numOutStreams = 0; - int i; - for(i = 0; i < _coderInfoVector.Size(); i++) - { - CThreadCoderInfo2 &coderInfo = _coderInfoVector[i]; - const CCoderStreamsInfo &coderStreamsInfo = _bindInfo.Coders[i]; - coderInfo.InStreams.Clear(); - UINT32 j; - for(j = 0; j < coderStreamsInfo.NumInStreams; j++) - coderInfo.InStreams.Add(NULL); - coderInfo.OutStreams.Clear(); - for(j = 0; j < coderStreamsInfo.NumOutStreams; j++) - coderInfo.OutStreams.Add(NULL); - } - - for(i = 0; i < _bindInfo.BindPairs.Size(); i++) - { - const CBindPair &bindPair = _bindInfo.BindPairs[i]; - UINT32 inCoderIndex, inCoderStreamIndex; - UINT32 outCoderIndex, outCoderStreamIndex; - _bindInfo.FindInStream(bindPair.InIndex, inCoderIndex, inCoderStreamIndex); - _bindInfo.FindOutStream(bindPair.OutIndex, outCoderIndex, outCoderStreamIndex); - - _streamBinders[i].CreateStreams( - &_coderInfoVector[inCoderIndex].InStreams[inCoderStreamIndex], - &_coderInfoVector[outCoderIndex].OutStreams[outCoderStreamIndex]); - } - - for(i = 0; i < _bindInfo.InStreams.Size(); i++) - { - UINT32 inCoderIndex, inCoderStreamIndex; - _bindInfo.FindInStream(_bindInfo.InStreams[i], inCoderIndex, inCoderStreamIndex); - _coderInfoVector[inCoderIndex].InStreams[inCoderStreamIndex] = inStreams[i]; - } - - for(i = 0; i < _bindInfo.OutStreams.Size(); i++) - { - UINT32 outCoderIndex, outCoderStreamIndex; - _bindInfo.FindOutStream(_bindInfo.OutStreams[i], outCoderIndex, outCoderStreamIndex); - _coderInfoVector[outCoderIndex].OutStreams[outCoderStreamIndex] = outStreams[i]; - } - return S_OK; -} - - -bool CCoderMixer2::MyCode() -{ - HANDLE events[2] = { _exitEvent, _startCompressingEvent }; - DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE); - if (waitResult == WAIT_OBJECT_0 + 0) - return false; - - for(int i = 0; i < _coderInfoVector.Size(); i++) - _coderInfoVector[i].CompressEvent->Set(); - DWORD result = ::WaitForMultipleObjects(_compressingCompletedEvents.Size(), - &_compressingCompletedEvents.Front(), TRUE, INFINITE); - - _compressingFinishedEvent.Set(); - - return true; -} - - -STDMETHODIMP CCoderMixer2::Code(ISequentialInStream **inStreams, - const UINT64 **inSizes, - UINT32 numInStreams, - ISequentialOutStream **outStreams, - const UINT64 **outSizes, - UINT32 numOutStreams, - ICompressProgressInfo *progress) -{ - if (numInStreams != (UINT32)_bindInfo.InStreams.Size() || - numOutStreams != (UINT32)_bindInfo.OutStreams.Size()) - return E_INVALIDARG; - - Init(inStreams, outStreams); - - _compressingFinishedEvent.Reset(); // ? - - CCrossThreadProgress *progressSpec = new CCrossThreadProgress; - CMyComPtr<ICompressProgressInfo> crossProgress = progressSpec; - progressSpec->Init(); - _coderInfoVector[_progressCoderIndex].Progress = crossProgress; - - _startCompressingEvent.Set(); - - - while (true) - { - HANDLE events[2] = {_compressingFinishedEvent, progressSpec->ProgressEvent }; - DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE); - if (waitResult == WAIT_OBJECT_0 + 0) - break; - if (progress != NULL) - progressSpec->Result = progress->SetRatioInfo(progressSpec->InSize, - progressSpec->OutSize); - else - progressSpec->Result = S_OK; - progressSpec->WaitEvent.Set(); - } - - int i; - for(i = 0; i < _coderInfoVector.Size(); i++) - { - HRESULT result = _coderInfoVector[i].Result; - if (result == S_FALSE) - return result; - } - for(i = 0; i < _coderInfoVector.Size(); i++) - { - HRESULT result = _coderInfoVector[i].Result; - if (result != S_OK && result != E_FAIL) - return result; - } - for(i = 0; i < _coderInfoVector.Size(); i++) - { - HRESULT result = _coderInfoVector[i].Result; - if (result != S_OK) - return result; - } - return S_OK; -} - -UINT64 CCoderMixer2::GetWriteProcessedSize(UINT32 binderIndex) const -{ - return _streamBinders[binderIndex].ProcessedSize; -} - } diff --git a/7zip/Archive/Common/CoderMixer2.h b/7zip/Archive/Common/CoderMixer2.h index ce1a0db7..e80f4bfe 100755 --- a/7zip/Archive/Common/CoderMixer2.h +++ b/7zip/Archive/Common/CoderMixer2.h @@ -1,49 +1,54 @@ // CoderMixer2.h -#pragma once - -#ifndef __CODERMIXER2_H -#define __CODERMIXER2_H +#ifndef __CODER_MIXER2_H +#define __CODER_MIXER2_H #include "../../../Common/Vector.h" +#include "../../../Common/Types.h" #include "../../../Common/MyCom.h" -#include "../../../Windows/Thread.h" -#include "../../Common/StreamBinder.h" #include "../../ICoder.h" -// #include "../../../Compress/Interface/CompressInterface.h" - namespace NCoderMixer2 { struct CBindPair { - UINT32 InIndex; - UINT32 OutIndex; + UInt32 InIndex; + UInt32 OutIndex; }; struct CCoderStreamsInfo { - UINT32 NumInStreams; - UINT32 NumOutStreams; + UInt32 NumInStreams; + UInt32 NumOutStreams; }; struct CBindInfo { CRecordVector<CCoderStreamsInfo> Coders; CRecordVector<CBindPair> BindPairs; - CRecordVector<UINT32> InStreams; - CRecordVector<UINT32> OutStreams; - - UINT32 GetCoderStartOutStream(UINT32 coderIndex) const + CRecordVector<UInt32> InStreams; + CRecordVector<UInt32> OutStreams; + + void Clear() { - UINT32 numOutStreams = 0; - for (UINT32 i = 0; i < coderIndex; i++) + Coders.Clear(); + BindPairs.Clear(); + InStreams.Clear(); + OutStreams.Clear(); + } + + /* + UInt32 GetCoderStartOutStream(UInt32 coderIndex) const + { + UInt32 numOutStreams = 0; + for (UInt32 i = 0; i < coderIndex; i++) numOutStreams += Coders[i].NumOutStreams; return numOutStreams; } + */ - void GetNumStreams(UINT32 &numInStreams, UINT32 &numOutStreams) const + void GetNumStreams(UInt32 &numInStreams, UInt32 &numOutStreams) const { numInStreams = 0; numOutStreams = 0; @@ -55,14 +60,14 @@ struct CBindInfo } } - int FindBinderForInStream(UINT32 inStream) const + int FindBinderForInStream(UInt32 inStream) const { for (int i = 0; i < BindPairs.Size(); i++) if (BindPairs[i].InIndex == inStream) return i; return -1; } - int FindBinderForOutStream(UINT32 outStream) const + int FindBinderForOutStream(UInt32 outStream) const { for (int i = 0; i < BindPairs.Size(); i++) if (BindPairs[i].OutIndex == outStream) @@ -70,29 +75,29 @@ struct CBindInfo return -1; } - UINT32 GetCoderInStreamIndex(UINT32 coderIndex) const + UInt32 GetCoderInStreamIndex(UInt32 coderIndex) const { - UINT32 streamIndex = 0; - for (UINT32 i = 0; i < coderIndex; i++) + UInt32 streamIndex = 0; + for (UInt32 i = 0; i < coderIndex; i++) streamIndex += Coders[i].NumInStreams; return streamIndex; } - UINT32 GetCoderOutStreamIndex(UINT32 coderIndex) const + UInt32 GetCoderOutStreamIndex(UInt32 coderIndex) const { - UINT32 streamIndex = 0; - for (UINT32 i = 0; i < coderIndex; i++) + UInt32 streamIndex = 0; + for (UInt32 i = 0; i < coderIndex; i++) streamIndex += Coders[i].NumOutStreams; return streamIndex; } - void FindInStream(UINT32 streamIndex, UINT32 &coderIndex, - UINT32 &coderStreamIndex) const + void FindInStream(UInt32 streamIndex, UInt32 &coderIndex, + UInt32 &coderStreamIndex) const { - for (coderIndex = 0; coderIndex < (UINT32)Coders.Size(); coderIndex++) + for (coderIndex = 0; coderIndex < (UInt32)Coders.Size(); coderIndex++) { - UINT32 curSize = Coders[coderIndex].NumInStreams; + UInt32 curSize = Coders[coderIndex].NumInStreams; if (streamIndex < curSize) { coderStreamIndex = streamIndex; @@ -102,12 +107,12 @@ struct CBindInfo } throw 1; } - void FindOutStream(UINT32 streamIndex, UINT32 &coderIndex, - UINT32 &coderStreamIndex) const + void FindOutStream(UInt32 streamIndex, UInt32 &coderIndex, + UInt32 &coderStreamIndex) const { - for (coderIndex = 0; coderIndex < (UINT32)Coders.Size(); coderIndex++) + for (coderIndex = 0; coderIndex < (UInt32)Coders.Size(); coderIndex++) { - UINT32 curSize = Coders[coderIndex].NumOutStreams; + UInt32 curSize = Coders[coderIndex].NumOutStreams; if (streamIndex < curSize) { coderStreamIndex = streamIndex; @@ -121,132 +126,41 @@ struct CBindInfo class CBindReverseConverter { - UINT32 _numSrcOutStreams; + UInt32 _numSrcOutStreams; const NCoderMixer2::CBindInfo _srcBindInfo; - CRecordVector<UINT32> _srcInToDestOutMap; - CRecordVector<UINT32> _srcOutToDestInMap; - CRecordVector<UINT32> _destInToSrcOutMap; + CRecordVector<UInt32> _srcInToDestOutMap; + CRecordVector<UInt32> _srcOutToDestInMap; + CRecordVector<UInt32> _destInToSrcOutMap; public: - UINT32 NumSrcInStreams; - CRecordVector<UINT32> DestOutToSrcInMap; + UInt32 NumSrcInStreams; + CRecordVector<UInt32> DestOutToSrcInMap; CBindReverseConverter(const NCoderMixer2::CBindInfo &srcBindInfo); void CreateReverseBindInfo(NCoderMixer2::CBindInfo &destBindInfo); }; -// CreateEvents(); -// { -// SetCoderInfo() -// Init Streams -// set CompressEvent() -// wait CompressionCompletedEvent -// } - -struct CThreadCoderInfo2 +struct CCoderInfo { - NWindows::NSynchronization::CAutoResetEvent *CompressEvent; - HANDLE ExitEvent; - NWindows::NSynchronization::CAutoResetEvent *CompressionCompletedEvent; - - bool CompressorIsCoder2; CMyComPtr<ICompressCoder> Coder; CMyComPtr<ICompressCoder2> Coder2; - UINT32 NumInStreams; - UINT32 NumOutStreams; - - CObjectVector< CMyComPtr<ISequentialInStream> > InStreams; - CObjectVector< CMyComPtr<ISequentialOutStream> > OutStreams; - CRecordVector<ISequentialInStream *> InStreamPointers; - CRecordVector<ISequentialOutStream *> OutStreamPointers; - CRecordVector<UINT64> InSizes; - CRecordVector<UINT64> OutSizes; - CRecordVector<const UINT64 *> InSizePointers; - CRecordVector<const UINT64 *> OutSizePointers; - - CMyComPtr<ICompressProgressInfo> Progress; // CMyComPtr - HRESULT Result; - - CThreadCoderInfo2(UINT32 numInStreams, UINT32 numOutStreams); - void SetCoderInfo(const UINT64 **inSizes, - const UINT64 **outSizes, ICompressProgressInfo *progress); - ~CThreadCoderInfo2(); - bool WaitAndCode(); - void CreateEvents(); -}; - - -// SetBindInfo() -// for each coder -// { -// AddCoder[2]() -// } -// -// for each file -// { -// ReInit() -// for each coder -// { -// SetCoderInfo -// } -// SetProgressIndex(UINT32 coderIndex); -// Code -// } - - -class CCoderMixer2: - public ICompressCoder2, - public CMyUnknownImp -{ - MY_UNKNOWN_IMP - -public: - STDMETHOD(Init)(ISequentialInStream **inStreams, - ISequentialOutStream **outStreams); - - STDMETHOD(Code)(ISequentialInStream **inStreams, - const UINT64 **inSizes, - UINT32 numInStreams, - ISequentialOutStream **outStreams, - const UINT64 **outSizes, - UINT32 numOutStreams, - ICompressProgressInfo *progress); - - - CCoderMixer2(); - ~CCoderMixer2(); - void AddCoderCommon(); - void AddCoder(ICompressCoder *coder); - void AddCoder2(ICompressCoder2 *coder); - - void ReInit(); - void SetCoderInfo(UINT32 coderIndex, const UINT64 **anInSize, const UINT64 **outSize) - { _coderInfoVector[coderIndex].SetCoderInfo(anInSize, outSize, NULL); } - void SetProgressCoderIndex(UINT32 coderIndex) - { _progressCoderIndex = coderIndex; } - - - UINT64 GetWriteProcessedSize(UINT32 binderIndex) const; + UInt32 NumInStreams; + UInt32 NumOutStreams; + CRecordVector<UInt64> InSizes; + CRecordVector<UInt64> OutSizes; + CRecordVector<const UInt64 *> InSizePointers; + CRecordVector<const UInt64 *> OutSizePointers; - bool MyCode(); - -private: - CBindInfo _bindInfo; - CObjectVector<CStreamBinder> _streamBinders; - CObjectVector<CThreadCoderInfo2> _coderInfoVector; - CRecordVector<HANDLE> _threads; - NWindows::CThread _mainThread; - - NWindows::NSynchronization::CAutoResetEvent _startCompressingEvent; - CRecordVector<HANDLE> _compressingCompletedEvents; - NWindows::NSynchronization::CAutoResetEvent _compressingFinishedEvent; - - NWindows::NSynchronization::CManualResetEvent _exitEvent; - UINT32 _progressCoderIndex; + CCoderInfo(UInt32 numInStreams, UInt32 numOutStreams); + void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes); +}; +class CCoderMixer2 +{ public: - void SetBindInfo(const CBindInfo &bindInfo); - + virtual void SetBindInfo(const CBindInfo &bindInfo) = 0; + virtual void ReInit() = 0; + virtual void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes) = 0; }; } diff --git a/7zip/Archive/Common/CoderMixer2MT.cpp b/7zip/Archive/Common/CoderMixer2MT.cpp new file mode 100755 index 00000000..9f164e65 --- /dev/null +++ b/7zip/Archive/Common/CoderMixer2MT.cpp @@ -0,0 +1,360 @@ +// CoderMixer2MT.cpp + +#include "StdAfx.h" + +#include "CoderMixer2MT.h" +#include "CrossThreadProgress.h" + +using namespace NWindows; +using namespace NSynchronization; + +namespace NCoderMixer2 { + +CThreadCoderInfo::CThreadCoderInfo(UInt32 numInStreams, UInt32 numOutStreams): + ExitEvent(NULL), + CompressEvent(NULL), + CompressionCompletedEvent(NULL), + CCoderInfo(numInStreams, numOutStreams) +{ + InStreams.Reserve(NumInStreams); + InStreamPointers.Reserve(NumInStreams); + OutStreams.Reserve(NumOutStreams); + OutStreamPointers.Reserve(NumOutStreams); +} + +void CThreadCoderInfo::CreateEvents() +{ + CompressEvent = new CAutoResetEvent(false); + CompressionCompletedEvent = new CAutoResetEvent(false); +} + +CThreadCoderInfo::~CThreadCoderInfo() +{ + if (CompressEvent != NULL) + delete CompressEvent; + if (CompressionCompletedEvent != NULL) + delete CompressionCompletedEvent; +} + +class CCoderInfoFlusher2 +{ + CThreadCoderInfo *m_CoderInfo; +public: + CCoderInfoFlusher2(CThreadCoderInfo *coderInfo): m_CoderInfo(coderInfo) {} + ~CCoderInfoFlusher2() + { + int i; + for (i = 0; i < m_CoderInfo->InStreams.Size(); i++) + m_CoderInfo->InStreams[i].Release(); + for (i = 0; i < m_CoderInfo->OutStreams.Size(); i++) + m_CoderInfo->OutStreams[i].Release(); + m_CoderInfo->CompressionCompletedEvent->Set(); + } +}; + +bool CThreadCoderInfo::WaitAndCode() +{ + HANDLE events[2] = { ExitEvent, *CompressEvent }; + DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE); + if (waitResult == WAIT_OBJECT_0 + 0) + return false; + + { + InStreamPointers.Clear(); + OutStreamPointers.Clear(); + UInt32 i; + for (i = 0; i < NumInStreams; i++) + { + if (InSizePointers[i] != NULL) + InSizePointers[i] = &InSizes[i]; + InStreamPointers.Add(InStreams[i]); + } + for (i = 0; i < NumOutStreams; i++) + { + if (OutSizePointers[i] != NULL) + OutSizePointers[i] = &OutSizes[i]; + OutStreamPointers.Add(OutStreams[i]); + } + CCoderInfoFlusher2 coderInfoFlusher(this); + if (Coder) + Result = Coder->Code(InStreamPointers[0], + OutStreamPointers[0], + InSizePointers[0], + OutSizePointers[0], + Progress); + else + Result = Coder2->Code(&InStreamPointers.Front(), + &InSizePointers.Front(), + NumInStreams, + &OutStreamPointers.Front(), + &OutSizePointers.Front(), + NumOutStreams, + Progress); + } + return true; +} + +static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes, + CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems) +{ + sizes.Clear(); + sizePointers.Clear(); + for(UInt32 i = 0; i < numItems; i++) + { + if (srcSizes == 0 || srcSizes[i] == NULL) + { + sizes.Add(0); + sizePointers.Add(NULL); + } + else + { + sizes.Add(*srcSizes[i]); + sizePointers.Add(&sizes.Back()); + } + } +} + + +void CThreadCoderInfo::SetCoderInfo(const UInt64 **inSizes, + const UInt64 **outSizes, ICompressProgressInfo *progress) +{ + Progress = progress; + SetSizes(inSizes, InSizes, InSizePointers, NumInStreams); + SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams); +} + +static DWORD WINAPI CoderThread(void *threadCoderInfo) +{ + while(true) + { + if (!((CThreadCoderInfo *)threadCoderInfo)->WaitAndCode()) + return 0; + } +} + +////////////////////////////////////// +// CCoderMixer2MT + +static DWORD WINAPI MainCoderThread(void *threadCoderInfo) +{ + while(true) + { + if (!((CCoderMixer2MT *)threadCoderInfo)->MyCode()) + return 0; + } +} + +CCoderMixer2MT::CCoderMixer2MT() +{ + if (!_mainThread.Create(MainCoderThread, this)) + throw 271825; +} + +CCoderMixer2MT::~CCoderMixer2MT() +{ + _exitEvent.Set(); + _mainThread.Wait(); + for(int i = 0; i < _threads.Size(); i++) + { + _threads[i].Wait(); + _threads[i].Close(); + } +} + +void CCoderMixer2MT::SetBindInfo(const CBindInfo &bindInfo) +{ + _bindInfo = bindInfo; + _streamBinders.Clear(); + for(int i = 0; i < _bindInfo.BindPairs.Size(); i++) + { + _streamBinders.Add(CStreamBinder()); + _streamBinders.Back().CreateEvents(); + } +} + +void CCoderMixer2MT::AddCoderCommon() +{ + int index = _coderInfoVector.Size(); + const CCoderStreamsInfo &CoderStreamsInfo = _bindInfo.Coders[index]; + + CThreadCoderInfo threadCoderInfo(CoderStreamsInfo.NumInStreams, + CoderStreamsInfo.NumOutStreams); + _coderInfoVector.Add(threadCoderInfo); + _coderInfoVector.Back().CreateEvents(); + _coderInfoVector.Back().ExitEvent = _exitEvent; + _compressingCompletedEvents.Add(*_coderInfoVector.Back().CompressionCompletedEvent); + + NWindows::CThread newThread; + _threads.Add(newThread); + if (!_threads.Back().Create(CoderThread, &_coderInfoVector.Back())) + throw 271824; +} + +void CCoderMixer2MT::AddCoder(ICompressCoder *coder) +{ + AddCoderCommon(); + _coderInfoVector.Back().Coder = coder; +} + +void CCoderMixer2MT::AddCoder2(ICompressCoder2 *coder) +{ + AddCoderCommon(); + _coderInfoVector.Back().Coder2 = coder; +} + +/* +void CCoderMixer2MT::FinishAddingCoders() +{ + for(int i = 0; i < _coderInfoVector.Size(); i++) + { + DWORD id; + HANDLE newThread = ::CreateThread(NULL, 0, CoderThread, + &_coderInfoVector[i], 0, &id); + if (newThread == 0) + throw 271824; + _threads.Add(newThread); + } +} +*/ + +void CCoderMixer2MT::ReInit() +{ + for(int i = 0; i < _streamBinders.Size(); i++) + _streamBinders[i].ReInit(); +} + + +STDMETHODIMP CCoderMixer2MT::Init(ISequentialInStream **inStreams, + ISequentialOutStream **outStreams) +{ + if (_coderInfoVector.Size() != _bindInfo.Coders.Size()) + throw 0; + UInt32 numInStreams = 0, numOutStreams = 0; + int i; + for(i = 0; i < _coderInfoVector.Size(); i++) + { + CThreadCoderInfo &coderInfo = _coderInfoVector[i]; + const CCoderStreamsInfo &coderStreamsInfo = _bindInfo.Coders[i]; + coderInfo.InStreams.Clear(); + UInt32 j; + for(j = 0; j < coderStreamsInfo.NumInStreams; j++) + coderInfo.InStreams.Add(NULL); + coderInfo.OutStreams.Clear(); + for(j = 0; j < coderStreamsInfo.NumOutStreams; j++) + coderInfo.OutStreams.Add(NULL); + } + + for(i = 0; i < _bindInfo.BindPairs.Size(); i++) + { + const CBindPair &bindPair = _bindInfo.BindPairs[i]; + UInt32 inCoderIndex, inCoderStreamIndex; + UInt32 outCoderIndex, outCoderStreamIndex; + _bindInfo.FindInStream(bindPair.InIndex, inCoderIndex, inCoderStreamIndex); + _bindInfo.FindOutStream(bindPair.OutIndex, outCoderIndex, outCoderStreamIndex); + + _streamBinders[i].CreateStreams( + &_coderInfoVector[inCoderIndex].InStreams[inCoderStreamIndex], + &_coderInfoVector[outCoderIndex].OutStreams[outCoderStreamIndex]); + } + + for(i = 0; i < _bindInfo.InStreams.Size(); i++) + { + UInt32 inCoderIndex, inCoderStreamIndex; + _bindInfo.FindInStream(_bindInfo.InStreams[i], inCoderIndex, inCoderStreamIndex); + _coderInfoVector[inCoderIndex].InStreams[inCoderStreamIndex] = inStreams[i]; + } + + for(i = 0; i < _bindInfo.OutStreams.Size(); i++) + { + UInt32 outCoderIndex, outCoderStreamIndex; + _bindInfo.FindOutStream(_bindInfo.OutStreams[i], outCoderIndex, outCoderStreamIndex); + _coderInfoVector[outCoderIndex].OutStreams[outCoderStreamIndex] = outStreams[i]; + } + return S_OK; +} + + +bool CCoderMixer2MT::MyCode() +{ + HANDLE events[2] = { _exitEvent, _startCompressingEvent }; + DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE); + if (waitResult == WAIT_OBJECT_0 + 0) + return false; + + for(int i = 0; i < _coderInfoVector.Size(); i++) + _coderInfoVector[i].CompressEvent->Set(); + DWORD result = ::WaitForMultipleObjects(_compressingCompletedEvents.Size(), + &_compressingCompletedEvents.Front(), TRUE, INFINITE); + + _compressingFinishedEvent.Set(); + + return true; +} + + +STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress) +{ + if (numInStreams != (UInt32)_bindInfo.InStreams.Size() || + numOutStreams != (UInt32)_bindInfo.OutStreams.Size()) + return E_INVALIDARG; + + Init(inStreams, outStreams); + + _compressingFinishedEvent.Reset(); // ? + + CCrossThreadProgress *progressSpec = new CCrossThreadProgress; + CMyComPtr<ICompressProgressInfo> crossProgress = progressSpec; + progressSpec->Init(); + _coderInfoVector[_progressCoderIndex].Progress = crossProgress; + + _startCompressingEvent.Set(); + + + while (true) + { + HANDLE events[2] = {_compressingFinishedEvent, progressSpec->ProgressEvent }; + DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE); + if (waitResult == WAIT_OBJECT_0 + 0) + break; + if (progress != NULL) + progressSpec->Result = progress->SetRatioInfo(progressSpec->InSize, + progressSpec->OutSize); + else + progressSpec->Result = S_OK; + progressSpec->WaitEvent.Set(); + } + + int i; + for(i = 0; i < _coderInfoVector.Size(); i++) + { + HRESULT result = _coderInfoVector[i].Result; + if (result == S_FALSE) + return result; + } + for(i = 0; i < _coderInfoVector.Size(); i++) + { + HRESULT result = _coderInfoVector[i].Result; + if (result != S_OK && result != E_FAIL) + return result; + } + for(i = 0; i < _coderInfoVector.Size(); i++) + { + HRESULT result = _coderInfoVector[i].Result; + if (result != S_OK) + return result; + } + return S_OK; +} + +UInt64 CCoderMixer2MT::GetWriteProcessedSize(UInt32 binderIndex) const +{ + return _streamBinders[binderIndex].ProcessedSize; +} + +} diff --git a/7zip/Archive/Common/CoderMixer2MT.h b/7zip/Archive/Common/CoderMixer2MT.h new file mode 100755 index 00000000..78d752de --- /dev/null +++ b/7zip/Archive/Common/CoderMixer2MT.h @@ -0,0 +1,121 @@ +// CoderMixer2MT.h + +#ifndef __CODER_MIXER2_MT_H +#define __CODER_MIXER2_MT_H + +#include "CoderMixer2.h" +#include "../../../Common/MyCom.h" +#include "../../../Windows/Thread.h" +#include "../../Common/StreamBinder.h" + +namespace NCoderMixer2 { + +// CreateEvents(); +// { +// SetCoderInfo() +// Init Streams +// set CompressEvent() +// wait CompressionCompletedEvent +// } + +struct CThreadCoderInfo: public CCoderInfo +{ + NWindows::NSynchronization::CAutoResetEvent *CompressEvent; + HANDLE ExitEvent; + NWindows::NSynchronization::CAutoResetEvent *CompressionCompletedEvent; + + CObjectVector< CMyComPtr<ISequentialInStream> > InStreams; + CObjectVector< CMyComPtr<ISequentialOutStream> > OutStreams; + CRecordVector<ISequentialInStream *> InStreamPointers; + CRecordVector<ISequentialOutStream *> OutStreamPointers; + + CMyComPtr<ICompressProgressInfo> Progress; // CMyComPtr + HRESULT Result; + + CThreadCoderInfo(UInt32 numInStreams, UInt32 numOutStreams); + void SetCoderInfo(const UInt64 **inSizes, + const UInt64 **outSizes, ICompressProgressInfo *progress); + ~CThreadCoderInfo(); + bool WaitAndCode(); + void CreateEvents(); +}; + + +// SetBindInfo() +// for each coder +// { +// AddCoder[2]() +// } +// +// for each file +// { +// ReInit() +// for each coder +// { +// SetCoderInfo +// } +// SetProgressIndex(UInt32 coderIndex); +// Code +// } + + +class CCoderMixer2MT: + public ICompressCoder2, + public CCoderMixer2, + public CMyUnknownImp +{ + MY_UNKNOWN_IMP + +public: + STDMETHOD(Init)(ISequentialInStream **inStreams, + ISequentialOutStream **outStreams); + + STDMETHOD(Code)(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress); + + + CCoderMixer2MT(); + ~CCoderMixer2MT(); + void AddCoderCommon(); + void AddCoder(ICompressCoder *coder); + void AddCoder2(ICompressCoder2 *coder); + + void ReInit(); + void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes) + { _coderInfoVector[coderIndex].SetCoderInfo(inSizes, outSizes, NULL); } + void SetProgressCoderIndex(UInt32 coderIndex) + { _progressCoderIndex = coderIndex; } + + + UInt64 GetWriteProcessedSize(UInt32 binderIndex) const; + + + bool MyCode(); + +private: + CBindInfo _bindInfo; + CObjectVector<CStreamBinder> _streamBinders; + CObjectVector<CThreadCoderInfo> _coderInfoVector; + CRecordVector<NWindows::CThread> _threads; + NWindows::CThread _mainThread; + + NWindows::NSynchronization::CAutoResetEvent _startCompressingEvent; + CRecordVector<HANDLE> _compressingCompletedEvents; + NWindows::NSynchronization::CAutoResetEvent _compressingFinishedEvent; + + NWindows::NSynchronization::CManualResetEvent _exitEvent; + UInt32 _progressCoderIndex; + +public: + void SetBindInfo(const CBindInfo &bindInfo); + +}; + +} +#endif + diff --git a/7zip/Archive/Common/CoderMixer2ST.cpp b/7zip/Archive/Common/CoderMixer2ST.cpp new file mode 100755 index 00000000..c01b776d --- /dev/null +++ b/7zip/Archive/Common/CoderMixer2ST.cpp @@ -0,0 +1,238 @@ +// CoderMixer2ST.cpp + +#include "StdAfx.h" + +#include "CoderMixer2ST.h" + +namespace NCoderMixer2 { + +CCoderMixer2ST::CCoderMixer2ST() {} + +CCoderMixer2ST::~CCoderMixer2ST(){ } + +void CCoderMixer2ST::SetBindInfo(const CBindInfo &bindInfo) +{ + _bindInfo = bindInfo; +} + +void CCoderMixer2ST::AddCoderCommon(bool isMain) +{ + const CCoderStreamsInfo &csi = _bindInfo.Coders[_coders.Size()]; + _coders.Add(CSTCoderInfo(csi.NumInStreams, csi.NumOutStreams, isMain)); +} + +void CCoderMixer2ST::AddCoder(ICompressCoder *coder, bool isMain) +{ + AddCoderCommon(isMain); + _coders.Back().Coder = coder; +} + +void CCoderMixer2ST::AddCoder2(ICompressCoder2 *coder, bool isMain) +{ + AddCoderCommon(isMain); + _coders.Back().Coder2 = coder; +} + +void CCoderMixer2ST::ReInit() { } + +HRESULT CCoderMixer2ST::GetInStream( + ISequentialInStream **inStreams, const UInt64 **inSizes, + UInt32 streamIndex, ISequentialInStream **inStreamRes) +{ + CMyComPtr<ISequentialInStream> seqInStream; + int i; + for(i = 0; i < _bindInfo.InStreams.Size(); i++) + if (_bindInfo.InStreams[i] == streamIndex) + { + seqInStream = inStreams[i]; + *inStreamRes = seqInStream.Detach(); + return S_OK; + } + int binderIndex = _bindInfo.FindBinderForInStream(streamIndex); + if (binderIndex < 0) + return E_INVALIDARG; + + UInt32 coderIndex, coderStreamIndex; + _bindInfo.FindOutStream(_bindInfo.BindPairs[binderIndex].OutIndex, + coderIndex, coderStreamIndex); + + CCoderInfo &coder = _coders[coderIndex]; + if (!coder.Coder) + return E_NOTIMPL; + coder.Coder.QueryInterface(IID_ISequentialInStream, &seqInStream); + if (!seqInStream) + return E_NOTIMPL; + + UInt32 startIndex = _bindInfo.GetCoderInStreamIndex(coderIndex); + + CMyComPtr<ICompressSetInStream> setInStream; + if (!coder.Coder) + return E_NOTIMPL; + coder.Coder.QueryInterface(IID_ICompressSetInStream, &setInStream); + if (!setInStream) + return E_NOTIMPL; + + if (coder.NumInStreams > 1) + return E_NOTIMPL; + for (i = 0; i < (int)coder.NumInStreams; i++) + { + CMyComPtr<ISequentialInStream> seqInStream2; + RINOK(GetInStream(inStreams, inSizes, startIndex + i, &seqInStream2)); + RINOK(setInStream->SetInStream(seqInStream2)); + } + *inStreamRes = seqInStream.Detach(); + return S_OK; +} + +HRESULT CCoderMixer2ST::GetOutStream( + ISequentialOutStream **outStreams, const UInt64 **outSizes, + UInt32 streamIndex, ISequentialOutStream **outStreamRes) +{ + CMyComPtr<ISequentialOutStream> seqOutStream; + int i; + for(i = 0; i < _bindInfo.OutStreams.Size(); i++) + if (_bindInfo.OutStreams[i] == streamIndex) + { + seqOutStream = outStreams[i]; + *outStreamRes = seqOutStream.Detach(); + return S_OK; + } + int binderIndex = _bindInfo.FindBinderForOutStream(streamIndex); + if (binderIndex < 0) + return E_INVALIDARG; + + UInt32 coderIndex, coderStreamIndex; + _bindInfo.FindInStream(_bindInfo.BindPairs[binderIndex].InIndex, + coderIndex, coderStreamIndex); + + CCoderInfo &coder = _coders[coderIndex]; + if (!coder.Coder) + return E_NOTIMPL; + coder.Coder.QueryInterface(IID_ISequentialOutStream, &seqOutStream); + if (!seqOutStream) + return E_NOTIMPL; + + UInt32 startIndex = _bindInfo.GetCoderOutStreamIndex(coderIndex); + + CMyComPtr<ICompressSetOutStream> setOutStream; + if (!coder.Coder) + return E_NOTIMPL; + coder.Coder.QueryInterface(IID_ICompressSetOutStream, &setOutStream); + if (!setOutStream) + return E_NOTIMPL; + + if (coder.NumOutStreams > 1) + return E_NOTIMPL; + for (i = 0; i < (int)coder.NumOutStreams; i++) + { + CMyComPtr<ISequentialOutStream> seqOutStream2; + RINOK(GetOutStream(outStreams, outSizes, startIndex + i, &seqOutStream2)); + RINOK(setOutStream->SetOutStream(seqOutStream2)); + } + *outStreamRes = seqOutStream.Detach(); + return S_OK; +} + + +STDMETHODIMP CCoderMixer2ST::Code(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress) +{ + if (numInStreams != (UInt32)_bindInfo.InStreams.Size() || + numOutStreams != (UInt32)_bindInfo.OutStreams.Size()) + return E_INVALIDARG; + + // Find main coder + int _mainCoderIndex = -1; + int i; + for (i = 0; i < _coders.Size(); i++) + if (_coders[i].IsMain) + { + _mainCoderIndex = i; + break; + } + if (_mainCoderIndex < 0) + for (i = 0; i < _coders.Size(); i++) + if (_coders[i].NumInStreams > 1) + { + if (_mainCoderIndex >= 0) + return E_NOTIMPL; + _mainCoderIndex = i; + } + if (_mainCoderIndex < 0) + _mainCoderIndex = 0; + + // _mainCoderIndex = 0; + // _mainCoderIndex = _coders.Size() - 1; + CCoderInfo &mainCoder = _coders[_mainCoderIndex]; + + CObjectVector< CMyComPtr<ISequentialInStream> > seqInStreams; + CObjectVector< CMyComPtr<ISequentialOutStream> > seqOutStreams; + UInt32 startInIndex = _bindInfo.GetCoderInStreamIndex(_mainCoderIndex); + UInt32 startOutIndex = _bindInfo.GetCoderOutStreamIndex(_mainCoderIndex); + for (i = 0; i < (int)mainCoder.NumInStreams; i++) + { + CMyComPtr<ISequentialInStream> seqInStream; + RINOK(GetInStream(inStreams, inSizes, startInIndex + i, &seqInStream)); + seqInStreams.Add(seqInStream); + } + for (i = 0; i < (int)mainCoder.NumOutStreams; i++) + { + CMyComPtr<ISequentialOutStream> seqOutStream; + RINOK(GetOutStream(outStreams, outSizes, startOutIndex + i, &seqOutStream)); + seqOutStreams.Add(seqOutStream); + } + CRecordVector< ISequentialInStream * > seqInStreamsSpec; + CRecordVector< ISequentialOutStream * > seqOutStreamsSpec; + for (i = 0; i < (int)mainCoder.NumInStreams; i++) + seqInStreamsSpec.Add(seqInStreams[i]); + for (i = 0; i < (int)mainCoder.NumOutStreams; i++) + seqOutStreamsSpec.Add(seqOutStreams[i]); + + for (i = 0; i < _coders.Size(); i++) + { + if (i == _mainCoderIndex) + continue; + CCoderInfo &coder = _coders[i]; + CMyComPtr<ICompressSetOutStreamSize> setOutStreamSize; + coder.Coder.QueryInterface(IID_ICompressSetOutStreamSize, &setOutStreamSize); + if (setOutStreamSize) + { + RINOK(setOutStreamSize->SetOutStreamSize(coder.OutSizePointers[0])); + } + } + if (mainCoder.Coder) + { + RINOK(mainCoder.Coder->Code( + seqInStreamsSpec[0], seqOutStreamsSpec[0], + mainCoder.InSizePointers[0], mainCoder.OutSizePointers[0], + progress)); + } + else + { + RINOK(mainCoder.Coder2->Code( + &seqInStreamsSpec.Front(), + &mainCoder.InSizePointers.Front(), mainCoder.NumInStreams, + &seqOutStreamsSpec.Front(), + &mainCoder.OutSizePointers.Front(), mainCoder.NumOutStreams, + progress)); + } + CMyComPtr<IOutStreamFlush> flush; + seqOutStreams.Front().QueryInterface(IID_IOutStreamFlush, &flush); + if (flush) + return flush->Flush(); + return S_OK; +} + +/* +UInt64 CCoderMixer2ST::GetWriteProcessedSize(UInt32 binderIndex) const +{ + return _streamBinders[binderIndex].ProcessedSize; +} +*/ + +} diff --git a/7zip/Archive/Common/CoderMixer2ST.h b/7zip/Archive/Common/CoderMixer2ST.h new file mode 100755 index 00000000..3cddc171 --- /dev/null +++ b/7zip/Archive/Common/CoderMixer2ST.h @@ -0,0 +1,87 @@ +// CoderMixer2ST.h + +#ifndef __CODER_MIXER2_ST_H +#define __CODER_MIXER2_ST_H + +#include "CoderMixer2.h" +#include "../../../Common/MyCom.h" +#include "../../ICoder.h" + +namespace NCoderMixer2 { + +// SetBindInfo() +// for each coder +// { +// AddCoder[2]() +// } +// +// for each file +// { +// ReInit() +// for each coder +// { +// SetCoderInfo +// } +// SetProgressIndex(UInt32 coderIndex); +// Code +// } + +struct CSTCoderInfo: public CCoderInfo +{ + bool IsMain; + CSTCoderInfo(UInt32 numInStreams, UInt32 numOutStreams, bool isMain): + CCoderInfo(numInStreams, numOutStreams),IsMain(isMain) {} +}; + +class CCoderMixer2ST: + public ICompressCoder2, + public CCoderMixer2, + public CMyUnknownImp +{ + MY_UNKNOWN_IMP + + HRESULT GetInStream( + ISequentialInStream **inStreams, const UInt64 **inSizes, + UInt32 streamIndex, ISequentialInStream **inStreamRes); + HRESULT GetOutStream( + ISequentialOutStream **outStreams, const UInt64 **outSizes, + UInt32 streamIndex, ISequentialOutStream **outStreamRes); +public: + STDMETHOD(Code)(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress); + + CCoderMixer2ST(); + ~CCoderMixer2ST(); + void AddCoderCommon(bool isMain); + void AddCoder(ICompressCoder *coder, bool isMain); + void AddCoder2(ICompressCoder2 *coder, bool isMain); + + void ReInit(); + void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes) + { + { _coders[coderIndex].SetCoderInfo(inSizes, outSizes); } + } + void SetProgressCoderIndex(UInt32 coderIndex) + { + // _progressCoderIndex = coderIndex; + } + + // UInt64 GetWriteProcessedSize(UInt32 binderIndex) const; + +private: + CBindInfo _bindInfo; + CObjectVector<CSTCoderInfo> _coders; + int _mainCoderIndex; +public: + void SetBindInfo(const CBindInfo &bindInfo); + +}; + +} +#endif + diff --git a/7zip/Archive/Common/CoderPaths.cpp b/7zip/Archive/Common/CoderPaths.cpp deleted file mode 100755 index d2e75de6..00000000 --- a/7zip/Archive/Common/CoderPaths.cpp +++ /dev/null @@ -1,34 +0,0 @@ -// CodersPath.cpp - -#include "StdAfx.h" -#include "../../../Common/String.h" - -extern HINSTANCE g_hInstance; - -static CSysString GetLibraryPath() -{ - TCHAR fullPath[MAX_PATH + 1]; - ::GetModuleFileName(g_hInstance, fullPath, MAX_PATH); - return fullPath; -} - -static CSysString GetLibraryFolderPrefix() -{ - CSysString path = GetLibraryPath(); - int pos = path.ReverseFind(TEXT('\\')); - return path.Left(pos + 1); -} - -CSysString GetBaseFolderPrefix() -{ - CSysString libPrefix = GetLibraryFolderPrefix(); - CSysString temp = libPrefix; - temp.Delete(temp.Length() - 1); - int pos = temp.ReverseFind(TEXT('\\')); - return temp.Left(pos + 1); -} - -CSysString GetCodecsFolderPrefix() -{ - return GetBaseFolderPrefix() + TEXT("Compress\\"); -} diff --git a/7zip/Archive/Common/CrossThreadProgress.cpp b/7zip/Archive/Common/CrossThreadProgress.cpp index ad4e8960..a974b54c 100755 --- a/7zip/Archive/Common/CrossThreadProgress.cpp +++ b/7zip/Archive/Common/CrossThreadProgress.cpp @@ -4,7 +4,7 @@ #include "CrossThreadProgress.h" -STDMETHODIMP CCrossThreadProgress::SetRatioInfo(const UINT64 *inSize, const UINT64 *outSize) +STDMETHODIMP CCrossThreadProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) { InSize = inSize; OutSize = outSize; diff --git a/7zip/Archive/Common/CrossThreadProgress.h b/7zip/Archive/Common/CrossThreadProgress.h index dcc2ce57..5dd339dc 100755 --- a/7zip/Archive/Common/CrossThreadProgress.h +++ b/7zip/Archive/Common/CrossThreadProgress.h @@ -1,7 +1,5 @@ // CrossThreadProgress.h -#pragma once - #ifndef __CROSSTHREADPROGRESS_H #define __CROSSTHREADPROGRESS_H @@ -14,8 +12,8 @@ class CCrossThreadProgress: public CMyUnknownImp { public: - const UINT64 *InSize; - const UINT64 *OutSize; + const UInt64 *InSize; + const UInt64 *OutSize; HRESULT Result; NWindows::NSynchronization::CAutoResetEvent ProgressEvent; NWindows::NSynchronization::CAutoResetEvent WaitEvent; @@ -27,7 +25,7 @@ public: MY_UNKNOWN_IMP - STDMETHOD(SetRatioInfo)(const UINT64 *inSize, const UINT64 *outSize); + STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); }; #endif diff --git a/7zip/Archive/Common/DummyOutStream.cpp b/7zip/Archive/Common/DummyOutStream.cpp index de1a5b19..f188ac05 100755 --- a/7zip/Archive/Common/DummyOutStream.cpp +++ b/7zip/Archive/Common/DummyOutStream.cpp @@ -10,7 +10,7 @@ void CDummyOutStream::Init(ISequentialOutStream *outStream) } STDMETHODIMP CDummyOutStream::Write(const void *data, - UINT32 size, UINT32 *processedSize) + UInt32 size, UInt32 *processedSize) { if(m_Stream) return m_Stream->Write(data, size, processedSize); @@ -20,7 +20,7 @@ STDMETHODIMP CDummyOutStream::Write(const void *data, } STDMETHODIMP CDummyOutStream::WritePart(const void *data, - UINT32 size, UINT32 *processedSize) + UInt32 size, UInt32 *processedSize) { if(m_Stream) return m_Stream->WritePart(data, size, processedSize); diff --git a/7zip/Archive/Common/DummyOutStream.h b/7zip/Archive/Common/DummyOutStream.h index 85ff6dbf..2e66cd3d 100755 --- a/7zip/Archive/Common/DummyOutStream.h +++ b/7zip/Archive/Common/DummyOutStream.h @@ -1,7 +1,5 @@ // DummyOutStream.h -#pragma once - #ifndef __DUMMYOUTSTREAM_H #define __DUMMYOUTSTREAM_H @@ -15,8 +13,8 @@ class CDummyOutStream: public: MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize); - STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize); + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); private: CMyComPtr<ISequentialOutStream> m_Stream; public: diff --git a/7zip/Archive/Common/FilterCoder.cpp b/7zip/Archive/Common/FilterCoder.cpp new file mode 100755 index 00000000..3a7a95b6 --- /dev/null +++ b/7zip/Archive/Common/FilterCoder.cpp @@ -0,0 +1,244 @@ +// FilterCoder.cpp + +#include "StdAfx.h" + +#include "FilterCoder.h" +#include "../../../Common/Alloc.h" +#include "../../../Common/Defs.h" + +static const int kBufferSize = 1 << 17; + +CFilterCoder::CFilterCoder() +{ + _buffer = (Byte *)::BigAlloc(kBufferSize); +} + +CFilterCoder::~CFilterCoder() +{ + BigFree(_buffer); +} + +HRESULT CFilterCoder::WriteWithLimit(ISequentialOutStream *outStream, UInt32 size) +{ + if (_outSizeIsDefined) + { + UInt64 remSize = _outSize - _nowPos64; + if (size > remSize) + size = (UInt32)remSize; + } + UInt32 processedSize = 0; + RINOK(outStream->Write(_buffer, size, &processedSize)); + if (size != processedSize) + return E_FAIL; + _nowPos64 += processedSize; + return S_OK; +} + + +STDMETHODIMP CFilterCoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + Init(); + UInt32 bufferPos = 0; + if (_outSizeIsDefined = (outSize != 0)) + _outSize = *outSize; + + while(NeedMore()) + { + UInt32 processedSize; + UInt32 size = kBufferSize - bufferPos; + RINOK(inStream->Read(_buffer + bufferPos, size, &processedSize)); + UInt32 endPos = bufferPos + processedSize; + + bufferPos = Filter->Filter(_buffer, endPos); + if (bufferPos > endPos) + { + for (; endPos< bufferPos; endPos++) + _buffer[endPos] = 0; + bufferPos = Filter->Filter(_buffer, endPos); + } + + if (bufferPos == 0) + { + if (endPos > 0) + return WriteWithLimit(outStream, endPos); + return S_OK; + } + RINOK(WriteWithLimit(outStream, bufferPos)); + if (progress != NULL) + { + RINOK(progress->SetRatioInfo(&_nowPos64, &_nowPos64)); + } + UInt32 i = 0; + while(bufferPos < endPos) + _buffer[i++] = _buffer[bufferPos++]; + bufferPos = i; + } + return S_OK; +} + +// #ifdef _ST_MODE +STDMETHODIMP CFilterCoder::SetOutStream(ISequentialOutStream *outStream) +{ + _bufferPos = 0; + _outStream = outStream; + Init(); + return S_OK; +} + +STDMETHODIMP CFilterCoder::ReleaseOutStream() +{ + _outStream.Release(); + return S_OK; +}; + + +STDMETHODIMP CFilterCoder::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 processedSizeTotal = 0; + while(size > 0) + { + UInt32 sizeMax = kBufferSize - _bufferPos; + UInt32 sizeTemp = size; + if (sizeTemp > sizeMax) + sizeTemp = sizeMax; + memmove(_buffer + _bufferPos, data, sizeTemp); + size -= sizeTemp; + processedSizeTotal += sizeTemp; + data = (const Byte *)data + sizeTemp; + UInt32 endPos = _bufferPos + sizeTemp; + _bufferPos = Filter->Filter(_buffer, endPos); + if (_bufferPos == 0) + { + _bufferPos = endPos; + break; + } + if (_bufferPos > endPos) + { + if (size != 0) + return E_FAIL; + break; + } + RINOK(WriteWithLimit(_outStream, _bufferPos)); + UInt32 i = 0; + while(_bufferPos < endPos) + _buffer[i++] = _buffer[_bufferPos++]; + _bufferPos = i; + } + if (processedSize != NULL) + *processedSize = processedSizeTotal; + return S_OK; +} + +STDMETHODIMP CFilterCoder::WritePart(const void *data, UInt32 size, UInt32 *processedSize) +{ + return Write(data, size, processedSize); +} + +STDMETHODIMP CFilterCoder::Flush() +{ + if (_bufferPos != 0) + { + UInt32 endPos = Filter->Filter(_buffer, _bufferPos); + if (endPos > _bufferPos) + { + for (; _bufferPos < endPos; _bufferPos++) + _buffer[_bufferPos] = 0; + if (Filter->Filter(_buffer, endPos) != endPos) + return E_FAIL; + } + UInt32 processedSize; + RINOK(_outStream->Write(_buffer, _bufferPos, &processedSize)); + if (_bufferPos != processedSize) + return E_FAIL; + _bufferPos = 0; + } + CMyComPtr<IOutStreamFlush> flush; + _outStream.QueryInterface(IID_IOutStreamFlush, &flush); + if (flush) + return flush->Flush(); + return S_OK; +} + + +STDMETHODIMP CFilterCoder::SetInStream(ISequentialInStream *inStream) +{ + _convertedPosBegin = _convertedPosEnd = _bufferPos = 0; + _inStream = inStream; + Init(); + return S_OK; +} + +STDMETHODIMP CFilterCoder::ReleaseInStream() +{ + _inStream.Release(); + return S_OK; +}; + +STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 processedSizeTotal = 0; + while(size > 0) + { + if (_convertedPosBegin != _convertedPosEnd) + { + UInt32 sizeTemp = MyMin(size, _convertedPosEnd - _convertedPosBegin); + memmove(data, _buffer + _convertedPosBegin, sizeTemp); + _convertedPosBegin += sizeTemp; + data = (void *)((Byte *)data + sizeTemp); + size -= sizeTemp; + processedSizeTotal += sizeTemp; + continue; + } + int i; + for (i = 0; _convertedPosEnd + i < _bufferPos; i++) + _buffer[i] = _buffer[i + _convertedPosEnd]; + _bufferPos = i; + _convertedPosBegin = _convertedPosEnd = 0; + UInt32 processedSizeTemp; + UInt32 size0 = kBufferSize - _bufferPos; + RINOK(_inStream->Read(_buffer + _bufferPos, size0, &processedSizeTemp)); + _bufferPos = _bufferPos + processedSizeTemp; + _convertedPosEnd = Filter->Filter(_buffer, _bufferPos); + if (_convertedPosEnd == 0) + { + break; + } + if (_convertedPosEnd > _bufferPos) + { + for (; _bufferPos < _convertedPosEnd; _bufferPos++) + _buffer[_bufferPos] = 0; + _convertedPosEnd = Filter->Filter(_buffer, _bufferPos); + } + } + if (processedSize != NULL) + *processedSize = processedSizeTotal; + return S_OK; +} + +STDMETHODIMP CFilterCoder::ReadPart(void *data, UInt32 size, UInt32 *processedSize) +{ + return Read(data, size, processedSize); +} + +// #endif // _ST_MODE + +#ifndef _NO_CRYPTO +STDMETHODIMP CFilterCoder::CryptoSetPassword(const Byte *data, UInt32 size) +{ + return _setPassword->CryptoSetPassword(data, size); +} +#endif + +#ifndef EXTRACT_ONLY +STDMETHODIMP CFilterCoder::WriteCoderProperties(ISequentialOutStream *outStream) +{ + return _writeCoderProperties->WriteCoderProperties(outStream); +} +#endif + +STDMETHODIMP CFilterCoder::SetDecoderProperties2(const Byte *data, UInt32 size) +{ + return _setDecoderProperties->SetDecoderProperties2(data, size); +} diff --git a/7zip/Archive/Common/FilterCoder.h b/7zip/Archive/Common/FilterCoder.h new file mode 100755 index 00000000..a37e7715 --- /dev/null +++ b/7zip/Archive/Common/FilterCoder.h @@ -0,0 +1,132 @@ +// FilterCoder.h + +#ifndef __FILTERCODER_H +#define __FILTERCODER_H + +#include "../../../Common/MyCom.h" +#include "../../ICoder.h" +#include "../../IPassword.h" + +#define MY_QUERYINTERFACE_ENTRY_AG(i, sub0, sub) if (iid == IID_ ## i) \ +{ if (!sub) RINOK(sub0->QueryInterface(IID_ ## i, (void **)&sub)) \ +*outObject = (void *)(i *)this; AddRef(); return S_OK; } + +class CFilterCoder: + public ICompressCoder, + // #ifdef _ST_MODE + public ICompressSetInStream, + public ISequentialInStream, + public ICompressSetOutStream, + public ISequentialOutStream, + public IOutStreamFlush, + // #endif + + #ifndef _NO_CRYPTO + public ICryptoSetPassword, + #endif + #ifndef EXTRACT_ONLY + public ICompressWriteCoderProperties, + #endif + public ICompressSetDecoderProperties2, + public CMyUnknownImp +{ +protected: + Byte *_buffer; + // #ifdef _ST_MODE + CMyComPtr<ISequentialInStream> _inStream; + CMyComPtr<ISequentialOutStream> _outStream; + UInt32 _bufferPos; + UInt32 _convertedPosBegin; + UInt32 _convertedPosEnd; + // #endif + bool _outSizeIsDefined; + UInt64 _outSize; + UInt64 _nowPos64; + + void Init() + { + Filter->Init(); + _nowPos64 = 0; + _outSizeIsDefined = false; + } + + CMyComPtr<ICryptoSetPassword> _setPassword; + #ifndef EXTRACT_ONLY + CMyComPtr<ICompressWriteCoderProperties> _writeCoderProperties; + #endif + CMyComPtr<ICompressSetDecoderProperties2> _setDecoderProperties; +public: + CMyComPtr<ICompressFilter> Filter; + + CFilterCoder(); + ~CFilterCoder(); + HRESULT WriteWithLimit(ISequentialOutStream *outStream, UInt32 size); + bool NeedMore() const + { return (!_outSizeIsDefined || (_nowPos64 < _outSize)); } + +public: + MY_QUERYINTERFACE_BEGIN + MY_QUERYINTERFACE_ENTRY(ICompressCoder) + // #ifdef _ST_MODE + MY_QUERYINTERFACE_ENTRY(ICompressSetInStream) + MY_QUERYINTERFACE_ENTRY(ISequentialInStream) + + MY_QUERYINTERFACE_ENTRY(ICompressSetOutStream) + MY_QUERYINTERFACE_ENTRY(ISequentialOutStream) + MY_QUERYINTERFACE_ENTRY(IOutStreamFlush) + // #endif + + #ifndef _NO_CRYPTO + MY_QUERYINTERFACE_ENTRY_AG(ICryptoSetPassword, Filter, _setPassword) + #endif + + #ifndef EXTRACT_ONLY + MY_QUERYINTERFACE_ENTRY_AG(ICompressWriteCoderProperties, Filter, _writeCoderProperties) + #endif + + MY_QUERYINTERFACE_ENTRY_AG(ICompressSetDecoderProperties2, Filter, _setDecoderProperties) + MY_QUERYINTERFACE_END + MY_ADDREF_RELEASE + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + // #ifdef _ST_MODE + STDMETHOD(ReleaseInStream)(); + STDMETHOD(SetInStream)(ISequentialInStream *inStream); + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); \ + STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); \ + STDMETHOD(SetOutStream)(ISequentialOutStream *outStream); + STDMETHOD(ReleaseOutStream)(); + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(Flush)(); + // #endif + + #ifndef _NO_CRYPTO + STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); + #endif + #ifndef EXTRACT_ONLY + STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); + #endif + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); +}; + +// #ifdef _ST_MODE +class CInStreamReleaser +{ +public: + CFilterCoder *FilterCoder; + CInStreamReleaser(): FilterCoder(0) {} + ~CInStreamReleaser() { if (FilterCoder) FilterCoder->ReleaseInStream(); } +}; + +class COutStreamReleaser +{ +public: + CFilterCoder *FilterCoder; + COutStreamReleaser(): FilterCoder(0) {} + ~COutStreamReleaser() { if (FilterCoder) FilterCoder->ReleaseOutStream(); } +}; +// #endif + +#endif diff --git a/7zip/Archive/Common/InStreamWithCRC.cpp b/7zip/Archive/Common/InStreamWithCRC.cpp index 40e950a8..e1b98383 100755 --- a/7zip/Archive/Common/InStreamWithCRC.cpp +++ b/7zip/Archive/Common/InStreamWithCRC.cpp @@ -4,10 +4,34 @@ #include "InStreamWithCRC.h" +STDMETHODIMP CSequentialInStreamWithCRC::Read(void *data, + UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize; + HRESULT result = _stream->Read(data, size, &realProcessedSize); + _size += realProcessedSize; + _crc.Update(data, realProcessedSize); + if(processedSize != NULL) + *processedSize = realProcessedSize; + return result; +} + +STDMETHODIMP CSequentialInStreamWithCRC::ReadPart(void *data, + UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize; + HRESULT result = _stream->ReadPart(data, size, &realProcessedSize); + _size += realProcessedSize; + _crc.Update(data, realProcessedSize); + if(processedSize != NULL) + *processedSize = realProcessedSize; + return result; +} + STDMETHODIMP CInStreamWithCRC::Read(void *data, - UINT32 size, UINT32 *processedSize) + UInt32 size, UInt32 *processedSize) { - UINT32 realProcessedSize; + UInt32 realProcessedSize; HRESULT result = _stream->Read(data, size, &realProcessedSize); _size += realProcessedSize; _crc.Update(data, realProcessedSize); @@ -17,9 +41,9 @@ STDMETHODIMP CInStreamWithCRC::Read(void *data, } STDMETHODIMP CInStreamWithCRC::ReadPart(void *data, - UINT32 size, UINT32 *processedSize) + UInt32 size, UInt32 *processedSize) { - UINT32 realProcessedSize; + UInt32 realProcessedSize; HRESULT result = _stream->ReadPart(data, size, &realProcessedSize); _size += realProcessedSize; _crc.Update(data, realProcessedSize); @@ -28,8 +52,8 @@ STDMETHODIMP CInStreamWithCRC::ReadPart(void *data, return result; } -STDMETHODIMP CInStreamWithCRC::Seek(INT64 offset, - UINT32 seekOrigin, UINT64 *newPosition) +STDMETHODIMP CInStreamWithCRC::Seek(Int64 offset, + UInt32 seekOrigin, UInt64 *newPosition) { if (seekOrigin != STREAM_SEEK_SET || offset != 0) return E_FAIL; diff --git a/7zip/Archive/Common/InStreamWithCRC.h b/7zip/Archive/Common/InStreamWithCRC.h index 6f1aa13e..112af5d0 100755 --- a/7zip/Archive/Common/InStreamWithCRC.h +++ b/7zip/Archive/Common/InStreamWithCRC.h @@ -1,7 +1,5 @@ // InStreamWithCRC.h -// #pragma once - #ifndef __INSTREAMWITHCRC_H #define __INSTREAMWITHCRC_H @@ -9,6 +7,31 @@ #include "../../../Common/MyCom.h" #include "../../IStream.h" +class CSequentialInStreamWithCRC: + public ISequentialInStream, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); +private: + CMyComPtr<ISequentialInStream> _stream; + UInt64 _size; + CCRC _crc; +public: + void Init(ISequentialInStream *stream) + { + _stream = stream; + _size = 0; + _crc.Init(); + } + void ReleaseStream() { _stream.Release(); } + UInt32 GetCRC() const { return _crc.GetDigest(); } + UInt64 GetSize() const { return _size; } +}; + class CInStreamWithCRC: public IInStream, public CMyUnknownImp @@ -16,12 +39,12 @@ class CInStreamWithCRC: public: MY_UNKNOWN_IMP - STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize); - STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize); - STDMETHOD(Seek)(INT64 offset, UINT32 seekOrigin, UINT64 *newPosition); + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); private: CMyComPtr<IInStream> _stream; - UINT64 _size; + UInt64 _size; CCRC _crc; public: void Init(IInStream *stream) @@ -31,8 +54,8 @@ public: _crc.Init(); } void ReleaseStream() { _stream.Release(); } - UINT32 GetCRC() const { return _crc.GetDigest(); } - UINT64 GetSize() const { return _size; } + UInt32 GetCRC() const { return _crc.GetDigest(); } + UInt64 GetSize() const { return _size; } }; #endif diff --git a/7zip/Archive/Common/ItemNameUtils.cpp b/7zip/Archive/Common/ItemNameUtils.cpp index b367b274..4cfecd41 100755 --- a/7zip/Archive/Common/ItemNameUtils.cpp +++ b/7zip/Archive/Common/ItemNameUtils.cpp @@ -10,28 +10,41 @@ namespace NItemName { static const wchar_t kOSDirDelimiter = '\\'; static const wchar_t kDirDelimiter = '/'; -UString MakeLegalName(const UString &aName) +UString MakeLegalName(const UString &name) { - UString aZipName = aName; - aZipName.Replace(kOSDirDelimiter, kDirDelimiter); - return aZipName; + UString zipName = name; + zipName.Replace(kOSDirDelimiter, kDirDelimiter); + return zipName; } -UString GetOSName(const UString &aName) +UString GetOSName(const UString &name) { - UString aNewName = aName; - aNewName.Replace(kDirDelimiter, kOSDirDelimiter); - return aNewName; + UString newName = name; + newName.Replace(kDirDelimiter, kOSDirDelimiter); + return newName; } -UString GetOSName2(const UString &aName) +UString GetOSName2(const UString &name) { - if (aName.IsEmpty()) + if (name.IsEmpty()) return UString(); - UString aNewName = GetOSName(aName); - if (aNewName[aNewName.Length() - 1] == kOSDirDelimiter) - aNewName.Delete(aNewName.Length() - 1); - return aNewName; + UString newName = GetOSName(name); + if (newName[newName.Length() - 1] == kOSDirDelimiter) + newName.Delete(newName.Length() - 1); + return newName; +} + +bool HasTailSlash(const AString &name, UINT codePage) +{ + if (name.IsEmpty()) + return false; + LPCSTR prev = + #ifdef _WIN32 + CharPrevExA(codePage, name, &name[name.Length()], 0); + #else + (LPCSTR)(name) + (name.Length() - 1); + #endif + return (*prev == '/'); } }} diff --git a/7zip/Archive/Common/ItemNameUtils.h b/7zip/Archive/Common/ItemNameUtils.h index 0e9badc6..90dcba5b 100755 --- a/7zip/Archive/Common/ItemNameUtils.h +++ b/7zip/Archive/Common/ItemNameUtils.h @@ -1,7 +1,5 @@ // Archive/Common/ItemNameUtils.h -#pragma once - #ifndef __ARCHIVE_ITEMNAMEUTILS_H #define __ARCHIVE_ITEMNAMEUTILS_H @@ -10,9 +8,10 @@ namespace NArchive { namespace NItemName { - UString MakeLegalName(const UString &aName); - UString GetOSName(const UString &aName); - UString GetOSName2(const UString &aName); + UString MakeLegalName(const UString &name); + UString GetOSName(const UString &name); + UString GetOSName2(const UString &name); + bool HasTailSlash(const AString &name, UINT codePage); }} diff --git a/7zip/Archive/Common/MultiStream.cpp b/7zip/Archive/Common/MultiStream.cpp new file mode 100755 index 00000000..cdcb8886 --- /dev/null +++ b/7zip/Archive/Common/MultiStream.cpp @@ -0,0 +1,213 @@ +// MultiStream.cpp + +#include "StdAfx.h" + +#include "MultiStream.h" + +STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + if(processedSize != NULL) + *processedSize = 0; + while(_streamIndex < Streams.Size() && size > 0) + { + CSubStreamInfo &s = Streams[_streamIndex]; + if (_pos == s.Size) + { + _streamIndex++; + _pos = 0; + continue; + } + RINOK(s.Stream->Seek(s.Pos + _pos, STREAM_SEEK_SET, 0)); + UInt32 sizeToRead = UInt32(MyMin((UInt64)size, s.Size - _pos)); + UInt32 realProcessed; + HRESULT result = s.Stream->Read(data, sizeToRead, &realProcessed); + data = (void *)((Byte *)data + realProcessed); + size -= realProcessed; + if(processedSize != NULL) + *processedSize += realProcessed; + _pos += realProcessed; + _seekPos += realProcessed; + RINOK(result); + if (realProcessed == 0) + break; + } + return S_OK; +} + +STDMETHODIMP CMultiStream::ReadPart(void *data, UInt32 size, UInt32 *processedSize) +{ + return Read(data, size, processedSize); +} + +STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin, + UInt64 *newPosition) +{ + UInt64 newPos; + if(seekOrigin >= 3) + return STG_E_INVALIDFUNCTION; + switch(seekOrigin) + { + case STREAM_SEEK_SET: + newPos = offset; + break; + case STREAM_SEEK_CUR: + newPos = _seekPos + offset; + break; + case STREAM_SEEK_END: + newPos = _totalLength + offset; + break; + } + _seekPos = 0; + for (_streamIndex = 0; _streamIndex < Streams.Size(); _streamIndex++) + { + UInt64 size = Streams[_streamIndex].Size; + if (newPos < _seekPos + size) + { + _pos = newPos - _seekPos; + _seekPos += _pos; + if (newPosition != 0) + *newPosition = newPos; + return S_OK; + } + _seekPos += size; + } + if (newPos == _seekPos) + { + if (newPosition != 0) + *newPosition = newPos; + return S_OK; + } + return E_FAIL; +} + + +/* +class COutVolumeStream: + public ISequentialOutStream, + public CMyUnknownImp +{ + int _volIndex; + UInt64 _volSize; + UInt64 _curPos; + CMyComPtr<ISequentialOutStream> _volumeStream; + COutArchive _archive; + CCRC _crc; + +public: + MY_UNKNOWN_IMP + + CFileItem _file; + CUpdateOptions _options; + CMyComPtr<IArchiveUpdateCallback2> VolumeCallback; + void Init(IArchiveUpdateCallback2 *volumeCallback, + const UString &name) + { + _file.Name = name; + _file.IsStartPosDefined = true; + _file.StartPos = 0; + + VolumeCallback = volumeCallback; + _volIndex = 0; + _volSize = 0; + } + + HRESULT Flush(); + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +HRESULT COutVolumeStream::Flush() +{ + if (_volumeStream) + { + _file.UnPackSize = _curPos; + _file.FileCRC = _crc.GetDigest(); + RINOK(WriteVolumeHeader(_archive, _file, _options)); + _archive.Close(); + _volumeStream.Release(); + _file.StartPos += _file.UnPackSize; + } + return S_OK; +} +*/ + +/* +STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + if(processedSize != NULL) + *processedSize = 0; + while(size > 0) + { + if (_streamIndex >= Streams.Size()) + { + CSubStreamInfo subStream; + RINOK(VolumeCallback->GetVolumeSize(Streams.Size(), &subStream.Size)); + RINOK(VolumeCallback->GetVolumeStream(Streams.Size(), &subStream.Stream)); + subStream.Pos = 0; + Streams.Add(subStream); + continue; + } + CSubStreamInfo &subStream = Streams[_streamIndex]; + if (_offsetPos >= subStream.Size) + { + _offsetPos -= subStream.Size; + _streamIndex++; + continue; + } + if (_offsetPos != subStream.Pos) + { + CMyComPtr<IOutStream> outStream; + RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream)); + RINOK(outStream->Seek(_offsetPos, STREAM_SEEK_SET, NULL)); + subStream.Pos = _offsetPos; + } + + UInt32 curSize = (UInt32)MyMin((UInt64)size, subStream.Size - subStream.Pos); + UInt32 realProcessed; + RINOK(subStream.Stream->Write(data, curSize, &realProcessed)); + data = (void *)((Byte *)data + realProcessed); + size -= realProcessed; + subStream.Pos += realProcessed; + _offsetPos += realProcessed; + _absPos += realProcessed; + if (_absPos > _length) + _length = _absPos; + if(processedSize != NULL) + *processedSize += realProcessed; + if (subStream.Pos == subStream.Size) + { + _streamIndex++; + _offsetPos = 0; + } + if (realProcessed != curSize) + return E_FAIL; + } + return S_OK; +} + +STDMETHODIMP COutMultiStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize) +{ + return Write(data, size, processedSize); +} + +STDMETHODIMP COutMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +{ + if(seekOrigin >= 3) + return STG_E_INVALIDFUNCTION; + switch(seekOrigin) + { + case STREAM_SEEK_SET: + _absPos = offset; + break; + case STREAM_SEEK_CUR: + _absPos += offset; + break; + case STREAM_SEEK_END: + _absPos = _length + offset; + break; + } + _offsetPos = _absPos; + _streamIndex = 0; + return S_OK; +} +*/ diff --git a/7zip/Archive/Common/MultiStream.h b/7zip/Archive/Common/MultiStream.h new file mode 100755 index 00000000..b6e2abc5 --- /dev/null +++ b/7zip/Archive/Common/MultiStream.h @@ -0,0 +1,78 @@ +// MultiStream.h + +#ifndef __MULTISTREAM_H +#define __MULTISTREAM_H + +#include "../../../Common/MyCom.h" +#include "../../../Common/Vector.h" +#include "../../Archive/IArchive.h" + +class CMultiStream: + public IInStream, + public CMyUnknownImp +{ + int _streamIndex; + UInt64 _pos; + UInt64 _seekPos; + UInt64 _totalLength; +public: + struct CSubStreamInfo + { + CMyComPtr<IInStream> Stream; + UInt64 Pos; + UInt64 Size; + }; + CObjectVector<CSubStreamInfo> Streams; + void Init() + { + _streamIndex = 0; + _pos = 0; + _seekPos = 0; + _totalLength = 0; + for (int i = 0; i < Streams.Size(); i++) + _totalLength += Streams[i].Size; + } + + MY_UNKNOWN_IMP1(IInStream) + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); +}; + +/* +class COutMultiStream: + public IOutStream, + public CMyUnknownImp +{ + int _streamIndex; // required stream + UInt64 _offsetPos; // offset from start of _streamIndex index + UInt64 _absPos; + UInt64 _length; + + struct CSubStreamInfo + { + CMyComPtr<ISequentialOutStream> Stream; + UInt64 Size; + UInt64 Pos; + }; + CObjectVector<CSubStreamInfo> Streams; +public: + CMyComPtr<IArchiveUpdateCallback2> VolumeCallback; + void Init() + { + _streamIndex = 0; + _offsetPos = 0; + _absPos = 0; + _length = 0; + } + + MY_UNKNOWN_IMP1(IOutStream) + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); +}; +*/ + +#endif diff --git a/7zip/Archive/Common/OutStreamWithCRC.cpp b/7zip/Archive/Common/OutStreamWithCRC.cpp index 5899e753..ae832eef 100755 --- a/7zip/Archive/Common/OutStreamWithCRC.cpp +++ b/7zip/Archive/Common/OutStreamWithCRC.cpp @@ -5,10 +5,10 @@ #include "OutStreamWithCRC.h" STDMETHODIMP COutStreamWithCRC::Write(const void *data, - UINT32 size, UINT32 *processedSize) + UInt32 size, UInt32 *processedSize) { HRESULT result; - UINT32 realProcessedSize; + UInt32 realProcessedSize; if(!_stream) { realProcessedSize = size; @@ -23,9 +23,9 @@ STDMETHODIMP COutStreamWithCRC::Write(const void *data, } STDMETHODIMP COutStreamWithCRC::WritePart(const void *data, - UINT32 size, UINT32 *processedSize) + UInt32 size, UInt32 *processedSize) { - UINT32 realProcessedSize; + UInt32 realProcessedSize; HRESULT result; if(!_stream) { diff --git a/7zip/Archive/Common/OutStreamWithCRC.h b/7zip/Archive/Common/OutStreamWithCRC.h index b95abaf8..2668885c 100755 --- a/7zip/Archive/Common/OutStreamWithCRC.h +++ b/7zip/Archive/Common/OutStreamWithCRC.h @@ -1,7 +1,5 @@ // OutStreamWithCRC.h -// #pragma once - #ifndef __OUTSTREAMWITHCRC_H #define __OUTSTREAMWITHCRC_H @@ -16,8 +14,8 @@ class COutStreamWithCRC: public: MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize); - STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize); + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); private: CCRC _crc; CMyComPtr<ISequentialOutStream> _stream; @@ -28,7 +26,7 @@ public: _crc.Init(); } void ReleaseStream() { _stream.Release(); } - UINT32 GetCRC() const { return _crc.GetDigest(); } + UInt32 GetCRC() const { return _crc.GetDigest(); } void InitCRC() { _crc.Init(); } }; diff --git a/7zip/Archive/Common/StdAfx.h b/7zip/Archive/Common/StdAfx.h index a32fbed6..e7fb6986 100755 --- a/7zip/Archive/Common/StdAfx.h +++ b/7zip/Archive/Common/StdAfx.h @@ -1,8 +1,8 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> +#include "../../../Common/MyWindows.h" -#endif +#endif diff --git a/7zip/Archive/Deb/Deb.dsp b/7zip/Archive/Deb/Deb.dsp index 6c121a53..31b27e73 100755 --- a/7zip/Archive/Deb/Deb.dsp +++ b/7zip/Archive/Deb/Deb.dsp @@ -126,6 +126,14 @@ SOURCE=.\StdAfx.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\NewHandler.cpp # End Source File # Begin Source File @@ -134,6 +142,14 @@ SOURCE=..\..\..\Common\NewHandler.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\StringConvert.cpp # End Source File # Begin Source File diff --git a/7zip/Archive/Deb/DebHandler.cpp b/7zip/Archive/Deb/DebHandler.cpp index 389e5d15..bfcb1f20 100755 --- a/7zip/Archive/Deb/DebHandler.cpp +++ b/7zip/Archive/Deb/DebHandler.cpp @@ -29,7 +29,7 @@ namespace NDeb { STATPROPSTG kProperties[] = { { NULL, kpidPath, VT_BSTR}, - { NULL, kpidIsFolder, VT_BOOL}, + // { NULL, kpidIsFolder, VT_BOOL}, { NULL, kpidSize, VT_UI8}, { NULL, kpidPackedSize, VT_UI8}, { NULL, kpidLastWriteTime, VT_FILETIME} @@ -41,13 +41,13 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) return S_OK; } -STDMETHODIMP CHandler::GetNumberOfProperties(UINT32 *numProperties) +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) { *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); return S_OK; } -STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index, +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) { if(index >= sizeof(kProperties) / sizeof(kProperties[0])) @@ -59,13 +59,13 @@ STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index, return S_OK; } -STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UINT32 *numProperties) +STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) { *numProperties = 0; return S_OK; } -STDMETHODIMP CHandler::GetArchivePropertyInfo(UINT32 index, +STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) { return E_INVALIDARG; @@ -73,12 +73,11 @@ STDMETHODIMP CHandler::GetArchivePropertyInfo(UINT32 index, STDMETHODIMP CHandler::Open(IInStream *stream, - const UINT64 *maxCheckStartPosition, + const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) { COM_TRY_BEGIN bool mustBeClosed = true; - // try { CInArchive archive; if(archive.Open(stream) != S_OK) @@ -88,7 +87,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream, if (openArchiveCallback != NULL) { RINOK(openArchiveCallback->SetTotal(NULL, NULL)); - UINT64 numFiles = _items.Size(); + UInt64 numFiles = _items.Size(); RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); } @@ -107,18 +106,12 @@ STDMETHODIMP CHandler::Open(IInStream *stream, archive.SkeepData(itemInfo.Size); if (openArchiveCallback != NULL) { - UINT64 numFiles = _items.Size(); + UInt64 numFiles = _items.Size(); RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); } } _inStream = stream; } - /* - catch(...) - { - return S_FALSE; - } - */ return S_OK; COM_TRY_END } @@ -130,13 +123,13 @@ STDMETHODIMP CHandler::Close() return S_OK; } -STDMETHODIMP CHandler::GetNumberOfItems(UINT32 *numItems) +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) { *numItems = _items.Size(); return S_OK; } -STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value) +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant propVariant; @@ -174,24 +167,24 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *val COM_TRY_END } -STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, - INT32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - bool allFilesMode = (numItems == UINT32(-1)); + bool allFilesMode = (numItems == UInt32(-1)); if (allFilesMode) numItems = _items.Size(); if(numItems == 0) return S_OK; bool testMode = (_aTestMode != 0); - UINT64 totalSize = 0; - UINT32 i; + UInt64 totalSize = 0; + UInt32 i; for(i = 0; i < numItems; i++) totalSize += _items[allFilesMode ? i : indices[i]].Size; extractCallback->SetTotal(totalSize); - UINT64 currentTotalSize = 0; - UINT64 currentItemSize; + UInt64 currentTotalSize = 0; + UInt64 currentItemSize; CMyComPtr<ICompressCoder> copyCoder; @@ -199,10 +192,10 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, { RINOK(extractCallback->SetCompleted(¤tTotalSize)); CMyComPtr<ISequentialOutStream> realOutStream; - INT32 askMode; + Int32 askMode; askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract; - INT32 index = allFilesMode ? i : indices[i]; + Int32 index = allFilesMode ? i : indices[i]; const CItemEx &itemInfo = _items[index]; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); diff --git a/7zip/Archive/Deb/DebHandler.h b/7zip/Archive/Deb/DebHandler.h index 2da70596..bf1480e3 100755 --- a/7zip/Archive/Deb/DebHandler.h +++ b/7zip/Archive/Deb/DebHandler.h @@ -1,7 +1,5 @@ // DebHandler.h -#pragma once - #ifndef __DEB_HANDLER_H #define __DEB_HANDLER_H @@ -21,22 +19,22 @@ public: MY_UNKNOWN_IMP STDMETHOD(Open)(IInStream *stream, - const UINT64 *maxCheckStartPosition, + const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback); STDMETHOD(Close)(); - STDMETHOD(GetNumberOfItems)(UINT32 *numItems); - STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(Extract)(const UINT32* indices, UINT32 numItems, - INT32 testMode, IArchiveExtractCallback *extractCallback); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback); STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); - STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties); - STDMETHOD(GetPropertyInfo)(UINT32 index, + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType); - STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties); - STDMETHOD(GetArchivePropertyInfo)(UINT32 index, + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType); private: diff --git a/7zip/Archive/Deb/DebHeader.cpp b/7zip/Archive/Deb/DebHeader.cpp index b3c01119..dce00e1b 100755 --- a/7zip/Archive/Deb/DebHeader.cpp +++ b/7zip/Archive/Deb/DebHeader.cpp @@ -8,7 +8,6 @@ namespace NArchive { namespace NDeb { namespace NHeader { - const char *kSignature = "!<arch>\n"; +const char *kSignature = "!<arch>\n"; }}} - diff --git a/7zip/Archive/Deb/DebHeader.h b/7zip/Archive/Deb/DebHeader.h index 5edda3d0..c2884000 100755 --- a/7zip/Archive/Deb/DebHeader.h +++ b/7zip/Archive/Deb/DebHeader.h @@ -1,7 +1,5 @@ // Archive/Deb/Header.h -#pragma once - #ifndef __ARCHIVE_DEB_HEADER_H #define __ARCHIVE_DEB_HEADER_H @@ -10,16 +8,16 @@ namespace NArchive { namespace NDeb { -#pragma pack( push, PragmaDebHeaders) -#pragma pack( push, 1) - namespace NHeader { + const int kSignatureLen = 8; + extern const char *kSignature; const int kNameSize = 16; const int kTimeSize = 12; const int kModeSize = 8; const int kSizeSize = 10; + /* struct CHeader { char Name[kNameSize]; @@ -31,14 +29,10 @@ namespace NHeader char Quote; char NewLine; }; - - const int kSignatureLen = 8; - extern const char *kSignature; + */ + const int kHeaderSize = kNameSize + kTimeSize + 6 + 6 + kModeSize + kSizeSize + 1 + 1; } -#pragma pack(pop) -#pragma pack(pop, PragmaDebHeaders) - }} #endif diff --git a/7zip/Archive/Deb/DebIn.cpp b/7zip/Archive/Deb/DebIn.cpp index d6c32b05..55f1e034 100755 --- a/7zip/Archive/Deb/DebIn.cpp +++ b/7zip/Archive/Deb/DebIn.cpp @@ -12,7 +12,7 @@ namespace NDeb { using namespace NHeader; -HRESULT CInArchive::ReadBytes(void *data, UINT32 size, UINT32 &processedSize) +HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize) { RINOK(m_Stream->Read(data, size, &processedSize)); m_Position += processedSize; @@ -23,7 +23,7 @@ HRESULT CInArchive::Open(IInStream *inStream) { RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_Position)); char signature[kSignatureLen]; - UINT32 processedSize; + UInt32 processedSize; RINOK(inStream->Read(signature, kSignatureLen, &processedSize)); m_Position += processedSize; if (processedSize != kSignatureLen) @@ -56,7 +56,7 @@ static bool CheckDecimalString(const char *srcString, int numChars) #define ReturnIfBadOctal(x, y) { if (!CheckOctalString((x), (y))) return S_FALSE; } #define ReturnIfBadDecimal(x, y) { if (!CheckDecimalString((x), (y))) return S_FALSE; } -static UINT32 StringToNumber(const char *srcString, int numChars, int radix) +static UInt32 StringToNumber(const char *srcString, int numChars, int radix) { AString modString; for (int i = 0; i < numChars; i++) @@ -64,39 +64,48 @@ static UINT32 StringToNumber(const char *srcString, int numChars, int radix) char *endPtr; return strtoul(modString, &endPtr, radix); } -static UINT32 OctalToNumber(const char *srcString, int numChars) +static UInt32 OctalToNumber(const char *srcString, int numChars) { return StringToNumber(srcString, numChars, 8); } -static UINT32 DecimalToNumber(const char *srcString, int numChars) +static UInt32 DecimalToNumber(const char *srcString, int numChars) { return StringToNumber(srcString, numChars, 10); } HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item) { filled = false; - CHeader header; - UINT32 processedSize; + char header[NHeader::kHeaderSize]; + const char *cur = header; + + UInt32 processedSize; item.HeaderPosition = m_Position; - RINOK(ReadBytes(&header, sizeof(header), processedSize)); + RINOK(ReadBytes(header, sizeof(header), processedSize)); if (processedSize < sizeof(header)) return S_OK; char tempString[kNameSize + 1]; - strncpy(tempString, header.Name, kNameSize); + strncpy(tempString, cur, kNameSize); + cur += kNameSize; tempString[kNameSize] = '\0'; item.Name = tempString; item.Name.Trim(); for (int i = 0; i < item.Name.Length(); i++) - if (((BYTE)item.Name[i]) < 0x20) + if (((Byte)item.Name[i]) < 0x20) return S_FALSE; - ReturnIfBadDecimal(header.ModificationTime, kTimeSize); - ReturnIfBadOctal(header.Mode, kModeSize); - ReturnIfBadDecimal(header.Size, kSizeSize); + ReturnIfBadDecimal(cur, kTimeSize); + item.ModificationTime = DecimalToNumber(cur, kTimeSize); + cur += kTimeSize; + + cur += 6 + 6; + + ReturnIfBadOctal(cur, kModeSize); + item.Mode = OctalToNumber(cur, kModeSize); + cur += kModeSize; - item.ModificationTime = DecimalToNumber(header.ModificationTime, kTimeSize); - item.Mode = OctalToNumber(header.Mode, kModeSize); - item.Size = DecimalToNumber(header.Size, kSizeSize); + ReturnIfBadDecimal(cur, kSizeSize); + item.Size = DecimalToNumber(cur, kSizeSize); + cur += kSizeSize; filled = true; return S_OK; @@ -118,9 +127,9 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item) return S_OK; } -HRESULT CInArchive::Skeep(UINT64 numBytes) +HRESULT CInArchive::Skeep(UInt64 numBytes) { - UINT64 newPostion; + UInt64 newPostion; RINOK(m_Stream->Seek(numBytes, STREAM_SEEK_CUR, &newPostion)); m_Position += numBytes; if (m_Position != newPostion) @@ -128,9 +137,9 @@ HRESULT CInArchive::Skeep(UINT64 numBytes) return S_OK; } -HRESULT CInArchive::SkeepData(UINT64 dataSize) +HRESULT CInArchive::SkeepData(UInt64 dataSize) { - return Skeep((dataSize + 1) & 0xFFFFFFFFFFFFFFFE); + return Skeep((dataSize + 1) & (~((UInt64)0x1))); } }} diff --git a/7zip/Archive/Deb/DebIn.h b/7zip/Archive/Deb/DebIn.h index 5089ab27..c1b72b6e 100755 --- a/7zip/Archive/Deb/DebIn.h +++ b/7zip/Archive/Deb/DebIn.h @@ -1,7 +1,5 @@ // Archive/DebIn.h -#pragma once - #ifndef __ARCHIVE_DEB_IN_H #define __ARCHIVE_DEB_IN_H @@ -15,15 +13,15 @@ namespace NDeb { class CInArchive { CMyComPtr<IInStream> m_Stream; - UINT64 m_Position; + UInt64 m_Position; - HRESULT ReadBytes(void *data, UINT32 size, UINT32 &processedSize); + HRESULT ReadBytes(void *data, UInt32 size, UInt32 &processedSize); HRESULT GetNextItemReal(bool &filled, CItemEx &itemInfo); - HRESULT Skeep(UINT64 numBytes); + HRESULT Skeep(UInt64 numBytes); public: HRESULT Open(IInStream *inStream); HRESULT GetNextItem(bool &filled, CItemEx &itemInfo); - HRESULT SkeepData(UINT64 dataSize); + HRESULT SkeepData(UInt64 dataSize); }; }} diff --git a/7zip/Archive/Deb/DebItem.h b/7zip/Archive/Deb/DebItem.h index 58b493fa..f587f3f5 100755 --- a/7zip/Archive/Deb/DebItem.h +++ b/7zip/Archive/Deb/DebItem.h @@ -1,7 +1,5 @@ // Archive/Deb/ItemInfo.h -#pragma once - #ifndef __ARCHIVE_DEB_ITEMINFO_H #define __ARCHIVE_DEB_ITEMINFO_H @@ -16,17 +14,17 @@ class CItem { public: AString Name; - UINT64 Size; - UINT32 ModificationTime; - UINT32 Mode; + UInt64 Size; + UInt32 ModificationTime; + UInt32 Mode; }; class CItemEx: public CItem { public: - UINT64 HeaderPosition; - UINT64 GetDataPosition() const { return HeaderPosition + sizeof(NHeader::CHeader); }; - // UINT64 GetFullSize() const { return NFileHeader::kRecordSize + Size; }; + UInt64 HeaderPosition; + UInt64 GetDataPosition() const { return HeaderPosition + NHeader::kHeaderSize; }; + // UInt64 GetFullSize() const { return NFileHeader::kRecordSize + Size; }; }; }} diff --git a/7zip/Archive/Deb/DllExports.cpp b/7zip/Archive/Deb/DllExports.cpp index d80af48e..66bf7c38 100755 --- a/7zip/Archive/Deb/DllExports.cpp +++ b/7zip/Archive/Deb/DllExports.cpp @@ -2,11 +2,9 @@ #include "StdAfx.h" -#define INITGUID - +#include "Common/MyInitGuid.h" #include "Common/ComTry.h" #include "Windows/PropVariant.h" - #include "DebHandler.h" #include "../../ICoder.h" @@ -14,15 +12,9 @@ DEFINE_GUID(CLSID_CDebHandler, 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x0C, 0x00, 0x00); -// HINSTANCE g_hInstance; - extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) { - /* - if (dwReason == DLL_PROCESS_ATTACH) - g_hInstance = hInstance; - */ return TRUE; } @@ -67,6 +59,14 @@ STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) case NArchive::kKeepName: propVariant = false; break; + case NArchive::kStartSignature: + { + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)NArchive::NDeb::NHeader::kSignature, + NArchive::NDeb::NHeader::kSignatureLen)) != 0) + value->vt = VT_BSTR; + return S_OK; + } } propVariant.Detach(value); return S_OK; diff --git a/7zip/Archive/Deb/StdAfx.cpp b/7zip/Archive/Deb/StdAfx.cpp index 2550270c..d0feea85 100755 --- a/7zip/Archive/Deb/StdAfx.cpp +++ b/7zip/Archive/Deb/StdAfx.cpp @@ -1,3 +1,3 @@ // StdAfx.cpp -#include "stdafx.h" +#include "StdAfx.h" diff --git a/7zip/Archive/Deb/StdAfx.h b/7zip/Archive/Deb/StdAfx.h index 9f4df604..e7fb6986 100755 --- a/7zip/Archive/Deb/StdAfx.h +++ b/7zip/Archive/Deb/StdAfx.h @@ -1,10 +1,8 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> +#include "../../../Common/MyWindows.h" -#include <time.h> - -#endif +#endif diff --git a/7zip/Archive/Deb/resource.rc b/7zip/Archive/Deb/resource.rc index ad546918..774f9c0b 100755 --- a/7zip/Archive/Deb/resource.rc +++ b/7zip/Archive/Deb/resource.rc @@ -75,8 +75,8 @@ IDI_ICON1 ICON DISCARDABLE "Deb.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,9,2,0 - PRODUCTVERSION 3,9,2,0 + FILEVERSION 4,13,0,0 + PRODUCTVERSION 4,13,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -94,14 +94,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Igor Pavlov\0" VALUE "FileDescription", "Deb Plugin for 7-Zip\0" - VALUE "FileVersion", "3, 9, 2, 0\0" + VALUE "FileVersion", "4, 13, 0, 0\0" VALUE "InternalName", "deb\0" - VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2004 Igor Pavlov\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "deb.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "7-Zip\0" - VALUE "ProductVersion", "3, 9, 2, 0\0" + VALUE "ProductVersion", "4, 13, 0, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/7zip/Archive/GZip/DllExports.cpp b/7zip/Archive/GZip/DllExports.cpp index 6385b9fb..a0e4fb90 100755 --- a/7zip/Archive/GZip/DllExports.cpp +++ b/7zip/Archive/GZip/DllExports.cpp @@ -2,8 +2,7 @@ #include "StdAfx.h" -#define INITGUID - +#include "Common/MyInitGuid.h" #include "Common/ComTry.h" #include "Windows/PropVariant.h" #include "../../ICoder.h" @@ -97,6 +96,13 @@ STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) case NArchive::kKeepName: propVariant = true; break; + case NArchive::kStartSignature: + { + const unsigned char sig[] = { 0x1F, 0x8B }; + if ((value->bstrVal = ::SysAllocStringByteLen((const char *)sig, 2)) != 0) + value->vt = VT_BSTR; + return S_OK; + } } propVariant.Detach(value); return S_OK; diff --git a/7zip/Archive/GZip/GZip.dsp b/7zip/Archive/GZip/GZip.dsp index 5ba9663d..8076f70d 100755 --- a/7zip/Archive/GZip/GZip.dsp +++ b/7zip/Archive/GZip/GZip.dsp @@ -126,6 +126,14 @@ SOURCE=.\StdAfx.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\CRC.cpp # End Source File # Begin Source File @@ -266,10 +274,6 @@ SOURCE=..\..\Common\ProgressUtils.h # PROP Default_Filter "" # Begin Source File -SOURCE=..\Common\ArchiveInterface.h -# End Source File -# Begin Source File - SOURCE=..\Common\CodecsPath.cpp # End Source File # Begin Source File @@ -301,9 +305,5 @@ SOURCE=..\Common\OutStreamWithCRC.h SOURCE=.\gz.ico # End Source File -# Begin Source File - -SOURCE=.\gz1.ico -# End Source File # End Target # End Project diff --git a/7zip/Archive/GZip/GZipHandler.cpp b/7zip/Archive/GZip/GZipHandler.cpp index f839299d..f3d0d065 100755 --- a/7zip/Archive/GZip/GZipHandler.cpp +++ b/7zip/Archive/GZip/GZipHandler.cpp @@ -68,16 +68,16 @@ enum // PropID STATPROPSTG kProperties[] = { { NULL, kpidPath, VT_BSTR}, - { NULL, kpidIsFolder, VT_BOOL}, - { NULL, kpidLastWriteTime, VT_FILETIME}, + // { NULL, kpidIsFolder, VT_BOOL}, { NULL, kpidSize, VT_UI8}, { NULL, kpidPackedSize, VT_UI8}, - { NULL, kpidCommented, VT_BOOL}, + { NULL, kpidLastWriteTime, VT_FILETIME}, + // { NULL, kpidCommented, VT_BOOL}, // { NULL, kpidMethod, VT_UI1}, - { NULL, kpidHostOS, VT_BSTR} + { NULL, kpidHostOS, VT_BSTR}, - // { NULL, kpidCRC, VT_UI4}, + { NULL, kpidCRC, VT_UI4} // { L"Extra", kpidExtraIsPresent, VT_BOOL} // { L"Extra flags", kpidExtraFlags, VT_UI1}, // { L"Is Text", kpidIsText, VT_BOOL}, @@ -89,13 +89,13 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) return S_OK; } -STDMETHODIMP CHandler::GetNumberOfProperties(UINT32 *numProperties) +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) { *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); return S_OK; } -STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index, +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) { const STATPROPSTG &prop = kProperties[index]; @@ -105,19 +105,19 @@ STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index, return S_OK; } -STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UINT32 *numProperties) +STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) { *numProperties = 0; return S_OK; } -STDMETHODIMP CHandler::GetArchivePropertyInfo(UINT32 index, +STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) { return E_NOTIMPL; } -STDMETHODIMP CHandler::GetNumberOfItems(UINT32 *numItems) +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) { COM_TRY_BEGIN *numItems = 1; @@ -125,7 +125,7 @@ STDMETHODIMP CHandler::GetNumberOfItems(UINT32 *numItems) COM_TRY_END } -STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value) +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant propVariant; @@ -143,7 +143,7 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va FILETIME utcTime; if (m_Item.Time != 0) { - NTime::UnixTimeToFileTime(m_Item.Time, utcTime); + NTime::UnixTimeToFileTime((UInt32)m_Item.Time, utcTime); propVariant = utcTime; } else @@ -154,10 +154,10 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va break; } case kpidSize: - propVariant = UINT64(m_Item.UnPackSize32); + propVariant = UInt64(m_Item.UnPackSize32); break; case kpidPackedSize: - propVariant = m_Item.PackSize; + propVariant = m_PackSize; break; case kpidCommented: propVariant = m_Item.CommentIsPresent(); @@ -169,6 +169,9 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va case kpidMethod: propVariant = m_Item.CompressionMethod; break; + case kpidCRC: + propVariant = m_Item.FileCRC; + break; /* case kpidExtraFlags: propVariant = m_Item.ExtraFlags; @@ -187,7 +190,7 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va } STDMETHODIMP CHandler::Open(IInStream *inStream, - const UINT64 *maxCheckStartPosition, + const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) { COM_TRY_BEGIN @@ -196,14 +199,13 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, CInArchive archive; RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_StreamStartPosition)); RINOK(archive.ReadHeader(inStream, m_Item)); - UINT64 newPosition; + m_DataOffset = archive.GetOffset(); + UInt64 newPosition; RINOK(inStream->Seek(-8, STREAM_SEEK_END, &newPosition)); - m_Item.PackSize = newPosition - archive.GetPosition(); - UINT32 crc, unpackSize32; - if (archive.ReadPostInfo(inStream, crc, unpackSize32) != S_OK) + m_PackSize = newPosition - (m_StreamStartPosition + m_DataOffset); + if (archive.ReadPostHeader(inStream, m_Item) != S_OK) return S_FALSE; m_Stream = inStream; - m_Item.UnPackSize32 = unpackSize32; } catch(...) { @@ -219,11 +221,11 @@ STDMETHODIMP CHandler::Close() return S_OK; } -STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, - INT32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - bool allFilesMode = (numItems == UINT32(-1)); + bool allFilesMode = (numItems == UInt32(-1)); if (!allFilesMode) { if (numItems == 0) @@ -235,27 +237,21 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, } bool testMode = (_aTestMode != 0); - UINT64 totalUnPacked = 0, totalPacked = 0; - - totalUnPacked += m_Item.UnPackSize32; - totalPacked += m_Item.PackSize; - extractCallback->SetTotal(totalUnPacked); + extractCallback->SetTotal(m_PackSize); - UINT64 currentTotalUnPacked = 0, currentTotalPacked = 0; + UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0; - RINOK(extractCallback->SetCompleted(¤tTotalUnPacked)); + RINOK(extractCallback->SetCompleted(¤tTotalPacked)); CMyComPtr<ISequentialOutStream> realOutStream; - INT32 askMode; + Int32 askMode; askMode = testMode ? NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + NArchive::NExtract::NAskMode::kExtract; RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); if(!testMode && !realOutStream) - { return S_OK; - } extractCallback->PrepareOperation(askMode); @@ -266,14 +262,11 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, CLocalProgress *localProgressSpec = new CLocalProgress; CMyComPtr<ICompressProgressInfo> progress = localProgressSpec; - localProgressSpec->Init(extractCallback, false); + localProgressSpec->Init(extractCallback, true); CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo; CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec; - localCompressProgressSpec->Init(progress, - ¤tTotalPacked, - ¤tTotalUnPacked); #ifndef COMPRESS_DEFLATE CCoderLibrary lib; @@ -283,28 +276,31 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, RINOK(m_Stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL)); while(true) { + localCompressProgressSpec->Init(progress, + ¤tTotalPacked, + ¤tTotalUnPacked); + CInArchive archive; - CItemEx item; + CItem item; HRESULT result = archive.ReadHeader(m_Stream, item); if (result != S_OK) { if (firstItem) return E_FAIL; - else - { - outStream.Release(); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)) - return S_OK; - } + outStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)) + return S_OK; } firstItem = false; - RINOK(m_Stream->Seek(item.DataPosition, STREAM_SEEK_SET, NULL)); + + UInt64 dataStartPos; + RINOK(m_Stream->Seek(0, STREAM_SEEK_CUR, &dataStartPos)); outStreamSpec->InitCRC(); switch(m_Item.CompressionMethod) { - case NCompressionMethod::kDeflated: + case NFileHeader::NCompressionMethod::kDeflate: { if(!deflateDecoder) { @@ -341,15 +337,17 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, CMyComPtr<ICompressGetInStreamProcessedSize> getInStreamProcessedSize; RINOK(deflateDecoder.QueryInterface(IID_ICompressGetInStreamProcessedSize, &getInStreamProcessedSize)); - UINT64 packSize; + UInt64 packSize; RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&packSize)); - RINOK(m_Stream->Seek(item.DataPosition + packSize, STREAM_SEEK_SET, NULL)); + UInt64 pos; + RINOK(m_Stream->Seek(dataStartPos + packSize, STREAM_SEEK_SET, &pos)); + + currentTotalPacked = pos - m_StreamStartPosition; - UINT32 crc, unpackSize32; - if (archive.ReadPostInfo(m_Stream, crc, unpackSize32) != S_OK) + CItem postItem; + if (archive.ReadPostHeader(m_Stream, postItem) != S_OK) return E_FAIL; - - if((outStreamSpec->GetCRC() != crc)) + if((outStreamSpec->GetCRC() != postItem.FileCRC)) { RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kCRCError)) return S_OK; diff --git a/7zip/Archive/GZip/GZipHandler.h b/7zip/Archive/GZip/GZipHandler.h index 037eb419..130c809c 100755 --- a/7zip/Archive/GZip/GZipHandler.h +++ b/7zip/Archive/GZip/GZipHandler.h @@ -1,7 +1,5 @@ // GZip/Handler.h -#pragma once - #ifndef __GZIP_HANDLER_H #define __GZIP_HANDLER_H @@ -28,41 +26,43 @@ public: ISetProperties) STDMETHOD(Open)(IInStream *inStream, - const UINT64 *maxCheckStartPosition, + const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback); STDMETHOD(Close)(); - STDMETHOD(GetNumberOfItems)(UINT32 *numItems); - STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(Extract)(const UINT32* indices, UINT32 numItems, - INT32 testMode, IArchiveExtractCallback *extractCallback); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback); STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); - STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties); - STDMETHOD(GetPropertyInfo)(UINT32 index, + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType); - STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties); - STDMETHOD(GetArchivePropertyInfo)(UINT32 index, + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType); // IOutArchive - STDMETHOD(UpdateItems)(IOutStream *outStream, UINT32 numItems, + STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback); - STDMETHOD(GetFileTimeType)(UINT32 *timeType); + STDMETHOD(GetFileTimeType)(UInt32 *timeType); // ISetProperties - STDMETHOD(SetProperties)(const BSTR *names, const PROPVARIANT *values, INT32 numProperties); + STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties); public: CHandler() { InitMethodProperties(); } private: - NArchive::NGZip::CItemEx m_Item; - UINT64 m_StreamStartPosition; + NArchive::NGZip::CItem m_Item; + UInt64 m_StreamStartPosition; + UInt64 m_DataOffset; + UInt64 m_PackSize; CMyComPtr<IInStream> m_Stream; CCompressionMethodMode m_Method; void InitMethodProperties() diff --git a/7zip/Archive/GZip/GZipHandlerOut.cpp b/7zip/Archive/GZip/GZipHandlerOut.cpp index 2d410554..7f367e0e 100755 --- a/7zip/Archive/GZip/GZipHandlerOut.cpp +++ b/7zip/Archive/GZip/GZipHandlerOut.cpp @@ -1,4 +1,4 @@ -// Zip/OutHandler.cpp +// Archive/GZip/OutHandler.cpp #include "StdAfx.h" @@ -20,30 +20,30 @@ using namespace NTime; namespace NArchive { namespace NGZip { -STDMETHODIMP CHandler::GetFileTimeType(UINT32 *timeType) +STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType) { *timeType = NFileTimeType::kUnix; return S_OK; } -static HRESULT CopyStreams(IInStream *inStream, IOutStream *outStream, - IArchiveUpdateCallback *updateCallback) +static HRESULT CopyStreams(ISequentialInStream *inStream, + ISequentialOutStream *outStream, IArchiveUpdateCallback *updateCallback) { CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder; return copyCoder->Code(inStream, outStream, NULL, NULL, NULL); } -STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems, +STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback) { if (numItems != 1) return E_INVALIDARG; - UINT64 size; - INT32 newData; - INT32 newProperties; - UINT32 indexInArchive; - UINT32 itemIndex = 0; + UInt64 size; + Int32 newData; + Int32 newProperties; + UInt32 indexInArchive; + UInt32 itemIndex = 0; if (!updateCallback) return E_FAIL; RINOK(updateCallback->GetUpdateItemInfo(0, @@ -54,7 +54,7 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems, newItem.Flags = 0; if (IntToBool(newProperties)) { - UINT32 attributes; + UInt32 attributes; FILETIME utcTime; UString name; bool isDirectory; @@ -97,11 +97,8 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems, } if (isDirectory || NFile::NFind::NAttributes::IsDirectory(attributes)) return E_INVALIDARG; - time_t unixTime; - if(!FileTimeToUnixTime(utcTime, unixTime)) + if(!FileTimeToUnixTime(utcTime, newItem.Time)) return E_INVALIDARG; - - newItem.Time = unixTime; newItem.Name = UnicodeStringToMultiByte(name, CP_ACP); int dirDelimiterPos = newItem.Name.ReverseFind('\\'); if (dirDelimiterPos >= 0) @@ -117,9 +114,9 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems, RINOK(updateCallback->GetProperty(itemIndex, kpidSize, &propVariant)); if (propVariant.vt != VT_UI8) return E_INVALIDARG; - size = *(UINT64 *)(&propVariant.uhVal); + size = propVariant.uhVal.QuadPart; } - newItem.UnPackSize32 = (UINT32)size; + newItem.UnPackSize32 = (UInt32)size; return UpdateArchive(m_Stream, size, outStream, newItem, m_Method, itemIndex, updateCallback); } @@ -132,7 +129,7 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems, COutArchive outArchive; outArchive.Create(outStream); outArchive.WriteHeader(newItem); - RINOK(m_Stream->Seek(m_Item.DataPosition, STREAM_SEEK_SET, NULL)); + RINOK(m_Stream->Seek(m_StreamStartPosition + m_DataOffset, STREAM_SEEK_SET, NULL)); } else { @@ -141,13 +138,13 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems, return CopyStreams(m_Stream, outStream, updateCallback); } -static const UINT32 kMatchFastLenNormal = 32; -static const UINT32 kMatchFastLenMX = 64; +static const UInt32 kMatchFastLenNormal = 32; +static const UInt32 kMatchFastLenMX = 64; -static const UINT32 kNumPassesNormal = 1; -static const UINT32 kNumPassesMX = 3; +static const UInt32 kNumPassesNormal = 1; +static const UInt32 kNumPassesMX = 3; -STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *values, INT32 numProperties) +STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) { InitMethodProperties(); for (int i = 0; i < numProperties; i++) @@ -158,7 +155,7 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value if (name[0] == 'X') { name.Delete(0); - UINT32 level = 9; + UInt32 level = 9; if (value.vt == VT_UI4) { if (!name.IsEmpty()) @@ -171,10 +168,10 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value { const wchar_t *start = name; const wchar_t *end; - UINT64 v = ConvertStringToUINT64(start, &end); + UInt64 v = ConvertStringToUInt64(start, &end); if (end - start != name.Length()) return E_INVALIDARG; - level = (UINT32)v; + level = (UInt32)v; } } else diff --git a/7zip/Archive/GZip/GZipHeader.cpp b/7zip/Archive/GZip/GZipHeader.cpp index ec3f0ef7..5e697fa9 100755 --- a/7zip/Archive/GZip/GZipHeader.cpp +++ b/7zip/Archive/GZip/GZipHeader.cpp @@ -7,7 +7,7 @@ namespace NArchive { namespace NGZip { -extern UINT16 kSignature = 0x8B1F + 1; +extern UInt16 kSignature = 0x8B1F + 1; static class CMarkersInitializer { diff --git a/7zip/Archive/GZip/GZipHeader.h b/7zip/Archive/GZip/GZipHeader.h index 34dd39c0..e83548eb 100755 --- a/7zip/Archive/GZip/GZipHeader.h +++ b/7zip/Archive/GZip/GZipHeader.h @@ -1,7 +1,5 @@ // Archive/GZip/Header.h -#pragma once - #ifndef __ARCHIVE_GZIP_HEADER_H #define __ARCHIVE_GZIP_HEADER_H @@ -10,32 +8,22 @@ namespace NArchive { namespace NGZip { -extern UINT16 kSignature; -static const UINT32 kSignatureSize = 2; - -#pragma pack( push, PragmaGZipHeaders) -#pragma pack( push, 1) - -namespace NCompressionMethod -{ - enum EType - { - kDeflated = 8, - }; -} +extern UInt16 kSignature; +static const UInt32 kSignatureSize = 2; namespace NFileHeader { + /* struct CBlock { - UINT16 Id; - BYTE CompressionMethod; - BYTE Flags; - UINT32 Time; - BYTE ExtraFlags; - BYTE HostOS; + UInt16 Id; + Byte CompressionMethod; + Byte Flags; + UInt32 Time; + Byte ExtraFlags; + Byte HostOS; }; - + */ namespace NFlags { @@ -54,12 +42,12 @@ namespace NFileHeader kFastest = 4 }; } - + namespace NCompressionMethod { - const BYTE kDefalate = 8; + const Byte kDeflate = 8; } - + namespace NHostOS { enum EEnum @@ -92,9 +80,6 @@ namespace NFileHeader } } -#pragma pack(pop) -#pragma pack(pop, PragmaGZipHeaders) - }} #endif diff --git a/7zip/Archive/GZip/GZipIn.cpp b/7zip/Archive/GZip/GZipIn.cpp index 28bcd3d8..69270fb1 100755 --- a/7zip/Archive/GZip/GZipIn.cpp +++ b/7zip/Archive/GZip/GZipIn.cpp @@ -11,9 +11,9 @@ namespace NArchive { namespace NGZip { -HRESULT CInArchive::ReadBytes(IInStream *inStream, void *data, UINT32 size) +HRESULT CInArchive::ReadBytes(ISequentialInStream *inStream, void *data, UInt32 size) { - UINT32 realProcessedSize; + UInt32 realProcessedSize; RINOK(inStream->Read(data, size, &realProcessedSize)); m_Position += realProcessedSize; if(realProcessedSize != size) @@ -21,112 +21,99 @@ HRESULT CInArchive::ReadBytes(IInStream *inStream, void *data, UINT32 size) return S_OK; } -HRESULT CInArchive::UpdateCRCBytes(IInStream *inStream, - UINT32 numBytesToSkeep, CCRC &crc) +HRESULT CInArchive::ReadByte(ISequentialInStream *inStream, Byte &value) { - while (numBytesToSkeep > 0) + return ReadBytes(inStream, &value, 1); +} + +HRESULT CInArchive::ReadUInt16(ISequentialInStream *inStream, UInt16 &value) +{ + value = 0; + for (int i = 0; i < 2; i++) + { + Byte b; + RINOK(ReadByte(inStream, b)); + value |= (UInt16(b) << (8 * i)); + } + return S_OK; +} + +HRESULT CInArchive::ReadUInt32(ISequentialInStream *inStream, UInt32 &value) +{ + value = 0; + for (int i = 0; i < 4; i++) { - const UINT32 kBufferSize = (1 << 12); - BYTE buffer[kBufferSize]; - UINT32 currentSize = MyMin(numBytesToSkeep, kBufferSize); - RINOK(ReadBytes(inStream, buffer, currentSize)); - crc.Update(buffer, currentSize); - numBytesToSkeep -= currentSize; + Byte b; + RINOK(ReadByte(inStream, b)); + value |= (UInt32(b) << (8 * i)); } return S_OK; } -HRESULT CInArchive::ReadZeroTerminatedString(IInStream *inStream, AString &resString) +HRESULT CInArchive::ReadZeroTerminatedString(ISequentialInStream *inStream, AString &resString, CCRC &crc) { resString.Empty(); while(true) { - char c; - RINOK(ReadBytes(inStream, &c, sizeof(c))); + Byte c; + RINOK(ReadByte(inStream, c)); + crc.UpdateByte(c); if (c == 0) return S_OK; - resString += c; + resString += char(c); } } -HRESULT CInArchive::ReadHeader(IInStream *inStream, CItemEx &item) +HRESULT CInArchive::ReadHeader(ISequentialInStream *inStream, CItem &item) { - RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_StreamStartPosition)); - - m_Position = m_StreamStartPosition; - NFileHeader::CBlock fileHeader; + item.Clear(); + m_Position = 0; - RINOK(ReadBytes(inStream, &fileHeader, sizeof(fileHeader))); - - if (fileHeader.Id != kSignature) + UInt16 signature; + RINOK(ReadUInt16(inStream, signature)); + if (signature != kSignature) return S_FALSE; - - item.CompressionMethod = fileHeader.CompressionMethod; - item.Flags = fileHeader.Flags; - item.Time = fileHeader.Time; - item.ExtraFlags = fileHeader.ExtraFlags; - item.HostOS = fileHeader.HostOS; - + RINOK(ReadByte(inStream, item.CompressionMethod)); + RINOK(ReadByte(inStream, item.Flags)); + RINOK(ReadUInt32(inStream, item.Time)); + RINOK(ReadByte(inStream, item.ExtraFlags)); + RINOK(ReadByte(inStream, item.HostOS)); + CCRC crc; - crc.Update(&fileHeader, sizeof(fileHeader)); + crc.Update(&signature, 2); + crc.UpdateByte(item.CompressionMethod); + crc.UpdateByte(item.Flags); + crc.UpdateUInt32(item.Time); + crc.UpdateByte(item.ExtraFlags); + crc.UpdateByte(item.HostOS); + if (item.ExtraFieldIsPresent()) { - item.ExtraPosition = m_Position; - RINOK(ReadBytes(inStream, &item.ExtraFieldSize, - sizeof(item.ExtraFieldSize))); - crc.Update(&item.ExtraFieldSize, sizeof(item.ExtraFieldSize)); - RINOK(UpdateCRCBytes(inStream, item.ExtraFieldSize, crc)); + UInt16 extraSize; + RINOK(ReadUInt16(inStream, extraSize)); + crc.UpdateUInt16(extraSize); + item.Extra.SetCapacity(extraSize); + RINOK(ReadBytes(inStream, item.Extra, extraSize)); + crc.Update(item.Extra, extraSize); } - item.Name.Empty(); if (item.NameIsPresent()) - RINOK(ReadZeroTerminatedString(inStream, item.Name)); - AString comment; + RINOK(ReadZeroTerminatedString(inStream, item.Name, crc)); if (item.CommentIsPresent()) - { - item.CommentPosition = m_Position; - RINOK(ReadZeroTerminatedString(inStream, comment)); - item.CommentSize = comment.Length() + 1; - } + RINOK(ReadZeroTerminatedString(inStream, item.Comment, crc)); if (item.HeaderCRCIsPresent()) { - UINT16 headerCRC; - RINOK(ReadBytes(inStream, &headerCRC, sizeof(headerCRC))); - if (item.NameIsPresent()) - { - crc.Update((const char *)item.Name, item.Name.Length()); - BYTE zeroByte = 0;; - crc.Update(&zeroByte, sizeof(zeroByte)); - } - if (item.CommentIsPresent()) - { - crc.Update((const char *)comment, comment.Length()); - BYTE zeroByte = 0;; - crc.Update(&zeroByte, sizeof(zeroByte)); - } - if ((UINT16)crc.GetDigest() != headerCRC) + UInt16 headerCRC; + RINOK(ReadUInt16(inStream, headerCRC)); + if ((UInt16)crc.GetDigest() != headerCRC) return S_FALSE; } - - item.DataPosition = m_Position; - - item.UnPackSize32 = 0; - item.PackSize = 0; - - /* - UINT64 newPosition; - RINOK(inStream->Seek(-8, STREAM_SEEK_END, &newPosition)); - item.PackSize = newPosition - item.DataPosition; - - RINOK(ReadBytes(inStream, &item.FileCRC, sizeof(item.FileCRC))); - RINOK(ReadBytes(inStream, &item.UnPackSize32, sizeof(item.UnPackSize32))); - */ return S_OK; } -HRESULT CInArchive::ReadPostInfo(IInStream *inStream, UINT32 &crc, UINT32 &unpackSize32) +HRESULT CInArchive::ReadPostHeader(ISequentialInStream *inStream, CItem &item) { - RINOK(ReadBytes(inStream, &crc, sizeof(crc))); - return ReadBytes(inStream, &unpackSize32, sizeof(unpackSize32)); + RINOK(ReadUInt32(inStream, item.FileCRC)); + return ReadUInt32(inStream, item.UnPackSize32); } }} diff --git a/7zip/Archive/GZip/GZipIn.h b/7zip/Archive/GZip/GZipIn.h index f0f72403..998470e0 100755 --- a/7zip/Archive/GZip/GZipIn.h +++ b/7zip/Archive/GZip/GZipIn.h @@ -1,32 +1,29 @@ // Archive/GZipIn.h -#pragma once - #ifndef __ARCHIVE_GZIP_IN_H #define __ARCHIVE_GZIP_IN_H #include "GZipHeader.h" #include "GZipItem.h" -#include "../../IStream.h" #include "Common/CRC.h" +#include "../../IStream.h" namespace NArchive { namespace NGZip { class CInArchive { - UINT64 m_StreamStartPosition; - UINT64 m_Position; + UInt64 m_Position; - HRESULT ReadBytes(IInStream *inStream, void *data, UINT32 size); - HRESULT UpdateCRCBytes(IInStream *inStream, UINT32 numBytesToSkeep, CCRC &crc); - - HRESULT ReadZeroTerminatedString(IInStream *inStream, AString &resString); - + HRESULT ReadBytes(ISequentialInStream *inStream, void *data, UInt32 size); + HRESULT ReadZeroTerminatedString(ISequentialInStream *inStream, AString &resString, CCRC &crc); + HRESULT ReadByte(ISequentialInStream *inStream, Byte &value); + HRESULT ReadUInt16(ISequentialInStream *inStream, UInt16 &value); + HRESULT ReadUInt32(ISequentialInStream *inStream, UInt32 &value); public: - HRESULT ReadHeader(IInStream *inStream, CItemEx &item); - HRESULT ReadPostInfo(IInStream *inStream, UINT32 &crc, UINT32 &unpackSize32); - UINT64 GetPosition() const { return m_Position; } + HRESULT ReadHeader(ISequentialInStream *inStream, CItem &item); + HRESULT ReadPostHeader(ISequentialInStream *inStream, CItem &item); + UInt64 GetOffset() const { return m_Position; } }; }} diff --git a/7zip/Archive/GZip/GZipItem.h b/7zip/Archive/GZip/GZipItem.h index e47abadc..7006dfb3 100755 --- a/7zip/Archive/GZip/GZipItem.h +++ b/7zip/Archive/GZip/GZipItem.h @@ -1,12 +1,11 @@ // Archive/GZipItem.h -#pragma once - #ifndef __ARCHIVE_GZIP_ITEM_H #define __ARCHIVE_GZIP_ITEM_H #include "Common/Types.h" #include "Common/String.h" +#include "Common/Buffer.h" namespace NArchive { namespace NGZip { @@ -14,20 +13,19 @@ namespace NGZip { class CItem { private: - bool TestFlag(BYTE flag) const { return ((Flags & flag) != 0); } + bool TestFlag(Byte flag) const { return ((Flags & flag) != 0); } public: - BYTE CompressionMethod; - BYTE Flags; - UINT32 Time; - BYTE ExtraFlags; - BYTE HostOS; - UINT32 FileCRC; - UINT32 UnPackSize32; - UINT64 PackSize; + Byte CompressionMethod; + Byte Flags; + UInt32 Time; + Byte ExtraFlags; + Byte HostOS; + UInt32 FileCRC; + UInt32 UnPackSize32; AString Name; - UINT16 ExtraFieldSize; - UINT16 CommentSize; + AString Comment; + CByteBuffer Extra; bool IsText() const { return TestFlag(NFileHeader::NFlags::kDataIsText); } @@ -47,19 +45,15 @@ public: else Flags &= (~NFileHeader::NFlags::kNameIsPresent); } -}; -class CItemEx: public CItem -{ -public: - UINT64 DataPosition; - UINT64 CommentPosition; - UINT64 ExtraPosition; + void Clear() + { + Name.Empty(); + Comment.Empty();; + Extra.SetCapacity(0); + } }; - }} #endif - - diff --git a/7zip/Archive/GZip/GZipOut.cpp b/7zip/Archive/GZip/GZipOut.cpp index d1968385..e88ede19 100755 --- a/7zip/Archive/GZip/GZipOut.cpp +++ b/7zip/Archive/GZip/GZipOut.cpp @@ -9,40 +9,60 @@ namespace NArchive { namespace NGZip { -HRESULT COutArchive::WriteBytes(const void *buffer, UINT32 size) +HRESULT COutArchive::WriteBytes(const void *buffer, UInt32 size) { - UINT32 processedSize; + UInt32 processedSize; RINOK(m_Stream->Write(buffer, size, &processedSize)); if(processedSize != size) return E_FAIL; return S_OK; } +HRESULT COutArchive::WriteByte(Byte value) +{ + return WriteBytes(&value, 1); +} + +HRESULT COutArchive::WriteUInt16(UInt16 value) +{ + for (int i = 0; i < 2; i++) + { + RINOK(WriteByte((Byte)value)); + value >>= 8; + } + return S_OK; +} + +HRESULT COutArchive::WriteUInt32(UInt32 value) +{ + for (int i = 0; i < 4; i++) + { + RINOK(WriteByte((Byte)value)); + value >>= 8; + } + return S_OK; +} + HRESULT COutArchive::WriteHeader(const CItem &item) { - NFileHeader::CBlock header; - header.Id = kSignature; - header.CompressionMethod = item.CompressionMethod; - header.Flags = item.Flags; - header.Flags &= NFileHeader::NFlags::kNameIsPresent; - header.Time = item.Time; - header.ExtraFlags = item.ExtraFlags; - header.HostOS = item.HostOS; - RINOK(WriteBytes(&header, sizeof(header))); + RINOK(WriteUInt16(kSignature)); + RINOK(WriteByte(item.CompressionMethod)); + RINOK(WriteByte(item.Flags & NFileHeader::NFlags::kNameIsPresent)); + RINOK(WriteUInt32(item.Time)); + RINOK(WriteByte(item.ExtraFlags)); + RINOK(WriteByte(item.HostOS)); if (item.NameIsPresent()) { - RINOK(WriteBytes((LPCSTR)item.Name, item.Name.Length())); - BYTE zero = 0; - RINOK(WriteBytes(&zero, sizeof(zero))); + RINOK(WriteBytes((const char *)item.Name, item.Name.Length())); + RINOK(WriteByte(0)); } - // check it return S_OK; } -HRESULT COutArchive::WritePostInfo(UINT32 crc, UINT32 unpackSize) +HRESULT COutArchive::WritePostHeader(const CItem &item) { - RINOK(WriteBytes(&crc, sizeof(crc))); - return WriteBytes(&unpackSize, sizeof(unpackSize)); + RINOK(WriteUInt32(item.FileCRC)); + return WriteUInt32(item.UnPackSize32); } }} diff --git a/7zip/Archive/GZip/GZipOut.h b/7zip/Archive/GZip/GZipOut.h index 6cfd08e9..a2ba2ebf 100755 --- a/7zip/Archive/GZip/GZipOut.h +++ b/7zip/Archive/GZip/GZipOut.h @@ -1,7 +1,5 @@ // Archive/GZipOut.h -#pragma once - #ifndef __ARCHIVE_GZIP_OUT_H #define __ARCHIVE_GZIP_OUT_H @@ -15,12 +13,15 @@ namespace NGZip { class COutArchive { - CMyComPtr<IOutStream> m_Stream; - HRESULT WriteBytes(const void *buffer, UINT32 size); + CMyComPtr<ISequentialOutStream> m_Stream; + HRESULT WriteBytes(const void *buffer, UInt32 size); + HRESULT WriteByte(Byte value); + HRESULT WriteUInt16(UInt16 value); + HRESULT WriteUInt32(UInt32 value); public: - void Create(IOutStream *outStream) { m_Stream = outStream; } + void Create(ISequentialOutStream *outStream) { m_Stream = outStream; } HRESULT WriteHeader(const CItem &item); - HRESULT WritePostInfo(UINT32 crc, UINT32 anUnpackSize); + HRESULT WritePostHeader(const CItem &item); }; }} diff --git a/7zip/Archive/GZip/GZipUpdate.cpp b/7zip/Archive/GZip/GZipUpdate.cpp index ba31f69f..4ce178fd 100755 --- a/7zip/Archive/GZip/GZipUpdate.cpp +++ b/7zip/Archive/GZip/GZipUpdate.cpp @@ -22,7 +22,6 @@ // {23170F69-40C1-278B-0401-080000000100} DEFINE_GUID(CLSID_CCompressDeflateEncoder, 0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00); -extern CSysString GetBaseFolderPrefix(); #include "../Common/CoderLoader.h" extern CSysString GetDeflateCodecPath(); #endif @@ -30,17 +29,17 @@ extern CSysString GetDeflateCodecPath(); namespace NArchive { namespace NGZip { -static const BYTE kHostOS = NFileHeader::NHostOS::kFAT; +static const Byte kHostOS = NFileHeader::NHostOS::kFAT; HRESULT UpdateArchive(IInStream *inStream, - UINT64 unpackSize, - IOutStream *outStream, + UInt64 unpackSize, + ISequentialOutStream *outStream, const CItem &newItem, const CCompressionMethodMode &compressionMethod, int indexInClient, IArchiveUpdateCallback *updateCallback) { - UINT64 complexity = 0; + UInt64 complexity = 0; complexity += unpackSize; @@ -54,11 +53,11 @@ HRESULT UpdateArchive(IInStream *inStream, complexity = 0; RINOK(updateCallback->SetCompleted(&complexity)); - CMyComPtr<IInStream> fileInStream; + CMyComPtr<ISequentialInStream> fileInStream; RINOK(updateCallback->GetStream(indexInClient, &fileInStream)); - CInStreamWithCRC *inStreamSpec = new CInStreamWithCRC; + CSequentialInStreamWithCRC *inStreamSpec = new CSequentialInStreamWithCRC; CMyComPtr<ISequentialInStream> crcStream(inStreamSpec); inStreamSpec->Init(fileInStream); @@ -74,7 +73,7 @@ HRESULT UpdateArchive(IInStream *inStream, outArchive.Create(outStream); CItem item = newItem; - item.CompressionMethod = NFileHeader::NCompressionMethod::kDefalate; + item.CompressionMethod = NFileHeader::NCompressionMethod::kDeflate; item.ExtraFlags = 0; item.HostOS = kHostOS; @@ -101,10 +100,10 @@ HRESULT UpdateArchive(IInStream *inStream, } RINOK(deflateEncoder->Code(crcStream, outStream, NULL, NULL, compressProgress)); - RINOK(outArchive.WritePostInfo(inStreamSpec->GetCRC(), - (UINT32)inStreamSpec->GetSize())); - return updateCallback->SetOperationResult( - NArchive::NUpdate::NOperationResult::kOK); + item.FileCRC = inStreamSpec->GetCRC(); + item.UnPackSize32 = (UInt32)inStreamSpec->GetSize(); + RINOK(outArchive.WritePostHeader(item)); + return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK); } }} diff --git a/7zip/Archive/GZip/GZipUpdate.h b/7zip/Archive/GZip/GZipUpdate.h index a7df7ff9..7c660087 100755 --- a/7zip/Archive/GZip/GZipUpdate.h +++ b/7zip/Archive/GZip/GZipUpdate.h @@ -1,7 +1,5 @@ // GZip/Update.h -#pragma once - #ifndef __GZIP_UPDATE_H #define __GZIP_UPDATE_H @@ -15,13 +13,13 @@ namespace NGZip { struct CCompressionMethodMode { - UINT32 NumPasses; - UINT32 NumFastBytes; + UInt32 NumPasses; + UInt32 NumFastBytes; }; HRESULT UpdateArchive(IInStream *inStream, - UINT64 unpackSize, - IOutStream *outStream, + UInt64 unpackSize, + ISequentialOutStream *outStream, const CItem &newItem, const CCompressionMethodMode &compressionMethod, int indexInClient, diff --git a/7zip/Archive/GZip/StdAfx.cpp b/7zip/Archive/GZip/StdAfx.cpp index 2550270c..d0feea85 100755 --- a/7zip/Archive/GZip/StdAfx.cpp +++ b/7zip/Archive/GZip/StdAfx.cpp @@ -1,3 +1,3 @@ // StdAfx.cpp -#include "stdafx.h" +#include "StdAfx.h" diff --git a/7zip/Archive/GZip/StdAfx.h b/7zip/Archive/GZip/StdAfx.h index 9f4df604..e7fb6986 100755 --- a/7zip/Archive/GZip/StdAfx.h +++ b/7zip/Archive/GZip/StdAfx.h @@ -1,10 +1,8 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> +#include "../../../Common/MyWindows.h" -#include <time.h> - -#endif +#endif diff --git a/7zip/Archive/GZip/resource.rc b/7zip/Archive/GZip/resource.rc index 41565141..d5601f35 100755 --- a/7zip/Archive/GZip/resource.rc +++ b/7zip/Archive/GZip/resource.rc @@ -75,8 +75,8 @@ IDI_ICON1 ICON DISCARDABLE "gz.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,9,2,0 - PRODUCTVERSION 3,9,2,0 + FILEVERSION 4,19,0,0 + PRODUCTVERSION 4,19,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -94,14 +94,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Igor Pavlov\0" VALUE "FileDescription", "GZip Plugin for 7-Zip\0" - VALUE "FileVersion", "3, 9, 2, 0\0" + VALUE "FileVersion", "4, 19, 0, 0\0" VALUE "InternalName", "gz\0" - VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "gz.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "7-Zip\0" - VALUE "ProductVersion", "3, 9, 2, 0\0" + VALUE "ProductVersion", "4, 19, 0, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/7zip/Archive/IArchive.h b/7zip/Archive/IArchive.h index 541307cd..9c74b1bf 100755 --- a/7zip/Archive/IArchive.h +++ b/7zip/Archive/IArchive.h @@ -27,6 +27,8 @@ namespace NArchive kAddExtension, kUpdate, kKeepName, + kStartSignature, + kFinishSignature, }; namespace NExtract @@ -71,8 +73,8 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000100010000") IArchiveOpenCallback: public IUnknown { public: - STDMETHOD(SetTotal)(const UINT64 *files, const UINT64 *bytes) PURE; - STDMETHOD(SetCompleted)(const UINT64 *files, const UINT64 *bytes) PURE; + STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes) PURE; + STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes) PURE; }; // {23170F69-40C1-278A-0000-000100090000} @@ -82,10 +84,11 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000100090000") IArchiveExtractCallback: public IProgress { public: - STDMETHOD(GetStream)(UINT32 index, ISequentialOutStream **outStream, - INT32 askExtractMode) PURE; - STDMETHOD(PrepareOperation)(INT32 askExtractMode) PURE; - STDMETHOD(SetOperationResult)(INT32 resultEOperationResult) PURE; + STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, + Int32 askExtractMode) PURE; + // GetStream OUT: S_OK - OK, S_FALSE - skeep this file + STDMETHOD(PrepareOperation)(Int32 askExtractMode) PURE; + STDMETHOD(SetOperationResult)(Int32 resultEOperationResult) PURE; }; @@ -101,6 +104,17 @@ public: }; +// {23170F69-40C1-278A-0000-0001000D0100} +DEFINE_GUID(IID_IArchiveOpenSetSubArchiveName, +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0D, 0x01, 0x00); +MIDL_INTERFACE("23170F69-40C1-278A-0000-0001000D0100") +IArchiveOpenSetSubArchiveName: public IUnknown +{ +public: + STDMETHOD(SetSubArchiveName)(const wchar_t *name) PURE; +}; + + // {23170F69-40C1-278A-0000-000100080000} DEFINE_GUID(IID_IInArchive, 0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00); @@ -108,25 +122,35 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000100080000") IInArchive: public IUnknown { public: - STDMETHOD(Open)(IInStream *stream, const UINT64 *maxCheckStartPosition, + STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) PURE; STDMETHOD(Close)() PURE; - STDMETHOD(GetNumberOfItems)(UINT32 *numItems) PURE; - STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value) PURE; - STDMETHOD(Extract)(const UINT32* indices, UINT32 numItems, - INT32 testMode, IArchiveExtractCallback *extractCallback) PURE; + STDMETHOD(GetNumberOfItems)(UInt32 *numItems) PURE; + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) PURE; + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) PURE; STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) PURE; - STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties) PURE; - STDMETHOD(GetPropertyInfo)(UINT32 index, + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties) PURE; + STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) PURE; - STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties) PURE; - STDMETHOD(GetArchivePropertyInfo)(UINT32 index, + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties) PURE; + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) PURE; }; +// {23170F69-40C1-278A-0000-000100080100} +DEFINE_GUID(IID_IInArchiveGetStream, +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x01, 0x00); +MIDL_INTERFACE("23170F69-40C1-278A-0000-000100080100") +IInArchiveGetStream: public IUnknown +{ +public: + STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream) PURE; +}; + // {23170F69-40C1-278A-0000-000100040000} DEFINE_GUID(IID_IArchiveUpdateCallback, @@ -136,16 +160,25 @@ IArchiveUpdateCallback: public IProgress { public: // STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator) PURE; - STDMETHOD(GetUpdateItemInfo)(UINT32 index, - INT32 *newData, // 1 - new data, 0 - old data - INT32 *newProperties, // 1 - new properties, 0 - old properties - UINT32 *indexInArchive // -1 if there is no in archive, or if doesn't matter + STDMETHOD(GetUpdateItemInfo)(UInt32 index, + Int32 *newData, // 1 - new data, 0 - old data + Int32 *newProperties, // 1 - new properties, 0 - old properties + UInt32 *indexInArchive // -1 if there is no in archive, or if doesn't matter ) PURE; - STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value) PURE; - STDMETHOD(GetStream)(UINT32 index, IInStream **inStream) PURE; - STDMETHOD(SetOperationResult)(INT32 operationResult) PURE; - // STDMETHOD(GetVolumeSize)(UINT32 index, UINT64 *size) PURE; - // STDMETHOD(GetVolumeStream)(UINT32 index, IOutStream **volumeStream) PURE; + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) PURE; + STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream) PURE; + STDMETHOD(SetOperationResult)(Int32 operationResult) PURE; +}; + +// {23170F69-40C1-278A-0000-000100040002} +DEFINE_GUID(IID_IArchiveUpdateCallback2, +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x02); +MIDL_INTERFACE("23170F69-40C1-278A-0000-000100040002") +IArchiveUpdateCallback2: public IArchiveUpdateCallback +{ +public: + STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size) PURE; + STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream) PURE; }; // {23170F69-40C1-278A-0000-000100020000} @@ -154,9 +187,9 @@ DEFINE_GUID(IID_IOutArchive, MIDL_INTERFACE("23170F69-40C1-278A-0000-000100020000") IOutArchive: public IUnknown { - STDMETHOD(UpdateItems)(IOutStream *outStream, UINT32 numItems, + STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback) PURE; - STDMETHOD(GetFileTimeType)(UINT32 *type) PURE; + STDMETHOD(GetFileTimeType)(UInt32 *type) PURE; }; // {23170F69-40C1-278A-0000-000100030000} @@ -165,7 +198,7 @@ DEFINE_GUID(IID_ISetProperties, MIDL_INTERFACE("23170F69-40C1-278A-0000-000100030000") ISetProperties: public IUnknown { - STDMETHOD(SetProperties)(const BSTR *names, const PROPVARIANT *values, INT32 numProperties) PURE; + STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) PURE; }; diff --git a/7zip/Archive/RPM/DllExports.cpp b/7zip/Archive/RPM/DllExports.cpp index a529f03d..d712abfe 100755 --- a/7zip/Archive/RPM/DllExports.cpp +++ b/7zip/Archive/RPM/DllExports.cpp @@ -2,8 +2,7 @@ #include "StdAfx.h" -#include <initguid.h> - +#include "Common/MyInitGuid.h" #include "Common/ComTry.h" #include "Windows/PropVariant.h" #include "../../ICoder.h" diff --git a/7zip/Archive/RPM/Rpm.dsp b/7zip/Archive/RPM/Rpm.dsp index b10596ee..99f6b0b4 100755 --- a/7zip/Archive/RPM/Rpm.dsp +++ b/7zip/Archive/RPM/Rpm.dsp @@ -105,6 +105,10 @@ SOURCE=.\Rpm.def # End Source File # Begin Source File +SOURCE=.\Rpm.ico +# End Source File +# Begin Source File + SOURCE=.\StdAfx.cpp # ADD CPP /Yc"StdAfx.h" # End Source File @@ -154,19 +158,23 @@ SOURCE=..\..\Compress\Copy\CopyCoder.h # PROP Default_Filter "" # Begin Source File -SOURCE=..\..\..\Common\NewHandler.cpp +SOURCE=..\..\..\Common\Alloc.cpp # End Source File # Begin Source File -SOURCE=..\..\..\Common\NewHandler.h +SOURCE=..\..\..\Common\Alloc.h # End Source File -# End Group # Begin Source File -SOURCE=.\Rpm.ico +SOURCE=..\..\..\Common\NewHandler.cpp # End Source File # Begin Source File +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# End Group +# Begin Source File + SOURCE=.\RpmHandler.cpp # End Source File # Begin Source File diff --git a/7zip/Archive/RPM/RpmHandler.cpp b/7zip/Archive/RPM/RpmHandler.cpp index 0a339196..78789081 100755 --- a/7zip/Archive/RPM/RpmHandler.cpp +++ b/7zip/Archive/RPM/RpmHandler.cpp @@ -16,7 +16,6 @@ #include "../../Common/StreamObjects.h" #include "../../Common/ProgressUtils.h" #include "../../Common/LimitedStreams.h" -// #include "Interface/EnumStatProp.h" #include "../../Compress/Copy/CopyCoder.h" #include "../Common/ItemNameUtils.h" @@ -29,7 +28,7 @@ namespace NRpm { STATPROPSTG kProperties[] = { // { NULL, kpidPath, VT_BSTR}, - { NULL, kpidIsFolder, VT_BOOL}, +// { NULL, kpidIsFolder, VT_BOOL}, { NULL, kpidSize, VT_UI8}, { NULL, kpidPackedSize, VT_UI8} }; @@ -40,13 +39,13 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) return S_OK; } -STDMETHODIMP CHandler::GetNumberOfProperties(UINT32 *numProperties) +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) { *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); return S_OK; } -STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index, +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) { if(index >= sizeof(kProperties) / sizeof(kProperties[0])) @@ -58,20 +57,20 @@ STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index, return S_OK; } -STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UINT32 *numProperties) +STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) { *numProperties = 0; return S_OK; } -STDMETHODIMP CHandler::GetArchivePropertyInfo(UINT32 index, +STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) { return E_INVALIDARG; } STDMETHODIMP CHandler::Open(IInStream *inStream, - const UINT64 *maxCheckStartPosition, + const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) { COM_TRY_BEGIN @@ -81,7 +80,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, return S_FALSE; RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_Pos)); m_InStream = inStream; - UINT64 endPosition; + UInt64 endPosition; RINOK(inStream->Seek(0, STREAM_SEEK_END, &endPosition)); m_Size = endPosition - m_Pos; return S_OK; @@ -99,13 +98,13 @@ STDMETHODIMP CHandler::Close() return S_OK; } -STDMETHODIMP CHandler::GetNumberOfItems(UINT32 *numItems) +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) { *numItems = 1; return S_OK; } -STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value) +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant propVariant; @@ -130,11 +129,11 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *val COM_TRY_END } -STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, - INT32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - bool allFilesMode = (numItems == UINT32(-1)); + bool allFilesMode = (numItems == UInt32(-1)); if (allFilesMode) numItems = 1; if(numItems == 0) @@ -146,14 +145,14 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, bool testMode = (_aTestMode != 0); - UINT64 currentTotalSize = 0; + UInt64 currentTotalSize = 0; RINOK(extractCallback->SetTotal(m_Size)); RINOK(extractCallback->SetCompleted(¤tTotalSize)); CMyComPtr<ISequentialOutStream> realOutStream; - INT32 askMode; + Int32 askMode; askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract; - INT32 index = 0; + Int32 index = 0; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); diff --git a/7zip/Archive/RPM/RpmHandler.h b/7zip/Archive/RPM/RpmHandler.h index 214d258d..484c6c54 100755 --- a/7zip/Archive/RPM/RpmHandler.h +++ b/7zip/Archive/RPM/RpmHandler.h @@ -1,7 +1,5 @@ // RPM/Handler.h -// #pragma once - #ifndef __RPM_HANDLER_H #define __RPM_HANDLER_H @@ -19,29 +17,28 @@ public: MY_UNKNOWN_IMP STDMETHOD(Open)(IInStream *stream, - const UINT64 *maxCheckStartPosition, + const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback); STDMETHOD(Close)(); - STDMETHOD(GetNumberOfItems)(UINT32 *numItems); - STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(Extract)(const UINT32* indices, UINT32 numItems, - INT32 testMode, IArchiveExtractCallback *extractCallback); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback); STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); - STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties); - STDMETHOD(GetPropertyInfo)(UINT32 index, + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType); - STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties); - STDMETHOD(GetArchivePropertyInfo)(UINT32 index, + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType); - private: CMyComPtr<IInStream> m_InStream; - UINT64 m_Pos; - UINT64 m_Size; + UInt64 m_Pos; + UInt64 m_Size; }; }} diff --git a/7zip/Archive/RPM/RpmHeader.h b/7zip/Archive/RPM/RpmHeader.h index db68edd9..d76963bd 100755 --- a/7zip/Archive/RPM/RpmHeader.h +++ b/7zip/Archive/RPM/RpmHeader.h @@ -1,7 +1,5 @@ // Archive/RpmHeader.h -// #pragma once - #ifndef __ARCHIVE_RPM_HEADER_H #define __ARCHIVE_RPM_HEADER_H @@ -10,9 +8,6 @@ namespace NArchive { namespace NRpm { -#pragma pack(push, PragmaRPMHeaders) -#pragma pack(push, 1) - /* Reference: lib/signature.h of rpm package */ #define RPMSIG_NONE 0 /* Do not change! */ /* The following types are no longer generated */ @@ -22,68 +17,47 @@ namespace NRpm { #define RPMSIG_HEADERSIG 5 /* New Header style signature */ +const UInt32 kLeadSize = 96; struct CLead { unsigned char Magic[4]; - unsigned char Major; /* not supported ver1, only support 2,3 and lator */ + unsigned char Major; // not supported ver1, only support 2,3 and lator unsigned char Minor; - short Type; - short ArchNum; + UInt16 Type; + UInt16 ArchNum; char Name[66]; - short OSNum; - short SignatureType; - char Reserved[16]; /* pad to 96 bytes -- 8 byte aligned */ + UInt16 OSNum; + UInt16 SignatureType; + char Reserved[16]; // pad to 96 bytes -- 8 byte aligned bool MagicCheck() const { return Magic[0] == 0xed && Magic[1] == 0xab && Magic[2] == 0xee && Magic[3] == 0xdb; }; - static short my_htons(short s) - { - const unsigned char *p = (const unsigned char*)&s; - return (short(p[0]) << 8) + (p[1]); } - ; - void hton() - { - Type = my_htons(Type); - ArchNum = my_htons(ArchNum); - OSNum = my_htons(OSNum); - SignatureType = my_htons(SignatureType); - }; }; - +const UInt32 kEntryInfoSize = 16; +/* struct CEntryInfo { int Tag; int Type; - int Offset; /* Offset from beginning of data segment, only defined on disk */ + int Offset; // Offset from beginning of data segment, only defined on disk int Count; }; +*/ -/* case: SignatureType == RPMSIG_HEADERSIG */ +// case: SignatureType == RPMSIG_HEADERSIG +const UInt32 kCSigHeaderSigSize = 16; struct CSigHeaderSig { unsigned char Magic[4]; - int Reserved; - int IndexLen; /* count of index entries */ - int DataLen; /* number of bytes */ - int MagicCheck() + UInt32 Reserved; + UInt32 IndexLen; // count of index entries + UInt32 DataLen; // number of bytes + bool MagicCheck() { return Magic[0] == 0x8e && Magic[1] == 0xad && Magic[2] == 0xe8 && Magic[3] == 0x01; }; - int GetLostHeaderLen() - { return IndexLen * sizeof(CEntryInfo) + DataLen; }; - long my_htonl(long s) - { - unsigned char *p = (unsigned char*)&s; - return (p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3]; - }; - void hton() - { - IndexLen = my_htonl(IndexLen); - DataLen = my_htonl(DataLen); - }; + UInt32 GetLostHeaderLen() + { return IndexLen * kEntryInfoSize + DataLen; }; }; -#pragma pack(pop) -#pragma pack(pop, PragmaRPMHeaders) - }} #endif diff --git a/7zip/Archive/RPM/RpmIn.cpp b/7zip/Archive/RPM/RpmIn.cpp index c26605ec..9b48a0ae 100755 --- a/7zip/Archive/RPM/RpmIn.cpp +++ b/7zip/Archive/RPM/RpmIn.cpp @@ -11,18 +11,65 @@ namespace NArchive { namespace NRpm { - + +static UInt16 GetUInt16(const char *data) +{ + return (Byte)data[1] | (((UInt16)(Byte)data[0]) << 8); +} + +static UInt32 GetUInt32(const char *data) +{ + return + ((UInt32)(Byte)data[3]) | + (((UInt32)(Byte)data[2]) << 8) | + (((UInt32)(Byte)data[1]) << 16) | + (((UInt32)(Byte)data[0]) << 24); +} + +static HRESULT RedSigHeaderSig(IInStream *inStream, CSigHeaderSig &h) +{ + char dat[kCSigHeaderSigSize]; + char *cur = dat; + UInt32 processedSize; + RINOK(inStream->Read(dat, kCSigHeaderSigSize, &processedSize)); + if (kCSigHeaderSigSize != processedSize) + return S_FALSE; + memmove(h.Magic, cur, 4); + cur += 4; + cur += 4; + h.IndexLen = GetUInt32(cur); + cur += 4; + h.DataLen = GetUInt32(cur); + return S_OK; +} + HRESULT OpenArchive(IInStream *inStream) { - UINT64 pos; + UInt64 pos; + char leadData[kLeadSize]; + char *cur = leadData; CLead lead; - UINT32 processedSize; - RINOK(inStream->Read(&lead, sizeof(lead), &processedSize)); - if (sizeof(lead) != processedSize) + UInt32 processedSize; + RINOK(inStream->Read(leadData, kLeadSize, &processedSize)); + if (kLeadSize != processedSize) return S_FALSE; + memmove(lead.Magic, cur, 4); + cur += 4; + lead.Major = *cur++; + lead.Minor = *cur++; + lead.Type = GetUInt16(cur); + cur += 2; + lead.ArchNum = GetUInt16(cur); + cur += 2; + memmove(lead.Name, cur, sizeof(lead.Name)); + cur += sizeof(lead.Name); + lead.OSNum = GetUInt16(cur); + cur += 2; + lead.SignatureType = GetUInt16(cur); + cur += 2; + if (!lead.MagicCheck() || lead.Major < 3) return S_FALSE; - lead.hton(); CSigHeaderSig sigHeader, header; if(lead.SignatureType == RPMSIG_NONE) @@ -31,18 +78,15 @@ HRESULT OpenArchive(IInStream *inStream) } else if(lead.SignatureType == RPMSIG_PGP262_1024) { - UINT64 pos; + UInt64 pos; RINOK(inStream->Seek(256, STREAM_SEEK_CUR, &pos)); } else if(lead.SignatureType == RPMSIG_HEADERSIG) { - RINOK(inStream->Read(&sigHeader, sizeof(sigHeader), &processedSize)); - if (sizeof(sigHeader) != processedSize) - return S_FALSE; + RINOK(RedSigHeaderSig(inStream, sigHeader)); if(!sigHeader.MagicCheck()) return S_FALSE; - sigHeader.hton(); - int len = sigHeader.GetLostHeaderLen(); + UInt32 len = sigHeader.GetLostHeaderLen(); RINOK(inStream->Seek(len, STREAM_SEEK_CUR, &pos)); if((pos % 8) != 0) { @@ -53,12 +97,9 @@ HRESULT OpenArchive(IInStream *inStream) else return S_FALSE; - RINOK(inStream->Read(&header, sizeof(header), &processedSize)); - if (sizeof(header) != processedSize) - return S_FALSE; + RINOK(RedSigHeaderSig(inStream, header)); if(!header.MagicCheck()) return S_FALSE; - header.hton(); int headerLen = header.GetLostHeaderLen(); if(headerLen == -1) return S_FALSE; @@ -66,5 +107,4 @@ HRESULT OpenArchive(IInStream *inStream) return S_OK; } - }} diff --git a/7zip/Archive/RPM/RpmIn.h b/7zip/Archive/RPM/RpmIn.h index ff6ca1c6..ec798cb8 100755 --- a/7zip/Archive/RPM/RpmIn.h +++ b/7zip/Archive/RPM/RpmIn.h @@ -1,7 +1,5 @@ // Archive/RpmIn.h -// #pragma once - #ifndef __ARCHIVE_RPM_IN_H #define __ARCHIVE_RPM_IN_H diff --git a/7zip/Archive/RPM/StdAfx.cpp b/7zip/Archive/RPM/StdAfx.cpp index 2550270c..d0feea85 100755 --- a/7zip/Archive/RPM/StdAfx.cpp +++ b/7zip/Archive/RPM/StdAfx.cpp @@ -1,3 +1,3 @@ // StdAfx.cpp -#include "stdafx.h" +#include "StdAfx.h" diff --git a/7zip/Archive/RPM/StdAfx.h b/7zip/Archive/RPM/StdAfx.h index a32fbed6..e7fb6986 100755 --- a/7zip/Archive/RPM/StdAfx.h +++ b/7zip/Archive/RPM/StdAfx.h @@ -1,8 +1,8 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> +#include "../../../Common/MyWindows.h" -#endif +#endif diff --git a/7zip/Archive/RPM/resource.rc b/7zip/Archive/RPM/resource.rc index ae7fff20..ae3e7177 100755 --- a/7zip/Archive/RPM/resource.rc +++ b/7zip/Archive/RPM/resource.rc @@ -75,8 +75,8 @@ IDI_ICON1 ICON DISCARDABLE "Rpm.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,9,2,0 - PRODUCTVERSION 3,9,2,0 + FILEVERSION 4,7,0,0 + PRODUCTVERSION 4,7,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -94,14 +94,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Igor Pavlov\0" VALUE "FileDescription", "RPM Plugin for 7-Zip\0" - VALUE "FileVersion", "3, 9, 2, 0\0" + VALUE "FileVersion", "4, 7, 0, 0\0" VALUE "InternalName", "rpm\0" - VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2004 Igor Pavlov\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "rpm.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "7-Zip\0" - VALUE "ProductVersion", "3, 9, 2, 0\0" + VALUE "ProductVersion", "4, 7, 0, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/7zip/Archive/Rar/DllExports.cpp b/7zip/Archive/Rar/DllExports.cpp index 6c1830a7..7e24047c 100755 --- a/7zip/Archive/Rar/DllExports.cpp +++ b/7zip/Archive/Rar/DllExports.cpp @@ -2,11 +2,9 @@ #include "StdAfx.h" -#include <initguid.h> - +#include "Common/MyInitGuid.h" #include "Common/ComTry.h" #include "Windows/PropVariant.h" - #include "../../ICoder.h" #include "../../IPassword.h" #include "../Common/CodecsPath.h" @@ -19,46 +17,6 @@ DEFINE_GUID(CLSID_CCrypto_AES128_Decoder, HINSTANCE g_hInstance; -/* -static bool GetBaseFolderPrefix(TCHAR *path) -{ - TCHAR fullPath[MAX_PATH + 1]; - if (::GetModuleFileName(g_hInstance, fullPath, MAX_PATH) == 0) - return false; - // fullPath = "7-zip\Format\Rar.dll" - LPTSTR fileNamePointer; - TCHAR p[MAX_PATH + 1]; - DWORD needLength = ::GetFullPathName(fullPath, MAX_PATH + 1, - p, &fileNamePointer); - if (needLength == 0 || needLength >= MAX_PATH) - return false; - *fileNamePointer = 0; - // p = "7-zip\Format\" - int len = lstrlen(p); - if (len == 0) - return false; - if (p[len - 1] != '\\') - return false; - p[len - 1] = 0; - // p = "7-zip\Format" - needLength = ::GetFullPathName(p, MAX_PATH + 1, - path, &fileNamePointer); - if (needLength == 0 || needLength >= MAX_PATH) - return false; - // fileNamePointer -> "7-zip\"+ - *fileNamePointer = 0; - return true; -} - -bool GetCompressFolderPrefix(TCHAR *path) -{ - if (!GetBaseFolderPrefix(path)) - return false; - lstrcat(path, TEXT("Codecs\\")); - return true; -} -*/ - void GetCryptoFolderPrefix(TCHAR *path) { CSysString s = GetCodecsFolderPrefix(); @@ -154,6 +112,14 @@ STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) case NArchive::kKeepName: propVariant = false; break; + case NArchive::kStartSignature: + { + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)NArchive::NRar::NHeader::kMarker, + NArchive::NRar::NHeader::kMarkerSize)) != 0) + value->vt = VT_BSTR; + return S_OK; + } } propVariant.Detach(value); return S_OK; diff --git a/7zip/Archive/Rar/Rar.dsp b/7zip/Archive/Rar/Rar.dsp index 07dfd729..99cbd0ce 100755 --- a/7zip/Archive/Rar/Rar.dsp +++ b/7zip/Archive/Rar/Rar.dsp @@ -122,7 +122,15 @@ SOURCE=.\StdAfx.h # PROP Default_Filter "" # Begin Source File -SOURCE=..\..\..\..\SDK\Common\Buffer.h +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Buffer.h # End Source File # Begin Source File @@ -134,7 +142,15 @@ SOURCE=..\..\..\Common\CRC.h # End Source File # Begin Source File -SOURCE=..\..\..\..\SDK\Common\DynamicBuffer.h +SOURCE=..\..\..\Common\DynamicBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h # End Source File # Begin Source File @@ -190,27 +206,11 @@ SOURCE=..\Common\CoderLoader.h # End Source File # Begin Source File -SOURCE=..\Common\CoderMixer.cpp -# End Source File -# Begin Source File - -SOURCE=..\Common\CoderMixer.h -# End Source File -# Begin Source File - -SOURCE=..\Common\CoderMixer2.cpp +SOURCE=..\Common\FilterCoder.cpp # End Source File # Begin Source File -SOURCE=..\Common\CoderMixer2.h -# End Source File -# Begin Source File - -SOURCE=..\Common\CrossThreadProgress.cpp -# End Source File -# Begin Source File - -SOURCE=..\Common\CrossThreadProgress.h +SOURCE=..\Common\FilterCoder.h # End Source File # Begin Source File @@ -398,14 +398,6 @@ SOURCE=..\..\Common\ProgressUtils.h # End Source File # Begin Source File -SOURCE=..\..\Common\StreamBinder.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\Common\StreamBinder.h -# End Source File -# Begin Source File - SOURCE=..\..\Common\StreamObjects.cpp # End Source File # Begin Source File @@ -418,6 +410,14 @@ SOURCE=..\..\Common\StreamObjects.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\7z\7zMethodID.cpp +# End Source File +# Begin Source File + +SOURCE=..\7z\7zMethodID.h +# End Source File +# Begin Source File + SOURCE=..\7z\7zMethods.cpp # End Source File # Begin Source File diff --git a/7zip/Archive/Rar/RarHandler.cpp b/7zip/Archive/Rar/RarHandler.cpp index fb91479c..d38b65a4 100755 --- a/7zip/Archive/Rar/RarHandler.cpp +++ b/7zip/Archive/Rar/RarHandler.cpp @@ -6,27 +6,25 @@ #include "Common/StringConvert.h" #include "Common/ComTry.h" - -#include "../../Common/StreamObjects.h" -// #include "Interface/EnumStatProp.h" -#include "../../Common//ProgressUtils.h" -#include "../../IPassword.h" +#include "Common/IntToString.h" #include "Windows/PropVariant.h" #include "Windows/Time.h" +#include "../../IPassword.h" + +#include "../../Common//ProgressUtils.h" #include "../../Compress/Copy/CopyCoder.h" +#include "../../Crypto/Rar20/Rar20Cipher.h" +#include "../../Crypto/RarAES/RarAES.h" + #include "../Common/OutStreamWithCRC.h" -#include "../Common/CoderMixer.h" #include "../Common/CoderLoader.h" #include "../Common/CodecsPath.h" -#include "../7z/7zMethods.h" +#include "../Common/FilterCoder.h" -// #include "../../../Compress/Interface/CompressInterface.h" -// #include "../../../Crypto/Cipher/Common/CipherInterface.h" -#include "../../Crypto/Rar20/Rar20Cipher.h" -#include "../../Crypto/RarAES/RarAES.h" +#include "../7z/7zMethods.h" using namespace NWindows; using namespace NTime; @@ -96,10 +94,10 @@ STATPROPSTG kArchiveProperties[] = { NULL, kpidCommented, VT_BOOL}, }; -UINT64 CHandler::GetPackSize(int refIndex) const +UInt64 CHandler::GetPackSize(int refIndex) const { const CRefItem &refItem = _refItems[refIndex]; - UINT64 totalPackSize = 0; + UInt64 totalPackSize = 0; for (int i = 0; i < refItem.NumItems; i++) totalPackSize += _items[refItem.ItemIndex + i].PackSize; return totalPackSize; @@ -123,13 +121,13 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) COM_TRY_END } -STDMETHODIMP CHandler::GetNumberOfProperties(UINT32 *numProperties) +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) { *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); return S_OK; } -STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index, +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) { if(index >= sizeof(kProperties) / sizeof(kProperties[0])) @@ -141,13 +139,13 @@ STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index, return S_OK; } -STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UINT32 *numProperties) +STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) { *numProperties = sizeof(kArchiveProperties) / sizeof(kArchiveProperties[0]); return S_OK; } -STDMETHODIMP CHandler::GetArchivePropertyInfo(UINT32 index, +STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) { if(index >= sizeof(kArchiveProperties) / sizeof(kArchiveProperties[0])) @@ -159,7 +157,7 @@ STDMETHODIMP CHandler::GetArchivePropertyInfo(UINT32 index, return S_OK; } -STDMETHODIMP CHandler::GetNumberOfItems(UINT32 *numItems) +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) { *numItems = _refItems.Size(); return S_OK; @@ -169,17 +167,17 @@ static bool RarTimeToFileTime(const CRarTime &rarTime, FILETIME &result) { if (!DosTimeToFileTime(rarTime.DosTime, result)) return false; - UINT64 &value = *(UINT64 *)&result; - value += (int)rarTime.LowSecond * 10000000; - UINT64 subTime = ((UINT64)rarTime.SubTime[2] << 16) + - ((UINT64)rarTime.SubTime[1] << 8) + - ((UINT64)rarTime.SubTime[0]); - // value += (subTime * 10000000) >> 24; - value += subTime; + UInt64 value = (((UInt64)result.dwHighDateTime) << 32) + result.dwLowDateTime; + value += (UInt64)rarTime.LowSecond * 10000000; + value += ((UInt64)rarTime.SubTime[2] << 16) + + ((UInt64)rarTime.SubTime[1] << 8) + + ((UInt64)rarTime.SubTime[0]); + result.dwLowDateTime = (DWORD)value; + result.dwHighDateTime = DWORD(value >> 32); return true; } -STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value) +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant propVariant; @@ -270,7 +268,7 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va /* case kpidDictionarySize: if (!item.IsDirectory()) - propVariant = UINT32(0x10000 << item.GetDictSize()); + propVariant = UInt32(0x10000 << item.GetDictSize()); break; */ case kpidCRC: @@ -289,23 +287,23 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va case kpidMethod: { UString method; - if (item.Method >= BYTE('0') && item.Method <= BYTE('5')) + if (item.Method >= Byte('0') && item.Method <= Byte('5')) { method = L"m"; wchar_t temp[32]; - _itow (item.Method - BYTE('0'), temp, 10); + ConvertUInt64ToString(item.Method - Byte('0'), temp); method += temp; if (!item.IsDirectory()) { method += L":"; - _itow (16 + item.GetDictSize(), temp, 10); + ConvertUInt64ToString(16 + item.GetDictSize(), temp); method += temp; } } else { wchar_t temp[32]; - _itow (item.Method, temp, 10); + ConvertUInt64ToString(item.Method, temp); method += temp; } propVariant = method; @@ -407,7 +405,7 @@ public: }; STDMETHODIMP CHandler::Open(IInStream *stream, - const UINT64 *maxCheckStartPosition, + const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) { COM_TRY_BEGIN @@ -415,6 +413,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream, try { CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback; + CMyComPtr<ICryptoGetTextPassword> getTextPassword; CMyComPtr<IArchiveOpenCallback> openArchiveCallbackWrap = openArchiveCallback; CVolumeName seqName; @@ -423,8 +422,9 @@ STDMETHODIMP CHandler::Open(IInStream *stream, { openArchiveCallbackWrap.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback); RINOK(openArchiveCallback->SetTotal(NULL, NULL)); - UINT64 numFiles = _items.Size(); + UInt64 numFiles = _items.Size(); RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); + openArchiveCallbackWrap.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword); } while(true) @@ -467,14 +467,15 @@ STDMETHODIMP CHandler::Open(IInStream *stream, return S_FALSE; if (_archives.IsEmpty()) - { archive.GetArchiveInfo(_archiveInfo); - } - - + CItemEx item; - while(archive.GetNextItem(item)) + while(true) { + HRESULT result = archive.GetNextItem(item, getTextPassword); + if (result == S_FALSE) + break; + RINOK(result); if (item.IgnoreItem()) continue; @@ -499,7 +500,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream, _items.Add(item); if (openArchiveCallback != NULL) { - UINT64 numFiles = _items.Size(); + UInt64 numFiles = _items.Size(); RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); } } @@ -526,23 +527,23 @@ STDMETHODIMP CHandler::Close() struct CMethodItem { - BYTE RarUnPackVersion; + Byte RarUnPackVersion; CMyComPtr<ICompressCoder> Coder; }; -STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, - INT32 _aTestMode, IArchiveExtractCallback *_anExtractCallback) +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *_anExtractCallback) { COM_TRY_BEGIN CMyComPtr<ICryptoGetTextPassword> getTextPassword; bool testMode = (_aTestMode != 0); CMyComPtr<IArchiveExtractCallback> extractCallback = _anExtractCallback; - UINT64 censoredTotalUnPacked = 0, + UInt64 censoredTotalUnPacked = 0, // censoredTotalPacked = 0, importantTotalUnPacked = 0; // importantTotalPacked = 0; - bool allFilesMode = (numItems == UINT32(-1)); + bool allFilesMode = (numItems == UInt32(-1)); if (allFilesMode) numItems = _refItems.Size(); if(numItems == 0) @@ -551,14 +552,15 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, CRecordVector<int> importantIndexes; CRecordVector<bool> extractStatuses; - for(UINT32 t = 0; t < numItems; t++) + for(UInt32 t = 0; t < numItems; t++) { int index = allFilesMode ? t : indices[t]; const CRefItem &refItem = _refItems[index]; const CItemEx &item = _items[refItem.ItemIndex]; censoredTotalUnPacked += item.UnPackSize; // censoredTotalPacked += item.PackSize; - for(int j = lastIndex; j <= index; j++) + int j; + for(j = lastIndex; j <= index; j++) // if(!_items[_refItems[j].ItemIndex].IsSolid()) if(!IsSolid(j)) lastIndex = j; @@ -578,9 +580,9 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, } extractCallback->SetTotal(importantTotalUnPacked); - UINT64 currentImportantTotalUnPacked = 0; - UINT64 currentImportantTotalPacked = 0; - UINT64 currentUnPackSize, currentPackSize; + UInt64 currentImportantTotalUnPacked = 0; + UInt64 currentImportantTotalPacked = 0; + UInt64 currentUnPackSize, currentPackSize; /* CSysString path = GetCodecsFolderPrefix() + TEXT("Rar29.dll"); @@ -603,15 +605,17 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, NCompress::CCopyCoder *copyCoderSpec = NULL; CMyComPtr<ICompressCoder> copyCoder; - CCoderMixer *mixerCoderSpec; - CMyComPtr<ICompressCoder> mixerCoder; - - bool mixerCoderStoreMethod; + // CCoderMixer *mixerCoderSpec; + // CMyComPtr<ICompressCoder> mixerCoder; + // bool mixerCoderStoreMethod; + // int mixerCryptoVersion; - int mixerCryptoVersion; + CFilterCoder *filterStreamSpec = new CFilterCoder; + CMyComPtr<ISequentialInStream> filterStream = filterStreamSpec; - CMyComPtr<ICompressCoder> rar20CryptoDecoder; - CMyComPtr<ICompressCoder> rar29CryptoDecoder; + NCrypto::NRar20::CDecoder *rar20CryptoDecoderSpec; + CMyComPtr<ICompressFilter> rar20CryptoDecoder; + CMyComPtr<ICompressFilter> rar29CryptoDecoder; CFolderInStream *folderInStreamSpec = NULL; CMyComPtr<ISequentialInStream> folderInStream; @@ -624,14 +628,14 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, ¤tImportantTotalUnPacked)); CMyComPtr<ISequentialOutStream> realOutStream; - INT32 askMode; + Int32 askMode; if(extractStatuses[i]) askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract; else askMode = NArchive::NExtract::NAskMode::kSkip; - UINT32 index = importantIndexes[i]; + UInt32 index = importantIndexes[i]; const CRefItem &refItem = _refItems[index]; const CItemEx &item = _items[refItem.ItemIndex]; @@ -674,8 +678,8 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, outStreamSpec->Init(realOutStream); realOutStream.Release(); - UINT64 packedPos = currentImportantTotalPacked; - UINT64 unpackedPos = currentImportantTotalUnPacked; + UInt64 packedPos = currentImportantTotalPacked; + UInt64 unpackedPos = currentImportantTotalUnPacked; /* for (int partIndex = 0; partIndex < 1; partIndex++) @@ -710,11 +714,12 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, &packedPos, &unpackedPos); - UINT64 packSize = currentPackSize; + UInt64 packSize = currentPackSize; // packedPos += item.PackSize; // unpackedPos += 0; + CMyComPtr<ISequentialInStream> inStream; if (item.IsEncrypted()) { CMyComPtr<ICryptoSetPassword> cryptoSetPassword; @@ -722,28 +727,24 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, { if (!rar29CryptoDecoder) { - rar29CryptoDecoder = new NCrypto::NRar29::CDecoder(); + rar29CryptoDecoder = new NCrypto::NRar29::CDecoder; // RINOK(rar29CryptoDecoder.CoCreateInstance(CLSID_CCryptoRar29Decoder)); } - CMyComPtr<ICompressSetDecoderProperties> cryptoProperties; - RINOK(rar29CryptoDecoder.QueryInterface(IID_ICompressSetDecoderProperties, + CMyComPtr<ICompressSetDecoderProperties2> cryptoProperties; + RINOK(rar29CryptoDecoder.QueryInterface(IID_ICompressSetDecoderProperties2, &cryptoProperties)); - CSequentialInStreamImp *inStreamSpec = new CSequentialInStreamImp; - CMyComPtr<ISequentialInStream> inStreamProperties(inStreamSpec); - inStreamSpec->Init(item.Salt, item.HasSalt() ? sizeof(item.Salt) : 0); - RINOK(cryptoProperties->SetDecoderProperties(inStreamProperties)); - RINOK(rar29CryptoDecoder.QueryInterface(IID_ICryptoSetPassword, - &cryptoSetPassword)); + RINOK(cryptoProperties->SetDecoderProperties2(item.Salt, item.HasSalt() ? sizeof(item.Salt) : 0)); + filterStreamSpec->Filter = rar29CryptoDecoder; } else if (item.UnPackVersion >= 20) { if (!rar20CryptoDecoder) { - rar20CryptoDecoder = new NCrypto::NRar20::CDecoder(); + rar20CryptoDecoderSpec = new NCrypto::NRar20::CDecoder; + rar20CryptoDecoder = rar20CryptoDecoderSpec; // RINOK(rar20CryptoDecoder.CoCreateInstance(CLSID_CCryptoRar20Decoder)); } - RINOK(rar20CryptoDecoder.QueryInterface(IID_ICryptoSetPassword, - &cryptoSetPassword)); + filterStreamSpec->Filter = rar20CryptoDecoder; } else { @@ -751,6 +752,8 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); continue; } + RINOK(filterStreamSpec->Filter.QueryInterface(IID_ICryptoSetPassword, + &cryptoSetPassword)); if (!getTextPassword) extractCallback.QueryInterface(IID_ICryptoGetTextPassword, @@ -761,23 +764,39 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, RINOK(getTextPassword->CryptoGetTextPassword(&password)); if (item.UnPackVersion >= 29) { + CByteBuffer buffer; + UString unicodePassword(password); + const UInt32 sizeInBytes = unicodePassword.Length() * 2; + buffer.SetCapacity(sizeInBytes); + for (int i = 0; i < unicodePassword.Length(); i++) + { + wchar_t c = unicodePassword[i]; + ((Byte *)buffer)[i * 2] = (Byte)c; + ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8); + } RINOK(cryptoSetPassword->CryptoSetPassword( - (const BYTE *)(const wchar_t *)password, - password.Length() * sizeof(wchar_t))); + (const Byte *)buffer, sizeInBytes)); } else { AString oemPassword = UnicodeStringToMultiByte( (const wchar_t *)password, CP_OEMCP); RINOK(cryptoSetPassword->CryptoSetPassword( - (const BYTE *)(const char *)oemPassword, oemPassword.Length())); + (const Byte *)(const char *)oemPassword, oemPassword.Length())); } } else { RINOK(cryptoSetPassword->CryptoSetPassword(0, 0)); } + filterStreamSpec->SetInStream(folderInStream); + inStream = filterStream; } + else + { + inStream = folderInStream; + } + CMyComPtr<ICompressCoder> commonCoder; switch(item.Method) { case '0': @@ -787,39 +806,7 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, copyCoderSpec = new NCompress::CCopyCoder; copyCoder = copyCoderSpec; } - - if (item.IsEncrypted()) - { - { - if (!mixerCoder || !mixerCoderStoreMethod || - item.UnPackVersion != mixerCryptoVersion) - { - mixerCoder.Release(); - mixerCoderSpec = new CCoderMixer; - mixerCoder = mixerCoderSpec; - if (item.UnPackVersion >= 29) - mixerCoderSpec->AddCoder(rar29CryptoDecoder); - else - mixerCoderSpec->AddCoder(rar20CryptoDecoder); - mixerCoderSpec->AddCoder(copyCoder); - mixerCoderSpec->FinishAddingCoders(); - mixerCoderStoreMethod = true; - mixerCryptoVersion = item.UnPackVersion; - } - mixerCoderSpec->ReInit(); - mixerCoderSpec->SetCoderInfo(0, &packSize, &item.UnPackSize); - mixerCoderSpec->SetCoderInfo(1, &item.UnPackSize, &item.UnPackSize); - mixerCoderSpec->SetProgressCoderIndex(1); - - RINOK(mixerCoder->Code(folderInStream, outStream, - NULL, NULL, compressProgress)); - } - } - else - { - RINOK(copyCoder->Code(folderInStream, outStream, - NULL, NULL, compressProgress)); - } + commonCoder = copyCoder; break; } case '1': @@ -846,7 +833,7 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, mi.RarUnPackVersion = item.UnPackVersion; N7z::CMethodID methodID = { { 0x04, 0x03 } , 3 }; - BYTE myID; + Byte myID; if (item.UnPackVersion < 20) myID = 1; else if (item.UnPackVersion < 29) @@ -867,58 +854,16 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, } CMyComPtr<ICompressCoder> decoder = methodItems[m].Coder; - CMyComPtr<ICompressSetDecoderProperties> compressSetDecoderProperties; - RINOK(decoder.QueryInterface(IID_ICompressSetDecoderProperties, + CMyComPtr<ICompressSetDecoderProperties2> compressSetDecoderProperties; + RINOK(decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &compressSetDecoderProperties)); - BYTE isSolid = ( - // item.IsSolid() - IsSolid(index) - || - item.IsSplitBefore()) - ? 1: 0; - - CSequentialInStreamImp *inStreamSpec = new CSequentialInStreamImp; - CMyComPtr<ISequentialInStream> inStreamProperties(inStreamSpec); - inStreamSpec->Init(&isSolid, 1); - RINOK(compressSetDecoderProperties->SetDecoderProperties(inStreamProperties)); + Byte isSolid = + (IsSolid(index) || item.IsSplitBefore()) ? 1: 0; + + RINOK(compressSetDecoderProperties->SetDecoderProperties2(&isSolid, 1)); - HRESULT result; - if (item.IsEncrypted()) - { - if (!mixerCoder || mixerCoderStoreMethod) - { - mixerCoder.Release(); - mixerCoderSpec = new CCoderMixer; - mixerCoder = mixerCoderSpec; - if (item.UnPackVersion >= 29) - mixerCoderSpec->AddCoder(rar29CryptoDecoder); - else - mixerCoderSpec->AddCoder(rar20CryptoDecoder); - mixerCoderSpec->AddCoder(decoder); - mixerCoderSpec->FinishAddingCoders(); - mixerCoderStoreMethod = false; - } - mixerCoderSpec->ReInit(); - mixerCoderSpec->SetCoderInfo(1, &packSize, - &item.UnPackSize); - mixerCoderSpec->SetProgressCoderIndex(1); - result = mixerCoder->Code(folderInStream, outStream, - NULL, NULL, compressProgress); - } - else - { - result = decoder->Code(folderInStream, outStream, - &packSize, &item.UnPackSize, compressProgress); - } - if (result == S_FALSE) - { - outStream.Release(); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError)); - continue; - } - if (result != S_OK) - return result; + commonCoder = decoder; break; } default: @@ -926,6 +871,18 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); continue; } + HRESULT result = commonCoder->Code(inStream, outStream, + &packSize, &item.UnPackSize, compressProgress); + if (item.IsEncrypted()) + filterStreamSpec->ReleaseInStream(); + if (result == S_FALSE) + { + outStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError)); + continue; + } + if (result != S_OK) + return result; /* if (refItem.NumItems == 1 && @@ -961,11 +918,11 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, } /* -STDMETHODIMP CHandler::ExtractAllItems(INT32 testMode, +STDMETHODIMP CHandler::ExtractAllItems(Int32 testMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - CRecordVector<UINT32> indices; + CRecordVector<UInt32> indices; indices.Reserve(_refItems.Size()); for(int i = 0; i < _refItems.Size(); i++) indices.Add(i); diff --git a/7zip/Archive/Rar/RarHandler.h b/7zip/Archive/Rar/RarHandler.h index e75fcb86..68157904 100755 --- a/7zip/Archive/Rar/RarHandler.h +++ b/7zip/Archive/Rar/RarHandler.h @@ -1,7 +1,5 @@ // Rar/Handler.h -#pragma once - #ifndef __RAR_HANDLER_H #define __RAR_HANDLER_H @@ -20,22 +18,22 @@ public: MY_UNKNOWN_IMP STDMETHOD(Open)(IInStream *aStream, - const UINT64 *aMaxCheckStartPosition, + const UInt64 *aMaxCheckStartPosition, IArchiveOpenCallback *anOpenArchiveCallback); STDMETHOD(Close)(); - STDMETHOD(GetNumberOfItems)(UINT32 *numItems); - STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(Extract)(const UINT32* indices, UINT32 numItems, - INT32 testMode, IArchiveExtractCallback *anExtractCallback); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *anExtractCallback); STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); - STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties); - STDMETHOD(GetPropertyInfo)(UINT32 index, + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType); - STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties); - STDMETHOD(GetArchivePropertyInfo)(UINT32 index, + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType); private: @@ -44,7 +42,7 @@ private: CObjectVector<CInArchive> _archives; NArchive::NRar::CInArchiveInfo _archiveInfo; - UINT64 GetPackSize(int refIndex) const; + UInt64 GetPackSize(int refIndex) const; // NArchive::NRar::CInArchive _archive; bool IsSolid(int refIndex) diff --git a/7zip/Archive/Rar/RarHeader.cpp b/7zip/Archive/Rar/RarHeader.cpp index dd47f886..23f7ebb6 100755 --- a/7zip/Archive/Rar/RarHeader.cpp +++ b/7zip/Archive/Rar/RarHeader.cpp @@ -1,21 +1,14 @@ -// Archive::Rar::Headers.cpp +// Archive/Rar/Headers.cpp #include "StdAfx.h" #include "RarHeader.h" -#include "Common/CRC.h" - -static void UpdateCRCBytesWithoutStartBytes(CCRC &crc, const void *data, - UINT32 size, UINT32 exludeSize) -{ - crc.Update(((const BYTE *)data) + exludeSize, size - exludeSize); -} namespace NArchive{ namespace NRar{ namespace NHeader{ -BYTE kMarker[kMarkerSize] = {0x52 + 1, 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00}; +Byte kMarker[kMarkerSize] = {0x52 + 1, 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00}; class CMarkerInitializer { @@ -23,42 +16,6 @@ public: CMarkerInitializer() { kMarker[0]--; }; }; -static CMarkerInitializer aMarkerInitializer; - -namespace NArchive -{ - UINT16 CBlock::GetRealCRC() const - { - CCRC crc; - UpdateCRCBytesWithoutStartBytes(crc, this, - sizeof(*this), sizeof(CRC)); - return UINT16(crc.GetDigest()); - } -} - -namespace NFile -{ - /* - UINT16 CBlock32::GetRealCRC(const void *aName, UINT32 aNameSize, - bool anExtraDataDefined, BYTE *anExtraData) const - { - CCRC crc; - UpdateCRCBytesWithoutStartBytes(crc, this, - sizeof(*this), sizeof(HeadCRC)); - crc.Update(aName, aNameSize); - if (anExtraDataDefined) - crc.Update(anExtraData, 8); - return UINT16(crc.GetDigest()); - } - UINT16 CBlock64::GetRealCRC(const void *aName, UINT32 aNameSize) const - { - CCRC crc; - UpdateCRCBytesWithoutStartBytes(crc, this, - sizeof(*this), sizeof(HeadCRC)); - crc.Update(aName, aNameSize); - return UINT16(crc.GetDigest()); - } - */ -} +static CMarkerInitializer markerInitializer; }}}
\ No newline at end of file diff --git a/7zip/Archive/Rar/RarHeader.h b/7zip/Archive/Rar/RarHeader.h index 642778ed..f7e6f711 100755 --- a/7zip/Archive/Rar/RarHeader.h +++ b/7zip/Archive/Rar/RarHeader.h @@ -1,21 +1,16 @@ -// Archive::Rar::Header.h - -#pragma once +// Archive/RarHeader.h #ifndef __ARCHIVE_RAR_HEADER_H #define __ARCHIVE_RAR_HEADER_H #include "Common/Types.h" -#pragma pack(push, PragmaRarHeaders) -#pragma pack(push, 1) - namespace NArchive{ namespace NRar{ namespace NHeader{ const int kMarkerSize = 7; -extern BYTE kMarker[kMarkerSize]; +extern Byte kMarker[kMarkerSize]; const int kArchiveSolid = 0x1; @@ -38,26 +33,27 @@ namespace NBlockType namespace NArchive { - const UINT16 kVolume = 1; - const UINT16 kComment = 2; - const UINT16 kLock = 4; - const UINT16 kSolid = 8; - const UINT16 kNewVolName = 0x10; // ('volname.partN.rar') - const UINT16 kAuthenticity = 0x20; - const UINT16 kRecovery = 0x40; - const UINT16 kBlockEncryption = 0x80; - const UINT16 kFirstVolume = 0x100; // (set only by RAR 3.0 and later) + const UInt16 kVolume = 1; + const UInt16 kComment = 2; + const UInt16 kLock = 4; + const UInt16 kSolid = 8; + const UInt16 kNewVolName = 0x10; // ('volname.partN.rar') + const UInt16 kAuthenticity = 0x20; + const UInt16 kRecovery = 0x40; + const UInt16 kBlockEncryption = 0x80; + const UInt16 kFirstVolume = 0x100; // (set only by RAR 3.0 and later) struct CBlock { - UINT16 CRC; - BYTE Type; - UINT16 Flags; - UINT16 Size; - UINT16 Reserved1; - UINT32 Reserved2; - UINT16 GetRealCRC() const; + UInt16 CRC; + Byte Type; + UInt16 Flags; + UInt16 Size; + UInt16 Reserved1; + UInt32 Reserved2; + // UInt16 GetRealCRC() const; }; + const int kArchiveHeaderSize = 13; const int kBlockHeadersAreEncrypted = 0x80; } @@ -85,60 +81,62 @@ namespace NFile const int kLongBlock = 1 << 15; + /* struct CBlock { - // UINT16 HeadCRC; - // BYTE Type; - // UINT16 Flags; - // UINT16 HeadSize; - UINT32 PackSize; - UINT32 UnPackSize; - BYTE HostOS; - UINT32 FileCRC; - UINT32 Time; - BYTE UnPackVersion; - BYTE Method; - UINT16 NameSize; - UINT32 Attributes; + // UInt16 HeadCRC; + // Byte Type; + // UInt16 Flags; + // UInt16 HeadSize; + UInt32 PackSize; + UInt32 UnPackSize; + Byte HostOS; + UInt32 FileCRC; + UInt32 Time; + Byte UnPackVersion; + Byte Method; + UInt16 NameSize; + UInt32 Attributes; }; + */ - /* + /* struct CBlock32 { - UINT16 HeadCRC; - BYTE Type; - UINT16 Flags; - UINT16 HeadSize; - UINT32 PackSize; - UINT32 UnPackSize; - BYTE HostOS; - UINT32 FileCRC; - UINT32 Time; - BYTE UnPackVersion; - BYTE Method; - UINT16 NameSize; - UINT32 Attributes; - UINT16 GetRealCRC(const void *aName, UINT32 aNameSize, - bool anExtraDataDefined = false, BYTE *anExtraData = 0) const; + UInt16 HeadCRC; + Byte Type; + UInt16 Flags; + UInt16 HeadSize; + UInt32 PackSize; + UInt32 UnPackSize; + Byte HostOS; + UInt32 FileCRC; + UInt32 Time; + Byte UnPackVersion; + Byte Method; + UInt16 NameSize; + UInt32 Attributes; + UInt16 GetRealCRC(const void *aName, UInt32 aNameSize, + bool anExtraDataDefined = false, Byte *anExtraData = 0) const; }; struct CBlock64 { - UINT16 HeadCRC; - BYTE Type; - UINT16 Flags; - UINT16 HeadSize; - UINT32 PackSizeLow; - UINT32 UnPackSizeLow; - BYTE HostOS; - UINT32 FileCRC; - UINT32 Time; - BYTE UnPackVersion; - BYTE Method; - UINT16 NameSize; - UINT32 Attributes; - UINT32 PackSizeHigh; - UINT32 UnPackSizeHigh; - UINT16 GetRealCRC(const void *aName, UINT32 aNameSize) const; + UInt16 HeadCRC; + Byte Type; + UInt16 Flags; + UInt16 HeadSize; + UInt32 PackSizeLow; + UInt32 UnPackSizeLow; + Byte HostOS; + UInt32 FileCRC; + UInt32 Time; + Byte UnPackVersion; + Byte Method; + UInt16 NameSize; + UInt32 Attributes; + UInt32 PackSizeHigh; + UInt32 UnPackSizeHigh; + UInt16 GetRealCRC(const void *aName, UInt32 aNameSize) const; }; */ @@ -158,57 +156,56 @@ namespace NFile namespace NBlock { - const UINT16 kLongBlock = 1 << 15; + const UInt16 kLongBlock = 1 << 15; struct CBlock { - UINT16 CRC; - BYTE Type; - UINT16 Flags; - UINT16 HeadSize; - // UINT32 DataSize; + UInt16 CRC; + Byte Type; + UInt16 Flags; + UInt16 HeadSize; + // UInt32 DataSize; }; } +/* struct CSubBlock { - UINT16 HeadCRC; - BYTE HeadType; - UINT16 Flags; - UINT16 HeadSize; - UINT32 DataSize; - UINT16 SubType; - BYTE Level; // Reserved : Must be 0 + UInt16 HeadCRC; + Byte HeadType; + UInt16 Flags; + UInt16 HeadSize; + UInt32 DataSize; + UInt16 SubType; + Byte Level; // Reserved : Must be 0 }; struct CCommentBlock { - UINT16 HeadCRC; - BYTE HeadType; - UINT16 Flags; - UINT16 HeadSize; - UINT16 UnpSize; - BYTE UnpVer; - BYTE Method; - UINT16 CommCRC; + UInt16 HeadCRC; + Byte HeadType; + UInt16 Flags; + UInt16 HeadSize; + UInt16 UnpSize; + Byte UnpVer; + Byte Method; + UInt16 CommCRC; }; struct CProtectHeader { - UINT16 HeadCRC; - BYTE HeadType; - UINT16 Flags; - UINT16 HeadSize; - UINT32 DataSize; - BYTE Version; - UINT16 RecSectors; - UINT32 TotalBlocks; - BYTE Mark[8]; + UInt16 HeadCRC; + Byte HeadType; + UInt16 Flags; + UInt16 HeadSize; + UInt32 DataSize; + Byte Version; + UInt16 RecSectors; + UInt32 TotalBlocks; + Byte Mark[8]; }; +*/ }}} -#pragma pack(pop) -#pragma pack(pop, PragmaRarHeaders) - #endif diff --git a/7zip/Archive/Rar/RarIn.cpp b/7zip/Archive/Rar/RarIn.cpp index f21eb588..f6a4891f 100755 --- a/7zip/Archive/Rar/RarIn.cpp +++ b/7zip/Archive/Rar/RarIn.cpp @@ -19,8 +19,9 @@ void CInArchive::ThrowExceptionWithCode( throw CInArchiveException(cause); } -bool CInArchive::Open(IInStream *inStream, const UINT64 *searchHeaderSizeLimit) +bool CInArchive::Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit) { + m_CryptoMode = false; if(inStream->Seek(0, STREAM_SEEK_CUR, &m_StreamStartPosition) != S_OK) return false; m_Position = m_StreamStartPosition; @@ -39,14 +40,13 @@ void CInArchive::Close() static inline bool TestMarkerCandidate(const void *aTestBytes) { - // return (memcmp(aTestBytes, NHeader::kMarker, NHeader::kMarkerSize) == 0); - for (UINT32 i = 0; i < NHeader::kMarkerSize; i++) - if (((const BYTE *)aTestBytes)[i] != NHeader::kMarker[i]) + for (UInt32 i = 0; i < NHeader::kMarkerSize; i++) + if (((const Byte *)aTestBytes)[i] != NHeader::kMarker[i]) return false; return true; } -bool CInArchive::FindAndReadMarker(const UINT64 *searchHeaderSizeLimit) +bool CInArchive::FindAndReadMarker(const UInt64 *searchHeaderSizeLimit) { // if (m_Length < NHeader::kMarkerSize) // return false; @@ -55,8 +55,8 @@ bool CInArchive::FindAndReadMarker(const UINT64 *searchHeaderSizeLimit) if(m_Stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL) != S_OK) return false; - BYTE marker[NHeader::kMarkerSize]; - UINT32 processedSize; + Byte marker[NHeader::kMarkerSize]; + UInt32 processedSize; ReadBytes(marker, NHeader::kMarkerSize, &processedSize); if(processedSize != NHeader::kMarkerSize) return false; @@ -64,24 +64,24 @@ bool CInArchive::FindAndReadMarker(const UINT64 *searchHeaderSizeLimit) return true; CByteDynamicBuffer dynamicBuffer; - static const UINT32 kSearchMarkerBufferSize = 0x10000; + static const UInt32 kSearchMarkerBufferSize = 0x10000; dynamicBuffer.EnsureCapacity(kSearchMarkerBufferSize); - BYTE *buffer = dynamicBuffer; - UINT32 numBytesPrev = NHeader::kMarkerSize - 1; + Byte *buffer = dynamicBuffer; + UInt32 numBytesPrev = NHeader::kMarkerSize - 1; memmove(buffer, marker + 1, numBytesPrev); - UINT64 curTestPos = m_StreamStartPosition + 1; + UInt64 curTestPos = m_StreamStartPosition + 1; while(true) { if (searchHeaderSizeLimit != NULL) if (curTestPos - m_StreamStartPosition > *searchHeaderSizeLimit) return false; - UINT32 numReadBytes = kSearchMarkerBufferSize - numBytesPrev; + UInt32 numReadBytes = kSearchMarkerBufferSize - numBytesPrev; ReadBytes(buffer + numBytesPrev, numReadBytes, &processedSize); - UINT32 numBytesInBuffer = numBytesPrev + processedSize; + UInt32 numBytesInBuffer = numBytesPrev + processedSize; if (numBytesInBuffer < NHeader::kMarkerSize) return false; - UINT32 numTests = numBytesInBuffer - NHeader::kMarkerSize + 1; - for(UINT32 pos = 0; pos < numTests; pos++, curTestPos++) + UInt32 numTests = numBytesInBuffer - NHeader::kMarkerSize + 1; + for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++) { if (TestMarkerCandidate(buffer + pos)) { @@ -98,29 +98,36 @@ bool CInArchive::FindAndReadMarker(const UINT64 *searchHeaderSizeLimit) return false; } -//bool boolIsItCorrectArchive; - void CInArchive::ThrowUnexpectedEndOfArchiveException() { ThrowExceptionWithCode(CInArchiveException::kUnexpectedEndOfArchive); } -bool CInArchive::ReadBytesAndTestSize(void *data, UINT32 size) +bool CInArchive::ReadBytesAndTestSize(void *data, UInt32 size) { - UINT32 processedSize; + if (m_CryptoMode) + { + const Byte *bufData = (const Byte *)m_DecryptedData; + UInt32 bufSize = m_DecryptedDataSize; + UInt32 i; + for (i = 0; i < size && m_CryptoPos < bufSize; i++) + ((Byte *)data)[i] = bufData[m_CryptoPos++]; + return (i == size); + } + UInt32 processedSize; m_Stream->Read(data, size, &processedSize); return (processedSize == size); } -void CInArchive::ReadBytesAndTestResult(void *data, UINT32 size) +void CInArchive::ReadBytesAndTestResult(void *data, UInt32 size) { if(!ReadBytesAndTestSize(data,size)) ThrowUnexpectedEndOfArchiveException(); } -HRESULT CInArchive::ReadBytes(void *data, UINT32 size, UINT32 *processedSize) +HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize) { - UINT32 realProcessedSize; + UInt32 realProcessedSize; HRESULT result = m_Stream->Read(data, size, &realProcessedSize); if(processedSize != NULL) *processedSize = realProcessedSize; @@ -128,17 +135,36 @@ HRESULT CInArchive::ReadBytes(void *data, UINT32 size, UINT32 *processedSize) return result; } -bool CInArchive::ReadMarkerAndArchiveHeader(const UINT64 *searchHeaderSizeLimit) +bool CInArchive::ReadMarkerAndArchiveHeader(const UInt64 *searchHeaderSizeLimit) { if (!FindAndReadMarker(searchHeaderSizeLimit)) return false; - UINT32 processedSize; - ReadBytes(&m_ArchiveHeader, sizeof(m_ArchiveHeader), &processedSize); - if (processedSize != sizeof(m_ArchiveHeader)) + Byte buf[NHeader::NArchive::kArchiveHeaderSize]; + UInt32 processedSize; + ReadBytes(buf, sizeof(buf), &processedSize); + if (processedSize != sizeof(buf)) return false; - - if(m_ArchiveHeader.CRC != m_ArchiveHeader.GetRealCRC()) + m_CurData = buf; + m_CurPos = 0; + m_PosLimit = sizeof(buf); + + m_ArchiveHeader.CRC = ReadUInt16(); + m_ArchiveHeader.Type = ReadByte(); + m_ArchiveHeader.Flags = ReadUInt16(); + m_ArchiveHeader.Size = ReadUInt16(); + m_ArchiveHeader.Reserved1 = ReadUInt16(); + m_ArchiveHeader.Reserved2 = ReadUInt32(); + + CCRC crc; + crc.UpdateByte(m_ArchiveHeader.Type); + crc.UpdateUInt16(m_ArchiveHeader.Flags); + crc.UpdateUInt16(m_ArchiveHeader.Size); + crc.UpdateUInt16(m_ArchiveHeader.Reserved1); + crc.UpdateUInt32(m_ArchiveHeader.Reserved2); + + UInt32 u = crc.GetDigest(); + if(m_ArchiveHeader.CRC != (crc.GetDigest() & 0xFFFF)) ThrowExceptionWithCode(CInArchiveException::kArchiveHeaderCRCError); if (m_ArchiveHeader.Type != NHeader::NBlockType::kArchiveHeader) return false; @@ -151,7 +177,7 @@ void CInArchive::SkipArchiveComment() { if (!m_SeekOnArchiveComment) return; - AddToSeekValue(m_ArchiveHeader.Size - sizeof(m_ArchiveHeader)); + AddToSeekValue(m_ArchiveHeader.Size - NHeader::NArchive::kArchiveHeaderSize); m_SeekOnArchiveComment = false; } @@ -160,17 +186,17 @@ void CInArchive::GetArchiveInfo(CInArchiveInfo &archiveInfo) const archiveInfo.StartPosition = m_ArchiveStartPosition; archiveInfo.Flags = m_ArchiveHeader.Flags; archiveInfo.CommentPosition = m_ArchiveCommentPosition; - archiveInfo.CommentSize = m_ArchiveHeader.Size - sizeof(m_ArchiveHeader); + archiveInfo.CommentSize = m_ArchiveHeader.Size - NHeader::NArchive::kArchiveHeaderSize; } -static void DecodeUnicodeFileName(const char *name, const BYTE *encName, +static void DecodeUnicodeFileName(const char *name, const Byte *encName, int encSize, wchar_t *unicodeName, int maxDecSize) { int encPos = 0; int decPos = 0; int flagBits = 0; - BYTE flags = 0; - BYTE highByte = encName[encPos++]; + Byte flags = 0; + Byte highByte = encName[encPos++]; while (encPos < encSize && decPos < maxDecSize) { if (flagBits == 0) @@ -195,7 +221,7 @@ static void DecodeUnicodeFileName(const char *name, const BYTE *encName, int length = encName[encPos++]; if (length & 0x80) { - BYTE correction = encName[encPos++]; + Byte correction = encName[encPos++]; for (length = (length & 0x7f) + 2; length > 0 && decPos < maxDecSize; length--, decPos++) unicodeName[decPos] = ((name[decPos] + correction) & 0xff) + (highByte << 8); @@ -212,32 +238,32 @@ static void DecodeUnicodeFileName(const char *name, const BYTE *encName, unicodeName[decPos < maxDecSize ? decPos : maxDecSize - 1] = 0; } -void CInArchive::ReadName(const BYTE *data, CItemEx &item, int nameSize) +void CInArchive::ReadName(CItemEx &item, int nameSize) { - int sizeFileName = nameSize; item.UnicodeName.Empty(); - if (sizeFileName > 0) + if (nameSize > 0) { - m_NameBuffer.EnsureCapacity(sizeFileName + 1); + m_NameBuffer.EnsureCapacity(nameSize + 1); char *buffer = (char *)m_NameBuffer; - memmove(buffer, data, sizeFileName); + for (int i = 0; i < nameSize; i++) + buffer[i] = ReadByte(); int mainLen; - for (mainLen = 0; mainLen < sizeFileName; mainLen++) + for (mainLen = 0; mainLen < nameSize; mainLen++) if (buffer[mainLen] == '\0') break; buffer[mainLen] = '\0'; item.Name = buffer; - int unicodeNameSizeMax = MyMin(sizeFileName, (0x400)); + int unicodeNameSizeMax = MyMin(nameSize, (0x400)); _unicodeNameBuffer.EnsureCapacity(unicodeNameSizeMax + 1); if((m_BlockHeader.Flags & NHeader::NFile::kUnicodeName) != 0 && - mainLen < sizeFileName) + mainLen < nameSize) { - DecodeUnicodeFileName(buffer, (const BYTE *)buffer + mainLen + 1, - sizeFileName - (mainLen + 1), _unicodeNameBuffer, unicodeNameSizeMax); + DecodeUnicodeFileName(buffer, (const Byte *)buffer + mainLen + 1, + nameSize - (mainLen + 1), _unicodeNameBuffer, unicodeNameSizeMax); item.UnicodeName = _unicodeNameBuffer; } } @@ -245,157 +271,232 @@ void CInArchive::ReadName(const BYTE *data, CItemEx &item, int nameSize) item.Name.Empty(); } -static const BYTE *ReadTime(const BYTE *data, BYTE mask, CRarTime &rarTime) +Byte CInArchive::ReadByte() +{ + if (m_CurPos >= m_PosLimit) + throw CInArchiveException(CInArchiveException::kIncorrectArchive); + return m_CurData[m_CurPos++]; +} + +UInt16 CInArchive::ReadUInt16() +{ + UInt16 value = 0; + for (int i = 0; i < 2; i++) + { + Byte b = ReadByte(); + value |= (UInt16(b) << (8 * i)); + } + return value; +} + +UInt32 CInArchive::ReadUInt32() +{ + UInt32 value = 0; + for (int i = 0; i < 4; i++) + { + Byte b = ReadByte(); + value |= (UInt32(b) << (8 * i)); + } + return value; +} + +void CInArchive::ReadTime(Byte mask, CRarTime &rarTime) { rarTime.LowSecond = ((mask & 4) != 0) ? 1 : 0; int numDigits = (mask & 3); rarTime.SubTime[0] = rarTime.SubTime[1] = rarTime.SubTime[2] = 0; for (int i = 0; i < numDigits; i++) - rarTime.SubTime[3 - numDigits + i] = *data++; - return data; + rarTime.SubTime[3 - numDigits + i] = ReadByte(); } -void CInArchive::ReadHeaderReal(const BYTE *data, CItemEx &item) +void CInArchive::ReadHeaderReal(CItemEx &item) { - const BYTE *dataStart = data; - const NHeader::NFile::CBlock &fileHeader = - *(const NHeader::NFile::CBlock *)data; - // UINT32 sizeFileName = fileHeader.NameSize; - item.Flags = m_BlockHeader.Flags; - item.PackSize = fileHeader.PackSize; - item.UnPackSize = fileHeader.UnPackSize; - item.HostOS = fileHeader.HostOS; - item.FileCRC = fileHeader.FileCRC; - item.LastWriteTime.DosTime = fileHeader.Time; + item.PackSize = ReadUInt32(); + item.UnPackSize = ReadUInt32(); + item.HostOS = ReadByte(); + item.FileCRC = ReadUInt32(); + item.LastWriteTime.DosTime = ReadUInt32(); + item.UnPackVersion = ReadByte(); + item.Method = ReadByte(); + int nameSize = ReadUInt16(); + item.Attributes = ReadUInt32(); + item.LastWriteTime.LowSecond = 0; item.LastWriteTime.SubTime[0] = - item.LastWriteTime.SubTime[1] = - item.LastWriteTime.SubTime[2] = 0; - - - item.UnPackVersion = fileHeader.UnPackVersion; - item.Method = fileHeader.Method; - item.Attributes = fileHeader.Attributes; - - data += sizeof(fileHeader); + item.LastWriteTime.SubTime[1] = + item.LastWriteTime.SubTime[2] = 0; if((item.Flags & NHeader::NFile::kSize64Bits) != 0) { - item.PackSize |= (*((const UINT64 *)data)) << 32; - data += sizeof(UINT32); - item.UnPackSize |= (*((const UINT64 *)data)) << 32; - data += sizeof(UINT32); + item.PackSize |= ((UInt64)ReadUInt32() << 32); + item.UnPackSize |= ((UInt64)ReadUInt32() << 32); } - ReadName(data, item, fileHeader.NameSize); - data += fileHeader.NameSize; + ReadName(item, nameSize); if (item.HasSalt()) - { - memmove(item.Salt, data, sizeof(item.Salt)); - data += sizeof(item.Salt); - } + for (int i = 0; i < sizeof(item.Salt); i++) + item.Salt[i] = ReadByte(); if (item.HasExtTime()) { - BYTE access = (*data) >> 4; - data++; - BYTE modif = (*data) >> 4; - BYTE creat = (*data) & 0xF; - data++; - if ((modif & 8) != 0) - data = ReadTime(data, modif, item.LastWriteTime); - if (item.IsCreationTimeDefined = ((creat & 8) != 0)) + Byte accessMask = ReadByte() >> 4; + Byte b = ReadByte(); + Byte modifMask = b >> 4; + Byte createMask = b & 0xF; + if ((modifMask & 8) != 0) + ReadTime(modifMask, item.LastWriteTime); + if (item.IsCreationTimeDefined = ((createMask & 8) != 0)) { - item.CreationTime.DosTime = *(const UINT32 *)data; - data += sizeof(UINT32); - data = ReadTime(data, creat, item.CreationTime); + item.CreationTime.DosTime = ReadUInt32(); + ReadTime(createMask, item.CreationTime); } - if (item.IsLastAccessTimeDefined = ((access & 8) != 0)) + if (item.IsLastAccessTimeDefined = ((accessMask & 8) != 0)) { - item.LastAccessTime.DosTime = *(const UINT32 *)data; - data += sizeof(UINT32); - data = ReadTime(data, access, item.LastAccessTime); + item.LastAccessTime.DosTime = ReadUInt32(); + ReadTime(accessMask, item.LastAccessTime); } } - UINT16 fileHeaderWithNameSize = - sizeof(NHeader::NBlock::CBlock) + data - dataStart; + UInt16 fileHeaderWithNameSize = (UInt16)m_CurPos; item.Position = m_Position; item.MainPartSize = fileHeaderWithNameSize; item.CommentSize = m_BlockHeader.HeadSize - fileHeaderWithNameSize; - + + if (m_CryptoMode) + item.AlignSize = (16 - ((m_BlockHeader.HeadSize) & 0xF)) & 0xF; + else + item.AlignSize = 0; AddToSeekValue(m_BlockHeader.HeadSize); } -void CInArchive::AddToSeekValue(UINT64 addValue) +void CInArchive::AddToSeekValue(UInt64 addValue) { m_Position += addValue; } -bool CInArchive::GetNextItem(CItemEx &item) +HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPassword) { - if ((m_ArchiveHeader.Flags & - NHeader::NArchive::kBlockHeadersAreEncrypted) != 0) - return false; if (m_SeekOnArchiveComment) SkipArchiveComment(); while (true) { if(!SeekInArchive(m_Position)) - return false; - if(!ReadBytesAndTestSize(&m_BlockHeader, sizeof(m_BlockHeader))) - return false; + return S_FALSE; + if (!m_CryptoMode && (m_ArchiveHeader.Flags & + NHeader::NArchive::kBlockHeadersAreEncrypted) != 0) + { + m_CryptoMode = false; + if (getTextPassword == 0) + return S_FALSE; + if(!SeekInArchive(m_Position)) + return S_FALSE; + if (!m_RarAES) + { + m_RarAESSpec = new NCrypto::NRar29::CDecoder; + m_RarAES = m_RarAESSpec; + } + // Salt + const UInt32 kSaltSize = 8; + Byte salt[kSaltSize]; + if(!ReadBytesAndTestSize(salt, kSaltSize)) + return false; + m_Position += kSaltSize; + RINOK(m_RarAESSpec->SetDecoderProperties2(salt, kSaltSize)) + // Password + CMyComBSTR password; + RINOK(getTextPassword->CryptoGetTextPassword(&password)) + UString unicodePassword(password); + + RINOK(m_RarAESSpec->CryptoSetPassword( + (const Byte *)(const wchar_t *)unicodePassword, + unicodePassword.Length() * 2)); + + const UInt32 kDecryptedBufferSize = (1 << 12); + if (m_DecryptedData.GetCapacity() == 0) + { + m_DecryptedData.SetCapacity(kDecryptedBufferSize); + } + RINOK(m_RarAES->Init()); + RINOK(m_Stream->Read((Byte *)m_DecryptedData, kDecryptedBufferSize, &m_DecryptedDataSize)); + m_DecryptedDataSize = m_RarAES->Filter((Byte *)m_DecryptedData, m_DecryptedDataSize); + + m_CryptoMode = true; + m_CryptoPos = 0; + } + + m_FileHeaderData.EnsureCapacity(7); + if(!ReadBytesAndTestSize((Byte *)m_FileHeaderData, 7)) + return S_FALSE; + + m_CurData = (Byte *)m_FileHeaderData; + m_CurPos = 0; + m_PosLimit = 7; + m_BlockHeader.CRC = ReadUInt16(); + m_BlockHeader.Type = ReadByte(); + m_BlockHeader.Flags = ReadUInt16(); + m_BlockHeader.HeadSize = ReadUInt16(); if (m_BlockHeader.HeadSize < 7) ThrowExceptionWithCode(CInArchiveException::kIncorrectArchive); + if (m_BlockHeader.Type == NHeader::NBlockType::kEndOfArchive) + return S_FALSE; + if (m_BlockHeader.Type == NHeader::NBlockType::kFileHeader) { m_FileHeaderData.EnsureCapacity(m_BlockHeader.HeadSize); - UINT32 headerSize = m_BlockHeader.HeadSize - sizeof(m_BlockHeader); - ReadBytesAndTestResult(m_FileHeaderData, headerSize); - CCRC crc; - crc.Update(&m_BlockHeader.Type, sizeof(m_BlockHeader) - - sizeof(m_BlockHeader.CRC)); - - ReadHeaderReal(m_FileHeaderData, item); - - crc.Update(m_FileHeaderData, headerSize - item.CommentSize); - if ((crc.GetDigest() & 0xFFFF) != m_BlockHeader.CRC) + m_CurData = (Byte *)m_FileHeaderData; + m_PosLimit = m_BlockHeader.HeadSize; + ReadBytesAndTestResult(m_CurData + m_CurPos, m_BlockHeader.HeadSize - 7); + ReadHeaderReal(item); + if ((CCRC::CalculateDigest(m_CurData + 2, + m_BlockHeader.HeadSize - item.CommentSize - 2) & 0xFFFF) != m_BlockHeader.CRC) ThrowExceptionWithCode(CInArchiveException::kFileHeaderCRCError); + FinishCryptoBlock(); + m_CryptoMode = false; SeekInArchive(m_Position); // Move Position to compressed Data; - AddToSeekValue(item.PackSize); // m_Position points Tto next header; - return true; + AddToSeekValue(item.PackSize); // m_Position points to next header; + return S_OK; } + if (m_CryptoMode && m_BlockHeader.HeadSize > (1 << 12)) + return E_FAIL; // it's for bad passwords if ((m_BlockHeader.Flags & NHeader::NBlock::kLongBlock) != 0) { - UINT32 dataSize; - ReadBytesAndTestResult(&dataSize, sizeof(dataSize)); // test it + m_FileHeaderData.EnsureCapacity(7 + 4); + m_CurData = (Byte *)m_FileHeaderData; + ReadBytesAndTestResult(m_CurData + m_CurPos, 4); // test it + m_PosLimit = 7 + 4; + UInt32 dataSize = ReadUInt32(); AddToSeekValue(dataSize); + if (m_CryptoMode && dataSize > (1 << 27)) + return E_FAIL; // it's for bad passwords + m_CryptoPos = m_BlockHeader.HeadSize; } + else + m_CryptoPos = 0; AddToSeekValue(m_BlockHeader.HeadSize); + FinishCryptoBlock(); + m_CryptoMode = false; } } - -void CInArchive::DirectGetBytes(void *data, UINT32 size) +void CInArchive::DirectGetBytes(void *data, UInt32 size) { m_Stream->Read(data, size, NULL); } - -bool CInArchive::SeekInArchive(UINT64 position) +bool CInArchive::SeekInArchive(UInt64 position) { - UINT64 newPosition; + UInt64 newPosition; m_Stream->Seek(position, STREAM_SEEK_SET, &newPosition); return newPosition == position; } -ISequentialInStream* CInArchive::CreateLimitedStream(UINT64 position, UINT64 size) +ISequentialInStream* CInArchive::CreateLimitedStream(UInt64 position, UInt64 size) { CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; CMyComPtr<ISequentialInStream> inStream(streamSpec); diff --git a/7zip/Archive/Rar/RarIn.h b/7zip/Archive/Rar/RarIn.h index 242787c2..c370733a 100755 --- a/7zip/Archive/Rar/RarIn.h +++ b/7zip/Archive/Rar/RarIn.h @@ -1,7 +1,5 @@ // RarIn.h -#pragma once - #ifndef __ARCHIVE_RAR_IN_H #define __ARCHIVE_RAR_IN_H @@ -9,6 +7,9 @@ #include "Common/Exception.h" #include "Common/MyCom.h" #include "../../IStream.h" +#include "../../ICoder.h" +#include "../../Common/StreamObjects.h" +#include "../../Crypto/RarAES/RarAES.h" #include "RarHeader.h" #include "RarItem.h" @@ -32,9 +33,9 @@ public: class CInArchiveInfo { public: - UINT64 StartPosition; + UInt64 StartPosition; WORD Flags; - UINT64 CommentPosition; + UInt64 CommentPosition; WORD CommentSize; bool IsSolid() const { return (Flags & NHeader::NArchive::kSolid) != 0; } bool IsCommented() const { return (Flags & NHeader::NArchive::kComment) != 0; } @@ -46,49 +47,75 @@ class CInArchive { CMyComPtr<IInStream> m_Stream; - UINT64 m_StreamStartPosition; - UINT64 m_Position; - UINT64 m_ArchiveStartPosition; + UInt64 m_StreamStartPosition; + UInt64 m_Position; + UInt64 m_ArchiveStartPosition; NHeader::NArchive::CBlock m_ArchiveHeader; CDynamicBuffer<char> m_NameBuffer; CDynamicBuffer<wchar_t> _unicodeNameBuffer; bool m_SeekOnArchiveComment; - UINT64 m_ArchiveCommentPosition; + UInt64 m_ArchiveCommentPosition; - void ReadName(const BYTE *data, CItemEx &item, int nameSize); - void ReadHeaderReal(const BYTE *data, CItemEx &item); + void ReadName(CItemEx &item, int nameSize); + void ReadHeaderReal(CItemEx &item); - HRESULT ReadBytes(void *data, UINT32 size, UINT32 *aProcessedSize); - bool ReadBytesAndTestSize(void *data, UINT32 size); - void ReadBytesAndTestResult(void *data, UINT32 size); + HRESULT ReadBytes(void *data, UInt32 size, UInt32 *aProcessedSize); + bool ReadBytesAndTestSize(void *data, UInt32 size); + void ReadBytesAndTestResult(void *data, UInt32 size); - bool FindAndReadMarker(const UINT64 *searchHeaderSizeLimit); + bool FindAndReadMarker(const UInt64 *searchHeaderSizeLimit); void ThrowExceptionWithCode(CInArchiveException::CCauseType cause); void ThrowUnexpectedEndOfArchiveException(); - void AddToSeekValue(UINT64 addValue); + void AddToSeekValue(UInt64 addValue); protected: - CDynamicBuffer<BYTE> m_FileHeaderData; - + CDynamicBuffer<Byte> m_FileHeaderData; + NHeader::NBlock::CBlock m_BlockHeader; + + NCrypto::NRar29::CDecoder *m_RarAESSpec; + CMyComPtr<ICompressFilter> m_RarAES; - bool ReadMarkerAndArchiveHeader(const UINT64 *searchHeaderSizeLimit); + Byte *m_CurData; // it must point to start of Rar::Block + UInt32 m_CurPos; + UInt32 m_PosLimit; + Byte ReadByte(); + UInt16 ReadUInt16(); + UInt32 ReadUInt32(); + void ReadTime(Byte mask, CRarTime &rarTime); + + CBuffer<Byte> m_DecryptedData; + UInt32 m_DecryptedDataSize; + + bool m_CryptoMode; + UInt32 m_CryptoPos; + void FinishCryptoBlock() + { + if (m_CryptoMode) + while ((m_CryptoPos & 0xF) != 0) + { + m_CryptoPos++; + m_Position++; + } + } + + bool ReadMarkerAndArchiveHeader(const UInt64 *searchHeaderSizeLimit); public: - bool Open(IInStream *inStream, const UINT64 *searchHeaderSizeLimit); + bool Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit); void Close(); - bool GetNextItem(CItemEx &item); + HRESULT GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPassword); void SkipArchiveComment(); void GetArchiveInfo(CInArchiveInfo &archiveInfo) const; - void DirectGetBytes(void *data, UINT32 size); + void DirectGetBytes(void *data, UInt32 size); - bool SeekInArchive(UINT64 position); - ISequentialInStream *CreateLimitedStream(UINT64 position, UINT64 size); + bool SeekInArchive(UInt64 position); + ISequentialInStream *CreateLimitedStream(UInt64 position, UInt64 size); }; }} diff --git a/7zip/Archive/Rar/RarItem.cpp b/7zip/Archive/Rar/RarItem.cpp index 761f233e..8114728f 100755 --- a/7zip/Archive/Rar/RarItem.cpp +++ b/7zip/Archive/Rar/RarItem.cpp @@ -1,6 +1,6 @@ // RarItem.cpp -#include "stdafx.h" +#include "StdAfx.h" #include "RarItem.h" #include "RarHeader.h" @@ -39,7 +39,7 @@ bool CItem::IgnoreItem() const return false; } -UINT32 CItem::GetDictSize() const +UInt32 CItem::GetDictSize() const { return (Flags >> NHeader::NFile::kDictBitStart) & NHeader::NFile::kDictMask; } bool CItem::IsDirectory() const @@ -47,22 +47,22 @@ bool CItem::IsDirectory() const return (GetDictSize() == NHeader::NFile::kDictDirectoryValue); } -UINT32 CItem::GetWinAttributes() const +UInt32 CItem::GetWinAttributes() const { - UINT32 aWinAttributes; + UInt32 winAttributes; switch(HostOS) { case NHeader::NFile::kHostMSDOS: case NHeader::NFile::kHostOS2: case NHeader::NFile::kHostWin32: - aWinAttributes = Attributes; + winAttributes = Attributes; break; default: - aWinAttributes = 0; // must be converted from unix value;; + winAttributes = 0; // must be converted from unix value;; } if (IsDirectory()) // test it; - aWinAttributes |= NHeader::NFile::kWinFileDirectoryAttributeMask; - return aWinAttributes; + winAttributes |= NHeader::NFile::kWinFileDirectoryAttributeMask; + return winAttributes; } void CItem::ClearFlags() @@ -70,8 +70,8 @@ void CItem::ClearFlags() void CItem::SetFlagBits(int aStartBitNumber, int aNumBits, int aValue) { - UINT16 aMask = ((1 << aNumBits) - 1) << aStartBitNumber; - Flags &= ~aMask; + UInt16 mask = ((1 << aNumBits) - 1) << aStartBitNumber; + Flags &= ~mask; Flags |= aValue << aStartBitNumber; } @@ -83,7 +83,7 @@ void CItem::SetBitMask(int aBitMask, bool anEnable) Flags &= ~aBitMask; } -void CItem::SetDictSize(UINT32 aSize) +void CItem::SetDictSize(UInt32 aSize) { SetFlagBits(NHeader::NFile::kDictBitStart, NHeader::NFile::kNumDictBits, (aSize & NHeader::NFile::kDictMask)); } diff --git a/7zip/Archive/Rar/RarItem.h b/7zip/Archive/Rar/RarItem.h index 55c1086d..0140f888 100755 --- a/7zip/Archive/Rar/RarItem.h +++ b/7zip/Archive/Rar/RarItem.h @@ -1,7 +1,5 @@ // RarItem.h -#pragma once - #ifndef __ARCHIVE_RAR_ITEM_H #define __ARCHIVE_RAR_ITEM_H @@ -13,19 +11,19 @@ namespace NRar{ struct CRarTime { - UINT32 DosTime; - BYTE LowSecond; - BYTE SubTime[3]; + UInt32 DosTime; + Byte LowSecond; + Byte SubTime[3]; }; class CItem { public: - UINT16 Flags; - UINT64 PackSize; - UINT64 UnPackSize; - BYTE HostOS; - UINT32 FileCRC; + UInt16 Flags; + UInt64 PackSize; + UInt64 UnPackSize; + Byte HostOS; + UInt32 FileCRC; CRarTime CreationTime; CRarTime LastWriteTime; @@ -34,13 +32,13 @@ public: // bool IsLastWriteTimeDefined; bool IsLastAccessTimeDefined; - BYTE UnPackVersion; - BYTE Method; - UINT32 Attributes; + Byte UnPackVersion; + Byte Method; + UInt32 Attributes; AString Name; UString UnicodeName; - BYTE Salt[8]; + Byte Salt[8]; bool IsEncrypted() const; bool IsSolid() const; @@ -53,10 +51,10 @@ public: bool HasUnicodeName() const; bool IsOldVersion() const; - UINT32 GetDictSize() const; + UInt32 GetDictSize() const; bool IsDirectory() const; bool IgnoreItem() const; - UINT32 GetWinAttributes() const; + UInt32 GetWinAttributes() const; CItem(): IsCreationTimeDefined(false), IsLastAccessTimeDefined(false) {} private: @@ -64,7 +62,7 @@ private: void SetBitMask(int aBitMask, bool anEnable); public: void ClearFlags(); - void SetDictSize(UINT32 aSize); + void SetDictSize(UInt32 aSize); void SetAsDirectory(bool aDirectory); void SetEncrypted(bool anEncrypted); void SetSolid(bool aSolid); @@ -76,13 +74,14 @@ public: class CItemEx: public CItem { public: - UINT64 Position; - UINT16 MainPartSize; - UINT16 CommentSize; - UINT64 GetFullSize() const { return MainPartSize + CommentSize + PackSize; }; + UInt64 Position; + UInt16 MainPartSize; + UInt16 CommentSize; + UInt16 AlignSize; + UInt64 GetFullSize() const { return MainPartSize + CommentSize + AlignSize + PackSize; }; // DWORD GetHeaderWithCommentSize() const { return MainPartSize + CommentSize; }; - UINT64 GetCommentPosition() const { return Position + MainPartSize; }; - UINT64 GetDataPosition() const { return GetCommentPosition() + CommentSize; }; + UInt64 GetCommentPosition() const { return Position + MainPartSize; }; + UInt64 GetDataPosition() const { return GetCommentPosition() + CommentSize + AlignSize; }; }; }} diff --git a/7zip/Archive/Rar/RarItemEx.h b/7zip/Archive/Rar/RarItemEx.h deleted file mode 100755 index 509208dc..00000000 --- a/7zip/Archive/Rar/RarItemEx.h +++ /dev/null @@ -1,19 +0,0 @@ -// Archive::Rar::ItemInfoEx.h - -#pragma once - -#ifndef __ARCHIVE_RAR_ITEMINFOEX_H -#define __ARCHIVE_RAR_ITEMINFOEX_H - -#include "Archive/Rar/ItemInfo.h" - -namespace NArchive{ -namespace NRar{ - - -}} - -#endif - - - diff --git a/7zip/Archive/Rar/RarVolumeInStream.cpp b/7zip/Archive/Rar/RarVolumeInStream.cpp index 97efdb77..5a185707 100755 --- a/7zip/Archive/Rar/RarVolumeInStream.cpp +++ b/7zip/Archive/Rar/RarVolumeInStream.cpp @@ -46,17 +46,17 @@ HRESULT CFolderInStream::CloseStream() return S_OK; } -STDMETHODIMP CFolderInStream::Read(void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize) { - UINT32 realProcessedSize = 0; + UInt32 realProcessedSize = 0; while ((_curIndex < _refItem.NumItems || _fileIsOpen) && size > 0) { if (_fileIsOpen) { - UINT32 localProcessedSize; + UInt32 localProcessedSize; RINOK(_stream->Read( - ((BYTE *)data) + realProcessedSize, size, &localProcessedSize)); - _crc.Update(((BYTE *)data) + realProcessedSize, localProcessedSize); + ((Byte *)data) + realProcessedSize, size, &localProcessedSize)); + _crc.Update(((Byte *)data) + realProcessedSize, localProcessedSize); if (localProcessedSize == 0) { RINOK(CloseStream()); @@ -75,7 +75,7 @@ STDMETHODIMP CFolderInStream::Read(void *data, UINT32 size, UINT32 *processedSiz return S_OK; } -STDMETHODIMP CFolderInStream::ReadPart(void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CFolderInStream::ReadPart(void *data, UInt32 size, UInt32 *processedSize) { return Read(data, size, processedSize); } diff --git a/7zip/Archive/Rar/RarVolumeInStream.h b/7zip/Archive/Rar/RarVolumeInStream.h index 263d636c..53156306 100755 --- a/7zip/Archive/Rar/RarVolumeInStream.h +++ b/7zip/Archive/Rar/RarVolumeInStream.h @@ -1,7 +1,5 @@ // RarVolumeInStream.h -#pragma once - #ifndef __RAR_VOLUME_IN_STREAM_H #define __RAR_VOLUME_IN_STREAM_H @@ -26,8 +24,8 @@ class CFolderInStream: public: MY_UNKNOWN_IMP - STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize); - STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize); + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); private: CObjectVector<CInArchive> *_archives; @@ -45,7 +43,7 @@ public: const CObjectVector<CItemEx> *items, const CRefItem &refItem); - CRecordVector<UINT32> CRCs; + CRecordVector<UInt32> CRCs; }; }} diff --git a/7zip/Archive/Rar/StdAfx.cpp b/7zip/Archive/Rar/StdAfx.cpp index 2550270c..d0feea85 100755 --- a/7zip/Archive/Rar/StdAfx.cpp +++ b/7zip/Archive/Rar/StdAfx.cpp @@ -1,3 +1,3 @@ // StdAfx.cpp -#include "stdafx.h" +#include "StdAfx.h" diff --git a/7zip/Archive/Rar/StdAfx.h b/7zip/Archive/Rar/StdAfx.h index 97eb50d1..e7fb6986 100755 --- a/7zip/Archive/Rar/StdAfx.h +++ b/7zip/Archive/Rar/StdAfx.h @@ -1,9 +1,8 @@ -// stdafx.h - +// StdAfx.h + #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> -#include <time.h> +#include "../../../Common/MyWindows.h" -#endif +#endif diff --git a/7zip/Archive/Rar/resource.rc b/7zip/Archive/Rar/resource.rc index 731e0c29..1aef2af2 100755 --- a/7zip/Archive/Rar/resource.rc +++ b/7zip/Archive/Rar/resource.rc @@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,12,0,0 - PRODUCTVERSION 3,12,0,0 + FILEVERSION 4,13,0,0 + PRODUCTVERSION 4,13,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -85,14 +85,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Igor Pavlov \0" VALUE "FileDescription", "Rar Plugin for 7-Zip\0" - VALUE "FileVersion", "3, 12, 0, 0\0" + VALUE "FileVersion", "4, 13, 0, 0\0" VALUE "InternalName", "rar\0" - VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2004 Igor Pavlov\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "rar.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "7-Zip\0" - VALUE "ProductVersion", "3, 12, 0, 0\0" + VALUE "ProductVersion", "4, 13, 0, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/7zip/Archive/Split/DllExports.cpp b/7zip/Archive/Split/DllExports.cpp index 11053845..d8ea97c7 100755 --- a/7zip/Archive/Split/DllExports.cpp +++ b/7zip/Archive/Split/DllExports.cpp @@ -1,9 +1,8 @@ -// DLLExports.cpp : Implementation of DLL Exports. +// DLLExports.cpp #include "StdAfx.h" -#include <initguid.h> - +#include "Common/MyInitGuid.h" #include "Common/ComTry.h" #include "Windows/PropVariant.h" #include "SplitHandler.h" @@ -57,6 +56,9 @@ STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) case NArchive::kUpdate: propVariant = false; break; + case NArchive::kKeepName: + propVariant = true; + break; } propVariant.Detach(value); return S_OK; diff --git a/7zip/Archive/Split/Split.dsp b/7zip/Archive/Split/Split.dsp index 04a246af..1e80bc00 100755 --- a/7zip/Archive/Split/Split.dsp +++ b/7zip/Archive/Split/Split.dsp @@ -126,6 +126,14 @@ SOURCE=.\StdAfx.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\NewHandler.cpp # End Source File # Begin Source File @@ -186,6 +194,14 @@ SOURCE=..\..\Compress\Copy\CopyCoder.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\Common\MultiStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\MultiStream.h +# End Source File +# Begin Source File + SOURCE=..\..\Common\ProgressUtils.cpp # End Source File # Begin Source File diff --git a/7zip/Archive/Split/SplitHandler.cpp b/7zip/Archive/Split/SplitHandler.cpp index 0024804d..fddf0c70 100755 --- a/7zip/Archive/Split/SplitHandler.cpp +++ b/7zip/Archive/Split/SplitHandler.cpp @@ -15,6 +15,7 @@ #include "../../Common/ProgressUtils.h" #include "../../Compress/Copy/CopyCoder.h" #include "../Common/ItemNameUtils.h" +#include "../Common/MultiStream.h" using namespace NWindows; using namespace NTime; @@ -25,7 +26,7 @@ namespace NSplit { STATPROPSTG kProperties[] = { { NULL, kpidPath, VT_BSTR}, - { NULL, kpidIsFolder, VT_BOOL}, +// { NULL, kpidIsFolder, VT_BOOL}, { NULL, kpidSize, VT_UI8}, { NULL, kpidPackedSize, VT_UI8}, }; @@ -36,13 +37,13 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) return S_OK; } -STDMETHODIMP CHandler::GetNumberOfProperties(UINT32 *numProperties) +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) { *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); return S_OK; } -STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index, +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) { if(index >= sizeof(kProperties) / sizeof(kProperties[0])) @@ -54,13 +55,13 @@ STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index, return S_OK; } -STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UINT32 *numProperties) +STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) { *numProperties = 0; return S_OK; } -STDMETHODIMP CHandler::GetArchivePropertyInfo(UINT32 index, +STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) { return E_INVALIDARG; @@ -141,7 +142,7 @@ public: }; STDMETHODIMP CHandler::Open(IInStream *stream, - const UINT64 *maxCheckStartPosition, + const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) { COM_TRY_BEGIN @@ -217,20 +218,21 @@ STDMETHODIMP CHandler::Open(IInStream *stream, _subName = prefix.Left(prefix.Length() - 1); _totalSize = 0; - UINT64 size; + UInt64 size; { NCOM::CPropVariant propVariant; RINOK(openVolumeCallback->GetProperty(kpidSize, &propVariant)); if (propVariant.vt != VT_UI8) return E_INVALIDARG; - size = *(UINT64 *)(&propVariant.uhVal); + size = propVariant.uhVal.QuadPart; } _totalSize += size; + _sizes.Add(size); if (openArchiveCallback != NULL) { RINOK(openArchiveCallback->SetTotal(NULL, NULL)); - UINT64 numFiles = _streams.Size(); + UInt64 numFiles = _streams.Size(); RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); } @@ -250,13 +252,14 @@ STDMETHODIMP CHandler::Open(IInStream *stream, RINOK(openVolumeCallback->GetProperty(kpidSize, &propVariant)); if (propVariant.vt != VT_UI8) return E_INVALIDARG; - size = *(UINT64 *)(&propVariant.uhVal); + size = propVariant.uhVal.QuadPart; } _totalSize += size; + _sizes.Add(size); _streams.Add(nextStream); if (openArchiveCallback != NULL) { - UINT64 numFiles = _streams.Size(); + UInt64 numFiles = _streams.Size(); RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); } } @@ -277,13 +280,13 @@ STDMETHODIMP CHandler::Close() return S_OK; } -STDMETHODIMP CHandler::GetNumberOfItems(UINT32 *numItems) +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) { *numItems = _streams.IsEmpty() ? 0 : 1; return S_OK; } -STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value) +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant propVariant; @@ -306,12 +309,12 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *val COM_TRY_END } -STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, - INT32 _aTestMode, IArchiveExtractCallback *_anExtractCallback) +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *_anExtractCallback) { COM_TRY_BEGIN - if (numItems != UINT32(-1)) + if (numItems != UInt32(-1)) { if (numItems != 1) return E_INVALIDARG; @@ -328,15 +331,15 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, return E_FAIL; */ - UINT64 currentTotalSize = 0; - UINT64 currentItemSize; + UInt64 currentTotalSize = 0; + UInt64 currentItemSize; RINOK(extractCallback->SetCompleted(¤tTotalSize)); CMyComPtr<ISequentialOutStream> realOutStream; - INT32 askMode; + Int32 askMode; askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract; - INT32 index = 0; + Int32 index = 0; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); RINOK(extractCallback->PrepareOperation(askMode)); @@ -389,4 +392,24 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, COM_TRY_END } +STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +{ + if (index != 0) + return E_INVALIDARG; + *stream = 0; + CMultiStream *streamSpec = new CMultiStream; + CMyComPtr<ISequentialInStream> streamTemp = streamSpec; + for (int i = 0; i < _streams.Size(); i++) + { + CMultiStream::CSubStreamInfo subStreamInfo; + subStreamInfo.Stream = _streams[i]; + subStreamInfo.Pos = 0; + subStreamInfo.Size = _sizes[i]; + streamSpec->Streams.Add(subStreamInfo); + } + streamSpec->Init(); + *stream = streamTemp.Detach(); + return S_OK; +} + }} diff --git a/7zip/Archive/Split/SplitHandler.h b/7zip/Archive/Split/SplitHandler.h index 149995fb..f69c322e 100755 --- a/7zip/Archive/Split/SplitHandler.h +++ b/7zip/Archive/Split/SplitHandler.h @@ -1,7 +1,5 @@ // Split/Handler.h -#pragma once - #ifndef __SPLIT_HANDLER_H #define __SPLIT_HANDLER_H @@ -14,45 +12,49 @@ namespace NSplit { class CHandler: public IInArchive, + public IInArchiveGetStream, // public IOutArchive, public CMyUnknownImp { public: - MY_UNKNOWN_IMP1(IOutArchive) + MY_UNKNOWN_IMP1(IInArchiveGetStream) STDMETHOD(Open)(IInStream *stream, - const UINT64 *maxCheckStartPosition, + const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback); STDMETHOD(Close)(); - STDMETHOD(GetNumberOfItems)(UINT32 *numItems); - STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(Extract)(const UINT32* indices, UINT32 numItems, - INT32 testMode, IArchiveExtractCallback *extractCallback); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback); STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); - STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties); - STDMETHOD(GetPropertyInfo)(UINT32 index, + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType); - STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties); - STDMETHOD(GetArchivePropertyInfo)(UINT32 index, + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType); - /* + STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); + // IOutArchiveHandler - STDMETHOD(UpdateItems)(IOutStream *outStream, UINT32 numItems, + /* + STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback); - STDMETHOD(GetFileTimeType)(UINT32 *type); + STDMETHOD(GetFileTimeType)(UInt32 *type); */ private: UString _subName; UString _name; CObjectVector<CMyComPtr<IInStream> > _streams; + CRecordVector<UInt64> _sizes; - UINT64 _totalSize; + UInt64 _totalSize; }; }} diff --git a/7zip/Archive/Split/SplitHanlerOut.cpp b/7zip/Archive/Split/SplitHanlerOut.cpp index a7eddb14..ea86c281 100755 --- a/7zip/Archive/Split/SplitHanlerOut.cpp +++ b/7zip/Archive/Split/SplitHanlerOut.cpp @@ -13,14 +13,13 @@ namespace NArchive { namespace NSplit { /* -STDMETHODIMP CHandler::GetFileTimeType(UINT32 *type) +STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type) { *type = NFileTimeType::kWindows; return S_OK; } - -STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems, +STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback) { COM_TRY_BEGIN @@ -28,16 +27,21 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems, if (numItems != 1) return E_INVALIDARG; - UINT64 volumeSize; - RINOK(updateCallback->GetVolumeSize(0, &volumeSize)); + UInt64 volumeSize = 0; + + CMyComPtr<IArchiveUpdateCallback2> callback2; + updateCallback->QueryInterface(IID_IArchiveUpdateCallback2, + (void **)&callback2); + + RINOK(callback2->GetVolumeSize(0, &volumeSize)); - INT32 newData; - INT32 newProperties; - UINT32 indexInArchive; + Int32 newData; + Int32 newProperties; + UInt32 indexInArchive; if (!updateCallback) return E_FAIL; - UINT32 fileIndex; + UInt32 fileIndex = 0; RINOK(updateCallback->GetUpdateItemInfo(fileIndex, &newData, &newProperties, &indexInArchive)); @@ -72,7 +76,7 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems, } } } - UINT64 newSize; + UInt64 newSize; bool thereIsCopyData = false; if (newData != 0) { @@ -80,11 +84,16 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems, RINOK(updateCallback->GetProperty(fileIndex, kpidSize, &propVariant)); if (propVariant.vt != VT_UI8) return E_INVALIDARG; - newSize = *(const UINT64 *)(&propVariant.uhVal); + newSize = propVariant.uhVal.QuadPart; } else thereIsCopyData = true; + UInt64 pos = 0; + while(pos < newSize) + { + + } return S_OK; COM_TRY_END } diff --git a/7zip/Archive/Split/StdAfx.cpp b/7zip/Archive/Split/StdAfx.cpp index 2550270c..d0feea85 100755 --- a/7zip/Archive/Split/StdAfx.cpp +++ b/7zip/Archive/Split/StdAfx.cpp @@ -1,3 +1,3 @@ // StdAfx.cpp -#include "stdafx.h" +#include "StdAfx.h" diff --git a/7zip/Archive/Split/StdAfx.h b/7zip/Archive/Split/StdAfx.h index a32fbed6..e7fb6986 100755 --- a/7zip/Archive/Split/StdAfx.h +++ b/7zip/Archive/Split/StdAfx.h @@ -1,8 +1,8 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> +#include "../../../Common/MyWindows.h" -#endif +#endif diff --git a/7zip/Archive/Split/resource.rc b/7zip/Archive/Split/resource.rc index d1ab6f96..27ab8853 100755 --- a/7zip/Archive/Split/resource.rc +++ b/7zip/Archive/Split/resource.rc @@ -75,8 +75,8 @@ IDI_ICON1 ICON DISCARDABLE "Split.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,9,2,0 - PRODUCTVERSION 3,9,2,0 + FILEVERSION 4,14,0,0 + PRODUCTVERSION 4,14,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -94,14 +94,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Igor Pavlov\0" VALUE "FileDescription", "Split Plugin for 7-Zip\0" - VALUE "FileVersion", "3, 9, 2, 0\0" + VALUE "FileVersion", "4, 14, 0, 0\0" VALUE "InternalName", "split\0" - VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "split.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "7-Zip\0" - VALUE "ProductVersion", "3, 9, 2, 0\0" + VALUE "ProductVersion", "4, 14, 0, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/7zip/Archive/Tar/DllExports.cpp b/7zip/Archive/Tar/DllExports.cpp index ef4aa1b9..7f4f5c04 100755 --- a/7zip/Archive/Tar/DllExports.cpp +++ b/7zip/Archive/Tar/DllExports.cpp @@ -2,8 +2,7 @@ #include "StdAfx.h" -#include <initguid.h> - +#include "Common/MyInitGuid.h" #include "Common/ComTry.h" #include "Windows/PropVariant.h" #include "../../ICoder.h" diff --git a/7zip/Archive/Tar/StdAfx.cpp b/7zip/Archive/Tar/StdAfx.cpp index 2550270c..d0feea85 100755 --- a/7zip/Archive/Tar/StdAfx.cpp +++ b/7zip/Archive/Tar/StdAfx.cpp @@ -1,3 +1,3 @@ // StdAfx.cpp -#include "stdafx.h" +#include "StdAfx.h" diff --git a/7zip/Archive/Tar/StdAfx.h b/7zip/Archive/Tar/StdAfx.h index 6075e527..e7fb6986 100755 --- a/7zip/Archive/Tar/StdAfx.h +++ b/7zip/Archive/Tar/StdAfx.h @@ -1,9 +1,8 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> -#include <time.h> +#include "../../../Common/MyWindows.h" -#endif +#endif diff --git a/7zip/Archive/Tar/Tar.dsp b/7zip/Archive/Tar/Tar.dsp index ec9f3cfa..91dfbaf4 100755 --- a/7zip/Archive/Tar/Tar.dsp +++ b/7zip/Archive/Tar/Tar.dsp @@ -126,6 +126,22 @@ SOURCE=.\Tar.ico # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\NewHandler.cpp # End Source File # Begin Source File diff --git a/7zip/Archive/Tar/TarHandler.cpp b/7zip/Archive/Tar/TarHandler.cpp index 480a1f44..e4162e48 100755 --- a/7zip/Archive/Tar/TarHandler.cpp +++ b/7zip/Archive/Tar/TarHandler.cpp @@ -42,13 +42,13 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) return S_OK; } -STDMETHODIMP CHandler::GetNumberOfProperties(UINT32 *numProperties) +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) { *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); return S_OK; } -STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index, +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) { if(index >= sizeof(kProperties) / sizeof(kProperties[0])) @@ -60,20 +60,20 @@ STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index, return S_OK; } -STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UINT32 *numProperties) +STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) { *numProperties = 0; return S_OK; } -STDMETHODIMP CHandler::GetArchivePropertyInfo(UINT32 index, +STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) { return E_INVALIDARG; } STDMETHODIMP CHandler::Open(IInStream *stream, - const UINT64 *maxCheckStartPosition, + const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) { COM_TRY_BEGIN @@ -90,7 +90,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream, if (openArchiveCallback != NULL) { RINOK(openArchiveCallback->SetTotal(NULL, NULL)); - UINT64 numFiles = _items.Size(); + UInt64 numFiles = _items.Size(); RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); } @@ -109,7 +109,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream, archive.SkeepDataRecords(item.Size); if (openArchiveCallback != NULL) { - UINT64 numFiles = _items.Size(); + UInt64 numFiles = _items.Size(); RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); } } @@ -134,13 +134,13 @@ STDMETHODIMP CHandler::Close() return S_OK; } -STDMETHODIMP CHandler::GetNumberOfItems(UINT32 *numItems) +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) { *numItems = _items.Size(); return S_OK; } -STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value) +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant propVariant; @@ -157,13 +157,13 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *val break; case kpidSize: case kpidPackedSize: - propVariant = (UINT64)item.Size; + propVariant = (UInt64)item.Size; break; case kpidLastWriteTime: { FILETIME utcFileTime; if (item.ModificationTime != 0) - NTime::UnixTimeToFileTime(item.ModificationTime, utcFileTime); + NTime::UnixTimeToFileTime((UInt32)item.ModificationTime, utcFileTime); else { utcFileTime.dwLowDateTime = 0; @@ -186,24 +186,24 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *val COM_TRY_END } -STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, - INT32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN bool testMode = (_aTestMode != 0); - bool allFilesMode = (numItems == UINT32(-1)); + bool allFilesMode = (numItems == UInt32(-1)); if (allFilesMode) numItems = _items.Size(); - UINT64 totalSize = 0; + UInt64 totalSize = 0; if(numItems == 0) return S_OK; - UINT32 i; + UInt32 i; for(i = 0; i < numItems; i++) totalSize += _items[allFilesMode ? i : indices[i]].Size; extractCallback->SetTotal(totalSize); - UINT64 currentTotalSize = 0; - UINT64 currentItemSize; + UInt64 currentTotalSize = 0; + UInt64 currentItemSize; CMyComPtr<ICompressCoder> copyCoder; @@ -211,10 +211,10 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, { RINOK(extractCallback->SetCompleted(¤tTotalSize)); CMyComPtr<ISequentialOutStream> realOutStream; - INT32 askMode; + Int32 askMode; askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract; - INT32 index = allFilesMode ? i : indices[i]; + Int32 index = allFilesMode ? i : indices[i]; const CItemEx &item = _items[index]; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); diff --git a/7zip/Archive/Tar/TarHandler.h b/7zip/Archive/Tar/TarHandler.h index 526fb233..7b6e3a40 100755 --- a/7zip/Archive/Tar/TarHandler.h +++ b/7zip/Archive/Tar/TarHandler.h @@ -1,7 +1,5 @@ // Tar/Handler.h -#pragma once - #ifndef __TAR_HANDLER_H #define __TAR_HANDLER_H @@ -25,28 +23,28 @@ public: ) STDMETHOD(Open)(IInStream *stream, - const UINT64 *maxCheckStartPosition, + const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback); STDMETHOD(Close)(); - STDMETHOD(GetNumberOfItems)(UINT32 *numItems); - STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(Extract)(const UINT32* indices, UINT32 numItems, - INT32 testMode, IArchiveExtractCallback *extractCallback); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback); STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); - STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties); - STDMETHOD(GetPropertyInfo)(UINT32 index, + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType); - STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties); - STDMETHOD(GetArchivePropertyInfo)(UINT32 index, + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType); // IOutArchive - STDMETHOD(UpdateItems)(IOutStream *outStream, UINT32 numItems, + STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback); - STDMETHOD(GetFileTimeType)(UINT32 *type); + STDMETHOD(GetFileTimeType)(UInt32 *type); private: CObjectVector<CItemEx> _items; diff --git a/7zip/Archive/Tar/TarHandlerOut.cpp b/7zip/Archive/Tar/TarHandlerOut.cpp index 93ca7747..a54bb58d 100755 --- a/7zip/Archive/Tar/TarHandlerOut.cpp +++ b/7zip/Archive/Tar/TarHandlerOut.cpp @@ -20,23 +20,23 @@ using namespace NTime; namespace NArchive { namespace NTar { -STDMETHODIMP CHandler::GetFileTimeType(UINT32 *type) +STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type) { *type = NFileTimeType::kUnix; return S_OK; } -STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems, +STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback) { COM_TRY_BEGIN CObjectVector<CUpdateItemInfo> updateItems; - for(UINT32 i = 0; i < numItems; i++) + for(UInt32 i = 0; i < numItems; i++) { CUpdateItemInfo updateItem; - INT32 newData; - INT32 newProperties; - UINT32 indexInArchive; + Int32 newData; + Int32 newProperties; + UInt32 indexInArchive; if (!updateCallback) return E_FAIL; RINOK(updateCallback->GetUpdateItemInfo(i, @@ -51,7 +51,7 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems, FILETIME utcTime; UString name; bool isDirectoryStatusDefined; - UINT32 attributes; + UInt32 attributes; { NCOM::CPropVariant propVariant; RINOK(updateCallback->GetProperty(i, kpidAttributes, &propVariant)); @@ -98,18 +98,19 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems, updateItem.IsDirectory = ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0); if (updateItem.IsDirectory) updateItem.Name += '/'; + if(!FileTimeToUnixTime(utcTime, updateItem.Time)) return E_INVALIDARG; } if (IntToBool(newData)) { - UINT64 size; + UInt64 size; { NCOM::CPropVariant propVariant; RINOK(updateCallback->GetProperty(i, kpidSize, &propVariant)); if (propVariant.vt != VT_UI8) return E_INVALIDARG; - size = *(UINT64 *)(&propVariant.uhVal); + size = propVariant.uhVal.QuadPart; } updateItem.Size = size; } diff --git a/7zip/Archive/Tar/TarHeader.cpp b/7zip/Archive/Tar/TarHeader.cpp index 7b954aa1..9bf408c0 100755 --- a/7zip/Archive/Tar/TarHeader.cpp +++ b/7zip/Archive/Tar/TarHeader.cpp @@ -22,4 +22,3 @@ namespace NFileHeader { } }}} - diff --git a/7zip/Archive/Tar/TarHeader.h b/7zip/Archive/Tar/TarHeader.h index c7bc4785..c32092ca 100755 --- a/7zip/Archive/Tar/TarHeader.h +++ b/7zip/Archive/Tar/TarHeader.h @@ -1,7 +1,5 @@ // Archive/Tar/Header.h -#pragma once - #ifndef __ARCHIVE_TAR_HEADER_H #define __ARCHIVE_TAR_HEADER_H @@ -10,9 +8,6 @@ namespace NArchive { namespace NTar { -#pragma pack( push, PragmaTarHeaders) -#pragma pack( push, 1) - namespace NFileHeader { const int kRecordSize = 512; @@ -20,6 +15,7 @@ namespace NFileHeader const int kUserNameSize = 32; const int kGroupNameSize = 32; + /* struct CHeader { char Name[kNameSize]; @@ -36,17 +32,13 @@ namespace NFileHeader char GroupName[kGroupNameSize]; char DeviceMajor[8]; char DeviceMinor[8]; - /* - BYTE Padding[kRecordSize - (kNameSize + 8 + 8 + 12 + 12 + 8 + 1 + kNameSize + 8 + - kUserNameSize + kGroupNameSize + 8 + 8)]; - */ }; union CRecord { CHeader Header; - BYTE Padding[kRecordSize]; + Byte Padding[kRecordSize]; }; - + */ namespace NMode { @@ -99,9 +91,6 @@ namespace NFileHeader } -#pragma pack(pop) -#pragma pack(pop, PragmaTarHeaders) - }} #endif diff --git a/7zip/Archive/Tar/TarIn.cpp b/7zip/Archive/Tar/TarIn.cpp index e5f31bb1..92045e80 100755 --- a/7zip/Archive/Tar/TarIn.cpp +++ b/7zip/Archive/Tar/TarIn.cpp @@ -10,7 +10,7 @@ namespace NArchive { namespace NTar { -HRESULT CInArchive::ReadBytes(void *data, UINT32 size, UINT32 &processedSize) +HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize) { RINOK(m_Stream->Read(data, size, &processedSize)); m_Position += processedSize; @@ -24,7 +24,7 @@ HRESULT CInArchive::Open(IInStream *inStream) return S_OK; } -static UINT32 OctalToNumber(const char *srcString) +static UInt32 OctalToNumber(const char *srcString) { char *endPtr; return(strtoul(srcString, &endPtr, 8)); @@ -47,86 +47,131 @@ static bool CheckOctalString(const char *srcString, int numChars) #define ReturnIfBadOctal(x, y) { if (!CheckOctalString((x), (y))) return S_FALSE; } -static bool IsRecordLast(const NFileHeader::CRecord &record) +static bool IsRecordLast(const char *record) { - for (int i = 0; i < sizeof(record); i++) - if (record.Padding[i] != 0) + for (int i = 0; i < NFileHeader::kRecordSize; i++) + if (record[i] != 0) return false; return true; } +static void ReadString(const char *s, int size, AString &result) +{ + if (size > NFileHeader::kNameSize) + size = NFileHeader::kNameSize; + char tempString[NFileHeader::kNameSize + 1]; + strncpy(tempString, s, size); + tempString[size] = '\0'; + result = tempString; +} + +static char GetHex(Byte value) +{ + return (value < 10) ? ('0' + value) : ('A' + (value - 10)); +} + HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item) { item.LongLinkSize = 0; - NFileHeader::CRecord record; + // NFileHeader::CRecord record; + char record[NFileHeader::kRecordSize]; + char *cur = record; + filled = false; - UINT32 processedSize; + UInt32 processedSize; item.HeaderPosition = m_Position; - RINOK(ReadBytes(&record, sizeof(record), processedSize)); + RINOK(ReadBytes(record, NFileHeader::kRecordSize, processedSize)); if (processedSize == 0 || - (processedSize == sizeof(record) && IsRecordLast(record))) + (processedSize == NFileHeader::kRecordSize && IsRecordLast(record))) return S_OK; - if (processedSize < sizeof(record)) + if (processedSize < NFileHeader::kRecordSize) return S_FALSE; - NFileHeader::CHeader &header = record.Header; + // NFileHeader::CHeader &header = record.Header; - char tempString[NFileHeader::kNameSize + 1]; - strncpy(tempString, header.Name, NFileHeader::kNameSize); - tempString[NFileHeader::kNameSize] = '\0'; - item.Name = tempString; + AString name; + ReadString(cur, NFileHeader::kNameSize, name); + cur += NFileHeader::kNameSize; + item.Name.Empty(); int i; - for (i = 0; i < item.Name.Length(); i++) - if (((BYTE)item.Name[i]) < 0x20) + for (i = 0; i < name.Length(); i++) + { + char c = name[i]; + if (((Byte)c) < 0x08) + { return S_FALSE; - item.LinkFlag = header.LinkFlag; - - BYTE linkFlag = item.LinkFlag; - - ReturnIfBadOctal(header.Mode, 8); - ReturnIfBadOctal(header.UID, 8); - ReturnIfBadOctal(header.GID, 8); - ReturnIfBadOctal(header.Size, 12); - ReturnIfBadOctal(header.ModificationTime, 12); - ReturnIfBadOctal(header.CheckSum, 8); - ReturnIfBadOctal(header.DeviceMajor, 8); - ReturnIfBadOctal(header.DeviceMinor, 8); - - item.Mode = OctalToNumber(header.Mode); - item.UID = OctalToNumber(header.UID); - item.GID = OctalToNumber(header.GID); - - item.Size = OctalToNumber(header.Size); - if (item.LinkFlag == NFileHeader::NLinkFlag::kLink) - item.Size = 0; + } + if (((Byte)c) < 0x20) + { + item.Name += '['; + item.Name += GetHex(((Byte)c) >> 4); + item.Name += GetHex(((Byte)c) & 0xF); + item.Name += ']'; + } + else + item.Name += c; + } + + ReturnIfBadOctal(cur, 8); + item.Mode = OctalToNumber(cur); + cur += 8; + + ReturnIfBadOctal(cur, 8); + item.UID = OctalToNumber(cur); + cur += 8; + + ReturnIfBadOctal(cur, 8); + item.GID = OctalToNumber(cur); + cur += 8; - item.ModificationTime = OctalToNumber(header.ModificationTime); + ReturnIfBadOctal(cur, 12); + item.Size = OctalToNumber(cur); + cur += 12; + + ReturnIfBadOctal(cur, 12); + item.ModificationTime = OctalToNumber(cur); + cur += 12; + ReturnIfBadOctal(cur, 8); + UInt32 checkSum = OctalToNumber(cur); + memmove(cur, NFileHeader::kCheckSumBlanks, 8); + cur += 8; + + item.LinkFlag = *cur++; + Byte linkFlag = item.LinkFlag; - item.LinkName = header.LinkName; - memmove(item.Magic, header.Magic, 8); + ReadString(cur, NFileHeader::kNameSize, item.LinkName); + cur += NFileHeader::kNameSize; - item.UserName = header.UserName; - item.GroupName = header.GroupName; + memmove(item.Magic, cur, 8); + cur += 8; + ReadString(cur, NFileHeader::kUserNameSize, item.UserName); + cur += NFileHeader::kUserNameSize; + ReadString(cur, NFileHeader::kUserNameSize, item.GroupName); + cur += NFileHeader::kUserNameSize; - item.DeviceMajorDefined = (header.DeviceMajor[0] != 0); + ReturnIfBadOctal(cur, 8); + item.DeviceMajorDefined = (cur[0] != 0); if (item.DeviceMajorDefined) - item.DeviceMajor = OctalToNumber(header.DeviceMajor); - - item.DeviceMinorDefined = (header.DeviceMinor[0] != 0); + item.DeviceMajor = OctalToNumber(cur); + + ReturnIfBadOctal(cur, 8); + item.DeviceMinorDefined = (cur[0] != 0); if (item.DeviceMinorDefined) - item.DeviceMinor = OctalToNumber(header.DeviceMinor); - - UINT32 checkSum = OctalToNumber(header.CheckSum); + item.DeviceMinor = OctalToNumber(cur); + cur += 8; - memmove(header.CheckSum, NFileHeader::kCheckSumBlanks, 8); - UINT32 checkSumReal = 0; + if (item.LinkFlag == NFileHeader::NLinkFlag::kLink) + item.Size = 0; + + + UInt32 checkSumReal = 0; for(i = 0; i < NFileHeader::kRecordSize; i++) - checkSumReal += BYTE(record.Padding[i]); + checkSumReal += Byte(record[i]); if (checkSumReal != checkSum) return S_FALSE; @@ -145,12 +190,12 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item) { if (item.Name.Compare(NFileHeader::kLongLink) != 0) return S_FALSE; - UINT64 headerPosition = item.HeaderPosition; + UInt64 headerPosition = item.HeaderPosition; - UINT32 processedSize; + UInt32 processedSize; AString fullName; - char *buffer = fullName.GetBuffer((UINT32)item.Size + 1); - RINOK(ReadBytes(buffer, (UINT32)item.Size, processedSize)); + char *buffer = fullName.GetBuffer((UInt32)item.Size + 1); + RINOK(ReadBytes(buffer, (UInt32)item.Size, processedSize)); buffer[item.Size] = '\0'; fullName.ReleaseBuffer(); if (processedSize != item.Size) @@ -166,9 +211,9 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item) return S_OK; } -HRESULT CInArchive::Skeep(UINT64 numBytes) +HRESULT CInArchive::Skeep(UInt64 numBytes) { - UINT64 newPostion; + UInt64 newPostion; RINOK(m_Stream->Seek(numBytes, STREAM_SEEK_CUR, &newPostion)); m_Position += numBytes; if (m_Position != newPostion) @@ -177,15 +222,9 @@ HRESULT CInArchive::Skeep(UINT64 numBytes) } -HRESULT CInArchive::SkeepDataRecords(UINT64 dataSize) +HRESULT CInArchive::SkeepDataRecords(UInt64 dataSize) { - return Skeep((dataSize + 511) & - #if ( __GNUC__) - 0xFFFFFFFFFFFFFE00LL - #else - 0xFFFFFFFFFFFFFE00 - #endif - ); + return Skeep((dataSize + 0x1FF) & (~((UInt64)0x1FF))); } }} diff --git a/7zip/Archive/Tar/TarIn.h b/7zip/Archive/Tar/TarIn.h index bac91aee..28781375 100755 --- a/7zip/Archive/Tar/TarIn.h +++ b/7zip/Archive/Tar/TarIn.h @@ -1,7 +1,5 @@ // Archive/TarIn.h -#pragma once - #ifndef __ARCHIVE_TAR_IN_H #define __ARCHIVE_TAR_IN_H @@ -16,15 +14,15 @@ namespace NTar { class CInArchive { CMyComPtr<IInStream> m_Stream; - UINT64 m_Position; + UInt64 m_Position; - HRESULT ReadBytes(void *data, UINT32 size, UINT32 &processedSize); + HRESULT ReadBytes(void *data, UInt32 size, UInt32 &processedSize); public: HRESULT Open(IInStream *inStream); HRESULT GetNextItemReal(bool &filled, CItemEx &itemInfo); HRESULT GetNextItem(bool &filled, CItemEx &itemInfo); - HRESULT Skeep(UINT64 numBytes); - HRESULT SkeepDataRecords(UINT64 dataSize); + HRESULT Skeep(UInt64 numBytes); + HRESULT SkeepDataRecords(UInt64 dataSize); }; }} diff --git a/7zip/Archive/Tar/TarItem.h b/7zip/Archive/Tar/TarItem.h index a63ca6de..7637b537 100755 --- a/7zip/Archive/Tar/TarItem.h +++ b/7zip/Archive/Tar/TarItem.h @@ -1,7 +1,5 @@ // Archive/Tar/Item.h -#pragma once - #ifndef __ARCHIVE_TAR_ITEM_H #define __ARCHIVE_TAR_ITEM_H @@ -9,6 +7,8 @@ #include "Common/Types.h" #include "Common/String.h" + +#include "../Common/ItemNameUtils.h" #include "TarHeader.h" namespace NArchive { @@ -18,11 +18,11 @@ class CItem { public: AString Name; - UINT32 Mode; - UINT32 UID; - UINT32 GID; - UINT64 Size; - time_t ModificationTime; + UInt32 Mode; + UInt32 UID; + UInt32 GID; + UInt64 Size; + UInt32 ModificationTime; char LinkFlag; AString LinkName; char Magic[8]; @@ -30,9 +30,9 @@ public: AString GroupName; bool DeviceMajorDefined; - UINT32 DeviceMajor; + UInt32 DeviceMajor; bool DeviceMinorDefined; - UINT32 DeviceMinor; + UInt32 DeviceMinor; bool IsDirectory() const { @@ -41,13 +41,7 @@ public: if (LinkFlag == NFileHeader::NLinkFlag::kOldNormal || LinkFlag == NFileHeader::NLinkFlag::kNormal) { - if (Name.IsEmpty()) - return false; - #ifdef WIN32 - return (*CharPrevExA(CP_OEMCP, Name, &Name[Name.Length()], 0) == '/'); - #else - return (Name[Name.Length() - 1) == '/'); - #endif + return NItemName::HasTailSlash(Name, CP_OEMCP); } return false; } @@ -56,10 +50,10 @@ public: class CItemEx: public CItem { public: - UINT64 HeaderPosition; - UINT64 LongLinkSize; - UINT64 GetDataPosition() const { return HeaderPosition + LongLinkSize + NFileHeader::kRecordSize; }; - UINT64 GetFullSize() const { return LongLinkSize + NFileHeader::kRecordSize + Size; }; + UInt64 HeaderPosition; + UInt64 LongLinkSize; + UInt64 GetDataPosition() const { return HeaderPosition + LongLinkSize + NFileHeader::kRecordSize; }; + UInt64 GetFullSize() const { return LongLinkSize + NFileHeader::kRecordSize + Size; }; }; }} diff --git a/7zip/Archive/Tar/TarOut.cpp b/7zip/Archive/Tar/TarOut.cpp index ab05309a..45c7ef1d 100755 --- a/7zip/Archive/Tar/TarOut.cpp +++ b/7zip/Archive/Tar/TarOut.cpp @@ -5,14 +5,15 @@ #include "TarOut.h" #include "TarHeader.h" +#include "Common/IntToString.h" #include "Windows/Defs.h" namespace NArchive { namespace NTar { -HRESULT COutArchive::WriteBytes(const void *buffer, UINT32 size) +HRESULT COutArchive::WriteBytes(const void *buffer, UInt32 size) { - UINT32 processedSize; + UInt32 processedSize; RINOK(m_Stream->Write(buffer, size, &processedSize)); if(processedSize != size) return E_FAIL; @@ -24,14 +25,14 @@ void COutArchive::Create(ISequentialOutStream *outStream) m_Stream = outStream; } -static AString MakeOctalString(UINT64 value) +static AString MakeOctalString(UInt64 value) { char s[32]; - _ui64toa(value, s, 8); + ConvertUInt64ToString(value, s, 8); return AString(s) + ' '; } -static bool MakeOctalString8(char *s, UINT32 value) +static bool MakeOctalString8(char *s, UInt32 value) { AString tempString = MakeOctalString(value); @@ -45,7 +46,7 @@ static bool MakeOctalString8(char *s, UINT32 value) return true; } -static bool MakeOctalString12(char *s, UINT64 value) +static bool MakeOctalString12(char *s, UInt64 value) { AString tempString = MakeOctalString(value); const int kMaxSize = 12; @@ -70,45 +71,63 @@ static bool CopyString(char *dest, const AString &src, int maxSize) HRESULT COutArchive::WriteHeaderReal(const CItem &item) { - NFileHeader::CRecord record; + char record[NFileHeader::kRecordSize]; + char *cur = record; int i; for (i = 0; i < NFileHeader::kRecordSize; i++) - record.Padding[i] = 0; - - NFileHeader::CHeader &header = record.Header; + record[i] = 0; // RETURN_IF_NOT_TRUE(CopyString(header.Name, item.Name, NFileHeader::kNameSize)); if (item.Name.Length() > NFileHeader::kNameSize) return E_FAIL; - strncpy(header.Name, item.Name, NFileHeader::kNameSize); + strncpy(cur, item.Name, NFileHeader::kNameSize); + cur += NFileHeader::kNameSize; + + RETURN_IF_NOT_TRUE(MakeOctalString8(cur, item.Mode)); + cur += 8; + RETURN_IF_NOT_TRUE(MakeOctalString8(cur, item.UID)); + cur += 8; + RETURN_IF_NOT_TRUE(MakeOctalString8(cur, item.GID)); + cur += 8; + + RETURN_IF_NOT_TRUE(MakeOctalString12(cur, item.Size)); + cur += 12; + RETURN_IF_NOT_TRUE(MakeOctalString12(cur, item.ModificationTime)); + cur += 12; + + memmove(cur, NFileHeader::kCheckSumBlanks, 8); + cur += 8; - RETURN_IF_NOT_TRUE(CopyString(header.LinkName, item.LinkName, NFileHeader::kNameSize)); - RETURN_IF_NOT_TRUE(CopyString(header.UserName, item.UserName, NFileHeader::kUserNameSize)); - RETURN_IF_NOT_TRUE(CopyString(header.GroupName, item.GroupName, NFileHeader::kGroupNameSize)); + *cur++ = item.LinkFlag; - RETURN_IF_NOT_TRUE(MakeOctalString8(header.Mode, item.Mode)); - RETURN_IF_NOT_TRUE(MakeOctalString8(header.UID, item.UID)); - RETURN_IF_NOT_TRUE(MakeOctalString8(header.GID, item.GID)); + RETURN_IF_NOT_TRUE(CopyString(cur, item.LinkName, NFileHeader::kNameSize)); + cur += NFileHeader::kNameSize; + + memmove(cur, item.Magic, 8); + cur += 8; + + RETURN_IF_NOT_TRUE(CopyString(cur, item.UserName, NFileHeader::kUserNameSize)); + cur += NFileHeader::kUserNameSize; + RETURN_IF_NOT_TRUE(CopyString(cur, item.GroupName, NFileHeader::kGroupNameSize)); + cur += NFileHeader::kUserNameSize; - RETURN_IF_NOT_TRUE(MakeOctalString12(header.Size, item.Size)); - RETURN_IF_NOT_TRUE(MakeOctalString12(header.ModificationTime, item.ModificationTime)); - header.LinkFlag = item.LinkFlag; - memmove(header.Magic, item.Magic, 8); if (item.DeviceMajorDefined) - RETURN_IF_NOT_TRUE(MakeOctalString8(header.DeviceMajor, item.DeviceMajor)); + RETURN_IF_NOT_TRUE(MakeOctalString8(cur, item.DeviceMajor)); + cur += 8; + if (item.DeviceMinorDefined) - RETURN_IF_NOT_TRUE(MakeOctalString8(header.DeviceMinor, item.DeviceMinor)); + RETURN_IF_NOT_TRUE(MakeOctalString8(cur, item.DeviceMinor)); + cur += 8; - memmove(header.CheckSum, NFileHeader::kCheckSumBlanks, 8); - UINT32 checkSumReal = 0; + UInt32 checkSumReal = 0; for(i = 0; i < NFileHeader::kRecordSize; i++) - checkSumReal += BYTE(record.Padding[i]); + checkSumReal += Byte(record[i]); - RETURN_IF_NOT_TRUE(MakeOctalString8(header.CheckSum, checkSumReal)); + RETURN_IF_NOT_TRUE(MakeOctalString8(record + 148, checkSumReal)); - return WriteBytes(&record, sizeof(record)); + return WriteBytes(record, NFileHeader::kRecordSize); } HRESULT COutArchive::WriteHeader(const CItem &item) @@ -132,24 +151,24 @@ HRESULT COutArchive::WriteHeader(const CItem &item) return WriteHeaderReal(modifiedItem); } -HRESULT COutArchive::FillDataResidual(UINT64 dataSize) +HRESULT COutArchive::FillDataResidual(UInt64 dataSize) { - UINT32 lastRecordSize = UINT32(dataSize & (NFileHeader::kRecordSize - 1)); + UInt32 lastRecordSize = UInt32(dataSize & (NFileHeader::kRecordSize - 1)); if (lastRecordSize == 0) return S_OK; - UINT32 residualSize = NFileHeader::kRecordSize - lastRecordSize; - BYTE residualBytes[NFileHeader::kRecordSize]; - for (UINT32 i = 0; i < residualSize; i++) + UInt32 residualSize = NFileHeader::kRecordSize - lastRecordSize; + Byte residualBytes[NFileHeader::kRecordSize]; + for (UInt32 i = 0; i < residualSize; i++) residualBytes[i] = 0; return WriteBytes(residualBytes, residualSize); } HRESULT COutArchive::WriteFinishHeader() { - NFileHeader::CRecord record; + char record[NFileHeader::kRecordSize]; for (int i = 0; i < NFileHeader::kRecordSize; i++) - record.Padding[i] = 0; - return WriteBytes(&record, sizeof(record)); + record[i] = 0; + return WriteBytes(record, NFileHeader::kRecordSize); } }} diff --git a/7zip/Archive/Tar/TarOut.h b/7zip/Archive/Tar/TarOut.h index 73a50db9..ef837869 100755 --- a/7zip/Archive/Tar/TarOut.h +++ b/7zip/Archive/Tar/TarOut.h @@ -1,7 +1,5 @@ // Archive/TarOut.h -#pragma once - #ifndef __ARCHIVE_TAR_OUT_H #define __ARCHIVE_TAR_OUT_H @@ -16,12 +14,12 @@ namespace NTar { class COutArchive { CMyComPtr<ISequentialOutStream> m_Stream; - HRESULT WriteBytes(const void *buffer, UINT32 size); + HRESULT WriteBytes(const void *buffer, UInt32 size); public: void Create(ISequentialOutStream *outStream); HRESULT WriteHeaderReal(const CItem &item); HRESULT WriteHeader(const CItem &item); - HRESULT FillDataResidual(UINT64 dataSize); + HRESULT FillDataResidual(UInt64 dataSize); HRESULT WriteFinishHeader(); }; diff --git a/7zip/Archive/Tar/TarUpdate.cpp b/7zip/Archive/Tar/TarUpdate.cpp index d84b0dab..98133fb1 100755 --- a/7zip/Archive/Tar/TarUpdate.cpp +++ b/7zip/Archive/Tar/TarUpdate.cpp @@ -13,14 +13,14 @@ #include "TarOut.h" #include "TarUpdate.h" -static const UINT64 kOneItemComplexity = 512; +static const UInt64 kOneItemComplexity = 512; namespace NArchive { namespace NTar { static HRESULT CopyBlock(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress, - UINT64 *totalSize = NULL) + UInt64 *totalSize = NULL) { NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; @@ -38,7 +38,7 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, COutArchive outArchive; outArchive.Create(outStream); - UINT64 complexity = 0; + UInt64 complexity = 0; int i; for(i = 0; i < updateItems.Size(); i++) @@ -99,28 +99,31 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, if (updateItem.NewData) { item.Size = updateItem.Size; + if (item.Size == UInt64(Int64(-1))) + return E_INVALIDARG; } else { const CItemEx &existItemInfo = inputItems[updateItem.IndexInArchive]; item.Size = existItemInfo.Size; } - if (updateItem.NewData || updateItem.NewProperties) - { - RINOK(outArchive.WriteHeader(item)); - } - + if (updateItem.NewData) { - CMyComPtr<IInStream> fileInStream; - RINOK(updateCallback->GetStream(updateItem.IndexInClient, &fileInStream)); - if (!updateItem.IsDirectory) + CMyComPtr<ISequentialInStream> fileInStream; + HRESULT res = updateCallback->GetStream(updateItem.IndexInClient, &fileInStream); + if (res != S_FALSE) { - UINT64 totalSize; - RINOK(CopyBlock(fileInStream, outStream, compressProgress, &totalSize)); - if (totalSize != item.Size) - return E_FAIL; - RINOK(outArchive.FillDataResidual(item.Size)); + RINOK(res); + RINOK(outArchive.WriteHeader(item)); + if (!updateItem.IsDirectory) + { + UInt64 totalSize; + RINOK(CopyBlock(fileInStream, outStream, compressProgress, &totalSize)); + if (totalSize != item.Size) + return E_FAIL; + RINOK(outArchive.FillDataResidual(item.Size)); + } } complexity += updateItem.Size; RINOK(updateCallback->SetOperationResult( @@ -133,6 +136,7 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, const CItemEx &existItemInfo = inputItems[updateItem.IndexInArchive]; if (updateItem.NewProperties) { + RINOK(outArchive.WriteHeader(item)); RINOK(inStream->Seek(existItemInfo.GetDataPosition(), STREAM_SEEK_SET, NULL)); streamSpec->Init(inStream, existItemInfo.Size); diff --git a/7zip/Archive/Tar/TarUpdate.h b/7zip/Archive/Tar/TarUpdate.h index cd84dae4..92f5cebb 100755 --- a/7zip/Archive/Tar/TarUpdate.h +++ b/7zip/Archive/Tar/TarUpdate.h @@ -1,7 +1,5 @@ // Tar/Update.h -#pragma once - #ifndef __TAR_UPDATE_H #define __TAR_UPDATE_H @@ -22,8 +20,8 @@ struct CUpdateItemInfo int IndexInArchive; int IndexInClient; - time_t Time; - UINT64 Size; + UInt32 Time; + UInt64 Size; AString Name; bool IsDirectory; }; diff --git a/7zip/Archive/Tar/resource.rc b/7zip/Archive/Tar/resource.rc index 8fb4e242..33ef30b2 100755 --- a/7zip/Archive/Tar/resource.rc +++ b/7zip/Archive/Tar/resource.rc @@ -75,8 +75,8 @@ IDI_ICON1 ICON DISCARDABLE "Tar.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,9,2,0 - PRODUCTVERSION 3,9,2,0 + FILEVERSION 4,13,0,0 + PRODUCTVERSION 4,13,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -94,14 +94,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Igor Pavlov\0" VALUE "FileDescription", "Tar Plugin for 7-Zip\0" - VALUE "FileVersion", "3, 9, 2, 0\0" + VALUE "FileVersion", "4, 13, 0, 0\0" VALUE "InternalName", "tar\0" - VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2004 Igor Pavlov\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "tar.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "7-Zip\0" - VALUE "ProductVersion", "3, 9, 2, 0\0" + VALUE "ProductVersion", "4, 13, 0, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/7zip/Archive/Z/DllExports.cpp b/7zip/Archive/Z/DllExports.cpp new file mode 100755 index 00000000..df530a44 --- /dev/null +++ b/7zip/Archive/Z/DllExports.cpp @@ -0,0 +1,104 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" +#include "Windows/PropVariant.h" +#include "ZHandler.h" +#include "../../ICoder.h" + +// {23170F69-40C1-278B-0402-050000000000} +DEFINE_GUID(CLSID_CCompressZDecoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00); + +// {23170F69-40C1-278A-1000-0001100D0000} +DEFINE_GUID(CLSID_CZHandler, +0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x0D, 0x00, 0x00); + +HINSTANCE g_hInstance; + +#ifndef COMPRESS_BZIP2 +#include "../Common/CodecsPath.h" +CSysString GetBZip2CodecPath() +{ + return GetCodecsFolderPrefix() + TEXT("BZip2.dll"); +} +#endif + +extern "C" +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) +{ + if (dwReason == DLL_PROCESS_ATTACH) + g_hInstance = hInstance; + return TRUE; +} + +STDAPI CreateObject( + const GUID *classID, + const GUID *interfaceID, + void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + if (*classID != CLSID_CZHandler) + return CLASS_E_CLASSNOTAVAILABLE; + int needIn = *interfaceID == IID_IInArchive; + int needOut = *interfaceID == IID_IOutArchive; + if (needIn || needOut) + { + NArchive::NZ::CHandler *temp = new NArchive::NZ::CHandler; + if (needIn) + { + CMyComPtr<IInArchive> inArchive = (IInArchive *)temp; + *outObject = inArchive.Detach(); + } + else + { + CMyComPtr<IOutArchive> outArchive = (IOutArchive *)temp; + *outObject = outArchive.Detach(); + } + } + else + return E_NOINTERFACE; + COM_TRY_END + return S_OK; +} + + +STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant propVariant; + switch(propID) + { + case NArchive::kName: + propVariant = L"Z"; + break; + case NArchive::kClassID: + { + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CZHandler, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NArchive::kExtension: + propVariant = L"z"; + break; + case NArchive::kUpdate: + propVariant = false; + break; + case NArchive::kKeepName: + propVariant = true; + break; + case NArchive::kStartSignature: + { + const unsigned char sig[] = { 0x1F, 0x9D }; + if ((value->bstrVal = ::SysAllocStringByteLen((const char *)sig, 2)) != 0) + value->vt = VT_BSTR; + return S_OK; + } + + } + propVariant.Detach(value); + return S_OK; +} diff --git a/7zip/Archive/Z/StdAfx.cpp b/7zip/Archive/Z/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/7zip/Archive/Z/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/7zip/Archive/Z/StdAfx.h b/7zip/Archive/Z/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/7zip/Archive/Z/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/7zip/Archive/Z/Z.def b/7zip/Archive/Z/Z.def new file mode 100755 index 00000000..9b992292 --- /dev/null +++ b/7zip/Archive/Z/Z.def @@ -0,0 +1,8 @@ +; Z.def + +LIBRARY z.dll + +EXPORTS + CreateObject PRIVATE + GetHandlerProperty PRIVATE + diff --git a/7zip/Archive/Z/Z.dsp b/7zip/Archive/Z/Z.dsp new file mode 100755 index 00000000..47a2c1ae --- /dev/null +++ b/7zip/Archive/Z/Z.dsp @@ -0,0 +1,253 @@ +# Microsoft Developer Studio Project File - Name="Z" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Z - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Z.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Z.mak" CFG="Z - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Z - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Z - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Z - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Formats\z.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Z - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Formats\z.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Z - Win32 Release" +# Name "Z - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.h +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# Begin Source File + +SOURCE=.\Z.def +# End Source File +# Begin Source File + +SOURCE=.\Z.ico +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# End Group +# Begin Group "Compression" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Z\ZDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Z\ZDecoder.h +# End Source File +# End Group +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\CodecsPath.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\CodecsPath.h +# End Source File +# Begin Source File + +SOURCE=..\Common\CoderLoader.h +# End Source File +# Begin Source File + +SOURCE=..\Common\DummyOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\DummyOutStream.h +# End Source File +# End Group +# Begin Group "Engine" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\ZHandler.cpp +# End Source File +# Begin Source File + +SOURCE=.\ZHandler.h +# End Source File +# End Group +# Begin Group "7zip common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\z.ico +# End Source File +# End Target +# End Project diff --git a/7zip/Archive/Z/Z.dsw b/7zip/Archive/Z/Z.dsw new file mode 100755 index 00000000..1f67186a --- /dev/null +++ b/7zip/Archive/Z/Z.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Z"=.\Z.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/7zip/Archive/Z/Z.ico b/7zip/Archive/Z/Z.ico Binary files differnew file mode 100755 index 00000000..2db53583 --- /dev/null +++ b/7zip/Archive/Z/Z.ico diff --git a/7zip/Archive/Z/ZHandler.cpp b/7zip/Archive/Z/ZHandler.cpp new file mode 100755 index 00000000..e7b13a75 --- /dev/null +++ b/7zip/Archive/Z/ZHandler.cpp @@ -0,0 +1,201 @@ +// ZHandler.cpp + +#include "StdAfx.h" + +#include "ZHandler.h" + +#include "Common/Defs.h" + +#include "../../Common/ProgressUtils.h" +#include "../../Compress/Z/ZDecoder.h" + +#include "Windows/PropVariant.h" +#include "Windows/Defs.h" +#include "Common/ComTry.h" + +#include "../Common/DummyOutStream.h" + +namespace NArchive { +namespace NZ { + +STATPROPSTG kProperties[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidPackedSize, VT_UI8}, +}; + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +{ + value->vt = VT_EMPTY; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) +{ + *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); + return S_OK; +} + +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + if(index >= sizeof(kProperties) / sizeof(kProperties[0])) + return E_INVALIDARG; + const STATPROPSTG &srcItem = kProperties[index]; + *propID = srcItem.propid; + *varType = srcItem.vt; + *name = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) +{ + *numProperties = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + return E_INVALIDARG; +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = 1; + return S_OK; +} + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant propVariant; + if (index != 0) + return E_INVALIDARG; + switch(propID) + { + case kpidIsFolder: + propVariant = false; + break; + case kpidPackedSize: + propVariant = _packSize; + break; + } + propVariant.Detach(value); + return S_OK; + COM_TRY_END +} + +static const int kSignatureSize = 3; + +STDMETHODIMP CHandler::Open(IInStream *stream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openArchiveCallback) +{ + COM_TRY_BEGIN + try + { + RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_streamStartPosition)); + Byte buffer[kSignatureSize]; + UInt32 processedSize; + RINOK(stream->Read(buffer, kSignatureSize, &processedSize)); + if (processedSize != kSignatureSize) + return S_FALSE; + if (buffer[0] != 0x1F || buffer[1] != 0x9D) + return S_FALSE; + _properties = buffer[2]; + + UInt64 endPosition; + RINOK(stream->Seek(0, STREAM_SEEK_END, &endPosition)); + _packSize = endPosition - _streamStartPosition - kSignatureSize; + + _stream = stream; + } + catch(...) + { + return S_FALSE; + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + _stream.Release(); + return S_OK; +} + + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 testModeSpec, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool allFilesMode = (numItems == (UInt32)(-1)); + if (!allFilesMode) + { + if (numItems == 0) + return S_OK; + if (numItems != 1) + return E_INVALIDARG; + if (indices[0] != 0) + return E_INVALIDARG; + } + + bool testMode = (testModeSpec != 0); + + extractCallback->SetTotal(_packSize); + + UInt64 currentTotalPacked = 0; + + RINOK(extractCallback->SetCompleted(¤tTotalPacked)); + + CMyComPtr<ISequentialOutStream> realOutStream; + Int32 askMode; + askMode = testMode ? NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + + RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); + + if(!testMode && !realOutStream) + return S_OK; + + extractCallback->PrepareOperation(askMode); + + CDummyOutStream *outStreamSpec = new CDummyOutStream; + CMyComPtr<ISequentialOutStream> outStream(outStreamSpec); + outStreamSpec->Init(realOutStream); + + realOutStream.Release(); + + CLocalProgress *localProgressSpec = new CLocalProgress; + CMyComPtr<ICompressProgressInfo> progress = localProgressSpec; + localProgressSpec->Init(extractCallback, true); + + RINOK(_stream->Seek(_streamStartPosition + kSignatureSize, STREAM_SEEK_SET, NULL)); + + CMyComPtr<ICompressCoder> decoder; + NCompress::NZ::CDecoder *decoderSpec = new NCompress::NZ::CDecoder; + decoder = decoderSpec; + + HRESULT result = decoderSpec->SetDecoderProperties2(&_properties, 1); + + int opResult; + if (result != S_OK) + opResult = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + else + { + result = decoder->Code(_stream, outStream, NULL, NULL, progress); + outStream.Release(); + if (result == S_FALSE) + opResult = NArchive::NExtract::NOperationResult::kDataError; + else if (result == S_OK) + opResult = NArchive::NExtract::NOperationResult::kOK; + else + return result; + } + RINOK(extractCallback->SetOperationResult(opResult)); + return S_OK; + COM_TRY_END +} + +}} diff --git a/7zip/Archive/Z/ZHandler.h b/7zip/Archive/Z/ZHandler.h new file mode 100755 index 00000000..7abba29f --- /dev/null +++ b/7zip/Archive/Z/ZHandler.h @@ -0,0 +1,47 @@ +// ZHandler.h + +#ifndef __Z_HANDLER_H +#define __Z_HANDLER_H + +#include "Common/MyCom.h" +#include "../IArchive.h" + +namespace NArchive { +namespace NZ { + +class CHandler: + public IInArchive, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + STDMETHOD(Open)(IInStream *stream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openArchiveCallback); + STDMETHOD(Close)(); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback); + + STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); + + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + +private: + CMyComPtr<IInStream> _stream; + UInt64 _streamStartPosition; + UInt64 _packSize; + Byte _properties; +}; + +}} + +#endif diff --git a/7zip/Archive/Z/resource.h b/7zip/Archive/Z/resource.h new file mode 100755 index 00000000..7b0dd8ff --- /dev/null +++ b/7zip/Archive/Z/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by resource.rc +// +#define IDI_ICON1 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/7zip/Archive/Z/resource.rc b/7zip/Archive/Z/resource.rc new file mode 100755 index 00000000..cce458da --- /dev/null +++ b/7zip/Archive/Z/resource.rc @@ -0,0 +1,130 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Russian resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS) +#ifdef _WIN32 +LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT +#pragma code_page(1251) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // Russian resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON1 ICON DISCARDABLE "z.ico" + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 4,15,0,0 + PRODUCTVERSION 4,15,0,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", "Igor Pavlov\0" + VALUE "FileDescription", "Z Plugin for 7-Zip\0" + VALUE "FileVersion", "4, 15, 0, 0\0" + VALUE "InternalName", "z\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "z.dll\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "7-Zip\0" + VALUE "ProductVersion", "4, 15, 0, 0\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // !_MAC + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/7zip/Archive/Zip/DllExports.cpp b/7zip/Archive/Zip/DllExports.cpp index 935f43f7..0ecb3bcd 100755 --- a/7zip/Archive/Zip/DllExports.cpp +++ b/7zip/Archive/Zip/DllExports.cpp @@ -2,8 +2,7 @@ #include "StdAfx.h" -#include <initguid.h> - +#include "Common/MyInitGuid.h" #include "Common/ComTry.h" #include "ZipHandler.h" #include "Windows/PropVariant.h" @@ -116,6 +115,13 @@ STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) case NArchive::kKeepName: propVariant = false; break; + case NArchive::kStartSignature: + { + const char sig[] = { 0x50, 0x4B, 0x03, 0x04 }; + if ((value->bstrVal = ::SysAllocStringByteLen(sig, 4)) != 0) + value->vt = VT_BSTR; + return S_OK; + } } propVariant.Detach(value); return S_OK; diff --git a/7zip/Archive/Zip/StdAfx.cpp b/7zip/Archive/Zip/StdAfx.cpp index 2550270c..d0feea85 100755 --- a/7zip/Archive/Zip/StdAfx.cpp +++ b/7zip/Archive/Zip/StdAfx.cpp @@ -1,3 +1,3 @@ // StdAfx.cpp -#include "stdafx.h" +#include "StdAfx.h" diff --git a/7zip/Archive/Zip/StdAfx.h b/7zip/Archive/Zip/StdAfx.h index 8cd49d6c..e7fb6986 100755 --- a/7zip/Archive/Zip/StdAfx.h +++ b/7zip/Archive/Zip/StdAfx.h @@ -1,31 +1,8 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> -#include <time.h> -#include <limits.h> +#include "../../../Common/MyWindows.h" -#include <memory> - -/* -#define _ATL_APARTMENT_THREADED -// #define _ATL_FREE_THREADED - - -#define _ATL_NO_UUIDOF - -#include <atlbase.h> - -extern CComModule _Module; - -#include <atlcom.h> -#include <shlobj.h> -#include <shlguid.h> - -#include <new.h> - -*/ - -#endif +#endif diff --git a/7zip/Archive/Zip/Zip.dsp b/7zip/Archive/Zip/Zip.dsp index 0d3efa5d..c54f488b 100755 --- a/7zip/Archive/Zip/Zip.dsp +++ b/7zip/Archive/Zip/Zip.dsp @@ -43,7 +43,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 1 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZIP_EXPORTS" /YX /FD /c -# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZIP_EXPORTS" /D "CRYPTO_ZIP" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZIP_EXPORTS" /Yu"StdAfx.h" /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "NDEBUG" @@ -70,7 +70,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 1 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZIP_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZIP_EXPORTS" /D "CRYPTO_ZIP" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZIP_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "_DEBUG" @@ -122,6 +122,22 @@ SOURCE=.\Zip.def # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\AutoPtr.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Buffer.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\CRC.cpp # End Source File # Begin Source File @@ -218,23 +234,27 @@ SOURCE=..\Common\CodecsPath.h # End Source File # Begin Source File +SOURCE=..\Common\CoderLoader.cpp +# End Source File +# Begin Source File + SOURCE=..\Common\CoderLoader.h # End Source File # Begin Source File -SOURCE=..\Common\CoderMixer.cpp +SOURCE=..\Common\CrossThreadProgress.cpp # End Source File # Begin Source File -SOURCE=..\Common\CoderMixer.h +SOURCE=..\Common\CrossThreadProgress.h # End Source File # Begin Source File -SOURCE=..\Common\CrossThreadProgress.cpp +SOURCE=..\Common\FilterCoder.cpp # End Source File # Begin Source File -SOURCE=..\Common\CrossThreadProgress.h +SOURCE=..\Common\FilterCoder.h # End Source File # Begin Source File @@ -266,6 +286,14 @@ SOURCE=..\Common\OutStreamWithCRC.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + SOURCE=..\..\Common\LimitedStreams.cpp # End Source File # Begin Source File @@ -274,6 +302,14 @@ SOURCE=..\..\Common\LimitedStreams.h # End Source File # Begin Source File +SOURCE=..\..\Common\LSBFDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LSBFDecoder.h +# End Source File +# Begin Source File + SOURCE=..\..\Common\OffsetStream.cpp # End Source File # Begin Source File @@ -282,6 +318,14 @@ SOURCE=..\..\Common\OffsetStream.h # End Source File # Begin Source File +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + SOURCE=..\..\Common\ProgressUtils.cpp # End Source File # Begin Source File @@ -377,65 +421,109 @@ SOURCE=.\ZipUpdate.cpp SOURCE=.\ZipUpdate.h # End Source File # End Group -# Begin Group "copy" +# Begin Group "Crypto" # PROP Default_Filter "" # Begin Source File -SOURCE=..\..\Compress\Copy\CopyCoder.cpp +SOURCE=..\..\Crypto\Zip\ZipCipher.cpp # End Source File # Begin Source File -SOURCE=..\..\Compress\Copy\CopyCoder.h +SOURCE=..\..\Crypto\Zip\ZipCipher.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Zip\ZipCrypto.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Zip\ZipCrypto.h # End Source File # End Group -# Begin Group "Format Common" +# Begin Group "7z" # PROP Default_Filter "" +# Begin Source File + +SOURCE=..\7z\7zMethodID.cpp +# End Source File +# Begin Source File + +SOURCE=..\7z\7zMethodID.h +# End Source File +# Begin Source File + +SOURCE=..\7z\7zMethods.cpp +# End Source File +# Begin Source File + +SOURCE=..\7z\7zMethods.h +# End Source File # End Group -# Begin Group "Crypto" +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Group "Shrink" # PROP Default_Filter "" # Begin Source File -SOURCE=..\..\Crypto\Zip\ZipCipher.cpp +SOURCE=..\..\Compress\Shrink\ShrinkDecoder.cpp # End Source File # Begin Source File -SOURCE=..\..\Crypto\Zip\ZipCipher.h +SOURCE=..\..\Compress\Shrink\ShrinkDecoder.h # End Source File +# End Group +# Begin Group "copy" + +# PROP Default_Filter "" # Begin Source File -SOURCE=..\..\Crypto\Zip\ZipCrypto.cpp +SOURCE=..\..\Compress\Copy\CopyCoder.cpp # End Source File # Begin Source File -SOURCE=..\..\Crypto\Zip\ZipCrypto.h +SOURCE=..\..\Compress\Copy\CopyCoder.h # End Source File # End Group -# Begin Group "7z" +# Begin Group "Implode" # PROP Default_Filter "" # Begin Source File -SOURCE=..\7z\7zMethods.cpp +SOURCE=..\..\Compress\Implode\ImplodeDecoder.cpp # End Source File # Begin Source File -SOURCE=..\7z\7zMethods.h +SOURCE=..\..\Compress\Implode\ImplodeDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Implode\ImplodeHuffmanDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Implode\ImplodeHuffmanDecoder.h # End Source File # End Group +# Begin Group "LZ" + +# PROP Default_Filter "" # Begin Source File -SOURCE=".\7-zip.ico" +SOURCE=..\..\Compress\LZ\LZOutWindow.cpp # End Source File # Begin Source File -SOURCE=.\zip.ico +SOURCE=..\..\Compress\LZ\LZOutWindow.h # End Source File +# End Group +# End Group # Begin Source File -SOURCE=.\zip1.ico +SOURCE=.\zip.ico # End Source File # End Target # End Project diff --git a/7zip/Archive/Zip/ZipAddCommon.cpp b/7zip/Archive/Zip/ZipAddCommon.cpp index edbf7672..8c259c33 100755 --- a/7zip/Archive/Zip/ZipAddCommon.cpp +++ b/7zip/Archive/Zip/ZipAddCommon.cpp @@ -48,24 +48,24 @@ DEFINE_GUID(CLSID_CCryptoZipEncoder, namespace NArchive { namespace NZip { -static const BYTE kMethodIDForEmptyStream = NFileHeader::NCompressionMethod::kStored; -static const BYTE kExtractVersionForEmptyStream = NFileHeader::NCompressionMethod::kStoreExtractVersion; +static const Byte kMethodIDForEmptyStream = NFileHeader::NCompressionMethod::kStored; +static const Byte kExtractVersionForEmptyStream = NFileHeader::NCompressionMethod::kStoreExtractVersion; CAddCommon::CAddCommon(const CCompressionMethodMode &options): _options(options), _copyCoderSpec(NULL), - _mixerCoderSpec(0) + _cryptoStreamSpec(0) {} -static HRESULT GetStreamCRC(IInStream *inStream, UINT32 &resultCRC) +static HRESULT GetStreamCRC(IInStream *inStream, UInt32 &resultCRC) { CCRC crc; crc.Init(); - const UINT32 kBufferSize = (1 << 14); - BYTE buffer[kBufferSize]; + const UInt32 kBufferSize = (1 << 14); + Byte buffer[kBufferSize]; while(true) { - UINT32 realProcessedSize; + UInt32 realProcessedSize; RINOK(inStream->Read(buffer, kBufferSize, &realProcessedSize)); if(realProcessedSize == 0) { @@ -77,7 +77,7 @@ static HRESULT GetStreamCRC(IInStream *inStream, UINT32 &resultCRC) } HRESULT CAddCommon::Compress(IInStream *inStream, IOutStream *outStream, - UINT64 inSize, ICompressProgressInfo *progress, CCompressingResult &operationResult) + UInt64 inSize, ICompressProgressInfo *progress, CCompressingResult &operationResult) { /* if(inSize == 0) @@ -89,40 +89,33 @@ HRESULT CAddCommon::Compress(IInStream *inStream, IOutStream *outStream, } */ int numTestMethods = _options.MethodSequence.Size(); - BYTE method; - UINT64 resultSize = 0; + Byte method; + UInt64 resultSize = 0; + COutStreamReleaser outStreamReleaser; for(int i = 0; i < numTestMethods; i++) { + RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(outStream->Seek(0, STREAM_SEEK_SET, NULL)); if (_options.PasswordIsDefined) { - if (!_cryptoEncoder) + if (!_cryptoStream) { - #ifdef CRYPTO_ZIP - _cryptoEncoder = new NCrypto::NZip::CEncoder; - #else - // change it; - /* - RINOK(_cryptoLib.LoadAndCreateCoder( - GetBaseFolderPrefix() + TEXT("\\Crypto\\Zip.dll"), - CLSID_CCryptoZipEncoder, &_cryptoEncoder)); - */ - #endif + _cryptoStreamSpec = new CFilterCoder; + _cryptoStream = _cryptoStreamSpec; + _filterSpec = new NCrypto::NZip::CEncoder; + _cryptoStreamSpec->Filter = _filterSpec; } - CMyComPtr<ICryptoSetPassword> cryptoSetPassword; - RINOK(_cryptoEncoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword)); - RINOK(cryptoSetPassword->CryptoSetPassword( - (const BYTE *)(const char *)_options.Password, _options.Password.Length())); - UINT32 crc; - RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(_filterSpec->CryptoSetPassword( + (const Byte *)(const char *)_options.Password, _options.Password.Length())); + UInt32 crc; RINOK(GetStreamCRC(inStream, crc)); - CMyComPtr<ICryptoSetCRC> cryptoSetCRC; - RINOK(_cryptoEncoder.QueryInterface(IID_ICryptoSetCRC, &cryptoSetCRC)); - RINOK(cryptoSetCRC->CryptoSetCRC(crc)); + RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(_cryptoStreamSpec->SetOutStream(outStream)); + outStreamReleaser.FilterCoder = _cryptoStreamSpec; + RINOK(_filterSpec->CryptoSetCRC(crc)); + RINOK(_filterSpec->WriteHeader(outStream)); } - RINOK(outStream->Seek(0, STREAM_SEEK_SET, NULL)); - RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL)); - method = _options.MethodSequence[i]; switch(method) { @@ -133,30 +126,13 @@ HRESULT CAddCommon::Compress(IInStream *inStream, IOutStream *outStream, _copyCoderSpec = new NCompress::CCopyCoder; _copyCoder = _copyCoderSpec; } + CMyComPtr<ISequentialOutStream> outStreamNew; if (_options.PasswordIsDefined) - { - if (!_mixerCoder || _mixerCoderMethod != method) - { - _mixerCoder.Release(); - _mixerCoderSpec = new CCoderMixer; - _mixerCoder = _mixerCoderSpec; - _mixerCoderSpec->AddCoder(_copyCoder); - _mixerCoderSpec->AddCoder(_cryptoEncoder); - _mixerCoderSpec->FinishAddingCoders(); - _mixerCoderMethod = method; - } - _mixerCoderSpec->ReInit(); - _mixerCoderSpec->SetCoderInfo(0, NULL, NULL); - _mixerCoderSpec->SetCoderInfo(1, NULL, NULL); - _mixerCoderSpec->SetProgressCoderIndex(0); - RINOK(_mixerCoder->Code(inStream, outStream, - NULL, NULL, progress)); - } + outStreamNew = _cryptoStream; else - { - RINOK(_copyCoder->Code(inStream, outStream, + outStreamNew = outStream; + RINOK(_copyCoder->Code(inStream, outStreamNew, NULL, NULL, progress)); - } operationResult.ExtractVersion = NFileHeader::NCompressionMethod::kStoreExtractVersion; break; } @@ -225,29 +201,12 @@ HRESULT CAddCommon::Compress(IInStream *inStream, IOutStream *outStream, setCoderProperties->SetCoderProperties(propIDs, properties, 2); } } + CMyComPtr<ISequentialOutStream> outStreamNew; if (_options.PasswordIsDefined) - { - if (!_mixerCoder || _mixerCoderMethod != method) - { - _mixerCoder.Release(); - _mixerCoderSpec = new CCoderMixer; - _mixerCoder = _mixerCoderSpec; - _mixerCoderSpec->AddCoder(_compressEncoder); - _mixerCoderSpec->AddCoder(_cryptoEncoder); - _mixerCoderSpec->FinishAddingCoders(); - _mixerCoderMethod = method; - } - _mixerCoderSpec->ReInit(); - _mixerCoderSpec->SetCoderInfo(0, NULL, NULL); - _mixerCoderSpec->SetCoderInfo(1, NULL, NULL); - _mixerCoderSpec->SetProgressCoderIndex(0); - RINOK(_mixerCoder->Code(inStream, outStream, - NULL, NULL, progress)); - } + outStreamNew = _cryptoStream; else - { - RINOK(_compressEncoder->Code(inStream, outStream, NULL, NULL, progress)); - } + outStreamNew = outStream; + RINOK(_compressEncoder->Code(inStream, outStreamNew, NULL, NULL, progress)); operationResult.ExtractVersion = NFileHeader::NCompressionMethod::kDeflateExtractVersion; break; } @@ -261,7 +220,7 @@ HRESULT CAddCommon::Compress(IInStream *inStream, IOutStream *outStream, else if(resultSize < inSize) break; } - outStream->SetSize(resultSize); + RINOK(outStream->SetSize(resultSize)); operationResult.PackSize = resultSize; operationResult.Method = method; return S_OK; diff --git a/7zip/Archive/Zip/ZipAddCommon.h b/7zip/Archive/Zip/ZipAddCommon.h index 16de76b4..4da3840f 100755 --- a/7zip/Archive/Zip/ZipAddCommon.h +++ b/7zip/Archive/Zip/ZipAddCommon.h @@ -1,27 +1,26 @@ // Zip/AddCommon.h -#pragma once - #ifndef __ZIP_ADDCOMMON_H #define __ZIP_ADDCOMMON_H #include "../../ICoder.h" #include "../../IProgress.h" #include "../../Compress/Copy/CopyCoder.h" -#include "../Common/CoderMixer.h" #ifndef COMPRESS_DEFLATE #include "../Common/CoderLoader.h" #endif +#include "../Common/FilterCoder.h" #include "ZipCompressionMode.h" +#include "../../Crypto/Zip/ZipCipher.h" namespace NArchive { namespace NZip { struct CCompressingResult { - BYTE Method; - UINT64 PackSize; - BYTE ExtractVersion; + Byte Method; + UInt64 PackSize; + Byte ExtractVersion; }; class CAddCommon @@ -35,20 +34,15 @@ class CAddCommon #endif CMyComPtr<ICompressCoder> _compressEncoder; - #ifndef CRYPTO_ZIP - CCoderLibrary _cryptoLib; - #endif - CMyComPtr<ICompressCoder> _cryptoEncoder; - CCoderMixer *_mixerCoderSpec; - CMyComPtr<ICompressCoder> _mixerCoder; - BYTE _mixerCoderMethod; - // CMyComPtr<ICryptoGetTextPassword> getTextPassword; + CFilterCoder *_cryptoStreamSpec; + CMyComPtr<ISequentialOutStream> _cryptoStream; + NCrypto::NZip::CEncoder *_filterSpec; public: CAddCommon(const CCompressionMethodMode &options); HRESULT Compress(IInStream *inStream, IOutStream *outStream, - UINT64 inSize, ICompressProgressInfo *progress, CCompressingResult &operationResult); + UInt64 inSize, ICompressProgressInfo *progress, CCompressingResult &operationResult); }; }} diff --git a/7zip/Archive/Zip/ZipCompressionMode.h b/7zip/Archive/Zip/ZipCompressionMode.h index f153c179..2ef91460 100755 --- a/7zip/Archive/Zip/ZipCompressionMode.h +++ b/7zip/Archive/Zip/ZipCompressionMode.h @@ -1,7 +1,5 @@ // CompressionMode.h -#pragma once - #ifndef __ZIP_COMPRESSIONMETHOD_H #define __ZIP_COMPRESSIONMETHOD_H @@ -13,10 +11,10 @@ namespace NZip { struct CCompressionMethodMode { - CRecordVector<BYTE> MethodSequence; + CRecordVector<Byte> MethodSequence; // bool MaximizeRatio; - UINT32 NumPasses; - UINT32 NumFastBytes; + UInt32 NumPasses; + UInt32 NumFastBytes; bool PasswordIsDefined; AString Password; }; diff --git a/7zip/Archive/Zip/ZipHandler.cpp b/7zip/Archive/Zip/ZipHandler.cpp index 54c31d0a..6add2a08 100755 --- a/7zip/Archive/Zip/ZipHandler.cpp +++ b/7zip/Archive/Zip/ZipHandler.cpp @@ -1,4 +1,4 @@ -// Zip/Handler.cpp +// ZipHandler.cpp #include "StdAfx.h" @@ -13,21 +13,19 @@ #include "Windows/PropVariant.h" #include "../../IPassword.h" -// #include "../../../Compress/Interface/CompressInterface.h" #include "../../Common/ProgressUtils.h" #include "../../Common/StreamObjects.h" -// #include "Interface/EnumStatProp.h" -#include "../../Common/StreamObjects.h" #include "../../Compress/Copy/CopyCoder.h" - #include "../Common/ItemNameUtils.h" #include "../Common/OutStreamWithCRC.h" -#include "../Common/CoderMixer.h" +#include "../Common/FilterCoder.h" #include "../7z/7zMethods.h" +#include "../../Compress/Shrink/ShrinkDecoder.h" +#include "../../Compress/Implode/ImplodeDecoder.h" #ifdef COMPRESS_DEFLATE #include "../../Compress/Deflate/DeflateDecoder.h" @@ -45,13 +43,14 @@ DEFINE_GUID(CLSID_CCompressDeflate64Decoder, 0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00); #endif +/* #ifdef COMPRESS_IMPLODE -#include "../../Compress/Implode/ImplodeDecoder.h" #else // {23170F69-40C1-278B-0401-060000000000} DEFINE_GUID(CLSID_CCompressImplodeDecoder, 0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00); #endif +*/ #ifdef COMPRESS_BZIP2 #include "../../Compress/BZip2/BZip2Decoder.h" @@ -61,20 +60,12 @@ DEFINE_GUID(CLSID_CCompressBZip2Decoder, 0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00); #endif -#ifdef CRYPTO_ZIP #include "../../Crypto/Zip/ZipCipher.h" -#else -// {23170F69-40C1-278B-06F1-0101000000000} -DEFINE_GUID(CLSID_CCryptoZipDecoder, -0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00); -#endif #ifndef EXCLUDE_COM #include "../Common/CoderLoader.h" #endif -// using namespace std; - using namespace NWindows; using namespace NTime; @@ -128,7 +119,7 @@ STATPROPSTG kProperties[] = { NULL, kpidAttributes, VT_UI4}, { NULL, kpidEncrypted, VT_BOOL}, - { NULL, kpidCommented, VT_BOOL}, + { NULL, kpidComment, VT_BSTR}, { NULL, kpidCRC, VT_UI4}, @@ -141,7 +132,7 @@ STATPROPSTG kProperties[] = const wchar_t *kMethods[] = { L"Store", - L"Shrunk", + L"Shrink", L"Reduced1", L"Reduced2", L"Reduced2", @@ -172,13 +163,13 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) return S_OK; } -STDMETHODIMP CHandler::GetNumberOfProperties(UINT32 *numProperties) +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) { *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); return S_OK; } -STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index, +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) { if(index >= sizeof(kProperties) / sizeof(kProperties[0])) @@ -190,25 +181,25 @@ STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index, return S_OK; } -STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UINT32 *numProperties) +STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) { *numProperties = 0; return S_OK; } -STDMETHODIMP CHandler::GetArchivePropertyInfo(UINT32 index, +STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) { return E_NOTIMPL; } -STDMETHODIMP CHandler::GetNumberOfItems(UINT32 *numItems) +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) { *numItems = m_Items.Size(); return S_OK; } -STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID aPropID, PROPVARIANT *aValue) +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID aPropID, PROPVARIANT *aValue) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant propVariant; @@ -247,9 +238,20 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID aPropID, PROPVARIANT *a case kpidEncrypted: propVariant = item.IsEncrypted(); break; - case kpidCommented: - propVariant = item.IsCommented(); + case kpidComment: + { + int size = item.Comment.GetCapacity(); + if (size > 0) + { + AString s; + char *p = s.GetBuffer(size + 1); + strncpy(p, (const char *)(const Byte *)item.Comment, size); + p[size] = '\0'; + s.ReleaseBuffer(); + propVariant = MultiByteToUnicodeString(s, item.GetCodePage()); + } break; + } case kpidCRC: propVariant = item.FileCRC; break; @@ -278,12 +280,12 @@ class CPropgressImp: public CProgressVirt { CMyComPtr<IArchiveOpenCallback> m_OpenArchiveCallback; public: - STDMETHOD(SetCompleted)(const UINT64 *numFiles); + STDMETHOD(SetCompleted)(const UInt64 *numFiles); void Init(IArchiveOpenCallback *openArchiveCallback) { m_OpenArchiveCallback = openArchiveCallback; } }; -STDMETHODIMP CPropgressImp::SetCompleted(const UINT64 *numFiles) +STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles) { if (m_OpenArchiveCallback) return m_OpenArchiveCallback->SetCompleted(numFiles, NULL); @@ -291,7 +293,7 @@ STDMETHODIMP CPropgressImp::SetCompleted(const UINT64 *numFiles) } STDMETHODIMP CHandler::Open(IInStream *inStream, - const UINT64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) + const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) { COM_TRY_BEGIN // try @@ -330,24 +332,24 @@ STDMETHODIMP CHandler::Close() struct CMethodItem { - BYTE ZipMethod; + Byte ZipMethod; CMyComPtr<ICompressCoder> Coder; }; -STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, - INT32 _aTestMode, IArchiveExtractCallback *_anExtractCallback) +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *_anExtractCallback) { COM_TRY_BEGIN CMyComPtr<ICryptoGetTextPassword> getTextPassword; bool testMode = (_aTestMode != 0); CMyComPtr<IArchiveExtractCallback> extractCallback = _anExtractCallback; - UINT64 totalUnPacked = 0, totalPacked = 0; - bool allFilesMode = (numItems == UINT32(-1)); + UInt64 totalUnPacked = 0, totalPacked = 0; + bool allFilesMode = (numItems == UInt32(-1)); if (allFilesMode) numItems = m_Items.Size(); if(numItems == 0) return S_OK; - UINT32 i; + UInt32 i; for(i = 0; i < numItems; i++) { const CItemEx &item = m_Items[allFilesMode ? i : indices[i]]; @@ -356,8 +358,8 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, } extractCallback->SetTotal(totalUnPacked); - UINT64 currentTotalUnPacked = 0, currentTotalPacked = 0; - UINT64 currentItemUnPacked, currentItemPacked; + UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0; + UInt64 currentItemUnPacked, currentItemPacked; #ifndef EXCLUDE_COM @@ -382,11 +384,12 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, #endif */ - CMyComPtr<ICompressCoder> cryptoDecoder; - CCoderMixer *mixerCoderSpec; - CMyComPtr<ICompressCoder> mixerCoder; + NCrypto::NZip::CDecoder *cryptoDecoderSpec; + CMyComPtr<ICompressFilter> cryptoDecoder; + CFilterCoder *filterStreamSpec; + CMyComPtr<ISequentialInStream> filterStream; - UINT16 mixerCoderMethod; + // UInt16 mixerCoderMethod; for(i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked, currentTotalPacked += currentItemPacked) @@ -396,10 +399,10 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, RINOK(extractCallback->SetCompleted(¤tTotalUnPacked)); CMyComPtr<ISequentialOutStream> realOutStream; - INT32 askMode; + Int32 askMode; askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract; - INT32 index = allFilesMode ? i : indices[i]; + Int32 index = allFilesMode ? i : indices[i]; const CItemEx &item = m_Items[index]; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); @@ -420,6 +423,7 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, currentItemUnPacked = item.UnPackSize; currentItemPacked = item.PackSize; + CInStreamReleaser inStreamReleaser; { COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC; CMyComPtr<ISequentialOutStream> outStream(outStreamSpec); @@ -445,13 +449,8 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, { if (!cryptoDecoder) { - #ifdef CRYPTO_ZIP - cryptoDecoder = new NCrypto::NZip::CDecoder; - #else - RINOK(cryptoLib.LoadAndCreateCoder( - GetBaseFolderPrefix() + TEXT("\\Crypto\\Zip.dll"), - CLSID_CCryptoZipDecoder, &cryptoDecoder)); - #endif + cryptoDecoderSpec = new NCrypto::NZip::CDecoder; + cryptoDecoder = cryptoDecoderSpec; } CMyComPtr<ICryptoSetPassword> cryptoSetPassword; RINOK(cryptoDecoder.QueryInterface( @@ -468,7 +467,7 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, AString anOemPassword = UnicodeStringToMultiByte( (const wchar_t *)password, CP_OEMCP); RINOK(cryptoSetPassword->CryptoSetPassword( - (const BYTE *)(const char *)anOemPassword, anOemPassword.Length())); + (const Byte *)(const char *)anOemPassword, anOemPassword.Length())); } else { @@ -483,16 +482,18 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, if (m == methodItems.Size()) { CMethodItem mi; - mi.ZipMethod = item.CompressionMethod; + mi.ZipMethod = (Byte)item.CompressionMethod; + if (item.CompressionMethod == NFileHeader::NCompressionMethod::kStored) + mi.Coder = new NCompress::CCopyCoder; + else if (item.CompressionMethod == NFileHeader::NCompressionMethod::kShrunk) + mi.Coder = new NCompress::NShrink::CDecoder; + else if (item.CompressionMethod == NFileHeader::NCompressionMethod::kImploded) + mi.Coder = new NCompress::NImplode::NDecoder::CCoder; + else + { #ifdef EXCLUDE_COM switch(item.CompressionMethod) { - case NFileHeader::NCompressionMethod::kStored: - mi.Coder = new NCompress::CCopyCoder; - break; - case NFileHeader::NCompressionMethod::kImploded: - mi.Coder = new NCompress::NImplode::NDecoder::CCoder; - break; case NFileHeader::NCompressionMethod::kDeflated: mi.Coder = new NCompress::NDeflate::NDecoder::CCOMCoder; break; @@ -509,7 +510,7 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, } #else N7z::CMethodID methodID = { { 0x04, 0x01 } , 3 }; - methodID.ID[2] = item.CompressionMethod; + methodID.ID[2] = mi.ZipMethod; if (item.CompressionMethod == NFileHeader::NCompressionMethod::kStored) { methodID.ID[0] = 0; @@ -531,19 +532,16 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, RINOK(libraries.CreateCoder(methodInfo.FilePath, methodInfo.Decoder, &mi.Coder)); #endif + } m = methodItems.Add(mi); } ICompressCoder *coder = methodItems[m].Coder; - CMyComPtr<ICompressSetDecoderProperties> compressSetDecoderProperties; - if (coder->QueryInterface(IID_ICompressSetDecoderProperties, (void **)&compressSetDecoderProperties) == S_OK) + CMyComPtr<ICompressSetDecoderProperties2> compressSetDecoderProperties; + if (coder->QueryInterface(IID_ICompressSetDecoderProperties2, (void **)&compressSetDecoderProperties) == S_OK) { - // BYTE properties = (item.Flags & 6); - BYTE properties = item.Flags; - CSequentialInStreamImp *inStreamSpec = new CSequentialInStreamImp; - CMyComPtr<ISequentialInStream> inStreamProperties(inStreamSpec); - inStreamSpec->Init(&properties, 1); - RINOK(compressSetDecoderProperties->SetDecoderProperties(inStreamProperties)); + Byte properties = (Byte)item.Flags; + RINOK(compressSetDecoderProperties->SetDecoderProperties2(&properties, 1)); } // case NFileHeader::NCompressionMethod::kImploded: @@ -551,20 +549,20 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, try { HRESULT result; + CMyComPtr<ISequentialInStream> inStreamNew; if (item.IsEncrypted()) { - if (!mixerCoder || mixerCoderMethod != item.CompressionMethod) + if (!filterStream) { - mixerCoder.Release(); - mixerCoderSpec = new CCoderMixer; - mixerCoder = mixerCoderSpec; - mixerCoderSpec->AddCoder(cryptoDecoder); - mixerCoderSpec->AddCoder(coder); - mixerCoderSpec->FinishAddingCoders(); - mixerCoderMethod = item.CompressionMethod; + filterStreamSpec = new CFilterCoder; + filterStream = filterStreamSpec; + filterStreamSpec->Filter = cryptoDecoder; } - mixerCoderSpec->ReInit(); + RINOK(cryptoDecoderSpec->ReadHeader(inStream)); + RINOK(filterStreamSpec->SetInStream(inStream)); + inStreamReleaser.FilterCoder = filterStreamSpec; + /* switch(item.CompressionMethod) { case NFileHeader::NCompressionMethod::kStored: @@ -577,16 +575,15 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, mixerCoderSpec->SetCoderInfo(1, NULL, ¤tItemUnPacked); break; } - - mixerCoderSpec->SetProgressCoderIndex(1); - result = mixerCoder->Code(inStream, outStream, - NULL, NULL, compressProgress); + */ + inStreamNew = filterStream; } else { - result = coder->Code(inStream, outStream, - NULL, ¤tItemUnPacked, compressProgress); + inStreamNew = inStream; } + result = coder->Code(inStreamNew, outStream, + NULL, ¤tItemUnPacked, compressProgress); if (result == S_FALSE) throw "data error"; if (result != S_OK) diff --git a/7zip/Archive/Zip/ZipHandler.h b/7zip/Archive/Zip/ZipHandler.h index 93467715..f5a97ae2 100755 --- a/7zip/Archive/Zip/ZipHandler.h +++ b/7zip/Archive/Zip/ZipHandler.h @@ -1,7 +1,5 @@ // Zip/Handler.h -#pragma once - #ifndef __ZIP_HANDLER_H #define __ZIP_HANDLER_H @@ -29,31 +27,31 @@ public: ) STDMETHOD(Open)(IInStream *aStream, - const UINT64 *aMaxCheckStartPosition, + const UInt64 *aMaxCheckStartPosition, IArchiveOpenCallback *anOpenArchiveCallback); STDMETHOD(Close)(); - STDMETHOD(GetNumberOfItems)(UINT32 *numItems); - STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(Extract)(const UINT32* indices, UINT32 numItems, - INT32 testMode, IArchiveExtractCallback *anExtractCallback); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *anExtractCallback); STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); - STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties); - STDMETHOD(GetPropertyInfo)(UINT32 index, + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType); - STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties); - STDMETHOD(GetArchivePropertyInfo)(UINT32 index, + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType); // IOutArchive - STDMETHOD(UpdateItems)(IOutStream *outStream, UINT32 numItems, + STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback); - STDMETHOD(GetFileTimeType)(UINT32 *timeType); + STDMETHOD(GetFileTimeType)(UInt32 *timeType); // ISetProperties - STDMETHOD(SetProperties)(const BSTR *names, const PROPVARIANT *values, INT32 numProperties); + STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties); CHandler(); private: diff --git a/7zip/Archive/Zip/ZipHandlerOut.cpp b/7zip/Archive/Zip/ZipHandlerOut.cpp index 6bfd5f70..7b7fac4c 100755 --- a/7zip/Archive/Zip/ZipHandlerOut.cpp +++ b/7zip/Archive/Zip/ZipHandlerOut.cpp @@ -22,23 +22,23 @@ using namespace NTime; namespace NArchive { namespace NZip { -STDMETHODIMP CHandler::GetFileTimeType(UINT32 *timeType) +STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType) { *timeType = NFileTimeType::kDOS; return S_OK; } -STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems, +STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback) { COM_TRY_BEGIN CObjectVector<CUpdateItem> updateItems; - for(int i = 0; i < numItems; i++) + for(UInt32 i = 0; i < numItems; i++) { CUpdateItem updateItem; - INT32 newData; - INT32 newProperties; - UINT32 indexInArchive; + Int32 newData; + Int32 newProperties; + UInt32 indexInArchive; if (!updateCallback) return E_FAIL; RINOK(updateCallback->GetUpdateItemInfo(i, @@ -49,7 +49,7 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems, updateItem.NewData = IntToBool(newData); updateItem.IndexInArchive = indexInArchive; updateItem.IndexInClient = i; - bool existInArchive = (indexInArchive != UINT32(-1)); + bool existInArchive = (indexInArchive != UInt32(-1)); if (IntToBool(newProperties)) { FILETIME utcFileTime; @@ -100,13 +100,28 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems, return E_INVALIDARG; if(!FileTimeToDosTime(localFileTime, updateItem.Time)) return E_INVALIDARG; - updateItem.Name = UnicodeStringToMultiByte( - NItemName::MakeLegalName(name), CP_OEMCP); + if (!isDirectoryStatusDefined) updateItem.IsDirectory = ((updateItem.Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0); - if (updateItem.IsDirectory) - updateItem.Name += '/'; + + name = NItemName::MakeLegalName(name); + bool needSlash = updateItem.IsDirectory; + const wchar_t kSlash = L'/'; + if (!name.IsEmpty()) + { + if (name[name.Length() - 1] == kSlash) + { + if (!updateItem.IsDirectory) + return E_INVALIDARG; + needSlash = false; + } + } + if (needSlash) + name += kSlash; + updateItem.Name = UnicodeStringToMultiByte(name, CP_OEMCP); + updateItem.IndexInClient = i; + /* if(existInArchive) { const CItemEx &itemInfo = m_Items[indexInArchive]; @@ -120,19 +135,18 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems, } else updateItem.Commented = false; + */ } if (IntToBool(newData)) { - UINT64 size; + UInt64 size; { NCOM::CPropVariant propVariant; RINOK(updateCallback->GetProperty(i, kpidSize, &propVariant)); if (propVariant.vt != VT_UI8) return E_INVALIDARG; - size = *(UINT64 *)(&propVariant.uhVal); + size = propVariant.uhVal.QuadPart; } - if(size > 0xFFFFFFFF) - return E_NOTIMPL; updateItem.Size = size; } updateItems.Add(updateItem); @@ -147,7 +161,7 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems, if (getTextPassword) { CMyComBSTR password; - INT32 passwordIsDefined; + Int32 passwordIsDefined; RINOK(getTextPassword->CryptoGetTextPassword2( &passwordIsDefined, &password)); if (m_Method.PasswordIsDefined = IntToBool(passwordIsDefined)) @@ -162,16 +176,16 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems, COM_TRY_END } -static const UINT32 kNumPassesNormal = 1; -static const UINT32 kNumPassesMX = 3; +static const UInt32 kNumPassesNormal = 1; +static const UInt32 kNumPassesMX = 3; -static const UINT32 kMatchFastLenNormal = 32; -static const UINT32 kMatchFastLenMX = 64; +static const UInt32 kMatchFastLenNormal = 32; +static const UInt32 kMatchFastLenMX = 64; -STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *values, INT32 numProperties) +STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) { InitMethodProperties(); - BYTE mainMethod = NFileHeader::NCompressionMethod::kDeflated; + Byte mainMethod = NFileHeader::NCompressionMethod::kDeflated; for (int i = 0; i < numProperties; i++) { UString name = UString(names[i]); @@ -181,7 +195,7 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value if (name[0] == 'X') { name.Delete(0); - UINT32 level = 9; + UInt32 level = 9; if (value.vt == VT_UI4) { if (!name.IsEmpty()) @@ -194,10 +208,10 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value { const wchar_t *start = name; const wchar_t *end; - UINT64 v = ConvertStringToUINT64(start, &end); + UInt64 v = ConvertStringToUInt64(start, &end); if (end - start != name.Length()) return E_INVALIDARG; - level = (UINT32)v; + level = (UInt32)v; } } else @@ -246,7 +260,7 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value case NFileHeader::NCompressionMethod::kDeflated: case NFileHeader::NCompressionMethod::kDeflated64: case NFileHeader::NCompressionMethod::kBZip2: - mainMethod = value.ulVal; + mainMethod = (Byte)value.ulVal; break; default: return E_INVALIDARG; diff --git a/7zip/Archive/Zip/ZipHeader.cpp b/7zip/Archive/Zip/ZipHeader.cpp index fe32d4fd..fd8856bb 100755 --- a/7zip/Archive/Zip/ZipHeader.cpp +++ b/7zip/Archive/Zip/ZipHeader.cpp @@ -9,10 +9,12 @@ namespace NZip { namespace NSignature { - UINT32 kLocalFileHeader = 0x04034B50 + 1; - UINT32 kDataDescriptor = 0x08074B50 + 1; - UINT32 kCentralFileHeader = 0x02014B50 + 1; - UINT32 kEndOfCentralDir = 0x06054B50 + 1; + UInt32 kLocalFileHeader = 0x04034B50 + 1; + UInt32 kDataDescriptor = 0x08074B50 + 1; + UInt32 kCentralFileHeader = 0x02014B50 + 1; + UInt32 kEndOfCentralDir = 0x06054B50 + 1; + UInt32 kZip64EndOfCentralDir = 0x06064B50 + 1; + UInt32 kZip64EndOfCentralDirLocator = 0x07064B50 + 1; class CMarkersInitializer { @@ -23,6 +25,8 @@ namespace NSignature kDataDescriptor--; kCentralFileHeader--; kEndOfCentralDir--; + kZip64EndOfCentralDir--; + kZip64EndOfCentralDirLocator--; } }; static CMarkersInitializer g_MarkerInitializer; diff --git a/7zip/Archive/Zip/ZipHeader.h b/7zip/Archive/Zip/ZipHeader.h index cc8e4ed7..e6d1288a 100755 --- a/7zip/Archive/Zip/ZipHeader.h +++ b/7zip/Archive/Zip/ZipHeader.h @@ -1,7 +1,5 @@ // Archive/Zip/Header.h -#pragma once - #ifndef __ARCHIVE_ZIP_HEADER_H #define __ARCHIVE_ZIP_HEADER_H @@ -10,43 +8,48 @@ namespace NArchive { namespace NZip { -#pragma pack( push, PragmaZipHeaders) -#pragma pack( push, 1) - namespace NSignature { - extern UINT32 kLocalFileHeader; - extern UINT32 kDataDescriptor; - extern UINT32 kCentralFileHeader; - extern UINT32 kEndOfCentralDir; + extern UInt32 kLocalFileHeader; + extern UInt32 kDataDescriptor; + extern UInt32 kCentralFileHeader; + extern UInt32 kEndOfCentralDir; + extern UInt32 kZip64EndOfCentralDir; + extern UInt32 kZip64EndOfCentralDirLocator; - static const UINT32 kMarkerSize = 4; + static const UInt32 kMarkerSize = 4; } +const UInt32 kZip64EndOfCentralDirRecordSize = 44; + +/* struct CEndOfCentralDirectoryRecord { - UINT16 ThisDiskNumber; - UINT16 StartCentralDirectoryDiskNumber; - UINT16 NumEntriesInCentaralDirectoryOnThisDisk; - UINT16 NumEntriesInCentaralDirectory; - UINT32 CentralDirectorySize; - UINT32 CentralDirectoryStartOffset; - UINT16 CommentSize; + UInt16 ThisDiskNumber; + UInt16 StartCentralDirectoryDiskNumber; + UInt16 NumEntriesInCentaralDirectoryOnThisDisk; + UInt16 NumEntriesInCentaralDirectory; + UInt32 CentralDirectorySize; + UInt32 CentralDirectoryStartOffset; + UInt16 CommentSize; }; struct CEndOfCentralDirectoryRecordFull { - UINT32 Signature; + UInt32 Signature; CEndOfCentralDirectoryRecord Header; }; +*/ namespace NFileHeader { + /* struct CVersion { - BYTE Version; - BYTE HostOS; + Byte Version; + Byte HostOS; }; + */ namespace NCompressionMethod { @@ -67,67 +70,76 @@ namespace NFileHeader kBZip2 = 12 }; const int kNumCompressionMethods = 11; - const BYTE kMadeByProgramVersion = 20; + const Byte kMadeByProgramVersion = 20; - const BYTE kDeflateExtractVersion = 20; - const BYTE kStoreExtractVersion = 10; + const Byte kDeflateExtractVersion = 20; + const Byte kStoreExtractVersion = 10; - const BYTE kSupportedVersion = 20; + const Byte kSupportedVersion = 20; } + const UInt32 kLocalBlockSize = 26; + /* struct CLocalBlock { CVersion ExtractVersion; - UINT16 Flags; - UINT16 CompressionMethod; - UINT32 Time; - UINT32 FileCRC; - UINT32 PackSize; - UINT32 UnPackSize; - UINT16 NameSize; - UINT16 ExtraSize; + UInt16 Flags; + UInt16 CompressionMethod; + UInt32 Time; + UInt32 FileCRC; + UInt32 PackSize; + UInt32 UnPackSize; + UInt16 NameSize; + UInt16 ExtraSize; }; + */ + const UInt32 kDataDescriptorSize = 16; + /* struct CDataDescriptor { - UINT32 Signature; - UINT32 FileCRC; - UINT32 PackSize; - UINT32 UnPackSize; + UInt32 Signature; + UInt32 FileCRC; + UInt32 PackSize; + UInt32 UnPackSize; }; struct CLocalBlockFull { - UINT32 Signature; + UInt32 Signature; CLocalBlock Header; }; + */ + const UInt32 kCentralBlockSize = 42; + /* struct CBlock { CVersion MadeByVersion; CVersion ExtractVersion; - UINT16 Flags; - UINT16 CompressionMethod; - UINT32 Time; - UINT32 FileCRC; - UINT32 PackSize; - UINT32 UnPackSize; - UINT16 NameSize; - UINT16 ExtraSize; - UINT16 CommentSize; - UINT16 DiskNumberStart; - UINT16 InternalAttributes; - UINT32 ExternalAttributes; - UINT32 LocalHeaderOffset; + UInt16 Flags; + UInt16 CompressionMethod; + UInt32 Time; + UInt32 FileCRC; + UInt32 PackSize; + UInt32 UnPackSize; + UInt16 NameSize; + UInt16 ExtraSize; + UInt16 CommentSize; + UInt16 DiskNumberStart; + UInt16 InternalAttributes; + UInt32 ExternalAttributes; + UInt32 LocalHeaderOffset; }; struct CBlockFull { - UINT32 Signature; + UInt32 Signature; CBlock Header; }; - + */ + namespace NFlags { const int kNumUsedBits = 4; @@ -175,53 +187,50 @@ namespace NFileHeader } namespace NUnixAttribute { - const UINT32 kIFMT = 0170000; /* Unix file type mask */ + const UInt32 kIFMT = 0170000; /* Unix file type mask */ - const UINT32 kIFDIR = 0040000; /* Unix directory */ - const UINT32 kIFREG = 0100000; /* Unix regular file */ - const UINT32 kIFSOCK = 0140000; /* Unix socket (BSD, not SysV or Amiga) */ - const UINT32 kIFLNK = 0120000; /* Unix symbolic link (not SysV, Amiga) */ - const UINT32 kIFBLK = 0060000; /* Unix block special (not Amiga) */ - const UINT32 kIFCHR = 0020000; /* Unix character special (not Amiga) */ - const UINT32 kIFIFO = 0010000; /* Unix fifo (BCC, not MSC or Amiga) */ + const UInt32 kIFDIR = 0040000; /* Unix directory */ + const UInt32 kIFREG = 0100000; /* Unix regular file */ + const UInt32 kIFSOCK = 0140000; /* Unix socket (BSD, not SysV or Amiga) */ + const UInt32 kIFLNK = 0120000; /* Unix symbolic link (not SysV, Amiga) */ + const UInt32 kIFBLK = 0060000; /* Unix block special (not Amiga) */ + const UInt32 kIFCHR = 0020000; /* Unix character special (not Amiga) */ + const UInt32 kIFIFO = 0010000; /* Unix fifo (BCC, not MSC or Amiga) */ - const UINT32 kISUID = 04000; /* Unix set user id on execution */ - const UINT32 kISGID = 02000; /* Unix set group id on execution */ - const UINT32 kISVTX = 01000; /* Unix directory permissions control */ - const UINT32 kENFMT = kISGID; /* Unix record locking enforcement flag */ - const UINT32 kIRWXU = 00700; /* Unix read, write, execute: owner */ - const UINT32 kIRUSR = 00400; /* Unix read permission: owner */ - const UINT32 kIWUSR = 00200; /* Unix write permission: owner */ - const UINT32 kIXUSR = 00100; /* Unix execute permission: owner */ - const UINT32 kIRWXG = 00070; /* Unix read, write, execute: group */ - const UINT32 kIRGRP = 00040; /* Unix read permission: group */ - const UINT32 kIWGRP = 00020; /* Unix write permission: group */ - const UINT32 kIXGRP = 00010; /* Unix execute permission: group */ - const UINT32 kIRWXO = 00007; /* Unix read, write, execute: other */ - const UINT32 kIROTH = 00004; /* Unix read permission: other */ - const UINT32 kIWOTH = 00002; /* Unix write permission: other */ - const UINT32 kIXOTH = 00001; /* Unix execute permission: other */ + const UInt32 kISUID = 04000; /* Unix set user id on execution */ + const UInt32 kISGID = 02000; /* Unix set group id on execution */ + const UInt32 kISVTX = 01000; /* Unix directory permissions control */ + const UInt32 kENFMT = kISGID; /* Unix record locking enforcement flag */ + const UInt32 kIRWXU = 00700; /* Unix read, write, execute: owner */ + const UInt32 kIRUSR = 00400; /* Unix read permission: owner */ + const UInt32 kIWUSR = 00200; /* Unix write permission: owner */ + const UInt32 kIXUSR = 00100; /* Unix execute permission: owner */ + const UInt32 kIRWXG = 00070; /* Unix read, write, execute: group */ + const UInt32 kIRGRP = 00040; /* Unix read permission: group */ + const UInt32 kIWGRP = 00020; /* Unix write permission: group */ + const UInt32 kIXGRP = 00010; /* Unix execute permission: group */ + const UInt32 kIRWXO = 00007; /* Unix read, write, execute: other */ + const UInt32 kIROTH = 00004; /* Unix read permission: other */ + const UInt32 kIWOTH = 00002; /* Unix write permission: other */ + const UInt32 kIXOTH = 00001; /* Unix execute permission: other */ } namespace NAmigaAttribute { - const UINT32 kIFMT = 06000; /* Amiga file type mask */ - const UINT32 kIFDIR = 04000; /* Amiga directory */ - const UINT32 kIFREG = 02000; /* Amiga regular file */ - const UINT32 kIHIDDEN = 00200; /* to be supported in AmigaDOS 3.x */ - const UINT32 kISCRIPT = 00100; /* executable script (text command file) */ - const UINT32 kIPURE = 00040; /* allow loading into resident memory */ - const UINT32 kIARCHIVE = 00020; /* not modified since bit was last set */ - const UINT32 kIREAD = 00010; /* can be opened for reading */ - const UINT32 kIWRITE = 00004; /* can be opened for writing */ - const UINT32 kIEXECUTE = 00002; /* executable image, a loadable runfile */ - const UINT32 kIDELETE = 00001; /* can be deleted */ + const UInt32 kIFMT = 06000; /* Amiga file type mask */ + const UInt32 kIFDIR = 04000; /* Amiga directory */ + const UInt32 kIFREG = 02000; /* Amiga regular file */ + const UInt32 kIHIDDEN = 00200; /* to be supported in AmigaDOS 3.x */ + const UInt32 kISCRIPT = 00100; /* executable script (text command file) */ + const UInt32 kIPURE = 00040; /* allow loading into resident memory */ + const UInt32 kIARCHIVE = 00020; /* not modified since bit was last set */ + const UInt32 kIREAD = 00010; /* can be opened for reading */ + const UInt32 kIWRITE = 00004; /* can be opened for writing */ + const UInt32 kIEXECUTE = 00002; /* executable image, a loadable runfile */ + const UInt32 kIDELETE = 00001; /* can be deleted */ } } -#pragma pack(pop) -#pragma pack(pop, PragmaZipHeaders) - }} #endif diff --git a/7zip/Archive/Zip/ZipIn.cpp b/7zip/Archive/Zip/ZipIn.cpp index 6b23702b..4b4481ed 100755 --- a/7zip/Archive/Zip/ZipIn.cpp +++ b/7zip/Archive/Zip/ZipIn.cpp @@ -13,7 +13,7 @@ namespace NZip { // static const char kEndOfString = '\0'; -bool CInArchive::Open(IInStream *inStream, const UINT64 *searchHeaderSizeLimit) +bool CInArchive::Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit) { m_Stream = inStream; if(m_Stream->Seek(0, STREAM_SEEK_CUR, &m_StreamStartPosition) != S_OK) @@ -30,22 +30,23 @@ void CInArchive::Close() ////////////////////////////////////// // Markers -inline bool TestMarkerCandidate(const void *testBytes, UINT32 &value) +static inline bool TestMarkerCandidate(const Byte *p, UInt32 &value) { - value = *((const UINT32 *)(testBytes)); + value = p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24); return (value == NSignature::kLocalFileHeader) || (value == NSignature::kEndOfCentralDir); } -bool CInArchive::FindAndReadMarker(const UINT64 *searchHeaderSizeLimit) +bool CInArchive::FindAndReadMarker(const UInt64 *searchHeaderSizeLimit) { + m_ArchiveInfo.Clear(); m_ArchiveInfo.StartPosition = 0; m_Position = m_StreamStartPosition; if(m_Stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL) != S_OK) return false; - BYTE marker[NSignature::kMarkerSize]; - UINT32 processedSize; + Byte marker[NSignature::kMarkerSize]; + UInt32 processedSize; ReadBytes(marker, NSignature::kMarkerSize, &processedSize); if(processedSize != NSignature::kMarkerSize) return false; @@ -53,24 +54,24 @@ bool CInArchive::FindAndReadMarker(const UINT64 *searchHeaderSizeLimit) return true; CByteDynamicBuffer dynamicBuffer; - static const UINT32 kSearchMarkerBufferSize = 0x10000; + static const UInt32 kSearchMarkerBufferSize = 0x10000; dynamicBuffer.EnsureCapacity(kSearchMarkerBufferSize); - BYTE *buffer = dynamicBuffer; - UINT32 numBytesPrev = NSignature::kMarkerSize - 1; + Byte *buffer = dynamicBuffer; + UInt32 numBytesPrev = NSignature::kMarkerSize - 1; memmove(buffer, marker + 1, numBytesPrev); - UINT64 curTestPos = m_StreamStartPosition + 1; + UInt64 curTestPos = m_StreamStartPosition + 1; while(true) { if (searchHeaderSizeLimit != NULL) if (curTestPos - m_StreamStartPosition > *searchHeaderSizeLimit) return false; - UINT32 numReadBytes = kSearchMarkerBufferSize - numBytesPrev; + UInt32 numReadBytes = kSearchMarkerBufferSize - numBytesPrev; ReadBytes(buffer + numBytesPrev, numReadBytes, &processedSize); - UINT32 numBytesInBuffer = numBytesPrev + processedSize; + UInt32 numBytesInBuffer = numBytesPrev + processedSize; if (numBytesInBuffer < NSignature::kMarkerSize) return false; - UINT32 numTests = numBytesInBuffer - NSignature::kMarkerSize + 1; - for(UINT32 pos = 0; pos < numTests; pos++, curTestPos++) + UInt32 numTests = numBytesInBuffer - NSignature::kMarkerSize + 1; + for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++) { if (TestMarkerCandidate(buffer + pos, m_Signature)) { @@ -89,51 +90,92 @@ bool CInArchive::FindAndReadMarker(const UINT64 *searchHeaderSizeLimit) ////////////////////////////////////// // Read Operations -HRESULT CInArchive::ReadBytes(void *data, UINT32 size, UINT32 *processedSize) +HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize) { - UINT32 realProcessedSize; + UInt32 realProcessedSize; HRESULT result = m_Stream->Read(data, size, &realProcessedSize); if(processedSize != NULL) *processedSize = realProcessedSize; - IncreasePositionValue(realProcessedSize); + m_Position += realProcessedSize; return result; } -void CInArchive::IncreasePositionValue(UINT64 addValue) -{ - m_Position += addValue; -} - -void CInArchive::IncreaseRealPosition(UINT64 addValue) +void CInArchive::IncreaseRealPosition(UInt64 addValue) { if(m_Stream->Seek(addValue, STREAM_SEEK_CUR, &m_Position) != S_OK) throw CInArchiveException(CInArchiveException::kSeekStreamError); } -bool CInArchive::ReadBytesAndTestSize(void *data, UINT32 size) +bool CInArchive::ReadBytesAndTestSize(void *data, UInt32 size) { - UINT32 realProcessedSize; + UInt32 realProcessedSize; if(ReadBytes(data, size, &realProcessedSize) != S_OK) throw CInArchiveException(CInArchiveException::kReadStreamError); return (realProcessedSize == size); } -void CInArchive::SafeReadBytes(void *data, UINT32 size) +void CInArchive::SafeReadBytes(void *data, UInt32 size) { if(!ReadBytesAndTestSize(data, size)) throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive); } +void CInArchive::ReadBuffer(CByteBuffer &buffer, UInt32 size) +{ + buffer.SetCapacity(size); + if (size > 0) + SafeReadBytes(buffer, size); +} + +Byte CInArchive::ReadByte() +{ + Byte b; + SafeReadBytes(&b, 1); + return b; +} + +UInt16 CInArchive::ReadUInt16() +{ + UInt16 value = 0; + for (int i = 0; i < 2; i++) + value |= (((UInt16)ReadByte()) << (8 * i)); + return value; +} + +UInt32 CInArchive::ReadUInt32() +{ + UInt32 value = 0; + for (int i = 0; i < 4; i++) + value |= (((UInt32)ReadByte()) << (8 * i)); + return value; +} + +UInt64 CInArchive::ReadUInt64() +{ + UInt64 value = 0; + for (int i = 0; i < 8; i++) + value |= (((UInt64)ReadByte()) << (8 * i)); + return value; +} ////////////////////////////////// // Read headers -bool CInArchive::ReadSignature(UINT32 &signature) +bool CInArchive::ReadUInt32(UInt32 &value) { - return ReadBytesAndTestSize(&signature, sizeof(signature)); + value = 0; + for (int i = 0; i < 4; i++) + { + Byte b; + if (!ReadBytesAndTestSize(&b, 1)) + return false; + value |= (UInt32(b) << (8 * i)); + } + return true; } -AString CInArchive::ReadFileName(UINT32 nameSize) + +AString CInArchive::ReadFileName(UInt32 nameSize) { if (nameSize == 0) return AString(); @@ -152,6 +194,76 @@ void CInArchive::ThrowIncorrectArchiveException() throw CInArchiveException(CInArchiveException::kIncorrectArchive); } +static UInt32 GetUInt32(const Byte *data) +{ + return + ((UInt32)(Byte)data[0]) | + (((UInt32)(Byte)data[1]) << 8) | + (((UInt32)(Byte)data[2]) << 16) | + (((UInt32)(Byte)data[3]) << 24); +} + + +void CInArchive::ReadExtra(UInt32 extraSize, CExtraBlock &extraBlock, + UInt64 &unpackSize, UInt64 &packSize, UInt64 &localHeaderOffset, UInt32 &diskStartNumber) +{ + extraBlock.Clear(); + UInt32 remain = extraSize; + while(remain >= 4) + { + CExtraSubBlock subBlock; + subBlock.ID = ReadUInt16(); + UInt32 dataSize = ReadUInt16(); + remain -= 4; + if (dataSize > remain) // it's bug + dataSize = remain; + if (subBlock.ID == 0x1) + { + if (unpackSize == 0xFFFFFFFF) + { + if (dataSize < 8) + break; + unpackSize = ReadUInt64(); + remain -= 8; + dataSize -= 8; + } + if (packSize == 0xFFFFFFFF) + { + if (dataSize < 8) + break; + packSize = ReadUInt64(); + remain -= 8; + dataSize -= 8; + } + if (localHeaderOffset == 0xFFFFFFFF) + { + if (dataSize < 8) + break; + localHeaderOffset = ReadUInt64(); + remain -= 8; + dataSize -= 8; + } + if (diskStartNumber == 0xFFFF) + { + if (dataSize < 4) + break; + diskStartNumber = ReadUInt32(); + remain -= 4; + dataSize -= 4; + } + for (UInt32 i = 0; i < dataSize; i++) + ReadByte(); + } + else + { + ReadBuffer(subBlock.Data, dataSize); + extraBlock.SubBlocks.Add(subBlock); + } + remain -= dataSize; + } + IncreaseRealPosition(remain); +} + HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *progress) { // m_Signature must be kLocalFileHeaderSignature or @@ -162,70 +274,83 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *pr if (progress != 0) { - UINT64 numItems = items.Size(); + UInt64 numItems = items.Size(); RINOK(progress->SetCompleted(&numItems)); } - // FSeek -= sizeof(UINT32); // atention it's not real position while(m_Signature == NSignature::kLocalFileHeader) { // FSeek points to next byte after signature - NFileHeader::CLocalBlock localHeader; - CItemEx itemInfo; - itemInfo.LocalHeaderPosition = - UINT32(m_Position - m_StreamStartPosition - sizeof(UINT32)); // points to signature; - SafeReadBytes(&localHeader, sizeof(localHeader)); - UINT32 fileNameSize = localHeader.NameSize; - itemInfo.Name = ReadFileName(fileNameSize); + // NFileHeader::CLocalBlock localHeader; + CItemEx item; + item.LocalHeaderPosition = m_Position - m_StreamStartPosition - 4; // points to signature; + + // SafeReadBytes(&localHeader, sizeof(localHeader)); + + item.ExtractVersion.Version = ReadByte(); + item.ExtractVersion.HostOS = ReadByte(); + item.Flags = ReadUInt16() & NFileHeader::NFlags::kUsedBitsMask; + item.CompressionMethod = ReadUInt16(); + item.Time = ReadUInt32(); + item.FileCRC = ReadUInt32(); + item.PackSize = ReadUInt32(); + item.UnPackSize = ReadUInt32(); + UInt32 fileNameSize = ReadUInt16(); + item.LocalExtraSize = ReadUInt16(); + item.Name = ReadFileName(fileNameSize); /* - if (!NItemName::IsNameLegal(itemInfo.Name)) + if (!NItemName::IsNameLegal(item.Name)) ThrowIncorrectArchiveException(); */ - itemInfo.ExtractVersion.Version = localHeader.ExtractVersion.Version; - itemInfo.ExtractVersion.HostOS = localHeader.ExtractVersion.HostOS; - itemInfo.Flags = localHeader.Flags & NFileHeader::NFlags::kUsedBitsMask; - itemInfo.CompressionMethod = localHeader.CompressionMethod; - itemInfo.Time = localHeader.Time; - itemInfo.FileCRC = localHeader.FileCRC; - itemInfo.PackSize = localHeader.PackSize; - itemInfo.UnPackSize = localHeader.UnPackSize; - itemInfo.LocalExtraSize = localHeader.ExtraSize; - itemInfo.FileHeaderWithNameSize = sizeof(UINT32) + sizeof(localHeader) + fileNameSize; + item.FileHeaderWithNameSize = 4 + + NFileHeader::kLocalBlockSize + fileNameSize; - IncreaseRealPosition(localHeader.ExtraSize); + // IncreaseRealPosition(item.LocalExtraSize); + if (item.LocalExtraSize > 0) + { + UInt64 localHeaderOffset = 0; + UInt32 diskStartNumber = 0; + CExtraBlock extraBlock; + ReadExtra(item.LocalExtraSize, extraBlock, item.UnPackSize, item.PackSize, + localHeaderOffset, diskStartNumber); + } - if (itemInfo.HasDescriptor()) + if (item.HasDescriptor()) { const int kBufferSize = (1 << 12); - BYTE buffer[kBufferSize]; - UINT32 numBytesInBuffer = 0; - UINT32 packedSize = 0; + Byte buffer[kBufferSize]; + + UInt32 numBytesInBuffer = 0; + UInt32 packedSize = 0; bool descriptorWasFound = false; while (true) { - UINT32 processedSize; + UInt32 processedSize; RINOK(ReadBytes(buffer + numBytesInBuffer, kBufferSize - numBytesInBuffer, &processedSize)); numBytesInBuffer += processedSize; - if (numBytesInBuffer < sizeof(NFileHeader::CDataDescriptor)) + if (numBytesInBuffer < NFileHeader::kDataDescriptorSize) ThrowIncorrectArchiveException(); - int i; - for (i = 0; i <= numBytesInBuffer - - sizeof(NFileHeader::CDataDescriptor); i++) + UInt32 i; + for (i = 0; i <= numBytesInBuffer - NFileHeader::kDataDescriptorSize; i++) { - const NFileHeader::CDataDescriptor &descriptor = - *(NFileHeader::CDataDescriptor *)(buffer + i); - if (descriptor.Signature == NSignature::kDataDescriptor && - descriptor.PackSize == packedSize + i) + // descriptorSignature field is Info-ZIP's extension + // to Zip specification. + UInt32 descriptorSignature = GetUInt32(buffer + i); + + // !!!! It must be fixed for Zip64 archives + UInt32 descriptorPackSize = GetUInt32(buffer + i + 8); + if (descriptorSignature== NSignature::kDataDescriptor && + descriptorPackSize == packedSize + i) { descriptorWasFound = true; - itemInfo.FileCRC = descriptor.FileCRC; - itemInfo.PackSize = descriptor.PackSize; - itemInfo.UnPackSize = descriptor.UnPackSize; - IncreaseRealPosition(INT64(INT32(0 - (numBytesInBuffer - i - - sizeof(NFileHeader::CDataDescriptor))))); + item.FileCRC = GetUInt32(buffer + i + 4); + item.PackSize = descriptorPackSize; + item.UnPackSize = GetUInt32(buffer + i + 12); + IncreaseRealPosition(Int64(Int32(0 - (numBytesInBuffer - i - + NFileHeader::kDataDescriptorSize)))); break; }; } @@ -239,24 +364,24 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *pr } } else - IncreaseRealPosition(localHeader.PackSize); + IncreaseRealPosition(item.PackSize); - items.Add(itemInfo); + items.Add(item); if (progress != 0) { - UINT64 numItems = items.Size(); + UInt64 numItems = items.Size(); RINOK(progress->SetCompleted(&numItems)); } - if (!ReadSignature(m_Signature)) + if (!ReadUInt32(m_Signature)) break; } - UINT32 centralDirectorySize = 0; - UINT64 centralDirectoryStartOffset = m_Position - sizeof(UINT32); + UInt64 centralDirectorySize = 0; + UInt64 centralDirectoryStartOffset = m_Position - 4; for(int i = 0; i < items.Size(); i++) { if (progress != 0) { - UINT64 numItems = items.Size(); + UInt64 numItems = items.Size(); RINOK(progress->SetCompleted(&numItems)); } // if(m_Signature == NSignature::kEndOfCentralDir) @@ -264,10 +389,35 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *pr if(m_Signature != NSignature::kCentralFileHeader) ThrowIncorrectArchiveException(); - NFileHeader::CBlock header; - SafeReadBytes(&header, sizeof(header)); - UINT32 localHeaderOffset = header.LocalHeaderOffset; - header.Flags &= NFileHeader::NFlags::kUsedBitsMask; + // NFileHeader::CBlock header; + // SafeReadBytes(&header, sizeof(header)); + + Byte headerMadeByVersionVersion = ReadByte(); + Byte headerMadeByVersionHostOS = ReadByte(); + Byte centalHeaderExtractVersionVersion = ReadByte(); + Byte centalHeaderExtractVersionHostOS = ReadByte(); + UInt16 headerFlags = ReadUInt16() & NFileHeader::NFlags::kUsedBitsMask; + UInt16 headerCompressionMethod = ReadUInt16(); + UInt32 headerTime = ReadUInt32(); + UInt32 headerFileCRC = ReadUInt32(); + UInt64 headerPackSize = ReadUInt32(); + UInt64 headerUnPackSize = ReadUInt32(); + UInt16 headerNameSize = ReadUInt16(); + UInt16 headerExtraSize = ReadUInt16(); + UInt16 headerCommentSize = ReadUInt16(); + UInt32 headerDiskNumberStart = ReadUInt16(); + UInt16 headerInternalAttributes = ReadUInt16(); + UInt32 headerExternalAttributes = ReadUInt32(); + UInt64 localHeaderOffset = ReadUInt32(); + AString centralName = ReadFileName(headerNameSize); + + // item.Name = ReadFileName(fileNameSize); + + CExtraBlock centralExtra; + if (headerExtraSize > 0) + { + ReadExtra(headerExtraSize, centralExtra, headerUnPackSize, headerPackSize, localHeaderOffset, headerDiskNumberStart); + } int index; int left = 0, right = items.Size(); @@ -276,7 +426,7 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *pr if (left >= right) ThrowIncorrectArchiveException(); index = (left + right) / 2; - UINT32 position = items[index].LocalHeaderPosition; + UInt64 position = items[index].LocalHeaderPosition; if (localHeaderOffset == position) break; if (localHeaderOffset < position) @@ -284,73 +434,143 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *pr else left = index + 1; } - CItemEx &itemInfo = items[index]; - itemInfo.MadeByVersion.Version = header.MadeByVersion.Version; - itemInfo.MadeByVersion.HostOS = header.MadeByVersion.HostOS; - - CVersion centalHeaderExtractVersion; - centalHeaderExtractVersion.Version = header.ExtractVersion.Version; - centalHeaderExtractVersion.HostOS = header.ExtractVersion.HostOS; + CItemEx &item = items[index]; + item.MadeByVersion.Version = headerMadeByVersionVersion; + item.MadeByVersion.HostOS = headerMadeByVersionHostOS; + item.CentralExtra = centralExtra; if ( - // itemInfo.ExtractVersion != centalHeaderExtractVersion || - itemInfo.Flags != header.Flags || - itemInfo.CompressionMethod != header.CompressionMethod || - // itemInfo.Time != header.Time || - itemInfo.FileCRC != header.FileCRC || - itemInfo.PackSize != header.PackSize || - itemInfo.UnPackSize != header.UnPackSize) + // item.ExtractVersion != centalHeaderExtractVersion || + item.Flags != headerFlags || + item.CompressionMethod != headerCompressionMethod || + // item.Time != header.Time || + item.FileCRC != headerFileCRC) ThrowIncorrectArchiveException(); - AString centralName = ReadFileName(header.NameSize); - if (itemInfo.Name.Length() != centralName.Length()) + if (item.Name.Length() != centralName.Length()) ThrowIncorrectArchiveException(); // test it maybe better compare names - itemInfo.Name = centralName; + item.Name = centralName; - itemInfo.CentralExtraPosition = m_Position; - itemInfo.CentralExtraSize = header.ExtraSize; - itemInfo.CommentSize = header.CommentSize; - if (header.DiskNumberStart != 0) + // item.CentralExtraPosition = m_Position; + // item.CentralExtraSize = headerExtraSize; + // item.CommentSize = headerCommentSize; + if (headerDiskNumberStart != 0) throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported); - itemInfo.InternalAttributes = header.InternalAttributes; - itemInfo.ExternalAttributes = header.ExternalAttributes; + item.InternalAttributes = headerInternalAttributes; + item.ExternalAttributes = headerExternalAttributes; // May be these strings must be deleted - if (itemInfo.IsDirectory()) + if (item.IsDirectory()) { - // if (itemInfo.PackSize != 0 /* || itemInfo.UnPackSize != 0 */) + // if (item.PackSize != 0 /* || item.UnPackSize != 0 */) // ThrowIncorrectArchiveException(); - itemInfo.UnPackSize = 0; + item.UnPackSize = 0; } - UINT32 currentRecordSize = sizeof(UINT32) + sizeof(header) + - header.NameSize + header.ExtraSize + header.CommentSize; + UInt32 currentRecordSize = 4 + NFileHeader::kCentralBlockSize + + headerNameSize + headerExtraSize + headerCommentSize; centralDirectorySize += currentRecordSize; - IncreaseRealPosition(header.ExtraSize + header.CommentSize); - if (!ReadSignature(m_Signature)) + + // IncreaseRealPosition(headerExtraSize); + + if ( + item.PackSize != headerPackSize || + item.UnPackSize != headerUnPackSize + ) + ThrowIncorrectArchiveException(); + + // IncreaseRealPosition(headerCommentSize); + ReadBuffer(item.Comment, headerCommentSize); + + if (!ReadUInt32(m_Signature)) break; } + UInt32 thisDiskNumber = 0; + UInt32 startCDDiskNumber = 0; + UInt64 numEntriesInCDOnThisDisk = 0; + UInt64 numEntriesInCD = 0; + UInt64 cdSize = 0; + UInt64 cdStartOffsetFromRecord = 0; + bool isZip64 = false; + UInt64 zip64EndOfCDStartOffset = m_Position - 4; + if(m_Signature == NSignature::kZip64EndOfCentralDir) + { + isZip64 = true; + UInt64 recordSize = ReadUInt64(); + UInt16 versionMade = ReadUInt16(); + UInt16 versionNeedExtract = ReadUInt16(); + thisDiskNumber = ReadUInt32(); + startCDDiskNumber = ReadUInt32(); + numEntriesInCDOnThisDisk = ReadUInt64(); + numEntriesInCD = ReadUInt64(); + cdSize = ReadUInt64(); + cdStartOffsetFromRecord = ReadUInt64(); + IncreaseRealPosition(recordSize - kZip64EndOfCentralDirRecordSize); + if (!ReadUInt32(m_Signature)) + return S_FALSE; + if (thisDiskNumber != 0 || startCDDiskNumber != 0) + throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported); + if (numEntriesInCDOnThisDisk != items.Size() || + numEntriesInCD != items.Size() || + cdSize != centralDirectorySize || + (cdStartOffsetFromRecord != centralDirectoryStartOffset && + (!items.IsEmpty()))) + ThrowIncorrectArchiveException(); + } + if(m_Signature == NSignature::kZip64EndOfCentralDirLocator) + { + UInt32 startEndCDDiskNumber = ReadUInt32(); + UInt64 endCDStartOffset = ReadUInt64(); + UInt32 numberOfDisks = ReadUInt32(); + if (zip64EndOfCDStartOffset != endCDStartOffset) + ThrowIncorrectArchiveException(); + if (!ReadUInt32(m_Signature)) + return S_FALSE; + } if(m_Signature != NSignature::kEndOfCentralDir) ThrowIncorrectArchiveException(); - CEndOfCentralDirectoryRecord endOfCentralDirHeader; - SafeReadBytes(&endOfCentralDirHeader, sizeof(endOfCentralDirHeader)); - if (endOfCentralDirHeader.ThisDiskNumber != 0 || - endOfCentralDirHeader.StartCentralDirectoryDiskNumber != 0) - throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported); - if (endOfCentralDirHeader.NumEntriesInCentaralDirectoryOnThisDisk != ((UINT16)items.Size()) || - endOfCentralDirHeader.NumEntriesInCentaralDirectory != ((UINT16)items.Size()) || - endOfCentralDirHeader.CentralDirectorySize != centralDirectorySize || - (endOfCentralDirHeader.CentralDirectoryStartOffset != centralDirectoryStartOffset && + + UInt16 thisDiskNumber16 = ReadUInt16(); + if (!isZip64 || thisDiskNumber16) + thisDiskNumber = thisDiskNumber16; + + UInt16 startCDDiskNumber16 = ReadUInt16(); + if (!isZip64 || startCDDiskNumber16 != 0xFFFF) + startCDDiskNumber = startCDDiskNumber16; + + UInt16 numEntriesInCDOnThisDisk16 = ReadUInt16(); + if (!isZip64 || numEntriesInCDOnThisDisk16 != 0xFFFF) + numEntriesInCDOnThisDisk = numEntriesInCDOnThisDisk16; + + UInt16 numEntriesInCD16 = ReadUInt16(); + if (!isZip64 || numEntriesInCD16 != 0xFFFF) + numEntriesInCD = numEntriesInCD16; + + UInt32 cdSize32 = ReadUInt32(); + if (!isZip64 || cdSize32 != 0xFFFFFFFF) + cdSize = cdSize32; + + UInt32 cdStartOffsetFromRecord32 = ReadUInt32(); + if (!isZip64 || cdStartOffsetFromRecord32 != 0xFFFFFFFF) + cdStartOffsetFromRecord = cdStartOffsetFromRecord32; + + UInt16 commentSize = ReadUInt16(); + ReadBuffer(m_ArchiveInfo.Comment, commentSize); + + if (thisDiskNumber != 0 || startCDDiskNumber != 0) + throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported); + if ((UInt16)numEntriesInCDOnThisDisk != ((UInt16)items.Size()) || + (UInt16)numEntriesInCD != ((UInt16)items.Size()) || + (UInt32)cdSize != (UInt32)centralDirectorySize || + ((UInt32)(cdStartOffsetFromRecord) != (UInt32)centralDirectoryStartOffset && (!items.IsEmpty()))) ThrowIncorrectArchiveException(); - m_ArchiveInfo.CommentPosition = m_Position; - m_ArchiveInfo.CommentSize = endOfCentralDirHeader.CommentSize; return S_OK; } -ISequentialInStream* CInArchive::CreateLimitedStream(UINT64 position, UINT64 size) +ISequentialInStream* CInArchive::CreateLimitedStream(UInt64 position, UInt64 size) { CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; CMyComPtr<ISequentialInStream> inStream(streamSpec); @@ -365,12 +585,13 @@ IInStream* CInArchive::CreateStream() return inStream.Detach(); } -bool CInArchive::SeekInArchive(UINT64 position) +bool CInArchive::SeekInArchive(UInt64 position) { - UINT64 newPosition; + UInt64 newPosition; if(m_Stream->Seek(position, STREAM_SEEK_SET, &newPosition) != S_OK) return false; return (newPosition == position); } }} + diff --git a/7zip/Archive/Zip/ZipIn.h b/7zip/Archive/Zip/ZipIn.h index 606653dd..8f873578 100755 --- a/7zip/Archive/Zip/ZipIn.h +++ b/7zip/Archive/Zip/ZipIn.h @@ -1,7 +1,5 @@ // Archive/ZipIn.h -#pragma once - #ifndef __ZIP_IN_H #define __ZIP_IN_H @@ -17,7 +15,7 @@ namespace NZip { class CInArchiveException { public: - enum CCauseType + enum ECauseType { kUnexpectedEndOfArchive = 0, kArchiceHeaderCRCError, @@ -29,53 +27,58 @@ public: kSeekStreamError } Cause; - CInArchiveException(CCauseType cause): Cause(cause) {} + CInArchiveException(ECauseType cause): Cause(cause) {} }; class CInArchiveInfo { public: - UINT64 StartPosition; - UINT64 CommentPosition; - UINT16 CommentSize; - bool IsCommented() const { return (CommentSize != 0); }; + UInt64 StartPosition; + CByteBuffer Comment; + void Clear() { Comment.SetCapacity(0); } }; class CProgressVirt { public: - STDMETHOD(SetCompleted)(const UINT64 *numFiles) PURE; + STDMETHOD(SetCompleted)(const UInt64 *numFiles) PURE; }; class CInArchive { CMyComPtr<IInStream> m_Stream; - UINT32 m_Signature; - UINT64 m_StreamStartPosition; - UINT64 m_Position; + UInt32 m_Signature; + UInt64 m_StreamStartPosition; + UInt64 m_Position; CInArchiveInfo m_ArchiveInfo; AString m_NameBuffer; - bool FindAndReadMarker(const UINT64 *searchHeaderSizeLimit); - bool ReadSignature(UINT32 &signature); - AString ReadFileName(UINT32 nameSize); + bool FindAndReadMarker(const UInt64 *searchHeaderSizeLimit); + bool ReadUInt32(UInt32 &signature); + AString ReadFileName(UInt32 nameSize); - HRESULT ReadBytes(void *data, UINT32 size, UINT32 *processedSize); - bool ReadBytesAndTestSize(void *data, UINT32 size); - void SafeReadBytes(void *data, UINT32 size); + HRESULT ReadBytes(void *data, UInt32 size, UInt32 *processedSize); + bool ReadBytesAndTestSize(void *data, UInt32 size); + void SafeReadBytes(void *data, UInt32 size); + void ReadBuffer(CByteBuffer &buffer, UInt32 size); + Byte ReadByte(); + UInt16 ReadUInt16(); + UInt32 ReadUInt32(); + UInt64 ReadUInt64(); - void IncreasePositionValue(UINT64 addValue); - void IncreaseRealPosition(UINT64 addValue); + void IncreaseRealPosition(UInt64 addValue); void ThrowIncorrectArchiveException(); + void ReadExtra(UInt32 extraSize, CExtraBlock &extraBlock, + UInt64 &unpackSize, UInt64 &packSize, UInt64 &localHeaderOffset, UInt32 &diskStartNumber); public: HRESULT ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *progress); - bool Open(IInStream *inStream, const UINT64 *searchHeaderSizeLimit); + bool Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit); void Close(); void GetArchiveInfo(CInArchiveInfo &archiveInfo) const; - void DirectGetBytes(void *data, UINT32 num); - bool SeekInArchive(UINT64 position); - ISequentialInStream *CreateLimitedStream(UINT64 position, UINT64 size); + void DirectGetBytes(void *data, UInt32 num); + bool SeekInArchive(UInt64 position); + ISequentialInStream *CreateLimitedStream(UInt64 position, UInt64 size); IInStream* CreateStream(); }; diff --git a/7zip/Archive/Zip/ZipItem.cpp b/7zip/Archive/Zip/ZipItem.cpp index bb52624c..8a7fe75d 100755 --- a/7zip/Archive/Zip/ZipItem.cpp +++ b/7zip/Archive/Zip/ZipItem.cpp @@ -4,6 +4,7 @@ #include "ZipHeader.h" #include "ZipItem.h" +#include "../Common/ItemNameUtils.h" namespace NArchive { namespace NZip { @@ -41,17 +42,8 @@ static const char *kUnknownAttributes = "Unknown file attributes"; bool CItem::IsDirectory() const { - if (!Name.IsEmpty()) - { - #ifdef WIN32 - LPCSTR prev = CharPrevExA(GetCodePage(), Name, &Name[Name.Length()], 0); - if (*prev == '/') - return true; - #else - if (Name[Name.Length() - 1) == '/') - return true; - #endif - } + if (NItemName::HasTailSlash(Name, GetCodePage())) + return true; WORD highAttributes = WORD((ExternalAttributes >> 16 ) & 0xFFFF); switch(MadeByVersion.HostOS) { @@ -91,7 +83,7 @@ bool CItem::IsDirectory() const } } -UINT32 CItem::GetWinAttributes() const +UInt32 CItem::GetWinAttributes() const { DWORD winAttributes; switch(MadeByVersion.HostOS) diff --git a/7zip/Archive/Zip/ZipItem.h b/7zip/Archive/Zip/ZipItem.h index d1b21fb2..c12d85c7 100755 --- a/7zip/Archive/Zip/ZipItem.h +++ b/7zip/Archive/Zip/ZipItem.h @@ -1,45 +1,67 @@ // Archive/ZipItem.h -#pragma once - #ifndef __ARCHIVE_ZIP_ITEM_H #define __ARCHIVE_ZIP_ITEM_H #include "Common/Types.h" #include "Common/String.h" +#include "Common/Buffer.h" + +#include "ZipHeader.h" namespace NArchive { namespace NZip { struct CVersion { - BYTE Version; - BYTE HostOS; + Byte Version; + Byte HostOS; }; bool operator==(const CVersion &v1, const CVersion &v2); bool operator!=(const CVersion &v1, const CVersion &v2); +struct CExtraSubBlock +{ + UInt16 ID; + CByteBuffer Data; +}; + +struct CExtraBlock +{ + CObjectVector<CExtraSubBlock> SubBlocks; + void Clear() { SubBlocks.Clear(); } + UInt32 GetSize() const + { + UInt32 res = 0; + for (int i = 0; i < SubBlocks.Size(); i++) + res += SubBlocks[i].Data.GetCapacity() + 2 + 2; + return res; + } +}; + + class CItem { public: CVersion MadeByVersion; CVersion ExtractVersion; - UINT16 Flags; - UINT16 CompressionMethod; - UINT32 Time; - UINT32 FileCRC; - UINT32 PackSize; - UINT32 UnPackSize; - UINT16 InternalAttributes; - UINT32 ExternalAttributes; + UInt16 Flags; + UInt16 CompressionMethod; + UInt32 Time; + UInt32 FileCRC; + UInt64 PackSize; + UInt64 UnPackSize; + UInt16 InternalAttributes; + UInt32 ExternalAttributes; AString Name; - UINT32 LocalHeaderPosition; - UINT16 LocalExtraSize; - UINT16 CentralExtraSize; - UINT16 CommentSize; + UInt64 LocalHeaderPosition; + UInt16 LocalExtraSize; + + CExtraBlock CentralExtra; + CByteBuffer Comment; bool IsEncrypted() const; @@ -48,14 +70,16 @@ public: bool IsDirectory() const; bool IgnoreItem() const { return false; } - UINT32 GetWinAttributes() const; + UInt32 GetWinAttributes() const; bool HasDescriptor() const; - #ifdef WIN32 WORD GetCodePage() const - { return (MadeByVersion.HostOS == NFileHeader::NHostOS::kFAT) ? CP_OEMCP : CP_ACP; } - #endif + { + return (MadeByVersion.HostOS == NFileHeader::NHostOS::kFAT + || MadeByVersion.HostOS == NFileHeader::NHostOS::kNTFS + ) ? CP_OEMCP : CP_ACP; + } private: void SetFlagBits(int startBitNumber, int numBits, int value); diff --git a/7zip/Archive/Zip/ZipItemEx.h b/7zip/Archive/Zip/ZipItemEx.h index 6d8e3ce1..3666926d 100755 --- a/7zip/Archive/Zip/ZipItemEx.h +++ b/7zip/Archive/Zip/ZipItemEx.h @@ -1,12 +1,8 @@ // Archive/ZipItemEx.h -#pragma once - #ifndef __ARCHIVE_ZIP_ITEMEX_H #define __ARCHIVE_ZIP_ITEMEX_H -#include "Common/Vector.h" - #include "ZipHeader.h" #include "ZipItem.h" @@ -16,32 +12,17 @@ namespace NZip { class CItemEx: public CItem { public: - UINT16 FileHeaderWithNameSize; - UINT64 CentralExtraPosition; + UInt32 FileHeaderWithNameSize; - UINT32 GetLocalFullSize() const + UInt64 GetLocalFullSize() const { return FileHeaderWithNameSize + LocalExtraSize + PackSize + - (HasDescriptor() ? sizeof(NFileHeader::CDataDescriptor) : 0); }; - - UINT32 GetCentralExtraPlusCommentSize() const - { return CentralExtraSize + CommentSize; }; - - UINT64 GetCommentPosition() const - { return CentralExtraPosition + CentralExtraSize; }; - - bool IsCommented() const - { return CommentSize != 0; }; - - UINT64 GetLocalExtraPosition() const + (HasDescriptor() ? NFileHeader::kDataDescriptorSize : 0); }; + UInt64 GetLocalExtraPosition() const { return LocalHeaderPosition + FileHeaderWithNameSize; }; - - UINT64 GetDataPosition() const + UInt64 GetDataPosition() const { return GetLocalExtraPosition() + LocalExtraSize; }; }; }} #endif - - - diff --git a/7zip/Archive/Zip/ZipOut.cpp b/7zip/Archive/Zip/ZipOut.cpp index 58da75d4..c4443f78 100755 --- a/7zip/Archive/Zip/ZipOut.cpp +++ b/7zip/Archive/Zip/ZipOut.cpp @@ -16,19 +16,36 @@ void COutArchive::Create(IOutStream *outStream) m_BasePosition = 0; } -void COutArchive::MoveBasePosition(UINT32 distanceToMove) +void COutArchive::MoveBasePosition(UInt64 distanceToMove) { m_BasePosition += distanceToMove; // test overflow } -void COutArchive::PrepareWriteCompressedData(UINT16 fileNameLength) +void COutArchive::PrepareWriteCompressedDataZip64(UInt16 fileNameLength, bool isZip64) { - m_LocalFileHeaderSize = sizeof(NFileHeader::CLocalBlockFull) + fileNameLength; + m_IsZip64 = isZip64; + m_ExtraSize = isZip64 ? (4 + 8 + 8) : 0; + m_LocalFileHeaderSize = 4 + NFileHeader::kLocalBlockSize + fileNameLength + m_ExtraSize; } -void COutArchive::WriteBytes(const void *buffer, UINT32 size) +void COutArchive::PrepareWriteCompressedData(UInt16 fileNameLength, UInt64 unPackSize) { - UINT32 processedSize; + // We test it to 0xF8000000 to support case when compressed size + // can be larger than uncompressed size. + PrepareWriteCompressedDataZip64(fileNameLength, unPackSize >= 0xF8000000); +} + +void COutArchive::PrepareWriteCompressedData2(UInt16 fileNameLength, UInt64 unPackSize, UInt64 packSize) +{ + bool isUnPack64 = unPackSize >= 0xFFFFFFFF; + bool isPack64 = packSize >= 0xFFFFFFFF; + bool isZip64 = isPack64 || isUnPack64; + PrepareWriteCompressedDataZip64(fileNameLength, isZip64); +} + +void COutArchive::WriteBytes(const void *buffer, UInt32 size) +{ + UInt32 processedSize; if(m_Stream->Write(buffer, size, &processedSize) != S_OK) throw 0; if(processedSize != size) @@ -36,80 +53,177 @@ void COutArchive::WriteBytes(const void *buffer, UINT32 size) m_BasePosition += size; } -void COutArchive::WriteLocalHeader(const CItem &item) +void COutArchive::WriteByte(Byte b) { - NFileHeader::CLocalBlockFull fileHeader; - fileHeader.Signature = NSignature::kLocalFileHeader; - NFileHeader::CLocalBlock &header = fileHeader.Header; + WriteBytes(&b, 1); +} - header.ExtractVersion.HostOS = item.ExtractVersion.HostOS; - header.ExtractVersion.Version = item.ExtractVersion.Version; - header.Flags = item.Flags; - header.CompressionMethod = item.CompressionMethod; - header.Time = item.Time; - header.FileCRC = item.FileCRC; - header.PackSize = item.PackSize; - header.UnPackSize = item.UnPackSize; +void COutArchive::WriteUInt16(UInt16 value) +{ + for (int i = 0; i < 2; i++) + { + WriteByte((Byte)value); + value >>= 8; + } +} - header.NameSize = item.Name.Length(); - header.ExtraSize = item.LocalExtraSize; // test it; +void COutArchive::WriteUInt32(UInt32 value) +{ + for (int i = 0; i < 4; i++) + { + WriteByte((Byte)value); + value >>= 8; + } +} +void COutArchive::WriteUInt64(UInt64 value) +{ + for (int i = 0; i < 8; i++) + { + WriteByte((Byte)value); + value >>= 8; + } +} + +HRESULT COutArchive::WriteLocalHeader(const CItem &item) +{ m_Stream->Seek(m_BasePosition, STREAM_SEEK_SET, NULL); - WriteBytes(&fileHeader, sizeof(fileHeader)); - WriteBytes((const char *)item.Name, header.NameSize); - MoveBasePosition(header.ExtraSize + header.PackSize); + + bool isZip64 = m_IsZip64 || item.PackSize >= 0xFFFFFFFF || item.UnPackSize >= 0xFFFFFFFF; + + WriteUInt32(NSignature::kLocalFileHeader); + WriteByte(item.ExtractVersion.Version); + WriteByte(item.ExtractVersion.HostOS); + WriteUInt16(item.Flags); + WriteUInt16(item.CompressionMethod); + WriteUInt32(item.Time); + WriteUInt32(item.FileCRC); + WriteUInt32(isZip64 ? 0xFFFFFFFF: (UInt32)item.PackSize); + WriteUInt32(isZip64 ? 0xFFFFFFFF: (UInt32)item.UnPackSize); + WriteUInt16(item.Name.Length()); + UInt16 localExtraSize = isZip64 ? (4 + 16): 0; + if (localExtraSize > m_ExtraSize) + return E_FAIL; + WriteUInt16(m_ExtraSize); // test it; + WriteBytes((const char *)item.Name, item.Name.Length()); + if (m_ExtraSize > 0) + { + UInt16 remain = m_ExtraSize - 4; + WriteUInt16(0x1); // Zip64 Tag; + WriteUInt16(remain); + if (isZip64) + { + WriteUInt64(item.UnPackSize); + WriteUInt64(item.PackSize); + remain -= 16; + } + for (int i = 0; i < remain; i++) + WriteByte(0); + } + MoveBasePosition(item.PackSize); m_Stream->Seek(m_BasePosition, STREAM_SEEK_SET, NULL); + return S_OK; } void COutArchive::WriteCentralHeader(const CItem &item) { - NFileHeader::CBlockFull fileHeader; - fileHeader.Signature = NSignature::kCentralFileHeader; - NFileHeader::CBlock &header = fileHeader.Header; - - header.MadeByVersion.HostOS = item.MadeByVersion.HostOS; - header.MadeByVersion.Version = item.MadeByVersion.Version; - header.ExtractVersion.HostOS = item.ExtractVersion.HostOS; - header.ExtractVersion.Version = item.ExtractVersion.Version; - header.Flags = item.Flags; - header.CompressionMethod = item.CompressionMethod; - header.Time = item.Time; - header.FileCRC = item.FileCRC; - header.PackSize = item.PackSize; - header.UnPackSize = item.UnPackSize; - - header.NameSize = item.Name.Length(); - - header.ExtraSize = item.CentralExtraSize; // test it; - header.CommentSize = item.CommentSize; - header.DiskNumberStart = 0; - header.InternalAttributes = item.InternalAttributes; - header.ExternalAttributes = item.ExternalAttributes; - header.LocalHeaderOffset = item.LocalHeaderPosition; - m_Stream->Seek(m_BasePosition, STREAM_SEEK_SET, NULL); - WriteBytes(&fileHeader, sizeof(fileHeader)); - WriteBytes((const char *)item.Name, header.NameSize); -} -void COutArchive::WriteEndOfCentralDir(const COutArchiveInfo &archiveInfo) -{ - CEndOfCentralDirectoryRecordFull fileHeader; - fileHeader.Signature = NSignature::kEndOfCentralDir; - CEndOfCentralDirectoryRecord &header = fileHeader.Header; - - header.ThisDiskNumber = 0; - header.StartCentralDirectoryDiskNumber = 0; - - header.NumEntriesInCentaralDirectoryOnThisDisk = archiveInfo.NumEntriesInCentaralDirectory; - header.NumEntriesInCentaralDirectory = archiveInfo.NumEntriesInCentaralDirectory; + bool isUnPack64 = item.UnPackSize >= 0xFFFFFFFF; + bool isPack64 = item.PackSize >= 0xFFFFFFFF; + bool isPosition64 = item.LocalHeaderPosition >= 0xFFFFFFFF; + bool isZip64 = isPack64 || isUnPack64 || isPosition64; - header.CentralDirectorySize = archiveInfo.CentralDirectorySize; - header.CentralDirectoryStartOffset = archiveInfo.CentralDirectoryStartOffset; - header.CommentSize = archiveInfo.CommentSize; + WriteUInt32(NSignature::kCentralFileHeader); + WriteByte(item.MadeByVersion.Version); + WriteByte(item.MadeByVersion.HostOS); + WriteByte(item.ExtractVersion.Version); + WriteByte(item.ExtractVersion.HostOS); + WriteUInt16(item.Flags); + WriteUInt16(item.CompressionMethod); + WriteUInt32(item.Time); + WriteUInt32(item.FileCRC); + WriteUInt32(isPack64 ? 0xFFFFFFFF: (UInt32)item.PackSize); + WriteUInt32(isUnPack64 ? 0xFFFFFFFF: (UInt32)item.UnPackSize); + WriteUInt16(item.Name.Length()); + UInt16 zip64ExtraSize = (isUnPack64 ? 8: 0) + (isPack64 ? 8: 0) + (isPosition64 ? 8: 0); + UInt16 centralExtraSize = isZip64 ? (4 + zip64ExtraSize) : 0; + centralExtraSize += (UInt16)item.CentralExtra.GetSize(); + WriteUInt16(centralExtraSize); // test it; + WriteUInt16(item.Comment.GetCapacity()); + WriteUInt16(0); // DiskNumberStart; + WriteUInt16(item.InternalAttributes); + WriteUInt32(item.ExternalAttributes); + WriteUInt32(isPosition64 ? 0xFFFFFFFF: (UInt32)item.LocalHeaderPosition); + WriteBytes((const char *)item.Name, item.Name.Length()); + if (isZip64) + { + WriteUInt16(0x1); // Zip64 Tag; + WriteUInt16(zip64ExtraSize); + if(isUnPack64) + WriteUInt64(item.UnPackSize); + if(isPack64) + WriteUInt64(item.PackSize); + if(isPosition64) + WriteUInt64(item.LocalHeaderPosition); + } + if (item.CentralExtra.SubBlocks.Size() != 0) + { + for (int i = 0; i < item.CentralExtra.SubBlocks.Size(); i++) + { + CExtraSubBlock subBlock = item.CentralExtra.SubBlocks[i]; + WriteUInt16(subBlock.ID); + WriteUInt16((UInt16)subBlock.Data.GetCapacity()); + WriteBytes(subBlock.Data, subBlock.Data.GetCapacity()); + } + } + if (item.Comment.GetCapacity() > 0) + WriteBytes(item.Comment, item.Comment.GetCapacity()); +} +void COutArchive::WriteCentralDir(const CObjectVector<CItem> &items, const CByteBuffer &comment) +{ m_Stream->Seek(m_BasePosition, STREAM_SEEK_SET, NULL); - WriteBytes(&fileHeader, sizeof(fileHeader)); + + UInt64 cdOffset = GetCurrentPosition(); + for(int i = 0; i < items.Size(); i++) + WriteCentralHeader(items[i]); + UInt64 cd64EndOffset = GetCurrentPosition(); + UInt64 cdSize = cd64EndOffset - cdOffset; + bool cdOffset64 = cdOffset >= 0xFFFFFFFF; + bool cdSize64 = cdSize >= 0xFFFFFFFF; + bool items64 = items.Size() >= 0xFFFF; + bool isZip64 = (cdOffset64 || cdSize64 || items64); + + if (isZip64) + { + WriteUInt32(NSignature::kZip64EndOfCentralDir); + WriteUInt64(kZip64EndOfCentralDirRecordSize); // ThisDiskNumber = 0; + WriteUInt16(45); // version + WriteUInt16(45); // version + WriteUInt32(0); // ThisDiskNumber = 0; + WriteUInt32(0); // StartCentralDirectoryDiskNumber;; + WriteUInt64((UInt64)items.Size()); + WriteUInt64((UInt64)items.Size()); + WriteUInt64((UInt64)cdSize); + WriteUInt64((UInt64)cdOffset); + + WriteUInt32(NSignature::kZip64EndOfCentralDirLocator); + WriteUInt32(0); // number of the disk with the start of the zip64 end of central directory + WriteUInt64(cd64EndOffset); + WriteUInt32(1); // total number of disks + } + WriteUInt32(NSignature::kEndOfCentralDir); + WriteUInt16(0); // ThisDiskNumber = 0; + WriteUInt16(0); // StartCentralDirectoryDiskNumber; + WriteUInt16(items64 ? 0xFFFF: (UInt16)items.Size()); + WriteUInt16(items64 ? 0xFFFF: (UInt16)items.Size()); + WriteUInt32(cdSize64 ? 0xFFFFFFFF: (UInt32)cdSize); + WriteUInt32(cdOffset64 ? 0xFFFFFFFF: (UInt32)cdOffset); + UInt16 commentSize = comment.GetCapacity(); + WriteUInt16(commentSize); + if (commentSize > 0) + WriteBytes((const Byte *)comment, commentSize); } void COutArchive::CreateStreamForCompressing(IOutStream **outStream) diff --git a/7zip/Archive/Zip/ZipOut.h b/7zip/Archive/Zip/ZipOut.h index 8f9d98e5..79401243 100755 --- a/7zip/Archive/Zip/ZipOut.h +++ b/7zip/Archive/Zip/ZipOut.h @@ -1,7 +1,5 @@ // ZipOut.h -#pragma once - #ifndef __ZIP_OUT_H #define __ZIP_OUT_H @@ -9,39 +7,38 @@ #include "../../IStream.h" -#include "ZipHeader.h" #include "ZipItem.h" namespace NArchive { namespace NZip { -class COutArchiveInfo -{ -public: - UINT16 NumEntriesInCentaralDirectory; - UINT32 CentralDirectorySize; - UINT32 CentralDirectoryStartOffset; - UINT16 CommentSize; -}; - class COutArchive { CMyComPtr<IOutStream> m_Stream; - UINT32 m_BasePosition; - UINT32 m_LocalFileHeaderSize; + UInt64 m_BasePosition; + UInt32 m_LocalFileHeaderSize; + UInt32 m_ExtraSize; + bool m_IsZip64; - void WriteBytes(const void *buffer, UINT32 size); + void WriteBytes(const void *buffer, UInt32 size); + void WriteByte(Byte b); + void WriteUInt16(UInt16 value); + void WriteUInt32(UInt32 value); + void WriteUInt64(UInt64 value); + void WriteExtraHeader(const CItem &item); + void WriteCentralHeader(const CItem &item); public: void Create(IOutStream *outStream); - void MoveBasePosition(UINT32 distanceToMove); - UINT32 GetCurrentPosition() const { return m_BasePosition; }; - void PrepareWriteCompressedData(UINT16 fileNameLength); - void WriteLocalHeader(const CItem &item); - - void WriteCentralHeader(const CItem &item); - void WriteEndOfCentralDir(const COutArchiveInfo &archiveInfo); + void MoveBasePosition(UInt64 distanceToMove); + UInt64 GetCurrentPosition() const { return m_BasePosition; }; + void PrepareWriteCompressedDataZip64(UInt16 fileNameLength, bool isZip64); + void PrepareWriteCompressedData(UInt16 fileNameLength, UInt64 unPackSize); + void PrepareWriteCompressedData2(UInt16 fileNameLength, UInt64 unPackSize, UInt64 packSize); + HRESULT WriteLocalHeader(const CItem &item); + + void WriteCentralDir(const CObjectVector<CItem> &items, const CByteBuffer &comment); void CreateStreamForCompressing(IOutStream **outStream); void CreateStreamForCopying(ISequentialOutStream **outStream); diff --git a/7zip/Archive/Zip/ZipUpdate.cpp b/7zip/Archive/Zip/ZipUpdate.cpp index b9a5637b..d653a31b 100755 --- a/7zip/Archive/Zip/ZipUpdate.cpp +++ b/7zip/Archive/Zip/ZipUpdate.cpp @@ -7,6 +7,7 @@ #include "ZipOut.h" #include "Common/Defs.h" +#include "Common/AutoPtr.h" #include "Common/StringConvert.h" #include "Windows/Defs.h" @@ -16,16 +17,15 @@ #include "../Common/InStreamWithCRC.h" -using namespace std; namespace NArchive { namespace NZip { -static const BYTE kMadeByHostOS = NFileHeader::NHostOS::kFAT; -static const BYTE kExtractHostOS = NFileHeader::NHostOS::kFAT; +static const Byte kMadeByHostOS = NFileHeader::NHostOS::kFAT; +static const Byte kExtractHostOS = NFileHeader::NHostOS::kFAT; -static const BYTE kMethodForDirectory = NFileHeader::NCompressionMethod::kStored; -static const BYTE kExtractVersionForDirectory = NFileHeader::NCompressionMethod::kStoreExtractVersion; +static const Byte kMethodForDirectory = NFileHeader::NCompressionMethod::kStored; +static const Byte kExtractVersionForDirectory = NFileHeader::NCompressionMethod::kStoreExtractVersion; static HRESULT CopyBlock(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress) @@ -46,9 +46,9 @@ static HRESULT WriteRange(IInStream *inStream, COutArchive &outArchive, const CUpdateRange &range, IProgress *progress, - UINT64 ¤tComplexity) + UInt64 ¤tComplexity) { - UINT64 position; + UInt64 position; inStream->Seek(range.Position, STREAM_SEEK_SET, &position); CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; @@ -75,15 +75,19 @@ static HRESULT UpdateOneFile(IInStream *inStream, const CCompressionMethodMode &options, CAddCommon &compressor, const CUpdateItem &updateItem, - UINT64 ¤tComplexity, + UInt64 ¤tComplexity, IArchiveUpdateCallback *updateCallback, - CItemEx &fileHeader) + CItemEx &fileHeader, + CMyComPtr<ISequentialInStream> &fileInStream2) { CMyComPtr<IInStream> fileInStream; - RINOK(updateCallback->GetStream(updateItem.IndexInClient, &fileInStream)); + if (fileInStream2) + { + RINOK(fileInStream2.QueryInterface(IID_IInStream, &fileInStream)); + } bool isDirectory; - UINT32 fileSize = updateItem.Size; + UInt64 fileSize = updateItem.Size; fileHeader.UnPackSize = fileSize; if (updateItem.NewProperties) @@ -96,7 +100,7 @@ static HRESULT UpdateOneFile(IInStream *inStream, else isDirectory = fileHeader.IsDirectory(); - archive.PrepareWriteCompressedData(fileHeader.Name.Length()); + archive.PrepareWriteCompressedData(fileHeader.Name.Length(), fileSize); fileHeader.LocalHeaderPosition = archive.GetCurrentPosition(); fileHeader.MadeByVersion.HostOS = kMadeByHostOS; @@ -137,21 +141,24 @@ static HRESULT UpdateOneFile(IInStream *inStream, RINOK(compressor.Compress(inStream, outStream, fileSize, compressProgress, compressingResult)); - fileHeader.PackSize = (UINT32)compressingResult.PackSize; + fileHeader.PackSize = compressingResult.PackSize; fileHeader.CompressionMethod = compressingResult.Method; fileHeader.ExtractVersion.Version = compressingResult.ExtractVersion; fileHeader.FileCRC = inStreamSpec->GetCRC(); - fileHeader.UnPackSize = (UINT32)inStreamSpec->GetSize(); + fileHeader.UnPackSize = inStreamSpec->GetSize(); } } fileHeader.SetEncrypted(options.PasswordIsDefined); + /* fileHeader.CommentSize = (updateItem.Commented) ? WORD(updateItem.CommentRange.Size) : 0; + */ fileHeader.LocalExtraSize = 0; - fileHeader.CentralExtraSize = 0; + + // fileHeader.CentralExtraSize = 0; - archive.WriteLocalHeader(fileHeader); + RINOK(archive.WriteLocalHeader(fileHeader)); currentComplexity += fileSize; return updateCallback->SetOperationResult( NArchive::NUpdate::NOperationResult::kOK); @@ -162,12 +169,10 @@ static HRESULT Update2(COutArchive &archive, const CObjectVector<CItemEx> &inputItems, const CObjectVector<CUpdateItem> &updateItems, const CCompressionMethodMode *options, - bool commentRangeAssigned, - const CUpdateRange &commentRange, + const CByteBuffer &comment, IArchiveUpdateCallback *updateCallback) { - UINT64 complexity = 0; - UINT64 estimatedArchiveSize = (1<<20); // sfx part + UInt64 complexity = 0; int i; for(i = 0; i < updateItems.Size(); i++) @@ -176,36 +181,33 @@ static HRESULT Update2(COutArchive &archive, if (updateItem.NewData) { complexity += updateItem.Size; + /* if (updateItem.Commented) complexity += updateItem.CommentRange.Size; - estimatedArchiveSize += updateItem.Name.Length() * 2 + 100; + */ } else { const CItemEx &inputItem = inputItems[updateItem.IndexInArchive]; complexity += inputItem.GetLocalFullSize(); - complexity += inputItem.GetCentralExtraPlusCommentSize(); + // complexity += inputItem.GetCentralExtraPlusCommentSize(); } + complexity += NFileHeader::kLocalBlockSize; + complexity += NFileHeader::kCentralBlockSize; } - complexity += updateItems.Size(); - complexity += updateItems.Size(); - - estimatedArchiveSize += complexity; - if (estimatedArchiveSize > 0xFFFFFFFF) - return E_NOTIMPL; - - if (commentRangeAssigned) - complexity += commentRange.Size; + if (comment != 0) + complexity += comment.GetCapacity(); complexity++; // end of central updateCallback->SetTotal(complexity); - auto_ptr<CAddCommon> compressor; + CMyAutoPtr<CAddCommon> compressor; complexity = 0; - CObjectVector<CItemEx> items; + CObjectVector<CItem> items; + CRecordVector<UInt32> updateIndices; for(i = 0; i < updateItems.Size(); i++) { @@ -220,10 +222,23 @@ static HRESULT Update2(COutArchive &archive, { if(compressor.get() == NULL) { - compressor = auto_ptr<CAddCommon>(new CAddCommon(*options)); + CMyAutoPtr<CAddCommon> tmp(new CAddCommon(*options)); + compressor = tmp; + } + CMyComPtr<ISequentialInStream> fileInStream2; + HRESULT res = updateCallback->GetStream(updateItem.IndexInClient, &fileInStream2); + if (res == S_FALSE) + { + complexity += updateItem.Size; + complexity++; + RINOK(updateCallback->SetOperationResult( + NArchive::NUpdate::NOperationResult::kOK)); + continue; } + RINOK(res); RINOK(UpdateOneFile(inStream, archive, *options, - *compressor, updateItem, complexity, updateCallback, item)); + *compressor, updateItem, complexity, updateCallback, item, + fileInStream2)); } else { @@ -241,14 +256,13 @@ static HRESULT Update2(COutArchive &archive, // Test it item.Name = updateItem.Name; item.Time = updateItem.Time; - item.CentralExtraSize = 0; + item.CentralExtra.Clear(); item.LocalExtraSize = 0; - archive.PrepareWriteCompressedData(item.Name.Length()); + archive.PrepareWriteCompressedData2(item.Name.Length(), item.UnPackSize, item.PackSize); item.LocalHeaderPosition = archive.GetCurrentPosition(); archive.SeekToPackedDataPosition(); - RINOK(WriteRange(inStream, archive, range, - updateCallback, complexity)); + RINOK(WriteRange(inStream, archive, range, updateCallback, complexity)); archive.WriteLocalHeader(item); } else @@ -258,91 +272,46 @@ static HRESULT Update2(COutArchive &archive, // set new header position item.LocalHeaderPosition = archive.GetCurrentPosition(); - RINOK(WriteRange(inStream, archive, range, - updateCallback, complexity)); + RINOK(WriteRange(inStream, archive, range, updateCallback, complexity)); archive.MoveBasePosition(range.Size); } } items.Add(item); - complexity++; - } - DWORD centralDirStartPosition = archive.GetCurrentPosition(); - for(i = 0; i < items.Size(); i++) - { - archive.WriteCentralHeader(items[i]); - const CUpdateItem &updateItem = updateItems[i]; - if (updateItem.NewProperties) - { - if (updateItem.Commented) - { - const CUpdateRange range = updateItem.CommentRange; - RINOK(WriteRange(inStream, archive, range, - updateCallback, complexity)); - archive.MoveBasePosition(range.Size); - } - } - else - { - const CItemEx item = items[i]; - CUpdateRange range(item.CentralExtraPosition, - item.GetCentralExtraPlusCommentSize()); - RINOK(WriteRange(inStream, archive, range, - updateCallback, complexity)); - archive.MoveBasePosition(range.Size); - } - complexity++; + updateIndices.Add(i); + complexity += NFileHeader::kLocalBlockSize; } - COutArchiveInfo archiveInfo; - archiveInfo.NumEntriesInCentaralDirectory = items.Size(); - archiveInfo.CentralDirectorySize = archive.GetCurrentPosition() - - centralDirStartPosition; - archiveInfo.CentralDirectoryStartOffset = centralDirStartPosition; - archiveInfo.CommentSize = commentRangeAssigned ? WORD(commentRange.Size) : 0; - archive.WriteEndOfCentralDir(archiveInfo); - if (commentRangeAssigned) - RINOK(WriteRange(inStream, archive, commentRange, - updateCallback, complexity)); - complexity++; // end of central + + archive.WriteCentralDir(items, comment); return S_OK; } HRESULT Update( const CObjectVector<CItemEx> &inputItems, const CObjectVector<CUpdateItem> &updateItems, - IOutStream *outStream, + ISequentialOutStream *seqOutStream, CInArchive *inArchive, CCompressionMethodMode *compressionMethodMode, IArchiveUpdateCallback *updateCallback) { - DWORD startBlockSize; - bool commentRangeAssigned; - CUpdateRange commentRange; + CMyComPtr<IOutStream> outStream; + RINOK(seqOutStream->QueryInterface(IID_IOutStream, (void **)&outStream)); + if (!outStream) + return E_NOTIMPL; + + CInArchiveInfo archiveInfo; if(inArchive != 0) - { - CInArchiveInfo archiveInfo; inArchive->GetArchiveInfo(archiveInfo); - startBlockSize = archiveInfo.StartPosition; - commentRangeAssigned = archiveInfo.IsCommented(); - if (commentRangeAssigned) - { - commentRange.Position = archiveInfo.CommentPosition; - commentRange.Size = archiveInfo.CommentSize; - } - } else - { - startBlockSize = 0; - commentRangeAssigned = false; - } + archiveInfo.StartPosition = 0; COutArchive outArchive; outArchive.Create(outStream); - if (startBlockSize > 0) + if (archiveInfo.StartPosition > 0) { CMyComPtr<ISequentialInStream> inStream; - inStream.Attach(inArchive->CreateLimitedStream(0, startBlockSize)); + inStream.Attach(inArchive->CreateLimitedStream(0, archiveInfo.StartPosition)); RINOK(CopyBlockToArchive(inStream, outArchive, NULL)); - outArchive.MoveBasePosition(startBlockSize); + outArchive.MoveBasePosition(archiveInfo.StartPosition); } CMyComPtr<IInStream> inStream; if(inArchive != 0) @@ -351,7 +320,7 @@ HRESULT Update( return Update2(outArchive, inStream, inputItems, updateItems, compressionMethodMode, - commentRangeAssigned, commentRange, updateCallback); + archiveInfo.Comment, updateCallback); } }} diff --git a/7zip/Archive/Zip/ZipUpdate.h b/7zip/Archive/Zip/ZipUpdate.h index 87a4e31e..c8cdfbbf 100755 --- a/7zip/Archive/Zip/ZipUpdate.h +++ b/7zip/Archive/Zip/ZipUpdate.h @@ -1,7 +1,5 @@ // Zip/Update.h -#pragma once - #ifndef __ZIP_UPDATE_H #define __ZIP_UPDATE_H @@ -19,11 +17,10 @@ namespace NZip { struct CUpdateRange { - UINT32 Position; - UINT32 Size; + UInt64 Position; + UInt64 Size; CUpdateRange() {}; - CUpdateRange(UINT32 position, UINT32 size): - Position(position), Size(size) {}; + CUpdateRange(UInt64 position, UInt64 size): Position(position), Size(size) {}; }; struct CUpdateItem @@ -33,23 +30,18 @@ struct CUpdateItem bool IsDirectory; int IndexInArchive; int IndexInClient; - UINT32 Attributes; - UINT32 Time; - UINT32 Size; + UInt32 Attributes; + UInt32 Time; + UInt64 Size; AString Name; - // bool ExistInArchive; - bool Commented; - CUpdateRange CommentRange; - /* - bool IsDirectory() const - { return ((Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0); }; - */ + // bool Commented; + // CUpdateRange CommentRange; }; HRESULT Update( const CObjectVector<CItemEx> &inputItems, const CObjectVector<CUpdateItem> &updateItems, - IOutStream *outStream, + ISequentialOutStream *seqOutStream, CInArchive *inArchive, CCompressionMethodMode *compressionMethodMode, IArchiveUpdateCallback *updateCallback); diff --git a/7zip/Archive/Zip/resource.rc b/7zip/Archive/Zip/resource.rc index afc35c0e..c662ab04 100755 --- a/7zip/Archive/Zip/resource.rc +++ b/7zip/Archive/Zip/resource.rc @@ -75,8 +75,8 @@ IDI_ICON1 ICON DISCARDABLE "zip.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,12,0,0 - PRODUCTVERSION 3,12,0,0 + FILEVERSION 4,19,0,0 + PRODUCTVERSION 4,19,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -94,14 +94,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Igor Pavlov\0" VALUE "FileDescription", "Zip Plugin for 7-Zip\0" - VALUE "FileVersion", "3, 12, 0, 0\0" + VALUE "FileVersion", "4, 19, 0, 0\0" VALUE "InternalName", "zip\0" - VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "zip.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "7-Zip\0" - VALUE "ProductVersion", "3, 12, 0, 0\0" + VALUE "ProductVersion", "4, 19, 0, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/7zip/Archive/cpio/CpioHandler.cpp b/7zip/Archive/cpio/CpioHandler.cpp index 3354e598..fb71e8b0 100755 --- a/7zip/Archive/cpio/CpioHandler.cpp +++ b/7zip/Archive/cpio/CpioHandler.cpp @@ -50,13 +50,13 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) return S_OK; } -STDMETHODIMP CHandler::GetNumberOfProperties(UINT32 *numProperties) +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) { *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); return S_OK; } -STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index, +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) { if(index >= sizeof(kProperties) / sizeof(kProperties[0])) @@ -68,20 +68,20 @@ STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index, return S_OK; } -STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UINT32 *numProperties) +STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) { *numProperties = 0; return S_OK; } -STDMETHODIMP CHandler::GetArchivePropertyInfo(UINT32 index, +STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) { return E_INVALIDARG; } STDMETHODIMP CHandler::Open(IInStream *inStream, - const UINT64 *maxCheckStartPosition, + const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) { COM_TRY_BEGIN @@ -98,7 +98,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, if (openArchiveCallback != NULL) { RINOK(openArchiveCallback->SetTotal(NULL, NULL)); - UINT64 numFiles = m_Items.Size(); + UInt64 numFiles = m_Items.Size(); RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); } @@ -114,10 +114,10 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, if (!filled) break; m_Items.Add(itemInfo); - archive.SkeepDataRecords(itemInfo.Size, itemInfo.OldHeader); + archive.SkeepDataRecords(itemInfo.Size, itemInfo.Align); if (openArchiveCallback != NULL) { - UINT64 numFiles = m_Items.Size(); + UInt64 numFiles = m_Items.Size(); RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); } } @@ -142,13 +142,13 @@ STDMETHODIMP CHandler::Close() return S_OK; } -STDMETHODIMP CHandler::GetNumberOfItems(UINT32 *numItems) +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) { *numItems = m_Items.Size(); return S_OK; } -STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value) +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant propVariant; @@ -194,23 +194,24 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *val COM_TRY_END } -STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, - INT32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - bool allFilesMode = (numItems == UINT32(-1)); + bool allFilesMode = (numItems == UInt32(-1)); if (allFilesMode) numItems = m_Items.Size(); if(numItems == 0) return S_OK; bool testMode = (_aTestMode != 0); - UINT64 totalSize = 0; - for(UINT32 i = 0; i < numItems; i++) + UInt64 totalSize = 0; + UInt32 i; + for(i = 0; i < numItems; i++) totalSize += m_Items[allFilesMode ? i : indices[i]].Size; extractCallback->SetTotal(totalSize); - UINT64 currentTotalSize = 0; - UINT64 currentItemSize; + UInt64 currentTotalSize = 0; + UInt64 currentItemSize; CMyComPtr<ICompressCoder> copyCoder; @@ -218,10 +219,10 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, { RINOK(extractCallback->SetCompleted(¤tTotalSize)); CMyComPtr<ISequentialOutStream> realOutStream; - INT32 askMode; + Int32 askMode; askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract; - INT32 index = allFilesMode ? i : indices[i]; + Int32 index = allFilesMode ? i : indices[i]; const CItemEx &itemInfo = m_Items[index]; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); diff --git a/7zip/Archive/cpio/CpioHandler.h b/7zip/Archive/cpio/CpioHandler.h index 3e887992..5ff70408 100755 --- a/7zip/Archive/cpio/CpioHandler.h +++ b/7zip/Archive/cpio/CpioHandler.h @@ -1,7 +1,5 @@ // Archive/cpio/Handler.h -#pragma once - #ifndef __ARCHIVE_CPIO_HANDLER_H #define __ARCHIVE_CPIO_HANDLER_H @@ -21,22 +19,22 @@ public: MY_UNKNOWN_IMP STDMETHOD(Open)(IInStream *stream, - const UINT64 *maxCheckStartPosition, + const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback); STDMETHOD(Close)(); - STDMETHOD(GetNumberOfItems)(UINT32 *numItems); - STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(Extract)(const UINT32* indices, UINT32 numItems, - INT32 testMode, IArchiveExtractCallback *extractCallback); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback); STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); - STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties); - STDMETHOD(GetPropertyInfo)(UINT32 index, + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType); - STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties); - STDMETHOD(GetArchivePropertyInfo)(UINT32 index, + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType); private: diff --git a/7zip/Archive/cpio/CpioHeader.cpp b/7zip/Archive/cpio/CpioHeader.cpp index 06704db7..9e4d99cb 100755 --- a/7zip/Archive/cpio/CpioHeader.cpp +++ b/7zip/Archive/cpio/CpioHeader.cpp @@ -12,10 +12,11 @@ namespace NFileHeader { { extern const char *kMagic1 = "070701"; extern const char *kMagic2 = "070702"; + extern const char *kMagic3 = "070707"; extern const char *kEndName = "TRAILER!!!"; - extern unsigned short kMagicForRecord2 = 0x71C7; - extern unsigned short kMagicForRecord2BE = 0xC771; + const Byte kMagicForRecord2[2] = { 0xC7, 0x71 }; + // unsigned short kMagicForRecord2BE = 0xC771; } }}} diff --git a/7zip/Archive/cpio/CpioHeader.h b/7zip/Archive/cpio/CpioHeader.h index 6943fc1d..40a0014a 100755 --- a/7zip/Archive/cpio/CpioHeader.h +++ b/7zip/Archive/cpio/CpioHeader.h @@ -1,7 +1,5 @@ // Archive/cpio/Header.h -#pragma once - #ifndef __ARCHIVE_CPIO_HEADER_H #define __ARCHIVE_CPIO_HEADER_H @@ -10,20 +8,19 @@ namespace NArchive { namespace NCpio { -#pragma pack( push, PragmacpioHeaders) -#pragma pack( push, 1) - namespace NFileHeader { namespace NMagic { extern const char *kMagic1; extern const char *kMagic2; + extern const char *kMagic3; extern const char *kEndName; - extern unsigned short kMagicForRecord2; - extern unsigned short kMagicForRecord2BE; + extern const Byte kMagicForRecord2[2]; } + const UInt32 kRecord2Size = 26; + /* struct CRecord2 { unsigned short c_magic; @@ -38,31 +35,35 @@ namespace NFileHeader unsigned short c_namesize; unsigned short c_filesizes[2]; }; - + */ + + const UInt32 kRecordSize = 110; + /* struct CRecord { - char Magic[6]; /* "070701" for "new" portable format, "070702" for CRC format */ + char Magic[6]; // "070701" for "new" portable format, "070702" for CRC format char inode[8]; char Mode[8]; char UID[8]; char GID[8]; char nlink[8]; char mtime[8]; - char Size[8]; /* must be 0 for FIFOs and directories */ + char Size[8]; // must be 0 for FIFOs and directories char DevMajor[8]; char DevMinor[8]; - char RDevMajor[8]; /*only valid for chr and blk special files*/ - char RDevMinor[8]; /*only valid for chr and blk special files*/ - char NameSize[8]; /*count includes terminating NUL in pathname*/ - char ChkSum[8]; /* 0 for "new" portable format; for CRC format the sum of all the bytes in the file */ - bool CheckMagic() + char RDevMajor[8]; //only valid for chr and blk special files + char RDevMinor[8]; //only valid for chr and blk special files + char NameSize[8]; // count includes terminating NUL in pathname + char ChkSum[8]; // 0 for "new" portable format; for CRC format the sum of all the bytes in the file + bool CheckMagic() const { return memcmp(Magic, NMagic::kMagic1, 6) == 0 || memcmp(Magic, NMagic::kMagic2, 6) == 0; }; }; -} + */ -#pragma pack(pop) -#pragma pack(pop, PragmacpioHeaders) + const UInt32 kOctRecordSize = 76; + +} }} diff --git a/7zip/Archive/cpio/CpioIn.cpp b/7zip/Archive/cpio/CpioIn.cpp index a1c0cf58..ce2ab023 100755 --- a/7zip/Archive/cpio/CpioIn.cpp +++ b/7zip/Archive/cpio/CpioIn.cpp @@ -11,13 +11,42 @@ namespace NArchive { namespace NCpio { -HRESULT CInArchive::ReadBytes(void *data, UINT32 size, UINT32 &processedSize) +HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize) { RINOK(m_Stream->Read(data, size, &processedSize)); m_Position += processedSize; return S_OK; } +Byte CInArchive::ReadByte() +{ + if (_blockPos >= _blockSize) + throw "Incorrect cpio archive"; + return _block[_blockPos++]; +} + +UInt16 CInArchive::ReadUInt16() +{ + UInt16 value = 0; + for (int i = 0; i < 2; i++) + { + Byte b = ReadByte(); + value |= (UInt16(b) << (8 * i)); + } + return value; +} + +UInt32 CInArchive::ReadUInt32() +{ + UInt32 value = 0; + for (int i = 0; i < 4; i++) + { + Byte b = ReadByte(); + value |= (UInt32(b) << (8 * i)); + } + return value; +} + HRESULT CInArchive::Open(IInStream *inStream) { RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_Position)); @@ -25,12 +54,12 @@ HRESULT CInArchive::Open(IInStream *inStream) return S_OK; } -static bool HexStringToNumber(const char *s, UINT32 &resultValue) +bool CInArchive::ReadNumber(UInt32 &resultValue) { resultValue = 0; for (int i = 0; i < 8; i++) { - char c = s[i]; + char c = char(ReadByte()); int d; if (c >= '0' && c <= '9') d = c - '0'; @@ -46,9 +75,23 @@ static bool HexStringToNumber(const char *s, UINT32 &resultValue) return true; } -#define GetFromHex(x, y) { if (!HexStringToNumber((x), (y))) return E_FAIL; } +bool CInArchive::ReadOctNumber(int size, UInt32 &resultValue) +{ + char s[32]; + int i; + for (i = 0; i < size && i < 32; i++) + s[i] = char(ReadByte()); + s[i] = 0; + char *endPtr; + resultValue = strtoul(s, &endPtr, 8); + return true; +} + +#define GetFromHex(y) { if (!ReadNumber(y)) return E_FAIL; } +#define GetFromOct6(y) { if (!ReadOctNumber(6, y)) return E_FAIL; } +#define GetFromOct11(y) { if (!ReadOctNumber(11, y)) return E_FAIL; } -static inline unsigned short ConvertValue( +static unsigned short ConvertValue( unsigned short value, bool convert) { if (!convert) @@ -56,83 +99,135 @@ static inline unsigned short ConvertValue( return (((unsigned short)(value & 0xFF)) << 8) | (value >> 8); } +static UInt32 GetAlignedSize(UInt32 size, UInt32 align) +{ + while ((size & (align - 1)) != 0) + size++; + return size; +} + + HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item) { + /* union { NFileHeader::CRecord record; NFileHeader::CRecord2 record2; }; + */ filled = false; - UINT32 processedSize; + UInt32 processedSize; item.HeaderPosition = m_Position; - RINOK(ReadBytes(&record2, 2, processedSize)); + _blockSize = kMaxBlockSize; + RINOK(ReadBytes(_block, 2, processedSize)); if (processedSize != 2) return S_FALSE; + _blockPos = 0; - UINT32 nameSize; + UInt32 nameSize; - unsigned short signature = *(unsigned short *)&record; - bool oldBE = (signature == NFileHeader::NMagic::kMagicForRecord2BE); + bool oldBE = + _block[0] == NFileHeader::NMagic::kMagicForRecord2[1] && + _block[1] == NFileHeader::NMagic::kMagicForRecord2[0]; - if (signature == NFileHeader::NMagic::kMagicForRecord2 || oldBE) + bool binMode = (_block[0] == NFileHeader::NMagic::kMagicForRecord2[0] && + _block[1] == NFileHeader::NMagic::kMagicForRecord2[1]) || + oldBE; + + if (binMode) { - RINOK(ReadBytes((BYTE *)(&record2) + 2, - sizeof(record2) - 2, processedSize)); - if (processedSize != sizeof(record2) - 2) + RINOK(ReadBytes(_block + 2, NFileHeader::kRecord2Size - 2, processedSize)); + if (processedSize != NFileHeader::kRecord2Size - 2) return S_FALSE; - - item.inode = ConvertValue(record2.c_ino, oldBE); - item.Mode = ConvertValue(record2.c_mode, oldBE); - item.UID = ConvertValue(record2.c_uid, oldBE); - item.GID = ConvertValue(record2.c_gid, oldBE); - item.Size = - (UINT32(ConvertValue(record2.c_filesizes[0], oldBE)) << 16) - + ConvertValue(record2.c_filesizes[1], oldBE); - item.ModificationTime = - (UINT32(ConvertValue(record2.c_mtimes[0], oldBE)) << 16) + - ConvertValue(record2.c_mtimes[1], oldBE); - item.NumLinks = ConvertValue(record2.c_nlink, oldBE); + item.Align = 2; + _blockPos = 2; item.DevMajor = 0; - item.DevMinor = ConvertValue(record2.c_dev, oldBE); + item.DevMinor = ConvertValue(ReadUInt16(), oldBE); + item.inode = ConvertValue(ReadUInt16(), oldBE); + item.Mode = ConvertValue(ReadUInt16(), oldBE); + item.UID = ConvertValue(ReadUInt16(), oldBE); + item.GID = ConvertValue(ReadUInt16(), oldBE); + item.NumLinks = ConvertValue(ReadUInt16(), oldBE); item.RDevMajor =0; - item.RDevMinor = ConvertValue(record2.c_rdev, oldBE); + item.RDevMinor = ConvertValue(ReadUInt16(), oldBE); + UInt16 timeHigh = ConvertValue(ReadUInt16(), oldBE); + UInt16 timeLow = ConvertValue(ReadUInt16(), oldBE); + item.ModificationTime = (UInt32(timeHigh) << 16) + timeLow; + nameSize = ConvertValue(ReadUInt16(), oldBE); + UInt16 sizeHigh = ConvertValue(ReadUInt16(), oldBE); + UInt16 sizeLow = ConvertValue(ReadUInt16(), oldBE); + item.Size = (UInt32(sizeHigh) << 16) + sizeLow; + item.ChkSum = 0; - nameSize = ConvertValue(record2.c_namesize, oldBE); - item.HeaderSize = - (((nameSize + sizeof(NFileHeader::CRecord2) - 1) / 2) + 1) * 2; /* 4 byte padding for ("new cpio header" + "filename") */ - // nameSize + sizeof(NFileHeader::CRecord2); - nameSize = item.HeaderSize - sizeof(NFileHeader::CRecord2); - item.OldHeader = true; + item.HeaderSize = GetAlignedSize( + nameSize + NFileHeader::kRecord2Size, item.Align); + nameSize = item.HeaderSize - NFileHeader::kRecord2Size; } else { - RINOK(ReadBytes((BYTE *)(&record) + 2, sizeof(record) - 2, processedSize)); - if (processedSize != sizeof(record) - 2) - return S_FALSE; - - if (!record.CheckMagic()) + RINOK(ReadBytes(_block + 2, 4, processedSize)); + if (processedSize != 4) return S_FALSE; - - GetFromHex(record.inode, item.inode); - GetFromHex(record.Mode, item.Mode); - GetFromHex(record.UID, item.UID); - GetFromHex(record.GID, item.GID); - GetFromHex(record.nlink, item.NumLinks); - GetFromHex(record.mtime, *(UINT32 *)&item.ModificationTime); - GetFromHex(record.Size, item.Size); - GetFromHex(record.DevMajor, item.DevMajor); - GetFromHex(record.DevMinor, item.DevMinor); - GetFromHex(record.RDevMajor, item.RDevMajor); - GetFromHex(record.RDevMinor, item.RDevMinor); - GetFromHex(record.ChkSum, item.ChkSum); - GetFromHex(record.NameSize, nameSize) - item.HeaderSize = - (((nameSize + sizeof(NFileHeader::CRecord) - 1) / 4) + 1) * 4; /* 4 byte padding for ("new cpio header" + "filename") */ - nameSize = item.HeaderSize - sizeof(NFileHeader::CRecord); - item.OldHeader = false; + + bool magicOK = + memcmp(_block, NFileHeader::NMagic::kMagic1, 6) == 0 || + memcmp(_block, NFileHeader::NMagic::kMagic2, 6) == 0; + _blockPos = 6; + if (magicOK) + { + RINOK(ReadBytes(_block + 6, NFileHeader::kRecordSize - 6, processedSize)); + if (processedSize != NFileHeader::kRecordSize - 6) + return S_FALSE; + item.Align = 4; + + GetFromHex(item.inode); + GetFromHex(item.Mode); + GetFromHex(item.UID); + GetFromHex(item.GID); + GetFromHex(item.NumLinks); + UInt32 modificationTime; + GetFromHex(modificationTime); + item.ModificationTime = modificationTime; + GetFromHex(item.Size); + GetFromHex(item.DevMajor); + GetFromHex(item.DevMinor); + GetFromHex(item.RDevMajor); + GetFromHex(item.RDevMinor); + GetFromHex(nameSize); + GetFromHex(item.ChkSum); + item.HeaderSize = GetAlignedSize( + nameSize + NFileHeader::kRecordSize, item.Align); + nameSize = item.HeaderSize - NFileHeader::kRecordSize; + } + else + { + if (!memcmp(_block, NFileHeader::NMagic::kMagic3, 6) == 0) + return S_FALSE; + RINOK(ReadBytes(_block + 6, NFileHeader::kOctRecordSize - 6, processedSize)); + if (processedSize != NFileHeader::kOctRecordSize - 6) + return S_FALSE; + item.Align = 1; + item.DevMajor = 0; + GetFromOct6(item.DevMinor); + GetFromOct6(item.inode); + GetFromOct6(item.Mode); + GetFromOct6(item.UID); + GetFromOct6(item.GID); + GetFromOct6(item.NumLinks); + item.RDevMajor = 0; + GetFromOct6(item.RDevMinor); + UInt32 modificationTime; + GetFromOct11(modificationTime); + item.ModificationTime = modificationTime; + GetFromOct6(nameSize); + GetFromOct11(item.Size); // ????? + item.HeaderSize = GetAlignedSize( + nameSize + NFileHeader::kOctRecordSize, item.Align); + nameSize = item.HeaderSize - NFileHeader::kOctRecordSize; + } } if (nameSize == 0 || nameSize >= (1 << 27)) return E_FAIL; @@ -141,27 +236,27 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item) if (processedSize != nameSize) return E_FAIL; item.Name.ReleaseBuffer(); - if (item.Name == NFileHeader::NMagic::kEndName) + if (strcmp(item.Name, NFileHeader::NMagic::kEndName) == 0) return S_OK; filled = true; return S_OK; } -HRESULT CInArchive::Skeep(UINT64 aNumBytes) +HRESULT CInArchive::Skeep(UInt64 numBytes) { - UINT64 aNewPostion; - RINOK(m_Stream->Seek(aNumBytes, STREAM_SEEK_CUR, &aNewPostion)); - m_Position += aNumBytes; - if (m_Position != aNewPostion) + UInt64 newPostion; + RINOK(m_Stream->Seek(numBytes, STREAM_SEEK_CUR, &newPostion)); + m_Position += numBytes; + if (m_Position != newPostion) return E_FAIL; return S_OK; } -HRESULT CInArchive::SkeepDataRecords(UINT64 aDataSize, bool OldHeader) +HRESULT CInArchive::SkeepDataRecords(UInt64 dataSize, UInt32 align) { - if (OldHeader) - return Skeep((aDataSize + 1) & 0xFFFFFFFFFFFFFFFE); - return Skeep((aDataSize + 3) & 0xFFFFFFFFFFFFFFFC); + while ((dataSize & (align - 1)) != 0) + dataSize++; + return Skeep(dataSize); } }} diff --git a/7zip/Archive/cpio/CpioIn.h b/7zip/Archive/cpio/CpioIn.h index 8362aa9c..19e3da10 100755 --- a/7zip/Archive/cpio/CpioIn.h +++ b/7zip/Archive/cpio/CpioIn.h @@ -1,29 +1,39 @@ // CpioIn.h -#pragma once - #ifndef __ARCHIVE_CPIO_IN_H #define __ARCHIVE_CPIO_IN_H #include "Common/MyCom.h" +#include "Common/Types.h" #include "../../IStream.h" #include "CpioItem.h" namespace NArchive { namespace NCpio { +const UInt32 kMaxBlockSize = NFileHeader::kRecordSize; + class CInArchive { CMyComPtr<IInStream> m_Stream; + UInt64 m_Position; + + UInt16 _blockSize; + Byte _block[kMaxBlockSize]; + UInt32 _blockPos; + Byte ReadByte(); + UInt16 ReadUInt16(); + UInt32 ReadUInt32(); - UINT64 m_Position; - - HRESULT ReadBytes(void *data, UINT32 size, UINT32 &aProcessedSize); + bool ReadNumber(UInt32 &resultValue); + bool ReadOctNumber(int size, UInt32 &resultValue); + + HRESULT ReadBytes(void *data, UInt32 size, UInt32 &processedSize); public: HRESULT Open(IInStream *inStream); - HRESULT GetNextItem(bool &filled, CItemEx &anItemInfo); - HRESULT Skeep(UINT64 aNumBytes); - HRESULT SkeepDataRecords(UINT64 aDataSize, bool OldHeader); + HRESULT GetNextItem(bool &filled, CItemEx &itemInfo); + HRESULT Skeep(UInt64 numBytes); + HRESULT SkeepDataRecords(UInt64 dataSize, UInt32 align); }; }} diff --git a/7zip/Archive/cpio/CpioItem.h b/7zip/Archive/cpio/CpioItem.h index 465783c7..0eb2a0b4 100755 --- a/7zip/Archive/cpio/CpioItem.h +++ b/7zip/Archive/cpio/CpioItem.h @@ -1,7 +1,5 @@ // Archive/cpio/ItemInfo.h -#pragma once - #ifndef __ARCHIVE_CPIO_ITEMINFO_H #define __ARCHIVE_CPIO_ITEMINFO_H @@ -17,35 +15,39 @@ namespace NCpio { struct CItem { AString Name; - UINT32 inode; - UINT32 Mode; - UINT32 UID; - UINT32 GID; - UINT32 Size; - time_t ModificationTime; + UInt32 inode; + UInt32 Mode; + UInt32 UID; + UInt32 GID; + UInt32 Size; + UInt32 ModificationTime; // char LinkFlag; // AString LinkName; ????? char Magic[8]; - UINT32 NumLinks; - UINT32 DevMajor; - UINT32 DevMinor; - UINT32 RDevMajor; - UINT32 RDevMinor; - UINT32 ChkSum; + UInt32 NumLinks; + UInt32 DevMajor; + UInt32 DevMinor; + UInt32 RDevMajor; + UInt32 RDevMinor; + UInt32 ChkSum; - bool OldHeader; + UInt32 Align; bool IsDirectory() const +#ifdef _WIN32 { return (Mode & _S_IFMT) == _S_IFDIR; } +#else + { return (Mode & S_IFMT) == S_IFDIR; } +#endif }; class CItemEx: public CItem { public: - UINT64 HeaderPosition; - UINT32 HeaderSize; - UINT64 GetDataPosition() const { return HeaderPosition + HeaderSize; }; + UInt64 HeaderPosition; + UInt32 HeaderSize; + UInt64 GetDataPosition() const { return HeaderPosition + HeaderSize; }; }; }} diff --git a/7zip/Archive/cpio/DllExports.cpp b/7zip/Archive/cpio/DllExports.cpp index da6e3971..a72058a5 100755 --- a/7zip/Archive/cpio/DllExports.cpp +++ b/7zip/Archive/cpio/DllExports.cpp @@ -2,8 +2,7 @@ #include "StdAfx.h" -#define INITGUID - +#include "Common/MyInitGuid.h" #include "Common/ComTry.h" #include "Windows/PropVariant.h" #include "CpioHandler.h" diff --git a/7zip/Archive/cpio/StdAfx.cpp b/7zip/Archive/cpio/StdAfx.cpp index 2550270c..d0feea85 100755 --- a/7zip/Archive/cpio/StdAfx.cpp +++ b/7zip/Archive/cpio/StdAfx.cpp @@ -1,3 +1,3 @@ // StdAfx.cpp -#include "stdafx.h" +#include "StdAfx.h" diff --git a/7zip/Archive/cpio/StdAfx.h b/7zip/Archive/cpio/StdAfx.h index 9f4df604..e7fb6986 100755 --- a/7zip/Archive/cpio/StdAfx.h +++ b/7zip/Archive/cpio/StdAfx.h @@ -1,10 +1,8 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> +#include "../../../Common/MyWindows.h" -#include <time.h> - -#endif +#endif diff --git a/7zip/Archive/cpio/cpio.dsp b/7zip/Archive/cpio/cpio.dsp index da7ee1c6..accc0bff 100755 --- a/7zip/Archive/cpio/cpio.dsp +++ b/7zip/Archive/cpio/cpio.dsp @@ -126,6 +126,14 @@ SOURCE=.\StdAfx.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\NewHandler.cpp # End Source File # Begin Source File @@ -134,6 +142,10 @@ SOURCE=..\..\..\Common\NewHandler.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\StringConvert.cpp # End Source File # Begin Source File diff --git a/7zip/Archive/cpio/resource.rc b/7zip/Archive/cpio/resource.rc index 1aa0520a..e701c08b 100755 --- a/7zip/Archive/cpio/resource.rc +++ b/7zip/Archive/cpio/resource.rc @@ -75,8 +75,8 @@ IDI_ICON1 ICON DISCARDABLE "cpio.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,9,2,0 - PRODUCTVERSION 3,9,2,0 + FILEVERSION 4,11,0,0 + PRODUCTVERSION 4,11,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -94,14 +94,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Igor Pavlov\0" VALUE "FileDescription", "cpio Plugin for 7-Zip\0" - VALUE "FileVersion", "3, 9, 2, 0\0" + VALUE "FileVersion", "4, 11, 0, 0\0" VALUE "InternalName", "cpio\0" - VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2004 Igor Pavlov\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "cpio .dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "7-Zip\0" - VALUE "ProductVersion", "3, 9, 2, 0\0" + VALUE "ProductVersion", "4, 11, 0, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/7zip/Bundles/Alone/Alone.dsp b/7zip/Bundles/Alone/Alone.dsp index 6bd29f26..28593695 100755 --- a/7zip/Bundles/Alone/Alone.dsp +++ b/7zip/Bundles/Alone/Alone.dsp @@ -44,7 +44,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_MF_HC" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_DEFLATE64" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "FORMAT_Z" /D "FORMAT_SPLIT" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_DEFLATE64" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /c # ADD BASE RSC /l 0x419 /d "NDEBUG" # ADD RSC /l 0x419 /d "NDEBUG" BSC32=bscmake.exe @@ -69,7 +69,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_MF_HC" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_DEFLATE64" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "FORMAT_Z" /D "FORMAT_SPLIT" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_DEFLATE64" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /GZ /c # ADD BASE RSC /l 0x419 /d "_DEBUG" # ADD RSC /l 0x419 /d "_DEBUG" BSC32=bscmake.exe @@ -94,7 +94,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /Yu"StdAfx.h" /FD /c -# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_MF_HC" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_DEFLATE64" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "FORMAT_Z" /D "FORMAT_SPLIT" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_DEFLATE64" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /c # ADD BASE RSC /l 0x419 /d "NDEBUG" # ADD RSC /l 0x419 /d "NDEBUG" BSC32=bscmake.exe @@ -121,7 +121,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c -# ADD CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_MF_HC" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_DEFLATE64" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "FORMAT_Z" /D "FORMAT_SPLIT" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_DEFLATE64" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /GZ /c # ADD BASE RSC /l 0x419 /d "_DEBUG" # ADD RSC /l 0x419 /d "_DEBUG" BSC32=bscmake.exe @@ -160,19 +160,11 @@ SOURCE=..\..\UI\Console\ConsoleClose.h # End Source File # Begin Source File -SOURCE=..\..\UI\Console\Extract.cpp +SOURCE=..\..\UI\Console\ExtractCallbackConsole.cpp # End Source File # Begin Source File -SOURCE=..\..\UI\Console\Extract.h -# End Source File -# Begin Source File - -SOURCE=..\..\UI\Console\ExtractCallback.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\UI\Console\ExtractCallback.h +SOURCE=..\..\UI\Console\ExtractCallbackConsole.h # End Source File # Begin Source File @@ -192,11 +184,11 @@ SOURCE=..\..\UI\Console\MainAr.cpp # End Source File # Begin Source File -SOURCE=..\..\UI\Console\OpenCallback.cpp +SOURCE=..\..\UI\Console\OpenCallbackConsole.cpp # End Source File # Begin Source File -SOURCE=..\..\UI\Console\OpenCallback.h +SOURCE=..\..\UI\Console\OpenCallbackConsole.h # End Source File # Begin Source File @@ -208,27 +200,11 @@ SOURCE=..\..\UI\Console\PercentPrinter.h # End Source File # Begin Source File -SOURCE=..\..\UI\Console\TempFiles.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\UI\Console\TempFiles.h +SOURCE=..\..\UI\Console\UpdateCallbackConsole.cpp # End Source File # Begin Source File -SOURCE=..\..\UI\Console\Update.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\UI\Console\Update.h -# End Source File -# Begin Source File - -SOURCE=..\..\UI\Console\UpdateCallback.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\UI\Console\UpdateCallback.h +SOURCE=..\..\UI\Console\UpdateCallbackConsole.h # End Source File # Begin Source File @@ -273,6 +249,18 @@ SOURCE=..\..\..\Common\AlignedBuffer.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\AutoPtr.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\Buffer.h # End Source File # Begin Source File @@ -329,6 +317,26 @@ SOURCE=..\..\..\Common\MyCom.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\MyGuidDef.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyInitGuid.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyUnknown.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyWindows.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyWindows.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\NewHandler.cpp # End Source File # Begin Source File @@ -501,14 +509,6 @@ SOURCE=..\..\..\Windows\Synchronization.h # End Source File # Begin Source File -SOURCE=..\..\..\Windows\System.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\Windows\System.h -# End Source File -# Begin Source File - SOURCE=..\..\..\Windows\Thread.h # End Source File # Begin Source File @@ -569,35 +569,35 @@ SOURCE=..\..\Common\LimitedStreams.h # End Source File # Begin Source File -SOURCE=..\..\Common\LSBFDecoder.cpp +SOURCE=..\..\Common\LockedStream.cpp # End Source File # Begin Source File -SOURCE=..\..\Common\LSBFDecoder.h +SOURCE=..\..\Common\LockedStream.h # End Source File # Begin Source File -SOURCE=..\..\Common\LSBFEncoder.cpp +SOURCE=..\..\Common\LSBFDecoder.cpp # End Source File # Begin Source File -SOURCE=..\..\Common\LSBFEncoder.h +SOURCE=..\..\Common\LSBFDecoder.h # End Source File # Begin Source File -SOURCE=..\..\Common\MSBFDecoder.h +SOURCE=..\..\Common\LSBFEncoder.cpp # End Source File # Begin Source File -SOURCE=..\..\Common\MSBFEncoder.h +SOURCE=..\..\Common\LSBFEncoder.h # End Source File # Begin Source File -SOURCE=..\..\Common\MultiStream.cpp +SOURCE=..\..\Common\MSBFDecoder.h # End Source File # Begin Source File -SOURCE=..\..\Common\MultiStream.h +SOURCE=..\..\Common\MSBFEncoder.h # End Source File # Begin Source File @@ -648,6 +648,14 @@ SOURCE=..\..\Common\StreamObjects.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\Compress\Branch\BranchCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\BranchCoder.h +# End Source File +# Begin Source File + SOURCE=..\..\Compress\Branch\Coder.h # End Source File # Begin Source File @@ -704,195 +712,16 @@ SOURCE=..\..\Compress\Branch\x86_2.h # Begin Group "BZip2" # PROP Default_Filter "" -# Begin Group "Original BZip2" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\Compress\BZip2\Original\blocksort.c - -!IF "$(CFG)" == "Alone - Win32 Release" - -# ADD CPP /O2 -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Alone - Win32 Debug" - -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" - -# ADD CPP /O2 -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" - -# SUBTRACT CPP /YX /Yc /Yu - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\..\Compress\BZip2\Original\bzlib.c - -!IF "$(CFG)" == "Alone - Win32 Release" - -# ADD CPP /O2 -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Alone - Win32 Debug" - -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" - -# ADD CPP /O2 -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" - -# SUBTRACT CPP /YX /Yc /Yu - -!ENDIF - -# End Source File # Begin Source File -SOURCE=..\..\Compress\BZip2\Original\bzlib.h +SOURCE=..\..\Compress\BZip2\BZip2CRC.cpp # End Source File # Begin Source File -SOURCE=..\..\Compress\BZip2\Original\bzlib_private.h +SOURCE=..\..\Compress\BZip2\BZip2CRC.h # End Source File # Begin Source File -SOURCE=..\..\Compress\BZip2\Original\compress.c - -!IF "$(CFG)" == "Alone - Win32 Release" - -# ADD CPP /O2 -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Alone - Win32 Debug" - -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" - -# ADD CPP /O2 -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" - -# SUBTRACT CPP /YX /Yc /Yu - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\..\Compress\BZip2\Original\crctable.c - -!IF "$(CFG)" == "Alone - Win32 Release" - -# ADD CPP /O2 -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Alone - Win32 Debug" - -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" - -# ADD CPP /O2 -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" - -# SUBTRACT CPP /YX /Yc /Yu - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\..\Compress\BZip2\Original\decompress.c - -!IF "$(CFG)" == "Alone - Win32 Release" - -# ADD CPP /O2 -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Alone - Win32 Debug" - -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" - -# ADD CPP /O2 -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" - -# SUBTRACT CPP /YX /Yc /Yu - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\..\Compress\BZip2\Original\huffman.c - -!IF "$(CFG)" == "Alone - Win32 Release" - -# ADD CPP /O2 -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Alone - Win32 Debug" - -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" - -# ADD CPP /O2 -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" - -# SUBTRACT CPP /YX /Yc /Yu - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\..\Compress\BZip2\Original\randtable.c - -!IF "$(CFG)" == "Alone - Win32 Release" - -# ADD CPP /O2 -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Alone - Win32 Debug" - -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" - -# ADD CPP /O2 -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" - -# SUBTRACT CPP /YX /Yc /Yu - -!ENDIF - -# End Source File -# End Group -# Begin Source File - SOURCE=..\..\Compress\BZip2\BZip2Decoder.cpp !IF "$(CFG)" == "Alone - Win32 Release" @@ -941,10 +770,6 @@ SOURCE=..\..\Compress\BZip2\BZip2Encoder.cpp SOURCE=..\..\Compress\BZip2\BZip2Encoder.h # End Source File -# Begin Source File - -SOURCE=..\..\Compress\BZip2\BZip2Error.cpp -# End Source File # End Group # Begin Group "Copy" @@ -1132,14 +957,6 @@ SOURCE=..\..\Compress\LZ\HashChain\HC4b.h SOURCE=..\..\Compress\LZ\HashChain\HCMain.h # End Source File -# Begin Source File - -SOURCE=..\..\Compress\LZ\HashChain\HCMF.h -# End Source File -# Begin Source File - -SOURCE=..\..\Compress\LZ\HashChain\HCMFMain.h -# End Source File # End Group # Begin Source File @@ -1249,9 +1066,21 @@ SOURCE=..\..\Compress\LZMA\LZMAEncoder.cpp SOURCE=..\..\Compress\LZMA\LZMAEncoder.h # End Source File +# End Group +# Begin Group "PPMd" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDContext.h +# End Source File # Begin Source File -SOURCE=..\..\Compress\LZMA\LZMALen.cpp +SOURCE=..\..\Compress\PPMD\PPMDDecode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDDecoder.cpp !IF "$(CFG)" == "Alone - Win32 Release" @@ -1272,11 +1101,15 @@ SOURCE=..\..\Compress\LZMA\LZMALen.cpp # End Source File # Begin Source File -SOURCE=..\..\Compress\LZMA\LZMALen.h +SOURCE=..\..\Compress\PPMD\PPMDDecoder.h # End Source File # Begin Source File -SOURCE=..\..\Compress\LZMA\LZMALiteral.cpp +SOURCE=..\..\Compress\PPMD\PPMDEncode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDEncoder.cpp !IF "$(CFG)" == "Alone - Win32 Release" @@ -1297,35 +1130,37 @@ SOURCE=..\..\Compress\LZMA\LZMALiteral.cpp # End Source File # Begin Source File -SOURCE=..\..\Compress\LZMA\LZMALiteral.h +SOURCE=..\..\Compress\PPMD\PPMDEncoder.h # End Source File -# End Group -# Begin Group "PPMd" +# Begin Source File -# PROP Default_Filter "" +SOURCE=..\..\Compress\PPMD\PPMDSubAlloc.h +# End Source File # Begin Source File -SOURCE=..\..\Compress\PPMD\PPMDContext.h +SOURCE=..\..\Compress\PPMD\PPMDType.h # End Source File +# End Group +# Begin Group "RangeCoder" + +# PROP Default_Filter "" # Begin Source File -SOURCE=..\..\Compress\PPMD\PPMDDecode.h +SOURCE=..\..\Compress\RangeCoder\RangeCoder.h # End Source File # Begin Source File -SOURCE=..\..\Compress\PPMD\PPMDDecoder.cpp +SOURCE=..\..\Compress\RangeCoder\RangeCoderBit.cpp !IF "$(CFG)" == "Alone - Win32 Release" -# ADD CPP /O2 -# SUBTRACT CPP /YX /Yc /Yu +# ADD CPP /O1 !ELSEIF "$(CFG)" == "Alone - Win32 Debug" !ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" -# ADD CPP /O2 -# SUBTRACT CPP /YX /Yc /Yu +# ADD CPP /O1 !ELSEIF "$(CFG)" == "Alone - Win32 DebugU" @@ -1334,66 +1169,59 @@ SOURCE=..\..\Compress\PPMD\PPMDDecoder.cpp # End Source File # Begin Source File -SOURCE=..\..\Compress\PPMD\PPMDDecoder.h +SOURCE=..\..\Compress\RangeCoder\RangeCoderBit.h # End Source File # Begin Source File -SOURCE=..\..\Compress\PPMD\PPMDEncode.h +SOURCE=..\..\Compress\RangeCoder\RangeCoderBitTree.h # End Source File # Begin Source File -SOURCE=..\..\Compress\PPMD\PPMDEncoder.cpp - -!IF "$(CFG)" == "Alone - Win32 Release" - -# ADD CPP /O2 -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Alone - Win32 Debug" - -!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" - -# ADD CPP /O2 -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" +SOURCE=..\..\Compress\RangeCoder\RangeCoderOpt.h +# End Source File +# End Group +# Begin Group "Shrink" -!ENDIF +# PROP Default_Filter "" +# Begin Source File +SOURCE=..\..\Compress\Shrink\ShrinkDecoder.cpp # End Source File # Begin Source File -SOURCE=..\..\Compress\PPMD\PPMDEncoder.h +SOURCE=..\..\Compress\Shrink\ShrinkDecoder.h # End Source File +# End Group +# Begin Group "Z" + +# PROP Default_Filter "" # Begin Source File -SOURCE=..\..\Compress\PPMD\PPMDSubAlloc.h +SOURCE=..\..\Compress\Z\ZDecoder.cpp # End Source File # Begin Source File -SOURCE=..\..\Compress\PPMD\PPMDType.h +SOURCE=..\..\Compress\Z\ZDecoder.h # End Source File # End Group -# Begin Group "RangeCoder" +# Begin Group "BWT" # PROP Default_Filter "" # Begin Source File -SOURCE=..\..\Compress\RangeCoder\RangeCoder.h -# End Source File -# Begin Source File - -SOURCE=..\..\Compress\RangeCoder\RangeCoderBit.cpp +SOURCE=..\..\Compress\BWT\BlockSort.cpp !IF "$(CFG)" == "Alone - Win32 Release" -# ADD CPP /O1 +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu !ELSEIF "$(CFG)" == "Alone - Win32 Debug" !ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" -# ADD CPP /O1 +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu !ELSEIF "$(CFG)" == "Alone - Win32 DebugU" @@ -1402,15 +1230,11 @@ SOURCE=..\..\Compress\RangeCoder\RangeCoderBit.cpp # End Source File # Begin Source File -SOURCE=..\..\Compress\RangeCoder\RangeCoderBit.h +SOURCE=..\..\Compress\BWT\BlockSort.h # End Source File # Begin Source File -SOURCE=..\..\Compress\RangeCoder\RangeCoderBitTree.h -# End Source File -# Begin Source File - -SOURCE=..\..\Compress\RangeCoder\RangeCoderOpt.h +SOURCE=..\..\Compress\BWT\Mtf8.h # End Source File # End Group # End Group @@ -1746,19 +1570,27 @@ SOURCE=..\..\Archive\Zip\ZipUpdate.h # PROP Default_Filter "" # Begin Source File -SOURCE=..\..\Archive\Common\CoderMixer.cpp +SOURCE=..\..\Archive\Common\CoderMixer2.cpp # End Source File # Begin Source File -SOURCE=..\..\Archive\Common\CoderMixer.h +SOURCE=..\..\Archive\Common\CoderMixer2.h # End Source File # Begin Source File -SOURCE=..\..\Archive\Common\CoderMixer2.cpp +SOURCE=..\..\Archive\Common\CoderMixer2MT.cpp # End Source File # Begin Source File -SOURCE=..\..\Archive\Common\CoderMixer2.h +SOURCE=..\..\Archive\Common\CoderMixer2MT.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2ST.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2ST.h # End Source File # Begin Source File @@ -1770,6 +1602,14 @@ SOURCE=..\..\Archive\Common\DummyOutStream.h # End Source File # Begin Source File +SOURCE=..\..\Archive\Common\FilterCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\FilterCoder.h +# End Source File +# Begin Source File + SOURCE=..\..\Archive\Common\InStreamWithCRC.cpp # End Source File # Begin Source File @@ -1786,6 +1626,14 @@ SOURCE=..\..\Archive\Common\ItemNameUtils.h # End Source File # Begin Source File +SOURCE=..\..\Archive\Common\MultiStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\MultiStream.h +# End Source File +# Begin Source File + SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp # End Source File # Begin Source File @@ -1793,12 +1641,60 @@ SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp SOURCE=..\..\Archive\Common\OutStreamWithCRC.h # End Source File # End Group +# Begin Group "split" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Split\SplitHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Split\SplitHandler.h +# End Source File +# End Group +# Begin Group "Z Format" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Z\ZHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Z\ZHandler.h +# End Source File +# End Group # End Group # Begin Group "UI Common" # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\UI\Common\ArchiveCommandLine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveCommandLine.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveOpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveOpenCallback.h +# End Source File +# Begin Source File + SOURCE=..\..\UI\Common\ArchiverInfo.cpp # End Source File # Begin Source File @@ -1823,6 +1719,14 @@ SOURCE=..\..\UI\Common\EnumDirItems.h # End Source File # Begin Source File +SOURCE=..\..\UI\Common\Extract.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Extract.h +# End Source File +# Begin Source File + SOURCE=..\..\UI\Common\ExtractingFilePath.cpp # End Source File # Begin Source File @@ -1855,6 +1759,22 @@ SOURCE=..\..\UI\Common\SortUtils.h # End Source File # Begin Source File +SOURCE=..\..\UI\Common\TempFiles.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\TempFiles.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Update.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Update.h +# End Source File +# Begin Source File + SOURCE=..\..\UI\Common\UpdateAction.cpp # End Source File # Begin Source File @@ -1863,6 +1783,14 @@ SOURCE=..\..\UI\Common\UpdateAction.h # End Source File # Begin Source File +SOURCE=..\..\UI\Common\UpdateCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdateCallback.h +# End Source File +# Begin Source File + SOURCE=..\..\UI\Common\UpdatePair.cpp # End Source File # Begin Source File diff --git a/7zip/Bundles/Alone/StdAfx.cpp b/7zip/Bundles/Alone/StdAfx.cpp index 2550270c..d0feea85 100755 --- a/7zip/Bundles/Alone/StdAfx.cpp +++ b/7zip/Bundles/Alone/StdAfx.cpp @@ -1,3 +1,3 @@ // StdAfx.cpp -#include "stdafx.h" +#include "StdAfx.h" diff --git a/7zip/Bundles/Alone/StdAfx.h b/7zip/Bundles/Alone/StdAfx.h index 3bdedef1..92239aeb 100755 --- a/7zip/Bundles/Alone/StdAfx.h +++ b/7zip/Bundles/Alone/StdAfx.h @@ -1,12 +1,8 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> -#include <stdio.h> -#include <tchar.h> - -#include <vector> +#include "../../../Common/MyWindows.h" #endif diff --git a/7zip/Bundles/Alone/resource.rc b/7zip/Bundles/Alone/resource.rc index 9fb6641a..9ae29f6e 100755 --- a/7zip/Bundles/Alone/resource.rc +++ b/7zip/Bundles/Alone/resource.rc @@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,12,0,0 - PRODUCTVERSION 3,12,0,0 + FILEVERSION 4,20,0,0 + PRODUCTVERSION 4,20,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -85,14 +85,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Igor Pavlov\0" VALUE "FileDescription", "7-Zip Standalone Console version\0" - VALUE "FileVersion", "3, 12, 0, 0\0" + VALUE "FileVersion", "4, 20, 0, 0\0" VALUE "InternalName", "7za\0" - VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "7za.exe\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "7-Zip\0" - VALUE "ProductVersion", "3, 12, 0, 0\0" + VALUE "ProductVersion", "4, 20, 0, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/7zip/Bundles/Format7z/Format7z.dsp b/7zip/Bundles/Format7z/Format7z.dsp index 0ef0e8b8..240a4c0c 100755 --- a/7zip/Bundles/Format7z/Format7z.dsp +++ b/7zip/Bundles/Format7z/Format7z.dsp @@ -43,7 +43,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 1 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /c -# ADD CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_MF_HC" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE_DECODER" /D "COMPRESS_BZIP2_DECODER" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "NDEBUG" @@ -70,7 +70,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 1 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\..\SDK" /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_MF_HC" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\..\SDK" /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE_DECODER" /D "COMPRESS_BZIP2_DECODER" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "_DEBUG" @@ -134,6 +134,14 @@ SOURCE=..\..\..\Common\AlignedBuffer.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\CRC.cpp # End Source File # Begin Source File @@ -232,14 +240,6 @@ SOURCE=..\..\..\Windows\Synchronization.cpp SOURCE=..\..\..\Windows\Synchronization.h # End Source File -# Begin Source File - -SOURCE=..\..\..\Windows\System.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\Windows\System.h -# End Source File # End Group # Begin Group "Archive common" @@ -254,6 +254,14 @@ SOURCE=..\..\Archive\Common\CoderMixer2.h # End Source File # Begin Source File +SOURCE=..\..\Archive\Common\CoderMixer2MT.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2MT.h +# End Source File +# Begin Source File + SOURCE=..\..\Archive\Common\CrossThreadProgress.cpp # End Source File # Begin Source File @@ -262,6 +270,14 @@ SOURCE=..\..\Archive\Common\CrossThreadProgress.h # End Source File # Begin Source File +SOURCE=..\..\Archive\Common\FilterCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\FilterCoder.h +# End Source File +# Begin Source File + SOURCE=..\..\Archive\Common\InStreamWithCRC.cpp # End Source File # Begin Source File @@ -401,6 +417,14 @@ SOURCE=..\..\Compress\PPMD\PPMDType.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\Compress\Branch\BranchCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\BranchCoder.h +# End Source File +# Begin Source File + SOURCE=..\..\Compress\Branch\x86.cpp !IF "$(CFG)" == "7z - Win32 Release" @@ -487,29 +511,53 @@ SOURCE=..\..\Compress\LZMA\LZMAEncoder.cpp SOURCE=..\..\Compress\LZMA\LZMAEncoder.h # End Source File +# End Group +# Begin Group "Copy" + +# PROP Default_Filter "" # Begin Source File -SOURCE=..\..\Compress\LZMA\LZMALen.cpp +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File -!IF "$(CFG)" == "7z - Win32 Release" +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# Begin Group "RangeCoder" -# ADD CPP /O2 -# SUBTRACT CPP /YX /Yc /Yu +# PROP Default_Filter "" +# Begin Source File -!ELSEIF "$(CFG)" == "7z - Win32 Debug" +SOURCE=..\..\Compress\RangeCoder\RangeCoder.h +# End Source File +# Begin Source File -# SUBTRACT CPP /YX /Yc /Yu +SOURCE=..\..\Compress\RangeCoder\RangeCoderBit.cpp +# End Source File +# Begin Source File -!ENDIF +SOURCE=..\..\Compress\RangeCoder\RangeCoderBit.h +# End Source File +# Begin Source File +SOURCE=..\..\Compress\RangeCoder\RangeCoderBitTree.h # End Source File # Begin Source File -SOURCE=..\..\Compress\LZMA\LZMALen.h +SOURCE=..\..\Compress\RangeCoder\RangeCoderOpt.h # End Source File +# End Group +# Begin Group "Deflate" + +# PROP Default_Filter "" # Begin Source File -SOURCE=..\..\Compress\LZMA\LZMALiteral.cpp +SOURCE=..\..\Compress\Deflate\DeflateConst.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Deflate\DeflateDecoder.cpp !IF "$(CFG)" == "7z - Win32 Release" @@ -518,50 +566,50 @@ SOURCE=..\..\Compress\LZMA\LZMALiteral.cpp !ELSEIF "$(CFG)" == "7z - Win32 Debug" -# SUBTRACT CPP /YX /Yc /Yu - !ENDIF # End Source File # Begin Source File -SOURCE=..\..\Compress\LZMA\LZMALiteral.h +SOURCE=..\..\Compress\Deflate\DeflateDecoder.h # End Source File -# End Group -# Begin Group "Copy" - -# PROP Default_Filter "" # Begin Source File -SOURCE=..\..\Compress\Copy\CopyCoder.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\Compress\Copy\CopyCoder.h +SOURCE=..\..\Compress\Deflate\DeflateExtConst.h # End Source File # End Group -# Begin Group "RangeCoder" +# Begin Group "BZip2" # PROP Default_Filter "" # Begin Source File -SOURCE=..\..\Compress\RangeCoder\RangeCoder.h +SOURCE=..\..\Compress\BZip2\BZip2Const.h # End Source File # Begin Source File -SOURCE=..\..\Compress\RangeCoder\RangeCoderBit.cpp +SOURCE=..\..\Compress\BZip2\BZip2CRC.cpp # End Source File # Begin Source File -SOURCE=..\..\Compress\RangeCoder\RangeCoderBit.h +SOURCE=..\..\Compress\BZip2\BZip2CRC.h # End Source File # Begin Source File -SOURCE=..\..\Compress\RangeCoder\RangeCoderBitTree.h +SOURCE=..\..\Compress\BZip2\BZip2Decoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + # End Source File # Begin Source File -SOURCE=..\..\Compress\RangeCoder\RangeCoderOpt.h +SOURCE=..\..\Compress\BZip2\BZip2Decoder.h # End Source File # End Group # End Group @@ -862,11 +910,19 @@ SOURCE=..\..\Common\LimitedStreams.h # End Source File # Begin Source File -SOURCE=..\..\Common\MultiStream.cpp +SOURCE=..\..\Common\LockedStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LockedStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LSBFDecoder.cpp # End Source File # Begin Source File -SOURCE=..\..\Common\MultiStream.h +SOURCE=..\..\Common\LSBFDecoder.h # End Source File # Begin Source File diff --git a/7zip/Bundles/Format7zExtract/Format7z.dsp b/7zip/Bundles/Format7zExtract/Format7z.dsp new file mode 100755 index 00000000..b8eb291a --- /dev/null +++ b/7zip/Bundles/Format7zExtract/Format7z.dsp @@ -0,0 +1,821 @@ +# Microsoft Developer Studio Project File - Name="7z" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=7z - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Format7z.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Format7z.mak" CFG="7z - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "7z - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "7z - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "7z - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "EXTRACT_ONLY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE_DECODER" /D "COMPRESS_BZIP2_DECODER" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Formats\7zxa.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none /debug + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\..\SDK" /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "EXTRACT_ONLY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE_DECODER" /D "COMPRESS_BZIP2_DECODER" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Formats\7zxa.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "7z - Win32 Release" +# Name "7z - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\7z\7z.def +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7z.ico +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\resource.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\resource.rc +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\StdAfx.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\AlignedBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\AlignedBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# End Group +# Begin Group "Archive common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2MT.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2MT.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CrossThreadProgress.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CrossThreadProgress.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\FilterCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\FilterCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\InStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\InStreamWithCRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Group "LZ" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\LZ\LZOutWindow.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZ\LZOutWindow.h +# End Source File +# End Group +# Begin Group "PPMD" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDContext.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDDecode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDDecoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDSubAlloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDType.h +# End Source File +# End Group +# Begin Group "Branch" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Branch\BranchCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\BranchCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\x86.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\x86.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\x86_2.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\x86_2.h +# End Source File +# End Group +# Begin Group "LZMA" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\LZMA\LZMA.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZMA\LZMADecoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZMA\LZMADecoder.h +# End Source File +# End Group +# Begin Group "Copy" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# Begin Group "RangeCoder" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\RangeCoder\RangeCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\RangeCoder\RangeCoderBit.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\RangeCoder\RangeCoderBit.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\RangeCoder\RangeCoderBitTree.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\RangeCoder\RangeCoderOpt.h +# End Source File +# End Group +# Begin Group "Deflate" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Deflate\DeflateConst.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Deflate\DeflateDecoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Deflate\DeflateDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Deflate\DeflateExtConst.h +# End Source File +# End Group +# Begin Group "BZip2" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\BZip2\BZip2Const.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BZip2\BZip2CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BZip2\BZip2CRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BZip2\BZip2Decoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BZip2\BZip2Decoder.h +# End Source File +# End Group +# End Group +# Begin Group "Crypto" + +# PROP Default_Filter "" +# Begin Group "AES" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Crypto\AES\aes.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\AES_CBC.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\aescpp.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\aescrypt.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\aeskey.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\aesopt.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\aestab.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\MyAES.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\MyAES.h +# End Source File +# End Group +# Begin Group "7zAES" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Crypto\7zAES\7zAES.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\7zAES\7zAES.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\7zAES\MySHA256.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\7zAES\SHA256.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\7zAES\SHA256.h +# End Source File +# End Group +# End Group +# Begin Group "7z" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\7z\7zDecode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zDecode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zExtract.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zFolderOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zFolderOutStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHeader.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHeader.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zIn.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zItem.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zMethodID.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zMethodID.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zMethods.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zProperties.h +# End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LockedStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LockedStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LSBFDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LSBFDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.h +# End Source File +# End Group +# End Target +# End Project diff --git a/7zip/Bundles/Format7zExtract/Format7z.dsw b/7zip/Bundles/Format7zExtract/Format7z.dsw new file mode 100755 index 00000000..324dab1f --- /dev/null +++ b/7zip/Bundles/Format7zExtract/Format7z.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "7z"=.\Format7z.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/7zip/Bundles/SFXCon/Main.cpp b/7zip/Bundles/SFXCon/Main.cpp index 7ad3b0b3..355088f4 100755 --- a/7zip/Bundles/SFXCon/Main.cpp +++ b/7zip/Bundles/SFXCon/Main.cpp @@ -2,13 +2,14 @@ #include "StdAfx.h" -#include <initguid.h> +#include "Common/MyInitGuid.h" #include "Common/CommandLineParser.h" #include "Common/StdOutStream.h" #include "Common/Wildcard.h" #include "Common/StringConvert.h" #include "Common/MyCom.h" +#include "Common/Exception.h" #include "Windows/FileDir.h" #include "Windows/FileName.h" @@ -18,19 +19,22 @@ #include "../../ICoder.h" #include "../../UI/Common/OpenArchive.h" -#include "../../UI/Common/ZipRegistry.h" #include "../../UI/Common/DefaultName.h" +#include "../../UI/Common/ExitCode.h" +#include "../../UI/Common/Extract.h" -#include "../../UI/Console/Extract.h" -#include "../../UI/Console/ArError.h" #include "../../UI/Console/List.h" +#include "../../UI/Console/OpenCallbackConsole.h" +#include "../../UI/Console/ExtractCallbackConsole.h" using namespace NWindows; using namespace NFile; using namespace NCommandLineParser; +extern CStdOutStream *g_StdStream; + static const char *kCopyrightString = -"\n7-Zip SFX 3.12 Copyright (c) 1999-2003 Igor Pavlov 2003-12-10\n"; +"\n7-Zip SFX 4.20 Copyright (c) 1999-2005 Igor Pavlov 2005-05-30\n"; static const int kNumSwitches = 6; @@ -140,11 +144,13 @@ static const char *kUserErrorMessage = "Incorrect command line"; // NExitCode:: static const char *kIncorrectListFile = "Incorrect wildcard in listfile"; static const char *kIncorrectWildCardInCommandLine = "Incorrect wildcard in command line"; -static const CSysString kFileIsNotArchiveMessageBefore = "File \""; -static const CSysString kFileIsNotArchiveMessageAfter = "\" is not archive"; +// static const CSysString kFileIsNotArchiveMessageBefore = "File \""; +// static const CSysString kFileIsNotArchiveMessageAfter = "\" is not archive"; static const char *kProcessArchiveMessage = " archive: "; +static const char *kCantFindSFX = " cannot find sfx"; + // --------------------------- @@ -156,10 +162,7 @@ static const CSysString kDefaultWorkingDirectory = ""; // test it maybemust be struct CArchiveCommand { NCommandType::EEnum CommandType; - // NListMode::EEnum ListMode; - // bool ListFullPathes; NRecursedType::EEnum DefaultRecursedType() const; - bool IsFromExtractGroup(NExtractMode::EEnum &extractMode) const; }; NRecursedType::EEnum CArchiveCommand::DefaultRecursedType() const @@ -167,26 +170,6 @@ NRecursedType::EEnum CArchiveCommand::DefaultRecursedType() const return kCommandRecursedDefault[CommandType]; } -bool CArchiveCommand::IsFromExtractGroup(NExtractMode::EEnum &extractMode) const -{ - switch(CommandType) - { - case NCommandType::kTest: - extractMode = NExtractMode::kTest; - return true; - /* - case NCommandType::kExtract: - extractMode = NExtractMode::kExtractToOne; - return true; - */ - case NCommandType::kFullExtract: - extractMode = NExtractMode::kFullPath; - return true; - default: - return false; - } -} - static NRecursedType::EEnum GetRecursedTypeFromIndex(int index) { switch (index) @@ -261,7 +244,7 @@ static bool AddNameToCensor(NWildcard::CCensor &wildcardCensor, recursed = false; break; } - wildcardCensor.AddItem(name, include, recursed, isWildCard); + wildcardCensor.AddItem(name, include, recursed); return true; } @@ -284,6 +267,7 @@ void AddToCensorFromNonSwitchesStrings(NWildcard::CCensor &wildcardCensor, AddCommandLineWildCardToCensr(wildcardCensor, kUniversalWildcard, true, type); } +/* void AddSwitchWildCardsToCensor(NWildcard::CCensor &wildcardCensor, const UStringVector &strings, bool include, NRecursedType::EEnum commonRecursedType) { @@ -314,42 +298,48 @@ void AddSwitchWildCardsToCensor(NWildcard::CCensor &wildcardCensor, PrintHelpAndExit(); } } +*/ // ------------------------------------------------------------------ +/* static void ThrowPrintFileIsNotArchiveException(const CSysString &fileName) { CSysString message; message = kFileIsNotArchiveMessageBefore + fileName + kFileIsNotArchiveMessageAfter; ShowMessageAndThrowException(message, NExitCode::kFileIsNotArchive); } +*/ -void MyOpenArhive(const UString &archiveName, - const NFind::CFileInfoW &archiveFileInfo, - IInArchive **archiveHandler, - UString &defaultItemName) +#ifndef _WIN32 +static void GetArguments(int numArguments, const char *arguments[], UStringVector &parts) { - CArchiverInfo archiverInfo; - int subExtIndex; - HRESULT result = OpenArchive(archiveName, archiveHandler, - archiverInfo, subExtIndex, 0); - if (result == S_FALSE) - throw "file is not supported archive"; - if (result != S_OK) - throw "error"; - defaultItemName = GetDefaultName(archiveName, - archiverInfo.Extensions[subExtIndex].Extension, - archiverInfo.Extensions[subExtIndex].AddExtension); + parts.Clear(); + for(int i = 0; i < numArguments; i++) + { + UString s = MultiByteToUnicodeString(arguments[i]); + parts.Add(s); + } } +#endif -// int Main2(int numArguments, const char *arguments[]) -int Main2() +int Main2( + #ifndef _WIN32 + int numArguments, const char *arguments[] + #endif +) { + #ifdef _WIN32 SetFileApisToOEM(); + #endif g_StdOut << kCopyrightString; - + UStringVector commandStrings; - SplitCommandLine(GetCommandLineW(), commandStrings); + #ifdef _WIN32 + NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings); + #else + GetArguments(numArguments, arguments, commandStrings); + #endif UString archiveName = commandStrings.Front(); @@ -401,9 +391,8 @@ int Main2() if (archiveName.Right(4).CompareNoCase(defaultExt) != 0) archiveName += defaultExt; - - NExtractMode::EEnum extractMode; - bool isExtractGroupCommand = command.IsFromExtractGroup(extractMode); + // NExtractMode::EEnum extractMode; + // bool isExtractGroupCommand = command.IsFromExtractGroup(extractMode); bool passwordEnabled = parser[NKey::kPassword].ThereIs; @@ -411,49 +400,76 @@ int Main2() if(passwordEnabled) password = parser[NKey::kPassword].PostStrings[0]; - if(isExtractGroupCommand || command.CommandType == NCommandType::kList) + NFind::CFileInfoW archiveFileInfo; + if (!NFind::FindFile(archiveName, archiveFileInfo)) + throw kCantFindSFX; + if (archiveFileInfo.IsDirectory()) + throw kCantFindSFX; + + UString outputDir; + if(parser[NKey::kOutputDir].ThereIs) + { + outputDir = parser[NKey::kOutputDir].PostStrings[0]; + NName::NormalizeDirPathPrefix(outputDir); + } + { - NFind::CFileInfoW archiveFileInfo; - if (!NFind::FindFile(archiveName, archiveFileInfo) || archiveFileInfo.IsDirectory()) - throw "there is no such archive"; - - if (archiveFileInfo.IsDirectory()) - throw "there is no such archive"; - - UString defaultItemName; - CMyComPtr<IInArchive> archiveHandler; - CArchiverInfo archiverInfo; - MyOpenArhive(archiveName, archiveFileInfo, &archiveHandler, defaultItemName); - if(isExtractGroupCommand) + UStringVector v1, v2; + v1.Add(archiveName); + v2.Add(archiveName); + const NWildcard::CCensorNode &wildcardCensorHead = + wildcardCensor.Pairs.Front().Head; + if(command.CommandType != NCommandType::kList) { - PrintProcessTitle(kExtractGroupProcessMessage, archiveName); - UString outputDir; - if(parser[NKey::kOutputDir].ThereIs) + CExtractCallbackConsole *ecs = new CExtractCallbackConsole; + CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs; + ecs->OutStream = g_StdStream; + ecs->PasswordIsDefined = passwordEnabled; + ecs->Password = password; + ecs->Init(); + + COpenCallbackConsole openCallback; + openCallback.OutStream = g_StdStream; + openCallback.PasswordIsDefined = passwordEnabled; + openCallback.Password = password; + + CExtractOptions eo; + eo.StdOutMode = false; + eo.PathMode = NExtract::NPathMode::kFullPathnames; + eo.TestMode = command.CommandType == NCommandType::kTest; + eo.OverwriteMode = yesToAll ? + NExtract::NOverwriteMode::kWithoutPrompt : + NExtract::NOverwriteMode::kAskBefore; + eo.OutputDir = outputDir; + eo.YesToAll = yesToAll; + + HRESULT result = DecompressArchives( + v1, v2, + wildcardCensorHead, + eo, &openCallback, ecs); + + if (ecs->NumArchiveErrors != 0 || ecs->NumFileErrors != 0) { - outputDir = parser[NKey::kOutputDir].PostStrings[0]; - NName::NormalizeDirPathPrefix(outputDir); + if (ecs->NumArchiveErrors != 0) + (*g_StdStream) << endl << "Archive Errors: " << ecs->NumArchiveErrors << endl; + if (ecs->NumFileErrors != 0) + (*g_StdStream) << endl << "Sub items Errors: " << ecs->NumFileErrors << endl; + return NExitCode::kFatalError; } - NExtraction::NOverwriteMode::EEnum overwriteMode = - NExtraction::NOverwriteMode::kAskBefore; - CExtractOptions options(extractMode, outputDir, yesToAll, - passwordEnabled, password, overwriteMode); - options.DefaultItemName = defaultItemName; - options.ArchiveFileInfo = archiveFileInfo; - // options.ArchiveFileInfo = archiveFileInfo; - HRESULT result = DeCompressArchiveSTD(archiveHandler, wildcardCensor, options); if (result != S_OK) - { - return NExitCode::kErrorsDuringDecompression; - } + throw CSystemException(result); } else { - PrintProcessTitle(kListingProcessMessage, archiveName); - ListArchive(archiveHandler, defaultItemName, archiveFileInfo, - wildcardCensor/*, command.ListFullPathes, command.ListMode*/); + HRESULT result = ListArchives( + v1, v2, + wildcardCensorHead, + true, + passwordEnabled, + password); + if (result != S_OK) + throw CSystemException(result); } } - else - PrintHelpAndExit(); return 0; } diff --git a/7zip/Bundles/SFXCon/SFXCon.dsp b/7zip/Bundles/SFXCon/SFXCon.dsp index 592c8cfb..05899e39 100755 --- a/7zip/Bundles/SFXCon/SFXCon.dsp +++ b/7zip/Bundles/SFXCon/SFXCon.dsp @@ -50,7 +50,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"C:\Util\7zSfxCon.exe" /opt:NOWIN98 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"C:\Util\7zCon.sfx" /opt:NOWIN98 # SUBTRACT LINK32 /pdb:none !ELSEIF "$(CFG)" == "SFXCon - Win32 Debug" @@ -75,7 +75,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"C:\Util\7zSfxCon.exe" /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"C:\Util\7zCon.sfx" /pdbtype:sept !ENDIF @@ -117,6 +117,22 @@ SOURCE=..\..\Archive\Common\CoderMixer2.h # End Source File # Begin Source File +SOURCE=..\..\Archive\Common\CoderMixer2MT.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2MT.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2ST.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2ST.h +# End Source File +# Begin Source File + SOURCE=..\..\Archive\Common\CrossThreadProgress.cpp # End Source File # Begin Source File @@ -125,6 +141,14 @@ SOURCE=..\..\Archive\Common\CrossThreadProgress.h # End Source File # Begin Source File +SOURCE=..\..\Archive\Common\FilterCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\FilterCoder.h +# End Source File +# Begin Source File + SOURCE=..\..\Archive\Common\ItemNameUtils.cpp # End Source File # Begin Source File @@ -140,7 +164,7 @@ SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp SOURCE=..\..\Archive\Common\OutStreamWithCRC.h # End Source File # End Group -# Begin Group "Console Archiver" +# Begin Group "Console" # PROP Default_Filter "" # Begin Source File @@ -153,31 +177,31 @@ SOURCE=..\..\UI\Console\ConsoleClose.h # End Source File # Begin Source File -SOURCE=..\..\UI\Console\Extract.cpp +SOURCE=..\..\UI\Console\ExtractCallbackConsole.cpp # End Source File # Begin Source File -SOURCE=..\..\UI\Console\Extract.h +SOURCE=..\..\UI\Console\ExtractCallbackConsole.h # End Source File # Begin Source File -SOURCE=..\..\UI\Console\ExtractCallback.cpp +SOURCE=..\..\UI\Console\List.cpp # End Source File # Begin Source File -SOURCE=..\..\UI\Console\ExtractCallback.h +SOURCE=..\..\UI\Console\List.h # End Source File # Begin Source File -SOURCE=..\..\UI\Console\List.cpp +SOURCE=..\..\UI\Console\MainAr.cpp # End Source File # Begin Source File -SOURCE=..\..\UI\Console\List.h +SOURCE=..\..\UI\Console\OpenCallbackConsole.cpp # End Source File # Begin Source File -SOURCE=..\..\UI\Console\MainAr.cpp +SOURCE=..\..\UI\Console\OpenCallbackConsole.h # End Source File # Begin Source File @@ -239,6 +263,14 @@ SOURCE=..\..\Archive\7z\7zIn.h SOURCE=..\..\Archive\7z\7zItem.h # End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zMethodID.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zMethodID.h +# End Source File # End Group # Begin Group "Compress" @@ -256,6 +288,14 @@ SOURCE=..\..\Compress\LZMA\LZMADecoder.cpp # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\Compress\Branch\BranchCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\BranchCoder.h +# End Source File +# Begin Source File + SOURCE=..\..\Compress\Branch\x86.cpp # End Source File # Begin Source File @@ -438,18 +478,18 @@ SOURCE=..\..\..\Windows\Synchronization.cpp SOURCE=..\..\..\Windows\Synchronization.h # End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" # Begin Source File -SOURCE=..\..\..\Windows\System.cpp +SOURCE=..\..\..\Common\Alloc.cpp # End Source File # Begin Source File -SOURCE=..\..\..\Windows\System.h +SOURCE=..\..\..\Common\Alloc.h # End Source File -# End Group -# Begin Group "Common" - -# PROP Default_Filter "" # Begin Source File SOURCE=..\..\..\Common\CommandLineParser.cpp @@ -568,11 +608,11 @@ SOURCE=..\..\Common\LimitedStreams.h # End Source File # Begin Source File -SOURCE=..\..\Common\MultiStream.cpp +SOURCE=..\..\Common\LockedStream.cpp # End Source File # Begin Source File -SOURCE=..\..\Common\MultiStream.h +SOURCE=..\..\Common\LockedStream.h # End Source File # Begin Source File @@ -623,6 +663,22 @@ SOURCE=..\..\Common\StreamObjects.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\UI\Common\ArchiveExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveOpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveOpenCallback.h +# End Source File +# Begin Source File + SOURCE=..\..\UI\Common\ArchiverInfo.cpp # End Source File # Begin Source File @@ -639,6 +695,18 @@ SOURCE=..\..\UI\Common\DefaultName.h # End Source File # Begin Source File +SOURCE=..\..\UI\Common\ExitCode.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Extract.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Extract.h +# End Source File +# Begin Source File + SOURCE=..\..\UI\Common\ExtractingFilePath.cpp # End Source File # Begin Source File @@ -647,6 +715,10 @@ SOURCE=..\..\UI\Common\ExtractingFilePath.h # End Source File # Begin Source File +SOURCE=..\..\UI\Common\ExtractMode.h +# End Source File +# Begin Source File + SOURCE=..\..\UI\Common\OpenArchive.cpp # End Source File # Begin Source File diff --git a/7zip/Bundles/SFXCon/StdAfx.cpp b/7zip/Bundles/SFXCon/StdAfx.cpp index 2550270c..d0feea85 100755 --- a/7zip/Bundles/SFXCon/StdAfx.cpp +++ b/7zip/Bundles/SFXCon/StdAfx.cpp @@ -1,3 +1,3 @@ // StdAfx.cpp -#include "stdafx.h" +#include "StdAfx.h" diff --git a/7zip/Bundles/SFXCon/StdAfx.h b/7zip/Bundles/SFXCon/StdAfx.h index 77b5124c..e7fb6986 100755 --- a/7zip/Bundles/SFXCon/StdAfx.h +++ b/7zip/Bundles/SFXCon/StdAfx.h @@ -1,11 +1,8 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> -#include <stdio.h> -// #include <time.h> -#include <tchar.h> +#include "../../../Common/MyWindows.h" -#endif +#endif diff --git a/7zip/Bundles/SFXCon/resource.rc b/7zip/Bundles/SFXCon/resource.rc index f0444133..e28b2872 100755 --- a/7zip/Bundles/SFXCon/resource.rc +++ b/7zip/Bundles/SFXCon/resource.rc @@ -75,8 +75,8 @@ IDI_ICON1 ICON DISCARDABLE "7z.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,12,0,0 - PRODUCTVERSION 3,12,0,0 + FILEVERSION 4,20,0,0 + PRODUCTVERSION 4,20,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -94,14 +94,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Igor Pavlov\0" VALUE "FileDescription", "7z SFX (Console version)\0" - VALUE "FileVersion", "3, 12, 0, 0\0" + VALUE "FileVersion", "4, 20, 0, 0\0" VALUE "InternalName", "7zCon.sfx\0" - VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "7zCon.sfx\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "7-Zip\0" - VALUE "ProductVersion", "3, 12, 0, 0\0" + VALUE "ProductVersion", "4, 20, 0, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/7zip/Bundles/SFXSetup/ExtractCallback.cpp b/7zip/Bundles/SFXSetup/ExtractCallback.cpp index 893817d6..ea4cc9bb 100755 --- a/7zip/Bundles/SFXSetup/ExtractCallback.cpp +++ b/7zip/Bundles/SFXSetup/ExtractCallback.cpp @@ -31,7 +31,7 @@ void CExtractCallbackImp::Init(IInArchive *archiveHandler, const UString &directoryPath, const UString &itemDefaultName, const FILETIME &utcLastWriteTimeDefault, - UINT32 attributesDefault) + UInt32 attributesDefault) { _numErrors = 0; _itemDefaultName = itemDefaultName; @@ -42,7 +42,7 @@ void CExtractCallbackImp::Init(IInArchive *archiveHandler, NName::NormalizeDirPathPrefix(_directoryPath); } -STDMETHODIMP CExtractCallbackImp::SetTotal(UINT64 size) +STDMETHODIMP CExtractCallbackImp::SetTotal(UInt64 size) { #ifndef _NO_PROGRESS ProgressDialog.ProgressSynch.SetProgress(size, 0); @@ -50,7 +50,7 @@ STDMETHODIMP CExtractCallbackImp::SetTotal(UINT64 size) return S_OK; } -STDMETHODIMP CExtractCallbackImp::SetCompleted(const UINT64 *completeValue) +STDMETHODIMP CExtractCallbackImp::SetCompleted(const UInt64 *completeValue) { #ifndef _NO_PROGRESS while(true) @@ -78,8 +78,8 @@ void CExtractCallbackImp::CreateComplexDirectory(const UStringVector &dirPathPar } } -STDMETHODIMP CExtractCallbackImp::GetStream(UINT32 index, - ISequentialOutStream **outStream, INT32 askExtractMode) +STDMETHODIMP CExtractCallbackImp::GetStream(UInt32 index, + ISequentialOutStream **outStream, Int32 askExtractMode) { #ifndef _NO_PROGRESS if(ProgressDialog.ProgressSynch.GetStopped()) @@ -185,7 +185,7 @@ STDMETHODIMP CExtractCallbackImp::GetStream(UINT32 index, { _outFileStreamSpec = new COutFileStream; CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec); - if (!_outFileStreamSpec->Open(fullProcessedPath)) + if (!_outFileStreamSpec->Create(fullProcessedPath, true)) { #ifdef _SILENT _message = kCantOpenFile; @@ -206,7 +206,7 @@ STDMETHODIMP CExtractCallbackImp::GetStream(UINT32 index, return S_OK; } -STDMETHODIMP CExtractCallbackImp::PrepareOperation(INT32 askExtractMode) +STDMETHODIMP CExtractCallbackImp::PrepareOperation(Int32 askExtractMode) { _extractMode = false; switch (askExtractMode) @@ -218,7 +218,7 @@ STDMETHODIMP CExtractCallbackImp::PrepareOperation(INT32 askExtractMode) return S_OK; } -STDMETHODIMP CExtractCallbackImp::SetOperationResult(INT32 resultEOperationResult) +STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 resultEOperationResult) { switch(resultEOperationResult) { diff --git a/7zip/Bundles/SFXSetup/ExtractCallback.h b/7zip/Bundles/SFXSetup/ExtractCallback.h index b5b72a24..b983e90b 100755 --- a/7zip/Bundles/SFXSetup/ExtractCallback.h +++ b/7zip/Bundles/SFXSetup/ExtractCallback.h @@ -1,7 +1,5 @@ // ExtractCallback.h -#pragma once - #ifndef __EXTRACTCALLBACK_H #define __EXTRACTCALLBACK_H @@ -31,14 +29,14 @@ public: MY_UNKNOWN_IMP // IProgress - STDMETHOD(SetTotal)(UINT64 size); - STDMETHOD(SetCompleted)(const UINT64 *completeValue); + STDMETHOD(SetTotal)(UInt64 size); + STDMETHOD(SetCompleted)(const UInt64 *completeValue); // IExtractCallback - STDMETHOD(GetStream)(UINT32 index, ISequentialOutStream **outStream, - INT32 askExtractMode); - STDMETHOD(PrepareOperation)(INT32 askExtractMode); - STDMETHOD(SetOperationResult)(INT32 resultEOperationResult); + STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, + Int32 askExtractMode); + STDMETHOD(PrepareOperation)(Int32 askExtractMode); + STDMETHOD(SetOperationResult)(Int32 resultEOperationResult); private: CMyComPtr<IInArchive> _archiveHandler; @@ -53,7 +51,7 @@ private: { FILETIME UTCLastWriteTime; bool IsDirectory; - UINT32 Attributes; + UInt32 Attributes; } _processedFileInfo; COutFileStream *_outFileStreamSpec; @@ -61,7 +59,7 @@ private: UString _itemDefaultName; FILETIME _utcLastWriteTimeDefault; - UINT32 _attributesDefault; + UInt32 _attributesDefault; void CreateComplexDirectory(const UStringVector &dirPathParts); public: @@ -77,9 +75,9 @@ public: const UString &directoryPath, const UString &itemDefaultName, const FILETIME &utcLastWriteTimeDefault, - UINT32 attributesDefault); + UInt32 attributesDefault); - UINT64 _numErrors; + UInt64 _numErrors; #ifndef _NO_PROGRESS HRESULT StartProgressDialog(const UString &title) @@ -97,7 +95,7 @@ public: // _progressDialog.Start(m_ParentWindow, PROGDLG_MODAL | PROGDLG_AUTOTIME); return S_OK; } - ~CExtractCallbackImp() { ProgressDialog.Destroy(); } + virtual ~CExtractCallbackImp() { ProgressDialog.Destroy(); } #endif }; diff --git a/7zip/Bundles/SFXSetup/ExtractEngine.cpp b/7zip/Bundles/SFXSetup/ExtractEngine.cpp index dd45f53e..b98de9f3 100755 --- a/7zip/Bundles/SFXSetup/ExtractEngine.cpp +++ b/7zip/Bundles/SFXSetup/ExtractEngine.cpp @@ -21,7 +21,9 @@ using namespace NWindows; struct CThreadExtracting { - CMyComPtr<IInArchive> ArchiveHandler; + // CMyComPtr<IInArchive> ArchiveHandler; + CArchiveLink ArchiveLink; + CExtractCallbackImp *ExtractCallbackSpec; CMyComPtr<IArchiveExtractCallback> ExtractCallback; @@ -31,7 +33,7 @@ struct CThreadExtracting DWORD Process() { ExtractCallbackSpec->ProgressDialog.WaitCreating(); - Result = ArchiveHandler->Extract(0, (UINT32)-1 , BoolToInt(false), + Result = ArchiveLink.GetArchive()->Extract(0, (UInt32)-1 , BoolToInt(false), ExtractCallback); ExtractCallbackSpec->ProgressDialog.MyClose(); return 0; @@ -48,7 +50,8 @@ static const LPCTSTR kCantOpenArchive = TEXT("File is not correct archive"); HRESULT ExtractArchive( const UString &fileName, - const UString &folderName + const UString &folderName, + COpenCallbackGUI *openCallback #ifdef _SILENT , UString &resultMessage #endif @@ -67,10 +70,14 @@ HRESULT ExtractArchive( CThreadExtracting extracter; + HRESULT result = MyOpenArchive(fileName, extracter.ArchiveLink, openCallback); + + /* CArchiverInfo archiverInfoResult; int subExtIndex; HRESULT result = OpenArchive(fileName, &extracter.ArchiveHandler, archiverInfoResult, subExtIndex, NULL); + */ if (result != S_OK) { #ifdef _SILENT @@ -85,14 +92,14 @@ HRESULT ExtractArchive( /* UString directoryPath; { - UString aFullPath; - int aFileNamePartStartIndex; - if (!NWindows::NFile::NDirectory::MyGetFullPathName(fileName, aFullPath, aFileNamePartStartIndex)) + UString fullPath; + int fileNamePartStartIndex; + if (!NWindows::NFile::NDirectory::MyGetFullPathName(fileName, fullPath, fileNamePartStartIndex)) { MessageBox(NULL, "Error 1329484", "7-Zip", 0); return E_FAIL; } - directoryPath = aFullPath.Left(aFileNamePartStartIndex); + directoryPath = fullPath.Left(fileNamePartStartIndex); } */ @@ -117,7 +124,8 @@ HRESULT ExtractArchive( // anExtractCallBackSpec->m_ProgressDialog.ShowWindow(SW_SHOWNORMAL); - extracter.ExtractCallbackSpec->Init(extracter.ArchiveHandler, + extracter.ExtractCallbackSpec->Init( + extracter.ArchiveLink.GetArchive(), directoryPath, L"Default", archiveFileInfo.LastWriteTime, 0); #ifndef _NO_PROGRESS @@ -137,7 +145,7 @@ HRESULT ExtractArchive( #else - result = extracter.ArchiveHandler->Extract(0, (UINT32)-1, + result = extracter.ArchiveHandler->Extract(0, (UInt32)-1, BoolToInt(false), extracter.ExtractCallback); #ifdef _SILENT resultMessage = extracter.ExtractCallbackSpec->_message; diff --git a/7zip/Bundles/SFXSetup/ExtractEngine.h b/7zip/Bundles/SFXSetup/ExtractEngine.h index 331ac7fa..c1b670e2 100755 --- a/7zip/Bundles/SFXSetup/ExtractEngine.h +++ b/7zip/Bundles/SFXSetup/ExtractEngine.h @@ -4,10 +4,12 @@ #define __EXTRACTENGINE_H #include "Common/String.h" +#include "../../UI/GUI/OpenCallbackGUI.h" HRESULT ExtractArchive( const UString &fileName, - const UString &folderName + const UString &folderName, + COpenCallbackGUI *openCallback #ifdef _SILENT , UString &resultMessage #endif diff --git a/7zip/Bundles/SFXSetup/Main.cpp b/7zip/Bundles/SFXSetup/Main.cpp index b132522a..b53b4243 100755 --- a/7zip/Bundles/SFXSetup/Main.cpp +++ b/7zip/Bundles/SFXSetup/Main.cpp @@ -20,8 +20,11 @@ #include "../../Archive/IArchive.h" #include "../../UI/Explorer/MyMessages.h" +// #include "../../UI/GUI/ExtractGUI.h" + #include "ExtractEngine.h" + HINSTANCE g_hInstance; using namespace NWindows; @@ -37,25 +40,25 @@ static bool ReadDataString(LPCWSTR fileName, LPCSTR startID, return false; const int kBufferSize = (1 << 12); - BYTE buffer[kBufferSize]; + Byte buffer[kBufferSize]; int signatureStartSize = lstrlenA(startID); int signatureEndSize = lstrlenA(endID); - UINT32 numBytesPrev = 0; + UInt32 numBytesPrev = 0; bool writeMode = false; - UINT64 posTotal = 0; + UInt64 posTotal = 0; while(true) { if (posTotal > (1 << 20)) return (stringResult.IsEmpty()); - UINT32 numReadBytes = kBufferSize - numBytesPrev; - UINT32 processedSize; + UInt32 numReadBytes = kBufferSize - numBytesPrev; + UInt32 processedSize; if (!inFile.Read(buffer + numBytesPrev, numReadBytes, processedSize)) return false; if (processedSize == 0) return true; - UINT32 numBytesInBuffer = numBytesPrev + processedSize; - UINT32 pos = 0; + UInt32 numBytesInBuffer = numBytesPrev + processedSize; + UInt32 pos = 0; while (true) { if (writeMode) @@ -123,6 +126,7 @@ int APIENTRY WinMain( { InitCommonControls(); g_hInstance = (HINSTANCE)hInstance; + UString archiveName, switches; NCommandLineParser::SplitCommandLine(GetCommandLineW(), archiveName, switches); @@ -144,6 +148,9 @@ int APIENTRY WinMain( switches.Trim(); } +#ifdef _SHELL_EXECUTE + bool executeMode = false; +#endif UString appLaunched; if (!config.IsEmpty()) { @@ -163,6 +170,13 @@ int APIENTRY WinMain( return 0; } appLaunched = GetTextConfigValue(pairs, L"RunProgram"); +#ifdef _SHELL_EXECUTE + if (appLaunched.IsEmpty()) + { + executeMode = true; + appLaunched = GetTextConfigValue(pairs, L"Execute"); + } +#endif } NFile::NDirectory::CTempDirectory tempDir; @@ -172,64 +186,110 @@ int APIENTRY WinMain( return 1; } - HRESULT result = ExtractArchive(fullPath, GetUnicodeString(tempDir.GetPath())); + COpenCallbackGUI openCallback; + + UString tempDirPath = GetUnicodeString(tempDir.GetPath()); + HRESULT result = ExtractArchive(fullPath, tempDirPath, &openCallback); + if (result != S_OK) { if (result == S_FALSE) MyMessageBox(L"Can not open archive"); else if (result != E_ABORT) ShowErrorMessage(result); - return 1; + return 1; } CCurrentDirRestorer currentDirRestorer; if (!SetCurrentDirectory(tempDir.GetPath())) return 1; - if (appLaunched.IsEmpty()) { - appLaunched = L"Setup.exe"; + appLaunched = L"setup.exe"; if (!NFile::NFind::DoesFileExist(GetSystemString(appLaunched))) + { + MyMessageBox(L"Can not find setup.exe"); return 1; + } } - STARTUPINFO startupInfo; - startupInfo.cb = sizeof(startupInfo); - startupInfo.lpReserved = 0; - startupInfo.lpDesktop = 0; - startupInfo.lpTitle = 0; - startupInfo.dwFlags = 0; - startupInfo.cbReserved2 = 0; - startupInfo.lpReserved2 = 0; - - PROCESS_INFORMATION processInformation; - CSysString shortPath; - if (!NFile::NDirectory::MyGetShortPathName(tempDir.GetPath(), shortPath)) - return 1; + { + UString s2 = tempDirPath; + NFile::NName::NormalizeDirPathPrefix(s2); + appLaunched.Replace(L"%%T\\", s2); + } - UString appLaunchedSysU = appLaunched; - appLaunchedSysU.Replace(TEXT(L"%%T"), GetUnicodeString(shortPath)); + appLaunched.Replace(L"%%T", tempDirPath); - appLaunchedSysU += L' '; - appLaunchedSysU += switches; - - CSysString tempDirPathNormalized = shortPath; - NFile::NName::NormalizeDirPathPrefix(shortPath); - // CSysString appLaunchedSys = shortPath + GetSystemString(appLaunchedSysU); - CSysString appLaunchedSys = CSysString(TEXT(".\\")) + GetSystemString(appLaunchedSysU); - - BOOL createResult = CreateProcess(NULL, (LPTSTR)(LPCTSTR)appLaunchedSys, + + HANDLE hProcess = 0; +#ifdef _SHELL_EXECUTE + if (executeMode) + { + CSysString filePath = GetSystemString(appLaunched); + SHELLEXECUTEINFO execInfo; + execInfo.cbSize = sizeof(execInfo); + execInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT; + execInfo.hwnd = NULL; + execInfo.lpVerb = NULL; + execInfo.lpFile = filePath; + + CSysString switchesSys = GetSystemString(switches); + if (switchesSys.IsEmpty()) + execInfo.lpParameters = NULL; + else + execInfo.lpParameters = switchesSys; + + execInfo.lpDirectory = NULL; + execInfo.nShow = SW_SHOWNORMAL; + execInfo.hProcess = 0; + bool success = BOOLToBool(::ShellExecuteEx(&execInfo)); + result = (UINT32)execInfo.hInstApp; + if(result <= 32) + { + MyMessageBox(L"Can not open file"); + return 1; + } + hProcess = execInfo.hProcess; + } + else +#endif + { + if (!switches.IsEmpty()) + { + appLaunched += L' '; + appLaunched += switches; + } + STARTUPINFO startupInfo; + startupInfo.cb = sizeof(startupInfo); + startupInfo.lpReserved = 0; + startupInfo.lpDesktop = 0; + startupInfo.lpTitle = 0; + startupInfo.dwFlags = 0; + startupInfo.cbReserved2 = 0; + startupInfo.lpReserved2 = 0; + + PROCESS_INFORMATION processInformation; + + CSysString appLaunchedSys = CSysString(TEXT(".\\")) + GetSystemString(appLaunched); + + BOOL createResult = CreateProcess(NULL, (LPTSTR)(LPCTSTR)appLaunchedSys, NULL, NULL, FALSE, 0, NULL, NULL /*tempDir.GetPath() */, &startupInfo, &processInformation); - if (createResult == 0) + if (createResult == 0) + { + ShowLastErrorMessage(); + return 1; + } + ::CloseHandle(processInformation.hThread); + hProcess = processInformation.hProcess; + } + if (hProcess != 0) { - ShowLastErrorMessage(); - return 1; + WaitForSingleObject(hProcess, INFINITE); + ::CloseHandle(hProcess); } - WaitForSingleObject(processInformation.hProcess, INFINITE); - ::CloseHandle(processInformation.hThread); - ::CloseHandle(processInformation.hProcess); return 0; } diff --git a/7zip/Bundles/SFXSetup/SFXSetup.dsp b/7zip/Bundles/SFXSetup/SFXSetup.dsp index 38b10955..a2f4f204 100755 --- a/7zip/Bundles/SFXSetup/SFXSetup.dsp +++ b/7zip/Bundles/SFXSetup/SFXSetup.dsp @@ -54,7 +54,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 -# ADD LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\UTIL\7zSfxS.exe" /opt:NOWIN98 +# ADD LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7zS.sfx" /opt:NOWIN98 # SUBTRACT LINK32 /pdb:none !ELSEIF "$(CFG)" == "SFXSetup - Win32 Debug" @@ -109,7 +109,7 @@ BSC32=bscmake.exe LINK32=link.exe # ADD BASE LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\UTIL\7zWinSR.exe" # SUBTRACT BASE LINK32 /debug /nodefaultlib -# ADD LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\UTIL\7zSfxSD.exe" /opt:NOWIN98 +# ADD LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7zSD.sfx" /opt:NOWIN98 # SUBTRACT LINK32 /pdb:none !ENDIF @@ -191,6 +191,14 @@ SOURCE=..\..\Archive\7z\7zIn.h SOURCE=..\..\Archive\7z\7zItem.h # End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zMethodID.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zMethodID.h +# End Source File # End Group # Begin Group "Archive Common" @@ -205,6 +213,14 @@ SOURCE=..\..\Archive\Common\CoderMixer2.h # End Source File # Begin Source File +SOURCE=..\..\Archive\Common\CoderMixer2MT.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2MT.h +# End Source File +# Begin Source File + SOURCE=..\..\Archive\Common\CrossThreadProgress.cpp # End Source File # Begin Source File @@ -213,6 +229,14 @@ SOURCE=..\..\Archive\Common\CrossThreadProgress.h # End Source File # Begin Source File +SOURCE=..\..\Archive\Common\FilterCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\FilterCoder.h +# End Source File +# Begin Source File + SOURCE=..\..\Archive\Common\ItemNameUtils.cpp # End Source File # Begin Source File @@ -244,6 +268,14 @@ SOURCE=..\..\Compress\LZMA\LZMADecoder.cpp # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\Compress\Branch\BranchCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\BranchCoder.h +# End Source File +# Begin Source File + SOURCE=..\..\Compress\Branch\x86.cpp # End Source File # Begin Source File @@ -285,6 +317,14 @@ SOURCE=..\..\Compress\LZ\LZOutWindow.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\CommandLineParser.cpp # End Source File # Begin Source File @@ -481,11 +521,11 @@ SOURCE=..\..\Common\LimitedStreams.h # End Source File # Begin Source File -SOURCE=..\..\Common\MultiStream.cpp +SOURCE=..\..\Common\LockedStream.cpp # End Source File # Begin Source File -SOURCE=..\..\Common\MultiStream.h +SOURCE=..\..\Common\LockedStream.h # End Source File # Begin Source File @@ -540,6 +580,14 @@ SOURCE=..\..\UI\Explorer\MyMessages.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\UI\Common\ArchiveOpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveOpenCallback.h +# End Source File +# Begin Source File + SOURCE=..\..\UI\Common\ArchiverInfo.cpp # End Source File # Begin Source File @@ -548,6 +596,18 @@ SOURCE=..\..\UI\Common\ArchiverInfo.h # End Source File # Begin Source File +SOURCE=..\..\UI\Common\DefaultName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\DefaultName.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ExtractMode.h +# End Source File +# Begin Source File + SOURCE=..\..\UI\Common\OpenArchive.cpp # End Source File # Begin Source File @@ -555,6 +615,18 @@ SOURCE=..\..\UI\Common\OpenArchive.cpp SOURCE=..\..\UI\Common\OpenArchive.h # End Source File # End Group +# Begin Group "GUI" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\GUI\OpenCallbackGUI.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\GUI\OpenCallbackGUI.h +# End Source File +# End Group # End Group # Begin Group "File Manager" diff --git a/7zip/Bundles/SFXSetup/StdAfx.cpp b/7zip/Bundles/SFXSetup/StdAfx.cpp index 2550270c..d0feea85 100755 --- a/7zip/Bundles/SFXSetup/StdAfx.cpp +++ b/7zip/Bundles/SFXSetup/StdAfx.cpp @@ -1,3 +1,3 @@ // StdAfx.cpp -#include "stdafx.h" +#include "StdAfx.h" diff --git a/7zip/Bundles/SFXSetup/StdAfx.h b/7zip/Bundles/SFXSetup/StdAfx.h index fe98539c..eb294d41 100755 --- a/7zip/Bundles/SFXSetup/StdAfx.h +++ b/7zip/Bundles/SFXSetup/StdAfx.h @@ -1,11 +1,9 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> +#include "../../../Common/MyWindows.h" #include <commctrl.h> -#include <limits.h> -// #include <time.h> -#endif +#endif diff --git a/7zip/Bundles/SFXSetup/resource.rc b/7zip/Bundles/SFXSetup/resource.rc index 9ff820c2..894de776 100755 --- a/7zip/Bundles/SFXSetup/resource.rc +++ b/7zip/Bundles/SFXSetup/resource.rc @@ -76,8 +76,8 @@ IDI_ICON3 ICON DISCARDABLE "setup.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,12,0,0 - PRODUCTVERSION 3,12,0,0 + FILEVERSION 4,20,0,0 + PRODUCTVERSION 4,20,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -95,14 +95,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Igor Pavlov\0" VALUE "FileDescription", "7z Self-Extract Setup\0" - VALUE "FileVersion", "3, 12, 0, 0\0" + VALUE "FileVersion", "4, 20, 0, 0\0" VALUE "InternalName", "7zS.sfx\0" - VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "7zS.sfx\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "7-Zip\0" - VALUE "ProductVersion", "3, 12, 0, 0\0" + VALUE "ProductVersion", "4, 20, 0, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/7zip/Bundles/SFXWin/Main.cpp b/7zip/Bundles/SFXWin/Main.cpp index ec7e5fd0..ca6bb1b5 100755 --- a/7zip/Bundles/SFXWin/Main.cpp +++ b/7zip/Bundles/SFXWin/Main.cpp @@ -14,9 +14,9 @@ #include "../../ICoder.h" #include "../../IPassword.h" #include "../../Archive/IArchive.h" -#include "../../UI/Agent/Agent.h" -#include "../../UI/GUI/Extract.h" +#include "../../UI/Common/Extract.h" #include "../../UI/Explorer/MyMessages.h" +#include "../../UI/GUI/ExtractGUI.h" HINSTANCE g_hInstance; @@ -55,9 +55,37 @@ int APIENTRY WinMain( MyMessageBox(L"Error 1329484"); return 1; } + + COpenCallbackGUI openCallback; + + CExtractCallbackImp *ecs = new CExtractCallbackImp; + CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs; + ecs->Init(); + + CExtractOptions eo; + eo.OutputDir = outputFolderDefined ? outputFolder : + fullPath.Left(fileNamePartStartIndex); + eo.YesToAll = assumeYes; + eo.OverwriteMode = assumeYes ? + NExtract::NOverwriteMode::kWithoutPrompt : + NExtract::NOverwriteMode::kAskBefore; + eo.PathMode = NExtract::NPathMode::kFullPathnames; + eo.TestMode = false; + + UStringVector v1, v2; + v1.Add(fullPath); + v2.Add(fullPath); + NWildcard::CCensorNode wildcardCensor; + wildcardCensor.AddItem(L"*", true, true, true, true); + + HRESULT result = ExtractGUI(v1, v2, + wildcardCensor, eo, (assumeYes ? false: true), &openCallback, ecs); + + /* HRESULT result = ExtractArchive(NULL, path, assumeYes, !assumeYes, outputFolderDefined ? outputFolder : fullPath.Left(fileNamePartStartIndex)); + */ if (result == S_FALSE) MyMessageBox(L"Archive is not supported"); else if (result != S_OK && result != E_ABORT) diff --git a/7zip/Bundles/SFXWin/SFXWin.dsp b/7zip/Bundles/SFXWin/SFXWin.dsp index 89b3eee4..56164a35 100755 --- a/7zip/Bundles/SFXWin/SFXWin.dsp +++ b/7zip/Bundles/SFXWin/SFXWin.dsp @@ -53,7 +53,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\UTIL\7zSfx.exe" /opt:NOWIN98 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7z.sfx" /opt:NOWIN98 # SUBTRACT LINK32 /pdb:none !ELSEIF "$(CFG)" == "SFXWin - Win32 Debug" @@ -80,7 +80,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\UTIL\7zSfx.exe" /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\Util\7z.sfx" /pdbtype:sept !ENDIF @@ -148,6 +148,14 @@ SOURCE=..\..\Archive\7z\7zIn.cpp SOURCE=..\..\Archive\7z\7zIn.h # End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zMethodID.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zMethodID.h +# End Source File # End Group # Begin Group "Archive Common" @@ -162,6 +170,14 @@ SOURCE=..\..\Archive\Common\CoderMixer2.h # End Source File # Begin Source File +SOURCE=..\..\Archive\Common\CoderMixer2MT.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2MT.h +# End Source File +# Begin Source File + SOURCE=..\..\Archive\Common\CrossThreadProgress.cpp # End Source File # Begin Source File @@ -170,6 +186,14 @@ SOURCE=..\..\Archive\Common\CrossThreadProgress.h # End Source File # Begin Source File +SOURCE=..\..\Archive\Common\FilterCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\FilterCoder.h +# End Source File +# Begin Source File + SOURCE=..\..\Archive\Common\ItemNameUtils.cpp # End Source File # Begin Source File @@ -201,6 +225,14 @@ SOURCE=..\..\Compress\LZMA\LZMADecoder.cpp # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\Compress\Branch\BranchCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\BranchCoder.h +# End Source File +# Begin Source File + SOURCE=..\..\Compress\Branch\x86.cpp # End Source File # Begin Source File @@ -261,34 +293,6 @@ SOURCE=..\..\Compress\Copy\CopyCoder.h # End Source File # End Group # End Group -# Begin Group "Agent" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\UI\Agent\Agent.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\UI\Agent\Agent.h -# End Source File -# Begin Source File - -SOURCE=..\..\UI\Agent\AgentProxy.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\UI\Agent\AgentProxy.h -# End Source File -# Begin Source File - -SOURCE=..\..\UI\Agent\ArchiveExtractCallback.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\UI\Agent\ArchiveExtractCallback.h -# End Source File -# End Group # Begin Group "Crypto" # PROP Default_Filter "" @@ -310,28 +314,12 @@ SOURCE=..\..\Crypto\AES\aescpp.h # Begin Source File SOURCE=..\..\Crypto\AES\aescrypt.c - -!IF "$(CFG)" == "SFXWin - Win32 Release" - # SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "SFXWin - Win32 Debug" - -!ENDIF - # End Source File # Begin Source File SOURCE=..\..\Crypto\AES\aeskey.c - -!IF "$(CFG)" == "SFXWin - Win32 Release" - # SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "SFXWin - Win32 Debug" - -!ENDIF - # End Source File # Begin Source File @@ -340,15 +328,7 @@ SOURCE=..\..\Crypto\AES\aesopt.h # Begin Source File SOURCE=..\..\Crypto\AES\aestab.c - -!IF "$(CFG)" == "SFXWin - Win32 Release" - # SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "SFXWin - Win32 Debug" - -!ENDIF - # End Source File # Begin Source File @@ -457,11 +437,11 @@ SOURCE=..\..\Common\LimitedStreams.h # End Source File # Begin Source File -SOURCE=..\..\Common\MultiStream.cpp +SOURCE=..\..\Common\LockedStream.cpp # End Source File # Begin Source File -SOURCE=..\..\Common\MultiStream.h +SOURCE=..\..\Common\LockedStream.h # End Source File # Begin Source File @@ -641,6 +621,14 @@ SOURCE=..\..\..\Windows\Window.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\CommandLineParser.cpp # End Source File # Begin Source File @@ -704,6 +692,22 @@ SOURCE=..\..\..\Common\Wildcard.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\UI\Common\ArchiveExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveOpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveOpenCallback.h +# End Source File +# Begin Source File + SOURCE=..\..\UI\Common\ArchiverInfo.cpp # End Source File # Begin Source File @@ -720,6 +724,14 @@ SOURCE=..\..\UI\Common\DefaultName.h # End Source File # Begin Source File +SOURCE=..\..\UI\Common\Extract.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Extract.h +# End Source File +# Begin Source File + SOURCE=..\..\UI\Common\ExtractingFilePath.cpp # End Source File # Begin Source File @@ -740,19 +752,27 @@ SOURCE=..\..\UI\Common\OpenArchive.h # PROP Default_Filter "" # Begin Source File -SOURCE=..\..\UI\GUI\Extract.cpp +SOURCE=..\..\UI\GUI\ExtractDialog.cpp # End Source File # Begin Source File -SOURCE=..\..\UI\GUI\Extract.h +SOURCE=..\..\UI\GUI\ExtractDialog.h # End Source File # Begin Source File -SOURCE=..\..\UI\GUI\ExtractDialog.cpp +SOURCE=..\..\UI\GUI\ExtractGUI.cpp # End Source File # Begin Source File -SOURCE=..\..\UI\GUI\ExtractDialog.h +SOURCE=..\..\UI\GUI\ExtractGUI.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\GUI\OpenCallbackGUI.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\GUI\OpenCallbackGUI.h # End Source File # End Group # Begin Group "Explorer" diff --git a/7zip/Bundles/SFXWin/StdAfx.cpp b/7zip/Bundles/SFXWin/StdAfx.cpp index 2550270c..d0feea85 100755 --- a/7zip/Bundles/SFXWin/StdAfx.cpp +++ b/7zip/Bundles/SFXWin/StdAfx.cpp @@ -1,3 +1,3 @@ // StdAfx.cpp -#include "stdafx.h" +#include "StdAfx.h" diff --git a/7zip/Bundles/SFXWin/StdAfx.h b/7zip/Bundles/SFXWin/StdAfx.h index a6b81337..72988efa 100755 --- a/7zip/Bundles/SFXWin/StdAfx.h +++ b/7zip/Bundles/SFXWin/StdAfx.h @@ -1,14 +1,10 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> +#include "../../../Common/MyWindows.h" #include <commctrl.h> #include <ShlObj.h> -#include <tchar.h> -#include <limits.h> -// #include <vector> - -#endif +#endif diff --git a/7zip/Bundles/SFXWin/resource.h b/7zip/Bundles/SFXWin/resource.h index e6ff17a6..07c0e65a 100755 --- a/7zip/Bundles/SFXWin/resource.h +++ b/7zip/Bundles/SFXWin/resource.h @@ -7,9 +7,9 @@ #define IDI_ICON3 159 -#define IDC_EXTRACT_COMBO_PATH 1044 -#define IDC_EXTRACT_BUTTON_SET_PATH 1045 -#define IDC_STATIC_EXTRACT_EXTRACT_TO 1092 +#define IDC_STATIC_EXTRACT_EXTRACT_TO 1020 +#define IDC_EXTRACT_COMBO_PATH 1021 +#define IDC_EXTRACT_BUTTON_SET_PATH 1022 // Next default values for new objects // diff --git a/7zip/Bundles/SFXWin/resource.rc b/7zip/Bundles/SFXWin/resource.rc index cacc2257..f84d33d8 100755 --- a/7zip/Bundles/SFXWin/resource.rc +++ b/7zip/Bundles/SFXWin/resource.rc @@ -80,8 +80,8 @@ IDI_ICON3 ICON DISCARDABLE "7z.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,12,0,0 - PRODUCTVERSION 3,12,0,0 + FILEVERSION 4,20,0,0 + PRODUCTVERSION 4,20,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -99,14 +99,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Igor Pavlov\0" VALUE "FileDescription", "7z SFX\0" - VALUE "FileVersion", "3, 12, 0, 0\0" + VALUE "FileVersion", "4, 20, 0, 0\0" VALUE "InternalName", "7zWin.sfx\0" - VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "7zWin.sfx\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "7-Zip\0" - VALUE "ProductVersion", "3, 12, 0, 0\0" + VALUE "ProductVersion", "4, 20, 0, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/7zip/Common/FilePathAutoRename.cpp b/7zip/Common/FilePathAutoRename.cpp index ddeb7366..3283aa45 100755 --- a/7zip/Common/FilePathAutoRename.cpp +++ b/7zip/Common/FilePathAutoRename.cpp @@ -15,7 +15,7 @@ static bool MakeAutoName(const UString &name, const UString &extension, int value, UString &path) { wchar_t number[32]; - ConvertUINT64ToString(value, number); + ConvertUInt64ToString(value, number); path = name; path += number; path += extension; diff --git a/7zip/Common/FilePathAutoRename.h b/7zip/Common/FilePathAutoRename.h index 931c6566..99323094 100755 --- a/7zip/Common/FilePathAutoRename.h +++ b/7zip/Common/FilePathAutoRename.h @@ -1,7 +1,5 @@ // Util/FilePathAutoRename.h -#pragma once - #ifndef __FILEPATHAUTORENAME_H #define __FILEPATHAUTORENAME_H diff --git a/7zip/Common/FileStreams.cpp b/7zip/Common/FileStreams.cpp index 7a1f22b2..0051d3b3 100755 --- a/7zip/Common/FileStreams.cpp +++ b/7zip/Common/FileStreams.cpp @@ -1,12 +1,22 @@ // FileStreams.cpp #include "StdAfx.h" + +#ifndef _WIN32 +#include <fcntl.h> +#include <unistd.h> +#endif + #include "FileStreams.h" static inline HRESULT ConvertBoolToHRESULT(bool result) { // return result ? S_OK: E_FAIL; + #ifdef _WIN32 return result ? S_OK: (::GetLastError()); + #else + return result ? S_OK: E_FAIL; + #endif } bool CInFileStream::Open(LPCTSTR fileName) @@ -14,41 +24,104 @@ bool CInFileStream::Open(LPCTSTR fileName) return File.Open(fileName); } +#ifdef _WIN32 #ifndef _UNICODE bool CInFileStream::Open(LPCWSTR fileName) { return File.Open(fileName); } #endif +#endif -STDMETHODIMP CInFileStream::Read(void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) { - UINT32 realProcessedSize; + #ifdef _WIN32 + + UInt32 realProcessedSize; bool result = File.Read(data, size, realProcessedSize); if(processedSize != NULL) *processedSize = realProcessedSize; return ConvertBoolToHRESULT(result); + + #else + + if(processedSize != NULL) + *processedSize = 0; + ssize_t res = File.Read(data, (size_t)size); + if (res == -1) + return E_FAIL; + if(processedSize != NULL) + *processedSize = (UInt32)res; + return S_OK; + + #endif } -STDMETHODIMP CInFileStream::ReadPart(void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CInFileStream::ReadPart(void *data, UInt32 size, UInt32 *processedSize) { return Read(data, size, processedSize); } +#ifndef _WIN32_WCE +STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + #ifdef _WIN32 + UInt32 realProcessedSize; + BOOL res = ::ReadFile(GetStdHandle(STD_INPUT_HANDLE), + data, size, (DWORD *)&realProcessedSize, NULL); + if(processedSize != NULL) + *processedSize = realProcessedSize; + if (res == FALSE && GetLastError() == ERROR_BROKEN_PIPE) + return S_OK; + return ConvertBoolToHRESULT(res != FALSE); + + #else + + if(processedSize != NULL) + *processedSize = 0; + ssize_t res = read(0, data, (size_t)size); + if (res == -1) + return E_FAIL; + if(processedSize != NULL) + *processedSize = (UInt32)res; + return S_OK; + + #endif +} + +STDMETHODIMP CStdInFileStream::ReadPart(void *data, UInt32 size, UInt32 *processedSize) +{ + return Read(data, size, processedSize); +} +#endif -STDMETHODIMP CInFileStream::Seek(INT64 offset, UINT32 seekOrigin, - UINT64 *newPosition) +STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin, + UInt64 *newPosition) { if(seekOrigin >= 3) return STG_E_INVALIDFUNCTION; - UINT64 realNewPosition; + + #ifdef _WIN32 + + UInt64 realNewPosition; bool result = File.Seek(offset, seekOrigin, realNewPosition); if(newPosition != NULL) *newPosition = realNewPosition; return ConvertBoolToHRESULT(result); + + #else + + off_t res = File.Seek(offset, seekOrigin); + if (res == -1) + return E_FAIL; + if(newPosition != NULL) + *newPosition = (UInt64)res; + return S_OK; + + #endif } -STDMETHODIMP CInFileStream::GetSize(UINT64 *size) +STDMETHODIMP CInFileStream::GetSize(UInt64 *size) { return ConvertBoolToHRESULT(File.GetLength(*size)); } @@ -57,54 +130,132 @@ STDMETHODIMP CInFileStream::GetSize(UINT64 *size) ////////////////////////// // COutFileStream -bool COutFileStream::Open(LPCTSTR fileName) +bool COutFileStream::Create(LPCTSTR fileName, bool createAlways) { - File.SetOpenCreationDispositionCreateAlways(); - return File.Open(fileName); + return File.Create(fileName, createAlways); } +#ifdef _WIN32 #ifndef _UNICODE -bool COutFileStream::Open(LPCWSTR fileName) +bool COutFileStream::Create(LPCWSTR fileName, bool createAlways) { - File.SetOpenCreationDispositionCreateAlways(); - return File.Open(fileName); + return File.Create(fileName, createAlways); } #endif +#endif -STDMETHODIMP COutFileStream::Write(const void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize) { - UINT32 realProcessedSize; + #ifdef _WIN32 + + UInt32 realProcessedSize; bool result = File.Write(data, size, realProcessedSize); if(processedSize != NULL) *processedSize = realProcessedSize; return ConvertBoolToHRESULT(result); + + #else + + if(processedSize != NULL) + *processedSize = 0; + ssize_t res = File.Write(data, (size_t)size); + if (res == -1) + return E_FAIL; + if(processedSize != NULL) + *processedSize = (UInt32)res; + return S_OK; + + #endif } -STDMETHODIMP COutFileStream::WritePart(const void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP COutFileStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize) { return Write(data, size, processedSize); } -STDMETHODIMP COutFileStream::Seek(INT64 offset, UINT32 seekOrigin, - UINT64 *newPosition) +STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, + UInt64 *newPosition) { if(seekOrigin >= 3) return STG_E_INVALIDFUNCTION; - UINT64 realNewPosition; + #ifdef _WIN32 + + UInt64 realNewPosition; bool result = File.Seek(offset, seekOrigin, realNewPosition); if(newPosition != NULL) *newPosition = realNewPosition; return ConvertBoolToHRESULT(result); + + #else + + off_t res = File.Seek(offset, seekOrigin); + if (res == -1) + return E_FAIL; + if(newPosition != NULL) + *newPosition = (UInt64)res; + return S_OK; + + #endif } -STDMETHODIMP COutFileStream::SetSize(INT64 newSize) +STDMETHODIMP COutFileStream::SetSize(Int64 newSize) { - UINT64 currentPos; + #ifdef _WIN32 + UInt64 currentPos; if(!File.Seek(0, FILE_CURRENT, currentPos)) return E_FAIL; bool result = File.SetLength(newSize); - UINT64 currentPos2; + UInt64 currentPos2; result = result && File.Seek(currentPos, currentPos2); return result ? S_OK : E_FAIL; + #else + return E_FAIL; + #endif +} + +#ifndef _WIN32_WCE +STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + if(processedSize != NULL) + *processedSize = 0; + + #ifdef _WIN32 + UInt32 realProcessedSize; + BOOL res = TRUE; + while (size > 0) + { + // Seems that Windows doesn't like big amounts writing to stdout. + // So we limit portions by 32KB. + UInt32 sizeTemp = (1 << 15); + if (sizeTemp > size) + sizeTemp = size; + res = ::WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), + data, sizeTemp, (DWORD *)&realProcessedSize, NULL); + if (realProcessedSize == 0) + break; + size -= realProcessedSize; + data = (const void *)((const Byte *)data + realProcessedSize); + if(processedSize != NULL) + *processedSize += realProcessedSize; + } + return ConvertBoolToHRESULT(res != FALSE); + + #else + + ssize_t res = write(1, data, (size_t)size); + if (res == -1) + return E_FAIL; + if(processedSize != NULL) + *processedSize = (UInt32)res; + return S_OK; + + return S_OK; + #endif +} + +STDMETHODIMP CStdOutFileStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize) +{ + return Write(data, size, processedSize); } +#endif diff --git a/7zip/Common/FileStreams.h b/7zip/Common/FileStreams.h index f3295323..ea79e1b9 100755 --- a/7zip/Common/FileStreams.h +++ b/7zip/Common/FileStreams.h @@ -1,14 +1,16 @@ // FileStreams.h -#pragma once - #ifndef __FILESTREAMS_H #define __FILESTREAMS_H -#include "Windows/FileIO.h" +#ifdef _WIN32 +#include "../../Windows/FileIO.h" +#else +#include "../../Common/C_FileIO.h" +#endif #include "../IStream.h" -#include "Common/MyCom.h" +#include "../../Common/MyCom.h" class CInFileStream: public IInStream, @@ -16,40 +18,85 @@ class CInFileStream: public CMyUnknownImp { public: + #ifdef _WIN32 NWindows::NFile::NIO::CInFile File; + #else + NC::NFile::NIO::CInFile File; + #endif CInFileStream() {} + virtual ~CInFileStream() {} + bool Open(LPCTSTR fileName); + #ifdef _WIN32 #ifndef _UNICODE bool Open(LPCWSTR fileName); #endif + #endif + + MY_UNKNOWN_IMP2(IInStream, IStreamGetSize) - MY_UNKNOWN_IMP1(IStreamGetSize) + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize); - STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize); - STDMETHOD(Seek)(INT64 offset, UINT32 seekOrigin, UINT64 *newPosition); + STDMETHOD(GetSize)(UInt64 *size); +}; + +#ifndef _WIN32_WCE +class CStdInFileStream: + public ISequentialInStream, + public CMyUnknownImp +{ +public: + // HANDLE File; + // CStdInFileStream() File(INVALID_HANDLE_VALUE): {} + // void Open() { File = GetStdHandle(STD_INPUT_HANDLE); }; + MY_UNKNOWN_IMP - STDMETHOD(GetSize)(UINT64 *size); + virtual ~CStdInFileStream() {} + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); }; +#endif class COutFileStream: public IOutStream, public CMyUnknownImp { public: + #ifdef _WIN32 NWindows::NFile::NIO::COutFile File; - COutFileStream() {} - bool Open(LPCTSTR fileName); + #else + NC::NFile::NIO::COutFile File; + #endif + virtual ~COutFileStream() {} + bool Create(LPCTSTR fileName, bool createAlways); + #ifdef _WIN32 #ifndef _UNICODE - bool Open(LPCWSTR fileName); + bool Create(LPCWSTR fileName, bool createAlways); + #endif #endif + MY_UNKNOWN_IMP1(IOutStream) + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); + STDMETHOD(SetSize)(Int64 newSize); +}; + +#ifndef _WIN32_WCE +class CStdOutFileStream: + public ISequentialOutStream, + public CMyUnknownImp +{ +public: MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize); - STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize); - STDMETHOD(Seek)(INT64 offset, UINT32 seekOrigin, UINT64 *newPosition); - STDMETHOD(SetSize)(INT64 newSize); + virtual ~CStdOutFileStream() {} + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); }; +#endif #endif diff --git a/7zip/Common/InBuffer.cpp b/7zip/Common/InBuffer.cpp index 2d56e44d..8c05874b 100755 --- a/7zip/Common/InBuffer.cpp +++ b/7zip/Common/InBuffer.cpp @@ -1,41 +1,73 @@ // InBuffer.cpp -#include "stdafx.h" +#include "StdAfx.h" #include "InBuffer.h" -CInBuffer::CInBuffer(UINT32 bufferSize): - _bufferSize(bufferSize), - _bufferBase(0) +#include "../../Common/Alloc.h" + +CInBuffer::CInBuffer(): + _bufferBase(0), + _bufferSize(0), + _buffer(0), + _bufferLimit(0), + _stream(0) +{} + +bool CInBuffer::Create(UInt32 bufferSize) { - _bufferBase = new BYTE[_bufferSize]; + const UInt32 kMinBlockSize = 1; + if (bufferSize < kMinBlockSize) + bufferSize = kMinBlockSize; + if (_bufferBase != 0 && _bufferSize == bufferSize) + return true; + Free(); + _bufferSize = bufferSize; + _bufferBase = (Byte *)::BigAlloc(bufferSize); + return (_bufferBase != 0); } -CInBuffer::~CInBuffer() +void CInBuffer::Free() { - delete []_bufferBase; + BigFree(_bufferBase); + _bufferBase = 0; } -void CInBuffer::Init(ISequentialInStream *stream) +void CInBuffer::SetStream(ISequentialInStream *stream) { _stream = stream; +} + +void CInBuffer::Init() +{ _processedSize = 0; _buffer = _bufferBase; _bufferLimit = _buffer; - _streamWasExhausted = false; + _wasFinished = false; + #ifdef _NO_EXCEPTIONS + ErrorCode = S_OK; + #endif } bool CInBuffer::ReadBlock() { - if (_streamWasExhausted) + #ifdef _NO_EXCEPTIONS + if (ErrorCode != S_OK) + return false; + #endif + if (_wasFinished) return false; _processedSize += (_buffer - _bufferBase); - UINT32 numProcessedBytes; + UInt32 numProcessedBytes; HRESULT result = _stream->ReadPart(_bufferBase, _bufferSize, &numProcessedBytes); + #ifdef _NO_EXCEPTIONS + ErrorCode = result; + #else if (result != S_OK) throw CInBufferException(result); + #endif _buffer = _bufferBase; _bufferLimit = _buffer + numProcessedBytes; - _streamWasExhausted = (numProcessedBytes == 0); - return (!_streamWasExhausted); + _wasFinished = (numProcessedBytes == 0); + return (!_wasFinished); } diff --git a/7zip/Common/InBuffer.h b/7zip/Common/InBuffer.h index 604a6658..3d53eb51 100755 --- a/7zip/Common/InBuffer.h +++ b/7zip/Common/InBuffer.h @@ -1,39 +1,48 @@ // InBuffer.h -// #pragma once - #ifndef __INBUFFER_H #define __INBUFFER_H #include "../IStream.h" +#include "../../Common/MyCom.h" +#ifndef _NO_EXCEPTIONS class CInBufferException { public: HRESULT ErrorCode; CInBufferException(HRESULT errorCode): ErrorCode(errorCode) {} }; +#endif class CInBuffer { - UINT64 _processedSize; - BYTE *_bufferBase; - UINT32 _bufferSize; - BYTE *_buffer; - BYTE *_bufferLimit; - ISequentialInStream *_stream; - bool _streamWasExhausted; + UInt64 _processedSize; + Byte *_bufferBase; + UInt32 _bufferSize; + Byte *_buffer; + Byte *_bufferLimit; + CMyComPtr<ISequentialInStream> _stream; + bool _wasFinished; bool ReadBlock(); public: - CInBuffer(UINT32 bufferSize = 0x100000); - ~CInBuffer(); + #ifdef _NO_EXCEPTIONS + HRESULT ErrorCode; + #endif + + CInBuffer(); + ~CInBuffer() { Free(); } + + bool Create(UInt32 bufferSize); + void Free(); - void Init(ISequentialInStream *stream); - // void ReleaseStream() { _stream.Release(); } + void SetStream(ISequentialInStream *stream); + void Init(); + void ReleaseStream() { _stream.Release(); } - bool ReadByte(BYTE &b) + bool ReadByte(Byte &b) { if(_buffer >= _bufferLimit) if(!ReadBlock()) @@ -41,26 +50,27 @@ public: b = *_buffer++; return true; } - BYTE ReadByte() + Byte ReadByte() { if(_buffer >= _bufferLimit) if(!ReadBlock()) - return 0x0; + return 0xFF; return *_buffer++; } - void ReadBytes(void *data, UINT32 size, UINT32 &processedSize) + void ReadBytes(void *data, UInt32 size, UInt32 &processedSize) { for(processedSize = 0; processedSize < size; processedSize++) - if (!ReadByte(((BYTE *)data)[processedSize])) + if (!ReadByte(((Byte *)data)[processedSize])) return; } - bool ReadBytes(void *data, UINT32 size) + bool ReadBytes(void *data, UInt32 size) { - UINT32 processedSize; + UInt32 processedSize; ReadBytes(data, size, processedSize); return (processedSize == size); } - UINT64 GetProcessedSize() const { return _processedSize + (_buffer - _bufferBase); } + UInt64 GetProcessedSize() const { return _processedSize + (_buffer - _bufferBase); } + bool WasFinished() const { return _wasFinished; } }; #endif diff --git a/7zip/Common/InOutTempBuffer.cpp b/7zip/Common/InOutTempBuffer.cpp index cc956869..d7fb79d7 100755 --- a/7zip/Common/InOutTempBuffer.cpp +++ b/7zip/Common/InOutTempBuffer.cpp @@ -10,7 +10,7 @@ using namespace NWindows; using namespace NFile; using namespace NDirectory; -static UINT32 kTmpBufferMemorySize = (1 << 20); +static UInt32 kTmpBufferMemorySize = (1 << 20); static LPCTSTR kTempFilePrefixString = TEXT("iot"); @@ -21,7 +21,7 @@ CInOutTempBuffer::CInOutTempBuffer(): void CInOutTempBuffer::Create() { - _buffer = new BYTE[kTmpBufferMemorySize]; + _buffer = new Byte[kTmpBufferMemorySize]; } CInOutTempBuffer::~CInOutTempBuffer() @@ -35,7 +35,7 @@ void CInOutTempBuffer::InitWriting() _fileSize = 0; } -bool CInOutTempBuffer::WriteToFile(const void *data, UINT32 size) +bool CInOutTempBuffer::WriteToFile(const void *data, UInt32 size) { if (size == 0) return true; @@ -46,12 +46,12 @@ bool CInOutTempBuffer::WriteToFile(const void *data, UINT32 size) return false; if (_tempFile.Create(tempDirPath, kTempFilePrefixString, _tmpFileName) == 0) return false; - _outFile.SetOpenCreationDispositionCreateAlways(); - if(!_outFile.Open(_tmpFileName)) + // _outFile.SetOpenCreationDispositionCreateAlways(); + if(!_outFile.Create(_tmpFileName, true)) return false; _tmpFileCreated = true; } - UINT32 processedSize; + UInt32 processedSize; if(!_outFile.Write(data, size, processedSize)) return false; _fileSize += processedSize; @@ -63,16 +63,16 @@ bool CInOutTempBuffer::FlushWrite() return _outFile.Close(); } -bool CInOutTempBuffer::Write(const void *data, UINT32 size) +bool CInOutTempBuffer::Write(const void *data, UInt32 size) { - UINT32 numBytes = 0; + UInt32 numBytes = 0; if(_bufferPosition < kTmpBufferMemorySize) { - UINT32 curSize = MyMin(kTmpBufferMemorySize - _bufferPosition, size); - memmove(_buffer + _bufferPosition, (const BYTE *)data, curSize); + UInt32 curSize = MyMin(kTmpBufferMemorySize - _bufferPosition, size); + memmove(_buffer + _bufferPosition, (const Byte *)data, curSize); _bufferPosition += curSize; size -= curSize; - data = ((const BYTE *)data) + curSize; + data = ((const Byte *)data) + curSize; _fileSize += curSize; } return WriteToFile(data, size); @@ -87,21 +87,21 @@ bool CInOutTempBuffer::InitReading() } /* -bool CInOutTempBuffer::Read(void *data, UINT32 maxSize, UINT32 &processedSize) +bool CInOutTempBuffer::Read(void *data, UInt32 maxSize, UInt32 &processedSize) { processedSize = 0; if (_currentPositionInBuffer < _bufferPosition) { - UINT32 sizeToRead = MyMin(_bufferPosition - _currentPositionInBuffer, maxSize); + UInt32 sizeToRead = MyMin(_bufferPosition - _currentPositionInBuffer, maxSize); memmove(data, _buffer + _currentPositionInBuffer, sizeToRead); - data = ((BYTE *)data) + sizeToRead; + data = ((Byte *)data) + sizeToRead; _currentPositionInBuffer += sizeToRead; processedSize += sizeToRead; maxSize -= sizeToRead; } if (maxSize == 0 || !_tmpFileCreated) return true; - UINT32 localProcessedSize; + UInt32 localProcessedSize; bool result = _inFile.Read(data, maxSize, localProcessedSize); processedSize += localProcessedSize; return result; @@ -112,7 +112,7 @@ HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream) { if (_currentPositionInBuffer < _bufferPosition) { - UINT32 sizeToWrite = _bufferPosition - _currentPositionInBuffer; + UInt32 sizeToWrite = _bufferPosition - _currentPositionInBuffer; RINOK(stream->Write(_buffer + _currentPositionInBuffer, sizeToWrite, NULL)); _currentPositionInBuffer += sizeToWrite; } @@ -120,7 +120,7 @@ HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream) return true; while(true) { - UINT32 localProcessedSize; + UInt32 localProcessedSize; if (!_inFile.Read(_buffer, kTmpBufferMemorySize, localProcessedSize)) return E_FAIL; if (localProcessedSize == 0) @@ -129,7 +129,7 @@ HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream) } } -STDMETHODIMP CSequentialOutTempBufferImp::Write(const void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CSequentialOutTempBufferImp::Write(const void *data, UInt32 size, UInt32 *processedSize) { if (!_buffer->Write(data, size)) { @@ -142,7 +142,7 @@ STDMETHODIMP CSequentialOutTempBufferImp::Write(const void *data, UINT32 size, U return S_OK; } -STDMETHODIMP CSequentialOutTempBufferImp::WritePart(const void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CSequentialOutTempBufferImp::WritePart(const void *data, UInt32 size, UInt32 *processedSize) { return Write(data, size, processedSize); } diff --git a/7zip/Common/InOutTempBuffer.h b/7zip/Common/InOutTempBuffer.h index c1762b40..97ed56d0 100755 --- a/7zip/Common/InOutTempBuffer.h +++ b/7zip/Common/InOutTempBuffer.h @@ -1,9 +1,7 @@ // Util/InOutTempBuffer.h -#pragma once - -#ifndef __INOUTTEMPBUFFER_H -#define __INOUTTEMPBUFFER_H +#ifndef __IN_OUT_TEMP_BUFFER_H +#define __IN_OUT_TEMP_BUFFER_H #include "../../Windows/FileIO.h" #include "../../Windows/FileDir.h" @@ -16,26 +14,26 @@ class CInOutTempBuffer NWindows::NFile::NDirectory::CTempFile _tempFile; NWindows::NFile::NIO::COutFile _outFile; NWindows::NFile::NIO::CInFile _inFile; - BYTE *_buffer; - UINT32 _bufferPosition; - UINT32 _currentPositionInBuffer; + Byte *_buffer; + UInt32 _bufferPosition; + UInt32 _currentPositionInBuffer; CSysString _tmpFileName; bool _tmpFileCreated; - UINT64 _fileSize; + UInt64 _fileSize; - bool WriteToFile(const void *data, UINT32 size); + bool WriteToFile(const void *data, UInt32 size); public: CInOutTempBuffer(); ~CInOutTempBuffer(); void Create(); void InitWriting(); - bool Write(const void *data, UINT32 size); - UINT64 GetDataSize() const { return _fileSize; } + bool Write(const void *data, UInt32 size); + UInt64 GetDataSize() const { return _fileSize; } bool FlushWrite(); bool InitReading(); - // bool Read(void *data, UINT32 maxSize, UINT32 &processedSize); + // bool Read(void *data, UInt32 maxSize, UInt32 &processedSize); HRESULT WriteToStream(ISequentialOutStream *stream); }; @@ -46,14 +44,14 @@ class CSequentialOutTempBufferImp: CInOutTempBuffer *_buffer; public: // CSequentialOutStreamImp(): _size(0) {} - // UINT32 _size; + // UInt32 _size; void Init(CInOutTempBuffer *buffer) { _buffer = buffer; } - // UINT32 GetSize() const { return _size; } + // UInt32 GetSize() const { return _size; } MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize); - STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize); + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); }; #endif diff --git a/7zip/Common/LSBFDecoder.cpp b/7zip/Common/LSBFDecoder.cpp index 59df1acd..51e6aa9c 100755 --- a/7zip/Common/LSBFDecoder.cpp +++ b/7zip/Common/LSBFDecoder.cpp @@ -7,7 +7,7 @@ namespace NStream { namespace NLSBF { -BYTE kInvertTable[256]; +Byte kInvertTable[256]; class CInverterTableInitializer { @@ -16,8 +16,8 @@ public: { for(int i = 0; i < 256; i++) { - BYTE b = BYTE(i); - BYTE bInvert = 0; + Byte b = Byte(i); + Byte bInvert = 0; for(int j = 0; j < 8; j++) { bInvert <<= 1; diff --git a/7zip/Common/LSBFDecoder.h b/7zip/Common/LSBFDecoder.h index db6bf514..0fb31a3e 100755 --- a/7zip/Common/LSBFDecoder.h +++ b/7zip/Common/LSBFDecoder.h @@ -1,6 +1,4 @@ -// Stream/LSBFDecoder.h - -#pragma once +// LSBFDecoder.h #ifndef __STREAM_LSBFDECODER_H #define __STREAM_LSBFDECODER_H @@ -15,80 +13,113 @@ const int kNumBigValueBits = 8 * 4; const int kNumValueBytes = 3; const int kNumValueBits = 8 * kNumValueBytes; -const UINT32 kMask = (1 << kNumValueBits) - 1; +const UInt32 kMask = (1 << kNumValueBits) - 1; -extern BYTE kInvertTable[256]; +extern Byte kInvertTable[256]; // the Least Significant Bit of byte is First template<class TInByte> -class CDecoder +class CBaseDecoder { - UINT32 m_BitPos; - UINT32 m_Value; - UINT32 m_NormalValue; protected: + UInt32 m_BitPos; + UInt32 m_Value; TInByte m_Stream; public: - UINT32 NumExtraBytes; - void Init(ISequentialInStream *inStream) - { - m_Stream.Init(inStream); - Init(); - } + UInt32 NumExtraBytes; + bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); } + void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream); } + void ReleaseStream() { m_Stream.ReleaseStream(); } void Init() { + m_Stream.Init(); m_BitPos = kNumBigValueBits; - m_NormalValue = 0; + m_Value = 0; NumExtraBytes = 0; } - /* - void ReleaseStream() - { - m_Stream.ReleaseStream(); - } - */ - UINT64 GetProcessedSize() const + UInt64 GetProcessedSize() const { return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; } - UINT64 GetProcessedBitsSize() const + UInt64 GetProcessedBitsSize() const { return (m_Stream.GetProcessedSize() << 3) - (kNumBigValueBits - m_BitPos); } + UInt32 GetBitPosition() const { return (m_BitPos & 7); } void Normalize() { for (;m_BitPos >= 8; m_BitPos -= 8) { - BYTE b; + Byte b; if (!m_Stream.ReadByte(b)) + { + b = 0xFF; // check it NumExtraBytes++; - m_NormalValue = (b << (kNumBigValueBits - m_BitPos)) | m_NormalValue; - m_Value = (m_Value << 8) | kInvertTable[b]; + } + m_Value = (b << (kNumBigValueBits - m_BitPos)) | m_Value; } } - UINT32 GetValue(UINT32 numBits) + UInt32 ReadBits(UInt32 numBits) { Normalize(); - return ((m_Value >> (8 - m_BitPos)) & kMask) >> (kNumValueBits - numBits); + UInt32 res = m_Value & ((1 << numBits) - 1); + m_BitPos += numBits; + m_Value >>= numBits; + return res; + } + + bool ExtraBitsWereRead() const + { + if (NumExtraBytes == 0) + return false; + return ((kNumBigValueBits - m_BitPos) < (NumExtraBytes << 3)); } +}; - void MovePos(UINT32 numBits) +template<class TInByte> +class CDecoder: public CBaseDecoder<TInByte> +{ + UInt32 m_NormalValue; + +public: + void Init() { - m_BitPos += numBits; - m_NormalValue >>= numBits; + CBaseDecoder<TInByte>::Init(); + m_NormalValue = 0; + } + + void Normalize() + { + for (;this->m_BitPos >= 8; this->m_BitPos -= 8) + { + Byte b; + if (!this->m_Stream.ReadByte(b)) + { + b = 0xFF; // check it + this->NumExtraBytes++; + } + m_NormalValue = (b << (kNumBigValueBits - this->m_BitPos)) | m_NormalValue; + this->m_Value = (this->m_Value << 8) | kInvertTable[b]; + } } - UINT32 ReadBits(UINT32 numBits) + UInt32 GetValue(UInt32 numBits) { Normalize(); - UINT32 res = m_NormalValue & ( (1 << numBits) - 1); - MovePos(numBits); - return res; + return ((this->m_Value >> (8 - this->m_BitPos)) & kMask) >> (kNumValueBits - numBits); } - - UINT32 GetBitPosition() const + + void MovePos(UInt32 numBits) { - return (m_BitPos & 7); + this->m_BitPos += numBits; + m_NormalValue >>= numBits; } + UInt32 ReadBits(UInt32 numBits) + { + Normalize(); + UInt32 res = m_NormalValue & ( (1 << numBits) - 1); + MovePos(numBits); + return res; + } }; }} diff --git a/7zip/Common/LSBFEncoder.cpp b/7zip/Common/LSBFEncoder.cpp index 5c0f9a18..12a136bb 100755 --- a/7zip/Common/LSBFEncoder.cpp +++ b/7zip/Common/LSBFEncoder.cpp @@ -8,18 +8,18 @@ namespace NStream { namespace NLSBF { -void CEncoder::WriteBits(UINT32 aValue, UINT32 aNumBits) +void CEncoder::WriteBits(UInt32 value, UInt32 numBits) { - while(aNumBits > 0) + while(numBits > 0) { - UINT32 aNumNewBits = MyMin(aNumBits, m_BitPos); - aNumBits -= aNumNewBits; + UInt32 numNewBits = MyMin(numBits, m_BitPos); + numBits -= numNewBits; - UINT32 aMask = (1 << aNumNewBits) - 1; - m_CurByte |= (aValue & aMask) << (8 - m_BitPos); - aValue >>= aNumNewBits; + UInt32 mask = (1 << numNewBits) - 1; + m_CurByte |= (value & mask) << (8 - m_BitPos); + value >>= numNewBits; - m_BitPos -= aNumNewBits; + m_BitPos -= numNewBits; if (m_BitPos == 0) { @@ -31,16 +31,16 @@ void CEncoder::WriteBits(UINT32 aValue, UINT32 aNumBits) } -void CReverseEncoder::WriteBits(UINT32 aValue, UINT32 aNumBits) +void CReverseEncoder::WriteBits(UInt32 value, UInt32 numBits) { - UINT32 aReverseValue = 0; - for(UINT32 i = 0; i < aNumBits; i++) + UInt32 reverseValue = 0; + for(UInt32 i = 0; i < numBits; i++) { - aReverseValue <<= 1; - aReverseValue |= aValue & 1; - aValue >>= 1; + reverseValue <<= 1; + reverseValue |= value & 1; + value >>= 1; } - m_Encoder->WriteBits(aReverseValue, aNumBits); + m_Encoder->WriteBits(reverseValue, numBits); } }} diff --git a/7zip/Common/LSBFEncoder.h b/7zip/Common/LSBFEncoder.h index f9786dcb..77d2c696 100755 --- a/7zip/Common/LSBFEncoder.h +++ b/7zip/Common/LSBFEncoder.h @@ -1,7 +1,5 @@ // Stream/LSBFEncoder.h -#pragma once - #ifndef __STREAM_LSBFENCODER_H #define __STREAM_LSBFENCODER_H @@ -14,12 +12,15 @@ namespace NLSBF { class CEncoder { COutBuffer m_Stream; - UINT32 m_BitPos; - BYTE m_CurByte; + UInt32 m_BitPos; + Byte m_CurByte; public: - void Init(ISequentialOutStream *aStream) + bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); } + void SetStream(ISequentialOutStream *outStream) { m_Stream.SetStream(outStream); } + void ReleaseStream() { m_Stream.ReleaseStream(); } + void Init() { - m_Stream.Init(aStream); + m_Stream.Init(); m_BitPos = 8; m_CurByte = 0; } @@ -29,19 +30,9 @@ public: WriteBits(0, m_BitPos); return m_Stream.Flush(); } - /* - void ReleaseStream() - { - m_Stream.ReleaseStream(); - } - */ - - void WriteBits(UINT32 aValue, UINT32 aNumBits); - - UINT32 GetBitPosition() const - { return (8 - m_BitPos); } - - UINT64 GetProcessedSize() const { + void WriteBits(UInt32 value, UInt32 numBits); + UInt32 GetBitPosition() const { return (8 - m_BitPos); } + UInt64 GetProcessedSize() const { return m_Stream.GetProcessedSize() + (8 - m_BitPos + 7) /8; } }; @@ -49,9 +40,8 @@ class CReverseEncoder { CEncoder *m_Encoder; public: - void Init(CEncoder *anEncoder) - { m_Encoder = anEncoder; } - void WriteBits(UINT32 aValue, UINT32 aNumBits); + void Init(CEncoder *encoder) { m_Encoder = encoder; } + void WriteBits(UInt32 value, UInt32 numBits); }; }} diff --git a/7zip/Common/LimitedStreams.cpp b/7zip/Common/LimitedStreams.cpp index 49e8554c..6de13c05 100755 --- a/7zip/Common/LimitedStreams.cpp +++ b/7zip/Common/LimitedStreams.cpp @@ -5,17 +5,17 @@ #include "LimitedStreams.h" #include "../../Common/Defs.h" -void CLimitedSequentialInStream::Init(ISequentialInStream *stream, UINT64 streamSize) +void CLimitedSequentialInStream::Init(ISequentialInStream *stream, UInt64 streamSize) { _stream = stream; _size = streamSize; } STDMETHODIMP CLimitedSequentialInStream::Read(void *data, - UINT32 size, UINT32 *processedSize) + UInt32 size, UInt32 *processedSize) { - UINT32 processedSizeReal; - UINT32 sizeToRead = UINT32(MyMin(_size, UINT64(size))); + UInt32 processedSizeReal; + UInt32 sizeToRead = UInt32(MyMin(_size, UInt64(size))); HRESULT result = _stream->Read(data, sizeToRead, &processedSizeReal); _size -= processedSizeReal; if(processedSize != NULL) @@ -23,10 +23,10 @@ STDMETHODIMP CLimitedSequentialInStream::Read(void *data, return result; } -STDMETHODIMP CLimitedSequentialInStream::ReadPart(void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CLimitedSequentialInStream::ReadPart(void *data, UInt32 size, UInt32 *processedSize) { - UINT32 processedSizeReal; - UINT32 sizeToRead = UINT32(MyMin(_size, UINT64(size))); + UInt32 processedSizeReal; + UInt32 sizeToRead = UInt32(MyMin(_size, UInt64(size))); HRESULT result = _stream->ReadPart(data, sizeToRead, &processedSizeReal); _size -= processedSizeReal; if(processedSize != NULL) diff --git a/7zip/Common/LimitedStreams.h b/7zip/Common/LimitedStreams.h index b5c9be55..02633bc6 100755 --- a/7zip/Common/LimitedStreams.h +++ b/7zip/Common/LimitedStreams.h @@ -1,7 +1,5 @@ // LimitedStreams.h -#pragma once - #ifndef __LIMITEDSTREAMS_H #define __LIMITEDSTREAMS_H @@ -12,15 +10,15 @@ class CLimitedSequentialInStream: public ISequentialInStream, public CMyUnknownImp { - UINT64 _size; + UInt64 _size; CMyComPtr<ISequentialInStream> _stream; public: - void Init(ISequentialInStream *stream, UINT64 streamSize); + void Init(ISequentialInStream *stream, UInt64 streamSize); MY_UNKNOWN_IMP - STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize); - STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize); + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); }; #endif diff --git a/7zip/Common/MultiStream.cpp b/7zip/Common/LockedStream.cpp index d1141b09..44af676d 100755 --- a/7zip/Common/MultiStream.cpp +++ b/7zip/Common/LockedStream.cpp @@ -1,19 +1,19 @@ -// MultiStream.cpp +// LockedStream.cpp #include "StdAfx.h" -#include "MultiStream.h" +#include "LockedStream.h" -HRESULT CLockedInStream::Read(UINT64 startPos, void *data, UINT32 size, - UINT32 *processedSize) +HRESULT CLockedInStream::Read(UInt64 startPos, void *data, UInt32 size, + UInt32 *processedSize) { NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); RINOK(_stream->Seek(startPos, STREAM_SEEK_SET, NULL)); return _stream->Read(data, size, processedSize); } -HRESULT CLockedInStream::ReadPart(UINT64 startPos, void *data, UINT32 size, - UINT32 *processedSize) +HRESULT CLockedInStream::ReadPart(UInt64 startPos, void *data, UInt32 size, + UInt32 *processedSize) { NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); RINOK(_stream->Seek(startPos, STREAM_SEEK_SET, NULL)); @@ -21,9 +21,9 @@ HRESULT CLockedInStream::ReadPart(UINT64 startPos, void *data, UINT32 size, } -STDMETHODIMP CLockedSequentialInStreamImp::Read(void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CLockedSequentialInStreamImp::Read(void *data, UInt32 size, UInt32 *processedSize) { - UINT32 realProcessedSize = 0; + UInt32 realProcessedSize = 0; HRESULT result = _lockedInStream->Read(_pos, data, size, &realProcessedSize); _pos += realProcessedSize; if (processedSize != NULL) @@ -31,9 +31,9 @@ STDMETHODIMP CLockedSequentialInStreamImp::Read(void *data, UINT32 size, UINT32 return result; } -STDMETHODIMP CLockedSequentialInStreamImp::ReadPart(void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CLockedSequentialInStreamImp::ReadPart(void *data, UInt32 size, UInt32 *processedSize) { - UINT32 realProcessedSize = 0; + UInt32 realProcessedSize = 0; HRESULT result = _lockedInStream->ReadPart(_pos, data, size, &realProcessedSize); _pos += realProcessedSize; if (processedSize != NULL) diff --git a/7zip/Common/MultiStream.h b/7zip/Common/LockedStream.h index 6736a51d..90f28330 100755 --- a/7zip/Common/MultiStream.h +++ b/7zip/Common/LockedStream.h @@ -1,9 +1,7 @@ -// MultiStream.h +// LockedStream.h -#pragma once - -#ifndef __MULTISTREAM_H -#define __MULTISTREAM_H +#ifndef __LOCKEDSTREAM_H +#define __LOCKEDSTREAM_H #include "../../Windows/Synchronization.h" #include "../../Common/MyCom.h" @@ -16,8 +14,8 @@ class CLockedInStream public: void Init(IInStream *stream) { _stream = stream; } - HRESULT Read(UINT64 startPos, void *data, UINT32 size, UINT32 *processedSize); - HRESULT ReadPart(UINT64 startPos, void *data, UINT32 size, UINT32 *processedSize); + HRESULT Read(UInt64 startPos, void *data, UInt32 size, UInt32 *processedSize); + HRESULT ReadPart(UInt64 startPos, void *data, UInt32 size, UInt32 *processedSize); }; class CLockedSequentialInStreamImp: @@ -25,9 +23,9 @@ class CLockedSequentialInStreamImp: public CMyUnknownImp { CLockedInStream *_lockedInStream; - UINT64 _pos; + UInt64 _pos; public: - void Init(CLockedInStream *lockedInStream, UINT64 startPos) + void Init(CLockedInStream *lockedInStream, UInt64 startPos) { _lockedInStream = lockedInStream; _pos = startPos; @@ -35,8 +33,8 @@ public: MY_UNKNOWN_IMP - STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize); - STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize); + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); }; #endif diff --git a/7zip/Common/MSBFDecoder.h b/7zip/Common/MSBFDecoder.h index 53accff6..c21d5547 100755 --- a/7zip/Common/MSBFDecoder.h +++ b/7zip/Common/MSBFDecoder.h @@ -1,8 +1,6 @@ -// Stream/MSBFDecoder.h +// MSBFDecoder.h // the Most Significant Bit of byte is First -#pragma once - #ifndef __STREAM_MSBFDECODER_H #define __STREAM_MSBFDECODER_H @@ -10,37 +8,32 @@ namespace NStream { namespace NMSBF { const int kNumBigValueBits = 8 * 4; - const int kNumValueBytes = 3; const int kNumValueBits = 8 * kNumValueBytes; -const UINT32 kMask = (1 << kNumValueBits) - 1; +const UInt32 kMask = (1 << kNumValueBits) - 1; template<class TInByte> class CDecoder { TInByte m_Stream; - UINT32 m_BitPos; - UINT32 m_Value; - + UInt32 m_BitPos; + UInt32 m_Value; public: - - void Init(ISequentialInStream *aStream) + bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); } + void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream);} + void ReleaseStream() { m_Stream.ReleaseStream();} + + void Init() { - m_Stream.Init(aStream); + m_Stream.Init(); m_BitPos = kNumBigValueBits; Normalize(); } - /* - void ReleaseStream() - { - m_Stream.ReleaseStream(); - } - */ - - UINT64 GetProcessedSize() const + UInt64 GetProcessedSize() const { return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; } + UInt32 GetBitPosition() const { return (m_BitPos & 7); } void Normalize() { @@ -48,23 +41,23 @@ public: m_Value = (m_Value << 8) | m_Stream.ReadByte(); } - UINT32 GetValue(UINT32 aNumBits) const + UInt32 GetValue(UInt32 numBits) const { - // return (m_Value << m_BitPos) >> (kNumBigValueBits - aNumBits); - return ((m_Value >> (8 - m_BitPos)) & kMask) >> (kNumValueBits - aNumBits); + // return (m_Value << m_BitPos) >> (kNumBigValueBits - numBits); + return ((m_Value >> (8 - m_BitPos)) & kMask) >> (kNumValueBits - numBits); } - void MovePos(UINT32 aNumBits) + void MovePos(UInt32 numBits) { - m_BitPos += aNumBits; + m_BitPos += numBits; Normalize(); } - UINT32 ReadBits(UINT32 aNumBits) + UInt32 ReadBits(UInt32 numBits) { - UINT32 aRes = GetValue(aNumBits); - MovePos(aNumBits); - return aRes; + UInt32 res = GetValue(numBits); + MovePos(numBits); + return res; } }; diff --git a/7zip/Common/MSBFEncoder.h b/7zip/Common/MSBFEncoder.h index b87bdea3..150988c2 100755 --- a/7zip/Common/MSBFEncoder.h +++ b/7zip/Common/MSBFEncoder.h @@ -1,13 +1,11 @@ // Stream/MSBFEncoder.h -// the Most Significant Bit of byte is First - -#pragma once #ifndef __STREAM_MSBFENCODER_H #define __STREAM_MSBFENCODER_H #include "Common/Defs.h" -#include "Interface/IInOutStreams.h" +#include "../IStream.h" +#include "OutBuffer.h" namespace NStream { namespace NMSBF { @@ -16,12 +14,15 @@ template<class TOutByte> class CEncoder { TOutByte m_Stream; - UINT32 m_BitPos; - BYTE m_CurByte; + int m_BitPos; + Byte m_CurByte; public: - void Init(ISequentialOutStream *aStream) + bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); } + void SetStream(ISequentialOutStream *outStream) { m_Stream.SetStream(outStream);} + void ReleaseStream() { m_Stream.ReleaseStream(); } + void Init() { - m_Stream.Init(aStream); + m_Stream.Init(); m_BitPos = 8; m_CurByte = 0; } @@ -32,26 +33,19 @@ public: return m_Stream.Flush(); } - void ReleaseStream() - { - m_Stream.ReleaseStream(); - } - - void WriteBits(UINT32 aValue, UINT32 aNumBits) + void WriteBits(UInt32 value, int numBits) { - while(aNumBits > 0) + while(numBits > 0) { - UINT32 aNumNewBits = MyMin(aNumBits, m_BitPos); - aNumBits -= aNumNewBits; + int numNewBits = MyMin(numBits, m_BitPos); + numBits -= numNewBits; + m_CurByte <<= numNewBits; + UInt32 newBits = value >> numBits; + m_CurByte |= Byte(newBits); + value -= (newBits << numBits); - m_CurByte <<= aNumNewBits; - UINT32 aNewBits = aValue >> aNumBits; - m_CurByte |= BYTE(aNewBits); - aValue -= (aNewBits << aNumBits); - - - m_BitPos -= aNumNewBits; + m_BitPos -= numNewBits; if (m_BitPos == 0) { @@ -60,11 +54,10 @@ public: } } } - UINT64 GetProcessedSize() const { - return m_Stream.GetProcessedSize() + (8 - m_BitPos + 7) /8; } + UInt64 GetProcessedSize() const { + return m_Stream.GetProcessedSize() + (8 - m_BitPos + 7) / 8; } }; }} #endif - diff --git a/7zip/Common/OffsetStream.cpp b/7zip/Common/OffsetStream.cpp index 81347e4f..cc93c0db 100755 --- a/7zip/Common/OffsetStream.cpp +++ b/7zip/Common/OffsetStream.cpp @@ -5,28 +5,28 @@ #include "Common/Defs.h" #include "OffsetStream.h" -HRESULT COffsetOutStream::Init(IOutStream *stream, UINT64 offset) +HRESULT COffsetOutStream::Init(IOutStream *stream, UInt64 offset) { _offset = offset; _stream = stream; return _stream->Seek(offset, STREAM_SEEK_SET, NULL); } -STDMETHODIMP COffsetOutStream::Write(const void *data, UINT32 size, - UINT32 *processedSize) +STDMETHODIMP COffsetOutStream::Write(const void *data, UInt32 size, + UInt32 *processedSize) { return _stream->Write(data, size, processedSize); } -STDMETHODIMP COffsetOutStream::WritePart(const void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP COffsetOutStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize) { return _stream->WritePart(data, size, processedSize); } -STDMETHODIMP COffsetOutStream::Seek(INT64 offset, UINT32 seekOrigin, - UINT64 *newPosition) +STDMETHODIMP COffsetOutStream::Seek(Int64 offset, UInt32 seekOrigin, + UInt64 *newPosition) { - UINT64 absoluteNewPosition; + UInt64 absoluteNewPosition; if (seekOrigin == STREAM_SEEK_SET) offset += _offset; HRESULT result = _stream->Seek(offset, seekOrigin, &absoluteNewPosition); @@ -35,7 +35,7 @@ STDMETHODIMP COffsetOutStream::Seek(INT64 offset, UINT32 seekOrigin, return result; } -STDMETHODIMP COffsetOutStream::SetSize(INT64 newSize) +STDMETHODIMP COffsetOutStream::SetSize(Int64 newSize) { return _stream->SetSize(_offset + newSize); } diff --git a/7zip/Common/OffsetStream.h b/7zip/Common/OffsetStream.h index d98277c2..20c65452 100755 --- a/7zip/Common/OffsetStream.h +++ b/7zip/Common/OffsetStream.h @@ -1,7 +1,5 @@ // OffsetStream.h -#pragma once - #ifndef __OFFSETSTREAM_H #define __OFFSETSTREAM_H @@ -12,17 +10,17 @@ class COffsetOutStream: public IOutStream, public CMyUnknownImp { - UINT64 _offset; + UInt64 _offset; CMyComPtr<IOutStream> _stream; public: - HRESULT Init(IOutStream *stream, UINT64 offset); + HRESULT Init(IOutStream *stream, UInt64 offset); MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize); - STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize); - STDMETHOD(Seek)(INT64 offset, UINT32 seekOrigin, UINT64 *newPosition); - STDMETHOD(SetSize)(INT64 newSize); + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); + STDMETHOD(SetSize)(Int64 newSize); }; #endif diff --git a/7zip/Common/OutBuffer.cpp b/7zip/Common/OutBuffer.cpp index a5fc005d..ab4651b4 100755 --- a/7zip/Common/OutBuffer.cpp +++ b/7zip/Common/OutBuffer.cpp @@ -1,40 +1,49 @@ -// Stream/OutByte.cpp +// OutByte.cpp #include "StdAfx.h" #include "OutBuffer.h" -COutBuffer::COutBuffer(UINT32 bufferSize): - _bufferSize(bufferSize) +#include "../../Common/Alloc.h" + +bool COutBuffer::Create(UInt32 bufferSize) { - _buffer = new BYTE[_bufferSize]; + const UInt32 kMinBlockSize = 1; + if (bufferSize < kMinBlockSize) + bufferSize = kMinBlockSize; + if (_buffer != 0 && _bufferSize == bufferSize) + return true; + Free(); + _bufferSize = bufferSize; + _buffer = (Byte *)::BigAlloc(bufferSize); + return (_buffer != 0); } -COutBuffer::~COutBuffer() +void COutBuffer::Free() { - delete []_buffer; + BigFree(_buffer); + _buffer = 0; } -void COutBuffer::Init(ISequentialOutStream *stream) +void COutBuffer::SetStream(ISequentialOutStream *stream) { _stream = stream; - _processedSize = 0; - _pos = 0; } -/* -void COutBuffer::ReleaseStream() +void COutBuffer::Init() { - _stream.Release(); + _processedSize = 0; + _pos = 0; + #ifdef _NO_EXCEPTIONS + ErrorCode = S_OK; + #endif } -*/ - HRESULT COutBuffer::Flush() { if (_pos == 0) return S_OK; - UINT32 processedSize; + UInt32 processedSize; HRESULT result = _stream->Write(_buffer, _pos, &processedSize); if (result != S_OK) return result; @@ -47,7 +56,15 @@ HRESULT COutBuffer::Flush() void COutBuffer::WriteBlock() { + #ifdef _NO_EXCEPTIONS + if (ErrorCode != S_OK) + return; + #endif HRESULT result = Flush(); + #ifdef _NO_EXCEPTIONS + ErrorCode = result; + #else if (result != S_OK) throw COutBufferException(result); + #endif } diff --git a/7zip/Common/OutBuffer.h b/7zip/Common/OutBuffer.h index 777c5538..436e1323 100755 --- a/7zip/Common/OutBuffer.h +++ b/7zip/Common/OutBuffer.h @@ -1,62 +1,71 @@ // OutBuffer.h -// #pragma once - #ifndef __OUTBUFFER_H #define __OUTBUFFER_H #include "../IStream.h" +#include "../../Common/MyCom.h" -class COutBufferException +#ifndef _NO_EXCEPTIONS +struct COutBufferException { -public: HRESULT ErrorCode; COutBufferException(HRESULT errorCode): ErrorCode(errorCode) {} }; +#endif class COutBuffer { - BYTE *_buffer; - UINT32 _pos; - UINT32 _bufferSize; - ISequentialOutStream *_stream; - UINT64 _processedSize; + Byte *_buffer; + UInt32 _pos; + UInt32 _bufferSize; + CMyComPtr<ISequentialOutStream> _stream; + UInt64 _processedSize; void WriteBlock(); public: - COutBuffer(UINT32 bufferSize = (1 << 20)); - ~COutBuffer(); + #ifdef _NO_EXCEPTIONS + HRESULT ErrorCode; + #endif + + COutBuffer(): _buffer(0), _pos(0), _stream(0) {} + ~COutBuffer() { Free(); } + + bool Create(UInt32 bufferSize); + void Free(); - void Init(ISequentialOutStream *stream); + void SetStream(ISequentialOutStream *stream); + void Init(); HRESULT Flush(); - // void ReleaseStream(); + void ReleaseStream() { _stream.Release(); } - void *GetBuffer(UINT32 &sizeAvail) + /* + void *GetBuffer(UInt32 &sizeAvail) { sizeAvail = _bufferSize - _pos; return _buffer + _pos; } - void MovePos(UINT32 num) + void MovePos(UInt32 num) { _pos += num; if(_pos >= _bufferSize) WriteBlock(); } + */ - - void WriteByte(BYTE b) + void WriteByte(Byte b) { _buffer[_pos++] = b; if(_pos >= _bufferSize) WriteBlock(); } - void WriteBytes(const void *data, UINT32 size) + void WriteBytes(const void *data, UInt32 size) { - for (UINT32 i = 0; i < size; i++) - WriteByte(((const BYTE *)data)[i]); + for (UInt32 i = 0; i < size; i++) + WriteByte(((const Byte *)data)[i]); } - UINT64 GetProcessedSize() const { return _processedSize + _pos; } + UInt64 GetProcessedSize() const { return _processedSize + _pos; } }; #endif diff --git a/7zip/Common/ProgressUtils.cpp b/7zip/Common/ProgressUtils.cpp index 7e337263..382e7980 100755 --- a/7zip/Common/ProgressUtils.cpp +++ b/7zip/Common/ProgressUtils.cpp @@ -5,7 +5,7 @@ #include "ProgressUtils.h" void CLocalCompressProgressInfo::Init(ICompressProgressInfo *progress, - const UINT64 *inStartValue, const UINT64 *outStartValue) + const UInt64 *inStartValue, const UInt64 *outStartValue) { _progress = progress; _inStartValueIsAssigned = (inStartValue != NULL); @@ -17,11 +17,11 @@ void CLocalCompressProgressInfo::Init(ICompressProgressInfo *progress, } STDMETHODIMP CLocalCompressProgressInfo::SetRatioInfo( - const UINT64 *inSize, const UINT64 *outSize) + const UInt64 *inSize, const UInt64 *outSize) { - UINT64 inSizeNew, outSizeNew; - const UINT64 *inSizeNewPointer; - const UINT64 *outSizeNewPointer; + UInt64 inSizeNew, outSizeNew; + const UInt64 *inSizeNewPointer; + const UInt64 *outSizeNewPointer; if (_inStartValueIsAssigned && inSize != NULL) { inSizeNew = _inStartValue + (*inSize); @@ -51,7 +51,7 @@ void CLocalProgress::Init(IProgress *progress, bool inSizeIsMain) } STDMETHODIMP CLocalProgress::SetRatioInfo( - const UINT64 *inSize, const UINT64 *outSize) + const UInt64 *inSize, const UInt64 *outSize) { return _progress->SetCompleted(_inSizeIsMain ? inSize : outSize); } diff --git a/7zip/Common/ProgressUtils.h b/7zip/Common/ProgressUtils.h index d634d685..f89839fa 100755 --- a/7zip/Common/ProgressUtils.h +++ b/7zip/Common/ProgressUtils.h @@ -1,7 +1,5 @@ // ProgressUtils.h -// #pragma once - #ifndef __PROGRESSUTILS_H #define __PROGRESSUTILS_H @@ -17,21 +15,17 @@ class CLocalCompressProgressInfo: CMyComPtr<ICompressProgressInfo> _progress; bool _inStartValueIsAssigned; bool _outStartValueIsAssigned; - UINT64 _inStartValue; - UINT64 _outStartValue; + UInt64 _inStartValue; + UInt64 _outStartValue; public: void Init(ICompressProgressInfo *progress, - const UINT64 *inStartValue, const UINT64 *outStartValue); + const UInt64 *inStartValue, const UInt64 *outStartValue); MY_UNKNOWN_IMP - STDMETHOD(SetRatioInfo)(const UINT64 *inSize, const UINT64 *outSize); + STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); }; - -/////////////////////////////////////////// -// CLocalProgress - class CLocalProgress: public ICompressProgressInfo, public CMyUnknownImp @@ -43,8 +37,7 @@ public: MY_UNKNOWN_IMP - STDMETHOD(SetRatioInfo)(const UINT64 *inSize, const UINT64 *outSize); + STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); }; - #endif diff --git a/7zip/Common/StdAfx.h b/7zip/Common/StdAfx.h index a32fbed6..2736abc0 100755 --- a/7zip/Common/StdAfx.h +++ b/7zip/Common/StdAfx.h @@ -1,8 +1,8 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> +#include "../../Common/MyWindows.h" #endif diff --git a/7zip/Common/StreamBinder.cpp b/7zip/Common/StreamBinder.cpp index f4050ff1..fb4ca59f 100755 --- a/7zip/Common/StreamBinder.cpp +++ b/7zip/Common/StreamBinder.cpp @@ -16,8 +16,8 @@ class CSequentialInStreamForBinder: public: MY_UNKNOWN_IMP - STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize); - STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize); + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); private: CStreamBinder *m_StreamBinder; public: @@ -25,10 +25,10 @@ public: void SetBinder(CStreamBinder *streamBinder) { m_StreamBinder = streamBinder; } }; -STDMETHODIMP CSequentialInStreamForBinder::Read(void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CSequentialInStreamForBinder::Read(void *data, UInt32 size, UInt32 *processedSize) { return m_StreamBinder->Read(data, size, processedSize); } -STDMETHODIMP CSequentialInStreamForBinder::ReadPart(void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CSequentialInStreamForBinder::ReadPart(void *data, UInt32 size, UInt32 *processedSize) { return m_StreamBinder->ReadPart(data, size, processedSize); } class CSequentialOutStreamForBinder: @@ -38,8 +38,8 @@ class CSequentialOutStreamForBinder: public: MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize); - STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize); + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); private: CStreamBinder *m_StreamBinder; @@ -48,10 +48,10 @@ public: void SetBinder(CStreamBinder *streamBinder) { m_StreamBinder = streamBinder; } }; -STDMETHODIMP CSequentialOutStreamForBinder::Write(const void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CSequentialOutStreamForBinder::Write(const void *data, UInt32 size, UInt32 *processedSize) { return m_StreamBinder->Write(data, size, processedSize); } -STDMETHODIMP CSequentialOutStreamForBinder::WritePart(const void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CSequentialOutStreamForBinder::WritePart(const void *data, UInt32 size, UInt32 *processedSize) { return m_StreamBinder->WritePart(data, size, processedSize); } @@ -106,9 +106,9 @@ void CStreamBinder::CreateStreams(ISequentialInStream **inStream, ProcessedSize = 0; } -STDMETHODIMP CStreamBinder::ReadPart(void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CStreamBinder::ReadPart(void *data, UInt32 size, UInt32 *processedSize) { - UINT32 sizeToRead = size; + UInt32 sizeToRead = size; if (size > 0) { if(!_thereAreBytesToReadEvent->Lock()) @@ -117,7 +117,7 @@ STDMETHODIMP CStreamBinder::ReadPart(void *data, UINT32 size, UINT32 *processedS if (_bufferSize > 0) { MoveMemory(data, _buffer, sizeToRead); - _buffer = ((const BYTE *)_buffer) + sizeToRead; + _buffer = ((const Byte *)_buffer) + sizeToRead; _bufferSize -= sizeToRead; if (_bufferSize == 0) { @@ -132,16 +132,16 @@ STDMETHODIMP CStreamBinder::ReadPart(void *data, UINT32 size, UINT32 *processedS return S_OK; } -STDMETHODIMP CStreamBinder::Read(void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CStreamBinder::Read(void *data, UInt32 size, UInt32 *processedSize) { - UINT32 fullProcessedSize = 0; - UINT32 realProcessedSize; + UInt32 fullProcessedSize = 0; + UInt32 realProcessedSize; HRESULT result = S_OK; while(size > 0) { result = ReadPart(data, size, &realProcessedSize); size -= realProcessedSize; - data = (void *)((BYTE *)data + realProcessedSize); + data = (void *)((Byte *)data + realProcessedSize); fullProcessedSize += realProcessedSize; if (result != S_OK) break; @@ -158,7 +158,7 @@ void CStreamBinder::CloseRead() _readStreamIsClosedEvent->Set(); } -STDMETHODIMP CStreamBinder::Write(const void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSize) { if (size > 0) { @@ -184,7 +184,7 @@ STDMETHODIMP CStreamBinder::Write(const void *data, UINT32 size, UINT32 *process return S_OK; } -STDMETHODIMP CStreamBinder::WritePart(const void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CStreamBinder::WritePart(const void *data, UInt32 size, UInt32 *processedSize) { return Write(data, size, processedSize); } @@ -194,4 +194,3 @@ void CStreamBinder::CloseWrite() // _bufferSize must be = 0 _thereAreBytesToReadEvent->Set(); } - diff --git a/7zip/Common/StreamBinder.h b/7zip/Common/StreamBinder.h index dc656c02..588713ed 100755 --- a/7zip/Common/StreamBinder.h +++ b/7zip/Common/StreamBinder.h @@ -1,7 +1,5 @@ // StreamBinder.h -#pragma once - #ifndef __STREAMBINDER_H #define __STREAMBINDER_H @@ -13,11 +11,11 @@ class CStreamBinder NWindows::NSynchronization::CManualResetEvent *_allBytesAreWritenEvent; NWindows::NSynchronization::CManualResetEvent *_thereAreBytesToReadEvent; NWindows::NSynchronization::CManualResetEvent *_readStreamIsClosedEvent; - UINT32 _bufferSize; + UInt32 _bufferSize; const void *_buffer; public: // bool ReadingWasClosed; - UINT64 ProcessedSize; + UInt64 ProcessedSize; CStreamBinder(): _allBytesAreWritenEvent(NULL), _thereAreBytesToReadEvent(NULL), @@ -28,15 +26,14 @@ public: void CreateStreams(ISequentialInStream **inStream, ISequentialOutStream **outStream); - STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize); - STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize); + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); void CloseRead(); - STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize); - STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize); + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); void CloseWrite(); void ReInit(); }; #endif - diff --git a/7zip/Common/StreamObjects.cpp b/7zip/Common/StreamObjects.cpp index 5f696655..bff00d8d 100755 --- a/7zip/Common/StreamObjects.cpp +++ b/7zip/Common/StreamObjects.cpp @@ -5,6 +5,7 @@ #include "StreamObjects.h" #include "../../Common/Defs.h" +/* STDMETHODIMP COutStreamImp::Read(void *data, ULONG size, ULONG *processedSize) { return E_NOTIMPL; } @@ -19,7 +20,7 @@ STDMETHODIMP COutStreamImp::Write(void const *data, ULONG size, ULONG *processed return S_OK; } -void CInStreamImp::Init(BYTE *dataPointer, UINT32 size) +void CInStreamImp::Init(Byte *dataPointer, size_t size) { _dataPointer = dataPointer; _size = size; @@ -28,7 +29,7 @@ void CInStreamImp::Init(BYTE *dataPointer, UINT32 size) STDMETHODIMP CInStreamImp::Read(void *data, ULONG size, ULONG *processedSize) { - UINT32 numBytesToRead = MyMin(_pos + (UINT32)size, _size) - _pos; + UInt32 numBytesToRead = MyMin(_pos + (UInt32)size, _size) - _pos; if(processedSize != NULL) *processedSize = numBytesToRead; memmove(data, _dataPointer + _pos, numBytesToRead); @@ -41,12 +42,12 @@ STDMETHODIMP CInStreamImp::Read(void *data, ULONG size, ULONG *processedSize) STDMETHODIMP CInStreamImp::Write(void const *data, ULONG size, ULONG *processedSize) { return E_NOTIMPL; } +*/ - -STDMETHODIMP CSequentialInStreamImp::Read(void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CSequentialInStreamImp::Read(void *data, UInt32 size, UInt32 *processedSize) { - UINT32 numBytesToRead = MyMin(_pos + size, _size) - _pos; + UInt32 numBytesToRead = (UInt32)(MyMin(_pos + size, _size) - _pos); memmove(data, _dataPointer + _pos, numBytesToRead); _pos += numBytesToRead; if(processedSize != NULL) @@ -54,7 +55,7 @@ STDMETHODIMP CSequentialInStreamImp::Read(void *data, UINT32 size, UINT32 *proce return S_OK; } -STDMETHODIMP CSequentialInStreamImp::ReadPart(void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CSequentialInStreamImp::ReadPart(void *data, UInt32 size, UInt32 *processedSize) { return Read(data, size, processedSize); } @@ -62,7 +63,7 @@ STDMETHODIMP CSequentialInStreamImp::ReadPart(void *data, UINT32 size, UINT32 *p //////////////////// -void CWriteBuffer::Write(const void *data, UINT32 size) +void CWriteBuffer::Write(const void *data, size_t size) { size_t newCapacity = _size + size; _buffer.EnsureCapacity(newCapacity); @@ -70,7 +71,7 @@ void CWriteBuffer::Write(const void *data, UINT32 size) _size += size; } -STDMETHODIMP CSequentialOutStreamImp::Write(const void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CSequentialOutStreamImp::Write(const void *data, UInt32 size, UInt32 *processedSize) { _writeBuffer.Write(data, size); if(processedSize != NULL) @@ -78,14 +79,14 @@ STDMETHODIMP CSequentialOutStreamImp::Write(const void *data, UINT32 size, UINT3 return S_OK; } -STDMETHODIMP CSequentialOutStreamImp::WritePart(const void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CSequentialOutStreamImp::WritePart(const void *data, UInt32 size, UInt32 *processedSize) { return Write(data, size, processedSize); } -STDMETHODIMP CSequentialOutStreamImp2::Write(const void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CSequentialOutStreamImp2::Write(const void *data, UInt32 size, UInt32 *processedSize) { - UINT32 newSize = size; + UInt32 newSize = size; if (_pos + size > _size) newSize = _size - _pos; memmove(_buffer + _pos, data, newSize); @@ -97,16 +98,16 @@ STDMETHODIMP CSequentialOutStreamImp2::Write(const void *data, UINT32 size, UINT return S_OK; } -STDMETHODIMP CSequentialOutStreamImp2::WritePart(const void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CSequentialOutStreamImp2::WritePart(const void *data, UInt32 size, UInt32 *processedSize) { return Write(data, size, processedSize); } -STDMETHODIMP CSequentialInStreamSizeCount::Read(void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CSequentialInStreamSizeCount::Read(void *data, UInt32 size, UInt32 *processedSize) { - UINT32 realProcessedSize; + UInt32 realProcessedSize; HRESULT result = _stream->Read(data, size, &realProcessedSize); _size += realProcessedSize; if (processedSize != 0) @@ -114,9 +115,9 @@ STDMETHODIMP CSequentialInStreamSizeCount::Read(void *data, UINT32 size, UINT32 return result; } -STDMETHODIMP CSequentialInStreamSizeCount::ReadPart(void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CSequentialInStreamSizeCount::ReadPart(void *data, UInt32 size, UInt32 *processedSize) { - UINT32 realProcessedSize; + UInt32 realProcessedSize; HRESULT result = _stream->ReadPart(data, size, &realProcessedSize); _size += realProcessedSize; if (processedSize != 0) @@ -124,10 +125,63 @@ STDMETHODIMP CSequentialInStreamSizeCount::ReadPart(void *data, UINT32 size, UIN return result; } +STDMETHODIMP CSequentialInStreamRollback::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + HRESULT result = S_OK; + UInt32 realProcessedSizeTotal = 0; + while (size > 0) + { + UInt32 realProcessedSize = 0; + result = ReadPart(data, size, &realProcessedSize); + size -= realProcessedSize; + data = ((Byte *)data + realProcessedSize); + realProcessedSizeTotal += realProcessedSize; + if (realProcessedSize == 0 || result != S_OK) + break; + } + if (processedSize != 0) + *processedSize = realProcessedSizeTotal; + return result; +} + +STDMETHODIMP CSequentialInStreamRollback::ReadPart(void *data, UInt32 size, UInt32 *processedSize) +{ + if (_currentPos != _currentSize) + { + UInt32 curSize = _currentSize - _currentPos; + if (size > curSize) + size = curSize; + memmove(data, _buffer + _currentPos, size); + _currentPos += size; + if (processedSize != 0) + *processedSize = size; + return S_OK; + } + UInt32 realProcessedSize; + if (size > _bufferSize) + size = _bufferSize; + HRESULT result = _stream->ReadPart(_buffer, size, &realProcessedSize); + memmove(data, _buffer, realProcessedSize); + _size += realProcessedSize; + _currentSize = realProcessedSize; + _currentPos = realProcessedSize; + if (processedSize != 0) + *processedSize = realProcessedSize; + return result; +} + +HRESULT CSequentialInStreamRollback::Rollback(size_t rollbackSize) +{ + if (rollbackSize > _currentPos) + return E_INVALIDARG; + _currentPos -= rollbackSize; + return S_OK; +} + -STDMETHODIMP CSequentialOutStreamSizeCount::Write(const void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CSequentialOutStreamSizeCount::Write(const void *data, UInt32 size, UInt32 *processedSize) { - UINT32 realProcessedSize; + UInt32 realProcessedSize; HRESULT result = _stream->Write(data, size, &realProcessedSize); _size += realProcessedSize; if (processedSize != 0) @@ -135,9 +189,9 @@ STDMETHODIMP CSequentialOutStreamSizeCount::Write(const void *data, UINT32 size, return result; } -STDMETHODIMP CSequentialOutStreamSizeCount::WritePart(const void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CSequentialOutStreamSizeCount::WritePart(const void *data, UInt32 size, UInt32 *processedSize) { - UINT32 realProcessedSize; + UInt32 realProcessedSize; HRESULT result = _stream->WritePart(data, size, &realProcessedSize); _size += realProcessedSize; if (processedSize != 0) diff --git a/7zip/Common/StreamObjects.h b/7zip/Common/StreamObjects.h index 4c8139f1..78e31980 100755 --- a/7zip/Common/StreamObjects.h +++ b/7zip/Common/StreamObjects.h @@ -1,7 +1,5 @@ // StreamObjects.h -#pragma once - #ifndef __STREAMOBJECTS_H #define __STREAMOBJECTS_H @@ -9,16 +7,17 @@ #include "../../Common/MyCom.h" #include "../IStream.h" +/* class COutStreamImp: public ISequentialStream, public CMyUnknownImp { CByteDynamicBuffer _buffer; - UINT32 _size; + size_t _size; public: COutStreamImp(): _size(0) {} void Init(){ _size = 0; } - UINT32 GetSize() const { return _size; } + size_t GetSize() const { return _size; } const CByteDynamicBuffer& GetBuffer() const { return _buffer; } MY_UNKNOWN_IMP @@ -31,30 +30,31 @@ class CInStreamImp: public ISequentialStream, public CMyUnknownImp { - BYTE *_dataPointer; - UINT32 _size; - UINT32 _pos; + Byte *_dataPointer; + size_t _size; + size_t _pos; public: CInStreamImp(): _size(0xFFFFFFFF), _pos(0), _dataPointer(NULL) {} - void Init(BYTE *dataPointer, UINT32 size); + void Init(Byte *dataPointer, size_t size); MY_UNKNOWN_IMP STDMETHODIMP Read(void *data, ULONG size, ULONG *processedSize); STDMETHODIMP Write(void const *data, ULONG size, ULONG *processedSize); }; +*/ class CSequentialInStreamImp: public ISequentialInStream, public CMyUnknownImp { - const BYTE *_dataPointer; - UINT32 _size; - UINT32 _pos; + const Byte *_dataPointer; + size_t _size; + size_t _pos; public: - void Init(const BYTE *dataPointer, UINT32 size) + void Init(const Byte *dataPointer, size_t size) { _dataPointer = dataPointer; _size = size; @@ -63,18 +63,18 @@ public: MY_UNKNOWN_IMP - STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize); - STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize); + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); }; class CWriteBuffer { CByteDynamicBuffer _buffer; - UINT32 _size; + size_t _size; public: CWriteBuffer(): _size(0) {} - // void Init(UINT32 size = 0) + // void Init(size_t size = 0) void Init() { /* @@ -83,8 +83,8 @@ public: */ _size = 0; } - void Write(const void *data, UINT32 size); - UINT32 GetSize() const { return _size; } + void Write(const void *data, size_t size); + size_t GetSize() const { return _size; } const CByteDynamicBuffer& GetBuffer() const { return _buffer; } }; @@ -100,30 +100,30 @@ public: } /* - void Init(UINT32 size = 0) + void Init(size_t size = 0) { _writeBuffer.Init(size); } */ - UINT32 GetSize() const { return _writeBuffer.GetSize(); } + size_t GetSize() const { return _writeBuffer.GetSize(); } const CByteDynamicBuffer& GetBuffer() const { return _writeBuffer.GetBuffer(); } MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize); - STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize); + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); }; class CSequentialOutStreamImp2: public ISequentialOutStream, public CMyUnknownImp { - BYTE *_buffer; + Byte *_buffer; public: - UINT32 _size; - UINT32 _pos; + size_t _size; + size_t _pos; - void Init(BYTE *buffer, UINT32 size) + void Init(Byte *buffer, size_t size) { _buffer = buffer; _pos = 0; @@ -132,8 +132,8 @@ public: MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize); - STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize); + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); }; class CSequentialInStreamSizeCount: @@ -141,19 +141,58 @@ class CSequentialInStreamSizeCount: public CMyUnknownImp { CMyComPtr<ISequentialInStream> _stream; - UINT64 _size; + UInt64 _size; +public: + void Init(ISequentialInStream *stream) + { + _stream = stream; + _size = 0; + } + UInt64 GetSize() const { return _size; } + + MY_UNKNOWN_IMP + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); +}; + +class CSequentialInStreamRollback: + public ISequentialInStream, + public CMyUnknownImp +{ + CMyComPtr<ISequentialInStream> _stream; + Byte *_buffer; + size_t _bufferSize; + UInt64 _size; + + size_t _currentSize; + size_t _currentPos; public: + CSequentialInStreamRollback(size_t bufferSize): + _bufferSize(bufferSize), + _buffer(0) + { + _buffer = new Byte[bufferSize]; + } + ~CSequentialInStreamRollback() + { + delete _buffer; + } + void Init(ISequentialInStream *stream) { _stream = stream; _size = 0; + _currentSize = 0; + _currentPos = 0; } - UINT64 GetSize() const { return _size; } + UInt64 GetSize() const { return _size; } MY_UNKNOWN_IMP - STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize); - STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize); + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); + HRESULT Rollback(size_t rollbackSize); }; class CSequentialOutStreamSizeCount: @@ -161,19 +200,19 @@ class CSequentialOutStreamSizeCount: public CMyUnknownImp { CMyComPtr<ISequentialOutStream> _stream; - UINT64 _size; + UInt64 _size; public: void Init(ISequentialOutStream *stream) { _stream = stream; _size = 0; } - UINT64 GetSize() const { return _size; } + UInt64 GetSize() const { return _size; } MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize); - STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize); + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); }; #endif diff --git a/7zip/Compress/Arj/Decoder1.cpp b/7zip/Compress/Arj/Decoder1.cpp index b43a408d..b9f2881c 100755 --- a/7zip/Compress/Arj/Decoder1.cpp +++ b/7zip/Compress/Arj/Decoder1.cpp @@ -10,20 +10,17 @@ namespace NCompress{ namespace NArj { namespace NDecoder1 { -static const UINT32 kHistorySize = 26624; -static const UINT32 kMatchMaxLen = 256; -static const UINT32 kMatchMinLen = 3; +static const UInt32 kHistorySize = 26624; +static const UInt32 kMatchMaxLen = 256; +static const UInt32 kMatchMinLen = 3; -static const UINT32 kNC = 255 + kMatchMaxLen + 2 - kMatchMinLen; +static const UInt32 kNC = 255 + kMatchMaxLen + 2 - kMatchMinLen; -CCoder::CCoder() -{} - -void CCoder::make_table(int nchar, BYTE *bitlen, int tablebits, - UINT32 *table, int tablesize) +void CCoder::MakeTable(int nchar, Byte *bitlen, int tablebits, + UInt32 *table, int tablesize) { - UINT32 count[17], weight[17], start[18], *p; - UINT32 i, k, len, ch, jutbits, avail, nextcode, mask; + UInt32 count[17], weight[17], start[18], *p; + UInt32 i, k, len, ch, jutbits, avail, nextcode, mask; for (i = 1; i <= 16; i++) count[i] = 0; @@ -33,7 +30,7 @@ void CCoder::make_table(int nchar, BYTE *bitlen, int tablebits, start[1] = 0; for (i = 1; i <= 16; i++) start[i + 1] = start[i] + (count[i] << (16 - i)); - if (start[17] != (UINT32) (1 << 16)) + if (start[17] != (UInt32) (1 << 16)) throw "Data error"; jutbits = 16 - tablebits; @@ -49,7 +46,7 @@ void CCoder::make_table(int nchar, BYTE *bitlen, int tablebits, } i = start[tablebits + 1] >> jutbits; - if (i != (UINT32) (1 << 16)) + if (i != (UInt32) (1 << 16)) { k = 1 << tablebits; while (i != k) @@ -66,7 +63,7 @@ void CCoder::make_table(int nchar, BYTE *bitlen, int tablebits, nextcode = k + weight[len]; if ((int)len <= tablebits) { - if (nextcode > (UINT32)tablesize) + if (nextcode > (UInt32)tablesize) throw "Data error"; for (i = start[len]; i < nextcode; i++) table[i] = ch; @@ -97,10 +94,10 @@ void CCoder::make_table(int nchar, BYTE *bitlen, int tablebits, void CCoder::read_pt_len(int nn, int nbit, int i_special) { - UINT32 n = m_InBitStream.ReadBits(nbit); + UInt32 n = m_InBitStream.ReadBits(nbit); if (n == 0) { - UINT32 c = m_InBitStream.ReadBits(nbit); + UInt32 c = m_InBitStream.ReadBits(nbit); int i; for (i = 0; i < nn; i++) pt_len[i] = 0; @@ -109,14 +106,14 @@ void CCoder::read_pt_len(int nn, int nbit, int i_special) } else { - UINT32 i = 0; + UInt32 i = 0; while (i < n) { - UINT32 bitBuf = m_InBitStream.GetValue(16); + UInt32 bitBuf = m_InBitStream.GetValue(16); int c = bitBuf >> 13; if (c == 7) { - UINT32 mask = 1 << (12); + UInt32 mask = 1 << (12); while (mask & bitBuf) { mask >>= 1; @@ -124,24 +121,24 @@ void CCoder::read_pt_len(int nn, int nbit, int i_special) } } m_InBitStream.MovePos((c < 7) ? 3 : (int)(c - 3)); - pt_len[i++] = (BYTE)c; - if (i == (UINT32)i_special) + pt_len[i++] = (Byte)c; + if (i == (UInt32)i_special) { c = m_InBitStream.ReadBits(2); while (--c >= 0) pt_len[i++] = 0; } } - while (i < (UINT32)nn) + while (i < (UInt32)nn) pt_len[i++] = 0; - make_table(nn, pt_len, 8, pt_table, PTABLESIZE); + MakeTable(nn, pt_len, 8, pt_table, PTABLESIZE); } } void CCoder::read_c_len() { int i, c, n; - UINT32 mask; + UInt32 mask; n = m_InBitStream.ReadBits(CBIT); if (n == 0) @@ -157,7 +154,7 @@ void CCoder::read_c_len() i = 0; while (i < n) { - UINT32 bitBuf = m_InBitStream.GetValue(16); + UInt32 bitBuf = m_InBitStream.GetValue(16); c = pt_table[bitBuf >> (8)]; if (c >= NT) { @@ -184,18 +181,18 @@ void CCoder::read_c_len() c_len[i++] = 0; } else - c_len[i++] = (BYTE)(c - 2); + c_len[i++] = (Byte)(c - 2); } while (i < NC) c_len[i++] = 0; - make_table(NC, c_len, 12, c_table, CTABLESIZE); + MakeTable(NC, c_len, 12, c_table, CTABLESIZE); } } -UINT32 CCoder::decode_c() +UInt32 CCoder::decode_c() { - UINT32 j, mask; - UINT32 bitbuf = m_InBitStream.GetValue(16); + UInt32 j, mask; + UInt32 bitbuf = m_InBitStream.GetValue(16); j = c_table[bitbuf >> 4]; if (j >= NC) { @@ -213,10 +210,10 @@ UINT32 CCoder::decode_c() return j; } -UINT32 CCoder::decode_p() +UInt32 CCoder::decode_p() { - UINT32 j, mask; - UINT32 bitbuf = m_InBitStream.GetValue(16); + UInt32 j, mask; + UInt32 bitbuf = m_InBitStream.GetValue(16); j = pt_table[bitbuf >> (8)]; if (j >= NP) { @@ -241,9 +238,17 @@ UINT32 CCoder::decode_p() STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { + if (outSize == NULL) + return E_INVALIDARG; + + if (!m_OutWindowStream.Create(kHistorySize)) + return E_OUTOFMEMORY; + if (!m_InBitStream.Create(1 << 20)) + return E_OUTOFMEMORY; + int size1 = sizeof(c_table) / sizeof(c_table[0]); for (int i = 0; i < size1; i++) { @@ -253,20 +258,16 @@ STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream, c_table[i] = 0; } - if (outSize == NULL) - return E_INVALIDARG; - if (!m_OutWindowStream.IsCreated()) - { - try { m_OutWindowStream.Create(kHistorySize); } - catch(...) { return E_OUTOFMEMORY; } - } - UINT64 pos = 0; - m_OutWindowStream.Init(outStream, false); - m_InBitStream.Init(inStream); + UInt64 pos = 0; + m_OutWindowStream.SetStream(outStream); + m_OutWindowStream.Init(false); + m_InBitStream.SetStream(inStream); + m_InBitStream.Init(); + CCoderReleaser coderReleaser(this); - UINT32 blockSize = 0; + UInt32 blockSize = 0; while(pos < *outSize) { @@ -274,7 +275,7 @@ STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream, { if (progress != NULL) { - UINT64 packSize = m_InBitStream.GetProcessedSize(); + UInt64 packSize = m_InBitStream.GetProcessedSize(); RINOK(progress->SetRatioInfo(&packSize, &pos)); } blockSize = m_InBitStream.ReadBits(16); @@ -284,28 +285,29 @@ STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream, } blockSize--; - UINT32 number = decode_c(); + UInt32 number = decode_c(); if (number < 256) { - m_OutWindowStream.PutOneByte(number); + m_OutWindowStream.PutByte(number); pos++; continue; } else { - UINT32 len = number - 256 + kMatchMinLen; - UINT32 distance = decode_p(); + UInt32 len = number - 256 + kMatchMinLen; + UInt32 distance = decode_p(); if (distance >= pos) throw "data error"; - m_OutWindowStream.CopyBackBlock(distance, len); + m_OutWindowStream.CopyBlock(distance, len); pos += len; } } + coderReleaser.NeedFlush = false; return m_OutWindowStream.Flush(); } STDMETHODIMP CCoder::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { try { return CodeReal(inStream, outStream, inSize, outSize, progress);} diff --git a/7zip/Compress/Arj/Decoder1.h b/7zip/Compress/Arj/Decoder1.h index 6caa18e5..22b1002b 100755 --- a/7zip/Compress/Arj/Decoder1.h +++ b/7zip/Compress/Arj/Decoder1.h @@ -1,11 +1,9 @@ // Arj/Decoder1.h -#pragma once - #ifndef __COMPRESS_ARJ_DECODER1_H #define __COMPRESS_ARJ_DECODER1_H -#include "Common/MyCom.h" +#include "../../../Common/MyCom.h" #include "../../ICoder.h" #include "../../Common/MSBFDecoder.h" #include "../../Common/InBuffer.h" @@ -28,7 +26,7 @@ namespace NDecoder1 { #define MAXDICBIT 16 #define MATCHBIT 8 #define MAXMATCH 256 -#define NC (UCHAR_MAX + MAXMATCH + 2 - THRESHOLD) +#define NC (0xFF + MAXMATCH + 2 - THRESHOLD) #define NP (MAXDICBIT + 1) #define CBIT 9 #define NT (CODE_BIT + 3) @@ -52,55 +50,53 @@ class CCoder : CLZOutWindow m_OutWindowStream; NStream::NMSBF::CDecoder<CInBuffer> m_InBitStream; - UINT32 left[2 * NC - 1]; - UINT32 right[2 * NC - 1]; - BYTE c_len[NC]; - BYTE pt_len[NPT]; + UInt32 left[2 * NC - 1]; + UInt32 right[2 * NC - 1]; + Byte c_len[NC]; + Byte pt_len[NPT]; - UINT32 c_table[CTABLESIZE]; - UINT32 pt_table[PTABLESIZE]; + UInt32 c_table[CTABLESIZE]; + UInt32 pt_table[PTABLESIZE]; - - /* void CCoder::ReleaseStreams() { m_OutWindowStream.ReleaseStream(); m_InBitStream.ReleaseStream(); } - */ + class CCoderReleaser { CCoder *m_Coder; public: - CCoderReleaser(CCoder *aCoder): m_Coder(aCoder) {} + bool NeedFlush; + CCoderReleaser(CCoder *coder): m_Coder(coder), NeedFlush(true) {} ~CCoderReleaser() { - m_Coder->m_OutWindowStream.Flush(); - // m_Coder->ReleaseStreams(); + if (NeedFlush) + m_Coder->m_OutWindowStream.Flush(); + m_Coder->ReleaseStreams(); } }; friend class CCoderReleaser; - void make_table(int nchar, BYTE *bitlen, int tablebits, - UINT32 *table, int tablesize); + void MakeTable(int nchar, Byte *bitlen, int tablebits, + UInt32 *table, int tablesize); void read_c_len(); void read_pt_len(int nn, int nbit, int i_special); - UINT32 decode_c(); - UINT32 decode_p(); - + UInt32 decode_c(); + UInt32 decode_p(); public: - CCoder(); - + MY_UNKNOWN_IMP STDMETHOD(CodeReal)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); STDMETHOD(Code)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); }; diff --git a/7zip/Compress/Arj/Decoder2.cpp b/7zip/Compress/Arj/Decoder2.cpp index 87c3b4cb..ab6c57fa 100755 --- a/7zip/Compress/Arj/Decoder2.cpp +++ b/7zip/Compress/Arj/Decoder2.cpp @@ -4,43 +4,40 @@ #include "Decoder2.h" -#include "Windows/Defs.h" - namespace NCompress{ namespace NArj { namespace NDecoder2 { -static const UINT32 kHistorySize = 26624; -static const UINT32 kMatchMaxLen = 256; -static const UINT32 kMatchMinLen = 3; - -CCoder::CCoder() -{} +static const UInt32 kHistorySize = 26624; +static const UInt32 kMatchMaxLen = 256; +static const UInt32 kMatchMinLen = 3; STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { if (outSize == NULL) return E_INVALIDARG; - if (!m_OutWindowStream.IsCreated()) - { - try { m_OutWindowStream.Create(kHistorySize); } - catch(...) { return E_OUTOFMEMORY; } - } - UINT64 pos = 0; - m_OutWindowStream.Init(outStream, false); - m_InBitStream.Init(inStream); + if (!m_OutWindowStream.Create(kHistorySize)) + return E_OUTOFMEMORY; + if (!m_InBitStream.Create(1 << 20)) + return E_OUTOFMEMORY; + + UInt64 pos = 0; + m_OutWindowStream.SetStream(outStream); + m_OutWindowStream.Init(false); + m_InBitStream.SetStream(inStream); + m_InBitStream.Init(); CCoderReleaser coderReleaser(this); while(pos < *outSize) { - const UINT32 kStartWidth = 0; - const UINT32 kStopWidth = 7; - UINT32 power = 1 << kStartWidth; - UINT32 width; - UINT32 len = 0; + const UInt32 kStartWidth = 0; + const UInt32 kStopWidth = 7; + UInt32 power = 1 << kStartWidth; + UInt32 width; + UInt32 len = 0; for (width = kStartWidth; width < kStopWidth; width++) { if (m_InBitStream.ReadBits(1) == 0) @@ -52,18 +49,18 @@ STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream, len += m_InBitStream.ReadBits(width); if (len == 0) { - m_OutWindowStream.PutOneByte(m_InBitStream.ReadBits(8)); + m_OutWindowStream.PutByte(m_InBitStream.ReadBits(8)); pos++; continue; } else { len = len - 1 + kMatchMinLen; - const UINT32 kStartWidth = 9; - const UINT32 kStopWidth = 13; - UINT32 power = 1 << kStartWidth; - UINT32 width; - UINT32 distance = 0; + const UInt32 kStartWidth = 9; + const UInt32 kStopWidth = 13; + UInt32 power = 1 << kStartWidth; + UInt32 width; + UInt32 distance = 0; for (width = kStartWidth; width < kStopWidth; width++) { if (m_InBitStream.ReadBits(1) == 0) @@ -75,15 +72,16 @@ STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream, distance += m_InBitStream.ReadBits(width); if (distance >= pos) throw "data error"; - m_OutWindowStream.CopyBackBlock(distance, len); + m_OutWindowStream.CopyBlock(distance, len); pos += len; } } + coderReleaser.NeedFlush = false; return m_OutWindowStream.Flush(); } STDMETHODIMP CCoder::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { try { return CodeReal(inStream, outStream, inSize, outSize, progress);} diff --git a/7zip/Compress/Arj/Decoder2.h b/7zip/Compress/Arj/Decoder2.h index 0fa993c6..bc54c1dd 100755 --- a/7zip/Compress/Arj/Decoder2.h +++ b/7zip/Compress/Arj/Decoder2.h @@ -1,11 +1,9 @@ // Arj/Decoder2.h -#pragma once - #ifndef __COMPRESS_ARJ_DECODER2_H #define __COMPRESS_ARJ_DECODER2_H -#include "Common/MyCom.h" +#include "../../../Common/MyCom.h" #include "../../ICoder.h" #include "../../Common/MSBFDecoder.h" #include "../../Common/InBuffer.h" @@ -28,38 +26,36 @@ class CCoder : CLZOutWindow m_OutWindowStream; NStream::NMSBF::CDecoder<CInBuffer> m_InBitStream; - /* void CCoder::ReleaseStreams() { m_OutWindowStream.ReleaseStream(); m_InBitStream.ReleaseStream(); } - */ class CCoderReleaser { CCoder *m_Coder; public: - CCoderReleaser(CCoder *aCoder): m_Coder(aCoder) {} + bool NeedFlush; + CCoderReleaser(CCoder *coder): m_Coder(coder), NeedFlush(true) {} ~CCoderReleaser() { - m_Coder->m_OutWindowStream.Flush(); - // m_Coder->ReleaseStreams(); + if (NeedFlush) + m_Coder->m_OutWindowStream.Flush(); + m_Coder->ReleaseStreams(); } }; friend class CCoderReleaser; public: - CCoder(); - MY_UNKNOWN_IMP STDMETHOD(CodeReal)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); STDMETHOD(Code)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); }; diff --git a/7zip/Compress/Arj/StdAfx.h b/7zip/Compress/Arj/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/7zip/Compress/Arj/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/7zip/Compress/BWT/BlockSort.cpp b/7zip/Compress/BWT/BlockSort.cpp new file mode 100755 index 00000000..2729004a --- /dev/null +++ b/7zip/Compress/BWT/BlockSort.cpp @@ -0,0 +1,289 @@ +// BlockSort.cpp + +#include "StdAfx.h" + +#include "BlockSort.h" + +#include "Common/Alloc.h" + +namespace NCompress { + +static const int kNumHashBytes = 2; +static const UInt32 kNumHashValues = 1 << (kNumHashBytes * 8); + +static const int kNumFlagsBits = 5; // 32 Flags in UInt32 word +static const UInt32 kNumFlagsInWord = (1 << kNumFlagsBits); +static const UInt32 kFlagsMask = kNumFlagsInWord - 1; +static const UInt32 kAllFlags = 0xFFFFFFFF; + +bool CBlockSorter::Create(UInt32 blockSizeMax) +{ + if (Indices != 0 && blockSizeMax == BlockSizeMax) + return true; + Free(); + BlockSizeMax = blockSizeMax; + Indices = (UInt32 *)::BigAlloc((blockSizeMax * 2 + + ((blockSizeMax + kFlagsMask) >> kNumFlagsBits) + kNumHashValues) * sizeof(UInt32)); + return (Indices != 0); +} + +void CBlockSorter::Free() +{ + ::BigFree(Indices); + Indices = 0; +} + +// SortGroup - is recursive Radix-Range-Sort function with Bubble-Sort optimization +// It uses both mask & maskSize (Range-Sort), since it can change values (Groups) +// during sorting +// returns: 0 - if there are groups, 1 - no more groups +UInt32 CBlockSorter::SortGroup(UInt32 groupOffset, UInt32 groupSize, UInt32 mask, UInt32 maskSize) +{ + if (groupSize <= 2) + { + if (groupSize <= 1) + return 0; + UInt32 *ind2 = Indices + groupOffset; + UInt32 stringPos = ind2[0] + NumSortedBytes; + if (stringPos >= BlockSize) + stringPos -= BlockSize; + UInt32 group = Groups[stringPos]; + stringPos = ind2[1] + NumSortedBytes; + if (stringPos >= BlockSize) + stringPos -= BlockSize; + if (group == Groups[stringPos]) + return 1; + if (group > Groups[stringPos]) + { + UInt32 temp = ind2[0]; + ind2[0] = ind2[1]; + ind2[1] = temp; + } + Flags[groupOffset >> kNumFlagsBits] &= ~(1 << (groupOffset & kFlagsMask)); + Groups[ind2[1]] = groupOffset + 1; + return 0; + } + + // Check that all strings are in one group (cannot sort) + UInt32 *ind2 = Indices + groupOffset; + { + UInt32 stringPos = ind2[0] + NumSortedBytes; + if (stringPos >= BlockSize) + stringPos -= BlockSize; + UInt32 group = Groups[stringPos]; + UInt32 j; + for (j = 1; j < groupSize; j++) + { + stringPos = ind2[j] + NumSortedBytes; + if (stringPos >= BlockSize) + stringPos -= BlockSize; + if (Groups[stringPos] != group) + break; + } + if (j == groupSize) + return 1; + } + + if (groupSize <= 15) + { + // Bubble-Sort + UInt32 lastChange = groupSize; + do + { + UInt32 stringPos = ind2[0] + NumSortedBytes; + if (stringPos >= BlockSize) + stringPos -= BlockSize; + UInt32 group = Groups[stringPos]; + + UInt32 sortSize = lastChange; + lastChange = 0; + for (UInt32 j = 1; j < sortSize; j++) + { + stringPos = ind2[j] + NumSortedBytes; + if (stringPos >= BlockSize) + stringPos -= BlockSize; + if (Groups[stringPos] < group) + { + UInt32 temp = ind2[j]; + ind2[j] = ind2[j - 1]; + ind2[j - 1] = temp; + lastChange = j; + } + else + group = Groups[stringPos]; + } + } + while(lastChange > 1); + + // Write Flags + UInt32 stringPos = ind2[0] + NumSortedBytes; + if (stringPos >= BlockSize) + stringPos -= BlockSize; + UInt32 group = Groups[stringPos]; + + UInt32 j; + for (j = 1; j < groupSize; j++) + { + stringPos = ind2[j] + NumSortedBytes; + if (stringPos >= BlockSize) + stringPos -= BlockSize; + if (Groups[stringPos] != group) + { + group = Groups[stringPos]; + UInt32 t = groupOffset + j - 1; + Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask)); + } + } + + // Write new Groups values and Check that there are groups + UInt32 thereAreGroups = 0; + for (j = 0; j < groupSize; j++) + { + UInt32 group = groupOffset + j; + while (true) + { + Groups[ind2[j]] = group; + if ((Flags[(groupOffset + j) >> kNumFlagsBits] & (1 << ((groupOffset + j) & kFlagsMask))) == 0) + break; + j++; + thereAreGroups = 1; + } + } + return thereAreGroups; + } + + // Radix-Range Sort + UInt32 i; + do + { + if (maskSize == 0) + return 1; + UInt32 j = groupSize; + i = 0; + do + { + UInt32 stringPos = ind2[i] + NumSortedBytes; + if (stringPos >= BlockSize) + stringPos -= BlockSize; + if (Groups[stringPos] >= mask) + { + for (j--; j > i; j--) + { + stringPos = ind2[j] + NumSortedBytes; + if (stringPos >= BlockSize) + stringPos -= BlockSize; + if (Groups[stringPos] < mask) + { + UInt32 temp = ind2[i]; + ind2[i] = ind2[j]; + ind2[j] = temp; + break; + } + } + if (i >= j) + break; + } + } + while(++i < j); + maskSize >>= 1; + if (i == 0) + mask += maskSize; + else if (i == groupSize) + mask -= maskSize; + else + break; + } + while(true); + UInt32 t = (groupOffset + i - 1); + Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask)); + + for (UInt32 j = i; j < groupSize; j++) + Groups[ind2[j]] = groupOffset + i; + + UInt32 res = SortGroup(groupOffset, i, mask - maskSize, maskSize); + return res | SortGroup(groupOffset + i, groupSize - i, mask + maskSize, maskSize); +} + +UInt32 CBlockSorter::Sort(const Byte *data, UInt32 blockSize) +{ + BlockSize = blockSize; + UInt32 *counters = Indices + blockSize; + Groups = counters + kNumHashValues; + Flags = Groups + blockSize; + UInt32 i; + + // Radix-Sort for 2 bytes + for (i = 0; i < kNumHashValues; i++) + counters[i] = 0; + for (i = 0; i < blockSize - 1; i++) + counters[((UInt32)data[i] << 8) | data[i + 1]]++; + counters[((UInt32)data[i] << 8) | data[0]]++; + + { + { + UInt32 numWords = (blockSize + kFlagsMask) >> kNumFlagsBits; + for (i = 0; i < numWords; i++) + Flags[i] = kAllFlags; + } + + UInt32 sum = 0; + for (i = 0; i < kNumHashValues; i++) + { + UInt32 groupSize = counters[i]; + if (groupSize > 0) + { + UInt32 t = sum + groupSize - 1; + Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask)); + sum += groupSize; + } + counters[i] = sum - groupSize; + } + + for (i = 0; i < blockSize - 1; i++) + Groups[i] = counters[((UInt32)data[i] << 8) | data[i + 1]]; + Groups[i] = counters[((UInt32)data[i] << 8) | data[0]]; + + for (i = 0; i < blockSize - 1; i++) + Indices[counters[((UInt32)data[i] << 8) | data[i + 1]]++] = i; + Indices[counters[((UInt32)data[i] << 8) | data[0]]++] = i; + } + + UInt32 mask; + for (mask = 2; mask < blockSize; mask <<= 1); + mask >>= 1; + for (NumSortedBytes = kNumHashBytes; true; NumSortedBytes <<= 1) + { + UInt32 newLimit = 0; + for (i = 0; i < blockSize;) + { + if ((Flags[i >> kNumFlagsBits] & (1 << (i & kFlagsMask))) == 0) + { + i++; + continue; + } + UInt32 groupSize; + for(groupSize = 1; + (Flags[(i + groupSize) >> kNumFlagsBits] & (1 << ((i + groupSize) & kFlagsMask))) != 0; + groupSize++); + + groupSize++; + + if (NumSortedBytes >= blockSize) + for (UInt32 j = 0; j < groupSize; j++) + { + UInt32 t = (i + j); + Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask)); + Groups[Indices[t]] = t; + } + else + if (SortGroup(i, groupSize, mask, mask) != 0) + newLimit = i + groupSize; + i += groupSize; + } + if (newLimit == 0) + break; + } + return Groups[0]; +} + +} diff --git a/7zip/Compress/BWT/BlockSort.h b/7zip/Compress/BWT/BlockSort.h new file mode 100755 index 00000000..599c3b60 --- /dev/null +++ b/7zip/Compress/BWT/BlockSort.h @@ -0,0 +1,29 @@ +// BlockSort.h + +#ifndef __BLOCKSORT_H +#define __BLOCKSORT_H + +#include "Common/Types.h" + +namespace NCompress { + +class CBlockSorter +{ + UInt32 *Groups; + UInt32 *Flags; + UInt32 BlockSize; + UInt32 NumSortedBytes; + UInt32 BlockSizeMax; + UInt32 SortGroup(UInt32 groupOffset, UInt32 groupSize, UInt32 mask, UInt32 maskSize); +public: + UInt32 *Indices; + CBlockSorter(): Indices(0) {} + ~CBlockSorter() { Free(); } + bool Create(UInt32 blockSizeMax); + void Free(); + UInt32 Sort(const Byte *data, UInt32 blockSize); +}; + +} + +#endif diff --git a/7zip/Compress/BWT/Mtf8.h b/7zip/Compress/BWT/Mtf8.h new file mode 100755 index 00000000..4c0fb9cf --- /dev/null +++ b/7zip/Compress/BWT/Mtf8.h @@ -0,0 +1,140 @@ +// Mtf8.h + +#ifndef __MTF8_H +#define __MTF8_H + +#include "Common/Types.h" + +namespace NCompress { + +class CMtf8Encoder +{ +public: + Byte Buffer[256]; + int FindAndMove(Byte v) + { + int pos; + for (pos = 0; Buffer[pos] != v; pos++); + int resPos = pos; + for (; pos >= 8; pos -= 8) + { + Buffer[pos] = Buffer[pos - 1]; + Buffer[pos - 1] = Buffer[pos - 2]; + Buffer[pos - 2] = Buffer[pos - 3]; + Buffer[pos - 3] = Buffer[pos - 4]; + Buffer[pos - 4] = Buffer[pos - 5]; + Buffer[pos - 5] = Buffer[pos - 6]; + Buffer[pos - 6] = Buffer[pos - 7]; + Buffer[pos - 7] = Buffer[pos - 8]; + } + for (; pos > 0; pos--) + Buffer[pos] = Buffer[pos - 1]; + Buffer[0] = v; + return resPos; + } +}; + +class CMtf8Decoder +{ +public: + Byte Buffer[256]; + void Init(int size) {}; + Byte GetHead() const { return Buffer[0]; } + Byte GetAndMove(int pos) + { + Byte res = Buffer[pos]; + for (; pos >= 8; pos -= 8) + { + Buffer[pos] = Buffer[pos - 1]; + Buffer[pos - 1] = Buffer[pos - 2]; + Buffer[pos - 2] = Buffer[pos - 3]; + Buffer[pos - 3] = Buffer[pos - 4]; + Buffer[pos - 4] = Buffer[pos - 5]; + Buffer[pos - 5] = Buffer[pos - 6]; + Buffer[pos - 6] = Buffer[pos - 7]; + Buffer[pos - 7] = Buffer[pos - 8]; + } + for (; pos > 0; pos--) + Buffer[pos] = Buffer[pos - 1]; + Buffer[0] = res; + return res; + } +}; + +/* +const int kSmallSize = 64; +class CMtf8Decoder +{ + Byte SmallBuffer[kSmallSize]; + int SmallSize; + Byte Counts[16]; + int Size; +public: + Byte Buffer[256]; + + Byte GetHead() const + { + if (SmallSize > 0) + return SmallBuffer[kSmallSize - SmallSize]; + return Buffer[0]; + } + + void Init(int size) + { + Size = size; + SmallSize = 0; + for (int i = 0; i < 16; i++) + { + Counts[i] = ((size >= 16) ? 16 : size); + size -= Counts[i]; + } + } + + Byte GetAndMove(int pos) + { + if (pos < SmallSize) + { + Byte *p = SmallBuffer + kSmallSize - SmallSize; + Byte res = p[pos]; + for (; pos > 0; pos--) + p[pos] = p[pos - 1]; + SmallBuffer[kSmallSize - SmallSize] = res; + return res; + } + if (SmallSize == kSmallSize) + { + int i = Size - 1; + int g = 16; + do + { + g--; + int offset = (g << 4); + for (int t = Counts[g] - 1; t >= 0; t--, i--) + Buffer[i] = Buffer[offset + t]; + } + while(g != 0); + + for (i = kSmallSize - 1; i >= 0; i--) + Buffer[i] = SmallBuffer[i]; + Init(Size); + } + pos -= SmallSize; + int g; + for (g = 0; pos >= Counts[g]; g++) + pos -= Counts[g]; + int offset = (g << 4); + Byte res = Buffer[offset + pos]; + for (pos; pos < 16 - 1; pos++) + Buffer[offset + pos] = Buffer[offset + pos + 1]; + + SmallSize++; + SmallBuffer[kSmallSize - SmallSize] = res; + + Counts[g]--; + return res; + } +}; +*/ + +} +#endif diff --git a/7zip/Compress/BWT/StdAfx.h b/7zip/Compress/BWT/StdAfx.h new file mode 100755 index 00000000..b637fd40 --- /dev/null +++ b/7zip/Compress/BWT/StdAfx.h @@ -0,0 +1,6 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#endif diff --git a/7zip/Compress/BZip2/BZip2.dsp b/7zip/Compress/BZip2/BZip2.dsp index e7d38571..ba22a54b 100755 --- a/7zip/Compress/BZip2/BZip2.dsp +++ b/7zip/Compress/BZip2/BZip2.dsp @@ -117,52 +117,36 @@ SOURCE=.\StdAfx.cpp SOURCE=.\StdAfx.h # End Source File # End Group -# Begin Group "Origianl" +# Begin Group "Common" # PROP Default_Filter "" # Begin Source File -SOURCE=.\Original\blocksort.c - -!IF "$(CFG)" == "BZip2 - Win32 Release" - -# ADD CPP /O2 -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug" - -# SUBTRACT CPP /YX /Yc /Yu - -!ENDIF - +SOURCE=..\..\..\Common\Alloc.cpp # End Source File # Begin Source File -SOURCE=.\Original\bzlib.c - -!IF "$(CFG)" == "BZip2 - Win32 Release" - -# ADD CPP /O2 -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug" - -# SUBTRACT CPP /YX /Yc /Yu - -!ENDIF +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File +SOURCE=..\..\..\Common\NewHandler.cpp # End Source File # Begin Source File -SOURCE=.\Original\bzlib.h +SOURCE=..\..\..\Common\NewHandler.h # End Source File +# End Group +# Begin Group "Huffman" + +# PROP Default_Filter "" # Begin Source File -SOURCE=.\Original\bzlib_private.h +SOURCE=..\Huffman\HuffmanDecoder.h # End Source File # Begin Source File -SOURCE=.\Original\compress.c +SOURCE=..\Huffman\HuffmanEncoder.cpp !IF "$(CFG)" == "BZip2 - Win32 Release" @@ -171,46 +155,48 @@ SOURCE=.\Original\compress.c !ELSEIF "$(CFG)" == "BZip2 - Win32 Debug" -# SUBTRACT CPP /YX /Yc /Yu - !ENDIF # End Source File # Begin Source File -SOURCE=.\Original\crctable.c - -!IF "$(CFG)" == "BZip2 - Win32 Release" - -# ADD CPP /O2 -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug" - -# SUBTRACT CPP /YX /Yc /Yu +SOURCE=..\Huffman\HuffmanEncoder.h +# End Source File +# End Group +# Begin Group "7-Zip Common" -!ENDIF +# PROP Default_Filter "" +# Begin Source File +SOURCE=..\..\Common\InBuffer.cpp # End Source File # Begin Source File -SOURCE=.\Original\decompress.c - -!IF "$(CFG)" == "BZip2 - Win32 Release" - -# ADD CPP /O2 -# SUBTRACT CPP /YX /Yc /Yu +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File -!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug" +SOURCE=..\..\Common\MSBFDecoder.h +# End Source File +# Begin Source File -# SUBTRACT CPP /YX /Yc /Yu +SOURCE=..\..\Common\MSBFEncoder.h +# End Source File +# Begin Source File -!ENDIF +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File +SOURCE=..\..\Common\OutBuffer.h # End Source File +# End Group +# Begin Group "BWT" + +# PROP Default_Filter "" # Begin Source File -SOURCE=.\Original\huffman.c +SOURCE=..\BWT\BlockSort.cpp !IF "$(CFG)" == "BZip2 - Win32 Release" @@ -219,40 +205,26 @@ SOURCE=.\Original\huffman.c !ELSEIF "$(CFG)" == "BZip2 - Win32 Debug" -# SUBTRACT CPP /YX /Yc /Yu - !ENDIF # End Source File # Begin Source File -SOURCE=.\Original\randtable.c - -!IF "$(CFG)" == "BZip2 - Win32 Release" - -# ADD CPP /O2 -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug" - -# SUBTRACT CPP /YX /Yc /Yu - -!ENDIF +SOURCE=..\BWT\BlockSort.h +# End Source File +# Begin Source File +SOURCE=..\BWT\Mtf8.h # End Source File # End Group -# Begin Group "Common" - -# PROP Default_Filter "" # Begin Source File -SOURCE=..\..\..\Common\NewHandler.cpp +SOURCE=.\BZip2CRC.cpp # End Source File # Begin Source File -SOURCE=..\..\..\Common\NewHandler.h +SOURCE=.\BZip2CRC.h # End Source File -# End Group # Begin Source File SOURCE=.\BZip2Decoder.cpp @@ -289,9 +261,5 @@ SOURCE=.\BZip2Encoder.cpp SOURCE=.\BZip2Encoder.h # End Source File -# Begin Source File - -SOURCE=.\BZip2Error.cpp -# End Source File # End Target # End Project diff --git a/7zip/Compress/BZip2/BZip2CRC.cpp b/7zip/Compress/BZip2/BZip2CRC.cpp new file mode 100755 index 00000000..d3ca5e15 --- /dev/null +++ b/7zip/Compress/BZip2/BZip2CRC.cpp @@ -0,0 +1,26 @@ +// BZip2CRC.cpp + +#include "StdAfx.h" + +#include "BZip2CRC.h" + +UInt32 CBZip2CRC::Table[256]; + +static const UInt32 kBZip2CRCPoly = 0x04c11db7; /* AUTODIN II, Ethernet, & FDDI */ + +void CBZip2CRC::InitTable() +{ + for (UInt32 i = 0; i < 256; i++) + { + UInt32 r = (i << 24); + for (int j = 8; j > 0; j--) + r = (r & 0x80000000) ? ((r << 1) ^ kBZip2CRCPoly) : (r << 1); + Table[i] = r; + } +} + +class CBZip2CRCTableInit +{ +public: + CBZip2CRCTableInit() { CBZip2CRC::InitTable(); } +} g_CRCTableInit; diff --git a/7zip/Compress/BZip2/BZip2CRC.h b/7zip/Compress/BZip2/BZip2CRC.h new file mode 100755 index 00000000..7170fb1a --- /dev/null +++ b/7zip/Compress/BZip2/BZip2CRC.h @@ -0,0 +1,30 @@ +// BZip2CRC.h + +#ifndef __BZIP2_CRC_H +#define __BZIP2_CRC_H + +#include "Common/Types.h" + +class CBZip2CRC +{ + UInt32 _value; + static UInt32 Table[256]; +public: + static void InitTable(); + CBZip2CRC(): _value(0xFFFFFFFF) {}; + void Init() { _value = 0xFFFFFFFF; } + void UpdateByte(Byte b) { _value = Table[(_value >> 24) ^ b] ^ (_value << 8); } + UInt32 GetDigest() const { return _value ^ 0xFFFFFFFF; } +}; + +class CBZip2CombinedCRC +{ + UInt32 _value; +public: + CBZip2CombinedCRC(): _value(0){}; + void Init() { _value = 0; } + void Update(UInt32 v) { _value = ((_value << 1) | (_value >> 31)) ^ v; } + UInt32 GetDigest() const { return _value ; } +}; + +#endif diff --git a/7zip/Compress/BZip2/BZip2Const.h b/7zip/Compress/BZip2/BZip2Const.h new file mode 100755 index 00000000..62427aa6 --- /dev/null +++ b/7zip/Compress/BZip2/BZip2Const.h @@ -0,0 +1,54 @@ +// Compress/BZip2Const.h + +#ifndef __COMPRESS_BZIP2_CONST_H +#define __COMPRESS_BZIP2_CONST_H + +namespace NCompress { +namespace NBZip2 { + +const Byte kArSig0 = 'B'; +const Byte kArSig1 = 'Z'; +const Byte kArSig2 = 'h'; +const Byte kArSig3 = '0'; + +const Byte kFinSig0 = 0x17; +const Byte kFinSig1 = 0x72; +const Byte kFinSig2 = 0x45; +const Byte kFinSig3 = 0x38; +const Byte kFinSig4 = 0x50; +const Byte kFinSig5 = 0x90; + +const Byte kBlockSig0 = 0x31; +const Byte kBlockSig1 = 0x41; +const Byte kBlockSig2 = 0x59; +const Byte kBlockSig3 = 0x26; +const Byte kBlockSig4 = 0x53; +const Byte kBlockSig5 = 0x59; + +const int kNumOrigBits = 24; + +const int kNumTablesBits = 3; +const int kNumTablesMin = 2; +const int kNumTablesMax = 6; + +const int kNumLevelsBits = 5; + +const int kMaxHuffmanLen = 20; // Check it + +const int kMaxAlphaSize = 258; + +const int kGroupSize = 50; + +const int kBlockSizeMultMin = 1; +const int kBlockSizeMultMax = 9; +const UInt32 kBlockSizeStep = 100000; +const UInt32 kBlockSizeMax = kBlockSizeMultMax * kBlockSizeStep; + +const int kNumSelectorsBits = 15; +const UInt32 kNumSelectorsMax = (2 + (kBlockSizeMax / kGroupSize)); + +const int kRleModeRepSize = 4; + +}} + +#endif diff --git a/7zip/Compress/BZip2/BZip2Decoder.cpp b/7zip/Compress/BZip2/BZip2Decoder.cpp index 86e6480a..e620f027 100755 --- a/7zip/Compress/BZip2/BZip2Decoder.cpp +++ b/7zip/Compress/BZip2/BZip2Decoder.cpp @@ -4,122 +4,402 @@ #include "BZip2Decoder.h" -#include "Windows/Defs.h" -#include "Original/bzlib.h" +#include "../../../Common/Alloc.h" +#include "../../../Common/Defs.h" +#include "../BWT/Mtf8.h" +#include "BZip2CRC.h" namespace NCompress { namespace NBZip2 { -static const UINT32 kBufferSize = (1 << 20); +static const UInt32 kBufferSize = (1 << 17); -CDecoder::CDecoder() +static Int16 kRandNums[512] = { + 619, 720, 127, 481, 931, 816, 813, 233, 566, 247, + 985, 724, 205, 454, 863, 491, 741, 242, 949, 214, + 733, 859, 335, 708, 621, 574, 73, 654, 730, 472, + 419, 436, 278, 496, 867, 210, 399, 680, 480, 51, + 878, 465, 811, 169, 869, 675, 611, 697, 867, 561, + 862, 687, 507, 283, 482, 129, 807, 591, 733, 623, + 150, 238, 59, 379, 684, 877, 625, 169, 643, 105, + 170, 607, 520, 932, 727, 476, 693, 425, 174, 647, + 73, 122, 335, 530, 442, 853, 695, 249, 445, 515, + 909, 545, 703, 919, 874, 474, 882, 500, 594, 612, + 641, 801, 220, 162, 819, 984, 589, 513, 495, 799, + 161, 604, 958, 533, 221, 400, 386, 867, 600, 782, + 382, 596, 414, 171, 516, 375, 682, 485, 911, 276, + 98, 553, 163, 354, 666, 933, 424, 341, 533, 870, + 227, 730, 475, 186, 263, 647, 537, 686, 600, 224, + 469, 68, 770, 919, 190, 373, 294, 822, 808, 206, + 184, 943, 795, 384, 383, 461, 404, 758, 839, 887, + 715, 67, 618, 276, 204, 918, 873, 777, 604, 560, + 951, 160, 578, 722, 79, 804, 96, 409, 713, 940, + 652, 934, 970, 447, 318, 353, 859, 672, 112, 785, + 645, 863, 803, 350, 139, 93, 354, 99, 820, 908, + 609, 772, 154, 274, 580, 184, 79, 626, 630, 742, + 653, 282, 762, 623, 680, 81, 927, 626, 789, 125, + 411, 521, 938, 300, 821, 78, 343, 175, 128, 250, + 170, 774, 972, 275, 999, 639, 495, 78, 352, 126, + 857, 956, 358, 619, 580, 124, 737, 594, 701, 612, + 669, 112, 134, 694, 363, 992, 809, 743, 168, 974, + 944, 375, 748, 52, 600, 747, 642, 182, 862, 81, + 344, 805, 988, 739, 511, 655, 814, 334, 249, 515, + 897, 955, 664, 981, 649, 113, 974, 459, 893, 228, + 433, 837, 553, 268, 926, 240, 102, 654, 459, 51, + 686, 754, 806, 760, 493, 403, 415, 394, 687, 700, + 946, 670, 656, 610, 738, 392, 760, 799, 887, 653, + 978, 321, 576, 617, 626, 502, 894, 679, 243, 440, + 680, 879, 194, 572, 640, 724, 926, 56, 204, 700, + 707, 151, 457, 449, 797, 195, 791, 558, 945, 679, + 297, 59, 87, 824, 713, 663, 412, 693, 342, 606, + 134, 108, 571, 364, 631, 212, 174, 643, 304, 329, + 343, 97, 430, 751, 497, 314, 983, 374, 822, 928, + 140, 206, 73, 263, 980, 736, 876, 478, 430, 305, + 170, 514, 364, 692, 829, 82, 855, 953, 676, 246, + 369, 970, 294, 750, 807, 827, 150, 790, 288, 923, + 804, 378, 215, 828, 592, 281, 565, 555, 710, 82, + 896, 831, 547, 261, 524, 462, 293, 465, 502, 56, + 661, 821, 976, 991, 658, 869, 905, 758, 745, 193, + 768, 550, 608, 933, 378, 286, 215, 979, 792, 961, + 61, 688, 793, 644, 986, 403, 106, 366, 905, 644, + 372, 567, 466, 434, 645, 210, 389, 550, 919, 135, + 780, 773, 635, 389, 707, 100, 626, 958, 165, 504, + 920, 176, 193, 713, 857, 265, 203, 50, 668, 108, + 645, 990, 626, 197, 510, 357, 358, 850, 858, 364, + 936, 638 +}; + +CState::~CState() { - m_InBuffer = new BYTE[kBufferSize]; - m_OutBuffer = new BYTE[kBufferSize]; + ::BigFree(tt); } -CDecoder::~CDecoder() +bool CState::Alloc() { - delete []m_OutBuffer; - delete []m_InBuffer; + if (tt == 0) + tt = (UInt32 *)BigAlloc(kBlockSizeMax * sizeof(UInt32)); + return (tt != 0); } -struct CBZip2Decompressor: public bz_stream -{ - // bz_stream m_Object; -public: - int Init(int verbosity, int small) { return BZ2_bzDecompressInit(this, verbosity, small); } - int Decompress() { return BZ2_bzDecompress(this); } - int End() { return BZ2_bzDecompressEnd(this); } - UINT64 GetTotalIn() const { return (UINT64(total_in_hi32) << 32) + total_in_lo32; } - UINT64 GetTotalOut() const { return (UINT64(total_out_hi32) << 32) + total_out_lo32; } -}; +UInt32 CDecoder::ReadBits(int numBits) { return m_InStream.ReadBits(numBits); } +Byte CDecoder::ReadByte() {return (Byte)ReadBits(8); } +bool CDecoder::ReadBit() { return ReadBits(1) != 0; } -class CBZip2DecompressorReleaser +UInt32 CDecoder::ReadCRC() { - CBZip2Decompressor *m_Decompressor; -public: - CBZip2DecompressorReleaser(CBZip2Decompressor *aDecompressor): m_Decompressor(aDecompressor) {} - void Diable() { m_Decompressor = NULL; } - ~CBZip2DecompressorReleaser() { if (m_Decompressor != NULL) m_Decompressor->End(); } -}; + UInt32 crc = 0; + for (int i = 0; i < 4; i++) + { + crc <<= 8; + crc |= ReadByte(); + } + return crc; +} -STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, - ICompressProgressInfo *progress) +HRESULT CDecoder::ReadBlock(UInt32 blockSizeMax, CState &state) { - CBZip2Decompressor bzStream; - bzStream.bzalloc = NULL; - bzStream.bzfree = NULL; - bzStream.opaque = NULL; + state.BlockRandomised = ReadBit(); + state.OrigPtr = ReadBits(kNumOrigBits); + + // in original code it compares OrigPtr to (UInt32)(10 + blockSizeMax)) : why ? + if (state.OrigPtr >= blockSizeMax) + return S_FALSE; - - int result = bzStream.Init(0, 0); - switch(result) + CMtf8Decoder mtf; + int numInUse = 0; { - case BZ_OK: - break; - case BZ_MEM_ERROR: - return E_OUTOFMEMORY; - default: - return E_FAIL; + bool inUse16[16]; + int i; + for (i = 0; i < 16; i++) + inUse16[i] = ReadBit(); + for (i = 0; i < 256; i++) + if (inUse16[i >> 4]) + if (ReadBit()) + mtf.Buffer[numInUse++] = (Byte)i; + if (numInUse == 0) + return S_FALSE; + mtf.Init(numInUse); } - CBZip2DecompressorReleaser releaser(&bzStream); - bzStream.avail_in = 0; - while (true) + int alphaSize = numInUse + 2; + + int numTables = ReadBits(kNumTablesBits); + if (numTables < kNumTablesMin || numTables > kNumTablesMax) + return S_FALSE; + + UInt32 numSelectors = ReadBits(kNumSelectorsBits); + if (numSelectors < 1 || numSelectors > kNumSelectorsMax) + return S_FALSE; + { - if (bzStream.avail_in == 0) + Byte mtfPos[kNumTablesMax]; + int t = 0; + do + mtfPos[t] = (Byte)t; + while(++t < numTables); + UInt32 i = 0; + do { - bzStream.next_in = (char *)m_InBuffer; - UINT32 processedSize; - RINOK(inStream->Read(m_InBuffer, kBufferSize, &processedSize)); - bzStream.avail_in = processedSize; + int j = 0; + while (ReadBit()) + if (++j >= numTables) + return S_FALSE; + Byte tmp = mtfPos[j]; + for (;j > 0; j--) + mtfPos[j] = mtfPos[j - 1]; + state.m_Selectors[i] = mtfPos[0] = tmp; } + while(++i < numSelectors); + } - bzStream.next_out = (char *)m_OutBuffer; - bzStream.avail_out = kBufferSize; - result = bzStream.Decompress(); - UINT32 numBytesToWrite = kBufferSize - bzStream.avail_out; - if (numBytesToWrite > 0) + int t = 0; + do + { + Byte lens[kMaxAlphaSize]; + int len = (int)ReadBits(kNumLevelsBits); + int i; + for (i = 0; i < alphaSize; i++) { - UINT32 processedSize; - RINOK(outStream->Write(m_OutBuffer, numBytesToWrite, &processedSize)); - if (numBytesToWrite != processedSize) - return E_FAIL; + while (true) + { + if (len < 1 || len > kMaxHuffmanLen) + return S_FALSE; + if (!ReadBit()) + break; + if (ReadBit()) + len--; + else + len++; + } + lens[i] = (Byte)len; } + for (; i < kMaxAlphaSize; i++) + lens[i] = 0; + m_HuffmanDecoders[t].SetCodeLengths(lens); + } + while(++t < numTables); - if (result == BZ_STREAM_END) - break; - switch(result) + { + for (int i = 0; i < 256; i++) + state.CharCounters[i] = 0; + } + + UInt32 blockSize = 0; + { + UInt32 groupIndex = 0; + UInt32 groupSize = 0; + CHuffmanDecoder *huffmanDecoder = 0; + int runPower = 0; + UInt32 runCounter = 0; + + while (true) { - case BZ_DATA_ERROR: - case BZ_DATA_ERROR_MAGIC: - return S_FALSE; - case BZ_OK: + if (groupSize == 0) + { + if (groupIndex >= numSelectors) + return S_FALSE; + groupSize = kGroupSize; + huffmanDecoder = &m_HuffmanDecoders[state.m_Selectors[groupIndex++]]; + } + groupSize--; \ + + int nextSym = (int)huffmanDecoder->DecodeSymbol(&m_InStream); + + if (nextSym < 2) + { + runCounter += ((UInt32)(nextSym + 1) << runPower++); + if (blockSizeMax - blockSize < runCounter) + return S_FALSE; + continue; + } + if (runCounter != 0) + { + Byte b = mtf.GetHead(); + state.CharCounters[b] += runCounter; + do + state.tt[blockSize++] = (UInt32)b; + while(--runCounter != 0); + runPower = 0; + } + if (nextSym > numInUse) break; - case BZ_MEM_ERROR: - return E_OUTOFMEMORY; - default: - return E_FAIL; + Byte b = mtf.GetAndMove(nextSym - 1); + if (blockSize >= blockSizeMax) + return S_FALSE; + state.CharCounters[b]++; + state.tt[blockSize++] = (UInt32)b; } - if (progress != NULL) + } + if (state.OrigPtr >= blockSize) + return S_FALSE; + state.BlockSize = blockSize; + return S_OK; +} + +HRESULT CState::DecodeBlock(COutBuffer &m_OutStream) +{ + UInt32 *charCounters = this->CharCounters; + { + UInt32 sum = 0; + for (UInt32 i = 0; i < 256; i++) { - UINT64 totalIn = bzStream.GetTotalIn(); - UINT64 totalOut = bzStream.GetTotalOut(); - RINOK(progress->SetRatioInfo(&totalIn, &totalOut)); + sum += charCounters[i]; + charCounters[i] = sum - charCounters[i]; } } - // result = bzStream.End(); + + // Compute the T^(-1) vector + UInt32 blockSize = this->BlockSize; + UInt32 i = 0; + do + tt[charCounters[tt[i] & 0xFF]++] |= (i << 8); + while(++i < blockSize); - return S_OK; + // Decode + + CBZip2CRC crc; + + UInt32 randIndex = 1; + UInt32 randToGo = kRandNums[0] - 2; + + int numReps = 0; + + // it's for speed optimization: prefetch & prevByte_init; + UInt32 tPos = tt[tt[OrigPtr] >> 8]; + Byte prevByte = (Byte)(tPos & 0xFF); + + do + { + Byte b = (Byte)(tPos & 0xFF); + tPos = tt[tPos >> 8]; + + if (BlockRandomised) + { + if (randToGo == 0) + { + b ^= 1; + randToGo = kRandNums[randIndex++]; + randIndex &= 0x1FF; + } + randToGo--; + } + + if (numReps == kRleModeRepSize) + { + for (; b > 0; b--) + { + crc.UpdateByte(prevByte); + m_OutStream.WriteByte(prevByte); + } + numReps = 0; + continue; + } + if (prevByte == b) + numReps++; + else + { + numReps = 1; + prevByte = b; + } + crc.UpdateByte(b); + m_OutStream.WriteByte(b); + } + while(--blockSize != 0); + return (StoredCRC == crc.GetDigest()) ? S_OK : S_FALSE; +} + +HRESULT CDecoder::DecodeFile(bool &isBZ, ICompressProgressInfo *progress) +{ + isBZ = false; + Byte s[6]; + int i; + for (i = 0; i < 4; i++) + s[i] = ReadByte(); + if (s[0] != kArSig0 || + s[1] != kArSig1 || + s[2] != kArSig2 || + s[3] <= kArSig3 || + s[3] > kArSig3 + kBlockSizeMultMax) + return S_OK; + isBZ = true; + UInt32 dicSize = (UInt32)(s[3] - kArSig3) * kBlockSizeStep; + + if (!m_State.Alloc()) + return E_OUTOFMEMORY; + + CBZip2CombinedCRC computedCombinedCRC; + while (true) + { + if (progress) + { + UInt64 packSize = m_InStream.GetProcessedSize(); + UInt64 unpackSize = m_OutStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &unpackSize)); + } + + for (i = 0; i < 6; i++) + s[i] = ReadByte(); + UInt32 crc = ReadCRC(); + if (s[0] == kFinSig0) + { + if (s[1] != kFinSig1 || + s[2] != kFinSig2 || + s[3] != kFinSig3 || + s[4] != kFinSig4 || + s[5] != kFinSig5) + return S_FALSE; + + return (crc == computedCombinedCRC.GetDigest()) ? S_OK : S_FALSE; + } + if (s[0] != kBlockSig0 || + s[1] != kBlockSig1 || + s[2] != kBlockSig2 || + s[3] != kBlockSig3 || + s[4] != kBlockSig4 || + s[5] != kBlockSig5) + return S_FALSE; + m_State.StoredCRC = crc; + computedCombinedCRC.Update(crc); + RINOK(ReadBlock(dicSize, m_State)); + RINOK(m_State.DecodeBlock(m_OutStream)); + } +} + +HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + if (!m_InStream.Create(kBufferSize)) + return E_OUTOFMEMORY; + if (!m_OutStream.Create(kBufferSize)) + return E_OUTOFMEMORY; + + m_InStream.SetStream(inStream); + m_InStream.Init(); + + m_OutStream.SetStream(outStream); + m_OutStream.Init(); + + CDecoderFlusher flusher(this); + + bool isBZ; + RINOK(DecodeFile(isBZ, progress)); + return isBZ ? S_OK: S_FALSE; } STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { try { return CodeReal(inStream, outStream, inSize, outSize, progress); } catch(...) { return S_FALSE; } } +STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value) +{ + if (value == NULL) + return E_INVALIDARG; + *value = m_InStream.GetProcessedSize(); + return S_OK; +} + }} diff --git a/7zip/Compress/BZip2/BZip2Decoder.h b/7zip/Compress/BZip2/BZip2Decoder.h index 962da55e..0eb73130 100755 --- a/7zip/Compress/BZip2/BZip2Decoder.h +++ b/7zip/Compress/BZip2/BZip2Decoder.h @@ -1,39 +1,88 @@ // Compress/BZip2/Decoder.h -#pragma once - #ifndef __COMPRESS_BZIP2_DECODER_H #define __COMPRESS_BZIP2_DECODER_H #include "../../ICoder.h" -// #include "../../Interface/CompressInterface.h" -#include "Common/MyCom.h" +#include "../../../Common/MyCom.h" +#include "../../Common/MSBFDecoder.h" +#include "../../Common/InBuffer.h" +#include "../../Common/OutBuffer.h" +#include "../Huffman/HuffmanDecoder.h" +#include "BZip2Const.h" namespace NCompress { namespace NBZip2 { +typedef NCompress::NHuffman::CDecoder<kMaxHuffmanLen, kMaxAlphaSize> CHuffmanDecoder; + +struct CState +{ + UInt32 *tt; + bool BlockRandomised; + UInt32 OrigPtr; + UInt32 BlockSize; + UInt32 CharCounters[256]; + Byte m_Selectors[kNumSelectorsMax]; + UInt32 StoredCRC; + + CState(): tt(0) {} + ~CState(); + bool Alloc(); + HRESULT DecodeBlock(COutBuffer &m_OutStream); +}; + class CDecoder : public ICompressCoder, + public ICompressGetInStreamProcessedSize, public CMyUnknownImp { - BYTE *m_InBuffer; - BYTE *m_OutBuffer; -public: - CDecoder(); - ~CDecoder(); - - MY_UNKNOWN_IMP + NStream::NMSBF::CDecoder<CInBuffer> m_InStream; + COutBuffer m_OutStream; - HRESULT Flush(); - // void (ReleaseStreams)(); + CHuffmanDecoder m_HuffmanDecoders[kNumTablesMax]; + + CState m_State; - STDMETHOD(CodeReal)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + UInt32 ReadBits(int numBits); + Byte ReadByte(); + bool ReadBit(); + UInt32 ReadCRC(); + HRESULT ReadBlock(UInt32 blockSizeMax, CState &state); + HRESULT PrepareBlock(CState &state); + HRESULT DecodeFile(bool &isBZ, ICompressProgressInfo *progress); + HRESULT CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + class CDecoderFlusher + { + CDecoder *_decoder; + public: + bool NeedFlush; + CDecoderFlusher(CDecoder *decoder): _decoder(decoder), NeedFlush(true) {} + ~CDecoderFlusher() + { + if (NeedFlush) + _decoder->Flush(); + _decoder->ReleaseStreams(); + } + }; +public: + HRESULT Flush() { return m_OutStream.Flush(); } + void ReleaseStreams() + { + m_InStream.ReleaseStream(); + m_OutStream.ReleaseStream(); + } + + MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize) + STDMETHOD(Code)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + + STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); }; }} diff --git a/7zip/Compress/BZip2/BZip2Encoder.cpp b/7zip/Compress/BZip2/BZip2Encoder.cpp index b3525fe7..657fcfb2 100755 --- a/7zip/Compress/BZip2/BZip2Encoder.cpp +++ b/7zip/Compress/BZip2/BZip2Encoder.cpp @@ -2,119 +2,632 @@ #include "StdAfx.h" -#include "Windows/Defs.h" #include "BZip2Encoder.h" -#include "Original/bzlib.h" + +#include "../../../Common/Alloc.h" +#include "../BWT/Mtf8.h" +#include "BZip2CRC.h" namespace NCompress { namespace NBZip2 { -static const UINT32 kBufferSize = (1 << 20); +static const UInt32 kBufferSize = (1 << 17); +static const int kNumHuffPasses = 4; -CEncoder::CEncoder() -{ - m_InBuffer = new BYTE[kBufferSize]; - m_OutBuffer = new BYTE[kBufferSize]; -} +CEncoder::CEncoder(): + m_Block(0), + m_NeedHuffmanCreate(true), + m_NumPasses(1), + m_OptimizeNumTables(false), + m_BlockSizeMult(kBlockSizeMultMax) +{} CEncoder::~CEncoder() { - delete []m_OutBuffer; - delete []m_InBuffer; + ::BigFree(m_Block); } -struct CBZip2Compressor: public bz_stream -{ -public: - int Init(int blockSize100k, int verbosity, int small) - { return BZ2_bzCompressInit(this, blockSize100k, verbosity, small); } - int Compress(int action ) { return BZ2_bzCompress(this, action ); } - int End() { return BZ2_bzCompressEnd(this); } - UINT64 GetTotalIn() const { return (UINT64(total_in_hi32) << 32) + total_in_lo32; } - UINT64 GetTotalOut() const { return (UINT64(total_out_hi32) << 32) + total_out_lo32; } -}; - -class CBZip2CompressorReleaser +UInt32 CEncoder::ReadRleBlock(Byte *buffer) { - CBZip2Compressor *m_Compressor; -public: - CBZip2CompressorReleaser(CBZip2Compressor *compressor): m_Compressor(compressor) {} - void Disable() { m_Compressor = NULL; } - ~CBZip2CompressorReleaser() { if (m_Compressor != NULL) m_Compressor->End(); } -}; + UInt32 i = 0; + Byte prevByte; + if (m_InStream.ReadByte(prevByte)) + { + UInt32 blockSize = m_BlockSizeMult * kBlockSizeStep - 1; + int numReps = 1; + buffer[i++] = prevByte; + while (i < blockSize) // "- 1" to support RLE + { + Byte b; + if (!m_InStream.ReadByte(b)) + break; + if (b != prevByte) + { + if (numReps >= kRleModeRepSize) + buffer[i++] = numReps - kRleModeRepSize; + buffer[i++] = b; + numReps = 1; + prevByte = b; + continue; + } + numReps++; + if (numReps <= kRleModeRepSize) + buffer[i++] = b; + else if (numReps == kRleModeRepSize + 255) + { + buffer[i++] = numReps - kRleModeRepSize; + numReps = 0; + } + } + // it's to support original BZip2 decoder + if (numReps >= kRleModeRepSize) + buffer[i++] = numReps - kRleModeRepSize; + } + return i; +} +void CEncoder::WriteBits2(UInt32 value, UInt32 numBits) + { m_OutStreamCurrent->WriteBits(value, numBits); } +void CEncoder::WriteByte2(Byte b) { WriteBits2(b , 8); } +void CEncoder::WriteBit2(bool v) { WriteBits2((v ? 1 : 0), 1); } +void CEncoder::WriteCRC2(UInt32 v) +{ + for (int i = 0; i < 4; i++) + WriteByte2(((Byte)(v >> (24 - i * 8)))); +} -STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, - ICompressProgressInfo *progress) +void CEncoder::WriteBits(UInt32 value, UInt32 numBits) + { m_OutStream.WriteBits(value, numBits); } +void CEncoder::WriteByte(Byte b) { WriteBits(b , 8); } +void CEncoder::WriteBit(bool v) { WriteBits((v ? 1 : 0), 1); } +void CEncoder::WriteCRC(UInt32 v) +{ + for (int i = 0; i < 4; i++) + WriteByte(((Byte)(v >> (24 - i * 8)))); +} + + +// blockSize > 0 +void CEncoder::EncodeBlock(Byte *block, UInt32 blockSize) { - CBZip2Compressor bzStream; - bzStream.bzalloc = NULL; - bzStream.bzfree = NULL; - bzStream.opaque = NULL; + WriteBit2(false); // Randomised = false + + { + UInt32 origPtr = m_BlockSorter.Sort(block, blockSize); + WriteBits2(origPtr, kNumOrigBits); + } - int result = bzStream.Init(9, 0, 0); - switch(result) + CMtf8Encoder mtf; + int numInUse = 0; { - case BZ_OK: - break; - case BZ_MEM_ERROR: - return E_OUTOFMEMORY; - default: - return E_FAIL; + bool inUse[256]; + bool inUse16[16]; + UInt32 i; + for (i = 0; i < 256; i++) + inUse[i] = false; + for (i = 0; i < 16; i++) + inUse16[i] = false; + for (i = 0; i < blockSize; i++) + inUse[block[i]] = true; + for (i = 0; i < 256; i++) + if (inUse[i]) + { + inUse16[i >> 4] = true; + mtf.Buffer[numInUse++] = (Byte)i; + } + for (i = 0; i < 16; i++) + WriteBit2(inUse16[i]); + for (i = 0; i < 256; i++) + if (inUse16[i >> 4]) + WriteBit2(inUse[i]); } - CBZip2CompressorReleaser releaser(&bzStream); - bzStream.avail_in = 0; - while (true) + int alphaSize = numInUse + 2; + + Byte *mtfs = m_MtfArray; + UInt32 mtfArraySize = 0; + UInt32 symbolCounts[kMaxAlphaSize]; { - if (bzStream.avail_in == 0) + for (int i = 0; i < kMaxAlphaSize; i++) + symbolCounts[i] = 0; + } + + { + UInt32 rleSize = 0; + UInt32 i = 0; + do { - bzStream.next_in = (char *)m_InBuffer; - UINT32 processedSize; - RINOK(inStream->Read(m_InBuffer, kBufferSize, &processedSize)); - bzStream.avail_in = processedSize; + UInt32 index = m_BlockSorter.Indices[i]; + if (index == 0) + index = blockSize - 1; + else + index--; + int pos = mtf.FindAndMove(block[index]); + if (pos == 0) + rleSize++; + else + { + while (rleSize != 0) + { + rleSize--; + mtfs[mtfArraySize++] = (rleSize & 1); + symbolCounts[rleSize & 1]++; + rleSize >>= 1; + } + if (pos >= 0xFE) + { + mtfs[mtfArraySize++] = 0xFF; + mtfs[mtfArraySize++] = pos - 0xFE; + } + else + mtfs[mtfArraySize++] = pos + 1; + symbolCounts[pos + 1]++; + } } + while (++i < blockSize); - bzStream.next_out = (char *)m_OutBuffer; - bzStream.avail_out = kBufferSize; - bool askFinish = (bzStream.avail_in == 0); - result = bzStream.Compress(askFinish ? BZ_FINISH : BZ_RUN); - UINT32 numBytesToWrite = kBufferSize - bzStream.avail_out; - if (numBytesToWrite > 0) + while (rleSize != 0) { - UINT32 processedSize; - RINOK(outStream->Write(m_OutBuffer, numBytesToWrite, &processedSize)); - if (numBytesToWrite != processedSize) - return E_FAIL; + rleSize--; + mtfs[mtfArraySize++] = (rleSize & 1); + symbolCounts[rleSize & 1]++; + rleSize >>= 1; } - if (result == BZ_STREAM_END) + if (alphaSize < 256) + mtfs[mtfArraySize++] = (Byte)(alphaSize - 1); + else + { + mtfs[mtfArraySize++] = 0xFF; + mtfs[mtfArraySize++] = (Byte)(alphaSize - 256); + } + symbolCounts[alphaSize - 1]++; + } + + UInt32 numSymbols = 0; + { + for (int i = 0; i < kMaxAlphaSize; i++) + numSymbols += symbolCounts[i]; + } + + int bestNumTables = kNumTablesMin; + UInt32 bestPrice = 0xFFFFFFFF; + UInt32 startPos = m_OutStreamCurrent->GetPos(); + UInt32 startCurByte = m_OutStreamCurrent->GetCurByte(); + for (int nt = kNumTablesMin; nt <= kNumTablesMax + 1; nt++) + { + int numTables; + + if(m_OptimizeNumTables) + { + m_OutStreamCurrent->SetPos(startPos); + m_OutStreamCurrent->SetCurState((startPos & 7), startCurByte); + if (nt <= kNumTablesMax) + numTables = nt; + else + numTables = bestNumTables; + } + else + { + if (numSymbols < 200) numTables = 2; + else if (numSymbols < 600) numTables = 3; + else if (numSymbols < 1200) numTables = 4; + else if (numSymbols < 2400) numTables = 5; + else numTables = 6; + } + + WriteBits2(numTables, kNumTablesBits); + + UInt32 numSelectors = (numSymbols + kGroupSize - 1) / kGroupSize; + WriteBits2(numSelectors, kNumSelectorsBits); + + { + UInt32 remFreq = numSymbols; + int gs = 0; + int t = numTables; + do + { + UInt32 tFreq = remFreq / t; + int ge = gs; + UInt32 aFreq = 0; + while (aFreq < tFreq) // && ge < alphaSize) + aFreq += symbolCounts[ge++]; + + if (ge - 1 > gs && t != numTables && t != 1 && (((numTables - t) & 1) == 1)) + aFreq -= symbolCounts[--ge]; + + NCompression::NHuffman::CEncoder &huffEncoder = m_HuffEncoders[t - 1]; + int i = 0; + do + huffEncoder.m_Items[i].Len = (i >= gs && i < ge) ? 0 : 1; + while (++i < alphaSize); + gs = ge; + remFreq -= aFreq; + } + while(--t != 0); + } + + + for (int pass = 0; pass < kNumHuffPasses; pass++) + { + { + int t = 0; + do + m_HuffEncoders[t].StartNewBlock(); + while(++t < numTables); + } + + { + UInt32 mtfPos = 0; + UInt32 g = 0; + do + { + UInt32 symbols[kGroupSize]; + int i = 0; + do + { + UInt32 symbol = mtfs[mtfPos++]; + if (symbol >= 0xFF) + symbol += mtfs[mtfPos++]; + symbols[i] = symbol; + } + while (++i < kGroupSize && mtfPos < mtfArraySize); + + UInt32 bestPrice = 0xFFFFFFFF; + int t = 0; + do + { + NCompression::NHuffman::CItem *items = m_HuffEncoders[t].m_Items; + UInt32 price = 0; + int j = 0; + do + price += items[symbols[j]].Len; + while (++j < i); + if (price < bestPrice) + { + m_Selectors[g] = (Byte)t; + bestPrice = price; + } + } + while(++t < numTables); + NCompression::NHuffman::CEncoder &huffEncoder = m_HuffEncoders[m_Selectors[g++]]; + int j = 0; + do + huffEncoder.AddSymbol(symbols[j]); + while (++j < i); + } + while (mtfPos < mtfArraySize); + } + + int t = 0; + do + { + NCompression::NHuffman::CEncoder &huffEncoder = m_HuffEncoders[t]; + int i = 0; + do + if (huffEncoder.m_Items[i].Freq == 0) + huffEncoder.m_Items[i].Freq = 1; + while(++i < alphaSize); + Byte levels[kMaxAlphaSize]; + huffEncoder.BuildTree(levels); + } + while(++t < numTables); + } + + { + Byte mtfSel[kNumTablesMax]; + { + int t = 0; + do + mtfSel[t] = (Byte)t; + while(++t < numTables); + } + + UInt32 i = 0; + do + { + Byte sel = m_Selectors[i]; + int pos; + for (pos = 0; mtfSel[pos] != sel; pos++) + WriteBit2(true); + WriteBit2(false); + for (; pos > 0; pos--) + mtfSel[pos] = mtfSel[pos - 1]; + mtfSel[0] = sel; + } + while(++i < numSelectors); + } + + { + int t = 0; + do + { + NCompression::NHuffman::CItem *items = m_HuffEncoders[t].m_Items; + UInt32 len = items[0].Len; + WriteBits2(len, kNumLevelsBits); + int i = 0; + do + { + UInt32 level = items[i].Len; + while (len != level) + { + WriteBit2(true); + if (len < level) + { + WriteBit2(false); + len++; + } + else + { + WriteBit2(true); + len--; + } + } + WriteBit2(false); + } + while (++i < alphaSize); + } + while(++t < numTables); + } + + { + UInt32 groupSize = 0; + UInt32 groupIndex = 0; + NCompression::NHuffman::CEncoder *huffEncoder = 0; + UInt32 mtfPos = 0; + do + { + UInt32 symbol = mtfs[mtfPos++]; + if (symbol >= 0xFF) + symbol += mtfs[mtfPos++]; + if (groupSize == 0) + { + groupSize = kGroupSize; + huffEncoder = &m_HuffEncoders[m_Selectors[groupIndex++]]; + } + groupSize--; \ + huffEncoder->CodeOneValue(m_OutStreamCurrent, symbol); + } + while (mtfPos < mtfArraySize); + } + + if (!m_OptimizeNumTables) break; - switch(result) - { - case BZ_RUN_OK: - if (!askFinish) - break; - return E_FAIL; - case BZ_FINISH_OK: - if (askFinish) - break; - return E_FAIL; - case BZ_MEM_ERROR: - return E_OUTOFMEMORY; - default: - return E_FAIL; + UInt32 price = m_OutStreamCurrent->GetPos() - startPos; + if (price <= bestPrice) + { + if (nt == kNumTablesMax) + break; + bestPrice = price; + bestNumTables = nt; + } + } +} + +// blockSize > 0 +UInt32 CEncoder::EncodeBlockWithHeaders(Byte *block, UInt32 blockSize) +{ + WriteByte2(kBlockSig0); + WriteByte2(kBlockSig1); + WriteByte2(kBlockSig2); + WriteByte2(kBlockSig3); + WriteByte2(kBlockSig4); + WriteByte2(kBlockSig5); + + CBZip2CRC crc; + int numReps = 0; + Byte prevByte = block[0]; + UInt32 i = 0; + do + { + Byte b = block[i]; + if (numReps == kRleModeRepSize) + { + for (; b > 0; b--) + crc.UpdateByte(prevByte); + numReps = 0; + continue; + } + if (prevByte == b) + numReps++; + else + { + numReps = 1; + prevByte = b; + } + crc.UpdateByte(b); + } + while (++i < blockSize); + UInt32 crcRes = crc.GetDigest(); + WriteCRC2(crcRes); + EncodeBlock(block, blockSize); + return crcRes; +} + +void CEncoder::EncodeBlock2(CBZip2CombinedCRC &combinedCRC, + Byte *block, UInt32 blockSize, UInt32 numPasses) +{ + bool needCompare = false; + CBZip2CombinedCRC specCombinedCRC = combinedCRC; + + UInt32 startBytePos = m_OutStreamCurrent->GetBytePos(); + UInt32 startPos = m_OutStreamCurrent->GetPos(); + UInt32 startCurByte = m_OutStreamCurrent->GetCurByte(); + UInt32 endCurByte; + UInt32 endPos; + if (numPasses > 1 && blockSize >= (1 << 10)) + { + UInt32 blockSize0 = blockSize / 2; + for (;(block[blockSize0] == block[blockSize0 - 1] || + block[blockSize0 - 1] == block[blockSize0 - 2]) && + blockSize0 < blockSize; blockSize0++); + if (blockSize0 < blockSize) + { + EncodeBlock2(specCombinedCRC, block, blockSize0, numPasses - 1); + EncodeBlock2(specCombinedCRC, block + blockSize0, blockSize - blockSize0, + numPasses - 1); + endPos = m_OutStreamCurrent->GetPos(); + endCurByte = m_OutStreamCurrent->GetCurByte(); + if ((endPos & 7) > 0) + WriteBits2(0, 8 - (endPos & 7)); + m_OutStreamCurrent->SetCurState((startPos & 7), startCurByte); + needCompare = true; + } + } + + UInt32 startBytePos2 = m_OutStreamCurrent->GetBytePos(); + UInt32 startPos2 = m_OutStreamCurrent->GetPos(); + UInt32 crcVal = EncodeBlockWithHeaders(block, blockSize); + UInt32 endPos2 = m_OutStreamCurrent->GetPos(); + + combinedCRC.Update(crcVal); + + if (needCompare) + { + UInt32 size2 = endPos2 - startPos2; + if (size2 < endPos - startPos) + { + UInt32 numBytes = m_OutStreamCurrent->GetBytePos() - startBytePos2; + Byte *buffer = m_OutStreamCurrent->GetStream(); + for (UInt32 i = 0; i < numBytes; i++) + buffer[startBytePos + i] = buffer[startBytePos2 + i]; + m_OutStreamCurrent->SetPos(startPos + endPos2 - startPos2); } - if (progress != NULL) + else { - UINT64 totalIn = bzStream.GetTotalIn(); - UINT64 totalOut = bzStream.GetTotalOut(); - RINOK(progress->SetRatioInfo(&totalIn, &totalOut)); + m_OutStreamCurrent->SetPos(endPos); + m_OutStreamCurrent->SetCurState((endPos & 7), endCurByte); + combinedCRC = specCombinedCRC; } } - // result = bzStream.End(); +} + +void CEncoder::EncodeBlock3(CBZip2CombinedCRC &combinedCRC, UInt32 blockSize) +{ + CMsbfEncoderTemp outStreamTemp; + outStreamTemp.SetStream(m_TempArray); + outStreamTemp.Init(); + m_OutStreamCurrent = &outStreamTemp; + + EncodeBlock2(combinedCRC, m_Block, blockSize, m_NumPasses); + + UInt32 size = outStreamTemp.GetPos(); + UInt32 bytesSize = (size / 8); + for (UInt32 i = 0; i < bytesSize; i++) + m_OutStream.WriteBits(m_TempArray[i], 8); + WriteBits(outStreamTemp.GetCurByte(), (size & 7)); +} + +HRESULT CEncoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + if (!m_BlockSorter.Create(kBlockSizeMax)) + return E_OUTOFMEMORY; + + if (m_Block == 0) + { + m_Block = (Byte *)BigAlloc(kBlockSizeMax * 5 + kBlockSizeMax / 10 + (20 << 10)); + if (m_Block == 0) + return E_OUTOFMEMORY; + m_MtfArray = m_Block + kBlockSizeMax; + m_TempArray = m_MtfArray + kBlockSizeMax * 2 + 2; + } + if (!m_InStream.Create(kBufferSize)) + return E_OUTOFMEMORY; + if (!m_OutStream.Create(kBufferSize)) + return E_OUTOFMEMORY; + + if (m_NeedHuffmanCreate) + { + for (int i = 0; i < kNumTablesMax; i++) + if (!m_HuffEncoders[i].Create(kMaxAlphaSize, 0, 0, kMaxHuffmanLen)) + return E_OUTOFMEMORY; + m_NeedHuffmanCreate = false; + } + + m_InStream.SetStream(inStream); + m_InStream.Init(); + + m_OutStream.SetStream(outStream); + m_OutStream.Init(); + + CFlusher flusher(this); + + CBZip2CombinedCRC combinedCRC; + + WriteByte(kArSig0); + WriteByte(kArSig1); + WriteByte(kArSig2); + WriteByte((Byte)(kArSig3 + m_BlockSizeMult)); + + while (true) + { + UInt32 blockSize = ReadRleBlock(m_Block); + if (blockSize == 0) + break; + EncodeBlock3(combinedCRC, blockSize); + if (progress) + { + UInt64 packSize = m_InStream.GetProcessedSize(); + UInt64 unpackSize = m_OutStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &unpackSize)); + } + } + WriteByte(kFinSig0); + WriteByte(kFinSig1); + WriteByte(kFinSig2); + WriteByte(kFinSig3); + WriteByte(kFinSig4); + WriteByte(kFinSig5); + + WriteCRC(combinedCRC.GetDigest()); return S_OK; } +STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + catch(...) { return S_FALSE; } +} + +HRESULT CEncoder::SetCoderProperties(const PROPID *propIDs, + const PROPVARIANT *properties, UInt32 numProperties) +{ + for(UInt32 i = 0; i < numProperties; i++) + { + const PROPVARIANT &property = properties[i]; + switch(propIDs[i]) + { + case NCoderPropID::kNumPasses: + { + if (property.vt != VT_UI4) + return E_INVALIDARG; + UInt32 numPasses = property.ulVal; + if(numPasses == 0 || numPasses > 10) + return E_INVALIDARG; + m_NumPasses = numPasses; + m_OptimizeNumTables = (m_NumPasses > 1); + break; + } + case NCoderPropID::kDictionarySize: + { + if (property.vt != VT_UI4) + return E_INVALIDARG; + UInt32 dictionary = property.ulVal / kBlockSizeStep; + if (dictionary < kBlockSizeMultMin) + dictionary = kBlockSizeMultMin; + else if (dictionary > kBlockSizeMultMax) + dictionary = kBlockSizeMultMax; + m_BlockSizeMult = dictionary; + break; + } + default: + return E_INVALIDARG; + } + } + return S_OK; +} }} diff --git a/7zip/Compress/BZip2/BZip2Encoder.h b/7zip/Compress/BZip2/BZip2Encoder.h index c3617e3f..7eca18a0 100755 --- a/7zip/Compress/BZip2/BZip2Encoder.h +++ b/7zip/Compress/BZip2/BZip2Encoder.h @@ -1,34 +1,158 @@ // Compress/BZip2/Encoder.h -#pragma once - #ifndef __COMPRESS_BZIP2_ENCODER_H #define __COMPRESS_BZIP2_ENCODER_H -#include "Common/MyCom.h" #include "../../ICoder.h" - +#include "../../../Common/MyCom.h" +#include "../../Common/MSBFEncoder.h" +#include "../../Common/InBuffer.h" +#include "../../Common/OutBuffer.h" +#include "../Huffman/HuffmanEncoder.h" +#include "../BWT/BlockSort.h" +#include "BZip2Const.h" +#include "BZip2CRC.h" + namespace NCompress { namespace NBZip2 { +class CMsbfEncoderTemp +{ + UInt32 m_Pos; + int m_BitPos; + Byte m_CurByte; + Byte *Buffer; +public: + void SetStream(Byte *buffer) { Buffer = buffer; } + Byte *GetStream() const { return Buffer; } + + void Init() + { + m_Pos = 0; + m_BitPos = 8; + m_CurByte = 0; + } + + void Flush() + { + if(m_BitPos < 8) + WriteBits(0, m_BitPos); + } + + void WriteBits(UInt32 value, int numBits) + { + while(numBits > 0) + { + int numNewBits = MyMin(numBits, m_BitPos); + numBits -= numNewBits; + + m_CurByte <<= numNewBits; + UInt32 newBits = value >> numBits; + m_CurByte |= Byte(newBits); + value -= (newBits << numBits); + + m_BitPos -= numNewBits; + + if (m_BitPos == 0) + { + Buffer[m_Pos++] = m_CurByte; + m_BitPos = 8; + } + } + } + + UInt32 GetBytePos() const { return m_Pos ; } + UInt32 GetPos() const { return m_Pos * 8 + (8 - m_BitPos); } + Byte GetCurByte() const { return m_CurByte; } + void SetPos(UInt32 bitPos) + { + m_Pos = bitPos / 8; + m_BitPos = 8 - (bitPos & 7); + } + void SetCurState(UInt32 bitPos, Byte curByte) + { + m_BitPos = 8 - bitPos; + m_CurByte = curByte; + } +}; + class CEncoder : public ICompressCoder, + public ICompressSetCoderProperties, public CMyUnknownImp { - BYTE *m_InBuffer; - BYTE *m_OutBuffer; + Byte *m_Block; + CInBuffer m_InStream; + NStream::NMSBF::CEncoder<COutBuffer> m_OutStream; + CMsbfEncoderTemp *m_OutStreamCurrent; + CBlockSorter m_BlockSorter; + + bool m_NeedHuffmanCreate; + NCompression::NHuffman::CEncoder m_HuffEncoders[kNumTablesMax]; + + Byte *m_MtfArray; + Byte *m_TempArray; + + Byte m_Selectors[kNumSelectorsMax]; + + UInt32 m_BlockSizeMult; + UInt32 m_NumPasses; + bool m_OptimizeNumTables; + + UInt32 ReadRleBlock(Byte *buffer); + + void WriteBits2(UInt32 value, UInt32 numBits); + void WriteByte2(Byte b); + void WriteBit2(bool v); + void WriteCRC2(UInt32 v); + + void WriteBits(UInt32 value, UInt32 numBits); + void WriteByte(Byte b); + void WriteBit(bool v); + void WriteCRC(UInt32 v); + + void EncodeBlock(Byte *block, UInt32 blockSize); + UInt32 EncodeBlockWithHeaders(Byte *block, UInt32 blockSize); + void EncodeBlock2(CBZip2CombinedCRC &combinedCRC, Byte *block, UInt32 blockSize, UInt32 numPasses); + void EncodeBlock3(CBZip2CombinedCRC &combinedCRC, UInt32 blockSize); public: CEncoder(); ~CEncoder(); - MY_UNKNOWN_IMP + HRESULT Flush() { return m_OutStream.Flush(); } + + void ReleaseStreams() + { + m_InStream.ReleaseStream(); + m_OutStream.ReleaseStream(); + } + + class CFlusher + { + CEncoder *_coder; + public: + bool NeedFlush; + CFlusher(CEncoder *coder): _coder(coder), NeedFlush(true) {} + ~CFlusher() + { + if (NeedFlush) + _coder->Flush(); + _coder->ReleaseStreams(); + } + }; + + MY_UNKNOWN_IMP1(ICompressSetCoderProperties) - // STDMETHOD(ReleaseStreams)(); + HRESULT CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); STDMETHOD(Code)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + STDMETHOD(SetCoderProperties)(const PROPID *propIDs, + const PROPVARIANT *properties, UInt32 numProperties); }; }} diff --git a/7zip/Compress/BZip2/DllExports.cpp b/7zip/Compress/BZip2/DllExports.cpp index 65e47107..1f28a07c 100755 --- a/7zip/Compress/BZip2/DllExports.cpp +++ b/7zip/Compress/BZip2/DllExports.cpp @@ -2,11 +2,11 @@ #include "StdAfx.h" -#define INITGUID +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" #include "BZip2Encoder.h" #include "BZip2Decoder.h" -#include "Common/ComTry.h" // {23170F69-40C1-278B-0402-020000000000} DEFINE_GUID(CLSID_CCompressBZip2Decoder, diff --git a/7zip/Compress/BZip2/StdAfx.cpp b/7zip/Compress/BZip2/StdAfx.cpp index 2550270c..d0feea85 100755 --- a/7zip/Compress/BZip2/StdAfx.cpp +++ b/7zip/Compress/BZip2/StdAfx.cpp @@ -1,3 +1,3 @@ // StdAfx.cpp -#include "stdafx.h" +#include "StdAfx.h" diff --git a/7zip/Compress/BZip2/StdAfx.h b/7zip/Compress/BZip2/StdAfx.h index a32fbed6..e7fb6986 100755 --- a/7zip/Compress/BZip2/StdAfx.h +++ b/7zip/Compress/BZip2/StdAfx.h @@ -1,8 +1,8 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> +#include "../../../Common/MyWindows.h" -#endif +#endif diff --git a/7zip/Compress/BZip2/resource.rc b/7zip/Compress/BZip2/resource.rc index 602aa511..073e4744 100755 --- a/7zip/Compress/BZip2/resource.rc +++ b/7zip/Compress/BZip2/resource.rc @@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,8,1,0 - PRODUCTVERSION 3,8,1,0 + FILEVERSION 4,19,0,0 + PRODUCTVERSION 4,19,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -85,14 +85,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", " \0" VALUE "FileDescription", "BZip2 Coder\0" - VALUE "FileVersion", "3, 8, 1, 0\0" + VALUE "FileVersion", "4, 19, 0, 0\0" VALUE "InternalName", "BZip2\0" - VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "BZip2.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "7-Zip\0" - VALUE "ProductVersion", "3, 8, 1, 0\0" + VALUE "ProductVersion", "4, 19, 0, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/7zip/Compress/BZip2Original/BZip2.def b/7zip/Compress/BZip2Original/BZip2.def new file mode 100755 index 00000000..c7169268 --- /dev/null +++ b/7zip/Compress/BZip2Original/BZip2.def @@ -0,0 +1,9 @@ +; BZip2.def + +LIBRARY BZip2.dll + +EXPORTS + CreateObject PRIVATE + GetNumberOfMethods PRIVATE + GetMethodProperty PRIVATE + diff --git a/7zip/Compress/BZip2Original/BZip2.dsp b/7zip/Compress/BZip2Original/BZip2.dsp new file mode 100755 index 00000000..9c0e2820 --- /dev/null +++ b/7zip/Compress/BZip2Original/BZip2.dsp @@ -0,0 +1,305 @@ +# Microsoft Developer Studio Project File - Name="BZip2" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=BZip2 - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "BZip2.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "BZip2.mak" CFG="BZip2 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "BZip2 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "BZip2 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "BZip2 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /D "BZ_NO_STDIO" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Codecs\BZip2.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Codecs\BZip2.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "BZip2 - Win32 Release" +# Name "BZip2 - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\BZip2.def +# End Source File +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.h +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Origianl" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\Original\blocksort.c + +!IF "$(CFG)" == "BZip2 - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\Original\bzlib.c + +!IF "$(CFG)" == "BZip2 - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\Original\bzlib.h +# End Source File +# Begin Source File + +SOURCE=.\Original\bzlib_private.h +# End Source File +# Begin Source File + +SOURCE=.\Original\compress.c + +!IF "$(CFG)" == "BZip2 - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\Original\crctable.c + +!IF "$(CFG)" == "BZip2 - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\Original\decompress.c + +!IF "$(CFG)" == "BZip2 - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\Original\huffman.c + +!IF "$(CFG)" == "BZip2 - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\Original\randtable.c + +!IF "$(CFG)" == "BZip2 - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\BZip2Decoder.cpp + +!IF "$(CFG)" == "BZip2 - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\BZip2Decoder.h +# End Source File +# Begin Source File + +SOURCE=.\BZip2Encoder.cpp + +!IF "$(CFG)" == "BZip2 - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\BZip2Encoder.h +# End Source File +# Begin Source File + +SOURCE=.\BZip2Error.cpp +# End Source File +# End Target +# End Project diff --git a/7zip/Compress/BZip2Original/BZip2.dsw b/7zip/Compress/BZip2Original/BZip2.dsw new file mode 100755 index 00000000..697e5095 --- /dev/null +++ b/7zip/Compress/BZip2Original/BZip2.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "BZip2"=.\BZip2.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/7zip/Compress/BZip2Original/BZip2Decoder.cpp b/7zip/Compress/BZip2Original/BZip2Decoder.cpp new file mode 100755 index 00000000..2f691f09 --- /dev/null +++ b/7zip/Compress/BZip2Original/BZip2Decoder.cpp @@ -0,0 +1,131 @@ +// BZip2Decoder.cpp + +#include "StdAfx.h" + +#include "BZip2Decoder.h" + +#include "../../../Common/Alloc.h" +#include "Original/bzlib.h" + +namespace NCompress { +namespace NBZip2 { + +static const UInt32 kBufferSize = (1 << 20); + +CDecoder::~CDecoder() +{ + BigFree(m_InBuffer); +} + +struct CBZip2Decompressor: public bz_stream +{ + int Init(int verbosity, int small) { return BZ2_bzDecompressInit(this, verbosity, small); } + int Decompress() { return BZ2_bzDecompress(this); } + int End() { return BZ2_bzDecompressEnd(this); } + UInt64 GetTotalIn() const { return (UInt64(total_in_hi32) << 32) + total_in_lo32; } + UInt64 GetTotalOut() const { return (UInt64(total_out_hi32) << 32) + total_out_lo32; } +}; + +class CBZip2DecompressorReleaser +{ + CBZip2Decompressor *m_Decompressor; +public: + CBZip2DecompressorReleaser(CBZip2Decompressor *decompressor): m_Decompressor(decompressor) {} + void Diable() { m_Decompressor = NULL; } + ~CBZip2DecompressorReleaser() { if (m_Decompressor != NULL) m_Decompressor->End(); } +}; + +STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + m_InSize = 0; + if (m_InBuffer == 0) + { + m_InBuffer = (Byte *)BigAlloc(kBufferSize * 2); + if (m_InBuffer == 0) + return E_OUTOFMEMORY; + } + Byte *outBuffer = m_InBuffer + kBufferSize; + + CBZip2Decompressor bzStream; + bzStream.bzalloc = NULL; + bzStream.bzfree = NULL; + bzStream.opaque = NULL; + + int result = bzStream.Init(0, 0); + switch(result) + { + case BZ_OK: + break; + case BZ_MEM_ERROR: + return E_OUTOFMEMORY; + default: + return E_FAIL; + } + CBZip2DecompressorReleaser releaser(&bzStream); + bzStream.avail_in = 0; + while (true) + { + if (bzStream.avail_in == 0) + { + bzStream.next_in = (char *)m_InBuffer; + UInt32 processedSize; + RINOK(inStream->Read(m_InBuffer, kBufferSize, &processedSize)); + bzStream.avail_in = processedSize; + } + + bzStream.next_out = (char *)outBuffer; + bzStream.avail_out = kBufferSize; + result = bzStream.Decompress(); + UInt32 numBytesToWrite = kBufferSize - bzStream.avail_out; + if (numBytesToWrite > 0) + { + UInt32 processedSize; + RINOK(outStream->Write(outBuffer, numBytesToWrite, &processedSize)); + if (numBytesToWrite != processedSize) + return E_FAIL; + } + + if (result == BZ_STREAM_END) + break; + switch(result) + { + case BZ_DATA_ERROR: + case BZ_DATA_ERROR_MAGIC: + return S_FALSE; + case BZ_OK: + break; + case BZ_MEM_ERROR: + return E_OUTOFMEMORY; + default: + return E_FAIL; + } + if (progress != NULL) + { + UInt64 totalIn = bzStream.GetTotalIn(); + UInt64 totalOut = bzStream.GetTotalOut(); + RINOK(progress->SetRatioInfo(&totalIn, &totalOut)); + } + } + m_InSize = bzStream.GetTotalIn(); + return S_OK; +} + +STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + catch(...) { return S_FALSE; } +} + +STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value) +{ + if (value == NULL) + return E_INVALIDARG; + *value = m_InSize; + return S_OK; +} + +}} diff --git a/7zip/Compress/BZip2Original/BZip2Decoder.h b/7zip/Compress/BZip2Original/BZip2Decoder.h new file mode 100755 index 00000000..e41f730f --- /dev/null +++ b/7zip/Compress/BZip2Original/BZip2Decoder.h @@ -0,0 +1,38 @@ +// Compress/BZip2/Decoder.h + +#ifndef __COMPRESS_BZIP2_DECODER_H +#define __COMPRESS_BZIP2_DECODER_H + +#include "../../ICoder.h" +#include "../../../Common/MyCom.h" + +namespace NCompress { +namespace NBZip2 { + +class CDecoder : + public ICompressCoder, + public ICompressGetInStreamProcessedSize, + public CMyUnknownImp +{ + Byte *m_InBuffer; + UInt64 m_InSize; +public: + CDecoder(): m_InBuffer(0), m_InSize(0) {}; + ~CDecoder(); + + MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize) + + STDMETHOD(CodeReal)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); +}; + +}} + +#endif diff --git a/7zip/Compress/BZip2Original/BZip2Encoder.cpp b/7zip/Compress/BZip2Original/BZip2Encoder.cpp new file mode 100755 index 00000000..4580347d --- /dev/null +++ b/7zip/Compress/BZip2Original/BZip2Encoder.cpp @@ -0,0 +1,120 @@ +// BZip2Encoder.cpp + +#include "StdAfx.h" + +#include "BZip2Encoder.h" + +#include "../../../Common/Alloc.h" +#include "Original/bzlib.h" + +namespace NCompress { +namespace NBZip2 { + +static const UInt32 kBufferSize = (1 << 20); + +CEncoder::~CEncoder() +{ + BigFree(m_InBuffer); +} + +struct CBZip2Compressor: public bz_stream +{ + int Init(int blockSize100k, int verbosity, int small) + { return BZ2_bzCompressInit(this, blockSize100k, verbosity, small); } + int Compress(int action ) { return BZ2_bzCompress(this, action ); } + int End() { return BZ2_bzCompressEnd(this); } + UInt64 GetTotalIn() const { return (UInt64(total_in_hi32) << 32) + total_in_lo32; } + UInt64 GetTotalOut() const { return (UInt64(total_out_hi32) << 32) + total_out_lo32; } +}; + +class CBZip2CompressorReleaser +{ + CBZip2Compressor *m_Compressor; +public: + CBZip2CompressorReleaser(CBZip2Compressor *compressor): m_Compressor(compressor) {} + void Disable() { m_Compressor = NULL; } + ~CBZip2CompressorReleaser() { if (m_Compressor != NULL) m_Compressor->End(); } +}; + + +STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + if (m_InBuffer == 0) + { + m_InBuffer = (Byte *)BigAlloc(kBufferSize * 2); + if (m_InBuffer == 0) + return E_OUTOFMEMORY; + } + Byte *outBuffer = m_InBuffer + kBufferSize; + + CBZip2Compressor bzStream; + bzStream.bzalloc = NULL; + bzStream.bzfree = NULL; + bzStream.opaque = NULL; + + int result = bzStream.Init(9, 0, 0); + switch(result) + { + case BZ_OK: + break; + case BZ_MEM_ERROR: + return E_OUTOFMEMORY; + default: + return E_FAIL; + } + CBZip2CompressorReleaser releaser(&bzStream); + bzStream.avail_in = 0; + while (true) + { + if (bzStream.avail_in == 0) + { + bzStream.next_in = (char *)m_InBuffer; + UInt32 processedSize; + RINOK(inStream->Read(m_InBuffer, kBufferSize, &processedSize)); + bzStream.avail_in = processedSize; + } + + bzStream.next_out = (char *)outBuffer; + bzStream.avail_out = kBufferSize; + bool askFinish = (bzStream.avail_in == 0); + result = bzStream.Compress(askFinish ? BZ_FINISH : BZ_RUN); + UInt32 numBytesToWrite = kBufferSize - bzStream.avail_out; + if (numBytesToWrite > 0) + { + UInt32 processedSize; + RINOK(outStream->Write(outBuffer, numBytesToWrite, &processedSize)); + if (numBytesToWrite != processedSize) + return E_FAIL; + } + + if (result == BZ_STREAM_END) + break; + switch(result) + { + case BZ_RUN_OK: + if (!askFinish) + break; + return E_FAIL; + case BZ_FINISH_OK: + if (askFinish) + break; + return E_FAIL; + case BZ_MEM_ERROR: + return E_OUTOFMEMORY; + default: + return E_FAIL; + } + if (progress != NULL) + { + UInt64 totalIn = bzStream.GetTotalIn(); + UInt64 totalOut = bzStream.GetTotalOut(); + RINOK(progress->SetRatioInfo(&totalIn, &totalOut)); + } + } + // result = bzStream.End(); + return S_OK; +} + +}} diff --git a/7zip/Compress/BZip2Original/BZip2Encoder.h b/7zip/Compress/BZip2Original/BZip2Encoder.h new file mode 100755 index 00000000..c451a08d --- /dev/null +++ b/7zip/Compress/BZip2Original/BZip2Encoder.h @@ -0,0 +1,30 @@ +// Compress/BZip2/Encoder.h + +#ifndef __COMPRESS_BZIP2_ENCODER_H +#define __COMPRESS_BZIP2_ENCODER_H + +#include "../../ICoder.h" +#include "../../../Common/MyCom.h" + +namespace NCompress { +namespace NBZip2 { + +class CEncoder : + public ICompressCoder, + public CMyUnknownImp +{ + Byte *m_InBuffer; +public: + CEncoder(): m_InBuffer(0) {}; + ~CEncoder(); + + MY_UNKNOWN_IMP + + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); +}; + +}} + +#endif diff --git a/7zip/Compress/BZip2/BZip2Error.cpp b/7zip/Compress/BZip2Original/BZip2Error.cpp index c8a912dc..c8a912dc 100755 --- a/7zip/Compress/BZip2/BZip2Error.cpp +++ b/7zip/Compress/BZip2Original/BZip2Error.cpp diff --git a/7zip/Compress/BZip2Original/DllExports.cpp b/7zip/Compress/BZip2Original/DllExports.cpp new file mode 100755 index 00000000..1f28a07c --- /dev/null +++ b/7zip/Compress/BZip2Original/DllExports.cpp @@ -0,0 +1,86 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" + +#include "BZip2Encoder.h" +#include "BZip2Decoder.h" + +// {23170F69-40C1-278B-0402-020000000000} +DEFINE_GUID(CLSID_CCompressBZip2Decoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00); + +// {23170F69-40C1-278B-0402-020000000100} +DEFINE_GUID(CLSID_CCompressBZip2Encoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00); + +extern "C" +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) +{ + return TRUE; +} + +STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + int correctInterface = (*iid == IID_ICompressCoder); + CMyComPtr<ICompressCoder> coder; + if (*clsid == CLSID_CCompressBZip2Decoder) + { + if (!correctInterface) + return E_NOINTERFACE; + coder = (ICompressCoder *)new NCompress::NBZip2::CDecoder; + } + else if (*clsid == CLSID_CCompressBZip2Encoder) + { + if (!correctInterface) + return E_NOINTERFACE; + coder = (ICompressCoder *)new NCompress::NBZip2::CEncoder; + } + else + return CLASS_E_CLASSNOTAVAILABLE; + *outObject = coder.Detach(); + COM_TRY_END + return S_OK; +} + +STDAPI GetNumberOfMethods(UINT32 *numMethods) +{ + *numMethods = 1; + return S_OK; +} + +STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value) +{ + if (index != 0) + return E_INVALIDARG; + ::VariantClear((tagVARIANT *)value); + switch(propID) + { + case NMethodPropID::kID: + { + const char id[] = { 0x04, 0x02, 0x02 }; + if ((value->bstrVal = ::SysAllocStringByteLen(id, sizeof(id))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NMethodPropID::kName: + if ((value->bstrVal = ::SysAllocString(L"BZip2")) != 0) + value->vt = VT_BSTR; + return S_OK; + case NMethodPropID::kDecoder: + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CCompressBZip2Decoder, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + case NMethodPropID::kEncoder: + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CCompressBZip2Encoder, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + return S_OK; +} diff --git a/7zip/Compress/BZip2Original/StdAfx.cpp b/7zip/Compress/BZip2Original/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/7zip/Compress/BZip2Original/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/7zip/Compress/BZip2Original/StdAfx.h b/7zip/Compress/BZip2Original/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/7zip/Compress/BZip2Original/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/7zip/Compress/BZip2Original/resource.h b/7zip/Compress/BZip2Original/resource.h new file mode 100755 index 00000000..612062a2 --- /dev/null +++ b/7zip/Compress/BZip2Original/resource.h @@ -0,0 +1,15 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by resource.rc +// + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/7zip/Compress/BZip2Original/resource.rc b/7zip/Compress/BZip2Original/resource.rc new file mode 100755 index 00000000..530090e4 --- /dev/null +++ b/7zip/Compress/BZip2Original/resource.rc @@ -0,0 +1,121 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Russian resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS) +#ifdef _WIN32 +LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT +#pragma code_page(1251) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // Russian resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 4,16,0,0 + PRODUCTVERSION 4,16,0,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", " \0" + VALUE "FileDescription", "BZip2 Coder\0" + VALUE "FileVersion", "4, 16, 0, 0\0" + VALUE "InternalName", "BZip2\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "BZip2.dll\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "7-Zip\0" + VALUE "ProductVersion", "4, 16, 0, 0\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // !_MAC + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/7zip/Compress/Branch/ARM.cpp b/7zip/Compress/Branch/ARM.cpp index 309c355f..4bd5e183 100755 --- a/7zip/Compress/Branch/ARM.cpp +++ b/7zip/Compress/Branch/ARM.cpp @@ -3,67 +3,14 @@ #include "StdAfx.h" #include "ARM.h" -#include "Windows/Defs.h" +#include "BranchARM.c" -static HRESULT BC_ARM_Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, - ICompressProgressInfo *progress, BYTE *buffer, bool encoding) +UInt32 CBC_ARM_Encoder::SubFilter(Byte *data, UInt32 size) { - UINT32 nowPos = 0; - UINT64 nowPos64 = 0; - UINT32 bufferPos = 0; - while(true) - { - UINT32 processedSize; - UINT32 size = kBufferSize - bufferPos; - RINOK(inStream->Read(buffer + bufferPos, size, &processedSize)); - UINT32 endPos = bufferPos + processedSize; - if (endPos < 4) - { - if (endPos > 0) - { - RINOK(outStream->Write(buffer, endPos, &processedSize)); - if (endPos != processedSize) - return E_FAIL; - } - return S_OK; - } - for (bufferPos = 0; bufferPos <= endPos - 4; bufferPos += 4) - { - if (buffer[bufferPos + 3] == 0xeb) - { - UINT32 src = - (buffer[bufferPos + 2] << 16) | - (buffer[bufferPos + 1] << 8) | - (buffer[bufferPos + 0]); - - src <<= 2; - UINT32 dest; - if (encoding) - dest = nowPos + bufferPos + 8 + src; - else - dest = src - (nowPos + bufferPos + 8); - dest >>= 2; - buffer[bufferPos + 2] = (dest >> 16); - buffer[bufferPos + 1] = (dest >> 8); - buffer[bufferPos + 0] = dest; - } - } - nowPos += bufferPos; - nowPos64 += bufferPos; - RINOK(outStream->Write(buffer, bufferPos, &processedSize)); - if (bufferPos != processedSize) - return E_FAIL; - if (progress != NULL) - { - RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64)); - } - - UINT32 i = 0; - while(bufferPos < endPos) - buffer[i++] = buffer[bufferPos++]; - bufferPos = i; - } + return ::ARM_Convert(data, size, _bufferPos, 1); } -MyClassImp(BC_ARM) +UInt32 CBC_ARM_Decoder::SubFilter(Byte *data, UInt32 size) +{ + return ::ARM_Convert(data, size, _bufferPos, 0); +} diff --git a/7zip/Compress/Branch/ARM.h b/7zip/Compress/Branch/ARM.h index cdd3c0dc..5561299b 100755 --- a/7zip/Compress/Branch/ARM.h +++ b/7zip/Compress/Branch/ARM.h @@ -1,12 +1,10 @@ // ARM.h -#pragma once - #ifndef __ARM_H #define __ARM_H -#include "Coder.h" +#include "BranchCoder.h" -MyClass(BC_ARM, 0x05, 1) +MyClassA(BC_ARM, 0x05, 1) #endif diff --git a/7zip/Compress/Branch/ARMThumb.cpp b/7zip/Compress/Branch/ARMThumb.cpp index 69605885..fbd25701 100755 --- a/7zip/Compress/Branch/ARMThumb.cpp +++ b/7zip/Compress/Branch/ARMThumb.cpp @@ -3,74 +3,14 @@ #include "StdAfx.h" #include "ARMThumb.h" -#include "Windows/Defs.h" +#include "BranchARMThumb.c" -static HRESULT BC_ARMThumb_Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, - ICompressProgressInfo *progress, BYTE *buffer, bool encoding) +UInt32 CBC_ARMThumb_Encoder::SubFilter(Byte *data, UInt32 size) { - UINT32 nowPos = 0; - UINT64 nowPos64 = 0; - UINT32 bufferPos = 0; - while(true) - { - UINT32 processedSize; - UINT32 size = kBufferSize - bufferPos; - RINOK(inStream->Read(buffer + bufferPos, size, &processedSize)); - UINT32 endPos = bufferPos + processedSize; - if (endPos < 4) - { - if (endPos > 0) - { - RINOK(outStream->Write(buffer, endPos, &processedSize)); - if (endPos != processedSize) - return E_FAIL; - } - return S_OK; - } - for (bufferPos = 0; bufferPos <= endPos - 4; bufferPos += 2) - { - if ((buffer[bufferPos + 1] & 0xF8) == 0xF0 && - (buffer[bufferPos + 3] & 0xF8) == 0xF8) - { - UINT32 src = - ((buffer[bufferPos + 1] & 0x7) << 19) | - (buffer[bufferPos + 0] << 11) | - ((buffer[bufferPos + 3] & 0x7) << 8) | - (buffer[bufferPos + 2]); - - src <<= 1; - UINT32 dest; - if (encoding) - dest = nowPos + bufferPos + 4 + src; - else - dest = src - (nowPos + bufferPos + 4); - dest >>= 1; - - buffer[bufferPos + 1] = 0xF0 | ((dest >> 19) & 0x7); - buffer[bufferPos + 0] = (dest >> 11); - buffer[bufferPos + 3] = 0xF8 | ((dest >> 8) & 0x7); - buffer[bufferPos + 2] = (dest); - bufferPos += 2; - } - } - nowPos += bufferPos; - nowPos64 += bufferPos; - RINOK(outStream->Write(buffer, bufferPos, &processedSize)); - if (bufferPos != processedSize) - return E_FAIL; - if (progress != NULL) - { - RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64)); - } - - UINT32 i = 0; - while(bufferPos < endPos) - buffer[i++] = buffer[bufferPos++]; - bufferPos = i; - } + return ::ARMThumb_Convert(data, size, _bufferPos, 1); } -MyClassImp(BC_ARMThumb) - - +UInt32 CBC_ARMThumb_Decoder::SubFilter(Byte *data, UInt32 size) +{ + return ::ARMThumb_Convert(data, size, _bufferPos, 0); +} diff --git a/7zip/Compress/Branch/ARMThumb.h b/7zip/Compress/Branch/ARMThumb.h index 5e3bf3d5..601e40bf 100755 --- a/7zip/Compress/Branch/ARMThumb.h +++ b/7zip/Compress/Branch/ARMThumb.h @@ -1,12 +1,10 @@ // ARMThumb.h -#pragma once - #ifndef __ARMTHUMB_H #define __ARMTHUMB_H -#include "Coder.h" +#include "BranchCoder.h" -MyClass(BC_ARMThumb, 0x07, 1) +MyClassA(BC_ARMThumb, 0x07, 1) #endif diff --git a/7zip/Compress/Branch/Alpha.cpp b/7zip/Compress/Branch/Alpha.cpp deleted file mode 100755 index aa70d3a3..00000000 --- a/7zip/Compress/Branch/Alpha.cpp +++ /dev/null @@ -1,75 +0,0 @@ -// Alpha.cpp - -#include "StdAfx.h" -#include "Alpha.h" - -#include "Windows/Defs.h" - -static HRESULT BC_Alpha_Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, - ICompressProgressInfo *progress, BYTE *buffer, bool encoding) -{ - UINT32 nowPos = 0; - UINT64 nowPos64 = 0; - UINT32 bufferPos = 0; - while(true) - { - UINT32 processedSize; - UINT32 size = kBufferSize - bufferPos; - RINOK(inStream->Read(buffer + bufferPos, size, &processedSize)); - UINT32 endPos = bufferPos + processedSize; - if (endPos < 4) - { - if (endPos > 0) - { - RINOK(outStream->Write(buffer, endPos, &processedSize)); - if (endPos != processedSize) - return E_FAIL; - } - return S_OK; - } - for (bufferPos = 0; bufferPos <= endPos - 4; bufferPos += 4) - { - // if (buffer[bufferPos + 3] == 0xc3 && (buffer[bufferPos + 2] >> 5) == 7) // its jump - // if (buffer[bufferPos + 3] == 0xd3 && (buffer[bufferPos + 2] >> 5) == 2) - // if (buffer[bufferPos + 3] == 0xd3) - if ((buffer[bufferPos + 3] >> 2) == 0x34) - { - UINT32 src = - ((buffer[bufferPos + 2] & 0x1F) << 16) | - (buffer[bufferPos + 1] << 8) | - (buffer[bufferPos + 0]); - - src <<= 2; - - UINT32 dest; - if (encoding) - dest = (nowPos + bufferPos + 4) + src; - else - dest = src - (nowPos + bufferPos + 4); - dest >>= 2; - dest &= 0x1FFFFF; - buffer[bufferPos + 2] &= (~0x1F); - buffer[bufferPos + 2] |= (dest >> 16); - buffer[bufferPos + 1] = (dest >> 8); - buffer[bufferPos + 0] = dest; - } - } - nowPos += bufferPos; - nowPos64 += bufferPos; - RINOK(outStream->Write(buffer, bufferPos, &processedSize)); - if (bufferPos != processedSize) - return E_FAIL; - if (progress != NULL) - { - RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64)); - } - - UINT32 i = 0; - while(bufferPos < endPos) - buffer[i++] = buffer[bufferPos++]; - bufferPos = i; - } -} - -MyClassImp(BC_Alpha) diff --git a/7zip/Compress/Branch/Alpha.h b/7zip/Compress/Branch/Alpha.h deleted file mode 100755 index 7d4fdab3..00000000 --- a/7zip/Compress/Branch/Alpha.h +++ /dev/null @@ -1,12 +0,0 @@ -// Alpha.h - -#pragma once - -#ifndef __ALPHA_H -#define __ALPHA_H - -#include "Coder.h" - -MyClass(BC_Alpha, 0x03, 1) - -#endif diff --git a/7zip/Compress/Branch/Branch.dsp b/7zip/Compress/Branch/Branch.dsp index c43391e6..0f5d80e7 100755 --- a/7zip/Compress/Branch/Branch.dsp +++ b/7zip/Compress/Branch/Branch.dsp @@ -123,7 +123,7 @@ SOURCE=.\StdAfx.h # PROP Default_Filter "" # Begin Source File -SOURCE=.\Alpha.cpp +SOURCE=.\ARM.cpp !IF "$(CFG)" == "Branch - Win32 Release" @@ -137,11 +137,11 @@ SOURCE=.\Alpha.cpp # End Source File # Begin Source File -SOURCE=.\Alpha.h +SOURCE=.\ARM.h # End Source File # Begin Source File -SOURCE=.\ARM.cpp +SOURCE=.\ARMThumb.cpp !IF "$(CFG)" == "Branch - Win32 Release" @@ -155,29 +155,19 @@ SOURCE=.\ARM.cpp # End Source File # Begin Source File -SOURCE=.\ARM.h +SOURCE=.\ARMThumb.h # End Source File # Begin Source File -SOURCE=.\ARMThumb.cpp - -!IF "$(CFG)" == "Branch - Win32 Release" - -# ADD CPP /O2 -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Branch - Win32 Debug" - -!ENDIF - +SOURCE=.\BranchCoder.cpp # End Source File # Begin Source File -SOURCE=.\ARMThumb.h +SOURCE=.\BranchCoder.h # End Source File # Begin Source File -SOURCE=.\Coder.h +SOURCE=.\BranchX86.h # End Source File # Begin Source File @@ -199,7 +189,7 @@ SOURCE=.\IA64.h # End Source File # Begin Source File -SOURCE=.\M68.cpp +SOURCE=.\PPC.cpp !IF "$(CFG)" == "Branch - Win32 Release" @@ -213,25 +203,15 @@ SOURCE=.\M68.cpp # End Source File # Begin Source File -SOURCE=.\M68.h +SOURCE=.\PPC.h # End Source File # Begin Source File -SOURCE=.\PPC.cpp - -!IF "$(CFG)" == "Branch - Win32 Release" - -# ADD CPP /O2 -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Branch - Win32 Debug" - -!ENDIF - +SOURCE=.\SPARC.cpp # End Source File # Begin Source File -SOURCE=.\PPC.h +SOURCE=.\SPARC.h # End Source File # Begin Source File @@ -305,6 +285,14 @@ SOURCE=..\RangeCoder\RangeCoderBit.h # Begin Group "Common" # PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File # End Group # End Target # End Project diff --git a/7zip/Compress/Branch/BranchARM.c b/7zip/Compress/Branch/BranchARM.c new file mode 100755 index 00000000..7e0bbf8b --- /dev/null +++ b/7zip/Compress/Branch/BranchARM.c @@ -0,0 +1,26 @@ +// BranchARM.c + +#include "BranchARM.h" + +UInt32 ARM_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding) +{ + UInt32 i; + for (i = 0; i + 4 <= size; i += 4) + { + if (data[i + 3] == 0xEB) + { + UInt32 src = (data[i + 2] << 16) | (data[i + 1] << 8) | (data[i + 0]); + src <<= 2; + UInt32 dest; + if (encoding) + dest = nowPos + i + 8 + src; + else + dest = src - (nowPos + i + 8); + dest >>= 2; + data[i + 2] = (dest >> 16); + data[i + 1] = (dest >> 8); + data[i + 0] = dest; + } + } + return i; +} diff --git a/7zip/Compress/Branch/BranchARM.h b/7zip/Compress/Branch/BranchARM.h new file mode 100755 index 00000000..5140a178 --- /dev/null +++ b/7zip/Compress/Branch/BranchARM.h @@ -0,0 +1,10 @@ +// BranchARM.h + +#ifndef __BRANCH_ARM_H +#define __BRANCH_ARM_H + +#include "Common/Types.h" + +UInt32 ARM_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding); + +#endif diff --git a/7zip/Compress/Branch/BranchARMThumb.c b/7zip/Compress/Branch/BranchARMThumb.c new file mode 100755 index 00000000..d30b75c1 --- /dev/null +++ b/7zip/Compress/Branch/BranchARMThumb.c @@ -0,0 +1,35 @@ +// BranchARMThumb.c + +#include "BranchARMThumb.h" + +UInt32 ARMThumb_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding) +{ + UInt32 i; + for (i = 0; i + 4 <= size; i += 2) + { + if ((data[i + 1] & 0xF8) == 0xF0 && + (data[i + 3] & 0xF8) == 0xF8) + { + UInt32 src = + ((data[i + 1] & 0x7) << 19) | + (data[i + 0] << 11) | + ((data[i + 3] & 0x7) << 8) | + (data[i + 2]); + + src <<= 1; + UInt32 dest; + if (encoding) + dest = nowPos + i + 4 + src; + else + dest = src - (nowPos + i + 4); + dest >>= 1; + + data[i + 1] = 0xF0 | ((dest >> 19) & 0x7); + data[i + 0] = (dest >> 11); + data[i + 3] = 0xF8 | ((dest >> 8) & 0x7); + data[i + 2] = (dest); + i += 2; + } + } + return i; +} diff --git a/7zip/Compress/Branch/BranchARMThumb.h b/7zip/Compress/Branch/BranchARMThumb.h new file mode 100755 index 00000000..0f177b6c --- /dev/null +++ b/7zip/Compress/Branch/BranchARMThumb.h @@ -0,0 +1,10 @@ +// BranchARMThumb.h + +#ifndef __BRANCH_ARM_THUMB_H +#define __BRANCH_ARM_THUMB_H + +#include "Common/Types.h" + +UInt32 ARMThumb_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding); + +#endif diff --git a/7zip/Compress/Branch/BranchCoder.cpp b/7zip/Compress/Branch/BranchCoder.cpp new file mode 100755 index 00000000..8d25f0d5 --- /dev/null +++ b/7zip/Compress/Branch/BranchCoder.cpp @@ -0,0 +1,18 @@ +// BranchCoder.cpp + +#include "StdAfx.h" +#include "BranchCoder.h" + +STDMETHODIMP CBranchConverter::Init() +{ + _bufferPos = 0; + SubInit(); + return S_OK; +} + +STDMETHODIMP_(UInt32) CBranchConverter::Filter(Byte *data, UInt32 size) +{ + UInt32 processedSize = SubFilter(data, size); + _bufferPos += processedSize; + return processedSize; +} diff --git a/7zip/Compress/Branch/BranchCoder.h b/7zip/Compress/Branch/BranchCoder.h new file mode 100755 index 00000000..4b53b6cb --- /dev/null +++ b/7zip/Compress/Branch/BranchCoder.h @@ -0,0 +1,54 @@ +// BranchCoder.h + +#ifndef __BRANCH_CODER_H +#define __BRANCH_CODER_H + +#include "Common/MyCom.h" +#include "Common/Types.h" +#include "Common/Alloc.h" + +#include "../../ICoder.h" + +class CBranchConverter: + public ICompressFilter, + public CMyUnknownImp +{ +protected: + UInt32 _bufferPos; + virtual void SubInit() {} + virtual UInt32 SubFilter(Byte *data, UInt32 size) = 0; +public: + MY_UNKNOWN_IMP; + STDMETHOD(Init)(); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); +}; + +#define MyClassEncoderA(Name) class C ## Name: public CBranchConverter \ + { public: UInt32 SubFilter(Byte *data, UInt32 size); }; + +#define MyClassDecoderA(Name) class C ## Name: public CBranchConverter \ + { public: UInt32 SubFilter(Byte *data, UInt32 size); }; + +#define MyClassEncoderB(Name, ADD_ITEMS, ADD_INIT) class C ## Name: public CBranchConverter, public ADD_ITEMS \ + { public: UInt32 SubFilter(Byte *data, UInt32 size); ADD_INIT}; + +#define MyClassDecoderB(Name, ADD_ITEMS, ADD_INIT) class C ## Name: public CBranchConverter, public ADD_ITEMS \ + { public: UInt32 SubFilter(Byte *data, UInt32 size); ADD_INIT}; + +#define MyClass2b(Name, id, subId, encodingId) \ +DEFINE_GUID(CLSID_CCompressConvert ## Name, \ +0x23170F69, 0x40C1, 0x278B, 0x03, 0x03, id, subId, 0x00, 0x00, encodingId, 0x00); + +#define MyClassA(Name, id, subId) \ +MyClass2b(Name ## _Encoder, id, subId, 0x01) \ +MyClassEncoderA(Name ## _Encoder) \ +MyClass2b(Name ## _Decoder, id, subId, 0x00) \ +MyClassDecoderA(Name ## _Decoder) + +#define MyClassB(Name, id, subId, ADD_ITEMS, ADD_INIT) \ +MyClass2b(Name ## _Encoder, id, subId, 0x01) \ +MyClassEncoderB(Name ## _Encoder, ADD_ITEMS, ADD_INIT) \ +MyClass2b(Name ## _Decoder, id, subId, 0x00) \ +MyClassDecoderB(Name ## _Decoder, ADD_ITEMS, ADD_INIT) + +#endif diff --git a/7zip/Compress/Branch/BranchIA64.c b/7zip/Compress/Branch/BranchIA64.c new file mode 100755 index 00000000..55c03fa4 --- /dev/null +++ b/7zip/Compress/Branch/BranchIA64.c @@ -0,0 +1,65 @@ +// BranchIA64.c + +#include "BranchIA64.h" + +const Byte kBranchTable[32] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 4, 4, 6, 6, 0, 0, 7, 7, + 4, 4, 0, 0, 4, 4, 0, 0 +}; + +UInt32 IA64_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding) +{ + UInt32 i; + for (i = 0; i + 16 <= size; i += 16) + { + UInt32 instrTemplate = data[i] & 0x1F; + UInt32 mask = kBranchTable[instrTemplate]; + UInt32 bitPos = 5; + for (int slot = 0; slot < 3; slot++, bitPos += 41) + { + if (((mask >> slot) & 1) == 0) + continue; + UInt32 bytePos = (bitPos >> 3); + UInt32 bitRes = bitPos & 0x7; + // UInt64 instruction = *(UInt64 *)(data + i + bytePos); + UInt64 instruction = 0; + int j; + for (j = 0; j < 6; j++) + instruction += (UInt64)(data[i + j + bytePos]) << (8 * j); + + UInt64 instNorm = instruction >> bitRes; + if (((instNorm >> 37) & 0xF) == 0x5 + && ((instNorm >> 9) & 0x7) == 0 + // && (instNorm & 0x3F)== 0 + ) + { + UInt32 src = UInt32((instNorm >> 13) & 0xFFFFF); + src |= ((instNorm >> 36) & 1) << 20; + + src <<= 4; + + UInt32 dest; + if (encoding) + dest = nowPos + i + src; + else + dest = src - (nowPos + i); + + dest >>= 4; + + instNorm &= ~(UInt64(0x8FFFFF) << 13); + instNorm |= (UInt64(dest & 0xFFFFF) << 13); + instNorm |= (UInt64(dest & 0x100000) << (36 - 20)); + + instruction &= (1 << bitRes) - 1; + instruction |= (instNorm << bitRes); + // *(UInt64 *)(data + i + bytePos) = instruction; + for (j = 0; j < 6; j++) + data[i + j + bytePos] = Byte(instruction >> (8 * j)); + } + } + } + return i; +} diff --git a/7zip/Compress/Branch/BranchIA64.h b/7zip/Compress/Branch/BranchIA64.h new file mode 100755 index 00000000..0ad98ba8 --- /dev/null +++ b/7zip/Compress/Branch/BranchIA64.h @@ -0,0 +1,10 @@ +// BranchIA64.h + +#ifndef __BRANCH_IA64_H +#define __BRANCH_IA64_H + +#include "Common/Types.h" + +UInt32 IA64_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding); + +#endif diff --git a/7zip/Compress/Branch/BranchPPC.c b/7zip/Compress/Branch/BranchPPC.c new file mode 100755 index 00000000..eb3aafb4 --- /dev/null +++ b/7zip/Compress/Branch/BranchPPC.c @@ -0,0 +1,36 @@ +// BranchPPC.c + +#include "BranchPPC.h" + +UInt32 PPC_B_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding) +{ + UInt32 i; + for (i = 0; i + 4 <= size; i += 4) + { + // PowerPC branch 6(48) 24(Offset) 1(Abs) 1(Link) + if ((data[i] >> 2) == 0x12 && + ( + (data[i + 3] & 3) == 1 + // || (data[i+3] & 3) == 3 + ) + ) + { + UInt32 src = ((data[i + 0] & 3) << 24) | + (data[i + 1] << 16) | + (data[i + 2] << 8) | + (data[i + 3] & (~3)); + + UInt32 dest; + if (encoding) + dest = nowPos + i + src; + else + dest = src - (nowPos + i); + data[i + 0] = 0x48 | ((dest >> 24) & 0x3); + data[i + 1] = (dest >> 16); + data[i + 2] = (dest >> 8); + data[i + 3] &= 0x3; + data[i + 3] |= dest; + } + } + return i; +} diff --git a/7zip/Compress/Branch/BranchPPC.h b/7zip/Compress/Branch/BranchPPC.h new file mode 100755 index 00000000..1c4dca7f --- /dev/null +++ b/7zip/Compress/Branch/BranchPPC.h @@ -0,0 +1,10 @@ +// BranchPPC.h + +#ifndef __BRANCH_PPC_H +#define __BRANCH_PPC_H + +#include "Common/Types.h" + +UInt32 PPC_B_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding); + +#endif diff --git a/7zip/Compress/Branch/BranchSPARC.c b/7zip/Compress/Branch/BranchSPARC.c new file mode 100755 index 00000000..a8d3f4dc --- /dev/null +++ b/7zip/Compress/Branch/BranchSPARC.c @@ -0,0 +1,36 @@ +// BranchSPARC.c + +#include "BranchSPARC.h" + +UInt32 SPARC_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding) +{ + UInt32 i; + for (i = 0; i + 4 <= size; i += 4) + { + if (data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00 || + data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0) + { + UInt32 src = + ((UInt32)data[i + 0] << 24) | + ((UInt32)data[i + 1] << 16) | + ((UInt32)data[i + 2] << 8) | + ((UInt32)data[i + 3]); + + src <<= 2; + UInt32 dest; + if (encoding) + dest = nowPos + i + src; + else + dest = src - (nowPos + i); + dest >>= 2; + + dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000; + + data[i + 0] = (Byte)(dest >> 24); + data[i + 1] = (Byte)(dest >> 16); + data[i + 2] = (Byte)(dest >> 8); + data[i + 3] = (Byte)dest; + } + } + return i; +} diff --git a/7zip/Compress/Branch/BranchSPARC.h b/7zip/Compress/Branch/BranchSPARC.h new file mode 100755 index 00000000..dafa40d5 --- /dev/null +++ b/7zip/Compress/Branch/BranchSPARC.h @@ -0,0 +1,10 @@ +// BranchSPARC.h + +#ifndef __BRANCH_SPARC_H +#define __BRANCH_SPARC_H + +#include "Common/Types.h" + +UInt32 SPARC_B_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding); + +#endif diff --git a/7zip/Compress/Branch/BranchX86.c b/7zip/Compress/Branch/BranchX86.c new file mode 100755 index 00000000..2c6f69a5 --- /dev/null +++ b/7zip/Compress/Branch/BranchX86.c @@ -0,0 +1,101 @@ +/* BranchX86.c */ + +#include "BranchX86.h" + +/* +static int inline Test86MSByte(Byte b) +{ + return (b == 0 || b == 0xFF); +} +*/ +#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF) + +const int kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0}; +const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3}; + +/* +void x86_Convert_Init(UInt32 *prevMask, UInt32 *prevPos) +{ + *prevMask = 0; + *prevPos = (UInt32)(-5); +} +*/ + +UInt32 x86_Convert(Byte *buffer, UInt32 endPos, UInt32 nowPos, + UInt32 *prevMask, UInt32 *prevPos, int encoding) +{ + UInt32 bufferPos = 0; + UInt32 limit; + + if (endPos < 5) + return 0; + + if (nowPos - *prevPos > 5) + *prevPos = nowPos - 5; + + limit = endPos - 5; + while(bufferPos <= limit) + { + Byte b = buffer[bufferPos]; + UInt32 offset; + if (b != 0xE8 && b != 0xE9) + { + bufferPos++; + continue; + } + offset = (nowPos + bufferPos - *prevPos); + *prevPos = (nowPos + bufferPos); + if (offset > 5) + *prevMask = 0; + else + { + UInt32 i; + for (i = 0; i < offset; i++) + { + *prevMask &= 0x77; + *prevMask <<= 1; + } + } + b = buffer[bufferPos + 4]; + if (Test86MSByte(b) && kMaskToAllowedStatus[(*prevMask >> 1) & 0x7] && + (*prevMask >> 1) < 0x10) + { + UInt32 src = + ((UInt32)(b) << 24) | + ((UInt32)(buffer[bufferPos + 3]) << 16) | + ((UInt32)(buffer[bufferPos + 2]) << 8) | + (buffer[bufferPos + 1]); + + UInt32 dest; + while(1) + { + UInt32 index; + if (encoding) + dest = (nowPos + bufferPos + 5) + src; + else + dest = src - (nowPos + bufferPos + 5); + if (*prevMask == 0) + break; + index = kMaskToBitNumber[*prevMask >> 1]; + b = (Byte)(dest >> (24 - index * 8)); + if (!Test86MSByte(b)) + break; + src = dest ^ ((1 << (32 - index * 8)) - 1); + } + buffer[bufferPos + 4] = (Byte)(~(((dest >> 24) & 1) - 1)); + buffer[bufferPos + 3] = (Byte)(dest >> 16); + buffer[bufferPos + 2] = (Byte)(dest >> 8); + buffer[bufferPos + 1] = (Byte)dest; + bufferPos += 5; + *prevMask = 0; + } + else + { + bufferPos++; + *prevMask |= 1; + if (Test86MSByte(b)) + *prevMask |= 0x10; + } + } + return bufferPos; +} diff --git a/7zip/Compress/Branch/BranchX86.h b/7zip/Compress/Branch/BranchX86.h new file mode 100755 index 00000000..b7217ed8 --- /dev/null +++ b/7zip/Compress/Branch/BranchX86.h @@ -0,0 +1,19 @@ +/* BranchX86.h */ + +#ifndef __BRANCHX86_H +#define __BRANCHX86_H + +#ifndef UInt32 +#define UInt32 unsigned int +#endif + +#ifndef Byte +#define Byte unsigned char +#endif + +#define x86_Convert_Init(prevMask, prevPos) { prevMask = 0; prevPos = (UInt32)(-5); } + +UInt32 x86_Convert(Byte *buffer, UInt32 endPos, UInt32 nowPos, + UInt32 *prevMask, UInt32 *prevPos, int encoding); + +#endif diff --git a/7zip/Compress/Branch/Coder.h b/7zip/Compress/Branch/Coder.h deleted file mode 100755 index 3f37c1e4..00000000 --- a/7zip/Compress/Branch/Coder.h +++ /dev/null @@ -1,66 +0,0 @@ -// Branch/Coder.h - -#pragma once - -#ifndef __CallPowerPC_CODER_H -#define __CallPowerPC_CODER_H - -#include "Common/MyCom.h" -#include "Common/Types.h" - -#include "../../ICoder.h" - -const int kBufferSize = 1 << 17; - -class CDataBuffer -{ -protected: - BYTE *_buffer; -public: - CDataBuffer() - { _buffer = new BYTE[kBufferSize]; } - ~CDataBuffer() - { delete []_buffer; } -}; - -#define MyClass3(Name) \ -class C ## Name: \ - public ICompressCoder, \ - public CDataBuffer, \ - public CMyUnknownImp \ - { \ -public: \ - MY_UNKNOWN_IMP \ - STDMETHOD(Code)(ISequentialInStream *inStream, \ - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, \ - ICompressProgressInfo *progress); \ -}; - -// {23170F69-40C1-278B-0303-010100000100} -#define MyClass2(Name, id, subId, encodingId) \ -DEFINE_GUID(CLSID_CCompressConvert ## Name, \ -0x23170F69, 0x40C1, 0x278B, 0x03, 0x03, id, subId, 0x00, 0x00, encodingId, 0x00); \ -MyClass3(Name) \ - - -#define MyClass(Name, id, subId) \ -MyClass2(Name ## _Encoder, id, subId, 0x01) \ -MyClass2(Name ## _Decoder, id, subId, 0x00) - -#define MyClassImp(Name) \ -STDMETHODIMP C ## Name ## _Encoder::Code(ISequentialInStream *inStream, \ - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, \ - ICompressProgressInfo *progress) \ -{ \ - return Name ## _Code(inStream, outStream, inSize, outSize, \ - progress, _buffer, true); \ -} \ -STDMETHODIMP C ## Name ## _Decoder::Code(ISequentialInStream *inStream, \ - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, \ - ICompressProgressInfo *progress) \ -{ \ - return Name ## _Code(inStream, outStream, inSize, outSize, \ - progress, _buffer, false); \ -} - -#endif diff --git a/7zip/Compress/Branch/DllExports.cpp b/7zip/Compress/Branch/DllExports.cpp index 520a364c..55f399e4 100755 --- a/7zip/Compress/Branch/DllExports.cpp +++ b/7zip/Compress/Branch/DllExports.cpp @@ -2,52 +2,28 @@ #include "StdAfx.h" -#define INITGUID - +#include "Common/MyInitGuid.h" #include "Common/ComTry.h" -#include "Coder.h" #include "x86.h" #include "PPC.h" -#include "Alpha.h" #include "IA64.h" #include "ARM.h" #include "ARMThumb.h" -#include "M68.h" #include "x86_2.h" +#include "SPARC.h" -#include "../../ICoder.h" - - -#define MY_CreateClass(n) \ +#define MY_CreateClass0(n) \ if (*clsid == CLSID_CCompressConvert ## n ## _Encoder) { \ if (!correctInterface) \ return E_NOINTERFACE; \ - coder = (ICompressCoder *)new C ## n ## _Encoder(); \ + filter = (ICompressFilter *)new C ## n ## _Encoder(); \ } else if (*clsid == CLSID_CCompressConvert ## n ## _Decoder){ \ if (!correctInterface) \ return E_NOINTERFACE; \ - coder = (ICompressCoder *)new C ## n ## _Decoder(); \ + filter = (ICompressFilter *)new C ## n ## _Decoder(); \ } -/* -#define MyOBJECT_ENTRY(Name) \ - OBJECT_ENTRY(CLSID_CCompressConvert ## Name ## _Encoder, C ## Name ## _Encoder) \ - OBJECT_ENTRY(CLSID_CCompressConvert ## Name ## _Decoder, C ## Name ## _Decoder) \ - - -BEGIN_OBJECT_MAP(ObjectMap) - MyOBJECT_ENTRY(BCJ_x86) - MyOBJECT_ENTRY(BCJ2_x86) - MyOBJECT_ENTRY(BC_PPC_B) - MyOBJECT_ENTRY(BC_Alpha) - MyOBJECT_ENTRY(BC_IA64) - MyOBJECT_ENTRY(BC_ARM) - MyOBJECT_ENTRY(BC_ARMThumb) - MyOBJECT_ENTRY(BC_M68_B) -END_OBJECT_MAP() -*/ - extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) { @@ -61,22 +37,19 @@ STDAPI CreateObject( { COM_TRY_BEGIN *outObject = 0; - int correctInterface = (*interfaceID == IID_ICompressCoder); - CMyComPtr<ICompressCoder> coder; - - MY_CreateClass(BCJ_x86) - else - MY_CreateClass(BC_PPC_B) + int correctInterface = (*interfaceID == IID_ICompressFilter); + CMyComPtr<ICompressFilter> filter; + MY_CreateClass0(BCJ_x86) else - MY_CreateClass(BC_Alpha) + MY_CreateClass0(BC_ARM) else - MY_CreateClass(BC_IA64) + MY_CreateClass0(BC_PPC_B) else - MY_CreateClass(BC_ARM) + MY_CreateClass0(BC_IA64) else - MY_CreateClass(BC_ARMThumb) + MY_CreateClass0(BC_ARMThumb) else - MY_CreateClass(BC_M68_B) + MY_CreateClass0(BC_SPARC) else { CMyComPtr<ICompressCoder2> coder2; @@ -98,8 +71,9 @@ STDAPI CreateObject( *outObject = coder2.Detach(); return S_OK; } - *outObject = coder.Detach(); + *outObject = filter.Detach(); return S_OK; + COM_TRY_END } @@ -123,11 +97,12 @@ static CBranchMethodItem g_Methods[] = METHOD_ITEM(BCJ_x86, 0x01, 0x03, L"BCJ", 1), METHOD_ITEM(BCJ2_x86, 0x01, 0x1B, L"BCJ2", 4), METHOD_ITEM(BC_PPC_B, 0x02, 0x05, L"BC_PPC_B", 1), - METHOD_ITEM(BC_Alpha, 0x03, 1, L"BC_Alpha", 1), + // METHOD_ITEM(BC_Alpha, 0x03, 1, L"BC_Alpha", 1), METHOD_ITEM(BC_IA64, 0x04, 1, L"BC_IA64", 1), METHOD_ITEM(BC_ARM, 0x05, 1, L"BC_ARM", 1), - METHOD_ITEM(BC_M68_B, 0x06, 5, L"BC_M68_B", 1), - METHOD_ITEM(BC_ARMThumb, 0x07, 1, L"BC_ARMThumb", 1) + // METHOD_ITEM(BC_M68_B, 0x06, 5, L"BC_M68_B", 1), + METHOD_ITEM(BC_ARMThumb, 0x07, 1, L"BC_ARMThumb", 1), + METHOD_ITEM(BC_SPARC, 0x08, 0x05, L"BC_SPARC", 1) }; STDAPI GetNumberOfMethods(UINT32 *numMethods) @@ -175,4 +150,3 @@ STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value) } return S_OK; } - diff --git a/7zip/Compress/Branch/IA64.cpp b/7zip/Compress/Branch/IA64.cpp index 76614c22..75dfdcba 100755 --- a/7zip/Compress/Branch/IA64.cpp +++ b/7zip/Compress/Branch/IA64.cpp @@ -3,101 +3,14 @@ #include "StdAfx.h" #include "IA64.h" -#include "Windows/Defs.h" +#include "BranchIA64.c" -const BYTE kBranchTable[32] = -{ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 4, 4, 6, 6, 0, 0, 7, 7, - 4, 4, 0, 0, 4, 4, 0, 0 -}; - - -static HRESULT BC_IA64_Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, - ICompressProgressInfo *progress, BYTE *buffer, bool encoding) +UInt32 CBC_IA64_Encoder::SubFilter(Byte *data, UInt32 size) { - UINT32 nowPos = 0; - UINT64 nowPos64 = 0; - UINT32 bufferPos = 0; - while(true) - { - UINT32 processedSize; - UINT32 size = kBufferSize - bufferPos; - RINOK(inStream->Read(buffer + bufferPos, size, &processedSize)); - UINT32 endPos = bufferPos + processedSize; - if (endPos < 16) - { - if (endPos > 0) - { - RINOK(outStream->Write(buffer, endPos, &processedSize)); - if (endPos != processedSize) - return E_FAIL; - } - return S_OK; - } - for (bufferPos = 0; bufferPos <= endPos - 16; bufferPos += 16) - { - UINT32 instrTemplate = buffer[bufferPos] & 0x1F; - // ofs << hex << setw(4) << instrTemplate << endl; - UINT32 mask = kBranchTable[instrTemplate]; - UINT32 bitPos = 5; - for (int slot = 0; slot < 3; slot++, bitPos += 41) - { - if (((mask >> slot) & 1) == 0) - continue; - UINT32 bytePos = (bitPos >> 3); - UINT32 bitRes = bitPos & 0x7; - UINT64 instruction = *(UINT64 *)(buffer + bufferPos + bytePos); - UINT64 instNorm = instruction >> bitRes; - if (((instNorm >> 37) & 0xF) == 0x5 - && ((instNorm >> 9) & 0x7) == 0 - // && (instNorm & 0x3F)== 0 - ) - { - UINT32 src = UINT32((instNorm >> 13) & 0xFFFFF); - src |= ((instNorm >> 36) & 1) << 20; - - src <<= 4; - - UINT32 dest; - if (encoding) - dest = nowPos + bufferPos + src; - else - dest = src - (nowPos + bufferPos); - - dest >>= 4; - - UINT64 instNorm2 = instNorm; - - instNorm &= ~(UINT64(0x8FFFFF) << 13); - instNorm |= (UINT64(dest & 0xFFFFF) << 13); - instNorm |= (UINT64(dest & 0x100000) << (36 - 20)); - - instruction &= (1 << bitRes) - 1; - instruction |= (instNorm << bitRes); - *(UINT64 *)(buffer + bufferPos + bytePos) = instruction; - } - } - } - nowPos += bufferPos; - nowPos64 += bufferPos; - RINOK(outStream->Write(buffer, bufferPos, &processedSize)); - if (bufferPos != processedSize) - return E_FAIL; - if (progress != NULL) - { - RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64)); - } - - UINT32 i = 0; - while(bufferPos < endPos) - buffer[i++] = buffer[bufferPos++]; - bufferPos = i; - } + return ::IA64_Convert(data, size, _bufferPos, 1); } -MyClassImp(BC_IA64) - - +UInt32 CBC_IA64_Decoder::SubFilter(Byte *data, UInt32 size) +{ + return ::IA64_Convert(data, size, _bufferPos, 0); +} diff --git a/7zip/Compress/Branch/IA64.h b/7zip/Compress/Branch/IA64.h index d1840964..7fe715ed 100755 --- a/7zip/Compress/Branch/IA64.h +++ b/7zip/Compress/Branch/IA64.h @@ -1,14 +1,10 @@ // IA64.h -#pragma once - #ifndef __IA64_H #define __IA64_H -#include "Coder.h" - -MyClass(BC_IA64, 0x04, 1) +#include "BranchCoder.h" -// MyClass(IA64_Parse, 0x08, 1) +MyClassA(BC_IA64, 0x04, 1) #endif diff --git a/7zip/Compress/Branch/M68.cpp b/7zip/Compress/Branch/M68.cpp deleted file mode 100755 index 5340ed1f..00000000 --- a/7zip/Compress/Branch/M68.cpp +++ /dev/null @@ -1,69 +0,0 @@ -// M68.cpp - -#include "StdAfx.h" -#include "M68.h" - -#include "Windows/Defs.h" - -static HRESULT BC_M68_B_Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, - ICompressProgressInfo *progress, BYTE *buffer, bool encoding) -{ - UINT32 nowPos = 0; - UINT64 nowPos64 = 0; - UINT32 bufferPos = 0; - while(true) - { - UINT32 processedSize; - UINT32 size = kBufferSize - bufferPos; - RINOK(inStream->Read(buffer + bufferPos, size, &processedSize)); - UINT32 endPos = bufferPos + processedSize; - if (endPos < 4) - { - if (endPos > 0) - { - RINOK(outStream->Write(buffer, endPos, &processedSize)); - if (endPos != processedSize) - return E_FAIL; - } - return S_OK; - } - for (bufferPos = 0; bufferPos <= endPos - 4;) - { - if (buffer[bufferPos] == 0x61 && buffer[bufferPos + 1] == 0x00) - { - UINT32 src = - (buffer[bufferPos + 2] << 8) | - (buffer[bufferPos + 3]); - - UINT32 dest; - if (encoding) - dest = nowPos + bufferPos + 2 + src; - else - dest = src - (nowPos + bufferPos + 2); - buffer[bufferPos + 2] = (dest >> 8); - buffer[bufferPos + 3] = dest; - bufferPos += 4; - } - else - bufferPos += 2; - } - nowPos += bufferPos; - nowPos64 += bufferPos; - RINOK(outStream->Write(buffer, bufferPos, &processedSize)); - if (bufferPos != processedSize) - return E_FAIL; - if (progress != NULL) - { - RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64)); - } - - UINT32 i = 0; - while(bufferPos < endPos) - buffer[i++] = buffer[bufferPos++]; - bufferPos = i; - } -} - -MyClassImp(BC_M68_B) - diff --git a/7zip/Compress/Branch/M68.h b/7zip/Compress/Branch/M68.h deleted file mode 100755 index 0acdede4..00000000 --- a/7zip/Compress/Branch/M68.h +++ /dev/null @@ -1,12 +0,0 @@ -// M68.h - -#pragma once - -#ifndef __M68_H -#define __M68_H - -#include "Coder.h" - -MyClass(BC_M68_B, 0x06, 5) - -#endif diff --git a/7zip/Compress/Branch/PPC.cpp b/7zip/Compress/Branch/PPC.cpp index 9ecdc4c3..197a8e58 100755 --- a/7zip/Compress/Branch/PPC.cpp +++ b/7zip/Compress/Branch/PPC.cpp @@ -4,73 +4,14 @@ #include "PPC.h" #include "Windows/Defs.h" +#include "BranchPPC.c" -static HRESULT BC_PPC_B_Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, - ICompressProgressInfo *progress, BYTE *buffer, bool encoding) +UInt32 CBC_PPC_B_Encoder::SubFilter(Byte *data, UInt32 size) { - UINT32 nowPos = 0; - UINT64 nowPos64 = 0; - UINT32 bufferPos = 0; - while(true) - { - UINT32 processedSize; - UINT32 size = kBufferSize - bufferPos; - RINOK(inStream->Read(buffer + bufferPos, size, &processedSize)); - UINT32 endPos = bufferPos + processedSize; - if (endPos < 4) - { - if (endPos > 0) - { - RINOK(outStream->Write(buffer, endPos, &processedSize)); - if (endPos != processedSize) - return E_FAIL; - } - return S_OK; - } - for (bufferPos = 0; bufferPos <= endPos - 4; bufferPos += 4) - { - // PowerPC branch 6(48) 24(Offset) 1(Abs) 1(Link) - if ((buffer[bufferPos] >> 2) == 0x12 && - ( - (buffer[bufferPos + 3] & 3) == 1 - // || (buffer[bufferPos+3] & 3) == 3 - ) - ) - { - UINT32 src = ((buffer[bufferPos + 0] & 3) << 24) | - (buffer[bufferPos + 1] << 16) | - (buffer[bufferPos + 2] << 8) | - (buffer[bufferPos + 3] & (~3)); - - UINT32 dest; - if (encoding) - dest = nowPos + bufferPos + src; - else - dest = src - (nowPos + bufferPos); - buffer[bufferPos + 0] = 0x48 | ((dest >> 24) & 0x3); - buffer[bufferPos + 1] = (dest >> 16); - buffer[bufferPos + 2] = (dest >> 8); - buffer[bufferPos + 3] &= 0x3; - buffer[bufferPos + 3] |= dest; - } - } - nowPos += bufferPos; - nowPos64 += bufferPos; - RINOK(outStream->Write(buffer, bufferPos, &processedSize)); - if (bufferPos != processedSize) - return E_FAIL; - if (progress != NULL) - { - RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64)); - } - - UINT32 i = 0; - while(bufferPos < endPos) - buffer[i++] = buffer[bufferPos++]; - bufferPos = i; - } + return ::PPC_B_Convert(data, size, _bufferPos, 1); } -MyClassImp(BC_PPC_B) - +UInt32 CBC_PPC_B_Decoder::SubFilter(Byte *data, UInt32 size) +{ + return ::PPC_B_Convert(data, size, _bufferPos, 0); +} diff --git a/7zip/Compress/Branch/PPC.h b/7zip/Compress/Branch/PPC.h index aad9d0b8..a0e33444 100755 --- a/7zip/Compress/Branch/PPC.h +++ b/7zip/Compress/Branch/PPC.h @@ -1,12 +1,10 @@ // PPC.h -#pragma once - #ifndef __PPC_H #define __PPC_H -#include "Coder.h" +#include "BranchCoder.h" -MyClass(BC_PPC_B, 0x02, 5) +MyClassA(BC_PPC_B, 0x02, 5) #endif diff --git a/7zip/Compress/Branch/SPARC.cpp b/7zip/Compress/Branch/SPARC.cpp new file mode 100755 index 00000000..d054eaaf --- /dev/null +++ b/7zip/Compress/Branch/SPARC.cpp @@ -0,0 +1,17 @@ +// SPARC.cpp + +#include "StdAfx.h" +#include "SPARC.h" + +#include "Windows/Defs.h" +#include "BranchSPARC.c" + +UInt32 CBC_SPARC_Encoder::SubFilter(Byte *data, UInt32 size) +{ + return ::SPARC_Convert(data, size, _bufferPos, 1); +} + +UInt32 CBC_SPARC_Decoder::SubFilter(Byte *data, UInt32 size) +{ + return ::SPARC_Convert(data, size, _bufferPos, 0); +} diff --git a/7zip/Compress/Branch/SPARC.h b/7zip/Compress/Branch/SPARC.h new file mode 100755 index 00000000..e0a682ef --- /dev/null +++ b/7zip/Compress/Branch/SPARC.h @@ -0,0 +1,10 @@ +// SPARC.h + +#ifndef __SPARC_H +#define __SPARC_H + +#include "BranchCoder.h" + +MyClassA(BC_SPARC, 0x08, 5) + +#endif diff --git a/7zip/Compress/Branch/StdAfx.cpp b/7zip/Compress/Branch/StdAfx.cpp index 2550270c..d0feea85 100755 --- a/7zip/Compress/Branch/StdAfx.cpp +++ b/7zip/Compress/Branch/StdAfx.cpp @@ -1,3 +1,3 @@ // StdAfx.cpp -#include "stdafx.h" +#include "StdAfx.h" diff --git a/7zip/Compress/Branch/StdAfx.h b/7zip/Compress/Branch/StdAfx.h index a32fbed6..e7fb6986 100755 --- a/7zip/Compress/Branch/StdAfx.h +++ b/7zip/Compress/Branch/StdAfx.h @@ -1,8 +1,8 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> +#include "../../../Common/MyWindows.h" -#endif +#endif diff --git a/7zip/Compress/Branch/resource.rc b/7zip/Compress/Branch/resource.rc index 65a91cd3..a3e2c58c 100755 --- a/7zip/Compress/Branch/resource.rc +++ b/7zip/Compress/Branch/resource.rc @@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,9,2,0 - PRODUCTVERSION 3,9,2,0 + FILEVERSION 4,17,0,0 + PRODUCTVERSION 4,17,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -84,15 +84,15 @@ BEGIN BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Igor Pavlov\0" - VALUE "FileDescription", "Branch converter\0" - VALUE "FileVersion", "3, 9, 2, 0\0" + VALUE "FileDescription", "Branch filter\0" + VALUE "FileVersion", "4, 17, 0, 0\0" VALUE "InternalName", "Branch\0" - VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "Branch.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "7-Zip\0" - VALUE "ProductVersion", "3, 9, 2, 0\0" + VALUE "ProductVersion", "4, 17, 0, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/7zip/Compress/Branch/x86.cpp b/7zip/Compress/Branch/x86.cpp index 3f46a659..013e42b6 100755 --- a/7zip/Compress/Branch/x86.cpp +++ b/7zip/Compress/Branch/x86.cpp @@ -1,124 +1,18 @@ -// x86.h +// x86.cpp #include "StdAfx.h" #include "x86.h" #include "Windows/Defs.h" -static bool inline Test86MSByte(BYTE b) +#include "BranchX86.c" + +UInt32 CBCJ_x86_Encoder::SubFilter(Byte *data, UInt32 size) { - return (b == 0 || b == 0xFF); + return ::x86_Convert(data, size, _bufferPos, &_prevMask, &_prevPos, 1); } -const bool kMaskToAllowedStatus[8] = {true, true, true, false, true, false, false, false}; -const BYTE kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3}; - -static HRESULT BCJ_x86_Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, - ICompressProgressInfo *progress, BYTE *buffer, bool encoding) +UInt32 CBCJ_x86_Decoder::SubFilter(Byte *data, UInt32 size) { - UINT64 nowPos64 = 0; - UINT32 nowPos = 0; - UINT32 bufferPos = 0; - UINT32 prevMask = 0; - UINT32 prevPos = (- 5); - - while(true) - { - UINT32 processedSize; - UINT32 size = kBufferSize - bufferPos; - RINOK(inStream->Read(buffer + bufferPos, size, &processedSize)); - UINT32 endPos = bufferPos + processedSize; - if (endPos < 5) - { - if (endPos > 0) - { - RINOK(outStream->Write(buffer, endPos, &processedSize)); - if (endPos != processedSize) - return E_FAIL; - } - return S_OK; - } - bufferPos = 0; - if (nowPos - prevPos > 5) - prevPos = nowPos - 5; - - UINT32 limit = endPos - 5; - while(bufferPos <= limit) - { - if (buffer[bufferPos] != 0xE8 && buffer[bufferPos] != 0xE9) - { - bufferPos++; - continue; - } - UINT32 offset = (nowPos + bufferPos - prevPos); - prevPos = (nowPos + bufferPos); - if (offset > 5) - prevMask = 0; - else - { - for (UINT32 i = 0; i < offset; i++) - { - prevMask &= 0x77; - prevMask <<= 1; - } - } - BYTE &nextByte = buffer[bufferPos + 4]; - if (Test86MSByte(nextByte) && kMaskToAllowedStatus[(prevMask >> 1) & 0x7] && - (prevMask >> 1) < 0x10) - { - UINT32 src = - (UINT32(nextByte) << 24) | - (UINT32(buffer[bufferPos + 3]) << 16) | - (UINT32(buffer[bufferPos + 2]) << 8) | - (buffer[bufferPos + 1]); - - UINT32 dest; - while(true) - { - if (encoding) - dest = (nowPos + bufferPos + 5) + src; - else - dest = src - (nowPos + bufferPos + 5); - if (prevMask == 0) - break; - UINT32 index = kMaskToBitNumber[prevMask >> 1]; - if (!Test86MSByte(dest >> (24 - index * 8))) - break; - src = dest ^ ((1 << (32 - index * 8)) - 1); - // src = dest; - } - nextByte = ~(((dest >> 24) & 1) - 1); - buffer[bufferPos + 3] = (dest >> 16); - buffer[bufferPos + 2] = (dest >> 8); - buffer[bufferPos + 1] = dest; - bufferPos += 5; - prevMask = 0; - } - else - { - bufferPos++; - prevMask |= 1; - if (Test86MSByte(nextByte)) - prevMask |= 0x10; - } - } - nowPos += bufferPos; - nowPos64 += bufferPos; - RINOK(outStream->Write(buffer, bufferPos, &processedSize)); - if (bufferPos != processedSize) - return E_FAIL; - if (progress != NULL) - { - RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64)); - } - - UINT32 i = 0; - while(bufferPos < endPos) - buffer[i++] = buffer[bufferPos++]; - bufferPos = i; - } + return ::x86_Convert(data, size, _bufferPos, &_prevMask, &_prevPos, 0); } - - -MyClassImp(BCJ_x86) diff --git a/7zip/Compress/Branch/x86.h b/7zip/Compress/Branch/x86.h index cbe402a6..10d03982 100755 --- a/7zip/Compress/Branch/x86.h +++ b/7zip/Compress/Branch/x86.h @@ -1,13 +1,19 @@ // x86.h -#pragma once - #ifndef __X86_H #define __X86_H -#include "Coder.h" +#include "BranchCoder.h" +#include "BranchX86.h" + +struct CBranch86 +{ + UInt32 _prevMask; + UInt32 _prevPos; + void x86Init() { x86_Convert_Init(_prevMask, _prevPos); } +}; -MyClass(BCJ_x86, 0x01, 3) -// MyClass(x86_J, 0x01, 2) +MyClassB(BCJ_x86, 0x01, 3, CBranch86 , + virtual void SubInit() { x86Init(); }) #endif diff --git a/7zip/Compress/Branch/x86_2.cpp b/7zip/Compress/Branch/x86_2.cpp index 88d7f750..2f67899f 100755 --- a/7zip/Compress/Branch/x86_2.cpp +++ b/7zip/Compress/Branch/x86_2.cpp @@ -3,27 +3,46 @@ #include "StdAfx.h" #include "x86_2.h" -#include "Windows/Defs.h" -#include "../../ICoder.h" +#include "../../../Common/Alloc.h" -inline UINT32 Swap4(UINT32 value) -{ - return (value << 24) | (value >> 24) | - ( (value >> 8) & 0xFF00) | ( (value << 8) & 0xFF0000); -} +static const int kBufferSize = 1 << 17; -inline bool IsJcc(BYTE b0, BYTE b1) +inline bool IsJcc(Byte b0, Byte b1) { return (b0 == 0x0F && (b1 & 0xF0) == 0x80); } #ifndef EXTRACT_ONLY -static bool inline Test86MSByte(BYTE b) +static bool inline Test86MSByte(Byte b) { return (b == 0 || b == 0xFF); } +bool CBCJ2_x86_Encoder::Create() +{ + if (!_mainStream.Create(1 << 16)) + return false; + if (!_callStream.Create(1 << 20)) + return false; + if (!_jumpStream.Create(1 << 20)) + return false; + if (!_rangeEncoder.Create(1 << 20)) + return false; + if (_buffer == 0) + { + _buffer = (Byte *)BigAlloc(kBufferSize); + if (_buffer == 0) + return false; + } + return true; +} + +CBCJ2_x86_Encoder::~CBCJ2_x86_Encoder() +{ + BigFree(_buffer); +} + HRESULT CBCJ2_x86_Encoder::Flush() { RINOK(_mainStream.Flush()); @@ -33,21 +52,24 @@ HRESULT CBCJ2_x86_Encoder::Flush() return _rangeEncoder.FlushStream(); } -const UINT32 kDefaultLimit = (1 << 24); +const UInt32 kDefaultLimit = (1 << 24); HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams, - const UINT64 **inSizes, - UINT32 numInStreams, + const UInt64 **inSizes, + UInt32 numInStreams, ISequentialOutStream **outStreams, - const UINT64 **outSizes, - UINT32 numOutStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, ICompressProgressInfo *progress) { if (numInStreams != 1 || numOutStreams != 4) return E_INVALIDARG; + if (!Create()) + return E_OUTOFMEMORY; + bool sizeIsDefined = false; - UINT64 inSize; + UInt64 inSize; if (inSizes != NULL) if (inSizes[0] != NULL) { @@ -56,48 +78,50 @@ HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams, sizeIsDefined = true; } - ISequentialInStream *inStream = inStreams[0]; - _mainStream.Init(outStreams[0]); - _callStream.Init(outStreams[1]); - _jumpStream.Init(outStreams[2]); - _rangeEncoder.Init(outStreams[3]); + _mainStream.SetStream(outStreams[0]); + _mainStream.Init(); + _callStream.SetStream(outStreams[1]); + _callStream.Init(); + _jumpStream.SetStream(outStreams[2]); + _jumpStream.Init(); + _rangeEncoder.SetStream(outStreams[3]); + _rangeEncoder.Init(); for (int i = 0; i < 256; i++) _statusE8Encoder[i].Init(); _statusE9Encoder.Init(); _statusJccEncoder.Init(); - // CCoderReleaser releaser(this); + CCoderReleaser releaser(this); CMyComPtr<ICompressGetSubStreamSize> getSubStreamSize; { inStream->QueryInterface(IID_ICompressGetSubStreamSize, (void **)&getSubStreamSize); } + UInt32 nowPos = 0; + UInt64 nowPos64 = 0; + UInt32 bufferPos = 0; + UInt32 processedSize; - UINT32 nowPos = 0; - UINT64 nowPos64 = 0; - UINT32 bufferPos = 0; - UINT32 processedSize; - - BYTE prevByte = 0; + Byte prevByte = 0; - UINT64 subStreamIndex = 0; - UINT64 subStreamStartPos = 0; - UINT64 subStreamEndPos = 0; + UInt64 subStreamIndex = 0; + UInt64 subStreamStartPos = 0; + UInt64 subStreamEndPos = 0; while(true) { - UINT32 size = kBufferSize - bufferPos; + UInt32 size = kBufferSize - bufferPos; RINOK(inStream->Read(_buffer + bufferPos, size, &processedSize)); - UINT32 endPos = bufferPos + processedSize; + UInt32 endPos = bufferPos + processedSize; if (endPos < 5) { // change it for (bufferPos = 0; bufferPos < endPos; bufferPos++) { - BYTE b = _buffer[bufferPos]; + Byte b = _buffer[bufferPos]; _mainStream.WriteByte(b); if (b == 0xE8) _statusE8Encoder[prevByte].Encode(&_rangeEncoder, 0); @@ -112,10 +136,10 @@ HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams, bufferPos = 0; - UINT32 limit = endPos - 5; + UInt32 limit = endPos - 5; while(bufferPos <= limit) { - BYTE b = _buffer[bufferPos]; + Byte b = _buffer[bufferPos]; _mainStream.WriteByte(b); if (b != 0xE8 && b != 0xE9 && !IsJcc(prevByte, b)) { @@ -123,21 +147,21 @@ HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams, prevByte = b; continue; } - BYTE nextByte = _buffer[bufferPos + 4]; - UINT32 src = - (UINT32(nextByte) << 24) | - (UINT32(_buffer[bufferPos + 3]) << 16) | - (UINT32(_buffer[bufferPos + 2]) << 8) | + Byte nextByte = _buffer[bufferPos + 4]; + UInt32 src = + (UInt32(nextByte) << 24) | + (UInt32(_buffer[bufferPos + 3]) << 16) | + (UInt32(_buffer[bufferPos + 2]) << 8) | (_buffer[bufferPos + 1]); - UINT32 dest = (nowPos + bufferPos + 5) + src; + UInt32 dest = (nowPos + bufferPos + 5) + src; // if (Test86MSByte(nextByte)) bool convert; if (getSubStreamSize != NULL) { - UINT64 currentPos = (nowPos64 + bufferPos); + UInt64 currentPos = (nowPos64 + bufferPos); while (subStreamEndPos < currentPos) { - UINT64 subStreamSize; + UInt64 subStreamSize; HRESULT result = getSubStreamSize->GetSubStreamSize(subStreamIndex, &subStreamSize); if (result == S_OK) { @@ -165,7 +189,7 @@ HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams, convert = Test86MSByte(nextByte); else { - UINT64 dest64 = (currentPos + 5) + INT64(INT32(src)); + UInt64 dest64 = (currentPos + 5) + Int64(Int32(src)); convert = (dest64 >= subStreamStartPos && dest64 < subStreamEndPos); } } @@ -182,13 +206,21 @@ HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams, else _statusJccEncoder.Encode(&_rangeEncoder, 1); - dest = Swap4(dest); - bufferPos += 5; if (b == 0xE8) - _callStream.WriteBytes(&dest, sizeof(dest)); + { + _callStream.WriteByte((Byte)(dest >> 24)); + _callStream.WriteByte((Byte)(dest >> 16)); + _callStream.WriteByte((Byte)(dest >> 8)); + _callStream.WriteByte((Byte)(dest)); + } else - _jumpStream.WriteBytes(&dest, sizeof(dest)); + { + _jumpStream.WriteByte((Byte)(dest >> 24)); + _jumpStream.WriteByte((Byte)(dest >> 16)); + _jumpStream.WriteByte((Byte)(dest >> 8)); + _jumpStream.WriteByte((Byte)(dest)); + } prevByte = nextByte; } else @@ -211,8 +243,7 @@ HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams, RINOK(progress->SetRatioInfo(&nowPos64, NULL)); } - - UINT32 i = 0; + UInt32 i = 0; while(bufferPos < endPos) _buffer[i++] = _buffer[bufferPos++]; bufferPos = i; @@ -220,11 +251,11 @@ HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams, } STDMETHODIMP CBCJ2_x86_Encoder::Code(ISequentialInStream **inStreams, - const UINT64 **inSizes, - UINT32 numInStreams, + const UInt64 **inSizes, + UInt32 numInStreams, ISequentialOutStream **outStreams, - const UINT64 **outSizes, - UINT32 numOutStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, ICompressProgressInfo *progress) { try @@ -239,41 +270,58 @@ STDMETHODIMP CBCJ2_x86_Encoder::Code(ISequentialInStream **inStreams, #endif HRESULT CBCJ2_x86_Decoder::CodeReal(ISequentialInStream **inStreams, - const UINT64 **inSizes, - UINT32 numInStreams, + const UInt64 **inSizes, + UInt32 numInStreams, ISequentialOutStream **outStreams, - const UINT64 **outSizes, - UINT32 numOutStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, ICompressProgressInfo *progress) { if (numInStreams != 4 || numOutStreams != 1) return E_INVALIDARG; - _mainInStream.Init(inStreams[0]); - _callStream.Init(inStreams[1]); - _jumpStream.Init(inStreams[2]); - _rangeDecoder.Init(inStreams[3]); + if (!_mainInStream.Create(1 << 16)) + return E_OUTOFMEMORY; + if (!_callStream.Create(1 << 20)) + return E_OUTOFMEMORY; + if (!_jumpStream.Create(1 << 16)) + return E_OUTOFMEMORY; + if (!_rangeDecoder.Create(1 << 20)) + return E_OUTOFMEMORY; + if (!_outStream.Create(1 << 16)) + return E_OUTOFMEMORY; + + _mainInStream.SetStream(inStreams[0]); + _callStream.SetStream(inStreams[1]); + _jumpStream.SetStream(inStreams[2]); + _rangeDecoder.SetStream(inStreams[3]); + _outStream.SetStream(outStreams[0]); + + _mainInStream.Init(); + _callStream.Init(); + _jumpStream.Init(); + _rangeDecoder.Init(); + _outStream.Init(); + for (int i = 0; i < 256; i++) _statusE8Decoder[i].Init(); _statusE9Decoder.Init(); _statusJccDecoder.Init(); - _outStream.Init(outStreams[0]); - - // CCoderReleaser releaser(this); + CCoderReleaser releaser(this); - BYTE prevByte = 0; - UINT32 processedBytes = 0; + Byte prevByte = 0; + UInt32 processedBytes = 0; while(true) { if (processedBytes > (1 << 20) && progress != NULL) { - UINT64 nowPos64 = _outStream.GetProcessedSize(); + UInt64 nowPos64 = _outStream.GetProcessedSize(); RINOK(progress->SetRatioInfo(NULL, &nowPos64)); processedBytes = 0; } processedBytes++; - BYTE b; + Byte b; if (!_mainInStream.ReadByte(b)) return Flush(); _outStream.WriteByte(b); @@ -291,20 +339,44 @@ HRESULT CBCJ2_x86_Decoder::CodeReal(ISequentialInStream **inStreams, status = (_statusJccDecoder.Decode(&_rangeDecoder) == 1); if (status) { - UINT32 src; + UInt32 src; if (b == 0xE8) { - if (!_callStream.ReadBytes(&src, sizeof(src))) + Byte b0; + if(!_callStream.ReadByte(b0)) return S_FALSE; + src = ((UInt32)b0) << 24; + if(!_callStream.ReadByte(b0)) + return S_FALSE; + src |= ((UInt32)b0) << 16; + if(!_callStream.ReadByte(b0)) + return S_FALSE; + src |= ((UInt32)b0) << 8; + if(!_callStream.ReadByte(b0)) + return S_FALSE; + src |= ((UInt32)b0); } else { - if (!_jumpStream.ReadBytes(&src, sizeof(src))) + Byte b0; + if(!_jumpStream.ReadByte(b0)) + return S_FALSE; + src = ((UInt32)b0) << 24; + if(!_jumpStream.ReadByte(b0)) + return S_FALSE; + src |= ((UInt32)b0) << 16; + if(!_jumpStream.ReadByte(b0)) + return S_FALSE; + src |= ((UInt32)b0) << 8; + if(!_jumpStream.ReadByte(b0)) return S_FALSE; + src |= ((UInt32)b0); } - src = Swap4(src); - UINT32 dest = src - (UINT32(_outStream.GetProcessedSize()) + 4) ; - _outStream.WriteBytes(&dest, sizeof(dest)); + UInt32 dest = src - (UInt32(_outStream.GetProcessedSize()) + 4) ; + _outStream.WriteByte((Byte)(dest)); + _outStream.WriteByte((Byte)(dest >> 8)); + _outStream.WriteByte((Byte)(dest >> 16)); + _outStream.WriteByte((Byte)(dest >> 24)); prevByte = (dest >> 24); processedBytes += 4; } @@ -314,11 +386,11 @@ HRESULT CBCJ2_x86_Decoder::CodeReal(ISequentialInStream **inStreams, } STDMETHODIMP CBCJ2_x86_Decoder::Code(ISequentialInStream **inStreams, - const UINT64 **inSizes, - UINT32 numInStreams, + const UInt64 **inSizes, + UInt32 numInStreams, ISequentialOutStream **outStreams, - const UINT64 **outSizes, - UINT32 numOutStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, ICompressProgressInfo *progress) { try diff --git a/7zip/Compress/Branch/x86_2.h b/7zip/Compress/Branch/x86_2.h index 6d7aa958..3d34eb8d 100755 --- a/7zip/Compress/Branch/x86_2.h +++ b/7zip/Compress/Branch/x86_2.h @@ -1,14 +1,11 @@ // x86_2.h -#pragma once +#ifndef __BRANCH_X86_2_H +#define __BRANCH_X86_2_H -#ifndef __X86_2_H -#define __X86_2_H - -#include "Common/MyCom.h" -#include "Coder.h" +#include "../../../Common/MyCom.h" #include "../RangeCoder/RangeCoderBit.h" -// #include "../../Common/InBuffer.h" +#include "../../ICoder.h" // {23170F69-40C1-278B-0303-010100000100} #define MyClass2_a(Name, id, subId, encodingId) \ @@ -27,11 +24,13 @@ const int kNumMoveBits = 5; class CBCJ2_x86_Encoder: public ICompressCoder2, - public CDataBuffer, public CMyUnknownImp { + Byte *_buffer; public: - CBCJ2_x86_Encoder(): _mainStream(1 << 16) {} + CBCJ2_x86_Encoder(): _buffer(0) {}; + ~CBCJ2_x86_Encoder(); + bool Create(); COutBuffer _mainStream; COutBuffer _callStream; @@ -42,7 +41,6 @@ public: NCompress::NRangeCoder::CBitEncoder<kNumMoveBits> _statusJccEncoder; HRESULT Flush(); - /* void ReleaseStreams() { _mainStream.ReleaseStream(); @@ -55,32 +53,27 @@ public: { CBCJ2_x86_Encoder *_coder; public: - CCoderReleaser(CBCJ2_x86_Encoder *aCoder): _coder(aCoder) {} - ~CCoderReleaser() - { - _coder->ReleaseStreams(); - } + CCoderReleaser(CBCJ2_x86_Encoder *coder): _coder(coder) {} + ~CCoderReleaser() { _coder->ReleaseStreams(); } }; - friend class CCoderReleaser; - */ public: MY_UNKNOWN_IMP HRESULT CodeReal(ISequentialInStream **inStreams, - const UINT64 **inSizes, - UINT32 numInStreams, + const UInt64 **inSizes, + UInt32 numInStreams, ISequentialOutStream **outStreams, - const UINT64 **outSizes, - UINT32 numOutStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, ICompressProgressInfo *progress); STDMETHOD(Code)(ISequentialInStream **inStreams, - const UINT64 **inSizes, - UINT32 numInStreams, + const UInt64 **inSizes, + UInt32 numInStreams, ISequentialOutStream **outStreams, - const UINT64 **outSizes, - UINT32 numOutStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, ICompressProgressInfo *progress); }; @@ -91,8 +84,6 @@ class CBCJ2_x86_Decoder: public CMyUnknownImp { public: - CBCJ2_x86_Decoder(): _outStream(1 << 16), _mainInStream(1 << 16) {} - CInBuffer _mainInStream; CInBuffer _callStream; CInBuffer _jumpStream; @@ -103,7 +94,6 @@ public: COutBuffer _outStream; - /* void ReleaseStreams() { _mainInStream.ReleaseStream(); @@ -112,35 +102,31 @@ public: _rangeDecoder.ReleaseStream(); _outStream.ReleaseStream(); } - */ HRESULT Flush() { return _outStream.Flush(); } - /* class CCoderReleaser { CBCJ2_x86_Decoder *_coder; public: - CCoderReleaser(CBCJ2_x86_Decoder *aCoder): _coder(aCoder) {} + CCoderReleaser(CBCJ2_x86_Decoder *coder): _coder(coder) {} ~CCoderReleaser() { _coder->ReleaseStreams(); } }; - friend class CCoderReleaser; - */ public: MY_UNKNOWN_IMP HRESULT CodeReal(ISequentialInStream **inStreams, - const UINT64 **inSizes, - UINT32 numInStreams, + const UInt64 **inSizes, + UInt32 numInStreams, ISequentialOutStream **outStreams, - const UINT64 **outSizes, - UINT32 numOutStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, ICompressProgressInfo *progress); STDMETHOD(Code)(ISequentialInStream **inStreams, - const UINT64 **inSizes, - UINT32 numInStreams, + const UInt64 **inSizes, + UInt32 numInStreams, ISequentialOutStream **outStreams, - const UINT64 **outSizes, - UINT32 numOutStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, ICompressProgressInfo *progress); }; diff --git a/7zip/Compress/ByteSwap/ByteSwap.cpp b/7zip/Compress/ByteSwap/ByteSwap.cpp index 2db1a284..3f252f2c 100755 --- a/7zip/Compress/ByteSwap/ByteSwap.cpp +++ b/7zip/Compress/ByteSwap/ByteSwap.cpp @@ -1,100 +1,38 @@ -// Coder.cpp +// ByteSwap.cpp #include "StdAfx.h" #include "ByteSwap.h" -#include "Windows/Defs.h" -const int kBufferSize = 1 << 17; +STDMETHODIMP CByteSwap2::Init() { return S_OK; } -CBuffer::CBuffer(): - _buffer(0) +STDMETHODIMP_(UInt32) CByteSwap2::Filter(Byte *data, UInt32 size) { - _buffer = new BYTE[kBufferSize]; -} - -CBuffer::~CBuffer() -{ - delete []_buffer; -} - -STDMETHODIMP CByteSwap2::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, - ICompressProgressInfo *progress) -{ - const UINT32 kStep = 2; - UINT32 bufferPos = 0; - UINT64 nowPos64 = 0; - while(true) + const UInt32 kStep = 2; + UInt32 i; + for (i = 0; i + kStep <= size; i += kStep) { - UINT32 processedSize; - UINT32 size = kBufferSize - bufferPos; - RINOK(inStream->Read(_buffer + bufferPos, size, &processedSize)); - if (processedSize == 0) - return outStream->Write(_buffer, bufferPos, NULL); - - UINT32 endPos = bufferPos + processedSize; - for (UINT32 curPos = 0; curPos + kStep <= endPos; curPos += kStep) - { - BYTE data[kStep]; - data[0] = _buffer[curPos + 0]; - data[1] = _buffer[curPos + 1]; - _buffer[curPos + 0] = data[1]; - _buffer[curPos + 1] = data[0]; - } - RINOK(outStream->Write(_buffer, curPos, &processedSize)); - if (curPos != processedSize) - return E_FAIL; - nowPos64 += curPos; - if (progress != NULL) - { - RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64)); - } - bufferPos = 0; - while(curPos < endPos) - _buffer[bufferPos++] = _buffer[curPos++]; + Byte b = data[i]; + data[i] = data[i + 1]; + data[i + 1] = b; } + return i; } -STDMETHODIMP CByteSwap4::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, - ICompressProgressInfo *progress) +STDMETHODIMP CByteSwap4::Init() { return S_OK; } + +STDMETHODIMP_(UInt32) CByteSwap4::Filter(Byte *data, UInt32 size) { - const UINT32 kStep = 4; - UINT32 bufferPos = 0; - UINT64 nowPos64 = 0; - while(true) + const UInt32 kStep = 4; + UInt32 i; + for (i = 0; i + kStep <= size; i += kStep) { - UINT32 processedSize; - UINT32 size = kBufferSize - bufferPos; - RINOK(inStream->Read(_buffer + bufferPos, size, &processedSize)); - if (processedSize == 0) - return outStream->Write(_buffer, bufferPos, NULL); - - UINT32 endPos = bufferPos + processedSize; - for (UINT32 curPos = 0; curPos + kStep <= endPos; curPos += kStep) - { - BYTE data[kStep]; - data[0] = _buffer[curPos + 0]; - data[1] = _buffer[curPos + 1]; - data[2] = _buffer[curPos + 2]; - data[3] = _buffer[curPos + 3]; - _buffer[curPos + 0] = data[3]; - _buffer[curPos + 1] = data[2]; - _buffer[curPos + 2] = data[1]; - _buffer[curPos + 3] = data[0]; - } - RINOK(outStream->Write(_buffer, curPos, &processedSize)); - if (curPos != processedSize) - return E_FAIL; - nowPos64 += curPos; - if (progress != NULL) - { - RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64)); - } - bufferPos = 0; - while(curPos < endPos) - _buffer[bufferPos++] = _buffer[curPos++]; + Byte b0 = data[i]; + Byte b1 = data[i + 1]; + data[i] = data[i + 3]; + data[i + 1] = data[i + 2]; + data[i + 2] = b1; + data[i + 3] = b0; } + return i; } - diff --git a/7zip/Compress/ByteSwap/ByteSwap.h b/7zip/Compress/ByteSwap/ByteSwap.h index d8eff960..00303063 100755 --- a/7zip/Compress/ByteSwap/ByteSwap.h +++ b/7zip/Compress/ByteSwap/ByteSwap.h @@ -14,38 +14,24 @@ DEFINE_GUID(CLSID_CCompressConvertByteSwap2, DEFINE_GUID(CLSID_CCompressConvertByteSwap4, 0x23170F69, 0x40C1, 0x278B, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00); -class CBuffer -{ -protected: - BYTE *_buffer; -public: - CBuffer(); - ~CBuffer(); -}; - -class CByteSwap2 : - public ICompressCoder, - public CBuffer, +class CByteSwap2: + public ICompressFilter, public CMyUnknownImp { public: MY_UNKNOWN_IMP - STDMETHOD(Code)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, - ICompressProgressInfo *progress); + STDMETHOD(Init)(); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); }; -class CByteSwap4 : - public ICompressCoder, - public CBuffer, +class CByteSwap4: + public ICompressFilter, public CMyUnknownImp { public: MY_UNKNOWN_IMP - STDMETHOD(Code)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, - ICompressProgressInfo *progress); + STDMETHOD(Init)(); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); }; - -#endif
\ No newline at end of file +#endif diff --git a/7zip/Compress/ByteSwap/DllExports.cpp b/7zip/Compress/ByteSwap/DllExports.cpp index 4ce2a428..61a02c8d 100755 --- a/7zip/Compress/ByteSwap/DllExports.cpp +++ b/7zip/Compress/ByteSwap/DllExports.cpp @@ -2,8 +2,7 @@ #include "StdAfx.h" -#define INITGUID - +#include "Common/MyInitGuid.h" #include "Common/ComTry.h" #include "ByteSwap.h" #include "../../ICoder.h" @@ -18,19 +17,19 @@ STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) { COM_TRY_BEGIN *outObject = 0; - int correctInterface = (*iid == IID_ICompressCoder); - CMyComPtr<ICompressCoder> coder; + int correctInterface = (*iid == IID_ICompressFilter); + CMyComPtr<ICompressFilter> coder; if (*clsid == CLSID_CCompressConvertByteSwap2) { if (!correctInterface) return E_NOINTERFACE; - coder = (ICompressCoder *)new CByteSwap2(); + coder = (ICompressFilter *)new CByteSwap2(); } else if (*clsid == CLSID_CCompressConvertByteSwap4) { if (!correctInterface) return E_NOINTERFACE; - coder = (ICompressCoder *)new CByteSwap4(); + coder = (ICompressFilter *)new CByteSwap4(); } else return CLASS_E_CLASSNOTAVAILABLE; diff --git a/7zip/Compress/ByteSwap/StdAfx.cpp b/7zip/Compress/ByteSwap/StdAfx.cpp index 2550270c..d0feea85 100755 --- a/7zip/Compress/ByteSwap/StdAfx.cpp +++ b/7zip/Compress/ByteSwap/StdAfx.cpp @@ -1,3 +1,3 @@ // StdAfx.cpp -#include "stdafx.h" +#include "StdAfx.h" diff --git a/7zip/Compress/ByteSwap/StdAfx.h b/7zip/Compress/ByteSwap/StdAfx.h index a32fbed6..e7fb6986 100755 --- a/7zip/Compress/ByteSwap/StdAfx.h +++ b/7zip/Compress/ByteSwap/StdAfx.h @@ -1,8 +1,8 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> +#include "../../../Common/MyWindows.h" -#endif +#endif diff --git a/7zip/Compress/ByteSwap/resource.rc b/7zip/Compress/ByteSwap/resource.rc index c7e1c8e1..bc24ee42 100755 --- a/7zip/Compress/ByteSwap/resource.rc +++ b/7zip/Compress/ByteSwap/resource.rc @@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,9,2,0 - PRODUCTVERSION 3,9,2,0 + FILEVERSION 4,7,0,0 + PRODUCTVERSION 4,7,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -84,15 +84,15 @@ BEGIN BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Igor Pavlov\0" - VALUE "FileDescription", "Byte Swap converter \0" - VALUE "FileVersion", "3, 9, 2, 0\0" + VALUE "FileDescription", "Byte Swap filter\0" + VALUE "FileVersion", "4, 7, 0, 0\0" VALUE "InternalName", "Swap\0" - VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2004 Igor Pavlov\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "Swap.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "7-Zip\0" - VALUE "ProductVersion", "3, 9, 2, 0\0" + VALUE "ProductVersion", "4, 7, 0, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/7zip/Compress/Copy/Copy.dsp b/7zip/Compress/Copy/Copy.dsp index 02552719..4ab41ef3 100755 --- a/7zip/Compress/Copy/Copy.dsp +++ b/7zip/Compress/Copy/Copy.dsp @@ -113,6 +113,18 @@ SOURCE=.\StdAfx.cpp SOURCE=.\StdAfx.h # End Source File # End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# End Group # Begin Source File SOURCE=.\CopyCoder.cpp diff --git a/7zip/Compress/Copy/CopyCoder.cpp b/7zip/Compress/Copy/CopyCoder.cpp index 23e40a75..d8c7635b 100755 --- a/7zip/Compress/Copy/CopyCoder.cpp +++ b/7zip/Compress/Copy/CopyCoder.cpp @@ -3,32 +3,38 @@ #include "StdAfx.h" #include "CopyCoder.h" +#include "../../../Common/Alloc.h" namespace NCompress { -static const UINT32 kBufferSize = 1 << 17; - -CCopyCoder::CCopyCoder(): - TotalSize(0) -{ - _buffer = new BYTE[kBufferSize]; -} +static const UInt32 kBufferSize = 1 << 17; CCopyCoder::~CCopyCoder() { - delete []_buffer; + BigFree(_buffer); } STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UINT64 *inSize, const UINT64 *outSize, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { + if (_buffer == 0) + { + _buffer = (Byte *)BigAlloc(kBufferSize); + if (_buffer == 0) + return E_OUTOFMEMORY; + } + TotalSize = 0; while(true) { - UINT32 realProcessedSize; - RINOK(inStream->ReadPart(_buffer, kBufferSize, &realProcessedSize)); + UInt32 realProcessedSize; + UInt32 size = kBufferSize; + if (outSize != 0) + if (size > *outSize - TotalSize) + size = (UInt32)(*outSize - TotalSize); + RINOK(inStream->ReadPart(_buffer, size, &realProcessedSize)); if(realProcessedSize == 0) break; RINOK(outStream->Write(_buffer, realProcessedSize, NULL)); diff --git a/7zip/Compress/Copy/CopyCoder.h b/7zip/Compress/Copy/CopyCoder.h index 02447ad1..d2a26a89 100755 --- a/7zip/Compress/Copy/CopyCoder.h +++ b/7zip/Compress/Copy/CopyCoder.h @@ -1,31 +1,28 @@ // Compress/CopyCoder.h -// #pragma once - #ifndef __COMPRESS_COPYCODER_H #define __COMPRESS_COPYCODER_H #include "../../ICoder.h" #include "../../../Common/MyCom.h" - namespace NCompress { class CCopyCoder: public ICompressCoder, public CMyUnknownImp { - BYTE *_buffer; + Byte *_buffer; public: - UINT64 TotalSize; - CCopyCoder(); + UInt64 TotalSize; + CCopyCoder(): TotalSize(0) , _buffer(0) {}; ~CCopyCoder(); MY_UNKNOWN_IMP STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UINT64 *inSize, const UINT64 *outSize, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); }; diff --git a/7zip/Compress/Copy/DllExports.cpp b/7zip/Compress/Copy/DllExports.cpp index 47de3fd2..01d52dbf 100755 --- a/7zip/Compress/Copy/DllExports.cpp +++ b/7zip/Compress/Copy/DllExports.cpp @@ -2,10 +2,10 @@ #include "StdAfx.h" -#include <initguid.h> +#include "../../../Common/MyInitGuid.h" +#include "../../../Common/ComTry.h" #include "CopyCoder.h" -#include "../../../Common/ComTry.h" // {23170F69-40C1-278B-0000-000000000000} DEFINE_GUID(CLSID_CCompressCopyCoder, diff --git a/7zip/Compress/Copy/StdAfx.cpp b/7zip/Compress/Copy/StdAfx.cpp index 2550270c..d0feea85 100755 --- a/7zip/Compress/Copy/StdAfx.cpp +++ b/7zip/Compress/Copy/StdAfx.cpp @@ -1,3 +1,3 @@ // StdAfx.cpp -#include "stdafx.h" +#include "StdAfx.h" diff --git a/7zip/Compress/Copy/StdAfx.h b/7zip/Compress/Copy/StdAfx.h index a32fbed6..e7fb6986 100755 --- a/7zip/Compress/Copy/StdAfx.h +++ b/7zip/Compress/Copy/StdAfx.h @@ -1,8 +1,8 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> +#include "../../../Common/MyWindows.h" -#endif +#endif diff --git a/7zip/Compress/Copy/resource.rc b/7zip/Compress/Copy/resource.rc index d3700ba7..d2da5431 100755 --- a/7zip/Compress/Copy/resource.rc +++ b/7zip/Compress/Copy/resource.rc @@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,8,1,0 - PRODUCTVERSION 3,8,1,0 + FILEVERSION 4,7,0,0 + PRODUCTVERSION 4,7,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -85,14 +85,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Igor Pavlov\0" VALUE "FileDescription", "Copy Coder\0" - VALUE "FileVersion", "3, 8, 1, 0\0" + VALUE "FileVersion", "4, 7, 0, 0\0" VALUE "InternalName", "Copy\0" - VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2004 Igor Pavlov\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "Copy.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "7-Zip\0" - VALUE "ProductVersion", "3, 8, 1, 0\0" + VALUE "ProductVersion", "4, 7, 0, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/7zip/Compress/Deflate/Deflate.dsp b/7zip/Compress/Deflate/Deflate.dsp index cd7a98f7..417cf581 100755 --- a/7zip/Compress/Deflate/Deflate.dsp +++ b/7zip/Compress/Deflate/Deflate.dsp @@ -188,6 +188,14 @@ SOURCE=..\..\Common\OutBuffer.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\CRC.cpp # End Source File # Begin Source File @@ -210,6 +218,26 @@ SOURCE=..\..\..\Common\NewHandler.h # Begin Group "LZ" # PROP Default_Filter "" +# Begin Group "BinTree" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTree.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTree3Z.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTreeMain.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\LZ\IMatchFinder.h +# End Source File # Begin Source File SOURCE=..\LZ\LZInWindow.cpp diff --git a/7zip/Compress/Deflate/DeflateConst.h b/7zip/Compress/Deflate/DeflateConst.h index 7a19a9a2..81c40fc1 100755 --- a/7zip/Compress/Deflate/DeflateConst.h +++ b/7zip/Compress/Deflate/DeflateConst.h @@ -1,7 +1,5 @@ // DeflateConst.h -#pragma once - #ifndef __DEFLATE_CONST_H #define __DEFLATE_CONST_H @@ -10,59 +8,59 @@ namespace NCompress { namespace NDeflate { -const UINT32 kLenTableSize = 29; +const UInt32 kLenTableSize = 29; -const UINT32 kStaticDistTableSize = 32; -const UINT32 kStaticLenTableSize = 31; +const UInt32 kStaticDistTableSize = 32; +const UInt32 kStaticLenTableSize = 31; -const UINT32 kReadTableNumber = 0x100; -const UINT32 kMatchNumber = kReadTableNumber + 1; +const UInt32 kReadTableNumber = 0x100; +const UInt32 kMatchNumber = kReadTableNumber + 1; -const UINT32 kMainTableSize = kMatchNumber + kLenTableSize; //298; -const UINT32 kStaticMainTableSize = kMatchNumber + kStaticLenTableSize; //298; +const UInt32 kMainTableSize = kMatchNumber + kLenTableSize; //298; +const UInt32 kStaticMainTableSize = kMatchNumber + kStaticLenTableSize; //298; -const UINT32 kDistTableStart = kMainTableSize; +const UInt32 kDistTableStart = kMainTableSize; -const UINT32 kHeapTablesSizesSum32 = kMainTableSize + kDistTableSize32; -const UINT32 kHeapTablesSizesSum64 = kMainTableSize + kDistTableSize64; +const UInt32 kHeapTablesSizesSum32 = kMainTableSize + kDistTableSize32; +const UInt32 kHeapTablesSizesSum64 = kMainTableSize + kDistTableSize64; -const UINT32 kLevelTableSize = 19; +const UInt32 kLevelTableSize = 19; -const UINT32 kMaxTableSize32 = kHeapTablesSizesSum32; // test it -const UINT32 kMaxTableSize64 = kHeapTablesSizesSum64; // test it +const UInt32 kMaxTableSize32 = kHeapTablesSizesSum32; // test it +const UInt32 kMaxTableSize64 = kHeapTablesSizesSum64; // test it -const UINT32 kStaticMaxTableSize = kStaticMainTableSize + kStaticDistTableSize; +const UInt32 kStaticMaxTableSize = kStaticMainTableSize + kStaticDistTableSize; -const UINT32 kTableDirectLevels = 16; -const UINT32 kTableLevelRepNumber = kTableDirectLevels; -const UINT32 kTableLevel0Number = kTableLevelRepNumber + 1; -const UINT32 kTableLevel0Number2 = kTableLevel0Number + 1; +const UInt32 kTableDirectLevels = 16; +const UInt32 kTableLevelRepNumber = kTableDirectLevels; +const UInt32 kTableLevel0Number = kTableLevelRepNumber + 1; +const UInt32 kTableLevel0Number2 = kTableLevel0Number + 1; -const UINT32 kLevelMask = 0xF; +const UInt32 kLevelMask = 0xF; -const BYTE kLenStart32[kLenTableSize] = +const Byte kLenStart32[kLenTableSize] = {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224, 255}; -const BYTE kLenStart64[kLenTableSize] = +const Byte kLenStart64[kLenTableSize] = {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224, 0}; -const BYTE kLenDirectBits32[kLenTableSize] = +const Byte kLenDirectBits32[kLenTableSize] = {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0}; -const BYTE kLenDirectBits64[kLenTableSize] = +const Byte kLenDirectBits64[kLenTableSize] = {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 16}; -const UINT32 kDistStart[kDistTableSize64] = +const UInt32 kDistStart[kDistTableSize64] = {0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768, 1024,1536,2048,3072,4096,6144,8192,12288,16384,24576, 32768, 49152}; -const BYTE kDistDirectBits[kDistTableSize64] = +const Byte kDistDirectBits[kDistTableSize64] = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14}; -const BYTE kLevelDirectBits[kLevelTableSize] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7}; +const Byte kLevelDirectBits[kLevelTableSize] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7}; -const BYTE kCodeLengthAlphabetOrder[kLevelTableSize] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; +const Byte kCodeLengthAlphabetOrder[kLevelTableSize] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; -const UINT32 kMatchMinLen = 3; -const UINT32 kMatchMaxLen32 = kNumLenCombinations32 + kMatchMinLen - 1; //256 + 2; test it -const UINT32 kMatchMaxLen64 = kNumLenCombinations64 + kMatchMinLen - 1; //255 + 2; test it +const UInt32 kMatchMinLen = 3; +const UInt32 kMatchMaxLen32 = kNumLenCombinations32 + kMatchMinLen - 1; //256 + 2; test it +const UInt32 kMatchMaxLen64 = kNumLenCombinations64 + kMatchMinLen - 1; //255 + 2; test it const int kFinalBlockFieldSize = 1; @@ -88,18 +86,18 @@ namespace NBlockType }; } -const UINT32 kDeflateNumberOfLengthCodesFieldSize = 5; -const UINT32 kDeflateNumberOfDistanceCodesFieldSize = 5; -const UINT32 kDeflateNumberOfLevelCodesFieldSize = 4; +const UInt32 kDeflateNumberOfLengthCodesFieldSize = 5; +const UInt32 kDeflateNumberOfDistanceCodesFieldSize = 5; +const UInt32 kDeflateNumberOfLevelCodesFieldSize = 4; -const UINT32 kDeflateNumberOfLitLenCodesMin = 257; +const UInt32 kDeflateNumberOfLitLenCodesMin = 257; -const UINT32 kDeflateNumberOfDistanceCodesMin = 1; -const UINT32 kDeflateNumberOfLevelCodesMin = 4; +const UInt32 kDeflateNumberOfDistanceCodesMin = 1; +const UInt32 kDeflateNumberOfLevelCodesMin = 4; -const UINT32 kDeflateLevelCodeFieldSize = 3; +const UInt32 kDeflateLevelCodeFieldSize = 3; -const UINT32 kDeflateStoredBlockLengthFieldSizeSize = 16; +const UInt32 kDeflateStoredBlockLengthFieldSizeSize = 16; }} diff --git a/7zip/Compress/Deflate/DeflateDecoder.cpp b/7zip/Compress/Deflate/DeflateDecoder.cpp index 25e638f1..96da47b3 100755 --- a/7zip/Compress/Deflate/DeflateDecoder.cpp +++ b/7zip/Compress/Deflate/DeflateDecoder.cpp @@ -3,29 +3,21 @@ #include "StdAfx.h" #include "DeflateDecoder.h" -#include "DeflateConst.h" - -#include "Windows/Defs.h" namespace NCompress { namespace NDeflate { namespace NDecoder { -CCoder::CCoder(bool deflate64Mode): - m_MainDecoder(kStaticMainTableSize), - m_DistDecoder(kStaticDistTableSize), - m_LevelDecoder(kLevelTableSize), - _deflate64Mode(deflate64Mode) -{} +CCoder::CCoder(bool deflate64Mode): _deflate64Mode(deflate64Mode) {} -void CCoder::DeCodeLevelTable(BYTE *newLevels, int numLevels) +void CCoder::DeCodeLevelTable(Byte *newLevels, int numLevels) { int i = 0; while (i < numLevels) { - UINT32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream); + UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream); if (number < kTableDirectLevels) - newLevels[i++] = BYTE(number); + newLevels[i++] = Byte(number); else { if (number == kTableLevelRepNumber) @@ -62,12 +54,12 @@ void CCoder::ReadTables(void) case NBlockType::kStored: { m_StoredMode = true; - UINT32 currentBitPosition = m_InBitStream.GetBitPosition(); - UINT32 numBitsForAlign = currentBitPosition > 0 ? (8 - currentBitPosition): 0; + UInt32 currentBitPosition = m_InBitStream.GetBitPosition(); + UInt32 numBitsForAlign = currentBitPosition > 0 ? (8 - currentBitPosition): 0; if (numBitsForAlign > 0) m_InBitStream.ReadBits(numBitsForAlign); m_StoredBlockSize = m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize); - WORD onesComplementReverse = ~WORD(m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize)); + UInt16 onesComplementReverse = ~(UInt16)(m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize)); if (m_StoredBlockSize != onesComplementReverse) throw CException(CException::kData); break; @@ -76,8 +68,8 @@ void CCoder::ReadTables(void) case NBlockType::kDynamicHuffman: { m_StoredMode = false; - BYTE litLenLevels[kStaticMainTableSize]; - BYTE distLevels[kStaticDistTableSize]; + Byte litLenLevels[kStaticMainTableSize]; + Byte distLevels[kStaticDistTableSize]; if (blockType == NBlockType::kFixedHuffman) { int i; @@ -108,13 +100,13 @@ void CCoder::ReadTables(void) int numLevels = _deflate64Mode ? kHeapTablesSizesSum64 : kHeapTablesSizesSum32; - BYTE levelLevels[kLevelTableSize]; + Byte levelLevels[kLevelTableSize]; int i; for (i = 0; i < kLevelTableSize; i++) { int position = kCodeLengthAlphabetOrder[i]; if(i < numLevelCodes) - levelLevels[position] = BYTE(m_InBitStream.ReadBits(kDeflateLevelCodeFieldSize)); + levelLevels[position] = Byte(m_InBitStream.ReadBits(kDeflateLevelCodeFieldSize)); else levelLevels[position] = 0; } @@ -128,7 +120,7 @@ void CCoder::ReadTables(void) throw CException(CException::kData); } - BYTE tmpLevels[kStaticMaxTableSize]; + Byte tmpLevels[kStaticMaxTableSize]; DeCodeLevelTable(tmpLevels, numLitLenLevels + numDistLevels); memmove(litLenLevels, tmpLevels, numLitLenLevels); @@ -155,23 +147,19 @@ void CCoder::ReadTables(void) } HRESULT CCoder::CodeReal(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { - { - try - { - m_OutWindowStream.Create(_deflate64Mode ? kHistorySize64: kHistorySize32 /* , kMatchMaxLen */); - } - catch(...) - { - return E_OUTOFMEMORY; - } - } - UINT64 pos = 0; - m_OutWindowStream.Init(outStream, false); - m_InBitStream.Init(inStream); - // CCoderReleaser coderReleaser(this); + if (!m_OutWindowStream.Create(_deflate64Mode ? kHistorySize64: kHistorySize32)) + return E_OUTOFMEMORY; + if (!m_InBitStream.Create(1 << 17)) + return E_OUTOFMEMORY; + UInt64 pos = 0; + m_OutWindowStream.SetStream(outStream); + m_OutWindowStream.Init(false); + m_InBitStream.SetStream(inStream); + m_InBitStream.Init(); + CCoderReleaser coderReleaser(this); m_FinalBlock = false; @@ -179,14 +167,14 @@ HRESULT CCoder::CodeReal(ISequentialInStream *inStream, { if (progress != NULL) { - UINT64 packSize = m_InBitStream.GetProcessedSize(); + UInt64 packSize = m_InBitStream.GetProcessedSize(); RINOK(progress->SetRatioInfo(&packSize, &pos)); } ReadTables(); if(m_StoredMode) { - for (UINT32 i = 0; i < m_StoredBlockSize; i++) - m_OutWindowStream.PutOneByte(BYTE(m_InBitStream.ReadBits(8))); + for (UInt32 i = 0; i < m_StoredBlockSize; i++) + m_OutWindowStream.PutByte(Byte(m_InBitStream.ReadBits(8))); pos += m_StoredBlockSize; continue; } @@ -195,13 +183,13 @@ HRESULT CCoder::CodeReal(ISequentialInStream *inStream, if (m_InBitStream.NumExtraBytes > 4) throw CException(CException::kData); - UINT32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream); + UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream); if (number < 256) { if (outSize != NULL) if (pos >= *outSize) throw CException(CException::kData); - m_OutWindowStream.PutOneByte(BYTE(number)); + m_OutWindowStream.PutByte(Byte(number)); pos++; continue; } @@ -212,28 +200,28 @@ HRESULT CCoder::CodeReal(ISequentialInStream *inStream, throw CException(CException::kData); number -= kMatchNumber; - UINT32 length; + UInt32 length; if (_deflate64Mode) { - length = UINT32(kLenStart64[number]) + kMatchMinLen; - UINT32 numBits = kLenDirectBits64[number]; + length = UInt32(kLenStart64[number]) + kMatchMinLen; + UInt32 numBits = kLenDirectBits64[number]; if (numBits > 0) length += m_InBitStream.ReadBits(numBits); } else { - length = UINT32(kLenStart32[number]) + kMatchMinLen; - UINT32 numBits = kLenDirectBits32[number]; + length = UInt32(kLenStart32[number]) + kMatchMinLen; + UInt32 numBits = kLenDirectBits32[number]; if (numBits > 0) length += m_InBitStream.ReadBits(numBits); } number = m_DistDecoder.DecodeSymbol(&m_InBitStream); - UINT32 distance = kDistStart[number] + m_InBitStream.ReadBits(kDistDirectBits[number]); + UInt32 distance = kDistStart[number] + m_InBitStream.ReadBits(kDistDirectBits[number]); if (distance >= pos) throw "data error"; - m_OutWindowStream.CopyBackBlock(distance, length); + m_OutWindowStream.CopyBlock(distance, length); pos += length; } else if (number == kReadTableNumber) @@ -242,11 +230,12 @@ HRESULT CCoder::CodeReal(ISequentialInStream *inStream, throw CException(CException::kData); } } + coderReleaser.NeedFlush = false; return m_OutWindowStream.Flush(); } HRESULT CCoder::BaseCode(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { try { return CodeReal(inStream, outStream, inSize, outSize, progress); } @@ -255,7 +244,7 @@ HRESULT CCoder::BaseCode(ISequentialInStream *inStream, catch(...) { return S_FALSE; } } -HRESULT CCoder::BaseGetInStreamProcessedSize(UINT64 *value) +HRESULT CCoder::BaseGetInStreamProcessedSize(UInt64 *value) { if (value == NULL) return E_INVALIDARG; @@ -263,25 +252,25 @@ HRESULT CCoder::BaseGetInStreamProcessedSize(UINT64 *value) return S_OK; } -STDMETHODIMP CCOMCoder::GetInStreamProcessedSize(UINT64 *value) +STDMETHODIMP CCOMCoder::GetInStreamProcessedSize(UInt64 *value) { return BaseGetInStreamProcessedSize(value); } HRESULT CCOMCoder::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { return BaseCode(inStream, outStream, inSize, outSize, progress); } -STDMETHODIMP CCOMCoder64::GetInStreamProcessedSize(UINT64 *value) +STDMETHODIMP CCOMCoder64::GetInStreamProcessedSize(UInt64 *value) { return BaseGetInStreamProcessedSize(value); } HRESULT CCOMCoder64::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { return BaseCode(inStream, outStream, inSize, outSize, progress); diff --git a/7zip/Compress/Deflate/DeflateDecoder.h b/7zip/Compress/Deflate/DeflateDecoder.h index 446e2eb9..b1be0084 100755 --- a/7zip/Compress/Deflate/DeflateDecoder.h +++ b/7zip/Compress/Deflate/DeflateDecoder.h @@ -1,11 +1,9 @@ // DeflateDecoder.h -#pragma once - #ifndef __DEFLATE_DECODER_H #define __DEFLATE_DECODER_H -#include "Common/MyCom.h" +#include "../../../Common/MyCom.h" #include "../../ICoder.h" #include "../../Common/LSBFDecoder.h" @@ -14,6 +12,7 @@ #include "../Huffman/HuffmanDecoder.h" #include "DeflateExtConst.h" +#include "DeflateConst.h" namespace NCompress { namespace NDeflate { @@ -30,26 +29,24 @@ public: }; typedef NStream::NLSBF::CDecoder<CInBuffer> CInBit; -typedef NCompress::NHuffman::CDecoder<kNumHuffmanBits> CHuffmanDecoder; class CCoder { CLZOutWindow m_OutWindowStream; CInBit m_InBitStream; - CHuffmanDecoder m_MainDecoder; - CHuffmanDecoder m_DistDecoder; - CHuffmanDecoder m_LevelDecoder; // table for decoding other tables; + NCompress::NHuffman::CDecoder<kNumHuffmanBits, kStaticMainTableSize> m_MainDecoder; + NCompress::NHuffman::CDecoder<kNumHuffmanBits, kStaticDistTableSize> m_DistDecoder; + NCompress::NHuffman::CDecoder<kNumHuffmanBits, kLevelTableSize> m_LevelDecoder; bool m_FinalBlock; bool m_StoredMode; - UINT32 m_StoredBlockSize; + UInt32 m_StoredBlockSize; bool _deflate64Mode; - void DeCodeLevelTable(BYTE *newLevels, int numLevels); + void DeCodeLevelTable(Byte *newLevels, int numLevels); void ReadTables(); - /* void CCoder::ReleaseStreams() { m_OutWindowStream.ReleaseStream(); @@ -59,29 +56,30 @@ class CCoder { CCoder *m_Coder; public: - CCoderReleaser(CCoder *coder): m_Coder(coder) {} + bool NeedFlush; + CCoderReleaser(CCoder *coder): m_Coder(coder), NeedFlush(true) {} ~CCoderReleaser() { - m_Coder->m_OutWindowStream.Flush(); + if (NeedFlush) + m_Coder->m_OutWindowStream.Flush(); m_Coder->ReleaseStreams(); } }; friend class CCoderReleaser; - */ public: CCoder(bool deflate64Mode = false); HRESULT CodeReal(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); HRESULT BaseCode(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); // IGetInStreamProcessedSize - HRESULT BaseGetInStreamProcessedSize(UINT64 *aValue); + HRESULT BaseGetInStreamProcessedSize(UInt64 *aValue); }; class CCOMCoder : @@ -95,11 +93,11 @@ public: MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize) STDMETHOD(Code)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); // IGetInStreamProcessedSize - STDMETHOD(GetInStreamProcessedSize)(UINT64 *aValue); + STDMETHOD(GetInStreamProcessedSize)(UInt64 *aValue); CCOMCoder(): CCoder(false) {} }; @@ -114,11 +112,11 @@ public: MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize) STDMETHOD(Code)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); // IGetInStreamProcessedSize - STDMETHOD(GetInStreamProcessedSize)(UINT64 *aValue); + STDMETHOD(GetInStreamProcessedSize)(UInt64 *aValue); CCOMCoder64(): CCoder(true) {} }; diff --git a/7zip/Compress/Deflate/DeflateEncoder.cpp b/7zip/Compress/Deflate/DeflateEncoder.cpp index 07fa3a9f..e2d55cd9 100755 --- a/7zip/Compress/Deflate/DeflateEncoder.cpp +++ b/7zip/Compress/Deflate/DeflateEncoder.cpp @@ -7,7 +7,8 @@ #include "Windows/Defs.h" #include "Common/ComTry.h" -#include "../LZ/BinTree/BinTree3ZMain.h" +#include "../../../Common/Alloc.h" +#include "../LZ/BinTree/BinTree3Z.h" namespace NCompress { namespace NDeflate { @@ -25,22 +26,22 @@ static const int kValueBlockSize = 0x2000; static const int kMaxCodeBitLength = 15; static const int kMaxLevelBitLength = 7; -static const BYTE kFlagImm = 0; -static const BYTE kFlagLenPos = 4; +static const Byte kFlagImm = 0; +static const Byte kFlagLenPos = 4; -static const UINT32 kMaxUncompressedBlockSize = 0xFFFF; // test it !!! +static const UInt32 kMaxUncompressedBlockSize = 0xFFFF; // test it !!! -static const UINT32 kBlockUncompressedSizeThreshold = +static const UInt32 kBlockUncompressedSizeThreshold = kMaxUncompressedBlockSize - kMatchMaxLen32 - kNumOpts; static const int kNumGoodBacks = 0x10000; -static BYTE kNoLiteralDummy = 13; -static BYTE kNoLenDummy = 13; -static BYTE kNoPosDummy = 6; +static Byte kNoLiteralDummy = 13; +static Byte kNoLenDummy = 13; +static Byte kNoPosDummy = 6; -static BYTE g_LenSlots[kNumLenCombinations32]; -static BYTE g_FastPos[1 << 9]; +static Byte g_LenSlots[kNumLenCombinations32]; +static Byte g_FastPos[1 << 9]; class CFastPosInit { @@ -53,15 +54,15 @@ public: int c = kLenStart32[i]; int j = 1 << kLenDirectBits32[i]; for(int k = 0; k < j; k++, c++) - g_LenSlots[c] = i; + g_LenSlots[c] = (Byte)i; } const int kFastSlots = 18; int c = 0; - for (BYTE slotFast = 0; slotFast < kFastSlots; slotFast++) + for (Byte slotFast = 0; slotFast < kFastSlots; slotFast++) { - UINT32 k = (1 << kDistDirectBits[slotFast]); - for (UINT32 j = 0; j < k; j++, c++) + UInt32 k = (1 << kDistDirectBits[slotFast]); + for (UInt32 j = 0; j < k; j++, c++) g_FastPos[c] = slotFast; } } @@ -70,9 +71,9 @@ public: static CFastPosInit g_FastPosInit; -inline UINT32 GetPosSlot(UINT32 pos) +inline UInt32 GetPosSlot(UInt32 pos) { - // for (UINT32 i = 1; pos >= kDistStart[i]; i++); + // for (UInt32 i = 1; pos >= kDistStart[i]; i++); // return i - 1; if (pos < 0x200) return g_FastPos[pos]; @@ -81,11 +82,6 @@ inline UINT32 GetPosSlot(UINT32 pos) CCoder::CCoder(bool deflate64Mode): _deflate64Mode(deflate64Mode), - m_MainCoder(kMainTableSize, - deflate64Mode ? kLenDirectBits64 : kLenDirectBits32, - kMatchNumber, kMaxCodeBitLength), - m_DistCoder(deflate64Mode ? kDistTableSize64 : kDistTableSize32, kDistDirectBits, 0, kMaxCodeBitLength), - m_LevelCoder(kLevelTableSize, kLevelDirectBits, 0, kMaxLevelBitLength), m_NumPasses(1), m_NumFastBytes(32), m_OnePosMatchesMemory(0), @@ -99,47 +95,57 @@ CCoder::CCoder(bool deflate64Mode): kNumLenCombinations32; m_LenStart = deflate64Mode ? kLenStart64 : kLenStart32; m_LenDirectBits = deflate64Mode ? kLenDirectBits64 : kLenDirectBits32; - - m_Values = new CCodeValue[kValueBlockSize + kNumOpts]; } HRESULT CCoder::Create() { COM_TRY_BEGIN - m_MatchFinder.Create( - _deflate64Mode ? kHistorySize64 : kHistorySize32, - kNumOpts + kNumGoodBacks, m_NumFastBytes, - m_MatchMaxLen - m_NumFastBytes); + if (!m_MatchFinder) + { + m_MatchFinder = new NBT3Z::CMatchFinderBinTree; + if (m_MatchFinder == 0) + return E_OUTOFMEMORY; + } + if (m_Values == 0) + { + m_Values = (CCodeValue *)MyAlloc((kValueBlockSize + kNumOpts) * sizeof(CCodeValue)); + if (m_Values == 0) + return E_OUTOFMEMORY; + } + RINOK(m_MatchFinder->Create(_deflate64Mode ? kHistorySize64 : kHistorySize32, + kNumOpts + kNumGoodBacks, m_NumFastBytes, m_MatchMaxLen - m_NumFastBytes)); + if (!m_OutStream.Create(1 << 20)) + return E_OUTOFMEMORY; m_MatchLengthEdge = m_NumFastBytes + 1; + Free(); if (m_NumPasses > 1) { - m_OnePosMatchesMemory = new UINT16[kNumGoodBacks * (m_NumFastBytes + 1)]; - try - { - m_OnePosMatchesArray = new COnePosMatches[kNumGoodBacks]; - } - catch(...) - { - delete []m_OnePosMatchesMemory; - m_OnePosMatchesMemory = 0; - throw; - } - UINT16 *goodBacksWordsCurrent = m_OnePosMatchesMemory; + m_OnePosMatchesMemory = (UInt16 *)BigAlloc(kNumGoodBacks * (m_NumFastBytes + 1) * sizeof(UInt16)); + if (m_OnePosMatchesMemory == 0) + return E_OUTOFMEMORY; + m_OnePosMatchesArray = (COnePosMatches *)MyAlloc(kNumGoodBacks * sizeof(COnePosMatches)); + if (m_OnePosMatchesArray == 0) + return E_OUTOFMEMORY; + UInt16 *goodBacksWordsCurrent = m_OnePosMatchesMemory; for(int i = 0; i < kNumGoodBacks; i++, goodBacksWordsCurrent += (m_NumFastBytes + 1)) m_OnePosMatchesArray[i].Init(goodBacksWordsCurrent); } else - m_MatchDistances = new UINT16[m_NumFastBytes + 1]; + { + m_MatchDistances = (UInt16 *)MyAlloc((m_NumFastBytes + 1) * sizeof(UInt16)); + if (m_MatchDistances == 0) + return E_OUTOFMEMORY; + } return S_OK; COM_TRY_END } // ICompressSetEncoderProperties2 HRESULT CCoder::BaseSetEncoderProperties2(const PROPID *propIDs, - const PROPVARIANT *properties, UINT32 numProperties) + const PROPVARIANT *properties, UInt32 numProperties) { - for(UINT32 i = 0; i < numProperties; i++) + for(UInt32 i = 0; i < numProperties; i++) { const PROPVARIANT &property = properties[i]; switch(propIDs[i]) @@ -171,52 +177,52 @@ void CCoder::Free() { if (m_NumPasses > 1) { - delete []m_OnePosMatchesMemory; - delete []m_OnePosMatchesArray; + BigFree(m_OnePosMatchesMemory); + MyFree(m_OnePosMatchesArray); } else - delete []m_MatchDistances; + MyFree(m_MatchDistances); } } CCoder::~CCoder() { Free(); - delete []m_Values; + MyFree(m_Values); } void CCoder::ReadGoodBacks() { - UINT32 goodIndex; + UInt32 goodIndex; if (m_NumPasses > 1) { goodIndex = m_FinderPos % kNumGoodBacks; m_MatchDistances = m_OnePosMatchesArray[goodIndex].MatchDistances; } - UINT32 distanceTmp[kMatchMaxLen32 + 1]; - UINT32 len = m_MatchFinder.GetLongestMatch(distanceTmp); - for(UINT32 i = kMatchMinLen; i <= len; i++) - m_MatchDistances[i] = distanceTmp[i]; + UInt32 distanceTmp[kMatchMaxLen32 + 1]; + UInt32 len = m_MatchFinder->GetLongestMatch(distanceTmp); + for(UInt32 i = kMatchMinLen; i <= len; i++) + m_MatchDistances[i] = (UInt16)distanceTmp[i]; m_LongestMatchDistance = m_MatchDistances[len]; if (len == m_NumFastBytes && m_NumFastBytes != m_MatchMaxLen) - m_LongestMatchLength = len + m_MatchFinder.GetMatchLen(len, + m_LongestMatchLength = len + m_MatchFinder->GetMatchLen(len, m_LongestMatchDistance, m_MatchMaxLen - len); else m_LongestMatchLength = len; if (m_NumPasses > 1) { - m_OnePosMatchesArray[goodIndex].LongestMatchDistance = UINT16(m_LongestMatchDistance); - m_OnePosMatchesArray[goodIndex].LongestMatchLength = UINT16(m_LongestMatchLength); + m_OnePosMatchesArray[goodIndex].LongestMatchDistance = UInt16(m_LongestMatchDistance); + m_OnePosMatchesArray[goodIndex].LongestMatchLength = UInt16(m_LongestMatchLength); } - HRESULT result = m_MatchFinder.MovePos(); + HRESULT result = m_MatchFinder->MovePos(); if (result != S_OK) throw CMatchFinderException(result); m_FinderPos++; m_AdditionalOffset++; } -void CCoder::GetBacks(UINT32 pos) +void CCoder::GetBacks(UInt32 pos) { if(pos == m_FinderPos) ReadGoodBacks(); @@ -230,7 +236,7 @@ void CCoder::GetBacks(UINT32 pos) } else { - UINT32 goodIndex = pos % kNumGoodBacks; + UInt32 goodIndex = pos % kNumGoodBacks; m_MatchDistances = m_OnePosMatchesArray[goodIndex].MatchDistances; m_LongestMatchDistance = m_OnePosMatchesArray[goodIndex].LongestMatchDistance; m_LongestMatchLength = m_OnePosMatchesArray[goodIndex].LongestMatchLength; @@ -239,19 +245,19 @@ void CCoder::GetBacks(UINT32 pos) } -void CCoder::MovePos(UINT32 num) +void CCoder::MovePos(UInt32 num) { if (m_NumPasses > 1) { - for(UINT32 i = 0; i < num; i++) - GetBacks(UINT32(m_BlockStartPostion + m_CurrentBlockUncompressedSize + i + 1)); + for(UInt32 i = 0; i < num; i++) + GetBacks(UInt32(m_BlockStartPostion + m_CurrentBlockUncompressedSize + i + 1)); } else { for (;num > 0; num--) { - m_MatchFinder.DummyLongestMatch(); - HRESULT result = m_MatchFinder.MovePos(); + m_MatchFinder->DummyLongestMatch(); + HRESULT result = m_MatchFinder->MovePos(); if (result != S_OK) throw CMatchFinderException(result); m_FinderPos++; @@ -260,21 +266,21 @@ void CCoder::MovePos(UINT32 num) } } -static const UINT32 kIfinityPrice = 0xFFFFFFF; +static const UInt32 kIfinityPrice = 0xFFFFFFF; -UINT32 CCoder::Backward(UINT32 &backRes, UINT32 cur) +UInt32 CCoder::Backward(UInt32 &backRes, UInt32 cur) { m_OptimumEndIndex = cur; - UINT32 posMem = m_Optimum[cur].PosPrev; - UINT16 backMem = m_Optimum[cur].BackPrev; + UInt32 posMem = m_Optimum[cur].PosPrev; + UInt16 backMem = m_Optimum[cur].BackPrev; do { - UINT32 posPrev = posMem; - UINT16 backCur = backMem; + UInt32 posPrev = posMem; + UInt16 backCur = backMem; backMem = m_Optimum[posPrev].BackPrev; posMem = m_Optimum[posPrev].PosPrev; m_Optimum[posPrev].BackPrev = backCur; - m_Optimum[posPrev].PosPrev = cur; + m_Optimum[posPrev].PosPrev = (UInt16)cur; cur = posPrev; } while(cur > 0); @@ -283,11 +289,11 @@ UINT32 CCoder::Backward(UINT32 &backRes, UINT32 cur) return m_OptimumCurrentIndex; } -UINT32 CCoder::GetOptimal(UINT32 &backRes) +UInt32 CCoder::GetOptimal(UInt32 &backRes) { if(m_OptimumEndIndex != m_OptimumCurrentIndex) { - UINT32 len = m_Optimum[m_OptimumCurrentIndex].PosPrev - m_OptimumCurrentIndex; + UInt32 len = m_Optimum[m_OptimumCurrentIndex].PosPrev - m_OptimumCurrentIndex; backRes = m_Optimum[m_OptimumCurrentIndex].BackPrev; m_OptimumCurrentIndex = m_Optimum[m_OptimumCurrentIndex].PosPrev; return len; @@ -295,10 +301,10 @@ UINT32 CCoder::GetOptimal(UINT32 &backRes) m_OptimumCurrentIndex = 0; m_OptimumEndIndex = 0; - GetBacks(UINT32(m_BlockStartPostion + m_CurrentBlockUncompressedSize)); + GetBacks(UInt32(m_BlockStartPostion + m_CurrentBlockUncompressedSize)); - UINT32 lenMain = m_LongestMatchLength; - UINT32 backMain = m_LongestMatchDistance; + UInt32 lenMain = m_LongestMatchLength; + UInt32 backMain = m_LongestMatchDistance; if(lenMain < kMatchMinLen) return 1; @@ -308,13 +314,13 @@ UINT32 CCoder::GetOptimal(UINT32 &backRes) MovePos(lenMain - 1); return lenMain; } - m_Optimum[1].Price = m_LiteralPrices[m_MatchFinder.GetIndexByte(0 - m_AdditionalOffset)]; + m_Optimum[1].Price = m_LiteralPrices[m_MatchFinder->GetIndexByte(0 - m_AdditionalOffset)]; m_Optimum[1].PosPrev = 0; m_Optimum[2].Price = kIfinityPrice; m_Optimum[2].PosPrev = 1; - for(UINT32 i = kMatchMinLen; i <= lenMain; i++) + for(UInt32 i = kMatchMinLen; i <= lenMain; i++) { m_Optimum[i].PosPrev = 0; m_Optimum[i].BackPrev = m_MatchDistances[i]; @@ -322,26 +328,26 @@ UINT32 CCoder::GetOptimal(UINT32 &backRes) } - UINT32 cur = 0; - UINT32 lenEnd = lenMain; + UInt32 cur = 0; + UInt32 lenEnd = lenMain; while(true) { cur++; if(cur == lenEnd) return Backward(backRes, cur); - GetBacks(UINT32(m_BlockStartPostion + m_CurrentBlockUncompressedSize + cur)); - UINT32 newLen = m_LongestMatchLength; + GetBacks(UInt32(m_BlockStartPostion + m_CurrentBlockUncompressedSize + cur)); + UInt32 newLen = m_LongestMatchLength; if(newLen >= m_MatchLengthEdge) return Backward(backRes, cur); - UINT32 curPrice = m_Optimum[cur].Price; - UINT32 curAnd1Price = curPrice + - m_LiteralPrices[m_MatchFinder.GetIndexByte(cur - m_AdditionalOffset)]; + UInt32 curPrice = m_Optimum[cur].Price; + UInt32 curAnd1Price = curPrice + + m_LiteralPrices[m_MatchFinder->GetIndexByte(cur - m_AdditionalOffset)]; COptimal &optimum = m_Optimum[cur + 1]; if (curAnd1Price < optimum.Price) { optimum.Price = curAnd1Price; - optimum.PosPrev = cur; + optimum.PosPrev = (UInt16)cur; } if (newLen < kMatchMinLen) continue; @@ -349,24 +355,24 @@ UINT32 CCoder::GetOptimal(UINT32 &backRes) { if (cur + newLen > kNumOpts - 1) newLen = kNumOpts - 1 - cur; - UINT32 lenEndNew = cur + newLen; + UInt32 lenEndNew = cur + newLen; if (lenEnd < lenEndNew) { - for(UINT32 i = lenEnd + 1; i <= lenEndNew; i++) + for(UInt32 i = lenEnd + 1; i <= lenEndNew; i++) m_Optimum[i].Price = kIfinityPrice; lenEnd = lenEndNew; } } - for(UINT32 lenTest = kMatchMinLen; lenTest <= newLen; lenTest++) + for(UInt32 lenTest = kMatchMinLen; lenTest <= newLen; lenTest++) { - UINT16 curBack = m_MatchDistances[lenTest]; - UINT32 curAndLenPrice = curPrice + + UInt16 curBack = m_MatchDistances[lenTest]; + UInt32 curAndLenPrice = curPrice + m_LenPrices[lenTest - kMatchMinLen] + m_PosPrices[GetPosSlot(curBack)]; COptimal &optimum = m_Optimum[cur + lenTest]; if (curAndLenPrice < optimum.Price) { optimum.Price = curAndLenPrice; - optimum.PosPrev = cur; + optimum.PosPrev = (UInt16)cur; optimum.BackPrev = curBack; } } @@ -389,13 +395,13 @@ void CCoder::InitStructures() m_MainCoder.StartNewBlock(); m_DistCoder.StartNewBlock(); - UINT32 i; + UInt32 i; for(i = 0; i < 256; i++) m_LiteralPrices[i] = 8; for(i = 0; i < m_NumLenCombinations; i++) - m_LenPrices[i] = 5 + m_LenDirectBits[g_LenSlots[i]]; // test it + m_LenPrices[i] = (Byte)(5 + m_LenDirectBits[g_LenSlots[i]]); // test it for(i = 0; i < kDistTableSize64; i++) - m_PosPrices[i] = 5 + kDistDirectBits[i]; + m_PosPrices[i] = (Byte)(5 + kDistDirectBits[i]); } void CCoder::WriteBlockData(bool writeMode, bool finalBlock) @@ -407,27 +413,27 @@ void CCoder::WriteBlockData(bool writeMode, bool finalBlock) { if(method == NBlockType::kStored) { - for(UINT32 i = 0; i < m_CurrentBlockUncompressedSize; i++) + for(UInt32 i = 0; i < m_CurrentBlockUncompressedSize; i++) { - BYTE b = m_MatchFinder.GetIndexByte(i - m_AdditionalOffset - + Byte b = m_MatchFinder->GetIndexByte(i - m_AdditionalOffset - m_CurrentBlockUncompressedSize); m_OutStream.WriteBits(b, 8); } } else { - for (UINT32 i = 0; i < m_ValueIndex; i++) + for (UInt32 i = 0; i < m_ValueIndex; i++) { if (m_Values[i].Flag == kFlagImm) m_MainCoder.CodeOneValue(&m_ReverseOutStream, m_Values[i].Imm); else if (m_Values[i].Flag == kFlagLenPos) { - UINT32 len = m_Values[i].Len; - UINT32 lenSlot = g_LenSlots[len]; + UInt32 len = m_Values[i].Len; + UInt32 lenSlot = g_LenSlots[len]; m_MainCoder.CodeOneValue(&m_ReverseOutStream, kMatchNumber + lenSlot); m_OutStream.WriteBits(len - m_LenStart[lenSlot], m_LenDirectBits[lenSlot]); - UINT32 dist = m_Values[i].Pos; - UINT32 posSlot = GetPosSlot(dist); + UInt32 dist = m_Values[i].Pos; + UInt32 posSlot = GetPosSlot(dist); m_DistCoder.CodeOneValue(&m_ReverseOutStream, posSlot); m_OutStream.WriteBits(dist - kDistStart[posSlot], kDistDirectBits[posSlot]); } @@ -438,7 +444,7 @@ void CCoder::WriteBlockData(bool writeMode, bool finalBlock) m_MainCoder.StartNewBlock(); m_DistCoder.StartNewBlock(); m_ValueIndex = 0; - UINT32 i; + UInt32 i; for(i = 0; i < 256; i++) if(m_LastLevels[i] != 0) m_LiteralPrices[i] = m_LastLevels[i]; @@ -449,8 +455,8 @@ void CCoder::WriteBlockData(bool writeMode, bool finalBlock) for(i = 0; i < m_NumLenCombinations; i++) { - UINT32 slot = g_LenSlots[i]; - BYTE dummy = m_LastLevels[kMatchNumber + slot]; + UInt32 slot = g_LenSlots[i]; + Byte dummy = m_LastLevels[kMatchNumber + slot]; if (dummy != 0) m_LenPrices[i] = dummy; else @@ -459,7 +465,7 @@ void CCoder::WriteBlockData(bool writeMode, bool finalBlock) } for(i = 0; i < kDistTableSize64; i++) { - BYTE dummy = m_LastLevels[kDistTableStart + i]; + Byte dummy = m_LastLevels[kDistTableStart + i]; if (dummy != 0) m_PosPrices[i] = dummy; else @@ -468,7 +474,7 @@ void CCoder::WriteBlockData(bool writeMode, bool finalBlock) } } -void CCoder::CodeLevelTable(BYTE *newLevels, int numLevels, bool codeMode) +void CCoder::CodeLevelTable(Byte *newLevels, int numLevels, bool codeMode) { int prevLen = 0xFF; // last emitted length int nextLen = newLevels[0]; // length of next code @@ -480,7 +486,7 @@ void CCoder::CodeLevelTable(BYTE *newLevels, int numLevels, bool codeMode) maxCount = 138; minCount = 3; } - BYTE oldValueInGuardElement = newLevels[numLevels]; // push guard value + Byte oldValueInGuardElement = newLevels[numLevels]; // push guard value try { newLevels[numLevels] = 0xFF; // guard already set @@ -568,7 +574,7 @@ void CCoder::CodeLevelTable(BYTE *newLevels, int numLevels, bool codeMode) int CCoder::WriteTables(bool writeMode, bool finalBlock) { - BYTE newLevels[kMaxTableSize64 + 1]; // (+ 1) for guard + Byte newLevels[kMaxTableSize64 + 1]; // (+ 1) for guard m_MainCoder.BuildTree(&newLevels[0]); m_DistCoder.BuildTree(&newLevels[kDistTableStart]); @@ -604,22 +610,22 @@ int CCoder::WriteTables(bool writeMode, bool finalBlock) memcpy(m_LastLevels, newLevels, kMaxTableSize64); - BYTE levelLevels[kLevelTableSize]; + Byte levelLevels[kLevelTableSize]; m_LevelCoder.BuildTree(levelLevels); - BYTE levelLevelsStream[kLevelTableSize]; + Byte levelLevelsStream[kLevelTableSize]; int numLevelCodes = kDeflateNumberOfLevelCodesMin; int i; for (i = 0; i < kLevelTableSize; i++) { int streamPos = kCodeLengthAlphabetOrder[i]; - int level = levelLevels[streamPos]; + Byte level = levelLevels[streamPos]; if (level > 0 && i >= numLevelCodes) numLevelCodes = i + 1; levelLevelsStream[i] = level; } - UINT32 numLZHuffmanBits = m_MainCoder.GetBlockBitLength(); + UInt32 numLZHuffmanBits = m_MainCoder.GetBlockBitLength(); numLZHuffmanBits += m_DistCoder.GetBlockBitLength(); numLZHuffmanBits += m_LevelCoder.GetBlockBitLength(); numLZHuffmanBits += kDeflateNumberOfLengthCodesFieldSize + @@ -627,18 +633,18 @@ int CCoder::WriteTables(bool writeMode, bool finalBlock) kDeflateNumberOfLevelCodesFieldSize; numLZHuffmanBits += numLevelCodes * kDeflateLevelCodeFieldSize; - UINT32 nextBitPosition = + UInt32 nextBitPosition = (m_OutStream.GetBitPosition() + kBlockTypeFieldSize) % 8; - UINT32 numBitsForAlign = nextBitPosition > 0 ? (8 - nextBitPosition): 0; + UInt32 numBitsForAlign = nextBitPosition > 0 ? (8 - nextBitPosition): 0; - UINT32 numStoreBits = numBitsForAlign + (2 * sizeof(UINT16)) * 8; + UInt32 numStoreBits = numBitsForAlign + (2 * 2) * 8; numStoreBits += m_CurrentBlockUncompressedSize * 8; if(numStoreBits < numLZHuffmanBits) { m_OutStream.WriteBits(NBlockType::kStored, kBlockTypeFieldSize); // test it m_OutStream.WriteBits(0, numBitsForAlign); // test it - UINT16 currentBlockUncompressedSize = UINT16(m_CurrentBlockUncompressedSize); - UINT16 currentBlockUncompressedSizeNot = ~currentBlockUncompressedSize; + UInt16 currentBlockUncompressedSize = UInt16(m_CurrentBlockUncompressedSize); + UInt16 currentBlockUncompressedSizeNot = ~currentBlockUncompressedSize; m_OutStream.WriteBits(currentBlockUncompressedSize, kDeflateStoredBlockLengthFieldSizeSize); m_OutStream.WriteBits(currentBlockUncompressedSizeNot, kDeflateStoredBlockLengthFieldSizeSize); return NBlockType::kStored; @@ -669,23 +675,33 @@ int CCoder::WriteTables(bool writeMode, bool finalBlock) } HRESULT CCoder::CodeReal(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { if (!m_Created) { RINOK(Create()); + + if (!m_MainCoder.Create(kMainTableSize, _deflate64Mode ? kLenDirectBits64 : kLenDirectBits32, + kMatchNumber, kMaxCodeBitLength)) + return E_OUTOFMEMORY; + if (!m_DistCoder.Create(_deflate64Mode ? kDistTableSize64 : kDistTableSize32, + kDistDirectBits, 0, kMaxCodeBitLength)) + return E_OUTOFMEMORY; + if (!m_LevelCoder.Create(kLevelTableSize, kLevelDirectBits, 0, kMaxLevelBitLength)) + return E_OUTOFMEMORY; m_Created = true; } - UINT64 nowPos = 0; + UInt64 nowPos = 0; m_FinderPos = 0; - RINOK(m_MatchFinder.Init(inStream)); - m_OutStream.Init(outStream); + RINOK(m_MatchFinder->Init(inStream)); + m_OutStream.SetStream(outStream); + m_OutStream.Init(); m_ReverseOutStream.Init(&m_OutStream); - // CCoderReleaser coderReleaser(this); + CCoderReleaser coderReleaser(this); InitStructures(); while(true) @@ -696,29 +712,29 @@ HRESULT CCoder::CodeReal(ISequentialInStream *inStream, { while(true) { - noMoreBytes = (m_AdditionalOffset == 0 && m_MatchFinder.GetNumAvailableBytes() == 0); + noMoreBytes = (m_AdditionalOffset == 0 && m_MatchFinder->GetNumAvailableBytes() == 0); if (((m_CurrentBlockUncompressedSize >= kBlockUncompressedSizeThreshold || m_ValueIndex >= kValueBlockSize) && (m_OptimumEndIndex == m_OptimumCurrentIndex)) || noMoreBytes) break; - UINT32 pos; - UINT32 len = GetOptimal(pos); + UInt32 pos; + UInt32 len = GetOptimal(pos); if (len >= kMatchMinLen) { - UINT32 newLen = len - kMatchMinLen; + UInt32 newLen = len - kMatchMinLen; m_Values[m_ValueIndex].Flag = kFlagLenPos; - m_Values[m_ValueIndex].Len = BYTE(newLen); - UINT32 lenSlot = g_LenSlots[newLen]; + m_Values[m_ValueIndex].Len = Byte(newLen); + UInt32 lenSlot = g_LenSlots[newLen]; m_MainCoder.AddSymbol(kMatchNumber + lenSlot); - m_Values[m_ValueIndex].Pos = UINT16(pos); - UINT32 posSlot = GetPosSlot(pos); + m_Values[m_ValueIndex].Pos = UInt16(pos); + UInt32 posSlot = GetPosSlot(pos); m_DistCoder.AddSymbol(posSlot); } else if (len == 1) { - BYTE b = m_MatchFinder.GetIndexByte(0 - m_AdditionalOffset); + Byte b = m_MatchFinder->GetIndexByte(0 - m_AdditionalOffset); len = 1; m_MainCoder.AddSymbol(b); m_Values[m_ValueIndex].Flag = kFlagImm; @@ -738,14 +754,14 @@ HRESULT CCoder::CodeReal(ISequentialInStream *inStream, if (writeMode) break; nowPos = m_BlockStartPostion; - m_AdditionalOffset = UINT32(m_FinderPos - m_BlockStartPostion); + m_AdditionalOffset = UInt32(m_FinderPos - m_BlockStartPostion); m_CurrentBlockUncompressedSize = 0; } m_BlockStartPostion += m_CurrentBlockUncompressedSize; m_CurrentBlockUncompressedSize = 0; if (progress != NULL) { - UINT64 packSize = m_OutStream.GetProcessedSize(); + UInt64 packSize = m_OutStream.GetProcessedSize(); RINOK(progress->SetRatioInfo(&nowPos, &packSize)); } if (noMoreBytes) @@ -755,7 +771,7 @@ HRESULT CCoder::CodeReal(ISequentialInStream *inStream, } HRESULT CCoder::BaseCode(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { try { return CodeReal(inStream, outStream, inSize, outSize, progress); } @@ -765,21 +781,21 @@ HRESULT CCoder::BaseCode(ISequentialInStream *inStream, } STDMETHODIMP CCOMCoder::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { return BaseCode(inStream, outStream, inSize, outSize, progress); } STDMETHODIMP CCOMCoder::SetCoderProperties(const PROPID *propIDs, - const PROPVARIANT *properties, UINT32 numProperties) + const PROPVARIANT *properties, UInt32 numProperties) { return BaseSetEncoderProperties2(propIDs, properties, numProperties); } STDMETHODIMP CCOMCoder64::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { return BaseCode(inStream, outStream, inSize, outSize, progress); } STDMETHODIMP CCOMCoder64::SetCoderProperties(const PROPID *propIDs, - const PROPVARIANT *properties, UINT32 numProperties) + const PROPVARIANT *properties, UInt32 numProperties) { return BaseSetEncoderProperties2(propIDs, properties, numProperties); } }}} diff --git a/7zip/Compress/Deflate/DeflateEncoder.h b/7zip/Compress/Deflate/DeflateEncoder.h index 8ee38daf..d1d06311 100755 --- a/7zip/Compress/Deflate/DeflateEncoder.h +++ b/7zip/Compress/Deflate/DeflateEncoder.h @@ -1,7 +1,5 @@ // DeflateEncoder.h -#pragma once - #ifndef __DEFLATE_ENCODER_H #define __DEFLATE_ENCODER_H @@ -9,7 +7,7 @@ #include "../../ICoder.h" #include "../../Common/LSBFEncoder.h" -#include "../LZ/BinTree/BinTree3Z.h" +#include "../LZ/IMatchFinder.h" #include "../Huffman/HuffmanEncoder.h" #include "DeflateConst.h" @@ -20,22 +18,22 @@ namespace NEncoder { struct CCodeValue { - BYTE Flag; + Byte Flag; union { - BYTE Imm; - BYTE Len; + Byte Imm; + Byte Len; }; - UINT16 Pos; + UInt16 Pos; }; class COnePosMatches { public: - UINT16 *MatchDistances; - UINT16 LongestMatchLength; - UINT16 LongestMatchDistance; - void Init(UINT16 *matchDistances) + UInt16 *MatchDistances; + UInt16 LongestMatchLength; + UInt16 LongestMatchDistance; + void Init(UInt16 *matchDistances) { MatchDistances = matchDistances; }; @@ -43,21 +41,20 @@ public: struct COptimal { - UINT32 Price; - UINT16 PosPrev; - UINT16 BackPrev; + UInt32 Price; + UInt16 PosPrev; + UInt16 BackPrev; }; const int kNumOpts = 0x1000; class CCoder { - UINT32 m_FinderPos; + UInt32 m_FinderPos; COptimal m_Optimum[kNumOpts]; - // CComPtr<IInWindowStreamMatch> m_MatchFinder; - NBT3Z::CInTree m_MatchFinder; + CMyComPtr<IMatchFinder> m_MatchFinder; NStream::NLSBF::CEncoder m_OutStream; NStream::NLSBF::CReverseEncoder m_ReverseOutStream; @@ -66,93 +63,88 @@ class CCoder NCompression::NHuffman::CEncoder m_DistCoder; NCompression::NHuffman::CEncoder m_LevelCoder; - BYTE m_LastLevels[kMaxTableSize64]; + Byte m_LastLevels[kMaxTableSize64]; - UINT32 m_ValueIndex; + UInt32 m_ValueIndex; CCodeValue *m_Values; - UINT32 m_OptimumEndIndex; - UINT32 m_OptimumCurrentIndex; - UINT32 m_AdditionalOffset; + UInt32 m_OptimumEndIndex; + UInt32 m_OptimumCurrentIndex; + UInt32 m_AdditionalOffset; - UINT32 m_LongestMatchLength; - UINT32 m_LongestMatchDistance; - UINT16 *m_MatchDistances; + UInt32 m_LongestMatchLength; + UInt32 m_LongestMatchDistance; + UInt16 *m_MatchDistances; - UINT32 m_NumFastBytes; - UINT32 m_MatchLengthEdge; + UInt32 m_NumFastBytes; + UInt32 m_MatchLengthEdge; - BYTE m_LiteralPrices[256]; + Byte m_LiteralPrices[256]; - BYTE m_LenPrices[kNumLenCombinations32]; - BYTE m_PosPrices[kDistTableSize64]; + Byte m_LenPrices[kNumLenCombinations32]; + Byte m_PosPrices[kDistTableSize64]; - UINT32 m_CurrentBlockUncompressedSize; + UInt32 m_CurrentBlockUncompressedSize; COnePosMatches *m_OnePosMatchesArray; - UINT16 *m_OnePosMatchesMemory; + UInt16 *m_OnePosMatchesMemory; - UINT64 m_BlockStartPostion; + UInt64 m_BlockStartPostion; int m_NumPasses; bool m_Created; bool _deflate64Mode; - UINT32 m_NumLenCombinations; - UINT32 m_MatchMaxLen; - const BYTE *m_LenStart; - const BYTE *m_LenDirectBits; + UInt32 m_NumLenCombinations; + UInt32 m_MatchMaxLen; + const Byte *m_LenStart; + const Byte *m_LenDirectBits; HRESULT Create(); void Free(); - void GetBacks(UINT32 aPos); + void GetBacks(UInt32 aPos); void ReadGoodBacks(); - void MovePos(UINT32 num); - UINT32 Backward(UINT32 &backRes, UINT32 cur); - UINT32 GetOptimal(UINT32 &backRes); + void MovePos(UInt32 num); + UInt32 Backward(UInt32 &backRes, UInt32 cur); + UInt32 GetOptimal(UInt32 &backRes); void InitStructures(); - void CodeLevelTable(BYTE *newLevels, int numLevels, bool codeMode); + void CodeLevelTable(Byte *newLevels, int numLevels, bool codeMode); int WriteTables(bool writeMode, bool finalBlock); - void CopyBackBlockOp(UINT32 distance, UINT32 length); + void CopyBackBlockOp(UInt32 distance, UInt32 length); void WriteBlockData(bool writeMode, bool finalBlock); - /* void CCoder::ReleaseStreams() { - m_MatchFinder.ReleaseStream(); + // m_MatchFinder.ReleaseStream(); m_OutStream.ReleaseStream(); } class CCoderReleaser { CCoder *m_Coder; public: - CCoderReleaser(CCoder *aCoder): m_Coder(aCoder) {} - ~CCoderReleaser() - { - m_Coder->ReleaseStreams(); - } + CCoderReleaser(CCoder *coder): m_Coder(coder) {} + ~CCoderReleaser() { m_Coder->ReleaseStreams(); } }; friend class CCoderReleaser; - */ public: CCoder(bool deflate64Mode = false); ~CCoder(); HRESULT CodeReal(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); HRESULT BaseCode(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); // ICompressSetCoderProperties HRESULT BaseSetEncoderProperties2(const PROPID *propIDs, - const PROPVARIANT *properties, UINT32 numProperties); + const PROPVARIANT *properties, UInt32 numProperties); }; /////////////////////////////////////////////////////////////// @@ -167,11 +159,11 @@ public: MY_UNKNOWN_IMP1(ICompressSetCoderProperties) CCOMCoder(): CCoder(false) {}; STDMETHOD(Code)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); // ICompressSetCoderProperties STDMETHOD(SetCoderProperties)(const PROPID *propIDs, - const PROPVARIANT *properties, UINT32 numProperties); + const PROPVARIANT *properties, UInt32 numProperties); }; class CCOMCoder64 : @@ -184,11 +176,11 @@ public: MY_UNKNOWN_IMP1(ICompressSetCoderProperties) CCOMCoder64(): CCoder(true) {}; STDMETHOD(Code)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); // ICompressSetCoderProperties STDMETHOD(SetCoderProperties)(const PROPID *propIDs, - const PROPVARIANT *properties, UINT32 numProperties); + const PROPVARIANT *properties, UInt32 numProperties); }; diff --git a/7zip/Compress/Deflate/DeflateExtConst.h b/7zip/Compress/Deflate/DeflateExtConst.h index 7a58c856..31253a29 100755 --- a/7zip/Compress/Deflate/DeflateExtConst.h +++ b/7zip/Compress/Deflate/DeflateExtConst.h @@ -1,7 +1,5 @@ // DeflateExtConst.h -#pragma once - #ifndef __DEFLATE_EXTCONST_H #define __DEFLATE_EXTCONST_H @@ -10,17 +8,17 @@ namespace NCompress { namespace NDeflate { - // const UINT32 kDistTableSize = 30; - const UINT32 kDistTableSize32 = 30; - const UINT32 kDistTableSize64 = 32; + // const UInt32 kDistTableSize = 30; + const UInt32 kDistTableSize32 = 30; + const UInt32 kDistTableSize64 = 32; - const UINT32 kHistorySize32 = 0x8000; - const UINT32 kHistorySize64 = 0x10000; - const UINT32 kNumLenCombinations32 = 256; - const UINT32 kNumLenCombinations64 = 255; + const UInt32 kHistorySize32 = 0x8000; + const UInt32 kHistorySize64 = 0x10000; + const UInt32 kNumLenCombinations32 = 256; + const UInt32 kNumLenCombinations64 = 255; // don't change kNumLenCombinations64. It must be less than 255. - const UINT32 kNumHuffmanBits = 15; + const UInt32 kNumHuffmanBits = 15; }} diff --git a/7zip/Compress/Deflate/DllExports.cpp b/7zip/Compress/Deflate/DllExports.cpp index 9fdd6341..9cac0523 100755 --- a/7zip/Compress/Deflate/DllExports.cpp +++ b/7zip/Compress/Deflate/DllExports.cpp @@ -2,11 +2,11 @@ #include "StdAfx.h" -#define INITGUID +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" #include "DeflateEncoder.h" #include "DeflateDecoder.h" -#include "Common/ComTry.h" // {23170F69-40C1-278B-0401-080000000000} diff --git a/7zip/Compress/Deflate/StdAfx.cpp b/7zip/Compress/Deflate/StdAfx.cpp index 2550270c..d0feea85 100755 --- a/7zip/Compress/Deflate/StdAfx.cpp +++ b/7zip/Compress/Deflate/StdAfx.cpp @@ -1,3 +1,3 @@ // StdAfx.cpp -#include "stdafx.h" +#include "StdAfx.h" diff --git a/7zip/Compress/Deflate/StdAfx.h b/7zip/Compress/Deflate/StdAfx.h index a32fbed6..e7fb6986 100755 --- a/7zip/Compress/Deflate/StdAfx.h +++ b/7zip/Compress/Deflate/StdAfx.h @@ -1,8 +1,8 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> +#include "../../../Common/MyWindows.h" -#endif +#endif diff --git a/7zip/Compress/Deflate/resource.rc b/7zip/Compress/Deflate/resource.rc index fb37c0ee..7c9ff451 100755 --- a/7zip/Compress/Deflate/resource.rc +++ b/7zip/Compress/Deflate/resource.rc @@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,9,2,0 - PRODUCTVERSION 3,9,2,0 + FILEVERSION 4,19,0,0 + PRODUCTVERSION 4,19,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -85,14 +85,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", " \0" VALUE "FileDescription", "Deflate Coder\0" - VALUE "FileVersion", "3, 9, 2, 0\0" + VALUE "FileVersion", "4, 19, 0, 0\0" VALUE "InternalName", "Deflate\0" - VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "Deflate.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "7-Zip\0" - VALUE "ProductVersion", "3, 9, 2, 0\0" + VALUE "ProductVersion", "4, 19, 0, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/7zip/Compress/Huffman/HuffmanDecoder.h b/7zip/Compress/Huffman/HuffmanDecoder.h index 930e5367..096181fc 100755 --- a/7zip/Compress/Huffman/HuffmanDecoder.h +++ b/7zip/Compress/Huffman/HuffmanDecoder.h @@ -1,60 +1,42 @@ // Compress/HuffmanDecoder.h -#pragma once - #ifndef __COMPRESS_HUFFMANDECODER_H #define __COMPRESS_HUFFMANDECODER_H +#include "../../../Common/Types.h" + namespace NCompress { namespace NHuffman { class CDecoderException{}; -const UINT32 kValueTableBits = 8; +const UInt32 kValueTableBits = 9; -template <int kNumBitsInLongestCode> +template <int kNumBitsInLongestCode, UInt32 m_NumSymbols> class CDecoder { - UINT32 m_Limitits[kNumBitsInLongestCode + 1]; // m_Limitits[i] = value limit for symbols with length = i - UINT32 m_Positions[kNumBitsInLongestCode + 1]; // m_Positions[i] = index in m_Symbols[] of first symbol with length = i - UINT32 m_NumSymbols; - UINT32 *m_Symbols; // symbols: at first with len = 1 then 2, ... 15. - BYTE m_Lengths[1 << kValueTableBits]; + UInt32 m_Limitits[kNumBitsInLongestCode + 1]; // m_Limitits[i] = value limit for symbols with length = i + UInt32 m_Positions[kNumBitsInLongestCode + 1]; // m_Positions[i] = index in m_Symbols[] of first symbol with length = i + UInt32 m_Symbols[m_NumSymbols]; // symbols: at first with len = 1 then 2, ... 15. + Byte m_Lengths[1 << kValueTableBits]; public: - CDecoder(UINT32 numSymbols): - m_NumSymbols(numSymbols) - { m_Symbols = new UINT32[m_NumSymbols]; } - - ~CDecoder() - { delete []m_Symbols; } - - void SetNumSymbols(UINT32 numSymbols) - { m_NumSymbols = numSymbols; } - void SetCodeLengths(const BYTE *codeLengths); + void SetNumSymbols(UInt32 numSymbols) { m_NumSymbols = numSymbols; } + void SetCodeLengths(const Byte *codeLengths); template <class TBitDecoder> - UINT32 DecodeSymbol(TBitDecoder *bitStream) + UInt32 DecodeSymbol(TBitDecoder *bitStream) { - UINT32 numBits; + UInt32 numBits; - UINT32 value = bitStream->GetValue(kNumBitsInLongestCode); + UInt32 value = bitStream->GetValue(kNumBitsInLongestCode); if (value < m_Limitits[kValueTableBits]) numBits = m_Lengths[value >> (kNumBitsInLongestCode - kValueTableBits)]; - else if (value < m_Limitits[10]) - if (value < m_Limitits[9]) - numBits = 9; - else - numBits = 10; - else if (value < m_Limitits[11]) - numBits = 11; - else if (value < m_Limitits[12]) - numBits = 12; else - for (numBits = 13; numBits < kNumBitsInLongestCode; numBits++) + for (numBits = kValueTableBits + 1; numBits < kNumBitsInLongestCode; numBits++) if (value < m_Limitits[numBits]) break; bitStream->MovePos(numBits); - UINT32 index = m_Positions[numBits] + + UInt32 index = m_Positions[numBits] + ((value - m_Limitits[numBits - 1]) >> (kNumBitsInLongestCode - numBits)); if (index >= m_NumSymbols) throw CDecoderException(); // test it @@ -62,27 +44,26 @@ public: } }; - -template <int kNumBitsInLongestCode> -void CDecoder<kNumBitsInLongestCode>::SetCodeLengths(const BYTE *codeLengths) +template <int kNumBitsInLongestCode, UInt32 m_NumSymbols> +void CDecoder<kNumBitsInLongestCode, m_NumSymbols>::SetCodeLengths(const Byte *codeLengths) { int lenCounts[kNumBitsInLongestCode + 1], tmpPositions[kNumBitsInLongestCode + 1]; int i; for(i = 1; i <= kNumBitsInLongestCode; i++) lenCounts[i] = 0; - UINT32 symbol; + UInt32 symbol; for (symbol = 0; symbol < m_NumSymbols; symbol++) { - BYTE codeLength = codeLengths[symbol]; + Byte codeLength = codeLengths[symbol]; if (codeLength > kNumBitsInLongestCode) throw CDecoderException(); lenCounts[codeLength]++; } lenCounts[0] = 0; tmpPositions[0] = m_Positions[0] = m_Limitits[0] = 0; - UINT32 startPos = 0; - UINT32 index = 0; - const UINT32 kMaxValue = (1 << kNumBitsInLongestCode); + UInt32 startPos = 0; + UInt32 index = 0; + const UInt32 kMaxValue = (1 << kNumBitsInLongestCode); for (i = 1; i <= kNumBitsInLongestCode; i++) { startPos += lenCounts[i] << (kNumBitsInLongestCode - i); @@ -94,8 +75,8 @@ void CDecoder<kNumBitsInLongestCode>::SetCodeLengths(const BYTE *codeLengths) if(i <= kValueTableBits) { - UINT32 limit = (m_Limitits[i] >> (kNumBitsInLongestCode - kValueTableBits)); // change it - memset(m_Lengths + index, BYTE(i), limit - index); + UInt32 limit = (m_Limitits[i] >> (kNumBitsInLongestCode - kValueTableBits)); // change it + memset(m_Lengths + index, Byte(i), limit - index); index = limit; } } diff --git a/7zip/Compress/Huffman/HuffmanEncoder.cpp b/7zip/Compress/Huffman/HuffmanEncoder.cpp index a9e7e8e0..5876bae8 100755 --- a/7zip/Compress/Huffman/HuffmanEncoder.cpp +++ b/7zip/Compress/Huffman/HuffmanEncoder.cpp @@ -4,41 +4,63 @@ #include "HuffmanEncoder.h" #include "Common/Defs.h" +#include "Common/Alloc.h" namespace NCompression { namespace NHuffman { static const char *kIncorrectBitLenCountsMessage = "Incorrect bit len counts"; -CEncoder::CEncoder(UINT32 numSymbols, - const BYTE *extraBits, UINT32 extraBase, UINT32 maxLength): - m_NumSymbols(numSymbols), - m_ExtraBits(extraBits), - m_ExtraBase(extraBase), - m_MaxLength(maxLength), - m_HeapSize(numSymbols * 2+ 1) +CEncoder::CEncoder(): + m_Items(0), + m_Heap(0), + m_Depth(0) +{} + +void CEncoder::Free() +{ + MyFree(m_Items); + MyFree(m_Heap); + MyFree(m_Depth); + m_Items = 0; + m_Heap = 0; + m_Depth = 0; +} + +bool CEncoder::Create(UInt32 numSymbols, + const Byte *extraBits, UInt32 extraBase, UInt32 maxLength) { - m_Items = new CItem[m_HeapSize]; - m_Heap = new UINT32[m_HeapSize]; - m_Depth = new BYTE[m_HeapSize]; + m_NumSymbols = numSymbols; + m_ExtraBits = extraBits; + m_ExtraBase = extraBase; + m_MaxLength = maxLength; + m_HeapSize = numSymbols * 2 + 1; + Free(); + m_Items = (CItem *)MyAlloc(m_HeapSize * sizeof(CItem)); + m_Heap = (UInt32 *)MyAlloc(m_HeapSize * sizeof(UInt32)); + m_Depth = (Byte *)MyAlloc(m_HeapSize * sizeof(Byte)); + if (m_Items == 0 || m_Heap == 0 || m_Depth == 0) + { + Free(); + return false; + } + return true; } CEncoder::~CEncoder() { - delete []m_Depth; - delete []m_Heap; - delete []m_Items; + Free(); } void CEncoder::StartNewBlock() { - for (UINT32 i = 0; i < m_NumSymbols; i++) + for (UInt32 i = 0; i < m_NumSymbols; i++) m_Items[i].Freq = 0; } -void CEncoder::SetFreqs(const UINT32 *freqs) +void CEncoder::SetFreqs(const UInt32 *freqs) { - for (UINT32 i = 0; i < m_NumSymbols; i++) + for (UInt32 i = 0; i < m_NumSymbols; i++) m_Items[i].Freq = freqs[i]; } @@ -48,9 +70,9 @@ static const int kSmallest = 1; // Remove the smallest element from the heap and recreate the heap with // one less element. Updates heap and m_HeapLength. -UINT32 CEncoder::RemoveSmallest() +UInt32 CEncoder::RemoveSmallest() { - UINT32 top = m_Heap[kSmallest]; + UInt32 top = m_Heap[kSmallest]; m_Heap[kSmallest] = m_Heap[m_HeapLength--]; DownHeap(kSmallest); return top; @@ -72,15 +94,15 @@ bool CEncoder::Smaller(int n, int m) // when the m_Heap property is re-established (each father CompareFreqs than its // two sons). -void CEncoder::DownHeap(UINT32 k) +void CEncoder::DownHeap(UInt32 k) { - UINT32 symbol = m_Heap[k]; - for (UINT32 j = k << 1; j <= m_HeapLength;) // j: left son of k + UInt32 symbol = m_Heap[k]; + for (UInt32 j = k << 1; j <= m_HeapLength;) // j: left son of k { // Set j to the smallest of the two sons: if (j < m_HeapLength && Smaller(m_Heap[j+1], m_Heap[j])) j++; - UINT32 htemp = m_Heap[j]; // htemp required because of bug in SASC compiler + UInt32 htemp = m_Heap[j]; // htemp required because of bug in SASC compiler if (Smaller(symbol, htemp)) // Exit if v is smaller than both sons break; m_Heap[k] = htemp; // Exchange v with the smallest son @@ -100,22 +122,22 @@ void CEncoder::DownHeap(UINT32 k) // The length m_BlockBitLength is updated; static_len is also updated if stree is // not null. -void CEncoder::GenerateBitLen(UINT32 maxCode, UINT32 heapMax) +void CEncoder::GenerateBitLen(UInt32 maxCode, UInt32 heapMax) { int overflow = 0; // number of elements with bit length too large - for (UINT32 i = 0; i <= kNumBitsInLongestCode; i++) + for (UInt32 i = 0; i <= kNumBitsInLongestCode; i++) m_BitLenCounters[i] = 0; /* In a first pass, compute the optimal bit lengths (which may * overflow in the case of the bit length tree). */ m_Items[m_Heap[heapMax]].Len = 0; /* root of the heap */ - UINT32 h; /* heap index */ + UInt32 h; /* heap index */ for (h = heapMax+1; h < m_HeapSize; h++) { - UINT32 symbol = m_Heap[h]; - UINT32 len = m_Items[m_Items[symbol].Dad].Len + 1; + UInt32 symbol = m_Heap[h]; + UInt32 len = m_Items[m_Items[symbol].Dad].Len + 1; if (len > m_MaxLength) { len = m_MaxLength; @@ -125,7 +147,7 @@ void CEncoder::GenerateBitLen(UINT32 maxCode, UINT32 heapMax) if (symbol > maxCode) continue; // not a leaf node m_BitLenCounters[len]++; - UINT32 extraBits; + UInt32 extraBits; if (m_ExtraBits != 0 && symbol >= m_ExtraBase) extraBits = m_ExtraBits[symbol - m_ExtraBase]; else @@ -139,7 +161,7 @@ void CEncoder::GenerateBitLen(UINT32 maxCode, UINT32 heapMax) // Find the first bit length which could increase: do { - UINT32 bits = m_MaxLength-1; + UInt32 bits = m_MaxLength-1; while (m_BitLenCounters[bits] == 0) bits--; m_BitLenCounters[bits]--; // move one leaf down the m_Items @@ -155,12 +177,12 @@ void CEncoder::GenerateBitLen(UINT32 maxCode, UINT32 heapMax) // h is still equal to HEAP_SIZE. (It is simpler to reconstruct all // lengths instead of fixing only the wrong ones. This idea is taken // from 'ar' written by Haruhiko Okumura.) - for (UINT32 bits = m_MaxLength; bits != 0; bits--) + for (UInt32 bits = m_MaxLength; bits != 0; bits--) { - UINT32 numNodes = m_BitLenCounters[bits]; + UInt32 numNodes = m_BitLenCounters[bits]; while (numNodes != 0) { - UINT32 m = m_Heap[--h]; + UInt32 m = m_Heap[--h]; if (m > maxCode) continue; if (m_Items[m].Len != (unsigned) bits) @@ -182,22 +204,22 @@ void CEncoder::GenerateBitLen(UINT32 maxCode, UINT32 heapMax) // OUT assertion: the field code is set for all tree elements of non // zero code length. -// UINT32 maxCode = largest code with non zero frequency +// UInt32 maxCode = largest code with non zero frequency -void CEncoder::GenerateCodes(UINT32 maxCode) +void CEncoder::GenerateCodes(UInt32 maxCode) { - UINT32 nextCodes[kNumBitsInLongestCode + 1]; // next code value for each bit length - UINT32 code = 0; // running code value + UInt32 nextCodes[kNumBitsInLongestCode + 1]; // next code value for each bit length + UInt32 code = 0; // running code value // The distribution counts are first used to generate the code values // without bit reversal. - for (UINT32 bits = 1; bits <= kNumBitsInLongestCode; bits++) + for (UInt32 bits = 1; bits <= kNumBitsInLongestCode; bits++) nextCodes[bits] = code = (code + m_BitLenCounters[bits - 1]) << 1; // Check that the bit counts in m_BitLenCounters are consistent. The last code // must be all ones. if (code + m_BitLenCounters[kNumBitsInLongestCode] - 1 != (1 << kNumBitsInLongestCode) - 1) throw kIncorrectBitLenCountsMessage; - for (UINT32 n = 0; n <= maxCode; n++) + for (UInt32 n = 0; n <= maxCode; n++) { int len = m_Items[n].Len; if (len == 0) @@ -215,7 +237,7 @@ void CEncoder::GenerateCodes(UINT32 maxCode) // and corresponding code. The length m_BlockBitLength is updated; static_len is // also updated if stree is not null. The field max_code is set. -void CEncoder::BuildTree(BYTE *levels) +void CEncoder::BuildTree(Byte *levels) { m_BlockBitLength = 0; int maxCode = -1; // WAS = -1; largest code with non zero frequency */ @@ -226,7 +248,7 @@ void CEncoder::BuildTree(BYTE *levels) // m_HeapLength = 0; - UINT32 n; // iterate over m_Heap elements + UInt32 n; // iterate over m_Heap elements for (n = 0; n < m_NumSymbols; n++) { if (m_Items[n].Freq != 0) @@ -260,18 +282,18 @@ void CEncoder::BuildTree(BYTE *levels) // Construct the Huffman tree by repeatedly combining the least two // frequent nodes. int node = m_NumSymbols; // next internal node of the tree - UINT32 heapMax = m_NumSymbols * 2+ 1; + UInt32 heapMax = m_NumSymbols * 2+ 1; do { n = RemoveSmallest(); /* n = node of least frequency */ - UINT32 m = m_Heap[kSmallest]; /* m = node of next least frequency */ + UInt32 m = m_Heap[kSmallest]; /* m = node of next least frequency */ m_Heap[--heapMax] = n; /* keep the nodes sorted by frequency */ m_Heap[--heapMax] = m; // Create a new node father of n and m m_Items[node].Freq = m_Items[n].Freq + m_Items[m].Freq; - m_Depth[node] = (BYTE) (MyMax(m_Depth[n], m_Depth[m]) + 1); + m_Depth[node] = (Byte) (MyMax(m_Depth[n], m_Depth[m]) + 1); m_Items[n].Dad = m_Items[m].Dad = node; // and insert the new node in the m_Heap m_Heap[kSmallest] = node++; @@ -290,7 +312,7 @@ void CEncoder::BuildTree(BYTE *levels) GenerateCodes (maxCode); for (n = 0; n < m_NumSymbols; n++) - levels[n] = BYTE(m_Items[n].Len); + levels[n] = Byte(m_Items[n].Len); } }} diff --git a/7zip/Compress/Huffman/HuffmanEncoder.h b/7zip/Compress/Huffman/HuffmanEncoder.h index 1af89be6..ea9e69a0 100755 --- a/7zip/Compress/Huffman/HuffmanEncoder.h +++ b/7zip/Compress/Huffman/HuffmanEncoder.h @@ -1,7 +1,5 @@ // Compression/HuffmanEncoder.h -#pragma once - #ifndef __COMPRESSION_HUFFMANENCODER_H #define __COMPRESSION_HUFFMANENCODER_H @@ -10,54 +8,58 @@ namespace NCompression { namespace NHuffman { -const int kNumBitsInLongestCode = 15; +const int kNumBitsInLongestCode = 20; struct CItem { - UINT32 Freq; - UINT32 Code; - UINT32 Dad; - UINT32 Len; + UInt32 Freq; + UInt32 Code; + UInt32 Dad; + UInt32 Len; }; class CEncoder { - UINT32 m_NumSymbols; // number of symbols in adwSymbol +public: + UInt32 m_NumSymbols; // number of symbols in adwSymbol CItem *m_Items; - UINT32 *m_Heap; - UINT32 m_HeapSize; - BYTE *m_Depth; - const BYTE *m_ExtraBits; - UINT32 m_ExtraBase; - UINT32 m_MaxLength; + UInt32 *m_Heap; + UInt32 m_HeapSize; + Byte *m_Depth; + const Byte *m_ExtraBits; + UInt32 m_ExtraBase; + UInt32 m_MaxLength; - UINT32 m_HeapLength; - UINT32 m_BitLenCounters[kNumBitsInLongestCode + 1]; + UInt32 m_HeapLength; + UInt32 m_BitLenCounters[kNumBitsInLongestCode + 1]; - UINT32 RemoveSmallest(); + UInt32 RemoveSmallest(); bool Smaller(int n, int m); - void DownHeap(UINT32 k); - void GenerateBitLen(UINT32 maxCode, UINT32 heapMax); - void GenerateCodes(UINT32 maxCode); + void DownHeap(UInt32 k); + void GenerateBitLen(UInt32 maxCode, UInt32 heapMax); + void GenerateCodes(UInt32 maxCode); - UINT32 m_BlockBitLength; + UInt32 m_BlockBitLength; + + void Free(); + public: - CEncoder(UINT32 numSymbols, const BYTE *extraBits, - UINT32 extraBase, UINT32 maxLength); + CEncoder(); ~CEncoder(); + bool Create(UInt32 numSymbols, const Byte *extraBits, + UInt32 extraBase, UInt32 maxLength); void StartNewBlock(); - void AddSymbol(UINT32 symbol) - { m_Items[symbol].Freq++; } + void AddSymbol(UInt32 symbol) { m_Items[symbol].Freq++; } - void SetFreqs(const UINT32 *freqs); - void BuildTree(BYTE *levels); - UINT32 GetBlockBitLength() const { return m_BlockBitLength; } + void SetFreqs(const UInt32 *freqs); + void BuildTree(Byte *levels); + UInt32 GetBlockBitLength() const { return m_BlockBitLength; } template <class TBitEncoder> - void CodeOneValue(TBitEncoder *bitEncoder, UINT32 symbol) + void CodeOneValue(TBitEncoder *bitEncoder, UInt32 symbol) { bitEncoder->WriteBits(m_Items[symbol].Code, m_Items[symbol].Len); } }; diff --git a/7zip/Compress/Huffman/StdAfx.h b/7zip/Compress/Huffman/StdAfx.h index 2b5a157a..b637fd40 100755 --- a/7zip/Compress/Huffman/StdAfx.h +++ b/7zip/Compress/Huffman/StdAfx.h @@ -1,6 +1,6 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#endif +#endif diff --git a/7zip/Compress/Implode/DllExports.cpp b/7zip/Compress/Implode/DllExports.cpp index 3f817a09..4560af3a 100755 --- a/7zip/Compress/Implode/DllExports.cpp +++ b/7zip/Compress/Implode/DllExports.cpp @@ -2,8 +2,7 @@ #include "StdAfx.h" -#define INITGUID - +#include "Common/MyInitGuid.h" #include "Common/ComTry.h" #include "ImplodeDecoder.h" diff --git a/7zip/Compress/Implode/Implode.dsp b/7zip/Compress/Implode/Implode.dsp index 832d3c88..db88cd03 100755 --- a/7zip/Compress/Implode/Implode.dsp +++ b/7zip/Compress/Implode/Implode.dsp @@ -142,6 +142,14 @@ SOURCE=..\..\Common\LSBFDecoder.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\NewHandler.cpp # End Source File # Begin Source File diff --git a/7zip/Compress/Implode/ImplodeDecoder.cpp b/7zip/Compress/Implode/ImplodeDecoder.cpp index fccd1dd9..d8b5daea 100755 --- a/7zip/Compress/Implode/ImplodeDecoder.cpp +++ b/7zip/Compress/Implode/ImplodeDecoder.cpp @@ -5,12 +5,20 @@ #include "ImplodeDecoder.h" #include "Common/Defs.h" -#include "Windows/Defs.h" - namespace NCompress { namespace NImplode { namespace NDecoder { +class CException +{ +public: + enum ECauseType + { + kData + } m_Cause; + CException(ECauseType cause): m_Cause(cause) {} +}; + static const int kNumDistanceLowDirectBitsForBigDict = 7; static const int kNumDistanceLowDirectBitsForSmallDict = 6; @@ -30,20 +38,20 @@ static const int kLiteralTableSize = (1 << kNumBitsInByte); static const int kDistanceTableSize = 64; static const int kLengthTableSize = 64; -static const UINT32 kHistorySize = +static const UInt32 kHistorySize = (1 << MyMax(kNumDistanceLowDirectBitsForBigDict, kNumDistanceLowDirectBitsForSmallDict)) * kDistanceTableSize; // = 8 KB; static const int kNumAdditionalLengthBits = 8; -static const UINT32 kMatchMinLenWhenLiteralsOn = 3; -static const UINT32 kMatchMinLenWhenLiteralsOff = 2; +static const UInt32 kMatchMinLenWhenLiteralsOn = 3; +static const UInt32 kMatchMinLenWhenLiteralsOff = 2; -static const UINT32 kMatchMinLenMax = MyMax(kMatchMinLenWhenLiteralsOn, +static const UInt32 kMatchMinLenMax = MyMax(kMatchMinLenWhenLiteralsOn, kMatchMinLenWhenLiteralsOff); // 3 -static const UINT32 kMatchMaxLenMax = kMatchMinLenMax + +static const UInt32 kMatchMaxLenMax = kMatchMinLenMax + (kLengthTableSize - 1) + (1 << kNumAdditionalLengthBits) - 1; // or 2 enum @@ -58,20 +66,16 @@ CCoder::CCoder(): m_LengthDecoder(kLengthTableSize), m_DistanceDecoder(kDistanceTableSize) { - m_OutWindowStream.Create(kHistorySize/*, kMatchMaxLenMax*/); } -/* -STDMETHODIMP CCoder::ReleaseStreams() +void CCoder::ReleaseStreams() { m_OutWindowStream.ReleaseStream(); m_InBitStream.ReleaseStream(); - return S_OK; } -*/ void CCoder::ReadLevelItems(NImplode::NHuffman::CDecoder &decoder, - BYTE *levels, int numLevelItems) + Byte *levels, int numLevelItems) { int numCodedStructures = m_InBitStream.ReadBits(kNumBitsInByte) + kLevelStructuresNumberAdditionalValue; @@ -104,19 +108,18 @@ void CCoder::ReadTables(void) { if (m_LiteralsOn) { - BYTE literalLevels[kLiteralTableSize]; + Byte literalLevels[kLiteralTableSize]; ReadLevelItems(m_LiteralDecoder, literalLevels, kLiteralTableSize); } - BYTE lengthLevels[kLengthTableSize]; + Byte lengthLevels[kLengthTableSize]; ReadLevelItems(m_LengthDecoder, lengthLevels, kLengthTableSize); - BYTE distanceLevels[kDistanceTableSize]; + Byte distanceLevels[kDistanceTableSize]; ReadLevelItems(m_DistanceDecoder, distanceLevels, kDistanceTableSize); } -/* class CCoderReleaser { CCoder *m_Coder; @@ -124,19 +127,24 @@ public: CCoderReleaser(CCoder *coder): m_Coder(coder) {} ~CCoderReleaser() { m_Coder->ReleaseStreams(); } }; -*/ STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { + if (!m_InBitStream.Create(1 << 20)) + return E_OUTOFMEMORY; + if (!m_OutWindowStream.Create(kHistorySize)) + return E_OUTOFMEMORY; if (outSize == NULL) return E_INVALIDARG; - UINT64 pos = 0, unPackSize = *outSize; + UInt64 pos = 0, unPackSize = *outSize; - m_OutWindowStream.Init(outStream, false); - m_InBitStream.Init(inStream); - // CCoderReleaser coderReleaser(this); + m_OutWindowStream.SetStream(outStream); + m_OutWindowStream.Init(false); + m_InBitStream.SetStream(inStream); + m_InBitStream.Init(); + CCoderReleaser coderReleaser(this); ReadTables(); @@ -144,34 +152,34 @@ STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream, { if (progress != NULL && pos % (1 << 16) == 0) { - UINT64 packSize = m_InBitStream.GetProcessedSize(); + UInt64 packSize = m_InBitStream.GetProcessedSize(); RINOK(progress->SetRatioInfo(&packSize, &pos)); } if(m_InBitStream.ReadBits(1) == kMatchId) // match { - UINT32 lowDistBits = m_InBitStream.ReadBits(m_NumDistanceLowDirectBits); - UINT32 distance = (m_DistanceDecoder.DecodeSymbol(&m_InBitStream) << + UInt32 lowDistBits = m_InBitStream.ReadBits(m_NumDistanceLowDirectBits); + UInt32 distance = (m_DistanceDecoder.DecodeSymbol(&m_InBitStream) << m_NumDistanceLowDirectBits) + lowDistBits; - UINT32 lengthSymbol = m_LengthDecoder.DecodeSymbol(&m_InBitStream); - UINT32 length = lengthSymbol + m_MinMatchLength; + UInt32 lengthSymbol = m_LengthDecoder.DecodeSymbol(&m_InBitStream); + UInt32 length = lengthSymbol + m_MinMatchLength; if (lengthSymbol == kLengthTableSize - 1) // special symbol = 63 length += m_InBitStream.ReadBits(kNumAdditionalLengthBits); while(distance >= pos && length > 0) { - m_OutWindowStream.PutOneByte(0); + m_OutWindowStream.PutByte(0); pos++; length--; } if (length > 0) - m_OutWindowStream.CopyBackBlock(distance, length); + m_OutWindowStream.CopyBlock(distance, length); pos += length; } else { - BYTE b = BYTE(m_LiteralsOn ? m_LiteralDecoder.DecodeSymbol(&m_InBitStream) : + Byte b = Byte(m_LiteralsOn ? m_LiteralDecoder.DecodeSymbol(&m_InBitStream) : m_InBitStream.ReadBits(kNumBitsInByte)); - m_OutWindowStream.PutOneByte(b); + m_OutWindowStream.PutByte(b); pos++; } } @@ -181,7 +189,7 @@ STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream, } STDMETHODIMP CCoder::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { try { return CodeReal(inStream, outStream, inSize, outSize, progress); } @@ -189,13 +197,11 @@ STDMETHODIMP CCoder::Code(ISequentialInStream *inStream, catch(...) { return S_FALSE; } } -STDMETHODIMP CCoder::SetDecoderProperties(ISequentialInStream *inStream) +STDMETHODIMP CCoder::SetDecoderProperties2(const Byte *data, UInt32 size) { - BYTE flag; - UINT32 processedSize; - RINOK(inStream->Read(&flag, sizeof(flag), &processedSize)); - if (processedSize != sizeof(flag)) + if (size < 1) return E_INVALIDARG; + Byte flag = data[0]; m_BigDictionaryOn = ((flag & 2) != 0); m_NumDistanceLowDirectBits = m_BigDictionaryOn ? kNumDistanceLowDirectBitsForBigDict: diff --git a/7zip/Compress/Implode/ImplodeDecoder.h b/7zip/Compress/Implode/ImplodeDecoder.h index aa90f75c..7dd35003 100755 --- a/7zip/Compress/Implode/ImplodeDecoder.h +++ b/7zip/Compress/Implode/ImplodeDecoder.h @@ -3,9 +3,7 @@ #ifndef __IMPLODE_DECODER_H #define __IMPLODE_DECODER_H -#pragma once - -#include "Common/MyCom.h" +#include "../../../Common/MyCom.h" #include "../../ICoder.h" #include "../LZ/LZOutWindow.h" @@ -16,19 +14,9 @@ namespace NCompress { namespace NImplode { namespace NDecoder { -class CException -{ -public: - enum ECauseType - { - kData - } m_Cause; - CException(ECauseType cause): m_Cause(cause) {} -}; - class CCoder : public ICompressCoder, - public ICompressSetDecoderProperties, + public ICompressSetDecoderProperties2, public CMyUnknownImp { CLZOutWindow m_OutWindowStream; @@ -38,38 +26,34 @@ class CCoder : NImplode::NHuffman::CDecoder m_LengthDecoder; NImplode::NHuffman::CDecoder m_DistanceDecoder; - bool m_BigDictionaryOn; bool m_LiteralsOn; int m_NumDistanceLowDirectBits; - UINT32 m_MinMatchLength; + UInt32 m_MinMatchLength; void ReadLevelItems(NImplode::NHuffman::CDecoder &table, - BYTE *levels, int numLevelItems); + Byte *levels, int numLevelItems); void ReadTables(); - void DeCodeLevelTable(BYTE *newLevels, int numLevels); + void DeCodeLevelTable(Byte *newLevels, int numLevels); public: CCoder(); - MY_UNKNOWN_IMP1(ICompressSetDecoderProperties) + MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) - // STDMETHOD(ReleaseStreams)(); - // STDMETHOD(Code)(UINT32 aSize, UINT32 &aProcessedSize); + void ReleaseStreams(); HRESULT (Flush)() { return m_OutWindowStream.Flush(); } - - STDMETHOD(CodeReal)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + STDMETHOD(CodeReal)(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(Code)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); // ICompressSetDecoderProperties - // STDMETHOD(SetCoderProperties)(PROPVARIANT *aProperties, UINT32 aNumProperties); - STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream); + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); }; }}} diff --git a/7zip/Compress/Implode/ImplodeHuffmanDecoder.cpp b/7zip/Compress/Implode/ImplodeHuffmanDecoder.cpp index 1006d5c8..15046d55 100755 --- a/7zip/Compress/Implode/ImplodeHuffmanDecoder.cpp +++ b/7zip/Compress/Implode/ImplodeHuffmanDecoder.cpp @@ -8,10 +8,10 @@ namespace NCompress { namespace NImplode { namespace NHuffman { -CDecoder::CDecoder(UINT32 numSymbols): +CDecoder::CDecoder(UInt32 numSymbols): m_NumSymbols(numSymbols) { - m_Symbols = new UINT32[m_NumSymbols]; + m_Symbols = new UInt32[m_NumSymbols]; } CDecoder::~CDecoder() @@ -19,14 +19,14 @@ CDecoder::~CDecoder() delete []m_Symbols; } -void CDecoder::SetCodeLengths(const BYTE *codeLengths) +void CDecoder::SetCodeLengths(const Byte *codeLengths) { // int lenCounts[kNumBitsInLongestCode + 1], tmpPositions[kNumBitsInLongestCode + 1]; int lenCounts[kNumBitsInLongestCode + 2], tmpPositions[kNumBitsInLongestCode + 1]; int i; for(i = 0; i <= kNumBitsInLongestCode; i++) lenCounts[i] = 0; - UINT32 symbolIndex; + UInt32 symbolIndex; for (symbolIndex = 0; symbolIndex < m_NumSymbols; symbolIndex++) lenCounts[codeLengths[symbolIndex]]++; // lenCounts[0] = 0; @@ -37,8 +37,8 @@ void CDecoder::SetCodeLengths(const BYTE *codeLengths) lenCounts[kNumBitsInLongestCode + 1] = 0; - UINT32 startPos = 0; - static const UINT32 kMaxValue = (1 << kNumBitsInLongestCode); + UInt32 startPos = 0; + static const UInt32 kMaxValue = (1 << kNumBitsInLongestCode); for (i = kNumBitsInLongestCode; i > 0; i--) { @@ -62,10 +62,10 @@ void CDecoder::SetCodeLengths(const BYTE *codeLengths) m_Symbols[--tmpPositions[codeLengths[symbolIndex]]] = symbolIndex; } -UINT32 CDecoder::DecodeSymbol(CInBit *inStream) +UInt32 CDecoder::DecodeSymbol(CInBit *inStream) { - UINT32 numBits; - UINT32 value = inStream->GetValue(kNumBitsInLongestCode); + UInt32 numBits; + UInt32 value = inStream->GetValue(kNumBitsInLongestCode); int i; for(i = kNumBitsInLongestCode; i > 0; i--) { @@ -78,7 +78,7 @@ UINT32 CDecoder::DecodeSymbol(CInBit *inStream) if (i == 0) throw CDecoderException(); inStream->MovePos(numBits); - UINT32 index = m_Positions[numBits] + + UInt32 index = m_Positions[numBits] + ((value - m_Limitits[numBits + 1]) >> (kNumBitsInLongestCode - numBits)); if (index >= m_NumSymbols) throw CDecoderException(); // test it diff --git a/7zip/Compress/Implode/ImplodeHuffmanDecoder.h b/7zip/Compress/Implode/ImplodeHuffmanDecoder.h index 189f7c4c..5a8b4e90 100755 --- a/7zip/Compress/Implode/ImplodeHuffmanDecoder.h +++ b/7zip/Compress/Implode/ImplodeHuffmanDecoder.h @@ -1,7 +1,5 @@ // ImplodeHuffmanDecoder.h -#pragma once - #ifndef __IMPLODE_HUFFMAN_DECODER_H #define __IMPLODE_HUFFMAN_DECODER_H @@ -19,16 +17,16 @@ typedef NStream::NLSBF::CDecoder<CInBuffer> CInBit; class CDecoder { - UINT32 m_Limitits[kNumBitsInLongestCode + 2]; // m_Limitits[i] = value limit for symbols with length = i - UINT32 m_Positions[kNumBitsInLongestCode + 2]; // m_Positions[i] = index in m_Symbols[] of first symbol with length = i - UINT32 m_NumSymbols; // number of symbols in m_Symbols - UINT32 *m_Symbols; // symbols: at first with len=1 then 2, ... 15. + UInt32 m_Limitits[kNumBitsInLongestCode + 2]; // m_Limitits[i] = value limit for symbols with length = i + UInt32 m_Positions[kNumBitsInLongestCode + 2]; // m_Positions[i] = index in m_Symbols[] of first symbol with length = i + UInt32 m_NumSymbols; // number of symbols in m_Symbols + UInt32 *m_Symbols; // symbols: at first with len=1 then 2, ... 15. public: - CDecoder(UINT32 numSymbols); + CDecoder(UInt32 numSymbols); ~CDecoder(); - void SetCodeLengths(const BYTE *codeLengths); - UINT32 DecodeSymbol(CInBit *inStream); + void SetCodeLengths(const Byte *codeLengths); + UInt32 DecodeSymbol(CInBit *inStream); }; }}} diff --git a/7zip/Compress/Implode/StdAfx.cpp b/7zip/Compress/Implode/StdAfx.cpp index 2550270c..d0feea85 100755 --- a/7zip/Compress/Implode/StdAfx.cpp +++ b/7zip/Compress/Implode/StdAfx.cpp @@ -1,3 +1,3 @@ // StdAfx.cpp -#include "stdafx.h" +#include "StdAfx.h" diff --git a/7zip/Compress/Implode/StdAfx.h b/7zip/Compress/Implode/StdAfx.h index a32fbed6..e7fb6986 100755 --- a/7zip/Compress/Implode/StdAfx.h +++ b/7zip/Compress/Implode/StdAfx.h @@ -1,8 +1,8 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> +#include "../../../Common/MyWindows.h" -#endif +#endif diff --git a/7zip/Compress/Implode/resource.rc b/7zip/Compress/Implode/resource.rc index be30a871..fead08d8 100755 --- a/7zip/Compress/Implode/resource.rc +++ b/7zip/Compress/Implode/resource.rc @@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,9,2,0 - PRODUCTVERSION 3,9,2,0 + FILEVERSION 4,15,0,0 + PRODUCTVERSION 4,15,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -85,14 +85,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Igor Pavlov\0" VALUE "FileDescription", "Implode Decoder\0" - VALUE "FileVersion", "3, 9, 2, 0\0" + VALUE "FileVersion", "4, 15, 0, 0\0" VALUE "InternalName", "Implode\0" - VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "Implode.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "7-Zip\0" - VALUE "ProductVersion", "3, 9, 2, 0\0" + VALUE "ProductVersion", "4, 15, 0, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/7zip/Compress/LZ/BinTree/BinTree.h b/7zip/Compress/LZ/BinTree/BinTree.h index 9096fe70..dea1a734 100755 --- a/7zip/Compress/LZ/BinTree/BinTree.h +++ b/7zip/Compress/LZ/BinTree/BinTree.h @@ -1,116 +1,55 @@ // BinTree.h -// #pragma once - -// #ifndef __BINTREE_H -// #define __BINTREE_H - #include "../LZInWindow.h" -// #include "Common/Types.h" -// #include "Windows/Defs.h" +#include "../IMatchFinder.h" namespace BT_NAMESPACE { -// #define __USE_3_BYTES - -#ifdef __USE_3_BYTES - -#pragma pack(push, PragmaBinTree, 1) +typedef UInt32 CIndex; +const UInt32 kMaxValForNormalize = (UInt32(1) << 31) - 1; -struct CIndex +class CMatchFinderBinTree: + public IMatchFinder, + public IMatchFinderSetCallback, + public CLZInWindow, + public CMyUnknownImp { - BYTE Data[3]; - CIndex(){} - CIndex(UINT32 value) - { - Data[0] = value & 0xFF; - Data[1] = (value >> 8) & 0xFF; - Data[2] = (value >> 16) & 0xFF; - } - operator UINT32() const { return (*((const UINT32 *)Data)) & 0xFFFFFF; } -}; -const UINT32 kMaxValForNormalize = CIndex(-1); - -#pragma pack(pop, PragmaBinTree) - -#else - -typedef UINT32 CIndex; -const UINT32 kMaxValForNormalize = (UINT32(1) << 31) - 1; - -#endif - - - -// #define HASH_ARRAY_2 - -// #ifdef HASH_ARRAY_2 - -// #define HASH_ARRAY_3 - -// #else - -// #define HASH_ZIP - -// #endif - -#pragma pack(push, PragmaBinTreePair, 1) -// #pragma pack(push, 1) + UInt32 _cyclicBufferPos; + UInt32 _cyclicBufferSize; // it must be historySize + 1 + UInt32 _matchMaxLen; + CIndex *_hash; + UInt32 _cutValue; -struct CPair -{ - CIndex Left; - CIndex Right; -}; + CMyComPtr<IMatchFinderCallback> m_Callback; -// #pragma pack(pop) -#pragma pack(pop, PragmaBinTreePair) + void Normalize(); + void FreeThisClassMemory(); + void FreeMemory(); -class CInTree: public CLZInWindow -{ - UINT32 _cyclicBufferPos; - UINT32 _cyclicBufferSize; - UINT32 _historySize; - UINT32 _matchMaxLen; + MY_UNKNOWN_IMP1(IMatchFinderSetCallback) - CIndex *_hash; - - #ifdef HASH_ARRAY_2 - CIndex *_hash2; - #ifdef HASH_ARRAY_3 - CIndex *_hash3; - #endif - #endif - - CPair *_son; + STDMETHOD(Init)(ISequentialInStream *inStream); + STDMETHOD_(void, ReleaseStream)(); + STDMETHOD(MovePos)(); + STDMETHOD_(Byte, GetIndexByte)(Int32 index); + STDMETHOD_(UInt32, GetMatchLen)(Int32 index, UInt32 back, UInt32 limit); + STDMETHOD_(UInt32, GetNumAvailableBytes)(); + STDMETHOD_(const Byte *, GetPointerToCurrentPos)(); + STDMETHOD(Create)(UInt32 historySize, UInt32 keepAddBufferBefore, + UInt32 matchMaxLen, UInt32 keepAddBufferAfter); + STDMETHOD_(UInt32, GetLongestMatch)(UInt32 *distances); + STDMETHOD_(void, DummyLongestMatch)(); - UINT32 _cutValue; + // IMatchFinderSetCallback + STDMETHOD(SetCallback)(IMatchFinderCallback *callback); - void NormalizeLinks(CIndex *array, UINT32 numItems, UINT32 subValue); - void Normalize(); - void FreeMemory(); + virtual void BeforeMoveBlock(); + virtual void AfterMoveBlock(); public: - CInTree(); - ~CInTree(); - HRESULT Create(UINT32 sizeHistory, UINT32 keepAddBufferBefore, UINT32 matchMaxLen, - UINT32 keepAddBufferAfter, UINT32 sizeReserv = (1<<17)); - HRESULT Init(ISequentialInStream *stream); - void SetCutValue(UINT32 cutValue) { _cutValue = cutValue; } - UINT32 GetLongestMatch(UINT32 *distances); - void DummyLongestMatch(); - HRESULT MovePos() - { - _cyclicBufferPos++; - if (_cyclicBufferPos >= _cyclicBufferSize) - _cyclicBufferPos = 0; - RINOK(CLZInWindow::MovePos()); - if (_pos == kMaxValForNormalize) - Normalize(); - return S_OK; - } + CMatchFinderBinTree(); + virtual ~CMatchFinderBinTree(); + void SetCutValue(UInt32 cutValue) { _cutValue = cutValue; } }; } - -// #endif diff --git a/7zip/Compress/LZ/BinTree/BinTree2.h b/7zip/Compress/LZ/BinTree/BinTree2.h index 2a93e8b2..03ac8264 100755 --- a/7zip/Compress/LZ/BinTree/BinTree2.h +++ b/7zip/Compress/LZ/BinTree/BinTree2.h @@ -1,18 +1,12 @@ // BinTree2.h -// #pragma once - -#ifndef __BINTREE2__H -#define __BINTREE2__H - -#undef BT_CLSID -#define BT_CLSID CLSID_CMatchFinderBT2 +#ifndef __BINTREE2_H +#define __BINTREE2_H #undef BT_NAMESPACE #define BT_NAMESPACE NBT2 -#include "BinTreeMF.h" -#include "BinTreeMFMain.h" +#include "BinTree.h" +#include "BinTreeMain.h" #endif - diff --git a/7zip/Compress/LZ/BinTree/BinTree3.h b/7zip/Compress/LZ/BinTree/BinTree3.h index 69bb8711..f662c0e6 100755 --- a/7zip/Compress/LZ/BinTree/BinTree3.h +++ b/7zip/Compress/LZ/BinTree/BinTree3.h @@ -1,22 +1,16 @@ // BinTree3.h -// #pragma once - -#ifndef __BINTREE3__H -#define __BINTREE3__H - -#undef BT_CLSID -#define BT_CLSID CLSID_CMatchFinderBT3 +#ifndef __BINTREE3_H +#define __BINTREE3_H #undef BT_NAMESPACE #define BT_NAMESPACE NBT3 #define HASH_ARRAY_2 -#include "BinTreeMF.h" -#include "BinTreeMFMain.h" +#include "BinTree.h" +#include "BinTreeMain.h" #undef HASH_ARRAY_2 #endif - diff --git a/7zip/Compress/LZ/BinTree/BinTree3Z.h b/7zip/Compress/LZ/BinTree/BinTree3Z.h index 9217d9fe..60a52e89 100755 --- a/7zip/Compress/LZ/BinTree/BinTree3Z.h +++ b/7zip/Compress/LZ/BinTree/BinTree3Z.h @@ -1,9 +1,7 @@ // BinTree3Z.h -// #pragma once - -#ifndef __BINTREE3Z__H -#define __BINTREE3Z__H +#ifndef __BINTREE3Z_H +#define __BINTREE3Z_H #undef BT_NAMESPACE #define BT_NAMESPACE NBT3Z @@ -11,9 +9,8 @@ #define HASH_ZIP #include "BinTree.h" -// #include "BinTreeMain.h" +#include "BinTreeMain.h" #undef HASH_ZIP #endif - diff --git a/7zip/Compress/LZ/BinTree/BinTree3ZMain.h b/7zip/Compress/LZ/BinTree/BinTree3ZMain.h deleted file mode 100755 index ded819f1..00000000 --- a/7zip/Compress/LZ/BinTree/BinTree3ZMain.h +++ /dev/null @@ -1,18 +0,0 @@ -// BinTree3ZMain.h - -// #pragma once - -#ifndef __BINTREE3ZMAIN__H -#define __BINTREE3ZMAIN__H - -#undef BT_NAMESPACE -#define BT_NAMESPACE NBT3Z - -#define HASH_ZIP - -#include "BinTreeMain.h" - -#undef HASH_ZIP - -#endif - diff --git a/7zip/Compress/LZ/BinTree/BinTree4.h b/7zip/Compress/LZ/BinTree/BinTree4.h index c5cc2a76..7edcc07e 100755 --- a/7zip/Compress/LZ/BinTree/BinTree4.h +++ b/7zip/Compress/LZ/BinTree/BinTree4.h @@ -1,12 +1,7 @@ // BinTree4.h -// #pragma once - -#ifndef __BINTREE4__H -#define __BINTREE4__H - -#undef BT_CLSID -#define BT_CLSID CLSID_CMatchFinderBT4 +#ifndef __BINTREE4_H +#define __BINTREE4_H #undef BT_NAMESPACE #define BT_NAMESPACE NBT4 @@ -14,11 +9,10 @@ #define HASH_ARRAY_2 #define HASH_ARRAY_3 -#include "BinTreeMF.h" -#include "BinTreeMFMain.h" +#include "BinTree.h" +#include "BinTreeMain.h" #undef HASH_ARRAY_2 #undef HASH_ARRAY_3 #endif - diff --git a/7zip/Compress/LZ/BinTree/BinTree4b.h b/7zip/Compress/LZ/BinTree/BinTree4b.h index 0128f32c..3f5434cb 100755 --- a/7zip/Compress/LZ/BinTree/BinTree4b.h +++ b/7zip/Compress/LZ/BinTree/BinTree4b.h @@ -1,12 +1,7 @@ // BinTree4b.h -// #pragma once - -#ifndef __BINTREE4B__H -#define __BINTREE4B__H - -#undef BT_CLSID -#define BT_CLSID CLSID_CMatchFinderBT4b +#ifndef __BINTREE4B_H +#define __BINTREE4B_H #undef BT_NAMESPACE #define BT_NAMESPACE NBT4B @@ -15,12 +10,11 @@ #define HASH_ARRAY_3 #define HASH_BIG -#include "BinTreeMF.h" -#include "BinTreeMFMain.h" +#include "BinTree.h" +#include "BinTreeMain.h" #undef HASH_ARRAY_2 #undef HASH_ARRAY_3 #undef HASH_BIG #endif - diff --git a/7zip/Compress/LZ/BinTree/BinTreeMF.h b/7zip/Compress/LZ/BinTree/BinTreeMF.h deleted file mode 100755 index 9903db4f..00000000 --- a/7zip/Compress/LZ/BinTree/BinTreeMF.h +++ /dev/null @@ -1,110 +0,0 @@ -// BinTreeMF.h - -// #pragma once - -// #ifndef __BINTREEMF_H -// #define __BINTREEMF_H - -#include "../../../ICoder.h" -#include "BinTree.h" - -namespace BT_NAMESPACE { - -#undef kIDByte -#undef kIDString - -#ifdef HASH_ARRAY_2 - #ifdef HASH_ARRAY_3 - #ifdef HASH_BIG - #define kIDByte 0x4 - #define kIDString TEXT("4b") - #else - #define kIDByte 0x3 - #define kIDString TEXT("4") - #endif - #else - #define kIDByte 0x2 - #define kIDString TEXT("3") - #endif -#else - #ifdef HASH_ZIP - #define kIDByte 0x0 - #define kIDString TEXT("3Z") - #else - #define kIDByte 0x1 - #define kIDString TEXT("2") - #endif -#endif - -#undef kIDUse3BytesByte -#undef kIDUse3BytesString - -#ifdef __USE_3_BYTES - #define kIDUse3BytesByte 0x80 - #define kIDUse3BytesString TEXT("T") -#else - #define kIDUse3BytesByte 0x00 - #define kIDUse3BytesString TEXT("") -#endif - -// #undef kIDStringFull - -// #define kIDStringFull TEXT("Compress.MatchFinderBT") kIDString kIDUse3BytesString - -// {23170F69-40C1-278C-02XX-0000000000} -DEFINE_GUID(BT_CLSID, -0x23170F69, 0x40C1, 0x278C, 0x02, kIDByte | kIDUse3BytesByte, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - -class CInTree2: public CInTree -{ - CMyComPtr<IMatchFinderCallback> _callback; - virtual void BeforeMoveBlock(); - virtual void AfterMoveBlock(); -public: - void SetCallback(IMatchFinderCallback *callback) - { - _callback = callback; - } -}; - -class CMatchFinderBinTree: - public IMatchFinder, - public IMatchFinderSetCallback, - public CMyUnknownImp -{ - MY_UNKNOWN_IMP1(IMatchFinderSetCallback) - - STDMETHOD(Init)(ISequentialInStream *stream); - STDMETHOD_(void, ReleaseStream)(); - STDMETHOD(MovePos)(); - STDMETHOD_(BYTE, GetIndexByte)(UINT32 index); - STDMETHOD_(UINT32, GetMatchLen)(UINT32 index, UINT32 back, UINT32 limit); - STDMETHOD_(UINT32, GetNumAvailableBytes)(); - STDMETHOD_(const BYTE *, GetPointerToCurrentPos)(); - STDMETHOD(Create)(UINT32 sizeHistory, - UINT32 keepAddBufferBefore, UINT32 matchMaxLen, - UINT32 keepAddBufferAfter); - STDMETHOD_(UINT32, GetLongestMatch)(UINT32 *distances); - STDMETHOD_(void, DummyLongestMatch)(); - - // IMatchFinderSetCallback - STDMETHOD(SetCallback)(IMatchFinderCallback *callback); - -private: - // UINT32 m_WindowReservSize; - CInTree2 _matchFinder; -public: - // CMatchFinderBinTree(): m_WindowReservSize((1 << 19) + 256) {}; - void SetCutValue(UINT32 cutValue) - { _matchFinder.SetCutValue(cutValue); } - /* - void SetWindowReservSize(UINT32 reservWindowSize) - { m_WindowReservSize = reservWindowSize; } - */ -}; - -} - -// #endif - diff --git a/7zip/Compress/LZ/BinTree/BinTreeMFMain.h b/7zip/Compress/LZ/BinTree/BinTreeMFMain.h deleted file mode 100755 index 499686ba..00000000 --- a/7zip/Compress/LZ/BinTree/BinTreeMFMain.h +++ /dev/null @@ -1,81 +0,0 @@ -// BinTreeMFMain.h - -// #include "StdAfx.h" - -// #include "BinTreeMF.h" -#include "BinTreeMain.h" - -namespace BT_NAMESPACE { - -void CInTree2::BeforeMoveBlock() -{ - if (_callback) - _callback->BeforeChangingBufferPos(); - CInTree::BeforeMoveBlock(); -} - -void CInTree2::AfterMoveBlock() -{ - CInTree::AfterMoveBlock(); - if (_callback) - _callback->AfterChangingBufferPos(); -} - -STDMETHODIMP CMatchFinderBinTree::Init(ISequentialInStream *stream) - { return _matchFinder.Init(stream); } - -STDMETHODIMP_(void) CMatchFinderBinTree::ReleaseStream() -{ - // _matchFinder.ReleaseStream(); -} - -STDMETHODIMP CMatchFinderBinTree::MovePos() - { return _matchFinder.MovePos(); } - -STDMETHODIMP_(BYTE) CMatchFinderBinTree::GetIndexByte(UINT32 index) - { return _matchFinder.GetIndexByte(index); } - -STDMETHODIMP_(UINT32) CMatchFinderBinTree::GetMatchLen(UINT32 index, - UINT32 back, UINT32 limit) - { return _matchFinder.GetMatchLen(index, back, limit); } - -STDMETHODIMP_(UINT32) CMatchFinderBinTree::GetNumAvailableBytes() - { return _matchFinder.GetNumAvailableBytes(); } - -STDMETHODIMP CMatchFinderBinTree::Create(UINT32 sizeHistory, - UINT32 keepAddBufferBefore, UINT32 matchMaxLen, - UINT32 keepAddBufferAfter) -{ - UINT32 windowReservSize = (sizeHistory + keepAddBufferBefore + - matchMaxLen + keepAddBufferAfter) / 2 + 256; - try - { - return _matchFinder.Create(sizeHistory, keepAddBufferBefore, - matchMaxLen, keepAddBufferAfter, windowReservSize); - } - catch(...) - { - return E_OUTOFMEMORY; - } -} - -STDMETHODIMP_(UINT32) CMatchFinderBinTree::GetLongestMatch(UINT32 *distances) - { return _matchFinder.GetLongestMatch(distances); } - -STDMETHODIMP_(void) CMatchFinderBinTree::DummyLongestMatch() - { _matchFinder.DummyLongestMatch(); } - -STDMETHODIMP_(const BYTE *) CMatchFinderBinTree::GetPointerToCurrentPos() -{ - return _matchFinder.GetPointerToCurrentPos(); -} - -// IMatchFinderSetCallback -STDMETHODIMP CMatchFinderBinTree::SetCallback(IMatchFinderCallback *callback) -{ - _matchFinder.SetCallback(callback); - return S_OK; -} - - -} diff --git a/7zip/Compress/LZ/BinTree/BinTreeMain.h b/7zip/Compress/LZ/BinTree/BinTreeMain.h index 6657d07d..21ba1d7c 100755 --- a/7zip/Compress/LZ/BinTree/BinTreeMain.h +++ b/7zip/Compress/LZ/BinTree/BinTreeMain.h @@ -1,542 +1,444 @@ -// BinTreemain.h - -// #include "StdAfx.h" - -// #include "BinTree.h" -// #include "Common/NewHandler.h" +// BinTreeMain.h #include "../../../../Common/Defs.h" #include "../../../../Common/CRC.h" +#include "../../../../Common/Alloc.h" namespace BT_NAMESPACE { #ifdef HASH_ARRAY_2 - static const UINT32 kHash2Size = 1 << 10; + static const UInt32 kHash2Size = 1 << 10; #ifdef HASH_ARRAY_3 - static const UINT32 kNumHashDirectBytes = 0; - static const UINT32 kNumHashBytes = 4; - static const UINT32 kHash3Size = 1 << 18; + static const UInt32 kNumHashDirectBytes = 0; + static const UInt32 kNumHashBytes = 4; + static const UInt32 kHash3Size = 1 << 18; #ifdef HASH_BIG - static const UINT32 kHashSize = 1 << 23; + static const UInt32 kHashSize = 1 << 23; #else - static const UINT32 kHashSize = 1 << 20; + static const UInt32 kHashSize = 1 << 20; #endif #else - static const UINT32 kNumHashDirectBytes = 3; - static const UINT32 kNumHashBytes = 3; - static const UINT32 kHashSize = 1 << (8 * kNumHashBytes); + static const UInt32 kNumHashDirectBytes = 3; + static const UInt32 kNumHashBytes = 3; + static const UInt32 kHashSize = 1 << (8 * kNumHashBytes); #endif #else #ifdef HASH_ZIP - static const UINT32 kNumHashDirectBytes = 0; - static const UINT32 kNumHashBytes = 3; - static const UINT32 kHashSize = 1 << 16; + static const UInt32 kNumHashDirectBytes = 0; + static const UInt32 kNumHashBytes = 3; + static const UInt32 kHashSize = 1 << 16; #else - static const UINT32 kNumHashDirectBytes = 2; - static const UINT32 kNumHashBytes = 2; - static const UINT32 kHashSize = 1 << (8 * kNumHashBytes); + #define THERE_ARE_DIRECT_HASH_BYTES + static const UInt32 kNumHashDirectBytes = 2; + static const UInt32 kNumHashBytes = 2; + static const UInt32 kHashSize = 1 << (8 * kNumHashBytes); #endif #endif +static const UInt32 kHashSizeSum = kHashSize + #ifdef HASH_ARRAY_2 + + kHash2Size + #ifdef HASH_ARRAY_3 + + kHash3Size + #endif + #endif + ; -CInTree::CInTree(): - #ifdef HASH_ARRAY_2 - _hash2(0), - #ifdef HASH_ARRAY_3 - _hash3(0), - #endif - #endif +#ifdef HASH_ARRAY_2 +static const UInt32 kHash2Offset = kHashSize; +#ifdef HASH_ARRAY_3 +static const UInt32 kHash3Offset = kHashSize + kHash2Size; +#endif +#endif + +CMatchFinderBinTree::CMatchFinderBinTree(): _hash(0), - _son(0), _cutValue(0xFF) { } -void CInTree::FreeMemory() +void CMatchFinderBinTree::FreeThisClassMemory() { - #ifdef WIN32 - if (_son != 0) - VirtualFree(_son, 0, MEM_RELEASE); - if (_hash != 0) - VirtualFree(_hash, 0, MEM_RELEASE); - #else - delete []_son; - delete []_hash; - #endif - _son = 0; + BigFree(_hash); _hash = 0; +} + +void CMatchFinderBinTree::FreeMemory() +{ + FreeThisClassMemory(); CLZInWindow::Free(); } -CInTree::~CInTree() +CMatchFinderBinTree::~CMatchFinderBinTree() { FreeMemory(); } -HRESULT CInTree::Create(UINT32 sizeHistory, UINT32 keepAddBufferBefore, - UINT32 matchMaxLen, UINT32 keepAddBufferAfter, UINT32 sizeReserv) +STDMETHODIMP CMatchFinderBinTree::Create(UInt32 historySize, UInt32 keepAddBufferBefore, + UInt32 matchMaxLen, UInt32 keepAddBufferAfter) { - FreeMemory(); - try + UInt32 sizeReserv = (historySize + keepAddBufferBefore + + matchMaxLen + keepAddBufferAfter) / 2 + 256; + if (CLZInWindow::Create(historySize + keepAddBufferBefore, + matchMaxLen + keepAddBufferAfter, sizeReserv)) { - CLZInWindow::Create(sizeHistory + keepAddBufferBefore, - matchMaxLen + keepAddBufferAfter, sizeReserv); - - if (_blockSize + 256 > kMaxValForNormalize) + if (historySize + 256 > kMaxValForNormalize) + { + FreeMemory(); return E_INVALIDARG; - - _historySize = sizeHistory; + } _matchMaxLen = matchMaxLen; - - _cyclicBufferSize = sizeHistory + 1; - - - UINT32 size = kHashSize; - #ifdef HASH_ARRAY_2 - size += kHash2Size; - #ifdef HASH_ARRAY_3 - size += kHash3Size; - #endif - #endif - - #ifdef WIN32 - _son = (CPair *)::VirtualAlloc(0, (_cyclicBufferSize + 1) * sizeof(CPair), MEM_COMMIT, PAGE_READWRITE); - if (_son == 0) - throw 1; // CNewException(); - _hash = (CIndex *)::VirtualAlloc(0, (size + 1) * sizeof(CIndex), MEM_COMMIT, PAGE_READWRITE); - if (_hash == 0) - throw 1; // CNewException(); - #else - _son = new CPair[_cyclicBufferSize + 1]; - _hash = new CIndex[size + 1]; - #endif - - // m_RightBase = &m_LeftBase[_blockSize]; - - // _hash = &m_RightBase[_blockSize]; - #ifdef HASH_ARRAY_2 - _hash2 = &_hash[kHashSize]; - #ifdef HASH_ARRAY_3 - _hash3 = &_hash2[kHash2Size]; - #endif - #endif - return S_OK; - } - catch(...) - { - FreeMemory(); - return E_OUTOFMEMORY; + UInt32 newCyclicBufferSize = historySize + 1; + if (_hash != 0 && newCyclicBufferSize == _cyclicBufferSize) + return S_OK; + FreeThisClassMemory(); + _cyclicBufferSize = newCyclicBufferSize; // don't change it + _hash = (CIndex *)BigAlloc((kHashSizeSum + _cyclicBufferSize * 2) * sizeof(CIndex)); + if (_hash != 0) + return S_OK; } + FreeMemory(); + return E_OUTOFMEMORY; } -static const UINT32 kEmptyHashValue = 0; +static const UInt32 kEmptyHashValue = 0; -HRESULT CInTree::Init(ISequentialInStream *stream) +STDMETHODIMP CMatchFinderBinTree::Init(ISequentialInStream *stream) { RINOK(CLZInWindow::Init(stream)); - int i; - for(i = 0; i < kHashSize; i++) + for(UInt32 i = 0; i < kHashSizeSum; i++) _hash[i] = kEmptyHashValue; - - #ifdef HASH_ARRAY_2 - for(i = 0; i < kHash2Size; i++) - _hash2[i] = kEmptyHashValue; - #ifdef HASH_ARRAY_3 - for(i = 0; i < kHash3Size; i++) - _hash3[i] = kEmptyHashValue; - #endif - #endif - _cyclicBufferPos = 0; - - ReduceOffsets(0 - 1); + ReduceOffsets(-1); return S_OK; } +STDMETHODIMP_(void) CMatchFinderBinTree::ReleaseStream() +{ + // ReleaseStream(); +} #ifdef HASH_ARRAY_2 #ifdef HASH_ARRAY_3 -inline UINT32 Hash(const BYTE *pointer, UINT32 &hash2Value, UINT32 &hash3Value) +inline UInt32 Hash(const Byte *pointer, UInt32 &hash2Value, UInt32 &hash3Value) { - UINT32 temp = CCRC::Table[pointer[0]] ^ pointer[1]; + UInt32 temp = CCRC::Table[pointer[0]] ^ pointer[1]; hash2Value = temp & (kHash2Size - 1); - hash3Value = (temp ^ (UINT32(pointer[2]) << 8)) & (kHash3Size - 1); - return (temp ^ (UINT32(pointer[2]) << 8) ^ (CCRC::Table[pointer[3]] << 5)) & + hash3Value = (temp ^ (UInt32(pointer[2]) << 8)) & (kHash3Size - 1); + return (temp ^ (UInt32(pointer[2]) << 8) ^ (CCRC::Table[pointer[3]] << 5)) & (kHashSize - 1); } #else // no HASH_ARRAY_3 -inline UINT32 Hash(const BYTE *pointer, UINT32 &hash2Value) +inline UInt32 Hash(const Byte *pointer, UInt32 &hash2Value) { hash2Value = (CCRC::Table[pointer[0]] ^ pointer[1]) & (kHash2Size - 1); - return (*((const UINT32 *)pointer)) & 0xFFFFFF; + return ((UInt32(pointer[0]) << 16)) | ((UInt32(pointer[1]) << 8)) | pointer[2]; } #endif // HASH_ARRAY_3 #else // no HASH_ARRAY_2 #ifdef HASH_ZIP -inline UINT32 Hash(const BYTE *pointer) +inline UInt32 Hash(const Byte *pointer) { - return ((UINT32(pointer[0]) << 8) ^ + return ((UInt32(pointer[0]) << 8) ^ CCRC::Table[pointer[1]] ^ pointer[2]) & (kHashSize - 1); } #else // no HASH_ZIP -inline UINT32 Hash(const BYTE *pointer) +inline UInt32 Hash(const Byte *pointer) { - return pointer[0] ^ (UINT32(pointer[1]) << 8); + return pointer[0] ^ (UInt32(pointer[1]) << 8); } #endif // HASH_ZIP #endif // HASH_ARRAY_2 -UINT32 CInTree::GetLongestMatch(UINT32 *distances) +STDMETHODIMP_(UInt32) CMatchFinderBinTree::GetLongestMatch(UInt32 *distances) { - UINT32 currentLimit; + UInt32 lenLimit; if (_pos + _matchMaxLen <= _streamPos) - currentLimit = _matchMaxLen; + lenLimit = _matchMaxLen; else { - currentLimit = _streamPos - _pos; - if(currentLimit < kNumHashBytes) + lenLimit = _streamPos - _pos; + if(lenLimit < kNumHashBytes) return 0; } - UINT32 matchMinPos = (_pos > _historySize) ? (_pos - _historySize) : 1; - BYTE *cur = _buffer + _pos; - - UINT32 matchHashLenMax = 0; + UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0; + Byte *cur = _buffer + _pos; + + UInt32 maxLen = 0; #ifdef HASH_ARRAY_2 - UINT32 hash2Value; + UInt32 hash2Value; #ifdef HASH_ARRAY_3 - UINT32 hash3Value; - UINT32 hashValue = Hash(cur, hash2Value, hash3Value); + UInt32 hash3Value; + UInt32 hashValue = Hash(cur, hash2Value, hash3Value); #else - UINT32 hashValue = Hash(cur, hash2Value); + UInt32 hashValue = Hash(cur, hash2Value); #endif #else - UINT32 hashValue = Hash(cur); + UInt32 hashValue = Hash(cur); #endif - UINT32 curMatch = _hash[hashValue]; + UInt32 curMatch = _hash[hashValue]; #ifdef HASH_ARRAY_2 - UINT32 curMatch2 = _hash2[hash2Value]; + UInt32 curMatch2 = _hash[kHash2Offset + hash2Value]; #ifdef HASH_ARRAY_3 - UINT32 curMatch3 = _hash3[hash3Value]; + UInt32 curMatch3 = _hash[kHash3Offset + hash3Value]; #endif - _hash2[hash2Value] = _pos; - bool matchLen2Exist = false; - UINT32 len2Distance = 0; - if(curMatch2 >= matchMinPos) - { + _hash[kHash2Offset + hash2Value] = _pos; + distances[2] = 0xFFFFFFFF; + if(curMatch2 > matchMinPos) if (_buffer[curMatch2] == cur[0]) { - len2Distance = _pos - curMatch2 - 1; - matchHashLenMax = 2; - matchLen2Exist = true; + distances[2] = _pos - curMatch2 - 1; + maxLen = 2; } - } #ifdef HASH_ARRAY_3 - _hash3[hash3Value] = _pos; - UINT32 matchLen3Exist = false; - UINT32 len3Distance = 0; - if(curMatch3 >= matchMinPos) - { + _hash[kHash3Offset + hash3Value] = _pos; + distances[3] = 0xFFFFFFFF; + if(curMatch3 > matchMinPos) if (_buffer[curMatch3] == cur[0]) { - len3Distance = _pos - curMatch3 - 1; - matchHashLenMax = 3; - matchLen3Exist = true; - if (matchLen2Exist) - { - if (len3Distance < len2Distance) - len2Distance = len3Distance; - } - else - { - len2Distance = len3Distance; - matchLen2Exist = true; - } + distances[3] = _pos - curMatch3 - 1; + maxLen = 3; } - } #endif #endif _hash[hashValue] = _pos; - if(curMatch < matchMinPos) - { - _son[_cyclicBufferPos].Left = kEmptyHashValue; - _son[_cyclicBufferPos].Right = kEmptyHashValue; + CIndex *son = _hash + kHashSizeSum; + CIndex *ptr0 = son + (_cyclicBufferPos << 1) + 1; + CIndex *ptr1 = son + (_cyclicBufferPos << 1); - #ifdef HASH_ARRAY_2 - distances[2] = len2Distance; - #ifdef HASH_ARRAY_3 - distances[3] = len3Distance; - #endif - #endif + distances[kNumHashBytes] = 0xFFFFFFFF; - return matchHashLenMax; + #ifdef THERE_ARE_DIRECT_HASH_BYTES + if (lenLimit == kNumHashDirectBytes) + { + if(curMatch > matchMinPos) + while (maxLen < kNumHashDirectBytes) + distances[++maxLen] = _pos - curMatch - 1; + // We don't need tree in this case } - CIndex *ptrLeft = &_son[_cyclicBufferPos].Right; - CIndex *ptrRight = &_son[_cyclicBufferPos].Left; - - UINT32 maxLen, minSameLeft, minSameRight, minSame; - maxLen = minSameLeft = minSameRight = minSame = kNumHashDirectBytes; - - #ifdef HASH_ARRAY_2 - #ifndef HASH_ARRAY_3 - if (matchLen2Exist) - distances[2] = len2Distance; - else - if (kNumHashDirectBytes >= 2) - distances[2] = _pos - curMatch - 1; - #endif + else #endif - - distances[maxLen] = _pos - curMatch - 1; - - for(UINT32 count = _cutValue; count > 0; count--) { - BYTE *pby1 = _buffer + curMatch; - // CIndex left = _son[curMatch].Left; // it's prefetch - UINT32 currentLen; - for(currentLen = minSame; currentLen < currentLimit; currentLen++/*, dwComps++*/) - if (pby1[currentLen] != cur[currentLen]) - break; - while (currentLen > maxLen) - distances[++maxLen] = _pos - curMatch - 1; - - UINT32 delta = _pos - curMatch; - UINT32 cyclicPos = (delta <= _cyclicBufferPos) ? - (_cyclicBufferPos - delta): - (_cyclicBufferPos - delta + _cyclicBufferSize); - - if (currentLen != currentLimit) + UInt32 len0, len1; + len0 = len1 = kNumHashDirectBytes; + UInt32 count = _cutValue; + while(true) { - if (pby1[currentLen] < cur[currentLen]) + if(curMatch <= matchMinPos || count-- == 0) { - *ptrRight = curMatch; - ptrRight = &_son[cyclicPos].Right; - curMatch = _son[cyclicPos].Right; - if(currentLen > minSameLeft) - { - minSameLeft = currentLen; - minSame = MyMin(minSameLeft, minSameRight); - } + *ptr0 = kEmptyHashValue; + *ptr1 = kEmptyHashValue; + break; } - else + Byte *pb = _buffer + curMatch; + UInt32 len = MyMin(len0, len1); + do { - *ptrLeft = curMatch; - ptrLeft = &_son[cyclicPos].Left; - // curMatch = left; - curMatch = _son[cyclicPos].Left; - if(currentLen > minSameRight) - { - minSameRight = currentLen; - minSame = MyMin(minSameLeft, minSameRight); - } + if (pb[len] != cur[len]) + break; } - } - else - { - if(currentLen < _matchMaxLen) + while(++len != lenLimit); + + UInt32 delta = _pos - curMatch; + while (maxLen < len) + distances[++maxLen] = delta - 1; + + UInt32 cyclicPos = (delta <= _cyclicBufferPos) ? + (_cyclicBufferPos - delta): + (_cyclicBufferPos - delta + _cyclicBufferSize); + CIndex *pair = son + (cyclicPos << 1); + + if (len != lenLimit) { - *ptrLeft = curMatch; - ptrLeft = &_son[cyclicPos].Left; - curMatch = _son[cyclicPos].Left; - if(currentLen > minSameRight) + if (pb[len] < cur[len]) { - minSameRight = currentLen; - minSame = MyMin(minSameLeft, minSameRight); + *ptr1 = curMatch; + ptr1 = pair + 1; + curMatch = *ptr1; + len1 = len; + } + else + { + *ptr0 = curMatch; + ptr0 = pair; + curMatch = *ptr0; + len0 = len; } } else { - *ptrLeft = _son[cyclicPos].Right; - *ptrRight = _son[cyclicPos].Left; - - #ifdef HASH_ARRAY_2 - if (matchLen2Exist && len2Distance < distances[2]) - distances[2] = len2Distance; - #ifdef HASH_ARRAY_3 - if (matchLen3Exist && len3Distance < distances[3]) - distances[3] = len3Distance; - #endif - #endif - - return maxLen; + *ptr1 = pair[0]; + *ptr0 = pair[1]; + break; } } - if(curMatch < matchMinPos) - break; } - *ptrLeft = kEmptyHashValue; - *ptrRight = kEmptyHashValue; #ifdef HASH_ARRAY_2 - if (matchLen2Exist) - { - if (maxLen < 2) - { - distances[2] = len2Distance; - maxLen = 2; - } - else if (len2Distance < distances[2]) - distances[2] = len2Distance; - } #ifdef HASH_ARRAY_3 - if (matchLen3Exist) - { - if (maxLen < 3) - { - distances[3] = len3Distance; - maxLen = 3; - } - else if (len3Distance < distances[3]) - distances[3] = len3Distance; - } + if (distances[4] < distances[3]) + distances[3] = distances[4]; #endif + if (distances[3] < distances[2]) + distances[2] = distances[3]; #endif return maxLen; } -void CInTree::DummyLongestMatch() +STDMETHODIMP_(void) CMatchFinderBinTree::DummyLongestMatch() { - UINT32 currentLimit; + UInt32 lenLimit; if (_pos + _matchMaxLen <= _streamPos) - currentLimit = _matchMaxLen; + lenLimit = _matchMaxLen; else { - currentLimit = _streamPos - _pos; - if(currentLimit < kNumHashBytes) + lenLimit = _streamPos - _pos; + if(lenLimit < kNumHashBytes) return; } - UINT32 matchMinPos = (_pos > _historySize) ? (_pos - _historySize) : 1; - BYTE *cur = _buffer + _pos; - + UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0; + Byte *cur = _buffer + _pos; + #ifdef HASH_ARRAY_2 - UINT32 hash2Value; + UInt32 hash2Value; #ifdef HASH_ARRAY_3 - UINT32 hash3Value; - UINT32 hashValue = Hash(cur, hash2Value, hash3Value); - _hash3[hash3Value] = _pos; + UInt32 hash3Value; + UInt32 hashValue = Hash(cur, hash2Value, hash3Value); + _hash[kHash3Offset + hash3Value] = _pos; #else - UINT32 hashValue = Hash(cur, hash2Value); + UInt32 hashValue = Hash(cur, hash2Value); #endif - _hash2[hash2Value] = _pos; + _hash[kHash2Offset + hash2Value] = _pos; #else - UINT32 hashValue = Hash(cur); + UInt32 hashValue = Hash(cur); #endif - UINT32 curMatch = _hash[hashValue]; + UInt32 curMatch = _hash[hashValue]; _hash[hashValue] = _pos; - if(curMatch < matchMinPos) - { - _son[_cyclicBufferPos].Left = kEmptyHashValue; - _son[_cyclicBufferPos].Right = kEmptyHashValue; - return; - } - CIndex *ptrLeft = &_son[_cyclicBufferPos].Right; - CIndex *ptrRight = &_son[_cyclicBufferPos].Left; + CIndex *son = _hash + kHashSizeSum; + CIndex *ptr0 = son + (_cyclicBufferPos << 1) + 1; + CIndex *ptr1 = son + (_cyclicBufferPos << 1); - UINT32 maxLen, minSameLeft, minSameRight, minSame; - maxLen = minSameLeft = minSameRight = minSame = kNumHashDirectBytes; - for(UINT32 count = _cutValue; count > 0; count--) + #ifdef THERE_ARE_DIRECT_HASH_BYTES + if (lenLimit != kNumHashDirectBytes) + #endif { - BYTE *pby1 = _buffer + curMatch; - // CIndex left = _son[curMatch].Left; // it's prefetch - UINT32 currentLen; - for(currentLen = minSame; currentLen < currentLimit; currentLen++/*, dwComps++*/) - if (pby1[currentLen] != cur[currentLen]) - break; - - UINT32 delta = _pos - curMatch; - UINT32 cyclicPos = (delta <= _cyclicBufferPos) ? - (_cyclicBufferPos - delta): - (_cyclicBufferPos - delta + _cyclicBufferSize); - - if (currentLen != currentLimit) + UInt32 len0, len1; + len0 = len1 = kNumHashDirectBytes; + UInt32 count = _cutValue; + while(true) { - if (pby1[currentLen] < cur[currentLen]) + if(curMatch <= matchMinPos || count-- == 0) + break; + Byte *pb = _buffer + curMatch; + UInt32 len = MyMin(len0, len1); + do { - *ptrRight = curMatch; - ptrRight = &_son[cyclicPos].Right; - curMatch = _son[cyclicPos].Right; - if(currentLen > minSameLeft) - { - minSameLeft = currentLen; - minSame = MyMin(minSameLeft, minSameRight); - } + if (pb[len] != cur[len]) + break; } - else + while(++len != lenLimit); + + UInt32 delta = _pos - curMatch; + UInt32 cyclicPos = (delta <= _cyclicBufferPos) ? + (_cyclicBufferPos - delta): + (_cyclicBufferPos - delta + _cyclicBufferSize); + CIndex *pair = son + (cyclicPos << 1); + + if (len != lenLimit) { - *ptrLeft = curMatch; - ptrLeft = &_son[cyclicPos].Left; - curMatch = _son[cyclicPos].Left; - // curMatch = left; - if(currentLen > minSameRight) + if (pb[len] < cur[len]) { - minSameRight = currentLen; - minSame = MyMin(minSameLeft, minSameRight); + *ptr1 = curMatch; + ptr1 = pair + 1; + curMatch = *ptr1; + len1 = len; } - } - } - else - { - if(currentLen < _matchMaxLen) - { - *ptrLeft = curMatch; - ptrLeft = &_son[cyclicPos].Left; - curMatch = _son[cyclicPos].Left; - if(currentLen > minSameRight) + else { - minSameRight = currentLen; - minSame = MyMin(minSameLeft, minSameRight); + *ptr0 = curMatch; + ptr0 = pair; + curMatch = *ptr0; + len0 = len; } } else { - *ptrLeft = _son[cyclicPos].Right; - *ptrRight = _son[cyclicPos].Left; + *ptr1 = pair[0]; + *ptr0 = pair[1]; return; } } - if(curMatch < matchMinPos) - break; } - *ptrLeft = kEmptyHashValue; - *ptrRight = kEmptyHashValue; + *ptr0 = kEmptyHashValue; + *ptr1 = kEmptyHashValue; } -void CInTree::NormalizeLinks(CIndex *array, UINT32 numItems, UINT32 subValue) +void CMatchFinderBinTree::Normalize() { - for (UINT32 i = 0; i < numItems; i++) + UInt32 subValue = _pos - _cyclicBufferSize; + CIndex *items = _hash; + UInt32 numItems = (kHashSizeSum + _cyclicBufferSize * 2); + for (UInt32 i = 0; i < numItems; i++) { - UINT32 value = array[i]; + UInt32 value = items[i]; if (value <= subValue) value = kEmptyHashValue; else value -= subValue; - array[i] = value; + items[i] = value; } + ReduceOffsets(subValue); +} + +STDMETHODIMP CMatchFinderBinTree::MovePos() +{ + if (++_cyclicBufferPos == _cyclicBufferSize) + _cyclicBufferPos = 0; + RINOK(CLZInWindow::MovePos()); + if (_pos == kMaxValForNormalize) + Normalize(); + return S_OK; } -void CInTree::Normalize() +STDMETHODIMP_(Byte) CMatchFinderBinTree::GetIndexByte(Int32 index) + { return CLZInWindow::GetIndexByte(index); } + +STDMETHODIMP_(UInt32) CMatchFinderBinTree::GetMatchLen(Int32 index, + UInt32 back, UInt32 limit) + { return CLZInWindow::GetMatchLen(index, back, limit); } + +STDMETHODIMP_(UInt32) CMatchFinderBinTree::GetNumAvailableBytes() + { return CLZInWindow::GetNumAvailableBytes(); } + +STDMETHODIMP_(const Byte *) CMatchFinderBinTree::GetPointerToCurrentPos() + { return CLZInWindow::GetPointerToCurrentPos(); } + +// IMatchFinderSetCallback +STDMETHODIMP CMatchFinderBinTree::SetCallback(IMatchFinderCallback *callback) { - UINT32 startItem = _pos - _historySize; - UINT32 subValue = startItem - 1; - // NormalizeLinks((CIndex *)(_son + startItem), _historySize * 2, subValue); - NormalizeLinks((CIndex *)_son, _cyclicBufferSize * 2, subValue); - - NormalizeLinks(_hash, kHashSize, subValue); + m_Callback = callback; + return S_OK; +} - #ifdef HASH_ARRAY_2 - NormalizeLinks(_hash2, kHash2Size, subValue); - #ifdef HASH_ARRAY_3 - NormalizeLinks(_hash3, kHash3Size, subValue); - #endif - #endif +void CMatchFinderBinTree::BeforeMoveBlock() +{ + if (m_Callback) + m_Callback->BeforeChangingBufferPos(); + CLZInWindow::BeforeMoveBlock(); +} - ReduceOffsets(subValue); +void CMatchFinderBinTree::AfterMoveBlock() +{ + if (m_Callback) + m_Callback->AfterChangingBufferPos(); + CLZInWindow::AfterMoveBlock(); } } diff --git a/7zip/Compress/LZ/HashChain/HC.h b/7zip/Compress/LZ/HashChain/HC.h index 0928c747..393bb8af 100755 --- a/7zip/Compress/LZ/HashChain/HC.h +++ b/7zip/Compress/LZ/HashChain/HC.h @@ -1,108 +1,55 @@ // HC.h -// #pragma once - -// #ifndef __HC_H -// #define __HC_H - #include "../LZInWindow.h" -#include "Common/Types.h" -#include "Windows/Defs.h" +#include "../IMatchFinder.h" namespace HC_NAMESPACE { +typedef UInt32 CIndex; +const UInt32 kMaxValForNormalize = (UInt32(1) << 31) - 1; -// #define __USE_3_BYTES - -#ifdef __USE_3_BYTES - -#pragma pack(push, PragmaBinTree) -#pragma pack(push, 1) - -struct CIndex +class CMatchFinderHC: + public IMatchFinder, + public IMatchFinderSetCallback, + public CLZInWindow, + public CMyUnknownImp { - BYTE Data[3]; - CIndex(){} - CIndex(UINT32 aValue) - { - Data[0] = aValue & 0xFF; - Data[1] = (aValue >> 8) & 0xFF; - Data[2] = (aValue >> 16) & 0xFF; - } - operator UINT32() const { return (*((const UINT32 *)Data)) & 0xFFFFFF; } -}; -const UINT32 kMaxValForNormalize = CIndex(-1); - -#pragma pack(pop) -#pragma pack(pop, PragmaBinTree) - -#else - -typedef UINT32 CIndex; -const UINT32 kMaxValForNormalize = (UINT32(1) << 31) - 1; - -#endif - - - -// #define HASH_ARRAY_2 - -// #ifdef HASH_ARRAY_2 - -// #define HASH_ARRAY_3 - -// #else - -// #define HASH_ZIP + UInt32 _cyclicBufferPos; + UInt32 _cyclicBufferSize; // it must be historySize + 1 + UInt32 _matchMaxLen; + CIndex *_hash; + UInt32 _cutValue; -// #endif + CMyComPtr<IMatchFinderCallback> m_Callback; -class CInTree: public CLZInWindow -{ - UINT32 _cyclicBufferPos; - UINT32 _cyclicBufferSize; + void Normalize(); + void FreeThisClassMemory(); + void FreeMemory(); - UINT32 _historySize; - UINT32 _matchMaxLen; + MY_UNKNOWN_IMP1(IMatchFinderSetCallback) - CIndex *_hash; - - #ifdef HASH_ARRAY_2 - CIndex *_hash2; - #ifdef HASH_ARRAY_3 - CIndex *_hash3; - #endif - #endif - - CIndex *_chain; + STDMETHOD(Init)(ISequentialInStream *inStream); + STDMETHOD_(void, ReleaseStream)(); + STDMETHOD(MovePos)(); + STDMETHOD_(Byte, GetIndexByte)(Int32 index); + STDMETHOD_(UInt32, GetMatchLen)(Int32 index, UInt32 back, UInt32 limit); + STDMETHOD_(UInt32, GetNumAvailableBytes)(); + STDMETHOD_(const Byte *, GetPointerToCurrentPos)(); + STDMETHOD(Create)(UInt32 historySize, UInt32 keepAddBufferBefore, + UInt32 matchMaxLen, UInt32 keepAddBufferAfter); + STDMETHOD_(UInt32, GetLongestMatch)(UInt32 *distances); + STDMETHOD_(void, DummyLongestMatch)(); - UINT32 _cutValue; + // IMatchFinderSetCallback + STDMETHOD(SetCallback)(IMatchFinderCallback *callback); - void NormalizeLinks(CIndex *anArray, UINT32 aNumItems, UINT32 aSubValue); - void Normalize(); - void FreeMemory(); + virtual void BeforeMoveBlock(); + virtual void AfterMoveBlock(); public: - CInTree(); - ~CInTree(); - HRESULT Create(UINT32 aSizeHistory, UINT32 aKeepAddBufferBefore, UINT32 aMatchMaxLen, - UINT32 aKeepAddBufferAfter, UINT32 _dwSizeReserv = (1<<17)); - HRESULT Init(ISequentialInStream *aStream); - void SetCutValue(UINT32 aCutValue) { _cutValue = aCutValue; } - UINT32 GetLongestMatch(UINT32 *aDistances); - void DummyLongestMatch(); - HRESULT MovePos() - { - _cyclicBufferPos++; - if (_cyclicBufferPos >= _cyclicBufferSize) - _cyclicBufferPos = 0; - RINOK(CLZInWindow::MovePos()); - if (_pos == kMaxValForNormalize) - Normalize(); - return S_OK; - } + CMatchFinderHC(); + virtual ~CMatchFinderHC(); + void SetCutValue(UInt32 cutValue) { _cutValue = cutValue; } }; } - -// #endif diff --git a/7zip/Compress/LZ/HashChain/HC2.h b/7zip/Compress/LZ/HashChain/HC2.h index c2582cee..e9f22e1f 100755 --- a/7zip/Compress/LZ/HashChain/HC2.h +++ b/7zip/Compress/LZ/HashChain/HC2.h @@ -1,12 +1,7 @@ // HC2.h -#pragma once - -#ifndef __HC2__H -#define __HC2__H - -#undef HC_CLSID -#define HC_CLSID CLSID_CMatchFinderHC2 +#ifndef __HC2_H +#define __HC2_H #undef HC_NAMESPACE #define HC_NAMESPACE NHC2 diff --git a/7zip/Compress/LZ/HashChain/HC3.h b/7zip/Compress/LZ/HashChain/HC3.h index 1edca882..a9afd251 100755 --- a/7zip/Compress/LZ/HashChain/HC3.h +++ b/7zip/Compress/LZ/HashChain/HC3.h @@ -1,20 +1,15 @@ // HC3.h -#pragma once - -#ifndef __HC3__H -#define __HC3__H - -#undef HC_CLSID -#define HC_CLSID CLSID_CMatchFinderHC3 +#ifndef __HC3_H +#define __HC3_H #undef HC_NAMESPACE #define HC_NAMESPACE NHC3 #define HASH_ARRAY_2 -#include "HCMF.h" -#include "HCMFMain.h" +#include "HC.h" +#include "HCMain.h" #undef HASH_ARRAY_2 diff --git a/7zip/Compress/LZ/HashChain/HC4.h b/7zip/Compress/LZ/HashChain/HC4.h index fb0a39df..a88828d5 100755 --- a/7zip/Compress/LZ/HashChain/HC4.h +++ b/7zip/Compress/LZ/HashChain/HC4.h @@ -1,12 +1,7 @@ // HC4.h -#pragma once - -#ifndef __HC4__H -#define __HC4__H - -#undef HC_CLSID -#define HC_CLSID CLSID_CMatchFinderHC4 +#ifndef __HC4_H +#define __HC4_H #undef HC_NAMESPACE #define HC_NAMESPACE NHC4 @@ -14,8 +9,8 @@ #define HASH_ARRAY_2 #define HASH_ARRAY_3 -#include "HCMF.h" -#include "HCMFMain.h" +#include "HC.h" +#include "HCMain.h" #undef HASH_ARRAY_2 #undef HASH_ARRAY_3 diff --git a/7zip/Compress/LZ/HashChain/HC4b.h b/7zip/Compress/LZ/HashChain/HC4b.h index 6f8949d8..e2df3ef4 100755 --- a/7zip/Compress/LZ/HashChain/HC4b.h +++ b/7zip/Compress/LZ/HashChain/HC4b.h @@ -1,13 +1,8 @@ // HC4b.h -#pragma once - #ifndef __HC4B__H #define __HC4B__H -#undef HC_CLSID -#define HC_CLSID CLSID_CMatchFinderHC4b - #undef HC_NAMESPACE #define HC_NAMESPACE NHC4b @@ -15,8 +10,8 @@ #define HASH_ARRAY_3 #define HASH_BIG -#include "HCMF.h" -#include "HCMFMain.h" +#include "HC.h" +#include "HCMain.h" #undef HASH_ARRAY_2 #undef HASH_ARRAY_3 diff --git a/7zip/Compress/LZ/HashChain/HCMF.h b/7zip/Compress/LZ/HashChain/HCMF.h deleted file mode 100755 index 94f42f6b..00000000 --- a/7zip/Compress/LZ/HashChain/HCMF.h +++ /dev/null @@ -1,111 +0,0 @@ -// HCMF.h - -// #pragma once - -// #ifndef __HCMF_H -// #define __HCMF_H - -#include "Common/MyCom.h" -// #include "../../../Interface/CompressInterface.h" -#include "HC.h" - -namespace HC_NAMESPACE { - -#undef kIDByte -#undef kIDString - -#ifdef HASH_ARRAY_2 - #ifdef HASH_ARRAY_3 - #ifdef HASH_BIG - #define kIDByte 0x4 - #define kIDString TEXT("4b") - #else - #define kIDByte 0x3 - #define kIDString TEXT("4") - #endif - #else - #define kIDByte 0x2 - #define kIDString TEXT("3") - #endif -#else - #ifdef HASH_ZIP - #define kIDByte 0x0 - #define kIDString TEXT("3Z") - #else - #define kIDByte 0x1 - #define kIDString TEXT("2") - #endif -#endif - -#undef kIDUse3BytesByte -#undef kIDUse3BytesString - -#ifdef __USE_3_BYTES - #define kIDUse3BytesByte 0x80 - #define kIDUse3BytesString TEXT("T") -#else - #define kIDUse3BytesByte 0x00 - #define kIDUse3BytesString TEXT("") -#endif - -// #undef kIDStringFull - -// #define kIDStringFull TEXT("Compress.MatchFinderHC") kIDString kIDUse3BytesString - -// {23170F69-40C1-278C-03XX-0000000000} -DEFINE_GUID(HC_CLSID, -0x23170F69, 0x40C1, 0x278C, 0x03, kIDByte | kIDUse3BytesByte, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - -class CInTree2: public CInTree -{ - CMyComPtr<IMatchFinderCallback> m_Callback; - virtual void BeforeMoveBlock(); - virtual void AfterMoveBlock(); -public: - void SetCallback(IMatchFinderCallback *aCallback) - { - m_Callback = aCallback; - } -}; - -class CMatchFinderHC: - public IMatchFinder, - public IMatchFinderSetCallback, - public CMyUnknownImp -{ - MY_UNKNOWN_IMP1(IMatchFinderSetCallback) - - STDMETHOD(Init)(ISequentialInStream *aStream); - STDMETHOD_(void, ReleaseStream)(); - STDMETHOD(MovePos)(); - STDMETHOD_(BYTE, GetIndexByte)(UINT32 anIndex); - STDMETHOD_(UINT32, GetMatchLen)(UINT32 aIndex, UINT32 aBack, UINT32 aLimit); - STDMETHOD_(UINT32, GetNumAvailableBytes)(); - STDMETHOD_(const BYTE *, GetPointerToCurrentPos)(); - STDMETHOD(Create)(UINT32 aSizeHistory, - UINT32 aKeepAddBufferBefore, UINT32 aMatchMaxLen, - UINT32 aKeepAddBufferAfter); - STDMETHOD_(UINT32, GetLongestMatch)(UINT32 *aDistances); - STDMETHOD_(void, DummyLongestMatch)(); - - // IMatchFinderSetCallback - STDMETHOD(SetCallback)(IMatchFinderCallback *aCallback); - -private: - // UINT32 m_WindowReservSize; - CInTree2 m_MatchFinder; -public: - // CMatchFinderHC(): m_WindowReservSize((1 << 19) + 256) {}; - void SetCutValue(UINT32 aCutValue) - { m_MatchFinder.SetCutValue(aCutValue); } - /* - void SetWindowReservSize(UINT32 aReservWindowSize) - { m_WindowReservSize = aReservWindowSize; } - */ -}; - -} - -// #endif - diff --git a/7zip/Compress/LZ/HashChain/HCMFMain.h b/7zip/Compress/LZ/HashChain/HCMFMain.h deleted file mode 100755 index dd428488..00000000 --- a/7zip/Compress/LZ/HashChain/HCMFMain.h +++ /dev/null @@ -1,78 +0,0 @@ -// HCMFMain.h - -#include "HCMain.h" - -namespace HC_NAMESPACE { - -void CInTree2::BeforeMoveBlock() -{ - if (m_Callback) - m_Callback->BeforeChangingBufferPos(); - CInTree::BeforeMoveBlock(); -} - -void CInTree2::AfterMoveBlock() -{ - if (m_Callback) - m_Callback->AfterChangingBufferPos(); - CInTree::AfterMoveBlock(); -} - -STDMETHODIMP CMatchFinderHC::Init(ISequentialInStream *aStream) - { return m_MatchFinder.Init(aStream); } - -STDMETHODIMP_(void) CMatchFinderHC::ReleaseStream() -{ - // m_MatchFinder.ReleaseStream(); -} - -STDMETHODIMP CMatchFinderHC::MovePos() - { return m_MatchFinder.MovePos(); } - -STDMETHODIMP_(BYTE) CMatchFinderHC::GetIndexByte(UINT32 anIndex) - { return m_MatchFinder.GetIndexByte(anIndex); } - -STDMETHODIMP_(UINT32) CMatchFinderHC::GetMatchLen(UINT32 aIndex, - UINT32 aBack, UINT32 aLimit) - { return m_MatchFinder.GetMatchLen(aIndex, aBack, aLimit); } - -STDMETHODIMP_(UINT32) CMatchFinderHC::GetNumAvailableBytes() - { return m_MatchFinder.GetNumAvailableBytes(); } - -STDMETHODIMP CMatchFinderHC::Create(UINT32 aSizeHistory, - UINT32 aKeepAddBufferBefore, UINT32 aMatchMaxLen, - UINT32 aKeepAddBufferAfter) -{ - UINT32 aWindowReservSize = (aSizeHistory + aKeepAddBufferBefore + - aMatchMaxLen + aKeepAddBufferAfter) / 2 + 256; - try - { - return m_MatchFinder.Create(aSizeHistory, aKeepAddBufferBefore, aMatchMaxLen, - aKeepAddBufferAfter, aWindowReservSize); - } - catch(...) - { - return E_OUTOFMEMORY; - } -} - -STDMETHODIMP_(UINT32) CMatchFinderHC::GetLongestMatch(UINT32 *aDistances) - { return m_MatchFinder.GetLongestMatch(aDistances); } - -STDMETHODIMP_(void) CMatchFinderHC::DummyLongestMatch() - { m_MatchFinder.DummyLongestMatch(); } - -STDMETHODIMP_(const BYTE *) CMatchFinderHC::GetPointerToCurrentPos() -{ - return m_MatchFinder.GetPointerToCurrentPos(); -} - -// IMatchFinderSetCallback -STDMETHODIMP CMatchFinderHC::SetCallback(IMatchFinderCallback *aCallback) -{ - m_MatchFinder.SetCallback(aCallback); - return S_OK; -} - - -} diff --git a/7zip/Compress/LZ/HashChain/HCMain.h b/7zip/Compress/LZ/HashChain/HCMain.h index fbe6cb13..fe67e4f5 100755 --- a/7zip/Compress/LZ/HashChain/HCMain.h +++ b/7zip/Compress/LZ/HashChain/HCMain.h @@ -1,436 +1,350 @@ // HC.h -// #include "StdAfx.h" - -// #include "BinTree.h" -#include "Common/NewHandler.h" - -#include "Common/Defs.h" -#include "Common/CRC.h" +#include "../../../../Common/Defs.h" +#include "../../../../Common/CRC.h" +#include "../../../../Common/Alloc.h" namespace HC_NAMESPACE { #ifdef HASH_ARRAY_2 - static const UINT32 kHash2Size = 1 << 10; + static const UInt32 kHash2Size = 1 << 10; #ifdef HASH_ARRAY_3 - static const UINT32 kNumHashDirectBytes = 0; - static const UINT32 kNumHashBytes = 4; - static const UINT32 kHash3Size = 1 << 18; + static const UInt32 kNumHashDirectBytes = 0; + static const UInt32 kNumHashBytes = 4; + static const UInt32 kHash3Size = 1 << 18; #ifdef HASH_BIG - static const UINT32 kHashSize = 1 << 23; + static const UInt32 kHashSize = 1 << 23; #else - static const UINT32 kHashSize = 1 << 20; + static const UInt32 kHashSize = 1 << 20; #endif #else - static const UINT32 kNumHashBytes = 3; - // static const UINT32 kNumHashDirectBytes = 3; - // static const UINT32 kHashSize = 1 << (8 * kNumHashBytes); - static const UINT32 kNumHashDirectBytes = 0; - static const UINT32 kHashSize = 1 << (16); + static const UInt32 kNumHashDirectBytes = 0; + static const UInt32 kNumHashBytes = 3; + static const UInt32 kHashSize = 1 << (16); #endif #else #ifdef HASH_ZIP - static const UINT32 kNumHashDirectBytes = 0; - static const UINT32 kNumHashBytes = 3; - static const UINT32 kHashSize = 1 << 16; + static const UInt32 kNumHashDirectBytes = 0; + static const UInt32 kNumHashBytes = 3; + static const UInt32 kHashSize = 1 << 16; #else - static const UINT32 kNumHashDirectBytes = 2; - static const UINT32 kNumHashBytes = 2; - static const UINT32 kHashSize = 1 << (8 * kNumHashBytes); + #define THERE_ARE_DIRECT_HASH_BYTES + static const UInt32 kNumHashDirectBytes = 2; + static const UInt32 kNumHashBytes = 2; + static const UInt32 kHashSize = 1 << (8 * kNumHashBytes); #endif #endif +static const UInt32 kHashSizeSum = kHashSize + #ifdef HASH_ARRAY_2 + + kHash2Size + #ifdef HASH_ARRAY_3 + + kHash3Size + #endif + #endif + ; -CInTree::CInTree(): - #ifdef HASH_ARRAY_2 - _hash2(0), - #ifdef HASH_ARRAY_3 - _hash3(0), - #endif - #endif +#ifdef HASH_ARRAY_2 +static const UInt32 kHash2Offset = kHashSize; +#ifdef HASH_ARRAY_3 +static const UInt32 kHash3Offset = kHashSize + kHash2Size; +#endif +#endif + +CMatchFinderHC::CMatchFinderHC(): _hash(0), - _chain(0), _cutValue(16) { } -void CInTree::FreeMemory() +void CMatchFinderHC::FreeThisClassMemory() { - #ifdef WIN32 - if (_chain != 0) - VirtualFree(_chain, 0, MEM_RELEASE); - if (_hash != 0) - VirtualFree(_hash, 0, MEM_RELEASE); - #else - delete []_chain; - delete []_hash; - #endif - _chain = 0; + BigFree(_hash); _hash = 0; +} + +void CMatchFinderHC::FreeMemory() +{ + FreeThisClassMemory(); CLZInWindow::Free(); } -CInTree::~CInTree() +CMatchFinderHC::~CMatchFinderHC() { FreeMemory(); } -HRESULT CInTree::Create(UINT32 aSizeHistory, UINT32 aKeepAddBufferBefore, - UINT32 aMatchMaxLen, UINT32 aKeepAddBufferAfter, UINT32 aSizeReserv) +STDMETHODIMP CMatchFinderHC::Create(UInt32 historySize, UInt32 keepAddBufferBefore, + UInt32 matchMaxLen, UInt32 keepAddBufferAfter) { - FreeMemory(); - try + UInt32 sizeReserv = (historySize + keepAddBufferBefore + + matchMaxLen + keepAddBufferAfter) / 2 + 256; + if (CLZInWindow::Create(historySize + keepAddBufferBefore, + matchMaxLen + keepAddBufferAfter, sizeReserv)) { - CLZInWindow::Create(aSizeHistory + aKeepAddBufferBefore, - aMatchMaxLen + aKeepAddBufferAfter, aSizeReserv); - - if (_blockSize + 256 > kMaxValForNormalize) + if (historySize + 256 > kMaxValForNormalize) + { + FreeMemory(); return E_INVALIDARG; - - _historySize = aSizeHistory; - _matchMaxLen = aMatchMaxLen; - _cyclicBufferSize = aSizeHistory + 1; - - - UINT32 aSize = kHashSize; - #ifdef HASH_ARRAY_2 - aSize += kHash2Size; - #ifdef HASH_ARRAY_3 - aSize += kHash3Size; - #endif - #endif - - #ifdef WIN32 - _chain = (CIndex *)::VirtualAlloc(0, (_cyclicBufferSize + 1) * sizeof(CIndex), MEM_COMMIT, PAGE_READWRITE); - if (_chain == 0) - throw CNewException(); - _hash = (CIndex *)::VirtualAlloc(0, (aSize + 1) * sizeof(CIndex), MEM_COMMIT, PAGE_READWRITE); - if (_hash == 0) - throw CNewException(); - #else - _chain = new CIndex[_cyclicBufferSize + 1]; - _hash = new CIndex[aSize + 1]; - #endif - - // m_RightBase = &m_LeftBase[_blockSize]; - - // _hash = &m_RightBase[_blockSize]; - #ifdef HASH_ARRAY_2 - _hash2 = &_hash[kHashSize]; - #ifdef HASH_ARRAY_3 - _hash3 = &_hash2[kHash2Size]; - #endif - #endif - return S_OK; - } - catch(...) - { - FreeMemory(); - return E_OUTOFMEMORY; + } + _matchMaxLen = matchMaxLen; + UInt32 newCyclicBufferSize = historySize + 1; + if (_hash != 0 && newCyclicBufferSize == _cyclicBufferSize) + return S_OK; + FreeThisClassMemory(); + _cyclicBufferSize = newCyclicBufferSize; // don't change it + _hash = (CIndex *)BigAlloc((kHashSizeSum + _cyclicBufferSize) * sizeof(CIndex)); + if (_hash != 0) + return S_OK; } + FreeMemory(); + return E_OUTOFMEMORY; } -static const UINT32 kEmptyHashValue = 0; +static const UInt32 kEmptyHashValue = 0; -HRESULT CInTree::Init(ISequentialInStream *aStream) +STDMETHODIMP CMatchFinderHC::Init(ISequentialInStream *stream) { - RINOK(CLZInWindow::Init(aStream)); - int i; - for(i = 0; i < kHashSize; i++) + RINOK(CLZInWindow::Init(stream)); + for(UInt32 i = 0; i < kHashSizeSum; i++) _hash[i] = kEmptyHashValue; - - #ifdef HASH_ARRAY_2 - for(i = 0; i < kHash2Size; i++) - _hash2[i] = kEmptyHashValue; - #ifdef HASH_ARRAY_3 - for(i = 0; i < kHash3Size; i++) - _hash3[i] = kEmptyHashValue; - #endif - #endif - _cyclicBufferPos = 0; - - ReduceOffsets(0 - 1); + ReduceOffsets(-1); return S_OK; } +STDMETHODIMP_(void) CMatchFinderHC::ReleaseStream() +{ + // ReleaseStream(); +} #ifdef HASH_ARRAY_2 #ifdef HASH_ARRAY_3 -inline UINT32 Hash(const BYTE *pointer, UINT32 &hash2Value, UINT32 &aHash3Value) +inline UInt32 Hash(const Byte *pointer, UInt32 &hash2Value, UInt32 &hash3Value) { - UINT32 temp = CCRC::Table[pointer[0]] ^ pointer[1]; + UInt32 temp = CCRC::Table[pointer[0]] ^ pointer[1]; hash2Value = temp & (kHash2Size - 1); - aHash3Value = (temp ^ (UINT32(pointer[2]) << 8)) & (kHash3Size - 1); - return (temp ^ (UINT32(pointer[2]) << 8) ^ (CCRC::Table[pointer[3]] << 5)) & + hash3Value = (temp ^ (UInt32(pointer[2]) << 8)) & (kHash3Size - 1); + return (temp ^ (UInt32(pointer[2]) << 8) ^ (CCRC::Table[pointer[3]] << 5)) & (kHashSize - 1); } #else // no HASH_ARRAY_3 -inline UINT32 Hash(const BYTE *pointer, UINT32 &hash2Value) +inline UInt32 Hash(const Byte *pointer, UInt32 &hash2Value) { - UINT32 temp = CCRC::Table[pointer[0]] ^ pointer[1]; + UInt32 temp = CCRC::Table[pointer[0]] ^ pointer[1]; hash2Value = temp & (kHash2Size - 1); - return (temp ^ (UINT32(pointer[2]) << 8)) & (kHashSize - 1);; + return (temp ^ (UInt32(pointer[2]) << 8)) & (kHashSize - 1);; } #endif // HASH_ARRAY_3 #else // no HASH_ARRAY_2 #ifdef HASH_ZIP -inline UINT32 Hash(const BYTE *pointer) +inline UInt32 Hash(const Byte *pointer) { - return ((UINT32(pointer[0]) << 8) ^ + return ((UInt32(pointer[0]) << 8) ^ CCRC::Table[pointer[1]] ^ pointer[2]) & (kHashSize - 1); } #else // no HASH_ZIP -inline UINT32 Hash(const BYTE *pointer) +inline UInt32 Hash(const Byte *pointer) { - return pointer[0] ^ (UINT32(pointer[1]) << 8); + return pointer[0] ^ (UInt32(pointer[1]) << 8); } #endif // HASH_ZIP #endif // HASH_ARRAY_2 -UINT32 CInTree::GetLongestMatch(UINT32 *aDistances) +STDMETHODIMP_(UInt32) CMatchFinderHC::GetLongestMatch(UInt32 *distances) { - UINT32 aCurrentLimit; + UInt32 lenLimit; if (_pos + _matchMaxLen <= _streamPos) - aCurrentLimit = _matchMaxLen; + lenLimit = _matchMaxLen; else { - aCurrentLimit = _streamPos - _pos; - if(aCurrentLimit < kNumHashBytes) + lenLimit = _streamPos - _pos; + if(lenLimit < kNumHashBytes) return 0; } - UINT32 aMatchMinPos = (_pos > _historySize) ? (_pos - _historySize) : 1; - BYTE *aCur = _buffer + _pos; + UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0; + Byte *cur = _buffer + _pos; - UINT32 aMatchHashLenMax = 0; + UInt32 maxLen = 0; #ifdef HASH_ARRAY_2 - - UINT32 hash2Value; - + UInt32 hash2Value; #ifdef HASH_ARRAY_3 - - UINT32 aHash3Value; - UINT32 hashValue = Hash(aCur, hash2Value, aHash3Value); - - #else // no HASH_ARRAY_3 - - UINT32 hashValue = Hash(aCur, hash2Value); - - #endif // HASH_ARRAY_3 - - #else // no HASH_ARRAY_2 - - UINT32 hashValue = Hash(aCur); - + UInt32 hash3Value; + UInt32 hashValue = Hash(cur, hash2Value, hash3Value); + #else + UInt32 hashValue = Hash(cur, hash2Value); + #endif + #else + UInt32 hashValue = Hash(cur); #endif - #ifdef HASH_ARRAY_2 - UINT32 aCurMatch2 = _hash2[hash2Value]; - _hash2[hash2Value] = _pos; - bool aMatchLen2Exist = false; - UINT32 aLen2Distance = 0; - if(aCurMatch2 >= aMatchMinPos) - { - if (_buffer[aCurMatch2] == aCur[0]) + UInt32 curMatch2 = _hash[kHash2Offset + hash2Value]; + _hash[kHash2Offset + hash2Value] = _pos; + distances[2] = 0xFFFFFFFF; + if(curMatch2 > matchMinPos) + if (_buffer[curMatch2] == cur[0]) { - aLen2Distance = _pos - aCurMatch2 - 1; - aMatchHashLenMax = 2; - aMatchLen2Exist = true; + distances[2] = _pos - curMatch2 - 1; + maxLen = 2; } - } #ifdef HASH_ARRAY_3 - UINT32 aCurMatch3 = _hash3[aHash3Value]; - _hash3[aHash3Value] = _pos; - UINT32 aMatchLen3Exist = false; - UINT32 aLen3Distance = 0; - if(aCurMatch3 >= aMatchMinPos) - { - if (_buffer[aCurMatch3] == aCur[0]) + UInt32 curMatch3 = _hash[kHash3Offset + hash3Value]; + _hash[kHash3Offset + hash3Value] = _pos; + distances[3] = 0xFFFFFFFF; + if(curMatch3 > matchMinPos) + if (_buffer[curMatch3] == cur[0]) { - aLen3Distance = _pos - aCurMatch3 - 1; - aMatchHashLenMax = 3; - aMatchLen3Exist = true; - if (aMatchLen2Exist) - { - if (aLen3Distance < aLen2Distance) - aLen2Distance = aLen3Distance; - } - else - { - aLen2Distance = aLen3Distance; - aMatchLen2Exist = true; - } + distances[3] = _pos - curMatch3 - 1; + maxLen = 3; } - } #endif #endif - UINT32 aCurMatch = _hash[hashValue]; + UInt32 curMatch = _hash[hashValue]; _hash[hashValue] = _pos; - if(aCurMatch < aMatchMinPos) + CIndex *chain = _hash + kHashSizeSum; + chain[_cyclicBufferPos] = curMatch; + distances[kNumHashBytes] = 0xFFFFFFFF; + #ifdef THERE_ARE_DIRECT_HASH_BYTES + if (lenLimit == kNumHashDirectBytes) { - _chain[_cyclicBufferPos] = kEmptyHashValue; - - #ifdef HASH_ARRAY_2 - aDistances[2] = aLen2Distance; - #ifdef HASH_ARRAY_3 - aDistances[3] = aLen3Distance; - #endif - #endif - - return aMatchHashLenMax; + if(curMatch > matchMinPos) + while (maxLen < kNumHashDirectBytes) + distances[++maxLen] = _pos - curMatch - 1; } - _chain[_cyclicBufferPos] = aCurMatch; - - - #ifdef HASH_ARRAY_2 - #ifndef HASH_ARRAY_3 - if (aMatchLen2Exist) - aDistances[2] = aLen2Distance; - else - if (kNumHashDirectBytes >= 2) - aDistances[2] = _pos - aCurMatch - 1; - #endif + else #endif - - UINT32 aMax, aMinSame; - - aMax = aMinSame = kNumHashDirectBytes; - - aDistances[aMax] = _pos - aCurMatch - 1; - - for(UINT32 aCount = _cutValue; aCount > 0; aCount--) { - BYTE *pby1 = _buffer + aCurMatch; - UINT32 aCurrentLen; - for(aCurrentLen = aMinSame; aCurrentLen < aCurrentLimit; aCurrentLen++/*, dwComps++*/) - if (pby1[aCurrentLen] != aCur[aCurrentLen]) - break; - if (aCurrentLen > aMax) + UInt32 count = _cutValue; + do { - UINT32 dwBack = _pos - aCurMatch - 1; - for(UINT32 dwLen = aMax + 1; dwLen <= aCurrentLen; dwLen++) - aDistances[dwLen] = dwBack; - aMax = aCurrentLen; + if(curMatch <= matchMinPos) + break; + Byte *pby1 = _buffer + curMatch; + UInt32 currentLen = kNumHashDirectBytes; + do + { + if (pby1[currentLen] != cur[currentLen]) + break; + } + while(++currentLen != lenLimit); + + UInt32 delta = _pos - curMatch; + while (maxLen < currentLen) + distances[++maxLen] = delta - 1; + if(currentLen == lenLimit) + break; + + UInt32 cyclicPos = (delta <= _cyclicBufferPos) ? + (_cyclicBufferPos - delta): + (_cyclicBufferPos - delta + _cyclicBufferSize); + + curMatch = chain[cyclicPos]; } - if(aCurrentLen == aCurrentLimit) - break; - - UINT32 aDelta = _pos - aCurMatch; - UINT32 aCyclicPos = (aDelta <= _cyclicBufferPos) ? - (_cyclicBufferPos - aDelta): - (_cyclicBufferPos - aDelta + _cyclicBufferSize); - - aCurMatch = _chain[aCyclicPos]; - if(aCurMatch < aMatchMinPos) - break; + while(--count != 0); } #ifdef HASH_ARRAY_2 - if (aMatchLen2Exist) - { - if (aMax < 2) - { - aDistances[2] = aLen2Distance; - aMax = 2; - } - else if (aLen2Distance < aDistances[2]) - aDistances[2] = aLen2Distance; - } #ifdef HASH_ARRAY_3 - if (aMatchLen3Exist) - { - if (aMax < 3) - { - aDistances[3] = aLen3Distance; - aMax = 3; - } - else if (aLen3Distance < aDistances[3]) - aDistances[3] = aLen3Distance; - } + if (distances[4] < distances[3]) + distances[3] = distances[4]; #endif + if (distances[3] < distances[2]) + distances[2] = distances[3]; #endif - return aMax; + return maxLen; } -void CInTree::DummyLongestMatch() +STDMETHODIMP_(void) CMatchFinderHC::DummyLongestMatch() { - UINT32 aCurrentLimit; - if (_pos + _matchMaxLen <= _streamPos) - aCurrentLimit = _matchMaxLen; - else - { - aCurrentLimit = _streamPos - _pos; - if(aCurrentLimit < kNumHashBytes) - return; - } - UINT32 aMatchMinPos = (_pos > _historySize) ? (_pos - _historySize) : 1; - BYTE *aCur = _buffer + _pos; + if (_streamPos - _pos < kNumHashBytes) + return; + + Byte *cur = _buffer + _pos; - #ifdef HASH_ARRAY_2 - UINT32 hash2Value; + UInt32 hash2Value; #ifdef HASH_ARRAY_3 - UINT32 aHash3Value; - UINT32 hashValue = Hash(aCur, hash2Value, aHash3Value); - _hash3[aHash3Value] = _pos; + UInt32 hash3Value; + UInt32 hashValue = Hash(cur, hash2Value, hash3Value); + _hash[kHash3Offset + hash3Value] = _pos; #else - UINT32 hashValue = Hash(aCur, hash2Value); + UInt32 hashValue = Hash(cur, hash2Value); #endif - _hash2[hash2Value] = _pos; - - - #else // no hash - UINT32 hashValue = Hash(aCur); + _hash[kHash2Offset + hash2Value] = _pos; + #else + UInt32 hashValue = Hash(cur); #endif - UINT32 aCurMatch = _hash[hashValue]; + _hash[kHashSizeSum + _cyclicBufferPos] = _hash[hashValue]; _hash[hashValue] = _pos; - if(aCurMatch < aMatchMinPos) - { - _chain[_cyclicBufferPos] = kEmptyHashValue; - return; - } - _chain[_cyclicBufferPos] = aCurMatch; } -void CInTree::NormalizeLinks(CIndex *anArray, UINT32 aNumItems, UINT32 aSubValue) +void CMatchFinderHC::Normalize() { - for (UINT32 i = 0; i < aNumItems; i++) + UInt32 subValue = _pos - _cyclicBufferSize; + CIndex *items = _hash; + UInt32 numItems = kHashSizeSum + _cyclicBufferSize; + for (UInt32 i = 0; i < numItems; i++) { - UINT32 aValue = anArray[i]; - if (aValue <= aSubValue) - aValue = kEmptyHashValue; + UInt32 value = items[i]; + if (value <= subValue) + value = kEmptyHashValue; else - aValue -= aSubValue; - anArray[i] = aValue; + value -= subValue; + items[i] = value; } + ReduceOffsets(subValue); } -void CInTree::Normalize() +STDMETHODIMP CMatchFinderHC::MovePos() { - UINT32 aStartItem = _pos - _historySize; - UINT32 aSubValue = aStartItem - 1; - - // NormalizeLinks(_chain + aStartItem, _historySize, aSubValue); - NormalizeLinks(_chain, _cyclicBufferSize, aSubValue); + if (++_cyclicBufferPos == _cyclicBufferSize) + _cyclicBufferPos = 0; + RINOK(CLZInWindow::MovePos()); + if (_pos == kMaxValForNormalize) + Normalize(); + return S_OK; +} - NormalizeLinks(_hash, kHashSize, aSubValue); +STDMETHODIMP_(Byte) CMatchFinderHC::GetIndexByte(Int32 index) + { return CLZInWindow::GetIndexByte(index); } - #ifdef HASH_ARRAY_2 - NormalizeLinks(_hash2, kHash2Size, aSubValue); - #ifdef HASH_ARRAY_3 - NormalizeLinks(_hash3, kHash3Size, aSubValue); - #endif - #endif +STDMETHODIMP_(UInt32) CMatchFinderHC::GetMatchLen(Int32 index, + UInt32 back, UInt32 limit) + { return CLZInWindow::GetMatchLen(index, back, limit); } + +STDMETHODIMP_(UInt32) CMatchFinderHC::GetNumAvailableBytes() + { return CLZInWindow::GetNumAvailableBytes(); } - ReduceOffsets(aSubValue); +STDMETHODIMP_(const Byte *) CMatchFinderHC::GetPointerToCurrentPos() + { return CLZInWindow::GetPointerToCurrentPos(); } + +// IMatchFinderSetCallback +STDMETHODIMP CMatchFinderHC::SetCallback(IMatchFinderCallback *callback) +{ + m_Callback = callback; + return S_OK; +} + +void CMatchFinderHC::BeforeMoveBlock() +{ + if (m_Callback) + m_Callback->BeforeChangingBufferPos(); + CLZInWindow::BeforeMoveBlock(); +} + +void CMatchFinderHC::AfterMoveBlock() +{ + if (m_Callback) + m_Callback->AfterChangingBufferPos(); + CLZInWindow::AfterMoveBlock(); } } diff --git a/7zip/Compress/LZ/IMatchFinder.h b/7zip/Compress/LZ/IMatchFinder.h index 6efa8941..bb42f60a 100755 --- a/7zip/Compress/LZ/IMatchFinder.h +++ b/7zip/Compress/LZ/IMatchFinder.h @@ -1,7 +1,5 @@ // MatchFinders/IMatchFinder.h -// #pragma once - #ifndef __IMATCHFINDER_H #define __IMATCHFINDER_H @@ -14,10 +12,10 @@ IInWindowStream: public IUnknown STDMETHOD(Init)(ISequentialInStream *inStream) PURE; STDMETHOD_(void, ReleaseStream)() PURE; STDMETHOD(MovePos)() PURE; - STDMETHOD_(BYTE, GetIndexByte)(UINT32 index) PURE; - STDMETHOD_(UINT32, GetMatchLen)(UINT32 index, UINT32 distance, UINT32 limit) PURE; - STDMETHOD_(UINT32, GetNumAvailableBytes)() PURE; - STDMETHOD_(const BYTE *, GetPointerToCurrentPos)() PURE; + STDMETHOD_(Byte, GetIndexByte)(Int32 index) PURE; + STDMETHOD_(UInt32, GetMatchLen)(Int32 index, UInt32 distance, UInt32 limit) PURE; + STDMETHOD_(UInt32, GetNumAvailableBytes)() PURE; + STDMETHOD_(const Byte *, GetPointerToCurrentPos)() PURE; }; // {23170F69-40C1-278A-0000-000200020000} @@ -26,9 +24,9 @@ DEFINE_GUID(IID_IMatchFinder, MIDL_INTERFACE("23170F69-40C1-278A-0000-000200020000") IMatchFinder: public IInWindowStream { - STDMETHOD(Create)(UINT32 historySize, UINT32 keepAddBufferBefore, - UINT32 matchMaxLen, UINT32 keepAddBufferAfter) PURE; - STDMETHOD_(UINT32, GetLongestMatch)(UINT32 *distances) PURE; + STDMETHOD(Create)(UInt32 historySize, UInt32 keepAddBufferBefore, + UInt32 matchMaxLen, UInt32 keepAddBufferAfter) PURE; + STDMETHOD_(UInt32, GetLongestMatch)(UInt32 *distances) PURE; STDMETHOD_(void, DummyLongestMatch)() PURE; }; diff --git a/7zip/Compress/LZ/LZInWindow.cpp b/7zip/Compress/LZ/LZInWindow.cpp index 817ef800..0c76788f 100755 --- a/7zip/Compress/LZ/LZInWindow.cpp +++ b/7zip/Compress/LZ/LZInWindow.cpp @@ -4,27 +4,28 @@ #include "LZInWindow.h" #include "../../../Common/MyCom.h" - -CLZInWindow::~CLZInWindow() -{ - Free(); -} +#include "../../../Common/Alloc.h" void CLZInWindow::Free() { - delete []_bufferBase; + ::BigFree(_bufferBase); _bufferBase = 0; } -void CLZInWindow::Create(UINT32 keepSizeBefore, UINT32 keepSizeAfter, UINT32 keepSizeReserv) +bool CLZInWindow::Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 keepSizeReserv) { _keepSizeBefore = keepSizeBefore; _keepSizeAfter = keepSizeAfter; _keepSizeReserv = keepSizeReserv; - _blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv; - Free(); - _bufferBase = new BYTE[_blockSize]; + UInt32 blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv; + if (_bufferBase == 0 || _blockSize != blockSize) + { + Free(); + _blockSize = blockSize; + _bufferBase = (Byte *)::BigAlloc(_blockSize); + } _pointerToLastSafePosition = _bufferBase + _blockSize - keepSizeAfter; + return (_bufferBase != 0); } @@ -64,17 +65,17 @@ HRESULT CLZInWindow::ReadBlock() return S_OK; while(true) { - UINT32 size = (_bufferBase + _blockSize) - (_buffer + _streamPos); + UInt32 size = UInt32(_bufferBase - _buffer) + _blockSize - _streamPos; if(size == 0) return S_OK; - UINT32 numReadBytes; + UInt32 numReadBytes; RINOK(_stream->ReadPart(_buffer + _streamPos, size, &numReadBytes)); if(numReadBytes == 0) { _posLimit = _streamPos; - const BYTE *pointerToPostion = _buffer + _posLimit; + const Byte *pointerToPostion = _buffer + _posLimit; if(pointerToPostion > _pointerToLastSafePosition) - _posLimit = _pointerToLastSafePosition - _buffer; + _posLimit = (UInt32)(_pointerToLastSafePosition - _buffer); _streamEndWasReached = true; return S_OK; } @@ -90,8 +91,8 @@ HRESULT CLZInWindow::ReadBlock() void CLZInWindow::MoveBlock() { BeforeMoveBlock(); - UINT32 offset = (_buffer + _pos - _keepSizeBefore) - _bufferBase; - UINT32 numBytes = (_buffer + _streamPos) - (_bufferBase + offset); + UInt32 offset = UInt32(_buffer - _bufferBase) + _pos - _keepSizeBefore; + UInt32 numBytes = UInt32(_buffer - _bufferBase) + _streamPos - offset; memmove(_bufferBase, _bufferBase + offset, numBytes); _buffer -= offset; AfterMoveBlock(); diff --git a/7zip/Compress/LZ/LZInWindow.h b/7zip/Compress/LZ/LZInWindow.h index 6ae2da16..a9cb7320 100755 --- a/7zip/Compress/LZ/LZInWindow.h +++ b/7zip/Compress/LZ/LZInWindow.h @@ -1,7 +1,5 @@ // LZInWindow.h -// #pragma once - #ifndef __LZ_IN_WINDOW_H #define __LZ_IN_WINDOW_H @@ -9,19 +7,19 @@ class CLZInWindow { - BYTE *_bufferBase; // pointer to buffer with data + Byte *_bufferBase; // pointer to buffer with data ISequentialInStream *_stream; - UINT32 _posLimit; // offset (from _buffer) of first byte when new block reading must be done + UInt32 _posLimit; // offset (from _buffer) of first byte when new block reading must be done bool _streamEndWasReached; // if (true) then _streamPos shows real end of stream - const BYTE *_pointerToLastSafePosition; + const Byte *_pointerToLastSafePosition; protected: - BYTE *_buffer; // Pointer to virtual Buffer begin - UINT32 _blockSize; // Size of Allocated memory block - UINT32 _pos; // offset (from _buffer) of curent byte - UINT32 _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos - UINT32 _keepSizeAfter; // how many BYTEs must be kept buffer after _pos - UINT32 _keepSizeReserv; // how many BYTEs must be kept as reserv - UINT32 _streamPos; // offset (from _buffer) of first not read byte from Stream + Byte *_buffer; // Pointer to virtual Buffer begin + UInt32 _blockSize; // Size of Allocated memory block + UInt32 _pos; // offset (from _buffer) of curent byte + UInt32 _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos + UInt32 _keepSizeAfter; // how many BYTEs must be kept buffer after _pos + UInt32 _keepSizeReserv; // how many BYTEs must be kept as reserv + UInt32 _streamPos; // offset (from _buffer) of first not read byte from Stream virtual void BeforeMoveBlock() {}; virtual void AfterMoveBlock() {}; @@ -30,23 +28,24 @@ protected: void Free(); public: CLZInWindow(): _bufferBase(0) {} - ~CLZInWindow(); - void Create(UINT32 keepSizeBefore, UINT32 keepSizeAfter, - UINT32 keepSizeReserv = (1<<17)); + virtual ~CLZInWindow() { Free(); } + + bool Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, + UInt32 keepSizeReserv = (1<<17)); HRESULT Init(ISequentialInStream *stream); // void ReleaseStream(); - BYTE *GetBuffer() const { return _buffer; } + Byte *GetBuffer() const { return _buffer; } - const BYTE *GetPointerToCurrentPos() const { return _buffer + _pos; } + const Byte *GetPointerToCurrentPos() const { return _buffer + _pos; } HRESULT MovePos() { _pos++; if (_pos > _posLimit) { - const BYTE *pointerToPostion = _buffer + _pos; + const Byte *pointerToPostion = _buffer + _pos; if(pointerToPostion > _pointerToLastSafePosition) MoveBlock(); return ReadBlock(); @@ -54,29 +53,25 @@ public: else return S_OK; } - // BYTE GetCurrentByte()const; - BYTE GetIndexByte(UINT32 index)const - { return _buffer[_pos + index]; } - - // UINT32 GetCurPos()const { return _pos;}; - // BYTE *GetBufferBeg()const { return _buffer;}; + Byte GetIndexByte(Int32 index)const + { return _buffer[(size_t)_pos + index]; } // index + limit have not to exceed _keepSizeAfter; - UINT32 GetMatchLen(UINT32 index, UINT32 back, UINT32 limit) const + UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit) const { if(_streamEndWasReached) if ((_pos + index) + limit > _streamPos) limit = _streamPos - (_pos + index); - back++; - BYTE *pby = _buffer + _pos + index; - UINT32 i; - for(i = 0; i < limit && pby[i] == pby[i - back]; i++); + distance++; + Byte *pby = _buffer + (size_t)_pos + index; + UInt32 i; + for(i = 0; i < limit && pby[i] == pby[(size_t)i - distance]; i++); return i; } - UINT32 GetNumAvailableBytes() const { return _streamPos - _pos; } + UInt32 GetNumAvailableBytes() const { return _streamPos - _pos; } - void ReduceOffsets(UINT32 subValue) + void ReduceOffsets(Int32 subValue) { _buffer += subValue; _posLimit -= subValue; diff --git a/7zip/Compress/LZ/LZOutWindow.cpp b/7zip/Compress/LZ/LZOutWindow.cpp index 22fb4c04..4101079b 100755 --- a/7zip/Compress/LZ/LZOutWindow.cpp +++ b/7zip/Compress/LZ/LZOutWindow.cpp @@ -2,51 +2,52 @@ #include "StdAfx.h" +#include "../../../Common/Alloc.h" #include "LZOutWindow.h" -void CLZOutWindow::Create(UINT32 windowSize) +bool CLZOutWindow::Create(UInt32 windowSize) { + const UInt32 kMinBlockSize = 1; + if (windowSize < kMinBlockSize) + windowSize = kMinBlockSize; + if (_buffer != 0 && _windowSize == windowSize) + return true; + + // It's here to allow Solid decoding / and calling Create for RAR _pos = 0; _streamPos = 0; - UINT32 newBlockSize = windowSize; - const UINT32 kMinBlockSize = 1; - if (newBlockSize < kMinBlockSize) - newBlockSize = kMinBlockSize; - if (_buffer != 0 && _windowSize == newBlockSize) - return; - delete []_buffer; - _buffer = 0; - _windowSize = newBlockSize; - _buffer = new BYTE[_windowSize]; + + Free(); + _windowSize = windowSize; + _buffer = (Byte *)::BigAlloc(windowSize); + return (_buffer != 0); } -CLZOutWindow::~CLZOutWindow() +void CLZOutWindow::Free() { - // ReleaseStream(); - delete []_buffer; + ::BigFree(_buffer); + _buffer = 0; } -/* -void CLZOutWindow::SetWindowSize(UINT32 windowSize) +void CLZOutWindow::SetStream(ISequentialOutStream *stream) { - _windowSize = windowSize; + ReleaseStream(); + _stream = stream; + _stream->AddRef(); } -*/ -void CLZOutWindow::Init(ISequentialOutStream *stream, bool solid) +void CLZOutWindow::Init(bool solid) { - // ReleaseStream(); - _stream = stream; - // _stream->AddRef(); - if(!solid) { _streamPos = 0; _pos = 0; } + #ifdef _NO_EXCEPTIONS + ErrorCode = S_OK; + #endif } -/* void CLZOutWindow::ReleaseStream() { if(_stream != 0) @@ -56,26 +57,37 @@ void CLZOutWindow::ReleaseStream() _stream = 0; } } -*/ void CLZOutWindow::FlushWithCheck() { HRESULT result = Flush(); + #ifdef _NO_EXCEPTIONS + ErrorCode = result; + #else if (result != S_OK) throw CLZOutWindowException(result); + #endif } HRESULT CLZOutWindow::Flush() { - UINT32 size = _pos - _streamPos; + UInt32 size = _pos - _streamPos; if(size == 0) return S_OK; - UINT32 processedSize; - HRESULT result = _stream->Write(_buffer + _streamPos, size, &processedSize); - if (result != S_OK) - return result; - if (size != processedSize) - return E_FAIL; + #ifdef _NO_EXCEPTIONS + if (ErrorCode != S_OK) + return ErrorCode; + #endif + + if(_stream != 0) + { + UInt32 processedSize; + HRESULT result = _stream->Write(_buffer + _streamPos, size, &processedSize); + if (result != S_OK) + return result; + if (size != processedSize) + return E_FAIL; + } if (_pos >= _windowSize) _pos = 0; _streamPos = _pos; diff --git a/7zip/Compress/LZ/LZOutWindow.h b/7zip/Compress/LZ/LZOutWindow.h index d0b392c3..e2883608 100755 --- a/7zip/Compress/LZ/LZOutWindow.h +++ b/7zip/Compress/LZ/LZOutWindow.h @@ -1,78 +1,72 @@ // LZOutWindow.h -// #pragma once - #ifndef __LZ_OUT_WINDOW_H #define __LZ_OUT_WINDOW_H #include "../../IStream.h" -// m_KeepSizeBefore: how mach BYTEs must be in buffer before _pos; -// m_KeepSizeAfter: how mach BYTEs must be in buffer after _pos; -// m_KeepSizeReserv: how mach BYTEs must be in buffer for Moving Reserv; -// must be >= aKeepSizeAfter; // test it - +#ifndef _NO_EXCEPTIONS class CLZOutWindowException { public: HRESULT ErrorCode; CLZOutWindowException(HRESULT errorCode): ErrorCode(errorCode) {} }; +#endif class CLZOutWindow { - BYTE *_buffer; - UINT32 _pos; - UINT32 _windowSize; - UINT32 _streamPos; + Byte *_buffer; + UInt32 _pos; + UInt32 _windowSize; + UInt32 _streamPos; ISequentialOutStream *_stream; void FlushWithCheck(); - public: - CLZOutWindow(): _buffer(0), _stream(0) {} - ~CLZOutWindow(); - void Create(UINT32 windowSize); - bool IsCreated() const { return _buffer != 0; } + #ifdef _NO_EXCEPTIONS + HRESULT ErrorCode; + #endif - void Init(ISequentialOutStream *stream, bool solid = false); + void Free(); + CLZOutWindow(): _buffer(0), _stream(0) {} + ~CLZOutWindow() { Free(); /* ReleaseStream(); */ } + bool Create(UInt32 windowSize); + + void SetStream(ISequentialOutStream *stream); + void Init(bool solid = false); HRESULT Flush(); - // void ReleaseStream(); + void ReleaseStream(); - // UINT32 GetCurPos() const { return _pos; } - // const BYTE *GetPointerToCurrentPos() const { return _buffer + _pos;}; - - void CopyBackBlock(UINT32 distance, UINT32 len) + void CopyBlock(UInt32 distance, UInt32 len) { - UINT32 pos = _pos - distance - 1; - if (pos >= _windowSize) - pos += _windowSize; - for(; len > 0; len--) - { - if (pos >= _windowSize) - pos = 0; - _buffer[_pos++] = _buffer[pos++]; - if (_pos >= _windowSize) - FlushWithCheck(); - // PutOneByte(GetOneByte(0 - distance)); - } + UInt32 pos = _pos - distance - 1; + if (pos >= _windowSize) + pos += _windowSize; + for(; len > 0; len--) + { + if (pos >= _windowSize) + pos = 0; + _buffer[_pos++] = _buffer[pos++]; + if (_pos >= _windowSize) + FlushWithCheck(); + // PutOneByte(GetOneByte(distance)); + } } - - void PutOneByte(BYTE b) + + void PutByte(Byte b) { - _buffer[_pos++] = b; - if (_pos >= _windowSize) - FlushWithCheck(); + _buffer[_pos++] = b; + if (_pos >= _windowSize) + FlushWithCheck(); } - - BYTE GetOneByte(UINT32 index) const + + Byte GetByte(UInt32 distance) const { - UINT32 pos = _pos + index; - if (pos >= _windowSize) - pos += _windowSize; - return _buffer[pos]; + UInt32 pos = _pos - distance - 1; + if (pos >= _windowSize) + pos += _windowSize; + return _buffer[pos]; } - - // BYTE *GetBuffer() const { return _buffer; } }; #endif diff --git a/7zip/Compress/LZ/MT/MT.cpp b/7zip/Compress/LZ/MT/MT.cpp index 5fb76738..7e05135d 100755 --- a/7zip/Compress/LZ/MT/MT.cpp +++ b/7zip/Compress/LZ/MT/MT.cpp @@ -1,7 +1,9 @@ -// MT_MF.cpp +// MT.cpp #include "StdAfx.h" +#include "../../../../Common/Alloc.h" + #include "MT.h" class CMatchFinderCallback: @@ -14,7 +16,7 @@ class CMatchFinderCallback: STDMETHOD(AfterChangingBufferPos)(); public: CMatchFinderMT *m_MatchFinderMT; - const BYTE *m_BufferPosBefore; + const Byte *m_BufferPosBefore; }; STDMETHODIMP CMatchFinderCallback::BeforeChangingBufferPos() @@ -33,11 +35,11 @@ STDMETHODIMP CMatchFinderCallback::AfterChangingBufferPos() return S_OK; } -HRESULT CMatchFinderMT::SetMatchFinder(IMatchFinder *aMatchFinder, - UINT32 multiThreadMult) +HRESULT CMatchFinderMT::SetMatchFinder(IMatchFinder *matchFinder, + UInt32 multiThreadMult) { _multiThreadMult = multiThreadMult; - m_MatchFinder = aMatchFinder; + m_MatchFinder = matchFinder; CMyComPtr<IMatchFinderSetCallback> matchFinderSetCallback; if (m_MatchFinder.QueryInterface(IID_IMatchFinderSetCallback, &matchFinderSetCallback) == S_OK) @@ -54,69 +56,63 @@ HRESULT CMatchFinderMT::SetMatchFinder(IMatchFinder *aMatchFinder, } -STDMETHODIMP CMatchFinderMT::Init(ISequentialInStream *aStream) +STDMETHODIMP CMatchFinderMT::Init(ISequentialInStream *s) { - // OutputDebugString("Init\n"); m_AskChangeBufferPos.Reset(); m_CanChangeBufferPos.Reset(); m_BufferPosWasChanged.Reset(); m_StopWriting.Reset(); m_WritingWasStopped.Reset(); m_NeedStart = true; - HRESULT aResult = m_MatchFinder->Init(aStream); - if (aResult == S_OK) + m_CurrentPos = 0; + m_CurrentLimitPos = 0; + + HRESULT result = m_MatchFinder->Init(s); + if (result == S_OK) m_DataCurrentPos = m_MatchFinder->GetPointerToCurrentPos(); - return aResult; + return result; } STDMETHODIMP_(void) CMatchFinderMT::ReleaseStream() { - // OutputDebugString("ReleaseStream\n"); m_StopWriting.Set(); m_WritingWasStopped.Lock(); - // OutputDebugString("m_WritingWasStopped\n"); m_MatchFinder->ReleaseStream(); } STDMETHODIMP CMatchFinderMT::MovePos() { + if (m_Result != S_OK) + return m_Result; m_NumAvailableBytesCurrent--; m_DataCurrentPos++; return S_OK; } -STDMETHODIMP_(BYTE) CMatchFinderMT::GetIndexByte(UINT32 anIndex) +STDMETHODIMP_(Byte) CMatchFinderMT::GetIndexByte(Int32 index) { - return m_DataCurrentPos[anIndex]; + return m_DataCurrentPos[index]; } -STDMETHODIMP_(UINT32) CMatchFinderMT::GetMatchLen(UINT32 aIndex, - UINT32 aBack, UINT32 aLimit) +STDMETHODIMP_(UInt32) CMatchFinderMT::GetMatchLen(Int32 index, + UInt32 distance, UInt32 limit) { - if (int(aIndex + aLimit) > m_NumAvailableBytesCurrent) - aLimit = m_NumAvailableBytesCurrent - (aIndex); - aBack++; - const BYTE *pby = m_DataCurrentPos + aIndex; - UINT32 i; - for(i = 0; i < aLimit && pby[i] == pby[i - aBack]; i++); - /* - - char aSz[100]; - sprintf(aSz, "GetMatchLen = %d", i); - OutputDebugString(aSz); - OutputDebugString("\n"); - */ + if (int(index + limit) > m_NumAvailableBytesCurrent) + limit = m_NumAvailableBytesCurrent - (index); + distance++; + const Byte *pby = m_DataCurrentPos + index; + UInt32 i; + for(i = 0; i < limit && pby[i] == pby[i - distance]; i++); return i; - // return m_MatchFinder->GetMatchLen(aIndex, aBack, aLimit); } } -STDMETHODIMP_(const BYTE *) CMatchFinderMT::GetPointerToCurrentPos() +STDMETHODIMP_(const Byte *) CMatchFinderMT::GetPointerToCurrentPos() { return m_DataCurrentPos; } -STDMETHODIMP_(UINT32) CMatchFinderMT::GetNumAvailableBytes() +STDMETHODIMP_(UInt32) CMatchFinderMT::GetNumAvailableBytes() { if (m_NeedStart) return m_MatchFinder->GetNumAvailableBytes(); @@ -126,93 +122,110 @@ STDMETHODIMP_(UINT32) CMatchFinderMT::GetNumAvailableBytes() void CMatchFinderMT::FreeMem() { - delete []m_Buffer; + MyFree(m_Buffer); + MyFree(m_DummyBuffer); } -STDMETHODIMP CMatchFinderMT::Create(UINT32 aSizeHistory, - UINT32 aKeepAddBufferBefore, UINT32 matchMaxLen, - UINT32 aKeepAddBufferAfter) +STDMETHODIMP CMatchFinderMT::Create(UInt32 sizeHistory, + UInt32 keepAddBufferBefore, UInt32 matchMaxLen, + UInt32 keepAddBufferAfter) { FreeMem(); m_MatchMaxLen = matchMaxLen; m_BlockSize = (matchMaxLen + 1) * _multiThreadMult; - UINT32 aBufferSize = m_BlockSize * kNumMTBlocks; - m_Buffer = new UINT32[aBufferSize]; + UInt32 bufferSize = m_BlockSize * kNumMTBlocks; + m_DummyBuffer = (UInt32 *)MyAlloc((matchMaxLen + 1) * sizeof(UInt32)); + if (m_DummyBuffer == 0) + return E_OUTOFMEMORY; + m_Buffer = (UInt32 *)MyAlloc(bufferSize * sizeof(UInt32)); + if (m_Buffer == 0) + return E_OUTOFMEMORY; for (int i = 0; i < kNumMTBlocks; i++) m_Buffers[i] = &m_Buffer[i * m_BlockSize]; m_NeedStart = true; + m_CurrentPos = 0; + m_CurrentLimitPos = 0; - aKeepAddBufferBefore += aBufferSize; + keepAddBufferBefore += bufferSize; - return m_MatchFinder->Create(aSizeHistory, - aKeepAddBufferBefore, matchMaxLen, - aKeepAddBufferAfter); + return m_MatchFinder->Create(sizeHistory, keepAddBufferBefore, matchMaxLen, + keepAddBufferAfter); } -static DWORD WINAPI MFThread(void *aThreadCoderInfo) +static DWORD WINAPI MFThread(void *threadCoderInfo) { - CMatchFinderMT &aMT = *(CMatchFinderMT *)aThreadCoderInfo; + CMatchFinderMT &mt = *(CMatchFinderMT *)threadCoderInfo; + return mt.ThreadFunc(); +} + +DWORD CMatchFinderMT::ThreadFunc() +{ + bool errorMode = false; while (true) { - HANDLE anEvents[3] = { aMT.m_ExitEvent, aMT.m_StopWriting, aMT.m_CanWriteEvents[aMT.m_WriteBufferIndex] } ; - DWORD anWaitResult = ::WaitForMultipleObjects(3, anEvents, FALSE, INFINITE); - if (anWaitResult == WAIT_OBJECT_0 + 0) + HANDLE events[3] = { m_ExitEvent, m_StopWriting, m_CanWriteEvents[m_WriteBufferIndex] } ; + DWORD waitResult = ::WaitForMultipleObjects((errorMode ? 2: 3), events, FALSE, INFINITE); + if (waitResult == WAIT_OBJECT_0 + 0) return 0; - if (anWaitResult == WAIT_OBJECT_0 + 1) + if (waitResult == WAIT_OBJECT_0 + 1) { - // OutputDebugString("m_StopWriting\n"); - aMT.m_WriteBufferIndex = 0; + m_WriteBufferIndex = 0; for (int i = 0; i < kNumMTBlocks; i++) - aMT.m_CanWriteEvents[i].Reset(); - aMT.m_WritingWasStopped.Set(); + m_CanWriteEvents[i].Reset(); + m_WritingWasStopped.Set(); + errorMode = false; continue; } - // OutputDebugString("m_CanWriteEvents\n"); - UINT32 *aBuffer = aMT.m_Buffers[aMT.m_WriteBufferIndex]; - UINT32 aCurPos = 0; - UINT32 aNumBytes = 0; - while (aCurPos + aMT.m_MatchMaxLen + 1 <= aMT.m_BlockSize) + if (errorMode) + { + // this case means bug_in_program. So just exit; + return 1; + } + + m_Results[m_WriteBufferIndex] = S_OK; + UInt32 *buffer = m_Buffers[m_WriteBufferIndex]; + UInt32 curPos = 0; + UInt32 numBytes = 0; + UInt32 limit = m_BlockSize - m_MatchMaxLen; + IMatchFinder *mf = m_MatchFinder; + do { - if (aMT.m_MatchFinder->GetNumAvailableBytes() == 0) + if (mf->GetNumAvailableBytes() == 0) break; - UINT32 aLen = aMT.m_MatchFinder->GetLongestMatch(aBuffer + aCurPos); + UInt32 len = mf->GetLongestMatch(buffer + curPos); /* - if (aLen == 1) - aLen = 0; + if (len == 1) + len = 0; */ - aBuffer[aCurPos] = aLen; - aCurPos += aLen + 1; - HRESULT aResult = aMT.m_MatchFinder->MovePos(); - if (aResult != S_OK) - throw 124459; - aNumBytes++; + buffer[curPos] = len; + curPos += len + 1; + numBytes++; + HRESULT result = mf->MovePos(); + if (result != S_OK) + { + m_Results[m_WriteBufferIndex] = result; + errorMode = true; + break; + } } - aMT.m_LimitPos[aMT.m_WriteBufferIndex] = aCurPos; - aMT.m_NumAvailableBytes[aMT.m_WriteBufferIndex] = - aNumBytes + aMT.m_MatchFinder->GetNumAvailableBytes(); - // char aSz[100]; - // sprintf(aSz, "x = %d", aMT.m_WriteBufferIndex); - // OutputDebugString(aSz); - // OutputDebugString("aMT.m_CanReadEvents\n"); - aMT.m_CanReadEvents[aMT.m_WriteBufferIndex].Set(); - aMT.m_WriteBufferIndex++; - if (aMT.m_WriteBufferIndex == kNumMTBlocks) - aMT.m_WriteBufferIndex = 0; + while (curPos < limit); + m_LimitPos[m_WriteBufferIndex] = curPos; + if (errorMode) + m_NumAvailableBytes[m_WriteBufferIndex] = numBytes; + else + m_NumAvailableBytes[m_WriteBufferIndex] = numBytes + + mf->GetNumAvailableBytes(); + m_CanReadEvents[m_WriteBufferIndex].Set(); + if (++m_WriteBufferIndex == kNumMTBlocks) + m_WriteBufferIndex = 0; } - - /* - while(true) - { - if (!((CCoderMixer2 *)aThreadCoderInfo)->MyCode()) - return 0; - } - */ } CMatchFinderMT::CMatchFinderMT(): m_Buffer(0), + m_DummyBuffer(0), _multiThreadMult(100) { for (int i = 0; i < kNumMTBlocks; i++) @@ -227,17 +240,16 @@ CMatchFinderMT::CMatchFinderMT(): if (!m_Thread.Create(MFThread, this)) throw 271826; } + CMatchFinderMT::~CMatchFinderMT() { m_ExitEvent.Set(); - if (HANDLE(m_Thread) != 0) - ::WaitForSingleObject(m_Thread, INFINITE); + m_Thread.Wait(); FreeMem(); } void CMatchFinderMT::Start() { - // OutputDebugString("Start\n"); m_AskChangeBufferPos.Reset(); m_CanChangeBufferPos.Reset(); m_BufferPosWasChanged.Reset(); @@ -247,6 +259,7 @@ void CMatchFinderMT::Start() m_NeedStart = false; m_CurrentPos = 0; m_CurrentLimitPos = 0; + m_Result = S_OK; int i; for (i = 0; i < kNumMTBlocks; i++) m_CanReadEvents[i].Reset(); @@ -254,29 +267,17 @@ void CMatchFinderMT::Start() m_CanWriteEvents[i].Set(); } -STDMETHODIMP_(UINT32) CMatchFinderMT::GetLongestMatch(UINT32 *aDistances) +STDMETHODIMP_(UInt32) CMatchFinderMT::GetLongestMatch(UInt32 *distances) { - // OutputDebugString("GetLongestMatch\n"); - if (m_NeedStart) - Start(); - /* - if (m_CurrentPos > m_CurrentLimitPos) - throw 1123324; - */ if (m_CurrentPos == m_CurrentLimitPos) { - // OutputDebugString("m_CurrentPos == m_CurrentLimitPos\n"); + if (m_NeedStart) + Start(); while (true) { - /* - char aSz[100]; - sprintf(aSz, "m_CanReadEvents[m_ReadBufferIndex] = %d\n", m_ReadBufferIndex); - OutputDebugString(aSz); - OutputDebugString("\n"); - */ - HANDLE anEvents[2] = { m_AskChangeBufferPos, m_CanReadEvents[m_ReadBufferIndex] } ; - DWORD anWaitResult = ::WaitForMultipleObjects(2, anEvents, FALSE, INFINITE); - if (anWaitResult == WAIT_OBJECT_0 + 1) + HANDLE events[2] = { m_AskChangeBufferPos, m_CanReadEvents[m_ReadBufferIndex] } ; + DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE); + if (waitResult == WAIT_OBJECT_0 + 1) break; m_BufferPosWasChanged.Reset(); m_CanChangeBufferPos.Set(); @@ -286,32 +287,26 @@ STDMETHODIMP_(UINT32) CMatchFinderMT::GetLongestMatch(UINT32 *aDistances) m_CurrentLimitPos = m_LimitPos[m_ReadBufferIndex]; m_NumAvailableBytesCurrent = m_NumAvailableBytes[m_ReadBufferIndex]; m_CurrentPos = 0; + m_Result = m_Results[m_ReadBufferIndex]; } + /* if (m_CurrentPos >= m_CurrentLimitPos) throw 1123324; - const UINT32 *aBuffer = m_Buffers[m_ReadBufferIndex]; - UINT32 aLen = aBuffer[m_CurrentPos++]; - for (UINT32 i = 1; i <= aLen; i++) - aDistances[i] = aBuffer[m_CurrentPos++]; + */ + const UInt32 *buffer = m_Buffers[m_ReadBufferIndex]; + UInt32 len = buffer[m_CurrentPos++]; + for (UInt32 i = 1; i <= len; i++) + distances[i] = buffer[m_CurrentPos++]; if (m_CurrentPos == m_CurrentLimitPos) { m_CanWriteEvents[m_ReadBufferIndex].Set(); - m_ReadBufferIndex++; - if (m_ReadBufferIndex == kNumMTBlocks) + if (++m_ReadBufferIndex == kNumMTBlocks) m_ReadBufferIndex = 0; } - // char aSz[100]; - // sprintf(aSz, "m_NumAvailableBytesCurrent = %d", m_NumAvailableBytesCurrent); - // OutputDebugString(aSz); - // OutputDebugString("\n"); - return aLen; + return len; } STDMETHODIMP_(void) CMatchFinderMT::DummyLongestMatch() { - UINT32 aBuffer[512]; - GetLongestMatch(aBuffer); - // m_MatchFinder->DummyLongestMatch(); + GetLongestMatch(m_DummyBuffer); } - - diff --git a/7zip/Compress/LZ/MT/MT.h b/7zip/Compress/LZ/MT/MT.h index 40b140ff..e4035a6f 100755 --- a/7zip/Compress/LZ/MT/MT.h +++ b/7zip/Compress/LZ/MT/MT.h @@ -1,14 +1,12 @@ -// MT_MF.h +// LZ/MT.h -#pragma once +#ifndef __LZ_MT_H +#define __LZ_MT_H -#ifndef __MT_MF_H -#define __MT_MF_H +#include "../../../../Common/MyCom.h" -#include "Common/MyCom.h" - -#include "Windows/Thread.h" -#include "Windows/Synchronization.h" +#include "../../../../Windows/Thread.h" +#include "../../../../Windows/Synchronization.h" #include "../../../ICoder.h" #include "../IMatchFinder.h" @@ -21,65 +19,65 @@ class CMatchFinderMT: { MY_UNKNOWN_IMP - STDMETHOD(Init)(ISequentialInStream *aStream); + STDMETHOD(Init)(ISequentialInStream *s); STDMETHOD_(void, ReleaseStream)(); STDMETHOD(MovePos)(); - STDMETHOD_(BYTE, GetIndexByte)(UINT32 anIndex); - STDMETHOD_(UINT32, GetMatchLen)(UINT32 aIndex, UINT32 aBack, UINT32 aLimit); - STDMETHOD_(UINT32, GetNumAvailableBytes)(); - STDMETHOD_(const BYTE *, GetPointerToCurrentPos)(); - STDMETHOD(Create)(UINT32 aSizeHistory, - UINT32 aKeepAddBufferBefore, UINT32 aMatchMaxLen, - UINT32 aKeepAddBufferAfter); - STDMETHOD_(UINT32, GetLongestMatch)(UINT32 *aDistances); + STDMETHOD_(Byte, GetIndexByte)(Int32 index); + STDMETHOD_(UInt32, GetMatchLen)(Int32 index, UInt32 distance, UInt32 limit); + STDMETHOD_(UInt32, GetNumAvailableBytes)(); + STDMETHOD_(const Byte *, GetPointerToCurrentPos)(); + STDMETHOD(Create)(UInt32 sizeHistory, + UInt32 keepAddBufferBefore, UInt32 matchMaxLen, + UInt32 keepAddBufferAfter); + STDMETHOD_(UInt32, GetLongestMatch)(UInt32 *distances); STDMETHOD_(void, DummyLongestMatch)(); -private: -public: - CMyComPtr<IMatchFinder> m_MatchFinder; - UINT32 m_MatchMaxLen; + UInt32 m_CurrentPos; + UInt32 m_CurrentLimitPos; + UInt32 m_MatchMaxLen; - UINT32 m_BlockSize; - // UINT32 m_BufferSize; - UINT32 *m_Buffer; - UINT32 *m_Buffers[kNumMTBlocks]; + UInt32 m_BlockSize; + UInt32 *m_Buffer; + UInt32 *m_Buffers[kNumMTBlocks]; + UInt32 *m_DummyBuffer; bool m_NeedStart; - UINT32 m_WriteBufferIndex; - UINT32 m_ReadBufferIndex; + UInt32 m_WriteBufferIndex; + UInt32 m_ReadBufferIndex; NWindows::NSynchronization::CAutoResetEvent m_StopWriting; NWindows::NSynchronization::CAutoResetEvent m_WritingWasStopped; - NWindows::NSynchronization::CAutoResetEvent m_AskChangeBufferPos; - NWindows::NSynchronization::CAutoResetEvent m_CanChangeBufferPos; - NWindows::NSynchronization::CAutoResetEvent m_BufferPosWasChanged; - NWindows::NSynchronization::CManualResetEvent m_ExitEvent; - // NWindows::NSynchronization::CManualResetEvent m_NewStart; NWindows::NSynchronization::CAutoResetEvent m_CanReadEvents[kNumMTBlocks]; NWindows::NSynchronization::CAutoResetEvent m_CanWriteEvents[kNumMTBlocks]; - UINT32 m_LimitPos[kNumMTBlocks]; - UINT32 m_NumAvailableBytes[kNumMTBlocks]; + HRESULT m_Results[kNumMTBlocks]; - UINT32 m_NumAvailableBytesCurrent; - const BYTE *m_DataCurrentPos; - - UINT32 m_CurrentLimitPos; - UINT32 m_CurrentPos; + UInt32 m_LimitPos[kNumMTBlocks]; + UInt32 m_NumAvailableBytes[kNumMTBlocks]; + UInt32 m_NumAvailableBytesCurrent; + NWindows::CThread m_Thread; - // bool m_WriteWasClosed; - UINT32 _multiThreadMult; + UInt32 _multiThreadMult; + + HRESULT m_Result; + + void Start(); + void FreeMem(); + public: + NWindows::NSynchronization::CAutoResetEvent m_AskChangeBufferPos; + NWindows::NSynchronization::CAutoResetEvent m_CanChangeBufferPos; + NWindows::NSynchronization::CAutoResetEvent m_BufferPosWasChanged; + CMyComPtr<IMatchFinder> m_MatchFinder; + const Byte *m_DataCurrentPos; + + DWORD ThreadFunc(); + CMatchFinderMT(); ~CMatchFinderMT(); - void Start(); - void FreeMem(); - HRESULT SetMatchFinder(IMatchFinder *aMatchFinder, - UINT32 multiThreadMult = 200); + HRESULT SetMatchFinder(IMatchFinder *matchFinder, UInt32 multiThreadMult = 200); }; - #endif - diff --git a/7zip/Compress/LZ/MT/StdAfx.h b/7zip/Compress/LZ/MT/StdAfx.h index a32fbed6..a2f1e97b 100755 --- a/7zip/Compress/LZ/MT/StdAfx.h +++ b/7zip/Compress/LZ/MT/StdAfx.h @@ -1,8 +1,8 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> +#include "../../../../Common/MyWindows.h" -#endif +#endif diff --git a/7zip/Compress/LZ/Patricia/Pat.h b/7zip/Compress/LZ/Patricia/Pat.h index 50acb686..f2eae09e 100755 --- a/7zip/Compress/LZ/Patricia/Pat.h +++ b/7zip/Compress/LZ/Patricia/Pat.h @@ -1,12 +1,10 @@ // Pat.h -// #pragma once - // #ifndef __PATRICIA__H // #define __PATRICIA__H -#include "../../../../Common/AlignedBuffer.h" #include "../../../../Common/MyCom.h" +#include "../../../../Common/Types.h" #include "../LZInWindow.h" namespace PAT_NAMESPACE { @@ -15,13 +13,8 @@ struct CNode; typedef CNode *CNodePointer; -#pragma pack(push, PragmaPatrTree) -#pragma pack(push, 1) - // #define __AUTO_REMOVE -// #define __USE_3_BYTES - // #define __NODE_4_BITS // #define __NODE_3_BITS // #define __NODE_2_BITS @@ -30,55 +23,32 @@ typedef CNode *CNodePointer; // #define __HASH_3 -#ifdef __USE_3_BYTES -struct CIndex -{ - BYTE Data[3]; - operator =(UINT32 aValue) - { - Data[0] = aValue & 0xFF; - Data[1] = (aValue >> 8) & 0xFF; - Data[2] = (aValue >> 16) & 0xFF; - } - operator UINT32() const { return (*((const UINT32 *)Data)) & 0xFFFFFF; } -}; -#else - typedef UINT32 CIndex; -#endif - - -#pragma pack(pop) -#pragma pack(pop, PragmaPatrTree) +typedef UInt32 CIndex; #ifdef __NODE_4_BITS - typedef UINT32 CIndex2; - typedef UINT32 CSameBitsType; + typedef UInt32 CIndex2; + typedef UInt32 CSameBitsType; #else #ifdef __NODE_3_BITS - typedef UINT32 CIndex2; - typedef UINT32 CSameBitsType; + typedef UInt32 CIndex2; + typedef UInt32 CSameBitsType; #else - #ifdef __USE_3_BYTES - typedef BYTE CSameBitsType; - #else - typedef UINT32 CIndex; - typedef UINT32 CSameBitsType; - #endif + typedef UInt32 CIndex; + typedef UInt32 CSameBitsType; typedef CIndex CIndex2; #endif #endif -const UINT32 kNumBitsInIndex = sizeof(CIndex) * 8; -const UINT32 kMatchStartValue = UINT32(1) << (kNumBitsInIndex - 1); +const UInt32 kNumBitsInIndex = sizeof(CIndex) * 8; +const UInt32 kMatchStartValue = UInt32(1) << (kNumBitsInIndex - 1); +// don't change kMatchStartValue definition, since it is used in +// PatMain.h: typedef CIndex CMatchPointer; -const UINT32 kDescendantEmptyValue = kMatchStartValue - 1; - -#pragma pack(push, PragmaPatrTree2) -#pragma pack(push, 1) +const UInt32 kDescendantEmptyValue = kMatchStartValue - 1; union CDescendant { @@ -90,33 +60,27 @@ union CDescendant void MakeEmpty() { NodePointer = kDescendantEmptyValue; } }; -#pragma pack(pop) -#pragma pack(pop, PragmaPatrTree2) - -#pragma pack( push, PragmaBackNode) -#pragma pack( push, 1) - #undef MY_BYTE_SIZE #ifdef __NODE_4_BITS #define MY_BYTE_SIZE 8 - const UINT32 kNumSubBits = 4; + const UInt32 kNumSubBits = 4; #else #ifdef __NODE_3_BITS #define MY_BYTE_SIZE 9 - const UINT32 kNumSubBits = 3; + const UInt32 kNumSubBits = 3; #else #define MY_BYTE_SIZE 8 #ifdef __NODE_2_BITS - const UINT32 kNumSubBits = 2; + const UInt32 kNumSubBits = 2; #else - const UINT32 kNumSubBits = 1; + const UInt32 kNumSubBits = 1; #endif #endif #endif -const UINT32 kNumSubNodes = 1 << kNumSubBits; -const UINT32 kSubNodesMask = kNumSubNodes - 1; +const UInt32 kNumSubNodes = 1 << kNumSubBits; +const UInt32 kSubNodesMask = kNumSubNodes - 1; struct CNode { @@ -125,18 +89,15 @@ struct CNode union { CDescendant Descendants[kNumSubNodes]; - UINT32 NextFreeNode; + UInt32 NextFreeNode; }; #ifdef __NODE_2_BITS #ifdef __NODE_2_BITS_PADDING - UINT32 Padding[2]; + UInt32 Padding[2]; #endif #endif }; -#pragma pack(pop) -#pragma pack(pop, PragmaBackNode) - #undef kIDNumBitsByte #undef kIDNumBitsString @@ -183,13 +144,8 @@ struct CNode #undef kIDUse3BytesByte #undef kIDUse3BytesString -#ifdef __USE_3_BYTES - #define kIDUse3BytesByte 0x02 - #define kIDUse3BytesString TEXT("T") -#else - #define kIDUse3BytesByte 0x00 - #define kIDUse3BytesString TEXT("") -#endif +#define kIDUse3BytesByte 0x00 +#define kIDUse3BytesString TEXT("") #undef kIDPaddingByte #undef kIDPaddingString @@ -227,23 +183,23 @@ class CPatricia: STDMETHOD(Init)(ISequentialInStream *aStream); STDMETHOD_(void, ReleaseStream)(); STDMETHOD(MovePos)(); - STDMETHOD_(BYTE, GetIndexByte)(UINT32 anIndex); - STDMETHOD_(UINT32, GetMatchLen)(UINT32 aIndex, UINT32 aBack, UINT32 aLimit); - STDMETHOD_(UINT32, GetNumAvailableBytes)(); - STDMETHOD(Create)(UINT32 aSizeHistory, - UINT32 aKeepAddBufferBefore, UINT32 aMatchMaxLen, - UINT32 aKeepAddBufferAfter); - STDMETHOD_(UINT32, GetLongestMatch)(UINT32 *aDistances); + STDMETHOD_(Byte, GetIndexByte)(Int32 index); + STDMETHOD_(UInt32, GetMatchLen)(Int32 index, UInt32 back, UInt32 limit); + STDMETHOD_(UInt32, GetNumAvailableBytes)(); + STDMETHOD(Create)(UInt32 historySize, + UInt32 keepAddBufferBefore, UInt32 matchMaxLen, + UInt32 keepAddBufferAfter); + STDMETHOD_(UInt32, GetLongestMatch)(UInt32 *distances); STDMETHOD_(void, DummyLongestMatch)(); - STDMETHOD_(const BYTE *, GetPointerToCurrentPos)(); + STDMETHOD_(const Byte *, GetPointerToCurrentPos)(); void FreeMemory(); public: CPatricia(); ~CPatricia(); - UINT32 _sizeHistory; - UINT32 _matchMaxLen; + UInt32 _sizeHistory; + UInt32 _matchMaxLen; CDescendant *m_HashDescendants; #ifdef __HASH_3 @@ -252,21 +208,19 @@ public: CNode *m_Nodes; - UINT32 m_FreeNode; - UINT32 m_FreeNodeMax; + UInt32 m_FreeNode; + UInt32 m_FreeNodeMax; #ifdef __AUTO_REMOVE - UINT32 m_NumUsedNodes; - UINT32 m_NumNodes; + UInt32 m_NumUsedNodes; + UInt32 m_NumNodes; #else bool m_SpecialRemoveMode; #endif bool m_SpecialMode; - UINT32 m_NumNotChangedCycles; - UINT32 *m_TmpBacks; - - CAlignedBuffer m_AlignBuffer; + UInt32 m_NumNotChangedCycles; + UInt32 *m_TmpBacks; CMyComPtr<IMatchFinderCallback> m_Callback; @@ -274,25 +228,25 @@ public: virtual void AfterMoveBlock(); // IMatchFinderSetCallback - STDMETHOD(SetCallback)(IMatchFinderCallback *aCallback); + STDMETHOD(SetCallback)(IMatchFinderCallback *callback); - void ChangeLastMatch(UINT32 aHashValue); + void ChangeLastMatch(UInt32 hashValue); #ifdef __AUTO_REMOVE - void TestRemoveDescendant(CDescendant &aDescendant, UINT32 aLimitPos); + void TestRemoveDescendant(CDescendant &descendant, UInt32 limitPos); void TestRemoveNodes(); - void RemoveNode(UINT32 anIndex); - void TestRemoveAndNormalizeDescendant(CDescendant &aDescendant, - UINT32 aLimitPos, UINT32 aSubValue); + void RemoveNode(UInt32 index); + void TestRemoveAndNormalizeDescendant(CDescendant &descendant, + UInt32 limitPos, UInt32 subValue); void TestRemoveNodesAndNormalize(); #else - void NormalizeDescendant(CDescendant &aDescendant, UINT32 aSubValue); + void NormalizeDescendant(CDescendant &descendant, UInt32 subValue); void Normalize(); void RemoveMatch(); #endif private: void AddInternalNode(CNodePointer aNode, CIndex *aNodePointerPointer, - BYTE aByte, BYTE aByteXOR, UINT32 aNumSameBits, UINT32 aPos) + Byte aByte, Byte aByteXOR, UInt32 aNumSameBits, UInt32 aPos) { while((aByteXOR & kSubNodesMask) == 0) { @@ -302,7 +256,7 @@ private: } // Insert New Node CNodePointer aNewNode = &m_Nodes[m_FreeNode]; - UINT32 aNodeIndex = *aNodePointerPointer; + UInt32 aNodeIndex = *aNodePointerPointer; *aNodePointerPointer = m_FreeNode; m_FreeNode = aNewNode->NextFreeNode; #ifdef __AUTO_REMOVE @@ -314,9 +268,9 @@ private: m_Nodes[m_FreeNode].NextFreeNode = m_FreeNode + 1; } - UINT32 aBitsNew = aByte & kSubNodesMask; - UINT32 aBitsOld = (aByte ^ aByteXOR) & kSubNodesMask; - for (UINT32 i = 0; i < kNumSubNodes; i++) + UInt32 aBitsNew = aByte & kSubNodesMask; + UInt32 aBitsOld = (aByte ^ aByteXOR) & kSubNodesMask; + for (UInt32 i = 0; i < kNumSubNodes; i++) aNewNode->Descendants[i].NodePointer = kDescendantEmptyValue; aNewNode->Descendants[aBitsNew].MatchPointer = aPos + kMatchStartValue; aNewNode->Descendants[aBitsOld].NodePointer = aNodeIndex; @@ -326,15 +280,15 @@ private: aNode->NumSameBits = CSameBitsType(aNumSameBits - kNumSubBits); } - void AddLeafNode(CNodePointer aNode, BYTE aByte, BYTE aByteXOR, - UINT32 aNumSameBits, UINT32 aPos, UINT32 aDescendantIndex) + void AddLeafNode(CNodePointer aNode, Byte aByte, Byte aByteXOR, + UInt32 aNumSameBits, UInt32 aPos, UInt32 aDescendantIndex) { for(;(aByteXOR & kSubNodesMask) == 0; aNumSameBits += kNumSubBits) { aByte >>= kNumSubBits; aByteXOR >>= kNumSubBits; } - UINT32 aNewNodeIndex = m_FreeNode; + UInt32 aNewNodeIndex = m_FreeNode; CNodePointer aNewNode = &m_Nodes[m_FreeNode]; m_FreeNode = aNewNode->NextFreeNode; #ifdef __AUTO_REMOVE @@ -346,9 +300,9 @@ private: m_Nodes[m_FreeNode].NextFreeNode = m_FreeNode + 1; } - UINT32 aBitsNew = (aByte & kSubNodesMask); - UINT32 aBitsOld = (aByte ^ aByteXOR) & kSubNodesMask; - for (UINT32 i = 0; i < kNumSubNodes; i++) + UInt32 aBitsNew = (aByte & kSubNodesMask); + UInt32 aBitsOld = (aByte ^ aByteXOR) & kSubNodesMask; + for (UInt32 i = 0; i < kNumSubNodes; i++) aNewNode->Descendants[i].NodePointer = kDescendantEmptyValue; aNewNode->Descendants[aBitsNew].MatchPointer = aPos + kMatchStartValue; aNewNode->Descendants[aBitsOld].MatchPointer = diff --git a/7zip/Compress/LZ/Patricia/Pat2.h b/7zip/Compress/LZ/Patricia/Pat2.h index df25f0c7..23b3caea 100755 --- a/7zip/Compress/LZ/Patricia/Pat2.h +++ b/7zip/Compress/LZ/Patricia/Pat2.h @@ -1,7 +1,5 @@ // Pat2.h -#pragma once - #ifndef __PAT2__H #define __PAT2__H diff --git a/7zip/Compress/LZ/Patricia/Pat2H.h b/7zip/Compress/LZ/Patricia/Pat2H.h index 51f5180f..dd3963df 100755 --- a/7zip/Compress/LZ/Patricia/Pat2H.h +++ b/7zip/Compress/LZ/Patricia/Pat2H.h @@ -1,7 +1,5 @@ // Pat2H.h -#pragma once - #ifndef __PAT2H__H #define __PAT2H__H diff --git a/7zip/Compress/LZ/Patricia/Pat2R.h b/7zip/Compress/LZ/Patricia/Pat2R.h index f6af9191..d2d291c8 100755 --- a/7zip/Compress/LZ/Patricia/Pat2R.h +++ b/7zip/Compress/LZ/Patricia/Pat2R.h @@ -1,7 +1,5 @@ // Pat2R.h -#pragma once - #ifndef __PAT2R__H #define __PAT2R__H diff --git a/7zip/Compress/LZ/Patricia/Pat3H.h b/7zip/Compress/LZ/Patricia/Pat3H.h index 170ebf6b..0f1d6aab 100755 --- a/7zip/Compress/LZ/Patricia/Pat3H.h +++ b/7zip/Compress/LZ/Patricia/Pat3H.h @@ -1,7 +1,5 @@ // Pat3H.h -#pragma once - #ifndef __PAT3H__H #define __PAT3H__H diff --git a/7zip/Compress/LZ/Patricia/Pat4H.h b/7zip/Compress/LZ/Patricia/Pat4H.h index 15fa2bc2..9d8dc799 100755 --- a/7zip/Compress/LZ/Patricia/Pat4H.h +++ b/7zip/Compress/LZ/Patricia/Pat4H.h @@ -1,7 +1,5 @@ // Pat4H.h -#pragma once - #ifndef __PAT4H__H #define __PAT4H__H diff --git a/7zip/Compress/LZ/Patricia/PatMain.h b/7zip/Compress/LZ/Patricia/PatMain.h index 2b75341e..949f6054 100755 --- a/7zip/Compress/LZ/Patricia/PatMain.h +++ b/7zip/Compress/LZ/Patricia/PatMain.h @@ -1,13 +1,13 @@ // PatMain.h #include "../../../../Common/Defs.h" -#include "../../../../Common/NewHandler.h" +#include "../../../../Common/Alloc.h" namespace PAT_NAMESPACE { -STDMETHODIMP CPatricia::SetCallback(IMatchFinderCallback *aCallback) +STDMETHODIMP CPatricia::SetCallback(IMatchFinderCallback *callback) { - m_Callback = aCallback; + m_Callback = callback; return S_OK; } @@ -25,24 +25,24 @@ void CPatricia::AfterMoveBlock() CLZInWindow::AfterMoveBlock(); } -const UINT32 kMatchStartValue2 = 2; -const UINT32 kDescendantEmptyValue2 = kMatchStartValue2 - 1; -const UINT32 kDescendantsNotInitilized2 = kDescendantEmptyValue2 - 1; +const UInt32 kMatchStartValue2 = 2; +const UInt32 kDescendantEmptyValue2 = kMatchStartValue2 - 1; +const UInt32 kDescendantsNotInitilized2 = kDescendantEmptyValue2 - 1; #ifdef __HASH_3 -static const UINT32 kNumHashBytes = 3; -static const UINT32 kHashSize = 1 << (8 * kNumHashBytes); +static const UInt32 kNumHashBytes = 3; +static const UInt32 kHashSize = 1 << (8 * kNumHashBytes); -static const UINT32 kNumHash2Bytes = 2; -static const UINT32 kHash2Size = 1 << (8 * kNumHash2Bytes); -static const UINT32 kPrevHashSize = kNumHash2Bytes; +static const UInt32 kNumHash2Bytes = 2; +static const UInt32 kHash2Size = 1 << (8 * kNumHash2Bytes); +static const UInt32 kPrevHashSize = kNumHash2Bytes; #else -static const UINT32 kNumHashBytes = 2; -static const UINT32 kHashSize = 1 << (8 * kNumHashBytes); -static const UINT32 kPrevHashSize = 0; +static const UInt32 kNumHashBytes = 2; +static const UInt32 kHashSize = 1 << (8 * kNumHashBytes); +static const UInt32 kPrevHashSize = 0; #endif @@ -52,8 +52,8 @@ CPatricia::CPatricia(): #ifdef __HASH_3 m_Hash2Descendants(0), #endif - m_TmpBacks(0), - m_Nodes(0) + m_Nodes(0), + m_TmpBacks(0) { } @@ -64,91 +64,98 @@ CPatricia::~CPatricia() void CPatricia::FreeMemory() { - delete []m_TmpBacks; + MyFree(m_TmpBacks); m_TmpBacks = 0; - #ifdef WIN32 - if (m_Nodes != 0) - VirtualFree(m_Nodes, 0, MEM_RELEASE); + ::BigFree(m_Nodes); m_Nodes = 0; - #else - m_AlignBuffer.Free(); - #endif - delete []m_HashDescendants; + ::BigFree(m_HashDescendants); m_HashDescendants = 0; #ifdef __HASH_3 - delete []m_Hash2Descendants; + ::BigFree(m_Hash2Descendants); m_Hash2Descendants = 0; + CLZInWindow::Free(); + #endif } -STDMETHODIMP CPatricia::Create(UINT32 aSizeHistory, UINT32 aKeepAddBufferBefore, - UINT32 aMatchMaxLen, UINT32 aKeepAddBufferAfter) +STDMETHODIMP CPatricia::Create(UInt32 historySize, UInt32 keepAddBufferBefore, + UInt32 matchMaxLen, UInt32 keepAddBufferAfter) { FreeMemory(); - const int kNumBitsInNumSameBits = sizeof(CSameBitsType) * 8; - if (kNumBitsInNumSameBits < 32 && ((aMatchMaxLen * MY_BYTE_SIZE) > (1 << kNumBitsInNumSameBits))) + int kNumBitsInNumSameBits = sizeof(CSameBitsType) * 8; + if (kNumBitsInNumSameBits < 32 && ((matchMaxLen * MY_BYTE_SIZE) > ((UInt32)1 << kNumBitsInNumSameBits))) return E_INVALIDARG; - const UINT32 kAlignMask = (1 << 16) - 1; - UINT32 aWindowReservSize = aSizeHistory; - aWindowReservSize += kAlignMask; - aWindowReservSize &= ~(kAlignMask); - - const UINT32 kMinReservSize = (1 << 19); - if (aWindowReservSize < kMinReservSize) - aWindowReservSize = kMinReservSize; - aWindowReservSize += 256; - - try - { - CLZInWindow::Create(aSizeHistory + aKeepAddBufferBefore, - aMatchMaxLen + aKeepAddBufferAfter, aWindowReservSize); - _sizeHistory = aSizeHistory; - _matchMaxLen = aMatchMaxLen; - m_HashDescendants = new CDescendant[kHashSize + 1]; - #ifdef __HASH_3 - m_Hash2Descendants = new CDescendant[kHash2Size + 1]; - #endif + const UInt32 kAlignMask = (1 << 16) - 1; + UInt32 windowReservSize = historySize; + windowReservSize += kAlignMask; + windowReservSize &= ~(kAlignMask); - #ifdef __AUTO_REMOVE - - #ifdef __HASH_3 - m_NumNodes = aSizeHistory + _sizeHistory * 4 / 8 + (1 << 19); - #else - m_NumNodes = aSizeHistory + _sizeHistory * 4 / 8 + (1 << 10); - #endif + const UInt32 kMinReservSize = (1 << 19); + if (windowReservSize < kMinReservSize) + windowReservSize = kMinReservSize; + windowReservSize += 256; - #else + if (!CLZInWindow::Create(historySize + keepAddBufferBefore, + matchMaxLen + keepAddBufferAfter, windowReservSize)) + return E_OUTOFMEMORY; - UINT32 m_NumNodes = aSizeHistory; - - #endif - - const UINT32 kMaxNumNodes = UINT32(1) << (sizeof(CIndex) * 8 - 1); - if (m_NumNodes + 32 > kMaxNumNodes) - return E_INVALIDARG; - - #ifdef WIN32 - m_Nodes = (CNode *)::VirtualAlloc(0, (m_NumNodes + 2) * sizeof(CNode), MEM_COMMIT, PAGE_READWRITE); - if (m_Nodes == 0) - throw CNewException(); - #else - m_Nodes = (CNode *)m_AlignBuffer.Allocate(m_NumNodes + 2, sizeof(CNode), 0x40); - #endif + _sizeHistory = historySize; + _matchMaxLen = matchMaxLen; + m_HashDescendants = (CDescendant *)BigAlloc(kHashSize * sizeof(CDescendant)); + if (m_HashDescendants == 0) + { + FreeMemory(); + return E_OUTOFMEMORY; + } - m_TmpBacks = new UINT32[_matchMaxLen + 1]; - return S_OK; + #ifdef __HASH_3 + m_Hash2Descendants = (CDescendant *)BigAlloc(kHash2Size * sizeof(CDescendant)); + if (m_Hash2Descendants == 0) + { + FreeMemory(); + return E_OUTOFMEMORY; } - catch(...) + #endif + + #ifdef __AUTO_REMOVE + + #ifdef __HASH_3 + m_NumNodes = historySize + _sizeHistory * 4 / 8 + (1 << 19); + #else + m_NumNodes = historySize + _sizeHistory * 4 / 8 + (1 << 10); + #endif + + #else + + UInt32 m_NumNodes = historySize; + + #endif + + const UInt32 kMaxNumNodes = UInt32(1) << (sizeof(CIndex) * 8 - 1); + if (m_NumNodes + 32 > kMaxNumNodes) + return E_INVALIDARG; + + // m_Nodes = (CNode *)::BigAlloc((m_NumNodes + 2) * sizeof(CNode)); + m_Nodes = (CNode *)::BigAlloc((m_NumNodes + 12) * sizeof(CNode)); + if (m_Nodes == 0) { FreeMemory(); return E_OUTOFMEMORY; } + + m_TmpBacks = (UInt32 *)MyAlloc((_matchMaxLen + 1) * sizeof(UInt32)); + if (m_TmpBacks == 0) + { + FreeMemory(); + return E_OUTOFMEMORY; + } + return S_OK; } STDMETHODIMP CPatricia::Init(ISequentialInStream *aStream) @@ -158,10 +165,10 @@ STDMETHODIMP CPatricia::Init(ISequentialInStream *aStream) // memset(m_HashDescendants, 0xFF, kHashSize * sizeof(m_HashDescendants[0])); #ifdef __HASH_3 - for (UINT32 i = 0; i < kHash2Size; i++) + for (UInt32 i = 0; i < kHash2Size; i++) m_Hash2Descendants[i].MatchPointer = kDescendantsNotInitilized2; #else - for (UINT32 i = 0; i < kHashSize; i++) + for (UInt32 i = 0; i < kHashSize; i++) m_HashDescendants[i].MakeEmpty(); #endif @@ -183,169 +190,168 @@ STDMETHODIMP_(void) CPatricia::ReleaseStream() } // pos = _pos + kNumHashBytes -// aFullCurrentLimit = aCurrentLimit + kNumHashBytes -// aFullMatchLen = aMatchLen + kNumHashBytes +// fullCurrentLimit = currentLimit + kNumHashBytes +// fullMatchLen = matchLen + kNumHashBytes -void CPatricia::ChangeLastMatch(UINT32 aHashValue) +void CPatricia::ChangeLastMatch(UInt32 hashValue) { - UINT32 pos = _pos + kNumHashBytes - 1; - UINT32 descendantIndex; - const BYTE *aCurrentBytePointer = _buffer + pos; - UINT32 aNumLoadedBits = 0; - BYTE aByte; - CNodePointer aNode = &m_Nodes[m_HashDescendants[aHashValue].NodePointer]; + UInt32 pos = _pos + kNumHashBytes - 1; + UInt32 descendantIndex; + const Byte *currentBytePointer = _buffer + pos; + UInt32 numLoadedBits = 0; + Byte curByte = 0; // = 0 to disable warning of GCC + CNodePointer node = &m_Nodes[m_HashDescendants[hashValue].NodePointer]; while(true) { - UINT32 aNumSameBits = aNode->NumSameBits; - if(aNumSameBits > 0) + UInt32 numSameBits = node->NumSameBits; + if(numSameBits > 0) { - if (aNumLoadedBits < aNumSameBits) + if (numLoadedBits < numSameBits) { - aNumSameBits -= aNumLoadedBits; - aCurrentBytePointer += (aNumSameBits / MY_BYTE_SIZE); - aNumSameBits %= MY_BYTE_SIZE; - aByte = *aCurrentBytePointer++; - aNumLoadedBits = MY_BYTE_SIZE; + numSameBits -= numLoadedBits; + currentBytePointer += (numSameBits / MY_BYTE_SIZE); + numSameBits %= MY_BYTE_SIZE; + curByte = *currentBytePointer++; + numLoadedBits = MY_BYTE_SIZE; } - aByte >>= aNumSameBits; - aNumLoadedBits -= aNumSameBits; + curByte >>= numSameBits; + numLoadedBits -= numSameBits; } - if(aNumLoadedBits == 0) + if(numLoadedBits == 0) { - aByte = *aCurrentBytePointer++; - aNumLoadedBits = MY_BYTE_SIZE; + curByte = *currentBytePointer++; + numLoadedBits = MY_BYTE_SIZE; } - descendantIndex = (aByte & kSubNodesMask); - aNode->LastMatch = pos; - aNumLoadedBits -= kNumSubBits; - aByte >>= kNumSubBits; - if(aNode->Descendants[descendantIndex].IsNode()) - aNode = &m_Nodes[aNode->Descendants[descendantIndex].NodePointer]; + descendantIndex = (curByte & kSubNodesMask); + node->LastMatch = pos; + numLoadedBits -= kNumSubBits; + curByte >>= kNumSubBits; + if(node->Descendants[descendantIndex].IsNode()) + node = &m_Nodes[node->Descendants[descendantIndex].NodePointer]; else break; } - aNode->Descendants[descendantIndex].MatchPointer = pos + kMatchStartValue; + node->Descendants[descendantIndex].MatchPointer = pos + kMatchStartValue; } -UINT32 CPatricia::GetLongestMatch(UINT32 *aBacks) +UInt32 CPatricia::GetLongestMatch(UInt32 *distances) { - UINT32 aFullCurrentLimit; + UInt32 fullCurrentLimit; if (_pos + _matchMaxLen <= _streamPos) - aFullCurrentLimit = _matchMaxLen; + fullCurrentLimit = _matchMaxLen; else { - aFullCurrentLimit = _streamPos - _pos; - if(aFullCurrentLimit < kNumHashBytes) + fullCurrentLimit = _streamPos - _pos; + if(fullCurrentLimit < kNumHashBytes) return 0; } - UINT32 pos = _pos + kNumHashBytes; + UInt32 pos = _pos + kNumHashBytes; #ifdef __HASH_3 - UINT32 aHashValueTemp = (*((UINT32 *)(_buffer + _pos))); - UINT32 aHashValue = ((aHashValueTemp << 8) | - ((aHashValueTemp & 0xFFFFFF)>> 16)) & 0xFFFFFF; - CDescendant &aHashDescendant = m_HashDescendants[aHashValue]; - CDescendant &aHash2Descendant = m_Hash2Descendants[aHashValueTemp & 0xFFFF]; - if(aHash2Descendant.MatchPointer <= kDescendantEmptyValue2) - { - if(aHash2Descendant.MatchPointer == kDescendantsNotInitilized2) + UInt32 hash2Value = ((UInt32(_buffer[_pos])) << 8) | _buffer[_pos + 1]; + UInt32 hashValue = (hash2Value << 8) | _buffer[_pos + 2]; + CDescendant &hash2Descendant = m_Hash2Descendants[hash2Value]; + CDescendant &hashDescendant = m_HashDescendants[hashValue]; + if(hash2Descendant.MatchPointer <= kDescendantEmptyValue2) + { + if(hash2Descendant.MatchPointer == kDescendantsNotInitilized2) { - UINT32 aBase = aHashValue & 0xFFFF00; - for (UINT32 i = 0; i < 0x100; i++) - m_HashDescendants[aBase + i].MakeEmpty(); + UInt32 base = hashValue & 0xFFFF00; + for (UInt32 i = 0; i < 0x100; i++) + m_HashDescendants[base + i].MakeEmpty(); } - aHash2Descendant.MatchPointer = pos + kMatchStartValue2; - aHashDescendant.MatchPointer = pos + kMatchStartValue; + hash2Descendant.MatchPointer = pos + kMatchStartValue2; + hashDescendant.MatchPointer = pos + kMatchStartValue; return 0; } - aBacks[kNumHash2Bytes] = pos - (aHash2Descendant.MatchPointer - kMatchStartValue2) - 1; - aHash2Descendant.MatchPointer = pos + kMatchStartValue2; + distances[kNumHash2Bytes] = pos - (hash2Descendant.MatchPointer - kMatchStartValue2) - 1; + hash2Descendant.MatchPointer = pos + kMatchStartValue2; #ifdef __AUTO_REMOVE - if (aBacks[kNumHash2Bytes] >= _sizeHistory) + if (distances[kNumHash2Bytes] >= _sizeHistory) { - if (aHashDescendant.IsNode()) - RemoveNode(aHashDescendant.NodePointer); - aHashDescendant.MatchPointer = pos + kMatchStartValue; + if (hashDescendant.IsNode()) + RemoveNode(hashDescendant.NodePointer); + hashDescendant.MatchPointer = pos + kMatchStartValue; return 0; } #endif - if (aFullCurrentLimit == kNumHash2Bytes) + if (fullCurrentLimit == kNumHash2Bytes) return kNumHash2Bytes; #else - UINT32 aHashValue = UINT32(GetIndexByte(1)) | (UINT32(GetIndexByte(0)) << 8); - CDescendant &aHashDescendant = m_HashDescendants[aHashValue]; + UInt32 hashValue = UInt32(GetIndexByte(1)) | (UInt32(GetIndexByte(0)) << 8); + CDescendant &hashDescendant = m_HashDescendants[hashValue]; #endif if(m_SpecialMode) { - if(aHashDescendant.IsMatch()) + if(hashDescendant.IsMatch()) m_NumNotChangedCycles = 0; if(m_NumNotChangedCycles >= _sizeHistory - 1) { - ChangeLastMatch(aHashValue); + ChangeLastMatch(hashValue); m_NumNotChangedCycles = 0; } - if(GetIndexByte(aFullCurrentLimit - 1) == GetIndexByte(aFullCurrentLimit - 2)) + if(GetIndexByte(fullCurrentLimit - 1) == GetIndexByte(fullCurrentLimit - 2)) { - if(aHashDescendant.IsMatch()) - aHashDescendant.MatchPointer = pos + kMatchStartValue; + if(hashDescendant.IsMatch()) + hashDescendant.MatchPointer = pos + kMatchStartValue; else m_NumNotChangedCycles++; - for(UINT32 i = kNumHashBytes; i <= aFullCurrentLimit; i++) - aBacks[i] = 0; - return aFullCurrentLimit; + for(UInt32 i = kNumHashBytes; i <= fullCurrentLimit; i++) + distances[i] = 0; + return fullCurrentLimit; } else if(m_NumNotChangedCycles > 0) - ChangeLastMatch(aHashValue); + ChangeLastMatch(hashValue); m_SpecialMode = false; } - if(aHashDescendant.IsEmpty()) + if(hashDescendant.IsEmpty()) { - aHashDescendant.MatchPointer = pos + kMatchStartValue; + hashDescendant.MatchPointer = pos + kMatchStartValue; return kPrevHashSize; } - UINT32 aCurrentLimit = aFullCurrentLimit - kNumHashBytes; + UInt32 currentLimit = fullCurrentLimit - kNumHashBytes; - if(aHashDescendant.IsMatch()) + if(hashDescendant.IsMatch()) { - CMatchPointer aMatchPointer = aHashDescendant.MatchPointer; - UINT32 aBackReal = pos - (aMatchPointer - kMatchStartValue); - UINT32 aBack = aBackReal - 1; + CMatchPointer matchPointer = hashDescendant.MatchPointer; + UInt32 backReal = pos - (matchPointer - kMatchStartValue); + UInt32 back = backReal - 1; #ifdef __AUTO_REMOVE - if (aBack >= _sizeHistory) + if (back >= _sizeHistory) { - aHashDescendant.MatchPointer = pos + kMatchStartValue; + hashDescendant.MatchPointer = pos + kMatchStartValue; return kPrevHashSize; } #endif - UINT32 aMatchLen; - aBacks += kNumHashBytes; - BYTE *aBuffer = _buffer + pos; - for(aMatchLen = 0; true; aMatchLen++) + UInt32 matchLen; + distances += kNumHashBytes; + Byte *buffer = _buffer + pos; + for(matchLen = 0; true; matchLen++) { - *aBacks++ = aBack; - if (aMatchLen == aCurrentLimit) + *distances++ = back; + if (matchLen == currentLimit) { - aHashDescendant.MatchPointer = pos + kMatchStartValue; - return kNumHashBytes + aMatchLen; + hashDescendant.MatchPointer = pos + kMatchStartValue; + return kNumHashBytes + matchLen; } - if (aBuffer[aMatchLen] != aBuffer[aMatchLen - aBackReal]) + if (buffer[matchLen] != buffer[(size_t)matchLen - backReal]) break; } - // UINT32 aMatchLen = GetMatchLen(kNumHashBytes, aBack, aCurrentLimit); + // UInt32 matchLen = GetMatchLen(kNumHashBytes, back, currentLimit); - UINT32 aFullMatchLen = aMatchLen + kNumHashBytes; - aHashDescendant.NodePointer = m_FreeNode; - CNodePointer aNode = &m_Nodes[m_FreeNode]; - m_FreeNode = aNode->NextFreeNode; + UInt32 fullMatchLen = matchLen + kNumHashBytes; + hashDescendant.NodePointer = m_FreeNode; + CNodePointer node = &m_Nodes[m_FreeNode]; + m_FreeNode = node->NextFreeNode; #ifdef __AUTO_REMOVE m_NumUsedNodes++; #endif @@ -355,181 +361,181 @@ UINT32 CPatricia::GetLongestMatch(UINT32 *aBacks) m_Nodes[m_FreeNode].NextFreeNode = m_FreeNode + 1; } - for (UINT32 i = 0; i < kNumSubNodes; i++) - aNode->Descendants[i].NodePointer = kDescendantEmptyValue; - aNode->LastMatch = pos; + for (UInt32 i = 0; i < kNumSubNodes; i++) + node->Descendants[i].NodePointer = kDescendantEmptyValue; + node->LastMatch = pos; - BYTE aByteNew = GetIndexByte(aFullMatchLen); - BYTE aByteOld = GetIndexByte(aFullMatchLen - aBackReal); - BYTE aBitsNew, aBitsOld; - UINT32 aNumSameBits = aMatchLen * MY_BYTE_SIZE; + Byte byteNew = GetIndexByte(fullMatchLen); + Byte byteOld = GetIndexByte(fullMatchLen - backReal); + Byte bitsNew, bitsOld; + UInt32 numSameBits = matchLen * MY_BYTE_SIZE; while (true) { - aBitsNew = (aByteNew & kSubNodesMask); - aBitsOld = (aByteOld & kSubNodesMask); - if(aBitsNew != aBitsOld) + bitsNew = (byteNew & kSubNodesMask); + bitsOld = (byteOld & kSubNodesMask); + if(bitsNew != bitsOld) break; - aByteNew >>= kNumSubBits; - aByteOld >>= kNumSubBits; - aNumSameBits += kNumSubBits; + byteNew >>= kNumSubBits; + byteOld >>= kNumSubBits; + numSameBits += kNumSubBits; } - aNode->NumSameBits = CSameBitsType(aNumSameBits); - aNode->Descendants[aBitsNew].MatchPointer = pos + kMatchStartValue; - aNode->Descendants[aBitsOld].MatchPointer = aMatchPointer; - return aFullMatchLen; - } - const BYTE *aBaseCurrentBytePointer = _buffer + pos; - const BYTE *aCurrentBytePointer = aBaseCurrentBytePointer; - UINT32 aNumLoadedBits = 0; - BYTE aByte = 0; - CIndex *aNodePointerPointer = &aHashDescendant.NodePointer; - CNodePointer aNode = &m_Nodes[*aNodePointerPointer]; - aBacks += kNumHashBytes; - const BYTE *aBytePointerLimit = aBaseCurrentBytePointer + aCurrentLimit; - const BYTE *aCurrentAddingOffset = _buffer; + node->NumSameBits = CSameBitsType(numSameBits); + node->Descendants[bitsNew].MatchPointer = pos + kMatchStartValue; + node->Descendants[bitsOld].MatchPointer = matchPointer; + return fullMatchLen; + } + const Byte *baseCurrentBytePointer = _buffer + pos; + const Byte *currentBytePointer = baseCurrentBytePointer; + UInt32 numLoadedBits = 0; + Byte curByte = 0; + CIndex *nodePointerPointer = &hashDescendant.NodePointer; + CNodePointer node = &m_Nodes[*nodePointerPointer]; + distances += kNumHashBytes; + const Byte *bytePointerLimit = baseCurrentBytePointer + currentLimit; + const Byte *currentAddingOffset = _buffer; #ifdef __AUTO_REMOVE - UINT32 aLowPos; + UInt32 lowPos; if (pos > _sizeHistory) - aLowPos = pos - _sizeHistory; + lowPos = pos - _sizeHistory; else - aLowPos = 0; + lowPos = 0; #endif while(true) { #ifdef __AUTO_REMOVE - if (aNode->LastMatch < aLowPos) + if (node->LastMatch < lowPos) { - RemoveNode(*aNodePointerPointer); - *aNodePointerPointer = pos + kMatchStartValue; - if (aCurrentBytePointer == aBaseCurrentBytePointer) + RemoveNode(*nodePointerPointer); + *nodePointerPointer = pos + kMatchStartValue; + if (currentBytePointer == baseCurrentBytePointer) return kPrevHashSize; - return kNumHashBytes + (aCurrentBytePointer - aBaseCurrentBytePointer - 1); + return kNumHashBytes + (currentBytePointer - baseCurrentBytePointer - 1); } #endif - if(aNumLoadedBits == 0) + if(numLoadedBits == 0) { - *aBacks++ = pos - aNode->LastMatch - 1; - if(aCurrentBytePointer >= aBytePointerLimit) + *distances++ = pos - node->LastMatch - 1; + if(currentBytePointer >= bytePointerLimit) { - for (UINT32 i = 0; i < kNumSubNodes; i++) - aNode->Descendants[i].MatchPointer = pos + kMatchStartValue; - aNode->LastMatch = pos; - aNode->NumSameBits = 0; - return aFullCurrentLimit; + for (UInt32 i = 0; i < kNumSubNodes; i++) + node->Descendants[i].MatchPointer = pos + kMatchStartValue; + node->LastMatch = pos; + node->NumSameBits = 0; + return fullCurrentLimit; } - aByte = (*aCurrentBytePointer++); - aCurrentAddingOffset++; - aNumLoadedBits = MY_BYTE_SIZE; + curByte = (*currentBytePointer++); + currentAddingOffset++; + numLoadedBits = MY_BYTE_SIZE; } - UINT32 aNumSameBits = aNode->NumSameBits; - if(aNumSameBits > 0) + UInt32 numSameBits = node->NumSameBits; + if(numSameBits > 0) { - BYTE aByteXOR = ((*(aCurrentAddingOffset + aNode->LastMatch -1)) >> - (MY_BYTE_SIZE - aNumLoadedBits)) ^ aByte; - while(aNumLoadedBits <= aNumSameBits) + Byte byteXOR = ((*(currentAddingOffset + node->LastMatch -1)) >> + (MY_BYTE_SIZE - numLoadedBits)) ^ curByte; + while(numLoadedBits <= numSameBits) { - if(aByteXOR != 0) + if(byteXOR != 0) { - AddInternalNode(aNode, aNodePointerPointer, aByte, aByteXOR, - aNumSameBits, pos); - return kNumHashBytes + (aCurrentBytePointer - aBaseCurrentBytePointer - 1); + AddInternalNode(node, nodePointerPointer, curByte, byteXOR, + numSameBits, pos); + return kNumHashBytes + (currentBytePointer - baseCurrentBytePointer - 1); } - *aBacks++ = pos - aNode->LastMatch - 1; - aNumSameBits -= aNumLoadedBits; - if(aCurrentBytePointer >= aBytePointerLimit) + *distances++ = pos - node->LastMatch - 1; + numSameBits -= numLoadedBits; + if(currentBytePointer >= bytePointerLimit) { - for (UINT32 i = 0; i < kNumSubNodes; i++) - aNode->Descendants[i].MatchPointer = pos + kMatchStartValue; - aNode->LastMatch = pos; - aNode->NumSameBits = CSameBitsType(aNode->NumSameBits - aNumSameBits); - return aFullCurrentLimit; + for (UInt32 i = 0; i < kNumSubNodes; i++) + node->Descendants[i].MatchPointer = pos + kMatchStartValue; + node->LastMatch = pos; + node->NumSameBits = CSameBitsType(node->NumSameBits - numSameBits); + return fullCurrentLimit; } - aNumLoadedBits = MY_BYTE_SIZE; - aByte = (*aCurrentBytePointer++); - aByteXOR = aByte ^ (*(aCurrentAddingOffset + aNode->LastMatch)); - aCurrentAddingOffset++; + numLoadedBits = MY_BYTE_SIZE; + curByte = (*currentBytePointer++); + byteXOR = curByte ^ (*(currentAddingOffset + node->LastMatch)); + currentAddingOffset++; } - if((aByteXOR & ((1 << aNumSameBits) - 1)) != 0) + if((byteXOR & ((1 << numSameBits) - 1)) != 0) { - AddInternalNode(aNode, aNodePointerPointer, aByte, aByteXOR, - aNumSameBits, pos); - return kNumHashBytes + (aCurrentBytePointer - aBaseCurrentBytePointer - 1); + AddInternalNode(node, nodePointerPointer, curByte, byteXOR, + numSameBits, pos); + return kNumHashBytes + (currentBytePointer - baseCurrentBytePointer - 1); } - aByte >>= aNumSameBits; - aNumLoadedBits -= aNumSameBits; + curByte >>= numSameBits; + numLoadedBits -= numSameBits; } - UINT32 descendantIndex = (aByte & kSubNodesMask); - aNumLoadedBits -= kNumSubBits; - aNodePointerPointer = &aNode->Descendants[descendantIndex].NodePointer; - UINT32 aNextNodeIndex = *aNodePointerPointer; - aNode->LastMatch = pos; - if (aNextNodeIndex < kDescendantEmptyValue) + UInt32 descendantIndex = (curByte & kSubNodesMask); + numLoadedBits -= kNumSubBits; + nodePointerPointer = &node->Descendants[descendantIndex].NodePointer; + UInt32 nextNodeIndex = *nodePointerPointer; + node->LastMatch = pos; + if (nextNodeIndex < kDescendantEmptyValue) { - aByte >>= kNumSubBits; - aNode = &m_Nodes[aNextNodeIndex]; + curByte >>= kNumSubBits; + node = &m_Nodes[nextNodeIndex]; } - else if (aNextNodeIndex == kDescendantEmptyValue) + else if (nextNodeIndex == kDescendantEmptyValue) { - aNode->Descendants[descendantIndex].MatchPointer = pos + kMatchStartValue; - return kNumHashBytes + (aCurrentBytePointer - aBaseCurrentBytePointer - 1); + node->Descendants[descendantIndex].MatchPointer = pos + kMatchStartValue; + return kNumHashBytes + (currentBytePointer - baseCurrentBytePointer - 1); } else break; } - UINT32 descendantIndex = (aByte & kSubNodesMask); - aByte >>= kNumSubBits; - CMatchPointer aMatchPointer = aNode->Descendants[descendantIndex].MatchPointer; - CMatchPointer aRealMatchPointer; - aRealMatchPointer = aMatchPointer - kMatchStartValue; + UInt32 descendantIndex = (curByte & kSubNodesMask); + curByte >>= kNumSubBits; + CMatchPointer matchPointer = node->Descendants[descendantIndex].MatchPointer; + CMatchPointer realMatchPointer; + realMatchPointer = matchPointer - kMatchStartValue; #ifdef __AUTO_REMOVE - if (aRealMatchPointer < aLowPos) + if (realMatchPointer < lowPos) { - aNode->Descendants[descendantIndex].MatchPointer = pos + kMatchStartValue; - return kNumHashBytes + (aCurrentBytePointer - aBaseCurrentBytePointer - 1); + node->Descendants[descendantIndex].MatchPointer = pos + kMatchStartValue; + return kNumHashBytes + (currentBytePointer - baseCurrentBytePointer - 1); } #endif - BYTE aByteXOR; - UINT32 aNumSameBits = 0; - if(aNumLoadedBits != 0) + Byte byteXOR; + UInt32 numSameBits = 0; + if(numLoadedBits != 0) { - BYTE aMatchByte = *(aCurrentAddingOffset + aRealMatchPointer -1); - aMatchByte >>= (MY_BYTE_SIZE - aNumLoadedBits); - aByteXOR = aMatchByte ^ aByte; - if(aByteXOR != 0) + Byte matchByte = *(currentAddingOffset + realMatchPointer -1); + matchByte >>= (MY_BYTE_SIZE - numLoadedBits); + byteXOR = matchByte ^ curByte; + if(byteXOR != 0) { - AddLeafNode(aNode, aByte, aByteXOR, aNumSameBits, pos, descendantIndex); - return kNumHashBytes + (aCurrentBytePointer - aBaseCurrentBytePointer - 1); + AddLeafNode(node, curByte, byteXOR, numSameBits, pos, descendantIndex); + return kNumHashBytes + (currentBytePointer - baseCurrentBytePointer - 1); } - aNumSameBits += aNumLoadedBits; + numSameBits += numLoadedBits; } - const BYTE *aMatchBytePointer = _buffer + aRealMatchPointer + - (aCurrentBytePointer - aBaseCurrentBytePointer); - for(; aCurrentBytePointer < aBytePointerLimit; aNumSameBits += MY_BYTE_SIZE) + const Byte *matchBytePointer = _buffer + realMatchPointer + + (currentBytePointer - baseCurrentBytePointer); + for(; currentBytePointer < bytePointerLimit; numSameBits += MY_BYTE_SIZE) { - aByte = (*aCurrentBytePointer++); - *aBacks++ = pos - aRealMatchPointer - 1; - aByteXOR = aByte ^ (*aMatchBytePointer++); - if(aByteXOR != 0) + curByte = (*currentBytePointer++); + *distances++ = pos - realMatchPointer - 1; + byteXOR = curByte ^ (*matchBytePointer++); + if(byteXOR != 0) { - AddLeafNode(aNode, aByte, aByteXOR, aNumSameBits, pos, descendantIndex); - return kNumHashBytes + (aCurrentBytePointer - aBaseCurrentBytePointer - 1); + AddLeafNode(node, curByte, byteXOR, numSameBits, pos, descendantIndex); + return kNumHashBytes + (currentBytePointer - baseCurrentBytePointer - 1); } } - *aBacks = pos - aRealMatchPointer - 1; - aNode->Descendants[descendantIndex].MatchPointer = pos + kMatchStartValue; + *distances = pos - realMatchPointer - 1; + node->Descendants[descendantIndex].MatchPointer = pos + kMatchStartValue; - if(*aBacks == 0) + if(*distances == 0) { m_SpecialMode = true; m_NumNotChangedCycles = 0; } - return aFullCurrentLimit; + return fullCurrentLimit; } STDMETHODIMP_(void) CPatricia::DummyLongestMatch() @@ -541,7 +547,7 @@ STDMETHODIMP_(void) CPatricia::DummyLongestMatch() // ------------------------------------ // Remove Match -typedef BYTE CRemoveDataWord; +typedef Byte CRemoveDataWord; static const int kSizeRemoveDataWordInBits = MY_BYTE_SIZE * sizeof(CRemoveDataWord); @@ -556,134 +562,141 @@ void CPatricia::RemoveMatch() return; m_SpecialRemoveMode = false; } - UINT32 pos = _pos + kNumHashBytes - _sizeHistory; + UInt32 pos = _pos + kNumHashBytes - _sizeHistory; #ifdef __HASH_3 - // UINT32 aHashValue = (*((UINT32 *)(_buffer + _pos - _sizeHistory))) & 0xFFFFFF; - UINT32 aHashValueTemp = *((UINT32 *)(_buffer + _pos - _sizeHistory)); - UINT32 aHashValue = ((aHashValueTemp << 8) | - ((aHashValueTemp & 0xFFFFFF)>> 16)) & 0xFFFFFF; - - CDescendant &aHashDescendant = m_HashDescendants[aHashValue]; - CDescendant &aHash2Descendant = m_Hash2Descendants[aHashValueTemp & 0xFFFF]; - if (aHash2Descendant >= kMatchStartValue2) - if(aHash2Descendant.MatchPointer == pos + kMatchStartValue2) - aHash2Descendant.MatchPointer = kDescendantEmptyValue2; + const Byte *pp = _buffer + _pos - _sizeHistory; + UInt32 hash2Value = ((UInt32(pp[0])) << 8) | pp[1]; + UInt32 hashValue = (hash2Value << 8) | pp[2]; + CDescendant &hashDescendant = m_HashDescendants[hashValue]; + CDescendant &hash2Descendant = m_Hash2Descendants[hash2Value]; + if (hash2Descendant >= kMatchStartValue2) + if(hash2Descendant.MatchPointer == pos + kMatchStartValue2) + hash2Descendant.MatchPointer = kDescendantEmptyValue2; #else - UINT32 aHashValue = UINT32(GetIndexByte(1 - _sizeHistory)) | - (UINT32(GetIndexByte(0 - _sizeHistory)) << 8); - CDescendant &aHashDescendant = m_HashDescendants[aHashValue]; + UInt32 hashValue = UInt32(GetIndexByte(1 - _sizeHistory)) | + (UInt32(GetIndexByte(0 - _sizeHistory)) << 8); + CDescendant &hashDescendant = m_HashDescendants[hashValue]; #endif - if(aHashDescendant.IsEmpty()) + if(hashDescendant.IsEmpty()) return; - if(aHashDescendant.IsMatch()) + if(hashDescendant.IsMatch()) { - if(aHashDescendant.MatchPointer == pos + kMatchStartValue) - aHashDescendant.MakeEmpty(); + if(hashDescendant.MatchPointer == pos + kMatchStartValue) + hashDescendant.MakeEmpty(); return; } - UINT32 descendantIndex; - const CRemoveDataWord *aCurrentPointer = (const CRemoveDataWord *)(_buffer + pos); - UINT32 aNumLoadedBits = 0; - CRemoveDataWord aWord; + UInt32 descendantIndex; + const CRemoveDataWord *currentPointer = (const CRemoveDataWord *)(_buffer + pos); + UInt32 numLoadedBits = 0; + CRemoveDataWord curWord = 0; // = 0 to disable GCC warning - CIndex *aNodePointerPointer = &aHashDescendant.NodePointer; + CIndex *nodePointerPointer = &hashDescendant.NodePointer; - CNodePointer aNode = &m_Nodes[aHashDescendant.NodePointer]; + CNodePointer node = &m_Nodes[hashDescendant.NodePointer]; while(true) { - if(aNumLoadedBits == 0) + if(numLoadedBits == 0) { - aWord = *aCurrentPointer++; - aNumLoadedBits = kSizeRemoveDataWordInBits; + curWord = *currentPointer++; + numLoadedBits = kSizeRemoveDataWordInBits; } - UINT32 aNumSameBits = aNode->NumSameBits; - if(aNumSameBits > 0) + UInt32 numSameBits = node->NumSameBits; + if(numSameBits > 0) { - if (aNumLoadedBits <= aNumSameBits) + if (numLoadedBits <= numSameBits) { - aNumSameBits -= aNumLoadedBits; - aCurrentPointer += (aNumSameBits / kSizeRemoveDataWordInBits); - aNumSameBits %= kSizeRemoveDataWordInBits; - aWord = *aCurrentPointer++; - aNumLoadedBits = kSizeRemoveDataWordInBits; + numSameBits -= numLoadedBits; + currentPointer += (numSameBits / kSizeRemoveDataWordInBits); + numSameBits %= kSizeRemoveDataWordInBits; + curWord = *currentPointer++; + numLoadedBits = kSizeRemoveDataWordInBits; } - aWord >>= aNumSameBits; - aNumLoadedBits -= aNumSameBits; + curWord >>= numSameBits; + numLoadedBits -= numSameBits; } - descendantIndex = (aWord & kSubNodesMask); - aNumLoadedBits -= kNumSubBits; - aWord >>= kNumSubBits; - UINT32 aNextNodeIndex = aNode->Descendants[descendantIndex].NodePointer; - if (aNextNodeIndex < kDescendantEmptyValue) + descendantIndex = (curWord & kSubNodesMask); + numLoadedBits -= kNumSubBits; + curWord >>= kNumSubBits; + UInt32 nextNodeIndex = node->Descendants[descendantIndex].NodePointer; + if (nextNodeIndex < kDescendantEmptyValue) { - aNodePointerPointer = &aNode->Descendants[descendantIndex].NodePointer; - aNode = &m_Nodes[aNextNodeIndex]; + nodePointerPointer = &node->Descendants[descendantIndex].NodePointer; + node = &m_Nodes[nextNodeIndex]; } else break; } - if (aNode->Descendants[descendantIndex].MatchPointer != pos + kMatchStartValue) + if (node->Descendants[descendantIndex].MatchPointer != pos + kMatchStartValue) { - const BYTE *aCurrentBytePointer = _buffer + _pos - _sizeHistory; - const BYTE *aCurrentBytePointerLimit = aCurrentBytePointer + _matchMaxLen; - for(;aCurrentBytePointer < aCurrentBytePointerLimit; aCurrentBytePointer++) - if(*aCurrentBytePointer != *(aCurrentBytePointer+1)) + const Byte *currentBytePointer = _buffer + _pos - _sizeHistory; + const Byte *currentBytePointerLimit = currentBytePointer + _matchMaxLen; + for(;currentBytePointer < currentBytePointerLimit; currentBytePointer++) + if(*currentBytePointer != *(currentBytePointer+1)) return; m_SpecialRemoveMode = true; return; } - UINT32 aNumNodes = 0, aNumMatches = 0; + UInt32 numNodes = 0, numMatches = 0; - UINT32 i; + UInt32 i; for (i = 0; i < kNumSubNodes; i++) { - UINT32 aNodeIndex = aNode->Descendants[i].NodePointer; - if (aNodeIndex < kDescendantEmptyValue) - aNumNodes++; - else if (aNodeIndex > kDescendantEmptyValue) - aNumMatches++; + UInt32 nodeIndex = node->Descendants[i].NodePointer; + if (nodeIndex < kDescendantEmptyValue) + numNodes++; + else if (nodeIndex > kDescendantEmptyValue) + numMatches++; } - aNumMatches -= 1; - if (aNumNodes + aNumMatches > 1) + numMatches -= 1; + if (numNodes + numMatches > 1) { - aNode->Descendants[descendantIndex].MakeEmpty(); + node->Descendants[descendantIndex].MakeEmpty(); return; } - if(aNumNodes == 1) + if(numNodes == 1) { - UINT32 i; + UInt32 i; for (i = 0; i < kNumSubNodes; i++) - if (aNode->Descendants[i].IsNode()) + if (node->Descendants[i].IsNode()) break; - UINT32 aNextNodeIndex = aNode->Descendants[i].NodePointer; - CNodePointer aNextNode = &m_Nodes[aNextNodeIndex]; - aNextNode->NumSameBits += aNode->NumSameBits + kNumSubBits; - *aNode = *aNextNode; + UInt32 nextNodeIndex = node->Descendants[i].NodePointer; + CNodePointer nextNode = &m_Nodes[nextNodeIndex]; + nextNode->NumSameBits += node->NumSameBits + kNumSubBits; + *node = *nextNode; - aNextNode->NextFreeNode = m_FreeNode; - m_FreeNode = aNextNodeIndex; + nextNode->NextFreeNode = m_FreeNode; + m_FreeNode = nextNodeIndex; return; } - UINT32 aMatchPointer; + UInt32 matchPointer = 0; // = 0 to disable GCC warning for (i = 0; i < kNumSubNodes; i++) - if (aNode->Descendants[i].IsMatch() && i != descendantIndex) + if (node->Descendants[i].IsMatch() && i != descendantIndex) { - aMatchPointer = aNode->Descendants[i].MatchPointer; + matchPointer = node->Descendants[i].MatchPointer; break; } - aNode->NextFreeNode = m_FreeNode; - m_FreeNode = *aNodePointerPointer; - *aNodePointerPointer = aMatchPointer; + node->NextFreeNode = m_FreeNode; + m_FreeNode = *nodePointerPointer; + *nodePointerPointer = matchPointer; } #endif -const UINT32 kNormalizeStartPos = (UINT32(1) << (kNumBitsInIndex)) - + +// Commented code is more correct, but it gives warning +// on GCC: (1 << 32) +// So we use kMatchStartValue twice: +// kMatchStartValue = UInt32(1) << (kNumBitsInIndex - 1); +// must be defined in Pat.h +/* +const UInt32 kNormalizeStartPos = (UInt32(1) << (kNumBitsInIndex)) - kMatchStartValue - kNumHashBytes - 1; +*/ +const UInt32 kNormalizeStartPos = kMatchStartValue - kNumHashBytes - 1; STDMETHODIMP CPatricia::MovePos() { @@ -709,46 +722,46 @@ STDMETHODIMP CPatricia::MovePos() #ifndef __AUTO_REMOVE -void CPatricia::NormalizeDescendant(CDescendant &aDescendant, UINT32 aSubValue) +void CPatricia::NormalizeDescendant(CDescendant &descendant, UInt32 subValue) { - if (aDescendant.IsEmpty()) + if (descendant.IsEmpty()) return; - if (aDescendant.IsMatch()) - aDescendant.MatchPointer = aDescendant.MatchPointer - aSubValue; + if (descendant.IsMatch()) + descendant.MatchPointer = descendant.MatchPointer - subValue; else { - CNode &aNode = m_Nodes[aDescendant.NodePointer]; - aNode.LastMatch = aNode.LastMatch - aSubValue; - for (UINT32 i = 0; i < kNumSubNodes; i++) - NormalizeDescendant(aNode.Descendants[i], aSubValue); + CNode &node = m_Nodes[descendant.NodePointer]; + node.LastMatch = node.LastMatch - subValue; + for (UInt32 i = 0; i < kNumSubNodes; i++) + NormalizeDescendant(node.Descendants[i], subValue); } } void CPatricia::Normalize() { - UINT32 aSubValue = _pos - _sizeHistory; - CLZInWindow::ReduceOffsets(aSubValue); + UInt32 subValue = _pos - _sizeHistory; + CLZInWindow::ReduceOffsets(subValue); #ifdef __HASH_3 - for(UINT32 aHash = 0; aHash < kHash2Size; aHash++) + for(UInt32 hash = 0; hash < kHash2Size; hash++) { - CDescendant &aDescendant = m_Hash2Descendants[aHash]; - if (aDescendant.MatchPointer != kDescendantsNotInitilized2) + CDescendant &descendant = m_Hash2Descendants[hash]; + if (descendant.MatchPointer != kDescendantsNotInitilized2) { - UINT32 aBase = aHash << 8; - for (UINT32 i = 0; i < 0x100; i++) - NormalizeDescendant(m_HashDescendants[aBase + i], aSubValue); + UInt32 base = hash << 8; + for (UInt32 i = 0; i < 0x100; i++) + NormalizeDescendant(m_HashDescendants[base + i], subValue); } - if (aDescendant.MatchPointer < kMatchStartValue2) + if (descendant.MatchPointer < kMatchStartValue2) continue; - aDescendant.MatchPointer = aDescendant.MatchPointer - aSubValue; + descendant.MatchPointer = descendant.MatchPointer - subValue; } #else - for(UINT32 aHash = 0; aHash < kHashSize; aHash++) - NormalizeDescendant(m_HashDescendants[aHash], aSubValue); + for(UInt32 hash = 0; hash < kHashSize; hash++) + NormalizeDescendant(m_HashDescendants[hash], subValue); #endif @@ -756,219 +769,219 @@ void CPatricia::Normalize() #else -void CPatricia::TestRemoveDescendant(CDescendant &aDescendant, UINT32 aLimitPos) +void CPatricia::TestRemoveDescendant(CDescendant &descendant, UInt32 limitPos) { - CNode &aNode = m_Nodes[aDescendant.NodePointer]; - UINT32 aNumChilds = 0; - UINT32 aChildIndex; - for (UINT32 i = 0; i < kNumSubNodes; i++) + CNode &node = m_Nodes[descendant.NodePointer]; + UInt32 numChilds = 0; + UInt32 childIndex = 0; // = 0 to disable GCC warning + for (UInt32 i = 0; i < kNumSubNodes; i++) { - CDescendant &aDescendant2 = aNode.Descendants[i]; - if (aDescendant2.IsEmpty()) + CDescendant &descendant2 = node.Descendants[i]; + if (descendant2.IsEmpty()) continue; - if (aDescendant2.IsMatch()) + if (descendant2.IsMatch()) { - if (aDescendant2.MatchPointer < aLimitPos) - aDescendant2.MakeEmpty(); + if (descendant2.MatchPointer < limitPos) + descendant2.MakeEmpty(); else { - aNumChilds++; - aChildIndex = i; + numChilds++; + childIndex = i; } } else { - TestRemoveDescendant(aDescendant2, aLimitPos); - if (!aDescendant2.IsEmpty()) + TestRemoveDescendant(descendant2, limitPos); + if (!descendant2.IsEmpty()) { - aNumChilds++; - aChildIndex = i; + numChilds++; + childIndex = i; } } } - if (aNumChilds > 1) + if (numChilds > 1) return; - CIndex aNodePointerTemp = aDescendant.NodePointer; - if (aNumChilds == 1) + CIndex nodePointerTemp = descendant.NodePointer; + if (numChilds == 1) { - const CDescendant &aDescendant2 = aNode.Descendants[aChildIndex]; - if (aDescendant2.IsNode()) - m_Nodes[aDescendant2.NodePointer].NumSameBits += aNode.NumSameBits + kNumSubBits; - aDescendant = aDescendant2; + const CDescendant &descendant2 = node.Descendants[childIndex]; + if (descendant2.IsNode()) + m_Nodes[descendant2.NodePointer].NumSameBits += node.NumSameBits + kNumSubBits; + descendant = descendant2; } else - aDescendant.MakeEmpty(); - aNode.NextFreeNode = m_FreeNode; - m_FreeNode = aNodePointerTemp; + descendant.MakeEmpty(); + node.NextFreeNode = m_FreeNode; + m_FreeNode = nodePointerTemp; m_NumUsedNodes--; } -void CPatricia::RemoveNode(UINT32 anIndex) +void CPatricia::RemoveNode(UInt32 index) { - CNode &aNode = m_Nodes[anIndex]; - for (UINT32 i = 0; i < kNumSubNodes; i++) + CNode &node = m_Nodes[index]; + for (UInt32 i = 0; i < kNumSubNodes; i++) { - CDescendant &aDescendant2 = aNode.Descendants[i]; - if (aDescendant2.IsNode()) - RemoveNode(aDescendant2.NodePointer); + CDescendant &descendant2 = node.Descendants[i]; + if (descendant2.IsNode()) + RemoveNode(descendant2.NodePointer); } - aNode.NextFreeNode = m_FreeNode; - m_FreeNode = anIndex; + node.NextFreeNode = m_FreeNode; + m_FreeNode = index; m_NumUsedNodes--; } void CPatricia::TestRemoveNodes() { - UINT32 aLimitPos = kMatchStartValue + _pos - _sizeHistory + kNumHashBytes; + UInt32 limitPos = kMatchStartValue + _pos - _sizeHistory + kNumHashBytes; #ifdef __HASH_3 - UINT32 aLimitPos2 = kMatchStartValue2 + _pos - _sizeHistory + kNumHashBytes; - for(UINT32 aHash = 0; aHash < kHash2Size; aHash++) + UInt32 limitPos2 = kMatchStartValue2 + _pos - _sizeHistory + kNumHashBytes; + for(UInt32 hash = 0; hash < kHash2Size; hash++) { - CDescendant &aDescendant = m_Hash2Descendants[aHash]; - if (aDescendant.MatchPointer != kDescendantsNotInitilized2) + CDescendant &descendant = m_Hash2Descendants[hash]; + if (descendant.MatchPointer != kDescendantsNotInitilized2) { - UINT32 aBase = aHash << 8; - for (UINT32 i = 0; i < 0x100; i++) + UInt32 base = hash << 8; + for (UInt32 i = 0; i < 0x100; i++) { - CDescendant &aDescendant = m_HashDescendants[aBase + i]; - if (aDescendant.IsEmpty()) + CDescendant &descendant = m_HashDescendants[base + i]; + if (descendant.IsEmpty()) continue; - if (aDescendant.IsMatch()) + if (descendant.IsMatch()) { - if (aDescendant.MatchPointer < aLimitPos) - aDescendant.MakeEmpty(); + if (descendant.MatchPointer < limitPos) + descendant.MakeEmpty(); } else - TestRemoveDescendant(aDescendant, aLimitPos); + TestRemoveDescendant(descendant, limitPos); } } - if (aDescendant.MatchPointer < kMatchStartValue2) + if (descendant.MatchPointer < kMatchStartValue2) continue; - if (aDescendant.MatchPointer < aLimitPos2) - aDescendant.MatchPointer = kDescendantEmptyValue2; + if (descendant.MatchPointer < limitPos2) + descendant.MatchPointer = kDescendantEmptyValue2; } #else - for(UINT32 aHash = 0; aHash < kHashSize; aHash++) + for(UInt32 hash = 0; hash < kHashSize; hash++) { - CDescendant &aDescendant = m_HashDescendants[aHash]; - if (aDescendant.IsEmpty()) + CDescendant &descendant = m_HashDescendants[hash]; + if (descendant.IsEmpty()) continue; - if (aDescendant.IsMatch()) + if (descendant.IsMatch()) { - if (aDescendant.MatchPointer < aLimitPos) - aDescendant.MakeEmpty(); + if (descendant.MatchPointer < limitPos) + descendant.MakeEmpty(); } else - TestRemoveDescendant(aDescendant, aLimitPos); + TestRemoveDescendant(descendant, limitPos); } #endif } -void CPatricia::TestRemoveAndNormalizeDescendant(CDescendant &aDescendant, - UINT32 aLimitPos, UINT32 aSubValue) +void CPatricia::TestRemoveAndNormalizeDescendant(CDescendant &descendant, + UInt32 limitPos, UInt32 subValue) { - if (aDescendant.IsEmpty()) + if (descendant.IsEmpty()) return; - if (aDescendant.IsMatch()) + if (descendant.IsMatch()) { - if (aDescendant.MatchPointer < aLimitPos) - aDescendant.MakeEmpty(); + if (descendant.MatchPointer < limitPos) + descendant.MakeEmpty(); else - aDescendant.MatchPointer = aDescendant.MatchPointer - aSubValue; + descendant.MatchPointer = descendant.MatchPointer - subValue; return; } - CNode &aNode = m_Nodes[aDescendant.NodePointer]; - UINT32 aNumChilds = 0; - UINT32 aChildIndex; - for (UINT32 i = 0; i < kNumSubNodes; i++) + CNode &node = m_Nodes[descendant.NodePointer]; + UInt32 numChilds = 0; + UInt32 childIndex = 0; // = 0 to disable GCC warning + for (UInt32 i = 0; i < kNumSubNodes; i++) { - CDescendant &aDescendant2 = aNode.Descendants[i]; - TestRemoveAndNormalizeDescendant(aDescendant2, aLimitPos, aSubValue); - if (!aDescendant2.IsEmpty()) + CDescendant &descendant2 = node.Descendants[i]; + TestRemoveAndNormalizeDescendant(descendant2, limitPos, subValue); + if (!descendant2.IsEmpty()) { - aNumChilds++; - aChildIndex = i; + numChilds++; + childIndex = i; } } - if (aNumChilds > 1) + if (numChilds > 1) { - aNode.LastMatch = aNode.LastMatch - aSubValue; + node.LastMatch = node.LastMatch - subValue; return; } - CIndex aNodePointerTemp = aDescendant.NodePointer; - if (aNumChilds == 1) + CIndex nodePointerTemp = descendant.NodePointer; + if (numChilds == 1) { - const CDescendant &aDescendant2 = aNode.Descendants[aChildIndex]; - if (aDescendant2.IsNode()) - m_Nodes[aDescendant2.NodePointer].NumSameBits += aNode.NumSameBits + kNumSubBits; - aDescendant = aDescendant2; + const CDescendant &descendant2 = node.Descendants[childIndex]; + if (descendant2.IsNode()) + m_Nodes[descendant2.NodePointer].NumSameBits += node.NumSameBits + kNumSubBits; + descendant = descendant2; } else - aDescendant.MakeEmpty(); - aNode.NextFreeNode = m_FreeNode; - m_FreeNode = aNodePointerTemp; + descendant.MakeEmpty(); + node.NextFreeNode = m_FreeNode; + m_FreeNode = nodePointerTemp; m_NumUsedNodes--; } void CPatricia::TestRemoveNodesAndNormalize() { - UINT32 aSubValue = _pos - _sizeHistory; - UINT32 aLimitPos = kMatchStartValue + _pos - _sizeHistory + kNumHashBytes; - CLZInWindow::ReduceOffsets(aSubValue); + UInt32 subValue = _pos - _sizeHistory; + UInt32 limitPos = kMatchStartValue + _pos - _sizeHistory + kNumHashBytes; + CLZInWindow::ReduceOffsets(subValue); #ifdef __HASH_3 - UINT32 aLimitPos2 = kMatchStartValue2 + _pos - _sizeHistory + kNumHashBytes; - for(UINT32 aHash = 0; aHash < kHash2Size; aHash++) + UInt32 limitPos2 = kMatchStartValue2 + _pos - _sizeHistory + kNumHashBytes; + for(UInt32 hash = 0; hash < kHash2Size; hash++) { - CDescendant &aDescendant = m_Hash2Descendants[aHash]; - if (aDescendant.MatchPointer != kDescendantsNotInitilized2) + CDescendant &descendant = m_Hash2Descendants[hash]; + if (descendant.MatchPointer != kDescendantsNotInitilized2) { - UINT32 aBase = aHash << 8; - for (UINT32 i = 0; i < 0x100; i++) - TestRemoveAndNormalizeDescendant(m_HashDescendants[aBase + i], aLimitPos, aSubValue); + UInt32 base = hash << 8; + for (UInt32 i = 0; i < 0x100; i++) + TestRemoveAndNormalizeDescendant(m_HashDescendants[base + i], limitPos, subValue); } - if (aDescendant.MatchPointer < kMatchStartValue2) + if (descendant.MatchPointer < kMatchStartValue2) continue; - if (aDescendant.MatchPointer < aLimitPos2) - aDescendant.MatchPointer = kDescendantEmptyValue2; + if (descendant.MatchPointer < limitPos2) + descendant.MatchPointer = kDescendantEmptyValue2; else - aDescendant.MatchPointer = aDescendant.MatchPointer - aSubValue; + descendant.MatchPointer = descendant.MatchPointer - subValue; } #else - for(UINT32 aHash = 0; aHash < kHashSize; aHash++) - TestRemoveAndNormalizeDescendant(m_HashDescendants[aHash], aLimitPos, aSubValue); + for(UInt32 hash = 0; hash < kHashSize; hash++) + TestRemoveAndNormalizeDescendant(m_HashDescendants[hash], limitPos, subValue); #endif } #endif -STDMETHODIMP_(BYTE) CPatricia::GetIndexByte(UINT32 anIndex) +STDMETHODIMP_(Byte) CPatricia::GetIndexByte(Int32 index) { - return CLZInWindow::GetIndexByte(anIndex); + return CLZInWindow::GetIndexByte(index); } -STDMETHODIMP_(UINT32) CPatricia::GetMatchLen(UINT32 aIndex, UINT32 aBack, UINT32 aLimit) +STDMETHODIMP_(UInt32) CPatricia::GetMatchLen(Int32 index, UInt32 back, UInt32 limit) { - return CLZInWindow::GetMatchLen(aIndex, aBack, aLimit); + return CLZInWindow::GetMatchLen(index, back, limit); } -STDMETHODIMP_(UINT32) CPatricia::GetNumAvailableBytes() +STDMETHODIMP_(UInt32) CPatricia::GetNumAvailableBytes() { return CLZInWindow::GetNumAvailableBytes(); } -STDMETHODIMP_(const BYTE *) CPatricia::GetPointerToCurrentPos() +STDMETHODIMP_(const Byte *) CPatricia::GetPointerToCurrentPos() { return CLZInWindow::GetPointerToCurrentPos(); } diff --git a/7zip/Compress/LZ/StdAfx.h b/7zip/Compress/LZ/StdAfx.h index a32fbed6..3ff6d8a2 100755 --- a/7zip/Compress/LZ/StdAfx.h +++ b/7zip/Compress/LZ/StdAfx.h @@ -1,8 +1,6 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> - #endif diff --git a/7zip/Compress/LZMA/DllExports.cpp b/7zip/Compress/LZMA/DllExports.cpp index 043e2e93..81c75007 100755 --- a/7zip/Compress/LZMA/DllExports.cpp +++ b/7zip/Compress/LZMA/DllExports.cpp @@ -2,12 +2,12 @@ #include "StdAfx.h" -// #include <initguid.h> -#define INITGUID +#include "../../../Common/MyInitGuid.h" +#include "../../../Common/ComTry.h" #include "LZMAEncoder.h" #include "LZMADecoder.h" -#include "../../../Common/ComTry.h" +// #include "../../../Common/CRC.h" // {23170F69-40C1-278B-0301-010000000000} DEFINE_GUID(CLSID_CLZMADecoder, @@ -20,11 +20,15 @@ DEFINE_GUID(CLSID_CLZMAEncoder, extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) { + // NCompress::NRangeCoder::g_PriceTables.Init(); + // CCRC::InitTable(); return TRUE; } STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) { + // NCompress::NRangeCoder::g_PriceTables.Init(); + // CCRC::InitTable(); COM_TRY_BEGIN *outObject = 0; int correctInterface = (*iid == IID_ICompressCoder); diff --git a/7zip/Compress/LZMA/LZMA.dsp b/7zip/Compress/LZMA/LZMA.dsp index d52308ec..253b619d 100755 --- a/7zip/Compress/LZMA/LZMA.dsp +++ b/7zip/Compress/LZMA/LZMA.dsp @@ -43,7 +43,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 1 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMA_EXPORTS" /YX /FD /c -# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "../../../" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMA_EXPORTS" /D "COMPRESS_MF_BT" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_HC" /D "COMPRESS_MF_MT" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "../../../" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMA_EXPORTS" /D "COMPRESS_MF_MT" /Yu"StdAfx.h" /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "NDEBUG" @@ -70,7 +70,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 1 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMA_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "../../../" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMA_EXPORTS" /D "COMPRESS_MF_BT" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_HC" /D "COMPRESS_MF_MT" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "../../../" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMA_EXPORTS" /D "COMPRESS_MF_MT" /Yu"StdAfx.h" /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "_DEBUG" @@ -170,10 +170,6 @@ SOURCE=..\MatchFinders\IMatchFinder.h # End Source File # Begin Source File -SOURCE=..\..\IMyUnknown.h -# End Source File -# Begin Source File - SOURCE=..\..\IStream.h # End Source File # End Group @@ -261,14 +257,6 @@ SOURCE=..\LZ\BinTree\BinTree4b.h SOURCE=..\LZ\BinTree\BinTreeMain.h # End Source File -# Begin Source File - -SOURCE=..\LZ\BinTree\BinTreeMF.h -# End Source File -# Begin Source File - -SOURCE=..\LZ\BinTree\BinTreeMFMain.h -# End Source File # End Group # Begin Group "HC" @@ -297,14 +285,6 @@ SOURCE=..\LZ\HashChain\HC4b.h SOURCE=..\LZ\HashChain\HCMain.h # End Source File -# Begin Source File - -SOURCE=..\LZ\HashChain\HCMF.h -# End Source File -# Begin Source File - -SOURCE=..\LZ\HashChain\HCMFMain.h -# End Source File # End Group # Begin Source File @@ -340,6 +320,14 @@ SOURCE=..\..\..\Common\AlignedBuffer.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\ComTry.h # End Source File # Begin Source File @@ -364,6 +352,14 @@ SOURCE=..\..\..\Common\MyCom.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\MyUnknown.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyWindows.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\NewHandler.cpp # End Source File # Begin Source File @@ -376,12 +372,20 @@ SOURCE=..\..\..\Common\NewHandler.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\..\Windows\Handle.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\Synchronization.cpp # End Source File # Begin Source File SOURCE=..\..\..\Windows\Synchronization.h # End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Thread.h +# End Source File # End Group # Begin Source File @@ -423,41 +427,5 @@ SOURCE=.\LZMAEncoder.cpp SOURCE=.\LZMAEncoder.h # End Source File -# Begin Source File - -SOURCE=.\LZMALen.cpp - -!IF "$(CFG)" == "LZMA - Win32 Release" - -# ADD CPP /O2 -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "LZMA - Win32 Debug" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\LZMALen.h -# End Source File -# Begin Source File - -SOURCE=.\LZMALiteral.cpp - -!IF "$(CFG)" == "LZMA - Win32 Release" - -# ADD CPP /O2 -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "LZMA - Win32 Debug" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\LZMALiteral.h -# End Source File # End Target # End Project diff --git a/7zip/Compress/LZMA/LZMA.h b/7zip/Compress/LZMA/LZMA.h index f6e2d8d3..7bc4c438 100755 --- a/7zip/Compress/LZMA/LZMA.h +++ b/7zip/Compress/LZMA/LZMA.h @@ -1,55 +1,30 @@ // LZMA.h -// #pragma once - -#include "LZMALen.h" - #ifndef __LZMA_H #define __LZMA_H namespace NCompress { namespace NLZMA { -const UINT32 kNumRepDistances = 4; +const UInt32 kNumRepDistances = 4; -const BYTE kNumStates = 12; +const int kNumStates = 12; -const BYTE kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5}; -const BYTE kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10}; -const BYTE kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11}; -const BYTE kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11}; +const Byte kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5}; +const Byte kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10}; +const Byte kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11}; +const Byte kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11}; class CState { public: - BYTE Index; - void Init() - { Index = 0; } - void UpdateChar() - { Index = kLiteralNextStates[Index]; } - void UpdateMatch() - { Index = kMatchNextStates[Index]; } - void UpdateRep() - { Index = kRepNextStates[Index]; } - void UpdateShortRep() - { Index = kShortRepNextStates[Index]; } -}; - -class CBaseCoder -{ -protected: - CState _state; - BYTE _previousByte; - bool _peviousIsMatch; - UINT32 _repDistances[kNumRepDistances]; - void Init() - { - _state.Init(); - _previousByte = 0; - _peviousIsMatch = false; - for(int i = 0 ; i < kNumRepDistances; i++) - _repDistances[i] = 0; - } + Byte Index; + void Init() { Index = 0; } + void UpdateChar() { Index = kLiteralNextStates[Index]; } + void UpdateMatch() { Index = kMatchNextStates[Index]; } + void UpdateRep() { Index = kRepNextStates[Index]; } + void UpdateShortRep() { Index = kShortRepNextStates[Index]; } + bool IsCharState() const { return Index < 7; } }; const int kNumPosSlotBits = 6; @@ -57,8 +32,9 @@ const int kDicLogSizeMin = 0; const int kDicLogSizeMax = 32; const int kDistTableSizeMax = kDicLogSizeMax * 2; -const UINT32 kNumLenToPosStates = 4; -inline UINT32 GetLenToPosState(UINT32 len) +const UInt32 kNumLenToPosStates = 4; + +inline UInt32 GetLenToPosState(UInt32 len) { len -= 2; if (len < kNumLenToPosStates) @@ -66,31 +42,41 @@ inline UINT32 GetLenToPosState(UINT32 len) return kNumLenToPosStates - 1; } -const UINT32 kMatchMinLen = 2; +namespace NLength { -const UINT32 kMatchMaxLen = kMatchMinLen + NLength::kNumSymbolsTotal - 1; +const int kNumPosStatesBitsMax = 4; +const UInt32 kNumPosStatesMax = (1 << kNumPosStatesBitsMax); -const int kNumAlignBits = 4; -const UINT32 kAlignTableSize = 1 << kNumAlignBits; -const UINT32 kAlignMask = (kAlignTableSize - 1); +const int kNumPosStatesBitsEncodingMax = 4; +const UInt32 kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax); -const UINT32 kStartPosModelIndex = 4; -const UINT32 kEndPosModelIndex = 14; -const UINT32 kNumPosModels = kEndPosModelIndex - kStartPosModelIndex; +const int kNumLowBits = 3; +const int kNumMidBits = 3; +const int kNumHighBits = 8; +const UInt32 kNumLowSymbols = 1 << kNumLowBits; +const UInt32 kNumMidSymbols = 1 << kNumMidBits; +const UInt32 kNumSymbolsTotal = kNumLowSymbols + kNumMidSymbols + (1 << kNumHighBits); -const UINT32 kNumFullDistances = 1 << (kEndPosModelIndex / 2); +} -const UINT32 kMainChoiceLiteralIndex = 0; -const UINT32 kMainChoiceMatchIndex = 1; +const UInt32 kMatchMinLen = 2; +const UInt32 kMatchMaxLen = kMatchMinLen + NLength::kNumSymbolsTotal - 1; -const UINT32 kMatchChoiceDistanceIndex= 0; -const UINT32 kMatchChoiceRepetitionIndex = 1; +const int kNumAlignBits = 4; +const UInt32 kAlignTableSize = 1 << kNumAlignBits; +const UInt32 kAlignMask = (kAlignTableSize - 1); -const int kNumMoveBits = 5; +const UInt32 kStartPosModelIndex = 4; +const UInt32 kEndPosModelIndex = 14; +const UInt32 kNumPosModels = kEndPosModelIndex - kStartPosModelIndex; + +const UInt32 kNumFullDistances = 1 << (kEndPosModelIndex / 2); const int kNumLitPosStatesBitsEncodingMax = 4; const int kNumLitContextBitsMax = 8; +const int kNumMoveBits = 5; + }} #endif diff --git a/7zip/Compress/LZMA/LZMADecoder.cpp b/7zip/Compress/LZMA/LZMADecoder.cpp index 18374db7..0863186b 100755 --- a/7zip/Compress/LZMA/LZMADecoder.cpp +++ b/7zip/Compress/LZMA/LZMADecoder.cpp @@ -4,353 +4,353 @@ #include "LZMADecoder.h" #include "../../../Common/Defs.h" -#include "../../../Common/ComTry.h" -/* -#include "fstream.h" -#include "iomanip.h" - -ofstream ofs("res.dat"); - -const int kNumCounters = 3; -UINT32 g_Counter[kNumCounters]; -class C1 -{ -public: - ~C1() - { - for (int i = 0; i < kNumCounters; i++) - ofs << setw(10) << g_Counter[i] << endl; - } -} g_C1; -*/ +namespace NCompress { +namespace NLZMA { -/* -const UINT32 kLenTableMax = 20; -const UINT32 kNumDists = NCompress::NLZMA::kDistTableSizeMax / 2; -UINT32 g_Counts[kLenTableMax][kNumDists]; -class C1 +void CDecoder::Init() { -public: - ~C1 () - { - UINT32 sums[kLenTableMax]; - for (int len = 2; len < kLenTableMax; len++) + { + for(int i = 0; i < kNumStates; i++) { - sums[len] = 0; - for (int dist = 0; dist < kNumDists; dist++) - sums[len] += g_Counts[len][dist]; - if (sums[len] == 0) - sums[len] = 1; - } - for (int dist = 0; dist < kNumDists; dist++) - { - ofs << setw(4) << dist << " "; - for (int len = 2; len < kLenTableMax; len++) + for (UInt32 j = 0; j <= _posStateMask; j++) { - ofs << setw(4) << g_Counts[len][dist] * 1000 / sums[len]; + _isMatch[i][j].Init(); + _isRep0Long[i][j].Init(); } - ofs << endl; + _isRep[i].Init(); + _isRepG0[i].Init(); + _isRepG1[i].Init(); + _isRepG2[i].Init(); } } -} g_Class; + { + for (UInt32 i = 0; i < kNumLenToPosStates; i++) + _posSlotDecoder[i].Init(); + } + { + for(UInt32 i = 0; i < kNumFullDistances - kEndPosModelIndex; i++) + _posDecoders[i].Init(); + } + _posAlignDecoder.Init(); + _lenDecoder.Init(_posStateMask + 1); + _repMatchLenDecoder.Init(_posStateMask + 1); + _literalDecoder.Init(); -void UpdateStat(UINT32 len, UINT32 dist) -{ - if (len >= kLenTableMax) - len = kLenTableMax - 1; - g_Counts[len][dist / 2]++; + _state.Init(); + _reps[0] = _reps[1] = _reps[2] = _reps[3] = 0; } -*/ - -namespace NCompress { -namespace NLZMA { -HRESULT CDecoder::SetDictionarySize(UINT32 dictionarySize) +HRESULT CDecoder::CodeSpec(Byte *buffer, UInt32 curSize) { - if (_dictionarySize != dictionarySize) + if (_remainLen == -1) + return S_OK; + if (_remainLen == -2) { - _dictionarySize = dictionarySize; - _dictionarySizeCheck = MyMax(_dictionarySize, UINT32(1)); - UINT32 blockSize = MyMax(_dictionarySizeCheck, UINT32(1 << 12)); - try - { - _outWindowStream.Create(blockSize /*, kMatchMaxLen */); - } - catch(...) - { - return E_OUTOFMEMORY; - } + _rangeDecoder.Init(); + Init(); + _remainLen = 0; } - return S_OK; -} + if (curSize == 0) + return S_OK; -HRESULT CDecoder::SetLiteralProperties( - UINT32 numLiteralPosStateBits, UINT32 numLiteralContextBits) -{ - if (numLiteralPosStateBits > 8) - return E_INVALIDARG; - if (numLiteralContextBits > 8) - return E_INVALIDARG; - _literalDecoder.Create(numLiteralPosStateBits, numLiteralContextBits); - return S_OK; -} + UInt64 nowPos64 = _nowPos64; -HRESULT CDecoder::SetPosBitsProperties(UINT32 numPosStateBits) -{ - if (numPosStateBits > NLength::kNumPosStatesBitsMax) - return E_INVALIDARG; - UINT32 numPosStates = 1 << numPosStateBits; - _lenDecoder.Create(numPosStates); - _repMatchLenDecoder.Create(numPosStates); - _posStateMask = numPosStates - 1; - return S_OK; -} - -CDecoder::CDecoder(): - _dictionarySize((UINT32)-1) -{ - Create(); -} - -HRESULT CDecoder::Create() -{ - COM_TRY_BEGIN - for(int i = 0; i < kNumPosModels; i++) - _posDecoders[i].Create(((kStartPosModelIndex + i) >> 1) - 1); - COM_TRY_END - return S_OK; -} - - -HRESULT CDecoder::Init(ISequentialInStream *inStream, - ISequentialOutStream *outStream) -{ - _rangeDecoder.Init(inStream); - - _outWindowStream.Init(outStream); + UInt32 rep0 = _reps[0]; + UInt32 rep1 = _reps[1]; + UInt32 rep2 = _reps[2]; + UInt32 rep3 = _reps[3]; + CState state = _state; + Byte previousByte; - int i; - for(i = 0; i < kNumStates; i++) + while(_remainLen > 0 && curSize > 0) { - for (UINT32 j = 0; j <= _posStateMask; j++) - { - _mainChoiceDecoders[i][j].Init(); - _matchRepShortChoiceDecoders[i][j].Init(); - } - _matchChoiceDecoders[i].Init(); - _matchRepChoiceDecoders[i].Init(); - _matchRep1ChoiceDecoders[i].Init(); - _matchRep2ChoiceDecoders[i].Init(); + previousByte = _outWindowStream.GetByte(rep0); + _outWindowStream.PutByte(previousByte); + if (buffer) + *buffer++ = previousByte; + nowPos64++; + _remainLen--; + curSize--; } - - _literalDecoder.Init(); - - // _repMatchLenDecoder.Init(); - - for (i = 0; i < kNumLenToPosStates; i++) - _posSlotDecoder[i].Init(); - - for(i = 0; i < kNumPosModels; i++) - _posDecoders[i].Init(); - - _lenDecoder.Init(); - _repMatchLenDecoder.Init(); - - _posAlignDecoder.Init(); - return S_OK; - -} - - - -STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, - ISequentialOutStream *outStream, - const UINT64 *inSize, const UINT64 *outSize, - ICompressProgressInfo *progress) -{ - /* - if (outSize == NULL) - return E_INVALIDARG; - */ - - Init(inStream, outStream); - CDecoderFlusher flusher(this); - - CState state; - state.Init(); - bool peviousIsMatch = false; - BYTE previousByte = 0; - UINT32 repDistances[kNumRepDistances]; - for(int i = 0 ; i < kNumRepDistances; i++) - repDistances[i] = 0; + if (nowPos64 == 0) + previousByte = 0; + else + previousByte = _outWindowStream.GetByte(0); - UINT64 nowPos64 = 0; - UINT64 size = (outSize == NULL) ? (UINT64)(INT64)(-1) : *outSize; - while(nowPos64 < size) + while(curSize > 0) { - UINT64 nextPos = MyMin(nowPos64 + (1 << 18), size); - while(nowPos64 < nextPos) { - UINT32 posState = UINT32(nowPos64) & _posStateMask; - if (_mainChoiceDecoders[state.Index][posState].Decode(&_rangeDecoder) == kMainChoiceLiteralIndex) + #ifdef _NO_EXCEPTIONS + if (_rangeDecoder.Stream.ErrorCode != S_OK) + return _rangeDecoder.Stream.ErrorCode; + #endif + if (_rangeDecoder.Stream.WasFinished()) + return S_FALSE; + UInt32 posState = UInt32(nowPos64) & _posStateMask; + if (_isMatch[state.Index][posState].Decode(&_rangeDecoder) == 0) { - state.UpdateChar(); - if(peviousIsMatch) - { - BYTE matchByte = _outWindowStream.GetOneByte(0 - repDistances[0] - 1); + if(!state.IsCharState()) previousByte = _literalDecoder.DecodeWithMatchByte(&_rangeDecoder, - UINT32(nowPos64), previousByte, matchByte); - peviousIsMatch = false; - } + (UInt32)nowPos64, previousByte, _outWindowStream.GetByte(rep0)); else previousByte = _literalDecoder.DecodeNormal(&_rangeDecoder, - UINT32(nowPos64), previousByte); - _outWindowStream.PutOneByte(previousByte); + (UInt32)nowPos64, previousByte); + _outWindowStream.PutByte(previousByte); + if (buffer) + *buffer++ = previousByte; + state.UpdateChar(); + curSize--; nowPos64++; } else { - peviousIsMatch = true; - UINT32 distance, len; - if(_matchChoiceDecoders[state.Index].Decode(&_rangeDecoder) == - kMatchChoiceRepetitionIndex) + UInt32 len; + if(_isRep[state.Index].Decode(&_rangeDecoder) == 1) { - if(_matchRepChoiceDecoders[state.Index].Decode(&_rangeDecoder) == 0) + if(_isRepG0[state.Index].Decode(&_rangeDecoder) == 0) { - if(_matchRepShortChoiceDecoders[state.Index][posState].Decode(&_rangeDecoder) == 0) + if(_isRep0Long[state.Index][posState].Decode(&_rangeDecoder) == 0) { + if (nowPos64 == 0) + return S_FALSE; state.UpdateShortRep(); - previousByte = _outWindowStream.GetOneByte(0 - repDistances[0] - 1); - _outWindowStream.PutOneByte(previousByte); + previousByte = _outWindowStream.GetByte(rep0); + _outWindowStream.PutByte(previousByte); + if (buffer) + *buffer++ = previousByte; + curSize--; nowPos64++; continue; } - distance = repDistances[0]; } else { - if(_matchRep1ChoiceDecoders[state.Index].Decode(&_rangeDecoder) == 0) - distance = repDistances[1]; + UInt32 distance; + if(_isRepG1[state.Index].Decode(&_rangeDecoder) == 0) + distance = rep1; else { - if (_matchRep2ChoiceDecoders[state.Index].Decode(&_rangeDecoder) == 0) - distance = repDistances[2]; + if (_isRepG2[state.Index].Decode(&_rangeDecoder) == 0) + distance = rep2; else { - distance = repDistances[3]; - repDistances[3] = repDistances[2]; + distance = rep3; + rep3 = rep2; } - repDistances[2] = repDistances[1]; + rep2 = rep1; } - repDistances[1] = repDistances[0]; - repDistances[0] = distance; + rep1 = rep0; + rep0 = distance; } len = _repMatchLenDecoder.Decode(&_rangeDecoder, posState) + kMatchMinLen; state.UpdateRep(); } else { + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; len = kMatchMinLen + _lenDecoder.Decode(&_rangeDecoder, posState); state.UpdateMatch(); - UINT32 posSlot = _posSlotDecoder[GetLenToPosState(len)].Decode(&_rangeDecoder); + UInt32 posSlot = _posSlotDecoder[GetLenToPosState(len)].Decode(&_rangeDecoder); if (posSlot >= kStartPosModelIndex) { - UINT32 numDirectBits = (posSlot >> 1) - 1; - distance = ((2 | (posSlot & 1)) << numDirectBits); + UInt32 numDirectBits = (posSlot >> 1) - 1; + rep0 = ((2 | (posSlot & 1)) << numDirectBits); if (posSlot < kEndPosModelIndex) - distance += _posDecoders[posSlot - kStartPosModelIndex].Decode(&_rangeDecoder); + rep0 += NRangeCoder::ReverseBitTreeDecode(_posDecoders + + rep0 - posSlot - 1, &_rangeDecoder, numDirectBits); else { - distance += (_rangeDecoder.DecodeDirectBits( + rep0 += (_rangeDecoder.DecodeDirectBits( numDirectBits - kNumAlignBits) << kNumAlignBits); - distance += _posAlignDecoder.Decode(&_rangeDecoder); + rep0 += _posAlignDecoder.ReverseDecode(&_rangeDecoder); } } else - distance = posSlot; - - repDistances[3] = repDistances[2]; - repDistances[2] = repDistances[1]; - repDistances[1] = repDistances[0]; - repDistances[0] = distance; - // UpdateStat(len, posSlot); + rep0 = posSlot; + if (rep0 >= nowPos64 || rep0 >= _dictionarySizeCheck) + { + if (rep0 != (UInt32)(Int32)(-1)) + return S_FALSE; + _nowPos64 = nowPos64; + _remainLen = -1; + return S_OK; + } } - if (distance >= nowPos64 || distance >= _dictionarySizeCheck) + UInt32 locLen = len; + if (len > curSize) + locLen = (UInt32)curSize; + if (buffer) { - if (distance == (UINT32)(-1) && size == (UINT64)(INT64)(-1)) + for (UInt32 i = locLen; i != 0; i--) { - flusher.NeedFlush = false; - return Flush(); + previousByte = _outWindowStream.GetByte(rep0); + *buffer++ = previousByte; + _outWindowStream.PutByte(previousByte); } - throw "data error"; } - _outWindowStream.CopyBackBlock(distance, len); - nowPos64 += len; - previousByte = _outWindowStream.GetOneByte(0 - 1); + else + { + _outWindowStream.CopyBlock(rep0, locLen); + previousByte = _outWindowStream.GetByte(0); + } + curSize -= locLen; + nowPos64 += locLen; + len -= locLen; + if (len != 0) + { + _remainLen = (Int32)len; + break; + } + + #ifdef _NO_EXCEPTIONS + if (_outWindowStream.ErrorCode != S_OK) + return _outWindowStream.ErrorCode; + #endif } } + } + if (_rangeDecoder.Stream.WasFinished()) + return S_FALSE; + _nowPos64 = nowPos64; + _reps[0] = rep0; + _reps[1] = rep1; + _reps[2] = rep2; + _reps[3] = rep3; + _state = state; + + return S_OK; +} + +STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 *, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + SetInStream(inStream); + _outWindowStream.SetStream(outStream); + SetOutStreamSize(outSize); + CDecoderFlusher flusher(this); + + while (true) + { + UInt32 curSize = 1 << 18; + if (_outSize != (UInt64)(Int64)(-1)) + if (curSize > _outSize - _nowPos64) + curSize = (UInt32)(_outSize - _nowPos64); + RINOK(CodeSpec(0, curSize)); + if (_remainLen == -1) + break; if (progress != NULL) { - UINT64 inSize = _rangeDecoder.GetProcessedSize(); - RINOK(progress->SetRatioInfo(&inSize, &nowPos64)); + UInt64 inSize = _rangeDecoder.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&inSize, &_nowPos64)); } - } + if (_outSize != (UInt64)(Int64)(-1)) + if (_nowPos64 >= _outSize) + break; + } flusher.NeedFlush = false; return Flush(); } STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { - try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + #ifndef _NO_EXCEPTIONS + try + { + #endif + return CodeReal(inStream, outStream, inSize, outSize, progress); + #ifndef _NO_EXCEPTIONS + } catch(const CInBufferException &e) { return e.ErrorCode; } catch(const CLZOutWindowException &e) { return e.ErrorCode; } catch(...) { return S_FALSE; } + #endif } - -static HRESULT DecodeProperties(ISequentialInStream *inStream, - UINT32 &numPosStateBits, - UINT32 &numLiteralPosStateBits, - UINT32 &numLiteralContextBits, - UINT32 &dictionarySize) +STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *properties, UInt32 size) { - UINT32 processesedSize; - - BYTE firstByte; - RINOK(inStream->Read(&firstByte, sizeof(firstByte), &processesedSize)); - if (processesedSize != sizeof(firstByte)) + if (size < 5) + return E_INVALIDARG; + int lc = properties[0] % 9; + Byte remainder = (Byte)(properties[0] / 9); + int lp = remainder % 5; + int pb = remainder / 5; + if (pb > NLength::kNumPosStatesBitsMax) return E_INVALIDARG; + _posStateMask = (1 << pb) - 1; + UInt32 dictionarySize = 0; + for (int i = 0; i < 4; i++) + dictionarySize += ((UInt32)(properties[1 + i])) << (i * 8); + _dictionarySizeCheck = MyMax(dictionarySize, UInt32(1)); + UInt32 blockSize = MyMax(_dictionarySizeCheck, UInt32(1 << 12)); + if (!_outWindowStream.Create(blockSize)) + return E_OUTOFMEMORY; + if (!_literalDecoder.Create(lp, lc)) + return E_OUTOFMEMORY; + if (!_rangeDecoder.Create(1 << 20)) + return E_OUTOFMEMORY; + return S_OK; +} - numLiteralContextBits = firstByte % 9; - BYTE remainder = firstByte / 9; - numLiteralPosStateBits = remainder % 5; - numPosStateBits = remainder / 5; +STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value) +{ + *value = _rangeDecoder.GetProcessedSize(); + return S_OK; +} - RINOK(inStream->Read(&dictionarySize, sizeof(dictionarySize), &processesedSize)); - if (processesedSize != sizeof(dictionarySize)) - return E_INVALIDARG; +STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) +{ + _rangeDecoder.SetStream(inStream); return S_OK; } -STDMETHODIMP CDecoder::SetDecoderProperties(ISequentialInStream *inStream) +STDMETHODIMP CDecoder::ReleaseInStream() { - UINT32 numPosStateBits; - UINT32 numLiteralPosStateBits; - UINT32 numLiteralContextBits; - UINT32 dictionarySize; - RINOK(DecodeProperties(inStream, - numPosStateBits, - numLiteralPosStateBits, - numLiteralContextBits, - dictionarySize)); - RINOK(SetDictionarySize(dictionarySize)); - RINOK(SetLiteralProperties(numLiteralPosStateBits, numLiteralContextBits)); - RINOK(SetPosBitsProperties(numPosStateBits)); + _rangeDecoder.ReleaseStream(); return S_OK; } +STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) +{ + _outSize = (outSize == NULL) ? (UInt64)(Int64)(-1) : *outSize; + _nowPos64 = 0; + _remainLen = -2; // -2 means need_init + _outWindowStream.Init(); + return S_OK; +} + +STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + #ifndef _NO_EXCEPTIONS + try + { + #endif + UInt64 startPos = _nowPos64; + if (_outSize != (UInt64)(Int64)(-1)) + if (size > _outSize - _nowPos64) + size = (UInt32)(_outSize - _nowPos64); + HRESULT res = CodeSpec((Byte *)data, size); + if (processedSize) + *processedSize = (UInt32)(_nowPos64 - startPos); + return res; + #ifndef _NO_EXCEPTIONS + } + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(const CLZOutWindowException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } + #endif +} + +STDMETHODIMP CDecoder::ReadPart(void *data, UInt32 size, UInt32 *processedSize) +{ + return Read(data, size, processedSize); +} + }} diff --git a/7zip/Compress/LZMA/LZMADecoder.h b/7zip/Compress/LZMA/LZMADecoder.h index 28350963..5cfd72ad 100755 --- a/7zip/Compress/LZMA/LZMADecoder.h +++ b/7zip/Compress/LZMA/LZMADecoder.h @@ -1,105 +1,237 @@ // LZMA/Decoder.h -// #pragma once - #ifndef __LZMA_DECODER_H #define __LZMA_DECODER_H -#include "../../ICoder.h" #include "../../../Common/MyCom.h" +#include "../../../Common/Alloc.h" +#include "../../ICoder.h" #include "../LZ/LZOutWindow.h" +#include "../RangeCoder/RangeCoderBitTree.h" #include "LZMA.h" -#include "LZMALen.h" -#include "LZMALiteral.h" namespace NCompress { namespace NLZMA { typedef NRangeCoder::CBitDecoder<kNumMoveBits> CMyBitDecoder; +class CLiteralDecoder2 +{ + CMyBitDecoder _decoders[0x300]; +public: + void Init() + { + for (int i = 0; i < 0x300; i++) + _decoders[i].Init(); + } + Byte DecodeNormal(NRangeCoder::CDecoder *rangeDecoder) + { + UInt32 symbol = 1; + RC_INIT_VAR + do + { + // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder); + RC_GETBIT(kNumMoveBits, _decoders[symbol].Prob, symbol) + } + while (symbol < 0x100); + RC_FLUSH_VAR + return (Byte)symbol; + } + Byte DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, Byte matchByte) + { + UInt32 symbol = 1; + RC_INIT_VAR + do + { + UInt32 matchBit = (matchByte >> 7) & 1; + matchByte <<= 1; + // UInt32 bit = _decoders[1 + matchBit][symbol].Decode(rangeDecoder); + // symbol = (symbol << 1) | bit; + UInt32 bit; + RC_GETBIT2(kNumMoveBits, _decoders[0x100 + (matchBit << 8) + symbol].Prob, symbol, + bit = 0, bit = 1) + if (matchBit != bit) + { + while (symbol < 0x100) + { + // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder); + RC_GETBIT(kNumMoveBits, _decoders[symbol].Prob, symbol) + } + break; + } + } + while (symbol < 0x100); + RC_FLUSH_VAR + return (Byte)symbol; + } +}; + +class CLiteralDecoder +{ + CLiteralDecoder2 *_coders; + int _numPrevBits; + int _numPosBits; + UInt32 _posMask; +public: + CLiteralDecoder(): _coders(0) {} + ~CLiteralDecoder() { Free(); } + void Free() + { + MyFree(_coders); + _coders = 0; + } + bool Create(int numPosBits, int numPrevBits) + { + if (_coders == 0 || (numPosBits + numPrevBits) != + (_numPrevBits + _numPosBits) ) + { + Free(); + UInt32 numStates = 1 << (numPosBits + numPrevBits); + _coders = (CLiteralDecoder2 *)MyAlloc(numStates * sizeof(CLiteralDecoder2)); + } + _numPosBits = numPosBits; + _posMask = (1 << numPosBits) - 1; + _numPrevBits = numPrevBits; + return (_coders != 0); + } + void Init() + { + UInt32 numStates = 1 << (_numPrevBits + _numPosBits); + for (UInt32 i = 0; i < numStates; i++) + _coders[i].Init(); + } + UInt32 GetState(UInt32 pos, Byte prevByte) const + { return ((pos & _posMask) << _numPrevBits) + (prevByte >> (8 - _numPrevBits)); } + Byte DecodeNormal(NRangeCoder::CDecoder *rangeDecoder, UInt32 pos, Byte prevByte) + { return _coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); } + Byte DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, UInt32 pos, Byte prevByte, Byte matchByte) + { return _coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); } +}; + +namespace NLength { + +class CDecoder +{ + CMyBitDecoder _choice; + CMyBitDecoder _choice2; + NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumLowBits> _lowCoder[kNumPosStatesMax]; + NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumMidBits> _midCoder[kNumPosStatesMax]; + NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumHighBits> _highCoder; +public: + void Init(UInt32 numPosStates) + { + _choice.Init(); + _choice2.Init(); + for (UInt32 posState = 0; posState < numPosStates; posState++) + { + _lowCoder[posState].Init(); + _midCoder[posState].Init(); + } + _highCoder.Init(); + } + UInt32 Decode(NRangeCoder::CDecoder *rangeDecoder, UInt32 posState) + { + if(_choice.Decode(rangeDecoder) == 0) + return _lowCoder[posState].Decode(rangeDecoder); + if(_choice2.Decode(rangeDecoder) == 0) + return kNumLowSymbols + _midCoder[posState].Decode(rangeDecoder); + return kNumLowSymbols + kNumMidSymbols + _highCoder.Decode(rangeDecoder); + } +}; + +} + class CDecoder: public ICompressCoder, - public ICompressSetDecoderProperties, + public ICompressSetDecoderProperties2, + public ICompressSetInStream, + public ICompressSetOutStreamSize, + public ISequentialInStream, public CMyUnknownImp { CLZOutWindow _outWindowStream; NRangeCoder::CDecoder _rangeDecoder; - CMyBitDecoder _mainChoiceDecoders[kNumStates][NLength::kNumPosStatesMax]; - CMyBitDecoder _matchChoiceDecoders[kNumStates]; - CMyBitDecoder _matchRepChoiceDecoders[kNumStates]; - CMyBitDecoder _matchRep1ChoiceDecoders[kNumStates]; - CMyBitDecoder _matchRep2ChoiceDecoders[kNumStates]; - CMyBitDecoder _matchRepShortChoiceDecoders[kNumStates][NLength::kNumPosStatesMax]; + CMyBitDecoder _isMatch[kNumStates][NLength::kNumPosStatesMax]; + CMyBitDecoder _isRep[kNumStates]; + CMyBitDecoder _isRepG0[kNumStates]; + CMyBitDecoder _isRepG1[kNumStates]; + CMyBitDecoder _isRepG2[kNumStates]; + CMyBitDecoder _isRep0Long[kNumStates][NLength::kNumPosStatesMax]; NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumPosSlotBits> _posSlotDecoder[kNumLenToPosStates]; - NRangeCoder::CReverseBitTreeDecoder2<kNumMoveBits> _posDecoders[kNumPosModels]; - NRangeCoder::CReverseBitTreeDecoder<kNumMoveBits, kNumAlignBits> _posAlignDecoder; + CMyBitDecoder _posDecoders[kNumFullDistances - kEndPosModelIndex]; + NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumAlignBits> _posAlignDecoder; NLength::CDecoder _lenDecoder; NLength::CDecoder _repMatchLenDecoder; - NLiteral::CDecoder _literalDecoder; + CLiteralDecoder _literalDecoder; - UINT32 _dictionarySize; - UINT32 _dictionarySizeCheck; + UInt32 _dictionarySizeCheck; - UINT32 _posStateMask; - + UInt32 _posStateMask; + + /////////////////// + // State + UInt64 _outSize; + UInt64 _nowPos64; + UInt32 _reps[4]; + CState _state; + Int32 _remainLen; // -1 means end of stream. // -2 means need Init + + void Init(); + HRESULT CodeSpec(Byte *buffer, UInt32 size); public: + MY_UNKNOWN_IMP4( + ICompressSetDecoderProperties2, + ICompressSetInStream, + ICompressSetOutStreamSize, + ISequentialInStream) - MY_UNKNOWN_IMP1(ICompressSetDecoderProperties) - - CDecoder(); - HRESULT Create(); - - - HRESULT Init(ISequentialInStream *inStream, - ISequentialOutStream *outStream); - /* void ReleaseStreams() { _outWindowStream.ReleaseStream(); - _rangeDecoder.ReleaseStream(); + ReleaseInStream(); } - */ class CDecoderFlusher { CDecoder *_decoder; public: bool NeedFlush; - CDecoderFlusher(CDecoder *decoder): - _decoder(decoder), NeedFlush(true) {} + CDecoderFlusher(CDecoder *decoder): _decoder(decoder), NeedFlush(true) {} ~CDecoderFlusher() { if (NeedFlush) _decoder->Flush(); - // _decoder->ReleaseStreams(); + _decoder->ReleaseStreams(); } }; - HRESULT Flush() - { return _outWindowStream.Flush(); } + HRESULT Flush() { return _outWindowStream.Flush(); } - // ICompressCoder interface STDMETHOD(CodeReal)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); STDMETHOD(Code)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - // ICompressSetDecoderProperties - STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream); + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); + + STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); + + STDMETHOD(SetInStream)(ISequentialInStream *inStream); + STDMETHOD(ReleaseInStream)(); + STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); - HRESULT SetDictionarySize(UINT32 dictionarySize); - HRESULT SetLiteralProperties(UINT32 numLiteralPosStateBits, - UINT32 numLiteralContextBits); - HRESULT SetPosBitsProperties(UINT32 numPosStateBits); + virtual ~CDecoder() {} }; }} diff --git a/7zip/Compress/LZMA/LZMAEncoder.cpp b/7zip/Compress/LZMA/LZMAEncoder.cpp index aae4515b..4ad8b1f1 100755 --- a/7zip/Compress/LZMA/LZMAEncoder.cpp +++ b/7zip/Compress/LZMA/LZMAEncoder.cpp @@ -6,12 +6,36 @@ #include "LZMAEncoder.h" +// for minimal compressing code size define these: +// #define COMPRESS_MF_BT +// #define COMPRESS_MF_BT4 + +#if !defined(COMPRESS_MF_BT) && !defined(COMPRESS_MF_PAT) && !defined(COMPRESS_MF_HC) +#define COMPRESS_MF_BT +#define COMPRESS_MF_PAT +#define COMPRESS_MF_HC +#endif + #ifdef COMPRESS_MF_BT +#if !defined(COMPRESS_MF_BT2) && !defined(COMPRESS_MF_BT3) && !defined(COMPRESS_MF_BT4) && !defined(COMPRESS_MF_BT4B) +#define COMPRESS_MF_BT2 +#define COMPRESS_MF_BT3 +#define COMPRESS_MF_BT4 +#define COMPRESS_MF_BT4B +#endif +#ifdef COMPRESS_MF_BT2 #include "../LZ/BinTree/BinTree2.h" +#endif +#ifdef COMPRESS_MF_BT3 #include "../LZ/BinTree/BinTree3.h" +#endif +#ifdef COMPRESS_MF_BT4 #include "../LZ/BinTree/BinTree4.h" +#endif +#ifdef COMPRESS_MF_BT4B #include "../LZ/BinTree/BinTree4b.h" #endif +#endif #ifdef COMPRESS_MF_PAT #include "../LZ/Patricia/Pat2.h" @@ -33,6 +57,9 @@ namespace NCompress { namespace NLZMA { +const int kDefaultDictionaryLogSize = 20; +const UInt32 kNumFastBytesDefault = 0x20; + enum { kBT2, @@ -63,73 +90,206 @@ static const wchar_t *kMatchFinderIDs[] = L"HC4" }; -BYTE g_FastPos[1024]; +Byte g_FastPos[1024]; class CFastPosInit { public: - CFastPosInit() + CFastPosInit() { Init(); } + void Init() { - const BYTE kFastSlots = 20; + const Byte kFastSlots = 20; int c = 2; g_FastPos[0] = 0; g_FastPos[1] = 1; - for (BYTE slotFast = 2; slotFast < kFastSlots; slotFast++) + for (Byte slotFast = 2; slotFast < kFastSlots; slotFast++) { - UINT32 k = (1 << ((slotFast >> 1) - 1)); - for (UINT32 j = 0; j < k; j++, c++) + UInt32 k = (1 << ((slotFast >> 1) - 1)); + for (UInt32 j = 0; j < k; j++, c++) g_FastPos[c] = slotFast; } } } g_FastPosInit; -const int kDefaultDictionaryLogSize = 20; -const UINT32 kNumFastBytesDefault = 0x20; +void CLiteralEncoder2::Encode(NRangeCoder::CEncoder *rangeEncoder, Byte symbol) +{ + UInt32 context = 1; + int i = 8; + do + { + i--; + UInt32 bit = (symbol >> i) & 1; + _encoders[context].Encode(rangeEncoder, bit); + context = (context << 1) | bit; + } + while(i != 0); +} + +void CLiteralEncoder2::EncodeMatched(NRangeCoder::CEncoder *rangeEncoder, + Byte matchByte, Byte symbol) +{ + UInt32 context = 1; + int i = 8; + do + { + i--; + UInt32 bit = (symbol >> i) & 1; + UInt32 matchBit = (matchByte >> i) & 1; + _encoders[0x100 + (matchBit << 8) + context].Encode(rangeEncoder, bit); + context = (context << 1) | bit; + if (matchBit != bit) + { + while(i != 0) + { + i--; + UInt32 bit = (symbol >> i) & 1; + _encoders[context].Encode(rangeEncoder, bit); + context = (context << 1) | bit; + } + break; + } + } + while(i != 0); +} + +UInt32 CLiteralEncoder2::GetPrice(bool matchMode, Byte matchByte, Byte symbol) const +{ + UInt32 price = 0; + UInt32 context = 1; + int i = 8; + if (matchMode) + { + do + { + i--; + UInt32 matchBit = (matchByte >> i) & 1; + UInt32 bit = (symbol >> i) & 1; + price += _encoders[0x100 + (matchBit << 8) + context].GetPrice(bit); + context = (context << 1) | bit; + if (matchBit != bit) + break; + } + while (i != 0); + } + while(i != 0) + { + i--; + UInt32 bit = (symbol >> i) & 1; + price += _encoders[context].GetPrice(bit); + context = (context << 1) | bit; + } + return price; +}; + + +namespace NLength { + +void CEncoder::Init(UInt32 numPosStates) +{ + _choice.Init(); + _choice2.Init(); + for (UInt32 posState = 0; posState < numPosStates; posState++) + { + _lowCoder[posState].Init(); + _midCoder[posState].Init(); + } + _highCoder.Init(); +} + +void CEncoder::Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState) +{ + if(symbol < kNumLowSymbols) + { + _choice.Encode(rangeEncoder, 0); + _lowCoder[posState].Encode(rangeEncoder, symbol); + } + else + { + _choice.Encode(rangeEncoder, 1); + if(symbol < kNumLowSymbols + kNumMidSymbols) + { + _choice2.Encode(rangeEncoder, 0); + _midCoder[posState].Encode(rangeEncoder, symbol - kNumLowSymbols); + } + else + { + _choice2.Encode(rangeEncoder, 1); + _highCoder.Encode(rangeEncoder, symbol - kNumLowSymbols - kNumMidSymbols); + } + } +} + +UInt32 CEncoder::GetPrice(UInt32 symbol, UInt32 posState) const +{ + if(symbol < kNumLowSymbols) + return _choice.GetPrice0() + _lowCoder[posState].GetPrice(symbol); + UInt32 price = _choice.GetPrice1(); + if(symbol < kNumLowSymbols + kNumMidSymbols) + { + price += _choice2.GetPrice0(); + price += _midCoder[posState].GetPrice(symbol - kNumLowSymbols); + } + else + { + price += _choice2.GetPrice1(); + price += _highCoder.GetPrice(symbol - kNumLowSymbols - kNumMidSymbols); + } + return price; +} + +} CEncoder::CEncoder(): - _dictionarySize(1 << kDefaultDictionaryLogSize), - _dictionarySizePrev(UINT32(-1)), _numFastBytes(kNumFastBytesDefault), - _numFastBytesPrev(UINT32(-1)), _distTableSize(kDefaultDictionaryLogSize * 2), _posStateBits(2), _posStateMask(4 - 1), _numLiteralPosStateBits(0), _numLiteralContextBits(3), + _dictionarySize(1 << kDefaultDictionaryLogSize), + _dictionarySizePrev(UInt32(-1)), + _numFastBytesPrev(UInt32(-1)), + _matchFinderIndex(kBT4), #ifdef COMPRESS_MF_MT _multiThread(false), #endif - _matchFinderIndex(kBT4), _writeEndMark(false) { _maxMode = false; _fastMode = false; - _posAlignEncoder.Create(kNumAlignBits); - for(int i = 0; i < kNumPosModels; i++) - _posEncoders[i].Create(((kStartPosModelIndex + i) >> 1) - 1); } HRESULT CEncoder::Create() { + if (!_rangeEncoder.Create(1 << 20)) + return E_OUTOFMEMORY; if (!_matchFinder) { switch(_matchFinderIndex) { #ifdef COMPRESS_MF_BT + #ifdef COMPRESS_MF_BT2 case kBT2: _matchFinder = new NBT2::CMatchFinderBinTree; break; + #endif + #ifdef COMPRESS_MF_BT3 case kBT3: _matchFinder = new NBT3::CMatchFinderBinTree; break; + #endif + #ifdef COMPRESS_MF_BT4 case kBT4: _matchFinder = new NBT4::CMatchFinderBinTree; break; + #endif + #ifdef COMPRESS_MF_BT4B case kBT4B: _matchFinder = new NBT4B::CMatchFinderBinTree; break; #endif + #endif #ifdef COMPRESS_MF_PAT case kPat2: @@ -158,10 +318,15 @@ HRESULT CEncoder::Create() break; #endif } + if (_matchFinder == 0) + return E_OUTOFMEMORY; + #ifdef COMPRESS_MF_MT - if (_multiThread) + if (_multiThread && !(_fastMode && (_matchFinderIndex == kHC3 || _matchFinderIndex == kHC4))) { CMatchFinderMT *mfSpec = new CMatchFinderMT; + if (mfSpec == 0) + return E_OUTOFMEMORY; CMyComPtr<IMatchFinder> mf = mfSpec; RINOK(mfSpec->SetMatchFinder(_matchFinder)); _matchFinder.Release(); @@ -169,39 +334,47 @@ HRESULT CEncoder::Create() } #endif } + + if (!_literalEncoder.Create(_numLiteralPosStateBits, _numLiteralContextBits)) + return E_OUTOFMEMORY; + if (_dictionarySize == _dictionarySizePrev && _numFastBytesPrev == _numFastBytes) return S_OK; RINOK(_matchFinder->Create(_dictionarySize, kNumOpts, _numFastBytes, kMatchMaxLen - _numFastBytes)); _dictionarySizePrev = _dictionarySize; _numFastBytesPrev = _numFastBytes; - _literalEncoder.Create(_numLiteralPosStateBits, _numLiteralContextBits); - _lenEncoder.Create(1 << _posStateBits); - _repMatchLenEncoder.Create(1 << _posStateBits); return S_OK; } -static inline bool AreStringsEqual(const wchar_t *s, const wchar_t *testString) +static bool AreStringsEqual(const wchar_t *base, const wchar_t *testString) { while (true) { wchar_t c = *testString; if (c >= 'a' && c <= 'z') c -= 0x20; - if (*s != c) + if (*base != c) return false; if (c == 0) return true; - s++; + base++; testString++; } } -// ICompressSetEncoderProperties2 +static int FindMatchFinder(const wchar_t *s) +{ + for (int m = 0; m < (int)(sizeof(kMatchFinderIDs) / sizeof(kMatchFinderIDs[0])); m++) + if (AreStringsEqual(kMatchFinderIDs[m], s)) + return m; + return -1; +} + STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, - const PROPVARIANT *properties, UINT32 numProperties) + const PROPVARIANT *properties, UInt32 numProperties) { - for (UINT32 i = 0; i < numProperties; i++) + for (UInt32 i = 0; i < numProperties; i++) { const PROPVARIANT &prop = properties[i]; switch(propIDs[i]) @@ -210,7 +383,7 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, { if (prop.vt != VT_UI4) return E_INVALIDARG; - UINT32 numFastBytes = prop.ulVal; + UInt32 numFastBytes = prop.ulVal; if(numFastBytes < 2 || numFastBytes > kMatchMaxLen) return E_INVALIDARG; _numFastBytes = numFastBytes; @@ -220,7 +393,7 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, { if (prop.vt != VT_UI4) return E_INVALIDARG; - UINT32 maximize = prop.ulVal; + UInt32 maximize = prop.ulVal; _fastMode = (maximize == 0); _maxMode = (maximize >= 2); break; @@ -230,22 +403,13 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, if (prop.vt != VT_BSTR) return E_INVALIDARG; int matchFinderIndexPrev = _matchFinderIndex; - _matchFinderIndex = 0; - const int kNumMFs = sizeof(kMatchFinderIDs) / sizeof(kMatchFinderIDs[0]); - int m; - for (m = 0; m < kNumMFs; m++) - { - if (AreStringsEqual(kMatchFinderIDs[m], prop.bstrVal)) - { - _matchFinderIndex = m; - break; - } - } - if (m == kNumMFs) + int m = FindMatchFinder(prop.bstrVal); + if (m < 0) return E_INVALIDARG; - if (!_matchFinder && matchFinderIndexPrev != _matchFinderIndex) + _matchFinderIndex = m; + if (_matchFinder && matchFinderIndexPrev != _matchFinderIndex) { - _dictionarySizePrev = UINT32(-1); + _dictionarySizePrev = UInt32(-1); _matchFinder.Release(); } break; @@ -255,10 +419,10 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, { if (prop.vt != VT_BOOL) return E_INVALIDARG; - bool newMultiThread = (prop.boolVal != VARIANT_FALSE); + bool newMultiThread = (prop.boolVal == VARIANT_TRUE); if (newMultiThread != _multiThread) { - _dictionarySizePrev = UINT32(-1); + _dictionarySizePrev = UInt32(-1); _matchFinder.Release(); } _multiThread = newMultiThread; @@ -270,14 +434,14 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const int kDicLogSizeMaxCompress = 28; if (prop.vt != VT_UI4) return E_INVALIDARG; - UINT32 dictionarySize = prop.ulVal; - if (dictionarySize < UINT32(1 << kDicLogSizeMin) || - dictionarySize > UINT32(1 << kDicLogSizeMaxCompress)) + UInt32 dictionarySize = prop.ulVal; + if (dictionarySize < UInt32(1 << kDicLogSizeMin) || + dictionarySize > UInt32(1 << kDicLogSizeMaxCompress)) return E_INVALIDARG; _dictionarySize = dictionarySize; - UINT32 dicLogSize; - for(dicLogSize = 0; dicLogSize < kDicLogSizeMaxCompress; dicLogSize++) - if (dictionarySize <= (UINT32(1) << dicLogSize)) + UInt32 dicLogSize; + for(dicLogSize = 0; dicLogSize < (UInt32)kDicLogSizeMaxCompress; dicLogSize++) + if (dictionarySize <= (UInt32(1) << dicLogSize)) break; _distTableSize = dicLogSize * 2; break; @@ -286,8 +450,8 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, { if (prop.vt != VT_UI4) return E_INVALIDARG; - UINT32 value = prop.ulVal; - if (value > NLength::kNumPosStatesBitsEncodingMax) + UInt32 value = prop.ulVal; + if (value > (UInt32)NLength::kNumPosStatesBitsEncodingMax) return E_INVALIDARG; _posStateBits = value; _posStateMask = (1 << _posStateBits) - 1; @@ -297,8 +461,8 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, { if (prop.vt != VT_UI4) return E_INVALIDARG; - UINT32 value = prop.ulVal; - if (value > kNumLitPosStatesBitsEncodingMax) + UInt32 value = prop.ulVal; + if (value > (UInt32)kNumLitPosStatesBitsEncodingMax) return E_INVALIDARG; _numLiteralPosStateBits = value; break; @@ -307,12 +471,19 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, { if (prop.vt != VT_UI4) return E_INVALIDARG; - UINT32 value = prop.ulVal; - if (value > kNumLitContextBitsMax) + UInt32 value = prop.ulVal; + if (value > (UInt32)kNumLitContextBitsMax) return E_INVALIDARG; _numLiteralContextBits = value; break; } + case NCoderPropID::kEndMarker: + { + if (prop.vt != VT_BOOL) + return E_INVALIDARG; + SetWriteEndMarkerMode(prop.boolVal == VARIANT_TRUE); + break; + } default: return E_INVALIDARG; } @@ -322,45 +493,61 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) { - BYTE firstByte = (_posStateBits * 5 + _numLiteralPosStateBits) * 9 + _numLiteralContextBits; - RINOK(outStream->Write(&firstByte, sizeof(firstByte), NULL)); - return outStream->Write(&_dictionarySize, sizeof(_dictionarySize), NULL); + const UInt32 kPropSize = 5; + Byte properties[kPropSize]; + properties[0] = (_posStateBits * 5 + _numLiteralPosStateBits) * 9 + _numLiteralContextBits; + for (int i = 0; i < 4; i++) + properties[1 + i] = Byte(_dictionarySize >> (8 * i)); + return outStream->Write(properties, kPropSize, NULL); +} + +STDMETHODIMP CEncoder::SetOutStream(ISequentialOutStream *outStream) +{ + _rangeEncoder.SetStream(outStream); + return S_OK; } -STDMETHODIMP CEncoder::Init( - ISequentialOutStream *outStream) +STDMETHODIMP CEncoder::ReleaseOutStream() { - CBaseCoder::Init(); + _rangeEncoder.ReleaseStream(); + return S_OK; +} + +HRESULT CEncoder::Init() +{ + CBaseState::Init(); // RINOK(_matchFinder->Init(inStream)); - _rangeEncoder.Init(outStream); + _rangeEncoder.Init(); - int i; - for(i = 0; i < kNumStates; i++) + for(int i = 0; i < kNumStates; i++) { - for (UINT32 j = 0; j <= _posStateMask; j++) + for (UInt32 j = 0; j <= _posStateMask; j++) { - _mainChoiceEncoders[i][j].Init(); - _matchRepShortChoiceEncoders[i][j].Init(); + _isMatch[i][j].Init(); + _isRep0Long[i][j].Init(); } - _matchChoiceEncoders[i].Init(); - _matchRepChoiceEncoders[i].Init(); - _matchRep1ChoiceEncoders[i].Init(); - _matchRep2ChoiceEncoders[i].Init(); + _isRep[i].Init(); + _isRepG0[i].Init(); + _isRepG1[i].Init(); + _isRepG2[i].Init(); } _literalEncoder.Init(); // _repMatchLenEncoder.Init(); - for(i = 0; i < kNumLenToPosStates; i++) - _posSlotEncoder[i].Init(); - - for(i = 0; i < kNumPosModels; i++) - _posEncoders[i].Init(); + { + for(UInt32 i = 0; i < kNumLenToPosStates; i++) + _posSlotEncoder[i].Init(); + } + { + for(UInt32 i = 0; i < kNumFullDistances - kEndPosModelIndex; i++) + _posEncoders[i].Init(); + } - _lenEncoder.Init(); - _repMatchLenEncoder.Init(); + _lenEncoder.Init(1 << _posStateBits); + _repMatchLenEncoder.Init(1 << _posStateBits); _posAlignEncoder.Init(); @@ -372,23 +559,22 @@ STDMETHODIMP CEncoder::Init( return S_OK; } -void CEncoder::MovePos(UINT32 num) +HRESULT CEncoder::MovePos(UInt32 num) { - for (;num > 0; num--) + for (;num != 0; num--) { _matchFinder->DummyLongestMatch(); - HRESULT result = _matchFinder->MovePos(); - if (result != S_OK) - throw CMatchFinderException(result); + RINOK(_matchFinder->MovePos()); _additionalOffset++; } + return S_OK; } -UINT32 CEncoder::Backward(UINT32 &backRes, UINT32 cur) +UInt32 CEncoder::Backward(UInt32 &backRes, UInt32 cur) { _optimumEndIndex = cur; - UINT32 posMem = _optimum[cur].PosPrev; - UINT32 backMem = _optimum[cur].BackPrev; + UInt32 posMem = _optimum[cur].PosPrev; + UInt32 backMem = _optimum[cur].BackPrev; do { if (_optimum[cur].Prev1IsChar) @@ -402,8 +588,8 @@ UINT32 CEncoder::Backward(UINT32 &backRes, UINT32 cur) _optimum[posMem - 1].BackPrev = _optimum[cur].BackPrev2; } } - UINT32 posPrev = posMem; - UINT32 backCur = backMem; + UInt32 posPrev = posMem; + UInt32 backCur = backMem; backMem = _optimum[posPrev].BackPrev; posMem = _optimum[posPrev].PosPrev; @@ -412,36 +598,38 @@ UINT32 CEncoder::Backward(UINT32 &backRes, UINT32 cur) _optimum[posPrev].PosPrev = cur; cur = posPrev; } - while(cur > 0); + while(cur != 0); backRes = _optimum[0].BackPrev; _optimumCurrentIndex = _optimum[0].PosPrev; return _optimumCurrentIndex; } /* -inline UINT32 GetMatchLen(const BYTE *data, UINT32 back, UINT32 limit) +inline UInt32 GetMatchLen(const Byte *data, UInt32 back, UInt32 limit) { back++; - for(UINT32 i = 0; i < limit && data[i] == data[i - back]; i++); + for(UInt32 i = 0; i < limit && data[i] == data[i - back]; i++); return i; } */ -UINT32 CEncoder::GetOptimum(UINT32 &backRes, UINT32 position) +HRESULT CEncoder::GetOptimum(UInt32 position, UInt32 &backRes, UInt32 &lenRes) { if(_optimumEndIndex != _optimumCurrentIndex) { - UINT32 len = _optimum[_optimumCurrentIndex].PosPrev - _optimumCurrentIndex; + lenRes = _optimum[_optimumCurrentIndex].PosPrev - _optimumCurrentIndex; backRes = _optimum[_optimumCurrentIndex].BackPrev; _optimumCurrentIndex = _optimum[_optimumCurrentIndex].PosPrev; - return len; + return S_OK; } _optimumCurrentIndex = 0; _optimumEndIndex = 0; // test it; - UINT32 lenMain; + UInt32 lenMain; if (!_longestMatchWasFound) - lenMain = ReadMatchDistances(); + { + RINOK(ReadMatchDistances(lenMain)); + } else { lenMain = _longestMatchLength; @@ -449,10 +637,10 @@ UINT32 CEncoder::GetOptimum(UINT32 &backRes, UINT32 position) } - UINT32 reps[kNumRepDistances]; - UINT32 repLens[kNumRepDistances]; - UINT32 repMaxIndex = 0; - int i; + UInt32 reps[kNumRepDistances]; + UInt32 repLens[kNumRepDistances]; + UInt32 repMaxIndex = 0; + UInt32 i; for(i = 0; i < kNumRepDistances; i++) { reps[i] = _repDistances[i]; @@ -463,30 +651,32 @@ UINT32 CEncoder::GetOptimum(UINT32 &backRes, UINT32 position) if(repLens[repMaxIndex] > _numFastBytes) { backRes = repMaxIndex; - MovePos(repLens[repMaxIndex] - 1); - return repLens[repMaxIndex]; + lenRes = repLens[repMaxIndex]; + MovePos(lenRes - 1); + return S_OK; } if(lenMain > _numFastBytes) { - UINT32 backMain = (lenMain < _numFastBytes) ? _matchDistances[lenMain] : + UInt32 backMain = (lenMain < _numFastBytes) ? _matchDistances[lenMain] : _matchDistances[_numFastBytes]; backRes = backMain + kNumRepDistances; MovePos(lenMain - 1); - return lenMain; + lenRes = lenMain; + return S_OK; } - BYTE currentByte = _matchFinder->GetIndexByte(0 - 1); + Byte currentByte = _matchFinder->GetIndexByte(0 - 1); _optimum[0].State = _state; - BYTE matchByte; + Byte matchByte; matchByte = _matchFinder->GetIndexByte(0 - _repDistances[0] - 1 - 1); - UINT32 posState = (position & _posStateMask); + UInt32 posState = (position & _posStateMask); - _optimum[1].Price = _mainChoiceEncoders[_state.Index][posState].GetPrice(kMainChoiceLiteralIndex) + - _literalEncoder.GetPrice(position, _previousByte, _peviousIsMatch, matchByte, currentByte); + _optimum[1].Price = _isMatch[_state.Index][posState].GetPrice0() + + _literalEncoder.GetPrice(position, _previousByte, !_state.IsCharState(), matchByte, currentByte); _optimum[1].MakeAsChar(); _optimum[1].PosPrev = 0; @@ -494,13 +684,12 @@ UINT32 CEncoder::GetOptimum(UINT32 &backRes, UINT32 position) for (i = 0; i < kNumRepDistances; i++) _optimum[0].Backs[i] = reps[i]; - UINT32 matchPrice = _mainChoiceEncoders[_state.Index][posState].GetPrice(kMainChoiceMatchIndex); - UINT32 repMatchPrice = matchPrice + - _matchChoiceEncoders[_state.Index].GetPrice(kMatchChoiceRepetitionIndex); + UInt32 matchPrice = _isMatch[_state.Index][posState].GetPrice1(); + UInt32 repMatchPrice = matchPrice + _isRep[_state.Index].GetPrice1(); if(matchByte == currentByte) { - UINT32 shortRepPrice = repMatchPrice + GetRepLen1Price(_state, posState); + UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(_state, posState); if(shortRepPrice < _optimum[1].Price) { _optimum[1].Price = shortRepPrice; @@ -510,17 +699,18 @@ UINT32 CEncoder::GetOptimum(UINT32 &backRes, UINT32 position) if(lenMain < 2) { backRes = _optimum[1].BackPrev; - return 1; + lenRes = 1; + return S_OK; } - UINT32 normalMatchPrice = matchPrice + - _matchChoiceEncoders[_state.Index].GetPrice(kMatchChoiceDistanceIndex); + UInt32 normalMatchPrice = matchPrice + + _isRep[_state.Index].GetPrice0(); if (lenMain <= repLens[repMaxIndex]) lenMain = 0; - UINT32 len; + UInt32 len; for(len = 2; len <= lenMain; len++) { _optimum[len].PosPrev = 0; @@ -538,10 +728,10 @@ UINT32 CEncoder::GetOptimum(UINT32 &backRes, UINT32 position) for(i = 0; i < kNumRepDistances; i++) { - UINT repLen = repLens[i]; - for(UINT32 lenTest = 2; lenTest <= repLen; lenTest++) + UInt32 repLen = repLens[i]; + for(UInt32 lenTest = 2; lenTest <= repLen; lenTest++) { - UINT32 curAndLenPrice = repMatchPrice + GetRepPrice(i, lenTest, _state, posState); + UInt32 curAndLenPrice = repMatchPrice + GetRepPrice(i, lenTest, _state, posState); COptimal &optimum = _optimum[lenTest]; if (curAndLenPrice < optimum.Price) { @@ -553,16 +743,19 @@ UINT32 CEncoder::GetOptimum(UINT32 &backRes, UINT32 position) } } - UINT32 cur = 0; - UINT32 lenEnd = lenMain; + UInt32 cur = 0; + UInt32 lenEnd = lenMain; while(true) { cur++; - if(cur == lenEnd) - return Backward(backRes, cur); + if(cur == lenEnd) + { + lenRes = Backward(backRes, cur); + return S_OK; + } position++; - UINT32 posPrev = _optimum[cur].PosPrev; + UInt32 posPrev = _optimum[cur].PosPrev; CState state; if (_optimum[cur].Prev1IsChar) { @@ -581,19 +774,12 @@ UINT32 CEncoder::GetOptimum(UINT32 &backRes, UINT32 position) } else state = _optimum[posPrev].State; - bool prevWasMatch; if (posPrev == cur - 1) { if (_optimum[cur].IsShortRep()) - { - prevWasMatch = true; state.UpdateShortRep(); - } else - { - prevWasMatch = false; state.UpdateChar(); - } /* if (_optimum[cur].Prev1IsChar) for(int i = 0; i < kNumRepDistances; i++) @@ -602,8 +788,7 @@ UINT32 CEncoder::GetOptimum(UINT32 &backRes, UINT32 position) } else { - prevWasMatch = true; - UINT32 pos; + UInt32 pos; if (_optimum[cur].Prev1IsChar && _optimum[cur].Prev2) { posPrev = _optimum[cur].PosPrev2; @@ -621,7 +806,7 @@ UINT32 CEncoder::GetOptimum(UINT32 &backRes, UINT32 position) if (pos < kNumRepDistances) { reps[0] = _optimum[posPrev].Backs[pos]; - UINT32 i; + UInt32 i; for(i = 1; i <= pos; i++) reps[i] = _optimum[posPrev].Backs[i - 1]; for(; i < kNumRepDistances; i++) @@ -630,32 +815,34 @@ UINT32 CEncoder::GetOptimum(UINT32 &backRes, UINT32 position) else { reps[0] = (pos - kNumRepDistances); - for(UINT32 i = 1; i < kNumRepDistances; i++) + for(UInt32 i = 1; i < kNumRepDistances; i++) reps[i] = _optimum[posPrev].Backs[i - 1]; } } _optimum[cur].State = state; - for(UINT32 i = 0; i < kNumRepDistances; i++) + for(UInt32 i = 0; i < kNumRepDistances; i++) _optimum[cur].Backs[i] = reps[i]; - UINT32 newLen = ReadMatchDistances(); + UInt32 newLen; + RINOK(ReadMatchDistances(newLen)); if(newLen > _numFastBytes) { _longestMatchLength = newLen; _longestMatchWasFound = true; - return Backward(backRes, cur); + lenRes = Backward(backRes, cur); + return S_OK; } - UINT32 curPrice = _optimum[cur].Price; - // BYTE currentByte = _matchFinder->GetIndexByte(0 - 1); - // BYTE matchByte = _matchFinder->GetIndexByte(0 - reps[0] - 1 - 1); - const BYTE *data = _matchFinder->GetPointerToCurrentPos() - 1; - BYTE currentByte = *data; - BYTE matchByte = data[0 - reps[0] - 1]; + UInt32 curPrice = _optimum[cur].Price; + // Byte currentByte = _matchFinder->GetIndexByte(0 - 1); + // Byte matchByte = _matchFinder->GetIndexByte(0 - reps[0] - 1 - 1); + const Byte *data = _matchFinder->GetPointerToCurrentPos() - 1; + Byte currentByte = *data; + Byte matchByte = data[(size_t)0 - reps[0] - 1]; - UINT32 posState = (position & _posStateMask); + UInt32 posState = (position & _posStateMask); - UINT32 curAnd1Price = curPrice + - _mainChoiceEncoders[state.Index][posState].GetPrice(kMainChoiceLiteralIndex) + - _literalEncoder.GetPrice(position, data[-1], prevWasMatch, matchByte, currentByte); + UInt32 curAnd1Price = curPrice + + _isMatch[state.Index][posState].GetPrice0() + + _literalEncoder.GetPrice(position, data[(size_t)0 - 1], !state.IsCharState(), matchByte, currentByte); COptimal &nextOptimum = _optimum[cur + 1]; @@ -668,13 +855,13 @@ UINT32 CEncoder::GetOptimum(UINT32 &backRes, UINT32 position) nextIsChar = true; } - UINT32 matchPrice = curPrice + _mainChoiceEncoders[state.Index][posState].GetPrice(kMainChoiceMatchIndex); - UINT32 repMatchPrice = matchPrice + _matchChoiceEncoders[state.Index].GetPrice(kMatchChoiceRepetitionIndex); + UInt32 matchPrice = curPrice + _isMatch[state.Index][posState].GetPrice1(); + UInt32 repMatchPrice = matchPrice + _isRep[state.Index].GetPrice1(); if(matchByte == currentByte && !(nextOptimum.PosPrev < cur && nextOptimum.BackPrev == 0)) { - UINT32 shortRepPrice = repMatchPrice + GetRepLen1Price(state, posState); + UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(state, posState); if(shortRepPrice <= nextOptimum.Price) { nextOptimum.Price = shortRepPrice; @@ -688,7 +875,7 @@ UINT32 CEncoder::GetOptimum(UINT32 &backRes, UINT32 position) continue; */ - UINT32 numAvailableBytes = _matchFinder->GetNumAvailableBytes() + 1; + UInt32 numAvailableBytes = _matchFinder->GetNumAvailableBytes() + 1; numAvailableBytes = MyMin(kNumOpts - 1 - cur, numAvailableBytes); if (numAvailableBytes < 2) @@ -697,25 +884,25 @@ UINT32 CEncoder::GetOptimum(UINT32 &backRes, UINT32 position) numAvailableBytes = _numFastBytes; if (numAvailableBytes >= 3 && !nextIsChar) { - UINT32 backOffset = reps[0] + 1; - UINT32 temp; + UInt32 backOffset = reps[0] + 1; + UInt32 temp; for (temp = 1; temp < numAvailableBytes; temp++) - if (data[temp] != data[temp - backOffset]) + if (data[temp] != data[(size_t)temp - backOffset]) break; - UINT32 lenTest2 = temp - 1; + UInt32 lenTest2 = temp - 1; if (lenTest2 >= 2) { CState state2 = state; state2.UpdateChar(); - UINT32 posStateNext = (position + 1) & _posStateMask; - UINT32 nextRepMatchPrice = curAnd1Price + - _mainChoiceEncoders[state2.Index][posStateNext].GetPrice(kMainChoiceMatchIndex) + - _matchChoiceEncoders[state2.Index].GetPrice(kMatchChoiceRepetitionIndex); + UInt32 posStateNext = (position + 1) & _posStateMask; + UInt32 nextRepMatchPrice = curAnd1Price + + _isMatch[state2.Index][posStateNext].GetPrice1() + + _isRep[state2.Index].GetPrice1(); // for (; lenTest2 >= 2; lenTest2--) { while(lenEnd < cur + 1 + lenTest2) _optimum[++lenEnd].Price = kIfinityPrice; - UINT32 curAndLenPrice = nextRepMatchPrice + GetRepPrice( + UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice( 0, lenTest2, state2, posStateNext); COptimal &optimum = _optimum[cur + 1 + lenTest2]; if (curAndLenPrice < optimum.Price) @@ -729,19 +916,19 @@ UINT32 CEncoder::GetOptimum(UINT32 &backRes, UINT32 position) } } } - for(UINT32 repIndex = 0; repIndex < kNumRepDistances; repIndex++) + for(UInt32 repIndex = 0; repIndex < kNumRepDistances; repIndex++) { - // UINT32 repLen = _matchFinder->GetMatchLen(0 - 1, reps[repIndex], newLen); // test it; - UINT32 backOffset = reps[repIndex] + 1; - UINT32 lenTest; + // UInt32 repLen = _matchFinder->GetMatchLen(0 - 1, reps[repIndex], newLen); // test it; + UInt32 backOffset = reps[repIndex] + 1; + UInt32 lenTest; for (lenTest = 0; lenTest < numAvailableBytes; lenTest++) - if (data[lenTest] != data[lenTest - backOffset]) + if (data[lenTest] != data[(size_t)lenTest - backOffset]) break; for(; lenTest >= 2; lenTest--) { while(lenEnd < cur + lenTest) _optimum[++lenEnd].Price = kIfinityPrice; - UINT32 curAndLenPrice = repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState); + UInt32 curAndLenPrice = repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState); COptimal &optimum = _optimum[cur + lenTest]; if (curAndLenPrice < optimum.Price) { @@ -754,31 +941,31 @@ UINT32 CEncoder::GetOptimum(UINT32 &backRes, UINT32 position) /* if (_maxMode) { - UINT32 temp; + UInt32 temp; for (temp = lenTest + 1; temp < numAvailableBytes; temp++) - if (data[temp] != data[temp - backOffset]) + if (data[temp] != data[(size_t)temp - backOffset]) break; - UINT32 lenTest2 = temp - (lenTest + 1); + UInt32 lenTest2 = temp - (lenTest + 1); if (lenTest2 >= 2) { CState state2 = state; state2.UpdateRep(); - UINT32 posStateNext = (position + lenTest) & _posStateMask; - UINT32 curAndLenCharPrice = curAndLenPrice + - _mainChoiceEncoders[state2.Index][posStateNext].GetPrice(kMainChoiceLiteralIndex) + - _literalEncoder.GetPrice(position + lenTest, data[lenTest - 1], - true, data[lenTest - backOffset], data[lenTest]); + UInt32 posStateNext = (position + lenTest) & _posStateMask; + UInt32 curAndLenCharPrice = curAndLenPrice + + _isMatch[state2.Index][posStateNext].GetPrice0() + + _literalEncoder.GetPrice(position + lenTest, data[(size_t)lenTest - 1], + true, data[(size_t)lenTest - backOffset], data[lenTest]); state2.UpdateChar(); posStateNext = (position + lenTest + 1) & _posStateMask; - UINT32 nextMatchPrice = curAndLenCharPrice + _mainChoiceEncoders[state2.Index][posStateNext].GetPrice(kMainChoiceMatchIndex); - UINT32 nextRepMatchPrice = nextMatchPrice + _matchChoiceEncoders[state2.Index].GetPrice(kMatchChoiceRepetitionIndex); + UInt32 nextMatchPrice = curAndLenCharPrice + _isMatch[state2.Index][posStateNext].GetPrice1(); + UInt32 nextRepMatchPrice = nextMatchPrice + _isRep[state2.Index].GetPrice1(); // for(; lenTest2 >= 2; lenTest2--) { - UINT32 offset = lenTest + 1 + lenTest2; + UInt32 offset = lenTest + 1 + lenTest2; while(lenEnd < cur + offset) _optimum[++lenEnd].Price = kIfinityPrice; - UINT32 curAndLenPrice = nextRepMatchPrice + GetRepPrice( + UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice( 0, lenTest2, state2, posStateNext); COptimal &optimum = _optimum[cur + offset]; if (curAndLenPrice < optimum.Price) @@ -798,22 +985,22 @@ UINT32 CEncoder::GetOptimum(UINT32 &backRes, UINT32 position) } } - // for(UINT32 lenTest = 2; lenTest <= newLen; lenTest++) + // for(UInt32 lenTest = 2; lenTest <= newLen; lenTest++) if (newLen > numAvailableBytes) newLen = numAvailableBytes; if (newLen >= 2) { if (newLen == 2 && _matchDistances[2] >= 0x80) continue; - UINT32 normalMatchPrice = matchPrice + - _matchChoiceEncoders[state.Index].GetPrice(kMatchChoiceDistanceIndex); + UInt32 normalMatchPrice = matchPrice + + _isRep[state.Index].GetPrice0(); while(lenEnd < cur + newLen) _optimum[++lenEnd].Price = kIfinityPrice; - for(UINT32 lenTest = newLen; lenTest >= 2; lenTest--) + for(UInt32 lenTest = newLen; lenTest >= 2; lenTest--) { - UINT32 curBack = _matchDistances[lenTest]; - UINT32 curAndLenPrice = normalMatchPrice + GetPosLenPrice(curBack, lenTest, posState); + UInt32 curBack = _matchDistances[lenTest]; + UInt32 curAndLenPrice = normalMatchPrice + GetPosLenPrice(curBack, lenTest, posState); COptimal &optimum = _optimum[cur + lenTest]; if (curAndLenPrice < optimum.Price) { @@ -825,32 +1012,32 @@ UINT32 CEncoder::GetOptimum(UINT32 &backRes, UINT32 position) if (_maxMode) { - UINT32 backOffset = curBack + 1; - UINT32 temp; + UInt32 backOffset = curBack + 1; + UInt32 temp; for (temp = lenTest + 1; temp < numAvailableBytes; temp++) - if (data[temp] != data[temp - backOffset]) + if (data[temp] != data[(size_t)temp - backOffset]) break; - UINT32 lenTest2 = temp - (lenTest + 1); + UInt32 lenTest2 = temp - (lenTest + 1); if (lenTest2 >= 2) { CState state2 = state; state2.UpdateMatch(); - UINT32 posStateNext = (position + lenTest) & _posStateMask; - UINT32 curAndLenCharPrice = curAndLenPrice + - _mainChoiceEncoders[state2.Index][posStateNext].GetPrice(kMainChoiceLiteralIndex) + - _literalEncoder.GetPrice(position + lenTest, data[lenTest - 1], - true, data[lenTest - backOffset], data[lenTest]); + UInt32 posStateNext = (position + lenTest) & _posStateMask; + UInt32 curAndLenCharPrice = curAndLenPrice + + _isMatch[state2.Index][posStateNext].GetPrice0() + + _literalEncoder.GetPrice(position + lenTest, data[(size_t)lenTest - 1], + true, data[(size_t)lenTest - backOffset], data[lenTest]); state2.UpdateChar(); posStateNext = (position + lenTest + 1) & _posStateMask; - UINT32 nextMatchPrice = curAndLenCharPrice + _mainChoiceEncoders[state2.Index][posStateNext].GetPrice(kMainChoiceMatchIndex); - UINT32 nextRepMatchPrice = nextMatchPrice + _matchChoiceEncoders[state2.Index].GetPrice(kMatchChoiceRepetitionIndex); + UInt32 nextMatchPrice = curAndLenCharPrice + _isMatch[state2.Index][posStateNext].GetPrice1(); + UInt32 nextRepMatchPrice = nextMatchPrice + _isRep[state2.Index].GetPrice1(); // for(; lenTest2 >= 2; lenTest2--) { - UINT32 offset = lenTest + 1 + lenTest2; + UInt32 offset = lenTest + 1 + lenTest2; while(lenEnd < cur + offset) _optimum[++lenEnd].Price = kIfinityPrice; - UINT32 curAndLenPrice = nextRepMatchPrice + GetRepPrice( + UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice( 0, lenTest2, state2, posStateNext); COptimal &optimum = _optimum[cur + offset]; if (curAndLenPrice < optimum.Price) @@ -871,26 +1058,38 @@ UINT32 CEncoder::GetOptimum(UINT32 &backRes, UINT32 position) } } -static inline bool ChangePair(UINT32 smallDist, UINT32 bigDist) +static inline bool ChangePair(UInt32 smallDist, UInt32 bigDist) { const int kDif = 7; - return (smallDist < (UINT32(1) << (32-kDif)) && bigDist >= (smallDist << kDif)); + return (smallDist < (UInt32(1) << (32-kDif)) && bigDist >= (smallDist << kDif)); } -UINT32 CEncoder::GetOptimumFast(UINT32 &backRes, UINT32 position) +HRESULT CEncoder::ReadMatchDistances(UInt32 &lenRes) { - UINT32 lenMain; + lenRes = _matchFinder->GetLongestMatch(_matchDistances); + if (lenRes == _numFastBytes) + lenRes += _matchFinder->GetMatchLen(lenRes, _matchDistances[lenRes], + kMatchMaxLen - lenRes); + _additionalOffset++; + return _matchFinder->MovePos(); +} + +HRESULT CEncoder::GetOptimumFast(UInt32 position, UInt32 &backRes, UInt32 &lenRes) +{ + UInt32 lenMain; if (!_longestMatchWasFound) - lenMain = ReadMatchDistances(); + { + RINOK(ReadMatchDistances(lenMain)); + } else { lenMain = _longestMatchLength; _longestMatchWasFound = false; } - UINT32 repLens[kNumRepDistances]; - UINT32 repMaxIndex = 0; - for(int i = 0; i < kNumRepDistances; i++) + UInt32 repLens[kNumRepDistances]; + UInt32 repMaxIndex = 0; + for(UInt32 i = 0; i < kNumRepDistances; i++) { repLens[i] = _matchFinder->GetMatchLen(0 - 1, _repDistances[i], kMatchMaxLen); if (i == 0 || repLens[i] > repLens[repMaxIndex]) @@ -899,14 +1098,16 @@ UINT32 CEncoder::GetOptimumFast(UINT32 &backRes, UINT32 position) if(repLens[repMaxIndex] >= _numFastBytes) { backRes = repMaxIndex; - MovePos(repLens[repMaxIndex] - 1); - return repLens[repMaxIndex]; + lenRes = repLens[repMaxIndex]; + MovePos(lenRes - 1); + return S_OK; } if(lenMain >= _numFastBytes) { backRes = _matchDistances[_numFastBytes] + kNumRepDistances; MovePos(lenMain - 1); - return lenMain; + lenRes = lenMain; + return S_OK; } while (lenMain > 2) { @@ -917,54 +1118,58 @@ UINT32 CEncoder::GetOptimumFast(UINT32 &backRes, UINT32 position) if (lenMain == 2 && _matchDistances[2] >= 0x80) lenMain = 1; - UINT32 backMain = _matchDistances[lenMain]; + UInt32 backMain = _matchDistances[lenMain]; if (repLens[repMaxIndex] >= 2) { if (repLens[repMaxIndex] + 1 >= lenMain || repLens[repMaxIndex] + 2 >= lenMain && (backMain > (1<<12))) { backRes = repMaxIndex; - MovePos(repLens[repMaxIndex] - 1); - return repLens[repMaxIndex]; + lenRes = repLens[repMaxIndex]; + MovePos(lenRes - 1); + return S_OK; } } if (lenMain >= 2) { - _longestMatchLength = ReadMatchDistances(); + RINOK(ReadMatchDistances(_longestMatchLength)); if (_longestMatchLength >= 2 && ( - (_longestMatchLength >= lenMain && - _matchDistances[lenMain] < backMain) || + (_longestMatchLength >= lenMain && _matchDistances[lenMain] < backMain) || _longestMatchLength == lenMain + 1 && !ChangePair(backMain, _matchDistances[_longestMatchLength]) || _longestMatchLength > lenMain + 1 || - _longestMatchLength + 1 >= lenMain && + _longestMatchLength + 1 >= lenMain && lenMain >= 3 && ChangePair(_matchDistances[lenMain - 1], backMain) ) ) { _longestMatchWasFound = true; - backRes = UINT32(-1); - return 1; + backRes = UInt32(-1); + lenRes = 1; + return S_OK; } - for(int i = 0; i < kNumRepDistances; i++) + for(UInt32 i = 0; i < kNumRepDistances; i++) { - UINT32 repLen = _matchFinder->GetMatchLen(0 - 1, _repDistances[i], kMatchMaxLen); + UInt32 repLen = _matchFinder->GetMatchLen(0 - 1, _repDistances[i], kMatchMaxLen); if (repLen >= 2 && repLen + 1 >= lenMain) { _longestMatchWasFound = true; - backRes = UINT32(-1); - return 1; + backRes = UInt32(-1); + lenRes = 1; + return S_OK; } } backRes = backMain + kNumRepDistances; MovePos(lenMain - 2); - return lenMain; + lenRes = lenMain; + return S_OK; } - backRes = UINT32(-1); - return 1; + backRes = UInt32(-1); + lenRes = 1; + return S_OK; } STDMETHODIMP CEncoder::InitMatchFinder(IMatchFinder *matchFinder) @@ -973,44 +1178,48 @@ STDMETHODIMP CEncoder::InitMatchFinder(IMatchFinder *matchFinder) return S_OK; } -HRESULT CEncoder::Flush() +HRESULT CEncoder::Flush(UInt32 nowPos) { + ReleaseMFStream(); + WriteEndMarker(nowPos & _posStateMask); _rangeEncoder.FlushData(); return _rangeEncoder.FlushStream(); } -void CEncoder::WriteEndMarker(UINT32 posState) +void CEncoder::WriteEndMarker(UInt32 posState) { // This function for writing End Mark for stream version of LZMA. // In current version this feature is not used. if (!_writeEndMark) return; - _mainChoiceEncoders[_state.Index][posState].Encode(&_rangeEncoder, kMainChoiceMatchIndex); - _matchChoiceEncoders[_state.Index].Encode(&_rangeEncoder, kMatchChoiceDistanceIndex); + _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 1); + _isRep[_state.Index].Encode(&_rangeEncoder, 0); _state.UpdateMatch(); - UINT32 len = kMatchMinLen; // kMatchMaxLen; + UInt32 len = kMatchMinLen; // kMatchMaxLen; _lenEncoder.Encode(&_rangeEncoder, len - kMatchMinLen, posState); - UINT32 posSlot = (1 << kNumPosSlotBits) - 1; - UINT32 lenToPosState = GetLenToPosState(len); + UInt32 posSlot = (1 << kNumPosSlotBits) - 1; + UInt32 lenToPosState = GetLenToPosState(len); _posSlotEncoder[lenToPosState].Encode(&_rangeEncoder, posSlot); - UINT32 footerBits = 30; - UINT32 posReduced = (UINT32(1) << footerBits) - 1; + UInt32 footerBits = 30; + UInt32 posReduced = (UInt32(1) << footerBits) - 1; _rangeEncoder.EncodeDirectBits(posReduced >> kNumAlignBits, footerBits - kNumAlignBits); - _posAlignEncoder.Encode(&_rangeEncoder, posReduced & kAlignMask); + _posAlignEncoder.ReverseEncode(&_rangeEncoder, posReduced & kAlignMask); } HRESULT CEncoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UINT64 *inSize, const UINT64 *outSize, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { + _needReleaseMFStream = false; + CCoderReleaser coderReleaser(this); RINOK(SetStreams(inStream, outStream, inSize, outSize)); while(true) { - UINT64 processedInSize; - UINT64 processedOutSize; - INT32 finished; + UInt64 processedInSize; + UInt64 processedOutSize; + Int32 finished; RINOK(CodeOneBlock(&processedInSize, &processedOutSize, &finished)); if (finished != 0) return S_OK; @@ -1023,12 +1232,13 @@ HRESULT CEncoder::CodeReal(ISequentialInStream *inStream, HRESULT CEncoder::SetStreams(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UINT64 *inSize, const UINT64 *outSize) + const UInt64 *inSize, const UInt64 *outSize) { _inStream = inStream; _finished = false; RINOK(Create()); - RINOK(Init(outStream)); + RINOK(SetOutStream(outStream)); + RINOK(Init()); // CCoderReleaser releaser(this); @@ -1045,20 +1255,21 @@ HRESULT CEncoder::SetStreams(ISequentialInStream *inStream, } _lenEncoder.SetTableSize(_numFastBytes); - _lenEncoder.UpdateTables(); + _lenEncoder.UpdateTables(1 << _posStateBits); _repMatchLenEncoder.SetTableSize(_numFastBytes); - _repMatchLenEncoder.UpdateTables(); + _repMatchLenEncoder.UpdateTables(1 << _posStateBits); lastPosSlotFillingPos = 0; nowPos64 = 0; return S_OK; } -HRESULT CEncoder::CodeOneBlock(UINT64 *inSize, UINT64 *outSize, INT32 *finished) +HRESULT CEncoder::CodeOneBlock(UInt64 *inSize, UInt64 *outSize, Int32 *finished) { if (_inStream != 0) { RINOK(_matchFinder->Init(_inStream)); + _needReleaseMFStream = true; _inStream = 0; } @@ -1069,80 +1280,79 @@ HRESULT CEncoder::CodeOneBlock(UINT64 *inSize, UINT64 *outSize, INT32 *finished) _finished = true; - UINT64 progressPosValuePrev = nowPos64; + UInt64 progressPosValuePrev = nowPos64; if (nowPos64 == 0) { if (_matchFinder->GetNumAvailableBytes() == 0) - { - _matchFinder->ReleaseStream(); - WriteEndMarker(UINT32(nowPos64) & _posStateMask); - return Flush(); - } - ReadMatchDistances(); - UINT32 posState = UINT32(nowPos64) & _posStateMask; - _mainChoiceEncoders[_state.Index][posState].Encode(&_rangeEncoder, kMainChoiceLiteralIndex); + return Flush(UInt32(nowPos64)); + UInt32 len; // it's not used + RINOK(ReadMatchDistances(len)); + UInt32 posState = UInt32(nowPos64) & _posStateMask; + _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 0); _state.UpdateChar(); - BYTE curByte = _matchFinder->GetIndexByte(0 - _additionalOffset); - _literalEncoder.Encode(&_rangeEncoder, UINT32(nowPos64), _previousByte, - false, 0, curByte); + Byte curByte = _matchFinder->GetIndexByte(0 - _additionalOffset); + _literalEncoder.GetSubCoder(UInt32(nowPos64), _previousByte)->Encode(&_rangeEncoder, curByte); _previousByte = curByte; _additionalOffset--; nowPos64++; } if (_matchFinder->GetNumAvailableBytes() == 0) - { - _matchFinder->ReleaseStream(); - WriteEndMarker(UINT32(nowPos64) & _posStateMask); - return Flush(); - } + return Flush(UInt32(nowPos64)); while(true) { - UINT32 pos; - UINT32 posState = UINT32(nowPos64) & _posStateMask; + #ifdef _NO_EXCEPTIONS + if (_rangeEncoder.Stream.ErrorCode != S_OK) + return _rangeEncoder.Stream.ErrorCode; + #endif + UInt32 pos; + UInt32 posState = UInt32(nowPos64) & _posStateMask; - UINT32 len; + UInt32 len; + HRESULT result; if (_fastMode) - len = GetOptimumFast(pos, UINT32(nowPos64)); + result = GetOptimumFast(UInt32(nowPos64), pos, len); else - len = GetOptimum(pos, UINT32(nowPos64)); + result = GetOptimum(UInt32(nowPos64), pos, len); + RINOK(result); - if(len == 1 && pos == (-1)) + if(len == 1 && pos == 0xFFFFFFFF) { - _mainChoiceEncoders[_state.Index][posState].Encode(&_rangeEncoder, kMainChoiceLiteralIndex); + _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 0); + Byte curByte = _matchFinder->GetIndexByte(0 - _additionalOffset); + CLiteralEncoder2 *subCoder = _literalEncoder.GetSubCoder(UInt32(nowPos64), _previousByte); + if(!_state.IsCharState()) + { + Byte matchByte = _matchFinder->GetIndexByte(0 - _repDistances[0] - 1 - _additionalOffset); + subCoder->EncodeMatched(&_rangeEncoder, matchByte, curByte); + } + else + subCoder->Encode(&_rangeEncoder, curByte); _state.UpdateChar(); - BYTE matchByte; - if(_peviousIsMatch) - matchByte = _matchFinder->GetIndexByte(0 - _repDistances[0] - 1 - _additionalOffset); - BYTE curByte = _matchFinder->GetIndexByte(0 - _additionalOffset); - _literalEncoder.Encode(&_rangeEncoder, UINT32(nowPos64), _previousByte, _peviousIsMatch, - matchByte, curByte); _previousByte = curByte; - _peviousIsMatch = false; } else { - _peviousIsMatch = true; - _mainChoiceEncoders[_state.Index][posState].Encode(&_rangeEncoder, kMainChoiceMatchIndex); + _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 1); if(pos < kNumRepDistances) { - _matchChoiceEncoders[_state.Index].Encode(&_rangeEncoder, kMatchChoiceRepetitionIndex); + _isRep[_state.Index].Encode(&_rangeEncoder, 1); if(pos == 0) { - _matchRepChoiceEncoders[_state.Index].Encode(&_rangeEncoder, 0); + _isRepG0[_state.Index].Encode(&_rangeEncoder, 0); if(len == 1) - _matchRepShortChoiceEncoders[_state.Index][posState].Encode(&_rangeEncoder, 0); + _isRep0Long[_state.Index][posState].Encode(&_rangeEncoder, 0); else - _matchRepShortChoiceEncoders[_state.Index][posState].Encode(&_rangeEncoder, 1); + _isRep0Long[_state.Index][posState].Encode(&_rangeEncoder, 1); } else { - _matchRepChoiceEncoders[_state.Index].Encode(&_rangeEncoder, 1); + _isRepG0[_state.Index].Encode(&_rangeEncoder, 1); if (pos == 1) - _matchRep1ChoiceEncoders[_state.Index].Encode(&_rangeEncoder, 0); + _isRepG1[_state.Index].Encode(&_rangeEncoder, 0); else { - _matchRep1ChoiceEncoders[_state.Index].Encode(&_rangeEncoder, 1); - _matchRep2ChoiceEncoders[_state.Index].Encode(&_rangeEncoder, pos - 2); + _isRepG1[_state.Index].Encode(&_rangeEncoder, 1); + _isRepG2[_state.Index].Encode(&_rangeEncoder, pos - 2); } } if (len == 1) @@ -1154,42 +1364,44 @@ HRESULT CEncoder::CodeOneBlock(UINT64 *inSize, UINT64 *outSize, INT32 *finished) } - UINT32 distance = _repDistances[pos]; + UInt32 distance = _repDistances[pos]; if (pos != 0) { - for(UINT32 i = pos; i >= 1; i--) + for(UInt32 i = pos; i >= 1; i--) _repDistances[i] = _repDistances[i - 1]; _repDistances[0] = distance; } } else { - _matchChoiceEncoders[_state.Index].Encode(&_rangeEncoder, kMatchChoiceDistanceIndex); + _isRep[_state.Index].Encode(&_rangeEncoder, 0); _state.UpdateMatch(); _lenEncoder.Encode(&_rangeEncoder, len - kMatchMinLen, posState); pos -= kNumRepDistances; - UINT32 posSlot = GetPosSlot(pos); - UINT32 lenToPosState = GetLenToPosState(len); + UInt32 posSlot = GetPosSlot(pos); + UInt32 lenToPosState = GetLenToPosState(len); _posSlotEncoder[lenToPosState].Encode(&_rangeEncoder, posSlot); if (posSlot >= kStartPosModelIndex) { - UINT32 footerBits = ((posSlot >> 1) - 1); - UINT32 posReduced = pos - ((2 | (posSlot & 1)) << footerBits); + UInt32 footerBits = ((posSlot >> 1) - 1); + UInt32 base = ((2 | (posSlot & 1)) << footerBits); + UInt32 posReduced = pos - base; if (posSlot < kEndPosModelIndex) - _posEncoders[posSlot - kStartPosModelIndex].Encode(&_rangeEncoder, posReduced); + NRangeCoder::ReverseBitTreeEncode(_posEncoders + base - posSlot - 1, + &_rangeEncoder, footerBits, posReduced); else { _rangeEncoder.EncodeDirectBits(posReduced >> kNumAlignBits, footerBits - kNumAlignBits); - _posAlignEncoder.Encode(&_rangeEncoder, posReduced & kAlignMask); + _posAlignEncoder.ReverseEncode(&_rangeEncoder, posReduced & kAlignMask); if (!_fastMode) if (--_alignPriceCount == 0) FillAlignPrices(); } } - UINT32 distance = pos; - for(UINT32 i = kNumRepDistances - 1; i >= 1; i--) + UInt32 distance = pos; + for(UInt32 i = kNumRepDistances - 1; i >= 1; i--) _repDistances[i] = _repDistances[i - 1]; _repDistances[0] = distance; } @@ -1209,11 +1421,7 @@ HRESULT CEncoder::CodeOneBlock(UINT64 *inSize, UINT64 *outSize, INT32 *finished) *inSize = nowPos64; *outSize = _rangeEncoder.GetProcessedSize(); if (_matchFinder->GetNumAvailableBytes() == 0) - { - _matchFinder->ReleaseStream(); - WriteEndMarker(UINT32(nowPos64) & _posStateMask); - return Flush(); - } + return Flush(UInt32(nowPos64)); if (nowPos64 - progressPosValuePrev >= (1 << 12)) { _finished = false; @@ -1225,20 +1433,26 @@ HRESULT CEncoder::CodeOneBlock(UINT64 *inSize, UINT64 *outSize, INT32 *finished) } STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { - try { return CodeReal(inStream, outStream, inSize, outSize, progress); } - catch(CMatchFinderException &e) { return e.ErrorCode; } + #ifndef _NO_EXCEPTIONS + try + { + #endif + return CodeReal(inStream, outStream, inSize, outSize, progress); + #ifndef _NO_EXCEPTIONS + } catch(const COutBufferException &e) { return e.ErrorCode; } catch(...) { return E_FAIL; } + #endif } void CEncoder::FillPosSlotPrices() { - for (int lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++) + for (UInt32 lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++) { - UINT32 posSlot; + UInt32 posSlot; for (posSlot = 0; posSlot < kEndPosModelIndex && posSlot < _distTableSize; posSlot++) _posSlotPrices[lenToPosState][posSlot] = _posSlotEncoder[lenToPosState].GetPrice(posSlot); for (; posSlot < _distTableSize; posSlot++) @@ -1249,25 +1463,29 @@ void CEncoder::FillPosSlotPrices() void CEncoder::FillDistancesPrices() { - for (int lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++) + for (UInt32 lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++) { - UINT32 i; + UInt32 i; for (i = 0; i < kStartPosModelIndex; i++) _distancesPrices[lenToPosState][i] = _posSlotPrices[lenToPosState][i]; for (; i < kNumFullDistances; i++) { - UINT32 posSlot = GetPosSlot(i); + UInt32 posSlot = GetPosSlot(i); + UInt32 footerBits = ((posSlot >> 1) - 1); + UInt32 base = ((2 | (posSlot & 1)) << footerBits); + _distancesPrices[lenToPosState][i] = _posSlotPrices[lenToPosState][posSlot] + - _posEncoders[posSlot - kStartPosModelIndex].GetPrice(i - - ((2 | (posSlot & 1)) << (((posSlot >> 1) - 1)))); + NRangeCoder::ReverseBitTreeGetPrice(_posEncoders + + base - posSlot - 1, footerBits, i - base); + } } } void CEncoder::FillAlignPrices() { - for (int i = 0; i < kAlignTableSize; i++) - _alignPrices[i] = _posAlignEncoder.GetPrice(i); + for (UInt32 i = 0; i < kAlignTableSize; i++) + _alignPrices[i] = _posAlignEncoder.ReverseGetPrice(i); _alignPriceCount = kAlignTableSize; } diff --git a/7zip/Compress/LZMA/LZMAEncoder.h b/7zip/Compress/LZMA/LZMAEncoder.h index 7e29ee51..4c5f5c14 100755 --- a/7zip/Compress/LZMA/LZMAEncoder.h +++ b/7zip/Compress/LZMA/LZMAEncoder.h @@ -1,26 +1,34 @@ // LZMA/Encoder.h -// #pragma once - #ifndef __LZMA_ENCODER_H #define __LZMA_ENCODER_H -#include "../../ICoder.h" #include "../../../Common/MyCom.h" +#include "../../../Common/Alloc.h" +#include "../../ICoder.h" #include "../LZ/IMatchFinder.h" +#include "../RangeCoder/RangeCoderBitTree.h" #include "LZMA.h" -#include "LZMALen.h" -#include "LZMALiteral.h" namespace NCompress { namespace NLZMA { -class CMatchFinderException +typedef NRangeCoder::CBitEncoder<kNumMoveBits> CMyBitEncoder; + +class CBaseState { -public: - HRESULT ErrorCode; - CMatchFinderException(HRESULT errorCode): ErrorCode(errorCode) {} +protected: + CState _state; + Byte _previousByte; + UInt32 _repDistances[kNumRepDistances]; + void Init() + { + _state.Init(); + _previousByte = 0; + for(UInt32 i = 0 ; i < kNumRepDistances; i++) + _repDistances[i] = 0; + } }; struct COptimal @@ -30,21 +38,21 @@ struct COptimal bool Prev1IsChar; bool Prev2; - UINT32 PosPrev2; - UINT32 BackPrev2; + UInt32 PosPrev2; + UInt32 BackPrev2; - UINT32 Price; - UINT32 PosPrev; // posNext; - UINT32 BackPrev; - UINT32 Backs[kNumRepDistances]; - void MakeAsChar() { BackPrev = UINT32(-1); Prev1IsChar = false; } + UInt32 Price; + UInt32 PosPrev; // posNext; + UInt32 BackPrev; + UInt32 Backs[kNumRepDistances]; + void MakeAsChar() { BackPrev = UInt32(-1); Prev1IsChar = false; } void MakeAsShortRep() { BackPrev = 0; ; Prev1IsChar = false; } bool IsShortRep() { return (BackPrev == 0); } }; -extern BYTE g_FastPos[1024]; -inline UINT32 GetPosSlot(UINT32 pos) +extern Byte g_FastPos[1024]; +inline UInt32 GetPosSlot(UInt32 pos) { if (pos < (1 << 10)) return g_FastPos[pos]; @@ -53,7 +61,7 @@ inline UINT32 GetPosSlot(UINT32 pos) return g_FastPos[pos >> 18] + 36; } -inline UINT32 GetPosSlot2(UINT32 pos) +inline UInt32 GetPosSlot2(UInt32 pos) { if (pos < (1 << 16)) return g_FastPos[pos >> 6] + 12; @@ -62,78 +70,187 @@ inline UINT32 GetPosSlot2(UINT32 pos) return g_FastPos[pos >> 24] + 48; } -const UINT32 kIfinityPrice = 0xFFFFFFF; +const UInt32 kIfinityPrice = 0xFFFFFFF; -typedef NRangeCoder::CBitEncoder<kNumMoveBits> CMyBitEncoder; +const UInt32 kNumOpts = 1 << 12; + + +class CLiteralEncoder2 +{ + CMyBitEncoder _encoders[0x300]; +public: + void Init() + { + for (int i = 0; i < 0x300; i++) + _encoders[i].Init(); + } + void Encode(NRangeCoder::CEncoder *rangeEncoder, Byte symbol); + void EncodeMatched(NRangeCoder::CEncoder *rangeEncoder, Byte matchByte, Byte symbol); + UInt32 GetPrice(bool matchMode, Byte matchByte, Byte symbol) const; +}; + +class CLiteralEncoder +{ + CLiteralEncoder2 *_coders; + int _numPrevBits; + int _numPosBits; + UInt32 _posMask; +public: + CLiteralEncoder(): _coders(0) {} + ~CLiteralEncoder() { Free(); } + void Free() + { + MyFree(_coders); + _coders = 0; + } + bool Create(int numPosBits, int numPrevBits) + { + if (_coders == 0 || (numPosBits + numPrevBits) != + (_numPrevBits + _numPosBits) ) + { + Free(); + UInt32 numStates = 1 << (numPosBits + numPrevBits); + _coders = (CLiteralEncoder2 *)MyAlloc(numStates * sizeof(CLiteralEncoder2)); + } + _numPosBits = numPosBits; + _posMask = (1 << numPosBits) - 1; + _numPrevBits = numPrevBits; + return (_coders != 0); + } + void Init() + { + UInt32 numStates = 1 << (_numPrevBits + _numPosBits); + for (UInt32 i = 0; i < numStates; i++) + _coders[i].Init(); + } + UInt32 GetState(UInt32 pos, Byte prevByte) const + { return ((pos & _posMask) << _numPrevBits) + (prevByte >> (8 - _numPrevBits)); } + CLiteralEncoder2 *GetSubCoder(UInt32 pos, Byte prevByte) + { return &_coders[GetState(pos, prevByte)]; } + /* + void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 pos, Byte prevByte, + Byte symbol) + { _coders[GetState(pos, prevByte)].Encode(rangeEncoder, symbol); } + void EncodeMatched(NRangeCoder::CEncoder *rangeEncoder, UInt32 pos, Byte prevByte, + Byte matchByte, Byte symbol) + { _coders[GetState(pos, prevByte)].Encode(rangeEncoder, + matchByte, symbol); } + */ + UInt32 GetPrice(UInt32 pos, Byte prevByte, bool matchMode, Byte matchByte, Byte symbol) const + { return _coders[GetState(pos, prevByte)].GetPrice(matchMode, matchByte, symbol); } +}; -const UINT32 kNumOpts = 1 << 12; +namespace NLength { + +class CEncoder +{ + CMyBitEncoder _choice; + CMyBitEncoder _choice2; + NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumLowBits> _lowCoder[kNumPosStatesEncodingMax]; + NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumMidBits> _midCoder[kNumPosStatesEncodingMax]; + NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumHighBits> _highCoder; +public: + void Init(UInt32 numPosStates); + void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState); + UInt32 GetPrice(UInt32 symbol, UInt32 posState) const; +}; + +const UInt32 kNumSpecSymbols = kNumLowSymbols + kNumMidSymbols; + +class CPriceTableEncoder: public CEncoder +{ + UInt32 _prices[kNumSymbolsTotal][kNumPosStatesEncodingMax]; + UInt32 _tableSize; + UInt32 _counters[kNumPosStatesEncodingMax]; +public: + void SetTableSize(UInt32 tableSize) { _tableSize = tableSize; } + UInt32 GetPrice(UInt32 symbol, UInt32 posState) const + { return _prices[symbol][posState]; } + void UpdateTable(UInt32 posState) + { + for (UInt32 len = 0; len < _tableSize; len++) + _prices[len][posState] = CEncoder::GetPrice(len, posState); + _counters[posState] = _tableSize; + } + void UpdateTables(UInt32 numPosStates) + { + for (UInt32 posState = 0; posState < numPosStates; posState++) + UpdateTable(posState); + } + void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState) + { + CEncoder::Encode(rangeEncoder, symbol, posState); + if (--_counters[posState] == 0) + UpdateTable(posState); + } +}; + +} class CEncoder : public ICompressCoder, - // public IInitMatchFinder, + public ICompressSetOutStream, public ICompressSetCoderProperties, public ICompressWriteCoderProperties, - public CBaseCoder, + public CBaseState, public CMyUnknownImp { COptimal _optimum[kNumOpts]; -public: CMyComPtr<IMatchFinder> _matchFinder; // test it NRangeCoder::CEncoder _rangeEncoder; -private: - CMyBitEncoder _mainChoiceEncoders[kNumStates][NLength::kNumPosStatesEncodingMax]; - CMyBitEncoder _matchChoiceEncoders[kNumStates]; - CMyBitEncoder _matchRepChoiceEncoders[kNumStates]; - CMyBitEncoder _matchRep1ChoiceEncoders[kNumStates]; - CMyBitEncoder _matchRep2ChoiceEncoders[kNumStates]; - CMyBitEncoder _matchRepShortChoiceEncoders[kNumStates][NLength::kNumPosStatesEncodingMax]; + CMyBitEncoder _isMatch[kNumStates][NLength::kNumPosStatesEncodingMax]; + CMyBitEncoder _isRep[kNumStates]; + CMyBitEncoder _isRepG0[kNumStates]; + CMyBitEncoder _isRepG1[kNumStates]; + CMyBitEncoder _isRepG2[kNumStates]; + CMyBitEncoder _isRep0Long[kNumStates][NLength::kNumPosStatesEncodingMax]; NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumPosSlotBits> _posSlotEncoder[kNumLenToPosStates]; - NRangeCoder::CReverseBitTreeEncoder2<kNumMoveBits> _posEncoders[kNumPosModels]; - NRangeCoder::CReverseBitTreeEncoder2<kNumMoveBits> _posAlignEncoder; + CMyBitEncoder _posEncoders[kNumFullDistances - kEndPosModelIndex]; + NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumAlignBits> _posAlignEncoder; NLength::CPriceTableEncoder _lenEncoder; NLength::CPriceTableEncoder _repMatchLenEncoder; - NLiteral::CEncoder _literalEncoder; + CLiteralEncoder _literalEncoder; - UINT32 _matchDistances[kMatchMaxLen + 1]; + UInt32 _matchDistances[kMatchMaxLen + 1]; bool _fastMode; bool _maxMode; - UINT32 _numFastBytes; - UINT32 _longestMatchLength; + UInt32 _numFastBytes; + UInt32 _longestMatchLength; - UINT32 _additionalOffset; + UInt32 _additionalOffset; - UINT32 _optimumEndIndex; - UINT32 _optimumCurrentIndex; + UInt32 _optimumEndIndex; + UInt32 _optimumCurrentIndex; bool _longestMatchWasFound; - UINT32 _posSlotPrices[kNumLenToPosStates][kDistTableSizeMax]; + UInt32 _posSlotPrices[kNumLenToPosStates][kDistTableSizeMax]; - UINT32 _distancesPrices[kNumLenToPosStates][kNumFullDistances]; + UInt32 _distancesPrices[kNumLenToPosStates][kNumFullDistances]; - UINT32 _alignPrices[kAlignTableSize]; - UINT32 _alignPriceCount; + UInt32 _alignPrices[kAlignTableSize]; + UInt32 _alignPriceCount; - UINT32 _distTableSize; + UInt32 _distTableSize; - UINT32 _posStateBits; - UINT32 _posStateMask; - UINT32 _numLiteralPosStateBits; - UINT32 _numLiteralContextBits; + UInt32 _posStateBits; + UInt32 _posStateMask; + UInt32 _numLiteralPosStateBits; + UInt32 _numLiteralContextBits; - UINT32 _dictionarySize; + UInt32 _dictionarySize; - UINT32 _dictionarySizePrev; - UINT32 _numFastBytesPrev; + UInt32 _dictionarySizePrev; + UInt32 _numFastBytesPrev; - UINT64 lastPosSlotFillingPos; - UINT64 nowPos64; + UInt64 lastPosSlotFillingPos; + UInt64 nowPos64; bool _finished; ISequentialInStream *_inStream; @@ -143,58 +260,49 @@ private: #endif bool _writeEndMark; + + bool _needReleaseMFStream; - UINT32 ReadMatchDistances() - { - UINT32 len = _matchFinder->GetLongestMatch(_matchDistances); - if (len == _numFastBytes) - len += _matchFinder->GetMatchLen(len, _matchDistances[len], - kMatchMaxLen - len); - _additionalOffset++; - HRESULT result = _matchFinder->MovePos(); - if (result != S_OK) - throw CMatchFinderException(result); - return len; - } + HRESULT ReadMatchDistances(UInt32 &len); - void MovePos(UINT32 num); - UINT32 GetRepLen1Price(CState state, UINT32 posState) const + HRESULT MovePos(UInt32 num); + UInt32 GetRepLen1Price(CState state, UInt32 posState) const { - return _matchRepChoiceEncoders[state.Index].GetPrice(0) + - _matchRepShortChoiceEncoders[state.Index][posState].GetPrice(0); + return _isRepG0[state.Index].GetPrice0() + + _isRep0Long[state.Index][posState].GetPrice0(); } - UINT32 GetRepPrice(UINT32 repIndex, UINT32 len, CState state, UINT32 posState) const + UInt32 GetRepPrice(UInt32 repIndex, UInt32 len, CState state, UInt32 posState) const { - UINT32 price = _repMatchLenEncoder.GetPrice(len - kMatchMinLen, posState); + UInt32 price = _repMatchLenEncoder.GetPrice(len - kMatchMinLen, posState); if(repIndex == 0) { - price += _matchRepChoiceEncoders[state.Index].GetPrice(0); - price += _matchRepShortChoiceEncoders[state.Index][posState].GetPrice(1); + price += _isRepG0[state.Index].GetPrice0(); + price += _isRep0Long[state.Index][posState].GetPrice1(); } else { - price += _matchRepChoiceEncoders[state.Index].GetPrice(1); + price += _isRepG0[state.Index].GetPrice1(); if (repIndex == 1) - price += _matchRep1ChoiceEncoders[state.Index].GetPrice(0); + price += _isRepG1[state.Index].GetPrice0(); else { - price += _matchRep1ChoiceEncoders[state.Index].GetPrice(1); - price += _matchRep2ChoiceEncoders[state.Index].GetPrice(repIndex - 2); + price += _isRepG1[state.Index].GetPrice1(); + price += _isRepG2[state.Index].GetPrice(repIndex - 2); } } return price; } /* - UINT32 GetPosLen2Price(UINT32 pos, UINT32 posState) const + UInt32 GetPosLen2Price(UInt32 pos, UInt32 posState) const { if (pos >= kNumFullDistances) return kIfinityPrice; return _distancesPrices[0][pos] + _lenEncoder.GetPrice(0, posState); } - UINT32 GetPosLen3Price(UINT32 pos, UINT32 len, UINT32 posState) const + UInt32 GetPosLen3Price(UInt32 pos, UInt32 len, UInt32 posState) const { - UINT32 price; - UINT32 lenToPosState = GetLenToPosState(len); + UInt32 price; + UInt32 lenToPosState = GetLenToPosState(len); if (pos < kNumFullDistances) price = _distancesPrices[lenToPosState][pos]; else @@ -203,12 +311,12 @@ private: return price + _lenEncoder.GetPrice(len - kMatchMinLen, posState); } */ - UINT32 GetPosLenPrice(UINT32 pos, UINT32 len, UINT32 posState) const + UInt32 GetPosLenPrice(UInt32 pos, UInt32 len, UInt32 posState) const { if (len == 2 && pos >= 0x80) return kIfinityPrice; - UINT32 price; - UINT32 lenToPosState = GetLenToPosState(len); + UInt32 price; + UInt32 lenToPosState = GetLenToPosState(len); if (pos < kNumFullDistances) price = _distancesPrices[lenToPosState][pos]; else @@ -217,21 +325,30 @@ private: return price + _lenEncoder.GetPrice(len - kMatchMinLen, posState); } - UINT32 Backward(UINT32 &backRes, UINT32 cur); - UINT32 GetOptimum(UINT32 &backRes, UINT32 position); - UINT32 GetOptimumFast(UINT32 &backRes, UINT32 position); + UInt32 Backward(UInt32 &backRes, UInt32 cur); + HRESULT GetOptimum(UInt32 position, UInt32 &backRes, UInt32 &lenRes); + HRESULT GetOptimumFast(UInt32 position, UInt32 &backRes, UInt32 &lenRes); void FillPosSlotPrices(); void FillDistancesPrices(); void FillAlignPrices(); + void ReleaseMFStream() + { + if (_matchFinder && _needReleaseMFStream) + { + _matchFinder->ReleaseStream(); + _needReleaseMFStream = false; + } + } + void ReleaseStreams() { - _matchFinder->ReleaseStream(); - // _rangeEncoder.ReleaseStream(); + ReleaseMFStream(); + ReleaseOutStream(); } - HRESULT Flush(); + HRESULT Flush(UInt32 nowPos); class CCoderReleaser { CEncoder *_coder; @@ -244,7 +361,7 @@ private: }; friend class CCoderReleaser; - void WriteEndMarker(UINT32 posState); + void WriteEndMarker(UInt32 posState); public: CEncoder(); @@ -253,29 +370,29 @@ public: HRESULT Create(); - MY_UNKNOWN_IMP2( + MY_UNKNOWN_IMP3( + ICompressSetOutStream, ICompressSetCoderProperties, ICompressWriteCoderProperties ) - STDMETHOD(Init)( - ISequentialOutStream *outStream); + HRESULT Init(); // ICompressCoder interface HRESULT SetStreams(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UINT64 *inSize, const UINT64 *outSize); - HRESULT CodeOneBlock(UINT64 *inSize, UINT64 *outSize, INT32 *finished); + const UInt64 *inSize, const UInt64 *outSize); + HRESULT CodeOneBlock(UInt64 *inSize, UInt64 *outSize, Int32 *finished); HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UINT64 *inSize, const UINT64 *outSize, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); // ICompressCoder interface STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UINT64 *inSize, const UINT64 *outSize, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); // IInitMatchFinder interface @@ -283,10 +400,15 @@ public: // ICompressSetCoderProperties2 STDMETHOD(SetCoderProperties)(const PROPID *propIDs, - const PROPVARIANT *properties, UINT32 numProperties); + const PROPVARIANT *properties, UInt32 numProperties); // ICompressWriteCoderProperties STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); + + STDMETHOD(SetOutStream)(ISequentialOutStream *outStream); + STDMETHOD(ReleaseOutStream)(); + + virtual ~CEncoder() {} }; }} diff --git a/7zip/Compress/LZMA/LZMALen.cpp b/7zip/Compress/LZMA/LZMALen.cpp deleted file mode 100755 index 0a422605..00000000 --- a/7zip/Compress/LZMA/LZMALen.cpp +++ /dev/null @@ -1,74 +0,0 @@ -// LZMALen.cpp - -#include "StdAfx.h" - -#include "LZMALen.h" - -namespace NCompress { -namespace NLZMA { -namespace NLength { - -void CEncoder::Init() -{ - _choice.Init(); - for (UINT32 posState = 0; posState < _numPosStates; posState++) - { - _lowCoder[posState].Init(); - _midCoder[posState].Init(); - } - _choice2.Init(); - _highCoder.Init(); -} - -void CEncoder::Encode(NRangeCoder::CEncoder *rangeEncoder, UINT32 symbol, UINT32 posState) -{ - if(symbol < kNumLowSymbols) - { - _choice.Encode(rangeEncoder, 0); - _lowCoder[posState].Encode(rangeEncoder, symbol); - } - else - { - symbol -= kNumLowSymbols; - _choice.Encode(rangeEncoder, 1); - if(symbol < kNumMidSymbols) - { - _choice2.Encode(rangeEncoder, 0); - _midCoder[posState].Encode(rangeEncoder, symbol); - } - else - { - _choice2.Encode(rangeEncoder, 1); - _highCoder.Encode(rangeEncoder, symbol - kNumMidSymbols); - } - } -} - -UINT32 CEncoder::GetPrice(UINT32 symbol, UINT32 posState) const -{ - UINT32 price = 0; - if(symbol < kNumLowSymbols) - { - price += _choice.GetPrice(0); - price += _lowCoder[posState].GetPrice(symbol); - } - else - { - symbol -= kNumLowSymbols; - price += _choice.GetPrice(1); - if(symbol < kNumMidSymbols) - { - price += _choice2.GetPrice(0); - price += _midCoder[posState].GetPrice(symbol); - } - else - { - price += _choice2.GetPrice(1); - price += _highCoder.GetPrice(symbol - kNumMidSymbols); - } - } - return price; -} - -}}} - diff --git a/7zip/Compress/LZMA/LZMALen.h b/7zip/Compress/LZMA/LZMALen.h deleted file mode 100755 index c8b61f3d..00000000 --- a/7zip/Compress/LZMA/LZMALen.h +++ /dev/null @@ -1,114 +0,0 @@ -// LenCoder.h - -// #pragma once - -#ifndef __LENCODER_H -#define __LENCODER_H - -#include "../RangeCoder/RangeCoderBitTree.h" - -namespace NCompress { -namespace NLZMA { -namespace NLength { - -const int kNumMoveBits = 5; - -const int kNumPosStatesBitsMax = 4; -const UINT32 kNumPosStatesMax = (1 << kNumPosStatesBitsMax); - -const int kNumPosStatesBitsEncodingMax = 4; -const UINT32 kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax); - -const int kNumLenBits = 3; -const UINT32 kNumLowSymbols = 1 << kNumLenBits; -const int kNumMidBits = 3; -const UINT32 kNumMidSymbols = 1 << kNumMidBits; - -const int kNumHighBits = 8; - -const UINT32 kNumSymbolsTotal = kNumLowSymbols + kNumMidSymbols + (1 << kNumHighBits); - -class CEncoder -{ - NRangeCoder::CBitEncoder<kNumMoveBits> _choice; - NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumLenBits> _lowCoder[kNumPosStatesEncodingMax]; - NRangeCoder::CBitEncoder<kNumMoveBits> _choice2; - NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumMidBits> _midCoder[kNumPosStatesEncodingMax]; - NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumHighBits> _highCoder; -protected: - UINT32 _numPosStates; -public: - void Create(UINT32 numPosStates) - { _numPosStates = numPosStates; } - void Init(); - void Encode(NRangeCoder::CEncoder *rangeEncoder, UINT32 symbol, UINT32 posState); - UINT32 GetPrice(UINT32 symbol, UINT32 posState) const; -}; - -const UINT32 kNumSpecSymbols = kNumLowSymbols + kNumMidSymbols; - -class CPriceTableEncoder: public CEncoder -{ - UINT32 _prices[kNumSymbolsTotal][kNumPosStatesEncodingMax]; - UINT32 _tableSize; - UINT32 _counters[kNumPosStatesEncodingMax]; -public: - void SetTableSize(UINT32 tableSize) - { _tableSize = tableSize; } - UINT32 GetPrice(UINT32 symbol, UINT32 posState) const - { return _prices[symbol][posState]; } - void UpdateTable(UINT32 posState) - { - for (UINT32 len = 0; len < _tableSize; len++) - _prices[len][posState] = CEncoder::GetPrice(len , posState); - _counters[posState] = _tableSize; - } - void UpdateTables() - { - for (UINT32 posState = 0; posState < _numPosStates; posState++) - UpdateTable(posState); - } - void Encode(NRangeCoder::CEncoder *rangeEncoder, UINT32 symbol, UINT32 posState) - { - CEncoder::Encode(rangeEncoder, symbol, posState); - if (--_counters[posState] == 0) - UpdateTable(posState); - } -}; - - -class CDecoder -{ - NRangeCoder::CBitDecoder<kNumMoveBits> _choice; - NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumLenBits> _lowCoder[kNumPosStatesMax]; - NRangeCoder::CBitDecoder<kNumMoveBits> _choice2; - NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumMidBits> _midCoder[kNumPosStatesMax]; - NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumHighBits> _highCoder; - UINT32 _numPosStates; -public: - void Create(UINT32 numPosStates) - { _numPosStates = numPosStates; } - void Init() - { - _choice.Init(); - for (UINT32 posState = 0; posState < _numPosStates; posState++) - { - _lowCoder[posState].Init(); - _midCoder[posState].Init(); - } - _choice2.Init(); - _highCoder.Init(); - } - UINT32 Decode(NRangeCoder::CDecoder *rangeDecoder, UINT32 posState) - { - if(_choice.Decode(rangeDecoder) == 0) - return _lowCoder[posState].Decode(rangeDecoder); - if(_choice2.Decode(rangeDecoder) == 0) - return kNumLowSymbols + _midCoder[posState].Decode(rangeDecoder); - return kNumLowSymbols + kNumMidSymbols + _highCoder.Decode(rangeDecoder); - } -}; - -}}} - -#endif diff --git a/7zip/Compress/LZMA/LZMALiteral.cpp b/7zip/Compress/LZMA/LZMALiteral.cpp deleted file mode 100755 index e35bdba2..00000000 --- a/7zip/Compress/LZMA/LZMALiteral.cpp +++ /dev/null @@ -1,69 +0,0 @@ -// LZMALiteral.cpp - -#include "StdAfx.h" - -#include "LZMALiteral.h" - -namespace NCompress { -namespace NLZMA { -namespace NLiteral { - -void CEncoder2::Init() -{ - for (int i = 0; i < 3; i++) - for (int j = 1; j < (1 << 8); j++) - _encoders[i][j].Init(); -} - -void CEncoder2::Encode(NRangeCoder::CEncoder *rangeEncoder, - bool matchMode, BYTE matchByte, BYTE symbol) -{ - UINT32 context = 1; - bool same = true; - for (int i = 7; i >= 0; i--) - { - UINT32 bit = (symbol >> i) & 1; - UINT state; - if (matchMode && same) - { - UINT32 matchBit = (matchByte >> i) & 1; - state = 1 + matchBit; - same = (matchBit == bit); - } - else - state = 0; - _encoders[state][context].Encode(rangeEncoder, bit); - context = (context << 1) | bit; - } -} - -UINT32 CEncoder2::GetPrice(bool matchMode, BYTE matchByte, BYTE symbol) const -{ - UINT32 price = 0; - UINT32 context = 1; - int i = 7; - if (matchMode) - { - for (; i >= 0; i--) - { - UINT32 matchBit = (matchByte >> i) & 1; - UINT32 bit = (symbol >> i) & 1; - price += _encoders[1 + matchBit][context].GetPrice(bit); - context = (context << 1) | bit; - if (matchBit != bit) - { - i--; - break; - } - } - } - for (; i >= 0; i--) - { - UINT32 bit = (symbol >> i) & 1; - price += _encoders[0][context].GetPrice(bit); - context = (context << 1) | bit; - } - return price; -}; - -}}} diff --git a/7zip/Compress/LZMA/LZMALiteral.h b/7zip/Compress/LZMA/LZMALiteral.h deleted file mode 100755 index 09cf0c36..00000000 --- a/7zip/Compress/LZMA/LZMALiteral.h +++ /dev/null @@ -1,166 +0,0 @@ -// LiteralCoder.h - -// #pragma once - -#ifndef __LITERALCODER_H -#define __LITERALCODER_H - -#include "../RangeCoder/RangeCoderBit.h" -#include "../RangeCoder/RangeCoderOpt.h" - -namespace NCompress { -namespace NLZMA { -namespace NLiteral { - -const int kNumMoveBits = 5; - -class CEncoder2 -{ - NRangeCoder::CBitEncoder<kNumMoveBits> _encoders[3][1 << 8]; -public: - void Init(); - void Encode(NRangeCoder::CEncoder *rangeEncoder, bool matchMode, BYTE matchByte, BYTE symbol); - UINT32 GetPrice(bool matchMode, BYTE matchByte, BYTE symbol) const; -}; - -class CDecoder2 -{ - NRangeCoder::CBitDecoder<kNumMoveBits> _decoders[3][1 << 8]; -public: - void Init() - { - for (int i = 0; i < 3; i++) - for (int j = 1; j < (1 << 8); j++) - _decoders[i][j].Init(); - } - - BYTE DecodeNormal(NRangeCoder::CDecoder *rangeDecoder) - { - UINT32 symbol = 1; - RC_INIT_VAR - do - { - // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder); - RC_GETBIT(kNumMoveBits, _decoders[0][symbol].Probability, symbol) - } - while (symbol < 0x100); - RC_FLUSH_VAR - return symbol; - } - - BYTE DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, BYTE matchByte) - { - UINT32 symbol = 1; - RC_INIT_VAR - do - { - UINT32 matchBit = (matchByte >> 7) & 1; - matchByte <<= 1; - // UINT32 bit = _decoders[1 + matchBit][symbol].Decode(rangeDecoder); - // symbol = (symbol << 1) | bit; - UINT32 bit; - RC_GETBIT2(kNumMoveBits, _decoders[1 + matchBit][symbol].Probability, symbol, - bit = 0, bit = 1) - if (matchBit != bit) - { - while (symbol < 0x100) - { - // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder); - RC_GETBIT(kNumMoveBits, _decoders[0][symbol].Probability, symbol) - } - break; - } - } - while (symbol < 0x100); - RC_FLUSH_VAR - return symbol; - } -}; - -/* -const UINT32 kNumPrevByteBits = 1; -const UINT32 kNumPrevByteStates = (1 << kNumPrevByteBits); - -inline UINT32 GetLiteralState(BYTE prevByte) - { return (prevByte >> (8 - kNumPrevByteBits)); } -*/ - -class CEncoder -{ - CEncoder2 *_coders; - UINT32 _numPrevBits; - UINT32 _numPosBits; - UINT32 _posMask; -public: - CEncoder(): _coders(0) {} - ~CEncoder() { Free(); } - void Free() - { - delete []_coders; - _coders = 0; - } - void Create(UINT32 numPosBits, UINT32 numPrevBits) - { - Free(); - _numPosBits = numPosBits; - _posMask = (1 << numPosBits) - 1; - _numPrevBits = numPrevBits; - UINT32 numStates = 1 << (_numPrevBits + _numPosBits); - _coders = new CEncoder2[numStates]; - } - void Init() - { - UINT32 numStates = 1 << (_numPrevBits + _numPosBits); - for (UINT32 i = 0; i < numStates; i++) - _coders[i].Init(); - } - UINT32 GetState(UINT32 pos, BYTE prevByte) const - { return ((pos & _posMask) << _numPrevBits) + (prevByte >> (8 - _numPrevBits)); } - void Encode(NRangeCoder::CEncoder *rangeEncoder, UINT32 pos, BYTE prevByte, - bool matchMode, BYTE matchByte, BYTE symbol) - { _coders[GetState(pos, prevByte)].Encode(rangeEncoder, matchMode, - matchByte, symbol); } - UINT32 GetPrice(UINT32 pos, BYTE prevByte, bool matchMode, BYTE matchByte, BYTE symbol) const - { return _coders[GetState(pos, prevByte)].GetPrice(matchMode, matchByte, symbol); } -}; - -class CDecoder -{ - CDecoder2 *_coders; - UINT32 _numPrevBits; - UINT32 _numPosBits; - UINT32 _posMask; -public: - CDecoder(): _coders(0) {} - ~CDecoder() { Free(); } - void Free() - { - delete []_coders; - _coders = 0; - } - void Create(UINT32 numPosBits, UINT32 numPrevBits) - { - Free(); - _numPosBits = numPosBits; - _posMask = (1 << numPosBits) - 1; - _numPrevBits = numPrevBits; - UINT32 numStates = 1 << (_numPrevBits + _numPosBits); - _coders = new CDecoder2[numStates]; - } - void Init() - { - UINT32 numStates = 1 << (_numPrevBits + _numPosBits); - for (UINT32 i = 0; i < numStates; i++) - _coders[i].Init(); - } - UINT32 GetState(UINT32 pos, BYTE prevByte) const - { return ((pos & _posMask) << _numPrevBits) + (prevByte >> (8 - _numPrevBits)); } - BYTE DecodeNormal(NRangeCoder::CDecoder *rangeDecoder, UINT32 pos, BYTE prevByte) - { return _coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); } - BYTE DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, UINT32 pos, BYTE prevByte, BYTE matchByte) - { return _coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); } -}; - -}}} - -#endif diff --git a/7zip/Compress/LZMA/StdAfx.cpp b/7zip/Compress/LZMA/StdAfx.cpp index 2550270c..d0feea85 100755 --- a/7zip/Compress/LZMA/StdAfx.cpp +++ b/7zip/Compress/LZMA/StdAfx.cpp @@ -1,3 +1,3 @@ // StdAfx.cpp -#include "stdafx.h" +#include "StdAfx.h" diff --git a/7zip/Compress/LZMA/StdAfx.h b/7zip/Compress/LZMA/StdAfx.h index a32fbed6..e7fb6986 100755 --- a/7zip/Compress/LZMA/StdAfx.h +++ b/7zip/Compress/LZMA/StdAfx.h @@ -1,8 +1,8 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> +#include "../../../Common/MyWindows.h" -#endif +#endif diff --git a/7zip/Compress/LZMA/resource.rc b/7zip/Compress/LZMA/resource.rc index e6e906e6..6aa1a271 100755 --- a/7zip/Compress/LZMA/resource.rc +++ b/7zip/Compress/LZMA/resource.rc @@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,12,0,0 - PRODUCTVERSION 3,12,0,0 + FILEVERSION 4,17,0,0 + PRODUCTVERSION 4,17,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -85,14 +85,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Igor Pavlov\0" VALUE "FileDescription", "LZMA Codec\0" - VALUE "FileVersion", "3, 12, 0, 0\0" + VALUE "FileVersion", "4, 17, 0, 0\0" VALUE "InternalName", "LZMA\0" - VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "LZMA.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "7-Zip\0" - VALUE "ProductVersion", "3, 12, 0, 0\0" + VALUE "ProductVersion", "4, 17, 0, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/7zip/Compress/LZMA_Alone/AloneLZMA.dsp b/7zip/Compress/LZMA_Alone/AloneLZMA.dsp new file mode 100755 index 00000000..3f0efbdc --- /dev/null +++ b/7zip/Compress/LZMA_Alone/AloneLZMA.dsp @@ -0,0 +1,515 @@ +# Microsoft Developer Studio Project File - Name="AloneLZMA" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=AloneLZMA - Win32 DebugU +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "AloneLZMA.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "AloneLZMA.mak" CFG="AloneLZMA - Win32 DebugU" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "AloneLZMA - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "AloneLZMA - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "AloneLZMA - Win32 ReleaseU" (based on "Win32 (x86) Console Application") +!MESSAGE "AloneLZMA - Win32 DebugU" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "AloneLZMA - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /c +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\lzma.exe" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "AloneLZMA - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\lzma.exe" /pdbtype:sept + +!ELSEIF "$(CFG)" == "AloneLZMA - Win32 ReleaseU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "ReleaseU" +# PROP BASE Intermediate_Dir "ReleaseU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "ReleaseU" +# PROP Intermediate_Dir "ReleaseU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /c +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7za2.exe" /opt:NOWIN98 +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\lzma.exe" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "AloneLZMA - Win32 DebugU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "DebugU" +# PROP BASE Intermediate_Dir "DebugU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "DebugU" +# PROP Intermediate_Dir "DebugU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7za2.exe" /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\lzma.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "AloneLZMA - Win32 Release" +# Name "AloneLZMA - Win32 Debug" +# Name "AloneLZMA - Win32 ReleaseU" +# Name "AloneLZMA - Win32 DebugU" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Group "LZMA" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\LZMA\LZMA.h +# End Source File +# Begin Source File + +SOURCE=..\LZMA\LZMADecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\LZMA\LZMADecoder.h +# End Source File +# Begin Source File + +SOURCE=..\LZMA\LZMAEncoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\LZMA\LZMAEncoder.h +# End Source File +# End Group +# Begin Group "RangeCoder" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\RangeCoder\RangeCoder.h +# End Source File +# Begin Source File + +SOURCE=..\RangeCoder\RangeCoderBit.cpp +# End Source File +# Begin Source File + +SOURCE=..\RangeCoder\RangeCoderBit.h +# End Source File +# Begin Source File + +SOURCE=..\RangeCoder\RangeCoderBitTree.h +# End Source File +# Begin Source File + +SOURCE=..\RangeCoder\RangeCoderOpt.h +# End Source File +# End Group +# Begin Group "LZ" + +# PROP Default_Filter "" +# Begin Group "Pat" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\LZ\Patricia\Pat.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\Patricia\Pat2.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\Patricia\Pat2H.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\Patricia\Pat2R.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\Patricia\Pat3H.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\Patricia\Pat4H.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\Patricia\PatMain.h +# End Source File +# End Group +# Begin Group "BT" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTree.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTree2.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTree3.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTree3Z.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTree3ZMain.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTree4.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTree4b.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTreeMain.h +# End Source File +# End Group +# Begin Group "HC" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\LZ\HashChain\HC.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\HashChain\HC2.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\HashChain\HC3.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\HashChain\HC4.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\HashChain\HC4b.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\HashChain\HCMain.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\LZ\IMatchFinder.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\LZInWindow.cpp +# End Source File +# Begin Source File + +SOURCE=..\LZ\LZInWindow.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\LZOutWindow.cpp +# End Source File +# Begin Source File + +SOURCE=..\LZ\LZOutWindow.h +# End Source File +# End Group +# Begin Group "Branch" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Branch\BranchX86.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\Branch\BranchX86.h +# End Source File +# End Group +# Begin Group "LZMA_C" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\LZMA_C\LzmaDecode.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\LZMA_C\LzmaDecode.h +# End Source File +# End Group +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyCom.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Types.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\FileStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\ICoder.h +# End Source File +# Begin Source File + +SOURCE=.\LzmaAlone.cpp +# End Source File +# Begin Source File + +SOURCE=.\LzmaBench.cpp +# End Source File +# Begin Source File + +SOURCE=.\LzmaBench.h +# End Source File +# Begin Source File + +SOURCE=.\LzmaRam.cpp +# End Source File +# Begin Source File + +SOURCE=.\LzmaRam.h +# End Source File +# Begin Source File + +SOURCE=.\LzmaRamDecode.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=.\LzmaRamDecode.h +# End Source File +# End Target +# End Project diff --git a/7zip/Compress/LZMA_Alone/AloneLZMA.dsw b/7zip/Compress/LZMA_Alone/AloneLZMA.dsw new file mode 100755 index 00000000..d7482d8a --- /dev/null +++ b/7zip/Compress/LZMA_Alone/AloneLZMA.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "AloneLZMA"=.\AloneLZMA.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/7zip/Compress/LZMA_Alone/LzmaAlone.cpp b/7zip/Compress/LZMA_Alone/LzmaAlone.cpp new file mode 100755 index 00000000..96d26561 --- /dev/null +++ b/7zip/Compress/LZMA_Alone/LzmaAlone.cpp @@ -0,0 +1,481 @@ +// LzmaAlone.cpp + +#include "StdAfx.h" + +#include "../../../Common/MyWindows.h" +#include "../../../Common/MyInitGuid.h" + +#include <stdio.h> + +#if defined(_WIN32) || defined(OS2) || defined(MSDOS) +#include <fcntl.h> +#include <io.h> +#define MY_SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY) +#else +#define MY_SET_BINARY_MODE(file) +#endif + +#include "../../../Common/CommandLineParser.h" +#include "../../../Common/StringConvert.h" +#include "../../../Common/StringToInt.h" + +// #include "Windows/PropVariant.h" + +#include "../../Common/FileStreams.h" + +#include "../LZMA/LZMADecoder.h" +#include "../LZMA/LZMAEncoder.h" + +#include "LzmaBench.h" +#include "LzmaRam.h" + +extern "C" +{ +#include "LzmaRamDecode.h" +} + +using namespace NCommandLineParser; + +namespace NKey { +enum Enum +{ + kHelp1 = 0, + kHelp2, + kMode, + kDictionary, + kFastBytes, + kLitContext, + kLitPos, + kPosBits, + kMatchFinder, + kEOS, + kStdIn, + kStdOut, + kFilter86 +}; +} + +static const CSwitchForm kSwitchForms[] = +{ + { L"?", NSwitchType::kSimple, false }, + { L"H", NSwitchType::kSimple, false }, + { L"A", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"D", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"FB", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"LC", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"LP", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"PB", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"MF", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"EOS", NSwitchType::kSimple, false }, + { L"SI", NSwitchType::kSimple, false }, + { L"SO", NSwitchType::kSimple, false }, + { L"F86", NSwitchType::kSimple, false } +}; + +static const int kNumSwitches = sizeof(kSwitchForms) / sizeof(kSwitchForms[0]); + +static void PrintHelp() +{ + fprintf(stderr, "\nUsage: LZMA <e|d> inputFile outputFile [<switches>...]\n" + " e: encode file\n" + " d: decode file\n" + " b: Benchmark\n" + "<Switches>\n" + " -a{N}: set compression mode - [0, 2], default: 2 (max)\n" + " -d{N}: set dictionary - [0,28], default: 23 (8MB)\n" + " -fb{N}: set number of fast bytes - [5, 255], default: 128\n" + " -lc{N}: set number of literal context bits - [0, 8], default: 3\n" + " -lp{N}: set number of literal pos bits - [0, 4], default: 0\n" + " -pb{N}: set number of pos bits - [0, 4], default: 2\n" + " -mf{MF_ID}: set Match Finder: [bt2, bt3, bt4, bt4b, pat2r, pat2,\n" + " pat2h, pat3h, pat4h, hc3, hc4], default: bt4\n" + " -eos: write End Of Stream marker\n" + " -si: Read data from stdin\n" + " -so: Write data to stdout\n" + ); +} + +static void PrintHelpAndExit(const char *s) +{ + fprintf(stderr, "\nError: %s\n\n", s); + PrintHelp(); + throw -1; +} + +static void IncorrectCommand() +{ + PrintHelpAndExit("Incorrect command"); +} + +static void WriteArgumentsToStringList(int numArguments, const char *arguments[], + UStringVector &strings) +{ + for(int i = 1; i < numArguments; i++) + strings.Add(MultiByteToUnicodeString(arguments[i])); +} + +static bool GetNumber(const wchar_t *s, UInt32 &value) +{ + value = 0; + if (MyStringLen(s) == 0) + return false; + const wchar_t *end; + UInt64 res = ConvertStringToUInt64(s, &end); + if (*end != L'\0') + return false; + if (res > 0xFFFFFFFF) + return false; + value = UInt32(res); + return true; +} + +int main2(int n, const char *args[]) +{ + fprintf(stderr, "\nLZMA 4.17 Copyright (c) 1999-2004 Igor Pavlov 2005-04-18\n"); + + if (n == 1) + { + PrintHelp(); + return 0; + } + + if (sizeof(Byte) != 1 || sizeof(UInt32) < 4 || sizeof(UInt64) < 4) + { + fprintf(stderr, "Unsupported base types. Edit Common/Types.h and recompile"); + return 1; + } + + UStringVector commandStrings; + WriteArgumentsToStringList(n, args, commandStrings); + CParser parser(kNumSwitches); + try + { + parser.ParseStrings(kSwitchForms, commandStrings); + } + catch(...) + { + IncorrectCommand(); + } + + if(parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs) + { + PrintHelp(); + return 0; + } + const UStringVector &nonSwitchStrings = parser.NonSwitchStrings; + + int paramIndex = 0; + if (paramIndex >= nonSwitchStrings.Size()) + IncorrectCommand(); + const UString &command = nonSwitchStrings[paramIndex++]; + + bool dictionaryIsDefined = false; + UInt32 dictionary = 1 << 21; + if(parser[NKey::kDictionary].ThereIs) + { + UInt32 dicLog; + if (!GetNumber(parser[NKey::kDictionary].PostStrings[0], dicLog)) + IncorrectCommand(); + dictionary = 1 << dicLog; + dictionaryIsDefined = true; + } + UString mf = L"BT4"; + if (parser[NKey::kMatchFinder].ThereIs) + mf = parser[NKey::kMatchFinder].PostStrings[0]; + + if (command.CompareNoCase(L"b") == 0) + { + const UInt32 kNumDefaultItereations = 10; + UInt32 numIterations = kNumDefaultItereations; + { + if (paramIndex < nonSwitchStrings.Size()) + if (!GetNumber(nonSwitchStrings[paramIndex++], numIterations)) + numIterations = kNumDefaultItereations; + } + return LzmaBenchmark(stderr, numIterations, dictionary, + mf.CompareNoCase(L"BT4") == 0); + } + + bool encodeMode = false; + if (command.CompareNoCase(L"e") == 0) + encodeMode = true; + else if (command.CompareNoCase(L"d") == 0) + encodeMode = false; + else + IncorrectCommand(); + + bool stdInMode = parser[NKey::kStdIn].ThereIs; + bool stdOutMode = parser[NKey::kStdOut].ThereIs; + + CMyComPtr<ISequentialInStream> inStream; + CInFileStream *inStreamSpec = 0; + if (stdInMode) + { + inStream = new CStdInFileStream; + MY_SET_BINARY_MODE(stdin); + } + else + { + if (paramIndex >= nonSwitchStrings.Size()) + IncorrectCommand(); + const UString &inputName = nonSwitchStrings[paramIndex++]; + inStreamSpec = new CInFileStream; + inStream = inStreamSpec; + if (!inStreamSpec->Open(GetSystemString(inputName))) + { + fprintf(stderr, "\nError: can not open input file %s\n", + (const char *)GetOemString(inputName)); + return 1; + } + } + + CMyComPtr<ISequentialOutStream> outStream; + if (stdOutMode) + { + outStream = new CStdOutFileStream; + MY_SET_BINARY_MODE(stdout); + } + else + { + if (paramIndex >= nonSwitchStrings.Size()) + IncorrectCommand(); + const UString &outputName = nonSwitchStrings[paramIndex++]; + COutFileStream *outStreamSpec = new COutFileStream; + outStream = outStreamSpec; + if (!outStreamSpec->Create(GetSystemString(outputName), true)) + { + fprintf(stderr, "\nError: can not open output file %s\n", + (const char *)GetOemString(outputName)); + return 1; + } + } + + if (parser[NKey::kFilter86].ThereIs) + { + // -f86 switch is for x86 filtered mode: BCJ + LZMA. + if (parser[NKey::kEOS].ThereIs || stdInMode) + throw "Can not use stdin in this mode"; + UInt64 fileSize; + inStreamSpec->File.GetLength(fileSize); + if (fileSize > 0xF0000000) + throw "File is too big"; + UInt32 inSize = (UInt32)fileSize; + Byte *inBuffer = (Byte *)MyAlloc((size_t)inSize); + if (inBuffer == 0) + throw "Can not allocate memory"; + + UInt32 processedSize; + if (inStream->Read(inBuffer, (UInt32)inSize, &processedSize) != S_OK) + throw "Can not read"; + if ((UInt32)inSize != processedSize) + throw "Read size error"; + + Byte *outBuffer; + size_t outSizeProcessed; + if (encodeMode) + { + // we allocate 105% of original size for output buffer + size_t outSize = (size_t)fileSize / 20 * 21 + (1 << 16); + outBuffer = (Byte *)MyAlloc((size_t)outSize); + if (outBuffer == 0) + throw "Can not allocate memory"; + if (!dictionaryIsDefined) + dictionary = 1 << 23; + int res = LzmaRamEncode(inBuffer, inSize, outBuffer, outSize, &outSizeProcessed, + dictionary, SZ_FILTER_AUTO); + if (res != 0) + { + fprintf(stderr, "\nEncoder error = %d\n", (int)res); + return 1; + } + } + else + { + size_t outSize; + if (LzmaRamGetUncompressedSize(inBuffer, inSize, &outSize) != 0) + throw "data error"; + outBuffer = (Byte *)MyAlloc(outSize); + if (outBuffer == 0) + throw "Can not allocate memory"; + + int res = LzmaRamDecompress(inBuffer, inSize, outBuffer, outSize, &outSizeProcessed, malloc, free); + if (res != 0) + throw "LzmaDecoder error"; + } + if (outStream->Write(outBuffer, (UInt32)outSizeProcessed, &processedSize) != S_OK) + throw "Can not write"; + MyFree(outBuffer); + MyFree(inBuffer); + return 0; + } + + + UInt64 fileSize; + if (encodeMode) + { + NCompress::NLZMA::CEncoder *encoderSpec = + new NCompress::NLZMA::CEncoder; + CMyComPtr<ICompressCoder> encoder = encoderSpec; + + if (!dictionaryIsDefined) + dictionary = 1 << 23; + + UInt32 posStateBits = 2; + UInt32 litContextBits = 3; // for normal files + // UInt32 litContextBits = 0; // for 32-bit data + UInt32 litPosBits = 0; + // UInt32 litPosBits = 2; // for 32-bit data + UInt32 algorithm = 2; + UInt32 numFastBytes = 128; + + bool eos = parser[NKey::kEOS].ThereIs || stdInMode; + + if(parser[NKey::kMode].ThereIs) + if (!GetNumber(parser[NKey::kMode].PostStrings[0], algorithm)) + IncorrectCommand(); + + if(parser[NKey::kFastBytes].ThereIs) + if (!GetNumber(parser[NKey::kFastBytes].PostStrings[0], numFastBytes)) + IncorrectCommand(); + if(parser[NKey::kLitContext].ThereIs) + if (!GetNumber(parser[NKey::kLitContext].PostStrings[0], litContextBits)) + IncorrectCommand(); + if(parser[NKey::kLitPos].ThereIs) + if (!GetNumber(parser[NKey::kLitPos].PostStrings[0], litPosBits)) + IncorrectCommand(); + if(parser[NKey::kPosBits].ThereIs) + if (!GetNumber(parser[NKey::kPosBits].PostStrings[0], posStateBits)) + IncorrectCommand(); + + PROPID propIDs[] = + { + NCoderPropID::kDictionarySize, + NCoderPropID::kPosStateBits, + NCoderPropID::kLitContextBits, + NCoderPropID::kLitPosBits, + NCoderPropID::kAlgorithm, + NCoderPropID::kNumFastBytes, + NCoderPropID::kMatchFinder, + NCoderPropID::kEndMarker + }; + const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]); + /* + NWindows::NCOM::CPropVariant properties[kNumProps]; + properties[0] = UInt32(dictionary); + properties[1] = UInt32(posStateBits); + properties[2] = UInt32(litContextBits); + + properties[3] = UInt32(litPosBits); + properties[4] = UInt32(algorithm); + properties[5] = UInt32(numFastBytes); + properties[6] = mf; + properties[7] = eos; + */ + PROPVARIANT properties[kNumProps]; + for (int p = 0; p < 6; p++) + properties[p].vt = VT_UI4; + properties[0].ulVal = UInt32(dictionary); + properties[1].ulVal = UInt32(posStateBits); + properties[2].ulVal = UInt32(litContextBits); + properties[3].ulVal = UInt32(litPosBits); + properties[4].ulVal = UInt32(algorithm); + properties[5].ulVal = UInt32(numFastBytes); + + properties[6].vt = VT_BSTR; + properties[6].bstrVal = (BSTR)(const wchar_t *)mf; + + properties[7].vt = VT_BOOL; + properties[7].boolVal = eos ? VARIANT_TRUE : VARIANT_FALSE; + + if (encoderSpec->SetCoderProperties(propIDs, properties, kNumProps) != S_OK) + IncorrectCommand(); + encoderSpec->WriteCoderProperties(outStream); + + if (eos || stdInMode) + fileSize = (UInt64)(Int64)-1; + else + inStreamSpec->File.GetLength(fileSize); + + for (int i = 0; i < 8; i++) + { + Byte b = Byte(fileSize >> (8 * i)); + if (outStream->Write(&b, sizeof(b), 0) != S_OK) + { + fprintf(stderr, "Write error"); + return 1; + } + } + HRESULT result = encoder->Code(inStream, outStream, 0, 0, 0); + if (result == E_OUTOFMEMORY) + { + fprintf(stderr, "\nError: Can not allocate memory\n"); + return 1; + } + else if (result != S_OK) + { + fprintf(stderr, "\nEncoder error = %X\n", (unsigned int)result); + return 1; + } + } + else + { + NCompress::NLZMA::CDecoder *decoderSpec = + new NCompress::NLZMA::CDecoder; + CMyComPtr<ICompressCoder> decoder = decoderSpec; + const UInt32 kPropertiesSize = 5; + Byte properties[kPropertiesSize]; + UInt32 processedSize; + if (inStream->Read(properties, kPropertiesSize, &processedSize) != S_OK) + { + fprintf(stderr, "Read error"); + return 1; + } + if (processedSize != kPropertiesSize) + { + fprintf(stderr, "Read error"); + return 1; + } + if (decoderSpec->SetDecoderProperties2(properties, kPropertiesSize) != S_OK) + { + fprintf(stderr, "SetDecoderProperties error"); + return 1; + } + fileSize = 0; + for (int i = 0; i < 8; i++) + { + Byte b; + if (inStream->Read(&b, sizeof(b), &processedSize) != S_OK) + { + fprintf(stderr, "Read error"); + return 1; + } + if (processedSize != 1) + { + fprintf(stderr, "Read error"); + return 1; + } + fileSize |= ((UInt64)b) << (8 * i); + } + if (decoder->Code(inStream, outStream, 0, &fileSize, 0) != S_OK) + { + fprintf(stderr, "Decoder error"); + return 1; + } + } + return 0; +} + +int main(int n, const char *args[]) +{ + try { return main2(n, args); } + catch(const char *s) + { + fprintf(stderr, "\nError: %s\n", s); + return 1; + } + catch(...) + { + fprintf(stderr, "\nError\n"); + return 1; + } +} diff --git a/7zip/Compress/LZMA_Alone/LzmaBench.cpp b/7zip/Compress/LZMA_Alone/LzmaBench.cpp new file mode 100755 index 00000000..c491f97b --- /dev/null +++ b/7zip/Compress/LZMA_Alone/LzmaBench.cpp @@ -0,0 +1,528 @@ +// LzmaBench.cpp + +#include "StdAfx.h" + +#include "LzmaBench.h" + +#ifndef _WIN32 +#include <time.h> +#endif + +#include "../../../Common/CRC.h" +#include "../LZMA/LZMADecoder.h" +#include "../LZMA/LZMAEncoder.h" + +static const UInt32 kAdditionalSize = +#ifdef _WIN32_WCE +(1 << 20); +#else +(6 << 20); +#endif + +static const UInt32 kCompressedAdditionalSize = (1 << 10); +static const UInt32 kMaxLzmaPropSize = 10; + +class CRandomGenerator +{ + UInt32 A1; + UInt32 A2; +public: + CRandomGenerator() { Init(); } + void Init() { A1 = 362436069; A2 = 521288629;} + UInt32 GetRnd() + { + return + ((A1 = 36969 * (A1 & 0xffff) + (A1 >> 16)) << 16) ^ + ((A2 = 18000 * (A2 & 0xffff) + (A2 >> 16)) ); + } +}; + +class CBitRandomGenerator +{ + CRandomGenerator RG; + UInt32 Value; + int NumBits; +public: + void Init() + { + Value = 0; + NumBits = 0; + } + UInt32 GetRnd(int numBits) + { + if (NumBits > numBits) + { + UInt32 result = Value & ((1 << numBits) - 1); + Value >>= numBits; + NumBits -= numBits; + return result; + } + numBits -= NumBits; + UInt32 result = (Value << numBits); + Value = RG.GetRnd(); + result |= Value & ((1 << numBits) - 1); + Value >>= numBits; + NumBits = 32 - numBits; + return result; + } +}; + +class CBenchRandomGenerator +{ + CBitRandomGenerator RG; + UInt32 Pos; +public: + UInt32 BufferSize; + Byte *Buffer; + CBenchRandomGenerator(): Buffer(0) {} + ~CBenchRandomGenerator() { delete []Buffer; } + void Init() { RG.Init(); } + void Set(UInt32 bufferSize) + { + delete []Buffer; + Buffer = 0; + Buffer = new Byte[bufferSize]; + Pos = 0; + BufferSize = bufferSize; + } + UInt32 GetRndBit() { return RG.GetRnd(1); } + /* + UInt32 GetLogRand(int maxLen) + { + UInt32 len = GetRnd() % (maxLen + 1); + return GetRnd() & ((1 << len) - 1); + } + */ + UInt32 GetLogRandBits(int numBits) + { + UInt32 len = RG.GetRnd(numBits); + return RG.GetRnd(len); + } + UInt32 GetOffset() + { + if (GetRndBit() == 0) + return GetLogRandBits(4); + return (GetLogRandBits(4) << 10) | RG.GetRnd(10); + } + UInt32 GetLen() + { + if (GetRndBit() == 0) + return RG.GetRnd(2); + if (GetRndBit() == 0) + return 4 + RG.GetRnd(3); + return 12 + RG.GetRnd(4); + } + void Generate() + { + while(Pos < BufferSize) + { + if (GetRndBit() == 0 || Pos < 1) + Buffer[Pos++] = Byte(RG.GetRnd(8)); + else + { + UInt32 offset = GetOffset(); + while (offset >= Pos) + offset >>= 1; + offset += 1; + UInt32 len = 2 + GetLen(); + for (UInt32 i = 0; i < len && Pos < BufferSize; i++, Pos++) + Buffer[Pos] = Buffer[Pos - offset]; + } + } + } +}; + +class CBenchmarkInStream: + public ISequentialInStream, + public CMyUnknownImp +{ + const Byte *Data; + UInt32 Pos; + UInt32 Size; +public: + MY_UNKNOWN_IMP + void Init(const Byte *data, UInt32 size) + { + Data = data; + Size = size; + Pos = 0; + } + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); +}; + +STDMETHODIMP CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 remain = Size - Pos; + if (size > remain) + size = remain; + for (UInt32 i = 0; i < size; i++) + { + ((Byte *)data)[i] = Data[Pos + i]; + } + Pos += size; + if(processedSize != NULL) + *processedSize = size; + return S_OK; +} + +STDMETHODIMP CBenchmarkInStream::ReadPart(void *data, UInt32 size, UInt32 *processedSize) +{ + return Read(data, size, processedSize); +} + +class CBenchmarkOutStream: + public ISequentialOutStream, + public CMyUnknownImp +{ + UInt32 BufferSize; + FILE *_f; +public: + UInt32 Pos; + Byte *Buffer; + CBenchmarkOutStream(): _f(0), Buffer(0) {} + virtual ~CBenchmarkOutStream() { delete []Buffer; } + void Init(FILE *f, UInt32 bufferSize) + { + delete []Buffer; + Buffer = 0; + Buffer = new Byte[bufferSize]; + Pos = 0; + BufferSize = bufferSize; + _f = f; + } + MY_UNKNOWN_IMP + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +STDMETHODIMP CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 i; + for (i = 0; i < size && Pos < BufferSize; i++) + Buffer[Pos++] = ((const Byte *)data)[i]; + if(processedSize != NULL) + *processedSize = i; + if (i != size) + { + fprintf(_f, "\nERROR: Buffer is full\n"); + return E_FAIL; + } + return S_OK; +} + +STDMETHODIMP CBenchmarkOutStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize) +{ + return Write(data, size, processedSize); +} + +class CCrcOutStream: + public ISequentialOutStream, + public CMyUnknownImp +{ +public: + CCRC CRC; + MY_UNKNOWN_IMP + void Init() { CRC.Init(); } + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +STDMETHODIMP CCrcOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + CRC.Update(data, size); + if(processedSize != NULL) + *processedSize = size; + return S_OK; +} + +STDMETHODIMP CCrcOutStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize) +{ + return Write(data, size, processedSize); +} + +static UInt64 GetTimeCount() +{ + #ifdef _WIN32 + LARGE_INTEGER value; + if (::QueryPerformanceCounter(&value)) + return value.QuadPart; + return GetTickCount(); + #else + return clock(); + #endif +} + +static UInt64 GetFreq() +{ + #ifdef _WIN32 + LARGE_INTEGER value; + if (::QueryPerformanceFrequency(&value)) + return value.QuadPart; + return 1000; + #else + return CLOCKS_PER_SEC; + #endif +} + +struct CProgressInfo: + public ICompressProgressInfo, + public CMyUnknownImp +{ + UInt64 ApprovedStart; + UInt64 InSize; + UInt64 Time; + void Init() + { + InSize = 0; + Time = 0; + } + MY_UNKNOWN_IMP + STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); +}; + +STDMETHODIMP CProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) +{ + if (*inSize >= ApprovedStart && InSize == 0) + { + Time = ::GetTimeCount(); + InSize = *inSize; + } + return S_OK; +} + +static const int kSubBits = 8; + +static UInt32 GetLogSize(UInt32 size) +{ + for (int i = kSubBits; i < 32; i++) + for (UInt32 j = 0; j < (1 << kSubBits); j++) + if (size <= (((UInt32)1) << i) + (j << (i - kSubBits))) + return (i << kSubBits) + j; + return (32 << kSubBits); +} + +static UInt64 MyMultDiv64(UInt64 value, UInt64 elapsedTime) +{ + UInt64 freq = GetFreq(); + UInt64 elTime = elapsedTime; + while(freq > 1000000) + { + freq >>= 1; + elTime >>= 1; + } + if (elTime == 0) + elTime = 1; + return value * freq / elTime; +} + +static UInt64 GetCompressRating(UInt32 dictionarySize, bool isBT4, + UInt64 elapsedTime, UInt64 size) +{ + UInt64 numCommandsForOne; + if (isBT4) + { + UInt64 t = GetLogSize(dictionarySize) - (19 << kSubBits); + numCommandsForOne = 2000 + ((t * t * 68) >> (2 * kSubBits)); + } + else + { + UInt64 t = GetLogSize(dictionarySize) - (15 << kSubBits); + numCommandsForOne = 1500 + ((t * t * 41) >> (2 * kSubBits)); + } + UInt64 numCommands = (UInt64)(size) * numCommandsForOne; + return MyMultDiv64(numCommands, elapsedTime); +} + +static UInt64 GetDecompressRating(UInt64 elapsedTime, + UInt64 outSize, UInt64 inSize) +{ + UInt64 numCommands = inSize * 250 + outSize * 21; + return MyMultDiv64(numCommands, elapsedTime); +} + +/* +static UInt64 GetTotalRating( + UInt32 dictionarySize, + bool isBT4, + UInt64 elapsedTimeEn, UInt64 sizeEn, + UInt64 elapsedTimeDe, + UInt64 inSizeDe, UInt64 outSizeDe) +{ + return (GetCompressRating(dictionarySize, isBT4, elapsedTimeEn, sizeEn) + + GetDecompressRating(elapsedTimeDe, inSizeDe, outSizeDe)) / 2; +} +*/ + +static void PrintRating(FILE *f, UInt64 rating) +{ + fprintf(f, "%5d MIPS", (unsigned int)(rating / 1000000)); +} + +static void PrintResults( + FILE *f, + UInt32 dictionarySize, + bool isBT4, + UInt64 elapsedTime, + UInt64 size, + bool decompressMode, UInt64 secondSize) +{ + UInt64 speed = MyMultDiv64(size, elapsedTime); + fprintf(f, "%6d KB/s ", (unsigned int)(speed / 1024)); + UInt64 rating; + if (decompressMode) + rating = GetDecompressRating(elapsedTime, size, secondSize); + else + rating = GetCompressRating(dictionarySize, isBT4, elapsedTime, size); + PrintRating(f, rating); +} + +static void ThrowError(FILE *f, HRESULT result, const char *s) +{ + fprintf(f, "\nError: "); + if (result == E_ABORT) + fprintf(f, "User break"); + if (result == E_OUTOFMEMORY) + fprintf(f, "Can not allocate memory"); + else + fprintf(f, s); + fprintf(f, "\n"); +} + +const wchar_t *bt2 = L"BT2"; +const wchar_t *bt4 = L"BT4"; + +int LzmaBenchmark(FILE *f, UInt32 numIterations, UInt32 dictionarySize, bool isBT4) +{ + if (numIterations == 0) + return 0; + if (dictionarySize < (1 << 19) && isBT4 || dictionarySize < (1 << 15)) + { + fprintf(f, "\nError: dictionary size for benchmark must be >= 19 (512 KB)\n"); + return 1; + } + fprintf(f, "\n Compressing Decompressing\n\n"); + NCompress::NLZMA::CEncoder *encoderSpec = new NCompress::NLZMA::CEncoder; + CMyComPtr<ICompressCoder> encoder = encoderSpec; + + NCompress::NLZMA::CDecoder *decoderSpec = new NCompress::NLZMA::CDecoder; + CMyComPtr<ICompressCoder> decoder = decoderSpec; + + CBenchmarkOutStream *propStreamSpec = new CBenchmarkOutStream; + CMyComPtr<ISequentialOutStream> propStream = propStreamSpec; + propStreamSpec->Init(f, kMaxLzmaPropSize); + + PROPID propIDs[] = + { + NCoderPropID::kDictionarySize, + NCoderPropID::kMatchFinder + }; + const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]); + PROPVARIANT properties[kNumProps]; + properties[0].vt = VT_UI4; + properties[0].ulVal = UInt32(dictionarySize); + + properties[1].vt = VT_BSTR; + properties[1].bstrVal = isBT4 ? (BSTR)bt4: (BSTR)bt2; + + const UInt32 kBufferSize = dictionarySize + kAdditionalSize; + const UInt32 kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize; + + if (encoderSpec->SetCoderProperties(propIDs, properties, kNumProps) != S_OK) + { + fprintf(f, "\nError: Incorrect command\n"); + return 1; + } + encoderSpec->WriteCoderProperties(propStream); + + CBenchRandomGenerator rg; + rg.Init(); + rg.Set(kBufferSize); + rg.Generate(); + CCRC crc; + crc.Update(rg.Buffer, rg.BufferSize); + + CProgressInfo *progressInfoSpec = new CProgressInfo; + CMyComPtr<ICompressProgressInfo> progressInfo = progressInfoSpec; + + progressInfoSpec->ApprovedStart = dictionarySize; + + UInt64 totalBenchSize = 0; + UInt64 totalEncodeTime = 0; + UInt64 totalDecodeTime = 0; + UInt64 totalCompressedSize = 0; + + for (UInt32 i = 0; i < numIterations; i++) + { + progressInfoSpec->Init(); + CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream; + inStreamSpec->Init(rg.Buffer, rg.BufferSize); + CMyComPtr<ISequentialInStream> inStream = inStreamSpec; + CBenchmarkOutStream *outStreamSpec = new CBenchmarkOutStream; + outStreamSpec->Init(f, kCompressedBufferSize); + CMyComPtr<ISequentialOutStream> outStream = outStreamSpec; + HRESULT result = encoder->Code(inStream, outStream, 0, 0, progressInfo); + UInt64 encodeTime = ::GetTimeCount() - progressInfoSpec->Time; + UInt32 compressedSize = outStreamSpec->Pos; + if(result != S_OK) + { + ThrowError(f, result, "Encoder Error"); + return 1; + } + if (progressInfoSpec->InSize == 0) + { + fprintf(f, "\nError: Internal ERROR 1282\n"); + return 1; + } + + /////////////////////// + // Decompressing + + CCrcOutStream *crcOutStreamSpec = new CCrcOutStream; + CMyComPtr<ISequentialOutStream> crcOutStream = crcOutStreamSpec; + + UInt64 decodeTime; + for (int j = 0; j < 2; j++) + { + inStreamSpec->Init(outStreamSpec->Buffer, compressedSize); + crcOutStreamSpec->Init(); + + if (decoderSpec->SetDecoderProperties2(propStreamSpec->Buffer, propStreamSpec->Pos) != S_OK) + { + fprintf(f, "\nError: Set Decoder Properties Error\n"); + return 1; + } + UInt64 outSize = kBufferSize; + UInt64 startTime = ::GetTimeCount(); + result = decoder->Code(inStream, crcOutStream, 0, &outSize, 0); + decodeTime = ::GetTimeCount() - startTime; + if(result != S_OK) + { + ThrowError(f, result, "Decode Error"); + return 1; + } + if (crcOutStreamSpec->CRC.GetDigest() != crc.GetDigest()) + { + fprintf(f, "\nError: CRC Error\n"); + return 1; + } + } + UInt64 benchSize = kBufferSize - progressInfoSpec->InSize; + PrintResults(f, dictionarySize, isBT4, encodeTime, benchSize, false, 0); + fprintf(f, " "); + PrintResults(f, dictionarySize, isBT4, decodeTime, kBufferSize, true, compressedSize); + fprintf(f, "\n"); + + totalBenchSize += benchSize; + totalEncodeTime += encodeTime; + totalDecodeTime += decodeTime; + totalCompressedSize += compressedSize; + } + fprintf(f, "---------------------------------------------------\n"); + PrintResults(f, dictionarySize, isBT4, totalEncodeTime, totalBenchSize, false, 0); + fprintf(f, " "); + PrintResults(f, dictionarySize, isBT4, totalDecodeTime, + kBufferSize * numIterations, true, totalCompressedSize); + fprintf(f, " Average\n"); + return 0; +} diff --git a/7zip/Compress/LZMA_Alone/LzmaBench.h b/7zip/Compress/LZMA_Alone/LzmaBench.h new file mode 100755 index 00000000..bf1d3e0a --- /dev/null +++ b/7zip/Compress/LZMA_Alone/LzmaBench.h @@ -0,0 +1,11 @@ +// LzmaBench.h + +#ifndef __LzmaBench_h +#define __LzmaBench_h + +#include <stdio.h> +#include "../../../Common/Types.h" + +int LzmaBenchmark(FILE *f, UInt32 numIterations, UInt32 dictionarySize, bool isBT4); + +#endif diff --git a/7zip/Compress/LZMA_Alone/LzmaRam.cpp b/7zip/Compress/LZMA_Alone/LzmaRam.cpp new file mode 100755 index 00000000..bc8a0937 --- /dev/null +++ b/7zip/Compress/LZMA_Alone/LzmaRam.cpp @@ -0,0 +1,239 @@ +// LzmaRam.cpp + +#include "StdAfx.h" +#include "../../../Common/Types.h" +#include "../LZMA/LZMADecoder.h" +#include "../LZMA/LZMAEncoder.h" +#include "LzmaRam.h" + +extern "C" +{ +#include "../Branch/BranchX86.h" +} + +class CInStreamRam: + public ISequentialInStream, + public CMyUnknownImp +{ + const Byte *Data; + size_t Size; + size_t Pos; +public: + MY_UNKNOWN_IMP + void Init(const Byte *data, size_t size) + { + Data = data; + Size = size; + Pos = 0; + } + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); +}; + +STDMETHODIMP CInStreamRam::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 remain = Size - Pos; + if (size > remain) + size = remain; + for (UInt32 i = 0; i < size; i++) + { + ((Byte *)data)[i] = Data[Pos + i]; + } + Pos += size; + if(processedSize != NULL) + *processedSize = size; + return S_OK; +} + +STDMETHODIMP CInStreamRam::ReadPart(void *data, UInt32 size, UInt32 *processedSize) +{ + return Read(data, size, processedSize); +} + +class COutStreamRam: + public ISequentialOutStream, + public CMyUnknownImp +{ + size_t Size; +public: + Byte *Data; + size_t Pos; + bool Overflow; + void Init(Byte *data, size_t size) + { + Data = data; + Size = size; + Pos = 0; + Overflow = false; + } + void SetPos(size_t pos) + { + Overflow = false; + Pos = pos; + } + MY_UNKNOWN_IMP + HRESULT WriteByte(Byte b) + { + if (Pos >= Size) + { + Overflow = true; + return E_FAIL; + } + Data[Pos++] = b; + return S_OK; + } + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +STDMETHODIMP COutStreamRam::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 i; + for (i = 0; i < size && Pos < Size; i++) + Data[Pos++] = ((const Byte *)data)[i]; + if(processedSize != NULL) + *processedSize = i; + if (i != size) + { + Overflow = true; + return E_FAIL; + } + return S_OK; +} + +STDMETHODIMP COutStreamRam::WritePart(const void *data, UInt32 size, UInt32 *processedSize) +{ + return Write(data, size, processedSize); +} + +#define SZE_FAIL (1) +#define SZE_OUTOFMEMORY (2) +#define SZE_OUT_OVERFLOW (3) + +int LzmaRamEncode( + const Byte *inBuffer, size_t inSize, + Byte *outBuffer, size_t outSize, size_t *outSizeProcessed, + UInt32 dictionarySize, ESzFilterMode filterMode) +{ + #ifndef _NO_EXCEPTIONS + try { + #endif + + *outSizeProcessed = 0; + const size_t kIdSize = 1; + const size_t kLzmaPropsSize = 5; + const size_t kMinDestSize = kIdSize + kLzmaPropsSize + 8; + if (outSize < kMinDestSize) + return SZE_OUT_OVERFLOW; + NCompress::NLZMA::CEncoder *encoderSpec = new NCompress::NLZMA::CEncoder; + CMyComPtr<ICompressCoder> encoder = encoderSpec; + + PROPID propIDs[] = + { + NCoderPropID::kAlgorithm, + NCoderPropID::kDictionarySize, + NCoderPropID::kNumFastBytes, + }; + const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]); + PROPVARIANT properties[kNumProps]; + properties[0].vt = VT_UI4; + properties[1].vt = VT_UI4; + properties[2].vt = VT_UI4; + properties[0].ulVal = (UInt32)2; + properties[1].ulVal = (UInt32)dictionarySize; + properties[2].ulVal = (UInt32)64; + + if (encoderSpec->SetCoderProperties(propIDs, properties, kNumProps) != S_OK) + return 1; + + COutStreamRam *outStreamSpec = new COutStreamRam; + if (outStreamSpec == 0) + return SZE_OUTOFMEMORY; + CMyComPtr<ISequentialOutStream> outStream = outStreamSpec; + CInStreamRam *inStreamSpec = new CInStreamRam; + if (inStreamSpec == 0) + return SZE_OUTOFMEMORY; + CMyComPtr<ISequentialInStream> inStream = inStreamSpec; + + outStreamSpec->Init(outBuffer, outSize); + if (outStreamSpec->WriteByte(0) != S_OK) + return SZE_OUT_OVERFLOW; + + if (encoderSpec->WriteCoderProperties(outStream) != S_OK) + return SZE_OUT_OVERFLOW; + if (outStreamSpec->Pos != kIdSize + kLzmaPropsSize) + return 1; + + int i; + for (i = 0; i < 8; i++) + { + UInt64 t = (UInt64)(inSize); + if (outStreamSpec->WriteByte((Byte)((t) >> (8 * i))) != S_OK) + return SZE_OUT_OVERFLOW; + } + + Byte *filteredStream = 0; + + bool useFilter = (filterMode != SZ_FILTER_NO); + if (useFilter) + { + filteredStream = (Byte *)MyAlloc(inSize); + if (filteredStream == 0) + return SZE_OUTOFMEMORY; + memmove(filteredStream, inBuffer, inSize); + UInt32 _prevMask; + UInt32 _prevPos; + x86_Convert_Init(_prevMask, _prevPos); + x86_Convert(filteredStream, (UInt32)inSize, 0, &_prevMask, &_prevPos, 1); + } + + UInt32 minSize = 0; + int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1; + bool bestIsFiltered = false; + int mainResult = 0; + size_t startPos = outStreamSpec->Pos; + for (i = 0; i < numPasses; i++) + { + if (numPasses > 1 && i == numPasses - 1 && !bestIsFiltered) + break; + outStreamSpec->SetPos(startPos); + bool curModeIsFiltered = false; + if (useFilter && i == 0) + curModeIsFiltered = true; + if (numPasses > 1 && i == numPasses - 1) + curModeIsFiltered = true; + + inStreamSpec->Init(curModeIsFiltered ? filteredStream : inBuffer, inSize); + + HRESULT lzmaResult = encoder->Code(inStream, outStream, 0, 0, 0); + + mainResult = 0; + if (lzmaResult == E_OUTOFMEMORY) + { + mainResult = SZE_OUTOFMEMORY; + break; + } + if (i == 0 || outStreamSpec->Pos <= minSize) + { + minSize = outStreamSpec->Pos; + bestIsFiltered = curModeIsFiltered; + } + if (outStreamSpec->Overflow) + mainResult = SZE_OUT_OVERFLOW; + else if (lzmaResult != S_OK) + { + mainResult = SZE_FAIL; + break; + } + } + *outSizeProcessed = outStreamSpec->Pos; + if (bestIsFiltered) + outBuffer[0] = 1; + if (useFilter) + MyFree(filteredStream); + return mainResult; + + #ifndef _NO_EXCEPTIONS + } catch(...) { return SZE_OUTOFMEMORY; } + #endif +} diff --git a/7zip/Compress/LZMA_Alone/LzmaRam.h b/7zip/Compress/LZMA_Alone/LzmaRam.h new file mode 100755 index 00000000..1244dc86 --- /dev/null +++ b/7zip/Compress/LZMA_Alone/LzmaRam.h @@ -0,0 +1,46 @@ +// LzmaRam.h + +#ifndef __LzmaRam_h +#define __LzmaRam_h + +#include <stdlib.h> +#include "../../../Common/Types.h" + +/* +LzmaRamEncode: BCJ + LZMA RAM->RAM compressing. +It uses .lzma format, but it writes one additional byte to .lzma file: + 0: - no filter + 1: - x86(BCJ) filter. + +To provide best compression ratio dictionarySize mustbe >= inSize + +LzmaRamEncode allocates Data with MyAlloc/BigAlloc functions. +RAM Requirements: + RamSize = dictionarySize * 9.5 + 6MB + FilterBlockSize + FilterBlockSize = 0, if useFilter == false + FilterBlockSize = inSize, if useFilter == true + + Return code: + 0 - OK + 1 - Unspecified Error + 2 - Memory allocating error + 3 - Output buffer OVERFLOW + +If you use SZ_FILTER_AUTO mode, then encoder will use 2 or 3 passes: + 2 passes when FILTER_NO provides better compression. + 3 passes when FILTER_YES provides better compression. +*/ + +enum ESzFilterMode +{ + SZ_FILTER_NO, + SZ_FILTER_YES, + SZ_FILTER_AUTO +}; + +int LzmaRamEncode( + const Byte *inBuffer, size_t inSize, + Byte *outBuffer, size_t outSize, size_t *outSizeProcessed, + UInt32 dictionarySize, ESzFilterMode filterMode); + +#endif diff --git a/7zip/Compress/LZMA_Alone/LzmaRamDecode.c b/7zip/Compress/LZMA_Alone/LzmaRamDecode.c new file mode 100755 index 00000000..f576d12e --- /dev/null +++ b/7zip/Compress/LZMA_Alone/LzmaRamDecode.c @@ -0,0 +1,88 @@ +/* LzmaRamDecode.c */ + +#include "LzmaRamDecode.h" +#ifdef _SZ_ONE_DIRECTORY +#include "LzmaDecode.h" +#include "BranchX86.h" +#else +#include "../LZMA_C/LzmaDecode.h" +#include "../Branch/BranchX86.h" +#endif + +#define LZMA_PROPS_SIZE 14 +#define LZMA_SIZE_OFFSET 6 + +int LzmaRamGetUncompressedSize( + unsigned char *inBuffer, + size_t inSize, + size_t *outSize) +{ + unsigned int i; + if (inSize < LZMA_PROPS_SIZE) + return 1; + *outSize = 0; + for(i = 0; i < sizeof(size_t); i++) + *outSize += ((size_t)inBuffer[LZMA_SIZE_OFFSET + i]) << (8 * i); + for(; i < 8; i++) + if (inBuffer[LZMA_SIZE_OFFSET + i] != 0) + return 1; + return 0; +} + +#define SZE_DATA_ERROR (1) +#define SZE_OUTOFMEMORY (2) + +int LzmaRamDecompress( + unsigned char *inBuffer, + size_t inSize, + unsigned char *outBuffer, + size_t outSize, + size_t *outSizeProcessed, + void * (*allocFunc)(size_t size), + void (*freeFunc)(void *)) +{ + int lc, lp, pb; + size_t lzmaInternalSize; + void *lzmaInternalData; + int result; + UInt32 outSizeProcessedLoc; + + int useFilter = inBuffer[0]; + + *outSizeProcessed = 0; + if (useFilter > 1) + return 1; + + if (inSize < LZMA_PROPS_SIZE) + return 1; + lc = inBuffer[1]; + if (lc >= (9 * 5 * 5)) + return 1; + for (pb = 0; lc >= (9 * 5); pb++, lc -= (9 * 5)); + for (lp = 0; lc >= 9; lp++, lc -= 9); + + lzmaInternalSize = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp))) * sizeof(CProb); + lzmaInternalData = allocFunc(lzmaInternalSize); + if (lzmaInternalData == 0) + return SZE_OUTOFMEMORY; + + result = LzmaDecode((unsigned char *)lzmaInternalData, (UInt32)lzmaInternalSize, + lc, lp, pb, + inBuffer + LZMA_PROPS_SIZE, (UInt32)inSize - LZMA_PROPS_SIZE, + outBuffer, (UInt32)outSize, + &outSizeProcessedLoc); + freeFunc(lzmaInternalData); + if (result != LZMA_RESULT_OK) + return 1; + *outSizeProcessed = (size_t)outSizeProcessedLoc; + if (useFilter == 1) + { + UInt32 _prevMask; + UInt32 _prevPos; + x86_Convert_Init(_prevMask, _prevPos); + x86_Convert(outBuffer, (UInt32)outSizeProcessedLoc, 0, &_prevMask, &_prevPos, 0); + } + return 0; +} + + diff --git a/7zip/Compress/LZMA_Alone/LzmaRamDecode.h b/7zip/Compress/LZMA_Alone/LzmaRamDecode.h new file mode 100755 index 00000000..8c0fb9d1 --- /dev/null +++ b/7zip/Compress/LZMA_Alone/LzmaRamDecode.h @@ -0,0 +1,55 @@ +/* LzmaRamDecode.h */ + +#ifndef __LzmaRamDecode_h +#define __LzmaRamDecode_h + +#include <stdlib.h> + +/* +LzmaRamGetUncompressedSize: + In: + inBuffer - input data + inSize - input data size + Out: + outSize - uncompressed size + Return code: + 0 - OK + 1 - Error in headers +*/ + +int LzmaRamGetUncompressedSize( + unsigned char *inBuffer, + size_t inSize, + size_t *outSize); + + +/* +LzmaRamDecompress: + In: + inBuffer - input data + inSize - input data size + outBuffer - output data + outSize - output size + allocFunc - alloc function (can be malloc) + freeFunc - free function (can be free) + Out: + outSizeProcessed - processed size + Return code: + 0 - OK + 1 - Error in headers / data stream + 2 - Memory allocating error + +Memory requirements depend from properties of LZMA stream. +With default lzma settings it's about 16 KB. +*/ + +int LzmaRamDecompress( + unsigned char *inBuffer, + size_t inSize, + unsigned char *outBuffer, + size_t outSize, + size_t *outSizeProcessed, + void * (*allocFunc)(size_t size), + void (*freeFunc)(void *)); + +#endif diff --git a/7zip/Compress/LZMA_Alone/StdAfx.cpp b/7zip/Compress/LZMA_Alone/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/7zip/Compress/LZMA_Alone/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/7zip/Compress/LZMA_Alone/StdAfx.h b/7zip/Compress/LZMA_Alone/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/7zip/Compress/LZMA_Alone/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/7zip/Compress/LZMA_Alone/makefile b/7zip/Compress/LZMA_Alone/makefile new file mode 100755 index 00000000..afc64388 --- /dev/null +++ b/7zip/Compress/LZMA_Alone/makefile @@ -0,0 +1,109 @@ +PROG = lzma +CXX = g++ -O2 -Wall +CXX_C = gcc -O2 -Wall +LIB = -lm +RM = rm -f +CFLAGS = -c -I ../../../ + +OBJS = \ + LzmaAlone.o \ + LzmaBench.o \ + LzmaRam.o \ + LzmaRamDecode.o \ + LzmaDecode.o \ + BranchX86.o \ + LZMADecoder.o \ + LZMAEncoder.o \ + LZInWindow.o \ + LZOutWindow.o \ + RangeCoderBit.o \ + InBuffer.o \ + OutBuffer.o \ + FileStreams.o \ + Alloc.o \ + C_FileIO.o \ + CommandLineParser.o \ + CRC.o \ + String.o \ + StringConvert.o \ + StringToInt.o \ + Vector.o \ + + +all: $(PROG) + +$(PROG): $(OBJS) + $(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB) + +LzmaAlone.o: LzmaAlone.cpp + $(CXX) $(CFLAGS) LzmaAlone.cpp + +LzmaBench.o: LzmaBench.cpp + $(CXX) $(CFLAGS) LzmaBench.cpp + +LzmaRam.o: LzmaRam.cpp + $(CXX) $(CFLAGS) LzmaRam.cpp + +LzmaRamDecode.o: LzmaRamDecode.c + $(CXX_C) $(CFLAGS) LzmaRamDecode.c + +LzmaDecode.o: ../LZMA_C/LzmaDecode.c + $(CXX_C) $(CFLAGS) ../LZMA_C/LzmaDecode.c + +BranchX86.o: ../Branch/BranchX86.c + $(CXX_C) $(CFLAGS) ../Branch/BranchX86.c + +LZMADecoder.o: ../LZMA/LZMADecoder.cpp + $(CXX) $(CFLAGS) ../LZMA/LZMADecoder.cpp + +LZMAEncoder.o: ../LZMA/LZMAEncoder.cpp + $(CXX) $(CFLAGS) ../LZMA/LZMAEncoder.cpp + +LZInWindow.o: ../LZ/LZInWindow.cpp + $(CXX) $(CFLAGS) ../LZ/LZInWindow.cpp + +LZOutWindow.o: ../LZ/LZOutWindow.cpp + $(CXX) $(CFLAGS) ../LZ/LZOutWindow.cpp + +RangeCoderBit.o: ../RangeCoder/RangeCoderBit.cpp + $(CXX) $(CFLAGS) ../RangeCoder/RangeCoderBit.cpp + +InBuffer.o: ../../Common/InBuffer.cpp + $(CXX) $(CFLAGS) ../../Common/InBuffer.cpp + +OutBuffer.o: ../../Common/OutBuffer.cpp + $(CXX) $(CFLAGS) ../../Common/OutBuffer.cpp + +FileStreams.o: ../../Common/FileStreams.cpp + $(CXX) $(CFLAGS) ../../Common/FileStreams.cpp + +Alloc.o: ../../../Common/Alloc.cpp + $(CXX) $(CFLAGS) ../../../Common/Alloc.cpp + +C_FileIO.o: ../../../Common/C_FileIO.cpp + $(CXX) $(CFLAGS) ../../../Common/C_FileIO.cpp + +CommandLineParser.o: ../../../Common/CommandLineParser.cpp + $(CXX) $(CFLAGS) ../../../Common/CommandLineParser.cpp + +CRC.o: ../../../Common/CRC.cpp + $(CXX) $(CFLAGS) ../../../Common/CRC.cpp + +MyWindows.o: ../../../Common/MyWindows.cpp + $(CXX) $(CFLAGS) ../../../Common/MyWindows.cpp + +String.o: ../../../Common/String.cpp + $(CXX) $(CFLAGS) ../../../Common/String.cpp + +StringConvert.o: ../../../Common/StringConvert.cpp + $(CXX) $(CFLAGS) ../../../Common/StringConvert.cpp + +StringToInt.o: ../../../Common/StringToInt.cpp + $(CXX) $(CFLAGS) ../../../Common/StringToInt.cpp + +Vector.o: ../../../Common/Vector.cpp + $(CXX) $(CFLAGS) ../../../Common/Vector.cpp + +clean: + -$(RM) $(PROG) $(OBJS) + diff --git a/7zip/Compress/LZMA_C/LzmaDecode.c b/7zip/Compress/LZMA_C/LzmaDecode.c new file mode 100755 index 00000000..a17d6caa --- /dev/null +++ b/7zip/Compress/LZMA_C/LzmaDecode.c @@ -0,0 +1,586 @@ +/* + LzmaDecode.c + LZMA Decoder (optimized for Speed version) + + LZMA SDK 4.17 Copyright (c) 1999-2005 Igor Pavlov (2005-04-05) + http://www.7-zip.org/ + + LZMA SDK is licensed under two licenses: + 1) GNU Lesser General Public License (GNU LGPL) + 2) Common Public License (CPL) + It means that you can select one of these two licenses and + follow rules of that license. + + SPECIAL EXCEPTION: + Igor Pavlov, as the author of this Code, expressly permits you to + statically or dynamically link your Code (or bind by name) to the + interfaces of this file without subjecting your linked Code to the + terms of the CPL or GNU LGPL. Any modifications or additions + to this file, however, are subject to the LGPL or CPL terms. +*/ + +#include "LzmaDecode.h" + +#ifndef Byte +#define Byte unsigned char +#endif + +#define kNumTopBits 24 +#define kTopValue ((UInt32)1 << kNumTopBits) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 + +#define RC_READ_BYTE (*Buffer++) + +#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \ + { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }} + +#ifdef _LZMA_IN_CB + +#define RC_TEST { if (Buffer == BufferLim) \ + { UInt32 size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) return result; \ + BufferLim = Buffer + size; if (size == 0) return LZMA_RESULT_DATA_ERROR; }} + +#define RC_INIT Buffer = BufferLim = 0; RC_INIT2 + +#else + +#define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; } + +#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2 + +#endif + +#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; } + +#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound) +#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits; +#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits; + +#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \ + { UpdateBit0(p); mi <<= 1; A0; } else \ + { UpdateBit1(p); mi = (mi + mi) + 1; A1; } + +#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;) + +#define RangeDecoderBitTreeDecode(probs, numLevels, res) \ + { int i = numLevels; res = 1; \ + do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \ + res -= (1 << numLevels); } + + +#define kNumPosBitsMax 4 +#define kNumPosStatesMax (1 << kNumPosBitsMax) + +#define kLenNumLowBits 3 +#define kLenNumLowSymbols (1 << kLenNumLowBits) +#define kLenNumMidBits 3 +#define kLenNumMidSymbols (1 << kLenNumMidBits) +#define kLenNumHighBits 8 +#define kLenNumHighSymbols (1 << kLenNumHighBits) + +#define LenChoice 0 +#define LenChoice2 (LenChoice + 1) +#define LenLow (LenChoice2 + 1) +#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) +#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) +#define kNumLenProbs (LenHigh + kLenNumHighSymbols) + + +#define kNumStates 12 +#define kNumLitStates 7 + +#define kStartPosModelIndex 4 +#define kEndPosModelIndex 14 +#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) + +#define kNumPosSlotBits 6 +#define kNumLenToPosStates 4 + +#define kNumAlignBits 4 +#define kAlignTableSize (1 << kNumAlignBits) + +#define kMatchMinLen 2 + +#define IsMatch 0 +#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) +#define IsRepG0 (IsRep + kNumStates) +#define IsRepG1 (IsRepG0 + kNumStates) +#define IsRepG2 (IsRepG1 + kNumStates) +#define IsRep0Long (IsRepG2 + kNumStates) +#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) +#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) +#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) +#define LenCoder (Align + kAlignTableSize) +#define RepLenCoder (LenCoder + kNumLenProbs) +#define Literal (RepLenCoder + kNumLenProbs) + +#if Literal != LZMA_BASE_SIZE +StopCompilingDueBUG +#endif + +#ifdef _LZMA_OUT_READ + +typedef struct _LzmaVarState +{ + Byte *Buffer; + Byte *BufferLim; + UInt32 Range; + UInt32 Code; + #ifdef _LZMA_IN_CB + ILzmaInCallback *InCallback; + #endif + Byte *Dictionary; + UInt32 DictionarySize; + UInt32 DictionaryPos; + UInt32 GlobalPos; + UInt32 Reps[4]; + int lc; + int lp; + int pb; + int State; + int RemainLen; + Byte TempDictionary[4]; +} LzmaVarState; + +int LzmaDecoderInit( + unsigned char *buffer, UInt32 bufferSize, + int lc, int lp, int pb, + unsigned char *dictionary, UInt32 dictionarySize, + #ifdef _LZMA_IN_CB + ILzmaInCallback *InCallback + #else + unsigned char *inStream, UInt32 inSize + #endif + ) +{ + Byte *Buffer; + Byte *BufferLim; + UInt32 Range; + UInt32 Code; + LzmaVarState *vs = (LzmaVarState *)buffer; + CProb *p = (CProb *)(buffer + sizeof(LzmaVarState)); + UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + lp)); + UInt32 i; + if (bufferSize < numProbs * sizeof(CProb) + sizeof(LzmaVarState)) + return LZMA_RESULT_NOT_ENOUGH_MEM; + vs->Dictionary = dictionary; + vs->DictionarySize = dictionarySize; + vs->DictionaryPos = 0; + vs->GlobalPos = 0; + vs->Reps[0] = vs->Reps[1] = vs->Reps[2] = vs->Reps[3] = 1; + vs->lc = lc; + vs->lp = lp; + vs->pb = pb; + vs->State = 0; + vs->RemainLen = 0; + dictionary[dictionarySize - 1] = 0; + for (i = 0; i < numProbs; i++) + p[i] = kBitModelTotal >> 1; + + #ifdef _LZMA_IN_CB + RC_INIT; + #else + RC_INIT(inStream, inSize); + #endif + vs->Buffer = Buffer; + vs->BufferLim = BufferLim; + vs->Range = Range; + vs->Code = Code; + #ifdef _LZMA_IN_CB + vs->InCallback = InCallback; + #endif + + return LZMA_RESULT_OK; +} + +int LzmaDecode(unsigned char *buffer, + unsigned char *outStream, UInt32 outSize, + UInt32 *outSizeProcessed) +{ + LzmaVarState *vs = (LzmaVarState *)buffer; + Byte *Buffer = vs->Buffer; + Byte *BufferLim = vs->BufferLim; + UInt32 Range = vs->Range; + UInt32 Code = vs->Code; + #ifdef _LZMA_IN_CB + ILzmaInCallback *InCallback = vs->InCallback; + #endif + CProb *p = (CProb *)(buffer + sizeof(LzmaVarState)); + int state = vs->State; + Byte previousByte; + UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3]; + UInt32 nowPos = 0; + UInt32 posStateMask = (1 << (vs->pb)) - 1; + UInt32 literalPosMask = (1 << (vs->lp)) - 1; + int lc = vs->lc; + int len = vs->RemainLen; + UInt32 globalPos = vs->GlobalPos; + + Byte *dictionary = vs->Dictionary; + UInt32 dictionarySize = vs->DictionarySize; + UInt32 dictionaryPos = vs->DictionaryPos; + + Byte tempDictionary[4]; + if (dictionarySize == 0) + { + dictionary = tempDictionary; + dictionarySize = 1; + tempDictionary[0] = vs->TempDictionary[0]; + } + + if (len == -1) + { + *outSizeProcessed = 0; + return LZMA_RESULT_OK; + } + + while(len != 0 && nowPos < outSize) + { + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos]; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + len--; + } + if (dictionaryPos == 0) + previousByte = dictionary[dictionarySize - 1]; + else + previousByte = dictionary[dictionaryPos - 1]; +#else + +int LzmaDecode( + Byte *buffer, UInt32 bufferSize, + int lc, int lp, int pb, + #ifdef _LZMA_IN_CB + ILzmaInCallback *InCallback, + #else + unsigned char *inStream, UInt32 inSize, + #endif + unsigned char *outStream, UInt32 outSize, + UInt32 *outSizeProcessed) +{ + UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + lp)); + CProb *p = (CProb *)buffer; + + UInt32 i; + int state = 0; + Byte previousByte = 0; + UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; + UInt32 nowPos = 0; + UInt32 posStateMask = (1 << pb) - 1; + UInt32 literalPosMask = (1 << lp) - 1; + int len = 0; + + Byte *Buffer; + Byte *BufferLim; + UInt32 Range; + UInt32 Code; + + if (bufferSize < numProbs * sizeof(CProb)) + return LZMA_RESULT_NOT_ENOUGH_MEM; + for (i = 0; i < numProbs; i++) + p[i] = kBitModelTotal >> 1; + + + #ifdef _LZMA_IN_CB + RC_INIT; + #else + RC_INIT(inStream, inSize); + #endif +#endif + + *outSizeProcessed = 0; + while(nowPos < outSize) + { + CProb *prob; + UInt32 bound; + int posState = (int)( + (nowPos + #ifdef _LZMA_OUT_READ + + globalPos + #endif + ) + & posStateMask); + + prob = p + IsMatch + (state << kNumPosBitsMax) + posState; + IfBit0(prob) + { + int symbol = 1; + UpdateBit0(prob) + prob = p + Literal + (LZMA_LIT_SIZE * + ((( + (nowPos + #ifdef _LZMA_OUT_READ + + globalPos + #endif + ) + & literalPosMask) << lc) + (previousByte >> (8 - lc)))); + + if (state >= kNumLitStates) + { + int matchByte; + #ifdef _LZMA_OUT_READ + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + matchByte = dictionary[pos]; + #else + matchByte = outStream[nowPos - rep0]; + #endif + do + { + int bit; + CProb *probLit; + matchByte <<= 1; + bit = (matchByte & 0x100); + probLit = prob + 0x100 + bit + symbol; + RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break) + } + while (symbol < 0x100); + } + while (symbol < 0x100) + { + CProb *probLit = prob + symbol; + RC_GET_BIT(probLit, symbol) + } + previousByte = (Byte)symbol; + + outStream[nowPos++] = previousByte; + #ifdef _LZMA_OUT_READ + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + #endif + if (state < 4) state = 0; + else if (state < 10) state -= 3; + else state -= 6; + } + else + { + UpdateBit1(prob); + prob = p + IsRep + state; + IfBit0(prob) + { + UpdateBit0(prob); + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + state = state < kNumLitStates ? 0 : 3; + prob = p + LenCoder; + } + else + { + UpdateBit1(prob); + prob = p + IsRepG0 + state; + IfBit0(prob) + { + UpdateBit0(prob); + prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState; + IfBit0(prob) + { + #ifdef _LZMA_OUT_READ + UInt32 pos; + #endif + UpdateBit0(prob); + if (nowPos + #ifdef _LZMA_OUT_READ + + globalPos + #endif + == 0) + return LZMA_RESULT_DATA_ERROR; + state = state < kNumLitStates ? 9 : 11; + #ifdef _LZMA_OUT_READ + pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + previousByte = dictionary[pos]; + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + #else + previousByte = outStream[nowPos - rep0]; + #endif + outStream[nowPos++] = previousByte; + continue; + } + else + { + UpdateBit1(prob); + } + } + else + { + UInt32 distance; + UpdateBit1(prob); + prob = p + IsRepG1 + state; + IfBit0(prob) + { + UpdateBit0(prob); + distance = rep1; + } + else + { + UpdateBit1(prob); + prob = p + IsRepG2 + state; + IfBit0(prob) + { + UpdateBit0(prob); + distance = rep2; + } + else + { + UpdateBit1(prob); + distance = rep3; + rep3 = rep2; + } + rep2 = rep1; + } + rep1 = rep0; + rep0 = distance; + } + state = state < kNumLitStates ? 8 : 11; + prob = p + RepLenCoder; + } + { + int numBits, offset; + CProb *probLen = prob + LenChoice; + IfBit0(probLen) + { + UpdateBit0(probLen); + probLen = prob + LenLow + (posState << kLenNumLowBits); + offset = 0; + numBits = kLenNumLowBits; + } + else + { + UpdateBit1(probLen); + probLen = prob + LenChoice2; + IfBit0(probLen) + { + UpdateBit0(probLen); + probLen = prob + LenMid + (posState << kLenNumMidBits); + offset = kLenNumLowSymbols; + numBits = kLenNumMidBits; + } + else + { + UpdateBit1(probLen); + probLen = prob + LenHigh; + offset = kLenNumLowSymbols + kLenNumMidSymbols; + numBits = kLenNumHighBits; + } + } + RangeDecoderBitTreeDecode(probLen, numBits, len); + len += offset; + } + + if (state < 4) + { + int posSlot; + state += kNumLitStates; + prob = p + PosSlot + + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << + kNumPosSlotBits); + RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot); + if (posSlot >= kStartPosModelIndex) + { + int numDirectBits = ((posSlot >> 1) - 1); + rep0 = (2 | ((UInt32)posSlot & 1)); + if (posSlot < kEndPosModelIndex) + { + rep0 <<= numDirectBits; + prob = p + SpecPos + rep0 - posSlot - 1; + } + else + { + numDirectBits -= kNumAlignBits; + do + { + RC_NORMALIZE + Range >>= 1; + rep0 <<= 1; + if (Code >= Range) + { + Code -= Range; + rep0 |= 1; + } + } + while (--numDirectBits != 0); + prob = p + Align; + rep0 <<= kNumAlignBits; + numDirectBits = kNumAlignBits; + } + { + int i = 1; + int mi = 1; + do + { + CProb *prob3 = prob + mi; + RC_GET_BIT2(prob3, mi, ; , rep0 |= i); + i <<= 1; + } + while(--numDirectBits != 0); + } + } + else + rep0 = posSlot; + if (++rep0 == (UInt32)(0)) + { + /* it's for stream version */ + len = -1; + break; + } + } + + len += kMatchMinLen; + if (rep0 > nowPos + #ifdef _LZMA_OUT_READ + + globalPos || rep0 > dictionarySize + #endif + ) + return LZMA_RESULT_DATA_ERROR; + do + { + #ifdef _LZMA_OUT_READ + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + previousByte = dictionary[pos]; + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + #else + previousByte = outStream[nowPos - rep0]; + #endif + len--; + outStream[nowPos++] = previousByte; + } + while(len != 0 && nowPos < outSize); + } + } + RC_NORMALIZE; + + #ifdef _LZMA_OUT_READ + vs->Buffer = Buffer; + vs->BufferLim = BufferLim; + vs->Range = Range; + vs->Code = Code; + vs->DictionaryPos = dictionaryPos; + vs->GlobalPos = globalPos + nowPos; + vs->Reps[0] = rep0; + vs->Reps[1] = rep1; + vs->Reps[2] = rep2; + vs->Reps[3] = rep3; + vs->State = state; + vs->RemainLen = len; + vs->TempDictionary[0] = tempDictionary[0]; + #endif + + *outSizeProcessed = nowPos; + return LZMA_RESULT_OK; +} diff --git a/7zip/Compress/LZMA_C/LzmaDecode.h b/7zip/Compress/LZMA_C/LzmaDecode.h new file mode 100755 index 00000000..53677350 --- /dev/null +++ b/7zip/Compress/LZMA_C/LzmaDecode.h @@ -0,0 +1,100 @@ +/* + LzmaDecode.h + LZMA Decoder interface + + LZMA SDK 4.16 Copyright (c) 1999-2005 Igor Pavlov (2005-03-18) + http://www.7-zip.org/ + + LZMA SDK is licensed under two licenses: + 1) GNU Lesser General Public License (GNU LGPL) + 2) Common Public License (CPL) + It means that you can select one of these two licenses and + follow rules of that license. + + SPECIAL EXCEPTION: + Igor Pavlov, as the author of this code, expressly permits you to + statically or dynamically link your code (or bind by name) to the + interfaces of this file without subjecting your linked code to the + terms of the CPL or GNU LGPL. Any modifications or additions + to this file, however, are subject to the LGPL or CPL terms. +*/ + +#ifndef __LZMADECODE_H +#define __LZMADECODE_H + +/* #define _LZMA_IN_CB */ +/* Use callback for input data */ + +/* #define _LZMA_OUT_READ */ +/* Use read function for output data */ + +/* #define _LZMA_PROB32 */ +/* It can increase speed on some 32-bit CPUs, + but memory usage will be doubled in that case */ + +/* #define _LZMA_LOC_OPT */ +/* Enable local speed optimizations inside code */ + +#ifndef UInt32 +#ifdef _LZMA_UINT32_IS_ULONG +#define UInt32 unsigned long +#else +#define UInt32 unsigned int +#endif +#endif + +#ifdef _LZMA_PROB32 +#define CProb UInt32 +#else +#define CProb unsigned short +#endif + +#define LZMA_RESULT_OK 0 +#define LZMA_RESULT_DATA_ERROR 1 +#define LZMA_RESULT_NOT_ENOUGH_MEM 2 + +#ifdef _LZMA_IN_CB +typedef struct _ILzmaInCallback +{ + int (*Read)(void *object, unsigned char **buffer, UInt32 *bufferSize); +} ILzmaInCallback; +#endif + +#define LZMA_BASE_SIZE 1846 +#define LZMA_LIT_SIZE 768 + +/* +bufferSize = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp)))* sizeof(CProb) +bufferSize += 100 in case of _LZMA_OUT_READ +by default CProb is unsigned short, +but if specify _LZMA_PROB_32, CProb will be UInt32(unsigned int) +*/ + +#ifdef _LZMA_OUT_READ +int LzmaDecoderInit( + unsigned char *buffer, UInt32 bufferSize, + int lc, int lp, int pb, + unsigned char *dictionary, UInt32 dictionarySize, + #ifdef _LZMA_IN_CB + ILzmaInCallback *inCallback + #else + unsigned char *inStream, UInt32 inSize + #endif +); +#endif + +int LzmaDecode( + unsigned char *buffer, + #ifndef _LZMA_OUT_READ + UInt32 bufferSize, + int lc, int lp, int pb, + #ifdef _LZMA_IN_CB + ILzmaInCallback *inCallback, + #else + unsigned char *inStream, UInt32 inSize, + #endif + #endif + unsigned char *outStream, UInt32 outSize, + UInt32 *outSizeProcessed); + +#endif diff --git a/7zip/Compress/LZMA_C/LzmaDecodeSize.c b/7zip/Compress/LZMA_C/LzmaDecodeSize.c new file mode 100755 index 00000000..679ed238 --- /dev/null +++ b/7zip/Compress/LZMA_C/LzmaDecodeSize.c @@ -0,0 +1,667 @@ +/* + LzmaDecodeSize.c + LZMA Decoder (optimized for Size version) + + LZMA SDK 4.16 Copyright (c) 1999-2005 Igor Pavlov (2005-03-18) + http://www.7-zip.org/ + + LZMA SDK is licensed under two licenses: + 1) GNU Lesser General Public License (GNU LGPL) + 2) Common Public License (CPL) + It means that you can select one of these two licenses and + follow rules of that license. + + SPECIAL EXCEPTION: + Igor Pavlov, as the author of this code, expressly permits you to + statically or dynamically link your code (or bind by name) to the + interfaces of this file without subjecting your linked code to the + terms of the CPL or GNU LGPL. Any modifications or additions + to this file, however, are subject to the LGPL or CPL terms. +*/ + +#include "LzmaDecode.h" + +#ifndef Byte +#define Byte unsigned char +#endif + +#define kNumTopBits 24 +#define kTopValue ((UInt32)1 << kNumTopBits) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 + +typedef struct _CRangeDecoder +{ + Byte *Buffer; + Byte *BufferLim; + UInt32 Range; + UInt32 Code; + #ifdef _LZMA_IN_CB + ILzmaInCallback *InCallback; + int Result; + #endif + int ExtraBytes; +} CRangeDecoder; + +Byte RangeDecoderReadByte(CRangeDecoder *rd) +{ + if (rd->Buffer == rd->BufferLim) + { + #ifdef _LZMA_IN_CB + UInt32 size; + rd->Result = rd->InCallback->Read(rd->InCallback, &rd->Buffer, &size); + rd->BufferLim = rd->Buffer + size; + if (size == 0) + #endif + { + rd->ExtraBytes = 1; + return 0xFF; + } + } + return (*rd->Buffer++); +} + +/* #define ReadByte (*rd->Buffer++) */ +#define ReadByte (RangeDecoderReadByte(rd)) + +void RangeDecoderInit(CRangeDecoder *rd, + #ifdef _LZMA_IN_CB + ILzmaInCallback *inCallback + #else + Byte *stream, UInt32 bufferSize + #endif + ) +{ + int i; + #ifdef _LZMA_IN_CB + rd->InCallback = inCallback; + rd->Buffer = rd->BufferLim = 0; + #else + rd->Buffer = stream; + rd->BufferLim = stream + bufferSize; + #endif + rd->ExtraBytes = 0; + rd->Code = 0; + rd->Range = (0xFFFFFFFF); + for(i = 0; i < 5; i++) + rd->Code = (rd->Code << 8) | ReadByte; +} + +#define RC_INIT_VAR UInt32 range = rd->Range; UInt32 code = rd->Code; +#define RC_FLUSH_VAR rd->Range = range; rd->Code = code; +#define RC_NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | ReadByte; } + +UInt32 RangeDecoderDecodeDirectBits(CRangeDecoder *rd, int numTotalBits) +{ + RC_INIT_VAR + UInt32 result = 0; + int i; + for (i = numTotalBits; i != 0; i--) + { + /* UInt32 t; */ + range >>= 1; + + result <<= 1; + if (code >= range) + { + code -= range; + result |= 1; + } + /* + t = (code - range) >> 31; + t &= 1; + code -= range & (t - 1); + result = (result + result) | (1 - t); + */ + RC_NORMALIZE + } + RC_FLUSH_VAR + return result; +} + +int RangeDecoderBitDecode(CProb *prob, CRangeDecoder *rd) +{ + UInt32 bound = (rd->Range >> kNumBitModelTotalBits) * *prob; + if (rd->Code < bound) + { + rd->Range = bound; + *prob += (kBitModelTotal - *prob) >> kNumMoveBits; + if (rd->Range < kTopValue) + { + rd->Code = (rd->Code << 8) | ReadByte; + rd->Range <<= 8; + } + return 0; + } + else + { + rd->Range -= bound; + rd->Code -= bound; + *prob -= (*prob) >> kNumMoveBits; + if (rd->Range < kTopValue) + { + rd->Code = (rd->Code << 8) | ReadByte; + rd->Range <<= 8; + } + return 1; + } +} + +#define RC_GET_BIT2(prob, mi, A0, A1) \ + UInt32 bound = (range >> kNumBitModelTotalBits) * *prob; \ + if (code < bound) \ + { A0; range = bound; *prob += (kBitModelTotal - *prob) >> kNumMoveBits; mi <<= 1; } \ + else \ + { A1; range -= bound; code -= bound; *prob -= (*prob) >> kNumMoveBits; mi = (mi + mi) + 1; } \ + RC_NORMALIZE + +#define RC_GET_BIT(prob, mi) RC_GET_BIT2(prob, mi, ; , ;) + +int RangeDecoderBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd) +{ + int mi = 1; + int i; + #ifdef _LZMA_LOC_OPT + RC_INIT_VAR + #endif + for(i = numLevels; i != 0; i--) + { + #ifdef _LZMA_LOC_OPT + CProb *prob = probs + mi; + RC_GET_BIT(prob, mi) + #else + mi = (mi + mi) + RangeDecoderBitDecode(probs + mi, rd); + #endif + } + #ifdef _LZMA_LOC_OPT + RC_FLUSH_VAR + #endif + return mi - (1 << numLevels); +} + +int RangeDecoderReverseBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd) +{ + int mi = 1; + int i; + int symbol = 0; + #ifdef _LZMA_LOC_OPT + RC_INIT_VAR + #endif + for(i = 0; i < numLevels; i++) + { + #ifdef _LZMA_LOC_OPT + CProb *prob = probs + mi; + RC_GET_BIT2(prob, mi, ; , symbol |= (1 << i)) + #else + int bit = RangeDecoderBitDecode(probs + mi, rd); + mi = mi + mi + bit; + symbol |= (bit << i); + #endif + } + #ifdef _LZMA_LOC_OPT + RC_FLUSH_VAR + #endif + return symbol; +} + +Byte LzmaLiteralDecode(CProb *probs, CRangeDecoder *rd) +{ + int symbol = 1; + #ifdef _LZMA_LOC_OPT + RC_INIT_VAR + #endif + do + { + #ifdef _LZMA_LOC_OPT + CProb *prob = probs + symbol; + RC_GET_BIT(prob, symbol) + #else + symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd); + #endif + } + while (symbol < 0x100); + #ifdef _LZMA_LOC_OPT + RC_FLUSH_VAR + #endif + return symbol; +} + +Byte LzmaLiteralDecodeMatch(CProb *probs, CRangeDecoder *rd, Byte matchByte) +{ + int symbol = 1; + #ifdef _LZMA_LOC_OPT + RC_INIT_VAR + #endif + do + { + int bit; + int matchBit = (matchByte >> 7) & 1; + matchByte <<= 1; + #ifdef _LZMA_LOC_OPT + { + CProb *prob = probs + 0x100 + (matchBit << 8) + symbol; + RC_GET_BIT2(prob, symbol, bit = 0, bit = 1) + } + #else + bit = RangeDecoderBitDecode(probs + 0x100 + (matchBit << 8) + symbol, rd); + symbol = (symbol << 1) | bit; + #endif + if (matchBit != bit) + { + while (symbol < 0x100) + { + #ifdef _LZMA_LOC_OPT + CProb *prob = probs + symbol; + RC_GET_BIT(prob, symbol) + #else + symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd); + #endif + } + break; + } + } + while (symbol < 0x100); + #ifdef _LZMA_LOC_OPT + RC_FLUSH_VAR + #endif + return symbol; +} + +#define kNumPosBitsMax 4 +#define kNumPosStatesMax (1 << kNumPosBitsMax) + +#define kLenNumLowBits 3 +#define kLenNumLowSymbols (1 << kLenNumLowBits) +#define kLenNumMidBits 3 +#define kLenNumMidSymbols (1 << kLenNumMidBits) +#define kLenNumHighBits 8 +#define kLenNumHighSymbols (1 << kLenNumHighBits) + +#define LenChoice 0 +#define LenChoice2 (LenChoice + 1) +#define LenLow (LenChoice2 + 1) +#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) +#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) +#define kNumLenProbs (LenHigh + kLenNumHighSymbols) + +int LzmaLenDecode(CProb *p, CRangeDecoder *rd, int posState) +{ + if(RangeDecoderBitDecode(p + LenChoice, rd) == 0) + return RangeDecoderBitTreeDecode(p + LenLow + + (posState << kLenNumLowBits), kLenNumLowBits, rd); + if(RangeDecoderBitDecode(p + LenChoice2, rd) == 0) + return kLenNumLowSymbols + RangeDecoderBitTreeDecode(p + LenMid + + (posState << kLenNumMidBits), kLenNumMidBits, rd); + return kLenNumLowSymbols + kLenNumMidSymbols + + RangeDecoderBitTreeDecode(p + LenHigh, kLenNumHighBits, rd); +} + +#define kNumStates 12 +#define kNumLitStates 7 + +#define kStartPosModelIndex 4 +#define kEndPosModelIndex 14 +#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) + +#define kNumPosSlotBits 6 +#define kNumLenToPosStates 4 + +#define kNumAlignBits 4 +#define kAlignTableSize (1 << kNumAlignBits) + +#define kMatchMinLen 2 + +#define IsMatch 0 +#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) +#define IsRepG0 (IsRep + kNumStates) +#define IsRepG1 (IsRepG0 + kNumStates) +#define IsRepG2 (IsRepG1 + kNumStates) +#define IsRep0Long (IsRepG2 + kNumStates) +#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) +#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) +#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) +#define LenCoder (Align + kAlignTableSize) +#define RepLenCoder (LenCoder + kNumLenProbs) +#define Literal (RepLenCoder + kNumLenProbs) + +#if Literal != LZMA_BASE_SIZE +StopCompilingDueBUG +#endif + +#ifdef _LZMA_OUT_READ + +typedef struct _LzmaVarState +{ + CRangeDecoder RangeDecoder; + Byte *Dictionary; + UInt32 DictionarySize; + UInt32 DictionaryPos; + UInt32 GlobalPos; + UInt32 Reps[4]; + int lc; + int lp; + int pb; + int State; + int RemainLen; + Byte TempDictionary[4]; +} LzmaVarState; + +int LzmaDecoderInit( + unsigned char *buffer, UInt32 bufferSize, + int lc, int lp, int pb, + unsigned char *dictionary, UInt32 dictionarySize, + #ifdef _LZMA_IN_CB + ILzmaInCallback *inCallback + #else + unsigned char *inStream, UInt32 inSize + #endif + ) +{ + LzmaVarState *vs = (LzmaVarState *)buffer; + CProb *p = (CProb *)(buffer + sizeof(LzmaVarState)); + UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + lp)); + UInt32 i; + if (bufferSize < numProbs * sizeof(CProb) + sizeof(LzmaVarState)) + return LZMA_RESULT_NOT_ENOUGH_MEM; + vs->Dictionary = dictionary; + vs->DictionarySize = dictionarySize; + vs->DictionaryPos = 0; + vs->GlobalPos = 0; + vs->Reps[0] = vs->Reps[1] = vs->Reps[2] = vs->Reps[3] = 1; + vs->lc = lc; + vs->lp = lp; + vs->pb = pb; + vs->State = 0; + vs->RemainLen = 0; + dictionary[dictionarySize - 1] = 0; + for (i = 0; i < numProbs; i++) + p[i] = kBitModelTotal >> 1; + RangeDecoderInit(&vs->RangeDecoder, + #ifdef _LZMA_IN_CB + inCallback + #else + inStream, inSize + #endif + ); + return LZMA_RESULT_OK; +} + +int LzmaDecode(unsigned char *buffer, + unsigned char *outStream, UInt32 outSize, + UInt32 *outSizeProcessed) +{ + LzmaVarState *vs = (LzmaVarState *)buffer; + CProb *p = (CProb *)(buffer + sizeof(LzmaVarState)); + CRangeDecoder rd = vs->RangeDecoder; + int state = vs->State; + Byte previousByte; + UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3]; + UInt32 nowPos = 0; + UInt32 posStateMask = (1 << (vs->pb)) - 1; + UInt32 literalPosMask = (1 << (vs->lp)) - 1; + int lc = vs->lc; + int len = vs->RemainLen; + UInt32 globalPos = vs->GlobalPos; + + Byte *dictionary = vs->Dictionary; + UInt32 dictionarySize = vs->DictionarySize; + UInt32 dictionaryPos = vs->DictionaryPos; + + Byte tempDictionary[4]; + if (dictionarySize == 0) + { + dictionary = tempDictionary; + dictionarySize = 1; + tempDictionary[0] = vs->TempDictionary[0]; + } + + if (len == -1) + { + *outSizeProcessed = 0; + return LZMA_RESULT_OK; + } + + while(len != 0 && nowPos < outSize) + { + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos]; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + len--; + } + if (dictionaryPos == 0) + previousByte = dictionary[dictionarySize - 1]; + else + previousByte = dictionary[dictionaryPos - 1]; +#else + +int LzmaDecode( + Byte *buffer, UInt32 bufferSize, + int lc, int lp, int pb, + #ifdef _LZMA_IN_CB + ILzmaInCallback *inCallback, + #else + unsigned char *inStream, UInt32 inSize, + #endif + unsigned char *outStream, UInt32 outSize, + UInt32 *outSizeProcessed) +{ + UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + lp)); + CProb *p = (CProb *)buffer; + CRangeDecoder rd; + UInt32 i; + int state = 0; + Byte previousByte = 0; + UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; + UInt32 nowPos = 0; + UInt32 posStateMask = (1 << pb) - 1; + UInt32 literalPosMask = (1 << lp) - 1; + int len = 0; + if (bufferSize < numProbs * sizeof(CProb)) + return LZMA_RESULT_NOT_ENOUGH_MEM; + for (i = 0; i < numProbs; i++) + p[i] = kBitModelTotal >> 1; + RangeDecoderInit(&rd, + #ifdef _LZMA_IN_CB + inCallback + #else + inStream, inSize + #endif + ); +#endif + + *outSizeProcessed = 0; + while(nowPos < outSize) + { + int posState = (int)( + (nowPos + #ifdef _LZMA_OUT_READ + + globalPos + #endif + ) + & posStateMask); + #ifdef _LZMA_IN_CB + if (rd.Result != LZMA_RESULT_OK) + return rd.Result; + #endif + if (rd.ExtraBytes != 0) + return LZMA_RESULT_DATA_ERROR; + if (RangeDecoderBitDecode(p + IsMatch + (state << kNumPosBitsMax) + posState, &rd) == 0) + { + CProb *probs = p + Literal + (LZMA_LIT_SIZE * + ((( + (nowPos + #ifdef _LZMA_OUT_READ + + globalPos + #endif + ) + & literalPosMask) << lc) + (previousByte >> (8 - lc)))); + + if (state >= kNumLitStates) + { + Byte matchByte; + #ifdef _LZMA_OUT_READ + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + matchByte = dictionary[pos]; + #else + matchByte = outStream[nowPos - rep0]; + #endif + previousByte = LzmaLiteralDecodeMatch(probs, &rd, matchByte); + } + else + previousByte = LzmaLiteralDecode(probs, &rd); + outStream[nowPos++] = previousByte; + #ifdef _LZMA_OUT_READ + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + #endif + if (state < 4) state = 0; + else if (state < 10) state -= 3; + else state -= 6; + } + else + { + if (RangeDecoderBitDecode(p + IsRep + state, &rd) == 1) + { + if (RangeDecoderBitDecode(p + IsRepG0 + state, &rd) == 0) + { + if (RangeDecoderBitDecode(p + IsRep0Long + (state << kNumPosBitsMax) + posState, &rd) == 0) + { + #ifdef _LZMA_OUT_READ + UInt32 pos; + #endif + if ( + (nowPos + #ifdef _LZMA_OUT_READ + + globalPos + #endif + ) + == 0) + return LZMA_RESULT_DATA_ERROR; + state = state < 7 ? 9 : 11; + #ifdef _LZMA_OUT_READ + pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + previousByte = dictionary[pos]; + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + #else + previousByte = outStream[nowPos - rep0]; + #endif + outStream[nowPos++] = previousByte; + continue; + } + } + else + { + UInt32 distance; + if(RangeDecoderBitDecode(p + IsRepG1 + state, &rd) == 0) + distance = rep1; + else + { + if(RangeDecoderBitDecode(p + IsRepG2 + state, &rd) == 0) + distance = rep2; + else + { + distance = rep3; + rep3 = rep2; + } + rep2 = rep1; + } + rep1 = rep0; + rep0 = distance; + } + len = LzmaLenDecode(p + RepLenCoder, &rd, posState); + state = state < 7 ? 8 : 11; + } + else + { + int posSlot; + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + state = state < 7 ? 7 : 10; + len = LzmaLenDecode(p + LenCoder, &rd, posState); + posSlot = RangeDecoderBitTreeDecode(p + PosSlot + + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << + kNumPosSlotBits), kNumPosSlotBits, &rd); + if (posSlot >= kStartPosModelIndex) + { + int numDirectBits = ((posSlot >> 1) - 1); + rep0 = ((2 | ((UInt32)posSlot & 1)) << numDirectBits); + if (posSlot < kEndPosModelIndex) + { + rep0 += RangeDecoderReverseBitTreeDecode( + p + SpecPos + rep0 - posSlot - 1, numDirectBits, &rd); + } + else + { + rep0 += RangeDecoderDecodeDirectBits(&rd, + numDirectBits - kNumAlignBits) << kNumAlignBits; + rep0 += RangeDecoderReverseBitTreeDecode(p + Align, kNumAlignBits, &rd); + } + } + else + rep0 = posSlot; + rep0++; + } + if (rep0 == (UInt32)(0)) + { + /* it's for stream version */ + len = -1; + break; + } + if (rep0 > nowPos + #ifdef _LZMA_OUT_READ + + globalPos || rep0 > dictionarySize + #endif + ) + { + return LZMA_RESULT_DATA_ERROR; + } + len += kMatchMinLen; + do + { + #ifdef _LZMA_OUT_READ + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + previousByte = dictionary[pos]; + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + #else + previousByte = outStream[nowPos - rep0]; + #endif + outStream[nowPos++] = previousByte; + len--; + } + while(len != 0 && nowPos < outSize); + } + } + + #ifdef _LZMA_OUT_READ + vs->RangeDecoder = rd; + vs->DictionaryPos = dictionaryPos; + vs->GlobalPos = globalPos + nowPos; + vs->Reps[0] = rep0; + vs->Reps[1] = rep1; + vs->Reps[2] = rep2; + vs->Reps[3] = rep3; + vs->State = state; + vs->RemainLen = len; + vs->TempDictionary[0] = tempDictionary[0]; + #endif + + *outSizeProcessed = nowPos; + return LZMA_RESULT_OK; +} diff --git a/7zip/Compress/LZMA_C/LzmaTest.c b/7zip/Compress/LZMA_C/LzmaTest.c new file mode 100755 index 00000000..f84a8c56 --- /dev/null +++ b/7zip/Compress/LZMA_C/LzmaTest.c @@ -0,0 +1,240 @@ +/* +LzmaTest.c +Test application for LZMA Decoder +LZMA SDK 4.16 Copyright (c) 1999-2004 Igor Pavlov (2005-03-18) +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "LzmaDecode.h" + +size_t MyReadFile(FILE *file, void *data, size_t size) +{ + return (fread(data, 1, size, file) == size); +} + +#ifdef _LZMA_IN_CB +typedef struct _CBuffer +{ + ILzmaInCallback InCallback; + unsigned char *Buffer; + unsigned int Size; +} CBuffer; + +int LzmaReadCompressed(void *object, unsigned char **buffer, unsigned int *size) +{ + CBuffer *bo = (CBuffer *)object; + *size = bo->Size; /* You can specify any available size here */ + *buffer = bo->Buffer; + bo->Buffer += *size; + bo->Size -= *size; + return LZMA_RESULT_OK; +} +#endif + +int main2(int numargs, const char *args[], char *rs) +{ + FILE *inputHandle, *outputHandle; + unsigned int length, processedSize; + unsigned int compressedSize, outSize, outSizeProcessed, lzmaInternalSize; + void *inStream, *outStream, *lzmaInternalData; + unsigned char properties[5]; + unsigned char prop0; + int ii; + int lc, lp, pb; + int res; + #ifdef _LZMA_IN_CB + CBuffer bo; + #endif + + sprintf(rs + strlen(rs), "\nLZMA Decoder 4.16 Copyright (c) 1999-2005 Igor Pavlov 2005-03-18\n"); + if (numargs < 2 || numargs > 3) + { + sprintf(rs + strlen(rs), "\nUsage: lzmaDec file.lzma [outFile]\n"); + return 1; + } + + inputHandle = fopen(args[1], "rb"); + if (inputHandle == 0) + { + sprintf(rs + strlen(rs), "\n Open input file error"); + return 1; + } + + fseek(inputHandle, 0, SEEK_END); + length = ftell(inputHandle); + fseek(inputHandle, 0, SEEK_SET); + + if (!MyReadFile(inputHandle, properties, sizeof(properties))) + return 1; + + outSize = 0; + for (ii = 0; ii < 4; ii++) + { + unsigned char b; + if (!MyReadFile(inputHandle, &b, sizeof(b))) + return 1; + outSize += (unsigned int)(b) << (ii * 8); + } + + if (outSize == 0xFFFFFFFF) + { + sprintf(rs + strlen(rs), "\nstream version is not supported"); + return 1; + } + + for (ii = 0; ii < 4; ii++) + { + unsigned char b; + if (!MyReadFile(inputHandle, &b, sizeof(b))) + return 1; + if (b != 0) + { + sprintf(rs + strlen(rs), "\n too long file"); + return 1; + } + } + + compressedSize = length - 13; + inStream = malloc(compressedSize); + if (inStream == 0) + { + sprintf(rs + strlen(rs), "\n can't allocate"); + return 1; + } + if (!MyReadFile(inputHandle, inStream, compressedSize)) + { + sprintf(rs + strlen(rs), "\n can't read"); + return 1; + } + + fclose(inputHandle); + + prop0 = properties[0]; + if (prop0 >= (9*5*5)) + { + sprintf(rs + strlen(rs), "\n Properties error"); + return 1; + } + for (pb = 0; prop0 >= (9 * 5); + pb++, prop0 -= (9 * 5)); + for (lp = 0; prop0 >= 9; + lp++, prop0 -= 9); + lc = prop0; + + lzmaInternalSize = + (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp)))* sizeof(CProb); + + #ifdef _LZMA_OUT_READ + lzmaInternalSize += 100; + #endif + + outStream = malloc(outSize); + lzmaInternalData = malloc(lzmaInternalSize); + if (outStream == 0 || lzmaInternalData == 0) + { + sprintf(rs + strlen(rs), "\n can't allocate"); + return 1; + } + + #ifdef _LZMA_IN_CB + bo.InCallback.Read = LzmaReadCompressed; + bo.Buffer = (unsigned char *)inStream; + bo.Size = compressedSize; + #endif + + #ifdef _LZMA_OUT_READ + { + UInt32 nowPos; + unsigned char *dictionary; + UInt32 dictionarySize = 0; + int i; + for (i = 0; i < 4; i++) + dictionarySize += (UInt32)(properties[1 + i]) << (i * 8); + if (dictionarySize == 0) + dictionarySize = 1; /* LZMA decoder can not work with dictionarySize = 0 */ + dictionary = (unsigned char *)malloc(dictionarySize); + if (dictionary == 0) + { + sprintf(rs + strlen(rs), "\n can't allocate"); + return 1; + } + res = LzmaDecoderInit((unsigned char *)lzmaInternalData, lzmaInternalSize, + lc, lp, pb, + dictionary, dictionarySize, + #ifdef _LZMA_IN_CB + &bo.InCallback + #else + (unsigned char *)inStream, compressedSize + #endif + ); + if (res == 0) + for (nowPos = 0; nowPos < outSize;) + { + UInt32 blockSize = outSize - nowPos; + UInt32 kBlockSize = 0x10000; + if (blockSize > kBlockSize) + blockSize = kBlockSize; + res = LzmaDecode((unsigned char *)lzmaInternalData, + ((unsigned char *)outStream) + nowPos, blockSize, &outSizeProcessed); + if (res != 0) + break; + if (outSizeProcessed == 0) + { + outSize = nowPos; + break; + } + nowPos += outSizeProcessed; + } + free(dictionary); + } + + #else + res = LzmaDecode((unsigned char *)lzmaInternalData, lzmaInternalSize, + lc, lp, pb, + #ifdef _LZMA_IN_CB + &bo.InCallback, + #else + (unsigned char *)inStream, compressedSize, + #endif + (unsigned char *)outStream, outSize, &outSizeProcessed); + outSize = outSizeProcessed; + #endif + + if (res != 0) + { + sprintf(rs + strlen(rs), "\nerror = %d\n", res); + return 1; + } + + if (numargs > 2) + { + outputHandle = fopen(args[2], "wb+"); + if (outputHandle == 0) + { + sprintf(rs + strlen(rs), "\n Open output file error"); + return 1; + } + processedSize = fwrite(outStream, 1, outSize, outputHandle); + if (processedSize != outSize) + { + sprintf(rs + strlen(rs), "\n can't write"); + return 1; + } + fclose(outputHandle); + } + free(lzmaInternalData); + free(outStream); + free(inStream); + return 0; +} + +int main(int numargs, const char *args[]) +{ + char sz[800] = { 0 }; + int code = main2(numargs, args, sz); + printf(sz); + return code; +} diff --git a/7zip/Compress/PPMD/DllExports.cpp b/7zip/Compress/PPMD/DllExports.cpp index 3d7406aa..61f528f4 100755 --- a/7zip/Compress/PPMD/DllExports.cpp +++ b/7zip/Compress/PPMD/DllExports.cpp @@ -2,8 +2,7 @@ #include "StdAfx.h" -#define INITGUID - +#include "Common/MyInitGuid.h" #include "Common/ComTry.h" #include "PPMDEncoder.h" diff --git a/7zip/Compress/PPMD/PPMD.dsp b/7zip/Compress/PPMD/PPMD.dsp index 78e8bb13..9b10af62 100755 --- a/7zip/Compress/PPMD/PPMD.dsp +++ b/7zip/Compress/PPMD/PPMD.dsp @@ -101,6 +101,10 @@ SOURCE=.\PPMD.def # End Source File # Begin Source File +SOURCE=.\resource.rc +# End Source File +# Begin Source File + SOURCE=.\StdAfx.cpp # ADD CPP /Yc # End Source File @@ -197,9 +201,21 @@ SOURCE=..\..\Common\OutBuffer.h SOURCE=..\RangeCoder\RangeCoder.h # End Source File # End Group +# Begin Group "Common" + +# PROP Default_Filter "" # Begin Source File -SOURCE=.\resource.rc +SOURCE=..\..\..\Common\Alloc.cpp # End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Types.h +# End Source File +# End Group # End Target # End Project diff --git a/7zip/Compress/PPMD/PPMDContext.h b/7zip/Compress/PPMD/PPMDContext.h index 6a2b7025..1b926585 100755 --- a/7zip/Compress/PPMD/PPMDContext.h +++ b/7zip/Compress/PPMD/PPMDContext.h @@ -1,15 +1,13 @@ -// Compress/PPM/PPMD/Context.h +// Compress/PPMD/Context.h // This code is based on Dmitry Shkarin's PPMdH code -#pragma once +#ifndef __COMPRESS_PPMD_CONTEXT_H +#define __COMPRESS_PPMD_CONTEXT_H -#ifndef __COMPRESS_PPM_PPMD_CONTEXT_H -#define __COMPRESS_PPM_PPMD_CONTEXT_H +#include "../../../Common/Types.h" -#include "Common/Types.h" - -#include "PPMDSubAlloc.h" #include "../RangeCoder/RangeCoder.h" +#include "PPMDSubAlloc.h" namespace NCompress { namespace NPPMD { @@ -20,12 +18,12 @@ const int INT_BITS=7, PERIOD_BITS=7, TOT_BITS=INT_BITS+PERIOD_BITS, #pragma pack(1) struct SEE2_CONTEXT { // SEE-contexts for PPM-contexts with masked symbols - WORD Summ; - BYTE Shift, Count; + UInt16 Summ; + Byte Shift, Count; void init(int InitVal) { Summ=InitVal << (Shift=PERIOD_BITS-4); Count=4; } - UINT getMean() + unsigned int getMean() { - UINT RetVal=(Summ >> Shift); + unsigned int RetVal=(Summ >> Shift); Summ -= RetVal; return RetVal+(RetVal == 0); } @@ -41,14 +39,14 @@ struct SEE2_CONTEXT struct PPM_CONTEXT { - WORD NumStats,SummFreq; // sizeof(WORD) > sizeof(BYTE) - struct STATE { BYTE Symbol, Freq; PPM_CONTEXT* Successor; } _PACK_ATTR * Stats; + UInt16 NumStats,SummFreq; // sizeof(UInt16) > sizeof(Byte) + struct STATE { Byte Symbol, Freq; PPM_CONTEXT* Successor; } _PACK_ATTR * Stats; PPM_CONTEXT* Suffix; - PPM_CONTEXT* createChild(CSubAllocator &aSubAllocator, STATE* pStats, STATE& FirstState) + PPM_CONTEXT* createChild(CSubAllocator &subAllocator, STATE* pStats, STATE& FirstState) { - PPM_CONTEXT* pc = (PPM_CONTEXT*) aSubAllocator.AllocContext(); - if ( pc ) + PPM_CONTEXT* pc = (PPM_CONTEXT*) subAllocator.AllocContext(); + if (pc) { pc->NumStats = 1; pc->oneState() = FirstState; @@ -64,7 +62,7 @@ struct PPM_CONTEXT ///////////////////////////////// -const WORD InitBinEsc[] = +const UInt16 InitBinEsc[] = {0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051}; struct CInfo @@ -75,15 +73,15 @@ struct CInfo PPM_CONTEXT::STATE* FoundState; // found next state transition int NumMasked, InitEsc, OrderFall, RunLength, InitRL, MaxOrder; - BYTE CharMask[256], NS2Indx[256], NS2BSIndx[256], HB2Flag[256]; - BYTE EscCount, PrintCount, PrevSuccess, HiBitsFlag; - WORD BinSumm[128][64]; // binary SEE-contexts + Byte CharMask[256], NS2Indx[256], NS2BSIndx[256], HB2Flag[256]; + Byte EscCount, PrintCount, PrevSuccess, HiBitsFlag; + UInt16 BinSumm[128][64]; // binary SEE-contexts - WORD &GetBinSumm(const PPM_CONTEXT::STATE &rs, int aNumStates) + UInt16 &GetBinSumm(const PPM_CONTEXT::STATE &rs, int numStates) { HiBitsFlag = HB2Flag[FoundState->Symbol]; return BinSumm[rs.Freq - 1][ - PrevSuccess + NS2BSIndx[aNumStates - 1] + + PrevSuccess + NS2BSIndx[numStates - 1] + HiBitsFlag + 2 * HB2Flag[rs.Symbol] + ((RunLength >> 26) & 0x20)]; } @@ -114,7 +112,7 @@ struct CInfo SEE2Cont[i][k].init(5*i+10); } - void _FASTCALL StartModelRare(int MaxOrder) + void StartModelRare(int MaxOrder) { int i, k, m ,Step; EscCount=PrintCount=1; @@ -156,7 +154,7 @@ struct CInfo } } - PPM_CONTEXT* CreateSuccessors(BOOL Skip, PPM_CONTEXT::STATE* p1) + PPM_CONTEXT* CreateSuccessors(bool skip, PPM_CONTEXT::STATE* p1) { // static UpState declaration bypasses IntelC bug // static PPM_CONTEXT::STATE UpState; @@ -164,7 +162,7 @@ struct CInfo PPM_CONTEXT* pc = MinContext, * UpBranch = FoundState->Successor; PPM_CONTEXT::STATE * p, * ps[MAX_O], ** pps = ps; - if ( !Skip ) + if ( !skip ) { *pps++ = FoundState; if ( !pc->Suffix ) @@ -198,14 +196,14 @@ LOOP_ENTRY: NO_LOOP: if (pps == ps) return pc; - UpState.Symbol = *(BYTE*) UpBranch; - UpState.Successor = (PPM_CONTEXT*) (((BYTE*) UpBranch)+1); + UpState.Symbol = *(Byte*) UpBranch; + UpState.Successor = (PPM_CONTEXT*) (((Byte*) UpBranch)+1); if (pc->NumStats != 1) { if ((p = pc->Stats)->Symbol != UpState.Symbol) do { p++; } while (p->Symbol != UpState.Symbol); - UINT cf = p->Freq-1; - UINT s0 = pc->SummFreq - pc->NumStats - cf; + unsigned int cf = p->Freq-1; + unsigned int s0 = pc->SummFreq - pc->NumStats - cf; UpState.Freq = 1 + ((2 * cf <= s0) ? (5 * cf > s0) : ((2 * cf + 3 * s0 - 1) / (2 * s0))); } @@ -225,7 +223,7 @@ NO_LOOP: { PPM_CONTEXT::STATE fs = *FoundState, * p = NULL; PPM_CONTEXT* pc, * Successor; - UINT ns1, ns, cf, sf, s0; + unsigned int ns1, ns, cf, sf, s0; if (fs.Freq < MAX_FREQ/4 && (pc=MinContext->Suffix) != NULL) { if (pc->NumStats != 1) @@ -253,7 +251,7 @@ NO_LOOP: } if ( !OrderFall ) { - MinContext = MaxContext = FoundState->Successor = CreateSuccessors(TRUE, p); + MinContext = MaxContext = FoundState->Successor = CreateSuccessors(true, p); if ( !MinContext ) goto RESTART_MODEL; return; @@ -264,8 +262,8 @@ NO_LOOP: goto RESTART_MODEL; if ( fs.Successor ) { - if ((BYTE*) fs.Successor <= SubAllocator.pText && - (fs.Successor=CreateSuccessors(FALSE,p)) == NULL) + if ((Byte*) fs.Successor <= SubAllocator.pText && + (fs.Successor=CreateSuccessors(false, p)) == NULL) goto RESTART_MODEL; if ( !--OrderFall ) { @@ -363,19 +361,19 @@ RESTART_MODEL: RunLength = InitRL; } - SEE2_CONTEXT* makeEscFreq2(int Diff, UINT32 &aScale) + SEE2_CONTEXT* makeEscFreq2(int Diff, UInt32 &scale) { SEE2_CONTEXT* psee2c; if (MinContext->NumStats != 256) { psee2c = SEE2Cont[NS2Indx[Diff-1]] + (Diff < MinContext->Suffix->NumStats - MinContext->NumStats)+ 2 * (MinContext->SummFreq < 11 * MinContext->NumStats) + 4 * (NumMasked > Diff) + HiBitsFlag; - aScale = psee2c->getMean(); + scale = psee2c->getMean(); } else { psee2c = &DummySEE2Cont; - aScale = 1; + scale = 1; } return psee2c; } @@ -427,7 +425,7 @@ RESTART_MODEL: void NextContext() { - if (!OrderFall && (BYTE*) FoundState->Successor > SubAllocator.pText) + if (!OrderFall && (Byte*) FoundState->Successor > SubAllocator.pText) MinContext = MaxContext = FoundState->Successor; else { @@ -439,7 +437,7 @@ RESTART_MODEL: }; // Tabulated escapes for exponential symbol distribution -const BYTE ExpEscape[16]={ 25,14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 }; +const Byte ExpEscape[16]={ 25,14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 }; #define GET_MEAN(SUMM,SHIFT,ROUND) ((SUMM+(1 << (SHIFT-ROUND))) >> (SHIFT)) }} diff --git a/7zip/Compress/PPMD/PPMDDecode.h b/7zip/Compress/PPMD/PPMDDecode.h index 04888825..83445718 100755 --- a/7zip/Compress/PPMD/PPMDDecode.h +++ b/7zip/Compress/PPMD/PPMDDecode.h @@ -1,10 +1,8 @@ -// Decode.h +// PPMDDecode.h // This code is based on Dmitry Shkarin's PPMdH code -#pragma once - -#ifndef __COMPRESS_PPM_PPMD_DECODE_H -#define __COMPRESS_PPM_PPMD_DECODE_H +#ifndef __COMPRESS_PPMD_DECODE_H +#define __COMPRESS_PPMD_DECODE_H #include "PPMDContext.h" @@ -16,18 +14,18 @@ struct CDecodeInfo: public CInfo void DecodeBinSymbol(NRangeCoder::CDecoder *rangeDecoder) { PPM_CONTEXT::STATE& rs = MinContext->oneState(); - WORD& bs = GetBinSumm(rs, MinContext->Suffix->NumStats); + UInt16& bs = GetBinSumm(rs, MinContext->Suffix->NumStats); if (rangeDecoder->DecodeBit(bs, TOT_BITS) == 0) { FoundState = &rs; rs.Freq += (rs.Freq < 128); - bs += UINT16(INTERVAL-GET_MEAN(bs,PERIOD_BITS,2)); + bs += UInt16(INTERVAL-GET_MEAN(bs,PERIOD_BITS,2)); PrevSuccess = 1; RunLength++; } else { - bs -= UINT16(GET_MEAN(bs,PERIOD_BITS,2)); + bs -= UInt16(GET_MEAN(bs,PERIOD_BITS,2)); InitEsc = ExpEscape[bs >> 10]; NumMasked = 1; CharMask[rs.Symbol] = EscCount; @@ -44,7 +42,7 @@ struct CDecodeInfo: public CInfo { PrevSuccess = (2 * hiCnt > MinContext->SummFreq); RunLength += PrevSuccess; - rangeDecoder->Decode(0, MinContext->Stats->Freq, MinContext->SummFreq); + rangeDecoder->Decode(0, MinContext->Stats->Freq); // MinContext->SummFreq); (FoundState = p)->Freq=(hiCnt += 4); MinContext->SummFreq += 4; if (hiCnt > MAX_FREQ) @@ -57,14 +55,14 @@ struct CDecodeInfo: public CInfo if (--i == 0) { HiBitsFlag = HB2Flag[FoundState->Symbol]; - rangeDecoder->Decode(hiCnt, MinContext->SummFreq - hiCnt, MinContext->SummFreq); + rangeDecoder->Decode(hiCnt, MinContext->SummFreq - hiCnt); // , MinContext->SummFreq); CharMask[p->Symbol] = EscCount; i = (NumMasked = MinContext->NumStats)-1; FoundState = NULL; do { CharMask[(--p)->Symbol] = EscCount; } while ( --i ); return; } - rangeDecoder->Decode(hiCnt - p->Freq, p->Freq, MinContext->SummFreq); + rangeDecoder->Decode(hiCnt - p->Freq, p->Freq); // , MinContext->SummFreq); update1(p); } @@ -72,7 +70,7 @@ struct CDecodeInfo: public CInfo void DecodeSymbol2(NRangeCoder::CDecoder *rangeDecoder) { int count, hiCnt, i = MinContext->NumStats - NumMasked; - UINT32 freqSum; + UInt32 freqSum; SEE2_CONTEXT* psee2c = makeEscFreq2(i, freqSum); PPM_CONTEXT::STATE* ps[256], ** pps = ps, * p = MinContext->Stats-1; hiCnt = 0; @@ -93,14 +91,14 @@ struct CDecodeInfo: public CInfo hiCnt = 0; while ((hiCnt += p->Freq) <= count) p=*++pps; - rangeDecoder->Decode(hiCnt - p->Freq, p->Freq, freqSum); + rangeDecoder->Decode(hiCnt - p->Freq, p->Freq); // , freqSum); psee2c->update(); update2(p); } else { - rangeDecoder->Decode(hiCnt, freqSum - hiCnt, freqSum); + rangeDecoder->Decode(hiCnt, freqSum - hiCnt); // , freqSum); i = MinContext->NumStats - NumMasked; pps--; @@ -128,7 +126,7 @@ struct CDecodeInfo: public CInfo while (MinContext->NumStats == NumMasked); DecodeSymbol2(rangeDecoder); } - BYTE symbol = FoundState->Symbol; + Byte symbol = FoundState->Symbol; NextContext(); return symbol; } diff --git a/7zip/Compress/PPMD/PPMDDecoder.cpp b/7zip/Compress/PPMD/PPMDDecoder.cpp index aa2a98af..5677daf2 100755 --- a/7zip/Compress/PPMD/PPMDDecoder.cpp +++ b/7zip/Compress/PPMD/PPMDDecoder.cpp @@ -10,17 +10,14 @@ namespace NCompress { namespace NPPMD { -STDMETHODIMP CDecoder::SetDecoderProperties(ISequentialInStream *inStream) +STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *properties, UInt32 size) { - UINT32 processedSize; - RINOK(inStream->Read(&_order, - sizeof(_order), &processedSize)); - if (processedSize != sizeof(_order)) - return E_FAIL; - RINOK(inStream->Read(&_usedMemorySize, - sizeof(_usedMemorySize), &processedSize)); - if (processedSize != sizeof(_usedMemorySize)) - return E_FAIL; + if (size < 5) + return E_INVALIDARG; + _order = properties[0]; + _usedMemorySize = 0; + for (int i = 0; i < 4; i++) + _usedMemorySize += ((UInt32)(properties[1 + i])) << (i * 8); return S_OK; } @@ -32,51 +29,46 @@ public: ~CDecoderFlusher() { _coder->Flush(); - // _coder->ReleaseStreams(); + _coder->ReleaseStreams(); } }; -UINT32 GetMatchLen(const BYTE *pointer1, const BYTE *pointer2, - UINT32 limit) +UInt32 GetMatchLen(const Byte *pointer1, const Byte *pointer2, + UInt32 limit) { - UINT32 i; + UInt32 i; for(i = 0; i < limit && *pointer1 == *pointer2; pointer1++, pointer2++, i++); return i; } STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { - _rangeDecoder.Init(inStream); - _outStream.Init(outStream); + if (!_rangeDecoder.Create(1 << 20)) + return E_OUTOFMEMORY; + if (!_outStream.Create(1 << 20)) + return E_OUTOFMEMORY; - CDecoderFlusher flusher(this); + _rangeDecoder.SetStream(inStream); + _rangeDecoder.Init(); + _outStream.SetStream(outStream); + _outStream.Init(); - /* - if (outSize == NULL) - return E_INVALIDARG; - */ + CDecoderFlusher flusher(this); - UINT64 progressPosValuePrev = 0, pos = 0; + UInt64 progressPosValuePrev = 0, pos = 0; - try - { - if (!_info.SubAllocator.StartSubAllocator(_usedMemorySize)) - return E_OUTOFMEMORY; - } - catch(...) - { + if (!_info.SubAllocator.StartSubAllocator(_usedMemorySize)) return E_OUTOFMEMORY; - } // _info.Init(); // _info.MaxOrder = _order; _info.MaxOrder = 0; _info.StartModelRare(_order); - UINT64 size = (outSize == NULL) ? (UINT64)(INT64)(-1) : *outSize; + UInt64 size = (outSize == NULL) ? (UInt64)(Int64)(-1) : *outSize; while(pos < size) { @@ -87,7 +79,7 @@ STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, _outStream.WriteByte(symbol); if (pos - progressPosValuePrev >= (1 << 18) && progress != NULL) { - UINT64 inSize = _rangeDecoder.GetProcessedSize(); + UInt64 inSize = _rangeDecoder.GetProcessedSize(); RINOK(progress->SetRatioInfo(&inSize, &pos)); progressPosValuePrev = pos; } @@ -96,7 +88,7 @@ STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, } STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { try { return CodeReal(inStream, outStream, inSize, outSize, progress); } @@ -105,5 +97,4 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, catch(...) { return E_FAIL; } } - }} diff --git a/7zip/Compress/PPMD/PPMDDecoder.h b/7zip/Compress/PPMD/PPMDDecoder.h index 83a0c5e0..a5c2d18e 100755 --- a/7zip/Compress/PPMD/PPMDDecoder.h +++ b/7zip/Compress/PPMD/PPMDDecoder.h @@ -1,11 +1,9 @@ // Compress/PPM/PPMDDecoder.h -#pragma once +#ifndef __COMPRESS_PPMD_DECODER_H +#define __COMPRESS_PPMD_DECODER_H -#ifndef __COMPRESS_PPM_PPMD_DECODER_H -#define __COMPRESS_PPM_PPMD_DECODER_H - -#include "Common/MyCom.h" +#include "../../../Common/MyCom.h" #include "../../ICoder.h" #include "../../Common/OutBuffer.h" @@ -18,7 +16,7 @@ namespace NPPMD { class CDecoder : public ICompressCoder, - public ICompressSetDecoderProperties, + public ICompressSetDecoderProperties2, public CMyUnknownImp { NRangeCoder::CDecoder _rangeDecoder; @@ -27,39 +25,32 @@ class CDecoder : CDecodeInfo _info; - BYTE _order; - UINT32 _usedMemorySize; + Byte _order; + UInt32 _usedMemorySize; public: - MY_UNKNOWN_IMP1(ICompressSetDecoderProperties) + MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) - /* void ReleaseStreams() { _rangeDecoder.ReleaseStream(); _outStream.ReleaseStream(); } - */ - - // STDMETHOD(Code)(UINT32 aNumBytes, UINT32 &aProcessedBytes); - HRESULT Flush() - { return _outStream.Flush(); } + HRESULT Flush() { return _outStream.Flush(); } STDMETHOD(CodeReal)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UINT64 *inSize, const UINT64 *outSize, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); STDMETHOD(Code)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - // ICompressSetDecoderProperties - STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream); - + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); }; }} diff --git a/7zip/Compress/PPMD/PPMDEncode.h b/7zip/Compress/PPMD/PPMDEncode.h index f86fc4af..c2342058 100755 --- a/7zip/Compress/PPMD/PPMDEncode.h +++ b/7zip/Compress/PPMD/PPMDEncode.h @@ -1,10 +1,8 @@ // PPMDEncode.h // This code is based on Dmitry Shkarin's PPMdH code -#pragma once - -#ifndef __COMPRESS_PPM_PPMD_ENCODE_H -#define __COMPRESS_PPM_PPMD_ENCODE_H +#ifndef __COMPRESS_PPMD_ENCODE_H +#define __COMPRESS_PPMD_ENCODE_H #include "PPMDContext.h" @@ -17,20 +15,20 @@ struct CEncodeInfo: public CInfo void EncodeBinSymbol(int symbol, NRangeCoder::CEncoder *rangeEncoder) { PPM_CONTEXT::STATE& rs = MinContext->oneState(); - WORD &bs = GetBinSumm(rs, MinContext->Suffix->NumStats); + UInt16 &bs = GetBinSumm(rs, MinContext->Suffix->NumStats); if (rs.Symbol == symbol) { FoundState = &rs; rs.Freq += (rs.Freq < 128); rangeEncoder->EncodeBit(bs, TOT_BITS, 0); - bs += UINT16(INTERVAL-GET_MEAN(bs,PERIOD_BITS, 2)); + bs += UInt16(INTERVAL-GET_MEAN(bs,PERIOD_BITS, 2)); PrevSuccess = 1; RunLength++; } else { rangeEncoder->EncodeBit(bs, TOT_BITS, 1); - bs -= UINT16(GET_MEAN(bs,PERIOD_BITS, 2)); + bs -= UInt16(GET_MEAN(bs,PERIOD_BITS, 2)); InitEsc = ExpEscape[bs >> 10]; NumMasked = 1; CharMask[rs.Symbol] = EscCount; @@ -76,7 +74,7 @@ struct CEncodeInfo: public CInfo void EncodeSymbol2(int symbol, NRangeCoder::CEncoder *rangeEncoder) { int hiCnt, i = MinContext->NumStats - NumMasked; - UINT32 scale; + UInt32 scale; SEE2_CONTEXT* psee2c = makeEscFreq2(i, scale); PPM_CONTEXT::STATE* p = MinContext->Stats - 1; hiCnt = 0; @@ -98,8 +96,8 @@ struct CEncodeInfo: public CInfo return; SYMBOL_FOUND: - UINT32 highCount = hiCnt; - UINT32 lowCount = highCount - p->Freq; + UInt32 highCount = hiCnt; + UInt32 lowCount = highCount - p->Freq; if ( --i ) { PPM_CONTEXT::STATE* p1 = p; diff --git a/7zip/Compress/PPMD/PPMDEncoder.cpp b/7zip/Compress/PPMD/PPMDEncoder.cpp index 0675cdb1..16eaea60 100755 --- a/7zip/Compress/PPMD/PPMDEncoder.cpp +++ b/7zip/Compress/PPMD/PPMDEncoder.cpp @@ -14,13 +14,16 @@ namespace NCompress { namespace NPPMD { +const UInt32 kMinMemSize = (1 << 11); +const UInt32 kMinOrder = 2; + /* -UINT32 g_NumInner = 0; -UINT32 g_InnerCycles = 0; +UInt32 g_NumInner = 0; +UInt32 g_InnerCycles = 0; -UINT32 g_Encode2 = 0; -UINT32 g_Encode2Cycles = 0; -UINT32 g_Encode2Cycles2 = 0; +UInt32 g_Encode2 = 0; +UInt32 g_Encode2Cycles = 0; +UInt32 g_Encode2Cycles2 = 0; class CCounter { @@ -53,9 +56,9 @@ STDMETHODIMP CEncoder::SetRangeEncoder(CRangeEncoder *aRangeEncoder) */ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, - const PROPVARIANT *properties, UINT32 numProperties) + const PROPVARIANT *properties, UInt32 numProperties) { - for (UINT32 i = 0; i < numProperties; i++) + for (UInt32 i = 0; i < numProperties; i++) { const PROPVARIANT &aProperty = properties[i]; switch(propIDs[i]) @@ -72,7 +75,7 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, return E_INVALIDARG; if (aProperty.ulVal < kMinOrder || aProperty.ulVal > kMaxOrderCompress) return E_INVALIDARG; - _order = BYTE(aProperty.ulVal); + _order = Byte(aProperty.ulVal); break; default: return E_INVALIDARG; @@ -83,11 +86,15 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) { - RINOK(outStream->Write(&_order, sizeof(_order), NULL)); - return outStream->Write(&_usedMemorySize, sizeof(_usedMemorySize), NULL); + const UInt32 kPropSize = 5; + Byte properties[kPropSize]; + properties[0] = _order; + for (int i = 0; i < 4; i++) + properties[1 + i] = Byte(_usedMemorySize >> (8 * i)); + return outStream->Write(properties, kPropSize, NULL); } -const UINT32 kUsedMemorySizeDefault = (1 << 24); +const UInt32 kUsedMemorySizeDefault = (1 << 24); const int kOrderDefault = 6; CEncoder::CEncoder(): @@ -112,7 +119,7 @@ public: ~CEncoderFlusher() { _encoder->Flush(); - // _encoder->ReleaseStreams(); + _encoder->ReleaseStreams(); } }; @@ -120,16 +127,23 @@ public: HRESULT CEncoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UINT64 *inSize, const UINT64 *outSize, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { - _inStream.Init(inStream); - _rangeEncoder.Init(outStream); + if (!_inStream.Create(1 << 20)) + return E_OUTOFMEMORY; + if (!_rangeEncoder.Create(1 << 20)) + return E_OUTOFMEMORY; + + _inStream.SetStream(inStream); + _inStream.Init(); + _rangeEncoder.SetStream(outStream); + _rangeEncoder.Init(); - CEncoderFlusher aFlusher(this); + CEncoderFlusher flusher(this); - UINT64 pos = 0; - UINT64 prevProgressPos = 0; + UInt64 pos = 0; + UInt64 prevProgressPos = 0; try { @@ -148,7 +162,7 @@ HRESULT CEncoder::CodeReal(ISequentialInStream *inStream, while (true) { - BYTE symbol; + Byte symbol; if (!_inStream.ReadByte(symbol)) { // here we can write End Mark for stream version. @@ -161,7 +175,7 @@ HRESULT CEncoder::CodeReal(ISequentialInStream *inStream, pos++; if (pos - prevProgressPos >= (1 << 18) && progress != NULL) { - UINT64 outSize = _rangeEncoder.GetProcessedSize(); + UInt64 outSize = _rangeEncoder.GetProcessedSize(); RINOK(progress->SetRatioInfo(&pos, &outSize)); prevProgressPos = pos; } @@ -169,7 +183,7 @@ HRESULT CEncoder::CodeReal(ISequentialInStream *inStream, } STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { try { return CodeReal(inStream, outStream, inSize, outSize, progress); } diff --git a/7zip/Compress/PPMD/PPMDEncoder.h b/7zip/Compress/PPMD/PPMDEncoder.h index 434a727c..80ac7391 100755 --- a/7zip/Compress/PPMD/PPMDEncoder.h +++ b/7zip/Compress/PPMD/PPMDEncoder.h @@ -1,11 +1,9 @@ // Compress/PPMD/Encoder.h -#pragma once - #ifndef __COMPRESS_PPMD_ENCODER_H #define __COMPRESS_PPMD_ENCODER_H -#include "Common/MyCom.h" +#include "../../../Common/MyCom.h" #include "../../ICoder.h" #include "../../Common/InBuffer.h" @@ -28,8 +26,8 @@ public: NRangeCoder::CEncoder _rangeEncoder; CEncodeInfo _info; - UINT32 _usedMemorySize; - BYTE _order; + UInt32 _usedMemorySize; + Byte _order; public: @@ -39,23 +37,21 @@ public: // ICoder interface HRESULT Flush(); - /* void ReleaseStreams() { _inStream.ReleaseStream(); _rangeEncoder.ReleaseStream(); } - */ HRESULT CodeReal(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); STDMETHOD(Code)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); STDMETHOD(SetCoderProperties)(const PROPID *propIDs, - const PROPVARIANT *properties, UINT32 numProperties); + const PROPVARIANT *properties, UInt32 numProperties); STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); diff --git a/7zip/Compress/PPMD/PPMDSubAlloc.h b/7zip/Compress/PPMD/PPMDSubAlloc.h index b2733e26..e92ec316 100755 --- a/7zip/Compress/PPMD/PPMDSubAlloc.h +++ b/7zip/Compress/PPMD/PPMDSubAlloc.h @@ -1,35 +1,42 @@ -// SubAlloc.h +// PPMDSubAlloc.h // This code is based on Dmitry Shkarin's PPMdH code -#pragma once +#ifndef __PPMD_SUBALLOC_H +#define __PPMD_SUBALLOC_H -#ifndef __SubAlloc_H -#define __SubAlloc_H +#include "PPMDType.h" -#include "PPMdType.h" +#include "../../../Common/Alloc.h" const UINT N1=4, N2=4, N3=4, N4=(128+3-1*N1-2*N2-3*N3)/4; const UINT UNIT_SIZE=12, N_INDEXES=N1+N2+N3+N4; #pragma pack(1) -struct MEM_BLK { - WORD Stamp, NU; - MEM_BLK* next, * prev; - void insertAt(MEM_BLK* p) { - next=(prev=p)->next; p->next=next->prev=this; - } - void remove() { prev->next=next; next->prev=prev; } +struct MEM_BLK +{ + UInt16 Stamp, NU; + MEM_BLK *Next, *Prev; + void InsertAt(MEM_BLK* p) + { + Next = (Prev = p)->Next; + p->Next = Next->Prev = this; + } + void Remove() + { + Prev->Next=Next; + Next->Prev=Prev; + } } _PACK_ATTR; #pragma pack() class CSubAllocator { - DWORD SubAllocatorSize; - BYTE Indx2Units[N_INDEXES], Units2Indx[128], GlueCount; - struct NODE { NODE* next; } FreeList[N_INDEXES]; + UInt32 SubAllocatorSize; + Byte Indx2Units[N_INDEXES], Units2Indx[128], GlueCount; + struct NODE { NODE* Next; } FreeList[N_INDEXES]; public: - BYTE* HeapStart, * pText, * UnitsStart, * LoUnit, * HiUnit; + Byte* HeapStart, *pText, *UnitsStart, *LoUnit, *HiUnit; CSubAllocator(): SubAllocatorSize(0), GlueCount(0), @@ -47,159 +54,200 @@ public: }; -inline void InsertNode(void* p,int indx) { - ((NODE*) p)->next=FreeList[indx].next; FreeList[indx].next=(NODE*) p; -} -inline void* RemoveNode(int indx) { - NODE* RetVal=FreeList[indx].next; FreeList[indx].next=RetVal->next; + void InsertNode(void* p, int indx) + { + ((NODE*) p)->Next = FreeList[indx].Next; + FreeList[indx].Next = (NODE*)p; + } + + void* RemoveNode(int indx) + { + NODE* RetVal = FreeList[indx].Next; + FreeList[indx].Next = RetVal->Next; return RetVal; -} -inline UINT U2B(int NU) { return 8*NU+4*NU; } -inline void SplitBlock(void* pv,int OldIndx,int NewIndx) -{ - int i, UDiff=Indx2Units[OldIndx]-Indx2Units[NewIndx]; - BYTE* p=((BYTE*) pv)+U2B(Indx2Units[NewIndx]); - if (Indx2Units[i=Units2Indx[UDiff-1]] != UDiff) { - InsertNode(p,--i); p += U2B(i=Indx2Units[i]); - UDiff -= i; + } + + UINT U2B(int NU) { return 8 * NU + 4 * NU; } + + void SplitBlock(void* pv, int oldIndx, int newIndx) + { + int i, UDiff = Indx2Units[oldIndx] - Indx2Units[newIndx]; + Byte* p = ((Byte*)pv) + U2B(Indx2Units[newIndx]); + if (Indx2Units[i = Units2Indx[UDiff-1]] != UDiff) + { + InsertNode(p, --i); + p += U2B(i = Indx2Units[i]); + UDiff -= i; } - InsertNode(p,Units2Indx[UDiff-1]); -} - -DWORD _STDCALL GetUsedMemory() -{ - DWORD i, k, RetVal=SubAllocatorSize-(HiUnit-LoUnit)-(UnitsStart-pText); - for (k=i=0;i < N_INDEXES;i++, k=0) { - for (NODE* pn=FreeList+i;(pn=pn->next) != NULL;k++) - ; - RetVal -= UNIT_SIZE*Indx2Units[i]*k; + InsertNode(p, Units2Indx[UDiff - 1]); + } + + UInt32 GetUsedMemory() + { + UInt32 i, k, RetVal = SubAllocatorSize - (HiUnit - LoUnit) - (UnitsStart-pText); + for (k = i = 0; i < N_INDEXES; i++, k = 0) + { + for (NODE* pn = FreeList + i;(pn = pn->Next) != NULL; k++) + ; + RetVal -= UNIT_SIZE*Indx2Units[i] * k; } return (RetVal >> 2); -} - - void _STDCALL StopSubAllocator() + } + + void StopSubAllocator() { if ( SubAllocatorSize ) { - #ifdef WIN32 - VirtualFree(HeapStart, 0, MEM_RELEASE); - #else - delete[] HeapStart; - #endif + BigFree(HeapStart); SubAllocatorSize = 0; HeapStart = 0; } } - bool _STDCALL StartSubAllocator(UINT32 aSize) + bool StartSubAllocator(UInt32 size) { - if (SubAllocatorSize == aSize) + if (SubAllocatorSize == size) return true; StopSubAllocator(); - #ifdef WIN32 - if ((HeapStart = (BYTE *)::VirtualAlloc(0, aSize, MEM_COMMIT, PAGE_READWRITE)) == 0) - return false; - #else - if ((HeapStart = new BYTE[aSize]) == NULL) + if ((HeapStart = (Byte *)::BigAlloc(size)) == 0) return false; - #endif - SubAllocatorSize = aSize; + SubAllocatorSize = size; return true; } -inline void InitSubAllocator() -{ + void InitSubAllocator() + { int i, k; - memset(FreeList,0,sizeof(FreeList)); - HiUnit=(pText=HeapStart)+SubAllocatorSize; - UINT Diff=UNIT_SIZE*(SubAllocatorSize/8/UNIT_SIZE*7); - LoUnit=UnitsStart=HiUnit-Diff; - for (i=0,k=1;i < N1 ;i++,k += 1) Indx2Units[i]=k; - for (k++;i < N1+N2 ;i++,k += 2) Indx2Units[i]=k; - for (k++;i < N1+N2+N3 ;i++,k += 3) Indx2Units[i]=k; - for (k++;i < N1+N2+N3+N4;i++,k += 4) Indx2Units[i]=k; - for (GlueCount=k=i=0;k < 128;k++) { - i += (Indx2Units[i] < k+1); Units2Indx[k]=i; + memset(FreeList, 0, sizeof(FreeList)); + HiUnit = (pText = HeapStart) + SubAllocatorSize; + UINT Diff = UNIT_SIZE * (SubAllocatorSize / 8 / UNIT_SIZE * 7); + LoUnit = UnitsStart = HiUnit - Diff; + for (i = 0, k=1; i < N1 ; i++, k += 1) Indx2Units[i]=k; + for (k++; i < N1 + N2 ;i++, k += 2) Indx2Units[i]=k; + for (k++; i < N1 + N2 + N3 ;i++,k += 3) Indx2Units[i]=k; + for (k++; i < N1 + N2 + N3 + N4; i++, k += 4) Indx2Units[i]=k; + for (GlueCount = k = i = 0; k < 128; k++) + { + i += (Indx2Units[i] < k+1); + Units2Indx[k]=i; } -} -inline void GlueFreeBlocks() -{ - MEM_BLK s0, * p, * p1; + } + + void GlueFreeBlocks() + { + MEM_BLK s0, *p, *p1; int i, k, sz; - if (LoUnit != HiUnit) *LoUnit=0; - for (i=0, s0.next=s0.prev=&s0;i < N_INDEXES;i++) - while ( FreeList[i].next ) { - p=(MEM_BLK*) RemoveNode(i); p->insertAt(&s0); - p->Stamp=0xFFFF; p->NU=Indx2Units[i]; - } - for (p=s0.next;p != &s0;p=p->next) - while ((p1=p+p->NU)->Stamp == 0xFFFF && int(p->NU)+p1->NU < 0x10000) { - p1->remove(); p->NU += p1->NU; - } - while ((p=s0.next) != &s0) { - for (p->remove(), sz=p->NU;sz > 128;sz -= 128, p += 128) - InsertNode(p,N_INDEXES-1); - if (Indx2Units[i=Units2Indx[sz-1]] != sz) { - k=sz-Indx2Units[--i]; InsertNode(p+(sz-k),k-1); - } - InsertNode(p,i); + if (LoUnit != HiUnit) + *LoUnit=0; + for (i = 0, s0.Next = s0.Prev = &s0; i < N_INDEXES; i++) + while ( FreeList[i].Next ) + { + p = (MEM_BLK*) RemoveNode(i); + p->InsertAt(&s0); + p->Stamp = 0xFFFF; + p->NU = Indx2Units[i]; + } + for (p=s0.Next; p != &s0; p =p->Next) + while ((p1 = p + p->NU)->Stamp == 0xFFFF && int(p->NU) + p1->NU < 0x10000) + { + p1->Remove(); + p->NU += p1->NU; + } + while ((p=s0.Next) != &s0) + { + for (p->Remove(), sz=p->NU; sz > 128; sz -= 128, p += 128) + InsertNode(p, N_INDEXES - 1); + if (Indx2Units[i = Units2Indx[sz-1]] != sz) + { + k = sz-Indx2Units[--i]; + InsertNode(p + (sz - k), k - 1); + } + InsertNode(p,i); } -} -void* AllocUnitsRare(int indx) -{ - if ( !GlueCount ) { - GlueCount = 255; GlueFreeBlocks(); - if ( FreeList[indx].next ) return RemoveNode(indx); + } + void* AllocUnitsRare(int indx) + { + if ( !GlueCount ) + { + GlueCount = 255; + GlueFreeBlocks(); + if (FreeList[indx].Next) + return RemoveNode(indx); } - int i=indx; - do { - if (++i == N_INDEXES) { - GlueCount--; i=U2B(Indx2Units[indx]); - return (UnitsStart-pText > i)?(UnitsStart -= i):(NULL); - } - } while ( !FreeList[i].next ); - void* RetVal=RemoveNode(i); SplitBlock(RetVal,i,indx); + int i = indx; + do + { + if (++i == N_INDEXES) + { + GlueCount--; + i = U2B(Indx2Units[indx]); + return (UnitsStart - pText > i) ? (UnitsStart -= i) : (NULL); + } + } while (!FreeList[i].Next); + void* RetVal = RemoveNode(i); + SplitBlock(RetVal, i, indx); return RetVal; -} -inline void* AllocUnits(int NU) -{ - int indx=Units2Indx[NU-1]; - if ( FreeList[indx].next ) return RemoveNode(indx); - void* RetVal=LoUnit; LoUnit += U2B(Indx2Units[indx]); - if (LoUnit <= HiUnit) return RetVal; - LoUnit -= U2B(Indx2Units[indx]); return AllocUnitsRare(indx); -} -inline void* AllocContext() -{ - if (HiUnit != LoUnit) return (HiUnit -= UNIT_SIZE); - if ( FreeList->next ) return RemoveNode(0); + } + + void* AllocUnits(int NU) + { + int indx = Units2Indx[NU - 1]; + if (FreeList[indx].Next) + return RemoveNode(indx); + void* RetVal = LoUnit; + LoUnit += U2B(Indx2Units[indx]); + if (LoUnit <= HiUnit) + return RetVal; + LoUnit -= U2B(Indx2Units[indx]); + return AllocUnitsRare(indx); + } + + void* AllocContext() + { + if (HiUnit != LoUnit) + return (HiUnit -= UNIT_SIZE); + if (FreeList->Next) + return RemoveNode(0); return AllocUnitsRare(0); -} -inline void* ExpandUnits(void* OldPtr,int OldNU) -{ - int i0=Units2Indx[OldNU-1], i1=Units2Indx[OldNU-1+1]; - if (i0 == i1) return OldPtr; - void* ptr=AllocUnits(OldNU+1); - if ( ptr ) { - memcpy(ptr,OldPtr,U2B(OldNU)); InsertNode(OldPtr,i0); + } + + void* ExpandUnits(void* oldPtr, int oldNU) + { + int i0=Units2Indx[oldNU - 1], i1=Units2Indx[oldNU - 1 + 1]; + if (i0 == i1) + return oldPtr; + void* ptr = AllocUnits(oldNU + 1); + if (ptr) + { + memcpy(ptr, oldPtr, U2B(oldNU)); + InsertNode(oldPtr, i0); } return ptr; -} -inline void* ShrinkUnits(void* OldPtr,int OldNU,int NewNU) -{ - int i0=Units2Indx[OldNU-1], i1=Units2Indx[NewNU-1]; - if (i0 == i1) return OldPtr; - if ( FreeList[i1].next ) { - void* ptr=RemoveNode(i1); memcpy(ptr,OldPtr,U2B(NewNU)); - InsertNode(OldPtr,i0); return ptr; - } else { - SplitBlock(OldPtr,i0,i1); return OldPtr; + } + + void* ShrinkUnits(void* oldPtr, int oldNU, int newNU) + { + int i0 = Units2Indx[oldNU - 1], i1 = Units2Indx[newNU - 1]; + if (i0 == i1) + return oldPtr; + if ( FreeList[i1].Next ) + { + void* ptr = RemoveNode(i1); + memcpy(ptr, oldPtr, U2B(newNU)); + InsertNode(oldPtr,i0); + return ptr; + } + else + { + SplitBlock(oldPtr, i0, i1); + return oldPtr; } -} -inline void FreeUnits(void* ptr,int OldNU) -{ - InsertNode(ptr,Units2Indx[OldNU-1]); -} + } + + void FreeUnits(void* ptr, int oldNU) + { + InsertNode(ptr, Units2Indx[oldNU - 1]); + } }; #endif diff --git a/7zip/Compress/PPMD/PPMDType.h b/7zip/Compress/PPMD/PPMDType.h index 563d6d04..5a67ac84 100755 --- a/7zip/Compress/PPMD/PPMDType.h +++ b/7zip/Compress/PPMD/PPMDType.h @@ -3,45 +3,15 @@ * Written and distributed to public domain by Dmitry Shkarin 1997, * * 1999-2001 * * Contents: compilation parameters and miscelaneous definitions * - * Comments: system & compiler dependent file * + * Comments: system & compiler dependent file + + * modified by Igor Pavlov (2004-08-29). ****************************************************************************/ -#if !defined(_PPMDTYPE_H_) -#define _PPMDTYPE_H_ +#ifndef __PPMD_TYPE_H +#define __PPMD_TYPE_H -#include <stdio.h> - -const UINT32 kMinMemSize = (1 << 11); -const UINT32 kMinOrder = 2; const int kMaxOrderCompress = 32; -const int MAX_O=255; /* maximum allowed model order */ - -#define _WIN32_ENVIRONMENT_ -//#define _DOS32_ENVIRONMENT_ -//#define _POSIX_ENVIRONMENT_ -//#define _UNKNOWN_ENVIRONMENT_ -#if defined(_WIN32_ENVIRONMENT_)+defined(_DOS32_ENVIRONMENT_)+defined(_POSIX_ENVIRONMENT_)+defined(_UNKNOWN_ENVIRONMENT_) != 1 -#error Only one environment must be defined -#endif /* defined(_WIN32_ENVIRONMENT_)+defined(_DOS32_ENVIRONMENT_)+defined(_POSIX_ENVIRONMENT_)+defined(_UNKNOWN_ENVIRONMENT_) != 1 */ - -#if defined(_WIN32_ENVIRONMENT_) -#include <wtypes.h> -#else /* _DOS32_ENVIRONMENT_ || _POSIX_ENVIRONMENT_ || _UNKNOWN_ENVIRONMENT_ */ -typedef int BOOL; -#define FALSE 0 -#define TRUE 1 -typedef unsigned char BYTE; -typedef unsigned short WORD; -typedef unsigned long DWORD; -typedef unsigned int UINT; -#endif /* defined(_WIN32_ENVIRONMENT_) */ - -#if !defined(_UNKNOWN_ENVIRONMENT_) && !defined(__GNUC__) -#define _FASTCALL __fastcall -#define _STDCALL __stdcall -#else -#define _FASTCALL -#define _STDCALL -#endif /* !defined(_UNKNOWN_ENVIRONMENT_) && !defined(__GNUC__) */ +const int MAX_O = 255; /* maximum allowed model order */ #if defined(__GNUC__) #define _PACK_ATTR __attribute__ ((packed)) @@ -49,14 +19,7 @@ typedef unsigned int UINT; #define _PACK_ATTR #endif /* defined(__GNUC__) */ -// PPMd module works with file streams via ...GETC/...PUTC macros only -typedef FILE _PPMD_FILE; -#define _PPMD_E_GETC(fp) getc(fp) -#define _PPMD_E_PUTC(c,fp) putc((c),fp) -#define _PPMD_D_GETC(fp) getc(fp) -#define _PPMD_D_PUTC(c,fp) putc((c),fp) - template <class T> -inline void _PPMD_SWAP(T& t1,T& t2) { T tmp=t1; t1=t2; t2=tmp; } +inline void _PPMD_SWAP(T& t1,T& t2) { T tmp = t1; t1 = t2; t2 = tmp; } -#endif /* !defined(_PPMDTYPE_H_) */ +#endif diff --git a/7zip/Compress/PPMD/StdAfx.cpp b/7zip/Compress/PPMD/StdAfx.cpp index 2550270c..d0feea85 100755 --- a/7zip/Compress/PPMD/StdAfx.cpp +++ b/7zip/Compress/PPMD/StdAfx.cpp @@ -1,3 +1,3 @@ // StdAfx.cpp -#include "stdafx.h" +#include "StdAfx.h" diff --git a/7zip/Compress/PPMD/StdAfx.h b/7zip/Compress/PPMD/StdAfx.h index 99ff6f25..e7fb6986 100755 --- a/7zip/Compress/PPMD/StdAfx.h +++ b/7zip/Compress/PPMD/StdAfx.h @@ -1,8 +1,8 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> +#include "../../../Common/MyWindows.h" #endif diff --git a/7zip/Compress/PPMD/resource.rc b/7zip/Compress/PPMD/resource.rc index ca4ce99c..8ac85eba 100755 --- a/7zip/Compress/PPMD/resource.rc +++ b/7zip/Compress/PPMD/resource.rc @@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,9,2,0 - PRODUCTVERSION 3,9,2,0 + FILEVERSION 4,16,0,0 + PRODUCTVERSION 4,16,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -85,14 +85,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Igor Pavlov\0" VALUE "FileDescription", "PPMd Coder\0" - VALUE "FileVersion", "3, 9, 2, 0\0" + VALUE "FileVersion", "4, 16, 0, 0\0" VALUE "InternalName", "PPMd\0" - VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "PPMd.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "7-Zip\0" - VALUE "ProductVersion", "3, 9, 2, 0\0" + VALUE "ProductVersion", "4, 16, 0, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/7zip/Compress/RangeCoder/RangeCoder.h b/7zip/Compress/RangeCoder/RangeCoder.h index cb0292f9..186ae8b0 100755 --- a/7zip/Compress/RangeCoder/RangeCoder.h +++ b/7zip/Compress/RangeCoder/RangeCoder.h @@ -1,7 +1,4 @@ -// Compress/RangeCoder.h -// This code is based on Eugene Shelwien's Rangecoder code - -// #pragma once +// Compress/RangeCoder/RangeCoder.h #ifndef __COMPRESS_RANGECODER_H #define __COMPRESS_RANGECODER_H @@ -12,23 +9,25 @@ namespace NCompress { namespace NRangeCoder { -const UINT32 kNumTopBits = 24; -const UINT32 kTopValue = (1 << kNumTopBits); +const int kNumTopBits = 24; +const UInt32 kTopValue = (1 << kNumTopBits); class CEncoder { + UInt32 _ffNum; + Byte _cache; +public: + UInt64 Low; + UInt32 Range; COutBuffer Stream; - UINT64 Low; - UINT32 Range; - UINT32 _ffNum; - BYTE _cache; + bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); } -public: - void Init(ISequentialOutStream *stream) + void SetStream(ISequentialOutStream *stream) { Stream.SetStream(stream); } + void Init() { - Stream.Init(stream); + Stream.Init(); Low = 0; - Range = UINT32(-1); + Range = 0xFFFFFFFF; _ffNum = 0; _cache = 0; } @@ -40,15 +39,11 @@ public: ShiftLow(); } - HRESULT FlushStream() - { return Stream.Flush(); } + HRESULT FlushStream() { return Stream.Flush(); } - /* - void ReleaseStream() - { Stream.ReleaseStream(); } - */ + void ReleaseStream() { Stream.ReleaseStream(); } - void Encode(UINT32 start, UINT32 size, UINT32 total) + void Encode(UInt32 start, UInt32 size, UInt32 total) { Low += start * (Range /= total); Range *= size; @@ -60,13 +55,13 @@ public: } /* - void EncodeDirectBitsDiv(UINT32 value, UINT32 numTotalBits) + void EncodeDirectBitsDiv(UInt32 value, UInt32 numTotalBits) { Low += value * (Range >>= numTotalBits); Normalize(); } - void EncodeDirectBitsDiv2(UINT32 value, UINT32 numTotalBits) + void EncodeDirectBitsDiv2(UInt32 value, UInt32 numTotalBits) { if (numTotalBits <= kNumBottomBits) EncodeDirectBitsDiv(value, numTotalBits); @@ -79,19 +74,19 @@ public: */ void ShiftLow() { - if (Low < (UINT32)0xFF000000 || UINT32(Low >> 32) == 1) + if (Low < (UInt32)0xFF000000 || UInt32(Low >> 32) == 1) { - Stream.WriteByte(_cache + BYTE(Low >> 32)); + Stream.WriteByte(Byte(_cache + Byte(Low >> 32))); for (;_ffNum != 0; _ffNum--) - Stream.WriteByte(0xFF + BYTE(Low >> 32)); - _cache = BYTE(UINT32(Low) >> 24); + Stream.WriteByte(Byte(0xFF + Byte(Low >> 32))); + _cache = Byte(UInt32(Low) >> 24); } else _ffNum++; - Low = UINT32(Low) << 8; + Low = UInt32(Low) << 8; } - void EncodeDirectBits(UINT32 value, UINT32 numTotalBits) + void EncodeDirectBits(UInt32 value, int numTotalBits) { for (int i = numTotalBits - 1; i >= 0; i--) { @@ -106,9 +101,9 @@ public: } } - void EncodeBit(UINT32 size0, UINT32 numTotalBits, UINT32 symbol) + void EncodeBit(UInt32 size0, UInt32 numTotalBits, UInt32 symbol) { - UINT32 newBound = (Range >> numTotalBits) * size0; + UInt32 newBound = (Range >> numTotalBits) * size0; if (symbol == 0) Range = newBound; else @@ -123,16 +118,17 @@ public: } } - UINT64 GetProcessedSize() { return Stream.GetProcessedSize() + _ffNum; } + UInt64 GetProcessedSize() { return Stream.GetProcessedSize() + _ffNum; } }; class CDecoder { public: CInBuffer Stream; - UINT32 Range; - UINT32 Code; - // UINT32 m_Word; + UInt32 Range; + UInt32 Code; + bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); } + void Normalize() { while (Range < kTopValue) @@ -142,23 +138,24 @@ public: } } - void Init(ISequentialInStream *stream) + void SetStream(ISequentialInStream *stream) { Stream.SetStream(stream); } + void Init() { - Stream.Init(stream); + Stream.Init(); Code = 0; - Range = UINT32(-1); + Range = 0xFFFFFFFF; for(int i = 0; i < 5; i++) Code = (Code << 8) | Stream.ReadByte(); } - // void ReleaseStream() { Stream.ReleaseStream(); } + void ReleaseStream() { Stream.ReleaseStream(); } - UINT32 GetThreshold(UINT32 total) + UInt32 GetThreshold(UInt32 total) { return (Code) / ( Range /= total); } - void Decode(UINT32 start, UINT32 size, UINT32 total) + void Decode(UInt32 start, UInt32 size) { Code -= start * Range; Range *= size; @@ -166,31 +163,31 @@ public: } /* - UINT32 DecodeDirectBitsDiv(UINT32 numTotalBits) + UInt32 DecodeDirectBitsDiv(UInt32 numTotalBits) { Range >>= numTotalBits; - UINT32 threshold = Code / Range; + UInt32 threshold = Code / Range; Code -= threshold * Range; Normalize(); return threshold; } - UINT32 DecodeDirectBitsDiv2(UINT32 numTotalBits) + UInt32 DecodeDirectBitsDiv2(UInt32 numTotalBits) { if (numTotalBits <= kNumBottomBits) return DecodeDirectBitsDiv(numTotalBits); - UINT32 result = DecodeDirectBitsDiv(numTotalBits - kNumBottomBits) << kNumBottomBits; + UInt32 result = DecodeDirectBitsDiv(numTotalBits - kNumBottomBits) << kNumBottomBits; return (result | DecodeDirectBitsDiv(kNumBottomBits)); } */ - UINT32 DecodeDirectBits(UINT32 numTotalBits) + UInt32 DecodeDirectBits(int numTotalBits) { - UINT32 range = Range; - UINT32 code = Code; - UINT32 result = 0; - for (UINT32 i = numTotalBits; i > 0; i--) + UInt32 range = Range; + UInt32 code = Code; + UInt32 result = 0; + for (int i = numTotalBits; i != 0; i--) { range >>= 1; /* @@ -201,9 +198,8 @@ public: result |= 1; } */ - UINT32 t = (code - range) >> 31; + UInt32 t = (code - range) >> 31; code -= range & (t - 1); - // range = rangeTmp + ((range & 1) & (1 - t)); result = (result << 1) | (1 - t); if (range < kTopValue) @@ -217,10 +213,10 @@ public: return result; } - UINT32 DecodeBit(UINT32 size0, UINT32 numTotalBits) + UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits) { - UINT32 newBound = (Range >> numTotalBits) * size0; - UINT32 symbol; + UInt32 newBound = (Range >> numTotalBits) * size0; + UInt32 symbol; if (Code < newBound) { symbol = 0; @@ -236,7 +232,7 @@ public: return symbol; } - UINT64 GetProcessedSize() {return Stream.GetProcessedSize(); } + UInt64 GetProcessedSize() {return Stream.GetProcessedSize(); } }; }} diff --git a/7zip/Compress/RangeCoder/RangeCoderBit.cpp b/7zip/Compress/RangeCoder/RangeCoderBit.cpp index c8acf3cd..8e4c4d3a 100755 --- a/7zip/Compress/RangeCoder/RangeCoderBit.cpp +++ b/7zip/Compress/RangeCoder/RangeCoderBit.cpp @@ -7,12 +7,27 @@ namespace NCompress { namespace NRangeCoder { -CPriceTables::CPriceTables() +UInt32 CPriceTables::ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; +static CPriceTables g_PriceTables; + +CPriceTables::CPriceTables() { Init(); } + +void CPriceTables::Init() { + const int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits); + for(int i = kNumBits - 1; i >= 0; i--) + { + UInt32 start = 1 << (kNumBits - i - 1); + UInt32 end = 1 << (kNumBits - i); + for (UInt32 j = start; j < end; j++) + ProbPrices[j] = (i << kNumBitPriceShiftBits) + + (((end - j) << kNumBitPriceShiftBits) >> (kNumBits - i - 1)); + } + /* // simplest: bad solution - for(UINT32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++) - StatePrices[i] = kBitPrice; + for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++) + ProbPrices[i] = kBitPrice; */ /* @@ -21,20 +36,20 @@ CPriceTables::CPriceTables() // float solution double ln2 = log(double(2)); double lnAll = log(double(kBitModelTotal >> kNumMoveReducingBits)); - for(UINT32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++) - StatePrices[i] = UINT32((fabs(lnAll - log(double(i))) / ln2 + kDummyMultMid) * kBitPrice); + for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++) + ProbPrices[i] = UInt32((fabs(lnAll - log(double(i))) / ln2 + kDummyMultMid) * kBitPrice); */ /* // experimental, slow, solution: - for(UINT32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++) + for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++) { const int kCyclesBits = 5; - const UINT32 kCycles = (1 << kCyclesBits); + const UInt32 kCycles = (1 << kCyclesBits); - UINT32 range = UINT32(-1); - UINT32 bitCount = 0; - for (UINT32 j = 0; j < kCycles; j++) + UInt32 range = UInt32(-1); + UInt32 bitCount = 0; + for (UInt32 j = 0; j < kCycles; j++) { range >>= (kNumBitModelTotalBits - kNumMoveReducingBits); range *= i; @@ -55,23 +70,11 @@ CPriceTables::CPriceTables() range -= (1 << 31); } } - StatePrices[i] = (bitCount + ProbPrices[i] = (bitCount // + (1 << (kCyclesBits - 1)) ) >> kCyclesBits; } */ - - const int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits); - for(int i = kNumBits - 1; i >= 0; i--) - { - UINT32 start = 1 << (kNumBits - i - 1); - UINT32 end = 1 << (kNumBits - i); - for (UINT32 j = start; j < end; j++) - StatePrices[j] = (i << kNumBitPriceShiftBits) + - (((end - j) << kNumBitPriceShiftBits) >> (kNumBits - i - 1)); - } } -CPriceTables g_PriceTables; - }} diff --git a/7zip/Compress/RangeCoder/RangeCoderBit.h b/7zip/Compress/RangeCoder/RangeCoderBit.h index 2e49b304..624f887c 100755 --- a/7zip/Compress/RangeCoder/RangeCoderBit.h +++ b/7zip/Compress/RangeCoder/RangeCoderBit.h @@ -1,9 +1,7 @@ // Compress/RangeCoder/RangeCoderBit.h -// #pragma once - -#ifndef __COMPRESS_RANGECODER_BIT_TREE_H -#define __COMPRESS_RANGECODER_BIT_TREE_H +#ifndef __COMPRESS_RANGECODER_BIT_H +#define __COMPRESS_RANGECODER_BIT_H #include "RangeCoder.h" @@ -11,74 +9,90 @@ namespace NCompress { namespace NRangeCoder { const int kNumBitModelTotalBits = 11; -const UINT32 kBitModelTotal = (1 << kNumBitModelTotalBits); +const UInt32 kBitModelTotal = (1 << kNumBitModelTotalBits); const int kNumMoveReducingBits = 2; const int kNumBitPriceShiftBits = 6; -const UINT32 kBitPrice = 1 << kNumBitPriceShiftBits; +const UInt32 kBitPrice = 1 << kNumBitPriceShiftBits; class CPriceTables { public: - UINT32 StatePrices[kBitModelTotal >> kNumMoveReducingBits]; + static UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; + static void Init(); CPriceTables(); }; -extern CPriceTables g_PriceTables; - - -///////////////////////////// -// CBitModel - -template <int aNumMoveBits> +template <int numMoveBits> class CBitModel { public: - UINT32 Probability; - void UpdateModel(UINT32 symbol) + UInt32 Prob; + void UpdateModel(UInt32 symbol) { /* - Probability -= (Probability + ((symbol - 1) & ((1 << aNumMoveBits) - 1))) >> aNumMoveBits; - Probability += (1 - symbol) << (kNumBitModelTotalBits - aNumMoveBits); + Prob -= (Prob + ((symbol - 1) & ((1 << numMoveBits) - 1))) >> numMoveBits; + Prob += (1 - symbol) << (kNumBitModelTotalBits - numMoveBits); */ if (symbol == 0) - Probability += (kBitModelTotal - Probability) >> aNumMoveBits; + Prob += (kBitModelTotal - Prob) >> numMoveBits; else - Probability -= (Probability) >> aNumMoveBits; + Prob -= (Prob) >> numMoveBits; } public: - void Init() { Probability = kBitModelTotal / 2; } + void Init() { Prob = kBitModelTotal / 2; } }; -template <int aNumMoveBits> -class CBitEncoder: public CBitModel<aNumMoveBits> +template <int numMoveBits> +class CBitEncoder: public CBitModel<numMoveBits> { public: - void Encode(CEncoder *encoder, UINT32 symbol) + void Encode(CEncoder *encoder, UInt32 symbol) { - encoder->EncodeBit(Probability, kNumBitModelTotalBits, symbol); - UpdateModel(symbol); + /* + encoder->EncodeBit(this->Prob, kNumBitModelTotalBits, symbol); + this->UpdateModel(symbol); + */ + UInt32 newBound = (encoder->Range >> kNumBitModelTotalBits) * this->Prob; + if (symbol == 0) + { + encoder->Range = newBound; + this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits; + } + else + { + encoder->Low += newBound; + encoder->Range -= newBound; + this->Prob -= (this->Prob) >> numMoveBits; + } + if (encoder->Range < kTopValue) + { + encoder->Range <<= 8; + encoder->ShiftLow(); + } } - UINT32 GetPrice(UINT32 symbol) const + UInt32 GetPrice(UInt32 symbol) const { - return g_PriceTables.StatePrices[ - (((Probability - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits]; + return CPriceTables::ProbPrices[ + (((this->Prob - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits]; } + UInt32 GetPrice0() const { return CPriceTables::ProbPrices[this->Prob >> kNumMoveReducingBits]; } + UInt32 GetPrice1() const { return CPriceTables::ProbPrices[(kBitModelTotal - this->Prob) >> kNumMoveReducingBits]; } }; -template <int aNumMoveBits> -class CBitDecoder: public CBitModel<aNumMoveBits> +template <int numMoveBits> +class CBitDecoder: public CBitModel<numMoveBits> { public: - UINT32 Decode(CDecoder *decoder) + UInt32 Decode(CDecoder *decoder) { - UINT32 newBound = (decoder->Range >> kNumBitModelTotalBits) * Probability; + UInt32 newBound = (decoder->Range >> kNumBitModelTotalBits) * this->Prob; if (decoder->Code < newBound) { decoder->Range = newBound; - Probability += (kBitModelTotal - Probability) >> aNumMoveBits; + this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits; if (decoder->Range < kTopValue) { decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte(); @@ -90,7 +104,7 @@ public: { decoder->Range -= newBound; decoder->Code -= newBound; - Probability -= (Probability) >> aNumMoveBits; + this->Prob -= (this->Prob) >> numMoveBits; if (decoder->Range < kTopValue) { decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte(); @@ -103,5 +117,4 @@ public: }} - #endif diff --git a/7zip/Compress/RangeCoder/RangeCoderBitTree.h b/7zip/Compress/RangeCoder/RangeCoderBitTree.h index 02c74cdb..4f0c78b4 100755 --- a/7zip/Compress/RangeCoder/RangeCoderBitTree.h +++ b/7zip/Compress/RangeCoder/RangeCoderBitTree.h @@ -1,9 +1,7 @@ // Compress/RangeCoder/RangeCoderBitTree.h -// #pragma once - -#ifndef __COMPRESS_RANGECODER_BIT_H -#define __COMPRESS_RANGECODER_BIT_H +#ifndef __COMPRESS_RANGECODER_BIT_TREE_H +#define __COMPRESS_RANGECODER_BIT_TREE_H #include "RangeCoderBit.h" #include "RangeCoderOpt.h" @@ -11,120 +9,56 @@ namespace NCompress { namespace NRangeCoder { -/* -template <int numMoveBits> class CMyBitEncoder: - public NCompression::NArithmetic::CBitEncoder<numMoveBits> {}; -template <int numMoveBits> class CMyBitDecoder: - public NCompression::NArithmetic::CBitDecoder<numMoveBits> {}; -*/ - -////////////////////////// -// CBitTreeEncoder - -template <int numMoveBits, UINT32 NumBitLevels> +template <int numMoveBits, int NumBitLevels> class CBitTreeEncoder { CBitEncoder<numMoveBits> Models[1 << NumBitLevels]; public: void Init() { - for(UINT32 i = 1; i < (1 << NumBitLevels); i++) + for(UInt32 i = 1; i < (1 << NumBitLevels); i++) Models[i].Init(); } - void Encode(CEncoder *rangeEncoder, UINT32 symbol) + void Encode(CEncoder *rangeEncoder, UInt32 symbol) { - UINT32 modelIndex = 1; - for (UINT32 bitIndex = NumBitLevels; bitIndex > 0 ;) + UInt32 modelIndex = 1; + for (int bitIndex = NumBitLevels; bitIndex != 0 ;) { bitIndex--; - UINT32 bit = (symbol >> bitIndex ) & 1; + UInt32 bit = (symbol >> bitIndex) & 1; Models[modelIndex].Encode(rangeEncoder, bit); modelIndex = (modelIndex << 1) | bit; } }; - UINT32 GetPrice(UINT32 symbol) const + void ReverseEncode(CEncoder *rangeEncoder, UInt32 symbol) { - UINT32 price = 0; - UINT32 modelIndex = 1; - for (UINT32 bitIndex = NumBitLevels; bitIndex > 0 ;) + UInt32 modelIndex = 1; + for (int i = 0; i < NumBitLevels; i++) { - bitIndex--; - UINT32 bit = (symbol >> bitIndex ) & 1; - price += Models[modelIndex].GetPrice(bit); - modelIndex = (modelIndex << 1) + bit; + UInt32 bit = symbol & 1; + Models[modelIndex].Encode(rangeEncoder, bit); + modelIndex = (modelIndex << 1) | bit; + symbol >>= 1; } - return price; } -}; - -////////////////////////// -// CBitTreeDecoder - -template <int numMoveBits, UINT32 NumBitLevels> -class CBitTreeDecoder -{ - CBitDecoder<numMoveBits> Models[1 << NumBitLevels]; -public: - void Init() + UInt32 GetPrice(UInt32 symbol) const { - for(UINT32 i = 1; i < (1 << NumBitLevels); i++) - Models[i].Init(); - } - UINT32 Decode(CDecoder *rangeDecoder) - { - UINT32 modelIndex = 1; - RC_INIT_VAR - for(UINT32 bitIndex = NumBitLevels; bitIndex > 0; bitIndex--) + symbol |= (1 << NumBitLevels); + UInt32 price = 0; + while (symbol != 1) { - // modelIndex = (modelIndex << 1) + Models[modelIndex].Decode(rangeDecoder); - RC_GETBIT(numMoveBits, Models[modelIndex].Probability, modelIndex) - } - RC_FLUSH_VAR - return modelIndex - (1 << NumBitLevels); - }; -}; - -//////////////////////////////// -// CReverseBitTreeEncoder - -template <int numMoveBits> -class CReverseBitTreeEncoder2 -{ - CBitEncoder<numMoveBits> *Models; - UINT32 NumBitLevels; -public: - CReverseBitTreeEncoder2(): Models(0) { } - ~CReverseBitTreeEncoder2() { delete []Models; } - void Create(UINT32 numBitLevels) - { - NumBitLevels = numBitLevels; - Models = new CBitEncoder<numMoveBits>[1 << numBitLevels]; - // return (Models != 0); - } - void Init() - { - UINT32 numModels = 1 << NumBitLevels; - for(UINT32 i = 1; i < numModels; i++) - Models[i].Init(); - } - void Encode(CEncoder *rangeEncoder, UINT32 symbol) - { - UINT32 modelIndex = 1; - for (UINT32 i = 0; i < NumBitLevels; i++) - { - UINT32 bit = symbol & 1; - Models[modelIndex].Encode(rangeEncoder, bit); - modelIndex = (modelIndex << 1) | bit; + price += Models[symbol >> 1].GetPrice(symbol & 1); symbol >>= 1; } + return price; } - UINT32 GetPrice(UINT32 symbol) const + UInt32 ReverseGetPrice(UInt32 symbol) const { - UINT32 price = 0; - UINT32 modelIndex = 1; - for (UINT32 i = NumBitLevels; i > 0; i--) + UInt32 price = 0; + UInt32 modelIndex = 1; + for (int i = NumBitLevels; i != 0; i--) { - UINT32 bit = symbol & 1; + UInt32 bit = symbol & 1; symbol >>= 1; price += Models[modelIndex].GetPrice(bit); modelIndex = (modelIndex << 1) | bit; @@ -133,170 +67,94 @@ public: } }; -/* -template <int numMoveBits, int numBitLevels> -class CReverseBitTreeEncoder: public CReverseBitTreeEncoder2<numMoveBits> -{ -public: - CReverseBitTreeEncoder() - { Create(numBitLevels); } -}; -*/ -//////////////////////////////// -// CReverseBitTreeDecoder - -template <int numMoveBits> -class CReverseBitTreeDecoder2 +template <int numMoveBits, int NumBitLevels> +class CBitTreeDecoder { - CBitDecoder<numMoveBits> *Models; - UINT32 NumBitLevels; + CBitDecoder<numMoveBits> Models[1 << NumBitLevels]; public: - CReverseBitTreeDecoder2(): Models(0) { } - ~CReverseBitTreeDecoder2() { delete []Models; } - void Create(UINT32 numBitLevels) - { - NumBitLevels = numBitLevels; - Models = new CBitDecoder<numMoveBits>[1 << numBitLevels]; - // return (Models != 0); - } void Init() { - UINT32 numModels = 1 << NumBitLevels; - for(UINT32 i = 1; i < numModels; i++) + for(UInt32 i = 1; i < (1 << NumBitLevels); i++) Models[i].Init(); } - UINT32 Decode(CDecoder *rangeDecoder) + UInt32 Decode(CDecoder *rangeDecoder) { - UINT32 modelIndex = 1; - UINT32 symbol = 0; + UInt32 modelIndex = 1; RC_INIT_VAR - for(UINT32 bitIndex = 0; bitIndex < NumBitLevels; bitIndex++) + for(int bitIndex = NumBitLevels; bitIndex != 0; bitIndex--) { - // UINT32 bit = Models[modelIndex].Decode(rangeDecoder); - // modelIndex <<= 1; - // modelIndex += bit; - // symbol |= (bit << bitIndex); - RC_GETBIT2(numMoveBits, Models[modelIndex].Probability, modelIndex, ; , symbol |= (1 << bitIndex)) + // modelIndex = (modelIndex << 1) + Models[modelIndex].Decode(rangeDecoder); + RC_GETBIT(numMoveBits, Models[modelIndex].Prob, modelIndex) } RC_FLUSH_VAR - return symbol; + return modelIndex - (1 << NumBitLevels); }; -}; -//////////////////////////// -// CReverseBitTreeDecoder2 - -template <int numMoveBits, UINT32 NumBitLevels> -class CReverseBitTreeDecoder -{ - CBitDecoder<numMoveBits> Models[1 << NumBitLevels]; -public: - void Init() - { - for(UINT32 i = 1; i < (1 << NumBitLevels); i++) - Models[i].Init(); - } - UINT32 Decode(CDecoder *rangeDecoder) + UInt32 ReverseDecode(CDecoder *rangeDecoder) { - UINT32 modelIndex = 1; - UINT32 symbol = 0; + UInt32 modelIndex = 1; + UInt32 symbol = 0; RC_INIT_VAR - for(UINT32 bitIndex = 0; bitIndex < NumBitLevels; bitIndex++) + for(int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++) { - // UINT32 bit = Models[modelIndex].Decode(rangeDecoder); + // UInt32 bit = Models[modelIndex].Decode(rangeDecoder); // modelIndex <<= 1; // modelIndex += bit; // symbol |= (bit << bitIndex); - RC_GETBIT2(numMoveBits, Models[modelIndex].Probability, modelIndex, ; , symbol |= (1 << bitIndex)) + RC_GETBIT2(numMoveBits, Models[modelIndex].Prob, modelIndex, ; , symbol |= (1 << bitIndex)) } RC_FLUSH_VAR return symbol; } }; -/* -////////////////////////// -// CBitTreeEncoder2 - template <int numMoveBits> -class CBitTreeEncoder2 +void ReverseBitTreeEncode(CBitEncoder<numMoveBits> *Models, + CEncoder *rangeEncoder, int NumBitLevels, UInt32 symbol) { - NCompression::NArithmetic::CBitEncoder<numMoveBits> *Models; - UINT32 NumBitLevels; -public: - bool Create(UINT32 numBitLevels) - { - NumBitLevels = numBitLevels; - Models = new NCompression::NArithmetic::CBitEncoder<numMoveBits>[1 << numBitLevels]; - return (Models != 0); - } - void Init() - { - UINT32 numModels = 1 << NumBitLevels; - for(UINT32 i = 1; i < numModels; i++) - Models[i].Init(); - } - void Encode(CMyRangeEncoder *rangeEncoder, UINT32 symbol) - { - UINT32 modelIndex = 1; - for (UINT32 bitIndex = NumBitLevels; bitIndex > 0 ;) - { - bitIndex--; - UINT32 bit = (symbol >> bitIndex ) & 1; - Models[modelIndex].Encode(rangeEncoder, bit); - modelIndex = (modelIndex << 1) | bit; - } - } - UINT32 GetPrice(UINT32 symbol) const + UInt32 modelIndex = 1; + for (int i = 0; i < NumBitLevels; i++) { - UINT32 price = 0; - UINT32 modelIndex = 1; - for (UINT32 bitIndex = NumBitLevels; bitIndex > 0 ;) - { - bitIndex--; - UINT32 bit = (symbol >> bitIndex ) & 1; - price += Models[modelIndex].GetPrice(bit); - modelIndex = (modelIndex << 1) + bit; - } - return price; + UInt32 bit = symbol & 1; + Models[modelIndex].Encode(rangeEncoder, bit); + modelIndex = (modelIndex << 1) | bit; + symbol >>= 1; } -}; - - -////////////////////////// -// CBitTreeDecoder2 +} template <int numMoveBits> -class CBitTreeDecoder2 +UInt32 ReverseBitTreeGetPrice(CBitEncoder<numMoveBits> *Models, + UInt32 NumBitLevels, UInt32 symbol) { - NCompression::NArithmetic::CBitDecoder<numMoveBits> *Models; - UINT32 NumBitLevels; -public: - bool Create(UINT32 numBitLevels) - { - NumBitLevels = numBitLevels; - Models = new NCompression::NArithmetic::CBitDecoder<numMoveBits>[1 << numBitLevels]; - return (Models != 0); - } - void Init() + UInt32 price = 0; + UInt32 modelIndex = 1; + for (int i = NumBitLevels; i != 0; i--) { - UINT32 numModels = 1 << NumBitLevels; - for(UINT32 i = 1; i < numModels; i++) - Models[i].Init(); + UInt32 bit = symbol & 1; + symbol >>= 1; + price += Models[modelIndex].GetPrice(bit); + modelIndex = (modelIndex << 1) | bit; } - UINT32 Decode(CMyRangeDecoder *rangeDecoder) - { - UINT32 modelIndex = 1; - RC_INIT_VAR - for(UINT32 bitIndex = NumBitLevels; bitIndex > 0; bitIndex--) - { - // modelIndex = (modelIndex << 1) + Models[modelIndex].Decode(rangeDecoder); - RC_GETBIT(numMoveBits, Models[modelIndex].Probability, modelIndex) - } - RC_FLUSH_VAR - return modelIndex - (1 << NumBitLevels); - } -}; -*/ + return price; +} + +template <int numMoveBits> +UInt32 ReverseBitTreeDecode(CBitDecoder<numMoveBits> *Models, + CDecoder *rangeDecoder, int NumBitLevels) +{ + UInt32 modelIndex = 1; + UInt32 symbol = 0; + RC_INIT_VAR + for(int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++) + { + // UInt32 bit = Models[modelIndex].Decode(rangeDecoder); + // modelIndex <<= 1; + // modelIndex += bit; + // symbol |= (bit << bitIndex); + RC_GETBIT2(numMoveBits, Models[modelIndex].Prob, modelIndex, ; , symbol |= (1 << bitIndex)) + } + RC_FLUSH_VAR + return symbol; +} }} diff --git a/7zip/Compress/RangeCoder/RangeCoderOpt.h b/7zip/Compress/RangeCoder/RangeCoderOpt.h index f251caa8..668b9a5b 100755 --- a/7zip/Compress/RangeCoder/RangeCoderOpt.h +++ b/7zip/Compress/RangeCoder/RangeCoderOpt.h @@ -1,43 +1,31 @@ // Compress/RangeCoder/RangeCoderOpt.h -// #pragma once - #ifndef __COMPRESS_RANGECODER_OPT_H #define __COMPRESS_RANGECODER_OPT_H -#define RC_INIT_VAR \ - UINT32 range = rangeDecoder->Range; \ - UINT32 code = rangeDecoder->Code; +#define RC_INIT_VAR \ + UInt32 range = rangeDecoder->Range; \ + UInt32 code = rangeDecoder->Code; -#define RC_FLUSH_VAR \ - rangeDecoder->Range = range; \ +#define RC_FLUSH_VAR \ + rangeDecoder->Range = range; \ rangeDecoder->Code = code; -#define RC_NORMALIZE \ - if (range < NCompress::NRangeCoder::kTopValue) \ - { \ - code = (code << 8) | rangeDecoder->Stream.ReadByte(); \ - range <<= 8; } - -#define RC_GETBIT2(numMoveBits, prob, modelIndex, Action0, Action1) \ - {UINT32 newBound = (range >> NCompress::NRangeCoder::kNumBitModelTotalBits) * prob; \ - if (code < newBound) \ - { \ - Action0; \ - range = newBound; \ - prob += (NCompress::NRangeCoder::kBitModelTotal - prob) >> numMoveBits; \ - modelIndex <<= 1; \ - } \ - else \ - { \ - Action1; \ - range -= newBound; \ - code -= newBound; \ - prob -= (prob) >> numMoveBits; \ - modelIndex = (modelIndex << 1) + 1; \ - }} \ - RC_NORMALIZE - -#define RC_GETBIT(numMoveBits, prob, modelIndex) RC_GETBIT2(numMoveBits, prob, modelIndex, ; , ;) +#define RC_NORMALIZE \ + if (range < NCompress::NRangeCoder::kTopValue) \ + { code = (code << 8) | rangeDecoder->Stream.ReadByte(); range <<= 8; } + +#define RC_GETBIT2(numMoveBits, prob, mi, A0, A1) \ + { UInt32 bound = (range >> NCompress::NRangeCoder::kNumBitModelTotalBits) * prob; \ + if (code < bound) \ + { A0; range = bound; \ + prob += (NCompress::NRangeCoder::kBitModelTotal - prob) >> numMoveBits; \ + mi <<= 1; } \ + else \ + { A1; range -= bound; code -= bound; prob -= (prob) >> numMoveBits; \ + mi = (mi + mi) + 1; }} \ + RC_NORMALIZE + +#define RC_GETBIT(numMoveBits, prob, mi) RC_GETBIT2(numMoveBits, prob, mi, ; , ;) #endif diff --git a/7zip/Compress/RangeCoder/StdAfx.h b/7zip/Compress/RangeCoder/StdAfx.h index a32fbed6..b637fd40 100755 --- a/7zip/Compress/RangeCoder/StdAfx.h +++ b/7zip/Compress/RangeCoder/StdAfx.h @@ -1,8 +1,6 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> - -#endif +#endif diff --git a/7zip/Compress/Shrink/DllExports.cpp b/7zip/Compress/Shrink/DllExports.cpp new file mode 100755 index 00000000..25329f97 --- /dev/null +++ b/7zip/Compress/Shrink/DllExports.cpp @@ -0,0 +1,64 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" +#include "ShrinkDecoder.h" + +// {23170F69-40C1-278B-0401-010000000000} +DEFINE_GUID(CLSID_CCompressShrinkDecoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00); + +extern "C" +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) +{ + return TRUE; +} + +STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + if (*clsid != CLSID_CCompressShrinkDecoder) + return CLASS_E_CLASSNOTAVAILABLE; + if (*iid != IID_ICompressCoder) + return E_NOINTERFACE; + CMyComPtr<ICompressCoder> coder = (ICompressCoder *)new NCompress::NShrink::CDecoder; + *outObject = coder.Detach(); + COM_TRY_END + return S_OK; +} + +STDAPI GetNumberOfMethods(UINT32 *numMethods) +{ + *numMethods = 1; + return S_OK; +} + +STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value) +{ + if (index != 0) + return E_INVALIDARG; + ::VariantClear((tagVARIANT *)value); + switch(propID) + { + case NMethodPropID::kID: + { + const char id[] = { 0x04, 0x01, 0x01 }; + if ((value->bstrVal = ::SysAllocStringByteLen(id, sizeof(id))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NMethodPropID::kName: + if ((value->bstrVal = ::SysAllocString(L"Shrink")) != 0) + value->vt = VT_BSTR; + return S_OK; + case NMethodPropID::kDecoder: + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CCompressShrinkDecoder, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + return S_OK; +} diff --git a/7zip/Compress/Shrink/ShrinkDecoder.cpp b/7zip/Compress/Shrink/ShrinkDecoder.cpp new file mode 100755 index 00000000..47628164 --- /dev/null +++ b/7zip/Compress/Shrink/ShrinkDecoder.cpp @@ -0,0 +1,149 @@ +// ShrinkDecoder.cpp + +#include "StdAfx.h" + +#include "ShrinkDecoder.h" + +#include "../../../Common/Alloc.h" +#include "../../Common/InBuffer.h" +#include "../../Common/OutBuffer.h" +#include "../../Common/LSBFDecoder.h" + +namespace NCompress { +namespace NShrink { + +static const UInt32 kBufferSize = (1 << 20); + +static const int kNumMinBits = 9; + +STDMETHODIMP CDecoder ::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + NStream::NLSBF::CBaseDecoder<CInBuffer> inBuffer; + COutBuffer outBuffer; + + if (!inBuffer.Create(kBufferSize)) + return E_OUTOFMEMORY; + inBuffer.SetStream(inStream); + inBuffer.Init(); + + if (!outBuffer.Create(kBufferSize)) + return E_OUTOFMEMORY; + outBuffer.SetStream(outStream); + outBuffer.Init(); + + UInt64 prevPos = 0; + int numBits = kNumMinBits; + UInt32 head = 257; + + bool needPrev = false; + + _parents[256] = 0; // virus protection + _suffixes[256] = 0; + + int i; + for (i = 0; i < 257; i++) + _isFree[i] = false; + for (; i < kNumItems; i++) + _isFree[i] = true; + + UInt32 lastSymbol = 0; + while (true) + { + outBuffer.Flush(); + UInt32 symbol = inBuffer.ReadBits(numBits); + if (inBuffer.ExtraBitsWereRead()) + break; + if (_isFree[symbol]) + return S_FALSE; + if (symbol == 256) + { + // fix it; + UInt32 symbol = inBuffer.ReadBits(numBits); + if (symbol == 1) + { + if (numBits < kNumMaxBits) + numBits++; + } + else if (symbol == 2) + { + /* + maybe need delete prev also ? + if (needPrev) + _isFree[head - 1] = true; + */ + for (i = 257; i < kNumItems; i++) + _isParent[i] = false; + for (i = 257; i < kNumItems; i++) + if (!_isFree[i]) + _isParent[_parents[i]] = true; + for (i = 257; i < kNumItems; i++) + if (!_isParent[i]) + _isFree[i] = true; + head = 257; + while(head < ((UInt32)1 << numBits) && !_isFree[head]) + head++; + if (head < ((UInt32)1 << numBits)) + { + needPrev = true; + _isFree[head] = false; + _parents[head] = (UInt16)lastSymbol; + head++; + } + } + else + return S_FALSE; + continue; + } + UInt32 cur = symbol; + i = 0; + while (cur >= 256) + { + _stack[i++] = _suffixes[cur]; + cur = _parents[cur]; + } + _stack[i++] = (Byte)cur; + if (needPrev) + { + _suffixes[head - 1] = (Byte)cur; + if (symbol == head - 1) + _stack[0] = (Byte)cur; + } + while (i > 0) + outBuffer.WriteByte((_stack[--i])); + while(head < ((UInt32)1 << numBits) && !_isFree[head]) + head++; + if (head < ((UInt32)1 << numBits)) + { + needPrev = true; + _isFree[head] = false; + _parents[head] = (UInt16)symbol; + head++; + } + else + needPrev = false; + lastSymbol = symbol; + + UInt64 nowPos = outBuffer.GetProcessedSize(); + if (progress != NULL && nowPos - prevPos > (1 << 18)) + { + prevPos = nowPos; + UInt64 packSize = inBuffer.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &nowPos)); + } + } + return outBuffer.Flush(); +} + +STDMETHODIMP CDecoder ::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(const COutBufferException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + +}} diff --git a/7zip/Compress/Shrink/ShrinkDecoder.h b/7zip/Compress/Shrink/ShrinkDecoder.h new file mode 100755 index 00000000..1c15ea8a --- /dev/null +++ b/7zip/Compress/Shrink/ShrinkDecoder.h @@ -0,0 +1,39 @@ +// ShrinkDecoder.h + +#ifndef __SHRINK_DECODER_H +#define __SHRINK_DECODER_H + +#include "../../../Common/MyCom.h" + +#include "../../ICoder.h" + +namespace NCompress { +namespace NShrink { + +const int kNumMaxBits = 13; +const UInt32 kNumItems = 1 << kNumMaxBits; + +class CDecoder : + public ICompressCoder, + public CMyUnknownImp +{ + UInt16 _parents[kNumItems]; + Byte _suffixes[kNumItems]; + Byte _stack[kNumItems]; + bool _isFree[kNumItems]; + bool _isParent[kNumItems]; +public: + MY_UNKNOWN_IMP + + STDMETHOD(CodeReal)(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); +}; + +}} + +#endif diff --git a/7zip/Compress/Shrink/StdAfx.cpp b/7zip/Compress/Shrink/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/7zip/Compress/Shrink/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/7zip/Compress/Shrink/StdAfx.h b/7zip/Compress/Shrink/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/7zip/Compress/Shrink/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/7zip/Compress/Shrink/resource.h b/7zip/Compress/Shrink/resource.h new file mode 100755 index 00000000..612062a2 --- /dev/null +++ b/7zip/Compress/Shrink/resource.h @@ -0,0 +1,15 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by resource.rc +// + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/7zip/Compress/Z/StdAfx.cpp b/7zip/Compress/Z/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/7zip/Compress/Z/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/7zip/Compress/Z/StdAfx.h b/7zip/Compress/Z/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/7zip/Compress/Z/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/7zip/Compress/Z/ZDecoder.cpp b/7zip/Compress/Z/ZDecoder.cpp new file mode 100755 index 00000000..b896bf08 --- /dev/null +++ b/7zip/Compress/Z/ZDecoder.cpp @@ -0,0 +1,172 @@ +// ZDecoder.cpp + +#include "StdAfx.h" + +#include "ZDecoder.h" + +#include "../../../Common/Alloc.h" +#include "../../Common/InBuffer.h" +#include "../../Common/OutBuffer.h" +#include "../../Common/LSBFDecoder.h" + +namespace NCompress { +namespace NZ { + +static const UInt32 kBufferSize = (1 << 20); +static const Byte kNumBitsMask = 0x1F; +static const Byte kBlockModeMask = 0x80; +static const int kNumMinBits = 9; +static const int kNumMaxBits = 16; + +void CDecoder::Free() +{ + MyFree(_parents); + _parents = 0; + MyFree(_suffixes); + _suffixes = 0; + MyFree(_stack); + _stack = 0; +} + +bool CDecoder::Alloc(size_t numItems) +{ + Free(); + _parents = (UInt16 *)MyAlloc(numItems * sizeof(UInt16)); + if (_parents == 0) + return false; + _suffixes = (Byte *)MyAlloc(numItems * sizeof(Byte)); + if (_suffixes == 0) + return false; + _stack = (Byte *)MyAlloc(numItems * sizeof(Byte)); + return _stack != 0; +} + +CDecoder::~CDecoder() +{ + Free(); +} + +STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + NStream::NLSBF::CBaseDecoder<CInBuffer> inBuffer; + COutBuffer outBuffer; + + if (!inBuffer.Create(kBufferSize)) + return E_OUTOFMEMORY; + inBuffer.SetStream(inStream); + inBuffer.Init(); + + if (!outBuffer.Create(kBufferSize)) + return E_OUTOFMEMORY; + outBuffer.SetStream(outStream); + outBuffer.Init(); + + int maxbits = _properties & kNumBitsMask; + if (maxbits < kNumMinBits || maxbits > kNumMaxBits) + return S_FALSE; + UInt32 numItems = 1 << maxbits; + bool blockMode = ((_properties & kBlockModeMask) != 0); + if (!blockMode) + return E_NOTIMPL; + + if (maxbits != _numMaxBits || _parents == 0 || _suffixes == 0 || _stack == 0) + { + if (!Alloc(numItems)) + return E_OUTOFMEMORY; + _numMaxBits = maxbits; + } + + UInt64 prevPos = 0; + int numBits = kNumMinBits; + UInt32 head = blockMode ? 257 : 256; + + bool needPrev = false; + + int keepBits = 0; + + _parents[256] = 0; // virus protection + _suffixes[256] = 0; + + while (true) + { + if (keepBits < numBits) + keepBits = numBits * 8; + UInt32 symbol = inBuffer.ReadBits(numBits); + if (inBuffer.ExtraBitsWereRead()) + break; + keepBits -= numBits; + if (symbol >= head) + return S_FALSE; + if (blockMode && symbol == 256) + { + for (;keepBits > 0; keepBits--) + inBuffer.ReadBits(1); + numBits = kNumMinBits; + head = 257; + needPrev = false; + continue; + } + UInt32 cur = symbol; + int i = 0; + while (cur >= 256) + { + _stack[i++] = _suffixes[cur]; + cur = _parents[cur]; + } + _stack[i++] = (Byte)cur; + if (needPrev) + { + _suffixes[head - 1] = (Byte)cur; + if (symbol == head - 1) + _stack[0] = (Byte)cur; + } + while (i > 0) + outBuffer.WriteByte((_stack[--i])); + if (head < numItems) + { + needPrev = true; + _parents[head++] = (UInt16)symbol; + if (head > ((UInt32)1 << numBits)) + { + if (numBits < maxbits) + { + numBits++; + keepBits = numBits * 8; + } + } + } + else + needPrev = false; + + UInt64 nowPos = outBuffer.GetProcessedSize(); + if (progress != NULL && nowPos - prevPos > (1 << 18)) + { + prevPos = nowPos; + UInt64 packSize = inBuffer.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &nowPos)); + } + } + return outBuffer.Flush(); +} + +STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(const COutBufferException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + +STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) +{ + if (size < 1) + return E_INVALIDARG; + _properties = data[0]; + return S_OK; +} + +}} diff --git a/7zip/Compress/Z/ZDecoder.h b/7zip/Compress/Z/ZDecoder.h new file mode 100755 index 00000000..8b7f0b6d --- /dev/null +++ b/7zip/Compress/Z/ZDecoder.h @@ -0,0 +1,44 @@ +// ZDecoder.h + +#ifndef __COMPRESS_ZDECODER_H +#define __COMPRESS_ZDECODER_H + +#include "../../../Common/MyCom.h" +#include "../../ICoder.h" + +namespace NCompress { +namespace NZ { + +class CDecoder : + public ICompressCoder, + public ICompressSetDecoderProperties2, + public CMyUnknownImp +{ + BYTE _properties; + int _numMaxBits; + UInt16 *_parents; + Byte *_suffixes; + Byte *_stack; + +public: + CDecoder(): _properties(0), _numMaxBits(0), _parents(0), _suffixes(0), _stack(0) {}; + ~CDecoder(); + void Free(); + bool Alloc(size_t numItems); + + MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) + + STDMETHOD(CodeReal)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); +}; + +}} + +#endif diff --git a/7zip/Crypto/7zAES/7zAES.cpp b/7zip/Crypto/7zAES/7zAES.cpp index d98d6642..dcf69cb6 100755 --- a/7zip/Crypto/7zAES/7zAES.cpp +++ b/7zip/Crypto/7zAES/7zAES.cpp @@ -1,4 +1,4 @@ -// 7z_AES.h +// 7z_AES.cpp #include "StdAfx.h" @@ -28,7 +28,7 @@ bool CKeyInfo::IsEqualTo(const CKeyInfo &a) const { if (SaltSize != a.SaltSize || NumCyclesPower != a.NumCyclesPower) return false; - for (UINT32 i = 0; i < SaltSize; i++) + for (UInt32 i = 0; i < SaltSize; i++) if (Salt[i] != a.Salt[i]) return false; return (Password == a.Password); @@ -38,40 +38,28 @@ void CKeyInfo::CalculateDigest() { if (NumCyclesPower == 0x3F) { - UINT32 pos; + UInt32 pos; for (pos = 0; pos < SaltSize; pos++) Key[pos] = Salt[pos]; - for (UINT32 i = 0; i < Password.GetCapacity() && pos < kKeySize; i++) + for (UInt32 i = 0; i < Password.GetCapacity() && pos < kKeySize; i++) Key[pos++] = Password[i]; for (; pos < kKeySize; pos++) Key[pos] = 0; } else { - /* - CMyComPtr<ICryptoHash> sha; - RINOK(sha.CoCreateInstance(CLSID_CCrypto_Hash_SHA256)); - RINOK(sha->Init()); - */ - NCrypto::NSHA256::SHA256 sha; - const UINT64 numRounds = UINT64(1) << (NumCyclesPower); - for (UINT64 round = 0; round < numRounds; round++) + const UInt64 numRounds = UInt64(1) << (NumCyclesPower); + Byte temp[8] = { 0,0,0,0,0,0,0,0 }; + for (UInt64 round = 0; round < numRounds; round++) { - /* - RINOK(sha->Update(Salt, SaltSize)); - RINOK(sha->Update(Password, Password.GetCapacity())); - // change it if big endian; - RINOK(sha->Update(&round, sizeof(round))); - */ - - // sha.Update(Salt, sizeof(Salt)); sha.Update(Salt, SaltSize); sha.Update(Password, Password.GetCapacity()); - // change it if big endian; - sha.Update((const BYTE *)&round, sizeof(round)); + sha.Update(temp, 8); + for (int i = 0; i < 8; i++) + if (++(temp[i]) != 0) + break; } - // return sha->GetDigest(Key); sha.Final(Key); } } @@ -133,30 +121,30 @@ void CBase::CalculateDigest() /* -static void GetRandomData(BYTE *data) +static void GetRandomData(Byte *data) { // probably we don't need truly random. // it's enough to prevent dictionary attack; // but it gives some info about time when compressing // was made. - UINT64 tempValue; + UInt64 tempValue; SYSTEMTIME systemTime; FILETIME fileTime; ::GetSystemTime(&systemTime); ::SystemTimeToFileTime(&systemTime, &fileTime); - tempValue = *(const UINT64 *)&fileTime; + tempValue = *(const UInt64 *)&fileTime; LARGE_INTEGER counter; ::QueryPerformanceCounter(&counter); - tempValue += *(const UINT64 *)&counter; - tempValue += (UINT64)(GetTickCount()) << 32; - *(UINT64 *)data = tempValue; + tempValue += *(const UInt64 *)&counter; + tempValue += (UInt64)(GetTickCount()) << 32; + *(UInt64 *)data = tempValue; } */ STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) { _key.Init(); - for (UINT32 i = 0; i < sizeof(_iv); i++) + for (UInt32 i = 0; i < sizeof(_iv); i++) _iv[i] = 0; _key.SaltSize = 0; @@ -169,16 +157,16 @@ STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) // _key.NumCyclesPower = 0x3F; _key.NumCyclesPower = 18; - BYTE firstByte = _key.NumCyclesPower | + Byte firstByte = _key.NumCyclesPower | (((_key.SaltSize == 0) ? 0 : 1) << 7) | (((ivSize == 0) ? 0 : 1) << 6); - RINOK(outStream->Write(&firstByte, sizeof(firstByte), NULL)); + RINOK(outStream->Write(&firstByte, 1, NULL)); if (_key.SaltSize == 0 && ivSize == 0) return S_OK; - BYTE saltSizeSpec = (_key.SaltSize == 0) ? 0 : (_key.SaltSize - 1); - BYTE ivSizeSpec = (ivSize == 0) ? 0 : (ivSize - 1); - BYTE secondByte = ((saltSizeSpec) << 4) | ivSizeSpec; - RINOK(outStream->Write(&secondByte, sizeof(secondByte), NULL)); + Byte saltSizeSpec = (_key.SaltSize == 0) ? 0 : (_key.SaltSize - 1); + Byte ivSizeSpec = (ivSize == 0) ? 0 : (ivSize - 1); + Byte secondByte = ((saltSizeSpec) << 4) | ivSizeSpec; + RINOK(outStream->Write(&secondByte, 1, NULL)); if (_key.SaltSize > 0) { RINOK(outStream->Write(_key.Salt, _key.SaltSize, NULL)); @@ -190,56 +178,40 @@ STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) return S_OK; } -STDMETHODIMP CEncoder::SetDecoderProperties(ISequentialInStream *inStream) -{ - return S_OK; -} - -STDMETHODIMP CDecoder::SetDecoderProperties(ISequentialInStream *inStream) +STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) { _key.Init(); - for (int i = 0; i < sizeof(_iv); i++) + UInt32 i; + for (i = 0; i < sizeof(_iv); i++) _iv[i] = 0; - UINT32 processedSize; - BYTE firstByte; - RINOK(inStream->Read(&firstByte, sizeof(firstByte), &processedSize)); - if (processedSize == 0) + if (size == 0) return S_OK; + UInt32 pos = 0; + Byte firstByte = data[pos++]; _key.NumCyclesPower = firstByte & 0x3F; if ((firstByte & 0xC0) == 0) return S_OK; _key.SaltSize = (firstByte >> 7) & 1; - UINT32 ivSize = (firstByte >> 6) & 1; + UInt32 ivSize = (firstByte >> 6) & 1; - BYTE secondByte; - RINOK(inStream->Read(&secondByte, sizeof(secondByte), &processedSize)); - if (processedSize == 0) + if (pos >= size) return E_INVALIDARG; + Byte secondByte = data[pos++]; _key.SaltSize += (secondByte >> 4); ivSize += (secondByte & 0x0F); - RINOK(inStream->Read(_key.Salt, - _key.SaltSize, &processedSize)); - if (processedSize != _key.SaltSize) + if (pos + _key.SaltSize + ivSize > size) return E_INVALIDARG; - - RINOK(inStream->Read(_iv, ivSize, &processedSize)); - if (processedSize != ivSize) - return E_INVALIDARG; - - return S_OK; -} - -STDMETHODIMP CEncoder::CryptoSetPassword(const BYTE *data, UINT32 size) -{ - _key.Password.SetCapacity(size); - memcpy(_key.Password, data, size); + for (i = 0; i < _key.SaltSize; i++) + _key.Salt[i] = data[pos++]; + for (i = 0; i < ivSize; i++) + _iv[i] = data[pos++]; return S_OK; } -STDMETHODIMP CDecoder::CryptoSetPassword(const BYTE *data, UINT32 size) +STDMETHODIMP CBaseCoder::CryptoSetPassword(const Byte *data, UInt32 size) { _key.Password.SetCapacity(size); memcpy(_key.Password, data, size); @@ -247,12 +219,12 @@ STDMETHODIMP CDecoder::CryptoSetPassword(const BYTE *data, UINT32 size) } /* -static BYTE *WideToRaw(const wchar_t *src, BYTE *dest, int destSize=0x10000000) +static Byte *WideToRaw(const wchar_t *src, Byte *dest, int destSize=0x10000000) { for (int i = 0; i < destSize; i++, src++) { - dest[i * 2] = (BYTE)*src; - dest[i * 2 + 1]= (BYTE)(*src >> 8); + dest[i * 2] = (Byte)*src; + dest[i * 2 + 1]= (Byte)(*src >> 8); if (*src == 0) break; } @@ -276,80 +248,57 @@ bool GetAESLibPath(TCHAR *path) } #endif -STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, UINT64 const *inSize, - const UINT64 *outSize,ICompressProgressInfo *progress) +STDMETHODIMP CBaseCoder::Init() { CalculateDigest(); - - if (_aesEncoder == 0) + if (_aesFilter == 0) { - #ifdef CRYPTO_AES - _aesEncoder = new CAES256_CBC_Encoder; - #else - if ((HMODULE)_aesEncoderLibrary == 0) - { - TCHAR filePath[MAX_PATH + 2]; - if (!GetAESLibPath(filePath)) - return ::GetLastError(); - RINOK(_aesEncoderLibrary.LoadAndCreateCoder2(filePath, - CLSID_CCrypto_AES256_Encoder, &_aesEncoder)); - } - #endif + RINOK(CreateFilter()); } - - CSequentialInStreamImp *ivStreamSpec = new CSequentialInStreamImp; - CMyComPtr<ISequentialInStream> ivStream(ivStreamSpec); - ivStreamSpec->Init(_iv, sizeof(_iv)); - - CSequentialInStreamImp *keyStreamSpec = new CSequentialInStreamImp; - CMyComPtr<ISequentialInStream> keyStream(keyStreamSpec); - keyStreamSpec->Init(_key.Key, sizeof(_key.Key)); - - ISequentialInStream *inStreams[3] = { inStream, ivStream, keyStream }; - UINT64 ivSize = sizeof(_iv); - UINT64 keySize = sizeof(_key.Key); - const UINT64 *inSizes[3] = { inSize, &ivSize, &ivSize, }; - return _aesEncoder->Code(inStreams, inSizes, 3, - &outStream, &outSize, 1, progress); + CMyComPtr<ICryptoProperties> cp; + RINOK(_aesFilter.QueryInterface(IID_ICryptoProperties, &cp)); + RINOK(cp->SetKey(_key.Key, sizeof(_key.Key))); + RINOK(cp->SetInitVector(_iv, sizeof(_iv))); + return S_OK; } -STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, UINT64 const *inSize, - const UINT64 *outSize,ICompressProgressInfo *progress) +STDMETHODIMP_(UInt32) CBaseCoder::Filter(Byte *data, UInt32 size) { - CalculateDigest(); + return _aesFilter->Filter(data, size); +} - if (_aesDecoder == 0) +#ifndef CRYPTO_AES +HRESULT CBaseCoder::CreateFilterFromDLL(REFCLSID clsID) +{ + if (!_aesLibrary) { - #ifdef CRYPTO_AES - _aesDecoder = new CAES256_CBC_Decoder; - #else - if ((HMODULE)_aesDecoderLibrary == 0) - { - TCHAR filePath[MAX_PATH + 2]; - if (!GetAESLibPath(filePath)) - return ::GetLastError(); - RINOK(_aesDecoderLibrary.LoadAndCreateCoder2(filePath, - CLSID_CCrypto_AES256_Decoder, &_aesDecoder)); - } - #endif + TCHAR filePath[MAX_PATH + 2]; + if (!GetAESLibPath(filePath)) + return ::GetLastError(); + return _aesLibrary.LoadAndCreateFilter(filePath, clsID, &_aesFilter); } + return S_OK; +} +#endif - CSequentialInStreamImp *ivStreamSpec = new CSequentialInStreamImp; - CMyComPtr<ISequentialInStream> ivStream(ivStreamSpec); - ivStreamSpec->Init(_iv, sizeof(_iv)); - - CSequentialInStreamImp *keyStreamSpec = new CSequentialInStreamImp; - CMyComPtr<ISequentialInStream> keyStream(keyStreamSpec); - keyStreamSpec->Init(_key.Key, sizeof(_key.Key)); +HRESULT CEncoder::CreateFilter() +{ + #ifdef CRYPTO_AES + _aesFilter = new CAES256_CBC_Encoder; + return S_OK; + #else + return CreateFilterFromDLL(CLSID_CCrypto_AES256_Encoder); + #endif +} - ISequentialInStream *inStreams[3] = { inStream, ivStream, keyStream }; - UINT64 ivSize = sizeof(_iv); - UINT64 keySize = sizeof(_key.Key); - const UINT64 *inSizes[3] = { inSize, &ivSize, &ivSize, }; - return _aesDecoder->Code(inStreams, inSizes, 3, - &outStream, &outSize, 1, progress); +HRESULT CDecoder::CreateFilter() +{ + #ifdef CRYPTO_AES + _aesFilter = new CAES256_CBC_Decoder; + return S_OK; + #else + return CreateFilterFromDLL(CLSID_CCrypto_AES256_Decoder); + #endif } }} diff --git a/7zip/Crypto/7zAES/7zAES.dsp b/7zip/Crypto/7zAES/7zAES.dsp index 002aee9b..3a14c7e9 100755 --- a/7zip/Crypto/7zAES/7zAES.dsp +++ b/7zip/Crypto/7zAES/7zAES.dsp @@ -122,6 +122,14 @@ SOURCE=.\StdAfx.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\NewHandler.cpp # End Source File # Begin Source File @@ -148,6 +156,14 @@ SOURCE=..\..\Common\StreamObjects.cpp SOURCE=..\..\Common\StreamObjects.h # End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File # End Group # Begin Group "Windows" @@ -169,6 +185,14 @@ SOURCE=..\..\..\Windows\Synchronization.cpp SOURCE=..\..\..\Windows\Synchronization.h # End Source File # End Group +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderLoader.h +# End Source File +# End Group # Begin Source File SOURCE=.\7zAES.cpp diff --git a/7zip/Crypto/7zAES/7zAES.h b/7zip/Crypto/7zAES/7zAES.h index 0c0e2cdc..e455b6c8 100755 --- a/7zip/Crypto/7zAES/7zAES.h +++ b/7zip/Crypto/7zAES/7zAES.h @@ -32,18 +32,15 @@ class CKeyInfo { public: int NumCyclesPower; - UINT32 SaltSize; - BYTE Salt[16]; + UInt32 SaltSize; + Byte Salt[16]; CByteBuffer Password; - BYTE Key[kKeySize]; + Byte Key[kKeySize]; bool IsEqualTo(const CKeyInfo &a) const; void CalculateDigest(); - CKeyInfo() - { - Init(); - } + CKeyInfo() { Init(); } void Init() { NumCyclesPower = 0; @@ -69,69 +66,57 @@ class CBase CKeyInfoCache _cachedKeys; protected: CKeyInfo _key; - BYTE _iv[16]; + Byte _iv[16]; // int _ivSize; void CalculateDigest(); CBase(); }; -class CEncoder: - public ICompressCoder, - public ICompressSetDecoderProperties, +class CBaseCoder: + public ICompressFilter, public ICryptoSetPassword, - public ICompressWriteCoderProperties, public CMyUnknownImp, public CBase { - MY_UNKNOWN_IMP3( - ICryptoSetPassword, - ICompressSetDecoderProperties, - ICompressWriteCoderProperties - ) +protected: + #ifndef CRYPTO_AES + CCoderLibrary _aesLibrary; + #endif + CMyComPtr<ICompressFilter> _aesFilter; - STDMETHOD(Code)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, UINT64 const *inSize, - const UINT64 *outSize,ICompressProgressInfo *progress); + virtual HRESULT CreateFilter() = 0; + #ifndef CRYPTO_AES + HRESULT CreateFilterFromDLL(REFCLSID clsID); + #endif +public: + STDMETHOD(Init)(); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); - STDMETHOD(CryptoSetPassword)(const BYTE *aData, UINT32 aSize); - - // ICompressSetDecoderProperties - STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream); + STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); +}; - // ICompressWriteCoderProperties +class CEncoder: + public CBaseCoder, + public ICompressWriteCoderProperties +{ + virtual HRESULT CreateFilter(); +public: + MY_UNKNOWN_IMP2( + ICryptoSetPassword, + ICompressWriteCoderProperties) STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); - - #ifndef CRYPTO_AES - CCoderLibrary _aesEncoderLibrary; - #endif - CMyComPtr<ICompressCoder2> _aesEncoder; }; class CDecoder: - public ICompressCoder, - public ICompressSetDecoderProperties, - public ICryptoSetPassword, - public CMyUnknownImp, - public CBase + public CBaseCoder, + public ICompressSetDecoderProperties2 { + virtual HRESULT CreateFilter(); +public: MY_UNKNOWN_IMP2( ICryptoSetPassword, - ICompressSetDecoderProperties - ) - - STDMETHOD(Code)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, UINT64 const *inSize, - const UINT64 *outSize,ICompressProgressInfo *progress); - - STDMETHOD(CryptoSetPassword)(const BYTE *aData, UINT32 aSize); - // ICompressSetDecoderProperties - - STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream); - - #ifndef CRYPTO_AES - CCoderLibrary _aesDecoderLibrary; - #endif - CMyComPtr<ICompressCoder2> _aesDecoder; + ICompressSetDecoderProperties2) + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); }; }} diff --git a/7zip/Crypto/7zAES/DllExports.cpp b/7zip/Crypto/7zAES/DllExports.cpp index 75998f95..907b74df 100755 --- a/7zip/Crypto/7zAES/DllExports.cpp +++ b/7zip/Crypto/7zAES/DllExports.cpp @@ -2,8 +2,7 @@ #include "StdAfx.h" -#define INITGUID - +#include "Common/MyInitGuid.h" #include "Common/ComTry.h" #include "7zAES.h" @@ -35,23 +34,23 @@ STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) { COM_TRY_BEGIN *outObject = 0; - int correctInterface = (*iid == IID_ICompressCoder); - CMyComPtr<ICompressCoder> coder; + int correctInterface = (*iid == IID_ICompressFilter); + CMyComPtr<ICompressFilter> filter; if (*clsid == CLSID_CCrypto7zAESDecoder) { if (!correctInterface) return E_NOINTERFACE; - coder = (ICompressCoder *)new NCrypto::NSevenZ::CDecoder(); + filter = (ICompressFilter *)new NCrypto::NSevenZ::CDecoder(); } else if (*clsid == CLSID_CCrypto7zAESEncoder) { if (!correctInterface) return E_NOINTERFACE; - coder = (ICompressCoder *)new NCrypto::NSevenZ::CEncoder(); + filter = (ICompressFilter *)new NCrypto::NSevenZ::CEncoder(); } else return CLASS_E_CLASSNOTAVAILABLE; - *outObject = coder.Detach(); + *outObject = filter.Detach(); COM_TRY_END return S_OK; } diff --git a/7zip/Crypto/7zAES/SHA256.cpp b/7zip/Crypto/7zAES/SHA256.cpp index 21c12fa2..9bfa34eb 100755 --- a/7zip/Crypto/7zAES/SHA256.cpp +++ b/7zip/Crypto/7zAES/SHA256.cpp @@ -1,4 +1,4 @@ -// Crypto/HASH/SHA256/SHA256.cpp +// Crypto/SHA256.cpp // This code is based on code from Wei Dai's Crypto++ library. #include "StdAfx.h" @@ -58,10 +58,10 @@ void SHA256::Init() #define s0(x) (rotrFixed(x,7)^rotrFixed(x,18)^(x>>3)) #define s1(x) (rotrFixed(x,17)^rotrFixed(x,19)^(x>>10)) -void SHA256::Transform(UINT32 *state, const UINT32 *data) +void SHA256::Transform(UInt32 *state, const UInt32 *data) { - UINT32 W[16]; - UINT32 T[8]; + UInt32 W[16]; + UInt32 T[8]; /* Copy context->state[] to working vars */ // memcpy(T, state, sizeof(T)); for (int s = 0; s < 8; s++) @@ -101,7 +101,7 @@ void SHA256::Transform(UINT32 *state, const UINT32 *data) // memset(T, 0, sizeof(T)); } -const UINT32 SHA256::K[64] = { +const UInt32 SHA256::K[64] = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, @@ -127,20 +127,20 @@ const UINT32 SHA256::K[64] = { void SHA256::WriteByteBlock() { - UINT32 data32[16]; + UInt32 data32[16]; for (int i = 0; i < 16; i++) { - data32[i] = (UINT32(_buffer[i * 4]) << 24) + - (UINT32(_buffer[i * 4 + 1]) << 16) + - (UINT32(_buffer[i * 4 + 2]) << 8) + - UINT32(_buffer[i * 4 + 3]); + data32[i] = (UInt32(_buffer[i * 4]) << 24) + + (UInt32(_buffer[i * 4 + 1]) << 16) + + (UInt32(_buffer[i * 4 + 2]) << 8) + + UInt32(_buffer[i * 4 + 3]); } Transform(m_digest, data32); } -void SHA256::Update(const BYTE *data, UINT32 size) +void SHA256::Update(const Byte *data, UInt32 size) { - UINT32 curBufferPos = UINT32(m_count) & 0x3F; + UInt32 curBufferPos = UInt32(m_count) & 0x3F; while (size > 0) { while(curBufferPos < 64 && size > 0) @@ -157,10 +157,10 @@ void SHA256::Update(const BYTE *data, UINT32 size) } } -void SHA256::Final(BYTE *digest) +void SHA256::Final(Byte *digest) { - UINT64 lenInBits = (m_count << 3); - UINT32 curBufferPos = UINT32(m_count) & 0x3F; + UInt64 lenInBits = (m_count << 3); + UInt32 curBufferPos = UInt32(m_count) & 0x3F; _buffer[curBufferPos++] = 0x80; while (curBufferPos != (64 - 8)) { @@ -171,7 +171,7 @@ void SHA256::Final(BYTE *digest) } for (int i = 0; i < 8; i++) { - _buffer[curBufferPos++] = BYTE(lenInBits >> 56); + _buffer[curBufferPos++] = Byte(lenInBits >> 56); lenInBits <<= 8; } WriteByteBlock(); diff --git a/7zip/Crypto/7zAES/SHA256.h b/7zip/Crypto/7zAES/SHA256.h index 59024435..0ccebca2 100755 --- a/7zip/Crypto/7zAES/SHA256.h +++ b/7zip/Crypto/7zAES/SHA256.h @@ -1,4 +1,4 @@ -// Crypto/SHA/SHA256.h +// Crypto/SHA256.h #ifndef __CRYPTO_SHA256_H #define __CRYPTO_SHA256_H @@ -10,19 +10,19 @@ namespace NSHA256 { class SHA256 { - static const UINT32 K[64]; + static const UInt32 K[64]; - UINT32 m_digest[8]; - UINT64 m_count; - BYTE _buffer[64]; - static void Transform(UINT32 *digest, const UINT32 *data); + UInt32 m_digest[8]; + UInt64 m_count; + Byte _buffer[64]; + static void Transform(UInt32 *digest, const UInt32 *data); void WriteByteBlock(); public: enum {DIGESTSIZE = 32}; SHA256() { Init(); } ; void Init(); - void Update(const BYTE *data, UINT32 size); - void Final(BYTE *digest); + void Update(const Byte *data, UInt32 size); + void Final(Byte *digest); }; }} diff --git a/7zip/Crypto/7zAES/StdAfx.cpp b/7zip/Crypto/7zAES/StdAfx.cpp index 2550270c..d0feea85 100755 --- a/7zip/Crypto/7zAES/StdAfx.cpp +++ b/7zip/Crypto/7zAES/StdAfx.cpp @@ -1,3 +1,3 @@ // StdAfx.cpp -#include "stdafx.h" +#include "StdAfx.h" diff --git a/7zip/Crypto/7zAES/StdAfx.h b/7zip/Crypto/7zAES/StdAfx.h index 99ff6f25..e7fb6986 100755 --- a/7zip/Crypto/7zAES/StdAfx.h +++ b/7zip/Crypto/7zAES/StdAfx.h @@ -1,8 +1,8 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> +#include "../../../Common/MyWindows.h" #endif diff --git a/7zip/Crypto/7zAES/resource.rc b/7zip/Crypto/7zAES/resource.rc index 15641858..d88d16c8 100755 --- a/7zip/Crypto/7zAES/resource.rc +++ b/7zip/Crypto/7zAES/resource.rc @@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,9,2,0 - PRODUCTVERSION 3,9,2,0 + FILEVERSION 4,16,0,0 + PRODUCTVERSION 4,16,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -84,15 +84,15 @@ BEGIN BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Igor Pavlov\0" - VALUE "FileDescription", "7z-AES Crypto\0" - VALUE "FileVersion", "3, 9, 2, 0\0" + VALUE "FileDescription", "7z-AES Crypto Codec\0" + VALUE "FileVersion", "4, 16, 0, 0\0" VALUE "InternalName", "7zAES\0" - VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "7zAES.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "7-Zip\0" - VALUE "ProductVersion", "3, 9, 2, 0\0" + VALUE "ProductVersion", "4, 16, 0, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/7zip/Crypto/AES/AES.dsp b/7zip/Crypto/AES/AES.dsp index 1e132956..c196c5d8 100755 --- a/7zip/Crypto/AES/AES.dsp +++ b/7zip/Crypto/AES/AES.dsp @@ -101,32 +101,16 @@ SOURCE=.\DllExports.cpp # End Source File # Begin Source File -SOURCE=.\StdAfx.cpp -# ADD CPP /Yc"StdAfx.h" -# End Source File -# Begin Source File - -SOURCE=.\StdAfx.h -# End Source File -# End Group -# Begin Group "7zip common" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\Common\InBuffer.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\Common\InBuffer.h +SOURCE=.\resource.rc # End Source File # Begin Source File -SOURCE=..\..\Common\OutBuffer.cpp +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" # End Source File # Begin Source File -SOURCE=..\..\Common\OutBuffer.h +SOURCE=.\StdAfx.h # End Source File # End Group # Begin Group "AES" @@ -215,9 +199,5 @@ SOURCE=.\MyAES.cpp SOURCE=.\MyAES.h # End Source File -# Begin Source File - -SOURCE=.\resource.rc -# End Source File # End Target # End Project diff --git a/7zip/Crypto/AES/AES_CBC.h b/7zip/Crypto/AES/AES_CBC.h index 67780a9d..fa3485a9 100755 --- a/7zip/Crypto/AES/AES_CBC.h +++ b/7zip/Crypto/AES/AES_CBC.h @@ -5,16 +5,17 @@ #include "aescpp.h" -class CAES_CBCEncoder: public AESclass +class CAES_CBC: public AESclass { - BYTE _prevBlock[16]; +protected: + Byte _prevBlock[16]; public: - void Init(const BYTE *iv) + void Init(const Byte *iv) { for (int i = 0; i < 16; i++) _prevBlock[i] = iv[i]; } - void ProcessData(BYTE *outBlock, const BYTE *inBlock) + void Encode(const Byte *inBlock, Byte *outBlock) { int i; for (i = 0; i < 16; i++) @@ -23,18 +24,8 @@ public: for (i = 0; i < 16; i++) _prevBlock[i] = outBlock[i]; } -}; -class CAES_CBCCBCDecoder: public AESclass -{ - BYTE _prevBlock[16]; -public: - void Init(const BYTE *iv) - { - for (int i = 0; i < 16; i++) - _prevBlock[i] = iv[i]; - } - void ProcessData(BYTE *outBlock, const BYTE *inBlock) + void Decode(const Byte *inBlock, Byte *outBlock) { dec_blk(inBlock, outBlock); int i; diff --git a/7zip/Crypto/AES/DllExports.cpp b/7zip/Crypto/AES/DllExports.cpp index 124a40a5..29d5fac1 100755 --- a/7zip/Crypto/AES/DllExports.cpp +++ b/7zip/Crypto/AES/DllExports.cpp @@ -2,87 +2,10 @@ #include "StdAfx.h" -#define INITGUID - +#include "Common/MyInitGuid.h" #include "Common/ComTry.h" -#include "../../ICoder.h" #include "MyAES.h" -/* -// {23170F69-40C1-278B-0601-000000000100} -DEFINE_GUID(CLSID_CCrypto_AES_Encoder, -0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00); - -// {23170F69-40C1-278B-0601-000000000000} -DEFINE_GUID(CLSID_CCrypto_AES_Decoder, -0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); -*/ - -/* -#include "Interface/ICoder.h" - -#include "Alien/Crypto/CryptoPP/crc.h" -#include "Alien/Crypto/CryptoPP/sha.h" -#include "Alien/Crypto/CryptoPP/md2.h" -#include "Alien/Crypto/CryptoPP/md5.h" -#include "Alien/Crypto/CryptoPP/ripemd.h" -#include "Alien/Crypto/CryptoPP/haval.h" -// #include "Alien/Crypto/CryptoPP/tiger.h" - - -using namespace CryptoPP; - -#define CLSIDName(Name) CLSID_CCryptoHash ## Name -#define ClassName(Name) aClass ## Name - -// {23170F69-40C1-278B-17??-000000000000} -#define MyClassID(Name, anID) DEFINE_GUID(CLSIDName(Name), \ - 0x23170F69, 0x40C1, 0x278B, 0x17, anID, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - -#define Pair(Name, anID) MyClassID(Name, anID)\ -typedef CHash<Name, &CLSIDName(Name)> ClassName(Name); - -Pair(CRC32, 1) -Pair(SHA1, 2) -Pair(SHA256, 3) -Pair(SHA384, 4) -Pair(SHA512, 5) -Pair(MD2, 6) -Pair(MD5, 7) -Pair(RIPEMD160, 8) -Pair(HAVAL, 9) -// Pair(Tiger, 18) - -#define My_OBJECT_ENTRY(ID) OBJECT_ENTRY(CLSIDName(ID), ClassName(ID)) - -BEGIN_OBJECT_MAP(ObjectMap) - My_OBJECT_ENTRY(CRC32) - My_OBJECT_ENTRY(SHA1) - My_OBJECT_ENTRY(SHA256) - My_OBJECT_ENTRY(SHA384) - My_OBJECT_ENTRY(SHA512) - My_OBJECT_ENTRY(MD2) - My_OBJECT_ENTRY(MD5) - My_OBJECT_ENTRY(RIPEMD160) - My_OBJECT_ENTRY(HAVAL) -// My_OBJECT_ENTRY(Tiger) -END_OBJECT_MAP() -*/ - -/* -#define MyOBJECT_ENTRY(Name) \ - OBJECT_ENTRY(CLSID_CCrypto ## Name ## _Encoder, C ## Name ## _Encoder) \ - OBJECT_ENTRY(CLSID_CCrypto ## Name ## _Decoder, C ## Name ## _Decoder) \ - -BEGIN_OBJECT_MAP(ObjectMap) - MyOBJECT_ENTRY(_AES128_CBC) - MyOBJECT_ENTRY(_AES256_CBC) -END_OBJECT_MAP() -*/ - -///////////////////////////////////////////////////////////////////////////// -// DLL Entry Point - extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) { @@ -91,13 +14,11 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) #define MY_CreateClass(n) \ if (*clsid == CLSID_CCrypto_ ## n ## _Encoder) { \ - if (!correctInterface) \ - return E_NOINTERFACE; \ - coder = (ICompressCoder2 *)new C ## n ## _Encoder(); \ + if (!correctInterface) return E_NOINTERFACE; \ + filter = (ICompressFilter *)new C ## n ## _Encoder(); \ } else if (*clsid == CLSID_CCrypto_ ## n ## _Decoder){ \ - if (!correctInterface) \ - return E_NOINTERFACE; \ - coder = (ICompressCoder2 *)new C ## n ## _Decoder(); \ + if (!correctInterface) return E_NOINTERFACE; \ + filter = (ICompressFilter *)new C ## n ## _Decoder(); \ } STDAPI CreateObject( @@ -107,15 +28,15 @@ STDAPI CreateObject( { COM_TRY_BEGIN *outObject = 0; - int correctInterface = (*interfaceID == IID_ICompressCoder2); - CMyComPtr<ICompressCoder2> coder; + int correctInterface = (*interfaceID == IID_ICompressFilter); + CMyComPtr<ICompressFilter> filter; MY_CreateClass(AES128_CBC) else MY_CreateClass(AES256_CBC) else return CLASS_E_CLASSNOTAVAILABLE; - *outObject = coder.Detach(); + *outObject = filter.Detach(); return S_OK; COM_TRY_END } @@ -173,12 +94,6 @@ STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value) (const char *)method.Encoder, sizeof(GUID))) != 0) value->vt = VT_BSTR; return S_OK; - case NMethodPropID::kInStreams: - { - value->vt = VT_UI4; - value->ulVal = 3; - return S_OK; - } } return S_OK; } diff --git a/7zip/Crypto/AES/MyAES.cpp b/7zip/Crypto/AES/MyAES.cpp index e97af86b..d52ab36b 100755 --- a/7zip/Crypto/AES/MyAES.cpp +++ b/7zip/Crypto/AES/MyAES.cpp @@ -1,4 +1,4 @@ -// Crypto/Rar20/Encoder.h +// Crypto/AES/MyAES.cpp #include "StdAfx.h" @@ -6,193 +6,70 @@ #include "MyAES.h" #include "Windows/Defs.h" -#include "Common/Defs.h" #include "AES_CBC.h" -extern "C" -{ -#include "aesopt.h" +static const int kAESBlockSize = 16; + +extern "C" +{ +#include "aesopt.h" } + class CTabInit { public: - CTabInit() - { - gen_tabs(); - } + CTabInit() { gen_tabs();} } g_TabInit; -const int kBlockSize = 16; +STDMETHODIMP CAESFilter::Init() +{ + return S_OK; +} -static HRESULT Encode( - CInBuffer &inBuffer, - COutBuffer &outBuffer, - ISequentialInStream **inStreams, - const UINT64 **inSizes, - UINT32 numInStreams, - ISequentialOutStream **outStreams, - const UINT64 **outSizes, - UINT32 numOutStreams, - ICompressProgressInfo *progress, - UINT32 keySize) +STDMETHODIMP_(UInt32) CAESFilter::Filter(Byte *data, UInt32 size) { - try + if (size > 0 && size < kAESBlockSize) + return kAESBlockSize; + UInt32 i; + for (i = 0; i + kAESBlockSize <= size; i += kAESBlockSize) { - if (numInStreams != 3 || numOutStreams != 1) - return E_INVALIDARG; - - BYTE key[32]; - BYTE iv[kBlockSize]; - - /* - int i; - for (i = 0; i < kBlockSize; i++) - iv[i] = 1; - for (i = 0; i < keySize; i++) - key[i] = 2; - - RINOK(outStreams[1]->Write(iv, kBlockSize, NULL)); - RINOK(outStreams[2]->Write(key, keySize, NULL)); - */ - UINT32 processedSize; - RINOK(inStreams[1]->Read(iv, kBlockSize, &processedSize)); - if (processedSize != kBlockSize) - return E_FAIL; - - RINOK(inStreams[2]->Read(key, keySize, &processedSize)); - if (processedSize != keySize) - return E_FAIL; - - CAES_CBCEncoder encoder; - encoder.enc_key(key, keySize); - encoder.Init(iv); - - inBuffer.Init(inStreams[0]); - outBuffer.Init(outStreams[0]); - - UINT64 nowPos = 0, posPrev = 0; - while(true) - { - BYTE inBlock[kBlockSize], outBlock[kBlockSize]; - UINT32 numBytes; - inBuffer.ReadBytes(inBlock, kBlockSize, numBytes); - for (int i = numBytes; i < kBlockSize; i++) - inBlock[i] = 0; - encoder.ProcessData(outBlock, inBlock); - outBuffer.WriteBytes(outBlock, kBlockSize); - - nowPos += numBytes; - if (progress != NULL && (nowPos - posPrev) > (1 << 18)) - { - UINT64 outSize = nowPos - numBytes + kBlockSize; - RINOK(progress->SetRatioInfo(&nowPos, &outSize)); - posPrev = nowPos; - } - if (numBytes < kBlockSize) - break; - } - return outBuffer.Flush(); - // inBuffer.ReleaseStream(); - // outBuffer.ReleaseStream(); - // return S_OK; + Byte outBlock[kAESBlockSize]; + SubFilter(data + i, outBlock); + for (int j = 0; j < kAESBlockSize; j++) + data[i + j] = outBlock[j]; } - catch(const CInBufferException &e) { return e.ErrorCode; } - catch(const COutBufferException &e) { return e.ErrorCode; } - catch(...) { return E_FAIL; } + return i; } -static HRESULT Decode( - CInBuffer &inBuffer, - COutBuffer &outBuffer, - ISequentialInStream **inStreams, - const UINT64 **inSizes, - UINT32 numInStreams, - ISequentialOutStream **outStreams, - const UINT64 **outSizes, - UINT32 numOutStreams, - ICompressProgressInfo *progress, - UINT32 keySize) +STDMETHODIMP CAESFilter::SetInitVector(const Byte *data, UInt32 size) { - try - { - if (numInStreams != 3 || numOutStreams != 1) - return E_INVALIDARG; - BYTE key[32]; - BYTE iv[kBlockSize]; - UINT32 processedSize; - RINOK(inStreams[1]->Read(iv, kBlockSize, &processedSize)); - if (processedSize != kBlockSize) - return E_FAIL; - - RINOK(inStreams[2]->Read(key, keySize, &processedSize)); - if (processedSize != keySize) - return E_FAIL; - - CAES_CBCCBCDecoder decoder; - decoder.dec_key(key, keySize); - decoder.Init(iv); - - inBuffer.Init(inStreams[0]); - outBuffer.Init(outStreams[0]); - - const UINT64 *outSize = outSizes[0]; - UINT64 nowPos = 0; - UINT64 posPrev = 0; - while(true) - { - BYTE inBlock[kBlockSize], outBlock[kBlockSize]; - UINT32 numBytes; - inBuffer.ReadBytes(inBlock, kBlockSize, numBytes); - if (numBytes == 0) - break; - decoder.ProcessData(outBlock, inBlock); - UINT32 numBytesToWrite = kBlockSize; - if (outSize != 0) - numBytesToWrite = (UINT32)MyMin((*outSize - nowPos), UINT64(numBytesToWrite)); - outBuffer.WriteBytes(outBlock, numBytesToWrite); - nowPos += numBytesToWrite; - - if (progress != NULL && (nowPos - posPrev) > (1 << 18)) - { - UINT64 inSize = inBuffer.GetProcessedSize(); - RINOK(progress->SetRatioInfo(&inSize, &nowPos)); - posPrev = nowPos; - } - - if (outSize != 0) - if (nowPos >= *outSize) - break; - } - return outBuffer.Flush(); - // inBuffer.ReleaseStream(); - // outBuffer.ReleaseStream(); - // return S_OK; - } - catch(const CInBufferException &e) { return e.ErrorCode; } - catch(const COutBufferException &e) { return e.ErrorCode; } - catch(...) { return E_FAIL; } + if (size != 16) + return E_INVALIDARG; + AES.Init(data); + return S_OK; } +STDMETHODIMP CAESEncoder::SetKey(const Byte *data, UInt32 size) +{ + if (AES.enc_key(data, size) != aes_good) + return E_FAIL; + return S_OK; +} -#define MyClassCryptoImp(Name, keySize) \ -STDMETHODIMP C ## Name ## _Encoder::Code( \ - ISequentialInStream **inStreams, const UINT64 **inSizes, UINT32 numInStreams, \ - ISequentialOutStream **outStreams, const UINT64 **outSizes, UINT32 numOutStreams, \ - ICompressProgressInfo *progress) \ -{ \ - return Encode(_inByte, _outByte, inStreams, inSizes, numInStreams, \ - outStreams, outSizes, numOutStreams, progress, keySize); \ -} \ -STDMETHODIMP C ## Name ## _Decoder::Code( \ - ISequentialInStream **inStreams, const UINT64 **inSizes, UINT32 numInStreams, \ - ISequentialOutStream **outStreams, const UINT64 **outSizes, UINT32 numOutStreams, \ - ICompressProgressInfo *progress) \ -{ \ - return Decode(_inByte, _outByte, inStreams, inSizes, numInStreams, \ - outStreams, outSizes, numOutStreams, progress, keySize); \ +void CAESEncoder::SubFilter(const Byte *inBlock, Byte *outBlock) +{ + AES.Encode(inBlock, outBlock); } -MyClassCryptoImp(AES128_CBC, 16) -MyClassCryptoImp(AES256_CBC, 32) +STDMETHODIMP CAESDecoder::SetKey(const Byte *data, UInt32 size) +{ + if (AES.dec_key(data, size) != aes_good) + return E_FAIL; + return S_OK; +} +void CAESDecoder::SubFilter(const Byte *inBlock, Byte *outBlock) +{ + AES.Decode(inBlock, outBlock); +} diff --git a/7zip/Crypto/AES/MyAES.h b/7zip/Crypto/AES/MyAES.h index 3da6b041..f224dee3 100755 --- a/7zip/Crypto/AES/MyAES.h +++ b/7zip/Crypto/AES/MyAES.h @@ -1,6 +1,4 @@ -// Cipher/AES/MyAES.h - -#pragma once +// Crypto/AES/MyAES.h #ifndef __CIPHER_MYAES_H #define __CIPHER_MYAES_H @@ -9,37 +7,53 @@ #include "Common/MyCom.h" #include "../../ICoder.h" -#include "../../IPassword.h" -#include "../../Common/InBuffer.h" -#include "../../Common/OutBuffer.h" - -// #include "Alien/Crypto/CryptoPP/algparam.h" -// #include "Alien/Crypto/CryptoPP/modes.h" -// #include "Alien/Crypto/CryptoPP/aes.h" - -#define MyClassCrypto3(Name) \ -class C ## Name: \ - public ICompressCoder2, \ - public CMyUnknownImp { \ - CInBuffer _inByte; \ - COutBuffer _outByte; \ -public: \ - MY_UNKNOWN_IMP \ - STDMETHOD(Code)( \ - ISequentialInStream **inStreams, const UINT64 **inSizes, UINT32 numInStreams, \ - ISequentialOutStream **outStreams, const UINT64 **outSizes, UINT32 numOutStreams, \ - ICompressProgressInfo *progress); \ +#include "AES_CBC.h" + +class CAESFilter: + public ICompressFilter, + public ICryptoProperties, + public CMyUnknownImp +{ +protected: + CAES_CBC AES; + // Byte Key[32]; + // Byte IV[kAESBlockSize]; +public: + MY_UNKNOWN_IMP1(ICryptoProperties) + STDMETHOD(Init)(); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); + STDMETHOD(SetKey)(const Byte *data, UInt32 size) = 0; + STDMETHOD(SetInitVector)(const Byte *data, UInt32 size); + virtual void SubFilter(const Byte *inBlock, Byte *outBlock) = 0; +}; + +class CAESEncoder: public CAESFilter +{ +public: + STDMETHOD(SetKey)(const Byte *data, UInt32 size); + virtual void SubFilter(const Byte *inBlock, Byte *outBlock); }; +class CAESDecoder: public CAESFilter +{ +public: + STDMETHOD(SetKey)(const Byte *data, UInt32 size); + virtual void SubFilter(const Byte *inBlock, Byte *outBlock); +}; + +#define MyClassCrypto3E(Name) class C ## Name: public CAESEncoder { }; +#define MyClassCrypto3D(Name) class C ## Name: public CAESDecoder { }; + // {23170F69-40C1-278B-0601-000000000000} #define MyClassCrypto2(Name, id, encodingId) \ DEFINE_GUID(CLSID_CCrypto_ ## Name, \ -0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, id, 0x00, 0x00, 0x00, encodingId, 0x00); \ -MyClassCrypto3(Name) \ +0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, id, 0x00, 0x00, 0x00, encodingId, 0x00); #define MyClassCrypto(Name, id) \ MyClassCrypto2(Name ## _Encoder, id, 0x01) \ -MyClassCrypto2(Name ## _Decoder, id, 0x00) +MyClassCrypto3E(Name ## _Encoder) \ +MyClassCrypto2(Name ## _Decoder, id, 0x00) \ +MyClassCrypto3D(Name ## _Decoder) \ MyClassCrypto(AES128_CBC, 0x01) MyClassCrypto(AES256_CBC, 0x81) diff --git a/7zip/Crypto/AES/StdAfx.cpp b/7zip/Crypto/AES/StdAfx.cpp index 2550270c..d0feea85 100755 --- a/7zip/Crypto/AES/StdAfx.cpp +++ b/7zip/Crypto/AES/StdAfx.cpp @@ -1,3 +1,3 @@ // StdAfx.cpp -#include "stdafx.h" +#include "StdAfx.h" diff --git a/7zip/Crypto/AES/StdAfx.h b/7zip/Crypto/AES/StdAfx.h index a32fbed6..e7fb6986 100755 --- a/7zip/Crypto/AES/StdAfx.h +++ b/7zip/Crypto/AES/StdAfx.h @@ -1,8 +1,8 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> +#include "../../../Common/MyWindows.h" -#endif +#endif diff --git a/7zip/Crypto/AES/aesopt.h b/7zip/Crypto/AES/aesopt.h index 040089c6..bcad345f 100755 --- a/7zip/Crypto/AES/aesopt.h +++ b/7zip/Crypto/AES/aesopt.h @@ -164,7 +164,7 @@ // 2003-09-16: Changed by Igor Pavlov. Check it. // #if defined(__GNUC__) || defined(__GNU_LIBRARY__) -#if (defined(__GNUC__) || defined(__GNU_LIBRARY__)) && !defined(WIN32) +#if (defined(__GNUC__) || defined(__GNU_LIBRARY__)) && !defined(_WIN32) # include <endian.h> # include <byteswap.h> @@ -183,7 +183,7 @@ # endif #elif defined(_MSC_VER) # include <stdlib.h> -#elif !defined(WIN32) +#elif !defined(_WIN32) # include <stdlib.h> # if !defined (_ENDIAN_H) # include <sys/param.h> diff --git a/7zip/Crypto/AES/resource.rc b/7zip/Crypto/AES/resource.rc index 57a99b6b..2f243181 100755 --- a/7zip/Crypto/AES/resource.rc +++ b/7zip/Crypto/AES/resource.rc @@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,9,2,0 - PRODUCTVERSION 3,9,2,0 + FILEVERSION 4,16,0,0 + PRODUCTVERSION 4,16,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -84,15 +84,15 @@ BEGIN BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Igor Pavlov\0" - VALUE "FileDescription", "AES Crypto\0" - VALUE "FileVersion", "3, 9, 2, 0\0" + VALUE "FileDescription", "AES Crypto Codec\0" + VALUE "FileVersion", "4, 16, 0, 0\0" VALUE "InternalName", "AES\0" - VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "AES.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "7-Zip\0" - VALUE "ProductVersion", "3, 9, 2, 0\0" + VALUE "ProductVersion", "4, 16, 0, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/7zip/Crypto/Rar20/Rar20Cipher.cpp b/7zip/Crypto/Rar20/Rar20Cipher.cpp index c2423482..322c6ff6 100755 --- a/7zip/Crypto/Rar20/Rar20Cipher.cpp +++ b/7zip/Crypto/Rar20/Rar20Cipher.cpp @@ -10,36 +10,44 @@ namespace NRar20 { static const int kBufferSize = 1 << 17; -CDecoder::CDecoder(): - _buffer(0) +STDMETHODIMP CDecoder::CryptoSetPassword(const Byte *data, UInt32 size) { - _buffer = new BYTE[kBufferSize]; + _coder.SetPassword(data, size); + return S_OK; } -CDecoder::~CDecoder() +STDMETHODIMP CDecoder::Init() { - delete []_buffer; + return S_OK; } -STDMETHODIMP CDecoder::CryptoSetPassword(const BYTE *data, UINT32 size) +STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size) { - _coder.SetPassword(data, size); - return S_OK; + const UInt16 kBlockSize = 16; + if (size > 0 && size < kBlockSize) + return kBlockSize; + UInt32 i; + for (i = 0; i + kBlockSize <= size; i += kBlockSize) + { + _coder.DecryptBlock(data + i); + } + return i; } +/* STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { - UINT64 nowPos = 0; - UINT32 bufferPos = 0; - UINT32 processedSize; + UInt64 nowPos = 0; + UInt32 bufferPos = 0; + UInt32 processedSize; while(true) { - UINT32 size = kBufferSize - bufferPos; + UInt32 size = kBufferSize - bufferPos; RINOK(inStream->Read(_buffer + bufferPos, size, &processedSize)); - UINT32 anEndPos = bufferPos + processedSize; + UInt32 anEndPos = bufferPos + processedSize; for (;bufferPos + 16 <= anEndPos; bufferPos += 16) _coder.DecryptBlock(_buffer + bufferPos); @@ -47,7 +55,7 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, return S_OK; if (outSize != NULL && nowPos + bufferPos > *outSize) - bufferPos = UINT32(*outSize - nowPos); + bufferPos = UInt32(*outSize - nowPos); RINOK(outStream->Write(_buffer, bufferPos, &processedSize)); if (bufferPos != processedSize) @@ -63,5 +71,6 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, bufferPos = i; } } +*/ }} diff --git a/7zip/Crypto/Rar20/Rar20Cipher.h b/7zip/Crypto/Rar20/Rar20Cipher.h index f4cc49d2..a0dee1e0 100755 --- a/7zip/Crypto/Rar20/Rar20Cipher.h +++ b/7zip/Crypto/Rar20/Rar20Cipher.h @@ -14,24 +14,19 @@ namespace NCrypto { namespace NRar20 { class CDecoder: - public ICompressCoder, + public ICompressFilter, public ICryptoSetPassword, public CMyUnknownImp { - BYTE *_buffer; public: CData _coder; - CDecoder(); - ~CDecoder(); - MY_UNKNOWN_IMP1(ICryptoSetPassword) - STDMETHOD(Code)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, UINT64 const *inSize, const UINT64 *outSize, - ICompressProgressInfo *progress); - - STDMETHOD(CryptoSetPassword)(const BYTE *data, UINT32 size); + STDMETHOD(Init)(); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); + + STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); }; diff --git a/7zip/Crypto/Rar20/Rar20Crypto.cpp b/7zip/Crypto/Rar20/Rar20Crypto.cpp index ae95655a..d8be2279 100755 --- a/7zip/Crypto/Rar20/Rar20Crypto.cpp +++ b/7zip/Crypto/Rar20/Rar20Crypto.cpp @@ -3,17 +3,17 @@ #include "StdAfx.h" #include "Rar20Crypto.h" -#include "Common/Crc.h" +#include "../../../Common/CRC.h" -#define rol(x,n) (((x)<<(n)) | ((x)>>(8*sizeof(x)-(n)))) -#define ror(x,n) (((x)>>(n)) | ((x)<<(8*sizeof(x)-(n)))) +#define rol(x,n) (((x) << (n)) | ((x) >> (8 * sizeof(x) - (n)))) +#define ror(x,n) (((x) >> (n)) | ((x) << (8 * sizeof(x) - (n)))) namespace NCrypto { namespace NRar20 { static const int kNumRounds = 32; -static const BYTE InitSubstTable[256]={ +static const Byte InitSubstTable[256] = { 215, 19,149, 35, 73,197,192,205,249, 28, 16,119, 48,221, 2, 42, 232, 1,177,233, 14, 88,219, 25,223,195,244, 90, 87,239,153,137, 255,199,147, 70, 92, 66,246, 13,216, 40, 62, 29,217,230, 86, 6, @@ -32,23 +32,22 @@ static const BYTE InitSubstTable[256]={ 116,184,160, 96,109, 37, 30,106,140,104,150, 5,204,117,112, 84 }; -void CData::UpdateKeys(const BYTE *data) +void CData::UpdateKeys(const Byte *data) { for (int i = 0; i < 16; i += 4) - for (int j = 0; j < 4; j ++) + for (int j = 0; j < 4; j++) Keys[j] ^= CCRC::Table[data[i + j]]; } -static void Swap(BYTE *Ch1, BYTE *Ch2) +static void Swap(Byte *b1, Byte *b2) { - BYTE Ch = *Ch1; - *Ch1 = *Ch2; - *Ch2 = Ch; + Byte b = *b1; + *b1 = *b2; + *b2 = b; } -void CData::SetPassword(const BYTE *password, UINT32 passwordLength) +void CData::SetPassword(const Byte *password, UInt32 passwordLength) { - // SetOldKeys(password); Keys[0] = 0xD3A3B879L; @@ -56,76 +55,56 @@ void CData::SetPassword(const BYTE *password, UINT32 passwordLength) Keys[2] = 0x7515A235L; Keys[3] = 0xA4E7F123L; - BYTE Psw[256]; - memset(Psw, 0, sizeof(Psw)); + Byte psw[256]; + memset(psw, 0, sizeof(psw)); - memmove(Psw, password, passwordLength); + memmove(psw, password, passwordLength); memcpy(SubstTable, InitSubstTable, sizeof(SubstTable)); - for (UINT32 j = 0; j < 256; j++) - for (UINT32 i = 0; i < passwordLength; i += 2) + for (UInt32 j = 0; j < 256; j++) + for (UInt32 i = 0; i < passwordLength; i += 2) { - UINT32 n2 = (BYTE)CCRC::Table[(Psw[i + 1] + j) & 0xFF]; - UINT32 n1 = (BYTE)CCRC::Table[(Psw[i] - j) & 0xFF]; - for (UINT32 k = 1; (n1 & 0xFF) != n2; n1++, k++) + UInt32 n2 = (Byte)CCRC::Table[(psw[i + 1] + j) & 0xFF]; + UInt32 n1 = (Byte)CCRC::Table[(psw[i] - j) & 0xFF]; + for (UInt32 k = 1; (n1 & 0xFF) != n2; n1++, k++) Swap(&SubstTable[n1 & 0xFF], &SubstTable[(n1 + i + k) & 0xFF]); } - for (UINT32 i = 0; i < passwordLength; i+= 16) - EncryptBlock(&Psw[i]); + for (UInt32 i = 0; i < passwordLength; i+= 16) + EncryptBlock(&psw[i]); } -void CData::EncryptBlock(BYTE *Buf) +static inline UInt32 GetUInt32FromMemLE(const Byte *p) { - UINT32 A, B, C, D, T, TA, TB; - - UINT32 *BufPtr; - BufPtr = (UINT32 *)Buf; - - A = BufPtr[0] ^ Keys[0]; - B = BufPtr[1] ^ Keys[1]; - C = BufPtr[2] ^ Keys[2]; - D = BufPtr[3] ^ Keys[3]; - - for(int i = 0; i < kNumRounds; i++) - { - T = ((C + rol(D, 11)) ^ Keys[i & 3]); - TA = A ^ SubstLong(T); - T=((D ^ rol(C, 17)) + Keys[i & 3]); - TB = B ^ SubstLong(T); - A = C; - B = D; - C = TA; - D = TB; - } - - BufPtr[0] = C ^ Keys[0]; - BufPtr[1] = D ^ Keys[1]; - BufPtr[2] = A ^ Keys[2]; - BufPtr[3] = B ^ Keys[3]; + return p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24); +} - UpdateKeys(Buf); +static inline void WriteUInt32ToMemLE(UInt32 v, Byte *p) +{ + p[0] = (Byte)v; + p[1] = (Byte)(v >> 8); + p[2] = (Byte)(v >> 16); + p[3] = (Byte)(v >> 24); } -void CData::DecryptBlock(BYTE *Buf) +void CData::CryptBlock(Byte *buf, bool encrypt) { - BYTE InBuf[16]; - UINT32 A, B, C, D, T, TA, TB; + Byte inBuf[16]; + UInt32 A, B, C, D, T, TA, TB; - UINT32 *BufPtr; - BufPtr = (UINT32 *)Buf; - - A = BufPtr[0] ^ Keys[0]; - B = BufPtr[1] ^ Keys[1]; - C = BufPtr[2] ^ Keys[2]; - D = BufPtr[3] ^ Keys[3]; + A = GetUInt32FromMemLE(buf + 0) ^ Keys[0]; + B = GetUInt32FromMemLE(buf + 4) ^ Keys[1]; + C = GetUInt32FromMemLE(buf + 8) ^ Keys[2]; + D = GetUInt32FromMemLE(buf + 12) ^ Keys[3]; - memcpy(InBuf, Buf, sizeof(InBuf)); + if (!encrypt) + memcpy(inBuf, buf, sizeof(inBuf)); - for(int i = kNumRounds - 1; i >= 0; i--) + for(int i = 0; i < kNumRounds; i++) { - T = ((C + rol(D, 11)) ^ Keys[i & 3]); + UInt32 key = Keys[(encrypt ? i : (kNumRounds - 1 - i)) & 3]; + T = ((C + rol(D, 11)) ^ key); TA = A ^ SubstLong(T); - T = ((D ^ rol(C, 17)) + Keys[i & 3]); + T = ((D ^ rol(C, 17)) + key); TB = B ^ SubstLong(T); A = C; B = D; @@ -133,12 +112,13 @@ void CData::DecryptBlock(BYTE *Buf) D = TB; } - BufPtr[0] = C ^ Keys[0]; - BufPtr[1] = D ^ Keys[1]; - BufPtr[2] = A ^ Keys[2]; - BufPtr[3] = B ^ Keys[3]; + WriteUInt32ToMemLE(C ^ Keys[0], buf + 0); + WriteUInt32ToMemLE(D ^ Keys[1], buf + 4); + WriteUInt32ToMemLE(A ^ Keys[2], buf + 8); + WriteUInt32ToMemLE(B ^ Keys[3], buf + 12); - UpdateKeys(InBuf); + UpdateKeys(encrypt ? buf : inBuf); } + }} diff --git a/7zip/Crypto/Rar20/Rar20Crypto.h b/7zip/Crypto/Rar20/Rar20Crypto.h index 589adae5..071d01f1 100755 --- a/7zip/Crypto/Rar20/Rar20Crypto.h +++ b/7zip/Crypto/Rar20/Rar20Crypto.h @@ -1,30 +1,31 @@ // Crypto/Rar20/Crypto.h -#pragma once - #ifndef __CRYPTO_RAR20_CRYPTO_H #define __CRYPTO_RAR20_CRYPTO_H +#include "../../../Common/Types.h" + namespace NCrypto { namespace NRar20 { class CData { - BYTE SubstTable[256]; - UINT32 Keys[4]; - UINT32 SubstLong(UINT32 t) + Byte SubstTable[256]; + UInt32 Keys[4]; + UInt32 SubstLong(UInt32 t) { - return (UINT32)SubstTable[(int)t & 255] | - ((UINT32)SubstTable[(int)(t >> 8) & 255] << 8) | - ((UINT32)SubstTable[(int)(t >> 16) & 255] << 16) | - ((UINT32)SubstTable[(int)(t >> 24) & 255] << 24); + return (UInt32)SubstTable[(int)t & 255] | + ((UInt32)SubstTable[(int)(t >> 8) & 255] << 8) | + ((UInt32)SubstTable[(int)(t >> 16) & 255] << 16) | + ((UInt32)SubstTable[(int)(t >> 24) & 255] << 24); } - void UpdateKeys(const BYTE *data); + void UpdateKeys(const Byte *data); + void CryptBlock(Byte *buf, bool encrypt); public: - void EncryptBlock(BYTE *Buf); - void DecryptBlock(BYTE *Buf); - void SetPassword(const BYTE *password, UINT32 passwordLength); + void EncryptBlock(Byte *buf) { CryptBlock(buf, true); } + void DecryptBlock(Byte *buf) { CryptBlock(buf, false); } + void SetPassword(const Byte *password, UInt32 passwordLength); }; }} diff --git a/7zip/Crypto/Rar20/StdAfx.h b/7zip/Crypto/Rar20/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/7zip/Crypto/Rar20/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/7zip/Crypto/RarAES/RarAES.cpp b/7zip/Crypto/RarAES/RarAES.cpp index 2a13e13b..827990af 100755 --- a/7zip/Crypto/RarAES/RarAES.cpp +++ b/7zip/Crypto/RarAES/RarAES.cpp @@ -3,11 +3,6 @@ #include "StdAfx.h" -#include "../../Common/StreamObjects.h" -#include "../../Archive/Common/CoderLoader.h" - -#include "Windows/Defs.h" - #include "RarAES.h" #include "sha1.h" @@ -28,16 +23,13 @@ CDecoder::CDecoder(): _salt[i] = 0; } -STDMETHODIMP CDecoder::SetDecoderProperties(ISequentialInStream *inStream) +STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) { bool thereIsSaltPrev = _thereIsSalt; _thereIsSalt = false; - UINT32 processedSize; - BYTE salt[8]; - RINOK(inStream->Read(salt, sizeof(salt), &processedSize)); - if (processedSize == 0) - _thereIsSalt = false; - if (processedSize != sizeof(salt)) + if (size == 0) + return S_OK; + if (size < 8) return E_INVALIDARG; _thereIsSalt = true; bool same = false; @@ -47,7 +39,7 @@ STDMETHODIMP CDecoder::SetDecoderProperties(ISequentialInStream *inStream) if (_thereIsSalt) { for (int i = 0; i < sizeof(_salt); i++) - if (_salt[i] != salt[i]) + if (_salt[i] != data[i]) { same = false; break; @@ -55,19 +47,19 @@ STDMETHODIMP CDecoder::SetDecoderProperties(ISequentialInStream *inStream) } } for (int i = 0; i < sizeof(_salt); i++) - _salt[i] = salt[i]; + _salt[i] = data[i]; if (!_needCalculate && !same) _needCalculate = true; return S_OK; } -STDMETHODIMP CDecoder::CryptoSetPassword(const BYTE *data, UINT32 size) +STDMETHODIMP CDecoder::CryptoSetPassword(const Byte *data, UInt32 size) { bool same = false; if (size == buffer.GetCapacity()) { same = true; - for (UINT32 i = 0; i < size; i++) + for (UInt32 i = 0; i < size; i++) if (data[i] != buffer[i]) { same = false; @@ -81,16 +73,41 @@ STDMETHODIMP CDecoder::CryptoSetPassword(const BYTE *data, UINT32 size) return S_OK; } -STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, UINT64 const *inSize, - const UINT64 *outSize,ICompressProgressInfo *progress) +STDMETHODIMP CDecoder::Init() +{ + Calculate(); + CreateFilter(); + CMyComPtr<ICryptoProperties> cp; + RINOK(_aesFilter.QueryInterface(IID_ICryptoProperties, &cp)); + RINOK(cp->SetKey(aesKey, 16)); + RINOK(cp->SetInitVector(aesInit, 16)); + _aesFilter->Init(); + return S_OK; +} + +HRESULT CDecoder::CreateFilter() +{ + if (_aesFilter) + return S_OK; + TCHAR aesLibPath[MAX_PATH + 64]; + GetCryptoFolderPrefix(aesLibPath); + lstrcat(aesLibPath, TEXT("AES.dll")); + return _aesLib.LoadAndCreateFilter(aesLibPath, CLSID_CCrypto_AES128_Decoder, &_aesFilter); +} + +STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size) +{ + return _aesFilter->Filter(data, size); +} + +void CDecoder::Calculate() { if (_needCalculate) { - const MAXPASSWORD = 128; - const SALT_SIZE = 8; + const int MAXPASSWORD = 128; + const int SALT_SIZE = 8; - BYTE rawPassword[2 * MAXPASSWORD+ SALT_SIZE]; + Byte rawPassword[2 * MAXPASSWORD+ SALT_SIZE]; memcpy(rawPassword, buffer, buffer.GetCapacity()); @@ -110,27 +127,36 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, for (i = 0; i < hashRounds; i++) { hash_process(&c, rawPassword, rawLength); - BYTE pswNum[3]; - pswNum[0] = (BYTE)i; - pswNum[1] = (BYTE)(i >> 8); - pswNum[2] = (BYTE)(i >> 16); + Byte pswNum[3]; + pswNum[0] = (Byte)i; + pswNum[1] = (Byte)(i >> 8); + pswNum[2] = (Byte)(i >> 16); hash_process(&c, pswNum, 3); if (i % (hashRounds / 16) == 0) { hash_context tempc = c; - UINT32 digest[5]; + UInt32 digest[5]; hash_final(&tempc, digest); - aesInit[i / (hashRounds / 16)] = (BYTE)digest[4]; + aesInit[i / (hashRounds / 16)] = (Byte)digest[4]; } } - UINT32 digest[5]; + UInt32 digest[5]; hash_final(&c, digest); for (i = 0; i < 4; i++) for (int j = 0; j < 4; j++) - aesKey[i * 4 + j] = (BYTE)(digest[i] >> (j * 8)); + aesKey[i * 4 + j] = (Byte)(digest[i] >> (j * 8)); } _needCalculate = false; +} + + +/* +STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, UInt64 const *inSize, + const UInt64 *outSize,ICompressProgressInfo *progress) +{ + Calculate(); TCHAR aesLibPath[MAX_PATH + 64]; GetCryptoFolderPrefix(aesLibPath); lstrcat(aesLibPath, TEXT("AES.dll")); @@ -147,11 +173,12 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, keyStreamSpec->Init(aesKey, 16); ISequentialInStream *inStreams[3] = { inStream, ivStream, keyStream }; - UINT64 ivSize = 16; - UINT64 keySize = 16; - const UINT64 *inSizes[3] = { inSize, &ivSize, &ivSize, }; + UInt64 ivSize = 16; + UInt64 keySize = 16; + const UInt64 *inSizes[3] = { inSize, &ivSize, &ivSize, }; return aesDecoder->Code(inStreams, inSizes, 3, &outStream, &outSize, 1, progress); } +*/ }} diff --git a/7zip/Crypto/RarAES/RarAES.h b/7zip/Crypto/RarAES/RarAES.h index 480c3b06..91473269 100755 --- a/7zip/Crypto/RarAES/RarAES.h +++ b/7zip/Crypto/RarAES/RarAES.h @@ -6,6 +6,7 @@ #include "Common/MyCom.h" #include "../../ICoder.h" #include "../../IPassword.h" +#include "../../Archive/Common/CoderLoader.h" #include "Common/Types.h" #include "Common/Buffer.h" @@ -14,31 +15,37 @@ namespace NCrypto { namespace NRar29 { class CDecoder: - public ICompressCoder, - public ICompressSetDecoderProperties, + public ICompressFilter, + public ICompressSetDecoderProperties2, public ICryptoSetPassword, public CMyUnknownImp { - BYTE _salt[8]; + Byte _salt[8]; bool _thereIsSalt; CByteBuffer buffer; - BYTE aesKey[16]; - BYTE aesInit[16]; + Byte aesKey[16]; + Byte aesInit[16]; bool _needCalculate; + + CCoderLibrary _aesLib; + CMyComPtr<ICompressFilter> _aesFilter; + + void Calculate(); + HRESULT CreateFilter(); + public: MY_UNKNOWN_IMP2( ICryptoSetPassword, - ICompressSetDecoderProperties) + ICompressSetDecoderProperties2) - STDMETHOD(Code)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, UINT64 const *inSize, - const UINT64 *outSize,ICompressProgressInfo *progress); + STDMETHOD(Init)(); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); - STDMETHOD(CryptoSetPassword)(const BYTE *aData, UINT32 aSize); + STDMETHOD(CryptoSetPassword)(const Byte *aData, UInt32 aSize); // ICompressSetDecoderProperties - STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream); + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); CDecoder(); }; diff --git a/7zip/Crypto/RarAES/StdAfx.h b/7zip/Crypto/RarAES/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/7zip/Crypto/RarAES/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/7zip/Crypto/RarAES/sha1.cpp b/7zip/Crypto/RarAES/sha1.cpp index a0944177..d6a503cb 100755 --- a/7zip/Crypto/RarAES/sha1.cpp +++ b/7zip/Crypto/RarAES/sha1.cpp @@ -52,12 +52,12 @@ By Steve Reid <steve@edmweb.com> /* Hash a single 512-bit block. This is the core of the algorithm. */ -void SHA1Transform(UINT32 state[5], unsigned char buffer[64]) +void SHA1Transform(UInt32 state[5], unsigned char buffer[64]) { - UINT32 a, b, c, d, e; + UInt32 a, b, c, d, e; typedef union { unsigned char c[64]; - UINT32 l[16]; + UInt32 l[16]; } CHAR64LONG16; CHAR64LONG16* block; #ifdef SHA1HANDSOFF @@ -82,7 +82,7 @@ void SHA1Transform(UINT32 state[5], unsigned char buffer[64]) } pinit=true; } - UINT32 s[5]; + UInt32 s[5]; for (int I=0;I<sizeof(s)/sizeof(s[0]);I++) s[I]=state[I]; @@ -159,7 +159,7 @@ void hash_initial(hash_context* context) void hash_process( hash_context * context, unsigned char * data, unsigned len ) { unsigned int i, j; - UINT32 blen = ((UINT32)len)<<3; + UInt32 blen = ((UInt32)len)<<3; j = (context->count[0] >> 3) & 63; if ((context->count[0] += blen) < blen ) context->count[1]++; @@ -180,9 +180,9 @@ void hash_process( hash_context * context, unsigned char * data, unsigned len ) /* Add padding and return the message digest. */ -void hash_final( hash_context* context, UINT32 digest[5] ) +void hash_final( hash_context* context, UInt32 digest[5] ) { - UINT32 i, j; + UInt32 i, j; unsigned char finalcount[8]; for (i = 0; i < 8; i++) { diff --git a/7zip/Crypto/RarAES/sha1.h b/7zip/Crypto/RarAES/sha1.h index 1177bb5c..3b564a65 100755 --- a/7zip/Crypto/RarAES/sha1.h +++ b/7zip/Crypto/RarAES/sha1.h @@ -4,16 +4,18 @@ #ifndef _RAR_SHA1_ #define _RAR_SHA1_ +#include "../../../Common/Types.h" + #define HW 5 typedef struct { - UINT32 state[5]; - UINT32 count[2]; + UInt32 state[5]; + UInt32 count[2]; unsigned char buffer[64]; } hash_context; void hash_initial( hash_context * c ); void hash_process( hash_context * c, unsigned char * data, unsigned len ); -void hash_final( hash_context * c, UINT32[HW] ); +void hash_final( hash_context * c, UInt32[HW] ); #endif diff --git a/7zip/Crypto/Zip/StdAfx.h b/7zip/Crypto/Zip/StdAfx.h index a32fbed6..e7fb6986 100755 --- a/7zip/Crypto/Zip/StdAfx.h +++ b/7zip/Crypto/Zip/StdAfx.h @@ -1,8 +1,8 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> +#include "../../../Common/MyWindows.h" -#endif +#endif diff --git a/7zip/Crypto/Zip/ZipCipher.cpp b/7zip/Crypto/Zip/ZipCipher.cpp index 50263267..9098f6c9 100755 --- a/7zip/Crypto/Zip/ZipCipher.cpp +++ b/7zip/Crypto/Zip/ZipCipher.cpp @@ -8,111 +8,97 @@ namespace NCrypto { namespace NZip { +/* const int kBufferSize = 1 << 17; CBuffer2::CBuffer2(): _buffer(0) { - _buffer = new BYTE[kBufferSize]; + _buffer = new Byte[kBufferSize]; } CBuffer2::~CBuffer2() { delete []_buffer; } +*/ -STDMETHODIMP CEncoder::CryptoSetPassword(const BYTE *data, UINT32 size) +STDMETHODIMP CEncoder::CryptoSetPassword(const Byte *data, UInt32 size) { _cipher.SetPassword(data, size); return S_OK; } -STDMETHODIMP CEncoder::CryptoSetCRC(UINT32 crc) +STDMETHODIMP CEncoder::CryptoSetCRC(UInt32 crc) { _crc = crc; return S_OK; } -STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, - ICompressProgressInfo *progress) +STDMETHODIMP CEncoder::Init() +{ + return S_OK; +} + +HRESULT CEncoder::WriteHeader(ISequentialOutStream *outStream) { CRandom random; random.Init(::GetTickCount()); - UINT64 nowPos = 0; - BYTE header[kHeaderSize]; + UInt64 nowPos = 0; + Byte header[kHeaderSize]; for (int i = 0; i < kHeaderSize - 2; i++) { - header[i] = BYTE(random.Generate()); + header[i] = Byte(random.Generate()); } - header[kHeaderSize - 1] = BYTE(_crc >> 24); - header[kHeaderSize - 2] = BYTE(_crc >> 16); + header[kHeaderSize - 1] = Byte(_crc >> 24); + header[kHeaderSize - 2] = Byte(_crc >> 16); - UINT32 processedSize; + UInt32 processedSize; _cipher.EncryptHeader(header); RINOK(outStream->Write(header, kHeaderSize, &processedSize)); if (processedSize != kHeaderSize) return E_FAIL; + return S_OK; +} - while(true) - { - if (outSize != NULL && nowPos == *outSize) - return S_OK; - RINOK(inStream->Read(_buffer, kBufferSize, &processedSize)); - if (processedSize == 0) - return S_OK; - for (UINT32 i = 0; i < processedSize; i++) - _buffer[i] = _cipher.EncryptByte(_buffer[i]); - UINT32 size = processedSize; - if (outSize != NULL && nowPos + size > *outSize) - size = UINT32(*outSize - nowPos); - RINOK(outStream->Write(_buffer, size, &processedSize)); - if (size != processedSize) - return E_FAIL; - nowPos += processedSize; - } +STDMETHODIMP_(UInt32) CEncoder::Filter(Byte *data, UInt32 size) +{ + UInt32 i; + for (i = 0; i < size; i++) + data[i] = _cipher.EncryptByte(data[i]); + return i; } -STDMETHODIMP CDecoder::CryptoSetPassword(const BYTE *data, UINT32 size) +STDMETHODIMP CDecoder::CryptoSetPassword(const Byte *data, UInt32 size) { _cipher.SetPassword(data, size); return S_OK; } -STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, - ICompressProgressInfo *progress) +HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream) { - UINT64 nowPos = 0; - - if (inSize != NULL && *inSize == 0) - return S_OK; - - BYTE header[kHeaderSize]; - UINT32 processedSize; + UInt64 nowPos = 0; + Byte header[kHeaderSize]; + UInt32 processedSize; RINOK(inStream->Read(header, kHeaderSize, &processedSize)); if (processedSize != kHeaderSize) return E_FAIL; _cipher.DecryptHeader(header); + return S_OK; +} - while(true) - { - if (outSize != NULL && nowPos == *outSize) - return S_OK; - RINOK(inStream->Read(_buffer, kBufferSize, &processedSize)); - if (processedSize == 0) - return S_OK; - for (UINT32 i = 0; i < processedSize; i++) - _buffer[i] = _cipher.DecryptByte(_buffer[i]); - UINT32 size = processedSize; - if (outSize != NULL && nowPos + size > *outSize) - size = UINT32(*outSize - nowPos); - RINOK(outStream->Write(_buffer, size, &processedSize)); - if (size != processedSize) - return E_FAIL; - nowPos += processedSize; - } +STDMETHODIMP CDecoder::Init() +{ + return S_OK; +} + +STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size) +{ + UInt32 i; + for (i = 0; i < size; i++) + data[i] = _cipher.DecryptByte(data[i]); + return i; } }} diff --git a/7zip/Crypto/Zip/ZipCipher.h b/7zip/Crypto/Zip/ZipCipher.h index 95ba5167..bad1eb0e 100755 --- a/7zip/Crypto/Zip/ZipCipher.h +++ b/7zip/Crypto/Zip/ZipCipher.h @@ -15,56 +15,56 @@ namespace NCrypto { namespace NZip { +/* class CBuffer2 { protected: - BYTE *_buffer; + Byte *_buffer; public: CBuffer2(); ~CBuffer2(); }; - +*/ class CEncoder : - public ICompressCoder, + public ICompressFilter, public ICryptoSetPassword, public ICryptoSetCRC, - public CMyUnknownImp, - public CBuffer2 + public CMyUnknownImp + // public CBuffer2 { CCipher _cipher; - UINT32 _crc; + UInt32 _crc; public: MY_UNKNOWN_IMP2( ICryptoSetPassword, ICryptoSetCRC ) - STDMETHOD(Code)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, - ICompressProgressInfo *progress); + STDMETHOD(Init)(); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); - STDMETHOD(CryptoSetPassword)(const BYTE *data, UINT32 size); - STDMETHOD(CryptoSetCRC)(UINT32 crc); + STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); + STDMETHOD(CryptoSetCRC)(UInt32 crc); + HRESULT WriteHeader(ISequentialOutStream *outStream); }; class CDecoder: - public ICompressCoder, + public ICompressFilter, public ICryptoSetPassword, - public CMyUnknownImp, - public CBuffer2 + public CMyUnknownImp + // public CBuffer2 { CCipher _cipher; public: MY_UNKNOWN_IMP1(ICryptoSetPassword) - STDMETHOD(Code)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, UINT64 const *inSize, - const UINT64 *outSize, - ICompressProgressInfo *progress); + STDMETHOD(Init)(); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); - STDMETHOD(CryptoSetPassword)(const BYTE *data, UINT32 size); + HRESULT ReadHeader(ISequentialInStream *inStream); + STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); }; }} diff --git a/7zip/Crypto/Zip/ZipCrypto.cpp b/7zip/Crypto/Zip/ZipCrypto.cpp index 966cec78..97dcd67b 100755 --- a/7zip/Crypto/Zip/ZipCrypto.cpp +++ b/7zip/Crypto/Zip/ZipCrypto.cpp @@ -3,60 +3,60 @@ #include "StdAfx.h" #include "ZipCipher.h" -#include "Common/Crc.h" +#include "../../../Common/CRC.h" namespace NCrypto { namespace NZip { -inline UINT32 CRC32(UINT32 c, BYTE b) +static inline UInt32 ZipCRC32(UInt32 c, Byte b) { return CCRC::Table[(c ^ b) & 0xFF] ^ (c >> 8); } -void CCipher::UpdateKeys(BYTE b) +void CCipher::UpdateKeys(Byte b) { - Keys[0] = CRC32(Keys[0], b); + Keys[0] = ZipCRC32(Keys[0], b); Keys[1] += Keys[0] & 0xff; Keys[1] = Keys[1] * 134775813L + 1; - Keys[2] = CRC32(Keys[2], Keys[1] >> 24); + Keys[2] = ZipCRC32(Keys[2], Keys[1] >> 24); } -void CCipher::SetPassword(const BYTE *password, UINT32 passwordLength) +void CCipher::SetPassword(const Byte *password, UInt32 passwordLength) { Keys[0] = 305419896L; Keys[1] = 591751049L; Keys[2] = 878082192L; - for (UINT32 i = 0; i < passwordLength; i++) + for (UInt32 i = 0; i < passwordLength; i++) UpdateKeys(password[i]); } -BYTE CCipher::DecryptByteSpec() +Byte CCipher::DecryptByteSpec() { - UINT32 temp = Keys[2] | 2; + UInt32 temp = Keys[2] | 2; return (temp * (temp ^ 1)) >> 8; } -BYTE CCipher::DecryptByte(BYTE encryptedByte) +Byte CCipher::DecryptByte(Byte encryptedByte) { - BYTE c = encryptedByte ^ DecryptByteSpec(); + Byte c = encryptedByte ^ DecryptByteSpec(); UpdateKeys(c); return c; } -BYTE CCipher::EncryptByte(BYTE b) +Byte CCipher::EncryptByte(Byte b) { - BYTE c = b ^ DecryptByteSpec(); + Byte c = b ^ DecryptByteSpec(); UpdateKeys(b); return c; } -void CCipher::DecryptHeader(BYTE *buffer) +void CCipher::DecryptHeader(Byte *buffer) { for (int i = 0; i < 12; i++) buffer[i] = DecryptByte(buffer[i]); } -void CCipher::EncryptHeader(BYTE *buffer) +void CCipher::EncryptHeader(Byte *buffer) { for (int i = 0; i < 12; i++) buffer[i] = EncryptByte(buffer[i]); diff --git a/7zip/Crypto/Zip/ZipCrypto.h b/7zip/Crypto/Zip/ZipCrypto.h index 051a2556..6b4ecaaa 100755 --- a/7zip/Crypto/Zip/ZipCrypto.h +++ b/7zip/Crypto/Zip/ZipCrypto.h @@ -1,7 +1,5 @@ // Crypto/ZipCrypto.h -#pragma once - #ifndef __CRYPTO_ZIP_CRYPTO_H #define __CRYPTO_ZIP_CRYPTO_H @@ -11,15 +9,15 @@ namespace NZip { const int kHeaderSize = 12; class CCipher { - UINT32 Keys[3]; - void UpdateKeys(BYTE b); - BYTE DecryptByteSpec(); + UInt32 Keys[3]; + void UpdateKeys(Byte b); + Byte DecryptByteSpec(); public: - void SetPassword(const BYTE *password, UINT32 passwordLength); - BYTE DecryptByte(BYTE encryptedByte); - BYTE EncryptByte(BYTE b); - void DecryptHeader(BYTE *buffer); - void EncryptHeader(BYTE *buffer); + void SetPassword(const Byte *password, UInt32 passwordLength); + Byte DecryptByte(Byte encryptedByte); + Byte EncryptByte(Byte b); + void DecryptHeader(Byte *buffer); + void EncryptHeader(Byte *buffer); }; diff --git a/7zip/FileManager/App.cpp b/7zip/FileManager/App.cpp index 90e7f6a3..fa5052b8 100755 --- a/7zip/FileManager/App.cpp +++ b/7zip/FileManager/App.cpp @@ -60,10 +60,29 @@ void CApp::SetListSettings() { bool showDots = ReadShowDots(); bool showRealFileIcons = ReadShowRealFileIcons(); + + DWORD extendedStyle = LVS_EX_HEADERDRAGDROP; + if (ReadFullRow()) + extendedStyle |= LVS_EX_FULLROWSELECT; + if (ReadShowGrid()) + extendedStyle |= LVS_EX_GRIDLINES; + + /* + if (ReadSingleClick()) + { + extendedStyle |= LVS_EX_ONECLICKACTIVATE + | LVS_EX_TRACKSELECT; + if (ReadUnderline()) + extendedStyle |= LVS_EX_UNDERLINEHOT; + } + */ + for (int i = 0; i < kNumPanelsMax; i++) { Panels[i]._showDots = showDots; Panels[i]._showRealFileIcons = showRealFileIcons; + Panels[i]._exStyle = extendedStyle; + Panels[i].SetExtendedStyle(); } } @@ -89,7 +108,7 @@ void CApp::CreateOnePanel(int panelIndex, const UString &mainPath) path = mainPath; int id = 1000 + 100 * panelIndex; Panels[panelIndex].Create(_window, _window, - id, 0, path, &m_PanelCallbackImp[panelIndex], &AppState); + id, path, &m_PanelCallbackImp[panelIndex], &AppState); PanelsCreated[panelIndex] = true; } @@ -301,7 +320,7 @@ void CApp::ReloadRebar(HWND hwnd) ReloadToolbars(); } -void CApp::Create(HWND hwnd, const UString &mainPath) +void CApp::Create(HWND hwnd, const UString &mainPath, int xSizes[2]) { ReadToolbar(); ReloadRebar(hwnd); @@ -316,9 +335,21 @@ void CApp::Create(HWND hwnd, const UString &mainPath) UString mainPathSpec = mainPath; if (LastFocusedPanel >= kNumPanelsMax) LastFocusedPanel = 0; + + CListMode listMode; + ReadListMode(listMode); + for (i = 0; i < kNumPanelsMax; i++) + { + Panels[i]._ListViewMode = listMode.Panels[i]; + Panels[i]._xSize = xSizes[i]; + } for (i = 0; i < kNumPanelsMax; i++) if (NumPanels > 1 || i == LastFocusedPanel) + { + if (NumPanels == 1) + Panels[i]._xSize = xSizes[0] + xSizes[1]; CreateOnePanel(i, (i == LastFocusedPanel) ? mainPath : L""); + } Panels[LastFocusedPanel].SetFocusToList(); } @@ -345,6 +376,7 @@ void CApp::SwitchOnOffOnePanel() void CApp::Save() { AppState.Save(); + CListMode listMode; for (int i = 0; i < kNumPanelsMax; i++) { const CPanel &panel = Panels[i]; @@ -354,7 +386,9 @@ void CApp::Save() else path = GetFolderPath(panel._parentFolders[0].ParentFolder); SavePanelPath(i, GetSystemString(path)); + listMode.Panels[i] = panel.GetListViewMode(); } + SaveListMode(listMode); } void CApp::Release() @@ -472,6 +506,10 @@ void CApp::OnCopy(UStringVector &externalNames, bool move, bool copyToSame, int int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex); CPanel &srcPanel = Panels[srcPanelIndex]; CPanel &destPanel = Panels[destPanelIndex]; + + CPanel::CDisableTimerProcessing disableTimerProcessing1(destPanel); + CPanel::CDisableTimerProcessing disableTimerProcessing2(srcPanel); + bool useSrcPanel = true; if (!external) if (NumPanels != 1) @@ -551,7 +589,7 @@ void CApp::OnCopy(UStringVector &externalNames, bool move, bool copyToSame, int { if (fileInfo.IsDirectory()) { - destPath += TEXT('\\'); + destPath += L'\\'; break; } } @@ -559,7 +597,12 @@ void CApp::OnCopy(UStringVector &externalNames, bool move, bool copyToSame, int if (pos < 0) destPath.Empty(); else + { + destPath = destPath.Left(pos + 1); + if (destPath.Length() == 3 && destPath[1] == L':') + break; destPath = destPath.Left(pos); + } } } copyDialog.Value = destPath; @@ -598,8 +641,12 @@ void CApp::OnCopy(UStringVector &externalNames, bool move, bool copyToSame, int LangLoadStringW(IDS_COPYING, 0x03020205); UString progressWindowTitle = LangLoadStringW(IDS_APP_TITLE, 0x03000000); - CPanel::CDisableTimerProcessing disableTimerProcessing1(destPanel); - CPanel::CDisableTimerProcessing disableTimerProcessing2(srcPanel); + CSelectedState srcSelState; + CSelectedState destSelState; + if (copyToSame || move) + srcPanel.SaveSelectedState(srcSelState); + if (!copyToSame) + destPanel.SaveSelectedState(destSelState); HRESULT result; if (useSrcPanel && !external) @@ -607,13 +654,14 @@ void CApp::OnCopy(UStringVector &externalNames, bool move, bool copyToSame, int CThreadExtract extracter; extracter.ExtractCallbackSpec = new CExtractCallbackImp; extracter.ExtractCallback = extracter.ExtractCallbackSpec; - extracter.ExtractCallbackSpec->_parentWindow = _window; + extracter.ExtractCallbackSpec->ParentWindow = _window; extracter.ExtractCallbackSpec->ProgressDialog.MainWindow = _window; extracter.ExtractCallbackSpec->ProgressDialog.MainTitle = progressWindowTitle; extracter.ExtractCallbackSpec->ProgressDialog.MainAddTitle = title + L" "; + extracter.ExtractCallbackSpec->OverwriteMode = NExtract::NOverwriteMode::kAskBefore; - extracter.ExtractCallbackSpec->Init(NExtractionMode::NOverwrite::kAskBefore, false, L""); + extracter.ExtractCallbackSpec->Init(); extracter.Move = move; extracter.FolderOperations = folderOperations; extracter.Indices = indices;; @@ -678,11 +726,11 @@ void CApp::OnCopy(UStringVector &externalNames, bool move, bool copyToSame, int } if (copyToSame || move) { - srcPanel.RefreshListCtrlSaveFocused(); + srcPanel.RefreshListCtrl(srcSelState); } if (!copyToSame) { - destPanel.RefreshListCtrlSaveFocused(); + destPanel.RefreshListCtrl(destSelState); srcPanel.KillSelection(); } disableTimerProcessing1.Restore(); @@ -735,10 +783,10 @@ void CApp::OnSetSubFolder(int srcPanelIndex) destPanel.RefreshListCtrl(); } -int CApp::GetFocusedPanelIndex() +/* +int CApp::GetFocusedPanelIndex() const { return LastFocusedPanel; - /* HWND hwnd = ::GetFocus(); while(true) { @@ -752,8 +800,8 @@ int CApp::GetFocusedPanelIndex() } hwnd = GetParent(hwnd); } - */ } + */ static CSysString g_ToolTipBuffer; diff --git a/7zip/FileManager/App.h b/7zip/FileManager/App.h index 374e8dc5..87acb0bf 100755 --- a/7zip/FileManager/App.h +++ b/7zip/FileManager/App.h @@ -1,7 +1,5 @@ // App.h -#pragma once - #ifndef __APP_H #define __APP_H @@ -74,7 +72,7 @@ public: void OnSetSubFolder(int srcPanelIndex); void CreateOnePanel(int panelIndex, const UString &mainPath); - void Create(HWND hwnd, const UString &mainPath); + void Create(HWND hwnd, const UString &mainPath, int xSizes[2]); void Read(); void Save(); void Release(); @@ -87,7 +85,8 @@ public: void SetFocusToLastItem() { Panels[LastFocusedPanel].SetFocusToLastRememberedItem(); } - int GetFocusedPanelIndex(); + int GetFocusedPanelIndex() const { return LastFocusedPanel; } + /* void SetCurrentIndex() { CurrentPanel = GetFocusedPanelIndex(); } @@ -114,6 +113,8 @@ public: { OnCopy(UStringVector(), true, false, GetFocusedPanelIndex()); } void Delete() { GetFocusedPanel().DeleteItems(); } + void Split(); + void Combine(); void Properties() { GetFocusedPanel().Properties(); } void Comment() @@ -228,10 +229,10 @@ public: void AddToArchive() { GetFocusedPanel().AddToArchive(); } - void ExtractArchive() - { GetFocusedPanel().ExtractArchive(); } - void TestArchive() - { GetFocusedPanel().TestArchive(); } + void ExtractArchives() + { GetFocusedPanel().ExtractArchives(); } + void TestArchives() + { GetFocusedPanel().TestArchives(); } void OnNotify(int ctrlID, LPNMHDR pnmh); }; diff --git a/7zip/FileManager/AppState.h b/7zip/FileManager/AppState.h index 49739f6e..35239266 100755 --- a/7zip/FileManager/AppState.h +++ b/7zip/FileManager/AppState.h @@ -1,7 +1,5 @@ // AppState.h -#pragma once - #ifndef __APPSTATE_H #define __APPSTATE_H diff --git a/7zip/FileManager/ExtractCallback.cpp b/7zip/FileManager/ExtractCallback.cpp index 8fabd7c7..19552da9 100755 --- a/7zip/FileManager/ExtractCallback.cpp +++ b/7zip/FileManager/ExtractCallback.cpp @@ -8,11 +8,13 @@ #include "Windows/FileDir.h" #include "Resource/OverwriteDialog/OverwriteDialog.h" +#ifndef _NO_CRYPTO #include "Resource/PasswordDialog/PasswordDialog.h" +#endif #include "Resource/MessagesDialog/MessagesDialog.h" #include "../UI/Resource/Extract/resource.h" -#include "Common/WildCard.h" +#include "Common/Wildcard.h" #include "Common/StringConvert.h" #include "FormatUtils.h" @@ -25,37 +27,32 @@ using namespace NFind; CExtractCallbackImp::~CExtractCallbackImp() { - if (!_messages.IsEmpty()) + if (!Messages.IsEmpty()) { CMessagesDialog messagesDialog; - messagesDialog._messages = &_messages; - messagesDialog.Create(_parentWindow); + messagesDialog.Messages = &Messages; + messagesDialog.Create(ParentWindow); } } -void CExtractCallbackImp::Init( - NExtractionMode::NOverwrite::EEnum overwriteMode, - bool passwordIsDefined, - const UString &password) +void CExtractCallbackImp::Init() { - _overwriteMode = overwriteMode; - _passwordIsDefined = passwordIsDefined; - _password = password; - _messages.Clear(); + Messages.Clear(); + NumArchiveErrors = 0; } -void CExtractCallbackImp::AddErrorMessage(LPCTSTR message) +void CExtractCallbackImp::AddErrorMessage(LPCWSTR message) { - _messages.Add(message); + Messages.Add(GetSystemString(message)); } -STDMETHODIMP CExtractCallbackImp::SetTotal(UINT64 total) +STDMETHODIMP CExtractCallbackImp::SetTotal(UInt64 total) { ProgressDialog.ProgressSynch.SetProgress(total, 0); return S_OK; } -STDMETHODIMP CExtractCallbackImp::SetCompleted(const UINT64 *completeValue) +STDMETHODIMP CExtractCallbackImp::SetCompleted(const UInt64 *completeValue) { while(true) { @@ -71,9 +68,9 @@ STDMETHODIMP CExtractCallbackImp::SetCompleted(const UINT64 *completeValue) } STDMETHODIMP CExtractCallbackImp::AskOverwrite( - const wchar_t *existName, const FILETIME *existTime, const UINT64 *existSize, - const wchar_t *newName, const FILETIME *newTime, const UINT64 *newSize, - INT32 *answer) + const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize, + const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize, + Int32 *answer) { COverwriteDialog dialog; @@ -98,7 +95,7 @@ STDMETHODIMP CExtractCallbackImp::AskOverwrite( NOverwriteDialog::NResult::EEnum writeAnswer = NOverwriteDialog::Execute(oldFileInfo, newFileInfo); */ - int writeAnswer = dialog.Create(NULL); // _parentWindow doesn't work with 7z + int writeAnswer = dialog.Create(NULL); // ParentWindow doesn't work with 7z switch(writeAnswer) { @@ -128,25 +125,24 @@ STDMETHODIMP CExtractCallbackImp::AskOverwrite( } -STDMETHODIMP CExtractCallbackImp::PrepareOperation(const wchar_t *name, INT32 askExtractMode) +STDMETHODIMP CExtractCallbackImp::PrepareOperation(const wchar_t *name, Int32 askExtractMode, const UInt64 *position) { - _currentFilePath = name; - return S_OK; + return SetCurrentFilePath(name); } STDMETHODIMP CExtractCallbackImp::MessageError(const wchar_t *message) { - AddErrorMessage(GetSystemString(message)); + AddErrorMessage(message); return S_OK; } STDMETHODIMP CExtractCallbackImp::ShowMessage(const wchar_t *message) { - AddErrorMessage(GetSystemString(message)); + AddErrorMessage(message); return S_OK; } -STDMETHODIMP CExtractCallbackImp::SetOperationResult(INT32 operationResult) +STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 operationResult) { switch(operationResult) { @@ -155,7 +151,7 @@ STDMETHODIMP CExtractCallbackImp::SetOperationResult(INT32 operationResult) default: { UINT messageID; - UINT32 langID; + UInt32 langID; switch(operationResult) { case NArchive::NExtract::NOperationResult::kUnSupportedMethod: @@ -173,30 +169,90 @@ STDMETHODIMP CExtractCallbackImp::SetOperationResult(INT32 operationResult) default: return E_FAIL; } + if (_needWriteArchivePath) + { + AddErrorMessage(_currentArchivePath); + _needWriteArchivePath = false; + } AddErrorMessage( - GetSystemString(MyFormatNew(messageID, + MyFormatNew(messageID, #ifdef LANG langID, #endif - _currentFilePath))); + _currentFilePath)); } } return S_OK; } +//////////////////////////////////////// +// IExtractCallbackUI + +HRESULT CExtractCallbackImp::BeforeOpen(const wchar_t *name) +{ + #ifndef _SFX + ProgressDialog.ProgressSynch.SetTitleFileName(name); + #endif + _currentArchivePath = name; + return S_OK; +} + +HRESULT CExtractCallbackImp::SetCurrentFilePath(const wchar_t *path) +{ + _currentFilePath = path; + #ifndef _SFX + ProgressDialog.ProgressSynch.SetCurrentFileName(path); + #endif + return S_OK; +} + +HRESULT CExtractCallbackImp::OpenResult(const wchar_t *name, HRESULT result) +{ + if (result != S_OK) + { + MessageError(name + (UString)L" is not supported archive"); + NumArchiveErrors++; + } + _currentArchivePath = name; + _needWriteArchivePath = true; + return S_OK; +} + +HRESULT CExtractCallbackImp::ThereAreNoFiles() +{ + return S_OK; +} + +HRESULT CExtractCallbackImp::ExtractResult(HRESULT result) +{ + if (result == S_OK) + return result; + NumArchiveErrors++; + if (result == E_ABORT) + return result; + return S_OK; +} + +HRESULT CExtractCallbackImp::SetPassword(const UString &password) +{ + PasswordIsDefined = true; + Password = password; + return S_OK; +} + STDMETHODIMP CExtractCallbackImp::CryptoGetTextPassword(BSTR *password) { - if (!_passwordIsDefined) + if (!PasswordIsDefined) { CPasswordDialog dialog; - if (dialog.Create(_parentWindow) == IDCANCEL) + if (dialog.Create(ParentWindow) == IDCANCEL) return E_ABORT; - _password = GetUnicodeString((LPCTSTR)dialog._password); - _passwordIsDefined = true; + Password = dialog.Password; + PasswordIsDefined = true; } - CMyComBSTR tempName = _password; + CMyComBSTR tempName(Password); *password = tempName.Detach(); return S_OK; @@ -205,11 +261,11 @@ STDMETHODIMP CExtractCallbackImp::CryptoGetTextPassword(BSTR *password) // IExtractCallBack3 STDMETHODIMP CExtractCallbackImp::AskWrite( - const wchar_t *srcPath, INT32 srcIsFolder, - const FILETIME *srcTime, const UINT64 *srcSize, + const wchar_t *srcPath, Int32 srcIsFolder, + const FILETIME *srcTime, const UInt64 *srcSize, const wchar_t *destPath, BSTR *destPathResult, - INT32 *writeAnswer) + Int32 *writeAnswer) { UString destPathResultTemp = destPath; /* @@ -249,13 +305,13 @@ STDMETHODIMP CExtractCallbackImp::AskWrite( return E_FAIL; } - switch(_overwriteMode) + switch(OverwriteMode) { - case NExtractionMode::NOverwrite::kSkipExisting: + case NExtract::NOverwriteMode::kSkipExisting: return S_OK; - case NExtractionMode::NOverwrite::kAskBefore: + case NExtract::NOverwriteMode::kAskBefore: { - INT32 overwiteResult; + Int32 overwiteResult; RINOK(AskOverwrite( destPathSpec, &destFileInfo.LastWriteTime, &destFileInfo.Size, @@ -269,22 +325,22 @@ STDMETHODIMP CExtractCallbackImp::AskWrite( case NOverwriteAnswer::kNo: return S_OK; case NOverwriteAnswer::kNoToAll: - _overwriteMode = NExtractionMode::NOverwrite::kSkipExisting; + OverwriteMode = NExtract::NOverwriteMode::kSkipExisting; return S_OK; case NOverwriteAnswer::kYesToAll: - _overwriteMode = NExtractionMode::NOverwrite::kWithoutPrompt; + OverwriteMode = NExtract::NOverwriteMode::kWithoutPrompt; break; case NOverwriteAnswer::kYes: break; case NOverwriteAnswer::kAutoRename: - _overwriteMode = NExtractionMode::NOverwrite::kAutoRename; + OverwriteMode = NExtract::NOverwriteMode::kAutoRename; break; default: throw 20413; } } } - if (_overwriteMode == NExtractionMode::NOverwrite::kAutoRename) + if (OverwriteMode == NExtract::NOverwriteMode::kAutoRename) { if (!AutoRenamePath(destPathSys)) { diff --git a/7zip/FileManager/ExtractCallback.h b/7zip/FileManager/ExtractCallback.h index 2ac07fa8..d7937354 100755 --- a/7zip/FileManager/ExtractCallback.h +++ b/7zip/FileManager/ExtractCallback.h @@ -1,7 +1,5 @@ // ExtractCallback.h -#pragma once - #ifndef __EXTRACTCALLBACK_H #define __EXTRACTCALLBACK_H @@ -20,14 +18,18 @@ #include "LangUtils.h" #endif +#ifndef _NO_CRYPTO #include "../IPassword.h" +#endif #include "Common/MyCom.h" #include "IFolder.h" class CExtractCallbackImp: - public IFolderArchiveExtractCallback, + public IExtractCallbackUI, public IFolderOperationsExtractCallback, + #ifndef _NO_CRYPTO public ICryptoGetTextPassword, + #endif public CMyUnknownImp { public: @@ -38,59 +40,85 @@ public: ) // IProgress - STDMETHOD(SetTotal)(UINT64 total); - STDMETHOD(SetCompleted)(const UINT64 *completeValue); + STDMETHOD(SetTotal)(UInt64 total); + STDMETHOD(SetCompleted)(const UInt64 *completeValue); // IFolderArchiveExtractCallback STDMETHOD(AskOverwrite)( - const wchar_t *existName, const FILETIME *existTime, const UINT64 *existSize, - const wchar_t *newName, const FILETIME *newTime, const UINT64 *newSize, - INT32 *answer); - STDMETHOD (PrepareOperation)(const wchar_t *name, INT32 askExtractMode); + const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize, + const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize, + Int32 *answer); + STDMETHOD (PrepareOperation)(const wchar_t *name, Int32 askExtractMode, const UInt64 *position); STDMETHOD(MessageError)(const wchar_t *message); - STDMETHOD(SetOperationResult)(INT32 operationResult); + STDMETHOD(SetOperationResult)(Int32 operationResult); + + // IExtractCallbackUI + + HRESULT BeforeOpen(const wchar_t *name); + HRESULT OpenResult(const wchar_t *name, HRESULT result); + HRESULT ThereAreNoFiles(); + HRESULT ExtractResult(HRESULT result); + + #ifndef _NO_CRYPTO + HRESULT SetPassword(const UString &password); + #endif // IFolderOperationsExtractCallback STDMETHOD(AskWrite)( const wchar_t *srcPath, - INT32 srcIsFolder, + Int32 srcIsFolder, const FILETIME *srcTime, - const UINT64 *srcSize, + const UInt64 *srcSize, const wchar_t *destPathRequest, BSTR *destPathResult, - INT32 *writeAnswer); + Int32 *writeAnswer); STDMETHOD(ShowMessage)(const wchar_t *message); + STDMETHOD(SetCurrentFilePath)(const wchar_t *filePath); // ICryptoGetTextPassword + #ifndef _NO_CRYPTO STDMETHOD(CryptoGetTextPassword)(BSTR *password); + #endif private: // CSysString _directoryPath; // CSysString m_DiskFilePath; // bool _extractMode; + UString _currentArchivePath; + bool _needWriteArchivePath; UString _currentFilePath; - NExtractionMode::NOverwrite::EEnum _overwriteMode; - - bool _passwordIsDefined; - UString _password; // void CreateComplexDirectory(const UStringVector &aDirPathParts); - void AddErrorMessage(LPCTSTR message); + void AddErrorMessage(LPCWSTR message); public: CProgressDialog ProgressDialog; - CSysStringVector _messages; - HWND _parentWindow; + CSysStringVector Messages; + HWND ParentWindow; INT_PTR StartProgressDialog(const UString &title) { - return ProgressDialog.Create(title, _parentWindow); + return ProgressDialog.Create(title, ParentWindow); } - + UInt32 NumArchiveErrors; + NExtract::NOverwriteMode::EEnum OverwriteMode; + + #ifndef _NO_CRYPTO + bool PasswordIsDefined; + UString Password; + #endif + + CExtractCallbackImp(): + #ifndef _NO_CRYPTO + PasswordIsDefined(false), + #endif + OverwriteMode(NExtract::NOverwriteMode::kAskBefore), + ParentWindow(0) + {} + ~CExtractCallbackImp(); - void Init(NExtractionMode::NOverwrite::EEnum overwriteMode, - bool passwordIsDefined, const UString &password); + void Init(); }; #endif diff --git a/7zip/FileManager/FM.cpp b/7zip/FileManager/FM.cpp index 5cfeb784..d99c5228 100755 --- a/7zip/FileManager/FM.cpp +++ b/7zip/FileManager/FM.cpp @@ -1,6 +1,6 @@ // FAM.cpp -#include "stdafx.h" +#include "StdAfx.h" #include "resource.h" #include "Panel.h" @@ -30,8 +30,6 @@ using namespace NWindows; HINSTANCE g_hInstance; HWND g_HWND; - - static UString g_MainPath; const int kNumDefaultPanels = 1; @@ -56,7 +54,6 @@ CSysString GetProgramFolderPrefix() } - class CSplitterPos { int _ratio; // 10000 is max @@ -106,8 +103,9 @@ public: }; bool g_CanChangeSplitter = false; -int g_SplitterPos = 0; +UINT32 g_SplitterPos = 0; CSplitterPos g_Splitter; +bool g_PanelsInfoDefined = false; int g_StartCaptureMousePos; int g_StartCaptureSplitterPos; @@ -126,7 +124,9 @@ BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) TCHAR windowClass[MAX_LOADSTRING]; // The window class name lstrcpy(windowClass, TEXT("FM")); - g_hInstance = hInstance; // Store instance handle in our global variable + g_hInstance = hInstance; + + ReloadLang(); // LoadString(hInstance, IDS_CLASS, windowClass, MAX_LOADSTRING); @@ -184,9 +184,8 @@ BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) } UINT32 numPanels, currentPanel; - UINT32 splitterPos; - bool panelsInfoDefined = ReadPanelsInfo(numPanels, currentPanel, splitterPos); - if (panelsInfoDefined) + g_PanelsInfoDefined = ReadPanelsInfo(numPanels, currentPanel, g_SplitterPos); + if (g_PanelsInfoDefined) { if (numPanels < 1 || numPanels > 2) numPanels = kNumDefaultPanels; @@ -207,17 +206,6 @@ BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) return FALSE; g_HWND = hWnd; - if (panelsInfoDefined) - { - g_SplitterPos = splitterPos; - g_Splitter.SetPos(hWnd, splitterPos); - } - else - { - g_Splitter.SetRatio(hWnd, kSplitterRateMax / 2); - g_SplitterPos = g_Splitter.GetPos(); - } - CWindow window(hWnd); WINDOWPLACEMENT placement; @@ -383,10 +371,10 @@ void ExecuteCommand(UINT commandID) g_App.AddToArchive(); break; case kExtractCommand: - g_App.ExtractArchive(); + g_App.ExtractArchives(); break; case kTestCommand: - g_App.TestArchive(); + g_App.TestArchives(); break; } } @@ -455,7 +443,23 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) // HCURSOR cursor = ::LoadCursor(0, IDC_SIZEWE); // ::SetCursor(cursor); - g_App.Create(hWnd, g_MainPath); + if (g_PanelsInfoDefined) + g_Splitter.SetPos(hWnd, g_SplitterPos); + else + { + g_Splitter.SetRatio(hWnd, kSplitterRateMax / 2); + g_SplitterPos = g_Splitter.GetPos(); + } + + RECT rect; + ::GetClientRect(hWnd, &rect); + int xSize = rect.right; + int xSizes[2]; + xSizes[0] = g_Splitter.GetPos(); + xSizes[1] = xSize - kSplitterWidth - xSizes[0]; + if (xSizes[1] < 0) + xSizes[1] = 0; + g_App.Create(hWnd, g_MainPath, xSizes); // g_SplitterPos = 0; DragAcceptFiles(hWnd, TRUE); diff --git a/7zip/FileManager/FM.dsp b/7zip/FileManager/FM.dsp index 2cd69412..c155536f 100755 --- a/7zip/FileManager/FM.dsp +++ b/7zip/FileManager/FM.dsp @@ -369,6 +369,10 @@ SOURCE=.\PanelSelect.cpp SOURCE=.\PanelSort.cpp # End Source File +# Begin Source File + +SOURCE=.\PanelSplitFile.cpp +# End Source File # End Group # Begin Group "Dialog" @@ -514,6 +518,27 @@ SOURCE=.\Resource\BenchmarkDialog\resource.rc # PROP Exclude_From_Build 1 # End Source File # End Group +# Begin Group "Split" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\Resource\SplitDialog\resource.h +# End Source File +# Begin Source File + +SOURCE=.\Resource\SplitDialog\resource.rc +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\Resource\SplitDialog\SplitDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\Resource\SplitDialog\SplitDialog.h +# End Source File +# End Group # Begin Source File SOURCE=.\Resource\ComboDialog\ComboDialog.cpp @@ -763,14 +788,6 @@ SOURCE=..\..\Windows\Handle.h # End Source File # Begin Source File -SOURCE=..\..\Windows\ItemIDListUtils.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\Windows\ItemIDListUtils.h -# End Source File -# Begin Source File - SOURCE=..\..\Windows\Menu.h # End Source File # Begin Source File @@ -835,14 +852,6 @@ SOURCE=..\..\Windows\Synchronization.h # End Source File # Begin Source File -SOURCE=..\..\Windows\System.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\Windows\System.h -# End Source File -# Begin Source File - SOURCE=..\..\Windows\Thread.h # End Source File # Begin Source File @@ -867,6 +876,14 @@ SOURCE=..\..\Windows\Window.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\Alloc.h +# End Source File +# Begin Source File + SOURCE=..\..\Common\Buffer.h # End Source File # Begin Source File @@ -1149,6 +1166,14 @@ SOURCE=.\resource.h # End Source File # Begin Source File +SOURCE=.\SplitUtils.cpp +# End Source File +# Begin Source File + +SOURCE=.\SplitUtils.h +# End Source File +# Begin Source File + SOURCE=.\StringUtils.cpp # End Source File # Begin Source File diff --git a/7zip/FileManager/FSDrives.h b/7zip/FileManager/FSDrives.h index 45c4ff88..8a835f29 100755 --- a/7zip/FileManager/FSDrives.h +++ b/7zip/FileManager/FSDrives.h @@ -1,7 +1,5 @@ // FSDrives.h -#pragma once - #ifndef __FSDRIVES_H #define __FSDRIVES_H diff --git a/7zip/FileManager/FSFolder.cpp b/7zip/FileManager/FSFolder.cpp index c0c20745..81963552 100755 --- a/7zip/FileManager/FSFolder.cpp +++ b/7zip/FileManager/FSFolder.cpp @@ -119,20 +119,34 @@ STDMETHODIMP CFSFolder::LoadItems() return S_OK; } +static const wchar_t *kDescriptionFileName = L"descript.ion"; + bool CFSFolder::LoadComments() { if (_commentsAreLoaded) return true; _comments.Clear(); _commentsAreLoaded = true; - CStdInStream file; - if (!file.Open(GetSystemString(_path + L"descript.ion", _fileCodePage))) + NIO::CInFile file; + if (!file.Open(_path + kDescriptionFileName)) + return false; + UInt64 length; + if (!file.GetLength(length)) + return false; + if (length >= 0xFFFFFFF) + return false; + AString s; + char *p = s.GetBuffer((size_t)length + 1); + UINT32 processedSize; + file.Read(p, length, processedSize); + p[length] = 0; + s.ReleaseBuffer(); + s.Replace("\r\n", "\n"); + if (processedSize != length) return false; - AString string; - file.ReadToString(string); file.Close(); UString unicodeString; - if (!ConvertUTF8ToUnicode(string, unicodeString)) + if (!ConvertUTF8ToUnicode(s, unicodeString)) return false; return _comments.ReadFromString(unicodeString); } @@ -147,19 +161,21 @@ static bool IsAscii(const UString &testString) bool CFSFolder::SaveComments() { - CStdOutStream file; - if (!file.Open(GetSystemString(_path + L"descript.ion", _fileCodePage))) + NIO::COutFile file; + if (!file.Create(_path + kDescriptionFileName, true)) return false; UString unicodeString; _comments.SaveToString(unicodeString); AString utfString; ConvertUnicodeToUTF8(unicodeString, utfString); + UINT32 processedSize; if (!IsAscii(unicodeString)) { - file << char(0xEF) << char(0xBB) << char(0xBF) << char('\n'); + Byte bom [] = { 0xEF, 0xBB, 0xBF, 0x0D, 0x0A }; + file.Write(bom , sizeof(bom), processedSize); } - file << utfString; - file.Close(); + utfString.Replace("\n", "\r\n"); + file.Write(utfString, utfString.Length(), processedSize); _commentsAreLoaded = false; return true; } @@ -457,7 +473,7 @@ STDMETHODIMP CFSFolder::CreateFile(const wchar_t *name, IProgress *progress) UString processedName; RINOK(GetComplexName(name, processedName)); NIO::COutFile outFile; - if (!outFile.Open(processedName)) + if (!outFile.Create(processedName, false)) return ::GetLastError(); return S_OK; } diff --git a/7zip/FileManager/FSFolder.h b/7zip/FileManager/FSFolder.h index d1262cbd..08a987dc 100755 --- a/7zip/FileManager/FSFolder.h +++ b/7zip/FileManager/FSFolder.h @@ -1,7 +1,5 @@ // FSFolder.h -#pragma once - #ifndef __FSFOLDER_H #define __FSFOLDER_H diff --git a/7zip/FileManager/FSFolderCopy.cpp b/7zip/FileManager/FSFolderCopy.cpp index 776567fd..8d7c8dd7 100755 --- a/7zip/FileManager/FSFolderCopy.cpp +++ b/7zip/FileManager/FSFolderCopy.cpp @@ -191,6 +191,7 @@ static HRESULT MyCopyFile( if (IntToBool(writeAskResult)) { UString destPathNew = UString(destPathResult); + RINOK(callback->SetCurrentFilePath(srcPath)); if (!::MyCopyFile(srcPath, destPathNew, callback, completedSize)) { UString message = GetUnicodeString(NError::MyFormatMessage(GetLastError())) + @@ -350,6 +351,7 @@ HRESULT MyMoveFile( if (IntToBool(writeAskResult)) { UString destPathNew = UString(destPathResult); + RINOK(callback->SetCurrentFilePath(srcPath)); if (!MyMoveFile(srcPath, destPathNew, callback, completedSize)) { UString message = UString(L"can not move to file ") + diff --git a/7zip/FileManager/FileFolderPluginOpen.cpp b/7zip/FileManager/FileFolderPluginOpen.cpp index 70754e83..ffb6788e 100755 --- a/7zip/FileManager/FileFolderPluginOpen.cpp +++ b/7zip/FileManager/FileFolderPluginOpen.cpp @@ -86,8 +86,8 @@ HRESULT OpenFileFolderPlugin( COpenArchiveCallback *openCallbackSpec = new COpenArchiveCallback; CMyComPtr<IProgress> openCallback = openCallbackSpec; - openCallbackSpec->_passwordIsDefined = false; - openCallbackSpec->_parentWindow = parentWindow; + openCallbackSpec->PasswordIsDefined = false; + openCallbackSpec->ParentWindow = parentWindow; openCallbackSpec->LoadFileInfo(dirPrefix, fileName); result = folderManager->OpenFolderFile(path, &folder, openCallback); diff --git a/7zip/FileManager/FileFolderPluginOpen.h b/7zip/FileManager/FileFolderPluginOpen.h index 3614484d..67d27046 100755 --- a/7zip/FileManager/FileFolderPluginOpen.h +++ b/7zip/FileManager/FileFolderPluginOpen.h @@ -1,7 +1,5 @@ // FileFolderPluginOpen.h -#pragma once - #ifndef __FILEFOLDERPLUGINOPEN_H #define __FILEFOLDERPLUGINOPEN_H diff --git a/7zip/FileManager/FilePlugins.h b/7zip/FileManager/FilePlugins.h index 6abe0537..805cac2a 100755 --- a/7zip/FileManager/FilePlugins.h +++ b/7zip/FileManager/FilePlugins.h @@ -1,7 +1,5 @@ // FilePlugins.h -#pragma once - #ifndef __FILEPLUGINS_H #define __FILEPLUGINS_H diff --git a/7zip/FileManager/FormatUtils.cpp b/7zip/FileManager/FormatUtils.cpp index 5515cd79..e0427df9 100755 --- a/7zip/FileManager/FormatUtils.cpp +++ b/7zip/FileManager/FormatUtils.cpp @@ -41,14 +41,14 @@ CSysString MyFormat(UINT32 resourceID, CSysString NumberToString(UINT64 number) { TCHAR temp[32]; - ConvertUINT64ToString(number, temp); + ConvertUInt64ToString(number, temp); return temp; } UString NumberToStringW(UINT64 number) { wchar_t numberString[32]; - ConvertUINT64ToString(number, numberString); + ConvertUInt64ToString(number, numberString); return numberString; } diff --git a/7zip/FileManager/FormatUtils.h b/7zip/FileManager/FormatUtils.h index 2d2333db..7902aeea 100755 --- a/7zip/FileManager/FormatUtils.h +++ b/7zip/FileManager/FormatUtils.h @@ -1,7 +1,5 @@ // FormatUtils.h -#pragma once - #ifndef __FORMATUTILS_H #define __FORMATUTILS_H diff --git a/7zip/FileManager/HelpUtils.h b/7zip/FileManager/HelpUtils.h index 7210bd20..b993f09b 100755 --- a/7zip/FileManager/HelpUtils.h +++ b/7zip/FileManager/HelpUtils.h @@ -3,10 +3,8 @@ #ifndef __HELPUTILS_H #define __HELPUTILS_H -#pragma once - #include "Common/String.h" void ShowHelpWindow(HWND hwnd, LPCWSTR topicFile); -#endif
\ No newline at end of file +#endif diff --git a/7zip/FileManager/IFolder.h b/7zip/FileManager/IFolder.h index d2f6d5c7..10734f7b 100755 --- a/7zip/FileManager/IFolder.h +++ b/7zip/FileManager/IFolder.h @@ -1,7 +1,5 @@ // FolderInterface.h -#pragma once - #ifndef __FOLDERINTERFACE_H #define __FOLDERINTERFACE_H @@ -106,6 +104,7 @@ public: BSTR *destPathResult, INT32 *writeAnswer) = 0; STDMETHOD(ShowMessage)(const wchar_t *message) = 0; + STDMETHOD(SetCurrentFilePath)(const wchar_t *filePath) = 0; }; /* diff --git a/7zip/FileManager/LangUtils.cpp b/7zip/FileManager/LangUtils.cpp index c12bbf79..a5fcb635 100755 --- a/7zip/FileManager/LangUtils.cpp +++ b/7zip/FileManager/LangUtils.cpp @@ -5,28 +5,54 @@ #include "LangUtils.h" #include "Common/StringConvert.h" #include "Windows/ResourceString.h" +#include "Windows/Synchronization.h" #include "Windows/Window.h" #include "RegistryUtils.h" +#include "ProgramLocation.h" -CLang g_Lang; -CSysString g_LangPath; +using namespace NWindows; + +static CLang g_Lang; +CSysString g_LangID; void ReloadLang() { - ReadRegLang(g_LangPath); + ReadRegLang(g_LangID); g_Lang.Clear(); - if (!g_LangPath.IsEmpty()) - g_Lang.Open(g_LangPath); + if (!g_LangID.IsEmpty()) + { + CSysString langPath = g_LangID; + if (langPath.Find('\\') < 0) + { + if (langPath.Find('.') < 0) + langPath += TEXT(".txt"); + UString folderPath; + if (GetProgramFolderPath(folderPath)) + langPath = GetSystemString(folderPath) + CSysString(TEXT("Lang\\")) + langPath; + } + g_Lang.Open(langPath); + } } +static bool g_Loaded = false; +static NSynchronization::CCriticalSection g_CriticalSection; + +void LoadLangOneTime() +{ + NSynchronization::CCriticalSectionLock lock(g_CriticalSection); + if (g_Loaded) + return; + g_Loaded = true; + ReloadLang(); +} + +/* class CLangLoader { public: - CLangLoader() - { - ReloadLang(); - } + CLangLoader() { ReloadLang(); } } g_LangLoader; +*/ void LangSetDlgItemsText(HWND dialogWindow, CIDLangPair *idLangPairs, int numItems) { @@ -42,14 +68,14 @@ void LangSetDlgItemsText(HWND dialogWindow, CIDLangPair *idLangPairs, int numIte } } -void LangSetWindowText(HWND window, UINT32 langID) +void LangSetWindowText(HWND window, UInt32 langID) { UString message; if (g_Lang.GetMessage(langID, message)) SetWindowText(window, GetSystemString(message)); } -UString LangLoadString(UINT32 langID) +UString LangLoadString(UInt32 langID) { UString message; if (g_Lang.GetMessage(langID, message)) @@ -57,7 +83,7 @@ UString LangLoadString(UINT32 langID) return UString(); } -CSysString LangLoadString(UINT resourceID, UINT32 langID) +CSysString LangLoadString(UINT resourceID, UInt32 langID) { UString message; if (g_Lang.GetMessage(langID, message)) @@ -65,7 +91,7 @@ CSysString LangLoadString(UINT resourceID, UINT32 langID) return NWindows::MyLoadString(resourceID); } -UString LangLoadStringW(UINT resourceID, UINT32 langID) +UString LangLoadStringW(UINT resourceID, UInt32 langID) { UString message; if (g_Lang.GetMessage(langID, message)) diff --git a/7zip/FileManager/LangUtils.h b/7zip/FileManager/LangUtils.h index 546fabd1..713b817c 100755 --- a/7zip/FileManager/LangUtils.h +++ b/7zip/FileManager/LangUtils.h @@ -1,32 +1,27 @@ // LangUtils.h -#pragma once - #ifndef __LANGUTILS_H #define __LANGUTILS_H #include "Common/Lang.h" -// extern CLang g_Lang; -extern CSysString g_LangPath; +extern CSysString g_LangID; struct CIDLangPair { int ControlID; - UINT32 LangID; + UInt32 LangID; }; void ReloadLang(); +void LoadLangOneTime(); void LangSetDlgItemsText(HWND dialogWindow, CIDLangPair *idLangPairs, int numItems); -void LangSetWindowText(HWND window, UINT32 langID); +void LangSetWindowText(HWND window, UInt32 langID); -UString LangLoadString(UINT32 langID); -CSysString LangLoadString(UINT resourceID, UINT32 langID); -UString LangLoadStringW(UINT resourceID, UINT32 langID); +UString LangLoadString(UInt32 langID); +CSysString LangLoadString(UINT resourceID, UInt32 langID); +UString LangLoadStringW(UINT resourceID, UInt32 langID); #endif - - - diff --git a/7zip/FileManager/MyLoadMenu.cpp b/7zip/FileManager/MyLoadMenu.cpp index cc906161..51b8fa56 100755 --- a/7zip/FileManager/MyLoadMenu.cpp +++ b/7zip/FileManager/MyLoadMenu.cpp @@ -77,6 +77,8 @@ static CIDLangPair kIDLangPairs[] = { IDM_DELETE, 0x03000233 }, { IDM_FILE_PROPERTIES, 0x03000240 }, { IDM_FILE_COMMENT, 0x03000241 }, + { IDM_FILE_SPLIT, 0x03000270 }, + { IDM_FILE_COMBINE, 0x03000271 }, { IDM_CREATE_FOLDER, 0x03000250 }, { IDM_CREATE_FILE, 0x03000251 }, { IDCLOSE, 0x03000260 }, @@ -189,6 +191,56 @@ void MyChangeMenu(HMENU menuLoc, int baseIndex = -1) } */ +/* +static bool g_IsNew_fMask = true; + +class CInit_fMask +{ +public: + CInit_fMask() + { + g_IsNew_fMask = false; + OSVERSIONINFO vi; + vi.dwOSVersionInfoSize = sizeof(vi); + if (::GetVersionEx(&vi)) + { + g_IsNew_fMask = (vi.dwMajorVersion > 4 || + (vi.dwMajorVersion == 4 && vi.dwMinorVersion > 0)); + } + g_IsNew_fMask = false; + } +} g_Init_fMask; + +// it's hack for supporting Windows NT +// constants are from WinUser.h + +#if(WINVER < 0x0500) +#define MIIM_STRING 0x00000040 +#define MIIM_BITMAP 0x00000080 +#define MIIM_FTYPE 0x00000100 +#endif + +static UINT Get_fMaskForString() +{ + return g_IsNew_fMask ? MIIM_STRING : MIIM_TYPE; +} + +static UINT Get_fMaskForFTypeAndString() +{ + return g_IsNew_fMask ? (MIIM_STRING | MIIM_FTYPE) : MIIM_TYPE; +} +*/ + +static UINT Get_fMaskForString() +{ + return MIIM_TYPE; +} + +static UINT Get_fMaskForFTypeAndString() +{ + return MIIM_TYPE; +} + static void MyChangeMenu(HMENU menuLoc, int level, int menuIndex) { CMenu menu; @@ -198,7 +250,7 @@ static void MyChangeMenu(HMENU menuLoc, int level, int menuIndex) MENUITEMINFO menuInfo; ZeroMemory(&menuInfo, sizeof(menuInfo)); menuInfo.cbSize = sizeof(menuInfo); - menuInfo.fMask = MIIM_STRING | MIIM_SUBMENU | MIIM_ID; + menuInfo.fMask = Get_fMaskForString() | MIIM_SUBMENU | MIIM_ID; menuInfo.fType = MFT_STRING; const int kBufferSize = 1024; TCHAR buffer[kBufferSize + 1]; @@ -250,9 +302,9 @@ static void MyChangeMenu(HMENU menuLoc, int level, int menuIndex) newString += shorcutString.Mid(tabPos); } menuInfo.dwTypeData = (LPTSTR)(LPCTSTR)newString; - menuInfo.fMask = MIIM_STRING; + menuInfo.fMask = Get_fMaskForString(); + menuInfo.fType = MFT_STRING; menu.SetItemInfo(i, true, &menuInfo); - // HMENU subMenu = menu.GetSubMenu(i); } } } @@ -278,7 +330,7 @@ void MyLoadMenu(HWND hWnd) HMENU baseMenu = ::LoadMenu(g_hInstance, MAKEINTRESOURCE(IDM_MENU)); ::SetMenu(hWnd, baseMenu); ::DestroyMenu(oldMenu); - if (!g_LangPath.IsEmpty()) + if (!g_LangID.IsEmpty()) { HMENU menuOld = ::GetMenu(hWnd); MyChangeMenu(menuOld, 0, 0); @@ -304,7 +356,7 @@ static void CopyMenu(HMENU srcMenuSpec, HMENU destMenuSpec) MENUITEMINFO menuInfo; ZeroMemory(&menuInfo, sizeof(menuInfo)); menuInfo.cbSize = sizeof(menuInfo); - menuInfo.fMask = MIIM_STATE | MIIM_ID | MIIM_FTYPE | MIIM_STRING; + menuInfo.fMask = MIIM_STATE | MIIM_ID | Get_fMaskForFTypeAndString(); menuInfo.fType = MFT_STRING; const int kBufferSize = 1024; TCHAR buffer[kBufferSize + 1]; @@ -464,7 +516,7 @@ void LoadFileMenu(HMENU hMenu, int startPos, bool forFileMode, menuInfo.dwTypeData = (LPTSTR)(LPCTSTR)menuString; */ - menuInfo.fMask = MIIM_STATE | MIIM_ID | MIIM_FTYPE | MIIM_STRING; + menuInfo.fMask = MIIM_STATE | MIIM_ID | Get_fMaskForFTypeAndString(); menuInfo.fType = MFT_STRING; const int kBufferSize = 1024; TCHAR buffer[kBufferSize + 1]; @@ -476,9 +528,9 @@ void LoadFileMenu(HMENU hMenu, int startPos, bool forFileMode, if (!programMenu) if (menuInfo.wID == IDCLOSE) continue; + /* bool createItem = (menuInfo.wID == IDM_CREATE_FOLDER || menuInfo.wID == IDM_CREATE_FILE); - /* if (forFileMode) { if (createItem) @@ -550,6 +602,12 @@ bool ExecuteFileCommand(int id) case IDM_DELETE: g_App.Delete(); break; + case IDM_FILE_SPLIT: + g_App.Split(); + break; + case IDM_FILE_COMBINE: + g_App.Combine(); + break; case IDM_FILE_PROPERTIES: g_App.Properties(); break; diff --git a/7zip/FileManager/MyLoadMenu.h b/7zip/FileManager/MyLoadMenu.h index 869cfd11..490dc6d8 100755 --- a/7zip/FileManager/MyLoadMenu.h +++ b/7zip/FileManager/MyLoadMenu.h @@ -1,7 +1,5 @@ // MyLoadMenu.h -#pragma once - #ifndef __MYLOADMENU_H #define __MYLOADMENU_H @@ -16,4 +14,3 @@ void LoadFileMenu(HMENU hMenu, int startPos, bool forFileMode, bool programMenu) bool ExecuteFileCommand(int id); #endif - diff --git a/7zip/FileManager/NetFolder.h b/7zip/FileManager/NetFolder.h index 4671f516..0aedb5b8 100755 --- a/7zip/FileManager/NetFolder.h +++ b/7zip/FileManager/NetFolder.h @@ -1,7 +1,5 @@ // NetFolder.h -#pragma once - #ifndef __NETFOLDER_H #define __NETFOLDER_H diff --git a/7zip/FileManager/OpenCallback.cpp b/7zip/FileManager/OpenCallback.cpp index 60003cfc..f12b9d04 100755 --- a/7zip/FileManager/OpenCallback.cpp +++ b/7zip/FileManager/OpenCallback.cpp @@ -32,6 +32,17 @@ STDMETHODIMP COpenArchiveCallback::SetCompleted(const UINT64 *completed) STDMETHODIMP COpenArchiveCallback::GetProperty(PROPID propID, PROPVARIANT *value) { NWindows::NCOM::CPropVariant propVariant; + if (_subArchiveMode) + { + switch(propID) + { + case kpidName: + propVariant = _subArchiveName; + break; + } + propVariant.Detach(value); + return S_OK; + } switch(propID) { case kpidName: @@ -64,6 +75,9 @@ STDMETHODIMP COpenArchiveCallback::GetStream(const wchar_t *name, IInStream **inStream) { *inStream = NULL; + if (_subArchiveMode) + return S_FALSE; + NWindows::NFile::NFind::CFileInfoW fileInfo; UString fullPath = _folderPrefix + name; @@ -82,18 +96,17 @@ STDMETHODIMP COpenArchiveCallback::GetStream(const wchar_t *name, STDMETHODIMP COpenArchiveCallback::CryptoGetTextPassword(BSTR *password) { - if (!_passwordIsDefined) + if (!PasswordIsDefined) { CPasswordDialog dialog; - if (dialog.Create(_parentWindow) == IDCANCEL) + if (dialog.Create(ParentWindow) == IDCANCEL) return E_ABORT; - _password = GetUnicodeString((LPCTSTR)dialog._password); - _passwordIsDefined = true; + Password = dialog.Password; + PasswordIsDefined = true; } - CMyComBSTR tempName = _password; + CMyComBSTR tempName(Password); *password = tempName.Detach(); - return S_OK; } diff --git a/7zip/FileManager/OpenCallback.h b/7zip/FileManager/OpenCallback.h index 37effc57..9e1fbc8f 100755 --- a/7zip/FileManager/OpenCallback.h +++ b/7zip/FileManager/OpenCallback.h @@ -1,7 +1,5 @@ // OpenCallback.h -#pragma once - #ifndef __OPENCALLBACK_H #define __OPENCALLBACK_H @@ -16,6 +14,7 @@ class COpenArchiveCallback: public IArchiveOpenCallback, public IArchiveOpenVolumeCallback, + public IArchiveOpenSetSubArchiveName, public IProgress, public ICryptoGetTextPassword, public CMyUnknownImp @@ -23,14 +22,18 @@ class COpenArchiveCallback: UString _folderPrefix; NWindows::NFile::NFind::CFileInfoW _fileInfo; public: - bool _passwordIsDefined; - UString _password; - HWND _parentWindow; + bool PasswordIsDefined; + UString Password; + HWND ParentWindow; + + bool _subArchiveMode; + UString _subArchiveName; public: - MY_UNKNOWN_IMP4( + MY_UNKNOWN_IMP5( IArchiveOpenCallback, IArchiveOpenVolumeCallback, + IArchiveOpenSetSubArchiveName, IProgress, ICryptoGetTextPassword) @@ -49,10 +52,24 @@ public: // ICryptoGetTextPassword STDMETHOD(CryptoGetTextPassword)(BSTR *password); + STDMETHOD(SetSubArchiveName(const wchar_t *name)) + { + _subArchiveMode = true; + _subArchiveName = name; + return S_OK; + } + + COpenArchiveCallback() + { + _subArchiveMode = false; + } + /* void Init() { - _passwordIsDefined = false; + PasswordIsDefined = false; + _subArchiveMode = false; } + */ void LoadFileInfo(const UString &folderPrefix, const UString &fileName) { _folderPrefix = folderPrefix; diff --git a/7zip/FileManager/Panel.cpp b/7zip/FileManager/Panel.cpp index 7268db40..3b65bc87 100755 --- a/7zip/FileManager/Panel.cpp +++ b/7zip/FileManager/Panel.cpp @@ -29,11 +29,11 @@ static const UINT kTimerElapse = 1000; static LPCWSTR kSelectOneFile = L"Select one file"; static LPCWSTR kSelectFiles = L"Select files"; -// static const int kCreateFolderID = 101; +static DWORD kStyles[4] = { LVS_ICON, LVS_SMALLICON, LVS_LIST, LVS_REPORT }; +// static const int kCreateFolderID = 101; // static const UINT kFileChangeNotifyMessage = WM_APP; - extern HINSTANCE g_hInstance; extern DWORD g_ComCtl32Version; @@ -53,7 +53,7 @@ CPanel::~CPanel() static LPCTSTR kClassName = TEXT("7-Zip::Panel"); -LRESULT CPanel::Create(HWND mainWindow, HWND parentWindow, UINT id, int xPos, +LRESULT CPanel::Create(HWND mainWindow, HWND parentWindow, UINT id, const UString ¤tFolderPrefix, CPanelCallback *panelCallback, CAppState *appState) { _mainWindow = mainWindow; @@ -66,12 +66,17 @@ LRESULT CPanel::Create(HWND mainWindow, HWND parentWindow, UINT id, int xPos, _baseID = id; _comboBoxID = _baseID + 3; _statusBarID = _comboBoxID + 1; - _ListViewMode = 0; - - BindToPath(currentFolderPrefix); + + UString cfp = currentFolderPrefix; + + if (!currentFolderPrefix.IsEmpty()) + if (currentFolderPrefix[0] == L'.') + if (!NFile::NDirectory::MyGetFullPathName(currentFolderPrefix, cfp)) + cfp = currentFolderPrefix; + BindToPath(cfp); if (!CreateEx(0, kClassName, 0, WS_CHILD | WS_VISIBLE, - xPos, 0, 116, 260, + 0, 0, _xSize, 260, parentWindow, (HMENU)id, g_hInstance)) return E_FAIL; return S_OK; @@ -287,9 +292,17 @@ bool CPanel::OnCreate(CREATESTRUCT *createStruct) style |= LVS_SHAREIMAGELISTS; // style |= LVS_AUTOARRANGE; - style |= WS_CLIPCHILDREN; + style |= WS_CLIPCHILDREN; style |= WS_CLIPSIBLINGS; - style |= WS_TABSTOP | LVS_REPORT | LVS_EDITLABELS | LVS_SINGLESEL; + + const UINT32 kNumListModes = sizeof(kStyles) / sizeof(kStyles[0]); + if (_ListViewMode >= kNumListModes) + _ListViewMode = kNumListModes - 1; + + style |= kStyles[_ListViewMode] + | WS_TABSTOP + | LVS_EDITLABELS + | LVS_SINGLESEL; /* if (_virtualMode) @@ -302,7 +315,7 @@ bool CPanel::OnCreate(CREATESTRUCT *createStruct) if (!_listView.CreateEx(exStyle, style, 0, 0, 116, 260, HWND(*this), (HMENU)_baseID + 1, g_hInstance, NULL)) return false; - SetListViewMode(3); + _listView.SetUserDataLongPtr(LONG_PTR(&_listView)); _listView._panel = this; @@ -329,15 +342,16 @@ bool CPanel::OnCreate(CREATESTRUCT *createStruct) ); _listView.SetImageList(imageList, LVSIL_NORMAL); - DWORD extendedStyle = _listView.GetExtendedListViewStyle(); - extendedStyle |= LVS_EX_HEADERDRAGDROP; // Version 4.70 - _listView.SetExtendedListViewStyle(extendedStyle); + // _exStyle |= LVS_EX_HEADERDRAGDROP; + // DWORD extendedStyle = _listView.GetExtendedListViewStyle(); + // extendedStyle |= _exStyle; + // _listView.SetExtendedListViewStyle(extendedStyle); + SetExtendedStyle(); _listView.Show(SW_SHOW); _listView.InvalidateRect(NULL, true); _listView.Update(); - // Ensure that the common control DLL is loaded. INITCOMMONCONTROLSEX icex; @@ -637,8 +651,6 @@ bool CPanel::IsFSFolder() const return (GetFolderTypeID() == L"FSFolder"); } -static DWORD kStyles[4] = { LVS_ICON, LVS_SMALLICON, LVS_LIST, LVS_REPORT }; - void CPanel::SetListViewMode(UINT32 index) { if (index >= 4) @@ -672,7 +684,7 @@ void CPanel::CompressDropFiles(HDROP dr) UString currentDirectory; if (IsFSFolder()) { - CompressFiles(_currentFolderPrefix + archiveName, fileNamesUnicode, + CompressFiles(_currentFolderPrefix, archiveName, fileNamesUnicode, false, // email true // showDialog ); @@ -709,11 +721,12 @@ void CPanel::AddToArchive() } const UString archiveName = CreateArchiveName( names.Front(), (names.Size() > 1), false); - CompressFiles(_currentFolderPrefix + archiveName, names, false, true); + CompressFiles(_currentFolderPrefix, archiveName, + names, false, true); KillSelection(); } -void CPanel::ExtractArchive() +void CPanel::ExtractArchives() { if (_parentFolders.Size() > 0) { @@ -722,22 +735,26 @@ void CPanel::ExtractArchive() } CRecordVector<UINT32> indices; GetOperatedItemIndices(indices); - if (indices.Size() != 1) + UStringVector paths; + if (indices.Size() == 0) { MessageBox(kSelectOneFile); return; } - int index = indices[0]; - if (IsItemFolder(index)) + for (int i = 0; i < indices.Size(); i++) { - MessageBox(kSelectOneFile); - return; + int index = indices[i]; + if (IsItemFolder(index)) + { + MessageBox(kSelectOneFile); + return; + } + paths.Add(_currentFolderPrefix + GetItemName(index)); } - UString fullPath = _currentFolderPrefix + GetItemName(index); - ::ExtractArchive(fullPath, _currentFolderPrefix, true); + ::ExtractArchives(paths, _currentFolderPrefix, true); } -void CPanel::TestArchive() +void CPanel::TestArchives() { CRecordVector<UINT32> indices; GetOperatedItemIndices(indices); @@ -746,18 +763,22 @@ void CPanel::TestArchive() MessageBox(L"Test archive operation is not supported for that folder"); return; } - if (indices.Size() != 1) + UStringVector paths; + if (indices.Size() == 0) { MessageBox(kSelectOneFile); return; } - int index = indices[0]; - if (IsItemFolder(index)) + for (int i = 0; i < indices.Size(); i++) { - MessageBox(kSelectOneFile); - return; + int index = indices[i]; + if (IsItemFolder(index)) + { + MessageBox(kSelectOneFile); + return; + } + paths.Add(_currentFolderPrefix + GetItemName(index)); } - UString fullPath = _currentFolderPrefix + GetItemName(index); - ::TestArchive(fullPath); + ::TestArchives(paths); } diff --git a/7zip/FileManager/Panel.h b/7zip/FileManager/Panel.h index 11f73e30..c9484d4e 100755 --- a/7zip/FileManager/Panel.h +++ b/7zip/FileManager/Panel.h @@ -1,7 +1,5 @@ // Panel.h -#pragma once - #ifndef __PANEL_H #define __PANEL_H @@ -54,7 +52,7 @@ struct CItemProperty VARTYPE Type; int Order; bool IsVisible; - UINT32 Width; + UInt32 Width; }; inline bool operator<(const CItemProperty &a1, const CItemProperty &a2) @@ -133,6 +131,14 @@ public: LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam); }; +struct CSelectedState +{ + int FocusedItem; + UString FocusedName; + UStringVector SelectedNames; + CSelectedState(): FocusedItem(-1) {} +}; + class CPanel:public NWindows::NControl::CWindow2 { HWND _mainWindow; @@ -170,6 +176,8 @@ public: void CreateFolder(); void CreateFile(); + // void Split(); + private: void ChangeWindowSize(int xSize, int ySize); @@ -194,7 +202,7 @@ public: void InvertSelection(); private: - CSysString GetFileType(UINT32 index); + CSysString GetFileType(UInt32 index); LRESULT SetItemText(LVITEM &item); // CRecordVector<PROPID> m_ColumnsPropIDs; @@ -210,13 +218,14 @@ public: bool _lastFocusedIsList; // NWindows::NControl::CStatusBar _statusBar2; + DWORD _exStyle; bool _showDots; bool _showRealFileIcons; // bool _virtualMode; CBoolVector _selectedStatusVector; CUIntVector _realIndices; - UINT32 GetRealIndex(const LVITEM &item) const + UInt32 GetRealIndex(const LVITEM &item) const { /* if (_virtualMode) @@ -236,7 +245,9 @@ public: return param; } - UINT32 _ListViewMode; + UInt32 _ListViewMode; + int _xSize; + UString _currentFolderPrefix; @@ -248,11 +259,13 @@ public: UStringVector _fastFolders; void GetSelectedNames(UStringVector &selectedNames); + void SaveSelectedState(CSelectedState &s); + void RefreshListCtrl(const CSelectedState &s); void RefreshListCtrlSaveFocused(); UString GetItemName(int itemIndex) const; bool IsItemFolder(int itemIndex) const; - UINT64 GetItemSize(int itemIndex) const; + UInt64 GetItemSize(int itemIndex) const; //////////////////////// // PanelFolderChange.cpp @@ -274,7 +287,7 @@ public: LRESULT Create(HWND mainWindow, HWND parentWindow, - UINT id, int xPos, + UINT id, const UString ¤tFolderPrefix, CPanelCallback *panelCallback, CAppState *appState); @@ -287,13 +300,25 @@ public: CPanel() : // _virtualMode(flase), + _exStyle(0), _showDots(false), _showRealFileIcons(false), _needSaveInfo(false), _startGroupSelect(0), - _selectionIsDefined(false) + _selectionIsDefined(false), + _ListViewMode(3), + _xSize(300) {} + void SetExtendedStyle() + { + // DWORD extendedStyle = _listView.GetExtendedListViewStyle(); + if (_listView != 0) + _listView.SetExtendedListViewStyle(_exStyle); + // extendedStyle |= _exStyle; + } + + bool _needSaveInfo; CSysString _typeIDString; CListViewInfo _listViewInfo; @@ -316,13 +341,13 @@ public: CMyComPtr<IContextMenu> _sevenZipContextMenu; CMyComPtr<IContextMenu> _systemContextMenu; void CreateShellContextMenu( - const CRecordVector<UINT32> &operatedIndices, + const CRecordVector<UInt32> &operatedIndices, CMyComPtr<IContextMenu> &systemContextMenu); void CreateSystemMenu(HMENU menu, - const CRecordVector<UINT32> &operatedIndices, + const CRecordVector<UInt32> &operatedIndices, CMyComPtr<IContextMenu> &systemContextMenu); void CreateSevenZipMenu(HMENU menu, - const CRecordVector<UINT32> &operatedIndices, + const CRecordVector<UInt32> &operatedIndices, CMyComPtr<IContextMenu> &sevenZipContextMenu); void CreateFileMenu(HMENU menu, CMyComPtr<IContextMenu> &sevenZipContextMenu, @@ -348,8 +373,8 @@ public: // void SortItems(int index); void SortItemsWithPropID(PROPID propID); - void GetSelectedItemsIndices(CRecordVector<UINT32> &indices) const; - void GetOperatedItemIndices(CRecordVector<UINT32> &indices) const; + void GetSelectedItemsIndices(CRecordVector<UInt32> &indices) const; + void GetOperatedItemIndices(CRecordVector<UInt32> &indices) const; void KillSelection(); UString GetFolderTypeID() const; @@ -422,8 +447,8 @@ public: void RenameFile(); void ChangeComment(); - void SetListViewMode(UINT32 index); - UINT32 GetListViewMode() { return _ListViewMode; }; + void SetListViewMode(UInt32 index); + UInt32 GetListViewMode() const { return _ListViewMode; }; void RefreshStatusBar(); void OnRefreshStatusBar(); @@ -431,8 +456,8 @@ public: void CompressDropFiles(HDROP dr); void AddToArchive(); - void ExtractArchive(); - void TestArchive(); + void ExtractArchives(); + void TestArchives(); }; #endif diff --git a/7zip/FileManager/PanelItemOpen.cpp b/7zip/FileManager/PanelItemOpen.cpp index b6a03a48..3b3d0793 100755 --- a/7zip/FileManager/PanelItemOpen.cpp +++ b/7zip/FileManager/PanelItemOpen.cpp @@ -12,7 +12,6 @@ #include "Windows/FileFind.h" #include "Windows/Thread.h" #include "Windows/Synchronization.h" -#include "Windows/System.h" #include "Windows/Error.h" #include "Windows/COM.h" @@ -35,6 +34,13 @@ static inline UINT GetCurrentFileCodePage() static LPCTSTR kTempDirPrefix = TEXT("7zO"); +static const wchar_t *virusMessage = L"File looks like virus (file name has long spaces in name). 7-Zip will not open it"; + +static bool IsNameVirus(const UString &name) +{ + return (name.Find(L" ") >= 0); +} + struct CTmpProcessInfo: public CTempFileInfo { HANDLE ProcessHandle; @@ -186,7 +192,7 @@ static HANDLE StartApplication(CSysString &path, HWND window) { SHELLEXECUTEINFO execInfo; execInfo.cbSize = sizeof(execInfo); - execInfo.fMask = SEE_MASK_NOCLOSEPROCESS; // + execInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT; execInfo.hwnd = NULL; execInfo.lpVerb = NULL; execInfo.lpFile = path; @@ -228,7 +234,9 @@ void CPanel::OpenFolderExternal(int index) { CSysString fullPath = GetSystemString((_currentFolderPrefix + GetItemName(index)), GetCurrentFileCodePage()); - StartApplication(fullPath, (HWND)*this); + HANDLE hProcess = StartApplication(fullPath, (HWND)*this); + if (hProcess != 0) + ::CloseHandle(hProcess); } void CPanel::OpenItem(int index, bool tryInternal, bool tryExternal) @@ -239,8 +247,14 @@ void CPanel::OpenItem(int index, bool tryInternal, bool tryExternal) OpenItemInArchive(index, tryInternal, tryExternal, false); return; } - CSysString fullPath = GetSystemString((_currentFolderPrefix + - GetItemName(index)), GetCurrentFileCodePage()); + UString name = GetItemName(index); + if (IsNameVirus(name)) + { + MessageBoxMyError(virusMessage); + return; + } + CSysString fullPath = GetSystemString((_currentFolderPrefix + name), + GetCurrentFileCodePage()); if (tryInternal) if (!tryExternal || !DoItemAlwaysStart(GetItemName(index))) if (OpenItemAsArchive(index) == S_OK) @@ -283,10 +297,14 @@ LRESULT CPanel::OnOpenItemChanged(LPARAM lParam) // LoadCurrentPath() if (tmpProcessInfo.FullPathFolderPrefix != _currentFolderPrefix) return 0; + + CSelectedState state; + SaveSelectedState(state); + HRESULT result = OnOpenItemChanged(tmpProcessInfo.FolderPath, tmpProcessInfo.ItemName); if (result != S_OK) return 0; - RefreshListCtrlSaveFocused(); + RefreshListCtrl(state); return 1; } @@ -375,6 +393,14 @@ struct CThreadExtractInArchive void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bool editMode) { + UString name = GetItemName(index); + if (IsNameVirus(name)) + { + MessageBoxMyError(virusMessage); + return; + } + + CMyComPtr<IFolderOperations> folderOperations; if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK) { @@ -390,13 +416,14 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, extracter.ExtractCallbackSpec = new CExtractCallbackImp; extracter.ExtractCallback = extracter.ExtractCallbackSpec; - extracter.ExtractCallbackSpec->_parentWindow = GetParent(); + extracter.ExtractCallbackSpec->ParentWindow = GetParent(); // extracter.ExtractCallbackSpec->_appTitle.Window = extracter.ExtractCallbackSpec->_parentWindow; // extracter.ExtractCallbackSpec->_appTitle.Title = progressWindowTitle; // extracter.ExtractCallbackSpec->_appTitle.AddTitle = title + CSysString(TEXT(" ")); - extracter.ExtractCallbackSpec->Init(NExtractionMode::NOverwrite::kWithoutPrompt, false, L""); + extracter.ExtractCallbackSpec->OverwriteMode = NExtract::NOverwriteMode::kWithoutPrompt; + extracter.ExtractCallbackSpec->Init(); extracter.Indices.Add(index); extracter.DestPath = GetUnicodeString(tempDir + NFile::NName::kDirDelimiter); extracter.FolderOperations = folderOperations; @@ -406,13 +433,18 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, throw 271824; extracter.ExtractCallbackSpec->StartProgressDialog(LangLoadStringW(IDS_OPENNING, 0x03020283)); - if (extracter.Result != S_OK) + if (extracter.Result != S_OK || extracter.ExtractCallbackSpec->Messages.Size() != 0) { - // MessageBox(TEXT("Can not extract item")); + if (extracter.Result != S_OK) + if (extracter.Result != E_ABORT) + { + // MessageBox(L"Can not extract item"); + // NError::MyFormatMessage(systemError.ErrorCode, message); + MessageBoxError(extracter.Result, L"7-Zip"); + } return; } - UString name = GetItemName(index); CSysString tempFileName = tempDir + NFile::NName::kDirDelimiter + GetSystemString(name); diff --git a/7zip/FileManager/PanelItems.cpp b/7zip/FileManager/PanelItems.cpp index 4a083982..5058285d 100755 --- a/7zip/FileManager/PanelItems.cpp +++ b/7zip/FileManager/PanelItems.cpp @@ -199,7 +199,6 @@ void CPanel::InsertColumn(int index) _listView.InsertColumn(index, &column); } - void CPanel::RefreshListCtrl() { RefreshListCtrl(UString(), 0, UStringVector()); @@ -211,13 +210,14 @@ int CALLBACK CompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData); void CPanel::GetSelectedNames(UStringVector &selectedNames) { selectedNames.Clear(); - /* + CRecordVector<UINT32> indices; - GetSelectedItemsIndexes(indices); + GetSelectedItemsIndices(indices); selectedNames.Reserve(indices.Size()); for (int i = 0; i < indices.Size(); i++) selectedNames.Add(GetItemName(indices[i])); - */ + + /* for (int i = 0; i < _listView.GetItemCount(); i++) { const int kSize = 1024; @@ -236,21 +236,21 @@ void CPanel::GetSelectedNames(UStringVector &selectedNames) if (_selectedStatusVector[realIndex]) selectedNames.Add(GetUnicodeString(item.pszText)); } + */ selectedNames.Sort(); } -void CPanel::RefreshListCtrlSaveFocused() +void CPanel::SaveSelectedState(CSelectedState &s) { - int focusedItem = _listView.GetFocusedItem(); - UString focusedName; - if (focusedItem >= 0) + s.FocusedName.Empty(); + s.SelectedNames.Clear(); + s.FocusedItem = _listView.GetFocusedItem(); + if (s.FocusedItem >= 0) { + int realIndex = GetRealItemIndex(s.FocusedItem); + if (realIndex != -1) + s.FocusedName = GetItemName(realIndex); /* - LPARAM param; - if (_listView.GetItemParam(focusedItem, param)) - // focusedName = m_Files[param].Name; - focusedName = GetItemName(param); - */ const int kSize = 1024; TCHAR name[kSize + 1]; LVITEM item; @@ -261,10 +261,21 @@ void CPanel::RefreshListCtrlSaveFocused() item.mask = LVIF_TEXT; if (_listView.GetItem(&item)) focusedName = GetUnicodeString(item.pszText); + */ } - UStringVector selectedNames; - GetSelectedNames(selectedNames); - RefreshListCtrl(focusedName, focusedItem, selectedNames); + GetSelectedNames(s.SelectedNames); +} + +void CPanel::RefreshListCtrl(const CSelectedState &s) +{ + RefreshListCtrl(s.FocusedName, s.FocusedItem, s.SelectedNames); +} + +void CPanel::RefreshListCtrlSaveFocused() +{ + CSelectedState state; + SaveSelectedState(state); + RefreshListCtrl(state); } void CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, @@ -378,8 +389,28 @@ void CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, item.lParam = i; const int kMaxNameSize = MAX_PATH * 2; - TCHAR string[kMaxNameSize]; - lstrcpyn(string, GetSystemString(itemName), kMaxNameSize); + TCHAR string[kMaxNameSize + 1]; + if (itemName.Find(L" ") >= 0) + { + UString correctedName; + int pos = 0; + while (true) + { + int posNew = itemName.Find(L" ", pos); + if (posNew < 0) + { + correctedName += itemName.Mid(pos); + break; + } + correctedName += itemName.Mid(pos, posNew - pos); + correctedName += L" ... "; + pos = posNew; + while (itemName[++pos] == ' '); + } + lstrcpyn(string, GetSystemString(correctedName), kMaxNameSize); + } + else + lstrcpyn(string, GetSystemString(itemName), kMaxNameSize); item.pszText = string; NCOM::CPropVariant propVariant; @@ -582,7 +613,7 @@ UINT64 CPanel::GetItemSize(int itemIndex) const throw 2723400; if (propVariant.vt == VT_EMPTY) return 0; - return ConvertPropVariantToUINT64(propVariant); + return ConvertPropVariantToUInt64(propVariant); } void CPanel::ReadListViewInfo() diff --git a/7zip/FileManager/PanelListNotify.cpp b/7zip/FileManager/PanelListNotify.cpp index ec449c68..34eb7a8a 100755 --- a/7zip/FileManager/PanelListNotify.cpp +++ b/7zip/FileManager/PanelListNotify.cpp @@ -24,20 +24,20 @@ static UString ConvertSizeToString(UINT64 value) wchar_t s[64]; if (value < (UINT64(10000) << 0) /*&& ((value & 0x3FF) != 0 || value == 0)*/) { - ConvertUINT64ToString(value, s); + ConvertUInt64ToString(value, s); return UString(s) + L" B"; } if (value < (UINT64(10000) << 10)) { - ConvertUINT64ToString((value >> 10), s); + ConvertUInt64ToString((value >> 10), s); return UString(s) + L" K"; } if (value < (UINT64(10000) << 20)) { - ConvertUINT64ToString((value >> 20), s); + ConvertUInt64ToString((value >> 20), s); return UString(s) + L" M"; } - ConvertUINT64ToString((value >> 30), s); + ConvertUInt64ToString((value >> 30), s); return UString(s) + L" G"; } @@ -129,7 +129,7 @@ LRESULT CPanel::SetItemText(LVITEM &item) && (propVariant.vt == VT_UI8 || propVariant.vt == VT_UI4)) { - string = ConvertSizeToString(ConvertPropVariantToUINT64(propVariant)); + string = ConvertSizeToString(ConvertPropVariantToUInt64(propVariant)); } else { @@ -150,10 +150,18 @@ extern DWORD g_ComCtl32Version; bool CPanel::OnNotifyList(LPNMHDR header, LRESULT &result) { + bool alt = (::GetKeyState(VK_MENU) & 0x8000) != 0; + bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0; + bool shift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0; switch(header->code) { - /* case LVN_ITEMCHANGED: + { + RefreshStatusBar(); + return false; + } + /* + case LVN_ODSTATECHANGED: { break; @@ -181,6 +189,14 @@ bool CPanel::OnNotifyList(LPNMHDR header, LRESULT &result) case LVN_COLUMNCLICK: OnColumnClick(LPNMLISTVIEW(header)); return false; + /* + case LVN_ITEMACTIVATE: + RefreshStatusBar(); + if (!alt && !ctrl && !shift) + OpenSelectedItems(true); + return false; + */ + case NM_DBLCLK: RefreshStatusBar(); OpenSelectedItems(true); diff --git a/7zip/FileManager/PanelOperations.cpp b/7zip/FileManager/PanelOperations.cpp index 51c65cc4..c6138888 100755 --- a/7zip/FileManager/PanelOperations.cpp +++ b/7zip/FileManager/PanelOperations.cpp @@ -15,6 +15,7 @@ #include "Resource/ComboDialog/ComboDialog.h" #include "FSFolder.h" +#include "LangUtils.h" #include "FormatUtils.h" #include "UpdateCallback100.h" @@ -25,7 +26,7 @@ using namespace NFile; struct CThreadDelete { CMyComPtr<IFolderOperations> FolderOperations; - CRecordVector<UINT32> Indices; + CRecordVector<UInt32> Indices; CMyComPtr<IFolderArchiveUpdateCallback> UpdateCallback; CUpdateCallback100Imp *UpdateCallbackSpec; HRESULT Result; @@ -46,7 +47,6 @@ struct CThreadDelete } }; - void CPanel::DeleteItems() { CMyComPtr<IFolderOperations> folderOperations; @@ -56,10 +56,14 @@ void CPanel::DeleteItems() return; } - CRecordVector<UINT32> indices; + CPanel::CDisableTimerProcessing disableTimerProcessing2(*this); + CRecordVector<UInt32> indices; GetOperatedItemIndices(indices); if (indices.IsEmpty()) return; + CSelectedState state; + SaveSelectedState(state); + UString title; UString message; if (indices.Size() == 1) @@ -86,7 +90,6 @@ void CPanel::DeleteItems() if (::MessageBoxW(GetParent(), message, title, MB_OKCANCEL | MB_ICONQUESTION) != IDOK) return; - CThreadDelete deleter; deleter.UpdateCallbackSpec = new CUpdateCallback100Imp; deleter.UpdateCallback = deleter.UpdateCallbackSpec; @@ -101,8 +104,6 @@ void CPanel::DeleteItems() deleter.FolderOperations = folderOperations; deleter.Indices = indices; - CPanel::CDisableTimerProcessing disableTimerProcessing2(*this); - CThread thread; if (!thread.Create(CThreadDelete::MyThreadFunction, &deleter)) throw 271824; @@ -112,7 +113,7 @@ void CPanel::DeleteItems() if (result != S_OK) MessageBoxError(result, LangLoadStringW(IDS_ERROR_DELETING, 0x03020217)); - RefreshListCtrlSaveFocused(); + RefreshListCtrl(state); } BOOL CPanel::OnBeginLabelEdit(LV_DISPINFO * lpnmh) @@ -149,10 +150,7 @@ BOOL CPanel::OnEndLabelEdit(LV_DISPINFO * lpnmh) return FALSE; } // Can't use RefreshListCtrl here. - // UStringVector selectedItems; - // selectedItems.Add(newName); - // RefreshListCtrl(newName, -1, selectedItems); - // RefreshListCtrl(); + // RefreshListCtrlSaveFocused(); PostMessage(kReLoadMessage); return TRUE; } @@ -165,27 +163,27 @@ void CPanel::CreateFolder() MessageBox(LangLoadStringW(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); return; } + CPanel::CDisableTimerProcessing disableTimerProcessing2(*this); + CSelectedState state; + SaveSelectedState(state); CComboDialog comboDialog; comboDialog.Title = LangLoadStringW(IDS_CREATE_FOLDER, 0x03020230); comboDialog.Static = LangLoadStringW(IDS_CREATE_FOLDER_NAME, 0x03020231); - comboDialog.Value = LangLoadStringW(IDS_CREATE_FOLDER_DEFAULT_NAME, /*0x03020232*/ (UINT32)-1); + comboDialog.Value = LangLoadStringW(IDS_CREATE_FOLDER_DEFAULT_NAME, /*0x03020232*/ (UInt32)-1); if (comboDialog.Create(GetParent()) == IDCANCEL) return; UString newName = GetUnicodeString(comboDialog.Value); - CPanel::CDisableTimerProcessing disableTimerProcessing2(*this); HRESULT result = folderOperations->CreateFolder(newName, 0); if (result != S_OK) { MessageBoxError(result, LangLoadStringW(IDS_CREATE_FOLDER_ERROR, 0x03020233)); return; } - UStringVector selectedNames; - GetSelectedNames(selectedNames); int pos = newName.Find(TEXT('\\')); if (pos >= 0) newName = newName.Left(pos); - // SetFocus(); - RefreshListCtrl(newName, _listView.GetFocusedItem(), selectedNames); + state.FocusedName = newName; + RefreshListCtrl(state); } void CPanel::CreateFile() @@ -196,27 +194,27 @@ void CPanel::CreateFile() MessageBox(LangLoadStringW(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); return; } + CPanel::CDisableTimerProcessing disableTimerProcessing2(*this); + CSelectedState state; + SaveSelectedState(state); CComboDialog comboDialog; comboDialog.Title = LangLoadStringW(IDS_CREATE_FILE, 0x03020240); comboDialog.Static = LangLoadStringW(IDS_CREATE_FILE_NAME, 0x03020241); - comboDialog.Value = LangLoadStringW(IDS_CREATE_FILE_DEFAULT_NAME, /*0x03020242*/ (UINT32)-1); + comboDialog.Value = LangLoadStringW(IDS_CREATE_FILE_DEFAULT_NAME, /*0x03020242*/ (UInt32)-1); if (comboDialog.Create(GetParent()) == IDCANCEL) return; UString newName = GetUnicodeString(comboDialog.Value); - CPanel::CDisableTimerProcessing disableTimerProcessing2(*this); HRESULT result = folderOperations->CreateFile(newName, 0); if (result != S_OK) { MessageBoxError(result, LangLoadStringW(IDS_CREATE_FILE_ERROR, 0x03020243)); return; } - UStringVector selectedNames; - GetSelectedNames(selectedNames); int pos = newName.Find(TEXT('\\')); if (pos >= 0) newName = newName.Left(pos); - RefreshListCtrl(newName, _listView.GetFocusedItem(), - selectedNames); + state.FocusedName = newName; + RefreshListCtrl(state); } void CPanel::RenameFile() @@ -228,12 +226,15 @@ void CPanel::RenameFile() void CPanel::ChangeComment() { + CPanel::CDisableTimerProcessing disableTimerProcessing2(*this); int index = _listView.GetFocusedItem(); if (index < 0) return; int realIndex = GetRealItemIndex(index); if (realIndex == -1) return; + CSelectedState state; + SaveSelectedState(state); CMyComPtr<IFolderOperations> folderOperations; if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK) { @@ -259,11 +260,12 @@ void CPanel::ChangeComment() if (comboDialog.Create(GetParent()) == IDCANCEL) return; NCOM::CPropVariant propVariant = GetUnicodeString(comboDialog.Value); + HRESULT result = folderOperations->SetProperty(realIndex, kpidComment, &propVariant, NULL); if (result != S_OK) { MessageBoxError(result, L"Set Comment Error"); } - RefreshListCtrlSaveFocused(); + RefreshListCtrl(state); } diff --git a/7zip/FileManager/PanelSplitFile.cpp b/7zip/FileManager/PanelSplitFile.cpp new file mode 100755 index 00000000..93a8420f --- /dev/null +++ b/7zip/FileManager/PanelSplitFile.cpp @@ -0,0 +1,463 @@ +// PanelSplitFile.cpp + +#include "StdAfx.h" + +#include "resource.h" + +#include "Common/Alloc.h" +#include "Common/Types.h" + +#include "Windows/COM.h" +#include "Windows/FileIO.h" +#include "Windows/FileFind.h" +#include "Windows/Thread.h" +#include "Resource/ProgressDialog2/ProgressDialog.h" +#include "Resource/SplitDialog/SplitDialog.h" +#include "Resource/CopyDialog/CopyDialog.h" + +#include "App.h" +#include "FormatUtils.h" +#include "LangUtils.h" + +using namespace NWindows; + +class CMyBuffer +{ + void *_data; +public: + CMyBuffer(): _data(0) {} + operator void *() { return _data; } + bool Allocate(size_t size) + { + if (_data != 0) + return false; + _data = BigAlloc(size); + return _data != 0; + } + ~CMyBuffer() { BigFree(_data); } +}; + +struct CVolSeqName +{ + UString UnchangedPart; + UString ChangedPart; + CVolSeqName(): ChangedPart(L"000") {}; + + bool ParseName(const UString &name) + { + if (name.Right(2) != L"01") + return false; + int numLetters = 2; + while (numLetters < name.Length()) + { + if (name[name.Length() - numLetters - 1] != '0') + break; + numLetters++; + } + UnchangedPart = name.Left(name.Length() - numLetters); + ChangedPart = name.Right(numLetters); + return true; + } + + UString GetNextName() + { + UString newName; + int i; + int numLetters = ChangedPart.Length(); + for (i = numLetters - 1; i >= 0; i--) + { + wchar_t c = ChangedPart[i]; + if (c == L'9') + { + c = L'0'; + newName = c + newName; + if (i == 0) + newName = UString(L'1') + newName; + continue; + } + c++; + newName = c + newName; + i--; + for (; i >= 0; i--) + newName = ChangedPart[i] + newName; + break; + } + ChangedPart = newName; + return UnchangedPart + ChangedPart; + } +}; + +static const UInt32 kBufSize = (1 << 20); + +struct CThreadSplit +{ + // HRESULT Result; + // CPanel *Panel; + CProgressDialog *ProgressDialog; + UString FilePath; + UString VolBasePath; + CRecordVector<UInt64> VolumeSizes; + UString Error; + + void Process2() + { + // NCOM::CComInitializer comInitializer; + ProgressDialog->WaitCreating(); + NFile::NIO::CInFile inFile; + if (!inFile.Open(FilePath)) + throw L"Can not open file"; + NFile::NIO::COutFile outFile; + CMyBuffer bufferObject; + if (!bufferObject.Allocate(kBufSize)) + throw L"Can not allocate buffer"; + Byte *buffer = (Byte *)(void *)bufferObject; + UInt64 curVolSize = 0; + CVolSeqName seqName; + UInt64 length; + if (!inFile.GetLength(length)) + throw "error"; + + ProgressDialog->ProgressSynch.SetProgress(length, 0); + UInt64 pos = 0; + + int volIndex = 0; + + while(true) + { + UInt64 volSize; + if (volIndex < VolumeSizes.Size()) + volSize = VolumeSizes[volIndex]; + else + volSize = VolumeSizes.Back(); + + UInt32 needSize = (UInt32)(MyMin((UInt64)kBufSize, volSize - curVolSize)); + UInt32 processedSize; + if (!inFile.Read(buffer, needSize, processedSize)) + throw L"Can not read input file"; + if (processedSize == 0) + break; + needSize = processedSize; + if (curVolSize == 0) + { + UString name = VolBasePath; + name += L"."; + name += seqName.GetNextName(); + if (!outFile.Create(name, false)) + throw L"Can not create output file"; + ProgressDialog->ProgressSynch.SetCurrentFileName(name); + } + if (!outFile.Write(buffer, needSize, processedSize)) + throw L"Can not write output file"; + if (needSize != processedSize) + throw L"Can not write output file"; + curVolSize += processedSize; + if (curVolSize == volSize) + { + outFile.Close(); + volIndex++; + curVolSize = 0; + } + pos += processedSize; + HRESULT res = ProgressDialog->ProgressSynch.SetPosAndCheckPaused(pos); + if (res != S_OK) + return; + } + } + DWORD Process() + { + try { Process2(); } + catch(const wchar_t *s) { Error = s; } + catch(...) { Error = L"Error"; } + ProgressDialog->MyClose(); + return 0; + } + + static DWORD WINAPI MyThreadFunction(void *param) + { + return ((CThreadSplit *)param)->Process(); + } +}; + +void CApp::Split() +{ + int srcPanelIndex = GetFocusedPanelIndex(); + CPanel &srcPanel = Panels[srcPanelIndex]; + if (!srcPanel.IsFSFolder()) + { + srcPanel.MessageBox(LangLoadStringW(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); + return; + } + CRecordVector<UInt32> indices; + srcPanel.GetOperatedItemIndices(indices); + if (indices.IsEmpty()) + return; + UString title; + UString message; + if (indices.Size() != 1) + { + srcPanel.MessageBox(L"Select one file"); + return; + } + int index = indices[0]; + if (srcPanel.IsItemFolder(index)) + { + srcPanel.MessageBox(L"Select one file"); + return; + } + const UString itemName = srcPanel.GetItemName(index); + + UString srcPath = srcPanel._currentFolderPrefix; + UString path = srcPath; + int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex); + CPanel &destPanel = Panels[destPanelIndex]; + if (NumPanels > 1) + if (destPanel.IsFSFolder()) + path = destPanel._currentFolderPrefix; + CSplitDialog splitDialog; + splitDialog.FilePath = itemName; + splitDialog.Path = path; + if (splitDialog.Create(srcPanel.GetParent()) == IDCANCEL) + return; + + CThreadSplit spliter; + // spliter.Panel = this; + + CProgressDialog progressDialog; + spliter.ProgressDialog = &progressDialog; + + progressDialog.ProgressSynch.SetTitleFileName(itemName); + + path = splitDialog.Path; + NFile::NName::NormalizeDirPathPrefix(path); + if (!NFile::NDirectory::CreateComplexDirectory(path)) + { + srcPanel.MessageBoxMyError(L"Can not create output folder"); + return; + } + + spliter.FilePath = srcPath + itemName; + spliter.VolBasePath = path + itemName; + spliter.VolumeSizes = splitDialog.VolumeSizes; + if (splitDialog.VolumeSizes.Size() == 0) + { + srcPanel.MessageBoxMyError(L"Incorrect volume size"); + return; + } + + NFile::NFind::CFileInfoW fileInfo; + if (!NFile::NFind::FindFile(spliter.FilePath, fileInfo)) + { + srcPanel.MessageBoxMyError(L"Can not find file"); + return; + } + if (fileInfo.Size <= splitDialog.VolumeSizes.Front()) + { + srcPanel.MessageBoxMyError(L"File is not larger than volume"); + return; + } + + + + // CPanel::CDisableTimerProcessing disableTimerProcessing1(srcPanel); + // CPanel::CDisableTimerProcessing disableTimerProcessing2(destPanel); + + CThread thread; + if (!thread.Create(CThreadSplit::MyThreadFunction, &spliter)) + throw 271824; + progressDialog.Create( + LangLoadStringW(IDS_SPLITTING, 0x03020510)); + + if (!spliter.Error.IsEmpty()) + srcPanel.MessageBoxMyError(spliter.Error); + // disableTimerProcessing1.Restore(); + // disableTimerProcessing2.Restore(); + // srcPanel.SetFocusToList(); + // srcPanel.RefreshListCtrlSaveFocused(); +} + + +struct CThreadCombine +{ + CProgressDialog *ProgressDialog; + UString InputDirPrefix; + UString FirstVolumeName; + UString OutputDirPrefix; + UString Error; + + void Process2() + { + // NCOM::CComInitializer comInitializer; + ProgressDialog->WaitCreating(); + + CVolSeqName volSeqName; + if (!volSeqName.ParseName(FirstVolumeName)) + throw L"Can not detect file as splitted file"; + + UString nextName = InputDirPrefix + FirstVolumeName; + UInt64 totalSize = 0; + while (true) + { + NFile::NFind::CFileInfoW fileInfo; + if (!NFile::NFind::FindFile(nextName, fileInfo)) + break; + if (fileInfo.IsDirectory()) + break; + totalSize += fileInfo.Size; + nextName = InputDirPrefix + volSeqName.GetNextName(); + } + if (totalSize == 0) + throw L"no data"; + ProgressDialog->ProgressSynch.SetProgress(totalSize, 0); + + if (!volSeqName.ParseName(FirstVolumeName)) + throw L"Can not detect file as splitted file"; + + UString outName = volSeqName.UnchangedPart; + while(!outName.IsEmpty()) + { + int lastIndex = outName.Length() - 1; + if (outName[lastIndex] != L'.') + break; + outName.Delete(lastIndex); + } + if (outName.IsEmpty()) + outName = L"file"; + NFile::NIO::COutFile outFile; + if (!outFile.Create(OutputDirPrefix + outName, false)) + throw L"Can create open output file"; + + NFile::NIO::CInFile inFile; + CMyBuffer bufferObject; + if (!bufferObject.Allocate(kBufSize)) + throw L"Can not allocate buffer"; + Byte *buffer = (Byte *)(void *)bufferObject; + UInt64 pos = 0; + nextName = InputDirPrefix + FirstVolumeName; + bool needOpen = true; + while(true) + { + if (needOpen) + { + NFile::NFind::CFileInfoW fileInfo; + if (!NFile::NFind::FindFile(nextName, fileInfo)) + break; + if (fileInfo.IsDirectory()) + break; + if (!inFile.Open(nextName)) + throw L"Can not open file"; + ProgressDialog->ProgressSynch.SetCurrentFileName(fileInfo.Name); + nextName = InputDirPrefix + volSeqName.GetNextName(); + needOpen = false; + } + UInt32 processedSize; + if (!inFile.Read(buffer, kBufSize, processedSize)) + throw L"Can not read input file"; + if (processedSize == 0) + { + needOpen = true; + continue; + } + UInt32 needSize = processedSize; + if (!outFile.Write(buffer, needSize, processedSize)) + throw L"Can not write output file"; + if (needSize != processedSize) + throw L"Can not write output file"; + pos += processedSize; + HRESULT res = ProgressDialog->ProgressSynch.SetPosAndCheckPaused(pos); + if (res != S_OK) + return; + } + } + DWORD Process() + { + try { Process2(); } + catch(const wchar_t *s) { Error = s; } + catch(...) { Error = L"Error";} + ProgressDialog->MyClose(); + return 0; + } + + static DWORD WINAPI MyThreadFunction(void *param) + { + return ((CThreadCombine *)param)->Process(); + } +}; + +void CApp::Combine() +{ + int srcPanelIndex = GetFocusedPanelIndex(); + CPanel &srcPanel = Panels[srcPanelIndex]; + if (!srcPanel.IsFSFolder()) + { + srcPanel.MessageBox(LangLoadStringW(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); + return; + } + CRecordVector<UInt32> indices; + srcPanel.GetOperatedItemIndices(indices); + if (indices.IsEmpty()) + return; + UString title; + UString message; + if (indices.Size() != 1) + { + srcPanel.MessageBox(L"Select only first file"); + return; + } + int index = indices[0]; + if (srcPanel.IsItemFolder(index)) + { + srcPanel.MessageBox(L"Select only first file"); + return; + } + const UString itemName = srcPanel.GetItemName(index); + + UString srcPath = srcPanel._currentFolderPrefix; + UString path = srcPath; + int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex); + CPanel &destPanel = Panels[destPanelIndex]; + if (NumPanels > 1) + if (destPanel.IsFSFolder()) + path = destPanel._currentFolderPrefix; + CCopyDialog copyDialog; + copyDialog.Value = path; + copyDialog.Title = LangLoadStringW(IDS_COMBINE, 0x03020600); + copyDialog.Title += ' '; + copyDialog.Title += itemName; + + copyDialog.Static = LangLoadStringW(IDS_COMBINE_TO, 0x03020601);; + if (copyDialog.Create(srcPanel.GetParent()) == IDCANCEL) + return; + + CThreadCombine combiner; + // combiner.Panel = this; + + CProgressDialog progressDialog; + combiner.ProgressDialog = &progressDialog; + + path = copyDialog.Value; + NFile::NName::NormalizeDirPathPrefix(path); + if (!NFile::NDirectory::CreateComplexDirectory(path)) + { + srcPanel.MessageBoxMyError(L"Can not create output folder"); + return; + } + + combiner.InputDirPrefix = srcPath; + combiner.FirstVolumeName = itemName; + combiner.OutputDirPrefix = path; + + // CPanel::CDisableTimerProcessing disableTimerProcessing1(srcPanel); + // CPanel::CDisableTimerProcessing disableTimerProcessing2(destPanel); + + CThread thread; + if (!thread.Create(CThreadCombine::MyThreadFunction, &combiner)) + throw 271824; + progressDialog.Create(LangLoadStringW(IDS_COMBINING, 0x03020610)); + + if (!combiner.Error.IsEmpty()) + srcPanel.MessageBoxMyError(combiner.Error); + // disableTimerProcessing1.Restore(); + // disableTimerProcessing2.Restore(); + // srcPanel.SetFocusToList(); + // srcPanel.RefreshListCtrlSaveFocused(); +} diff --git a/7zip/FileManager/PluginInterface.h b/7zip/FileManager/PluginInterface.h index 6f781340..249f5644 100755 --- a/7zip/FileManager/PluginInterface.h +++ b/7zip/FileManager/PluginInterface.h @@ -1,7 +1,5 @@ // PluginInterface.h -#pragma once - #ifndef __PLUGININTERFACE_H #define __PLUGININTERFACE_H diff --git a/7zip/FileManager/PluginLoader.h b/7zip/FileManager/PluginLoader.h index b13edb37..88329bbf 100755 --- a/7zip/FileManager/PluginLoader.h +++ b/7zip/FileManager/PluginLoader.h @@ -1,7 +1,5 @@ // PluginLoader.h -#pragma once - #ifndef __PLUGINLOADER_H #define __PLUGINLOADER_H @@ -31,4 +29,4 @@ public: } }; -#endif
\ No newline at end of file +#endif diff --git a/7zip/FileManager/ProgramLocation.h b/7zip/FileManager/ProgramLocation.h index aacda0fa..8a8dcf7d 100755 --- a/7zip/FileManager/ProgramLocation.h +++ b/7zip/FileManager/ProgramLocation.h @@ -1,7 +1,5 @@ // ProgramLocation.h -#pragma once - #ifndef __PROGRAMLOCATION_H #define __PROGRAMLOCATION_H diff --git a/7zip/FileManager/PropertyName.cpp b/7zip/FileManager/PropertyName.cpp index 96f4d018..5619273c 100755 --- a/7zip/FileManager/PropertyName.cpp +++ b/7zip/FileManager/PropertyName.cpp @@ -44,6 +44,7 @@ static CPropertyIDNamePair kPropertyIDNamePairs[] = { kpidGroup, IDS_PROPERTY_GROUP, 0x0200021A}, { kpidBlock, IDS_PROPERTY_BLOCK, 0x0200021B }, { kpidComment, IDS_PROPERTY_COMMENT, 0x0200021C }, + { kpidPosition, IDS_PROPERTY_POSITION, 0x0200021D }, { kpidTotalSize, IDS_PROPERTY_TOTAL_SIZE, 0x03031100 }, { kpidFreeSpace, IDS_PROPERTY_FREE_SPACE, 0x03031101 }, diff --git a/7zip/FileManager/PropertyName.h b/7zip/FileManager/PropertyName.h index d1cee697..c99fe933 100755 --- a/7zip/FileManager/PropertyName.h +++ b/7zip/FileManager/PropertyName.h @@ -1,7 +1,5 @@ // PropertyName.h -#pragma once - #ifndef __PROPERTYNAME_H #define __PROPERTYNAME_H @@ -9,4 +7,4 @@ UString GetNameOfProperty(PROPID propID); -#endif
\ No newline at end of file +#endif diff --git a/7zip/FileManager/RegistryAssociations.cpp b/7zip/FileManager/RegistryAssociations.cpp index 89fb0414..a3d9c620 100755 --- a/7zip/FileManager/RegistryAssociations.cpp +++ b/7zip/FileManager/RegistryAssociations.cpp @@ -9,7 +9,6 @@ #include "Windows/COM.h" #include "Windows/Synchronization.h" #include "Windows/Registry.h" -#include "Windows/System.h" #include "Windows/FileName.h" diff --git a/7zip/FileManager/RegistryAssociations.h b/7zip/FileManager/RegistryAssociations.h index a55c36d6..75a25e34 100755 --- a/7zip/FileManager/RegistryAssociations.h +++ b/7zip/FileManager/RegistryAssociations.h @@ -1,7 +1,5 @@ // RegistryAssociations.h -#pragma once - #ifndef __REGISTRYASSOCIATIONS_H #define __REGISTRYASSOCIATIONS_H @@ -44,5 +42,4 @@ namespace NRegistryAssociations { // bool GetProgramDirPrefix(CSysString &aFolder); - -#endif
\ No newline at end of file +#endif diff --git a/7zip/FileManager/RegistryPlugins.h b/7zip/FileManager/RegistryPlugins.h index 9f19b3bf..a3e0b493 100755 --- a/7zip/FileManager/RegistryPlugins.h +++ b/7zip/FileManager/RegistryPlugins.h @@ -1,7 +1,5 @@ // RegistryPlugins.h -#pragma once - #ifndef __REGISTRYPLUGINS_H #define __REGISTRYPLUGINS_H @@ -32,4 +30,3 @@ void ReadPluginInfoList(CObjectVector<CPluginInfo> &plugins); void ReadFileFolderPluginInfoList(CObjectVector<CPluginInfo> &plugins); #endif - diff --git a/7zip/FileManager/RegistrySystem.cpp b/7zip/FileManager/RegistrySystem.cpp deleted file mode 100755 index 1d1cc940..00000000 --- a/7zip/FileManager/RegistrySystem.cpp +++ /dev/null @@ -1,152 +0,0 @@ -// ZipRegistryMain.cpp - -#include "StdAfx.h" - -#include "ZipRegistryMain.h" - -#ifndef NO_REGISTRY - -#include "Windows/COM.h" -#include "Windows/Synchronization.h" -#include "Windows/Registry.h" - -#include "Windows/FileDir.h" -#include "Windows/FileName.h" - -using namespace NZipSettings; - -using namespace NWindows; -using namespace NCOM; -using namespace NRegistry; - -#endif - -namespace NZipRootRegistry { - -#ifndef NO_REGISTRY -////////////////////////////////// -static const TCHAR *kLMBasePath = _T("Software\\7-ZIP"); -// m_LMKey.Create(HKEY_LOCAL_MACHINE, kLMBasePath); - -static const TCHAR *kArchiversKeyName = _T("Archivers"); - -namespace NArchiveType -{ - static const TCHAR *kExtension = _T("Extension"); - static const TCHAR *kAddExtension = _T("AddExtension"); - static const TCHAR *kUpdate = _T("Update"); - static const TCHAR *kKeepName = _T("KeepName"); -} - -static NSynchronization::CCriticalSection g_RegistryOperationsCriticalSection; - -static CSysString GetArchiversKeyName() -{ - return CSysString(kLMBasePath) + CSysString(kKeyNameDelimiter) + - CSysString(kArchiversKeyName); -} -#endif - -void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &anInfoList) -{ - anInfoList.Clear(); - - #ifdef NO_REGISTRY - - CArchiverInfo anItemInfo; - #ifdef FORMAT_7Z - anItemInfo.UpdateEnabled = true; - anItemInfo.KeepName = false; - anItemInfo.Name = TEXT("7z"); - anItemInfo.Extension = TEXT("7z"); - anInfoList.Add(anItemInfo); - #endif - - #ifdef FORMAT_BZIP2 - anItemInfo.UpdateEnabled = true; - anItemInfo.KeepName = true; - anItemInfo.Name = TEXT("BZip2"); - anItemInfo.Extension = TEXT("bz2"); - anInfoList.Add(anItemInfo); - #endif - - #ifdef FORMAT_GZIP - anItemInfo.UpdateEnabled = true; - anItemInfo.KeepName = false; - anItemInfo.Name = TEXT("GZip"); - anItemInfo.Extension = TEXT("gz"); - anInfoList.Add(anItemInfo); - #endif - - #ifdef FORMAT_TAR - anItemInfo.UpdateEnabled = true; - anItemInfo.KeepName = false; - anItemInfo.Name = TEXT("Tar"); - anItemInfo.Extension = TEXT("tar"); - anInfoList.Add(anItemInfo); - #endif - - #ifdef FORMAT_ZIP - anItemInfo.UpdateEnabled = true; - anItemInfo.KeepName = false; - anItemInfo.Name = TEXT("Zip"); - anItemInfo.Extension = TEXT("zip"); - anInfoList.Add(anItemInfo); - #endif - - #ifdef FORMAT_CPIO - anItemInfo.UpdateEnabled = false; - anItemInfo.Name = TEXT("cpio"); - anItemInfo.Extension = TEXT("cpio"); - anInfoList.Add(anItemInfo); - #endif - - #ifdef FORMAT_RPM - anItemInfo.UpdateEnabled = false; - anItemInfo.Name = TEXT("RPM"); - anItemInfo.Extension = TEXT("rpm"); - anItemInfo.AddExtension = TEXT(".cpio.gz"); - anInfoList.Add(anItemInfo); - #endif - - #ifdef FORMAT_ARJ - anItemInfo.UpdateEnabled = false; - anItemInfo.Name = TEXT("arj"); - anItemInfo.Extension = TEXT("arj"); - anInfoList.Add(anItemInfo); - #endif - - #else - - NSynchronization::CSingleLock aLock(&g_RegistryOperationsCriticalSection, true); - - CKey anArchiversKey; - if(anArchiversKey.Open(HKEY_LOCAL_MACHINE, GetArchiversKeyName(), KEY_READ) != ERROR_SUCCESS) - return; - - CSysStringVector aClassIDs; - anArchiversKey.EnumKeys(aClassIDs); - for(int i = 0; i < aClassIDs.Size(); i++) - { - const CSysString aClassIDString = aClassIDs[i]; - CArchiverInfo anItemInfo; - anItemInfo.UpdateEnabled = false; - anItemInfo.KeepName = false; - CKey aClassIDKey; - if(aClassIDKey.Open(anArchiversKey, aClassIDString, KEY_READ) != ERROR_SUCCESS) - return; - - if(StringToGUID(aClassIDString, anItemInfo.ClassID) != NOERROR) - return; // test it maybe creation; - aClassIDKey.QueryValue(NULL, anItemInfo.Name); - aClassIDKey.QueryValue(NArchiveType::kExtension, anItemInfo.Extension); - aClassIDKey.QueryValue(NArchiveType::kAddExtension, anItemInfo.AddExtension); - aClassIDKey.QueryValue(NArchiveType::kUpdate, anItemInfo.UpdateEnabled); - aClassIDKey.QueryValue(NArchiveType::kKeepName, anItemInfo.KeepName); - anInfoList.Add(anItemInfo); - } - #endif -} - -} - diff --git a/7zip/FileManager/RegistrySystem.h b/7zip/FileManager/RegistrySystem.h deleted file mode 100755 index 2a59e6e0..00000000 --- a/7zip/FileManager/RegistrySystem.h +++ /dev/null @@ -1,28 +0,0 @@ -// ZipRegistryMain.h - -#pragma once - -#ifndef __ZIPREGISTRYMAIN_H -#define __ZIPREGISTRYMAIN_H - -#include "ZipSettings.h" - -namespace NZipRootRegistry { - - struct CArchiverInfo - { - #ifndef NO_REGISTRY - CLSID ClassID; - #endif - CSysString Name; - CSysString Extension; - CSysString AddExtension; - bool UpdateEnabled; - bool KeepName; - }; - - void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &anInfoList); -} - - -#endif
\ No newline at end of file diff --git a/7zip/FileManager/RegistryUtils.cpp b/7zip/FileManager/RegistryUtils.cpp index 470d3eb5..e15f153a 100755 --- a/7zip/FileManager/RegistryUtils.cpp +++ b/7zip/FileManager/RegistryUtils.cpp @@ -9,13 +9,18 @@ using namespace NWindows; using namespace NRegistry; static const TCHAR *kCUBasePath = TEXT("Software\\7-ZIP"); - static const TCHAR *kCU_FMPath = TEXT("Software\\7-ZIP\\FM"); + static const TCHAR *kLangValueName = TEXT("Lang"); -static const TCHAR *kEditorValueName = TEXT("Editor"); -static const TCHAR *kShowDotsValueName = TEXT("ShowDots"); -static const TCHAR *kShowRealFileIconsValueName = TEXT("ShowRealFileIcons"); -static const TCHAR *kShowSystemMenuValueName = TEXT("ShowSystemMenu"); +static const TCHAR *kEditor = TEXT("Editor"); +static const TCHAR *kShowDots = TEXT("ShowDots"); +static const TCHAR *kShowRealFileIcons = TEXT("ShowRealFileIcons"); +static const TCHAR *kShowSystemMenu = TEXT("ShowSystemMenu"); + +static const TCHAR *kFullRow = TEXT("FullRow"); +static const TCHAR *kShowGrid = TEXT("ShowGrid"); +// static const TCHAR *kSingleClick = TEXT("SingleClick"); +// static const TCHAR *kUnderline = TEXT("Underline"); void SaveRegLang(const CSysString &langFile) { @@ -36,7 +41,7 @@ void SaveRegEditor(const CSysString &editorPath) { CKey cuKey; cuKey.Create(HKEY_CURRENT_USER, kCU_FMPath); - cuKey.SetValue(kEditorValueName, editorPath); + cuKey.SetValue(kEditor, editorPath); } void ReadRegEditor(CSysString &editorPath) @@ -44,7 +49,7 @@ void ReadRegEditor(CSysString &editorPath) editorPath.Empty(); CKey cuKey; cuKey.Create(HKEY_CURRENT_USER, kCU_FMPath); - cuKey.QueryValue(kEditorValueName, editorPath); + cuKey.QueryValue(kEditor, editorPath); /* if (editorPath.IsEmpty()) editorPath = TEXT("notepad.exe"); @@ -68,17 +73,25 @@ static bool ReadOption(const TCHAR *value, bool defaultValue) return enabled; } -void SaveShowDots(bool showDots) - { SaveOption(kShowDotsValueName, showDots); } -bool ReadShowDots() - { return ReadOption(kShowDotsValueName, false); } +void SaveShowDots(bool showDots) { SaveOption(kShowDots, showDots); } +bool ReadShowDots() { return ReadOption(kShowDots, false); } + +void SaveShowRealFileIcons(bool show) { SaveOption(kShowRealFileIcons, show); } +bool ReadShowRealFileIcons() { return ReadOption(kShowRealFileIcons, false); } + +void SaveShowSystemMenu(bool show) { SaveOption(kShowSystemMenu, show); } +bool ReadShowSystemMenu(){ return ReadOption(kShowSystemMenu, false); } + +void SaveFullRow(bool enable) { SaveOption(kFullRow, enable); } +bool ReadFullRow() { return ReadOption(kFullRow, false); } + +void SaveShowGrid(bool enable) { SaveOption(kShowGrid, enable); } +bool ReadShowGrid(){ return ReadOption(kShowGrid, false); } -void SaveShowRealFileIcons(bool show) - { SaveOption(kShowRealFileIconsValueName, show); } -bool ReadShowRealFileIcons() - { return ReadOption(kShowRealFileIconsValueName, false); } +/* +void SaveSingleClick(bool enable) { SaveOption(kSingleClick, enable); } +bool ReadSingleClick(){ return ReadOption(kSingleClick, false); } -void SaveShowSystemMenu(bool show) - { SaveOption(kShowSystemMenuValueName, show); } -bool ReadShowSystemMenu() - { return ReadOption(kShowSystemMenuValueName, false); } +void SaveUnderline(bool enable) { SaveOption(kUnderline, enable); } +bool ReadUnderline(){ return ReadOption(kUnderline, false); } +*/
\ No newline at end of file diff --git a/7zip/FileManager/RegistryUtils.h b/7zip/FileManager/RegistryUtils.h index dade674b..775f8f12 100755 --- a/7zip/FileManager/RegistryUtils.h +++ b/7zip/FileManager/RegistryUtils.h @@ -1,7 +1,5 @@ // RegistryUtils.h -#pragma once - #include "Common/StringConvert.h" #ifndef __REGISTRYUTILS_H @@ -22,4 +20,18 @@ bool ReadShowRealFileIcons(); void SaveShowSystemMenu(bool showSystemMenu); bool ReadShowSystemMenu(); -#endif
\ No newline at end of file +void SaveFullRow(bool enable); +bool ReadFullRow(); + +void SaveShowGrid(bool enable); +bool ReadShowGrid(); + +/* +void SaveSingleClick(bool enable); +bool ReadSingleClick(); + +void SaveUnderline(bool enable); +bool ReadUnderline(); +*/ + +#endif diff --git a/7zip/FileManager/Resource/AboutDialog/AboutDialog.cpp b/7zip/FileManager/Resource/AboutDialog/AboutDialog.cpp index 7631f9fe..733b1890 100755 --- a/7zip/FileManager/Resource/AboutDialog/AboutDialog.cpp +++ b/7zip/FileManager/Resource/AboutDialog/AboutDialog.cpp @@ -16,11 +16,8 @@ static CIDLangPair kIDLangPairs[] = }; static LPCTSTR kHomePageURL = TEXT("http://www.7-zip.org/"); -// static LPCTSTR kRegisterRegNowURL = TEXT("https://secure.shareit.com/shareit/checkout.html?PRODUCT[104808]=1&languageid=1"); -static LPCTSTR kRegisterRegNowURL = TEXT("https://www.regnow.com/softsell/nph-softsell.cgi?item=2521-1&vreferrer=program"); - -static LPCTSTR kEmailAction = - TEXT("mailto:support@7-zip.org?subject=7-Zip"); +static LPCTSTR kRegisterPageURL = TEXT("http://www.7-zip.org/register.html"); +static LPCTSTR kSupportPageURL = TEXT("http://www.7-zip.org/support.html"); static LPCWSTR kHelpTopic = L"start.htm"; @@ -36,27 +33,26 @@ void CAboutDialog::OnHelp() ShowHelpWindow(NULL, kHelpTopic); } +static void MyShellExecute(LPCTSTR url) +{ + ::ShellExecute(NULL, NULL, url, NULL, NULL, SW_SHOWNORMAL); +} + bool CAboutDialog::OnButtonClicked(int buttonID, HWND buttonHWND) { switch(buttonID) { case IDC_ABOUT_BUTTON_HOMEPAGE: - ::ShellExecute(NULL, NULL, kHomePageURL, NULL, NULL, SW_SHOWNORMAL); + ::MyShellExecute(kHomePageURL); break; case IDC_ABOUT_BUTTON_REGISTER: { - LPCTSTR registerURL = kRegisterRegNowURL; - /* - LCID aLCID = ::GetUserDefaultLCID(); - if (aLCID == 0x0419 || aLCID == 0x422 || aLCID == 0x0423) - registerURL = TEXT("http://www.7-zip.org/ru/donate.html"); - */ - ::ShellExecute(NULL, NULL, registerURL, NULL, NULL, SW_SHOWNORMAL); + ::MyShellExecute(kRegisterPageURL); break; } case IDC_ABOUT_BUTTON_EMAIL: { - ::ShellExecute(NULL, NULL, kEmailAction, NULL, NULL, SW_SHOWNORMAL); + ::MyShellExecute(kSupportPageURL); break; } default: diff --git a/7zip/FileManager/Resource/AboutDialog/AboutDialog.h b/7zip/FileManager/Resource/AboutDialog/AboutDialog.h index e1ff98ee..ccd50c1a 100755 --- a/7zip/FileManager/Resource/AboutDialog/AboutDialog.h +++ b/7zip/FileManager/Resource/AboutDialog/AboutDialog.h @@ -1,7 +1,5 @@ // AboutDialog.h -#pragma once - #ifndef __ABOUTDIALOG_H #define __ABOUTDIALOG_H diff --git a/7zip/FileManager/Resource/AboutDialog/resource.rc b/7zip/FileManager/Resource/AboutDialog/resource.rc index 600fc863..df8b3caf 100755 --- a/7zip/FileManager/Resource/AboutDialog/resource.rc +++ b/7zip/FileManager/Resource/AboutDialog/resource.rc @@ -80,13 +80,13 @@ FONT 8, "MS Shell Dlg" BEGIN PUSHBUTTON "OK",IDOK,180,151,50,14 PUSHBUTTON "www.7-zip.org",IDC_ABOUT_BUTTON_HOMEPAGE,136,7,94,14 - PUSHBUTTON "support@7-zip.org",IDC_ABOUT_BUTTON_EMAIL,136,30,94,14 + PUSHBUTTON "Support",IDC_ABOUT_BUTTON_EMAIL,136,30,94,14 PUSHBUTTON "Register",IDC_ABOUT_BUTTON_REGISTER,136,53,94,14 ICON IDI_LOGO,IDC_STATIC,7,7,20,20,SS_REALSIZEIMAGE - LTEXT "7-Zip 3.13",IDC_STATIC,7,54,119,9 - LTEXT "Copyright (c) 1999-2003 Igor Pavlov",IDC_STATIC,7,67, + LTEXT "7-Zip 4.20",IDC_STATIC,7,54,119,9 + LTEXT "Copyright (c) 1999-2005 Igor Pavlov",IDC_STATIC,7,67, 119,17 - LTEXT "7-Zip is free software. However, you can support development of 7-Zip by registering. As registered user, you will be able to get technical support.", + LTEXT "7-Zip is free software. However, you can support development of 7-Zip by registering.", IDC_ABOUT_STATIC_REGISTER_INFO,7,91,223,54 END diff --git a/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.cpp b/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.cpp index a0eb020b..416f388d 100755 --- a/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.cpp +++ b/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.cpp @@ -24,8 +24,8 @@ static LPCWSTR kHelpTopic = L"fm/benchmark.htm"; static const UINT_PTR kTimerID = 4; static const UINT kTimerElapse = 1000; -static const UINT32 kAdditionalSize = (6 << 20); -static const UINT32 kCompressedAdditionalSize = (1 << 10); +static const UInt32 kAdditionalSize = (6 << 20); +static const UInt32 kCompressedAdditionalSize = (1 << 10); static const int kSubBits = 8; #ifdef LANG @@ -65,7 +65,7 @@ static void MyMessageBoxError(HWND hwnd, LPCWSTR message) MessageBoxW(hwnd, message, L"7-Zip", MB_ICONERROR); } -UINT64 GetTimeCount() +UInt64 GetTimeCount() { return GetTickCount(); /* @@ -76,7 +76,7 @@ UINT64 GetTimeCount() */ } -UINT64 GetFreq() +UInt64 GetFreq() { return 1000; /* @@ -89,12 +89,12 @@ UINT64 GetFreq() class CRandomGenerator { - UINT32 A1; - UINT32 A2; + UInt32 A1; + UInt32 A2; public: CRandomGenerator() { Init(); } void Init() { A1 = 362436069; A2 = 521288629;} - UINT32 GetRnd() + UInt32 GetRnd() { return ((A1 = 36969 * (A1 & 0xffff) + (A1 >> 16)) << 16) ^ @@ -105,7 +105,7 @@ public: class CBitRandomGenerator { CRandomGenerator RG; - UINT32 Value; + UInt32 Value; int NumBits; public: void Init() @@ -113,17 +113,17 @@ public: Value = 0; NumBits = 0; } - UINT32 GetRnd(int numBits) + UInt32 GetRnd(int numBits) { if (NumBits > numBits) { - UINT32 result = Value & ((1 << numBits) - 1); + UInt32 result = Value & ((1 << numBits) - 1); Value >>= numBits; NumBits -= numBits; return result; } numBits -= NumBits; - UINT32 result = (Value << numBits); + UInt32 result = (Value << numBits); Value = RG.GetRnd(); result |= Value & ((1 << numBits) - 1); Value >>= numBits; @@ -135,41 +135,41 @@ public: class CBenchRandomGenerator { CBitRandomGenerator RG; - UINT32 Pos; + UInt32 Pos; public: - UINT32 BufferSize; - BYTE *Buffer; + UInt32 BufferSize; + Byte *Buffer; CBenchRandomGenerator(): Buffer(0) {} ~CBenchRandomGenerator() { delete []Buffer; } void Init() { RG.Init(); } - void Set(UINT32 bufferSize) + void Set(UInt32 bufferSize) { delete []Buffer; Buffer = 0; - Buffer = new BYTE[bufferSize]; + Buffer = new Byte[bufferSize]; Pos = 0; BufferSize = bufferSize; } - UINT32 GetRndBit() { return RG.GetRnd(1); } + UInt32 GetRndBit() { return RG.GetRnd(1); } /* - UINT32 GetLogRand(int maxLen) + UInt32 GetLogRand(int maxLen) { - UINT32 len = GetRnd() % (maxLen + 1); + UInt32 len = GetRnd() % (maxLen + 1); return GetRnd() & ((1 << len) - 1); } */ - UINT32 GetLogRandBits(int numBits) + UInt32 GetLogRandBits(int numBits) { - UINT32 len = RG.GetRnd(numBits); + UInt32 len = RG.GetRnd(numBits); return RG.GetRnd(len); } - UINT32 GetOffset() + UInt32 GetOffset() { if (GetRndBit() == 0) return GetLogRandBits(4); return (GetLogRandBits(4) << 10) | RG.GetRnd(10); } - UINT32 GetLen() + UInt32 GetLen() { if (GetRndBit() == 0) return RG.GetRnd(2); @@ -182,15 +182,15 @@ public: while(Pos < BufferSize) { if (GetRndBit() == 0 || Pos < 1) - Buffer[Pos++] = BYTE(RG.GetRnd(8)); + Buffer[Pos++] = Byte(RG.GetRnd(8)); else { - UINT32 offset = GetOffset(); + UInt32 offset = GetOffset(); while (offset >= Pos) offset >>= 1; offset += 1; - UINT32 len = 2 + GetLen(); - for (UINT32 i = 0; i < len && Pos < BufferSize; i++, Pos++) + UInt32 len = 2 + GetLen(); + for (UInt32 i = 0; i < len && Pos < BufferSize; i++, Pos++) Buffer[Pos] = Buffer[Pos - offset]; } } @@ -213,9 +213,9 @@ bool CBenchmarkDialog::OnInit() for (int i = kNumBenchDictionaryBitsStart; i < 28; i++) for (int j = 0; j < 2; j++) { - UINT32 dictionary = (1 << i) + (j << (i - 1)); + UInt32 dictionary = (1 << i) + (j << (i - 1)); TCHAR s[40]; - ConvertUINT64ToString((dictionary >> 20), s); + ConvertUInt64ToString((dictionary >> 20), s); lstrcat(s, kMB); int index = m_Dictionary.AddString(s); m_Dictionary.SetItemData(index, dictionary); @@ -231,24 +231,24 @@ bool CBenchmarkDialog::OnInit() return CModalDialog::OnInit(); } -static UINT64 GetLZMAUsage(UINT32 dictionary) - { return ((UINT64)dictionary * 19 / 2) + (8 << 20); } +static UInt64 GetLZMAUsage(UInt32 dictionary) + { return ((UInt64)dictionary * 19 / 2) + (8 << 20); } -static UINT64 GetMemoryUsage(UINT32 dictionary) +static UInt64 GetMemoryUsage(UInt32 dictionary) { - const UINT32 kBufferSize = dictionary + kAdditionalSize; - const UINT32 kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize; + const UInt32 kBufferSize = dictionary + kAdditionalSize; + const UInt32 kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize; return kBufferSize + kCompressedBufferSize + GetLZMAUsage(dictionary) + dictionary + (1 << 20); } -UINT32 CBenchmarkDialog::OnChangeDictionary() +UInt32 CBenchmarkDialog::OnChangeDictionary() { - UINT64 dictionary = m_Dictionary.GetItemData(m_Dictionary.GetCurSel()); - UINT64 memUsage = GetMemoryUsage(dictionary); + UInt64 dictionary = m_Dictionary.GetItemData(m_Dictionary.GetCurSel()); + UInt64 memUsage = GetMemoryUsage(dictionary); memUsage = (memUsage + (1 << 20) - 1) >> 20; TCHAR s[40]; - ConvertUINT64ToString(memUsage, s); + ConvertUInt64ToString(memUsage, s); lstrcat(s, kMB); SetItemText(IDC_BENCHMARK_MEMORY_VALUE, s); return dictionary; @@ -257,7 +257,7 @@ UINT32 CBenchmarkDialog::OnChangeDictionary() void CBenchmarkDialog::OnChangeSettings() { EnableItem(IDC_BUTTON_STOP, true); - UINT32 dictionary = OnChangeDictionary(); + UInt32 dictionary = OnChangeDictionary(); SetItemText(IDC_BENCHMARK_COMPRESSING_SPEED, kProcessingString); SetItemText(IDC_BENCHMARK_COMPRESSING_SPEED2, kProcessingString); SetItemText(IDC_BENCHMARK_COMPRESSING_RATING, kProcessingString); @@ -299,83 +299,83 @@ void CBenchmarkDialog::OnCancel() CModalDialog::OnCancel(); } -static void GetTimeString(UINT64 timeValue, TCHAR *s) +static void GetTimeString(UInt64 timeValue, TCHAR *s) { wsprintf(s, TEXT("%02d:%02d:%02d"), - UINT32(timeValue / 3600), - UINT32((timeValue / 60) % 60), - UINT32(timeValue % 60)); + UInt32(timeValue / 3600), + UInt32((timeValue / 60) % 60), + UInt32(timeValue % 60)); } void CBenchmarkDialog::PrintTime() { - UINT32 curTime = ::GetTickCount(); - UINT32 elapsedTime = (curTime - _startTime); - UINT32 elapsedSec = elapsedTime / 1000; + UInt32 curTime = ::GetTickCount(); + UInt32 elapsedTime = (curTime - _startTime); + UInt32 elapsedSec = elapsedTime / 1000; TCHAR s[40]; GetTimeString(elapsedSec, s); SetItemText(IDC_BENCHMARK_ELAPSED_VALUE, s); } -static UINT32 GetLogSize(UINT32 size) +static UInt32 GetLogSize(UInt32 size) { for (int i = kSubBits; i < 32; i++) - for (UINT32 j = 0; j < (1 << kSubBits); j++) - if (size <= (((UINT32)1) << i) + (j << (i - kSubBits))) + for (UInt32 j = 0; j < (1 << kSubBits); j++) + if (size <= (((UInt32)1) << i) + (j << (i - kSubBits))) return (i << kSubBits) + j; return (32 << kSubBits); } -static UINT64 GetCompressRating(UINT32 dictionarySize, - UINT64 elapsedTime, UINT64 size) +static UInt64 GetCompressRating(UInt32 dictionarySize, + UInt64 elapsedTime, UInt64 size) { if (elapsedTime == 0) elapsedTime = 1; - UINT64 t = GetLogSize(dictionarySize) - (19 << kSubBits); - UINT64 numCommandsForOne = 2000 + ((t * t * 68) >> (2 * kSubBits)); - UINT64 numCommands = (UINT64)(size) * numCommandsForOne; + UInt64 t = GetLogSize(dictionarySize) - (19 << kSubBits); + UInt64 numCommandsForOne = 2000 + ((t * t * 68) >> (2 * kSubBits)); + UInt64 numCommands = (UInt64)(size) * numCommandsForOne; return numCommands * GetFreq() / elapsedTime; } -static UINT64 GetDecompressRating(UINT64 elapsedTime, - UINT64 outSize, UINT64 inSize) +static UInt64 GetDecompressRating(UInt64 elapsedTime, + UInt64 outSize, UInt64 inSize) { if (elapsedTime == 0) elapsedTime = 1; - UINT64 numCommands = inSize * 250 + outSize * 20; + UInt64 numCommands = inSize * 250 + outSize * 21; return numCommands * GetFreq() / elapsedTime; } -static UINT64 GetTotalRating( - UINT32 dictionarySize, - UINT64 elapsedTimeEn, UINT64 sizeEn, - UINT64 elapsedTimeDe, - UINT64 inSizeDe, UINT64 outSizeDe) +static UInt64 GetTotalRating( + UInt32 dictionarySize, + UInt64 elapsedTimeEn, UInt64 sizeEn, + UInt64 elapsedTimeDe, + UInt64 inSizeDe, UInt64 outSizeDe) { return (GetCompressRating(dictionarySize, elapsedTimeEn, sizeEn) + GetDecompressRating(elapsedTimeDe, inSizeDe, outSizeDe)) / 2; } -void CBenchmarkDialog::PrintRating(UINT64 rating, UINT controlID) +void CBenchmarkDialog::PrintRating(UInt64 rating, UINT controlID) { TCHAR s[40]; - ConvertUINT64ToString(rating / 1000000, s); + ConvertUInt64ToString(rating / 1000000, s); lstrcat(s, kMIPS); SetItemText(controlID, s); } void CBenchmarkDialog::PrintResults( - UINT32 dictionarySize, - UINT64 elapsedTime, - UINT64 size, UINT speedID, UINT ratingID, - bool decompressMode, UINT64 secondSize) + UInt32 dictionarySize, + UInt64 elapsedTime, + UInt64 size, UINT speedID, UINT ratingID, + bool decompressMode, UInt64 secondSize) { TCHAR s[40]; - UINT64 speed = size * GetFreq() / elapsedTime; - ConvertUINT64ToString(speed / 1024, s); + UInt64 speed = size * GetFreq() / elapsedTime; + ConvertUInt64ToString(speed / 1024, s); lstrcat(s, kKBs); SetItemText(speedID, s); - UINT64 rating; + UInt64 rating; if (decompressMode) rating = GetDecompressRating(elapsedTime, size, secondSize); else @@ -389,20 +389,20 @@ bool CBenchmarkDialog::OnTimer(WPARAM timerID, LPARAM callback) NWindows::NSynchronization::CCriticalSectionLock lock(_syncInfo.CS); TCHAR s[40]; - ConvertUINT64ToString((_syncInfo.ProcessedSize >> 20), s); + ConvertUInt64ToString((_syncInfo.ProcessedSize >> 20), s); lstrcat(s, kMB); SetItemText(IDC_BENCHMARK_SIZE_VALUE, s); - ConvertUINT64ToString(_syncInfo.NumPasses, s); + ConvertUInt64ToString(_syncInfo.NumPasses, s); SetItemText(IDC_BENCHMARK_PASSES_VALUE, s); - ConvertUINT64ToString(_syncInfo.NumErrors, s); + ConvertUInt64ToString(_syncInfo.NumErrors, s); SetItemText(IDC_BENCHMARK_ERRORS_VALUE, s); - UINT64 elapsedTime = _syncInfo.CompressingInfoTemp.Time; + UInt64 elapsedTime = _syncInfo.CompressingInfoTemp.Time; if (elapsedTime >= 1) { - UINT32 dicSizeTemp = (UINT32)MyMax(_syncInfo.ProcessedSize, UINT64(1) << 20); + UInt32 dicSizeTemp = (UInt32)MyMax(_syncInfo.ProcessedSize, UInt64(1) << 20); dicSizeTemp = MyMin(dicSizeTemp, _syncInfo.DictionarySize), PrintResults(dicSizeTemp, elapsedTime, _syncInfo.CompressingInfoTemp.InSize, @@ -487,29 +487,29 @@ class CBenchmarkInStream: public ISequentialInStream, public CMyUnknownImp { - const BYTE *Data; - UINT32 Pos; - UINT32 Size; + const Byte *Data; + UInt32 Pos; + UInt32 Size; public: MY_UNKNOWN_IMP - void Init(const BYTE *data, UINT32 size) + void Init(const Byte *data, UInt32 size) { Data = data; Size = size; Pos = 0; } - STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize); - STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize); + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); }; -STDMETHODIMP CBenchmarkInStream::Read(void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processedSize) { - UINT32 remain = Size - Pos; + UInt32 remain = Size - Pos; if (size > remain) size = remain; - for (UINT32 i = 0; i < size; i++) + for (UInt32 i = 0; i < size; i++) { - ((BYTE *)data)[i] = Data[Pos + i]; + ((Byte *)data)[i] = Data[Pos + i]; } Pos += size; if(processedSize != NULL) @@ -517,7 +517,7 @@ STDMETHODIMP CBenchmarkInStream::Read(void *data, UINT32 size, UINT32 *processed return S_OK; } -STDMETHODIMP CBenchmarkInStream::ReadPart(void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CBenchmarkInStream::ReadPart(void *data, UInt32 size, UInt32 *processedSize) { return Read(data, size, processedSize); } @@ -526,30 +526,30 @@ class CBenchmarkOutStream: public ISequentialOutStream, public CMyUnknownImp { - UINT32 BufferSize; + UInt32 BufferSize; public: - UINT32 Pos; - BYTE *Buffer; + UInt32 Pos; + Byte *Buffer; CBenchmarkOutStream(): Buffer(0) {} ~CBenchmarkOutStream() { delete []Buffer; } - void Init(UINT32 bufferSize) + void Init(UInt32 bufferSize) { delete []Buffer; Buffer = 0; - Buffer = new BYTE[bufferSize]; + Buffer = new Byte[bufferSize]; Pos = 0; BufferSize = bufferSize; } MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize); - STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize); + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); }; -STDMETHODIMP CBenchmarkOutStream::Write(const void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) { - UINT32 i; + UInt32 i; for (i = 0; i < size && Pos < BufferSize; i++) - Buffer[Pos++] = ((const BYTE *)data)[i]; + Buffer[Pos++] = ((const Byte *)data)[i]; if(processedSize != NULL) *processedSize = i; if (i != size) @@ -560,7 +560,7 @@ STDMETHODIMP CBenchmarkOutStream::Write(const void *data, UINT32 size, UINT32 *p return S_OK; } -STDMETHODIMP CBenchmarkOutStream::WritePart(const void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CBenchmarkOutStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize) { return Write(data, size, processedSize); } @@ -573,11 +573,11 @@ public: CCRC CRC; MY_UNKNOWN_IMP void Init() { CRC.Init(); } - STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize); - STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize); + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); }; -STDMETHODIMP CCompareOutStream::Write(const void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CCompareOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) { CRC.Update(data, size); if(processedSize != NULL) @@ -585,12 +585,12 @@ STDMETHODIMP CCompareOutStream::Write(const void *data, UINT32 size, UINT32 *pro return S_OK; } -STDMETHODIMP CCompareOutStream::WritePart(const void *data, UINT32 size, UINT32 *processedSize) +STDMETHODIMP CCompareOutStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize) { return Write(data, size, processedSize); } -typedef UINT32 (WINAPI * CreateObjectPointer)(const GUID *clsID, +typedef UInt32 (WINAPI * CreateObjectPointer)(const GUID *clsID, const GUID *interfaceID, void **outObject); struct CDecoderProgressInfo: @@ -599,11 +599,11 @@ struct CDecoderProgressInfo: { CProgressSyncInfo *SyncInfo; MY_UNKNOWN_IMP - STDMETHOD(SetRatioInfo)(const UINT64 *inSize, const UINT64 *outSize); + STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); }; STDMETHODIMP CDecoderProgressInfo::SetRatioInfo( - const UINT64 *inSize, const UINT64 *outSize) + const UInt64 *inSize, const UInt64 *outSize) { NSynchronization::CCriticalSectionLock lock(SyncInfo->CS); if (SyncInfo->Changed) @@ -616,8 +616,8 @@ struct CThreadBenchmark: public CMyUnknownImp { CProgressSyncInfo *SyncInfo; - UINT64 _startTime; - UINT64 _approvedStart; + UInt64 _startTime; + UInt64 _approvedStart; NDLL::CLibrary Library; CMyComPtr<ICompressCoder> Encoder; CMyComPtr<ICompressCoder> Decoder; @@ -627,7 +627,7 @@ struct CThreadBenchmark: return ((CThreadBenchmark *)param)->Process(); } MY_UNKNOWN_IMP - STDMETHOD(SetRatioInfo)(const UINT64 *inSize, const UINT64 *outSize); + STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); }; DWORD CThreadBenchmark::Process() @@ -640,9 +640,9 @@ DWORD CThreadBenchmark::Process() CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties; Encoder.QueryInterface(IID_ICompressWriteCoderProperties, &writeCoderProperties); - CMyComPtr<ICompressSetDecoderProperties> compressSetDecoderProperties; + CMyComPtr<ICompressSetDecoderProperties2> compressSetDecoderProperties; Decoder.QueryInterface( - IID_ICompressSetDecoderProperties, &compressSetDecoderProperties); + IID_ICompressSetDecoderProperties2, &compressSetDecoderProperties); CSequentialOutStreamImp *propStreamSpec = 0; CMyComPtr<ISequentialOutStream> propStream; if (writeCoderProperties != NULL) @@ -655,14 +655,6 @@ DWORD CThreadBenchmark::Process() Encoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties); - CBenchmarkInStream *propDecoderStreamSpec = 0; - CMyComPtr<ISequentialInStream> propDecoderStream; - if (compressSetDecoderProperties) - { - propDecoderStreamSpec = new CBenchmarkInStream; - propDecoderStream = propDecoderStreamSpec; - } - CDecoderProgressInfo *decoderProgressInfoSpec = new CDecoderProgressInfo; CMyComPtr<ICompressProgressInfo> decoderProgress = decoderProgressInfoSpec; @@ -677,7 +669,7 @@ DWORD CThreadBenchmark::Process() Sleep(200); continue; } - UINT32 dictionarySize; + UInt32 dictionarySize; bool multiThread; { NSynchronization::CCriticalSectionLock lock(SyncInfo->CS); @@ -687,8 +679,8 @@ DWORD CThreadBenchmark::Process() SyncInfo->Init(); } - const UINT32 kBufferSize = dictionarySize + kAdditionalSize; - const UINT32 kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize; + const UInt32 kBufferSize = dictionarySize + kAdditionalSize; + const UInt32 kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize; if (setCoderProperties) { @@ -699,7 +691,7 @@ DWORD CThreadBenchmark::Process() }; const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]); NWindows::NCOM::CPropVariant properties[kNumProps]; - properties[0] = UINT32(dictionarySize); + properties[0] = UInt32(dictionarySize); properties[1] = bool(multiThread); RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, kNumProps)); @@ -733,8 +725,8 @@ DWORD CThreadBenchmark::Process() _approvedStart = dictionarySize; _startTime = ::GetTimeCount(); HRESULT result = Encoder->Code(inStream, outStream, 0, 0, this); - UINT64 tickCount = ::GetTimeCount() - _startTime; - UINT32 compressedSize = outStreamSpec->Pos; + UInt64 tickCount = ::GetTimeCount() - _startTime; + UInt32 compressedSize = outStreamSpec->Pos; { NSynchronization::CCriticalSectionLock lock(SyncInfo->CS); if (result == S_OK) @@ -778,13 +770,12 @@ DWORD CThreadBenchmark::Process() if (compressSetDecoderProperties) { - propDecoderStreamSpec->Init( - propStreamSpec->GetBuffer(), propStreamSpec->GetSize()); - RINOK(compressSetDecoderProperties->SetDecoderProperties(propDecoderStream)); + RINOK(compressSetDecoderProperties->SetDecoderProperties2( + propStreamSpec->GetBuffer(), propStreamSpec->GetSize())); } - UINT64 outSize = kBufferSize; - UINT64 startTime = ::GetTimeCount(); + UInt64 outSize = kBufferSize; + UInt64 startTime = ::GetTimeCount(); result = Decoder->Code(inStream, outCompareStream, 0, &outSize, decoderProgress); tickCount = ::GetTimeCount() - startTime; { @@ -827,7 +818,7 @@ DWORD CThreadBenchmark::Process() } STDMETHODIMP CThreadBenchmark::SetRatioInfo( - const UINT64 *inSize, const UINT64 *outSize) + const UInt64 *inSize, const UInt64 *outSize) { NSynchronization::CCriticalSectionLock lock(SyncInfo->CS); if (SyncInfo->Changed || SyncInfo->WasPaused() || SyncInfo->WasStopped()) @@ -838,7 +829,7 @@ STDMETHODIMP CThreadBenchmark::SetRatioInfo( ci.Time = ::GetTimeCount() - _startTime; SyncInfo->ProcessedSize = *inSize; - UINT64 deltaTime = ci.Time - SyncInfo->CompressingInfoPrev.Time; + UInt64 deltaTime = ci.Time - SyncInfo->CompressingInfoPrev.Time; if (deltaTime >= GetFreq()) { SyncInfo->CompressingInfoTemp.Time = deltaTime; @@ -859,8 +850,8 @@ static bool GetCoderPath(UString &path) return true; } -typedef UINT32 (WINAPI *GetMethodPropertyFunc)( - UINT32 index, PROPID propID, PROPVARIANT *value); +typedef UInt32 (WINAPI *GetMethodPropertyFunc)( + UInt32 index, PROPID propID, PROPVARIANT *value); static bool LoadCoder( const UString &filePath, diff --git a/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.h b/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.h index a70fd621..e26e4a2b 100755 --- a/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.h +++ b/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.h @@ -1,7 +1,5 @@ // BenchmarkDialog.h -#pragma once - #ifndef __BENCHMARKDIALOG_H #define __BENCHMARKDIALOG_H diff --git a/7zip/FileManager/Resource/ComboDialog/ComboDialog.h b/7zip/FileManager/Resource/ComboDialog/ComboDialog.h index 29cc789c..438b9998 100755 --- a/7zip/FileManager/Resource/ComboDialog/ComboDialog.h +++ b/7zip/FileManager/Resource/ComboDialog/ComboDialog.h @@ -1,7 +1,5 @@ // ComboDialog.h -#pragma once - #ifndef __COMBODIALOG_H #define __COMBODIALOG_H @@ -20,7 +18,6 @@ public: UString Static; UString Value; CSysStringVector Strings; - // CComboDialog(): Sorted(false) {}; INT_PTR Create(HWND parentWindow = 0) { return CModalDialog::Create(MAKEINTRESOURCE(IDD_DIALOG_COMBO), parentWindow); } diff --git a/7zip/FileManager/Resource/CopyDialog/CopyDialog.cpp b/7zip/FileManager/Resource/CopyDialog/CopyDialog.cpp index b36ba93a..4c1af363 100755 --- a/7zip/FileManager/Resource/CopyDialog/CopyDialog.cpp +++ b/7zip/FileManager/Resource/CopyDialog/CopyDialog.cpp @@ -38,15 +38,15 @@ bool CCopyDialog::OnInit() return CModalDialog::OnInit(); } -bool CCopyDialog::OnButtonClicked(int aButtonID, HWND buttonHWND) +bool CCopyDialog::OnButtonClicked(int buttonID, HWND buttonHWND) { - switch(aButtonID) + switch(buttonID) { case IDC_COPY_SET_PATH: OnButtonSetPath(); return true; } - return CModalDialog::OnButtonClicked(aButtonID, buttonHWND); + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); } void CCopyDialog::OnButtonSetPath() diff --git a/7zip/FileManager/Resource/CopyDialog/CopyDialog.h b/7zip/FileManager/Resource/CopyDialog/CopyDialog.h index 1db2f87b..4d3956a9 100755 --- a/7zip/FileManager/Resource/CopyDialog/CopyDialog.h +++ b/7zip/FileManager/Resource/CopyDialog/CopyDialog.h @@ -1,7 +1,5 @@ // CopyDialog.h -#pragma once - #ifndef __COPYDIALOG_H #define __COPYDIALOG_H diff --git a/7zip/FileManager/Resource/EditPage/EditPage.h b/7zip/FileManager/Resource/EditPage/EditPage.h index fb8e1ab9..26999dcf 100755 --- a/7zip/FileManager/Resource/EditPage/EditPage.h +++ b/7zip/FileManager/Resource/EditPage/EditPage.h @@ -1,7 +1,5 @@ // EditPage.h -#pragma once - #ifndef __EDITPAGE_H #define __EDITPAGE_H diff --git a/7zip/FileManager/Resource/LangPage/LangPage.cpp b/7zip/FileManager/Resource/LangPage/LangPage.cpp index 3563a02d..88d3482d 100755 --- a/7zip/FileManager/Resource/LangPage/LangPage.cpp +++ b/7zip/FileManager/Resource/LangPage/LangPage.cpp @@ -47,12 +47,19 @@ bool CLangPage::OnInit() continue; CLang lang; UString filePath = folderPath + fileInfo.Name; + UString shortName; + const kExtSize = 4; + if (fileInfo.Name.Right(kExtSize) != L".txt") + continue; + shortName = fileInfo.Name.Left(fileInfo.Name.Length() - kExtSize); if (lang.Open(GetSystemString(filePath))) { UString name; UString englishName, nationalName; if (lang.GetMessage(0x00000000, englishName)) - name += englishName; + name = englishName; + else + name = shortName; if (lang.GetMessage(0x00000001, nationalName)) { if (!nationalName.IsEmpty()) @@ -62,12 +69,11 @@ bool CLangPage::OnInit() name += L")"; } } - if (name.IsEmpty()) - name = fileInfo.Name; index = _langCombo.AddString(GetSystemString(name)); _langCombo.SetItemData(index, _paths.Size()); - _paths.Add(GetSystemString(filePath)); - if (g_LangPath.CollateNoCase(GetSystemString(filePath)) == 0) + _paths.Add(GetSystemString(shortName)); + if (g_LangID.CollateNoCase(GetSystemString(shortName)) == 0 || + g_LangID.CollateNoCase(GetSystemString(filePath)) == 0) _langCombo.SetCurSel(index); } } diff --git a/7zip/FileManager/Resource/LangPage/LangPage.h b/7zip/FileManager/Resource/LangPage/LangPage.h index 4838e429..d30cbe49 100755 --- a/7zip/FileManager/Resource/LangPage/LangPage.h +++ b/7zip/FileManager/Resource/LangPage/LangPage.h @@ -1,7 +1,5 @@ // LangPage.h -#pragma once - #ifndef __LANGPAGE_H #define __LANGPAGE_H diff --git a/7zip/FileManager/Resource/ListViewDialog/ListViewDialog.h b/7zip/FileManager/Resource/ListViewDialog/ListViewDialog.h index dda9ea42..5c93e07d 100755 --- a/7zip/FileManager/Resource/ListViewDialog/ListViewDialog.h +++ b/7zip/FileManager/Resource/ListViewDialog/ListViewDialog.h @@ -1,7 +1,5 @@ // ListViewDialog.h -#pragma once - #ifndef __LISTVIEWDIALOG_H #define __LISTVIEWDIALOG_H diff --git a/7zip/FileManager/Resource/MessagesDialog/MessagesDialog.cpp b/7zip/FileManager/Resource/MessagesDialog/MessagesDialog.cpp index f8bc20ef..3ea94809 100755 --- a/7zip/FileManager/Resource/MessagesDialog/MessagesDialog.cpp +++ b/7zip/FileManager/Resource/MessagesDialog/MessagesDialog.cpp @@ -4,8 +4,6 @@ #include "MessagesDialog.h" #include "Windows/ResourceString.h" -// #include "../resource.h" - #ifdef LANG #include "../../LangUtils.h" #endif @@ -19,7 +17,7 @@ static CIDLangPair kIDLangPairs[] = }; #endif -void CMessagesDialog::AddMessage(LPCTSTR aMessage) +void CMessagesDialog::AddMessageDirect(LPCTSTR message) { int itemIndex = _messageList.GetItemCount(); LVITEM item; @@ -36,11 +34,25 @@ void CMessagesDialog::AddMessage(LPCTSTR aMessage) _messageList.InsertItem(&item); item.mask = LVIF_TEXT; - item.pszText = (LPTSTR)aMessage; + item.pszText = (LPTSTR)message; item.iSubItem = 1; _messageList.SetItem(&item); } +void CMessagesDialog::AddMessage(LPCTSTR message) +{ + CSysString s = message; + while (!s.IsEmpty()) + { + int pos = s.Find(TEXT('\n')); + if (pos < 0) + break; + AddMessageDirect(s.Left(pos)); + s.Delete(0, pos + 1); + } + AddMessageDirect(s); +} + bool CMessagesDialog::OnInit() { #ifdef LANG @@ -73,8 +85,8 @@ bool CMessagesDialog::OnInit() _messageList.InsertColumn(1, &columnInfo); - for(int i = 0; i < _messages->Size(); i++) - AddMessage((*_messages)[i]); + for(int i = 0; i < Messages->Size(); i++) + AddMessage((*Messages)[i]); /* if(_messageList.GetItemCount() > 0) diff --git a/7zip/FileManager/Resource/MessagesDialog/MessagesDialog.h b/7zip/FileManager/Resource/MessagesDialog/MessagesDialog.h index 81b0fcbb..14393d13 100755 --- a/7zip/FileManager/Resource/MessagesDialog/MessagesDialog.h +++ b/7zip/FileManager/Resource/MessagesDialog/MessagesDialog.h @@ -1,7 +1,5 @@ // MessagesDialog.h -#pragma once - #ifndef __MESSAGESDIALOG_H #define __MESSAGESDIALOG_H @@ -13,10 +11,11 @@ class CMessagesDialog: public NWindows::NControl::CModalDialog { NWindows::NControl::CListView _messageList; - void AddMessage(LPCTSTR string); + void AddMessageDirect(LPCTSTR message); + void AddMessage(LPCTSTR message); virtual bool OnInit(); public: - const CSysStringVector *_messages; + const CSysStringVector *Messages; INT_PTR Create(HWND parentWindow = 0) { return CModalDialog::Create(MAKEINTRESOURCE(IDD_DIALOG_MESSAGES), parentWindow); } }; diff --git a/7zip/FileManager/Resource/MessagesDialog/resource.h b/7zip/FileManager/Resource/MessagesDialog/resource.h index 4f23ac83..1a886be5 100755 --- a/7zip/FileManager/Resource/MessagesDialog/resource.h +++ b/7zip/FileManager/Resource/MessagesDialog/resource.h @@ -3,7 +3,7 @@ // Used by resource.rc // -#define IDS_MESSAGES_DIALOG_MESSAGE_COLUMN 11 +#define IDS_MESSAGES_DIALOG_MESSAGE_COLUMN 503 #define IDD_DIALOG_MESSAGES 503 @@ -14,7 +14,7 @@ // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 157 +#define _APS_NEXT_RESOURCE_VALUE 657 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1002 #define _APS_NEXT_SYMED_VALUE 101 diff --git a/7zip/FileManager/Resource/MessagesDialog/resource.rc b/7zip/FileManager/Resource/MessagesDialog/resource.rc index ff35395e..019ae5d3 100755 --- a/7zip/FileManager/Resource/MessagesDialog/resource.rc +++ b/7zip/FileManager/Resource/MessagesDialog/resource.rc @@ -84,7 +84,6 @@ END #ifdef APSTUDIO_INVOKED GUIDELINES DESIGNINFO DISCARDABLE BEGIN - IDD_DIALOG_MESSAGES, DIALOG BEGIN LEFTMARGIN, 7 @@ -92,8 +91,9 @@ BEGIN TOPMARGIN, 7 BOTTOMMARGIN, 128 END - END +#endif // APSTUDIO_INVOKED + ///////////////////////////////////////////////////////////////////////////// // @@ -105,9 +105,6 @@ BEGIN IDS_MESSAGES_DIALOG_MESSAGE_COLUMN "Message" END - -#endif // APSTUDIO_INVOKED - #endif // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/7zip/FileManager/Resource/OverwriteDialog/OverwriteDialog.cpp b/7zip/FileManager/Resource/OverwriteDialog/OverwriteDialog.cpp index 8ebeeb01..1232b0db 100755 --- a/7zip/FileManager/Resource/OverwriteDialog/OverwriteDialog.cpp +++ b/7zip/FileManager/Resource/OverwriteDialog/OverwriteDialog.cpp @@ -67,7 +67,7 @@ void COverwriteDialog::SetFileInfoControl(int textID, int iconID, FILETIME localFileTime; if (!FileTimeToLocalFileTime(&fileInfo.Time, &localFileTime)) throw 4190402; - timeString = ConvertFileTimeToString2(localFileTime); + timeString = ConvertFileTimeToString(localFileTime); fullString += #ifdef LANG diff --git a/7zip/FileManager/Resource/OverwriteDialog/OverwriteDialog.h b/7zip/FileManager/Resource/OverwriteDialog/OverwriteDialog.h index de5f0f18..329d85ea 100755 --- a/7zip/FileManager/Resource/OverwriteDialog/OverwriteDialog.h +++ b/7zip/FileManager/Resource/OverwriteDialog/OverwriteDialog.h @@ -1,7 +1,5 @@ // OverwriteDialog.h -#pragma once - #ifndef __OVERWRITEDIALOG_H #define __OVERWRITEDIALOG_H diff --git a/7zip/FileManager/Resource/PasswordDialog/PasswordDialog.cpp b/7zip/FileManager/Resource/PasswordDialog/PasswordDialog.cpp index b2f9536c..2a6a2727 100755 --- a/7zip/FileManager/Resource/PasswordDialog/PasswordDialog.cpp +++ b/7zip/FileManager/Resource/PasswordDialog/PasswordDialog.cpp @@ -24,7 +24,7 @@ bool CPasswordDialog::OnInit() LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); #endif _passwordControl.Attach(GetItem(IDC_EDIT_PASSWORD)); - _passwordControl.SetText(_password); + _passwordControl.SetText(Password); _passwordControl.SetPasswordChar(TEXT('*')); return CModalDialog::OnInit(); } @@ -45,6 +45,6 @@ bool CPasswordDialog::OnButtonClicked(int buttonID, HWND buttonHWND) void CPasswordDialog::OnOK() { - _passwordControl.GetText(_password); + _passwordControl.GetText(Password); CModalDialog::OnOK(); } diff --git a/7zip/FileManager/Resource/PasswordDialog/PasswordDialog.h b/7zip/FileManager/Resource/PasswordDialog/PasswordDialog.h index e890aefa..481050a0 100755 --- a/7zip/FileManager/Resource/PasswordDialog/PasswordDialog.h +++ b/7zip/FileManager/Resource/PasswordDialog/PasswordDialog.h @@ -1,7 +1,5 @@ // PasswordDialog.h -#pragma once - #ifndef __PASSWORDDIALOG_H #define __PASSWORDDIALOG_H @@ -16,7 +14,7 @@ class CPasswordDialog: public NWindows::NControl::CModalDialog virtual bool OnInit(); virtual bool OnButtonClicked(int buttonID, HWND buttonHWND); public: - CSysString _password; + UString Password; INT_PTR Create(HWND parentWindow = 0) { return CModalDialog::Create(MAKEINTRESOURCE(IDD_DIALOG_PASSWORD), parentWindow); } }; diff --git a/7zip/FileManager/Resource/PluginsPage/PluginsPage.h b/7zip/FileManager/Resource/PluginsPage/PluginsPage.h index ec4cecb2..3c31bbc4 100755 --- a/7zip/FileManager/Resource/PluginsPage/PluginsPage.h +++ b/7zip/FileManager/Resource/PluginsPage/PluginsPage.h @@ -1,7 +1,5 @@ // PluginsPage.h -#pragma once - #include "Windows/Control/ListView.h" #ifndef __PLUGINSPAGE_H diff --git a/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.cpp b/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.cpp index 16a59cf5..1e0fd392 100755 --- a/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.cpp +++ b/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.cpp @@ -61,7 +61,7 @@ void CProgressDialog::OnCancel() void CProgressDialog::SetRange(UINT64 range) { _range = range; - _peviousPos = _UI64_MAX; + _peviousPos = (UInt64)(Int64)-1; _converter.Init(range); m_ProgressBar.SetRange32(0 , _converter.Count(range)); // Test it for 100% } @@ -99,7 +99,7 @@ bool CProgressDialog::OnTimer(WPARAM timerID, LPARAM callback) if (percentValue != _prevPercentValue) { wchar_t s[64]; - ConvertUINT64ToString(percentValue, s); + ConvertUInt64ToString(percentValue, s); UString title = s; title += L"% "; SetText(title + _title); diff --git a/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.h b/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.h index e56b3b67..4ed48519 100755 --- a/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.h +++ b/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.h @@ -1,7 +1,5 @@ // ProgressDialog.h -#pragma once - #ifndef __PROGRESSDIALOG_H #define __PROGRESSDIALOG_H diff --git a/7zip/FileManager/Resource/ProgressDialog2/ProgressDialog.cpp b/7zip/FileManager/Resource/ProgressDialog2/ProgressDialog.cpp index 678db72a..0ed2960e 100755 --- a/7zip/FileManager/Resource/ProgressDialog2/ProgressDialog.cpp +++ b/7zip/FileManager/Resource/ProgressDialog2/ProgressDialog.cpp @@ -29,6 +29,20 @@ static CIDLangPair kIDLangPairs[] = }; #endif +HRESULT CProgressSynch::SetPosAndCheckPaused(UInt64 completed) +{ + while(true) + { + if(GetStopped()) + return E_ABORT; + if(!GetPaused()) + break; + ::Sleep(100); + } + SetPos(completed); + return S_OK; +} + #ifndef _SFX CProgressDialog::~CProgressDialog() { @@ -42,17 +56,26 @@ void CProgressDialog::AddToTitle(LPCWSTR s) window.SetText(s + UString(MainTitle)); } } + +static const int kTitleFileNameSizeLimit = 36; +static const int kCurrentFileNameSizeLimit = 68; + +static void ReduceString(UString &s, int size) +{ + if (s.Length() > size) + s = s.Left(size / 2) + UString(L" ... ") + s.Right(size / 2); +} #endif bool CProgressDialog::OnInit() { - _range = UINT64(-1); - _prevPercentValue = UINT32(-1); - _prevElapsedSec = UINT32(-1); - _prevRemainingSec = UINT32(-1); - _prevSpeed = UINT32(-1); + _range = UInt64(-1); + _prevPercentValue = UInt32(-1); + _prevElapsedSec = UInt32(-1); + _prevRemainingSec = UInt32(-1); + _prevSpeed = UInt32(-1); _prevMode = kSpeedBytes; - _pevTime = ::GetTickCount(); + _prevTime = ::GetTickCount(); _elapsedTime = 0; _foreground = true; @@ -88,35 +111,35 @@ void CProgressDialog::OnCancel() ProgressSynch.SetStopped(true); } -static void ConvertSizeToString(UINT64 value, wchar_t *s) +static void ConvertSizeToString(UInt64 value, wchar_t *s) { - if (value < (UINT64(10000) << 0)) + if (value < (UInt64(10000) << 0)) { - ConvertUINT64ToString(value, s); + ConvertUInt64ToString(value, s); lstrcatW(s, L" B"); return; } - if (value < (UINT64(10000) << 10)) + if (value < (UInt64(10000) << 10)) { - ConvertUINT64ToString((value >> 10), s); + ConvertUInt64ToString((value >> 10), s); lstrcatW(s, L" KB"); return; } - if (value < (UINT64(10000) << 20)) + if (value < (UInt64(10000) << 20)) { - ConvertUINT64ToString((value >> 20), s); + ConvertUInt64ToString((value >> 20), s); lstrcatW(s, L" MB"); return; } - ConvertUINT64ToString((value >> 30), s); + ConvertUInt64ToString((value >> 30), s); lstrcatW(s, L" GB"); return; } -void CProgressDialog::SetRange(UINT64 range) +void CProgressDialog::SetRange(UInt64 range) { _range = range; - _previousPos = _UI64_MAX; + _previousPos = (UInt64)(Int64)-1; _converter.Init(range); m_ProgressBar.SetRange32(0 , _converter.Count(range)); // Test it for 100% @@ -125,7 +148,7 @@ void CProgressDialog::SetRange(UINT64 range) SetItemText(IDC_PROGRESS_SPEED_TOTAL_VALUE, s); } -void CProgressDialog::SetPos(UINT64 pos) +void CProgressDialog::SetPos(UInt64 pos) { bool redraw = true; if (pos < _range && pos > _previousPos) @@ -140,31 +163,31 @@ void CProgressDialog::SetPos(UINT64 pos) } } -static void GetTimeString(UINT64 timeValue, TCHAR *s) +static void GetTimeString(UInt64 timeValue, TCHAR *s) { wsprintf(s, TEXT("%02d:%02d:%02d"), - UINT32(timeValue / 3600), - UINT32((timeValue / 60) % 60), - UINT32(timeValue % 60)); + UInt32(timeValue / 3600), + UInt32((timeValue / 60) % 60), + UInt32(timeValue % 60)); } bool CProgressDialog::OnTimer(WPARAM timerID, LPARAM callback) { if (ProgressSynch.GetPaused()) return true; - UINT64 total, completed; + UInt64 total, completed; ProgressSynch.GetProgress(total, completed); - UINT32 curTime = ::GetTickCount(); + UInt32 curTime = ::GetTickCount(); if (total != _range) SetRange(total); SetPos(completed); - _elapsedTime += (curTime - _pevTime); - _pevTime = curTime; + _elapsedTime += (curTime - _prevTime); + _prevTime = curTime; - UINT32 elapsedSec = _elapsedTime / 1000; + UInt32 elapsedSec = _elapsedTime / 1000; bool elapsedChanged = false; if (elapsedSec != _prevElapsedSec) @@ -178,10 +201,10 @@ bool CProgressDialog::OnTimer(WPARAM timerID, LPARAM callback) if (completed != 0 && elapsedChanged) { - UINT64 remainingTime = 0; + UInt64 remainingTime = 0; if (completed < total) remainingTime = _elapsedTime * (total - completed) / completed; - UINT64 remainingSec = remainingTime / 1000; + UInt64 remainingSec = remainingTime / 1000; if (remainingSec != _prevRemainingSec) { TCHAR s[40]; @@ -191,17 +214,17 @@ bool CProgressDialog::OnTimer(WPARAM timerID, LPARAM callback) } // if (elapsedChanged) { - UINT64 speedB = (completed * 1000) / _elapsedTime; - UINT64 speedKB = speedB / 1024; - UINT64 speedMB = speedKB / 1024; - const UINT32 kLimit1 = 10; + UInt64 speedB = (completed * 1000) / _elapsedTime; + UInt64 speedKB = speedB / 1024; + UInt64 speedMB = speedKB / 1024; + const UInt32 kLimit1 = 10; TCHAR s[40]; bool needRedraw = false; if (speedMB >= kLimit1) { if (_prevMode != kSpeedMBytes || speedMB != _prevSpeed) { - ConvertUINT64ToString(speedMB, s); + ConvertUInt64ToString(speedMB, s); lstrcat(s, TEXT(" MB/s")); _prevMode = kSpeedMBytes; _prevSpeed = speedMB; @@ -212,7 +235,7 @@ bool CProgressDialog::OnTimer(WPARAM timerID, LPARAM callback) { if (_prevMode != kSpeedKBytes || speedKB != _prevSpeed) { - ConvertUINT64ToString(speedKB, s); + ConvertUInt64ToString(speedKB, s); lstrcat(s, TEXT(" KB/s")); _prevMode = kSpeedKBytes; _prevSpeed = speedKB; @@ -223,7 +246,7 @@ bool CProgressDialog::OnTimer(WPARAM timerID, LPARAM callback) { if (_prevMode != kSpeedBytes || speedB != _prevSpeed) { - ConvertUINT64ToString(speedB, s); + ConvertUInt64ToString(speedB, s); lstrcat(s, TEXT(" B/s")); _prevMode = kSpeedBytes; _prevSpeed = speedB; @@ -237,24 +260,24 @@ bool CProgressDialog::OnTimer(WPARAM timerID, LPARAM callback) if (total == 0) total = 1; - UINT32 percentValue = (UINT32)(completed * 100 / total); - if (percentValue != _prevPercentValue) + UInt32 percentValue = (UInt32)(completed * 100 / total); + UString titleName; + ProgressSynch.GetTitleFileName(titleName); + if (percentValue != _prevPercentValue || _prevTitleName != titleName) { - wchar_t s[64]; - ConvertUINT64ToString(percentValue, s); - UString title = s; - title += L"% "; - if (!_foreground) - { - title += backgroundedString; - title += L" "; - } - SetText(title + _title); - #ifndef _SFX - AddToTitle(title + MainAddTitle); - #endif _prevPercentValue = percentValue; + SetTitleText(); + _prevTitleName = titleName; + } + UString fileName; + ProgressSynch.GetCurrentFileName(fileName); + if (_prevFileName != fileName) + { + ReduceString(fileName, kCurrentFileNameSizeLimit); + SetItemText(IDC_PROGRESS_FILE_NAME, fileName); + _prevFileName == fileName; } + return true; } @@ -262,9 +285,9 @@ bool CProgressDialog::OnTimer(WPARAM timerID, LPARAM callback) //////////////////// // CU64ToI32Converter -static const UINT64 kMaxIntValue = 0x7FFFFFFF; +static const UInt64 kMaxIntValue = 0x7FFFFFFF; -void CU64ToI32Converter::Init(UINT64 range) +void CU64ToI32Converter::Init(UInt64 range) { _numShiftBits = 0; while(range > kMaxIntValue) @@ -274,7 +297,7 @@ void CU64ToI32Converter::Init(UINT64 range) } } -int CU64ToI32Converter::Count(UINT64 aValue) +int CU64ToI32Converter::Count(UInt64 aValue) { return int(aValue >> _numShiftBits); } @@ -301,23 +324,54 @@ bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) return CModalDialog::OnMessage(message, wParam, lParam); } +void CProgressDialog::SetTitleText() +{ + UString title; + if (ProgressSynch.GetPaused()) + { + title = pausedString; + title += L" "; + } + wchar_t s[64]; + ConvertUInt64ToString(_prevPercentValue, s); + title += s; + title += L"%"; + if (!_foreground) + { + title += L" "; + title += backgroundedString; + } + title += L" "; + UString totalTitle = title + _title; + UString fileName; + ProgressSynch.GetTitleFileName(fileName); + if (!fileName.IsEmpty()) + { + ReduceString(fileName, kTitleFileNameSizeLimit); + totalTitle += L" "; + totalTitle += fileName; + } + SetText(totalTitle); + #ifndef _SFX + AddToTitle(title + MainAddTitle); + #endif +} + void CProgressDialog::SetPauseText() { SetItemText(IDC_BUTTON_PAUSE, ProgressSynch.GetPaused() ? continueString : pauseString); - - SetText(LangLoadStringW(IDS_PROGRESS_PAUSED, 0x02000C20) + - UString(L" ") + _title); + SetTitleText(); } void CProgressDialog::OnPauseButton() { bool paused = !ProgressSynch.GetPaused(); ProgressSynch.SetPaused(paused); - UINT32 curTime = ::GetTickCount(); + UInt32 curTime = ::GetTickCount(); if (paused) - _elapsedTime += (curTime - _pevTime); - _pevTime = curTime; + _elapsedTime += (curTime - _prevTime); + _prevTime = curTime; SetPauseText(); } @@ -326,6 +380,7 @@ void CProgressDialog::SetPriorityText() SetItemText(IDC_BUTTON_PROGRESS_PRIORITY, _foreground ? backgroundString : foregroundString); + SetTitleText(); } void CProgressDialog::OnPriorityButton() diff --git a/7zip/FileManager/Resource/ProgressDialog2/ProgressDialog.h b/7zip/FileManager/Resource/ProgressDialog2/ProgressDialog.h index 40806296..713e0f29 100755 --- a/7zip/FileManager/Resource/ProgressDialog2/ProgressDialog.h +++ b/7zip/FileManager/Resource/ProgressDialog2/ProgressDialog.h @@ -1,12 +1,12 @@ // ProgressDialog.h -#pragma once - #ifndef __PROGRESSDIALOG_H #define __PROGRESSDIALOG_H #include "resource.h" +#include "Common/Types.h" + #include "Windows/Control/Dialog.h" #include "Windows/Control/ProgressBar.h" #include "Windows/Synchronization.h" @@ -16,8 +16,10 @@ class CProgressSynch NWindows::NSynchronization::CCriticalSection _criticalSection; bool _stopped; bool _paused; - UINT64 _total; - UINT64 _completed; + UInt64 _total; + UInt64 _completed; + UString TitleFileName; + UString CurrentFileName; public: CProgressSynch(): _stopped(false), _paused(false), _total(1), _completed(0) {} @@ -41,31 +43,52 @@ public: NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); _paused = value; } - void SetProgress(UINT64 total, UINT64 completed) + void SetProgress(UInt64 total, UInt64 completed) { NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); _total = total; _completed = completed; } - void SetPos(UINT64 completed) + void SetPos(UInt64 completed) { NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); _completed = completed; } - void GetProgress(UINT64 &total, UINT64 &completed) + HRESULT SetPosAndCheckPaused(UInt64 completed); + void GetProgress(UInt64 &total, UInt64 &completed) { NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); total = _total; completed = _completed; } + void SetTitleFileName(const UString &fileName) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + TitleFileName = fileName; + } + void GetTitleFileName(UString &fileName) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + fileName = TitleFileName; + } + void SetCurrentFileName(const UString &fileName) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + CurrentFileName = fileName; + } + void GetCurrentFileName(UString &fileName) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + fileName = CurrentFileName; + } }; class CU64ToI32Converter { - UINT64 _numShiftBits; + UInt64 _numShiftBits; public: - void Init(UINT64 _range); - int Count(UINT64 aValue); + void Init(UInt64 _range); + int Count(UInt64 aValue); }; // class CProgressDialog: public NWindows::NControl::CModelessDialog @@ -79,6 +102,8 @@ enum ESpeedMode class CProgressDialog: public NWindows::NControl::CModalDialog { + UString _prevFileName; + UString _prevTitleName; private: UString backgroundString; UString backgroundedString; @@ -93,23 +118,23 @@ private: UString _title; CU64ToI32Converter _converter; - UINT64 _previousPos; - UINT64 _range; + UInt64 _previousPos; + UInt64 _range; NWindows::NControl::CProgressBar m_ProgressBar; - UINT32 _prevPercentValue; - UINT32 _pevTime; - UINT32 _elapsedTime; - UINT32 _prevElapsedSec; - UINT64 _prevRemainingSec; + UInt32 _prevPercentValue; + UInt32 _prevTime; + UInt32 _elapsedTime; + UInt32 _prevElapsedSec; + UInt64 _prevRemainingSec; ESpeedMode _prevMode; - UINT64 _prevSpeed; + UInt64 _prevSpeed; bool _foreground; bool OnTimer(WPARAM timerID, LPARAM callback); - void SetRange(UINT64 range); - void SetPos(UINT64 pos); + void SetRange(UInt64 range); + void SetPos(UInt64 pos); virtual bool OnInit(); virtual void OnCancel(); NWindows::NSynchronization::CManualResetEvent _dialogCreatedEvent; @@ -122,6 +147,8 @@ private: void OnPauseButton(); void OnPriorityButton(); bool OnButtonClicked(int buttonID, HWND buttonHWND); + + void SetTitleText(); public: CProgressSynch ProgressSynch; @@ -134,7 +161,7 @@ public: CProgressDialog(): _timer(0) #ifndef _SFX - ,MainWindow(0) + ,MainWindow(0) #endif {} @@ -151,10 +178,7 @@ public: virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam); - void MyClose() - { - PostMessage(kCloseMessage); - }; + void MyClose() { PostMessage(kCloseMessage); }; }; #endif diff --git a/7zip/FileManager/Resource/ProgressDialog2/resource.h b/7zip/FileManager/Resource/ProgressDialog2/resource.h index f13a7c2b..07febd92 100755 --- a/7zip/FileManager/Resource/ProgressDialog2/resource.h +++ b/7zip/FileManager/Resource/ProgressDialog2/resource.h @@ -5,6 +5,10 @@ #define IDC_BUTTON_PAUSE 3 #define IDC_BUTTON_PROGRESS_PRIORITY 4 #define IDD_DIALOG_PROGRESS 500 +#define IDS_PROGRESS_PAUSED 700 +#define IDS_PROGRESS_FOREGROUND 701 +#define IDS_PROGRESS_CONTINUE 702 +#define IDS_PROGRESS_ASK_CANCEL 703 #define IDC_PROGRESS1 1000 #define IDC_PROGRESS_ELAPSED 1002 #define IDC_PROGRESS_ELAPSED_VALUE 1003 @@ -14,11 +18,7 @@ #define IDC_PROGRESS_SPEED_VALUE 1007 #define IDC_PROGRESS_TOTAL 1008 #define IDC_PROGRESS_SPEED_TOTAL_VALUE 1009 - -#define IDS_PROGRESS_PAUSED 700 -#define IDS_PROGRESS_FOREGROUND 701 -#define IDS_PROGRESS_CONTINUE 702 -#define IDS_PROGRESS_ASK_CANCEL 703 +#define IDC_PROGRESS_FILE_NAME 1010 // Next default values for new objects // diff --git a/7zip/FileManager/Resource/ProgressDialog2/resource.rc b/7zip/FileManager/Resource/ProgressDialog2/resource.rc index 5540e88b..b7d766ad 100755 --- a/7zip/FileManager/Resource/ProgressDialog2/resource.rc +++ b/7zip/FileManager/Resource/ProgressDialog2/resource.rc @@ -63,25 +63,26 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // Dialog // -IDD_DIALOG_PROGRESS DIALOG DISCARDABLE 0, 0, 246, 78 +IDD_DIALOG_PROGRESS DIALOG DISCARDABLE 0, 0, 304, 90 STYLE DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Progress" FONT 8, "MS Shell Dlg" BEGIN - PUSHBUTTON "&Background",IDC_BUTTON_PROGRESS_PRIORITY,7,57,72,14 - PUSHBUTTON "&Pause",IDC_BUTTON_PAUSE,92,57,72,14 - PUSHBUTTON "Cancel",IDCANCEL,175,57,64,14 - LTEXT "Elapsed time:",IDC_PROGRESS_ELAPSED,7,7,71,8 - RTEXT "00:00:00",IDC_PROGRESS_ELAPSED_VALUE,78,7,42,8 - LTEXT "Remaining time:",IDC_PROGRESS_REMAINING,7,18,71,8 - RTEXT "",IDC_PROGRESS_REMAINING_VALUE,78,18,42,8 - LTEXT "Size:",IDC_PROGRESS_TOTAL,149,7,48,8 - RTEXT "",IDC_PROGRESS_SPEED_TOTAL_VALUE,197,7,42,8 - LTEXT "Speed:",IDC_PROGRESS_SPEED,149,18,48,8 - RTEXT "",IDC_PROGRESS_SPEED_VALUE,197,18,42,8 + PUSHBUTTON "&Background",IDC_BUTTON_PROGRESS_PRIORITY,61,69,72,14 + PUSHBUTTON "&Pause",IDC_BUTTON_PAUSE,143,69,72,14 + PUSHBUTTON "Cancel",IDCANCEL,225,69,72,14 + LTEXT "Elapsed time:",IDC_PROGRESS_ELAPSED,7,7,91,8 + RTEXT "00:00:00",IDC_PROGRESS_ELAPSED_VALUE,98,7,42,8 + LTEXT "Remaining time:",IDC_PROGRESS_REMAINING,7,18,91,8 + RTEXT "",IDC_PROGRESS_REMAINING_VALUE,98,18,42,8 + LTEXT "Size:",IDC_PROGRESS_TOTAL,178,7,77,8 + RTEXT "",IDC_PROGRESS_SPEED_TOTAL_VALUE,255,7,42,8 + LTEXT "Speed:",IDC_PROGRESS_SPEED,178,18,77,8 + RTEXT "",IDC_PROGRESS_SPEED_VALUE,255,18,42,8 CONTROL "Progress1",IDC_PROGRESS1,"msctls_progress32",PBS_SMOOTH | - WS_BORDER,7,34,232,13 + WS_BORDER,7,49,290,13 + LTEXT "",IDC_PROGRESS_FILE_NAME,7,34,290,8 END @@ -96,13 +97,13 @@ BEGIN IDD_DIALOG_PROGRESS, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 239 - VERTGUIDE, 78 - VERTGUIDE, 120 - VERTGUIDE, 149 - VERTGUIDE, 197 + RIGHTMARGIN, 297 + VERTGUIDE, 98 + VERTGUIDE, 140 + VERTGUIDE, 178 + VERTGUIDE, 255 TOPMARGIN, 7 - BOTTOMMARGIN, 71 + BOTTOMMARGIN, 83 END END #endif // APSTUDIO_INVOKED diff --git a/7zip/FileManager/Resource/PropertyName/resource.h b/7zip/FileManager/Resource/PropertyName/resource.h index 40f298cd..f318905a 100755 --- a/7zip/FileManager/Resource/PropertyName/resource.h +++ b/7zip/FileManager/Resource/PropertyName/resource.h @@ -28,6 +28,7 @@ #define IDS_PROPERTY_GROUP 26 #define IDS_PROPERTY_BLOCK 27 #define IDS_PROPERTY_COMMENT 28 +#define IDS_PROPERTY_POSITION 29 // Next default values for new objects // diff --git a/7zip/FileManager/Resource/PropertyName/resource.rc b/7zip/FileManager/Resource/PropertyName/resource.rc index 6bdce925..a40362a8 100755 --- a/7zip/FileManager/Resource/PropertyName/resource.rc +++ b/7zip/FileManager/Resource/PropertyName/resource.rc @@ -95,6 +95,7 @@ BEGIN IDS_PROPERTY_GROUP "Group" IDS_PROPERTY_BLOCK "Block" IDS_PROPERTY_COMMENT "Comment" + IDS_PROPERTY_POSITION "Position" END #endif // English (U.S.) resources diff --git a/7zip/FileManager/Resource/SettingsPage/SettingsPage.cpp b/7zip/FileManager/Resource/SettingsPage/SettingsPage.cpp index c476c97a..656fc3eb 100755 --- a/7zip/FileManager/Resource/SettingsPage/SettingsPage.cpp +++ b/7zip/FileManager/Resource/SettingsPage/SettingsPage.cpp @@ -19,7 +19,11 @@ static CIDLangPair kIDLangPairs[] = { { IDC_SETTINGS_SHOW_DOTS, 0x03010401}, { IDC_SETTINGS_SHOW_REAL_FILE_ICONS, 0x03010402}, - { IDC_SETTINGS_SHOW_SYSTEM_MENU, 0x03010410} + { IDC_SETTINGS_SHOW_SYSTEM_MENU, 0x03010410}, + { IDC_SETTINGS_FULL_ROW, 0x03010420}, + { IDC_SETTINGS_SHOW_GRID, 0x03010421} + // { IDC_SETTINGS_SINGLE_CLICK, 0x03010422}, + // { IDC_SETTINGS_UNDERLINE, 0x03010423} }; static LPCWSTR kEditTopic = L"FM/options.htm#settings"; @@ -31,15 +35,36 @@ bool CSettingsPage::OnInit() CheckButton(IDC_SETTINGS_SHOW_DOTS, ReadShowDots()); CheckButton(IDC_SETTINGS_SHOW_SYSTEM_MENU, ReadShowSystemMenu()); CheckButton(IDC_SETTINGS_SHOW_REAL_FILE_ICONS, ReadShowRealFileIcons()); + + CheckButton(IDC_SETTINGS_FULL_ROW, ReadFullRow()); + CheckButton(IDC_SETTINGS_SHOW_GRID, ReadShowGrid()); + // CheckButton(IDC_SETTINGS_SINGLE_CLICK, ReadSingleClick()); + // CheckButton(IDC_SETTINGS_UNDERLINE, ReadUnderline()); + + // EnableSubItems(); + return CPropertyPage::OnInit(); } +/* +void CSettingsPage::EnableSubItems() +{ + EnableItem(IDC_SETTINGS_UNDERLINE, IsButtonCheckedBool(IDC_SETTINGS_SINGLE_CLICK)); +} +*/ + LONG CSettingsPage::OnApply() { SaveShowDots(IsButtonCheckedBool(IDC_SETTINGS_SHOW_DOTS)); SaveShowSystemMenu(IsButtonCheckedBool(IDC_SETTINGS_SHOW_SYSTEM_MENU)); SaveShowRealFileIcons(IsButtonCheckedBool(IDC_SETTINGS_SHOW_REAL_FILE_ICONS)); + SaveFullRow(IsButtonCheckedBool(IDC_SETTINGS_FULL_ROW)); + SaveShowGrid(IsButtonCheckedBool(IDC_SETTINGS_SHOW_GRID)); + + // SaveSingleClick(IsButtonCheckedBool(IDC_SETTINGS_SINGLE_CLICK)); + // SaveUnderline(IsButtonCheckedBool(IDC_SETTINGS_UNDERLINE)); + return PSNRET_NOERROR; } @@ -48,21 +73,22 @@ void CSettingsPage::OnNotifyHelp() ShowHelpWindow(NULL, kEditTopic); // change it } - -bool CSettingsPage::OnCommand(int code, int itemID, LPARAM param) -{ - if (code == EN_CHANGE && - ( - itemID == IDC_SETTINGS_SHOW_DOTS || - itemID == IDC_SETTINGS_SHOW_SYSTEM_MENU || - itemID == IDC_SETTINGS_SHOW_REAL_FILE_ICONS - ) - ) +bool CSettingsPage::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + switch(buttonID) { - Changed(); - return true; + /* + case IDC_SETTINGS_SINGLE_CLICK: + EnableSubItems(); + break; + */ + case IDC_SETTINGS_SHOW_DOTS: + case IDC_SETTINGS_SHOW_SYSTEM_MENU: + case IDC_SETTINGS_SHOW_REAL_FILE_ICONS: + case IDC_SETTINGS_FULL_ROW: + case IDC_SETTINGS_SHOW_GRID: + Changed(); + return true; } - return CPropertyPage::OnCommand(code, itemID, param); + return CPropertyPage::OnButtonClicked(buttonID, buttonHWND); } - - diff --git a/7zip/FileManager/Resource/SettingsPage/SettingsPage.h b/7zip/FileManager/Resource/SettingsPage/SettingsPage.h index f8bd5de3..e5fe6e67 100755 --- a/7zip/FileManager/Resource/SettingsPage/SettingsPage.h +++ b/7zip/FileManager/Resource/SettingsPage/SettingsPage.h @@ -1,7 +1,5 @@ // SettingsPage.h -#pragma once - #ifndef __SETTINGSPAGE_H #define __SETTINGSPAGE_H @@ -10,10 +8,11 @@ class CSettingsPage: public NWindows::NControl::CPropertyPage { + // void EnableSubItems(); + bool OnButtonClicked(int buttonID, HWND buttonHWND); public: virtual bool OnInit(); virtual void OnNotifyHelp(); - virtual bool OnCommand(int code, int itemID, LPARAM param); virtual LONG OnApply(); }; diff --git a/7zip/FileManager/Resource/SettingsPage/resource.h b/7zip/FileManager/Resource/SettingsPage/resource.h index 762ca83f..1300d440 100755 --- a/7zip/FileManager/Resource/SettingsPage/resource.h +++ b/7zip/FileManager/Resource/SettingsPage/resource.h @@ -2,10 +2,14 @@ // Microsoft Developer Studio generated include file. // Used by resource.rc // -#define IDD_SETTINGS 904 -#define IDC_SETTINGS_SHOW_DOTS 1000 +#define IDD_SETTINGS 904 +#define IDC_SETTINGS_SHOW_DOTS 1000 #define IDC_SETTINGS_SHOW_REAL_FILE_ICONS 1001 -#define IDC_SETTINGS_SHOW_SYSTEM_MENU 1010 +#define IDC_SETTINGS_SHOW_SYSTEM_MENU 1010 +#define IDC_SETTINGS_FULL_ROW 1011 +#define IDC_SETTINGS_SHOW_GRID 1013 +#define IDC_SETTINGS_SINGLE_CLICK 1014 +#define IDC_SETTINGS_UNDERLINE 1015 // Next default values for new objects // diff --git a/7zip/FileManager/Resource/SettingsPage/resource.rc b/7zip/FileManager/Resource/SettingsPage/resource.rc index d9c4f4af..021c59ba 100755 --- a/7zip/FileManager/Resource/SettingsPage/resource.rc +++ b/7zip/FileManager/Resource/SettingsPage/resource.rc @@ -70,10 +70,21 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "Show "".."" item",IDC_SETTINGS_SHOW_DOTS,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,7,7,196,10 - CONTROL "Show real file icons",IDC_SETTINGS_SHOW_REAL_FILE_ICONS, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,21,196,10 - CONTROL "Show system menu",IDC_SETTINGS_SHOW_SYSTEM_MENU,"Button", + CONTROL "Show real file &icons", + IDC_SETTINGS_SHOW_REAL_FILE_ICONS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,21,196,10 + CONTROL "Show system &menu",IDC_SETTINGS_SHOW_SYSTEM_MENU,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,7,35,196,10 + CONTROL "&Full row select",IDC_SETTINGS_FULL_ROW,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,63,196,10 + CONTROL "Show &grid lines",IDC_SETTINGS_SHOW_GRID,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,77,196,10 + CONTROL "&Single-click to open an item", + IDC_SETTINGS_SINGLE_CLICK,"Button",BS_AUTOCHECKBOX | NOT + WS_VISIBLE | WS_TABSTOP,7,91,196,10 + CONTROL "&Underline current name",IDC_SETTINGS_UNDERLINE,"Button", + BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,19,105,184, + 10 END diff --git a/7zip/FileManager/Resource/SplitDialog/SplitDialog.cpp b/7zip/FileManager/Resource/SplitDialog/SplitDialog.cpp new file mode 100755 index 00000000..014ba7ec --- /dev/null +++ b/7zip/FileManager/Resource/SplitDialog/SplitDialog.cpp @@ -0,0 +1,85 @@ +// SplitDialog.cpp + +#include "StdAfx.h" +#include "SplitDialog.h" + +#include "Common/StringToInt.h" +#include "Windows/Shell.h" +#include "Windows/FileName.h" + +#include "../../SplitUtils.h" +#ifdef LANG +#include "../../LangUtils.h" +#endif + +using namespace NWindows; + +#ifdef LANG +static CIDLangPair kIDLangPairs[] = +{ + { IDC_STATIC_SPLIT_PATH, 0x03020501 }, + { IDC_STATIC_SPLIT_VOLUME, 0x02000D40 }, +}; +#endif + + +bool CSplitDialog::OnInit() +{ + #ifdef LANG + LangSetWindowText(HWND(*this), 0x03020500); + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + #endif + _pathCombo.Attach(GetItem(IDC_COMBO_SPLIT_PATH)); + _volumeCombo.Attach(GetItem(IDC_COMBO_SPLIT_VOLUME)); + + if (!FilePath.IsEmpty()) + { + UString title; + GetText(title); + title += ' '; + title += FilePath; + SetText(title); + } + _pathCombo.SetText(Path); + AddVolumeItems(_volumeCombo); + _volumeCombo.SetCurSel(0); + return CModalDialog::OnInit(); +} + +bool CSplitDialog::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + switch(buttonID) + { + case IDC_BUTTON_SPLIT_PATH: + OnButtonSetPath(); + return true; + } + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); +} + +void CSplitDialog::OnButtonSetPath() +{ + CSysString currentPath; + _pathCombo.GetText(currentPath); + CSysString title = TEXT("Specify a location for output folder"); + CSysString resultPath; + if (!NShell::BrowseForFolder(HWND(*this), title, currentPath, resultPath)) + return; + NFile::NName::NormalizeDirPathPrefix(resultPath); + _pathCombo.SetCurSel(-1); + _pathCombo.SetText(resultPath); +} + +void CSplitDialog::OnOK() +{ + _pathCombo.GetText(Path); + UString volumeString; + _volumeCombo.GetText(volumeString); + volumeString.Trim(); + if (!ParseVolumeSizes(volumeString, VolumeSizes)) + { + MessageBox((HWND)*this, TEXT("Incorrect volume size"), TEXT("7-Zip"), MB_ICONERROR); + return; + } + CModalDialog::OnOK(); +} diff --git a/7zip/FileManager/Resource/SplitDialog/SplitDialog.h b/7zip/FileManager/Resource/SplitDialog/SplitDialog.h new file mode 100755 index 00000000..bc5ebecf --- /dev/null +++ b/7zip/FileManager/Resource/SplitDialog/SplitDialog.h @@ -0,0 +1,27 @@ +// SplitDialog.h + +#ifndef __SPLITDIALOG_H +#define __SPLITDIALOG_H + +#include "Common/Types.h" +#include "Windows/Control/Dialog.h" +#include "Windows/Control/ComboBox.h" +#include "resource.h" + +class CSplitDialog: public NWindows::NControl::CModalDialog +{ + NWindows::NControl::CComboBox _pathCombo; + NWindows::NControl::CComboBox _volumeCombo; + virtual void OnOK(); + virtual bool OnInit(); + virtual bool OnButtonClicked(int buttonID, HWND buttonHWND); + void OnButtonSetPath(); +public: + UString FilePath; + UString Path; + CRecordVector<UInt64> VolumeSizes; + INT_PTR Create(HWND parentWindow = 0) + { return CModalDialog::Create(MAKEINTRESOURCE(IDD_DIALOG_SPLIT), parentWindow); } +}; + +#endif diff --git a/7zip/FileManager/Resource/SplitDialog/resource.h b/7zip/FileManager/Resource/SplitDialog/resource.h new file mode 100755 index 00000000..9553f775 --- /dev/null +++ b/7zip/FileManager/Resource/SplitDialog/resource.h @@ -0,0 +1,21 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by resource.rc +// +#define IDD_DIALOG_SPLIT 504 +#define IDC_STATIC_SPLIT_PATH 1000 +#define IDC_COMBO_SPLIT_PATH 1001 +#define IDC_BUTTON_SPLIT_PATH 1002 +#define IDC_STATIC_SPLIT_VOLUME 1010 +#define IDC_COMBO_SPLIT_VOLUME 1011 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 157 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1004 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/7zip/FileManager/Resource/SplitDialog/resource.rc b/7zip/FileManager/Resource/SplitDialog/resource.rc new file mode 100755 index 00000000..1fa17e7c --- /dev/null +++ b/7zip/FileManager/Resource/SplitDialog/resource.rc @@ -0,0 +1,106 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Russian resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS) +#ifdef _WIN32 +LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT +#pragma code_page(1251) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // Russian resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_DIALOG_SPLIT DIALOG DISCARDABLE 0, 0, 237, 103 +STYLE DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | + WS_SYSMENU +CAPTION "Split File" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "&Split to:",IDC_STATIC_SPLIT_PATH,7,7,223,8 + COMBOBOX IDC_COMBO_SPLIT_PATH,7,18,193,126,CBS_DROPDOWN | + CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "...",IDC_BUTTON_SPLIT_PATH,210,17,20,14,WS_GROUP + LTEXT "Split to &volumes, bytes:",IDC_STATIC_SPLIT_VOLUME,7,38, + 223,8 + COMBOBOX IDC_COMBO_SPLIT_VOLUME,7,50,120,52,CBS_DROPDOWN | + CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "OK",IDOK,91,82,64,14 + PUSHBUTTON "Cancel",IDCANCEL,166,82,64,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_DIALOG_SPLIT, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 230 + TOPMARGIN, 7 + BOTTOMMARGIN, 96 + END +END +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + diff --git a/7zip/FileManager/Resource/SystemPage/SystemPage.h b/7zip/FileManager/Resource/SystemPage/SystemPage.h index 3a2052e8..25994b89 100755 --- a/7zip/FileManager/Resource/SystemPage/SystemPage.h +++ b/7zip/FileManager/Resource/SystemPage/SystemPage.h @@ -1,7 +1,5 @@ // SystemPage.h -#pragma once - #ifndef __SYSTEMPAGE_H #define __SYSTEMPAGE_H diff --git a/7zip/FileManager/RootFolder.h b/7zip/FileManager/RootFolder.h index 97e28c85..6dd08bc0 100755 --- a/7zip/FileManager/RootFolder.h +++ b/7zip/FileManager/RootFolder.h @@ -1,7 +1,5 @@ // RootFolder.h -#pragma once - #ifndef __ROOTFOLDER_H #define __ROOTFOLDER_H diff --git a/7zip/FileManager/SplitUtils.cpp b/7zip/FileManager/SplitUtils.cpp new file mode 100755 index 00000000..350b672b --- /dev/null +++ b/7zip/FileManager/SplitUtils.cpp @@ -0,0 +1,65 @@ +// SplitUtils.cpp + +#include "StdAfx.h" + +#include "Common/StringToInt.h" + +#include "SplitUtils.h" +#include "StringUtils.h" + +bool ParseVolumeSizes(const UString &s, CRecordVector<UInt64> &values) +{ + values.Clear(); + UStringVector destStrings; + SplitString(s, destStrings); + bool prevIsNumber = false; + for (int i = 0; i < destStrings.Size(); i++) + { + UString subString = destStrings[i]; + subString.MakeUpper(); + if (subString.IsEmpty()) + return false; + if (subString == L"-") + return true; + if (prevIsNumber) + { + wchar_t c = subString[0]; + UInt64 &value = values.Back(); + prevIsNumber = false; + switch(c) + { + case L'B': + continue; + case L'K': + value <<= 10; + continue; + case L'M': + value <<= 20; + continue; + case L'G': + value <<= 30; + continue; + } + } + const wchar_t *start = subString; + const wchar_t *end; + UInt64 value = ConvertStringToUInt64(start, &end); + if (start == end) + return false; + if (value == 0) + return false; + values.Add(value); + prevIsNumber = true; + UString rem = subString.Mid(end - start); + if (!rem.IsEmpty()) + destStrings.Insert(i + 1, rem); + } + return true; +} + +void AddVolumeItems(NWindows::NControl::CComboBox &volumeCombo) +{ + volumeCombo.AddString(TEXT("1457664 - 3.5\" floppy")); + volumeCombo.AddString(TEXT("650M - CD")); + volumeCombo.AddString(TEXT("700M - CD")); +} diff --git a/7zip/FileManager/SplitUtils.h b/7zip/FileManager/SplitUtils.h new file mode 100755 index 00000000..e41efa67 --- /dev/null +++ b/7zip/FileManager/SplitUtils.h @@ -0,0 +1,13 @@ +// SplitUtils.h + +#ifndef __SPLITUTILS_H +#define __SPLITUTILS_H + +#include "Common/String.h" +#include "Common/Types.h" +#include "Windows/Control/ComboBox.h" + +bool ParseVolumeSizes(const UString &s, CRecordVector<UInt64> &values); +void AddVolumeItems(NWindows::NControl::CComboBox &volumeCombo); + +#endif diff --git a/7zip/FileManager/StdAfx.h b/7zip/FileManager/StdAfx.h index 4e8dc51d..1adf6737 100755 --- a/7zip/FileManager/StdAfx.h +++ b/7zip/FileManager/StdAfx.h @@ -3,10 +3,11 @@ #ifndef __STDAFX_H #define __STDAFX_H -#pragma once - #define _WIN32_WINNT 0x0400 +// it's for Windows NT supporting (MENUITEMINFOW) +#define WINVER 0x0400 + #include <windows.h> #include <stdio.h> #include <commctrl.h> @@ -37,5 +38,4 @@ extern CComModule _Module; */ #include <memory> - #endif diff --git a/7zip/FileManager/StringUtils.cpp b/7zip/FileManager/StringUtils.cpp index 8a4e48ae..93fbe094 100755 --- a/7zip/FileManager/StringUtils.cpp +++ b/7zip/FileManager/StringUtils.cpp @@ -8,22 +8,22 @@ void SplitStringToTwoStrings(const UString &src, UString &dest1, UString &dest2) { dest1.Empty(); dest2.Empty(); - bool aQuoteMode = false; + bool quoteMode = false; for (int i = 0; i < src.Length(); i++) { - wchar_t aChar = src[i]; - if (aChar == L'\"') - aQuoteMode = !aQuoteMode; - else if (aChar == L' ' && !aQuoteMode) + wchar_t c = src[i]; + if (c == L'\"') + quoteMode = !quoteMode; + else if (c == L' ' && !quoteMode) { - if (!aQuoteMode) + if (!quoteMode) { i++; break; } } else - dest1 += aChar; + dest1 += c; } dest2 = src.Mid(i); } @@ -32,10 +32,10 @@ void SplitString(const UString &srcString, UStringVector &destStrings) { destStrings.Clear(); UString string; - int aLen = srcString.Length(); - if (aLen == 0) + int len = srcString.Length(); + if (len == 0) return; - for (int i = 0; i < aLen; i++) + for (int i = 0; i < len; i++) { wchar_t c = srcString[i]; if (c == L' ') diff --git a/7zip/FileManager/StringUtils.h b/7zip/FileManager/StringUtils.h index 6a17da9b..376a3024 100755 --- a/7zip/FileManager/StringUtils.h +++ b/7zip/FileManager/StringUtils.h @@ -1,7 +1,5 @@ // StringUtils.h -#pragma once - #ifndef __STRINGUTILS_H #define __STRINGUTILS_H @@ -12,6 +10,4 @@ void SplitStringToTwoStrings(const UString &src, UString &dest1, UString &dest2) void SplitString(const UString &srcString, UStringVector &destStrings); UString JoinStrings(const UStringVector &srcStrings); - - -#endif
\ No newline at end of file +#endif diff --git a/7zip/FileManager/SysIconUtils.h b/7zip/FileManager/SysIconUtils.h index 186a1549..cf8f79e5 100755 --- a/7zip/FileManager/SysIconUtils.h +++ b/7zip/FileManager/SysIconUtils.h @@ -1,7 +1,5 @@ // SysIconUtils.h -#pragma once - #ifndef __SYSICONUTILS_H #define __SYSICONUTILS_H @@ -52,6 +50,4 @@ DWORD_PTR GetRealIconIndex(LPCTSTR path, UINT32 attributes, int &iconIndex); DWORD_PTR GetRealIconIndex(const CSysString &fileName, UINT32 attributes, int &iconIndex, CSysString &typeName); int GetIconIndexForCSIDL(int aCSIDL); - #endif - diff --git a/7zip/FileManager/TextPairs.h b/7zip/FileManager/TextPairs.h index bce4755c..247a92d9 100755 --- a/7zip/FileManager/TextPairs.h +++ b/7zip/FileManager/TextPairs.h @@ -1,7 +1,5 @@ // Common/TextPairs.h -#pragma once - #ifndef __COMMON_TEXTPAIRS_H #define __COMMON_TEXTPAIRS_H @@ -32,5 +30,3 @@ public: }; #endif - - diff --git a/7zip/FileManager/UpdateCallback100.cpp b/7zip/FileManager/UpdateCallback100.cpp index 05f50887..8b8fcb01 100755 --- a/7zip/FileManager/UpdateCallback100.cpp +++ b/7zip/FileManager/UpdateCallback100.cpp @@ -7,11 +7,27 @@ #include "UpdateCallback100.h" // #include "Windows/ProcessMessages.h" // #include "Resource/PasswordDialog/PasswordDialog.h" +#include "Resource/MessagesDialog/MessagesDialog.h" #include "Common/Defs.h" using namespace NWindows; +CUpdateCallback100Imp::~CUpdateCallback100Imp() +{ + if (!Messages.IsEmpty()) + { + CMessagesDialog messagesDialog; + messagesDialog.Messages = &Messages; + messagesDialog.Create(_parentWindow); + } +} + +void CUpdateCallback100Imp::AddErrorMessage(LPCWSTR message) +{ + Messages.Add(GetSystemString(message)); +} + STDMETHODIMP CUpdateCallback100Imp::SetTotal(UINT64 size) { ProgressDialog.ProgressSynch.SetProgress(size, 0); @@ -35,6 +51,7 @@ STDMETHODIMP CUpdateCallback100Imp::SetCompleted(const UINT64 *completeValue) STDMETHODIMP CUpdateCallback100Imp::CompressOperation(const wchar_t *name) { + ProgressDialog.ProgressSynch.SetCurrentFileName(name); return S_OK; } @@ -48,6 +65,12 @@ STDMETHODIMP CUpdateCallback100Imp::OperationResult(INT32 operationResult) return S_OK; } +STDMETHODIMP CUpdateCallback100Imp::UpdateErrorMessage(const wchar_t *message) +{ + AddErrorMessage(message); + return S_OK; +} + STDMETHODIMP CUpdateCallback100Imp::CryptoGetTextPassword2(INT32 *passwordIsDefined, BSTR *password) { *passwordIsDefined = BoolToInt(_passwordIsDefined); diff --git a/7zip/FileManager/UpdateCallback100.h b/7zip/FileManager/UpdateCallback100.h index ca1c50b2..3e132101 100755 --- a/7zip/FileManager/UpdateCallback100.h +++ b/7zip/FileManager/UpdateCallback100.h @@ -1,9 +1,7 @@ -// UpdateCallback.h +// UpdateCallback100.h -#pragma once - -#ifndef __UPDATECALLBACK100_H -#define __UPDATECALLBACK100_H +#ifndef __UPDATE_CALLBACK100_H +#define __UPDATE_CALLBACK100_H #include "Common/MyCom.h" #include "Common/String.h" @@ -35,13 +33,17 @@ public: STDMETHOD(CompressOperation)(const wchar_t *name); STDMETHOD(DeleteOperation)(const wchar_t *name); STDMETHOD(OperationResult)(INT32 operationResult); + STDMETHOD(UpdateErrorMessage)(const wchar_t *message); STDMETHOD(CryptoGetTextPassword2)(INT32 *passwordIsDefined, BSTR *password); private: bool _passwordIsDefined; UString _password; + void AddErrorMessage(LPCWSTR message); + CSysStringVector Messages; public: + ~CUpdateCallback100Imp(); CProgressDialog ProgressDialog; HWND _parentWindow; void Init(HWND parentWindow, @@ -59,6 +61,4 @@ public: }; - - #endif diff --git a/7zip/FileManager/ViewSettings.cpp b/7zip/FileManager/ViewSettings.cpp index 5955bf10..d9fd98d6 100755 --- a/7zip/FileManager/ViewSettings.cpp +++ b/7zip/FileManager/ViewSettings.cpp @@ -20,68 +20,108 @@ static const TCHAR *kPanelsInfoValueName = TEXT("Panels"); static const TCHAR *kToolbars = TEXT("Toolbars"); static const TCHAR *kPanelPathValueName = TEXT("PanelPath"); +static const TCHAR *kListMode = TEXT("ListMode"); static const TCHAR *kFolderHistoryValueName = TEXT("FolderHistory"); static const TCHAR *kFastFoldersValueName = TEXT("FolderShortcuts"); static const TCHAR *kCopyHistoryValueName = TEXT("CopyHistory"); +/* +class CColumnInfoSpec +{ + UInt32 PropID; + Byte IsVisible; + UInt32 Width; +}; + +struct CColumnHeader +{ + UInt32 Version; + UInt32 SortID; + Byte Ascending; +}; +*/ -#pragma pack( push, PragmaColumnInfoSpec) -#pragma pack( push, 1) +static const UInt32 kColumnInfoSpecHeader = 12; +static const UInt32 kColumnHeaderSize = 12; -class CColumnInfoSpec +static const UInt32 kColumnInfoVersion = 1; + +static NSynchronization::CCriticalSection g_RegistryOperationsCriticalSection; + +class CTempOutBufferSpec { - UINT32 PropID; - BYTE IsVisible; - UINT32 Width; + CByteBuffer Buffer; + UInt32 Size; + UInt32 Pos; public: - void GetFromColumnInfo(const CColumnInfo &aSrc) + operator const Byte *() const { return (const Byte *)Buffer; } + void Init(UInt32 dataSize) { - PropID = aSrc.PropID; - IsVisible = aSrc.IsVisible ? 1: 0; - Width = aSrc.Width; + Buffer.SetCapacity(dataSize); + Size = dataSize; + Pos = 0; } - void PutColumnInfo(CColumnInfo &aDest) + void WriteByte(Byte value) { - aDest.PropID = PropID; - aDest.IsVisible = (IsVisible != 0); - aDest.Width = Width; + if (Pos >= Size) + throw "overflow"; + ((Byte *)Buffer)[Pos++] = value; + } + void WriteUInt32(UInt32 value) + { + for (int i = 0; i < 4; i++) + { + WriteByte((Byte)value); + value >>= 8; + } + } + void WriteBool(bool value) + { + WriteUInt32(value ? 1 : 0); } }; -struct CColumnHeader +class CTempInBufferSpec { - UINT32 Version; - // UINT32 SortIndex; - UINT32 SortID; - BYTE Ascending; +public: + Byte *Buffer; + UInt32 Size; + UInt32 Pos; + Byte ReadByte() + { + if (Pos >= Size) + throw "overflow"; + return Buffer[Pos++]; + } + UInt32 ReadUInt32() + { + UInt32 value = 0; + for (int i = 0; i < 4; i++) + value |= (((UInt32)ReadByte()) << (8 * i)); + return value; + } + bool ReadBool() + { + return (ReadUInt32() != 0); + } }; -#pragma pack(pop) -#pragma pack(pop, PragmaColumnInfoSpec) - -static const UINT32 kColumnInfoVersion = 0; - -static NSynchronization::CCriticalSection g_RegistryOperationsCriticalSection; - void SaveListViewInfo(const CSysString &id, const CListViewInfo &viewInfo) { const CObjectVector<CColumnInfo> &columns = viewInfo.Columns; - CByteBuffer buffer; - UINT32 dataSize = sizeof(CColumnHeader) + sizeof(CColumnInfoSpec) * columns.Size(); - buffer.SetCapacity(dataSize); - BYTE *dataPointer = (BYTE *)buffer; - CColumnHeader &columnHeader = *(CColumnHeader *)dataPointer; - columnHeader.Version = kColumnInfoVersion; - - // columnHeader.SortIndex = viewInfo.SortIndex; - columnHeader.SortID = viewInfo.SortID; + CTempOutBufferSpec buffer; + UInt32 dataSize = kColumnHeaderSize + kColumnInfoSpecHeader * columns.Size(); + buffer.Init(dataSize); - columnHeader.Ascending = viewInfo.Ascending ? 1 : 0; - CColumnInfoSpec *destItems = (CColumnInfoSpec *)(dataPointer + sizeof(CColumnHeader)); + buffer.WriteUInt32(kColumnInfoVersion); + buffer.WriteUInt32(viewInfo.SortID); + buffer.WriteBool(viewInfo.Ascending); for(int i = 0; i < columns.Size(); i++) { - CColumnInfoSpec &columnInfoSpec = destItems[i]; - columnInfoSpec.GetFromColumnInfo(columns[i]); + const CColumnInfo &column = columns[i]; + buffer.WriteUInt32(column.PropID); + buffer.WriteBool(column.IsVisible); + buffer.WriteUInt32(column.Width); } { NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); @@ -90,7 +130,7 @@ void SaveListViewInfo(const CSysString &id, const CListViewInfo &viewInfo) keyName += kCulumnsKeyName; CKey key; key.Create(HKEY_CURRENT_USER, keyName); - key.SetValue(id, dataPointer, dataSize); + key.SetValue(id, (const Byte *)buffer, dataSize); } } @@ -99,7 +139,7 @@ void ReadListViewInfo(const CSysString &id, CListViewInfo &viewInfo) viewInfo.Clear(); CObjectVector<CColumnInfo> &columns = viewInfo.Columns; CByteBuffer buffer; - UINT32 size; + UInt32 size; { NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); CSysString keyName = kCUBasePath; @@ -111,49 +151,52 @@ void ReadListViewInfo(const CSysString &id, CListViewInfo &viewInfo) if (key.QueryValue(id, buffer, size) != ERROR_SUCCESS) return; } - if (size < sizeof(CColumnHeader)) + if (size < kColumnHeaderSize) return; - BYTE *dataPointer = (BYTE *)buffer; - const CColumnHeader &columnHeader = *(CColumnHeader*)dataPointer; - if (columnHeader.Version != kColumnInfoVersion) - return; - viewInfo.Ascending = (columnHeader.Ascending != 0); + CTempInBufferSpec inBuffer; + inBuffer.Size = size; + inBuffer.Buffer = (Byte *)buffer; + inBuffer.Pos = 0; - // viewInfo.SortIndex = columnHeader.SortIndex; - viewInfo.SortID = columnHeader.SortID; - size -= sizeof(CColumnHeader); - if (size % sizeof(CColumnHeader) != 0) + UInt32 version = inBuffer.ReadUInt32(); + if (version != kColumnInfoVersion) return; - int numItems = size / sizeof(CColumnInfoSpec); - CColumnInfoSpec *specItems = (CColumnInfoSpec *)(dataPointer + sizeof(CColumnHeader));; + viewInfo.SortID = inBuffer.ReadUInt32(); + viewInfo.Ascending = inBuffer.ReadBool(); + + size -= kColumnHeaderSize; + if (size % kColumnInfoSpecHeader != 0) + return; + int numItems = size / kColumnInfoSpecHeader; columns.Reserve(numItems); for(int i = 0; i < numItems; i++) { CColumnInfo columnInfo; - specItems[i].PutColumnInfo(columnInfo); + columnInfo.PropID = inBuffer.ReadUInt32(); + columnInfo.IsVisible = inBuffer.ReadBool(); + columnInfo.Width = inBuffer.ReadUInt32(); columns.Add(columnInfo); } } -#pragma pack( push, PragmaWindowPosition) -#pragma pack( push, 1) +static const UInt32 kWindowPositionHeaderSize = 5 * 4; +static const UInt32 kPanelsInfoHeaderSize = 3 * 4; +/* struct CWindowPosition { RECT Rect; - UINT32 Maximized; + UInt32 Maximized; }; struct CPanelsInfo { - UINT32 NumPanels; - UINT32 CurrentPanel; - UINT32 SplitterPos; + UInt32 NumPanels; + UInt32 CurrentPanel; + UInt32 SplitterPos; }; - -#pragma pack(pop) -#pragma pack(pop, PragmaWindowPosition) +*/ void SaveWindowSize(const RECT &rect, bool maximized) { @@ -161,10 +204,15 @@ void SaveWindowSize(const RECT &rect, bool maximized) CKey key; NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); key.Create(HKEY_CURRENT_USER, keyName); - CWindowPosition position; - position.Rect = rect; - position.Maximized = maximized ? 1: 0; - key.SetValue(kPositionValueName, &position, sizeof(position)); + // CWindowPosition position; + CTempOutBufferSpec buffer; + buffer.Init(kWindowPositionHeaderSize); + buffer.WriteUInt32(rect.left); + buffer.WriteUInt32(rect.top); + buffer.WriteUInt32(rect.right); + buffer.WriteUInt32(rect.bottom); + buffer.WriteBool(maximized); + key.SetValue(kPositionValueName, (const Byte *)buffer, kWindowPositionHeaderSize); } bool ReadWindowSize(RECT &rect, bool &maximized) @@ -175,31 +223,39 @@ bool ReadWindowSize(RECT &rect, bool &maximized) if(key.Open(HKEY_CURRENT_USER, keyName, KEY_READ) != ERROR_SUCCESS) return false; CByteBuffer buffer; - UINT32 size; + UInt32 size; if (key.QueryValue(kPositionValueName, buffer, size) != ERROR_SUCCESS) return false; - if (size != sizeof(CWindowPosition)) + if (size != kWindowPositionHeaderSize) return false; - const CWindowPosition &position = *(const CWindowPosition *)(const BYTE *)buffer; - rect = position.Rect; - maximized = (position.Maximized != 0); + CTempInBufferSpec inBuffer; + inBuffer.Size = size; + inBuffer.Buffer = (Byte *)buffer; + inBuffer.Pos = 0; + rect.left = inBuffer.ReadUInt32(); + rect.top = inBuffer.ReadUInt32(); + rect.right = inBuffer.ReadUInt32(); + rect.bottom = inBuffer.ReadUInt32(); + maximized = inBuffer.ReadBool(); return true; } -void SavePanelsInfo(UINT32 numPanels, UINT32 currentPanel, UINT32 splitterPos) +void SavePanelsInfo(UInt32 numPanels, UInt32 currentPanel, UInt32 splitterPos) { CSysString keyName = kCUBasePath; CKey key; NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); key.Create(HKEY_CURRENT_USER, keyName); - CPanelsInfo block; - block.NumPanels = numPanels; - block.CurrentPanel = currentPanel; - block.SplitterPos = splitterPos; - key.SetValue(kPanelsInfoValueName, &block, sizeof(block)); + + CTempOutBufferSpec buffer; + buffer.Init(kPanelsInfoHeaderSize); + buffer.WriteUInt32(numPanels); + buffer.WriteUInt32(currentPanel); + buffer.WriteUInt32(splitterPos); + key.SetValue(kPanelsInfoValueName, (const Byte *)buffer, kPanelsInfoHeaderSize); } -bool ReadPanelsInfo(UINT32 &numPanels, UINT32 ¤tPanel, UINT32 &splitterPos) +bool ReadPanelsInfo(UInt32 &numPanels, UInt32 ¤tPanel, UInt32 &splitterPos) { CSysString keyName = kCUBasePath; CKey key; @@ -207,19 +263,22 @@ bool ReadPanelsInfo(UINT32 &numPanels, UINT32 ¤tPanel, UINT32 &splitterPos if(key.Open(HKEY_CURRENT_USER, keyName, KEY_READ) != ERROR_SUCCESS) return false; CByteBuffer buffer; - UINT32 size; + UInt32 size; if (key.QueryValue(kPanelsInfoValueName, buffer, size) != ERROR_SUCCESS) return false; - if (size != sizeof(CPanelsInfo)) + if (size != kPanelsInfoHeaderSize) return false; - const CPanelsInfo &block = *(const CPanelsInfo *)(const BYTE *)buffer; - numPanels = block.NumPanels; - currentPanel = block.CurrentPanel; - splitterPos = block.SplitterPos; + CTempInBufferSpec inBuffer; + inBuffer.Size = size; + inBuffer.Buffer = (Byte *)buffer; + inBuffer.Pos = 0; + numPanels = inBuffer.ReadUInt32(); + currentPanel = inBuffer.ReadUInt32(); + splitterPos = inBuffer.ReadUInt32(); return true; } -void SaveToolbarsMask(UINT32 toolbarMask) +void SaveToolbarsMask(UInt32 toolbarMask) { CKey key; key.Create(HKEY_CURRENT_USER, kCUBasePath); @@ -228,48 +287,73 @@ void SaveToolbarsMask(UINT32 toolbarMask) static const kDefaultToolbarMask = 8 | 4 | 1; -UINT32 ReadToolbarsMask() +UInt32 ReadToolbarsMask() { CKey key; if(key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS) return kDefaultToolbarMask; - UINT32 mask; + UInt32 mask; if (key.QueryValue(kToolbars, mask) != ERROR_SUCCESS) return kDefaultToolbarMask; return mask; } -static CSysString GetPanelPathName(UINT32 panelIndex) +static CSysString GetPanelPathName(UInt32 panelIndex) { TCHAR panelString[32]; - ConvertUINT64ToString(panelIndex, panelString); + ConvertUInt64ToString(panelIndex, panelString); return CSysString(kPanelPathValueName) + panelString; } -void SavePanelPath(UINT32 panel, const CSysString &path) +void SavePanelPath(UInt32 panel, const CSysString &path) { - CSysString keyName = kCUBasePath; CKey key; NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); - key.Create(HKEY_CURRENT_USER, keyName); + key.Create(HKEY_CURRENT_USER, kCUBasePath); key.SetValue(GetPanelPathName(panel), path); } -bool ReadPanelPath(UINT32 panel, CSysString &path) +bool ReadPanelPath(UInt32 panel, CSysString &path) { - CSysString keyName = kCUBasePath; CKey key; NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); - if(key.Open(HKEY_CURRENT_USER, keyName, KEY_READ) != ERROR_SUCCESS) + if(key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS) return false; return (key.QueryValue(GetPanelPathName(panel), path) == ERROR_SUCCESS); } +void SaveListMode(const CListMode &listMode) +{ + CKey key; + key.Create(HKEY_CURRENT_USER, kCUBasePath); + UInt32 t = 0; + for (int i = 0; i < 2; i++) + t |= ((listMode.Panels[i]) & 0xFF) << (i * 8); + key.SetValue(kListMode, t); +} + +void ReadListMode(CListMode &listMode) +{ + CKey key; + listMode.Init(); + if(key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS) + return; + UInt32 t; + if (key.QueryValue(kListMode, t) != ERROR_SUCCESS) + return; + for (int i = 0; i < 2; i++) + { + listMode.Panels[i] = (t & 0xFF); + t >>= 8; + } +} + + void SaveStringList(LPCTSTR valueName, const UStringVector &folders) { - UINT32 sizeInChars = 0; + UInt32 sizeInChars = 0; int i; for (i = 0; i < folders.Size(); i++) sizeInChars += folders[i].Length() + 1; @@ -295,12 +379,12 @@ void ReadStringList(LPCTSTR valueName, UStringVector &folders) if(key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS) return; CByteBuffer buffer; - UINT32 dataSize; + UInt32 dataSize; if (key.QueryValue(valueName, buffer, dataSize) != ERROR_SUCCESS) return; if (dataSize % sizeof(wchar_t) != 0) return; - const wchar_t *data = (const wchar_t *)(const BYTE *)buffer; + const wchar_t *data = (const wchar_t *)(const Byte *)buffer; int sizeInChars = dataSize / sizeof(wchar_t); UString string; for (int i = 0; i < sizeInChars; i++) diff --git a/7zip/FileManager/ViewSettings.h b/7zip/FileManager/ViewSettings.h index 5d2f509d..b9da8bf2 100755 --- a/7zip/FileManager/ViewSettings.h +++ b/7zip/FileManager/ViewSettings.h @@ -1,7 +1,5 @@ // ViewSettings.h -#pragma once - #ifndef __VIEWSETTINGS_H #define __VIEWSETTINGS_H @@ -12,7 +10,7 @@ struct CColumnInfo { PROPID PropID; bool IsVisible; - UINT32 Width; + UInt32 Width; }; inline bool operator==(const CColumnInfo &a1, const CColumnInfo &a2) @@ -26,17 +24,14 @@ inline bool operator!=(const CColumnInfo &a1, const CColumnInfo &a2) return !(a1 == a2); } - struct CListViewInfo { CObjectVector<CColumnInfo> Columns; - // int SortIndex; PROPID SortID; bool Ascending; void Clear() { - // SortIndex = -1; SortID = 0; Ascending = true; Columns.Clear(); @@ -62,7 +57,6 @@ struct CListViewInfo return false; return true; } - // void OrderItems(); }; void SaveListViewInfo(const CSysString &anID, const CListViewInfo &viewInfo); @@ -71,14 +65,24 @@ void ReadListViewInfo(const CSysString &anID, CListViewInfo &viewInfo); void SaveWindowSize(const RECT &rect, bool maximized); bool ReadWindowSize(RECT &rect, bool &maximized); -void SavePanelsInfo(UINT32 numPanels, UINT32 currentPanel, UINT32 splitterPos); -bool ReadPanelsInfo(UINT32 &numPanels, UINT32 ¤tPanel, UINT32 &splitterPos); +void SavePanelsInfo(UInt32 numPanels, UInt32 currentPanel, UInt32 splitterPos); +bool ReadPanelsInfo(UInt32 &numPanels, UInt32 ¤tPanel, UInt32 &splitterPos); + +void SaveToolbarsMask(UInt32 toolbarMask); +UInt32 ReadToolbarsMask(); -void SaveToolbarsMask(UINT32 toolbarMask); -UINT32 ReadToolbarsMask(); +void SavePanelPath(UInt32 panel, const CSysString &path); +bool ReadPanelPath(UInt32 panel, CSysString &path); + +struct CListMode +{ + UInt32 Panels[2]; + void Init() { Panels[0] = Panels[1] = 3; } + CListMode() { Init(); } +}; -void SavePanelPath(UINT32 panel, const CSysString &path); -bool ReadPanelPath(UINT32 panel, CSysString &path); +void SaveListMode(const CListMode &listMode); +void ReadListMode(CListMode &listMode); void SaveFolderHistory(const UStringVector &folders); void ReadFolderHistory(UStringVector &folders); diff --git a/7zip/FileManager/resource.h b/7zip/FileManager/resource.h index e8d2b612..5aade245 100755 --- a/7zip/FileManager/resource.h +++ b/7zip/FileManager/resource.h @@ -16,6 +16,8 @@ #define IDM_COPY_TO 231 #define IDM_MOVE_TO 232 #define IDM_DELETE 233 +#define IDM_FILE_SPLIT 238 +#define IDM_FILE_COMBINE 239 #define IDM_FILE_PROPERTIES 240 #define IDM_FILE_COMMENT 241 #define IDM_CREATE_FOLDER 250 @@ -125,12 +127,18 @@ #define IDS_COMMENT2 4002 #define IDS_SYSTEM 4010 +#define IDS_SPLITTING 4020 + +#define IDS_COMBINE 4030 +#define IDS_COMBINE_TO 4031 +#define IDS_COMBINING 4032 + // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 4020 -#define _APS_NEXT_COMMAND_VALUE 40078 +#define _APS_NEXT_RESOURCE_VALUE 4030 +#define _APS_NEXT_COMMAND_VALUE 40080 #define _APS_NEXT_CONTROL_VALUE 3000 #define _APS_NEXT_SYMED_VALUE 4010 #endif diff --git a/7zip/FileManager/resource.rc b/7zip/FileManager/resource.rc index 293559b4..f9f11e1a 100755 --- a/7zip/FileManager/resource.rc +++ b/7zip/FileManager/resource.rc @@ -47,6 +47,7 @@ BEGIN "#include ""Resource\\MessagesDialog\\resource.rc""\r\n" "#include ""Resource\\OverwriteDialog\\resource.rc""\r\n" "#include ""Resource\\PasswordDialog\\resource.rc""\r\n" + "#include ""Resource\\SplitDialog\\resource.rc""\r\n" "#include ""Resource\\ProgressDialog2\\resource.rc""\r\n" "#include ""Resource\\BenchmarkDialog\\resource.rc""\r\n" "#include ""Resource\\AboutDialog\\resource.rc""\r\n" @@ -81,8 +82,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,13,0,0 - PRODUCTVERSION 3,13,0,0 + FILEVERSION 4,20,0,0 + PRODUCTVERSION 4,20,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -100,14 +101,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Igor Pavlov\0" VALUE "FileDescription", "7-Zip File Manager\0" - VALUE "FileVersion", "3, 13, 0, 0\0" + VALUE "FileVersion", "4, 20, 0, 0\0" VALUE "InternalName", "7zFM\0" - VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "7zFM.exe\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "7-Zip\0" - VALUE "ProductVersion", "3, 13, 0, 0\0" + VALUE "ProductVersion", "4, 20, 0, 0\0" VALUE "SpecialBuild", "\0" END END @@ -146,7 +147,6 @@ BEGIN MENUITEM "&Open\tEnter", IDM_FILE_OPEN MENUITEM "Open &Inside\tCtrl+PgDn", IDM_FILE_OPEN_INSIDE MENUITEM "Open O&utside\tShift+Enter", IDM_FILE_OPEN_OUTSIDE - MENUITEM "&View\tF3", IDM_FILE_VIEW, GRAYED MENUITEM "&Edit\tF4", IDM_FILE_EDIT MENUITEM SEPARATOR MENUITEM "Rena&me\tF2", IDM_RENAME @@ -154,6 +154,9 @@ BEGIN MENUITEM "&Move To...\tF6", IDM_MOVE_TO MENUITEM "&Delete\tDel", IDM_DELETE MENUITEM SEPARATOR + MENUITEM "&Split file...", IDM_FILE_SPLIT + MENUITEM "Com&bine files...", IDM_FILE_COMBINE + MENUITEM SEPARATOR MENUITEM "P&roperties\tAlt+Enter", IDM_FILE_PROPERTIES MENUITEM "Comme&nt\tCtrl+Z", IDM_FILE_COMMENT MENUITEM SEPARATOR @@ -285,6 +288,18 @@ END STRINGTABLE DISCARDABLE BEGIN + IDS_SPLITTING "Splitting..." + IDS_COMBINE "Combine Files" + IDS_COMBINE_TO "&Combine to:" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_COMBINING "Combining..." +END + +STRINGTABLE DISCARDABLE +BEGIN IDS_OPERATION_IS_NOT_SUPPORTED "Operation is not supported." IDS_CONFIRM_FILE_DELETE "Confirm File Delete" IDS_CONFIRM_FOLDER_DELETE "Confirm Folder Delete" @@ -399,6 +414,7 @@ END #include "Resource\MessagesDialog\resource.rc" #include "Resource\OverwriteDialog\resource.rc" #include "Resource\PasswordDialog\resource.rc" +#include "Resource\SplitDialog\resource.rc" #include "Resource\ProgressDialog2\resource.rc" #include "Resource\BenchmarkDialog\resource.rc" #include "Resource\AboutDialog\resource.rc" diff --git a/7zip/ICoder.h b/7zip/ICoder.h index 0068bef0..631df96c 100755 --- a/7zip/ICoder.h +++ b/7zip/ICoder.h @@ -1,7 +1,5 @@ // ICoder.h -// #pragma once - #ifndef __ICODER_H #define __ICODER_H @@ -13,7 +11,7 @@ DEFINE_GUID(IID_ICompressProgressInfo, MIDL_INTERFACE("23170F69-40C1-278A-0000-000200040000") ICompressProgressInfo: public IUnknown { - STDMETHOD(SetRatioInfo)(const UINT64 *inSize, const UINT64 *outSize) = 0; + STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) = 0; }; // {23170F69-40C1-278A-0000-000200050000} @@ -24,8 +22,8 @@ ICompressCoder: public IUnknown { STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UINT64 *inSize, - const UINT64 *outSize, + const UInt64 *inSize, + const UInt64 *outSize, ICompressProgressInfo *progress) = 0; }; @@ -36,11 +34,11 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000200180000") ICompressCoder2: public IUnknown { STDMETHOD(Code)(ISequentialInStream **inStreams, - const UINT64 **inSizes, - UINT32 numInStreams, + const UInt64 **inSizes, + UInt32 numInStreams, ISequentialOutStream **outStreams, - const UINT64 **outSizes, - UINT32 numOutStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, ICompressProgressInfo *progress) PURE; }; @@ -58,7 +56,8 @@ namespace NCoderPropID kMatchFinder, kNumPasses = 0x460, kAlgorithm = 0x470, - kMultiThread = 0x480 + kMultiThread = 0x480, + kEndMarker = 0x490 }; } @@ -69,16 +68,27 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000200200000") ICompressSetCoderProperties: public IUnknown { STDMETHOD(SetCoderProperties)(const PROPID *propIDs, - const PROPVARIANT *properties, UINT32 numProperties) PURE; + const PROPVARIANT *properties, UInt32 numProperties) PURE; }; +/* // {23170F69-40C1-278A-0000-000200210000} DEFINE_GUID(IID_ICompressSetDecoderProperties, 0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x21, 0x00, 0x00); MIDL_INTERFACE("23170F69-40C1-278A-0000-000200210000") ICompressSetDecoderProperties: public IUnknown { - STDMETHOD(SetDecoderProperties)(ISequentialInStream *anInStream) PURE; + STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream) PURE; +}; +*/ + +// {23170F69-40C1-278A-0000-000200210200} +DEFINE_GUID(IID_ICompressSetDecoderProperties2, +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x21, 0x02, 0x00); +MIDL_INTERFACE("23170F69-40C1-278A-0000-000200210200") +ICompressSetDecoderProperties2: public IUnknown +{ + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size) PURE; }; // {23170F69-40C1-278A-0000-000200230000} @@ -96,7 +106,7 @@ DEFINE_GUID(IID_ICompressGetInStreamProcessedSize, MIDL_INTERFACE("23170F69-40C1-278A-0000-000200240000") ICompressGetInStreamProcessedSize: public IUnknown { - STDMETHOD(GetInStreamProcessedSize)(UINT64 *value) PURE; + STDMETHOD(GetInStreamProcessedSize)(UInt64 *value) PURE; }; // {23170F69-40C1-278A-0000-000200250000} @@ -105,7 +115,70 @@ DEFINE_GUID(IID_ICompressGetSubStreamSize, MIDL_INTERFACE("23170F69-40C1-278A-0000-000200250000") ICompressGetSubStreamSize: public IUnknown { - STDMETHOD(GetSubStreamSize)(UINT64 subStream, UINT64 *value) PURE; + STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value) PURE; +}; + +// {23170F69-40C1-278A-0000-000200260000} +DEFINE_GUID(IID_ICompressSetInStream, +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x26, 0x00, 0x00); +MIDL_INTERFACE("23170F69-40C1-278A-0000-000200260000") +ICompressSetInStream: public IUnknown +{ + STDMETHOD(SetInStream)(ISequentialInStream *inStream) PURE; + STDMETHOD(ReleaseInStream)() PURE; +}; + +// {23170F69-40C1-278A-0000-000200270000} +DEFINE_GUID(IID_ICompressSetOutStream, +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x27, 0x00, 0x00); +MIDL_INTERFACE("23170F69-40C1-278A-0000-000200270000") +ICompressSetOutStream: public IUnknown +{ + STDMETHOD(SetOutStream)(ISequentialOutStream *outStream) PURE; + STDMETHOD(ReleaseOutStream)() PURE; +}; + +// {23170F69-40C1-278A-0000-000200280000} +DEFINE_GUID(IID_ICompressSetInStreamSize, +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x00); +MIDL_INTERFACE("23170F69-40C1-278A-0000-000200280000") +ICompressSetInStreamSize: public IUnknown +{ + STDMETHOD(SetInStreamSize)(const UInt64 *inSize) PURE; +}; + +// {23170F69-40C1-278A-0000-000200290000} +DEFINE_GUID(IID_ICompressSetOutStreamSize, +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x29, 0x00, 0x00); +MIDL_INTERFACE("23170F69-40C1-278A-0000-000200290000") +ICompressSetOutStreamSize: public IUnknown +{ + STDMETHOD(SetOutStreamSize)(const UInt64 *outSize) PURE; +}; + +// {23170F69-40C1-278A-0000-000200400000} +DEFINE_GUID(IID_ICompressFilter, +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x40, 0x00, 0x00); +MIDL_INTERFACE("23170F69-40C1-278A-0000-000200400000") +ICompressFilter: public IUnknown +{ + STDMETHOD(Init)() PURE; + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size) PURE; + // Filter return outSize (UInt32) + // if (outSize <= size): Filter have converted outSize bytes + // if (outSize > size): Filter have not converted anything. + // and it needs at least outSize bytes to convert one block + // (it's for crypto block algorithms). +}; + +// {23170F69-40C1-278A-0000-000200800000} +DEFINE_GUID(IID_ICryptoProperties, +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x80, 0x00, 0x00); +MIDL_INTERFACE("23170F69-40C1-278A-0000-000200800000") +ICryptoProperties: public IUnknown +{ + STDMETHOD(SetKey)(const Byte *data, UInt32 size) PURE; + STDMETHOD(SetInitVector)(const Byte *data, UInt32 size) PURE; }; ////////////////////// @@ -120,7 +193,7 @@ namespace NMethodPropID kEncoder, kInStreams, kOutStreams, - kDescription, + kDescription }; } diff --git a/7zip/IMyUnknown.h b/7zip/IMyUnknown.h deleted file mode 100755 index d614d99a..00000000 --- a/7zip/IMyUnknown.h +++ /dev/null @@ -1,71 +0,0 @@ -// IMyUnknown.h - -// #pragma once - -#ifndef __MYUNKNOWN_H -#define __MYUNKNOWN_H - -#ifdef WIN32 - -// #include <guiddef.h> -#include <basetyps.h> - -#else - -#define HRESULT LONG -#define STDMETHODCALLTYPE __stdcall -#define STDMETHOD_(t, f) virtual t STDMETHODCALLTYPE f -#define STDMETHOD(f) STDMETHOD_(HRESULT, f) -#define STDMETHODIMP_(type) type STDMETHODCALLTYPE -#define STDMETHODIMP STDMETHODIMP_(HRESULT) - -#define PURE = 0; - -typedef struct { - unsigned long Data1; - unsigned short Data2; - unsigned short Data3; - unsigned char Data4[8]; -} GUID; - -#ifdef __cplusplus - #define MY_EXTERN_C extern "C" -#else - #define MY_EXTERN_C extern -#endif - -#ifdef INITGUID - #define MY_DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - MY_EXTERN_C const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } -#else - #define MY_DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - MY_EXTERN_C const GUID name -#endif - -#ifdef __cplusplus -#define REFGUID const GUID & -#else -#define REFGUID const GUID * __MIDL_CONST -#endif - -#define MIDL_INTERFACE(x) struct -inline int operator==(REFGUID g1, REFGUID g2) -{ - for (int i = 0; i < sizeof(g1); i++) - if (((unsigned char *)&g1)[i] != ((unsigned char *)&g2)[i]) - return false; - return true; -} -inline int operator!=(REFGUID &g1, REFGUID &g2) - { return !(g1 == g2); } - -struct IUnknown -{ - STDMETHOD(QueryInterface) (const GUID *iid, void **outObject) PURE; - STDMETHOD_(ULONG, AddRef)() PURE; - STDMETHOD_(ULONG, Release)() PURE; -}; - -#endif - -#endif diff --git a/7zip/IPassword.h b/7zip/IPassword.h index 301031ae..a302b26c 100755 --- a/7zip/IPassword.h +++ b/7zip/IPassword.h @@ -1,11 +1,10 @@ // IPassword.h -// #pragma once - #ifndef __IPASSWORD_H #define __IPASSWORD_H -// #include "Common/Types.h" +#include "../Common/MyUnknown.h" +#include "../Common/Types.h" // {23170F69-40C1-278A-0000-000200250000} DEFINE_GUID(IID_ICryptoSetPassword, @@ -13,7 +12,7 @@ DEFINE_GUID(IID_ICryptoSetPassword, MIDL_INTERFACE("23170F69-40C1-278A-0000-000200250000") ICryptoSetPassword: public IUnknown { - STDMETHOD(CryptoSetPassword)(const BYTE *data, UINT32 size) PURE; + STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size) PURE; }; // {23170F69-40C1-278A-0000-000200251000} @@ -22,7 +21,7 @@ DEFINE_GUID(IID_ICryptoSetCRC, MIDL_INTERFACE("23170F69-40C1-278A-0000-000200251000") ICryptoSetCRC: public IUnknown { - STDMETHOD(CryptoSetCRC)(UINT32 crc) PURE; + STDMETHOD(CryptoSetCRC)(UInt32 crc) PURE; }; // {23170F69-40C1-278A-0000-000200270000} @@ -40,7 +39,7 @@ DEFINE_GUID(IID_ICryptoGetTextPassword2, MIDL_INTERFACE("23170F69-40C1-278A-0000-000200270200") ICryptoGetTextPassword2: public IUnknown { - STDMETHOD(CryptoGetTextPassword2)(INT32 *passwordIsDefined, BSTR *password) PURE; + STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password) PURE; }; #endif diff --git a/7zip/IProgress.h b/7zip/IProgress.h index db14b051..23edfc73 100755 --- a/7zip/IProgress.h +++ b/7zip/IProgress.h @@ -1,10 +1,11 @@ // Interface/IProgress.h -// #pragma once - #ifndef __IPROGRESS_H #define __IPROGRESS_H +#include "../Common/MyUnknown.h" +#include "../Common/Types.h" + // {23170F69-40C1-278A-0000-000000050000} DEFINE_GUID(IID_IProgress, 0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00); @@ -12,8 +13,8 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000000050000") IProgress: public IUnknown { public: - STDMETHOD(SetTotal)(UINT64 total) PURE; - STDMETHOD(SetCompleted)(const UINT64 *completeValue) PURE; + STDMETHOD(SetTotal)(UInt64 total) PURE; + STDMETHOD(SetCompleted)(const UInt64 *completeValue) PURE; }; /* @@ -24,8 +25,8 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000000050002") IProgress2: public IUnknown { public: - STDMETHOD(SetTotal)(const UINT64 *total) PURE; - STDMETHOD(SetCompleted)(const UINT64 *completeValue) PURE; + STDMETHOD(SetTotal)(const UInt64 *total) PURE; + STDMETHOD(SetCompleted)(const UInt64 *completeValue) PURE; }; */ diff --git a/7zip/IStream.h b/7zip/IStream.h index 147be411..fd98f771 100755 --- a/7zip/IStream.h +++ b/7zip/IStream.h @@ -1,11 +1,10 @@ // IStream.h -// #pragma once - #ifndef __ISTREAMS_H #define __ISTREAMS_H -#include "IMyUnknown.h" +#include "../Common/MyUnknown.h" +#include "../Common/Types.h" // {23170F69-40C1-278A-0000-000000010000} DEFINE_GUID(IID_ISequentialInStream, @@ -14,9 +13,15 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000000010000") ISequentialInStream : public IUnknown { public: - // out: if (processedSize == 0) then there are no more bytes - STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize) = 0; - STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize) = 0; + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) = 0; + STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize) = 0; + + // For both functions Out: if (*processedSize == 0) then + // there are no more bytes in stream. + // Read function always tries to read "size" bytes from stream. It + // can read less only if it reaches end of stream. + // ReadPart function can read X bytes: (0<=X<="size") and X can + // be less than number of remaining bytes in stream. }; // {23170F69-40C1-278A-0000-000000020000} @@ -26,8 +31,8 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000000020000") ISequentialOutStream : public IUnknown { public: - STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize) = 0; - STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize) = 0; + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) = 0; + STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize) = 0; }; // {23170F69-40C1-278A-0000-000000030000} @@ -37,7 +42,7 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000000030000") IInStream : public ISequentialInStream { public: - STDMETHOD(Seek)(INT64 offset, UINT32 seekOrigin, UINT64 *newPosition) = 0; + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) = 0; }; // {23170F69-40C1-278A-0000-000000040000} @@ -47,8 +52,8 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000000040000") IOutStream : public ISequentialOutStream { public: - STDMETHOD(Seek)(INT64 offset, UINT32 seekOrigin, UINT64 *newPosition) = 0; - STDMETHOD(SetSize)(INT64 aNewSize) = 0; + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) = 0; + STDMETHOD(SetSize)(Int64 newSize) = 0; }; // {23170F69-40C1-278A-0000-000000060000} @@ -58,7 +63,17 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000000060000") IStreamGetSize : public IUnknown { public: - STDMETHOD(GetSize)(UINT64 *size) = 0; + STDMETHOD(GetSize)(UInt64 *size) = 0; +}; + +// {23170F69-40C1-278A-0000-000000070000} +DEFINE_GUID(IID_IOutStreamFlush, +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00); +MIDL_INTERFACE("23170F69-40C1-278A-0000-000000070000") +IOutStreamFlush : public IUnknown +{ +public: + STDMETHOD(Flush)() = 0; }; #endif diff --git a/7zip/PropID.h b/7zip/PropID.h index d0e8e86e..9dafc4b6 100755 --- a/7zip/PropID.h +++ b/7zip/PropID.h @@ -1,7 +1,5 @@ // Interface/PropID.h -// #pragma once - #ifndef __INTERFACE_PROPID_H #define __INTERFACE_PROPID_H @@ -36,6 +34,7 @@ enum kpidGroup, kpidBlock, kpidComment, + kpidPosition, kpidTotalSize = 0x1100, kpidFreeSpace, diff --git a/7zip/UI/Agent/Agent.cpp b/7zip/UI/Agent/Agent.cpp index 2e59769a..3f0be7d2 100755 --- a/7zip/UI/Agent/Agent.cpp +++ b/7zip/UI/Agent/Agent.cpp @@ -8,11 +8,10 @@ #include "Windows/PropVariant.h" #include "Windows/FileFind.h" -#include "../Common/OpenArchive.h" #include "../Common/DefaultName.h" +#include "../Common/ArchiveExtractCallback.h" #include "Agent.h" -#include "ArchiveExtractCallback.h" #ifdef FORMAT_7Z #include "../../Archive/7z/7zHandler.h" @@ -62,8 +61,7 @@ STDMETHODIMP CAgentFolder::GetProperty(UINT32 itemIndex, PROPID propID, PROPVARI break; default: if (item.IsLeaf) - return _agentSpec->_archive->GetProperty(item.Index, - propID, value); + return _agentSpec->GetArchive()->GetProperty(item.Index, propID, value); } } else @@ -79,7 +77,7 @@ STDMETHODIMP CAgentFolder::GetProperty(UINT32 itemIndex, PROPID propID, PROPVARI propVariant = item.Name; break; default: - return _agentSpec->_archive->GetProperty(item.Index, + return _agentSpec->GetArchive()->GetProperty(item.Index, propID, value); } } @@ -140,7 +138,7 @@ struct CArchiveItemPropertyTemp STDMETHODIMP CAgentFolder::GetNumberOfProperties(UINT32 *numProperties) { COM_TRY_BEGIN - return _agentSpec->_archive->GetNumberOfProperties(numProperties); + return _agentSpec->GetArchive()->GetNumberOfProperties(numProperties); COM_TRY_END } @@ -148,7 +146,7 @@ STDMETHODIMP CAgentFolder::GetPropertyInfo(UINT32 index, BSTR *name, PROPID *propID, VARTYPE *varType) { COM_TRY_BEGIN - RINOK(_agentSpec->_archive->GetPropertyInfo(index, name, propID, varType)); + RINOK(_agentSpec->GetArchive()->GetPropertyInfo(index, name, propID, varType)); if (*propID == kpidPath) *propID = kpidName; return S_OK; @@ -200,8 +198,8 @@ STDMETHODIMP CAgentFolder::GetPath(BSTR *path) STDMETHODIMP CAgentFolder::Extract(const UINT32 *indices, UINT32 numItems, - NExtractionMode::NPath::EEnum pathMode, - NExtractionMode::NOverwrite::EEnum overwriteMode, + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, const wchar_t *path, INT32 testMode, IFolderArchiveExtractCallback *extractCallback2) @@ -216,8 +214,9 @@ STDMETHODIMP CAgentFolder::Extract(const UINT32 *indices, pathParts.Insert(0, currentProxyFolder->Name); currentProxyFolder = currentProxyFolder->Parent; } - extractCallbackSpec->Init(_agentSpec->_archive, + extractCallbackSpec->Init(_agentSpec->GetArchive(), extractCallback2, + false, path, pathMode, overwriteMode, @@ -229,7 +228,7 @@ STDMETHODIMP CAgentFolder::Extract(const UINT32 *indices, ); CUIntVector realIndices; _proxyFolderItem->GetRealIndices(indices, numItems, realIndices); - return _agentSpec->_archive->Extract(&realIndices.Front(), + return _agentSpec->GetArchive()->Extract(&realIndices.Front(), realIndices.Size(), testMode, extractCallback); COM_TRY_END } @@ -262,23 +261,19 @@ STDMETHODIMP CAgent::Open( return ::GetLastError(); if (fileInfo.IsDirectory()) return E_FAIL; - CArchiverInfo archiverInfo; - int subExtIndex; - HRESULT res = OpenArchive(_archiveFilePath, - #ifndef EXCLUDE_COM - &_library, - #endif - &_archive, archiverInfo, subExtIndex, openArchiveCallback); + CArchiverInfo archiverInfo0, archiverInfo1; + HRESULT res = OpenArchive(_archiveFilePath, _archiveLink, openArchiveCallback); + // _archive = _archiveLink.GetArchive(); + DefaultName = _archiveLink.GetDefaultItemName(); + const CArchiverInfo &ai = _archiveLink.GetArchiverInfo(); + RINOK(res); - DefaultName = GetDefaultName(_archiveFilePath, - archiverInfo.Extensions[subExtIndex].Extension, - archiverInfo.Extensions[subExtIndex].AddExtension); DefaultTime = fileInfo.LastWriteTime; DefaultAttributes = fileInfo.Attributes; - ArchiveType = archiverInfo.Name; + ArchiveType = ai.Name; if (archiveType != 0) { - CMyComBSTR name = archiverInfo.Name; + CMyComBSTR name = ArchiveType; *archiveType = name.Detach(); } return S_OK; @@ -295,7 +290,7 @@ STDMETHODIMP CAgent::ReOpen( delete _proxyArchive; _proxyArchive = NULL; } - RINOK(ReOpenArchive(_archive, _archiveFilePath)); + RINOK(ReOpenArchive(_archiveLink, _archiveFilePath)); return ReadItems(); COM_TRY_END } @@ -303,7 +298,13 @@ STDMETHODIMP CAgent::ReOpen( STDMETHODIMP CAgent::Close() { COM_TRY_BEGIN - return _archive->Close(); + RINOK(_archiveLink.Close()); + if (_archiveLink.GetNumLevels() > 1) + { + // return S_OK; + } + // _archive->Close(); + return S_OK; COM_TRY_END } @@ -319,7 +320,7 @@ HRESULT CAgent::ReadItems() if (_proxyArchive != NULL) return S_OK; _proxyArchive = new CProxyArchive(); - return _proxyArchive->Load(_archive, + return _proxyArchive->Load(GetArchive(), DefaultName, // _defaultTime, // _defaultAttributes, @@ -340,8 +341,8 @@ STDMETHODIMP CAgent::BindToRootFolder(IFolderFolder **resultFolder) STDMETHODIMP CAgent::Extract( - NExtractionMode::NPath::EEnum pathMode, - NExtractionMode::NOverwrite::EEnum overwriteMode, + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, const wchar_t *path, INT32 testMode, IFolderArchiveExtractCallback *extractCallback2) @@ -349,8 +350,9 @@ STDMETHODIMP CAgent::Extract( COM_TRY_BEGIN CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback; CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec; - extractCallbackSpec->Init(_archive, + extractCallbackSpec->Init(GetArchive(), extractCallback2, + false, path, pathMode, overwriteMode, @@ -360,14 +362,14 @@ STDMETHODIMP CAgent::Extract( DefaultAttributes // ,_srcDirectoryPrefix ); - return _archive->Extract(0, -1, testMode, extractCallback); + return GetArchive()->Extract(0, -1, testMode, extractCallback); COM_TRY_END } STDMETHODIMP CAgent::GetNumberOfProperties(UINT32 *numProperties) { COM_TRY_BEGIN - return _archive->GetNumberOfProperties(numProperties); + return GetArchive()->GetNumberOfProperties(numProperties); COM_TRY_END } @@ -375,7 +377,7 @@ STDMETHODIMP CAgent::GetPropertyInfo(UINT32 index, BSTR *name, PROPID *propID, VARTYPE *varType) { COM_TRY_BEGIN - RINOK(_archive->GetPropertyInfo(index, name, propID, varType)); + RINOK(GetArchive()->GetPropertyInfo(index, name, propID, varType)); if (*propID == kpidPath) *propID = kpidName; return S_OK; @@ -385,14 +387,14 @@ STDMETHODIMP CAgent::GetPropertyInfo(UINT32 index, STDMETHODIMP CAgent::GetArchiveProperty(PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN - return _archive->GetArchiveProperty(propID, value); + return GetArchive()->GetArchiveProperty(propID, value); COM_TRY_END } STDMETHODIMP CAgent::GetNumberOfArchiveProperties(UINT32 *numProperties) { COM_TRY_BEGIN - return _archive->GetNumberOfArchiveProperties(numProperties); + return GetArchive()->GetNumberOfArchiveProperties(numProperties); COM_TRY_END } @@ -400,7 +402,7 @@ STDMETHODIMP CAgent::GetArchivePropertyInfo(UINT32 index, BSTR *name, PROPID *propID, VARTYPE *varType) { COM_TRY_BEGIN - return _archive->GetArchivePropertyInfo(index, + return GetArchive()->GetArchivePropertyInfo(index, name, propID, varType); COM_TRY_END } diff --git a/7zip/UI/Agent/Agent.h b/7zip/UI/Agent/Agent.h index b3c73a5c..a2325daf 100755 --- a/7zip/UI/Agent/Agent.h +++ b/7zip/UI/Agent/Agent.h @@ -1,15 +1,16 @@ // Agent/Agent.h -#pragma once - #ifndef __AGENT_AGENT_H #define __AGENT_AGENT_H -#include "Windows/PropVariant.h" +#include <vector> + #include "Common/MyCom.h" +#include "Windows/PropVariant.h" #include "../Common/UpdateAction.h" #include "../Common/ArchiverInfo.h" +#include "../Common/OpenArchive.h" #include "IFolderArchive.h" #include "AgentProxy.h" @@ -74,8 +75,8 @@ public: // IArchiveFolder STDMETHOD(Extract)(const UINT32 *indices, UINT32 numItems, - NExtractionMode::NPath::EEnum pathMode, - NExtractionMode::NOverwrite::EEnum overwriteMode, + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, const wchar_t *path, INT32 testMode, IFolderArchiveExtractCallback *extractCallback); @@ -137,6 +138,7 @@ public: CMyComPtr<IFolderFolder> _parentFolder; CMyComPtr<IInFolderArchive> _agent; CAgent *_agentSpec; +private: }; // {23170F69-40C1-278A-1000-000100030000} @@ -189,8 +191,8 @@ public: BSTR *name, PROPID *propID, VARTYPE *varType); STDMETHOD(BindToRootFolder)(IFolderFolder **resultFolder); STDMETHOD(Extract)( - NExtractionMode::NPath::EEnum pathMode, - NExtractionMode::NOverwrite::EEnum overwriteMode, + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, const wchar_t *path, INT32 testMode, IFolderArchiveExtractCallback *extractCallback2); @@ -204,11 +206,12 @@ public: const wchar_t *filePath, const CLSID *clsID, const wchar_t *newArchiveName, - const BYTE *stateActions, + const Byte *stateActions, const wchar_t *sfxModule, IFolderArchiveUpdateCallback *updateCallback); - HRESULT CommonUpdate(const wchar_t *newArchiveName, + HRESULT CommonUpdate( + const wchar_t *newArchiveName, int numUpdateItems, IArchiveUpdateCallback *updateCallback); @@ -224,7 +227,7 @@ public: IFolderArchiveUpdateCallback *updateCallback100); // ISetProperties - STDMETHOD(SetProperties)(const BSTR *names, const PROPVARIANT *values, INT32 numProperties); + STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, INT32 numProperties); #endif CAgent(); @@ -234,16 +237,14 @@ private: public: CProxyArchive *_proxyArchive; - #ifndef EXCLUDE_COM - NWindows::NDLL::CLibrary _library; - #endif - - CMyComPtr<IInArchive> _archive; + CArchiveLink _archiveLink; + // IInArchive *_archive2; // CLSID _CLSID; // CMyComPtr<IArchiveFolder> m_RootFolder; UString DefaultName; + FILETIME DefaultTime; UINT32 DefaultAttributes; @@ -258,9 +259,12 @@ public: UString _archiveFilePath; #ifndef EXTRACT_ONLY - CObjectVector<CMyComBSTR> m_PropNames; + CObjectVector<UString> m_PropNames; std::vector<NWindows::NCOM::CPropVariant> m_PropValues; #endif + + IInArchive *GetArchive() { return _archiveLink.GetArchive(); } + bool CanUpdate() const { return _archiveLink.GetNumLevels() <= 1; } }; #ifdef NEW_FOLDER_INTERFACE diff --git a/7zip/UI/Agent/AgentOut.cpp b/7zip/UI/Agent/AgentOut.cpp index 7f1f8e77..7368550f 100755 --- a/7zip/UI/Agent/AgentOut.cpp +++ b/7zip/UI/Agent/AgentOut.cpp @@ -1,26 +1,26 @@ -// Zip/Handler.cpp +// AgentOutcpp #include "StdAfx.h" -#include "../Common/UpdatePair.h" -#include "../Common/EnumDirItems.h" -#include "../Common/HandlerLoader.h" -// #include "../Common/UpdatePairAction.h" -// #include "../Common/CompressEngineCommon.h" -// #include "../Common/UpdateProducer.h" -#include "../../Compress/Copy/CopyCoder.h" - #include "Common/StringConvert.h" +#include "Common/IntToString.h" #include "Windows/Defs.h" #include "Windows/PropVariant.h" #include "Windows/PropVariantConversions.h" #include "Windows/FileDir.h" +#include "../../Compress/Copy/CopyCoder.h" #include "../../Common/FileStreams.h" +#include "../Common/UpdatePair.h" +#include "../Common/EnumDirItems.h" +#include "../Common/HandlerLoader.h" +#include "../Common/UpdateCallback.h" +#include "../Common/OpenArchive.h" + #include "Agent.h" -#include "ArchiveUpdateCallback.h" +#include "UpdateCallbackAgent.h" using namespace NWindows; using namespace NCOM; @@ -90,7 +90,7 @@ STDMETHODIMP CAgent::SetFiles(const wchar_t *folderPrefix, static HRESULT GetFileTime(CAgent *agent, UINT32 itemIndex, FILETIME &fileTime) { CPropVariant property; - RINOK(agent->_archive->GetProperty(itemIndex, kpidLastWriteTime, &property)); + RINOK(agent->GetArchive()->GetProperty(itemIndex, kpidLastWriteTime, &property)); if (property.vt == VT_FILETIME) fileTime = property.filetime; else if (property.vt == VT_EMPTY) @@ -114,9 +114,9 @@ static HRESULT EnumerateArchiveItems(CAgent *agent, RINOK(::GetFileTime(agent, fileItem.Index, archiveItem.LastWriteTime)); CPropVariant property; - agent->_archive->GetProperty(fileItem.Index, kpidSize, &property); + agent->GetArchive()->GetProperty(fileItem.Index, kpidSize, &property); if (archiveItem.SizeIsDefined = (property.vt != VT_EMPTY)) - archiveItem.Size = ConvertPropVariantToUINT64(property); + archiveItem.Size = ConvertPropVariantToUInt64(property); archiveItem.IsDirectory = false; archiveItem.Name = prefix + fileItem.Name; archiveItem.Censored = true; // test it @@ -147,10 +147,12 @@ STDMETHODIMP CAgent::DoOperation( const wchar_t *filePath, const CLSID *clsID, const wchar_t *newArchiveName, - const BYTE *stateActions, + const Byte *stateActions, const wchar_t *sfxModule, IFolderArchiveUpdateCallback *updateCallback100) { + if (!CanUpdate()) + return E_NOTIMPL; NUpdateArchive::CActionSet actionSet; for (int i = 0; i < NUpdateArchive::NPairState::kNumValues; i++) actionSet.StateActions[i] = (NUpdateArchive::NPairAction::EEnum)stateActions[i]; @@ -159,18 +161,20 @@ STDMETHODIMP CAgent::DoOperation( UString folderPrefix = _folderPrefix; NFile::NName::NormalizeDirPathPrefix(folderPrefix); - ::EnumerateDirItems(folderPrefix, _names, _archiveNamePrefix, dirItems); + RINOK(::EnumerateDirItems(folderPrefix, _names, _archiveNamePrefix, dirItems)); + + NWindows::NDLL::CLibrary library; CMyComPtr<IOutArchive> outArchive; - if (_archive) + if (GetArchive()) { - RINOK(_archive.QueryInterface(IID_IOutArchive, &outArchive)); + RINOK(GetArchive()->QueryInterface(IID_IOutArchive, (void **)&outArchive)); } else { CHandlerLoader loader; RINOK(loader.CreateHandler(filePath, *clsID, (void **)&outArchive, true)); - _library.Attach(loader.Detach()); + library.Attach(loader.Detach()); } NFileTimeType::EEnum fileTimeType; @@ -191,7 +195,7 @@ STDMETHODIMP CAgent::DoOperation( CObjectVector<CUpdatePair> updatePairs; CObjectVector<CArchiveItem> archiveItems; - if (_archive) + if (GetArchive()) { RINOK(ReadItems()); EnumerateArchiveItems(this, _proxyArchive->RootFolder, L"", archiveItems); @@ -199,16 +203,22 @@ STDMETHODIMP CAgent::DoOperation( GetUpdatePairInfoList(dirItems, archiveItems, fileTimeType, updatePairs); - CObjectVector<CUpdatePair2> operationChain; + CObjectVector<CUpdatePair2> updatePairs2; UpdateProduce(dirItems, archiveItems, updatePairs, actionSet, - operationChain); + updatePairs2); + CUpdateCallbackAgent updateCallbackAgent; + updateCallbackAgent.Callback = updateCallback100; CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec ); - - updateCallbackSpec->Init(folderPrefix,&dirItems, &archiveItems, - &operationChain, NULL, updateCallback100); - + + updateCallbackSpec->DirPrefix = folderPrefix; + updateCallbackSpec->DirItems = &dirItems; + updateCallbackSpec->ArchiveItems = &archiveItems; + updateCallbackSpec->UpdatePairs = &updatePairs2; + updateCallbackSpec->Archive = GetArchive(); + updateCallbackSpec->Callback = &updateCallbackAgent; + COutFileStream *outStreamSpec = new COutFileStream; CMyComPtr<IOutStream> outStream(outStreamSpec); UString archiveName = newArchiveName; @@ -219,7 +229,7 @@ STDMETHODIMP CAgent::DoOperation( throw 141716; NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos)); } - if (!outStreamSpec->Open(archiveName)) + if (!outStreamSpec->Create(archiveName, true)) { // ShowLastErrorMessage(); return E_FAIL; @@ -234,11 +244,12 @@ STDMETHODIMP CAgent::DoOperation( } else { - std::vector<BSTR> names; + CRecordVector<const wchar_t *> names; for(i = 0; i < m_PropNames.Size(); i++) - names.push_back(m_PropNames[i]); - RINOK(setProperties->SetProperties(&names.front(), - &m_PropValues.front(), names.size())); + names.Add((const wchar_t *)m_PropNames[i]); + + RINOK(setProperties->SetProperties(&names.Front(), + &m_PropValues.front(), names.Size())); } } m_PropNames.Clear(); @@ -253,20 +264,24 @@ STDMETHODIMP CAgent::DoOperation( RINOK(CopyBlock(sfxStream, outStream)); } - return outArchive->UpdateItems(outStream, operationChain.Size(), + return outArchive->UpdateItems(outStream, updatePairs2.Size(), updateCallback); } -HRESULT CAgent::CommonUpdate(const wchar_t *newArchiveName, +HRESULT CAgent::CommonUpdate( + const wchar_t *newArchiveName, int numUpdateItems, IArchiveUpdateCallback *updateCallback) { + if (!CanUpdate()) + return E_NOTIMPL; CMyComPtr<IOutArchive> outArchive; - RINOK(_archive.QueryInterface(IID_IOutArchive, &outArchive)); + RINOK(GetArchive()->QueryInterface(IID_IOutArchive, (void **)&outArchive)); COutFileStream *outStreamSpec = new COutFileStream; CMyComPtr<IOutStream> outStream(outStreamSpec); + UString archiveName = newArchiveName; { UString resultPath; @@ -275,7 +290,30 @@ HRESULT CAgent::CommonUpdate(const wchar_t *newArchiveName, throw 141716; NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos)); } - if (!outStreamSpec->Open(archiveName)) + + /* + bool isOK = false; + for (int i = 0; i < (1 << 16); i++) + { + resultName = newArchiveName; + if (i > 0) + { + wchar_t s[32]; + ConvertUInt64ToString(i, s); + resultName += s; + } + if (outStreamSpec->Open(realPath)) + { + isOK = true; + break; + } + if (::GetLastError() != ERROR_FILE_EXISTS) + return ::GetLastError(); + } + if (!isOK) + return ::GetLastError(); + */ + if (!outStreamSpec->Create(archiveName, true)) { // ShowLastErrorMessage(); return E_FAIL; @@ -290,6 +328,10 @@ STDMETHODIMP CAgent::DeleteItems( const UINT32 *indices, UINT32 numItems, IFolderArchiveUpdateCallback *updateCallback100) { + if (!CanUpdate()) + return E_NOTIMPL; + CUpdateCallbackAgent updateCallbackAgent; + updateCallbackAgent.Callback = updateCallback100; CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec); @@ -298,7 +340,7 @@ STDMETHODIMP CAgent::DeleteItems( CObjectVector<CUpdatePair2> updatePairs; int curIndex = 0; UINT32 numItemsInArchive; - RINOK(_archive->GetNumberOfItems(&numItemsInArchive)); + RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive)); for (int i = 0; i < numItemsInArchive; i++) { if (curIndex < realIndices.Size()) @@ -311,11 +353,13 @@ STDMETHODIMP CAgent::DeleteItems( updatePair.NewData = updatePair.NewProperties = false; updatePair.ExistInArchive = true; updatePair.ExistOnDisk = false; - updatePair.IsAnti = false; + updatePair.IsAnti = false; // check it. Maybe it can be undefined updatePair.ArchiveItemIndex = i; updatePairs.Add(updatePair); } - updateCallbackSpec->Init(L"", NULL, NULL, &updatePairs, NULL, updateCallback100); + updateCallbackSpec->UpdatePairs = &updatePairs; + updateCallbackSpec->Archive = GetArchive(); + updateCallbackSpec->Callback = &updateCallbackAgent; return CommonUpdate(newArchiveName, updatePairs.Size(), updateCallback); } @@ -324,19 +368,23 @@ HRESULT CAgent::CreateFolder( const wchar_t *folderName, IFolderArchiveUpdateCallback *updateCallback100) { + if (!CanUpdate()) + return E_NOTIMPL; + CUpdateCallbackAgent updateCallbackAgent; + updateCallbackAgent.Callback = updateCallback100; CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec); CObjectVector<CUpdatePair2> updatePairs; UINT32 numItemsInArchive; - RINOK(_archive->GetNumberOfItems(&numItemsInArchive)); + RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive)); for (int i = 0; i < numItemsInArchive; i++) { CUpdatePair2 updatePair; updatePair.NewData = updatePair.NewProperties = false; updatePair.ExistInArchive = true; updatePair.ExistOnDisk = false; - updatePair.IsAnti = false; + updatePair.IsAnti = false; // check it. updatePair.ArchiveItemIndex = i; updatePairs.Add(updatePair); } @@ -366,7 +414,10 @@ HRESULT CAgent::CreateFolder( dirItems.Add(dirItem); - updateCallbackSpec->Init(L"", &dirItems, NULL, &updatePairs, NULL, updateCallback100); + updateCallbackSpec->Callback = &updateCallbackAgent; + updateCallbackSpec->DirItems = &dirItems; + updateCallbackSpec->UpdatePairs = &updatePairs; + updateCallbackSpec->Archive = GetArchive(); return CommonUpdate(newArchiveName, updatePairs.Size(), updateCallback); } @@ -377,8 +428,12 @@ HRESULT CAgent::RenameItem( const wchar_t *newItemName, IFolderArchiveUpdateCallback *updateCallback100) { + if (!CanUpdate()) + return E_NOTIMPL; if (numItems != 1) return E_INVALIDARG; + CUpdateCallbackAgent updateCallbackAgent; + updateCallbackAgent.Callback = updateCallback100; CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec); @@ -393,7 +448,7 @@ HRESULT CAgent::RenameItem( CObjectVector<CUpdatePair2> updatePairs; int curIndex = 0; UINT32 numItemsInArchive; - RINOK(_archive->GetNumberOfItems(&numItemsInArchive)); + RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive)); for (int i = 0; i < numItemsInArchive; i++) { if (curIndex < realIndices.Size()) @@ -404,37 +459,19 @@ HRESULT CAgent::RenameItem( updatePair.NewProperties = true; updatePair.ExistInArchive = true; updatePair.ExistOnDisk = false; - updatePair.IsAnti = false; // ? + RINOK(IsArchiveItemAnti(GetArchive(), i, updatePair.IsAnti)); updatePair.ArchiveItemIndex = i; updatePair.NewNameIsDefined = true; updatePair.NewName = newItemName; UString oldFullPath; - { - NCOM::CPropVariant propVariant; - RINOK(_archive->GetProperty( - updatePair.ArchiveItemIndex, kpidPath, &propVariant)); - if (propVariant.vt != VT_BSTR) - return E_INVALIDARG; - oldFullPath = propVariant.bstrVal; - } + RINOK(GetArchiveItemPath(GetArchive(), i, DefaultName, oldFullPath)); + if (oldItemPath.CollateNoCase(oldFullPath.Left(oldItemPath.Length())) != 0) return E_INVALIDARG; - { - NCOM::CPropVariant propVariant; - RINOK(_archive->GetProperty(i, kpidIsAnti, &propVariant)); - if (propVariant.vt == VT_EMPTY) - updatePair.IsAnti = false; - else if (propVariant.vt != VT_BOOL) - return E_INVALIDARG; - else - updatePair.IsAnti = (propVariant.boolVal != VARIANT_FALSE); - } - updatePair.NewName = newItemPath + oldFullPath.Mid(oldItemPath.Length()); - updatePairs.Add(updatePair); curIndex++; continue; @@ -447,13 +484,13 @@ HRESULT CAgent::RenameItem( updatePair.ArchiveItemIndex = i; updatePairs.Add(updatePair); } - updateCallbackSpec->Init(L"", NULL, NULL, &updatePairs, _archive, updateCallback100); + updateCallbackSpec->Callback = &updateCallbackAgent; + updateCallbackSpec->UpdatePairs = &updatePairs; + updateCallbackSpec->Archive = GetArchive(); return CommonUpdate(newArchiveName, updatePairs.Size(), updateCallback); } - - -STDMETHODIMP CAgent::SetProperties(const BSTR *names, +STDMETHODIMP CAgent::SetProperties(const wchar_t **names, const PROPVARIANT *values, INT32 numProperties) { m_PropNames.Clear(); diff --git a/7zip/UI/Agent/AgentProxy.cpp b/7zip/UI/Agent/AgentProxy.cpp index f2627e6d..a77656bb 100755 --- a/7zip/UI/Agent/AgentProxy.cpp +++ b/7zip/UI/Agent/AgentProxy.cpp @@ -7,6 +7,7 @@ #include "Common/MyCom.h" #include "Windows/PropVariant.h" #include "Windows/Defs.h" +#include "../Common/OpenArchive.h" using namespace NWindows; @@ -184,11 +185,9 @@ HRESULT CProxyArchive::ReadObjects(IInArchive *archiveHandler, IProgress *progre } NCOM::CPropVariant propVariantIsFolder; - RINOK(archiveHandler->GetProperty(i, - kpidIsFolder, &propVariantIsFolder)); - if(propVariantIsFolder.vt != VT_BOOL) - return E_FAIL; - if(VARIANT_BOOLToBool(propVariantIsFolder.boolVal)) + bool isFolder; + RINOK(IsArchiveItemFolder(archiveHandler, i, isFolder)); + if(isFolder) currentItem->AddDirSubItem(i, true, fileName); else currentItem->AddFileSubItem(i, fileName); diff --git a/7zip/UI/Agent/AgentProxy.h b/7zip/UI/Agent/AgentProxy.h index d07b8a10..9402cfdd 100755 --- a/7zip/UI/Agent/AgentProxy.h +++ b/7zip/UI/Agent/AgentProxy.h @@ -1,7 +1,5 @@ // AgentProxy.h -#pragma once - #ifndef __AGENT_PROXY_H #define __AGENT_PROXY_H diff --git a/7zip/UI/Agent/ArchiveFolder.cpp b/7zip/UI/Agent/ArchiveFolder.cpp index 4701653d..cb834fcc 100755 --- a/7zip/UI/Agent/ArchiveFolder.cpp +++ b/7zip/UI/Agent/ArchiveFolder.cpp @@ -12,9 +12,9 @@ #include "../../Common/FileStreams.h" #include "../Common/UpdatePair.h" +#include "../Common/ArchiveExtractCallback.h" #include "Agent.h" -#include "ArchiveExtractCallback.h" using namespace NWindows; using namespace NCOM; @@ -41,11 +41,12 @@ STDMETHODIMP CAgentFolder::CopyTo(const UINT32 *indices, UINT32 numItems, IID_IFolderArchiveExtractCallback, &extractCallback2)); } - extractCallbackSpec->Init(_agentSpec->_archive, + extractCallbackSpec->Init(_agentSpec->GetArchive(), extractCallback2, + false, path, - NExtractionMode::NPath::kCurrentPathnames, - NExtractionMode::NOverwrite::kAskBefore, + NExtract::NPathMode::kCurrentPathnames, + NExtract::NOverwriteMode::kAskBefore, pathParts, _agentSpec->DefaultName, _agentSpec->DefaultTime, @@ -54,7 +55,7 @@ STDMETHODIMP CAgentFolder::CopyTo(const UINT32 *indices, UINT32 numItems, ); CUIntVector realIndices; _proxyFolderItem->GetRealIndices(indices, numItems, realIndices); - return _agentSpec->_archive->Extract(&realIndices.Front(), + return _agentSpec->GetArchive()->Extract(&realIndices.Front(), realIndices.Size(), BoolToInt(false), extractCallback); COM_TRY_END } diff --git a/7zip/UI/Agent/ArchiveFolderOpen.cpp b/7zip/UI/Agent/ArchiveFolderOpen.cpp index 2e6defc7..7a843c3f 100755 --- a/7zip/UI/Agent/ArchiveFolderOpen.cpp +++ b/7zip/UI/Agent/ArchiveFolderOpen.cpp @@ -8,7 +8,7 @@ #include "../Common/OpenArchive.h" -static const UINT64 kMaxCheckStartPosition = 1 << 20; +static const UInt64 kMaxCheckStartPosition = 1 << 20; static inline UINT GetCurrentFileCodePage() { return AreFileApisANSI() ? CP_ACP : CP_OEMCP; } diff --git a/7zip/UI/Agent/ArchiveFolderOut.cpp b/7zip/UI/Agent/ArchiveFolderOut.cpp index fed01b78..b16d106d 100755 --- a/7zip/UI/Agent/ArchiveFolderOut.cpp +++ b/7zip/UI/Agent/ArchiveFolderOut.cpp @@ -85,7 +85,7 @@ HRESULT CAgentFolder::CommonUpdateOperation( } else { - BYTE actionSetByte[NUpdateArchive::NPairState::kNumValues]; + Byte actionSetByte[NUpdateArchive::NPairState::kNumValues]; for (int i = 0; i < NUpdateArchive::NPairState::kNumValues; i++) actionSetByte[i] = actionSet->StateActions[i]; result = _agentSpec->DoOperation(NULL, NULL, diff --git a/7zip/UI/Agent/ArchiveUpdateCallback.cpp b/7zip/UI/Agent/ArchiveUpdateCallback.cpp deleted file mode 100755 index fd0c136e..00000000 --- a/7zip/UI/Agent/ArchiveUpdateCallback.cpp +++ /dev/null @@ -1,229 +0,0 @@ -// ArchiveUpdateCallback.h - -#include "StdAfx.h" - -#include "ArchiveUpdateCallback.h" - -#include "Common/StringConvert.h" -#include "Common/Defs.h" - -#include "Windows/FileName.h" -#include "Windows/PropVariant.h" - -#include "../../Common/FileStreams.h" - -#include "Windows/Defs.h" - -using namespace NWindows; - -void CArchiveUpdateCallback::Init(const UString &baseFolderPrefix, - const CObjectVector<CDirItem> *dirItems, - const CObjectVector<CArchiveItem> *archiveItems, // test CItemInfoExList - CObjectVector<CUpdatePair2> *updatePairs, - IInArchive *inArchive, - IFolderArchiveUpdateCallback *updateCallback) -{ - m_BaseFolderPrefix = baseFolderPrefix; - NFile::NName::NormalizeDirPathPrefix(m_BaseFolderPrefix); - m_DirItems = dirItems; - m_ArchiveItems = archiveItems; - m_UpdatePairs = updatePairs; - m_UpdateCallback = updateCallback; - m_CodePage = ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; - _inArchive = inArchive;; -} - -STDMETHODIMP CArchiveUpdateCallback::SetTotal(UINT64 size) -{ - if (m_UpdateCallback) - return m_UpdateCallback->SetTotal(size); - return S_OK; -} - -STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UINT64 *completeValue) -{ - if (m_UpdateCallback) - return m_UpdateCallback->SetCompleted(completeValue); - return S_OK; -} - -/* -STATPROPSTG kProperties[] = -{ - { NULL, kpidPath, VT_BSTR}, - { NULL, kpidIsFolder, VT_BOOL}, - { NULL, kpidSize, VT_UI8}, - { NULL, kpidLastAccessTime, VT_FILETIME}, - { NULL, kpidCreationTime, VT_FILETIME}, - { NULL, kpidLastWriteTime, VT_FILETIME}, - { NULL, kpidAttributes, VT_UI4}, - { NULL, kpidIsAnti, VT_BOOL} -}; - -STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **enumerator) -{ - return CStatPropEnumerator::CreateEnumerator(kProperties, - sizeof(kProperties) / sizeof(kProperties[0]), enumerator); -} -*/ - -STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UINT32 index, - INT32 *newData, INT32 *newProperties, UINT32 *indexInArchive) -{ - const CUpdatePair2 &updatePair = (*m_UpdatePairs)[index]; - if(newData != NULL) - *newData = BoolToInt(updatePair.NewData); - if(newProperties != NULL) - *newProperties = BoolToInt(updatePair.NewProperties); - if(indexInArchive != NULL) - { - if (updatePair.ExistInArchive) - { - if (m_ArchiveItems == 0) - *indexInArchive = updatePair.ArchiveItemIndex; - else - *indexInArchive = (*m_ArchiveItems)[updatePair.ArchiveItemIndex].IndexInServer; - } - else - *indexInArchive = UINT32(-1); - } - return S_OK; -} - -STDMETHODIMP CArchiveUpdateCallback::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value) -{ - const CUpdatePair2 &updatePair = (*m_UpdatePairs)[index]; - NWindows::NCOM::CPropVariant propVariant; - - if (propID == kpidIsAnti) - { - propVariant = updatePair.IsAnti; - propVariant.Detach(value); - return S_OK; - } - - if (updatePair.IsAnti) - { - switch(propID) - { - case kpidIsFolder: - case kpidPath: - break; - case kpidSize: - propVariant = (UINT64)0; - propVariant.Detach(value); - return S_OK; - default: - propVariant.Detach(value); - return S_OK; - } - } - - if(updatePair.ExistOnDisk) - { - const CDirItem &dirItem = (*m_DirItems)[updatePair.DirItemIndex]; - switch(propID) - { - case kpidPath: - propVariant = dirItem.Name; - break; - case kpidIsFolder: - propVariant = dirItem.IsDirectory(); - break; - case kpidSize: - propVariant = dirItem.Size; - break; - case kpidAttributes: - propVariant = dirItem.Attributes; - break; - case kpidLastAccessTime: - propVariant = dirItem.LastAccessTime; - break; - case kpidCreationTime: - propVariant = dirItem.CreationTime; - break; - case kpidLastWriteTime: - propVariant = dirItem.LastWriteTime; - break; - } - } - else - { - if (propID == kpidPath) - { - if (updatePair.NewNameIsDefined) - { - propVariant = updatePair.NewName; - propVariant.Detach(value); - return S_OK; - } - } - if (updatePair.ExistInArchive && _inArchive) - { - UINT32 indexInArchive; - if (m_ArchiveItems == 0) - indexInArchive = updatePair.ArchiveItemIndex; - else - indexInArchive = (*m_ArchiveItems)[updatePair.ArchiveItemIndex].IndexInServer; - return _inArchive->GetProperty(indexInArchive, propID, value); - } - } - propVariant.Detach(value); - return S_OK; -} - -STDMETHODIMP CArchiveUpdateCallback::GetStream(UINT32 index, - IInStream **inStream) -{ - const CUpdatePair2 &updatePair = (*m_UpdatePairs)[index]; - if(!updatePair.NewData) - return E_FAIL; - const CDirItem &dirItem = (*m_DirItems)[updatePair.DirItemIndex]; - - /* - m_PercentPrinter.PrintString("Compressing "); - m_PercentCanBePrint = true; - m_PercentPrinter.PrintString(UnicodeStringToMultiByte(dirItem.Name, CP_OEMCP)); - m_PercentPrinter.PreparePrint(); - m_PercentPrinter.RePrintRatio(); - */ - - if (m_UpdateCallback) - { - RINOK(m_UpdateCallback->CompressOperation( - GetUnicodeString(dirItem.FullPath, m_CodePage))); - } - - if(dirItem.IsDirectory()) - return S_OK; - - CInFileStream *inStreamSpec = new CInFileStream; - CMyComPtr<IInStream> inStreamLoc(inStreamSpec); - if(!inStreamSpec->Open(m_BaseFolderPrefix + dirItem.FullPath)) - return ::GetLastError(); - - *inStream = inStreamLoc.Detach(); - return S_OK; -} - -STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(INT32 operationResult) -{ - if (m_UpdateCallback) - return m_UpdateCallback->OperationResult(operationResult); - return S_OK; -} - -STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(INT32 *passwordIsDefined, BSTR *password) -{ - *passwordIsDefined = BoolToInt(false); - if (!_cryptoGetTextPassword) - { - if (!m_UpdateCallback) - return S_OK; - HRESULT result = m_UpdateCallback.QueryInterface( - IID_ICryptoGetTextPassword2, &_cryptoGetTextPassword); - if (result != S_OK) - return S_OK; - } - return _cryptoGetTextPassword->CryptoGetTextPassword2(passwordIsDefined, password); -} diff --git a/7zip/UI/Agent/ArchiveUpdateCallback.h b/7zip/UI/Agent/ArchiveUpdateCallback.h deleted file mode 100755 index bef5dbc3..00000000 --- a/7zip/UI/Agent/ArchiveUpdateCallback.h +++ /dev/null @@ -1,71 +0,0 @@ -// ArchiveUpdateCallback.h - -#pragma once - -#ifndef __ARCHIVEUPDATECALLBACK_H -#define __ARCHIVEUPDATECALLBACK_H - -#include "../../Archive/IArchive.h" -#include "../../IPassword.h" -#include "IFolderArchive.h" - -#include "Common/String.h" -#include "Common/MyCom.h" - -#include "../Common/UpdateProduce.h" -// #include "Interface/CryptoInterface.h" -// #include "Interface/MyCom.h" - -class CArchiveUpdateCallback: - public IArchiveUpdateCallback, - public ICryptoGetTextPassword2, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP1(ICryptoGetTextPassword2) - - - // IProgress - - STDMETHOD(SetTotal)(UINT64 size); - STDMETHOD(SetCompleted)(const UINT64 *completeValue); - - // IArchiveUpdateCallback - // STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator); - STDMETHOD(GetUpdateItemInfo)(UINT32 index, - INT32 *newData, // 1 - new data, 0 - old data - INT32 *newProperties, // 1 - new properties, 0 - old properties - UINT32 *indexInArchive// set if existInArchive == true - ); - - STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value); - - STDMETHOD(GetStream)(UINT32 index, IInStream **anInStream); - STDMETHOD(SetOperationResult)(INT32 operationResult); - STDMETHOD(CryptoGetTextPassword2)(INT32 *passwordIsDefined, BSTR *password); - -private: - UString m_BaseFolderPrefix; - const CObjectVector<CDirItem> *m_DirItems; - const CObjectVector<CArchiveItem> *m_ArchiveItems; - const CObjectVector<CUpdatePair2> *m_UpdatePairs; - CMyComPtr<IFolderArchiveUpdateCallback> m_UpdateCallback; - CMyComPtr<ICryptoGetTextPassword2> _cryptoGetTextPassword; - UINT m_CodePage; - - CMyComPtr<IInArchive> _inArchive; - -public: - void Init(const UString &baseFolderPrefix, - const CObjectVector<CDirItem> *dirItems, - const CObjectVector<CArchiveItem> *archiveItems, // test CItemInfoExList - CObjectVector<CUpdatePair2> *updatePairs, - // UINT codePage, - IInArchive *inArchive, - IFolderArchiveUpdateCallback *updateCallback); -}; - - - - -#endif diff --git a/7zip/UI/Agent/IFolderArchive.h b/7zip/UI/Agent/IFolderArchive.h index 3f101e85..41d9eb22 100755 --- a/7zip/UI/Agent/IFolderArchive.h +++ b/7zip/UI/Agent/IFolderArchive.h @@ -1,65 +1,13 @@ // IFolderArchive.h -#pragma once - -#ifndef __IFOLDERARCHIVE_H -#define __IFOLDERARCHIVE_H +#ifndef __IFOLDER_ARCHIVE_H +#define __IFOLDER_ARCHIVE_H #include "../../Archive/IArchive.h" // #include "../Format/Common/ArchiveInterface.h" #include "../../FileManager/IFolder.h" - -namespace NExtractionMode { - namespace NPath - { - enum EEnum - { - kFullPathnames, - kCurrentPathnames, - kNoPathnames - }; - } - namespace NOverwrite - { - enum EEnum - { - kAskBefore, - kWithoutPrompt, - kSkipExisting, - kAutoRename - }; - } -} - -namespace NOverwriteAnswer -{ - enum EEnum - { - kYes, - kYesToAll, - kNo, - kNoToAll, - kAutoRename, - kCancel, - }; -} - - -// {23170F69-40C1-278A-0000-000100070000} -DEFINE_GUID(IID_IFolderArchiveExtractCallback, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000100070000") -IFolderArchiveExtractCallback: public IProgress -{ -public: - STDMETHOD(AskOverwrite)( - const wchar_t *existName, const FILETIME *existTime, const UINT64 *existSize, - const wchar_t *newName, const FILETIME *newTime, const UINT64 *newSize, - INT32 *answer); - STDMETHOD(PrepareOperation)(const wchar_t *name, INT32 askExtractMode) PURE; - STDMETHOD(MessageError)(const wchar_t *message) PURE; - STDMETHOD(SetOperationResult)(INT32 operationResult) PURE; -}; +#include "../Common/IFileExtractCallback.h" +#include "../Common/ExtractMode.h" // {23170F69-40C1-278A-0000-000100050000} DEFINE_GUID(IID_IArchiveFolder, @@ -69,8 +17,8 @@ IArchiveFolder: public IUnknown { public: STDMETHOD(Extract)(const UINT32 *indices, UINT32 numItems, - NExtractionMode::NPath::EEnum pathMode, - NExtractionMode::NOverwrite::EEnum overwriteMode, + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, const wchar_t *path, INT32 testMode, IFolderArchiveExtractCallback *extractCallback2) PURE; @@ -100,8 +48,8 @@ public: BSTR *name, PROPID *propID, VARTYPE *varType) PURE; STDMETHOD(BindToRootFolder)(IFolderFolder **resultFolder) PURE; STDMETHOD(Extract)( - NExtractionMode::NPath::EEnum pathMode, - NExtractionMode::NOverwrite::EEnum overwriteMode, + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, const wchar_t *path, INT32 testMode, IFolderArchiveExtractCallback *extractCallback2) PURE; @@ -117,6 +65,7 @@ public: STDMETHOD(CompressOperation)(const wchar_t *name) PURE; STDMETHOD(DeleteOperation)(const wchar_t *name) PURE; STDMETHOD(OperationResult)(INT32 operationResult) PURE; + STDMETHOD(UpdateErrorMessage)(const wchar_t *message) PURE; }; // {23170F69-40C1-278A-0000-0001000A0000} @@ -133,7 +82,7 @@ IOutFolderArchive: public IUnknown const wchar_t *filePath, const CLSID *clsID, const wchar_t *newArchiveName, - const BYTE *stateActions, + const Byte *stateActions, const wchar_t *sfxModule, IFolderArchiveUpdateCallback *updateCallback) PURE; }; diff --git a/7zip/UI/Agent/UpdateCallbackAgent.cpp b/7zip/UI/Agent/UpdateCallbackAgent.cpp new file mode 100755 index 00000000..b12280d5 --- /dev/null +++ b/7zip/UI/Agent/UpdateCallbackAgent.cpp @@ -0,0 +1,80 @@ +// UpdateCallbackAgent.h + +#include "StdAfx.h" + +#include "Windows/Error.h" + +#include "UpdateCallbackAgent.h" + +using namespace NWindows; + +HRESULT CUpdateCallbackAgent::SetTotal(UINT64 size) +{ + if (Callback) + return Callback->SetTotal(size); + return S_OK; +} + +HRESULT CUpdateCallbackAgent::SetCompleted(const UINT64 *completeValue) +{ + if (Callback) + return Callback->SetCompleted(completeValue); + return S_OK; +} + +HRESULT CUpdateCallbackAgent::CheckBreak() +{ + return S_OK; +} + +HRESULT CUpdateCallbackAgent::Finilize() +{ + return S_OK; +} + +HRESULT CUpdateCallbackAgent::OpenFileError(const wchar_t *name, DWORD systemError) +{ + // if (systemError == ERROR_SHARING_VIOLATION) + { + if (Callback) + { + RINOK(Callback->UpdateErrorMessage( + UString(L"WARNING: ") + + NError::MyFormatMessageW(systemError) + + UString(L": ") + + UString(name))); + return S_FALSE; + } + } + // FailedFiles.Add(name); + return systemError; +} + +HRESULT CUpdateCallbackAgent::GetStream(const wchar_t *name, bool isAnti) +{ + if (Callback) + return Callback->CompressOperation(name); + return S_OK; +} + +HRESULT CUpdateCallbackAgent::SetOperationResult(INT32 operationResult) +{ + if (Callback) + return Callback->OperationResult(operationResult); + return S_OK; +} + +HRESULT CUpdateCallbackAgent::CryptoGetTextPassword2(INT32 *passwordIsDefined, BSTR *password) +{ + *passwordIsDefined = BoolToInt(false); + if (!_cryptoGetTextPassword) + { + if (!Callback) + return S_OK; + HRESULT result = Callback.QueryInterface( + IID_ICryptoGetTextPassword2, &_cryptoGetTextPassword); + if (result != S_OK) + return S_OK; + } + return _cryptoGetTextPassword->CryptoGetTextPassword2(passwordIsDefined, password); +} diff --git a/7zip/UI/Agent/UpdateCallbackAgent.h b/7zip/UI/Agent/UpdateCallbackAgent.h new file mode 100755 index 00000000..1cff501a --- /dev/null +++ b/7zip/UI/Agent/UpdateCallbackAgent.h @@ -0,0 +1,24 @@ +// UpdateCallbackAgent.h + +#ifndef __UPDATECALLBACKAGENT_H +#define __UPDATECALLBACKAGENT_H + +#include "../Common/UpdateCallback.h" +#include "IFolderArchive.h" + +class CUpdateCallbackAgent: public IUpdateCallbackUI +{ + virtual HRESULT SetTotal(UINT64 size); + virtual HRESULT SetCompleted(const UINT64 *completeValue); + virtual HRESULT CheckBreak(); + virtual HRESULT Finilize(); + virtual HRESULT GetStream(const wchar_t *name, bool isAnti); + virtual HRESULT OpenFileError(const wchar_t *name, DWORD systemError); + virtual HRESULT SetOperationResult(INT32 operationResult); + virtual HRESULT CryptoGetTextPassword2(INT32 *passwordIsDefined, BSTR *password); + CMyComPtr<ICryptoGetTextPassword2> _cryptoGetTextPassword; +public: + CMyComPtr<IFolderArchiveUpdateCallback> Callback; +}; + +#endif diff --git a/7zip/UI/Client7z/Client7z.cpp b/7zip/UI/Client7z/Client7z.cpp index 32211dca..970e85a9 100755 --- a/7zip/UI/Client7z/Client7z.cpp +++ b/7zip/UI/Client7z/Client7z.cpp @@ -1,6 +1,6 @@ -// Client7z.cpp : Defines the entry point for the console application. +// Client7z.cpp -#include "stdafx.h" +#include "StdAfx.h" #include <initguid.h> @@ -59,9 +59,9 @@ int main(int argc, char* argv[]) } if (archive->Open(file, 0, 0) != S_OK) return 0; - UINT32 numItems = 0; + UInt32 numItems = 0; archive->GetNumberOfItems(&numItems); - for (UINT32 i = 0; i < numItems; i++) + for (UInt32 i = 0; i < numItems; i++) { NWindows::NCOM::CPropVariant propVariant; archive->GetProperty(i, kpidPath, &propVariant); diff --git a/7zip/UI/Client7z/Client7z.dsp b/7zip/UI/Client7z/Client7z.dsp index 612a2078..fb957bf8 100755 --- a/7zip/UI/Client7z/Client7z.dsp +++ b/7zip/UI/Client7z/Client7z.dsp @@ -81,35 +81,19 @@ LINK32=link.exe # Name "Client7z - Win32 Release" # Name "Client7z - Win32 Debug" -# Begin Group "Source Files" +# Begin Group "Spec" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File -SOURCE=.\Client7z.cpp -# End Source File -# Begin Source File - SOURCE=.\StdAfx.cpp # ADD CPP /Yc"stdafx.h" # End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE=.\StdAfx.h # End Source File # End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# Begin Group "SDK" - -# PROP Default_Filter "" -# End Group # Begin Group "Windows" # PROP Default_Filter "" @@ -186,5 +170,9 @@ SOURCE=..\..\Common\FileStreams.cpp SOURCE=..\..\Common\FileStreams.h # End Source File # End Group +# Begin Source File + +SOURCE=.\Client7z.cpp +# End Source File # End Target # End Project diff --git a/7zip/UI/Client7z/StdAfx.cpp b/7zip/UI/Client7z/StdAfx.cpp index 710de2fb..d0feea85 100755 --- a/7zip/UI/Client7z/StdAfx.cpp +++ b/7zip/UI/Client7z/StdAfx.cpp @@ -1,8 +1,3 @@ -// stdafx.cpp : source file that includes just the standard includes -// Client7z.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information +// StdAfx.cpp -#include "stdafx.h" - -// TODO: reference any additional headers you need in STDAFX.H -// and not in this file +#include "StdAfx.h" diff --git a/7zip/UI/Client7z/StdAfx.h b/7zip/UI/Client7z/StdAfx.h index 40ea3552..b23436e9 100755 --- a/7zip/UI/Client7z/StdAfx.h +++ b/7zip/UI/Client7z/StdAfx.h @@ -1,6 +1,4 @@ -// stdafx.h - -#pragma once +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H @@ -9,4 +7,3 @@ #include <stdio.h> #endif - diff --git a/7zip/UI/Common/ArchiveCommandLine.cpp b/7zip/UI/Common/ArchiveCommandLine.cpp new file mode 100755 index 00000000..e11cfd34 --- /dev/null +++ b/7zip/UI/Common/ArchiveCommandLine.cpp @@ -0,0 +1,830 @@ +// ArchiveCommandLine.cpp + +#include "StdAfx.h" + +#include <io.h> +#include <stdio.h> + +#include "Common/ListFileUtils.h" +#include "Common/StringConvert.h" +#include "Common/StringToInt.h" + +#include "Windows/FileName.h" +#include "Windows/FileDir.h" +#ifdef _WIN32 +#include "Windows/FileMapping.h" +#include "Windows/Synchronization.h" +#endif + +#include "ArchiveCommandLine.h" +#include "UpdateAction.h" +#include "Update.h" +#include "ArchiverInfo.h" +#include "SortUtils.h" +#include "EnumDirItems.h" + +using namespace NCommandLineParser; +using namespace NWindows; +using namespace NFile; + +static const int kNumSwitches = 24; + +namespace NKey { +enum Enum +{ + kHelp1 = 0, + kHelp2, + kDisableHeaders, + kDisablePercents, + kArchiveType, + kYes, + kPassword, + kProperty, + kOutputDir, + kWorkingDir, + kInclude, + kExclude, + kArInclude, + kArExclude, + kNoArName, + kUpdate, + kVolume, + kRecursed, + kSfx, + kStdIn, + kStdOut, + kOverwrite, + kEmail, + kShowDialog +}; + +} + + +static const wchar_t kRecursedIDChar = 'R'; +static const wchar_t *kRecursedPostCharSet = L"0-"; + +static const wchar_t *kDefaultArchiveType = L"7z"; +static const wchar_t *kSFXExtension = L"exe"; + +namespace NRecursedPostCharIndex { + enum EEnum + { + kWildCardRecursionOnly = 0, + kNoRecursion = 1 + }; +} + +static const char kImmediateNameID = '!'; +static const char kMapNameID = '#'; +static const char kFileListID = '@'; + +static const char kSomeCludePostStringMinSize = 2; // at least <@|!><N>ame must be +static const char kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!><N>ame must be + +static const wchar_t *kOverwritePostCharSet = L"asut"; + +NExtract::NOverwriteMode::EEnum k_OverwriteModes[] = +{ + NExtract::NOverwriteMode::kWithoutPrompt, + NExtract::NOverwriteMode::kSkipExisting, + NExtract::NOverwriteMode::kAutoRename, + NExtract::NOverwriteMode::kAutoRenameExisting +}; + +static const CSwitchForm kSwitchForms[kNumSwitches] = + { + { L"?", NSwitchType::kSimple, false }, + { L"H", NSwitchType::kSimple, false }, + { L"BA", NSwitchType::kSimple, false }, + { L"BD", NSwitchType::kSimple, false }, + { L"T", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"Y", NSwitchType::kSimple, false }, + { L"P", NSwitchType::kUnLimitedPostString, false, 0 }, + { L"M", NSwitchType::kUnLimitedPostString, true, 1 }, + { L"O", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"W", NSwitchType::kUnLimitedPostString, false, 0 }, + { L"I", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize}, + { L"X", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize}, + { L"AI", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize}, + { L"AX", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize}, + { L"AN", NSwitchType::kSimple, false }, + { L"U", NSwitchType::kUnLimitedPostString, true, 1}, + { L"V", NSwitchType::kUnLimitedPostString, true, 1}, + { L"R", NSwitchType::kPostChar, false, 0, 0, kRecursedPostCharSet }, + { L"SFX", NSwitchType::kUnLimitedPostString, false, 0 }, + { L"SI", NSwitchType::kUnLimitedPostString, false, 0 }, + { L"SO", NSwitchType::kSimple, false, 0 }, + { L"AO", NSwitchType::kPostChar, false, 1, 1, kOverwritePostCharSet}, + { L"SEML", NSwitchType::kUnLimitedPostString, false, 0}, + { L"AD", NSwitchType::kSimple, false } + }; + +static const int kNumCommandForms = 7; + +static const CCommandForm g_CommandForms[kNumCommandForms] = +{ + { L"A", false }, + { L"U", false }, + { L"D", false }, + { L"T", false }, + { L"E", false }, + { L"X", false }, + { L"L", false } +}; + +static const int kMaxCmdLineSize = 1000; +static const wchar_t *kUniversalWildcard = L"*"; +static const int kMinNonSwitchWords = 1; +static const int kCommandIndex = 0; + +// --------------------------- +// exception messages + +static const char *kUserErrorMessage = "Incorrect command line"; +static const char *kIncorrectListFile = "Incorrect wildcard in listfile"; +static const char *kIncorrectWildCardInListFile = "Incorrect wildcard in listfile"; +static const char *kIncorrectWildCardInCommandLine = "Incorrect wildcard in command line"; +static const char *kTerminalOutError = "I won't write compressed data to a terminal"; + +// --------------------------- + +bool CArchiveCommand::IsFromExtractGroup() const +{ + switch(CommandType) + { + case NCommandType::kTest: + case NCommandType::kExtract: + case NCommandType::kFullExtract: + return true; + default: + return false; + } +} + +NExtract::NPathMode::EEnum CArchiveCommand::GetPathMode() const +{ + switch(CommandType) + { + case NCommandType::kTest: + case NCommandType::kFullExtract: + return NExtract::NPathMode::kFullPathnames; + default: + return NExtract::NPathMode::kNoPathnames; + } +} + +bool CArchiveCommand::IsFromUpdateGroup() const +{ + return (CommandType == NCommandType::kAdd || + CommandType == NCommandType::kUpdate || + CommandType == NCommandType::kDelete); +} + +static NRecursedType::EEnum GetRecursedTypeFromIndex(int index) +{ + switch (index) + { + case NRecursedPostCharIndex::kWildCardRecursionOnly: + return NRecursedType::kWildCardOnlyRecursed; + case NRecursedPostCharIndex::kNoRecursion: + return NRecursedType::kNonRecursed; + default: + return NRecursedType::kRecursed; + } +} + +static bool ParseArchiveCommand(const UString &commandString, CArchiveCommand &command) +{ + UString commandStringUpper = commandString; + commandStringUpper.MakeUpper(); + UString postString; + int commandIndex = ParseCommand(kNumCommandForms, g_CommandForms, commandStringUpper, + postString) ; + if (commandIndex < 0) + return false; + command.CommandType = (NCommandType::EEnum)commandIndex; + return true; +} + +// ------------------------------------------------------------------ +// filenames functions + +static bool AddNameToCensor(NWildcard::CCensor &wildcardCensor, + const UString &name, bool include, NRecursedType::EEnum type) +{ + bool isWildCard = DoesNameContainWildCard(name); + bool recursed; + + switch (type) + { + case NRecursedType::kWildCardOnlyRecursed: + recursed = isWildCard; + break; + case NRecursedType::kRecursed: + recursed = true; + break; + case NRecursedType::kNonRecursed: + recursed = false; + break; + } + wildcardCensor.AddItem(name, include, recursed); + return true; +} + +static inline UINT GetCurrentCodePage() + { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; } + +static void AddToCensorFromListFile(NWildcard::CCensor &wildcardCensor, + LPCWSTR fileName, bool include, NRecursedType::EEnum type) +{ + UStringVector names; + if (!ReadNamesFromListFile(GetSystemString(fileName, + GetCurrentCodePage()), names)) + throw kIncorrectListFile; + for (int i = 0; i < names.Size(); i++) + if (!AddNameToCensor(wildcardCensor, names[i], include, type)) + throw kIncorrectWildCardInListFile; +} + +static void AddCommandLineWildCardToCensr(NWildcard::CCensor &wildcardCensor, + const UString &name, bool include, NRecursedType::EEnum recursedType) +{ + if (!AddNameToCensor(wildcardCensor, name, include, recursedType)) + throw kIncorrectWildCardInCommandLine; +} + +static void AddToCensorFromNonSwitchesStrings( + int startIndex, + NWildcard::CCensor &wildcardCensor, + const UStringVector &nonSwitchStrings, NRecursedType::EEnum type, + bool thereAreSwitchIncludes) +{ + if(nonSwitchStrings.Size() == startIndex && (!thereAreSwitchIncludes)) + AddCommandLineWildCardToCensr(wildcardCensor, kUniversalWildcard, true, type); + for(int i = startIndex; i < nonSwitchStrings.Size(); i++) + { + const UString &s = nonSwitchStrings[i]; + if (s[0] == kFileListID) + AddToCensorFromListFile(wildcardCensor, s.Mid(1), true, type); + else + AddCommandLineWildCardToCensr(wildcardCensor, s, true, type); + } +} + +#ifdef _WIN32 +static void ParseMapWithPaths(NWildcard::CCensor &wildcardCensor, + const UString &switchParam, bool include, + NRecursedType::EEnum commonRecursedType) +{ + int splitPos = switchParam.Find(L':'); + if (splitPos < 0) + throw kUserErrorMessage; + UString mappingName = switchParam.Left(splitPos); + + UString switchParam2 = switchParam.Mid(splitPos + 1); + splitPos = switchParam2.Find(L':'); + if (splitPos < 0) + throw kUserErrorMessage; + + UString mappingSize = switchParam2.Left(splitPos); + UString eventName = switchParam2.Mid(splitPos + 1); + + UInt64 dataSize64 = ConvertStringToUInt64(mappingSize, NULL); + UInt32 dataSize = (UInt32)dataSize64; + { + CFileMapping fileMapping; + if (!fileMapping.Open(FILE_MAP_READ, false, GetSystemString(mappingName))) + throw L"Can not open mapping"; + LPVOID data = fileMapping.MapViewOfFile(FILE_MAP_READ, 0, dataSize); + if (data == NULL) + throw L"MapViewOfFile error"; + try + { + const wchar_t *curData = (const wchar_t *)data; + if (*curData != 0) + throw L"Incorrect mapping data"; + UInt32 numChars = dataSize / sizeof(wchar_t); + UString name; + for (UInt32 i = 1; i < numChars; i++) + { + wchar_t c = curData[i]; + if (c == L'\0') + { + AddCommandLineWildCardToCensr(wildcardCensor, + name, include, commonRecursedType); + name.Empty(); + } + else + name += c; + } + if (!name.IsEmpty()) + throw L"data error"; + } + catch(...) + { + UnmapViewOfFile(data); + throw; + } + UnmapViewOfFile(data); + } + + { + NSynchronization::CEvent event; + event.Open(EVENT_MODIFY_STATE, false, GetSystemString(eventName)); + event.Set(); + } +} +#endif + +static void AddSwitchWildCardsToCensor(NWildcard::CCensor &wildcardCensor, + const UStringVector &strings, bool include, + NRecursedType::EEnum commonRecursedType) +{ + for(int i = 0; i < strings.Size(); i++) + { + const UString &name = strings[i]; + NRecursedType::EEnum recursedType; + int pos = 0; + if (name.Length() < kSomeCludePostStringMinSize) + throw kUserErrorMessage; + if (::MyCharUpper(name[pos]) == kRecursedIDChar) + { + pos++; + int index = UString(kRecursedPostCharSet).Find(name[pos]); + recursedType = GetRecursedTypeFromIndex(index); + if (index >= 0) + pos++; + } + else + recursedType = commonRecursedType; + if (name.Length() < pos + kSomeCludeAfterRecursedPostStringMinSize) + throw kUserErrorMessage; + UString tail = name.Mid(pos + 1); + if (name[pos] == kImmediateNameID) + AddCommandLineWildCardToCensr(wildcardCensor, tail, include, recursedType); + else if (name[pos] == kFileListID) + AddToCensorFromListFile(wildcardCensor, tail, include, recursedType); + #ifdef _WIN32 + else if (name[pos] == kMapNameID) + ParseMapWithPaths(wildcardCensor, tail, include, recursedType); + #endif + else + throw kUserErrorMessage; + } +} + +static NUpdateArchive::NPairAction::EEnum GetUpdatePairActionType(int i) +{ + switch(i) + { + case NUpdateArchive::NPairAction::kIgnore: return NUpdateArchive::NPairAction::kIgnore; + case NUpdateArchive::NPairAction::kCopy: return NUpdateArchive::NPairAction::kCopy; + case NUpdateArchive::NPairAction::kCompress: return NUpdateArchive::NPairAction::kCompress; + case NUpdateArchive::NPairAction::kCompressAsAnti: return NUpdateArchive::NPairAction::kCompressAsAnti; + } + throw 98111603; +} + +const UString kUpdatePairStateIDSet = L"PQRXYZW"; +const int kUpdatePairStateNotSupportedActions[] = {2, 2, 1, -1, -1, -1, -1}; + +const UString kUpdatePairActionIDSet = L"0123"; //Ignore, Copy, Compress, Create Anti + +const wchar_t *kUpdateIgnoreItselfPostStringID = L"-"; +const wchar_t kUpdateNewArchivePostCharID = '!'; + + +static bool ParseUpdateCommandString2(const UString &command, + NUpdateArchive::CActionSet &actionSet, UString &postString) +{ + for(int i = 0; i < command.Length();) + { + wchar_t c = MyCharUpper(command[i]); + int statePos = kUpdatePairStateIDSet.Find(c); + if (statePos < 0) + { + postString = command.Mid(i); + return true; + } + i++; + if (i >= command.Length()) + return false; + int actionPos = kUpdatePairActionIDSet.Find(::MyCharUpper(command[i])); + if (actionPos < 0) + return false; + actionSet.StateActions[statePos] = GetUpdatePairActionType(actionPos); + if (kUpdatePairStateNotSupportedActions[statePos] == actionPos) + return false; + i++; + } + postString.Empty(); + return true; +} + +static void ParseUpdateCommandString(CUpdateOptions &options, + const UStringVector &updatePostStrings, + const NUpdateArchive::CActionSet &defaultActionSet) +{ + for(int i = 0; i < updatePostStrings.Size(); i++) + { + const UString &updateString = updatePostStrings[i]; + if(updateString.CompareNoCase(kUpdateIgnoreItselfPostStringID) == 0) + { + if(options.UpdateArchiveItself) + { + options.UpdateArchiveItself = false; + options.Commands.Delete(0); + } + } + else + { + NUpdateArchive::CActionSet actionSet = defaultActionSet; + + UString postString; + if (!ParseUpdateCommandString2(updateString, actionSet, postString)) + throw kUserErrorMessage; + if(postString.IsEmpty()) + { + if(options.UpdateArchiveItself) + options.Commands[0].ActionSet = actionSet; + } + else + { + if(MyCharUpper(postString[0]) != kUpdateNewArchivePostCharID) + throw kUserErrorMessage; + CUpdateArchiveCommand uc; + UString archivePath = postString.Mid(1); + if (archivePath.IsEmpty()) + throw kUserErrorMessage; + uc.ArchivePath.BaseExtension = options.ArchivePath.BaseExtension; + uc.ArchivePath.VolExtension = options.ArchivePath.VolExtension; + uc.ArchivePath.ParseFromPath(archivePath); + uc.ActionSet = actionSet; + options.Commands.Add(uc); + } + } + } +} + +static const char kByteSymbol = 'B'; +static const char kKiloSymbol = 'K'; +static const char kMegaSymbol = 'M'; +static const char kGigaSymbol = 'G'; + +static bool ParseComplexSize(const UString &src, UInt64 &result) +{ + UString s = src; + s.MakeUpper(); + + const wchar_t *start = s; + const wchar_t *end; + UInt64 number = ConvertStringToUInt64(start, &end); + int numDigits = end - start; + if (numDigits == 0 || s.Length() > numDigits + 1) + return false; + if (s.Length() == numDigits) + { + result = number; + return true; + } + int numBits; + switch (s[numDigits]) + { + case kByteSymbol: + result = number; + return true; + case kKiloSymbol: + numBits = 10; + break; + case kMegaSymbol: + numBits = 20; + break; + case kGigaSymbol: + numBits = 30; + break; + default: + return false; + } + if (number >= ((UInt64)1 << (64 - numBits))) + return false; + result = number << numBits; + return true; +} + +static void SetAddCommandOptions( + NCommandType::EEnum commandType, + const CParser &parser, + CUpdateOptions &options) +{ + NUpdateArchive::CActionSet defaultActionSet; + switch(commandType) + { + case NCommandType::kAdd: + defaultActionSet = NUpdateArchive::kAddActionSet; + break; + case NCommandType::kDelete: + defaultActionSet = NUpdateArchive::kDeleteActionSet; + break; + default: + defaultActionSet = NUpdateArchive::kUpdateActionSet; + } + + options.UpdateArchiveItself = true; + + options.Commands.Clear(); + CUpdateArchiveCommand updateMainCommand; + updateMainCommand.ActionSet = defaultActionSet; + options.Commands.Add(updateMainCommand); + if(parser[NKey::kUpdate].ThereIs) + ParseUpdateCommandString(options, parser[NKey::kUpdate].PostStrings, + defaultActionSet); + if(parser[NKey::kWorkingDir].ThereIs) + { + const UString &postString = parser[NKey::kWorkingDir].PostStrings[0]; + if (postString.IsEmpty()) + NDirectory::MyGetTempPath(options.WorkingDir); + else + options.WorkingDir = postString; + } + if(options.SfxMode = parser[NKey::kSfx].ThereIs) + options.SfxModule = parser[NKey::kSfx].PostStrings[0]; + + if (parser[NKey::kVolume].ThereIs) + { + const UStringVector &sv = parser[NKey::kVolume].PostStrings; + for (int i = 0; i < sv.Size(); i++) + { + const UString &s = sv[i]; + UInt64 size; + if (!ParseComplexSize(sv[i], size)) + throw "incorrect volume size"; + options.VolumesSizes.Add(size); + } + } +} + +static void SetMethodOptions(const CParser &parser, + CUpdateOptions &options) +{ + if (parser[NKey::kProperty].ThereIs) + { + // options.MethodMode.Properties.Clear(); + for(int i = 0; i < parser[NKey::kProperty].PostStrings.Size(); i++) + { + CProperty property; + const UString &postString = parser[NKey::kProperty].PostStrings[i]; + int index = postString.Find(L'='); + if (index < 0) + property.Name = postString; + else + { + property.Name = postString.Left(index); + property.Value = postString.Mid(index + 1); + } + options.MethodMode.Properties.Add(property); + } + } +} + + +static void SetArchiveType(const UString &archiveType, +#ifndef EXCLUDE_COM + UString &filePath, CLSID &classID, +#else + UString &formatName, +#endif + UString &archiveExtension) +{ + CObjectVector<CArchiverInfo> archiverInfoVector; + ReadArchiverInfoList(archiverInfoVector); + if (archiverInfoVector.Size() == 0) + throw "There are no installed archive handlers"; + if (archiveType.IsEmpty()) + throw "Incorrect archive type was assigned"; + for (int i = 0; i < archiverInfoVector.Size(); i++) + { + const CArchiverInfo &archiverInfo = archiverInfoVector[i]; + if (archiverInfo.Name.CompareNoCase(archiveType) == 0) + { + #ifndef EXCLUDE_COM + classID = archiverInfo.ClassID; + filePath = archiverInfo.FilePath; + #else + formatName = archiverInfo.Name; + + #endif + + archiveExtension = archiverInfo.GetMainExtension(); + return; + } + } + throw "Incorrect archive type was assigned"; +} + + +CArchiveCommandLineParser::CArchiveCommandLineParser(): parser(kNumSwitches) {} + +void CArchiveCommandLineParser::Parse1(UStringVector commandStrings, + CArchiveCommandLineOptions &options) +{ + try + { + parser.ParseStrings(kSwitchForms, commandStrings); + } + catch(...) + { + throw kUserErrorMessage; + } + + options.IsInTerminal = (isatty(fileno(stdin)) != 0); + options.IsStdOutTerminal = (isatty(fileno(stdout)) != 0); + options.IsStdErrTerminal = (isatty(fileno(stderr)) != 0); + options.StdOutMode = parser[NKey::kStdOut].ThereIs; + options.EnableHeaders = !parser[NKey::kDisableHeaders].ThereIs; + options.HelpMode = parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs; +} + +void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options) +{ + const UStringVector &nonSwitchStrings = parser.NonSwitchStrings; + int numNonSwitchStrings = nonSwitchStrings.Size(); + if(numNonSwitchStrings < kMinNonSwitchWords) + throw kUserErrorMessage; + + if (!ParseArchiveCommand(nonSwitchStrings[kCommandIndex], options.Command)) + throw kUserErrorMessage; + + NRecursedType::EEnum recursedType; + if (parser[NKey::kRecursed].ThereIs) + recursedType = GetRecursedTypeFromIndex(parser[NKey::kRecursed].PostCharIndex); + else + recursedType = NRecursedType::kNonRecursed; + + bool thereAreSwitchIncludes = false; + if (parser[NKey::kInclude].ThereIs) + { + thereAreSwitchIncludes = true; + AddSwitchWildCardsToCensor(options.WildcardCensor, + parser[NKey::kInclude].PostStrings, true, recursedType); + } + if (parser[NKey::kExclude].ThereIs) + AddSwitchWildCardsToCensor(options.WildcardCensor, + parser[NKey::kExclude].PostStrings, false, recursedType); + + int curCommandIndex = kCommandIndex + 1; + bool thereIsArchiveName = !parser[NKey::kNoArName].ThereIs; + if (thereIsArchiveName) + { + if(curCommandIndex >= numNonSwitchStrings) + throw kUserErrorMessage; + options.ArchiveName = nonSwitchStrings[curCommandIndex++]; + } + + AddToCensorFromNonSwitchesStrings( + curCommandIndex, options.WildcardCensor, + nonSwitchStrings, recursedType, thereAreSwitchIncludes); + + options.YesToAll = parser[NKey::kYes].ThereIs; + + bool isExtractGroupCommand = options.Command.IsFromExtractGroup(); + + options.PasswordEnabled = parser[NKey::kPassword].ThereIs; + + if(options.PasswordEnabled) + options.Password = parser[NKey::kPassword].PostStrings[0]; + + options.StdInMode = parser[NKey::kStdIn].ThereIs; + options.ShowDialog = parser[NKey::kShowDialog].ThereIs; + + if(isExtractGroupCommand || options.Command.CommandType == NCommandType::kList) + { + if (options.StdInMode) + throw "reading archives from stdin is not implemented"; + if (!options.WildcardCensor.AllAreRelative()) + throw "cannot use absolute pathnames for this command"; + + NWildcard::CCensor archiveWildcardCensor; + + if (parser[NKey::kArInclude].ThereIs) + { + AddSwitchWildCardsToCensor(archiveWildcardCensor, + parser[NKey::kArInclude].PostStrings, true, NRecursedType::kNonRecursed); + } + if (parser[NKey::kArExclude].ThereIs) + AddSwitchWildCardsToCensor(archiveWildcardCensor, + parser[NKey::kArExclude].PostStrings, false, NRecursedType::kNonRecursed); + + if (thereIsArchiveName) + AddCommandLineWildCardToCensr(archiveWildcardCensor, options.ArchiveName, true, NRecursedType::kNonRecursed); + + CObjectVector<CDirItem> dirItems; + EnumerateItems(archiveWildcardCensor, dirItems, NULL); + UStringVector archivePaths; + int i; + for (i = 0; i < dirItems.Size(); i++) + archivePaths.Add(dirItems[i].FullPath); + + if (archivePaths.Size() == 0) + throw "there is no such archive"; + + UStringVector archivePathsFull; + + for (i = 0; i < archivePaths.Size(); i++) + { + UString fullPath; + NFile::NDirectory::MyGetFullPathName(archivePaths[i], fullPath); + archivePathsFull.Add(fullPath); + } + CIntVector indices; + SortStringsToIndices(archivePathsFull, indices); + options.ArchivePathsSorted.Reserve(indices.Size()); + options.ArchivePathsFullSorted.Reserve(indices.Size()); + for (i = 0; i < indices.Size(); i++) + { + options.ArchivePathsSorted.Add(archivePaths[indices[i]]); + options.ArchivePathsFullSorted.Add(archivePathsFull[indices[i]]); + } + + if(isExtractGroupCommand) + { + if (options.StdOutMode && options.IsStdOutTerminal) + throw kTerminalOutError; + if(parser[NKey::kOutputDir].ThereIs) + { + options.OutputDir = parser[NKey::kOutputDir].PostStrings[0]; + NFile::NName::NormalizeDirPathPrefix(options.OutputDir); + } + + options.OverwriteMode = NExtract::NOverwriteMode::kAskBefore; + if(parser[NKey::kOverwrite].ThereIs) + options.OverwriteMode = + k_OverwriteModes[parser[NKey::kOverwrite].PostCharIndex]; + else if (options.YesToAll) + options.OverwriteMode = NExtract::NOverwriteMode::kWithoutPrompt; + } + } + else if(options.Command.IsFromUpdateGroup()) + { + CUpdateOptions &updateOptions = options.UpdateOptions; + + UString archiveType; + if(parser[NKey::kArchiveType].ThereIs) + archiveType = parser[NKey::kArchiveType].PostStrings[0]; + else + archiveType = kDefaultArchiveType; + + UString typeExtension; + if (!archiveType.IsEmpty()) + { + #ifndef EXCLUDE_COM + SetArchiveType(archiveType, updateOptions.MethodMode.FilePath, + updateOptions.MethodMode.ClassID, typeExtension); + #else + SetArchiveType(archiveType, updateOptions.MethodMode.Name, typeExtension); + #endif + } + UString extension = typeExtension; + if(parser[NKey::kSfx].ThereIs) + extension = kSFXExtension; + updateOptions.ArchivePath.BaseExtension = extension; + updateOptions.ArchivePath.VolExtension = typeExtension; + updateOptions.ArchivePath.ParseFromPath(options.ArchiveName); + SetAddCommandOptions(options.Command.CommandType, parser, + updateOptions); + + SetMethodOptions(parser, updateOptions); + + options.EnablePercents = !parser[NKey::kDisablePercents].ThereIs; + + if (options.EnablePercents) + { + if ((options.StdOutMode && !options.IsStdErrTerminal) || + (!options.StdOutMode && !options.IsStdOutTerminal)) + options.EnablePercents = false; + } + + if (updateOptions.EMailMode = parser[NKey::kEmail].ThereIs) + { + updateOptions.EMailAddress = parser[NKey::kEmail].PostStrings.Front(); + if (updateOptions.EMailAddress.Length() > 0) + if (updateOptions.EMailAddress[0] == L'.') + { + updateOptions.EMailRemoveAfter = true; + updateOptions.EMailAddress.Delete(0); + } + } + + updateOptions.StdOutMode = options.StdOutMode; + updateOptions.StdInMode = options.StdInMode; + + if (updateOptions.StdOutMode && updateOptions.EMailMode) + throw "stdout mode and email mode cannot be combined"; + if (updateOptions.StdOutMode && options.IsStdOutTerminal) + throw kTerminalOutError; + if(updateOptions.StdInMode) + updateOptions.StdInFileName = parser[NKey::kStdIn].PostStrings.Front(); + } + else + throw kUserErrorMessage; +} diff --git a/7zip/UI/Common/ArchiveCommandLine.h b/7zip/UI/Common/ArchiveCommandLine.h new file mode 100755 index 00000000..d4cacb17 --- /dev/null +++ b/7zip/UI/Common/ArchiveCommandLine.h @@ -0,0 +1,84 @@ +// ArchiveCommandLine.h + +#ifndef __ARCHIVECOMMANDLINE_H +#define __ARCHIVECOMMANDLINE_H + +#include "Common/Wildcard.h" +#include "Common/CommandLineParser.h" + +#include "Extract.h" +#include "Update.h" + +namespace NCommandType { enum EEnum +{ + kAdd = 0, + kUpdate, + kDelete, + kTest, + kExtract, + kFullExtract, + kList +};} + +namespace NRecursedType { enum EEnum +{ + kRecursed, + kWildCardOnlyRecursed, + kNonRecursed, +};} + +struct CArchiveCommand +{ + NCommandType::EEnum CommandType; + bool IsFromExtractGroup() const; + bool IsFromUpdateGroup() const; + bool IsTestMode() const { return CommandType == NCommandType::kTest; } + NExtract::NPathMode::EEnum GetPathMode() const; +}; + +struct CArchiveCommandLineOptions +{ + bool HelpMode; + + bool IsInTerminal; + bool IsStdOutTerminal; + bool IsStdErrTerminal; + bool StdInMode; + bool StdOutMode; + bool EnableHeaders; + + bool YesToAll; + bool ShowDialog; + // NWildcard::CCensor ArchiveWildcardCensor; + NWildcard::CCensor WildcardCensor; + + CArchiveCommand Command; + UString ArchiveName; + + bool PasswordEnabled; + UString Password; + + // Extract + bool AppendName; + UString OutputDir; + NExtract::NOverwriteMode::EEnum OverwriteMode; + UStringVector ArchivePathsSorted; + UStringVector ArchivePathsFullSorted; + + CUpdateOptions UpdateOptions; + bool EnablePercents; + + CArchiveCommandLineOptions(): StdInMode(false), StdOutMode(false) {}; + +}; + +class CArchiveCommandLineParser +{ + NCommandLineParser::CParser parser; +public: + CArchiveCommandLineParser(); + void Parse1(const UStringVector commandStrings, CArchiveCommandLineOptions &options); + void Parse2(CArchiveCommandLineOptions &options); +}; + +#endif diff --git a/7zip/UI/Agent/ArchiveExtractCallback.cpp b/7zip/UI/Common/ArchiveExtractCallback.cpp index 90b390c2..6e4be552 100755 --- a/7zip/UI/Agent/ArchiveExtractCallback.cpp +++ b/7zip/UI/Common/ArchiveExtractCallback.cpp @@ -1,4 +1,4 @@ -// ExtractCallback.cpp +// ArchiveExtractCallback.cpp #include "StdAfx.h" @@ -18,49 +18,47 @@ #include "../../Common/FilePathAutoRename.h" #include "../Common/ExtractingFilePath.h" +#include "OpenArchive.h" using namespace NWindows; +static const wchar_t *kCantAutoRename = L"ERROR: Can not create file with auto name"; +static const wchar_t *kCantRenameFile = L"ERROR: Can not rename existing file "; +static const wchar_t *kCantDeleteOutputFile = L"ERROR: Can not delete output file "; + + void CArchiveExtractCallback::Init( IInArchive *archiveHandler, IFolderArchiveExtractCallback *extractCallback2, + bool stdOutMode, const UString &directoryPath, - NExtractionMode::NPath::EEnum pathMode, - NExtractionMode::NOverwrite::EEnum overwriteMode, + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, const UStringVector &removePathParts, const UString &itemDefaultName, const FILETIME &utcLastWriteTimeDefault, - UINT32 attributesDefault) - // bool passwordIsDefined, const UString &password - // UString srcDirectoryPrefix) + UInt32 attributesDefault) { - _extractCallback2 = extractCallback2; - // m_PasswordIsDefined = passwordIsDefined; - // m_Password = password; + _stdOutMode = stdOutMode; _numErrors = 0; - + _extractCallback2 = extractCallback2; _itemDefaultName = itemDefaultName; _utcLastWriteTimeDefault = utcLastWriteTimeDefault; _attributesDefault = attributesDefault; - _removePathParts = removePathParts; - _pathMode = pathMode; _overwriteMode = overwriteMode; - _archiveHandler = archiveHandler; _directoryPath = directoryPath; NFile::NName::NormalizeDirPathPrefix(_directoryPath); - - // _srcDirectoryPrefix = srcDirectoryPrefix; } -STDMETHODIMP CArchiveExtractCallback::SetTotal(UINT64 size) +STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 size) { return _extractCallback2->SetTotal(size); } -STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UINT64 *completeValue) +STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UInt64 *completeValue) { return _extractCallback2->SetCompleted(completeValue); } @@ -89,8 +87,8 @@ static UString MakePathNameFromParts(const UStringVector &parts) } -STDMETHODIMP CArchiveExtractCallback::GetStream(UINT32 index, - ISequentialOutStream **outStream, INT32 askExtractMode) +STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, + ISequentialOutStream **outStream, Int32 askExtractMode) { *outStream = 0; _outFileStream.Release(); @@ -99,9 +97,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UINT32 index, UString fullPath; if(propVariant.vt == VT_EMPTY) - { fullPath = _itemDefaultName; - } else { if(propVariant.vt != VT_BSTR) @@ -111,9 +107,26 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UINT32 index, // UString fullPathCorrect = GetCorrectPath(fullPath); _filePath = fullPath; + _isSplit = false; + + RINOK(_archiveHandler->GetProperty(index, kpidPosition, &propVariant)); + if (propVariant.vt != VT_EMPTY) + { + if (propVariant.vt != VT_UI8) + return E_FAIL; + _position = propVariant.uhVal.QuadPart; + _isSplit = true; + } if(askExtractMode == NArchive::NExtract::NAskMode::kExtract) { + if (_stdOutMode) + { + CMyComPtr<ISequentialOutStream> outStreamLoc = new CStdOutFileStream; + *outStream = outStreamLoc.Detach(); + return S_OK; + } + RINOK(_archiveHandler->GetProperty(index, kpidAttributes, &propVariant)); if (propVariant.vt == VT_EMPTY) { @@ -128,8 +141,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UINT32 index, _processedFileInfo.AttributesAreDefined = true; } - RINOK(_archiveHandler->GetProperty(index, kpidIsFolder, &propVariant)); - _processedFileInfo.IsDirectory = VARIANT_BOOLToBool(propVariant.boolVal); + RINOK(IsArchiveItemFolder(_archiveHandler, index, _processedFileInfo.IsDirectory)); RINOK(_archiveHandler->GetProperty(index, kpidLastWriteTime, &propVariant)); switch(propVariant.vt) @@ -146,9 +158,9 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UINT32 index, RINOK(_archiveHandler->GetProperty(index, kpidSize, &propVariant)); bool newFileSizeDefined = (propVariant.vt != VT_EMPTY); - UINT64 newFileSize; + UInt64 newFileSize; if (newFileSizeDefined) - newFileSize = ConvertPropVariantToUINT64(propVariant); + newFileSize = ConvertPropVariantToUInt64(propVariant); bool isAnti = false; { @@ -160,8 +172,6 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UINT32 index, } UStringVector pathParts; - - // SplitPathToParts(fullPathCorrect, pathParts); SplitPathToParts(fullPath, pathParts); if(pathParts.IsEmpty()) @@ -169,14 +179,14 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UINT32 index, UString processedPath; switch(_pathMode) { - case NExtractionMode::NPath::kFullPathnames: + case NExtract::NPathMode::kFullPathnames: { - // processedPath = fullPathCorrect; - processedPath = GetCorrectPath(fullPath); + processedPath = fullPath; break; } - case NExtractionMode::NPath::kCurrentPathnames: + case NExtract::NPathMode::kCurrentPathnames: { + // for incorrect paths: "/dir1/dir2/file" int numRemovePathParts = _removePathParts.Size(); if(pathParts.Size() <= numRemovePathParts) return E_FAIL; @@ -185,28 +195,25 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UINT32 index, return E_FAIL; pathParts.Delete(0, numRemovePathParts); processedPath = MakePathNameFromParts(pathParts); - processedPath = GetCorrectPath(processedPath); break; } - case NExtractionMode::NPath::kNoPathnames: + case NExtract::NPathMode::kNoPathnames: { processedPath = pathParts.Back(); pathParts.Delete(0, pathParts.Size() - 1); // Test it!! break; } } + processedPath = GetCorrectPath(processedPath); if(!_processedFileInfo.IsDirectory) pathParts.DeleteBack(); - for(int i = 0; i < pathParts.Size(); i++) - pathParts[i] = GetCorrectFileName(pathParts[i]); + MakeCorrectPath(pathParts); if (!isAnti) if (!pathParts.IsEmpty()) CreateComplexDirectory(pathParts); - - const UString fullProcessedPathUnicode = _directoryPath + processedPath; UString fullProcessedPath = _directoryPath + processedPath; if(_processedFileInfo.IsDirectory) @@ -217,18 +224,20 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UINT32 index, return S_OK; } + if (!_isSplit) + { NFile::NFind::CFileInfoW fileInfo; if(NFile::NFind::FindFile(fullProcessedPath, fileInfo)) { switch(_overwriteMode) { - case NExtractionMode::NOverwrite::kSkipExisting: + case NExtract::NOverwriteMode::kSkipExisting: return S_OK; - case NExtractionMode::NOverwrite::kAskBefore: + case NExtract::NOverwriteMode::kAskBefore: { - INT32 overwiteResult; + Int32 overwiteResult; RINOK(_extractCallback2->AskOverwrite( - fullProcessedPathUnicode, &fileInfo.LastWriteTime, &fileInfo.Size, + fullProcessedPath, &fileInfo.LastWriteTime, &fileInfo.Size, fullPath, &_processedFileInfo.UTCLastWriteTime, newFileSizeDefined? &newFileSize : NULL, &overwiteResult)) @@ -239,27 +248,43 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UINT32 index, case NOverwriteAnswer::kNo: return S_OK; case NOverwriteAnswer::kNoToAll: - _overwriteMode = NExtractionMode::NOverwrite::kSkipExisting; + _overwriteMode = NExtract::NOverwriteMode::kSkipExisting; return S_OK; case NOverwriteAnswer::kYesToAll: - _overwriteMode = NExtractionMode::NOverwrite::kWithoutPrompt; + _overwriteMode = NExtract::NOverwriteMode::kWithoutPrompt; break; case NOverwriteAnswer::kYes: break; case NOverwriteAnswer::kAutoRename: - _overwriteMode = NExtractionMode::NOverwrite::kAutoRename; + _overwriteMode = NExtract::NOverwriteMode::kAutoRename; break; default: throw 20413; } } } - if (_overwriteMode == NExtractionMode::NOverwrite::kAutoRename) + if (_overwriteMode == NExtract::NOverwriteMode::kAutoRename) { if (!AutoRenamePath(fullProcessedPath)) { - UString message = UString(L"can not create name of file ") + - fullProcessedPathUnicode; + UString message = UString(kCantAutoRename) + + fullProcessedPath; + RINOK(_extractCallback2->MessageError(message)); + return E_ABORT; + } + } + else if (_overwriteMode == NExtract::NOverwriteMode::kAutoRenameExisting) + { + UString existPath = fullProcessedPath; + if (!AutoRenamePath(existPath)) + { + UString message = kCantAutoRename + fullProcessedPath; + RINOK(_extractCallback2->MessageError(message)); + return E_ABORT; + } + if(!NFile::NDirectory::MyMoveFile(fullProcessedPath, existPath)) + { + UString message = UString(kCantRenameFile) + fullProcessedPath; RINOK(_extractCallback2->MessageError(message)); return E_ABORT; } @@ -267,21 +292,30 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UINT32 index, else if (!NFile::NDirectory::DeleteFileAlways(fullProcessedPath)) { - UString message = UString(L"can not delete output file ") + - fullProcessedPathUnicode; + UString message = UString(kCantDeleteOutputFile) + + fullProcessedPath; RINOK(_extractCallback2->MessageError(message)); return E_ABORT; } } + } if (!isAnti) { _outFileStreamSpec = new COutFileStream; CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec); - if (!_outFileStreamSpec->Open(fullProcessedPath)) + if (!_outFileStreamSpec->File.Open(fullProcessedPath, + _isSplit ? OPEN_ALWAYS: CREATE_ALWAYS)) + { + // if (::GetLastError() != ERROR_FILE_EXISTS || !isSplit) + { + UString message = L"can not open output file " + fullProcessedPath; + RINOK(_extractCallback2->MessageError(message)); + return S_OK; + } + } + if (_isSplit) { - UString message = L"can not open output file " + fullProcessedPathUnicode; - RINOK(_extractCallback2->MessageError(message)); - return S_OK; + RINOK(_outFileStreamSpec->Seek(_position, STREAM_SEEK_SET, NULL)); } _outFileStream = outStreamLoc; *outStream = outStreamLoc.Detach(); @@ -295,7 +329,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UINT32 index, return S_OK; } -STDMETHODIMP CArchiveExtractCallback::PrepareOperation(INT32 askExtractMode) +STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode) { _extractMode = false; switch (askExtractMode) @@ -303,7 +337,7 @@ STDMETHODIMP CArchiveExtractCallback::PrepareOperation(INT32 askExtractMode) case NArchive::NExtract::NAskMode::kExtract: _extractMode = true; }; - return _extractCallback2->PrepareOperation(_filePath, askExtractMode); + return _extractCallback2->PrepareOperation(_filePath, askExtractMode, _isSplit ? &_position: 0); } void CArchiveExtractCallback::AddErrorMessage(LPCTSTR message) @@ -311,7 +345,7 @@ void CArchiveExtractCallback::AddErrorMessage(LPCTSTR message) _messages.Add(message); } -STDMETHODIMP CArchiveExtractCallback::SetOperationResult(INT32 operationResult) +STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult) { switch(operationResult) { diff --git a/7zip/UI/Agent/ArchiveExtractCallback.h b/7zip/UI/Common/ArchiveExtractCallback.h index bf0388ac..2a7423c9 100755 --- a/7zip/UI/Agent/ArchiveExtractCallback.h +++ b/7zip/UI/Common/ArchiveExtractCallback.h @@ -1,12 +1,10 @@ // ArchiveExtractCallback.h -#pragma once - #ifndef __ARCHIVEEXTRACTCALLBACK_H #define __ARCHIVEEXTRACTCALLBACK_H #include "../../Archive/IArchive.h" -#include "IFolderArchive.h" +#include "IFileExtractCallback.h" #include "Common/String.h" #include "Common/MyCom.h" @@ -14,6 +12,8 @@ #include "../../Common/FileStreams.h" #include "../../IPassword.h" +#include "ExtractMode.h" + class CArchiveExtractCallback: public IArchiveExtractCallback, // public IArchiveVolumeExtractCallback, @@ -25,14 +25,14 @@ public: // COM_INTERFACE_ENTRY(IArchiveVolumeExtractCallback) // IProgress - STDMETHOD(SetTotal)(UINT64 aize); - STDMETHOD(SetCompleted)(const UINT64 *completeValue); + STDMETHOD(SetTotal)(UInt64 aize); + STDMETHOD(SetCompleted)(const UInt64 *completeValue); // IExtractCallBack - STDMETHOD(GetStream)(UINT32 anIndex, ISequentialOutStream **outStream, - INT32 askExtractMode); - STDMETHOD(PrepareOperation)(INT32 askExtractMode); - STDMETHOD(SetOperationResult)(INT32 resultEOperationResult); + STDMETHOD(GetStream)(UInt32 anIndex, ISequentialOutStream **outStream, + Int32 askExtractMode); + STDMETHOD(PrepareOperation)(Int32 askExtractMode); + STDMETHOD(SetOperationResult)(Int32 resultEOperationResult); // IArchiveVolumeExtractCallback // STDMETHOD(GetInStream)(const wchar_t *name, ISequentialInStream **inStream); @@ -45,10 +45,12 @@ private: CMyComPtr<IFolderArchiveExtractCallback> _extractCallback2; CMyComPtr<ICryptoGetTextPassword> _cryptoGetTextPassword; UString _directoryPath; - NExtractionMode::NPath::EEnum _pathMode; - NExtractionMode::NOverwrite::EEnum _overwriteMode; + NExtract::NPathMode::EEnum _pathMode; + NExtract::NOverwriteMode::EEnum _overwriteMode; UString _filePath; + UInt64 _position; + bool _isSplit; UString _diskFilePath; @@ -60,48 +62,34 @@ private: FILETIME UTCLastWriteTime; bool IsDirectory; bool AttributesAreDefined; - UINT32 Attributes; + UInt32 Attributes; } _processedFileInfo; - COutFileStream *_outFileStreamSpec; CMyComPtr<ISequentialOutStream> _outFileStream; UStringVector _removePathParts; UString _itemDefaultName; FILETIME _utcLastWriteTimeDefault; - UINT32 _attributesDefault; - - // bool m_PasswordIsDefined; - // UString m_Password; - - - // UString _srcDirectoryPrefix; + UInt32 _attributesDefault; + bool _stdOutMode; void CreateComplexDirectory(const UStringVector &dirPathParts); - /* - void GetPropertyValue(LPITEMIDLIST anItemIDList, PROPID aPropId, - PROPVARIANT *aValue); - bool IsEncrypted(LPITEMIDLIST anItemIDList); - */ void AddErrorMessage(LPCTSTR message); public: - // CProgressDialog m_ProcessDialog; void Init( IInArchive *archiveHandler, IFolderArchiveExtractCallback *extractCallback2, + bool stdOutMode, const UString &directoryPath, - NExtractionMode::NPath::EEnum pathMode, - NExtractionMode::NOverwrite::EEnum overwriteMode, + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, const UStringVector &removePathParts, const UString &itemDefaultName, const FILETIME &utcLastWriteTimeDefault, - UINT32 anAttributesDefault - // bool passwordIsDefined, const UString &password - // UString srcDirectoryPrefix - ); + UInt32 attributesDefault); - UINT64 _numErrors; + UInt64 _numErrors; }; #endif diff --git a/7zip/UI/Common/ArchiveName.cpp b/7zip/UI/Common/ArchiveName.cpp index 91ce0a9f..22fa9ecb 100755 --- a/7zip/UI/Common/ArchiveName.cpp +++ b/7zip/UI/Common/ArchiveName.cpp @@ -29,7 +29,7 @@ UString CreateArchiveName(const UString &srcName, bool fromPrev, bool keepName) { NFile::NFind::CFileInfoW fileInfo; if (!NFile::NFind::FindFile(srcName, fileInfo)) - return ::GetLastError(); + return resultName; resultName = fileInfo.Name; if (!fileInfo.IsDirectory() && !keepName) { diff --git a/7zip/UI/Common/ArchiveName.h b/7zip/UI/Common/ArchiveName.h index 605d0a70..6b001a5a 100755 --- a/7zip/UI/Common/ArchiveName.h +++ b/7zip/UI/Common/ArchiveName.h @@ -1,7 +1,5 @@ // ArchiveName.h -#pragma once - #ifndef __ARCHIVENAME_H #define __ARCHIVENAME_H @@ -9,4 +7,4 @@ UString CreateArchiveName(const UString &srcName, bool fromPrev, bool keepName); -#endif
\ No newline at end of file +#endif diff --git a/7zip/UI/Common/ArchiveOpenCallback.cpp b/7zip/UI/Common/ArchiveOpenCallback.cpp new file mode 100755 index 00000000..bd7ec157 --- /dev/null +++ b/7zip/UI/Common/ArchiveOpenCallback.cpp @@ -0,0 +1,117 @@ +// ArchiveOpenCallback.cpp + +#include "StdAfx.h" + +#include "ArchiveOpenCallback.h" + +#include "Common/StringConvert.h" +#include "Windows/PropVariant.h" + +#include "../../Common/FileStreams.h" + +using namespace NWindows; + +STDMETHODIMP COpenCallbackImp::SetTotal(const UInt64 *files, const UInt64 *bytes) +{ + return Callback->SetTotal(files, bytes); +} + +STDMETHODIMP COpenCallbackImp::SetCompleted(const UInt64 *files, const UInt64 *bytes) +{ + return Callback->SetTotal(files, bytes); +} + +STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value) +{ + NCOM::CPropVariant propVariant; + if (_subArchiveMode) + { + switch(propID) + { + case kpidName: + propVariant = _subArchiveName; + break; + } + propVariant.Detach(value); + return S_OK; + } + switch(propID) + { + case kpidName: + propVariant = _fileInfo.Name; + break; + case kpidIsFolder: + propVariant = _fileInfo.IsDirectory(); + break; + case kpidSize: + propVariant = _fileInfo.Size; + break; + case kpidAttributes: + propVariant = (UInt32)_fileInfo.Attributes; + break; + case kpidLastAccessTime: + propVariant = _fileInfo.LastAccessTime; + break; + case kpidCreationTime: + propVariant = _fileInfo.CreationTime; + break; + case kpidLastWriteTime: + propVariant = _fileInfo.LastWriteTime; + break; + } + propVariant.Detach(value); + return S_OK; +} + +int COpenCallbackImp::FindName(const UString &name) +{ + for (int i = 0; i < FileNames.Size(); i++) + if (name.CompareNoCase(FileNames[i]) == 0) + return i; + return -1; +} + +struct CInFileStreamVol: public CInFileStream +{ + UString Name; + COpenCallbackImp *OpenCallbackImp; + CMyComPtr<IArchiveOpenCallback> OpenCallbackRef; + ~CInFileStreamVol() + { + int index = OpenCallbackImp->FindName(Name); + if (index >= 0) + OpenCallbackImp->FileNames.Delete(index); + } +}; + +STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, + IInStream **inStream) +{ + if (_subArchiveMode) + return S_FALSE; + RINOK(Callback->CheckBreak()); + *inStream = NULL; + UString fullPath = _folderPrefix + name; + if (!NFile::NFind::FindFile(fullPath, _fileInfo)) + return S_FALSE; + if (_fileInfo.IsDirectory()) + return S_FALSE; + CInFileStreamVol *inFile = new CInFileStreamVol; + CMyComPtr<IInStream> inStreamTemp = inFile; + if (!inFile->Open(fullPath)) + return ::GetLastError(); + *inStream = inStreamTemp.Detach(); + inFile->Name = name; + inFile->OpenCallbackImp = this; + inFile->OpenCallbackRef = this; + FileNames.Add(name); + return S_OK; +} + +#ifndef _NO_CRYPTO +STDMETHODIMP COpenCallbackImp::CryptoGetTextPassword(BSTR *password) +{ + return Callback->CryptoGetTextPassword(password); +} +#endif + diff --git a/7zip/UI/Common/ArchiveOpenCallback.h b/7zip/UI/Common/ArchiveOpenCallback.h new file mode 100755 index 00000000..5cf95370 --- /dev/null +++ b/7zip/UI/Common/ArchiveOpenCallback.h @@ -0,0 +1,87 @@ +// ArchiveOpenCallback.h + +#ifndef __ARCHIVE_OPEN_CALLBACK_H +#define __ARCHIVE_OPEN_CALLBACK_H + +#include "Common/String.h" +#include "Common/MyCom.h" +#include "Windows/FileFind.h" + +#ifndef _NO_CRYPTO +#include "../../IPassword.h" +#endif +#include "../../Archive/IArchive.h" + +struct IOpenCallbackUI +{ + virtual HRESULT CheckBreak() = 0; + virtual HRESULT SetTotal(const UInt64 *files, const UInt64 *bytes) = 0; + virtual HRESULT SetCompleted(const UInt64 *files, const UInt64 *bytes) = 0; + #ifndef _NO_CRYPTO + virtual HRESULT CryptoGetTextPassword(BSTR *password) = 0; + virtual HRESULT GetPasswordIfAny(UString &password) = 0; + #endif +}; + +class COpenCallbackImp: + public IArchiveOpenCallback, + public IArchiveOpenVolumeCallback, + public IArchiveOpenSetSubArchiveName, + #ifndef _NO_CRYPTO + public ICryptoGetTextPassword, + #endif + public CMyUnknownImp +{ +public: + #ifndef _NO_CRYPTO + MY_UNKNOWN_IMP3( + IArchiveOpenVolumeCallback, + ICryptoGetTextPassword, + IArchiveOpenSetSubArchiveName + ) + #else + MY_UNKNOWN_IMP2( + IArchiveOpenVolumeCallback, + IArchiveOpenSetSubArchiveName + ) + #endif + + STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes); + STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes); + + // IArchiveOpenVolumeCallback + STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value); + STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream); + + #ifndef _NO_CRYPTO + // ICryptoGetTextPassword + STDMETHOD(CryptoGetTextPassword)(BSTR *password); + #endif + + STDMETHOD(SetSubArchiveName(const wchar_t *name)) + { + _subArchiveMode = true; + _subArchiveName = name; + return S_OK; + } + +private: + UString _folderPrefix; + NWindows::NFile::NFind::CFileInfoW _fileInfo; + bool _subArchiveMode; + UString _subArchiveName; +public: + UStringVector FileNames; + IOpenCallbackUI *Callback; + void Init(const UString &folderPrefix, const UString &fileName) + { + _folderPrefix = folderPrefix; + if (!NWindows::NFile::NFind::FindFile(_folderPrefix + fileName, _fileInfo)) + throw 1; + FileNames.Clear(); + _subArchiveMode = false; + } + int FindName(const UString &name); +}; + +#endif diff --git a/7zip/UI/Common/ArchiverInfo.cpp b/7zip/UI/Common/ArchiverInfo.cpp index 0ff7bae2..5e88d432 100755 --- a/7zip/UI/Common/ArchiverInfo.cpp +++ b/7zip/UI/Common/ArchiverInfo.cpp @@ -10,7 +10,9 @@ #include "Windows/FileFind.h" #include "Windows/FileName.h" #include "Windows/DLL.h" +#ifdef _WIN32 #include "Windows/Registry.h" +#endif #include "Windows/PropVariant.h" #include "../../Archive/IArchive.h" @@ -48,7 +50,7 @@ static void SplitString(const UString &srcString, UStringVector &destStrings) destStrings.Add(string); } -typedef UINT32 (WINAPI * GetHandlerPropertyFunc)( +typedef UInt32 (WINAPI * GetHandlerPropertyFunc)( PROPID propID, PROPVARIANT *value); /* @@ -72,7 +74,7 @@ static wchar_t *kFormatFolderName = L"Formats"; static LPCTSTR kRegistryPath = TEXT("Software\\7-zip"); static LPCTSTR kProgramPathValue = TEXT("Path"); -UString GetBaseFolderPrefix() +static UString GetBaseFolderPrefixFromRegistry() { UString moduleFolderPrefix = GetModuleFolderPrefix(); NFind::CFileInfoW fileInfo; @@ -80,6 +82,7 @@ UString GetBaseFolderPrefix() if (fileInfo.IsDirectory()) return moduleFolderPrefix; CSysString pathSys; + #ifdef _WIN32 { NRegistry::CKey key; if(key.Open(HKEY_CURRENT_USER, kRegistryPath, KEY_READ) == ERROR_SUCCESS) @@ -100,16 +103,25 @@ UString GetBaseFolderPrefix() return path; } } + #endif return moduleFolderPrefix; } -typedef UINT32 (WINAPI *CreateObjectPointer)( +typedef UInt32 (WINAPI *CreateObjectPointer)( const GUID *clsID, const GUID *interfaceID, void **outObject); #endif +#ifndef _SFX +static void SetBuffer(CByteBuffer &bb, const Byte *data, int size) +{ + bb.SetCapacity(size); + memmove((Byte *)bb, data, size); +} +#endif + void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers) { archivers.Clear(); @@ -123,6 +135,10 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers) item.KeepName = false; item.Name = L"7z"; item.Extensions.Add(CArchiverExtInfo(L"7z")); + #ifndef _SFX + const unsigned char kSig[] = {'7' , 'z', 0xBC, 0xAF, 0x27, 0x1C}; + SetBuffer(item.StartSignature, kSig, 6); + #endif archivers.Add(item); } #endif @@ -135,6 +151,10 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers) item.Name = L"BZip2"; item.Extensions.Add(CArchiverExtInfo(L"bz2")); item.Extensions.Add(CArchiverExtInfo(L"tbz2", L".tar")); + #ifndef _SFX + const unsigned char sig[] = {'B' , 'Z', 'h' }; + SetBuffer(item.StartSignature, sig, 3); + #endif archivers.Add(item); } #endif @@ -147,6 +167,21 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers) item.Name = L"GZip"; item.Extensions.Add(CArchiverExtInfo(L"gz")); item.Extensions.Add(CArchiverExtInfo(L"tgz", L".tar")); + #ifndef _SFX + const unsigned char sig[] = { 0x1F, 0x8B }; + SetBuffer(item.StartSignature, sig, 2); + #endif + archivers.Add(item); + } + #endif + + #ifdef FORMAT_SPLIT + { + CArchiverInfo item; + item.UpdateEnabled = false; + item.KeepName = true; + item.Name = L"Split"; + item.Extensions.Add(CArchiverExtInfo(L"001")); archivers.Add(item); } #endif @@ -169,6 +204,10 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers) item.KeepName = false; item.Name = L"Zip"; item.Extensions.Add(CArchiverExtInfo(L"zip")); + #ifndef _SFX + const unsigned char sig[] = { 0x50, 0x4B, 0x03, 0x04 }; + SetBuffer(item.StartSignature, sig, 4); + #endif archivers.Add(item); } #endif @@ -199,13 +238,31 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers) item.UpdateEnabled = false; item.Name = L"Arj"; item.Extensions.Add(CArchiverExtInfo(L"arj")); + #ifndef _SFX + const unsigned char sig[] = { 0x60, 0xEA }; + SetBuffer(item.StartSignature, sig, 2); + #endif + archivers.Add(item); + } + #endif + + #ifdef FORMAT_Z + { + CArchiverInfo item; + item.UpdateEnabled = false; + item.Name = L"Z"; + item.Extensions.Add(CArchiverExtInfo(L"Z")); + #ifndef _SFX + const unsigned char sig[] = { 0x1F, 0x9D }; + SetBuffer(item.StartSignature, sig, 2); + #endif archivers.Add(item); } #endif #else - UString folderPath = GetBaseFolderPrefix() + + UString folderPath = GetBaseFolderPrefixFromRegistry() + kFormatFolderName + L"\\"; NFind::CEnumeratorW enumerator(folderPath + L"*"); NFind::CFileInfoW fileInfo; @@ -253,6 +310,7 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers) UString ext = prop.bstrVal; // item.Extension = prop.bstrVal; + prop.Clear(); UString addExt; @@ -282,23 +340,30 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers) item.Extensions.Add(extInfo); } - if (getHandlerProperty(NArchive::kUpdate, &prop) != S_OK) - continue; - if (prop.vt != VT_BOOL) - continue; - item.UpdateEnabled = VARIANT_BOOLToBool(prop.boolVal); + if (getHandlerProperty(NArchive::kUpdate, &prop) == S_OK) + if (prop.vt == VT_BOOL) + item.UpdateEnabled = VARIANT_BOOLToBool(prop.boolVal); prop.Clear(); if (item.UpdateEnabled) { - if (getHandlerProperty(NArchive::kKeepName, &prop) != S_OK) - continue; - if (prop.vt != VT_BOOL) - continue; - item.KeepName = VARIANT_BOOLToBool(prop.boolVal); + if (getHandlerProperty(NArchive::kKeepName, &prop) == S_OK) + if (prop.vt == VT_BOOL) + item.KeepName = VARIANT_BOOLToBool(prop.boolVal); prop.Clear(); } + if (getHandlerProperty(NArchive::kStartSignature, &prop) == S_OK) + { + if (prop.vt == VT_BSTR) + { + UINT len = ::SysStringByteLen(prop.bstrVal); + item.StartSignature.SetCapacity(len); + memmove(item.StartSignature, prop.bstrVal, len); + } + } + prop.Clear(); + archivers.Add(item); } diff --git a/7zip/UI/Common/ArchiverInfo.h b/7zip/UI/Common/ArchiverInfo.h index 8a21266e..0ce057fa 100755 --- a/7zip/UI/Common/ArchiverInfo.h +++ b/7zip/UI/Common/ArchiverInfo.h @@ -1,12 +1,11 @@ // ArchiverInfo.h -#pragma once - #ifndef __ARCHIVERINFO_H #define __ARCHIVERINFO_H #include "Common/String.h" #include "Common/Types.h" +#include "Common/Buffer.h" struct CArchiverExtInfo { @@ -27,6 +26,10 @@ struct CArchiverInfo #endif UString Name; CObjectVector<CArchiverExtInfo> Extensions; + #ifndef _SFX + CByteBuffer StartSignature; + CByteBuffer FinishSignature; + #endif int FindExtension(const UString &ext) const { for (int i = 0; i < Extensions.Size(); i++) diff --git a/7zip/UI/Common/CompressCall.cpp b/7zip/UI/Common/CompressCall.cpp index d6cdf57e..7e4548be 100755 --- a/7zip/UI/Common/CompressCall.cpp +++ b/7zip/UI/Common/CompressCall.cpp @@ -11,14 +11,18 @@ #include "Windows/Synchronization.h" #include "Windows/FileMapping.h" +#include "Windows/FileDir.h" #include "../../FileManager/ProgramLocation.h" using namespace NWindows; static LPCWSTR kShowDialogSwitch = L" -ad"; -static LPCWSTR kEmailSwitch = L" -seml"; +static LPCWSTR kEmailSwitch = L" -seml."; static LPCWSTR kMapSwitch = L" -i#"; +static LPCWSTR kArchiveNoNameSwitch = L" -an"; +static LPCWSTR kArchiveMapSwitch = L" -ai#"; +static LPCWSTR kStopSwitchParsing = L" --"; static bool IsItWindowsNT() @@ -31,6 +35,7 @@ static bool IsItWindowsNT() } HRESULT MyCreateProcess(const UString ¶ms, + LPCTSTR curDir, NWindows::NSynchronization::CEvent *event) { STARTUPINFO startupInfo; @@ -45,7 +50,8 @@ HRESULT MyCreateProcess(const UString ¶ms, PROCESS_INFORMATION processInformation; BOOL result = ::CreateProcess(NULL, (TCHAR *)(const TCHAR *) GetSystemString(params), - NULL, NULL, FALSE, 0, NULL, NULL, + NULL, NULL, FALSE, 0, NULL, + curDir, &startupInfo, &processInformation); if (result == 0) return ::GetLastError(); @@ -70,7 +76,7 @@ static UString GetQuotedString(const UString &s) static UString Get7zGuiPath() { - UString path = L"\""; + UString path; UString folder; if (GetProgramFolderPath(folder)) path += folder; @@ -78,28 +84,117 @@ static UString Get7zGuiPath() path += L"7zgn.exe"; else path += L"7zg.exe"; - path += L"\""; - return path; + // path += L"7z.exe"; + return GetQuotedString(path); +} + +static HRESULT CreateMap(const UStringVector &names, + const UString &id, + CFileMapping &fileMapping, NSynchronization::CEvent &event, + UString ¶ms) +{ + UInt32 extraSize = 2; + UInt32 dataSize = 0; + for (int i = 0; i < names.Size(); i++) + dataSize += (names[i].Length() + 1) * sizeof(wchar_t); + UInt32 totalSize = extraSize + dataSize; + + UString mappingName; + UString eventName; + + CRandom random; + random.Init(GetTickCount()); + while(true) + { + int number = random.Generate(); + wchar_t temp[32]; + ConvertUInt64ToString(UInt32(number), temp); + mappingName = id; + mappingName += L"Mapping"; + mappingName += temp; + if (!fileMapping.Create(INVALID_HANDLE_VALUE, NULL, + PAGE_READWRITE, totalSize, GetSystemString(mappingName))) + return E_FAIL; + if (::GetLastError() != ERROR_ALREADY_EXISTS) + break; + fileMapping.Close(); + } + + while(true) + { + int number = random.Generate(); + wchar_t temp[32]; + ConvertUInt64ToString(UInt32(number), temp); + eventName = id; + eventName += L"MappingEndEvent"; + eventName += temp; + if (!event.Create(true, false, GetSystemString(eventName))) + return E_FAIL; + if (::GetLastError() != ERROR_ALREADY_EXISTS) + break; + event.Close(); + } + + params += mappingName; + params += L":"; + wchar_t string[10]; + ConvertUInt64ToString(totalSize, string); + params += string; + + params += L":"; + params += eventName; + + LPVOID data = fileMapping.MapViewOfFile(FILE_MAP_WRITE, 0, totalSize); + if (data == NULL) + return E_FAIL; + try + { + wchar_t *curData = (wchar_t *)data; + *curData = 0; + curData++; + for (int i = 0; i < names.Size(); i++) + { + const UString &s = names[i]; + memcpy(curData, (const wchar_t *)s, s.Length() * sizeof(wchar_t)); + curData += s.Length(); + *curData++ = L'\0'; + } + } + catch(...) + { + UnmapViewOfFile(data); + throw; + } + // UnmapViewOfFile(data); + return S_OK; } HRESULT CompressFiles( + const UString &curDir, const UString &archiveName, const UStringVector &names, // const UString &outFolder, bool email, bool showDialog) { + /* + UString curDir; + if (names.Size() > 0) + { + NFile::NDirectory::GetOnlyDirPrefix(names[0], curDir); + } + */ UString params; params = Get7zGuiPath(); params += L" a"; params += kMapSwitch; // params += _fileNames[0]; - UINT32 extraSize = 2; - UINT32 dataSize = 0; + UInt32 extraSize = 2; + UInt32 dataSize = 0; for (int i = 0; i < names.Size(); i++) dataSize += (names[i].Length() + 1) * sizeof(wchar_t); - UINT32 totalSize = extraSize + dataSize; + UInt32 totalSize = extraSize + dataSize; UString mappingName; UString eventName; @@ -111,7 +206,7 @@ HRESULT CompressFiles( { int number = random.Generate(); wchar_t temp[32]; - ConvertUINT64ToString(UINT32(number), temp); + ConvertUInt64ToString(UInt32(number), temp); mappingName = L"7zCompressMapping"; mappingName += temp; if (!fileMapping.Create(INVALID_HANDLE_VALUE, NULL, @@ -130,7 +225,7 @@ HRESULT CompressFiles( { int number = random.Generate(); wchar_t temp[32]; - ConvertUINT64ToString(UINT32(number), temp); + ConvertUInt64ToString(UInt32(number), temp); eventName = L"7zCompressMappingEndEvent"; eventName += temp; if (!event.Create(true, false, GetSystemString(eventName))) @@ -146,7 +241,7 @@ HRESULT CompressFiles( params += mappingName; params += L":"; wchar_t string[10]; - ConvertUINT64ToString(totalSize, string); + ConvertUInt64ToString(totalSize, string); params += string; params += L":"; @@ -158,7 +253,9 @@ HRESULT CompressFiles( if (showDialog) params += kShowDialogSwitch; + params += kStopSwitchParsing; params += L" "; + params += GetQuotedString(archiveName); LPVOID data = fileMapping.MapViewOfFile(FILE_MAP_WRITE, 0, totalSize); @@ -177,11 +274,14 @@ HRESULT CompressFiles( const UString &unicodeString = names[i]; memcpy(curData, (const wchar_t *)unicodeString , unicodeString .Length() * sizeof(wchar_t)); - curData += unicodeString .Length(); + curData += unicodeString.Length(); *curData++ = L'\0'; } // MessageBox(0, params, 0, 0); - RINOK(MyCreateProcess(params, &event)); + CSysString sysCurDir = GetSystemString(curDir); + RINOK(MyCreateProcess(params, + (sysCurDir.IsEmpty()? 0: (LPCTSTR)sysCurDir), + &event)); } catch(...) { @@ -190,8 +290,7 @@ HRESULT CompressFiles( } UnmapViewOfFile(data); - - + /* CThreadCompressMain *compressor = new CThreadCompressMain();; compressor->FileNames = _fileNames; @@ -202,13 +301,24 @@ HRESULT CompressFiles( return S_OK; } -HRESULT ExtractArchive(const UString &archiveName, +static HRESULT ExtractGroupCommand(const UStringVector &archivePaths, + const UString ¶ms) +{ + UString params2 = params; + params2 += kArchiveNoNameSwitch; + params2 += kArchiveMapSwitch; + CFileMapping fileMapping; + NSynchronization::CEvent event; + RINOK(CreateMap(archivePaths, L"7zExtract", fileMapping, event, params2)); + return MyCreateProcess(params2, 0, &event); +} + +HRESULT ExtractArchives(const UStringVector &archivePaths, const UString &outFolder, bool showDialog) { UString params; params = Get7zGuiPath(); - params += L" x "; - params += GetQuotedString(archiveName); + params += L" x"; if (!outFolder.IsEmpty()) { params += L" -o"; @@ -216,14 +326,13 @@ HRESULT ExtractArchive(const UString &archiveName, } if (showDialog) params += kShowDialogSwitch; - return MyCreateProcess(params); + return ExtractGroupCommand(archivePaths, params); } -HRESULT TestArchive(const UString &archiveName) +HRESULT TestArchives(const UStringVector &archivePaths) { UString params; params = Get7zGuiPath(); - params += L" t "; - params += GetQuotedString(archiveName); - return MyCreateProcess(params); + params += L" t"; + return ExtractGroupCommand(archivePaths, params); } diff --git a/7zip/UI/Common/CompressCall.h b/7zip/UI/Common/CompressCall.h index 73d93984..6cf86b69 100755 --- a/7zip/UI/Common/CompressCall.h +++ b/7zip/UI/Common/CompressCall.h @@ -6,17 +6,21 @@ #include "Common/String.h" #include "Windows/Synchronization.h" -HRESULT MyCreateProcess(const UString ¶ms, - NWindows::NSynchronization::CEvent *event = NULL); -HRESULT CompressFiles(const UString &archiveName, +HRESULT MyCreateProcess(const UString ¶ms, + LPCTSTR lpCurrentDirectory, + NWindows::NSynchronization::CEvent *event = NULL); +HRESULT CompressFiles( + const UString &curDir, + const UString &archiveName, const UStringVector &names, // const UString &outFolder, bool email, bool showDialog); -HRESULT ExtractArchive(const UString &archiveName, +HRESULT ExtractArchives( + const UStringVector &archivePaths, const UString &outFolder, bool showDialog); -HRESULT TestArchive(const UString &archiveName); +HRESULT TestArchives(const UStringVector &archivePaths); #endif diff --git a/7zip/UI/Common/DefaultName.cpp b/7zip/UI/Common/DefaultName.cpp index 73ba2274..dcc2152d 100755 --- a/7zip/UI/Common/DefaultName.cpp +++ b/7zip/UI/Common/DefaultName.cpp @@ -2,32 +2,22 @@ #include "StdAfx.h" -#include "Windows/FileDir.h" - -#include "Common/StringConvert.h" #include "DefaultName.h" -const wchar_t *kEmptyFileAlias = L"[Content]"; - -using namespace NWindows; -using namespace NFile; -using namespace NDirectory; +static const wchar_t *kEmptyFileAlias = L"[Content]"; -UString GetDefaultName(const UString &fullFileName, +UString GetDefaultName2(const UString &fileName, const UString &extension, const UString &addSubExtension) { - UString fileName; - if (!GetOnlyName(fullFileName, fileName)) - throw 5011749; int extLength = extension.Length(); int fileNameLength = fileName.Length(); - if (fileNameLength <= extLength + 1) - return kEmptyFileAlias; - int dotPos = fileNameLength - (extLength + 1); - if (fileName[dotPos] != '.') - return kEmptyFileAlias; - if (extension.CollateNoCase(fileName.Mid(dotPos + 1)) == 0) - return fileName.Left(dotPos) + addSubExtension; + if (fileNameLength > extLength + 1) + { + int dotPos = fileNameLength - (extLength + 1); + if (fileName[dotPos] == '.') + if (extension.CollateNoCase(fileName.Mid(dotPos + 1)) == 0) + return fileName.Left(dotPos) + addSubExtension; + } return kEmptyFileAlias; } diff --git a/7zip/UI/Common/DefaultName.h b/7zip/UI/Common/DefaultName.h index 57e64cec..ff6330fa 100755 --- a/7zip/UI/Common/DefaultName.h +++ b/7zip/UI/Common/DefaultName.h @@ -1,13 +1,11 @@ // DefaultName.h -#pragma once - #ifndef __DEFAULTNAME_H #define __DEFAULTNAME_H #include "Common/String.h" -UString GetDefaultName(const UString &fullFileName, +UString GetDefaultName2(const UString &fileName, const UString &extension, const UString &addSubExtension); #endif diff --git a/7zip/UI/Common/DirItem.h b/7zip/UI/Common/DirItem.h index 7fe882bc..9537071c 100755 --- a/7zip/UI/Common/DirItem.h +++ b/7zip/UI/Common/DirItem.h @@ -1,21 +1,18 @@ // DirItem.h -#pragma once - #ifndef __DIR_ITEM_H #define __DIR_ITEM_H -// #include "Common/Types.h" #include "Common/String.h" -// #include "Windows/PropVariant.h" +#include "Common/Types.h" struct CDirItem { - UINT32 Attributes; + UInt32 Attributes; FILETIME CreationTime; FILETIME LastAccessTime; FILETIME LastWriteTime; - UINT64 Size; + UInt64 Size; UString Name; UString FullPath; bool IsDirectory() const { return (Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0 ; } @@ -28,7 +25,7 @@ struct CArchiveItem // NWindows::NCOM::CPropVariant LastWriteTime; FILETIME LastWriteTime; bool SizeIsDefined; - UINT64 Size; + UInt64 Size; UString Name; bool Censored; int IndexInServer; diff --git a/7zip/UI/Common/EnumDirItems.cpp b/7zip/UI/Common/EnumDirItems.cpp index 50fc2a28..e7df5392 100755 --- a/7zip/UI/Common/EnumDirItems.cpp +++ b/7zip/UI/Common/EnumDirItems.cpp @@ -2,8 +2,11 @@ #include "StdAfx.h" -#include "EnumDirItems.h" #include "Common/StringConvert.h" +#include "Common/Wildcard.h" +#include "Common/MyCom.h" + +#include "EnumDirItems.h" using namespace NWindows; using namespace NFile; @@ -28,27 +31,33 @@ void AddDirFileInfo( dirItems.Add(item); } -static void EnumerateDirectory( +static HRESULT EnumerateDirectory( const UString &baseFolderPrefix, const UString &directory, const UString &prefix, CObjectVector<CDirItem> &dirItems) { NFind::CEnumeratorW enumerator(baseFolderPrefix + directory + wchar_t(kAnyStringWildcard)); - NFind::CFileInfoW fileInfo; - while (enumerator.Next(fileInfo)) + while (true) { + NFind::CFileInfoW fileInfo; + bool found; + if (!enumerator.Next(fileInfo, found)) + return ::GetLastError(); + if (!found) + break; AddDirFileInfo(prefix, directory + fileInfo.Name, fileInfo, dirItems); if (fileInfo.IsDirectory()) { - EnumerateDirectory(baseFolderPrefix, directory + fileInfo.Name + wchar_t(kDirDelimiter), - prefix + fileInfo.Name + wchar_t(kDirDelimiter), dirItems); + RINOK(EnumerateDirectory(baseFolderPrefix, directory + fileInfo.Name + wchar_t(kDirDelimiter), + prefix + fileInfo.Name + wchar_t(kDirDelimiter), dirItems)); } } + return S_OK; } -void EnumerateDirItems( +HRESULT EnumerateDirItems( const UString &baseFolderPrefix, const UStringVector &fileNames, const UString &archiveNamePrefix, @@ -63,9 +72,88 @@ void EnumerateDirItems( AddDirFileInfo(archiveNamePrefix, fileName, fileInfo, dirItems); if (fileInfo.IsDirectory()) { - EnumerateDirectory(baseFolderPrefix, fileName + wchar_t(kDirDelimiter), + RINOK(EnumerateDirectory(baseFolderPrefix, fileName + wchar_t(kDirDelimiter), archiveNamePrefix + fileInfo.Name + wchar_t(kDirDelimiter), - dirItems); + dirItems)); + } + } + return S_OK; +} + +static HRESULT EnumerateDirItems( + const NWildcard::CCensorNode &curNode, + const UString &diskPrefix, + const UString &archivePrefix, + const UString &addArchivePrefix, + CObjectVector<CDirItem> &dirItems, + bool enterToSubFolders, + IEnumDirItemCallback *callback) +{ + if (!enterToSubFolders) + if (curNode.NeedCheckSubDirs()) + enterToSubFolders = true; + if (callback) + RINOK(callback->CheckBreak()); + NFind::CEnumeratorW enumerator(diskPrefix + wchar_t(kAnyStringWildcard)); + while (true) + { + NFind::CFileInfoW fileInfo; + bool found; + if (!enumerator.Next(fileInfo, found)) + return ::GetLastError(); + if (!found) + break; + + if (callback) + RINOK(callback->CheckBreak()); + UString name = fileInfo.Name; + bool enterToSubFolders2 = enterToSubFolders; + if (curNode.CheckPathToRoot(addArchivePrefix + name, !fileInfo.IsDirectory())) + { + AddDirFileInfo(archivePrefix, diskPrefix + fileInfo.Name, fileInfo, dirItems); + if (fileInfo.IsDirectory()) + enterToSubFolders2 = true;; + } + if (!fileInfo.IsDirectory()) + continue; + + const NWildcard::CCensorNode *nextNode = 0; + if (addArchivePrefix.IsEmpty()) + { + int index = curNode.FindSubNode(name); + if (index >= 0) + nextNode = &curNode.SubNodes[index]; + } + if (!enterToSubFolders2 && nextNode == 0) + continue; + + UString archivePrefixNew = archivePrefix; + UString addArchivePrefixNew = addArchivePrefix; + if (nextNode == 0) + { + nextNode = &curNode; + addArchivePrefixNew += name; + addArchivePrefixNew += wchar_t(kDirDelimiter); } + archivePrefixNew += name; + archivePrefixNew += wchar_t(kDirDelimiter); + RINOK(EnumerateDirItems(*nextNode, + diskPrefix + fileInfo.Name + wchar_t(kDirDelimiter), + archivePrefixNew, addArchivePrefixNew, + dirItems, enterToSubFolders2, callback)); + } + return S_OK; +} + +HRESULT EnumerateItems(const NWildcard::CCensor &censor, + CObjectVector<CDirItem> &dirItems, IEnumDirItemCallback *callback) +{ + for (int i = 0; i < censor.Pairs.Size(); i++) + { + if (callback) + RINOK(callback->CheckBreak()); + const NWildcard::CPair &pair = censor.Pairs[i]; + RINOK(EnumerateDirItems(pair.Head, pair.Prefix, L"", L"", dirItems, false, callback)); } + return S_OK; } diff --git a/7zip/UI/Common/EnumDirItems.h b/7zip/UI/Common/EnumDirItems.h index 4d2d4386..cb508cdf 100755 --- a/7zip/UI/Common/EnumDirItems.h +++ b/7zip/UI/Common/EnumDirItems.h @@ -1,14 +1,10 @@ // EnumDirItems.h -#pragma once - #ifndef __ENUM_DIR_ITEMS_H #define __ENUM_DIR_ITEMS_H -#include "Common/String.h" -#include "Common/Vector.h" +#include "Common/Wildcard.h" #include "DirItem.h" -// #include "UpdatePairBasic.h" #include "Windows/FileFind.h" @@ -18,16 +14,20 @@ void AddDirFileInfo( NWindows::NFile::NFind::CFileInfoW &fileInfo, CObjectVector<CDirItem> &dirItems); -void EnumerateDirItems( + +HRESULT EnumerateDirItems( const UString &baseFolderPrefix, const UStringVector &fileNames, const UString &archiveNamePrefix, CObjectVector<CDirItem> &dirItems); -/* -void EnumerateItems(const CSysStringVector &filePaths, - const UString &archiveNamePrefix, - CArchiveStyleDirItemInfoVector &dirFileInfoVector, UINT codePage); -*/ +struct IEnumDirItemCallback +{ + virtual HRESULT CheckBreak() { return S_OK; } +}; + + +HRESULT EnumerateItems(const NWildcard::CCensor &censor, + CObjectVector<CDirItem> &dirItems, IEnumDirItemCallback *callback); #endif diff --git a/7zip/UI/Common/ExitCode.h b/7zip/UI/Common/ExitCode.h new file mode 100755 index 00000000..0aac3695 --- /dev/null +++ b/7zip/UI/Common/ExitCode.h @@ -0,0 +1,27 @@ +// ExitCode.h + +#ifndef __EXIT_CODE_H +#define __EXIT_CODE_H + +namespace NExitCode { + +enum EEnum { + + kSuccess = 0, // Successful operation + kWarning = 1, // Non fatal error(s) occurred + kFatalError = 2, // A fatal error occurred + // kCRCError = 3, // A CRC error occurred when unpacking + // kLockedArchive = 4, // Attempt to modify an archive previously locked + // kWriteError = 5, // Write to disk error + // kOpenError = 6, // Open file error + kUserError = 7, // Command line option error + kMemoryError = 8, // Not enough memory for operation + // kCreateFileError = 9, // Create file error + + kUserBreak = 255 // User stopped the process + +}; + +} + +#endif diff --git a/7zip/UI/Common/Extract.cpp b/7zip/UI/Common/Extract.cpp new file mode 100755 index 00000000..bf335107 --- /dev/null +++ b/7zip/UI/Common/Extract.cpp @@ -0,0 +1,127 @@ +// Extract.cpp + +#include "StdAfx.h" + +#include "Extract.h" + +#include "Windows/Defs.h" +#include "Windows/PropVariant.h" +#include "Windows/FileDir.h" + +#include "OpenArchive.h" + +#ifndef EXCLUDE_COM +#include "Windows/DLL.h" +#endif + +using namespace NWindows; + +HRESULT DecompressArchive( + IInArchive *archive, + const UString &defaultName, + const NWildcard::CCensorNode &wildcardCensor, + const CExtractOptions &options, + IExtractCallbackUI *callback) +{ + CRecordVector<UInt32> realIndices; + UInt32 numItems; + RINOK(archive->GetNumberOfItems(&numItems)); + + for(UInt32 i = 0; i < numItems; i++) + { + UString filePath; + RINOK(GetArchiveItemPath(archive, i, options.DefaultItemName, filePath)); + bool isFolder; + RINOK(IsArchiveItemFolder(archive, i, isFolder)); + if (!wildcardCensor.CheckPath(filePath, !isFolder)) + continue; + realIndices.Add(i); + } + if (realIndices.Size() == 0) + { + callback->ThereAreNoFiles(); + return S_OK; + } + + CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback; + CMyComPtr<IArchiveExtractCallback> extractCallback(extractCallbackSpec); + + UStringVector removePathParts; + + UString outDir = options.OutputDir; + outDir.Replace(L"*", defaultName); + if(!outDir.IsEmpty()) + if(!NFile::NDirectory::CreateComplexDirectory(outDir)) + { + throw UString(L"Can not create output directory ") + outDir; + } + + extractCallbackSpec->Init( + archive, + callback, + options.StdOutMode, + outDir, + options.PathMode, + options.OverwriteMode, + removePathParts, + options.DefaultItemName, + options.ArchiveFileInfo.LastWriteTime, + options.ArchiveFileInfo.Attributes); + + HRESULT result = archive->Extract(&realIndices.Front(), + realIndices.Size(), options.TestMode? 1: 0, + extractCallback); + + return callback->ExtractResult(result); +} + +HRESULT DecompressArchives( + UStringVector &archivePaths, UStringVector &archivePathsFull, + const NWildcard::CCensorNode &wildcardCensor, + const CExtractOptions &optionsSpec, + IOpenCallbackUI *openCallback, + IExtractCallbackUI *extractCallback) +{ + CExtractOptions options = optionsSpec; + for (int i = 0; i < archivePaths.Size(); i++) + { + const UString &archivePath = archivePaths[i]; + NFile::NFind::CFileInfoW archiveFileInfo; + if (!NFile::NFind::FindFile(archivePath, archiveFileInfo)) + throw "there is no such archive"; + + if (archiveFileInfo.IsDirectory()) + throw "there is no such archive"; + + options.ArchiveFileInfo = archiveFileInfo; + + RINOK(extractCallback->BeforeOpen(archivePath)); + CArchiveLink archiveLink; + HRESULT result = MyOpenArchive(archivePath, archiveLink, openCallback); + RINOK(extractCallback->OpenResult(archivePath, result)); + if (result != S_OK) + continue; + + for (int v = 0; v < archiveLink.VolumePaths.Size(); v++) + { + int index = archivePathsFull.FindInSorted(archiveLink.VolumePaths[v]); + if (index >= 0 && index > i) + { + archivePaths.Delete(index); + archivePathsFull.Delete(index); + } + } + UString password; + RINOK(openCallback->GetPasswordIfAny(password)); + if (!password.IsEmpty()) + { + RINOK(extractCallback->SetPassword(password)); + } + + options.DefaultItemName = archiveLink.GetDefaultItemName(); + RINOK(DecompressArchive( + archiveLink.GetArchive(), archiveLink.GetDefaultItemName(), + wildcardCensor, options, extractCallback)); + } + return S_OK; +}
\ No newline at end of file diff --git a/7zip/UI/Common/Extract.h b/7zip/UI/Common/Extract.h new file mode 100755 index 00000000..e124d466 --- /dev/null +++ b/7zip/UI/Common/Extract.h @@ -0,0 +1,55 @@ +// Extract.h + +#ifndef __EXTRACT_H +#define __EXTRACT_H + +#include "Common/Wildcard.h" +#include "Windows/FileFind.h" + +#include "../../Archive/IArchive.h" +#include "../Common/ZipRegistry.h" + +#include "ArchiveExtractCallback.h" +#include "ArchiveOpenCallback.h" +#include "ExtractMode.h" + +class CExtractOptions +{ +public: + bool StdOutMode; + bool TestMode; + NExtract::NPathMode::EEnum PathMode; + + UString OutputDir; + bool YesToAll; + UString DefaultItemName; + NWindows::NFile::NFind::CFileInfoW ArchiveFileInfo; + + // bool ShowDialog; + // bool PasswordEnabled; + // UString Password; + + NExtract::NOverwriteMode::EEnum OverwriteMode; + + CExtractOptions(): + StdOutMode(false), + YesToAll(false), + TestMode(false), + PathMode(NExtract::NPathMode::kFullPathnames), + OverwriteMode(NExtract::NOverwriteMode::kAskBefore) + {} + + /* + bool FullPathMode() const { return (ExtractMode == NExtractMode::kTest) || + (ExtractMode == NExtractMode::kFullPath); } + */ +}; + +HRESULT DecompressArchives( + UStringVector &archivePaths, UStringVector &archivePathsFull, + const NWildcard::CCensorNode &wildcardCensor, + const CExtractOptions &options, + IOpenCallbackUI *openCallback, + IExtractCallbackUI *extractCallback); + +#endif diff --git a/7zip/UI/Common/ExtractMode.h b/7zip/UI/Common/ExtractMode.h new file mode 100755 index 00000000..96b5a8cd --- /dev/null +++ b/7zip/UI/Common/ExtractMode.h @@ -0,0 +1,31 @@ +// ExtractMode.h + +#ifndef __EXTRACT_MODE_H +#define __EXTRACT_MODE_H + +namespace NExtract { + + namespace NPathMode + { + enum EEnum + { + kFullPathnames, + kCurrentPathnames, + kNoPathnames + }; + } + + namespace NOverwriteMode + { + enum EEnum + { + kAskBefore, + kWithoutPrompt, + kSkipExisting, + kAutoRename, + kAutoRenameExisting + }; + } +} + +#endif diff --git a/7zip/UI/Common/ExtractingFilePath.cpp b/7zip/UI/Common/ExtractingFilePath.cpp index d1797f64..b1a6d876 100755 --- a/7zip/UI/Common/ExtractingFilePath.cpp +++ b/7zip/UI/Common/ExtractingFilePath.cpp @@ -3,20 +3,32 @@ #include "StdAfx.h" #include "ExtractingFilePath.h" -UString GetCorrectFileName(const UString &path) +static void ReplaceDisk(UString &s) { - UString result = path; - result.Trim(); - result.Replace(L"..\\", L""); - result.Replace(L"../", L""); - if (result.Length() > 1) + int i; + for (i = 0; i < s.Length(); i++) + if (s[i] != ' ') + break; + if (s.Length() > i + 1) { - if (result[1] == L':') + if (s[i + 1] == L':') { - result.Delete(1); - // result.Insert(first + 1, L'_'); + s.Delete(i + 1); + // s.Insert(i + 1, L'_'); } } +} + +UString GetCorrectFileName(const UString &path) +{ + UString result = path; + { + UString test = path; + test.Trim(); + if (test == L"..") + result.Replace(L"..", L""); + } + ReplaceDisk(result); return result; } @@ -29,7 +41,6 @@ UString GetCorrectPath(const UString &path) break; while(result.Length() > first) { - if (result[first] == L'\\' || result[first] == L'/') { result.Delete(first); @@ -40,15 +51,19 @@ UString GetCorrectPath(const UString &path) result.Replace(L"..\\", L""); result.Replace(L"../", L""); - if (result.Length() > 1) - { - if (result[first + 1] == L':') - { - result.Delete(first + 1); - // result.Insert(first + 1, L'_'); - } - } + ReplaceDisk(result); return result; - } +void MakeCorrectPath(UStringVector &pathParts) +{ + for (int i = 0; i < pathParts.Size();) + { + UString &s = pathParts[i]; + s = GetCorrectFileName(s); + if (s.IsEmpty()) + pathParts.Delete(i); + else + i++; + } +} diff --git a/7zip/UI/Common/ExtractingFilePath.h b/7zip/UI/Common/ExtractingFilePath.h index 0b8f08bb..0ae9e9b8 100755 --- a/7zip/UI/Common/ExtractingFilePath.h +++ b/7zip/UI/Common/ExtractingFilePath.h @@ -1,7 +1,5 @@ // ExtractingFilePath.h -#pragma once - #ifndef __EXTRACTINGFILEPATH_H #define __EXTRACTINGFILEPATH_H @@ -9,5 +7,6 @@ UString GetCorrectFileName(const UString &path); UString GetCorrectPath(const UString &path); +void MakeCorrectPath(UStringVector &pathParts); #endif diff --git a/7zip/UI/Common/HandlerLoader.h b/7zip/UI/Common/HandlerLoader.h index ec81b5c7..2a878019 100755 --- a/7zip/UI/Common/HandlerLoader.h +++ b/7zip/UI/Common/HandlerLoader.h @@ -1,14 +1,12 @@ // HandlerLoader.h -#pragma once - #ifndef __HANDLERLOADER_H #define __HANDLERLOADER_H #include "../../ICoder.h" #include "Windows/DLL.h" -typedef UINT32 (WINAPI * CreateObjectFunc)( +typedef UInt32 (WINAPI * CreateObjectFunc)( const GUID *clsID, const GUID *interfaceID, void **outObject); @@ -37,6 +35,4 @@ public: } }; - #endif - diff --git a/7zip/UI/Common/IFileExtractCallback.h b/7zip/UI/Common/IFileExtractCallback.h new file mode 100755 index 00000000..ac2c6543 --- /dev/null +++ b/7zip/UI/Common/IFileExtractCallback.h @@ -0,0 +1,46 @@ +// IFileExtractCallback.h + +#ifndef __IFILEEXTRACTCALLBACK_H +#define __IFILEEXTRACTCALLBACK_H + +#include "Common/String.h" + +namespace NOverwriteAnswer +{ + enum EEnum + { + kYes, + kYesToAll, + kNo, + kNoToAll, + kAutoRename, + kCancel, + }; +} + +// {23170F69-40C1-278A-0000-000100070000} +DEFINE_GUID(IID_IFolderArchiveExtractCallback, +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x00); +MIDL_INTERFACE("23170F69-40C1-278A-0000-000100070000") +IFolderArchiveExtractCallback: public IProgress +{ +public: + STDMETHOD(AskOverwrite)( + const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize, + const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize, + Int32 *answer) PURE; + STDMETHOD(PrepareOperation)(const wchar_t *name, Int32 askExtractMode, const UInt64 *position) PURE; + STDMETHOD(MessageError)(const wchar_t *message) PURE; + STDMETHOD(SetOperationResult)(Int32 operationResult) PURE; +}; + +struct IExtractCallbackUI: IFolderArchiveExtractCallback +{ + virtual HRESULT BeforeOpen(const wchar_t *name) = 0; + virtual HRESULT OpenResult(const wchar_t *name, HRESULT result) = 0; + virtual HRESULT ThereAreNoFiles() = 0; + virtual HRESULT ExtractResult(HRESULT result) = 0; + virtual HRESULT SetPassword(const UString &password) = 0; +}; + +#endif diff --git a/7zip/UI/Common/OpenArchive.cpp b/7zip/UI/Common/OpenArchive.cpp index d64f436f..a045f7dc 100755 --- a/7zip/UI/Common/OpenArchive.cpp +++ b/7zip/UI/Common/OpenArchive.cpp @@ -4,9 +4,12 @@ #include "OpenArchive.h" +#include "Common/Wildcard.h" + #include "Windows/FileName.h" #include "Windows/FileDir.h" #include "Windows/Defs.h" +#include "Windows/PropVariant.h" #include "../../Common/FileStreams.h" @@ -24,6 +27,10 @@ #include "../../Archive/GZip/GZipHandler.h" #endif +#ifdef FORMAT_SPLIT +#include "../../Archive/Split/SplitHandler.h" +#endif + #ifdef FORMAT_TAR #include "../../Archive/Tar/TarHandler.h" #endif @@ -32,17 +39,86 @@ #include "../../Archive/Zip/ZipHandler.h" #endif +#ifdef FORMAT_Z +#include "../../Archive/Z/ZHandler.h" +#endif + #ifndef EXCLUDE_COM #include "HandlerLoader.h" #endif +#include "DefaultName.h" using namespace NWindows; -const UINT64 kMaxCheckStartPosition = 1 << 20; +HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, UString &result) +{ + NCOM::CPropVariant prop; + RINOK(archive->GetProperty(index, kpidPath, &prop)); + if(prop.vt == VT_BSTR) + result = prop.bstrVal; + else if (prop.vt == VT_EMPTY) + result.Empty(); + else + return E_FAIL; + return S_OK; +} -HRESULT ReOpenArchive(IInArchive *archive, - const UString &fileName) +HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, const UString &defaultName, UString &result) +{ + RINOK(GetArchiveItemPath(archive, index, result)); + if (result.IsEmpty()) + result = defaultName; + return S_OK; +} + +HRESULT GetArchiveItemFileTime(IInArchive *archive, UInt32 index, + const FILETIME &defaultFileTime, FILETIME &fileTime) +{ + NCOM::CPropVariant prop; + RINOK(archive->GetProperty(index, kpidLastWriteTime, &prop)); + if (prop.vt == VT_FILETIME) + fileTime = prop.filetime; + else if (prop.vt == VT_EMPTY) + fileTime = defaultFileTime; + else + return E_FAIL; + return S_OK; +} + +static HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result) +{ + NCOM::CPropVariant prop; + RINOK(archive->GetProperty(index, propID, &prop)); + if(prop.vt == VT_BOOL) + result = VARIANT_BOOLToBool(prop.boolVal); + else if (prop.vt == VT_EMPTY) + result = false; + else + return E_FAIL; + return S_OK; +} + +HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result) +{ + return IsArchiveItemProp(archive, index, kpidIsFolder, result); +} + +HRESULT IsArchiveItemAnti(IInArchive *archive, UInt32 index, bool &result) +{ + return IsArchiveItemProp(archive, index, kpidIsAnti, result); +} + +// Static-SFX (for Linux) can be big +const UInt64 kMaxCheckStartPosition = +#ifdef _WIN32 +1 << 20; +#else +1 << 22; +#endif + + +HRESULT ReOpenArchive(IInArchive *archive, const UString &fileName) { CInFileStream *inStreamSpec = new CInFileStream; CMyComPtr<IInStream> inStream(inStreamSpec); @@ -50,49 +126,87 @@ HRESULT ReOpenArchive(IInArchive *archive, return archive->Open(inStream, &kMaxCheckStartPosition, NULL); } -HRESULT OpenArchive(const UString &fileName, +#ifndef _SFX +static inline bool TestSignature(const Byte *p1, const Byte *p2, UInt32 size) +{ + for (UInt32 i = 0; i < size; i++) + if (p1[i] != p2[i]) + return false; + return true; +} +#endif + +HRESULT OpenArchive( + IInStream *inStream, + const UString &fileName, #ifndef EXCLUDE_COM HMODULE *module, #endif IInArchive **archiveResult, CArchiverInfo &archiverInfoResult, - int &subExtIndex, + UString &defaultItemName, IArchiveOpenCallback *openArchiveCallback) { - CInFileStream *inStreamSpec = new CInFileStream; - CMyComPtr<IInStream> inStream(inStreamSpec); - if (!inStreamSpec->Open(fileName)) - return GetLastError(); - *archiveResult = NULL; CObjectVector<CArchiverInfo> archiverInfoList; ReadArchiverInfoList(archiverInfoList); UString extension; { - UString name, pureName, dot; - if(!NFile::NDirectory::GetOnlyName(fileName, name)) - return E_FAIL; - NFile::NName::SplitNameToPureNameAndExtension(name, pureName, dot, extension); + int dotPos = fileName.ReverseFind(L'.'); + if (dotPos >= 0) + extension = fileName.Mid(dotPos + 1); } CIntVector orderIndices; - int firstArchiverIndex; - for(firstArchiverIndex = 0; - firstArchiverIndex < archiverInfoList.Size(); firstArchiverIndex++) + int i; + bool finded = false; + for(i = 0; i < archiverInfoList.Size(); i++) { - int subIndex = archiverInfoList[firstArchiverIndex].FindExtension(extension); - if (subIndex >= 0) - break; + if (archiverInfoList[i].FindExtension(extension) >= 0) + { + orderIndices.Insert(0, i); + finded = true; + } + else + orderIndices.Add(i); } - if(firstArchiverIndex < archiverInfoList.Size()) - orderIndices.Add(firstArchiverIndex); - for(int j = 0; j < archiverInfoList.Size(); j++) - if(j != firstArchiverIndex) - orderIndices.Add(j); + #ifndef _SFX + if (!finded) + { + CByteBuffer byteBuffer; + const UInt32 kBufferSize = (200 << 10); + byteBuffer.SetCapacity(kBufferSize); + Byte *buffer = byteBuffer; + RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL)); + UInt32 processedSize; + RINOK(inStream->Read(buffer, kBufferSize, &processedSize)); + int numFinded = 0; + for (int pos = (int)processedSize; pos >= 0 ; pos--) + { + for(int i = numFinded; i < orderIndices.Size(); i++) + { + int index = orderIndices[i]; + const CArchiverInfo &ai = archiverInfoList[index]; + const CByteBuffer &sig = ai.StartSignature; + if (sig.GetCapacity() == 0) + continue; + if (pos + sig.GetCapacity() > processedSize) + continue; + if (TestSignature(buffer + pos, sig, sig.GetCapacity())) + { + orderIndices.Delete(i); + orderIndices.Insert(0, index); + numFinded++; + } + } + } + } + #endif + HRESULT badResult = S_OK; - for(int i = 0; i < orderIndices.Size(); i++) + for(i = 0; i < orderIndices.Size(); i++) { - inStreamSpec->Seek(0, STREAM_SEEK_SET, NULL); + inStream->Seek(0, STREAM_SEEK_SET, NULL); const CArchiverInfo &archiverInfo = archiverInfoList[orderIndices[i]]; #ifndef EXCLUDE_COM CHandlerLoader loader; @@ -114,6 +228,11 @@ HRESULT OpenArchive(const UString &fileName, archive = new NArchive::NGZip::CHandler; #endif + #ifdef FORMAT_SPLIT + if (archiverInfo.Name.CompareNoCase(L"Split") == 0) + archive = new NArchive::NSplit::CHandler; + #endif + #ifdef FORMAT_TAR if (archiverInfo.Name.CompareNoCase(L"Tar") == 0) archive = new NArchive::NTar::CHandler; @@ -124,6 +243,11 @@ HRESULT OpenArchive(const UString &fileName, archive = new NArchive::NZip::CHandler; #endif + #ifdef FORMAT_Z + if (archiverInfo.Name.CompareNoCase(L"Z") == 0) + archive = new NArchive::NZ::CHandler; + #endif + #ifndef EXCLUDE_COM if (!archive) @@ -144,28 +268,260 @@ HRESULT OpenArchive(const UString &fileName, if(result != S_OK) { badResult = result; + if(result == E_ABORT) + break; continue; - // return result; } *archiveResult = archive.Detach(); #ifndef EXCLUDE_COM *module = loader.Detach(); #endif archiverInfoResult = archiverInfo; - subExtIndex = archiverInfo.FindExtension(extension); + int subExtIndex = archiverInfo.FindExtension(extension); if (subExtIndex < 0) subExtIndex = 0; + defaultItemName = GetDefaultName2(fileName, + archiverInfo.Extensions[subExtIndex].Extension, + archiverInfo.Extensions[subExtIndex].AddExtension); + return S_OK; } if (badResult != S_OK) return badResult; return S_FALSE; - - /* - #else - return S_FALSE; - #endif - +} + +HRESULT OpenArchive(const UString &filePath, + #ifndef EXCLUDE_COM + HMODULE *module, + #endif + IInArchive **archiveResult, + CArchiverInfo &archiverInfo, + UString &defaultItemName, + IArchiveOpenCallback *openArchiveCallback) +{ + CInFileStream *inStreamSpec = new CInFileStream; + CMyComPtr<IInStream> inStream(inStreamSpec); + if (!inStreamSpec->Open(filePath)) + return GetLastError(); + return OpenArchive(inStream, ExtractFileNameFromPath(filePath), + #ifndef EXCLUDE_COM + module, + #endif + archiveResult, archiverInfo, + defaultItemName, openArchiveCallback); +} + +static void MakeDefaultName(UString &name) +{ + int dotPos = name.ReverseFind(L'.'); + if (dotPos < 0) + return; + UString ext = name.Mid(dotPos + 1); + if (ext.IsEmpty()) + return; + for (int pos = 0; pos < ext.Length(); pos++) + if (ext[pos] < L'0' || ext[pos] > L'9') + return; + name = name.Left(dotPos); +} + +HRESULT OpenArchive(const UString &fileName, + #ifndef EXCLUDE_COM + HMODULE *module0, + HMODULE *module1, + #endif + IInArchive **archive0, + IInArchive **archive1, + CArchiverInfo &archiverInfo0, + CArchiverInfo &archiverInfo1, + UString &defaultItemName0, + UString &defaultItemName1, + IArchiveOpenCallback *openArchiveCallback) +{ + HRESULT result = OpenArchive(fileName, + #ifndef EXCLUDE_COM + module0, + #endif + archive0, archiverInfo0, defaultItemName0, openArchiveCallback); + RINOK(result); + CMyComPtr<IInArchiveGetStream> getStream; + result = (*archive0)->QueryInterface(IID_IInArchiveGetStream, (void **)&getStream); + if (result != S_OK || getStream == 0) + return S_OK; + + CMyComPtr<ISequentialInStream> subSeqStream; + result = getStream->GetStream(0, &subSeqStream); + if (result != S_OK) + return S_OK; + + CMyComPtr<IInStream> subStream; + if (subSeqStream.QueryInterface(IID_IInStream, &subStream) != S_OK) + return S_OK; + if (!subStream) + return S_OK; + + UInt32 numItems; + RINOK((*archive0)->GetNumberOfItems(&numItems)); + if (numItems < 1) + return S_OK; + + UString subPath; + RINOK(GetArchiveItemPath(*archive0, 0, subPath)) + if (subPath.IsEmpty()) + { + MakeDefaultName(defaultItemName0); + subPath = defaultItemName0; + if (archiverInfo0.Name.CompareNoCase(L"7z") == 0) + { + if (subPath.Right(3).CompareNoCase(L".7z") != 0) + subPath += L".7z"; + } + } + else + subPath = ExtractFileNameFromPath(subPath); + + CMyComPtr<IArchiveOpenSetSubArchiveName> setSubArchiveName; + openArchiveCallback->QueryInterface(IID_IArchiveOpenSetSubArchiveName, (void **)&setSubArchiveName); + if (setSubArchiveName) + setSubArchiveName->SetSubArchiveName(subPath); + + result = OpenArchive(subStream, subPath, + #ifndef EXCLUDE_COM + module1, + #endif + archive1, archiverInfo1, defaultItemName1, openArchiveCallback); + return S_OK; +} + +HRESULT MyOpenArchive(const UString &archiveName, + #ifndef EXCLUDE_COM + HMODULE *module, + #endif + IInArchive **archive, + UString &defaultItemName, + IOpenCallbackUI *openCallbackUI) +{ + COpenCallbackImp *openCallbackSpec = new COpenCallbackImp; + CMyComPtr<IArchiveOpenCallback> openCallback = openCallbackSpec; + openCallbackSpec->Callback = openCallbackUI; + + UString fullName; + int fileNamePartStartIndex; + NFile::NDirectory::MyGetFullPathName(archiveName, fullName, fileNamePartStartIndex); + openCallbackSpec->Init( + fullName.Left(fileNamePartStartIndex), + fullName.Mid(fileNamePartStartIndex)); + + CArchiverInfo archiverInfo; + return OpenArchive(archiveName, + #ifndef EXCLUDE_COM + module, + #endif + archive, + archiverInfo, + defaultItemName, + openCallback); +} + +HRESULT MyOpenArchive(const UString &archiveName, + #ifndef EXCLUDE_COM + HMODULE *module0, + HMODULE *module1, + #endif + IInArchive **archive0, + IInArchive **archive1, + UString &defaultItemName0, + UString &defaultItemName1, + UStringVector &volumePaths, + IOpenCallbackUI *openCallbackUI) +{ + COpenCallbackImp *openCallbackSpec = new COpenCallbackImp; + CMyComPtr<IArchiveOpenCallback> openCallback = openCallbackSpec; + openCallbackSpec->Callback = openCallbackUI; + + UString fullName; + int fileNamePartStartIndex; + NFile::NDirectory::MyGetFullPathName(archiveName, fullName, fileNamePartStartIndex); + UString prefix = fullName.Left(fileNamePartStartIndex); + UString name = fullName.Mid(fileNamePartStartIndex); + openCallbackSpec->Init(prefix, name); + + CArchiverInfo archiverInfo0, archiverInfo1; + HRESULT result = OpenArchive(archiveName, + #ifndef EXCLUDE_COM + module0, + module1, + #endif + archive0, + archive1, + archiverInfo0, + archiverInfo1, + defaultItemName0, + defaultItemName1, + openCallback); + RINOK(result); + volumePaths.Add(prefix + name); + for (int i = 0; i < openCallbackSpec->FileNames.Size(); i++) + volumePaths.Add(prefix + openCallbackSpec->FileNames[i]); + return S_OK; +} + +HRESULT CArchiveLink::Close() +{ + if (Archive1 != 0) + RINOK(Archive1->Close()); + if (Archive0 != 0) + RINOK(Archive0->Close()); + return S_OK; +} + +void CArchiveLink::Release() +{ + if (Archive1 != 0) + Archive1.Release(); + if (Archive0 != 0) + Archive0.Release(); + #ifndef EXCLUDE_COM + Library1.Free(); + Library0.Free(); #endif - */ +} + +HRESULT OpenArchive(const UString &archiveName, + CArchiveLink &archiveLink, + IArchiveOpenCallback *openCallback) +{ + return OpenArchive(archiveName, + #ifndef EXCLUDE_COM + &archiveLink.Library0, &archiveLink.Library1, + #endif + &archiveLink.Archive0, &archiveLink.Archive1, + archiveLink.ArchiverInfo0, archiveLink.ArchiverInfo1, + archiveLink.DefaultItemName0, archiveLink.DefaultItemName1, + openCallback); +} + +HRESULT MyOpenArchive(const UString &archiveName, + CArchiveLink &archiveLink, + IOpenCallbackUI *openCallbackUI) +{ + return MyOpenArchive(archiveName, + #ifndef EXCLUDE_COM + &archiveLink.Library0, &archiveLink.Library1, + #endif + &archiveLink.Archive0, &archiveLink.Archive1, + archiveLink.DefaultItemName0, archiveLink.DefaultItemName1, + archiveLink.VolumePaths, + openCallbackUI); +} + +HRESULT ReOpenArchive(CArchiveLink &archiveLink, + const UString &fileName) +{ + if (archiveLink.GetNumLevels() > 1) + return E_NOTIMPL; + if (archiveLink.GetNumLevels() == 0) + return MyOpenArchive(fileName, archiveLink, 0); + return ReOpenArchive(archiveLink.GetArchive(), fileName); } diff --git a/7zip/UI/Common/OpenArchive.h b/7zip/UI/Common/OpenArchive.h index 7c4128dc..5de18a71 100755 --- a/7zip/UI/Common/OpenArchive.h +++ b/7zip/UI/Common/OpenArchive.h @@ -4,21 +4,130 @@ #define __OPENARCHIVE_H #include "Common/String.h" +#include "Windows/FileFind.h" #include "../../Archive/IArchive.h" #include "ArchiverInfo.h" +#include "ArchiveOpenCallback.h" -HRESULT OpenArchive(const UString &fileName, +#ifndef EXCLUDE_COM +#include "Windows/DLL.h" +#endif + +HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, const UString &defaultName, UString &result); +HRESULT GetArchiveItemFileTime(IInArchive *archive, UInt32 index, + const FILETIME &defaultFileTime, FILETIME &fileTime); +HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result); +HRESULT IsArchiveItemAnti(IInArchive *archive, UInt32 index, bool &result); + +struct ISetSubArchiveName +{ + virtual void SetSubArchiveName(const wchar_t *name) = 0; +}; + +HRESULT OpenArchive( + IInStream *inStream, + const UString &fileName, #ifndef EXCLUDE_COM HMODULE *module, #endif - IInArchive **archive, + IInArchive **archiveResult, CArchiverInfo &archiverInfoResult, - int &subExtIndex, + UString &defaultItemName, + IArchiveOpenCallback *openArchiveCallback); + +HRESULT OpenArchive(const UString &filePath, + #ifndef EXCLUDE_COM + HMODULE *module, + #endif + IInArchive **archive, + CArchiverInfo &archiverInfo, + UString &defaultItemName, + IArchiveOpenCallback *openArchiveCallback); + +HRESULT OpenArchive(const UString &filePath, + #ifndef EXCLUDE_COM + HMODULE *module0, + HMODULE *module1, + #endif + IInArchive **archive0, + IInArchive **archive1, + CArchiverInfo &archiverInfo0, + CArchiverInfo &archiverInfo1, + UString &defaultItemName0, + UString &defaultItemName1, IArchiveOpenCallback *openArchiveCallback); + HRESULT ReOpenArchive(IInArchive *archive, const UString &fileName); +HRESULT MyOpenArchive(const UString &archiveName, + #ifndef EXCLUDE_COM + HMODULE *module, + #endif + IInArchive **archive, + UString &defaultItemName, + IOpenCallbackUI *openCallbackUI); + +HRESULT MyOpenArchive(const UString &archiveName, + #ifndef EXCLUDE_COM + HMODULE *module0, + HMODULE *module1, + #endif + IInArchive **archive0, + IInArchive **archive1, + UString &defaultItemName0, + UString &defaultItemName1, + UStringVector &volumePaths, + IOpenCallbackUI *openCallbackUI); + +struct CArchiveLink +{ + #ifndef EXCLUDE_COM + NWindows::NDLL::CLibrary Library0; + NWindows::NDLL::CLibrary Library1; + #endif + CMyComPtr<IInArchive> Archive0; + CMyComPtr<IInArchive> Archive1; + UString DefaultItemName0; + UString DefaultItemName1; + + CArchiverInfo ArchiverInfo0; + CArchiverInfo ArchiverInfo1; + + UStringVector VolumePaths; + + int GetNumLevels() const + { + int result = 0; + if (Archive0) + { + result++; + if (Archive1) + result++; + } + return result; + } + + + IInArchive *GetArchive() { return Archive1 != 0 ? Archive1: Archive0; } + UString GetDefaultItemName() { return Archive1 != 0 ? DefaultItemName1: DefaultItemName0; } + const CArchiverInfo &GetArchiverInfo() { return Archive1 != 0 ? ArchiverInfo1: ArchiverInfo0; } + HRESULT Close(); + void Release(); +}; + +HRESULT OpenArchive(const UString &archiveName, + CArchiveLink &archiveLink, + IArchiveOpenCallback *openCallback); + +HRESULT MyOpenArchive(const UString &archiveName, + CArchiveLink &archiveLink, + IOpenCallbackUI *openCallbackUI); + +HRESULT ReOpenArchive(CArchiveLink &archiveLink, + const UString &fileName); #endif + diff --git a/7zip/UI/Common/PropIDUtils.cpp b/7zip/UI/Common/PropIDUtils.cpp index bd836fff..8869e565 100755 --- a/7zip/UI/Common/PropIDUtils.cpp +++ b/7zip/UI/Common/PropIDUtils.cpp @@ -14,13 +14,24 @@ using namespace NWindows; -static UString ConvertUINT32ToString(UINT32 value) +static UString ConvertUInt32ToString(UInt32 value) { wchar_t buffer[32]; - ConvertUINT64ToString(value, buffer); + ConvertUInt64ToString(value, buffer); return buffer; } +static void ConvertUInt32ToHex(UInt32 value, wchar_t *s) +{ + for (int i = 0; i < 8; i++) + { + int t = value & 0xF; + value >>= 4; + s[7 - i] = (wchar_t)((t < 10) ? (L'0' + t) : (L'A' + (t - 10))); + } + s[8] = L'\0'; +} + UString ConvertPropertyToString(const PROPVARIANT &propVariant, PROPID propID, bool full) { @@ -38,22 +49,22 @@ UString ConvertPropertyToString(const PROPVARIANT &propVariant, return UString(); if (!::FileTimeToLocalFileTime(&propVariant.filetime, &localFileTime)) return UString(); // It is error; - return ConvertFileTimeToString2(localFileTime, true, full); + return ConvertFileTimeToString(localFileTime, true, full); } case kpidCRC: { if(propVariant.vt != VT_UI4) break; - TCHAR temp[17]; - wsprintf(temp, TEXT("%08X"), propVariant.ulVal); - return GetUnicodeString(temp); + wchar_t temp[12]; + ConvertUInt32ToHex(propVariant.ulVal, temp); + return temp; } case kpidAttributes: { if(propVariant.vt != VT_UI4) break; UString result; - UINT32 attributes = propVariant.ulVal; + UInt32 attributes = propVariant.ulVal; if (NFile::NFind::NAttributes::IsReadOnly(attributes)) result += L'R'; if (NFile::NFind::NAttributes::IsHidden(attributes)) result += L'H'; if (NFile::NFind::NAttributes::IsSystem(attributes)) result += L'S'; @@ -67,12 +78,12 @@ UString ConvertPropertyToString(const PROPVARIANT &propVariant, { if(propVariant.vt != VT_UI4) break; - UINT32 size = propVariant.ulVal; + UInt32 size = propVariant.ulVal; if (size % (1 << 20) == 0) - return ConvertUINT32ToString(size >> 20) + L"MB"; + return ConvertUInt32ToString(size >> 20) + L"MB"; if (size % (1 << 10) == 0) - return ConvertUINT32ToString(size >> 10) + L"KB"; - return ConvertUINT32ToString(size); + return ConvertUInt32ToString(size >> 10) + L"KB"; + return ConvertUInt32ToString(size); } } return ConvertPropVariantToString(propVariant); diff --git a/7zip/UI/Common/PropIDUtils.h b/7zip/UI/Common/PropIDUtils.h index 82ee249a..aa540885 100755 --- a/7zip/UI/Common/PropIDUtils.h +++ b/7zip/UI/Common/PropIDUtils.h @@ -1,7 +1,5 @@ // PropIDUtils.h -#pragma once - #ifndef __PROPIDUTILS_H #define __PROPIDUTILS_H diff --git a/7zip/UI/Common/SortUtils.cpp b/7zip/UI/Common/SortUtils.cpp index 881aec0b..b6ed8d52 100755 --- a/7zip/UI/Common/SortUtils.cpp +++ b/7zip/UI/Common/SortUtils.cpp @@ -11,7 +11,7 @@ static int __cdecl CompareStrings(const void *a1, const void *a2) return s1.CompareNoCase(s2); } -void SortStringsToIndices(UStringVector &strings, CIntVector &indices) +void SortStringsToIndices(const UStringVector &strings, CIntVector &indices) { indices.Clear(); if (strings.IsEmpty()) @@ -22,9 +22,19 @@ void SortStringsToIndices(UStringVector &strings, CIntVector &indices) indices.Reserve(numItems); int i; for(i = 0; i < numItems; i++) - pointers.Add(&strings.CPointerVector::operator[](i)); + pointers.Add((void *)&strings.CPointerVector::operator[](i)); void **stringsBase = (void **)pointers[0]; qsort(&pointers[0], numItems, sizeof(void *), CompareStrings); for(i = 0; i < numItems; i++) indices.Add((void **)pointers[i] - stringsBase); } + +void SortStrings(const UStringVector &src, UStringVector &dest) +{ + CIntVector indices; + SortStringsToIndices(src, indices); + dest.Clear(); + dest.Reserve(indices.Size()); + for (int i = 0; i < indices.Size(); i++) + dest.Add(src[indices[i]]); +} diff --git a/7zip/UI/Common/SortUtils.h b/7zip/UI/Common/SortUtils.h index 36eda0b9..5b9af264 100755 --- a/7zip/UI/Common/SortUtils.h +++ b/7zip/UI/Common/SortUtils.h @@ -1,12 +1,11 @@ // SortUtils.h -#pragma once - #ifndef __SORTUTLS_H #define __SORTUTLS_H #include "Common/String.h" -void SortStringsToIndices(UStringVector &strings, CIntVector &indices); +void SortStringsToIndices(const UStringVector &strings, CIntVector &indices); +void SortStrings(const UStringVector &src, UStringVector &dest); #endif diff --git a/7zip/UI/Common/TempFiles.cpp b/7zip/UI/Common/TempFiles.cpp new file mode 100755 index 00000000..3e604aea --- /dev/null +++ b/7zip/UI/Common/TempFiles.cpp @@ -0,0 +1,22 @@ +// TempFiles.cpp + +#include "StdAfx.h" + +#include "TempFiles.h" + +#include "Windows/FileDir.h" +#include "Windows/FileIO.h" + +using namespace NWindows; +using namespace NFile; + +void CTempFiles::Clear() +{ + while(!Paths.IsEmpty()) + { + NDirectory::DeleteFileAlways(Paths.Back()); + Paths.DeleteBack(); + } +} + + diff --git a/7zip/UI/Common/TempFiles.h b/7zip/UI/Common/TempFiles.h new file mode 100755 index 00000000..173713a0 --- /dev/null +++ b/7zip/UI/Common/TempFiles.h @@ -0,0 +1,16 @@ +// TempFiles.h + +#ifndef __TEMPFILES_H +#define __TEMPFILES_H + +#include "Common/String.h" + +class CTempFiles +{ + void Clear(); +public: + UStringVector Paths; + ~CTempFiles() { Clear(); } +}; + +#endif diff --git a/7zip/UI/Common/Update.cpp b/7zip/UI/Common/Update.cpp new file mode 100755 index 00000000..eea03aa5 --- /dev/null +++ b/7zip/UI/Common/Update.cpp @@ -0,0 +1,850 @@ +// Update.cpp + +#include "StdAfx.h" + +#ifdef _WIN32 +#include <mapi.h> +#endif + +#include "Update.h" + +#include "Common/IntToString.h" +#include "Common/StringToInt.h" +#include "Common/StringConvert.h" +#include "Common/CommandLineParser.h" + +#ifdef _WIN32 +#include "Windows/DLL.h" +#endif + +#include "Windows/Defs.h" +#include "Windows/FileDir.h" +#include "Windows/FileFind.h" +#include "Windows/FileName.h" +#include "Windows/PropVariant.h" +#include "Windows/PropVariantConversions.h" +// #include "Windows/Synchronization.h" + +#include "../../Common/FileStreams.h" +#include "../../Compress/Copy/CopyCoder.h" + +#include "../Common/DirItem.h" +#include "../Common/EnumDirItems.h" +#include "../Common/UpdateProduce.h" +#include "../Common/OpenArchive.h" + +#include "TempFiles.h" +#include "UpdateCallback.h" +#include "EnumDirItems.h" + +#ifdef FORMAT_7Z +#include "../../Archive/7z/7zHandler.h" +#endif + +#ifdef FORMAT_BZIP2 +#include "../../Archive/BZip2/BZip2Handler.h" +#endif + +#ifdef FORMAT_GZIP +#include "../../Archive/GZip/GZipHandler.h" +#endif + +#ifdef FORMAT_TAR +#include "../../Archive/Tar/TarHandler.h" +#endif + +#ifdef FORMAT_ZIP +#include "../../Archive/Zip/ZipHandler.h" +#endif + +#ifndef EXCLUDE_COM +#include "../Common/HandlerLoader.h" +#endif + +static const char *kUpdateIsNotSupoorted = + "update operations are not supported for this archive"; + +using namespace NCommandLineParser; +using namespace NWindows; +using namespace NCOM; +using namespace NFile; +using namespace NName; + +static const wchar_t *kTempArchiveFilePrefixString = L"7zi"; +static const wchar_t *kTempFolderPrefix = L"7zE"; + +static const char *kIllegalFileNameMessage = "Illegal file name for temp archive"; + +using namespace NUpdateArchive; + +static void ParseNumberString(const UString &s, NCOM::CPropVariant &prop) +{ + const wchar_t *endPtr; + UInt64 result = ConvertStringToUInt64(s, &endPtr); + if (endPtr - (const wchar_t *)s != s.Length()) + prop = s; + else if (result <= 0xFFFFFFFF) + prop = (UInt32)result; + else + prop = result; +} + +static HRESULT CopyBlock(ISequentialInStream *inStream, ISequentialOutStream *outStream) +{ + CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder; + return copyCoder->Code(inStream, outStream, NULL, NULL, NULL); +} + +class COutMultiVolStream: + public IOutStream, + public CMyUnknownImp +{ + size_t _streamIndex; // required stream + UInt64 _offsetPos; // offset from start of _streamIndex index + UInt64 _absPos; + UInt64 _length; + + struct CSubStreamInfo + { + CMyComPtr<IOutStream> Stream; + UString Name; + UInt64 Pos; + UInt64 RealSize; + }; + CObjectVector<CSubStreamInfo> Streams; +public: + // CMyComPtr<IArchiveUpdateCallback2> VolumeCallback; + CRecordVector<UInt64> Sizes; + UString Prefix; + CTempFiles *TempFiles; + + void Init() + { + _streamIndex = 0; + _offsetPos = 0; + _absPos = 0; + _length = 0; + } + + MY_UNKNOWN_IMP1(IOutStream) + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); + STDMETHOD(SetSize)(Int64 newSize); +}; + +// static NSynchronization::CCriticalSection g_TempPathsCS; + +STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + if(processedSize != NULL) + *processedSize = 0; + while(size > 0) + { + if (_streamIndex >= (size_t)Streams.Size()) + { + CSubStreamInfo subStream; + + wchar_t temp[32]; + ConvertUInt64ToString(_streamIndex + 1, temp); + UString res = temp; + while (res.Length() < 3) + res = UString(L'0') + res; + UString name = Prefix + res; + COutFileStream *streamSpec = new COutFileStream; + subStream.Stream = streamSpec; + if(!streamSpec->Create(name, false)) + return ::GetLastError(); + { + // NSynchronization::CCriticalSectionLock lock(g_TempPathsCS); + TempFiles->Paths.Add(name); + } + + subStream.Pos = 0; + subStream.RealSize = 0; + subStream.Name = name; + Streams.Add(subStream); + continue; + } + CSubStreamInfo &subStream = Streams[_streamIndex]; + + int index = _streamIndex; + if (index >= Sizes.Size()) + index = Sizes.Size() - 1; + UInt64 volSize = Sizes[index]; + + if (_offsetPos >= volSize) + { + _offsetPos -= volSize; + _streamIndex++; + continue; + } + if (_offsetPos != subStream.Pos) + { + // CMyComPtr<IOutStream> outStream; + // RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream)); + RINOK(subStream.Stream->Seek(_offsetPos, STREAM_SEEK_SET, NULL)); + subStream.Pos = _offsetPos; + } + + UInt32 curSize = (UInt32)MyMin((UInt64)size, volSize - subStream.Pos); + UInt32 realProcessed; + RINOK(subStream.Stream->Write(data, curSize, &realProcessed)); + data = (void *)((Byte *)data + realProcessed); + size -= realProcessed; + subStream.Pos += realProcessed; + _offsetPos += realProcessed; + _absPos += realProcessed; + if (_absPos > _length) + _length = _absPos; + if (_offsetPos > subStream.RealSize) + subStream.RealSize = _offsetPos; + if(processedSize != NULL) + *processedSize += realProcessed; + if (subStream.Pos == volSize) + { + _streamIndex++; + _offsetPos = 0; + } + if (realProcessed != curSize) + return E_FAIL; + } + return S_OK; +} + +STDMETHODIMP COutMultiVolStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize) +{ + return Write(data, size, processedSize); +} + +STDMETHODIMP COutMultiVolStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +{ + if(seekOrigin >= 3) + return STG_E_INVALIDFUNCTION; + switch(seekOrigin) + { + case STREAM_SEEK_SET: + _absPos = offset; + break; + case STREAM_SEEK_CUR: + _absPos += offset; + break; + case STREAM_SEEK_END: + _absPos = _length + offset; + break; + } + _offsetPos = _absPos; + if (newPosition != NULL) + *newPosition = _absPos; + _streamIndex = 0; + return S_OK; +} + +STDMETHODIMP COutMultiVolStream::SetSize(Int64 newSize) +{ + if (newSize < 0) + return E_INVALIDARG; + int i = 0; + while (i < Streams.Size()) + { + CSubStreamInfo &subStream = Streams[i++]; + if ((UInt64)newSize < subStream.RealSize) + { + RINOK(subStream.Stream->SetSize(newSize)); + subStream.RealSize = newSize; + break; + } + newSize -= subStream.RealSize; + } + while (i < Streams.Size()) + { + { + CSubStreamInfo &subStream = Streams.Back(); + subStream.Stream.Release(); + NDirectory::DeleteFileAlways(subStream.Name); + } + Streams.DeleteBack(); + } + _offsetPos = _absPos; + _streamIndex = 0; + _length = newSize; + return S_OK; +} + + +static HRESULT Compress( + const CActionSet &actionSet, + IInArchive *archive, + const CCompressionMethodMode &compressionMethod, + CArchivePath &archivePath, + const CObjectVector<CArchiveItem> &archiveItems, + bool stdInMode, + const UString &stdInFileName, + bool stdOutMode, + const CObjectVector<CDirItem> &dirItems, + bool sfxMode, + const UString &sfxModule, + const CRecordVector<UInt64> &volumesSizes, + CTempFiles &tempFiles, + CUpdateErrorInfo &errorInfo, + IUpdateCallbackUI *callback) +{ + #ifndef EXCLUDE_COM + CHandlerLoader loader; + #endif + + CMyComPtr<IOutArchive> outArchive; + if(archive != NULL) + { + CMyComPtr<IInArchive> archive2 = archive; + HRESULT result = archive2.QueryInterface(IID_IOutArchive, &outArchive); + if(result != S_OK) + throw kUpdateIsNotSupoorted; + } + else + { + #ifndef EXCLUDE_COM + + if (loader.CreateHandler(compressionMethod.FilePath, + compressionMethod.ClassID, (void **)&outArchive, true) != S_OK) + throw kUpdateIsNotSupoorted; + #endif + + #ifdef FORMAT_7Z + if (compressionMethod.Name.CompareNoCase(L"7z") == 0) + outArchive = new NArchive::N7z::CHandler; + #endif + + #ifdef FORMAT_BZIP2 + if (compressionMethod.Name.CompareNoCase(L"BZip2") == 0) + outArchive = new NArchive::NBZip2::CHandler; + #endif + + #ifdef FORMAT_GZIP + if (compressionMethod.Name.CompareNoCase(L"GZip") == 0) + outArchive = new NArchive::NGZip::CHandler; + #endif + + #ifdef FORMAT_TAR + if (compressionMethod.Name.CompareNoCase(L"Tar") == 0) + outArchive = new NArchive::NTar::CHandler; + #endif + + #ifdef FORMAT_ZIP + if (compressionMethod.Name.CompareNoCase(L"Zip") == 0) + outArchive = new NArchive::NZip::CHandler; + #endif + + } + if (outArchive == 0) + throw kUpdateIsNotSupoorted; + + NFileTimeType::EEnum fileTimeType; + UInt32 value; + RINOK(outArchive->GetFileTimeType(&value)); + + switch(value) + { + case NFileTimeType::kWindows: + case NFileTimeType::kDOS: + case NFileTimeType::kUnix: + fileTimeType = NFileTimeType::EEnum(value); + break; + default: + return E_FAIL; + } + + CObjectVector<CUpdatePair> updatePairs; + GetUpdatePairInfoList(dirItems, archiveItems, fileTimeType, updatePairs); // must be done only once!!! + + CObjectVector<CUpdatePair2> updatePairs2; + UpdateProduce(dirItems, archiveItems, updatePairs, actionSet, updatePairs2); + + CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; + CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec ); + + updateCallbackSpec->StdInMode = stdInMode; + updateCallbackSpec->Callback = callback; + updateCallbackSpec->DirItems = &dirItems; + updateCallbackSpec->ArchiveItems = &archiveItems; + updateCallbackSpec->UpdatePairs = &updatePairs2; + + CMyComPtr<ISequentialOutStream> outStream; + + const UString &archiveName = archivePath.GetFinalPath(); + if (!stdOutMode) + { + UString resultPath; + int pos; + if(!NFile::NDirectory::MyGetFullPathName(archiveName, resultPath, pos)) + throw 1417161; + NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos)); + } + if (volumesSizes.Size() == 0) + { + if (stdOutMode) + outStream = new CStdOutFileStream; + else + { + COutFileStream *outStreamSpec = new COutFileStream; + outStream = outStreamSpec; + bool isOK = false; + UString realPath; + for (int i = 0; i < (1 << 16); i++) + { + if (archivePath.Temp) + { + if (i > 0) + { + wchar_t s[32]; + ConvertUInt64ToString(i, s); + archivePath.TempPostfix = s; + } + realPath = archivePath.GetTempPath(); + } + else + realPath = archivePath.GetFinalPath(); + if (outStreamSpec->Create(realPath, false)) + { + tempFiles.Paths.Add(realPath); + isOK = true; + break; + } + if (::GetLastError() != ERROR_FILE_EXISTS) + break; + if (!archivePath.Temp) + break; + } + if (!isOK) + { + errorInfo.SystemError = ::GetLastError(); + errorInfo.FileName = realPath; + errorInfo.Message = L"Can not open file"; + return E_FAIL; + } + } + } + else + { + if (stdOutMode) + return E_FAIL; + COutMultiVolStream *volStreamSpec = new COutMultiVolStream; + outStream = volStreamSpec; + volStreamSpec->Sizes = volumesSizes; + volStreamSpec->Prefix = archivePath.GetFinalPath() + UString(L"."); + volStreamSpec->TempFiles = &tempFiles; + volStreamSpec->Init(); + + /* + updateCallbackSpec->VolumesSizes = volumesSizes; + updateCallbackSpec->VolName = archivePath.Prefix + archivePath.Name; + if (!archivePath.VolExtension.IsEmpty()) + updateCallbackSpec->VolExt = UString(L'.') + archivePath.VolExtension; + */ + } + + CMyComPtr<ISetProperties> setProperties; + if (outArchive.QueryInterface(IID_ISetProperties, &setProperties) == S_OK) + { + UStringVector realNames; + CPropVariant *values = new CPropVariant[compressionMethod.Properties.Size()]; + try + { + int i; + for(i = 0; i < compressionMethod.Properties.Size(); i++) + { + const CProperty &property = compressionMethod.Properties[i]; + NCOM::CPropVariant propVariant; + if (!property.Value.IsEmpty()) + ParseNumberString(property.Value, propVariant); + realNames.Add(property.Name); + values[i] = propVariant; + } + CRecordVector<const wchar_t *> names; + for(i = 0; i < realNames.Size(); i++) + names.Add((const wchar_t *)realNames[i]); + + RINOK(setProperties->SetProperties(&names.Front(), values, names.Size())); + } + catch(...) + { + delete []values; + throw; + } + delete []values; + } + + if (sfxMode) + { + CInFileStream *sfxStreamSpec = new CInFileStream; + CMyComPtr<IInStream> sfxStream(sfxStreamSpec); + if (!sfxStreamSpec->Open(sfxModule)) + { + errorInfo.SystemError = ::GetLastError(); + errorInfo.Message = L"Can't open sfx module"; + errorInfo.FileName = sfxModule; + return E_FAIL; + } + + CMyComPtr<ISequentialOutStream> sfxOutStream; + if (volumesSizes.Size() == 0) + sfxOutStream = outStream; + else + { + COutFileStream *outStreamSpec = new COutFileStream; + sfxOutStream = outStreamSpec; + UString realPath = archivePath.GetFinalPath(); + if (!outStreamSpec->Create(realPath, false)) + { + errorInfo.SystemError = ::GetLastError(); + errorInfo.FileName = realPath; + errorInfo.Message = L"Can not open file"; + return E_FAIL; + } + } + RINOK(CopyBlock(sfxStream, sfxOutStream)); + } + + HRESULT result = outArchive->UpdateItems(outStream, updatePairs2.Size(), + updateCallback); + callback->Finilize(); + return result; +} + + + +HRESULT EnumerateInArchiveItems(const NWildcard::CCensor &censor, + IInArchive *archive, + const UString &defaultItemName, + const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo, + CObjectVector<CArchiveItem> &archiveItems) +{ + archiveItems.Clear(); + UInt32 numItems; + RINOK(archive->GetNumberOfItems(&numItems)); + archiveItems.Reserve(numItems); + for(UInt32 i = 0; i < numItems; i++) + { + CArchiveItem ai; + + RINOK(GetArchiveItemPath(archive, i, defaultItemName, ai.Name)); + RINOK(IsArchiveItemFolder(archive, i, ai.IsDirectory)); + ai.Censored = censor.CheckPath(ai.Name, !ai.IsDirectory); + RINOK(GetArchiveItemFileTime(archive, i, + archiveFileInfo.LastWriteTime, ai.LastWriteTime)); + + CPropVariant propertySize; + RINOK(archive->GetProperty(i, kpidSize, &propertySize)); + if (ai.SizeIsDefined = (propertySize.vt != VT_EMPTY)) + ai.Size = ConvertPropVariantToUInt64(propertySize); + + ai.IndexInServer = i; + archiveItems.Add(ai); + } + return S_OK; +} + + +static HRESULT UpdateWithItemLists( + CUpdateOptions &options, + IInArchive *archive, + const CObjectVector<CArchiveItem> &archiveItems, + const CObjectVector<CDirItem> &dirItems, + CTempFiles &tempFiles, + CUpdateErrorInfo &errorInfo, + IUpdateCallbackUI2 *callback) +{ + for(int i = 0; i < options.Commands.Size(); i++) + { + CUpdateArchiveCommand &command = options.Commands[i]; + if (options.StdOutMode) + { + RINOK(callback->StartArchive(0, archive != 0)); + } + else + { + RINOK(callback->StartArchive(command.ArchivePath.GetFinalPath(), + i == 0 && options.UpdateArchiveItself && archive != 0)); + } + + RINOK(Compress(command.ActionSet, archive, + options.MethodMode, + command.ArchivePath, + archiveItems, + options.StdInMode, options.StdInFileName, + options.StdOutMode, + dirItems, + options.SfxMode, options.SfxModule, + options.VolumesSizes, + tempFiles, + errorInfo, callback)); + + RINOK(callback->FinishArchive()); + } + return S_OK; +} + +#ifdef _WIN32 +class CCurrentDirRestorer +{ + CSysString m_CurrentDirectory; +public: + CCurrentDirRestorer() + { NFile::NDirectory::MyGetCurrentDirectory(m_CurrentDirectory); } + ~CCurrentDirRestorer() + { RestoreDirectory();} + bool RestoreDirectory() + { return BOOLToBool(::SetCurrentDirectory(m_CurrentDirectory)); } +}; +#endif + +struct CEnumDirItemUpdateCallback: public IEnumDirItemCallback +{ + IUpdateCallbackUI2 *Callback; + HRESULT CheckBreak() { return Callback->CheckBreak(); } +}; + +HRESULT UpdateArchive(const NWildcard::CCensor &censor, + CUpdateOptions &options, + CUpdateErrorInfo &errorInfo, + IOpenCallbackUI *openCallback, + IUpdateCallbackUI2 *callback) +{ + if (options.StdOutMode && options.EMailMode) + return E_FAIL; + + if (options.VolumesSizes.Size() > 0 && (options.EMailMode || options.SfxMode)) + return E_NOTIMPL; + + if (options.SfxMode) + { + CProperty property; + property.Name = L"rsfx"; + property.Value = L"on"; + options.MethodMode.Properties.Add(property); + if (options.SfxModule.IsEmpty()) + { + errorInfo.Message = L"sfx file is not specified"; + return E_FAIL; + } + UString name = options.SfxModule; + if (!NDirectory::MySearchPath(NULL, name, NULL, options.SfxModule)) + { + errorInfo.Message = L"can't find specified sfx module"; + return E_FAIL; + } + } + + const UString archiveName = options.ArchivePath.GetFinalPath(); + + UString defaultItemName; + NFind::CFileInfoW archiveFileInfo; + + CArchiveLink archiveLink; + IInArchive *archive = 0; + if (NFind::FindFile(archiveName, archiveFileInfo)) + { + if (archiveFileInfo.IsDirectory()) + throw "there is no such archive"; + if (options.VolumesSizes.Size() > 0) + return E_NOTIMPL; + HRESULT result = MyOpenArchive(archiveName, archiveLink, openCallback); + RINOK(callback->OpenResult(archiveName, result)); + RINOK(result); + if (archiveLink.VolumePaths.Size() > 1) + { + errorInfo.SystemError = E_NOTIMPL; + errorInfo.Message = L"Updating for multivolume archives is not implemented"; + return E_NOTIMPL; + } + archive = archiveLink.GetArchive(); + defaultItemName = archiveLink.GetDefaultItemName(); + } + else + { + /* + if (archiveType.IsEmpty()) + throw "type of archive is not specified"; + */ + } + + CObjectVector<CDirItem> dirItems; + if (options.StdInMode) + { + CDirItem item; + item.FullPath = item.Name = options.StdInFileName; + item.Size = (UInt64)(Int64)-1; + item.Attributes = 0; + SYSTEMTIME st; + FILETIME ft; + GetSystemTime(&st); + SystemTimeToFileTime(&st, &ft); + item.CreationTime = item.LastAccessTime = item.LastWriteTime = ft; + dirItems.Add(item); + } + else + { + bool needScanning = false; + for(int i = 0; i < options.Commands.Size(); i++) + if (options.Commands[i].ActionSet.NeedScanning()) + needScanning = true; + if (needScanning) + { + CEnumDirItemUpdateCallback enumCallback; + enumCallback.Callback = callback; + RINOK(callback->StartScanning()); + RINOK(EnumerateItems(censor, dirItems, &enumCallback)); + RINOK(callback->FinishScanning()); + } + } + + UString tempDirPrefix; + bool usesTempDir = false; + + #ifdef _WIN32 + NDirectory::CTempDirectoryW tempDirectory; + if (options.EMailMode && options.EMailRemoveAfter) + { + tempDirectory.Create(kTempFolderPrefix); + tempDirPrefix = tempDirectory.GetPath(); + NormalizeDirPathPrefix(tempDirPrefix); + usesTempDir = true; + } + #endif + + CTempFiles tempFiles; + + bool createTempFile = false; + if(!options.StdOutMode && options.UpdateArchiveItself) + { + CArchivePath &ap = options.Commands[0].ArchivePath; + ap = options.ArchivePath; + // if ((archive != 0 && !usesTempDir) || !options.WorkingDir.IsEmpty()) + if ((archive != 0 || !options.WorkingDir.IsEmpty()) && !usesTempDir && options.VolumesSizes.Size() == 0) + { + createTempFile = true; + ap.Temp = true; + if (!options.WorkingDir.IsEmpty()) + { + ap.TempPrefix = options.WorkingDir; + NormalizeDirPathPrefix(ap.TempPrefix); + } + } + } + + for(int i = 0; i < options.Commands.Size(); i++) + { + CArchivePath &ap = options.Commands[i].ArchivePath; + if (usesTempDir) + { + // Check it + ap.Prefix = tempDirPrefix; + // ap.Temp = true; + // ap.TempPrefix = tempDirPrefix; + } + if (i > 0 || !createTempFile) + { + const UString &path = ap.GetFinalPath(); + if (NFind::DoesFileExist(path)) + { + errorInfo.SystemError = 0; + errorInfo.Message = L"File already exists"; + errorInfo.FileName = path; + return E_FAIL; + } + } + } + + CObjectVector<CArchiveItem> archiveItems; + if (archive != NULL) + { + RINOK(EnumerateInArchiveItems(censor, + archive, defaultItemName, archiveFileInfo, archiveItems)); + } + + RINOK(UpdateWithItemLists(options, archive, archiveItems, dirItems, + tempFiles, errorInfo, callback)); + + if (archive != NULL) + { + RINOK(archiveLink.Close()); + archiveLink.Release(); + } + + tempFiles.Paths.Clear(); + if(createTempFile) + { + try + { + CArchivePath &ap = options.Commands[0].ArchivePath; + const UString &tempPath = ap.GetTempPath(); + if (archive != NULL) + if (!NDirectory::DeleteFileAlways(archiveName)) + { + errorInfo.SystemError = ::GetLastError(); + errorInfo.Message = L"delete file error"; + errorInfo.FileName = archiveName; + return E_FAIL; + } + if (!NDirectory::MyMoveFile(tempPath, archiveName)) + { + errorInfo.SystemError = ::GetLastError(); + errorInfo.Message = L"move file error"; + errorInfo.FileName = tempPath; + errorInfo.FileName2 = archiveName; + return E_FAIL; + } + } + catch(...) + { + throw; + } + } + + #ifdef _WIN32 + if (options.EMailMode) + { + NDLL::CLibrary mapiLib; + if (!mapiLib.Load(TEXT("Mapi32.dll"))) + { + errorInfo.SystemError = ::GetLastError(); + errorInfo.Message = L"can not load Mapi32.dll"; + return E_FAIL; + } + LPMAPISENDDOCUMENTS fnSend = (LPMAPISENDDOCUMENTS) + mapiLib.GetProcAddress("MAPISendDocuments"); + if (fnSend == 0) + { + errorInfo.SystemError = ::GetLastError(); + errorInfo.Message = L"can not find MAPISendDocuments function"; + return E_FAIL; + } + UStringVector fullPaths; + int i; + for(i = 0; i < options.Commands.Size(); i++) + { + CArchivePath &ap = options.Commands[i].ArchivePath; + UString arcPath; + if(!NFile::NDirectory::MyGetFullPathName(ap.GetFinalPath(), arcPath)) + { + errorInfo.SystemError = ::GetLastError(); + return E_FAIL; + } + fullPaths.Add(arcPath); + } + CCurrentDirRestorer curDirRestorer; + for(i = 0; i < fullPaths.Size(); i++) + { + UString arcPath = fullPaths[i]; + UString fileName = ExtractFileNameFromPath(arcPath); + AString path = GetAnsiString(arcPath); + AString name = GetAnsiString(fileName); + // Warning!!! MAPISendDocuments function changes Current directory + fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0); + } + } + #endif + return S_OK; +} + diff --git a/7zip/UI/Common/Update.h b/7zip/UI/Common/Update.h new file mode 100755 index 00000000..680a461b --- /dev/null +++ b/7zip/UI/Common/Update.h @@ -0,0 +1,157 @@ +// Update.h + +#ifndef __UPDATE_H +#define __UPDATE_H + +#include "Common/Wildcard.h" +#include "Windows/FileFind.h" +#include "../../Archive/IArchive.h" + +#include "UpdateAction.h" +#include "ArchiveOpenCallback.h" +#include "UpdateCallback.h" + +struct CArchivePath +{ + UString Prefix; // path(folder) prefix including slash + UString Name; // base name + UString BaseExtension; // archive type extension or "exe" extension + UString VolExtension; // archive type extension for volumes + + bool Temp; + UString TempPrefix; // path(folder) for temp location + UString TempPostfix; + + CArchivePath(): Temp(false) {}; + + void ParseFromPath(const UString &path) + { + SplitPathToParts(path, Prefix, Name); + if (Name.IsEmpty()) + return; + int dotPos = Name.ReverseFind(L'.'); + if (dotPos < 0) + return; + if (dotPos == Name.Length() - 1) + { + Name = Name.Left(dotPos); + BaseExtension.Empty(); + return; + } + if (BaseExtension.CompareNoCase(Name.Mid(dotPos + 1)) == 0) + Name = Name.Left(dotPos); + else + BaseExtension.Empty(); + } + + UString GetPathWithoutExt() const + { + return Prefix + Name; + } + + UString GetFinalPath() const + { + UString path = GetPathWithoutExt(); + if (!BaseExtension.IsEmpty()) + path += UString(L'.') + BaseExtension; + return path; + } + + + UString GetTempPath() const + { + UString path = TempPrefix + Name; + if (!BaseExtension.IsEmpty()) + path += UString(L'.') + BaseExtension; + path += L".tmp"; + path += TempPostfix; + return path; + } +}; + +struct CUpdateArchiveCommand +{ + CArchivePath ArchivePath; + NUpdateArchive::CActionSet ActionSet; +}; + +struct CProperty +{ + UString Name; + UString Value; +}; + +struct CCompressionMethodMode +{ + #ifndef EXCLUDE_COM + UString FilePath; + CLSID ClassID; + #else + UString Name; + #endif + CObjectVector<CProperty> Properties; +}; + +struct CUpdateOptions +{ + CCompressionMethodMode MethodMode; + + CObjectVector<CUpdateArchiveCommand> Commands; + bool UpdateArchiveItself; + CArchivePath ArchivePath; + + bool SfxMode; + UString SfxModule; + + bool StdInMode; + UString StdInFileName; + bool StdOutMode; + + bool EMailMode; + bool EMailRemoveAfter; + UString EMailAddress; + + UString WorkingDir; + + CUpdateOptions(): + UpdateArchiveItself(true), + SfxMode(false), + StdInMode(false), + StdOutMode(false), + EMailMode(false), + EMailRemoveAfter(false) + {}; + CRecordVector<UInt64> VolumesSizes; +}; + +struct CErrorInfo +{ + DWORD SystemError; + UString FileName; + UString FileName2; + UString Message; + CErrorInfo(): SystemError(0) {}; +}; + +struct CUpdateErrorInfo: public CErrorInfo +{ +}; + +struct IUpdateCallbackUI2: public IUpdateCallbackUI +{ + virtual HRESULT OpenResult(const wchar_t *name, HRESULT result) = 0; + + virtual HRESULT StartScanning() = 0; + virtual HRESULT FinishScanning() = 0; + + virtual HRESULT StartArchive(const wchar_t *name, bool updating) = 0; + virtual HRESULT FinishArchive() = 0; +}; + +HRESULT UpdateArchive(const NWildcard::CCensor &censor, + CUpdateOptions &options, + CUpdateErrorInfo &errorInfo, + IOpenCallbackUI *openCallback, + IUpdateCallbackUI2 *callback); + +#endif diff --git a/7zip/UI/Common/UpdateAction.h b/7zip/UI/Common/UpdateAction.h index 1cd2fd69..aa050975 100755 --- a/7zip/UI/Common/UpdateAction.h +++ b/7zip/UI/Common/UpdateAction.h @@ -1,7 +1,5 @@ // UpdateAction.h -#pragma once - #ifndef __UPDATE_ACTION_H #define __UPDATE_ACTION_H @@ -34,6 +32,17 @@ namespace NUpdateArchive { struct CActionSet { NPairAction::EEnum StateActions[NPairState::kNumValues]; + bool NeedScanning() const + { + int i; + for (i = 0; i < NPairState::kNumValues; i++) + if (StateActions[i] == NPairAction::kCompress) + return true; + for (i = 1; i < NPairState::kNumValues; i++) + if (StateActions[i] != NPairAction::kIgnore) + return true; + return false; + } }; extern const CActionSet kAddActionSet; extern const CActionSet kUpdateActionSet; diff --git a/7zip/UI/Common/UpdateCallback.cpp b/7zip/UI/Common/UpdateCallback.cpp new file mode 100755 index 00000000..cc3d20ae --- /dev/null +++ b/7zip/UI/Common/UpdateCallback.cpp @@ -0,0 +1,242 @@ +// UpdateCallback.cpp + +#include "StdAfx.h" + +#include "UpdateCallback.h" + +#include "Common/StringConvert.h" +#include "Common/IntToString.h" +#include "Common/Defs.h" + +#include "Windows/PropVariant.h" + +#include "../../Common/FileStreams.h" + +using namespace NWindows; + +CArchiveUpdateCallback::CArchiveUpdateCallback(): + Callback(0), + StdInMode(false), + DirItems(0), + ArchiveItems(0), + UpdatePairs(0) + {} + + +STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 size) +{ + return Callback->SetTotal(size); +} + +STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 *completeValue) +{ + return Callback->SetCompleted(completeValue); +} + +/* +STATPROPSTG kProperties[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidIsFolder, VT_BOOL}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidLastAccessTime, VT_FILETIME}, + { NULL, kpidCreationTime, VT_FILETIME}, + { NULL, kpidLastWriteTime, VT_FILETIME}, + { NULL, kpidAttributes, VT_UI4}, + { NULL, kpidIsAnti, VT_BOOL} +}; +*/ + +STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **enumerator) +{ + return E_NOTIMPL; + /* + return CStatPropEnumerator::CreateEnumerator(kProperties, + sizeof(kProperties) / sizeof(kProperties[0]), enumerator); + */ +} + +STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index, + Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive) +{ + RINOK(Callback->CheckBreak()); + const CUpdatePair2 &updatePair = (*UpdatePairs)[index]; + if(newData != NULL) + *newData = BoolToInt(updatePair.NewData); + if(newProperties != NULL) + *newProperties = BoolToInt(updatePair.NewProperties); + if(indexInArchive != NULL) + { + if (updatePair.ExistInArchive) + { + if (ArchiveItems == 0) + *indexInArchive = updatePair.ArchiveItemIndex; + else + *indexInArchive = (*ArchiveItems)[updatePair.ArchiveItemIndex].IndexInServer; + } + else + *indexInArchive = UInt32(-1); + } + return S_OK; +} + +STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + const CUpdatePair2 &updatePair = (*UpdatePairs)[index]; + NWindows::NCOM::CPropVariant propVariant; + + if (propID == kpidIsAnti) + { + propVariant = updatePair.IsAnti; + propVariant.Detach(value); + return S_OK; + } + + if (updatePair.IsAnti) + { + switch(propID) + { + case kpidIsFolder: + case kpidPath: + break; + case kpidSize: + propVariant = (UInt64)0; + propVariant.Detach(value); + return S_OK; + default: + propVariant.Detach(value); + return S_OK; + } + } + + if(updatePair.ExistOnDisk) + { + const CDirItem &dirItem = (*DirItems)[updatePair.DirItemIndex]; + switch(propID) + { + case kpidPath: + propVariant = dirItem.Name; + break; + case kpidIsFolder: + propVariant = dirItem.IsDirectory(); + break; + case kpidSize: + propVariant = dirItem.Size; + break; + case kpidAttributes: + propVariant = dirItem.Attributes; + break; + case kpidLastAccessTime: + propVariant = dirItem.LastAccessTime; + break; + case kpidCreationTime: + propVariant = dirItem.CreationTime; + break; + case kpidLastWriteTime: + propVariant = dirItem.LastWriteTime; + break; + } + } + else + { + if (propID == kpidPath) + { + if (updatePair.NewNameIsDefined) + { + propVariant = updatePair.NewName; + propVariant.Detach(value); + return S_OK; + } + } + if (updatePair.ExistInArchive && Archive) + { + UInt32 indexInArchive; + if (ArchiveItems == 0) + indexInArchive = updatePair.ArchiveItemIndex; + else + indexInArchive = (*ArchiveItems)[updatePair.ArchiveItemIndex].IndexInServer; + return Archive->GetProperty(indexInArchive, propID, value); + } + } + propVariant.Detach(value); + return S_OK; +} + +STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, + ISequentialInStream **inStream) +{ + const CUpdatePair2 &updatePair = (*UpdatePairs)[index]; + if(!updatePair.NewData) + return E_FAIL; + + RINOK(Callback->CheckBreak()); + RINOK(Callback->Finilize()); + + if(updatePair.IsAnti) + { + return Callback->GetStream((*ArchiveItems)[updatePair.ArchiveItemIndex].Name, true); + } + const CDirItem &dirItem = (*DirItems)[updatePair.DirItemIndex]; + RINOK(Callback->GetStream(dirItem.Name, false)); + + if(dirItem.IsDirectory()) + return S_OK; + + if (StdInMode) + { + CStdInFileStream *inStreamSpec = new CStdInFileStream; + CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec); + *inStream = inStreamLoc.Detach(); + } + else + { + CInFileStream *inStreamSpec = new CInFileStream; + CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec); + UString path = DirPrefix + dirItem.FullPath; + if(!inStreamSpec->Open(path)) + { + return Callback->OpenFileError(path, ::GetLastError()); + } + *inStream = inStreamLoc.Detach(); + } + return S_OK; +} + +STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 operationResult) +{ + return Callback->SetOperationResult(operationResult); +} + +STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size) +{ + if (VolumesSizes.Size() == 0) + return S_FALSE; + if (index >= (UInt32)VolumesSizes.Size()) + index = VolumesSizes.Size() - 1; + *size = VolumesSizes[index]; + return S_OK; +} + +STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream) +{ + wchar_t temp[32]; + ConvertUInt64ToString(index + 1, temp); + UString res = temp; + while (res.Length() < 2) + res = UString(L'0') + res; + UString fileName = VolName; + fileName += L'.'; + fileName += res; + fileName += VolExt; + COutFileStream *streamSpec = new COutFileStream; + CMyComPtr<ISequentialOutStream> streamLoc(streamSpec); + if(!streamSpec->Create(fileName, false)) + return ::GetLastError(); + *volumeStream = streamLoc.Detach(); + return S_OK; +} + +STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) +{ + return Callback->CryptoGetTextPassword2(passwordIsDefined, password); +} diff --git a/7zip/UI/Common/UpdateCallback.h b/7zip/UI/Common/UpdateCallback.h new file mode 100755 index 00000000..8b14a9dc --- /dev/null +++ b/7zip/UI/Common/UpdateCallback.h @@ -0,0 +1,70 @@ +// UpdateCallback.h + +#ifndef __UPDATECALLBACK_H +#define __UPDATECALLBACK_H + +#include "Common/MyCom.h" +#include "Common/String.h" + +#include "../../IPassword.h" + +#include "../Common/UpdatePair.h" +#include "../Common/UpdateProduce.h" + +struct IUpdateCallbackUI +{ + virtual HRESULT SetTotal(UInt64 size) = 0; + virtual HRESULT SetCompleted(const UInt64 *completeValue) = 0; + virtual HRESULT CheckBreak() = 0; + virtual HRESULT Finilize() = 0; + virtual HRESULT GetStream(const wchar_t *name, bool isAnti) = 0; + virtual HRESULT OpenFileError(const wchar_t *name, DWORD systemError) = 0; + virtual HRESULT SetOperationResult(Int32 operationResult) = 0; + virtual HRESULT CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) = 0; + virtual HRESULT CloseProgress() { return S_OK; }; +}; + +class CArchiveUpdateCallback: + public IArchiveUpdateCallback2, + public ICryptoGetTextPassword2, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP2(IArchiveUpdateCallback2, + ICryptoGetTextPassword2) + + // IProgress + STDMETHOD(SetTotal)(UInt64 size); + STDMETHOD(SetCompleted)(const UInt64 *completeValue); + + // IUpdateCallback + STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator); + STDMETHOD(GetUpdateItemInfo)(UInt32 index, + Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream); + STDMETHOD(SetOperationResult)(Int32 operationResult); + + STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size); + STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream); + + STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password); + +public: + CRecordVector<UInt64> VolumesSizes; + UString VolName; + UString VolExt; + + IUpdateCallbackUI *Callback; + + UString DirPrefix; + bool StdInMode; + const CObjectVector<CDirItem> *DirItems; + const CObjectVector<CArchiveItem> *ArchiveItems; + const CObjectVector<CUpdatePair2> *UpdatePairs; + CMyComPtr<IInArchive> Archive; + + CArchiveUpdateCallback(); +}; + +#endif diff --git a/7zip/UI/Common/UpdatePair.cpp b/7zip/UI/Common/UpdatePair.cpp index ce33812e..64515865 100755 --- a/7zip/UI/Common/UpdatePair.cpp +++ b/7zip/UI/Common/UpdatePair.cpp @@ -11,7 +11,6 @@ #include "SortUtils.h" using namespace NWindows; -// using namespace NCOM; using namespace NTime; static int MyCompareTime(NFileTimeType::EEnum fileTimeType, @@ -23,7 +22,7 @@ static int MyCompareTime(NFileTimeType::EEnum fileTimeType, return ::CompareFileTime(&time1, &time2); case NFileTimeType::kUnix: { - time_t unixTime1, unixTime2; + UInt32 unixTime1, unixTime2; if (!FileTimeToUnixTime(time1, unixTime1)) throw 4191614; if (!FileTimeToUnixTime(time2, unixTime2)) @@ -32,7 +31,7 @@ static int MyCompareTime(NFileTimeType::EEnum fileTimeType, } case NFileTimeType::kDOS: { - UINT32 dosTime1, dosTime2; + UInt32 dosTime1, dosTime2; if (!FileTimeToDosTime(time1, dosTime1)) throw 4191616; if (!FileTimeToDosTime(time2, dosTime2)) @@ -51,23 +50,32 @@ static const char *kSameTimeChangedSizeCollisionMessaged = "Collision between files with same date/time and different sizes:\n"; */ -static void TestDuplicateString(const UStringVector &strings, - const CIntVector &indices) +static inline int MyFileNameCompare(const UString &s1, const UString &s2) +{ + return + #ifdef _WIN32 + s1.CollateNoCase(s2); + #else + s1.Compare(s2); + #endif +} + +static void TestDuplicateString(const UStringVector &strings, const CIntVector &indices) { for(int i = 0; i + 1 < indices.Size(); i++) - if (strings[indices[i]].CollateNoCase(strings[indices[i + 1]]) == 0) + if (MyFileNameCompare(strings[indices[i]], strings[indices[i + 1]]) == 0) { UString message = kDuplicateFileNameMessage; message += L"\n"; message += strings[indices[i]]; message += L"\n"; - message += strings[indices[i+1]]; + message += strings[indices[i + 1]]; throw message; } } void GetUpdatePairInfoList( - const CObjectVector<CDirItem> &dirItems, + const CObjectVector<CDirItem> &dirItems, const CObjectVector<CArchiveItem> &archiveItems, NFileTimeType::EEnum fileTimeType, CObjectVector<CUpdatePair> &updatePairs) @@ -96,7 +104,7 @@ void GetUpdatePairInfoList( archiveItemIndex2 = archiveIndices[archiveItemIndex]; const CDirItem &dirItem = dirItems[dirItemIndex2]; const CArchiveItem &archiveItem = archiveItems[archiveItemIndex2]; - int compareResult = dirItem.Name.CollateNoCase(archiveItem.Name); + int compareResult = MyFileNameCompare(dirItem.Name, archiveItem.Name); if (compareResult < 0) { pair.State = NUpdateArchive::NPairState::kOnlyOnDisk; diff --git a/7zip/UI/Common/UpdatePair.h b/7zip/UI/Common/UpdatePair.h index 41a9b09b..f50a23f8 100755 --- a/7zip/UI/Common/UpdatePair.h +++ b/7zip/UI/Common/UpdatePair.h @@ -1,9 +1,7 @@ // UpdatePair.h -#pragma once - -#ifndef __UPDATEPAIR_H -#define __UPDATEPAIR_H +#ifndef __UPDATE_PAIR_H +#define __UPDATE_PAIR_H #include "DirItem.h" #include "UpdateAction.h" diff --git a/7zip/UI/Common/UpdateProduce.h b/7zip/UI/Common/UpdateProduce.h index d09a0fba..9c1e1e44 100755 --- a/7zip/UI/Common/UpdateProduce.h +++ b/7zip/UI/Common/UpdateProduce.h @@ -1,9 +1,7 @@ // UpdateProduce.h -#pragma once - -#ifndef __UPDATEPRODUCE_H -#define __UPDATEPRODUCE_H +#ifndef __UPDATE_PRODUCE_H +#define __UPDATE_PRODUCE_H #include "UpdatePair.h" diff --git a/7zip/UI/Common/WorkDir.cpp b/7zip/UI/Common/WorkDir.cpp index 75147245..8db6f4f1 100755 --- a/7zip/UI/Common/WorkDir.cpp +++ b/7zip/UI/Common/WorkDir.cpp @@ -5,6 +5,7 @@ #include "WorkDir.h" #include "Common/StringConvert.h" +#include "Common/Wildcard.h" #include "Windows/FileName.h" #include "Windows/FileDir.h" @@ -16,23 +17,13 @@ using namespace NWindows; using namespace NFile; using namespace NName; -static UString GetContainingDir(const UString &path) -{ - UString resultPath; - int pos; - if(!NFile::NDirectory::MyGetFullPathName(path, resultPath, pos)) - throw 141716; - return resultPath.Left(pos); -} - -UString GetWorkDir(const NWorkDir::CInfo &workDirInfo, - const UString &archiveName) +UString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const UString &path) { NWorkDir::NMode::EEnum mode = workDirInfo.Mode; if (workDirInfo.ForRemovableOnly) { mode = NWorkDir::NMode::kCurrent; - UString prefix = archiveName.Left(3); + UString prefix = path.Left(3); if (prefix[1] == L':' && prefix[2] == L'\\') { UINT driveType = GetDriveType(GetSystemString(prefix, GetCurrentCodePage())); @@ -51,7 +42,7 @@ UString GetWorkDir(const NWorkDir::CInfo &workDirInfo, { case NWorkDir::NMode::kCurrent: { - return GetContainingDir(archiveName); + return ExtractDirPrefixFromPath(path); } case NWorkDir::NMode::kSpecified: { @@ -59,7 +50,7 @@ UString GetWorkDir(const NWorkDir::CInfo &workDirInfo, NormalizeDirPathPrefix(tempDir); return tempDir; } - default: // NZipSettings::NWorkDir::NMode::kSystem: + default: { UString tempDir; if(!NFile::NDirectory::MyGetTempPath(tempDir)) diff --git a/7zip/UI/Common/WorkDir.h b/7zip/UI/Common/WorkDir.h index 16720ae6..0643d67a 100755 --- a/7zip/UI/Common/WorkDir.h +++ b/7zip/UI/Common/WorkDir.h @@ -1,14 +1,10 @@ // WorkDir.h -#pragma once - #ifndef __WORKDIR_H #define __WORKDIR_H -#include "../Common/ZipRegistry.h" +#include "ZipRegistry.h" -UString GetWorkDir(const NWorkDir::CInfo &workDirInfo, - const UString &archiveName); +UString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const UString &path); #endif - diff --git a/7zip/UI/Common/ZipRegistry.cpp b/7zip/UI/Common/ZipRegistry.cpp index 16c3a808..5e376e53 100755 --- a/7zip/UI/Common/ZipRegistry.cpp +++ b/7zip/UI/Common/ZipRegistry.cpp @@ -36,7 +36,7 @@ static CSysString GetKeyPath(const CSysString &path) return CSysString(kCUBasePath) + CSysString('\\') + CSysString(path); } -void SaveExtractionInfo(const NExtraction::CInfo &info) +void SaveExtractionInfo(const NExtract::CInfo &info) { NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); CKey extractionKey; @@ -48,20 +48,20 @@ void SaveExtractionInfo(const NExtraction::CInfo &info) for(int i = 0; i < info.Paths.Size(); i++) { TCHAR numberString[16]; - ConvertUINT64ToString(i, numberString); + ConvertUInt64ToString(i, numberString); pathHistoryKey.SetValue(numberString, info.Paths[i]); } } - extractionKey.SetValue(kExtractionExtractModeValueName, UINT32(info.PathMode)); - extractionKey.SetValue(kExtractionOverwriteModeValueName, UINT32(info.OverwriteMode)); + extractionKey.SetValue(kExtractionExtractModeValueName, UInt32(info.PathMode)); + extractionKey.SetValue(kExtractionOverwriteModeValueName, UInt32(info.OverwriteMode)); extractionKey.SetValue(kExtractionShowPasswordValueName, info.ShowPassword); } -void ReadExtractionInfo(NExtraction::CInfo &info) +void ReadExtractionInfo(NExtract::CInfo &info) { info.Paths.Clear(); - info.PathMode = NExtraction::NPathMode::kFullPathnames; - info.OverwriteMode = NExtraction::NOverwriteMode::kAskBefore; + info.PathMode = NExtract::NPathMode::kCurrentPathnames; + info.OverwriteMode = NExtract::NOverwriteMode::kAskBefore; info.ShowPassword = false; NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); @@ -77,7 +77,7 @@ void ReadExtractionInfo(NExtraction::CInfo &info) while(true) { TCHAR numberString[16]; - ConvertUINT64ToString(info.Paths.Size(), numberString); + ConvertUInt64ToString(info.Paths.Size(), numberString); CSysString path; if (pathHistoryKey.QueryValue(numberString, path) != ERROR_SUCCESS) break; @@ -85,29 +85,29 @@ void ReadExtractionInfo(NExtraction::CInfo &info) } } } - UINT32 extractModeIndex; + UInt32 extractModeIndex; if (extractionKey.QueryValue(kExtractionExtractModeValueName, extractModeIndex) == ERROR_SUCCESS) { switch (extractModeIndex) { - case NExtraction::NPathMode::kFullPathnames: - case NExtraction::NPathMode::kCurrentPathnames: - case NExtraction::NPathMode::kNoPathnames: - info.PathMode = NExtraction::NPathMode::EEnum(extractModeIndex); + case NExtract::NPathMode::kFullPathnames: + case NExtract::NPathMode::kCurrentPathnames: + case NExtract::NPathMode::kNoPathnames: + info.PathMode = NExtract::NPathMode::EEnum(extractModeIndex); break; } } - UINT32 overwriteModeIndex; + UInt32 overwriteModeIndex; if (extractionKey.QueryValue(kExtractionOverwriteModeValueName, overwriteModeIndex) == ERROR_SUCCESS) { switch (overwriteModeIndex) { - case NExtraction::NOverwriteMode::kAskBefore: - case NExtraction::NOverwriteMode::kWithoutPrompt: - case NExtraction::NOverwriteMode::kSkipExisting: - case NExtraction::NOverwriteMode::kAutoRename: - case NExtraction::NOverwriteMode::kAutoRenameExisting: - info.OverwriteMode = NExtraction::NOverwriteMode::EEnum(overwriteModeIndex); + case NExtract::NOverwriteMode::kAskBefore: + case NExtract::NOverwriteMode::kWithoutPrompt: + case NExtract::NOverwriteMode::kSkipExisting: + case NExtract::NOverwriteMode::kAutoRename: + case NExtract::NOverwriteMode::kAutoRenameExisting: + info.OverwriteMode = NExtract::NOverwriteMode::EEnum(overwriteModeIndex); break; } } @@ -151,7 +151,7 @@ void SaveCompressionInfo(const NCompression::CInfo &info) for(int i = 0; i < info.HistoryArchives.Size(); i++) { TCHAR numberString[16]; - ConvertUINT64ToString(i, numberString); + ConvertUInt64ToString(i, numberString); historyArchivesKey.SetValue(numberString, info.HistoryArchives[i]); } } @@ -171,7 +171,7 @@ void SaveCompressionInfo(const NCompression::CInfo &info) formatKey.DeleteValue(kCompressionOptions); else formatKey.SetValue(kCompressionOptions, fo.Options); - if (fo.Level == UINT32(-1)) + if (fo.Level == UInt32(-1)) formatKey.DeleteValue(kCompressionLevel); else formatKey.SetValue(kCompressionLevel, fo.Level); @@ -179,18 +179,18 @@ void SaveCompressionInfo(const NCompression::CInfo &info) formatKey.DeleteValue(kCompressionMethod); else formatKey.SetValue(kCompressionMethod, fo.Method); - if (fo.Dictionary == UINT32(-1)) + if (fo.Dictionary == UInt32(-1)) formatKey.DeleteValue(kCompressionDictionary); else formatKey.SetValue(kCompressionDictionary, fo.Dictionary); - if (fo.Order == UINT32(-1)) + if (fo.Order == UInt32(-1)) formatKey.DeleteValue(kCompressionOrder); else formatKey.SetValue(kCompressionOrder, fo.Order); } } - compressionKey.SetValue(kCompressionLevelValueName, UINT32(info.Level)); + compressionKey.SetValue(kCompressionLevelValueName, UInt32(info.Level)); compressionKey.SetValue(kCompressionLastFormatValueName, GetSystemString(info.ArchiveType)); @@ -235,7 +235,7 @@ void ReadCompressionInfo(NCompression::CInfo &info) while(true) { TCHAR numberString[16]; - ConvertUINT64ToString(info.HistoryArchives.Size(), numberString); + ConvertUInt64ToString(info.HistoryArchives.Size(), numberString); CSysString path; if (historyArchivesKey.QueryValue(numberString, path) != ERROR_SUCCESS) break; @@ -269,13 +269,13 @@ void ReadCompressionInfo(NCompression::CInfo &info) if (formatKey.QueryValue(kCompressionOptions, fo.Options) != ERROR_SUCCESS) fo.Options.Empty(); if (formatKey.QueryValue(kCompressionLevel, fo.Level) != ERROR_SUCCESS) - fo.Level = UINT32(-1); + fo.Level = UInt32(-1); if (formatKey.QueryValue(kCompressionMethod, fo.Method) != ERROR_SUCCESS) fo.Method.Empty();; if (formatKey.QueryValue(kCompressionDictionary, fo.Dictionary) != ERROR_SUCCESS) - fo.Dictionary = UINT32(-1); + fo.Dictionary = UInt32(-1); if (formatKey.QueryValue(kCompressionOrder, fo.Order) != ERROR_SUCCESS) - fo.Order = UINT32(-1); + fo.Order = UInt32(-1); info.FormatOptionsVector.Add(fo); } @@ -283,7 +283,7 @@ void ReadCompressionInfo(NCompression::CInfo &info) } } - UINT32 level; + UInt32 level; if (compressionKey.QueryValue(kCompressionLevelValueName, level) == ERROR_SUCCESS) info.Level = level; CSysString archiveType; @@ -318,7 +318,7 @@ void SaveWorkDirInfo(const NWorkDir::CInfo &info) NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); CKey optionsKey; optionsKey.Create(HKEY_CURRENT_USER, GetKeyPath(kOptionsInfoKeyName)); - optionsKey.SetValue(kWorkDirTypeValueName, UINT32(info.Mode)); + optionsKey.SetValue(kWorkDirTypeValueName, UInt32(info.Mode)); optionsKey.SetValue(kWorkDirPathValueName, GetSystemString(info.Path)); optionsKey.SetValue(kTempRemovableOnlyValueName, info.ForRemovableOnly); } @@ -332,7 +332,7 @@ void ReadWorkDirInfo(NWorkDir::CInfo &info) if(optionsKey.Open(HKEY_CURRENT_USER, GetKeyPath(kOptionsInfoKeyName), KEY_READ) != ERROR_SUCCESS) return; - UINT32 dirType; + UInt32 dirType; if (optionsKey.QueryValue(kWorkDirTypeValueName, dirType) != ERROR_SUCCESS) return; switch (dirType) @@ -380,7 +380,7 @@ bool ReadCascadedMenu() { return ReadOption(kCascadedMenuValueName, false); } -static void SaveValue(const TCHAR *value, UINT32 valueToWrite) +static void SaveValue(const TCHAR *value, UInt32 valueToWrite) { NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); CKey optionsKey; @@ -388,7 +388,7 @@ static void SaveValue(const TCHAR *value, UINT32 valueToWrite) optionsKey.SetValue(value, valueToWrite); } -static bool ReadValue(const TCHAR *value, UINT32 &result) +static bool ReadValue(const TCHAR *value, UInt32 &result) { NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); CKey optionsKey; @@ -397,8 +397,8 @@ static bool ReadValue(const TCHAR *value, UINT32 &result) return (optionsKey.QueryValue(value, result) == ERROR_SUCCESS); } -void SaveContextMenuStatus(UINT32 value) +void SaveContextMenuStatus(UInt32 value) { SaveValue(kContextMenuValueName, value); } -bool ReadContextMenuStatus(UINT32 &value) +bool ReadContextMenuStatus(UInt32 &value) { return ReadValue(kContextMenuValueName, value); } diff --git a/7zip/UI/Common/ZipRegistry.h b/7zip/UI/Common/ZipRegistry.h index 7bf56b46..74f87339 100755 --- a/7zip/UI/Common/ZipRegistry.h +++ b/7zip/UI/Common/ZipRegistry.h @@ -1,36 +1,14 @@ // ZipRegistry.h -#pragma once - #ifndef __ZIPREGISTRY_H #define __ZIPREGISTRY_H #include "Common/String.h" +#include "Common/Types.h" +#include "ExtractMode.h" -namespace NExtraction { - - namespace NPathMode - { - enum EEnum - { - kFullPathnames, - kCurrentPathnames, - kNoPathnames - }; - } - - namespace NOverwriteMode - { - enum EEnum - { - kAskBefore, - kWithoutPrompt, - kSkipExisting, - kAutoRename, - kAutoRenameExisting - }; - } - +namespace NExtract +{ struct CInfo { NPathMode::EEnum PathMode; @@ -46,13 +24,13 @@ namespace NCompression { { CSysString FormatID; CSysString Options; - UINT32 Level; + UInt32 Level; CSysString Method; - UINT32 Dictionary; - UINT32 Order; + UInt32 Dictionary; + UInt32 Order; void Init() { - Level = Dictionary = Order = UINT32(-1); + Level = Dictionary = Order = UInt32(-1); Method.Empty(); // Options.Empty(); } @@ -63,7 +41,7 @@ namespace NCompression { { CSysStringVector HistoryArchives; // bool LevelIsDefined; - UINT32 Level; + UInt32 Level; UString ArchiveType; bool Solid; @@ -101,8 +79,8 @@ namespace NWorkDir{ }; } -void SaveExtractionInfo(const NExtraction::CInfo &info); -void ReadExtractionInfo(NExtraction::CInfo &info); +void SaveExtractionInfo(const NExtract::CInfo &info); +void ReadExtractionInfo(NExtract::CInfo &info); void SaveCompressionInfo(const NCompression::CInfo &info); void ReadCompressionInfo(NCompression::CInfo &info); @@ -113,7 +91,7 @@ void ReadWorkDirInfo(NWorkDir::CInfo &info); void SaveCascadedMenu(bool enabled); bool ReadCascadedMenu(); -void SaveContextMenuStatus(UINT32 value); -bool ReadContextMenuStatus(UINT32 &value); +void SaveContextMenuStatus(UInt32 value); +bool ReadContextMenuStatus(UInt32 &value); #endif diff --git a/7zip/UI/Console/ArError.h b/7zip/UI/Console/ArError.h deleted file mode 100755 index 70f1d5b0..00000000 --- a/7zip/UI/Console/ArError.h +++ /dev/null @@ -1,64 +0,0 @@ -// ArError.h - -#pragma once - -#ifndef __ARERROR_H -#define __ARERROR_H - -namespace NExitCode { - -struct CSystemError -{ - UINT32 ErrorValue; - CSystemError(UINT32 anErrorValue): ErrorValue(anErrorValue) {} -}; - -struct CMultipleErrors -{ - UINT64 NumErrors; - CMultipleErrors(UINT64 aNumErrors): NumErrors(aNumErrors) {} -}; - - -enum EEnum { - - kSuccess = 0, // Successful operation (User exit) - kWarning = 1, // Non fatal error(s) occurred - kFatalError = 2, // A fatal error occurred - kCRCError = 3, // A CRC error occurred when unpacking - kLockedArchive = 4, // Attempt to modify an archive previously locked - kWriteError = 5, // Write to disk error - kOpenError = 6, // Open file error - kUserError = 7, // Command line option error - kMemoryError = 8, // Not enough memory for operation - - - kNotSupported = 102, // format of file doesn't supported - kFileError = 103, // - - kVerError = 110, // Version doesn't supported - kMethodError = 111, // Unsupported method - - kUserQuit = 120, // Unsupported method - - kFileIsNotArchive = 130, // File Is Not Archive - - kCommonError = 150, - - kInputArchiveException = 160, // archive file does not exist - - kErrorsDuringDecompression = 170, // Errors during decompression - - - kDirFileWith64BitSize = 171, - kFileTimeWinToDosConvertError = 172, - - kFileChangedDuringOperation = 180, - - kUserBreak = 255 // User stopped the process - -}; - -} - -#endif diff --git a/7zip/UI/Console/CompressionMode.h b/7zip/UI/Console/CompressionMode.h deleted file mode 100755 index e20c4f3b..00000000 --- a/7zip/UI/Console/CompressionMode.h +++ /dev/null @@ -1,28 +0,0 @@ -// CompressionMethodUtils.h - -#pragma once - -#ifndef __COMPRESSIONMETHODUTILS_H -#define __COMPRESSIONMETHODUTILS_H - -struct CProperty -{ - UString Name; - UString Value; -}; - -struct CCompressionMethodMode -{ - #ifndef EXCLUDE_COM - UString FilePath; - CLSID ClassID1; - #else - UString Name; - #endif - CObjectVector<CProperty> Properties; - bool PasswordIsDefined; - bool AskPassword; - UString Password; -}; - -#endif diff --git a/7zip/UI/Console/Console.dsp b/7zip/UI/Console/Console.dsp index 762975e4..59a1e11c 100755 --- a/7zip/UI/Console/Console.dsp +++ b/7zip/UI/Console/Console.dsp @@ -158,14 +158,6 @@ SOURCE=.\StdAfx.h # PROP Default_Filter "" # Begin Source File -SOURCE=.\ArError.h -# End Source File -# Begin Source File - -SOURCE=.\CompressionMode.h -# End Source File -# Begin Source File - SOURCE=.\ConsoleClose.cpp # End Source File # Begin Source File @@ -174,19 +166,11 @@ SOURCE=.\ConsoleClose.h # End Source File # Begin Source File -SOURCE=.\Extract.cpp -# End Source File -# Begin Source File - -SOURCE=.\Extract.h -# End Source File -# Begin Source File - -SOURCE=.\ExtractCallback.cpp +SOURCE=.\ExtractCallbackConsole.cpp # End Source File # Begin Source File -SOURCE=.\ExtractCallback.h +SOURCE=.\ExtractCallbackConsole.h # End Source File # Begin Source File @@ -206,11 +190,11 @@ SOURCE=.\MainAr.cpp # End Source File # Begin Source File -SOURCE=.\OpenCallback.cpp +SOURCE=.\OpenCallbackConsole.cpp # End Source File # Begin Source File -SOURCE=.\OpenCallback.h +SOURCE=.\OpenCallbackConsole.h # End Source File # Begin Source File @@ -222,27 +206,11 @@ SOURCE=.\PercentPrinter.h # End Source File # Begin Source File -SOURCE=.\TempFiles.cpp -# End Source File -# Begin Source File - -SOURCE=.\TempFiles.h -# End Source File -# Begin Source File - -SOURCE=.\Update.cpp -# End Source File -# Begin Source File - -SOURCE=.\Update.h -# End Source File -# Begin Source File - -SOURCE=.\UpdateCallback.cpp +SOURCE=.\UpdateCallbackConsole.cpp # End Source File # Begin Source File -SOURCE=.\UpdateCallback.h +SOURCE=.\UpdateCallbackConsole.h # End Source File # Begin Source File @@ -328,18 +296,22 @@ SOURCE=..\..\..\Windows\Registry.cpp SOURCE=..\..\..\Windows\Registry.h # End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" # Begin Source File -SOURCE=..\..\..\Windows\System.cpp +SOURCE=..\..\..\Common\Alloc.cpp # End Source File # Begin Source File -SOURCE=..\..\..\Windows\System.h +SOURCE=..\..\..\Common\Alloc.h # End Source File -# End Group -# Begin Group "Common" +# Begin Source File -# PROP Default_Filter "" +SOURCE=..\..\..\Common\Buffer.h +# End Source File # Begin Source File SOURCE=..\..\..\Common\CommandLineParser.cpp @@ -422,6 +394,14 @@ SOURCE=..\..\..\Common\StringConvert.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\UTFConvert.cpp # End Source File # Begin Source File @@ -450,6 +430,30 @@ SOURCE=..\..\..\Common\Wildcard.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\Common\ArchiveCommandLine.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveCommandLine.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveOpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveOpenCallback.h +# End Source File +# Begin Source File + SOURCE=..\Common\ArchiverInfo.cpp # End Source File # Begin Source File @@ -458,6 +462,10 @@ SOURCE=..\Common\ArchiverInfo.h # End Source File # Begin Source File +SOURCE=..\Common\CompressionMode.h +# End Source File +# Begin Source File + SOURCE=..\Common\DefaultName.cpp # End Source File # Begin Source File @@ -478,6 +486,18 @@ SOURCE=..\Common\EnumDirItems.h # End Source File # Begin Source File +SOURCE=..\Common\ExitCode.h +# End Source File +# Begin Source File + +SOURCE=..\Common\Extract.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\Extract.h +# End Source File +# Begin Source File + SOURCE=..\Common\ExtractingFilePath.cpp # End Source File # Begin Source File @@ -490,6 +510,10 @@ SOURCE=..\Common\HandlerLoader.h # End Source File # Begin Source File +SOURCE=..\Common\IFileExtractCallback.h +# End Source File +# Begin Source File + SOURCE=..\Common\OpenArchive.cpp # End Source File # Begin Source File @@ -514,6 +538,22 @@ SOURCE=..\Common\SortUtils.h # End Source File # Begin Source File +SOURCE=..\Common\TempFiles.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\TempFiles.h +# End Source File +# Begin Source File + +SOURCE=..\Common\Update.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\Update.h +# End Source File +# Begin Source File + SOURCE=..\Common\UpdateAction.cpp # End Source File # Begin Source File @@ -522,6 +562,14 @@ SOURCE=..\Common\UpdateAction.h # End Source File # Begin Source File +SOURCE=..\Common\UpdateCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateCallback.h +# End Source File +# Begin Source File + SOURCE=..\Common\UpdatePair.cpp # End Source File # Begin Source File @@ -544,6 +592,10 @@ SOURCE=..\Common\WorkDir.cpp SOURCE=..\Common\WorkDir.h # End Source File +# Begin Source File + +SOURCE=..\Common\ZipRegistry.h +# End Source File # End Group # Begin Group "7-zip Common" diff --git a/7zip/UI/Console/ConsoleClose.h b/7zip/UI/Console/ConsoleClose.h index 9a0fc792..3c5fd55d 100755 --- a/7zip/UI/Console/ConsoleClose.h +++ b/7zip/UI/Console/ConsoleClose.h @@ -1,7 +1,5 @@ // ConsoleCloseUtils.h -#pragma once - #ifndef __CONSOLECLOSEUTILS_H #define __CONSOLECLOSEUTILS_H @@ -24,4 +22,3 @@ void CheckCtrlBreak(); } #endif - diff --git a/7zip/UI/Console/Extract.cpp b/7zip/UI/Console/Extract.cpp deleted file mode 100755 index 1230ece0..00000000 --- a/7zip/UI/Console/Extract.cpp +++ /dev/null @@ -1,94 +0,0 @@ -// Extract.cpp - -#include "StdAfx.h" - -#include "Extract.h" -#include "ExtractCallback.h" -#include "ArError.h" - -#include "Common/StdOutStream.h" -#include "Windows/Defs.h" -#include "Windows/PropVariant.h" -#include "Windows/FileDir.h" - -using namespace NWindows; - -static const char *kEverythingIsOk = "Everything is Ok"; - -HRESULT DeCompressArchiveSTD( - IInArchive *archive, - const NWildcard::CCensor &wildcardCensor, - const CExtractOptions &options) -{ - CRecordVector<UINT32> realIndices; - UINT32 numItems; - RINOK(archive->GetNumberOfItems(&numItems)); - - for(UINT32 i = 0; i < numItems; i++) - { - NCOM::CPropVariant propVariant; - RINOK(archive->GetProperty(i, kpidPath, &propVariant)); - UString filePath; - if(propVariant.vt == VT_EMPTY) - filePath = options.DefaultItemName; - else - { - if(propVariant.vt != VT_BSTR) - return E_FAIL; - filePath = propVariant.bstrVal; - } - if (!wildcardCensor.CheckName(filePath)) - continue; - realIndices.Add(i); - } - if (realIndices.Size() == 0) - { - g_StdOut << endl << "No files to process" << endl; - return S_OK; - } - - CExtractCallbackImp *extractCallbackSpec = new CExtractCallbackImp; - CMyComPtr<IArchiveExtractCallback> extractCallback(extractCallbackSpec); - - UStringVector removePathParts; - - NExtraction::CInfo extractionInfo; - extractionInfo.PathMode = options.FullPathMode() ? NExtraction::NPathMode::kFullPathnames: - NExtraction::NPathMode::kNoPathnames; - - if (options.YesToAll) - extractionInfo.OverwriteMode = NExtraction::NOverwriteMode::kWithoutPrompt; - else - { - extractionInfo.OverwriteMode = options.OverwriteMode; - } - - if(!options.OutputBaseDir.IsEmpty()) - if(!NFile::NDirectory::CreateComplexDirectory(options.OutputBaseDir)) - { - throw "Can not create output directory"; - } - - extractCallbackSpec->Init(archive, - options.OutputBaseDir, - extractionInfo, removePathParts, - options.DefaultItemName, - options.ArchiveFileInfo.LastWriteTime, - options.ArchiveFileInfo.Attributes, - options.PasswordEnabled, - options.Password); - - HRESULT result = archive->Extract(&realIndices.Front(), - realIndices.Size(), options.ExtractMode == NExtractMode::kTest, - extractCallback); - - if (extractCallbackSpec->m_NumErrors != 0) - throw NExitCode::CMultipleErrors(extractCallbackSpec->m_NumErrors); - - if (result != S_OK) - throw NExitCode::CSystemError(result); - - g_StdOut << endl << kEverythingIsOk << endl; - - return S_OK; -} diff --git a/7zip/UI/Console/Extract.h b/7zip/UI/Console/Extract.h deleted file mode 100755 index 8e2b4cb8..00000000 --- a/7zip/UI/Console/Extract.h +++ /dev/null @@ -1,65 +0,0 @@ -// Extract.h - -#pragma once - -#ifndef __EXTRACT_H -#define __EXTRACT_H - -#include "Common/Wildcard.h" -#include "Windows/FileFind.h" - -#include "../../Archive/IArchive.h" -#include "../Common/ZipRegistry.h" - -namespace NExtractMode { - -enum EEnum -{ - kTest, - kFullPath, - kExtractToOne -}; - - -} - -class CExtractOptions -{ -public: - NExtractMode::EEnum ExtractMode; - UString OutputBaseDir; - bool YesToAll; - UString DefaultItemName; - NWindows::NFile::NFind::CFileInfoW ArchiveFileInfo; - bool PasswordEnabled; - UString Password; - - NExtraction::NOverwriteMode::EEnum OverwriteMode; - - - CExtractOptions(NExtractMode::EEnum extractMode, const UString &outputBaseDir, - bool yesToAll, bool passwordEnabled, const UString &password, - NExtraction::NOverwriteMode::EEnum overwriteMode): - ExtractMode(extractMode), - OutputBaseDir(outputBaseDir), - YesToAll(yesToAll), - PasswordEnabled(passwordEnabled), - Password(password), - OverwriteMode(overwriteMode) - {} - - bool TestMode() const { return (ExtractMode == NExtractMode::kTest); } - bool FullPathMode() const { return (ExtractMode == NExtractMode::kTest) || - (ExtractMode == NExtractMode::kFullPath); } -}; - -HRESULT DeCompressArchiveSTD(IInArchive *archive, - const NWildcard::CCensor &wildcardCensor, - const CExtractOptions &options); - -/* -bool DeCompressArchiveSTD(TTWildCardInputArchive &anArchive, - const TTExtractOptions &anOptions); -*/ - -#endif diff --git a/7zip/UI/Console/ExtractCallback.cpp b/7zip/UI/Console/ExtractCallback.cpp deleted file mode 100755 index c3f0d498..00000000 --- a/7zip/UI/Console/ExtractCallback.cpp +++ /dev/null @@ -1,405 +0,0 @@ -// ExtractCallback.h - -#include "StdAfx.h" - -#include "ExtractCallback.h" -#include "UserInputUtils.h" - -#include "ConsoleClose.h" -#include "Common/StdOutStream.h" -#include "Common/StdInStream.h" -#include "Common/Wildcard.h" -#include "Common/StringConvert.h" - -#include "Windows/COM.h" -#include "Windows/FileDir.h" -#include "Windows/FileFind.h" -#include "Windows/Time.h" -#include "Windows/Defs.h" -#include "Windows/PropVariant.h" - -#include "Windows/PropVariantConversions.h" - -#include "../../Common/FilePathAutoRename.h" - -#include "../Common/ExtractingFilePath.h" - -using namespace NWindows; -using namespace NFile; -using namespace NDirectory; - -static const char *kTestingString = "Testing "; -static const char *kExtractingString = "Extracting "; -static const char *kSkippingString = "Skipping "; - -static const char *kCantAutoRename = "can not create file with auto name\n"; -static const char *kCantRenameFile = "can not rename existing file\n"; -static const char *kCantDeleteOutputFile = "can not delete output file "; -void CExtractCallbackImp::Init(IInArchive *archive, - const UString &directoryPath, - const NExtraction::CInfo &extractModeInfo, - const UStringVector &removePathParts, - const UString &itemDefaultName, - const FILETIME &utcLastWriteTimeDefault, - UINT32 attributesDefault, - bool passwordIsDefined, - const UString &password) -{ - m_PasswordIsDefined = passwordIsDefined; - m_Password = password; - m_NumErrors = 0; - - m_ItemDefaultName = itemDefaultName; - m_UTCLastWriteTimeDefault = utcLastWriteTimeDefault; - m_AttributesDefault = attributesDefault; - - m_RemovePathParts = removePathParts; - m_ExtractModeInfo = extractModeInfo; - m_ArchiveHandler = archive; - m_DirectoryPath = directoryPath; - NFile::NName::NormalizeDirPathPrefix(m_DirectoryPath); -} - -bool CExtractCallbackImp::IsEncrypted(UINT32 index) -{ - NCOM::CPropVariant propVariant; - if(m_ArchiveHandler->GetProperty(index, kpidEncrypted, &propVariant) != S_OK) - return false; - if (propVariant.vt != VT_BOOL) - return false; - return VARIANT_BOOLToBool(propVariant.boolVal); -} - -STDMETHODIMP CExtractCallbackImp::SetTotal(UINT64 size) -{ - return S_OK; -} - -STDMETHODIMP CExtractCallbackImp::SetCompleted(const UINT64 *completeValue) -{ - if (NConsoleClose::TestBreakSignal()) - return E_ABORT; - return S_OK; -} - -void CExtractCallbackImp::CreateComplexDirectory(const UStringVector &dirPathParts) -{ - UString fullPath = m_DirectoryPath; - for(int i = 0; i < dirPathParts.Size(); i++) - { - fullPath += dirPathParts[i]; - MyCreateDirectory(fullPath); - fullPath += (wchar_t)NFile::NName::kDirDelimiter; - } -} - -static UString MakePathNameFromParts(const UStringVector &parts) -{ - UString result; - for(int i = 0; i < parts.Size(); i++) - { - if(i != 0) - result += wchar_t(NFile::NName::kDirDelimiter); - result += parts[i]; - } - return result; -} - -STDMETHODIMP CExtractCallbackImp::GetStream(UINT32 index, - ISequentialOutStream **outStream, INT32 askExtractMode) -{ - *outStream = NULL; - if (NConsoleClose::TestBreakSignal()) - return E_ABORT; - m_OutFileStream.Release(); - NCOM::CPropVariant propVariantName; - RINOK(m_ArchiveHandler->GetProperty(index, kpidPath, &propVariantName)); - UString fullPath; - if(propVariantName.vt == VT_EMPTY) - fullPath = m_ItemDefaultName; - else - { - if(propVariantName.vt != VT_BSTR) - return E_FAIL; - fullPath = propVariantName.bstrVal; - } - - m_FilePath = fullPath; - - UString fullPathCorrect = GetCorrectPath(fullPath); - - if(askExtractMode == NArchive::NExtract::NAskMode::kExtract) - { - NCOM::CPropVariant propVariant; - RINOK(m_ArchiveHandler->GetProperty(index, kpidAttributes, &propVariant)); - if (propVariant.vt == VT_EMPTY) - { - m_ProcessedFileInfo.Attributes = m_AttributesDefault; - m_ProcessedFileInfo.AttributesAreDefined = false; - } - else - { - if (propVariant.vt != VT_UI4) - throw "incorrect item"; - m_ProcessedFileInfo.Attributes = propVariant.ulVal; - m_ProcessedFileInfo.AttributesAreDefined = true; - } - - RINOK(m_ArchiveHandler->GetProperty(index, kpidIsFolder, &propVariant)); - m_ProcessedFileInfo.IsDirectory = VARIANT_BOOLToBool(propVariant.boolVal); - - bool isAnti = false; - { - NCOM::CPropVariant propVariantTemp; - RINOK(m_ArchiveHandler->GetProperty(index, kpidIsAnti, - &propVariantTemp)); - if (propVariantTemp.vt == VT_BOOL) - isAnti = VARIANT_BOOLToBool(propVariantTemp.boolVal); - } - - RINOK(m_ArchiveHandler->GetProperty(index, kpidLastWriteTime, &propVariant)); - switch(propVariant.vt) - { - case VT_EMPTY: - m_ProcessedFileInfo.UTCLastWriteTime = m_UTCLastWriteTimeDefault; - break; - case VT_FILETIME: - m_ProcessedFileInfo.UTCLastWriteTime = propVariant.filetime; - break; - default: - return E_FAIL; - } - - // GetPropertyValue(anItemIDList, kpidSize, &propVariant); - // UINT64 newFileSize = ConvertPropVariantToUINT64(propVariant); - - UStringVector pathParts; - SplitPathToParts(fullPathCorrect, pathParts); - if(pathParts.IsEmpty()) - return E_FAIL; - UString processedPath; - switch(m_ExtractModeInfo.PathMode) - { - case NExtraction::NPathMode::kFullPathnames: - { - processedPath = fullPathCorrect; - break; - } - case NExtraction::NPathMode::kCurrentPathnames: - { - int numRemovePathParts = m_RemovePathParts.Size(); - if(pathParts.Size() <= numRemovePathParts) - return E_FAIL; - for(int i = 0; i < numRemovePathParts; i++) - if(m_RemovePathParts[i].CollateNoCase(pathParts[i]) != 0) - return E_FAIL; - pathParts.Delete(0, numRemovePathParts); - processedPath = MakePathNameFromParts(pathParts); - break; - } - case NExtraction::NPathMode::kNoPathnames: - { - processedPath = pathParts.Back(); - pathParts.Delete(0, pathParts.Size() - 1); // Test it!! - break; - } - } - if(!m_ProcessedFileInfo.IsDirectory) - pathParts.DeleteBack(); - if (!pathParts.IsEmpty()) - { - if (!isAnti) - CreateComplexDirectory(pathParts); - } - - UString fullProcessedPath = m_DirectoryPath + GetCorrectPath(processedPath); - - if(m_ProcessedFileInfo.IsDirectory) - { - m_DiskFilePath = fullProcessedPath; - - if (isAnti) - MyRemoveDirectory(m_DiskFilePath); - return S_OK; - } - - NFile::NFind::CFileInfoW fileInfo; - if(NFile::NFind::FindFile(fullProcessedPath, fileInfo)) - { - switch(m_ExtractModeInfo.OverwriteMode) - { - case NExtraction::NOverwriteMode::kSkipExisting: - return S_OK; - case NExtraction::NOverwriteMode::kAskBefore: - { - /* - NOverwriteDialog::CFileInfo oldFileInfo, newFileInfo; - oldFileInfo.Time = fileInfo.LastWriteTime; - oldFileInfo.Size = fileInfo.Size; - oldFileInfo.Name = fullProcessedPath; - - newFileInfo.Time = m_ProcessedFileInfo.UTCLastWriteTime; - newFileInfo.Size = newFileSize; - newFileInfo.Name = fullPath; - - NOverwriteDialog::NResult::EEnum result = - NOverwriteDialog::Execute(oldFileInfo, newFileInfo); - */ - - g_StdOut << "file " << fullProcessedPath << - "\nalready exists. Overwrite with " << endl; - g_StdOut << fullPathCorrect; - - NUserAnswerMode::EEnum overwriteAnswer = ScanUserYesNoAllQuit(); - - switch(overwriteAnswer) - { - case NUserAnswerMode::kQuit: - return E_ABORT; - case NUserAnswerMode::kNo: - return S_OK; - case NUserAnswerMode::kNoAll: - m_ExtractModeInfo.OverwriteMode = NExtraction::NOverwriteMode::kSkipExisting; - return S_OK; - case NUserAnswerMode::kYesAll: - m_ExtractModeInfo.OverwriteMode = NExtraction::NOverwriteMode::kWithoutPrompt; - break; - case NUserAnswerMode::kYes: - break; - case NUserAnswerMode::kAutoRename: - m_ExtractModeInfo.OverwriteMode = NExtraction::NOverwriteMode::kAutoRename; - break; - default: - throw 20413; - } - break; - } - } - if (m_ExtractModeInfo.OverwriteMode == NExtraction::NOverwriteMode::kAutoRename) - { - if (!AutoRenamePath(fullProcessedPath)) - { - g_StdOut << kCantAutoRename; - g_StdOut << fullProcessedPath; - return E_ABORT; - } - } - else if (m_ExtractModeInfo.OverwriteMode == NExtraction::NOverwriteMode::kAutoRenameExisting) - { - UString existPath = fullProcessedPath; - if (!AutoRenamePath(existPath)) - { - g_StdOut << kCantAutoRename; - g_StdOut << fullProcessedPath; - return E_ABORT; - } - if(!MyMoveFile(fullProcessedPath, existPath)) - { - g_StdOut << kCantRenameFile; - return E_ABORT; - } - } - else - if (!DeleteFileAlways(fullProcessedPath)) - { - g_StdOut << kCantDeleteOutputFile << endl; - g_StdOut << fullProcessedPath; - return E_ABORT; - } - } - - if (!isAnti) - { - m_OutFileStreamSpec = new COutFileStream; - CMyComPtr<ISequentialOutStream> outStreamLoc(m_OutFileStreamSpec); - if (!m_OutFileStreamSpec->Open(fullProcessedPath)) - { - m_NumErrors++; - g_StdOut << "Can not open output file " << endl; - g_StdOut << fullProcessedPath << endl; - return S_OK; - } - m_OutFileStream = outStreamLoc; - *outStream = outStreamLoc.Detach(); - } - m_DiskFilePath = fullProcessedPath; - } - else - { - *outStream = NULL; - } - return S_OK; -} - -STDMETHODIMP CExtractCallbackImp::PrepareOperation(INT32 askExtractMode) -{ - m_ExtractMode = false; - switch (askExtractMode) - { - case NArchive::NExtract::NAskMode::kExtract: - m_ExtractMode = true; - g_StdOut << kExtractingString; - break; - case NArchive::NExtract::NAskMode::kTest: - g_StdOut << kTestingString; - break; - case NArchive::NExtract::NAskMode::kSkip: - g_StdOut << kSkippingString; - break; - }; - g_StdOut << m_FilePath; - return S_OK; -} - -STDMETHODIMP CExtractCallbackImp::SetOperationResult(INT32 resultEOperationResult) -{ - switch(resultEOperationResult) - { - case NArchive::NExtract::NOperationResult::kOK: - { - break; - } - default: - { - m_NumErrors++; - switch(resultEOperationResult) - { - case NArchive::NExtract::NOperationResult::kUnSupportedMethod: - g_StdOut << " Unsupported Method"; - break; - case NArchive::NExtract::NOperationResult::kCRCError: - g_StdOut << " CRC Failed"; - break; - case NArchive::NExtract::NOperationResult::kDataError: - g_StdOut << " Data Error"; - break; - default: - g_StdOut << " Unknown Error"; - // m_OutFileStream.Release(); - // return E_FAIL; - } - } - } - if(m_OutFileStream != NULL) - m_OutFileStreamSpec->File.SetLastWriteTime(&m_ProcessedFileInfo.UTCLastWriteTime); - m_OutFileStream.Release(); - if (m_ExtractMode && m_ProcessedFileInfo.AttributesAreDefined) - MySetFileAttributes(m_DiskFilePath, m_ProcessedFileInfo.Attributes); - g_StdOut << endl; - return S_OK; -} - -STDMETHODIMP CExtractCallbackImp::CryptoGetTextPassword(BSTR *password) -{ - if (!m_PasswordIsDefined) - { - g_StdOut << "\nEnter password:"; - AString oemPassword = g_StdIn.ScanStringUntilNewLine(); - m_Password = MultiByteToUnicodeString(oemPassword, CP_OEMCP); - m_PasswordIsDefined = true; - } - CMyComBSTR tempName(m_Password); - *password = tempName.Detach(); - return S_OK; -} - diff --git a/7zip/UI/Console/ExtractCallback.h b/7zip/UI/Console/ExtractCallback.h deleted file mode 100755 index 762d82cc..00000000 --- a/7zip/UI/Console/ExtractCallback.h +++ /dev/null @@ -1,77 +0,0 @@ -// ExtractCallback.h - -#pragma once - -#ifndef __EXTRACTCALLBACK_H -#define __EXTRACTCALLBACK_H - -#include "Common/String.h" -#include "../../Common/FileStreams.h" -#include "../../IPassword.h" -#include "../../Archive/IArchive.h" -#include "../Common/ZipRegistry.h" - -class CExtractCallbackImp: - public IArchiveExtractCallback, - public ICryptoGetTextPassword, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP1(ICryptoGetTextPassword) - - // IProgress - STDMETHOD(SetTotal)(UINT64 size); - STDMETHOD(SetCompleted)(const UINT64 *completeValue); - - // IExtractCallback200 - STDMETHOD(GetStream)(UINT32 index, ISequentialOutStream **outStream, - INT32 askExtractMode); - STDMETHOD(PrepareOperation)(INT32 askExtractMode); - STDMETHOD(SetOperationResult)(INT32 resultEOperationResult); - - // ICryptoGetTextPassword - STDMETHOD(CryptoGetTextPassword)(BSTR *password); - -private: - CMyComPtr<IInArchive> m_ArchiveHandler; - UString m_DirectoryPath; - NExtraction::CInfo m_ExtractModeInfo; - - UString m_FilePath; - - UString m_DiskFilePath; - - bool m_ExtractMode; - struct CProcessedFileInfo - { - FILETIME UTCLastWriteTime; - bool IsDirectory; - bool AttributesAreDefined; - UINT32 Attributes; - } m_ProcessedFileInfo; - - COutFileStream *m_OutFileStreamSpec; - CMyComPtr<ISequentialOutStream> m_OutFileStream; - UStringVector m_RemovePathParts; - - UString m_ItemDefaultName; - FILETIME m_UTCLastWriteTimeDefault; - UINT32 m_AttributesDefault; - - bool m_PasswordIsDefined; - UString m_Password; - - void CreateComplexDirectory(const UStringVector &dirPathParts); - bool IsEncrypted(UINT32 index); -public: - void Init(IInArchive *archive, const UString &directoryPath, - const NExtraction::CInfo &anExtractModeInfo, - const UStringVector &removePathParts, - const UString &itemDefaultName, - const FILETIME &utcLastWriteTimeDefault, UINT32 attributesDefault, - bool passwordIsDefined, const UString &password); - - UINT64 m_NumErrors; -}; - -#endif diff --git a/7zip/UI/Console/ExtractCallbackConsole.cpp b/7zip/UI/Console/ExtractCallbackConsole.cpp new file mode 100755 index 00000000..03445af1 --- /dev/null +++ b/7zip/UI/Console/ExtractCallbackConsole.cpp @@ -0,0 +1,227 @@ +// ExtractCallbackConsole.h + +#include "StdAfx.h" + +#include "ExtractCallbackConsole.h" +#include "UserInputUtils.h" +#include "ConsoleClose.h" + +#include "Common/Wildcard.h" + +#include "Windows/FileDir.h" +#include "Windows/FileFind.h" +#include "Windows/Time.h" +#include "Windows/Defs.h" +#include "Windows/PropVariant.h" +#include "Windows/Error.h" +#include "Windows/PropVariantConversions.h" + +#include "../../Common/FilePathAutoRename.h" + +#include "../Common/ExtractingFilePath.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDirectory; + +static const char *kTestingString = "Testing "; +static const char *kExtractingString = "Extracting "; +static const char *kSkippingString = "Skipping "; + +static const char *kCantAutoRename = "can not create file with auto name\n"; +static const char *kCantRenameFile = "can not rename existing file\n"; +static const char *kCantDeleteOutputFile = "can not delete output file "; +static const char *kError = "ERROR: "; +static const char *kMemoryExceptionMessage = "Can't allocate required memory!"; + +static const char *kProcessing = "Processing archive: "; +static const char *kEverythingIsOk = "Everything is Ok"; +static const char *kNoFiles = "No files to process"; + +static const char *kUnsupportedMethod = "Unsupported Method"; +static const char *kCRCFailed = "CRC Failed"; +static const char *kDataError = "Data Error"; +static const char *kUnknownError = "Unknown Error"; + +STDMETHODIMP CExtractCallbackConsole::SetTotal(UInt64 size) +{ + if (NConsoleClose::TestBreakSignal()) + return E_ABORT; + return S_OK; +} + +STDMETHODIMP CExtractCallbackConsole::SetCompleted(const UInt64 *completeValue) +{ + if (NConsoleClose::TestBreakSignal()) + return E_ABORT; + return S_OK; +} + +STDMETHODIMP CExtractCallbackConsole::AskOverwrite( + const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize, + const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize, + Int32 *answer) +{ + (*OutStream) << "file " << existName << + "\nalready exists. Overwrite with " << endl; + (*OutStream) << newName; + + NUserAnswerMode::EEnum overwriteAnswer = ScanUserYesNoAllQuit(OutStream); + + switch(overwriteAnswer) + { + case NUserAnswerMode::kQuit: + return E_ABORT; + case NUserAnswerMode::kNo: + *answer = NOverwriteAnswer::kNo; + break; + case NUserAnswerMode::kNoAll: + *answer = NOverwriteAnswer::kNoToAll; + break; + case NUserAnswerMode::kYesAll: + *answer = NOverwriteAnswer::kYesToAll; + break; + case NUserAnswerMode::kYes: + *answer = NOverwriteAnswer::kYes; + break; + case NUserAnswerMode::kAutoRename: + *answer = NOverwriteAnswer::kAutoRename; + break; + default: + return E_FAIL; + } + return S_OK; +} + +STDMETHODIMP CExtractCallbackConsole::PrepareOperation(const wchar_t *name, Int32 askExtractMode, const UInt64 *position) +{ + switch (askExtractMode) + { + case NArchive::NExtract::NAskMode::kExtract: + (*OutStream) << kExtractingString; + break; + case NArchive::NExtract::NAskMode::kTest: + (*OutStream) << kTestingString; + break; + case NArchive::NExtract::NAskMode::kSkip: + (*OutStream) << kSkippingString; + break; + }; + (*OutStream) << name; + if (position != 0) + (*OutStream) << " <" << *position << ">"; + return S_OK; +} + +STDMETHODIMP CExtractCallbackConsole::MessageError(const wchar_t *message) +{ + (*OutStream) << message << endl; + return S_OK; +} + +STDMETHODIMP CExtractCallbackConsole::SetOperationResult(Int32 operationResult) +{ + switch(operationResult) + { + case NArchive::NExtract::NOperationResult::kOK: + break; + default: + { + NumFileErrorsInCurrentArchive++; + NumFileErrors++; + (*OutStream) << " "; + switch(operationResult) + { + case NArchive::NExtract::NOperationResult::kUnSupportedMethod: + (*OutStream) << kUnsupportedMethod; + break; + case NArchive::NExtract::NOperationResult::kCRCError: + (*OutStream) << kCRCFailed; + break; + case NArchive::NExtract::NOperationResult::kDataError: + (*OutStream) << kDataError; + break; + default: + (*OutStream) << kUnknownError; + } + } + } + (*OutStream) << endl; + return S_OK; +} + +STDMETHODIMP CExtractCallbackConsole::CryptoGetTextPassword(BSTR *password) +{ + if (!PasswordIsDefined) + { + Password = GetPassword(OutStream); + PasswordIsDefined = true; + } + CMyComBSTR tempName(Password); + *password = tempName.Detach(); + return S_OK; +} + +HRESULT CExtractCallbackConsole::BeforeOpen(const wchar_t *name) +{ + NumArchives++; + NumFileErrorsInCurrentArchive = 0; + (*OutStream) << endl << kProcessing << name << endl; + return S_OK; +} + +HRESULT CExtractCallbackConsole::OpenResult(const wchar_t *name, HRESULT result) +{ + (*OutStream) << endl; + if (result != S_OK) + { + (*OutStream) << "Error: " << name << " is not supported archive" << endl; + NumArchiveErrors++; + } + return S_OK; +} + +HRESULT CExtractCallbackConsole::ThereAreNoFiles() +{ + (*OutStream) << endl << kNoFiles << endl; + return S_OK; +} + +HRESULT CExtractCallbackConsole::ExtractResult(HRESULT result) +{ + if (result == S_OK) + { + (*OutStream) << endl; + if (NumFileErrorsInCurrentArchive == 0) + (*OutStream) << kEverythingIsOk << endl; + else + { + NumArchiveErrors++; + (*OutStream) << "Sub items Errors: " << NumFileErrorsInCurrentArchive << endl; + } + } + if (result == S_OK) + return result; + if (result == E_ABORT) + return result; + (*OutStream) << endl << kError; + if (result == E_OUTOFMEMORY) + (*OutStream) << kMemoryExceptionMessage; + else + { + UString message; + NError::MyFormatMessage(result, message); + (*OutStream) << message; + } + (*OutStream) << endl; + + NumArchiveErrors++; + return S_OK; +} + +HRESULT CExtractCallbackConsole::SetPassword(const UString &password) +{ + PasswordIsDefined = true; + Password = password; + return S_OK; +} diff --git a/7zip/UI/Console/ExtractCallbackConsole.h b/7zip/UI/Console/ExtractCallbackConsole.h new file mode 100755 index 00000000..eb3d078a --- /dev/null +++ b/7zip/UI/Console/ExtractCallbackConsole.h @@ -0,0 +1,65 @@ +// ExtractCallbackConsole.h + +#ifndef __EXTRACTCALLBACKCONSOLE_H +#define __EXTRACTCALLBACKCONSOLE_H + +#include "Common/String.h" +#include "Common/StdOutStream.h" +#include "../../Common/FileStreams.h" +#include "../../IPassword.h" +#include "../../Archive/IArchive.h" +#include "../Common/ArchiveExtractCallback.h" + +class CExtractCallbackConsole: + public IExtractCallbackUI, + public ICryptoGetTextPassword, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP2(IFolderArchiveExtractCallback, ICryptoGetTextPassword) + + STDMETHOD(SetTotal)(UInt64 total); + STDMETHOD(SetCompleted)(const UInt64 *completeValue); + + // IFolderArchiveExtractCallback + STDMETHOD(AskOverwrite)( + const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize, + const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize, + Int32 *answer); + STDMETHOD (PrepareOperation)(const wchar_t *name, Int32 askExtractMode, const UInt64 *position); + + STDMETHOD(MessageError)(const wchar_t *message); + STDMETHOD(SetOperationResult)(Int32 operationResult); + + // ICryptoGetTextPassword + STDMETHOD(CryptoGetTextPassword)(BSTR *password); + + HRESULT BeforeOpen(const wchar_t *name); + HRESULT OpenResult(const wchar_t *name, HRESULT result); + HRESULT ThereAreNoFiles(); + HRESULT ExtractResult(HRESULT result); + + HRESULT SetPassword(const UString &password); + +public: + bool PasswordIsDefined; + UString Password; + + UInt64 NumArchives; + UInt64 NumArchiveErrors; + UInt64 NumFileErrors; + UInt64 NumFileErrorsInCurrentArchive; + + CStdOutStream *OutStream; + + void CExtractCallbackConsole::Init() + { + NumArchives = 0; + NumArchiveErrors = 0; + NumFileErrors = 0; + NumFileErrorsInCurrentArchive = 0; + } + +}; + +#endif diff --git a/7zip/UI/Console/List.cpp b/7zip/UI/Console/List.cpp index 3676e5a9..07637cba 100755 --- a/7zip/UI/Console/List.cpp +++ b/7zip/UI/Console/List.cpp @@ -13,45 +13,40 @@ #include "Windows/PropVariant.h" #include "Windows/Defs.h" #include "Windows/PropVariantConversions.h" +#include "Windows/FileDir.h" -#include "../Common/PropIDUtils.h" +#include "../../Archive/IArchive.h" -using namespace NWindows; +#include "../Common/PropIDUtils.h" +#include "../Common/OpenArchive.h" -/* -static const char kEmptyFlag = '.'; +#include "OpenCallbackConsole.h" -static const char kPasswordFlag = '*'; -static const char kSolidFlag = 'S'; -static const char kSplitBeforeFlag = 'B'; -static const char kSplitAfterFlag = 'A'; -static const char kCommentedFlag = 'C'; -*/ +using namespace NWindows; static const char kEmptyAttributeChar = '.'; -//static const char kVolumeAttributeChar = 'V'; static const char kDirectoryAttributeChar = 'D'; static const char kReadonlyAttributeChar = 'R'; static const char kHiddenAttributeChar = 'H'; static const char kSystemAttributeChar = 'S'; static const char kArchiveAttributeChar = 'A'; -static AString GetAttributesString(DWORD winAttributes, bool directory) +static const char *kListing = "Listing archive: "; +static const wchar_t *kFilesMessage = L"files"; + +static void GetAttributesString(DWORD wa, bool directory, char *s) { - AString s; - // s = ((winAttributes & kLabelFileAttribute) != 0) ? - // kVolumeAttributeChar: kEmptyAttributeChar; - s += ((winAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0 || directory) ? - kDirectoryAttributeChar: kEmptyAttributeChar; - s += ((winAttributes & FILE_ATTRIBUTE_READONLY) != 0)? - kReadonlyAttributeChar: kEmptyAttributeChar; - s += ((winAttributes & FILE_ATTRIBUTE_HIDDEN) != 0) ? - kHiddenAttributeChar: kEmptyAttributeChar; - s += ((winAttributes & FILE_ATTRIBUTE_SYSTEM) != 0) ? - kSystemAttributeChar: kEmptyAttributeChar; - s += ((winAttributes & FILE_ATTRIBUTE_ARCHIVE) != 0) ? - kArchiveAttributeChar: kEmptyAttributeChar; - return s; + s[0] = ((wa & FILE_ATTRIBUTE_DIRECTORY) != 0 || directory) ? + kDirectoryAttributeChar: kEmptyAttributeChar; + s[1] = ((wa & FILE_ATTRIBUTE_READONLY) != 0)? + kReadonlyAttributeChar: kEmptyAttributeChar; + s[2] = ((wa & FILE_ATTRIBUTE_HIDDEN) != 0) ? + kHiddenAttributeChar: kEmptyAttributeChar; + s[3] = ((wa & FILE_ATTRIBUTE_SYSTEM) != 0) ? + kSystemAttributeChar: kEmptyAttributeChar; + s[4] = ((wa & FILE_ATTRIBUTE_ARCHIVE) != 0) ? + kArchiveAttributeChar: kEmptyAttributeChar; + s[5] = '\0'; } enum EAdjustment @@ -127,9 +122,9 @@ public: HRESULT PrintItemInfo(IInArchive *archive, const UString &defaultItemName, const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo, - UINT32 index); - HRESULT PrintSummaryInfo(UINT64 numFiles, const UINT64 *size, - const UINT64 *compressedSize); + UInt32 index); + HRESULT PrintSummaryInfo(UInt64 numFiles, const UInt64 *size, + const UInt64 *compressedSize); }; void CFieldPrinter::Init(const CFieldInfoInit *standardFieldTable, int numItems) @@ -155,7 +150,8 @@ void CFieldPrinter::PrintTitle() { const CFieldInfo &fieldInfo = _fields[i]; PrintSpaces(fieldInfo.PrefixSpacesWidth); - PrintString(fieldInfo.TitleAdjustment, fieldInfo.Width, fieldInfo.Name); + PrintString(fieldInfo.TitleAdjustment, + ((fieldInfo.PropID == kpidPath) ? 0: fieldInfo.Width), fieldInfo.Name); } } @@ -176,8 +172,7 @@ BOOL IsFileTimeZero(CONST FILETIME *lpFileTime) return (lpFileTime->dwLowDateTime == 0) && (lpFileTime->dwHighDateTime == 0); } - -const char *kEmptyTimeString = " "; +static const char *kEmptyTimeString = " "; void PrintTime(const NCOM::CPropVariant &propVariant) { if (propVariant.vt != VT_FILETIME) @@ -189,14 +184,9 @@ void PrintTime(const NCOM::CPropVariant &propVariant) FILETIME localFileTime; if (!FileTimeToLocalFileTime(&propVariant.filetime, &localFileTime)) throw "FileTimeToLocalFileTime error"; - SYSTEMTIME st; - if (FileTimeToSystemTime(&localFileTime, &st)) - { - char s[32]; - wsprintfA(s, "%04u-%02u-%02u %02u:%02u:%02u", - st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); + char s[32]; + if (ConvertFileTimeToString(localFileTime, s, true, true)) g_StdOut << s; - } else g_StdOut << kEmptyTimeString; } @@ -205,7 +195,7 @@ void PrintTime(const NCOM::CPropVariant &propVariant) HRESULT CFieldPrinter::PrintItemInfo(IInArchive *archive, const UString &defaultItemName, const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo, - UINT32 index) + UInt32 index) { for (int i = 0; i < _fields.Size(); i++) { @@ -213,8 +203,8 @@ HRESULT CFieldPrinter::PrintItemInfo(IInArchive *archive, PrintSpaces(fieldInfo.PrefixSpacesWidth); NCOM::CPropVariant propVariant; - RINOK(archive->GetProperty(index, - fieldInfo.PropID, &propVariant)); + RINOK(archive->GetProperty(index, fieldInfo.PropID, &propVariant)); + int width = (fieldInfo.PropID == kpidPath) ? 0: fieldInfo.Width; if (propVariant.vt == VT_EMPTY) { switch(fieldInfo.PropID) @@ -226,7 +216,7 @@ HRESULT CFieldPrinter::PrintItemInfo(IInArchive *archive, propVariant = archiveFileInfo.LastWriteTime; break; default: - PrintSpaces(fieldInfo.Width); + PrintSpaces(width); continue; } } @@ -240,39 +230,37 @@ HRESULT CFieldPrinter::PrintItemInfo(IInArchive *archive, { if (propVariant.vt != VT_UI4) throw "incorrect item"; - UINT32 attributes = propVariant.ulVal; - NCOM::CPropVariant propVariantIsFolder; - RINOK(archive->GetProperty(index, - kpidIsFolder, &propVariantIsFolder)); - if(propVariantIsFolder.vt != VT_BOOL) - return E_FAIL; - g_StdOut << GetAttributesString(attributes, VARIANT_BOOLToBool(propVariantIsFolder.boolVal)); + UInt32 attributes = propVariant.ulVal; + bool isFolder; + RINOK(IsArchiveItemFolder(archive, index, isFolder)); + char s[8]; + GetAttributesString(attributes, isFolder, s); + g_StdOut << s; continue; } if (propVariant.vt == VT_BSTR) { - PrintString(fieldInfo.TextAdjustment, fieldInfo.Width, propVariant.bstrVal); + PrintString(fieldInfo.TextAdjustment, width, propVariant.bstrVal); continue; } - PrintString(fieldInfo.TextAdjustment, fieldInfo.Width, + PrintString(fieldInfo.TextAdjustment, width, ConvertPropertyToString(propVariant, fieldInfo.PropID)); } return S_OK; } -void PrintNumberString(EAdjustment adjustment, int width, const UINT64 *value) +void PrintNumberString(EAdjustment adjustment, int width, const UInt64 *value) { wchar_t textString[32] = { 0 }; if (value != NULL) - ConvertUINT64ToString(*value, textString); + ConvertUInt64ToString(*value, textString); PrintString(adjustment, width, textString); } -static const wchar_t *kFilesMessage = L"files"; -HRESULT CFieldPrinter::PrintSummaryInfo(UINT64 numFiles, - const UINT64 *size, const UINT64 *compressedSize) +HRESULT CFieldPrinter::PrintSummaryInfo(UInt64 numFiles, + const UInt64 *size, const UInt64 *compressedSize) { for (int i = 0; i < _fields.Size(); i++) { @@ -286,11 +274,11 @@ HRESULT CFieldPrinter::PrintSummaryInfo(UINT64 numFiles, else if (fieldInfo.PropID == kpidPath) { wchar_t textString[32]; - ConvertUINT64ToString(numFiles, textString); + ConvertUInt64ToString(numFiles, textString); UString temp = textString; temp += L" "; temp += kFilesMessage; - PrintString(fieldInfo.TextAdjustment, fieldInfo.Width, temp); + PrintString(fieldInfo.TextAdjustment, 0, temp); } else PrintString(fieldInfo.TextAdjustment, fieldInfo.Width, L""); @@ -298,84 +286,147 @@ HRESULT CFieldPrinter::PrintSummaryInfo(UINT64 numFiles, return S_OK; } -bool GetUINT64Value(IInArchive *archive, UINT32 index, - PROPID propID, UINT64 &value) +bool GetUInt64Value(IInArchive *archive, UInt32 index, PROPID propID, UInt64 &value) { NCOM::CPropVariant propVariant; if (archive->GetProperty(index, propID, &propVariant) != S_OK) throw "GetPropertyValue error"; if (propVariant.vt == VT_EMPTY) return false; - value = ConvertPropVariantToUINT64(propVariant); + value = ConvertPropVariantToUInt64(propVariant); return true; } -HRESULT ListArchive(IInArchive *archive, - const UString &defaultItemName, - const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo, - const NWildcard::CCensor &wildcardCensor/*, bool fullPathMode, - NListMode::EEnum mode*/) +HRESULT ListArchives(UStringVector &archivePaths, UStringVector &archivePathsFull, + const NWildcard::CCensorNode &wildcardCensor, + bool enableHeaders, bool &passwordEnabled, UString &password) { CFieldPrinter fieldPrinter; fieldPrinter.Init(kStandardFieldTable, sizeof(kStandardFieldTable) / sizeof(kStandardFieldTable[0])); - fieldPrinter.PrintTitle(); - g_StdOut << endl; - fieldPrinter.PrintTitleLines(); - g_StdOut << endl; - - // bool nameFirst = (fullPathMode && (mode != NListMode::kDefault)) || (mode == NListMode::kAll); - - UINT64 numFiles = 0, totalPackSize = 0, totalUnPackSize = 0; - UINT64 *totalPackSizePointer = 0, *totalUnPackSizePointer = 0; - UINT32 numItems; - RINOK(archive->GetNumberOfItems(&numItems)); - for(UINT32 i = 0; i < numItems; i++) + + UInt64 numFiles2 = 0, totalPackSize2 = 0, totalUnPackSize2 = 0; + UInt64 *totalPackSizePointer2 = 0, *totalUnPackSizePointer2 = 0; + int numErrors = 0; + for (int i = 0; i < archivePaths.Size(); i++) { - if (NConsoleClose::TestBreakSignal()) - return E_ABORT; - NCOM::CPropVariant propVariant; - RINOK(archive->GetProperty(i, kpidPath, &propVariant)); - UString filePath; - if(propVariant.vt == VT_EMPTY) - filePath = defaultItemName; - else + const UString &archiveName = archivePaths[i]; + NFile::NFind::CFileInfoW archiveFileInfo; + if (!NFile::NFind::FindFile(archiveName, archiveFileInfo) || archiveFileInfo.IsDirectory()) { - if(propVariant.vt != VT_BSTR) - return E_FAIL; - filePath = propVariant.bstrVal; + g_StdOut << endl << "Error: " << archiveName << " is not archive" << endl; + numErrors++; + continue; } - if (!wildcardCensor.CheckName(filePath)) + if (archiveFileInfo.IsDirectory()) + { + g_StdOut << endl << "Error: " << archiveName << " is not file" << endl; + numErrors++; continue; + } - fieldPrinter.PrintItemInfo(archive, defaultItemName, archiveFileInfo, i); + CArchiveLink archiveLink; - UINT64 packSize, unpackSize; - if (!GetUINT64Value(archive, i, kpidSize, unpackSize)) - unpackSize = 0; - else - totalUnPackSizePointer = &totalUnPackSize; - if (!GetUINT64Value(archive, i, kpidPackedSize, packSize)) - packSize = 0; - else - totalPackSizePointer = &totalPackSize; + COpenCallbackConsole openCallback; + openCallback.OutStream = &g_StdOut; + openCallback.PasswordIsDefined = passwordEnabled; + openCallback.Password = password; - g_StdOut << endl; + HRESULT result = MyOpenArchive(archiveName, archiveLink, &openCallback); + if (result != S_OK) + { + g_StdOut << endl << "Error: " << archiveName << " is not supported archive" << endl; + numErrors++; + continue; + } - numFiles++; - totalPackSize += packSize; - totalUnPackSize += unpackSize; - } - fieldPrinter.PrintTitleLines(); - g_StdOut << endl; - /* - if(numFiles == 0) - g_StdOut << kNoFilesMessage); - else - */ - fieldPrinter.PrintSummaryInfo(numFiles, totalUnPackSizePointer, totalPackSizePointer); - g_StdOut << endl; - return S_OK; -} + for (int v = 0; v < archiveLink.VolumePaths.Size(); v++) + { + int index = archivePathsFull.FindInSorted(archiveLink.VolumePaths[v]); + if (index >= 0 && index > i) + { + archivePaths.Delete(index); + archivePathsFull.Delete(index); + } + } + IInArchive *archive = archiveLink.GetArchive(); + const UString defaultItemName = archiveLink.GetDefaultItemName(); + if (enableHeaders) + g_StdOut << endl << kListing << archiveName << endl << endl; + if (enableHeaders) + { + fieldPrinter.PrintTitle(); + g_StdOut << endl; + fieldPrinter.PrintTitleLines(); + g_StdOut << endl; + } + + UInt64 numFiles = 0, totalPackSize = 0, totalUnPackSize = 0; + UInt64 *totalPackSizePointer = 0, *totalUnPackSizePointer = 0; + UInt32 numItems; + RINOK(archive->GetNumberOfItems(&numItems)); + for(UInt32 i = 0; i < numItems; i++) + { + if (NConsoleClose::TestBreakSignal()) + return E_ABORT; + + UString filePath; + RINOK(GetArchiveItemPath(archive, i, defaultItemName, filePath)); + + bool isFolder; + RINOK(IsArchiveItemFolder(archive, i, isFolder)); + if (!wildcardCensor.CheckPath(filePath, !isFolder)) + continue; + + fieldPrinter.PrintItemInfo(archive, defaultItemName, archiveFileInfo, i); + + UInt64 packSize, unpackSize; + if (!GetUInt64Value(archive, i, kpidSize, unpackSize)) + unpackSize = 0; + else + totalUnPackSizePointer = &totalUnPackSize; + if (!GetUInt64Value(archive, i, kpidPackedSize, packSize)) + packSize = 0; + else + totalPackSizePointer = &totalPackSize; + + g_StdOut << endl; + + numFiles++; + totalPackSize += packSize; + totalUnPackSize += unpackSize; + } + if (enableHeaders) + { + fieldPrinter.PrintTitleLines(); + g_StdOut << endl; + fieldPrinter.PrintSummaryInfo(numFiles, totalUnPackSizePointer, totalPackSizePointer); + g_StdOut << endl; + } + if (totalPackSizePointer != 0) + { + totalPackSizePointer2 = &totalPackSize2; + totalPackSize2 += totalPackSize; + } + if (totalUnPackSizePointer != 0) + { + totalUnPackSizePointer2 = &totalUnPackSize2; + totalUnPackSize2 += totalUnPackSize; + } + numFiles2 += numFiles; + } + if (enableHeaders && archivePaths.Size() > 1) + { + g_StdOut << endl; + fieldPrinter.PrintTitleLines(); + g_StdOut << endl; + fieldPrinter.PrintSummaryInfo(numFiles2, totalUnPackSizePointer2, totalPackSizePointer2); + g_StdOut << endl; + g_StdOut << "Archives: " << archivePaths.Size() << endl; + } + if (numErrors > 0) + g_StdOut << endl << "Errors: " << numErrors; + return S_OK; +} diff --git a/7zip/UI/Console/List.h b/7zip/UI/Console/List.h index e8c16164..847979b5 100755 --- a/7zip/UI/Console/List.h +++ b/7zip/UI/Console/List.h @@ -1,31 +1,13 @@ // List.h -#pragma once - #ifndef __LIST_H #define __LIST_H -#include "../../Archive/IArchive.h" #include "Common/Wildcard.h" -#include "Windows/FileFind.h" - -/* -namespace NListMode -{ - enum EEnum - { - kDefault, - kAdd, - kAll - }; -} -*/ -HRESULT ListArchive(IInArchive *archive, - const UString &defaultItemName, - const NWindows::NFile::NFind::CFileInfoW &srchiveFileInfo, - const NWildcard::CCensor &wildcardCensor/*, bool fullPathMode, - NListMode::EEnum mode*/); +HRESULT ListArchives(UStringVector &archivePaths, UStringVector &archivePathsFull, + const NWildcard::CCensorNode &wildcardCensor, + bool enableHeaders, bool &passwordEnabled, UString &password); #endif diff --git a/7zip/UI/Console/Main.cpp b/7zip/UI/Console/Main.cpp index 8e01ae8d..c6424f15 100755 --- a/7zip/UI/Console/Main.cpp +++ b/7zip/UI/Console/Main.cpp @@ -2,33 +2,37 @@ #include "StdAfx.h" -#include <initguid.h> #include <io.h> - +#include "Common/MyInitGuid.h" #include "Common/CommandLineParser.h" #include "Common/StdOutStream.h" #include "Common/Wildcard.h" #include "Common/ListFileUtils.h" #include "Common/StringConvert.h" +#include "Common/StdInStream.h" +#include "Common/StringToInt.h" +#include "Common/Exception.h" #include "Windows/FileDir.h" #include "Windows/FileName.h" #include "Windows/Defs.h" +#include "Windows/Error.h" #include "../../IPassword.h" #include "../../ICoder.h" #include "../../Compress/LZ/IMatchFinder.h" -#include "../Common/DefaultName.h" -#include "../Common/OpenArchive.h" #include "../Common/ArchiverInfo.h" #include "../Common/UpdateAction.h" +#include "../Common/Update.h" +#include "../Common/Extract.h" +#include "../Common/ArchiveCommandLine.h" +#include "../Common/ExitCode.h" #include "List.h" -#include "Extract.h" -#include "Update.h" -#include "ArError.h" -#include "OpenCallback.h" +#include "OpenCallbackConsole.h" +#include "ExtractCallbackConsole.h" +#include "UpdateCallbackConsole.h" #ifndef EXCLUDE_COM #include "Windows/DLL.h" @@ -39,6 +43,7 @@ using namespace NFile; using namespace NCommandLineParser; HINSTANCE g_hInstance = 0; +extern CStdOutStream *g_StdStream; static const char *kCopyrightString = "\n7-Zip" #ifdef EXCLUDE_COM @@ -49,155 +54,14 @@ static const char *kCopyrightString = "\n7-Zip" " [NT]" #endif -" 3.12 Copyright (c) 1999-2003 Igor Pavlov 2003-12-10\n"; - -const wchar_t *kDefaultArchiveType = L"7z"; -const wchar_t *kDefaultSfxModule = L"7zCon.sfx"; -const wchar_t *kSFXExtension = L"exe"; - -static const int kNumSwitches = 15; - -namespace NKey { -enum Enum -{ - kHelp1 = 0, - kHelp2, - kDisablePercents, - kArchiveType, - kYes, - kPassword, - kProperty, - kOutputDir, - kWorkingDir, - kInclude, - kExclude, - kUpdate, - kRecursed, - kSfx, - kOverwrite -}; - -} - -namespace NRecursedType { -enum EEnum -{ - kRecursed, - kWildCardOnlyRecursed, - kNonRecursed, -}; -} - -static const wchar_t kRecursedIDChar = 'R'; -static const wchar_t *kRecursedPostCharSet = L"0-"; - -namespace NRecursedPostCharIndex { - enum EEnum - { - kWildCardRecursionOnly = 0, - kNoRecursion = 1 - }; -} - -static const char kFileListID = '@'; -static const char kImmediateNameID = '!'; - -static const char kSomeCludePostStringMinSize = 2; // at least <@|!><N>ame must be -static const char kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!><N>ame must be - -static const wchar_t *kOverwritePostCharSet = L"asut"; - -NExtraction::NOverwriteMode::EEnum k_OverwriteModes[] = -{ - NExtraction::NOverwriteMode::kWithoutPrompt, - NExtraction::NOverwriteMode::kSkipExisting, - NExtraction::NOverwriteMode::kAutoRename, - NExtraction::NOverwriteMode::kAutoRenameExisting -}; - - -static const CSwitchForm kSwitchForms[kNumSwitches] = - { - { L"?", NSwitchType::kSimple, false }, - { L"H", NSwitchType::kSimple, false }, - { L"BD", NSwitchType::kSimple, false }, - { L"T", NSwitchType::kUnLimitedPostString, false, 1 }, - { L"Y", NSwitchType::kSimple, false }, - { L"P", NSwitchType::kUnLimitedPostString, false, 0 }, - { L"M", NSwitchType::kUnLimitedPostString, true, 1 }, - { L"O", NSwitchType::kUnLimitedPostString, false, 1 }, - { L"W", NSwitchType::kUnLimitedPostString, false, 0 }, - { L"I", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize}, - { L"X", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize}, - { L"U", NSwitchType::kUnLimitedPostString, true, 1}, - { L"R", NSwitchType::kPostChar, false, 0, 0, kRecursedPostCharSet }, - { L"SFX", NSwitchType::kUnLimitedPostString, false, 0 }, - { L"AO", NSwitchType::kPostChar, false, 1, 1, kOverwritePostCharSet} - }; - -static const int kNumCommandForms = 7; - -namespace NCommandType { -enum EEnum -{ - kAdd = 0, - kUpdate, - kDelete, - kTest, - kExtract, - kFullExtract, - kList -}; - -} - -static const CCommandForm g_CommandForms[kNumCommandForms] = -{ - { L"A", false }, - { L"U", false }, - { L"D", false }, - { L"T", false }, - { L"E", false }, - { L"X", false }, - { L"L", false } - // { "L", true } -}; - -static const NRecursedType::EEnum kCommandRecursedDefault[kNumCommandForms] = -{ - NRecursedType::kNonRecursed, - NRecursedType::kNonRecursed, - NRecursedType::kNonRecursed, - NRecursedType::kRecursed, - NRecursedType::kRecursed, - NRecursedType::kRecursed, - NRecursedType::kRecursed -}; - - -// ------------------------------------------------- -// Update area - -const UString kUpdatePairStateIDSet = L"PQRXYZW"; -const int kUpdatePairStateNotSupportedActions[] = {2, 2, 1, -1, -1, -1, -1}; - -const UString kUpdatePairActionIDSet = L"0123"; //Ignore, Copy, Compress - -const wchar_t *kUpdateIgnoreItselfPostStringID = L"-"; -const wchar_t kUpdateNewArchivePostCharID = '!'; - -static const bool kTestExtractRecursedDefault = true; -static const bool kAddRecursedDefault = false; - -static const int kMaxCmdLineSize = 1000; -static const wchar_t *kUniversalWildcard = L"*"; -static const int kMinNonSwitchWords = 2; -static const int kCommandIndex = 0; -static const int kArchiveNameIndex = kCommandIndex + 1; -static const int kFirstFileNameIndex = kArchiveNameIndex + 1; +" 4.20 Copyright (c) 1999-2005 Igor Pavlov 2005-05-30\n"; static const char *kHelpString = - "\nUsage: 7z <command> [<switches>...] <archive_name> [<file_names>...]\n" + "\nUsage: 7z" +#ifdef EXCLUDE_COM + "a" +#endif + " <command> [<switches>...] <archive_name> [<file_names>...]\n" " [<@listfiles...>]\n" "\n" "<Commands>\n" @@ -213,722 +77,243 @@ static const char *kHelpString = " u: Update files to archive\n" " x: eXtract files with full pathname\n" "<Switches>\n" - " -bd Disable percentage indicator\n" + " -ai[r[-|0]]{@listfile|!wildcard}: Include archives\n" + " -ax[r[-|0]]{@listfile|!wildcard}: eXclude archives\n" + " -bd: Disable percentage indicator\n" " -i[r[-|0]]{@listfile|!wildcard}: Include filenames\n" " -m{Parameters}: set compression Method\n" -// " -m0: store (no compression)\n" -// " -md<#>[b|k|m]: set Dictionary Size\n" -// " -mx: maXimize compression\n" " -o{Directory}: set Output directory\n" " -p{Password}: set Password\n" " -r[-|0]: Recurse subdirectories\n" " -sfx[{name}]: Create SFX archive\n" + " -si: read data from stdin\n" + " -so: write data to stdout\n" " -t{Type}: Set type of archive\n" + " -v{Size}}[b|k|m|g]: Create volumes\n" " -u[-][p#][q#][r#][x#][y#][z#][!newArchiveName]: Update options\n" " -w[{path}]: assign Work directory. Empty path means a temporary directory\n" " -x[r[-|0]]]{@listfile|!wildcard}: eXclude filenames\n" " -y: assume Yes on all queries\n"; - // --------------------------- // exception messages -static const char *kUserErrorMessage = "Incorrect command line"; // NExitCode::kUserError -static const char *kIncorrectListFile = "Incorrect wildcard in listfile"; -static const char *kIncorrectWildCardInListFile = "Incorrect wildcard in listfile"; -static const char *kIncorrectWildCardInCommandLine = "Incorrect wildcard in command line"; - static const char *kProcessArchiveMessage = " archive: "; +static const char *kEverythingIsOk = "Everything is Ok"; +static const char *kUserErrorMessage = "Incorrect command line"; // NExitCode::kUserError -// --------------------------- - -static const AString kExtractGroupProcessMessage = "Processing"; -static const AString kListingProcessMessage = "Listing"; - -static const AString kDefaultWorkingDirectory = ""; // test it maybemust be "." - -struct CArchiveCommand -{ - NCommandType::EEnum CommandType; - NRecursedType::EEnum DefaultRecursedType() const; - bool IsFromExtractGroup(NExtractMode::EEnum &extractMode) const; - bool IsFromUpdateGroup() const; -}; - -NRecursedType::EEnum CArchiveCommand::DefaultRecursedType() const -{ - return kCommandRecursedDefault[CommandType]; -} - -bool CArchiveCommand::IsFromExtractGroup(NExtractMode::EEnum &extractMode) const -{ - switch(CommandType) - { - case NCommandType::kTest: - extractMode = NExtractMode::kTest; - return true; - case NCommandType::kExtract: - extractMode = NExtractMode::kExtractToOne; - return true; - case NCommandType::kFullExtract: - extractMode = NExtractMode::kFullPath; - return true; - default: - return false; - } -} - -bool CArchiveCommand::IsFromUpdateGroup() const -{ - return (CommandType == NCommandType::kAdd || - CommandType == NCommandType::kUpdate || - CommandType == NCommandType::kDelete); -} +static const wchar_t *kDefaultSfxModule = L"7zCon.sfx"; -static NRecursedType::EEnum GetRecursedTypeFromIndex(int index) +static void PrintHelp(CStdOutStream &s) { - switch (index) - { - case NRecursedPostCharIndex::kWildCardRecursionOnly: - return NRecursedType::kWildCardOnlyRecursed; - case NRecursedPostCharIndex::kNoRecursion: - return NRecursedType::kNonRecursed; - default: - return NRecursedType::kRecursed; - } -} - -void PrintHelp(void) -{ - g_StdOut << kHelpString; + s << kHelpString; } -static void ShowMessageAndThrowException(LPCSTR message, NExitCode::EEnum code) +static void ShowMessageAndThrowException(CStdOutStream &s, LPCSTR message, NExitCode::EEnum code) { - g_StdOut << message << endl; + s << message << endl; throw code; } -static void PrintHelpAndExit() // yyy -{ - PrintHelp(); - ShowMessageAndThrowException(kUserErrorMessage, NExitCode::kUserError); -} - -static void PrintProcessTitle(const AString &processTitle, const UString &archiveName) +static void PrintHelpAndExit(CStdOutStream &s) // yyy { - g_StdOut << endl << processTitle << - kProcessArchiveMessage << archiveName << endl << endl; + PrintHelp(s); + ShowMessageAndThrowException(s, kUserErrorMessage, NExitCode::kUserError); } -bool ParseArchiveCommand(const UString &commandString, CArchiveCommand &command) +static void PrintProcessTitle(CStdOutStream &s, const AString &processTitle, const UString &archiveName) { - UString commandStringUpper = commandString; - commandStringUpper.MakeUpper(); - UString postString; - int commandIndex = ParseCommand(kNumCommandForms, g_CommandForms, commandStringUpper, - postString) ; - if (commandIndex < 0) - return false; - command.CommandType = (NCommandType::EEnum)commandIndex; - return true; + s << endl << processTitle << kProcessArchiveMessage << archiveName << endl << endl; } -// ------------------------------------------------------------------ -// filenames functions - -static bool TestIsPathLegal(const UString &name) +#ifndef _WIN32 +static void GetArguments(int numArguments, const char *arguments[], UStringVector &parts) { - if (name.Length() == 0) - return false; - if (name[0] == L'\\' || name[0] == L'/') - return false; - if (name.Length() < 3) - return true; - if (name[1] == L':' && name[2] == L'\\') - return false; - return true; -} - -static bool AddNameToCensor(NWildcard::CCensor &wildcardCensor, - const UString &name, bool include, NRecursedType::EEnum type) -{ - if (!TestIsPathLegal(name)) - throw "Can't use absolute paths"; - bool isWildCard = DoesNameContainWildCard(name); - bool recursed; - - switch (type) + parts.Clear(); + for(int i = 0; i < numArguments; i++) { - case NRecursedType::kWildCardOnlyRecursed: - recursed = isWildCard; - break; - case NRecursedType::kRecursed: - recursed = true; - break; - case NRecursedType::kNonRecursed: - recursed = false; - break; + UString s = MultiByteToUnicodeString(arguments[i]); + parts.Add(s); } - wildcardCensor.AddItem(name, include, recursed, isWildCard); - return true; -} - -static inline UINT GetCurrentCodePage() - { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; } - -void AddToCensorFromListFile(NWildcard::CCensor &wildcardCensor, - LPCWSTR fileName, bool include, NRecursedType::EEnum type) -{ - UStringVector names; - if (!ReadNamesFromListFile(GetSystemString(fileName, - GetCurrentCodePage()), names)) - ShowMessageAndThrowException(kIncorrectListFile, NExitCode::kUserError); - for (int i = 0; i < names.Size(); i++) - if (!AddNameToCensor(wildcardCensor, names[i], include, type)) - ShowMessageAndThrowException(kIncorrectWildCardInListFile, NExitCode::kUserError); -} - -void AddCommandLineWildCardToCensr(NWildcard::CCensor &wildcardCensor, - const UString &name, bool include, NRecursedType::EEnum type) -{ - if (!AddNameToCensor(wildcardCensor, name, include, type)) - ShowMessageAndThrowException(kIncorrectWildCardInCommandLine, NExitCode::kUserError); } - -void AddToCensorFromNonSwitchesStrings(NWildcard::CCensor &wildcardCensor, - const UStringVector &nonSwitchStrings, NRecursedType::EEnum type, - bool thereAreSwitchIncludeWildCards) -{ - int numNonSwitchStrings = nonSwitchStrings.Size(); - if(numNonSwitchStrings == kMinNonSwitchWords && (!thereAreSwitchIncludeWildCards)) - AddCommandLineWildCardToCensr(wildcardCensor, kUniversalWildcard, true, type); - for(int i = kFirstFileNameIndex; i < numNonSwitchStrings; i++) - { - const UString &s = nonSwitchStrings[i]; - if (s[0] == kFileListID) - AddToCensorFromListFile(wildcardCensor, s.Mid(1), true, type); - else - AddCommandLineWildCardToCensr(wildcardCensor, s, true, type); - } -} - -void AddSwitchWildCardsToCensor(NWildcard::CCensor &wildcardCensor, - const UStringVector &strings, bool include, - NRecursedType::EEnum commonRecursedType) -{ - for(int i = 0; i < strings.Size(); i++) - { - const UString &name = strings[i]; - NRecursedType::EEnum recursedType; - int pos = 0; - if (name.Length() < kSomeCludePostStringMinSize) - PrintHelpAndExit(); - if (::MyCharUpper(name[pos]) == kRecursedIDChar) - { - pos++; - int index = UString(kRecursedPostCharSet).Find(name[pos]); - recursedType = GetRecursedTypeFromIndex(index); - if (index >= 0) - pos++; - } - else - recursedType = commonRecursedType; - if (name.Length() < pos + kSomeCludeAfterRecursedPostStringMinSize) - PrintHelpAndExit(); - UString tail = name.Mid(pos + 1); - if (name[pos] == kImmediateNameID) - AddCommandLineWildCardToCensr(wildcardCensor, tail, include, recursedType); - else if (name[pos] == kFileListID) - AddToCensorFromListFile(wildcardCensor, tail, include, recursedType); - else - PrintHelpAndExit(); - } -} - -// ------------------------------------------------------ -// AddCommand functions - -static NUpdateArchive::NPairAction::EEnum GetUpdatePairActionType(int i) -{ - switch(i) - { - case NUpdateArchive::NPairAction::kIgnore: return NUpdateArchive::NPairAction::kIgnore; - case NUpdateArchive::NPairAction::kCopy: return NUpdateArchive::NPairAction::kCopy; - case NUpdateArchive::NPairAction::kCompress: return NUpdateArchive::NPairAction::kCompress; - case NUpdateArchive::NPairAction::kCompressAsAnti: return NUpdateArchive::NPairAction::kCompressAsAnti; - } - throw 98111603; -} - -bool ParseUpdateCommandString2(const UString &command, - NUpdateArchive::CActionSet &actionSet, UString &postString) -{ - for(int i = 0; i < command.Length();) - { - char c = MyCharUpper(command[i]); - int statePos = kUpdatePairStateIDSet.Find(c); - if (statePos < 0) - { - postString = command.Mid(i); - return true; - } - i++; - if (i >= command.Length()) - return false; - int actionPos = kUpdatePairActionIDSet.Find(::MyCharUpper(command[i])); - if (actionPos < 0) - return false; - actionSet.StateActions[statePos] = GetUpdatePairActionType(actionPos); - if (kUpdatePairStateNotSupportedActions[statePos] == actionPos) - return false; - i++; - } - postString.Empty(); - return true; -} - -UString MakeFullArchiveName(const UString &name, const UString &extension) -{ - if (extension.IsEmpty()) - return name; - if (name.IsEmpty()) - return name; - if (name[name.Length() - 1] == L'.') - return name.Left(name.Length() - 1); - int slash1Pos = name.ReverseFind(L'\\'); - int slash2Pos = name.ReverseFind(L'/'); - int slashPos = MyMax(slash1Pos, slash2Pos); - int dotPos = name.ReverseFind(L'.'); - if (dotPos >= 0 && (dotPos > slashPos || slashPos < 0)) - return name; - return name + L'.' + extension; -} - -void ParseUpdateCommandString(CUpdateArchiveOptions &options, - const UStringVector &updatePostStrings, - const NUpdateArchive::CActionSet &defaultActionSet, - const UString &extension) -{ - for(int i = 0; i < updatePostStrings.Size(); i++) - { - const UString &updateString = updatePostStrings[i]; - if(updateString.CompareNoCase(kUpdateIgnoreItselfPostStringID) == 0) - { - if(options.UpdateArchiveItself) - { - options.UpdateArchiveItself = false; - options.Commands.Delete(0); - } - } - else - { - NUpdateArchive::CActionSet actionSet = defaultActionSet; - - UString postString; - if (!ParseUpdateCommandString2(updateString, actionSet, postString)) - PrintHelpAndExit(); - if(postString.IsEmpty()) - { - if(options.UpdateArchiveItself) - { - options.Commands[0].ActionSet = actionSet; - } - } - else - { - if(MyCharUpper(postString[0]) != kUpdateNewArchivePostCharID) - PrintHelpAndExit(); - CUpdateArchiveCommand updateCommand; - - UString archivePath = postString.Mid(1); - - if (archivePath.IsEmpty()) - PrintHelpAndExit(); - updateCommand.ArchivePath = MakeFullArchiveName(archivePath, extension); - updateCommand.ActionSet = actionSet; - options.Commands.Add(updateCommand); - } - } - } -} - -static void SetAddCommandOptions(NCommandType::EEnum commandType, - const CParser &parser, - const UString &archivePath, - CUpdateArchiveOptions &options, UString &workingDir, - const UString &extension) -{ - NUpdateArchive::CActionSet defaultActionSet; - switch(commandType) - { - case NCommandType::kAdd: - defaultActionSet = NUpdateArchive::kAddActionSet; - break; - case NCommandType::kDelete: - defaultActionSet = NUpdateArchive::kDeleteActionSet; - break; - default: - defaultActionSet = NUpdateArchive::kUpdateActionSet; - } - - options.ArchivePath = archivePath; - options.UpdateArchiveItself = true; - - options.Commands.Clear(); - CUpdateArchiveCommand updateMainCommand; - updateMainCommand.ActionSet = defaultActionSet; - options.Commands.Add(updateMainCommand); - // options.ItselfActionSet = defaultActionSet; - if(parser[NKey::kUpdate].ThereIs) - ParseUpdateCommandString(options, parser[NKey::kUpdate].PostStrings, - defaultActionSet, extension); - if(parser[NKey::kWorkingDir].ThereIs) - { - const UString &postString = parser[NKey::kWorkingDir].PostStrings[0]; - if (postString.IsEmpty()) - NDirectory::MyGetTempPath(workingDir); - else - workingDir = postString; - } - else - { - if (!NDirectory::GetOnlyDirPrefix(archivePath, workingDir)) - throw "bad archive name"; - if (workingDir.IsEmpty()) - workingDir = L".\\"; - } - if(options.SfxMode = parser[NKey::kSfx].ThereIs) - { - UString moduleName = parser[NKey::kSfx].PostStrings[0]; - if (moduleName.IsEmpty()) - moduleName = kDefaultSfxModule; - if (!NDirectory::MySearchPath(NULL, moduleName, NULL, options.SfxModule)) - throw "can't find specified sfx module"; - } -} - -static const char kByteSymbol = 'B'; -static const char kKiloByteSymbol = 'K'; -static const char kMegaByteSymbol = 'M'; - -static void SetMethodOptions(const CParser &parser, - CUpdateArchiveOptions &options) -{ - if (parser[NKey::kProperty].ThereIs) - { - // options.MethodMode.Properties.Clear(); - for(int i = 0; i < parser[NKey::kProperty].PostStrings.Size(); i++) - { - CProperty property; - const UString &postString = parser[NKey::kProperty].PostStrings[i]; - int index = postString.Find(L'='); - if (index < 0) - property.Name = postString; - else - { - property.Name = postString.Left(index); - property.Value = postString.Mid(index + 1); - } - options.MethodMode.Properties.Add(property); - } - } -} - -static void MyOpenArhive(const UString &archiveName, - const NFind::CFileInfoW &archiveFileInfo, - #ifndef EXCLUDE_COM - HMODULE *module, - #endif - IInArchive **archiveHandler, - UString &defaultItemName, - bool &passwordEnabled, - UString &password) -{ - COpenCallbackImp *openCallbackSpec = new COpenCallbackImp; - CMyComPtr<IArchiveOpenCallback> openCallback = openCallbackSpec; - if (passwordEnabled) - { - openCallbackSpec->PasswordIsDefined = passwordEnabled; - openCallbackSpec->Password = password; - } - - UString fullName; - int fileNamePartStartIndex; - NFile::NDirectory::MyGetFullPathName(archiveName, fullName, fileNamePartStartIndex); - openCallbackSpec->LoadFileInfo( - fullName.Left(fileNamePartStartIndex), - fullName.Mid(fileNamePartStartIndex)); - - CArchiverInfo archiverInfo; - int subExtIndex; - HRESULT result = OpenArchive(archiveName, - #ifndef EXCLUDE_COM - module, - #endif - archiveHandler, - archiverInfo, - subExtIndex, - openCallback); - if (result == S_FALSE) - throw "file is not supported archive"; - if (result != S_OK) - throw "error"; - defaultItemName = GetDefaultName(archiveName, - archiverInfo.Extensions[subExtIndex].Extension, - archiverInfo.Extensions[subExtIndex].AddExtension); - passwordEnabled = openCallbackSpec->PasswordIsDefined; - password = openCallbackSpec->Password; -} - -#ifndef EXCLUDE_COM -void SetArchiveType(const UString &archiveType, - UString &filePath, CLSID &classID, UString &archiveExtension) -#else -void SetArchiveType(const UString &archiveType, - UString &formatName, UString &archiveExtension) #endif -{ - CObjectVector<CArchiverInfo> archiverInfoVector; - ReadArchiverInfoList(archiverInfoVector); - if (archiverInfoVector.Size() == 0) - throw "There are no installed archive handlers"; - if (archiveType.IsEmpty()) - throw "Incorrect archive type was assigned"; - for (int i = 0; i < archiverInfoVector.Size(); i++) - { - const CArchiverInfo &archiverInfo = archiverInfoVector[i]; - if (archiverInfo.Name.CompareNoCase(archiveType) == 0) - { - #ifndef EXCLUDE_COM - classID = archiverInfo.ClassID; - filePath = archiverInfo.FilePath; - #else - formatName = archiverInfo.Name; - - #endif - - archiveExtension = archiverInfo.GetMainExtension(); - return; - } - } - throw "Incorrect archive type was assigned"; -} -// int Main2(int numArguments, const char *arguments[]) -int Main2() +int Main2( + #ifndef _WIN32 + int numArguments, const char *arguments[] + #endif +) { + #ifdef _WIN32 SetFileApisToOEM(); + #endif - g_StdOut << kCopyrightString; - UStringVector commandStrings; + #ifdef _WIN32 NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings); + #else + GetArguments(numArguments, arguments, commandStrings); + #endif if(commandStrings.Size() == 1) { - PrintHelp(); + g_StdOut << kCopyrightString; + g_StdOut << kHelpString; return 0; } commandStrings.Delete(0); - CParser parser(kNumSwitches); - try - { - parser.ParseStrings(kSwitchForms, commandStrings); - } - catch(...) - { - PrintHelpAndExit(); - } + CArchiveCommandLineOptions options; - if(parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs) + CArchiveCommandLineParser parser; + + parser.Parse1(commandStrings, options); + + if(options.HelpMode) { - PrintHelp(); + g_StdOut << kCopyrightString; + PrintHelp(g_StdOut); return 0; } - const UStringVector &nonSwitchStrings = parser.NonSwitchStrings; - - int numNonSwitchStrings = nonSwitchStrings.Size(); - if(numNonSwitchStrings < kMinNonSwitchWords) - PrintHelpAndExit(); - CArchiveCommand command; - if (!ParseArchiveCommand(nonSwitchStrings[kCommandIndex], command)) - PrintHelpAndExit(); - - NRecursedType::EEnum recursedType; - if (parser[NKey::kRecursed].ThereIs) - recursedType = GetRecursedTypeFromIndex(parser[NKey::kRecursed].PostCharIndex); - else - recursedType = command.DefaultRecursedType(); - - NWildcard::CCensor wildcardCensor; - - bool thereAreSwitchIncludeWildCards; - if (parser[NKey::kInclude].ThereIs) - { - thereAreSwitchIncludeWildCards = true; - AddSwitchWildCardsToCensor(wildcardCensor, parser[NKey::kInclude].PostStrings, - true, recursedType); - } - else - thereAreSwitchIncludeWildCards = false; - if (parser[NKey::kExclude].ThereIs) - AddSwitchWildCardsToCensor(wildcardCensor, parser[NKey::kExclude].PostStrings, - false, recursedType); - - AddToCensorFromNonSwitchesStrings(wildcardCensor, nonSwitchStrings, recursedType, - thereAreSwitchIncludeWildCards); - - bool yesToAll = parser[NKey::kYes].ThereIs; + CStdOutStream &stdStream = options.StdOutMode ? g_StdErr : g_StdOut; + g_StdStream = &stdStream; - UString archiveName; - archiveName = nonSwitchStrings[kArchiveNameIndex]; + if (options.EnableHeaders) + stdStream << kCopyrightString; - NExtractMode::EEnum extractMode; - bool isExtractGroupCommand = command.IsFromExtractGroup(extractMode); + parser.Parse2(options); - bool passwordEnabled = parser[NKey::kPassword].ThereIs; - - UString password; - if(passwordEnabled) - password = parser[NKey::kPassword].PostStrings[0]; - - if(isExtractGroupCommand || command.CommandType == NCommandType::kList) + bool isExtractGroupCommand = options.Command.IsFromExtractGroup(); + if(isExtractGroupCommand || + options.Command.CommandType == NCommandType::kList) { - NFind::CFileInfoW archiveFileInfo; - if (!NFind::FindFile(archiveName, archiveFileInfo) || archiveFileInfo.IsDirectory()) - throw "there is no such archive"; - - if (archiveFileInfo.IsDirectory()) - throw "there is no such archive"; - - UString defaultItemName; - - #ifndef EXCLUDE_COM - NDLL::CLibrary library; - #endif - CMyComPtr<IInArchive> archiveHandler; - CArchiverInfo archiverInfo; - - MyOpenArhive(archiveName, archiveFileInfo, - #ifndef EXCLUDE_COM - &library, - #endif - &archiveHandler, - defaultItemName, passwordEnabled, password); - if(isExtractGroupCommand) { - PrintProcessTitle(kExtractGroupProcessMessage, archiveName); - UString outputDir; - if(parser[NKey::kOutputDir].ThereIs) + CExtractCallbackConsole *ecs = new CExtractCallbackConsole; + CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs; + + ecs->OutStream = &stdStream; + ecs->PasswordIsDefined = options.PasswordEnabled; + ecs->Password = options.Password; + ecs->Init(); + + COpenCallbackConsole openCallback; + openCallback.OutStream = &stdStream; + openCallback.PasswordIsDefined = options.PasswordEnabled; + openCallback.Password = options.Password; + + CExtractOptions eo; + eo.StdOutMode = options.StdOutMode; + eo.PathMode = options.Command.GetPathMode(); + eo.TestMode = options.Command.IsTestMode(); + eo.OverwriteMode = options.OverwriteMode; + eo.OutputDir = options.OutputDir; + eo.YesToAll = options.YesToAll; + HRESULT result = DecompressArchives( + options.ArchivePathsSorted, + options.ArchivePathsFullSorted, + options.WildcardCensor.Pairs.Front().Head, + eo, &openCallback, ecs); + + if (ecs->NumArchives > 1) { - outputDir = parser[NKey::kOutputDir].PostStrings[0]; // test this DirPath - NName::NormalizeDirPathPrefix(outputDir); + stdStream << endl << endl << "Total:" << endl; + stdStream << "Archives: " << ecs->NumArchives << endl; } - - NExtraction::NOverwriteMode::EEnum overwriteMode = - NExtraction::NOverwriteMode::kAskBefore; - if(parser[NKey::kOverwrite].ThereIs) - overwriteMode = k_OverwriteModes[parser[NKey::kOverwrite].PostCharIndex]; - - - CExtractOptions options(extractMode, outputDir, yesToAll, - passwordEnabled, password, overwriteMode); - options.DefaultItemName = defaultItemName; - options.ArchiveFileInfo = archiveFileInfo; - // options.ArchiveFileInfo = archiveFileInfo; - HRESULT result = DeCompressArchiveSTD(archiveHandler, wildcardCensor, options); - if (result != S_OK) + if (ecs->NumArchiveErrors != 0 || ecs->NumFileErrors != 0) { - return NExitCode::kErrorsDuringDecompression; + if (ecs->NumArchives > 1) + { + if (ecs->NumArchiveErrors != 0) + stdStream << "Archive Errors: " << ecs->NumArchiveErrors << endl; + if (ecs->NumFileErrors != 0) + stdStream << "Sub items Errors: " << ecs->NumFileErrors << endl; + } + return NExitCode::kFatalError; } + if (result != S_OK) + throw CSystemException(result); } else { - PrintProcessTitle(kListingProcessMessage, archiveName); - ListArchive(archiveHandler, defaultItemName, archiveFileInfo, - wildcardCensor/*, command.ListFullPathes, command.ListMode*/); + HRESULT result = ListArchives( + options.ArchivePathsSorted, + options.ArchivePathsFullSorted, + options.WildcardCensor.Pairs.Front().Head, + options.EnableHeaders, + options.PasswordEnabled, + options.Password); + if (result != S_OK) + throw CSystemException(result); } } - else if(command.IsFromUpdateGroup()) + else if(options.Command.IsFromUpdateGroup()) { - CUpdateArchiveOptions options; - - options.MethodMode.PasswordIsDefined = passwordEnabled && !password.IsEmpty(); - options.MethodMode.AskPassword = passwordEnabled && password.IsEmpty(); - options.MethodMode.Password = password; - UString workingDir; - UString archiveType; - if(parser[NKey::kArchiveType].ThereIs) - archiveType = parser[NKey::kArchiveType].PostStrings[0]; - else - archiveType = kDefaultArchiveType; + CUpdateOptions &uo = options.UpdateOptions; + if (uo.SfxMode && uo.SfxModule.IsEmpty()) + uo.SfxModule = kDefaultSfxModule; - UString extension; - if (!archiveType.IsEmpty()) - { - #ifndef EXCLUDE_COM - SetArchiveType(archiveType, options.MethodMode.FilePath, - options.MethodMode.ClassID1, extension); - #else - SetArchiveType(archiveType, options.MethodMode.Name, extension); - #endif - } - if(parser[NKey::kSfx].ThereIs) - extension = kSFXExtension; - archiveName = MakeFullArchiveName(archiveName, extension); + bool passwordIsDefined = + options.PasswordEnabled && !options.Password.IsEmpty(); - SetAddCommandOptions(command.CommandType, parser, archiveName, options, - workingDir, extension); - - SetMethodOptions(parser, options); + COpenCallbackConsole openCallback; + openCallback.OutStream = &stdStream; + openCallback.PasswordIsDefined = passwordIsDefined; + openCallback.Password = options.Password; - if (options.SfxMode) - { - CProperty property; - property.Name = L"rsfx"; - property.Value = L"on"; - options.MethodMode.Properties.Add(property); - } + CUpdateCallbackConsole callback; + callback.EnablePercents = options.EnablePercents; + callback.PasswordIsDefined = passwordIsDefined; + callback.AskPassword = options.PasswordEnabled && options.Password.IsEmpty(); + callback.Password = options.Password; + callback.StdOutMode = uo.StdOutMode; + callback.Init(&stdStream); + + CUpdateErrorInfo errorInfo; - NFind::CFileInfoW archiveFileInfo; - #ifndef EXCLUDE_COM - NDLL::CLibrary library; - #endif - CMyComPtr<IInArchive> archive; + HRESULT result = UpdateArchive( + options.WildcardCensor, uo, + errorInfo, &openCallback, &callback); - UString defaultItemName; - if (NFind::FindFile(archiveName, archiveFileInfo)) + if (result != S_OK) { - if (archiveFileInfo.IsDirectory()) - throw "there is no such archive"; - MyOpenArhive(archiveName, archiveFileInfo, - #ifndef EXCLUDE_COM - &library, - #endif - &archive, - defaultItemName, passwordEnabled, password); + stdStream << "\nError:\n"; + if (!errorInfo.Message.IsEmpty()) + stdStream << errorInfo.Message << endl; + if (!errorInfo.FileName.IsEmpty()) + stdStream << errorInfo.FileName << endl; + if (!errorInfo.FileName2.IsEmpty()) + stdStream << errorInfo.FileName2 << endl; + if (errorInfo.SystemError != 0) + stdStream << NError::MyFormatMessageW(errorInfo.SystemError) << endl; + throw CSystemException(result); } + int exitCode = NExitCode::kSuccess; + int numErrors = callback.FailedFiles.Size(); + if (numErrors == 0) + stdStream << kEverythingIsOk << endl; else - if (archiveType.IsEmpty()) - throw "type of archive is not specified"; - bool enableParcents = !parser[NKey::kDisablePercents].ThereIs; - if (enableParcents) { - if (!isatty(fileno(stdout))) - enableParcents = false; + stdStream << endl; + stdStream << "WARNINGS for files:" << endl << endl; + for (int i = 0; i < numErrors; i++) + { + stdStream << callback.FailedFiles[i] << " : "; + stdStream << NError::MyFormatMessageW(callback.FailedCodes[i]) << endl; + } + stdStream << "----------------" << endl; + stdStream << "WARNING: Cannot open " << numErrors << " file"; + if (numErrors > 1) + stdStream << "s"; + stdStream << endl; + exitCode = NExitCode::kWarning; } - HRESULT result = UpdateArchiveStdMain(wildcardCensor, options, workingDir, - archive, &defaultItemName, &archiveFileInfo, enableParcents); - if (result != S_OK) - throw NExitCode::CSystemError(result); + return exitCode; } else - PrintHelpAndExit(); + PrintHelpAndExit(stdStream); return 0; } diff --git a/7zip/UI/Console/MainAr.cpp b/7zip/UI/Console/MainAr.cpp index 8c612bd4..3af8cb8b 100755 --- a/7zip/UI/Console/MainAr.cpp +++ b/7zip/UI/Console/MainAr.cpp @@ -4,28 +4,34 @@ // #include <locale.h> -#include "Windows/COM.h" #include "Windows/Error.h" #include "Common/StdOutStream.h" #include "Common/NewHandler.h" +#include "Common/Exception.h" #include "Common/StringConvert.h" +#include "../Common/ExitCode.h" #include "ConsoleClose.h" -#include "ArError.h" using namespace NWindows; -// extern int Main2(int numArguments, const char *arguments[]); -extern int Main2(); +CStdOutStream *g_StdStream = 0; + +extern int Main2( + #ifndef _WIN32 + int numArguments, const char *arguments[] + #endif +); static const char *kExceptionErrorMessage = "\n\nError:\n"; static const char *kUserBreak = "\nBreak signaled\n"; -static const char *kMemoryExceptionMessage = "\n\nMemory Error! Can't allocate!\n"; +static const char *kMemoryExceptionMessage = "\n\nERROR: Can't allocate required memory!\n"; static const char *kUnknownExceptionMessage = "\n\nUnknown Error\n"; static const char *kInternalExceptionMessage = "\n\nInternal Error #"; +#ifdef UNICODE static inline bool IsItWindowsNT() { OSVERSIONINFO versionInfo; @@ -34,81 +40,100 @@ static inline bool IsItWindowsNT() return false; return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); } +#endif -int __cdecl main() -// int __cdecl main(int numArguments, const char *arguments[]) +int +#ifdef _MSC_VER +__cdecl +#endif +main +( +#ifndef _WIN32 +int numArguments, const char *arguments[] +#endif +) { + g_StdStream = &g_StdOut; #ifdef UNICODE if (!IsItWindowsNT()) { - g_StdOut << "This program requires Windows NT/2000/XP"; + (*g_StdStream) << "This program requires Windows NT/2000/XP/2003"; return NExitCode::kFatalError; } #endif // setlocale(LC_COLLATE, ".OCP"); - int result=1; - NCOM::CComInitializer comInitializer; + NConsoleClose::CCtrlHandlerSetter ctrlHandlerSetter; try { - NConsoleClose::CCtrlHandlerSetter aCtrlHandlerSetter; - try - { - // result = Main2(numArguments, arguments); - result = Main2(); - } - catch(const NConsoleClose::CCtrlBreakException &) - { - g_StdOut << endl << kUserBreak; - return (NExitCode::kUserBreak); - } + return Main2( +#ifndef _WIN32 + numArguments, arguments +#endif + ); } - catch(const CNewException) + catch(const CNewException &) { - g_StdOut << kMemoryExceptionMessage; + (*g_StdStream) << kMemoryExceptionMessage; return (NExitCode::kMemoryError); } - catch(const CSystemException &e) - { - g_StdOut << "System Error: " << (UINT64)(e.ErrorCode); - return (NExitCode::kFatalError); - } - catch(NExitCode::EEnum &aExitCode) + catch(const NConsoleClose::CCtrlBreakException &) { - g_StdOut << kInternalExceptionMessage << aExitCode << endl; - return (aExitCode); + (*g_StdStream) << endl << kUserBreak; + return (NExitCode::kUserBreak); } - catch(const NExitCode::CSystemError &systemError) + catch(const CSystemException &systemError) { + if (systemError.ErrorCode == E_OUTOFMEMORY) + { + (*g_StdStream) << kMemoryExceptionMessage; + return (NExitCode::kMemoryError); + } + if (systemError.ErrorCode == E_ABORT) + { + (*g_StdStream) << endl << kUserBreak; + return (NExitCode::kUserBreak); + } UString message; - NError::MyFormatMessage(systemError.ErrorValue, message); - g_StdOut << endl << endl << "System error:" << endl << + NError::MyFormatMessage(systemError.ErrorCode, message); + (*g_StdStream) << endl << endl << "System error:" << endl << message << endl; return (NExitCode::kFatalError); } + catch(NExitCode::EEnum &exitCode) + { + (*g_StdStream) << kInternalExceptionMessage << exitCode << endl; + return (exitCode); + } + /* catch(const NExitCode::CMultipleErrors &multipleErrors) { - g_StdOut << endl << multipleErrors.NumErrors << " errors" << endl; + (*g_StdStream) << endl << multipleErrors.NumErrors << " errors" << endl; return (NExitCode::kFatalError); } + */ catch(const UString &s) { - g_StdOut << kExceptionErrorMessage << s << endl; + (*g_StdStream) << kExceptionErrorMessage << s << endl; + return (NExitCode::kFatalError); + } + catch(const AString &s) + { + (*g_StdStream) << kExceptionErrorMessage << s << endl; return (NExitCode::kFatalError); } catch(const char *s) { - g_StdOut << kExceptionErrorMessage << s << endl; + (*g_StdStream) << kExceptionErrorMessage << s << endl; return (NExitCode::kFatalError); } catch(int t) { - g_StdOut << kInternalExceptionMessage << t << endl; + (*g_StdStream) << kInternalExceptionMessage << t << endl; return (NExitCode::kFatalError); } catch(...) { - g_StdOut << kUnknownExceptionMessage; + (*g_StdStream) << kUnknownExceptionMessage; return (NExitCode::kFatalError); } - return result; } diff --git a/7zip/UI/Console/OpenCallback.cpp b/7zip/UI/Console/OpenCallback.cpp deleted file mode 100755 index beefe38f..00000000 --- a/7zip/UI/Console/OpenCallback.cpp +++ /dev/null @@ -1,92 +0,0 @@ -// OpenCallback.cpp - -#include "StdAfx.h" - -#include "OpenCallback.h" - -#include "Common/StdOutStream.h" -#include "Common/StdInStream.h" -#include "Common/StringConvert.h" - -#include "../../Common/FileStreams.h" - -#include "Windows/PropVariant.h" - -#include "ConsoleClose.h" - -STDMETHODIMP COpenCallbackImp::SetTotal(const UINT64 *files, const UINT64 *bytes) -{ - if (NConsoleClose::TestBreakSignal()) - return E_ABORT; - return S_OK; -} - -STDMETHODIMP COpenCallbackImp::SetCompleted(const UINT64 *files, const UINT64 *bytes) -{ - if (NConsoleClose::TestBreakSignal()) - return E_ABORT; - return S_OK; -} - -STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value) -{ - NWindows::NCOM::CPropVariant propVariant; - switch(propID) - { - case kpidName: - propVariant = _fileInfo.Name; - break; - case kpidIsFolder: - propVariant = _fileInfo.IsDirectory(); - break; - case kpidSize: - propVariant = _fileInfo.Size; - break; - case kpidAttributes: - propVariant = (UINT32)_fileInfo.Attributes; - break; - case kpidLastAccessTime: - propVariant = _fileInfo.LastAccessTime; - break; - case kpidCreationTime: - propVariant = _fileInfo.CreationTime; - break; - case kpidLastWriteTime: - propVariant = _fileInfo.LastWriteTime; - break; - } - propVariant.Detach(value); - return S_OK; -} - -STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, - IInStream **inStream) -{ - *inStream = NULL; - UString fullPath = _folderPrefix + name; - if (!NWindows::NFile::NFind::FindFile(fullPath, _fileInfo)) - return S_FALSE; - if (_fileInfo.IsDirectory()) - return S_FALSE; - CInFileStream *inFile = new CInFileStream; - CMyComPtr<IInStream> inStreamTemp = inFile; - if (!inFile->Open(fullPath)) - return ::GetLastError(); - *inStream = inStreamTemp.Detach(); - return S_OK; -} - -STDMETHODIMP COpenCallbackImp::CryptoGetTextPassword(BSTR *password) -{ - if (!PasswordIsDefined) - { - g_StdOut << "\nEnter password:"; - AString oemPassword = g_StdIn.ScanStringUntilNewLine(); - Password = MultiByteToUnicodeString(oemPassword, CP_OEMCP); - PasswordIsDefined = true; - } - CMyComBSTR temp(Password); - *password = temp.Detach(); - return S_OK; -} - diff --git a/7zip/UI/Console/OpenCallback.h b/7zip/UI/Console/OpenCallback.h deleted file mode 100755 index a0064414..00000000 --- a/7zip/UI/Console/OpenCallback.h +++ /dev/null @@ -1,52 +0,0 @@ -// OpenCallback.h - -#pragma once - -#ifndef __OPENCALLBACK_H -#define __OPENCALLBACK_H - -#include "Common/String.h" -#include "Common/MyCom.h" -#include "Windows/FileFind.h" - -#include "../../Archive/IArchive.h" -#include "../../IPassword.h" - -class COpenCallbackImp: - public IArchiveOpenCallback, - public IArchiveOpenVolumeCallback, - public ICryptoGetTextPassword, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP2( - IArchiveOpenVolumeCallback, - ICryptoGetTextPassword - ) - - STDMETHOD(SetTotal)(const UINT64 *files, const UINT64 *bytes); - STDMETHOD(SetCompleted)(const UINT64 *files, const UINT64 *bytes); - - // IArchiveOpenVolumeCallback - STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value); - STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream); - - // ICryptoGetTextPassword - STDMETHOD(CryptoGetTextPassword)(BSTR *password); - -private: - UString _folderPrefix; - NWindows::NFile::NFind::CFileInfoW _fileInfo; -public: - bool PasswordIsDefined; - UString Password; - COpenCallbackImp(): PasswordIsDefined(false) {} - void LoadFileInfo(const UString &folderPrefix, const UString &fileName) - { - _folderPrefix = folderPrefix; - if (!NWindows::NFile::NFind::FindFile(_folderPrefix + fileName, _fileInfo)) - throw 1; - } -}; - -#endif diff --git a/7zip/UI/Console/OpenCallbackConsole.cpp b/7zip/UI/Console/OpenCallbackConsole.cpp new file mode 100755 index 00000000..f4833a2a --- /dev/null +++ b/7zip/UI/Console/OpenCallbackConsole.cpp @@ -0,0 +1,47 @@ +// OpenCallbackConsole.cpp + +#include "StdAfx.h" + +#include "OpenCallbackConsole.h" + +#include "ConsoleClose.h" +#include "UserInputUtils.h" + +HRESULT COpenCallbackConsole::CheckBreak() +{ + if (NConsoleClose::TestBreakSignal()) + return E_ABORT; + return S_OK; +} + +HRESULT COpenCallbackConsole::SetTotal(const UInt64 *files, const UInt64 *bytes) +{ + return CheckBreak(); +} + +HRESULT COpenCallbackConsole::SetCompleted(const UInt64 *files, const UInt64 *bytes) +{ + return CheckBreak(); +} + +HRESULT COpenCallbackConsole::CryptoGetTextPassword(BSTR *password) +{ + RINOK(CheckBreak()); + if (!PasswordIsDefined) + { + Password = GetPassword(OutStream); + PasswordIsDefined = true; + } + CMyComBSTR temp(Password); + *password = temp.Detach(); + return S_OK; +} + +HRESULT COpenCallbackConsole::GetPasswordIfAny(UString &password) +{ + if (PasswordIsDefined) + password = Password; + return S_OK; +} + + diff --git a/7zip/UI/Console/OpenCallbackConsole.h b/7zip/UI/Console/OpenCallbackConsole.h new file mode 100755 index 00000000..b01d4d88 --- /dev/null +++ b/7zip/UI/Console/OpenCallbackConsole.h @@ -0,0 +1,24 @@ +// OpenCallbackConsole.h + +#ifndef __OPENCALLBACKCONSOLE_H +#define __OPENCALLBACKCONSOLE_H + +#include "Common/StdOutStream.h" +#include "../Common/ArchiveOpenCallback.h" + +class COpenCallbackConsole: public IOpenCallbackUI +{ +public: + HRESULT CheckBreak(); + HRESULT SetTotal(const UInt64 *files, const UInt64 *bytes); + HRESULT SetCompleted(const UInt64 *files, const UInt64 *bytes); + HRESULT CryptoGetTextPassword(BSTR *password); + HRESULT GetPasswordIfAny(UString &password); + + CStdOutStream *OutStream; + bool PasswordIsDefined; + UString Password; + COpenCallbackConsole(): PasswordIsDefined(false) {} +}; + +#endif diff --git a/7zip/UI/Console/PercentPrinter.cpp b/7zip/UI/Console/PercentPrinter.cpp index 5e88ecbb..21fba7e0 100755 --- a/7zip/UI/Console/PercentPrinter.cpp +++ b/7zip/UI/Console/PercentPrinter.cpp @@ -2,7 +2,6 @@ #include "StdAfx.h" -#include "Common/StdOutStream.h" #include "Common/IntToString.h" #include "Common/String.h" @@ -14,7 +13,7 @@ static const char *kCloseString = "\b\b\b\b \b\b\b\b"; static const char *kPercentFormatString1 = "\b\b\b\b"; static const int kNumDigits = 3; -CPercentPrinter::CPercentPrinter(UINT64 minStepSize): +CPercentPrinter::CPercentPrinter(UInt64 minStepSize): m_MinStepSize(minStepSize), m_ScreenPos(0), m_StringIsPrinted(false) @@ -27,53 +26,51 @@ CPercentPrinter::CPercentPrinter(UINT64 minStepSize): void CPercentPrinter::PreparePrint() { if (m_ScreenPos < kNumPercentSpaces) - g_StdOut << (m_Spaces + m_ScreenPos); + (*OutStream) << (m_Spaces + m_ScreenPos); m_ScreenPos = kNumPercentSpaces; - g_StdOut << kPrepareString; + (*OutStream) << kPrepareString; } void CPercentPrinter::ClosePrint() { - g_StdOut << kCloseString; + (*OutStream) << kCloseString; m_StringIsPrinted = false; } void CPercentPrinter::PrintString(const char *s) { m_ScreenPos += MyStringLen(s); - g_StdOut << s; + (*OutStream) << s; } void CPercentPrinter::PrintString(const wchar_t *s) { m_ScreenPos += MyStringLen(s); - g_StdOut << s; + (*OutStream) << s; } void CPercentPrinter::PrintNewLine() { m_ScreenPos = 0; - g_StdOut << "\n"; + (*OutStream) << "\n"; m_StringIsPrinted = false; } -void CPercentPrinter::SetRatio(UINT64 doneValue) +void CPercentPrinter::SetRatio(UInt64 doneValue) { m_CurValue = doneValue; } void CPercentPrinter::RePrintRatio() { if (m_Total == 0) return; - UINT64 ratio = m_CurValue * 100 / m_Total; - // char temp[32]; - // sprintf(temp, kPercentFormatString, ratio); + UInt64 ratio = m_CurValue * 100 / m_Total; char temp[32 + kNumDigits] = " "; // for 4 digits; - ConvertUINT64ToString(ratio, temp + kNumDigits); - int len = lstrlenA(temp + kNumDigits); - lstrcatA(temp, "%"); + ConvertUInt64ToString(ratio, temp + kNumDigits); + int len = strlen(temp + kNumDigits); + strcat(temp, "%"); int pos = (len > kNumDigits)? kNumDigits : len; - g_StdOut << kPercentFormatString1; - g_StdOut << (temp + pos); + (*OutStream) << kPercentFormatString1; + (*OutStream) << (temp + pos); m_PrevValue = m_CurValue; m_StringIsPrinted = true; } diff --git a/7zip/UI/Console/PercentPrinter.h b/7zip/UI/Console/PercentPrinter.h index 15713fa9..0260cad2 100755 --- a/7zip/UI/Console/PercentPrinter.h +++ b/7zip/UI/Console/PercentPrinter.h @@ -1,25 +1,27 @@ // PercentPrinter.h -#pragma once - #ifndef __PERCENTPRINTER_H #define __PERCENTPRINTER_H #include "Common/Defs.h" +#include "Common/Types.h" +#include "Common/StdOutStream.h" const int kNumPercentSpaces = 70; class CPercentPrinter { - UINT64 m_MinStepSize; - UINT64 m_PrevValue; - UINT64 m_CurValue; - UINT64 m_Total; - UINT32 m_ScreenPos; + UInt64 m_MinStepSize; + UInt64 m_PrevValue; + UInt64 m_CurValue; + UInt64 m_Total; + UInt32 m_ScreenPos; char m_Spaces[kNumPercentSpaces + 1]; bool m_StringIsPrinted; public: - CPercentPrinter(UINT64 minStepSize = 1); - void SetTotal(UINT64 total) + CStdOutStream *OutStream; + + CPercentPrinter(UInt64 minStepSize = 1); + void SetTotal(UInt64 total) { m_Total = total; m_PrevValue = 0; @@ -30,7 +32,7 @@ public: void PrintNewLine(); void PreparePrint(); void ClosePrint(); - void SetRatio(UINT64 doneValue); + void SetRatio(UInt64 doneValue); void RePrintRatio(); void PrintRatio(); }; diff --git a/7zip/UI/Console/StdAfx.cpp b/7zip/UI/Console/StdAfx.cpp index 2550270c..d0feea85 100755 --- a/7zip/UI/Console/StdAfx.cpp +++ b/7zip/UI/Console/StdAfx.cpp @@ -1,3 +1,3 @@ // StdAfx.cpp -#include "stdafx.h" +#include "StdAfx.h" diff --git a/7zip/UI/Console/StdAfx.h b/7zip/UI/Console/StdAfx.h index f2d39704..92239aeb 100755 --- a/7zip/UI/Console/StdAfx.h +++ b/7zip/UI/Console/StdAfx.h @@ -1,16 +1,8 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#ifdef WIN32 -#include <windows.h> -#include <tchar.h> -#endif - -#include <stdio.h> -#include <time.h> - -#include <vector> +#include "../../../Common/MyWindows.h" #endif diff --git a/7zip/UI/Console/TempFiles.cpp b/7zip/UI/Console/TempFiles.cpp deleted file mode 100755 index 19793c08..00000000 --- a/7zip/UI/Console/TempFiles.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// TempFiles.cpp - -#include "StdAfx.h" - -#include "TempFiles.h" - -#include "Windows/FileDir.h" -#include "Windows/FileIO.h" - -using namespace NWindows; -using namespace NFile; - -void CFileVectorBundle::DisableDeleting(int index) -{ - m_FileNames.Delete(index); -} - -bool CFileVectorBundle::Add(const UString &filePath, bool tryToOpen) -{ - if (tryToOpen) - { - NIO::COutFile file; - if (!file.Open(filePath)) - return false; - } - m_FileNames.Add(filePath); - return true; -} - -void CFileVectorBundle::Clear() -{ - while(!m_FileNames.IsEmpty()) - { - NDirectory::DeleteFileAlways(m_FileNames.Back()); - m_FileNames.DeleteBack(); - } -} - - diff --git a/7zip/UI/Console/TempFiles.h b/7zip/UI/Console/TempFiles.h deleted file mode 100755 index b51276fd..00000000 --- a/7zip/UI/Console/TempFiles.h +++ /dev/null @@ -1,20 +0,0 @@ -// FileCreationUtils.h - -#pragma once - -#ifndef __FILECREATIONUTILS_H -#define __FILECREATIONUTILS_H - -#include "Common/String.h" - -class CFileVectorBundle -{ - UStringVector m_FileNames; -public: - ~CFileVectorBundle() { Clear(); } - bool Add(const UString &filePath, bool tryToOpen = true); - void DisableDeleting(int index); - void Clear(); -}; - -#endif diff --git a/7zip/UI/Console/Update.cpp b/7zip/UI/Console/Update.cpp deleted file mode 100755 index 4831e005..00000000 --- a/7zip/UI/Console/Update.cpp +++ /dev/null @@ -1,503 +0,0 @@ -// Update.cpp - -#include "StdAfx.h" - -#include "Update.h" - -#include "Common/StdOutStream.h" -#include "Common/StringConvert.h" -#include "Common/MyCom.h" - -#include "Windows/Defs.h" -#include "Windows/Error.h" -#include "Windows/FileDir.h" -#include "Windows/FileFind.h" -#include "Windows/FileName.h" -#include "Windows/PropVariant.h" -#include "Windows/PropVariantConversions.h" -#include "Windows/Error.h" - -#include "../../Common/FileStreams.h" -#include "../../Compress/Copy/CopyCoder.h" - -#include "../Common/DirItem.h" -#include "../Common/EnumDirItems.h" -#include "../Common/UpdateProduce.h" - -#include "TempFiles.h" -#include "ConsoleClose.h" -#include "UpdateCallback.h" - -#ifdef FORMAT_7Z -#include "../../Archive/7z/7zHandler.h" -#endif - -#ifdef FORMAT_BZIP2 -#include "../../Archive/BZip2/BZip2Handler.h" -#endif - -#ifdef FORMAT_GZIP -#include "../../Archive/GZip/GZipHandler.h" -#endif - -#ifdef FORMAT_TAR -#include "../../Archive/Tar/TarHandler.h" -#endif - -#ifdef FORMAT_ZIP -#include "../../Archive/Zip/ZipHandler.h" -#endif - -#ifndef EXCLUDE_COM -#include "../Common/HandlerLoader.h" -#endif - -static const char *kCreatingArchiveMessage = "Creating archive "; -static const char *kUpdatingArchiveMessage = "Updating archive "; -static const char *kScanningMessage = "Scanning"; -static const char *kNoFilesScannedMessage = "No files scanned"; -static const char *kTotalFilesAddedMessage = "Total files added to archive: "; - -using namespace NWindows; -using namespace NCOM; -using namespace NFile; -using namespace NName; - -static wchar_t *kTempArchiveFilePrefixString = L"7zi"; -static const char *kEverythingIsOk = "Everything is Ok"; - -static const char *kIllegalFileNameMessage = "Illegal file name for temp archive"; - -using namespace NUpdateArchive; - -static bool ParseNumberString(const UString &srcString, UINT32 &number) -{ - wchar_t *anEndPtr; - number = wcstoul(srcString, &anEndPtr, 10); - return (anEndPtr - srcString == srcString.Length()); -} - - -static HRESULT CopyBlock(ISequentialInStream *inStream, ISequentialOutStream *outStream) -{ - CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder; - return copyCoder->Code(inStream, outStream, NULL, NULL, NULL); -} - -HRESULT Compress( - const CActionSet &actionSet, - IInArchive *archive, - const CCompressionMethodMode &compressionMethod, - const UString &archiveName, - const CObjectVector<CArchiveItem> &archiveItems, - const CObjectVector<CDirItem> &dirItems, - bool enablePercents, - bool sfxMode, - const UString &sfxModule) -{ - #ifndef EXCLUDE_COM - CHandlerLoader loader; - #endif - - CMyComPtr<IOutArchive> outArchive; - if(archive != NULL) - { - CMyComPtr<IInArchive> archive2 = archive; - HRESULT result = archive2.QueryInterface(IID_IOutArchive, &outArchive); - if(result != S_OK) - { - throw "update operations are not supported for this archive"; - } - } - else - { - #ifndef EXCLUDE_COM - - HRESULT result = loader.CreateHandler(compressionMethod.FilePath, - compressionMethod.ClassID1, (void **)&outArchive, true); - - if (result != S_OK) - { - throw "update operations are not supported for this archive"; - return E_FAIL; - } - #endif - - #ifdef FORMAT_7Z - if (compressionMethod.Name.CompareNoCase(L"7z") == 0) - outArchive = new NArchive::N7z::CHandler; - #endif - - #ifdef FORMAT_BZIP2 - if (compressionMethod.Name.CompareNoCase(L"BZip2") == 0) - outArchive = new NArchive::NBZip2::CHandler; - #endif - - #ifdef FORMAT_GZIP - if (compressionMethod.Name.CompareNoCase(L"GZip") == 0) - outArchive = new NArchive::NGZip::CHandler; - #endif - - #ifdef FORMAT_TAR - if (compressionMethod.Name.CompareNoCase(L"Tar") == 0) - outArchive = new NArchive::NTar::CHandler; - #endif - - #ifdef FORMAT_ZIP - if (compressionMethod.Name.CompareNoCase(L"Zip") == 0) - outArchive = new NArchive::NZip::CHandler; - #endif - - - if (outArchive == 0) - { - throw "update operations are not supported for this archive"; - return E_FAIL; - } - } - - NFileTimeType::EEnum fileTimeType; - UINT32 value; - RINOK(outArchive->GetFileTimeType(&value)); - - switch(value) - { - case NFileTimeType::kWindows: - case NFileTimeType::kDOS: - case NFileTimeType::kUnix: - fileTimeType = NFileTimeType::EEnum(value); - break; - default: - return E_FAIL; - } - - CObjectVector<CUpdatePair> updatePairs; - GetUpdatePairInfoList(dirItems, archiveItems, fileTimeType, updatePairs); // must be done only once!!! - - CObjectVector<CUpdatePair2> operationChain; - UpdateProduce(dirItems, archiveItems, updatePairs, actionSet, - operationChain); - - CUpdateCallbackImp *updateCallbackSpec = new CUpdateCallbackImp; - CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec ); - - updateCallbackSpec->Init(&dirItems, &archiveItems, &operationChain, enablePercents, - compressionMethod.PasswordIsDefined, compressionMethod.Password, - compressionMethod.AskPassword); - - COutFileStream *outStreamSpec = new COutFileStream; - CMyComPtr<IOutStream> outStream(outStreamSpec); - - { - UString resultPath; - int pos; - if(! NFile::NDirectory::MyGetFullPathName(archiveName, resultPath, pos)) - throw 141716; - NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos)); - } - if (!outStreamSpec->Open(archiveName)) - { - UString message; - NError::MyFormatMessage(::GetLastError(), message); - g_StdOut << message << endl; - return E_FAIL; - } - - CMyComPtr<ISetProperties> setProperties; - if (outArchive.QueryInterface(IID_ISetProperties, &setProperties) == S_OK) - { - CObjectVector<CMyComBSTR> realNames; - std::vector<CPropVariant> values; - int i; - for(i = 0; i < compressionMethod.Properties.Size(); i++) - { - const CProperty &property = compressionMethod.Properties[i]; - NCOM::CPropVariant propVariant; - UINT32 number; - if (!property.Value.IsEmpty()) - { - if (ParseNumberString(property.Value, number)) - propVariant = number; - else - propVariant = property.Value; - } - CMyComBSTR comBSTR(property.Name); - realNames.Add(comBSTR); - values.push_back(propVariant); - } - std::vector<BSTR> names; - for(i = 0; i < realNames.Size(); i++) - names.push_back(realNames[i]); - - RINOK(setProperties->SetProperties(&names.front(), - &values.front(), names.size())); - } - - if (sfxMode) - { - CInFileStream *sfxStreamSpec = new CInFileStream; - CMyComPtr<IInStream> sfxStream(sfxStreamSpec); - if (!sfxStreamSpec->Open(sfxModule)) - throw "Can't open sfx module"; - RINOK(CopyBlock(sfxStream, outStream)); - } - - return outArchive->UpdateItems(outStream, operationChain.Size(), - updateCallback); -} - -static void EnumerateDirItems(const NWildcard::CCensorNode &curNode, - const UString &directory, - const UString &prefix, - bool checkNameFull, - CObjectVector<CDirItem> &dirItems, - bool enterToSubFolders) -{ - NConsoleClose::CheckCtrlBreak(); - - NFind::CEnumeratorW enumerator(directory + wchar_t(kAnyStringWildcard)); - NFind::CFileInfoW fileInfo; - while (enumerator.Next(fileInfo)) - { - NConsoleClose::CheckCtrlBreak(); - UString unicodeName = fileInfo.Name; - if (checkNameFull) - { - if (curNode.CheckNameFull(unicodeName)) - AddDirFileInfo(prefix, directory + fileInfo.Name, fileInfo, - dirItems); - } - else - { - if (curNode.CheckNameRecursive(unicodeName)) - AddDirFileInfo(prefix, directory + fileInfo.Name, fileInfo, - dirItems); - } - if (enterToSubFolders && fileInfo.IsDirectory()) - { - const NWildcard::CCensorNode *nextNode = &curNode; - if (checkNameFull) - { - nextNode = ((NWildcard::CCensorNode *)&curNode)->FindSubNode(unicodeName); - if (nextNode == NULL) - nextNode = &curNode; - } - EnumerateDirItems(*nextNode, - directory + fileInfo.Name + wchar_t(kDirDelimiter), - prefix + unicodeName + wchar_t(kDirDelimiter), - nextNode != (&curNode), dirItems, true); - } - } -} - -static void EnumerateItems(const NWildcard::CCensorNode &curNode, - const UString &directory, - const UString &prefix, - CObjectVector<CDirItem> &dirItems) -{ - NConsoleClose::CheckCtrlBreak(); - if (!curNode.GetAllowedRecursedNamesVector(false).IsEmpty() || - !curNode.GetAllowedRecursedNamesVector(true).IsEmpty()) - { - EnumerateDirItems(curNode, directory, prefix, true, dirItems, - true); - return; - } - if (!curNode.GetAllowedNamesVector(false, true).IsEmpty()) - { - EnumerateDirItems(curNode, directory, prefix, true, dirItems, - false); - } - else - { - const UStringVector &directNames = curNode.GetAllowedNamesVector(false, false); - for (int i = 0; i < directNames.Size(); i++) - { - const UString &nameSpec = directNames[i]; - if (curNode.CheckName(nameSpec, false, false)) - continue; - - NFind::CFileInfoW fileInfo; - if (!NFind::FindFile(directory + nameSpec, fileInfo)) - continue; - - AddDirFileInfo(prefix, directory + fileInfo.Name, fileInfo, dirItems); - } - } - for (int i = 0; i < curNode.SubNodes.Size(); i++) - { - const NWildcard::CCensorNode &nextNode = curNode.SubNodes[i]; - EnumerateItems(nextNode, - directory + nextNode.Name + wchar_t(kDirDelimiter), - prefix + nextNode.Name + wchar_t(kDirDelimiter), - dirItems); - } -} - -HRESULT GetFileTime(IInArchive *archive, UINT32 index, - FILETIME &fileTime, const FILETIME &defaultFileTime) -{ - CPropVariant property; - RINOK(archive->GetProperty(index, kpidLastWriteTime, &property)); - if (property.vt == VT_FILETIME) - fileTime = property.filetime; - else if (property.vt == VT_EMPTY) - fileTime = defaultFileTime; - else - throw 4190407; - return S_OK; -} - -HRESULT EnumerateInArchiveItems(const NWildcard::CCensor &censor, - IInArchive *archive, - const UString &defaultItemName, - const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo, - CObjectVector<CArchiveItem> &archiveItems) -{ - archiveItems.Clear(); - UINT32 numItems; - RINOK(archive->GetNumberOfItems(&numItems)); - archiveItems.Reserve(numItems); - for(UINT32 i = 0; i < numItems; i++) - { - CArchiveItem archiveItem; - NCOM::CPropVariant propVariantPath; - RINOK(archive->GetProperty(i, kpidPath, &propVariantPath)); - UString filePath; - if(propVariantPath.vt == VT_EMPTY) - archiveItem.Name = defaultItemName; - else - { - if(propVariantPath.vt != VT_BSTR) - return E_FAIL; - archiveItem.Name = propVariantPath.bstrVal; - } - archiveItem.Censored = censor.CheckName(archiveItem.Name); - - RINOK(GetFileTime(archive, i, archiveItem.LastWriteTime, - archiveFileInfo.LastWriteTime)); - - CPropVariant propertySize; - RINOK(archive->GetProperty(i, kpidSize, &propertySize)); - if (archiveItem.SizeIsDefined = (propertySize.vt != VT_EMPTY)) - archiveItem.Size = ConvertPropVariantToUINT64(propertySize); - - CPropVariant propertyIsFolder; - RINOK(archive->GetProperty(i, kpidIsFolder, &propertyIsFolder)); - if(propertyIsFolder.vt != VT_BOOL) - return E_FAIL; - archiveItem.IsDirectory = VARIANT_BOOLToBool(propertyIsFolder.boolVal); - - archiveItem.IndexInServer = i; - archiveItems.Add(archiveItem); - } - return S_OK; -} - - -static HRESULT UpdateWithItemLists( - const CUpdateArchiveOptions &options, - IInArchive *archive, - const CObjectVector<CArchiveItem> &archiveItems, - const CObjectVector<CDirItem> &dirItems, - bool enablePercents) -{ - for(int i = 0; i < options.Commands.Size(); i++) - { - const CUpdateArchiveCommand &command = options.Commands[i]; - const UString &realArchivePath = command.ArchivePath; - if (i == 0 && options.UpdateArchiveItself) - { - if(archive != 0) - g_StdOut << kUpdatingArchiveMessage; - else - g_StdOut << kCreatingArchiveMessage; - g_StdOut << options.ArchivePath; - } - else - g_StdOut << kCreatingArchiveMessage << realArchivePath; - - g_StdOut << endl << endl; - - RINOK(Compress(command.ActionSet, archive, - options.MethodMode, realArchivePath, - archiveItems, dirItems, enablePercents, - options.SfxMode, options.SfxModule)); - - g_StdOut << endl; - } - return S_OK; -} - -HRESULT UpdateArchiveStdMain(const NWildcard::CCensor &censor, - CUpdateArchiveOptions &options, const UString &workingDir, - IInArchive *archive, - const UString *defaultItemName, - const NWindows::NFile::NFind::CFileInfoW *archiveFileInfo, - bool enablePercents) -{ - CObjectVector<CDirItem> dirItems; - g_StdOut << kScanningMessage; - EnumerateItems(censor._head, L"", L"", dirItems); - g_StdOut << endl; - - CFileVectorBundle fileVectorBundle; - if(options.UpdateArchiveItself) - { - if (!NDirectory::MyGetTempFileName(workingDir, kTempArchiveFilePrefixString, - options.Commands[0].ArchivePath)) - throw "create temp file error"; - } - - int i; - for(i = 0; i < options.Commands.Size(); i++) - { - fileVectorBundle.Add(options.Commands[i].ArchivePath, - i > 0 || !options.UpdateArchiveItself); - // SetBanOnFile(censor,currentDir, options.Commands[i].ArchivePath); - } - g_StdOut << endl; - - CObjectVector<CArchiveItem> archiveItems; - if (archive != NULL) - { - RINOK(EnumerateInArchiveItems(censor, - archive, *defaultItemName, *archiveFileInfo, archiveItems)); - } - - RINOK(UpdateWithItemLists(options, archive, archiveItems, dirItems, enablePercents)); - - if (archive != NULL) - { - RINOK(archive->Close()); - } - - int firstNotTempArchiveIndex = options.UpdateArchiveItself ? 1 : 0; - for(i = options.Commands.Size() - 1; i >= firstNotTempArchiveIndex; i--) - fileVectorBundle.DisableDeleting(i); - if(options.UpdateArchiveItself) - { - try - { - if (archive != NULL) - if (!NDirectory::DeleteFileAlways(options.ArchivePath)) - throw "delete file error"; - - if (!NDirectory::MyMoveFile(options.Commands[0].ArchivePath, options.ArchivePath)) - { - g_StdOut << endl << "Error: "; - g_StdOut << NError::MyFormatMessage(::GetLastError()) << endl; - g_StdOut << options.Commands[0].ArchivePath << endl; - g_StdOut << options.ArchivePath << endl; - throw "move file error"; - } - } - catch(...) - { - fileVectorBundle.DisableDeleting(0); - throw; - } - } - g_StdOut << kEverythingIsOk << endl; - return S_OK; -} diff --git a/7zip/UI/Console/Update.h b/7zip/UI/Console/Update.h deleted file mode 100755 index 3db55d9d..00000000 --- a/7zip/UI/Console/Update.h +++ /dev/null @@ -1,41 +0,0 @@ -// Update.h - -#pragma once - -#ifndef __UPDATE_H -#define __UPDATE_H - -#include "Common/Wildcard.h" -#include "../Common/UpdateAction.h" -// #include "ProxyHandler.h" -#include "Windows/FileFind.h" -#include "../../Archive/IArchive.h" -#include "CompressionMode.h" - -struct CUpdateArchiveCommand -{ - UString ArchivePath; - NUpdateArchive::CActionSet ActionSet; -}; - -struct CUpdateArchiveOptions -{ - CObjectVector<CUpdateArchiveCommand> Commands; - bool UpdateArchiveItself; - - bool SfxMode; - UString SfxModule; - - UString ArchivePath; - CCompressionMethodMode MethodMode; -}; - - -HRESULT UpdateArchiveStdMain(const NWildcard::CCensor &censor, - CUpdateArchiveOptions &options, const UString &workingDir, - IInArchive *archive, - const UString *defaultItemName, - const NWindows::NFile::NFind::CFileInfoW *archiveFileInfo, - bool enablePercents); - -#endif diff --git a/7zip/UI/Console/UpdateCallback.cpp b/7zip/UI/Console/UpdateCallback.cpp deleted file mode 100755 index 744274db..00000000 --- a/7zip/UI/Console/UpdateCallback.cpp +++ /dev/null @@ -1,259 +0,0 @@ -// UpdateCallback.cpp - -#include "StdAfx.h" - -#include "UpdateCallback.h" - -#include "Common/StdInStream.h" -#include "Common/StdOutStream.h" -#include "Common/StringConvert.h" -#include "Common/Defs.h" -#include "Windows/PropVariant.h" - -#include "../../Common/FileStreams.h" -// #include "Interface/EnumStatProp.h" - -#include "ConsoleClose.h" - -CUpdateCallbackImp::CUpdateCallbackImp(): - m_PercentPrinter(1 << 16) {} - -void CUpdateCallbackImp::Init( - const CObjectVector<CDirItem> *dirItems, - const CObjectVector<CArchiveItem> *archiveItems, // test CItemInfoExList - CObjectVector<CUpdatePair2> *updatePairs, - bool enablePercents, - bool passwordIsDefined, - const UString &password, - bool askPassword) -{ - _passwordIsDefined = passwordIsDefined; - _password = password; - _askPassword = askPassword; - - m_EnablePercents = enablePercents; - m_DirItems = dirItems; - m_ArchiveItems = archiveItems; - m_UpdatePairs = updatePairs; - m_PercentCanBePrint = false; - m_NeedBeClosed = false; -} - -void CUpdateCallbackImp::Finilize() -{ - if (m_NeedBeClosed) - { - if (m_EnablePercents) - { - m_PercentPrinter.ClosePrint(); - m_PercentCanBePrint = false; - m_NeedBeClosed = false; - } - m_PercentPrinter.PrintNewLine(); - } -} - -STDMETHODIMP CUpdateCallbackImp::SetTotal(UINT64 size) -{ - if (m_EnablePercents) - m_PercentPrinter.SetTotal(size); - return S_OK; -} - -STDMETHODIMP CUpdateCallbackImp::SetCompleted(const UINT64 *completeValue) -{ - if (completeValue != NULL) - { - if (m_EnablePercents) - { - m_PercentPrinter.SetRatio(*completeValue); - if (m_PercentCanBePrint) - m_PercentPrinter.PrintRatio(); - } - } - - if (NConsoleClose::TestBreakSignal()) - return E_ABORT; - return S_OK; -} - -/* -STATPROPSTG kProperties[] = -{ - { NULL, kpidPath, VT_BSTR}, - { NULL, kpidIsFolder, VT_BOOL}, - { NULL, kpidSize, VT_UI8}, - { NULL, kpidLastAccessTime, VT_FILETIME}, - { NULL, kpidCreationTime, VT_FILETIME}, - { NULL, kpidLastWriteTime, VT_FILETIME}, - { NULL, kpidAttributes, VT_UI4}, - { NULL, kpidIsAnti, VT_BOOL} -}; -*/ - -STDMETHODIMP CUpdateCallbackImp::EnumProperties(IEnumSTATPROPSTG **enumerator) -{ - return E_NOTIMPL; - - /* - return CStatPropEnumerator::CreateEnumerator(kProperties, - sizeof(kProperties) / sizeof(kProperties[0]), enumerator); - */ -} - -STDMETHODIMP CUpdateCallbackImp::GetUpdateItemInfo(UINT32 index, - INT32 *newData, INT32 *newProperties, UINT32 *indexInArchive) -{ - if (NConsoleClose::TestBreakSignal()) - return E_ABORT; - const CUpdatePair2 &updatePair = (*m_UpdatePairs)[index]; - if(newData != NULL) - *newData = BoolToInt(updatePair.NewData); - if(newProperties != NULL) - *newProperties = BoolToInt(updatePair.NewProperties); - if(indexInArchive != NULL) - { - if (updatePair.ExistInArchive) - *indexInArchive = (*m_ArchiveItems)[updatePair.ArchiveItemIndex].IndexInServer; - else - *indexInArchive = UINT32(-1); - } - return S_OK; -} - -STDMETHODIMP CUpdateCallbackImp::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value) -{ - const CUpdatePair2 &updatePair = (*m_UpdatePairs)[index]; - NWindows::NCOM::CPropVariant propVariant; - - if (propID == kpidIsAnti) - { - propVariant = updatePair.IsAnti; - propVariant.Detach(value); - return S_OK; - } - - if (updatePair.IsAnti) - { - switch(propID) - { - case kpidIsFolder: - case kpidPath: - break; - case kpidSize: - propVariant = (UINT64)0; - propVariant.Detach(value); - return S_OK; - default: - propVariant.Detach(value); - return S_OK; - } - } - - if(updatePair.ExistOnDisk) - { - const CDirItem &dirItem = - (*m_DirItems)[updatePair.DirItemIndex]; - switch(propID) - { - case kpidPath: - propVariant = dirItem.Name; - break; - case kpidIsFolder: - propVariant = dirItem.IsDirectory(); - break; - case kpidSize: - propVariant = dirItem.Size; - break; - case kpidAttributes: - propVariant = dirItem.Attributes; - break; - case kpidLastAccessTime: - propVariant = dirItem.LastAccessTime; - break; - case kpidCreationTime: - propVariant = dirItem.CreationTime; - break; - case kpidLastWriteTime: - propVariant = dirItem.LastWriteTime; - break; - } - } - propVariant.Detach(value); - return S_OK; -} - -STDMETHODIMP CUpdateCallbackImp::GetStream(UINT32 index, - IInStream **inStream) -{ - const CUpdatePair2 &updatePair = (*m_UpdatePairs)[index]; - if(!updatePair.NewData) - return E_FAIL; - - if (NConsoleClose::TestBreakSignal()) - return E_ABORT; - - Finilize(); - - if(updatePair.IsAnti) - { - m_PercentPrinter.PrintString("Anti item "); - m_PercentPrinter.PrintString( - (*m_ArchiveItems)[updatePair.ArchiveItemIndex].Name); - } - else - { - const CDirItem &dirItem = - (*m_DirItems)[updatePair.DirItemIndex]; - - m_PercentPrinter.PrintString("Compressing "); - m_PercentPrinter.PrintString(dirItem.Name); - } - if (m_EnablePercents) - { - m_PercentCanBePrint = true; - m_PercentPrinter.PreparePrint(); - m_PercentPrinter.RePrintRatio(); - } - - if(updatePair.IsAnti) - return S_OK; - - const CDirItem &dirItem = - (*m_DirItems)[updatePair.DirItemIndex]; - - if(dirItem.IsDirectory()) - return S_OK; - - CInFileStream *inStreamSpec = new CInFileStream; - CMyComPtr<IInStream> inStreamLoc(inStreamSpec); - if(!inStreamSpec->Open(dirItem.FullPath)) - return ::GetLastError(); - *inStream = inStreamLoc.Detach(); - return S_OK; -} - -STDMETHODIMP CUpdateCallbackImp::SetOperationResult(INT32 operationResult) -{ - m_NeedBeClosed = true; - return S_OK; -} - - -STDMETHODIMP CUpdateCallbackImp::CryptoGetTextPassword2(INT32 *passwordIsDefined, BSTR *password) -{ - if (!_passwordIsDefined) - { - if (_askPassword) - { - g_StdOut << "\nEnter password:"; - AString oemPassword = g_StdIn.ScanStringUntilNewLine(); - _password = MultiByteToUnicodeString(oemPassword, CP_OEMCP); - _passwordIsDefined = true; - } - } - *passwordIsDefined = BoolToInt(_passwordIsDefined); - CMyComBSTR tempName(_password); - *password = tempName.Detach(); - return S_OK; -} diff --git a/7zip/UI/Console/UpdateCallback.h b/7zip/UI/Console/UpdateCallback.h deleted file mode 100755 index 1bc6b10f..00000000 --- a/7zip/UI/Console/UpdateCallback.h +++ /dev/null @@ -1,78 +0,0 @@ -// UpdateCallback.h - -#pragma once - -#ifndef __UPDATECALLBACK_H -#define __UPDATECALLBACK_H - -// #include "../Format/Common/ArchiveInterface.h" -#include "Common/MyCom.h" -#include "Common/String.h" - -#include "../../IPassword.h" - -#include "../Common/UpdatePair.h" -#include "../Common/UpdateProduce.h" - -#include "PercentPrinter.h" - -class CUpdateCallbackImp: - public IArchiveUpdateCallback, - public ICryptoGetTextPassword2, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP1(ICryptoGetTextPassword2) - - // IProfress - - STDMETHOD(SetTotal)(UINT64 size); - STDMETHOD(SetCompleted)(const UINT64 *completeValue); - - // IUpdateCallback - STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator); - STDMETHOD(GetUpdateItemInfo)(UINT32 index, - INT32 *newData, INT32 *newProperties, UINT32 *indexInArchive); - - STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value); - - STDMETHOD(GetStream)(UINT32 index, IInStream **inStream); - - STDMETHOD(SetOperationResult)(INT32 operationResult); - - STDMETHOD(CryptoGetTextPassword2)(INT32 *passwordIsDefined, BSTR *password); - -private: - const CObjectVector<CDirItem> *m_DirItems; - const CObjectVector<CArchiveItem> *m_ArchiveItems; - const CObjectVector<CUpdatePair2> *m_UpdatePairs; - - CPercentPrinter m_PercentPrinter; - - bool m_EnablePercents; - bool m_PercentCanBePrint; - bool m_NeedBeClosed; - - bool _passwordIsDefined; - UString _password; - bool _askPassword; - -public: - CUpdateCallbackImp(); - ~CUpdateCallbackImp() - { Finilize(); } - void Init( - const CObjectVector<CDirItem> *dirItems, - const CObjectVector<CArchiveItem> *archiveItems, // test CItemInfoExList - CObjectVector<CUpdatePair2> *updatePairs, - bool enablePercents, - bool passwordIsDefined, - const UString &password, - bool askPassword); - void Finilize(); -}; - - - - -#endif diff --git a/7zip/UI/Console/UpdateCallbackConsole.cpp b/7zip/UI/Console/UpdateCallbackConsole.cpp new file mode 100755 index 00000000..f12e7187 --- /dev/null +++ b/7zip/UI/Console/UpdateCallbackConsole.cpp @@ -0,0 +1,159 @@ +// UpdateCallbackConsole.cpp + +#include "StdAfx.h" + +#include "UpdateCallbackConsole.h" + +#include "Windows/Error.h" + +#include "ConsoleClose.h" +#include "UserInputUtils.h" + +using namespace NWindows; + +static const char *kCreatingArchiveMessage = "Creating archive "; +static const char *kUpdatingArchiveMessage = "Updating archive "; +static const char *kScanningMessage = "Scanning"; +static const char *kNoFilesScannedMessage = "No files scanned"; +static const char *kTotalFilesAddedMessage = "Total files added to archive: "; + +HRESULT CUpdateCallbackConsole::OpenResult(const wchar_t *name, HRESULT result) +{ + (*OutStream) << endl; + if (result != S_OK) + (*OutStream) << "Error: " << name << " is not supported archive" << endl; + return S_OK; +} + +HRESULT CUpdateCallbackConsole::StartScanning() +{ + (*OutStream) << kScanningMessage; + return S_OK; +} + +HRESULT CUpdateCallbackConsole::FinishScanning() +{ + (*OutStream) << endl << endl; + return S_OK; +} + +HRESULT CUpdateCallbackConsole::StartArchive(const wchar_t *name, bool updating) +{ + if(updating) + (*OutStream) << kUpdatingArchiveMessage; + else + (*OutStream) << kCreatingArchiveMessage; + if (name != 0) + (*OutStream) << name; + else + (*OutStream) << "StdOut"; + (*OutStream) << endl << endl; + return S_OK; +} + +HRESULT CUpdateCallbackConsole::FinishArchive() +{ + (*OutStream) << endl; + return S_OK; +} + +HRESULT CUpdateCallbackConsole::CheckBreak() +{ + if (NConsoleClose::TestBreakSignal()) + return E_ABORT; + return S_OK; +} + +HRESULT CUpdateCallbackConsole::Finilize() +{ + if (m_NeedBeClosed) + { + if (EnablePercents) + { + m_PercentPrinter.ClosePrint(); + m_PercentCanBePrint = false; + } + if (!StdOutMode) + m_PercentPrinter.PrintNewLine(); + m_NeedBeClosed = false; + } + return S_OK; +} + +HRESULT CUpdateCallbackConsole::SetTotal(UInt64 size) +{ + if (EnablePercents) + m_PercentPrinter.SetTotal(size); + return S_OK; +} + +HRESULT CUpdateCallbackConsole::SetCompleted(const UInt64 *completeValue) +{ + if (completeValue != NULL) + { + if (EnablePercents) + { + m_PercentPrinter.SetRatio(*completeValue); + if (m_PercentCanBePrint) + m_PercentPrinter.PrintRatio(); + } + } + if (NConsoleClose::TestBreakSignal()) + return E_ABORT; + return S_OK; +} + +HRESULT CUpdateCallbackConsole::GetStream(const wchar_t *name, bool isAnti) +{ + if (StdOutMode) + return S_OK; + if(isAnti) + m_PercentPrinter.PrintString("Anti item "); + else + m_PercentPrinter.PrintString("Compressing "); + m_PercentPrinter.PrintString(name); + if (EnablePercents) + { + m_PercentCanBePrint = true; + m_PercentPrinter.PreparePrint(); + m_PercentPrinter.RePrintRatio(); + } + return S_OK; +} + +HRESULT CUpdateCallbackConsole::OpenFileError(const wchar_t *name, DWORD systemError) +{ + FailedCodes.Add(systemError); + FailedFiles.Add(name); + // if (systemError == ERROR_SHARING_VIOLATION) + { + m_PercentPrinter.ClosePrint(); + m_PercentPrinter.PrintNewLine(); + m_PercentPrinter.PrintString("WARNING: "); + m_PercentPrinter.PrintString(NError::MyFormatMessageW(systemError)); + return S_FALSE; + } + return systemError; +} + +HRESULT CUpdateCallbackConsole::SetOperationResult(Int32 operationResult) +{ + m_NeedBeClosed = true; + return S_OK; +} + +HRESULT CUpdateCallbackConsole::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) +{ + if (!PasswordIsDefined) + { + if (AskPassword) + { + Password = GetPassword(OutStream); + PasswordIsDefined = true; + } + } + *passwordIsDefined = BoolToInt(PasswordIsDefined); + CMyComBSTR tempName(Password); + *password = tempName.Detach(); + return S_OK; +} diff --git a/7zip/UI/Console/UpdateCallbackConsole.h b/7zip/UI/Console/UpdateCallbackConsole.h new file mode 100755 index 00000000..d0e679ea --- /dev/null +++ b/7zip/UI/Console/UpdateCallbackConsole.h @@ -0,0 +1,68 @@ +// UpdateCallbackConsole.h + +#ifndef __UPDATECALLBACKCONSOLE_H +#define __UPDATECALLBACKCONSOLE_H + +#include "Common/String.h" +#include "Common/StdOutStream.h" +#include "PercentPrinter.h" +#include "../Common/Update.h" + +class CUpdateCallbackConsole: public IUpdateCallbackUI2 +{ + CPercentPrinter m_PercentPrinter; + bool m_PercentCanBePrint; + bool m_NeedBeClosed; + + CStdOutStream *OutStream; +public: + bool EnablePercents; + bool StdOutMode; + + bool PasswordIsDefined; + UString Password; + bool AskPassword; + + + CUpdateCallbackConsole(): + m_PercentPrinter(1 << 16), + PasswordIsDefined(false), + AskPassword(false), + StdOutMode(false), + EnablePercents(true) + {} + + ~CUpdateCallbackConsole() { Finilize(); } + void Init(CStdOutStream *outStream) + { + m_PercentCanBePrint = false; + m_NeedBeClosed = false; + FailedFiles.Clear(); + FailedCodes.Clear(); + OutStream = outStream; + m_PercentPrinter.OutStream = outStream; + } + + HRESULT OpenResult(const wchar_t *name, HRESULT result); + + HRESULT StartScanning(); + HRESULT FinishScanning(); + + HRESULT StartArchive(const wchar_t *name, bool updating); + HRESULT FinishArchive(); + + HRESULT CheckBreak(); + HRESULT Finilize(); + HRESULT SetTotal(UInt64 size); + HRESULT SetCompleted(const UInt64 *completeValue); + + HRESULT GetStream(const wchar_t *name, bool isAnti); + HRESULT OpenFileError(const wchar_t *name, DWORD systemError); + HRESULT SetOperationResult(Int32 operationResult); + HRESULT CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password); + + UStringVector FailedFiles; + CRecordVector<HRESULT> FailedCodes; +}; + +#endif diff --git a/7zip/UI/Console/UserInputUtils.cpp b/7zip/UI/Console/UserInputUtils.cpp index a32cd6f2..e8904a75 100755 --- a/7zip/UI/Console/UserInputUtils.cpp +++ b/7zip/UI/Console/UserInputUtils.cpp @@ -3,16 +3,16 @@ #include "StdAfx.h" #include "Common/StdInStream.h" -#include "Common/StdOutStream.h" +#include "Common/StringConvert.h" #include "UserInputUtils.h" -static const char kYes = 'Y'; -static const char kNo = 'N'; -static const char kYesAll = 'A'; -static const char kNoAll = 'S'; -static const char kAutoRename = 'U'; -static const char kQuit = 'Q'; +static const char kYes = 'Y'; +static const char kNo = 'N'; +static const char kYesAll = 'A'; +static const char kNoAll = 'S'; +static const char kAutoRename = 'U'; +static const char kQuit = 'Q'; static const char *kFirstQuestionMessage = "?\n"; static const char *kHelpQuestionMessage = @@ -22,12 +22,12 @@ static const char *kHelpQuestionMessage = // in: anAll // out: anAll, anYes; -NUserAnswerMode::EEnum ScanUserYesNoAllQuit() +NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream) { - g_StdOut << kFirstQuestionMessage; + (*outStream) << kFirstQuestionMessage; do { - g_StdOut << kHelpQuestionMessage; + (*outStream) << kHelpQuestionMessage; AString scannedString = g_StdIn.ScanStringUntilNewLine(); scannedString.Trim(); if(!scannedString.IsEmpty()) @@ -49,3 +49,10 @@ NUserAnswerMode::EEnum ScanUserYesNoAllQuit() } while(true); } + +UString GetPassword(CStdOutStream *outStream) +{ + (*outStream) << "\nEnter password:"; + AString oemPassword = g_StdIn.ScanStringUntilNewLine(); + return MultiByteToUnicodeString(oemPassword, CP_OEMCP); +} diff --git a/7zip/UI/Console/UserInputUtils.h b/7zip/UI/Console/UserInputUtils.h index dabd27ac..75c85ee6 100755 --- a/7zip/UI/Console/UserInputUtils.h +++ b/7zip/UI/Console/UserInputUtils.h @@ -1,10 +1,10 @@ // UserInputUtils.h -#pragma once - #ifndef __USERINPUTUTILS_H #define __USERINPUTUTILS_H +#include "Common/StdOutStream.h" + namespace NUserAnswerMode { enum EEnum @@ -18,6 +18,7 @@ enum EEnum }; } -NUserAnswerMode::EEnum ScanUserYesNoAllQuit(); +NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream); +UString GetPassword(CStdOutStream *outStream); #endif diff --git a/7zip/UI/Console/resource.rc b/7zip/UI/Console/resource.rc index 9670d79e..e5e08352 100755 --- a/7zip/UI/Console/resource.rc +++ b/7zip/UI/Console/resource.rc @@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,12,0,0 - PRODUCTVERSION 3,12,0,0 + FILEVERSION 4,20,0,0 + PRODUCTVERSION 4,20,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -85,14 +85,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Igor Pavlov\0" VALUE "FileDescription", "7-Zip Console version\0" - VALUE "FileVersion", "3, 12, 0, 0\0" + VALUE "FileVersion", "4, 20, 0, 0\0" VALUE "InternalName", "7z\0" - VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "7z.exe\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "7-Zip\0" - VALUE "ProductVersion", "3, 12, 0, 0\0" + VALUE "ProductVersion", "4, 20, 0, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/7zip/UI/Explorer/ContextMenu.cpp b/7zip/UI/Explorer/ContextMenu.cpp index 53071716..2d721d04 100755 --- a/7zip/UI/Explorer/ContextMenu.cpp +++ b/7zip/UI/Explorer/ContextMenu.cpp @@ -13,7 +13,6 @@ #include "Windows/FileFind.h" #include "Windows/FileDir.h" #include "Windows/FileName.h" -#include "Windows/System.h" #include "Windows/Thread.h" #include "Windows/Window.h" @@ -260,13 +259,18 @@ static UString GetSubFolderNameForExtract(const UString &archiveName) { int dotPos = archiveName.ReverseFind('.'); if (dotPos >= 0) - return archiveName.Left(dotPos); + { + UString res = archiveName.Left(dotPos); + res.TrimRight(); + return res; + } return archiveName + UString(L"~"); } STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT commandIDFirst, UINT commandIDLast, UINT flags) { + LoadLangOneTime(); if(_fileNames.Size() == 0) return E_FAIL; UINT currentCommandID = commandIDFirst; @@ -311,7 +315,6 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu, if(_fileNames.Size() == 1 && currentCommandID + 6 <= commandIDLast) { const UString &fileName = _fileNames.Front(); - UString folderPrefix; NFile::NDirectory::GetOnlyDirPrefix(fileName, folderPrefix); @@ -328,7 +331,28 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu, MyInsertMenu(popupMenu, subIndex++, currentCommandID++, GetSystemString(mainString)); _commandMap.push_back(commandMapItem); } - + } + } + + if(_fileNames.Size() > 0 && currentCommandID + 10 <= commandIDLast) + { + bool thereAreFolders = false; + for(int i = 0; i < _fileNames.Size(); i++) + { + NFile::NFind::CFileInfoW fileInfo; + if (!NFile::NFind::FindFile(_fileNames[i], fileInfo)) + return E_FAIL; + if (fileInfo.IsDirectory()) + thereAreFolders = true; + } + const UString &fileName = _fileNames.Front(); + if (!thereAreFolders) + { + UString folderPrefix; + NFile::NDirectory::GetOnlyDirPrefix(fileName, folderPrefix); + NFile::NFind::CFileInfoW fileInfo; + if (!NFile::NFind::FindFile(fileName, fileInfo)) + return E_FAIL; // Extract if ((contextMenuFlags & NContextMenuFlags::kExtract) != 0) { @@ -357,14 +381,17 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu, CCommandMapItem commandMapItem; UString s; FillCommand2(kExtractTo, s, commandMapItem); - UString folder = GetSubFolderNameForExtract(fileInfo.Name) + - UString(L'\\'); + UString folder; + if (_fileNames.Size() == 1) + folder = GetSubFolderNameForExtract(fileInfo.Name); + else + folder = L'*'; + folder += L'\\'; commandMapItem.Folder = folderPrefix + folder; s = MyFormatNew(s, folder); MyInsertMenu(popupMenu, subIndex++, currentCommandID++, GetSystemString(s)); _commandMap.push_back(commandMapItem); } - // Test if ((contextMenuFlags & NContextMenuFlags::kTest) != 0) { @@ -374,11 +401,6 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu, _commandMap.push_back(commandMapItem); } } - } - - if(_fileNames.Size() > 0 && currentCommandID + 6 <= commandIDLast) - { - const UString &fileName = _fileNames.Front(); UString archiveName = CreateArchiveName(fileName, _fileNames.Size() > 1, false); UString archiveName7z = archiveName + L".7z"; UString archivePathPrefix; @@ -388,7 +410,8 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu, if ((contextMenuFlags & NContextMenuFlags::kCompress) != 0) { CCommandMapItem commandMapItem; - commandMapItem.Archive = archivePathPrefix + archiveName; + commandMapItem.Folder = archivePathPrefix; + commandMapItem.Archive = archiveName; FillCommand(kCompress, mainString, commandMapItem); MyInsertMenu(popupMenu, subIndex++, currentCommandID++, GetSystemString(mainString)); _commandMap.push_back(commandMapItem); @@ -401,7 +424,8 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu, CCommandMapItem commandMapItem; UString s; FillCommand2(kCompressTo, s, commandMapItem); - commandMapItem.Archive = archivePathPrefix + archiveName7z; + commandMapItem.Folder = archivePathPrefix; + commandMapItem.Archive = archiveName7z; UString t = UString(L"\"") + archiveName7z + UString(L"\""); s = MyFormatNew(s, t); MyInsertMenu(popupMenu, subIndex++, currentCommandID++, GetSystemString(s)); @@ -609,20 +633,20 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo) params += L" \""; params += _fileNames[0]; params += L"\""; - MyCreateProcess(params); + MyCreateProcess(params, 0); break; } case kExtract: case kExtractHere: case kExtractTo: { - ExtractArchive(_fileNames[0], commandMapItem.Folder, + ExtractArchives(_fileNames, commandMapItem.Folder, (commandInternalID == kExtract)); break; } case kTest: { - TestArchive(_fileNames[0]); + TestArchives(_fileNames); break; } case kCompress: @@ -634,7 +658,8 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo) (commandInternalID == kCompressToEmail); bool showDialog = (commandInternalID == kCompress) || (commandInternalID == kCompressEmail); - CompressFiles(commandMapItem.Archive, _fileNames, email, showDialog); + CompressFiles(commandMapItem.Folder, commandMapItem.Archive, + _fileNames, email, showDialog); break; } } diff --git a/7zip/UI/Explorer/ContextMenu.h b/7zip/UI/Explorer/ContextMenu.h index 2dec9c80..3ee94227 100755 --- a/7zip/UI/Explorer/ContextMenu.h +++ b/7zip/UI/Explorer/ContextMenu.h @@ -1,7 +1,5 @@ // ContextMenu.h -#pragma once - #ifndef __CONTEXTMENU_H #define __CONTEXTMENU_H @@ -9,10 +7,14 @@ DEFINE_GUID(CLSID_CZipContextMenu, 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00); +#include <vector> + #include "Common/String.h" #include "../../FileManager/PluginInterface.h" + + class CZipContextMenu: public IContextMenu, public IShellExtInit, @@ -89,4 +91,4 @@ private: CCommandMapItem &commandMapItem); }; -#endif
\ No newline at end of file +#endif diff --git a/7zip/UI/Explorer/ContextMenuFlags.h b/7zip/UI/Explorer/ContextMenuFlags.h index 3e3bb5f3..b2f4a3a6 100755 --- a/7zip/UI/Explorer/ContextMenuFlags.h +++ b/7zip/UI/Explorer/ContextMenuFlags.h @@ -1,7 +1,5 @@ // ContextMenuFlags.h -#pragma once - #ifndef __SEVENZIP_CONTEXTMENUFLAGS_H #define __SEVENZIP_CONTEXTMENUFLAGS_H diff --git a/7zip/UI/Explorer/DllExports.cpp b/7zip/UI/Explorer/DllExports.cpp index 88f0ea58..ff481b9b 100755 --- a/7zip/UI/Explorer/DllExports.cpp +++ b/7zip/UI/Explorer/DllExports.cpp @@ -1,4 +1,4 @@ -// DLLExports.cpp : Implementation of DLL Exports. +// DLLExports.cpp #include "StdAfx.h" @@ -8,9 +8,9 @@ #include <ShlGuid.h> #include <windows.h> -// #include "../../Compress/Interface/CompressInterface.h" #include "../../IPassword.h" #include "../Agent/Agent.h" +#include "../../FileManager/LangUtils.h" #include "Common/ComTry.h" #include "ContextMenu.h" @@ -44,9 +44,9 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID) { // setlocale(LC_COLLATE, ".ACP"); - g_hInstance = hInstance; if (dwReason == DLL_PROCESS_ATTACH) { + g_hInstance = hInstance; #ifdef UNICODE if (!IsItWindowsNT()) return FALSE; @@ -56,7 +56,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID) } else if (dwReason == DLL_PROCESS_DETACH) _Module.Term(); - return TRUE; // ok + return TRUE; } ///////////////////////////////////////////////////////////////////////////// @@ -93,6 +93,7 @@ STDAPI CreateObject( const GUID *interfaceID, void **outObject) { + LoadLangOneTime(); COM_TRY_BEGIN *outObject = 0; if (*classID == CLSID_CAgentArchiveHandler) diff --git a/7zip/UI/Explorer/Explorer.dsp b/7zip/UI/Explorer/Explorer.dsp index f1c274bf..9f013046 100755 --- a/7zip/UI/Explorer/Explorer.dsp +++ b/7zip/UI/Explorer/Explorer.dsp @@ -182,6 +182,14 @@ SOURCE=.\StdAfx.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\Common\ArchiveExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveExtractCallback.h +# End Source File +# Begin Source File + SOURCE=..\Common\ArchiveName.cpp # End Source File # Begin Source File @@ -190,6 +198,14 @@ SOURCE=..\Common\ArchiveName.h # End Source File # Begin Source File +SOURCE=..\Common\ArchiveOpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveOpenCallback.h +# End Source File +# Begin Source File + SOURCE=..\Common\ArchiverInfo.cpp # End Source File # Begin Source File @@ -266,6 +282,14 @@ SOURCE=..\Common\UpdateAction.h # End Source File # Begin Source File +SOURCE=..\Common\UpdateCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateCallback.h +# End Source File +# Begin Source File + SOURCE=..\Common\UpdatePair.cpp # End Source File # Begin Source File @@ -396,14 +420,6 @@ SOURCE=..\Agent\AgentProxy.h # End Source File # Begin Source File -SOURCE=..\Agent\ArchiveExtractCallback.cpp -# End Source File -# Begin Source File - -SOURCE=..\Agent\ArchiveExtractCallback.h -# End Source File -# Begin Source File - SOURCE=..\Agent\ArchiveFolder.cpp # End Source File # Begin Source File @@ -416,39 +432,19 @@ SOURCE=..\Agent\ArchiveFolderOut.cpp # End Source File # Begin Source File -SOURCE=..\Agent\ArchiveUpdateCallback.cpp -# End Source File -# Begin Source File - -SOURCE=..\Agent\ArchiveUpdateCallback.h +SOURCE=..\Agent\IFileExtractCallback.h # End Source File # Begin Source File SOURCE=..\Agent\IFolderArchive.h # End Source File -# End Group -# Begin Group "Spec Interfaces" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\Format\Common\ArchiveInterface.h -# End Source File -# Begin Source File - -SOURCE=..\Common\ArchiveStyleDirItemInfo.h -# End Source File -# Begin Source File - -SOURCE=..\..\Compress\Interface\CompressInterface.h -# End Source File # Begin Source File -SOURCE=..\Common\FolderArchiveInterface.h +SOURCE=..\Agent\UpdateCallbackAgent.cpp # End Source File # Begin Source File -SOURCE=..\Format\Common\FormatCryptoInterface.h +SOURCE=..\Agent\UpdateCallbackAgent.h # End Source File # End Group # Begin Group "FileManager" @@ -507,6 +503,14 @@ SOURCE=..\..\FileManager\RegistryUtils.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\IntToString.cpp # End Source File # Begin Source File @@ -731,14 +735,6 @@ SOURCE=..\..\..\Windows\Synchronization.h # End Source File # Begin Source File -SOURCE=..\..\..\Windows\System.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\Windows\System.h -# End Source File -# Begin Source File - SOURCE=..\..\..\Windows\Window.cpp # End Source File # Begin Source File @@ -797,7 +793,7 @@ SOURCE=.\OptionsDialog.h # End Source File # Begin Source File -SOURCE=.\RegistryContextMenu..cpp +SOURCE=.\RegistryContextMenu.cpp # End Source File # Begin Source File diff --git a/7zip/UI/Explorer/FoldersPage/FoldersPage.h b/7zip/UI/Explorer/FoldersPage/FoldersPage.h index 66e899b5..e3f3b124 100755 --- a/7zip/UI/Explorer/FoldersPage/FoldersPage.h +++ b/7zip/UI/Explorer/FoldersPage/FoldersPage.h @@ -1,7 +1,5 @@ // FoldersPage.h -#pragma once - #ifndef __FOLDERSPAGE_H #define __FOLDERSPAGE_H diff --git a/7zip/UI/Explorer/MyMessages.h b/7zip/UI/Explorer/MyMessages.h index 4921bd6e..b3c02d74 100755 --- a/7zip/UI/Explorer/MyMessages.h +++ b/7zip/UI/Explorer/MyMessages.h @@ -1,7 +1,5 @@ // MyMessages.h -#pragma once - #ifndef __MYMESSAGES_H #define __MYMESSAGES_H diff --git a/7zip/UI/Explorer/OptionsDialog.h b/7zip/UI/Explorer/OptionsDialog.h index f0397011..7e85d357 100755 --- a/7zip/UI/Explorer/OptionsDialog.h +++ b/7zip/UI/Explorer/OptionsDialog.h @@ -1,7 +1,5 @@ // OptionsDialog.h -#pragma once - #ifndef __SEVENZIP_OPTIONSDIALOG_H #define __SEVENZIP_OPTIONSDIALOG_H diff --git a/7zip/UI/Explorer/RegistryContextMenu..cpp b/7zip/UI/Explorer/RegistryContextMenu.cpp index 21fdec23..db2d3868 100755 --- a/7zip/UI/Explorer/RegistryContextMenu..cpp +++ b/7zip/UI/Explorer/RegistryContextMenu.cpp @@ -6,7 +6,6 @@ #include "Windows/COM.h" #include "Windows/Synchronization.h" #include "Windows/Registry.h" -#include "Windows/System.h" #include "Windows/FileName.h" using namespace NWindows; diff --git a/7zip/UI/Explorer/RegistryContextMenu.h b/7zip/UI/Explorer/RegistryContextMenu.h index 06d493e1..3c2fb1ab 100755 --- a/7zip/UI/Explorer/RegistryContextMenu.h +++ b/7zip/UI/Explorer/RegistryContextMenu.h @@ -1,7 +1,5 @@ // RegistryContextMenu.h -#pragma once - #ifndef __REGISTRYCONTEXTMENU_H #define __REGISTRYCONTEXTMENU_H @@ -14,5 +12,4 @@ namespace NZipRootRegistry { // bool GetProgramDirPrefix(CSysString &folder); - -#endif
\ No newline at end of file +#endif diff --git a/7zip/UI/Explorer/StdAfx.h b/7zip/UI/Explorer/StdAfx.h index dfb7077f..fc42ac61 100755 --- a/7zip/UI/Explorer/StdAfx.h +++ b/7zip/UI/Explorer/StdAfx.h @@ -1,8 +1,11 @@ -// stdafx.h : include file for standard system include files, +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H +#define _WIN32_WINNT 0x0400 +// it's hack for Windows NT supporting +#define WINVER 0x0400 // #define _WIN32_IE 0x0500 #include <windows.h> @@ -27,14 +30,4 @@ extern CComModule _Module; #include <shlguid.h> #include <regstr.h> -// #include <new.h> - -#undef _MT - -#include <vector> -#include <map> -#include <algorithm> - -#define _MT - #endif diff --git a/7zip/UI/Explorer/SystemPage/SystemPage.cpp b/7zip/UI/Explorer/SystemPage/SystemPage.cpp index fe800532..0fdba63d 100755 --- a/7zip/UI/Explorer/SystemPage/SystemPage.cpp +++ b/7zip/UI/Explorer/SystemPage/SystemPage.cpp @@ -143,15 +143,16 @@ void CSystemPage::OnNotifyHelp() ShowHelpWindow(NULL, kSystemTopic); } -bool CSystemPage::OnButtonClicked(int aButtonID, HWND aButtonHWND) +bool CSystemPage::OnButtonClicked(int buttonID, HWND buttonHWND) { - switch(aButtonID) + switch(buttonID) { + case IDC_SYSTEM_CASCADED_MENU: case IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU: Changed(); return true; } - return CPropertyPage::OnButtonClicked(aButtonID, aButtonHWND); + return CPropertyPage::OnButtonClicked(buttonID, buttonHWND); } diff --git a/7zip/UI/Explorer/SystemPage/SystemPage.h b/7zip/UI/Explorer/SystemPage/SystemPage.h index 5fb148a4..a7de7c79 100755 --- a/7zip/UI/Explorer/SystemPage/SystemPage.h +++ b/7zip/UI/Explorer/SystemPage/SystemPage.h @@ -1,7 +1,5 @@ // SystemPage.h -#pragma once - #ifndef __SYSTEMPAGE_H #define __SYSTEMPAGE_H diff --git a/7zip/UI/Explorer/resource.rc b/7zip/UI/Explorer/resource.rc index 3c480e92..31e99e1a 100755 --- a/7zip/UI/Explorer/resource.rc +++ b/7zip/UI/Explorer/resource.rc @@ -68,8 +68,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,13,0,0 - PRODUCTVERSION 3,13,0,0 + FILEVERSION 4,20,0,0 + PRODUCTVERSION 4,20,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -87,14 +87,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Igor Pavlov\0" VALUE "FileDescription", "7-Zip Shell Extension\0" - VALUE "FileVersion", "3, 13, 0, 0\0" + VALUE "FileVersion", "4, 20, 0, 0\0" VALUE "InternalName", "7-zip\0" - VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "7-zip.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "7-Zip\0" - VALUE "ProductVersion", "3, 13, 0, 0\0" + VALUE "ProductVersion", "4, 20, 0, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/7zip/UI/Far/CompressEngine.cpp b/7zip/UI/Far/CompressEngine.cpp deleted file mode 100755 index bf5f57fc..00000000 --- a/7zip/UI/Far/CompressEngine.cpp +++ /dev/null @@ -1,347 +0,0 @@ -// CompressEngine.h - -#include "StdAfx.h" - -#include "ProxyHandler.h" -#include "CompressEngine.h" -#include "UpdateEngine.h" - -#include "../../Archiver/Common/CompressEngineCommon.h" -#include "../../Archiver/Common/OpenEngine2.h" -#include "../../Archiver/Common/UpdateProducer.h" -#include "../../Archiver/Common/UpdateUtils.h" - -#include "Windows/File/Name.h" -#include "Windows/File/Find.h" -#include "Windows/File/Directory.h" -#include "Windows/PropVariant.h" -#include "Windows/Error.h" - -#include "../../../WinWrappers/PropVariantConversions.h" - -// #include "CompressDialog.h" - -#include "Common/StringConvert.h" -// #include "ArchiveStyleDirItemInfo.h" - -#include "Interface/FileStreams.h" - -#include "Messages.h" -#include "Far/FarUtils.h" -// #include "ZipViewUtils.h" - -using namespace NWindows; -using namespace NFile; -using namespace NName; -using namespace NCOM; - -using namespace NFar; -using namespace NUpdateArchive; - -#define RETURN_IF_NOT_S_OK(x) { HRESULT aResult = (x); if(aResult != S_OK) return aResult; } - -static LPCTSTR kTempArcivePrefix = "7zi"; - -static void GetFileTime(CProxyHandler *aProxyHandler, LPCITEMIDLIST anItemIDList, - FILETIME &aFileTime) -{ - CPropVariant aProperty; - aProxyHandler->GetPropertyValue(anItemIDList, kaipidLastWriteTime, &aProperty); - if (aProperty.vt == VT_FILETIME) - aFileTime = aProperty.filetime; - else if (aProperty.vt == VT_EMPTY) - aFileTime = aProxyHandler->m_ArchiveFileInfo.LastWriteTime; - else - throw 4190407; -} - -void EnumerateInArchiveItems(CProxyHandler *aProxyHandler, - const CArchiveFolderItem &anItem, const UString &aPrefix, - CArchiveItemInfoVector &anArchiveItems) -{ - for(int i = 0; i < anItem.m_FileSubItems.Size(); i++) - { - const CArchiveFolderFileItem &aFileItem = anItem.m_FileSubItems[i]; - CArchiveItemInfo anItemInfo; - - GetFileTime(aProxyHandler, aFileItem.m_Properties, anItemInfo.LastWriteTime); - - CPropVariant aProperty; - aProxyHandler->GetPropertyValue(aFileItem.m_Properties, kaipidSize, &aProperty); - if (anItemInfo.SizeIsDefined = (aProperty.vt != VT_EMPTY)) - anItemInfo.Size = ConvertPropVariantToUINT64(aProperty); - anItemInfo.IsDirectory = false; - anItemInfo.Name = aPrefix + aFileItem.m_Name; - anItemInfo.Censored = true; // test it - anItemInfo.IndexInServer = aProxyHandler->GetHandlerItemIndex(aFileItem.m_Properties); - anArchiveItems.Add(anItemInfo); - } - for(i = 0; i < anItem.m_DirSubItems.Size(); i++) - { - const CArchiveFolderItem &aDirItem = anItem.m_DirSubItems[i]; - if(!aDirItem.m_IsLeaf) - continue; - CArchiveItemInfo anItemInfo; - GetFileTime(aProxyHandler, aDirItem.m_Properties, anItemInfo.LastWriteTime); - anItemInfo.IsDirectory = true; - anItemInfo.SizeIsDefined = false; - anItemInfo.Name = aPrefix + aDirItem.m_Name; - anItemInfo.Censored = true; // test it - anItemInfo.IndexInServer = aProxyHandler->GetHandlerItemIndex( - aDirItem.m_Properties); - anArchiveItems.Add(anItemInfo); - EnumerateInArchiveItems(aProxyHandler, aDirItem, anItemInfo.Name + - wchar_t(kDirDelimiter), anArchiveItems); - } -} - - -static const char *kExtension = _T(".zip"); - - -HRESULT Compress(const CSysStringVector &aFileNames, - const UString &anArchiveNamePrefix, - const CActionSet &anActionSet, CProxyHandler *aProxyHandler, - const CLSID &aClassID, bool aStoreMode, bool aMaximizeRatioMode, - CSysString &anArchiveName, CProgressBox *aProgressBox) -{ - CComPtr<IOutArchiveHandler> anOutArchive; - CArchiveItemInfoVector anArchiveItems; - if(aProxyHandler != NULL) - { - HRESULT aResult = aProxyHandler->m_ArchiveHandler.QueryInterface(&anOutArchive); - if(aResult != S_OK) - { - g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive); - return E_FAIL; - } - EnumerateInArchiveItems(aProxyHandler, - aProxyHandler->m_FolderItemHead, L"", anArchiveItems); - } - else - { - HRESULT aResult = anOutArchive.CoCreateInstance(aClassID); - if (aResult != S_OK) - { - g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive); - return E_FAIL; - } - } - CArchiveStyleDirItemInfoVector aDirItems; - - EnumerateItems(aFileNames, anArchiveNamePrefix, aDirItems, CP_OEMCP); - - CUpdatePairInfoVector anUpdatePairs; - - NFileTimeType::EEnum aFileTimeType; - UINT32 aValue; - RETURN_IF_NOT_S_OK(anOutArchive->GetFileTimeType(&aValue)); - - switch(aValue) - { - case NFileTimeType::kWindows: - case NFileTimeType::kDOS: - case NFileTimeType::kUnix: - aFileTimeType = NFileTimeType::EEnum(aValue); - break; - default: - return E_FAIL; - } - - GetUpdatePairInfoList(aDirItems, anArchiveItems, aFileTimeType, anUpdatePairs); - - CUpdatePairInfo2Vector anOperationChain; - UpdateProduce(aDirItems, anArchiveItems, anUpdatePairs, anActionSet, - anOperationChain); - - CComObjectNoLock<CUpdateCallBackImp> *anUpdateCallBackSpec = - new CComObjectNoLock<CUpdateCallBackImp>; - CComPtr<IUpdateCallBack> anUpdateCallBack(anUpdateCallBackSpec ); - - anUpdateCallBackSpec->Init(&aDirItems, &anArchiveItems, &anOperationChain, - aProgressBox); - - CComObjectNoLock<COutFileStream> *anOutStreamSpec = - new CComObjectNoLock<COutFileStream>; - CComPtr<IOutStream> anOutStream(anOutStreamSpec); - - { - CSysString aResultPath; - int aPos; - if(! NFile::NDirectory::MyGetFullPathName(anArchiveName, aResultPath, aPos)) - throw 141716; - NFile::NDirectory::CreateComplexDirectory(aResultPath.Left(aPos)); - } - if (!anOutStreamSpec->Open(anArchiveName)) - { - ShowLastErrorMessage(); - return E_FAIL; - } - - HRESULT aResult = anOutArchive->UpdateItems(anOutStream, anOperationChain.Size(), - BoolToMyBool(aStoreMode), BoolToMyBool(aMaximizeRatioMode), anUpdateCallBack); - return aResult; -} - - -// The returned string ends with a backslash - - -/* - -void CompressArchive(const CSysStringVector &aFileNames) -{ - if (aFileNames.Size() == 0) - return; - CSysString aResultPath; - { - CParsedPath aParsedPath; - aParsedPath.ParsePath(aFileNames.Front()); - if(aParsedPath.PathParts.Size() == 0) - return; // Error - if (aFileNames.Size() == 1 || aParsedPath.PathParts.Size() == 1) - { - CSysString aPureName, aDot, anExtension; - SplitNameToPureNameAndExtension(aParsedPath.PathParts.Back(), - aPureName, aDot, anExtension); - // aParsedPath.PathParts.Back() = aPureName; - // aResultPath = aParsedPath.MergePath(); - aResultPath = aPureName; - } - else - { - aParsedPath.PathParts.DeleteBack(); - // aResultPath = aParsedPath.MergePath(); - // aResultPath += NFile::NName::kDirDelimiter; - // aResultPath += aParsedPath.PathParts.Back(); - aResultPath = aParsedPath.PathParts.Back(); - } - aResultPath += kExtension; - } - CSysString aCurrentDir; - { - CParsedPath aParsedPath; - aParsedPath.ParsePath(aFileNames.Front()); - aParsedPath.PathParts.DeleteBack(); - aCurrentDir = aParsedPath.MergePath(); - if (aParsedPath.PathParts.Size() > 0) - aCurrentDir += NFile::NName::kDirDelimiter; - } - - - CCompressDialog aDialog; - - - - CZipRegistryManager aZipRegistryManager; - aDialog.m_ZipRegistryManager = &aZipRegistryManager; - - NZipRootRegistry::CArchiverInfoVector anArchiverInfoList; - NZipRootRegistry::ReadArchiverInfoList(anArchiverInfoList); - aDialog.m_ArchiverInfoList.Clear(); - for(int i = 0; i < anArchiverInfoList.Size(); i++) - { - NZipRootRegistry::CArchiverInfo anArchiverInfo = anArchiverInfoList[i]; - if (anArchiverInfo.UpdateEnabled) - aDialog.m_ArchiverInfoList.Add(anArchiverInfo); - } - if(aDialog.m_ArchiverInfoList.Size() == 0) - { - AfxMessageBox("No Update Engines"); - return; - } - - aDialog.m_Info.ArchiveName = aResultPath; - aDialog.m_Info.CurrentDirPrefix = aCurrentDir; - - if(aDialog.DoModal() != IDOK) - return; - - CSysString anArcPath; - if (!aDialog.m_Info.GetFullPathName(anArcPath)) - { - AfxMessageBox("Incorrect archive path");; - return; - } - const CActionSet *anActionSet; - switch(aDialog.m_Info.UpdateMode) - { - case NCompressDialog::NUpdateMode::kAdd: - anActionSet = &kAddActionSet; - break; - case NCompressDialog::NUpdateMode::kUpdate: - anActionSet = &kUpdateActionSet; - break; - case NCompressDialog::NUpdateMode::kFresh: - anActionSet = &kFreshActionSet; - break; - case NCompressDialog::NUpdateMode::kSynchronize: - anActionSet = &kSynchronizeActionSet; - break; - default: - throw 1091756; - } - - - NZipSettings::NWorkDir::CInfo aWorkDirInfo; - aZipRegistryManager.ReadWorkDirInfo(aWorkDirInfo); - CSysString aWorkDir = GetWorkDir(aWorkDirInfo, anArcPath); - NFile::NDirectory::CreateComplexDirectory(aWorkDir); - - NFile::NDirectory::CTempFile aTempFile; - CSysString aTempFileName; - if (aTempFile.Create(aWorkDir, kTempArcivePrefix, aTempFileName) == 0) - return; - - CProxyHandler *aProxyHandler; - NFind::CFileInfo aFileInfo; - if(NFind::FindFile(anArcPath, aFileInfo)) - { - if (aFileInfo.IsDirectory()) - { - CString aMessage; - AfxFormatString1(aMessage, IDS_CANT_UPDATE_ARCHIVE, anArcPath); - AfxMessageBox(aMessage); - return; - } - bool aHandlerIsNew; - if (!g_HandlersManager.GetProxyHandler(anArcPath, &aProxyHandler, aHandlerIsNew)) - { - CString aMessage; - AfxFormatString1(aMessage, IDS_CANT_UPDATE_ARCHIVE, anArcPath); - AfxMessageBox(aMessage); - return; - } - } - else - aProxyHandler = NULL; - - - HRESULT aResult = Compress(aFileNames, *anActionSet, aProxyHandler, - aDialog.m_ArchiverInfoList[aDialog.m_Info.ArchiverInfoIndex].ClassID, - aDialog.m_Info.Method == NCompressDialog::NMethod::kStore, - aDialog.m_Info.Method == NCompressDialog::NMethod::kMaximum, - aTempFileName); - if (aResult != S_OK) - { - ShowErrorMessage(aResult); - return; - } - if(aProxyHandler != 0) // Update - { - if (!NFile::NDirectory::DeleteFileAlways(anArcPath)) - { - ShowLastErrorMessage(); - return; - } - } - aTempFile.DisableDeleting(); - if (!MoveFile(aTempFileName, anArcPath)) - { - ShowLastErrorMessage(); - return; - } -} -*/ - - diff --git a/7zip/UI/Far/CompressEngine.h b/7zip/UI/Far/CompressEngine.h deleted file mode 100755 index 062286ef..00000000 --- a/7zip/UI/Far/CompressEngine.h +++ /dev/null @@ -1,23 +0,0 @@ -// CompressEngine.h - -#pragma once - -#ifndef __COMPRESSENGINE_H -#define __COMPRESSENGINE_H - -#include "Common/String.h" -#include "../../Archiver/Common/CompressEngineCommon.h" -#include "ProxyHandler.h" - -#include "Far/ProgressBox.h" - - -HRESULT Compress(const CSysStringVector &aFileNames, - const UString &anArchiveNamePrefix, - const NUpdateArchive::CActionSet &anActionSet, CProxyHandler *aProxyHandler, - const CLSID &aClassID, bool aStoreMode, bool aMaximizeRatioMode, - CSysString &anArchiveName, CProgressBox *aProgressBox); - -// void CompressArchive(const CSysStringVector &aFileNames); - -#endif diff --git a/7zip/UI/Far/ExtractEngine.cpp b/7zip/UI/Far/ExtractEngine.cpp index 90304d94..6140a242 100755 --- a/7zip/UI/Far/ExtractEngine.cpp +++ b/7zip/UI/Far/ExtractEngine.cpp @@ -2,18 +2,19 @@ #include "StdAfx.h" -#include "ExtractEngine.h" -#include "Far/FarUtils.h" - -#include "Messages.h" +#include <stdio.h> -#include "OverwriteDialog.h" +#include "ExtractEngine.h" -#include "Common/WildCard.h" +#include "Common/Wildcard.h" #include "Common/StringConvert.h" #include "Windows/Defs.h" +#include "FarUtils.h" +#include "Messages.h" +#include "OverwriteDialog.h" + using namespace NWindows; using namespace NFar; @@ -102,7 +103,7 @@ STDMETHODIMP CExtractCallBackImp::AskOverwrite( return S_OK; } -STDMETHODIMP CExtractCallBackImp::PrepareOperation(const wchar_t *name, INT32 askExtractMode) +STDMETHODIMP CExtractCallBackImp::PrepareOperation(const wchar_t *name, INT32 askExtractMode, const UINT64 *position) { m_CurrentFilePath = name; return S_OK; diff --git a/7zip/UI/Far/ExtractEngine.h b/7zip/UI/Far/ExtractEngine.h index eeed516f..b95b6ae8 100755 --- a/7zip/UI/Far/ExtractEngine.h +++ b/7zip/UI/Far/ExtractEngine.h @@ -1,17 +1,16 @@ // ExtractEngine.h -#pragma once - #ifndef __EXTRACTENGINE_H #define __EXTRACTENGINE_H #include "Common/MyCom.h" #include "Common/String.h" -#include "Far/ProgressBox.h" #include "../../IPassword.h" #include "../Agent/IFolderArchive.h" +#include "ProgressBox.h" + class CExtractCallBackImp: public IFolderArchiveExtractCallback, public ICryptoGetTextPassword, @@ -29,7 +28,7 @@ public: const wchar_t *existName, const FILETIME *existTime, const UINT64 *existSize, const wchar_t *newName, const FILETIME *newTime, const UINT64 *newSize, INT32 *result); - STDMETHOD (PrepareOperation)(const wchar_t *name, INT32 askExtractMode); + STDMETHOD (PrepareOperation)(const wchar_t *name, INT32 askExtractMode, const UINT64 *position); STDMETHOD(MessageError)(const wchar_t *message); STDMETHOD(SetOperationResult)(INT32 resultEOperationResult); diff --git a/7zip/UI/Far/Far.dsp b/7zip/UI/Far/Far.dsp index 0e6e0d10..1ecda11d 100755 --- a/7zip/UI/Far/Far.dsp +++ b/7zip/UI/Far/Far.dsp @@ -118,6 +118,14 @@ SOURCE=.\StdAfx.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\IntToString.cpp # End Source File # Begin Source File @@ -194,10 +202,6 @@ SOURCE=.\Plugin.h # End Source File # Begin Source File -SOURCE=.\PluginCommon.cpp -# End Source File -# Begin Source File - SOURCE=.\PluginDelete.cpp # End Source File # Begin Source File @@ -226,23 +230,23 @@ SOURCE=.\UpdateCallback100.h # PROP Default_Filter "" # Begin Source File -SOURCE=..\..\..\Far\FarPlugin.h +SOURCE=.\FarPlugin.h # End Source File # Begin Source File -SOURCE=..\..\..\Far\FarUtils.cpp +SOURCE=.\FarUtils.cpp # End Source File # Begin Source File -SOURCE=..\..\..\Far\FarUtils.h +SOURCE=.\FarUtils.h # End Source File # Begin Source File -SOURCE=..\..\..\Far\ProgressBox.cpp +SOURCE=.\ProgressBox.cpp # End Source File # Begin Source File -SOURCE=..\..\..\Far\ProgressBox.h +SOURCE=.\ProgressBox.h # End Source File # End Group # Begin Group "Windows" @@ -332,18 +336,26 @@ SOURCE=..\..\..\Windows\Synchronization.cpp SOURCE=..\..\..\Windows\Synchronization.h # End Source File +# End Group +# Begin Group "UI Common" + +# PROP Default_Filter "" # Begin Source File -SOURCE=..\..\..\Windows\System.cpp +SOURCE=..\Common\ArchiveExtractCallback.cpp # End Source File # Begin Source File -SOURCE=..\..\..\Windows\System.h +SOURCE=..\Common\ArchiveExtractCallback.h # End Source File -# End Group -# Begin Group "UI Common" +# Begin Source File -# PROP Default_Filter "" +SOURCE=..\Common\ArchiveOpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveOpenCallback.h +# End Source File # Begin Source File SOURCE=..\Common\ArchiverInfo.cpp @@ -382,6 +394,10 @@ SOURCE=..\Common\ExtractingFilePath.h # End Source File # Begin Source File +SOURCE=..\Common\ExtractMode.h +# End Source File +# Begin Source File + SOURCE=..\Common\HandlerLoader.h # End Source File # Begin Source File @@ -418,6 +434,14 @@ SOURCE=..\Common\UpdateAction.h # End Source File # Begin Source File +SOURCE=..\Common\UpdateCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateCallback.h +# End Source File +# Begin Source File + SOURCE=..\Common\UpdatePair.cpp # End Source File # Begin Source File @@ -474,23 +498,15 @@ SOURCE=..\Agent\AgentProxy.h # End Source File # Begin Source File -SOURCE=..\Agent\ArchiveExtractCallback.cpp -# End Source File -# Begin Source File - -SOURCE=..\Agent\ArchiveExtractCallback.h -# End Source File -# Begin Source File - -SOURCE=..\Agent\ArchiveUpdateCallback.cpp +SOURCE=..\Agent\IFolderArchive.h # End Source File # Begin Source File -SOURCE=..\Agent\ArchiveUpdateCallback.h +SOURCE=..\Agent\UpdateCallbackAgent.cpp # End Source File # Begin Source File -SOURCE=..\Agent\IFolderArchive.h +SOURCE=..\Agent\UpdateCallbackAgent.h # End Source File # End Group # Begin Group "Compress" diff --git a/7zip/UI/Far/Far.rc b/7zip/UI/Far/Far.rc index 8e7deeeb..1243d301 100755 --- a/7zip/UI/Far/Far.rc +++ b/7zip/UI/Far/Far.rc @@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,13,0,0 - PRODUCTVERSION 3,13,0,0 + FILEVERSION 4,20,0,0 + PRODUCTVERSION 4,20,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -85,14 +85,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Igor Pavlov\0" VALUE "FileDescription", "7-Zip FAR Plugin\0" - VALUE "FileVersion", "3, 13, 0, 0\0" + VALUE "FileVersion", "4, 20, 0, 0\0" VALUE "InternalName", "7-ZipFar\0" - VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "7-ZipFar.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "7-Zip\0" - VALUE "ProductVersion", "3, 13, 0, 0\0" + VALUE "ProductVersion", "4, 20, 0, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/Far/FarPlugin.h b/7zip/UI/Far/FarPlugin.h index 31e85c6c..9f1fbe24 100755 --- a/Far/FarPlugin.h +++ b/7zip/UI/Far/FarPlugin.h @@ -1,4 +1,7 @@ -#pragma once +// FarPlugin.h + +#ifndef __FARPLUGIN_H +#define __FARPLUGIN_H #if defined(__BORLANDC__) && (__BORLANDC <= 0x520) #pragma option -a1 @@ -562,3 +565,5 @@ enum OPERATION_MODES { #else #pragma pack(pop) #endif + +#endif diff --git a/7zip/UI/Far/FarUtils.cpp b/7zip/UI/Far/FarUtils.cpp new file mode 100755 index 00000000..11fb422c --- /dev/null +++ b/7zip/UI/Far/FarUtils.cpp @@ -0,0 +1,415 @@ +// FarUtils.cpp + +#include "StdAfx.h" + +#include "FarUtils.h" +#include "Common/DynamicBuffer.h" +#include "Common/StringConvert.h" +#include "Windows/Defs.h" +#include "Windows/Console.h" +#include "Windows/Error.h" + +using namespace NWindows; + +namespace NFar { + +CStartupInfo g_StartupInfo; + +void CStartupInfo::Init(const PluginStartupInfo &pluginStartupInfo, + const CSysString &pliginNameForRegestry) +{ + m_Data = pluginStartupInfo; + m_RegistryPath = pluginStartupInfo.RootKey; + m_RegistryPath += '\\'; + m_RegistryPath += pliginNameForRegestry; +} + +const char *CStartupInfo::GetMsgString(int messageId) +{ + return (const char*)m_Data.GetMsg(m_Data.ModuleNumber, messageId); +} + +int CStartupInfo::ShowMessage(unsigned int flags, + const char *helpTopic, const char **items, int numItems, int numButtons) +{ + return m_Data.Message(m_Data.ModuleNumber, flags, (char *)helpTopic, + (char **)items, numItems, numButtons); +} + +namespace NMessageID +{ + enum + { + kOk, + kCancel, + kWarning, + kError + }; +} + +int CStartupInfo::ShowMessage(const char *message) +{ + const char *messagesItems[]= { GetMsgString(NMessageID::kError), message, + GetMsgString(NMessageID::kOk) }; + return ShowMessage(FMSG_WARNING, NULL, messagesItems, + sizeof(messagesItems) / sizeof(messagesItems[0]), 1); +} + +int CStartupInfo::ShowMessage(int messageId) +{ + return ShowMessage(GetMsgString(messageId)); +} + +int CStartupInfo::ShowDialog(int X1, int Y1, int X2, int Y2, + const char *helpTopic, struct FarDialogItem *items, int numItems) +{ + return m_Data.Dialog(m_Data.ModuleNumber, X1, Y1, X2, Y2, (char *)helpTopic, + items, numItems); +} + +int CStartupInfo::ShowDialog(int sizeX, int sizeY, + const char *helpTopic, struct FarDialogItem *items, int numItems) +{ + return ShowDialog(-1, -1, sizeX, sizeY, helpTopic, items, numItems); +} + +inline static BOOL GetBOOLValue(bool v) { return (v? TRUE: FALSE); } + +void CStartupInfo::InitDialogItems(const CInitDialogItem *srcItems, + FarDialogItem *destItems, int numItems) +{ + for (int i = 0; i < numItems; i++) + { + const CInitDialogItem &srcItem = srcItems[i]; + FarDialogItem &destItem = destItems[i]; + + destItem.Type = srcItem.Type; + destItem.X1 = srcItem.X1; + destItem.Y1 = srcItem.Y1; + destItem.X2 = srcItem.X2; + destItem.Y2 = srcItem.Y2; + destItem.Focus = GetBOOLValue(srcItem.Focus); + if(srcItem.HistoryName != NULL) + destItem.Selected = int(srcItem.HistoryName); + else + destItem.Selected = GetBOOLValue(srcItem.Selected); + destItem.Flags = srcItem.Flags; + destItem.DefaultButton = GetBOOLValue(srcItem.DefaultButton); + + if(srcItem.DataMessageId < 0) + strcpy(destItem.Data, srcItem.DataString); + else + strcpy(destItem.Data, GetMsgString(srcItem.DataMessageId)); + + /* + if ((unsigned int)Init[i].Data < 0xFFF) + strcpy(destItem.Data, GetMsg((unsigned int)srcItem.Data)); + else + strcpy(destItem.Data,srcItem.Data); + */ + } +} + +// -------------------------------------------- + +HANDLE CStartupInfo::SaveScreen(int X1, int Y1, int X2, int Y2) +{ + return m_Data.SaveScreen(X1, Y1, X2, Y2); +} + +HANDLE CStartupInfo::SaveScreen() +{ + return SaveScreen(0, 0, -1, -1); +} + +void CStartupInfo::RestoreScreen(HANDLE handle) +{ + m_Data.RestoreScreen(handle); +} + +const char kRegestryKeyDelimiter = '\''; + +CSysString CStartupInfo::GetFullKeyName(const CSysString &keyName) const +{ + return (keyName.IsEmpty()) ? m_RegistryPath: + (m_RegistryPath + kRegestryKeyDelimiter + keyName); +} + + +LONG CStartupInfo::CreateRegKey(HKEY parentKey, + const CSysString &keyName, NRegistry::CKey &destKey) const +{ + return destKey.Create(parentKey, GetFullKeyName(keyName)); +} + +LONG CStartupInfo::OpenRegKey(HKEY parentKey, + const CSysString &keyName, NRegistry::CKey &destKey) const +{ + return destKey.Open(parentKey, GetFullKeyName(keyName)); +} + +void CStartupInfo::SetRegKeyValue(HKEY parentKey, const CSysString &keyName, + LPCTSTR valueName, LPCTSTR value) const +{ + NRegistry::CKey regKey; + CreateRegKey(parentKey, keyName, regKey); + regKey.SetValue(valueName, value); +} + +void CStartupInfo::SetRegKeyValue(HKEY parentKey, const CSysString &keyName, + LPCTSTR valueName, UINT32 value) const +{ + NRegistry::CKey regKey; + CreateRegKey(parentKey, keyName, regKey); + regKey.SetValue(valueName, value); +} + +void CStartupInfo::SetRegKeyValue(HKEY parentKey, const CSysString &keyName, + LPCTSTR valueName, bool value) const +{ + NRegistry::CKey regKey; + CreateRegKey(parentKey, keyName, regKey); + regKey.SetValue(valueName, value); +} + +CSysString CStartupInfo::QueryRegKeyValue(HKEY parentKey, const CSysString &keyName, + LPCTSTR valueName, const CSysString &valueDefault) const +{ + NRegistry::CKey regKey; + if (OpenRegKey(parentKey, keyName, regKey) != ERROR_SUCCESS) + return valueDefault; + + CSysString value; + if(regKey.QueryValue(valueName, value) != ERROR_SUCCESS) + return valueDefault; + + return value; +} + +UINT32 CStartupInfo::QueryRegKeyValue(HKEY parentKey, const CSysString &keyName, + LPCTSTR valueName, UINT32 valueDefault) const +{ + NRegistry::CKey regKey; + if (OpenRegKey(parentKey, keyName, regKey) != ERROR_SUCCESS) + return valueDefault; + + UINT32 value; + if(regKey.QueryValue(valueName, value) != ERROR_SUCCESS) + return valueDefault; + + return value; +} + +bool CStartupInfo::QueryRegKeyValue(HKEY parentKey, const CSysString &keyName, + LPCTSTR valueName, bool valueDefault) const +{ + NRegistry::CKey regKey; + if (OpenRegKey(parentKey, keyName, regKey) != ERROR_SUCCESS) + return valueDefault; + + bool value; + if(regKey.QueryValue(valueName, value) != ERROR_SUCCESS) + return valueDefault; + + return value; +} + +bool CStartupInfo::Control(HANDLE pluginHandle, int command, void *param) +{ + return BOOLToBool(m_Data.Control(pluginHandle, command, param)); +} + +bool CStartupInfo::ControlRequestActivePanel(int command, void *param) +{ + return Control(INVALID_HANDLE_VALUE, command, param); +} + +bool CStartupInfo::ControlGetActivePanelInfo(PanelInfo &panelInfo) +{ + return ControlRequestActivePanel(FCTL_GETPANELINFO, &panelInfo); +} + +bool CStartupInfo::ControlSetSelection(const PanelInfo &panelInfo) +{ + return ControlRequestActivePanel(FCTL_SETSELECTION, (void *)&panelInfo); +} + +bool CStartupInfo::ControlGetActivePanelCurrentItemInfo( + PluginPanelItem &pluginPanelItem) +{ + PanelInfo panelInfo; + if(!ControlGetActivePanelInfo(panelInfo)) + return false; + if(panelInfo.ItemsNumber <= 0) + throw "There are no items"; + pluginPanelItem = panelInfo.PanelItems[panelInfo.CurrentItem]; + return true; +} + +bool CStartupInfo::ControlGetActivePanelSelectedOrCurrentItems( + CObjectVector<PluginPanelItem> &pluginPanelItems) +{ + pluginPanelItems.Clear(); + PanelInfo panelInfo; + if(!ControlGetActivePanelInfo(panelInfo)) + return false; + if(panelInfo.ItemsNumber <= 0) + throw "There are no items"; + if (panelInfo.SelectedItemsNumber == 0) + pluginPanelItems.Add(panelInfo.PanelItems[panelInfo.CurrentItem]); + else + for (int i = 0; i < panelInfo.SelectedItemsNumber; i++) + pluginPanelItems.Add(panelInfo.SelectedItems[i]); + return true; +} + +bool CStartupInfo::ControlClearPanelSelection() +{ + PanelInfo panelInfo; + if(!ControlGetActivePanelInfo(panelInfo)) + return false; + for (int i = 0; i < panelInfo.ItemsNumber; i++) + panelInfo.PanelItems[i].Flags &= ~PPIF_SELECTED; + return ControlSetSelection(panelInfo); +} + +//////////////////////////////////////////////// +// menu function + +int CStartupInfo::Menu( + int x, + int y, + int maxHeight, + unsigned int flags, + const char *title, + const char *aBottom, + const char *helpTopic, + int *breakKeys, + int *breakCode, + struct FarMenuItem *items, + int numItems) +{ + return m_Data.Menu(m_Data.ModuleNumber, x, y, maxHeight, flags, (char *)title, + (char *)aBottom, (char *)helpTopic, breakKeys, breakCode, items, numItems); +} + +int CStartupInfo::Menu( + unsigned int flags, + const char *title, + const char *helpTopic, + struct FarMenuItem *items, + int numItems) +{ + return Menu(-1, -1, 0, flags, title, NULL, helpTopic, NULL, + NULL, items, numItems); +} + +int CStartupInfo::Menu( + unsigned int flags, + const char *title, + const char *helpTopic, + const CSysStringVector &items, + int selectedItem) +{ + CRecordVector<FarMenuItem> farMenuItems; + for(int i = 0; i < items.Size(); i++) + { + FarMenuItem item; + item.Checked = 0; + item.Separator = 0; + item.Selected = (i == selectedItem); + CSysString reducedString = + items[i].Left(sizeof(item.Text) / sizeof(item.Text[0]) - 1); + strcpy(item.Text, reducedString); + farMenuItems.Add(item); + } + return Menu(flags, title, helpTopic, &farMenuItems.Front(), farMenuItems.Size()); +} + + +////////////////////////////////// +// CScreenRestorer + +CScreenRestorer::~CScreenRestorer() +{ + Restore(); +} +void CScreenRestorer::Save() +{ + if(m_Saved) + return; + m_HANDLE = g_StartupInfo.SaveScreen(); + m_Saved = true; +} + +void CScreenRestorer::Restore() +{ + if(m_Saved) + { + g_StartupInfo.RestoreScreen(m_HANDLE); + m_Saved = false; + } +}; + +static CSysString DWORDToString(DWORD number) +{ + char buffer[32]; + ultoa(number, buffer, 10); + return buffer; +} + +void PrintErrorMessage(const char *message, int code) +{ + CSysString tmp = message; + tmp += " #"; + tmp += DWORDToString(code); + g_StartupInfo.ShowMessage(tmp); +} + +void PrintErrorMessage(const char *message, const char *text) +{ + CSysString tmp = message; + tmp += ": "; + tmp += text; + g_StartupInfo.ShowMessage(tmp); +} + +bool WasEscPressed() +{ + NConsole::CIn inConsole; + HANDLE handle = ::GetStdHandle(STD_INPUT_HANDLE); + if(handle == INVALID_HANDLE_VALUE) + return true; + inConsole.Attach(handle); + while (true) + { + DWORD numEvents; + if(!inConsole.GetNumberOfEvents(numEvents)) + return true; + if(numEvents == 0) + return false; + + INPUT_RECORD event; + if(!inConsole.ReadEvent(event, numEvents)) + return true; + if (event.EventType == KEY_EVENT && + event.Event.KeyEvent.bKeyDown && + event.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) + return true; + } +} + +void ShowErrorMessage(DWORD errorCode) +{ + CSysString message; + NError::MyFormatMessage(errorCode, message); + g_StartupInfo.ShowMessage(SystemStringToOemString(message)); + +} + +void ShowLastErrorMessage() +{ + ShowErrorMessage(::GetLastError()); +} + +} diff --git a/7zip/UI/Far/FarUtils.h b/7zip/UI/Far/FarUtils.h new file mode 100755 index 00000000..4fba193d --- /dev/null +++ b/7zip/UI/Far/FarUtils.h @@ -0,0 +1,185 @@ +// FarUtils.h + +#ifndef __FARUTILS_H +#define __FARUTILS_H + +#include "FarPlugin.h" +#include "Common/String.h" +#include "Common/Vector.h" +#include "Windows/Registry.h" + +namespace NFar { + +namespace NFileOperationReturnCode +{ + enum EEnum + { + kInterruptedByUser = -1, + kError = 0, + kSuccess = 1 + }; +} + +namespace NEditorReturnCode +{ + enum EEnum + { + kOpenError = 0, + kFileWasChanged = 1, + kFileWasNotChanged = 2, + kInterruptedByUser = 3 + }; +} + +struct CInitDialogItem +{ + DialogItemTypes Type; + int X1,Y1,X2,Y2; + bool Focus; + bool Selected; + unsigned int Flags; //FarDialogItemFlags Flags; + bool DefaultButton; + int DataMessageId; + const char *DataString; + const char *HistoryName; + // void InitToFarDialogItem(struct FarDialogItem &anItemDest); +}; + +class CStartupInfo +{ + PluginStartupInfo m_Data; + CSysString m_RegistryPath; + + CSysString GetFullKeyName(const CSysString &keyName) const; + LONG CreateRegKey(HKEY parentKey, + const CSysString &keyName, NWindows::NRegistry::CKey &destKey) const; + LONG OpenRegKey(HKEY parentKey, + const CSysString &keyName, NWindows::NRegistry::CKey &destKey) const; + +public: + void Init(const PluginStartupInfo &pluginStartupInfo, + const CSysString &pliginNameForRegestry); + const char *GetMsgString(int messageId); + int ShowMessage(unsigned int flags, const char *helpTopic, + const char **items, int numItems, int numButtons); + int ShowMessage(const char *message); + int ShowMessage(int messageId); + + int ShowDialog(int X1, int Y1, int X2, int Y2, + const char *helpTopic, struct FarDialogItem *items, int numItems); + int ShowDialog(int sizeX, int sizeY, + const char *helpTopic, struct FarDialogItem *items, int numItems); + + void InitDialogItems(const CInitDialogItem *srcItems, + FarDialogItem *destItems, int numItems); + + HANDLE SaveScreen(int X1, int Y1, int X2, int Y2); + HANDLE SaveScreen(); + void RestoreScreen(HANDLE handle); + + void SetRegKeyValue(HKEY parentKey, const CSysString &keyName, + const LPCTSTR valueName, LPCTSTR value) const; + void SetRegKeyValue(HKEY hRoot, const CSysString &keyName, + const LPCTSTR valueName, UINT32 value) const; + void SetRegKeyValue(HKEY hRoot, const CSysString &keyName, + const LPCTSTR valueName, bool value) const; + + CSysString QueryRegKeyValue(HKEY parentKey, const CSysString &keyName, + LPCTSTR valueName, const CSysString &valueDefault) const; + + UINT32 QueryRegKeyValue(HKEY parentKey, const CSysString &keyName, + LPCTSTR valueName, UINT32 valueDefault) const; + + bool QueryRegKeyValue(HKEY parentKey, const CSysString &keyName, + LPCTSTR valueName, bool valueDefault) const; + + bool Control(HANDLE plugin, int command, void *param); + bool ControlRequestActivePanel(int command, void *param); + bool ControlGetActivePanelInfo(PanelInfo &panelInfo); + bool ControlSetSelection(const PanelInfo &panelInfo); + bool ControlGetActivePanelCurrentItemInfo(PluginPanelItem &pluginPanelItem); + bool ControlGetActivePanelSelectedOrCurrentItems( + CObjectVector<PluginPanelItem> &pluginPanelItems); + + bool ControlClearPanelSelection(); + + int Menu( + int x, + int y, + int maxHeight, + unsigned int flags, + const char *title, + const char *aBottom, + const char *helpTopic, + int *breakKeys, + int *breakCode, + FarMenuItem *items, + int numItems); + int Menu( + unsigned int flags, + const char *title, + const char *helpTopic, + FarMenuItem *items, + int numItems); + + int Menu( + unsigned int flags, + const char *title, + const char *helpTopic, + const CSysStringVector &items, + int selectedItem); + + int Editor(const char *fileName, const char *title, + int X1, int Y1, int X2, int Y2, DWORD flags, int startLine, int startChar) + { return m_Data.Editor((char *)fileName, (char *)title, X1, Y1, X2, Y2, + flags, startLine, startChar); } + int Editor(const char *fileName) + { return Editor(fileName, NULL, 0, 0, -1, -1, 0, -1, -1); } + + int Viewer(const char *fileName, const char *title, + int X1, int Y1, int X2, int Y2, DWORD flags) + { return m_Data.Viewer((char *)fileName, (char *)title, X1, Y1, X2, Y2, flags); } + int Viewer(const char *fileName) + { return Viewer(fileName, NULL, 0, 0, -1, -1, VF_NONMODAL); } + +}; + +class CScreenRestorer +{ + bool m_Saved; + HANDLE m_HANDLE; +public: + CScreenRestorer(): m_Saved(false){}; + ~CScreenRestorer(); + void Save(); + void Restore(); +}; + + +extern CStartupInfo g_StartupInfo; + +void PrintErrorMessage(const char *message, int code); +void PrintErrorMessage(const char *message, const char *aText); + +#define MY_TRY_BEGIN try\ + { + +#define MY_TRY_END1(x) }\ + catch(int n) { PrintErrorMessage(x, n); return; }\ + catch(const CSysString &s) { PrintErrorMessage(x, s); return; }\ + catch(const char *s) { PrintErrorMessage(x, s); return; }\ + catch(...) { g_StartupInfo.ShowMessage(x); return; } + +#define MY_TRY_END2(x, y) }\ + catch(int n) { PrintErrorMessage(x, n); return y; }\ + catch(const CSysString &s) { PrintErrorMessage(x, s); return y; }\ + catch(const char *s) { PrintErrorMessage(x, s); return y; }\ + catch(...) { g_StartupInfo.ShowMessage(x); return y; } + +bool WasEscPressed(); +void ShowErrorMessage(DWORD errorCode); +void ShowLastErrorMessage(); + +} + +#endif diff --git a/7zip/UI/Far/Main.cpp b/7zip/UI/Far/Main.cpp index 5a74bfe1..d27cc059 100755 --- a/7zip/UI/Far/Main.cpp +++ b/7zip/UI/Far/Main.cpp @@ -7,7 +7,7 @@ #include "Plugin.h" -#include "Common/WildCard.h" +#include "Common/Wildcard.h" #include "Common/DynamicBuffer.h" #include "Common/StringConvert.h" #include "Common/Defs.h" @@ -17,18 +17,16 @@ #include "Windows/FileDir.h" #include "Windows/Defs.h" -#include "Far/FarUtils.h" -#include "Far/ProgressBox.h" - -#include "Messages.h" - +#include "../../IPassword.h" #include "../../Common/FileStreams.h" #include "../Common/DefaultName.h" #include "../Common/OpenArchive.h" #include "../Agent/Agent.h" -// #include "../../Compress/Interface/CompressInterface.h" -#include "../../IPassword.h" + +#include "ProgressBox.h" +#include "FarUtils.h" +#include "Messages.h" using namespace NWindows; using namespace NFar; @@ -249,6 +247,8 @@ STDMETHODIMP COpenArchiveCallback::SetCompleted(const UINT64 *completed) STDMETHODIMP COpenArchiveCallback::GetStream(const wchar_t *name, IInStream **inStream) { + if (WasEscPressed()) + return E_ABORT; *inStream = NULL; UString fullPath = _folderPrefix + name; if (!NWindows::NFile::NFind::FindFile(fullPath, _fileInfo)) @@ -297,6 +297,8 @@ STDMETHODIMP COpenArchiveCallback::GetProperty(PROPID propID, PROPVARIANT *value HRESULT GetPassword(UString &password) { + if (WasEscPressed()) + return E_ABORT; password.Empty(); CInitDialogItem initItems[]= { @@ -396,7 +398,11 @@ static HANDLE MyOpenFilePlugin(const char *name) archiverInfoResult, defaultName, openArchiveCallback); */ if (result != S_OK) - return INVALID_HANDLE_VALUE; + { + if (result == E_ABORT) + return (HANDLE)-2; + return INVALID_HANDLE_VALUE; + } // ::OutputDebugString("after OpenArchive\n"); diff --git a/7zip/UI/Far/Messages.h b/7zip/UI/Far/Messages.h index ed156fd2..a0f1098c 100755 --- a/7zip/UI/Far/Messages.h +++ b/7zip/UI/Far/Messages.h @@ -1,7 +1,5 @@ // SevenZip/ Messages.h -#pragma once - #ifndef __SEVENZIP_MESSAGES_H #define __SEVENZIP_MESSAGES_H @@ -47,6 +45,7 @@ enum EEnum kGroup, kBlock, kComment, + kPosition, kGetPasswordTitle, kEnterPasswordForFile, diff --git a/7zip/UI/Far/OverwriteDialog.cpp b/7zip/UI/Far/OverwriteDialog.cpp index 1da2b2ef..028fff4e 100755 --- a/7zip/UI/Far/OverwriteDialog.cpp +++ b/7zip/UI/Far/OverwriteDialog.cpp @@ -1,16 +1,19 @@ -// OverwriteDialog.cpp : implementation file +// OverwriteDialog.cpp #include "StdAfx.h" +#include <stdio.h> + #include "OverwriteDialog.h" +#include "Common/String.h" +#include "Common/StringConvert.h" + #include "Windows/FileName.h" #include "Windows/Defs.h" #include "Windows/PropVariantConversions.h" -#include "Common/String.h" -#include "Common/StringConvert.h" -#include "Far/FarUtils.h" +#include "FarUtils.h" #include "Messages.h" using namespace NWindows; @@ -45,7 +48,7 @@ void SetFileInfoStrings(const CFileInfo &fileInfo, FILETIME localFileTime; if (!FileTimeToLocalFileTime(&fileInfo.Time, &localFileTime)) throw 4190402; - UString timeString = ConvertFileTimeToString2(localFileTime); + UString timeString = ConvertFileTimeToString(localFileTime); fileInfoStrings.Time = g_StartupInfo.GetMsgString(NMessageID::kOverwriteModifiedOn); fileInfoStrings.Time += " "; diff --git a/7zip/UI/Far/OverwriteDialog.h b/7zip/UI/Far/OverwriteDialog.h index 577d5702..ff1a480e 100755 --- a/7zip/UI/Far/OverwriteDialog.h +++ b/7zip/UI/Far/OverwriteDialog.h @@ -1,7 +1,5 @@ // OverwriteDialog.h -#pragma once - #ifndef OVERWRITEDIALOG_H #define OVERWRITEDIALOG_H diff --git a/7zip/UI/Far/Plugin.cpp b/7zip/UI/Far/Plugin.cpp index 8b4af589..e16c6cf8 100755 --- a/7zip/UI/Far/Plugin.cpp +++ b/7zip/UI/Far/Plugin.cpp @@ -4,21 +4,17 @@ #include "Plugin.h" -// #include "Windows/Time.h" -#include "Windows/FileName.h" -#include "Windows/FileDir.h" - #include "Common/StringConvert.h" +#include "Common/Wildcard.h" #include "Windows/PropVariantConversions.h" - -#include "Far/FarUtils.h" +#include "Windows/FileName.h" +#include "Windows/FileDir.h" #include "../Common/PropIDUtils.h" -#include "Common/WildCard.h" - #include "Messages.h" +#include "FarUtils.h" using namespace NWindows; using namespace NFar; @@ -111,7 +107,7 @@ void CPlugin::ReadPluginPanelItem(PluginPanelItem &panelItem, UINT32 itemIndex) if (propVariant.vt == VT_EMPTY) length = 0; else - length = ::ConvertPropVariantToUINT64(propVariant); + length = ::ConvertPropVariantToUInt64(propVariant); panelItem.FindData.nFileSizeLow = UINT32(length); panelItem.FindData.nFileSizeHigh = UINT32(length >> 32); @@ -128,7 +124,7 @@ void CPlugin::ReadPluginPanelItem(PluginPanelItem &panelItem, UINT32 itemIndex) if (propVariant.vt == VT_EMPTY) length = 0; else - length = ::ConvertPropVariantToUINT64(propVariant); + length = ::ConvertPropVariantToUInt64(propVariant); panelItem.PackSize = UINT32(length); panelItem.PackSizeHigh = UINT32(length >> 32); @@ -170,7 +166,7 @@ int CPlugin::GetFindData(PluginPanelItem **panelItems, *panelItems = new PluginPanelItem[numItems]; try { - for(int i = 0; i < numItems; i++) + for(UINT32 i = 0; i < numItems; i++) { PluginPanelItem &panelItem = (*panelItems)[i]; ReadPluginPanelItem(panelItem, i); @@ -210,13 +206,13 @@ void CPlugin::EnterToDirectory(const UString &aDirName) int CPlugin::SetDirectory(const char *aszDir, int opMode) { - UString aDir = MultiByteToUnicodeString(aszDir, CP_OEMCP); - if (aDir == L"\\") + UString path = MultiByteToUnicodeString(aszDir, CP_OEMCP); + if (path == L"\\") { _folder.Release(); m_ArchiveHandler->BindToRootFolder(&_folder); } - else if (aDir == L"..") + else if (path == L"..") { CMyComPtr<IFolderFolder> newFolder; _folder->BindToParentFolder(&newFolder); @@ -224,29 +220,22 @@ int CPlugin::SetDirectory(const char *aszDir, int opMode) throw 40312; _folder = newFolder; } - else if (aDir.IsEmpty()) - EnterToDirectory(aDir); + else if (path.IsEmpty()) + EnterToDirectory(path); else { - if (aDir[0] == L'\\') + if (path[0] == L'\\') { _folder.Release(); m_ArchiveHandler->BindToRootFolder(&_folder); - aDir = aDir.Mid(1); + path = path.Mid(1); } UStringVector pathParts; - SplitPathToParts(aDir, pathParts); + SplitPathToParts(path, pathParts); for(int i = 0; i < pathParts.Size(); i++) EnterToDirectory(pathParts[i]); } - m_CurrentDir.Empty(); - UStringVector pathParts; - GetPathParts(pathParts); - for (int i = 0; i < pathParts.Size(); i++) - { - m_CurrentDir += L'\\'; - m_CurrentDir += pathParts[i]; - } + GetCurrentDir(); return TRUE; } @@ -267,6 +256,18 @@ void CPlugin::GetPathParts(UStringVector &pathParts) } } +void CPlugin::GetCurrentDir() +{ + m_CurrentDir.Empty(); + UStringVector pathParts; + GetPathParts(pathParts); + for (int i = 0; i < pathParts.Size(); i++) + { + m_CurrentDir += L'\\'; + m_CurrentDir += pathParts[i]; + } +} + static char *kPluginFormatName = "7-ZIP"; @@ -302,7 +303,9 @@ static CPROPIDToName kPROPIDToName[] = { kpidUser, NMessageID::kUser }, { kpidGroup, NMessageID::kGroup }, { kpidBlock, NMessageID::kBlock }, - { kpidComment, NMessageID::kComment } + { kpidComment, NMessageID::kComment }, + { kpidPosition, NMessageID::kPosition } + }; static const int kNumPROPIDToName = sizeof(kPROPIDToName) / sizeof(kPROPIDToName[0]); @@ -537,7 +540,7 @@ HRESULT CPlugin::ShowAttributesWindow() UINT32 numProps; RINOK(m_ArchiveHandler->GetNumberOfProperties(&numProps)); int i; - for (i = 0; i < numProps; i++) + for (i = 0; i < (int)numProps; i++) { CMyComBSTR name; PROPID propID; diff --git a/7zip/UI/Far/Plugin.h b/7zip/UI/Far/Plugin.h index 2357c3c8..61b03f49 100755 --- a/7zip/UI/Far/Plugin.h +++ b/7zip/UI/Far/Plugin.h @@ -1,19 +1,19 @@ -// Far/Plugin.h +// 7zip/Far/Plugin.h -#pragma once +#ifndef __7ZIP_FAR_PLUGIN_H +#define __7ZIP_FAR_PLUGIN_H -#ifndef __FAR_PLUGIN_H -#define __FAR_PLUGIN_H +#include "Common/MyCom.h" #include "Windows/COM.h" #include "Windows/FileFind.h" #include "Windows/PropVariant.h" -#include "Common/MyCom.h" -#include "Far/FarUtils.h" #include "../Common/ArchiverInfo.h" #include "../Agent/IFolderArchive.h" +#include "FarUtils.h" + class CPlugin { NWindows::NCOM::CComInitializer m_ComInitializer; @@ -36,6 +36,7 @@ class CPlugin void EnterToDirectory(const UString &aDirName); void GetPathParts(UStringVector &aPathParts); + void GetCurrentDir(); public: UString m_FileName; // UString m_DefaultName; @@ -80,14 +81,14 @@ public: */ HRESULT ExtractFiles( - bool aDecompressAllItems, - const UINT32 *anIndexes, + bool decompressAllItems, + const UINT32 *indices, UINT32 numIndices, - bool aSilent, - NExtractionMode::NPath::EEnum aPathMode, - NExtractionMode::NOverwrite::EEnum overwriteMode, + bool silent, + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, const UString &destPath, - bool aPasswordIsDefined, const UString &password); + bool passwordIsDefined, const UString &password); NFar::NFileOperationReturnCode::EEnum GetFiles(struct PluginPanelItem *aPanelItem, int itemsNumber, int move, char *destPath, int opMode); diff --git a/7zip/UI/Far/PluginCommon.cpp b/7zip/UI/Far/PluginCommon.cpp index 5e7679f9..767b2bcb 100755 --- a/7zip/UI/Far/PluginCommon.cpp +++ b/7zip/UI/Far/PluginCommon.cpp @@ -4,9 +4,11 @@ #include "Plugin.h" +/* using namespace NWindows; using namespace std; using namespace NFar; +*/ /* void CPlugin::AddRealIndexOfFile(const CArchiveFolderItem &aFolder, diff --git a/7zip/UI/Far/PluginDelete.cpp b/7zip/UI/Far/PluginDelete.cpp index 36dccdc4..6a969c15 100755 --- a/7zip/UI/Far/PluginDelete.cpp +++ b/7zip/UI/Far/PluginDelete.cpp @@ -2,6 +2,8 @@ #include "StdAfx.h" +#include <stdio.h> + #include "Plugin.h" #include "Messages.h" #include "UpdateCallback100.h" @@ -14,10 +16,7 @@ #include "../Common/ZipRegistry.h" #include "../Common/WorkDir.h" -// #include "../Common/OpenEngine2.h" - -using namespace std; using namespace NFar; using namespace NWindows; using namespace NFile; @@ -109,7 +108,7 @@ int CPlugin::DeleteFiles(PluginPanelItem *panelItems, int numItems, } outArchive->SetFolder(_folder); - CUpdateCallBack100Imp *updateCallbackSpec = new CUpdateCallBack100Imp; + CUpdateCallback100Imp *updateCallbackSpec = new CUpdateCallback100Imp; CMyComPtr<IFolderArchiveUpdateCallback> updateCallback(updateCallbackSpec ); updateCallbackSpec->Init(m_ArchiveHandler, &progressBox); @@ -164,6 +163,7 @@ int CPlugin::DeleteFiles(PluginPanelItem *panelItems, int numItems, break; _folder = newFolder; } + GetCurrentDir(); return(TRUE); } diff --git a/7zip/UI/Far/PluginRead.cpp b/7zip/UI/Far/PluginRead.cpp index d4761b8e..e9b6f98c 100755 --- a/7zip/UI/Far/PluginRead.cpp +++ b/7zip/UI/Far/PluginRead.cpp @@ -17,8 +17,6 @@ #include "ExtractEngine.h" - -using namespace std; using namespace NFar; using namespace NWindows; @@ -33,8 +31,8 @@ HRESULT CPlugin::ExtractFiles( const UINT32 *indices, UINT32 numIndices, bool silent, - NExtractionMode::NPath::EEnum pathMode, - NExtractionMode::NOverwrite::EEnum overwriteMode, + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, const UString &destPath, bool passwordIsDefined, const UString &password) { @@ -96,9 +94,10 @@ NFileOperationReturnCode::EEnum CPlugin::GetFilesReal(struct PluginPanelItem *pa NFile::NName::NormalizeDirPathPrefix(destPath); bool extractSelectedFiles = true; - NExtraction::CInfo extractionInfo; - extractionInfo.PathMode = NExtraction::NPathMode::kCurrentPathnames; - extractionInfo.OverwriteMode = NExtraction::NOverwriteMode::kWithoutPrompt; + + NExtract::CInfo extractionInfo; + extractionInfo.PathMode = NExtract::NPathMode::kCurrentPathnames; + extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kWithoutPrompt; bool silent = (opMode & OPM_SILENT) != 0; bool decompressAllItems = false; @@ -129,27 +128,27 @@ NFileOperationReturnCode::EEnum CPlugin::GetFilesReal(struct PluginPanelItem *pa { DI_SINGLEBOX, 4, 5, kXMid - 2, 5 + 4, false, false, 0, false, NMessageID::kExtractPathMode, NULL, NULL }, { DI_RADIOBUTTON, 6, 6, 0, 0, false, - extractionInfo.PathMode == NExtraction::NPathMode::kFullPathnames, + extractionInfo.PathMode == NExtract::NPathMode::kFullPathnames, DIF_GROUP, false, NMessageID::kExtractPathFull, NULL, NULL }, { DI_RADIOBUTTON, 6, 7, 0, 0, false, - extractionInfo.PathMode == NExtraction::NPathMode::kCurrentPathnames, + extractionInfo.PathMode == NExtract::NPathMode::kCurrentPathnames, 0, false, NMessageID::kExtractPathCurrent, NULL, NULL }, { DI_RADIOBUTTON, 6, 8, 0, 0, false, - extractionInfo.PathMode == NExtraction::NPathMode::kNoPathnames, + extractionInfo.PathMode == NExtract::NPathMode::kNoPathnames, false, 0, NMessageID::kExtractPathNo, NULL, NULL }, { DI_SINGLEBOX, kXMid, 5, 70, 5 + 5, false, false, 0, false, NMessageID::kExtractOwerwriteMode, NULL, NULL }, { DI_RADIOBUTTON, kXMid + 2, 6, 0, 0, false, - extractionInfo.OverwriteMode == NExtraction::NOverwriteMode::kAskBefore, + extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kAskBefore, DIF_GROUP, false, NMessageID::kExtractOwerwriteAsk, NULL, NULL }, { DI_RADIOBUTTON, kXMid + 2, 7, 0, 0, false, - extractionInfo.OverwriteMode == NExtraction::NOverwriteMode::kWithoutPrompt, + extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kWithoutPrompt, 0, false, NMessageID::kExtractOwerwritePrompt, NULL, NULL }, { DI_RADIOBUTTON, kXMid + 2, 8, 0, 0, false, - extractionInfo.OverwriteMode == NExtraction::NOverwriteMode::kSkipExisting, + extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kSkipExisting, 0, false, NMessageID::kExtractOwerwriteSkip, NULL, NULL }, { DI_RADIOBUTTON, kXMid + 2, 9, 0, 0, false, - extractionInfo.OverwriteMode == NExtraction::NOverwriteMode::kAutoRename, + extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kAutoRename, 0, false, NMessageID::kExtractOwerwriteAutoRename, NULL, NULL }, { DI_SINGLEBOX, 4, 10, kXMid- 2, 10 + 3, false, false, 0, false, NMessageID::kExtractFilesMode, NULL, NULL }, @@ -196,22 +195,22 @@ NFileOperationReturnCode::EEnum CPlugin::GetFilesReal(struct PluginPanelItem *pa } if (dialogItems[kPathModeRadioIndex].Selected) - extractionInfo.PathMode = NExtraction::NPathMode::kFullPathnames; + extractionInfo.PathMode = NExtract::NPathMode::kFullPathnames; else if (dialogItems[kPathModeRadioIndex + 1].Selected) - extractionInfo.PathMode = NExtraction::NPathMode::kCurrentPathnames; + extractionInfo.PathMode = NExtract::NPathMode::kCurrentPathnames; else if (dialogItems[kPathModeRadioIndex + 2].Selected) - extractionInfo.PathMode = NExtraction::NPathMode::kNoPathnames; + extractionInfo.PathMode = NExtract::NPathMode::kNoPathnames; else throw 31806; if (dialogItems[kOverwriteModeRadioIndex].Selected) - extractionInfo.OverwriteMode = NExtraction::NOverwriteMode::kAskBefore; + extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kAskBefore; else if (dialogItems[kOverwriteModeRadioIndex + 1].Selected) - extractionInfo.OverwriteMode = NExtraction::NOverwriteMode::kWithoutPrompt; + extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kWithoutPrompt; else if (dialogItems[kOverwriteModeRadioIndex + 2].Selected) - extractionInfo.OverwriteMode = NExtraction::NOverwriteMode::kSkipExisting; + extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kSkipExisting; else if (dialogItems[kOverwriteModeRadioIndex + 3].Selected) - extractionInfo.OverwriteMode = NExtraction::NOverwriteMode::kAutoRename; + extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kAutoRename; else throw 31806; @@ -248,35 +247,35 @@ NFileOperationReturnCode::EEnum CPlugin::GetFilesReal(struct PluginPanelItem *pa for (int i = 0; i < itemsNumber; i++) indices.Add(panelItems[i].UserData); - NExtractionMode::NPath::EEnum pathMode; - NExtractionMode::NOverwrite::EEnum overwriteMode; + NExtract::NPathMode::EEnum pathMode; + NExtract::NOverwriteMode::EEnum overwriteMode; switch (extractionInfo.OverwriteMode) { - case NExtraction::NOverwriteMode::kAskBefore: - overwriteMode = NExtractionMode::NOverwrite::kAskBefore; + case NExtract::NOverwriteMode::kAskBefore: + overwriteMode = NExtract::NOverwriteMode::kAskBefore; break; - case NExtraction::NOverwriteMode::kWithoutPrompt: - overwriteMode = NExtractionMode::NOverwrite::kWithoutPrompt; + case NExtract::NOverwriteMode::kWithoutPrompt: + overwriteMode = NExtract::NOverwriteMode::kWithoutPrompt; break; - case NExtraction::NOverwriteMode::kSkipExisting: - overwriteMode = NExtractionMode::NOverwrite::kSkipExisting; + case NExtract::NOverwriteMode::kSkipExisting: + overwriteMode = NExtract::NOverwriteMode::kSkipExisting; break; - case NExtraction::NOverwriteMode::kAutoRename: - overwriteMode = NExtractionMode::NOverwrite::kAutoRename; + case NExtract::NOverwriteMode::kAutoRename: + overwriteMode = NExtract::NOverwriteMode::kAutoRename; break; default: throw 12334454; } switch (extractionInfo.PathMode) { - case NExtraction::NPathMode::kFullPathnames: - pathMode = NExtractionMode::NPath::kFullPathnames; + case NExtract::NPathMode::kFullPathnames: + pathMode = NExtract::NPathMode::kFullPathnames; break; - case NExtraction::NPathMode::kCurrentPathnames: - pathMode = NExtractionMode::NPath::kCurrentPathnames; + case NExtract::NPathMode::kCurrentPathnames: + pathMode = NExtract::NPathMode::kCurrentPathnames; break; - case NExtraction::NPathMode::kNoPathnames: - pathMode = NExtractionMode::NPath::kNoPathnames; + case NExtract::NPathMode::kNoPathnames: + pathMode = NExtract::NPathMode::kNoPathnames; break; default: throw 12334455; diff --git a/7zip/UI/Far/PluginWrite.cpp b/7zip/UI/Far/PluginWrite.cpp index 5abb136d..b6b3b2f2 100755 --- a/7zip/UI/Far/PluginWrite.cpp +++ b/7zip/UI/Far/PluginWrite.cpp @@ -4,8 +4,6 @@ #include "Plugin.h" -#include "Messages.h" - #include "Common/StringConvert.h" #include "Windows/FileDir.h" @@ -15,23 +13,14 @@ #include "Windows/PropVariant.h" #include "../Common/ZipRegistry.h" -// #include "../Common/UpdatePairBasic.h" -// #include "../Common/CompressEngineCommon.h" #include "../Common/WorkDir.h" #include "../Common/OpenArchive.h" -#include "Far/ProgressBox.h" - -#include "UpdateCallback100.h" - #include "../Agent/Agent.h" -/* -#include "../../Archiver/Common/DefaultName.h" -#include "../../Archiver/Common/OpenEngine2.h" -*/ - -// #include "CompressEngine.h" +#include "ProgressBox.h" +#include "Messages.h" +#include "UpdateCallback100.h" using namespace NWindows; using namespace NFile; @@ -50,20 +39,19 @@ static UINT32 g_MethodMap[] = { 0, 1, 3, 5, 7, 9 }; static HRESULT SetOutProperties(IOutFolderArchive *outArchive, UINT32 method) { - CMyComPtr<ISetProperties> aSetProperties; - if (outArchive->QueryInterface(&aSetProperties) == S_OK) + CMyComPtr<ISetProperties> setProperties; + if (outArchive->QueryInterface(&setProperties) == S_OK) { - CMyComBSTR comBSTR = L"x"; - CObjectVector<CMyComBSTR> realNames; + UStringVector realNames; + realNames.Add(UString(L"x")); std::vector<NCOM::CPropVariant> values; - realNames.Add(comBSTR); values.push_back(NCOM::CPropVariant((UINT32)method)); - std::vector<BSTR> names; + CRecordVector<const wchar_t *> names; for(int i = 0; i < realNames.Size(); i++) - names.push_back(realNames[i]); - RINOK(aSetProperties->SetProperties(&names.front(), - &values.front(), names.size())); + names.Add(realNames[i]); + RINOK(setProperties->SetProperties(&names.Front(), + &values.front(), names.Size())); } return S_OK; } @@ -243,7 +231,7 @@ NFileOperationReturnCode::EEnum CPlugin::PutFiles( for (i = 0; i < NUpdateArchive::NPairState::kNumValues; i++) actionSetByte[i] = actionSet->StateActions[i]; - CUpdateCallBack100Imp *updateCallbackSpec = new CUpdateCallBack100Imp; + CUpdateCallback100Imp *updateCallbackSpec = new CUpdateCallback100Imp; CMyComPtr<IFolderArchiveUpdateCallback> updateCallback(updateCallbackSpec ); updateCallbackSpec->Init(m_ArchiveHandler, &progressBox); @@ -669,7 +657,7 @@ HRESULT CompressFiles(const CObjectVector<PluginPanelItem> &pluginPanelItems) for (i = 0; i < NUpdateArchive::NPairState::kNumValues; i++) actionSetByte[i] = actionSet->StateActions[i]; - CUpdateCallBack100Imp *updateCallbackSpec = new CUpdateCallBack100Imp; + CUpdateCallback100Imp *updateCallbackSpec = new CUpdateCallback100Imp; CMyComPtr<IFolderArchiveUpdateCallback> updateCallback(updateCallbackSpec ); updateCallbackSpec->Init(archiveHandler, &progressBox); diff --git a/7zip/UI/Far/ProgressBox.cpp b/7zip/UI/Far/ProgressBox.cpp new file mode 100755 index 00000000..64e0e09d --- /dev/null +++ b/7zip/UI/Far/ProgressBox.cpp @@ -0,0 +1,103 @@ +// ProgressBox.cpp + +#include "StdAfx.h" + +#include <stdio.h> + +#include "ProgressBox.h" + +#include "FarUtils.h" + +using namespace NFar; + +static void CopySpaces(char *destString, int numSpaces) +{ + for(int i = 0; i < numSpaces; i++) + destString[i] = ' '; + destString[i] = '\0'; +} + +///////////////////////////////// +// CMessageBox + +const int kNumStringsMax = 10; + +void CMessageBox::Init(const CSysString &title, const CSysString &message, + int numStrings, int width) +{ + if (numStrings > kNumStringsMax) + throw 120620; + m_NumStrings = numStrings; + m_Width = width; + + m_Title = title; + m_Message = message; +} + +const int kNumStaticStrings = 2; + +void CMessageBox::ShowProcessMessages(const char *messages[]) +{ + const char *msgItems[kNumStaticStrings + kNumStringsMax]; + msgItems[0] = m_Title; + msgItems[1] = m_Message; + + char formattedMessages[kNumStringsMax][256]; + + for (int i = 0; i < m_NumStrings; i++) + { + char *formattedMessage = formattedMessages[i]; + int len = strlen(messages[i]); + int size = MyMax(m_Width, len); + int startPos = (size - len) / 2; + CopySpaces(formattedMessage, startPos); + strcpy(formattedMessage + startPos, messages[i]); + CopySpaces(formattedMessage + startPos + len, size - startPos - len); + msgItems[kNumStaticStrings + i] = formattedMessage; + } + + g_StartupInfo.ShowMessage(0, NULL, msgItems, kNumStaticStrings + m_NumStrings, 0); +} + +///////////////////////////////// +// CProgressBox + +void CProgressBox::Init(const CSysString &title, const CSysString &message, + UInt64 step) +{ + CMessageBox::Init(title, message, 1, 22); + m_Step = step; + m_CompletedPrev = 0; + m_Total = 0; +} + + +void CProgressBox::ShowProcessMessage(const char *message) +{ + CMessageBox::ShowProcessMessages(&message); +} + +void CProgressBox::PrintPercent(UInt64 percent) +{ + char valueBuffer[32]; + sprintf(valueBuffer, "%I64u%%", percent); + ShowProcessMessage(valueBuffer); +} + +void CProgressBox::SetTotal(UInt64 total) +{ + m_Total = total; +} + +void CProgressBox::PrintCompeteValue(UInt64 completed) +{ + if (completed >= m_CompletedPrev + m_Step || completed < m_CompletedPrev || + completed == 0) + { + if (m_Total == 0) + PrintPercent(0); + else + PrintPercent(completed * 100 / m_Total); + m_CompletedPrev = completed; + } +} diff --git a/7zip/UI/Far/ProgressBox.h b/7zip/UI/Far/ProgressBox.h new file mode 100755 index 00000000..8721b456 --- /dev/null +++ b/7zip/UI/Far/ProgressBox.h @@ -0,0 +1,35 @@ +// ProgressBox.h + +#ifndef __PROGRESSBOX_H +#define __PROGRESSBOX_H + +#include "Common/String.h" +#include "Common/Types.h" + +class CMessageBox +{ + CSysString m_Title; + CSysString m_Message; + int m_NumStrings; + int m_Width; +public: + void Init(const CSysString &title, + const CSysString &message, int numStrings, int width); + void ShowProcessMessages(const char *messages[]); +}; + +class CProgressBox: public CMessageBox +{ + UInt64 m_Total; + UInt64 m_CompletedPrev; + UInt64 m_Step; +public: + void Init(const CSysString &title, + const CSysString &message, UInt64 step); + void ShowProcessMessage(const char *message); + void PrintPercent(UInt64 percent); + void PrintCompeteValue(UInt64 completed); + void SetTotal(UInt64 total); +}; + +#endif diff --git a/7zip/UI/Far/StdAfx.h b/7zip/UI/Far/StdAfx.h index f91028f7..da08641d 100755 --- a/7zip/UI/Far/StdAfx.h +++ b/7zip/UI/Far/StdAfx.h @@ -1,28 +1,8 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H #include <windows.h> -/* -#define _ATL_APARTMENT_THREADED - -#define _ATL_NO_UUIDOF - -#include <atlbase.h> - -extern CComModule _Module; - -#include <atlcom.h> -#include <shlobj.h> -#include <shlguid.h> -#include <regstr.h> -#include <stdio.h> - -#include <memory> -// #include <algorithm> -*/ -#include <vector> - #endif diff --git a/7zip/UI/Far/UpdateCallback100.cpp b/7zip/UI/Far/UpdateCallback100.cpp index 72d0c783..f1a2946e 100755 --- a/7zip/UI/Far/UpdateCallback100.cpp +++ b/7zip/UI/Far/UpdateCallback100.cpp @@ -5,11 +5,12 @@ #include "UpdateCallback100.h" #include "Common/Defs.h" -#include "Far/FarUtils.h" +#include "Common/StringConvert.h" +#include "FarUtils.h" using namespace NFar; -STDMETHODIMP CUpdateCallBack100Imp::SetTotal(UINT64 aSize) +STDMETHODIMP CUpdateCallback100Imp::SetTotal(UINT64 aSize) { if (m_ProgressBox != 0) { @@ -19,7 +20,7 @@ STDMETHODIMP CUpdateCallBack100Imp::SetTotal(UINT64 aSize) return S_OK; } -STDMETHODIMP CUpdateCallBack100Imp::SetCompleted(const UINT64 *aCompleteValue) +STDMETHODIMP CUpdateCallback100Imp::SetCompleted(const UINT64 *aCompleteValue) { if(WasEscPressed()) return E_ABORT; @@ -28,17 +29,26 @@ STDMETHODIMP CUpdateCallBack100Imp::SetCompleted(const UINT64 *aCompleteValue) return S_OK; } -STDMETHODIMP CUpdateCallBack100Imp::CompressOperation(const wchar_t *aName) +STDMETHODIMP CUpdateCallback100Imp::CompressOperation(const wchar_t *aName) { return S_OK; } -STDMETHODIMP CUpdateCallBack100Imp::DeleteOperation(const wchar_t *aName) +STDMETHODIMP CUpdateCallback100Imp::DeleteOperation(const wchar_t *aName) { return S_OK; } -STDMETHODIMP CUpdateCallBack100Imp::OperationResult(INT32 aOperationResult) +STDMETHODIMP CUpdateCallback100Imp::OperationResult(INT32 aOperationResult) { return S_OK; } + +STDMETHODIMP CUpdateCallback100Imp::UpdateErrorMessage(const wchar_t *message) +{ + CSysString s = UnicodeStringToMultiByte(message, CP_OEMCP); + if (g_StartupInfo.ShowMessage(s) == -1) + return E_ABORT; + return S_OK; +} + diff --git a/7zip/UI/Far/UpdateCallback100.h b/7zip/UI/Far/UpdateCallback100.h index 57c787ef..d66137cc 100755 --- a/7zip/UI/Far/UpdateCallback100.h +++ b/7zip/UI/Far/UpdateCallback100.h @@ -1,7 +1,5 @@ // UpdateCallback.h -#pragma once - #ifndef __UPDATECALLBACK100_H #define __UPDATECALLBACK100_H @@ -10,9 +8,9 @@ #include "../Agent/IFolderArchive.h" -#include "Far/ProgressBox.h" +#include "ProgressBox.h" -class CUpdateCallBack100Imp: +class CUpdateCallback100Imp: public IFolderArchiveUpdateCallback, public CMyUnknownImp { @@ -28,6 +26,7 @@ public: STDMETHOD(CompressOperation)(const wchar_t *aName); STDMETHOD(DeleteOperation)(const wchar_t *aName); STDMETHOD(OperationResult)(INT32 aOperationResult); + STDMETHOD(UpdateErrorMessage)(const wchar_t *message); private: CMyComPtr<IInFolderArchive> m_ArchiveHandler; diff --git a/7zip/UI/GUI/Compress.cpp b/7zip/UI/GUI/Compress.cpp deleted file mode 100755 index 2212ecc4..00000000 --- a/7zip/UI/GUI/Compress.cpp +++ /dev/null @@ -1,636 +0,0 @@ -// Compress.cpp - -#include "StdAfx.h" - -#include <mapi.h> - -#include "Compress.h" -#include "CompressDialog.h" -#include "resource.h" - -#include "Common/StringConvert.h" -#include "Common/IntToString.h" - -#include "Windows/FileName.h" -#include "Windows/FileFind.h" -#include "Windows/FileDir.h" -#include "Windows/Thread.h" -#include "Windows/COM.h" -#include "Windows/PropVariant.h" - -#include "../../FileManager/ProgramLocation.h" -#include "../../FileManager/FormatUtils.h" -#include "../../FileManager/UpdateCallback100.h" - -#include "../Agent/Agent.h" -#include "../Common/UpdateAction.h" -#include "../Common/WorkDir.h" -#include "../Common/ZipRegistry.h" -#include "../Common/OpenArchive.h" -#include "../Resource/Extract/resource.h" -#include "../Explorer/MyMessages.h" - -using namespace NWindows; -using namespace NFile; -using namespace NDirectory; -using namespace NName; - -static LPCWSTR kTempArchivePrefix = L"7zA"; -static LPCWSTR kTempFolderPrefix = L"7zE"; -static LPCWSTR kDefaultSfxModule = L"7zC.sfx"; - -static void SplitString(const UString &srcString, UStringVector &destStrings) -{ - destStrings.Clear(); - for (int pos = 0; pos < srcString.Length();) - { - int spacePos = srcString.Find(L' ', pos); - if (spacePos < 0) - { - destStrings.Add(srcString.Mid(pos)); - return; - } - if (spacePos != pos) - destStrings.Add(srcString.Mid(pos, spacePos - pos)); - pos = spacePos + 1; - } -} - -static bool ParseNumberString(const UString &string, UINT32 &number) -{ - wchar_t *endPtr; - number = wcstoul(string, &endPtr, 10); - return (endPtr - string == string.Length()); -} - -static void SetOptions(const UString &options, - CObjectVector<CMyComBSTR> &realNames, - std::vector<NCOM::CPropVariant> &values) -{ - UStringVector strings; - SplitString(options, strings); - for(int i = 0; i < strings.Size(); i++) - { - const UString &s = strings[i]; - int index = s.Find(L'='); - CMyComBSTR name; - NCOM::CPropVariant propVariant; - if (index < 0) - name = s; - else - { - name = s.Left(index); - UString value = s.Mid(index + 1); - if (!value.IsEmpty()) - { - UINT32 number; - if (ParseNumberString(value, number)) - propVariant = number; - else - propVariant = value; - } - } - realNames.Add(name); - values.push_back(propVariant); - } -} - -static HRESULT SetOutProperties(IOutFolderArchive * outArchive, - bool is7z, - UINT32 level, - const UString &method, - UINT32 dictionary, - bool orderMode, - UINT32 order, - bool solidModeIsAllowed, bool solidMode, - bool multiThreadIsAllowed, bool multiThread, - bool encryptHeadersIsAllowed, bool encryptHeaders, - bool sfxMode, - const UString &options) -{ - CMyComPtr<ISetProperties> setProperties; - if (outArchive->QueryInterface(&setProperties) == S_OK) - { - CObjectVector<CMyComBSTR> realNames; - std::vector<NCOM::CPropVariant> values; - if (level != (UINT32)(INT32)-1) - { - CMyComBSTR comBSTR = L"x"; - realNames.Add(comBSTR); - values.push_back(NCOM::CPropVariant((UINT32)level)); - } - if (!method.IsEmpty()) - { - CMyComBSTR comBSTR; - if (is7z) - comBSTR = L"0"; - else - comBSTR = L"m"; - realNames.Add(comBSTR); - values.push_back(NCOM::CPropVariant(method)); - } - if (dictionary != (UINT32)(INT32)-1) - { - CMyComBSTR comBSTR; - if (is7z) - if (orderMode) - comBSTR = L"0mem"; - else - comBSTR = L"0d"; - else - if (orderMode) - comBSTR = L"mem"; - else - comBSTR = L"d"; - realNames.Add(comBSTR); - wchar_t s[32]; - ConvertUINT64ToString(dictionary, s); - wcscat(s, L"B"); - values.push_back(NCOM::CPropVariant(s)); - } - if (order != (UINT32)(INT32)-1) - { - CMyComBSTR comBSTR; - if (is7z) - if (orderMode) - comBSTR = L"0o"; - else - comBSTR = L"0fb"; - else - if (orderMode) - comBSTR = L"o"; - else - comBSTR = L"fb"; - realNames.Add(comBSTR); - values.push_back(NCOM::CPropVariant((UINT32)order)); - } - - if (sfxMode) - { - realNames.Add(L"rsfx"); - values.push_back(NCOM::CPropVariant(L"on")); - } - - if (encryptHeadersIsAllowed) - { - if (encryptHeaders) - { - realNames.Add(L"he"); - values.push_back(NCOM::CPropVariant(L"on")); - } - } - - // Solid - if (solidModeIsAllowed) - { - realNames.Add(L"s"); - values.push_back(NCOM::CPropVariant(solidMode ? L"on": L"off")); - } - if (multiThreadIsAllowed) - { - realNames.Add(L"mt"); - values.push_back(NCOM::CPropVariant(multiThread ? L"on": L"off")); - } - - // Options - SetOptions(options, realNames, values); - - std::vector<BSTR> names; - for(int i = 0; i < realNames.Size(); i++) - names.push_back(realNames[i]); - RINOK(setProperties->SetProperties(&names.front(), - &values.front(), names.size())); - } - return S_OK; -} - -struct CThreadUpdateCompress -{ - CMyComPtr<IOutFolderArchive> OutArchive; - UString LibPath; - CLSID ClassID; - UString OutArchivePath; - BYTE ActionSetByte[NUpdateArchive::NPairState::kNumValues]; - bool SfxMode; - UString SfxModule; - - - UStringVector FileNames; - CRecordVector<const wchar_t *> FileNamePointers; - CMyComPtr<IFolderArchiveUpdateCallback> UpdateCallback; - CUpdateCallback100Imp *UpdateCallbackSpec; - HRESULT Result; - - DWORD Process() - { - NCOM::CComInitializer comInitializer; - UpdateCallbackSpec->ProgressDialog.WaitCreating(); - try - { - Result = OutArchive->DoOperation( - LibPath, &ClassID, - OutArchivePath, ActionSetByte, - (SfxMode ? (const wchar_t *)SfxModule: NULL), - UpdateCallback); - } - catch(const UString &s) - { - MyMessageBox(s); - Result = E_FAIL; - } - catch(...) - { - Result = E_FAIL; - } - UpdateCallbackSpec->ProgressDialog.MyClose(); - return 0; - } - - static DWORD WINAPI MyThreadFunction(void *param) - { - return ((CThreadUpdateCompress *)param)->Process(); - } -}; - -static UString MakeFullArchiveName(const UString &name, - const UString &extension, bool sfx) -{ - if (sfx) - { - UString sfxExt = L".exe"; - if (sfxExt.CollateNoCase(name.Right(sfxExt.Length())) == 0) - return name; - return name + sfxExt; - } - - if (extension.IsEmpty()) - return name; - if (name.IsEmpty()) - return name; - if (name[name.Length() - 1] == '.') - return name.Left(name.Length() - 1); - int slash1Pos = name.ReverseFind(L'\\'); - int slash2Pos = name.ReverseFind(L'/'); - int slashPos = MyMax(slash1Pos, slash2Pos); - int dotPos = name.ReverseFind(L'.'); - if (dotPos >= 0 && (dotPos > slashPos || slashPos < 0)) - return name; - return name + UString(L'.') + extension; -} - -HRESULT CompressArchive( - const UString &archivePath, - const UStringVector &fileNames, - const UString &archiveType, - bool email, - bool showDialog) -{ - if (fileNames.Size() == 0) - return S_OK; - - CObjectVector<CArchiverInfo> archivers; - ReadArchiverInfoList(archivers); - - CArchiverInfo archiverInfo; - UString password; - bool encryptHeadersIsAllowed = false; - bool encryptHeaders = false; - const NUpdateArchive::CActionSet *actionSet; - NCompressDialog::CInfo compressInfo; - - UString tempDirPath; - UString currentDirPrefix; - bool needTempFile = true; - NDirectory::CTempDirectoryW tempDirectory; - UString archiveName; - int pos = archivePath.ReverseFind(L'\\'); - if (pos < 0) - { - archiveName = archivePath; - MyGetCurrentDirectory(currentDirPrefix); - } - else - { - currentDirPrefix = archivePath.Left(pos + 1); - archiveName = archivePath.Mid(pos + 1); - } - - if (email) - { - tempDirectory.Create(kTempFolderPrefix); - currentDirPrefix = tempDirectory.GetPath(); - NormalizeDirPathPrefix(currentDirPrefix); - needTempFile = false; - } - - if (showDialog) - { - bool oneFile = false; - NFind::CFileInfoW fileInfo; - if (!NFind::FindFile(fileNames.Front(), fileInfo)) - return ::GetLastError(); - if (fileNames.Size() == 1) - oneFile = !fileInfo.IsDirectory(); - - CCompressDialog dialog; - for(int i = 0; i < archivers.Size(); i++) - { - const CArchiverInfo &archiverInfo = archivers[i]; - if (archiverInfo.UpdateEnabled && - (oneFile || !archiverInfo.KeepName)) - dialog.m_ArchiverInfoList.Add(archiverInfo); - } - if(dialog.m_ArchiverInfoList.Size() == 0) - { - MyMessageBox(L"No Update Engines"); - return E_FAIL; - } - dialog.m_Info.ArchiveName = archiveName; - dialog.OriginalFileName = fileInfo.Name; - - dialog.m_Info.CurrentDirPrefix = currentDirPrefix; - dialog.m_Info.SFXMode = false; - dialog.m_Info.Solid = true; - dialog.m_Info.MultiThread = false; - - dialog.m_Info.KeepName = !oneFile; - - if(dialog.Create(0) != IDOK) - return S_OK; - - if (dialog.m_Info.VolumeSizeIsDefined) - { - MyMessageBox(L"Splitting to volumes is not supported"); - return E_FAIL; - } - - switch(dialog.m_Info.UpdateMode) - { - case NCompressDialog::NUpdateMode::kAdd: - actionSet = &NUpdateArchive::kAddActionSet; - break; - case NCompressDialog::NUpdateMode::kUpdate: - actionSet = &NUpdateArchive::kUpdateActionSet; - break; - case NCompressDialog::NUpdateMode::kFresh: - actionSet = &NUpdateArchive::kFreshActionSet; - break; - case NCompressDialog::NUpdateMode::kSynchronize: - actionSet = &NUpdateArchive::kSynchronizeActionSet; - break; - default: - throw 1091756; - } - archiverInfo = dialog.m_ArchiverInfoList[dialog.m_Info.ArchiverInfoIndex]; - password = GetUnicodeString(dialog.Password); - encryptHeadersIsAllowed = dialog.EncryptHeadersIsAllowed; - encryptHeaders = dialog.EncryptHeaders; - compressInfo = dialog.m_Info; - compressInfo.ArchiveName = MakeFullArchiveName( - compressInfo.ArchiveName, - archiverInfo.GetMainExtension(), compressInfo.SFXMode); - } - else - { - int i; - for(i = 0; i < archivers.Size(); i++) - { - if (archivers[i].Name.CollateNoCase(archiveType) == 0) - { - archiverInfo = archivers[i]; - break; - } - } - if (i == archivers.Size()) - { - MyMessageBox(L"No archiver"); - return E_FAIL; - } - actionSet = &NUpdateArchive::kAddActionSet; - bool is7z = (archiveType.CollateNoCase(L"7z") == 0); - compressInfo.SolidIsAllowed = is7z; - compressInfo.Solid = true; - compressInfo.MultiThreadIsAllowed = is7z; - compressInfo.MultiThread = false; - compressInfo.SFXMode = false; - compressInfo.KeepName = false; - compressInfo.ArchiveName = archiveName; - compressInfo.CurrentDirPrefix = currentDirPrefix; - compressInfo.Level = 5; - } - UString arcPath; - if (!compressInfo.GetFullPathName(arcPath)) - { - MyMessageBox(L"Incorrect archive path"); - return E_FAIL; - } - if (compressInfo.ArchiveName.Find('\\') >= 0) - { - needTempFile = true; - } - - // MessageBox(0, arcPath, 0, 0); - - NWorkDir::CInfo workDirInfo; - ReadWorkDirInfo(workDirInfo); - UString workDir = GetWorkDir(workDirInfo, arcPath); - NFile::NDirectory::CreateComplexDirectory(workDir); - - NFile::NDirectory::CTempFileW tempFile; - UString tempFileName; - if (needTempFile) - { - if (tempFile.Create(workDir, kTempArchivePrefix, tempFileName) == 0) - return E_FAIL; - } - else - tempFileName = arcPath; - - - /* - const CLSID &classID = - dialog.m_ArchiverInfoList[dialog.m_Info.ArchiverInfoIndex].ClassID; - */ - NFind::CFileInfoW fileInfo; - - CMyComPtr<IOutFolderArchive> outArchive; - - CMyComPtr<IInFolderArchive> archiveHandler; - if(NFind::FindFile(arcPath, fileInfo)) - { - if (fileInfo.IsDirectory()) - { - MyMessageBox(L"There is a folder with such name"); - return E_FAIL; - } - CAgent *agentSpec = new CAgent; - archiveHandler = agentSpec; - // CLSID realClassID; - CMyComBSTR archiveType; - HRESULT result = agentSpec->Open( - GetUnicodeString(arcPath), &archiveType, NULL); - if (result == S_FALSE) - { - MyMessageBox(IDS_OPEN_IS_NOT_SUPORTED_ARCHIVE, 0x02000604); - return E_FAIL; - } - /* - HRESULT result = OpenArchive(arcPath, &archiveHandler, - archiverInfoResult, defaultName, NULL); - if (result == S_FALSE) - { - MyMessageBox(IDS_OPEN_IS_NOT_SUPORTED_ARCHIVE, 0x02000604); - return E_FAIL; - } - */ - if (result != S_OK) - { - MyMessageBox(L"Open error"); - return E_FAIL; - } - if (archiverInfo.Name.CollateNoCase((const wchar_t *)archiveType) != 0) - { - MyMessageBox(L"Type of existing archive differs from specified type"); - return E_FAIL; - } - result = archiveHandler.QueryInterface(IID_IOutFolderArchive, &outArchive); - if(result != S_OK) - { - MyMessageBox(MyFormatNew(IDS_CANT_UPDATE_ARCHIVE, 0x02000602, - GetUnicodeString(arcPath))); - return E_FAIL; - } - } - else - { - CAgent *agentSpec = new CAgent; - outArchive = agentSpec; - } - - CRecordVector<const wchar_t *> fileNamePointers; - fileNamePointers.Reserve(fileNames.Size()); - - int i; - for(i = 0; i < fileNames.Size(); i++) - fileNamePointers.Add(fileNames[i]); - - outArchive->SetFolder(NULL); - - // Don't uses CurrentFolder here, since files are absolute paths; - // MyGetCurrentDirectory(aCurrentFolder); - - UINT codePage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; - outArchive->SetFiles(L"", - &fileNamePointers.Front(), fileNamePointers.Size()); - - CThreadUpdateCompress updater; - for (i = 0; i < NUpdateArchive::NPairState::kNumValues; i++) - updater.ActionSetByte[i] = actionSet->StateActions[i]; - updater.UpdateCallbackSpec = new CUpdateCallback100Imp; - updater.UpdateCallback = updater.UpdateCallbackSpec; - updater.OutArchive = outArchive; - // updater.SrcFolderPrefix = srcPanel._currentFolderPrefix; - - UString title = LangLoadStringW(IDS_PROGRESS_COMPRESSING, 0x02000DC0); - updater.UpdateCallbackSpec->Init(0, !password.IsEmpty(), password); - - // UINT32 level = MyMin(compressInfo.Level, UINT32(9)); - UINT32 level = compressInfo.Level; - HRESULT result = SetOutProperties(outArchive, - archiverInfo.Name.CompareNoCase(L"7z") == 0, - level, - compressInfo.Method, - compressInfo.Dictionary, - compressInfo.OrderMode, compressInfo.Order, - compressInfo.SolidIsAllowed, compressInfo.Solid, - compressInfo.MultiThreadIsAllowed, compressInfo.MultiThread, - encryptHeadersIsAllowed, encryptHeaders, - compressInfo.SFXMode, - GetUnicodeString(compressInfo.Options)); - - if (result != S_OK) - { - if (result != E_ABORT) - ShowErrorMessage(result); - return result; - } - - - UString sfxModule; - if (compressInfo.SFXMode) - { - UString sfxModule2; - LPCWSTR path = NULL; - UString sfxModule3; - if (GetProgramFolderPath(sfxModule3)) - path = sfxModule3; - if (!NDirectory::MySearchPath(path, kDefaultSfxModule, NULL, sfxModule2)) - { - MyMessageBox(L"can't find sfx module"); - return E_FAIL; - } - sfxModule = sfxModule2; - } - - updater.OutArchivePath = GetUnicodeString(tempFileName, codePage); - updater.SfxMode = compressInfo.SFXMode; - updater.SfxModule = sfxModule; - updater.LibPath = GetUnicodeString(archiverInfo.FilePath); - updater.ClassID = archiverInfo.ClassID; - - CThread thread; - if (!thread.Create(CThreadUpdateCompress::MyThreadFunction, &updater)) - throw 271824; - updater.UpdateCallbackSpec->StartProgressDialog(title); - result = updater.Result; - - updater.UpdateCallback.Release(); - - updater.OutArchive.Release(); - outArchive.Release(); - - if (result != S_OK) - { - if (result != E_ABORT) - ShowErrorMessage(result); - return result; - } - - if(archiveHandler) - { - archiveHandler->Close(); - if (!DeleteFileAlways(arcPath)) - { - ShowLastErrorMessage(); - return E_FAIL; - } - } - if (needTempFile) - { - tempFile.DisableDeleting(); - if (!NDirectory::MyMoveFile(tempFileName, arcPath)) - { - ShowLastErrorMessage(); - return E_FAIL; - } - } - - if (email) - { - NDLL::CLibrary mapiLib; - if (!mapiLib.Load(TEXT("Mapi32.dll"))) - return E_FAIL; - LPMAPISENDDOCUMENTS fnSend = (LPMAPISENDDOCUMENTS) - mapiLib.GetProcAddress("MAPISendDocuments"); - if (fnSend == 0) - return E_FAIL; - - UString fileName; - GetOnlyName(arcPath, fileName); - AString path = GetAnsiString(arcPath); - AString name = GetAnsiString(fileName); - fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0); - } - - return S_OK; -} diff --git a/7zip/UI/GUI/Compress.h b/7zip/UI/GUI/Compress.h deleted file mode 100755 index 07562ee7..00000000 --- a/7zip/UI/GUI/Compress.h +++ /dev/null @@ -1,17 +0,0 @@ -// GUI/Compress.h - -#pragma once - -#ifndef __GUI_COMPRESS_H -#define __GUI_COMPRESS_H - -#include "Common/String.h" - -HRESULT CompressArchive( - const UString &archivePath, - const UStringVector &fileNames, - const UString &archiveType, - bool email, - bool showDialog); - -#endif diff --git a/7zip/UI/GUI/CompressDialog.cpp b/7zip/UI/GUI/CompressDialog.cpp index 1b098d91..1991ddd7 100755 --- a/7zip/UI/GUI/CompressDialog.cpp +++ b/7zip/UI/GUI/CompressDialog.cpp @@ -5,13 +5,14 @@ #include "resource.h" #include "Common/Defs.h" #include "Common/StringConvert.h" -#include "Common/StringToInt.h" #include "Common/IntToString.h" #include "Windows/FileDir.h" #include "Windows/FileName.h" #include "Windows/ResourceString.h" #include "../../FileManager/HelpUtils.h" +#include "../../FileManager/SplitUtils.h" + #include "../Common/ZipRegistry.h" #include "CompressDialog.h" @@ -63,8 +64,8 @@ static LPCWSTR k7zFormat = L"7z"; struct CLevelInfo { - UINT32 ResourceID; - UINT32 LangID; + UInt32 ResourceID; + UInt32 LangID; }; enum ELevel @@ -115,8 +116,14 @@ static const EMethodID g_7zMethods[] = { kLZMA, kPPMd, - kBZip2, - kDeflate + kBZip2 +}; + +static const EMethodID g_7zSfxMethods[] = +{ + kCopy, + kLZMA, + kPPMd }; static EMethodID g_ZipMethods[] = @@ -139,7 +146,7 @@ static EMethodID g_BZip2Methods[] = struct CFormatInfo { LPCWSTR Name; - UINT32 LevelsMask; + UInt32 LevelsMask; const EMethodID *MathodIDs; int NumMethods; bool Solid; @@ -177,7 +184,7 @@ static const CFormatInfo g_Formats[] = }, { L"BZip2", - (1 << 5), + (1 << 5) | (1 << 7) | (1 << 9), g_BZip2Methods, MY_SIZE_OF_ARRAY(g_BZip2Methods), false, false, false, false, false @@ -190,6 +197,14 @@ static const CFormatInfo g_Formats[] = } }; +static bool IsMethodSupportedBySfx(int methodID) +{ + for (int i = 0; i < MY_SIZE_OF_ARRAY(g_7zSfxMethods); i++) + if (methodID == g_7zSfxMethods[i]) + return true; + return false; +}; + class CDoubleZeroStringList { CRecordVector<int> m_Indexes; @@ -222,7 +237,7 @@ bool CCompressDialog::OnInit() LangSetDlgItemsText(HWND(*this), kIDLangPairs, MY_SIZE_OF_ARRAY(kIDLangPairs) ); #endif _passwordControl.Attach(GetItem(IDC_COMPRESS_EDIT_PASSWORD)); - _passwordControl.SetText(TEXT("")); + _passwordControl.SetText(Info.Password); m_ArchivePath.Attach(GetItem(IDC_COMPRESS_COMBO_ARCHIVE)); m_Format.Attach(GetItem(IDC_COMPRESS_COMBO_FORMAT)); @@ -235,9 +250,7 @@ bool CCompressDialog::OnInit() m_Volume.Attach(GetItem(IDC_COMPRESS_COMBO_VOLUME)); m_Params.Attach(GetItem(IDC_COMPRESS_EDIT_PARAMETERS)); - m_Volume.AddString(TEXT("1457664 - 3.5 Floppy")); - m_Volume.AddString(TEXT("650M - CD-650MB")); - m_Volume.AddString(TEXT("700M - CD-700MB")); + AddVolumeItems(m_Volume); ReadCompressionInfo(m_RegistryInfo); CheckButton(IDC_COMPRESS_CHECK_SHOW_PASSWORD, m_RegistryInfo.ShowPassword); @@ -245,7 +258,7 @@ bool CCompressDialog::OnInit() UpdatePasswordControl(); - m_Info.ArchiverInfoIndex = 0; + Info.ArchiverInfoIndex = 0; int i; for(i = 0; i < m_ArchiverInfoList.Size(); i++) { @@ -253,11 +266,11 @@ bool CCompressDialog::OnInit() m_Format.AddString(GetSystemString(ai.Name)); if (ai.Name.CollateNoCase( m_RegistryInfo.ArchiveType) == 0) - m_Info.ArchiverInfoIndex = i; + Info.ArchiverInfoIndex = i; } - m_Format.SetCurSel(m_Info.ArchiverInfoIndex); + m_Format.SetCurSel(Info.ArchiverInfoIndex); - SetArchiveName(m_Info.ArchiveName); + SetArchiveName(Info.ArchiveName); SetLevel(); SetParams(); @@ -271,12 +284,12 @@ bool CCompressDialog::OnInit() m_UpdateMode.SetCurSel(0); - m_Info.Solid = m_RegistryInfo.Solid; - m_Info.MultiThread = m_RegistryInfo.MultiThread; + Info.Solid = m_RegistryInfo.Solid; + Info.MultiThread = m_RegistryInfo.MultiThread; - CheckButton(IDC_COMPRESS_SOLID, m_Info.Solid); - CheckButton(IDC_COMPRESS_MULTI_THREAD, m_Info.MultiThread); - CheckButton(IDC_COMPRESS_SFX, m_Info.SFXMode); + CheckButton(IDC_COMPRESS_SOLID, Info.Solid); + CheckButton(IDC_COMPRESS_MULTI_THREAD, Info.MultiThread); + CheckButton(IDC_COMPRESS_SFX, Info.SFXMode); CheckControlsEnable(); @@ -339,16 +352,8 @@ void CCompressDialog::CheckSFXControlsEnable() bool enable = fi.SFX; if (enable) { - switch(GetMethodID()) - { - case -1: - case kLZMA: - case kPPMd: - case kCopy: - break; - default: - enable = false; - } + int methodID = GetMethodID(); + enable = (methodID == -1 || IsMethodSupportedBySfx(methodID)); } if (!enable) CheckButton(IDC_COMPRESS_SFX, false); @@ -358,10 +363,10 @@ void CCompressDialog::CheckSFXControlsEnable() void CCompressDialog::CheckControlsEnable() { const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; - m_Info.SolidIsAllowed = fi.Solid; + Info.SolidIsAllowed = fi.Solid; bool multiThreadEnable = fi.MultiThread & IsMultiProcessor(); - m_Info.MultiThreadIsAllowed = multiThreadEnable; - EncryptHeadersIsAllowed = fi.EncryptFileNames; + Info.MultiThreadIsAllowed = multiThreadEnable; + Info.EncryptHeadersIsAllowed = fi.EncryptFileNames; EnableItem(IDC_COMPRESS_SOLID, fi.Solid); EnableItem(IDC_COMPRESS_MULTI_THREAD, multiThreadEnable); @@ -384,13 +389,16 @@ bool CCompressDialog::IsSFX() void CCompressDialog::OnButtonSFX() { + SetMethod(); + UString fileName; m_ArchivePath.GetText(fileName); int dotPos = fileName.ReverseFind(L'.'); int slashPos = fileName.ReverseFind(L'\\'); if (dotPos < 0 || dotPos <= slashPos) dotPos = -1; - if (IsSFX()) + bool isSFX = IsSFX(); + if (isSFX) { if (dotPos >= 0) fileName = fileName.Left(dotPos); @@ -410,6 +418,10 @@ void CCompressDialog::OnButtonSFX() } SetArchiveName2(false); // it's for OnInit } + + m_Volume.Enable(!isSFX); + if (isSFX) + m_Volume.SetText(TEXT("")); } void CCompressDialog::OnButtonSetArchive() @@ -420,11 +432,11 @@ void CCompressDialog::OnButtonSetArchive() m_ArchivePath.GetText(fileName); fileName.TrimLeft(); fileName.TrimRight(); - m_Info.ArchiveName = fileName; + Info.ArchiveName = fileName; UString fullFileName; - if (!m_Info.GetFullPathName(fullFileName)) + if (!Info.GetFullPathName(fullFileName)) { - fullFileName = m_Info.ArchiveName; + fullFileName = Info.ArchiveName; // throw "Incorrect archive path"; return; } @@ -482,42 +494,10 @@ void CCompressDialog::OnButtonSetArchive() // in ExtractDialog.cpp extern void AddUniqueString(CSysStringVector &strings, const CSysString &srcString); -bool ParseVolumeSize(const CSysString &s, UINT64 &value) -{ - const TCHAR *start = s; - const TCHAR *end; - value = ConvertStringToUINT64(start, &end); - if (start == end) - return false; - while (true) - { - TCHAR c = *end++; - c = MyCharUpper(c); - switch(c) - { - case TEXT('\0'): - case TEXT('B'): - return true; - case TEXT('K'): - value <<= 10; - return true; - case TEXT('M'): - value <<= 20; - return true; - case TEXT('G'): - value <<= 30; - return true; - case TEXT(' '): - continue; - default: - return true; - } - } -} void CCompressDialog::OnOK() { - _passwordControl.GetText(Password); + _passwordControl.GetText(Info.Password); SaveOptionsInMem(); int currentItem = m_ArchivePath.GetCurSel(); @@ -537,32 +517,33 @@ void CCompressDialog::OnOK() s.Trim(); m_RegistryInfo.HistoryArchives.Clear(); AddUniqueString(m_RegistryInfo.HistoryArchives, GetSystemString(s)); - m_Info.ArchiveName = s; - m_Info.UpdateMode = NCompressDialog::NUpdateMode::EEnum(m_UpdateMode.GetCurSel()); + Info.ArchiveName = s; + Info.UpdateMode = NCompressDialog::NUpdateMode::EEnum(m_UpdateMode.GetCurSel()); - m_Info.Level = GetLevelSpec(); - m_Info.Dictionary = GetDictionarySpec(); - m_Info.Order = GetOrderSpec(); - m_Info.OrderMode = GetOrderMode(); - m_Info.Method = GetUnicodeString(GetMethodSpec()); + Info.Level = GetLevelSpec(); + Info.Dictionary = GetDictionarySpec(); + Info.Order = GetOrderSpec(); + Info.OrderMode = GetOrderMode(); + Info.Method = GetUnicodeString(GetMethodSpec()); - m_Info.ArchiverInfoIndex = m_Format.GetCurSel(); + Info.ArchiverInfoIndex = m_Format.GetCurSel(); - m_Info.SFXMode = IsSFX(); - m_RegistryInfo.Solid = m_Info.Solid = IsButtonCheckedBool(IDC_COMPRESS_SOLID); - m_RegistryInfo.MultiThread = m_Info.MultiThread = IsButtonCheckedBool(IDC_COMPRESS_MULTI_THREAD); - m_RegistryInfo.EncryptHeaders = EncryptHeaders = IsButtonCheckedBool(IDC_COMPRESS_CHECK_ENCRYPT_FILE_NAMES); + Info.SFXMode = IsSFX(); + m_RegistryInfo.Solid = Info.Solid = IsButtonCheckedBool(IDC_COMPRESS_SOLID); + m_RegistryInfo.MultiThread = Info.MultiThread = IsButtonCheckedBool(IDC_COMPRESS_MULTI_THREAD); + m_RegistryInfo.EncryptHeaders = Info.EncryptHeaders = IsButtonCheckedBool(IDC_COMPRESS_CHECK_ENCRYPT_FILE_NAMES); - m_Params.GetText(m_Info.Options); - CSysString volumeString; + m_Params.GetText(Info.Options); + UString volumeString; m_Volume.GetText(volumeString); volumeString.Trim(); - m_Info.VolumeSizeIsDefined = ParseVolumeSize( - volumeString, m_Info.VolumeSize); - /* - if (!m_Info.VolumeSizeIsDefined && !volumeString.IsEmpty()) - MessageBox(0, TEXT("Incorrect volume size"), TEXT("7-Zip"), 0); - */ + Info.VolumeSizes.Clear(); + if (!volumeString.IsEmpty()) + if (!ParseVolumeSizes(volumeString, Info.VolumeSizes)) + { + MessageBox(*this, TEXT("Incorrect volume size"), TEXT("7-Zip"), 0); + return; + } for(int i = 0; i < m_ArchivePath.GetCount(); i++) if(i != currentItem) @@ -576,8 +557,8 @@ void CCompressDialog::OnOK() //////////////////// // Method - m_RegistryInfo.Level = m_Info.Level; - m_RegistryInfo.ArchiveType = m_ArchiverInfoList[m_Info.ArchiverInfoIndex].Name; + m_RegistryInfo.Level = Info.Level; + m_RegistryInfo.ArchiveType = m_ArchiverInfoList[Info.ArchiverInfoIndex].Name; m_RegistryInfo.ShowPassword = (IsButtonChecked( IDC_COMPRESS_CHECK_SHOW_PASSWORD) == BST_CHECKED); @@ -646,7 +627,7 @@ void CCompressDialog::SetArchiveName2(bool prevWasSFX) UString fileName; m_ArchivePath.GetText(fileName); const CArchiverInfo &prevArchiverInfo = m_ArchiverInfoList[m_PrevFormat]; - if (prevArchiverInfo.KeepName || m_Info.KeepName) + if (prevArchiverInfo.KeepName || Info.KeepName) { UString prevExtension = prevArchiverInfo.GetMainExtension(); if (prevWasSFX) @@ -671,19 +652,23 @@ void CCompressDialog::OnChangeFormat() SetArchiveName2(isSFX); } +// if type.KeepName then use OriginalFileName +// else if !KeepName remove extension +// add new extension + void CCompressDialog::SetArchiveName(const UString &name) { UString fileName = name; - m_Info.ArchiverInfoIndex = m_Format.GetCurSel(); - const CArchiverInfo &ai = m_ArchiverInfoList[m_Info.ArchiverInfoIndex]; - m_PrevFormat = m_Info.ArchiverInfoIndex; + Info.ArchiverInfoIndex = m_Format.GetCurSel(); + const CArchiverInfo &ai = m_ArchiverInfoList[Info.ArchiverInfoIndex]; + m_PrevFormat = Info.ArchiverInfoIndex; if (ai.KeepName) { fileName = OriginalFileName; } else { - if (!m_Info.KeepName) + if (!Info.KeepName) { int dotPos = fileName.ReverseFind('.'); int slashPos = MyMax(fileName.ReverseFind('\\'), fileName.ReverseFind('/')); @@ -736,10 +721,10 @@ int CCompressDialog::GetStaticFormatIndex() } void CCompressDialog::SetNearestSelectComboBox( - NControl::CComboBox &comboBox, UINT32 value) + NControl::CComboBox &comboBox, UInt32 value) { for (int i = comboBox.GetCount() - 1; i >= 0; i--) - if (comboBox.GetItemData(i) <= value) + if ((UInt32)comboBox.GetItemData(i) <= value) { comboBox.SetCurSel(i); return; @@ -754,7 +739,7 @@ void CCompressDialog::SetLevel() const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; const CArchiverInfo &ai = m_ArchiverInfoList[m_Format.GetCurSel()]; int index = FindRegistryFormat(ai.Name); - UINT32 level = kNormal; + UInt32 level = kNormal; if (index >= 0) { const NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index]; @@ -817,9 +802,14 @@ void CCompressDialog::SetMethod() const NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index]; defaultMethod = GetUnicodeString(fo.Method); } + bool isSfx = IsSFX(); for(int m = 0; m < fi.NumMethods; m++) { - const LPCWSTR method = kMethodsNames[fi.MathodIDs[m]]; + EMethodID methodID = fi.MathodIDs[m]; + if (isSfx) + if (!IsMethodSupportedBySfx(methodID)) + continue; + const LPCWSTR method = kMethodsNames[methodID]; int itemIndex = m_Method.AddString(GetSystemString(method)); if (defaultMethod.CompareNoCase(method) == 0 || m == 0) m_Method.SetCurSel(itemIndex); @@ -848,15 +838,15 @@ CSysString CCompressDialog::GetMethodSpec() return result; } -int CCompressDialog::AddDictionarySize(UINT32 size, bool kilo, bool maga) +int CCompressDialog::AddDictionarySize(UInt32 size, bool kilo, bool maga) { - UINT32 sizePrint = size; + UInt32 sizePrint = size; if (kilo) sizePrint >>= 10; else if (maga) sizePrint >>= 20; TCHAR s[40]; - ConvertUINT64ToString(sizePrint, s); + ConvertUInt64ToString(sizePrint, s); if (kilo) lstrcat(s, TEXT(" K")); else if (maga) @@ -869,7 +859,7 @@ int CCompressDialog::AddDictionarySize(UINT32 size, bool kilo, bool maga) return index; } -int CCompressDialog::AddDictionarySize(UINT32 size) +int CCompressDialog::AddDictionarySize(UInt32 size) { if (size > 0) { @@ -887,7 +877,7 @@ void CCompressDialog::SetDictionary() const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; const CArchiverInfo &ai = m_ArchiverInfoList[m_Format.GetCurSel()]; int index = FindRegistryFormat(ai.Name); - UINT32 defaultDictionary = UINT32(-1); + UInt32 defaultDictionary = UInt32(-1); if (index >= 0) { const NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index]; @@ -905,7 +895,7 @@ void CCompressDialog::SetDictionary() { case kLZMA: { - if (defaultDictionary == UINT32(-1)) + if (defaultDictionary == UInt32(-1)) { if (level >= 9) defaultDictionary = (32 << 20); @@ -923,7 +913,7 @@ void CCompressDialog::SetDictionary() { if (i == 20 && j > 0) continue; - UINT32 dictionary = (1 << i) + (j << (i - 1)); + UInt32 dictionary = (1 << i) + (j << (i - 1)); AddDictionarySize(dictionary); } SetNearestSelectComboBox(m_Dictionary, defaultDictionary); @@ -931,7 +921,7 @@ void CCompressDialog::SetDictionary() } case kPPMd: { - if (defaultDictionary == UINT32(-1)) + if (defaultDictionary == UInt32(-1)) { if (level >= 9) defaultDictionary = (192 << 20); @@ -948,7 +938,7 @@ void CCompressDialog::SetDictionary() { if (i == 20 && j > 0) continue; - UINT32 dictionary = (1 << i) + (j << (i - 1)); + UInt32 dictionary = (1 << i) + (j << (i - 1)); if (dictionary >= (1 << 31)) continue; AddDictionarySize(dictionary); @@ -978,24 +968,24 @@ void CCompressDialog::SetDictionary() SetMemoryUsage(); } -UINT32 CCompressDialog::GetDictionary() +UInt32 CCompressDialog::GetDictionary() { if (m_Dictionary.GetCount() <= 0) return -1; return m_Dictionary.GetItemData(m_Dictionary.GetCurSel()); } -UINT32 CCompressDialog::GetDictionarySpec() +UInt32 CCompressDialog::GetDictionarySpec() { if (m_Dictionary.GetCount() <= 1) return -1; return GetDictionary(); } -int CCompressDialog::AddOrder(UINT32 size) +int CCompressDialog::AddOrder(UInt32 size) { TCHAR s[40]; - ConvertUINT64ToString(size, s); + ConvertUInt64ToString(size, s); int index = m_Order.AddString(s); m_Order.SetItemData(index, size); return index; @@ -1007,7 +997,7 @@ void CCompressDialog::SetOrder() const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; const CArchiverInfo &ai = m_ArchiverInfoList[m_Format.GetCurSel()]; int index = FindRegistryFormat(ai.Name); - UINT32 defaultOrder = UINT32(-1); + UInt32 defaultOrder = UInt32(-1); if (index >= 0) { const NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index]; @@ -1025,7 +1015,7 @@ void CCompressDialog::SetOrder() { case kLZMA: { - if (defaultOrder == UINT32(-1)) + if (defaultOrder == UInt32(-1)) { if (level >= 7) defaultOrder = 64; @@ -1036,7 +1026,7 @@ void CCompressDialog::SetOrder() for (i = 3; i < 8; i++) for (int j = 0; j < 2; j++) { - UINT32 order = (1 << i) + (j << (i - 1)); + UInt32 order = (1 << i) + (j << (i - 1)); if (order < 255) AddOrder(order); } @@ -1046,7 +1036,7 @@ void CCompressDialog::SetOrder() } case kPPMd: { - if (defaultOrder == UINT32(-1)) + if (defaultOrder == UInt32(-1)) { if (level >= 9) defaultOrder = 32; @@ -1063,7 +1053,7 @@ void CCompressDialog::SetOrder() for (i = 2; i < 8; i++) for (int j = 0; j < 4; j++) { - UINT32 order = (1 << i) + (j << (i - 2)); + UInt32 order = (1 << i) + (j << (i - 2)); if (order < 32) AddOrder(order); } @@ -1074,7 +1064,7 @@ void CCompressDialog::SetOrder() case kDeflate: case kDeflate64: { - if (defaultOrder == UINT32(-1)) + if (defaultOrder == UInt32(-1)) { if (level >= 7) defaultOrder = 64; @@ -1085,7 +1075,7 @@ void CCompressDialog::SetOrder() for (i = 3; i < 8; i++) for (int j = 0; j < 2; j++) { - UINT32 order = (1 << i) + (j << (i - 1)); + UInt32 order = (1 << i) + (j << (i - 1)); if (order < 255) AddOrder(order); } @@ -1105,34 +1095,30 @@ bool CCompressDialog::GetOrderMode() { switch (GetMethodID()) { - case kLZMA: - case kDeflate: - case kDeflate64: - return false; case kPPMd: return true; } return false; } -UINT32 CCompressDialog::GetOrder() +UInt32 CCompressDialog::GetOrder() { if (m_Order.GetCount() <= 0) return -1; return m_Order.GetItemData(m_Order.GetCurSel()); } -UINT32 CCompressDialog::GetOrderSpec() +UInt32 CCompressDialog::GetOrderSpec() { if (m_Order.GetCount() <= 1) return -1; return GetOrder(); } -UINT64 CCompressDialog::GetMemoryUsage(UINT64 &decompressMemory) +UInt64 CCompressDialog::GetMemoryUsage(UInt64 &decompressMemory) { - decompressMemory = UINT64(INT64(-1)); - UINT32 dictionary = GetDictionary(); + decompressMemory = UInt64(Int64(-1)); + UInt32 dictionary = GetDictionary(); int level = GetLevel2(); if (level == 0) { @@ -1143,17 +1129,17 @@ UINT64 CCompressDialog::GetMemoryUsage(UINT64 &decompressMemory) { case kLZMA: { - UINT64 size; + UInt64 size; if (level >= 5) { - size = ((UINT64)dictionary * 19 / 2) + (2 << 20); + size = ((UInt64)dictionary * 19 / 2) + (2 << 20); if (level >= 9) size += (34 << 20) + (12 << 20) * 2 + (5 << 20); else size += (6 << 20); } else - size = ((UINT64)dictionary * 11 / 2) + (2 << 20); + size = ((UInt64)dictionary * 11 / 2) + (2 << 20); decompressMemory = dictionary + (2 << 20); return size; } @@ -1165,10 +1151,10 @@ UINT64 CCompressDialog::GetMemoryUsage(UINT64 &decompressMemory) case kDeflate: case kDeflate64: { - UINT32 order = GetOrder(); - if (order == UINT32(-1)) + UInt32 order = GetOrder(); + if (order == UInt32(-1)) order = 32; - UINT64 size = 0; + UInt64 size = 0; if (level >= 7) size = (order * 2 + 4) * (64 << 10); size += 3 << 20; @@ -1181,27 +1167,27 @@ UINT64 CCompressDialog::GetMemoryUsage(UINT64 &decompressMemory) return 10 << 20; } } - return UINT64(INT64(-1)); + return UInt64(Int64(-1)); } -void CCompressDialog::PrintMemUsage(UINT res, UINT64 value) +void CCompressDialog::PrintMemUsage(UINT res, UInt64 value) { - if (value == (UINT64)INT64(-1)) + if (value == (UInt64)Int64(-1)) { SetItemText(res, TEXT("?")); return; } value = (value + (1 << 20) - 1) >> 20; TCHAR s[40]; - ConvertUINT64ToString(value, s); + ConvertUInt64ToString(value, s); lstrcat(s, TEXT(" MB")); SetItemText(res, s); } void CCompressDialog::SetMemoryUsage() { - UINT64 decompressMem; - UINT64 memUsage = GetMemoryUsage(decompressMem); + UInt64 decompressMem; + UInt64 memUsage = GetMemoryUsage(decompressMem); PrintMemUsage(IDC_STATIC_COMPRESS_MEMORY_VALUE, memUsage); PrintMemUsage(IDC_STATIC_COMPRESS_MEMORY_DE_VALUE, decompressMem); } @@ -1220,12 +1206,12 @@ void CCompressDialog::SetParams() void CCompressDialog::SaveOptionsInMem() { - const CArchiverInfo &ai = m_ArchiverInfoList[m_Info.ArchiverInfoIndex]; + const CArchiverInfo &ai = m_ArchiverInfoList[Info.ArchiverInfoIndex]; int index = FindRegistryFormatAlways(ai.Name); - m_Params.GetText(m_Info.Options); - m_Info.Options.Trim(); + m_Params.GetText(Info.Options); + Info.Options.Trim(); NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index]; - fo.Options = m_Info.Options; + fo.Options = GetSystemString(Info.Options); fo.Level = GetLevelSpec(); fo.Dictionary = GetDictionarySpec(); fo.Order = GetOrderSpec(); diff --git a/7zip/UI/GUI/CompressDialog.h b/7zip/UI/GUI/CompressDialog.h index 6662c683..8afa423f 100755 --- a/7zip/UI/GUI/CompressDialog.h +++ b/7zip/UI/GUI/CompressDialog.h @@ -1,7 +1,5 @@ // CompressDialog.h -#pragma once - #ifndef __COMPRESSDIALOG_H #define __COMPRESSDIALOG_H @@ -34,15 +32,14 @@ namespace NCompressDialog bool MultiThreadIsAllowed; bool MultiThread; - bool VolumeSizeIsDefined; - UINT64 VolumeSize; + CRecordVector<UInt64> VolumeSizes; - UINT32 Level; + UInt32 Level; UString Method; - UINT32 Dictionary; + UInt32 Dictionary; bool OrderMode; - UINT32 Order; - CSysString Options; + UInt32 Order; + UString Options; bool SFXMode; @@ -54,9 +51,13 @@ namespace NCompressDialog int ArchiverInfoIndex; + UString Password; + bool EncryptHeadersIsAllowed; + bool EncryptHeaders; + void Init() { - Level = Dictionary = Order = UINT32(-1); + Level = Dictionary = Order = UInt32(-1); OrderMode = false; Method.Empty(); Options.Empty(); @@ -97,7 +98,7 @@ class CCompressDialog: public NWindows::NControl::CModalDialog int GetStaticFormatIndex(); void SetNearestSelectComboBox( - NWindows::NControl::CComboBox &comboBox, UINT32 value); + NWindows::NControl::CComboBox &comboBox, UInt32 value); void SetLevel(); int GetLevel(); @@ -108,21 +109,21 @@ class CCompressDialog: public NWindows::NControl::CModalDialog int GetMethodID(); CSysString GetMethodSpec(); - AddDictionarySize(UINT32 size, bool kilo, bool maga); - AddDictionarySize(UINT32 size); + AddDictionarySize(UInt32 size, bool kilo, bool maga); + AddDictionarySize(UInt32 size); void SetDictionary(); - UINT32 GetDictionary(); - UINT32 GetDictionarySpec(); + UInt32 GetDictionary(); + UInt32 GetDictionarySpec(); - int AddOrder(UINT32 size); + int AddOrder(UInt32 size); void SetOrder(); bool GetOrderMode(); - UINT32 GetOrder(); - UINT32 GetOrderSpec(); + UInt32 GetOrder(); + UInt32 GetOrderSpec(); - UINT64 GetMemoryUsage(UINT64 &decompressMemory); - void PrintMemUsage(UINT res, UINT64 value); + UInt64 GetMemoryUsage(UInt64 &decompressMemory); + void PrintMemUsage(UINT res, UInt64 value); void SetMemoryUsage(); void SetParams(); void SaveOptionsInMem(); @@ -131,13 +132,9 @@ class CCompressDialog: public NWindows::NControl::CModalDialog public: CObjectVector<CArchiverInfo> m_ArchiverInfoList; - NCompressDialog::CInfo m_Info; + NCompressDialog::CInfo Info; UString OriginalFileName; // for bzip2, gzip2 - CSysString Password; - bool EncryptHeadersIsAllowed; - bool EncryptHeaders; - INT_PTR Create(HWND wndParent = 0) { return CModalDialog::Create(MAKEINTRESOURCE(IDD_DIALOG_COMPRESS ), wndParent); } diff --git a/7zip/UI/GUI/Extract.cpp b/7zip/UI/GUI/Extract.cpp deleted file mode 100755 index f8ed33af..00000000 --- a/7zip/UI/GUI/Extract.cpp +++ /dev/null @@ -1,225 +0,0 @@ -// Extract.h - -#include "StdAfx.h" - -#include "Extract.h" - -#include "Common/StringConvert.h" - -#include "Windows/FileDir.h" -#include "Windows/Error.h" -#include "Windows/FileFind.h" -#ifndef EXCLUDE_COM -#include "Windows/DLL.h" -#endif -#include "Windows/Thread.h" - -#include "../Common/OpenArchive.h" -#include "../Common/DefaultName.h" - -#ifndef EXCLUDE_COM -#include "../Common/ZipRegistry.h" -#endif - -#include "../Resource/Extract/resource.h" - -#include "../Explorer/MyMessages.h" -#include "../../FileManager/FormatUtils.h" - -#include "ExtractDialog.h" -#include "../../FileManager/ExtractCallback.h" - -#include "../Agent/ArchiveExtractCallback.h" - -#include "../../FileManager/OpenCallback.h" - -using namespace NWindows; - -struct CThreadExtracting -{ - #ifndef EXCLUDE_COM - NDLL::CLibrary Library; - #endif - CMyComPtr<IInArchive> Archive; - CExtractCallbackImp *ExtractCallbackSpec; - CMyComPtr<IFolderArchiveExtractCallback> ExtractCallback2; - CMyComPtr<IArchiveExtractCallback> ArchiveExtractCallback; - - HRESULT Result; - - DWORD Process() - { - ExtractCallbackSpec->ProgressDialog.WaitCreating(); - Result = Archive->Extract(0, -1, BoolToInt(false), - ArchiveExtractCallback); - ExtractCallbackSpec->ProgressDialog.MyClose(); - return 0; - } - static DWORD WINAPI MyThreadFunction(void *param) - { - return ((CThreadExtracting *)param)->Process(); - } -}; - -static inline UINT GetCurrentFileCodePage() - { return AreFileApisANSI() ? CP_ACP : CP_OEMCP; } - -HRESULT ExtractArchive(HWND parentWindow, const UString &fileName, - bool assumeYes, bool showDialog, const UString &outputFolder) -{ - CThreadExtracting extracter; - - CArchiverInfo archiverInfo; - - COpenArchiveCallback *openCallbackSpec = new COpenArchiveCallback; - CMyComPtr<IArchiveOpenCallback> openCallback = openCallbackSpec; - openCallbackSpec->_passwordIsDefined = false; - openCallbackSpec->_parentWindow = parentWindow; - - UString fullName; - int fileNamePartStartIndex; - NFile::NDirectory::MyGetFullPathName(fileName, fullName, fileNamePartStartIndex); - - openCallbackSpec->LoadFileInfo( - fullName.Left(fileNamePartStartIndex), - fullName.Mid(fileNamePartStartIndex)); - - int subExtIndex; - HRESULT res = OpenArchive(fileName, - #ifndef EXCLUDE_COM - &extracter.Library, - #endif - &extracter.Archive, archiverInfo, subExtIndex, openCallback); - RINOK(res); - - NFile::NFind::CFileInfoW fileInfo; - if (!NFile::NFind::FindFile(fileName, fileInfo)) - return E_FAIL; - UString defaultName = GetDefaultName(fileName, - archiverInfo.Extensions[subExtIndex].Extension, - archiverInfo.Extensions[subExtIndex].AddExtension); - - UString directoryPath; - NExtractionDialog::CModeInfo extractModeInfo; - UString password; - if (openCallbackSpec->_passwordIsDefined) - password = openCallbackSpec->_password; - if (showDialog) - { - CExtractDialog dialog; - if (!NFile::NDirectory::MyGetFullPathName(outputFolder, dialog.DirectoryPath)) - { - MyMessageBox(L"Error 32432432"); - return E_FAIL; - } - // dialog.DirectoryPath = outputFolder; - // dialog.FilesMode = NExtractionDialog::NFilesMode::kAll; - // dialog._enableSelectedFilesButton = false; - dialog.Password = password; - - if(dialog.Create(parentWindow) != IDOK) - return E_ABORT; - directoryPath = dialog.DirectoryPath; - dialog.GetModeInfo(extractModeInfo); - - password = dialog.Password; - } - else - { - if (!NFile::NDirectory::MyGetFullPathName(outputFolder, directoryPath)) - { - MyMessageBox(L"Error 98324982"); - return E_FAIL; - } - NFile::NName::NormalizeDirPathPrefix(directoryPath); - - extractModeInfo.PathMode = NExtractionDialog::NPathMode::kFullPathnames; - extractModeInfo.OverwriteMode = assumeYes ? - NExtractionDialog::NOverwriteMode::kWithoutPrompt: - NExtractionDialog::NOverwriteMode::kAskBefore; - // extractModeInfo.FilesMode = NExtractionDialog::NFilesMode::kAll; - } - if(!NFile::NDirectory::CreateComplexDirectory(directoryPath)) - { - UString s = GetUnicodeString(NError::MyFormatMessage(GetLastError())); - UString s2 = MyFormatNew(IDS_CANNOT_CREATE_FOLDER, - #ifdef LANG - 0x02000603, - #endif - directoryPath); - MyMessageBox(s2 + UString(L"\n") + s); - return E_FAIL; - } - - extracter.ExtractCallbackSpec = new CExtractCallbackImp; - - extracter.ExtractCallback2 = extracter.ExtractCallbackSpec; - - extracter.ExtractCallbackSpec->_parentWindow = 0; - #ifdef LANG - const UString title = LangLoadStringW(IDS_PROGRESS_EXTRACTING, 0x02000890); - #else - const UString title = NWindows::MyLoadStringW(IDS_PROGRESS_EXTRACTING); - #endif - - NFile::NFind::CFileInfoW archiveFileInfo; - if (!NFile::NFind::FindFile(fileName, archiveFileInfo)) - throw "there is no archive file"; - - extracter.ExtractCallbackSpec->Init(NExtractionMode::NOverwrite::kAskBefore, - !password.IsEmpty(), password); - - NExtractionMode::NPath::EEnum pathMode; - NExtractionMode::NOverwrite::EEnum overwriteMode; - switch (extractModeInfo.OverwriteMode) - { - case NExtractionDialog::NOverwriteMode::kAskBefore: - overwriteMode = NExtractionMode::NOverwrite::kAskBefore; - break; - case NExtractionDialog::NOverwriteMode::kWithoutPrompt: - overwriteMode = NExtractionMode::NOverwrite::kWithoutPrompt; - break; - case NExtractionDialog::NOverwriteMode::kSkipExisting: - overwriteMode = NExtractionMode::NOverwrite::kSkipExisting; - break; - case NExtractionDialog::NOverwriteMode::kAutoRename: - overwriteMode = NExtractionMode::NOverwrite::kAutoRename; - break; - default: - throw 12334454; - } - switch (extractModeInfo.PathMode) - { - case NExtractionDialog::NPathMode::kFullPathnames: - pathMode = NExtractionMode::NPath::kFullPathnames; - break; - case NExtractionDialog::NPathMode::kCurrentPathnames: - pathMode = NExtractionMode::NPath::kCurrentPathnames; - break; - case NExtractionDialog::NPathMode::kNoPathnames: - pathMode = NExtractionMode::NPath::kNoPathnames; - break; - default: - throw 12334455; - } - - CArchiveExtractCallback *extractCallbackSpec = new - CArchiveExtractCallback; - extracter.ArchiveExtractCallback = extractCallbackSpec; - - extractCallbackSpec->Init(extracter.Archive, - extracter.ExtractCallback2, - directoryPath, pathMode, - overwriteMode, UStringVector(), - defaultName, - fileInfo.LastWriteTime, fileInfo.Attributes); - - CThread thread; - if (!thread.Create(CThreadExtracting::MyThreadFunction, &extracter)) - throw 271824; - extracter.ExtractCallbackSpec->StartProgressDialog(title); - return extracter.Result; -} - - - diff --git a/7zip/UI/GUI/Extract.h b/7zip/UI/GUI/Extract.h deleted file mode 100755 index 0c2b6dbe..00000000 --- a/7zip/UI/GUI/Extract.h +++ /dev/null @@ -1,12 +0,0 @@ -// GUI/Extract.h - -#ifndef __GUI_EXTRACT_H -#define __GUI_EXTRACT_H - -#include "Common/String.h" - -HRESULT ExtractArchive(HWND parentWindow, const UString &fileName, - bool assumeYes, bool showDialog, const UString &outputFolder); - -#endif - diff --git a/7zip/UI/GUI/ExtractDialog.cpp b/7zip/UI/GUI/ExtractDialog.cpp index 322b22f8..43c04ae3 100755 --- a/7zip/UI/GUI/ExtractDialog.cpp +++ b/7zip/UI/GUI/ExtractDialog.cpp @@ -31,21 +31,40 @@ using namespace NWindows; using namespace NFile; using namespace NName; -static const int kPathnamesButtons[] = +static const int kPathModeButtons[] = { IDC_EXTRACT_RADIO_FULL_PATHNAMES, IDC_EXTRACT_RADIO_CURRENT_PATHNAMES, IDC_EXTRACT_RADIO_NO_PATHNAMES }; -static const int kNumPathnamesButtons = sizeof(kPathnamesButtons) / sizeof(kPathnamesButtons[0]); + +static const NExtract::NPathMode::EEnum kPathModeButtonsVals[] = +{ + NExtract::NPathMode::kFullPathnames, + NExtract::NPathMode::kCurrentPathnames, + NExtract::NPathMode::kNoPathnames +}; + +static const int kNumPathnamesButtons = sizeof(kPathModeButtons) / sizeof(kPathModeButtons[0]); static const int kOverwriteButtons[] = { IDC_EXTRACT_RADIO_ASK_BEFORE_OVERWRITE, IDC_EXTRACT_RADIO_OVERWRITE_WITHOUT_PROMPT, IDC_EXTRACT_RADIO_SKIP_EXISTING_FILES, - IDC_EXTRACT_RADIO_AUTO_RENAME + IDC_EXTRACT_RADIO_AUTO_RENAME, + IDC_EXTRACT_RADIO_AUTO_RENAME_EXISTING, }; + +static const NExtract::NOverwriteMode::EEnum kOverwriteButtonsVals[] = +{ + NExtract::NOverwriteMode::kAskBefore, + NExtract::NOverwriteMode::kWithoutPrompt, + NExtract::NOverwriteMode::kSkipExisting, + NExtract::NOverwriteMode::kAutoRename, + NExtract::NOverwriteMode::kAutoRenameExisting +}; + static const int kNumOverwriteButtons = sizeof(kOverwriteButtons) / sizeof(kOverwriteButtons[0]); /* @@ -58,22 +77,60 @@ static const int kNumFilesButtons = sizeof(kFilesButtons) / sizeof(kFilesButtons */ #ifndef _SFX -int CExtractDialog::GetPathNameMode() const +void CExtractDialog::GetPathMode() { for (int i = 0; i < kNumPathnamesButtons; i++) - if(IsButtonCheckedBool(kPathnamesButtons[i])) - return i; - throw 0; + if(IsButtonCheckedBool(kPathModeButtons[i])) + { + PathMode = kPathModeButtonsVals[i]; + return; + } + throw 1; +} + +void CExtractDialog::SetPathMode() +{ + for (int j = 0; j < 2; j++) + { + for (int i = 0; i < kNumPathnamesButtons; i++) + if(PathMode == kPathModeButtonsVals[i]) + { + CheckRadioButton(kPathModeButtons[0], kPathModeButtons[kNumPathnamesButtons - 1], + kPathModeButtons[i]); + return; + } + PathMode = kPathModeButtonsVals[0]; + } + throw 1; } -int CExtractDialog::GetOverwriteMode() const +void CExtractDialog::GetOverwriteMode() { for (int i = 0; i < kNumOverwriteButtons; i++) if(IsButtonCheckedBool(kOverwriteButtons[i])) - return i; + { + OverwriteMode = kOverwriteButtonsVals[i]; + return; + } throw 0; } +void CExtractDialog::SetOverwriteMode() +{ + for (int j = 0; j < 2; j++) + { + for (int i = 0; i < kNumOverwriteButtons; i++) + if(OverwriteMode == kOverwriteButtonsVals[i]) + { + CheckRadioButton(kOverwriteButtons[0], kOverwriteButtons[kNumOverwriteButtons - 1], + kOverwriteButtons[i]); + return; + } + OverwriteMode = kOverwriteButtonsVals[0]; + } + throw 1; +} + /* int CExtractDialog::GetFilesMode() const { @@ -99,6 +156,7 @@ static CIDLangPair kIDLangPairs[] = { IDC_EXTRACT_RADIO_OVERWRITE_WITHOUT_PROMPT, 0x02000822 }, { IDC_EXTRACT_RADIO_SKIP_EXISTING_FILES, 0x02000823 }, { IDC_EXTRACT_RADIO_AUTO_RENAME, 0x02000824 }, + { IDC_EXTRACT_RADIO_AUTO_RENAME_EXISTING, 0x02000825 }, { IDC_EXTRACT_FILES, 0x02000830 }, { IDC_EXTRACT_RADIO_SELECTED_FILES, 0x02000831 }, { IDC_EXTRACT_RADIO_ALL_FILES, 0x02000832 }, @@ -127,19 +185,20 @@ bool CExtractDialog::OnInit() _passwordControl.SetPasswordChar(TEXT('*')); #endif - NExtraction::CInfo extractionInfo; + NExtract::CInfo extractionInfo; #ifdef NO_REGISTRY - extractionInfo.PathMode = NExtraction::NPathMode::kFullPathnames; - extractionInfo.OverwriteMode = NExtraction::NOverwriteMode::kAskBefore; - // extractionInfo.Paths = NExtraction::NPathMode::kFullPathnames; + PathMode = NExtract::NPathMode::kFullPathnames; + OverwriteMode = NExtract::NOverwriteMode::kAskBefore; + // extractionInfo.Paths = NExtract::NPathMode::kFullPathnames; #else ReadExtractionInfo(extractionInfo); CheckButton(IDC_EXTRACT_CHECK_SHOW_PASSWORD, extractionInfo.ShowPassword); UpdatePasswordControl(); + PathMode = extractionInfo.PathMode; + OverwriteMode = extractionInfo.OverwriteMode; #endif - _path.Attach(GetItem(IDC_EXTRACT_COMBO_PATH)); _path.SetText(DirectoryPath); @@ -155,15 +214,10 @@ bool CExtractDialog::OnInit() */ - _pathMode = extractionInfo.PathMode; - _overwriteMode = extractionInfo.OverwriteMode; #ifndef _SFX - CheckRadioButton(kPathnamesButtons[0], kPathnamesButtons[kNumPathnamesButtons - 1], - kPathnamesButtons[_pathMode]); - - CheckRadioButton(kOverwriteButtons[0], kOverwriteButtons[kNumOverwriteButtons - 1], - kOverwriteButtons[_overwriteMode]); + SetPathMode(); + SetOverwriteMode(); /* CheckRadioButton(kFilesButtons[0], kFilesButtons[kNumFilesButtons - 1], @@ -177,8 +231,8 @@ bool CExtractDialog::OnInit() #endif - // CWindow aFilesWindow = GetItem(IDC_EXTRACT_RADIO_FILES); - // aFilesWindow.Enable(_enableFilesButton); + // CWindow filesWindow = GetItem(IDC_EXTRACT_RADIO_FILES); + // filesWindow.Enable(_enableFilesButton); // UpdateWildCardState(); return CModalDialog::OnInit(); @@ -254,16 +308,16 @@ void AddUniqueString(CSysStringVector &list, const CSysString &s) void CExtractDialog::OnOK() { #ifndef _SFX - _pathMode = GetPathNameMode(); - _overwriteMode = GetOverwriteMode(); + GetPathMode(); + GetOverwriteMode(); // _filesMode = (NExtractionDialog::NFilesMode::EEnum)GetFilesMode(); _passwordControl.GetText(Password); #endif - NExtraction::CInfo extractionInfo; - extractionInfo.PathMode = NExtraction::NPathMode::EEnum(_pathMode); - extractionInfo.OverwriteMode = NExtraction::NOverwriteMode::EEnum(_overwriteMode); + NExtract::CInfo extractionInfo; + extractionInfo.PathMode = PathMode; + extractionInfo.OverwriteMode = OverwriteMode; extractionInfo.ShowPassword = (IsButtonChecked( IDC_EXTRACT_CHECK_SHOW_PASSWORD) == BST_CHECKED); @@ -318,54 +372,12 @@ void CExtractDialog::UpdateWildCardState() } */ -/* -static DWORD aHelpArray[] = -{ - IDC_EXTRACT_COMBO_PATH, IDH_EXTRACT_COMBO_PATH, - IDC_EXTRACT_BUTTON_SET_PATH, IDH_EXTRACT_BUTTON_SET_PATH, - - IDC_EXTRACT_PATH_MODE, IDH_EXTRACT_PATH_MODE, - IDC_EXTRACT_RADIO_FULL_PATHNAMES, IDH_EXTRACT_RADIO_FULL_PATHNAMES, - IDC_EXTRACT_RADIO_CURRENT_PATHNAMES,IDH_EXTRACT_RADIO_CURRENT_PATHNAMES, - IDC_EXTRACT_RADIO_NO_PATHNAMES,IDH_EXTRACT_RADIO_NO_PATHNAMES, - - IDC_EXTRACT_OVERWRITE_MODE, IDH_EXTRACT_OVERWRITE_MODE, - IDC_EXTRACT_RADIO_ASK_BEFORE_OVERWRITE, IDH_EXTRACT_RADIO_ASK_BEFORE_OVERWRITE, - IDC_EXTRACT_RADIO_OVERWRITE_WITHOUT_PROMPT, IDH_EXTRACT_RADIO_OVERWRITE_WITHOUT_PROMPT, - IDC_EXTRACT_RADIO_SKIP_EXISTING_FILES, IDH_EXTRACT_RADIO_SKIP_EXISTING_FILES, - - IDC_EXTRACT_FILES, IDH_EXTRACT_FILES, - IDC_EXTRACT_RADIO_SELECTED_FILES, IDH_EXTRACT_RADIO_SELECTED_FILES, - IDC_EXTRACT_RADIO_ALL_FILES, IDH_EXTRACT_RADIO_ALL_FILES, - IDC_EXTRACT_RADIO_FILES, IDH_EXTRACT_RADIO_FILES, - IDC_EXTRACT_EDIT_WILDCARDS, IDH_EXTRACT_EDIT_WILDCARDS, - 0,0 -}; -*/ - - -void CExtractDialog::GetModeInfo(NExtractionDialog::CModeInfo &modeInfo) -{ - modeInfo.OverwriteMode = NExtractionDialog::NOverwriteMode::EEnum(_overwriteMode); - modeInfo.PathMode = NExtractionDialog::NPathMode::EEnum(_pathMode); - // modeInfo.FilesMode = NExtractionDialog::NFilesMode::EEnum(FilesMode); - modeInfo.FileList.Clear(); -} - #ifndef NO_REGISTRY static LPCWSTR kHelpTopic = L"fm/plugins/7-zip/extract.htm"; void CExtractDialog::OnHelp() { ShowHelpWindow(NULL, kHelpTopic); CModalDialog::OnHelp(); - /* - if (pHelpInfo->iContextType == HELPINFO_WINDOW) - { - return ::HtmlHelp((HWND)pHelpInfo->hItemHandle, - TEXT("C:\\SRC\\VC\\ZipView\\Help\\7zip.chm::/Context/Extract.txt"), - HH_TP_HELP_WM_HELP, (DWORD)(LPVOID)aHelpArray) != NULL; - } - */ } #endif diff --git a/7zip/UI/GUI/ExtractDialog.h b/7zip/UI/GUI/ExtractDialog.h index 3efbcbd0..94027f4c 100755 --- a/7zip/UI/GUI/ExtractDialog.h +++ b/7zip/UI/GUI/ExtractDialog.h @@ -1,7 +1,5 @@ // ExtractDialog.h -#pragma once - #ifndef __EXTRACTDIALOG_H #define __EXTRACTDIALOG_H @@ -14,9 +12,11 @@ #ifndef NO_REGISTRY #include "../Common/ZipRegistry.h" #endif +#include "../Common/ExtractMode.h" namespace NExtractionDialog { + /* namespace NFilesMode { enum EEnum @@ -26,32 +26,7 @@ namespace NExtractionDialog kSpecified }; } - namespace NPathMode - { - enum EEnum - { - kFullPathnames, - kCurrentPathnames, - kNoPathnames, - }; - } - namespace NOverwriteMode - { - enum EEnum - { - kAskBefore, - kWithoutPrompt, - kSkipExisting, - kAutoRename - }; - } - struct CModeInfo - { - NOverwriteMode::EEnum OverwriteMode; - NPathMode::EEnum PathMode; - // NFilesMode::EEnum FilesMode; - UStringVector FileList; - }; + */ } class CExtractDialog: public NWindows::NControl::CModalDialog @@ -66,12 +41,11 @@ class CExtractDialog: public NWindows::NControl::CModalDialog NWindows::NControl::CEdit _passwordControl; #endif - int _pathMode; - int _overwriteMode; - #ifndef _SFX - int GetPathNameMode() const; - int GetOverwriteMode() const; + void GetPathMode(); + void SetPathMode(); + void GetOverwriteMode(); + void SetOverwriteMode(); // int GetFilesMode() const; void UpdatePasswordControl(); #endif @@ -87,13 +61,15 @@ class CExtractDialog: public NWindows::NControl::CModalDialog public: // bool _enableSelectedFilesButton; // bool _enableFilesButton; - UString DirectoryPath; // NExtractionDialog::NFilesMode::EEnum FilesMode; + + UString DirectoryPath; UString Password; + NExtract::NPathMode::EEnum PathMode; + NExtract::NOverwriteMode::EEnum OverwriteMode; INT_PTR Create(HWND aWndParent = 0) { return CModalDialog::Create(MAKEINTRESOURCE(IDD_DIALOG_EXTRACT), aWndParent); } - void GetModeInfo(NExtractionDialog::CModeInfo &modeInfo); }; #endif diff --git a/7zip/UI/GUI/ExtractGUI.cpp b/7zip/UI/GUI/ExtractGUI.cpp new file mode 100755 index 00000000..d176623f --- /dev/null +++ b/7zip/UI/GUI/ExtractGUI.cpp @@ -0,0 +1,174 @@ +// ExtractGUI.cpp + +#include "StdAfx.h" + +#include "ExtractGUI.h" + +#include "Common/StringConvert.h" + +#include "Windows/FileDir.h" +#include "Windows/Error.h" +#include "Windows/FileFind.h" +#include "Windows/Thread.h" + +#include "../../FileManager/FormatUtils.h" +#include "../../FileManager/ExtractCallback.h" + +#include "../Common/ArchiveExtractCallback.h" +#include "../Explorer/MyMessages.h" +#include "../Resource/Extract/resource.h" + +#include "OpenCallbackGUI.h" +#include "ExtractDialog.h" + +using namespace NWindows; + +static const wchar_t *kIncorrectOutDir = L"Incorrect output directory path"; + +struct CThreadExtracting +{ + CExtractCallbackImp *ExtractCallbackSpec; + + UStringVector *ArchivePaths; + UStringVector *ArchivePathsFull; + const NWildcard::CCensorNode *WildcardCensor; + const CExtractOptions *Options; + COpenCallbackGUI *OpenCallback; + CMyComPtr<IExtractCallbackUI> ExtractCallback; + + UString ErrorMessage; + HRESULT Result; + + DWORD Process() + { + ExtractCallbackSpec->ProgressDialog.WaitCreating(); + try + { + Result = DecompressArchives(*ArchivePaths, *ArchivePathsFull, + *WildcardCensor, *Options, OpenCallback, ExtractCallback); + } + catch(const UString &s) + { + ErrorMessage = s; + Result = E_FAIL; + } + catch(const wchar_t *s) + { + ErrorMessage = s; + Result = E_FAIL; + } + catch(const char *s) + { + ErrorMessage = GetUnicodeString(s); + Result = E_FAIL; + } + catch(...) + { + Result = E_FAIL; + } + ExtractCallbackSpec->ProgressDialog.MyClose(); + return 0; + } + static DWORD WINAPI MyThreadFunction(void *param) + { + return ((CThreadExtracting *)param)->Process(); + } +}; + +HRESULT ExtractGUI( + UStringVector &archivePaths, + UStringVector &archivePathsFull, + const NWildcard::CCensorNode &wildcardCensor, + CExtractOptions &options, + bool showDialog, + COpenCallbackGUI *openCallback, + CExtractCallbackImp *extractCallback) +{ + CThreadExtracting extracter; + + if (!options.TestMode) + { + UString outputDir = options.OutputDir; + if (outputDir.IsEmpty()) + NFile::NDirectory::MyGetCurrentDirectory(outputDir); + if (showDialog) + { + CExtractDialog dialog; + if (!NFile::NDirectory::MyGetFullPathName(outputDir, dialog.DirectoryPath)) + { + MyMessageBox(kIncorrectOutDir); + return E_FAIL; + } + NFile::NName::NormalizeDirPathPrefix(dialog.DirectoryPath); + + // dialog.OverwriteMode = options.OverwriteMode; + // dialog.PathMode = options.PathMode; + + if(dialog.Create(0) != IDOK) + return E_ABORT; + outputDir = dialog.DirectoryPath; + options.OverwriteMode = dialog.OverwriteMode; + options.PathMode = dialog.PathMode; + openCallback->Password = dialog.Password; + openCallback->PasswordIsDefined = !dialog.Password.IsEmpty(); + } + if (!NFile::NDirectory::MyGetFullPathName(outputDir, options.OutputDir)) + { + MyMessageBox(kIncorrectOutDir); + return E_FAIL; + } + NFile::NName::NormalizeDirPathPrefix(options.OutputDir); + + /* + if(!NFile::NDirectory::CreateComplexDirectory(options.OutputDir)) + { + UString s = GetUnicodeString(NError::MyFormatMessage(GetLastError())); + UString s2 = MyFormatNew(IDS_CANNOT_CREATE_FOLDER, + #ifdef LANG + 0x02000603, + #endif + options.OutputDir); + MyMessageBox(s2 + UString(L"\n") + s); + return E_FAIL; + } + */ + } + + UString title = + #ifdef LANG + LangLoadStringW(options.TestMode ? IDS_PROGRESS_TESTING : IDS_PROGRESS_EXTRACTING, + options.TestMode ? 0x02000F90: 0x02000890); + #else + NWindows::MyLoadStringW(options.TestMode ? IDS_PROGRESS_TESTING : IDS_PROGRESS_EXTRACTING); + #endif + + extracter.ExtractCallbackSpec = extractCallback; + extracter.ExtractCallback = extractCallback; + extracter.ExtractCallbackSpec->Init(); + + extracter.ArchivePaths = &archivePaths; + extracter.ArchivePathsFull = &archivePathsFull; + extracter.WildcardCensor = &wildcardCensor; + extracter.Options = &options; + extracter.OpenCallback = openCallback; + + CThread thread; + if (!thread.Create(CThreadExtracting::MyThreadFunction, &extracter)) + throw 271824; + extracter.ExtractCallbackSpec->StartProgressDialog(title); + if (extracter.Result == S_OK && options.TestMode && extracter.ExtractCallbackSpec->Messages.IsEmpty()) + { + #ifndef _SFX + MessageBoxW(0, LangLoadStringW(IDS_MESSAGE_NO_ERRORS, 0x02000608), + LangLoadStringW(IDS_PROGRESS_TESTING, 0x02000F90), 0); + #endif + } + if (extracter.Result != S_OK) + { + if (!extracter.ErrorMessage.IsEmpty()) + throw extracter.ErrorMessage; + } + return extracter.Result; +} + + diff --git a/7zip/UI/GUI/ExtractGUI.h b/7zip/UI/GUI/ExtractGUI.h new file mode 100755 index 00000000..5a0b157d --- /dev/null +++ b/7zip/UI/GUI/ExtractGUI.h @@ -0,0 +1,20 @@ +// GUI/ExtractGUI.h + +#ifndef __EXTRACT_GUI_H +#define __EXTRACT_GUI_H + +#include "../Common/Extract.h" +#include "OpenCallbackGUI.h" + +#include "../../FileManager/ExtractCallback.h" + +HRESULT ExtractGUI( + UStringVector &archivePaths, + UStringVector &archivePathsFull, + const NWildcard::CCensorNode &wildcardCensor, + CExtractOptions &options, + bool showDialog, + COpenCallbackGUI *openCallback, + CExtractCallbackImp *extractCallback); + +#endif diff --git a/7zip/UI/GUI/GUI.cpp b/7zip/UI/GUI/GUI.cpp index 71772d4a..51a6250b 100755 --- a/7zip/UI/GUI/GUI.cpp +++ b/7zip/UI/GUI/GUI.cpp @@ -7,355 +7,228 @@ #include "Common/NewHandler.h" #include "Common/StringConvert.h" #include "Common/CommandLineParser.h" +#include "Common/Exception.h" #include "Windows/COM.h" #include "Windows/FileMapping.h" #include "Windows/FileDir.h" #include "Windows/Synchronization.h" +#include "Windows/Error.h" #include "Windows/FileName.h" #include "../../IStream.h" #include "../../IPassword.h" -// #include "../../Compress/Interface/CompressInterface.h" -// #include "../../FileManager/FolderInterface.h" #include "../../FileManager/StringUtils.h" +#include "../Common/ExitCode.h" +#include "../Common/ArchiveCommandLine.h" + #include "../Resource/Extract/resource.h" -#include "../Agent/Agent.h" -// #include "../Common/FolderArchiveInterface.h" #include "../Explorer/MyMessages.h" -#include "Test.h" -#include "Extract.h" -#include "Compress.h" +#include "ExtractGUI.h" +#include "UpdateGUI.h" using namespace NWindows; -using namespace NCommandLineParser; HINSTANCE g_hInstance; -static const int kNumSwitches = 5; - -namespace NKey { -enum Enum -{ - // kHelp1 = 0, - // kHelp2, - // kDisablePercents, - kArchiveType, - // kYes, - // kPassword, - // kProperty, - kOutputDir, - // kWorkingDir, - kInclude, - // kExclude, - // kUpdate, - // kRecursed, - // kSfx, - // kOverwrite, - kEmail, - kShowDialog - // kMap -}; - -} - -static const int kSomeCludePostStringMinSize = 2; // at least <@|!><N>ame must be -static const int kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!><N>ame must be -static const wchar_t *kRecursedPostCharSet = L"0-"; -static const wchar_t *kOverwritePostCharSet = L"asut"; - -static const CSwitchForm kSwitchForms[kNumSwitches] = - { - // { L"?", NSwitchType::kSimple, false }, - // { L"H", NSwitchType::kSimple, false }, - // { L"BD", NSwitchType::kSimple, false }, - { L"T", NSwitchType::kUnLimitedPostString, false, 1 }, - // { L"Y", NSwitchType::kSimple, false }, - // { L"P", NSwitchType::kUnLimitedPostString, false, 0 }, - // { L"M", NSwitchType::kUnLimitedPostString, true, 1 }, - { L"O", NSwitchType::kUnLimitedPostString, false, 1 }, - // { L"W", NSwitchType::kUnLimitedPostString, false, 0 }, - { L"I", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize}, - // { L"X", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize}, - // { L"U", NSwitchType::kUnLimitedPostString, true, 1}, - // { L"R", NSwitchType::kPostChar, false, 0, 0, kRecursedPostCharSet }, - // { L"SFX", NSwitchType::kUnLimitedPostString, false, 0 }, - // { L"AO", NSwitchType::kPostChar, false, 1, 1, kOverwritePostCharSet}, - { L"SEML", NSwitchType::kSimple, false }, - { L"AD", NSwitchType::kSimple, false } - // { L"MAP=", NSwitchType::kUnLimitedPostString, false, 1 } - }; - - -static bool inline IsItWindowsNT() -{ - OSVERSIONINFO versionInfo; - versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); - if (!::GetVersionEx(&versionInfo)) - return false; - return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); -} +static const wchar_t *kExceptionErrorMessage = L"Error:"; +static const wchar_t *kUserBreak = L"Break signaled"; -static void MyMessageBoxError(const char *message) -{ - ::MessageBoxA(0, message, "Error", 0); -} +static const wchar_t *kMemoryExceptionMessage = L"ERROR: Can't allocate required memory!"; +static const wchar_t *kUnknownExceptionMessage = L"Unknown Error"; +static const wchar_t *kInternalExceptionMessage = L"Internal Error #"; -static wchar_t *kIncorrectCommandMessage = L"Incorrect command"; +static const wchar_t *kIncorrectCommandMessage = L"Incorrect command"; static void ErrorMessage(const wchar_t *message) { MessageBoxW(0, message, L"7-Zip GUI", MB_ICONERROR); } -static bool ParseIncludeMap(const UString &switchParam, UStringVector &fileNames) +int Main2() { - int splitPos = switchParam.Find(L':'); - if (splitPos < 0) - { - ErrorMessage(L"Bad switch"); - return false; - } - UString mappingName = switchParam.Left(splitPos); - - UString switchParam2 = switchParam.Mid(splitPos + 1); - splitPos = switchParam2.Find(L':'); - if (splitPos < 0) + /* + TCHAR t[512]; + GetCurrentDirectory(512, t); + ErrorMessage(t); + return 0; + */ + + UStringVector commandStrings; + NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings); + if(commandStrings.Size() <= 1) { - ErrorMessage(L"Bad switch"); - return false; + MessageBoxW(0, L"Specify command", L"7-Zip", 0); + return 0; } + commandStrings.Delete(0); + + CArchiveCommandLineOptions options; + CArchiveCommandLineParser parser; + + parser.Parse1(commandStrings, options); + parser.Parse2(options); - UString mappingSize = switchParam2.Left(splitPos); - UString eventName = switchParam2.Mid(splitPos + 1); - - wchar_t *endptr; - UINT32 dataSize = wcstoul(mappingSize, &endptr, 10); - + bool isExtractGroupCommand = options.Command.IsFromExtractGroup(); + + if (isExtractGroupCommand) { - CFileMapping fileMapping; - if (!fileMapping.Open(FILE_MAP_READ, false, - GetSystemString(mappingName))) - { - // ShowLastErrorMessage(0); - ErrorMessage(L"Can not open mapping"); - return false; - } - LPVOID data = fileMapping.MapViewOfFile(FILE_MAP_READ, 0, dataSize); - if (data == NULL) - { - ErrorMessage(L"MapViewOfFile error"); - return false; - } - try - { - const wchar_t *curData = (const wchar_t *)data; - if (*curData != 0) - { - ErrorMessage(L"Incorrect mapping data"); - return false; - } - UINT32 numChars = dataSize /2; - UString name; - - for (int i = 1; i < numChars; i++) - { - wchar_t c = curData[i]; - if (c == L'\0') - { - fileNames.Add(name); - name.Empty(); - } - else - name += c; - } - if (!name.IsEmpty()) - { - ErrorMessage(L"data error"); - return false; - } - } - catch(...) + CExtractCallbackImp *ecs = new CExtractCallbackImp; + CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs; + ecs->PasswordIsDefined = options.PasswordEnabled; + ecs->Password = options.Password; + ecs->Init(); + + COpenCallbackGUI openCallback; + openCallback.PasswordIsDefined = options.PasswordEnabled; + openCallback.Password = options.Password; + + CExtractOptions eo; + eo.StdOutMode = options.StdOutMode; + eo.OutputDir = options.OutputDir; + eo.YesToAll = options.YesToAll; + eo.OverwriteMode = options.OverwriteMode; + eo.PathMode = options.Command.GetPathMode(); + eo.TestMode = options.Command.IsTestMode(); + + HRESULT result = ExtractGUI( + options.ArchivePathsSorted, + options.ArchivePathsFullSorted, + options.WildcardCensor.Pairs.Front().Head, + eo, options.ShowDialog, &openCallback, ecs); + if (result == S_FALSE) { - UnmapViewOfFile(data); - throw; + MyMessageBox(IDS_OPEN_IS_NOT_SUPORTED_ARCHIVE, 0x02000604); + return NExitCode::kFatalError; } - UnmapViewOfFile(data); + else if (result != S_OK) + throw CSystemException(result); + if (ecs->Messages.Size() > 0) + return NExitCode::kFatalError; } - + else if (options.Command.IsFromUpdateGroup()) { - NSynchronization::CEvent event; - event.Open(EVENT_MODIFY_STATE, false, GetSystemString(eventName)); - event.Set(); - } - return true; -} + bool passwordIsDefined = + options.PasswordEnabled && !options.Password.IsEmpty(); -static bool ParseIncludeSwitches(CParser &parser, UStringVector &fileNames) -{ - if (parser[NKey::kInclude].ThereIs) - { - for (int i = 0; i < parser[NKey::kInclude].PostStrings.Size(); i++) + COpenCallbackGUI openCallback; + openCallback.PasswordIsDefined = passwordIsDefined; + openCallback.Password = options.Password; + + CUpdateCallbackGUI callback; + // callback.EnablePercents = options.EnablePercents; + callback.PasswordIsDefined = passwordIsDefined; + callback.AskPassword = options.PasswordEnabled && options.Password.IsEmpty(); + callback.Password = options.Password; + // callback.StdOutMode = options.UpdateOptions.StdOutMode; + callback.Init(); + + CUpdateErrorInfo errorInfo; + + HRESULT result = UpdateGUI( + options.WildcardCensor, options.UpdateOptions, + options.ShowDialog, + errorInfo, &openCallback, &callback); + + if (result != S_OK) { - UString switchParam = parser[NKey::kInclude].PostStrings[i]; - if (switchParam.Length() < 1) - return false; - if (switchParam[0] == L'#') - { - if (!ParseIncludeMap(switchParam.Mid(1), fileNames)) - return false; - } - else if (switchParam[0] == L'!') - { - fileNames.Add(switchParam.Mid(1)); - } - else - { - ErrorMessage(L"Incorrect command"); - return false; - } + if (!errorInfo.Message.IsEmpty()) + ErrorMessage(errorInfo.Message); + throw CSystemException(result); } + if (callback.FailedFiles.Size() > 0) + return NExitCode::kWarning; } - const UStringVector &nonSwitchStrings = parser.NonSwitchStrings; - for (int i = 2; i < nonSwitchStrings.Size(); i++) + else { - // ErrorMessage(nonSwitchStrings[i]); - fileNames.Add(nonSwitchStrings[i]); + ErrorMessage(L"Use correct command"); + return 0; } - return true; + return 0; +} + +static bool inline IsItWindowsNT() +{ + OSVERSIONINFO versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + if (!::GetVersionEx(&versionInfo)) + return false; + return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); } -int APIENTRY WinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nCmdShow) +int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { g_hInstance = hInstance; InitCommonControls(); + ReloadLang(); + + #ifdef UNICODE if (!IsItWindowsNT()) { - // g_StdOut << "This program requires Windows NT/2000/XP"; - return 0; + MyMessageBox(L"This program requires Windows NT/2000/XP/2003"); + return NExitCode::kFatalError; } #endif // setlocale(LC_COLLATE, ".ACP"); - int result = 0; try { - UStringVector commandStrings; - SplitCommandLine(GetCommandLineW(), commandStrings); - if (commandStrings.Size() > 0) - commandStrings.Delete(0); - CParser parser(kNumSwitches); - try - { - parser.ParseStrings(kSwitchForms, commandStrings); - } - catch(...) - { - MyMessageBox(kIncorrectCommandMessage); - return 1; - } - - const UStringVector &nonSwitchStrings = parser.NonSwitchStrings; - int numNonSwitchStrings = nonSwitchStrings.Size(); - - if(numNonSwitchStrings < 1) - { - MyMessageBox(kIncorrectCommandMessage); - return 1; - } - - UString command = nonSwitchStrings[0]; - - if (command == L"t") - { - if(numNonSwitchStrings < 2) - { - MyMessageBox(kIncorrectCommandMessage); - return 1; - } - UString archiveName = nonSwitchStrings[1]; - HRESULT result = TestArchive(0, archiveName); - if (result == S_FALSE) - MyMessageBox(IDS_OPEN_IS_NOT_SUPORTED_ARCHIVE, 0x02000604); - else if (result != S_OK) - ShowErrorMessage(0, result); - } - else if (command == L"x") - { - if(numNonSwitchStrings < 2) - { - MyMessageBox(kIncorrectCommandMessage); - return 1; - } - UString archiveName = nonSwitchStrings[1]; - - UString outputDir; - bool outputDirDefined = parser[NKey::kOutputDir].ThereIs; - if(outputDirDefined) - outputDir = parser[NKey::kOutputDir].PostStrings[0]; - else - NFile::NDirectory::MyGetCurrentDirectory(outputDir); - NFile::NName::NormalizeDirPathPrefix(outputDir); - HRESULT result = ExtractArchive(0, archiveName, - false, parser[NKey::kShowDialog].ThereIs, outputDir); - if (result == S_FALSE) - MyMessageBox(IDS_OPEN_IS_NOT_SUPORTED_ARCHIVE, 0x02000604); - else if (result != S_OK) - ShowErrorMessage(0, result); - } - else if (command == L"a") + return Main2(); + } + catch(const CNewException &) + { + MyMessageBox(kMemoryExceptionMessage); + return (NExitCode::kMemoryError); + } + catch(const CSystemException &systemError) + { + if (systemError.ErrorCode == E_OUTOFMEMORY) { - if(numNonSwitchStrings < 2) - { - MyMessageBox(kIncorrectCommandMessage); - return 1; - } - const UString &archiveName = nonSwitchStrings[1]; - - UString mapString, emailString; - bool emailMode = parser[NKey::kEmail].ThereIs; - UStringVector fileNames; - if (!ParseIncludeSwitches(parser, fileNames)) - return 1; - if (fileNames.Size() == 0) - { - ErrorMessage(L"Incorrect command: No files"); - return 1; - } - UString archiveType = L"7z";; - if (parser[NKey::kArchiveType].ThereIs) - archiveType = parser[NKey::kArchiveType].PostStrings.Front(); - HRESULT result = CompressArchive(archiveName, fileNames, - archiveType, emailMode, parser[NKey::kShowDialog].ThereIs); - // if (result != S_OK) - // ShowErrorMessage(result); + MyMessageBox(kMemoryExceptionMessage); + return (NExitCode::kMemoryError); } - else + if (systemError.ErrorCode == E_ABORT) { - ErrorMessage(L"Use correct command"); - return 0; + // MyMessageBox(kUserBreak); + return (NExitCode::kUserBreak); } - return 0; + UString message; + NError::MyFormatMessage(systemError.ErrorCode, message); + MyMessageBox(message); + return (NExitCode::kFatalError); } - catch(const CNewException &) + /* + catch(NExitCode::EEnum &exitCode) + { + g_StdErr << kInternalExceptionMessage << exitCode << endl; + return (exitCode); + } + */ + catch(const UString &s) + { + MyMessageBox(s); + return (NExitCode::kFatalError); + } + catch(const char *s) + { + MyMessageBox(GetUnicodeString(s)); + return (NExitCode::kFatalError); + } + /* + catch(int t) { - // MyMessageBoxError(kMemoryExceptionMessage); - return 1; + g_StdErr << kInternalExceptionMessage << t << endl; + return (NExitCode::kFatalError); } + */ catch(...) { - // g_StdOut << kUnknownExceptionMessage; - return 2; + MyMessageBox(kUnknownExceptionMessage); + return (NExitCode::kFatalError); } - return result; } - - diff --git a/7zip/UI/GUI/GUI.dsp b/7zip/UI/GUI/GUI.dsp index 3febf756..e38e80a8 100755 --- a/7zip/UI/GUI/GUI.dsp +++ b/7zip/UI/GUI/GUI.dsp @@ -152,6 +152,14 @@ LINK32=link.exe # PROP Default_Filter "" # Begin Source File +SOURCE=.\7zG.exe.manifest +# End Source File +# Begin Source File + +SOURCE=.\FM.ico +# End Source File +# Begin Source File + SOURCE=.\resource.h # End Source File # Begin Source File @@ -176,6 +184,14 @@ SOURCE=.\StdAfx.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\CommandLineParser.cpp # End Source File # Begin Source File @@ -200,6 +216,14 @@ SOURCE=..\..\..\Common\Lang.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\ListFileUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ListFileUtils.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\NewHandler.cpp # End Source File # Begin Source File @@ -417,6 +441,30 @@ SOURCE=..\..\..\Windows\Window.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\Common\ArchiveCommandLine.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveCommandLine.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveOpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveOpenCallback.h +# End Source File +# Begin Source File + SOURCE=..\Common\ArchiverInfo.cpp # End Source File # Begin Source File @@ -445,6 +493,18 @@ SOURCE=..\Common\EnumDirItems.h # End Source File # Begin Source File +SOURCE=..\Common\ExitCode.h +# End Source File +# Begin Source File + +SOURCE=..\Common\Extract.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\Extract.h +# End Source File +# Begin Source File + SOURCE=..\Common\ExtractingFilePath.cpp # End Source File # Begin Source File @@ -453,10 +513,18 @@ SOURCE=..\Common\ExtractingFilePath.h # End Source File # Begin Source File +SOURCE=..\Common\ExtractMode.h +# End Source File +# Begin Source File + SOURCE=..\Common\HandlerLoader.h # End Source File # Begin Source File +SOURCE=..\Common\IFileExtractCallback.h +# End Source File +# Begin Source File + SOURCE=..\Common\OpenArchive.cpp # End Source File # Begin Source File @@ -481,6 +549,22 @@ SOURCE=..\Common\SortUtils.h # End Source File # Begin Source File +SOURCE=..\Common\TempFiles.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\TempFiles.h +# End Source File +# Begin Source File + +SOURCE=..\Common\Update.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\Update.h +# End Source File +# Begin Source File + SOURCE=..\Common\UpdateAction.cpp # End Source File # Begin Source File @@ -489,6 +573,14 @@ SOURCE=..\Common\UpdateAction.h # End Source File # Begin Source File +SOURCE=..\Common\UpdateCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateCallback.h +# End Source File +# Begin Source File + SOURCE=..\Common\UpdatePair.cpp # End Source File # Begin Source File @@ -520,10 +612,6 @@ SOURCE=..\Common\ZipRegistry.cpp SOURCE=..\Common\ZipRegistry.h # End Source File # End Group -# Begin Group "Console" - -# PROP Default_Filter "" -# End Group # Begin Group "Explorer" # PROP Default_Filter "" @@ -571,6 +659,15 @@ SOURCE=..\..\FileManager\Resource\MessagesDialog\MessagesDialog.cpp SOURCE=..\..\FileManager\Resource\MessagesDialog\MessagesDialog.h # End Source File +# Begin Source File + +SOURCE=..\..\FileManager\Resource\MessagesDialog\resource.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\Resource\MessagesDialog\resource.rc +# PROP Exclude_From_Build 1 +# End Source File # End Group # Begin Group "Overwtite" @@ -713,111 +810,67 @@ SOURCE=..\..\FileManager\RegistryUtils.h # End Source File # Begin Source File -SOURCE=..\..\FileManager\StringUtils.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\FileManager\StringUtils.h -# End Source File -# Begin Source File - -SOURCE=..\..\FileManager\UpdateCallback100.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\FileManager\UpdateCallback100.h -# End Source File -# End Group -# Begin Group "Agent" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\Agent\Agent.cpp -# End Source File -# Begin Source File - -SOURCE=..\Agent\Agent.h +SOURCE=..\..\FileManager\SplitUtils.cpp # End Source File # Begin Source File -SOURCE=..\Agent\AgentOut.cpp +SOURCE=..\..\FileManager\SplitUtils.h # End Source File # Begin Source File -SOURCE=..\Agent\AgentProxy.cpp -# End Source File -# Begin Source File - -SOURCE=..\Agent\AgentProxy.h -# End Source File -# Begin Source File - -SOURCE=..\Agent\ArchiveExtractCallback.cpp -# End Source File -# Begin Source File - -SOURCE=..\Agent\ArchiveExtractCallback.h +SOURCE=..\..\FileManager\StringUtils.cpp # End Source File # Begin Source File -SOURCE=..\Agent\ArchiveUpdateCallback.cpp +SOURCE=..\..\FileManager\StringUtils.h # End Source File # Begin Source File -SOURCE=..\Agent\ArchiveUpdateCallback.h +SOURCE=..\..\FileManager\UpdateCallback100.cpp # End Source File # Begin Source File -SOURCE=..\Agent\IFolderArchive.h +SOURCE=..\..\FileManager\UpdateCallback100.h # End Source File # End Group -# Begin Group "Archive Interfaces" +# Begin Group "Engine" # PROP Default_Filter "" # Begin Source File -SOURCE=..\Format\Common\ArchiveInterface.h -# End Source File -# Begin Source File - -SOURCE=..\..\Compress\Interface\CompressInterface.h +SOURCE=.\ExtractGUI.cpp # End Source File # Begin Source File -SOURCE=..\..\..\SDK\Interface\CryptoInterface.h +SOURCE=.\ExtractGUI.h # End Source File # Begin Source File -SOURCE=..\Common\FolderArchiveInterface.h +SOURCE=.\GUI.cpp # End Source File -# End Group -# Begin Group "Engine" - -# PROP Default_Filter "" # Begin Source File -SOURCE=.\Compress.cpp +SOURCE=.\OpenCallbackGUI.cpp # End Source File # Begin Source File -SOURCE=.\Compress.h +SOURCE=.\OpenCallbackGUI.h # End Source File # Begin Source File -SOURCE=.\Extract.cpp +SOURCE=.\UpdateCallbackGUI.cpp # End Source File # Begin Source File -SOURCE=.\Extract.h +SOURCE=.\UpdateCallbackGUI.h # End Source File # Begin Source File -SOURCE=.\Test.cpp +SOURCE=.\UpdateGUI.cpp # End Source File # Begin Source File -SOURCE=.\Test.h +SOURCE=.\UpdateGUI.h # End Source File # End Group # Begin Group "7-zip Common" @@ -852,17 +905,5 @@ SOURCE=..\..\Compress\Copy\CopyCoder.cpp SOURCE=..\..\Compress\Copy\CopyCoder.h # End Source File # End Group -# Begin Source File - -SOURCE=.\7zG.exe.manifest -# End Source File -# Begin Source File - -SOURCE=.\FM.ico -# End Source File -# Begin Source File - -SOURCE=.\GUI.cpp -# End Source File # End Target # End Project diff --git a/7zip/UI/GUI/OpenCallbackGUI.cpp b/7zip/UI/GUI/OpenCallbackGUI.cpp new file mode 100755 index 00000000..12b35843 --- /dev/null +++ b/7zip/UI/GUI/OpenCallbackGUI.cpp @@ -0,0 +1,51 @@ +// OpenCallbackGUI.cpp + +#include "StdAfx.h" + +#include "OpenCallbackGUI.h" + +#include "Common/StdOutStream.h" +#include "Common/StdInStream.h" +#include "Common/StringConvert.h" + +#include "../../FileManager/Resource/PasswordDialog/PasswordDialog.h" + +HRESULT COpenCallbackGUI::CheckBreak() +{ + return S_OK; +} + +HRESULT COpenCallbackGUI::SetTotal(const UInt64 *files, const UInt64 *bytes) +{ + return S_OK; +} + +HRESULT COpenCallbackGUI::SetCompleted(const UInt64 *files, const UInt64 *bytes) +{ + return S_OK; +} + +#ifndef _NO_CRYPTO +HRESULT COpenCallbackGUI::CryptoGetTextPassword(BSTR *password) +{ + if (!PasswordIsDefined) + { + CPasswordDialog dialog; + if (dialog.Create(ParentWindow) == IDCANCEL) + return E_ABORT; + Password = dialog.Password; + PasswordIsDefined = true; + } + CMyComBSTR tempName(Password); + *password = tempName.Detach(); + return S_OK; +} + +HRESULT COpenCallbackGUI::GetPasswordIfAny(UString &password) +{ + if (PasswordIsDefined) + password = Password; + return S_OK; +} +#endif + diff --git a/7zip/UI/GUI/OpenCallbackGUI.h b/7zip/UI/GUI/OpenCallbackGUI.h new file mode 100755 index 00000000..eb593abe --- /dev/null +++ b/7zip/UI/GUI/OpenCallbackGUI.h @@ -0,0 +1,30 @@ +// OpenCallbackGUI.h + +#ifndef __OPEN_CALLBACK_GUI_H +#define __OPEN_CALLBACK_GUI_H + +#include "../Common/ArchiveOpenCallback.h" + +class COpenCallbackGUI: public IOpenCallbackUI +{ +public: + HRESULT CheckBreak(); + HRESULT SetTotal(const UInt64 *files, const UInt64 *bytes); + HRESULT SetCompleted(const UInt64 *files, const UInt64 *bytes); + #ifndef _NO_CRYPTO + HRESULT CryptoGetTextPassword(BSTR *password); + HRESULT GetPasswordIfAny(UString &password); + bool PasswordIsDefined; + UString Password; + #endif + + HWND ParentWindow; + + COpenCallbackGUI(): + #ifndef _NO_CRYPTO + PasswordIsDefined(false), + #endif + ParentWindow(0) {} +}; + +#endif diff --git a/7zip/UI/GUI/StdAfx.h b/7zip/UI/GUI/StdAfx.h index f10df8d5..7960a33d 100755 --- a/7zip/UI/GUI/StdAfx.h +++ b/7zip/UI/GUI/StdAfx.h @@ -1,38 +1,11 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H #include <windows.h> #include <commctrl.h> -#include <limits.h> #include <shlobj.h> - -/* -#define _ATL_APARTMENT_THREADED - -#define _ATL_NO_UUIDOF - -#include <atlbase.h> - -extern CComModule _Module; - -#include <atlcom.h> - -#include <crtdbg.h> -#include <string.h> -#include <mbstring.h> -#include <tchar.h> -#include <shlguid.h> -#include <regstr.h> - -#include <new.h> - -#pragma warning(disable:4786) - -#include <map> -#include <algorithm> -*/ -#include <vector> +#include <stdio.h> #endif diff --git a/7zip/UI/GUI/Test.cpp b/7zip/UI/GUI/Test.cpp deleted file mode 100755 index d7128b47..00000000 --- a/7zip/UI/GUI/Test.cpp +++ /dev/null @@ -1,122 +0,0 @@ -// Test.h - -#include "StdAfx.h" - -#include "Test.h" - -#include "Common/StringConvert.h" - -#include "Windows/FileDir.h" -#include "Windows/FileFind.h" -#include "Windows/DLL.h" -#include "Windows/Thread.h" - -#include "../Common/OpenArchive.h" -#include "../Common/DefaultName.h" - -#ifndef EXCLUDE_COM -#include "../Common/ZipRegistry.h" -#endif - -#include "../Explorer/MyMessages.h" -#include "../../FileManager/FormatUtils.h" - -#include "../../FileManager/ExtractCallback.h" -#include "../../FileManager/LangUtils.h" - -#include "../Agent/ArchiveExtractCallback.h" - -#include "resource.h" - -#include "../../FileManager/OpenCallback.h" - -using namespace NWindows; - -struct CThreadTesting -{ - NDLL::CLibrary Library; - CMyComPtr<IInArchive> Archive; - CExtractCallbackImp *ExtractCallbackSpec; - CMyComPtr<IFolderArchiveExtractCallback> ExtractCallback2; - CMyComPtr<IArchiveExtractCallback> ExtractCallback; - - HRESULT Result; - - DWORD Process() - { - ExtractCallbackSpec->ProgressDialog.WaitCreating(); - Result = Archive->Extract(0, -1, BoolToInt(true), ExtractCallback); - ExtractCallbackSpec->ProgressDialog.MyClose(); - return 0; - } - static DWORD WINAPI MyThreadFunction(void *param) - { - return ((CThreadTesting *)param)->Process(); - } -}; - -HRESULT TestArchive(HWND parentWindow, const UString &fileName) -{ - CThreadTesting tester; - - COpenArchiveCallback *openCallbackSpec = new COpenArchiveCallback; - CMyComPtr<IArchiveOpenCallback> openCallback = openCallbackSpec; - openCallbackSpec->_passwordIsDefined = false; - openCallbackSpec->_parentWindow = parentWindow; - - UString fullName; - int fileNamePartStartIndex; - NFile::NDirectory::MyGetFullPathName(fileName, fullName, fileNamePartStartIndex); - - openCallbackSpec->LoadFileInfo( - fullName.Left(fileNamePartStartIndex), - fullName.Mid(fileNamePartStartIndex)); - - CArchiverInfo archiverInfo; - int subExtIndex; - RINOK(OpenArchive(fileName, - &tester.Library, &tester.Archive, - archiverInfo, subExtIndex, openCallback)); - - UString defaultName = GetDefaultName(fileName, - archiverInfo.Extensions[subExtIndex].Extension, - archiverInfo.Extensions[subExtIndex].AddExtension); - - tester.ExtractCallbackSpec = new CExtractCallbackImp; - tester.ExtractCallback2 = tester.ExtractCallbackSpec; - - tester.ExtractCallbackSpec->_parentWindow = 0; - #ifdef LANG - const UString title = LangLoadStringW(IDS_PROGRESS_TESTING, 0x02000F90); - #else - const UString title = NWindows::MyLoadStringW(IDS_PROGRESS_TESTING); - #endif - - tester.ExtractCallbackSpec->Init(NExtractionMode::NOverwrite::kAskBefore, - openCallbackSpec->_passwordIsDefined, openCallbackSpec->_password); - - CArchiveExtractCallback *extractCallback200Spec = new CArchiveExtractCallback; - tester.ExtractCallback = extractCallback200Spec; - - FILETIME fileTomeDefault; - extractCallback200Spec->Init(tester.Archive, - tester.ExtractCallback2, - L"", NExtractionMode::NPath::kFullPathnames, - NExtractionMode::NOverwrite::kWithoutPrompt, UStringVector(), - defaultName, - fileTomeDefault, 0); - - - CThread thread; - if (!thread.Create(CThreadTesting::MyThreadFunction, &tester)) - throw 271824; - tester.ExtractCallbackSpec->StartProgressDialog(title); - - if (tester.Result == S_OK && tester.ExtractCallbackSpec->_messages.IsEmpty()) - { - // extractCallbackSpec->DestroyWindows(); - MessageBoxW(0, LangLoadStringW(IDS_MESSAGE_NO_ERRORS, 0x02000608), - LangLoadStringW(IDS_PROGRESS_TESTING, 0x02000F90), 0); - } - return tester.Result; -} diff --git a/7zip/UI/GUI/Test.h b/7zip/UI/GUI/Test.h deleted file mode 100755 index 0356087e..00000000 --- a/7zip/UI/GUI/Test.h +++ /dev/null @@ -1,13 +0,0 @@ -// GUI/Test.h - -#pragma once - -#ifndef __GUI_TEST_H -#define __GUI_TEST_H - -#include "Common/String.h" - -HRESULT TestArchive(HWND parentWindow, const UString &fileName); - -#endif - diff --git a/7zip/UI/GUI/UpdateCallbackGUI.cpp b/7zip/UI/GUI/UpdateCallbackGUI.cpp new file mode 100755 index 00000000..91c599b1 --- /dev/null +++ b/7zip/UI/GUI/UpdateCallbackGUI.cpp @@ -0,0 +1,155 @@ +// UpdateCallbackConsole.cpp + +#include "StdAfx.h" + +#include "UpdateCallbackGUI.h" + +#include "Common/StringConvert.h" +#include "Common/IntToString.h" +#include "Common/Defs.h" + +#include "Windows/PropVariant.h" +#include "Windows/Error.h" +#include "../../FileManager/Resource/MessagesDialog/MessagesDialog.h" +#include "../../FileManager/Resource/PasswordDialog/PasswordDialog.h" + +using namespace NWindows; + +CUpdateCallbackGUI::~CUpdateCallbackGUI() +{ + if (!Messages.IsEmpty()) + { + CMessagesDialog messagesDialog; + messagesDialog.Messages = &Messages; + messagesDialog.Create(ParentWindow); + } +} + +void CUpdateCallbackGUI::Init() +{ + FailedFiles.Clear(); + Messages.Clear(); + NumArchiveErrors = 0; +} + +void CUpdateCallbackGUI::AddErrorMessage(LPCWSTR message) +{ + Messages.Add(GetSystemString(message)); +} + +HRESULT CUpdateCallbackGUI::OpenResult(const wchar_t *name, HRESULT result) +{ + if (result != S_OK) + { + AddErrorMessage (UString(L"Error: ") + name + + UString(L" is not supported archive")); + } + return S_OK; +} + +HRESULT CUpdateCallbackGUI::StartScanning() +{ + return S_OK; +} + +HRESULT CUpdateCallbackGUI::FinishScanning() +{ + return S_OK; +} + +HRESULT CUpdateCallbackGUI::StartArchive(const wchar_t *name, bool updating) +{ + ProgressDialog.ProgressSynch.SetTitleFileName(name); + return S_OK; +} + +HRESULT CUpdateCallbackGUI::FinishArchive() +{ + return S_OK; +} + +HRESULT CUpdateCallbackGUI::CheckBreak() +{ + while(true) + { + if(ProgressDialog.ProgressSynch.GetStopped()) + return E_ABORT; + if(!ProgressDialog.ProgressSynch.GetPaused()) + break; + ::Sleep(100); + } + return S_OK; +} + +HRESULT CUpdateCallbackGUI::Finilize() +{ + return S_OK; +} + +HRESULT CUpdateCallbackGUI::SetTotal(UInt64 total) +{ + ProgressDialog.ProgressSynch.SetProgress(total, 0); + return S_OK; +} + +HRESULT CUpdateCallbackGUI::SetCompleted(const UInt64 *completeValue) +{ + RINOK(CheckBreak()); + if (completeValue != NULL) + ProgressDialog.ProgressSynch.SetPos(*completeValue); + return S_OK; +} + +HRESULT CUpdateCallbackGUI::GetStream(const wchar_t *name, bool isAnti) +{ + ProgressDialog.ProgressSynch.SetCurrentFileName(name); + return S_OK; +} + +HRESULT CUpdateCallbackGUI::OpenFileError(const wchar_t *name, DWORD systemError) +{ + FailedFiles.Add(name); + // if (systemError == ERROR_SHARING_VIOLATION) + { + AddErrorMessage( + UString(L"WARNING: ") + + NError::MyFormatMessageW(systemError) + + UString(L": ") + + UString(name)); + return S_FALSE; + } + return systemError; +} + +HRESULT CUpdateCallbackGUI::SetOperationResult(Int32 operationResult) +{ + return S_OK; +} + +HRESULT CUpdateCallbackGUI::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) +{ + if (!PasswordIsDefined) + { + if (AskPassword) + { + CPasswordDialog dialog; + if (dialog.Create(ParentWindow) == IDCANCEL) + return E_ABORT; + Password = dialog.Password; + PasswordIsDefined = true; + } + } + *passwordIsDefined = BoolToInt(PasswordIsDefined); + CMyComBSTR tempName(Password); + *password = tempName.Detach(); + return S_OK; +} + +/* +It doesn't work, since main stream waits Dialog +HRESULT CUpdateCallbackGUI::CloseProgress() +{ + ProgressDialog.MyClose(); + return S_OK; +}; +*/
\ No newline at end of file diff --git a/7zip/UI/GUI/UpdateCallbackGUI.h b/7zip/UI/GUI/UpdateCallbackGUI.h new file mode 100755 index 00000000..e3d05769 --- /dev/null +++ b/7zip/UI/GUI/UpdateCallbackGUI.h @@ -0,0 +1,61 @@ +// UpdateCallbackGUI.h + +#ifndef __UPDATE_CALLBACK_GUI_H +#define __UPDATE_CALLBACK_GUI_H + +#include "../Common/Update.h" +#include "../../FileManager/Resource/ProgressDialog2/ProgressDialog.h" + +class CUpdateCallbackGUI: public IUpdateCallbackUI2 +{ +public: + // bool StdOutMode; + bool PasswordIsDefined; + UString Password; + bool AskPassword; + + CUpdateCallbackGUI(): + PasswordIsDefined(false), + AskPassword(false), + // StdOutMode(false) + ParentWindow(0) + {} + + ~CUpdateCallbackGUI(); + void Init(); + + HRESULT OpenResult(const wchar_t *name, HRESULT result); + + HRESULT StartScanning(); + HRESULT FinishScanning(); + + HRESULT StartArchive(const wchar_t *name, bool updating); + HRESULT FinishArchive(); + + HRESULT CheckBreak(); + HRESULT Finilize(); + HRESULT SetTotal(UInt64 total); + HRESULT SetCompleted(const UInt64 *completeValue); + + HRESULT GetStream(const wchar_t *name, bool isAnti); + HRESULT OpenFileError(const wchar_t *name, DWORD systemError); + HRESULT SetOperationResult(Int32 operationResult); + HRESULT CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password); + + // HRESULT CloseProgress(); + + UStringVector FailedFiles; + + CProgressDialog ProgressDialog; + HWND ParentWindow; + void StartProgressDialog(const UString &title) + { + ProgressDialog.Create(title, ParentWindow); + } + + CSysStringVector Messages; + int NumArchiveErrors; + void AddErrorMessage(LPCWSTR message); +}; + +#endif diff --git a/7zip/UI/GUI/UpdateGUI.cpp b/7zip/UI/GUI/UpdateGUI.cpp new file mode 100755 index 00000000..32b434c6 --- /dev/null +++ b/7zip/UI/GUI/UpdateGUI.cpp @@ -0,0 +1,354 @@ +// UpdateGUI.cpp + +#include "StdAfx.h" + +#include "UpdateGUI.h" + +#include "resource.h" +#include "Common/StringConvert.h" +#include "Common/IntToString.h" + +#include "Windows/FileDir.h" +#include "Windows/Error.h" +#include "Windows/FileFind.h" +#include "Windows/Thread.h" + +#include "../../FileManager/FormatUtils.h" +#include "../../FileManager/ExtractCallback.h" +#include "../../FileManager/StringUtils.h" + +#include "../Common/ArchiveExtractCallback.h" +#include "../Common/WorkDir.h" +#include "../Explorer/MyMessages.h" +#include "../Resource/Extract/resource.h" + +#include "OpenCallbackGUI.h" +#include "CompressDialog.h" +#include "UpdateGUI.h" + +using namespace NWindows; +using namespace NFile; + +static const wchar_t *kIncorrectOutDir = L"Incorrect output directory path"; +static const wchar_t *kDefaultSfxModule = L"7zC.sfx"; +static const wchar_t *kSFXExtension = L"exe"; + +struct CThreadUpdating +{ + CUpdateCallbackGUI *UpdateCallbackGUI; + + const NWildcard::CCensor *WildcardCensor; + CUpdateOptions *Options; + COpenCallbackGUI *OpenCallback; + + CUpdateErrorInfo *ErrorInfo; + HRESULT Result; + + DWORD Process() + { + UpdateCallbackGUI->ProgressDialog.WaitCreating(); + try + { + Result = UpdateArchive(*WildcardCensor, *Options, + *ErrorInfo, OpenCallback, UpdateCallbackGUI); + } + catch(const UString &s) + { + ErrorInfo->Message = s; + Result = E_FAIL; + } + catch(const wchar_t *s) + { + ErrorInfo->Message = s; + Result = E_FAIL; + } + catch(const char *s) + { + ErrorInfo->Message = GetUnicodeString(s); + Result = E_FAIL; + } + catch(...) + { + Result = E_FAIL; + } + UpdateCallbackGUI->ProgressDialog.MyClose(); + return 0; + } + static DWORD WINAPI MyThreadFunction(void *param) + { + return ((CThreadUpdating *)param)->Process(); + } +}; + +static void AddProp(CObjectVector<CProperty> &properties, + const UString &name, const UString &value) +{ + CProperty prop; + prop.Name = name; + prop.Value = value; + properties.Add(prop); +} + +static void AddProp(CObjectVector<CProperty> &properties, + const UString &name, UInt32 value) +{ + wchar_t tmp[32]; + ConvertUInt64ToString(value, tmp); + AddProp(properties, name, tmp); +} + +static void AddProp(CObjectVector<CProperty> &properties, + const UString &name, bool value) +{ + AddProp(properties, name, value ? UString(L"on"): UString(L"off")); +} + +static void ParseAndAddPropertires(CObjectVector<CProperty> &properties, + const UString &propertiesString) +{ + UStringVector strings; + SplitString(propertiesString, strings); + for (int i = 0; i < strings.Size(); i++) + { + const UString &s = strings[i]; + CProperty property; + int index = s.Find(L'='); + if (index < 0) + property.Name = s; + else + { + property.Name = s.Left(index); + property.Value = s.Mid(index + 1); + } + properties.Add(property); + } +} + +static void SetOutProperties( + CObjectVector<CProperty> &properties, + bool is7z, + UInt32 level, + const UString &method, + UInt32 dictionary, + bool orderMode, + UInt32 order, + bool solidModeIsAllowed, bool solidMode, + bool multiThreadIsAllowed, bool multiThread, + bool encryptHeadersIsAllowed, bool encryptHeaders, + bool sfxMode) +{ + if (level != (UInt32)(Int32)-1) + AddProp(properties, L"x", (UInt32)level); + if (!method.IsEmpty()) + AddProp(properties, is7z ? L"0": L"m", method); + if (dictionary != (UInt32)(Int32)-1) + { + UString name; + if (is7z) + name = L"0"; + if (orderMode) + name += L"mem"; + else + name += L"d"; + wchar_t s[32]; + ConvertUInt64ToString(dictionary, s); + wcscat(s, L"B"); + AddProp(properties, name, UString(s)); + } + if (order != (UInt32)(Int32)-1) + { + UString name; + if (is7z) + name = L"0"; + if (orderMode) + name += L"o"; + else + name += L"fb"; + AddProp(properties, name, (UInt32)order); + } + + if (encryptHeadersIsAllowed) + AddProp(properties, L"he", encryptHeaders); + if (solidModeIsAllowed) + AddProp(properties, L"s", solidMode); + if (multiThreadIsAllowed) + AddProp(properties, L"mt", multiThread); +} + +static HRESULT ShowDialog(const NWildcard::CCensor &censor, + CUpdateOptions &options, CUpdateCallbackGUI *callback) +{ + if (options.Commands.Size() != 1) + throw "It must be one command"; + CObjectVector<CArchiverInfo> archivers; + CArchiverInfo archiverInfo; + ReadArchiverInfoList(archivers); + UString currentDirPrefix; + + bool oneFile = false; + NFind::CFileInfoW fileInfo; + if (censor.Pairs.Size() > 0) + { + const NWildcard::CPair &pair = censor.Pairs[0]; + currentDirPrefix = pair.Prefix; + if (pair.Head.Items.Size() > 0) + { + const NWildcard::CItem &item = pair.Head.Items[0]; + if (item.ForFile) + { + UString name = pair.Prefix; + for (int i = 0; i < item.PathParts.Size(); i++) + { + if (i > 0) + name += L'\\'; + name += item.PathParts[i]; + } + if (NFind::FindFile(name, fileInfo)) + { + if (censor.Pairs.Size() == 1 && pair.Head.Items.Size() == 1) + oneFile = !fileInfo.IsDirectory(); + } + } + } + } + + CCompressDialog dialog; + NCompressDialog::CInfo &di = dialog.Info; + for(int i = 0; i < archivers.Size(); i++) + { + const CArchiverInfo &ai = archivers[i]; + if (ai.UpdateEnabled && (oneFile || !ai.KeepName)) + dialog.m_ArchiverInfoList.Add(ai); + } + if(dialog.m_ArchiverInfoList.Size() == 0) + { + MyMessageBox(L"No Update Engines"); + return E_FAIL; + } + + // di.ArchiveName = options.ArchivePath.GetFinalPath(); + di.ArchiveName = options.ArchivePath.GetPathWithoutExt(); + dialog.OriginalFileName = fileInfo.Name; + + di.CurrentDirPrefix = currentDirPrefix; + di.SFXMode = options.SfxMode; + + di.Solid = true; + di.MultiThread = false; + + if (callback->PasswordIsDefined) + di.Password = callback->Password; + + di.KeepName = !oneFile; + + if(dialog.Create(0) != IDOK) + return E_ABORT; + + options.VolumesSizes = di.VolumeSizes; + /* + if (di.VolumeSizeIsDefined) + { + MyMessageBox(L"Splitting to volumes is not supported"); + return E_FAIL; + } + */ + + NUpdateArchive::CActionSet &actionSet = options.Commands.Front().ActionSet; + + switch(di.UpdateMode) + { + case NCompressDialog::NUpdateMode::kAdd: + actionSet = NUpdateArchive::kAddActionSet; + break; + case NCompressDialog::NUpdateMode::kUpdate: + actionSet = NUpdateArchive::kUpdateActionSet; + break; + case NCompressDialog::NUpdateMode::kFresh: + actionSet = NUpdateArchive::kFreshActionSet; + break; + case NCompressDialog::NUpdateMode::kSynchronize: + actionSet = NUpdateArchive::kSynchronizeActionSet; + break; + default: + throw 1091756; + } + archiverInfo = dialog.m_ArchiverInfoList[di.ArchiverInfoIndex]; + if (callback->PasswordIsDefined = (!di.Password.IsEmpty())) + callback->Password = di.Password; + + options.MethodMode.Properties.Clear(); + + SetOutProperties( + options.MethodMode.Properties, + archiverInfo.Name.CompareNoCase(L"7z") == 0, + di.Level, + di.Method, + di.Dictionary, + di.OrderMode, di.Order, + di.SolidIsAllowed, di.Solid, + di.MultiThreadIsAllowed, di.MultiThread, + di.EncryptHeadersIsAllowed, di.EncryptHeaders, + di.SFXMode); + + ParseAndAddPropertires(options.MethodMode.Properties, + di.Options); + + if (di.SFXMode) + options.SfxMode = true; + options.MethodMode.FilePath = archiverInfo.FilePath; + options.MethodMode.ClassID = archiverInfo.ClassID; + + options.ArchivePath.VolExtension = archiverInfo.GetMainExtension(); + if(di.SFXMode) + options.ArchivePath.BaseExtension = kSFXExtension; + else + options.ArchivePath.BaseExtension = options.ArchivePath.VolExtension; + options.ArchivePath.ParseFromPath(di.ArchiveName); + + NWorkDir::CInfo workDirInfo; + ReadWorkDirInfo(workDirInfo); + options.WorkingDir.Empty(); + if (workDirInfo.Mode != NWorkDir::NMode::kCurrent) + { + UString fullPath; + NDirectory::MyGetFullPathName(di.ArchiveName, fullPath); + options.WorkingDir = GetWorkDir(workDirInfo, fullPath); + NFile::NDirectory::CreateComplexDirectory(options.WorkingDir); + } + return S_OK; +} + +HRESULT UpdateGUI( + const NWildcard::CCensor &censor, + CUpdateOptions &options, + bool showDialog, + CUpdateErrorInfo &errorInfo, + COpenCallbackGUI *openCallback, + CUpdateCallbackGUI *callback) +{ + if (showDialog) + { + RINOK(ShowDialog(censor, options, callback)); + } + if (options.SfxMode && options.SfxModule.IsEmpty()) + options.SfxModule = kDefaultSfxModule; + + CThreadUpdating tu; + + tu.UpdateCallbackGUI = callback; + tu.UpdateCallbackGUI->Init(); + + tu.WildcardCensor = &censor; + tu.Options = &options; + tu.OpenCallback = openCallback; + tu.ErrorInfo = &errorInfo; + + CThread thread; + if (!thread.Create(CThreadUpdating::MyThreadFunction, &tu)) + throw 271824; + const UString title = LangLoadStringW(IDS_PROGRESS_COMPRESSING, 0x02000DC0); + tu.UpdateCallbackGUI->StartProgressDialog(title); + return tu.Result; +} + + diff --git a/7zip/UI/GUI/UpdateGUI.h b/7zip/UI/GUI/UpdateGUI.h new file mode 100755 index 00000000..c5061aca --- /dev/null +++ b/7zip/UI/GUI/UpdateGUI.h @@ -0,0 +1,20 @@ +// GUI/UpdateGUI.h + +#ifndef __UPDATE_GUI_H +#define __UPDATE_GUI_H + +#include "../Common/Update.h" +#include "OpenCallbackGUI.h" +#include "UpdateCallbackGUI.h" + +#include "../../FileManager/UpdateCallback100.h" + +HRESULT UpdateGUI( + const NWildcard::CCensor &censor, + CUpdateOptions &options, + bool showDialog, + CUpdateErrorInfo &errorInfo, + COpenCallbackGUI *openCallback, + CUpdateCallbackGUI *callback); + +#endif diff --git a/7zip/UI/GUI/resource.rc b/7zip/UI/GUI/resource.rc index 0dd0cbc2..a99f1368 100755 --- a/7zip/UI/GUI/resource.rc +++ b/7zip/UI/GUI/resource.rc @@ -74,8 +74,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,13,0,0 - PRODUCTVERSION 3,13,0,0 + FILEVERSION 4,20,0,0 + PRODUCTVERSION 4,20,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -93,14 +93,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Igor Pavlov\0" VALUE "FileDescription", "7-Zip GUI Module\0" - VALUE "FileVersion", "3, 13, 0, 0\0" + VALUE "FileVersion", "4, 20, 0, 0\0" VALUE "InternalName", "7zg\0" - VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0" VALUE "LegalTrademarks", "\0" - VALUE "OriginalFilename", "7zg.dll\0" + VALUE "OriginalFilename", "7zg.exe\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "7-Zip\0" - VALUE "ProductVersion", "3, 13, 0, 0\0" + VALUE "ProductVersion", "4, 20, 0, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/7zip/UI/Resource/CompressDialog/resource.rc b/7zip/UI/Resource/CompressDialog/resource.rc index a26d8b14..83d757d4 100755 --- a/7zip/UI/Resource/CompressDialog/resource.rc +++ b/7zip/UI/Resource/CompressDialog/resource.rc @@ -63,16 +63,16 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // Dialog // -IDD_DIALOG_COMPRESS DIALOG DISCARDABLE 0, 0, 313, 277 +IDD_DIALOG_COMPRESS DIALOG DISCARDABLE 0, 0, 335, 277 STYLE DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Add to Archive" FONT 8, "MS Shell Dlg" BEGIN LTEXT "&Archive:",IDC_STATIC_COMPRESS_ARCHIVE,7,7,283,8 - COMBOBOX IDC_COMPRESS_COMBO_ARCHIVE,7,18,259,126,CBS_DROPDOWN | + COMBOBOX IDC_COMPRESS_COMBO_ARCHIVE,7,18,290,126,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "...",IDC_COMPRESS_BUTTON_SET_ARCHIVE,286,17,20,14, + PUSHBUTTON "...",IDC_COMPRESS_BUTTON_SET_ARCHIVE,308,17,20,14, WS_GROUP LTEXT "Archive &format:",IDC_STATIC_COMPRESS_FORMAT,7,41,79,8 COMBOBOX IDC_COMPRESS_COMBO_FORMAT,88,39,76,80,CBS_DROPDOWNLIST | @@ -103,31 +103,30 @@ BEGIN CONTROL "Multi-threading",IDC_COMPRESS_MULTI_THREAD,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,7,195,157,10 LTEXT "Split to &volumes, bytes:",IDC_STATIC_COMPRESS_VOLUME, - 186,183,77,8,NOT WS_VISIBLE - COMBOBOX IDC_COMPRESS_COMBO_VOLUME,186,196,31,73,CBS_DROPDOWN | - CBS_AUTOHSCROLL | NOT WS_VISIBLE | WS_VSCROLL | - WS_TABSTOP + 186,183,142,8 + COMBOBOX IDC_COMPRESS_COMBO_VOLUME,186,196,142,73,CBS_DROPDOWN | + CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP LTEXT "&Parameters:",IDC_STATIC_COMPRESS_PARAMETERS,7,214,157, 8 - EDITTEXT IDC_COMPRESS_EDIT_PARAMETERS,7,225,283,14,ES_AUTOHSCROLL + EDITTEXT IDC_COMPRESS_EDIT_PARAMETERS,7,225,321,14,ES_AUTOHSCROLL LTEXT "&Update mode:",IDC_STATIC_COMPRESS_UPDATE_MODE,186,39, 104,8 - COMBOBOX IDC_COMPRESS_COMBO_UPDATE_MODE,186,50,120,80, + COMBOBOX IDC_COMPRESS_COMBO_UPDATE_MODE,186,50,142,80, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - GROUPBOX "Options",IDC_STATIC_COMPRESS_OPTIONS,186,73,120,32 + GROUPBOX "Options",IDC_STATIC_COMPRESS_OPTIONS,186,73,142,32 CONTROL "Create SF&X archive",IDC_COMPRESS_SFX,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,194,87,105,10 - GROUPBOX "Password",IDC_COMPRESS_PASSWORD,186,113,120,63 - EDITTEXT IDC_COMPRESS_EDIT_PASSWORD,194,127,105,14,ES_PASSWORD | + BS_AUTOCHECKBOX | WS_TABSTOP,194,87,127,10 + GROUPBOX "Password",IDC_COMPRESS_PASSWORD,186,113,142,63 + EDITTEXT IDC_COMPRESS_EDIT_PASSWORD,194,127,127,14,ES_PASSWORD | ES_AUTOHSCROLL CONTROL "Show Password",IDC_COMPRESS_CHECK_SHOW_PASSWORD,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,194,145,105,10 + BS_AUTOCHECKBOX | WS_TABSTOP,194,145,127,10 CONTROL "Encrypt file &names", IDC_COMPRESS_CHECK_ENCRYPT_FILE_NAMES,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,194,159,105,10 - DEFPUSHBUTTON "OK",IDOK,98,256,64,14 - PUSHBUTTON "Cancel",IDCANCEL,170,256,64,14 - PUSHBUTTON "Help",IDHELP,242,256,64,14 + BS_AUTOCHECKBOX | WS_TABSTOP,194,159,127,10 + DEFPUSHBUTTON "OK",IDOK,109,256,64,14 + PUSHBUTTON "Cancel",IDCANCEL,181,256,64,14 + PUSHBUTTON "Help",IDHELP,264,256,64,14 END @@ -142,14 +141,14 @@ BEGIN IDD_DIALOG_COMPRESS, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 306 + RIGHTMARGIN, 328 VERTGUIDE, 86 VERTGUIDE, 88 VERTGUIDE, 128 VERTGUIDE, 164 VERTGUIDE, 186 VERTGUIDE, 194 - VERTGUIDE, 299 + VERTGUIDE, 321 BOTTOMMARGIN, 270 END END diff --git a/7zip/UI/Resource/ExtractDialog/resource.h b/7zip/UI/Resource/ExtractDialog/resource.h index 91fa171a..b50c343d 100755 --- a/7zip/UI/Resource/ExtractDialog/resource.h +++ b/7zip/UI/Resource/ExtractDialog/resource.h @@ -2,26 +2,31 @@ // Microsoft Developer Studio generated include file. // Used by resource.rc // +#define IDC_STATIC_EXTRACT_EXTRACT_TO 1020 +#define IDC_EXTRACT_COMBO_PATH 1021 +#define IDC_EXTRACT_BUTTON_SET_PATH 1022 -#define IDC_EXTRACT_COMBO_PATH 1044 -#define IDC_EXTRACT_BUTTON_SET_PATH 1045 -#define IDC_EXTRACT_RADIO_FULL_PATHNAMES 1046 -#define IDC_EXTRACT_RADIO_CURRENT_PATHNAMES 1048 -#define IDC_EXTRACT_RADIO_NO_PATHNAMES 1049 -#define IDC_EXTRACT_RADIO_ASK_BEFORE_OVERWRITE 1050 -#define IDC_EXTRACT_RADIO_OVERWRITE_WITHOUT_PROMPT 1051 -#define IDC_EXTRACT_RADIO_SKIP_EXISTING_FILES 1052 -#define IDC_EXTRACT_RADIO_SELECTED_FILES 1053 -#define IDC_EXTRACT_RADIO_ALL_FILES 1054 -#define IDC_EXTRACT_RADIO_AUTO_RENAME 1055 -#define IDC_EXTRACT_PATH_MODE 1056 -#define IDC_EXTRACT_OVERWRITE_MODE 1057 -#define IDC_EXTRACT_FILES 1058 -#define IDC_EXTRACT_EDIT_PASSWORD 1068 -#define IDC_EXTRACT_PASSWORD 1106 -#define IDC_EXTRACT_CHECK_SHOW_PASSWORD 1109 -#define IDC_STATIC_EXTRACT_EXTRACT_TO 1092 +#define IDC_EXTRACT_PATH_MODE 1040 +#define IDC_EXTRACT_RADIO_FULL_PATHNAMES 1041 +#define IDC_EXTRACT_RADIO_CURRENT_PATHNAMES 1042 +#define IDC_EXTRACT_RADIO_NO_PATHNAMES 1043 + +#define IDC_EXTRACT_OVERWRITE_MODE 1050 +#define IDC_EXTRACT_RADIO_ASK_BEFORE_OVERWRITE 1051 +#define IDC_EXTRACT_RADIO_OVERWRITE_WITHOUT_PROMPT 1052 +#define IDC_EXTRACT_RADIO_SKIP_EXISTING_FILES 1053 +#define IDC_EXTRACT_RADIO_SELECTED_FILES 1054 +#define IDC_EXTRACT_RADIO_ALL_FILES 1055 +#define IDC_EXTRACT_RADIO_AUTO_RENAME 1056 +#define IDC_EXTRACT_RADIO_AUTO_RENAME_EXISTING 1057 + + +#define IDC_EXTRACT_FILES 1060 + +#define IDC_EXTRACT_PASSWORD 1100 +#define IDC_EXTRACT_EDIT_PASSWORD 1101 +#define IDC_EXTRACT_CHECK_SHOW_PASSWORD 1102 // Next default values for new objects // diff --git a/7zip/UI/Resource/ExtractDialog/resource.rc b/7zip/UI/Resource/ExtractDialog/resource.rc index 6b399665..4dcc83d3 100755 --- a/7zip/UI/Resource/ExtractDialog/resource.rc +++ b/7zip/UI/Resource/ExtractDialog/resource.rc @@ -63,7 +63,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // Dialog // -IDD_DIALOG_EXTRACT DIALOG DISCARDABLE 0, 0, 299, 202 +IDD_DIALOG_EXTRACT DIALOG DISCARDABLE 0, 0, 299, 218 STYLE DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Extract" @@ -81,7 +81,7 @@ BEGIN CONTROL "No pathnames",IDC_EXTRACT_RADIO_NO_PATHNAMES,"Button", BS_AUTORADIOBUTTON,13,85,114,10 GROUPBOX "Overwrite mode",IDC_EXTRACT_OVERWRITE_MODE,148,44,144, - 75,WS_GROUP + 88,WS_GROUP CONTROL "Ask before overwrite", IDC_EXTRACT_RADIO_ASK_BEFORE_OVERWRITE,"Button", BS_AUTORADIOBUTTON | WS_GROUP,154,57,130,10 @@ -93,23 +93,46 @@ BEGIN BS_AUTORADIOBUTTON,154,85,130,10 CONTROL "Auto rename",IDC_EXTRACT_RADIO_AUTO_RENAME,"Button", BS_AUTORADIOBUTTON,154,99,130,10 - GROUPBOX "Files",IDC_EXTRACT_FILES,7,125,127,48,NOT WS_VISIBLE | - WS_GROUP + CONTROL "Auto rename existing files", + IDC_EXTRACT_RADIO_AUTO_RENAME_EXISTING,"Button", + BS_AUTORADIOBUTTON,154,113,130,10 + GROUPBOX "Files",IDC_EXTRACT_FILES,7,140,127,48,NOT WS_VISIBLE | + WS_DISABLED | WS_GROUP CONTROL "&Selected files",IDC_EXTRACT_RADIO_SELECTED_FILES, - "Button",BS_AUTORADIOBUTTON | NOT WS_VISIBLE | WS_GROUP, - 13,137,114,10 + "Button",BS_AUTORADIOBUTTON | NOT WS_VISIBLE | + WS_DISABLED | WS_GROUP,13,153,114,10 CONTROL "&All files",IDC_EXTRACT_RADIO_ALL_FILES,"Button", - BS_AUTORADIOBUTTON | NOT WS_VISIBLE,13,151,114,10 - GROUPBOX "Password",IDC_EXTRACT_PASSWORD,148,126,144,46 - EDITTEXT IDC_EXTRACT_EDIT_PASSWORD,154,138,130,14,ES_PASSWORD | + BS_AUTORADIOBUTTON | NOT WS_VISIBLE | WS_DISABLED,13,166, + 114,10 + GROUPBOX "Password",IDC_EXTRACT_PASSWORD,148,142,144,46 + EDITTEXT IDC_EXTRACT_EDIT_PASSWORD,154,153,130,14,ES_PASSWORD | ES_AUTOHSCROLL CONTROL "Show Password",IDC_EXTRACT_CHECK_SHOW_PASSWORD,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,154,157,129,10 - DEFPUSHBUTTON "OK",IDOK,80,181,64,14,WS_GROUP - PUSHBUTTON "Cancel",IDCANCEL,154,181,64,14 - PUSHBUTTON "Help",IDHELP,228,181,64,14 + BS_AUTOCHECKBOX | WS_TABSTOP,154,172,129,10 + DEFPUSHBUTTON "OK",IDOK,80,197,64,14,WS_GROUP + PUSHBUTTON "Cancel",IDCANCEL,154,197,64,14 + PUSHBUTTON "Help",IDHELP,228,197,64,14 END + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + "IDD_DIALOG_EXTRACT", DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 292 + TOPMARGIN, 7 + BOTTOMMARGIN, 211 + END +END +#endif // APSTUDIO_INVOKED + #endif // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/Common/AlignedBuffer.cpp b/Common/AlignedBuffer.cpp index dd811335..ec472ced 100755 --- a/Common/AlignedBuffer.cpp +++ b/Common/AlignedBuffer.cpp @@ -3,14 +3,14 @@ #include "StdAfx.h" #include "AlignedBuffer.h" -#include "Types.h" -void *CAlignedBuffer::Allocate(size_t numItems, size_t itemSize, size_t alignValue) +void *CAlignedBuffer::Allocate(size_t size, size_t mask) { Free(); - m_Buffer = new unsigned char[numItems * itemSize + alignValue - 1]; - UINT_PTR p = UINT_PTR(m_Buffer) + (alignValue - 1); - p -= (p % alignValue); + m_Buffer = new unsigned char[size + mask]; + unsigned char *p = m_Buffer; + while(((size_t)p & mask) != 0) + p++; return (void *)p; } diff --git a/Common/AlignedBuffer.h b/Common/AlignedBuffer.h index 1bff6591..d040463e 100755 --- a/Common/AlignedBuffer.h +++ b/Common/AlignedBuffer.h @@ -1,7 +1,9 @@ -// AlignedBuffer.h +// Common/AlignedBuffer.h -#ifndef __ALIGNBUFFER_H -#define __ALIGNBUFFER_H +#ifndef __COMMON_ALIGNEDBUFFER_H +#define __COMMON_ALIGNEDBUFFER_H + +#include <stddef.h> class CAlignedBuffer { @@ -9,7 +11,7 @@ class CAlignedBuffer public: CAlignedBuffer(): m_Buffer(0) {}; ~CAlignedBuffer() { Free(); } - void *Allocate(size_t numItems, size_t itemSize, size_t alignValue); + void *Allocate(size_t size, size_t mask); void Free(); }; diff --git a/Common/Alloc.cpp b/Common/Alloc.cpp new file mode 100755 index 00000000..e1c5f7bd --- /dev/null +++ b/Common/Alloc.cpp @@ -0,0 +1,79 @@ +// Common/Alloc.cpp + +#include "StdAfx.h" + +#ifdef _WIN32 +#include "MyWindows.h" +#else +#include <stdlib.h> +#endif + +#include "Alloc.h" + +/* #define _SZ_ALLOC_DEBUG */ +/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */ +#ifdef _SZ_ALLOC_DEBUG +#include <stdio.h> +int g_allocCount = 0; +int g_allocCountBig = 0; +#endif + +void *MyAlloc(size_t size) +{ + #ifdef _SZ_ALLOC_DEBUG + fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount++); + #endif + + return ::malloc(size); +} + +void MyFree(void *address) +{ + #ifdef _SZ_ALLOC_DEBUG + if (address != 0) + fprintf(stderr, "\nFree; count = %10d", --g_allocCount); + #endif + + ::free(address); +} + +void *BigAlloc(size_t size) +{ + #ifdef _SZ_ALLOC_DEBUG + fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++); + #endif + + #ifdef _WIN32 + return ::VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE); + #else + return ::malloc(size); + #endif +} + +void BigFree(void *address) +{ + #ifdef _SZ_ALLOC_DEBUG + if (address != 0) + fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig); + #endif + + if (address == 0) + return; + #ifdef _WIN32 + ::VirtualFree(address, 0, MEM_RELEASE); + #else + ::free(address); + #endif +} + +/* +void *BigAllocE(size_t size) +{ + void *res = BigAlloc(size); + #ifndef _NO_EXCEPTIONS + if (res == 0) + throw CNewException(); + #endif + return res; +} +*/ diff --git a/Common/Alloc.h b/Common/Alloc.h new file mode 100755 index 00000000..881af966 --- /dev/null +++ b/Common/Alloc.h @@ -0,0 +1,14 @@ +// Common/Alloc.h + +#ifndef __COMMON_ALLOC_H +#define __COMMON_ALLOC_H + +#include <stddef.h> + +void *MyAlloc(size_t size); +void MyFree(void *address); +void *BigAlloc(size_t size); +void BigFree(void *address); +// void *BigAllocE(size_t size); + +#endif diff --git a/Common/AutoPtr.h b/Common/AutoPtr.h new file mode 100755 index 00000000..8fc93573 --- /dev/null +++ b/Common/AutoPtr.h @@ -0,0 +1,35 @@ +// Common/AutoPtr.h + +#ifndef __COMMON_AUTOPTR_H +#define __COMMON_AUTOPTR_H + +template<class T> class CMyAutoPtr +{ + T *_p; +public: + CMyAutoPtr(T *p = 0) : _p(p) {} + CMyAutoPtr(CMyAutoPtr<T>& p): _p(p.release()) {} + CMyAutoPtr<T>& operator=(CMyAutoPtr<T>& p) + { + reset(p.release()); + return (*this); + } + ~CMyAutoPtr() { delete _p; } + T& operator*() const { return *_p; } + // T* operator->() const { return (&**this); } + T* get() const {return _p; } + T* release() + { + T *tmp = _p; + _p = 0; + return tmp; + } + void reset(T* p = 0) + { + if (p != _p) + delete _p; + _p = p; + } +}; + +#endif diff --git a/Common/Buffer.h b/Common/Buffer.h index db80c751..9d5fcaec 100755 --- a/Common/Buffer.h +++ b/Common/Buffer.h @@ -1,11 +1,9 @@ // Common/Buffer.h -#pragma once - #ifndef __COMMON_BUFFER_H #define __COMMON_BUFFER_H -// #include "Common/Defs.h" +#include "Defs.h" template <class T> class CBuffer { @@ -28,9 +26,15 @@ public: size_t GetCapacity() const { return _capacity; } void SetCapacity(size_t newCapacity) { - T *newBuffer = new T[newCapacity]; - if(_capacity > 0) - memmove(newBuffer, _items, MyMin(_capacity, newCapacity) * sizeof(T)); + T *newBuffer; + if (newCapacity > 0) + { + newBuffer = new T[newCapacity]; + if(_capacity > 0) + memmove(newBuffer, _items, MyMin(_capacity, newCapacity) * sizeof(T)); + } + else + newBuffer = 0; delete []_items; _items = newBuffer; _capacity = newCapacity; diff --git a/Common/CRC.cpp b/Common/CRC.cpp index 006da6d9..3e90c713 100755 --- a/Common/CRC.cpp +++ b/Common/CRC.cpp @@ -4,18 +4,15 @@ #include "CRC.h" -static const UINT32 kCRCPoly = 0xEDB88320; +static const UInt32 kCRCPoly = 0xEDB88320; -UINT32 CCRC::Table[256]; +UInt32 CCRC::Table[256]; -class CCRCTableInit -{ -public: -CCRCTableInit() +void CCRC::InitTable() { - for (UINT32 i = 0; i < 256; i++) + for (UInt32 i = 0; i < 256; i++) { - UINT32 r = i; + UInt32 r = i; for (int j = 0; j < 8; j++) if (r & 1) r = (r >> 1) ^ kCRCPoly; @@ -24,87 +21,41 @@ CCRCTableInit() CCRC::Table[i] = r; } } + +class CCRCTableInit +{ +public: + CCRCTableInit() { CCRC::InitTable(); } } g_CRCTableInit; -/* -const UINT32 CCRC::Table[] = { - 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, - 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, - 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, - 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, - 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, - 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, - 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, - 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, - 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, - 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, - 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, - 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, - 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, - 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, - 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, - 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, - 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, - 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, - 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, - 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, - 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, - 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, - 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, - 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, - 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, - 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, - 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, - 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, - 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, - 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, - 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, - 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, - 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, - 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, - 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, - 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, - 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, - 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, - 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, - 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, - 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, - 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, - 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, - 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, - 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, - 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, - 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, - 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, - 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, - 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, - 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, - 0x2d02ef8dL -}; -*/ +void CCRC::UpdateByte(Byte b) +{ + _value = Table[((Byte)(_value)) ^ b] ^ (_value >> 8); +} -#define UPDATE valueLoc = Table[(BYTE)valueLoc] ^ (valueLoc >> 8) -#define UPDATE4 UPDATE; UPDATE; UPDATE; UPDATE; +void CCRC::UpdateUInt16(UInt16 v) +{ + UpdateByte(Byte(v)); + UpdateByte(Byte(v >> 8)); +} -void CCRC::Update(const void *data, UINT32 size) +void CCRC::UpdateUInt32(UInt32 v) { - UINT32 valueLoc = _value; - const BYTE *byteBuffer = (const BYTE *)data; - - for(; (UINT_PTR(byteBuffer) & 3) != 0 && size > 0; size--, byteBuffer++) - valueLoc = Table[(((BYTE)(valueLoc)) ^ (*byteBuffer))] ^ - (valueLoc >> 8); - - const UINT32 kBlockSize = 4; - while (size >= kBlockSize) - { - size -= kBlockSize; - valueLoc ^= *(const UINT32 *)byteBuffer; - UPDATE4 - byteBuffer += kBlockSize; - } - for(UINT32 i = 0; i < size; i++) - valueLoc = Table[(((BYTE)(valueLoc)) ^ (byteBuffer)[i])] ^ - (valueLoc >> 8); - _value = valueLoc; + for (int i = 0; i < 4; i++) + UpdateByte((Byte)(v >> (8 * i))); +} + +void CCRC::UpdateUInt64(UInt64 v) +{ + for (int i = 0; i < 8; i++) + UpdateByte((Byte)(v >> (8 * i))); +} + +void CCRC::Update(const void *data, UInt32 size) +{ + UInt32 v = _value; + const Byte *p = (const Byte *)data; + for (; size > 0 ; size--, p++) + v = Table[((Byte)(v)) ^ *p] ^ (v >> 8); + _value = v; } diff --git a/Common/CRC.h b/Common/CRC.h index 34514883..58f8e636 100755 --- a/Common/CRC.h +++ b/Common/CRC.h @@ -1,7 +1,5 @@ // Common/CRC.h -// #pragma once - #ifndef __COMMON_CRC_H #define __COMMON_CRC_H @@ -9,20 +7,26 @@ class CCRC { - UINT32 _value; + UInt32 _value; public: - static UINT32 Table[256]; + static UInt32 Table[256]; + static void InitTable(); + CCRC(): _value(0xFFFFFFFF){}; void Init() { _value = 0xFFFFFFFF; } - void Update(const void *data, UINT32 size); - UINT32 GetDigest() const { return _value ^ 0xFFFFFFFF; } - static UINT32 CalculateDigest(const void *data, UINT32 size) + void UpdateByte(Byte v); + void UpdateUInt16(UInt16 v); + void UpdateUInt32(UInt32 v); + void UpdateUInt64(UInt64 v); + void Update(const void *data, UInt32 size); + UInt32 GetDigest() const { return _value ^ 0xFFFFFFFF; } + static UInt32 CalculateDigest(const void *data, UInt32 size) { CCRC crc; crc.Update(data, size); return crc.GetDigest(); } - static bool VerifyDigest(UINT32 digest, const void *data, UINT32 size) + static bool VerifyDigest(UInt32 digest, const void *data, UInt32 size) { return (CalculateDigest(data, size) == digest); } diff --git a/Common/C_FileIO.cpp b/Common/C_FileIO.cpp new file mode 100755 index 00000000..7d9e00d0 --- /dev/null +++ b/Common/C_FileIO.cpp @@ -0,0 +1,78 @@ +// Common/C_FileIO.h + +#include "C_FileIO.h" + +#include <fcntl.h> +#include <unistd.h> + +namespace NC { +namespace NFile { +namespace NIO { + +bool CFileBase::OpenBinary(const char *name, int flags) +{ + #ifdef O_BINARY + flags |= O_BINARY; + #endif + Close(); + _handle = ::open(name, flags, 0666); + return _handle != -1; +} + +bool CFileBase::Close() +{ + if(_handle == -1) + return true; + if (close(_handle) != 0) + return false; + _handle = -1; + return true; +} + +bool CFileBase::GetLength(UInt64 &length) const +{ + off_t curPos = Seek(0, SEEK_CUR); + off_t lengthTemp = Seek(0, SEEK_END); + Seek(curPos, SEEK_SET); + length = (UInt64)lengthTemp; + return true; +} + +off_t CFileBase::Seek(off_t distanceToMove, int moveMethod) const +{ + return ::lseek(_handle, distanceToMove, moveMethod); +} + +///////////////////////// +// CInFile + +bool CInFile::Open(const char *name) +{ + return CFileBase::OpenBinary(name, O_RDONLY); +} + +ssize_t CInFile::Read(void *data, size_t size) +{ + return read(_handle, data, size); +} + +///////////////////////// +// COutFile + +bool COutFile::Create(const char *name, bool createAlways) +{ + if (createAlways) + { + Close(); + _handle = ::creat(name, 0666); + return _handle != -1; + } + return OpenBinary(name, O_CREAT | O_EXCL | O_WRONLY); +} + +ssize_t COutFile::Write(const void *data, size_t size) +{ + return write(_handle, data, size); +} + +}}} diff --git a/Common/C_FileIO.h b/Common/C_FileIO.h new file mode 100755 index 00000000..2ad07167 --- /dev/null +++ b/Common/C_FileIO.h @@ -0,0 +1,45 @@ +// Common/C_FileIO.h + +#ifndef __COMMON_C_FILEIO_H +#define __COMMON_C_FILEIO_H + +#include <stdio.h> +#include <sys/types.h> + +#include "Types.h" +#include "MyWindows.h" + +namespace NC { +namespace NFile { +namespace NIO { + +class CFileBase +{ +protected: + int _handle; + bool OpenBinary(const char *name, int flags); +public: + CFileBase(): _handle(-1) {}; + ~CFileBase() { Close(); } + bool Close(); + bool GetLength(UInt64 &length) const; + off_t Seek(off_t distanceToMove, int moveMethod) const; +}; + +class CInFile: public CFileBase +{ +public: + bool Open(const char *name); + ssize_t Read(void *data, size_t size); +}; + +class COutFile: public CFileBase +{ +public: + bool Create(const char *name, bool createAlways); + ssize_t Write(const void *data, size_t size); +}; + +}}} + +#endif diff --git a/Common/ComTry.h b/Common/ComTry.h index 3162e502..bef6ad54 100755 --- a/Common/ComTry.h +++ b/Common/ComTry.h @@ -1,9 +1,7 @@ // ComTry.h -// #pragma once - -#ifndef __Com_Try_H -#define __Com_Try_H +#ifndef __COM_TRY_H +#define __COM_TRY_H #include "Exception.h" diff --git a/Common/CommandLineParser.cpp b/Common/CommandLineParser.cpp index 295465b4..27a3d385 100755 --- a/Common/CommandLineParser.cpp +++ b/Common/CommandLineParser.cpp @@ -37,8 +37,8 @@ void SplitCommandLine(const UString &s, UStringVector &parts) { UString s1, s2; SplitCommandLine(sTemp, s1, s2); - s1.Trim(); - s2.Trim(); + // s1.Trim(); + // s2.Trim(); if (!s1.IsEmpty()) parts.Add(s1); if (s2.IsEmpty()) @@ -49,13 +49,14 @@ void SplitCommandLine(const UString &s, UStringVector &parts) static const wchar_t kSwitchID1 = '-'; -static const wchar_t kSwitchID2 = '/'; +// static const wchar_t kSwitchID2 = '/'; static const wchar_t kSwitchMinus = '-'; +static const wchar_t *kStopSwitchParsing = L"--"; static bool IsItSwitchChar(wchar_t c) { - return (c == kSwitchID1 || c == kSwitchID2); + return (c == kSwitchID1 /*|| c == kSwitchID2 */); } CParser::CParser(int numSwitches): @@ -73,9 +74,19 @@ void CParser::ParseStrings(const CSwitchForm *switchForms, const UStringVector &commandStrings) { int numCommandStrings = commandStrings.Size(); + bool stopSwitch = false; for (int i = 0; i < numCommandStrings; i++) - if (!ParseString(commandStrings[i], switchForms)) - NonSwitchStrings.Add(commandStrings[i]); + { + const UString &s = commandStrings[i]; + if (stopSwitch) + NonSwitchStrings.Add(s); + else + if (s == kStopSwitchParsing) + stopSwitch = true; + else + if (!ParseString(s, switchForms)) + NonSwitchStrings.Add(s); + } } // if string contains switch then function updates switch structures @@ -93,11 +104,11 @@ bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms) if (IsItSwitchChar(s[pos])) pos++; const int kNoLen = -1; - int matchedSwitchIndex; + int matchedSwitchIndex = 0; // GCC Warning int maxLen = kNoLen; for(int switchIndex = 0; switchIndex < _numSwitches; switchIndex++) { - int switchLen = wcslen(switchForms[switchIndex].IDString); + int switchLen = MyStringLen(switchForms[switchIndex].IDString); if (switchLen <= maxLen || pos + switchLen > len) continue; @@ -122,7 +133,7 @@ bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms) NSwitchType::EEnum type = switchForm.Type; switch(type) { - case (NSwitchType::kPostMinus): + case NSwitchType::kPostMinus: { if (tailSize == 0) matchedSwitch.WithMinus = false; @@ -134,7 +145,7 @@ bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms) } break; } - case (NSwitchType::kPostChar): + case NSwitchType::kPostChar: { if (tailSize < switchForm.MinLen) throw "switch is not full"; @@ -155,7 +166,8 @@ bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms) } break; } - case NSwitchType::kLimitedPostString: case NSwitchType::kUnLimitedPostString: + case NSwitchType::kLimitedPostString: + case NSwitchType::kUnLimitedPostString: { int minLen = switchForm.MinLen; if (tailSize < minLen) @@ -176,7 +188,10 @@ bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms) stringSwitch += c; } matchedSwitch.PostStrings.Add(stringSwitch); + break; } + case NSwitchType::kSimple: + break; } } return true; @@ -223,7 +238,7 @@ bool ParseSubCharsCommand(int numForms, const CCommandSubCharsSet *forms, { const CCommandSubCharsSet &set = forms[i]; int currentIndex = -1; - int len = wcslen(set.Chars); + int len = MyStringLen(set.Chars); for(int j = 0; j < len; j++) { wchar_t c = set.Chars[j]; diff --git a/Common/CommandLineParser.h b/Common/CommandLineParser.h index 187debe6..e1fe1443 100755 --- a/Common/CommandLineParser.h +++ b/Common/CommandLineParser.h @@ -1,7 +1,5 @@ // Common/CommandLineParser.h -#pragma once - #ifndef __COMMON_COMMANDLINEPARSER_H #define __COMMON_COMMANDLINEPARSER_H diff --git a/Common/Copy of StringConvert.cpp b/Common/Copy of StringConvert.cpp new file mode 100755 index 00000000..d6d05d6c --- /dev/null +++ b/Common/Copy of StringConvert.cpp @@ -0,0 +1,93 @@ +// Common/StringConvert.cpp + +#include "StdAfx.h" + +#include "StringConvert.h" + +#ifndef _WIN32 +#include <stdlib.h> +#endif + +#ifdef _WIN32 +UString MultiByteToUnicodeString(const AString &srcString, UINT codePage) +{ + UString resultString; + if(!srcString.IsEmpty()) + { + int numChars = MultiByteToWideChar(codePage, 0, srcString, + srcString.Length(), resultString.GetBuffer(srcString.Length()), + srcString.Length() + 1); + #ifndef _WIN32_WCE + if(numChars == 0) + throw 282228; + #endif + resultString.ReleaseBuffer(numChars); + } + return resultString; +} + +AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage) +{ + AString resultString; + if(!srcString.IsEmpty()) + { + int numRequiredBytes = srcString.Length() * 2; + int numChars = WideCharToMultiByte(codePage, 0, srcString, + srcString.Length(), resultString.GetBuffer(numRequiredBytes), + numRequiredBytes + 1, NULL, NULL); + #ifndef _WIN32_WCE + if(numChars == 0) + throw 282229; + #endif + resultString.ReleaseBuffer(numChars); + } + return resultString; +} + +#ifndef _WIN32_WCE +AString SystemStringToOemString(const CSysString &srcString) +{ + AString result; + CharToOem(srcString, result.GetBuffer(srcString.Length() * 2)); + result.ReleaseBuffer(); + return result; +} +#endif + +#else + +UString MultiByteToUnicodeString(const AString &srcString, UINT codePage) +{ + UString resultString; + for (int i = 0; i < srcString.Length(); i++) + resultString += wchar_t(srcString[i]); + /* + if(!srcString.IsEmpty()) + { + int numChars = mbstowcs(resultString.GetBuffer(srcString.Length()), srcString, srcString.Length() + 1); + if (numChars < 0) throw "Your environment does not support UNICODE"; + resultString.ReleaseBuffer(numChars); + } + */ + return resultString; +} + +AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage) +{ + AString resultString; + for (int i = 0; i < srcString.Length(); i++) + resultString += char(srcString[i]); + /* + if(!srcString.IsEmpty()) + { + int numRequiredBytes = srcString.Length() * 6 + 1; + int numChars = wcstombs(resultString.GetBuffer(numRequiredBytes), srcString, numRequiredBytes); + if (numChars < 0) throw "Your environment does not support UNICODE"; + resultString.ReleaseBuffer(numChars); + } + */ + return resultString; +} + +#endif + diff --git a/Common/Copy of StringConvert.h b/Common/Copy of StringConvert.h new file mode 100755 index 00000000..daee50b0 --- /dev/null +++ b/Common/Copy of StringConvert.h @@ -0,0 +1,71 @@ +// Common/StringConvert.h + +#ifndef __COMMON_STRINGCONVERT_H +#define __COMMON_STRINGCONVERT_H + +#include "MyWindows.h" +#include "Common/String.h" +#include "Types.h" + +UString MultiByteToUnicodeString(const AString &srcString, UINT codePage = CP_ACP); +AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage = CP_ACP); + +inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString) + { return unicodeString; } +inline const UString& GetUnicodeString(const UString &unicodeString) + { return unicodeString; } +inline UString GetUnicodeString(const AString &ansiString) + { return MultiByteToUnicodeString(ansiString); } +inline UString GetUnicodeString(const AString &multiByteString, UINT codePage) + { return MultiByteToUnicodeString(multiByteString, codePage); } +inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString, UINT codePage) + { return unicodeString; } +inline const UString& GetUnicodeString(const UString &unicodeString, UINT codePage) + { return unicodeString; } + +inline const char* GetAnsiString(const char* ansiString) + { return ansiString; } +inline const AString& GetAnsiString(const AString &ansiString) + { return ansiString; } +inline AString GetAnsiString(const UString &unicodeString) + { return UnicodeStringToMultiByte(unicodeString); } + +inline const char* GetOemString(const char* oemString) + { return oemString; } +inline const AString& GetOemString(const AString &oemString) + { return oemString; } +inline AString GetOemString(const UString &unicodeString) + { return UnicodeStringToMultiByte(unicodeString, CP_OEMCP); } + + +#ifdef _UNICODE + inline const wchar_t* GetSystemString(const wchar_t* unicodeString) + { return unicodeString;} + inline const UString& GetSystemString(const UString &unicodeString) + { return unicodeString;} + inline const wchar_t* GetSystemString(const wchar_t* unicodeString, UINT codePage) + { return unicodeString;} + inline const UString& GetSystemString(const UString &unicodeString, UINT codePage) + { return unicodeString;} + inline UString GetSystemString(const AString &multiByteString, UINT codePage) + { return MultiByteToUnicodeString(multiByteString, codePage);} + inline UString GetSystemString(const AString &multiByteString) + { return MultiByteToUnicodeString(multiByteString);} +#else + inline const char* GetSystemString(const char *ansiString) + { return ansiString; } + inline const AString& GetSystemString(const AString &multiByteString, UINT codePage) + { return multiByteString; } + inline const char * GetSystemString(const char *multiByteString, UINT codePage) + { return multiByteString; } + inline AString GetSystemString(const UString &unicodeString) + { return UnicodeStringToMultiByte(unicodeString); } + inline AString GetSystemString(const UString &unicodeString, UINT codePage) + { return UnicodeStringToMultiByte(unicodeString, codePage); } +#endif + +#ifndef _WIN32_WCE +AString SystemStringToOemString(const CSysString &srcString); +#endif + +#endif diff --git a/Common/Copy of UTFConvert.cpp b/Common/Copy of UTFConvert.cpp new file mode 100755 index 00000000..e15695bb --- /dev/null +++ b/Common/Copy of UTFConvert.cpp @@ -0,0 +1,91 @@ +// UTFConvert.cpp + +#include "StdAfx.h" + +#include "UTFConvert.h" +#include "Types.h" + +static Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; + +// These functions are for UTF8 <-> UTF16 conversion. + +bool ConvertUTF8ToUnicode(const AString &src, UString &dest) +{ + dest.Empty(); + for(int i = 0; i < src.Length();) + { + Byte c = (Byte)src[i++]; + if (c < 0x80) + { + dest += (wchar_t)c; + continue; + } + if(c < 0xC0) + return false; + int numAdds; + for (numAdds = 1; numAdds < 5; numAdds++) + if (c < kUtf8Limits[numAdds]) + break; + UInt32 value = (c - kUtf8Limits[numAdds - 1]); + do + { + if (i >= src.Length()) + return false; + Byte c2 = (Byte)src[i++]; + if (c2 < 0x80 || c2 >= 0xC0) + return false; + value <<= 6; + value |= (c2 - 0x80); + numAdds--; + } + while(numAdds > 0); + if (value < 0x10000) + dest += (wchar_t)(value); + else + { + value -= 0x10000; + if (value >= 0x100000) + return false; + dest += (wchar_t)(0xD800 + (value >> 10)); + dest += (wchar_t)(0xDC00 + (value & 0x3FF)); + } + } + return true; +} + +bool ConvertUnicodeToUTF8(const UString &src, AString &dest) +{ + dest.Empty(); + for(int i = 0; i < src.Length();) + { + UInt32 value = (UInt32)src[i++]; + if (value < 0x80) + { + dest += (char)value; + continue; + } + if (value >= 0xD800 && value < 0xE000) + { + if (value >= 0xDC00) + return false; + if (i >= src.Length()) + return false; + UInt32 c2 = (UInt32)src[i++]; + if (c2 < 0xDC00 || c2 >= 0xE000) + return false; + value = ((value - 0xD800) << 10) | (c2 - 0xDC00); + } + int numAdds; + for (numAdds = 1; numAdds < 5; numAdds++) + if (value < (((UInt32)1) << (numAdds * 5 + 6))) + break; + dest += (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds))); + do + { + numAdds--; + dest += (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F)); + } + while(numAdds > 0); + } + return true; +} diff --git a/Common/Copy of UTFConvert.h b/Common/Copy of UTFConvert.h new file mode 100755 index 00000000..47434111 --- /dev/null +++ b/Common/Copy of UTFConvert.h @@ -0,0 +1,11 @@ +// Common/UTFConvert.h + +#ifndef __COMMON_UTFCONVERT_H +#define __COMMON_UTFCONVERT_H + +#include "Common/String.h" + +bool ConvertUTF8ToUnicode(const AString &utfString, UString &resultString); +bool ConvertUnicodeToUTF8(const UString &unicodeString, AString &resultString); + +#endif diff --git a/Common/Defs.h b/Common/Defs.h index bfaaa6c9..dad3ae8f 100755 --- a/Common/Defs.h +++ b/Common/Defs.h @@ -1,7 +1,5 @@ // Common/Defs.h -// #pragma once - #ifndef __COMMON_DEFS_H #define __COMMON_DEFS_H diff --git a/Common/DynamicBuffer.h b/Common/DynamicBuffer.h index c41900c5..1709657d 100755 --- a/Common/DynamicBuffer.h +++ b/Common/DynamicBuffer.h @@ -1,7 +1,5 @@ // Common/DynamicBuffer.h -#pragma once - #ifndef __COMMON_DYNAMICBUFFER_H #define __COMMON_DYNAMICBUFFER_H @@ -12,14 +10,14 @@ template <class T> class CDynamicBuffer: public CBuffer<T> void GrowLength(size_t size) { size_t delta; - if (_capacity > 64) - delta = _capacity / 4; - else if (_capacity > 8) + if (this->_capacity > 64) + delta = this->_capacity / 4; + else if (this->_capacity > 8) delta = 16; else delta = 4; delta = MyMax(delta, size); - SetCapacity(_capacity + delta); + SetCapacity(this->_capacity + delta); } public: CDynamicBuffer(): CBuffer<T>() {}; @@ -27,18 +25,18 @@ public: CDynamicBuffer(size_t size): CBuffer<T>(size) {}; CDynamicBuffer& operator=(const CDynamicBuffer &buffer) { - Free(); + this->Free(); if(buffer._capacity > 0) { SetCapacity(buffer._capacity); - memmove(_items, buffer._items, buffer._capacity * sizeof(T)); + memmove(this->_items, buffer._items, buffer._capacity * sizeof(T)); } return *this; } void EnsureCapacity(size_t capacity) { - if (_capacity < capacity) - GrowLength(capacity - _capacity); + if (this->_capacity < capacity) + GrowLength(capacity - this->_capacity); } }; diff --git a/Common/Exception.h b/Common/Exception.h index a1023950..d7f86a90 100755 --- a/Common/Exception.h +++ b/Common/Exception.h @@ -1,18 +1,8 @@ // Common/Exception.h -// #pragma once - #ifndef __COMMON_EXCEPTION_H #define __COMMON_EXCEPTION_H -/* -struct CCException -{ - CCException() {} - virtual ~CCException() {} -}; -*/ - struct CSystemException { DWORD ErrorCode; @@ -21,4 +11,3 @@ struct CSystemException }; #endif - diff --git a/Common/IntToString.cpp b/Common/IntToString.cpp index 142fa218..d841635d 100755 --- a/Common/IntToString.cpp +++ b/Common/IntToString.cpp @@ -4,54 +4,60 @@ #include "IntToString.h" -void ConvertUINT64ToString(UINT64 value, char *s) +void ConvertUInt64ToString(UInt64 value, char *s, UInt32 base) { - char temp[32]; + if (base < 2 || base > 36) + { + *s = L'\0'; + return; + } + char temp[72]; int pos = 0; do { - temp[pos++] = '0' + int(value % 10); - value /= 10; + int delta = (int)(value % base); + temp[pos++] = (delta < 10) ? ('0' + delta) : ('a' + (delta - 10)); + value /= base; } while (value != 0); - while(pos > 0) + do *s++ = temp[--pos]; - *s = L'\0'; + while(pos > 0); + *s = '\0'; } -void ConvertUINT64ToString(UINT64 value, wchar_t *s) +void ConvertUInt64ToString(UInt64 value, wchar_t *s) { wchar_t temp[32]; int pos = 0; do { - temp[pos++] = L'0' + int(value % 10); + temp[pos++] = L'0' + (int)(value % 10); value /= 10; } while (value != 0); - while(pos > 0) + do *s++ = temp[--pos]; + while(pos > 0); *s = L'\0'; } -void ConvertINT64ToString(INT64 value, char *s) +void ConvertInt64ToString(Int64 value, char *s) { - if (value >= 0) - ConvertUINT64ToString(value, s); - else + if (value < 0) { *s++ = '-'; - ConvertUINT64ToString(-value, s); + value = -value; } + ConvertUInt64ToString(value, s); } -void ConvertINT64ToString(INT64 value, wchar_t *s) +void ConvertInt64ToString(Int64 value, wchar_t *s) { - if (value >= 0) - ConvertUINT64ToString(value, s); - else + if (value < 0) { *s++ = L'-'; - ConvertUINT64ToString(-value, s); + value = -value; } + ConvertUInt64ToString(value, s); } diff --git a/Common/IntToString.h b/Common/IntToString.h index a40acfba..cf86090f 100755 --- a/Common/IntToString.h +++ b/Common/IntToString.h @@ -1,18 +1,15 @@ // Common/IntToString.h -#pragma once - #ifndef __COMMON_INTTOSTRING_H #define __COMMON_INTTOSTRING_H -#include "types.h" +#include <stddef.h> +#include "Types.h" -void ConvertUINT64ToString(UINT64 value, char *s); -void ConvertUINT64ToString(UINT64 value, wchar_t *s); +void ConvertUInt64ToString(UInt64 value, char *s, UInt32 base = 10); +void ConvertUInt64ToString(UInt64 value, wchar_t *s); -void ConvertINT64ToString(INT64 value, char *s); -void ConvertINT64ToString(INT64 value, wchar_t *s); +void ConvertInt64ToString(Int64 value, char *s); +void ConvertInt64ToString(Int64 value, wchar_t *s); #endif - - diff --git a/Common/Lang.cpp b/Common/Lang.cpp index 9a004c37..495a3f06 100755 --- a/Common/Lang.cpp +++ b/Common/Lang.cpp @@ -10,9 +10,9 @@ #include "Defs.h" /* -static UINT32 HexStringToNumber(const char *string, int &finishPos) +static UInt32 HexStringToNumber(const char *string, int &finishPos) { - UINT32 number = 0; + UInt32 number = 0; for (finishPos = 0; finishPos < 8; finishPos++) { char c = string[finishPos]; @@ -31,7 +31,7 @@ static UINT32 HexStringToNumber(const char *string, int &finishPos) return number; } */ -static bool HexStringToNumber(const UString &string, UINT32 &aResultValue) +static bool HexStringToNumber(const UString &string, UInt32 &aResultValue) { aResultValue = 0; if (string.IsEmpty()) @@ -82,7 +82,7 @@ bool CLang::Open(LPCTSTR fileName) int pos = 0; if (string.Length() >= 3) { - if (BYTE(string[0]) == 0xEF && BYTE(string[1]) == 0xBB && BYTE(string[2]) == 0xBF) + if (Byte(string[0]) == 0xEF && Byte(string[1]) == 0xBB && Byte(string[2]) == 0xBF) pos += 3; } @@ -117,13 +117,13 @@ bool CLang::Open(LPCTSTR fileName) return true; } -int CLang::FindItem(UINT32 value) const +int CLang::FindItem(UInt32 value) const { int left = 0, right = _langPairs.Size(); while (left != right) { - UINT32 mid = (left + right) / 2; - UINT32 midValue = _langPairs[mid].Value; + UInt32 mid = (left + right) / 2; + UInt32 midValue = _langPairs[mid].Value; if (value == midValue) return mid; if (value < midValue) @@ -134,7 +134,7 @@ int CLang::FindItem(UINT32 value) const return -1; } -bool CLang::GetMessage(UINT32 value, UString &message) const +bool CLang::GetMessage(UInt32 value, UString &message) const { int index = FindItem(value); if (index < 0) diff --git a/Common/Lang.h b/Common/Lang.h index 683268db..2b4615d0 100755 --- a/Common/Lang.h +++ b/Common/Lang.h @@ -1,16 +1,15 @@ // Common/Lang.h -#pragma once - #ifndef __COMMON_LANG_H #define __COMMON_LANG_H #include "Common/Vector.h" #include "Common/String.h" +#include "Common/Types.h" struct CLangPair { - UINT32 Value; + UInt32 Value; UString String; }; @@ -20,8 +19,8 @@ class CLang public: bool Open(LPCTSTR fileName); void Clear() { _langPairs.Clear(); } - int FindItem(UINT32 value) const; - bool GetMessage(UINT32 value, UString &message) const; + int FindItem(UInt32 value) const; + bool GetMessage(UInt32 value, UString &message) const; }; #endif diff --git a/Common/ListFileUtils.h b/Common/ListFileUtils.h index 7debead8..93bb4507 100755 --- a/Common/ListFileUtils.h +++ b/Common/ListFileUtils.h @@ -1,7 +1,5 @@ // Common/ListFileUtils.h -#pragma once - #ifndef __COMMON_LISTFILEUTILS_H #define __COMMON_LISTFILEUTILS_H diff --git a/Common/MyCom.h b/Common/MyCom.h index 40e4ce29..4101d815 100755 --- a/Common/MyCom.h +++ b/Common/MyCom.h @@ -1,10 +1,10 @@ // MyCom.h -// #pragma once - #ifndef __MYCOM_H #define __MYCOM_H +#include "MyWindows.h" + #define RINOK(x) { HRESULT __result_ = (x); if(__result_ != S_OK) return __result_; } template <class T> @@ -50,10 +50,12 @@ public: _p = NULL; return pt; } + #ifdef _WIN32 HRESULT CoCreateInstance(REFCLSID rclsid, REFIID iid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) { return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, (void**)&_p); } + #endif /* HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) { @@ -146,8 +148,10 @@ public: #define MY_QUERYINTERFACE_BEGIN STDMETHOD(QueryInterface) \ (REFGUID iid, void **outObject) { + #define MY_QUERYINTERFACE_ENTRY(i) if (iid == IID_ ## i) \ { *outObject = (void *)(i *)this; AddRef(); return S_OK; } + #define MY_QUERYINTERFACE_END return E_NOINTERFACE; } #define MY_ADDREF_RELEASE \ @@ -172,11 +176,13 @@ STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \ MY_QUERYINTERFACE_ENTRY(i1) \ MY_QUERYINTERFACE_ENTRY(i2) \ ) + #define MY_UNKNOWN_IMP3(i1, i2, i3) MY_UNKNOWN_IMP_SPEC( \ MY_QUERYINTERFACE_ENTRY(i1) \ MY_QUERYINTERFACE_ENTRY(i2) \ MY_QUERYINTERFACE_ENTRY(i3) \ ) + #define MY_UNKNOWN_IMP4(i1, i2, i3, i4) MY_UNKNOWN_IMP_SPEC( \ MY_QUERYINTERFACE_ENTRY(i1) \ MY_QUERYINTERFACE_ENTRY(i2) \ @@ -184,4 +190,12 @@ STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \ MY_QUERYINTERFACE_ENTRY(i4) \ ) +#define MY_UNKNOWN_IMP5(i1, i2, i3, i4, i5) MY_UNKNOWN_IMP_SPEC( \ + MY_QUERYINTERFACE_ENTRY(i1) \ + MY_QUERYINTERFACE_ENTRY(i2) \ + MY_QUERYINTERFACE_ENTRY(i3) \ + MY_QUERYINTERFACE_ENTRY(i4) \ + MY_QUERYINTERFACE_ENTRY(i5) \ + ) + #endif diff --git a/Common/MyGuidDef.h b/Common/MyGuidDef.h new file mode 100755 index 00000000..2fb7df65 --- /dev/null +++ b/Common/MyGuidDef.h @@ -0,0 +1,52 @@ +// Common/MyGuidDef.h + +#ifndef GUID_DEFINED +#define GUID_DEFINED + +typedef struct { + unsigned long Data1; + unsigned short Data2; + unsigned short Data3; + unsigned char Data4[8]; +} GUID; + +#ifdef __cplusplus +#define REFGUID const GUID & +#else +#define REFGUID const GUID * +#endif + +#define REFCLSID REFGUID +#define REFIID REFGUID + +#ifdef __cplusplus +inline bool operator==(REFGUID g1, REFGUID g2) +{ + for (int i = 0; i < (int)sizeof(g1); i++) + if (((unsigned char *)&g1)[i] != ((unsigned char *)&g2)[i]) + return false; + return true; +} +inline bool operator!=(REFGUID g1, REFGUID g2) { return !(g1 == g2); } +#endif + +#ifdef __cplusplus + #define MY_EXTERN_C extern "C" +#else + #define MY_EXTERN_C extern +#endif + +#endif // GUID_DEFINED + + +#ifdef DEFINE_GUID +#undef DEFINE_GUID +#endif + +#ifdef INITGUID + #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + MY_EXTERN_C const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } +#else + #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + MY_EXTERN_C const GUID name +#endif diff --git a/Common/MyInitGuid.h b/Common/MyInitGuid.h new file mode 100755 index 00000000..5bdfeed5 --- /dev/null +++ b/Common/MyInitGuid.h @@ -0,0 +1,13 @@ +// Common/MyInitGuid.h + +#ifndef __COMMON_MYINITGUID_H +#define __COMMON_MYINITGUID_H + +#ifdef _WIN32 +#include <initguid.h> +#else +#define INITGUID +#include "MyGuidDef.h" +#endif + +#endif diff --git a/Common/MyUnknown.h b/Common/MyUnknown.h new file mode 100755 index 00000000..d28d8542 --- /dev/null +++ b/Common/MyUnknown.h @@ -0,0 +1,24 @@ +// MyUnknown.h + +#ifndef __MYUNKNOWN_H +#define __MYUNKNOWN_H + +#ifdef _WIN32 + +#ifdef _WIN32_WCE +#if (_WIN32_WCE > 300) +#include <basetyps.h> +#else +#define MIDL_INTERFACE(x) struct +#endif +#else +#include <basetyps.h> +#endif + +#include <unknwn.h> + +#else +#include "MyWindows.h" +#endif + +#endif diff --git a/Common/MyWindows.cpp b/Common/MyWindows.cpp new file mode 100755 index 00000000..4cf065cf --- /dev/null +++ b/Common/MyWindows.cpp @@ -0,0 +1,113 @@ +// MyWindows.cpp + +#include "StdAfx.h" + +#ifndef _WIN32 + +#include "MyWindows.h" +#include "Types.h" +#include <malloc.h> + +static inline void *AllocateForBSTR(size_t cb) { return ::malloc(cb); } +static inline void FreeForBSTR(void *pv) { ::free(pv);} + +static UINT MyStringLen(const wchar_t *s) +{ + UINT i; + for (i = 0; s[i] != '\0'; i++); + return i; +} + +BSTR SysAllocStringByteLen(LPCSTR psz, UINT len) +{ + int realLen = len + sizeof(UINT) + sizeof(OLECHAR) + sizeof(OLECHAR); + void *p = AllocateForBSTR(realLen); + if (p == 0) + return 0; + *(UINT *)p = len; + BSTR bstr = (BSTR)((UINT *)p + 1); + memmove(bstr, psz, len); + Byte *pb = ((Byte *)bstr) + len; + for (int i = 0; i < sizeof(OLECHAR) * 2; i++) + pb[i] = 0; + return bstr; +} + +BSTR SysAllocString(const OLECHAR *sz) +{ + if (sz == 0) + return 0; + UINT strLen = MyStringLen(sz); + UINT len = (strLen + 1) * sizeof(OLECHAR); + void *p = AllocateForBSTR(len + sizeof(UINT)); + if (p == 0) + return 0; + *(UINT *)p = strLen; + BSTR bstr = (BSTR)((UINT *)p + 1); + memmove(bstr, sz, len); + return bstr; +} + +void SysFreeString(BSTR bstr) +{ + if (bstr != 0) + FreeForBSTR((UINT *)bstr - 1); +} + +UINT SysStringByteLen(BSTR bstr) +{ + if (bstr == 0) + return 0; + return *((UINT *)bstr - 1); +} + +UINT SysStringLen(BSTR bstr) +{ + return SysStringByteLen(bstr) / sizeof(OLECHAR); +} + +HRESULT VariantClear(VARIANTARG *prop) +{ + if (prop->vt == VT_BSTR) + SysFreeString(prop->bstrVal); + prop->vt = VT_EMPTY; + return S_OK; +} + +HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src) +{ + HRESULT res = ::VariantClear(dest); + if (res != S_OK) + return res; + if (src->vt == VT_BSTR) + { + dest->bstrVal = SysAllocStringByteLen((LPCSTR)src->bstrVal, + SysStringByteLen(src->bstrVal)); + if (dest->bstrVal == 0) + return E_OUTOFMEMORY; + dest->vt = VT_BSTR; + } + else + *dest = *src; + return S_OK; +} + +LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2) +{ + if(ft1->dwHighDateTime < ft2->dwHighDateTime) + return -1; + if(ft1->dwHighDateTime > ft2->dwHighDateTime) + return 1; + if(ft1->dwLowDateTime < ft2->dwLowDateTime) + return -1; + if(ft1->dwLowDateTime > ft2->dwLowDateTime) + return 1; + return 0; +} + +DWORD GetLastError() +{ + return 0; +} + +#endif diff --git a/Common/MyWindows.h b/Common/MyWindows.h new file mode 100755 index 00000000..d93afc1c --- /dev/null +++ b/Common/MyWindows.h @@ -0,0 +1,184 @@ +// MyWindows.h + +#ifndef __MYWINDOWS_H +#define __MYWINDOWS_H + +#ifdef _WIN32 + +#include <windows.h> + +#else + +#include <stddef.h> // for wchar_t +#include <string.h> + +#include "Types.h" +#include "MyGuidDef.h" + +typedef char CHAR; +typedef unsigned char UCHAR; +typedef unsigned char BYTE; + +typedef short SHORT; +typedef unsigned short USHORT; +typedef unsigned short WORD; +typedef short VARIANT_BOOL; + +typedef int INT; +typedef Int32 INT32; +typedef unsigned int UINT; +typedef UInt32 UINT32; +typedef INT32 LONG; // LONG, ULONG and DWORD must be 32-bit +typedef UINT32 ULONG; +typedef UINT32 DWORD; + +typedef Int64 LONGLONG; +typedef UInt64 ULONGLONG; + +typedef struct LARGE_INTEGER { LONGLONG QuadPart; }LARGE_INTEGER; +typedef struct _ULARGE_INTEGER { ULONGLONG QuadPart;} ULARGE_INTEGER; + +typedef const CHAR *LPCSTR; +typedef CHAR TCHAR; +typedef const TCHAR *LPCTSTR; +typedef wchar_t WCHAR; +typedef WCHAR OLECHAR; +typedef const WCHAR *LPCWSTR; +typedef OLECHAR *BSTR; +typedef const OLECHAR *LPCOLESTR; +typedef OLECHAR *LPOLESTR; + +typedef struct _FILETIME +{ + DWORD dwLowDateTime; + DWORD dwHighDateTime; +}FILETIME; + +#define HRESULT LONG +#define FAILED(Status) ((HRESULT)(Status)<0) +typedef ULONG PROPID; +typedef LONG SCODE; + +#define S_OK ((HRESULT)0x00000000L) +#define S_FALSE ((HRESULT)0x00000001L) +#define E_NOINTERFACE ((HRESULT)0x80004002L) +#define E_ABORT ((HRESULT)0x80004004L) +#define E_FAIL ((HRESULT)0x80004005L) +#define STG_E_INVALIDFUNCTION ((HRESULT)0x80030001L) +#define E_OUTOFMEMORY ((HRESULT)0x8007000EL) +#define E_INVALIDARG ((HRESULT)0x80070057L) + +#ifdef _MSC_VER +#define STDMETHODCALLTYPE __stdcall +#else +#define STDMETHODCALLTYPE +#endif + +#define STDMETHOD_(t, f) virtual t STDMETHODCALLTYPE f +#define STDMETHOD(f) STDMETHOD_(HRESULT, f) +#define STDMETHODIMP_(type) type STDMETHODCALLTYPE +#define STDMETHODIMP STDMETHODIMP_(HRESULT) + +#define PURE = 0 + +#define MIDL_INTERFACE(x) struct + +struct IUnknown +{ + STDMETHOD(QueryInterface) (REFIID iid, void **outObject) PURE; + STDMETHOD_(ULONG, AddRef)() PURE; + STDMETHOD_(ULONG, Release)() PURE; +}; + +typedef IUnknown *LPUNKNOWN; + +#define VARIANT_TRUE ((VARIANT_BOOL)-1) +#define VARIANT_FALSE ((VARIANT_BOOL)0) + +enum VARENUM +{ + VT_EMPTY = 0, + VT_NULL = 1, + VT_I2 = 2, + VT_I4 = 3, + VT_R4 = 4, + VT_R8 = 5, + VT_CY = 6, + VT_DATE = 7, + VT_BSTR = 8, + VT_DISPATCH = 9, + VT_ERROR = 10, + VT_BOOL = 11, + VT_VARIANT = 12, + VT_UNKNOWN = 13, + VT_DECIMAL = 14, + VT_I1 = 16, + VT_UI1 = 17, + VT_UI2 = 18, + VT_UI4 = 19, + VT_I8 = 20, + VT_UI8 = 21, + VT_INT = 22, + VT_UINT = 23, + VT_VOID = 24, + VT_HRESULT = 25, + VT_FILETIME = 64 +}; + +typedef unsigned short VARTYPE; +typedef WORD PROPVAR_PAD1; +typedef WORD PROPVAR_PAD2; +typedef WORD PROPVAR_PAD3; + +typedef struct tagPROPVARIANT +{ + VARTYPE vt; + PROPVAR_PAD1 wReserved1; + PROPVAR_PAD2 wReserved2; + PROPVAR_PAD3 wReserved3; + union + { + CHAR cVal; + UCHAR bVal; + SHORT iVal; + USHORT uiVal; + LONG lVal; + ULONG ulVal; + INT intVal; + UINT uintVal; + LARGE_INTEGER hVal; + ULARGE_INTEGER uhVal; + VARIANT_BOOL boolVal; + SCODE scode; + FILETIME filetime; + BSTR bstrVal; + }; +} PROPVARIANT; + +typedef PROPVARIANT tagVARIANT; +typedef tagVARIANT VARIANT; +typedef VARIANT VARIANTARG; + +MY_EXTERN_C BSTR SysAllocStringByteLen(LPCSTR psz, UINT len); +MY_EXTERN_C BSTR SysAllocString(const OLECHAR *sz); +MY_EXTERN_C void SysFreeString(BSTR bstr); +MY_EXTERN_C UINT SysStringByteLen(BSTR bstr); +MY_EXTERN_C UINT SysStringLen(BSTR bstr); + +MY_EXTERN_C DWORD GetLastError(); +MY_EXTERN_C HRESULT VariantClear(VARIANTARG *prop); +MY_EXTERN_C HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src); +MY_EXTERN_C LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2); + +#define CP_ACP 0 +#define CP_OEMCP 1 + +typedef enum tagSTREAM_SEEK +{ + STREAM_SEEK_SET = 0, + STREAM_SEEK_CUR = 1, + STREAM_SEEK_END = 2 +} STREAM_SEEK; + +#endif +#endif diff --git a/Common/NewHandler.cpp b/Common/NewHandler.cpp index d45d51b0..3b036bdb 100755 --- a/Common/NewHandler.cpp +++ b/Common/NewHandler.cpp @@ -8,6 +8,7 @@ #ifndef DEBUG_MEMORY_LEAK +#include <stdlib.h> void * __cdecl operator new(size_t size) { diff --git a/Common/NewHandler.h b/Common/NewHandler.h index c1e430e2..331f3043 100755 --- a/Common/NewHandler.h +++ b/Common/NewHandler.h @@ -1,12 +1,8 @@ // Common/NewHandler.h -#pragma once - #ifndef __COMMON_NEWHANDLER_H #define __COMMON_NEWHANDLER_H -#include "Exception.h" - -class CNewException: public CSystemException{}; +class CNewException {}; #endif diff --git a/Common/Random.cpp b/Common/Random.cpp index 6232a920..c003e8a7 100755 --- a/Common/Random.cpp +++ b/Common/Random.cpp @@ -3,6 +3,7 @@ #include "StdAfx.h" #include <time.h> +#include <stdlib.h> #include "Common/Random.h" diff --git a/Common/Random.h b/Common/Random.h index 6f3b39b7..ffef20d1 100755 --- a/Common/Random.h +++ b/Common/Random.h @@ -1,7 +1,5 @@ // Common/Random.h -#pragma once - #ifndef __COMMON_RANDOM_H #define __COMMON_RANDOM_H diff --git a/Common/StdAfx.h b/Common/StdAfx.h index a32fbed6..38c17215 100755 --- a/Common/StdAfx.h +++ b/Common/StdAfx.h @@ -1,8 +1,8 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> +// #include "MyWindows.h" #endif diff --git a/Common/StdInStream.cpp b/Common/StdInStream.cpp index 9c45da29..8da30738 100755 --- a/Common/StdInStream.cpp +++ b/Common/StdInStream.cpp @@ -39,18 +39,18 @@ CStdInStream::~CStdInStream() AString CStdInStream::ScanStringUntilNewLine() { - AString string; + AString s; while(true) { - int aIntChar = GetChar(); - if(aIntChar == EOF) + int intChar = GetChar(); + if(intChar == EOF) throw kEOFMessage; - char aChar = char(aIntChar); - if (aChar == kIllegalChar) + char c = char(intChar); + if (c == kIllegalChar) throw kIllegalCharMessage; - if(aChar == kNewLineChar) - return string; - string += aChar; + if(c == kNewLineChar) + return s; + s += c; } } diff --git a/Common/StdInStream.h b/Common/StdInStream.h index 2a5c18f1..c1a0a222 100755 --- a/Common/StdInStream.h +++ b/Common/StdInStream.h @@ -1,13 +1,11 @@ // Common/StdInStream.h -#pragma once - #ifndef __COMMON_STDINSTREAM_H #define __COMMON_STDINSTREAM_H #include <stdio.h> -#include "String.h" +#include "Common/String.h" #include "Types.h" class CStdInStream diff --git a/Common/StdOutStream.cpp b/Common/StdOutStream.cpp index f1174a83..b00fc399 100755 --- a/Common/StdOutStream.cpp +++ b/Common/StdOutStream.cpp @@ -10,15 +10,15 @@ static const char kNewLineChar = '\n'; -static LPCTSTR kFileOpenMode = TEXT("wt"); +static const char *kFileOpenMode = "wt"; CStdOutStream g_StdOut(stdout); CStdOutStream g_StdErr(stderr); -bool CStdOutStream::Open(LPCTSTR fileName) +bool CStdOutStream::Open(const char *fileName) { Close(); - _stream = _tfopen(fileName, kFileOpenMode); + _stream = fopen(fileName, kFileOpenMode); _streamIsOpen = (_stream != 0); return _streamIsOpen; } @@ -67,14 +67,14 @@ CStdOutStream & CStdOutStream::operator<<(char c) CStdOutStream & CStdOutStream::operator<<(int number) { - char textString[16]; - ConvertINT64ToString(number, textString); + char textString[32]; + ConvertInt64ToString(number, textString); return operator<<(textString); } -CStdOutStream & CStdOutStream::operator<<(UINT64 number) +CStdOutStream & CStdOutStream::operator<<(UInt64 number) { char textString[32]; - ConvertUINT64ToString(number, textString); + ConvertUInt64ToString(number, textString); return operator<<(textString); } diff --git a/Common/StdOutStream.h b/Common/StdOutStream.h index 8ebf9aa7..bf63bb3a 100755 --- a/Common/StdOutStream.h +++ b/Common/StdOutStream.h @@ -1,7 +1,5 @@ // Common/StdOutStream.h -#pragma once - #ifndef __COMMON_STDOUTSTREAM_H #define __COMMON_STDOUTSTREAM_H @@ -17,7 +15,7 @@ public: CStdOutStream (): _streamIsOpen(false) {}; CStdOutStream (FILE *stream): _streamIsOpen(false), _stream(stream) {}; ~CStdOutStream (); - bool Open(LPCTSTR fileName); + bool Open(const char *fileName); bool Close(); CStdOutStream & operator<<(CStdOutStream & (* aFunction)(CStdOutStream &)); @@ -25,7 +23,7 @@ public: CStdOutStream & operator<<(const wchar_t *string); CStdOutStream & operator<<(char c); CStdOutStream & operator<<(int number); - CStdOutStream & operator<<(UINT64 number); + CStdOutStream & operator<<(UInt64 number); }; CStdOutStream & endl(CStdOutStream & outStream); diff --git a/Common/String.cpp b/Common/String.cpp index 6e109b70..34ec37e0 100755 --- a/Common/String.cpp +++ b/Common/String.cpp @@ -2,8 +2,16 @@ #include "StdAfx.h" -#include "String.h" +#ifdef _WIN32 #include "StringConvert.h" +#else +#include <ctype.h> +#endif + +#include "Common/String.h" + + +#ifdef _WIN32 #ifndef _UNICODE @@ -11,9 +19,9 @@ wchar_t MyCharUpper(wchar_t c) { if (c == 0) return 0; - wchar_t *res = CharUpperW((LPWSTR)c); + wchar_t *res = CharUpperW((LPWSTR)(unsigned int)c); if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) - return (wchar_t)res; + return (wchar_t)(unsigned int)res; const int kBufferSize = 4; char s[kBufferSize]; int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufferSize, 0, 0); @@ -26,9 +34,9 @@ wchar_t MyCharLower(wchar_t c) { if (c == 0) return 0; - wchar_t *res = CharLowerW((LPWSTR)c); + wchar_t *res = CharLowerW((LPWSTR)(unsigned int)c); if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) - return (wchar_t)res; + return (wchar_t)(unsigned int)res; const int kBufferSize = 4; char s[kBufferSize]; int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufferSize, 0, 0); @@ -61,24 +69,107 @@ wchar_t * MyStringLower(wchar_t *s) return MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a)); } +#endif + +inline int ConvertCompareResult(int r) { return r - 2; } + int MyStringCollate(const wchar_t *s1, const wchar_t *s2) { int res = CompareStringW( LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1); + #ifdef _UNICODE + return ConvertCompareResult(res); + #else if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) return ConvertCompareResult(res); return MyStringCollate(UnicodeStringToMultiByte(s1), UnicodeStringToMultiByte(s2)); + #endif } +#ifndef _WIN32_WCE +int MyStringCollate(const char *s1, const char *s2) +{ + return ConvertCompareResult(CompareStringA( + LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1)); +} + +int MyStringCollateNoCase(const char *s1, const char *s2) +{ + return ConvertCompareResult(CompareStringA( + LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1)); +} +#endif + int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2) { int res = CompareStringW( LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1); + #ifdef _UNICODE + return ConvertCompareResult(res); + #else if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) return ConvertCompareResult(res); return MyStringCollateNoCase(UnicodeStringToMultiByte(s1), UnicodeStringToMultiByte(s2)); + #endif +} + +#else + +inline int NormalizeCompareResult(int res) +{ + if (res < 0) return -1; + if (res > 0) return 1; + return 0; +} + +/* +inline wchar_t MyCharUpper(wchar_t c) + { return towupper(c); } +*/ +wchar_t MyCharUpper(wchar_t c) +{ + return toupper(c); +} + +int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2) +{ + while (true) + { + wchar_t c1 = *s1++; + wchar_t c2 = *s2++; + wchar_t u1 = MyCharUpper(c1); + wchar_t u2 = MyCharUpper(c2); + + if (u1 < u2) return -1; + if (u1 > u2) return 1; + if (u1 == 0) return 0; + } } #endif + +int MyStringCompare(const char *s1, const char *s2) +{ + while (true) + { + unsigned char c1 = (unsigned char)*s1++; + unsigned char c2 = (unsigned char)*s2++; + if (c1 < c2) return -1; + if (c1 > c2) return 1; + if (c1 == 0) return 0; + } +} + +int MyStringCompare(const wchar_t *s1, const wchar_t *s2) +{ + while (true) + { + wchar_t c1 = *s1++; + wchar_t c2 = *s2++; + if (c1 < c2) return -1; + if (c1 > c2) return 1; + if (c1 == 0) return 0; + } +} diff --git a/Common/String.h b/Common/String.h index be273271..bbe05174 100755 --- a/Common/String.h +++ b/Common/String.h @@ -1,13 +1,16 @@ // Common/String.h -#pragma once - #ifndef __COMMON_STRING_H #define __COMMON_STRING_H +#include <string.h> +// #include <wchar.h> + #include "Vector.h" -extern bool g_IsNT; +#ifdef _WIN32 +#include "MyWindows.h" +#endif static const char *kTrimDefaultCharSet = " \n\t"; @@ -36,7 +39,7 @@ inline wchar_t* MyStringGetPrevCharPointer(const wchar_t *base, wchar_t *p) inline const wchar_t* MyStringGetPrevCharPointer(const wchar_t *base, const wchar_t *p) { return (p - 1); } -#ifdef WIN32 +#ifdef _WIN32 inline char* MyStringGetNextCharPointer(char *p) { return CharNextA(p); } @@ -49,7 +52,7 @@ inline const char* MyStringGetPrevCharPointer(const char *base, const char *p) { return CharPrevA(base, p); } inline char MyCharUpper(char c) - { return (char)CharUpperA((LPSTR)(unsigned char)c); } + { return (char)(unsigned int)CharUpperA((LPSTR)(unsigned int)(unsigned char)c); } #ifdef _UNICODE inline wchar_t MyCharUpper(wchar_t c) { return (wchar_t)CharUpperW((LPWSTR)c); } @@ -58,7 +61,7 @@ wchar_t MyCharUpper(wchar_t c); #endif inline char MyCharLower(char c) - { return (char)CharLowerA((LPSTR)(unsigned char)c); } + { return (char)(unsigned int)CharLowerA((LPSTR)(unsigned int)(unsigned char)c); } #ifdef _UNICODE inline wchar_t MyCharLower(wchar_t c) { return (wchar_t)CharLowerW((LPWSTR)c); } @@ -66,89 +69,36 @@ inline wchar_t MyCharLower(wchar_t c) wchar_t MyCharLower(wchar_t c); #endif - -inline char * MyStringUpper(char *s) - { return CharUpperA(s); } +inline char * MyStringUpper(char *s) { return CharUpperA(s); } #ifdef _UNICODE -inline wchar_t * MyStringUpper(wchar_t *s) - { return CharUpperW(s); } +inline wchar_t * MyStringUpper(wchar_t *s) { return CharUpperW(s); } #else wchar_t * MyStringUpper(wchar_t *s); #endif -inline char * MyStringLower(char *s) - { return CharLowerA(s); } +inline char * MyStringLower(char *s) { return CharLowerA(s); } #ifdef _UNICODE -inline wchar_t * MyStringLower(wchar_t *s) - { return CharLowerW(s); } +inline wchar_t * MyStringLower(wchar_t *s) { return CharLowerW(s); } #else wchar_t * MyStringLower(wchar_t *s); #endif +#else // Standard-C +wchar_t MyCharUpper(wchar_t c); +#endif ////////////////////////////////////// // Compare -inline int ConvertCompareResult(int r) - { return r - 2; } - -inline int MyStringCollate(const char *s1, const char *s2) - { return ConvertCompareResult(CompareStringA( - LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1)); } -#ifdef _UNICODE -inline int MyStringCollate(const wchar_t *s1, const wchar_t *s2) - { return ConvertCompareResult(CompareStringW( - LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1)); } -#else -int MyStringCollate(const wchar_t *s1, const wchar_t *s2); +#ifndef _WIN32_WCE +int MyStringCollate(const char *s1, const char *s2); +int MyStringCollateNoCase(const char *s1, const char *s2); #endif - -inline int MyStringCollateNoCase(const char *s1, const char *s2) - { return ConvertCompareResult(CompareStringA( - LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1)); } -#ifdef _UNICODE -inline int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2) - { return ConvertCompareResult(CompareStringW( - LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1)); } -#else +int MyStringCollate(const wchar_t *s1, const wchar_t *s2); int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2); -#endif -#else // Standard-C - -inline NormalizeCompareResult(int res) -{ - if (res < 0) - return -1; - if (res > 0) - return 1; - return 0; -} - -inline wchar_t MyCharUpper(wchar_t c) - { return towupper(c); } - -inline int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2) - { return NormalizeCompareResult(wcscoll(s1, s2)); } - -#endif - - -template <class T> -inline int MyStringCompare(const T *s1, const T *s2) -{ - while (true) - { - unsigned int c1 = (unsigned int)*s1++; - unsigned int c2 = (unsigned int)*s2++; - if (c1 < c2) - return -1; - if (c1 > c2) - return 1; - if (c1 == 0) - return 0; - } -} +int MyStringCompare(const char *s1, const char *s2); +int MyStringCompare(const wchar_t *s1, const wchar_t *s2); template <class T> inline int MyStringCompareNoCase(const T *s1, const T *s2) @@ -471,21 +421,24 @@ public: p = GetNextCharPointer(p); Delete(0, p - _chars); } - void TrimLeft() + private: + CStringBase GetTrimDefaultCharSet() { CStringBase<T> charSet; - for(int i = 0; i < sizeof(kTrimDefaultCharSet) / - sizeof(kTrimDefaultCharSet[0]); i++) - charSet += kTrimDefaultCharSet[i]; - TrimLeftWithCharSet(charSet); + for(int i = 0; i < (int)(sizeof(kTrimDefaultCharSet) / + sizeof(kTrimDefaultCharSet[0])); i++) + charSet += (T)kTrimDefaultCharSet[i]; + return charSet; + } + public: + + void TrimLeft() + { + TrimLeftWithCharSet(GetTrimDefaultCharSet()); } void TrimRight() { - CStringBase<T> charSet; - for(int i = 0; i < sizeof(kTrimDefaultCharSet) / - sizeof(kTrimDefaultCharSet[0]); i++) - charSet += kTrimDefaultCharSet[i]; - TrimRightWithCharSet(charSet); + TrimRightWithCharSet(GetTrimDefaultCharSet()); } void TrimRight(T c) { diff --git a/Common/StringConvert.cpp b/Common/StringConvert.cpp index 961c8454..d6d05d6c 100755 --- a/Common/StringConvert.cpp +++ b/Common/StringConvert.cpp @@ -4,7 +4,11 @@ #include "StringConvert.h" -#ifdef WIN32 +#ifndef _WIN32 +#include <stdlib.h> +#endif + +#ifdef _WIN32 UString MultiByteToUnicodeString(const AString &srcString, UINT codePage) { UString resultString; @@ -57,6 +61,14 @@ UString MultiByteToUnicodeString(const AString &srcString, UINT codePage) UString resultString; for (int i = 0; i < srcString.Length(); i++) resultString += wchar_t(srcString[i]); + /* + if(!srcString.IsEmpty()) + { + int numChars = mbstowcs(resultString.GetBuffer(srcString.Length()), srcString, srcString.Length() + 1); + if (numChars < 0) throw "Your environment does not support UNICODE"; + resultString.ReleaseBuffer(numChars); + } + */ return resultString; } @@ -65,7 +77,17 @@ AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage) AString resultString; for (int i = 0; i < srcString.Length(); i++) resultString += char(srcString[i]); + /* + if(!srcString.IsEmpty()) + { + int numRequiredBytes = srcString.Length() * 6 + 1; + int numChars = wcstombs(resultString.GetBuffer(numRequiredBytes), srcString, numRequiredBytes); + if (numChars < 0) throw "Your environment does not support UNICODE"; + resultString.ReleaseBuffer(numChars); + } + */ return resultString; } -#endif
\ No newline at end of file +#endif + diff --git a/Common/StringConvert.h b/Common/StringConvert.h index 982fb897..daee50b0 100755 --- a/Common/StringConvert.h +++ b/Common/StringConvert.h @@ -1,11 +1,10 @@ // Common/StringConvert.h -#pragma once - #ifndef __COMMON_STRINGCONVERT_H #define __COMMON_STRINGCONVERT_H -#include "String.h" +#include "MyWindows.h" +#include "Common/String.h" #include "Types.h" UString MultiByteToUnicodeString(const AString &srcString, UINT codePage = CP_ACP); diff --git a/Common/StringToInt.cpp b/Common/StringToInt.cpp index a592b062..9f02ec9d 100755 --- a/Common/StringToInt.cpp +++ b/Common/StringToInt.cpp @@ -4,9 +4,9 @@ #include "StringToInt.h" -UINT64 ConvertStringToUINT64(const char *s, const char **end) +UInt64 ConvertStringToUInt64(const char *s, const char **end) { - UINT64 result = 0; + UInt64 result = 0; while(true) { char c = *s; @@ -22,9 +22,9 @@ UINT64 ConvertStringToUINT64(const char *s, const char **end) } } -UINT64 ConvertStringToUINT64(const wchar_t *s, const wchar_t **end) +UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end) { - UINT64 result = 0; + UInt64 result = 0; while(true) { wchar_t c = *s; @@ -41,10 +41,9 @@ UINT64 ConvertStringToUINT64(const wchar_t *s, const wchar_t **end) } -INT64 ConvertStringToINT64(const char *s, const char **end) +Int64 ConvertStringToInt64(const char *s, const char **end) { - INT64 result = 0; if (*s == '-') - return -(INT64)ConvertStringToUINT64(s + 1, end); - return ConvertStringToUINT64(s, end); + return -(Int64)ConvertStringToUInt64(s + 1, end); + return ConvertStringToUInt64(s, end); } diff --git a/Common/StringToInt.h b/Common/StringToInt.h index 3c7961de..f3fc22e8 100755 --- a/Common/StringToInt.h +++ b/Common/StringToInt.h @@ -1,14 +1,15 @@ // Common/StringToInt.h -#pragma once - #ifndef __COMMON_STRINGTOINT_H #define __COMMON_STRINGTOINT_H -UINT64 ConvertStringToUINT64(const char *s, const char **end); -UINT64 ConvertStringToUINT64(const wchar_t *s, const wchar_t **end); +#include <string.h> +#include "Types.h" + +UInt64 ConvertStringToUInt64(const char *s, const char **end); +UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end); -INT64 ConvertStringToINT64(const char *s, const char **end); +Int64 ConvertStringToInt64(const char *s, const char **end); #endif diff --git a/Common/TextConfig.h b/Common/TextConfig.h index 62cf98e9..1552df65 100755 --- a/Common/TextConfig.h +++ b/Common/TextConfig.h @@ -1,7 +1,5 @@ // Common/TextConfig.h -#pragma once - #ifndef __COMMON_TEXTCONFIG_H #define __COMMON_TEXTCONFIG_H diff --git a/Common/Types.h b/Common/Types.h index 02853e0d..0bf66e08 100755 --- a/Common/Types.h +++ b/Common/Types.h @@ -1,19 +1,19 @@ // Common/Types.h -// #pragma once - #ifndef __COMMON_TYPES_H #define __COMMON_TYPES_H -#include <basetsd.h> - -typedef unsigned char UINT8; -typedef unsigned short UINT16; -typedef short INT16; -#ifndef _WINDOWS_ - // typedef unsigned long UINT32; - typedef UINT8 BYTE; +typedef unsigned char Byte; +typedef short Int16; +typedef unsigned short UInt16; +typedef int Int32; +typedef unsigned int UInt32; +#ifdef _MSC_VER +typedef __int64 Int64; +typedef unsigned __int64 UInt64; +#else +typedef long long int Int64; +typedef unsigned long long int UInt64; #endif #endif - diff --git a/Common/UTFConvert.cpp b/Common/UTFConvert.cpp index 22404466..e15695bb 100755 --- a/Common/UTFConvert.cpp +++ b/Common/UTFConvert.cpp @@ -5,66 +5,87 @@ #include "UTFConvert.h" #include "Types.h" -bool ConvertUTF8ToUnicode(const AString &utfString, UString &resultString) +static Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; + +// These functions are for UTF8 <-> UTF16 conversion. + +bool ConvertUTF8ToUnicode(const AString &src, UString &dest) { - resultString.Empty(); - for(int i = 0; i < utfString.Length(); i++) + dest.Empty(); + for(int i = 0; i < src.Length();) { - BYTE c = utfString[i]; + Byte c = (Byte)src[i++]; if (c < 0x80) { - resultString += c; + dest += (wchar_t)c; continue; } - if(c < 0xC0 || c >= 0xF0) - return false; - i++; - if (i >= utfString.Length()) - return false; - BYTE c2 = utfString[i]; - if (c2 < 0x80) + if(c < 0xC0) return false; - c2 -= 0x80; - if (c2 >= 0x40) - return false; - if (c < 0xE0) + int numAdds; + for (numAdds = 1; numAdds < 5; numAdds++) + if (c < kUtf8Limits[numAdds]) + break; + UInt32 value = (c - kUtf8Limits[numAdds - 1]); + do { - resultString += wchar_t( ((wchar_t(c - 0xC0)) << 6) + c2); - continue; + if (i >= src.Length()) + return false; + Byte c2 = (Byte)src[i++]; + if (c2 < 0x80 || c2 >= 0xC0) + return false; + value <<= 6; + value |= (c2 - 0x80); + numAdds--; + } + while(numAdds > 0); + if (value < 0x10000) + dest += (wchar_t)(value); + else + { + value -= 0x10000; + if (value >= 0x100000) + return false; + dest += (wchar_t)(0xD800 + (value >> 10)); + dest += (wchar_t)(0xDC00 + (value & 0x3FF)); } - i++; - if (i >= utfString.Length()) - return false; - BYTE c3 = utfString[i]; - c3 -= 0x80; - if (c3 >= 0x40) - return false; - resultString += wchar_t(((wchar_t(c - 0xE0)) << 12) + - ((wchar_t(c2)) << 6) + c3); } return true; } -void ConvertUnicodeToUTF8(const UString &unicodeString, AString &resultString) +bool ConvertUnicodeToUTF8(const UString &src, AString &dest) { - resultString.Empty(); - for(int i = 0; i < unicodeString.Length(); i++) + dest.Empty(); + for(int i = 0; i < src.Length();) { - wchar_t c = unicodeString[i]; - if (c < 0x80) + UInt32 value = (UInt32)src[i++]; + if (value < 0x80) { - resultString += char(c); + dest += (char)value; continue; } - if (c < 0x07FF) + if (value >= 0xD800 && value < 0xE000) { - resultString += char(0xC0 + (c >> 6)); - resultString += char(0x80 + (c & 0x003F)); - continue; + if (value >= 0xDC00) + return false; + if (i >= src.Length()) + return false; + UInt32 c2 = (UInt32)src[i++]; + if (c2 < 0xDC00 || c2 >= 0xE000) + return false; + value = ((value - 0xD800) << 10) | (c2 - 0xDC00); } - resultString += char(0xE0 + (c >> 12)); - resultString += char(0x80 + ((c >> 6) & 0x003F)); - resultString += char(0x80 + (c & 0x003F)); + int numAdds; + for (numAdds = 1; numAdds < 5; numAdds++) + if (value < (((UInt32)1) << (numAdds * 5 + 6))) + break; + dest += (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds))); + do + { + numAdds--; + dest += (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F)); + } + while(numAdds > 0); } + return true; } - diff --git a/Common/UTFConvert.h b/Common/UTFConvert.h index 0e558c88..47434111 100755 --- a/Common/UTFConvert.h +++ b/Common/UTFConvert.h @@ -1,13 +1,11 @@ // Common/UTFConvert.h -#pragma once - #ifndef __COMMON_UTFCONVERT_H #define __COMMON_UTFCONVERT_H #include "Common/String.h" bool ConvertUTF8ToUnicode(const AString &utfString, UString &resultString); -void ConvertUnicodeToUTF8(const UString &unicodeString, AString &resultString); +bool ConvertUnicodeToUTF8(const UString &unicodeString, AString &resultString); #endif diff --git a/Common/Vector.cpp b/Common/Vector.cpp index c8b1c1e9..cb3d8752 100755 --- a/Common/Vector.cpp +++ b/Common/Vector.cpp @@ -2,6 +2,8 @@ #include "StdAfx.h" +#include <string.h> + #include "Vector.h" CBaseRecordVector::~CBaseRecordVector() @@ -42,7 +44,7 @@ void CBaseRecordVector::Reserve(int newCapacity) unsigned char *p = new unsigned char[newCapacity * _itemSize]; int numRecordsToMove = _capacity; memmove(p, _items, _itemSize * numRecordsToMove); - delete []_items; + delete [](unsigned char *)_items; _items = p; _capacity = newCapacity; } diff --git a/Common/Vector.h b/Common/Vector.h index 051d4e46..858e53d3 100755 --- a/Common/Vector.h +++ b/Common/Vector.h @@ -1,7 +1,5 @@ // Common/Vector.h -#pragma once - #ifndef __COMMON_VECTOR_H #define __COMMON_VECTOR_H @@ -22,7 +20,7 @@ protected: { if (index + num > _size) num = _size - index; } public: CBaseRecordVector(size_t itemSize): - _size(0), _capacity(0), _items(0), _itemSize(itemSize) {} + _capacity(0), _size(0), _items(0), _itemSize(itemSize) {} virtual ~CBaseRecordVector(); int Size() const { return _size; } bool IsEmpty() const { return (_size == 0); } @@ -72,7 +70,11 @@ public: T& Front() { return operator[](0); } const T& Back() const { return operator[](_size - 1); } T& Back() { return operator[](_size - 1); } - static int __cdecl CompareRecordItems(const void *a1, const void *a2) + static int + #ifdef _MSC_VER + __cdecl + #endif + CompareRecordItems(const void *a1, const void *a2) { return MyCompare(*((const T *)a1), *((const T *)a2)); } void Sort() { qsort(&Front(), Size(), _itemSize, CompareRecordItems); } @@ -125,7 +127,7 @@ public: int Find(const T& item) const { for(int i = 0; i < Size(); i++) - if (item == (*this)[mid]) + if (item == (*this)[i]) return i; return -1; } @@ -165,7 +167,11 @@ public: Insert(right, item); return right; } - static int __cdecl CompareObjectItems(const void *a1, const void *a2) + static int + #ifdef _MSC_VER + __cdecl + #endif + CompareObjectItems(const void *a1, const void *a2) { return MyCompare(*(*((const T **)a1)), *(*((const T **)a2))); } void Sort() { diff --git a/Common/Wildcard.cpp b/Common/Wildcard.cpp index 78385db2..6f7efc71 100755 --- a/Common/Wildcard.cpp +++ b/Common/Wildcard.cpp @@ -2,7 +2,7 @@ #include "StdAfx.h" -#include "WildCard.h" +#include "Wildcard.h" static const wchar_t kPeriodChar = L'.'; static const wchar_t kAnyCharsChar = L'*'; @@ -11,12 +11,6 @@ static const wchar_t kAnyCharChar = L'?'; static const wchar_t kDirDelimiter1 = L'\\'; static const wchar_t kDirDelimiter2 = L'/'; -static const wchar_t kDiskNameDelimiterChar = ':'; - -static const UString kRootDirName = L""; - -static const wchar_t kSpaceChar = L' '; - static const UString kWildCardCharSet = L"?*"; static const UString kIllegalWildCardFileNameChars= @@ -50,8 +44,10 @@ static bool EnhancedMaskTest(const UString &mask, int maskPos, wchar_t maskChar = mask[maskPos]; if(maskChar == kAnyCharChar) { + /* if (EnhancedMaskTest(mask, maskPos + 1, name, namePos)) return true; + */ if (nameLen == 0) return false; return EnhancedMaskTest(mask, maskPos + 1, name, namePos + 1); @@ -68,7 +64,9 @@ static bool EnhancedMaskTest(const UString &mask, int maskPos, { wchar_t c = name[namePos]; if (maskChar != c) +#ifdef _WIN32 if (MyCharUpper(maskChar) != MyCharUpper(c)) +#endif return false; return EnhancedMaskTest(mask, maskPos + 1, name, namePos + 1); } @@ -98,50 +96,43 @@ void SplitPathToParts(const UString &path, UStringVector &pathParts) pathParts.Add(name); } -/* -void SplitPathToParts(const AString &path, AStringVector &pathParts) +void SplitPathToParts(const UString &path, UString &dirPrefix, UString &name) { - pathParts.Clear(); - AString name; - int len = path.Length(); - if (len == 0) - return; - for (int i = 0; i < len; i++) - { - wchar_t c = path[i]; - if (IsCharDirLimiter(c)) - { - pathParts.Add(name); - name.Empty(); - } - else - name += path[i]; - } - pathParts.Add(name); + int i; + for(i = path.Length() - 1; i >= 0; i--) + if(IsCharDirLimiter(path[i])) + break; + dirPrefix = path.Left(i + 1); + name = path.Mid(i + 1); } -*/ -// -------------------------------------------------- -// ExtractFileNameFromPath +UString ExtractDirPrefixFromPath(const UString &path) +{ + int i; + for(i = path.Length() - 1; i >= 0; i--) + if(IsCharDirLimiter(path[i])) + break; + return path.Left(i + 1); +} -UString ExtractFileNameFromPath(const UString &pathName) +UString ExtractFileNameFromPath(const UString &path) { - UString result; - int len = pathName.Length(); - for(int i = len - 1; i >= 0; i--) - if(IsCharDirLimiter(pathName[i])) - return pathName.Mid(i + 1); - return pathName; + int i; + for(i = path.Length() - 1; i >= 0; i--) + if(IsCharDirLimiter(path[i])) + break; + return path.Mid(i + 1); } + bool CompareWildCardWithName(const UString &mask, const UString &name) { return EnhancedMaskTest(mask, 0, name, 0); } -bool DoesNameContainWildCard(const UString &pathName) +bool DoesNameContainWildCard(const UString &path) { - return (pathName.FindOneOf(kWildCardCharSet) >= 0); + return (path.FindOneOf(kWildCardCharSet) >= 0); } @@ -155,182 +146,286 @@ static inline int BoolToIndex(bool value) return value ? 1: 0; } -const UStringVector& CCensorNode::GetNamesVector(bool allowed, bool recursed, bool wildCard) const -{ - return _names[BoolToIndex(allowed)][BoolToIndex(recursed)][BoolToIndex(wildCard)]; -} -void CCensorNode::AddItem(const UString &name, bool allowed, bool recursed, bool wildCard) -{ - _names[BoolToIndex(allowed)][BoolToIndex(recursed)][BoolToIndex(wildCard)].Add(name); -} +/* +M = MaskParts.Size(); +N = TestNameParts.Size(); -CCensorNode *CCensorNode::FindSubNode(const UString &name) -{ - for (int i = 0; i < SubNodes.Size(); i++) - if (name.CollateNoCase(SubNodes[i].Name) == 0) - return &SubNodes[i]; - return NULL; -} + File Dir +ForFile req M<=N [N-M, N) - + nonreq M=N [0, M) - + +ForDir req M<N [0, M) ... [N-M-1, N-1) same as ForBoth-File + nonreq [0, M) same as ForBoth-File + +ForBoth req m<=N [0, M) ... [N-M, N) same as ForBoth-File + nonreq [0, M) same as ForBoth-File -CCensorNode *CCensorNode::AddSubNode(const UString &name) +*/ + +bool CItem::CheckPath(const UStringVector &pathParts, bool isFile) const { - CCensorNode *subNode = FindSubNode(name); - if (subNode != NULL) - return subNode; - SubNodes.Add(CCensorNode(this, name)); - return &SubNodes.Back(); + if (!isFile && !ForDir) + return false; + int delta = (int)pathParts.Size() - (int)PathParts.Size(); + if (delta < 0) + return false; + int start = 0; + int finish = 0; + if (isFile) + { + if (!ForDir && !Recursive && delta !=0) + return false; + if (!ForFile && delta == 0) + return false; + if (!ForDir && Recursive) + start = delta; + } + if (Recursive) + { + finish = delta; + if (isFile && !ForFile) + finish = delta - 1; + } + for (int d = start; d <= finish; d++) + { + int i; + for (i = 0; i < PathParts.Size(); i++) + if (!CompareWildCardWithName(PathParts[i], pathParts[i + d])) + break; + if (i == PathParts.Size()) + return true; + } + return false; } -int FindString(const UStringVector &strings, const UString &string) +int CCensorNode::FindSubNode(const UString &name) const { - for (int i = 0; i < strings.Size(); i++) - if (string.CollateNoCase(strings[i]) == 0) + for (int i = 0; i < SubNodes.Size(); i++) + if (SubNodes[i].Name.CollateNoCase(name) == 0) return i; return -1; } -int FindInWildcardVector(const UStringVector &strings, const UString &string) +void CCensorNode::AddItem(CItem &item) { - for (int i = 0; i < strings.Size(); i++) - if (CompareWildCardWithName(strings[i], string)) - return i; - return -1; + if (item.PathParts.Size() <= 1) + { + Items.Add(item); + return; + } + const UString &front = item.PathParts.Front(); + if (DoesNameContainWildCard(front)) + { + Items.Add(item); + return; + } + int index = FindSubNode(front); + if (index < 0) + index = SubNodes.Add(CCensorNode(front, this)); + item.PathParts.Delete(0); + SubNodes[index].AddItem(item); } -bool CCensorNode::CheckName(const UString &name, bool allowed, bool recursed) const +void CCensorNode::AddItem(const UString &path, bool include, bool recursive, bool forFile, bool forDir) { - if (FindString(_names[BoolToIndex(allowed)][BoolToIndex(recursed)][0], name) >= 0) - return true; - if (FindInWildcardVector(_names[BoolToIndex(allowed)][BoolToIndex(recursed)][1], name) >= 0) - return true; - return false; + CItem item; + SplitPathToParts(path, item.PathParts); + item.Include = include; + item.Recursive = recursive; + item.ForFile = forFile; + item.ForDir = forDir; + AddItem(item); } -bool CCensorNode::CheckNameRecursive(const UString &name, bool allowed) const +bool CCensorNode::NeedCheckSubDirs() const { - const CCensorNode *curItem = this; - while (curItem != NULL) + for (int i = 0; i < Items.Size(); i++) { - if (curItem->CheckName(name, allowed, true)) + const CItem &item = Items[i]; + if (!item.Include) + continue; + if (item.Recursive || item.PathParts.Size() > 1) return true; - curItem = curItem->_parent; } return false; } -bool CCensorNode::CheckNameRecursive(const UString &name) const +bool CCensorNode::CheckPathCurrent(const UStringVector &pathParts, bool isFile, bool &include) const { - if (!CheckNameRecursive(name, true)) - return false; - return !CheckNameRecursive(name, false); + bool finded = false; + for (int i = 0; i < Items.Size(); i++) + { + const CItem &item = Items[i]; + if (item.CheckPath(pathParts, isFile)) + { + finded = true; + include = item.Include; + if (!include) + return true; + } + } + return finded; } -bool CCensorNode::CheckNameFull(const UString &name, bool allowed) const +bool CCensorNode::CheckPath(UStringVector &pathParts, bool isFile, bool &include) const { - if (CheckName(name, allowed, false)) + bool finded = CheckPathCurrent(pathParts, isFile, include); + if (finded && !include) return true; - return CheckNameRecursive(name, allowed); + if (pathParts.Size() == 1) + return finded; + int index = FindSubNode(pathParts.Front()); + if (index >= 0) + { + UStringVector pathParts2 = pathParts; + pathParts2.Delete(0); + if (SubNodes[index].CheckPath(pathParts2, isFile, include)) + finded = true; + } + return finded; } -bool CCensorNode::CheckNameFull(const UString &name) const +bool CCensorNode::CheckPath(const UString &path, bool isFile, bool &include) const { - if (!CheckNameFull(name, true)) - return false; - return !CheckNameFull(name, false); + UStringVector pathParts; + SplitPathToParts(path, pathParts); + return CheckPath(pathParts, isFile, include); } -//////////////////////////////////// -// CCensor - -void CCensor::AddItem(const UString &path, bool allowed, bool recursed, bool wildCard) +bool CCensorNode::CheckPath(const UString &path, bool isFile) const { - UStringVector pathParts; - SplitPathToParts(path, pathParts); - int numParts = pathParts.Size(); - if (numParts == 0) - throw "Empty path"; - CCensorNode *curItem = &_head; - int i; - for(i = 0; i < numParts - 1; i++) - curItem = curItem->AddSubNode(pathParts[i]); - curItem->AddItem(pathParts[i], allowed, recursed, wildCard); + bool include; + if(CheckPath(path, isFile, include)) + return include; + return false; } - -bool CCensor::CheckName(const UString &path) const +bool CCensorNode::CheckPathToRoot(UStringVector &pathParts, bool isFile, bool &include) const { - UStringVector pathParts; - SplitPathToParts(path, pathParts); - int numParts = pathParts.Size(); - if (numParts == 0) - throw "Empty path"; - const CCensorNode *curItem = &_head; - const UString &name = pathParts[numParts - 1]; - for(int i = 0; i < numParts - 1; i++) - { - const CCensorNode *nextItem = ((CCensorNode *)curItem)->FindSubNode(pathParts[i]); - if (nextItem == NULL) - return curItem->CheckNameRecursive(name); - curItem = nextItem; - } - return curItem->CheckNameFull(name); + bool finded = CheckPathCurrent(pathParts, isFile, include); + if (finded && !include) + return true; + if (Parent == 0) + return finded; + pathParts.Insert(0, Name); + if (Parent->CheckPathToRoot(pathParts, isFile, include)) + finded = true; + return finded; } +bool CCensorNode::CheckPathToRoot(UStringVector &pathParts, bool isFile) const +{ + bool include; + if(CheckPathToRoot(pathParts, isFile, include)) + return include; + return false; } -//////////////////////////////////// -// Filename and WildCard function - -static bool TestStringLengthAndBounds(const UString &string) +bool CCensorNode::CheckPathToRoot(const UString &path, bool isFile) const { - if (string.Length() <= 0) - return false; - return (string.ReverseFind(kSpaceChar) != string.Length() - 1); + UStringVector pathParts; + SplitPathToParts(path, pathParts); + return CheckPathToRoot(pathParts, isFile); } -bool IsFileNameLegal(const UString &name) + + +void CCensorNode::AddItem2(const UString &path, bool include, bool recursive) { - if (!TestStringLengthAndBounds(name)) - return false; - return (name.FindOneOf(kIllegalFileNameChars) < 0); + if (path.IsEmpty()) + return; + bool forFile = true; + bool forFolder = true; + UString path2 = path; + if (IsCharDirLimiter(path[path.Length() - 1])) + { + path2.Delete(path.Length() - 1); + forFile = false; + } + AddItem(path2, include, recursive, forFile, forFolder); } -bool IsWildCardFileNameLegal(const UString &name) +int CCensor::FindPrefix(const UString &prefix) const { - if (!TestStringLengthAndBounds(name)) - return false; - return (name.FindOneOf(kIllegalWildCardFileNameChars) < 0); + for (int i = 0; i < Pairs.Size(); i++) + if (Pairs[i].Prefix.CollateNoCase(prefix) == 0) + return i; + return -1; } -bool IsFilePathLegal(const UString &path) +void CCensor::AddItem(const UString &path, bool include, bool recursive) { - UStringVector pathParts; + UStringVector pathParts; SplitPathToParts(path, pathParts); - int count = pathParts.Size(); - if (count == 0) - return false; - for(int i = 0; i < count; i++) - if (!IsFileNameLegal(pathParts[i])) - return false; - return true; + bool forFile = true; + if (pathParts.Back().IsEmpty()) + { + forFile = false; + pathParts.DeleteBack(); + } + const UString &front = pathParts.Front(); + bool isAbs = false; + if (front.IsEmpty()) + isAbs = true; + else if (front.Length() == 2 && front[1] == L':') + isAbs = true; + else + { + for (int i = 0; i < pathParts.Size(); i++) + { + const UString &part = pathParts[i]; + if (part == L".." || part == L".") + { + isAbs = true; + break; + } + } + } + int numAbsParts = 0; + if (isAbs) + if (pathParts.Size() > 1) + numAbsParts = pathParts.Size() - 1; + else + numAbsParts = 1; + UString prefix; + for (int i = 0; i < numAbsParts; i++) + { + const UString &front = pathParts.Front(); + if (DoesNameContainWildCard(front)) + break; + prefix += front; + prefix += L'\\'; + pathParts.Delete(0); + } + int index = FindPrefix(prefix); + if (index < 0) + index = Pairs.Add(CPair(prefix)); + + CItem item; + item.PathParts = pathParts; + item.ForDir = true; + item.ForFile = forFile; + item.Include = include; + item.Recursive = recursive; + Pairs[index].Head.AddItem(item); } -bool IsWildCardFilePathLegal(const UString &path) +bool CCensor::CheckPath(const UString &path, bool isFile) const { - UStringVector pathParts; - SplitPathToParts(path, pathParts); - int count = pathParts.Size(); - if (count == 0) - return false; - for(int i = 0; i < count - 1; i++) - if (!IsFileNameLegal(pathParts[i])) - return false; - return IsWildCardFileNameLegal(pathParts[count - 1]); + bool finded = false; + for (int i = 0; i < Pairs.Size(); i++) + { + bool include; + if (Pairs[i].Head.CheckPath(path, isFile, include)) + { + if (!include) + return false; + finded = true; + } + } + return finded; } -static bool IsCharAPrefixDelimiter(wchar_t c) -{ - return (IsCharDirLimiter(c) || c == kDiskNameDelimiterChar); } bool AreTheFileNamesDirDelimiterEqual(const UString &name1, const UString &name2) @@ -348,4 +443,3 @@ bool AreTheFileNamesDirDelimiterEqual(const UString &name1, const UString &name2 } return true; } - diff --git a/Common/Wildcard.h b/Common/Wildcard.h index 8bed3ead..59c0a0e8 100755 --- a/Common/Wildcard.h +++ b/Common/Wildcard.h @@ -1,55 +1,75 @@ // Common/Wildcard.h -#pragma once - #ifndef __COMMON_WILDCARD_H #define __COMMON_WILDCARD_H #include "Common/String.h" -void SplitPathToParts(const UString &path, UStringVector &aPathParts); -// void SplitPathToParts(const AString &path, AStringVector &aPathParts); -UString ExtractFileNameFromPath(const UString &pathName); -bool DoesNameContainWildCard(const UString &pathName); +void SplitPathToParts(const UString &path, UStringVector &pathParts); +void SplitPathToParts(const UString &path, UString &dirPrefix, UString &name); +UString ExtractDirPrefixFromPath(const UString &path); +UString ExtractFileNameFromPath(const UString &path); +bool DoesNameContainWildCard(const UString &path); bool CompareWildCardWithName(const UString &mask, const UString &name); namespace NWildcard { +struct CItem +{ + UStringVector PathParts; + bool Include; + bool Recursive; + bool ForFile; + bool ForDir; + bool CheckPath(const UStringVector &pathParts, bool isFile) const; +}; + class CCensorNode { - CCensorNode *_parent; - UStringVector _names[2][2][2]; - bool CheckNameRecursive(const UString &name, bool allowed) const; - bool CheckNameFull(const UString &name, bool allowed) const; -public: UString Name; + CCensorNode *Parent; + bool CheckPathCurrent(const UStringVector &pathParts, bool isFile, bool &include) const; +public: + CCensorNode(): Parent(0) { }; + CCensorNode(const UString &name, CCensorNode *parent): + Name(name), Parent(parent) { }; CObjectVector<CCensorNode> SubNodes; - CCensorNode(CCensorNode *parent, const UString &name): - _parent(parent), Name(name) {}; - CCensorNode *FindSubNode(const UString &name); - CCensorNode *AddSubNode(const UString &name); - void AddItem(const UString &name, bool allowed, bool recursed, bool wildCard); - bool CheckName(const UString &name, bool allowed, bool recursed) const; - bool CheckNameRecursive(const UString &name) const; - bool CheckNameFull(const UString &name) const; - - const UStringVector&GetNamesVector(bool allowed, bool recursed, bool wildCard) const; - const UStringVector&GetAllowedNamesVector(bool recursed, bool wildCard) const - { return GetNamesVector(true, recursed, wildCard); } - const UStringVector&GetRecursedNamesVector(bool allowed, bool wildCard) const - { return GetNamesVector(allowed, true, wildCard); } - const UStringVector&GetAllowedRecursedNamesVector(bool wildCard) const - { return GetRecursedNamesVector(true, wildCard); } + CObjectVector<CItem> Items; + + int FindSubNode(const UString &path) const; + void AddItem(CItem &item); + void AddItem(const UString &path, bool include, bool recursive, bool forFile, bool forDir); + void AddItem2(const UString &path, bool include, bool recursive); + + bool NeedCheckSubDirs() const; + + bool CheckPath(UStringVector &pathParts, bool isFile, bool &include) const; + bool CheckPath(const UString &path, bool isFile, bool &include) const; + bool CheckPath(const UString &path, bool isFile) const; + + bool CheckPathToRoot(UStringVector &pathParts, bool isFile, bool &include) const; + bool CheckPathToRoot(UStringVector &pathParts, bool isFile) const; + bool CheckPathToRoot(const UString &path, bool isFile) const; + +}; + +struct CPair +{ + UString Prefix; + CCensorNode Head; + CPair(const UString &prefix): Prefix(prefix) { }; }; class CCensor { + int FindPrefix(const UString &prefix) const; public: - CCensorNode _head; - CCensor(): _head(NULL, L"") {} - void AddItem(const UString &path, bool allowed, bool recursed, bool wildCard); - bool CheckName(const UString &path) const; + CObjectVector<CPair> Pairs; + bool AllAreRelative() const + { return (Pairs.Size() == 1 && Pairs.Front().Prefix.IsEmpty()); } + void AddItem(const UString &path, bool include, bool recursive); + bool CheckPath(const UString &path, bool isFile) const; }; } diff --git a/Common/WindowsTypes.h b/Common/WindowsTypes.h deleted file mode 100755 index 510eb148..00000000 --- a/Common/WindowsTypes.h +++ /dev/null @@ -1,75 +0,0 @@ -// Common/WindowsTypes.h - -// #pragma once - -#ifndef __COMMON_WindowsTypes_H -#define __COMMON_WindowsTypes_H - - // typedef unsigned long UINT32; - typedef unsigned __int64 UINT64; - typedef UINT32 UINT; - typedef UINT32 DWORD; - #define CP_ACP 0 - #define CP_OEMCP 1 - #define CP_UTF8 65001 - typedef const char *LPCTSTR; - typedef const wchar_t *LPCWSTR; - #define TEXT - typedef struct { - unsigned long Data1; - unsigned short Data2; - unsigned short Data3; - unsigned char Data4[ 8 ]; - } GUID; - typedef GUID CLSID; - typedef char TCHAR; - typedef char CHAR; - typedef unsigned char UCHAR; - typedef short SHORT; - typedef unsigned short USHORT; - typedef int INT; - typedef UINT UINT_PTR; - typedef long BOOL; - typedef long LONG; - typedef unsigned long ULONG; - #define FALSE 0 - #define TRUE 1 - typedef short VARIANT_BOOL; - #define VARIANT_TRUE ((VARIANT_BOOL)-1) - #define VARIANT_FALSE ((VARIANT_BOOL)0) - - #define FILE_ATTRIBUTE_READONLY 0x00000001 - #define FILE_ATTRIBUTE_HIDDEN 0x00000002 - #define FILE_ATTRIBUTE_SYSTEM 0x00000004 - #define FILE_ATTRIBUTE_DIRECTORY 0x00000010 - #define FILE_ATTRIBUTE_ARCHIVE 0x00000020 - #define FILE_ATTRIBUTE_DEVICE 0x00000040 - #define FILE_ATTRIBUTE_NORMAL 0x00000080 - #define FILE_ATTRIBUTE_TEMPORARY 0x00000100 - #define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200 - #define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400 - #define FILE_ATTRIBUTE_COMPRESSED 0x00000800 - #define FILE_ATTRIBUTE_OFFLINE 0x00001000 - #define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000 - #define FILE_ATTRIBUTE_ENCRYPTED 0x00004000 - typedef struct _FILETIME { - DWORD dwLowDateTime; - DWORD dwHighDateTime; - } FILETIME, *PFILETIME, *LPFILETIME; - typedef void *HANDLE; - - typedef __int64 LONGLONG; - typedef unsigned __int64 ULONGLONG; - - struct LARGE_INTEGER { LONGLONG QuadPart; }; - struct ULARGE_INTEGER { ULONGLONG QuadPart; }; - typedef float FLOAT; - typedef double DOUBLE; - typedef VARIANT_BOOL _VARIANT_BOOL; - typedef LONG SCODE; - struct CY { LONGLONG int64; }; - typedef double DATE; - typedef wchar_t *BSTR; - -#endif - diff --git a/DOC/7zC.txt b/DOC/7zC.txt new file mode 100755 index 00000000..e2585f16 --- /dev/null +++ b/DOC/7zC.txt @@ -0,0 +1,238 @@ +7z ANSI-C Decoder 4.16 +---------------------- + +7z ANSI-C Decoder 4.16 Copyright (C) 1999-2005 Igor Pavlov + +7z ANSI-C provides 7z/LZMA decoding. +7z ANSI-C version is simplified version ported from C++ code. + +LZMA is default and general compression method of 7z format +in 7-Zip compression program (www.7-zip.org). LZMA provides high +compression ratio and very fast decompression. + + +LICENSE +------- + +Read lzma.txt for informaton about license. + + +Files +--------------------- + +7zAlloc.* - Allocate and Free +7zBuffer.* - Buffer structure +7zCrc.* - CRC32 code +7zDecode.* - Low level memory->memory decoding +7zExtract.* - High level stream->memory decoding +7zHeader.* - .7z format constants +7zIn.* - .7z archive opening +7zItem.* - .7z structures +7zMain.c - Test application +7zMethodID.* - MethodID structure +7zTypes.h - Base types and constants + + +How To Use +---------- + +You must download 7-Zip program from www.7-zip.org. + +You can create .7z archive with 7z.exe or 7za.exe: + + 7za.exe a archive.7z *.htm -r -mx -m0fb=255 + +If you have big number of files in archive, and you need fast extracting, +you can use partly-solid archives: + + 7za.exe a archive.7z *.htm -ms=512K -r -mx -m0fb=255 -m0d=512K + +In that example 7-Zip will use 512KB solid blocks. So it needs to decompress only +512KB for extracting one file from such archive. + + +Limitations of current version of 7z ANSI-C Decoder +--------------------------------------------------- + + - It doesn't support separated "folder" items inside archive. + But you still can use files that are in subfolders + - It doesn't support empty files (size = 0) inside archive. + - It reads only "FileName", "Size", and "CRC" information for each file in archive. + - It supports only LZMA and Copy (no compression) methods. + - It converts original UTF-16 Unicode file names to UTF-8 Unicode file names. + +These limitations will be fixed in future versions. + + +Using 7z ANSI-C Decoder Test application: +----------------------------------------- + +Usage: 7zDec <command> <archive_name> + +<Command>: + e: Extract files from archive + l: List contents of archive + t: Test integrity of archive + +Example: + + 7zDec l archive.7z + +lists contents of archive.7z + + 7zDec e archive.7z + +extracts files from archive.7z to current folder. + + +How to use .7z Decoder +---------------------- + +.7z Decoder can be compiled in one of two modes: + +1) Default mode. In that mode 7z Decoder will read full compressed + block to RAM before decompressing. + +2) Mode with defined _LZMA_IN_CB. In that mode 7z Decoder can read + compressed block by parts. And you can specify desired buffer size. + So memory requirements can be reduced. But decompressing speed will + be 5-10% lower and code size is slightly larger. + + +Memory allocation +~~~~~~~~~~~~~~~~~ + +7z Decoder uses two memory pools: +1) Temporary pool +2) Main pool +Such scheme can allow you to avoid fragmentation of alocated blocks. + +Steps for using 7z decoder +-------------------------- + +Use code at 7zMain.c as example. + +1) Declare variables: + inStream /* implements ISzInStream interface */ + CArchiveDatabaseEx db; /* 7z archive database structure */ + ISzAlloc allocImp; /* memory functions for main pool */ + ISzAlloc allocTempImp; /* memory functions for temporary pool */ + +2) call InitCrcTable(); function to initialize CRC structures. + +3) call SzArDbExInit(&db); function to initialize db structures. + +4) call SzArchiveOpen(inStream, &db, &allocMain, &allocTemp) to open archive + +This function opens archive "inStream" and reads headers to "db". +All items in "db" will be allocated with "allocMain" functions. +SzArchiveOpen function allocates and frees temporary structures by "allocTemp" functions. + +5) List items or Extract items + + Listing code: + ~~~~~~~~~~~~~ + { + UInt32 i; + for (i = 0; i < db.Database.NumFiles; i++) + { + CFileItem *f = db.Database.Files + i; + printf("%10d %s\n", (int)f->Size, f->Name); + } + } + + Extracting code: + ~~~~~~~~~~~~~~~~ + + SZ_RESULT SzExtract( + ISzInStream *inStream, + CArchiveDatabaseEx *db, + UInt32 fileIndex, /* index of file */ + UInt32 *blockIndex, /* index of solid block */ + Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */ + size_t *outBufferSize, /* buffer size for output buffer */ + size_t *offset, /* offset of stream for required file in *outBuffer */ + size_t *outSizeProcessed, /* size of file in *outBuffer */ + ISzAlloc *allocMain, + ISzAlloc *allocTemp); + + If you need to decompress more than one file, you can send these values from preevious call: + blockIndex, + outBuffer, + outBufferSize, + You can consider "outBuffer" as cache of solid block. If your archive is solid, + it will increase decompression speed. + + After decompressing you must free "outBuffer": + allocImp.Free(outBuffer); + +6) call SzArDbExFree(&db, allocImp.Free) to free allocated items in "db". + + + + +Memory requirements for .7z decoding +------------------------------------ + +Memory usage for Archive openning: + - Temporary pool: + - Memory for compressed .7z headers (if _LZMA_IN_CB is not defined) + - Memory for uncompressed .7z headers + - some other temporary blocks + - Main pool: + - Memory for database: + Estimated size of one file structures in solid archive: + - Size (4 or 8 Bytes) + - CRC32 (4 bytes) + - Some file information (4 bytes) + - File Name (variable length) + pointer + allocation structures + +Memory usage for archive Decompressing: + - Temporary pool: + - Memory for compressed solid block (if _LZMA_IN_CB is not defined) + - Memory for LZMA decompressing structures + - Main pool: + - Memory for decompressed solid block + + +If _LZMA_IN_CB is defined, 7z Decoder will not allocate memory for +compressed blocks. Instead of this, you must allocate buffer with desired +size before calling 7z Decoder. Use 7zMain.c as example. + + + +EXIT codes +----------- + +7z Decoder functions can return one of the following codes: + +#define SZ_OK (0) +#define SZE_DATA_ERROR (1) +#define SZE_OUTOFMEMORY (2) +#define SZE_CRC_ERROR (3) + +#define SZE_NOTIMPL (4) +#define SZE_FAIL (5) + +#define SZE_ARCHIVE_ERROR (6) + + + +LZMA Defines +------------ + +_LZMA_IN_CB - Use special callback mode for input stream to reduce memory requirements + +_SZ_FILE_SIZE_64 - define it if you need support for files larger than 4 GB +_SZ_NO_INT_64 - define it if your compiler doesn't support long long int + +_LZMA_PROB32 - it can increase LZMA decompressing speed on some 32-bit CPUs. + +_SZ_ONE_DIRECTORY - define it if you want to locate all source files to one direcory +_SZ_ALLOC_DEBUG - define it if you want to debug alloc/free operations to stderr. + + +--- + +http://www.7-zip.org +http://www.7-zip.org/support.html diff --git a/DOC/7zip.nsi b/DOC/7zip.nsi new file mode 100755 index 00000000..5426635b --- /dev/null +++ b/DOC/7zip.nsi @@ -0,0 +1,449 @@ +;-------------------------------- +;Defines + +!define VERSION_MAJOR 4 +!define VERSION_MINOR 20 +!define VERSION_POSTFIX_FULL "" +!define NAME_FULL "7-Zip ${VERSION_MAJOR}.${VERSION_MINOR}${VERSION_POSTFIX_FULL}" +!define VERSION_POSTFIX "" + +!define FM_LINK "7-Zip File Manager.lnk" +!define HELP_LINK "7-Zip Help.lnk" + +!define CLSID_CONTEXT_MENU {23170F69-40C1-278A-1000-000100020000} + +#!define NO_COMPRESSION + + !include "Library.nsh" + !include "MUI.nsh" + +;-------------------------------- +;Configuration + + ;General + Name "${NAME_FULL}" + BrandingText "www.7-zip.org" + OutFile "..\7z${VERSION_MAJOR}${VERSION_MINOR}${VERSION_POSTFIX}.exe" + + ;Folder selection page + InstallDir "$PROGRAMFILES\7-Zip" + + ;Get install folder from registry if available + InstallDirRegKey HKLM "Software\7-Zip" "Path" + + ;Compressor +!ifndef NO_COMPRESSION + SetCompressor lzma + SetCompressorDictSize 4 +!else + SetCompressor zlib + SetCompress off +!endif + +;-------------------------------- +;Interface Settings + + !define MUI_ABORTWARNING + +;-------------------------------- +;Pages + + #!insertmacro MUI_PAGE_LICENSE "License.txt" + !insertmacro MUI_PAGE_DIRECTORY + !insertmacro MUI_PAGE_INSTFILES + !insertmacro MUI_PAGE_FINISH + + !insertmacro MUI_UNPAGE_CONFIRM + !insertmacro MUI_UNPAGE_INSTFILES + !insertmacro MUI_UNPAGE_FINISH + +;-------------------------------- +;Languages + + !insertmacro MUI_LANGUAGE "English" + +;-------------------------------- +;Reserve Files + + ;These files should be inserted before other files in the data block + ;Keep these lines before any File command + ;Only for solid compression (by default, solid compression is enabled for BZIP2 and LZMA) + + !insertmacro MUI_RESERVEFILE_LANGDLL + +;-------------------------------- +;Installer Sections + +Section + + # delete old unwanted files + Delete $INSTDIR\7zn.exe + Delete $INSTDIR\7zan.exe + Delete $INSTDIR\7zipDoc.txt + Delete $INSTDIR\Codecs\Implode.dll + + # install files + SetOutPath "$INSTDIR" + + File file_id.diz + File descript.ion + File History.txt + File License.txt + File copying.txt + File readme.txt + File 7zip_pad.xml + + # File 7-zip.dll + # File 7-zipn.dll + File 7zFM.exe + File 7zFMn.exe + File 7z.exe + File 7za.exe + File 7zg.exe + File 7zgn.exe + + File 7z.sfx + File 7zCon.sfx + File 7zC.sfx + + File 7-zip.chm + + SetOutPath $INSTDIR\Formats + + File 7z.dll + File arj.dll + File bz2.dll + File cab.dll + File cpio.dll + File deb.dll + File gz.dll + File rar.dll + File rpm.dll + File split.dll + File tar.dll + File z.dll + File zip.dll + + SetOutPath $INSTDIR\Codecs + + File LZMA.dll + File Rar29.dll + File Deflate.dll + File Branch.dll + File Swap.dll + File Copy.dll + File PPMD.dll + File BZip2.dll + File AES.dll + File 7zAES.dll + + SetOutPath $INSTDIR\Lang + + File en.ttt + File af.txt + File ar.txt + File ast.txt + File az.txt + File be.txt + File bg.txt + File br.txt + File ca.txt + File cs.txt + File da.txt + File de.txt + File el.txt + File eo.txt + File es.txt + File et.txt + File fa.txt + File fi.txt + File fr.txt + File fur.txt + File fy.txt + File gl.txt + File he.txt + File hr.txt + File hu.txt + File id.txt + File it.txt + File ja.txt + File ka.txt + File ko.txt + File lt.txt + File lv.txt + File mk.txt + File mn.txt + File nl.txt + File no.txt + File pl.txt + File pt.txt + File pt-br.txt + File ro.txt + File ru.txt + File sk.txt + File sl.txt + File sr.txt + File sv.txt + File ta.txt + File th.txt + File tr.txt + File uk.txt + File uz.txt + File va.txt + File vi.txt + File vr.txt + File zh-cn.txt + File zh-tw.txt + + SetOutPath $INSTDIR + + # delete "current user" menu items + + Delete "$SMPROGRAMS\7-Zip\${FM_LINK}" + Delete "$SMPROGRAMS\7-Zip\${HELP_LINK}" + RMDir "$SMPROGRAMS\7-Zip" + + # set "all users" mode + + SetShellVarContext all + + StrCpy $0 0 + System::Call "kernel32::GetVersion() i .r0" + IntCmpU $0 0x80000000 0 regNT 0 + !insertmacro InstallLib REGDLL NOTSHARED REBOOT_NOTPROTECTED 7-zip.dll $INSTDIR\7-zip.dll $INSTDIR + File 7-Zipn.dll + Goto doneReg + regNT: + !insertmacro InstallLib REGDLL NOTSHARED REBOOT_NOTPROTECTED 7-zipn.dll $INSTDIR\7-zipn.dll $INSTDIR + File 7-Zip.dll + doneReg: + + ClearErrors + + # create start menu icons + SetOutPath $INSTDIR # working directory + CreateDirectory $SMPROGRAMS\7-Zip + StrCpy $1 "n" + IntCmpU $0 0x80000000 0 +2 0 + StrCpy $1 "" + CreateShortcut "$SMPROGRAMS\7-Zip\${FM_LINK}" $INSTDIR\7zFM$1.exe + CreateShortcut "$SMPROGRAMS\7-Zip\${HELP_LINK}" $INSTDIR\7-zip.chm + + IfErrors 0 noScErrors + + SetShellVarContext current + + CreateDirectory $SMPROGRAMS\7-Zip + CreateShortcut "$SMPROGRAMS\7-Zip\${FM_LINK}" $INSTDIR\7zFM$1.exe + CreateShortcut "$SMPROGRAMS\7-Zip\${HELP_LINK}" $INSTDIR\7-zip.chm + + noScErrors: + + # store install folder + WriteRegStr HKLM "Software\7-Zip" "Path" $INSTDIR + WriteRegStr HKCU "Software\7-Zip" "Path" $INSTDIR + + # write reg entries + WriteRegStr HKCR "*\shellex\ContextMenuHandlers\7-Zip" "" "${CLSID_CONTEXT_MENU}" + WriteRegStr HKCR "Directory\shellex\ContextMenuHandlers\7-Zip" "" "${CLSID_CONTEXT_MENU}" + WriteRegStr HKCR "Folder\shellex\ContextMenuHandlers\7-Zip" "" "${CLSID_CONTEXT_MENU}" + + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\App Paths\7zFM.exe" "" "$INSTDIR\7zFM.exe" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\App Paths\7zFM.exe" "Path" "$INSTDIR" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\App Paths\7zFMn.exe" "" "$INSTDIR\7zFMn.exe" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\App Paths\7zFMn.exe" "Path" "$INSTDIR" + + # create uninstaller + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\7-Zip" "DisplayName" "${NAME_FULL}" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\7-Zip" "UninstallString" '"$INSTDIR\Uninstall.exe"' + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\7-Zip" "NoModify" 1 + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\7-Zip" "NoRepair" 1 + WriteUninstaller $INSTDIR\Uninstall.exe + +SectionEnd + + +;-------------------------------- +;Installer Functions + +/* +Function .onInit + + !insertmacro MUI_LANGDLL_DISPLAY + +FunctionEnd +*/ + +;-------------------------------- +;Uninstaller Section + +Section "Uninstall" + + # delete files + + Delete $INSTDIR\file_id.diz + Delete $INSTDIR\descript.ion + Delete $INSTDIR\History.txt + Delete $INSTDIR\License.txt + Delete $INSTDIR\copying.txt + Delete $INSTDIR\readme.txt + Delete $INSTDIR\7zip_pad.xml + + Delete /REBOOTOK $INSTDIR\7-zip.dll + Delete /REBOOTOK $INSTDIR\7-zipn.dll + Delete $INSTDIR\7zFM.exe + Delete $INSTDIR\7zFMn.exe + Delete $INSTDIR\7z.exe + Delete $INSTDIR\7za.exe + Delete $INSTDIR\7zg.exe + Delete $INSTDIR\7zgn.exe + + Delete $INSTDIR\7z.sfx + Delete $INSTDIR\7zCon.sfx + Delete $INSTDIR\7zC.sfx + + Delete $INSTDIR\7-zip.chm + + Delete $INSTDIR\Formats\7z.dll + Delete $INSTDIR\Formats\arj.dll + Delete $INSTDIR\Formats\bz2.dll + Delete $INSTDIR\Formats\cab.dll + Delete $INSTDIR\Formats\cpio.dll + Delete $INSTDIR\Formats\deb.dll + Delete $INSTDIR\Formats\gz.dll + Delete $INSTDIR\Formats\rar.dll + Delete $INSTDIR\Formats\rpm.dll + Delete $INSTDIR\Formats\split.dll + Delete $INSTDIR\Formats\tar.dll + Delete $INSTDIR\Formats\z.dll + Delete $INSTDIR\Formats\zip.dll + + RMDir $INSTDIR\Formats + + Delete $INSTDIR\Codecs\LZMA.dll + Delete $INSTDIR\Codecs\Rar29.dll + Delete $INSTDIR\Codecs\Deflate.dll + Delete $INSTDIR\Codecs\Branch.dll + Delete $INSTDIR\Codecs\Swap.dll + Delete $INSTDIR\Codecs\Copy.dll + Delete $INSTDIR\Codecs\PPMD.dll + Delete $INSTDIR\Codecs\BZip2.dll + Delete $INSTDIR\Codecs\AES.dll + Delete $INSTDIR\Codecs\7zAES.dll + + RMDir $INSTDIR\Codecs + + Delete $INSTDIR\Lang\en.ttt + Delete $INSTDIR\Lang\af.txt + Delete $INSTDIR\Lang\ar.txt + Delete $INSTDIR\Lang\ast.txt + Delete $INSTDIR\Lang\az.txt + Delete $INSTDIR\Lang\be.txt + Delete $INSTDIR\Lang\bg.txt + Delete $INSTDIR\Lang\br.txt + Delete $INSTDIR\Lang\ca.txt + Delete $INSTDIR\Lang\cs.txt + Delete $INSTDIR\Lang\da.txt + Delete $INSTDIR\Lang\de.txt + Delete $INSTDIR\Lang\el.txt + Delete $INSTDIR\Lang\eo.txt + Delete $INSTDIR\Lang\es.txt + Delete $INSTDIR\Lang\et.txt + Delete $INSTDIR\Lang\fa.txt + Delete $INSTDIR\Lang\fi.txt + Delete $INSTDIR\Lang\fr.txt + Delete $INSTDIR\Lang\fur.txt + Delete $INSTDIR\Lang\fy.txt + Delete $INSTDIR\Lang\gl.txt + Delete $INSTDIR\Lang\he.txt + Delete $INSTDIR\Lang\hr.txt + Delete $INSTDIR\Lang\hu.txt + Delete $INSTDIR\Lang\id.txt + Delete $INSTDIR\Lang\it.txt + Delete $INSTDIR\Lang\ja.txt + Delete $INSTDIR\Lang\ka.txt + Delete $INSTDIR\Lang\ko.txt + Delete $INSTDIR\Lang\lt.txt + Delete $INSTDIR\Lang\lv.txt + Delete $INSTDIR\Lang\mk.txt + Delete $INSTDIR\Lang\mn.txt + Delete $INSTDIR\Lang\nl.txt + Delete $INSTDIR\Lang\no.txt + Delete $INSTDIR\Lang\pl.txt + Delete $INSTDIR\Lang\pt.txt + Delete $INSTDIR\Lang\pt-br.txt + Delete $INSTDIR\Lang\ro.txt + Delete $INSTDIR\Lang\ru.txt + Delete $INSTDIR\Lang\sk.txt + Delete $INSTDIR\Lang\sl.txt + Delete $INSTDIR\Lang\sr.txt + Delete $INSTDIR\Lang\sv.txt + Delete $INSTDIR\Lang\ta.txt + Delete $INSTDIR\Lang\th.txt + Delete $INSTDIR\Lang\tr.txt + Delete $INSTDIR\Lang\uk.txt + Delete $INSTDIR\Lang\uz.txt + Delete $INSTDIR\Lang\va.txt + Delete $INSTDIR\Lang\vi.txt + Delete $INSTDIR\Lang\vr.txt + Delete $INSTDIR\Lang\zh-cn.txt + Delete $INSTDIR\Lang\zh-tw.txt + + RMDir $INSTDIR\Lang + + Delete $INSTDIR\Uninstall.exe + + RMDir $INSTDIR + + # delete start menu entires + + SetShellVarContext all + + # ClearErrors + + Delete "$SMPROGRAMS\7-Zip\${FM_LINK}" + Delete "$SMPROGRAMS\7-Zip\${HELP_LINK}" + RMDir "$SMPROGRAMS\7-Zip" + + # IfErrors 0 noScErrors + + SetShellVarContext current + + Delete "$SMPROGRAMS\7-Zip\${FM_LINK}" + Delete "$SMPROGRAMS\7-Zip\${HELP_LINK}" + RMDir "$SMPROGRAMS\7-Zip" + + # noScErrors: + + + # delete registry entries + + DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\7-Zip" + DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\App Paths\7zFM.exe" + DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\App Paths\7zFMn.exe" + + DeleteRegKey HKLM "Software\7-Zip" + DeleteRegKey HKCU "Software\7-Zip" + + DeleteRegKey HKCR "CLSID\${CLSID_CONTEXT_MENU}" + + DeleteRegKey HKCR "*\shellex\ContextMenuHandlers\7-Zip" + DeleteRegKey HKCR "Directory\shellex\ContextMenuHandlers\7-Zip" + DeleteRegKey HKCR "Folder\shellex\ContextMenuHandlers\7-Zip" + + DeleteRegKey HKCR "7-Zip.001" + DeleteRegKey HKCR "7-Zip.7z" + DeleteRegKey HKCR "7-Zip.arj" + DeleteRegKey HKCR "7-Zip.bz2" + DeleteRegKey HKCR "7-Zip.cab" + DeleteRegKey HKCR "7-Zip.cpio" + DeleteRegKey HKCR "7-Zip.deb" + DeleteRegKey HKCR "7-Zip.gz" + DeleteRegKey HKCR "7-Zip.rar" + DeleteRegKey HKCR "7-Zip.rpm" + DeleteRegKey HKCR "7-Zip.split" + DeleteRegKey HKCR "7-Zip.tar" + DeleteRegKey HKCR "7-Zip.z" + DeleteRegKey HKCR "7-Zip.zip" + +SectionEnd diff --git a/DOC/Methods.txt b/DOC/Methods.txt index c766bbb5..82ee9d3a 100755 --- a/DOC/Methods.txt +++ b/DOC/Methods.txt @@ -1,4 +1,4 @@ -Compression method IDs (3.08 beta) +Compression method IDs (4.16 beta) ---------------------------------- Each compression method in 7z has unique binary value (ID). @@ -35,7 +35,8 @@ List of defined IDs 05 - BC_M68_B (Big Endian) 07 - ARM Thumb 01 - BC_ARMThumb - 08 - reserved for SPARC + 08 - SPARC + 05 - BC_SPARC 04 - PPMD 01 - Version @@ -43,9 +44,12 @@ List of defined IDs 04 - Misc 00 - Reserved 01 - Zip - 06 - Imploded + 00 - Copy (not used). Use {00} instead + 01 - Shrink + 06 - Implode 08 - Deflate 09 - Deflate64 + 12 - BZip2 (not used). Use {04 02 02} instead 02 - BZip 02 - BZip2 03 - Rar diff --git a/DOC/history.txt b/DOC/history.txt index 64f7b7c9..7b9b9122 100755 --- a/DOC/history.txt +++ b/DOC/history.txt @@ -1,6 +1,33 @@ Sources history of the 7-Zip ---------------------------- + Version 4.19 beta 2005-05-21 + -------------------------------------- + - BZip2 code was rewritten. Now 7-Zip doesn't use original BZip2 code. + Old (original) version was moved to folder 7zip/Compress/BZip2Original/ + + + Version 4.14 beta 2005-01-11 + -------------------------------------- + - STL using was reduced + - 7za now supports Split(001) archves + + + Version 4.10 beta 2004-10-21 + -------------------------------------- + - Codecs now use new interface: ICompressSetDecoderProperties2 + + + Version 4.07 beta 2004-10-03 + -------------------------------------- + - some interfaces were changed slightly to support + -stdin -stdout mode. + - FilterCoder for simple filters + - Wildcard censor class was changed. + - Bug was fixed: when encrypted stream was multiple 16, + it used additional 16 empty bytes. + + Version 3.11 2003-10-06 -------------------------------------- File functions support unicode strings even diff --git a/DOC/lzma.txt b/DOC/lzma.txt new file mode 100755 index 00000000..191e0f99 --- /dev/null +++ b/DOC/lzma.txt @@ -0,0 +1,544 @@ +LZMA SDK 4.17 +------------- + +LZMA SDK 4.17 Copyright (C) 1999-2005 Igor Pavlov + +LZMA SDK provides developers with documentation, source code, +and sample code necessary to write software that uses LZMA compression. + +LZMA is default and general compression method of 7z format +in 7-Zip compression program (www.7-zip.org). LZMA provides high +compression ratio and very fast decompression. + +LZMA is an improved version of famous LZ77 compression algorithm. +It was improved in way of maximum increasing of compression ratio, +keeping high decompression speed and low memory requirements for +decompressing. + + + +LICENSE +------- + +LZMA SDK is licensed under two licenses: + +1) GNU Lesser General Public License (GNU LGPL) +2) Common Public License (CPL) + +It means that you can select one of these two licenses and +follow rules of that license. + +SPECIAL EXCEPTION +Igor Pavlov, as the author of this code, expressly permits you +to statically or dynamically link your code (or bind by name) +to the files from LZMA SDK without subjecting your linked +code to the terms of the CPL or GNU LGPL. +Any modifications or additions to files from LZMA SDK, however, +are subject to the GNU LGPL or CPL terms. + + +SPECIAL EXCEPTION allows you to use LZMA SDK in applications with closed code, +while you keep LZMA SDK code unmodified. + + +SPECIAL EXCEPTION #2: Igor Pavlov, as the author of this code, expressly permits +you to use this code under the same terms and conditions contained in the License +Agreement you have for any previous version of LZMA SDK developed by Igor Pavlov. + +SPECIAL EXCEPTION #2 allows owners of proprietary licenses to use latest version +of LZMA SDK as update for previous versions. + + +SPECIAL EXCEPTION #3: Igor Pavlov, as the author of this code, expressly permits +you to use code of examples (LzmaTest.c) as public domain code. + + +GNU LGPL and CPL licenses are pretty similar and both these +licenses are classified as + +1) "Free software licenses" at http://www.gnu.org/ +2) "OSI-approved" at http://www.opensource.org/ + + + +LZMA SDK also can be available under a proprietary license which +can include: + +1) Right to modify code without subjecting modified code to the +terms of the CPL or GNU LGPL +2) Technical support for code + +To request such proprietary license or any additional consultations, +send email message from that page: +http://www.7-zip.org/support.html + + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +You should have received a copy of the Common Public License +along with this library. + + +LZMA SDK Contents +----------------- + +LZMA SDK includes: + + - C++ source code of LZMA Encoder and Decoder + - C++ source code for file->file LZMA compressing and decompressing + - ANSI-C compatible source code for LZMA decompressing + - Compiled file->file LZMA compressing/decompressing program for Windows system + +ANSI-C LZMA decompression code was ported from original C++ sources to C. +Also it was simplified and optimized for code size. +But it is fully compatible with LZMA from 7-Zip. + + +UNIX/Linux version +------------------ +To compile C++ version of file->file LZMA, go to directory +SRC/7zip/Compress/LZMA_Alone +and type "make" or "make clean all" to recompile all. + +In some UNIX/Linux versions you must compile LZMA with static libraries. +To compile with static libraries, change string in makefile +LIB = -lm +to string +LIB = -lm -static + + +Files +--------------------- +SRC - directory with source code +lzma.txt - LZMA SDK description (this file) +7zFormat.txt - 7z Format description +7zC.txt - 7z ANSI-C Decoder description (this file) +methods.txt - Compression method IDs for .7z +LGPL.txt - GNU Lesser General Public License +CPL.html - Common Public License +lzma.exe - Compiled file->file LZMA encoder/decoder for Windows +history.txt - history of the LZMA SDK + + +Source code structure +--------------------- + +SRC + Common - common files for C++ projects + Windows - common files for Windows related code + 7zip - files related to 7-Zip Project + Common - common files for 7-Zip + Compress - files related to compression/decompression + LZ - files related to LZ (Lempel-Ziv) compression algorithm + BinTree - Binary Tree Match Finder for LZ algorithm + HashChain - Hash Chain Match Finder for LZ algorithm + Patricia - Patricia Match Finder for LZ algorithm + RangeCoder - Range Coder (special code of compression/decompression) + LZMA - LZMA compression/decompression on C++ + LZMA_Alone - file->file LZMA compression/decompression + LZMA_C - ANSI-C compatible LZMA decompressor + LzmaDecode.h - interface for LZMA decoding on ANSI-C + LzmaDecode.c - LZMA decoding on ANSI-C (new fastest version) + LzmaDecodeSize.c - LZMA decoding on ANSI-C (old size-optimized version) + LzmaTest.c - test application that decodes LZMA encoded file + Branch - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code + Archive - files related to archiving + 7z_C - 7z ANSI-C Decoder + +Source code of LZMA SDK is only part of big 7-Zip project. That is +why LZMA SDK uses such complex source code structure. + +You can find ANSI-C LZMA decompressing code at folder + SRC/7zip/Compress/LZMA_C +7-Zip doesn't use that ANSI-C LZMA code and that code was developed +specially for this SDK. And files from LZMA_C do not need files from +other directories of SDK for compiling. + +7-Zip source code can be downloaded from 7-Zip's SourceForge page: + + http://sourceforge.net/projects/sevenzip/ + + +LZMA Decompression features +--------------------------- + - Variable dictionary size (up to 256 MB) + - Estimated compressing speed: about 500 KB/s on 1 GHz CPU + - Estimated decompressing speed: + - 8-12 MB/s on 1 GHz Intel Pentium 3 or AMD Athlon + - 500-1000 KB/s on 100 MHz ARM, MIPS, PowerPC or other simple RISC + - Small memory requirements for decompressing (8-32 KB + DictionarySize) + - Small code size for decompressing: 2-8 KB (depending from + speed optimizations) + +LZMA decoder uses only integer operations and can be +implemented in any modern 32-bit CPU (or on 16-bit CPU with some conditions). + +Some critical operations that affect to speed of LZMA decompression: + 1) 32*16 bit integer multiply + 2) Misspredicted branches (penalty mostly depends from pipeline length) + 3) 32-bit shift and arithmetic operations + +Speed of LZMA decompression mostly depends from CPU speed. +Memory speed has no big meaning. But if your CPU has small data cache, +overall weight of memory speed will slightly increase. + + +How To Use +---------- + +Using LZMA encoder/decoder executable +-------------------------------------- + +Usage: LZMA <e|d> inputFile outputFile [<switches>...] + + e: encode file + + d: decode file + + b: Benchmark. There are two tests: compressing and decompressing + with LZMA method. Benchmark shows rating in MIPS (million + instructions per second). Rating value is calculated from + measured speed and it is normalized with AMD Athlon XP CPU + results. Also Benchmark checks possible hardware errors (RAM + errors in most cases). Benchmark uses these settings: + (-a1, -d21, -fb32, -mfbt4). You can change only -d. Also you + can change number of iterations. Example for 30 iterations: + LZMA b 30 + Default number of iterations is 10. + +<Switches> + + + -a{N}: set compression mode 0 = fast, 1 = normal, 2 = max + default: 2 (max) + + d{N}: Sets Dictionary size - [0, 28], default: 23 (8MB) + The maximum value for dictionary size is 256 MB = 2^28 bytes. + Dictionary size is calculated as DictionarySize = 2^N bytes. + For decompressing file compressed by LZMA method with dictionary + size D = 2^N you need about D bytes of memory (RAM). + + -fb{N}: set number of fast bytes - [5, 255], default: 128 + Usually big number gives a little bit better compression ratio + and slower compression process. + + -lc{N}: set number of literal context bits - [0, 8], default: 3 + Sometimes lc=4 gives gain for big files. + + -lp{N}: set number of literal pos bits - [0, 4], default: 0 + lp switch is intended for periodical data when period is + equal 2^N. For example, for 32-bit (4 bytes) + periodical data you can use lp=2. Often it's better to set lc0, + if you change lp switch. + + -pb{N}: set number of pos bits - [0, 4], default: 2 + pb switch is intended for periodical data + when period is equal 2^N. + + -mf{MF_ID}: set Match Finder. Default: bt4. + Compression ratio for all bt* and pat* almost the same. + Algorithms from hc* group doesn't provide good compression + ratio, but they often works pretty fast in combination with + fast mode (-a0). Methods from bt* group require less memory + than methods from pat* group. Usually bt4 works faster than + any pat*, but for some types of files pat* can work faster. + + Memory requirements depend from dictionary size + (parameter "d" in table below). + + MF_ID Memory Description + + bt2 d*9.5 + 1MB Binary Tree with 2 bytes hashing. + bt3 d*9.5 + 65MB Binary Tree with 2-3(full) bytes hashing. + bt4 d*9.5 + 6MB Binary Tree with 2-3-4 bytes hashing. + bt4b d*9.5 + 34MB Binary Tree with 2-3-4(big) bytes hashing. + pat2r d*26 + 1MB Patricia Tree with 2-bits nodes, removing. + pat2 d*38 + 1MB Patricia Tree with 2-bits nodes. + pat2h d*38 + 77MB Patricia Tree with 2-bits nodes, 2-3 bytes hashing. + pat3h d*62 + 85MB Patricia Tree with 3-bits nodes, 2-3 bytes hashing. + pat4h d*110 +101MB Patricia Tree with 4-bits nodes, 2-3 bytes hashing. + hc3 d*5.5 + 1MB Hash Chain with 2-3 bytes hashing. + hc4 d*5.5 + 6MB Hash Chain with 2-3-4 bytes hashing. + + -eos: write End Of Stream marker. By default LZMA doesn't write + eos marker, since LZMA decoder knows uncompressed size + stored in .lzma file header. + + -si: Read data from stdin (it will write End Of Stream marker). + -so: Write data to stdout + + +Examples: + +1) LZMA e file.bin file.lzma -d16 -lc0 + +compresses file.bin to file.lzma with 64 KB dictionary (2^16=64K) +and 0 literal context bits. -lc0 allows to reduce memory requirements +for decompression. + + +2) LZMA e file.bin file.lzma -lc0 -lp2 + +compresses file.bin to file.lzma with settings suitable +for 32-bit periodical data (for example, ARM or MIPS code). + +3) LZMA d file.lzma file.bin + +decompresses file.lzma to file.bin. + + +Compression ratio hints +----------------------- + +Recommendations +--------------- + +To increase compression ratio for LZMA compressing it's desirable +to have aligned data (if it's possible) and also it's desirable to locate +data in such order, where code is grouped in one place and data is +grouped in other place (it's better than such mixing: code, data, code, +data, ...). + + +Using Filters +------------- +You can increase compression ratio for some data types, using +special filters before compressing. For example, it's possible to +increase compression ratio on 5-10% for code for those CPU ISAs: +x86, IA-64, ARM, ARM-Thumb, PowerPC, SPARC. + +You can find C/C++ source code of such filters in folder "7zip/Compress/Branch" + +You can check compression ratio gain of these filters with such +7-Zip commands (example for ARM code): +No filter: + 7z a a1.7z a.bin -m0=lzma + +With filter for little-endian ARM code: + 7z a a2.7z a.bin -m0=bc_arm -m1=lzma + +With filter for big-endian ARM code (using additional Swap4 filter): + 7z a a3.7z a.bin -m0=swap4 -m1=bc_arm -m2=lzma + +It works in such manner: +Compressing = Filter_encoding + LZMA_encoding +Decompressing = LZMA_decoding + Filter_decoding + +Compressing and decompressing speed of such filters is very high, +so it will not increase decompressing time too much. +Moreover, it reduces decompression time for LZMA_decoding, +since compression ratio with filtering is higher. + +These filters convert CALL (calling procedure) instructions +from relative offsets to absolute addresses, so such data becomes more +compressible. Source code of these CALL filters is pretty simple +(about 20 lines of C++), so you can convert it from C++ version yourself. + +For some ISAs (for example, for MIPS) it's impossible to get gain from such filter. + + +LZMA compressed file format +--------------------------- +Offset Size Description + 0 1 Special LZMA properties for compressed data + 1 4 Dictionary size (little endian) + 5 8 Uncompressed size (little endian). -1 means unknown size + 13 Compressed data + + +ANSI-C LZMA Decoder +~~~~~~~~~~~~~~~~~~~ + +To use ANSI-C LZMA Decoder you need to files: +LzmaDecode.h and one of the following two files: +1) LzmaDecode.c - LZMA decoding on ANSI-C (new fastest version) +2) LzmaDecodeSize.c - LZMA decoding on ANSI-C (old size-optimized version) +use LzmaDecode.c, if you need fastest code. + + +Memory requirements for LZMA decoding +------------------------------------- + +LZMA decoder doesn't allocate memory itself, so you must +calculate required memory, allocate it and send it to LZMA. + +Stack usage of LZMA function for local variables is not +larger than 200 bytes. + +Memory requirements for decompression depend +from interface that you want to use: + + a) Memory to memory decompression: + + M1 = (inputSize + outputSize + lzmaInternalSize). + + b) Decompression with buffering: + + M2 = (inputBufferSize + outputBufferSize + dictionarySize + lzmaInternalSize) + + +How To decompress data +---------------------- + +1) Read first byte of properties for LZMA compressed stream, + check that it has correct value and calculate three + LZMA property variables: + + int lc, lp, pb; + unsigned char prop0 = properties[0]; + if (prop0 >= (9*5*5)) + { + sprintf(rs + strlen(rs), "\n properties error"); + return 1; + } + for (pb = 0; prop0 >= (9 * 5); + pb++, prop0 -= (9 * 5)); + for (lp = 0; prop0 >= 9; + lp++, prop0 -= 9); + lc = prop0; + +2) Calculate required amount for LZMA lzmaInternalSize: + + lzmaInternalSize = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp))) * + sizeof(CProb) + + LZMA_BASE_SIZE = 1846 + LZMA_LIT_SIZE = 768 + + LZMA decoder uses array of CProb variables as internal structure. + By default, CProb is (unsigned short) + But you can define _LZMA_PROB32 to make it (unsigned int) + It can increase speed on some 32-bit CPUs, but memory usage will + be doubled in that case. + + + 2b) If you use Decompression with buffering, add 100 bytes to + lzmaInternalSize: + + #ifdef _LZMA_OUT_READ + lzmaInternalSize += 100; + #endif + +3) Allocate that memory with malloc or some other function: + + lzmaInternalData = malloc(lzmaInternalSize); + + +4) Decompress data: + + 4a) If you use simple memory to memory decompression: + + int result = LzmaDecode(lzmaInternalData, lzmaInternalSize, + lc, lp, pb, + unsigned char *inStream, unsigned int inSize, + unsigned char *outStream, unsigned int outSize, + &outSizeProcessed); + + 4b) If you use Decompression with buffering + + 4.1) Read dictionary size from properties + + unsigned int dictionarySize = 0; + int i; + for (i = 0; i < 4; i++) + dictionarySize += (unsigned int)(b) << (i * 8); + + 4.2) Allocate memory for dictionary + + unsigned char *dictionary = malloc(dictionarySize); + + 4.3) Initialize LZMA decoder: + + LzmaDecoderInit((unsigned char *)lzmaInternalData, lzmaInternalSize, + lc, lp, pb, + dictionary, dictionarySize, + &bo.ReadCallback); + + 4.4) In loop call LzmaDecoderCode function: + + for (nowPos = 0; nowPos < outSize;) + { + unsigned int blockSize = outSize - nowPos; + unsigned int kBlockSize = 0x10000; + if (blockSize > kBlockSize) + blockSize = kBlockSize; + res = LzmaDecode((unsigned char *)lzmaInternalData, + ((unsigned char *)outStream) + nowPos, blockSize, &outSizeProcessed); + if (res != 0) + { + printf("\nerror = %d\n", res); + break; + } + nowPos += outSizeProcessed; + if (outSizeProcessed == 0) + { + outSize = nowPos; + break; + } + } + + +EXIT codes +----------- + +LZMA decoder can return one of the following codes: + +#define LZMA_RESULT_OK 0 +#define LZMA_RESULT_DATA_ERROR 1 +#define LZMA_RESULT_NOT_ENOUGH_MEM 2 + +If you use callback function for input data and you return some +error code, LZMA Decoder also returns that code. + + + +LZMA Defines +------------ + +_LZMA_IN_CB - Use callback for input data + +_LZMA_OUT_READ - Use read function for output data + +_LZMA_LOC_OPT - Enable local speed optimizations inside code. + _LZMA_LOC_OPT is only for LzmaDecodeSize.c (size-optimized version). + _LZMA_LOC_OPT doesn't affect LzmaDecode.c (speed-optimized version) + +_LZMA_PROB32 - It can increase speed on some 32-bit CPUs, + but memory usage will be doubled in that case + +_LZMA_UINT32_IS_ULONG - Define it if int is 16-bit on your compiler + and long is 32-bit. + + +NOTES +----- +1) please note that LzmaTest.c doesn't free allocated memory in some cases. +But in your real applicaions you must free memory after decompression. + +2) All numbers above were calculated for case when int is not more than + 32-bit in your compiler. If in your compiler int is 64-bit or larger + probably LZMA can require more memory for some structures. + + + +C++ LZMA Encoder/Decoder +~~~~~~~~~~~~~~~~~~~~~~~~ +C++ LZMA code use COM-like interfaces. So if you want to use it, +you can study basics of COM/OLE. + +By default, LZMA Encoder contains all Match Finders. +But for compressing it's enough to have just one of them. +So for reducing size of compressing code you can define: + #define COMPRESS_MF_BT + #define COMPRESS_MF_BT4 +and it will use only bt4 match finder. + + +--- + +http://www.7-zip.org +http://www.7-zip.org/support.html + + diff --git a/DOC/readme.txt b/DOC/readme.txt index c800237a..f26a352d 100755 --- a/DOC/readme.txt +++ b/DOC/readme.txt @@ -1,9 +1,9 @@ -7-Zip 3.11 Sources +7-Zip 4.20 Sources ------------------ -7-Zip is a file archiver for Windows 95/98/ME/NT/2000/XP. +7-Zip is a file archiver for Windows 95/98/ME/NT/2000/2003/XP. -7-Zip Copyright (C) 1999-2003 Igor Pavlov. +7-Zip Copyright (C) 1999-2005 Igor Pavlov. License Info @@ -27,14 +27,18 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA License notes ------------- -You can support development of 7-Zip by registering and -paying $20. As registered user, you will be able -to get technical support via e-mail support@7-zip.org. +You can support development of 7-Zip by registering. 7-Zip is free software distributed under the GNU LGPL. -If you need license with other conditions, write to support@7-zip.org. -You also can request for help in creating code based on -7-Zip's code for your custom application. +If you need license with other conditions, write to +http://www.7-zip.org/support.html + +--- +Also this package contains files from LZMA SDK +you can download LZMA SDK from this page: +http://www.7-zip.org/sdk.html +read about license for LZMA SDk in file +DOC/lzma.txt How to compile @@ -44,8 +48,29 @@ For compiling some files you also need new Platform SDK from Microsoft' Site: http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm or +http://www.microsoft.com/msdownload/platformsdk/sdkupdate/XPSP2FULLInstall.htm +or http://www.microsoft.com/msdownload/platformsdk/sdkupdate/ +If you use MSVC6, specify SDK directories at top of directories lists: +Tools / Options / Directories + - Include files + - Library files + + +Also if you want to compile Original BZip2 code you must +download BZip source to folder +7zip/Compress/BZip2Original/Original +You can find BZip2 sources from that page: +http://sources.redhat.com/bzip2/index.html + + + +Compiling under Unix/Linux +-------------------------- +If sizeof(wchar_t) == 4 in your compiler, +you must use only 2 low bytes of wchar_t. + Notes: ------ @@ -72,16 +97,12 @@ DOC Documentation history.txt - Sources history Methods.txt - Compression method IDs readme.txt - Readme file - - Alien Must contains third party sources - Compress - BZip2 BZip2 compression sources from - http://sources.redhat.com/bzip2/index.html + lzma.txt - LZMA SDK description + 7zip.nsi - installer script for NSIS Common Common modules Windows Win32 wrappers -Far FAR interface wrappers 7zip ------- @@ -153,7 +174,6 @@ Far FAR interface wrappers --- Igor Pavlov http://www.7-zip.org -support@7-zip.org --- diff --git a/Far/FarUtils.cpp b/Far/FarUtils.cpp deleted file mode 100755 index ad6db12a..00000000 --- a/Far/FarUtils.cpp +++ /dev/null @@ -1,421 +0,0 @@ -// FarUtils.cpp - -#include "StdAfx.h" - -#include "FarUtils.h" -#include "Common/DynamicBuffer.h" -#include "Common/StringConvert.h" -#include "Windows/Defs.h" -#include "Windows/Console.h" -#include "Windows/Error.h" - -using namespace NWindows; -using namespace std; - -namespace NFar { - -CStartupInfo g_StartupInfo; - - -void CStartupInfo::Init(const PluginStartupInfo &aPluginStartupInfo, - const CSysString &aPliginNameForRegestry) -{ - m_Data = aPluginStartupInfo; - m_RegistryPath = aPluginStartupInfo.RootKey; - m_RegistryPath += '\\'; - m_RegistryPath += aPliginNameForRegestry; -} - -const char *CStartupInfo::GetMsgString(int aMessageId) -{ - return (const char*)m_Data.GetMsg(m_Data.ModuleNumber, aMessageId); -} - -int CStartupInfo::ShowMessage(unsigned int aFlags, - const char *aHelpTopic, const char **anItems, int anItemsNumber, int aButtonsNumber) -{ - return m_Data.Message(m_Data.ModuleNumber, aFlags, (char *)aHelpTopic, - (char **)anItems, anItemsNumber, aButtonsNumber); -} - -namespace NMessageID -{ - enum - { - kOk, - kCancel, - kWarning, - kError - }; -} - -int CStartupInfo::ShowMessage(const char *aMessage) -{ - const char *aMessagesItems[]= { GetMsgString(NMessageID::kError), aMessage, - GetMsgString(NMessageID::kOk) }; - return ShowMessage(FMSG_WARNING, NULL, aMessagesItems, - sizeof(aMessagesItems) / sizeof(aMessagesItems[0]), 1); -} - -int CStartupInfo::ShowMessage(int aMessageId) -{ - return ShowMessage(GetMsgString(aMessageId)); -} - -int CStartupInfo::ShowDialog(int X1, int Y1, int X2, int Y2, - const char *aHelpTopic, struct FarDialogItem *anItems, int aNumItems) -{ - return m_Data.Dialog(m_Data.ModuleNumber, X1, Y1, X2, Y2, (char *)aHelpTopic, - anItems, aNumItems); -} - -int CStartupInfo::ShowDialog(int aSizeX, int aSizeY, - const char *aHelpTopic, struct FarDialogItem *anItems, int aNumItems) -{ - return ShowDialog(-1, -1, aSizeX, aSizeY, aHelpTopic, anItems, aNumItems); -} - -inline static BOOL GetBOOLValue(bool aBool) -{ - return (aBool? TRUE: FALSE); -} - -void CStartupInfo::InitDialogItems(const CInitDialogItem *aSrcItems, - FarDialogItem *aDestItems, int aNum) -{ - for (int i = 0; i < aNum; i++) - { - const CInitDialogItem &aSrcItem = aSrcItems[i]; - FarDialogItem &aDestItem = aDestItems[i]; - - aDestItem.Type = aSrcItem.Type; - aDestItem.X1 = aSrcItem.X1; - aDestItem.Y1 = aSrcItem.Y1; - aDestItem.X2 = aSrcItem.X2; - aDestItem.Y2 = aSrcItem.Y2; - aDestItem.Focus = GetBOOLValue(aSrcItem.Focus); - if(aSrcItem.HistoryName != NULL) - aDestItem.Selected = int(aSrcItem.HistoryName); - else - aDestItem.Selected = GetBOOLValue(aSrcItem.Selected); - aDestItem.Flags = aSrcItem.Flags; - aDestItem.DefaultButton = GetBOOLValue(aSrcItem.DefaultButton); - - if(aSrcItem.DataMessageId < 0) - strcpy(aDestItem.Data, aSrcItem.DataString); - else - strcpy(aDestItem.Data, GetMsgString(aSrcItem.DataMessageId)); - - /* - if ((unsigned int)Init[i].Data < 0xFFF) - strcpy(aDestItem.Data, GetMsg((unsigned int)aSrcItem.Data)); - else - strcpy(aDestItem.Data,aSrcItem.Data); - */ - } -} - -// -------------------------------------------- - -HANDLE CStartupInfo::SaveScreen(int X1, int Y1, int X2, int Y2) -{ - return m_Data.SaveScreen(X1, Y1, X2, Y2); -} - -HANDLE CStartupInfo::SaveScreen() -{ - return SaveScreen(0, 0, -1, -1); -} - -void CStartupInfo::RestoreScreen(HANDLE aHandle) -{ - m_Data.RestoreScreen(aHandle); -} - -const char kRegestryKeyDelimiter = '\''; - -CSysString CStartupInfo::GetFullKeyName(const CSysString &aKeyName) const -{ - return (aKeyName.IsEmpty()) ? m_RegistryPath: - (m_RegistryPath + kRegestryKeyDelimiter + aKeyName); -} - - -LONG CStartupInfo::CreateRegKey(HKEY aKeyParent, - const CSysString &aKeyName, NRegistry::CKey &aDestKey) const -{ - return aDestKey.Create(aKeyParent, GetFullKeyName(aKeyName)); -} - -LONG CStartupInfo::OpenRegKey(HKEY aKeyParent, - const CSysString &aKeyName, NRegistry::CKey &aDestKey) const -{ - return aDestKey.Open(aKeyParent, GetFullKeyName(aKeyName)); -} - -void CStartupInfo::SetRegKeyValue(HKEY aKeyParent, const CSysString &aKeyName, - LPCTSTR aValueName, LPCTSTR aValue) const -{ - NRegistry::CKey aRegKey; - CreateRegKey(aKeyParent, aKeyName, aRegKey); - aRegKey.SetValue(aValueName, aValue); -} - -void CStartupInfo::SetRegKeyValue(HKEY aKeyParent, const CSysString &aKeyName, - LPCTSTR aValueName, UINT32 aValue) const -{ - NRegistry::CKey aRegKey; - CreateRegKey(aKeyParent, aKeyName, aRegKey); - aRegKey.SetValue(aValueName, aValue); -} - -void CStartupInfo::SetRegKeyValue(HKEY aKeyParent, const CSysString &aKeyName, - LPCTSTR aValueName, bool aValue) const -{ - NRegistry::CKey aRegKey; - CreateRegKey(aKeyParent, aKeyName, aRegKey); - aRegKey.SetValue(aValueName, aValue); -} - -CSysString CStartupInfo::QueryRegKeyValue(HKEY aKeyParent, const CSysString &aKeyName, - LPCTSTR aValueName, const CSysString &aValueDefault) const -{ - NRegistry::CKey aRegKey; - if (OpenRegKey(aKeyParent, aKeyName, aRegKey) != ERROR_SUCCESS) - return aValueDefault; - - CSysString aValue; - if(aRegKey.QueryValue(aValueName, aValue) != ERROR_SUCCESS) - return aValueDefault; - - return aValue; -} - -UINT32 CStartupInfo::QueryRegKeyValue(HKEY aKeyParent, const CSysString &aKeyName, - LPCTSTR aValueName, UINT32 aValueDefault) const -{ - NRegistry::CKey aRegKey; - if (OpenRegKey(aKeyParent, aKeyName, aRegKey) != ERROR_SUCCESS) - return aValueDefault; - - UINT32 aValue; - if(aRegKey.QueryValue(aValueName, aValue) != ERROR_SUCCESS) - return aValueDefault; - - return aValue; -} - -bool CStartupInfo::QueryRegKeyValue(HKEY aKeyParent, const CSysString &aKeyName, - LPCTSTR aValueName, bool aValueDefault) const -{ - NRegistry::CKey aRegKey; - if (OpenRegKey(aKeyParent, aKeyName, aRegKey) != ERROR_SUCCESS) - return aValueDefault; - - bool aValue; - if(aRegKey.QueryValue(aValueName, aValue) != ERROR_SUCCESS) - return aValueDefault; - - return aValue; -} - -bool CStartupInfo::Control(HANDLE aPlugin, int aCommand, void *aParam) -{ - return BOOLToBool(m_Data.Control(aPlugin, aCommand, aParam)); -} - -bool CStartupInfo::ControlRequestActivePanel(int aCommand, void *aParam) -{ - return Control(INVALID_HANDLE_VALUE, aCommand, aParam); -} - -bool CStartupInfo::ControlGetActivePanelInfo(PanelInfo &aPanelInfo) -{ - return ControlRequestActivePanel(FCTL_GETPANELINFO, &aPanelInfo); -} - -bool CStartupInfo::ControlSetSelection(const PanelInfo &aPanelInfo) -{ - return ControlRequestActivePanel(FCTL_SETSELECTION, (void *)&aPanelInfo); -} - -bool CStartupInfo::ControlGetActivePanelCurrentItemInfo( - PluginPanelItem &aPluginPanelItem) -{ - PanelInfo aPanelInfo; - if(!ControlGetActivePanelInfo(aPanelInfo)) - return false; - if(aPanelInfo.ItemsNumber <= 0) - throw "There are no items"; - aPluginPanelItem = aPanelInfo.PanelItems[aPanelInfo.CurrentItem]; - return true; -} - -bool CStartupInfo::ControlGetActivePanelSelectedOrCurrentItems( - CObjectVector<PluginPanelItem> &aPluginPanelItems) -{ - aPluginPanelItems.Clear(); - PanelInfo aPanelInfo; - if(!ControlGetActivePanelInfo(aPanelInfo)) - return false; - if(aPanelInfo.ItemsNumber <= 0) - throw "There are no items"; - if (aPanelInfo.SelectedItemsNumber == 0) - aPluginPanelItems.Add(aPanelInfo.PanelItems[aPanelInfo.CurrentItem]); - else - for (int i = 0; i < aPanelInfo.SelectedItemsNumber; i++) - aPluginPanelItems.Add(aPanelInfo.SelectedItems[i]); - return true; -} - -bool CStartupInfo::ControlClearPanelSelection() -{ - PanelInfo aPanelInfo; - if(!ControlGetActivePanelInfo(aPanelInfo)) - return false; - for (int i = 0; i < aPanelInfo.ItemsNumber; i++) - aPanelInfo.PanelItems[i].Flags &= ~PPIF_SELECTED; - return ControlSetSelection(aPanelInfo); -} - -//////////////////////////////////////////////// -// menu function - -int CStartupInfo::Menu( - int x, - int y, - int aMaxHeight, - unsigned int aFlags, - const char *aTitle, - const char *aBottom, - const char *aHelpTopic, - int *aBreakKeys, - int *aBreakCode, - struct FarMenuItem *anItems, - int aNumItems) -{ - return m_Data.Menu(m_Data.ModuleNumber, x, y, aMaxHeight, aFlags, (char *)aTitle, - (char *)aBottom, (char *)aHelpTopic, aBreakKeys, aBreakCode, anItems, aNumItems); -} - -int CStartupInfo::Menu( - unsigned int aFlags, - const char *aTitle, - const char *aHelpTopic, - struct FarMenuItem *anItems, - int aNumItems) -{ - return Menu(-1, -1, 0, aFlags, aTitle, NULL, aHelpTopic, NULL, - NULL, anItems, aNumItems); -} - -int CStartupInfo::Menu( - unsigned int aFlags, - const char *aTitle, - const char *aHelpTopic, - const CSysStringVector &anItems, - int aSelectedItem) -{ - vector<FarMenuItem> aFarMenuItems; - for(int i = 0; i < anItems.Size(); i++) - { - FarMenuItem anItem; - anItem.Checked = 0; - anItem.Separator = 0; - anItem.Selected = (i == aSelectedItem); - CSysString aReducedString = - anItems[i].Left(sizeof(anItem.Text) / sizeof(anItem.Text[0]) - 1); - strcpy(anItem.Text, aReducedString); - aFarMenuItems.push_back(anItem); - } - return Menu(aFlags, aTitle, aHelpTopic, &aFarMenuItems.front(), - aFarMenuItems.size()); -} - - -////////////////////////////////// -// CScreenRestorer - -CScreenRestorer::~CScreenRestorer() -{ - Restore(); -} -void CScreenRestorer::Save() -{ - if(m_Saved) - return; - m_HANDLE = g_StartupInfo.SaveScreen(); - m_Saved = true; -} - -void CScreenRestorer::Restore() -{ - if(m_Saved) - { - g_StartupInfo.RestoreScreen(m_HANDLE); - m_Saved = false; - } -}; - -static CSysString DWORDToString(DWORD aNumber) -{ - char aBuffer[32]; - ultoa(aNumber, aBuffer, 10); - return aBuffer; -} - -void PrintErrorMessage(const char *aMessage, int anCode) -{ - CSysString aTmp = aMessage; - aTmp += " #"; - aTmp += DWORDToString(anCode); - g_StartupInfo.ShowMessage(aTmp); -} - -void PrintErrorMessage(const char *aMessage, const char *aText) -{ - CSysString aTmp = aMessage; - aTmp += ": "; - aTmp += aText; - g_StartupInfo.ShowMessage(aTmp); -} - -bool WasEscPressed() -{ - NConsole::CIn anInConsole; - HANDLE aHandle = ::GetStdHandle(STD_INPUT_HANDLE); - if(aHandle == INVALID_HANDLE_VALUE) - return true; - anInConsole.Attach(aHandle); - while (true) - { - DWORD aNumberOfEvents; - if(!anInConsole.GetNumberOfEvents(aNumberOfEvents)) - return true; - if(aNumberOfEvents == 0) - return false; - - INPUT_RECORD anEvent; - if(!anInConsole.ReadEvent(anEvent, aNumberOfEvents)) - return true; - if (anEvent.EventType == KEY_EVENT && - anEvent.Event.KeyEvent.bKeyDown && - anEvent.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) - return true; - } -} - -void ShowErrorMessage(DWORD aError) -{ - CSysString aMessage; - NError::MyFormatMessage(aError, aMessage); - g_StartupInfo.ShowMessage(SystemStringToOemString(aMessage)); - -} - -void ShowLastErrorMessage() -{ - ShowErrorMessage(::GetLastError()); -} - -} diff --git a/Far/FarUtils.h b/Far/FarUtils.h deleted file mode 100755 index a6240349..00000000 --- a/Far/FarUtils.h +++ /dev/null @@ -1,220 +0,0 @@ -// FarUtils.h - -#pragma once - -#ifndef __FARUTILS_H -#define __FARUTILS_H - -#include "FarPlugin.h" -#include "Common/String.h" -#include "Common/Vector.h" -#include "Windows/Registry.h" - -namespace NFar { - -namespace NFileOperationReturnCode -{ - enum EEnum - { - kInterruptedByUser = -1, - kError = 0, - kSuccess = 1 - }; -} - -namespace NEditorReturnCode -{ - enum EEnum - { - kOpenError = 0, - kFileWasChanged = 1, - kFileWasNotChanged = 2, - kInterruptedByUser = 3 - }; -} - -struct CInitDialogItem -{ - DialogItemTypes Type; - int X1,Y1,X2,Y2; - bool Focus; - bool Selected; - unsigned int Flags; //FarDialogItemFlags Flags; - bool DefaultButton; - int DataMessageId; - const char *DataString; - const char *HistoryName; - // void InitToFarDialogItem(struct FarDialogItem &anItemDest); -}; - -class CStartupInfo -{ - PluginStartupInfo m_Data; - CSysString m_RegistryPath; - - CSysString GetFullKeyName(const CSysString &aKeyName) const; - LONG CreateRegKey(HKEY aKeyParent, - const CSysString &aKeyName, NWindows::NRegistry::CKey &aDestKey) const; - LONG OpenRegKey(HKEY aKeyParent, - const CSysString &aKeyName, NWindows::NRegistry::CKey &aDestKey) const; - -public: - void Init(const PluginStartupInfo &aPluginStartupInfo, - const CSysString &aPliginNameForRegestry); - const char *GetMsgString(int aMessageId); - int ShowMessage(unsigned int aFlags, const char *aHelpTopic, - const char **anItems, int anItemsNumber, int aButtonsNumber); - int ShowMessage(const char *aMessage); - int ShowMessage(int aMessageId); - - int ShowDialog(int X1, int Y1, int X2, int Y2, - const char *aHelpTopic, struct FarDialogItem *anItems, int aNumItems); - int ShowDialog(int aSizeX, int aSizeY, - const char *aHelpTopic, struct FarDialogItem *anItems, int aNumItems); - - void InitDialogItems(const CInitDialogItem *aSrcItems, - FarDialogItem *aDestItems, int aNum); - - HANDLE SaveScreen(int X1, int Y1, int X2, int Y2); - HANDLE SaveScreen(); - void RestoreScreen(HANDLE aHandle); - - void SetRegKeyValue(HKEY aKeyParent, const CSysString &aKeyName, - const LPCTSTR aValueName, LPCTSTR aValue) const; - void SetRegKeyValue(HKEY hRoot, const CSysString &aKeyName, - const LPCTSTR aValueName, UINT32 aValue) const; - void SetRegKeyValue(HKEY hRoot, const CSysString &aKeyName, - const LPCTSTR aValueName, bool aValue) const; - - CSysString QueryRegKeyValue(HKEY aKeyParent, const CSysString &aKeyName, - LPCTSTR aValueName, const CSysString &aValueDefault) const; - - UINT32 QueryRegKeyValue(HKEY aKeyParent, const CSysString &aKeyName, - LPCTSTR aValueName, UINT32 aValueDefault) const; - - bool QueryRegKeyValue(HKEY aKeyParent, const CSysString &aKeyName, - LPCTSTR aValueName, bool aValueDefault) const; - - bool Control(HANDLE aPlugin, int aCommand, void *aParam); - bool ControlRequestActivePanel(int aCommand, void *aParam); - bool ControlGetActivePanelInfo(PanelInfo &aPanelInfo); - bool ControlSetSelection(const PanelInfo &aPanelInfo); - bool ControlGetActivePanelCurrentItemInfo(PluginPanelItem &aPluginPanelItem); - bool ControlGetActivePanelSelectedOrCurrentItems( - CObjectVector<PluginPanelItem> &aPluginPanelItems); - - bool ControlClearPanelSelection(); - - int Menu( - int x, - int y, - int aMaxHeight, - unsigned int aFlags, - const char *aTitle, - const char *aBottom, - const char *aHelpTopic, - int *aBreakKeys, - int *aBreakCode, - FarMenuItem *anItems, - int aNumItems); - int Menu( - unsigned int aFlags, - const char *aTitle, - const char *aHelpTopic, - FarMenuItem *anItems, - int aNumItems); - - int Menu( - unsigned int aFlags, - const char *aTitle, - const char *aHelpTopic, - const CSysStringVector &anItems, - int aSelectedItem); - - int Editor(const char *aFileName, const char *aTitle, - int X1, int Y1, int X2, int Y2, DWORD aFlags, int aStartLine, int aStartChar) - { return m_Data.Editor((char *)aFileName, (char *)aTitle, X1, Y1, X2, Y2, - aFlags, aStartLine, aStartChar); } - int Editor(const char *aFileName) - { return Editor(aFileName, NULL, 0, 0, -1, -1, 0, -1, -1); } - - int Viewer(const char *aFileName, const char *aTitle, - int X1, int Y1, int X2, int Y2, DWORD aFlags) - { return m_Data.Viewer((char *)aFileName, (char *)aTitle, X1, Y1, X2, Y2, aFlags); } - int Viewer(const char *aFileName) - { return Viewer(aFileName, NULL, 0, 0, -1, -1, VF_NONMODAL); } - -}; - -class CScreenRestorer -{ - bool m_Saved; - HANDLE m_HANDLE; -public: - CScreenRestorer(): m_Saved(false){}; - ~CScreenRestorer(); - void Save(); - void Restore(); -}; - - -extern CStartupInfo g_StartupInfo; - -void PrintErrorMessage(const char *aMessage, int anCode); -void PrintErrorMessage(const char *aMessage, const char *aText); - -#define MY_TRY_BEGIN try\ - { - -#define MY_TRY_END1(x) }\ - catch(int n)\ - {\ - PrintErrorMessage(x, n);\ - return;\ - }\ - catch(const CSysString &aText)\ - {\ - PrintErrorMessage(x, aText);\ - return;\ - }\ - catch(const char *aText)\ - {\ - PrintErrorMessage(x, aText);\ - return;\ - }\ - catch(...)\ - {\ - g_StartupInfo.ShowMessage(x);\ - return;\ - } - -#define MY_TRY_END2(x, y) }\ - catch(int n)\ - {\ - PrintErrorMessage(x, n);\ - return y;\ - }\ - catch(const CSysString &aText)\ - {\ - PrintErrorMessage(x, aText);\ - return y;\ - }\ - catch(const char *aText)\ - {\ - PrintErrorMessage(x, aText);\ - return y;\ - }\ - catch(...)\ - {\ - g_StartupInfo.ShowMessage(x);\ - return y;\ - } - -bool WasEscPressed(); - -void ShowErrorMessage(DWORD aError); -void ShowLastErrorMessage(); - -} - -#endif diff --git a/Far/ProgressBox.cpp b/Far/ProgressBox.cpp deleted file mode 100755 index c37c7ad5..00000000 --- a/Far/ProgressBox.cpp +++ /dev/null @@ -1,101 +0,0 @@ -// ProgressBox.cpp - -#include "StdAfx.h" - -#include "ProgressBox.h" - -#include "FarUtils.h" - -using namespace NFar; - -static void CopySpaces(char *aString, int aNumSpaces) -{ - for(int i = 0; i < aNumSpaces; i++) - aString[i] = ' '; - aString[i] = '\0'; -} - -///////////////////////////////// -// CMessageBox - -const int kNumStringsMax = 10; - -void CMessageBox::Init(const CSysString &aTitle, const CSysString &aMessage, - int aNumStrings, int aWidth) -{ - if (aNumStrings > kNumStringsMax) - throw 120620; - m_NumStrings = aNumStrings; - m_Width = aWidth; - - m_Title = aTitle; - m_Message = aMessage; -} - -const int kNumStaticStrings = 2; - -void CMessageBox::ShowProcessMessages(const char *aMessages[]) -{ - const char *aMsgItems[kNumStaticStrings + kNumStringsMax]; - aMsgItems[0] = m_Title; - aMsgItems[1] = m_Message; - - char aFormattedMessages[kNumStringsMax][256]; - - for (int i = 0; i < m_NumStrings; i++) - { - char *aFormattedMessage = aFormattedMessages[i]; - int aLen = strlen(aMessages[i]); - int aSize = MyMax(m_Width, aLen); - int aStartPos = (aSize - aLen) / 2; - CopySpaces(aFormattedMessage, aStartPos); - strcpy(aFormattedMessage + aStartPos, aMessages[i]); - CopySpaces(aFormattedMessage + aStartPos + aLen, aSize - aStartPos - aLen); - aMsgItems[kNumStaticStrings + i] = aFormattedMessage; - } - - g_StartupInfo.ShowMessage(0, NULL, aMsgItems, kNumStaticStrings + m_NumStrings, 0); -} - -///////////////////////////////// -// CProgressBox - -void CProgressBox::Init(const CSysString &aTitle, const CSysString &aMessage, - UINT64 aStep) -{ - CMessageBox::Init(aTitle, aMessage, 1, 22); - m_Step = aStep; - m_CompletedPrev = 0; - m_Total = 0; -} - - -void CProgressBox::ShowProcessMessage(const char *aMessage) -{ - CMessageBox::ShowProcessMessages(&aMessage); -} - -void CProgressBox::PrintPercent(UINT64 aPercent) -{ - char aValueBuffer[32]; - sprintf(aValueBuffer, "%I64u%%", aPercent); - ShowProcessMessage(aValueBuffer); -} - -void CProgressBox::SetTotal(UINT64 aTotal) -{ - m_Total = aTotal; -} - -void CProgressBox::PrintCompeteValue(UINT64 aCompleted) -{ - if (aCompleted >= m_CompletedPrev + m_Step || aCompleted < m_CompletedPrev || - aCompleted == 0) - { - if (m_Total == 0) - PrintPercent(0); - else - PrintPercent(aCompleted * 100 / m_Total); - m_CompletedPrev = aCompleted; - } -} diff --git a/Far/ProgressBox.h b/Far/ProgressBox.h deleted file mode 100755 index 1878bc39..00000000 --- a/Far/ProgressBox.h +++ /dev/null @@ -1,36 +0,0 @@ -// ProgressBox.h - -#pragma once - -#ifndef __PROGRESSBOX_H -#define __PROGRESSBOX_H - -#include "Common/String.h" - -class CMessageBox -{ - CSysString m_Title; - CSysString m_Message; - int m_NumStrings; - int m_Width; -public: - void Init(const CSysString &aConvertingTitle, - const CSysString &aConvertingMessage, int aNumStrings, int aWidth); - void ShowProcessMessages(const char *aMessages[]); -}; - -class CProgressBox: public CMessageBox -{ - UINT64 m_Total; - UINT64 m_CompletedPrev; - UINT64 m_Step; -public: - void Init(const CSysString &aConvertingTitle, - const CSysString &aConvertingMessage, UINT64 aStep); - void ShowProcessMessage(const char *aMessage); - void PrintPercent(UINT64 aPercent); - void PrintCompeteValue(UINT64 aCompleted); - void SetTotal(UINT64 aTotal); -}; - -#endif diff --git a/Windows/COM.h b/Windows/COM.h index 715d6875..80651406 100755 --- a/Windows/COM.h +++ b/Windows/COM.h @@ -1,7 +1,5 @@ // Windows/COM.h -#pragma once - #ifndef __WINDOWS_COM_H #define __WINDOWS_COM_H diff --git a/Windows/Console.h b/Windows/Console.h index edd4e52c..b4e6d35b 100755 --- a/Windows/Console.h +++ b/Windows/Console.h @@ -3,8 +3,6 @@ #ifndef __WINDOWS_CONSOLE_H #define __WINDOWS_CONSOLE_H -#pragma once - #include "Windows/Defs.h" namespace NWindows{ diff --git a/Windows/Control/ComboBox.h b/Windows/Control/ComboBox.h index 864dbfbc..7ff12c38 100755 --- a/Windows/Control/ComboBox.h +++ b/Windows/Control/ComboBox.h @@ -1,7 +1,5 @@ // Windows/Control/ComboBox.h -#pragma once - #ifndef __WINDOWS_CONTROL_COMBOBOX_H #define __WINDOWS_CONTROL_COMBOBOX_H diff --git a/Windows/Control/Dialog.h b/Windows/Control/Dialog.h index e59cf4b3..154c4988 100755 --- a/Windows/Control/Dialog.h +++ b/Windows/Control/Dialog.h @@ -1,7 +1,5 @@ // Windows/Control/Dialog.h -#pragma once - #ifndef __WINDOWS_CONTROL_DIALOG_H #define __WINDOWS_CONTROL_DIALOG_H diff --git a/Windows/Control/Edit.h b/Windows/Control/Edit.h index a7c7bb99..d1af3644 100755 --- a/Windows/Control/Edit.h +++ b/Windows/Control/Edit.h @@ -1,7 +1,5 @@ // Windows/Control/Edit.h -#pragma once - #ifndef __WINDOWS_CONTROL_EDIT_H #define __WINDOWS_CONTROL_EDIT_H diff --git a/Windows/Control/ImageList.h b/Windows/Control/ImageList.h index 26a3f25c..fc8ddfbd 100755 --- a/Windows/Control/ImageList.h +++ b/Windows/Control/ImageList.h @@ -1,7 +1,5 @@ // Windows/Control/ImageList.h -#pragma once - #ifndef __WINDOWS_CONTROL_IMAGELIST_H #define __WINDOWS_CONTROL_IMAGELIST_H diff --git a/Windows/Control/ListView.h b/Windows/Control/ListView.h index 6f446884..dad175b6 100755 --- a/Windows/Control/ListView.h +++ b/Windows/Control/ListView.h @@ -1,7 +1,5 @@ // Windows/Control/ListView.h -#pragma once - #ifndef __WINDOWS_CONTROL_LISTVIEW_H #define __WINDOWS_CONTROL_LISTVIEW_H diff --git a/Windows/Control/ProgressBar.h b/Windows/Control/ProgressBar.h index 0785eba1..89550afa 100755 --- a/Windows/Control/ProgressBar.h +++ b/Windows/Control/ProgressBar.h @@ -1,7 +1,5 @@ // Windows/Control/ProgressBar.h -#pragma once - #ifndef __WINDOWS_CONTROL_PROGRESSBAR_H #define __WINDOWS_CONTROL_PROGRESSBAR_H diff --git a/Windows/Control/PropertyPage.h b/Windows/Control/PropertyPage.h index 2f7b4e82..94a0e99d 100755 --- a/Windows/Control/PropertyPage.h +++ b/Windows/Control/PropertyPage.h @@ -1,7 +1,5 @@ // Windows/Control/PropertyPage.h -#pragma once - #ifndef __WINDOWS_CONTROL_PROPERTYPAGE_H #define __WINDOWS_CONTROL_PROPERTYPAGE_H diff --git a/Windows/Control/ReBar.h b/Windows/Control/ReBar.h index 6dfb3b4e..9475d5b4 100755 --- a/Windows/Control/ReBar.h +++ b/Windows/Control/ReBar.h @@ -1,7 +1,5 @@ // Windows/Control/ReBar.h -#pragma once - #ifndef __WINDOWS_CONTROL_REBAR_H #define __WINDOWS_CONTROL_REBAR_H diff --git a/Windows/Control/Static.h b/Windows/Control/Static.h index ba8a3a72..5dded0ec 100755 --- a/Windows/Control/Static.h +++ b/Windows/Control/Static.h @@ -1,7 +1,5 @@ // Windows/Control/Static.h -#pragma once - #ifndef __WINDOWS_CONTROL_STATIC_H #define __WINDOWS_CONTROL_STATIC_H diff --git a/Windows/Control/StatusBar.h b/Windows/Control/StatusBar.h index fa277259..e9527192 100755 --- a/Windows/Control/StatusBar.h +++ b/Windows/Control/StatusBar.h @@ -1,6 +1,4 @@ // Windows/Control/StatusBar.h - -#pragma once #ifndef __WINDOWS_CONTROL_STATUSBAR_H #define __WINDOWS_CONTROL_STATUSBAR_H diff --git a/Windows/Control/ToolBar.h b/Windows/Control/ToolBar.h index 22d72377..169e2dd2 100755 --- a/Windows/Control/ToolBar.h +++ b/Windows/Control/ToolBar.h @@ -1,7 +1,5 @@ // Windows/Control/ToolBar.h -#pragma once - #ifndef __WINDOWS_CONTROL_TOOLBAR_H #define __WINDOWS_CONTROL_TOOLBAR_H diff --git a/Windows/Control/Trackbar.h b/Windows/Control/Trackbar.h index 8f1b46ee..bbd7009a 100755 --- a/Windows/Control/Trackbar.h +++ b/Windows/Control/Trackbar.h @@ -1,7 +1,5 @@ // Windows/Control/Trackbar.h -#pragma once - #ifndef __WINDOWS_CONTROL_TRACKBAR_H #define __WINDOWS_CONTROL_TRACKBAR_H diff --git a/Windows/Control/Window2.h b/Windows/Control/Window2.h index 3a8b814e..8c9a9274 100755 --- a/Windows/Control/Window2.h +++ b/Windows/Control/Window2.h @@ -1,7 +1,5 @@ // Windows/Control/Window2.h -#pragma once - #ifndef __WINDOWS_CONTROL_WINDOW2_H #define __WINDOWS_CONTROL_WINDOW2_H diff --git a/Windows/DLL.h b/Windows/DLL.h index a4209ac9..83061958 100755 --- a/Windows/DLL.h +++ b/Windows/DLL.h @@ -3,8 +3,6 @@ #ifndef __WINDOWS_DLL_H #define __WINDOWS_DLL_H -#pragma once - #include "../Common/String.h" namespace NWindows { diff --git a/Windows/Defs.h b/Windows/Defs.h index 1e1aecd5..c0038d61 100755 --- a/Windows/Defs.h +++ b/Windows/Defs.h @@ -1,7 +1,5 @@ // Windows/Defs.h -#pragma once - #ifndef __WINDOWS_DEFS_H #define __WINDOWS_DEFS_H @@ -17,7 +15,4 @@ inline VARIANT_BOOL BoolToVARIANT_BOOL(bool value) inline bool VARIANT_BOOLToBool(VARIANT_BOOL value) { return (value != VARIANT_FALSE); } -// #define RETURN_IF_NOT_S_OK(x) { HRESULT __result_ = (x); if(__result_ != S_OK) return __result_; } -// #define RINOK(x) { HRESULT __result_ = (x); if(__result_ != S_OK) return __result_; } - #endif diff --git a/Windows/Error.h b/Windows/Error.h index d42a1116..4d9a9fa6 100755 --- a/Windows/Error.h +++ b/Windows/Error.h @@ -1,7 +1,5 @@ // Windows/Error.h -#pragma once - #ifndef __WINDOWS_ERROR_H #define __WINDOWS_ERROR_H diff --git a/Windows/FileDir.h b/Windows/FileDir.h index 07e2a0b2..7572fee7 100755 --- a/Windows/FileDir.h +++ b/Windows/FileDir.h @@ -1,7 +1,5 @@ // Windows/FileDir.h -#pragma once - #ifndef __WINDOWS_FILEDIR_H #define __WINDOWS_FILEDIR_H diff --git a/Windows/FileFind.cpp b/Windows/FileFind.cpp index 27e405f4..36694593 100755 --- a/Windows/FileFind.cpp +++ b/Windows/FileFind.cpp @@ -221,6 +221,17 @@ bool CEnumerator::Next(CFileInfo &fileInfo) } } +bool CEnumerator::Next(CFileInfo &fileInfo, bool &found) +{ + if (Next(fileInfo)) + { + found = true; + return true; + } + found = false; + return (::GetLastError() == ERROR_NO_MORE_FILES); +} + #ifndef _UNICODE bool CEnumeratorW::NextAny(CFileInfoW &fileInfo) { @@ -240,6 +251,18 @@ bool CEnumeratorW::Next(CFileInfoW &fileInfo) return true; } } + +bool CEnumeratorW::Next(CFileInfoW &fileInfo, bool &found) +{ + if (Next(fileInfo)) + { + found = true; + return true; + } + found = false; + return (::GetLastError() == ERROR_NO_MORE_FILES); +} + #endif //////////////////////////////// diff --git a/Windows/FileFind.h b/Windows/FileFind.h index 0ff24a92..d25ac7ce 100755 --- a/Windows/FileFind.h +++ b/Windows/FileFind.h @@ -1,7 +1,5 @@ // Windows/FileFind.h -#pragma once - #ifndef __WINDOWS_FILEFIND_H #define __WINDOWS_FILEFIND_H @@ -109,6 +107,7 @@ public: CEnumerator(): _wildcard(NName::kAnyStringWildcard) {} CEnumerator(const CSysString &wildcard): _wildcard(wildcard) {} bool Next(CFileInfo &fileInfo); + bool Next(CFileInfo &fileInfo, bool &found); }; #ifdef _UNICODE @@ -123,6 +122,7 @@ public: CEnumeratorW(): _wildcard(NName::kAnyStringWildcard) {} CEnumeratorW(const UString &wildcard): _wildcard(wildcard) {} bool Next(CFileInfoW &fileInfo); + bool Next(CFileInfoW &fileInfo, bool &found); }; #endif diff --git a/Windows/FileIO.cpp b/Windows/FileIO.cpp index 7b7c960c..67a2397b 100755 --- a/Windows/FileIO.cpp +++ b/Windows/FileIO.cpp @@ -158,13 +158,22 @@ bool CInFile::Read(void *data, UINT32 size, UINT32 &processedSize) bool COutFile::Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes) { - return Create(fileName, GENERIC_WRITE, shareMode, + return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); } -bool COutFile::Open(LPCTSTR fileName) +static inline DWORD GetCreationDisposition(bool createAlways) + { return createAlways? CREATE_ALWAYS: CREATE_NEW; } + +bool COutFile::Open(LPCTSTR fileName, DWORD creationDisposition) +{ + return Open(fileName, FILE_SHARE_READ, + creationDisposition, FILE_ATTRIBUTE_NORMAL); +} + +bool COutFile::Create(LPCTSTR fileName, bool createAlways) { - return Open(fileName, FILE_SHARE_READ, m_CreationDisposition, FILE_ATTRIBUTE_NORMAL); + return Open(fileName, GetCreationDisposition(createAlways)); } #ifndef _UNICODE @@ -172,13 +181,19 @@ bool COutFile::Open(LPCTSTR fileName) bool COutFile::Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes) { - return Create(fileName, GENERIC_WRITE, shareMode, + return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); } -bool COutFile::Open(LPCWSTR fileName) +bool COutFile::Open(LPCWSTR fileName, DWORD creationDisposition) +{ + return Open(fileName, FILE_SHARE_READ, + creationDisposition, FILE_ATTRIBUTE_NORMAL); +} + +bool COutFile::Create(LPCWSTR fileName, bool createAlways) { - return Open(fileName, FILE_SHARE_READ, m_CreationDisposition, FILE_ATTRIBUTE_NORMAL); + return Open(fileName, GetCreationDisposition(createAlways)); } #endif diff --git a/Windows/FileIO.h b/Windows/FileIO.h index a8360c0c..36f69df7 100755 --- a/Windows/FileIO.h +++ b/Windows/FileIO.h @@ -1,7 +1,5 @@ // Windows/FileIO.h -#pragma once - #ifndef __WINDOWS_FILEIO_H #define __WINDOWS_FILEIO_H @@ -67,23 +65,27 @@ public: class COutFile: public CFileBase { - DWORD m_CreationDisposition; + // DWORD m_CreationDisposition; public: - COutFile(): m_CreationDisposition(CREATE_NEW){}; + // COutFile(): m_CreationDisposition(CREATE_NEW){}; bool Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes); - bool Open(LPCTSTR fileName); + bool Open(LPCTSTR fileName, DWORD creationDisposition); + bool Create(LPCTSTR fileName, bool createAlways); #ifndef _UNICODE bool Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes); - bool Open(LPCWSTR fileName); + bool Open(LPCWSTR fileName, DWORD creationDisposition); + bool Create(LPCWSTR fileName, bool createAlways); #endif + /* void SetOpenCreationDisposition(DWORD creationDisposition) { m_CreationDisposition = creationDisposition; } void SetOpenCreationDispositionCreateAlways() { m_CreationDisposition = CREATE_ALWAYS; } + */ bool SetTime(const FILETIME *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime); diff --git a/Windows/FileMapping.h b/Windows/FileMapping.h index 7d201597..22db8f17 100755 --- a/Windows/FileMapping.h +++ b/Windows/FileMapping.h @@ -1,7 +1,5 @@ // Windows/FileMapping.h -#pragma once - #ifndef __WINDOWS_FILEMAPPING_H #define __WINDOWS_FILEMAPPING_H diff --git a/Windows/FileName.cpp b/Windows/FileName.cpp index 945caef8..49e957cf 100755 --- a/Windows/FileName.cpp +++ b/Windows/FileName.cpp @@ -3,7 +3,7 @@ #include "StdAfx.h" #include "Windows/FileName.h" -#include "Common/WildCard.h" +#include "Common/Wildcard.h" namespace NWindows { namespace NFile { diff --git a/Windows/FileName.h b/Windows/FileName.h index 8adf684c..255c06c0 100755 --- a/Windows/FileName.h +++ b/Windows/FileName.h @@ -1,7 +1,5 @@ // Windows/FileName.h -#pragma once - #ifndef __WINDOWS_FILENAME_H #define __WINDOWS_FILENAME_H diff --git a/Windows/FileSystem.h b/Windows/FileSystem.h index 5a630d95..62f50d40 100755 --- a/Windows/FileSystem.h +++ b/Windows/FileSystem.h @@ -1,7 +1,5 @@ // Windows/FileSystem.h -#pragma once - #ifndef __WINDOWS_FILESYSTEM_H #define __WINDOWS_FILESYSTEM_H diff --git a/Windows/Handle.h b/Windows/Handle.h index 66c893e9..d4d8aae5 100755 --- a/Windows/Handle.h +++ b/Windows/Handle.h @@ -1,7 +1,5 @@ // Windows/Handle.h -#pragma once - #ifndef __WINDOWS_HANDLE_H #define __WINDOWS_HANDLE_H diff --git a/Windows/ItemIDListUtils.cpp b/Windows/ItemIDListUtils.cpp deleted file mode 100755 index a429464e..00000000 --- a/Windows/ItemIDListUtils.cpp +++ /dev/null @@ -1,166 +0,0 @@ -// ItemIDListUtils.h - -#include "StdAfx.h" - -#include "ItemIDListUtils.h" - -namespace NItemIDList { - -CHolder::CHolder(const CHolder& anItemIDList): - m_Object(NULL) -{ - *this = anItemIDList; -} - -bool CHolder::Create(UINT16 aPureSize) -{ - Free(); - m_Object = LPITEMIDLIST(CoTaskMemAlloc(2 + aPureSize + 2)); - if(m_Object == NULL) - return false; - m_Object->mkid.cb = 2 + aPureSize; - LPITEMIDLIST aNewIDListEnd = LPITEMIDLIST(((BYTE *)m_Object) + 2 + aPureSize); - aNewIDListEnd->mkid.cb = 0; - return (m_Object != NULL); -} - -void CHolder::Free() -{ - if(m_Object == NULL) - return; - CoTaskMemFree(m_Object); - m_Object = NULL; -} - -CHolder& CHolder::operator=(LPCITEMIDLIST anObject) -{ - if(m_Object != NULL) - Free(); - UINT32 aSize = GetSize(anObject); - m_Object = (LPITEMIDLIST)CoTaskMemAlloc(aSize); - if(m_Object != NULL) - MoveMemory(m_Object, anObject, aSize); - return *this; -} - -CHolder& CHolder::operator=(const CHolder &anObject) -{ - if(m_Object != NULL) - Free(); - if(anObject.m_Object != NULL) - { - UINT32 aSize = GetSize(anObject.m_Object); - m_Object = (LPITEMIDLIST)CoTaskMemAlloc(aSize); - if(m_Object != NULL) - MoveMemory(m_Object, anObject.m_Object, aSize); - } - return *this; -} - -//////////////////////// -// static - -LPITEMIDLIST GetNextItem(LPCITEMIDLIST anIDList) -{ - if (anIDList) - return (LPITEMIDLIST)(LPBYTE) ( ((LPBYTE)anIDList) + anIDList->mkid.cb); - return (NULL); -} - -UINT32 GetSize(LPCITEMIDLIST anIDList) -{ - UINT32 aSizeTotal = 0; - if(anIDList != NULL) - { - while(anIDList->mkid.cb != 0) - { - aSizeTotal += anIDList->mkid.cb; - anIDList = GetNextItem(anIDList); - } - aSizeTotal += sizeof(ITEMIDLIST) - 1; - } - return (aSizeTotal); -} - -LPITEMIDLIST GetLastItem(LPCITEMIDLIST anIDList) -{ - LPITEMIDLIST anIDListLast = NULL; - if(anIDList) - while(anIDList->mkid.cb != 0) - { - anIDListLast = (LPITEMIDLIST)anIDList; - anIDList = GetNextItem(anIDList); - } - return anIDListLast; -} - -} - -//////////////////////////////////////////////////////////////// -// CItemIDListManager : Class to manage pidls - -CItemIDListManager::CItemIDListManager(): - m_pMalloc(NULL) -{ - SHGetMalloc(&m_pMalloc); -} - -CItemIDListManager::~CItemIDListManager() -{ - if (m_pMalloc) - m_pMalloc->Release(); -} - -LPITEMIDLIST CItemIDListManager::Create(UINT16 aPureSize) -{ - LPITEMIDLIST aPointer = LPITEMIDLIST(m_pMalloc->Alloc(2 + aPureSize + 2)); - if(aPointer == NULL) - return NULL; - aPointer->mkid.cb = 2 + aPureSize; - LPITEMIDLIST aNewIDListEnd = LPITEMIDLIST(((BYTE *)aPointer) + 2 + aPureSize); - aNewIDListEnd->mkid.cb = 0; - return aPointer; -} - -void CItemIDListManager::Delete(LPITEMIDLIST anIDList) -{ - m_pMalloc->Free(anIDList); -} - -LPITEMIDLIST CItemIDListManager::Copy(LPCITEMIDLIST anIDListSrc) -{ - if (NULL == anIDListSrc) - return (NULL); - LPITEMIDLIST anIDListTarget = NULL; - UINT32 aSize = NItemIDList::GetSize(anIDListSrc); - anIDListTarget = (LPITEMIDLIST)m_pMalloc->Alloc(aSize); - if (!anIDListTarget) - return (NULL); - MoveMemory(anIDListTarget, anIDListSrc, aSize); - return anIDListTarget; -} - -LPITEMIDLIST CItemIDListManager::Concatenate(LPCITEMIDLIST anIDList1, - LPCITEMIDLIST anIDList2) -{ - if(!anIDList1 && !anIDList2) - return NULL; - - if(!anIDList1) - return Copy(anIDList2); - - if(!anIDList2) - return Copy(anIDList1); - - UINT32 cb1 = NItemIDList::GetSize(anIDList1) - 2; - UINT32 cb2 = NItemIDList::GetSize(anIDList2); - - LPITEMIDLIST anIDListNew = (LPITEMIDLIST)m_pMalloc->Alloc(cb1 + cb2); - - if(anIDListNew) - { - MoveMemory(anIDListNew, anIDList1, cb1); - MoveMemory(((LPBYTE)anIDListNew) + cb1, anIDList2, cb2); - } - return anIDListNew; -} diff --git a/Windows/ItemIDListUtils.h b/Windows/ItemIDListUtils.h deleted file mode 100755 index 53721d41..00000000 --- a/Windows/ItemIDListUtils.h +++ /dev/null @@ -1,98 +0,0 @@ -// ItemIDListUtils.h - -#pragma once - -#ifndef __ITEMIDLISTUTILS_H -#define __ITEMIDLISTUTILS_H - -#include "Common/Types.h" - -///////////////////////////// -// It is not for shell using -// It's for internal using only -// since it uses CoTaskMemFree instead SHGetMalloc - -namespace NItemIDList { - -LPITEMIDLIST GetNextItem(LPCITEMIDLIST anIDList); -UINT32 GetSize(LPCITEMIDLIST anIDList); -LPITEMIDLIST GetLastItem(LPCITEMIDLIST anIDList); - -class CHolder -{ - LPITEMIDLIST m_Object; -public: - CHolder(): m_Object(NULL) {} - CHolder(const CHolder& anItemIDList); - ~CHolder() { Free(); } - void Attach(LPITEMIDLIST anObject) - { - if (m_Object != NULL) - Free(); - m_Object = anObject; - } - LPITEMIDLIST Detach() - { - LPITEMIDLIST anObject = m_Object; - m_Object = NULL; - return anObject; - } - void Free(); - bool Create(UINT16 aPureSize); - operator LPITEMIDLIST() { return m_Object;} - operator LPCITEMIDLIST() const { return m_Object;} - LPITEMIDLIST* operator&() { return &m_Object; } - LPITEMIDLIST operator->() { return m_Object; } - - CHolder& operator=(LPCITEMIDLIST anObject); - CHolder& operator=(const CHolder &anObject); -}; - -} - -class CItemIDListManager -{ -public: - CItemIDListManager(); - ~CItemIDListManager(); -public: - LPITEMIDLIST Create(UINT16 aPureSize); - void Delete(LPITEMIDLIST anIDList); - LPITEMIDLIST Copy(LPCITEMIDLIST anIDListSrc); - // CZipIDData* GetDataPointer(LPCITEMIDLIST anIDList); - LPITEMIDLIST Concatenate(LPCITEMIDLIST anIDList1, LPCITEMIDLIST anIDList2); -private: - LPMALLOC m_pMalloc; -}; - -class CShellItemIDList -{ - CItemIDListManager *m_Manager; - LPITEMIDLIST m_Object; -public: - CShellItemIDList(CItemIDListManager *aManager): - m_Manager(aManager), - m_Object(NULL) {} - bool Create(UINT16 aPureSize) - { - Free(); - m_Object = m_Manager->Create(aPureSize); - return (m_Object != NULL); - } - ~CShellItemIDList() { Free(); } - void Free() - { - if(m_Object != NULL) - m_Manager->Delete(m_Object); - m_Object = NULL; - } - void Attach(LPITEMIDLIST anObject) - { - Free(); - m_Object = anObject; - } - operator LPITEMIDLIST() { return m_Object;} - LPITEMIDLIST* operator&() { return &m_Object; } -}; - -#endif
\ No newline at end of file diff --git a/Windows/Memory.h b/Windows/Memory.h index 1a8dde45..7aa958bd 100755 --- a/Windows/Memory.h +++ b/Windows/Memory.h @@ -1,7 +1,5 @@ // Windows/Memory.h -#pragma once - #ifndef __WINDOWS_MEMORY_H #define __WINDOWS_MEMORY_H diff --git a/Windows/Menu.h b/Windows/Menu.h index 55d33447..69b20601 100755 --- a/Windows/Menu.h +++ b/Windows/Menu.h @@ -1,7 +1,5 @@ // Windows/Menu.h -#pragma once - #ifndef __WINDOWS_MENU_H #define __WINDOWS_MENU_H diff --git a/Windows/NationalTime.h b/Windows/NationalTime.h index 70d5967d..4e40f84a 100755 --- a/Windows/NationalTime.h +++ b/Windows/NationalTime.h @@ -1,7 +1,5 @@ // Windows/NationalTime.h -#pragma once - #ifndef __WINDOWS_NATIONALTIME_H #define __WINDOWS_NATIONALTIME_H diff --git a/Windows/Net.h b/Windows/Net.h index ead481be..0f7f6f85 100755 --- a/Windows/Net.h +++ b/Windows/Net.h @@ -1,7 +1,5 @@ // Windows/Net.h -#pragma once - #ifndef __WINDOWS_NET_H #define __WINDOWS_NET_H diff --git a/Windows/ProcessMessages.h b/Windows/ProcessMessages.h index 76643a9f..63f8ec8a 100755 --- a/Windows/ProcessMessages.h +++ b/Windows/ProcessMessages.h @@ -1,7 +1,5 @@ // Windows/ProcessMessages.h -#pragma once - #ifndef __WINDOWS_PROCESSMESSAGES_H #define __WINDOWS_PROCESSMESSAGES_H diff --git a/Windows/PropVariant.cpp b/Windows/PropVariant.cpp index 39a412d9..82d71457 100755 --- a/Windows/PropVariant.cpp +++ b/Windows/PropVariant.cpp @@ -33,8 +33,6 @@ CPropVariant::CPropVariant(LPCOLESTR lpszSrc) *this = lpszSrc; } -/////////////////////////// -// Assignment Operators CPropVariant& CPropVariant::operator=(const CPropVariant& varSrc) { InternalCopy(&varSrc); @@ -48,14 +46,7 @@ CPropVariant& CPropVariant::operator=(const PROPVARIANT& varSrc) CPropVariant& CPropVariant::operator=(BSTR bstrSrc) { - InternalClear(); - vt = VT_BSTR; - bstrVal = ::SysAllocString(bstrSrc); - if (bstrVal == NULL && bstrSrc != NULL) - { - vt = VT_ERROR; - scode = E_OUTOFMEMORY; - } + *this = (LPCOLESTR)bstrSrc; return *this; } @@ -64,7 +55,6 @@ CPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc) InternalClear(); vt = VT_BSTR; bstrVal = ::SysAllocString(lpszSrc); - if (bstrVal == NULL && lpszSrc != NULL) { vt = VT_ERROR; @@ -85,7 +75,7 @@ CPropVariant& CPropVariant::operator=(bool bSrc) return *this; } -CPropVariant& CPropVariant::operator=(UINT32 value) +CPropVariant& CPropVariant::operator=(UInt32 value) { if (vt != VT_UI4) { @@ -96,14 +86,14 @@ CPropVariant& CPropVariant::operator=(UINT32 value) return *this; } -CPropVariant& CPropVariant::operator=(UINT64 value) +CPropVariant& CPropVariant::operator=(UInt64 value) { if (vt != VT_UI8) { InternalClear(); vt = VT_UI8; } - uhVal = *(ULARGE_INTEGER*)&value; + uhVal.QuadPart = value; return *this; } @@ -118,7 +108,7 @@ CPropVariant& CPropVariant::operator=(const FILETIME &value) return *this; } -CPropVariant& CPropVariant::operator=(int value) +CPropVariant& CPropVariant::operator=(Int32 value) { if (vt != VT_I4) { @@ -130,7 +120,7 @@ CPropVariant& CPropVariant::operator=(int value) return *this; } -CPropVariant& CPropVariant::operator=(BYTE value) +CPropVariant& CPropVariant::operator=(Byte value) { if (vt != VT_UI1) { @@ -141,7 +131,7 @@ CPropVariant& CPropVariant::operator=(BYTE value) return *this; } -CPropVariant& CPropVariant::operator=(short value) +CPropVariant& CPropVariant::operator=(Int16 value) { if (vt != VT_I2) { @@ -163,9 +153,9 @@ CPropVariant& CPropVariant::operator=(long value) return *this; } -static HRESULT MyPropVariantClear(PROPVARIANT *aPropVariant) +static HRESULT MyPropVariantClear(PROPVARIANT *propVariant) { - switch(aPropVariant->vt) + switch(propVariant->vt) { case VT_UI1: case VT_I1: @@ -183,10 +173,10 @@ static HRESULT MyPropVariantClear(PROPVARIANT *aPropVariant) case VT_R8: case VT_CY: case VT_DATE: - aPropVariant->vt = VT_EMPTY; + propVariant->vt = VT_EMPTY; return S_OK; } - return ::VariantClear((tagVARIANT *)aPropVariant); + return ::VariantClear((VARIANTARG *)propVariant); } HRESULT CPropVariant::Clear() @@ -215,7 +205,7 @@ HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc) case VT_R8: case VT_CY: case VT_DATE: - MoveMemory((PROPVARIANT*)this, pSrc, sizeof(PROPVARIANT)); + memmove((PROPVARIANT*)this, pSrc, sizeof(PROPVARIANT)); return S_OK; } return ::VariantCopy((tagVARIANT *)this, (tagVARIANT *)(pSrc)); @@ -224,41 +214,22 @@ HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc) HRESULT CPropVariant::Attach(PROPVARIANT* pSrc) { - // Clear out the variant HRESULT hr = Clear(); - if (!FAILED(hr)) - { - // Copy the contents and give control to CPropVariant - memcpy(this, pSrc, sizeof(PROPVARIANT)); - pSrc->vt = VT_EMPTY; - hr = S_OK; - } - return hr; + if (FAILED(hr)) + return hr; + memcpy(this, pSrc, sizeof(PROPVARIANT)); + pSrc->vt = VT_EMPTY; + return S_OK; } HRESULT CPropVariant::Detach(PROPVARIANT* pDest) { - // Clear out the variant HRESULT hr = MyPropVariantClear(pDest); - // HRESULT hr = ::VariantClear((VARIANT* )pDest); - if (!FAILED(hr)) - { - // Copy the contents and remove control from CPropVariant - memcpy(pDest, this, sizeof(PROPVARIANT)); - vt = VT_EMPTY; - hr = S_OK; - } - return hr; -} - -HRESULT CPropVariant::ChangeType(VARTYPE vtNew, const PROPVARIANT* pSrc) -{ - PROPVARIANT* pVar = const_cast<PROPVARIANT*>(pSrc); - // Convert in place if pSrc is NULL - if (pVar == NULL) - pVar = this; - // Do nothing if doing in place convert and vts not different - return ::VariantChangeType((VARIANT *)this, (VARIANT *)pVar, 0, vtNew); + if (FAILED(hr)) + return hr; + memcpy(pDest, this, sizeof(PROPVARIANT)); + vt = VT_EMPTY; + return S_OK; } HRESULT CPropVariant::InternalClear() @@ -282,148 +253,6 @@ void CPropVariant::InternalCopy(const PROPVARIANT* pSrc) } } -HRESULT CPropVariant::WriteToStream(ISequentialStream *stream) const -{ - HRESULT aResult = stream->Write(&vt, sizeof(vt), NULL); - if (FAILED(aResult)) - return aResult; - - if (vt == VT_EMPTY) - return S_OK; - - int aNumBytes = 0; - switch (vt) - { - case VT_UI1: - case VT_I1: - aNumBytes = sizeof(BYTE); - break; - case VT_I2: - case VT_UI2: - case VT_BOOL: - aNumBytes = sizeof(short); - break; - case VT_I4: - case VT_UI4: - case VT_R4: - case VT_INT: - case VT_UINT: - case VT_ERROR: - aNumBytes = sizeof(long); - break; - case VT_FILETIME: - case VT_UI8: - case VT_R8: - case VT_CY: - case VT_DATE: - aNumBytes = sizeof(double); - break; - default: - break; - } - if (aNumBytes != 0) - return stream->Write(&bVal, aNumBytes, NULL); - - if (vt == VT_BSTR) - { - UINT32 aLen = 0; - if(bstrVal != NULL) - aLen = SysStringLen(bstrVal); - HRESULT aResult = stream->Write(&aLen, sizeof(UINT32), NULL); - if (FAILED(aResult)) - return aResult; - if(bstrVal == NULL) - return S_OK; - if(aLen == 0) - return S_OK; - return stream->Write(bstrVal, aLen * sizeof(wchar_t), NULL); - } - else - { - return E_FAIL; - /* - CPropVariant varBSTR; - HRESULT hr = VariantChangeType(&varBSTR, this, VARIANT_NOVALUEPROP, VT_BSTR); - if (FAILED(hr)) - return; - MoveMemory(aMemoryPointer, varBSTR.bstrVal, SysStringLen(varBSTR.bstrVal)); - */ - } -} - -HRESULT CPropVariant::ReadFromStream(ISequentialStream *stream) -{ - HRESULT hr = Clear(); - if (FAILED(hr)) - return hr; - - VARTYPE vtRead; - hr = stream->Read(&vtRead, sizeof(VARTYPE), NULL); - if (hr == S_FALSE) - hr = E_FAIL; - if (FAILED(hr)) - return hr; - - vt = vtRead; - if (vt == VT_EMPTY) - return S_OK; - int aNumBytes = 0; - switch (vt) - { - case VT_UI1: - case VT_I1: - aNumBytes = sizeof(BYTE); - break; - case VT_I2: - case VT_UI2: - case VT_BOOL: - aNumBytes = sizeof(short); - break; - case VT_I4: - case VT_UI4: - case VT_R4: - case VT_INT: - case VT_UINT: - case VT_ERROR: - aNumBytes = sizeof(long); - break; - case VT_FILETIME: - case VT_UI8: - case VT_R8: - case VT_CY: - case VT_DATE: - aNumBytes = sizeof(double); - break; - default: - break; - } - if (aNumBytes != 0) - { - hr = stream->Read(&bVal, aNumBytes, NULL); - if (hr == S_FALSE) - hr = E_FAIL; - return hr; - } - - if (vt == VT_BSTR) - { - bstrVal = NULL; - UINT32 aLen = 0; - hr = stream->Read(&aLen, sizeof(UINT32), NULL); - if (hr != S_OK) - return E_FAIL; - bstrVal = SysAllocStringLen(NULL, aLen); - if(bstrVal == NULL) - return E_OUTOFMEMORY; - hr = stream->Read(bstrVal, aLen * sizeof(wchar_t), NULL); - if (hr == S_FALSE) - hr = E_FAIL; - return hr; - } - else - return E_FAIL; -} - int CPropVariant::Compare(const CPropVariant &a) { if(vt != a.vt) @@ -458,12 +287,12 @@ int CPropVariant::Compare(const CPropVariant &a) return MyCompare(uintVal, a.uintVal); */ case VT_I8: - return MyCompare(INT64(*(const INT64 *)&hVal), INT64(*(const INT64 *)&a.hVal)); + return MyCompare(hVal.QuadPart, a.hVal.QuadPart); case VT_UI8: - return MyCompare(UINT64(*(const UINT64 *)&uhVal), UINT64(*(const UINT64 *)&a.uhVal)); + return MyCompare(uhVal.QuadPart, a.uhVal.QuadPart); case VT_BOOL: - return -MyCompare(boolVal, a.boolVal); // Test it + return -MyCompare(boolVal, a.boolVal); case VT_FILETIME: return ::CompareFileTime(&filetime, &a.filetime); diff --git a/Windows/PropVariant.h b/Windows/PropVariant.h index 44fd74f5..548ed6fe 100755 --- a/Windows/PropVariant.h +++ b/Windows/PropVariant.h @@ -1,10 +1,11 @@ // Windows/PropVariant.h -// #pragma once - #ifndef __WINDOWS_PROPVARIANT_H #define __WINDOWS_PROPVARIANT_H +#include "../Common/MyWindows.h" +#include "../Common/Types.h" + namespace NWindows { namespace NCOM { @@ -18,12 +19,12 @@ public: CPropVariant(BSTR bstrSrc); CPropVariant(LPCOLESTR lpszSrc); CPropVariant(bool bSrc) { vt = VT_BOOL; boolVal = (bSrc ? VARIANT_TRUE : VARIANT_FALSE); }; - CPropVariant(UINT32 value) { vt = VT_UI4; ulVal = value; } - CPropVariant(UINT64 value) { vt = VT_UI8; uhVal = *(ULARGE_INTEGER*)&value; } + CPropVariant(UInt32 value) { vt = VT_UI4; ulVal = value; } + CPropVariant(UInt64 value) { vt = VT_UI8; uhVal = *(ULARGE_INTEGER*)&value; } CPropVariant(const FILETIME &value) { vt = VT_FILETIME; filetime = value; } - CPropVariant(int value) { vt = VT_I4; lVal = value; } - CPropVariant(BYTE value) { vt = VT_UI1; bVal = value; } - CPropVariant(short value) { vt = VT_I2; iVal = value; } + CPropVariant(Int32 value) { vt = VT_I4; lVal = value; } + CPropVariant(Byte value) { vt = VT_UI1; bVal = value; } + CPropVariant(Int16 value) { vt = VT_I2; iVal = value; } CPropVariant(long value, VARTYPE vtSrc = VT_I4) { vt = vtSrc; lVal = value; } CPropVariant& operator=(const CPropVariant& varSrc); @@ -31,27 +32,23 @@ public: CPropVariant& operator=(BSTR bstrSrc); CPropVariant& operator=(LPCOLESTR lpszSrc); CPropVariant& operator=(bool bSrc); - CPropVariant& operator=(UINT32 value); - CPropVariant& operator=(UINT64 value); + CPropVariant& operator=(UInt32 value); + CPropVariant& operator=(UInt64 value); CPropVariant& operator=(const FILETIME &value); - CPropVariant& operator=(int value); - CPropVariant& operator=(BYTE value); - CPropVariant& operator=(short value); + CPropVariant& operator=(Int32 value); + CPropVariant& operator=(Byte value); + CPropVariant& operator=(Int16 value); CPropVariant& operator=(long value); HRESULT Clear(); HRESULT Copy(const PROPVARIANT* pSrc); HRESULT Attach(PROPVARIANT* pSrc); HRESULT Detach(PROPVARIANT* pDest); - HRESULT ChangeType(VARTYPE vtNew, const PROPVARIANT* pSrc = NULL); HRESULT InternalClear(); void InternalCopy(const PROPVARIANT* pSrc); - HRESULT WriteToStream(ISequentialStream *stream) const; - HRESULT ReadFromStream(ISequentialStream *stream); - int Compare(const CPropVariant &a1); }; diff --git a/Windows/PropVariantConversions.cpp b/Windows/PropVariantConversions.cpp index 15652693..f7743d6e 100755 --- a/Windows/PropVariantConversions.cpp +++ b/Windows/PropVariantConversions.cpp @@ -2,6 +2,8 @@ #include "StdAfx.h" +#include <stdio.h> + #include "PropVariantConversions.h" #include "Windows/NationalTime.h" @@ -12,70 +14,75 @@ using namespace NWindows; -static UString ConvertUINT64ToString(UINT64 value) +static UString ConvertUInt64ToString(UInt64 value) { wchar_t buffer[32]; - ConvertUINT64ToString(value, buffer); + ConvertUInt64ToString(value, buffer); return buffer; } -static UString ConvertINT64ToString(INT64 value) +static UString ConvertInt64ToString(Int64 value) { wchar_t buffer[32]; - ConvertINT64ToString(value, buffer); + ConvertInt64ToString(value, buffer); return buffer; } /* -CSysString ConvertFileTimeToString(const FILETIME &fileTime, bool includeTime) +static void UIntToStringSpec(UInt32 value, char *s, int numPos) { - SYSTEMTIME systemTime; - if(!BOOLToBool(FileTimeToSystemTime(&fileTime, &systemTime))) - #ifndef _WIN32_WCE - throw 311907; - #else - return CSysString(); - #endif - - const int kBufferSize = 64; - CSysString stringDate; - if(!NNational::NTime::MyGetDateFormat(LOCALE_USER_DEFAULT, - 0, &systemTime, NULL, stringDate)) - #ifndef _WIN32_WCE - throw 311908; - #else - return CSysString(); - #endif - if (!includeTime) - return stringDate; - CSysString stringTime; - if(!NNational::NTime::MyGetTimeFormat(LOCALE_USER_DEFAULT, - 0, &systemTime, NULL, stringTime)) - #ifndef _WIN32_WCE - throw 311909; - #else - return CSysString(); - #endif - return stringDate + _T(" ") + stringTime; + char s2[32]; + ConvertUInt64ToString(value, s2); + int len = strlen(s2); + int i; + for (i = 0; i < numPos - len; i++) + s[i] = '0'; + for (int j = 0; j < len; j++, i++) + s[i] = s2[j]; + s[i] = '\0'; } */ -UString ConvertFileTimeToString2(const FILETIME &fileTime, - bool includeTime, bool includeSeconds) +bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime, bool includeSeconds) { - CSysString string; - SYSTEMTIME systemTime; - if(!BOOLToBool(FileTimeToSystemTime(&fileTime, &systemTime))) - return UString(); - TCHAR buffer[64]; - wsprintf(buffer, TEXT("%04d-%02d-%02d"), systemTime.wYear, systemTime.wMonth, systemTime.wDay); + s[0] = '\0'; + SYSTEMTIME st; + if(!BOOLToBool(FileTimeToSystemTime(&ft, &st))) + return false; + /* + UIntToStringSpec(st.wYear, s, 4); + strcat(s, "-"); + UIntToStringSpec(st.wMonth, s + strlen(s), 2); + strcat(s, "-"); + UIntToStringSpec(st.wDay, s + strlen(s), 2); + if (includeTime) + { + strcat(s, " "); + UIntToStringSpec(st.wHour, s + strlen(s), 2); + strcat(s, ":"); + UIntToStringSpec(st.wMinute, s + strlen(s), 2); + if (includeSeconds) + { + strcat(s, ":"); + UIntToStringSpec(st.wSecond, s + strlen(s), 2); + } + } + */ + sprintf(s, "%04d-%02d-%02d", st.wYear, st.wMonth, st.wDay); if (includeTime) { - wsprintf(buffer + lstrlen(buffer), TEXT(" %02d:%02d"), systemTime.wHour, systemTime.wMinute); + sprintf(s + strlen(s), " %02d:%02d", st.wHour, st.wMinute); if (includeSeconds) - wsprintf(buffer + lstrlen(buffer), TEXT(":%02d"), systemTime.wSecond); + sprintf(s + strlen(s), ":%02d", st.wSecond); } - return GetUnicodeString(buffer); + return true; +} + +UString ConvertFileTimeToString(const FILETIME &fileTime, bool includeTime, bool includeSeconds) +{ + char s[32]; + ConvertFileTimeToString(fileTime, s, includeTime, includeSeconds); + return GetUnicodeString(s); } @@ -88,27 +95,25 @@ UString ConvertPropVariantToString(const PROPVARIANT &propVariant) case VT_BSTR: return propVariant.bstrVal; case VT_UI1: - return ConvertUINT64ToString(propVariant.bVal); + return ConvertUInt64ToString(propVariant.bVal); case VT_UI2: - return ConvertUINT64ToString(propVariant.uiVal); + return ConvertUInt64ToString(propVariant.uiVal); case VT_UI4: - return ConvertUINT64ToString(propVariant.ulVal); + return ConvertUInt64ToString(propVariant.ulVal); case VT_UI8: - return ConvertUINT64ToString(*(UINT64 *)(&propVariant.uhVal)); + return ConvertUInt64ToString(propVariant.uhVal.QuadPart); case VT_FILETIME: - return ConvertFileTimeToString2(propVariant.filetime, true, true); - - + return ConvertFileTimeToString(propVariant.filetime, true, true); /* case VT_I1: - return ConvertINT64ToString(propVariant.cVal); + return ConvertInt64ToString(propVariant.cVal); */ case VT_I2: - return ConvertINT64ToString(propVariant.iVal); + return ConvertInt64ToString(propVariant.iVal); case VT_I4: - return ConvertINT64ToString(propVariant.lVal); + return ConvertInt64ToString(propVariant.lVal); case VT_I8: - return ConvertINT64ToString(*(INT64 *)(&propVariant.hVal)); + return ConvertInt64ToString(propVariant.hVal.QuadPart); case VT_BOOL: return VARIANT_BOOLToBool(propVariant.boolVal) ? L"1" : L"0"; @@ -116,12 +121,12 @@ UString ConvertPropVariantToString(const PROPVARIANT &propVariant) #ifndef _WIN32_WCE throw 150245; #else - return CSysString(); + return UString(); #endif } } -UINT64 ConvertPropVariantToUINT64(const PROPVARIANT &propVariant) +UInt64 ConvertPropVariantToUInt64(const PROPVARIANT &propVariant) { switch (propVariant.vt) { @@ -132,7 +137,7 @@ UINT64 ConvertPropVariantToUINT64(const PROPVARIANT &propVariant) case VT_UI4: return propVariant.ulVal; case VT_UI8: - return (*(UINT64 *)(&propVariant.uhVal)); + return (UInt64)propVariant.uhVal.QuadPart; default: #ifndef _WIN32_WCE throw 151199; diff --git a/Windows/PropVariantConversions.h b/Windows/PropVariantConversions.h index 1067a7d8..a3f3ebbf 100755 --- a/Windows/PropVariantConversions.h +++ b/Windows/PropVariantConversions.h @@ -1,17 +1,14 @@ // Windows/PropVariantConversions.h -#pragma once - #ifndef __PROPVARIANTCONVERSIONS_H #define __PROPVARIANTCONVERSIONS_H +#include "Common/Types.h" #include "Common/String.h" -// CSysString ConvertFileTimeToString(const FILETIME &fileTime, bool includeTime = true); -UString ConvertFileTimeToString2(const FILETIME &fileTime, bool includeTime = true, - bool includeSeconds = true); +bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime = true, bool includeSeconds = true); +UString ConvertFileTimeToString(const FILETIME &ft, bool includeTime = true, bool includeSeconds = true); UString ConvertPropVariantToString(const PROPVARIANT &propVariant); - -UINT64 ConvertPropVariantToUINT64(const PROPVARIANT &propVariant); +UInt64 ConvertPropVariantToUInt64(const PROPVARIANT &propVariant); #endif diff --git a/Windows/Registry.h b/Windows/Registry.h index d47ef22c..a020900c 100755 --- a/Windows/Registry.h +++ b/Windows/Registry.h @@ -1,7 +1,5 @@ // Windows/Registry.h -#pragma once - #ifndef __WINDOWS_REGISTRY_H #define __WINDOWS_REGISTRY_H diff --git a/Windows/ResourceString.h b/Windows/ResourceString.h index 8819e1a3..a74f925d 100755 --- a/Windows/ResourceString.h +++ b/Windows/ResourceString.h @@ -1,7 +1,5 @@ // Windows/ResourceString.h -#pragma once - #ifndef __WINDOWS_RESOURCESTRING_H #define __WINDOWS_RESOURCESTRING_H diff --git a/Windows/Shell.h b/Windows/Shell.h index 88efa9e6..59a54fe8 100755 --- a/Windows/Shell.h +++ b/Windows/Shell.h @@ -1,7 +1,5 @@ // Windows/Shell.h -#pragma once - #ifndef __WINDOWS_SHELL_H #define __WINDOWS_SHELL_H diff --git a/Windows/StdAfx.h b/Windows/StdAfx.h index a32fbed6..da52182c 100755 --- a/Windows/StdAfx.h +++ b/Windows/StdAfx.h @@ -1,8 +1,8 @@ -// stdafx.h +// StdAfx.h #ifndef __STDAFX_H #define __STDAFX_H -#include <windows.h> +#include "../Common/MyWindows.h" #endif diff --git a/Windows/Synchronization.h b/Windows/Synchronization.h index 72e51342..c40fa988 100755 --- a/Windows/Synchronization.h +++ b/Windows/Synchronization.h @@ -1,7 +1,5 @@ // Windows/Synchronization.h -#pragma once - #ifndef __WINDOWS_SYNCHRONIZATION_H #define __WINDOWS_SYNCHRONIZATION_H diff --git a/Windows/System.cpp b/Windows/System.cpp deleted file mode 100755 index 655857a1..00000000 --- a/Windows/System.cpp +++ /dev/null @@ -1,15 +0,0 @@ -// Windows/System.h - -#include "StdAfx.h" - -#include "System.h" -#ifndef _UNICODE -#include "../Common/StringConvert.h" -#endif - -namespace NWindows { -namespace NSystem { - - -}} - diff --git a/Windows/System.h b/Windows/System.h deleted file mode 100755 index 1f6fa04e..00000000 --- a/Windows/System.h +++ /dev/null @@ -1,15 +0,0 @@ -// Windows/System.h - -#pragma once - -#ifndef __WINDOWS_SYSTEM_H -#define __WINDOWS_SYSTEM_H - -#include "../Common/String.h" - -namespace NWindows { -namespace NSystem { - -}} - -#endif diff --git a/Windows/Thread.h b/Windows/Thread.h index 4cb87e95..8ecc13f1 100755 --- a/Windows/Thread.h +++ b/Windows/Thread.h @@ -1,7 +1,5 @@ // Windows/Thread.h -#pragma once - #ifndef __WINDOWS_THREAD_H #define __WINDOWS_THREAD_H @@ -12,6 +10,7 @@ namespace NWindows { class CThread: public CHandle { + bool IsOpen() const { return _handle != 0; } public: bool Create(LPSECURITY_ATTRIBUTES threadAttributes, SIZE_T stackSize, LPTHREAD_START_ROUTINE startAddress, @@ -38,6 +37,14 @@ public: { return ::GetThreadPriority(_handle); } bool SetPriority(int priority) { return BOOLToBool(::SetThreadPriority(_handle, priority)); } + + bool Wait() + { + if (!IsOpen()) + return true; + return (::WaitForSingleObject(_handle, INFINITE) == WAIT_OBJECT_0); + } + }; } diff --git a/Windows/Time.h b/Windows/Time.h index 296ae963..3dcf1051 100755 --- a/Windows/Time.h +++ b/Windows/Time.h @@ -1,55 +1,48 @@ // Windows/Time.h -#pragma once - #ifndef __WINDOWS_TIME_H #define __WINDOWS_TIME_H #include "Common/Types.h" -// #include <windows.h> -// #include <time.h> #include "Windows/Defs.h" namespace NWindows { namespace NTime { -inline bool DosTimeToFileTime(UINT32 dosTime, FILETIME &fileTime) +inline bool DosTimeToFileTime(UInt32 dosTime, FILETIME &fileTime) { - return BOOLToBool(::DosDateTimeToFileTime(UINT16(dosTime >> 16), - UINT16(dosTime & 0xFFFF), &fileTime)); + return BOOLToBool(::DosDateTimeToFileTime(UInt16(dosTime >> 16), + UInt16(dosTime & 0xFFFF), &fileTime)); } -inline bool FileTimeToDosTime(const FILETIME &fileTime, UINT32 &dosTime) +inline bool FileTimeToDosTime(const FILETIME &fileTime, UInt32 &dosTime) { - return BOOLToBool(::FileTimeToDosDateTime(&fileTime, - ((LPWORD)&dosTime) + 1, (LPWORD)&dosTime)); + WORD datePart, timePart; + if (!::FileTimeToDosDateTime(&fileTime, &datePart, &timePart)) + return false; + dosTime = (((UInt32)datePart) << 16) + timePart; + return true; } -const UINT64 kUnixTimeStartValue = - #if ( __GNUC__) - 116444736000000000LL; - #else - 116444736000000000; - #endif -const UINT32 kNumTimeQuantumsInSecond = 10000000; +const UInt32 kNumTimeQuantumsInSecond = 10000000; +const UInt64 kUnixTimeStartValue = ((UInt64)kNumTimeQuantumsInSecond) * 60 * 60 * 24 * 134774; -inline void UnixTimeToFileTime(long unixTime, FILETIME &fileTime) +inline void UnixTimeToFileTime(UInt32 unixTime, FILETIME &fileTime) { - ULONGLONG ll = UInt32x32To64(unixTime, kNumTimeQuantumsInSecond) + - kUnixTimeStartValue; - fileTime.dwLowDateTime = (DWORD) ll; - fileTime.dwHighDateTime = DWORD(ll >> 32); + UInt64 v = kUnixTimeStartValue + ((UInt64)unixTime) * kNumTimeQuantumsInSecond; + fileTime.dwLowDateTime = (DWORD)v; + fileTime.dwHighDateTime = (DWORD)(v >> 32); } -inline bool FileTimeToUnixTime(const FILETIME &fileTime, long &unixTime) +inline bool FileTimeToUnixTime(const FILETIME &fileTime, UInt32 &unixTime) { - UINT64 winTime = (((UINT64)fileTime.dwHighDateTime) << 32) + fileTime.dwLowDateTime; + UInt64 winTime = (((UInt64)fileTime.dwHighDateTime) << 32) + fileTime.dwLowDateTime; if (winTime < kUnixTimeStartValue) return false; winTime = (winTime - kUnixTimeStartValue) / kNumTimeQuantumsInSecond; - if (winTime >= 0xFFFFFFFF) + if (winTime > 0xFFFFFFFF) return false; - unixTime = (long)winTime; + unixTime = (UInt32)winTime; return true; } diff --git a/Windows/Window.h b/Windows/Window.h index 24786d12..87a50e5c 100755 --- a/Windows/Window.h +++ b/Windows/Window.h @@ -1,7 +1,5 @@ // Windows/Window.h -#pragma once - #ifndef __WINDOWS_WINDOW_H #define __WINDOWS_WINDOW_H |