diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2008-08-13 04:00:00 +0400 |
---|---|---|
committer | Kornel LesiĆski <kornel@geekhood.net> | 2016-05-28 02:15:56 +0300 |
commit | 173c07e166fdf6fcd20f18ea73008f1b628945df (patch) | |
tree | 13ebea85cdc4c16ae93714ff0627ee9f91ad7e08 /CPP/7zip/Archive | |
parent | 3901bf0ab88106a5b031cba7bc18d60cdebf7eef (diff) |
4.59 beta
Diffstat (limited to 'CPP/7zip/Archive')
238 files changed, 12240 insertions, 6019 deletions
diff --git a/CPP/7zip/Archive/7z/7z.dsp b/CPP/7zip/Archive/7z/7z.dsp new file mode 100755 index 00000000..bddb2673 --- /dev/null +++ b/CPP/7zip/Archive/7z/7z.dsp @@ -0,0 +1,640 @@ +# 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 "7z.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.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 /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "COMPRESS_MT" /D "EXTERNAL_CODECS" /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 0x409 /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\7z.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!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 "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "COMPRESS_MT" /D "EXTERNAL_CODECS" /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 0x409 /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\7z.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.def +# End Source File +# Begin Source File + +SOURCE=..\ArchiveExports.cpp +# End Source File +# Begin Source File + +SOURCE=..\DllExports.cpp +# 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 "Engine" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\7zCompressionMode.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zCompressionMode.h +# End Source File +# Begin Source File + +SOURCE=.\7zDecode.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zDecode.h +# End Source File +# Begin Source File + +SOURCE=.\7zEncode.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zEncode.h +# End Source File +# Begin Source File + +SOURCE=.\7zExtract.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zFolderInStream.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zFolderInStream.h +# End Source File +# Begin Source File + +SOURCE=.\7zFolderOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zFolderOutStream.h +# End Source File +# Begin Source File + +SOURCE=.\7zHandler.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zHandler.h +# End Source File +# Begin Source File + +SOURCE=.\7zHandlerOut.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zHeader.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zHeader.h +# End Source File +# Begin Source File + +SOURCE=.\7zIn.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zIn.h +# End Source File +# Begin Source File + +SOURCE=.\7zItem.h +# End Source File +# Begin Source File + +SOURCE=.\7zOut.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zOut.h +# End Source File +# Begin Source File + +SOURCE=.\7zProperties.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zProperties.h +# End Source File +# Begin Source File + +SOURCE=.\7zRegister.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zSpecStream.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zSpecStream.h +# End Source File +# Begin Source File + +SOURCE=.\7zUpdate.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zUpdate.h +# End Source File +# End Group +# Begin Group "Interface" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\IArchive.h +# End Source File +# Begin Source File + +SOURCE=..\..\ICoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\IMyUnknown.h +# End Source File +# Begin Source File + +SOURCE=..\..\IPassword.h +# End Source File +# Begin Source File + +SOURCE=..\..\IProgress.h +# End Source File +# Begin Source File + +SOURCE=..\..\IStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\PropID.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Buffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# 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 + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.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 +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# End Group +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\CoderMixer2.cpp +# End Source File +# Begin Source File + +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 + +SOURCE=..\Common\CrossThreadProgress.h +# End Source File +# Begin Source File + +SOURCE=..\Common\HandlerOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\HandlerOut.h +# End Source File +# Begin Source File + +SOURCE=..\Common\InStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\InStreamWithCRC.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +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 + +SOURCE=..\Common\OutStreamWithCRC.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ParseProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ParseProperties.h +# End Source File +# End Group +# Begin Group "7-Zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\CreateCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CreateCoder.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\InOutTempBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InOutTempBuffer.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\MethodId.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MethodId.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MethodProps.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MethodProps.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\RegisterArc.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\RegisterCodec.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 +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\VirtThread.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\VirtThread.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\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\FileName.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Handle.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 +# 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 +# End Group +# Begin Group "Compress" + +# 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 "C" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Alloc.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.h +# End Source File +# End Group +# End Target +# End Project diff --git a/CPP/7zip/Archive/7z/7z.dsw b/CPP/7zip/Archive/7z/7z.dsw new file mode 100755 index 00000000..702a86c7 --- /dev/null +++ b/CPP/7zip/Archive/7z/7z.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"=".\7z.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Archive/7z/7zCompressionMode.h b/CPP/7zip/Archive/7z/7zCompressionMode.h index 5753606f..a7cf999c 100755 --- a/CPP/7zip/Archive/7z/7zCompressionMode.h +++ b/CPP/7zip/Archive/7z/7zCompressionMode.h @@ -40,7 +40,7 @@ struct CCompressionMethodMode bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); } CCompressionMethodMode(): PasswordIsDefined(false) #ifdef COMPRESS_MT - , NumThreads(1) + , NumThreads(1) #endif {} }; diff --git a/CPP/7zip/Archive/7z/7zDecode.cpp b/CPP/7zip/Archive/7z/7zDecode.cpp index 0f81de40..13fe50c8 100755 --- a/CPP/7zip/Archive/7z/7zDecode.cpp +++ b/CPP/7zip/Archive/7z/7zDecode.cpp @@ -44,7 +44,7 @@ static void ConvertFolderItemInfoToBindInfo(const CFolder &folder, bindInfo.InStreams.Add((UInt32)folder.PackStreams[i]); } -static bool AreCodersEqual(const NCoderMixer::CCoderStreamsInfo &a1, +static bool AreCodersEqual(const NCoderMixer::CCoderStreamsInfo &a1, const NCoderMixer::CCoderStreamsInfo &a2) { return (a1.NumInStreams == a2.NumInStreams) && @@ -94,17 +94,20 @@ HRESULT CDecoder::Decode( IInStream *inStream, UInt64 startPos, const UInt64 *packSizes, - const CFolder &folderInfo, + const CFolder &folderInfo, ISequentialOutStream *outStream, ICompressProgressInfo *compressProgress #ifndef _NO_CRYPTO - , ICryptoGetTextPassword *getTextPassword + , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined #endif #ifdef COMPRESS_MT , bool mtMode, UInt32 numThreads #endif ) { + #ifndef _NO_CRYPTO + passwordIsDefined = false; + #endif CObjectVector< CMyComPtr<ISequentialInStream> > inStreams; CLockedInStream lockedInStream; @@ -112,13 +115,13 @@ HRESULT CDecoder::Decode( for (int j = 0; j < folderInfo.PackStreams.Size(); j++) { - CLockedSequentialInStreamImp *lockedStreamImpSpec = new + CLockedSequentialInStreamImp *lockedStreamImpSpec = new CLockedSequentialInStreamImp; CMyComPtr<ISequentialInStream> lockedStreamImp = lockedStreamImpSpec; lockedStreamImpSpec->Init(&lockedInStream, startPos); startPos += packSizes[j]; - CLimitedSequentialInStream *streamSpec = new + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; CMyComPtr<ISequentialInStream> inStream = streamSpec; streamSpec->SetStream(lockedStreamImp); @@ -212,7 +215,7 @@ HRESULT CDecoder::Decode( int i; _mixerCoderCommon->ReInit(); - UInt32 packStreamIndex = 0, unPackStreamIndex = 0; + UInt32 packStreamIndex = 0, unpackStreamIndex = 0; UInt32 coderIndex = 0; // UInt32 coder2Index = 0; @@ -257,20 +260,20 @@ HRESULT CDecoder::Decode( { if (getTextPassword == 0) return E_FAIL; - CMyComBSTR password; - RINOK(getTextPassword->CryptoGetTextPassword(&password)); + CMyComBSTR passwordBSTR; + RINOK(getTextPassword->CryptoGetTextPassword(&passwordBSTR)); CByteBuffer buffer; - UString unicodePassword(password); - const UInt32 sizeInBytes = unicodePassword.Length() * 2; + passwordIsDefined = true; + UString password = passwordBSTR; + const UInt32 sizeInBytes = password.Length() * 2; buffer.SetCapacity(sizeInBytes); - for (int i = 0; i < unicodePassword.Length(); i++) + for (int i = 0; i < password.Length(); i++) { - wchar_t c = unicodePassword[i]; + wchar_t c = password[i]; ((Byte *)buffer)[i * 2] = (Byte)c; ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8); } - RINOK(cryptoSetPassword->CryptoSetPassword( - (const Byte *)buffer, sizeInBytes)); + RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, sizeInBytes)); } } #endif @@ -280,19 +283,19 @@ HRESULT CDecoder::Decode( UInt32 numInStreams = (UInt32)coderInfo.NumInStreams; UInt32 numOutStreams = (UInt32)coderInfo.NumOutStreams; CRecordVector<const UInt64 *> packSizesPointers; - CRecordVector<const UInt64 *> unPackSizesPointers; + CRecordVector<const UInt64 *> unpackSizesPointers; packSizesPointers.Reserve(numInStreams); - unPackSizesPointers.Reserve(numOutStreams); + unpackSizesPointers.Reserve(numOutStreams); UInt32 j; - for (j = 0; j < numOutStreams; j++, unPackStreamIndex++) - unPackSizesPointers.Add(&folderInfo.UnPackSizes[unPackStreamIndex]); + for (j = 0; j < numOutStreams; j++, unpackStreamIndex++) + unpackSizesPointers.Add(&folderInfo.UnpackSizes[unpackStreamIndex]); for (j = 0; j < numInStreams; j++, packStreamIndex++) { 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); @@ -302,9 +305,9 @@ HRESULT CDecoder::Decode( } } - _mixerCoderCommon->SetCoderInfo(i, - &packSizesPointers.Front(), - &unPackSizesPointers.Front()); + _mixerCoderCommon->SetCoderInfo(i, + &packSizesPointers.Front(), + &unpackSizesPointers.Front()); } UInt32 mainCoder, temp; bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp); @@ -323,7 +326,7 @@ HRESULT CDecoder::Decode( for (i = 0; i < inStreams.Size(); i++) inStreamPointers.Add(inStreams[i]); ISequentialOutStream *outStreamPointer = outStream; - return _mixerCoder->Code(&inStreamPointers.Front(), NULL, + return _mixerCoder->Code(&inStreamPointers.Front(), NULL, inStreams.Size(), &outStreamPointer, NULL, 1, compressProgress); } diff --git a/CPP/7zip/Archive/7z/7zDecode.h b/CPP/7zip/Archive/7z/7zDecode.h index 7c10dfe2..1057a525 100755 --- a/CPP/7zip/Archive/7z/7zDecode.h +++ b/CPP/7zip/Archive/7z/7zDecode.h @@ -51,11 +51,11 @@ public: IInStream *inStream, UInt64 startPos, const UInt64 *packSizes, - const CFolder &folder, + const CFolder &folder, ISequentialOutStream *outStream, ICompressProgressInfo *compressProgress #ifndef _NO_CRYPTO - , ICryptoGetTextPassword *getTextPasswordSpec + , ICryptoGetTextPassword *getTextPasswordSpec, bool &passwordIsDefined #endif #ifdef COMPRESS_MT , bool mtMode, UInt32 numThreads diff --git a/CPP/7zip/Archive/7z/7zEncode.cpp b/CPP/7zip/Archive/7z/7zEncode.cpp index 3a5cfcd5..b5a43f56 100755 --- a/CPP/7zip/Archive/7z/7zEncode.cpp +++ b/CPP/7zip/Archive/7z/7zEncode.cpp @@ -164,7 +164,7 @@ HRESULT CEncoder::Encode( } for (i = 1; i < _bindInfo.OutStreams.Size(); i++) { - CSequentialOutTempBufferImp *tempBufferSpec = + CSequentialOutTempBufferImp *tempBufferSpec = new CSequentialOutTempBufferImp; CMyComPtr<ISequentialOutStream> tempBuffer = tempBufferSpec; tempBufferSpec->Init(&inOutTempBuffers[i - 1]); @@ -195,10 +195,10 @@ HRESULT CEncoder::Encode( // UInt64 outStreamStartPos; // RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos)); - CSequentialInStreamSizeCount2 *inStreamSizeCountSpec = + CSequentialInStreamSizeCount2 *inStreamSizeCountSpec = new CSequentialInStreamSizeCount2; CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec; - CSequentialOutStreamSizeCount *outStreamSizeCountSpec = + CSequentialOutStreamSizeCount *outStreamSizeCountSpec = new CSequentialOutStreamSizeCount; CMyComPtr<ISequentialOutStream> outStreamSizeCount = outStreamSizeCountSpec; @@ -275,7 +275,7 @@ HRESULT CEncoder::Encode( streamSize = inStreamSizeCountSpec->GetSize(); else streamSize = _mixerCoderSpec->GetWriteProcessedSize(binder); - folderItem.UnPackSizes.Add(streamSize); + folderItem.UnpackSizes.Add(streamSize); } for (i = numMethods - 1; i >= 0; i--) folderItem.Coders[numMethods - 1 - i].Properties = _codersInfo[i].Properties; diff --git a/CPP/7zip/Archive/7z/7zExtract.cpp b/CPP/7zip/Archive/7z/7zExtract.cpp index 42977097..06e9ef97 100755 --- a/CPP/7zip/Archive/7z/7zExtract.cpp +++ b/CPP/7zip/Archive/7z/7zExtract.cpp @@ -23,18 +23,18 @@ struct CExtractFolderInfo CNum FileIndex; CNum FolderIndex; CBoolVector ExtractStatuses; - UInt64 UnPackSize; + UInt64 UnpackSize; CExtractFolderInfo( #ifdef _7Z_VOL - int volumeIndex, + int volumeIndex, #endif - CNum fileIndex, CNum folderIndex): + CNum fileIndex, CNum folderIndex): #ifdef _7Z_VOL VolumeIndex(volumeIndex), #endif FileIndex(fileIndex), - FolderIndex(folderIndex), - UnPackSize(0) + FolderIndex(folderIndex), + UnpackSize(0) { if (fileIndex != kNumNoIndex) { @@ -50,15 +50,15 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, COM_TRY_BEGIN bool testMode = (testModeSpec != 0); CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec; - UInt64 importantTotalUnPacked = 0; + UInt64 importantTotalUnpacked = 0; bool allFilesMode = (numItems == UInt32(-1)); if (allFilesMode) - numItems = + numItems = #ifdef _7Z_VOL _refs.Size(); #else - _database.Files.Size(); + _db.Files.Size(); #endif if(numItems == 0) @@ -68,7 +68,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, if(_volumes.Size() != 1) return E_FAIL; const CVolume &volume = _volumes.Front(); - const CArchiveDatabaseEx &_database = volume.Database; + const CArchiveDatabaseEx &_db = volume.Database; IInStream *_inStream = volume.Stream; */ @@ -87,25 +87,25 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, int volumeIndex = ref.VolumeIndex; const CVolume &volume = _volumes[volumeIndex]; - const CArchiveDatabaseEx &database = volume.Database; + const CArchiveDatabaseEx &db = volume.Database; UInt32 fileIndex = ref.ItemIndex; #else - const CArchiveDatabaseEx &database = _database; + const CArchiveDatabaseEx &db = _db; UInt32 fileIndex = ref2Index; #endif - CNum folderIndex = database.FileIndexToFolderIndexMap[fileIndex]; + CNum folderIndex = db.FileIndexToFolderIndexMap[fileIndex]; if (folderIndex == kNumNoIndex) { extractFolderInfoVector.Add(CExtractFolderInfo( #ifdef _7Z_VOL - volumeIndex, + volumeIndex, #endif fileIndex, kNumNoIndex)); continue; } - if (extractFolderInfoVector.IsEmpty() || - folderIndex != extractFolderInfoVector.Back().FolderIndex + if (extractFolderInfoVector.IsEmpty() || + folderIndex != extractFolderInfoVector.Back().FolderIndex #ifdef _7Z_VOL || volumeIndex != extractFolderInfoVector.Back().VolumeIndex #endif @@ -113,32 +113,32 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, { extractFolderInfoVector.Add(CExtractFolderInfo( #ifdef _7Z_VOL - volumeIndex, + volumeIndex, #endif kNumNoIndex, folderIndex)); - const CFolder &folderInfo = database.Folders[folderIndex]; - UInt64 unPackSize = folderInfo.GetUnPackSize(); - importantTotalUnPacked += unPackSize; - extractFolderInfoVector.Back().UnPackSize = unPackSize; + const CFolder &folderInfo = db.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]; + CNum startIndex = db.FolderStartFileIndex[folderIndex]; for (CNum index = efi.ExtractStatuses.Size(); index <= fileIndex - startIndex; index++) { - // UInt64 unPackSize = _database.Files[startIndex + index].UnPackSize; + // UInt64 unpackSize = _db.Files[startIndex + index].UnpackSize; // Count partial_folder_size - // efi.UnPackSize += unPackSize; - // importantTotalUnPacked += unPackSize; + // efi.UnpackSize += unpackSize; + // importantTotalUnpacked += unpackSize; efi.ExtractStatuses.Add(index == fileIndex - startIndex); } } } - extractCallback->SetTotal(importantTotalUnPacked); + extractCallback->SetTotal(importantTotalUnpacked); CDecoder decoder( #ifdef _ST_MODE @@ -150,24 +150,24 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, // CDecoder1 decoder; UInt64 currentTotalPacked = 0; - UInt64 currentTotalUnPacked = 0; - UInt64 totalFolderUnPacked; + UInt64 currentTotalUnpacked = 0; + UInt64 totalFolderUnpacked; UInt64 totalFolderPacked; CLocalProgress *lps = new CLocalProgress; CMyComPtr<ICompressProgressInfo> progress = lps; lps->Init(extractCallback, false); - for(int i = 0; i < extractFolderInfoVector.Size(); i++, - currentTotalUnPacked += totalFolderUnPacked, + for(int i = 0; i < extractFolderInfoVector.Size(); i++, + currentTotalUnpacked += totalFolderUnpacked, currentTotalPacked += totalFolderPacked) { - lps->OutSize = currentTotalUnPacked; + lps->OutSize = currentTotalUnpacked; lps->InSize = currentTotalPacked; RINOK(lps->SetCur()); const CExtractFolderInfo &efi = extractFolderInfoVector[i]; - totalFolderUnPacked = efi.UnPackSize; + totalFolderUnpacked = efi.UnpackSize; totalFolderPacked = 0; @@ -176,25 +176,25 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, #ifdef _7Z_VOL const CVolume &volume = _volumes[efi.VolumeIndex]; - const CArchiveDatabaseEx &database = volume.Database; + const CArchiveDatabaseEx &db = volume.Database; #else - const CArchiveDatabaseEx &database = _database; + const CArchiveDatabaseEx &db = _db; #endif CNum startIndex; if (efi.FileIndex != kNumNoIndex) startIndex = efi.FileIndex; else - startIndex = database.FolderStartFileIndex[efi.FolderIndex]; + startIndex = db.FolderStartFileIndex[efi.FolderIndex]; - HRESULT result = folderOutStream->Init(&database, + HRESULT result = folderOutStream->Init(&db, #ifdef _7Z_VOL - volume.StartRef2Index, + volume.StartRef2Index, #else 0, #endif - startIndex, + startIndex, &efi.ExtractStatuses, extractCallback, testMode, _crcSize != 0); RINOK(result); @@ -203,12 +203,12 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, continue; CNum folderIndex = efi.FolderIndex; - const CFolder &folderInfo = database.Folders[folderIndex]; + const CFolder &folderInfo = db.Folders[folderIndex]; - totalFolderPacked = _database.GetFolderFullPackSize(folderIndex); + totalFolderPacked = _db.GetFolderFullPackSize(folderIndex); - CNum packStreamIndex = database.FolderStartPackStreamIndex[folderIndex]; - UInt64 folderStartPackPos = database.GetFolderStreamPos(folderIndex, 0); + CNum packStreamIndex = db.FolderStartPackStreamIndex[folderIndex]; + UInt64 folderStartPackPos = db.GetFolderStreamPos(folderIndex, 0); #ifndef _NO_CRYPTO CMyComPtr<ICryptoGetTextPassword> getTextPassword; @@ -218,6 +218,10 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, try { + #ifndef _NO_CRYPTO + bool passwordIsDefined; + #endif + HRESULT result = decoder.Decode( EXTERNAL_CODECS_VARS #ifdef _7Z_VOL @@ -225,13 +229,13 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, #else _inStream, #endif - folderStartPackPos, - &database.PackSizes[packStreamIndex], + folderStartPackPos, + &db.PackSizes[packStreamIndex], folderInfo, outStream, progress #ifndef _NO_CRYPTO - , getTextPassword + , getTextPassword, passwordIsDefined #endif #ifdef COMPRESS_MT , true, _numThreads diff --git a/CPP/7zip/Archive/7z/7zFolderInStream.cpp b/CPP/7zip/Archive/7z/7zFolderInStream.cpp index f60a7177..b029ae15 100755 --- a/CPP/7zip/Archive/7z/7zFolderInStream.cpp +++ b/CPP/7zip/Archive/7z/7zFolderInStream.cpp @@ -13,7 +13,7 @@ CFolderInStream::CFolderInStream() _inStreamWithHash = _inStreamWithHashSpec; } -void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback, +void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback, const UInt32 *fileIndices, UInt32 numFiles) { _updateCallback = updateCallback; diff --git a/CPP/7zip/Archive/7z/7zFolderInStream.h b/CPP/7zip/Archive/7z/7zFolderInStream.h index 9a720c8b..68e2b27b 100755 --- a/CPP/7zip/Archive/7z/7zFolderInStream.h +++ b/CPP/7zip/Archive/7z/7zFolderInStream.h @@ -14,7 +14,7 @@ namespace NArchive { namespace N7z { -class CFolderInStream: +class CFolderInStream: public ISequentialInStream, public ICompressGetSubStreamSize, public CMyUnknownImp @@ -47,7 +47,7 @@ private: HRESULT CloseStream(); void AddDigest(); public: - void Init(IArchiveUpdateCallback *updateCallback, + void Init(IArchiveUpdateCallback *updateCallback, const UInt32 *fileIndices, UInt32 numFiles); CRecordVector<bool> Processed; CRecordVector<UInt32> CRCs; @@ -55,7 +55,7 @@ public: UInt64 GetFullSize() const { UInt64 size = 0; - for (int i = 0; i < Sizes.Size(); i++) + for (int i = 0; i < Sizes.Size(); i++) size += Sizes[i]; return size; } diff --git a/CPP/7zip/Archive/7z/7zFolderOutStream.cpp b/CPP/7zip/Archive/7z/7zFolderOutStream.cpp index 6206ffec..61b938d0 100755 --- a/CPP/7zip/Archive/7z/7zFolderOutStream.cpp +++ b/CPP/7zip/Archive/7z/7zFolderOutStream.cpp @@ -17,7 +17,7 @@ HRESULT CFolderOutStream::Init( const CArchiveDatabaseEx *archiveDatabase, UInt32 ref2Offset, UInt32 startIndex, - const CBoolVector *extractStatuses, + const CBoolVector *extractStatuses, IArchiveExtractCallback *extractCallback, bool testMode, bool checkCrc) @@ -41,7 +41,7 @@ HRESULT CFolderOutStream::OpenFile() { Int32 askMode; if((*_extractStatuses)[_currentIndex]) - askMode = _testMode ? + askMode = _testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract; else @@ -54,10 +54,10 @@ HRESULT CFolderOutStream::OpenFile() _outStreamWithHashSpec->SetStream(realOutStream); _outStreamWithHashSpec->Init(_checkCrc); if (askMode == NArchive::NExtract::NAskMode::kExtract && - (!realOutStream)) + (!realOutStream)) { - const CFileItem &fileInfo = _archiveDatabase->Files[index]; - if (!fileInfo.IsAnti && !fileInfo.IsDirectory) + const CFileItem &fi = _archiveDatabase->Files[index]; + if (!_archiveDatabase->IsItemAnti(index) && !fi.IsDir) askMode = NArchive::NExtract::NAskMode::kSkip; } return _extractCallback->PrepareOperation(askMode); @@ -68,18 +68,17 @@ HRESULT CFolderOutStream::WriteEmptyFiles() for(;_currentIndex < _extractStatuses->Size(); _currentIndex++) { UInt32 index = _startIndex + _currentIndex; - const CFileItem &fileInfo = _archiveDatabase->Files[index]; - if (!fileInfo.IsAnti && !fileInfo.IsDirectory && fileInfo.UnPackSize != 0) + const CFileItem &fi = _archiveDatabase->Files[index]; + if (!_archiveDatabase->IsItemAnti(index) && !fi.IsDir && fi.Size != 0) return S_OK; RINOK(OpenFile()); - RINOK(_extractCallback->SetOperationResult( - NArchive::NExtract::NOperationResult::kOK)); + RINOK(_extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); _outStreamWithHashSpec->ReleaseStream(); } return S_OK; } -STDMETHODIMP CFolderOutStream::Write(const void *data, +STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) { UInt32 realProcessedSize = 0; @@ -88,14 +87,14 @@ STDMETHODIMP CFolderOutStream::Write(const void *data, if (_fileIsOpen) { UInt32 index = _startIndex + _currentIndex; - const CFileItem &fileInfo = _archiveDatabase->Files[index]; - UInt64 fileSize = fileInfo.UnPackSize; + const CFileItem &fi = _archiveDatabase->Files[index]; + UInt64 fileSize = fi.Size; - UInt32 numBytesToWrite = (UInt32)MyMin(fileSize - _filePos, + UInt32 numBytesToWrite = (UInt32)MyMin(fileSize - _filePos, UInt64(size - realProcessedSize)); UInt32 processedSizeLocal; - RINOK(_outStreamWithHash->Write((const Byte *)data + realProcessedSize, + RINOK(_outStreamWithHash->Write((const Byte *)data + realProcessedSize, numBytesToWrite, &processedSizeLocal)); _filePos += processedSizeLocal; @@ -103,13 +102,13 @@ STDMETHODIMP CFolderOutStream::Write(const void *data, if (_filePos == fileSize) { bool digestsAreEqual; - if (fileInfo.IsFileCRCDefined && _checkCrc) - digestsAreEqual = fileInfo.FileCRC == _outStreamWithHashSpec->GetCRC(); + if (fi.CrcDefined && _checkCrc) + digestsAreEqual = fi.Crc == _outStreamWithHashSpec->GetCRC(); else digestsAreEqual = true; RINOK(_extractCallback->SetOperationResult( - digestsAreEqual ? + digestsAreEqual ? NArchive::NExtract::NOperationResult::kOK : NArchive::NExtract::NOperationResult::kCRCError)); _outStreamWithHashSpec->ReleaseStream(); diff --git a/CPP/7zip/Archive/7z/7zFolderOutStream.h b/CPP/7zip/Archive/7z/7zFolderOutStream.h index 8ca91e64..f54fba3e 100755 --- a/CPP/7zip/Archive/7z/7zFolderOutStream.h +++ b/CPP/7zip/Archive/7z/7zFolderOutStream.h @@ -12,7 +12,7 @@ namespace NArchive { namespace N7z { -class CFolderOutStream: +class CFolderOutStream: public ISequentialOutStream, public CMyUnknownImp { @@ -47,7 +47,7 @@ public: const CArchiveDatabaseEx *archiveDatabase, UInt32 ref2Offset, UInt32 startIndex, - const CBoolVector *extractStatuses, + const CBoolVector *extractStatuses, IArchiveExtractCallback *extractCallback, bool testMode, bool checkCrc); diff --git a/CPP/7zip/Archive/7z/7zHandler.cpp b/CPP/7zip/Archive/7z/7zHandler.cpp index bbef1ea5..76b3c72d 100755 --- a/CPP/7zip/Archive/7z/7zHandler.cpp +++ b/CPP/7zip/Archive/7z/7zHandler.cpp @@ -10,9 +10,6 @@ #include "../../../Windows/Defs.h" #include "../Common/ItemNameUtils.h" -#ifdef _7Z_VOL -#include "../Common/MultiStream.h" -#endif #ifdef __7Z_SET_PROPERTIES #ifdef EXTRACT_ONLY @@ -35,9 +32,13 @@ CHandler::CHandler() { _crcSize = 4; + #ifndef _NO_CRYPTO + _passwordIsDefined = false; + #endif + #ifdef EXTRACT_ONLY #ifdef COMPRESS_MT - _numThreads = NWindows::NSystem::GetNumberOfProcessors(); + _numThreads = NSystem::GetNumberOfProcessors(); #endif #else Init(); @@ -46,12 +47,7 @@ CHandler::CHandler() STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) { - *numItems = - #ifdef _7Z_VOL - _refs.Size(); - #else - *numItems = _database.Files.Size(); - #endif + *numItems = _db.Files.Size(); return S_OK; } @@ -64,7 +60,7 @@ 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; @@ -73,17 +69,20 @@ STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */, #else -STATPROPSTG kArcProps[] = +STATPROPSTG kArcProps[] = { { NULL, kpidMethod, VT_BSTR}, { NULL, kpidSolid, VT_BOOL}, - { NULL, kpidNumBlocks, VT_UI4} + { NULL, kpidNumBlocks, VT_UI4}, + { NULL, kpidPhySize, VT_UI8}, + { NULL, kpidHeadersSize, VT_UI8}, + { NULL, kpidOffset, VT_UI8} }; STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; + NCOM::CPropVariant prop; switch(propID) { case kpidMethod: @@ -91,9 +90,9 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) UString resString; CRecordVector<UInt64> ids; int i; - for (i = 0; i < _database.Folders.Size(); i++) + for (i = 0; i < _db.Folders.Size(); i++) { - const CFolder &f = _database.Folders[i]; + const CFolder &f = _db.Folders[i]; for (int j = f.Coders.Size() - 1; j >= 0; j--) ids.AddToUniqueSorted(f.Coders[j].MethodID); } @@ -109,11 +108,14 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) resString += L' '; resString += methodName; } - prop = resString; + prop = resString; break; } - case kpidSolid: prop = _database.IsSolid(); break; - case kpidNumBlocks: prop = (UInt32)_database.Folders.Size(); break; + case kpidSolid: prop = _db.IsSolid(); break; + case kpidNumBlocks: prop = (UInt32)_db.Folders.Size(); break; + case kpidHeadersSize: prop = _db.HeadersSize; break; + case kpidPhySize: prop = _db.PhySize; break; + case kpidOffset: if (_db.ArchiveInfo.StartPosition != 0) prop = _db.ArchiveInfo.StartPosition; break; } prop.Detach(value); return S_OK; @@ -124,10 +126,16 @@ IMP_IInArchive_ArcProps #endif -static void MySetFileTime(bool timeDefined, FILETIME unixTime, NWindows::NCOM::CPropVariant &prop) +static void SetPropFromUInt64Def(CUInt64DefVector &v, int index, NCOM::CPropVariant &prop) { - if (timeDefined) - prop = unixTime; + UInt64 value; + if (v.GetItem(index, value)) + { + FILETIME ft; + ft.dwLowDateTime = (DWORD)value; + ft.dwHighDateTime = (DWORD)(value >> 32); + prop = ft; + } } #ifndef _SFX @@ -192,10 +200,10 @@ static inline UInt32 GetUInt32FromMemLE(const Byte *p) bool CHandler::IsEncrypted(UInt32 index2) const { - CNum folderIndex = _database.FileIndexToFolderIndexMap[index2]; + CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; if (folderIndex != kNumNoIndex) { - const CFolder &folderInfo = _database.Folders[folderIndex]; + const CFolder &folderInfo = _db.Folders[folderIndex]; for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--) if (folderInfo.Coders[i].MethodID == k_AES) return true; @@ -206,7 +214,7 @@ bool CHandler::IsEncrypted(UInt32 index2) const STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; + NCOM::CPropVariant prop; /* const CRef2 &ref2 = _refs[index]; @@ -215,54 +223,31 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va 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]; + const CFileItem &item = _db.Files[index]; UInt32 index2 = index; - #endif switch(propID) { case kpidPath: - { if (!item.Name.IsEmpty()) prop = NItemName::GetOSName(item.Name); break; - } - case kpidIsFolder: - prop = item.IsDirectory; - break; + case kpidIsDir: prop = item.IsDir; break; case kpidSize: { - prop = item.UnPackSize; - // prop = ref2.UnPackSize; + prop = item.Size; + // prop = ref2.Size; break; } - case kpidPosition: - { - /* - if (ref2.Refs.Size() > 1) - prop = ref2.StartPos; - else - */ - if (item.IsStartPosDefined) - prop = item.StartPos; - break; - } - case kpidPackedSize: + case kpidPackSize: { // prop = ref2.PackSize; { - CNum folderIndex = _database.FileIndexToFolderIndexMap[index2]; + CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; if (folderIndex != kNumNoIndex) { - if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2) - prop = _database.GetFolderFullPackSize(folderIndex); + if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2) + prop = _db.GetFolderFullPackSize(folderIndex); /* else prop = (UInt64)0; @@ -273,35 +258,21 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va } break; } - case kpidLastAccessTime: - MySetFileTime(item.IsLastAccessTimeDefined, item.LastAccessTime, prop); - break; - case kpidCreationTime: - MySetFileTime(item.IsCreationTimeDefined, item.CreationTime, prop); - break; - case kpidLastWriteTime: - MySetFileTime(item.IsLastWriteTimeDefined, item.LastWriteTime, prop); - break; - case kpidAttributes: - if (item.AreAttributesDefined) - prop = item.Attributes; - break; - case kpidCRC: - if (item.IsFileCRCDefined) - prop = item.FileCRC; - break; - case kpidEncrypted: - { - prop = IsEncrypted(index2); - break; - } + case kpidPosition: { UInt64 v; if (_db.StartPos.GetItem(index2, v)) prop = v; break; } + case kpidCTime: SetPropFromUInt64Def(_db.CTime, index2, prop); break; + case kpidATime: SetPropFromUInt64Def(_db.ATime, index2, prop); break; + case kpidMTime: SetPropFromUInt64Def(_db.MTime, index2, prop); break; + case kpidAttrib: if (item.AttribDefined) prop = item.Attrib; break; + case kpidCRC: if (item.CrcDefined) prop = item.Crc; break; + case kpidEncrypted: prop = IsEncrypted(index2); break; + case kpidIsAnti: prop = _db.IsItemAnti(index2); break; #ifndef _SFX case kpidMethod: { - CNum folderIndex = _database.FileIndexToFolderIndexMap[index2]; + CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; if (folderIndex != kNumNoIndex) { - const CFolder &folderInfo = _database.Folders[folderIndex]; + const CFolder &folderInfo = _db.Folders[folderIndex]; UString methodsString; for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--) { @@ -312,7 +283,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va { UString methodName; bool methodIsKnown = FindMethod( - EXTERNAL_CODECS_VARS + EXTERNAL_CODECS_VARS coderInfo.MethodID, methodName); if (methodIsKnown) @@ -398,7 +369,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va break; case kpidBlock: { - CNum folderIndex = _database.FileIndexToFolderIndexMap[index2]; + CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; if (folderIndex != kNumNoIndex) prop = (UInt32)folderIndex; } @@ -409,14 +380,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va case kpidPackedSize3: case kpidPackedSize4: { - CNum folderIndex = _database.FileIndexToFolderIndexMap[index2]; + CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; if (folderIndex != kNumNoIndex) { - const CFolder &folderInfo = _database.Folders[folderIndex]; - if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2 && + const CFolder &folderInfo = _db.Folders[folderIndex]; + if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2 && folderInfo.PackStreams.Size() > (int)(propID - kpidPackedSize0)) { - prop = _database.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0); + prop = _db.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0); } else prop = (UInt64)0; @@ -426,97 +397,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va } break; #endif - case kpidIsAnti: - prop = item.IsAnti; - break; } prop.Detach(value); return S_OK; COM_TRY_END } -#ifdef _7Z_VOL - -static const wchar_t *kExt = L"7z"; -static const wchar_t *kAfterPart = L".7z"; - -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 @@ -527,11 +415,6 @@ STDMETHODIMP CHandler::Open(IInStream *stream, try { CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = openArchiveCallback; - #ifdef _7Z_VOL - CVolumeName seqName; - - CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback; - #endif #ifndef _NO_CRYPTO CMyComPtr<ICryptoGetTextPassword> getTextPassword; @@ -541,127 +424,22 @@ STDMETHODIMP CHandler::Open(IInStream *stream, IID_ICryptoGetTextPassword, &getTextPassword); } #endif - #ifdef _7Z_VOL - if (openArchiveCallback) - { - openArchiveCallbackTemp.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback); - } - for (;;) - { - CMyComPtr<IInStream> inStream; - if (!_volumes.IsEmpty()) - { - if (!openVolumeCallback) - break; - if(_volumes.Size() == 1) - { - UString baseName; - { - NCOM::CPropVariant prop; - RINOK(openVolumeCallback->GetProperty(kpidName, &prop)); - if (prop.vt != VT_BSTR) - break; - baseName = prop.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)); + #ifndef _NO_CRYPTO + _passwordIsDefined = false; + UString password; + #endif HRESULT result = archive.ReadDatabase( EXTERNAL_CODECS_VARS - _database + _db #ifndef _NO_CRYPTO - , getTextPassword + , getTextPassword, _passwordIsDefined #endif ); RINOK(result); - _database.Fill(); + _db.Fill(); _inStream = stream; - #endif } catch(...) { @@ -679,75 +457,12 @@ STDMETHODIMP CHandler::Open(IInStream *stream, STDMETHODIMP CHandler::Close() { COM_TRY_BEGIN - #ifdef _7Z_VOL - _volumes.Clear(); - _refs.Clear(); - #else _inStream.Release(); - _database.Clear(); - #endif + _db.Clear(); 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; - if (coder.MethodID != k_Copy) - 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 - - #ifdef __7Z_SET_PROPERTIES #ifdef EXTRACT_ONLY @@ -783,7 +498,7 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v } return S_OK; COM_TRY_END -} +} #endif #endif diff --git a/CPP/7zip/Archive/7z/7zHandler.h b/CPP/7zip/Archive/7z/7zHandler.h index ad4df41f..9adf8464 100755 --- a/CPP/7zip/Archive/7z/7zHandler.h +++ b/CPP/7zip/Archive/7z/7zHandler.h @@ -18,56 +18,35 @@ namespace NArchive { namespace N7z { -#ifdef _7Z_VOL -struct CRef -{ - int VolumeIndex; - int ItemIndex; -}; - -struct CVolume -{ - int StartRef2Index; - CMyComPtr<IInStream> Stream; - CArchiveDatabaseEx Database; -}; -#endif - #ifndef __7Z_SET_PROPERTIES #ifdef EXTRACT_ONLY #ifdef COMPRESS_MT #define __7Z_SET_PROPERTIES #endif -#else +#else #define __7Z_SET_PROPERTIES #endif #endif -class CHandler: +class CHandler: #ifndef EXTRACT_ONLY public NArchive::COutHandler, #endif public IInArchive, - #ifdef _7Z_VOL - public IInArchiveGetStream, - #endif #ifdef __7Z_SET_PROPERTIES - public ISetProperties, + public ISetProperties, #endif #ifndef EXTRACT_ONLY - public IOutArchive, + public IOutArchive, #endif PUBLIC_ISetCompressCodecsInfo public CMyUnknownImp { public: MY_QUERYINTERFACE_BEGIN2(IInArchive) - #ifdef _7Z_VOL - MY_QUERYINTERFACE_ENTRY(IInArchiveGetStream) - #endif #ifdef __7Z_SET_PROPERTIES MY_QUERYINTERFACE_ENTRY(ISetProperties) #endif @@ -80,10 +59,6 @@ public: INTERFACE_IInArchive(;) - #ifdef _7Z_VOL - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); - #endif - #ifdef __7Z_SET_PROPERTIES STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties); #endif @@ -97,12 +72,10 @@ public: CHandler(); private: - #ifdef _7Z_VOL - CObjectVector<CVolume> _volumes; - CObjectVector<CRef> _refs; - #else CMyComPtr<IInStream> _inStream; - NArchive::N7z::CArchiveDatabaseEx _database; + NArchive::N7z::CArchiveDatabaseEx _db; + #ifndef _NO_CRYPTO + bool _passwordIsDefined; #endif #ifdef EXTRACT_ONLY @@ -139,6 +112,8 @@ private: void FillPopIDs(); #endif + + DECL_EXTERNAL_CODECS_VARS }; }} diff --git a/CPP/7zip/Archive/7z/7zHandlerOut.cpp b/CPP/7zip/Archive/7z/7zHandlerOut.cpp index af4b9427..ac9ef987 100755 --- a/CPP/7zip/Archive/7z/7zHandlerOut.cpp +++ b/CPP/7zip/Archive/7z/7zHandlerOut.cpp @@ -163,7 +163,7 @@ HRESULT CHandler::SetCompressionMethod( for (int j = 0; j < methodFull.Properties.Size(); j++) { const CProp &prop = methodFull.Properties[j]; - if ((prop.Id == NCoderPropID::kDictionarySize || + if ((prop.Id == NCoderPropID::kDictionarySize || prop.Id == NCoderPropID::kUsedMemorySize) && prop.Value.vt == VT_UI4) { _numSolidBytes = ((UInt64)prop.Value.ulVal) << 7; @@ -185,17 +185,20 @@ HRESULT CHandler::SetCompressionMethod( return S_OK; } -static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, PROPID propID, CArchiveFileTime &filetime, bool &filetimeIsDefined) +static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, bool writeTime, PROPID propID, UInt64 &ft, bool &ftDefined) { - filetimeIsDefined = false; - NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(index, propID, &propVariant)); - if (propVariant.vt == VT_FILETIME) + ft = 0; + ftDefined = false; + if (!writeTime) + return S_OK; + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(index, propID, &prop)); + if (prop.vt == VT_FILETIME) { - filetime = propVariant.filetime; - filetimeIsDefined = true; + ft = prop.filetime.dwLowDateTime | ((UInt64)prop.filetime.dwHighDateTime << 32); + ftDefined = true; } - else if (propVariant.vt != VT_EMPTY) + else if (prop.vt != VT_EMPTY) return E_INVALIDARG; return S_OK; } @@ -205,7 +208,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt { COM_TRY_BEGIN - const CArchiveDatabaseEx *database = 0; + const CArchiveDatabaseEx *db = 0; #ifdef _7Z_VOL if(_volumes.Size() > 1) return E_FAIL; @@ -213,139 +216,131 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt if (_volumes.Size() == 1) { volume = &_volumes.Front(); - database = &volume->Database; + db = &volume->Database; } #else if (_inStream != 0) - database = &_database; + db = &_db; #endif - // CRecordVector<bool> compressStatuses; CObjectVector<CUpdateItem> updateItems; - // CRecordVector<UInt32> copyIndices; - // CMyComPtr<IUpdateCallback2> updateCallback2; - // updateCallback->QueryInterface(&updateCallback2); - - for(UInt32 i = 0; i < numItems; i++) + for (UInt32 i = 0; i < numItems; i++) { Int32 newData; Int32 newProperties; UInt32 indexInArchive; if (!updateCallback) return E_FAIL; - RINOK(updateCallback->GetUpdateItemInfo(i, - &newData, &newProperties, &indexInArchive)); - CUpdateItem updateItem; - updateItem.NewProperties = IntToBool(newProperties); - updateItem.NewData = IntToBool(newData); - updateItem.IndexInArchive = indexInArchive; - updateItem.IndexInClient = i; - updateItem.IsAnti = false; - updateItem.Size = 0; - - if (updateItem.IndexInArchive != -1) + RINOK(updateCallback->GetUpdateItemInfo(i, &newData, &newProperties, &indexInArchive)); + CUpdateItem ui; + ui.NewProperties = IntToBool(newProperties); + ui.NewData = IntToBool(newData); + ui.IndexInArchive = indexInArchive; + ui.IndexInClient = i; + ui.IsAnti = false; + ui.Size = 0; + + if (ui.IndexInArchive != -1) { - const CFileItem &fileItem = database->Files[updateItem.IndexInArchive]; - updateItem.Name = fileItem.Name; - updateItem.IsDirectory = fileItem.IsDirectory; - updateItem.Size = fileItem.UnPackSize; - updateItem.IsAnti = fileItem.IsAnti; + const CFileItem &fi = db->Files[ui.IndexInArchive]; + ui.Name = fi.Name; + ui.IsDir = fi.IsDir; + ui.Size = fi.Size; + ui.IsAnti = db->IsItemAnti(ui.IndexInArchive); - updateItem.CreationTime = fileItem.CreationTime; - updateItem.IsCreationTimeDefined = fileItem.IsCreationTimeDefined; - updateItem.LastWriteTime = fileItem.LastWriteTime; - updateItem.IsLastWriteTimeDefined = fileItem.IsLastWriteTimeDefined; - updateItem.LastAccessTime = fileItem.LastAccessTime; - updateItem.IsLastAccessTimeDefined = fileItem.IsLastAccessTimeDefined; + ui.CTimeDefined = db->CTime.GetItem(ui.IndexInArchive, ui.CTime); + ui.ATimeDefined = db->ATime.GetItem(ui.IndexInArchive, ui.ATime); + ui.MTimeDefined = db->MTime.GetItem(ui.IndexInArchive, ui.MTime); } - if (updateItem.NewProperties) + if (ui.NewProperties) { bool nameIsDefined; bool folderStatusIsDefined; { - NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(i, kpidAttributes, &propVariant)); - if (propVariant.vt == VT_EMPTY) - updateItem.AttributesAreDefined = false; - else if (propVariant.vt != VT_UI4) + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(i, kpidAttrib, &prop)); + if (prop.vt == VT_EMPTY) + ui.AttribDefined = false; + else if (prop.vt != VT_UI4) return E_INVALIDARG; else { - updateItem.Attributes = propVariant.ulVal; - updateItem.AttributesAreDefined = true; + ui.Attrib = prop.ulVal; + ui.AttribDefined = true; } } - RINOK(GetTime(updateCallback, i, kpidCreationTime, updateItem.CreationTime, updateItem.IsCreationTimeDefined)); - RINOK(GetTime(updateCallback, i, kpidLastWriteTime, updateItem.LastWriteTime , updateItem.IsLastWriteTimeDefined)); - RINOK(GetTime(updateCallback, i, kpidLastAccessTime, updateItem.LastAccessTime, updateItem.IsLastAccessTimeDefined)); + // we need MTime to sort files. + RINOK(GetTime(updateCallback, i, WriteCTime, kpidCTime, ui.CTime, ui.CTimeDefined)); + RINOK(GetTime(updateCallback, i, WriteATime, kpidATime, ui.ATime, ui.ATimeDefined)); + RINOK(GetTime(updateCallback, i, true, kpidMTime, ui.MTime, ui.MTimeDefined)); { - NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(i, kpidPath, &propVariant)); - if (propVariant.vt == VT_EMPTY) + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(i, kpidPath, &prop)); + if (prop.vt == VT_EMPTY) nameIsDefined = false; - else if (propVariant.vt != VT_BSTR) + else if (prop.vt != VT_BSTR) return E_INVALIDARG; else { - updateItem.Name = NItemName::MakeLegalName(propVariant.bstrVal); + ui.Name = NItemName::MakeLegalName(prop.bstrVal); nameIsDefined = true; } } { - NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(i, kpidIsFolder, &propVariant)); - if (propVariant.vt == VT_EMPTY) + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(i, kpidIsDir, &prop)); + if (prop.vt == VT_EMPTY) folderStatusIsDefined = false; - else if (propVariant.vt != VT_BOOL) + else if (prop.vt != VT_BOOL) return E_INVALIDARG; else { - updateItem.IsDirectory = (propVariant.boolVal != VARIANT_FALSE); + ui.IsDir = (prop.boolVal != VARIANT_FALSE); folderStatusIsDefined = true; } } { - NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(i, kpidIsAnti, &propVariant)); - if (propVariant.vt == VT_EMPTY) - updateItem.IsAnti = false; - else if (propVariant.vt != VT_BOOL) + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(i, kpidIsAnti, &prop)); + if (prop.vt == VT_EMPTY) + ui.IsAnti = false; + else if (prop.vt != VT_BOOL) return E_INVALIDARG; else - updateItem.IsAnti = (propVariant.boolVal != VARIANT_FALSE); + ui.IsAnti = (prop.boolVal != VARIANT_FALSE); } - if (updateItem.IsAnti) + if (ui.IsAnti) { - updateItem.AttributesAreDefined = false; + ui.AttribDefined = false; - updateItem.IsCreationTimeDefined = false; - updateItem.IsLastWriteTimeDefined = false; - updateItem.IsLastAccessTimeDefined = false; + ui.CTimeDefined = false; + ui.ATimeDefined = false; + ui.MTimeDefined = false; - updateItem.Size = 0; + ui.Size = 0; } - if (!folderStatusIsDefined && updateItem.AttributesAreDefined) - updateItem.SetDirectoryStatusFromAttributes(); + if (!folderStatusIsDefined && ui.AttribDefined) + ui.SetDirStatusFromAttrib(); } - if (updateItem.NewData) + if (ui.NewData) { - NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(i, kpidSize, &propVariant)); - if (propVariant.vt != VT_UI8) + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(i, kpidSize, &prop)); + if (prop.vt != VT_UI8) return E_INVALIDARG; - updateItem.Size = (UInt64)propVariant.uhVal.QuadPart; - if (updateItem.Size != 0 && updateItem.IsAnti) + ui.Size = (UInt64)prop.uhVal.QuadPart; + if (ui.Size != 0 && ui.IsAnti) return E_INVALIDARG; } - updateItems.Add(updateItem); + updateItems.Add(ui); } CCompressionMethodMode methodMode, headerMethod; @@ -359,10 +354,18 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt bool compressMainHeader = _compressHeaders; // check it + bool encryptHeaders = false; + if (methodMode.PasswordIsDefined) { - compressMainHeader = true; - if(_encryptHeaders) + if (_encryptHeadersSpecified) + encryptHeaders = _encryptHeaders; + #ifndef _NO_CRYPTO + else + encryptHeaders = _passwordIsDefined; + #endif + compressMainHeader = true; + if(encryptHeaders) RINOK(SetPassword(headerMethod, updateCallback)); } @@ -371,32 +374,42 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt CUpdateOptions options; options.Method = &methodMode; - options.HeaderMethod = (_compressHeaders || - (methodMode.PasswordIsDefined && _encryptHeaders)) ? - &headerMethod : 0; + options.HeaderMethod = (_compressHeaders || encryptHeaders) ? &headerMethod : 0; options.UseFilters = _level != 0 && _autoFilter; options.MaxFilter = _level >= 8; options.HeaderOptions.CompressMainHeader = compressMainHeader; - options.HeaderOptions.WriteModified = WriteModified; - options.HeaderOptions.WriteCreated = WriteCreated; - options.HeaderOptions.WriteAccessed = WriteAccessed; + options.HeaderOptions.WriteCTime = WriteCTime; + options.HeaderOptions.WriteATime = WriteATime; + options.HeaderOptions.WriteMTime = WriteMTime; options.NumSolidFiles = _numSolidFiles; options.NumSolidBytes = _numSolidBytes; options.SolidExtension = _solidExtension; options.RemoveSfxBlock = _removeSfxBlock; options.VolumeMode = _volumeMode; - return Update( + + COutArchive archive; + CArchiveDatabase newDatabase; + HRESULT res = Update( EXTERNAL_CODECS_VARS #ifdef _7Z_VOL - volume ? volume->Stream: 0, - volume ? database: 0, + volume ? volume->Stream: 0, + volume ? db : 0, #else - _inStream, - database, + _inStream, + db, #endif - updateItems, outStream, updateCallback, options); + updateItems, + archive, newDatabase, outStream, updateCallback, options); + + RINOK(res); + + updateItems.ClearAndFree(); + + return archive.WriteDatabase(EXTERNAL_CODECS_VARS + newDatabase, options.HeaderMethod, options.HeaderOptions); + COM_TRY_END } @@ -459,6 +472,6 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v return S_OK; COM_TRY_END -} +} }} diff --git a/CPP/7zip/Archive/7z/7zHeader.cpp b/CPP/7zip/Archive/7z/7zHeader.cpp index 425231fc..f232a23e 100755 --- a/CPP/7zip/Archive/7z/7zHeader.cpp +++ b/CPP/7zip/Archive/7z/7zHeader.cpp @@ -14,9 +14,9 @@ Byte kFinishSignature[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C + class SignatureInitializer { public: - SignatureInitializer() - { - kSignature[0]--; + SignatureInitializer() + { + kSignature[0]--; #ifdef _7Z_VOL kFinishSignature[0]--; #endif diff --git a/CPP/7zip/Archive/7z/7zHeader.h b/CPP/7zip/Archive/7z/7zHeader.h index e239ab23..30622b90 100755 --- a/CPP/7zip/Archive/7z/7zHeader.h +++ b/CPP/7zip/Archive/7z/7zHeader.h @@ -13,7 +13,7 @@ extern Byte kSignature[kSignatureSize]; // #define _7Z_VOL // 7z-MultiVolume is not finished yet. -// It can work already, but I still do not like some +// It can work already, but I still do not like some // things of that new multivolume format. // So please keep it commented. @@ -63,7 +63,7 @@ namespace NID kFilesInfo, kPackInfo, - kUnPackInfo, + kUnpackInfo, kSubStreamsInfo, kSize, @@ -71,23 +71,24 @@ namespace NID kFolder, - kCodersUnPackSize, - kNumUnPackStream, + kCodersUnpackSize, + kNumUnpackStream, kEmptyStream, kEmptyFile, kAnti, kName, - kCreationTime, - kLastAccessTime, - kLastWriteTime, + kCTime, + kATime, + kMTime, kWinAttributes, kComment, kEncodedHeader, - kStartPos + kStartPos, + kDummy }; } diff --git a/CPP/7zip/Archive/7z/7zIn.cpp b/CPP/7zip/Archive/7z/7zIn.cpp index f892e0cd..6cf3fdf6 100755 --- a/CPP/7zip/Archive/7z/7zIn.cpp +++ b/CPP/7zip/Archive/7z/7zIn.cpp @@ -6,13 +6,17 @@ #include "7zDecode.h" #include "../../Common/StreamObjects.h" #include "../../Common/StreamUtils.h" -extern "C" -{ -#include "../../../../C/7zCrc.h" -#include "../../../../C/CpuArch.h" +extern "C" +{ + #include "../../../../C/7zCrc.h" + #include "../../../../C/CpuArch.h" } -// define FORMAT_7Z_RECOVERY if you want to recover multivolume archives with empty StartHeader +#define Get16(p) GetUi16(p) +#define Get32(p) GetUi32(p) +#define Get64(p) GetUi64(p) + +// define FORMAT_7Z_RECOVERY if you want to recover multivolume archives with empty StartHeader #ifndef _SFX #define FORMAT_7Z_RECOVERY #endif @@ -36,7 +40,7 @@ public: { kUnsupportedVersion = 0, kUnsupported, - kIncorrect, + kIncorrect, kEndOfData, } Cause; CInArchiveException(CCauseType cause): Cause(cause) {}; @@ -97,16 +101,6 @@ void CStreamSwitch::Set(CInArchive *archive, const CObjectVector<CByteBuffer> *d } } -#ifdef LITTLE_ENDIAN_UNALIGN -static inline UInt16 GetUInt16FromMem(const Byte *p) { return *(const UInt16 *)p; } -static inline UInt32 GetUInt32FromMem(const Byte *p) { return *(const UInt32 *)p; } -static inline UInt64 GetUInt64FromMem(const Byte *p) { return *(const UInt64 *)p; } -#else -static inline UInt16 GetUInt16FromMem(const Byte *p) { return p[0] | ((UInt16)p[1] << 8); } -static inline UInt32 GetUInt32FromMem(const Byte *p) { return p[0] | ((UInt32)p[1] << 8) | ((UInt32)p[2] << 16) | ((UInt32)p[3] << 24); } -static inline UInt64 GetUInt64FromMem(const Byte *p) { return GetUInt32FromMem(p) | ((UInt64)GetUInt32FromMem(p + 4) << 32); } -#endif - Byte CInByte2::ReadByte() { if (_pos >= _size) @@ -126,6 +120,7 @@ void CInByte2::SkeepData(UInt64 size) { if (size > _size - _pos) ThrowEndOfData(); + _pos += (size_t)size; } void CInByte2::SkeepData() @@ -157,8 +152,8 @@ UInt64 CInByte2::ReadNumber() } CNum CInByte2::ReadNum() -{ - UInt64 value = ReadNumber(); +{ + UInt64 value = ReadNumber(); if (value > kNumMax) ThrowUnsupported(); return (CNum)value; @@ -168,7 +163,7 @@ UInt32 CInByte2::ReadUInt32() { if (_pos + 4 > _size) ThrowEndOfData(); - UInt32 res = GetUInt32FromMem(_buffer + _pos); + UInt32 res = Get32(_buffer + _pos); _pos += 4; return res; } @@ -177,7 +172,7 @@ UInt64 CInByte2::ReadUInt64() { if (_pos + 8 > _size) ThrowEndOfData(); - UInt64 res = GetUInt64FromMem(_buffer + _pos); + UInt64 res = Get64(_buffer + _pos); _pos += 8; return res; } @@ -200,9 +195,8 @@ void CInByte2::ReadString(UString &s) ThrowUnsupported(); wchar_t *p = s.GetBuffer(len); int i; - for (i = 0; i < len; i++, buf += 2) - p[i] = (wchar_t)GetUInt16FromMem(buf); - p[i] = 0; + for (i = 0; i < len; i++, buf += 2) + p[i] = (wchar_t)Get16(buf); s.ReleaseBuffer(len); _pos += rem + 2; } @@ -234,23 +228,32 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search if (searchHeaderSizeLimit != NULL) if (curTestPos - _arhiveBeginStreamPosition > *searchHeaderSizeLimit) break; - UInt32 numReadBytes = kBufferSize - numPrevBytes; - UInt32 processedSize; - RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize)); - UInt32 numBytesInBuffer = numPrevBytes + processedSize; - if (numBytesInBuffer < kHeaderSize) - break; - UInt32 numTests = numBytesInBuffer - kHeaderSize + 1; - for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++) - { + do + { + UInt32 numReadBytes = kBufferSize - numPrevBytes; + UInt32 processedSize; + RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize)); + numPrevBytes += processedSize; + if (processedSize == 0) + return S_FALSE; + } + while (numPrevBytes < kHeaderSize); + UInt32 numTests = numPrevBytes - kHeaderSize + 1; + for (UInt32 pos = 0; pos < numTests; pos++) + { + for (; buffer[pos] != '7' && pos < numTests; pos++); + if (pos == numTests) + break; if (TestSignatureCandidate(buffer + pos)) { memcpy(_header, buffer + pos, kHeaderSize); + curTestPos += pos; _arhiveBeginStreamPosition = curTestPos; return stream->Seek(curTestPos + kHeaderSize, STREAM_SEEK_SET, NULL); } } - numPrevBytes = numBytesInBuffer - numTests; + curTestPos += numTests; + numPrevBytes -= numTests; memmove(buffer, buffer + numTests, numPrevBytes); } return S_FALSE; @@ -259,6 +262,7 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search // S_FALSE means that file is not archive HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit) { + HeadersSize = 0; Close(); RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_arhiveBeginStreamPosition)) RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit)); @@ -338,7 +342,7 @@ void CInArchive::GetNextFolderItem(CFolder &folder) { CBindPair bindPair; bindPair.InIndex = ReadNum(); - bindPair.OutIndex = ReadNum(); + bindPair.OutIndex = ReadNum(); folder.BindPairs.Add(bindPair); } @@ -354,7 +358,7 @@ void CInArchive::GetNextFolderItem(CFolder &folder) } } else - for(i = 0; i < numPackedStreams; i++) + for (i = 0; i < numPackedStreams; i++) folder.PackStreams.Add(ReadNum()); } @@ -372,13 +376,13 @@ void CInArchive::WaitAttribute(UInt64 attribute) } void CInArchive::ReadHashDigests(int numItems, - CRecordVector<bool> &digestsDefined, + CRecordVector<bool> &digestsDefined, CRecordVector<UInt32> &digests) { ReadBoolVector2(numItems, digestsDefined); digests.Clear(); digests.Reserve(numItems); - for(int i = 0; i < numItems; i++) + for (int i = 0; i < numItems; i++) { UInt32 crc = 0; if (digestsDefined[i]) @@ -410,7 +414,7 @@ void CInArchive::ReadPackInfo( break; if (type == NID::kCRC) { - ReadHashDigests(numPackStreams, packCRCsDefined, packCRCs); + ReadHashDigests(numPackStreams, packCRCsDefined, packCRCs); continue; } SkeepData(); @@ -421,7 +425,7 @@ void CInArchive::ReadPackInfo( packCRCsDefined.Clear(); packCRCs.Reserve(numPackStreams); packCRCs.Clear(); - for(CNum i = 0; i < numPackStreams; i++) + for (CNum i = 0; i < numPackStreams; i++) { packCRCsDefined.Add(false); packCRCs.Add(0); @@ -429,7 +433,7 @@ void CInArchive::ReadPackInfo( } } -void CInArchive::ReadUnPackInfo( +void CInArchive::ReadUnpackInfo( const CObjectVector<CByteBuffer> *dataVector, CObjectVector<CFolder> &folders) { @@ -441,23 +445,23 @@ void CInArchive::ReadUnPackInfo( streamSwitch.Set(this, dataVector); folders.Clear(); folders.Reserve(numFolders); - for(CNum i = 0; i < numFolders; i++) + for (CNum i = 0; i < numFolders; i++) { folders.Add(CFolder()); GetNextFolderItem(folders.Back()); } } - WaitAttribute(NID::kCodersUnPackSize); + WaitAttribute(NID::kCodersUnpackSize); CNum i; for (i = 0; i < numFolders; i++) { CFolder &folder = folders[i]; CNum numOutStreams = folder.GetNumOutStreams(); - folder.UnPackSizes.Reserve(numOutStreams); + folder.UnpackSizes.Reserve(numOutStreams); for (CNum j = 0; j < numOutStreams; j++) - folder.UnPackSizes.Add(ReadNumber()); + folder.UnpackSizes.Add(ReadNumber()); } for (;;) @@ -469,12 +473,12 @@ void CInArchive::ReadUnPackInfo( { CRecordVector<bool> crcsDefined; CRecordVector<UInt32> crcs; - ReadHashDigests(numFolders, crcsDefined, crcs); - for(i = 0; i < numFolders; i++) + ReadHashDigests(numFolders, crcsDefined, crcs); + for (i = 0; i < numFolders; i++) { CFolder &folder = folders[i]; - folder.UnPackCRCDefined = crcsDefined[i]; - folder.UnPackCRC = crcs[i]; + folder.UnpackCRCDefined = crcsDefined[i]; + folder.UnpackCRC = crcs[i]; } continue; } @@ -484,21 +488,21 @@ void CInArchive::ReadUnPackInfo( void CInArchive::ReadSubStreamsInfo( const CObjectVector<CFolder> &folders, - CRecordVector<CNum> &numUnPackStreamsInFolders, - CRecordVector<UInt64> &unPackSizes, - CRecordVector<bool> &digestsDefined, + CRecordVector<CNum> &numUnpackStreamsInFolders, + CRecordVector<UInt64> &unpackSizes, + CRecordVector<bool> &digestsDefined, CRecordVector<UInt32> &digests) { - numUnPackStreamsInFolders.Clear(); - numUnPackStreamsInFolders.Reserve(folders.Size()); + numUnpackStreamsInFolders.Clear(); + numUnpackStreamsInFolders.Reserve(folders.Size()); UInt64 type; for (;;) { type = ReadID(); - if (type == NID::kNumUnPackStream) + if (type == NID::kNumUnpackStream) { - for(int i = 0; i < folders.Size(); i++) - numUnPackStreamsInFolders.Add(ReadNum()); + for (int i = 0; i < folders.Size(); i++) + numUnpackStreamsInFolders.Add(ReadNum()); continue; } if (type == NID::kCRC || type == NID::kSize) @@ -508,16 +512,16 @@ void CInArchive::ReadSubStreamsInfo( SkeepData(); } - if (numUnPackStreamsInFolders.IsEmpty()) - for(int i = 0; i < folders.Size(); i++) - numUnPackStreamsInFolders.Add(1); + if (numUnpackStreamsInFolders.IsEmpty()) + for (int i = 0; i < folders.Size(); i++) + numUnpackStreamsInFolders.Add(1); int i; - for(i = 0; i < numUnPackStreamsInFolders.Size(); i++) + for (i = 0; i < numUnpackStreamsInFolders.Size(); i++) { // v3.13 incorrectly worked with empty folders // v4.07: we check that folder is empty - CNum numSubstreams = numUnPackStreamsInFolders[i]; + CNum numSubstreams = numUnpackStreamsInFolders[i]; if (numSubstreams == 0) continue; UInt64 sum = 0; @@ -525,20 +529,20 @@ void CInArchive::ReadSubStreamsInfo( if (type == NID::kSize) { UInt64 size = ReadNumber(); - unPackSizes.Add(size); + unpackSizes.Add(size); sum += size; } - unPackSizes.Add(folders[i].GetUnPackSize() - sum); + unpackSizes.Add(folders[i].GetUnpackSize() - sum); } if (type == NID::kSize) type = ReadID(); int numDigests = 0; int numDigestsTotal = 0; - for(i = 0; i < folders.Size(); i++) + for (i = 0; i < folders.Size(); i++) { - CNum numSubstreams = numUnPackStreamsInFolders[i]; - if (numSubstreams != 1 || !folders[i].UnPackCRCDefined) + CNum numSubstreams = numUnpackStreamsInFolders[i]; + if (numSubstreams != 1 || !folders[i].UnpackCRCDefined) numDigests += numSubstreams; numDigestsTotal += numSubstreams; } @@ -547,18 +551,18 @@ void CInArchive::ReadSubStreamsInfo( { if (type == NID::kCRC) { - CRecordVector<bool> digestsDefined2; + CRecordVector<bool> digestsDefined2; CRecordVector<UInt32> digests2; ReadHashDigests(numDigests, digestsDefined2, digests2); int digestIndex = 0; for (i = 0; i < folders.Size(); i++) { - CNum numSubstreams = numUnPackStreamsInFolders[i]; + CNum numSubstreams = numUnpackStreamsInFolders[i]; const CFolder &folder = folders[i]; - if (numSubstreams == 1 && folder.UnPackCRCDefined) + if (numSubstreams == 1 && folder.UnpackCRCDefined) { digestsDefined.Add(true); - digests.Add(folder.UnPackCRC); + digests.Add(folder.UnpackCRC); } else for (CNum j = 0; j < numSubstreams; j++, digestIndex++) @@ -595,9 +599,9 @@ void CInArchive::ReadStreamsInfo( CRecordVector<bool> &packCRCsDefined, CRecordVector<UInt32> &packCRCs, CObjectVector<CFolder> &folders, - CRecordVector<CNum> &numUnPackStreamsInFolders, - CRecordVector<UInt64> &unPackSizes, - CRecordVector<bool> &digestsDefined, + CRecordVector<CNum> &numUnpackStreamsInFolders, + CRecordVector<UInt64> &unpackSizes, + CRecordVector<bool> &digestsDefined, CRecordVector<UInt32> &digests) { for (;;) @@ -614,15 +618,15 @@ void CInArchive::ReadStreamsInfo( ReadPackInfo(dataOffset, packSizes, packCRCsDefined, packCRCs); break; } - case NID::kUnPackInfo: + case NID::kUnpackInfo: { - ReadUnPackInfo(dataVector, folders); + ReadUnpackInfo(dataVector, folders); break; } case NID::kSubStreamsInfo: { - ReadSubStreamsInfo(folders, numUnPackStreamsInFolders, - unPackSizes, digestsDefined, digests); + ReadSubStreamsInfo(folders, numUnpackStreamsInFolders, + unpackSizes, digestsDefined, digests); break; } default: @@ -637,7 +641,7 @@ void CInArchive::ReadBoolVector(int numItems, CBoolVector &v) v.Reserve(numItems); Byte b = 0; Byte mask = 0; - for(int i = 0; i < numItems; i++) + for (int i = 0; i < numItems; i++) { if (mask == 0) { @@ -663,54 +667,30 @@ void CInArchive::ReadBoolVector2(int numItems, CBoolVector &v) v.Add(true); } -void CInArchive::ReadTime(const CObjectVector<CByteBuffer> &dataVector, - CObjectVector<CFileItem> &files, UInt32 type) +void CInArchive::ReadUInt64DefVector(const CObjectVector<CByteBuffer> &dataVector, + CUInt64DefVector &v, int numFiles) { - CBoolVector boolVector; - ReadBoolVector2(files.Size(), boolVector); + ReadBoolVector2(numFiles, v.Defined); CStreamSwitch streamSwitch; streamSwitch.Set(this, &dataVector); + v.Values.Reserve(numFiles); - for(int i = 0; i < files.Size(); i++) + for (int i = 0; i < numFiles; i++) { - CFileItem &file = files[i]; - CArchiveFileTime fileTime; - fileTime.dwLowDateTime = 0; - fileTime.dwHighDateTime = 0; - bool defined = boolVector[i]; - if (defined) - { - fileTime.dwLowDateTime = ReadUInt32(); - fileTime.dwHighDateTime = ReadUInt32(); - } - switch(type) - { - case NID::kCreationTime: - file.IsCreationTimeDefined = defined; - if (defined) - file.CreationTime = fileTime; - break; - case NID::kLastWriteTime: - file.IsLastWriteTimeDefined = defined; - if (defined) - file.LastWriteTime = fileTime; - break; - case NID::kLastAccessTime: - file.IsLastAccessTimeDefined = defined; - if (defined) - file.LastAccessTime = fileTime; - break; - } + UInt64 t = 0; + if (v.Defined[i]) + t = ReadUInt64(); + v.Values.Add(t); } } HRESULT CInArchive::ReadAndDecodePackedStreams( DECL_EXTERNAL_CODECS_LOC_VARS - UInt64 baseOffset, + UInt64 baseOffset, UInt64 &dataOffset, CObjectVector<CByteBuffer> &dataVector #ifndef _NO_CRYPTO - , ICryptoGetTextPassword *getTextPassword + , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined #endif ) { @@ -719,23 +699,23 @@ HRESULT CInArchive::ReadAndDecodePackedStreams( CRecordVector<UInt32> packCRCs; CObjectVector<CFolder> folders; - CRecordVector<CNum> numUnPackStreamsInFolders; - CRecordVector<UInt64> unPackSizes; + CRecordVector<CNum> numUnpackStreamsInFolders; + CRecordVector<UInt64> unpackSizes; CRecordVector<bool> digestsDefined; CRecordVector<UInt32> digests; - ReadStreamsInfo(NULL, + ReadStreamsInfo(NULL, dataOffset, - packSizes, - packCRCsDefined, - packCRCs, + packSizes, + packCRCsDefined, + packCRCs, folders, - numUnPackStreamsInFolders, - unPackSizes, - digestsDefined, + numUnpackStreamsInFolders, + unpackSizes, + digestsDefined, digests); - // database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader; + // db.ArchiveInfo.DataStartPosition2 += db.ArchiveInfo.StartPositionAfterHeader; CNum packIndex = 0; CDecoder decoder( @@ -746,27 +726,27 @@ HRESULT CInArchive::ReadAndDecodePackedStreams( #endif ); UInt64 dataStartPos = baseOffset + dataOffset; - for(int i = 0; i < folders.Size(); i++) + for (int i = 0; i < folders.Size(); i++) { const CFolder &folder = folders[i]; dataVector.Add(CByteBuffer()); CByteBuffer &data = dataVector.Back(); - UInt64 unPackSize64 = folder.GetUnPackSize(); - size_t unPackSize = (size_t)unPackSize64; - if (unPackSize != unPackSize64) + UInt64 unpackSize64 = folder.GetUnpackSize(); + size_t unpackSize = (size_t)unpackSize64; + if (unpackSize != unpackSize64) ThrowUnsupported(); - data.SetCapacity(unPackSize); + data.SetCapacity(unpackSize); CSequentialOutStreamImp2 *outStreamSpec = new CSequentialOutStreamImp2; CMyComPtr<ISequentialOutStream> outStream = outStreamSpec; - outStreamSpec->Init(data, unPackSize); + outStreamSpec->Init(data, unpackSize); HRESULT result = decoder.Decode( EXTERNAL_CODECS_LOC_VARS - _stream, dataStartPos, + _stream, dataStartPos, &packSizes[packIndex], folder, outStream, NULL #ifndef _NO_CRYPTO - , getTextPassword + , getTextPassword, passwordIsDefined #endif #ifdef COMPRESS_MT , false, 1 @@ -774,20 +754,24 @@ HRESULT CInArchive::ReadAndDecodePackedStreams( ); RINOK(result); - if (folder.UnPackCRCDefined) - if (CrcCalc(data, unPackSize) != folder.UnPackCRC) + if (folder.UnpackCRCDefined) + if (CrcCalc(data, unpackSize) != folder.UnpackCRC) ThrowIncorrect(); - for (int j = 0; j < folder.PackStreams.Size(); j++) - dataStartPos += packSizes[packIndex++]; + for (int j = 0; j < folder.PackStreams.Size(); j++) + { + UInt64 packSize = packSizes[packIndex++]; + dataStartPos += packSize; + HeadersSize += packSize; + } } return S_OK; } HRESULT CInArchive::ReadHeader( DECL_EXTERNAL_CODECS_LOC_VARS - CArchiveDatabaseEx &database + CArchiveDatabaseEx &db #ifndef _NO_CRYPTO - , ICryptoGetTextPassword *getTextPassword + , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined #endif ) { @@ -795,7 +779,7 @@ HRESULT CInArchive::ReadHeader( if (type == NID::kArchiveProperties) { - ReadArchiveProperties(database.ArchiveInfo); + ReadArchiveProperties(db.ArchiveInfo); type = ReadID(); } @@ -805,50 +789,50 @@ HRESULT CInArchive::ReadHeader( { HRESULT result = ReadAndDecodePackedStreams( EXTERNAL_CODECS_LOC_VARS - database.ArchiveInfo.StartPositionAfterHeader, - database.ArchiveInfo.DataStartPosition2, + db.ArchiveInfo.StartPositionAfterHeader, + db.ArchiveInfo.DataStartPosition2, dataVector #ifndef _NO_CRYPTO - , getTextPassword + , getTextPassword, passwordIsDefined #endif ); RINOK(result); - database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader; + db.ArchiveInfo.DataStartPosition2 += db.ArchiveInfo.StartPositionAfterHeader; type = ReadID(); } - CRecordVector<UInt64> unPackSizes; + CRecordVector<UInt64> unpackSizes; CRecordVector<bool> digestsDefined; CRecordVector<UInt32> digests; if (type == NID::kMainStreamsInfo) { ReadStreamsInfo(&dataVector, - database.ArchiveInfo.DataStartPosition, - database.PackSizes, - database.PackCRCsDefined, - database.PackCRCs, - database.Folders, - database.NumUnPackStreamsVector, - unPackSizes, + db.ArchiveInfo.DataStartPosition, + db.PackSizes, + db.PackCRCsDefined, + db.PackCRCs, + db.Folders, + db.NumUnpackStreamsVector, + unpackSizes, digestsDefined, digests); - database.ArchiveInfo.DataStartPosition += database.ArchiveInfo.StartPositionAfterHeader; + db.ArchiveInfo.DataStartPosition += db.ArchiveInfo.StartPositionAfterHeader; type = ReadID(); } else { - for(int i = 0; i < database.Folders.Size(); i++) + for (int i = 0; i < db.Folders.Size(); i++) { - database.NumUnPackStreamsVector.Add(1); - CFolder &folder = database.Folders[i]; - unPackSizes.Add(folder.GetUnPackSize()); - digestsDefined.Add(folder.UnPackCRCDefined); - digests.Add(folder.UnPackCRC); + db.NumUnpackStreamsVector.Add(1); + CFolder &folder = db.Folders[i]; + unpackSizes.Add(folder.GetUnpackSize()); + digestsDefined.Add(folder.UnpackCRCDefined); + digests.Add(folder.UnpackCRC); } } - database.Files.Clear(); + db.Files.Clear(); if (type == NID::kEnd) return S_OK; @@ -856,20 +840,20 @@ HRESULT CInArchive::ReadHeader( ThrowIncorrect(); CNum numFiles = ReadNum(); - database.Files.Reserve(numFiles); + db.Files.Reserve(numFiles); CNum i; - for(i = 0; i < numFiles; i++) - database.Files.Add(CFileItem()); + for (i = 0; i < numFiles; i++) + db.Files.Add(CFileItem()); - database.ArchiveInfo.FileInfoPopIDs.Add(NID::kSize); - if (!database.PackSizes.IsEmpty()) - database.ArchiveInfo.FileInfoPopIDs.Add(NID::kPackInfo); + db.ArchiveInfo.FileInfoPopIDs.Add(NID::kSize); + if (!db.PackSizes.IsEmpty()) + db.ArchiveInfo.FileInfoPopIDs.Add(NID::kPackInfo); if (numFiles > 0 && !digests.IsEmpty()) - database.ArchiveInfo.FileInfoPopIDs.Add(NID::kCRC); + db.ArchiveInfo.FileInfoPopIDs.Add(NID::kCRC); CBoolVector emptyStreamVector; emptyStreamVector.Reserve((int)numFiles); - for(i = 0; i < numFiles; i++) + for (i = 0; i < numFiles; i++) emptyStreamVector.Add(false); CBoolVector emptyFileVector; CBoolVector antiFileVector; @@ -881,6 +865,8 @@ HRESULT CInArchive::ReadHeader( if (type == NID::kEnd) break; UInt64 size = ReadNumber(); + size_t ppp = _inByteBack->_pos; + bool addPropIdToList = true; bool isKnownType = true; if (type > ((UInt32)1 << 30)) isKnownType = false; @@ -890,37 +876,22 @@ HRESULT CInArchive::ReadHeader( { CStreamSwitch streamSwitch; streamSwitch.Set(this, &dataVector); - for(int i = 0; i < database.Files.Size(); i++) - _inByteBack->ReadString(database.Files[i].Name); + for (int i = 0; i < db.Files.Size(); i++) + _inByteBack->ReadString(db.Files[i].Name); break; } case NID::kWinAttributes: { CBoolVector boolVector; - ReadBoolVector2(database.Files.Size(), boolVector); - CStreamSwitch streamSwitch; - streamSwitch.Set(this, &dataVector); - for(i = 0; i < numFiles; i++) - { - CFileItem &file = database.Files[i]; - file.AreAttributesDefined = boolVector[i]; - if (file.AreAttributesDefined) - file.Attributes = ReadUInt32(); - } - break; - } - case NID::kStartPos: - { - CBoolVector boolVector; - ReadBoolVector2(database.Files.Size(), boolVector); + ReadBoolVector2(db.Files.Size(), boolVector); CStreamSwitch streamSwitch; streamSwitch.Set(this, &dataVector); - for(i = 0; i < numFiles; i++) + for (i = 0; i < numFiles; i++) { - CFileItem &file = database.Files[i]; - file.IsStartPosDefined = boolVector[i]; - if (file.IsStartPosDefined) - file.StartPos = ReadUInt64(); + CFileItem &file = db.Files[i]; + file.AttribDefined = boolVector[i]; + if (file.AttribDefined) + file.Attrib = ReadUInt32(); } break; } @@ -939,55 +910,68 @@ HRESULT CInArchive::ReadHeader( } break; } - case NID::kEmptyFile: - { - ReadBoolVector(numEmptyStreams, emptyFileVector); - break; - } - case NID::kAnti: - { - ReadBoolVector(numEmptyStreams, antiFileVector); - break; - } - case NID::kCreationTime: - case NID::kLastWriteTime: - case NID::kLastAccessTime: + case NID::kEmptyFile: ReadBoolVector(numEmptyStreams, emptyFileVector); break; + case NID::kAnti: ReadBoolVector(numEmptyStreams, antiFileVector); break; + case NID::kStartPos: ReadUInt64DefVector(dataVector, db.StartPos, (int)numFiles); break; + case NID::kCTime: ReadUInt64DefVector(dataVector, db.CTime, (int)numFiles); break; + case NID::kATime: ReadUInt64DefVector(dataVector, db.ATime, (int)numFiles); break; + case NID::kMTime: ReadUInt64DefVector(dataVector, db.MTime, (int)numFiles); break; + case NID::kDummy: { - ReadTime(dataVector, database.Files, (UInt32)type); + for (UInt64 j = 0; j < size; j++) + if (ReadByte() != 0) + ThrowIncorrect(); + addPropIdToList = false; break; } default: - isKnownType = false; + addPropIdToList = isKnownType = false; } if (isKnownType) - database.ArchiveInfo.FileInfoPopIDs.Add(type); + { + if(addPropIdToList) + db.ArchiveInfo.FileInfoPopIDs.Add(type); + } else SkeepData(size); + bool checkRecordsSize = (db.ArchiveInfo.Version.Major > 0 || + db.ArchiveInfo.Version.Minor > 2); + if (checkRecordsSize && _inByteBack->_pos - ppp != size) + ThrowIncorrect(); } CNum emptyFileIndex = 0; CNum sizeIndex = 0; - for(i = 0; i < numFiles; i++) + + CNum numAntiItems = 0; + for (i = 0; i < numEmptyStreams; i++) + if (antiFileVector[i]) + numAntiItems++; + + for (i = 0; i < numFiles; i++) { - CFileItem &file = database.Files[i]; + CFileItem &file = db.Files[i]; + bool isAnti; file.HasStream = !emptyStreamVector[i]; - if(file.HasStream) + if (file.HasStream) { - file.IsDirectory = false; - file.IsAnti = false; - file.UnPackSize = unPackSizes[sizeIndex]; - file.FileCRC = digests[sizeIndex]; - file.IsFileCRCDefined = digestsDefined[sizeIndex]; + file.IsDir = false; + isAnti = false; + file.Size = unpackSizes[sizeIndex]; + file.Crc = digests[sizeIndex]; + file.CrcDefined = digestsDefined[sizeIndex]; sizeIndex++; } else { - file.IsDirectory = !emptyFileVector[emptyFileIndex]; - file.IsAnti = antiFileVector[emptyFileIndex]; + file.IsDir = !emptyFileVector[emptyFileIndex]; + isAnti = antiFileVector[emptyFileIndex]; emptyFileIndex++; - file.UnPackSize = 0; - file.IsFileCRCDefined = false; + file.Size = 0; + file.CrcDefined = false; } + if (numAntiItems != 0) + db.IsAnti.Add(isAnti); } return S_OK; } @@ -998,7 +982,7 @@ void CArchiveDatabaseEx::FillFolderStartPackStream() FolderStartPackStreamIndex.Clear(); FolderStartPackStreamIndex.Reserve(Folders.Size()); CNum startPos = 0; - for(int i = 0; i < Folders.Size(); i++) + for (int i = 0; i < Folders.Size(); i++) { FolderStartPackStreamIndex.Add(startPos); startPos += (CNum)Folders[i].PackStreams.Size(); @@ -1010,7 +994,7 @@ void CArchiveDatabaseEx::FillStartPos() PackStreamStartPositions.Clear(); PackStreamStartPositions.Reserve(PackSizes.Size()); UInt64 startPos = 0; - for(int i = 0; i < PackSizes.Size(); i++) + for (int i = 0; i < PackSizes.Size(); i++) { PackStreamStartPositions.Add(startPos); startPos += PackSizes[i]; @@ -1044,7 +1028,7 @@ void CArchiveDatabaseEx::FillFolderStartFileIndex() if (folderIndex >= Folders.Size()) ThrowIncorrect(); FolderStartFileIndex.Add(i); // check it - if (NumUnPackStreamsVector[folderIndex] != 0) + if (NumUnpackStreamsVector[folderIndex] != 0) break; folderIndex++; } @@ -1053,7 +1037,7 @@ void CArchiveDatabaseEx::FillFolderStartFileIndex() if (emptyStream) continue; indexInFolder++; - if (indexInFolder >= NumUnPackStreamsVector[folderIndex]) + if (indexInFolder >= NumUnpackStreamsVector[folderIndex]) { folderIndex++; indexInFolder = 0; @@ -1063,25 +1047,25 @@ void CArchiveDatabaseEx::FillFolderStartFileIndex() HRESULT CInArchive::ReadDatabase2( DECL_EXTERNAL_CODECS_LOC_VARS - CArchiveDatabaseEx &database + CArchiveDatabaseEx &db #ifndef _NO_CRYPTO - , ICryptoGetTextPassword *getTextPassword + , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined #endif ) { - database.Clear(); - database.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition; + db.Clear(); + db.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition; - database.ArchiveInfo.Version.Major = _header[6]; - database.ArchiveInfo.Version.Minor = _header[7]; + db.ArchiveInfo.Version.Major = _header[6]; + db.ArchiveInfo.Version.Minor = _header[7]; - if (database.ArchiveInfo.Version.Major != kMajorVersion) + if (db.ArchiveInfo.Version.Major != kMajorVersion) ThrowUnsupportedVersion(); - UInt32 crcFromArchive = GetUInt32FromMem(_header + 8); - UInt64 nextHeaderOffset = GetUInt64FromMem(_header + 0xC); - UInt64 nextHeaderSize = GetUInt64FromMem(_header + 0x14); - UInt32 nextHeaderCRC = GetUInt32FromMem(_header + 0x1C); + UInt32 crcFromArchive = Get32(_header + 8); + UInt64 nextHeaderOffset = Get64(_header + 0xC); + UInt64 nextHeaderSize = Get64(_header + 0x14); + UInt32 nextHeaderCRC = Get32(_header + 0x1C); UInt32 crc = CrcCalc(_header + 0xC, 20); #ifdef FORMAT_7Z_RECOVERY @@ -1097,16 +1081,15 @@ HRESULT CInArchive::ReadDatabase2( checkSize = (int)(cur2 - cur); RINOK(_stream->Seek(-checkSize, STREAM_SEEK_END, &cur2)); - UInt32 realProcessedSize; - RINOK(_stream->Read(buf, (UInt32)kCheckSize, &realProcessedSize)); + RINOK(ReadStream_FALSE(_stream, buf, (size_t)checkSize)); int i; - for (i = (int)realProcessedSize - 2; i >= 0; i--) + for (i = (int)checkSize - 2; i >= 0; i--) if (buf[i] == 0x17 && buf[i + 1] == 0x6 || buf[i] == 0x01 && buf[i + 1] == 0x04) break; if (i < 0) return S_FALSE; - nextHeaderSize = realProcessedSize - i; + nextHeaderSize = checkSize - i; nextHeaderOffset = cur2 - cur + i; nextHeaderCRC = CrcCalc(buf + i, (size_t)nextHeaderSize); RINOK(_stream->Seek(cur, STREAM_SEEK_SET, NULL)); @@ -1117,7 +1100,7 @@ HRESULT CInArchive::ReadDatabase2( crcFromArchive = crc; #endif - database.ArchiveInfo.StartPositionAfterHeader = _arhiveBeginStreamPosition + kHeaderSize; + db.ArchiveInfo.StartPositionAfterHeader = _arhiveBeginStreamPosition + kHeaderSize; if (crc != crcFromArchive) ThrowIncorrect(); @@ -1133,10 +1116,10 @@ HRESULT CInArchive::ReadDatabase2( CByteBuffer buffer2; buffer2.SetCapacity((size_t)nextHeaderSize); - UInt32 realProcessedSize; - RINOK(_stream->Read(buffer2, (UInt32)nextHeaderSize, &realProcessedSize)); - if (realProcessedSize != (UInt32)nextHeaderSize) - return S_FALSE; + RINOK(ReadStream_FALSE(_stream, buffer2, (size_t)nextHeaderSize)); + HeadersSize += kHeaderSize + nextHeaderSize; + db.PhySize = kHeaderSize + nextHeaderOffset + nextHeaderSize; + if (CrcCalc(buffer2, (UInt32)nextHeaderSize) != nextHeaderCRC) ThrowIncorrect(); @@ -1145,20 +1128,18 @@ HRESULT CInArchive::ReadDatabase2( CObjectVector<CByteBuffer> dataVector; - for (;;) + UInt64 type = ReadID(); + if (type != NID::kHeader) { - UInt64 type = ReadID(); - if (type == NID::kHeader) - break; if (type != NID::kEncodedHeader) ThrowIncorrect(); HRESULT result = ReadAndDecodePackedStreams( EXTERNAL_CODECS_LOC_VARS - database.ArchiveInfo.StartPositionAfterHeader, - database.ArchiveInfo.DataStartPosition2, + db.ArchiveInfo.StartPositionAfterHeader, + db.ArchiveInfo.DataStartPosition2, dataVector #ifndef _NO_CRYPTO - , getTextPassword + , getTextPassword, passwordIsDefined #endif ); RINOK(result); @@ -1168,31 +1149,35 @@ HRESULT CInArchive::ReadDatabase2( ThrowIncorrect(); streamSwitch.Remove(); streamSwitch.Set(this, dataVector.Front()); + if (ReadID() != NID::kHeader) + ThrowIncorrect(); } + db.HeadersSize = HeadersSize; + return ReadHeader( EXTERNAL_CODECS_LOC_VARS - database + db #ifndef _NO_CRYPTO - , getTextPassword + , getTextPassword, passwordIsDefined #endif ); } HRESULT CInArchive::ReadDatabase( DECL_EXTERNAL_CODECS_LOC_VARS - CArchiveDatabaseEx &database + CArchiveDatabaseEx &db #ifndef _NO_CRYPTO - , ICryptoGetTextPassword *getTextPassword + , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined #endif ) { try { return ReadDatabase2( - EXTERNAL_CODECS_LOC_VARS database + EXTERNAL_CODECS_LOC_VARS db #ifndef _NO_CRYPTO - , getTextPassword + , getTextPassword, passwordIsDefined #endif ); } diff --git a/CPP/7zip/Archive/7z/7zIn.h b/CPP/7zip/Archive/7z/7zIn.h index aae43506..86d0e339 100755 --- a/CPP/7zip/Archive/7z/7zIn.h +++ b/CPP/7zip/Archive/7z/7zIn.h @@ -36,6 +36,9 @@ struct CArchiveDatabaseEx: public CArchiveDatabase CRecordVector<CNum> FolderStartFileIndex; CRecordVector<CNum> FileIndexToFolderIndexMap; + UInt64 HeadersSize; + UInt64 PhySize; + void Clear() { CArchiveDatabase::Clear(); @@ -44,6 +47,9 @@ struct CArchiveDatabaseEx: public CArchiveDatabase FolderStartPackStreamIndex.Clear(); FolderStartFileIndex.Clear(); FileIndexToFolderIndexMap.Clear(); + + HeadersSize = 0; + PhySize = 0; } void FillFolderStartPackStream(); @@ -63,7 +69,7 @@ struct CArchiveDatabaseEx: public CArchiveDatabase PackStreamStartPositions[FolderStartPackStreamIndex[folderIndex] + indexInFolder]; } - UInt64 GetFolderFullPackSize(int folderIndex) const + UInt64 GetFolderFullPackSize(int folderIndex) const { CNum packStreamIndex = FolderStartPackStreamIndex[folderIndex]; const CFolder &folder = Folders[folderIndex]; @@ -73,7 +79,7 @@ struct CArchiveDatabaseEx: public CArchiveDatabase return size; } - UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const + UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const { return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex]; } @@ -92,8 +98,8 @@ class CInByte2 { const Byte *_buffer; size_t _size; - size_t _pos; public: + size_t _pos; void Init(const Byte *buffer, size_t size) { _buffer = buffer; @@ -128,6 +134,8 @@ class CInArchive Byte _header[kHeaderSize]; + UInt64 HeadersSize; + void AddByteStream(const Byte *buffer, size_t size) { _inByteVector.Add(CInByte2()); @@ -167,15 +175,15 @@ private: CRecordVector<bool> &packCRCsDefined, CRecordVector<UInt32> &packCRCs); - void ReadUnPackInfo( + void ReadUnpackInfo( const CObjectVector<CByteBuffer> *dataVector, CObjectVector<CFolder> &folders); void ReadSubStreamsInfo( const CObjectVector<CFolder> &folders, - CRecordVector<CNum> &numUnPackStreamsInFolders, - CRecordVector<UInt64> &unPackSizes, - CRecordVector<bool> &digestsDefined, + CRecordVector<CNum> &numUnpackStreamsInFolders, + CRecordVector<UInt64> &unpackSizes, + CRecordVector<bool> &digestsDefined, CRecordVector<UInt32> &digests); void ReadStreamsInfo( @@ -185,36 +193,36 @@ private: CRecordVector<bool> &packCRCsDefined, CRecordVector<UInt32> &packCRCs, CObjectVector<CFolder> &folders, - CRecordVector<CNum> &numUnPackStreamsInFolders, - CRecordVector<UInt64> &unPackSizes, - CRecordVector<bool> &digestsDefined, + CRecordVector<CNum> &numUnpackStreamsInFolders, + CRecordVector<UInt64> &unpackSizes, + CRecordVector<bool> &digestsDefined, CRecordVector<UInt32> &digests); void ReadBoolVector(int numItems, CBoolVector &v); void ReadBoolVector2(int numItems, CBoolVector &v); - void ReadTime(const CObjectVector<CByteBuffer> &dataVector, - CObjectVector<CFileItem> &files, UInt32 type); + void ReadUInt64DefVector(const CObjectVector<CByteBuffer> &dataVector, + CUInt64DefVector &v, int numFiles); HRESULT ReadAndDecodePackedStreams( DECL_EXTERNAL_CODECS_LOC_VARS UInt64 baseOffset, UInt64 &dataOffset, CObjectVector<CByteBuffer> &dataVector #ifndef _NO_CRYPTO - , ICryptoGetTextPassword *getTextPassword + , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined #endif ); HRESULT ReadHeader( DECL_EXTERNAL_CODECS_LOC_VARS - CArchiveDatabaseEx &database + CArchiveDatabaseEx &db #ifndef _NO_CRYPTO - ,ICryptoGetTextPassword *getTextPassword + ,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined #endif ); HRESULT ReadDatabase2( DECL_EXTERNAL_CODECS_LOC_VARS - CArchiveDatabaseEx &database + CArchiveDatabaseEx &db #ifndef _NO_CRYPTO - ,ICryptoGetTextPassword *getTextPassword + ,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined #endif ); public: @@ -223,9 +231,9 @@ public: HRESULT ReadDatabase( DECL_EXTERNAL_CODECS_LOC_VARS - CArchiveDatabaseEx &database + CArchiveDatabaseEx &db #ifndef _NO_CRYPTO - ,ICryptoGetTextPassword *getTextPassword + ,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined #endif ); }; diff --git a/CPP/7zip/Archive/7z/7zItem.h b/CPP/7zip/Archive/7z/7zItem.h index 31c5ce2d..763a159f 100755 --- a/CPP/7zip/Archive/7z/7zItem.h +++ b/CPP/7zip/Archive/7z/7zItem.h @@ -35,19 +35,19 @@ struct CFolder CObjectVector<CCoderInfo> Coders; CRecordVector<CBindPair> BindPairs; CRecordVector<CNum> PackStreams; - CRecordVector<UInt64> UnPackSizes; - UInt32 UnPackCRC; - bool UnPackCRCDefined; + CRecordVector<UInt64> UnpackSizes; + UInt32 UnpackCRC; + bool UnpackCRCDefined; - CFolder(): UnPackCRCDefined(false) {} + CFolder(): UnpackCRCDefined(false) {} - UInt64 GetUnPackSize() const // test it - { - if (UnPackSizes.IsEmpty()) + UInt64 GetUnpackSize() const // test it + { + if (UnpackSizes.IsEmpty()) return 0; - for (int i = UnPackSizes.Size() - 1; i >= 0; i--) + for (int i = UnpackSizes.Size() - 1; i >= 0; i--) if (FindBindPairForOutStream(i) < 0) - return UnPackSizes[i]; + return UnpackSizes[i]; throw 1; } @@ -82,101 +82,171 @@ struct CFolder } }; -typedef FILETIME CArchiveFileTime; +struct CUInt64DefVector +{ + CRecordVector<UInt64> Values; + CRecordVector<bool> Defined; + + void Clear() + { + Values.Clear(); + Defined.Clear(); + } + + void ReserveDown() + { + Values.ReserveDown(); + Values.ReserveDown(); + } + + bool GetItem(int index, UInt64 &value) const + { + if (index < Defined.Size() && Defined[index]) + { + value = Values[index]; + return true; + } + value = 0; + return false; + } + + void SetItem(int index, bool defined, UInt64 value) + { + while (index >= Defined.Size()) + Defined.Add(false); + Defined[index] = defined; + if (!defined) + return; + while (index >= Values.Size()) + Values.Add(0); + Values[index] = value; + } + + bool CheckSize(int size) const { return Defined.Size() == size || Defined.Size() == 0; } +}; -class CFileItem +struct CFileItem { -public: - CArchiveFileTime CreationTime; - CArchiveFileTime LastWriteTime; - CArchiveFileTime LastAccessTime; - UInt64 UnPackSize; - UInt64 StartPos; - UInt32 Attributes; - UInt32 FileCRC; + UInt64 Size; + UInt32 Attrib; + UInt32 Crc; UString Name; - bool HasStream; // Test it !!! it means that there is + bool HasStream; // Test it !!! it means that there is // stream in some folder. It can be empty stream - bool IsDirectory; - bool IsAnti; - bool IsFileCRCDefined; - bool AreAttributesDefined; - bool IsCreationTimeDefined; - bool IsLastWriteTimeDefined; - bool IsLastAccessTimeDefined; - bool IsStartPosDefined; - - /* - const bool HasStream() const { - return !IsDirectory && !IsAnti && UnPackSize != 0; } - */ - CFileItem(): + bool IsDir; + bool CrcDefined; + bool AttribDefined; + + CFileItem(): HasStream(true), - IsDirectory(false), - IsAnti(false), - IsFileCRCDefined(false), - AreAttributesDefined(false), - IsCreationTimeDefined(false), - IsLastWriteTimeDefined(false), - IsLastAccessTimeDefined(false), - IsStartPosDefined(false) + IsDir(false), + CrcDefined(false), + AttribDefined(false) {} - void SetAttributes(UInt32 attributes) - { - AreAttributesDefined = true; - Attributes = attributes; - } - void SetCreationTime(const CArchiveFileTime &creationTime) - { - IsCreationTimeDefined = true; - CreationTime = creationTime; - } - void SetLastWriteTime(const CArchiveFileTime &lastWriteTime) + void SetAttrib(UInt32 attrib) { - IsLastWriteTimeDefined = true; - LastWriteTime = lastWriteTime; - } - void SetLastAccessTime(const CArchiveFileTime &lastAccessTime) - { - IsLastAccessTimeDefined = true; - LastAccessTime = lastAccessTime; + AttribDefined = true; + Attrib = attrib; } }; +struct CFileItem2 +{ + UInt64 CTime; + UInt64 ATime; + UInt64 MTime; + UInt64 StartPos; + bool CTimeDefined; + bool ATimeDefined; + bool MTimeDefined; + bool StartPosDefined; + bool IsAnti; +}; + struct CArchiveDatabase { CRecordVector<UInt64> PackSizes; CRecordVector<bool> PackCRCsDefined; CRecordVector<UInt32> PackCRCs; CObjectVector<CFolder> Folders; - CRecordVector<CNum> NumUnPackStreamsVector; + CRecordVector<CNum> NumUnpackStreamsVector; CObjectVector<CFileItem> Files; + + CUInt64DefVector CTime; + CUInt64DefVector ATime; + CUInt64DefVector MTime; + CUInt64DefVector StartPos; + CRecordVector<bool> IsAnti; + void Clear() { PackSizes.Clear(); PackCRCsDefined.Clear(); PackCRCs.Clear(); Folders.Clear(); - NumUnPackStreamsVector.Clear(); + NumUnpackStreamsVector.Clear(); Files.Clear(); + CTime.Clear(); + ATime.Clear(); + MTime.Clear(); + StartPos.Clear(); + IsAnti.Clear(); } + + void ReserveDown() + { + PackSizes.ReserveDown(); + PackCRCsDefined.ReserveDown(); + PackCRCs.ReserveDown(); + Folders.ReserveDown(); + NumUnpackStreamsVector.ReserveDown(); + Files.ReserveDown(); + CTime.ReserveDown(); + ATime.ReserveDown(); + MTime.ReserveDown(); + StartPos.ReserveDown(); + IsAnti.ReserveDown(); + } + bool IsEmpty() const { - return (PackSizes.IsEmpty() && - PackCRCsDefined.IsEmpty() && - PackCRCs.IsEmpty() && - Folders.IsEmpty() && - NumUnPackStreamsVector.IsEmpty() && + return (PackSizes.IsEmpty() && + PackCRCsDefined.IsEmpty() && + PackCRCs.IsEmpty() && + Folders.IsEmpty() && + NumUnpackStreamsVector.IsEmpty() && Files.IsEmpty()); } + + bool CheckNumFiles() const + { + int size = Files.Size(); + return ( + CTime.CheckSize(size) && + ATime.CheckSize(size) && + MTime.CheckSize(size) && + StartPos.CheckSize(size) && + (size == IsAnti.Size() || IsAnti.Size() == 0)); + } + bool IsSolid() const { - for (int i = 0; i < NumUnPackStreamsVector.Size(); i++) - if (NumUnPackStreamsVector[i] > 1) + for (int i = 0; i < NumUnpackStreamsVector.Size(); i++) + if (NumUnpackStreamsVector[i] > 1) return true; return false; } + bool IsItemAnti(int index) const { return (index < IsAnti.Size() && IsAnti[index]); } + void SetItemAnti(int index, bool isAnti) + { + while (index >= IsAnti.Size()) + IsAnti.Add(false); + IsAnti[index] = isAnti; + } + + void GetFile(int index, CFileItem &file, CFileItem2 &file2) const; + void AddFile(const CFileItem &file, const CFileItem2 &file2); }; }} diff --git a/CPP/7zip/Archive/7z/7zOut.cpp b/CPP/7zip/Archive/7z/7zOut.cpp index a00cdf5c..dae242a6 100755 --- a/CPP/7zip/Archive/7z/7zOut.cpp +++ b/CPP/7zip/Archive/7z/7zOut.cpp @@ -7,8 +7,8 @@ #include "7zOut.h" -extern "C" -{ +extern "C" +{ #include "../../../../C/7zCrc.h" } @@ -19,7 +19,7 @@ static HRESULT WriteBytes(ISequentialOutStream *stream, const void *data, size_t UInt32 curSize = (UInt32)MyMin(size, (size_t)0xFFFFFFFF); UInt32 processedSize; RINOK(stream->Write(data, curSize, &processedSize)); - if(processedSize == 0) + if (processedSize == 0) return E_FAIL; data = (const void *)((const Byte *)data + processedSize); size -= processedSize; @@ -35,45 +35,13 @@ HRESULT COutArchive::WriteDirect(const void *data, UInt32 size) return ::WriteBytes(SeqStream, data, size); } -UInt32 CrcUpdateUInt32(UInt32 crc, UInt32 value) -{ - for (int i = 0; i < 4; i++, value >>= 8) - crc = CRC_UPDATE_BYTE(crc, (Byte)value); - return crc; -} - -UInt32 CrcUpdateUInt64(UInt32 crc, UInt64 value) -{ - for (int i = 0; i < 8; i++, value >>= 8) - crc = CRC_UPDATE_BYTE(crc, (Byte)value); - return crc; -} - -HRESULT COutArchive::WriteDirectUInt32(UInt32 value) -{ - for (int i = 0; i < 4; i++) - { - RINOK(WriteDirectByte((Byte)value)); - value >>= 8; - } - return S_OK; -} - -HRESULT COutArchive::WriteDirectUInt64(UInt64 value) -{ - for (int i = 0; i < 8; i++) - { - RINOK(WriteDirectByte((Byte)value)); - value >>= 8; - } - return S_OK; -} - HRESULT COutArchive::WriteSignature() { - RINOK(WriteDirect(kSignature, kSignatureSize)); - RINOK(WriteDirectByte(kMajorVersion)); - return WriteDirectByte(2); + Byte buf[8]; + memcpy(buf, kSignature, kSignatureSize); + buf[kSignatureSize] = kMajorVersion; + buf[kSignatureSize + 1] = 3; + return WriteDirect(buf, 8); } #ifdef _7Z_VOL @@ -88,16 +56,26 @@ HRESULT COutArchive::WriteFinishSignature() } #endif +static void SetUInt32(Byte *p, UInt32 d) +{ + for (int i = 0; i < 4; i++, d >>= 8) + p[i] = (Byte)d; +} + +static void SetUInt64(Byte *p, UInt64 d) +{ + for (int i = 0; i < 8; i++, d >>= 8) + p[i] = (Byte)d; +} + HRESULT COutArchive::WriteStartHeader(const CStartHeader &h) { - UInt32 crc = CRC_INIT_VAL; - crc = CrcUpdateUInt64(crc, h.NextHeaderOffset); - crc = CrcUpdateUInt64(crc, h.NextHeaderSize); - crc = CrcUpdateUInt32(crc, h.NextHeaderCRC); - RINOK(WriteDirectUInt32(CRC_GET_DIGEST(crc))); - RINOK(WriteDirectUInt64(h.NextHeaderOffset)); - RINOK(WriteDirectUInt64(h.NextHeaderSize)); - return WriteDirectUInt32(h.NextHeaderCRC); + Byte buf[24]; + SetUInt64(buf + 4, h.NextHeaderOffset); + SetUInt64(buf + 12, h.NextHeaderSize); + SetUInt32(buf + 20, h.NextHeaderCRC); + SetUInt32(buf, CrcCalc(buf + 4, 20)); + return WriteDirect(buf, 24); } #ifdef _7Z_VOL @@ -172,47 +150,60 @@ HRESULT COutArchive::SkeepPrefixArchiveHeader() return Stream->Seek(24, STREAM_SEEK_CUR, NULL); } -HRESULT COutArchive::WriteBytes(const void *data, size_t size) +UInt64 COutArchive::GetPos() const { - if (_mainMode) + if (_countMode) + return _countSize; + if (_writeToStream) + return _outByte.GetProcessedSize(); + return _outByte2.GetPos(); +} + +void COutArchive::WriteBytes(const void *data, size_t size) +{ + if (_countMode) + _countSize += size; + else if (_writeToStream) { - if (_dynamicMode) - _dynamicBuffer.Write(data, size); - else - _outByte.WriteBytes(data, size); + _outByte.WriteBytes(data, size); _crc = CrcUpdate(_crc, data, size); } else - { - if (_countMode) - _countSize += size; - else - RINOK(_outByte2.Write(data, size)); - } - return S_OK; + _outByte2.WriteBytes(data, size); } -HRESULT COutArchive::WriteBytes(const CByteBuffer &data) +void COutArchive::WriteByte(Byte b) { - return WriteBytes(data, data.GetCapacity()); + if (_countMode) + _countSize++; + else if (_writeToStream) + { + _outByte.WriteByte(b); + _crc = CRC_UPDATE_BYTE(_crc, b); + } + else + _outByte2.WriteByte(b); } -HRESULT COutArchive::WriteByte(Byte b) +void COutArchive::WriteUInt32(UInt32 value) { - return WriteBytes(&b, 1); + for (int i = 0; i < 4; i++) + { + WriteByte((Byte)value); + value >>= 8; + } } -HRESULT COutArchive::WriteUInt32(UInt32 value) +void COutArchive::WriteUInt64(UInt64 value) { - for (int i = 0; i < 4; i++) + for (int i = 0; i < 8; i++) { - RINOK(WriteByte((Byte)value)); + WriteByte((Byte)value); value >>= 8; } - return S_OK; } -HRESULT COutArchive::WriteNumber(UInt64 value) +void COutArchive::WriteNumber(UInt64 value) { Byte firstByte = 0; Byte mask = 0x80; @@ -227,25 +218,24 @@ HRESULT COutArchive::WriteNumber(UInt64 value) firstByte |= mask; mask >>= 1; } - RINOK(WriteByte(firstByte)); + WriteByte(firstByte); for (;i > 0; i--) { - RINOK(WriteByte((Byte)value)); + WriteByte((Byte)value); value >>= 8; } - return S_OK; } -#ifdef _7Z_VOL static UInt32 GetBigNumberSize(UInt64 value) { int i; - for (i = 0; i < 8; i++) - if (value < ((UInt64(1) << ( 7 * (i + 1))))) + for (i = 1; i < 9; i++) + if (value < (((UInt64)1 << (i * 7)))) break; - return 1 + i; + return i; } +#ifdef _7Z_VOL UInt32 COutArchive::GetVolHeadersSize(UInt64 dataSize, int nameLength, bool props) { UInt32 result = GetBigNumberSize(dataSize) * 2 + 41; @@ -280,9 +270,9 @@ UInt64 COutArchive::GetVolPureSize(UInt64 volSize, int nameLength, bool props) } #endif -HRESULT COutArchive::WriteFolder(const CFolder &folder) +void COutArchive::WriteFolder(const CFolder &folder) { - RINOK(WriteNumber(folder.Coders.Size())); + WriteNumber(folder.Coders.Size()); int i; for (i = 0; i < folder.Coders.Size(); i++) { @@ -290,7 +280,7 @@ HRESULT COutArchive::WriteFolder(const CFolder &folder) { size_t propertiesSize = coder.Properties.GetCapacity(); - UInt64 id = coder.MethodID; + UInt64 id = coder.MethodID; int idSize; for (idSize = 1; idSize < sizeof(id); idSize++) if ((id >> (8 * idSize)) == 0) @@ -303,161 +293,152 @@ HRESULT COutArchive::WriteFolder(const CFolder &folder) bool isComplex = !coder.IsSimpleCoder(); b |= (isComplex ? 0x10 : 0); b |= ((propertiesSize != 0) ? 0x20 : 0 ); - RINOK(WriteByte(b)); - RINOK(WriteBytes(longID, idSize)); + WriteByte(b); + WriteBytes(longID, idSize); if (isComplex) { - RINOK(WriteNumber(coder.NumInStreams)); - RINOK(WriteNumber(coder.NumOutStreams)); + WriteNumber(coder.NumInStreams); + WriteNumber(coder.NumOutStreams); } if (propertiesSize == 0) continue; - RINOK(WriteNumber(propertiesSize)); - RINOK(WriteBytes(coder.Properties, propertiesSize)); + WriteNumber(propertiesSize); + WriteBytes(coder.Properties, propertiesSize); } } for (i = 0; i < folder.BindPairs.Size(); i++) { const CBindPair &bindPair = folder.BindPairs[i]; - RINOK(WriteNumber(bindPair.InIndex)); - RINOK(WriteNumber(bindPair.OutIndex)); + WriteNumber(bindPair.InIndex); + WriteNumber(bindPair.OutIndex); } if (folder.PackStreams.Size() > 1) for (i = 0; i < folder.PackStreams.Size(); i++) { - RINOK(WriteNumber(folder.PackStreams[i])); + WriteNumber(folder.PackStreams[i]); } - return S_OK; } -HRESULT COutArchive::WriteBoolVector(const CBoolVector &boolVector) +void COutArchive::WriteBoolVector(const CBoolVector &boolVector) { Byte b = 0; Byte mask = 0x80; - for(int i = 0; i < boolVector.Size(); i++) + for (int i = 0; i < boolVector.Size(); i++) { if (boolVector[i]) b |= mask; mask >>= 1; if (mask == 0) { - RINOK(WriteByte(b)); + WriteByte(b); mask = 0x80; b = 0; } } if (mask != 0x80) - { - RINOK(WriteByte(b)); - } - return S_OK; + WriteByte(b); } -HRESULT COutArchive::WriteHashDigests( +void COutArchive::WriteHashDigests( const CRecordVector<bool> &digestsDefined, const CRecordVector<UInt32> &digests) { int numDefined = 0; int i; - for(i = 0; i < digestsDefined.Size(); i++) + for (i = 0; i < digestsDefined.Size(); i++) if (digestsDefined[i]) numDefined++; if (numDefined == 0) - return S_OK; + return; - RINOK(WriteByte(NID::kCRC)); + WriteByte(NID::kCRC); if (numDefined == digestsDefined.Size()) - { - RINOK(WriteByte(1)); - } + WriteByte(1); else { - RINOK(WriteByte(0)); - RINOK(WriteBoolVector(digestsDefined)); - } - for(i = 0; i < digests.Size(); i++) - { - if(digestsDefined[i]) - RINOK(WriteUInt32(digests[i])); + WriteByte(0); + WriteBoolVector(digestsDefined); } - return S_OK; + for (i = 0; i < digests.Size(); i++) + if (digestsDefined[i]) + WriteUInt32(digests[i]); } -HRESULT COutArchive::WritePackInfo( +void COutArchive::WritePackInfo( UInt64 dataOffset, const CRecordVector<UInt64> &packSizes, const CRecordVector<bool> &packCRCsDefined, const CRecordVector<UInt32> &packCRCs) { if (packSizes.IsEmpty()) - return S_OK; - RINOK(WriteByte(NID::kPackInfo)); - RINOK(WriteNumber(dataOffset)); - RINOK(WriteNumber(packSizes.Size())); - RINOK(WriteByte(NID::kSize)); - for(int i = 0; i < packSizes.Size(); i++) - RINOK(WriteNumber(packSizes[i])); - - RINOK(WriteHashDigests(packCRCsDefined, packCRCs)); + return; + WriteByte(NID::kPackInfo); + WriteNumber(dataOffset); + WriteNumber(packSizes.Size()); + WriteByte(NID::kSize); + for (int i = 0; i < packSizes.Size(); i++) + WriteNumber(packSizes[i]); + + WriteHashDigests(packCRCsDefined, packCRCs); - return WriteByte(NID::kEnd); + WriteByte(NID::kEnd); } -HRESULT COutArchive::WriteUnPackInfo(const CObjectVector<CFolder> &folders) +void COutArchive::WriteUnpackInfo(const CObjectVector<CFolder> &folders) { if (folders.IsEmpty()) - return S_OK; + return; - RINOK(WriteByte(NID::kUnPackInfo)); + WriteByte(NID::kUnpackInfo); - RINOK(WriteByte(NID::kFolder)); - RINOK(WriteNumber(folders.Size())); + WriteByte(NID::kFolder); + WriteNumber(folders.Size()); { - RINOK(WriteByte(0)); - for(int i = 0; i < folders.Size(); i++) - RINOK(WriteFolder(folders[i])); + WriteByte(0); + for (int i = 0; i < folders.Size(); i++) + WriteFolder(folders[i]); } - RINOK(WriteByte(NID::kCodersUnPackSize)); + WriteByte(NID::kCodersUnpackSize); int i; - for(i = 0; i < folders.Size(); i++) + for (i = 0; i < folders.Size(); i++) { const CFolder &folder = folders[i]; - for (int j = 0; j < folder.UnPackSizes.Size(); j++) - RINOK(WriteNumber(folder.UnPackSizes[j])); + for (int j = 0; j < folder.UnpackSizes.Size(); j++) + WriteNumber(folder.UnpackSizes[j]); } - CRecordVector<bool> unPackCRCsDefined; - CRecordVector<UInt32> unPackCRCs; - for(i = 0; i < folders.Size(); i++) + CRecordVector<bool> unpackCRCsDefined; + CRecordVector<UInt32> unpackCRCs; + for (i = 0; i < folders.Size(); i++) { const CFolder &folder = folders[i]; - unPackCRCsDefined.Add(folder.UnPackCRCDefined); - unPackCRCs.Add(folder.UnPackCRC); + unpackCRCsDefined.Add(folder.UnpackCRCDefined); + unpackCRCs.Add(folder.UnpackCRC); } - RINOK(WriteHashDigests(unPackCRCsDefined, unPackCRCs)); + WriteHashDigests(unpackCRCsDefined, unpackCRCs); - return WriteByte(NID::kEnd); + WriteByte(NID::kEnd); } -HRESULT COutArchive::WriteSubStreamsInfo( +void COutArchive::WriteSubStreamsInfo( const CObjectVector<CFolder> &folders, - const CRecordVector<CNum> &numUnPackStreamsInFolders, - const CRecordVector<UInt64> &unPackSizes, + const CRecordVector<CNum> &numUnpackStreamsInFolders, + const CRecordVector<UInt64> &unpackSizes, const CRecordVector<bool> &digestsDefined, const CRecordVector<UInt32> &digests) { - RINOK(WriteByte(NID::kSubStreamsInfo)); + WriteByte(NID::kSubStreamsInfo); int i; - for(i = 0; i < numUnPackStreamsInFolders.Size(); i++) + for (i = 0; i < numUnpackStreamsInFolders.Size(); i++) { - if (numUnPackStreamsInFolders[i] != 1) + if (numUnpackStreamsInFolders[i] != 1) { - RINOK(WriteByte(NID::kNumUnPackStream)); - for(i = 0; i < numUnPackStreamsInFolders.Size(); i++) - RINOK(WriteNumber(numUnPackStreamsInFolders[i])); + WriteByte(NID::kNumUnpackStream); + for (i = 0; i < numUnpackStreamsInFolders.Size(); i++) + WriteNumber(numUnpackStreamsInFolders[i]); break; } } @@ -465,15 +446,15 @@ HRESULT COutArchive::WriteSubStreamsInfo( bool needFlag = true; CNum index = 0; - for(i = 0; i < numUnPackStreamsInFolders.Size(); i++) - for (CNum j = 0; j < numUnPackStreamsInFolders[i]; j++) + for (i = 0; i < numUnpackStreamsInFolders.Size(); i++) + for (CNum j = 0; j < numUnpackStreamsInFolders[i]; j++) { - if (j + 1 != numUnPackStreamsInFolders[i]) + if (j + 1 != numUnpackStreamsInFolders[i]) { if (needFlag) - RINOK(WriteByte(NID::kSize)); + WriteByte(NID::kSize); needFlag = false; - RINOK(WriteNumber(unPackSizes[index])); + WriteNumber(unpackSizes[index]); } index++; } @@ -484,8 +465,8 @@ HRESULT COutArchive::WriteSubStreamsInfo( int digestIndex = 0; for (i = 0; i < folders.Size(); i++) { - int numSubStreams = (int)numUnPackStreamsInFolders[i]; - if (numSubStreams == 1 && folders[i].UnPackCRCDefined) + int numSubStreams = (int)numUnpackStreamsInFolders[i]; + if (numSubStreams == 1 && folders[i].UnpackCRCDefined) digestIndex++; else for (int j = 0; j < numSubStreams; j++, digestIndex++) @@ -494,84 +475,70 @@ HRESULT COutArchive::WriteSubStreamsInfo( digests2.Add(digests[digestIndex]); } } - RINOK(WriteHashDigests(digestsDefined2, digests2)); - return WriteByte(NID::kEnd); + WriteHashDigests(digestsDefined2, digests2); + WriteByte(NID::kEnd); } -HRESULT COutArchive::WriteTime( - const CObjectVector<CFileItem> &files, Byte type) +void COutArchive::SkipAlign(unsigned /* pos */, unsigned /* alignSize */) { - ///////////////////////////////////////////////// - // CreationTime - CBoolVector boolVector; - boolVector.Reserve(files.Size()); - bool thereAreDefined = false; - bool allDefined = true; - int i; - for(i = 0; i < files.Size(); i++) - { - const CFileItem &item = files[i]; - bool defined; - switch(type) - { - case NID::kCreationTime: - defined = item.IsCreationTimeDefined; - break; - case NID::kLastWriteTime: - defined = item.IsLastWriteTimeDefined; - break; - case NID::kLastAccessTime: - defined = item.IsLastAccessTimeDefined; - break; - default: - throw 1; - } - boolVector.Add(defined); - thereAreDefined = (thereAreDefined || defined); - allDefined = (allDefined && defined); - } - if (!thereAreDefined) - return S_OK; - RINOK(WriteByte(type)); - size_t dataSize = 1 + 1; - dataSize += files.Size() * 8; - if (allDefined) - { - RINOK(WriteNumber(dataSize)); + return; +} + +/* +7-Zip 4.50 - 4.58 contain BUG, so they do not support .7z archives with Unknown field. + +void COutArchive::SkipAlign(unsigned pos, unsigned alignSize) +{ + pos += (unsigned)GetPos(); + pos &= (alignSize - 1); + if (pos == 0) + return; + unsigned skip = alignSize - pos; + if (skip < 2) + skip += alignSize; + skip -= 2; + WriteByte(NID::kDummy); + WriteByte((Byte)skip); + for (unsigned i = 0; i < skip; i++) + WriteByte(0); +} +*/ + +void COutArchive::WriteAlignedBoolHeader(const CBoolVector &v, int numDefined, Byte type, unsigned itemSize) +{ + const UInt64 bvSize = (numDefined == v.Size()) ? 0 : (v.Size() + 7) / 8; + const UInt64 dataSize = (UInt64)numDefined * itemSize + bvSize + 2; + SkipAlign(3 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), itemSize); + + WriteByte(type); + WriteNumber(dataSize); + if (numDefined == v.Size()) WriteByte(1); - } else { - RINOK(WriteNumber(1 + (boolVector.Size() + 7) / 8 + dataSize)); WriteByte(0); - RINOK(WriteBoolVector(boolVector)); - } - RINOK(WriteByte(0)); - for(i = 0; i < files.Size(); i++) - { - if (boolVector[i]) - { - const CFileItem &item = files[i]; - CArchiveFileTime timeValue; - timeValue.dwLowDateTime = 0; - timeValue.dwHighDateTime = 0; - switch(type) - { - case NID::kCreationTime: - timeValue = item.CreationTime; - break; - case NID::kLastWriteTime: - timeValue = item.LastWriteTime; - break; - case NID::kLastAccessTime: - timeValue = item.LastAccessTime; - break; - } - RINOK(WriteUInt32(timeValue.dwLowDateTime)); - RINOK(WriteUInt32(timeValue.dwHighDateTime)); - } + WriteBoolVector(v); } - return S_OK; + WriteByte(0); +} + +void COutArchive::WriteUInt64DefVector(const CUInt64DefVector &v, Byte type) +{ + int numDefined = 0; + + int i; + for (i = 0; i < v.Defined.Size(); i++) + if (v.Defined[i]) + numDefined++; + + if (numDefined == 0) + return; + + WriteAlignedBoolHeader(v.Defined, numDefined, type, 8); + + for (i = 0; i < v.Defined.Size(); i++) + if (v.Defined[i]) + WriteUInt64(v.Values[i]); } HRESULT COutArchive::EncodeStream( @@ -583,8 +550,8 @@ HRESULT COutArchive::EncodeStream( CMyComPtr<ISequentialInStream> stream = streamSpec; streamSpec->Init(data, dataSize); CFolder folderItem; - folderItem.UnPackCRCDefined = true; - folderItem.UnPackCRC = CrcCalc(data, dataSize); + folderItem.UnpackCRCDefined = true; + folderItem.UnpackCRC = CrcCalc(data, dataSize); UInt64 dataSize64 = dataSize; RINOK(encoder.Encode( EXTERNAL_CODECS_LOC_VARS @@ -595,7 +562,7 @@ HRESULT COutArchive::EncodeStream( HRESULT COutArchive::EncodeStream( DECL_EXTERNAL_CODECS_LOC_VARS - CEncoder &encoder, const CByteBuffer &data, + CEncoder &encoder, const CByteBuffer &data, CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders) { return EncodeStream( @@ -603,212 +570,70 @@ HRESULT COutArchive::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, +void COutArchive::WriteHeader( + const CArchiveDatabase &db, const CHeaderOptions &headerOptions, UInt64 &headerOffset) { 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; - if (numDefinedNames > 0) - { - 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; - 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; - } - } - - ///////////////////////////////// - // Write Attributes - CBoolVector attributesBoolVector; - attributesBoolVector.Reserve(database.Files.Size()); - int numDefinedAttributes = 0; - for(i = 0; i < database.Files.Size(); i++) - { - bool defined = database.Files[i].AreAttributesDefined; - attributesBoolVector.Add(defined); - if (defined) - numDefinedAttributes++; - } - - CByteBuffer attributesData; - if (numDefinedAttributes > 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) - { - WriteUInt32ToBuffer(attributesData + pos, file.Attributes); - pos += 4; - } - } - } - - ///////////////////////////////// - // 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; - 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; - } - } - } - - ///////////////////////////////// - // Write Last Write Time - // /* - CNum numDefinedLastWriteTimes = 0; - for(i = 0; i < database.Files.Size(); i++) - if (database.Files[i].IsLastWriteTimeDefined) - numDefinedLastWriteTimes++; - - if (numDefinedLastWriteTimes > 0) - { - CByteBuffer lastWriteTimeData; - 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) - { - WriteUInt32ToBuffer(lastWriteTimeData + pos, file.LastWriteTime.dwLowDateTime); - pos += 4; - WriteUInt32ToBuffer(lastWriteTimeData + pos, file.LastWriteTime.dwHighDateTime); - pos += 4; - } - } - } - // */ - - UInt64 packedSize = 0; - for(i = 0; i < database.PackSizes.Size(); i++) - packedSize += database.PackSizes[i]; + for (i = 0; i < db.PackSizes.Size(); i++) + packedSize += db.PackSizes[i]; headerOffset = packedSize; - _mainMode = true; - - _outByte.SetStream(SeqStream); - _outByte.Init(); - _crc = CRC_INIT_VAL; - - - RINOK(WriteByte(NID::kHeader)); + WriteByte(NID::kHeader); // Archive Properties - if (database.Folders.Size() > 0) + if (db.Folders.Size() > 0) { - RINOK(WriteByte(NID::kMainStreamsInfo)); - RINOK(WritePackInfo(0, database.PackSizes, - database.PackCRCsDefined, - database.PackCRCs)); + WriteByte(NID::kMainStreamsInfo); + WritePackInfo(0, db.PackSizes, + db.PackCRCsDefined, + db.PackCRCs); - RINOK(WriteUnPackInfo(database.Folders)); + WriteUnpackInfo(db.Folders); - CRecordVector<UInt64> unPackSizes; + CRecordVector<UInt64> unpackSizes; CRecordVector<bool> digestsDefined; CRecordVector<UInt32> digests; - for (i = 0; i < database.Files.Size(); i++) + for (i = 0; i < db.Files.Size(); i++) { - const CFileItem &file = database.Files[i]; + const CFileItem &file = db.Files[i]; if (!file.HasStream) continue; - unPackSizes.Add(file.UnPackSize); - digestsDefined.Add(file.IsFileCRCDefined); - digests.Add(file.FileCRC); + unpackSizes.Add(file.Size); + digestsDefined.Add(file.CrcDefined); + digests.Add(file.Crc); } - RINOK(WriteSubStreamsInfo( - database.Folders, - database.NumUnPackStreamsVector, - unPackSizes, + WriteSubStreamsInfo( + db.Folders, + db.NumUnpackStreamsVector, + unpackSizes, digestsDefined, - digests)); - RINOK(WriteByte(NID::kEnd)); + digests); + WriteByte(NID::kEnd); } - if (database.Files.IsEmpty()) + if (db.Files.IsEmpty()) { - RINOK(WriteByte(NID::kEnd)); - return _outByte.Flush(); + WriteByte(NID::kEnd); + return; } - RINOK(WriteByte(NID::kFilesInfo)); - RINOK(WriteNumber(database.Files.Size())); + WriteByte(NID::kFilesInfo); + WriteNumber(db.Files.Size()); + { + /* ---------- Empty Streams ---------- */ CBoolVector emptyStreamVector; - emptyStreamVector.Reserve(database.Files.Size()); + emptyStreamVector.Reserve(db.Files.Size()); int numEmptyStreams = 0; - for(i = 0; i < database.Files.Size(); i++) - if (database.Files[i].HasStream) + for (i = 0; i < db.Files.Size(); i++) + if (db.Files[i].HasStream) emptyStreamVector.Add(false); else { @@ -817,134 +642,126 @@ HRESULT COutArchive::WriteHeader( } if (numEmptyStreams > 0) { - RINOK(WriteByte(NID::kEmptyStream)); - RINOK(WriteNumber((emptyStreamVector.Size() + 7) / 8)); - RINOK(WriteBoolVector(emptyStreamVector)); + WriteByte(NID::kEmptyStream); + WriteNumber((emptyStreamVector.Size() + 7) / 8); + WriteBoolVector(emptyStreamVector); CBoolVector emptyFileVector, antiVector; emptyFileVector.Reserve(numEmptyStreams); antiVector.Reserve(numEmptyStreams); CNum numEmptyFiles = 0, numAntiItems = 0; - for(i = 0; i < database.Files.Size(); i++) + for (i = 0; i < db.Files.Size(); i++) { - const CFileItem &file = database.Files[i]; + const CFileItem &file = db.Files[i]; if (!file.HasStream) { - emptyFileVector.Add(!file.IsDirectory); - if (!file.IsDirectory) + emptyFileVector.Add(!file.IsDir); + if (!file.IsDir) numEmptyFiles++; - antiVector.Add(file.IsAnti); - if (file.IsAnti) + bool isAnti = db.IsItemAnti(i); + antiVector.Add(isAnti); + if (isAnti) numAntiItems++; } } if (numEmptyFiles > 0) { - RINOK(WriteByte(NID::kEmptyFile)); - RINOK(WriteNumber((emptyFileVector.Size() + 7) / 8)); - RINOK(WriteBoolVector(emptyFileVector)); + WriteByte(NID::kEmptyFile); + WriteNumber((emptyFileVector.Size() + 7) / 8); + WriteBoolVector(emptyFileVector); } if (numAntiItems > 0) { - RINOK(WriteByte(NID::kAnti)); - RINOK(WriteNumber((antiVector.Size() + 7) / 8)); - RINOK(WriteBoolVector(antiVector)); + WriteByte(NID::kAnti); + WriteNumber((antiVector.Size() + 7) / 8); + WriteBoolVector(antiVector); } } - - if (numDefinedNames > 0) - { - ///////////////////////////////////////////////// - RINOK(WriteByte(NID::kName)); - { - RINOK(WriteNumber(1 + namesData.GetCapacity())); - RINOK(WriteByte(0)); - RINOK(WriteBytes(namesData)); - } - } - if (headerOptions.WriteCreated) - { - RINOK(WriteTime(database.Files, NID::kCreationTime)); - } - if (headerOptions.WriteModified) - { - RINOK(WriteTime(database.Files, NID::kLastWriteTime)); - } - if (headerOptions.WriteAccessed) - { - RINOK(WriteTime(database.Files, NID::kLastAccessTime)); - } - if (numDefinedAttributes > 0) { - RINOK(WriteByte(NID::kWinAttributes)); - size_t size = 2; - if (numDefinedAttributes != database.Files.Size()) - size += (attributesBoolVector.Size() + 7) / 8 + 1; - size += attributesData.GetCapacity(); - - RINOK(WriteNumber(size)); - if (numDefinedAttributes == database.Files.Size()) + /* ---------- Names ---------- */ + + int numDefined = 0; + size_t namesDataSize = 0; + for (int i = 0; i < db.Files.Size(); i++) { - RINOK(WriteByte(1)); + const UString &name = db.Files[i].Name; + if (!name.IsEmpty()) + numDefined++; + namesDataSize += (name.Length() + 1) * 2; } - else + + if (numDefined > 0) { - RINOK(WriteByte(0)); - RINOK(WriteBoolVector(attributesBoolVector)); - } + namesDataSize++; + SkipAlign(2 + GetBigNumberSize(namesDataSize), 2); - { - RINOK(WriteByte(0)); - RINOK(WriteBytes(attributesData)); + WriteByte(NID::kName); + WriteNumber(namesDataSize); + WriteByte(0); + for (int i = 0; i < db.Files.Size(); i++) + { + const UString &name = db.Files[i].Name; + for (int t = 0; t <= name.Length(); t++) + { + wchar_t c = name[t]; + WriteByte((Byte)c); + WriteByte((Byte)(c >> 8)); + } + } } } - if (numDefinedStarts > 0) + if (headerOptions.WriteCTime) WriteUInt64DefVector(db.CTime, NID::kCTime); + if (headerOptions.WriteATime) WriteUInt64DefVector(db.ATime, NID::kATime); + if (headerOptions.WriteMTime) WriteUInt64DefVector(db.MTime, NID::kMTime); + WriteUInt64DefVector(db.StartPos, NID::kStartPos); + { - RINOK(WriteByte(NID::kStartPos)); - size_t size = 2; - if (numDefinedStarts != database.Files.Size()) - size += (startsBoolVector.Size() + 7) / 8 + 1; - size += startsData.GetCapacity(); - - RINOK(WriteNumber(size)); - if (numDefinedStarts == database.Files.Size()) + /* ---------- Write Attrib ---------- */ + CBoolVector boolVector; + boolVector.Reserve(db.Files.Size()); + int numDefined = 0; + for (i = 0; i < db.Files.Size(); i++) { - RINOK(WriteByte(1)); + bool defined = db.Files[i].AttribDefined; + boolVector.Add(defined); + if (defined) + numDefined++; } - else + if (numDefined > 0) { - RINOK(WriteByte(0)); - RINOK(WriteBoolVector(startsBoolVector)); - } - - { - RINOK(WriteByte(0)); - RINOK(WriteBytes(startsData)); + WriteAlignedBoolHeader(boolVector, numDefined, NID::kWinAttributes, 4); + for (i = 0; i < db.Files.Size(); i++) + { + const CFileItem &file = db.Files[i]; + if (file.AttribDefined) + WriteUInt32(file.Attrib); + } } } - RINOK(WriteByte(NID::kEnd)); // for files - RINOK(WriteByte(NID::kEnd)); // for headers - - return _outByte.Flush(); + WriteByte(NID::kEnd); // for files + WriteByte(NID::kEnd); // for headers } HRESULT COutArchive::WriteDatabase( DECL_EXTERNAL_CODECS_LOC_VARS - const CArchiveDatabase &database, - const CCompressionMethodMode *options, + const CArchiveDatabase &db, + const CCompressionMethodMode *options, const CHeaderOptions &headerOptions) { + if (!db.CheckNumFiles()) + return E_FAIL; + UInt64 headerOffset; UInt32 headerCRC; UInt64 headerSize; - if (database.IsEmpty()) + if (db.IsEmpty()) { headerSize = 0; headerOffset = 0; @@ -952,19 +769,35 @@ HRESULT COutArchive::WriteDatabase( } else { - _dynamicBuffer.Init(); - _dynamicMode = false; - + bool encodeHeaders = false; if (options != 0) if (options->IsEmpty()) options = 0; if (options != 0) if (options->PasswordIsDefined || headerOptions.CompressMainHeader) - _dynamicMode = true; - RINOK(WriteHeader(database, headerOptions, headerOffset)); + encodeHeaders = true; + + _outByte.SetStream(SeqStream); + _outByte.Init(); + _crc = CRC_INIT_VAL; + _countMode = encodeHeaders; + _writeToStream = true; + _countSize = 0; + WriteHeader(db, headerOptions, headerOffset); - if (_dynamicMode) + if (encodeHeaders) { + CByteBuffer buf; + buf.SetCapacity(_countSize); + _outByte2.Init((Byte *)buf, _countSize); + + _countMode = false; + _writeToStream = false; + WriteHeader(db, headerOptions, headerOffset); + + if (_countSize != _outByte2.GetPos()) + return E_FAIL; + CCompressionMethodMode encryptOptions; encryptOptions.PasswordIsDefined = options->PasswordIsDefined; encryptOptions.Password = options->Password; @@ -973,27 +806,23 @@ HRESULT COutArchive::WriteDatabase( CObjectVector<CFolder> folders; RINOK(EncodeStream( EXTERNAL_CODECS_LOC_VARS - encoder, _dynamicBuffer, - _dynamicBuffer.GetSize(), packSizes, folders)); - _dynamicMode = false; - _mainMode = true; - - _outByte.SetStream(SeqStream); - _outByte.Init(); - _crc = CRC_INIT_VAL; + encoder, (const Byte *)buf, + _countSize, packSizes, folders)); + + _writeToStream = true; if (folders.Size() == 0) throw 1; - RINOK(WriteID(NID::kEncodedHeader)); - RINOK(WritePackInfo(headerOffset, packSizes, - CRecordVector<bool>(), CRecordVector<UInt32>())); - RINOK(WriteUnPackInfo(folders)); - RINOK(WriteByte(NID::kEnd)); + WriteID(NID::kEncodedHeader); + WritePackInfo(headerOffset, packSizes, + CRecordVector<bool>(), CRecordVector<UInt32>()); + WriteUnpackInfo(folders); + WriteByte(NID::kEnd); for (int i = 0; i < packSizes.Size(); i++) headerOffset += packSizes[i]; - RINOK(_outByte.Flush()); } + RINOK(_outByte.Flush()); headerCRC = CRC_GET_DIGEST(_crc); headerSize = _outByte.GetProcessedSize(); } @@ -1003,8 +832,8 @@ HRESULT COutArchive::WriteDatabase( CFinishHeader h; h.NextHeaderSize = headerSize; h.NextHeaderCRC = headerCRC; - h.NextHeaderOffset = - UInt64(0) - (headerSize + + h.NextHeaderOffset = + UInt64(0) - (headerSize + 4 + kFinishHeaderSize); h.ArchiveStartOffset = h.NextHeaderOffset - headerOffset; h.AdditionalStartBlockSize = 0; @@ -1023,4 +852,25 @@ HRESULT COutArchive::WriteDatabase( } } +void CArchiveDatabase::GetFile(int index, CFileItem &file, CFileItem2 &file2) const +{ + file = Files[index]; + file2.CTimeDefined = CTime.GetItem(index, file2.CTime); + file2.ATimeDefined = ATime.GetItem(index, file2.ATime); + file2.MTimeDefined = MTime.GetItem(index, file2.MTime); + file2.StartPosDefined = StartPos.GetItem(index, file2.StartPos); + file2.IsAnti = IsItemAnti(index); +} + +void CArchiveDatabase::AddFile(const CFileItem &file, const CFileItem2 &file2) +{ + int index = Files.Size(); + CTime.SetItem(index, file2.CTimeDefined, file2.CTime); + ATime.SetItem(index, file2.ATimeDefined, file2.ATime); + MTime.SetItem(index, file2.MTimeDefined, file2.MTime); + StartPos.SetItem(index, file2.StartPosDefined, file2.StartPos); + SetItemAnti(index, file2.IsAnti); + Files.Add(file); +} + }} diff --git a/CPP/7zip/Archive/7z/7zOut.h b/CPP/7zip/Archive/7z/7zOut.h index fd798184..bdd84abc 100755 --- a/CPP/7zip/Archive/7z/7zOut.h +++ b/CPP/7zip/Archive/7z/7zOut.h @@ -9,7 +9,6 @@ #include "7zEncode.h" #include "../../Common/OutBuffer.h" -#include "../../../Common/DynamicBuffer.h" namespace NArchive { namespace N7z { @@ -21,58 +20,41 @@ class CWriteBufferLoc size_t _pos; public: CWriteBufferLoc(): _size(0), _pos(0) {} - void Init(Byte *data, size_t size) - { - _pos = 0; + void Init(Byte *data, size_t size) + { _data = data; - _size = size; + _size = size; + _pos = 0; } - HRESULT Write(const void *data, size_t size) + void WriteBytes(const void *data, size_t size) { - if (_pos + size > _size) - return E_FAIL; - memmove(_data + _pos, data, size); + if (size > _size - _pos) + throw 1; + memcpy(_data + _pos, data, size); _pos += size; - return S_OK; - } -}; - -class CWriteDynamicBuffer -{ - CByteDynamicBuffer _buffer; - size_t _pos; -public: - CWriteDynamicBuffer(): _pos(0) {} - void Init() - { - _pos = 0; } - void Write(const void *data, size_t size) + void WriteByte(Byte b) { - if (_pos + size > _buffer.GetCapacity()) - _buffer.EnsureCapacity(_pos + size); - memmove(((Byte *)_buffer) +_pos, data, size); - _pos += size; + if (_size == _pos) + throw 1; + _data[_pos++] = b; } - operator Byte *() { return (Byte *)_buffer; }; - operator const Byte *() const { return (const Byte *)_buffer; }; - size_t GetSize() const { return _pos; } + size_t GetPos() const { return _pos; } }; struct CHeaderOptions { - // bool UseAdditionalHeaderStreams; bool CompressMainHeader; - bool WriteModified; - bool WriteCreated; - bool WriteAccessed; + bool WriteCTime; + bool WriteATime; + bool WriteMTime; - CHeaderOptions(): - // UseAdditionalHeaderStreams(false), + CHeaderOptions(): CompressMainHeader(true), - WriteModified(true), - WriteCreated(false), - WriteAccessed(false) {} + WriteCTime(false), + WriteATime(false), + WriteMTime(true) + {} }; class COutArchive @@ -80,56 +62,41 @@ class COutArchive UInt64 _prefixHeaderPos; 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); + UInt64 GetPos() const; + void WriteBytes(const void *data, size_t size); + void WriteBytes(const CByteBuffer &data) { WriteBytes(data, data.GetCapacity()); } + void WriteByte(Byte b); + void WriteUInt32(UInt32 value); + void WriteUInt64(UInt64 value); + void WriteNumber(UInt64 value); + void WriteID(UInt64 value) { WriteNumber(value); } + + void WriteFolder(const CFolder &folder); HRESULT WriteFileHeader(const CFileItem &itemInfo); - HRESULT WriteBoolVector(const CBoolVector &boolVector); - HRESULT WriteHashDigests( + void WriteBoolVector(const CBoolVector &boolVector); + void WriteHashDigests( const CRecordVector<bool> &digestsDefined, const CRecordVector<UInt32> &hashDigests); - HRESULT WritePackInfo( + void WritePackInfo( UInt64 dataOffset, const CRecordVector<UInt64> &packSizes, const CRecordVector<bool> &packCRCsDefined, const CRecordVector<UInt32> &packCRCs); - HRESULT WriteUnPackInfo(const CObjectVector<CFolder> &folders); + void WriteUnpackInfo(const CObjectVector<CFolder> &folders); - HRESULT WriteSubStreamsInfo( + void WriteSubStreamsInfo( const CObjectVector<CFolder> &folders, - const CRecordVector<CNum> &numUnPackStreamsInFolders, - const CRecordVector<UInt64> &unPackSizes, + const CRecordVector<CNum> &numUnpackStreamsInFolders, + const CRecordVector<UInt64> &unpackSizes, const CRecordVector<bool> &digestsDefined, const CRecordVector<UInt32> &hashDigests); - /* - HRESULT WriteStreamsInfo( - UInt64 dataOffset, - const CRecordVector<UInt64> &packSizes, - const CRecordVector<bool> &packCRCsDefined, - const CRecordVector<UInt32> &packCRCs, - bool externalFolders, - UInt64 externalFoldersStreamIndex, - const CObjectVector<CFolder> &folders, - const CRecordVector<CNum> &numUnPackStreamsInFolders, - const CRecordVector<UInt64> &unPackSizes, - const CRecordVector<bool> &digestsDefined, - const CRecordVector<UInt32> &hashDigests); - */ - - - HRESULT WriteTime(const CObjectVector<CFileItem> &files, Byte type); + void SkipAlign(unsigned pos, unsigned alignSize); + void WriteAlignedBoolHeader(const CBoolVector &v, int numDefined, Byte type, unsigned itemSize); + void WriteUInt64DefVector(const CUInt64DefVector &v, Byte type); HRESULT EncodeStream( DECL_EXTERNAL_CODECS_LOC_VARS @@ -137,23 +104,19 @@ class COutArchive CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders); HRESULT EncodeStream( DECL_EXTERNAL_CODECS_LOC_VARS - CEncoder &encoder, const CByteBuffer &data, + CEncoder &encoder, const CByteBuffer &data, CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders); - HRESULT WriteHeader( - const CArchiveDatabase &database, + void WriteHeader( + const CArchiveDatabase &db, const CHeaderOptions &headerOptions, UInt64 &headerOffset); - bool _mainMode; - - bool _dynamicMode; - bool _countMode; + bool _writeToStream; size_t _countSize; + UInt32 _crc; COutBuffer _outByte; CWriteBufferLoc _outByte2; - CWriteDynamicBuffer _dynamicBuffer; - UInt32 _crc; #ifdef _7Z_VOL bool _endMarker; @@ -177,8 +140,8 @@ public: HRESULT SkeepPrefixArchiveHeader(); HRESULT WriteDatabase( DECL_EXTERNAL_CODECS_LOC_VARS - const CArchiveDatabase &database, - const CCompressionMethodMode *options, + const CArchiveDatabase &db, + const CCompressionMethodMode *options, const CHeaderOptions &headerOptions); #ifdef _7Z_VOL diff --git a/CPP/7zip/Archive/7z/7zProperties.cpp b/CPP/7zip/Archive/7z/7zProperties.cpp index f5b5ba98..66d90785 100755 --- a/CPP/7zip/Archive/7z/7zProperties.cpp +++ b/CPP/7zip/Archive/7z/7zProperties.cpp @@ -17,11 +17,11 @@ struct CPropMap STATPROPSTG StatPROPSTG; }; -CPropMap kPropMap[] = +CPropMap kPropMap[] = { { NID::kName, NULL, kpidPath, VT_BSTR}, { NID::kSize, NULL, kpidSize, VT_UI8}, - { NID::kPackInfo, NULL, kpidPackedSize, VT_UI8}, + { NID::kPackInfo, NULL, kpidPackSize, VT_UI8}, #ifdef _MULTI_PACK { 100, L"Pack0", kpidPackedSize0, VT_UI8}, @@ -31,10 +31,10 @@ CPropMap kPropMap[] = { 104, L"Pack4", kpidPackedSize4, VT_UI8}, #endif - { NID::kCreationTime, NULL, kpidCreationTime, VT_FILETIME}, - { NID::kLastWriteTime, NULL, kpidLastWriteTime, VT_FILETIME}, - { NID::kLastAccessTime, NULL, kpidLastAccessTime, VT_FILETIME}, - { NID::kWinAttributes, NULL, kpidAttributes, VT_UI4}, + { NID::kCTime, NULL, kpidCTime, VT_FILETIME}, + { NID::kMTime, NULL, kpidMTime, VT_FILETIME}, + { NID::kATime, NULL, kpidATime, VT_FILETIME}, + { NID::kWinAttributes, NULL, kpidAttrib, VT_UI4}, { NID::kStartPos, NULL, kpidPosition, VT_UI4}, { NID::kCRC, NULL, kpidCRC, VT_UI4}, @@ -58,7 +58,7 @@ static int FindPropInMap(UInt64 filePropID) return -1; } -static void CopyOneItem(CRecordVector<UInt64> &src, +static void CopyOneItem(CRecordVector<UInt64> &src, CRecordVector<UInt64> &dest, UInt32 item) { for (int i = 0; i < src.Size(); i++) @@ -92,17 +92,17 @@ static void InsertToHead(CRecordVector<UInt64> &dest, UInt32 item) } void CHandler::FillPopIDs() -{ +{ _fileInfoPopIDs.Clear(); #ifdef _7Z_VOL if(_volumes.Size() < 1) return; const CVolume &volume = _volumes.Front(); - const CArchiveDatabaseEx &_database = volume.Database; + const CArchiveDatabaseEx &_db = volume.Database; #endif - CRecordVector<UInt64> fileInfoPopIDs = _database.ArchiveInfo.FileInfoPopIDs; + CRecordVector<UInt64> fileInfoPopIDs = _db.ArchiveInfo.FileInfoPopIDs; RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream); RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile); @@ -111,13 +111,13 @@ void CHandler::FillPopIDs() CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kAnti); CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kSize); CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kPackInfo); - CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCreationTime); - CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kLastWriteTime); - CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kLastAccessTime); + CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCTime); + CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kMTime); + CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kATime); CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kWinAttributes); CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCRC); CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kComment); - _fileInfoPopIDs += fileInfoPopIDs; + _fileInfoPopIDs += fileInfoPopIDs; #ifndef _SFX _fileInfoPopIDs.Add(97); @@ -133,7 +133,7 @@ void CHandler::FillPopIDs() #endif #ifndef _SFX - InsertToHead(_fileInfoPopIDs, NID::kLastWriteTime); + InsertToHead(_fileInfoPopIDs, NID::kMTime); InsertToHead(_fileInfoPopIDs, NID::kPackInfo); InsertToHead(_fileInfoPopIDs, NID::kSize); InsertToHead(_fileInfoPopIDs, NID::kName); diff --git a/CPP/7zip/Archive/7z/7zProperties.h b/CPP/7zip/Archive/7z/7zProperties.h index 4da85f04..66181795 100755 --- a/CPP/7zip/Archive/7z/7zProperties.h +++ b/CPP/7zip/Archive/7z/7zProperties.h @@ -11,7 +11,7 @@ namespace N7z { enum { kpidPackedSize0 = kpidUserDefined, - kpidPackedSize1, + kpidPackedSize1, kpidPackedSize2, kpidPackedSize3, kpidPackedSize4 diff --git a/CPP/7zip/Archive/7z/7zSpecStream.cpp b/CPP/7zip/Archive/7z/7zSpecStream.cpp index 80d303a4..06969636 100755 --- a/CPP/7zip/Archive/7z/7zSpecStream.cpp +++ b/CPP/7zip/Archive/7z/7zSpecStream.cpp @@ -11,7 +11,7 @@ STDMETHODIMP CSequentialInStreamSizeCount2::Read(void *data, UInt32 size, UInt32 _size += realProcessedSize; if (processedSize != 0) *processedSize = realProcessedSize; - return result; + return result; } STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize( diff --git a/CPP/7zip/Archive/7z/7zSpecStream.h b/CPP/7zip/Archive/7z/7zSpecStream.h index 0253c421..2e26efd5 100755 --- a/CPP/7zip/Archive/7z/7zSpecStream.h +++ b/CPP/7zip/Archive/7z/7zSpecStream.h @@ -7,7 +7,7 @@ #include "../../ICoder.h" #include "../../../Common/MyCom.h" -class CSequentialInStreamSizeCount2: +class CSequentialInStreamSizeCount2: public ISequentialInStream, public ICompressGetSubStreamSize, public CMyUnknownImp diff --git a/CPP/7zip/Archive/7z/7zUpdate.cpp b/CPP/7zip/Archive/7z/7zUpdate.cpp index 68f4604d..d3039d49 100755 --- a/CPP/7zip/Archive/7z/7zUpdate.cpp +++ b/CPP/7zip/Archive/7z/7zUpdate.cpp @@ -22,7 +22,7 @@ static const UInt32 kDictionaryForBCJ2_LZMA = 1 << 20; static const UInt32 kAlgorithmForBCJ2_LZMA = 1; static const UInt32 kNumFastBytesForBCJ2_LZMA = 64; -static HRESULT WriteRange(IInStream *inStream, ISequentialOutStream *outStream, +static HRESULT WriteRange(IInStream *inStream, ISequentialOutStream *outStream, UInt64 position, UInt64 size, ICompressProgressInfo *progress) { RINOK(inStream->Seek(position, STREAM_SEEK_SET, 0)); @@ -117,9 +117,9 @@ static int CompareFolderRefs(const int *p1, const int *p2, void *param) db.Folders[i1], db.Folders[i2])); RINOZ(MyCompare( - db.NumUnPackStreamsVector[i1], - db.NumUnPackStreamsVector[i2])); - if (db.NumUnPackStreamsVector[i1] == 0) + db.NumUnpackStreamsVector[i1], + db.NumUnpackStreamsVector[i2])); + if (db.NumUnpackStreamsVector[i1] == 0) return 0; return CompareFiles( db.Files[db.FolderStartFileIndex[i1]], @@ -133,9 +133,9 @@ static int CompareEmptyItems(const int *p1, const int *p2, void *param) const CObjectVector<CUpdateItem> &updateItems = *(const CObjectVector<CUpdateItem> *)param; const CUpdateItem &u1 = updateItems[*p1]; const CUpdateItem &u2 = updateItems[*p2]; - if (u1.IsDirectory != u2.IsDirectory) - return (u1.IsDirectory) ? 1 : -1; - if (u1.IsDirectory) + if (u1.IsDir != u2.IsDir) + return (u1.IsDir) ? 1 : -1; + if (u1.IsDir) { if (u1.IsAnti != u2.IsAnti) return (u1.IsAnti ? 1 : -1); @@ -147,8 +147,8 @@ static int CompareEmptyItems(const int *p1, const int *p2, void *param) return MyStringCompareNoCase(u1.Name, u2.Name); } -static const char *g_Exts = - " lzma 7z ace arc arj bz bz2 deb lzo lzx gz pak rpm sit tgz tbz tbz2 tgz cab ha lha lzh rar zoo" +static const char *g_Exts = + " lzma 7z ace arc arj bz bz2 deb lzo lzx gz pak rpm sit tgz tbz tbz2 tgz cab ha lha lzh rar zoo" " zip jar ear war msi" " 3gp avi mov mpeg mpg mpe wmv" " aac ape fla flac la mp3 m4a mp4 ofr ogg pac ra rm rka shn swa tta wv wma wav" @@ -161,7 +161,7 @@ static const char *g_Exts = " iso bin nrg mdf img pdi tar cpio xpi" " vfd vhd vud vmc vsv" " vmdk dsk nvram vmem vmsd vmsn vmss vmtm" - " inl inc idl acf asa h hpp hxx c cpp cxx rc java cs pas bas vb cls ctl frm dlg def" + " inl inc idl acf asa h hpp hxx c cpp cxx rc java cs pas bas vb cls ctl frm dlg def" " f77 f f90 f95" " asm sql manifest dep " " mak clw csproj vcproj sln dsp dsw " @@ -212,29 +212,29 @@ int GetExtIndex(const char *ext) struct CRefItem { - UInt32 Index; const CUpdateItem *UpdateItem; + UInt32 Index; UInt32 ExtensionPos; UInt32 NamePos; int ExtensionIndex; - CRefItem(UInt32 index, const CUpdateItem &updateItem, bool sortByType): + CRefItem(UInt32 index, const CUpdateItem &ui, bool sortByType): + UpdateItem(&ui), Index(index), - UpdateItem(&updateItem), ExtensionPos(0), NamePos(0), ExtensionIndex(0) { if (sortByType) { - int slashPos = GetReverseSlashPos(updateItem.Name); + int slashPos = GetReverseSlashPos(ui.Name); NamePos = ((slashPos >= 0) ? (slashPos + 1) : 0); - int dotPos = updateItem.Name.ReverseFind(L'.'); + int dotPos = ui.Name.ReverseFind(L'.'); if (dotPos < 0 || (dotPos < slashPos && slashPos >= 0)) - ExtensionPos = updateItem.Name.Length(); - else + ExtensionPos = ui.Name.Length(); + else { ExtensionPos = dotPos + 1; - UString us = updateItem.Name.Mid(ExtensionPos); + UString us = ui.Name.Mid(ExtensionPos); if (!us.IsEmpty()) { us.MakeLower(); @@ -264,9 +264,9 @@ static int CompareUpdateItems(const CRefItem *p1, const CRefItem *p2, void *para const CUpdateItem &u1 = *a1.UpdateItem; const CUpdateItem &u2 = *a2.UpdateItem; int n; - if (u1.IsDirectory != u2.IsDirectory) - return (u1.IsDirectory) ? 1 : -1; - if (u1.IsDirectory) + if (u1.IsDir != u2.IsDir) + return (u1.IsDir) ? 1 : -1; + if (u1.IsDir) { if (u1.IsAnti != u2.IsAnti) return (u1.IsAnti ? 1 : -1); @@ -279,8 +279,9 @@ static int CompareUpdateItems(const CRefItem *p1, const CRefItem *p2, void *para RINOZ(MyCompare(a1.ExtensionIndex, a2.ExtensionIndex)) RINOZ(MyStringCompareNoCase(u1.Name + a1.ExtensionPos, u2.Name + a2.ExtensionPos)); RINOZ(MyStringCompareNoCase(u1.Name + a1.NamePos, u2.Name + a2.NamePos)); - if (u1.IsLastWriteTimeDefined && u2.IsLastWriteTimeDefined) - RINOZ(CompareFileTime(&u1.LastWriteTime, &u2.LastWriteTime)); + if (!u1.MTimeDefined && u2.MTimeDefined) return 1; + if (u1.MTimeDefined && !u2.MTimeDefined) return -1; + if (u1.MTimeDefined && u2.MTimeDefined) RINOZ(MyCompare(u1.MTime, u2.MTime)); RINOZ(MyCompare(u1.Size, u2.Size)) } return MyStringCompareNoCase(u1.Name, u2.Name); @@ -313,7 +314,7 @@ static const UInt64 k_LZMA = 0x030101; static const UInt64 k_BCJ = 0x03030103; static const UInt64 k_BCJ2 = 0x0303011B; -static bool GetMethodFull(UInt64 methodID, +static bool GetMethodFull(UInt64 methodID, UInt32 numInStreams, CMethodFull &methodResult) { methodResult.Id = methodID; @@ -322,7 +323,7 @@ static bool GetMethodFull(UInt64 methodID, return true; } -static bool MakeExeMethod(const CCompressionMethodMode &method, +static bool MakeExeMethod(const CCompressionMethodMode &method, bool bcj2Filter, CCompressionMethodMode &exeMethod) { exeMethod = method; @@ -392,10 +393,10 @@ static bool MakeExeMethod(const CCompressionMethodMode &method, exeMethod.Binds.Add(bind); } return true; -} +} static void SplitFilesToGroups( - const CCompressionMethodMode &method, + const CCompressionMethodMode &method, bool useFilters, bool maxFilter, const CObjectVector<CUpdateItem> &updateItems, CObjectVector<CSolidGroup> &groups) @@ -411,14 +412,14 @@ static void SplitFilesToGroups( int i; for (i = 0; i < updateItems.Size(); i++) { - const CUpdateItem &updateItem = updateItems[i]; - if (!updateItem.NewData) + const CUpdateItem &ui = updateItems[i]; + if (!ui.NewData) continue; - if (!updateItem.HasStream()) + if (!ui.HasStream()) continue; if (useFilters) { - const UString name = updateItem.Name; + const UString name = ui.Name; int dotPos = name.ReverseFind(L'.'); if (dotPos >= 0) { @@ -442,31 +443,31 @@ static void SplitFilesToGroups( i++; } -static void FromUpdateItemToFileItem(const CUpdateItem &updateItem, - CFileItem &file) +static void FromUpdateItemToFileItem(const CUpdateItem &ui, + CFileItem &file, CFileItem2 &file2) { - file.Name = NItemName::MakeLegalName(updateItem.Name); - if (updateItem.AttributesAreDefined) - file.SetAttributes(updateItem.Attributes); - - if (updateItem.IsCreationTimeDefined) - file.SetCreationTime(updateItem.CreationTime); - if (updateItem.IsLastWriteTimeDefined) - file.SetLastWriteTime(updateItem.LastWriteTime); - if (updateItem.IsLastAccessTimeDefined) - file.SetLastAccessTime(updateItem.LastAccessTime); + file.Name = NItemName::MakeLegalName(ui.Name); + if (ui.AttribDefined) + file.SetAttrib(ui.Attrib); - file.UnPackSize = updateItem.Size; - file.IsDirectory = updateItem.IsDirectory; - file.IsAnti = updateItem.IsAnti; - file.HasStream = updateItem.HasStream(); + file2.CTime = ui.CTime; file2.CTimeDefined = ui.CTimeDefined; + file2.ATime = ui.ATime; file2.ATimeDefined = ui.ATimeDefined; + file2.MTime = ui.MTime; file2.MTimeDefined = ui.MTimeDefined; + file2.IsAnti = ui.IsAnti; + file2.StartPosDefined = false; + + file.Size = ui.Size; + file.IsDir = ui.IsDir; + file.HasStream = ui.HasStream(); } static HRESULT Update2( DECL_EXTERNAL_CODECS_LOC_VARS IInStream *inStream, - const CArchiveDatabaseEx *database, + const CArchiveDatabaseEx *db, const CObjectVector<CUpdateItem> &updateItems, + COutArchive &archive, + CArchiveDatabase &newDatabase, ISequentialOutStream *seqOutStream, IArchiveUpdateCallback *updateCallback, const CUpdateOptions &options) @@ -481,17 +482,17 @@ static HRESULT Update2( return E_NOTIMPL; */ - UInt64 startBlockSize = database != 0 ? database->ArchiveInfo.StartPosition: 0; + UInt64 startBlockSize = db != 0 ? db->ArchiveInfo.StartPosition: 0; if (startBlockSize > 0 && !options.RemoveSfxBlock) { RINOK(WriteRange(inStream, seqOutStream, 0, startBlockSize, NULL)); } CRecordVector<int> fileIndexToUpdateIndexMap; - if (database != 0) + if (db != 0) { - fileIndexToUpdateIndexMap.Reserve(database->Files.Size()); - for (int i = 0; i < database->Files.Size(); i++) + fileIndexToUpdateIndexMap.Reserve(db->Files.Size()); + for (int i = 0; i < db->Files.Size(); i++) fileIndexToUpdateIndexMap.Add(-1); } int i; @@ -503,17 +504,17 @@ static HRESULT Update2( } CRecordVector<int> folderRefs; - if (database != 0) + if (db != 0) { - for(i = 0; i < database->Folders.Size(); i++) + for(i = 0; i < db->Folders.Size(); i++) { CNum indexInFolder = 0; CNum numCopyItems = 0; - CNum numUnPackStreams = database->NumUnPackStreamsVector[i]; - for (CNum fileIndex = database->FolderStartFileIndex[i]; - indexInFolder < numUnPackStreams; fileIndex++) + CNum numUnpackStreams = db->NumUnpackStreamsVector[i]; + for (CNum fileIndex = db->FolderStartFileIndex[i]; + indexInFolder < numUnpackStreams; fileIndex++) { - if (database->Files[fileIndex].HasStream) + if (db->Files[fileIndex].HasStream) { indexInFolder++; int updateIndex = fileIndexToUpdateIndexMap[fileIndex]; @@ -522,38 +523,35 @@ static HRESULT Update2( numCopyItems++; } } - if (numCopyItems != numUnPackStreams && numCopyItems != 0) + if (numCopyItems != numUnpackStreams && numCopyItems != 0) return E_NOTIMPL; // It needs repacking !!! if (numCopyItems > 0) folderRefs.Add(i); } - folderRefs.Sort(CompareFolderRefs, (void *)database); + folderRefs.Sort(CompareFolderRefs, (void *)db); } - CArchiveDatabase newDatabase; - //////////////////////////// - COutArchive archive; RINOK(archive.Create(seqOutStream, false)); RINOK(archive.SkeepPrefixArchiveHeader()); UInt64 complexity = 0; for(i = 0; i < folderRefs.Size(); i++) - complexity += database->GetFolderFullPackSize(folderRefs[i]); + complexity += db->GetFolderFullPackSize(folderRefs[i]); UInt64 inSizeForReduce = 0; for(i = 0; i < updateItems.Size(); i++) { - const CUpdateItem &updateItem = updateItems[i]; - if (updateItem.NewData) + const CUpdateItem &ui = updateItems[i]; + if (ui.NewData) { - complexity += updateItem.Size; + complexity += ui.Size; if (numSolidFiles == 1) { - if (updateItem.Size > inSizeForReduce) - inSizeForReduce = updateItem.Size; + if (ui.Size > inSizeForReduce) + inSizeForReduce = ui.Size; } else - inSizeForReduce += updateItem.Size; + inSizeForReduce += ui.Size; } } RINOK(updateCallback->SetTotal(complexity)); @@ -573,57 +571,62 @@ static HRESULT Update2( int folderIndex = folderRefs[i]; lps->ProgressOffset = complexity; - UInt64 packSize = database->GetFolderFullPackSize(folderIndex); + UInt64 packSize = db->GetFolderFullPackSize(folderIndex); RINOK(WriteRange(inStream, archive.SeqStream, - database->GetFolderStreamPos(folderIndex, 0), packSize, progress)); + db->GetFolderStreamPos(folderIndex, 0), packSize, progress)); complexity += packSize; - const CFolder &folder = database->Folders[folderIndex]; - CNum startIndex = database->FolderStartPackStreamIndex[folderIndex]; + const CFolder &folder = db->Folders[folderIndex]; + CNum startIndex = db->FolderStartPackStreamIndex[folderIndex]; for (int j = 0; j < folder.PackStreams.Size(); j++) { - newDatabase.PackSizes.Add(database->PackSizes[startIndex + j]); - // newDatabase.PackCRCsDefined.Add(database.PackCRCsDefined[startIndex + j]); - // newDatabase.PackCRCs.Add(database.PackCRCs[startIndex + j]); + newDatabase.PackSizes.Add(db->PackSizes[startIndex + j]); + // newDatabase.PackCRCsDefined.Add(db.PackCRCsDefined[startIndex + j]); + // newDatabase.PackCRCs.Add(db.PackCRCs[startIndex + j]); } newDatabase.Folders.Add(folder); - CNum numUnPackStreams = database->NumUnPackStreamsVector[folderIndex]; - newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams); + CNum numUnpackStreams = db->NumUnpackStreamsVector[folderIndex]; + newDatabase.NumUnpackStreamsVector.Add(numUnpackStreams); CNum indexInFolder = 0; - for (CNum fi = database->FolderStartFileIndex[folderIndex]; - indexInFolder < numUnPackStreams; fi++) + for (CNum fi = db->FolderStartFileIndex[folderIndex]; + indexInFolder < numUnpackStreams; fi++) { - CFileItem file = database->Files[fi]; + CFileItem file; + CFileItem2 file2; + db->GetFile(fi, file, file2); if (file.HasStream) { indexInFolder++; int updateIndex = fileIndexToUpdateIndexMap[fi]; if (updateIndex >= 0) { - const CUpdateItem &updateItem = updateItems[updateIndex]; - if (updateItem.NewProperties) + const CUpdateItem &ui = updateItems[updateIndex]; + if (ui.NewProperties) { - CFileItem file2; - FromUpdateItemToFileItem(updateItem, file2); - file2.UnPackSize = file.UnPackSize; - file2.FileCRC = file.FileCRC; - file2.IsFileCRCDefined = file.IsFileCRCDefined; - file2.HasStream = file.HasStream; - file = file2; + CFileItem uf; + FromUpdateItemToFileItem(ui, uf, file2); + uf.Size = file.Size; + uf.Crc = file.Crc; + uf.CrcDefined = file.CrcDefined; + uf.HasStream = file.HasStream; + file = uf; } } - newDatabase.Files.Add(file); + newDatabase.AddFile(file, file2); } } } + folderRefs.ClearAndFree(); + fileIndexToUpdateIndexMap.ClearAndFree(); + ///////////////////////////////////////// // Compress New Files CObjectVector<CSolidGroup> groups; - SplitFilesToGroups(*options.Method, options.UseFilters, options.MaxFilter, + SplitFilesToGroups(*options.Method, options.UseFilters, options.MaxFilter, updateItems, groups); const UInt32 kMinReduceSize = (1 << 16); @@ -651,13 +654,13 @@ static HRESULT Update2( UInt32 index = refItems[i].Index; indices.Add(index); /* - const CUpdateItem &updateItem = updateItems[index]; + const CUpdateItem &ui = updateItems[index]; CFileItem file; - if (updateItem.NewProperties) - FromUpdateItemToFileItem(updateItem, file); + if (ui.NewProperties) + FromUpdateItemToFileItem(ui, file); else - file = database.Files[updateItem.IndexInArchive]; - if (file.IsAnti || file.IsDirectory) + file = db.Files[ui.IndexInArchive]; + if (file.IsAnti || file.IsDir) return E_FAIL; newDatabase.Files.Add(file); */ @@ -670,16 +673,16 @@ static HRESULT Update2( UInt64 totalSize = 0; int numSubFiles; UString prevExtension; - for (numSubFiles = 0; i + numSubFiles < numFiles && + for (numSubFiles = 0; i + numSubFiles < numFiles && numSubFiles < numSolidFiles; numSubFiles++) { - const CUpdateItem &updateItem = updateItems[indices[i + numSubFiles]]; - totalSize += updateItem.Size; + const CUpdateItem &ui = updateItems[indices[i + numSubFiles]]; + totalSize += ui.Size; if (totalSize > options.NumSolidBytes) break; if (options.SolidExtension) { - UString ext = updateItem.GetExtension(); + UString ext = ui.GetExtension(); if (numSubFiles == 0) prevExtension = ext; else @@ -699,29 +702,30 @@ static HRESULT Update2( int startPackIndex = newDatabase.PackSizes.Size(); RINOK(encoder.Encode( EXTERNAL_CODECS_LOC_VARS - solidInStream, NULL, &inSizeForReduce, folderItem, + solidInStream, NULL, &inSizeForReduce, folderItem, archive.SeqStream, newDatabase.PackSizes, progress)); for (; startPackIndex < newDatabase.PackSizes.Size(); startPackIndex++) lps->OutSize += newDatabase.PackSizes[startPackIndex]; - lps->InSize += folderItem.GetUnPackSize(); + lps->InSize += folderItem.GetUnpackSize(); // for() // newDatabase.PackCRCsDefined.Add(false); // newDatabase.PackCRCs.Add(0); newDatabase.Folders.Add(folderItem); - CNum numUnPackStreams = 0; + CNum numUnpackStreams = 0; for (int subIndex = 0; subIndex < numSubFiles; subIndex++) { - const CUpdateItem &updateItem = updateItems[indices[i + subIndex]]; + const CUpdateItem &ui = updateItems[indices[i + subIndex]]; CFileItem file; - if (updateItem.NewProperties) - FromUpdateItemToFileItem(updateItem, file); + CFileItem2 file2; + if (ui.NewProperties) + FromUpdateItemToFileItem(ui, file, file2); else - file = database->Files[updateItem.IndexInArchive]; - if (file.IsAnti || file.IsDirectory) + db->GetFile(ui.IndexInArchive, file, file2); + if (file2.IsAnti || file.IsDir) return E_FAIL; /* @@ -734,28 +738,30 @@ static HRESULT Update2( // file.Name += L".locked"; } - file.FileCRC = inStreamSpec->CRCs[subIndex]; - file.UnPackSize = inStreamSpec->Sizes[subIndex]; - if (file.UnPackSize != 0) + file.Crc = inStreamSpec->CRCs[subIndex]; + file.Size = inStreamSpec->Sizes[subIndex]; + if (file.Size != 0) { - file.IsFileCRCDefined = true; + file.CrcDefined = true; file.HasStream = true; - numUnPackStreams++; + numUnpackStreams++; } else { - file.IsFileCRCDefined = false; + file.CrcDefined = false; file.HasStream = false; } - newDatabase.Files.Add(file); + newDatabase.AddFile(file, file2); } - // numUnPackStreams = 0 is very bad case for locked files + // numUnpackStreams = 0 is very bad case for locked files // v3.13 doesn't understand it. - newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams); + newDatabase.NumUnpackStreamsVector.Add(numUnpackStreams); i += numSubFiles; } } + groups.ClearAndFree(); + { ///////////////////////////////////////// // Write Empty Files & Folders @@ -763,267 +769,51 @@ static HRESULT Update2( CRecordVector<int> emptyRefs; for(i = 0; i < updateItems.Size(); i++) { - const CUpdateItem &updateItem = updateItems[i]; - if (updateItem.NewData) + const CUpdateItem &ui = updateItems[i]; + if (ui.NewData) { - if (updateItem.HasStream()) + if (ui.HasStream()) continue; } else - if (updateItem.IndexInArchive != -1) - if (database->Files[updateItem.IndexInArchive].HasStream) + if (ui.IndexInArchive != -1) + if (db->Files[ui.IndexInArchive].HasStream) continue; emptyRefs.Add(i); } emptyRefs.Sort(CompareEmptyItems, (void *)&updateItems); - for(i = 0; i < emptyRefs.Size(); i++) + for (i = 0; i < emptyRefs.Size(); i++) { - const CUpdateItem &updateItem = updateItems[emptyRefs[i]]; + const CUpdateItem &ui = updateItems[emptyRefs[i]]; CFileItem file; - if (updateItem.NewProperties) - FromUpdateItemToFileItem(updateItem, file); + CFileItem2 file2; + if (ui.NewProperties) + FromUpdateItemToFileItem(ui, file, file2); else - file = database->Files[updateItem.IndexInArchive]; - newDatabase.Files.Add(file); + db->GetFile(ui.IndexInArchive, file, file2); + newDatabase.AddFile(file, file2); } } - /* - if (newDatabase.Files.Size() != updateItems.Size()) - return E_FAIL; - */ - - return archive.WriteDatabase(EXTERNAL_CODECS_LOC_VARS - newDatabase, options.HeaderMethod, options.HeaderOptions); -} - -#ifdef _7Z_VOL - -static const UInt64 k_Copy = 0x0; - -static HRESULT WriteVolumeHeader(COutArchive &archive, CFileItem &file, const CUpdateOptions &options) -{ - CCoderInfo coder; - coder.NumInStreams = coder.NumOutStreams = 1; - coder.MethodID = k_Copy; - - 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); -} - -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; - RINOK(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); -}; - -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 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; - RINOK(_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 && realProcessed == 0) - return E_FAIL; - if (_curPos == pureSize) - { - RINOK(Flush()); - } - } + newDatabase.ReserveDown(); return S_OK; } -#endif - HRESULT Update( DECL_EXTERNAL_CODECS_LOC_VARS IInStream *inStream, - const CArchiveDatabaseEx *database, + const CArchiveDatabaseEx *db, const CObjectVector<CUpdateItem> &updateItems, + COutArchive &archive, + CArchiveDatabase &newDatabase, ISequentialOutStream *seqOutStream, IArchiveUpdateCallback *updateCallback, const CUpdateOptions &options) { - #ifdef _7Z_VOL - if (seqOutStream) - #endif - return Update2( + return Update2( EXTERNAL_CODECS_LOC_VARS - 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 + inStream, db, updateItems, + archive, newDatabase, seqOutStream, updateCallback, options); } }} diff --git a/CPP/7zip/Archive/7z/7zUpdate.h b/CPP/7zip/Archive/7z/7zUpdate.h index ac1b5b65..bcc7cef7 100755 --- a/CPP/7zip/Archive/7z/7zUpdate.h +++ b/CPP/7zip/Archive/7z/7zUpdate.h @@ -14,38 +14,40 @@ namespace N7z { struct CUpdateItem { - bool NewData; - bool NewProperties; int IndexInArchive; int IndexInClient; - UInt32 Attributes; - FILETIME CreationTime; - FILETIME LastWriteTime; - FILETIME LastAccessTime; + UInt64 CTime; + UInt64 ATime; + UInt64 MTime; UInt64 Size; UString Name; + + UInt32 Attrib; + bool NewData; + bool NewProperties; + bool IsAnti; - bool IsDirectory; - - bool IsCreationTimeDefined; - bool IsLastWriteTimeDefined; - bool IsLastAccessTimeDefined; - bool AttributesAreDefined; - - bool HasStream() const - { return !IsDirectory && !IsAnti && Size != 0; } - CUpdateItem(): - IsAnti(false), - AttributesAreDefined(false), - IsCreationTimeDefined(false), - IsLastWriteTimeDefined(false), - IsLastAccessTimeDefined(false) + bool IsDir; + + bool AttribDefined; + bool CTimeDefined; + bool ATimeDefined; + bool MTimeDefined; + + bool HasStream() const { return !IsDir && !IsAnti && Size != 0; } + + CUpdateItem(): + IsAnti(false), + IsDir(false), + AttribDefined(false), + CTimeDefined(false), + ATimeDefined(false), + MTimeDefined(false) {} - void SetDirectoryStatusFromAttributes() - { IsDirectory = ((Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0); }; + void SetDirStatusFromAttrib() { IsDir = ((Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0); }; int GetExtensionPos() const; UString GetExtension() const; @@ -70,8 +72,10 @@ struct CUpdateOptions HRESULT Update( DECL_EXTERNAL_CODECS_LOC_VARS IInStream *inStream, - const CArchiveDatabaseEx *database, + const CArchiveDatabaseEx *db, const CObjectVector<CUpdateItem> &updateItems, + COutArchive &archive, + CArchiveDatabase &newDatabase, ISequentialOutStream *seqOutStream, IArchiveUpdateCallback *updateCallback, const CUpdateOptions &options); diff --git a/CPP/7zip/Archive/7z/makefile b/CPP/7zip/Archive/7z/makefile new file mode 100755 index 00000000..1a72da0e --- /dev/null +++ b/CPP/7zip/Archive/7z/makefile @@ -0,0 +1,111 @@ +PROG = 7z.dll +DEF_FILE = ../Archive.def +CFLAGS = $(CFLAGS) -I ../../../ \ + -DCOMPRESS_MT \ + -DEXTERNAL_CODECS \ + +LIBS = $(LIBS) oleaut32.lib user32.lib + +AR_OBJS = \ + $O\ArchiveExports.obj \ + $O\DllExports.obj \ + +7Z_OBJS = \ + $O\7zCompressionMode.obj \ + $O\7zDecode.obj \ + $O\7zEncode.obj \ + $O\7zExtract.obj \ + $O\7zFolderInStream.obj \ + $O\7zFolderOutStream.obj \ + $O\7zHandler.obj \ + $O\7zHandlerOut.obj \ + $O\7zHeader.obj \ + $O\7zIn.obj \ + $O\7zOut.obj \ + $O\7zProperties.obj \ + $O\7zSpecStream.obj \ + $O\7zUpdate.obj \ + $O\7zRegister.obj \ + +COMMON_OBJS = \ + $O\CRC.obj \ + $O\IntToString.obj \ + $O\NewHandler.obj \ + $O\MyString.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\MyVector.obj \ + +WIN_OBJS = \ + $O\DLL.obj \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\PropVariant.obj \ + $O\Synchronization.obj \ + $O\System.obj \ + +7ZIP_COMMON_OBJS = \ + $O\CreateCoder.obj \ + $O\InOutTempBuffer.obj \ + $O\FilterCoder.obj \ + $O\LimitedStreams.obj \ + $O\LockedStream.obj \ + $O\MethodId.obj \ + $O\MethodProps.obj \ + $O\OutBuffer.obj \ + $O\ProgressUtils.obj \ + $O\StreamBinder.obj \ + $O\StreamObjects.obj \ + $O\StreamUtils.obj \ + $O\VirtThread.obj \ + +AR_COMMON_OBJS = \ + $O\CoderMixer2.obj \ + $O\CoderMixer2MT.obj \ + $O\CrossThreadProgress.obj \ + $O\HandlerOut.obj \ + $O\InStreamWithCRC.obj \ + $O\ItemNameUtils.obj \ + $O\MultiStream.obj \ + $O\OutStreamWithCRC.obj \ + $O\ParseProperties.obj \ + +C_OBJS = \ + $O\Alloc.obj \ + $O\Threads.obj \ + +!include "../../Crc2.mak" + +OBJS = \ + $O\StdAfx.obj \ + $(AR_OBJS) \ + $(7Z_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(AR_COMMON_OBJS) \ + $O\CopyCoder.obj \ + $(C_OBJS) \ + $(CRC_OBJS) \ + $O\resource.res + +!include "../../../Build.mak" + +$(AR_OBJS): ../$(*B).cpp + $(COMPL) +$(7Z_OBJS): $(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(AR_COMMON_OBJS): ../Common/$(*B).cpp + $(COMPL) +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) +$(C_OBJS): ../../../../C/$(*B).c + $(COMPL_O2) +!include "../../Crc.mak" diff --git a/CPP/7zip/Archive/7z/resource.rc b/CPP/7zip/Archive/7z/resource.rc new file mode 100755 index 00000000..f79dac08 --- /dev/null +++ b/CPP/7zip/Archive/7z/resource.rc @@ -0,0 +1,11 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("7z Plugin", "7z") + +0 ICON "../Icons/7z.ico" + +STRINGTABLE +BEGIN + 100 "7z:0" +END + diff --git a/CPP/7zip/Archive/ArchiveExports.cpp b/CPP/7zip/Archive/ArchiveExports.cpp index 3c51a3f5..ae388d67 100755 --- a/CPP/7zip/Archive/ArchiveExports.cpp +++ b/CPP/7zip/Archive/ArchiveExports.cpp @@ -13,14 +13,14 @@ static const unsigned int kNumArcsMax = 32; static unsigned int g_NumArcs = 0; -static const CArcInfo *g_Arcs[kNumArcsMax]; -void RegisterArc(const CArcInfo *arcInfo) -{ +static const CArcInfo *g_Arcs[kNumArcsMax]; +void RegisterArc(const CArcInfo *arcInfo) +{ if (g_NumArcs < kNumArcsMax) - g_Arcs[g_NumArcs++] = arcInfo; + g_Arcs[g_NumArcs++] = arcInfo; } -DEFINE_GUID(CLSID_CArchiveHandler, +DEFINE_GUID(CLSID_CArchiveHandler, 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00); #define CLS_ARC_ID_ITEM(cls) ((cls).Data4[5]) diff --git a/CPP/7zip/Archive/Arj/ArjHandler.cpp b/CPP/7zip/Archive/Arj/ArjHandler.cpp deleted file mode 100755 index d154fd76..00000000 --- a/CPP/7zip/Archive/Arj/ArjHandler.cpp +++ /dev/null @@ -1,311 +0,0 @@ -// ArjHandler.cpp - -#include "StdAfx.h" - -#include "Common/Defs.h" -#include "Common/StringConvert.h" -#include "Common/ComTry.h" - -#include "Windows/Time.h" -#include "Windows/PropVariant.h" - -#include "ArjHandler.h" - -#include "../../ICoder.h" - -#include "../../Common/StreamObjects.h" -#include "../../Common/ProgressUtils.h" -#include "../../Common/LimitedStreams.h" - -#include "../../Compress/Copy/CopyCoder.h" -#include "../../Compress/Arj/ArjDecoder1.h" -#include "../../Compress/Arj/ArjDecoder2.h" - -#include "../Common/ItemNameUtils.h" -#include "../Common/OutStreamWithCRC.h" - -using namespace NWindows; -using namespace NTime; - -namespace NArchive { -namespace NArj{ - -const wchar_t *kHostOS[] = -{ - L"MSDOS", - L"PRIMOS", - L"Unix", - L"AMIGA", - L"Mac", - L"OS/2", - L"APPLE GS", - L"Atari ST", - L"Next", - L"VAX VMS", - L"WIN95" -}; - - -const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]); - -const wchar_t *kUnknownOS = L"Unknown"; - - -STATPROPSTG kProps[] = -{ - { NULL, kpidPath, VT_BSTR}, - { NULL, kpidIsFolder, VT_BOOL}, - { NULL, kpidSize, VT_UI8}, - { NULL, kpidPackedSize, VT_UI8}, - { NULL, kpidLastWriteTime, VT_FILETIME}, - { NULL, kpidAttributes, VT_UI4}, - { NULL, kpidEncrypted, VT_BOOL}, - { NULL, kpidCRC, VT_UI4}, - { NULL, kpidMethod, VT_UI1}, - // { NULL, kpidUnpackVer, VT_UI1}, - { NULL, kpidHostOS, VT_BSTR} -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps_NO - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = _items.Size(); - return S_OK; -} - -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; - const CItemEx &item = _items[index]; - switch(propID) - { - case kpidPath: prop = NItemName::GetOSName(MultiByteToUnicodeString(item.Name, CP_OEMCP)); break; - case kpidIsFolder: prop = item.IsDirectory(); break; - case kpidSize: prop = item.Size; break; - case kpidPackedSize: prop = item.PackSize; break; - case kpidAttributes: prop = item.GetWinAttributes(); break; - case kpidEncrypted: prop = item.IsEncrypted(); break; - case kpidCRC: prop = item.FileCRC; break; - case kpidMethod: prop = item.Method; break; - case kpidHostOS: prop = (item.HostOS < kNumHostOSes) ? (kHostOS[item.HostOS]) : kUnknownOS; break; - case kpidLastWriteTime: - { - FILETIME localFileTime, utcFileTime; - if (DosTimeToFileTime(item.ModifiedTime, localFileTime)) - { - if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime)) - utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; - } - else - utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; - prop = utcFileTime; - break; - } - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Open(IInStream *inStream, - const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback) -{ - COM_TRY_BEGIN - try - { - _items.Clear(); - CInArchive archive; - if(!archive.Open(inStream, maxCheckStartPosition)) - return S_FALSE; - if (callback != NULL) - { - RINOK(callback->SetTotal(NULL, NULL)); - UInt64 numFiles = _items.Size(); - RINOK(callback->SetCompleted(&numFiles, NULL)); - } - for (;;) - { - CItemEx item; - bool filled; - HRESULT result = archive.GetNextItem(filled, item); - if (result == S_FALSE) - return S_FALSE; - if (result != S_OK) - return S_FALSE; - if (!filled) - break; - _items.Add(item); - archive.IncreaseRealPosition(item.PackSize); - if (callback != NULL) - { - UInt64 numFiles = _items.Size(); - RINOK(callback->SetCompleted(&numFiles, NULL)); - } - } - _stream = inStream; - } - catch(...) - { - return S_FALSE; - } - COM_TRY_END - return S_OK; -} - -STDMETHODIMP CHandler::Close() -{ - _items.Clear(); - _stream.Release(); - return S_OK; -} - - - -////////////////////////////////////// -// CHandler::DecompressItems - -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)); - if (allFilesMode) - numItems = _items.Size(); - if(numItems == 0) - return S_OK; - UInt32 i; - for(i = 0; i < numItems; i++) - { - const CItemEx &item = _items[allFilesMode ? i : indices[i]]; - totalUnPacked += item.Size; - totalPacked += item.PackSize; - } - extractCallback->SetTotal(totalUnPacked); - - UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0; - UInt64 currentItemUnPacked, currentItemPacked; - - CMyComPtr<ICompressCoder> arj1Decoder; - CMyComPtr<ICompressCoder> arj2Decoder; - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr<ICompressProgressInfo> progress = lps; - lps->Init(extractCallback, false); - - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr<ISequentialInStream> inStream(streamSpec); - streamSpec->SetStream(_stream); - - for(i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked, - currentTotalPacked += currentItemPacked) - { - lps->InSize = currentTotalPacked; - lps->OutSize = currentTotalUnPacked; - RINOK(lps->SetCur()); - - currentItemUnPacked = currentItemPacked = 0; - - CMyComPtr<ISequentialOutStream> realOutStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - Int32 index = allFilesMode ? i : indices[i]; - const CItemEx &item = _items[index]; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - - if(item.IsDirectory()) - { - // if (!testMode) - { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - } - continue; - } - - if (!testMode && (!realOutStream)) - continue; - - RINOK(extractCallback->PrepareOperation(askMode)); - currentItemUnPacked = item.Size; - currentItemPacked = item.PackSize; - - { - COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC; - CMyComPtr<ISequentialOutStream> outStream(outStreamSpec); - outStreamSpec->SetStream(realOutStream); - outStreamSpec->Init(); - realOutStream.Release(); - - streamSpec->Init(item.PackSize); - - UInt64 pos; - _stream->Seek(item.DataPosition, STREAM_SEEK_SET, &pos); - - HRESULT result = S_OK; - Int32 opRes = NExtract::NOperationResult::kOK; - - if (item.IsEncrypted()) - { - opRes = NExtract::NOperationResult::kUnSupportedMethod; - } - else - { - switch(item.Method) - { - case NFileHeader::NCompressionMethod::kStored: - { - result = copyCoder->Code(inStream, outStream, NULL, NULL, progress); - if (result == S_OK && copyCoderSpec->TotalSize != item.PackSize) - result = S_FALSE; - break; - } - case NFileHeader::NCompressionMethod::kCompressed1a: - case NFileHeader::NCompressionMethod::kCompressed1b: - case NFileHeader::NCompressionMethod::kCompressed1c: - { - if (!arj1Decoder) - arj1Decoder = new NCompress::NArj::NDecoder1::CCoder; - result = arj1Decoder->Code(inStream, outStream, NULL, ¤tItemUnPacked, progress); - break; - } - case NFileHeader::NCompressionMethod::kCompressed2: - { - if (!arj2Decoder) - arj2Decoder = new NCompress::NArj::NDecoder2::CCoder; - result = arj2Decoder->Code(inStream, outStream, NULL, ¤tItemUnPacked, progress); - break; - } - default: - opRes = NExtract::NOperationResult::kUnSupportedMethod; - } - } - if (opRes == NExtract::NOperationResult::kOK) - { - if (result == S_FALSE) - opRes = NExtract::NOperationResult::kDataError; - else - { - RINOK(result); - opRes = (outStreamSpec->GetCRC() == item.FileCRC) ? - NExtract::NOperationResult::kOK: - NExtract::NOperationResult::kCRCError; - } - } - outStream.Release(); - RINOK(extractCallback->SetOperationResult(opRes)); - } - } - return S_OK; - COM_TRY_END -} - - -}} diff --git a/CPP/7zip/Archive/Arj/ArjHeader.h b/CPP/7zip/Archive/Arj/ArjHeader.h deleted file mode 100755 index 7aca1b98..00000000 --- a/CPP/7zip/Archive/Arj/ArjHeader.h +++ /dev/null @@ -1,121 +0,0 @@ -// Archive/Arj/Header.h - -#ifndef __ARCHIVE_ARJ_HEADER_H -#define __ARCHIVE_ARJ_HEADER_H - -#include "Common/Types.h" - -namespace NArchive { -namespace NArj { - -const int kMaxBlockSize = 2600; - -namespace NSignature -{ - const Byte kSig0 = 0x60; - const Byte kSig1 = 0xEA; -} - -/* -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; -}; -*/ - -namespace NFileHeader -{ - namespace NCompressionMethod - { - enum EType - { - kStored = 0, - kCompressed1a = 1, - kCompressed1b = 2, - kCompressed1c = 3, - kCompressed2 = 4, - kNoDataNoCRC = 8, - kNoData = 9 - }; - } - namespace NFileType - { - enum EType - { - kBinary = 0, - k7BitText = 1, - kDirectory = 3, - kVolumeLablel = 4, - kChapterLabel = 5 - }; - } - namespace NFlags - { - 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; - }; - */ - - namespace NHostOS - { - enum EEnum - { - kMSDOS = 0, // filesystem used by MS-DOS, OS/2, Win32 - // pkarj 2.50 (FAT / VFAT / FAT32 file systems) - kPRIMOS = 1, - kUnix = 2, // VAX/VMS - kAMIGA = 3, - kMac = 4, - kOS_2 = 5, // what if it's a minix filesystem? [cjh] - kAPPLE_GS = 6, // filesystem used by OS/2 (and NT 3.x) - kAtari_ST = 7, - kNext = 8, - kVAX_VMS = 9, - kWIN95 = 10 - }; - } -} - -}} - -#endif diff --git a/CPP/7zip/Archive/Arj/ArjIn.cpp b/CPP/7zip/Archive/Arj/ArjIn.cpp deleted file mode 100755 index cc7cde49..00000000 --- a/CPP/7zip/Archive/Arj/ArjIn.cpp +++ /dev/null @@ -1,287 +0,0 @@ -// Archive/arj/InEngine.cpp - -#include "StdAfx.h" - -#include "Common/StringConvert.h" -#include "Common/Buffer.h" - -#include "../../Common/StreamUtils.h" - -#include "ArjIn.h" - -extern "C" -{ - #include "../../../../C/7zCrc.h" -} - -namespace NArchive { -namespace NArj { - -HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize) -{ - size_t realProcessedSize = size; - HRESULT result = ReadStream(_stream, data, &realProcessedSize); - if (processedSize != NULL) - *processedSize = (UInt32)realProcessedSize; - IncreasePositionValue(realProcessedSize); - return result; -} - -static inline UInt16 GetUInt16FromMemLE(const Byte *p) -{ - return (UInt16)(p[0] | (((UInt16)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)); - if (block[0] != NSignature::kSig0 || block[1] != NSignature::kSig1) - return false; - UInt32 blockSize = GetUInt16FromMemLE(block + 2); - if (maxSize < 2 + 2 + blockSize + 4) - return false; - block += 4; - if (blockSize == 0 || blockSize > 2600) - return false; - UInt32 crcFromFile = GetUInt32FromMemLE(block + blockSize); - return (crcFromFile == CrcCalc(block, blockSize)); -} - -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 + 4; - - CByteBuffer byteBuffer; - static const UInt32 kSearchMarkerBufferSize = 0x10000; - byteBuffer.SetCapacity(kSearchMarkerBufferSize); - Byte *buffer = byteBuffer; - - UInt32 processedSize; - ReadBytes(buffer, kMarkerSizeMax, &processedSize); - if (processedSize == 0) - return false; - if (TestMarkerCandidate(buffer, processedSize)) - { - _position = _streamStartPosition; - if(_stream->Seek(_position, STREAM_SEEK_SET, NULL) != S_OK) - return false; - return true; - } - - UInt32 numBytesPrev = processedSize - 1; - memmove(buffer, buffer + 1, numBytesPrev); - UInt64 curTestPos = _streamStartPosition + 1; - for (;;) - { - if (searchHeaderSizeLimit != NULL) - if (curTestPos - _streamStartPosition > *searchHeaderSizeLimit) - return false; - UInt32 numReadBytes = kSearchMarkerBufferSize - numBytesPrev; - ReadBytes(buffer + numBytesPrev, numReadBytes, &processedSize); - UInt32 numBytesInBuffer = numBytesPrev + processedSize; - if (numBytesInBuffer < 1) - return false; - UInt32 numTests = numBytesInBuffer; - for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++) - { - if (TestMarkerCandidate(buffer + pos, numBytesInBuffer - pos)) - { - // _archiveInfo.StartPosition = curTestPos; - _position = curTestPos; - if(_stream->Seek(_position, STREAM_SEEK_SET, NULL) != S_OK) - return false; - return true; - } - } - numBytesPrev = numBytesInBuffer - numTests; - memmove(buffer, buffer + numTests, numBytesPrev); - } -} - -void CInArchive::IncreasePositionValue(UInt64 addValue) -{ - _position += 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) -{ - UInt32 realProcessedSize; - if(ReadBytes(data, size, &realProcessedSize) != S_OK) - throw CInArchiveException(CInArchiveException::kReadStreamError); - return (realProcessedSize == 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() -{ - _blockPos = 0; - _blockSize = SafeReadUInt16(); - if (_blockSize == 0 || _blockSize > kMaxBlockSize) - return false; - SafeReadBytes(_block, _blockSize); - UInt32 crcFromFile = SafeReadUInt32(); - if (crcFromFile != CrcCalc(_block, _blockSize)) - throw CInArchiveException(CInArchiveException::kCRCError); - return true; -} - -bool CInArchive::ReadBlock2() -{ - 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) -{ - _stream = inStream; - if(_stream->Seek(0, STREAM_SEEK_CUR, &_streamStartPosition) != S_OK) - return false; - _position = _streamStartPosition; - if (!FindAndReadMarker(searchHeaderSizeLimit)) - return false; - if (!ReadBlock2()) - return false; - for (;;) - if (!ReadBlock()) - break; - return true; -} - -void CInArchive::Close() -{ - _stream.Release(); -} - -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; - - 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; - if ((header.Flags & NFileHeader::NFlags::kExtFile) != 0) - extraData = GetUInt32FromMemLE(_block + pos); - */ - _blockPos = firstHeaderSize; - - for (; _blockPos < _blockSize;) - item.Name += (char)ReadByte(); - - for (;;) - if (!ReadBlock()) - break; - - item.DataPosition = _position; - - filled = true; - return S_OK; -} - -}} diff --git a/CPP/7zip/Archive/Arj/ArjIn.h b/CPP/7zip/Archive/Arj/ArjIn.h deleted file mode 100755 index b73d7dba..00000000 --- a/CPP/7zip/Archive/Arj/ArjIn.h +++ /dev/null @@ -1,75 +0,0 @@ -// Archive/ArjIn.h - -#ifndef __ARCHIVE_ARJIN_H -#define __ARCHIVE_ARJIN_H - -#include "Common/MyCom.h" -#include "../../IStream.h" - -#include "ArjItem.h" - -namespace NArchive { -namespace NArj { - -class CInArchiveException -{ -public: - enum CCauseType - { - kUnexpectedEndOfArchive = 0, - kCRCError, - kIncorrectArchive, - kReadStreamError, - kSeekStreamError - } - Cause; - CInArchiveException(CCauseType cause): Cause(cause) {}; -}; - -class CProgressVirt -{ -public: - STDMETHOD(SetCompleted)(const UInt64 *numFiles) PURE; -}; - -class CInArchive -{ - CMyComPtr<IInStream> _stream; - UInt64 _streamStartPosition; - UInt64 _position; - UInt16 _blockSize; - Byte _block[kMaxBlockSize]; - UInt32 _blockPos; - - - bool FindAndReadMarker(const UInt64 *searchHeaderSizeLimit); - - bool ReadBlock(); - bool ReadBlock2(); - - 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); - void Close(); - - void IncreaseRealPosition(UInt64 addValue); -}; - -}} - -#endif diff --git a/CPP/7zip/Archive/Arj/ArjItem.h b/CPP/7zip/Archive/Arj/ArjItem.h deleted file mode 100755 index a0112107..00000000 --- a/CPP/7zip/Archive/Arj/ArjItem.h +++ /dev/null @@ -1,75 +0,0 @@ -// Archive/ArjItem.h - -#ifndef __ARCHIVE_ARJ_ITEM_H -#define __ARCHIVE_ARJ_ITEM_H - -#include "Common/Types.h" -#include "Common/MyString.h" -#include "ArjHeader.h" - -namespace NArchive { -namespace NArj { - -struct CVersion -{ - Byte Version; - Byte HostOS; -}; - -inline bool operator==(const CVersion &v1, const CVersion &v2) - { return (v1.Version == v2.Version) && (v1.HostOS == v2.HostOS); } -inline bool operator!=(const CVersion &v1, const CVersion &v2) - { return !(v1 == v2); } - -class CItem -{ -public: - 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; - - AString Name; - - bool IsEncrypted() const { return (Flags & NFileHeader::NFlags::kGarbled) != 0; } - bool IsDirectory() const { return (FileType == NFileHeader::NFileType::kDirectory); } - UInt32 GetWinAttributes() const - { - UInt32 winAtrributes; - switch(HostOS) - { - case NFileHeader::NHostOS::kMSDOS: - case NFileHeader::NHostOS::kWIN95: - winAtrributes = FileAccessMode; - break; - default: - winAtrributes = 0; - } - if (IsDirectory()) - winAtrributes |= FILE_ATTRIBUTE_DIRECTORY; - return winAtrributes; - } -}; - -class CItemEx: public CItem -{ -public: - UInt64 DataPosition; -}; - -}} - -#endif - - diff --git a/CPP/7zip/Archive/Arj/ArjRegister.cpp b/CPP/7zip/Archive/Arj/ArjRegister.cpp deleted file mode 100755 index 8fb6c9ee..00000000 --- a/CPP/7zip/Archive/Arj/ArjRegister.cpp +++ /dev/null @@ -1,13 +0,0 @@ -// ArjRegister.cpp - -#include "StdAfx.h" - -#include "../../Common/RegisterArc.h" - -#include "ArjHandler.h" -static IInArchive *CreateArc() { return new NArchive::NArj::CHandler; } - -static CArcInfo g_ArcInfo = - { L"Arj", L"arj", 0, 4, { 0x60, 0xEA }, 2, false, CreateArc, 0 }; - -REGISTER_ARC(Arj) diff --git a/CPP/7zip/Archive/Arj/StdAfx.cpp b/CPP/7zip/Archive/Arj/StdAfx.cpp deleted file mode 100755 index d0feea85..00000000 --- a/CPP/7zip/Archive/Arj/StdAfx.cpp +++ /dev/null @@ -1,3 +0,0 @@ -// StdAfx.cpp - -#include "StdAfx.h" diff --git a/CPP/7zip/Archive/ArjHandler.cpp b/CPP/7zip/Archive/ArjHandler.cpp new file mode 100755 index 00000000..9b12ed31 --- /dev/null +++ b/CPP/7zip/Archive/ArjHandler.cpp @@ -0,0 +1,792 @@ +// ArjHandler.cpp + +#include "StdAfx.h" + +#include "Common/ComTry.h" +#include "Common/StringConvert.h" + +#include "Windows/PropVariant.h" +#include "Windows/Time.h" + +#include "../../../C/CpuArch.h" + +#include "../Common/LimitedStreams.h" +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamObjects.h" +#include "../Common/StreamUtils.h" + +#include "../Compress/Arj/ArjDecoder1.h" +#include "../Compress/Arj/ArjDecoder2.h" +#include "../Compress/Copy/CopyCoder.h" + +#include "IArchive.h" + +#include "Common/ItemNameUtils.h" +#include "Common/OutStreamWithCRC.h" + +using namespace NWindows; + +#define Get16(p) GetUi16(p) +#define Get32(p) GetUi32(p) + +namespace NArchive { +namespace NArj { + +const int kBlockSizeMin = 30; +const int kBlockSizeMax = 2600; + +namespace NSignature +{ + const Byte kSig0 = 0x60; + const Byte kSig1 = 0xEA; +} + +namespace NFileHeader +{ + namespace NCompressionMethod + { + enum + { + kStored = 0, + kCompressed1a = 1, + kCompressed1b = 2, + kCompressed1c = 3, + kCompressed2 = 4, + kNoDataNoCRC = 8, + kNoData = 9 + }; + } + + namespace NFileType + { + enum + { + kBinary = 0, + k7BitText = 1, + kArchiveHeader = 2, + kDirectory = 3, + kVolumeLablel = 4, + kChapterLabel = 5 + }; + } + + namespace NFlags + { + const Byte kGarbled = 1; + const Byte kVolume = 4; + const Byte kExtFile = 8; + const Byte kPathSym = 0x10; + const Byte kBackup = 0x20; + } + + namespace NHostOS + { + enum EEnum + { + kMSDOS = 0, // filesystem used by MS-DOS, OS/2, Win32 + // pkarj 2.50 (FAT / VFAT / FAT32 file systems) + kPRIMOS, + kUnix, + kAMIGA, + kMac, + kOS_2, + kAPPLE_GS, + kAtari_ST, + kNext, + kVAX_VMS, + kWIN95 + }; + } +} + +struct CArchiveHeader +{ + // Byte ArchiverVersion; + // Byte ExtractVersion; + Byte HostOS; + // Byte Flags; + // Byte SecuryVersion; + // Byte FileType; + // Byte Reserved; + UInt32 CTime; + UInt32 MTime; + UInt32 ArchiveSize; + // UInt32 SecurityEnvelopeFilePosition; + // UInt16 FilespecPositionInFilename; + // UInt16 LengthOfSecurityEnvelopeSata; + // Byte EncryptionVersion; + // Byte LastChapter; + AString Name; + AString Comment; + + HRESULT Parse(const Byte *p, unsigned size); +}; + +static HRESULT ReadString(const Byte *p, unsigned &size, AString &res) +{ + AString s; + for (unsigned i = 0; i < size;) + { + char c = (char)p[i++]; + if (c == 0) + { + size = i; + res = s; + return S_OK; + } + s += c; + } + return S_FALSE; +} + +HRESULT CArchiveHeader::Parse(const Byte *p, unsigned size) +{ + if (size < kBlockSizeMin) + return S_FALSE; + Byte firstHeaderSize = p[0]; + if (firstHeaderSize > size) + return S_FALSE; + // ArchiverVersion = p[1]; + // ExtractVersion = p[2]; + HostOS = p[3]; + // Flags = p[4]; + // SecuryVersion = p[5]; + if (p[6] != NFileHeader::NFileType::kArchiveHeader) + return S_FALSE; + // Reserved = p[7]; + CTime = Get32(p + 8); + MTime = Get32(p + 12); + ArchiveSize = Get32(p + 16); + // SecurityEnvelopeFilePosition = Get32(p + 20); + // UInt16 filespecPositionInFilename = Get16(p + 24); + // LengthOfSecurityEnvelopeSata = Get16(p + 26); + // EncryptionVersion = p[28]; + // LastChapter = p[29]; + unsigned pos = firstHeaderSize; + unsigned size1 = size - pos; + RINOK(ReadString(p + pos, size1, Name)); + pos += size1; + size1 = size - pos; + RINOK(ReadString(p + pos, size1, Comment)); + pos += size1; + return S_OK; +} + +struct CItem +{ + AString Name; + AString Comment; + + UInt32 MTime; + UInt32 PackSize; + UInt32 Size; + UInt32 FileCRC; + + Byte Version; + Byte ExtractVersion; + Byte HostOS; + Byte Flags; + Byte Method; + Byte FileType; + + // UInt16 FilespecPositionInFilename; + UInt16 FileAccessMode; + // Byte FirstChapter; + // Byte LastChapter; + + UInt64 DataPosition; + + bool IsEncrypted() const { return (Flags & NFileHeader::NFlags::kGarbled) != 0; } + bool IsDir() const { return (FileType == NFileHeader::NFileType::kDirectory); } + UInt32 GetWinAttributes() const + { + UInt32 winAtrributes; + switch(HostOS) + { + case NFileHeader::NHostOS::kMSDOS: + case NFileHeader::NHostOS::kWIN95: + winAtrributes = FileAccessMode; + break; + default: + winAtrributes = 0; + } + if (IsDir()) + winAtrributes |= FILE_ATTRIBUTE_DIRECTORY; + return winAtrributes; + } + + HRESULT Parse(const Byte *p, unsigned size); +}; + +HRESULT CItem::Parse(const Byte *p, unsigned size) +{ + if (size < kBlockSizeMin) + return S_FALSE; + + Byte firstHeaderSize = p[0]; + + Version = p[1]; + ExtractVersion = p[2]; + HostOS = p[3]; + Flags = p[4]; + Method = p[5]; + FileType = p[6]; + // Reserved = p[7]; + MTime = Get32(p + 8); + PackSize = Get32(p + 12); + Size = Get32(p + 16); + FileCRC = Get32(p + 20); + // FilespecPositionInFilename = Get16(p + 24); + FileAccessMode = Get16(p + 26); + // FirstChapter = p[28]; + // FirstChapter = p[29]; + + unsigned pos = firstHeaderSize; + unsigned size1 = size - pos; + RINOK(ReadString(p + pos, size1, Name)); + pos += size1; + size1 = size - pos; + RINOK(ReadString(p + pos, size1, Comment)); + pos += size1; + + return S_OK; +} + +struct CInArchiveException +{ + enum CCauseType + { + kUnexpectedEndOfArchive = 0, + kCRCError, + kIncorrectArchive, + } + Cause; + CInArchiveException(CCauseType cause): Cause(cause) {}; +}; + +class CInArchive +{ + UInt32 _blockSize; + Byte _block[kBlockSizeMax + 4]; + + HRESULT ReadBlock(bool &filled); + HRESULT ReadSignatureAndBlock(bool &filled); + HRESULT SkeepExtendedHeaders(); + + HRESULT SafeReadBytes(void *data, UInt32 size); + +public: + CArchiveHeader Header; + + IInStream *Stream; + IArchiveOpenCallback *Callback; + UInt64 NumFiles; + UInt64 NumBytes; + + HRESULT Open(const UInt64 *searchHeaderSizeLimit); + HRESULT GetNextItem(bool &filled, CItem &item); +}; + +static inline bool TestMarkerCandidate(const Byte *p, unsigned maxSize) +{ + if (p[0] != NSignature::kSig0 || p[1] != NSignature::kSig1) + return false; + UInt32 blockSize = Get16(p + 2); + p += 4; + if (p[6] != NFileHeader::NFileType::kArchiveHeader || + p[0] > blockSize || + maxSize < 2 + 2 + blockSize + 4 || + blockSize < kBlockSizeMin || blockSize > kBlockSizeMax || + p[28] > 8) // EncryptionVersion + return false; + // return (Get32(p + blockSize) == CrcCalc(p, blockSize)); + return true; +} + +static HRESULT FindAndReadMarker(ISequentialInStream *stream, const UInt64 *searchHeaderSizeLimit, UInt64 &position) +{ + position = 0; + + const int kMarkerSizeMin = 2 + 2 + kBlockSizeMin + 4; + const int kMarkerSizeMax = 2 + 2 + kBlockSizeMax + 4; + + CByteBuffer byteBuffer; + const UInt32 kBufSize = 1 << 16; + byteBuffer.SetCapacity(kBufSize); + Byte *buf = byteBuffer; + + size_t processedSize = kMarkerSizeMax; + RINOK(ReadStream(stream, buf, &processedSize)); + if (processedSize < kMarkerSizeMin) + return S_FALSE; + if (TestMarkerCandidate(buf, (unsigned)processedSize)) + return S_OK; + + UInt32 numBytesPrev = (UInt32)processedSize - 1; + memmove(buf, buf + 1, numBytesPrev); + UInt64 curTestPos = 1; + for (;;) + { + if (searchHeaderSizeLimit != NULL) + if (curTestPos > *searchHeaderSizeLimit) + return S_FALSE; + processedSize = kBufSize - numBytesPrev; + RINOK(ReadStream(stream, buf + numBytesPrev, &processedSize)); + UInt32 numBytesInBuffer = numBytesPrev + (UInt32)processedSize; + if (numBytesInBuffer < kMarkerSizeMin) + return S_FALSE; + UInt32 numTests = numBytesInBuffer - kMarkerSizeMin + 1; + UInt32 pos; + for (pos = 0; pos < numTests; pos++) + { + for (; buf[pos] != NSignature::kSig0 && pos < numTests; pos++); + if (pos == numTests) + break; + if (TestMarkerCandidate(buf + pos, numBytesInBuffer - pos)) + { + position = curTestPos + pos; + return S_OK; + } + } + curTestPos += pos; + numBytesPrev = numBytesInBuffer - numTests; + memmove(buf, buf + numTests, numBytesPrev); + } +} + +HRESULT CInArchive::SafeReadBytes(void *data, UInt32 size) +{ + size_t processed = size; + RINOK(ReadStream(Stream, data, &processed)); + if (processed != size) + throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive); + return S_OK; +} + +HRESULT CInArchive::ReadBlock(bool &filled) +{ + filled = false; + Byte buf[2]; + RINOK(SafeReadBytes(buf, 2)); + _blockSize = Get16(buf); + if (_blockSize == 0) + return S_OK; + if (_blockSize > kBlockSizeMax) + throw CInArchiveException(CInArchiveException::kIncorrectArchive); + RINOK(SafeReadBytes(_block, _blockSize + 4)); + NumBytes += _blockSize + 6; + if (Get32(_block + _blockSize) != CrcCalc(_block, _blockSize)) + throw CInArchiveException(CInArchiveException::kCRCError); + filled = true; + return S_OK; +} + +HRESULT CInArchive::ReadSignatureAndBlock(bool &filled) +{ + Byte id[2]; + RINOK(SafeReadBytes(id, 2)); + if (id[0] != NSignature::kSig0 || id[1] != NSignature::kSig1) + throw CInArchiveException(CInArchiveException::kIncorrectArchive); + return ReadBlock(filled); +} + +HRESULT CInArchive::SkeepExtendedHeaders() +{ + for (UInt32 i = 0;; i++) + { + bool filled; + RINOK(ReadBlock(filled)); + if (!filled) + return S_OK; + if (Callback && (i & 0xFF) == 0) + RINOK(Callback->SetCompleted(&NumFiles, &NumBytes)); + } +} + +HRESULT CInArchive::Open(const UInt64 *searchHeaderSizeLimit) +{ + UInt64 position = 0; + RINOK(FindAndReadMarker(Stream, searchHeaderSizeLimit, position)); + RINOK(Stream->Seek(position, STREAM_SEEK_SET, NULL)); + bool filled; + RINOK(ReadSignatureAndBlock(filled)); + if (!filled) + return S_FALSE; + RINOK(Header.Parse(_block, _blockSize)); + return SkeepExtendedHeaders(); +} + +HRESULT CInArchive::GetNextItem(bool &filled, CItem &item) +{ + RINOK(ReadSignatureAndBlock(filled)); + if (!filled) + return S_OK; + filled = false; + RINOK(item.Parse(_block, _blockSize)); + /* + UInt32 extraData; + if ((header.Flags & NFileHeader::NFlags::kExtFile) != 0) + extraData = GetUInt32FromMemLE(_block + pos); + */ + + RINOK(SkeepExtendedHeaders()); + filled = true; + return S_OK; +} + +class CHandler: + public IInArchive, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP1(IInArchive) + + INTERFACE_IInArchive(;) + + HRESULT Open2(IInStream *inStream, const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *callback); +private: + CInArchive _archive; + CObjectVector<CItem> _items; + CMyComPtr<IInStream> _stream; +}; + +const wchar_t *kHostOS[] = +{ + L"MSDOS", + L"PRIMOS", + L"UNIX", + L"AMIGA", + L"MAC", + L"OS/2", + L"APPLE GS", + L"ATARI ST", + L"NEXT", + L"VAX VMS", + L"WIN95" +}; + +const wchar_t *kUnknownOS = L"Unknown"; + +const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]); + +STATPROPSTG kArcProps[] = +{ + { NULL, kpidName, VT_BSTR}, + { NULL, kpidCTime, VT_BSTR}, + { NULL, kpidMTime, VT_BSTR}, + { NULL, kpidHostOS, VT_BSTR}, + { NULL, kpidComment, VT_BSTR} +}; + +STATPROPSTG kProps[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidIsDir, VT_BOOL}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackSize, VT_UI8}, + { NULL, kpidMTime, VT_FILETIME}, + { NULL, kpidAttrib, VT_UI4}, + { NULL, kpidEncrypted, VT_BOOL}, + { NULL, kpidCRC, VT_UI4}, + { NULL, kpidMethod, VT_UI1}, + { NULL, kpidHostOS, VT_BSTR}, + { NULL, kpidComment, VT_BSTR} +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +static void SetTime(UInt32 dosTime, NWindows::NCOM::CPropVariant &prop) +{ + if (dosTime == 0) + return; + FILETIME localFileTime, utc; + if (NTime::DosTimeToFileTime(dosTime, localFileTime)) + { + if (!LocalFileTimeToFileTime(&localFileTime, &utc)) + utc.dwHighDateTime = utc.dwLowDateTime = 0; + } + else + utc.dwHighDateTime = utc.dwLowDateTime = 0; + prop = utc; +} + +static void SetHostOS(Byte hostOS, NWindows::NCOM::CPropVariant &prop) +{ + prop = hostOS < kNumHostOSes ? kHostOS[hostOS] : kUnknownOS; +} + +static void SetUnicodeString(const AString &s, NWindows::NCOM::CPropVariant &prop) +{ + if (!s.IsEmpty()) + prop = MultiByteToUnicodeString(s, CP_OEMCP); +} + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch(propID) + { + case kpidName: SetUnicodeString(_archive.Header.Name, prop); break; + case kpidCTime: SetTime(_archive.Header.CTime, prop); break; + case kpidMTime: SetTime(_archive.Header.MTime, prop); break; + case kpidHostOS: SetHostOS(_archive.Header.HostOS, prop); break; + case kpidComment: SetUnicodeString(_archive.Header.Comment, prop); break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _items.Size(); + return S_OK; +} + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + const CItem &item = _items[index]; + switch(propID) + { + case kpidPath: prop = NItemName::GetOSName(MultiByteToUnicodeString(item.Name, CP_OEMCP)); break; + case kpidIsDir: prop = item.IsDir(); break; + case kpidSize: prop = item.Size; break; + case kpidPackSize: prop = item.PackSize; break; + case kpidAttrib: prop = item.GetWinAttributes(); break; + case kpidEncrypted: prop = item.IsEncrypted(); break; + case kpidCRC: prop = item.FileCRC; break; + case kpidMethod: prop = item.Method; break; + case kpidHostOS: SetHostOS(item.HostOS, prop); break; + case kpidMTime: SetTime(item.MTime, prop); break; + case kpidComment: SetUnicodeString(item.Comment, prop); break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +HRESULT CHandler::Open2(IInStream *inStream, const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *callback) +{ + Close(); + + UInt64 endPos = 0; + if (callback != NULL) + { + RINOK(inStream->Seek(0, STREAM_SEEK_END, &endPos)); + RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL)); + } + + _archive.Stream = inStream; + _archive.Callback = callback; + _archive.NumFiles = _archive.NumBytes = 0; + + RINOK(_archive.Open(maxCheckStartPosition)); + if (callback != NULL) + RINOK(callback->SetTotal(NULL, &endPos)); + for (;;) + { + CItem item; + bool filled; + + + RINOK(_archive.GetNextItem(filled, item)); + + RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &item.DataPosition)); + + if (!filled) + break; + _items.Add(item); + + if (inStream->Seek(item.PackSize, STREAM_SEEK_CUR, NULL) != S_OK) + throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive); + + _archive.NumFiles = _items.Size(); + _archive.NumBytes = item.DataPosition; + + if (callback != NULL && _items.Size() % 100 == 0) + { + RINOK(callback->SetCompleted(&_archive.NumFiles, &_archive.NumBytes)); + } + } + return S_OK; +} + +STDMETHODIMP CHandler::Open(IInStream *inStream, + const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback) +{ + COM_TRY_BEGIN + HRESULT res; + try + { + res = Open2(inStream, maxCheckStartPosition, callback); + if (res == S_OK) + { + _stream = inStream; + return S_OK; + } + } + catch(const CInArchiveException &) { res = S_FALSE; } + Close(); + return res; + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + _items.Clear(); + _stream.Release(); + return S_OK; +} + +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)); + if (allFilesMode) + numItems = _items.Size(); + if (numItems == 0) + return S_OK; + UInt32 i; + for (i = 0; i < numItems; i++) + { + const CItem &item = _items[allFilesMode ? i : indices[i]]; + totalUnpacked += item.Size; + totalPacked += item.PackSize; + } + extractCallback->SetTotal(totalUnpacked); + + totalUnpacked = totalPacked = 0; + UInt64 curUnpacked, curPacked; + + CMyComPtr<ICompressCoder> arj1Decoder; + CMyComPtr<ICompressCoder> arj2Decoder; + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); + CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr<ICompressProgressInfo> progress = lps; + lps->Init(extractCallback, false); + + CLimitedSequentialInStream *inStreamSpec = new CLimitedSequentialInStream; + CMyComPtr<ISequentialInStream> inStream(inStreamSpec); + inStreamSpec->SetStream(_stream); + + for (i = 0; i < numItems; i++, totalUnpacked += curUnpacked, totalPacked += curPacked) + { + lps->InSize = totalPacked; + lps->OutSize = totalUnpacked; + RINOK(lps->SetCur()); + + curUnpacked = curPacked = 0; + + CMyComPtr<ISequentialOutStream> realOutStream; + Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + Int32 index = allFilesMode ? i : indices[i]; + const CItem &item = _items[index]; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + + if (item.IsDir()) + { + // if (!testMode) + { + RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + } + continue; + } + + if (!testMode && (!realOutStream)) + continue; + + RINOK(extractCallback->PrepareOperation(askMode)); + curUnpacked = item.Size; + curPacked = item.PackSize; + + { + COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC; + CMyComPtr<ISequentialOutStream> outStream(outStreamSpec); + outStreamSpec->SetStream(realOutStream); + realOutStream.Release(); + outStreamSpec->Init(); + + inStreamSpec->Init(item.PackSize); + + UInt64 pos; + _stream->Seek(item.DataPosition, STREAM_SEEK_SET, &pos); + + HRESULT result = S_OK; + Int32 opRes = NExtract::NOperationResult::kOK; + + if (item.IsEncrypted()) + opRes = NExtract::NOperationResult::kUnSupportedMethod; + else + { + switch(item.Method) + { + case NFileHeader::NCompressionMethod::kStored: + { + result = copyCoder->Code(inStream, outStream, NULL, NULL, progress); + if (result == S_OK && copyCoderSpec->TotalSize != item.PackSize) + result = S_FALSE; + break; + } + case NFileHeader::NCompressionMethod::kCompressed1a: + case NFileHeader::NCompressionMethod::kCompressed1b: + case NFileHeader::NCompressionMethod::kCompressed1c: + { + if (!arj1Decoder) + arj1Decoder = new NCompress::NArj::NDecoder1::CCoder; + result = arj1Decoder->Code(inStream, outStream, NULL, &curUnpacked, progress); + break; + } + case NFileHeader::NCompressionMethod::kCompressed2: + { + if (!arj2Decoder) + arj2Decoder = new NCompress::NArj::NDecoder2::CCoder; + result = arj2Decoder->Code(inStream, outStream, NULL, &curUnpacked, progress); + break; + } + default: + opRes = NExtract::NOperationResult::kUnSupportedMethod; + } + } + if (opRes == NExtract::NOperationResult::kOK) + { + if (result == S_FALSE) + opRes = NExtract::NOperationResult::kDataError; + else + { + RINOK(result); + opRes = (outStreamSpec->GetCRC() == item.FileCRC) ? + NExtract::NOperationResult::kOK: + NExtract::NOperationResult::kCRCError; + } + } + outStream.Release(); + RINOK(extractCallback->SetOperationResult(opRes)); + } + } + return S_OK; + COM_TRY_END +} + +static IInArchive *CreateArc() { return new CHandler; } + +static CArcInfo g_ArcInfo = + { L"Arj", L"arj", 0, 4, { 0x60, 0xEA }, 2, false, CreateArc, 0 }; + +REGISTER_ARC(Arj) + +}} diff --git a/CPP/7zip/Archive/BZip2/BZip2Handler.cpp b/CPP/7zip/Archive/BZip2/BZip2Handler.cpp index c88c883f..30b75444 100755 --- a/CPP/7zip/Archive/BZip2/BZip2Handler.cpp +++ b/CPP/7zip/Archive/BZip2/BZip2Handler.cpp @@ -21,9 +21,9 @@ namespace NBZip2 { static const CMethodId kMethodId_BZip2 = 0x040202; -STATPROPSTG kProps[] = +STATPROPSTG kProps[] = { - { NULL, kpidPackedSize, VT_UI8} + { NULL, kpidPackSize, VT_UI8} }; IMP_IInArchive_Props @@ -40,13 +40,13 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIA NWindows::NCOM::CPropVariant prop; switch(propID) { - case kpidPackedSize: prop = _item.PackSize; break; + case kpidPackSize: prop = _item.PackSize; break; } prop.Detach(value); return S_OK; } -STDMETHODIMP CHandler::Open(IInStream *stream, +STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 * /* maxCheckStartPosition */, IArchiveOpenCallback * /* openArchiveCallback */) { diff --git a/CPP/7zip/Archive/BZip2/BZip2Handler.h b/CPP/7zip/Archive/BZip2/BZip2Handler.h index 4a45e52f..5bb3360a 100755 --- a/CPP/7zip/Archive/BZip2/BZip2Handler.h +++ b/CPP/7zip/Archive/BZip2/BZip2Handler.h @@ -15,7 +15,7 @@ namespace NArchive { namespace NBZip2 { -class CHandler: +class CHandler: public IInArchive, public IOutArchive, public ISetProperties, @@ -35,11 +35,11 @@ class CHandler: DECL_EXTERNAL_CODECS_VARS - void InitMethodProperties() - { + void InitMethodProperties() + { _level = 5; - _dicSize = - _numPasses = 0xFFFFFFFF; + _dicSize = + _numPasses = 0xFFFFFFFF; #ifdef COMPRESS_MT _numThreads = NWindows::NSystem::GetNumberOfProcessors();; #endif diff --git a/CPP/7zip/Archive/BZip2/BZip2HandlerOut.cpp b/CPP/7zip/Archive/BZip2/BZip2HandlerOut.cpp index 33c9d0bf..fd93f179 100755 --- a/CPP/7zip/Archive/BZip2/BZip2HandlerOut.cpp +++ b/CPP/7zip/Archive/BZip2/BZip2HandlerOut.cpp @@ -55,7 +55,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt { { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(0, kpidIsFolder, &prop)); + RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop)); if (prop.vt == VT_BOOL) { if (prop.boolVal != VARIANT_FALSE) @@ -79,21 +79,21 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt UInt32 dicSize = _dicSize; if (dicSize == 0xFFFFFFFF) - dicSize = (_level >= 5 ? kDicSizeX5 : - (_level >= 3 ? kDicSizeX3 : + dicSize = (_level >= 5 ? kDicSizeX5 : + (_level >= 3 ? kDicSizeX3 : kDicSizeX1)); UInt32 numPasses = _numPasses; if (numPasses == 0xFFFFFFFF) - numPasses = (_level >= 9 ? kNumPassesX9 : - (_level >= 7 ? kNumPassesX7 : + numPasses = (_level >= 9 ? kNumPassesX9 : + (_level >= 7 ? kNumPassesX7 : kNumPassesX1)); return UpdateArchive( EXTERNAL_CODECS_VARS - size, outStream, 0, dicSize, numPasses, + size, outStream, 0, dicSize, numPasses, #ifdef COMPRESS_MT - _numThreads, + _numThreads, #endif updateCallback); } @@ -151,6 +151,6 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v return E_INVALIDARG; } return S_OK; -} +} }} diff --git a/CPP/7zip/Archive/BZip2/BZip2Update.cpp b/CPP/7zip/Archive/BZip2/BZip2Update.cpp index d5eecc17..300d8844 100755 --- a/CPP/7zip/Archive/BZip2/BZip2Update.cpp +++ b/CPP/7zip/Archive/BZip2/BZip2Update.cpp @@ -47,15 +47,15 @@ HRESULT UpdateArchive( encoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties); if (setCoderProperties) { - NWindows::NCOM::CPropVariant properties[] = + NWindows::NCOM::CPropVariant properties[] = { - dictionary, + dictionary, numPasses #ifdef COMPRESS_MT , numThreads #endif }; - PROPID propIDs[] = + PROPID propIDs[] = { NCoderPropID::kDictionarySize, NCoderPropID::kNumPasses diff --git a/CPP/7zip/Archive/BZip2/StdAfx.cpp b/CPP/7zip/Archive/BZip2/StdAfx.cpp deleted file mode 100755 index d0feea85..00000000 --- a/CPP/7zip/Archive/BZip2/StdAfx.cpp +++ /dev/null @@ -1,3 +0,0 @@ -// StdAfx.cpp - -#include "StdAfx.h" diff --git a/CPP/7zip/Archive/Cab/CabBlockInStream.cpp b/CPP/7zip/Archive/Cab/CabBlockInStream.cpp index 343ef821..308616b8 100755 --- a/CPP/7zip/Archive/Cab/CabBlockInStream.cpp +++ b/CPP/7zip/Archive/Cab/CabBlockInStream.cpp @@ -2,8 +2,8 @@ #include "StdAfx.h" -extern "C" -{ +extern "C" +{ #include "../../../../C/Alloc.h" } @@ -45,7 +45,7 @@ public: m_Value ^= ((UInt32)(m_Hist[i])) << (8 * (m_Pos - i - 1)); } void UpdateUInt32(UInt32 v) { m_Value ^= v; } - UInt32 GetResult() const { return m_Value; } + UInt32 GetResult() const { return m_Value; } }; void CCheckSum2::Update(const void *data, UInt32 size) @@ -65,7 +65,7 @@ void CCheckSum2::Update(const void *data, UInt32 size) int numWords = size / 4; - while (numWords-- != 0) + while (numWords-- != 0) { UInt32 temp = *dataPointer++; temp |= ((UInt32)(*dataPointer++)) << 8; diff --git a/CPP/7zip/Archive/Cab/CabBlockInStream.h b/CPP/7zip/Archive/Cab/CabBlockInStream.h index b8b5d8b9..1db3835b 100755 --- a/CPP/7zip/Archive/Cab/CabBlockInStream.h +++ b/CPP/7zip/Archive/Cab/CabBlockInStream.h @@ -9,7 +9,7 @@ namespace NArchive { namespace NCab { -class CCabBlockInStream: +class CCabBlockInStream: public ISequentialInStream, public CMyUnknownImp { diff --git a/CPP/7zip/Archive/Cab/CabHandler.cpp b/CPP/7zip/Archive/Cab/CabHandler.cpp index b3e65d90..f4a11afb 100755 --- a/CPP/7zip/Archive/Cab/CabHandler.cpp +++ b/CPP/7zip/Archive/Cab/CabHandler.cpp @@ -31,19 +31,18 @@ namespace NCab { // #define _CAB_DETAILS #ifdef _CAB_DETAILS -enum +enum { kpidBlockReal = kpidUserDefined }; #endif -STATPROPSTG kProps[] = +STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, - // { NULL, kpidIsFolder, VT_BOOL}, { NULL, kpidSize, VT_UI8}, - { NULL, kpidLastWriteTime, VT_FILETIME}, - { NULL, kpidAttributes, VT_UI4}, + { NULL, kpidMTime, VT_FILETIME}, + { NULL, kpidAttrib, VT_UI4}, { NULL, kpidMethod, VT_BSTR}, { NULL, kpidBlock, VT_I4} #ifdef _CAB_DETAILS @@ -54,7 +53,7 @@ STATPROPSTG kProps[] = #endif }; -static const wchar_t *kMethods[] = +static const wchar_t *kMethods[] = { L"None", L"MSZip", @@ -65,7 +64,7 @@ static const wchar_t *kMethods[] = static const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]); static const wchar_t *kUnknownMethod = L"Unknown"; -STATPROPSTG kArcProps[] = +STATPROPSTG kArcProps[] = { { NULL, kpidMethod, VT_BSTR}, // { NULL, kpidSolid, VT_BOOL}, @@ -101,7 +100,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) resString += L' '; resString += method; } - prop = resString; + prop = resString; break; } // case kpidSolid: prop = _database.IsSolid(); break; @@ -145,13 +144,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va prop = (const wchar_t *)NItemName::WinNameToOSName(unicodeName); break; } - case kpidIsFolder: - prop = item.IsDirectory(); - break; - case kpidSize: - prop = item.Size; - break; - case kpidLastWriteTime: + case kpidIsDir: prop = item.IsDir(); break; + case kpidSize: prop = item.Size; break; + case kpidAttrib: prop = item.GetWinAttributes(); break; + + case kpidMTime: { FILETIME localFileTime, utcFileTime; if (NTime::DosTimeToFileTime(item.Time, localFileTime)) @@ -164,9 +161,6 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va prop = utcFileTime; break; } - case kpidAttributes: - prop = item.GetWinAttributes(); - break; case kpidMethod: { @@ -174,7 +168,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va const CFolder &folder = db.Folders[realFolderIndex]; int methodIndex = folder.GetCompressionMethod(); UString method = (methodIndex < kNumMethods) ? kMethods[methodIndex] : kUnknownMethod; - if (methodIndex == NHeader::NCompressionMethodMajor::kLZX || + if (methodIndex == NHeader::NCompressionMethodMajor::kLZX || methodIndex == NHeader::NCompressionMethodMajor::kQuantum) { method += L":"; @@ -185,21 +179,13 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va prop = method; break; } - case kpidBlock: - prop = (Int32)m_Database.GetFolderIndex(&mvItem); - break; + case kpidBlock: prop = (Int32)m_Database.GetFolderIndex(&mvItem); break; #ifdef _CAB_DETAILS - case kpidBlockReal: - prop = UInt32(item.FolderIndex); - break; - case kpidOffset: - prop = (UInt32)item.Offset; - break; - case kpidVolume: - prop = (UInt32)mvItem.VolumeIndex; - break; + case kpidBlockReal: prop = (UInt32)item.FolderIndex; break; + case kpidOffset: prop = (UInt32)item.Offset; break; + case kpidVolume: prop = (UInt32)mvItem.VolumeIndex; break; #endif } @@ -209,7 +195,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va } /* -class CPropgressImp: public CProgressVirt +class CProgressImp: public CProgressVirt { CMyComPtr<IArchiveOpenCallback> m_OpenArchiveCallback; public: @@ -219,14 +205,14 @@ public: { m_OpenArchiveCallback = openArchiveCallback; } }; -STDMETHODIMP CPropgressImp::SetTotal(const UInt64 *numFiles) +STDMETHODIMP CProgressImp::SetTotal(const UInt64 *numFiles) { if (m_OpenArchiveCallback) return m_OpenArchiveCallback->SetCompleted(numFiles, NULL); return S_OK; } -STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles) +STDMETHODIMP CProgressImp::SetCompleted(const UInt64 *numFiles) { if (m_OpenArchiveCallback) return m_OpenArchiveCallback->SetCompleted(numFiles, NULL); @@ -234,9 +220,9 @@ STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles) } */ -STDMETHODIMP CHandler::Open(IInStream *inStream, +STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *openArchiveCallback) + IArchiveOpenCallback *callback) { COM_TRY_BEGIN Close(); @@ -244,7 +230,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, CInArchive archive; CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback; { - CMyComPtr<IArchiveOpenCallback> openArchiveCallbackWrap = openArchiveCallback; + CMyComPtr<IArchiveOpenCallback> openArchiveCallbackWrap = callback; openArchiveCallbackWrap.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback); } @@ -264,7 +250,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, { const CDatabaseEx &dbPrev = m_Database.Volumes[prevChecked ? m_Database.Volumes.Size() - 1 : 0]; if (dbPrev.ArchiveInfo.SetID != db.ArchiveInfo.SetID || - dbPrev.ArchiveInfo.CabinetNumber + (prevChecked ? 1: - 1) != + dbPrev.ArchiveInfo.CabinetNumber + (prevChecked ? 1: - 1) != db.ArchiveInfo.CabinetNumber) res = S_FALSE; } @@ -273,7 +259,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, m_Database.Volumes.Insert(prevChecked ? m_Database.Volumes.Size() : 0, db); else if (res != S_FALSE) return res; - else + else { if (m_Database.Volumes.IsEmpty()) return S_FALSE; @@ -283,7 +269,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, } numItems += db.Items.Size(); - RINOK(openArchiveCallback->SetCompleted(&numItems, NULL)); + RINOK(callback->SetCompleted(&numItems, NULL)); nextStream = 0; for (;;) @@ -342,7 +328,7 @@ STDMETHODIMP CHandler::Close() return S_OK; } -class CCabFolderOutStream: +class CCabFolderOutStream: public ISequentialOutStream, public CMyUnknownImp { @@ -373,8 +359,8 @@ public: void Init( const CMvDatabaseEx *database, - const CRecordVector<bool> *extractStatuses, - int startIndex, + const CRecordVector<bool> *extractStatuses, + int startIndex, UInt64 folderSize, IArchiveExtractCallback *extractCallback, bool testMode); @@ -387,8 +373,8 @@ public: void CCabFolderOutStream::Init( const CMvDatabaseEx *database, - const CRecordVector<bool> *extractStatuses, - int startIndex, + const CRecordVector<bool> *extractStatuses, + int startIndex, UInt64 folderSize, IArchiveExtractCallback *extractCallback, bool testMode) @@ -409,7 +395,7 @@ void CCabFolderOutStream::Init( HRESULT CCabFolderOutStream::OpenFile() { - Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? (m_TestMode ? + Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? (m_TestMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract) : NExtract::NAskMode::kSkip; @@ -474,7 +460,7 @@ HRESULT CCabFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *proce { m_RealOutStream.Release(); RINOK(m_ExtractCallback->SetOperationResult( - m_IsOk ? + m_IsOk ? NArchive::NExtract::NOperationResult::kOK: NArchive::NExtract::NOperationResult::kDataError)); m_FileIsOpen = false; @@ -574,7 +560,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, int index = allFilesMode ? i : indices[i]; const CMvItem &mvItem = m_Database.Items[index]; const CItem &item = m_Database.Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; - if (item.IsDirectory()) + if (item.IsDir()) continue; int folderIndex = m_Database.GetFolderIndex(&mvItem); if (folderIndex != lastFolder) @@ -622,9 +608,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, const CItem &item = db.Items[itemIndex]; i++; - if (item.IsDirectory()) + if (item.IsDir()) { - Int32 askMode= testMode ? + Int32 askMode= testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract; CMyComPtr<ISequentialOutStream> realOutStream; @@ -638,7 +624,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, if (folderIndex < 0) { // If we need previous archive - Int32 askMode= testMode ? + Int32 askMode= testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract; CMyComPtr<ISequentialOutStream> realOutStream; @@ -661,7 +647,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, int indexNext = allFilesMode ? i : indices[i]; const CMvItem &mvItem = m_Database.Items[indexNext]; const CItem &item = m_Database.Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; - if (item.IsDirectory()) + if (item.IsDir()) continue; int newFolderIndex = m_Database.GetFolderIndex(&mvItem); @@ -683,7 +669,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, const CFolder &folder = db.Folders[item.GetFolderIndex(db.Folders.Size())]; - cabFolderOutStream->Init(&m_Database, &extractStatuses, startIndex2, + cabFolderOutStream->Init(&m_Database, &extractStatuses, startIndex2, curUnpack, extractCallback, testMode); cabBlockInStreamSpec->MsZip = false; diff --git a/CPP/7zip/Archive/Cab/CabHandler.h b/CPP/7zip/Archive/Cab/CabHandler.h index e17c3a7d..1edcd11e 100755 --- a/CPP/7zip/Archive/Cab/CabHandler.h +++ b/CPP/7zip/Archive/Cab/CabHandler.h @@ -10,7 +10,7 @@ namespace NArchive { namespace NCab { -class CHandler: +class CHandler: public IInArchive, public CMyUnknownImp { diff --git a/CPP/7zip/Archive/Cab/CabHeader.cpp b/CPP/7zip/Archive/Cab/CabHeader.cpp index 37533dff..d1f71df3 100755 --- a/CPP/7zip/Archive/Cab/CabHeader.cpp +++ b/CPP/7zip/Archive/Cab/CabHeader.cpp @@ -8,12 +8,8 @@ namespace NArchive{ namespace NCab{ namespace NHeader{ -namespace NArchive { +Byte kMarker[kMarkerSize] = {'M' + 1, 'S', 'C', 'F', 0, 0, 0, 0 }; -UInt32 kSignature = 0x4643534d + 1; -static class CSignatureInitializer -{ public: CSignatureInitializer() { kSignature--; }} g_SignatureInitializer; - -} +struct SignatureInitializer { SignatureInitializer() { kMarker[0]--; }; } g_SignatureInitializer; }}} diff --git a/CPP/7zip/Archive/Cab/CabHeader.h b/CPP/7zip/Archive/Cab/CabHeader.h index 5c122743..0f0d2af3 100755 --- a/CPP/7zip/Archive/Cab/CabHeader.h +++ b/CPP/7zip/Archive/Cab/CabHeader.h @@ -7,11 +7,13 @@ namespace NArchive { namespace NCab { -namespace NHeader{ +namespace NHeader { -namespace NArchive +const unsigned kMarkerSize = 8; +extern Byte kMarker[kMarkerSize]; + +namespace NArchive { - extern UInt32 kSignature; namespace NFlags { const int kPrevCabinet = 0x0001; diff --git a/CPP/7zip/Archive/Cab/CabIn.cpp b/CPP/7zip/Archive/Cab/CabIn.cpp index ae774f19..072e4076 100755 --- a/CPP/7zip/Archive/Cab/CabIn.cpp +++ b/CPP/7zip/Archive/Cab/CabIn.cpp @@ -2,15 +2,12 @@ #include "StdAfx.h" -#include "Common/StringConvert.h" -#include "Common/MyCom.h" #include "CabIn.h" -#include "Windows/Defs.h" -#include "../../Common/StreamUtils.h" +#include "../Common/FindSignature.h" -namespace NArchive{ -namespace NCab{ +namespace NArchive { +namespace NCab { /* static HRESULT ReadBytes(IInStream *inStream, void *data, UInt32 size) @@ -94,39 +91,21 @@ void CInArchive::Skeep(size_t size) ReadByte(); } -HRESULT CInArchive::Open2(IInStream *inStream, +HRESULT CInArchive::Open2(IInStream *stream, const UInt64 *searchHeaderSizeLimit, CDatabase &database) { database.Clear(); - RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &database.StartPosition)); + RINOK(stream->Seek(0, STREAM_SEEK_SET, &database.StartPosition)); - { - 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; - for (;;) - { - Byte b; - if (!inBuffer.ReadByte(b)) - return S_FALSE; - value >>= 8; - value |= ((UInt64)b) << ((kSignatureSize - 1) * 8); - if (inBuffer.GetProcessedSize() >= kSignatureSize) - { - if (value == kSignature64) - break; - if (searchHeaderSizeLimit != NULL) - if (inBuffer.GetProcessedSize() > (*searchHeaderSizeLimit)) - return S_FALSE; - } - } - database.StartPosition += inBuffer.GetProcessedSize() - kSignatureSize; - } + RINOK(FindSignatureInStream(stream, NHeader::kMarker, NHeader::kMarkerSize, + searchHeaderSizeLimit, database.StartPosition)); + + RINOK(stream->Seek(database.StartPosition + NHeader::kMarkerSize, STREAM_SEEK_SET, NULL)); + if (!inBuffer.Create(1 << 17)) + return E_OUTOFMEMORY; + inBuffer.SetStream(stream); + inBuffer.Init(); CInArchiveInfo &archiveInfo = database.ArchiveInfo; @@ -141,7 +120,9 @@ HRESULT CInArchive::Open2(IInStream *inStream, archiveInfo.VersionMajor = ReadByte(); // cabinet file format version, major archiveInfo.NumFolders = ReadUInt16(); // number of CFFOLDER entries in this cabinet archiveInfo.NumFiles = ReadUInt16(); // number of CFFILE entries in this cabinet - archiveInfo.Flags = ReadUInt16(); // number of CFFILE entries in this cabinet + archiveInfo.Flags = ReadUInt16(); + if (archiveInfo.Flags > 7) + return S_FALSE; archiveInfo.SetID = ReadUInt16(); // must be the same for all cabinets in a set archiveInfo.CabinetNumber = ReadUInt16(); // number of this cabinet file in a set @@ -175,9 +156,9 @@ HRESULT CInArchive::Open2(IInStream *inStream, database.Folders.Add(folder); } - RINOK(inStream->Seek(database.StartPosition + archiveInfo.FileHeadersOffset, STREAM_SEEK_SET, NULL)); + RINOK(stream->Seek(database.StartPosition + archiveInfo.FileHeadersOffset, STREAM_SEEK_SET, NULL)); - inBuffer.SetStream(inStream); + inBuffer.SetStream(stream); inBuffer.Init(); for(i = 0; i < archiveInfo.NumFiles; i++) { @@ -221,8 +202,8 @@ static int CompareMvItems(const CMvItem *p1, const CMvItem *p2, void *param) const CDatabaseEx &db2 = mvDb.Volumes[p2->VolumeIndex]; const CItem &item1 = db1.Items[p1->ItemIndex]; const CItem &item2 = db2.Items[p2->ItemIndex];; - bool isDir1 = item1.IsDirectory(); - bool isDir2 = item2.IsDirectory(); + bool isDir1 = item1.IsDir(); + bool isDir2 = item2.IsDir(); if (isDir1 && !isDir2) return -1; if (isDir2 && !isDir1) @@ -322,7 +303,7 @@ bool CMvDatabaseEx::Check() if (fIndex >= FolderStartFileIndex.Size()) return false; const CItem &item = Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; - if (item.IsDirectory()) + if (item.IsDir()) continue; int folderIndex = GetFolderIndex(&mvItem); if (folderIndex != prevFolder) diff --git a/CPP/7zip/Archive/Cab/CabIn.h b/CPP/7zip/Archive/Cab/CabIn.h index ebeead87..4975095f 100755 --- a/CPP/7zip/Archive/Cab/CabIn.h +++ b/CPP/7zip/Archive/Cab/CabIn.h @@ -93,7 +93,7 @@ public: return true; return false; } - int GetNumberOfNewFolders() const + int GetNumberOfNewFolders() const { int res = Folders.Size(); if (IsTherePrevFolder()) @@ -124,10 +124,10 @@ public: CRecordVector<CMvItem> Items; CRecordVector<int> StartFolderOfVol; CRecordVector<int> FolderStartFileIndex; - int GetFolderIndex(const CMvItem *mvi) const + int GetFolderIndex(const CMvItem *mvi) const { const CDatabaseEx &db = Volumes[mvi->VolumeIndex]; - return StartFolderOfVol[mvi->VolumeIndex] + + return StartFolderOfVol[mvi->VolumeIndex] + db.Items[mvi->ItemIndex].GetFolderIndex(db.Folders.Size()); } void Clear() @@ -152,7 +152,7 @@ class CInArchive void Skeep(size_t size); void ReadOtherArchive(COtherArchive &oa); - HRESULT Open2(IInStream *inStream, + HRESULT Open2(IInStream *inStream, const UInt64 *searchHeaderSizeLimit, CDatabase &database); public: diff --git a/CPP/7zip/Archive/Cab/CabItem.h b/CPP/7zip/Archive/Cab/CabItem.h index 8b41fe69..63a1e856 100755 --- a/CPP/7zip/Archive/Cab/CabItem.h +++ b/CPP/7zip/Archive/Cab/CabItem.h @@ -19,9 +19,8 @@ struct CFolder Byte GetCompressionMethod() const { return (Byte)(CompressionTypeMajor & 0xF); } }; -class CItem +struct CItem { -public: AString Name; UInt32 Offset; UInt32 Size; @@ -29,26 +28,28 @@ public: UInt16 FolderIndex; UInt16 Flags; UInt16 Attributes; + UInt64 GetEndOffset() const { return (UInt64)Offset + Size; } UInt32 GetWinAttributes() const { return (Attributes & ~NHeader::kFileNameIsUTFAttributeMask); } bool IsNameUTF() const { return (Attributes & NHeader::kFileNameIsUTFAttributeMask) != 0; } - bool IsDirectory() const { return (Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; } + bool IsDir() const { return (Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; } - bool ContinuedFromPrev() const - { - return + bool ContinuedFromPrev() const + { + return (FolderIndex == NHeader::NFolderIndex::kContinuedFromPrev) || (FolderIndex == NHeader::NFolderIndex::kContinuedPrevAndNext); } - bool ContinuedToNext() const - { - return + + bool ContinuedToNext() const + { + return (FolderIndex == NHeader::NFolderIndex::kContinuedToNext) || (FolderIndex == NHeader::NFolderIndex::kContinuedPrevAndNext); } - int GetFolderIndex(int numFolders) const - { + int GetFolderIndex(int numFolders) const + { if (ContinuedFromPrev()) return 0; if (ContinuedToNext()) diff --git a/CPP/7zip/Archive/Cab/StdAfx.cpp b/CPP/7zip/Archive/Cab/StdAfx.cpp deleted file mode 100755 index d0feea85..00000000 --- a/CPP/7zip/Archive/Cab/StdAfx.cpp +++ /dev/null @@ -1,3 +0,0 @@ -// StdAfx.cpp - -#include "StdAfx.h" diff --git a/CPP/7zip/Archive/Chm/ChmHandler.cpp b/CPP/7zip/Archive/Chm/ChmHandler.cpp index 7f3b1837..9da64bce 100755 --- a/CPP/7zip/Archive/Chm/ChmHandler.cpp +++ b/CPP/7zip/Archive/Chm/ChmHandler.cpp @@ -32,17 +32,16 @@ namespace NChm { #ifdef _CHM_DETAILS -enum +enum { kpidSection = kpidUserDefined }; #endif -STATPROPSTG kProps[] = +STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, - // { NULL, kpidIsFolder, VT_BOOL}, { NULL, kpidSize, VT_UI8}, { NULL, kpidMethod, VT_BSTR}, { NULL, kpidBlock, VT_UI4} @@ -54,7 +53,7 @@ STATPROPSTG kProps[] = #endif }; -STATPROPSTG kArcProps[] = +STATPROPSTG kArcProps[] = { { NULL, kpidNumBlocks, VT_UI8} }; @@ -71,7 +70,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) NWindows::NCOM::CPropVariant prop; switch(propID) { - case kpidNumBlocks: + case kpidNumBlocks: { UInt64 numBlocks = 0; for (int i = 0; i < m_Database.Sections.Size(); i++) @@ -84,7 +83,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) numBlocks += m.LzxInfo.ResetTable.GetNumBlocks(); } } - prop = numBlocks; + prop = numBlocks; break; } } @@ -132,15 +131,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va } break; } - case kpidIsFolder: - prop = item.IsDirectory(); - break; - case kpidSize: - prop = item.Size; - break; + case kpidIsDir: prop = item.IsDir(); break; + case kpidSize: prop = item.Size; break; case kpidMethod: { - if (!item.IsDirectory()) + if (!item.IsDir()) if (item.Section == 0) prop = L"Copy"; else if (item.Section < m_Database.Sections.Size()) @@ -156,12 +151,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va #ifdef _CHM_DETAILS - case kpidSection: - prop = (UInt32)item.Section; - break; - case kpidOffset: - prop = (UInt32)item.Offset; - break; + case kpidSection: prop = (UInt32)item.Section; break; + case kpidOffset: prop = (UInt32)item.Offset; break; #endif } @@ -170,41 +161,39 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va COM_TRY_END } -class CPropgressImp: public CProgressVirt +class CProgressImp: public CProgressVirt { - CMyComPtr<IArchiveOpenCallback> m_OpenArchiveCallback; + CMyComPtr<IArchiveOpenCallback> _callback; public: STDMETHOD(SetTotal)(const UInt64 *numFiles); STDMETHOD(SetCompleted)(const UInt64 *numFiles); - void Init(IArchiveOpenCallback *openArchiveCallback) - { m_OpenArchiveCallback = openArchiveCallback; } + CProgressImp(IArchiveOpenCallback *callback): _callback(callback) {}; }; -STDMETHODIMP CPropgressImp::SetTotal(const UInt64 *numFiles) +STDMETHODIMP CProgressImp::SetTotal(const UInt64 *numFiles) { - if (m_OpenArchiveCallback) - return m_OpenArchiveCallback->SetCompleted(numFiles, NULL); + if (_callback) + return _callback->SetCompleted(numFiles, NULL); return S_OK; } -STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles) +STDMETHODIMP CProgressImp::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, +STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *openArchiveCallback) + IArchiveOpenCallback * /* openArchiveCallback */) { COM_TRY_BEGIN m_Stream.Release(); try { CInArchive archive; - CPropgressImp progressImp; - progressImp.Init(openArchiveCallback); + // CProgressImp progressImp(openArchiveCallback); RINOK(archive.Open(inStream, maxCheckStartPosition, m_Database)); /* if (m_Database.LowLevel) @@ -227,7 +216,7 @@ STDMETHODIMP CHandler::Close() return S_OK; } -class CChmFolderOutStream: +class CChmFolderOutStream: public ISequentialOutStream, public CMyUnknownImp { @@ -280,7 +269,7 @@ void CChmFolderOutStream::Init( HRESULT CChmFolderOutStream::OpenFile() { - Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? (m_TestMode ? + Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? (m_TestMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract) : NExtract::NAskMode::kSkip; @@ -345,7 +334,7 @@ HRESULT CChmFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *proce { m_RealOutStream.Release(); RINOK(m_ExtractCallback->SetOperationResult( - m_IsOk ? + m_IsOk ? NArchive::NExtract::NOperationResult::kOK: NArchive::NExtract::NOperationResult::kDataError)); m_FileIsOpen = false; @@ -356,7 +345,7 @@ HRESULT CChmFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *proce else { if (m_CurrentIndex >= m_NumFiles) - return E_FAIL; + return E_FAIL; int fullIndex = m_StartIndex + m_CurrentIndex; m_RemainFileSize = m_Database->GetFileSize(fullIndex); UInt64 fileOffset = m_Database->GetFileOffset(fullIndex); @@ -458,7 +447,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(lps->SetCur()); CMyComPtr<ISequentialOutStream> realOutStream; - Int32 askMode= testMode ? + Int32 askMode= testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract; Int32 index = allFilesMode ? i : indices[i]; @@ -502,7 +491,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); realOutStream.Release(); - RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ? + RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ? NArchive::NExtract::NOperationResult::kOK: NArchive::NExtract::NOperationResult::kDataError)); } @@ -516,7 +505,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, int entryIndex = m_Database.Indices[index]; const CItem &item = m_Database.Items[entryIndex]; UInt64 sectionIndex = item.Section; - if (item.IsDirectory() || item.Size == 0) + if (item.IsDir() || item.Size == 0) continue; if (sectionIndex == 0) { @@ -554,10 +543,10 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, int entryIndex = m_Database.Indices[index]; const CItem &item = m_Database.Items[entryIndex]; UInt64 sectionIndex = item.Section; - Int32 askMode= testMode ? + Int32 askMode= testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract; - if (item.IsDirectory()) + if (item.IsDir()) { CMyComPtr<ISequentialOutStream> realOutStream; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); diff --git a/CPP/7zip/Archive/Chm/ChmHandler.h b/CPP/7zip/Archive/Chm/ChmHandler.h index 09113b8f..440c50f1 100755 --- a/CPP/7zip/Archive/Chm/ChmHandler.h +++ b/CPP/7zip/Archive/Chm/ChmHandler.h @@ -10,7 +10,7 @@ namespace NArchive { namespace NChm { -class CHandler: +class CHandler: public IInArchive, public CMyUnknownImp { diff --git a/CPP/7zip/Archive/Chm/ChmHeader.cpp b/CPP/7zip/Archive/Chm/ChmHeader.cpp index 4d485b6c..e8dc9f3e 100755 --- a/CPP/7zip/Archive/Chm/ChmHeader.cpp +++ b/CPP/7zip/Archive/Chm/ChmHeader.cpp @@ -11,11 +11,11 @@ namespace NHeader{ UInt32 kItsfSignature = 0x46535449 + 1; UInt32 kItolSignature = 0x4C4F5449 + 1; static class CSignatureInitializer -{ -public: +{ +public: CSignatureInitializer() - { - kItsfSignature--; + { + kItsfSignature--; kItolSignature--; } }g_SignatureInitializer; diff --git a/CPP/7zip/Archive/Chm/ChmIn.cpp b/CPP/7zip/Archive/Chm/ChmIn.cpp index 5e13f54b..1379b1fd 100755 --- a/CPP/7zip/Archive/Chm/ChmIn.cpp +++ b/CPP/7zip/Archive/Chm/ChmIn.cpp @@ -17,16 +17,16 @@ namespace NChm{ // define CHM_LOW, if you want to see low level items // #define CHM_LOW -static const GUID kChmLzxGuid = +static const GUID kChmLzxGuid = { 0x7FC28940, 0x9D31, 0x11D0, 0x9B, 0x27, 0x00, 0xA0, 0xC9, 0x1E, 0x9C, 0x7C }; -static const GUID kHelp2LzxGuid = +static const GUID kHelp2LzxGuid = { 0x0A9007C6, 0x4076, 0x11D3, 0x87, 0x89, 0x00, 0x00, 0xF8, 0x10, 0x57, 0x54 }; -static const GUID kDesGuid = +static const GUID kDesGuid = { 0x67F6E4A2, 0x60BF, 0x11D3, 0x85, 0x40, 0x00, 0xC0, 0x4F, 0x58, 0xC3, 0xCF }; static bool AreGuidsEqual(REFGUID g1, REFGUID g2) -{ - if (g1.Data1 != g2.Data1 || +{ + if (g1.Data1 != g2.Data1 || g1.Data2 != g2.Data2 || g1.Data3 != g2.Data3) return false; @@ -60,7 +60,7 @@ static void PrintUInt32(UInt32 v, AString &s) } AString CMethodInfo::GetGuidString() const -{ +{ AString s; s += '{'; PrintUInt32(Guid.Data1, s); @@ -278,9 +278,9 @@ HRESULT CInArchive::OpenChm(IInStream *inStream, CDatabase &database) if (unknown1 != 0 && unknown1 != 1) // it's 0 in one .sll file return S_FALSE; /* UInt32 timeStamp = */ ReadUInt32(); - // Considered as a big-endian DWORD, it appears to contain seconds (MSB) and - // fractional seconds (second byte). - // The third and fourth bytes may contain even more fractional bits. + // Considered as a big-endian DWORD, it appears to contain seconds (MSB) and + // fractional seconds (second byte). + // The third and fourth bytes may contain even more fractional bits. // The 4 least significant bits in the last byte are constant. /* UInt32 lang = */ ReadUInt32(); GUID g; @@ -326,12 +326,12 @@ HRESULT CInArchive::OpenChm(IInStream *inStream, CDatabase &database) if (dirChunkSize < 32) return S_FALSE; /* UInt32 density = */ ReadUInt32(); // "Density" of quickref section, usually 2. - /* UInt32 depth = */ ReadUInt32(); // Depth of the index tree: 1 there is no index, + /* UInt32 depth = */ ReadUInt32(); // Depth of the index tree: 1 there is no index, // 2 if there is one level of PMGI chunks. /* UInt32 chunkNumber = */ ReadUInt32(); // Chunk number of root index chunk, -1 if there is none - // (though at least one file has 0 despite there being no - // index chunk, probably a bug.) + // (though at least one file has 0 despite there being no + // index chunk, probably a bug.) /* UInt32 firstPmglChunkNumber = */ ReadUInt32(); // Chunk number of first PMGL (listing) chunk /* UInt32 lastPmglChunkNumber = */ ReadUInt32(); // Chunk number of last PMGL (listing) chunk ReadUInt32(); // -1 (unknown) @@ -348,11 +348,11 @@ HRESULT CInArchive::OpenChm(IInStream *inStream, CDatabase &database) UInt64 chunkPos = _inBuffer.GetProcessedSize(); if (ReadUInt32() == NHeader::kPmglSignature) { - // The quickref area is written backwards from the end of the chunk. - // One quickref entry exists for every n entries in the file, where n - // is calculated as 1 + (1 << quickref density). So for density = 2, n = 5. + // The quickref area is written backwards from the end of the chunk. + // One quickref entry exists for every n entries in the file, where n + // is calculated as 1 + (1 << quickref density). So for density = 2, n = 5. - UInt32 quickrefLength = ReadUInt32(); // Length of free space and/or quickref area at end of directory chunk + UInt32 quickrefLength = ReadUInt32(); // Length of free space and/or quickref area at end of directory chunk if (quickrefLength > dirChunkSize || quickrefLength < 2) return S_FALSE; ReadUInt32(); // Always 0 @@ -393,10 +393,10 @@ HRESULT CInArchive::OpenHelp2(IInStream *inStream, CDatabase &database) if (numHeaderSections != kNumHeaderSectionsMax) return S_FALSE; ReadUInt32(); // Length of post-header table - GUID g; + GUID g; ReadGUID(g); // {0A9007C1-4076-11D3-8789-0000F8105754} - // header section table + // header section table UInt64 sectionOffsets[kNumHeaderSectionsMax]; UInt64 sectionSizes[kNumHeaderSectionsMax]; UInt32 i; @@ -434,9 +434,9 @@ HRESULT CInArchive::OpenHelp2(IInStream *inStream, CDatabase &database) ReadUInt64(); // Number of directory index entries (same as number of AOLL // chunks in main directory) - // (The obvious guess for the following two fields, which recur in a number - // of places, is they are maximum sizes for the directory and directory index. - // However, I have seen no direct evidence that this is the case.) + // (The obvious guess for the following two fields, which recur in a number + // of places, is they are maximum sizes for the directory and directory index. + // However, I have seen no direct evidence that this is the case.) ReadUInt32(); // $100000 (Same as field following chunk size in directory) ReadUInt32(); // $20000 (Same as field following chunk size in directory index) @@ -480,8 +480,8 @@ HRESULT CInArchive::OpenHelp2(IInStream *inStream, CDatabase &database) if (unknown != 0 && unknown != 1) // = 0 for some HxW files, 1 in other cases; return S_FALSE; database.ContentOffset = _startPosition + ReadUInt64(); - /* UInt32 timeStamp = */ ReadUInt32(); - // A timestamp of some sort. + /* UInt32 timeStamp = */ ReadUInt32(); + // A timestamp of some sort. // Considered as a big-endian DWORD, it appears to contain // seconds (MSB) and fractional seconds (second byte). // The third and fourth bytes may contain even more fractional @@ -527,7 +527,7 @@ HRESULT CInArchive::OpenHelp2(IInStream *inStream, CDatabase &database) UInt32 quickrefLength = ReadUInt32(); // Length of quickref area at end of directory chunk if (quickrefLength > dirChunkSize || quickrefLength < 2) return S_FALSE; - ReadUInt64(); // Directory chunk number + ReadUInt64(); // Directory chunk number // This must match physical position in file, that is // the chunk size times the chunk number must be the // offset from the end of the directory header. @@ -625,8 +625,8 @@ static int CompareFiles(const int *p1, const int *p2, void *param) const CObjectVector<CItem> &items = *(const CObjectVector<CItem> *)param; const CItem &item1 = items[*p1]; const CItem &item2 = items[*p2]; - bool isDir1 = item1.IsDirectory(); - bool isDir2 = item2.IsDirectory(); + bool isDir1 = item1.IsDir(); + bool isDir2 = item2.IsDir(); if (isDir1 && !isDir2) return -1; if (isDir2) @@ -663,7 +663,7 @@ bool CFilesDatabase::Check() for(int i = 0; i < Indices.Size(); i++) { const CItem &item = Items[Indices[i]]; - if (item.Section == 0 || item.IsDirectory()) + if (item.Section == 0 || item.IsDir()) continue; if (item.Section != prevSection) { @@ -718,7 +718,7 @@ HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database) AString transformPrefix = sectionPrefix + kTransform; if (database.Help2Format) { - // Transform List + // Transform List RINOK(DecompressStream(inStream, database, transformPrefix + kTransformList)); if ((_chunkSize & 0xF) != 0) return S_FALSE; @@ -760,21 +760,21 @@ HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database) li.WindowSize = ReadUInt32(); li.CacheSize = ReadUInt32(); if ( - li.ResetInterval != 1 && - li.ResetInterval != 2 && - li.ResetInterval != 4 && - li.ResetInterval != 8 && - li.ResetInterval != 16 && - li.ResetInterval != 32 && + li.ResetInterval != 1 && + li.ResetInterval != 2 && + li.ResetInterval != 4 && + li.ResetInterval != 8 && + li.ResetInterval != 16 && + li.ResetInterval != 32 && li.ResetInterval != 64) return S_FALSE; if ( - li.WindowSize != 1 && - li.WindowSize != 2 && - li.WindowSize != 4 && - li.WindowSize != 8 && - li.WindowSize != 16 && - li.WindowSize != 32 && + li.WindowSize != 1 && + li.WindowSize != 2 && + li.WindowSize != 4 && + li.WindowSize != 8 && + li.WindowSize != 16 && + li.WindowSize != 32 && li.WindowSize != 64) return S_FALSE; numDWORDS -= 5; @@ -803,7 +803,7 @@ HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database) if (method.IsLzx()) { // ResetTable; - RINOK(DecompressStream(inStream, database, transformPrefix + + RINOK(DecompressStream(inStream, database, transformPrefix + method.GetGuidString() + kResetTable)); CResetTable &rt = method.LzxInfo.ResetTable; if (_chunkSize < 4) @@ -845,7 +845,7 @@ HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database) return database.Check() ? S_OK : S_FALSE; } -HRESULT CInArchive::Open2(IInStream *inStream, +HRESULT CInArchive::Open2(IInStream *inStream, const UInt64 *searchHeaderSizeLimit, CFilesDatabase &database) { @@ -864,6 +864,11 @@ HRESULT CInArchive::Open2(IInStream *inStream, const int kSignatureSize = 8; UInt64 hxsSignature = NHeader::GetHxsSignature(); UInt64 chmSignature = ((UInt64)chmVersion << 32)| NHeader::kItsfSignature; + UInt64 limit = 1 << 18; + if (searchHeaderSizeLimit) + if (limit > *searchHeaderSizeLimit) + limit = *searchHeaderSizeLimit; + for (;;) { Byte b; @@ -880,9 +885,8 @@ HRESULT CInArchive::Open2(IInStream *inStream, database.Help2Format = true; break; } - if (searchHeaderSizeLimit != NULL) - if (_inBuffer.GetProcessedSize() > (*searchHeaderSizeLimit)) - return S_FALSE; + if (_inBuffer.GetProcessedSize() > limit) + return S_FALSE; } } _startPosition += _inBuffer.GetProcessedSize() - kSignatureSize; @@ -919,7 +923,7 @@ HRESULT CInArchive::Open2(IInStream *inStream, return S_OK; } -HRESULT CInArchive::Open(IInStream *inStream, +HRESULT CInArchive::Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit, CFilesDatabase &database) { diff --git a/CPP/7zip/Archive/Chm/ChmIn.h b/CPP/7zip/Archive/Chm/ChmIn.h index e677c618..943336cb 100755 --- a/CPP/7zip/Archive/Chm/ChmIn.h +++ b/CPP/7zip/Archive/Chm/ChmIn.h @@ -19,21 +19,21 @@ struct CItem UInt64 Size; AString Name; - bool IsFormatRelatedItem() const + bool IsFormatRelatedItem() const { if (Name.Length() < 2) return false; return Name[0] == ':' && Name[1] == ':'; } - bool IsUserItem() const + bool IsUserItem() const { if (Name.Length() < 2) return false; return Name[0] == '/'; } - bool IsDirectory() const + bool IsDir() const { if (Name.Length() == 0) return false; @@ -57,12 +57,12 @@ struct CDatabase return -1; } - void Clear() - { + void Clear() + { NewFormat = false; NewFormatString.Empty(); Help2Format = false; - Items.Clear(); + Items.Clear(); } }; @@ -72,7 +72,7 @@ struct CResetTable UInt64 CompressedSize; UInt64 BlockSize; CRecordVector<UInt64> ResetOffsets; - bool GetCompressedSizeOfBlocks(UInt64 blockIndex, UInt32 numBlocks, UInt64 &size) const + bool GetCompressedSizeOfBlocks(UInt64 blockIndex, UInt32 numBlocks, UInt64 &size) const { if (blockIndex >= ResetOffsets.Size()) return false; @@ -83,11 +83,11 @@ struct CResetTable size = ResetOffsets[(int)(blockIndex + numBlocks)] - startPos; return true; } - bool GetCompressedSizeOfBlock(UInt64 blockIndex, UInt64 &size) const + bool GetCompressedSizeOfBlock(UInt64 blockIndex, UInt64 &size) const { return GetCompressedSizeOfBlocks(blockIndex, 1, size); } - UInt64 GetNumBlocks(UInt64 size) const + UInt64 GetNumBlocks(UInt64 size) const { return (size + BlockSize - 1) / BlockSize; } @@ -116,16 +116,16 @@ struct CLzxInfo UInt64 GetFolder(UInt64 offset) const { return offset / GetFolderSize(); }; UInt64 GetFolderPos(UInt64 folderIndex) const { return folderIndex * GetFolderSize(); }; UInt64 GetBlockIndexFromFolderIndex(UInt64 folderIndex) const { return folderIndex * ResetInterval; }; - bool GetOffsetOfFolder(UInt64 folderIndex, UInt64 &offset) const - { + bool GetOffsetOfFolder(UInt64 folderIndex, UInt64 &offset) const + { UInt64 blockIndex = GetBlockIndexFromFolderIndex(folderIndex); if (blockIndex >= ResetTable.ResetOffsets.Size()) return false; offset = ResetTable.ResetOffsets[(int)blockIndex]; return true; } - bool GetCompressedSizeOfFolder(UInt64 folderIndex, UInt64 &size) const - { + bool GetCompressedSizeOfFolder(UInt64 folderIndex, UInt64 &size) const + { UInt64 blockIndex = GetBlockIndexFromFolderIndex(folderIndex); return ResetTable.GetCompressedSizeOfBlocks(blockIndex, ResetInterval, size); } @@ -165,8 +165,8 @@ public: UInt64 GetFileSize(int fileIndex) const { return Items[Indices[fileIndex]].Size; } UInt64 GetFileOffset(int fileIndex) const { return Items[Indices[fileIndex]].Offset; } - UInt64 GetFolder(int fileIndex) const - { + UInt64 GetFolder(int fileIndex) const + { const CItem &item = Items[Indices[fileIndex]]; const CSectionInfo §ion = Sections[(int)item.Section]; if (section.IsLzx()) @@ -174,8 +174,8 @@ public: return 0; } - UInt64 GetLastFolder(int fileIndex) const - { + UInt64 GetLastFolder(int fileIndex) const + { const CItem &item = Items[Indices[fileIndex]]; const CSectionInfo §ion = Sections[(int)item.Section]; if (section.IsLzx()) @@ -183,16 +183,16 @@ public: return 0; } - void HighLevelClear() - { + void HighLevelClear() + { LowLevel = true; - Indices.Clear(); - Sections.Clear(); + Indices.Clear(); + Sections.Clear(); } - void Clear() - { - CDatabase::Clear(); + void Clear() + { + CDatabase::Clear(); HighLevelClear(); } void SetIndices(); diff --git a/CPP/7zip/Archive/Chm/StdAfx.cpp b/CPP/7zip/Archive/Chm/StdAfx.cpp deleted file mode 100755 index d0feea85..00000000 --- a/CPP/7zip/Archive/Chm/StdAfx.cpp +++ /dev/null @@ -1,3 +0,0 @@ -// StdAfx.cpp - -#include "StdAfx.h" diff --git a/CPP/7zip/Archive/Com/ComHandler.cpp b/CPP/7zip/Archive/Com/ComHandler.cpp index 2255c021..8b46976c 100755 --- a/CPP/7zip/Archive/Com/ComHandler.cpp +++ b/CPP/7zip/Archive/Com/ComHandler.cpp @@ -10,19 +10,19 @@ namespace NArchive { namespace NCom { -STATPROPSTG kProps[] = +STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, - { NULL, kpidIsFolder, VT_BOOL}, + { NULL, kpidIsDir, VT_BOOL}, { NULL, kpidSize, VT_UI8}, // { NULL, kpidAttributes, VT_UI4}, - { NULL, kpidPackedSize, VT_UI8}, - { NULL, kpidCreationTime, VT_FILETIME}, - { NULL, kpidLastWriteTime, VT_FILETIME} + { NULL, kpidPackSize, VT_UI8}, + { NULL, kpidCTime, VT_FILETIME}, + { NULL, kpidMTime, VT_FILETIME} }; -STATPROPSTG kArcProps[] = +STATPROPSTG kArcProps[] = { { NULL, kpidClusterSize, VT_UI4} }; @@ -58,25 +58,19 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val prop = name; break; } - case kpidIsFolder: - prop = item.IsDir(); - break; - case kpidCreationTime: - prop = item.CreationTime; - break; - case kpidLastWriteTime: - prop = item.LastWriteTime; - break; + case kpidIsDir: prop = item.IsDir(); break; + case kpidCTime: prop = item.CTime; break; + case kpidMTime: prop = item.MTime; break; /* case kpidAttributes: prop = item.Falgs; break; */ - case kpidPackedSize: + case kpidPackSize: if (!item.IsDir()) { - int numBits = _db.IsLargeStream(item.Size) ? - _db.SectorSizeBits : + int numBits = _db.IsLargeStream(item.Size) ? + _db.SectorSizeBits : _db.MiniSectorSizeBits; prop = (item.Size + ((UInt64)1 << numBits) - 1) >> numBits << numBits; break; @@ -91,7 +85,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val COM_TRY_END } -STDMETHODIMP CHandler::Open(IInStream *inStream, +STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 * /* maxCheckStartPosition */, IArchiveOpenCallback * /* openArchiveCallback */) { @@ -150,7 +144,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, currentItemSize = item.Size; CMyComPtr<ISequentialOutStream> realOutStream; - Int32 askMode = testMode ? + Int32 askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); @@ -204,7 +198,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, if (fid >= _db.NumSectorsInMiniStream) break; size = 1 << _db.MiniSectorSizeBits; - offset = (((UInt64)_db.MiniSids[fid] + 1) << _db.SectorSizeBits) + + offset = (((UInt64)_db.MiniSids[fid] + 1) << _db.SectorSizeBits) + ((sid & ((1 << subBits) - 1)) << _db.MiniSectorSizeBits); if (sid >= _db.MatSize) break; diff --git a/CPP/7zip/Archive/Com/ComHandler.h b/CPP/7zip/Archive/Com/ComHandler.h index f8b2b135..89bc98d0 100755 --- a/CPP/7zip/Archive/Com/ComHandler.h +++ b/CPP/7zip/Archive/Com/ComHandler.h @@ -10,7 +10,7 @@ namespace NArchive { namespace NCom { -class CHandler: +class CHandler: public IInArchive, public CMyUnknownImp { diff --git a/CPP/7zip/Archive/Com/ComIn.cpp b/CPP/7zip/Archive/Com/ComIn.cpp index b8dfdb81..74e601c1 100755 --- a/CPP/7zip/Archive/Com/ComIn.cpp +++ b/CPP/7zip/Archive/Com/ComIn.cpp @@ -2,8 +2,8 @@ #include "StdAfx.h" -extern "C" -{ +extern "C" +{ #include "../../../../C/Alloc.h" } @@ -69,8 +69,8 @@ static void ReadItem(Byte *p, CItem &item, bool mode64bit) item.RightDid = GetUi32(p + 72); item.SonDid = GetUi32(p + 76); // item.Flags = GetUi32(p + 96); - GetFileTimeFromMem(p + 100, &item.CreationTime); - GetFileTimeFromMem(p + 108, &item.LastWriteTime); + GetFileTimeFromMem(p + 100, &item.CTime); + GetFileTimeFromMem(p + 108, &item.MTime); item.Sid = GetUi32(p + 116); item.Size = GetUi32(p + 120); if (mode64bit) @@ -127,7 +127,7 @@ static UString CompoundNameToFileName(const UString &s) } else res += c; - } + } return res; } @@ -219,7 +219,7 @@ HRESULT OpenArchive(IInStream *inStream, CDatabase &db) db.SectorSizeBits = sectorSizeBits; db.MiniSectorSizeBits = miniSectorSizeBits; - if (sectorSizeBits > 28 || miniSectorSizeBits > 28 || + if (sectorSizeBits > 28 || miniSectorSizeBits > 28 || sectorSizeBits < 7 || miniSectorSizeBits < 2 || miniSectorSizeBits > sectorSizeBits) return S_FALSE; UInt32 numSectorsForFAT = GetUi32(p + 0x2C); diff --git a/CPP/7zip/Archive/Com/ComIn.h b/CPP/7zip/Archive/Com/ComIn.h index 683e61dc..081c6aaa 100755 --- a/CPP/7zip/Archive/Com/ComIn.h +++ b/CPP/7zip/Archive/Com/ComIn.h @@ -46,8 +46,8 @@ struct CItem Byte Name[kNameSizeMax]; // UInt16 NameSize; // UInt32 Flags; - FILETIME CreationTime; - FILETIME LastWriteTime; + FILETIME CTime; + FILETIME MTime; UInt64 Size; UInt32 LeftDid; UInt32 RightDid; diff --git a/CPP/7zip/Archive/Common/CoderMixer.cpp b/CPP/7zip/Archive/Common/CoderMixer.cpp index db626fe1..a19f0457 100755 --- a/CPP/7zip/Archive/Common/CoderMixer.cpp +++ b/CPP/7zip/Archive/Common/CoderMixer.cpp @@ -16,4 +16,4 @@ void CCoderInfo::SetCoderInfo(const UInt64 *inSize, const UInt64 *outSize) OutSizeValue = *outSize; } -} +} diff --git a/CPP/7zip/Archive/Common/CoderMixer2.cpp b/CPP/7zip/Archive/Common/CoderMixer2.cpp index d11e9e60..aed94f9c 100755 --- a/CPP/7zip/Archive/Common/CoderMixer2.cpp +++ b/CPP/7zip/Archive/Common/CoderMixer2.cpp @@ -81,7 +81,7 @@ void CBindReverseConverter::CreateReverseBindInfo(CBindInfo &destBindInfo) destBindInfo.InStreams.Add(_srcOutToDestInMap[_srcBindInfo.OutStreams[i]]); } -CCoderInfo2::CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams): +CCoderInfo2::CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams): NumInStreams(numInStreams), NumOutStreams(numOutStreams) { @@ -91,7 +91,7 @@ CCoderInfo2::CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams): OutSizePointers.Reserve(NumOutStreams); } -static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes, +static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes, CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems) { sizes.Clear(); @@ -118,4 +118,4 @@ void CCoderInfo2::SetCoderInfo(const UInt64 **inSizes, SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams); } -} +} diff --git a/CPP/7zip/Archive/Common/CoderMixer2.h b/CPP/7zip/Archive/Common/CoderMixer2.h index be68c680..a03722d6 100755 --- a/CPP/7zip/Archive/Common/CoderMixer2.h +++ b/CPP/7zip/Archive/Common/CoderMixer2.h @@ -92,7 +92,7 @@ struct CBindInfo } - void FindInStream(UInt32 streamIndex, UInt32 &coderIndex, + void FindInStream(UInt32 streamIndex, UInt32 &coderIndex, UInt32 &coderStreamIndex) const { for (coderIndex = 0; coderIndex < (UInt32)Coders.Size(); coderIndex++) @@ -107,7 +107,7 @@ struct CBindInfo } throw 1; } - void FindOutStream(UInt32 streamIndex, UInt32 &coderIndex, + void FindOutStream(UInt32 streamIndex, UInt32 &coderIndex, UInt32 &coderStreamIndex) const { for (coderIndex = 0; coderIndex < (UInt32)Coders.Size(); coderIndex++) diff --git a/CPP/7zip/Archive/Common/CoderMixer2MT.cpp b/CPP/7zip/Archive/Common/CoderMixer2MT.cpp index e1030976..1265dfcd 100755 --- a/CPP/7zip/Archive/Common/CoderMixer2MT.cpp +++ b/CPP/7zip/Archive/Common/CoderMixer2MT.cpp @@ -6,7 +6,7 @@ namespace NCoderMixer { -CCoder2::CCoder2(UInt32 numInStreams, UInt32 numOutStreams): +CCoder2::CCoder2(UInt32 numInStreams, UInt32 numOutStreams): CCoderInfo2(numInStreams, numOutStreams) { InStreams.Reserve(NumInStreams); @@ -35,7 +35,7 @@ void CCoder2::Code(ICompressProgressInfo *progress) OutStreamPointers.Add((ISequentialOutStream *)OutStreams[i]); } if (Coder) - Result = Coder->Code(InStreamPointers[0], OutStreamPointers[0], + Result = Coder->Code(InStreamPointers[0], OutStreamPointers[0], InSizePointers[0], OutSizePointers[0], progress); else Result = Coder2->Code(&InStreamPointers.Front(), &InSizePointers.Front(), NumInStreams, @@ -49,7 +49,7 @@ void CCoder2::Code(ICompressProgressInfo *progress) } } -static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes, +static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes, CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems) { sizes.Clear(); @@ -80,8 +80,8 @@ void CCoder2::SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes) // CCoderMixer2MT HRESULT CCoderMixer2MT::SetBindInfo(const CBindInfo &bindInfo) -{ - _bindInfo = bindInfo; +{ + _bindInfo = bindInfo; _streamBinders.Clear(); for(int i = 0; i < _bindInfo.BindPairs.Size(); i++) { @@ -118,7 +118,7 @@ void CCoderMixer2MT::ReInit() } -HRESULT CCoderMixer2MT::Init(ISequentialInStream **inStreams, ISequentialOutStream **outStreams) +HRESULT CCoderMixer2MT::Init(ISequentialInStream **inStreams, ISequentialOutStream **outStreams) { /* if (_coders.Size() != _bindInfo.Coders.Size()) @@ -176,9 +176,9 @@ HRESULT CCoderMixer2MT::ReturnIfError(HRESULT code) } STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams, - const UInt64 ** /* inSizes */, + const UInt64 ** /* inSizes */, UInt32 numInStreams, - ISequentialOutStream **outStreams, + ISequentialOutStream **outStreams, const UInt64 ** /* outSizes */, UInt32 numOutStreams, ICompressProgressInfo *progress) @@ -227,4 +227,4 @@ STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams, return S_OK; } -} +} diff --git a/CPP/7zip/Archive/Common/CoderMixer2MT.h b/CPP/7zip/Archive/Common/CoderMixer2MT.h index 505f1a88..d1c7f4d0 100755 --- a/CPP/7zip/Archive/Common/CoderMixer2MT.h +++ b/CPP/7zip/Archive/Common/CoderMixer2MT.h @@ -35,7 +35,7 @@ struct CCoder2: public CCoderInfo2, public CVirtThread { ReInit() for each coder - SetCoderInfo + SetCoderInfo Code } */ @@ -57,9 +57,9 @@ public: MY_UNKNOWN_IMP STDMETHOD(Code)(ISequentialInStream **inStreams, - const UInt64 **inSizes, + const UInt64 **inSizes, UInt32 numInStreams, - ISequentialOutStream **outStreams, + ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams, ICompressProgressInfo *progress); diff --git a/CPP/7zip/Archive/Common/CoderMixer2ST.cpp b/CPP/7zip/Archive/Common/CoderMixer2ST.cpp index 6bcab0dd..a59ce5fc 100755 --- a/CPP/7zip/Archive/Common/CoderMixer2ST.cpp +++ b/CPP/7zip/Archive/Common/CoderMixer2ST.cpp @@ -11,9 +11,9 @@ CCoderMixer2ST::CCoderMixer2ST() {} CCoderMixer2ST::~CCoderMixer2ST(){ } HRESULT CCoderMixer2ST::SetBindInfo(const CBindInfo &bindInfo) -{ - _bindInfo = bindInfo; - return S_OK; +{ + _bindInfo = bindInfo; + return S_OK; } void CCoderMixer2ST::AddCoderCommon(bool isMain) @@ -37,7 +37,7 @@ void CCoderMixer2ST::AddCoder2(ICompressCoder2 *coder, bool isMain) void CCoderMixer2ST::ReInit() { } HRESULT CCoderMixer2ST::GetInStream( - ISequentialInStream **inStreams, const UInt64 **inSizes, + ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 streamIndex, ISequentialInStream **inStreamRes) { CMyComPtr<ISequentialInStream> seqInStream; @@ -54,7 +54,7 @@ HRESULT CCoderMixer2ST::GetInStream( return E_INVALIDARG; UInt32 coderIndex, coderStreamIndex; - _bindInfo.FindOutStream(_bindInfo.BindPairs[binderIndex].OutIndex, + _bindInfo.FindOutStream(_bindInfo.BindPairs[binderIndex].OutIndex, coderIndex, coderStreamIndex); CCoderInfo &coder = _coders[coderIndex]; @@ -86,7 +86,7 @@ HRESULT CCoderMixer2ST::GetInStream( } HRESULT CCoderMixer2ST::GetOutStream( - ISequentialOutStream **outStreams, const UInt64 **outSizes, + ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 streamIndex, ISequentialOutStream **outStreamRes) { CMyComPtr<ISequentialOutStream> seqOutStream; @@ -103,7 +103,7 @@ HRESULT CCoderMixer2ST::GetOutStream( return E_INVALIDARG; UInt32 coderIndex, coderStreamIndex; - _bindInfo.FindInStream(_bindInfo.BindPairs[binderIndex].InIndex, + _bindInfo.FindInStream(_bindInfo.BindPairs[binderIndex].InIndex, coderIndex, coderStreamIndex); CCoderInfo &coder = _coders[coderIndex]; @@ -136,9 +136,9 @@ HRESULT CCoderMixer2ST::GetOutStream( STDMETHODIMP CCoderMixer2ST::Code(ISequentialInStream **inStreams, - const UInt64 **inSizes, + const UInt64 **inSizes, UInt32 numInStreams, - ISequentialOutStream **outStreams, + ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams, ICompressProgressInfo *progress) @@ -216,9 +216,9 @@ STDMETHODIMP CCoderMixer2ST::Code(ISequentialInStream **inStreams, else { RINOK(mainCoder.Coder2->Code( - &seqInStreamsSpec.Front(), + &seqInStreamsSpec.Front(), &mainCoder.InSizePointers.Front(), mainCoder.NumInStreams, - &seqOutStreamsSpec.Front(), + &seqOutStreamsSpec.Front(), &mainCoder.OutSizePointers.Front(), mainCoder.NumOutStreams, progress)); } @@ -236,4 +236,4 @@ UInt64 CCoderMixer2ST::GetWriteProcessedSize(UInt32 binderIndex) const } */ -} +} diff --git a/CPP/7zip/Archive/Common/CoderMixer2ST.h b/CPP/7zip/Archive/Common/CoderMixer2ST.h index ea5a53e3..a4ea7e80 100755 --- a/CPP/7zip/Archive/Common/CoderMixer2ST.h +++ b/CPP/7zip/Archive/Common/CoderMixer2ST.h @@ -14,13 +14,13 @@ namespace NCoderMixer2 { // { // AddCoder[2]() // } -// +// // for each file // { // ReInit() // for each coder // { -// SetCoderInfo +// SetCoderInfo // } // SetProgressIndex(UInt32 coderIndex); // Code @@ -41,16 +41,16 @@ class CCoderMixer2ST: MY_UNKNOWN_IMP HRESULT GetInStream( - ISequentialInStream **inStreams, const UInt64 **inSizes, + ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 streamIndex, ISequentialInStream **inStreamRes); HRESULT GetOutStream( - ISequentialOutStream **outStreams, const UInt64 **outSizes, + ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 streamIndex, ISequentialOutStream **outStreamRes); public: STDMETHOD(Code)(ISequentialInStream **inStreams, - const UInt64 **inSizes, + const UInt64 **inSizes, UInt32 numInStreams, - ISequentialOutStream **outStreams, + ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams, ICompressProgressInfo *progress); @@ -63,13 +63,13 @@ public: void ReInit(); void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes) - { + { { _coders[coderIndex].SetCoderInfo(inSizes, outSizes); } } void SetProgressCoderIndex(UInt32 /*coderIndex*/) - { - // _progressCoderIndex = coderIndex; + { + // _progressCoderIndex = coderIndex; } // UInt64 GetWriteProcessedSize(UInt32 binderIndex) const; diff --git a/CPP/7zip/Archive/Common/CoderMixerMT.cpp b/CPP/7zip/Archive/Common/CoderMixerMT.cpp index 85cf0a52..f43d1612 100755 --- a/CPP/7zip/Archive/Common/CoderMixerMT.cpp +++ b/CPP/7zip/Archive/Common/CoderMixerMT.cpp @@ -10,9 +10,9 @@ void CCoder::Execute() { Code(NULL); } void CCoder::Code(ICompressProgressInfo *progress) { - Result = Coder->Code(InStream, OutStream, - InSizeAssigned ? &InSizeValue : NULL, - OutSizeAssigned ? &OutSizeValue : NULL, + Result = Coder->Code(InStream, OutStream, + InSizeAssigned ? &InSizeValue : NULL, + OutSizeAssigned ? &OutSizeValue : NULL, progress); InStream.Release(); OutStream.Release(); @@ -39,7 +39,7 @@ HRESULT CCoderMixerMT::ReturnIfError(HRESULT code) } STDMETHODIMP CCoderMixerMT::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, + ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) { @@ -96,4 +96,4 @@ STDMETHODIMP CCoderMixerMT::Code(ISequentialInStream *inStream, return S_OK; } -} +} diff --git a/CPP/7zip/Archive/Common/CoderMixerMT.h b/CPP/7zip/Archive/Common/CoderMixerMT.h index 6fd1ba44..c70e1829 100755 --- a/CPP/7zip/Archive/Common/CoderMixerMT.h +++ b/CPP/7zip/Archive/Common/CoderMixerMT.h @@ -29,7 +29,7 @@ struct CCoder: public CCoderInfo, public CVirtThread { ReInit() for each coder - SetCoderInfo + SetCoderInfo Code } */ @@ -48,7 +48,7 @@ public: MY_UNKNOWN_IMP STDMETHOD(Code)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); diff --git a/CPP/7zip/Archive/Common/CrossThreadProgress.h b/CPP/7zip/Archive/Common/CrossThreadProgress.h index b5422a31..7e0b1053 100755 --- a/CPP/7zip/Archive/Common/CrossThreadProgress.h +++ b/CPP/7zip/Archive/Common/CrossThreadProgress.h @@ -7,7 +7,7 @@ #include "../../../Windows/Synchronization.h" #include "../../../Common/MyCom.h" -class CCrossThreadProgress: +class CCrossThreadProgress: public ICompressProgressInfo, public CMyUnknownImp { diff --git a/CPP/7zip/Archive/Common/DummyOutStream.h b/CPP/7zip/Archive/Common/DummyOutStream.h index d19b3111..13d5b62c 100755 --- a/CPP/7zip/Archive/Common/DummyOutStream.h +++ b/CPP/7zip/Archive/Common/DummyOutStream.h @@ -6,7 +6,7 @@ #include "../../IStream.h" #include "Common/MyCom.h" -class CDummyOutStream: +class CDummyOutStream: public ISequentialOutStream, public CMyUnknownImp { @@ -14,6 +14,7 @@ class CDummyOutStream: UInt64 _size; public: void SetStream(ISequentialOutStream *outStream) { _stream = outStream; } + void ReleaseStream() { _stream.Release(); } void Init() { _size = 0; } MY_UNKNOWN_IMP STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); diff --git a/CPP/7zip/Archive/Common/FindSignature.cpp b/CPP/7zip/Archive/Common/FindSignature.cpp new file mode 100755 index 00000000..15aa6cea --- /dev/null +++ b/CPP/7zip/Archive/Common/FindSignature.cpp @@ -0,0 +1,62 @@ +// FindSignature.cpp + +#include "StdAfx.h" + +#include "Common/Buffer.h" + +#include "FindSignature.h" + +#include "../../Common/StreamUtils.h" + +HRESULT FindSignatureInStream(ISequentialInStream *stream, + const Byte *signature, unsigned signatureSize, + const UInt64 *limit, UInt64 &resPos) +{ + resPos = 0; + CByteBuffer byteBuffer2; + byteBuffer2.SetCapacity(signatureSize); + RINOK(ReadStream_FALSE(stream, byteBuffer2, signatureSize)); + + if (memcmp(byteBuffer2, signature, signatureSize) == 0) + return S_OK; + + const UInt32 kBufferSize = (1 << 16); + CByteBuffer byteBuffer; + byteBuffer.SetCapacity(kBufferSize); + Byte *buffer = byteBuffer; + UInt32 numPrevBytes = signatureSize - 1; + memcpy(buffer, (const Byte *)byteBuffer2 + 1, numPrevBytes); + resPos = 1; + for (;;) + { + if (limit != NULL) + if (resPos > *limit) + return S_FALSE; + do + { + UInt32 numReadBytes = kBufferSize - numPrevBytes; + UInt32 processedSize; + RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize)); + numPrevBytes += processedSize; + if (processedSize == 0) + return S_FALSE; + } + while (numPrevBytes < signatureSize); + UInt32 numTests = numPrevBytes - signatureSize + 1; + for (UInt32 pos = 0; pos < numTests; pos++) + { + Byte b = signature[0]; + for (; buffer[pos] != b && pos < numTests; pos++); + if (pos == numTests) + break; + if (memcmp(buffer + pos, signature, signatureSize) == 0) + { + resPos += pos; + return S_OK; + } + } + resPos += numTests; + numPrevBytes -= numTests; + memmove(buffer, buffer + numTests, numPrevBytes); + } +} diff --git a/CPP/7zip/Archive/Common/FindSignature.h b/CPP/7zip/Archive/Common/FindSignature.h new file mode 100755 index 00000000..e15af573 --- /dev/null +++ b/CPP/7zip/Archive/Common/FindSignature.h @@ -0,0 +1,12 @@ +// FindSignature.h + +#ifndef __FINDSIGNATURE_H +#define __FINDSIGNATURE_H + +#include "../../IStream.h" + +HRESULT FindSignatureInStream(ISequentialInStream *stream, + const Byte *signature, unsigned signatureSize, + const UInt64 *limit, UInt64 &resPos); + +#endif diff --git a/CPP/7zip/Archive/Common/HandlerOut.cpp b/CPP/7zip/Archive/Common/HandlerOut.cpp index 082a484d..63899fe4 100755 --- a/CPP/7zip/Archive/Common/HandlerOut.cpp +++ b/CPP/7zip/Archive/Common/HandlerOut.cpp @@ -79,10 +79,10 @@ static bool AreEqual(const UString &methodName, const wchar_t *s) { return (methodName.CompareNoCase(s) == 0); } static inline bool IsLZMAMethod(const UString &methodName) -{ - return - AreEqual(methodName, kLZMAMethodName) || - AreEqual(methodName, kLZMA2MethodName); +{ + return + AreEqual(methodName, kLZMAMethodName) || + AreEqual(methodName, kLZMA2MethodName); } static inline bool IsBZip2Method(const UString &methodName) @@ -92,10 +92,10 @@ static inline bool IsPpmdMethod(const UString &methodName) { return AreEqual(methodName, kPpmdMethodName); } static inline bool IsDeflateMethod(const UString &methodName) -{ - return - AreEqual(methodName, kDeflateMethodName) || - AreEqual(methodName, kDeflate64MethodName); +{ + return + AreEqual(methodName, kDeflateMethodName) || + AreEqual(methodName, kDeflate64MethodName); } struct CNameToPropID @@ -105,7 +105,7 @@ struct CNameToPropID const wchar_t *Name; }; -CNameToPropID g_NameToPropID[] = +CNameToPropID g_NameToPropID[] = { { NCoderPropID::kOrder, VT_UI4, L"O" }, { NCoderPropID::kPosStateBits, VT_UI4, L"PB" }, @@ -158,7 +158,7 @@ static int FindPropIdFromStringName(const UString &name) return -1; } -static void SetOneMethodProp(COneMethodInfo &oneMethodInfo, PROPID propID, +static void SetOneMethodProp(COneMethodInfo &oneMethodInfo, PROPID propID, const NWindows::NCOM::CPropVariant &value) { for (int j = 0; j < oneMethodInfo.Properties.Size(); j++) @@ -182,24 +182,24 @@ void COutHandler::SetCompressionMethod2(COneMethodInfo &oneMethodInfo if (IsLZMAMethod(oneMethodInfo.MethodName)) { - UInt32 dicSize = - (level >= 9 ? kLzmaDicSizeX9 : - (level >= 7 ? kLzmaDicSizeX7 : - (level >= 5 ? kLzmaDicSizeX5 : - (level >= 3 ? kLzmaDicSizeX3 : - kLzmaDicSizeX1)))); + UInt32 dicSize = + (level >= 9 ? kLzmaDicSizeX9 : + (level >= 7 ? kLzmaDicSizeX7 : + (level >= 5 ? kLzmaDicSizeX5 : + (level >= 3 ? kLzmaDicSizeX3 : + kLzmaDicSizeX1)))); - UInt32 algo = - (level >= 5 ? kLzmaAlgoX5 : - kLzmaAlgoX1); + UInt32 algo = + (level >= 5 ? kLzmaAlgoX5 : + kLzmaAlgoX1); - UInt32 fastBytes = - (level >= 7 ? kLzmaFastBytesX7 : - kLzmaFastBytesX1); + UInt32 fastBytes = + (level >= 7 ? kLzmaFastBytesX7 : + kLzmaFastBytesX1); - const wchar_t *matchFinder = - (level >= 5 ? kLzmaMatchFinderX5 : - kLzmaMatchFinderX1); + const wchar_t *matchFinder = + (level >= 5 ? kLzmaMatchFinderX5 : + kLzmaMatchFinderX1); SetOneMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize); SetOneMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algo); @@ -211,19 +211,19 @@ void COutHandler::SetCompressionMethod2(COneMethodInfo &oneMethodInfo } else if (IsDeflateMethod(oneMethodInfo.MethodName)) { - UInt32 fastBytes = - (level >= 9 ? kDeflateFastBytesX9 : - (level >= 7 ? kDeflateFastBytesX7 : + UInt32 fastBytes = + (level >= 9 ? kDeflateFastBytesX9 : + (level >= 7 ? kDeflateFastBytesX7 : kDeflateFastBytesX1)); - UInt32 numPasses = - (level >= 9 ? kDeflatePassesX9 : - (level >= 7 ? kDeflatePassesX7 : + UInt32 numPasses = + (level >= 9 ? kDeflatePassesX9 : + (level >= 7 ? kDeflatePassesX7 : kDeflatePassesX1)); - UInt32 algo = - (level >= 5 ? kDeflateAlgoX5 : - kDeflateAlgoX1); + UInt32 algo = + (level >= 5 ? kDeflateAlgoX5 : + kDeflateAlgoX1); SetOneMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algo); SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes); @@ -231,14 +231,14 @@ void COutHandler::SetCompressionMethod2(COneMethodInfo &oneMethodInfo } else if (IsBZip2Method(oneMethodInfo.MethodName)) { - UInt32 numPasses = - (level >= 9 ? kBZip2NumPassesX9 : - (level >= 7 ? kBZip2NumPassesX7 : + UInt32 numPasses = + (level >= 9 ? kBZip2NumPassesX9 : + (level >= 7 ? kBZip2NumPassesX7 : kBZip2NumPassesX1)); - UInt32 dicSize = - (level >= 5 ? kBZip2DicSizeX5 : - (level >= 3 ? kBZip2DicSizeX3 : + UInt32 dicSize = + (level >= 5 ? kBZip2DicSizeX5 : + (level >= 3 ? kBZip2DicSizeX3 : kBZip2DicSizeX1)); SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses); @@ -249,16 +249,16 @@ void COutHandler::SetCompressionMethod2(COneMethodInfo &oneMethodInfo } else if (IsPpmdMethod(oneMethodInfo.MethodName)) { - UInt32 useMemSize = - (level >= 9 ? kPpmdMemSizeX9 : - (level >= 7 ? kPpmdMemSizeX7 : - (level >= 5 ? kPpmdMemSizeX5 : + UInt32 useMemSize = + (level >= 9 ? kPpmdMemSizeX9 : + (level >= 7 ? kPpmdMemSizeX7 : + (level >= 5 ? kPpmdMemSizeX5 : kPpmdMemSizeX1))); - UInt32 order = - (level >= 9 ? kPpmdOrderX9 : - (level >= 7 ? kPpmdOrderX7 : - (level >= 5 ? kPpmdOrderX5 : + UInt32 order = + (level >= 9 ? kPpmdOrderX9 : + (level >= 7 ? kPpmdOrderX7 : + (level >= 5 ? kPpmdOrderX5 : kPpmdOrderX1))); SetOneMethodProp(oneMethodInfo, NCoderPropID::kUsedMemorySize, useMemSize); @@ -313,7 +313,7 @@ HRESULT COutHandler::SetParam(COneMethodInfo &oneMethodInfo, const UString &name { CProp property; if ( - name.CompareNoCase(L"D") == 0 || + name.CompareNoCase(L"D") == 0 || name.CompareNoCase(L"MEM") == 0) { UInt32 dicSize; @@ -457,11 +457,12 @@ void COutHandler::Init() { _removeSfxBlock = false; _compressHeaders = true; + _encryptHeadersSpecified = false; _encryptHeaders = false; - WriteModified = true; - WriteCreated = false; - WriteAccessed = false; + WriteCTime = false; + WriteATime = false; + WriteMTime = true; #ifdef COMPRESS_MT _numThreads = NWindows::NSystem::GetNumberOfProcessors(); @@ -530,12 +531,9 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val #endif return S_OK; } - if (name.CompareNoCase(L"RSFX") == 0) - return SetBoolProperty(_removeSfxBlock, value); - if (name.CompareNoCase(L"F") == 0) - return SetBoolProperty(_autoFilter, value); - if (name.CompareNoCase(L"HC") == 0) - return SetBoolProperty(_compressHeaders, value); + if (name.CompareNoCase(L"RSFX") == 0) return SetBoolProperty(_removeSfxBlock, value); + if (name.CompareNoCase(L"F") == 0) return SetBoolProperty(_autoFilter, value); + if (name.CompareNoCase(L"HC") == 0) return SetBoolProperty(_compressHeaders, value); if (name.CompareNoCase(L"HCF") == 0) { bool compressHeadersFull = true; @@ -545,15 +543,15 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val return S_OK; } if (name.CompareNoCase(L"HE") == 0) - return SetBoolProperty(_encryptHeaders, value); - if (name.CompareNoCase(L"TM") == 0) - return SetBoolProperty(WriteModified, value); - if (name.CompareNoCase(L"TC") == 0) - return SetBoolProperty(WriteCreated, value); - if (name.CompareNoCase(L"TA") == 0) - return SetBoolProperty(WriteAccessed, value); - if (name.CompareNoCase(L"V") == 0) - return SetBoolProperty(_volumeMode, value); + { + RINOK(SetBoolProperty(_encryptHeaders, value)); + _encryptHeadersSpecified = true; + return S_OK; + } + if (name.CompareNoCase(L"TC") == 0) return SetBoolProperty(WriteCTime, value); + if (name.CompareNoCase(L"TA") == 0) return SetBoolProperty(WriteATime, value); + if (name.CompareNoCase(L"TM") == 0) return SetBoolProperty(WriteMTime, value); + if (name.CompareNoCase(L"V") == 0) return SetBoolProperty(_volumeMode, value); number = 0; } if (number > 10000) @@ -623,6 +621,6 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val } } return S_OK; -} +} } diff --git a/CPP/7zip/Archive/Common/HandlerOut.h b/CPP/7zip/Archive/Common/HandlerOut.h index ab925cc3..b6095a6b 100755 --- a/CPP/7zip/Archive/Common/HandlerOut.h +++ b/CPP/7zip/Archive/Common/HandlerOut.h @@ -4,7 +4,7 @@ #define __HANDLER_OUT_H #include "../../Common/MethodProps.h" -#include "../../Common/CreateCoder.h" +#include "../../../Common/MyString.h" namespace NArchive { @@ -31,17 +31,18 @@ public: CObjectVector<COneMethodInfo> _methods; bool _removeSfxBlock; - UInt64 _numSolidFiles; + UInt64 _numSolidFiles; UInt64 _numSolidBytes; bool _numSolidBytesDefined; bool _solidExtension; bool _compressHeaders; + bool _encryptHeadersSpecified; bool _encryptHeaders; - bool WriteModified; - bool WriteCreated; - bool WriteAccessed; + bool WriteCTime; + bool WriteATime; + bool WriteMTime; bool _autoFilter; UInt32 _level; @@ -77,8 +78,6 @@ public: UInt32 numProcessors; UInt32 mainDicSize; UInt32 mainDicMethodIndex; - - DECL_EXTERNAL_CODECS_VARS }; } diff --git a/CPP/7zip/Archive/Common/InStreamWithCRC.h b/CPP/7zip/Archive/Common/InStreamWithCRC.h index 96bea9b2..c5ada6fe 100755 --- a/CPP/7zip/Archive/Common/InStreamWithCRC.h +++ b/CPP/7zip/Archive/Common/InStreamWithCRC.h @@ -6,12 +6,12 @@ #include "../../../Common/MyCom.h" #include "../../IStream.h" -extern "C" -{ +extern "C" +{ #include "../../../../C/7zCrc.h" } -class CSequentialInStreamWithCRC: +class CSequentialInStreamWithCRC: public ISequentialInStream, public CMyUnknownImp { @@ -38,7 +38,7 @@ public: bool WasFinished() const { return _wasFinished; } }; -class CInStreamWithCRC: +class CInStreamWithCRC: public IInStream, public CMyUnknownImp { diff --git a/CPP/7zip/Archive/Common/ItemNameUtils.cpp b/CPP/7zip/Archive/Common/ItemNameUtils.cpp index f7c3fcd9..6dfaf980 100755 --- a/CPP/7zip/Archive/Common/ItemNameUtils.cpp +++ b/CPP/7zip/Archive/Common/ItemNameUtils.cpp @@ -38,7 +38,7 @@ bool HasTailSlash(const AString &name, UINT codePage) { if (name.IsEmpty()) return false; - LPCSTR prev = + LPCSTR prev = #ifdef _WIN32 CharPrevExA((WORD)codePage, name, &name[name.Length()], 0); #else diff --git a/CPP/7zip/Archive/Common/MultiStream.cpp b/CPP/7zip/Archive/Common/MultiStream.cpp index a8cb333e..cf7dc050 100755 --- a/CPP/7zip/Archive/Common/MultiStream.cpp +++ b/CPP/7zip/Archive/Common/MultiStream.cpp @@ -33,7 +33,7 @@ STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize) return S_OK; } -STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin, +STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) { UInt64 newPos; @@ -76,7 +76,7 @@ STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin, /* -class COutVolumeStream: +class COutVolumeStream: public ISequentialOutStream, public CMyUnknownImp { @@ -93,9 +93,9 @@ public: CFileItem _file; CUpdateOptions _options; CMyComPtr<IArchiveUpdateCallback2> VolumeCallback; - void Init(IArchiveUpdateCallback2 *volumeCallback, - const UString &name) - { + void Init(IArchiveUpdateCallback2 *volumeCallback, + const UString &name) + { _file.Name = name; _file.IsStartPosDefined = true; _file.StartPos = 0; diff --git a/CPP/7zip/Archive/Common/MultiStream.h b/CPP/7zip/Archive/Common/MultiStream.h index b0fe41d6..137c9400 100755 --- a/CPP/7zip/Archive/Common/MultiStream.h +++ b/CPP/7zip/Archive/Common/MultiStream.h @@ -7,7 +7,7 @@ #include "../../../Common/MyVector.h" #include "../../Archive/IArchive.h" -class CMultiStream: +class CMultiStream: public IInStream, public CMyUnknownImp { @@ -40,7 +40,7 @@ public: }; /* -class COutMultiStream: +class COutMultiStream: public IOutStream, public CMyUnknownImp { diff --git a/CPP/7zip/Archive/Common/OutStreamWithCRC.h b/CPP/7zip/Archive/Common/OutStreamWithCRC.h index eaeecde7..32870235 100755 --- a/CPP/7zip/Archive/Common/OutStreamWithCRC.h +++ b/CPP/7zip/Archive/Common/OutStreamWithCRC.h @@ -6,12 +6,12 @@ #include "../../../Common/MyCom.h" #include "../../IStream.h" -extern "C" -{ +extern "C" +{ #include "../../../../C/7zCrc.h" } -class COutStreamWithCRC: +class COutStreamWithCRC: public ISequentialOutStream, public CMyUnknownImp { diff --git a/CPP/7zip/Archive/Common/OutStreamWithSha1.h b/CPP/7zip/Archive/Common/OutStreamWithSha1.h index 976b347c..6df23080 100755 --- a/CPP/7zip/Archive/Common/OutStreamWithSha1.h +++ b/CPP/7zip/Archive/Common/OutStreamWithSha1.h @@ -11,7 +11,7 @@ #include "../../Crypto/Hash/Sha1.h" -class COutStreamWithSha1: +class COutStreamWithSha1: public ISequentialOutStream, public CMyUnknownImp { diff --git a/CPP/7zip/Archive/Common/ParseProperties.cpp b/CPP/7zip/Archive/Common/ParseProperties.cpp index 83d51241..5cd849e2 100755 --- a/CPP/7zip/Archive/Common/ParseProperties.cpp +++ b/CPP/7zip/Archive/Common/ParseProperties.cpp @@ -138,7 +138,7 @@ int ParseStringToUInt32(const UString &srcString, UInt32 &number) const wchar_t *start = srcString; const wchar_t *end; UInt64 number64 = ConvertStringToUInt64(start, &end); - if (number64 > 0xFFFFFFFF) + if (number64 > 0xFFFFFFFF) { number = 0; return 0; @@ -158,7 +158,7 @@ HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 default break; default: { - bool val; + bool val; RINOK(SetBoolProperty(val, prop)); numThreads = (val ? defaultNumThreads : 1); break; diff --git a/CPP/7zip/Archive/Cpio/CpioHandler.cpp b/CPP/7zip/Archive/Cpio/CpioHandler.cpp index e2392b86..e034c87b 100755 --- a/CPP/7zip/Archive/Cpio/CpioHandler.cpp +++ b/CPP/7zip/Archive/Cpio/CpioHandler.cpp @@ -27,20 +27,20 @@ namespace NArchive { namespace NCpio { /* -enum // PropID +enum { kpidinode = kpidUserDefined, kpidiChkSum }; */ -STATPROPSTG kProps[] = +STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, - { NULL, kpidIsFolder, VT_BOOL}, + { NULL, kpidIsDir, VT_BOOL}, { NULL, kpidSize, VT_UI8}, - { NULL, kpidPackedSize, VT_UI8}, - { NULL, kpidLastWriteTime, VT_FILETIME}, + { NULL, kpidPackSize, VT_UI8}, + { NULL, kpidMTime, VT_FILETIME}, // { NULL, kpidUser, VT_BSTR}, // { NULL, kpidGroup, VT_BSTR}, // { L"inode", kpidinode, VT_UI4} @@ -50,27 +50,28 @@ STATPROPSTG kProps[] = IMP_IInArchive_Props IMP_IInArchive_ArcProps_NO -STDMETHODIMP CHandler::Open(IInStream *stream, +STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback *openArchiveCallback) + IArchiveOpenCallback *callback) { COM_TRY_BEGIN // try { CInArchive archive; - if (archive.Open(stream) != S_OK) - return S_FALSE; - - _items.Clear(); + UInt64 endPos = 0; + bool needSetTotal = true; - if (openArchiveCallback != NULL) + if (callback != NULL) { - RINOK(openArchiveCallback->SetTotal(NULL, NULL)); - UInt64 numFiles = _items.Size(); - RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); + RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos)); + RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); } + RINOK(archive.Open(stream)); + + _items.Clear(); + for (;;) { CItemEx item; @@ -84,10 +85,19 @@ STDMETHODIMP CHandler::Open(IInStream *stream, break; _items.Add(item); archive.SkeepDataRecords(item.Size, item.Align); - if (openArchiveCallback != NULL) + if (callback != NULL) { - UInt64 numFiles = _items.Size(); - RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); + if (needSetTotal) + { + RINOK(callback->SetTotal(NULL, &endPos)); + needSetTotal = false; + } + if (_items.Size() % 100 == 0) + { + UInt64 numFiles = _items.Size(); + UInt64 numBytes = item.HeaderPosition; + RINOK(callback->SetCompleted(&numFiles, &numBytes)); + } } } if (_items.Size() == 0) @@ -127,17 +137,16 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val switch(propID) { case kpidPath: - prop = (const wchar_t *)NItemName::GetOSName( - MultiByteToUnicodeString(item.Name, CP_OEMCP)); + prop = NItemName::GetOSName(MultiByteToUnicodeString(item.Name, CP_OEMCP)); break; - case kpidIsFolder: - prop = item.IsDirectory(); + case kpidIsDir: + prop = item.IsDir(); break; case kpidSize: - case kpidPackedSize: + case kpidPackSize: prop = (UInt64)item.Size; break; - case kpidLastWriteTime: + case kpidMTime: { FILETIME utcFileTime; if (item.ModificationTime != 0) @@ -151,12 +160,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val break; } /* - case kpidinode: - prop = item.inode; - break; - case kpidiChkSum: - prop = item.ChkSum; - break; + case kpidinode: prop = item.inode; break; + case kpidiChkSum: prop = item.ChkSum; break; */ } prop.Detach(value); @@ -199,14 +204,14 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, lps->InSize = lps->OutSize = currentTotalSize; RINOK(lps->SetCur()); CMyComPtr<ISequentialOutStream> realOutStream; - Int32 askMode = testMode ? + Int32 askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract; Int32 index = allFilesMode ? i : indices[i]; const CItemEx &item = _items[index]; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); currentItemSize = item.Size; - if (item.IsDirectory()) + if (item.IsDir()) { RINOK(extractCallback->PrepareOperation(askMode)); RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); @@ -224,7 +229,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, streamSpec->Init(item.Size); RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); realOutStream.Release(); - RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ? + RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ? NArchive::NExtract::NOperationResult::kOK: NArchive::NExtract::NOperationResult::kDataError)); } diff --git a/CPP/7zip/Archive/Cpio/CpioHandler.h b/CPP/7zip/Archive/Cpio/CpioHandler.h index 3b4e7036..1993c37f 100755 --- a/CPP/7zip/Archive/Cpio/CpioHandler.h +++ b/CPP/7zip/Archive/Cpio/CpioHandler.h @@ -11,7 +11,7 @@ namespace NArchive { namespace NCpio { -class CHandler: +class CHandler: public IInArchive, public CMyUnknownImp { diff --git a/CPP/7zip/Archive/Cpio/CpioHeader.cpp b/CPP/7zip/Archive/Cpio/CpioHeader.cpp index 9e4d99cb..f7b5a414 100755 --- a/CPP/7zip/Archive/Cpio/CpioHeader.cpp +++ b/CPP/7zip/Archive/Cpio/CpioHeader.cpp @@ -8,7 +8,7 @@ namespace NArchive { namespace NCpio { namespace NFileHeader { - namespace NMagic + namespace NMagic { extern const char *kMagic1 = "070701"; extern const char *kMagic2 = "070702"; diff --git a/CPP/7zip/Archive/Cpio/CpioHeader.h b/CPP/7zip/Archive/Cpio/CpioHeader.h index 40a0014a..21afcc17 100755 --- a/CPP/7zip/Archive/Cpio/CpioHeader.h +++ b/CPP/7zip/Archive/Cpio/CpioHeader.h @@ -10,7 +10,7 @@ namespace NCpio { namespace NFileHeader { - namespace NMagic + namespace NMagic { extern const char *kMagic1; extern const char *kMagic2; @@ -56,7 +56,7 @@ namespace NFileHeader 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 || + { return memcmp(Magic, NMagic::kMagic1, 6) == 0 || memcmp(Magic, NMagic::kMagic2, 6) == 0; }; }; */ diff --git a/CPP/7zip/Archive/Cpio/CpioIn.cpp b/CPP/7zip/Archive/Cpio/CpioIn.cpp index 4732a32e..d4d807e1 100755 --- a/CPP/7zip/Archive/Cpio/CpioIn.cpp +++ b/CPP/7zip/Archive/Cpio/CpioIn.cpp @@ -140,12 +140,12 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item) UInt32 nameSize; - bool oldBE = + bool oldBE = _block[0] == NFileHeader::NMagic::kMagicForRecord2[1] && _block[1] == NFileHeader::NMagic::kMagicForRecord2[0]; bool binMode = (_block[0] == NFileHeader::NMagic::kMagicForRecord2[0] && - _block[1] == NFileHeader::NMagic::kMagicForRecord2[1]) || + _block[1] == NFileHeader::NMagic::kMagicForRecord2[1]) || oldBE; if (binMode) @@ -175,7 +175,7 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item) item.ChkSum = 0; item.HeaderSize = GetAlignedSize( nameSize + NFileHeader::kRecord2Size, item.Align); - nameSize = item.HeaderSize - NFileHeader::kRecord2Size; + nameSize = item.HeaderSize - NFileHeader::kRecord2Size; } else { @@ -183,8 +183,8 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item) if (processedSize != 4) return S_FALSE; - bool magicOK = - memcmp(_block, NFileHeader::NMagic::kMagic1, 6) == 0 || + bool magicOK = + memcmp(_block, NFileHeader::NMagic::kMagic1, 6) == 0 || memcmp(_block, NFileHeader::NMagic::kMagic2, 6) == 0; _blockPos = 6; if (magicOK) @@ -211,7 +211,7 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item) GetFromHex(item.ChkSum); item.HeaderSize = GetAlignedSize( nameSize + NFileHeader::kRecordSize, item.Align); - nameSize = item.HeaderSize - NFileHeader::kRecordSize; + nameSize = item.HeaderSize - NFileHeader::kRecordSize; } else { @@ -237,7 +237,7 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item) GetFromOct11(item.Size); // ????? item.HeaderSize = GetAlignedSize( nameSize + NFileHeader::kOctRecordSize, item.Align); - nameSize = item.HeaderSize - NFileHeader::kOctRecordSize; + nameSize = item.HeaderSize - NFileHeader::kOctRecordSize; } } if (nameSize == 0 || nameSize >= (1 << 27)) diff --git a/CPP/7zip/Archive/Cpio/CpioItem.h b/CPP/7zip/Archive/Cpio/CpioItem.h index cee8b5b3..70aa384d 100755 --- a/CPP/7zip/Archive/Cpio/CpioItem.h +++ b/CPP/7zip/Archive/Cpio/CpioItem.h @@ -34,7 +34,7 @@ struct CItem UInt32 Align; - bool IsDirectory() const + bool IsDir() const #ifdef _WIN32 { return (Mode & _S_IFMT) == _S_IFDIR; } #else diff --git a/CPP/7zip/Archive/Cpio/StdAfx.cpp b/CPP/7zip/Archive/Cpio/StdAfx.cpp deleted file mode 100755 index d0feea85..00000000 --- a/CPP/7zip/Archive/Cpio/StdAfx.cpp +++ /dev/null @@ -1,3 +0,0 @@ -// StdAfx.cpp - -#include "StdAfx.h" diff --git a/CPP/7zip/Archive/Deb/DebHandler.cpp b/CPP/7zip/Archive/Deb/DebHandler.cpp deleted file mode 100755 index 19cf310b..00000000 --- a/CPP/7zip/Archive/Deb/DebHandler.cpp +++ /dev/null @@ -1,202 +0,0 @@ -// DebHandler.cpp - -#include "StdAfx.h" - -#include "DebHandler.h" -#include "DebIn.h" - -#include "Common/Defs.h" -#include "Common/StringConvert.h" -#include "Common/NewHandler.h" -#include "Common/ComTry.h" - -#include "Windows/Time.h" -#include "Windows/PropVariant.h" - -#include "../../Common/ProgressUtils.h" -#include "../../Common/LimitedStreams.h" - -#include "../../Compress/Copy/CopyCoder.h" - -#include "../Common/ItemNameUtils.h" - -using namespace NWindows; -using namespace NTime; - -namespace NArchive { -namespace NDeb { - -STATPROPSTG kProps[] = -{ - { NULL, kpidPath, VT_BSTR}, - { NULL, kpidSize, VT_UI8}, - { NULL, kpidPackedSize, VT_UI8}, - { NULL, kpidLastWriteTime, VT_FILETIME} -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps_NO - -STDMETHODIMP CHandler::Open(IInStream *stream, - const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback *openArchiveCallback) -{ - COM_TRY_BEGIN - { - CInArchive archive; - if(archive.Open(stream) != S_OK) - return S_FALSE; - _items.Clear(); - - if (openArchiveCallback != NULL) - { - RINOK(openArchiveCallback->SetTotal(NULL, NULL)); - UInt64 numFiles = _items.Size(); - RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); - } - - for (;;) - { - CItemEx item; - bool filled; - HRESULT result = archive.GetNextItem(filled, item); - if (result == S_FALSE) - return S_FALSE; - if (result != S_OK) - return S_FALSE; - if (!filled) - break; - _items.Add(item); - archive.SkeepData(item.Size); - if (openArchiveCallback != NULL) - { - UInt64 numFiles = _items.Size(); - RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); - } - } - _inStream = stream; - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _inStream.Release(); - _items.Clear(); - return S_OK; -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = _items.Size(); - return S_OK; -} - -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; - const CItemEx &item = _items[index]; - - switch(propID) - { - case kpidPath: - prop = (const wchar_t *)NItemName::GetOSName2( - MultiByteToUnicodeString(item.Name, CP_OEMCP)); - break; - case kpidIsFolder: - prop = false; - break; - case kpidSize: - case kpidPackedSize: - prop = item.Size; - break; - case kpidLastWriteTime: - { - FILETIME utcFileTime; - if (item.ModificationTime != 0) - NTime::UnixTimeToFileTime(item.ModificationTime, utcFileTime); - else - { - utcFileTime.dwLowDateTime = 0; - utcFileTime.dwHighDateTime = 0; - } - prop = utcFileTime; - break; - } - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 _aTestMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - bool testMode = (_aTestMode != 0); - bool allFilesMode = (numItems == UInt32(-1)); - if (allFilesMode) - numItems = _items.Size(); - if (numItems == 0) - return S_OK; - 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; - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr<ICompressProgressInfo> progress = lps; - lps->Init(extractCallback, false); - - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr<ISequentialInStream> inStream(streamSpec); - streamSpec->SetStream(_inStream); - - for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) - { - lps->InSize = lps->OutSize = currentTotalSize; - RINOK(lps->SetCur()); - CMyComPtr<ISequentialOutStream> realOutStream; - Int32 askMode = testMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; - Int32 index = allFilesMode ? i : indices[i]; - const CItemEx &item = _items[index]; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - currentItemSize = item.Size; - - - - - - - if (!testMode && (!realOutStream)) - continue; - RINOK(extractCallback->PrepareOperation(askMode)); - if (testMode) - { - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); - continue; - } - RINOK(_inStream->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL)); - streamSpec->Init(item.Size); - RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ? - NArchive::NExtract::NOperationResult::kOK: - NArchive::NExtract::NOperationResult::kDataError)); - } - return S_OK; - COM_TRY_END -} - -}} diff --git a/CPP/7zip/Archive/Deb/DebHeader.cpp b/CPP/7zip/Archive/Deb/DebHeader.cpp deleted file mode 100755 index dce00e1b..00000000 --- a/CPP/7zip/Archive/Deb/DebHeader.cpp +++ /dev/null @@ -1,13 +0,0 @@ -// Archive/Deb/Header.h - -#include "StdAfx.h" - -#include "DebHeader.h" - -namespace NArchive { -namespace NDeb { -namespace NHeader { - -const char *kSignature = "!<arch>\n"; - -}}} diff --git a/CPP/7zip/Archive/Deb/DebHeader.h b/CPP/7zip/Archive/Deb/DebHeader.h deleted file mode 100755 index c2884000..00000000 --- a/CPP/7zip/Archive/Deb/DebHeader.h +++ /dev/null @@ -1,38 +0,0 @@ -// Archive/Deb/Header.h - -#ifndef __ARCHIVE_DEB_HEADER_H -#define __ARCHIVE_DEB_HEADER_H - -#include "Common/Types.h" - -namespace NArchive { -namespace NDeb { - -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]; - char ModificationTime[kTimeSize]; - char Number0[6]; - char Number1[6]; - char Mode[kModeSize]; - char Size[kSizeSize]; - char Quote; - char NewLine; - }; - */ - const int kHeaderSize = kNameSize + kTimeSize + 6 + 6 + kModeSize + kSizeSize + 1 + 1; -} - -}} - -#endif diff --git a/CPP/7zip/Archive/Deb/DebIn.cpp b/CPP/7zip/Archive/Deb/DebIn.cpp deleted file mode 100755 index 41aaeb8a..00000000 --- a/CPP/7zip/Archive/Deb/DebIn.cpp +++ /dev/null @@ -1,156 +0,0 @@ -// Archive/DebIn.cpp - -#include "StdAfx.h" - -#include "DebIn.h" -#include "DebHeader.h" - -#include "Common/StringToInt.h" -#include "Windows/Defs.h" - -#include "../../Common/StreamUtils.h" - -namespace NArchive { -namespace NDeb { - -using namespace NHeader; - -HRESULT CInArchive::Open(IInStream *inStream) -{ - RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_Position)); - char signature[kSignatureLen]; - RINOK(ReadStream_FALSE(inStream, signature, kSignatureLen)); - m_Position += kSignatureLen; - if (memcmp(signature, kSignature, kSignatureLen) != 0) - return S_FALSE; - m_Stream = inStream; - return S_OK; -} - -static void MyStrNCpy(char *dest, const char *src, int size) -{ - for (int i = 0; i < size; i++) - { - char c = src[i]; - dest[i] = c; - if (c == 0) - break; - } -} - -static bool OctalToNumber(const char *s, int size, UInt64 &res) -{ - char sz[32]; - MyStrNCpy(sz, s, size); - sz[size] = 0; - const char *end; - int i; - for (i = 0; sz[i] == ' '; i++); - res = ConvertOctStringToUInt64(sz + i, &end); - return (*end == ' ' || *end == 0); -} - -static bool OctalToNumber32(const char *s, int size, UInt32 &res) -{ - UInt64 res64; - if (!OctalToNumber(s, size, res64)) - return false; - res = (UInt32)res64; - return (res64 <= 0xFFFFFFFF); -} - -static bool DecimalToNumber(const char *s, int size, UInt64 &res) -{ - char sz[32]; - MyStrNCpy(sz, s, size); - sz[size] = 0; - const char *end; - int i; - for (i = 0; sz[i] == ' '; i++); - res = ConvertStringToUInt64(sz + i, &end); - return (*end == ' ' || *end == 0); -} - -static bool DecimalToNumber32(const char *s, int size, UInt32 &res) -{ - UInt64 res64; - if (!DecimalToNumber(s, size, res64)) - return false; - res = (UInt32)res64; - return (res64 <= 0xFFFFFFFF); -} - -#define RIF(x) { if (!(x)) return S_FALSE; } - - -HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item) -{ - filled = false; - - char header[NHeader::kHeaderSize]; - const char *cur = header; - - size_t processedSize = sizeof(header); - item.HeaderPosition = m_Position; - RINOK(ReadStream(m_Stream, header, &processedSize)); - m_Position += processedSize; - if (processedSize != sizeof(header)) - return S_OK; - - char tempString[kNameSize + 1]; - MyStrNCpy(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) - return S_FALSE; - - RIF(DecimalToNumber32(cur, kTimeSize, item.ModificationTime)); - cur += kTimeSize; - - cur += 6 + 6; - - RIF(OctalToNumber32(cur, kModeSize, item.Mode)); - cur += kModeSize; - - RIF(DecimalToNumber(cur, kSizeSize, item.Size)); - cur += kSizeSize; - - filled = true; - return S_OK; -} - -HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item) -{ - for (;;) - { - RINOK(GetNextItemReal(filled, item)); - if (!filled) - return S_OK; - if (item.Name.CompareNoCase("debian-binary") != 0) - return S_OK; - if (item.Size != 4) - return S_OK; - SkeepData(item.Size); - } -} - -HRESULT CInArchive::Skeep(UInt64 numBytes) -{ - 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::SkeepData(UInt64 dataSize) -{ - return Skeep((dataSize + 1) & (~((UInt64)0x1))); -} - -}} diff --git a/CPP/7zip/Archive/Deb/DebIn.h b/CPP/7zip/Archive/Deb/DebIn.h deleted file mode 100755 index 7d33fa59..00000000 --- a/CPP/7zip/Archive/Deb/DebIn.h +++ /dev/null @@ -1,28 +0,0 @@ -// Archive/DebIn.h - -#ifndef __ARCHIVE_DEB_IN_H -#define __ARCHIVE_DEB_IN_H - -#include "Common/MyCom.h" -#include "../../IStream.h" -#include "DebItem.h" - -namespace NArchive { -namespace NDeb { - -class CInArchive -{ - CMyComPtr<IInStream> m_Stream; - UInt64 m_Position; - - HRESULT GetNextItemReal(bool &filled, CItemEx &itemInfo); - HRESULT Skeep(UInt64 numBytes); -public: - HRESULT Open(IInStream *inStream); - HRESULT GetNextItem(bool &filled, CItemEx &itemInfo); - HRESULT SkeepData(UInt64 dataSize); -}; - -}} - -#endif diff --git a/CPP/7zip/Archive/Deb/DebItem.h b/CPP/7zip/Archive/Deb/DebItem.h deleted file mode 100755 index 86e6740d..00000000 --- a/CPP/7zip/Archive/Deb/DebItem.h +++ /dev/null @@ -1,32 +0,0 @@ -// Archive/Deb/ItemInfo.h - -#ifndef __ARCHIVE_DEB_ITEMINFO_H -#define __ARCHIVE_DEB_ITEMINFO_H - -#include "Common/Types.h" -#include "Common/MyString.h" -#include "DebHeader.h" - -namespace NArchive { -namespace NDeb { - -class CItem -{ -public: - AString Name; - UInt64 Size; - UInt32 ModificationTime; - UInt32 Mode; -}; - -class CItemEx: public CItem -{ -public: - UInt64 HeaderPosition; - UInt64 GetDataPosition() const { return HeaderPosition + NHeader::kHeaderSize; }; - // UInt64 GetFullSize() const { return NFileHeader::kRecordSize + Size; }; -}; - -}} - -#endif diff --git a/CPP/7zip/Archive/Deb/DebRegister.cpp b/CPP/7zip/Archive/Deb/DebRegister.cpp deleted file mode 100755 index 35c4965e..00000000 --- a/CPP/7zip/Archive/Deb/DebRegister.cpp +++ /dev/null @@ -1,13 +0,0 @@ -// DebRegister.cpp - -#include "StdAfx.h" - -#include "../../Common/RegisterArc.h" - -#include "DebHandler.h" -static IInArchive *CreateArc() { return new NArchive::NDeb::CHandler; } - -static CArcInfo g_ArcInfo = - { L"Deb", L"deb", 0, 0xEC, { '!', '<', 'a', 'r', 'c', 'h', '>', '\n' }, 8, false, CreateArc, 0 }; - -REGISTER_ARC(Deb) diff --git a/CPP/7zip/Archive/Deb/StdAfx.cpp b/CPP/7zip/Archive/Deb/StdAfx.cpp deleted file mode 100755 index d0feea85..00000000 --- a/CPP/7zip/Archive/Deb/StdAfx.cpp +++ /dev/null @@ -1,3 +0,0 @@ -// StdAfx.cpp - -#include "StdAfx.h" diff --git a/CPP/7zip/Archive/Deb/StdAfx.h b/CPP/7zip/Archive/Deb/StdAfx.h deleted file mode 100755 index e7fb6986..00000000 --- a/CPP/7zip/Archive/Deb/StdAfx.h +++ /dev/null @@ -1,8 +0,0 @@ -// StdAfx.h - -#ifndef __STDAFX_H -#define __STDAFX_H - -#include "../../../Common/MyWindows.h" - -#endif diff --git a/CPP/7zip/Archive/DebHandler.cpp b/CPP/7zip/Archive/DebHandler.cpp new file mode 100755 index 00000000..9bac2b7d --- /dev/null +++ b/CPP/7zip/Archive/DebHandler.cpp @@ -0,0 +1,411 @@ +// DebHandler.cpp + +#include "StdAfx.h" + +#include "Common/ComTry.h" +#include "Common/Defs.h" +#include "Common/NewHandler.h" +#include "Common/StringConvert.h" +#include "Common/StringToInt.h" + +#include "Windows/PropVariant.h" +#include "Windows/Time.h" + +#include "../Common/LimitedStreams.h" +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +#include "../Compress/Copy/CopyCoder.h" + +#include "Common/ItemNameUtils.h" + +using namespace NWindows; +using namespace NTime; + +namespace NArchive { +namespace NDeb { + +namespace NHeader +{ + const int kSignatureLen = 8; + + const char *kSignature = "!<arch>\n"; + + const int kNameSize = 16; + const int kTimeSize = 12; + const int kModeSize = 8; + const int kSizeSize = 10; + + /* + struct CHeader + { + char Name[kNameSize]; + char MTime[kTimeSize]; + char Number0[6]; + char Number1[6]; + char Mode[kModeSize]; + char Size[kSizeSize]; + char Quote; + char NewLine; + }; + */ + const int kHeaderSize = kNameSize + kTimeSize + 6 + 6 + kModeSize + kSizeSize + 1 + 1; +} + +class CItem +{ +public: + AString Name; + UInt64 Size; + UInt32 MTime; + UInt32 Mode; +}; + +class CItemEx: public CItem +{ +public: + UInt64 HeaderPosition; + UInt64 GetDataPosition() const { return HeaderPosition + NHeader::kHeaderSize; }; + // UInt64 GetFullSize() const { return NFileHeader::kRecordSize + Size; }; +}; + +class CInArchive +{ + CMyComPtr<IInStream> m_Stream; + UInt64 m_Position; + + HRESULT GetNextItemReal(bool &filled, CItemEx &itemInfo); + HRESULT Skeep(UInt64 numBytes); +public: + HRESULT Open(IInStream *inStream); + HRESULT GetNextItem(bool &filled, CItemEx &itemInfo); + HRESULT SkeepData(UInt64 dataSize); +}; + +HRESULT CInArchive::Open(IInStream *inStream) +{ + RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_Position)); + char signature[NHeader::kSignatureLen]; + RINOK(ReadStream_FALSE(inStream, signature, NHeader::kSignatureLen)); + m_Position += NHeader::kSignatureLen; + if (memcmp(signature, NHeader::kSignature, NHeader::kSignatureLen) != 0) + return S_FALSE; + m_Stream = inStream; + return S_OK; +} + +static void MyStrNCpy(char *dest, const char *src, int size) +{ + for (int i = 0; i < size; i++) + { + char c = src[i]; + dest[i] = c; + if (c == 0) + break; + } +} + +static bool OctalToNumber(const char *s, int size, UInt64 &res) +{ + char sz[32]; + MyStrNCpy(sz, s, size); + sz[size] = 0; + const char *end; + int i; + for (i = 0; sz[i] == ' '; i++); + res = ConvertOctStringToUInt64(sz + i, &end); + return (*end == ' ' || *end == 0); +} + +static bool OctalToNumber32(const char *s, int size, UInt32 &res) +{ + UInt64 res64; + if (!OctalToNumber(s, size, res64)) + return false; + res = (UInt32)res64; + return (res64 <= 0xFFFFFFFF); +} + +static bool DecimalToNumber(const char *s, int size, UInt64 &res) +{ + char sz[32]; + MyStrNCpy(sz, s, size); + sz[size] = 0; + const char *end; + int i; + for (i = 0; sz[i] == ' '; i++); + res = ConvertStringToUInt64(sz + i, &end); + return (*end == ' ' || *end == 0); +} + +static bool DecimalToNumber32(const char *s, int size, UInt32 &res) +{ + UInt64 res64; + if (!DecimalToNumber(s, size, res64)) + return false; + res = (UInt32)res64; + return (res64 <= 0xFFFFFFFF); +} + +#define RIF(x) { if (!(x)) return S_FALSE; } + + +HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item) +{ + filled = false; + + char header[NHeader::kHeaderSize]; + const char *cur = header; + + size_t processedSize = sizeof(header); + item.HeaderPosition = m_Position; + RINOK(ReadStream(m_Stream, header, &processedSize)); + m_Position += processedSize; + if (processedSize != sizeof(header)) + return S_OK; + + char tempString[NHeader::kNameSize + 1]; + MyStrNCpy(tempString, cur, NHeader::kNameSize); + cur += NHeader::kNameSize; + tempString[NHeader::kNameSize] = '\0'; + item.Name = tempString; + item.Name.Trim(); + + for (int i = 0; i < item.Name.Length(); i++) + if (((Byte)item.Name[i]) < 0x20) + return S_FALSE; + + RIF(DecimalToNumber32(cur, NHeader::kTimeSize, item.MTime)); + cur += NHeader::kTimeSize; + + cur += 6 + 6; + + RIF(OctalToNumber32(cur, NHeader::kModeSize, item.Mode)); + cur += NHeader::kModeSize; + + RIF(DecimalToNumber(cur, NHeader::kSizeSize, item.Size)); + cur += NHeader::kSizeSize; + + filled = true; + return S_OK; +} + +HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item) +{ + for (;;) + { + RINOK(GetNextItemReal(filled, item)); + if (!filled) + return S_OK; + if (item.Name.CompareNoCase("debian-binary") != 0) + return S_OK; + if (item.Size != 4) + return S_OK; + SkeepData(item.Size); + } +} + +HRESULT CInArchive::Skeep(UInt64 numBytes) +{ + 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::SkeepData(UInt64 dataSize) +{ + return Skeep((dataSize + 1) & (~((UInt64)0x1))); +} + + +class CHandler: + public IInArchive, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP1(IInArchive) + + INTERFACE_IInArchive(;) + +private: + CObjectVector<CItemEx> _items; + CMyComPtr<IInStream> _inStream; +}; + + +STATPROPSTG kProps[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackSize, VT_UI8}, + { NULL, kpidMTime, VT_FILETIME} +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO + +STDMETHODIMP CHandler::Open(IInStream *stream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback *openArchiveCallback) +{ + COM_TRY_BEGIN + { + CInArchive archive; + if(archive.Open(stream) != S_OK) + return S_FALSE; + _items.Clear(); + + if (openArchiveCallback != NULL) + { + RINOK(openArchiveCallback->SetTotal(NULL, NULL)); + UInt64 numFiles = _items.Size(); + RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); + } + + for (;;) + { + CItemEx item; + bool filled; + HRESULT result = archive.GetNextItem(filled, item); + if (result == S_FALSE) + return S_FALSE; + if (result != S_OK) + return S_FALSE; + if (!filled) + break; + _items.Add(item); + archive.SkeepData(item.Size); + if (openArchiveCallback != NULL) + { + UInt64 numFiles = _items.Size(); + RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); + } + } + _inStream = stream; + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + _inStream.Release(); + _items.Clear(); + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _items.Size(); + return S_OK; +} + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + const CItemEx &item = _items[index]; + + switch(propID) + { + case kpidPath: prop = (const wchar_t *)NItemName::GetOSName2(MultiByteToUnicodeString(item.Name, CP_OEMCP)); break; + case kpidSize: + case kpidPackSize: + prop = item.Size; + break; + case kpidMTime: + { + if (item.MTime != 0) + { + FILETIME fileTime; + NTime::UnixTimeToFileTime(item.MTime, fileTime); + prop = fileTime; + } + break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool testMode = (_aTestMode != 0); + bool allFilesMode = (numItems == UInt32(-1)); + if (allFilesMode) + numItems = _items.Size(); + if (numItems == 0) + return S_OK; + 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; + + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); + CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr<ICompressProgressInfo> progress = lps; + lps->Init(extractCallback, false); + + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr<ISequentialInStream> inStream(streamSpec); + streamSpec->SetStream(_inStream); + + for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) + { + lps->InSize = lps->OutSize = currentTotalSize; + RINOK(lps->SetCur()); + CMyComPtr<ISequentialOutStream> realOutStream; + Int32 askMode = testMode ? + NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + Int32 index = allFilesMode ? i : indices[i]; + const CItemEx &item = _items[index]; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + currentItemSize = item.Size; + + + + + + + if (!testMode && (!realOutStream)) + continue; + RINOK(extractCallback->PrepareOperation(askMode)); + if (testMode) + { + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + continue; + } + RINOK(_inStream->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL)); + streamSpec->Init(item.Size); + RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ? + NArchive::NExtract::NOperationResult::kOK: + NArchive::NExtract::NOperationResult::kDataError)); + } + return S_OK; + COM_TRY_END +} + +static IInArchive *CreateArc() { return new NArchive::NDeb::CHandler; } + +static CArcInfo g_ArcInfo = + { L"Deb", L"deb", 0, 0xEC, { '!', '<', 'a', 'r', 'c', 'h', '>', '\n' }, 8, false, CreateArc, 0 }; + +REGISTER_ARC(Deb) + +}} diff --git a/CPP/7zip/Archive/DllExports.cpp b/CPP/7zip/Archive/DllExports.cpp index dae2698f..ccad2126 100755 --- a/CPP/7zip/Archive/DllExports.cpp +++ b/CPP/7zip/Archive/DllExports.cpp @@ -18,7 +18,7 @@ static bool IsItWindowsNT() { OSVERSIONINFO versionInfo; versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); - if (!::GetVersionEx(&versionInfo)) + if (!::GetVersionEx(&versionInfo)) return false; return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); } @@ -37,7 +37,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) return TRUE; } -DEFINE_GUID(CLSID_CArchiveHandler, +DEFINE_GUID(CLSID_CArchiveHandler, 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00); STDAPI CreateArchiver(const GUID *classID, const GUID *iid, void **outObject); diff --git a/CPP/7zip/Archive/DllExports2.cpp b/CPP/7zip/Archive/DllExports2.cpp index d3b15f06..545fcbd3 100755 --- a/CPP/7zip/Archive/DllExports2.cpp +++ b/CPP/7zip/Archive/DllExports2.cpp @@ -7,8 +7,8 @@ #include "../../Common/Types.h" #include "../../Windows/PropVariant.h" #if defined(_WIN32) && defined(_7ZIP_LARGE_PAGES) -extern "C" -{ +extern "C" +{ #include "../../../C/Alloc.h" } #endif @@ -25,7 +25,7 @@ static bool IsItWindowsNT() { OSVERSIONINFO versionInfo; versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); - if (!::GetVersionEx(&versionInfo)) + if (!::GetVersionEx(&versionInfo)) return false; return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); } @@ -47,12 +47,12 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) return TRUE; } -DEFINE_GUID(CLSID_CArchiveHandler, +DEFINE_GUID(CLSID_CArchiveHandler, 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00); static const UInt16 kDecodeId = 0x2790; -DEFINE_GUID(CLSID_CCodec, +DEFINE_GUID(CLSID_CCodec, 0x23170F69, 0x40C1, kDecodeId, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject); diff --git a/CPP/7zip/Archive/DmgHandler.cpp b/CPP/7zip/Archive/DmgHandler.cpp new file mode 100755 index 00000000..7d5201c0 --- /dev/null +++ b/CPP/7zip/Archive/DmgHandler.cpp @@ -0,0 +1,778 @@ +// DmgHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#include "Common/Buffer.h" +#include "Common/ComTry.h" +#include "Common/IntToString.h" +#include "Common/MyXml.h" +#include "Common/UTFConvert.h" + +#include "Windows/PropVariant.h" + +#include "../Common/LimitedStreams.h" +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +#include "../Compress/BZip2/BZip2Decoder.h" +#include "../Compress/Copy/CopyCoder.h" +#include "../Compress/Deflate/ZlibDecoder.h" + +// #define DMG_SHOW_RAW + +// #include <stdio.h> +#define PRF(x) // x + +#define Get32(p) GetBe32(p) +#define Get64(p) GetBe64(p) + +static int Base64ToByte(char c) +{ + if (c >= 'A' && c <= 'Z') return c - 'A'; + if (c >= 'a' && c <= 'z') return c - 'a' + 26; + if (c >= '0' && c <= '9') return c - '0' + 52; + if (c == '+') return 62; + if (c == '/') return 63; + if (c == '=') return 0; + return -1; +} + +static int Base64ToBin(Byte *dest, const char *src, int srcLen) +{ + int srcPos = 0; + int destPos = 0; + while (srcPos < srcLen) + { + Byte buf[4]; + int filled = 0; + while (srcPos < srcLen) + { + int n = Base64ToByte(src[srcPos++]); + if (n >= 0) + { + buf[filled++] = (Byte)n; + if (filled == 4) + break; + } + } + if (filled >= 2) { if (dest) dest[destPos] = (buf[0] << 2) | (buf[1] >> 4); destPos++; } + if (filled >= 3) { if (dest) dest[destPos] = (buf[1] << 4) | (buf[2] >> 2); destPos++; } + if (filled >= 4) { if (dest) dest[destPos] = (buf[2] << 6) | (buf[3] ); destPos++; } + } + return destPos; +} + +static UString GetSizeString(UInt64 value) +{ + wchar_t s[32]; + wchar_t c; + if (value < (UInt64)20000) c = 0; + else if (value < ((UInt64)20000 << 10)) { value >>= 10; c = L'K'; } + else if (value < ((UInt64)20000 << 20)) { value >>= 20; c = L'M'; } + else { value >>= 30; c = L'G'; } + ConvertUInt64ToString(value, s); + int p = MyStringLen(s); + s[p++] = c; + s[p++] = L'\0'; + return s; +} + +namespace NArchive { +namespace NDmg { + +struct CBlock +{ + UInt32 Type; + UInt64 UnpPos; + UInt64 UnpSize; + UInt64 PackPos; + UInt64 PackSize; +}; + +struct CFile +{ + CByteBuffer Raw; + // UInt64 StartPos; + CRecordVector<CBlock> Blocks; + UInt64 GetUnpackSize() const + { + UInt64 size = 0; + for (int i = 0; i < Blocks.Size(); i++) + size += Blocks[i].UnpSize; + return size; + }; + UInt64 GetPackSize() const + { + UInt64 size = 0; + for (int i = 0; i < Blocks.Size(); i++) + size += Blocks[i].PackSize; + return size; + }; + + AString Name; +}; + +class CHandler: + public IInArchive, + public CMyUnknownImp +{ + CMyComPtr<IInStream> _inStream; + + AString _xml; + CObjectVector<CFile> _files; + CRecordVector<int> _fileIndices; + + HRESULT Open2(IInStream *stream); + HRESULT Extract(IInStream *stream); +public: + MY_UNKNOWN_IMP1(IInArchive) + INTERFACE_IInArchive(;) +}; + +const UInt32 kXmlSizeMax = ((UInt32)1 << 31) - (1 << 14); + +enum +{ + METHOD_ZERO_0 = 0, + METHOD_COPY = 1, + METHOD_ZERO_2 = 2, + METHOD_ZLIB = 0x80000005, + METHOD_BZIP2 = 0x80000006, + METHOD_DUMMY = 0x7FFFFFFE, + METHOD_END = 0xFFFFFFFF +}; + +struct CMethodStat +{ + UInt32 NumBlocks; + UInt64 PackSize; + UInt64 UnpSize; + CMethodStat(): NumBlocks(0), PackSize(0), UnpSize(0) {} +}; + +struct CMethods +{ + CRecordVector<CMethodStat> Stats; + CRecordVector<UInt32> Types; + void Update(const CFile &file); + UString GetString() const; +}; + +void CMethods::Update(const CFile &file) +{ + for (int i = 0; i < file.Blocks.Size(); i++) + { + const CBlock &b = file.Blocks[i]; + int index = Types.FindInSorted(b.Type); + if (index < 0) + { + index = Types.AddToUniqueSorted(b.Type); + Stats.Insert(index, CMethodStat()); + } + CMethodStat &m = Stats[index]; + m.PackSize += b.PackSize; + m.UnpSize += b.UnpSize; + m.NumBlocks++; + } +} + +UString CMethods::GetString() const +{ + UString res; + for (int i = 0; i < Types.Size(); i++) + { + if (i != 0) + res += L' '; + wchar_t buf[32]; + const wchar_t *s; + const CMethodStat &m = Stats[i]; + bool showPack = true; + UInt32 type = Types[i]; + switch(type) + { + case METHOD_ZERO_0: s = L"zero0"; showPack = (m.PackSize != 0); break; + case METHOD_ZERO_2: s = L"zero2"; showPack = (m.PackSize != 0); break; + case METHOD_COPY: s = L"copy"; showPack = (m.UnpSize != m.PackSize); break; + case METHOD_ZLIB: s = L"zlib"; break; + case METHOD_BZIP2: s = L"bzip2"; break; + default: ConvertUInt64ToString(type, buf); s = buf; + } + res += s; + if (m.NumBlocks != 1) + { + res += L'['; + ConvertUInt64ToString(m.NumBlocks, buf); + res += buf; + res += L']'; + } + res += L'-'; + res += GetSizeString(m.UnpSize); + if (showPack) + { + res += L'-'; + res += GetSizeString(m.PackSize); + } + } + return res; +} + +STATPROPSTG kProps[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackSize, VT_UI8}, + { NULL, kpidComment, VT_BSTR}, + { NULL, kpidMethod, VT_BSTR} +}; + +IMP_IInArchive_Props + +STATPROPSTG kArcProps[] = +{ + { NULL, kpidMethod, VT_BSTR}, + { NULL, kpidNumBlocks, VT_UI4} +}; + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch(propID) + { + case kpidMethod: + { + CMethods m; + for (int i = 0; i < _files.Size(); i++) + m.Update(_files[i]); + prop = m.GetString(); + break; + } + case kpidNumBlocks: + { + UInt64 numBlocks = 0; + for (int i = 0; i < _files.Size(); i++) + numBlocks += _files[i].Blocks.Size(); + prop = numBlocks; + break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +IMP_IInArchive_ArcProps + +static int FindKeyPair(const CXmlItem &item, const AString &key, const AString &nextTag) +{ + for (int i = 0; i + 1 < item.SubItems.Size(); i++) + { + const CXmlItem &si = item.SubItems[i]; + if (si.IsTagged("key") && si.GetSubString() == key && item.SubItems[i + 1].IsTagged(nextTag)) + return i + 1; + } + return -1; +} + +static AString GetStringFromKeyPair(const CXmlItem &item, const AString &key, const AString &nextTag) +{ + int index = FindKeyPair(item, key, nextTag); + if (index >= 0) + return item.SubItems[index].GetSubString(); + return AString(); +} + +HRESULT CHandler::Open2(IInStream *stream) +{ + const int HEADER_SIZE = 0x1E0; + + UInt64 headerPos; + RINOK(stream->Seek(-HEADER_SIZE, STREAM_SEEK_END, &headerPos)); + Byte buf[HEADER_SIZE]; + RINOK(ReadStream_FALSE(stream, buf, HEADER_SIZE)); + UInt64 address1 = Get64(buf + 0); + UInt64 address2 = Get64(buf + 0xB8); + UInt64 size64 = Get64(buf + 0xC0); + if (address1 != address2 || size64 >= kXmlSizeMax || size64 == 0 || + address1 >= headerPos || address1 + size64 > headerPos) + return S_FALSE; + RINOK(stream->Seek(address1, STREAM_SEEK_SET, NULL)); + size_t size = (size_t)size64; + + char *ss = _xml.GetBuffer((int)size + 1); + RINOK(ReadStream_FALSE(stream, ss, size)); + ss[size] = 0; + _xml.ReleaseBuffer(); + + CXml xml; + if (!xml.Parse(_xml)) + return S_FALSE; + if (xml.Root.Name != "plist") + return S_FALSE; + + int dictIndex = xml.Root.FindSubTag("dict"); + if (dictIndex < 0) + return S_FALSE; + + const CXmlItem &dictItem = xml.Root.SubItems[dictIndex]; + int rfDictIndex = FindKeyPair(dictItem, "resource-fork", "dict"); + if (rfDictIndex < 0) + return S_FALSE; + + const CXmlItem &rfDictItem = dictItem.SubItems[rfDictIndex]; + int arrIndex = FindKeyPair(rfDictItem, "blkx", "array"); + if (arrIndex < 0) + return S_FALSE; + + const CXmlItem &arrItem = rfDictItem.SubItems[arrIndex]; + + /* some DMG file has BUG: + PackPos for each new file is 0. + So we use additional "StartPos" to fix that BUG */ + + /* + UInt64 startPos = 0; + bool startPosIsDefined = false; + */ + + + for (int i = 0; i < arrItem.SubItems.Size(); i++) + { + const CXmlItem &item = arrItem.SubItems[i]; + if (!item.IsTagged("dict")) + continue; + + CFile file; + // file.StartPos = startPos; + + int destLen; + { + AString dataString; + AString name = GetStringFromKeyPair(item, "Name", "string"); + if (name.IsEmpty()) + name = GetStringFromKeyPair(item, "CFName", "string"); + file.Name = name; + dataString = GetStringFromKeyPair(item, "Data", "data"); + + destLen = Base64ToBin(NULL, dataString, dataString.Length()); + file.Raw.SetCapacity(destLen); + Base64ToBin(file.Raw, dataString, dataString.Length()); + } + + if (destLen > 0xCC && Get32(file.Raw) == 0x6D697368) + { + PRF(printf("\n\n index = %d", _files.Size())); + const int kRecordSize = 40; + for (int offset = 0xCC; offset + kRecordSize <= destLen; offset += kRecordSize) + { + const Byte *p = (const Byte *)file.Raw + offset; + CBlock b; + b.Type = Get32(p); + if (b.Type == METHOD_END) + break; + if (b.Type == METHOD_DUMMY) + continue; + + b.UnpPos = Get64(p + 0x08) << 9; + b.UnpSize = Get64(p + 0x10) << 9; + b.PackPos = Get64(p + 0x18); + b.PackSize = Get64(p + 0x20); + + /* + if (startPosIsdefined) + { + } + else + { + startPosIsdefined = true; + startPos = b.PackPos; + } + startPos += b.PackSize; + */ + + file.Blocks.Add(b); + + PRF(printf("\nType=%8x m[1]=%8x uPos=%8x uSize=%7x pPos=%8x pSize=%7x", + b.Type, Get32(p + 4), (UInt32)b.UnpPos, (UInt32)b.UnpSize, (UInt32)b.PackPos, (UInt32)b.PackSize)); + } + } + int itemIndex = _files.Add(file); + if (file.Blocks.Size() > 0) + { + // if (file.Name.Find("HFS") >= 0) + _fileIndices.Add(itemIndex); + } + } + return S_OK; +} + +STDMETHODIMP CHandler::Open(IInStream *stream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback * /* openArchiveCallback */) +{ + COM_TRY_BEGIN + { + Close(); + if (Open2(stream) != S_OK) + return S_FALSE; + _inStream = stream; + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + _inStream.Release(); + _fileIndices.Clear(); + _files.Clear(); + _xml.Empty(); + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _fileIndices.Size() + #ifdef DMG_SHOW_RAW + + _files.Size() + 1; + #endif + ; + return S_OK; +} + +#define RAW_PREFIX L"raw" WSTRING_PATH_SEPARATOR + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + + #ifdef DMG_SHOW_RAW + if ((int)index == _fileIndices.Size()) + { + switch(propID) + { + case kpidPath: + prop = RAW_PREFIX L"a.xml"; + break; + case kpidSize: + case kpidPackedSize: + prop = (UInt64)_xml.Length(); + break; + } + } + else if ((int)index > _fileIndices.Size()) + { + int rawIndex = (int)index - (_fileIndices.Size() + 1); + switch(propID) + { + case kpidPath: + { + wchar_t s[32] = RAW_PREFIX; + ConvertUInt64ToString(rawIndex, s + MyStringLen(s)); + prop = s; + break; + } + case kpidSize: + case kpidPackedSize: + prop = (UInt64)_files[rawIndex].Raw.GetCapacity(); + break; + } + } + else + #endif + { + int itemIndex = _fileIndices[index]; + const CFile &item = _files[itemIndex]; + switch(propID) + { + case kpidMethod: + { + CMethods m; + m.Update(item); + UString resString = m.GetString(); + if (!resString.IsEmpty()) + prop = resString; + break; + } + + // case kpidExtension: prop = L"hfs"; break; + + case kpidPath: + { + // break; + UString name; + wchar_t s[32]; + ConvertUInt64ToString(index, s); + name = s; + int num = 10; + int numDigits; + for (numDigits = 1; num < _fileIndices.Size(); numDigits++) + num *= 10; + while (name.Length() < numDigits) + name = L'0' + name; + + AString subName; + int pos1 = item.Name.Find('('); + if (pos1 >= 0) + { + pos1++; + int pos2 = item.Name.Find(')', pos1); + if (pos2 >= 0) + { + subName = item.Name.Mid(pos1, pos2 - pos1); + pos1 = subName.Find(':'); + if (pos1 >= 0) + subName = subName.Left(pos1); + } + } + subName.Trim(); + if (!subName.IsEmpty()) + { + if (subName == "Apple_HFS") + subName = "hfs"; + else if (subName == "Apple_HFSX") + subName = "hfsx"; + else if (subName == "Apple_Free") + subName = "free"; + else if (subName == "DDM") + subName = "ddm"; + UString name2; + ConvertUTF8ToUnicode(subName, name2); + name += L'.'; + name += name2; + } + else + { + UString name2; + ConvertUTF8ToUnicode(item.Name, name2); + if (!name2.IsEmpty()) + name += L" - "; + name += name2; + } + prop = name; + break; + } + case kpidComment: + { + UString name; + ConvertUTF8ToUnicode(item.Name, name); + prop = name; + break; + } + + case kpidSize: prop = item.GetUnpackSize(); break; + case kpidPackSize: prop = item.GetPackSize(); break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool testMode = (_aTestMode != 0); + bool allFilesMode = (numItems == UInt32(-1)); + if (allFilesMode) + numItems = _files.Size(); + if (numItems == 0) + return S_OK; + UInt64 totalSize = 0; + UInt32 i; + for (i = 0; i < numItems; i++) + { + int index = (int)(allFilesMode ? i : indices[i]); + #ifdef DMG_SHOW_RAW + if (index == _fileIndices.Size()) + totalSize += _xml.Length(); + else if (index > _fileIndices.Size()) + totalSize += _files[index - (_fileIndices.Size() + 1)].Raw.GetCapacity(); + else + #endif + totalSize += _files[_fileIndices[index]].GetUnpackSize(); + } + extractCallback->SetTotal(totalSize); + + UInt64 currentPackTotal = 0; + UInt64 currentUnpTotal = 0; + UInt64 currentPackSize = 0; + UInt64 currentUnpSize = 0; + + const UInt32 kZeroBufSize = (1 << 14); + CByteBuffer zeroBuf; + zeroBuf.SetCapacity(kZeroBufSize); + memset(zeroBuf, 0, kZeroBufSize); + + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); + CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; + + NCompress::NBZip2::CDecoder *bzip2CoderSpec = new NCompress::NBZip2::CDecoder(); + CMyComPtr<ICompressCoder> bzip2Coder = bzip2CoderSpec; + + NCompress::NZlib::CDecoder *zlibCoderSpec = new NCompress::NZlib::CDecoder(); + CMyComPtr<ICompressCoder> zlibCoder = zlibCoderSpec; + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr<ICompressProgressInfo> progress = lps; + lps->Init(extractCallback, false); + + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr<ISequentialInStream> inStream(streamSpec); + streamSpec->SetStream(_inStream); + + for (i = 0; i < numItems; i++, currentPackTotal += currentPackSize, currentUnpTotal += currentUnpSize) + { + lps->InSize = currentPackTotal; + lps->OutSize = currentUnpTotal; + currentPackSize = 0; + currentUnpSize = 0; + RINOK(lps->SetCur()); + CMyComPtr<ISequentialOutStream> realOutStream; + Int32 askMode = testMode ? + NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + Int32 index = allFilesMode ? i : indices[i]; + // const CItemEx &item = _files[index]; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + + + if (!testMode && (!realOutStream)) + continue; + RINOK(extractCallback->PrepareOperation(askMode)); + + CLimitedSequentialOutStream *outStreamSpec = new CLimitedSequentialOutStream; + CMyComPtr<ISequentialOutStream> outStream(outStreamSpec); + outStreamSpec->SetStream(realOutStream); + + realOutStream.Release(); + + Int32 opRes = NArchive::NExtract::NOperationResult::kOK; + #ifdef DMG_SHOW_RAW + if (index > _fileIndices.Size()) + { + const CByteBuffer &buf = _files[index - (_fileIndices.Size() + 1)].Raw; + outStreamSpec->Init(buf.GetCapacity()); + RINOK(WriteStream(outStream, buf, buf.GetCapacity())); + currentPackSize = currentUnpSize = buf.GetCapacity(); + } + else if (index == _fileIndices.Size()) + { + outStreamSpec->Init(_xml.Length()); + RINOK(WriteStream(outStream, (const char *)_xml, _xml.Length())); + currentPackSize = currentUnpSize = _xml.Length(); + } + else + #endif + { + const CFile &item = _files[_fileIndices[index]]; + currentPackSize = item.GetPackSize(); + currentUnpSize = item.GetUnpackSize(); + + UInt64 unpPos = 0; + UInt64 packPos = 0; + { + for (int j = 0; j < item.Blocks.Size(); j++) + { + lps->InSize = currentPackTotal + packPos; + lps->OutSize = currentUnpTotal + unpPos; + RINOK(lps->SetCur()); + + const CBlock &block = item.Blocks[j]; + + packPos += block.PackSize; + if (block.UnpPos != unpPos) + { + opRes = NArchive::NExtract::NOperationResult::kDataError; + break; + } + + RINOK(_inStream->Seek(block.PackPos, STREAM_SEEK_SET, NULL)); + streamSpec->Init(block.PackSize); + // UInt64 startSize = outStreamSpec->GetSize(); + bool realMethod = true; + outStreamSpec->Init(block.UnpSize); + HRESULT res = S_OK; + + switch(block.Type) + { + case METHOD_ZERO_0: + case METHOD_ZERO_2: + realMethod = false; + if (block.PackSize != 0) + opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + break; + + case METHOD_COPY: + if (block.UnpSize != block.PackSize) + { + opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + break; + } + res = copyCoder->Code(inStream, outStream, NULL, NULL, progress); + break; + + case METHOD_ZLIB: + { + res = zlibCoder->Code(inStream, outStream, NULL, NULL, progress); + if (res != S_OK) + break; + break; + } + + case METHOD_BZIP2: + { + res = bzip2Coder->Code(inStream, outStream, NULL, NULL, progress); + if (res == S_OK) + if (streamSpec->GetSize() != block.PackSize) + opRes = NArchive::NExtract::NOperationResult::kDataError; + break; + } + + default: + opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + break; + } + if (res != S_OK) + { + if (res != S_FALSE) + return res; + if (opRes == NArchive::NExtract::NOperationResult::kOK) + opRes = NArchive::NExtract::NOperationResult::kDataError; + } + unpPos += block.UnpSize; + if (!outStreamSpec->IsFinishedOK()) + { + if (realMethod && opRes == NArchive::NExtract::NOperationResult::kOK) + opRes = NArchive::NExtract::NOperationResult::kDataError; + + while (outStreamSpec->GetRem() != 0) + { + UInt64 rem = outStreamSpec->GetRem(); + UInt32 size = (UInt32)MyMin(rem, (UInt64)kZeroBufSize); + RINOK(WriteStream(outStream, zeroBuf, size)); + } + } + } + } + } + outStream.Release(); + RINOK(extractCallback->SetOperationResult(opRes)); + } + return S_OK; + COM_TRY_END +} + +static IInArchive *CreateArc() { return new CHandler; } + +static CArcInfo g_ArcInfo = + { L"Dmg", L"dmg", 0, 0xE4, { 0 }, 0, false, CreateArc, 0 }; + +REGISTER_ARC(Dmg) + +}} diff --git a/CPP/7zip/Archive/ElfHandler.cpp b/CPP/7zip/Archive/ElfHandler.cpp new file mode 100755 index 00000000..952f2273 --- /dev/null +++ b/CPP/7zip/Archive/ElfHandler.cpp @@ -0,0 +1,543 @@ +4// ElfHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#include "Common/Buffer.h" +#include "Common/ComTry.h" +#include "Common/IntToString.h" + +#include "Windows/PropVariantUtils.h" + +#include "../Common/LimitedStreams.h" +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +#include "../Compress/Copy/CopyCoder.h" + +#include "Common/DummyOutStream.h" + +static UInt16 Get16(const Byte *p, int be) { if (be) return GetBe16(p); return GetUi16(p); } +static UInt32 Get32(const Byte *p, int be) { if (be) return GetBe32(p); return GetUi32(p); } +static UInt64 Get64(const Byte *p, int be) { if (be) return GetBe64(p); return GetUi64(p); } + +using namespace NWindows; + +namespace NArchive { +namespace NElf { + +#define ELF_CLASS_32 1 +#define ELF_CLASS_64 2 + +#define ELF_DATA_2LSB 1 +#define ELF_DATA_2MSB 2 + +#define NUM_SCAN_SECTIONS_MAX (1 << 6) + +struct CHeader +{ + bool Mode64; + bool Be; + Byte Os; + Byte AbiVer; + + UInt16 Type; + UInt16 Machine; + // UInt32 Version; + + // UInt64 EntryVa; + UInt64 ProgOffset; + UInt64 SectOffset; + UInt32 Flags; + UInt16 ElfHeaderSize; + UInt16 SegmentEntrySize; + UInt16 NumSegments; + UInt16 SectEntrySize; + UInt16 NumSections; + // UInt16 SectNameStringTableIndex; + + bool Parse(const Byte *buf); + + bool CheckSegmentEntrySize() const + { + return (Mode64 && SegmentEntrySize == 0x38) || (!Mode64 && SegmentEntrySize == 0x20); + }; + + UInt64 GetHeadersSize() const + { return ElfHeaderSize + + (UInt64)SegmentEntrySize * NumSegments + + (UInt64)SectEntrySize * NumSections; } + +}; + +bool CHeader::Parse(const Byte *p) +{ + switch(p[4]) + { + case ELF_CLASS_32: Mode64 = false; break; + case ELF_CLASS_64: Mode64 = true; break; + default: return false; + } + bool be; + switch(p[5]) + { + case ELF_DATA_2LSB: be = false; break; + case ELF_DATA_2MSB: be = true; break; + default: return false; + } + Be = be; + if (p[6] != 1) // Version + return false; + Os = p[7]; + AbiVer = p[8]; + for (int i = 9; i < 16; i++) + if (p[i] != 0) + return false; + + Type = Get16(p + 0x10, be); + Machine = Get16(p + 0x12, be); + if (Get32(p + 0x14, be) != 1) // Version + return false; + + if (Mode64) + { + // EntryVa = Get64(p + 0x18, be); + ProgOffset = Get64(p + 0x20, be); + SectOffset = Get64(p + 0x28, be); + p += 0x30; + } + else + { + // EntryVa = Get32(p + 0x18, be); + ProgOffset = Get32(p + 0x1C, be); + SectOffset = Get32(p + 0x20, be); + p += 0x24; + } + + Flags = Get32(p + 0, be); + ElfHeaderSize = Get16(p + 4, be); + SegmentEntrySize = Get16(p + 6, be); + NumSegments = Get16(p + 8, be); + SectEntrySize = Get16(p + 10, be); + NumSections = Get16(p + 12, be); + // SectNameStringTableIndex = Get16(p + 14, be); + return CheckSegmentEntrySize(); +} + +struct CSegment +{ + UInt32 Type; + UInt32 Flags; + UInt64 Offset; + UInt64 Va; + // UInt64 Pa; + UInt64 PSize; + UInt64 VSize; + // UInt64 Align; + + void UpdateTotalSize(UInt64 &totalSize) + { + UInt64 t = Offset + PSize; + if (t > totalSize) + totalSize = t; + } + void Parse(const Byte *p, bool mode64, bool be); +}; + +void CSegment::Parse(const Byte *p, bool mode64, bool be) +{ + Type = Get32(p, be); + if (mode64) + { + Flags = Get32(p + 4, be); + Offset = Get64(p + 8, be); + Va = Get64(p + 0x10, be); + // Pa = Get64(p + 0x18, be); + PSize = Get64(p + 0x20, be); + VSize = Get64(p + 0x28, be); + // Align = Get64(p + 0x30, be); + } + else + { + Offset = Get32(p + 4, be); + Va = Get32(p + 8, be); + // Pa = Get32(p + 12, be); + PSize = Get32(p + 16, be); + VSize = Get32(p + 20, be); + Flags = Get32(p + 24, be); + // Align = Get32(p + 28, be); + } +} + +static const CUInt32PCharPair g_MachinePairs[] = +{ + { 0, "None" }, + { 1, "AT&T WE 32100" }, + { 2, "SPARC" }, + { 3, "Intel 386" }, + { 4, "Motorola 68000" }, + { 5, "Motorola 88000" }, + { 6, "Intel 486" }, + { 7, "Intel i860" }, + { 8, "MIPS" }, + { 9, "IBM S/370" }, + { 10, "MIPS RS3000 LE" }, + { 11, "RS6000" }, + + { 15, "PA-RISC" }, + { 16, "nCUBE" }, + { 17, "Fujitsu VPP500" }, + { 18, "SPARC 32+" }, + { 19, "Intel i960" }, + { 20, "PowerPC" }, + { 21, "PowerPC 64-bit" }, + { 22, "IBM S/390" }, + + { 36, "NEX v800" }, + { 37, "Fujitsu FR20" }, + { 38, "TRW RH-32" }, + { 39, "Motorola RCE" }, + { 40, "ARM" }, + { 41, "Alpha" }, + { 42, "Hitachi SH" }, + { 43, "SPARC-V9" }, + { 44, "Siemens Tricore" }, + { 45, "ARC" }, + { 46, "H8/300" }, + { 47, "H8/300H" }, + { 48, "H8S" }, + { 49, "H8/500" }, + { 50, "IA-64" }, + { 51, "Stanford MIPS-X" }, + { 52, "Motorola ColdFire" }, + { 53, "M68HC12" }, + { 54, "Fujitsu MMA" }, + { 55, "Siemens PCP" }, + { 56, "Sony nCPU" }, + { 57, "Denso NDR1" }, + { 58, "Motorola StarCore" }, + { 59, "Toyota ME16" }, + { 60, "ST100" }, + { 61, "Advanced Logic TinyJ" }, + { 62, "AMD64" }, + { 63, "Sony DSP" }, + + { 66, "Siemens FX66" }, + { 67, "ST9+" }, + { 68, "ST7" }, + { 69, "MC68HC16" }, + { 70, "MC68HC11" }, + { 71, "MC68HC08" }, + { 72, "MC68HC05" }, + { 73, "Silicon Graphics SVx" }, + { 74, "ST19" }, + { 75, "Digital VAX" }, + { 76, "Axis CRIS" }, + { 77, "Infineon JAVELIN" }, + { 78, "Element 14 FirePath" }, + { 79, "LSI ZSP" }, + { 80, "MMIX" }, + { 81, "HUANY" }, + { 82, "SiTera Prism" }, + { 83, "Atmel AVR" }, + { 84, "Fujitsu FR30" }, + { 85, "Mitsubishi D10V" }, + { 86, "Mitsubishi D30V" }, + { 87, "NEC v850" }, + { 88, "Mitsubishi M32R" }, + { 89, "Matsushita MN10300" }, + { 90, "Matsushita MN10200" }, + { 91, "picoJava" }, + { 92, "OpenRISC" }, + { 93, "ARC Tangent-A5" }, + { 94, "Tensilica Xtensa" }, + { 0x9026, "Alpha" } +}; + +static const CUInt32PCharPair g_AbiOS[] = +{ + { 0, "None" }, + { 1, "HP-UX" }, + { 2, "NetBSD" }, + { 3, "Linux" }, + + { 6, "Solaris" }, + { 7, "AIX" }, + { 8, "IRIX" }, + { 9, "FreeBSD" }, + { 10, "TRU64" }, + { 11, "Novell Modesto" }, + { 12, "OpenBSD" }, + { 13, "OpenVMS" }, + { 14, "HP NSK" }, + { 15, "AROS" }, + { 97, "ARM" }, + { 255, "Standalone" } +}; + +static const CUInt32PCharPair g_SegmentFlags[] = +{ + { 1 << 0, "Execute" }, + { 1 << 1, "Write" }, + { 1 << 2, "Read" } +}; + +static const char *g_Types[] = +{ + "None", + "Relocatable file", + "Executable file", + "Shared object file", + "Core file" +}; + +static const char *g_SegnmentTypes[] = +{ + "Unused", + "Loadable segment", + "Dynamic linking tables", + "Program interpreter path name", + "Note section", + "SHLIB", + "Program header table", + "TLS" +}; + +class CHandler: + public IInArchive, + public CMyUnknownImp +{ + CMyComPtr<IInStream> _inStream; + CObjectVector<CSegment> _sections; + UInt32 _peOffset; + CHeader _header; + UInt64 _totalSize; + HRESULT Open2(IInStream *stream); + bool Parse(const Byte *buf, UInt32 size); +public: + MY_UNKNOWN_IMP1(IInArchive) + INTERFACE_IInArchive(;) +}; + +#define ELF_PT_PHDR 6 + +bool CHandler::Parse(const Byte *buf, UInt32 size) +{ + if (size < 64) + return false; + if (!_header.Parse(buf)) + return false; + if (_header.ProgOffset > size || + _header.ProgOffset + (UInt64)_header.SegmentEntrySize * _header.NumSegments > size || + _header.NumSegments > NUM_SCAN_SECTIONS_MAX) + return false; + const Byte *p = buf + _header.ProgOffset; + _totalSize = _header.ProgOffset; + + for (int i = 0; i < _header.NumSegments; i++, p += _header.SegmentEntrySize) + { + CSegment sect; + sect.Parse(p, _header.Mode64, _header.Be); + sect.UpdateTotalSize(_totalSize); + if (sect.Type != ELF_PT_PHDR) + _sections.Add(sect); + } + UInt64 total2 = _header.SectOffset + (UInt64)_header.SectEntrySize * _header.NumSections; + if (total2 > _totalSize) + _totalSize = total2; + return true; +} + +STATPROPSTG kArcProps[] = +{ + { NULL, kpidCpu, VT_BSTR}, + { NULL, kpidBit64, VT_BOOL}, + { NULL, kpidBigEndian, VT_BOOL}, + { NULL, kpidHostOS, VT_BSTR}, + { NULL, kpidCharacts, VT_BSTR}, + { NULL, kpidPhySize, VT_UI8}, + { NULL, kpidHeadersSize, VT_UI8} + }; + +STATPROPSTG kProps[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackSize, VT_UI8}, + { NULL, kpidType, VT_BSTR}, + { NULL, kpidCharacts, VT_BSTR}, + { NULL, kpidOffset, VT_UI8}, + { NULL, kpidVa, VT_UI8} +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + switch(propID) + { + case kpidPhySize: prop = _totalSize; break; + case kpidHeadersSize: prop = _header.GetHeadersSize(); break; + case kpidBit64: if (_header.Mode64) prop = _header.Mode64; break; + case kpidBigEndian: if (_header.Be) prop = _header.Be; break; + case kpidCpu: PAIR_TO_PROP(g_MachinePairs, _header.Machine, prop); break; + case kpidHostOS: PAIR_TO_PROP(g_AbiOS, _header.Os, prop); break; + case kpidCharacts: TYPE_TO_PROP(g_Types, _header.Type, prop); break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + const CSegment &item = _sections[index]; + switch(propID) + { + case kpidPath: + { + wchar_t sz[32]; + ConvertUInt64ToString(index, sz); + prop = sz; + break; + } + case kpidSize: prop = (UInt64)item.VSize; break; + case kpidPackSize: prop = (UInt64)item.PSize; break; + case kpidOffset: prop = item.Offset; break; + case kpidVa: prop = item.Va; break; + case kpidType: TYPE_TO_PROP(g_SegnmentTypes, item.Type, prop); break; + case kpidCharacts: FLAGS_TO_PROP(g_SegmentFlags, item.Flags, prop); break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +HRESULT CHandler::Open2(IInStream *stream) +{ + const UInt32 kBufSize = 1 << 18; + const UInt32 kSigSize = 4; + + CByteBuffer buffer; + buffer.SetCapacity(kBufSize); + Byte *buf = buffer; + + size_t processed = kSigSize; + RINOK(ReadStream_FALSE(stream, buf, processed)); + if (buf[0] != 0x7F || buf[1] != 'E' || buf[2] != 'L' || buf[3] != 'F') + return S_FALSE; + processed = kBufSize - kSigSize; + RINOK(ReadStream(stream, buf + kSigSize, &processed)); + processed += kSigSize; + if (!Parse(buf, (UInt32)processed)) + return S_FALSE; + UInt64 fileSize; + RINOK(stream->Seek(0, STREAM_SEEK_END, &fileSize)); + return (fileSize == _totalSize) ? S_OK : S_FALSE; +} + +STDMETHODIMP CHandler::Open(IInStream *inStream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback * /* openArchiveCallback */) +{ + COM_TRY_BEGIN + Close(); + RINOK(Open2(inStream)); + _inStream = inStream; + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + _inStream.Release(); + _sections.Clear(); + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _sections.Size(); + return S_OK; +} + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool testMode = (_aTestMode != 0); + bool allFilesMode = (numItems == UInt32(-1)); + if (allFilesMode) + numItems = _sections.Size(); + if (numItems == 0) + return S_OK; + UInt64 totalSize = 0; + UInt32 i; + for (i = 0; i < numItems; i++) + totalSize += _sections[allFilesMode ? i : indices[i]].PSize; + extractCallback->SetTotal(totalSize); + + UInt64 currentTotalSize = 0; + UInt64 currentItemSize; + + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); + CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr<ICompressProgressInfo> progress = lps; + lps->Init(extractCallback, false); + + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr<ISequentialInStream> inStream(streamSpec); + streamSpec->SetStream(_inStream); + + CDummyOutStream *outStreamSpec = new CDummyOutStream; + CMyComPtr<ISequentialOutStream> outStream(outStreamSpec); + + for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) + { + lps->InSize = lps->OutSize = currentTotalSize; + RINOK(lps->SetCur()); + Int32 askMode = testMode ? + NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + UInt32 index = allFilesMode ? i : indices[i]; + const CSegment &item = _sections[index]; + currentItemSize = item.PSize; + { + CMyComPtr<ISequentialOutStream> realOutStream; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + if (!testMode && (!realOutStream)) + continue; + outStreamSpec->SetStream(realOutStream); + outStreamSpec->Init(); + } + + RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(_inStream->Seek(item.Offset, STREAM_SEEK_SET, NULL)); + streamSpec->Init(currentItemSize); + RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); + outStreamSpec->ReleaseStream(); + RINOK(extractCallback->SetOperationResult(copyCoderSpec->TotalSize == currentItemSize ? + NArchive::NExtract::NOperationResult::kOK: + NArchive::NExtract::NOperationResult::kDataError)); + } + return S_OK; + COM_TRY_END +} + +static IInArchive *CreateArc() { return new CHandler; } + +static CArcInfo g_ArcInfo = + { L"ELF", L"", 0, 0xDE, { 0 }, 0, false, CreateArc, 0 }; + +REGISTER_ARC(Elf) + +}} diff --git a/CPP/7zip/Archive/GZip/GZipHandler.cpp b/CPP/7zip/Archive/GZip/GZipHandler.cpp index 48d85fa4..96ae85f1 100755 --- a/CPP/7zip/Archive/GZip/GZipHandler.cpp +++ b/CPP/7zip/Archive/GZip/GZipHandler.cpp @@ -22,7 +22,7 @@ namespace NGZip { static const CMethodId kMethodId_Deflate = 0x040108; -const wchar_t *kHostOS[] = +const wchar_t *kHostOS[] = { L"FAT", L"AMIGA", @@ -34,14 +34,14 @@ const wchar_t *kHostOS[] = L"Mac", L"Z_System", L"CPM", - L"TOPS20", // pkzip 2.50 NTFS - L"NTFS", // filesystem used by Windows NT + L"TOPS20", // pkzip 2.50 NTFS + L"NTFS", // filesystem used by Windows NT L"QDOS ", // SMS/QDOS L"Acorn", // Archimedes Acorn RISC OS L"VFAT", // filesystem used by Windows 95, NT L"MVS", L"BeOS", // hybrid POSIX/database filesystem - // BeBOX or PowerMac + // BeBOX or PowerMac L"Tandem", L"THEOS" }; @@ -59,16 +59,14 @@ enum // PropID }; */ -STATPROPSTG kProps[] = +STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, { NULL, kpidSize, VT_UI8}, - { NULL, kpidPackedSize, VT_UI8}, - - { NULL, kpidLastWriteTime, VT_FILETIME}, + { NULL, kpidPackSize, VT_UI8}, + { NULL, kpidMTime, VT_FILETIME}, // { NULL, kpidMethod, VT_UI1}, { NULL, kpidHostOS, VT_BSTR}, - { NULL, kpidCRC, VT_UI4} // { L"Extra", kpidExtraIsPresent, VT_BOOL} // { L"Extra flags", kpidExtraFlags, VT_UI1}, @@ -94,7 +92,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIA if (m_Item.NameIsPresent()) prop = MultiByteToUnicodeString(m_Item.Name, CP_ACP); break; - case kpidLastWriteTime: + case kpidMTime: { FILETIME utcTime; if (m_Item.Time != 0) @@ -109,35 +107,19 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIA } break; } - case kpidSize: - prop = UInt64(m_Item.UnPackSize32); - break; - case kpidPackedSize: - prop = m_PackSize; - break; - case kpidCommented: - prop = m_Item.CommentIsPresent(); - break; + case kpidSize: prop = UInt64(m_Item.UnPackSize32); break; + case kpidPackSize: prop = m_PackSize; break; + case kpidCommented: prop = m_Item.CommentIsPresent(); break; case kpidHostOS: prop = (m_Item.HostOS < kNumHostOSes) ? kHostOS[m_Item.HostOS] : kUnknownOS; break; - case kpidMethod: - prop = m_Item.CompressionMethod; - break; - case kpidCRC: - prop = m_Item.FileCRC; - break; + case kpidMethod: prop = m_Item.CompressionMethod; break; + case kpidCRC: prop = m_Item.FileCRC; break; /* - case kpidExtraFlags: - prop = m_Item.ExtraFlags; - break; - case kpidIsText: - prop = m_Item.IsText(); - break; - case kpidExtraIsPresent: - prop = m_Item.ExtraFieldIsPresent(); - break; + case kpidExtraFlags: prop = m_Item.ExtraFlags; break; + case kpidIsText: prop = m_Item.IsText(); break; + case kpidExtraIsPresent: prop = m_Item.ExtraFieldIsPresent(); break; */ } prop.Detach(value); @@ -145,7 +127,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIA COM_TRY_END } -STDMETHODIMP CHandler::Open(IInStream *inStream, +STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 * /* maxCheckStartPosition */, IArchiveOpenCallback * /* openArchiveCallback */) { @@ -155,7 +137,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, CInArchive archive; RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_StreamStartPosition)); RINOK(archive.ReadHeader(inStream, m_Item)); - m_DataOffset = archive.GetOffset(); + m_DataOffset = archive.GetOffset(); UInt64 newPosition; RINOK(inStream->Seek(-8, STREAM_SEEK_END, &newPosition)); m_PackSize = newPosition - (m_StreamStartPosition + m_DataOffset); @@ -274,7 +256,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, } CMyComPtr<ICompressGetInStreamProcessedSize> getInStreamProcessedSize; - RINOK(deflateDecoder.QueryInterface(IID_ICompressGetInStreamProcessedSize, + RINOK(deflateDecoder.QueryInterface(IID_ICompressGetInStreamProcessedSize, &getInStreamProcessedSize)); UInt64 packSize; RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&packSize)); diff --git a/CPP/7zip/Archive/GZip/GZipHandler.h b/CPP/7zip/Archive/GZip/GZipHandler.h index 3f5a1acd..49a01a8d 100755 --- a/CPP/7zip/Archive/GZip/GZipHandler.h +++ b/CPP/7zip/Archive/GZip/GZipHandler.h @@ -15,7 +15,7 @@ namespace NArchive { namespace NGZip { -class CHandler: +class CHandler: public IInArchive, public IOutArchive, public ISetProperties, @@ -53,7 +53,7 @@ private: void InitMethodProperties() { m_Method.NumMatchFinderCyclesDefined = false; - m_Level = m_Method.NumPasses = m_Method.NumFastBytes = + m_Level = m_Method.NumPasses = m_Method.NumFastBytes = m_Method.NumMatchFinderCycles = m_Method.Algo = 0xFFFFFFFF; } }; diff --git a/CPP/7zip/Archive/GZip/GZipHandlerOut.cpp b/CPP/7zip/Archive/GZip/GZipHandlerOut.cpp index f2776adb..1fb1547d 100755 --- a/CPP/7zip/Archive/GZip/GZipHandlerOut.cpp +++ b/CPP/7zip/Archive/GZip/GZipHandlerOut.cpp @@ -9,7 +9,6 @@ #include "Common/StringToInt.h" #include "Windows/Time.h" -#include "Windows/FileFind.h" #include "Windows/PropVariant.h" #include "../../Compress/Copy/CopyCoder.h" @@ -65,23 +64,11 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt newItem.Flags = 0; if (IntToBool(newProperties)) { - UInt32 attributes; FILETIME utcTime; UString name; - bool isDirectory; { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(itemIndex, kpidAttributes, &prop)); - if (prop.vt == VT_EMPTY) - attributes = 0; - else if (prop.vt != VT_UI4) - return E_INVALIDARG; - else - attributes = prop.ulVal; - } - { - NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(itemIndex, kpidLastWriteTime, &prop)); + RINOK(updateCallback->GetProperty(itemIndex, kpidMTime, &prop)); if (prop.vt != VT_FILETIME) return E_INVALIDARG; utcTime = prop.filetime; @@ -98,16 +85,15 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt } { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(itemIndex, kpidIsFolder, &prop)); - if (prop.vt == VT_EMPTY) - isDirectory = false; - else if (prop.vt != VT_BOOL) + RINOK(updateCallback->GetProperty(itemIndex, kpidIsDir, &prop)); + if (prop.vt == VT_BOOL) + { + if (prop.boolVal != VARIANT_FALSE) + return E_INVALIDARG; + } + else if (prop.vt != VT_EMPTY) return E_INVALIDARG; - else - isDirectory = (prop.boolVal != VARIANT_FALSE); } - if (isDirectory || NFile::NFind::NAttributes::IsDirectory(attributes)) - return E_INVALIDARG; if(!FileTimeToUnixTime(utcTime, newItem.Time)) return E_INVALIDARG; newItem.Name = UnicodeStringToMultiByte(name, CP_ACP); @@ -133,17 +119,17 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt if (level == 0xFFFFFFFF) level = 5; if (m_Method.NumPasses == 0xFFFFFFFF) - m_Method.NumPasses = (level >= 9 ? kNumPassesX9 : - (level >= 7 ? kNumPassesX7 : + m_Method.NumPasses = (level >= 9 ? kNumPassesX9 : + (level >= 7 ? kNumPassesX7 : kNumPassesX1)); if (m_Method.NumFastBytes == 0xFFFFFFFF) - m_Method.NumFastBytes = (level >= 9 ? kNumFastBytesX9 : - (level >= 7 ? kNumFastBytesX7 : + m_Method.NumFastBytes = (level >= 9 ? kNumFastBytesX9 : + (level >= 7 ? kNumFastBytesX7 : kNumFastBytesX1)); if (m_Method.Algo == 0xFFFFFFFF) - m_Method.Algo = - (level >= 5 ? kAlgoX5 : - kAlgoX1); + m_Method.Algo = + (level >= 5 ? kAlgoX5 : + kAlgoX1); return UpdateArchive( EXTERNAL_CODECS_VARS @@ -210,6 +196,6 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v return E_INVALIDARG; } return S_OK; -} +} }} diff --git a/CPP/7zip/Archive/GZip/GZipHeader.cpp b/CPP/7zip/Archive/GZip/GZipHeader.cpp index 5e697fa9..88b34e86 100755 --- a/CPP/7zip/Archive/GZip/GZipHeader.cpp +++ b/CPP/7zip/Archive/GZip/GZipHeader.cpp @@ -12,7 +12,7 @@ extern UInt16 kSignature = 0x8B1F + 1; static class CMarkersInitializer { public: - CMarkersInitializer() + CMarkersInitializer() { kSignature--; } } g_MarkerInitializer; diff --git a/CPP/7zip/Archive/GZip/GZipHeader.h b/CPP/7zip/Archive/GZip/GZipHeader.h index e83548eb..010a60aa 100755 --- a/CPP/7zip/Archive/GZip/GZipHeader.h +++ b/CPP/7zip/Archive/GZip/GZipHeader.h @@ -25,7 +25,7 @@ namespace NFileHeader }; */ - namespace NFlags + namespace NFlags { const int kDataIsText = 1 << 0; const int kHeaderCRCIsPresent = 1 << 1; @@ -34,7 +34,7 @@ namespace NFileHeader const int kComentIsPresent = 1 << 4; } - namespace NExtraFlags + namespace NExtraFlags { enum EEnum { @@ -52,7 +52,7 @@ namespace NFileHeader { enum EEnum { - kFAT = 0, // filesystem used by MS-DOS, OS/2, Win32 + kFAT = 0, // filesystem used by MS-DOS, OS/2, Win32 // pkzip 2.50 (FAT / VFAT / FAT32 file systems) kAMIGA = 1, kVMS = 2, // VAX/VMS @@ -63,14 +63,14 @@ namespace NFileHeader kMac = 7, kZ_System = 8, kCPM = 9, - kTOPS20 = 10, // pkzip 2.50 NTFS - kNTFS = 11, // filesystem used by Windows NT + kTOPS20 = 10, // pkzip 2.50 NTFS + kNTFS = 11, // filesystem used by Windows NT kQDOS = 12, // SMS/QDOS kAcorn = 13, // Archimedes Acorn RISC OS kVFAT = 14, // filesystem used by Windows 95, NT kMVS = 15, kBeOS = 16, // hybrid POSIX/database filesystem - // BeBOX or PowerMac + // BeBOX or PowerMac kTandem = 17, kTHEOS = 18, diff --git a/CPP/7zip/Archive/GZip/GZipIn.cpp b/CPP/7zip/Archive/GZip/GZipIn.cpp index 33b0ac47..d754c045 100755 --- a/CPP/7zip/Archive/GZip/GZipIn.cpp +++ b/CPP/7zip/Archive/GZip/GZipIn.cpp @@ -10,9 +10,9 @@ #include "../../Common/StreamUtils.h" -extern "C" -{ - #include "../../../../C/7zCrc.h" +extern "C" +{ + #include "../../../../C/7zCrc.h" } namespace NArchive { diff --git a/CPP/7zip/Archive/GZip/GZipItem.h b/CPP/7zip/Archive/GZip/GZipItem.h index cd5e59f0..678962a9 100755 --- a/CPP/7zip/Archive/GZip/GZipItem.h +++ b/CPP/7zip/Archive/GZip/GZipItem.h @@ -39,7 +39,7 @@ public: { return TestFlag(NFileHeader::NFlags::kComentIsPresent); } void SetNameIsPresentFlag(bool nameIsPresent) - { + { if (nameIsPresent) Flags |= NFileHeader::NFlags::kNameIsPresent; else diff --git a/CPP/7zip/Archive/GZip/GZipRegister.cpp b/CPP/7zip/Archive/GZip/GZipRegister.cpp index e293cfc3..b4bc6ded 100755 --- a/CPP/7zip/Archive/GZip/GZipRegister.cpp +++ b/CPP/7zip/Archive/GZip/GZipRegister.cpp @@ -13,6 +13,6 @@ static IOutArchive *CreateArcOut() { return new NArchive::NGZip::CHandler; } #endif static CArcInfo g_ArcInfo = - { L"GZip", L"gz gzip tgz tpz", L"* * .tar .tar", 0xEF, { 0x1F, 0x8B }, 2, true, CreateArc, CreateArcOut }; + { L"GZip", L"gz gzip tgz tpz", L"* * .tar .tar", 0xEF, { 0x1F, 0x8B, 8 }, 3, true, CreateArc, CreateArcOut }; REGISTER_ARC(GZip) diff --git a/CPP/7zip/Archive/GZip/GZipUpdate.cpp b/CPP/7zip/Archive/GZip/GZipUpdate.cpp index 1f5ebd0e..8f8a2c4f 100755 --- a/CPP/7zip/Archive/GZip/GZipUpdate.cpp +++ b/CPP/7zip/Archive/GZip/GZipUpdate.cpp @@ -22,11 +22,16 @@ namespace NGZip { static const CMethodId kMethodId_Deflate = 0x040108; -static const Byte kHostOS = NFileHeader::NHostOS::kFAT; +static const Byte kHostOS = + #ifdef _WIN32 + NFileHeader::NHostOS::kFAT; + #else + NFileHeader::NHostOS::kUnix; + #endif HRESULT UpdateArchive( DECL_EXTERNAL_CODECS_LOC_VARS - IInStream * /* inStream */, + IInStream * /* inStream */, UInt64 unpackSize, ISequentialOutStream *outStream, const CItem &newItem, @@ -73,17 +78,17 @@ HRESULT UpdateArchive( if (!deflateEncoder) return E_NOTIMPL; - NWindows::NCOM::CPropVariant properties[] = - { - compressionMethod.Algo, - compressionMethod.NumPasses, + NWindows::NCOM::CPropVariant properties[] = + { + compressionMethod.Algo, + compressionMethod.NumPasses, compressionMethod.NumFastBytes, compressionMethod.NumMatchFinderCycles }; - PROPID propIDs[] = - { + PROPID propIDs[] = + { NCoderPropID::kAlgorithm, - NCoderPropID::kNumPasses, + NCoderPropID::kNumPasses, NCoderPropID::kNumFastBytes, NCoderPropID::kMatchFinderCycles }; diff --git a/CPP/7zip/Archive/GZip/GZipUpdate.h b/CPP/7zip/Archive/GZip/GZipUpdate.h index 27a396bf..231d7972 100755 --- a/CPP/7zip/Archive/GZip/GZipUpdate.h +++ b/CPP/7zip/Archive/GZip/GZipUpdate.h @@ -24,7 +24,7 @@ struct CCompressionMethodMode HRESULT UpdateArchive( DECL_EXTERNAL_CODECS_LOC_VARS - IInStream *inStream, + IInStream *inStream, UInt64 unpackSize, ISequentialOutStream *outStream, const CItem &newItem, diff --git a/CPP/7zip/Archive/GZip/StdAfx.cpp b/CPP/7zip/Archive/GZip/StdAfx.cpp deleted file mode 100755 index d0feea85..00000000 --- a/CPP/7zip/Archive/GZip/StdAfx.cpp +++ /dev/null @@ -1,3 +0,0 @@ -// StdAfx.cpp - -#include "StdAfx.h" diff --git a/CPP/7zip/Archive/Hfs/HfsHandler.cpp b/CPP/7zip/Archive/Hfs/HfsHandler.cpp new file mode 100755 index 00000000..ade53877 --- /dev/null +++ b/CPP/7zip/Archive/Hfs/HfsHandler.cpp @@ -0,0 +1,244 @@ +// HfsHandler.cpp + +#include "StdAfx.h" + +#include "Common/ComTry.h" +#include "Windows/PropVariant.h" +#include "../../Common/StreamUtils.h" +#include "HfsHandler.h" + +namespace NArchive { +namespace NHfs { + +STATPROPSTG kProps[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidIsDir, VT_BOOL}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackSize, VT_UI8}, + { NULL, kpidCTime, VT_FILETIME}, + { NULL, kpidMTime, VT_FILETIME}, + { NULL, kpidATime, VT_FILETIME} +}; + +STATPROPSTG kArcProps[] = +{ + { NULL, kpidMethod, VT_BSTR}, + { NULL, kpidClusterSize, VT_UI4}, + { NULL, kpidFreeSpace, VT_UI8}, + { NULL, kpidCTime, VT_FILETIME}, + { NULL, kpidMTime, VT_FILETIME} +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +static void HfsTimeToProp(UInt32 hfsTime, NWindows::NCOM::CPropVariant &prop) +{ + FILETIME ft; + HfsTimeToFileTime(hfsTime, ft); + prop = ft; +} + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch(propID) + { + case kpidMethod: prop = _db.Header.IsHfsX() ? L"HFSX" : L"HFS+"; break; + case kpidClusterSize: prop = (UInt32)1 << _db.Header.BlockSizeLog; break; + case kpidFreeSpace: prop = (UInt64)_db.Header.NumFreeBlocks << _db.Header.BlockSizeLog; break; + case kpidMTime: HfsTimeToProp(_db.Header.MTime, prop); break; + case kpidCTime: + { + FILETIME localFt, ft; + HfsTimeToFileTime(_db.Header.CTime, localFt); + if (LocalFileTimeToFileTime(&localFt, &ft)) + prop = ft; + break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + const CItem &item = _db.Items[index]; + switch(propID) + { + case kpidPath: prop = _db.GetItemPath(index); break; + case kpidIsDir: prop = item.IsDir(); break; + + case kpidCTime: HfsTimeToProp(item.CTime, prop); break; + case kpidMTime: HfsTimeToProp(item.MTime, prop); break; + case kpidATime: HfsTimeToProp(item.ATime, prop); break; + + case kpidPackSize: if (!item.IsDir()) prop = (UInt64)item.NumBlocks << _db.Header.BlockSizeLog; break; + case kpidSize: if (!item.IsDir()) prop = item.Size; break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +class CProgressImp: public CProgressVirt +{ + CMyComPtr<IArchiveOpenCallback> _callback; +public: + HRESULT SetTotal(UInt64 numFiles); + HRESULT SetCompleted(UInt64 numFiles); + CProgressImp(IArchiveOpenCallback *callback): _callback(callback) {} +}; + +HRESULT CProgressImp::SetTotal(UInt64 numFiles) +{ + if (_callback) + return _callback->SetTotal(&numFiles, NULL); + return S_OK; +} + +HRESULT CProgressImp::SetCompleted(UInt64 numFiles) +{ + if (_callback) + return _callback->SetCompleted(&numFiles, NULL); + return S_OK; +} + +STDMETHODIMP CHandler::Open(IInStream *inStream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback *callback) +{ + COM_TRY_BEGIN + Close(); + try + { + CProgressImp progressImp(callback); + HRESULT res = _db.Open(inStream, &progressImp); + if (res == E_ABORT) + return res; + if (res != S_OK) + return S_FALSE; + _stream = inStream; + } + catch(...) { return S_FALSE; } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + _stream.Release(); + _db.Clear(); + return S_OK; +} + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool testMode = (_aTestMode != 0); + bool allFilesMode = (numItems == UInt32(-1)); + if (allFilesMode) + numItems = _db.Items.Size(); + if (numItems == 0) + return S_OK; + UInt32 i; + UInt64 totalSize = 0; + for (i = 0; i < numItems; i++) + { + const CItem &item = _db.Items[allFilesMode ? i : indices[i]]; + if (!item.IsDir()) + totalSize += item.Size; + } + RINOK(extractCallback->SetTotal(totalSize)); + + UInt64 currentTotalSize = 0, currentItemSize = 0; + + CByteBuffer buf; + const UInt32 kBufSize = (1 << 16); + buf.SetCapacity(kBufSize); + + for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) + { + RINOK(extractCallback->SetCompleted(¤tTotalSize)); + Int32 index = allFilesMode ? i : indices[i]; + const CItem &item = _db.Items[index]; + currentItemSize = 0; + if (!item.IsDir()) + currentItemSize = item.Size; + + CMyComPtr<ISequentialOutStream> realOutStream; + Int32 askMode = testMode ? + NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + + if (item.IsDir()) + { + RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + continue; + } + if (!testMode && (!realOutStream)) + continue; + RINOK(extractCallback->PrepareOperation(askMode)); + UInt64 pos = 0; + int res = NArchive::NExtract::NOperationResult::kOK; + int i; + for (i = 0; i < item.Extents.Size(); i++) + { + if (item.Size == pos) + break; + if (res != NArchive::NExtract::NOperationResult::kOK) + break; + const CExtent &e = item.Extents[i]; + RINOK(_stream->Seek((UInt64)e.Pos << _db.Header.BlockSizeLog, STREAM_SEEK_SET, NULL)); + UInt64 extentSize = (UInt64)e.NumBlocks << _db.Header.BlockSizeLog; + for (;;) + { + if (extentSize == 0) + break; + UInt64 rem = item.Size - pos; + if (rem == 0) + { + if (extentSize >= (UInt64)((UInt32)1 << _db.Header.BlockSizeLog)) + res = NArchive::NExtract::NOperationResult::kDataError; + break; + } + UInt32 curSize = kBufSize; + if (curSize > rem) + curSize = (UInt32)rem; + if (curSize > extentSize) + curSize = (UInt32)extentSize; + RINOK(ReadStream_FALSE(_stream, buf, curSize)); + if (realOutStream) + { + RINOK(WriteStream(realOutStream, buf, curSize)); + } + pos += curSize; + extentSize -= curSize; + UInt64 processed = currentTotalSize + pos; + RINOK(extractCallback->SetCompleted(&processed)); + } + } + if (i != item.Extents.Size() || item.Size != pos) + res = NArchive::NExtract::NOperationResult::kDataError; + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(res)); + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _db.Items.Size(); + return S_OK; +} + +}} diff --git a/CPP/7zip/Archive/Arj/ArjHandler.h b/CPP/7zip/Archive/Hfs/HfsHandler.h index 4351b26f..269af218 100755 --- a/CPP/7zip/Archive/Arj/ArjHandler.h +++ b/CPP/7zip/Archive/Hfs/HfsHandler.h @@ -1,27 +1,24 @@ -// ArjHandler.h +// HfsHandler.h -#ifndef __ARJ_HANDLER_H -#define __ARJ_HANDLER_H +#ifndef __ARCHIVE_HFS_HANDLER_H +#define __ARCHIVE_HFS_HANDLER_H #include "Common/MyCom.h" #include "../IArchive.h" -#include "ArjIn.h" +#include "HfsIn.h" namespace NArchive { -namespace NArj { +namespace NHfs { -class CHandler: +class CHandler: public IInArchive, public CMyUnknownImp { + CMyComPtr<IInStream> _stream; + CDatabase _db; public: MY_UNKNOWN_IMP1(IInArchive) - INTERFACE_IInArchive(;) - -private: - CObjectVector<CItemEx> _items; - CMyComPtr<IInStream> _stream; }; }} diff --git a/CPP/7zip/Archive/Hfs/HfsIn.cpp b/CPP/7zip/Archive/Hfs/HfsIn.cpp new file mode 100755 index 00000000..8391dd93 --- /dev/null +++ b/CPP/7zip/Archive/Hfs/HfsIn.cpp @@ -0,0 +1,480 @@ +// HfsIn.cpp + +#include "StdAfx.h" + +#include "../../Common/StreamUtils.h" +#include "Common/IntToString.h" + +#include "HfsIn.h" + +#include "../../../../C/CpuArch.h" + +#define Get16(p) GetBe16(p) +#define Get32(p) GetBe32(p) +#define Get64(p) GetBe64(p) + +namespace NArchive { +namespace NHfs { + +#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } + +static int CompareIdToIndex(const CIdIndexPair *p1, const CIdIndexPair *p2, void * /* param */) +{ + RINOZ(MyCompare(p1->ID, p2->ID)); + return MyCompare(p1->Index, p2->Index); +} + +bool operator< (const CIdIndexPair &a1, const CIdIndexPair &a2) { return (a1.ID < a2.ID); } +bool operator> (const CIdIndexPair &a1, const CIdIndexPair &a2) { return (a1.ID > a2.ID); } +bool operator==(const CIdIndexPair &a1, const CIdIndexPair &a2) { return (a1.ID == a2.ID); } +bool operator!=(const CIdIndexPair &a1, const CIdIndexPair &a2) { return (a1.ID != a2.ID); } + +static UString GetSpecName(const UString &name, UInt32 /* id */) +{ + UString name2 = name; + name2.Trim(); + if (name2.IsEmpty()) + { + /* + wchar_t s[32]; + ConvertUInt64ToString(id, s); + return L"[" + (UString)s + L"]"; + */ + return L"[]"; + } + return name; +} + +UString CDatabase::GetItemPath(int index) const +{ + const CItem *item = &Items[index]; + UString name = GetSpecName(item->Name, item->ID); + + for (int i = 0; i < 1000; i++) + { + if (item->ParentID < 16 && item->ParentID != 2) + { + if (item->ParentID != 1) + break; + return name; + } + CIdIndexPair pair; + pair.ID = item->ParentID; + pair.Index = 0; + int indexInMap = IdToIndexMap.FindInSorted(pair); + if (indexInMap < 0) + break; + item = &Items[IdToIndexMap[indexInMap].Index]; + name = GetSpecName(item->Name, item->ID) + WCHAR_PATH_SEPARATOR + name; + } + return (UString)L"Unknown" + WCHAR_PATH_SEPARATOR + name; +} + +void CFork::Parse(const Byte *p) +{ + Size = Get64(p); + // ClumpSize = Get32(p + 8); + NumBlocks = Get32(p + 0xC); + for (int i = 0; i < 8; i++) + { + CExtent &e = Extents[i]; + e.Pos = Get32(p + 0x10 + i * 8); + e.NumBlocks = Get32(p + 0x10 + i * 8 + 4); + } +} + +static HRESULT ReadExtent(int blockSizeLog, IInStream *inStream, Byte *buf, const CExtent &e) +{ + RINOK(inStream->Seek((UInt64)e.Pos << blockSizeLog, STREAM_SEEK_SET, NULL)); + return ReadStream_FALSE(inStream, buf, (size_t)e.NumBlocks << blockSizeLog); +} + +HRESULT CDatabase::ReadFile(const CFork &fork, CByteBuffer &buf, IInStream *inStream) +{ + if (fork.NumBlocks >= Header.NumBlocks) + return S_FALSE; + size_t totalSize = (size_t)fork.NumBlocks << Header.BlockSizeLog; + if ((totalSize >> Header.BlockSizeLog) != fork.NumBlocks) + return S_FALSE; + buf.SetCapacity(totalSize); + UInt32 curBlock = 0; + for (int i = 0; i < 8; i++) + { + if (curBlock >= fork.NumBlocks) + break; + const CExtent &e = fork.Extents[i]; + if (fork.NumBlocks - curBlock < e.NumBlocks || e.Pos >= Header.NumBlocks) + return S_FALSE; + RINOK(ReadExtent(Header.BlockSizeLog, inStream, + (Byte *)buf + ((size_t)curBlock << Header.BlockSizeLog), e)); + curBlock += e.NumBlocks; + } + return S_OK; +} + +struct CNodeDescriptor +{ + UInt32 fLink; + UInt32 bLink; + Byte Kind; + Byte Height; + UInt16 NumRecords; + // UInt16 Reserved; + void Parse(const Byte *p); +}; + +void CNodeDescriptor::Parse(const Byte *p) +{ + fLink = Get32(p); + bLink = Get32(p + 4); + Kind = p[8]; + Height = p[9]; + NumRecords = Get16(p + 10); +} + +struct CHeaderRec +{ + // UInt16 TreeDepth; + // UInt32 RootNode; + // UInt32 LeafRecords; + UInt32 FirstLeafNode; + // UInt32 LastLeafNode; + int NodeSizeLog; + // UInt16 MaxKeyLength; + UInt32 TotalNodes; + // UInt32 FreeNodes; + // UInt16 Reserved1; + // UInt32 ClumpSize; + // Byte BtreeType; + // Byte KeyCompareType; + // UInt32 Attributes; + // UInt32 Reserved3[16]; + + HRESULT Parse(const Byte *p); +}; + +HRESULT CHeaderRec::Parse(const Byte *p) +{ + // TreeDepth = Get16(p); + // RootNode = Get32(p + 2); + // LeafRecords = Get32(p + 6); + FirstLeafNode = Get32(p + 0xA); + // LastLeafNode = Get32(p + 0xE); + UInt32 nodeSize = Get16(p + 0x12); + + int i; + for (i = 9; ((UInt32)1 << i) != nodeSize; i++) + if (i == 16) + return S_FALSE; + NodeSizeLog = i; + + // MaxKeyLength = Get16(p + 0x14); + TotalNodes = Get32(p + 0x16); + // FreeNodes = Get32(p + 0x1A); + // Reserved1 = Get16(p + 0x1E); + // ClumpSize = Get32(p + 0x20); + // BtreeType = p[0x24]; + // KeyCompareType = p[0x25]; + // Attributes = Get32(p + 0x26); + /* + for (int i = 0; i < 16; i++) + Reserved3[i] = Get32(p + 0x2A + i * 4); + */ + return S_OK; +} + + +enum ENodeType +{ + NODE_TYPE_LEAF = 0xFF, + NODE_TYPE_INDEX = 0, + NODE_TYPE_HEADER = 1, + NODE_TYPE_MODE = 2 +}; + +HRESULT CDatabase::LoadExtentFile(IInStream *inStream) +{ + // FileExtents.Clear(); + // ResExtents.Clear(); + + CByteBuffer extents; + RINOK(ReadFile(Header.ExtentsFile, extents, inStream)); + + const Byte *p = (const Byte *)extents; + + // CNodeDescriptor nodeDesc; + // nodeDesc.Parse(p); + CHeaderRec hr; + RINOK(hr.Parse(p + 14)); + + UInt32 node = hr.FirstLeafNode; + if (node != 0) + return S_FALSE; + /* + while (node != 0) + { + size_t nodeOffset = node * hr.NodeSize; + if ((node + 1)* hr.NodeSize > CatalogBuf.GetCapacity()) + return S_FALSE; + CNodeDescriptor desc; + desc.Parse(p + nodeOffset); + if (desc.Kind != NODE_TYPE_LEAF) + return S_FALSE; + UInt32 ptr = hr.NodeSize; + for (int i = 0; i < desc.NumRecords; i++) + { + UInt32 offs = Get16(p + nodeOffset + hr.NodeSize - (i + 1) * 2); + UInt32 offsNext = Get16(p + nodeOffset + hr.NodeSize - (i + 2) * 2); + + const Byte *r = p + nodeOffset + offs; + int keyLength = Get16(r); + Byte forkType = r[2]; + UInt32 id = Get16(r + 4); + UInt32 startBlock = Get16(r + 4); + CObjectVector<CIdExtents> *extents = (forkType == 0) ? &FileExtents : &ResExtents; + if (extents->Size() == 0) + extents->Add(CIdExtents()); + else + { + CIdExtents &e = extents->Back(); + if (e.ID != id) + { + if (e.ID > id) + return S_FALSE; + extents->Add(CIdExtents()); + } + } + CIdExtents &e = extents->Back(); + for (UInt32 k = offs + 10 + 2; k + 8 <= offsNext; k += 8) + { + CExtent ee; + ee.Pos = Get32(p + nodeOffset + k); + ee.NumBlocks = Get32(p + nodeOffset + k * 4); + e.Extents.Add(ee); + } + } + node = desc.fLink; + } + */ + return S_OK; +} + + +HRESULT CDatabase::LoadCatalog(IInStream *inStream, CProgressVirt *progress) +{ + Items.Clear(); + IdToIndexMap.ClearAndFree(); + + CByteBuffer catalogBuf; + RINOK(ReadFile(Header.CatalogFile, catalogBuf, inStream)); + const Byte *p = (const Byte *)catalogBuf; + + // CNodeDescriptor nodeDesc; + // nodeDesc.Parse(p); + CHeaderRec hr; + hr.Parse(p + 14); + + // CaseSensetive = (Header.IsHfsX() && hr.KeyCompareType == 0xBC); + + if ((catalogBuf.GetCapacity() >> hr.NodeSizeLog) < hr.TotalNodes) + return S_FALSE; + + CByteBuffer usedBuf; + usedBuf.SetCapacity(hr.TotalNodes); + for (UInt32 i = 0; i < hr.TotalNodes; i++) + usedBuf[i] = 0; + + UInt32 node = hr.FirstLeafNode; + while (node != 0) + { + if (node >= hr.TotalNodes) + return S_FALSE; + if (usedBuf[node]) + return S_FALSE; + usedBuf[node] = 1; + size_t nodeOffset = (size_t)node << hr.NodeSizeLog; + CNodeDescriptor desc; + desc.Parse(p + nodeOffset); + if (desc.Kind != NODE_TYPE_LEAF) + return S_FALSE; + for (int i = 0; i < desc.NumRecords; i++) + { + UInt32 nodeSize = (1 << hr.NodeSizeLog); + UInt32 offs = Get16(p + nodeOffset + nodeSize - (i + 1) * 2); + UInt32 offsNext = Get16(p + nodeOffset + nodeSize - (i + 2) * 2); + UInt32 recSize = offsNext - offs; + if (offsNext >= nodeSize || offsNext < offs || recSize < 6) + return S_FALSE; + + CItem item; + + const Byte *r = p + nodeOffset + offs; + UInt32 keyLength = Get16(r); + item.ParentID = Get32(r + 2); + UString name; + if (keyLength < 6 || (keyLength & 1) != 0 || keyLength + 2 > recSize) + return S_FALSE; + r += 6; + recSize -= 6; + keyLength -= 6; + + int nameLength = Get16(r); + if (nameLength * 2 != (int)keyLength) + return S_FALSE; + r += 2; + recSize -= 2; + + wchar_t *pp = name.GetBuffer(nameLength + 1); + + int j; + for (j = 0; j < nameLength; j++) + pp[j] = ((wchar_t)r[j * 2] << 8) | r[j * 2 + 1]; + pp[j] = 0; + name.ReleaseBuffer(); + r += j * 2; + recSize -= j * 2; + + if (recSize < 2) + return S_FALSE; + item.Type = Get16(r); + + if (item.Type != RECORD_TYPE_FOLDER && item.Type != RECORD_TYPE_FILE) + continue; + if (recSize < 0x58) + return S_FALSE; + + // item.Flags = Get16(r + 2); + // item.Valence = Get32(r + 4); + item.ID = Get32(r + 8); + item.CTime = Get32(r + 0xC); + item.MTime = Get32(r + 0x10); + // item.AttrMTime = Get32(r + 0x14); + item.ATime = Get32(r + 0x18); + // item.BackupDate = Get32(r + 0x1C); + + /* + item.OwnerID = Get32(r + 0x20); + item.GroupID = Get32(r + 0x24); + item.AdminFlags = r[0x28]; + item.OwnerFlags = r[0x29]; + item.FileMode = Get16(r + 0x2A); + item.special.iNodeNum = Get16(r + 0x2C); + */ + + item.Name = name; + + if (item.IsDir()) + { + CIdIndexPair pair; + pair.ID = item.ID; + pair.Index = Items.Size(); + IdToIndexMap.Add(pair); + } + else + { + CFork fd; + recSize -= 0x58; + r += 0x58; + if (recSize < 0x50 * 2) + return S_FALSE; + fd.Parse(r); + item.Size = fd.Size; + item.NumBlocks = fd.NumBlocks; + UInt32 curBlock = 0; + for (int j = 0; j < 8; j++) + { + if (curBlock >= fd.NumBlocks) + break; + const CExtent &e = fd.Extents[j]; + item.Extents.Add(e); + curBlock += e.NumBlocks; + } + } + Items.Add(item); + if (progress && Items.Size() % 100 == 0) + { + RINOK(progress->SetCompleted(Items.Size())); + } + } + node = desc.fLink; + } + IdToIndexMap.Sort(CompareIdToIndex, NULL); + return S_OK; +} + +HRESULT CDatabase::Open(IInStream *inStream, CProgressVirt *progress) +{ + static const UInt32 kHeaderSize = 1024 + 512; + Byte buf[kHeaderSize]; + RINOK(ReadStream_FALSE(inStream, buf, kHeaderSize)); + int i; + for (i = 0; i < 1024; i++) + if (buf[i] != 0) + return S_FALSE; + const Byte *p = buf + 1024; + CVolHeader &h = Header; + + h.Header[0] = p[0]; + h.Header[1] = p[1]; + if (p[0] != 'H' || (p[1] != '+' && p[1] != 'X')) + return S_FALSE; + h.Version = Get16(p + 2); + if (h.Version < 4 || h.Version > 5) + return S_FALSE; + + // h.Attr = Get32(p + 4); + // h.LastMountedVersion = Get32(p + 8); + // h.JournalInfoBlock = Get32(p + 0xC); + + h.CTime = Get32(p + 0x10); + h.MTime = Get32(p + 0x14); + // h.BackupTime = Get32(p + 0x18); + // h.CheckedTime = Get32(p + 0x1C); + + // h.NumFiles = Get32(p + 0x20); + // h.NumFolders = Get32(p + 0x24); + + UInt32 numFiles = Get32(p + 0x20); + UInt32 numFolders = Get32(p + 0x24);; + if (progress) + { + RINOK(progress->SetTotal(numFolders + numFiles)); + } + + UInt32 blockSize = Get32(p + 0x28); + + for (i = 9; ((UInt32)1 << i) != blockSize; i++) + if (i == 31) + return S_FALSE; + h.BlockSizeLog = i; + + h.NumBlocks = Get32(p + 0x2C); + h.NumFreeBlocks = Get32(p + 0x30); + + /* + h.WriteCount = Get32(p + 0x44); + for (i = 0; i < 6; i++) + h.FinderInfo[i] = Get32(p + 0x50 + i * 4); + h.VolID = Get64(p + 0x68); + */ + + UInt64 endPos; + RINOK(inStream->Seek(0, STREAM_SEEK_END, &endPos)); + if ((endPos >> h.BlockSizeLog) < h.NumBlocks) + return S_FALSE; + + // h.AllocationFile.Parse(p + 0x70 + 0x50 * 0); + h.ExtentsFile.Parse( p + 0x70 + 0x50 * 1); + h.CatalogFile.Parse( p + 0x70 + 0x50 * 2); + // h.AttributesFile.Parse(p + 0x70 + 0x50 * 3); + // h.StartupFile.Parse( p + 0x70 + 0x50 * 4); + + RINOK(LoadExtentFile(inStream)); + RINOK(LoadCatalog(inStream, progress)); + + // if (Header.NumFiles + Header.NumFolders != (UInt32)Items.Size()) return S_OK; + + return S_OK; +} + +}} diff --git a/CPP/7zip/Archive/Hfs/HfsIn.h b/CPP/7zip/Archive/Hfs/HfsIn.h new file mode 100755 index 00000000..c1953905 --- /dev/null +++ b/CPP/7zip/Archive/Hfs/HfsIn.h @@ -0,0 +1,154 @@ +// HfsIn.h + +#ifndef __ARCHIVE_HFS_IN_H +#define __ARCHIVE_HFS_IN_H + +#include "Common/MyString.h" +#include "Common/Buffer.h" + +namespace NArchive { +namespace NHfs { + +struct CExtent +{ + UInt32 Pos; + UInt32 NumBlocks; +}; + +struct CFork +{ + UInt64 Size; + // UInt32 ClumpSize; + UInt32 NumBlocks; + CExtent Extents[8]; + void Parse(const Byte *p); +}; + +struct CVolHeader +{ + Byte Header[2]; + UInt16 Version; + // UInt32 Attr; + // UInt32 LastMountedVersion; + // UInt32 JournalInfoBlock; + + UInt32 CTime; + UInt32 MTime; + // UInt32 BackupTime; + // UInt32 CheckedTime; + + // UInt32 NumFiles; + // UInt32 NumFolders; + int BlockSizeLog; + UInt32 NumBlocks; + UInt32 NumFreeBlocks; + + // UInt32 WriteCount; + // UInt32 FinderInfo[8]; + // UInt64 VolID; + + // CFork AllocationFile; + CFork ExtentsFile; + CFork CatalogFile; + // CFork AttributesFile; + // CFork StartupFile; + + bool IsHfsX() const { return Version > 4; } +}; + +inline void HfsTimeToFileTime(UInt32 hfsTime, FILETIME &ft) +{ + UInt64 v = ((UInt64)3600 * 24 * (365 * 303 + 24 * 3) + hfsTime) * 10000000; + ft.dwLowDateTime = (DWORD)v; + ft.dwHighDateTime = (DWORD)(v >> 32); +} + +enum ERecordType +{ + RECORD_TYPE_FOLDER = 1, + RECORD_TYPE_FILE = 2, + RECORD_TYPE_FOLDER_THREAD = 3, + RECORD_TYPE_FILE_THREAD = 4 +}; + +struct CItem +{ + UString Name; + + UInt32 ParentID; + + UInt16 Type; + // UInt16 Flags; + // UInt32 Valence; + UInt32 ID; + UInt32 CTime; + UInt32 MTime; + // UInt32 AttrMTime; + UInt32 ATime; + // UInt32 BackupDate; + + /* + UInt32 OwnerID; + UInt32 GroupID; + Byte AdminFlags; + Byte OwnerFlags; + UInt16 FileMode; + union + { + UInt32 iNodeNum; + UInt32 LinkCount; + UInt32 RawDevice; + } special; + */ + + UInt64 Size; + UInt32 NumBlocks; + CRecordVector<CExtent> Extents; + + bool IsDir() const { return Type == RECORD_TYPE_FOLDER; } + CItem(): Size(0), NumBlocks(0) {} +}; + +struct CIdIndexPair +{ + UInt32 ID; + int Index; +}; + +struct CProgressVirt +{ + virtual HRESULT SetTotal(UInt64 numFiles) PURE; + virtual HRESULT SetCompleted(UInt64 numFiles) PURE; +}; + +class CDatabase +{ + // CObjectVector<CIdExtents> FileExtents; + // CObjectVector<CIdExtents> ResExtents; + CRecordVector<CIdIndexPair> IdToIndexMap; + + HRESULT LoadExtentFile(IInStream *inStream); + HRESULT LoadCatalog(IInStream *inStream, CProgressVirt *progress); + + HRESULT ReadFile(const CFork &fork, CByteBuffer &buf, IInStream *inStream); +public: + CVolHeader Header; + CObjectVector<CItem> Items; + // bool CaseSensetive; + + void Clear() + { + // CaseSensetive = false; + Items.Clear(); + // FileExtents.Clear(); + // ResExtents.Clear(); + IdToIndexMap.Clear(); + } + + UString GetItemPath(int index) const; + HRESULT Open(IInStream *inStream, CProgressVirt *progress); +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Hfs/HfsRegister.cpp b/CPP/7zip/Archive/Hfs/HfsRegister.cpp new file mode 100755 index 00000000..2d706900 --- /dev/null +++ b/CPP/7zip/Archive/Hfs/HfsRegister.cpp @@ -0,0 +1,13 @@ +// HfsRegister.cpp + +#include "StdAfx.h" + +#include "../../Common/RegisterArc.h" + +#include "HfsHandler.h" +static IInArchive *CreateArc() { return new NArchive::NHfs::CHandler; } + +static CArcInfo g_ArcInfo = + { L"HFS", L"hfs", 0, 0xE3, { 'H', '+', 0, 4 }, 4, false, CreateArc, 0 }; + +REGISTER_ARC(Hfs) diff --git a/CPP/7zip/Archive/IArchive.h b/CPP/7zip/Archive/IArchive.h index e0ae7aa1..88d6c408 100755 --- a/CPP/7zip/Archive/IArchive.h +++ b/CPP/7zip/Archive/IArchive.h @@ -22,7 +22,7 @@ namespace NFileTimeType namespace NArchive { - enum + enum { kName = 0, kClassID, @@ -39,7 +39,7 @@ namespace NArchive { namespace NAskMode { - enum + enum { kExtract = 0, kTest, @@ -48,7 +48,7 @@ namespace NArchive } namespace NOperationResult { - enum + enum { kOK = 0, kUnSupportedMethod, @@ -61,7 +61,7 @@ namespace NArchive { namespace NOperationResult { - enum + enum { kOK = 0, kError @@ -70,33 +70,42 @@ namespace NArchive } } +#define INTERFACE_IArchiveOpenCallback(x) \ + STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes) x; \ + STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes) x; \ + ARCHIVE_INTERFACE(IArchiveOpenCallback, 0x10) { - STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes) PURE; - STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes) PURE; + INTERFACE_IArchiveOpenCallback(PURE); }; +#define INTERFACE_IArchiveExtractCallback(x) \ + INTERFACE_IProgress(x) \ + /* GetStream OUT: S_OK - OK, S_FALSE - skeep this file */ \ + STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode) x; \ + STDMETHOD(PrepareOperation)(Int32 askExtractMode) x; \ + STDMETHOD(SetOperationResult)(Int32 resultEOperationResult) x; \ + ARCHIVE_INTERFACE_SUB(IArchiveExtractCallback, IProgress, 0x20) { - 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; + INTERFACE_IArchiveExtractCallback(PURE) }; +#define INTERFACE_IArchiveOpenVolumeCallback(x) \ + STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value) x; \ + STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream) x; \ + ARCHIVE_INTERFACE(IArchiveOpenVolumeCallback, 0x30) { - STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value) PURE; - STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream) PURE; + INTERFACE_IArchiveOpenVolumeCallback(PURE); }; ARCHIVE_INTERFACE(IInArchiveGetStream, 0x40) { - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream) PURE; + STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream) PURE; }; @@ -108,7 +117,7 @@ ARCHIVE_INTERFACE(IArchiveOpenSetSubArchiveName, 0x50) /* IInArchive::Extract: - indices must be sorted + indices must be sorted numItems = 0xFFFFFFFF means "all files" testMode != 0 means "test files without writing to outStream" */ @@ -131,23 +140,30 @@ ARCHIVE_INTERFACE(IInArchive, 0x60) }; +#define INTERFACE_IArchiveUpdateCallback(x) \ + INTERFACE_IProgress(x); \ + 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 */ \ + ) x; \ + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \ + STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream) x; \ + STDMETHOD(SetOperationResult)(Int32 operationResult) x; \ + ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback, IProgress, 0x80) { - 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, ISequentialInStream **inStream) PURE; - STDMETHOD(SetOperationResult)(Int32 operationResult) PURE; + INTERFACE_IArchiveUpdateCallback(PURE); }; +#define INTERFACE_IArchiveUpdateCallback2(x) \ + INTERFACE_IArchiveUpdateCallback(x) \ + STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size) x; \ + STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream) x; \ ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback2, IArchiveUpdateCallback, 0x82) { - STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size) PURE; - STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream) PURE; + INTERFACE_IArchiveUpdateCallback2(PURE); }; @@ -196,12 +212,17 @@ ARCHIVE_INTERFACE(ISetProperties, 0x03) { *numProperties = sizeof(kArcProps) / sizeof(kArcProps[0]); return S_OK; } \ STDMETHODIMP CHandler::GetArchivePropertyInfo IMP_IInArchive_GetProp(kArcProps) +#define IMP_IInArchive_ArcProps_WITH_NAME \ + STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) \ + { *numProperties = sizeof(kArcProps) / sizeof(kArcProps[0]); return S_OK; } \ + STDMETHODIMP CHandler::GetArchivePropertyInfo IMP_IInArchive_GetProp_WITH_NAME(kArcProps) + #define IMP_IInArchive_ArcProps_NO \ STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) \ { *numProperties = 0; return S_OK; } \ STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32, BSTR *, PROPID *, VARTYPE *) \ { return E_NOTIMPL; } \ STDMETHODIMP CHandler::GetArchiveProperty(PROPID, PROPVARIANT *value) \ - { value->vt = VT_EMPTY; return S_OK; } + { value->vt = VT_EMPTY; return S_OK; } #endif diff --git a/CPP/7zip/Archive/7z/7z.ico b/CPP/7zip/Archive/Icons/7z.ico Binary files differindex 319753a1..319753a1 100755 --- a/CPP/7zip/Archive/7z/7z.ico +++ b/CPP/7zip/Archive/Icons/7z.ico diff --git a/CPP/7zip/Archive/Arj/arj.ico b/CPP/7zip/Archive/Icons/arj.ico Binary files differindex c0f8b141..c0f8b141 100755 --- a/CPP/7zip/Archive/Arj/arj.ico +++ b/CPP/7zip/Archive/Icons/arj.ico diff --git a/CPP/7zip/Archive/BZip2/bz2.ico b/CPP/7zip/Archive/Icons/bz2.ico Binary files differindex 614e3540..614e3540 100755 --- a/CPP/7zip/Archive/BZip2/bz2.ico +++ b/CPP/7zip/Archive/Icons/bz2.ico diff --git a/CPP/7zip/Archive/Cab/cab.ico b/CPP/7zip/Archive/Icons/cab.ico Binary files differindex cc2007fc..cc2007fc 100755 --- a/CPP/7zip/Archive/Cab/cab.ico +++ b/CPP/7zip/Archive/Icons/cab.ico diff --git a/CPP/7zip/Archive/Cpio/cpio.ico b/CPP/7zip/Archive/Icons/cpio.ico Binary files differindex 9abaabc7..9abaabc7 100755 --- a/CPP/7zip/Archive/Cpio/cpio.ico +++ b/CPP/7zip/Archive/Icons/cpio.ico diff --git a/CPP/7zip/Archive/Deb/deb.ico b/CPP/7zip/Archive/Icons/deb.ico Binary files differindex 97a08654..97a08654 100755 --- a/CPP/7zip/Archive/Deb/deb.ico +++ b/CPP/7zip/Archive/Icons/deb.ico diff --git a/CPP/7zip/Archive/Icons/dmg.ico b/CPP/7zip/Archive/Icons/dmg.ico Binary files differnew file mode 100755 index 00000000..7d63b09f --- /dev/null +++ b/CPP/7zip/Archive/Icons/dmg.ico diff --git a/CPP/7zip/Archive/GZip/gz.ico b/CPP/7zip/Archive/Icons/gz.ico Binary files differindex f50d8c08..f50d8c08 100755 --- a/CPP/7zip/Archive/GZip/gz.ico +++ b/CPP/7zip/Archive/Icons/gz.ico diff --git a/CPP/7zip/Archive/Icons/hfs.ico b/CPP/7zip/Archive/Icons/hfs.ico Binary files differnew file mode 100755 index 00000000..92a46b81 --- /dev/null +++ b/CPP/7zip/Archive/Icons/hfs.ico diff --git a/CPP/7zip/Archive/Iso/Iso.ico b/CPP/7zip/Archive/Icons/iso.ico Binary files differindex 2538e408..2538e408 100755 --- a/CPP/7zip/Archive/Iso/Iso.ico +++ b/CPP/7zip/Archive/Icons/iso.ico diff --git a/CPP/7zip/Archive/Lzh/lzh.ico b/CPP/7zip/Archive/Icons/lzh.ico Binary files differindex 84dab49c..84dab49c 100755 --- a/CPP/7zip/Archive/Lzh/lzh.ico +++ b/CPP/7zip/Archive/Icons/lzh.ico diff --git a/CPP/7zip/Archive/Lzma/lzma.ico b/CPP/7zip/Archive/Icons/lzma.ico Binary files differindex 1f4f754c..2de2c249 100755 --- a/CPP/7zip/Archive/Lzma/lzma.ico +++ b/CPP/7zip/Archive/Icons/lzma.ico diff --git a/CPP/7zip/Archive/Rar/rar.ico b/CPP/7zip/Archive/Icons/rar.ico Binary files differindex 2918d294..2918d294 100755 --- a/CPP/7zip/Archive/Rar/rar.ico +++ b/CPP/7zip/Archive/Icons/rar.ico diff --git a/CPP/7zip/Archive/RPM/rpm.ico b/CPP/7zip/Archive/Icons/rpm.ico Binary files differindex cdeb8d1b..cdeb8d1b 100755 --- a/CPP/7zip/Archive/RPM/rpm.ico +++ b/CPP/7zip/Archive/Icons/rpm.ico diff --git a/CPP/7zip/Archive/Split/Split.ico b/CPP/7zip/Archive/Icons/split.ico Binary files differindex 5cb93e84..5cb93e84 100755 --- a/CPP/7zip/Archive/Split/Split.ico +++ b/CPP/7zip/Archive/Icons/split.ico diff --git a/CPP/7zip/Archive/Tar/tar.ico b/CPP/7zip/Archive/Icons/tar.ico Binary files differindex 6835885b..6835885b 100755 --- a/CPP/7zip/Archive/Tar/tar.ico +++ b/CPP/7zip/Archive/Icons/tar.ico diff --git a/CPP/7zip/Archive/Wim/wim.ico b/CPP/7zip/Archive/Icons/wim.ico Binary files differindex 887975e6..887975e6 100755 --- a/CPP/7zip/Archive/Wim/wim.ico +++ b/CPP/7zip/Archive/Icons/wim.ico diff --git a/CPP/7zip/Archive/Icons/xar.ico b/CPP/7zip/Archive/Icons/xar.ico Binary files differnew file mode 100755 index 00000000..02707351 --- /dev/null +++ b/CPP/7zip/Archive/Icons/xar.ico diff --git a/CPP/7zip/Archive/Z/Z.ico b/CPP/7zip/Archive/Icons/z.ico Binary files differindex 2db53583..2db53583 100755 --- a/CPP/7zip/Archive/Z/Z.ico +++ b/CPP/7zip/Archive/Icons/z.ico diff --git a/CPP/7zip/Archive/Zip/zip.ico b/CPP/7zip/Archive/Icons/zip.ico Binary files differindex 2af46066..2af46066 100755 --- a/CPP/7zip/Archive/Zip/zip.ico +++ b/CPP/7zip/Archive/Icons/zip.ico diff --git a/CPP/7zip/Archive/Iso/IsoHandler.cpp b/CPP/7zip/Archive/Iso/IsoHandler.cpp index 0ab39c4f..db1b9c06 100755 --- a/CPP/7zip/Archive/Iso/IsoHandler.cpp +++ b/CPP/7zip/Archive/Iso/IsoHandler.cpp @@ -26,19 +26,19 @@ using namespace NTime; namespace NArchive { namespace NIso { -STATPROPSTG kProps[] = +STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, - { NULL, kpidIsFolder, VT_BOOL}, + { NULL, kpidIsDir, VT_BOOL}, { NULL, kpidSize, VT_UI8}, - { NULL, kpidPackedSize, VT_UI8}, - { NULL, kpidLastWriteTime, VT_FILETIME} + { NULL, kpidPackSize, VT_UI8}, + { NULL, kpidMTime, VT_FILETIME} }; IMP_IInArchive_Props IMP_IInArchive_ArcProps_NO -STDMETHODIMP CHandler::Open(IInStream *stream, +STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 * /* maxCheckStartPosition */, IArchiveOpenCallback * /* openArchiveCallback */) { @@ -89,15 +89,13 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val prop = (const wchar_t *)s; break; } - case kpidIsFolder: + case kpidIsDir: prop = false; break; case kpidSize: - case kpidPackedSize: - { + case kpidPackSize: prop = (UInt64)_archive.GetBootItemSize(index); break; - } } } else @@ -125,15 +123,15 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val prop = (const wchar_t *)NItemName::GetOSName2(s); } break; - case kpidIsFolder: + case kpidIsDir: prop = item.IsDir(); break; case kpidSize: - case kpidPackedSize: + case kpidPackSize: if (!item.IsDir()) prop = (UInt64)item.DataLength; break; - case kpidLastWriteTime: + case kpidMTime: { FILETIME utcFileTime; if (item.DateTime.GetFileTime(utcFileTime)) @@ -242,7 +240,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, streamSpec->Init(currentItemSize); RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); realOutStream.Release(); - RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == currentItemSize) ? + RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == currentItemSize) ? NArchive::NExtract::NOperationResult::kOK: NArchive::NExtract::NOperationResult::kDataError)); } diff --git a/CPP/7zip/Archive/Iso/IsoHandler.h b/CPP/7zip/Archive/Iso/IsoHandler.h index 5750cbc9..bb905a22 100755 --- a/CPP/7zip/Archive/Iso/IsoHandler.h +++ b/CPP/7zip/Archive/Iso/IsoHandler.h @@ -12,7 +12,7 @@ namespace NArchive { namespace NIso { -class CHandler: +class CHandler: public IInArchive, public CMyUnknownImp { diff --git a/CPP/7zip/Archive/Iso/IsoHeader.cpp b/CPP/7zip/Archive/Iso/IsoHeader.cpp index 9555e49b..b3e418bb 100755 --- a/CPP/7zip/Archive/Iso/IsoHeader.cpp +++ b/CPP/7zip/Archive/Iso/IsoHeader.cpp @@ -9,7 +9,7 @@ namespace NIso { const char *kElToritoSpec = "EL TORITO SPECIFICATION\0\0\0\0\0\0\0\0\0"; -const wchar_t *kMediaTypes[5] = +const wchar_t *kMediaTypes[5] = { L"NoEmulation", L"1.2M", diff --git a/CPP/7zip/Archive/Iso/IsoIn.cpp b/CPP/7zip/Archive/Iso/IsoIn.cpp index f4896d37..37d2798a 100755 --- a/CPP/7zip/Archive/Iso/IsoIn.cpp +++ b/CPP/7zip/Archive/Iso/IsoIn.cpp @@ -174,7 +174,7 @@ void CInArchive::ReadDirRecord2(CDirRecord &r, Byte len) ReadBytes((Byte *)r.FileId, idLen); int padSize = 1 - (idLen & 1); - // SkeepZeros(1 - (idLen & 1)); + // SkeepZeros(1 - (idLen & 1)); Skeep(1 - (idLen & 1)); // it's bug in some cd's. Must be zeros int curPos = 33 + idLen + padSize; @@ -187,7 +187,7 @@ void CInArchive::ReadDirRecord2(CDirRecord &r, Byte len) void CInArchive::ReadDirRecord(CDirRecord &r) { - Byte len = ReadByte(); + Byte len = ReadByte(); // Some CDs can have incorrect value len = 48 ('0') in VolumeDescriptor. // But maybe we must use real "len" for other records. len = 34; @@ -218,8 +218,8 @@ void CInArchive::ReadVolumeDescriptor(CVolumeDescriptor &d) ReadBytes(d.CopyrightFileId, sizeof(d.CopyrightFileId)); ReadBytes(d.AbstractFileId, sizeof(d.AbstractFileId)); ReadBytes(d.BibFileId, sizeof(d.BibFileId)); - ReadDateTime(d.CreationTime); - ReadDateTime(d.ModificationTime); + ReadDateTime(d.CTime); + ReadDateTime(d.MTime); ReadDateTime(d.ExpirationTime); ReadDateTime(d.EffectiveTime); d.FileStructureVersion = ReadByte(); // = 1 @@ -228,13 +228,19 @@ void CInArchive::ReadVolumeDescriptor(CVolumeDescriptor &d) SkeepZeros(653); } -static inline bool CheckDescriptorSignature(const Byte *sig) +static const Byte kSig_CD001[5] = { 'C', 'D', '0', '0', '1' }; + +static const Byte kSig_NSR02[5] = { 'N', 'S', 'R', '0', '2' }; +static const Byte kSig_NSR03[5] = { 'N', 'S', 'R', '0', '3' }; +static const Byte kSig_BEA01[5] = { 'B', 'E', 'A', '0', '1' }; +static const Byte kSig_TEA01[5] = { 'T', 'E', 'A', '0', '1' }; + +static inline bool CheckSignature(const Byte *sig, const Byte *data) { - return sig[0] == 'C' && - sig[1] == 'D' && - sig[2] == '0' && - sig[3] == '0' && - sig[4] == '1'; + for (int i = 0; i < 5; i++) + if (sig[i] != data[i]) + return false; + return true; } void CInArchive::SeekToBlock(UInt32 blockIndex) @@ -346,17 +352,41 @@ HRESULT CInArchive::Open2() VolDescs.Add(CVolumeDescriptor()); for (;;) { - Byte sig[6]; - ReadBytes(sig, 6); - if (!CheckDescriptorSignature(sig + 1)) + Byte sig[7]; + ReadBytes(sig, 7); + Byte ver = sig[6]; + if (!CheckSignature(kSig_CD001, sig + 1)) + { return S_FALSE; + /* + if (sig[0] != 0 || ver != 1) + break; + if (CheckSignature(kSig_BEA01, sig + 1)) + { + } + else if (CheckSignature(kSig_TEA01, sig + 1)) + { + break; + } + else if (CheckSignature(kSig_NSR02, sig + 1)) + { + } + else + break; + SkeepZeros(0x800 - 7); + continue; + */ + } // version = 2 for ISO 9660:1999? - Byte ver = ReadByte(); if (ver > 2) throw S_FALSE; if (sig[0] == NVolDescType::kTerminator) + { break; + // Skeep(0x800 - 7); + // continue; + } switch(sig[0]) { case NVolDescType::kBootRecord: diff --git a/CPP/7zip/Archive/Iso/IsoIn.h b/CPP/7zip/Archive/Iso/IsoIn.h index 4f9705c4..ce53a1e3 100755 --- a/CPP/7zip/Archive/Iso/IsoIn.h +++ b/CPP/7zip/Archive/Iso/IsoIn.h @@ -109,7 +109,7 @@ struct CDateTime Byte Second; Byte Hundredths; signed char GmtOffset; // min intervals from -48 (West) to +52 (East) recorded. - bool NotSpecified() const { return Year == 0 && Month == 0 && Day == 0 && + bool NotSpecified() const { return Year == 0 && Month == 0 && Day == 0 && Hour == 0 && Minute == 0 && Second == 0 && GmtOffset == 0; } }; @@ -130,7 +130,7 @@ struct CBootInitialEntry { bool Bootable; Byte BootMediaType; - UInt16 LoadSegment; + UInt16 LoadSegment; /* This is the load segment for the initial boot image. If this value is 0 the system will use the traditional segment of 7C0. If this value is non-zero the system will use the specified segment. This applies to x86 @@ -143,10 +143,10 @@ struct CBootInitialEntry UInt32 LoadRBA; // This is the start address of the virtual disk. CDs use // Relative/Logical block addressing. - UInt64 GetSize() const - { + UInt64 GetSize() const + { // if (BootMediaType == NBootMediaType::k1d44Floppy) (1440 << 10); - return SectorCount * 512; + return SectorCount * 512; } UString GetName() const @@ -173,7 +173,7 @@ struct CBootInitialEntry struct CVolumeDescriptor { Byte VolFlags; - Byte SystemId[32]; // a-characters. An identification of a system + Byte SystemId[32]; // a-characters. An identification of a system // which can recognize and act upon the content of the Logical // Sectors with logical Sector Numbers 0 to 15 of the volume. Byte VolumeId[32]; // d-characters. An identification of the volume. @@ -195,19 +195,19 @@ struct CVolumeDescriptor Byte CopyrightFileId[37]; Byte AbstractFileId[37]; Byte BibFileId[37]; - CDateTime CreationTime; - CDateTime ModificationTime; + CDateTime CTime; + CDateTime MTime; CDateTime ExpirationTime; CDateTime EffectiveTime; Byte FileStructureVersion; // = 1; Byte ApplicationUse[512]; - bool IsJoliet() const + bool IsJoliet() const { if ((VolFlags & 1) != 0) return false; Byte b = EscapeSequence[2]; - return (EscapeSequence[0] == 0x25 && EscapeSequence[1] == 0x2F && + return (EscapeSequence[0] == 0x25 && EscapeSequence[1] == 0x2F && (b == 0x40 || b == 0x43 || b == 0x45)); } }; @@ -272,8 +272,8 @@ public: bool IsJoliet() const { return VolDescs[MainVolDescIndex].IsJoliet(); } - UInt64 GetBootItemSize(int index) const - { + UInt64 GetBootItemSize(int index) const + { const CBootInitialEntry &be = BootEntries[index]; UInt64 size = be.GetSize(); if (be.BootMediaType == NBootMediaType::k1d2Floppy) @@ -288,7 +288,7 @@ public: if (_archiveSize - startPos < size) size = _archiveSize - startPos; } - return size; + return size; } bool IsSusp; diff --git a/CPP/7zip/Archive/Iso/IsoItem.h b/CPP/7zip/Archive/Iso/IsoItem.h index fcb9531f..f39c2f5d 100755 --- a/CPP/7zip/Archive/Iso/IsoItem.h +++ b/CPP/7zip/Archive/Iso/IsoItem.h @@ -7,6 +7,8 @@ #include "Common/MyString.h" #include "Common/Buffer.h" +#include "Windows/Time.h" + #include "IsoHeader.h" namespace NArchive { @@ -24,22 +26,16 @@ struct CRecordingDateTime bool GetFileTime(FILETIME &ft) const { - SYSTEMTIME st; - st.wYear = (WORD)(Year + 1900); - st.wMonth = Month; - st.wDayOfWeek = 0; // check it - st.wDay = Day; - st.wHour = Hour; - st.wMinute = Minute; - st.wSecond = Second; - st.wMilliseconds = 0; - if (!SystemTimeToFileTime(&st, &ft)) - return false; - UInt64 value = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime; - value -= (UInt64)((Int64)GmtOffset * 15 * 60 * 10000000); + UInt64 value; + bool res = NWindows::NTime::GetSecondsSince1601(Year + 1900, Month, Day, Hour, Minute, Second, value); + if (res) + { + value -= (UInt64)((Int64)GmtOffset * 15 * 60); + value *= 10000000; + } ft.dwLowDateTime = (DWORD)value; ft.dwHighDateTime = (DWORD)(value >> 32); - return true; + return res; } }; @@ -57,8 +53,8 @@ struct CDirRecord CByteBuffer SystemUse; bool IsDir() const { return (FileFlags & NFileFlags::kDirectory) != 0; } - bool IsSystemItem() const - { + bool IsSystemItem() const + { if (FileId.GetCapacity() != 1) return false; Byte b = *(const Byte *)FileId; @@ -111,11 +107,11 @@ struct CDirRecord bool CheckSusp(const Byte *p, int &startPos) const { - if (p[0] == 'S' && - p[1] == 'P' && - p[2] == 0x7 && - p[3] == 0x1 && - p[4] == 0xBE && + if (p[0] == 'S' && + p[1] == 'P' && + p[2] == 0x7 && + p[3] == 0x1 && + p[4] == 0xBE && p[5] == 0xEF) { startPos = p[6]; diff --git a/CPP/7zip/Archive/Iso/StdAfx.cpp b/CPP/7zip/Archive/Iso/StdAfx.cpp deleted file mode 100755 index d0feea85..00000000 --- a/CPP/7zip/Archive/Iso/StdAfx.cpp +++ /dev/null @@ -1,3 +0,0 @@ -// StdAfx.cpp - -#include "StdAfx.h" diff --git a/CPP/7zip/Archive/Lzh/LzhCRC.cpp b/CPP/7zip/Archive/Lzh/LzhCRC.cpp index ca1235bb..e299bf6c 100755 --- a/CPP/7zip/Archive/Lzh/LzhCRC.cpp +++ b/CPP/7zip/Archive/Lzh/LzhCRC.cpp @@ -17,9 +17,9 @@ void CCRC::InitTable() { UInt32 r = i; for (int j = 0; j < 8; j++) - if (r & 1) + if (r & 1) r = (r >> 1) ^ kCRCPoly; - else + else r >>= 1; CCRC::Table[i] = (UInt16)r; } diff --git a/CPP/7zip/Archive/Lzh/LzhCRC.h b/CPP/7zip/Archive/Lzh/LzhCRC.h index e49d649c..be2a4569 100755 --- a/CPP/7zip/Archive/Lzh/LzhCRC.h +++ b/CPP/7zip/Archive/Lzh/LzhCRC.h @@ -19,7 +19,7 @@ public: CCRC(): _value(0){}; void Init() { _value = 0; } void Update(const void *data, size_t size); - UInt16 GetDigest() const { return _value; } + UInt16 GetDigest() const { return _value; } }; }} diff --git a/CPP/7zip/Archive/Lzh/LzhHandler.cpp b/CPP/7zip/Archive/Lzh/LzhHandler.cpp index c5123f56..ee43a3b0 100755 --- a/CPP/7zip/Archive/Lzh/LzhHandler.cpp +++ b/CPP/7zip/Archive/Lzh/LzhHandler.cpp @@ -34,7 +34,7 @@ struct COsPair const wchar_t *Name; }; -COsPair g_OsPairs[] = +COsPair g_OsPairs[] = { { 'M', L"MS-DOS" }, { '2', L"OS/2" }, @@ -67,14 +67,14 @@ static const wchar_t *GetOS(Byte osId) return kUnknownOS; }; -STATPROPSTG kProps[] = +STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, - { NULL, kpidIsFolder, VT_BOOL}, + { NULL, kpidIsDir, VT_BOOL}, { NULL, kpidSize, VT_UI8}, - { NULL, kpidPackedSize, VT_UI8}, - { NULL, kpidLastWriteTime, VT_FILETIME}, - { NULL, kpidAttributes, VT_UI4}, + { NULL, kpidPackSize, VT_UI8}, + { NULL, kpidMTime, VT_FILETIME}, + { NULL, kpidAttrib, VT_UI4}, // { NULL, kpidCommented, VT_BOOL}, @@ -114,23 +114,17 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va } break; } - case kpidIsFolder: - prop = item.IsDirectory(); - break; - case kpidSize: - prop = item.Size; - break; - case kpidPackedSize: - prop = item.PackSize; - break; - case kpidLastWriteTime: + case kpidIsDir: prop = item.IsDir(); break; + case kpidSize: prop = item.Size; break; + case kpidPackSize: prop = item.PackSize; break; + case kpidCRC: prop = (UInt32)item.CRC; break; + case kpidHostOS: prop = GetOS(item.OsId); break; + case kpidMTime: { FILETIME utcFileTime; UInt32 unixTime; if (item.GetUnixTime(unixTime)) - { NTime::UnixTimeToFileTime(unixTime, utcFileTime); - } else { FILETIME localFileTime; @@ -146,16 +140,9 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va break; } /* - case kpidAttributes: - prop = (UInt32)item.Attributes; - break; - case kpidCommented: - prop = item.IsCommented(); - break; + case kpidAttrib: prop = (UInt32)item.Attributes; break; + case kpidCommented: prop = item.IsCommented(); break; */ - case kpidCRC: - prop = (UInt32)item.CRC; - break; case kpidMethod: { wchar_t method2[kMethodIdSize + 1]; @@ -165,9 +152,6 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va prop = method2; break; } - case kpidHostOS: - prop = GetOS(item.OsId); - break; } prop.Detach(value); return S_OK; @@ -175,14 +159,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va } /* -class CPropgressImp: public CProgressVirt +class CProgressImp: public CProgressVirt { public: CMyComPtr<IArchiveOpenCallback> Callback; STDMETHOD(SetCompleted)(const UInt64 *numFiles); }; -STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles) +STDMETHODIMP CProgressImp::SetCompleted(const UInt64 *numFiles) { if (Callback) return Callback->SetCompleted(numFiles, NULL); @@ -190,7 +174,7 @@ STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles) } */ -STDMETHODIMP CHandler::Open(IInStream *inStream, +STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 * /* maxCheckStartPosition */, IArchiveOpenCallback *callback) { COM_TRY_BEGIN @@ -198,13 +182,17 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, { _items.Clear(); CInArchive archive; - RINOK(archive.Open(inStream)); + + UInt64 endPos = 0; + bool needSetTotal = true; + if (callback != NULL) { - RINOK(callback->SetTotal(NULL, NULL)); - UInt64 numFiles = _items.Size(); - RINOK(callback->SetCompleted(&numFiles, NULL)); + RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos)); + RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); } + + RINOK(archive.Open(stream)); for (;;) { CItemEx item; @@ -220,14 +208,23 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, archive.Skeep(item.PackSize); if (callback != NULL) { - UInt64 numFiles = _items.Size(); - RINOK(callback->SetCompleted(&numFiles, NULL)); + if (needSetTotal) + { + RINOK(callback->SetTotal(NULL, &endPos)); + needSetTotal = false; + } + if (_items.Size() % 100 == 0) + { + UInt64 numFiles = _items.Size(); + UInt64 numBytes = item.DataPosition; + RINOK(callback->SetCompleted(&numFiles, &numBytes)); + } } } if (_items.IsEmpty()) return S_FALSE; - _stream = inStream; + _stream = stream; } catch(...) { @@ -306,7 +303,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, const CItemEx &item = _items[index]; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - if(item.IsDirectory()) + if (item.IsDir()) { // if (!testMode) { @@ -316,7 +313,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, continue; } - if (!testMode && (!realOutStream)) + if (!testMode && (!realOutStream)) continue; RINOK(extractCallback->PrepareOperation(askMode)); @@ -345,7 +342,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, } else if (item.IsLh4GroupMethod()) { - if(!lzhDecoder) + if (!lzhDecoder) { lzhDecoderSpec = new NCompress::NLzh::NDecoder::CCoder; lzhDecoder = lzhDecoderSpec; @@ -356,7 +353,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, /* else if (item.IsLh1GroupMethod()) { - if(!lzh1Decoder) + if (!lzh1Decoder) { lzh1DecoderSpec = new NCompress::NLzh1::NDecoder::CCoder; lzh1Decoder = lzh1DecoderSpec; diff --git a/CPP/7zip/Archive/Lzh/LzhHandler.h b/CPP/7zip/Archive/Lzh/LzhHandler.h index 2caf21fd..ed504dd2 100755 --- a/CPP/7zip/Archive/Lzh/LzhHandler.h +++ b/CPP/7zip/Archive/Lzh/LzhHandler.h @@ -10,7 +10,7 @@ namespace NArchive { namespace NLzh { -class CHandler: +class CHandler: public IInArchive, public CMyUnknownImp { diff --git a/CPP/7zip/Archive/Lzh/LzhItem.h b/CPP/7zip/Archive/Lzh/LzhItem.h index d0ba25e2..494a65bf 100755 --- a/CPP/7zip/Archive/Lzh/LzhItem.h +++ b/CPP/7zip/Archive/Lzh/LzhItem.h @@ -45,15 +45,15 @@ public: bool IsValidMethod() const { return (Method[0] == '-' && Method[1] == 'l' && Method[4] == '-'); } bool IsLhMethod() const {return (IsValidMethod() && Method[2] == 'h'); } - bool IsDirectory() const {return (IsLhMethod() && Method[3] == 'd'); } + bool IsDir() const {return (IsLhMethod() && Method[3] == 'd'); } - bool IsCopyMethod() const + bool IsCopyMethod() const { - return (IsLhMethod() && Method[3] == '0') || + return (IsLhMethod() && Method[3] == '0') || (IsValidMethod() && Method[2] == 'z' && Method[3] == '4'); } - bool IsLh1GroupMethod() const + bool IsLh1GroupMethod() const { if (!IsLhMethod()) return false; @@ -65,7 +65,7 @@ public: return false; } - bool IsLh4GroupMethod() const + bool IsLh4GroupMethod() const { if (!IsLhMethod()) return false; @@ -80,7 +80,7 @@ public: return false; } - int GetNumDictBits() const + int GetNumDictBits() const { if (!IsLhMethod()) return 0; @@ -124,9 +124,9 @@ public: return false; } const Byte *data = (const Byte *)(Extensions[index].Data); - value = data[0] | - ((UInt32)data[1] << 8) | - ((UInt32)data[2] << 16) | + value = data[0] | + ((UInt32)data[1] << 8) | + ((UInt32)data[2] << 16) | ((UInt32)data[3] << 24); return true; } diff --git a/CPP/7zip/Archive/Lzh/LzhOutStreamWithCRC.h b/CPP/7zip/Archive/Lzh/LzhOutStreamWithCRC.h index 31b536b7..fd73f4ae 100755 --- a/CPP/7zip/Archive/Lzh/LzhOutStreamWithCRC.h +++ b/CPP/7zip/Archive/Lzh/LzhOutStreamWithCRC.h @@ -10,7 +10,7 @@ namespace NArchive { namespace NLzh { -class COutStreamWithCRC: +class COutStreamWithCRC: public ISequentialOutStream, public CMyUnknownImp { diff --git a/CPP/7zip/Archive/Lzh/StdAfx.cpp b/CPP/7zip/Archive/Lzh/StdAfx.cpp deleted file mode 100755 index d0feea85..00000000 --- a/CPP/7zip/Archive/Lzh/StdAfx.cpp +++ /dev/null @@ -1,3 +0,0 @@ -// StdAfx.cpp - -#include "StdAfx.h" diff --git a/CPP/7zip/Archive/Lzma/LzmaFiltersDecode.cpp b/CPP/7zip/Archive/Lzma/LzmaFiltersDecode.cpp index d3450616..26c1092f 100755 --- a/CPP/7zip/Archive/Lzma/LzmaFiltersDecode.cpp +++ b/CPP/7zip/Archive/Lzma/LzmaFiltersDecode.cpp @@ -13,7 +13,7 @@ static const UInt64 k_BCJ = 0x03030103; HRESULT CDecoder::Code( DECL_EXTERNAL_CODECS_LOC_VARS const CHeader &block, - ISequentialInStream *inStream, ISequentialOutStream *outStream, + ISequentialInStream *inStream, ISequentialOutStream *outStream, UInt64 *inProcessedSize, ICompressProgressInfo *progress) { *inProcessedSize = (UInt64)(Int64)-1; @@ -57,7 +57,7 @@ HRESULT CDecoder::Code( if (!setOutStream) return E_NOTIMPL; RINOK(setOutStream->SetOutStream(outStream)); - outStream = _bcjStream; + outStream = _bcjStream; } const UInt64 *unpackSize = block.HasUnpackSize() ? &block.UnpackSize : NULL; diff --git a/CPP/7zip/Archive/Lzma/LzmaFiltersDecode.h b/CPP/7zip/Archive/Lzma/LzmaFiltersDecode.h index a9f4927b..36de4966 100755 --- a/CPP/7zip/Archive/Lzma/LzmaFiltersDecode.h +++ b/CPP/7zip/Archive/Lzma/LzmaFiltersDecode.h @@ -17,7 +17,7 @@ class CDecoder public: HRESULT Code(DECL_EXTERNAL_CODECS_LOC_VARS const CHeader &block, - ISequentialInStream *inStream, ISequentialOutStream *outStream, + ISequentialInStream *inStream, ISequentialOutStream *outStream, UInt64 *inProcessedSize, ICompressProgressInfo *progress); }; diff --git a/CPP/7zip/Archive/Lzma/LzmaHandler.cpp b/CPP/7zip/Archive/Lzma/LzmaHandler.cpp index 70126aa4..c434595d 100755 --- a/CPP/7zip/Archive/Lzma/LzmaHandler.cpp +++ b/CPP/7zip/Archive/Lzma/LzmaHandler.cpp @@ -20,10 +20,10 @@ namespace NArchive { namespace NLzma { -STATPROPSTG kProps[] = +STATPROPSTG kProps[] = { { NULL, kpidSize, VT_UI8}, - { NULL, kpidPackedSize, VT_UI8}, + { NULL, kpidPackSize, VT_UI8}, { NULL, kpidMethod, VT_UI1} }; @@ -82,7 +82,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va if (m_StreamInfo.HasUnpackSize()) propVariant = (UInt64)m_StreamInfo.UnpackSize; break; - case kpidPackedSize: + case kpidPackSize: propVariant = (UInt64)m_PackSize; break; case kpidMethod: @@ -111,7 +111,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va return S_OK; } -STDMETHODIMP CHandler::Open(IInStream *inStream, +STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 * /* maxCheckStartPosition */, IArchiveOpenCallback * /* openArchiveCallback */) { @@ -169,7 +169,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, { CMyComPtr<ISequentialOutStream> realOutStream; - Int32 askMode = testMode ? + Int32 askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract; diff --git a/CPP/7zip/Archive/Lzma/LzmaHandler.h b/CPP/7zip/Archive/Lzma/LzmaHandler.h index e4078309..e8fdcedc 100755 --- a/CPP/7zip/Archive/Lzma/LzmaHandler.h +++ b/CPP/7zip/Archive/Lzma/LzmaHandler.h @@ -15,7 +15,7 @@ namespace NLzma { // const UInt64 k_LZMA = 0x030101; -class CHandler: +class CHandler: public IInArchive, PUBLIC_ISetCompressCodecsInfo public CMyUnknownImp @@ -27,24 +27,24 @@ public: MY_QUERYINTERFACE_END MY_ADDREF_RELEASE - STDMETHOD(Open)(IInStream *inStream, + STDMETHOD(Open)(IInStream *inStream, const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *openArchiveCallback); - STDMETHOD(Close)(); + IArchiveOpenCallback *openArchiveCallback); + STDMETHOD(Close)(); - STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + 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); UString GetMethodString(); diff --git a/CPP/7zip/Archive/MachoHandler.cpp b/CPP/7zip/Archive/MachoHandler.cpp new file mode 100755 index 00000000..bbae3150 --- /dev/null +++ b/CPP/7zip/Archive/MachoHandler.cpp @@ -0,0 +1,490 @@ +// MachoHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#include "Common/Buffer.h" +#include "Common/ComTry.h" + +#include "Windows/PropVariantUtils.h" + +#include "../Common/LimitedStreams.h" +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +#include "../Compress/Copy/CopyCoder.h" + +#include "Common/DummyOutStream.h" + +static UInt32 Get32(const Byte *p, int be) { if (be) return GetBe32(p); return GetUi32(p); } +static UInt64 Get64(const Byte *p, int be) { if (be) return GetBe64(p); return GetUi64(p); } + +using namespace NWindows; + +namespace NArchive { +namespace NMacho { + +#define MACH_ARCH_ABI64 (1 << 24) +#define MACH_MACHINE_386 7 +#define MACH_MACHINE_ARM 12 +#define MACH_MACHINE_SPARC 14 +#define MACH_MACHINE_PPC 18 + +#define MACH_MACHINE_PPC64 (MACH_ARCH_ABI64 | MACH_MACHINE_PPC) +#define MACH_MACHINE_AMD64 (MACH_ARCH_ABI64 | MACH_MACHINE_386) + +#define MACH_CMD_SEGMENT_32 1 +#define MACH_CMD_SEGMENT_64 0x19 + +#define MACH_SECT_TYPE_MASK 0x000000FF +#define MACH_SECT_ATTR_MASK 0xFFFFFF00 + +#define MACH_SECT_ATTR_ZEROFILL 1 + +const char *g_SectTypes[] = +{ + "REGULAR", + "ZEROFILL", + "CSTRINGS", + "4BYTE_LITERALS", + "8BYTE_LITERALS", + "LITERAL_POINTERS", + "NON_LAZY_SYMBOL_POINTERS", + "LAZY_SYMBOL_POINTERS", + "SYMBOL_STUBS", + "MOD_INIT_FUNC_POINTERS", + "MOD_TERM_FUNC_POINTERS", + "COALESCED", + "GB_ZEROFILL", + "INTERPOSING", + "16BYTE_LITERALS" +}; + +const char *g_FileTypes[] = +{ + "0", + "OBJECT", + "EXECUTE", + "FVMLIB", + "CORE", + "PRELOAD", + "DYLIB", + "DYLINKER", + "BUNDLE", + "DYLIB_STUB", + "DSYM" +}; + +static const CUInt32PCharPair g_Flags[] = +{ + { (UInt32)1 << 31, "PURE_INSTRUCTIONS" }, + { 1 << 30, "NO_TOC" }, + { 1 << 29, "STRIP_STATIC_SYMS" }, + { 1 << 28, "NO_DEAD_STRIP" }, + { 1 << 27, "LIVE_SUPPORT" }, + { 1 << 26, "SELF_MODIFYING_CODE" }, + { 1 << 25, "DEBUG" }, + { 1 << 10, "SOME_INSTRUCTIONS" }, + { 1 << 9, "EXT_RELOC" }, + { 1 << 8, "LOC_RELOC" } +}; + +static const CUInt32PCharPair g_MachinePairs[] = +{ + { MACH_MACHINE_386, "x86" }, + { MACH_MACHINE_ARM, "ARM" }, + { MACH_MACHINE_SPARC, "SPARC" }, + { MACH_MACHINE_PPC, "PowerPC" }, + { MACH_MACHINE_PPC64, "PowerPC 64-bit" }, + { MACH_MACHINE_AMD64, "x64" } +}; + +static const int kNameSize = 16; + +struct CSegment +{ + char Name[kNameSize]; +}; + +struct CSection +{ + char Name[kNameSize]; + char SegName[kNameSize]; + UInt64 Va; + UInt64 Size; + UInt32 Pa; + UInt32 Flags; + int SegmentIndex; + UInt64 GetPackSize() const { return Flags == MACH_SECT_ATTR_ZEROFILL ? 0 : Size; } +}; + + +class CHandler: + public IInArchive, + public CMyUnknownImp +{ + CMyComPtr<IInStream> _inStream; + CObjectVector<CSegment> _segments; + CObjectVector<CSection> _sections; + bool _mode64; + bool _be; + UInt32 _machine; + UInt32 _type; + UInt32 _headersSize; + UInt64 _totalSize; + HRESULT Open2(ISequentialInStream *stream); + bool Parse(const Byte *buf, UInt32 size); +public: + MY_UNKNOWN_IMP1(IInArchive) + INTERFACE_IInArchive(;) +}; + +bool CHandler::Parse(const Byte *buf, UInt32 size) +{ + bool mode64 = _mode64; + bool be = _be; + + const Byte *bufStart = buf; + bool reduceCommands = false; + if (size < 512) + return false; + + _machine = Get32(buf + 4, be); + _type = Get32(buf + 0xC, be); + + UInt32 numCommands = Get32(buf + 0x10, be); + UInt32 commandsSize = Get32(buf + 0x14, be); + if (commandsSize > size) + return false; + + if (commandsSize > (1 << 24) || numCommands > (1 << 18)) + return false; + + if (numCommands > 16) + { + reduceCommands = true; + numCommands = 16; + } + + _headersSize = 0; + + buf += 0x1C; + size -= 0x1C; + + if (mode64) + { + buf += 4; + size -= 4; + } + + _totalSize = (UInt32)(buf - bufStart); + if (commandsSize < size) + size = commandsSize; + + for (UInt32 cmdIndex = 0; cmdIndex < numCommands; cmdIndex++) + { + if (size < 8) + return false; + UInt32 cmd = Get32(buf, be); + UInt32 cmdSize = Get32(buf + 4, be); + if (size < cmdSize) + return false; + if (cmd == MACH_CMD_SEGMENT_32 || cmd == MACH_CMD_SEGMENT_64) + { + UInt32 offs = (cmd == MACH_CMD_SEGMENT_64) ? 0x48 : 0x38; + if (cmdSize < offs) + break; + + { + UInt64 vmAddr, vmSize, phAddr, phSize; + if (cmd == MACH_CMD_SEGMENT_64) + { + vmAddr = Get64(buf + 0x18, be); + vmSize = Get64(buf + 0x20, be); + phAddr = Get64(buf + 0x28, be); + phSize = Get64(buf + 0x30, be); + } + else + { + vmAddr = Get32(buf + 0x18, be); + vmSize = Get32(buf + 0x1C, be); + phAddr = Get32(buf + 0x20, be); + phSize = Get32(buf + 0x24, be); + } + { + UInt64 totalSize = phAddr + phSize; + if (totalSize > _totalSize) + _totalSize = totalSize; + } + } + + CSegment seg; + memcpy(seg.Name, buf + 8, kNameSize); + _segments.Add(seg); + + UInt32 numSections = Get32(buf + offs - 8, be); + if (numSections > (1 << 8)) + return false; + + while (numSections-- != 0) + { + CSection section; + UInt32 headerSize = (cmd == MACH_CMD_SEGMENT_64) ? 0x50 : 0x44; + const Byte *p = buf + offs; + if (cmdSize - offs < headerSize) + break; + if (cmd == MACH_CMD_SEGMENT_64) + { + section.Va = Get64(p + 0x20, be); + section.Size = Get64(p + 0x28, be); + section.Pa = Get32(p + 0x30, be); + section.Flags = Get32(p + 0x40, be); + } + else + { + section.Va = Get32(p + 0x20, be); + section.Size = Get32(p + 0x24, be); + section.Pa = Get32(p + 0x28, be); + section.Flags = Get32(p + 0x38, be); + } + memcpy(section.Name, p, kNameSize); + memcpy(section.SegName, p + kNameSize, kNameSize); + section.SegmentIndex = _segments.Size() - 1; + _sections.Add(section); + offs += headerSize; + } + if (offs != cmdSize) + return false; + } + buf += cmdSize; + size -= cmdSize; + } + _headersSize = (UInt32)(buf - bufStart); + return reduceCommands || (size == 0); +} + +STATPROPSTG kArcProps[] = +{ + { NULL, kpidCpu, VT_BSTR}, + { NULL, kpidBit64, VT_BOOL}, + { NULL, kpidBigEndian, VT_BOOL}, + { NULL, kpidCharacts, VT_BSTR}, + { NULL, kpidPhySize, VT_UI8}, + { NULL, kpidHeadersSize, VT_UI4} +}; + +STATPROPSTG kProps[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackSize, VT_UI8}, + { NULL, kpidCharacts, VT_BSTR}, + { NULL, kpidOffset, VT_UI8}, + { NULL, kpidVa, VT_UI8} +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + switch(propID) + { + case kpidCpu: PAIR_TO_PROP(g_MachinePairs, _machine, prop); break; + case kpidCharacts: TYPE_TO_PROP(g_FileTypes, _type, prop); break; + case kpidPhySize: prop = _totalSize; break; + case kpidHeadersSize: prop = _headersSize; break; + case kpidBit64: if (_mode64) prop = _mode64; break; + case kpidBigEndian: if (_be) prop = _be; break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +static AString GetName(const char *name) +{ + AString res; + char *p = res.GetBuffer(kNameSize); + strncpy(p, name, kNameSize); + p[kNameSize] = 0; + res.ReleaseBuffer(); + return res; +} + +static AString SectFlagsToString(UInt32 flags) +{ + AString res = TypeToString(g_SectTypes, sizeof(g_SectTypes) / sizeof(g_SectTypes[0]), + flags & MACH_SECT_TYPE_MASK); + AString s = FlagsToString(g_Flags, sizeof(g_Flags) / sizeof(g_Flags[0]), + flags & MACH_SECT_ATTR_MASK); + if (!s.IsEmpty()) + { + res += ' '; + res += s; + } + return res; +} + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + const CSection &item = _sections[index]; + switch(propID) + { + case kpidPath: StringToProp(GetName(_segments[item.SegmentIndex].Name) + GetName(item.Name), prop); break; + case kpidSize: prop = (UInt64)item.Size; break; + case kpidPackSize: prop = (UInt64)item.GetPackSize(); break; + case kpidCharacts: StringToProp(SectFlagsToString(item.Flags), prop); break; + case kpidOffset: prop = item.Pa; break; + case kpidVa: prop = item.Va; break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +HRESULT CHandler::Open2(ISequentialInStream *stream) +{ + const UInt32 kBufSize = 1 << 18; + const UInt32 kSigSize = 4; + + CByteBuffer buffer; + buffer.SetCapacity(kBufSize); + Byte *buf = buffer; + + size_t processed = kSigSize; + RINOK(ReadStream_FALSE(stream, buf, processed)); + UInt32 sig = GetUi32(buf); + bool be, mode64; + switch(sig) + { + case 0xCEFAEDFE: be = true; mode64 = false; break; + case 0xCFFAEDFE: be = true; mode64 = true; break; + case 0xFEEDFACE: be = false; mode64 = false; break; + case 0xFEEDFACF: be = false; mode64 = true; break; + default: return S_FALSE; + } + processed = kBufSize - kSigSize; + RINOK(ReadStream(stream, buf + kSigSize, &processed)); + _mode64 = mode64; + _be = be; + return Parse(buf, (UInt32)processed + kSigSize) ? S_OK : S_FALSE; +} + +STDMETHODIMP CHandler::Open(IInStream *inStream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback * /* openArchiveCallback */) +{ + COM_TRY_BEGIN + Close(); + RINOK(Open2(inStream)); + _inStream = inStream; + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + _inStream.Release(); + _sections.Clear(); + _segments.Clear(); + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _sections.Size(); + return S_OK; +} + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool testMode = (_aTestMode != 0); + bool allFilesMode = (numItems == UInt32(-1)); + if (allFilesMode) + numItems = _sections.Size(); + if (numItems == 0) + return S_OK; + UInt64 totalSize = 0; + UInt32 i; + for (i = 0; i < numItems; i++) + totalSize += _sections[allFilesMode ? i : indices[i]].GetPackSize(); + extractCallback->SetTotal(totalSize); + + UInt64 currentTotalSize = 0; + UInt64 currentItemSize; + + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); + CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr<ICompressProgressInfo> progress = lps; + lps->Init(extractCallback, false); + + + + + + + + + + + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr<ISequentialInStream> inStream(streamSpec); + streamSpec->SetStream(_inStream); + + CDummyOutStream *outStreamSpec = new CDummyOutStream; + CMyComPtr<ISequentialOutStream> outStream(outStreamSpec); + + for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) + { + lps->InSize = lps->OutSize = currentTotalSize; + RINOK(lps->SetCur()); + Int32 askMode = testMode ? + NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + UInt32 index = allFilesMode ? i : indices[i]; + const CSection &item = _sections[index]; + currentItemSize = item.GetPackSize(); + { + CMyComPtr<ISequentialOutStream> realOutStream; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + if (!testMode && (!realOutStream)) + continue; + outStreamSpec->SetStream(realOutStream); + outStreamSpec->Init(); + } + + RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(_inStream->Seek(item.Pa, STREAM_SEEK_SET, NULL)); + streamSpec->Init(currentItemSize); + RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); + outStreamSpec->ReleaseStream(); + RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == currentItemSize) ? + + NArchive::NExtract::NOperationResult::kOK: + + NArchive::NExtract::NOperationResult::kDataError)); + } + return S_OK; + COM_TRY_END +} + +static IInArchive *CreateArc() { return new CHandler; } + +static CArcInfo g_ArcInfo = + { L"MachO", L"", 0, 0xDF, { 0 }, 0, false, CreateArc, 0 }; + +REGISTER_ARC(Macho) + +}} +
\ No newline at end of file diff --git a/CPP/7zip/Archive/MubHandler.cpp b/CPP/7zip/Archive/MubHandler.cpp new file mode 100755 index 00000000..edf00f93 --- /dev/null +++ b/CPP/7zip/Archive/MubHandler.cpp @@ -0,0 +1,264 @@ +// MubHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#include "Common/ComTry.h" + +#include "Windows/PropVariant.h" + +#include "../Common/LimitedStreams.h" +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +#include "../Compress/Copy/CopyCoder.h" + +#define Get32(p) GetBe32(p) + +namespace NArchive { +namespace NMub { + +struct CItem +{ + UInt32 Type; + UInt32 SubType; + UInt64 Offset; + UInt64 Size; + UInt32 Align; + bool IsTail; +}; + +const UInt32 kNumFilesMax = 10; + +class CHandler: + public IInArchive, + public CMyUnknownImp +{ + UInt64 _startPos; + CMyComPtr<IInStream> _inStream; + UInt32 _numItems; + CItem _items[kNumFilesMax + 1]; + HRESULT Open2(IInStream *stream); +public: + MY_UNKNOWN_IMP1(IInArchive) + INTERFACE_IInArchive(;) +}; + +STATPROPSTG kProps[] = +{ + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackSize, VT_UI8} +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO + +#define MACH_ARCH_ABI64 0x1000000 +#define MACH_MACHINE_386 7 +#define MACH_MACHINE_ARM 12 +#define MACH_MACHINE_SPARC 14 +#define MACH_MACHINE_PPC 18 + +#define MACH_MACHINE_PPC64 (MACH_MACHINE_PPC | MACH_ARCH_ABI64) +#define MACH_MACHINE_AMD64 (MACH_MACHINE_386 | MACH_ARCH_ABI64) + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant prop; + const CItem &item = _items[index]; + switch(propID) + { + case kpidExtension: + { + const wchar_t *ext; + if (item.IsTail) + ext = L"tail"; + else + { + switch(item.Type) + { + case MACH_MACHINE_386: ext = L"86"; break; + case MACH_MACHINE_ARM: ext = L"arm"; break; + case MACH_MACHINE_SPARC: ext = L"sparc"; break; + case MACH_MACHINE_PPC: ext = L"ppc"; break; + case MACH_MACHINE_PPC64: ext = L"ppc64"; break; + case MACH_MACHINE_AMD64: ext = L"x64"; break; + default: ext = L"unknown"; break; + } + } + prop = ext; + break; + } + case kpidSize: + case kpidPackSize: + prop = (UInt64)item.Size; + break; + } + prop.Detach(value); + return S_OK; +} + +#define MACH_TYPE_ABI64 (1 << 24) +#define MACH_SUBTYPE_ABI64 (1 << 31) + +HRESULT CHandler::Open2(IInStream *stream) +{ + RINOK(stream->Seek(0, STREAM_SEEK_SET, &_startPos)); + + const UInt32 kHeaderSize = 8; + const UInt32 kRecordSize = 5 * 4; + const UInt32 kBufSize = kHeaderSize + kNumFilesMax * kRecordSize; + Byte buf[kBufSize]; + size_t processed = kBufSize; + RINOK(ReadStream(stream, buf, &processed)); + if (processed < kHeaderSize) + return S_FALSE; + UInt32 num = Get32(buf + 4); + if (Get32(buf) != 0xCAFEBABE || num > kNumFilesMax || processed < kHeaderSize + num * kRecordSize) + return S_FALSE; + UInt64 endPosMax = kHeaderSize; + for (UInt32 i = 0; i < num; i++) + { + const Byte *p = buf + kHeaderSize + i * kRecordSize; + CItem &sb = _items[i]; + sb.IsTail = false; + sb.Type = Get32(p); + sb.SubType = Get32(p + 4); + sb.Offset = Get32(p + 8); + sb.Size = Get32(p + 12); + sb.Align = Get32(p + 16); + + if ((sb.Type & ~MACH_TYPE_ABI64) >= 0x100 || + (sb.SubType & ~MACH_SUBTYPE_ABI64) >= 0x100 || + sb.Align > 31) + return S_FALSE; + + UInt64 endPos = (UInt64)sb.Offset + sb.Size; + if (endPos > endPosMax) + endPosMax = endPos; + } + UInt64 fileSize; + RINOK(stream->Seek(0, STREAM_SEEK_END, &fileSize)); + fileSize -= _startPos; + _numItems = num; + if (fileSize > endPosMax) + { + CItem &sb = _items[_numItems++]; + sb.IsTail = true; + sb.Type = 0; + sb.SubType = 0; + sb.Offset = endPosMax; + sb.Size = fileSize - endPosMax; + sb.Align = 0; + } + return S_OK; +} + +STDMETHODIMP CHandler::Open(IInStream *inStream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback * /* openArchiveCallback */) +{ + COM_TRY_BEGIN + Close(); + try + { + if (Open2(inStream) != S_OK) + return S_FALSE; + _inStream = inStream; + } + catch(...) { return S_FALSE; } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + _inStream.Release(); + _numItems = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _numItems; + return S_OK; +} + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool testMode = (_aTestMode != 0); + bool allFilesMode = (numItems == UInt32(-1)); + if (allFilesMode) + numItems = _numItems; + if (numItems == 0) + return S_OK; + 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; + + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); + CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr<ICompressProgressInfo> progress = lps; + lps->Init(extractCallback, false); + + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr<ISequentialInStream> inStream(streamSpec); + streamSpec->SetStream(_inStream); + + for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) + { + lps->InSize = lps->OutSize = currentTotalSize; + RINOK(lps->SetCur()); + CMyComPtr<ISequentialOutStream> realOutStream; + Int32 askMode = testMode ? + NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + UInt32 index = allFilesMode ? i : indices[i]; + const CItem &item = _items[index]; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + currentItemSize = item.Size; + + + + + + + if (!testMode && (!realOutStream)) + continue; + RINOK(extractCallback->PrepareOperation(askMode)); + if (testMode) + { + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + continue; + } + RINOK(_inStream->Seek(_startPos + item.Offset, STREAM_SEEK_SET, NULL)); + streamSpec->Init(item.Size); + RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ? + NArchive::NExtract::NOperationResult::kOK: + NArchive::NExtract::NOperationResult::kDataError)); + } + return S_OK; + COM_TRY_END +} + +static IInArchive *CreateArc() { return new CHandler; } + +static CArcInfo g_ArcInfo = + { L"Mub", L"", 0, 0xE2, { 0xCA, 0xFE, 0xBA, 0xBE, 0, 0, 0 }, 7, false, CreateArc, 0 }; + +REGISTER_ARC(Mub) + +}} diff --git a/CPP/7zip/Archive/Nsis/NsisHandler.cpp b/CPP/7zip/Archive/Nsis/NsisHandler.cpp index b24d966d..b8945130 100755 --- a/CPP/7zip/Archive/Nsis/NsisHandler.cpp +++ b/CPP/7zip/Archive/Nsis/NsisHandler.cpp @@ -14,6 +14,10 @@ #include "../Common/ItemNameUtils.h" #include "../../Common/StreamUtils.h" +#include "../../../../C/CpuArch.h" + +#define Get32(p) GetUi32(p) + using namespace NWindows; namespace NArchive { @@ -22,7 +26,7 @@ namespace NNsis { static const wchar_t *kBcjMethod = L"BCJ"; static const wchar_t *kUnknownMethod = L"Unknown"; -static const wchar_t *kMethods[] = +static const wchar_t *kMethods[] = { L"Copy", L"Deflate", @@ -32,18 +36,17 @@ static const wchar_t *kMethods[] = static const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]); -STATPROPSTG kProps[] = +STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, - { NULL, kpidIsFolder, VT_BOOL}, { NULL, kpidSize, VT_UI8}, - { NULL, kpidPackedSize, VT_UI8}, - { NULL, kpidLastWriteTime, VT_FILETIME}, + { NULL, kpidPackSize, VT_UI8}, + { NULL, kpidMTime, VT_FILETIME}, { NULL, kpidMethod, VT_BSTR}, { NULL, kpidSolid, VT_BOOL} }; -STATPROPSTG kArcProps[] = +STATPROPSTG kArcProps[] = { { NULL, kpidMethod, VT_BSTR}, { NULL, kpidSolid, VT_BOOL} @@ -69,7 +72,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) if (item.DictionarySize > dict) dict = item.DictionarySize; } - prop = GetMethod(filter, dict); + prop = GetMethod(filter, dict); break; } case kpidSolid: prop = _archive.IsSolid; break; @@ -211,19 +214,10 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val { switch(propID) { - case kpidPath: - prop = L"[NSIS].nsi"; - break; - case kpidIsFolder: - prop = false; - break; + case kpidPath: prop = L"[NSIS].nsi"; break; case kpidSize: - case kpidPackedSize: - prop = (UInt64)_archive.Script.Length(); - break; - case kpidSolid: - prop = false; - break; + case kpidPackSize: prop = (UInt64)_archive.Script.Length(); break; + case kpidSolid: prop = false; break; } } else @@ -244,9 +238,6 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val prop = (const wchar_t *)s; break; } - case kpidIsFolder: - prop = false; - break; case kpidSize: { UInt32 size; @@ -254,28 +245,22 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val prop = (UInt64)size; break; } - case kpidPackedSize: + case kpidPackSize: { UInt32 size; if (GetCompressedSize(index, size)) prop = (UInt64)size; break; } - case kpidLastWriteTime: + case kpidMTime: { - if (item.DateTime.dwHighDateTime > 0x01000000 && - item.DateTime.dwHighDateTime < 0xFF000000) - prop = item.DateTime; + if (item.MTime.dwHighDateTime > 0x01000000 && + item.MTime.dwHighDateTime < 0xFF000000) + prop = item.MTime; break; } - case kpidMethod: - { - prop = GetMethod(item.UseFilter, item.DictionarySize); - break; - } - case kpidSolid: - prop = _archive.IsSolid; - break; + case kpidMethod: prop = GetMethod(item.UseFilter, item.DictionarySize); break; + case kpidSolid: prop = _archive.IsSolid; break; } } prop.Detach(value); @@ -409,7 +394,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, if (processedSize != 4) return E_FAIL; streamPos += processedSize; - fullSize = GetUInt32FromMemLE(buffer); + fullSize = Get32(buffer); sizeIsKnown = true; needDecompress = true; } @@ -424,7 +409,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(_archive.Decoder.Init( EXTERNAL_CODECS_VARS _inStream, _archive.Method, _archive.FilterFlag, useFilter)); - fullSize = GetUInt32FromMemLE(buffer); + fullSize = Get32(buffer); } else fullSize = item.Size; @@ -461,9 +446,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, UInt64 completed; if (_archive.IsSolid) - completed = streamPos; - else completed = currentTotalSize + offset; + else + completed = streamPos; RINOK(extractCallback->SetCompleted(&completed)); if (!testMode) RINOK(WriteStream(realOutStream, buffer, processedSize)); @@ -491,7 +476,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, } } realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(dataError ? + RINOK(extractCallback->SetOperationResult(dataError ? NArchive::NExtract::NOperationResult::kDataError : NArchive::NExtract::NOperationResult::kOK)); } diff --git a/CPP/7zip/Archive/Nsis/NsisHandler.h b/CPP/7zip/Archive/Nsis/NsisHandler.h index 5dc30107..95fea5d0 100755 --- a/CPP/7zip/Archive/Nsis/NsisHandler.h +++ b/CPP/7zip/Archive/Nsis/NsisHandler.h @@ -13,7 +13,7 @@ namespace NArchive { namespace NNsis { -class CHandler: +class CHandler: public IInArchive, PUBLIC_ISetCompressCodecsInfo public CMyUnknownImp diff --git a/CPP/7zip/Archive/Nsis/NsisIn.cpp b/CPP/7zip/Archive/Nsis/NsisIn.cpp index 5c5c872f..9e7e89bb 100755 --- a/CPP/7zip/Archive/Nsis/NsisIn.cpp +++ b/CPP/7zip/Archive/Nsis/NsisIn.cpp @@ -14,17 +14,17 @@ #include "Common/StringConvert.h" #include "Common/IntToString.h" +#include "../../../../C/CpuArch.h" + +#define Get32(p) GetUi32(p) + namespace NArchive { namespace NNsis { -Byte kSignature[kSignatureSize] = { 0xEF + 1, 0xBE, 0xAD, 0xDE, +Byte kSignature[kSignatureSize] = { 0xEF + 1, 0xBE, 0xAD, 0xDE, 0x4E, 0x75, 0x6C, 0x6C, 0x73, 0x6F, 0x66, 0x74, 0x49, 0x6E, 0x73, 0x74}; -class SignatureInitializer -{ -public: - SignatureInitializer() { kSignature[0]--; }; -} g_SignatureInitializer; +struct CSignatureInit { CSignatureInit() { kSignature[0]--; } } g_SignatureInit; #ifdef NSIS_SCRIPT static const char *kCrLf = "\x0D\x0A"; @@ -35,13 +35,7 @@ static const char *kCrLf = "\x0D\x0A"; #define NS_UN_SHELL_CODE 0xE002 #define NS_UN_LANG_CODE 0xE003 #define NS_UN_CODES_START NS_UN_SKIP_CODE -#define NS_UN_CODES_END NS_UN_LANG_CODE - - -UInt32 GetUInt32FromMemLE(const Byte *p) -{ - return p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24); -} +#define NS_UN_CODES_END NS_UN_LANG_CODE Byte CInArchive::ReadByte() { @@ -84,14 +78,30 @@ static int CompareItems(void *const *p1, void *const *p2, void * /* param */) return 0; } -AString CInArchive::ReadStringA(UInt32 pos) +static AString UIntToString(UInt32 v) +{ + char sz[32]; + ConvertUInt64ToString(v, sz); + return sz; +} + +static AString IntToString(Int32 v) +{ + char sz[32]; + ConvertInt64ToString(v, sz); + return sz; +} + +AString CInArchive::ReadStringA(UInt32 pos) const { AString s; + if (pos >= _size) + return IntToString((Int32)pos); UInt32 offset = GetOffset() + _stringsPos + pos; for (;;) { if (offset >= _size) - throw 1; + break; // throw 1; char c = _data[offset++]; if (c == 0) break; @@ -100,14 +110,14 @@ AString CInArchive::ReadStringA(UInt32 pos) return s; } -UString CInArchive::ReadStringU(UInt32 pos) +UString CInArchive::ReadStringU(UInt32 pos) const { UString s; UInt32 offset = GetOffset() + _stringsPos + (pos * 2); for (;;) { if (offset >= _size || offset + 1 >= _size) - throw 1; + return s; // throw 1; char c0 = _data[offset++]; char c1 = _data[offset++]; wchar_t c = (c0 | ((wchar_t)c1 << 8)); @@ -287,7 +297,7 @@ enum }; #ifdef NSIS_SCRIPT -static CCommandPair kCommandPairs[] = +static CCommandPair kCommandPairs[] = { { 0, "Invalid" }, { 0, "Return" }, @@ -315,7 +325,7 @@ static CCommandPair kCommandPairs[] = { 2, "Delete" }, { 5, "MessageBox" }, { 2, "RMDir" }, - { 2, "Assign" }, + { 2, "StrLen" }, { 4, "StrCpy" }, { 5, "StrCmp" }, { 3, "ReadEnvStr" }, @@ -368,7 +378,7 @@ static CCommandPair kCommandPairs[] = #endif -static const char *kShellStrings[] = +static const char *kShellStrings[] = { "", "", @@ -451,7 +461,7 @@ static const int kNumShellStrings = sizeof(kShellStrings) / sizeof(kShellStrings # define _OUTDIR 29 */ -static const char *kVarStrings[] = +static const char *kVarStrings[] = { "CMDLINE", "INSTDIR", @@ -460,6 +470,8 @@ static const char *kVarStrings[] = "LANGUAGE", "TEMP", "PLUGINSDIR", + "EXEPATH", // test it + "EXEFILE", // test it "HWNDPARENT", "_CLICK", "_OUTDIR" @@ -468,20 +480,6 @@ static const char *kVarStrings[] = static const int kNumVarStrings = sizeof(kVarStrings) / sizeof(kVarStrings[0]); -static AString UIntToString(UInt32 v) -{ - char sz[32]; - ConvertUInt64ToString(v, sz); - return sz; -} - -static AString IntToString(Int32 v) -{ - char sz[32]; - ConvertInt64ToString(v, sz); - return sz; -} - static AString GetVar(UInt32 index) { AString res = "$"; @@ -586,17 +584,17 @@ UString GetNsisString(const UString &s) return res; } -AString CInArchive::ReadString2A(UInt32 pos) +AString CInArchive::ReadString2A(UInt32 pos) const { return GetNsisString(ReadStringA(pos)); } -UString CInArchive::ReadString2U(UInt32 pos) +UString CInArchive::ReadString2U(UInt32 pos) const { return GetNsisString(ReadStringU(pos)); } -AString CInArchive::ReadString2(UInt32 pos) +AString CInArchive::ReadString2(UInt32 pos) const { if (IsUnicode) return UnicodeStringToMultiByte(ReadString2U(pos)); @@ -604,6 +602,11 @@ AString CInArchive::ReadString2(UInt32 pos) return ReadString2A(pos); } +AString CInArchive::ReadString2Qw(UInt32 pos) const +{ + return "\"" + ReadString2(pos) + "\""; +} + #define DEL_DIR 1 #define DEL_RECURSE 2 #define DEL_REBOOT 4 @@ -639,6 +642,31 @@ AString CEntry::GetParamsString(int numParams) return s; } +#ifdef NSIS_SCRIPT + +static AString GetRegRootID(UInt32 val) +{ + const char *s; + switch(val) + { + case 0: s = "SHCTX"; break; + case 0x80000000: s = "HKCR"; break; + case 0x80000001: s = "HKCU"; break; + case 0x80000002: s = "HKLM"; break; + case 0x80000003: s = "HKU"; break; + case 0x80000004: s = "HKPD"; break; + case 0x80000005: s = "HKCC"; break; + case 0x80000006: s = "HKDD"; break; + case 0x80000050: s = "HKPT"; break; + case 0x80000060: s = "HKPN"; break; + default: + return UIntToString(val); break; + } + return s; +} + +#endif + HRESULT CInArchive::ReadEntries(const CBlockHeader &bh) { _posInData = bh.Offset + GetOffset(); @@ -698,8 +726,8 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh) } /* UInt32 overwriteFlag = e.Params[0]; */ item.Pos = e.Params[2]; - item.DateTime.dwLowDateTime = e.Params[3]; - item.DateTime.dwHighDateTime = e.Params[4]; + item.MTime.dwLowDateTime = e.Params[3]; + item.MTime.dwHighDateTime = e.Params[4]; /* UInt32 allowIgnore = e.Params[5]; */ if (Items.Size() > 0) { @@ -815,18 +843,25 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh) Script += ReadString2(e.Params[0]); break; } + case EW_STRLEN: + { + Script += " "; + Script += GetVar(e.Params[0]);; + Script += " "; + Script += ReadString2Qw(e.Params[1]); + break; + } case EW_ASSIGNVAR: { Script += " "; Script += GetVar(e.Params[0]);; - Script += " \""; + Script += " "; + Script += ReadString2Qw(e.Params[1]); AString maxLen, startOffset; - Script += ReadString2(e.Params[1]); - Script += "\""; if (e.Params[2] != 0) - maxLen = ReadString(e.Params[2]); + maxLen = ReadString2(e.Params[2]); if (e.Params[3] != 0) - startOffset = ReadString(e.Params[3]); + startOffset = ReadString2(e.Params[3]); if (!maxLen.IsEmpty() || !startOffset.IsEmpty()) { Script += " "; @@ -846,13 +881,11 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh) { Script += " "; - Script += " \""; - Script += ReadString2(e.Params[0]); - Script += "\""; + Script += " "; + Script += ReadString2Qw(e.Params[0]); - Script += " \""; - Script += ReadString2(e.Params[1]); - Script += "\""; + Script += " "; + Script += ReadString2Qw(e.Params[1]); for (int j = 2; j < 5; j++) { @@ -861,6 +894,62 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh) } break; } + case EW_INTCMP: + { + if (e.Params[5] != 0) + Script += "U"; + + Script += " "; + Script += ReadString2(e.Params[0]); + Script += " "; + Script += ReadString2(e.Params[1]); + + for (int i = 2; i < 5; i++) + { + Script += " "; + Script += UIntToString(e.Params[i]); + } + break; + } + case EW_INTOP: + { + Script += " "; + Script += GetVar(e.Params[0]); + Script += " "; + int numOps = 2; + AString op; + switch (e.Params[3]) + { + case 0: op = '+'; break; + case 1: op = '-'; break; + case 2: op = '*'; break; + case 3: op = '/'; break; + case 4: op = '|'; break; + case 5: op = '&'; break; + case 6: op = '^'; break; + case 7: op = '~'; numOps = 1; break; + case 8: op = '!'; numOps = 1; break; + case 9: op = "||"; break; + case 10: op = "&&"; break; + case 11: op = '%'; break; + default: op = UIntToString(e.Params[3]); + } + AString p1 = ReadString2(e.Params[1]); + if (numOps == 1) + { + Script += op; + Script += p1; + } + else + { + Script += p1; + Script += " "; + Script += op; + Script += " "; + Script += ReadString2(e.Params[2]); + } + break; + } case EW_PUSHPOP: { @@ -888,24 +977,55 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh) break; } - /* case EW_SENDMESSAGE: { + // SendMessage: 6 [output, hwnd, msg, wparam, lparam, [wparamstring?1:0 | lparamstring?2:0 | timeout<<2] Script += " "; - Script += IntToString(e.Params[0]); - Script += " "; - Script += GetVar(e.Params[1]); + // Script += ReadString2(e.Params[0]); + // Script += " "; + Script += ReadString2(e.Params[1]); Script += " "; Script += ReadString2(e.Params[2]); + Script += " "; - Script += UIntToString(e.Params[3]); - Script += " "; - Script += IntToString(e.Params[4]); + UInt32 spec = e.Params[5]; + // if (spec & 1) + Script += IntToString(e.Params[3]); + // else + // Script += ReadString2(e.Params[3]); + Script += " "; - Script += UIntToString(e.Params[5]); + // if (spec & 2) + Script += IntToString(e.Params[4]); + // else + // Script += ReadString2(e.Params[4]); + + if ((Int32)e.Params[0] >= 0) + { + Script += " "; + Script += GetVar(e.Params[1]); + } + + spec >>= 2; + if (spec != 0) + { + Script += " /TIMEOUT="; + Script += IntToString(spec); + } break; } - */ + + case EW_GETDLGITEM: + { + Script += " "; + Script += GetVar(e.Params[0]);; + Script += " "; + Script += ReadString2(e.Params[1]); + Script += " "; + Script += ReadString2(e.Params[2]); + break; + } + case EW_REGISTERDLL: { @@ -923,14 +1043,10 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh) AString s; Script += " "; - Script += " \""; - Script += ReadString2(e.Params[0]); - Script += " \""; + Script += ReadString2Qw(e.Params[0]); Script += " "; - Script += " \""; - Script += ReadString2(e.Params[1]); - Script += " \""; + Script += ReadString2Qw(e.Params[1]); for (int j = 2; j < 5; j++) { @@ -968,6 +1084,38 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh) } */ + case EW_WRITEREG: + { + AString s; + switch(e.Params[4]) + { + case 1: s = "Str"; break; + case 2: s = "ExpandStr"; break; + case 3: s = "Bin"; break; + case 4: s = "DWORD"; break; + default: s = "?" + UIntToString(e.Params[4]); break; + } + Script += s; + Script += " "; + Script += GetRegRootID(e.Params[0]); + Script += " "; + + AString keyName, valueName; + keyName = ReadString2Qw(e.Params[1]); + Script += keyName; + Script += " "; + + valueName = ReadString2Qw(e.Params[2]); + Script += valueName; + Script += " "; + + valueName = ReadString2Qw(e.Params[3]); + Script += valueName; + Script += " "; + + break; + } + case EW_WRITEUNINSTALLER: { Script += " "; @@ -1006,7 +1154,7 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh) { Items.Sort(CompareItems, 0); int i; - // if (IsSolid) + // if (IsSolid) for (i = 0; i + 1 < Items.Size();) { bool sameName = IsUnicode ? @@ -1035,7 +1183,7 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh) RINOK(ReadStream(_stream, sig, &processedSize)); if (processedSize < 4) return S_FALSE; - UInt32 size = GetUInt32FromMemLE(sig); + UInt32 size = Get32(sig); if ((size & 0x80000000) != 0) { item.IsCompressed = true; @@ -1047,7 +1195,7 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh) return S_FALSE; if (FilterFlag) item.UseFilter = (sig[4] != 0); - item.DictionarySize = GetUInt32FromMemLE(sig + 5 + (FilterFlag ? 1 : 0)); + item.DictionarySize = Get32(sig + 5 + (FilterFlag ? 1 : 0)); } } else @@ -1085,7 +1233,7 @@ HRESULT CInArchive::Parse() int numZeros0 = 0; int numZeros1 = 0; int i; - const kBlockSize = 256; + const int kBlockSize = 256; for (i = 0; i < kBlockSize; i++) { if (pos >= _size || pos + 1 >= _size) @@ -1117,7 +1265,7 @@ HRESULT CInArchive::Parse() static bool IsLZMA(const Byte *p, UInt32 &dictionary) { - dictionary = GetUInt32FromMemLE(p + 1); + dictionary = Get32(p + 1); return (p[0] == 0x5D && p[1] == 0x00 && p[2] == 0x00 && p[5] == 0x00); } @@ -1152,7 +1300,7 @@ HRESULT CInArchive::Open2( IsSolid = true; FilterFlag = false; - UInt32 compressedHeaderSize = GetUInt32FromMemLE(sig); + UInt32 compressedHeaderSize = Get32(sig); if (compressedHeaderSize == FirstHeader.HeaderLength) { @@ -1218,7 +1366,7 @@ HRESULT CInArchive::Open2( } /* -NsisExe = +NsisExe = { ExeStub Archive // must start from 512 * N @@ -1253,51 +1401,39 @@ HRESULT CInArchive::Open( IInStream *inStream, const UInt64 *maxCheckStartPosition) { Clear(); - UInt64 pos; - RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &pos)); - RINOK(inStream->Seek(0, STREAM_SEEK_END, &_archiveSize)); - UInt64 position; - RINOK(inStream->Seek(pos, STREAM_SEEK_SET, &position)); - UInt64 maxSize = (maxCheckStartPosition != 0) ? *maxCheckStartPosition : (1 << 20); + RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL)); + UInt64 maxSize = ((maxCheckStartPosition != 0) ? *maxCheckStartPosition : 0); const UInt32 kStep = 512; - const UInt32 kStartHeaderSize = 4 * 7; Byte buffer[kStep]; - bool found = false; - UInt64 headerPosition = 0; - while (position <= maxSize) + UInt64 position = 0; + for (; position <= maxSize; position += kStep) { - RINOK(ReadStream_FALSE(inStream, buffer, kStartHeaderSize)); - headerPosition = position; - position += kStartHeaderSize; - if(memcmp(buffer + 4, kSignature, kSignatureSize) == 0) - { - found = true; + RINOK(ReadStream_FALSE(inStream, buffer, kStep)); + if (memcmp(buffer + 4, kSignature, kSignatureSize) == 0) break; - } - const UInt32 kRem = kStep - kStartHeaderSize; - RINOK(ReadStream_FALSE(inStream, buffer + kStartHeaderSize, kRem)); - position += kRem; } - if (!found) + if (position > maxSize) return S_FALSE; - FirstHeader.Flags = GetUInt32FromMemLE(buffer); - FirstHeader.HeaderLength = GetUInt32FromMemLE(buffer + kSignatureSize + 4); - FirstHeader.ArchiveSize = GetUInt32FromMemLE(buffer + kSignatureSize + 8); - if (_archiveSize - headerPosition < FirstHeader.ArchiveSize) + const UInt32 kStartHeaderSize = 4 * 7; + RINOK(inStream->Seek(0, STREAM_SEEK_END, &_archiveSize)); + RINOK(inStream->Seek(position + kStartHeaderSize, STREAM_SEEK_SET, 0)); + FirstHeader.Flags = Get32(buffer); + FirstHeader.HeaderLength = Get32(buffer + kSignatureSize + 4); + FirstHeader.ArchiveSize = Get32(buffer + kSignatureSize + 8); + if (_archiveSize - position < FirstHeader.ArchiveSize) return S_FALSE; - _stream = inStream; - HRESULT res = S_FALSE; - try - { - res = Open2( - EXTERNAL_CODECS_LOC_VARS2 - ); + try + { + _stream = inStream; + HRESULT res = Open2(EXTERNAL_CODECS_LOC_VARS2); + if (res != S_OK) + Clear(); + _stream.Release(); + return res; } - catch(...) { Clear(); res = S_FALSE; } - _stream.Release(); - return res; + catch(...) { Clear(); return S_FALSE; } } void CInArchive::Clear() @@ -1306,6 +1442,7 @@ void CInArchive::Clear() Script.Empty(); #endif Items.Clear(); + _stream.Release(); } }} diff --git a/CPP/7zip/Archive/Nsis/NsisIn.h b/CPP/7zip/Archive/Nsis/NsisIn.h index e7908862..4257b687 100755 --- a/CPP/7zip/Archive/Nsis/NsisIn.h +++ b/CPP/7zip/Archive/Nsis/NsisIn.h @@ -37,7 +37,7 @@ struct CFirstHeader UInt32 ArchiveSize; - bool ThereIsCrc() const + bool ThereIsCrc() const { if ((Flags & NFlags::kForceCrc ) != 0) return true; @@ -60,7 +60,7 @@ struct CItem UString PrefixU; AString NameA; UString NameU; - FILETIME DateTime; + FILETIME MTime; bool IsUnicode; bool UseFilter; bool IsCompressed; @@ -73,7 +73,7 @@ struct CItem UInt32 EstimatedSize; UInt32 DictionarySize; - CItem(): IsUnicode(false), UseFilter(false), IsCompressed(true), SizeIsDefined(false), + CItem(): IsUnicode(false), UseFilter(false), IsCompressed(true), SizeIsDefined(false), CompressedSizeIsDefined(false), EstimatedSizeIsDefined(false), Size(0) {} bool IsINSTDIR() const @@ -81,7 +81,7 @@ struct CItem return (PrefixA.Length() >= 3 || PrefixU.Length() >= 3); } - AString GetReducedNameA() const + AString GetReducedNameA() const { AString prefix = PrefixA; if (prefix.Length() > 0) @@ -94,7 +94,7 @@ struct CItem return s2; } - UString GetReducedNameU() const + UString GetReducedNameU() const { UString prefix = PrefixU; if (prefix.Length() > 0) @@ -120,11 +120,12 @@ class CInArchive DECL_EXTERNAL_CODECS_LOC_VARS2 ); void ReadBlockHeader(CBlockHeader &bh); - AString ReadStringA(UInt32 pos); - UString ReadStringU(UInt32 pos); - AString ReadString2A(UInt32 pos); - UString ReadString2U(UInt32 pos); - AString ReadString2(UInt32 pos); + AString ReadStringA(UInt32 pos) const; + UString ReadStringU(UInt32 pos) const; + AString ReadString2A(UInt32 pos) const; + UString ReadString2U(UInt32 pos) const; + AString ReadString2(UInt32 pos) const; + AString ReadString2Qw(UInt32 pos) const; HRESULT ReadEntries(const CBlockHeader &bh); HRESULT Parse(); @@ -165,14 +166,14 @@ public: return GetOffset() + FirstHeader.HeaderLength + item.Pos; } - UInt64 GetPosOfSolidItem(int index) const - { + UInt64 GetPosOfSolidItem(int index) const + { const CItem &item = Items[index]; return 4 + FirstHeader.HeaderLength + item.Pos; } - UInt64 GetPosOfNonSolidItem(int index) const - { + UInt64 GetPosOfNonSolidItem(int index) const + { const CItem &item = Items[index]; return StreamOffset + _nonSolidStartOffset + 4 + item.Pos; } @@ -184,8 +185,6 @@ public: }; -UInt32 GetUInt32FromMemLE(const Byte *p); - }} #endif diff --git a/CPP/7zip/Archive/Nsis/NsisRegister.cpp b/CPP/7zip/Archive/Nsis/NsisRegister.cpp index 81dd2c82..7e6f7acb 100755 --- a/CPP/7zip/Archive/Nsis/NsisRegister.cpp +++ b/CPP/7zip/Archive/Nsis/NsisRegister.cpp @@ -8,7 +8,7 @@ static IInArchive *CreateArc() { return new NArchive::NNsis::CHandler; } static CArcInfo g_ArcInfo = - { L"Nsis", 0, 0, 0x9, { 0xEF, 0xBE, 0xAD, 0xDE, + { L"Nsis", 0, 0, 0x9, { 0xEF, 0xBE, 0xAD, 0xDE, 0x4E, 0x75, 0x6C, 0x6C, 0x73, 0x6F, 0x66, 0x74, 0x49, 0x6E, 0x73, 0x74}, 16, false, CreateArc, 0 }; REGISTER_ARC(Nsis) diff --git a/CPP/7zip/Archive/Nsis/StdAfx.cpp b/CPP/7zip/Archive/Nsis/StdAfx.cpp deleted file mode 100755 index d0feea85..00000000 --- a/CPP/7zip/Archive/Nsis/StdAfx.cpp +++ /dev/null @@ -1,3 +0,0 @@ -// StdAfx.cpp - -#include "StdAfx.h" diff --git a/CPP/7zip/Archive/PeHandler.cpp b/CPP/7zip/Archive/PeHandler.cpp new file mode 100755 index 00000000..88808b56 --- /dev/null +++ b/CPP/7zip/Archive/PeHandler.cpp @@ -0,0 +1,892 @@ +// PeHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#include "Common/Buffer.h" +#include "Common/ComTry.h" +#include "Common/IntToString.h" + +#include "Windows/PropVariantUtils.h" +#include "Windows/Time.h" + +#include "../Common/LimitedStreams.h" +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +#include "../Compress/Copy/CopyCoder.h" + +#include "Common/DummyOutStream.h" + +#define Get16(p) GetUi16(p) +#define Get32(p) GetUi32(p) +#define Get64(p) GetUi64(p) + +using namespace NWindows; + +namespace NArchive { +namespace NPe { + +#define NUM_SCAN_SECTIONS_MAX (1 << 6) + +#define PE_SIG 0x00004550 +#define PE_OptHeader_Magic_32 0x10B +#define PE_OptHeader_Magic_64 0x20B + +static AString GetDecString(UInt32 v) +{ + char sz[32]; + ConvertUInt64ToString(v, sz); + return sz; +} + +struct CVersion +{ + UInt16 Major; + UInt16 Minor; + + void Parse(const Byte *buf); + AString GetString() const { return GetDecString(Major) + '.' + GetDecString(Minor); } +}; + +void CVersion::Parse(const Byte *p) +{ + Major = Get16(p); + Minor = Get16(p + 2); +} + +static const UInt32 kHeaderSize = 4 + 20; + +struct CHeader +{ + UInt16 NumSections; + UInt32 Time; + UInt32 PointerToSymbolTable; + UInt32 NumSymbols; + UInt16 OptHeaderSize; + UInt16 Flags; + UInt16 Machine; + + bool Parse(const Byte *buf); +}; + +bool CHeader::Parse(const Byte *p) +{ + if (Get32(p) != PE_SIG) + return false; + p += 4; + Machine = Get16(p + 0); + NumSections = Get16(p + 2); + Time = Get32(p + 4); + PointerToSymbolTable = Get32(p + 8); + NumSymbols = Get32(p + 12); + OptHeaderSize = Get16(p + 16); + Flags = Get16(p + 18); + return true; +} + +struct CDirLink +{ + UInt32 Va; + UInt32 Size; + void Parse(const Byte *p); +}; + +void CDirLink::Parse(const Byte *p) +{ + Va = Get32(p); + Size = Get32(p + 4); +}; + +enum +{ + kDirLink_Certificate = 4, + kDirLink_Debug = 6 +}; + +struct CDebugEntry +{ + UInt32 Flags; + UInt32 Time; + CVersion Ver; + UInt32 Type; + UInt32 Size; + UInt32 Va; + UInt32 Pa; + + void Parse(const Byte *p); +}; + +void CDebugEntry::Parse(const Byte *p) +{ + Flags = Get32(p); + Time = Get32(p + 4); + Ver.Parse(p + 8); + Type = Get32(p + 12); + Size = Get32(p + 16); + Va = Get32(p + 20); + Pa = Get32(p + 24); +} + +static const kNumDirItemsMax = 16; + +struct COptHeader +{ + UInt16 Magic; + Byte LinkerVerMajor; + Byte LinkerVerMinor; + + UInt32 CodeSize; + UInt32 InitDataSize; + UInt32 UninitDataSize; + + // UInt32 AddressOfEntryPoint; + // UInt32 BaseOfCode; + // UInt32 BaseOfData32; + // UInt64 ImageBase; + + UInt32 SectAlign; + UInt32 FileAlign; + + CVersion OsVer; + CVersion ImageVer; + CVersion SubsysVer; + + UInt32 ImageSize; + UInt32 HeadersSize; + UInt32 CheckSum; + UInt16 SubSystem; + UInt16 DllCharacts; + + UInt64 StackReserve; + UInt64 StackCommit; + UInt64 HeapReserve; + UInt64 HeapCommit; + + UInt32 NumDirItems; + CDirLink DirItems[kNumDirItemsMax]; + + bool Is64Bit() const { return Magic == PE_OptHeader_Magic_64; } + bool Parse(const Byte *p, UInt32 size); +}; + +bool COptHeader::Parse(const Byte *p, UInt32 size) +{ + Magic = Get16(p); + switch (Magic) + { + case PE_OptHeader_Magic_32: + case PE_OptHeader_Magic_64: + break; + default: + return false; + } + LinkerVerMajor = p[2]; + LinkerVerMinor = p[3]; + + bool hdr64 = Is64Bit(); + + CodeSize = Get32(p + 4); + InitDataSize = Get32(p + 8); + UninitDataSize = Get32(p + 12); + + // AddressOfEntryPoint = Get32(p + 16); + // BaseOfCode = Get32(p + 20); + // BaseOfData32 = Get32(p + 24); + // ImageBase = hdr64 ? GetUi64(p + 24) :Get32(p + 28); + + SectAlign = Get32(p + 32); + FileAlign = Get32(p + 36); + + OsVer.Parse(p + 40); + ImageVer.Parse(p + 44); + SubsysVer.Parse(p + 48); + + // reserved = Get32(p + 52); + + ImageSize = Get32(p + 56); + HeadersSize = Get32(p + 60); + CheckSum = Get32(p + 64); + SubSystem = Get16(p + 68); + DllCharacts = Get16(p + 70); + + if (hdr64) + { + StackReserve = Get64(p + 72); + StackCommit = Get64(p + 80); + HeapReserve = Get64(p + 88); + HeapCommit = Get64(p + 96); + } + else + { + StackReserve = Get32(p + 72); + StackCommit = Get32(p + 76); + HeapReserve = Get32(p + 80); + HeapCommit = Get32(p + 84); + } + UInt32 pos = (hdr64 ? 108 : 92); + NumDirItems = Get32(p + pos); + pos += 4; + if (pos + 8 * NumDirItems != size) + return false; + for (UInt32 i = 0; i < NumDirItems && i < kNumDirItemsMax; i++) + DirItems[i].Parse(p + pos + i * 8); + return true; +} + +static const UInt32 kSectionSize = 40; + +struct CSection +{ + AString Name; + + UInt32 VSize; + UInt32 Va; + UInt32 PSize; + UInt32 Pa; + UInt32 Flags; + UInt32 Time; + // UInt16 NumRelocs; + bool IsDebug; + bool IsRealSect; + + CSection(): IsRealSect(false), IsDebug(false) {} + UInt64 GetPackSize() const { return PSize; } + + void UpdateTotalSize(UInt32 &totalSize) + { + UInt32 t = Pa + PSize; + if (t > totalSize) + totalSize = t; + } + void Parse(const Byte *p); +}; + +static AString GetName(const Byte *name) +{ + const int kNameSize = 8; + AString res; + char *p = res.GetBuffer(kNameSize); + memcpy(p, name, kNameSize); + p[kNameSize] = 0; + res.ReleaseBuffer(); + return res; +} + +void CSection::Parse(const Byte *p) +{ + Name = GetName(p); + VSize = Get32(p + 8); + Va = Get32(p + 12); + PSize = Get32(p + 16); + Pa = Get32(p + 20); + // NumRelocs = Get16(p + 32); + Flags = Get32(p + 36); +} + +static const CUInt32PCharPair g_HeaderCharacts[] = +{ + { 1 << 1, "Executable" }, + { 1 << 13, "DLL" }, + { 1 << 8, "32-bit" }, + { 1 << 5, "LargeAddress" }, + { 1 << 0, "NoRelocs" }, + { 1 << 2, "NoLineNums" }, + { 1 << 3, "NoLocalSyms" }, + { 1 << 4, "AggressiveWsTrim" }, + { 1 << 9, "NoDebugInfo" }, + { 1 << 10, "RemovableRun" }, + { 1 << 11, "NetRun" }, + { 1 << 12, "System" }, + { 1 << 14, "UniCPU" }, + { 1 << 7, "Little-Endian" }, + { 1 << 15, "Big-Endian" } +}; + +static const CUInt32PCharPair g_DllCharacts[] = +{ + { 1 << 6, "Relocated" }, + { 1 << 7, "Integrity" }, + { 1 << 8, "NX-Compatible" }, + { 1 << 9, "NoIsolation" }, + { 1 << 10, "NoSEH" }, + { 1 << 11, "NoBind" }, + { 1 << 13, "WDM" }, + { 1 << 15, "TerminalServerAware" } +}; + +static const CUInt32PCharPair g_SectFlags[] = +{ + { 1 << 3, "NoPad" }, + { 1 << 5, "Code" }, + { 1 << 6, "InitializedData" }, + { 1 << 7, "UninitializedData" }, + { 1 << 9, "Comments" }, + { 1 << 11, "Remove" }, + { 1 << 12, "COMDAT" }, + { 1 << 15, "GP" }, + { 1 << 24, "ExtendedRelocations" }, + { 1 << 25, "Discardable" }, + { 1 << 26, "NotCached" }, + { 1 << 27, "NotPaged" }, + { 1 << 28, "Shared" }, + { 1 << 29, "Execute" }, + { 1 << 30, "Read" }, + { (UInt32)1 << 31, "Write" } +}; + +static const CUInt32PCharPair g_MachinePairs[] = +{ + { 0x014C, "x86" }, + { 0x0162, "MIPS-R3000" }, + { 0x0166, "MIPS-R4000" }, + { 0x0168, "MIPS-R10000" }, + { 0x0169, "MIPS-V2" }, + { 0x0184, "Alpha" }, + { 0x01A2, "SH3" }, + { 0x01A3, "SH3-DSP" }, + { 0x01A4, "SH3E" }, + { 0x01A6, "SH4" }, + { 0x01A8, "SH5" }, + { 0x01C0, "ARM" }, + { 0x01C2, "ARM-Thumb" }, + { 0x01F0, "PPC" }, + { 0x01F1, "PPC-FP" }, + { 0x0200, "IA-64" }, + { 0x0284, "Alpha-64" }, + { 0x0200, "IA-64" }, + { 0x0366, "MIPSFPU" }, + { 0x8664, "x64" }, + { 0x0EBC, "EFI" } +}; + +static const CUInt32PCharPair g_SubSystems[] = +{ + { 0, "Unknown" }, + { 1, "Native" }, + { 2, "Windows GUI" }, + { 3, "Windows CUI" }, + { 7, "Posix" }, + { 9, "Windows CE" }, + { 10, "EFI" }, + { 11, "EFI Boot" }, + { 12, "EFI Runtime" }, + { 13, "EFI ROM" }, + { 14, "XBOX" } +}; + +class CHandler: + public IInArchive, + public CMyUnknownImp +{ + CMyComPtr<IInStream> _inStream; + CObjectVector<CSection> _sections; + UInt32 _peOffset; + CHeader _header; + COptHeader _optHeader; + UInt32 _totalSize; + UInt32 _totalSizeLimited; + HRESULT LoadDebugSections(IInStream *stream, bool &thereIsSection); + HRESULT Open2(IInStream *stream); + bool Parse(const Byte *buf, UInt32 size); +public: + MY_UNKNOWN_IMP1(IInArchive) + INTERFACE_IInArchive(;) +}; + +bool CHandler::Parse(const Byte *buf, UInt32 size) +{ + UInt32 i; + if (size < 512) + return false; + _peOffset = Get32(buf + 0x3C); + if (_peOffset >= 0x1000 || _peOffset + 512 > size || (_peOffset & 7) != 0) + return false; + + UInt32 pos = _peOffset; + if (!_header.Parse(buf + pos)) + return false; + if (_header.OptHeaderSize > 512 || _header.NumSections > NUM_SCAN_SECTIONS_MAX) + return false; + pos += kHeaderSize; + + if (!_optHeader.Parse(buf + pos, _header.OptHeaderSize)) + return false; + + pos += _header.OptHeaderSize; + _totalSize = pos; + + for (i = 0; i < _header.NumSections; i++, pos += kSectionSize) + { + CSection sect; + if (pos + kSectionSize > size) + return false; + sect.Parse(buf + pos); + sect.IsRealSect = true; + sect.UpdateTotalSize(_totalSize); + _sections.Add(sect); + } + + return true; +} + +enum +{ + kpidSectAlign = kpidUserDefined, + kpidFileAlign, + kpidLinkerVer, + kpidOsVer, + kpidImageVer, + kpidSubsysVer, + kpidCodeSize, + kpidImageSize, + kpidInitDataSize, + kpidUnInitDataSize, + kpidHeadersSizeUnInitDataSize, + kpidSubSystem, + kpidDllCharacts, + kpidStackReserve, + kpidStackCommit, + kpidHeapReserve, + kpidHeapCommit, +}; + +STATPROPSTG kArcProps[] = +{ + { NULL, kpidCpu, VT_BSTR}, + { NULL, kpidBit64, VT_BOOL}, + { NULL, kpidCharacts, VT_BSTR}, + { NULL, kpidCTime, VT_FILETIME}, + { NULL, kpidPhySize, VT_UI4}, + { NULL, kpidHeadersSize, VT_UI4}, + { NULL, kpidChecksum, VT_UI4}, + { L"Image Size", kpidImageSize, VT_UI4}, + { L"Section Alignment", kpidSectAlign, VT_UI4}, + { L"File Alignment", kpidFileAlign, VT_UI4}, + { L"Code Size", kpidCodeSize, VT_UI4}, + { L"Initialized Data Size", kpidInitDataSize, VT_UI4}, + { L"Uninitialized Data Size", kpidUnInitDataSize, VT_UI4}, + { L"Linker Version", kpidLinkerVer, VT_BSTR}, + { L"OS Version", kpidOsVer, VT_BSTR}, + { L"Image Version", kpidImageVer, VT_BSTR}, + { L"Subsystem Version", kpidSubsysVer, VT_BSTR}, + { L"Subsystem", kpidSubSystem, VT_BSTR}, + { L"DLL Characteristics", kpidDllCharacts, VT_BSTR}, + { L"Stack Reserve", kpidStackReserve, VT_UI8}, + { L"Stack Commit", kpidStackCommit, VT_UI8}, + { L"Heap Reserve", kpidHeapReserve, VT_UI8}, + { L"Heap Commit", kpidHeapCommit, VT_UI8}, + }; + +STATPROPSTG kProps[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackSize, VT_UI8}, + { NULL, kpidCharacts, VT_BSTR}, + { NULL, kpidOffset, VT_UI8}, + { NULL, kpidVa, VT_UI8} +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_WITH_NAME + +static void VerToProp(const CVersion &v, NCOM::CPropVariant &prop) +{ + StringToProp(v.GetString(), prop); +} + +void TimeToProp(UInt32 unixTime, NCOM::CPropVariant &prop) +{ + if (unixTime != 0) + { + FILETIME ft; + NTime::UnixTimeToFileTime(unixTime, ft); + prop = ft; + } +} + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + switch(propID) + { + case kpidSectAlign: prop = _optHeader.SectAlign; break; + case kpidFileAlign: prop = _optHeader.FileAlign; break; + case kpidLinkerVer: + { + CVersion v = { _optHeader.LinkerVerMajor, _optHeader.LinkerVerMinor }; + VerToProp(v, prop); break; + break; + } + + case kpidOsVer: VerToProp(_optHeader.OsVer, prop); break; + case kpidImageVer: VerToProp(_optHeader.ImageVer, prop); break; + case kpidSubsysVer: VerToProp(_optHeader.SubsysVer, prop); break; + case kpidCodeSize: prop = _optHeader.CodeSize; break; + case kpidInitDataSize: prop = _optHeader.InitDataSize; break; + case kpidUnInitDataSize: prop = _optHeader.UninitDataSize; break; + case kpidImageSize: prop = _optHeader.ImageSize; break; + case kpidPhySize: prop = _totalSize; break; + case kpidHeadersSize: prop = _optHeader.HeadersSize; break; + case kpidChecksum: prop = _optHeader.CheckSum; break; + + case kpidCpu: PAIR_TO_PROP(g_MachinePairs, _header.Machine, prop); break; + case kpidBit64: if (_optHeader.Is64Bit()) prop = true; break; + case kpidSubSystem: PAIR_TO_PROP(g_SubSystems, _optHeader.SubSystem, prop); break; + + case kpidMTime: + case kpidCTime: TimeToProp(_header.Time, prop); break; + case kpidCharacts: FLAGS_TO_PROP(g_HeaderCharacts, _header.Flags, prop); break; + case kpidDllCharacts: FLAGS_TO_PROP(g_DllCharacts, _optHeader.DllCharacts, prop); break; + case kpidStackReserve: prop = _optHeader.StackReserve; break; + case kpidStackCommit: prop = _optHeader.StackCommit; break; + case kpidHeapReserve: prop = _optHeader.HeapReserve; break; + case kpidHeapCommit: prop = _optHeader.HeapCommit; break; + + /* + if (_optHeader.Is64Bit()) + s += " 64-bit"; + */ + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + const CSection &item = _sections[index]; + switch(propID) + { + case kpidPath: StringToProp(item.Name, prop); break; + case kpidSize: prop = (UInt64)item.VSize; break; + case kpidPackSize: prop = (UInt64)item.GetPackSize(); break; + case kpidOffset: prop = item.Pa; break; + case kpidVa: if (item.IsRealSect) prop = item.Va; break; + case kpidMTime: + case kpidCTime: + TimeToProp(item.IsDebug ? item.Time : _header.Time, prop); break; + case kpidCharacts: if (item.IsRealSect) FLAGS_TO_PROP(g_SectFlags, item.Flags, prop); break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +HRESULT CHandler::LoadDebugSections(IInStream *stream, bool &thereIsSection) +{ + thereIsSection = false; + const CDirLink &debugLink = _optHeader.DirItems[kDirLink_Debug]; + if (debugLink.Size == 0) + return S_OK; + const unsigned kEntrySize = 28; + UInt32 numItems = debugLink.Size / kEntrySize; + if (numItems * kEntrySize != debugLink.Size || numItems > 16) + return S_FALSE; + + UInt64 pa = 0; + int i; + for (i = 0; i < _sections.Size(); i++) + { + const CSection § = _sections[i]; + if (sect.Va < debugLink.Va && debugLink.Va + debugLink.Size <= sect.Va + sect.PSize) + { + pa = sect.Pa + (debugLink.Va - sect.Va); + break; + } + } + if (i == _sections.Size()) + return S_FALSE; + + CByteBuffer buffer; + buffer.SetCapacity(debugLink.Size); + Byte *buf = buffer; + + RINOK(stream->Seek(pa, STREAM_SEEK_SET, NULL)); + RINOK(ReadStream_FALSE(stream, buf, debugLink.Size)); + + for (i = 0; i < (int)numItems; i++) + { + CDebugEntry de; + de.Parse(buf); + + if (de.Size == 0) + continue; + + CSection sect; + sect.Name = ".debug" + GetDecString(i); + + sect.IsDebug = true; + sect.Time = de.Time; + sect.Va = de.Va; + sect.Pa = de.Pa; + sect.PSize = sect.VSize = de.Size; + UInt32 totalSize = sect.Pa + sect.PSize; + if (totalSize > _totalSize) + { + _totalSize = totalSize; + _sections.Add(sect); + thereIsSection = true; + } + buf += kEntrySize; + } + + return S_OK; +} + +HRESULT CHandler::Open2(IInStream *stream) +{ + const UInt32 kBufSize = 1 << 18; + const UInt32 kSigSize = 2; + + CByteBuffer buffer; + buffer.SetCapacity(kBufSize); + Byte *buf = buffer; + + size_t processed = kSigSize; + RINOK(ReadStream_FALSE(stream, buf, processed)); + if (buf[0] != 'M' || buf[1] != 'Z') + return S_FALSE; + processed = kBufSize - kSigSize; + RINOK(ReadStream(stream, buf + kSigSize, &processed)); + processed += kSigSize; + if (!Parse(buf, (UInt32)processed)) + return S_FALSE; + bool thereISDebug; + RINOK(LoadDebugSections(stream, thereISDebug)); + + const CDirLink &certLink = _optHeader.DirItems[kDirLink_Certificate]; + if (certLink.Size != 0) + { + CSection sect; + sect.Name = "CERTIFICATE"; + sect.Va = 0; + sect.Pa = certLink.Va; + sect.PSize = sect.VSize = certLink.Size; + sect.UpdateTotalSize(_totalSize); + _sections.Add(sect); + } + + if (thereISDebug) + { + const UInt32 kAlign = 1 << 12; + UInt32 alignPos = _totalSize & (kAlign - 1); + if (alignPos != 0) + { + UInt32 size = kAlign - alignPos; + RINOK(stream->Seek(_totalSize, STREAM_SEEK_SET, NULL)); + buffer.Free(); + buffer.SetCapacity(kAlign); + Byte *buf = buffer; + size_t processed = size; + RINOK(ReadStream(stream, buf, &processed)); + size_t i; + for (i = 0; i < processed; i++) + { + if (buf[i] != 0) + break; + } + if (processed < size && processed < 100) + _totalSize += (UInt32)processed; + else if (((_totalSize + i) & 0x1FF) == 0 || processed < size) + _totalSize += (UInt32)i; + } + } + + if (_header.NumSymbols > 0 && _header.PointerToSymbolTable >= 512) + { + if (_header.NumSymbols >= (1 << 24)) + return S_FALSE; + CSection sect; + sect.Name = "COFF_SYMBOLS"; + UInt32 size = _header.NumSymbols * 18; + RINOK(stream->Seek((UInt64)_header.PointerToSymbolTable + size, STREAM_SEEK_SET, NULL)); + Byte buf[4]; + RINOK(ReadStream_FALSE(stream, buf, 4)); + UInt32 size2 = Get32(buf); + if (size2 >= (1 << 28)) + return S_FALSE; + size += size2; + + sect.Va = 0; + sect.Pa = _header.PointerToSymbolTable; + sect.PSize = sect.VSize = size; + sect.UpdateTotalSize(_totalSize); + _sections.Add(sect); + } + + UInt64 fileSize; + RINOK(stream->Seek(0, STREAM_SEEK_END, &fileSize)); + if (fileSize > _totalSize) + return S_FALSE; + _totalSizeLimited = (_totalSize < fileSize) ? _totalSize : (UInt32)fileSize; + return S_OK; +} + +HRESULT CalcCheckSum(ISequentialInStream *stream, UInt32 size, UInt32 excludePos, UInt32 &res) +{ + // size &= ~1; + const UInt32 kBufSize = 1 << 23; + CByteBuffer buffer; + buffer.SetCapacity(kBufSize); + Byte *buf = buffer; + + UInt32 sum = 0; + UInt32 pos; + for(pos = 0;;) + { + UInt32 rem = size - pos; + if (rem > kBufSize) + rem = kBufSize; + if (rem == 0) + break; + size_t processed = rem; + RINOK(ReadStream(stream, buf, &processed)); + + /* + */ + /* + for (; processed < rem; processed++) + buf[processed] = 0; + */ + + if ((processed & 1) != 0) + buf[processed] = 0; + + for (int j = 0; j < 4; j++) + { + UInt32 p = excludePos + j; + if (pos <= p && p < pos + processed) + buf[p - pos] = 0; + } + + for (size_t i = 0; i < processed; i += 2) + { + sum += Get16(buf + i); + sum = (sum + (sum >> 16)) & 0xFFFF; + } + pos += (UInt32)processed; + if (rem != processed) + break; + } + sum += pos; + res = sum; + return S_OK; +} + +STDMETHODIMP CHandler::Open(IInStream *inStream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback * /* openArchiveCallback */) +{ + COM_TRY_BEGIN + Close(); + RINOK(Open2(inStream)); + _inStream = inStream; + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + _inStream.Release(); + _sections.Clear(); + + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _sections.Size(); + return S_OK; +} + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool testMode = (_aTestMode != 0); + bool allFilesMode = (numItems == UInt32(-1)); + if (allFilesMode) + numItems = _sections.Size(); + if (numItems == 0) + return S_OK; + UInt64 totalSize = 0; + UInt32 i; + for (i = 0; i < numItems; i++) + totalSize += _sections[allFilesMode ? i : indices[i]].GetPackSize(); + extractCallback->SetTotal(totalSize); + + UInt64 currentTotalSize = 0; + UInt64 currentItemSize; + + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); + CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr<ICompressProgressInfo> progress = lps; + lps->Init(extractCallback, false); + + bool checkSumOK = true; + if (_optHeader.CheckSum != 0 && (int)numItems == _sections.Size()) + { + UInt32 checkSum = 0; + RINOK(_inStream->Seek(0, STREAM_SEEK_SET, NULL)); + CalcCheckSum(_inStream, _totalSizeLimited, _peOffset + kHeaderSize + 64, checkSum); + checkSumOK = (checkSum == _optHeader.CheckSum); + } + + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr<ISequentialInStream> inStream(streamSpec); + streamSpec->SetStream(_inStream); + + CDummyOutStream *outStreamSpec = new CDummyOutStream; + CMyComPtr<ISequentialOutStream> outStream(outStreamSpec); + + for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) + { + lps->InSize = lps->OutSize = currentTotalSize; + RINOK(lps->SetCur()); + Int32 askMode = testMode ? + NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + UInt32 index = allFilesMode ? i : indices[i]; + const CSection &item = _sections[index]; + currentItemSize = item.GetPackSize(); + { + CMyComPtr<ISequentialOutStream> realOutStream; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + if (!testMode && (!realOutStream)) + continue; + outStreamSpec->SetStream(realOutStream); + outStreamSpec->Init(); + } + + RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(_inStream->Seek(item.Pa, STREAM_SEEK_SET, NULL)); + streamSpec->Init(currentItemSize); + RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); + outStreamSpec->ReleaseStream(); + RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == currentItemSize) ? + checkSumOK ? + NArchive::NExtract::NOperationResult::kOK: + NArchive::NExtract::NOperationResult::kCRCError: + NArchive::NExtract::NOperationResult::kDataError)); + } + return S_OK; + COM_TRY_END +} + +static IInArchive *CreateArc() { return new CHandler; } + +static CArcInfo g_ArcInfo = + { L"PE", L"", 0, 0xDD, { 0 }, 0, false, CreateArc, 0 }; + +REGISTER_ARC(Pe) + +}} diff --git a/CPP/7zip/Archive/RPM/RpmHandler.cpp b/CPP/7zip/Archive/RPM/RpmHandler.cpp deleted file mode 100755 index 9a9f9af4..00000000 --- a/CPP/7zip/Archive/RPM/RpmHandler.cpp +++ /dev/null @@ -1,152 +0,0 @@ -// RPM/Handler.cpp - -#include "StdAfx.h" - -#include "RpmHandler.h" -#include "RpmIn.h" - -#include "Common/ComTry.h" -#include "Common/MyString.h" - -#include "Windows/PropVariant.h" - -#include "../../Common/ProgressUtils.h" -#include "../../Common/StreamUtils.h" - -#include "../../Compress/Copy/CopyCoder.h" - -using namespace NWindows; - -namespace NArchive { -namespace NRpm { - -STATPROPSTG kProps[] = -{ - { NULL, kpidSize, VT_UI8}, - { NULL, kpidPackedSize, VT_UI8} -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps_NO - -STDMETHODIMP CHandler::Open(IInStream *inStream, - const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback * /* openArchiveCallback */) -{ - COM_TRY_BEGIN - try - { - if(OpenArchive(inStream) != S_OK) - return S_FALSE; - RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_Pos)); - UInt64 endPosition; - RINOK(inStream->Seek(0, STREAM_SEEK_END, &endPosition)); - m_Size = endPosition - m_Pos; - - RINOK(inStream->Seek(m_Pos, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(inStream, _sig, sizeof(_sig) / sizeof(_sig[0]))); - - m_InStream = inStream; - return S_OK; - } - catch(...) - { - return S_FALSE; - } - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - m_InStream.Release(); - return S_OK; -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = 1; - return S_OK; -} - -STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) -{ - NWindows::NCOM::CPropVariant prop; - switch(propID) - { - case kpidSize: - case kpidPackedSize: - prop = m_Size; - break; - case kpidExtension: - { - wchar_t s[32]; - MyStringCopy(s, L"cpio."); - const wchar_t *ext; - if (_sig[0] == 0x1F && _sig[1] == 0x8B) - ext = L"gz"; - else if (_sig[0] == 'B' && _sig[1] == 'Z' && _sig[2] == 'h') - ext = L"bz2"; - else - ext = L"lzma"; - MyStringCopy(s + MyStringLen(s), ext); - prop = s; - break; - } - } - prop.Detach(value); - return S_OK; -} - -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 _aTestMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - bool allFilesMode = (numItems == UInt32(-1)); - if (allFilesMode) - numItems = 1; - if(numItems == 0) - return S_OK; - if(numItems != 1) - return E_FAIL; - if (indices[0] != 0) - return E_FAIL; - - bool testMode = (_aTestMode != 0); - - UInt64 currentTotalSize = 0; - RINOK(extractCallback->SetTotal(m_Size)); - RINOK(extractCallback->SetCompleted(¤tTotalSize)); - CMyComPtr<ISequentialOutStream> realOutStream; - Int32 askMode = testMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; - Int32 index = 0; - - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - - if(!testMode && (!realOutStream)) - return S_OK; - - RINOK(extractCallback->PrepareOperation(askMode)); - - if (testMode) - { - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); - return S_OK; - } - - RINOK(m_InStream->Seek(m_Pos, STREAM_SEEK_SET, NULL)); - - CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr<ICompressProgressInfo> progress = lps; - lps->Init(extractCallback, false); - - RINOK(copyCoder->Code(m_InStream, realOutStream, NULL, NULL, progress)); - realOutStream.Release(); - return extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK); - COM_TRY_END -} - -}} diff --git a/CPP/7zip/Archive/RPM/RpmHandler.h b/CPP/7zip/Archive/RPM/RpmHandler.h deleted file mode 100755 index 92efc107..00000000 --- a/CPP/7zip/Archive/RPM/RpmHandler.h +++ /dev/null @@ -1,30 +0,0 @@ -// RPM/Handler.h - -#ifndef __RPM_HANDLER_H -#define __RPM_HANDLER_H - -#include "Common/MyCom.h" -#include "../IArchive.h" - -namespace NArchive { -namespace NRpm { - -class CHandler: - public IInArchive, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP1(IInArchive) - - INTERFACE_IInArchive(;) - -private: - CMyComPtr<IInStream> m_InStream; - UInt64 m_Pos; - UInt64 m_Size; - Byte _sig[4]; -}; - -}} - -#endif diff --git a/CPP/7zip/Archive/RPM/RpmHeader.h b/CPP/7zip/Archive/RPM/RpmHeader.h deleted file mode 100755 index d76963bd..00000000 --- a/CPP/7zip/Archive/RPM/RpmHeader.h +++ /dev/null @@ -1,63 +0,0 @@ -// Archive/RpmHeader.h - -#ifndef __ARCHIVE_RPM_HEADER_H -#define __ARCHIVE_RPM_HEADER_H - -#include "Common/Types.h" - -namespace NArchive { -namespace NRpm { - -/* Reference: lib/signature.h of rpm package */ -#define RPMSIG_NONE 0 /* Do not change! */ -/* The following types are no longer generated */ -#define RPMSIG_PGP262_1024 1 /* No longer generated */ /* 256 byte */ -/* These are the new-style signatures. They are Header structures. */ -/* Inside them we can put any number of any type of signature we like. */ - -#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 Minor; - UInt16 Type; - UInt16 ArchNum; - char Name[66]; - 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; }; -}; - -const UInt32 kEntryInfoSize = 16; -/* -struct CEntryInfo -{ - int Tag; - int Type; - int Offset; // Offset from beginning of data segment, only defined on disk - int Count; -}; -*/ - -// case: SignatureType == RPMSIG_HEADERSIG -const UInt32 kCSigHeaderSigSize = 16; -struct CSigHeaderSig -{ - unsigned char Magic[4]; - 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; }; - UInt32 GetLostHeaderLen() - { return IndexLen * kEntryInfoSize + DataLen; }; -}; - -}} - -#endif diff --git a/CPP/7zip/Archive/RPM/RpmIn.cpp b/CPP/7zip/Archive/RPM/RpmIn.cpp deleted file mode 100755 index db7a6f63..00000000 --- a/CPP/7zip/Archive/RPM/RpmIn.cpp +++ /dev/null @@ -1,106 +0,0 @@ -// Archive/RpmIn.cpp - -#include "StdAfx.h" - -#include "RpmIn.h" - -#include "RpmHeader.h" - -#include "Windows/Defs.h" -#include "Common/MyCom.h" - -#include "../../Common/StreamUtils.h" - -namespace NArchive { -namespace NRpm { - -static UInt16 GetUInt16(const char *data) -{ - return (UInt16)((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; - RINOK(ReadStream_FALSE(inStream, dat, kCSigHeaderSigSize)); - 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; - char leadData[kLeadSize]; - char *cur = leadData; - CLead lead; - RINOK(ReadStream_FALSE(inStream, leadData, kLeadSize)); - 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; - - CSigHeaderSig sigHeader, header; - if(lead.SignatureType == RPMSIG_NONE) - { - ; - } - else if(lead.SignatureType == RPMSIG_PGP262_1024) - { - UInt64 pos; - RINOK(inStream->Seek(256, STREAM_SEEK_CUR, &pos)); - } - else if(lead.SignatureType == RPMSIG_HEADERSIG) - { - RINOK(RedSigHeaderSig(inStream, sigHeader)); - if(!sigHeader.MagicCheck()) - return S_FALSE; - UInt32 len = sigHeader.GetLostHeaderLen(); - RINOK(inStream->Seek(len, STREAM_SEEK_CUR, &pos)); - if((pos % 8) != 0) - { - RINOK(inStream->Seek((pos / 8 + 1) * 8 - pos, - STREAM_SEEK_CUR, &pos)); - } - } - else - return S_FALSE; - - RINOK(RedSigHeaderSig(inStream, header)); - if(!header.MagicCheck()) - return S_FALSE; - int headerLen = header.GetLostHeaderLen(); - if(headerLen == -1) - return S_FALSE; - RINOK(inStream->Seek(headerLen, STREAM_SEEK_CUR, &pos)); - return S_OK; -} - -}} diff --git a/CPP/7zip/Archive/RPM/RpmIn.h b/CPP/7zip/Archive/RPM/RpmIn.h deleted file mode 100755 index ec798cb8..00000000 --- a/CPP/7zip/Archive/RPM/RpmIn.h +++ /dev/null @@ -1,15 +0,0 @@ -// Archive/RpmIn.h - -#ifndef __ARCHIVE_RPM_IN_H -#define __ARCHIVE_RPM_IN_H - -#include "../../IStream.h" - -namespace NArchive { -namespace NRpm { - -HRESULT OpenArchive(IInStream *inStream); - -}} - -#endif diff --git a/CPP/7zip/Archive/RPM/RpmRegister.cpp b/CPP/7zip/Archive/RPM/RpmRegister.cpp deleted file mode 100755 index 61082bac..00000000 --- a/CPP/7zip/Archive/RPM/RpmRegister.cpp +++ /dev/null @@ -1,13 +0,0 @@ -// RpmRegister.cpp - -#include "StdAfx.h" - -#include "../../Common/RegisterArc.h" - -#include "RpmHandler.h" -static IInArchive *CreateArc() { return new NArchive::NRpm::CHandler; } - -static CArcInfo g_ArcInfo = - { L"Rpm", L"rpm", 0, 0xEB, { 0}, 0, false, CreateArc, 0 }; - -REGISTER_ARC(Rpm) diff --git a/CPP/7zip/Archive/RPM/StdAfx.cpp b/CPP/7zip/Archive/RPM/StdAfx.cpp deleted file mode 100755 index d0feea85..00000000 --- a/CPP/7zip/Archive/RPM/StdAfx.cpp +++ /dev/null @@ -1,3 +0,0 @@ -// StdAfx.cpp - -#include "StdAfx.h" diff --git a/CPP/7zip/Archive/RPM/StdAfx.h b/CPP/7zip/Archive/RPM/StdAfx.h deleted file mode 100755 index e7fb6986..00000000 --- a/CPP/7zip/Archive/RPM/StdAfx.h +++ /dev/null @@ -1,8 +0,0 @@ -// StdAfx.h - -#ifndef __STDAFX_H -#define __STDAFX_H - -#include "../../../Common/MyWindows.h" - -#endif diff --git a/CPP/7zip/Archive/Rar/RarHandler.cpp b/CPP/7zip/Archive/Rar/RarHandler.cpp index 435c5c17..c8a20643 100755 --- a/CPP/7zip/Archive/Rar/RarHandler.cpp +++ b/CPP/7zip/Archive/Rar/RarHandler.cpp @@ -42,16 +42,16 @@ static const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]); static const wchar_t *kUnknownOS = L"Unknown"; -STATPROPSTG kProps[] = +STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, - { NULL, kpidIsFolder, VT_BOOL}, + { NULL, kpidIsDir, VT_BOOL}, { NULL, kpidSize, VT_UI8}, - { NULL, kpidPackedSize, VT_UI8}, - { NULL, kpidLastWriteTime, VT_FILETIME}, - { NULL, kpidCreationTime, VT_FILETIME}, - { NULL, kpidLastAccessTime, VT_FILETIME}, - { NULL, kpidAttributes, VT_UI4}, + { NULL, kpidPackSize, VT_UI8}, + { NULL, kpidMTime, VT_FILETIME}, + { NULL, kpidCTime, VT_FILETIME}, + { NULL, kpidATime, VT_FILETIME}, + { NULL, kpidAttrib, VT_UI4}, { NULL, kpidEncrypted, VT_BOOL}, { NULL, kpidSolid, VT_BOOL}, @@ -64,13 +64,14 @@ STATPROPSTG kProps[] = { NULL, kpidUnpackVer, VT_UI1} }; -STATPROPSTG kArcProps[] = +STATPROPSTG kArcProps[] = { { NULL, kpidSolid, VT_BOOL}, { NULL, kpidNumBlocks, VT_UI4}, { NULL, kpidEncrypted, VT_BOOL}, { NULL, kpidIsVolume, VT_BOOL}, { NULL, kpidNumVolumes, VT_UI4}, + { NULL, kpidPhySize, VT_UI8} // { NULL, kpidCommented, VT_BOOL} }; @@ -95,18 +96,18 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) case kpidSolid: prop = _archiveInfo.IsSolid(); break; case kpidEncrypted: prop = _archiveInfo.IsEncrypted(); break; case kpidIsVolume: prop = _archiveInfo.IsVolume(); break; + case kpidNumVolumes: prop = (UInt32)_archives.Size(); break; + case kpidOffset: if (_archiveInfo.StartPosition != 0) prop = _archiveInfo.StartPosition; break; + // case kpidCommented: prop = _archiveInfo.IsCommented(); break; case kpidNumBlocks: { UInt32 numBlocks = 0; for (int i = 0; i < _refItems.Size(); i++) if (!IsSolid(i)) numBlocks++; - prop = (UInt32)numBlocks; + prop = (UInt32)numBlocks; break; } - case kpidNumVolumes: prop = (UInt32)_archives.Size(); - - // case kpidCommented: prop = _archiveInfo.IsCommented(); break; } prop.Detach(value); return S_OK; @@ -125,7 +126,7 @@ static bool RarTimeToFileTime(const CRarTime &rarTime, FILETIME &result) return false; UInt64 value = (((UInt64)result.dwHighDateTime) << 32) + result.dwLowDateTime; value += (UInt64)rarTime.LowSecond * 10000000; - value += ((UInt64)rarTime.SubTime[2] << 16) + + value += ((UInt64)rarTime.SubTime[2] << 16) + ((UInt64)rarTime.SubTime[1] << 8) + ((UInt64)rarTime.SubTime[0]); result.dwLowDateTime = (DWORD)value; @@ -164,13 +165,13 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va prop = (const wchar_t *)NItemName::WinNameToOSName(u); break; } - case kpidIsFolder: prop = item.IsDirectory(); break; - case kpidSize: prop = item.UnPackSize; break; - case kpidPackedSize: prop = GetPackSize(index); break; - case kpidLastWriteTime: RarTimeToProp(item.LastWriteTime, prop); break; - case kpidCreationTime: if (item.IsCreationTimeDefined) RarTimeToProp(item.CreationTime, prop); break; - case kpidLastAccessTime: if (item.IsLastAccessTimeDefined) RarTimeToProp(item.LastAccessTime, prop); break; - case kpidAttributes: prop = item.GetWinAttributes(); break; + case kpidIsDir: prop = item.IsDir(); break; + case kpidSize: prop = item.Size; break; + case kpidPackSize: prop = GetPackSize(index); break; + case kpidMTime: RarTimeToProp(item.MTime, prop); break; + case kpidCTime: if (item.CTimeDefined) RarTimeToProp(item.CTime, prop); break; + case kpidATime: if (item.ATimeDefined) RarTimeToProp(item.ATime, prop); break; + case kpidAttrib: prop = item.GetWinAttributes(); break; case kpidEncrypted: prop = item.IsEncrypted(); break; case kpidSolid: prop = IsSolid(index); break; case kpidCommented: prop = item.IsCommented(); break; @@ -192,7 +193,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va wchar_t temp[32]; ConvertUInt64ToString(item.Method - Byte('0'), temp); method += temp; - if (!item.IsDirectory()) + if (!item.IsDir()) { method += L":"; ConvertUInt64ToString(16 + item.GetDictSize(), temp); @@ -220,8 +221,8 @@ class CVolumeName bool _first; bool _newStyle; UString _unchangedPart; - UString _changedPart; - UString _afterPart; + UString _changedPart; + UString _afterPart; public: CVolumeName(): _newStyle(true) {}; @@ -243,7 +244,7 @@ public: { _afterPart = L".rar"; basePart = name.Left(dotPos); - } + } else if (!_newStyle) { if (ext.CompareNoCase(L"000") == 0 || ext.CompareNoCase(L"001") == 0) @@ -275,7 +276,7 @@ public: numLetters++; } } - else + else return false; _unchangedPart = basePart.Left(basePart.Length() - numLetters); _changedPart = basePart.Right(numLetters); @@ -284,7 +285,7 @@ public: UString GetNextName() { - UString newName; + UString newName; if (_newStyle || !_first) { int i; @@ -314,13 +315,10 @@ public: } }; -STDMETHODIMP CHandler::Open(IInStream *stream, +HRESULT CHandler::Open2(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) { - COM_TRY_BEGIN - Close(); - try { CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback; CMyComPtr<ICryptoGetTextPassword> getTextPassword; @@ -328,12 +326,12 @@ STDMETHODIMP CHandler::Open(IInStream *stream, CVolumeName seqName; + UInt64 totalBytes = 0; + UInt64 curBytes = 0; + if (openArchiveCallback != NULL) { openArchiveCallbackWrap.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback); - RINOK(openArchiveCallback->SetTotal(NULL, NULL)); - UInt64 numFiles = _items.Size(); - RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); openArchiveCallbackWrap.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword); } @@ -371,10 +369,18 @@ STDMETHODIMP CHandler::Open(IInStream *stream, } else inStream = stream; + + UInt64 endPos = 0; + if (openArchiveCallback != NULL) + { + RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos)); + RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); + totalBytes += endPos; + RINOK(openArchiveCallback->SetTotal(NULL, &totalBytes)); + } NArchive::NRar::CInArchive archive; - if(!archive.Open(inStream, maxCheckStartPosition)) - return S_FALSE; + RINOK(archive.Open(inStream, maxCheckStartPosition)); if (_archives.IsEmpty()) archive.GetArchiveInfo(_archiveInfo); @@ -408,20 +414,35 @@ STDMETHODIMP CHandler::Open(IInStream *stream, _refItems.Add(refItem); } _items.Add(item); - if (openArchiveCallback != NULL) + if (openArchiveCallback != NULL && _items.Size() % 100 == 0) { UInt64 numFiles = _items.Size(); - RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); + UInt64 numBytes = curBytes + item.Position; + RINOK(openArchiveCallback->SetCompleted(&numFiles, &numBytes)); } } + curBytes += endPos; _archives.Add(archive); } } - catch(...) + return S_OK; +} + +STDMETHODIMP CHandler::Open(IInStream *stream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openArchiveCallback) +{ + COM_TRY_BEGIN + Close(); + try { - return S_FALSE; + HRESULT res = Open2(stream, maxCheckStartPosition, openArchiveCallback); + if (res != S_OK) + Close(); + return res; } - return S_OK; + catch(const CInArchiveException &) { Close(); return S_FALSE; } + catch(...) { Close(); throw; } COM_TRY_END } @@ -449,9 +470,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, CMyComPtr<ICryptoGetTextPassword> getTextPassword; bool testMode = (_aTestMode != 0); CMyComPtr<IArchiveExtractCallback> extractCallback = _anExtractCallback; - UInt64 censoredTotalUnPacked = 0, + UInt64 censoredTotalUnPacked = 0, // censoredTotalPacked = 0, - importantTotalUnPacked = 0; + importantTotalUnPacked = 0; // importantTotalPacked = 0; bool allFilesMode = (numItems == UInt32(-1)); if (allFilesMode) @@ -467,7 +488,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, int index = allFilesMode ? t : indices[t]; const CRefItem &refItem = _refItems[index]; const CItemEx &item = _items[refItem.ItemIndex]; - censoredTotalUnPacked += item.UnPackSize; + censoredTotalUnPacked += item.Size; // censoredTotalPacked += item.PackSize; int j; for(j = lastIndex; j <= index; j++) @@ -481,7 +502,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, // const CItemEx &item = _items[j]; - importantTotalUnPacked += item.UnPackSize; + importantTotalUnPacked += item.Size; // importantTotalPacked += item.PackSize; importantIndexes.Add(j); extractStatuses.Add(j == index); @@ -515,7 +536,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, lps->Init(extractCallback, false); bool solidStart = true; - for(int i = 0; i < importantIndexes.Size(); i++, + for(int i = 0; i < importantIndexes.Size(); i++, currentImportantTotalUnPacked += currentUnPackSize, currentImportantTotalPacked += currentPackSize) { @@ -526,7 +547,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, Int32 askMode; if(extractStatuses[i]) - askMode = testMode ? + askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract; else @@ -537,7 +558,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, const CRefItem &refItem = _refItems[index]; const CItemEx &item = _items[refItem.ItemIndex]; - currentUnPackSize = item.UnPackSize; + currentUnPackSize = item.Size; currentPackSize = GetPackSize(index); @@ -548,7 +569,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, if (!IsSolid(index)) solidStart = true; - if(item.IsDirectory()) + if(item.IsDir()) { RINOK(extractCallback->PrepareOperation(askMode)); RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); @@ -618,7 +639,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, } rar29CryptoDecoderSpec->SetRar350Mode(item.UnPackVersion < 36); CMyComPtr<ICompressSetDecoderProperties2> cryptoProperties; - RINOK(rar29CryptoDecoder.QueryInterface(IID_ICompressSetDecoderProperties2, + RINOK(rar29CryptoDecoder.QueryInterface(IID_ICompressSetDecoderProperties2, &cryptoProperties)); RINOK(cryptoProperties->SetDecoderProperties2(item.Salt, item.HasSalt() ? sizeof(item.Salt) : 0)); filterStreamSpec->Filter = rar29CryptoDecoder; @@ -639,11 +660,11 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); continue; } - RINOK(filterStreamSpec->Filter.QueryInterface(IID_ICryptoSetPassword, + RINOK(filterStreamSpec->Filter.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword)); if (!getTextPassword) - extractCallback.QueryInterface(IID_ICryptoGetTextPassword, + extractCallback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword); if (getTextPassword) { @@ -722,7 +743,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, methodID += 1; else if (item.UnPackVersion < 29) methodID += 2; - else + else methodID += 3; RINOK(CreateCoder(EXTERNAL_CODECS_VARS methodID, mi.Coder, false)); } @@ -739,7 +760,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, CMyComPtr<ICompressCoder> decoder = methodItems[m].Coder; CMyComPtr<ICompressSetDecoderProperties2> compressSetDecoderProperties; - RINOK(decoder.QueryInterface(IID_ICompressSetDecoderProperties2, + RINOK(decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &compressSetDecoderProperties)); Byte isSolid = (Byte)((IsSolid(index) || item.IsSplitBefore()) ? 1: 0); @@ -760,7 +781,7 @@ 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, progress); + HRESULT result = commonCoder->Code(inStream, outStream, &packSize, &item.Size, progress); if (item.IsEncrypted()) filterStreamSpec->ReleaseInStream(); if (result == S_FALSE) @@ -773,7 +794,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, return result; /* - if (refItem.NumItems == 1 && + if (refItem.NumItems == 1 && !item.IsSplitBefore() && !item.IsSplitAfter()) */ { diff --git a/CPP/7zip/Archive/Rar/RarHandler.h b/CPP/7zip/Archive/Rar/RarHandler.h index 811802a9..58e3fefc 100755 --- a/CPP/7zip/Archive/Rar/RarHandler.h +++ b/CPP/7zip/Archive/Rar/RarHandler.h @@ -12,7 +12,7 @@ namespace NArchive { namespace NRar { -class CHandler: +class CHandler: public IInArchive, PUBLIC_ISetCompressCodecsInfo public CMyUnknownImp @@ -49,6 +49,10 @@ private: } return item.IsSolid(); } + + HRESULT Open2(IInStream *stream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openArchiveCallback); }; }} diff --git a/CPP/7zip/Archive/Rar/RarHeader.h b/CPP/7zip/Archive/Rar/RarHeader.h index 832a21c0..4df42e62 100755 --- a/CPP/7zip/Archive/Rar/RarHeader.h +++ b/CPP/7zip/Archive/Rar/RarHeader.h @@ -17,7 +17,7 @@ const int kArchiveSolid = 0x1; namespace NBlockType { enum EBlockType - { + { kMarker = 0x72, kArchiveHeader = 0x73, kFileHeader = 0x74, @@ -129,7 +129,7 @@ namespace NFile Byte Method; UInt16 NameSize; UInt32 Attributes; - UInt16 GetRealCRC(const void *aName, UInt32 aNameSize, + UInt16 GetRealCRC(const void *aName, UInt32 aNameSize, bool anExtraDataDefined = false, Byte *anExtraData = 0) const; }; struct CBlock64 @@ -157,10 +157,10 @@ namespace NFile const int kWinFileDirectoryAttributeMask = 0x10; enum CHostOS - { - kHostMSDOS = 0, - kHostOS2 = 1, - kHostWin32 = 2, + { + kHostMSDOS = 0, + kHostOS2 = 1, + kHostWin32 = 2, kHostUnix = 3, kHostMacOS = 4, kHostBeOS = 5 diff --git a/CPP/7zip/Archive/Rar/RarIn.cpp b/CPP/7zip/Archive/Rar/RarIn.cpp index efb87fb7..18669405 100755 --- a/CPP/7zip/Archive/Rar/RarIn.cpp +++ b/CPP/7zip/Archive/Rar/RarIn.cpp @@ -9,9 +9,11 @@ #include "../../Common/LimitedStreams.h" #include "../../Common/StreamUtils.h" -extern "C" -{ - #include "../../../../C/7zCrc.h" +#include "../Common/FindSignature.h" + +extern "C" +{ + #include "../../../../C/7zCrc.h" } namespace NArchive { @@ -23,17 +25,18 @@ void CInArchive::ThrowExceptionWithCode( throw CInArchiveException(cause); } -bool CInArchive::Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit) +HRESULT 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; - m_Stream = inStream; - if (ReadMarkerAndArchiveHeader(searchHeaderSizeLimit)) - return true; - m_Stream.Release(); - return false; + try + { + Close(); + HRESULT res = Open2(inStream, searchHeaderSizeLimit); + if (res == S_OK) + return res; + Close(); + return res; + } + catch(...) { Close(); throw; } } void CInArchive::Close() @@ -50,56 +53,14 @@ static inline bool TestMarkerCandidate(const void *aTestBytes) return true; } -bool CInArchive::FindAndReadMarker(const UInt64 *searchHeaderSizeLimit) +HRESULT CInArchive::FindAndReadMarker(IInStream *stream, const UInt64 *searchHeaderSizeLimit) { - // if (m_Length < NHeader::kMarkerSize) - // return false; - m_ArchiveStartPosition = 0; - m_Position = m_StreamStartPosition; - if(m_Stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL) != S_OK) - return false; - - Byte marker[NHeader::kMarkerSize]; - UInt32 processedSize; - ReadBytes(marker, NHeader::kMarkerSize, &processedSize); - if(processedSize != NHeader::kMarkerSize) - return false; - if (TestMarkerCandidate(marker)) - return true; - - CByteDynamicBuffer dynamicBuffer; - static const UInt32 kSearchMarkerBufferSize = 0x10000; - dynamicBuffer.EnsureCapacity(kSearchMarkerBufferSize); - Byte *buffer = dynamicBuffer; - UInt32 numBytesPrev = NHeader::kMarkerSize - 1; - memmove(buffer, marker + 1, numBytesPrev); - UInt64 curTestPos = m_StreamStartPosition + 1; - for (;;) - { - if (searchHeaderSizeLimit != NULL) - if (curTestPos - m_StreamStartPosition > *searchHeaderSizeLimit) - break; - UInt32 numReadBytes = kSearchMarkerBufferSize - numBytesPrev; - ReadBytes(buffer + numBytesPrev, numReadBytes, &processedSize); - UInt32 numBytesInBuffer = numBytesPrev + processedSize; - if (numBytesInBuffer < NHeader::kMarkerSize) - break; - UInt32 numTests = numBytesInBuffer - NHeader::kMarkerSize + 1; - for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++) - { - if (TestMarkerCandidate(buffer + pos)) - { - m_ArchiveStartPosition = curTestPos; - m_Position = curTestPos + NHeader::kMarkerSize; - if(m_Stream->Seek(m_Position, STREAM_SEEK_SET, NULL) != S_OK) - return false; - return true; - } - } - numBytesPrev = numBytesInBuffer - numTests; - memmove(buffer, buffer + numTests, numBytesPrev); - } - return false; + RINOK(FindSignatureInStream(stream, + NHeader::kMarker, NHeader::kMarkerSize, + searchHeaderSizeLimit, m_ArchiveStartPosition)); + m_Stream = stream; + m_Position = m_ArchiveStartPosition + NHeader::kMarkerSize; + return m_Stream->Seek(m_Position, STREAM_SEEK_SET, NULL); } void CInArchive::ThrowUnexpectedEndOfArchiveException() @@ -154,18 +115,21 @@ static UInt32 CrcUpdateUInt32(UInt32 crc, UInt32 v) } -bool CInArchive::ReadMarkerAndArchiveHeader(const UInt64 *searchHeaderSizeLimit) +HRESULT CInArchive::Open2(IInStream *stream, const UInt64 *searchHeaderSizeLimit) { - if (!FindAndReadMarker(searchHeaderSizeLimit)) - return false; + m_CryptoMode = false; + RINOK(stream->Seek(0, STREAM_SEEK_SET, &m_StreamStartPosition)); + m_Position = m_StreamStartPosition; + + RINOK(FindAndReadMarker(stream, searchHeaderSizeLimit)); Byte buf[NHeader::NArchive::kArchiveHeaderSize]; UInt32 processedSize; ReadBytes(buf, sizeof(buf), &processedSize); if (processedSize != sizeof(buf)) - return false; + return S_FALSE; m_CurData = buf; - m_CurPos = 0; + m_CurPos = 0; m_PosLimit = sizeof(buf); m_ArchiveHeader.CRC = ReadUInt16(); @@ -187,17 +151,17 @@ bool CInArchive::ReadMarkerAndArchiveHeader(const UInt64 *searchHeaderSizeLimit) { ReadBytes(&m_ArchiveHeader.EncryptVersion, 1, &processedSize); if (processedSize != 1) - return false; + return S_FALSE; crc = CRC_UPDATE_BYTE(crc, m_ArchiveHeader.EncryptVersion); } if(m_ArchiveHeader.CRC != (CRC_GET_DIGEST(crc) & 0xFFFF)) ThrowExceptionWithCode(CInArchiveException::kArchiveHeaderCRCError); if (m_ArchiveHeader.Type != NHeader::NBlockType::kArchiveHeader) - return false; + return S_FALSE; m_ArchiveCommentPosition = m_Position; m_SeekOnArchiveComment = true; - return true; + return S_OK; } void CInArchive::SkipArchiveComment() @@ -216,7 +180,7 @@ void CInArchive::GetArchiveInfo(CInArchiveInfo &archiveInfo) const archiveInfo.CommentSize = (UInt16)(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; @@ -249,7 +213,7 @@ static void DecodeUnicodeFileName(const char *name, const Byte *encName, if (length & 0x80) { Byte correction = encName[encPos++]; - for (length = (length & 0x7f) + 2; + for (length = (length & 0x7f) + 2; length > 0 && decPos < maxDecSize; length--, decPos++) unicodeName[decPos] = (wchar_t)(((name[decPos] + correction) & 0xff) + (highByte << 8)); } @@ -289,7 +253,7 @@ void CInArchive::ReadName(CItemEx &item, int nameSize) { int unicodeNameSizeMax = MyMin(nameSize, (0x400)); _unicodeNameBuffer.EnsureCapacity(unicodeNameSizeMax + 1); - DecodeUnicodeFileName(buffer, (const Byte *)buffer + mainLen + 1, + DecodeUnicodeFileName(buffer, (const Byte *)buffer + mainLen + 1, nameSize - (mainLen + 1), _unicodeNameBuffer, unicodeNameSizeMax); item.UnicodeName = _unicodeNameBuffer; } @@ -341,26 +305,26 @@ void CInArchive::ReadTime(Byte mask, CRarTime &rarTime) void CInArchive::ReadHeaderReal(CItemEx &item) { - item.Flags = m_BlockHeader.Flags; + item.Flags = m_BlockHeader.Flags; item.PackSize = ReadUInt32(); - item.UnPackSize = ReadUInt32(); + item.Size = ReadUInt32(); item.HostOS = ReadByte(); item.FileCRC = ReadUInt32(); - item.LastWriteTime.DosTime = ReadUInt32(); + item.MTime.DosTime = ReadUInt32(); item.UnPackVersion = ReadByte(); item.Method = ReadByte(); int nameSize = ReadUInt16(); - item.Attributes = ReadUInt32(); + item.Attrib = ReadUInt32(); - item.LastWriteTime.LowSecond = 0; - item.LastWriteTime.SubTime[0] = - item.LastWriteTime.SubTime[1] = - item.LastWriteTime.SubTime[2] = 0; + item.MTime.LowSecond = 0; + item.MTime.SubTime[0] = + item.MTime.SubTime[1] = + item.MTime.SubTime[2] = 0; if((item.Flags & NHeader::NFile::kSize64Bits) != 0) { item.PackSize |= ((UInt64)ReadUInt32() << 32); - item.UnPackSize |= ((UInt64)ReadUInt32() << 32); + item.Size |= ((UInt64)ReadUInt32() << 32); } ReadName(item, nameSize); @@ -377,18 +341,18 @@ void CInArchive::ReadHeaderReal(CItemEx &item) Byte modifMask = (Byte)(b >> 4); Byte createMask = (Byte)(b & 0xF); if ((modifMask & 8) != 0) - ReadTime(modifMask, item.LastWriteTime); - item.IsCreationTimeDefined = ((createMask & 8) != 0); - if (item.IsCreationTimeDefined) + ReadTime(modifMask, item.MTime); + item.CTimeDefined = ((createMask & 8) != 0); + if (item.CTimeDefined) { - item.CreationTime.DosTime = ReadUInt32(); - ReadTime(createMask, item.CreationTime); + item.CTime.DosTime = ReadUInt32(); + ReadTime(createMask, item.CTime); } - item.IsLastAccessTimeDefined = ((accessMask & 8) != 0); - if (item.IsLastAccessTimeDefined) + item.ATimeDefined = ((accessMask & 8) != 0); + if (item.ATimeDefined) { - item.LastAccessTime.DosTime = ReadUInt32(); - ReadTime(accessMask, item.LastAccessTime); + item.ATime.DosTime = ReadUInt32(); + ReadTime(accessMask, item.ATime); } } @@ -418,7 +382,7 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa { if(!SeekInArchive(m_Position)) return S_FALSE; - if (!m_CryptoMode && (m_ArchiveHeader.Flags & + if (!m_CryptoMode && (m_ArchiveHeader.Flags & NHeader::NArchive::kBlockHeadersAreEncrypted) != 0) { m_CryptoMode = false; @@ -487,23 +451,23 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa if (m_BlockHeader.HeadSize < 7) ThrowExceptionWithCode(CInArchiveException::kIncorrectArchive); - if (m_BlockHeader.Type == NHeader::NBlockType::kEndOfArchive) + if (m_BlockHeader.Type == NHeader::NBlockType::kEndOfArchive) return S_FALSE; - if (m_BlockHeader.Type == NHeader::NBlockType::kFileHeader) + if (m_BlockHeader.Type == NHeader::NBlockType::kFileHeader) { m_FileHeaderData.EnsureCapacity(m_BlockHeader.HeadSize); m_CurData = (Byte *)m_FileHeaderData; m_PosLimit = m_BlockHeader.HeadSize; ReadBytesAndTestResult(m_CurData + m_CurPos, m_BlockHeader.HeadSize - 7); - ReadHeaderReal(item); - if ((CrcCalc(m_CurData + 2, + ReadHeaderReal(item); + if ((CrcCalc(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; + SeekInArchive(m_Position); // Move Position to compressed Data; AddToSeekValue(item.PackSize); // m_Position points to next header; return S_OK; } diff --git a/CPP/7zip/Archive/Rar/RarIn.h b/CPP/7zip/Archive/Rar/RarIn.h index 94cea223..7be3f53c 100755 --- a/CPP/7zip/Archive/Rar/RarIn.h +++ b/CPP/7zip/Archive/Rar/RarIn.h @@ -24,7 +24,7 @@ public: kArchiveHeaderCRCError, kFileHeaderCRCError, kIncorrectArchive - } + } Cause; CInArchiveException(CCauseType cause) : Cause(cause) {} }; @@ -64,7 +64,9 @@ class CInArchive bool ReadBytesAndTestSize(void *data, UInt32 size); void ReadBytesAndTestResult(void *data, UInt32 size); - bool FindAndReadMarker(const UInt64 *searchHeaderSizeLimit); + HRESULT FindAndReadMarker(IInStream *stream, const UInt64 *searchHeaderSizeLimit); + HRESULT Open2(IInStream *stream, const UInt64 *searchHeaderSizeLimit); + void ThrowExceptionWithCode(CInArchiveException::CCauseType cause); void ThrowUnexpectedEndOfArchiveException(); @@ -102,9 +104,8 @@ protected: } } - bool ReadMarkerAndArchiveHeader(const UInt64 *searchHeaderSizeLimit); public: - bool Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit); + HRESULT Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit); void Close(); HRESULT GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPassword); diff --git a/CPP/7zip/Archive/Rar/RarItem.cpp b/CPP/7zip/Archive/Rar/RarItem.cpp index 61a72557..9216ae57 100755 --- a/CPP/7zip/Archive/Rar/RarItem.cpp +++ b/CPP/7zip/Archive/Rar/RarItem.cpp @@ -3,47 +3,24 @@ #include "StdAfx.h" #include "RarItem.h" -#include "RarHeader.h" namespace NArchive{ namespace NRar{ -bool CItem::IsEncrypted() const - { return (Flags & NHeader::NFile::kEncrypted) != 0; } -bool CItem::IsSolid() const - { return (Flags & NHeader::NFile::kSolid) != 0; } -bool CItem::IsCommented() const - { return (Flags & NHeader::NFile::kComment) != 0; } -bool CItem::IsSplitBefore() const - { return (Flags & NHeader::NFile::kSplitBefore) != 0; } -bool CItem::IsSplitAfter() const - { return (Flags & NHeader::NFile::kSplitAfter) != 0; } -bool CItem::HasSalt() const - { return (Flags & NHeader::NFile::kSalt) != 0; } -bool CItem::HasExtTime() const - { return (Flags & NHeader::NFile::kExtTime) != 0; } -bool CItem::HasUnicodeName() const - { return (Flags & NHeader::NFile::kUnicodeName) != 0; } -bool CItem::IsOldVersion() const - { return (Flags & NHeader::NFile::kOldVersion) != 0; } - bool CItem::IgnoreItem() const -{ +{ switch(HostOS) { - case NHeader::NFile::kHostMSDOS: - case NHeader::NFile::kHostOS2: - case NHeader::NFile::kHostWin32: - return ((Attributes & NHeader::NFile::kLabelFileAttribute) != 0); + case NHeader::NFile::kHostMSDOS: + case NHeader::NFile::kHostOS2: + case NHeader::NFile::kHostWin32: + return ((Attrib & NHeader::NFile::kLabelFileAttribute) != 0); } return false; } -UInt32 CItem::GetDictSize() const -{ return (Flags >> NHeader::NFile::kDictBitStart) & NHeader::NFile::kDictMask; } - -bool CItem::IsDirectory() const -{ +bool CItem::IsDir() const +{ if (GetDictSize() == NHeader::NFile::kDictDirectoryValue) return true; switch(HostOS) @@ -51,7 +28,7 @@ bool CItem::IsDirectory() const case NHeader::NFile::kHostMSDOS: case NHeader::NFile::kHostOS2: case NHeader::NFile::kHostWin32: - if ((Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) + if ((Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0) return true; } return false; @@ -62,57 +39,17 @@ UInt32 CItem::GetWinAttributes() const UInt32 winAttributes; switch(HostOS) { - case NHeader::NFile::kHostMSDOS: - case NHeader::NFile::kHostOS2: - case NHeader::NFile::kHostWin32: - winAttributes = Attributes; - break; - default: - winAttributes = 0; // must be converted from unix value;; + case NHeader::NFile::kHostMSDOS: + case NHeader::NFile::kHostOS2: + case NHeader::NFile::kHostWin32: + winAttributes = Attrib; + break; + default: + winAttributes = 0; // must be converted from unix value; } - if (IsDirectory()) // test it; + if (IsDir()) winAttributes |= NHeader::NFile::kWinFileDirectoryAttributeMask; return winAttributes; } -void CItem::ClearFlags() -{ Flags = 0; } - -void CItem::SetFlagBits(int startBitNumber, int numBits, int value) -{ - UInt16 mask = (UInt16)(((1 << numBits) - 1) << startBitNumber); - Flags &= ~mask; - Flags |= value << startBitNumber; -} - -void CItem::SetBitMask(int bitMask, bool enable) -{ - if(enable) - Flags |= bitMask; - else - Flags &= ~bitMask; -} - -void CItem::SetDictSize(UInt32 size) -{ - SetFlagBits(NHeader::NFile::kDictBitStart, NHeader::NFile::kNumDictBits, (size & NHeader::NFile::kDictMask)); -} - -void CItem::SetAsDirectory(bool directory) -{ - if (directory) - SetDictSize(NHeader::NFile::kDictDirectoryValue); -} - -void CItem::SetEncrypted(bool encrypted) - { SetBitMask(NHeader::NFile::kEncrypted, encrypted); } -void CItem::SetSolid(bool solid) - { SetBitMask(NHeader::NFile::kSolid, solid); } -void CItem::SetCommented(bool commented) - { SetBitMask(NHeader::NFile::kComment, commented); } -void CItem::SetSplitBefore(bool splitBefore) - { SetBitMask(NHeader::NFile::kSplitBefore, splitBefore); } -void CItem::SetSplitAfter(bool splitAfter) - { SetBitMask(NHeader::NFile::kSplitAfter, splitAfter); } - }} diff --git a/CPP/7zip/Archive/Rar/RarItem.h b/CPP/7zip/Archive/Rar/RarItem.h index 5ab8a46e..4aa4d866 100755 --- a/CPP/7zip/Archive/Rar/RarItem.h +++ b/CPP/7zip/Archive/Rar/RarItem.h @@ -6,6 +6,8 @@ #include "Common/Types.h" #include "Common/MyString.h" +#include "RarHeader.h" + namespace NArchive{ namespace NRar{ @@ -16,59 +18,47 @@ struct CRarTime Byte SubTime[3]; }; -class CItem +struct CItem { -public: - UInt16 Flags; + UInt64 Size; UInt64 PackSize; - UInt64 UnPackSize; - Byte HostOS; - UInt32 FileCRC; - CRarTime CreationTime; - CRarTime LastWriteTime; - CRarTime LastAccessTime; - bool IsCreationTimeDefined; - // bool IsLastWriteTimeDefined; - bool IsLastAccessTimeDefined; + CRarTime CTime; + CRarTime ATime; + CRarTime MTime; + + UInt32 FileCRC; + UInt32 Attrib; + UInt16 Flags; + Byte HostOS; Byte UnPackVersion; Byte Method; - UInt32 Attributes; + + bool CTimeDefined; + bool ATimeDefined; + AString Name; UString UnicodeName; Byte Salt[8]; - bool IsEncrypted() const; - bool IsSolid() const; - bool IsCommented() const; - bool IsSplitBefore() const; - bool IsSplitAfter() const; - bool HasSalt() const; - bool HasExtTime() const; - - bool HasUnicodeName() const; - bool IsOldVersion() const; + bool IsEncrypted() const { return (Flags & NHeader::NFile::kEncrypted) != 0; } + bool IsSolid() const { return (Flags & NHeader::NFile::kSolid) != 0; } + bool IsCommented() const { return (Flags & NHeader::NFile::kComment) != 0; } + bool IsSplitBefore() const { return (Flags & NHeader::NFile::kSplitBefore) != 0; } + bool IsSplitAfter() const { return (Flags & NHeader::NFile::kSplitAfter) != 0; } + bool HasSalt() const { return (Flags & NHeader::NFile::kSalt) != 0; } + bool HasExtTime() const { return (Flags & NHeader::NFile::kExtTime) != 0; } + bool HasUnicodeName()const { return (Flags & NHeader::NFile::kUnicodeName) != 0; } + bool IsOldVersion() const { return (Flags & NHeader::NFile::kOldVersion) != 0; } - UInt32 GetDictSize() const; - bool IsDirectory() const; + UInt32 GetDictSize() const { return (Flags >> NHeader::NFile::kDictBitStart) & NHeader::NFile::kDictMask; } + bool IsDir() const; bool IgnoreItem() const; UInt32 GetWinAttributes() const; - CItem(): IsCreationTimeDefined(false), IsLastAccessTimeDefined(false) {} -private: - void SetFlagBits(int startBitNumber, int numBits, int value); - void SetBitMask(int bitMask, bool enable); -public: - void ClearFlags(); - void SetDictSize(UInt32 size); - void SetAsDirectory(bool directory); - void SetEncrypted(bool encrypted); - void SetSolid(bool solid); - void SetCommented(bool commented); - void SetSplitBefore(bool splitBefore); - void SetSplitAfter(bool splitAfter); + CItem(): CTimeDefined(false), ATimeDefined(false) {} }; class CItemEx: public CItem @@ -87,5 +77,3 @@ public: }} #endif - - diff --git a/CPP/7zip/Archive/Rar/RarVolumeInStream.cpp b/CPP/7zip/Archive/Rar/RarVolumeInStream.cpp index aeb52ecc..1845e20a 100755 --- a/CPP/7zip/Archive/Rar/RarVolumeInStream.cpp +++ b/CPP/7zip/Archive/Rar/RarVolumeInStream.cpp @@ -7,16 +7,16 @@ #include "Windows/Defs.h" #include "Common/Defs.h" -extern "C" -{ - #include "../../../../C/7zCrc.h" +extern "C" +{ + #include "../../../../C/7zCrc.h" } namespace NArchive { namespace NRar { void CFolderInStream::Init( - CObjectVector<CInArchive> *archives, + CObjectVector<CInArchive> *archives, const CObjectVector<CItemEx> *items, const CRefItem &refItem) { diff --git a/CPP/7zip/Archive/Rar/RarVolumeInStream.h b/CPP/7zip/Archive/Rar/RarVolumeInStream.h index 7c5902b5..78d95b10 100755 --- a/CPP/7zip/Archive/Rar/RarVolumeInStream.h +++ b/CPP/7zip/Archive/Rar/RarVolumeInStream.h @@ -16,7 +16,7 @@ struct CRefItem int NumItems; }; -class CFolderInStream: +class CFolderInStream: public ISequentialInStream, public CMyUnknownImp { @@ -37,7 +37,7 @@ private: HRESULT OpenStream(); HRESULT CloseStream(); public: - void Init(CObjectVector<CInArchive> *archives, + void Init(CObjectVector<CInArchive> *archives, const CObjectVector<CItemEx> *items, const CRefItem &refItem); diff --git a/CPP/7zip/Archive/RpmHandler.cpp b/CPP/7zip/Archive/RpmHandler.cpp new file mode 100755 index 00000000..f39ee3c5 --- /dev/null +++ b/CPP/7zip/Archive/RpmHandler.cpp @@ -0,0 +1,303 @@ +// RpmHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#include "Common/ComTry.h" +#include "Common/MyString.h" + +#include "Windows/PropVariant.h" + +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +#include "../Compress/Copy/CopyCoder.h" + +using namespace NWindows; + +#define Get16(p) GetBe16(p) +#define Get32(p) GetBe32(p) + +namespace NArchive { +namespace NRpm { + +/* Reference: lib/signature.h of rpm package */ +#define RPMSIG_NONE 0 /* Do not change! */ +/* The following types are no longer generated */ +#define RPMSIG_PGP262_1024 1 /* No longer generated */ /* 256 byte */ +/* These are the new-style signatures. They are Header structures. */ +/* Inside them we can put any number of any type of signature we like. */ + +#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 Minor; + UInt16 Type; + UInt16 ArchNum; + char Name[66]; + 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; }; +}; + +const UInt32 kEntryInfoSize = 16; +/* +struct CEntryInfo +{ + int Tag; + int Type; + int Offset; // Offset from beginning of data segment, only defined on disk + int Count; +}; +*/ + +// case: SignatureType == RPMSIG_HEADERSIG +const UInt32 kCSigHeaderSigSize = 16; +struct CSigHeaderSig +{ + unsigned char Magic[4]; + 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; }; + UInt32 GetLostHeaderLen() + { return IndexLen * kEntryInfoSize + DataLen; }; +}; + +static HRESULT RedSigHeaderSig(IInStream *inStream, CSigHeaderSig &h) +{ + char dat[kCSigHeaderSigSize]; + char *cur = dat; + RINOK(ReadStream_FALSE(inStream, dat, kCSigHeaderSigSize)); + memmove(h.Magic, cur, 4); + cur += 4; + cur += 4; + h.IndexLen = Get32(cur); + cur += 4; + h.DataLen = Get32(cur); + return S_OK; +} + +HRESULT OpenArchive(IInStream *inStream) +{ + UInt64 pos; + char leadData[kLeadSize]; + char *cur = leadData; + CLead lead; + RINOK(ReadStream_FALSE(inStream, leadData, kLeadSize)); + memmove(lead.Magic, cur, 4); + cur += 4; + lead.Major = *cur++; + lead.Minor = *cur++; + lead.Type = Get16(cur); + cur += 2; + lead.ArchNum = Get16(cur); + cur += 2; + memmove(lead.Name, cur, sizeof(lead.Name)); + cur += sizeof(lead.Name); + lead.OSNum = Get16(cur); + cur += 2; + lead.SignatureType = Get16(cur); + cur += 2; + + if (!lead.MagicCheck() || lead.Major < 3) + return S_FALSE; + + CSigHeaderSig sigHeader, header; + if(lead.SignatureType == RPMSIG_NONE) + { + ; + } + else if(lead.SignatureType == RPMSIG_PGP262_1024) + { + UInt64 pos; + RINOK(inStream->Seek(256, STREAM_SEEK_CUR, &pos)); + } + else if(lead.SignatureType == RPMSIG_HEADERSIG) + { + RINOK(RedSigHeaderSig(inStream, sigHeader)); + if(!sigHeader.MagicCheck()) + return S_FALSE; + UInt32 len = sigHeader.GetLostHeaderLen(); + RINOK(inStream->Seek(len, STREAM_SEEK_CUR, &pos)); + if((pos % 8) != 0) + { + RINOK(inStream->Seek((pos / 8 + 1) * 8 - pos, + STREAM_SEEK_CUR, &pos)); + } + } + else + return S_FALSE; + + RINOK(RedSigHeaderSig(inStream, header)); + if(!header.MagicCheck()) + return S_FALSE; + int headerLen = header.GetLostHeaderLen(); + if(headerLen == -1) + return S_FALSE; + RINOK(inStream->Seek(headerLen, STREAM_SEEK_CUR, &pos)); + return S_OK; +} + +class CHandler: + public IInArchive, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP1(IInArchive) + + INTERFACE_IInArchive(;) + +private: + CMyComPtr<IInStream> m_InStream; + UInt64 m_Pos; + UInt64 m_Size; + Byte _sig[4]; +}; + +STATPROPSTG kProps[] = +{ + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackSize, VT_UI8} +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO + +STDMETHODIMP CHandler::Open(IInStream *inStream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback * /* openArchiveCallback */) +{ + COM_TRY_BEGIN + try + { + if(OpenArchive(inStream) != S_OK) + return S_FALSE; + RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_Pos)); + UInt64 endPosition; + RINOK(inStream->Seek(0, STREAM_SEEK_END, &endPosition)); + m_Size = endPosition - m_Pos; + + RINOK(inStream->Seek(m_Pos, STREAM_SEEK_SET, NULL)); + RINOK(ReadStream_FALSE(inStream, _sig, sizeof(_sig) / sizeof(_sig[0]))); + + m_InStream = inStream; + return S_OK; + } + catch(...) + { + return S_FALSE; + } + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + m_InStream.Release(); + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = 1; + return S_OK; +} + +STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant prop; + switch(propID) + { + case kpidSize: + case kpidPackSize: + prop = m_Size; + break; + case kpidExtension: + { + wchar_t s[32]; + MyStringCopy(s, L"cpio."); + const wchar_t *ext; + if (_sig[0] == 0x1F && _sig[1] == 0x8B) + ext = L"gz"; + else if (_sig[0] == 'B' && _sig[1] == 'Z' && _sig[2] == 'h') + ext = L"bz2"; + else + ext = L"lzma"; + MyStringCopy(s + MyStringLen(s), ext); + prop = s; + break; + } + } + prop.Detach(value); + return S_OK; +} + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool allFilesMode = (numItems == UInt32(-1)); + if (allFilesMode) + numItems = 1; + if(numItems == 0) + return S_OK; + if(numItems != 1) + return E_FAIL; + if (indices[0] != 0) + return E_FAIL; + + bool testMode = (_aTestMode != 0); + + UInt64 currentTotalSize = 0; + RINOK(extractCallback->SetTotal(m_Size)); + RINOK(extractCallback->SetCompleted(¤tTotalSize)); + CMyComPtr<ISequentialOutStream> realOutStream; + Int32 askMode = testMode ? + NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + Int32 index = 0; + + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + + if(!testMode && (!realOutStream)) + return S_OK; + + RINOK(extractCallback->PrepareOperation(askMode)); + + if (testMode) + { + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + return S_OK; + } + + RINOK(m_InStream->Seek(m_Pos, STREAM_SEEK_SET, NULL)); + + CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder; + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr<ICompressProgressInfo> progress = lps; + lps->Init(extractCallback, false); + + RINOK(copyCoder->Code(m_InStream, realOutStream, NULL, NULL, progress)); + realOutStream.Release(); + return extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK); + COM_TRY_END +} + +static IInArchive *CreateArc() { return new NArchive::NRpm::CHandler; } + +static CArcInfo g_ArcInfo = + { L"Rpm", L"rpm", 0, 0xEB, { 0}, 0, false, CreateArc, 0 }; + +REGISTER_ARC(Rpm) + +}} diff --git a/CPP/7zip/Archive/Split/SplitHandler.cpp b/CPP/7zip/Archive/Split/SplitHandler.cpp index 0cd31639..380e6ce3 100755 --- a/CPP/7zip/Archive/Split/SplitHandler.cpp +++ b/CPP/7zip/Archive/Split/SplitHandler.cpp @@ -23,12 +23,11 @@ using namespace NTime; namespace NArchive { namespace NSplit { -STATPROPSTG kProps[] = +STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, -// { NULL, kpidIsFolder, VT_BOOL}, { NULL, kpidSize, VT_UI8}, - { NULL, kpidPackedSize, VT_UI8}, + { NULL, kpidPackSize, VT_UI8}, }; IMP_IInArchive_Props @@ -38,11 +37,11 @@ class CSeqName { public: UString _unchangedPart; - UString _changedPart; + UString _changedPart; bool _splitStyle; UString GetNextName() { - UString newName; + UString newName; if (_splitStyle) { int i; @@ -108,7 +107,7 @@ public: } }; -STDMETHODIMP CHandler::Open(IInStream *stream, +STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 * /* maxCheckStartPosition */, IArchiveOpenCallback *openArchiveCallback) { @@ -120,7 +119,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream, { CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback; CMyComPtr<IArchiveOpenCallback> openArchiveCallbackWrap = openArchiveCallback; - if (openArchiveCallbackWrap.QueryInterface(IID_IArchiveOpenVolumeCallback, + if (openArchiveCallbackWrap.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback) != S_OK) return S_FALSE; @@ -169,7 +168,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream, if (numLetters != ext.Length()) return S_FALSE; } - else + else return S_FALSE; _streams.Add(stream); @@ -197,7 +196,6 @@ STDMETHODIMP CHandler::Open(IInStream *stream, if (openArchiveCallback != NULL) { - RINOK(openArchiveCallback->SetTotal(NULL, NULL)); UInt64 numFiles = _streams.Size(); RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); } @@ -261,11 +259,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIAN case kpidPath: prop = _subName; break; - case kpidIsFolder: - prop = false; - break; case kpidSize: - case kpidPackedSize: + case kpidPackSize: prop = _totalSize; break; } diff --git a/CPP/7zip/Archive/Split/SplitHandler.h b/CPP/7zip/Archive/Split/SplitHandler.h index 79e63353..9e020763 100755 --- a/CPP/7zip/Archive/Split/SplitHandler.h +++ b/CPP/7zip/Archive/Split/SplitHandler.h @@ -10,10 +10,10 @@ namespace NArchive { namespace NSplit { -class CHandler: +class CHandler: public IInArchive, public IInArchiveGetStream, - // public IOutArchive, + // public IOutArchive, public CMyUnknownImp { public: @@ -21,7 +21,7 @@ public: INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); + STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); private: UString _subName; diff --git a/CPP/7zip/Archive/Split/SplitHandlerOut.cpp b/CPP/7zip/Archive/Split/SplitHandlerOut.cpp index 26e19669..6edf86f4 100755 --- a/CPP/7zip/Archive/Split/SplitHandlerOut.cpp +++ b/CPP/7zip/Archive/Split/SplitHandlerOut.cpp @@ -30,7 +30,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt UInt64 volumeSize = 0; CMyComPtr<IArchiveUpdateCallback2> callback2; - updateCallback->QueryInterface(IID_IArchiveUpdateCallback2, + updateCallback->QueryInterface(IID_IArchiveUpdateCallback2, (void **)&callback2); RINOK(callback2->GetVolumeSize(0, &volumeSize)); diff --git a/CPP/7zip/Archive/Split/StdAfx.cpp b/CPP/7zip/Archive/Split/StdAfx.cpp deleted file mode 100755 index d0feea85..00000000 --- a/CPP/7zip/Archive/Split/StdAfx.cpp +++ /dev/null @@ -1,3 +0,0 @@ -// StdAfx.cpp - -#include "StdAfx.h" diff --git a/CPP/7zip/Archive/StdAfx.h b/CPP/7zip/Archive/StdAfx.h index 99a8aa46..ef555ec1 100755 --- a/CPP/7zip/Archive/StdAfx.h +++ b/CPP/7zip/Archive/StdAfx.h @@ -4,5 +4,6 @@ #define __STDAFX_H #include "../../Common/MyWindows.h" +#include "../../Common/NewHandler.h" #endif diff --git a/CPP/7zip/Archive/Tar/StdAfx.cpp b/CPP/7zip/Archive/Tar/StdAfx.cpp deleted file mode 100755 index d0feea85..00000000 --- a/CPP/7zip/Archive/Tar/StdAfx.cpp +++ /dev/null @@ -1,3 +0,0 @@ -// StdAfx.cpp - -#include "StdAfx.h" diff --git a/CPP/7zip/Archive/Tar/TarHandler.cpp b/CPP/7zip/Archive/Tar/TarHandler.cpp index 33866d61..f70f7e4e 100755 --- a/CPP/7zip/Archive/Tar/TarHandler.cpp +++ b/CPP/7zip/Archive/Tar/TarHandler.cpp @@ -15,104 +15,99 @@ #include "../../Common/ProgressUtils.h" #include "../../Common/LimitedStreams.h" +#include "../Common/DummyOutStream.h" #include "../../Compress/Copy/CopyCoder.h" #include "../Common/ItemNameUtils.h" using namespace NWindows; -using namespace NTime; namespace NArchive { namespace NTar { -STATPROPSTG kProps[] = +STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, - { NULL, kpidIsFolder, VT_BOOL}, + { NULL, kpidIsDir, VT_BOOL}, { NULL, kpidSize, VT_UI8}, - { NULL, kpidPackedSize, VT_UI8}, - { NULL, kpidLastWriteTime, VT_FILETIME}, + { NULL, kpidPackSize, VT_UI8}, + { NULL, kpidMTime, VT_FILETIME}, { NULL, kpidUser, VT_BSTR}, - { NULL, kpidGroup, VT_BSTR}, + { NULL, kpidGroup, VT_BSTR} }; - - - - - - - - IMP_IInArchive_Props IMP_IInArchive_ArcProps_NO -STDMETHODIMP CHandler::Open(IInStream *stream, - const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback *openArchiveCallback) +HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) { - COM_TRY_BEGIN - // try + UInt64 endPos = 0; + if (callback != NULL) { - CInArchive archive; - - if (archive.Open(stream) != S_OK) + RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos)); + RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); + } + + UInt64 pos = 0; + for (;;) + { + CItemEx item; + bool filled; + item.HeaderPosition = pos; + RINOK(ReadItem(stream, filled, item)); + if (!filled) + break; + _items.Add(item); + + RINOK(stream->Seek(item.GetPackSize(), STREAM_SEEK_CUR, &pos)); + if (pos >= endPos) return S_FALSE; - - _items.Clear(); - - if (openArchiveCallback != NULL) + if (callback != NULL) { - RINOK(openArchiveCallback->SetTotal(NULL, NULL)); - UInt64 numFiles = _items.Size(); - RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); - } - - for (;;) - { - CItemEx item; - bool filled; - HRESULT result = archive.GetNextItem(filled, item); - if (result == S_FALSE) - return S_FALSE; - if (result != S_OK) - return S_FALSE; - if (!filled) - break; - _items.Add(item); - archive.SkeepDataRecords(item.Size); - if (openArchiveCallback != NULL) + if (_items.Size() == 1) + { + RINOK(callback->SetTotal(NULL, &endPos)); + } + if (_items.Size() % 100 == 0) { UInt64 numFiles = _items.Size(); - RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); + RINOK(callback->SetCompleted(&numFiles, &pos)); } } - if (_items.Size() == 0) - { - CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback; - if (!openArchiveCallback) - return S_FALSE; - openArchiveCallback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback); - if (!openVolumeCallback) - return S_FALSE; - NCOM::CPropVariant prop; - RINOK(openVolumeCallback->GetProperty(kpidName, &prop)); - if (prop.vt != VT_BSTR) - return S_FALSE; - UString baseName = prop.bstrVal; - baseName = baseName.Right(4); - if (baseName.CompareNoCase(L".tar") != 0) - return S_FALSE; - } - _inStream = stream; } - /* - catch(...) + + if (_items.Size() == 0) + { + CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback; + if (!callback) + return S_FALSE; + callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback); + if (!openVolumeCallback) + return S_FALSE; + NCOM::CPropVariant prop; + if (openVolumeCallback->GetProperty(kpidName, &prop) != S_OK) + return S_FALSE; + if (prop.vt != VT_BSTR) + return S_FALSE; + UString baseName = prop.bstrVal; + baseName = baseName.Right(4); + if (baseName.CompareNoCase(L".tar") != 0) + return S_FALSE; + } + return S_OK; +} + +STDMETHODIMP CHandler::Open(IInStream *stream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback *openArchiveCallback) +{ + COM_TRY_BEGIN { - return S_FALSE; + Close(); + RINOK(Open2(stream, openArchiveCallback)); + _inStream = stream; } - */ return S_OK; COM_TRY_END } @@ -138,38 +133,20 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val switch(propID) { - case kpidPath: - prop = (const wchar_t *)NItemName::GetOSName2( - MultiByteToUnicodeString(item.Name, CP_OEMCP)); - break; - case kpidIsFolder: - prop = item.IsDirectory(); - break; - case kpidSize: - case kpidPackedSize: - prop = (UInt64)item.Size; - break; - case kpidLastWriteTime: - { - FILETIME utcFileTime; - if (item.ModificationTime != 0) - NTime::UnixTimeToFileTime(item.ModificationTime, utcFileTime); - else + case kpidPath: prop = NItemName::GetOSName2(MultiByteToUnicodeString(item.Name, CP_OEMCP)); break; + case kpidIsDir: prop = item.IsDir(); break; + case kpidSize: prop = item.Size; break; + case kpidPackSize: prop = item.GetPackSize(); break; + case kpidMTime: + if (item.MTime != 0) { - utcFileTime.dwLowDateTime = 0; - utcFileTime.dwHighDateTime = 0; + FILETIME ft; + NTime::UnixTimeToFileTime(item.MTime, ft); + prop = ft; } - prop = utcFileTime; - break; - } - case kpidUser: - prop = (const wchar_t *) - MultiByteToUnicodeString(item.UserName, CP_OEMCP); - break; - case kpidGroup: - prop = (const wchar_t *) - MultiByteToUnicodeString(item.GroupName, CP_OEMCP); break; + case kpidUser: prop = MultiByteToUnicodeString(item.UserName, CP_OEMCP); break; + case kpidGroup: prop = MultiByteToUnicodeString(item.GroupName, CP_OEMCP); break; } prop.Detach(value); return S_OK; @@ -192,8 +169,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, totalSize += _items[allFilesMode ? i : indices[i]].Size; extractCallback->SetTotal(totalSize); - UInt64 currentTotalSize = 0; - UInt64 currentItemSize; + UInt64 totalPackSize, curPackSize, curSize; + totalSize = totalPackSize = 0; NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; @@ -206,19 +183,24 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, CMyComPtr<ISequentialInStream> inStream(streamSpec); streamSpec->SetStream(_inStream); - for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) + CDummyOutStream *outStreamSpec = new CDummyOutStream; + CMyComPtr<ISequentialOutStream> outStream(outStreamSpec); + + for (i = 0; i < numItems; i++, totalSize += curSize, totalPackSize += curPackSize) { - lps->InSize = lps->OutSize = currentTotalSize; + lps->InSize = totalPackSize; + lps->OutSize = totalSize; RINOK(lps->SetCur()); CMyComPtr<ISequentialOutStream> realOutStream; - Int32 askMode = testMode ? + Int32 askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract; Int32 index = allFilesMode ? i : indices[i]; const CItemEx &item = _items[index]; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - currentItemSize = item.Size; - if (item.IsDirectory()) + curSize = item.Size; + curPackSize = item.GetPackSize(); + if (item.IsDir()) { RINOK(extractCallback->PrepareOperation(askMode)); RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); @@ -227,16 +209,16 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, if (!testMode && (!realOutStream)) continue; RINOK(extractCallback->PrepareOperation(askMode)); - if (testMode) - { - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); - continue; - } + + outStreamSpec->SetStream(realOutStream); + realOutStream.Release(); + outStreamSpec->Init(); + RINOK(_inStream->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL)); streamSpec->Init(item.Size); - RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ? + RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); + outStreamSpec->ReleaseStream(); + RINOK(extractCallback->SetOperationResult(copyCoderSpec->TotalSize == item.Size ? NArchive::NExtract::NOperationResult::kOK: NArchive::NExtract::NOperationResult::kDataError)); } diff --git a/CPP/7zip/Archive/Tar/TarHandler.h b/CPP/7zip/Archive/Tar/TarHandler.h index 8332fbfe..a98b5404 100755 --- a/CPP/7zip/Archive/Tar/TarHandler.h +++ b/CPP/7zip/Archive/Tar/TarHandler.h @@ -11,7 +11,7 @@ namespace NArchive { namespace NTar { -class CHandler: +class CHandler: public IInArchive, public IOutArchive, public CMyUnknownImp @@ -25,6 +25,8 @@ public: INTERFACE_IInArchive(;) INTERFACE_IOutArchive(;) + HRESULT Open2(IInStream *stream, IArchiveOpenCallback *callback); + private: CObjectVector<CItemEx> _items; CMyComPtr<IInStream> _inStream; diff --git a/CPP/7zip/Archive/Tar/TarHandlerOut.cpp b/CPP/7zip/Archive/Tar/TarHandlerOut.cpp index ea39d7e2..3454868e 100755 --- a/CPP/7zip/Archive/Tar/TarHandlerOut.cpp +++ b/CPP/7zip/Archive/Tar/TarHandlerOut.cpp @@ -15,7 +15,6 @@ using namespace NWindows; using namespace NCOM; -using namespace NTime; namespace NArchive { namespace NTar { @@ -27,34 +26,33 @@ STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type) } STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, - IArchiveUpdateCallback *updateCallback) + IArchiveUpdateCallback *callback) { COM_TRY_BEGIN - CObjectVector<CUpdateItemInfo> updateItems; - for(UInt32 i = 0; i < numItems; i++) + CObjectVector<CUpdateItem> updateItems; + for (UInt32 i = 0; i < numItems; i++) { - CUpdateItemInfo updateItem; + CUpdateItem ui; Int32 newData; Int32 newProperties; UInt32 indexInArchive; - if (!updateCallback) + if (!callback) return E_FAIL; - RINOK(updateCallback->GetUpdateItemInfo(i, - &newData, &newProperties, &indexInArchive)); - updateItem.NewProperties = IntToBool(newProperties); - updateItem.NewData = IntToBool(newData); - updateItem.IndexInArchive = indexInArchive; - updateItem.IndexInClient = i; + RINOK(callback->GetUpdateItemInfo(i, &newData, &newProperties, &indexInArchive)); + ui.NewProperties = IntToBool(newProperties); + ui.NewData = IntToBool(newData); + ui.IndexInArchive = indexInArchive; + ui.IndexInClient = i; if (IntToBool(newProperties)) { FILETIME utcTime; UString name; - bool isDirectoryStatusDefined; + /* UInt32 attributes; { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(i, kpidAttributes, &prop)); + RINOK(callback->GetProperty(i, kpidAttrib, &prop)); if (prop.vt == VT_EMPTY) attributes = 0; else if (prop.vt != VT_UI4) @@ -62,16 +60,17 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt else attributes = prop.ulVal; } + */ { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(i, kpidLastWriteTime, &prop)); + RINOK(callback->GetProperty(i, kpidMTime, &prop)); if (prop.vt != VT_FILETIME) return E_INVALIDARG; utcTime = prop.filetime; } { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(i, kpidPath, &prop)); + RINOK(callback->GetProperty(i, kpidPath, &prop)); if (prop.vt == VT_EMPTY) name.Empty(); else if (prop.vt != VT_BSTR) @@ -81,27 +80,21 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt } { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(i, kpidIsFolder, &prop)); + RINOK(callback->GetProperty(i, kpidIsDir, &prop)); if (prop.vt == VT_EMPTY) - isDirectoryStatusDefined = false; + ui.IsDir = false; else if (prop.vt != VT_BOOL) return E_INVALIDARG; else - { - updateItem.IsDirectory = (prop.boolVal != VARIANT_FALSE); - isDirectoryStatusDefined = true; - } + ui.IsDir = (prop.boolVal != VARIANT_FALSE); } - updateItem.Name = UnicodeStringToMultiByte( - NItemName::MakeLegalName(name), CP_OEMCP); - if (!isDirectoryStatusDefined) - updateItem.IsDirectory = ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0); - if (updateItem.IsDirectory) - updateItem.Name += '/'; + ui.Name = UnicodeStringToMultiByte(NItemName::MakeLegalName(name), CP_OEMCP); + if (ui.IsDir) + ui.Name += '/'; - if(!FileTimeToUnixTime(utcTime, updateItem.Time)) + if (!NTime::FileTimeToUnixTime(utcTime, ui.Time)) { - updateItem.Time = 0; + ui.Time = 0; // return E_INVALIDARG; } } @@ -110,16 +103,16 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt UInt64 size; { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(i, kpidSize, &prop)); + RINOK(callback->GetProperty(i, kpidSize, &prop)); if (prop.vt != VT_UI8) return E_INVALIDARG; size = prop.uhVal.QuadPart; } - updateItem.Size = size; + ui.Size = size; } - updateItems.Add(updateItem); + updateItems.Add(ui); } - return UpdateArchive(_inStream, outStream, _items, updateItems, updateCallback); + return UpdateArchive(_inStream, outStream, _items, updateItems, callback); COM_TRY_END } diff --git a/CPP/7zip/Archive/Tar/TarHeader.cpp b/CPP/7zip/Archive/Tar/TarHeader.cpp index 35f0d0cf..3275b284 100755 --- a/CPP/7zip/Archive/Tar/TarHeader.cpp +++ b/CPP/7zip/Archive/Tar/TarHeader.cpp @@ -15,7 +15,7 @@ namespace NFileHeader { const char *kLongLink2 = "@LongLink"; // The magic field is filled with this if uname and gname are valid. - namespace NMagic + namespace NMagic { const char *kUsTar = "ustar"; // 5 chars const char *kGNUTar = "GNUtar "; // 7 chars and a null diff --git a/CPP/7zip/Archive/Tar/TarHeader.h b/CPP/7zip/Archive/Tar/TarHeader.h index 19bb1cac..0b78bdc2 100755 --- a/CPP/7zip/Archive/Tar/TarHeader.h +++ b/CPP/7zip/Archive/Tar/TarHeader.h @@ -45,7 +45,7 @@ namespace NFileHeader namespace NMode { const int kSetUID = 04000; // Set UID on execution - const int kSetGID = 02000; // Set GID on execution + const int kSetGID = 02000; // Set GID on execution const int kSaveText = 01000; // Save text (sticky bit) } @@ -67,7 +67,7 @@ namespace NFileHeader namespace NLinkFlag { const char kOldNormal = '\0'; // Normal disk file, Unix compatible - const char kNormal = '0'; // Normal disk file + const char kNormal = '0'; // Normal disk file const char kLink = '1'; // Link to previously dumped file const char kSymbolicLink = '2'; // Symbolic link const char kCharacter = '3'; // Character special file @@ -76,12 +76,12 @@ namespace NFileHeader const char kFIFO = '6'; // FIFO special file const char kContiguous = '7'; // Contiguous file - const char kDumpDir = 'D'; /* GNUTYPE_DUMPDIR. + const char kDumpDir = 'D'; /* GNUTYPE_DUMPDIR. data: list of files created by the --incremental (-G) option - Each file name is preceded by either - - 'Y' (file should be in this archive) - - 'N' (file is a directory, or is not stored in the archive.) - Each file name is terminated by a null + an additional null after + Each file name is preceded by either + - 'Y' (file should be in this archive) + - 'N' (file is a directory, or is not stored in the archive.) + Each file name is terminated by a null + an additional null after the last file name. */ } @@ -94,7 +94,7 @@ namespace NFileHeader extern const char *kLongLink2; // = "@LongLink"; // The magic field is filled with this if uname and gname are valid. - namespace NMagic + namespace NMagic { extern const char *kUsTar; // = "ustar"; // 5 chars extern const char *kGNUTar; // = "GNUtar "; // 7 chars and a null diff --git a/CPP/7zip/Archive/Tar/TarIn.cpp b/CPP/7zip/Archive/Tar/TarIn.cpp index 1318613a..55215ac7 100755 --- a/CPP/7zip/Archive/Tar/TarIn.cpp +++ b/CPP/7zip/Archive/Tar/TarIn.cpp @@ -13,21 +13,6 @@ namespace NArchive { namespace NTar { -HRESULT CInArchive::ReadBytes(void *data, size_t size, size_t &processedSize) -{ - processedSize = size; - RINOK(ReadStream(m_Stream, data, &processedSize)); - m_Position += processedSize; - return S_OK; -} - -HRESULT CInArchive::Open(IInStream *inStream) -{ - RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_Position)); - m_Stream = inStream; - return S_OK; -} - static void MyStrNCpy(char *dest, const char *src, int size) { for (int i = 0; i < size; i++) @@ -62,130 +47,76 @@ static bool OctalToNumber32(const char *srcString, int size, UInt32 &res) #define RIF(x) { if (!(x)) return S_FALSE; } -static bool IsRecordLast(const char *record) +static bool IsRecordLast(const char *buf) { for (int i = 0; i < NFileHeader::kRecordSize; i++) - if (record[i] != 0) + if (buf[i] != 0) return false; return true; } static void ReadString(const char *s, int size, AString &result) { - if (size > NFileHeader::kRecordSize) - size = NFileHeader::kNameSize; - char tempString[NFileHeader::kRecordSize + 1]; - MyStrNCpy(tempString, s, size); - tempString[size] = '\0'; - result = tempString; -} - -static char GetHex(Byte value) -{ - return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10))); + char temp[NFileHeader::kRecordSize + 1]; + MyStrNCpy(temp, s, size); + temp[size] = '\0'; + result = temp; } -HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item) +static HRESULT GetNextItemReal(ISequentialInStream *stream, bool &filled, CItemEx &item, size_t &processedSize) { item.LongLinkSize = 0; - // NFileHeader::CRecord record; - char record[NFileHeader::kRecordSize]; - char *cur = record; + char buf[NFileHeader::kRecordSize]; + char *p = buf; filled = false; - size_t processedSize; - item.HeaderPosition = m_Position; - RINOK(ReadBytes(record, NFileHeader::kRecordSize, processedSize)); - if (processedSize == 0 || - (processedSize == NFileHeader::kRecordSize && IsRecordLast(record))) + processedSize = NFileHeader::kRecordSize; + RINOK(ReadStream(stream, buf, &processedSize)); + if (processedSize == 0 || (processedSize == NFileHeader::kRecordSize && IsRecordLast(buf))) return S_OK; if (processedSize < NFileHeader::kRecordSize) return S_FALSE; - // NFileHeader::CHeader &header = record.Header; - - AString name; - ReadString(cur, NFileHeader::kNameSize, name); - cur += NFileHeader::kNameSize; - - item.Name.Empty(); - int i; - for (i = 0; i < name.Length(); i++) - { - char c = name[i]; - if (((Byte)c) < 0x08) - { - return S_FALSE; - } - if (((Byte)c) < 0x20) - { - item.Name += '['; - item.Name += GetHex((Byte)(((Byte)c) >> 4)); - item.Name += GetHex((Byte)(((Byte)c) & 0xF)); - item.Name += ']'; - } - else - item.Name += c; - } + ReadString(p, NFileHeader::kNameSize, item.Name); p += NFileHeader::kNameSize; - RIF(OctalToNumber32(cur, 8, item.Mode)); - cur += 8; + RIF(OctalToNumber32(p, 8, item.Mode)); p += 8; - if (!OctalToNumber32(cur, 8, item.UID)) - item.UID = 0; - cur += 8; + if (!OctalToNumber32(p, 8, item.UID)) item.UID = 0; p += 8; + if (!OctalToNumber32(p, 8, item.GID)) item.GID = 0; p += 8; - if (!OctalToNumber32(cur, 8, item.GID)) - item.GID = 0; - cur += 8; - - RIF(OctalToNumber(cur, 12, item.Size)); - cur += 12; - - RIF(OctalToNumber32(cur, 12, item.ModificationTime)); - cur += 12; + RIF(OctalToNumber(p, 12, item.Size)); p += 12; + RIF(OctalToNumber32(p, 12, item.MTime)); p += 12; UInt32 checkSum; - RIF(OctalToNumber32(cur, 8, checkSum)); - memmove(cur, NFileHeader::kCheckSumBlanks, 8); - cur += 8; + RIF(OctalToNumber32(p, 8, checkSum)); + memcpy(p, NFileHeader::kCheckSumBlanks, 8); p += 8; - item.LinkFlag = *cur++; + item.LinkFlag = *p++; - ReadString(cur, NFileHeader::kNameSize, item.LinkName); - cur += NFileHeader::kNameSize; + ReadString(p, NFileHeader::kNameSize, item.LinkName); p += NFileHeader::kNameSize; - memmove(item.Magic, cur, 8); - cur += 8; + memcpy(item.Magic, p, 8); p += 8; - ReadString(cur, NFileHeader::kUserNameSize, item.UserName); - cur += NFileHeader::kUserNameSize; - ReadString(cur, NFileHeader::kUserNameSize, item.GroupName); - cur += NFileHeader::kUserNameSize; + ReadString(p, NFileHeader::kUserNameSize, item.UserName); p += NFileHeader::kUserNameSize; + ReadString(p, NFileHeader::kUserNameSize, item.GroupName); p += NFileHeader::kUserNameSize; - item.DeviceMajorDefined = (cur[0] != 0); - RIF(OctalToNumber32(cur, 8, item.DeviceMajor)); - cur += 8; - - item.DeviceMinorDefined = (cur[0] != 0); - RIF(OctalToNumber32(cur, 8, item.DeviceMinor)); - cur += 8; + item.DeviceMajorDefined = (p[0] != 0); RIF(OctalToNumber32(p, 8, item.DeviceMajor)); p += 8; + item.DeviceMinorDefined = (p[0] != 0); RIF(OctalToNumber32(p, 8, item.DeviceMinor)); p += 8; AString prefix; - ReadString(cur, NFileHeader::kPrefixSize, prefix); - cur += NFileHeader::kPrefixSize; - if (!prefix.IsEmpty() && item.IsMagic() && + ReadString(p, NFileHeader::kPrefixSize, prefix); + p += NFileHeader::kPrefixSize; + if (!prefix.IsEmpty() && item.IsMagic() && (item.LinkFlag != 'L' /* || prefix != "00000000000" */ )) item.Name = prefix + AString('/') + item.Name; if (item.LinkFlag == NFileHeader::NLinkFlag::kLink) item.Size = 0; - UInt32 checkSumReal = 0; - for(i = 0; i < NFileHeader::kRecordSize; i++) - checkSumReal += Byte(record[i]); + for (int i = 0; i < NFileHeader::kRecordSize; i++) + checkSumReal += (Byte)buf[i]; if (checkSumReal != checkSum) return S_FALSE; @@ -194,9 +125,10 @@ HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item) return S_OK; } -HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item) +HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &item) { - RINOK(GetNextItemReal(filled, item)); + size_t processedSize; + RINOK(GetNextItemReal(stream, filled, item, processedSize)); if (!filled) return S_OK; // GNUtar extension @@ -205,22 +137,25 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item) if (item.Name.Compare(NFileHeader::kLongLink) != 0) if (item.Name.Compare(NFileHeader::kLongLink2) != 0) return S_FALSE; - UInt64 headerPosition = item.HeaderPosition; - size_t processedSize; AString fullName; if (item.Size > (1 << 15)) return S_FALSE; - char *buffer = fullName.GetBuffer((int)item.Size + 1); - RINOK(ReadBytes(buffer, (size_t)item.Size, processedSize)); + int packSize = (int)item.GetPackSize(); + char *buffer = fullName.GetBuffer(packSize + 1); + + RINOK(ReadStream_FALSE(stream, buffer, packSize)); + processedSize += packSize; buffer[item.Size] = '\0'; fullName.ReleaseBuffer(); - if (processedSize != item.Size) - return S_FALSE; - RINOK(Skeep((0 - item.Size) & 0x1FF)); - RINOK(GetNextItemReal(filled, item)); + + UInt64 headerPosition = item.HeaderPosition; + { + size_t processedSize2; + RINOK(GetNextItemReal(stream, filled, item, processedSize2)); + } + item.LongLinkSize = (unsigned)processedSize; item.Name = fullName; - item.LongLinkSize = item.HeaderPosition - headerPosition; item.HeaderPosition = headerPosition; } else if (item.LinkFlag == 'g' || item.LinkFlag == 'x' || item.LinkFlag == 'X') @@ -238,20 +173,4 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item) return S_OK; } -HRESULT CInArchive::Skeep(UInt64 numBytes) -{ - 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 dataSize) -{ - return Skeep((dataSize + 0x1FF) & (~((UInt64)0x1FF))); -} - }} diff --git a/CPP/7zip/Archive/Tar/TarIn.h b/CPP/7zip/Archive/Tar/TarIn.h index 20c030ef..cc6e3f5b 100755 --- a/CPP/7zip/Archive/Tar/TarIn.h +++ b/CPP/7zip/Archive/Tar/TarIn.h @@ -11,20 +11,8 @@ namespace NArchive { namespace NTar { -class CInArchive -{ - CMyComPtr<IInStream> m_Stream; - UInt64 m_Position; - - HRESULT ReadBytes(void *data, size_t size, size_t &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 ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &itemInfo); + }} #endif diff --git a/CPP/7zip/Archive/Tar/TarItem.h b/CPP/7zip/Archive/Tar/TarItem.h index 451d74bc..7d95844d 100755 --- a/CPP/7zip/Archive/Tar/TarItem.h +++ b/CPP/7zip/Archive/Tar/TarItem.h @@ -3,8 +3,6 @@ #ifndef __ARCHIVE_TAR_ITEM_H #define __ARCHIVE_TAR_ITEM_H -#include <time.h> - #include "Common/Types.h" #include "Common/MyString.h" @@ -14,28 +12,29 @@ namespace NArchive { namespace NTar { -class CItem +struct CItem { -public: AString Name; + UInt64 Size; + UInt32 Mode; UInt32 UID; UInt32 GID; - UInt64 Size; - UInt32 ModificationTime; - char LinkFlag; + UInt32 MTime; + UInt32 DeviceMajor; + UInt32 DeviceMinor; + AString LinkName; - char Magic[8]; AString UserName; AString GroupName; + char Magic[8]; + char LinkFlag; bool DeviceMajorDefined; - UInt32 DeviceMajor; bool DeviceMinorDefined; - UInt32 DeviceMinor; - bool IsDirectory() const - { + bool IsDir() const + { switch(LinkFlag) { case NFileHeader::NLinkFlag::kDirectory: @@ -48,22 +47,23 @@ public: return false; } - bool IsMagic() const - { + bool IsMagic() const + { for (int i = 0; i < 5; i++) if (Magic[i] != NFileHeader::NMagic::kUsTar[i]) return false; return true; } + + UInt64 GetPackSize() const { return (Size + 0x1FF) & (~((UInt64)0x1FF)); } }; -class CItemEx: public CItem +struct CItemEx: public CItem { -public: UInt64 HeaderPosition; - UInt64 LongLinkSize; - UInt64 GetDataPosition() const { return HeaderPosition + LongLinkSize + NFileHeader::kRecordSize; }; - UInt64 GetFullSize() const { return LongLinkSize + NFileHeader::kRecordSize + Size; }; + unsigned LongLinkSize; + UInt64 GetDataPosition() const { return HeaderPosition + LongLinkSize + NFileHeader::kRecordSize; } + UInt64 GetFullSize() const { return LongLinkSize + NFileHeader::kRecordSize + Size; } }; }} diff --git a/CPP/7zip/Archive/Tar/TarOut.cpp b/CPP/7zip/Archive/Tar/TarOut.cpp index a697b4d2..0892748f 100755 --- a/CPP/7zip/Archive/Tar/TarOut.cpp +++ b/CPP/7zip/Archive/Tar/TarOut.cpp @@ -100,7 +100,7 @@ HRESULT COutArchive::WriteHeaderReal(const CItem &item) RETURN_IF_NOT_TRUE(MakeOctalString12(cur, item.Size)); cur += 12; - RETURN_IF_NOT_TRUE(MakeOctalString12(cur, item.ModificationTime)); + RETURN_IF_NOT_TRUE(MakeOctalString12(cur, item.MTime)); cur += 12; memmove(cur, NFileHeader::kCheckSumBlanks, 8); diff --git a/CPP/7zip/Archive/Tar/TarUpdate.cpp b/CPP/7zip/Archive/Tar/TarUpdate.cpp index b4241e0d..62c6bff6 100755 --- a/CPP/7zip/Archive/Tar/TarUpdate.cpp +++ b/CPP/7zip/Archive/Tar/TarUpdate.cpp @@ -18,7 +18,7 @@ namespace NTar { HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, const CObjectVector<NArchive::NTar::CItemEx> &inputItems, - const CObjectVector<CUpdateItemInfo> &updateItems, + const CObjectVector<CUpdateItem> &updateItems, IArchiveUpdateCallback *updateCallback) { COutArchive outArchive; @@ -29,11 +29,11 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, int i; for(i = 0; i < updateItems.Size(); i++) { - const CUpdateItemInfo &updateItem = updateItems[i]; - if (updateItem.NewData) - complexity += updateItem.Size; + const CUpdateItem &ui = updateItems[i]; + if (ui.NewData) + complexity += ui.Size; else - complexity += inputItems[updateItem.IndexInArchive].GetFullSize(); + complexity += inputItems[ui.IndexInArchive].GetFullSize(); } RINOK(updateCallback->SetTotal(complexity)); @@ -56,13 +56,13 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, lps->InSize = lps->OutSize = complexity; RINOK(lps->SetCur()); - const CUpdateItemInfo &updateItem = updateItems[i]; + const CUpdateItem &ui = updateItems[i]; CItem item; - if (updateItem.NewProperties) + if (ui.NewProperties) { item.Mode = 0777; - item.Name = (updateItem.Name); - if (updateItem.IsDirectory) + item.Name = (ui.Name); + if (ui.IsDir) { item.LinkFlag = NFileHeader::NLinkFlag::kDirectory; item.Size = 0; @@ -70,9 +70,9 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, else { item.LinkFlag = NFileHeader::NLinkFlag::kNormal; - item.Size = updateItem.Size; + item.Size = ui.Size; } - item.ModificationTime = updateItem.Time; + item.MTime = ui.Time; item.DeviceMajorDefined = false; item.DeviceMinorDefined = false; item.UID = 0; @@ -81,30 +81,30 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, } else { - const CItemEx &existItemInfo = inputItems[updateItem.IndexInArchive]; + const CItemEx &existItemInfo = inputItems[ui.IndexInArchive]; item = existItemInfo; } - if (updateItem.NewData) + if (ui.NewData) { - item.Size = updateItem.Size; + item.Size = ui.Size; if (item.Size == UInt64(Int64(-1))) return E_INVALIDARG; } else { - const CItemEx &existItemInfo = inputItems[updateItem.IndexInArchive]; + const CItemEx &existItemInfo = inputItems[ui.IndexInArchive]; item.Size = existItemInfo.Size; } - if (updateItem.NewData) + if (ui.NewData) { CMyComPtr<ISequentialInStream> fileInStream; - HRESULT res = updateCallback->GetStream(updateItem.IndexInClient, &fileInStream); + HRESULT res = updateCallback->GetStream(ui.IndexInClient, &fileInStream); if (res != S_FALSE) { RINOK(res); RINOK(outArchive.WriteHeader(item)); - if (!updateItem.IsDirectory) + if (!ui.IsDir) { RINOK(copyCoder->Code(fileInStream, outStream, NULL, NULL, progress)); if (copyCoderSpec->TotalSize != item.Size) @@ -112,14 +112,14 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, RINOK(outArchive.FillDataResidual(item.Size)); } } - complexity += updateItem.Size; + complexity += ui.Size; RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); } else { - const CItemEx &existItemInfo = inputItems[updateItem.IndexInArchive]; + const CItemEx &existItemInfo = inputItems[ui.IndexInArchive]; UInt64 size; - if (updateItem.NewProperties) + if (ui.NewProperties) { RINOK(outArchive.WriteHeader(item)); RINOK(inStream->Seek(existItemInfo.GetDataPosition(), STREAM_SEEK_SET, NULL)); diff --git a/CPP/7zip/Archive/Tar/TarUpdate.h b/CPP/7zip/Archive/Tar/TarUpdate.h index 67d671f5..7d196d1c 100755 --- a/CPP/7zip/Archive/Tar/TarUpdate.h +++ b/CPP/7zip/Archive/Tar/TarUpdate.h @@ -9,7 +9,7 @@ namespace NArchive { namespace NTar { -struct CUpdateItemInfo +struct CUpdateItem { bool NewData; bool NewProperties; @@ -19,12 +19,12 @@ struct CUpdateItemInfo UInt32 Time; UInt64 Size; AString Name; - bool IsDirectory; + bool IsDir; }; HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, const CObjectVector<CItemEx> &inputItems, - const CObjectVector<CUpdateItemInfo> &updateItems, + const CObjectVector<CUpdateItem> &updateItems, IArchiveUpdateCallback *updateCallback); }} diff --git a/CPP/7zip/Archive/Arj/StdAfx.h b/CPP/7zip/Archive/Udf/StdAfx.h index e7fb6986..2e4be10b 100755 --- a/CPP/7zip/Archive/Arj/StdAfx.h +++ b/CPP/7zip/Archive/Udf/StdAfx.h @@ -4,5 +4,6 @@ #define __STDAFX_H #include "../../../Common/MyWindows.h" +#include "../../../Common/NewHandler.h" #endif diff --git a/CPP/7zip/Archive/Udf/UdfHandler.cpp b/CPP/7zip/Archive/Udf/UdfHandler.cpp new file mode 100755 index 00000000..10a1a900 --- /dev/null +++ b/CPP/7zip/Archive/Udf/UdfHandler.cpp @@ -0,0 +1,361 @@ +// Udf/Handler.cpp + +#include "StdAfx.h" + +#include "UdfHandler.h" + +#include "Common/NewHandler.h" +#include "Common/ComTry.h" + +#include "Windows/Time.h" +#include "Windows/PropVariant.h" + +#include "../../Common/ProgressUtils.h" +#include "../../Compress/Copy/CopyCoder.h" +#include "../Common/DummyOutStream.h" + +namespace NArchive { +namespace NUdf { + +void UdfTimeToFileTime(const CTime &t, NWindows::NCOM::CPropVariant &prop) +{ + UInt64 numSecs; + const Byte *d = t.Data; + if (!NWindows::NTime::GetSecondsSince1601(t.GetYear(), d[4], d[5], d[6], d[7], d[8], numSecs)) + return; + if (t.IsLocal()) + numSecs -= t.GetMinutesOffset() * 60; + FILETIME ft; + UInt64 v = (((numSecs * 100 + d[9]) * 100 + d[10]) * 100 + d[11]) * 10; + ft.dwLowDateTime = (UInt32)v; + ft.dwHighDateTime = (UInt32)(v >> 32); + prop = ft; +} + +STATPROPSTG kProps[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidIsDir, VT_BOOL}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackSize, VT_UI8}, + { NULL, kpidMTime, VT_FILETIME}, + { NULL, kpidATime, VT_FILETIME} +}; + +STATPROPSTG kArcProps[] = +{ + { NULL, kpidComment, VT_BSTR}, + { NULL, kpidClusterSize, VT_UI4}, + { NULL, kpidCTime, VT_FILETIME} +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch(propID) + { + case kpidComment: + { + UString comment = _archive.GetComment(); + if (!comment.IsEmpty()) + prop = comment; + break; + } + + case kpidClusterSize: + if (_archive.LogVols.Size() > 0) + { + UInt32 blockSize = _archive.LogVols[0].BlockSize; + int i; + for (i = 1; i < _archive.LogVols.Size(); i++) + if (_archive.LogVols[i].BlockSize != blockSize) + break; + if (i == _archive.LogVols.Size()) + prop = blockSize; + } + break; + + case kpidCTime: + if (_archive.LogVols.Size() == 1) + { + const CLogVol &vol = _archive.LogVols[0]; + if (vol.FileSets.Size() >= 1) + UdfTimeToFileTime(vol.FileSets[0].RecodringTime, prop); + } + break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +class CProgressImp: public CProgressVirt +{ + CMyComPtr<IArchiveOpenCallback> _callback; + UInt64 _numFiles; + UInt64 _numBytes; +public: + HRESULT SetTotal(UInt64 numBytes); + HRESULT SetCompleted(UInt64 numFiles, UInt64 numBytes); + HRESULT SetCompleted(); + CProgressImp(IArchiveOpenCallback *callback): _callback(callback), _numFiles(0), _numBytes(0) {} +}; + +HRESULT CProgressImp::SetTotal(UInt64 numBytes) +{ + if (_callback) + return _callback->SetTotal(NULL, &numBytes); + return S_OK; +} + +HRESULT CProgressImp::SetCompleted(UInt64 numFiles, UInt64 numBytes) +{ + _numFiles = numFiles; + _numBytes = numBytes; + return SetCompleted(); +} + +HRESULT CProgressImp::SetCompleted() +{ + if (_callback) + return _callback->SetCompleted(&_numFiles, &_numBytes); + return S_OK; +} + +STDMETHODIMP CHandler::Open(IInStream *stream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback *callback) +{ + COM_TRY_BEGIN + { + Close(); + CProgressImp progressImp(callback); + RINOK(_archive.Open(stream, &progressImp)); + bool showVolName = (_archive.LogVols.Size() > 1); + for (int volIndex = 0; volIndex < _archive.LogVols.Size(); volIndex++) + { + const CLogVol &vol = _archive.LogVols[volIndex]; + bool showFileSetName = (vol.FileSets.Size() > 1); + for (int fsIndex = 0; fsIndex < vol.FileSets.Size(); fsIndex++) + { + const CFileSet &fs = vol.FileSets[fsIndex]; + for (int i = ((showVolName || showFileSetName) ? 0 : 1); i < fs.Refs.Size(); i++) + { + CRef2 ref2; + ref2.Vol = volIndex; + ref2.Fs = fsIndex; + ref2.Ref = i; + _refs2.Add(ref2); + } + } + } + _inStream = stream; + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + _inStream.Release(); + _archive.Clear(); + _refs2.Clear(); + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _refs2.Size(); + return S_OK; +} + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + { + const CRef2 &ref2 = _refs2[index]; + const CLogVol &vol = _archive.LogVols[ref2.Vol]; + const CRef &ref = vol.FileSets[ref2.Fs].Refs[ref2.Ref]; + const CFile &file = _archive.Files[ref.FileIndex]; + const CItem &item = _archive.Items[file.ItemIndex]; + switch(propID) + { + case kpidPath: prop = _archive.GetItemPath(ref2.Vol, ref2.Fs, ref2.Ref, + _archive.LogVols.Size() > 1, vol.FileSets.Size() > 1); break; + case kpidIsDir: prop = item.IsDir(); break; + case kpidSize: if (!item.IsDir()) prop = (UInt64)item.Size; break; + case kpidPackSize: if (!item.IsDir()) prop = (UInt64)item.NumLogBlockRecorded * vol.BlockSize; break; + case kpidMTime: UdfTimeToFileTime(item.MTime, prop); break; + case kpidATime: UdfTimeToFileTime(item.ATime, prop); break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +class CUdfInStream: + public ISequentialInStream, + public CMyUnknownImp +{ + MY_UNKNOWN_IMP + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + UInt64 _rem; +public: + CInArchive *_archive; + CMyComPtr<IInStream> _stream; + CRef2 _ref2; + int _extentIndex; + UInt32 _offsetInExtent; + + void Init(UInt64 size) + { + _extentIndex = 0; + _offsetInExtent = 0; + _rem = size; + } + void ReleaseStream() { _stream.Release(); } +}; + +STDMETHODIMP CUdfInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + if (processedSize) + *processedSize = 0; + if (size > _rem) + size = (UInt32)_rem; + while (size > 0) + { + const CLogVol &vol = _archive->LogVols[_ref2.Vol]; + const CRef &ref = vol.FileSets[_ref2.Fs].Refs[_ref2.Ref]; + const CFile &file = _archive->Files[ref.FileIndex]; + const CItem &item = _archive->Items[file.ItemIndex]; + + const CMyExtent &extent = item.Extents[_extentIndex]; + UInt32 rem = extent.GetLen() - _offsetInExtent; + if (rem == 0) + { + _extentIndex++; + _offsetInExtent = 0; + continue; + } + if (size > rem) + size = rem; + + int partitionIndex = vol.PartitionMaps[extent.PartitionRef].PartitionIndex; + UInt32 logBlockNumber = extent.Pos; + const CPartition &partition = _archive->Partitions[partitionIndex]; + UInt64 offset = ((UInt64)partition.Pos << _archive->SecLogSize) + + (UInt64)logBlockNumber * vol.BlockSize + _offsetInExtent; + + RINOK(_stream->Seek(offset, STREAM_SEEK_SET, NULL)); + HRESULT res = _stream->Read(data, size, &size); + _offsetInExtent += size; + _rem -= size; + if (processedSize) + *processedSize = size; + return res; + } + return S_OK; +} + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool testMode = (_aTestMode != 0); + bool allFilesMode = (numItems == UInt32(-1)); + if (allFilesMode) + numItems = _refs2.Size(); + if (numItems == 0) + return S_OK; + UInt64 totalSize = 0; + UInt32 i; + + for (i = 0; i < numItems; i++) + { + UInt32 index = (allFilesMode ? i : indices[i]); + const CRef2 &ref2 = _refs2[index]; + const CRef &ref = _archive.LogVols[ref2.Vol].FileSets[ref2.Fs].Refs[ref2.Ref]; + const CFile &file = _archive.Files[ref.FileIndex]; + const CItem &item = _archive.Items[file.ItemIndex]; + if (!item.IsDir()) + totalSize += item.Size; + } + extractCallback->SetTotal(totalSize); + + UInt64 currentTotalSize = 0; + UInt64 currentItemSize; + + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); + CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr<ICompressProgressInfo> progress = lps; + lps->Init(extractCallback, false); + + CUdfInStream *udfInStreamSpec = new CUdfInStream(); + CMyComPtr<ISequentialInStream> udfInStream = udfInStreamSpec; + + udfInStreamSpec->_archive = &_archive; + udfInStreamSpec->_stream = _inStream; + + CDummyOutStream *outStreamSpec = new CDummyOutStream; + CMyComPtr<ISequentialOutStream> outStream(outStreamSpec); + + for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) + { + lps->InSize = lps->OutSize = currentTotalSize; + RINOK(lps->SetCur()); + currentItemSize = 0; + CMyComPtr<ISequentialOutStream> realOutStream; + Int32 askMode = testMode ? + NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + UInt32 index = allFilesMode ? i : indices[i]; + + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + + const CRef2 &ref2 = _refs2[index]; + const CRef &ref = _archive.LogVols[ref2.Vol].FileSets[ref2.Fs].Refs[ref2.Ref]; + const CFile &file = _archive.Files[ref.FileIndex]; + const CItem &item = _archive.Items[file.ItemIndex]; + + if (item.IsDir()) + { + RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + continue; + } + currentItemSize = item.Size; + + if (!testMode && (!realOutStream)) + continue; + RINOK(extractCallback->PrepareOperation(askMode)); + + outStreamSpec->SetStream(realOutStream); + realOutStream.Release(); + outStreamSpec->Init(); + Int32 opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + if (item.IsRecAndAlloc() && item.CheckChunkSizes() && _archive.CheckItemExtents(ref2.Vol, item)) + { + udfInStreamSpec->_ref2 = ref2; + udfInStreamSpec->Init(item.Size); + RINOK(copyCoder->Code(udfInStream, outStream, NULL, NULL, progress)); + opRes = (outStreamSpec->GetSize() == currentItemSize) ? + NArchive::NExtract::NOperationResult::kOK: + NArchive::NExtract::NOperationResult::kDataError; + } + outStreamSpec->ReleaseStream(); + RINOK(extractCallback->SetOperationResult(opRes)); + } + return S_OK; + COM_TRY_END +} + +}} diff --git a/CPP/7zip/Archive/Deb/DebHandler.h b/CPP/7zip/Archive/Udf/UdfHandler.h index 297a91be..ceab85ae 100755 --- a/CPP/7zip/Archive/Deb/DebHandler.h +++ b/CPP/7zip/Archive/Udf/UdfHandler.h @@ -1,30 +1,36 @@ -// DebHandler.h +// Udf/Handler.h -#ifndef __DEB_HANDLER_H -#define __DEB_HANDLER_H +#ifndef __UDF_HANDLER_H +#define __UDF_HANDLER_H #include "Common/MyCom.h" #include "../IArchive.h" -#include "DebItem.h" +#include "UdfIn.h" namespace NArchive { -namespace NDeb { +namespace NUdf { -class CHandler: +struct CRef2 +{ + int Vol; + int Fs; + int Ref; +}; + +class CHandler: public IInArchive, public CMyUnknownImp { + CMyComPtr<IInStream> _inStream; + CInArchive _archive; + CRecordVector<CRef2> _refs2; public: MY_UNKNOWN_IMP1(IInArchive) - INTERFACE_IInArchive(;) - -private: - CObjectVector<CItemEx> _items; - CMyComPtr<IInStream> _inStream; }; }} #endif +
\ No newline at end of file diff --git a/CPP/7zip/Archive/Udf/UdfIn.cpp b/CPP/7zip/Archive/Udf/UdfIn.cpp new file mode 100755 index 00000000..3637bbc6 --- /dev/null +++ b/CPP/7zip/Archive/Udf/UdfIn.cpp @@ -0,0 +1,853 @@ +// Archive/UdfIn.cpp + +#include "StdAfx.h" + +#include "UdfIn.h" + +#include "../../Common/StreamUtils.h" + +extern "C" +{ + #include "../../../../C/CpuArch.h" +} + +#define Get16(p) GetUi16(p) +#define Get32(p) GetUi32(p) +#define Get64(p) GetUi64(p) + +namespace NArchive { +namespace NUdf { + +const int kNumPartitionsMax = 64; +const int kNumLogVolumesMax = 64; +const int kNumRecureseLevelsMax = 1 << 10; +const int kNumItemsMax = 1 << 27; +const int kNumFilesMax = 1 << 28; +const int kNumRefsMax = 1 << 28; +const UInt32 kNumExtentsMax = (UInt32)1 << 30; +const UInt64 kFileNameLengthTotalMax = (UInt64)1 << 33; + +void MY_FAST_CALL Crc16GenerateTable(void); + +#define CRC16_INIT_VAL 0 +#define CRC16_GET_DIGEST(crc) (crc) +#define CRC16_UPDATE_BYTE(crc, b) (g_Crc16Table[(((crc) >> 8) ^ (b)) & 0xFF] ^ ((crc) << 8)) + +#define kCrc16Poly 0x1021 +UInt16 g_Crc16Table[256]; + +void MY_FAST_CALL Crc16GenerateTable(void) +{ + UInt32 i; + for (i = 0; i < 256; i++) + { + UInt32 r = (i << 8); + for (int j = 8; j > 0; j--) + r = ((r & 0x8000) ? ((r << 1) ^ kCrc16Poly) : (r << 1)) & 0xFFFF; + g_Crc16Table[i] = (UInt16)r; + } +} + +UInt16 MY_FAST_CALL Crc16_Update(UInt16 v, const void *data, size_t size) +{ + const Byte *p = (const Byte *)data; + for (; size > 0 ; size--, p++) + v = CRC16_UPDATE_BYTE(v, *p); + return v; +} + +UInt16 MY_FAST_CALL Crc16Calc(const void *data, size_t size) +{ + return Crc16_Update(CRC16_INIT_VAL, data, size); +} + +struct CCrc16TableInit { CCrc16TableInit() { Crc16GenerateTable(); } } g_Crc16TableInit; + +void CDString128::Parse(const Byte *buf) { memcpy(Data, buf, sizeof(Data)); } + +void CDString::Parse(const Byte *p, unsigned size) +{ + Data.SetCapacity(size); + memcpy(Data, p, size); +} + +static UString ParseDString(const Byte *data, int size) +{ + UString res; + wchar_t *p; + if (size > 0) + { + Byte type = data[0]; + if (type == 8) + { + p = res.GetBuffer((int)size + 1); + for (int i = 1; i < size; i++) + { + wchar_t c = data[i]; + if (c == 0) + break; + *p++ = c; + } + } + else if (type == 16) + { + p = res.GetBuffer((int)size / 2 + 1); + for (int i = 1; i + 2 <= size; i += 2) + { + wchar_t c = ((wchar_t)data[i] << 8) | data[i + 1]; + if (c == 0) + break; + *p++ = c; + } + } + else + return L"[unknow]"; + *p++ = 0; + res.ReleaseBuffer(); + } + return res; +} + +UString CDString:: GetString() const { return ParseDString(Data, (int)Data.GetCapacity()); } +UString CDString128::GetString() const +{ + int size = Data[sizeof(Data) - 1]; + return ParseDString(Data, MyMin(size, (int)(sizeof(Data) - 1))); +} + +void CTime::Parse(const Byte *buf) { memcpy(Data, buf, sizeof(Data)); } + +/* +void CRegId::Parse(const Byte *buf) +{ + Flags = buf[0]; + memcpy(Id, buf + 1, sizeof(Id)); + memcpy(Suffix, buf + 24, sizeof(Suffix)); +} +*/ + +// ECMA 3/7.1 + +struct CExtent +{ + UInt32 Len; + UInt32 Pos; + + void Parse(const Byte *buf); +}; + +void CExtent::Parse(const Byte *buf) +{ + Len = Get32(buf); + Pos = Get32(buf + 4); +} + +// ECMA 3/7.2 + +struct CTag +{ + UInt16 Id; + UInt16 Version; + // Byte Checksum; + // UInt16 SerialNumber; + // UInt16 Crc; + // UInt16 CrcLen; + // UInt32 TagLocation; + + HRESULT Parse(const Byte *buf, size_t size); +}; + +HRESULT CTag::Parse(const Byte *buf, size_t size) +{ + if (size < 16) + return S_FALSE; + Byte sum = 0; + int i; + for (i = 0; i < 4; i++) sum = sum + buf[i]; + for (i = 5; i < 16; i++) sum = sum + buf[i]; + if (sum != buf[4] || buf[5] != 0) return S_FALSE; + + Id = Get16(buf); + Version = Get16(buf + 2); + // SerialNumber = Get16(buf + 6); + UInt16 crc = Get16(buf + 8); + UInt16 crcLen = Get16(buf + 10); + // TagLocation = Get32(buf + 12); + + if (size >= 16 + (size_t)crcLen) + if (crc == Crc16Calc(buf + 16, crcLen)) + return S_OK; + return S_FALSE; +} + +// ECMA 3/7.2.1 + +enum EDescriptorType +{ + DESC_TYPE_SpoaringTable = 0, // UDF + DESC_TYPE_PrimVol = 1, + DESC_TYPE_AnchorVolPtr = 2, + DESC_TYPE_VolPtr = 3, + DESC_TYPE_ImplUseVol = 4, + DESC_TYPE_Partition = 5, + DESC_TYPE_LogicalVol = 6, + DESC_TYPE_UnallocSpace = 7, + DESC_TYPE_Terminating = 8, + DESC_TYPE_LogicalVolIntegrity = 9, + DESC_TYPE_FileSet = 256, + DESC_TYPE_FileId = 257, + DESC_TYPE_AllocationExtent = 258, + DESC_TYPE_Indirect = 259, + DESC_TYPE_Terminal = 260, + DESC_TYPE_File = 261, + DESC_TYPE_ExtendedAttrHeader = 262, + DESC_TYPE_UnallocatedSpace = 263, + DESC_TYPE_SpaceBitmap = 264, + DESC_TYPE_PartitionIntegrity = 265, + DESC_TYPE_ExtendedFile = 266, +}; + + +void CLogBlockAddr::Parse(const Byte *buf) +{ + Pos = Get32(buf); + PartitionRef = Get16(buf + 4); +} + +void CShortAllocDesc::Parse(const Byte *buf) +{ + Len = Get32(buf); + Pos = Get32(buf + 4); +} + +/* +void CADImpUse::Parse(const Byte *buf) +{ + Flags = Get16(buf); + UdfUniqueId = Get32(buf + 2); +} +*/ + +void CLongAllocDesc::Parse(const Byte *buf) +{ + Len = Get32(buf); + Location.Parse(buf + 4); + // memcpy(ImplUse, buf + 10, sizeof(ImplUse)); + // adImpUse.Parse(ImplUse); +} + +bool CInArchive::CheckExtent(int volIndex, int partitionRef, UInt32 blockPos, UInt32 len) const +{ + const CLogVol &vol = LogVols[volIndex]; + const CPartition &partition = Partitions[vol.PartitionMaps[partitionRef].PartitionIndex]; + UInt64 offset = ((UInt64)partition.Pos << SecLogSize) + (UInt64)blockPos * vol.BlockSize; + return (offset + len) <= (((UInt64)partition.Pos + partition.Len) << SecLogSize); +} + +bool CInArchive::CheckItemExtents(int volIndex, const CItem &item) const +{ + for (int i = 0; i < item.Extents.Size(); i++) + { + const CMyExtent &e = item.Extents[i]; + if (!CheckExtent(volIndex, e.PartitionRef, e.Pos, e.GetLen())) + return false; + } + return true; +} + +HRESULT CInArchive::Read(int volIndex, int partitionRef, UInt32 blockPos, UInt32 len, Byte *buf) +{ + if (!CheckExtent(volIndex, partitionRef, blockPos, len)) + return S_FALSE; + const CLogVol &vol = LogVols[volIndex]; + const CPartition &partition = Partitions[vol.PartitionMaps[partitionRef].PartitionIndex]; + RINOK(_stream->Seek(((UInt64)partition.Pos << SecLogSize) + + (UInt64)blockPos * vol.BlockSize, STREAM_SEEK_SET, NULL)); + return ReadStream_FALSE(_stream, buf, len); +} + +HRESULT CInArchive::Read(int volIndex, const CLongAllocDesc &lad, Byte *buf) +{ + return Read(volIndex, lad.Location.PartitionRef, lad.Location.Pos, lad.GetLen(), (Byte *)buf); +} + +HRESULT CInArchive::ReadFromFile(int volIndex, const CItem &item, CByteBuffer &buf) +{ + if (item.Size >= (UInt32)1 << 30) + return S_FALSE; + buf.SetCapacity((size_t)item.Size); + size_t pos = 0; + for (int i = 0; i < item.Extents.Size(); i++) + { + const CMyExtent &e = item.Extents[i]; + UInt32 len = e.GetLen(); + RINOK(Read(volIndex, e.PartitionRef, e.Pos, len, (Byte *)buf + pos)); + pos += len; + } + return S_OK; +} + + +void CIcbTag::Parse(const Byte *p) +{ + // PriorDirectNum = Get32(p); + // StrategyType = Get16(p + 4); + // StrategyParam = Get16(p + 6); + // MaxNumOfEntries = Get16(p + 8); + FileType = p[11]; + // ParentIcb.Parse(p + 12); + Flags = Get16(p + 18); +} + +void CItem::Parse(const Byte *p) +{ + // Uid = Get32(p + 36); + // Gid = Get32(p + 40); + // Permissions = Get32(p + 44); + // FileLinkCount = Get16(p + 48); + // RecordFormat = p[50]; + // RecordDisplayAttr = p[51]; + // RecordLen = Get32(p + 52); + Size = Get64(p + 56); + NumLogBlockRecorded = Get64(p + 64); + ATime.Parse(p + 72); + MTime.Parse(p + 84); + // AttrtTime.Parse(p + 96); + // CheckPoint = Get32(p + 108); + // ExtendedAttrIcb.Parse(p + 112); + // ImplId.Parse(p + 128); + // UniqueId = Get64(p + 160); +} + +// 4/14.4 +struct CFileId +{ + // UInt16 FileVersion; + Byte FileCharacteristics; + // CByteBuffer ImplUse; + CDString Id; + CLongAllocDesc Icb; + + bool IsItLinkParent() const { return (FileCharacteristics & FILEID_CHARACS_Parent) != 0; } + HRESULT Parse(const Byte *p, size_t size, size_t &processed); +}; + +HRESULT CFileId::Parse(const Byte *p, size_t size, size_t &processed) +{ + processed = 0; + if (size < 38) + return S_FALSE; + CTag tag; + RINOK(tag.Parse(p, size)); + if (tag.Id != DESC_TYPE_FileId) + return S_FALSE; + // FileVersion = Get16(p + 16); + FileCharacteristics = p[18]; + unsigned idLen = p[19]; + Icb.Parse(p + 20); + unsigned impLen = Get16(p + 36); + if (size < 38 + idLen + impLen) + return S_FALSE; + // ImplUse.SetCapacity(impLen); + processed = 38; + // memcpy(ImplUse, p + processed, impLen); + processed += impLen; + Id.Parse(p + processed, idLen); + processed += idLen; + for (;(processed & 3) != 0; processed++) + if (p[processed] != 0) + return S_FALSE; + return (processed <= size) ? S_OK : S_FALSE; +} + +HRESULT CInArchive::ReadFileItem(int volIndex, int fsIndex, const CLongAllocDesc &lad, int numRecurseAllowed) +{ + if (Files.Size() % 100 == 0) + RINOK(_progress->SetCompleted(Files.Size(), _processedProgressBytes)); + if (numRecurseAllowed-- == 0) + return S_FALSE; + CFile &file = Files.Back(); + const CLogVol &vol = LogVols[volIndex]; + CPartition &partition = Partitions[vol.PartitionMaps[lad.Location.PartitionRef].PartitionIndex]; + + UInt32 key = lad.Location.Pos; + UInt32 value; + const UInt32 kRecursedErrorValue = (UInt32)(Int32)-1; + if (partition.Map.Find(key, value)) + { + if (value == kRecursedErrorValue) + return S_FALSE; + file.ItemIndex = value; + } + else + { + value = Items.Size(); + file.ItemIndex = (int)value; + if (partition.Map.Set(key, kRecursedErrorValue)) + return S_FALSE; + RINOK(ReadItem(volIndex, fsIndex, lad, numRecurseAllowed)); + if (!partition.Map.Set(key, value)) + return S_FALSE; + } + return S_OK; +} + +HRESULT CInArchive::ReadItem(int volIndex, int fsIndex, const CLongAllocDesc &lad, int numRecurseAllowed) +{ + if (Items.Size() > kNumItemsMax) + return S_FALSE; + Items.Add(CItem()); + CItem &item = Items.Back(); + + const CLogVol &vol = LogVols[volIndex]; + + if (lad.GetLen() != vol.BlockSize) + return S_FALSE; + + CByteBuffer buf; + size_t size = lad.GetLen(); + buf.SetCapacity(size); + RINOK(Read(volIndex, lad, buf)); + + CTag tag; + const Byte *p = buf; + RINOK(tag.Parse(p, size)); + if (tag.Id != DESC_TYPE_File) + return S_FALSE; + + item.IcbTag.Parse(p + 16); + if (item.IcbTag.FileType != ICB_FILE_TYPE_DIR && + item.IcbTag.FileType != ICB_FILE_TYPE_FILE) + return S_FALSE; + + item.Parse(p); + + _processedProgressBytes += (UInt64)item.NumLogBlockRecorded * vol.BlockSize + size; + + UInt32 extendedAttrLen = Get32(p + 168); + UInt32 allocDescriptorsLen = Get32(p + 172); + + if ((extendedAttrLen & 3) != 0) + return S_FALSE; + int pos = 176; + if (extendedAttrLen > size - pos) + return S_FALSE; + /* + if (extendedAttrLen != 16) + { + if (extendedAttrLen < 24) + return S_FALSE; + CTag attrTag; + RINOK(attrTag.Parse(p + pos, size)); + if (attrTag.Id != DESC_TYPE_ExtendedAttrHeader) + return S_FALSE; + // UInt32 implAttrLocation = Get32(p + pos + 16); + // UInt32 applicationlAttrLocation = Get32(p + pos + 20); + } + */ + pos += extendedAttrLen; + + int desctType = item.IcbTag.GetDescriptorType(); + // if (desctType == ICB_DESC_TYPE_INLINE || desctType == ICB_DESC_TYPE_EXTENDED) + if (desctType != ICB_DESC_TYPE_SHORT && desctType != ICB_DESC_TYPE_LONG) + return S_FALSE; + if (allocDescriptorsLen > size - pos) + return S_FALSE; + for (UInt32 i = 0; i < allocDescriptorsLen;) + { + CMyExtent e; + if (desctType == ICB_DESC_TYPE_SHORT) + { + if (i + 8 > allocDescriptorsLen) + return S_FALSE; + CShortAllocDesc sad; + sad.Parse(p + pos + i); + e.Pos = sad.Pos; + e.Len = sad.Len; + e.PartitionRef = lad.Location.PartitionRef; + i += 8; + } + else + { + if (i + 16 > allocDescriptorsLen) + return S_FALSE; + CLongAllocDesc ladNew; + ladNew.Parse(p + pos + i); + e.Pos = ladNew.Location.Pos; + e.PartitionRef = ladNew.Location.PartitionRef; + e.Len = ladNew.Len; + i += 16; + } + item.Extents.Add(e); + } + + if (item.IcbTag.IsDir()) + { + if (!item.CheckChunkSizes() || !CheckItemExtents(volIndex, item)) + return S_FALSE; + CByteBuffer buf; + RINOK(ReadFromFile(volIndex, item, buf)); + item.Size = 0; + item.Extents.ClearAndFree(); + + const Byte *p = buf; + size = buf.GetCapacity(); + size_t processedTotal = 0; + for (; processedTotal < size;) + { + size_t processedCur; + CFileId fileId; + RINOK(fileId.Parse(p + processedTotal, size - processedTotal, processedCur)); + if (!fileId.IsItLinkParent()) + { + CFile file; + // file.FileVersion = fileId.FileVersion; + // file.FileCharacteristics = fileId.FileCharacteristics; + // file.ImplUse = fileId.ImplUse; + file.Id = fileId.Id; + + _fileNameLengthTotal += file.Id.Data.GetCapacity(); + if (_fileNameLengthTotal > kFileNameLengthTotalMax) + return S_FALSE; + + item.SubFiles.Add(Files.Size()); + if (Files.Size() > kNumFilesMax) + return S_FALSE; + Files.Add(file); + RINOK(ReadFileItem(volIndex, fsIndex, fileId.Icb, numRecurseAllowed)); + } + processedTotal += processedCur; + } + } + else + { + if ((UInt32)item.Extents.Size() > kNumExtentsMax - _numExtents) + return S_FALSE; + _numExtents += item.Extents.Size(); + } + + return S_OK; +} + +HRESULT CInArchive::FillRefs(CFileSet &fs, int fileIndex, int parent, int numRecurseAllowed) +{ + if (_numRefs % 10000 == 0) + { + RINOK(_progress->SetCompleted()); + } + if (numRecurseAllowed-- == 0) + return S_FALSE; + if (_numRefs >= kNumRefsMax) + return S_FALSE; + _numRefs++; + CRef ref; + ref.FileIndex = fileIndex; + ref.Parent = parent; + parent = fs.Refs.Size(); + fs.Refs.Add(ref); + const CItem &item = Items[Files[fileIndex].ItemIndex]; + for (int i = 0; i < item.SubFiles.Size(); i++) + { + RINOK(FillRefs(fs, item.SubFiles[i], parent, numRecurseAllowed)); + } + return S_OK; +} + +HRESULT CInArchive::Open2() +{ + Clear(); + + UInt64 fileSize; + RINOK(_stream->Seek(0, STREAM_SEEK_END, &fileSize)); + + const int kSecLogSizeMax = 11; + const int kSecLogSizeMin = 8; + Byte buf[1 << kSecLogSizeMax]; + for (SecLogSize = kSecLogSizeMax; SecLogSize >= kSecLogSizeMin; SecLogSize -= 3) + { + Int32 bufSize = 1 << SecLogSize; + if (bufSize > fileSize) + return S_FALSE; + RINOK(_stream->Seek(-bufSize, STREAM_SEEK_END, NULL)); + RINOK(ReadStream_FALSE(_stream, buf, bufSize)); + CTag tag; + if (tag.Parse(buf, bufSize) == S_OK) + if (tag.Id == DESC_TYPE_AnchorVolPtr) + break; + } + if (SecLogSize < kSecLogSizeMin) + return S_FALSE; + + CExtent extentVDS; + extentVDS.Parse(buf + 16); + + for (UInt32 location = extentVDS.Pos; ; location++) + { + size_t bufSize = 1 << SecLogSize; + size_t pos = 0; + RINOK(_stream->Seek((UInt64)location << SecLogSize, STREAM_SEEK_SET, NULL)); + RINOK(ReadStream_FALSE(_stream, buf, bufSize)); + CTag tag; + RINOK(tag.Parse(buf + pos, bufSize - pos)); + if (tag.Id == DESC_TYPE_Terminating) + break; + if (tag.Id == DESC_TYPE_Partition) + { + if (Partitions.Size() >= kNumPartitionsMax) + return S_FALSE; + CPartition partition; + // UInt32 volDescSeqNumer = Get32(buf + 16); + // partition.Flags = Get16(buf + 20); + partition.Number = Get16(buf + 22); + // partition.ContentsId.Parse(buf + 24); + + // memcpy(partition.ContentsUse, buf + 56, sizeof(partition.ContentsUse)); + // ContentsUse is Partition Header Description. + + // partition.AccessType = Get32(buf + 184); + partition.Pos = Get32(buf + 188); + partition.Len = Get32(buf + 192); + // partition.ImplId.Parse(buf + 196); + // memcpy(partition.ImplUse, buf + 228, sizeof(partition.ImplUse)); + + Partitions.Add(partition); + } + else if (tag.Id == DESC_TYPE_LogicalVol) + { + if (LogVols.Size() >= kNumLogVolumesMax) + return S_FALSE; + CLogVol vol; + vol.Id.Parse(buf + 84); + vol.BlockSize = Get32(buf + 212); + // vol.DomainId.Parse(buf + 216); + + if (vol.BlockSize < 512 || vol.BlockSize > ((UInt32)1 << 30)) + return S_FALSE; + + // memcpy(vol.ContentsUse, buf + 248, sizeof(vol.ContentsUse)); + vol.FileSetLocation.Parse(buf + 248); + + // UInt32 mapTableLength = Get32(buf + 264); + UInt32 numPartitionMaps = Get32(buf + 268); + if (numPartitionMaps > kNumPartitionsMax) + return S_FALSE; + // vol.ImplId.Parse(buf + 272); + // memcpy(vol.ImplUse, buf + 128, sizeof(vol.ImplUse)); + size_t pos = 440; + for (UInt32 i = 0; i < numPartitionMaps; i++) + { + if (pos + 2 > bufSize) + return S_FALSE; + CPartitionMap pm; + pm.Type = buf[pos]; + // pm.Length = buf[pos + 1]; + Byte len = buf[pos + 1]; + + if (pos + len > bufSize) + return S_FALSE; + + // memcpy(pm.Data, buf + pos + 2, pm.Length - 2); + if (pm.Type == 1) + { + if (pos + 6 > bufSize) + return S_FALSE; + // pm.VolSeqNumber = Get16(buf + pos + 2); + pm.PartitionNumber = Get16(buf + pos + 4); + } + else + return S_FALSE; + pos += len; + vol.PartitionMaps.Add(pm); + } + LogVols.Add(vol); + } + } + + UInt64 totalSize = 0; + + int volIndex; + for (volIndex = 0; volIndex < LogVols.Size(); volIndex++) + { + CLogVol &vol = LogVols[volIndex]; + for (int pmIndex = 0; pmIndex < vol.PartitionMaps.Size(); pmIndex++) + { + CPartitionMap &pm = vol.PartitionMaps[pmIndex]; + int i; + for (i = 0; i < Partitions.Size(); i++) + { + CPartition &part = Partitions[i]; + if (part.Number == pm.PartitionNumber) + { + if (part.VolIndex >= 0) + return S_FALSE; + pm.PartitionIndex = i; + part.VolIndex = volIndex; + + totalSize += (UInt64)part.Len << SecLogSize; + break; + } + } + if (i == Partitions.Size()) + return S_FALSE; + } + } + + RINOK(_progress->SetTotal(totalSize)); + + for (volIndex = 0; volIndex < LogVols.Size(); volIndex++) + { + CLogVol &vol = LogVols[volIndex]; + + CLongAllocDesc nextExtent = vol.FileSetLocation; + // while (nextExtent.ExtentLen != 0) + // for (int i = 0; i < 1; i++) + { + if (nextExtent.GetLen() < 512) + return S_FALSE; + CByteBuffer buf; + buf.SetCapacity(nextExtent.GetLen()); + RINOK(Read(volIndex, nextExtent, buf)); + const Byte *p = buf; + size_t size = nextExtent.GetLen(); + + CTag tag; + RINOK(tag.Parse(p, size)); + if (tag.Id != DESC_TYPE_FileSet) + return S_FALSE; + + CFileSet fs; + fs.RecodringTime.Parse(p + 16); + // fs.InterchangeLevel = Get16(p + 18); + // fs.MaxInterchangeLevel = Get16(p + 20); + // fs.FileSetNumber = Get32(p + 40); + // fs.FileSetDescNumber = Get32(p + 44); + + // fs.Id.Parse(p + 304); + // fs.CopyrightId.Parse(p + 336); + // fs.AbstractId.Parse(p + 368); + + fs.RootDirICB.Parse(p + 400); + // fs.DomainId.Parse(p + 416); + + // fs.SystemStreamDirICB.Parse(p + 464); + + vol.FileSets.Add(fs); + + // nextExtent.Parse(p + 448); + } + + for (int fsIndex = 0; fsIndex < vol.FileSets.Size(); fsIndex++) + { + CFileSet &fs = vol.FileSets[fsIndex]; + int fileIndex = Files.Size(); + Files.Add(CFile()); + RINOK(ReadFileItem(volIndex, fsIndex, fs.RootDirICB, kNumRecureseLevelsMax)); + RINOK(FillRefs(fs, fileIndex, -1, kNumRecureseLevelsMax)); + } + } + + return S_OK; +} + +HRESULT CInArchive::Open(IInStream *inStream, CProgressVirt *progress) +{ + _progress = progress; + _stream = inStream; + HRESULT res; + try { res = Open2(); } + catch(...) { Clear(); res = S_FALSE; } + _stream.Release(); + return res; +} + +void CInArchive::Clear() +{ + Partitions.Clear(); + LogVols.Clear(); + Items.Clear(); + Files.Clear(); + _fileNameLengthTotal = 0; + _numRefs = 0; + _numExtents = 0; + _processedProgressBytes = 0; +} + +UString CInArchive::GetComment() const +{ + UString res; + for (int i = 0; i < LogVols.Size(); i++) + { + if (i > 0) + res += L" "; + res += LogVols[i].GetName(); + } + return res; +} + +static UString GetSpecName(const UString &name) +{ + UString name2 = name; + name2.Trim(); + if (name2.IsEmpty()) + { + /* + wchar_t s[32]; + ConvertUInt64ToString(id, s); + return L"[" + (UString)s + L"]"; + */ + return L"[]"; + } + return name; +} + +static void UpdateWithName(UString &res, const UString &addString) +{ + if (res.IsEmpty()) + res = addString; + else + res = addString + WCHAR_PATH_SEPARATOR + res; +} + +UString CInArchive::GetItemPath(int volIndex, int fsIndex, int refIndex, + bool showVolName, bool showFsName) const +{ + // showVolName = true; + const CLogVol &vol = LogVols[volIndex]; + const CFileSet &fs = vol.FileSets[fsIndex]; + + UString name; + + for (;;) + { + const CRef &ref = fs.Refs[refIndex]; + refIndex = ref.Parent; + if (refIndex < 0) + break; + UpdateWithName(name, GetSpecName(Files[ref.FileIndex].GetName())); + } + + if (showFsName) + { + wchar_t s[32]; + ConvertUInt64ToString(fsIndex, s); + UString newName = L"File Set "; + newName += s; + UpdateWithName(name, newName); + } + + if (showVolName) + { + wchar_t s[32]; + ConvertUInt64ToString(volIndex, s); + UString newName = s; + UString newName2 = vol.GetName(); + if (newName2.IsEmpty()) + newName2 = L"Volume"; + newName += L'-'; + newName += newName2; + UpdateWithName(name, newName); + } + return name; +} + +}} diff --git a/CPP/7zip/Archive/Udf/UdfIn.h b/CPP/7zip/Archive/Udf/UdfIn.h new file mode 100755 index 00000000..f99991a0 --- /dev/null +++ b/CPP/7zip/Archive/Udf/UdfIn.h @@ -0,0 +1,368 @@ +// Archive/UdfIn.h -- UDF / ECMA-167 + +#ifndef __ARCHIVE_UDF_IN_H +#define __ARCHIVE_UDF_IN_H + +#include "Common/MyCom.h" +#include "Common/IntToString.h" +#include "Common/Buffer.h" +#include "Common/MyString.h" +#include "Common/MyMap.h" + +#include "../../IStream.h" + +namespace NArchive { +namespace NUdf { + +// ---------- ECMA Part 1 ---------- + +// ECMA 1/7.2.12 + +/* +struct CDString32 +{ + Byte Data[32]; + void Parse(const Byte *buf); + // UString GetString() const; +}; +*/ + +struct CDString128 +{ + Byte Data[128]; + void Parse(const Byte *buf); + UString GetString() const; +}; + +struct CDString +{ + CByteBuffer Data; + void Parse(const Byte *p, unsigned size); + UString GetString() const; +}; + + +// ECMA 1/7.3 + +struct CTime +{ + Byte Data[12]; + + unsigned GetType() const { return Data[1] >> 4; } + bool IsLocal() const { return GetType() == 1; } + int GetMinutesOffset() const + { + int t = (Data[0] | ((UInt16)Data[1] << 8)) & 0xFFF; + if ((t >> 11) != 0) + t -= (1 << 12); + return (t > (60 * 24) || t < -(60 * 24)) ? 0 : t; + } + unsigned GetYear() const { return (Data[2] | ((UInt16)Data[3] << 8)); } + void Parse(const Byte *buf); +}; + + +// ECMA 1/7.4 + +/* +struct CRegId +{ + Byte Flags; + char Id[23]; + char Suffix[8]; + + void Parse(const Byte *buf); +}; +*/ + +// ---------- ECMA Part 3: Volume Structure ---------- + +// ECMA 3/10.5 + +struct CPartition +{ + // UInt16 Flags; + UInt16 Number; + // CRegId ContentsId; + // Byte ContentsUse[128]; + // UInt32 AccessType; + + UInt32 Pos; + UInt32 Len; + + // CRegId ImplId; + // Byte ImplUse[128]; + + int VolIndex; + CMap32 Map; + + CPartition(): VolIndex(-1) {} + + // bool IsNsr() const { return (strncmp(ContentsId.Id, "+NSR0", 5) == 0); } + // bool IsAllocated() const { return ((Flags & 1) != 0); } +}; + +struct CLogBlockAddr +{ + UInt32 Pos; + UInt16 PartitionRef; + + void Parse(const Byte *buf); +}; + +enum EShortAllocDescType +{ + SHORT_ALLOC_DESC_TYPE_RecordedAndAllocated = 0, + SHORT_ALLOC_DESC_TYPE_NotRecordedButAllocated = 1, + SHORT_ALLOC_DESC_TYPE_NotRecordedAndNotAllocated = 2, + SHORT_ALLOC_DESC_TYPE_NextExtent = 3 +}; + +struct CShortAllocDesc +{ + UInt32 Len; + UInt32 Pos; + + // 4/14.14.1 + // UInt32 GetLen() const { return Len & 0x3FFFFFFF; } + // UInt32 GetType() const { return Len >> 30; } + // bool IsRecAndAlloc() const { return GetType() == SHORT_ALLOC_DESC_TYPE_RecordedAndAllocated; } + void Parse(const Byte *buf); +}; + +/* +struct CADImpUse +{ + UInt16 Flags; + UInt32 UdfUniqueId; + void Parse(const Byte *buf); +}; +*/ + +struct CLongAllocDesc +{ + UInt32 Len; + CLogBlockAddr Location; + + // Byte ImplUse[6]; + // CADImpUse adImpUse; // UDF + + UInt32 GetLen() const { return Len & 0x3FFFFFFF; } + UInt32 GetType() const { return Len >> 30; } + bool IsRecAndAlloc() const { return GetType() == SHORT_ALLOC_DESC_TYPE_RecordedAndAllocated; } + void Parse(const Byte *buf); +}; + +struct CPartitionMap +{ + Byte Type; + // Byte Len; + + // Type - 1 + // UInt16 VolSeqNumber; + UInt16 PartitionNumber; + + // Byte Data[256]; + + int PartitionIndex; +}; + +enum EIcbFileType +{ + ICB_FILE_TYPE_DIR = 4, + ICB_FILE_TYPE_FILE = 5 +}; + +enum EIcbDescriptorType +{ + ICB_DESC_TYPE_SHORT = 0, + ICB_DESC_TYPE_LONG = 1, + ICB_DESC_TYPE_EXTENDED = 2, + ICB_DESC_TYPE_INLINE = 3 +}; + +struct CIcbTag +{ + // UInt32 PriorDirectNum; + // UInt16 StrategyType; + // UInt16 StrategyParam; + // UInt16 MaxNumOfEntries; + Byte FileType; + // CLogBlockAddr ParentIcb; + UInt16 Flags; + + bool IsDir() const { return FileType == ICB_FILE_TYPE_DIR; } + int GetDescriptorType() const { return Flags & 3; } + void Parse(const Byte *p); +}; + +// const Byte FILEID_CHARACS_Existance = (1 << 0); +const Byte FILEID_CHARACS_Parent = (1 << 3); + +struct CFile +{ + // UInt16 FileVersion; + // Byte FileCharacteristics; + // CByteBuffer ImplUse; + CDString Id; + + CFile(): /* FileVersion(0), FileCharacteristics(0), */ ItemIndex(-1) {} + int ItemIndex; + UString GetName() const { return Id.GetString(); } +}; + +struct CMyExtent +{ + UInt32 Pos; + UInt32 Len; + int PartitionRef; + + UInt32 GetLen() const { return Len & 0x3FFFFFFF; } + UInt32 GetType() const { return Len >> 30; } + bool IsRecAndAlloc() const { return GetType() == SHORT_ALLOC_DESC_TYPE_RecordedAndAllocated; } +}; + +struct CItem +{ + CIcbTag IcbTag; + + // UInt32 Uid; + // UInt32 Gid; + // UInt32 Permissions; + // UInt16 FileLinkCount; + // Byte RecordFormat; + // Byte RecordDisplayAttr; + // UInt32 RecordLen; + UInt64 Size; + UInt64 NumLogBlockRecorded; + CTime ATime; + CTime MTime; + // CTime AttrtTime; + // UInt32 CheckPoint; + // CLongAllocDesc ExtendedAttrIcb; + // CRegId ImplId; + // UInt64 UniqueId; + + CRecordVector<CMyExtent> Extents; + CRecordVector<int> SubFiles; + + void Parse(const Byte *buf); + + bool IsRecAndAlloc() const + { + for (int i = 0; i < Extents.Size(); i++) + if (!Extents[i].IsRecAndAlloc()) + return false; + return true; + } + + UInt64 GetChunksSumSize() const + { + UInt64 size = 0; + for (int i = 0; i < Extents.Size(); i++) + size += Extents[i].GetLen(); + return size; + } + + bool CheckChunkSizes() const { return GetChunksSumSize() == Size; } + + bool IsDir() const { return IcbTag.IsDir(); } +}; + +struct CRef +{ + int Parent; + int FileIndex; +}; + + +// ECMA 4 / 14.1 +struct CFileSet +{ + CTime RecodringTime; + // UInt16 InterchangeLevel; + // UInt16 MaxInterchangeLevel; + // UInt32 FileSetNumber; + // UInt32 FileSetDescNumber; + // CDString32 Id; + // CDString32 CopyrightId; + // CDString32 AbstractId; + + CLongAllocDesc RootDirICB; + // CRegId DomainId; + // CLongAllocDesc SystemStreamDirICB; + + CRecordVector<CRef> Refs; +}; + + +// ECMA 3/10.6 + +struct CLogVol +{ + CDString128 Id; + UInt32 BlockSize; + // CRegId DomainId; + + // Byte ContentsUse[16]; + CLongAllocDesc FileSetLocation; // UDF + + // CRegId ImplId; + // Byte ImplUse[128]; + + CObjectVector<CPartitionMap> PartitionMaps; + CObjectVector<CFileSet> FileSets; + + UString GetName() const { return Id.GetString(); } +}; + +struct CProgressVirt +{ + virtual HRESULT SetTotal(UInt64 numBytes) PURE; + virtual HRESULT SetCompleted(UInt64 numFiles, UInt64 numBytes) PURE; + virtual HRESULT SetCompleted() PURE; +}; + +class CInArchive +{ + CMyComPtr<IInStream> _stream; + CProgressVirt *_progress; + + HRESULT Read(int volIndex, int partitionRef, UInt32 blockPos, UInt32 len, Byte *buf); + HRESULT Read(int volIndex, const CLongAllocDesc &lad, Byte *buf); + HRESULT ReadFromFile(int volIndex, const CItem &item, CByteBuffer &buf); + + HRESULT ReadFileItem(int volIndex, int fsIndex, const CLongAllocDesc &lad, int numRecurseAllowed); + HRESULT ReadItem(int volIndex, int fsIndex, const CLongAllocDesc &lad, int numRecurseAllowed); + + HRESULT Open2(); + HRESULT FillRefs(CFileSet &fs, int fileIndex, int parent, int numRecurseAllowed); + + UInt64 _processedProgressBytes; + + UInt64 _fileNameLengthTotal; + int _numRefs; + UInt32 _numExtents; + bool CheckExtent(int volIndex, int partitionRef, UInt32 blockPos, UInt32 len) const; +public: + HRESULT Open(IInStream *inStream, CProgressVirt *progress); + void Clear(); + + CObjectVector<CPartition> Partitions; + CObjectVector<CLogVol> LogVols; + + CObjectVector<CItem> Items; + CObjectVector<CFile> Files; + + int SecLogSize; + + UString GetComment() const; + UString GetItemPath(int volIndex, int fsIndex, int refIndex, + bool showVolName, bool showFsName) const; + + bool CheckItemExtents(int volIndex, const CItem &item) const; +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Udf/UdfRegister.cpp b/CPP/7zip/Archive/Udf/UdfRegister.cpp new file mode 100755 index 00000000..b3a6c152 --- /dev/null +++ b/CPP/7zip/Archive/Udf/UdfRegister.cpp @@ -0,0 +1,13 @@ +// UdfRegister.cpp + +#include "StdAfx.h" + +#include "../../Common/RegisterArc.h" + +#include "UdfHandler.h" +static IInArchive *CreateArc() { return new NArchive::NUdf::CHandler; } + +static CArcInfo g_ArcInfo = + { L"Udf", L"iso", 0, 0xE0, { 0, 'N', 'S', 'R', '0' }, 5, false, CreateArc, 0 }; + +REGISTER_ARC(Udf) diff --git a/CPP/7zip/Archive/Wim/WimHandler.cpp b/CPP/7zip/Archive/Wim/WimHandler.cpp index baa2c824..1b8661c9 100755 --- a/CPP/7zip/Archive/Wim/WimHandler.cpp +++ b/CPP/7zip/Archive/Wim/WimHandler.cpp @@ -5,14 +5,22 @@ #include "Common/IntToString.h" #include "Common/Defs.h" #include "Common/ComTry.h" +#include "Common/StringToInt.h" +#include "Common/UTFConvert.h" #include "Windows/PropVariant.h" #include "../../Common/StreamUtils.h" #include "../../Common/ProgressUtils.h" +#include "../../../../C/CpuArch.h" + #include "WimHandler.h" +#define Get16(p) GetUi16(p) +#define Get32(p) GetUi32(p) +#define Get64(p) GetUi64(p) + using namespace NWindows; namespace NArchive { @@ -20,17 +28,17 @@ namespace NWim { #define WIM_DETAILS -STATPROPSTG kProps[] = +STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, - { NULL, kpidIsFolder, VT_BOOL}, + { NULL, kpidIsDir, VT_BOOL}, { NULL, kpidSize, VT_UI8}, - { NULL, kpidPackedSize, VT_UI8}, - { NULL, kpidAttributes, VT_UI8}, + { NULL, kpidPackSize, VT_UI8}, + { NULL, kpidAttrib, VT_UI4}, { NULL, kpidMethod, VT_BSTR}, - { NULL, kpidCreationTime, VT_FILETIME}, - { NULL, kpidLastAccessTime, VT_FILETIME}, - { NULL, kpidLastWriteTime, VT_FILETIME} + { NULL, kpidMTime, VT_FILETIME}, + { NULL, kpidCTime, VT_FILETIME}, + { NULL, kpidATime, VT_FILETIME} #ifdef WIM_DETAILS , { NULL, kpidVolume, VT_UI4} @@ -39,17 +47,113 @@ STATPROPSTG kProps[] = #endif }; -STATPROPSTG kArcProps[] = +STATPROPSTG kArcProps[] = { { NULL, kpidSize, VT_UI8}, - { NULL, kpidPackedSize, VT_UI8}, + { NULL, kpidPackSize, VT_UI8}, + { NULL, kpidMethod, VT_BSTR}, + { NULL, kpidCTime, VT_FILETIME}, + { NULL, kpidMTime, VT_FILETIME}, + { NULL, kpidComment, VT_FILETIME}, { NULL, kpidIsVolume, VT_BOOL}, { NULL, kpidVolume, VT_UI4}, { NULL, kpidNumVolumes, VT_UI4} }; +static bool ParseNumber64(const AString &s, UInt64 &res) +{ + const char *end; + if (s.Left(2) == "0x") + { + if (s.Length() == 2) + return false; + res = ConvertHexStringToUInt64((const char *)s + 2, &end); + } + else + { + if (s.IsEmpty()) + return false; + res = ConvertStringToUInt64(s, &end); + } + return *end == 0; +} + +static bool ParseNumber32(const AString &s, UInt32 &res) +{ + UInt64 res64; + if (!ParseNumber64(s, res64) || res64 >= ((UInt64)1 << 32)) + return false; + res = (UInt32)res64; + return true; +} + +void ParseTime(const CXmlItem &item, bool &defined, FILETIME &ft, const AString &s) +{ + defined = false; + int cTimeIndex = item.FindSubTag(s); + if (cTimeIndex >= 0) + { + const CXmlItem &timeItem = item.SubItems[cTimeIndex]; + UInt32 high = 0, low = 0; + if (ParseNumber32(timeItem.GetSubStringForTag("HIGHPART"), high) && + ParseNumber32(timeItem.GetSubStringForTag("LOWPART"), low)) + { + defined = true; + ft.dwHighDateTime = high; + ft.dwLowDateTime = low; + } + } +} + +void CImageInfo::Parse(const CXmlItem &item) +{ + ParseTime(item, CTimeDefined, CTime, "CREATIONTIME"); + ParseTime(item, MTimeDefined, MTime, "LASTMODIFICATIONTIME"); + NameDefined = ConvertUTF8ToUnicode(item.GetSubStringForTag("NAME"), Name); + // IndexDefined = ParseNumber32(item.GetPropertyValue("INDEX"), Index); +} + +void CXml::Parse() +{ + size_t size = Data.GetCapacity(); + if (size < 2 || (size & 1) != 0 || (size > 1 << 24)) + return; + const Byte *p = Data; + if (Get16(p) != 0xFEFF) + return; + UString s; + { + wchar_t *chars = s.GetBuffer((int)size / 2 + 1); + for (size_t i = 2; i < size; i += 2) + *chars++ = (wchar_t)Get16(p + i); + *chars = 0; + s.ReleaseBuffer(); + } + + AString utf; + if (!ConvertUnicodeToUTF8(s, utf)) + return; + ::CXml xml; + if (!xml.Parse(utf)) + return; + if (xml.Root.Name != "WIM") + return; + + for (int i = 0; i < xml.Root.SubItems.Size(); i++) + { + const CXmlItem &item = xml.Root.SubItems[i]; + if (item.IsTagged("IMAGE")) + { + CImageInfo imageInfo; + imageInfo.Parse(item); + Images.Add(imageInfo); + } + } +} + static const wchar_t *kStreamsNamePrefix = L"Files" WSTRING_PATH_SEPARATOR; static const wchar_t *kMethodLZX = L"LZX"; +static const wchar_t *kMethodXpress = L"XPress"; static const wchar_t *kMethodCopy = L"Copy"; IMP_IInArchive_Props @@ -59,11 +163,57 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; + + const CImageInfo *image = NULL; + if (m_Xmls.Size() == 1) + { + const CXml &xml = m_Xmls[0]; + if (xml.Images.Size() == 1) + image = &xml.Images[0]; + } + switch(propID) { case kpidSize: prop = m_Database.GetUnpackSize(); break; - case kpidPackedSize: prop = m_Database.GetPackSize(); break; - case kpidIsVolume: + case kpidPackSize: prop = m_Database.GetPackSize(); break; + + case kpidCTime: + if (m_Xmls.Size() == 1) + { + const CXml &xml = m_Xmls[0]; + int index = -1; + for (int i = 0; i < xml.Images.Size(); i++) + { + const CImageInfo &image = xml.Images[i]; + if (image.CTimeDefined) + if (index < 0 || ::CompareFileTime(&image.CTime, &xml.Images[index].CTime) < 0) + index = i; + } + if (index >= 0) + prop = xml.Images[index].CTime; + } + break; + + case kpidMTime: + if (m_Xmls.Size() == 1) + { + const CXml &xml = m_Xmls[0]; + int index = -1; + for (int i = 0; i < xml.Images.Size(); i++) + { + const CImageInfo &image = xml.Images[i]; + if (image.MTimeDefined) + if (index < 0 || ::CompareFileTime(&image.MTime, &xml.Images[index].MTime) > 0) + index = i; + } + if (index >= 0) + prop = xml.Images[index].MTime; + } + break; + + case kpidComment: if (image != NULL && image->NameDefined) prop = image->Name; break; + + case kpidIsVolume: if (m_Xmls.Size() > 0) { UInt16 volIndex = m_Xmls[0].VolIndex; @@ -71,7 +221,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) prop = (m_Volumes[volIndex].Header.NumParts > 1); } break; - case kpidVolume: + case kpidVolume: if (m_Xmls.Size() > 0) { UInt16 volIndex = m_Xmls[0].VolIndex; @@ -79,7 +229,39 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) prop = (UInt32)m_Volumes[volIndex].Header.PartNumber; } break; - case kpidNumVolumes: if (m_Volumes.Size() > 0) prop = (UInt32)(m_Volumes.Size() - 1); + case kpidNumVolumes: if (m_Volumes.Size() > 0) prop = (UInt32)(m_Volumes.Size() - 1); break; + case kpidMethod: + { + bool lzx = false, xpress = false, copy = false; + for (int i = 0; i < m_Xmls.Size(); i++) + { + const CVolume &vol = m_Volumes[m_Xmls[i].VolIndex]; + const CHeader &header = vol.Header; + if (header.IsCompressed()) + if (header.IsLzxMode()) + lzx = true; + else + xpress = true; + else + copy = true; + } + UString res; + if (lzx) + res = kMethodLZX; + if (xpress) + { + if (!res.IsEmpty()) + res += L' '; + res += kMethodXpress; + } + if (copy) + { + if (!res.IsEmpty()) + res += L' '; + res += kMethodCopy; + } + prop = res; + } } prop.Detach(value); return S_OK; @@ -94,8 +276,12 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val { const CItem &item = m_Database.Items[index]; const CStreamInfo *si = NULL; + const CVolume *vol = NULL; if (item.StreamIndex >= 0) + { si = &m_Database.Streams[item.StreamIndex]; + vol = &m_Volumes[si->PartNumber]; + } switch(propID) { @@ -114,59 +300,19 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val break; } break; - case kpidIsFolder: - prop = item.IsDirectory(); - break; - case kpidAttributes: - if (item.HasMetadata) - prop = item.Attributes; - break; - case kpidCreationTime: - if (item.HasMetadata) - prop = item.CreationTime; - break; - case kpidLastAccessTime: - if (item.HasMetadata) - prop = item.LastAccessTime; - break; - case kpidLastWriteTime: - if (item.HasMetadata) - prop = item.LastWriteTime; - break; - case kpidPackedSize: - if (si) - prop = si->Resource.PackSize; - else - prop = (UInt64)0; - break; - case kpidSize: - if (si) - prop = si->Resource.UnpackSize; - else - prop = (UInt64)0; - break; - case kpidMethod: - if (si) - if (si->Resource.IsCompressed()) - prop = kMethodLZX; - else - prop = kMethodCopy; - break; + case kpidIsDir: prop = item.isDir(); break; + case kpidAttrib: if (item.HasMetadata) prop = item.Attrib; break; + case kpidCTime: if (item.HasMetadata) prop = item.CTime; break; + case kpidATime: if (item.HasMetadata) prop = item.ATime; break; + case kpidMTime: if (item.HasMetadata) prop = item.MTime; break; + case kpidPackSize: prop = si ? si->Resource.PackSize : (UInt64)0; break; + case kpidSize: prop = si ? si->Resource.UnpackSize : (UInt64)0; break; + case kpidMethod: if (si) prop = si->Resource.IsCompressed() ? + (vol->Header.IsLzxMode() ? kMethodLZX : kMethodXpress) : kMethodCopy; break; #ifdef WIM_DETAILS - case kpidVolume: - if (si) - prop = (UInt32)si->PartNumber; - break; - case kpidOffset: - if (si) - prop = (UInt64)si->Resource.Offset; - break; - case kpidLinks: - if (si) - prop = (UInt32)si->RefCount; - else - prop = (UInt64)0; - break; + case kpidVolume: if (si) prop = (UInt32)si->PartNumber; break; + case kpidOffset: if (si) prop = (UInt64)si->Resource.Offset; break; + case kpidLinks: prop = si ? (UInt32)si->RefCount : (UInt32)0; break; #endif } } @@ -184,16 +330,10 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val prop = s; break; } - case kpidIsFolder: - prop = false; - break; - case kpidPackedSize: - case kpidSize: - prop = (UInt64)m_Xmls[index].Data.GetCapacity(); - break; - case kpidMethod: - prop = L"Copy"; - break; + case kpidIsDir: prop = false; break; + case kpidPackSize: + case kpidSize: prop = (UInt64)m_Xmls[index].Data.GetCapacity(); break; + case kpidMethod: prop = L"Copy"; break; } } } @@ -206,7 +346,7 @@ class CVolumeName { // UInt32 _volIndex; UString _before; - UString _after; + UString _after; public: CVolumeName() {}; @@ -228,7 +368,7 @@ public: } }; -STDMETHODIMP CHandler::Open(IInStream *inStream, +STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 * /* maxCheckStartPosition */, IArchiveOpenCallback *openArchiveCallback) { @@ -300,7 +440,10 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, if (xml.Data == m_Xmls[0].Data) needAddXml = false; if (needAddXml) + { + xml.Parse(); m_Xmls.Add(xml); + } if (i == 1) { @@ -398,7 +541,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(lps->SetCur()); UInt32 index = allFilesMode ? i : indices[i]; i++; - Int32 askMode = testMode ? + Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; @@ -428,7 +571,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, continue; RINOK(extractCallback->PrepareOperation(askMode)); realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(item.HasStream() ? + RINOK(extractCallback->SetOperationResult(item.HasStream() ? NExtract::NOperationResult::kDataError : NExtract::NOperationResult::kOK)); continue; @@ -445,7 +588,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, if (streamIndex != prevSuccessStreamIndex || realOutStream) { Byte digest[20]; - HRESULT res = unpacker.Unpack(m_Volumes[si.PartNumber].Stream, si.Resource, realOutStream, progress, digest); + const CVolume &vol = m_Volumes[si.PartNumber]; + HRESULT res = unpacker.Unpack(vol.Stream, si.Resource, vol.Header.IsLzxMode(), + realOutStream, progress, digest); if (res == S_OK) { if (memcmp(digest, si.Hash, kHashSize) == 0) diff --git a/CPP/7zip/Archive/Wim/WimHandler.h b/CPP/7zip/Archive/Wim/WimHandler.h index 25567743..b7df3606 100755 --- a/CPP/7zip/Archive/Wim/WimHandler.h +++ b/CPP/7zip/Archive/Wim/WimHandler.h @@ -4,6 +4,8 @@ #define __ARCHIVE_WIM_HANDLER_H #include "Common/MyCom.h" +#include "Common/MyXml.h" + #include "../IArchive.h" #include "WimIn.h" @@ -16,13 +18,35 @@ struct CVolume CMyComPtr<IInStream> Stream; }; +struct CImageInfo +{ + bool CTimeDefined; + bool MTimeDefined; + bool NameDefined; + // bool IndexDefined; + + FILETIME CTime; + FILETIME MTime; + UString Name; + // UInt32 Index; + + CImageInfo(): CTimeDefined(false), MTimeDefined(false), NameDefined(false) + // , IndexDefined(false) + {} + void Parse(const CXmlItem &item); +}; + struct CXml { CByteBuffer Data; UInt16 VolIndex; + + CObjectVector<CImageInfo> Images; + + void Parse(); }; -class CHandler: +class CHandler: public IInArchive, public CMyUnknownImp { diff --git a/CPP/7zip/Archive/Wim/WimIn.cpp b/CPP/7zip/Archive/Wim/WimIn.cpp index e9efdaa4..5c741f8f 100755 --- a/CPP/7zip/Archive/Wim/WimIn.cpp +++ b/CPP/7zip/Archive/Wim/WimIn.cpp @@ -15,19 +15,127 @@ #include "WimIn.h" +#define Get16(p) GetUi16(p) +#define Get32(p) GetUi32(p) +#define Get64(p) GetUi64(p) + namespace NArchive{ namespace NWim{ static const int kChunkSizeBits = 15; static const UInt32 kChunkSize = (1 << kChunkSizeBits); +namespace NXpress { + +class CDecoderFlusher +{ + CDecoder *m_Decoder; +public: + bool NeedFlush; + CDecoderFlusher(CDecoder *decoder): m_Decoder(decoder), NeedFlush(true) {} + ~CDecoderFlusher() + { + if (NeedFlush) + m_Decoder->Flush(); + m_Decoder->ReleaseStreams(); + } +}; + +HRESULT CDecoder::CodeSpec(UInt32 outSize) +{ + { + Byte levels[kMainTableSize]; + for (int i = 0; i < kMainTableSize; i += 2) + { + Byte b = m_InBitStream.DirectReadByte(); + levels[i] = b & 0xF; + levels[i + 1] = b >> 4; + } + if (!m_MainDecoder.SetCodeLengths(levels)) + return S_FALSE; + } + + while (outSize > 0) + { + UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream); + if (number < 256) + { + m_OutWindowStream.PutByte((Byte)number); + outSize--; + } + else + { + if (number >= kMainTableSize) + return S_FALSE; + UInt32 posLenSlot = number - 256; + UInt32 posSlot = posLenSlot / kNumLenSlots; + UInt32 len = posLenSlot % kNumLenSlots; + UInt32 distance = (1 << posSlot) - 1 + m_InBitStream.ReadBits(posSlot); + + if (len == kNumLenSlots - 1) + { + len = m_InBitStream.DirectReadByte(); + if (len == 0xFF) + { + len = m_InBitStream.DirectReadByte(); + len |= (UInt32)m_InBitStream.DirectReadByte() << 8; + } + else + len += kNumLenSlots - 1; + } + + len += kMatchMinLen; + UInt32 locLen = (len <= outSize ? len : outSize); + + if (!m_OutWindowStream.CopyBlock(distance, locLen)) + return S_FALSE; + + len -= locLen; + outSize -= locLen; + if (len != 0) + return S_FALSE; + } + } + return S_OK; +} + +const UInt32 kDictSize = (1 << kNumPosSlots); + +HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, UInt32 outSize) +{ + if (!m_OutWindowStream.Create(kDictSize) || !m_InBitStream.Create(1 << 16)) + return E_OUTOFMEMORY; + + CDecoderFlusher flusher(this); + + m_InBitStream.SetStream(inStream); + m_OutWindowStream.SetStream(outStream); + m_InBitStream.Init(); + m_OutWindowStream.Init(false); + + RINOK(CodeSpec(outSize)); + + flusher.NeedFlush = false; + return Flush(); +} + +HRESULT CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, UInt32 outSize) +{ + try { return CodeReal(inStream, outStream, outSize); } + catch(const CInBufferException &e) { return e.ErrorCode; } \ + catch(const CLZOutWindowException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + +} + static void GetFileTimeFromMem(const Byte *p, FILETIME *ft) { - ft->dwLowDateTime = GetUi32(p); - ft->dwHighDateTime = GetUi32(p + 4); + ft->dwLowDateTime = Get32(p); + ft->dwHighDateTime = Get32(p + 4); } -HRESULT CUnpacker::Unpack(IInStream *inStream, const CResource &resource, +HRESULT CUnpacker::Unpack(IInStream *inStream, const CResource &resource, bool lzxMode, ISequentialOutStream *outStream, ICompressProgressInfo *progress) { RINOK(inStream->Seek(resource.Offset, STREAM_SEEK_SET, NULL)); @@ -64,7 +172,7 @@ HRESULT CUnpacker::Unpack(IInStream *inStream, const CResource &resource, RINOK(ReadStream_FALSE(inStream, (Byte *)sizesBuf, sizesBufSize)); const Byte *p = (const Byte *)sizesBuf; - if (!lzxDecoder) + if (lzxMode && !lzxDecoder) { lzxDecoderSpec = new NCompress::NLzx::CDecoder(true); lzxDecoder = lzxDecoderSpec; @@ -78,18 +186,12 @@ HRESULT CUnpacker::Unpack(IInStream *inStream, const CResource &resource, UInt64 offset = 0; if (i > 0) { - if (entrySize == 4) - offset = GetUi32(p); - else - offset = GetUi64(p); + offset = (entrySize == 4) ? Get32(p): Get64(p); p += entrySize; } UInt64 nextOffset = resource.PackSize - sizesBufSize64; if (i + 1 < (UInt32)numChunks) - if (entrySize == 4) - nextOffset = GetUi32(p); - else - nextOffset = GetUi64(p); + nextOffset = (entrySize == 4) ? Get32(p): Get64(p); if (nextOffset < offset) return S_FALSE; @@ -106,28 +208,41 @@ HRESULT CUnpacker::Unpack(IInStream *inStream, const CResource &resource, if (outProcessed + outSize > resource.UnpackSize) outSize = (UInt32)(resource.UnpackSize - outProcessed); UInt64 outSize64 = outSize; - lzxDecoderSpec->SetKeepHistory(false); - ICompressCoder *coder = (inSize == outSize) ? copyCoder : lzxDecoder; - RINOK(coder->Code(limitedStreamSpec, outStream, NULL, &outSize64, NULL)); + if (inSize == outSize) + { + RINOK(copyCoder->Code(limitedStreamSpec, outStream, NULL, &outSize64, NULL)); + } + else + { + if (lzxMode) + { + lzxDecoderSpec->SetKeepHistory(false); + RINOK(lzxDecoder->Code(limitedStreamSpec, outStream, NULL, &outSize64, NULL)); + } + else + { + RINOK(xpressDecoder.Code(limitedStreamSpec, outStream, outSize)); + } + } outProcessed += outSize; } return S_OK; } -HRESULT CUnpacker::Unpack(IInStream *inStream, const CResource &resource, +HRESULT CUnpacker::Unpack(IInStream *inStream, const CResource &resource, bool lzxMode, ISequentialOutStream *outStream, ICompressProgressInfo *progress, Byte *digest) { COutStreamWithSha1 *shaStreamSpec = new COutStreamWithSha1(); CMyComPtr<ISequentialOutStream> shaStream = shaStreamSpec; shaStreamSpec->SetStream(outStream); shaStreamSpec->Init(digest != NULL); - HRESULT result = Unpack(inStream, resource, shaStream, progress); + HRESULT result = Unpack(inStream, resource, lzxMode, shaStream, progress); if (digest) shaStreamSpec->Final(digest); return result; } -static HRESULT UnpackData(IInStream *inStream, const CResource &resource, CByteBuffer &buf, Byte *digest) +static HRESULT UnpackData(IInStream *inStream, const CResource &resource, bool lzxMode, CByteBuffer &buf, Byte *digest) { size_t size = (size_t)resource.UnpackSize; if (size != resource.UnpackSize) @@ -140,29 +255,31 @@ static HRESULT UnpackData(IInStream *inStream, const CResource &resource, CByteB outStreamSpec->Init((Byte *)buf, size); CUnpacker unpacker; - return unpacker.Unpack(inStream, resource, outStream, NULL, digest); + return unpacker.Unpack(inStream, resource, lzxMode, outStream, NULL, digest); } static const UInt32 kSignatureSize = 8; static const Byte kSignature[kSignatureSize] = { 'M', 'S', 'W', 'I', 'M', 0, 0, 0 }; -static void GetResource(const Byte *p, CResource &res) +void CResource::Parse(const Byte *p) { - res.Flags = p[7]; - res.PackSize = GetUi64(p) & (((UInt64)1 << 56) - 1); - res.Offset = GetUi64(p + 8); - res.UnpackSize = GetUi64(p + 16); + Flags = p[7]; + PackSize = Get64(p) & (((UInt64)1 << 56) - 1); + Offset = Get64(p + 8); + UnpackSize = Get64(p + 16); } +#define GetResource(p, res) res.Parse(p) + static void GetStream(const Byte *p, CStreamInfo &s) { - GetResource(p, s.Resource); - s.PartNumber = GetUi16(p + 24); - s.RefCount = GetUi32(p + 26); + s.Resource.Parse(p); + s.PartNumber = Get16(p + 24); + s.RefCount = Get32(p + 26); memcpy(s.Hash, p + 30, kHashSize); } -static HRESULT ParseDirItem(const Byte *base, size_t pos, size_t size, +static HRESULT ParseDirItem(const Byte *base, size_t pos, size_t size, const UString &prefix, CObjectVector<CItem> &items) { for (;;) @@ -170,22 +287,22 @@ static HRESULT ParseDirItem(const Byte *base, size_t pos, size_t size, if (pos + 8 > size) return S_FALSE; const Byte *p = base + pos; - UInt64 length = GetUi64(p); + UInt64 length = Get64(p); if (length == 0) return S_OK; if (pos + 102 > size || pos + length + 8 > size || length > ((UInt64)1 << 62)) return S_FALSE; CItem item; - item.Attributes = GetUi32(p + 8); - // item.SecurityId = GetUi32(p + 0xC); - UInt64 subdirOffset = GetUi64(p + 0x10); - GetFileTimeFromMem(p + 0x28, &item.CreationTime); - GetFileTimeFromMem(p + 0x30, &item.LastAccessTime); - GetFileTimeFromMem(p + 0x38, &item.LastWriteTime); + item.Attrib = Get32(p + 8); + // item.SecurityId = Get32(p + 0xC); + UInt64 subdirOffset = Get64(p + 0x10); + GetFileTimeFromMem(p + 0x28, &item.CTime); + GetFileTimeFromMem(p + 0x30, &item.ATime); + GetFileTimeFromMem(p + 0x38, &item.MTime); memcpy(item.Hash, p + 0x40, kHashSize); - // UInt16 shortNameLen = GetUi16(p + 98); - UInt16 fileNameLen = GetUi16(p + 100); + // UInt16 shortNameLen = Get16(p + 98); + UInt16 fileNameLen = Get16(p + 100); size_t tempPos = pos + 102; if (tempPos + fileNameLen > size) @@ -195,17 +312,17 @@ static HRESULT ParseDirItem(const Byte *base, size_t pos, size_t size, MyStringCopy(sz, (const wchar_t *)prefix); sz += prefix.Length(); for (UInt16 i = 0; i + 2 <= fileNameLen; i += 2) - *sz++ = GetUi16(base + tempPos + i); + *sz++ = Get16(base + tempPos + i); *sz++ = '\0'; item.Name.ReleaseBuffer(); - if (fileNameLen == 0 && item.IsDirectory() && !item.HasStream()) + if (fileNameLen == 0 && item.isDir() && !item.HasStream()) { - item.Attributes = 0x10; // some swm archives have system/hidden attributes for root + item.Attrib = 0x10; // some swm archives have system/hidden attributes for root item.Name.Delete(item.Name.Length() - 1); } items.Add(item); pos += (size_t)length; - if (item.IsDirectory() && (subdirOffset != 0)) + if (item.isDir() && (subdirOffset != 0)) { if (subdirOffset >= size) return S_FALSE; @@ -214,15 +331,15 @@ static HRESULT ParseDirItem(const Byte *base, size_t pos, size_t size, } } -static HRESULT ParseDir(const Byte *base, size_t size, +static HRESULT ParseDir(const Byte *base, size_t size, const UString &prefix, CObjectVector<CItem> &items) { - size_t pos = 0; + size_t pos = 0; if (pos + 8 > size) return S_FALSE; const Byte *p = base + pos; - UInt32 totalLength = GetUi32(p); - // UInt32 numEntries = GetUi32(p + 4); + UInt32 totalLength = Get32(p); + // UInt32 numEntries = Get32(p + 4); pos += 8; { /* @@ -232,7 +349,7 @@ static HRESULT ParseDir(const Byte *base, size_t size, { if (pos + 8 > size) return S_FALSE; - UInt64 len = GetUi64(p + pos); + UInt64 len = Get64(p + pos); entryLens.Add(len); sum += len; pos += 8; @@ -267,9 +384,9 @@ int CompareItems(void *const *a1, void *const *a2, void * /* param */) const CItem &i1 = **((const CItem **)a1); const CItem &i2 = **((const CItem **)a2); - if (i1.IsDirectory() != i2.IsDirectory()) - return (i1.IsDirectory()) ? 1 : -1; - if (i1.IsDirectory()) + if (i1.isDir() != i2.isDir()) + return (i1.isDir()) ? 1 : -1; + if (i1.isDir()) return -MyStringCompareNoCase(i1.Name, i2.Name); int res = MyCompare(i1.StreamIndex, i2.StreamIndex); @@ -278,10 +395,10 @@ int CompareItems(void *const *a1, void *const *a2, void * /* param */) return MyStringCompareNoCase(i1.Name, i2.Name); } -static int FindHash(const CRecordVector<CStreamInfo> &streams, +static int FindHash(const CRecordVector<CStreamInfo> &streams, const CRecordVector<int> &sortedByHash, const Byte *hash) { - int left = 0, right = streams.Size(); + int left = 0, right = streams.Size(); while (left != right) { int mid = (left + right) / 2; @@ -301,50 +418,56 @@ static int FindHash(const CRecordVector<CStreamInfo> &streams, return -1; } -HRESULT ReadHeader(IInStream *inStream, CHeader &h) +HRESULT CHeader::Parse(const Byte *p) { - const UInt32 kHeaderSizeMax = 0xD0; - Byte p[kHeaderSizeMax]; - RINOK(ReadStream_FALSE(inStream, p, kHeaderSizeMax)); - UInt32 haderSize = GetUi32(p + 8); - if (memcmp(p, kSignature, kSignatureSize) != 0) - return S_FALSE; + UInt32 haderSize = Get32(p + 8); if (haderSize < 0x74) return S_FALSE; - h.Version = GetUi32(p + 0x0C); - h.Flags = GetUi32(p + 0x10); - if (!h.IsSupported()) + Version = Get32(p + 0x0C); + Flags = Get32(p + 0x10); + if (!IsSupported()) return S_FALSE; - if (GetUi32(p + 0x14) != kChunkSize) + UInt32 chunkSize = Get32(p + 0x14); + if (chunkSize != kChunkSize && chunkSize != 0) return S_FALSE; - memcpy(h.Guid, p + 0x18, 16); - h.PartNumber = GetUi16(p + 0x28); - h.NumParts = GetUi16(p + 0x2A); + memcpy(Guid, p + 0x18, 16); + PartNumber = Get16(p + 0x28); + NumParts = Get16(p + 0x2A); int offset = 0x2C; - if (h.IsNewVersion()) + if (IsNewVersion()) { - h.NumImages = GetUi32(p + offset); + NumImages = Get32(p + offset); offset += 4; } - GetResource(p + offset, h.OffsetResource); - GetResource(p + offset + 0x18, h.XmlResource); - GetResource(p + offset + 0x30, h.MetadataResource); + GetResource(p + offset, OffsetResource); + GetResource(p + offset + 0x18, XmlResource); + GetResource(p + offset + 0x30, MetadataResource); /* - if (h.IsNewVersion()) + if (IsNewVersion()) { if (haderSize < 0xD0) return S_FALSE; - GetResource(p + offset + 0x4C, h.IntegrityResource); - h.BootIndex = GetUi32(p + 0x48); + IntegrityResource.Parse(p + offset + 0x4C); + BootIndex = Get32(p + 0x48); } */ return S_OK; } +HRESULT ReadHeader(IInStream *inStream, CHeader &h) +{ + const UInt32 kHeaderSizeMax = 0xD0; + Byte p[kHeaderSizeMax]; + RINOK(ReadStream_FALSE(inStream, p, kHeaderSizeMax)); + if (memcmp(p, kSignature, kSignatureSize) != 0) + return S_FALSE; + return h.Parse(p); +} + HRESULT ReadStreams(IInStream *inStream, const CHeader &h, CDatabase &db) { CByteBuffer offsetBuf; - RINOK(UnpackData(inStream, h.OffsetResource, offsetBuf, NULL)); + RINOK(UnpackData(inStream, h.OffsetResource, h.IsLzxMode(), offsetBuf, NULL)); for (size_t i = 0; i + kStreamInfoSize <= offsetBuf.GetCapacity(); i += kStreamInfoSize) { CStreamInfo s; @@ -357,7 +480,7 @@ HRESULT ReadStreams(IInStream *inStream, const CHeader &h, CDatabase &db) HRESULT OpenArchive(IInStream *inStream, const CHeader &h, CByteBuffer &xml, CDatabase &db) { - RINOK(UnpackData(inStream, h.XmlResource, xml, NULL)); + RINOK(UnpackData(inStream, h.XmlResource, h.IsLzxMode(), xml, NULL)); RINOK(ReadStreams(inStream, h, db)); bool needBootMetadata = !h.MetadataResource.IsEmpty(); @@ -372,13 +495,13 @@ HRESULT OpenArchive(IInStream *inStream, const CHeader &h, CByteBuffer &xml, CDa continue; Byte hash[kHashSize]; CByteBuffer metadata; - RINOK(UnpackData(inStream, si.Resource, metadata, hash)); + RINOK(UnpackData(inStream, si.Resource, h.IsLzxMode(), metadata, hash)); if (memcmp(hash, si.Hash, kHashSize) != 0) return S_FALSE; wchar_t sz[32]; ConvertUInt64ToString(imageIndex++, sz); UString s = sz; - s += WCHAR_PATH_SEPARATOR; + s += WCHAR_PATH_SEPARATOR; RINOK(ParseDir(metadata, metadata.GetCapacity(), s, db.Items)); if (needBootMetadata) if (h.MetadataResource.Offset == si.Resource.Offset) @@ -389,7 +512,7 @@ HRESULT OpenArchive(IInStream *inStream, const CHeader &h, CByteBuffer &xml, CDa if (needBootMetadata) { CByteBuffer metadata; - RINOK(UnpackData(inStream, h.MetadataResource, metadata, NULL)); + RINOK(UnpackData(inStream, h.MetadataResource, h.IsLzxMode(), metadata, NULL)); RINOK(ParseDir(metadata, metadata.GetCapacity(), L"0" WSTRING_PATH_SEPARATOR, db.Items)); } return S_OK; diff --git a/CPP/7zip/Archive/Wim/WimIn.h b/CPP/7zip/Archive/Wim/WimIn.h index 467b99ae..79e7bd01 100755 --- a/CPP/7zip/Archive/Wim/WimIn.h +++ b/CPP/7zip/Archive/Wim/WimIn.h @@ -12,6 +12,77 @@ namespace NArchive { namespace NWim { +namespace NXpress { + +class CBitStream +{ + CInBuffer m_Stream; + UInt32 m_Value; + unsigned m_BitPos; +public: + bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); } + void SetStream(ISequentialInStream *s) { m_Stream.SetStream(s); } + void ReleaseStream() { m_Stream.ReleaseStream(); } + + void Init() { m_Stream.Init(); m_BitPos = 0; } + // UInt64 GetProcessedSize() const { return m_Stream.GetProcessedSize() - m_BitPos / 8; } + Byte DirectReadByte() { return m_Stream.ReadByte(); } + + void Normalize() + { + if (m_BitPos < 16) + { + Byte b0 = m_Stream.ReadByte(); + Byte b1 = m_Stream.ReadByte(); + m_Value = (m_Value << 8) | b1; + m_Value = (m_Value << 8) | b0; + m_BitPos += 16; + } + } + + UInt32 GetValue(unsigned numBits) + { + Normalize(); + return (m_Value >> (m_BitPos - numBits)) & ((1 << numBits) - 1); + } + + void MovePos(unsigned numBits) { m_BitPos -= numBits; } + + UInt32 ReadBits(unsigned numBits) + { + UInt32 res = GetValue(numBits); + m_BitPos -= numBits; + return res; + } +}; + +const int kNumHuffmanBits = 16; +const UInt32 kMatchMinLen = 3; +const UInt32 kNumLenSlots = 16; +const UInt32 kNumPosSlots = 16; +const UInt32 kNumPosLenSlots = kNumPosSlots * kNumLenSlots; +const UInt32 kMainTableSize = 256 + kNumPosLenSlots; + +class CDecoder +{ + CBitStream m_InBitStream; + CLZOutWindow m_OutWindowStream; + NCompress::NHuffman::CDecoder<kNumHuffmanBits, kMainTableSize> m_MainDecoder; + + HRESULT CodeSpec(UInt32 size); + HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, UInt32 outSize); +public: + void ReleaseStreams() + { + m_OutWindowStream.ReleaseStream(); + m_InBitStream.ReleaseStream(); + } + HRESULT Flush() { return m_OutWindowStream.Flush(); } + HRESULT Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, UInt32 outSize); +}; + +} + namespace NResourceFlags { const Byte Compressed = 4; @@ -24,6 +95,8 @@ struct CResource UInt64 Offset; UInt64 UnpackSize; Byte Flags; + + void Parse(const Byte *p); bool IsCompressed() const { return (Flags & NResourceFlags::Compressed) != 0; } bool IsMetadata() const { return (Flags & NResourceFlags::kMetadata) != 0; } bool IsEmpty() const { return (UnpackSize == 0); } @@ -47,6 +120,7 @@ struct CHeader UInt16 NumParts; UInt32 NumImages; Byte Guid[16]; + CResource OffsetResource; CResource XmlResource; CResource MetadataResource; @@ -54,8 +128,11 @@ struct CHeader CResource IntegrityResource; UInt32 BootIndex; */ + + HRESULT Parse(const Byte *p); bool IsCompressed() const { return (Flags & NHeaderFlags::kCompression) != 0; } - bool IsSupported() const { return (!IsCompressed() || (Flags & NHeaderFlags::kLZX) != 0); } + bool IsSupported() const { return (!IsCompressed() || (Flags & NHeaderFlags::kLZX) != 0 || (Flags & NHeaderFlags::kXPRESS) != 0 ) ; } + bool IsLzxMode() const { return (Flags & NHeaderFlags::kLZX) != 0; } bool IsSpanned() const { return (!IsCompressed() || (Flags & NHeaderFlags::kSpanned) != 0); } bool IsNewVersion()const { return (Version > 0x010C00); } @@ -80,12 +157,12 @@ struct CStreamInfo struct CItem { UString Name; - UInt32 Attributes; + UInt32 Attrib; // UInt32 SecurityId; BYTE Hash[kHashSize]; - FILETIME CreationTime; - FILETIME LastAccessTime; - FILETIME LastWriteTime; + FILETIME CTime; + FILETIME ATime; + FILETIME MTime; // UInt32 ReparseTag; // UInt64 HardLink; // UInt16 NumStreams; @@ -93,9 +170,9 @@ struct CItem int StreamIndex; bool HasMetadata; CItem(): HasMetadata(true), StreamIndex(-1) {} - bool IsDirectory() const { return HasMetadata && ((Attributes & 0x10) != 0); } - bool HasStream() const - { + bool isDir() const { return HasMetadata && ((Attrib & 0x10) != 0); } + bool HasStream() const + { for (int i = 0; i < kHashSize; i++) if (Hash[i] != 0) return true; @@ -143,11 +220,13 @@ class CUnpacker NCompress::NLzx::CDecoder *lzxDecoderSpec; CMyComPtr<ICompressCoder> lzxDecoder; + NXpress::CDecoder xpressDecoder; + CByteBuffer sizesBuf; - HRESULT Unpack(IInStream *inStream, const CResource &res, + HRESULT Unpack(IInStream *inStream, const CResource &res, bool lzxMode, ISequentialOutStream *outStream, ICompressProgressInfo *progress); public: - HRESULT Unpack(IInStream *inStream, const CResource &res, + HRESULT Unpack(IInStream *inStream, const CResource &res, bool lzxMode, ISequentialOutStream *outStream, ICompressProgressInfo *progress, Byte *digest); }; diff --git a/CPP/7zip/Archive/XarHandler.cpp b/CPP/7zip/Archive/XarHandler.cpp new file mode 100755 index 00000000..1069d15d --- /dev/null +++ b/CPP/7zip/Archive/XarHandler.cpp @@ -0,0 +1,586 @@ +// XarHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#include "Common/ComTry.h" +#include "Common/MyXml.h" +#include "Common/StringToInt.h" +#include "Common/UTFConvert.h" + +#include "Windows/PropVariant.h" +#include "Windows/Time.h" + +#include "../Common/LimitedStreams.h" +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamObjects.h" +#include "../Common/StreamUtils.h" + +#include "../Compress/BZip2/BZip2Decoder.h" +#include "../Compress/Copy/CopyCoder.h" +#include "../Compress/Deflate/ZlibDecoder.h" + +#include "Common/OutStreamWithSha1.h" + +#define XAR_SHOW_RAW + +#define Get16(p) GetBe16(p) +#define Get32(p) GetBe32(p) +#define Get64(p) GetBe64(p) + +namespace NArchive { +namespace NXar { + +struct CFile +{ + AString Name; + AString Method; + UInt64 Size; + UInt64 PackSize; + UInt64 Offset; + + // UInt32 mode; + UInt64 CTime; + UInt64 MTime; + UInt64 ATime; + + bool IsDir; + bool HasData; + + bool Sha1IsDefined; + Byte Sha1[20]; + // bool packSha1IsDefined; + // Byte packSha1[20]; + + int Parent; + + CFile(): IsDir(false), HasData(false), Sha1IsDefined(false), + /* packSha1IsDefined(false), */ + Parent(-1), Size(0), PackSize(0), CTime(0), MTime(0), ATime(0) {} +}; + +class CHandler: + public IInArchive, + public CMyUnknownImp +{ + UInt64 _dataStartPos; + CMyComPtr<IInStream> _inStream; + AString _xml; + CObjectVector<CFile> _files; + + HRESULT Open2(IInStream *stream); + HRESULT Extract(IInStream *stream); +public: + MY_UNKNOWN_IMP1(IInArchive) + INTERFACE_IInArchive(;) +}; + +const UInt32 kXmlSizeMax = ((UInt32)1 << 30) - (1 << 14); + +STATPROPSTG kProps[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackSize, VT_UI8}, + { NULL, kpidMTime, VT_FILETIME}, + { NULL, kpidCTime, VT_FILETIME}, + { NULL, kpidATime, VT_FILETIME}, + { NULL, kpidMethod, VT_BSTR} +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO + +static bool ParseNumber(const char *s, int size, UInt32 &res) +{ + const char *end; + res = (UInt32)ConvertStringToUInt64(s, &end); + return (end - s == size); +} + +static bool ParseUInt64(const CXmlItem &item, const char *name, UInt64 &res) +{ + AString s = item.GetSubStringForTag(name); + const char *end; + res = ConvertStringToUInt64(s, &end); + return (end - (const char *)s == s.Length()); +} + +static UInt64 ParseTime(const CXmlItem &item, const char *name) +{ + AString s = item.GetSubStringForTag(name); + if (s.Length() < 20) + return 0; + const char *p = s; + if (p[ 4] != '-' || p[ 7] != '-' || p[10] != 'T' || + p[13] != ':' || p[16] != ':' || p[19] != 'Z') + return 0; + UInt32 year, month, day, hour, min, sec; + if (!ParseNumber(p, 4, year )) return 0; + if (!ParseNumber(p + 5, 2, month)) return 0; + if (!ParseNumber(p + 8, 2, day )) return 0; + if (!ParseNumber(p + 11, 2, hour )) return 0; + if (!ParseNumber(p + 14, 2, min )) return 0; + if (!ParseNumber(p + 17, 2, sec )) return 0; + + UInt64 numSecs; + if (!NWindows::NTime::GetSecondsSince1601(year, month, day, hour, min, sec, numSecs)) + return 0; + return numSecs * 10000000; +} + +static bool HexToByte(char c, Byte &res) +{ + if (c >= '0' && c <= '9') res = c - '0'; + else if (c >= 'A' && c <= 'F') res = c - 'A' + 10; + else if (c >= 'a' && c <= 'f') res = c - 'a' + 10; + else return false; + return true; +} + +#define METHOD_NAME_ZLIB "zlib" + +static bool ParseSha1(const CXmlItem &item, const char *name, Byte *digest) +{ + int index = item.FindSubTag(name); + if (index < 0) + return false; + const CXmlItem &checkItem = item.SubItems[index]; + AString style = checkItem.GetPropertyValue("style"); + if (style == "SHA1") + { + AString s = checkItem.GetSubString(); + if (s.Length() != 40) + return false; + for (int i = 0; i < s.Length(); i += 2) + { + Byte b0, b1; + if (!HexToByte(s[i], b0) || !HexToByte(s[i + 1], b1)) + return false; + digest[i / 2] = (b0 << 4) | b1; + } + return true; + } + return false; +} + +static bool AddItem(const CXmlItem &item, CObjectVector<CFile> &files, int parent) +{ + if (!item.IsTag) + return true; + if (item.Name == "file") + { + CFile file; + file.Parent = parent; + parent = files.Size(); + file.Name = item.GetSubStringForTag("name"); + AString type = item.GetSubStringForTag("type"); + if (type == "directory") + file.IsDir = true; + else if (type == "file") + file.IsDir = false; + else + return false; + + int dataIndex = item.FindSubTag("data"); + if (dataIndex >= 0 && !file.IsDir) + { + file.HasData = true; + const CXmlItem &dataItem = item.SubItems[dataIndex]; + if (!ParseUInt64(dataItem, "size", file.Size)) + return false; + if (!ParseUInt64(dataItem, "length", file.PackSize)) + return false; + if (!ParseUInt64(dataItem, "offset", file.Offset)) + return false; + file.Sha1IsDefined = ParseSha1(dataItem, "extracted-checksum", file.Sha1); + // file.packSha1IsDefined = ParseSha1(dataItem, "archived-checksum", file.packSha1); + int encodingIndex = dataItem.FindSubTag("encoding"); + const CXmlItem &encodingItem = dataItem.SubItems[encodingIndex]; + if (encodingItem.IsTag) + { + AString s = encodingItem.GetPropertyValue("style"); + if (s.Length() >= 0) + { + AString appl = "application/"; + if (s.Left(appl.Length()) == appl) + { + s = s.Mid(appl.Length()); + AString xx = "x-"; + if (s.Left(xx.Length()) == xx) + { + s = s.Mid(xx.Length()); + if (s == "gzip") + s = METHOD_NAME_ZLIB; + } + } + file.Method = s; + } + } + } + + file.CTime = ParseTime(item, "ctime"); + file.MTime = ParseTime(item, "mtime"); + file.ATime = ParseTime(item, "atime"); + files.Add(file); + } + for (int i = 0; i < item.SubItems.Size(); i++) + if (!AddItem(item.SubItems[i], files, parent)) + return false; + return true; +} + +HRESULT CHandler::Open2(IInStream *stream) +{ + UInt64 archiveStartPos; + RINOK(stream->Seek(0, STREAM_SEEK_SET, &archiveStartPos)); + + const UInt32 kHeaderSize = 0x1C; + Byte buf[kHeaderSize]; + RINOK(ReadStream_FALSE(stream, buf, kHeaderSize)); + + UInt32 size = Get16(buf + 4); + // UInt32 ver = Get16(buf + 6); // == 0 + if (Get32(buf) != 0x78617221 || size != kHeaderSize) + return S_FALSE; + + UInt64 packSize = Get64(buf + 8); + UInt64 unpackSize = Get64(buf + 0x10); + // UInt32 checkSumAlogo = Get32(buf + 0x18); + + if (unpackSize >= kXmlSizeMax) + return S_FALSE; + + _dataStartPos = archiveStartPos + kHeaderSize + packSize; + + char *ss = _xml.GetBuffer((int)unpackSize + 1); + + NCompress::NZlib::CDecoder *zlibCoderSpec = new NCompress::NZlib::CDecoder(); + CMyComPtr<ICompressCoder> zlibCoder = zlibCoderSpec; + + CLimitedSequentialInStream *inStreamLimSpec = new CLimitedSequentialInStream; + CMyComPtr<ISequentialInStream> inStreamLim(inStreamLimSpec); + inStreamLimSpec->SetStream(stream); + inStreamLimSpec->Init(packSize); + + CSequentialOutStreamImp2 *outStreamLimSpec = new CSequentialOutStreamImp2; + CMyComPtr<ISequentialOutStream> outStreamLim(outStreamLimSpec); + outStreamLimSpec->Init((Byte *)ss, (size_t)unpackSize); + + RINOK(zlibCoder->Code(inStreamLim, outStreamLim, NULL, NULL, NULL)); + + if (outStreamLimSpec->GetPos() != (size_t)unpackSize) + return S_FALSE; + + ss[(size_t)unpackSize] = 0; + _xml.ReleaseBuffer(); + + CXml xml; + if (!xml.Parse(_xml)) + return S_FALSE; + + if (!xml.Root.IsTagged("xar") || xml.Root.SubItems.Size() != 1) + return S_FALSE; + const CXmlItem &toc = xml.Root.SubItems[0]; + if (!toc.IsTagged("toc")) + return S_FALSE; + if (!AddItem(toc, _files, -1)) + return S_FALSE; + return S_OK; +} + +STDMETHODIMP CHandler::Open(IInStream *stream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback * /* openArchiveCallback */) +{ + COM_TRY_BEGIN + { + Close(); + if (Open2(stream) != S_OK) + return S_FALSE; + _inStream = stream; + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + _inStream.Release(); + _files.Clear(); + _xml.Empty(); + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _files.Size() + #ifdef XAR_SHOW_RAW + + 1 + #endif + ; + return S_OK; +} + +static void TimeToProp(UInt64 t, NWindows::NCOM::CPropVariant &prop) +{ + if (t != 0) + { + FILETIME ft; + ft.dwLowDateTime = (UInt32)(t); + ft.dwHighDateTime = (UInt32)(t >> 32); + prop = ft; + } +} + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + + #ifdef XAR_SHOW_RAW + if ((int)index == _files.Size()) + { + switch(propID) + { + case kpidPath: prop = L"[TOC].xml"; break; + case kpidSize: + case kpidPackSize: prop = (UInt64)_xml.Length(); break; + } + } + else + #endif + { + const CFile &item = _files[index]; + switch(propID) + { + case kpidMethod: + { + UString name; + if (ConvertUTF8ToUnicode(item.Method, name)) + prop = name; + break; + } + case kpidPath: + { + AString path; + int cur = index; + do + { + const CFile &item = _files[cur]; + AString s = item.Name; + if (s.IsEmpty()) + s = "unknown"; + if (path.IsEmpty()) + path = s; + else + path = s + CHAR_PATH_SEPARATOR + path; + cur = item.Parent; + } + while (cur >= 0); + + UString name; + if (ConvertUTF8ToUnicode(path, name)) + prop = name; + break; + } + + case kpidIsDir: prop = item.IsDir; break; + case kpidSize: if (!item.IsDir) prop = item.Size; break; + case kpidPackSize: if (!item.IsDir) prop = item.PackSize; break; + + case kpidMTime: TimeToProp(item.MTime, prop); break; + case kpidCTime: TimeToProp(item.CTime, prop); break; + case kpidATime: TimeToProp(item.ATime, prop); break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool testMode = (_aTestMode != 0); + bool allFilesMode = (numItems == UInt32(-1)); + if (allFilesMode) + numItems = _files.Size(); + if (numItems == 0) + return S_OK; + UInt64 totalSize = 0; + UInt32 i; + for (i = 0; i < numItems; i++) + { + int index = (int)(allFilesMode ? i : indices[i]); + #ifdef XAR_SHOW_RAW + if (index == _files.Size()) + totalSize += _xml.Length(); + else + #endif + totalSize += _files[index].Size; + } + extractCallback->SetTotal(totalSize); + + UInt64 currentPackTotal = 0; + UInt64 currentUnpTotal = 0; + UInt64 currentPackSize = 0; + UInt64 currentUnpSize = 0; + + const UInt32 kZeroBufSize = (1 << 14); + CByteBuffer zeroBuf; + zeroBuf.SetCapacity(kZeroBufSize); + memset(zeroBuf, 0, kZeroBufSize); + + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); + CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; + + NCompress::NZlib::CDecoder *zlibCoderSpec = new NCompress::NZlib::CDecoder(); + CMyComPtr<ICompressCoder> zlibCoder = zlibCoderSpec; + + NCompress::NBZip2::CDecoder *bzip2CoderSpec = new NCompress::NBZip2::CDecoder(); + CMyComPtr<ICompressCoder> bzip2Coder = bzip2CoderSpec; + + NCompress::NDeflate::NDecoder::CCOMCoder *deflateCoderSpec = new NCompress::NDeflate::NDecoder::CCOMCoder(); + CMyComPtr<ICompressCoder> deflateCoder = deflateCoderSpec; + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr<ICompressProgressInfo> progress = lps; + lps->Init(extractCallback, false); + + CLimitedSequentialInStream *inStreamSpec = new CLimitedSequentialInStream; + CMyComPtr<ISequentialInStream> inStream(inStreamSpec); + inStreamSpec->SetStream(_inStream); + + + CLimitedSequentialOutStream *outStreamLimSpec = new CLimitedSequentialOutStream; + CMyComPtr<ISequentialOutStream> outStream(outStreamLimSpec); + + COutStreamWithSha1 *outStreamSha1Spec = new COutStreamWithSha1; + { + CMyComPtr<ISequentialOutStream> outStreamSha1(outStreamSha1Spec); + outStreamLimSpec->SetStream(outStreamSha1); + } + + for (i = 0; i < numItems; i++, currentPackTotal += currentPackSize, currentUnpTotal += currentUnpSize) + { + lps->InSize = currentPackTotal; + lps->OutSize = currentUnpTotal; + currentPackSize = 0; + currentUnpSize = 0; + RINOK(lps->SetCur()); + CMyComPtr<ISequentialOutStream> realOutStream; + Int32 askMode = testMode ? + NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + Int32 index = allFilesMode ? i : indices[i]; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + + if (index < _files.Size()) + { + const CFile &item = _files[index]; + if (item.IsDir) + { + RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + continue; + } + } + + if (!testMode && (!realOutStream)) + continue; + RINOK(extractCallback->PrepareOperation(askMode)); + + outStreamSha1Spec->SetStream(realOutStream); + realOutStream.Release(); + + Int32 opRes = NArchive::NExtract::NOperationResult::kOK; + #ifdef XAR_SHOW_RAW + if (index == _files.Size()) + { + outStreamSha1Spec->Init(false); + outStreamLimSpec->Init(_xml.Length()); + RINOK(WriteStream(outStream, (const char *)_xml, _xml.Length())); + currentPackSize = currentUnpSize = _xml.Length(); + } + else + #endif + { + const CFile &item = _files[index]; + if (item.HasData) + { + currentPackSize = item.PackSize; + currentUnpSize = item.Size; + + RINOK(_inStream->Seek(_dataStartPos + item.Offset, STREAM_SEEK_SET, NULL)); + inStreamSpec->Init(item.PackSize); + outStreamSha1Spec->Init(item.Sha1IsDefined); + outStreamLimSpec->Init(item.Size); + HRESULT res = S_OK; + + ICompressCoder *coder = NULL; + if (item.Method == "octet-stream") + if (item.PackSize == item.Size) + coder = copyCoder; + else + opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + else if (item.Method == METHOD_NAME_ZLIB) + coder = zlibCoder; + else if (item.Method == "bzip2") + coder = bzip2Coder; + else + opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + + if (coder) + res = coder->Code(inStream, outStream, NULL, NULL, progress); + + if (res != S_OK) + { + if (!outStreamLimSpec->IsFinishedOK()) + opRes = NArchive::NExtract::NOperationResult::kDataError; + else if (res != S_FALSE) + return res; + if (opRes == NArchive::NExtract::NOperationResult::kOK) + opRes = NArchive::NExtract::NOperationResult::kDataError; + } + + if (opRes == NArchive::NExtract::NOperationResult::kOK) + { + if (outStreamLimSpec->IsFinishedOK() && + outStreamSha1Spec->GetSize() == item.Size) + { + if (!outStreamLimSpec->IsFinishedOK()) + { + opRes = NArchive::NExtract::NOperationResult::kDataError; + } + else if (item.Sha1IsDefined) + { + Byte digest[NCrypto::NSha1::kDigestSize]; + outStreamSha1Spec->Final(digest); + if (memcmp(digest, item.Sha1, NCrypto::NSha1::kDigestSize) != 0) + opRes = NArchive::NExtract::NOperationResult::kCRCError; + } + } + else + opRes = NArchive::NExtract::NOperationResult::kDataError; + } + } + } + outStreamSha1Spec->ReleaseStream(); + RINOK(extractCallback->SetOperationResult(opRes)); + } + return S_OK; + COM_TRY_END +} + +static IInArchive *CreateArc() { return new NArchive::NXar::CHandler; } + +static CArcInfo g_ArcInfo = + { L"Xar", L"xar", 0, 0xE1, { 'x', 'a', 'r', '!', 0, 0x1C }, 6, false, CreateArc, 0 }; + +REGISTER_ARC(Xar) + +}} diff --git a/CPP/7zip/Archive/Z/StdAfx.cpp b/CPP/7zip/Archive/Z/StdAfx.cpp deleted file mode 100755 index d0feea85..00000000 --- a/CPP/7zip/Archive/Z/StdAfx.cpp +++ /dev/null @@ -1,3 +0,0 @@ -// StdAfx.cpp - -#include "StdAfx.h" diff --git a/CPP/7zip/Archive/Z/StdAfx.h b/CPP/7zip/Archive/Z/StdAfx.h deleted file mode 100755 index e7fb6986..00000000 --- a/CPP/7zip/Archive/Z/StdAfx.h +++ /dev/null @@ -1,8 +0,0 @@ -// StdAfx.h - -#ifndef __STDAFX_H -#define __STDAFX_H - -#include "../../../Common/MyWindows.h" - -#endif diff --git a/CPP/7zip/Archive/Z/ZHandler.h b/CPP/7zip/Archive/Z/ZHandler.h deleted file mode 100755 index e8b3b8c5..00000000 --- a/CPP/7zip/Archive/Z/ZHandler.h +++ /dev/null @@ -1,29 +0,0 @@ -// 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_IMP1(IInArchive) - INTERFACE_IInArchive(;) - -private: - CMyComPtr<IInStream> _stream; - UInt64 _streamStartPosition; - UInt64 _packSize; - Byte _properties; -}; - -}} - -#endif diff --git a/CPP/7zip/Archive/Z/ZRegister.cpp b/CPP/7zip/Archive/Z/ZRegister.cpp deleted file mode 100755 index 288dc6ca..00000000 --- a/CPP/7zip/Archive/Z/ZRegister.cpp +++ /dev/null @@ -1,13 +0,0 @@ -// ZRegister.cpp - -#include "StdAfx.h" - -#include "../../Common/RegisterArc.h" - -#include "ZHandler.h" -static IInArchive *CreateArc() { return new NArchive::NZ::CHandler; } - -static CArcInfo g_ArcInfo = - { L"Z", L"z taz", L"* .tar", 5, { 0x1F, 0x9D }, 2, false, CreateArc, 0 }; - -REGISTER_ARC(Z) diff --git a/CPP/7zip/Archive/Z/ZHandler.cpp b/CPP/7zip/Archive/ZHandler.cpp index 81289050..bc006eda 100755 --- a/CPP/7zip/Archive/Z/ZHandler.cpp +++ b/CPP/7zip/Archive/ZHandler.cpp @@ -2,26 +2,46 @@ #include "StdAfx.h" -#include "ZHandler.h" +#include "Common/ComTry.h" -#include "Common/Defs.h" +#include "Windows/PropVariant.h" -#include "../../Common/ProgressUtils.h" -#include "../../Compress/Z/ZDecoder.h" -#include "../../Common/StreamUtils.h" +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" -#include "Windows/PropVariant.h" -#include "Windows/Defs.h" -#include "Common/ComTry.h" +#include "../Compress/Z/ZDecoder.h" -#include "../Common/DummyOutStream.h" +#include "Common/DummyOutStream.h" namespace NArchive { namespace NZ { -STATPROPSTG kProps[] = +class CHandler: + public IInArchive, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP1(IInArchive) + INTERFACE_IInArchive(;) + +private: + CMyComPtr<IInStream> _stream; + UInt64 _streamStartPosition; + UInt64 _packSize; + Byte _properties; +}; + +static IInArchive *CreateArc() { return new CHandler; } + +static CArcInfo g_ArcInfo = + { L"Z", L"z taz", L"* .tar", 5, { 0x1F, 0x9D }, 2, false, CreateArc, 0 }; + +REGISTER_ARC(Z) + +STATPROPSTG kProps[] = { - { NULL, kpidPackedSize, VT_UI8}, + { NULL, kpidPackSize, VT_UI8} }; IMP_IInArchive_Props @@ -38,7 +58,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIA NWindows::NCOM::CPropVariant prop; switch(propID) { - case kpidPackedSize: prop = _packSize; break; + case kpidPackSize: prop = _packSize; break; } prop.Detach(value); return S_OK; @@ -46,12 +66,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIA static const int kSignatureSize = 3; -STDMETHODIMP CHandler::Open(IInStream *stream, +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]; @@ -66,10 +85,6 @@ STDMETHODIMP CHandler::Open(IInStream *stream, _stream = stream; } - catch(...) - { - return S_FALSE; - } return S_OK; COM_TRY_END } @@ -105,7 +120,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(extractCallback->SetCompleted(¤tTotalPacked)); CMyComPtr<ISequentialOutStream> realOutStream; - Int32 askMode = testMode ? + Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; @@ -124,7 +139,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, CLocalProgress *lps = new CLocalProgress; CMyComPtr<ICompressProgressInfo> progress = lps; - lps->Init(extractCallback, false); + lps->Init(extractCallback, true); RINOK(_stream->Seek(_streamStartPosition + kSignatureSize, STREAM_SEEK_SET, NULL)); diff --git a/CPP/7zip/Archive/Zip/StdAfx.cpp b/CPP/7zip/Archive/Zip/StdAfx.cpp deleted file mode 100755 index d0feea85..00000000 --- a/CPP/7zip/Archive/Zip/StdAfx.cpp +++ /dev/null @@ -1,3 +0,0 @@ -// StdAfx.cpp - -#include "StdAfx.h" diff --git a/CPP/7zip/Archive/Zip/ZipAddCommon.cpp b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp index 0f76b04a..ca16ef97 100755 --- a/CPP/7zip/Archive/Zip/ZipAddCommon.cpp +++ b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp @@ -2,8 +2,8 @@ #include "StdAfx.h" -extern "C" -{ +extern "C" +{ #include "../../../../C/7zCrc.h" } @@ -49,7 +49,7 @@ static HRESULT GetStreamCRC(ISequentialInStream *inStream, UInt32 &resultCRC) HRESULT CAddCommon::Compress( DECL_EXTERNAL_CODECS_LOC_VARS - ISequentialInStream *inStream, IOutStream *outStream, + ISequentialInStream *inStream, IOutStream *outStream, ICompressProgressInfo *progress, CCompressingResult &operationResult) { CSequentialInStreamWithCRC *inSecCrcStreamSpec = 0; @@ -57,7 +57,7 @@ HRESULT CAddCommon::Compress( CMyComPtr<ISequentialInStream> inCrcStream; { CMyComPtr<IInStream> inStream2; - // we don't support stdin, since stream from stdin can require 64-bit size header + // we don't support stdin, since stream from stdin can require 64-bit size header RINOK(inStream->QueryInterface(IID_IInStream, (void **)&inStream2)); if (inStream2) { @@ -149,10 +149,10 @@ HRESULT CAddCommon::Compress( switch(method) { case NFileHeader::NCompressionMethod::kBZip2: - methodId = kMethodId_BZip2; + methodId = kMethodId_BZip2; break; default: - methodId = kMethodId_ZipBase + method; + methodId = kMethodId_ZipBase + method; break; } RINOK(CreateCoder( @@ -164,14 +164,14 @@ HRESULT CAddCommon::Compress( if (method == NFileHeader::NCompressionMethod::kDeflated || method == NFileHeader::NCompressionMethod::kDeflated64) { - NWindows::NCOM::CPropVariant properties[] = + NWindows::NCOM::CPropVariant properties[] = { - _options.Algo, - _options.NumPasses, + _options.Algo, + _options.NumPasses, _options.NumFastBytes, _options.NumMatchFinderCycles }; - PROPID propIDs[] = + PROPID propIDs[] = { NCoderPropID::kAlgorithm, NCoderPropID::kNumPasses, @@ -187,18 +187,18 @@ HRESULT CAddCommon::Compress( { RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, numProps)); } - } + } else if (method == NFileHeader::NCompressionMethod::kBZip2) { - NWindows::NCOM::CPropVariant properties[] = + NWindows::NCOM::CPropVariant properties[] = { - _options.DicSize, + _options.DicSize, _options.NumPasses #ifdef COMPRESS_MT , _options.NumThreads #endif }; - PROPID propIDs[] = + PROPID propIDs[] = { NCoderPropID::kDictionarySize, NCoderPropID::kNumPasses @@ -240,11 +240,11 @@ HRESULT CAddCommon::Compress( if (_options.PasswordIsDefined) { - if (operationResult.PackSize < operationResult.UnpackSize + + if (operationResult.PackSize < operationResult.UnpackSize + (_options.IsAesMode ? _filterAesSpec->GetHeaderSize() : NCrypto::NZip::kHeaderSize)) break; } - else if (operationResult.PackSize < operationResult.UnpackSize) + else if (operationResult.PackSize < operationResult.UnpackSize) break; } if (_options.IsAesMode) diff --git a/CPP/7zip/Archive/Zip/ZipAddCommon.h b/CPP/7zip/Archive/Zip/ZipAddCommon.h index 7bce0cbe..6c766037 100755 --- a/CPP/7zip/Archive/Zip/ZipAddCommon.h +++ b/CPP/7zip/Archive/Zip/ZipAddCommon.h @@ -48,7 +48,7 @@ public: CAddCommon(const CCompressionMethodMode &options); HRESULT Compress( DECL_EXTERNAL_CODECS_LOC_VARS - ISequentialInStream *inStream, IOutStream *outStream, + ISequentialInStream *inStream, IOutStream *outStream, ICompressProgressInfo *progress, CCompressingResult &operationResult); }; diff --git a/CPP/7zip/Archive/Zip/ZipCompressionMode.h b/CPP/7zip/Archive/Zip/ZipCompressionMode.h index 37f22f77..ae29a5a4 100755 --- a/CPP/7zip/Archive/Zip/ZipCompressionMode.h +++ b/CPP/7zip/Archive/Zip/ZipCompressionMode.h @@ -26,12 +26,12 @@ struct CCompressionMethodMode bool IsAesMode; Byte AesKeyMode; - CCompressionMethodMode(): - NumMatchFinderCyclesDefined(false), - PasswordIsDefined(false), - IsAesMode(false), - AesKeyMode(3) - {} + CCompressionMethodMode(): + NumMatchFinderCyclesDefined(false), + PasswordIsDefined(false), + IsAesMode(false), + AesKeyMode(3) + {} }; }} diff --git a/CPP/7zip/Archive/Zip/ZipHandler.cpp b/CPP/7zip/Archive/Zip/ZipHandler.cpp index 7d478a36..aba36b3b 100755 --- a/CPP/7zip/Archive/Zip/ZipHandler.cpp +++ b/CPP/7zip/Archive/Zip/ZipHandler.cpp @@ -36,7 +36,6 @@ #endif using namespace NWindows; -using namespace NTime; namespace NArchive { namespace NZip { @@ -45,7 +44,7 @@ namespace NZip { static const CMethodId kMethodId_ZipBase = 0x040100; static const CMethodId kMethodId_BZip2 = 0x040202; -const wchar_t *kHostOS[] = +const wchar_t *kHostOS[] = { L"FAT", L"AMIGA", @@ -74,17 +73,17 @@ static const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]); static const wchar_t *kUnknownOS = L"Unknown"; -STATPROPSTG kProps[] = +STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, - { NULL, kpidIsFolder, VT_BOOL}, + { NULL, kpidIsDir, VT_BOOL}, { NULL, kpidSize, VT_UI8}, - { NULL, kpidPackedSize, VT_UI8}, - { NULL, kpidLastWriteTime, VT_FILETIME}, - { NULL, kpidCreationTime, VT_FILETIME}, - { NULL, kpidLastAccessTime, VT_FILETIME}, + { NULL, kpidPackSize, VT_UI8}, + { NULL, kpidMTime, VT_FILETIME}, + { NULL, kpidCTime, VT_FILETIME}, + { NULL, kpidATime, VT_FILETIME}, - { NULL, kpidAttributes, VT_UI4}, + { NULL, kpidAttrib, VT_UI4}, { NULL, kpidEncrypted, VT_BOOL}, { NULL, kpidComment, VT_BSTR}, @@ -97,7 +96,7 @@ STATPROPSTG kProps[] = // { NULL, kpidUnpackVer, VT_UI1}, }; -const wchar_t *kMethods[] = +const wchar_t *kMethods[] = { L"Store", L"Shrink", @@ -116,6 +115,7 @@ const wchar_t *kMethods[] = const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]); // const wchar_t *kUnknownMethod = L"Unknown"; +const wchar_t *kWavPackMethod = L"WavPack"; const wchar_t *kPPMdMethod = L"PPMd"; const wchar_t *kAESMethod = L"AES"; const wchar_t *kZipCryptoMethod = L"ZipCrypto"; @@ -127,7 +127,7 @@ struct CStrongCryptoPair const wchar_t *Name; }; -CStrongCryptoPair g_StrongCryptoPairs[] = +CStrongCryptoPair g_StrongCryptoPairs[] = { { NStrongCryptoFlags::kDES, L"DES" }, { NStrongCryptoFlags::kRC2old, L"RC2a" }, @@ -142,13 +142,13 @@ CStrongCryptoPair g_StrongCryptoPairs[] = { NStrongCryptoFlags::kRC4, L"RC4" } }; -STATPROPSTG kArcProps[] = +STATPROPSTG kArcProps[] = { + { NULL, kpidBit64, VT_BOOL}, { NULL, kpidComment, VT_BSTR} }; -CHandler::CHandler(): - m_ArchiveIsOpen(false) +CHandler::CHandler() { InitMethodProperties(); } @@ -176,6 +176,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) NWindows::NCOM::CPropVariant prop; switch(propID) { + case kpidBit64: if (m_Archive.IsZip64) prop = m_Archive.IsZip64; break; case kpidComment: prop = MultiByteToUnicodeString(BytesToString(m_Archive.m_ArchiveInfo.Comment), CP_ACP); break; @@ -198,44 +199,38 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val const CItemEx &item = m_Items[index]; switch(propID) { - case kpidPath: - prop = NItemName::GetOSName2(item.GetUnicodeString(item.Name)); - break; - case kpidIsFolder: - prop = item.IsDirectory(); - break; - case kpidSize: - prop = item.UnPackSize; - break; - case kpidPackedSize: - prop = item.PackSize; - break; + case kpidPath: prop = NItemName::GetOSName2(item.GetUnicodeString(item.Name)); break; + case kpidIsDir: prop = item.IsDir(); break; + case kpidSize: prop = item.UnPackSize; break; + case kpidPackSize: prop = item.PackSize; break; case kpidTimeType: + { FILETIME utcFileTime; if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kTagTime, utcFileTime)) prop = (UInt32)NFileTimeType::kWindows; break; - case kpidCreationTime: + } + case kpidCTime: { FILETIME ft; if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kCTime, ft)) prop = ft; break; } - case kpidLastAccessTime: + case kpidATime: { FILETIME ft; if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kATime, ft)) prop = ft; break; } - case kpidLastWriteTime: + case kpidMTime: { FILETIME utcFileTime; if (!item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, utcFileTime)) { FILETIME localFileTime; - if (DosTimeToFileTime(item.Time, localFileTime)) + if (NTime::DosTimeToFileTime(item.Time, localFileTime)) { if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime)) utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; @@ -246,21 +241,10 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val prop = utcFileTime; break; } - case kpidAttributes: - prop = item.GetWinAttributes(); - break; - case kpidEncrypted: - prop = item.IsEncrypted(); - break; - case kpidComment: - { - prop = item.GetUnicodeString(BytesToString(item.Comment)); - break; - } - case kpidCRC: - if (item.IsThereCrc()) - prop = item.FileCRC; - break; + case kpidAttrib: prop = item.GetWinAttributes(); break; + case kpidEncrypted: prop = item.IsEncrypted(); break; + case kpidComment: prop = item.GetUnicodeString(BytesToString(item.Comment)); break; + case kpidCRC: if (item.IsThereCrc()) prop = item.FileCRC; break; case kpidMethod: { UInt16 methodId = item.CompressionMethod; @@ -310,8 +294,10 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val } if (methodId < kNumMethods) method += kMethods[methodId]; - else if (methodId == NFileHeader::NCompressionMethod::kWzPPMd) + else if (methodId == NFileHeader::NCompressionMethod::kPPMd) method += kPPMdMethod; + else if (methodId == NFileHeader::NCompressionMethod::kWavPack) + method += kWavPackMethod; else { wchar_t s[32]; @@ -331,55 +317,50 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val COM_TRY_END } -class CPropgressImp: public CProgressVirt +class CProgressImp: public CProgressVirt { - CMyComPtr<IArchiveOpenCallback> m_OpenArchiveCallback; + CMyComPtr<IArchiveOpenCallback> _callback; public: - STDMETHOD(SetCompleted)(const UInt64 *numFiles); - void Init(IArchiveOpenCallback *openArchiveCallback) - { m_OpenArchiveCallback = openArchiveCallback; } + STDMETHOD(SetTotal)(UInt64 numFiles); + STDMETHOD(SetCompleted)(UInt64 numFiles); + CProgressImp(IArchiveOpenCallback *callback): _callback(callback) {} }; -STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles) +STDMETHODIMP CProgressImp::SetTotal(UInt64 numFiles) +{ + if (_callback) + return _callback->SetTotal(&numFiles, NULL); + return S_OK; +} + +STDMETHODIMP CProgressImp::SetCompleted(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) +STDMETHODIMP CHandler::Open(IInStream *inStream, + const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback) { COM_TRY_BEGIN - // try + try { - if(!m_Archive.Open(inStream, maxCheckStartPosition)) - return S_FALSE; - m_ArchiveIsOpen = true; - m_Items.Clear(); - if (openArchiveCallback != NULL) - { - RINOK(openArchiveCallback->SetTotal(NULL, NULL)); - } - CPropgressImp propgressImp; - propgressImp.Init(openArchiveCallback); - RINOK(m_Archive.ReadHeaders(m_Items, &propgressImp)); - } - /* - catch(...) - { - return S_FALSE; + Close(); + RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(m_Archive.Open(inStream, maxCheckStartPosition)); + CProgressImp progressImp(callback); + return m_Archive.ReadHeaders(m_Items, &progressImp); } - */ + catch(const CInArchiveException &) { Close(); return S_FALSE; } + catch(...) { Close(); throw; } COM_TRY_END - return S_OK; } STDMETHODIMP CHandler::Close() { m_Items.Clear(); m_Archive.Close(); - m_ArchiveIsOpen = false; return S_OK; } @@ -412,17 +393,17 @@ public: HRESULT Decode( DECL_EXTERNAL_CODECS_LOC_VARS - CInArchive &archive, const CItemEx &item, - ISequentialOutStream *realOutStream, - IArchiveExtractCallback *extractCallback, + CInArchive &archive, const CItemEx &item, + ISequentialOutStream *realOutStream, + IArchiveExtractCallback *extractCallback, ICompressProgressInfo *compressProgress, UInt32 numThreads, Int32 &res); }; HRESULT CZipDecoder::Decode( DECL_EXTERNAL_CODECS_LOC_VARS - CInArchive &archive, const CItemEx &item, - ISequentialOutStream *realOutStream, + CInArchive &archive, const CItemEx &item, + ISequentialOutStream *realOutStream, IArchiveExtractCallback *extractCallback, ICompressProgressInfo *compressProgress, UInt32 numThreads, Int32 &res) @@ -534,7 +515,7 @@ HRESULT CZipDecoder::Decode( CMyComBSTR password; RINOK(getTextPassword->CryptoGetTextPassword(&password)); AString charPassword; - if (aesMode + if (aesMode #ifdef ZIP_STRONG_SUPORT || pkAesMode #endif @@ -662,7 +643,7 @@ HRESULT CZipDecoder::Decode( } RINOK(filterStreamSpec->SetInStream(inStream)); inStreamReleaser.FilterCoder = filterStreamSpec; - inStreamNew = filterStream; + inStreamNew = filterStream; if (aesMode) { @@ -671,7 +652,7 @@ HRESULT CZipDecoder::Decode( } } else - inStreamNew = inStream; + inStreamNew = inStream; result = coder->Code(inStreamNew, outStream, NULL, &item.UnPackSize, compressProgress); if (result == S_FALSE) return S_OK; @@ -688,7 +669,7 @@ HRESULT CZipDecoder::Decode( authOk = false; } - res = ((crcOK && authOk) ? + res = ((crcOK && authOk) ? NArchive::NExtract::NOperationResult::kOK : NArchive::NExtract::NOperationResult::kCRCError); return S_OK; @@ -734,7 +715,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(lps->SetCur()); CMyComPtr<ISequentialOutStream> realOutStream; - Int32 askMode = testMode ? + Int32 askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract; Int32 index = allFilesMode ? i : indices[i]; @@ -747,7 +728,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, HRESULT res = m_Archive.ReadLocalItemAfterCdItem(item); if (res == S_FALSE) { - if (item.IsDirectory() || realOutStream || testMode) + if (item.IsDir() || realOutStream || testMode) { RINOK(extractCallback->PrepareOperation(askMode)); realOutStream.Release(); @@ -758,7 +739,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(res); } - if (item.IsDirectory() || item.IgnoreItem()) + if (item.IsDir() || item.IgnoreItem()) { // if (!testMode) { @@ -772,7 +753,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, currentItemUnPacked = item.UnPackSize; currentItemPacked = item.PackSize; - if (!testMode && (!realOutStream)) + if (!testMode && (!realOutStream)) continue; RINOK(extractCallback->PrepareOperation(askMode)); @@ -780,7 +761,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, Int32 res; RINOK(myDecoder.Decode( EXTERNAL_CODECS_VARS - m_Archive, item, realOutStream, extractCallback, + m_Archive, item, realOutStream, extractCallback, progress, _numThreads, res)); realOutStream.Release(); diff --git a/CPP/7zip/Archive/Zip/ZipHandler.h b/CPP/7zip/Archive/Zip/ZipHandler.h index c8fa392c..09179111 100755 --- a/CPP/7zip/Archive/Zip/ZipHandler.h +++ b/CPP/7zip/Archive/Zip/ZipHandler.h @@ -19,7 +19,7 @@ namespace NArchive { namespace NZip { -class CHandler: +class CHandler: public IInArchive, public IOutArchive, public ISetProperties, @@ -45,7 +45,6 @@ public: private: CObjectVector<CItemEx> m_Items; CInArchive m_Archive; - bool m_ArchiveIsOpen; int m_Level; int m_MainMethod; @@ -73,10 +72,10 @@ private: { m_Level = -1; m_MainMethod = -1; - m_Algo = - m_DicSize = - m_NumPasses = - m_NumFastBytes = + m_Algo = + m_DicSize = + m_NumPasses = + m_NumFastBytes = m_NumMatchFinderCycles = 0xFFFFFFFF; m_NumMatchFinderCyclesDefined = false; m_IsAesMode = false; diff --git a/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp index 2846c988..c493b0c9 100755 --- a/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp +++ b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp @@ -83,7 +83,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt { COM_TRY_BEGIN2 CObjectVector<CUpdateItem> updateItems; - for(UInt32 i = 0; i < numItems; i++) + for (UInt32 i = 0; i < numItems; i++) { CUpdateItem ui; Int32 newData; @@ -91,10 +91,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt UInt32 indexInArchive; if (!callback) return E_FAIL; - RINOK(callback->GetUpdateItemInfo(i, - &newData, // 1 - compress 0 - copy - &newProperties, - &indexInArchive)); + RINOK(callback->GetUpdateItemInfo(i, &newData, &newProperties, &indexInArchive)); ui.NewProperties = IntToBool(newProperties); ui.NewData = IntToBool(newData); ui.IndexInArchive = indexInArchive; @@ -103,10 +100,9 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt if (IntToBool(newProperties)) { UString name; - bool isDirectoryStatusDefined; { NCOM::CPropVariant prop; - RINOK(callback->GetProperty(i, kpidAttributes, &prop)); + RINOK(callback->GetProperty(i, kpidAttrib, &prop)); if (prop.vt == VT_EMPTY) ui.Attributes = 0; else if (prop.vt != VT_UI4) @@ -127,16 +123,13 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt } { NCOM::CPropVariant prop; - RINOK(callback->GetProperty(i, kpidIsFolder, &prop)); + RINOK(callback->GetProperty(i, kpidIsDir, &prop)); if (prop.vt == VT_EMPTY) - isDirectoryStatusDefined = false; + ui.IsDir = false; else if (prop.vt != VT_BOOL) return E_INVALIDARG; else - { - ui.IsDirectory = (prop.boolVal != VARIANT_FALSE); - isDirectoryStatusDefined = true; - } + ui.IsDir = (prop.boolVal != VARIANT_FALSE); } { @@ -147,9 +140,9 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt else ui.NtfsTimeIsDefined = m_WriteNtfsTimeExtra; } - RINOK(GetTime(callback, i, kpidLastWriteTime, ui.NtfsMTime)); - RINOK(GetTime(callback, i, kpidLastAccessTime, ui.NtfsATime)); - RINOK(GetTime(callback, i, kpidCreationTime, ui.NtfsCTime)); + RINOK(GetTime(callback, i, kpidMTime, ui.NtfsMTime)); + RINOK(GetTime(callback, i, kpidATime, ui.NtfsATime)); + RINOK(GetTime(callback, i, kpidCTime, ui.NtfsCTime)); { FILETIME localFileTime = { 0, 0 }; @@ -160,17 +153,14 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt FileTimeToDosTime(localFileTime, ui.Time); } - if (!isDirectoryStatusDefined) - ui.IsDirectory = ((ui.Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0); - name = NItemName::MakeLegalName(name); - bool needSlash = ui.IsDirectory; + bool needSlash = ui.IsDir; const wchar_t kSlash = L'/'; if (!name.IsEmpty()) { if (name[name.Length() - 1] == kSlash) { - if (!ui.IsDirectory) + if (!ui.IsDir) return E_INVALIDARG; needSlash = false; } @@ -205,12 +195,12 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt ui.IndexInClient = i; /* - if(existInArchive) + if (existInArchive) { const CItemEx &itemInfo = m_Items[indexInArchive]; // ui.Commented = itemInfo.IsCommented(); ui.Commented = false; - if(ui.Commented) + if (ui.Commented) { ui.CommentRange.Position = itemInfo.GetCommentPosition(); ui.CommentRange.Size = itemInfo.CommentSize; @@ -280,7 +270,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt options.MethodSequence.Add(mainMethod); if (mainMethod != NFileHeader::NCompressionMethod::kStored) options.MethodSequence.Add(NFileHeader::NCompressionMethod::kStored); - bool isDeflate = (mainMethod == NFileHeader::NCompressionMethod::kDeflated) || + bool isDeflate = (mainMethod == NFileHeader::NCompressionMethod::kDeflated) || (mainMethod == NFileHeader::NCompressionMethod::kDeflated64); bool isBZip2 = (mainMethod == NFileHeader::NCompressionMethod::kBZip2); options.NumPasses = m_NumPasses; @@ -295,34 +285,34 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt if (isDeflate) { if (options.NumPasses == 0xFFFFFFFF) - options.NumPasses = (level >= 9 ? kDeflateNumPassesX9 : - (level >= 7 ? kDeflateNumPassesX7 : + options.NumPasses = (level >= 9 ? kDeflateNumPassesX9 : + (level >= 7 ? kDeflateNumPassesX7 : kDeflateNumPassesX1)); if (options.NumFastBytes == 0xFFFFFFFF) - options.NumFastBytes = (level >= 9 ? kNumFastBytesX9 : - (level >= 7 ? kNumFastBytesX7 : + options.NumFastBytes = (level >= 9 ? kNumFastBytesX9 : + (level >= 7 ? kNumFastBytesX7 : kNumFastBytesX1)); if (options.Algo == 0xFFFFFFFF) - options.Algo = - (level >= 5 ? kDeflateAlgoX5 : - kDeflateAlgoX1); + options.Algo = + (level >= 5 ? kDeflateAlgoX5 : + kDeflateAlgoX1); } if (isBZip2) { if (options.NumPasses == 0xFFFFFFFF) - options.NumPasses = (level >= 9 ? kBZip2NumPassesX9 : - (level >= 7 ? kBZip2NumPassesX7 : + options.NumPasses = (level >= 9 ? kBZip2NumPassesX9 : + (level >= 7 ? kBZip2NumPassesX7 : kBZip2NumPassesX1)); if (options.DicSize == 0xFFFFFFFF) - options.DicSize = (level >= 5 ? kBZip2DicSizeX5 : - (level >= 3 ? kBZip2DicSizeX3 : + options.DicSize = (level >= 5 ? kBZip2DicSizeX5 : + (level >= 3 ? kBZip2DicSizeX3 : kBZip2DicSizeX1)); } return Update( EXTERNAL_CODECS_VARS - m_Items, updateItems, outStream, - m_ArchiveIsOpen ? &m_Archive : NULL, &options, callback); + m_Items, updateItems, outStream, + m_Archive.IsOpen() ? &m_Archive : NULL, &options, callback); COM_TRY_END2 } @@ -363,7 +353,7 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v m_MainMethod = NFileHeader::NCompressionMethod::kDeflated64; else if (valueString == L"BZIP2") m_MainMethod = NFileHeader::NCompressionMethod::kBZip2; - else + else return E_INVALIDARG; } else if (prop.vt == VT_UI4) @@ -463,10 +453,10 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v m_ForseLocal = false; return S_OK; } - else + else return E_INVALIDARG; } return S_OK; -} +} }} diff --git a/CPP/7zip/Archive/Zip/ZipHeader.cpp b/CPP/7zip/Archive/Zip/ZipHeader.cpp index fd8856bb..582187b5 100755 --- a/CPP/7zip/Archive/Zip/ZipHeader.cpp +++ b/CPP/7zip/Archive/Zip/ZipHeader.cpp @@ -19,9 +19,9 @@ namespace NSignature class CMarkersInitializer { public: - CMarkersInitializer() - { - kLocalFileHeader--; + CMarkersInitializer() + { + kLocalFileHeader--; kDataDescriptor--; kCentralFileHeader--; kEndOfCentralDir--; diff --git a/CPP/7zip/Archive/Zip/ZipHeader.h b/CPP/7zip/Archive/Zip/ZipHeader.h index 0c978a7c..3af72369 100755 --- a/CPP/7zip/Archive/Zip/ZipHeader.h +++ b/CPP/7zip/Archive/Zip/ZipHeader.h @@ -55,7 +55,7 @@ namespace NFileHeader namespace NCompressionMethod { enum EType - { + { kStored = 0, kShrunk = 1, kReduced1 = 2, @@ -64,12 +64,13 @@ namespace NFileHeader kReduced4 = 5, kImploded = 6, kReservedTokenizing = 7, // reserved for tokenizing - kDeflated = 8, + kDeflated = 8, kDeflated64 = 9, kPKImploding = 10, kBZip2 = 12, - kWzPPMd = 0x62, + kWavPack = 0x61, + kPPMd = 0x62, kWzAES = 0x63 }; const int kNumCompressionMethods = 11; @@ -83,8 +84,8 @@ namespace NFileHeader namespace NExtraID { - enum - { + enum + { kZip64 = 0x01, kNTFS = 0x0A, kStrongEncrypt = 0x17, @@ -166,7 +167,7 @@ namespace NFileHeader }; */ - namespace NFlags + namespace NFlags { const int kEncrypted = 1 << 0; const int kDescriptorUsedMask = 1 << 3; @@ -196,8 +197,8 @@ namespace NFileHeader kMac = 7, kZ_System = 8, kCPM = 9, - kTOPS20 = 10, // pkzip 2.50 NTFS - kNTFS = 11, // filesystem used by Windows NT + kTOPS20 = 10, // pkzip 2.50 NTFS + kNTFS = 11, // filesystem used by Windows NT kQDOS = 12, // SMS/QDOS kAcorn = 13, // Archimedes Acorn RISC OS kVFAT = 14, // filesystem used by Windows 95, NT diff --git a/CPP/7zip/Archive/Zip/ZipIn.cpp b/CPP/7zip/Archive/Zip/ZipIn.cpp index f8e81c59..d67713ce 100755 --- a/CPP/7zip/Archive/Zip/ZipIn.cpp +++ b/CPP/7zip/Archive/Zip/ZipIn.cpp @@ -9,18 +9,29 @@ #include "../../Common/LimitedStreams.h" #include "../../Common/StreamUtils.h" +extern "C" +{ + #include "../../../../C/CpuArch.h" +} + +#define Get16(p) GetUi16(p) +#define Get32(p) GetUi32(p) +#define Get64(p) GetUi64(p) + namespace NArchive { namespace NZip { // static const char kEndOfString = '\0'; - -bool CInArchive::Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit) + +HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit) { - m_Stream = inStream; - if(m_Stream->Seek(0, STREAM_SEEK_CUR, &m_StreamStartPosition) != S_OK) - return false; + Close(); + RINOK(stream->Seek(0, STREAM_SEEK_CUR, &m_StreamStartPosition)); m_Position = m_StreamStartPosition; - return FindAndReadMarker(searchHeaderSizeLimit); + RINOK(FindAndReadMarker(stream, searchHeaderSizeLimit)); + RINOK(stream->Seek(m_Position, STREAM_SEEK_SET, NULL)); + m_Stream = stream; + return S_OK; } void CInArchive::Close() @@ -38,85 +49,76 @@ HRESULT CInArchive::Seek(UInt64 offset) static inline bool TestMarkerCandidate(const Byte *p, UInt32 &value) { - value = p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24); - return (value == NSignature::kLocalFileHeader) || + value = Get32(p); + return + (value == NSignature::kLocalFileHeader) || (value == NSignature::kEndOfCentralDir); } static const UInt32 kNumMarkerAddtionalBytes = 2; static inline bool TestMarkerCandidate2(const Byte *p, UInt32 &value) { - value = p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24); + value = Get32(p); if (value == NSignature::kEndOfCentralDir) - { - UInt16 nextWord = p[0] | (((UInt16)p[1]) << 8); - return (nextWord == 0); - } - if (value != NSignature::kLocalFileHeader) - return false; - if (p[0] > 128) - return false; - return true; + return (Get16(p + 4) == 0); + return (value == NSignature::kLocalFileHeader && p[4] < 128); } -bool CInArchive::FindAndReadMarker(const UInt64 *searchHeaderSizeLimit) +HRESULT CInArchive::FindAndReadMarker(IInStream *stream, const UInt64 *searchHeaderSizeLimit) { m_ArchiveInfo.Clear(); m_Position = m_StreamStartPosition; - if(Seek(m_StreamStartPosition) != S_OK) - return false; Byte marker[NSignature::kMarkerSize]; - UInt32 processedSize; - ReadBytes(marker, NSignature::kMarkerSize, &processedSize); - if(processedSize != NSignature::kMarkerSize) - return false; + RINOK(ReadStream_FALSE(stream, marker, NSignature::kMarkerSize)); + m_Position += NSignature::kMarkerSize; if (TestMarkerCandidate(marker, m_Signature)) - return true; + return S_OK; CByteDynamicBuffer dynamicBuffer; - static const UInt32 kSearchMarkerBufferSize = 0x10000; + const UInt32 kSearchMarkerBufferSize = 0x10000; dynamicBuffer.EnsureCapacity(kSearchMarkerBufferSize); Byte *buffer = dynamicBuffer; UInt32 numBytesPrev = NSignature::kMarkerSize - 1; - memmove(buffer, marker + 1, numBytesPrev); + memcpy(buffer, marker + 1, numBytesPrev); UInt64 curTestPos = m_StreamStartPosition + 1; for (;;) { if (searchHeaderSizeLimit != NULL) if (curTestPos - m_StreamStartPosition > *searchHeaderSizeLimit) break; - UInt32 numReadBytes = kSearchMarkerBufferSize - numBytesPrev; - ReadBytes(buffer + numBytesPrev, numReadBytes, &processedSize); - UInt32 numBytesInBuffer = numBytesPrev + processedSize; + size_t numReadBytes = kSearchMarkerBufferSize - numBytesPrev; + RINOK(ReadStream(stream, buffer + numBytesPrev, &numReadBytes)); + m_Position += numReadBytes; + UInt32 numBytesInBuffer = numBytesPrev + (UInt32)numReadBytes; const UInt32 kMarker2Size = NSignature::kMarkerSize + kNumMarkerAddtionalBytes; if (numBytesInBuffer < kMarker2Size) break; UInt32 numTests = numBytesInBuffer - kMarker2Size + 1; - for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++) - { + for (UInt32 pos = 0; pos < numTests; pos++) + { + if (buffer[pos] != 0x50) + continue; if (TestMarkerCandidate2(buffer + pos, m_Signature)) { + curTestPos += pos; m_ArchiveInfo.StartPosition = curTestPos; - // m_ArchiveInfo.Base = m_ArchiveInfo.StartPosition; - // m_ArchiveInfo.Base = 0; m_Position = curTestPos + NSignature::kMarkerSize; - if(Seek(m_Position) != S_OK) - return false; - return true; + return S_OK; } } + curTestPos += numTests; numBytesPrev = numBytesInBuffer - numTests; memmove(buffer, buffer + numTests, numBytesPrev); } - return false; + return S_FALSE; } HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize) { size_t realProcessedSize = size; HRESULT result = ReadStream(m_Stream, data, &realProcessedSize); - if(processedSize != NULL) + if (processedSize != NULL) *processedSize = (UInt32)realProcessedSize; m_Position += realProcessedSize; return result; @@ -124,21 +126,21 @@ HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize) void CInArchive::IncreaseRealPosition(UInt64 addValue) { - if(m_Stream->Seek(addValue, STREAM_SEEK_CUR, &m_Position) != S_OK) + if (m_Stream->Seek(addValue, STREAM_SEEK_CUR, &m_Position) != S_OK) throw CInArchiveException(CInArchiveException::kSeekStreamError); } bool CInArchive::ReadBytesAndTestSize(void *data, UInt32 size) { UInt32 realProcessedSize; - if(ReadBytes(data, size, &realProcessedSize) != S_OK) + if (ReadBytes(data, size, &realProcessedSize) != S_OK) throw CInArchiveException(CInArchiveException::kReadStreamError); return (realProcessedSize == size); } void CInArchive::SafeReadBytes(void *data, UInt32 size) { - if(!ReadBytesAndTestSize(data, size)) + if (!ReadBytesAndTestSize(data, size)) throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive); } @@ -198,8 +200,10 @@ AString CInArchive::ReadFileName(UInt32 nameSize) { if (nameSize == 0) return AString(); - SafeReadBytes(m_NameBuffer.GetBuffer(nameSize), nameSize); - m_NameBuffer.ReleaseBuffer(nameSize); + char *p = m_NameBuffer.GetBuffer(nameSize); + SafeReadBytes(p, nameSize); + p[nameSize] = 0; + m_NameBuffer.ReleaseBuffer(); return m_NameBuffer; } @@ -217,7 +221,7 @@ void CInArchive::ThrowIncorrectArchiveException() static UInt32 GetUInt32(const Byte *data) { - return + return ((UInt32)(Byte)data[0]) | (((UInt32)(Byte)data[1]) << 8) | (((UInt32)(Byte)data[2]) << 16) | @@ -227,7 +231,7 @@ static UInt32 GetUInt32(const Byte *data) /* static UInt16 GetUInt16(const Byte *data) { - return + return ((UInt16)(Byte)data[0]) | (((UInt16)(Byte)data[1]) << 8); } @@ -240,7 +244,7 @@ static UInt64 GetUInt64(const Byte *data) -void CInArchive::ReadExtra(UInt32 extraSize, CExtraBlock &extraBlock, +void CInArchive::ReadExtra(UInt32 extraSize, CExtraBlock &extraBlock, UInt64 &unpackSize, UInt64 &packSize, UInt64 &localHeaderOffset, UInt32 &diskStartNumber) { extraBlock.Clear(); @@ -318,11 +322,11 @@ HRESULT CInArchive::ReadLocalItem(CItemEx &item) { UInt64 localHeaderOffset = 0; UInt32 diskStartNumber = 0; - ReadExtra(item.LocalExtraSize, item.LocalExtra, item.UnPackSize, item.PackSize, + ReadExtra(item.LocalExtraSize, item.LocalExtra, item.UnPackSize, item.PackSize, localHeaderOffset, diskStartNumber); } /* - if (item.IsDirectory()) + if (item.IsDir()) item.UnPackSize = 0; // check It */ return S_OK; @@ -354,10 +358,10 @@ HRESULT CInArchive::ReadLocalItemAfterCdItem(CItemEx &item) if (item.CompressionMethod != localItem.CompressionMethod || // item.Time != localItem.Time || - (!localItem.HasDescriptor() && - ( + (!localItem.HasDescriptor() && + ( item.FileCRC != localItem.FileCRC || - item.PackSize != localItem.PackSize || + item.PackSize != localItem.PackSize || item.UnPackSize != localItem.UnPackSize ) ) || @@ -394,7 +398,7 @@ HRESULT CInArchive::ReadLocalItemDescriptor(CItemEx &item) UInt32 i; for (i = 0; i <= numBytesInBuffer - NFileHeader::kDataDescriptorSize; i++) { - // descriptorSignature field is Info-ZIP's extension + // descriptorSignature field is Info-ZIP's extension // to Zip specification. UInt32 descriptorSignature = GetUInt32(buffer + i); @@ -415,7 +419,7 @@ HRESULT CInArchive::ReadLocalItemDescriptor(CItemEx &item) packedSize += i; int j; for (j = 0; i < numBytesInBuffer; i++, j++) - buffer[j] = buffer[i]; + buffer[j] = buffer[i]; numBytesInBuffer = j; } } @@ -463,28 +467,31 @@ HRESULT CInArchive::ReadLocalItemAfterCdItemFull(CItemEx &item) HRESULT CInArchive::ReadCdItem(CItemEx &item) { item.FromCentral = true; - item.MadeByVersion.Version = ReadByte(); - item.MadeByVersion.HostOS = ReadByte(); - item.ExtractVersion.Version = ReadByte(); - item.ExtractVersion.HostOS = ReadByte(); - item.Flags = ReadUInt16(); - item.CompressionMethod = ReadUInt16(); - item.Time = ReadUInt32(); - item.FileCRC = ReadUInt32(); - item.PackSize = ReadUInt32(); - item.UnPackSize = ReadUInt32(); - UInt16 headerNameSize = ReadUInt16(); - UInt16 headerExtraSize = ReadUInt16(); - UInt16 headerCommentSize = ReadUInt16(); - UInt32 headerDiskNumberStart = ReadUInt16(); - item.InternalAttributes = ReadUInt16(); - item.ExternalAttributes = ReadUInt32(); - item.LocalHeaderPosition = ReadUInt32(); + const int kBufSize = 42; + Byte p[kBufSize]; + SafeReadBytes(p, kBufSize); + item.MadeByVersion.Version = p[0]; + item.MadeByVersion.HostOS = p[1]; + item.ExtractVersion.Version = p[2]; + item.ExtractVersion.HostOS = p[3]; + item.Flags = Get16(p + 4); + item.CompressionMethod = Get16(p + 6); + item.Time = Get32(p + 8); + item.FileCRC = Get32(p + 12); + item.PackSize = Get32(p + 16); + item.UnPackSize = Get32(p + 20); + UInt16 headerNameSize = Get16(p + 24); + UInt16 headerExtraSize = Get16(p + 26); + UInt16 headerCommentSize = Get16(p + 28); + UInt32 headerDiskNumberStart = Get16(p + 30); + item.InternalAttributes = Get16(p + 32); + item.ExternalAttributes = Get32(p + 34); + item.LocalHeaderPosition = Get32(p + 38); item.Name = ReadFileName(headerNameSize); if (headerExtraSize > 0) { - ReadExtra(headerExtraSize, item.CentralExtra, item.UnPackSize, item.PackSize, + ReadExtra(headerExtraSize, item.CentralExtra, item.UnPackSize, item.PackSize, item.LocalHeaderPosition, headerDiskNumberStart); } @@ -493,7 +500,7 @@ HRESULT CInArchive::ReadCdItem(CItemEx &item) // May be these strings must be deleted /* - if (item.IsDirectory()) + if (item.IsDir()) item.UnPackSize = 0; */ @@ -506,7 +513,7 @@ HRESULT CInArchive::TryEcd64(UInt64 offset, CCdInfo &cdInfo) RINOK(Seek(offset)); const UInt32 kEcd64Size = 56; Byte buf[kEcd64Size]; - if(!ReadBytesAndTestSize(buf, kEcd64Size)) + if (!ReadBytesAndTestSize(buf, kEcd64Size)) return S_FALSE; if (GetUInt32(buf) != NSignature::kZip64EndOfCentralDir) return S_FALSE; @@ -531,7 +538,7 @@ HRESULT CInArchive::FindCd(CCdInfo &cdInfo) return S_FALSE; if (!ReadBytesAndTestSize(buf, bufSize)) return S_FALSE; - for (int i = (int)(bufSize - kEcdSize); i >= 0; i--) + for (int i = (int)(bufSize - kEcdSize); i >= 0; i--) { if (GetUInt32(buf + i) == NSignature::kEndOfCentralDir) { @@ -566,7 +573,7 @@ HRESULT CInArchive::FindCd(CCdInfo &cdInfo) return S_FALSE; } -HRESULT CInArchive::TryReadCd(CObjectVector<CItemEx> &items, UInt64 cdOffset, UInt64 cdSize) +HRESULT CInArchive::TryReadCd(CObjectVector<CItemEx> &items, UInt64 cdOffset, UInt64 cdSize, CProgressVirt *progress) { items.Clear(); RINOK(m_Stream->Seek(cdOffset, STREAM_SEEK_SET, &m_Position)); @@ -574,16 +581,18 @@ HRESULT CInArchive::TryReadCd(CObjectVector<CItemEx> &items, UInt64 cdOffset, UI return S_FALSE; while(m_Position - cdOffset < cdSize) { - if(ReadUInt32() != NSignature::kCentralFileHeader) + if (ReadUInt32() != NSignature::kCentralFileHeader) return S_FALSE; CItemEx cdItem; RINOK(ReadCdItem(cdItem)); items.Add(cdItem); + if (progress && items.Size() % 1000 == 0) + RINOK(progress->SetCompleted(items.Size())); } return (m_Position - cdOffset == cdSize) ? S_OK : S_FALSE; } -HRESULT CInArchive::ReadCd(CObjectVector<CItemEx> &items, UInt64 &cdOffset, UInt64 &cdSize) +HRESULT CInArchive::ReadCd(CObjectVector<CItemEx> &items, UInt64 &cdOffset, UInt64 &cdSize, CProgressVirt *progress) { m_ArchiveInfo.Base = 0; CCdInfo cdInfo; @@ -591,10 +600,10 @@ HRESULT CInArchive::ReadCd(CObjectVector<CItemEx> &items, UInt64 &cdOffset, UInt HRESULT res = S_FALSE; cdSize = cdInfo.Size; cdOffset = cdInfo.Offset; - res = TryReadCd(items, m_ArchiveInfo.Base + cdOffset, cdSize); + res = TryReadCd(items, m_ArchiveInfo.Base + cdOffset, cdSize, progress); if (res == S_FALSE && m_ArchiveInfo.Base == 0) { - res = TryReadCd(items, cdInfo.Offset + m_ArchiveInfo.StartPosition, cdSize); + res = TryReadCd(items, cdInfo.Offset + m_ArchiveInfo.StartPosition, cdSize, progress); if (res == S_OK) m_ArchiveInfo.Base = m_ArchiveInfo.StartPosition; } @@ -616,23 +625,17 @@ HRESULT CInArchive::ReadLocalsAndCd(CObjectVector<CItemEx> &items, CProgressVirt item.FromLocal = true; ReadLocalItemDescriptor(item); items.Add(item); - if (progress != 0) - { - UInt64 numItems = items.Size(); - RINOK(progress->SetCompleted(&numItems)); - } + if (progress && items.Size() % 100 == 0) + RINOK(progress->SetCompleted(items.Size())); if (!ReadUInt32(m_Signature)) break; } cdOffset = m_Position - 4; - for(int i = 0; i < items.Size(); i++) + for (int i = 0; i < items.Size(); i++) { - if (progress != 0) - { - UInt64 numItems = items.Size(); - RINOK(progress->SetCompleted(&numItems)); - } - if(m_Signature != NSignature::kCentralFileHeader) + if (progress && i % 1000 == 0) + RINOK(progress->SetCompleted(items.Size())); + if (m_Signature != NSignature::kCentralFileHeader) return S_FALSE; CItemEx cdItem; @@ -688,6 +691,58 @@ HRESULT CInArchive::ReadLocalsAndCd(CObjectVector<CItemEx> &items, CProgressVirt return S_OK; } +struct CEcd +{ + UInt16 thisDiskNumber; + UInt16 startCDDiskNumber; + UInt16 numEntriesInCDOnThisDisk; + UInt16 numEntriesInCD; + UInt32 cdSize; + UInt32 cdStartOffset; + UInt16 commentSize; + void Parse(const Byte *p); +}; + +void CEcd::Parse(const Byte *p) +{ + thisDiskNumber = Get16(p); + startCDDiskNumber = Get16(p + 2); + numEntriesInCDOnThisDisk = Get16(p + 4); + numEntriesInCD = Get16(p + 6); + cdSize = Get32(p + 8); + cdStartOffset = Get32(p + 12); + commentSize = Get16(p + 16); +} + +struct CEcd64 +{ + UInt16 versionMade; + UInt16 versionNeedExtract; + UInt32 thisDiskNumber; + UInt32 startCDDiskNumber; + UInt64 numEntriesInCDOnThisDisk; + UInt64 numEntriesInCD; + UInt64 cdSize; + UInt64 cdStartOffset; + void Parse(const Byte *p); + CEcd64() { memset(this, 0, sizeof(*this)); } +}; + +void CEcd64::Parse(const Byte *p) +{ + versionMade = Get16(p); + versionNeedExtract = Get16(p + 2); + thisDiskNumber = Get32(p + 4); + startCDDiskNumber = Get32(p + 8); + numEntriesInCDOnThisDisk = Get64(p + 12); + numEntriesInCD = Get64(p + 20); + cdSize = Get64(p + 28); + cdStartOffset = Get64(p + 36); +} + +#define COPY_ECD_ITEM_16(n) if (!isZip64 || ecd. ## n != 0xFFFF) ecd64. ## n = ecd. ## n; +#define COPY_ECD_ITEM_32(n) if (!isZip64 || ecd. ## n != 0xFFFFFFFF) ecd64. ## n = ecd. ## n; + HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *progress) { // m_Signature must be kLocalFileHeaderSignature or @@ -696,14 +751,9 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *pr IsZip64 = false; items.Clear(); - if (progress != 0) - { - UInt64 numItems = items.Size(); - RINOK(progress->SetCompleted(&numItems)); - } UInt64 cdSize, cdStartOffset; - HRESULT res = ReadCd(items, cdStartOffset, cdSize); + HRESULT res = ReadCd(items, cdStartOffset, cdSize, progress); if (res != S_FALSE && res != S_OK) return res; @@ -726,39 +776,32 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *pr cdStartOffset -= m_ArchiveInfo.Base; } - UInt32 thisDiskNumber = 0; - UInt32 startCDDiskNumber = 0; - UInt64 numEntriesInCDOnThisDisk = 0; - UInt64 numEntriesInCD = 0; - UInt64 cdSizeFromRecord = 0; - UInt64 cdStartOffsetFromRecord = 0; + CEcd64 ecd64; bool isZip64 = false; UInt64 zip64EcdStartOffset = m_Position - 4 - m_ArchiveInfo.Base; - if(m_Signature == NSignature::kZip64EndOfCentralDir) + if (m_Signature == NSignature::kZip64EndOfCentralDir) { IsZip64 = isZip64 = true; UInt64 recordSize = ReadUInt64(); - /* UInt16 versionMade = */ ReadUInt16(); - /* UInt16 versionNeedExtract = */ ReadUInt16(); - thisDiskNumber = ReadUInt32(); - startCDDiskNumber = ReadUInt32(); - numEntriesInCDOnThisDisk = ReadUInt64(); - numEntriesInCD = ReadUInt64(); - cdSizeFromRecord = ReadUInt64(); - cdStartOffsetFromRecord = ReadUInt64(); + + const int kBufSize = kZip64EcdSize; + Byte buf[kBufSize]; + SafeReadBytes(buf, kBufSize); + ecd64.Parse(buf); + IncreaseRealPosition(recordSize - kZip64EcdSize); if (!ReadUInt32(m_Signature)) return S_FALSE; - if (thisDiskNumber != 0 || startCDDiskNumber != 0) + if (ecd64.thisDiskNumber != 0 || ecd64.startCDDiskNumber != 0) throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported); - if (numEntriesInCDOnThisDisk != items.Size() || - numEntriesInCD != items.Size() || - cdSizeFromRecord != cdSize || - (cdStartOffsetFromRecord != cdStartOffset && + if (ecd64.numEntriesInCDOnThisDisk != items.Size() || + ecd64.numEntriesInCD != items.Size() || + ecd64.cdSize != cdSize || + (ecd64.cdStartOffset != cdStartOffset && (!items.IsEmpty()))) return S_FALSE; } - if(m_Signature == NSignature::kZip64EndOfCentralDirLocator) + if (m_Signature == NSignature::kZip64EndOfCentralDirLocator) { /* UInt32 startEndCDDiskNumber = */ ReadUInt32(); UInt64 endCDStartOffset = ReadUInt64(); @@ -768,42 +811,30 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *pr if (!ReadUInt32(m_Signature)) return S_FALSE; } - if(m_Signature != NSignature::kEndOfCentralDir) + if (m_Signature != NSignature::kEndOfCentralDir) return S_FALSE; - UInt16 thisDiskNumber16 = ReadUInt16(); - if (!isZip64 || thisDiskNumber16 != 0xFFFF) - thisDiskNumber = thisDiskNumber16; - - UInt16 startCDDiskNumber16 = ReadUInt16(); - if (!isZip64 || startCDDiskNumber16 != 0xFFFF) - startCDDiskNumber = startCDDiskNumber16; - - UInt16 numEntriesInCDOnThisDisk16 = ReadUInt16(); - if (!isZip64 || numEntriesInCDOnThisDisk16 != 0xFFFF) - numEntriesInCDOnThisDisk = numEntriesInCDOnThisDisk16; + const int kBufSize = kEcdSize - 4; + Byte buf[kBufSize]; + SafeReadBytes(buf, kBufSize); + CEcd ecd; + ecd.Parse(buf); - UInt16 numEntriesInCD16 = ReadUInt16(); - if (!isZip64 || numEntriesInCD16 != 0xFFFF) - numEntriesInCD = numEntriesInCD16; + COPY_ECD_ITEM_16(thisDiskNumber); + COPY_ECD_ITEM_16(startCDDiskNumber); + COPY_ECD_ITEM_16(numEntriesInCDOnThisDisk); + COPY_ECD_ITEM_16(numEntriesInCD); + COPY_ECD_ITEM_32(cdSize); + COPY_ECD_ITEM_32(cdStartOffset); - UInt32 cdSizeFromRecord32 = ReadUInt32(); - if (!isZip64 || cdSizeFromRecord32 != 0xFFFFFFFF) - cdSizeFromRecord = cdSizeFromRecord32; + ReadBuffer(m_ArchiveInfo.Comment, ecd.commentSize); - UInt32 cdStartOffsetFromRecord32 = ReadUInt32(); - if (!isZip64 || cdStartOffsetFromRecord32 != 0xFFFFFFFF) - cdStartOffsetFromRecord = cdStartOffsetFromRecord32; - - UInt16 commentSize = ReadUInt16(); - ReadBuffer(m_ArchiveInfo.Comment, commentSize); - - if (thisDiskNumber != 0 || startCDDiskNumber != 0) + if (ecd64.thisDiskNumber != 0 || ecd64.startCDDiskNumber != 0) throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported); - if ((UInt16)numEntriesInCDOnThisDisk != ((UInt16)items.Size()) || - (UInt16)numEntriesInCD != ((UInt16)items.Size()) || - (UInt32)cdSizeFromRecord != (UInt32)cdSize || - ((UInt32)(cdStartOffsetFromRecord) != (UInt32)cdStartOffset && + if ((UInt16)ecd64.numEntriesInCDOnThisDisk != ((UInt16)items.Size()) || + (UInt16)ecd64.numEntriesInCD != ((UInt16)items.Size()) || + (UInt32)ecd64.cdSize != (UInt32)cdSize || + ((UInt32)(ecd64.cdStartOffset) != (UInt32)cdStartOffset && (!items.IsEmpty()))) return S_FALSE; @@ -813,26 +844,25 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *pr ISequentialInStream* CInArchive::CreateLimitedStream(UInt64 position, UInt64 size) { CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr<ISequentialInStream> inStream(streamSpec); + CMyComPtr<ISequentialInStream> stream(streamSpec); SeekInArchive(m_ArchiveInfo.Base + position); streamSpec->SetStream(m_Stream); streamSpec->Init(size); - return inStream.Detach(); + return stream.Detach(); } IInStream* CInArchive::CreateStream() { - CMyComPtr<IInStream> inStream = m_Stream; - return inStream.Detach(); + CMyComPtr<IInStream> stream = m_Stream; + return stream.Detach(); } bool CInArchive::SeekInArchive(UInt64 position) { UInt64 newPosition; - if(m_Stream->Seek(position, STREAM_SEEK_SET, &newPosition) != S_OK) + if (m_Stream->Seek(position, STREAM_SEEK_SET, &newPosition) != S_OK) return false; return (newPosition == position); } }} - diff --git a/CPP/7zip/Archive/Zip/ZipIn.h b/CPP/7zip/Archive/Zip/ZipIn.h index b5a5a3ef..750095d6 100755 --- a/CPP/7zip/Archive/Zip/ZipIn.h +++ b/CPP/7zip/Archive/Zip/ZipIn.h @@ -25,7 +25,7 @@ public: kMultiVolumeArchiveAreNotSupported, kReadStreamError, kSeekStreamError - } + } Cause; CInArchiveException(ECauseType cause): Cause(cause) {} }; @@ -37,18 +37,19 @@ public: UInt64 StartPosition; CByteBuffer Comment; CInArchiveInfo(): Base(0), StartPosition(0) {} - void Clear() - { + void Clear() + { Base = 0; StartPosition = 0; - Comment.SetCapacity(0); + Comment.SetCapacity(0); } }; class CProgressVirt { public: - STDMETHOD(SetCompleted)(const UInt64 *numFiles) PURE; + STDMETHOD(SetTotal)(UInt64 numFiles) PURE; + STDMETHOD(SetCompleted)(UInt64 numFiles) PURE; }; struct CCdInfo @@ -68,7 +69,7 @@ class CInArchive HRESULT Seek(UInt64 offset); - bool FindAndReadMarker(const UInt64 *searchHeaderSizeLimit); + HRESULT FindAndReadMarker(IInStream *stream, const UInt64 *searchHeaderSizeLimit); bool ReadUInt32(UInt32 &signature); AString ReadFileName(UInt32 nameSize); @@ -83,15 +84,15 @@ class CInArchive void IncreaseRealPosition(UInt64 addValue); - void ReadExtra(UInt32 extraSize, CExtraBlock &extraBlock, + void ReadExtra(UInt32 extraSize, CExtraBlock &extraBlock, UInt64 &unpackSize, UInt64 &packSize, UInt64 &localHeaderOffset, UInt32 &diskStartNumber); HRESULT ReadLocalItem(CItemEx &item); HRESULT ReadLocalItemDescriptor(CItemEx &item); HRESULT ReadCdItem(CItemEx &item); HRESULT TryEcd64(UInt64 offset, CCdInfo &cdInfo); HRESULT FindCd(CCdInfo &cdInfo); - HRESULT TryReadCd(CObjectVector<CItemEx> &items, UInt64 cdOffset, UInt64 cdSize); - HRESULT ReadCd(CObjectVector<CItemEx> &items, UInt64 &cdOffset, UInt64 &cdSize); + HRESULT TryReadCd(CObjectVector<CItemEx> &items, UInt64 cdOffset, UInt64 cdSize, CProgressVirt *progress); + HRESULT ReadCd(CObjectVector<CItemEx> &items, UInt64 &cdOffset, UInt64 &cdSize, CProgressVirt *progress); HRESULT ReadLocalsAndCd(CObjectVector<CItemEx> &items, CProgressVirt *progress, UInt64 &cdOffset); public: CInArchiveInfo m_ArchiveInfo; @@ -100,12 +101,14 @@ public: HRESULT ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *progress); HRESULT ReadLocalItemAfterCdItem(CItemEx &item); HRESULT ReadLocalItemAfterCdItemFull(CItemEx &item); - bool Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit); + HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); void Close(); void GetArchiveInfo(CInArchiveInfo &archiveInfo) const; bool SeekInArchive(UInt64 position); ISequentialInStream *CreateLimitedStream(UInt64 position, UInt64 size); IInStream* CreateStream(); + + bool IsOpen() const { return m_Stream != NULL; } }; }} diff --git a/CPP/7zip/Archive/Zip/ZipItem.cpp b/CPP/7zip/Archive/Zip/ZipItem.cpp index 484696f5..9bbf3882 100755 --- a/CPP/7zip/Archive/Zip/ZipItem.cpp +++ b/CPP/7zip/Archive/Zip/ZipItem.cpp @@ -18,7 +18,7 @@ bool operator==(const CVersion &v1, const CVersion &v2) bool operator!=(const CVersion &v1, const CVersion &v2) { return !(v1 == v2); -} +} bool CExtraSubBlock::ExtractNtfsTime(int index, FILETIME &ft) const { @@ -52,26 +52,26 @@ bool CExtraSubBlock::ExtractNtfsTime(int index, FILETIME &ft) const } bool CLocalItem::IsImplodeBigDictionary() const -{ +{ if (CompressionMethod != NFileHeader::NCompressionMethod::kImploded) throw 12312212; - return (Flags & NFileHeader::NFlags::kImplodeDictionarySizeMask) != 0; + return (Flags & NFileHeader::NFlags::kImplodeDictionarySizeMask) != 0; } bool CLocalItem::IsImplodeLiteralsOn() const { if (CompressionMethod != NFileHeader::NCompressionMethod::kImploded) throw 12312213; - return (Flags & NFileHeader::NFlags::kImplodeLiteralsOnMask) != 0; + return (Flags & NFileHeader::NFlags::kImplodeLiteralsOnMask) != 0; } -bool CLocalItem::IsDirectory() const -{ +bool CLocalItem::IsDir() const +{ return NItemName::HasTailSlash(Name, GetCodePage()); } -bool CItem::IsDirectory() const -{ +bool CItem::IsDir() const +{ if (NItemName::HasTailSlash(Name, GetCodePage())) return true; if (!FromCentral) @@ -80,14 +80,11 @@ bool CItem::IsDirectory() const switch(MadeByVersion.HostOS) { case NFileHeader::NHostOS::kAMIGA: - switch (highAttributes & NFileHeader::NAmigaAttribute::kIFMT) + switch (highAttributes & NFileHeader::NAmigaAttribute::kIFMT) { - case NFileHeader::NAmigaAttribute::kIFDIR: - return true; - case NFileHeader::NAmigaAttribute::kIFREG: - return false; - default: - return false; // change it throw kUnknownAttributes; + case NFileHeader::NAmigaAttribute::kIFDIR: return true; + case NFileHeader::NAmigaAttribute::kIFREG: return false; + default: return false; // change it throw kUnknownAttributes; } case NFileHeader::NHostOS::kFAT: case NFileHeader::NHostOS::kNTFS: @@ -103,7 +100,7 @@ bool CItem::IsDirectory() const return false; // change it throw kUnknownAttributes; default: /* - switch (highAttributes & NFileHeader::NUnixAttribute::kIFMT) + switch (highAttributes & NFileHeader::NUnixAttribute::kIFMT) { case NFileHeader::NUnixAttribute::kIFDIR: return true; @@ -118,7 +115,7 @@ bool CItem::IsDirectory() const UInt32 CLocalItem::GetWinAttributes() const { DWORD winAttributes = 0; - if (IsDirectory()) + if (IsDir()) winAttributes |= FILE_ATTRIBUTE_DIRECTORY; return winAttributes; } @@ -131,26 +128,26 @@ UInt32 CItem::GetWinAttributes() const case NFileHeader::NHostOS::kFAT: case NFileHeader::NHostOS::kNTFS: if (FromCentral) - winAttributes = ExternalAttributes; + winAttributes = ExternalAttributes; break; default: winAttributes = 0; // must be converted from unix value; } - if (IsDirectory()) // test it; + if (IsDir()) // test it; winAttributes |= FILE_ATTRIBUTE_DIRECTORY; return winAttributes; } void CLocalItem::SetFlagBits(int startBitNumber, int numBits, int value) -{ +{ UInt16 mask = (UInt16)(((1 << numBits) - 1) << startBitNumber); Flags &= ~mask; Flags |= value << startBitNumber; } void CLocalItem::SetBitMask(int bitMask, bool enable) -{ - if(enable) +{ + if(enable) Flags |= bitMask; else Flags &= ~bitMask; diff --git a/CPP/7zip/Archive/Zip/ZipItem.h b/CPP/7zip/Archive/Zip/ZipItem.h index 8d7cc3b4..bc1b27c0 100755 --- a/CPP/7zip/Archive/Zip/ZipItem.h +++ b/CPP/7zip/Archive/Zip/ZipItem.h @@ -32,8 +32,8 @@ struct CExtraSubBlock struct CWzAesExtraField { - UInt16 VendorVersion; // 0x0001 - AE-1, 0x0002 - AE-2, - // UInt16 VendorId; // "AE" + UInt16 VendorVersion; // 0x0001 - AE-1, 0x0002 - AE-2, + // UInt16 VendorId; // "AE" Byte Strength; // 1 - 128-bit , 2 - 192-bit , 3 - 256-bit UInt16 Method; @@ -111,14 +111,14 @@ struct CExtraBlock { CObjectVector<CExtraSubBlock> SubBlocks; void Clear() { SubBlocks.Clear(); } - size_t GetSize() const + size_t GetSize() const { size_t res = 0; for (int i = 0; i < SubBlocks.Size(); i++) res += SubBlocks[i].Data.GetCapacity() + 2 + 2; return res; } - bool GetWzAesField(CWzAesExtraField &aesField) const + bool GetWzAesField(CWzAesExtraField &aesField) const { for (int i = 0; i < SubBlocks.Size(); i++) if (aesField.ParseFromSubBlock(SubBlocks[i])) @@ -126,7 +126,7 @@ struct CExtraBlock return false; } - bool GetStrongCryptoField(CStrongCryptoField &f) const + bool GetStrongCryptoField(CStrongCryptoField &f) const { for (int i = 0; i < SubBlocks.Size(); i++) if (f.ParseFromSubBlock(SubBlocks[i])) @@ -134,13 +134,13 @@ struct CExtraBlock return false; } - bool HasWzAesField() const + bool HasWzAesField() const { CWzAesExtraField aesField; return GetWzAesField(aesField); } - bool GetNtfsTime(int index, FILETIME &ft) const + bool GetNtfsTime(int index, FILETIME &ft) const { for (int i = 0; i < SubBlocks.Size(); i++) { @@ -152,7 +152,7 @@ struct CExtraBlock } /* - bool HasStrongCryptoField() const + bool HasStrongCryptoField() const { CStrongCryptoField f; return GetStrongCryptoField(f); @@ -191,14 +191,14 @@ public: bool IsImplodeBigDictionary() const; bool IsImplodeLiteralsOn() const; - bool IsDirectory() const; + bool IsDir() const; bool IgnoreItem() const { return false; } UInt32 GetWinAttributes() const; bool HasDescriptor() const { return (Flags & NFileHeader::NFlags::kDescriptorUsedMask) != 0; } - UString GetUnicodeString(const AString &s) const - { + UString GetUnicodeString(const AString &s) const + { UString res; if (IsUtf8()) if (!ConvertUTF8ToUnicode(s, res)) @@ -239,10 +239,10 @@ public: bool FromCentral; bool NtfsTimeIsDefined; - bool IsDirectory() const; + bool IsDir() const; UInt32 GetWinAttributes() const; - bool IsThereCrc() const + bool IsThereCrc() const { if (CompressionMethod == NFileHeader::NCompressionMethod::kWzAES) { @@ -250,12 +250,12 @@ public: if (CentralExtra.GetWzAesField(aesField)) return aesField.NeedCrc(); } - return (FileCRC != 0 || !IsDirectory()); + return (FileCRC != 0 || !IsDir()); } WORD GetCodePage() const { - return (WORD)((MadeByVersion.HostOS == NFileHeader::NHostOS::kFAT + return (WORD)((MadeByVersion.HostOS == NFileHeader::NHostOS::kFAT || MadeByVersion.HostOS == NFileHeader::NHostOS::kNTFS ) ? CP_OEMCP : CP_ACP); } diff --git a/CPP/7zip/Archive/Zip/ZipItemEx.h b/CPP/7zip/Archive/Zip/ZipItemEx.h index 0c5ba0ca..ab62cdbb 100755 --- a/CPP/7zip/Archive/Zip/ZipItemEx.h +++ b/CPP/7zip/Archive/Zip/ZipItemEx.h @@ -15,17 +15,17 @@ public: UInt32 FileHeaderWithNameSize; UInt16 LocalExtraSize; - UInt64 GetLocalFullSize() const - { return FileHeaderWithNameSize + LocalExtraSize + PackSize + + UInt64 GetLocalFullSize() const + { return FileHeaderWithNameSize + LocalExtraSize + PackSize + (HasDescriptor() ? NFileHeader::kDataDescriptorSize : 0); }; /* - UInt64 GetLocalFullSize(bool isZip64) const - { return FileHeaderWithNameSize + LocalExtraSize + PackSize + + UInt64 GetLocalFullSize(bool isZip64) const + { return FileHeaderWithNameSize + LocalExtraSize + PackSize + (HasDescriptor() ? (isZip64 ? NFileHeader::kDataDescriptor64Size : NFileHeader::kDataDescriptorSize) : 0); }; */ - UInt64 GetLocalExtraPosition() const + UInt64 GetLocalExtraPosition() const { return LocalHeaderPosition + FileHeaderWithNameSize; }; - UInt64 GetDataPosition() const + UInt64 GetDataPosition() const { return GetLocalExtraPosition() + LocalExtraSize; }; }; diff --git a/CPP/7zip/Archive/Zip/ZipOut.cpp b/CPP/7zip/Archive/Zip/ZipOut.cpp index fd89b1e8..5b1bdeee 100755 --- a/CPP/7zip/Archive/Zip/ZipOut.cpp +++ b/CPP/7zip/Archive/Zip/ZipOut.cpp @@ -36,7 +36,7 @@ void COutArchive::PrepareWriteCompressedDataZip64(UInt16 fileNameLength, bool is void COutArchive::PrepareWriteCompressedData(UInt16 fileNameLength, UInt64 unPackSize, bool aesEncryption) { - // We test it to 0xF8000000 to support case when compressed size + // We test it to 0xF8000000 to support case when compressed size // can be larger than uncompressed size. PrepareWriteCompressedDataZip64(fileNameLength, unPackSize >= 0xF8000000, aesEncryption); } diff --git a/CPP/7zip/Archive/Zip/ZipUpdate.cpp b/CPP/7zip/Archive/Zip/ZipUpdate.cpp index 2ec08981..3294ad78 100755 --- a/CPP/7zip/Archive/Zip/ZipUpdate.cpp +++ b/CPP/7zip/Archive/Zip/ZipUpdate.cpp @@ -30,13 +30,20 @@ using namespace NSynchronization; namespace NArchive { namespace NZip { -static const Byte kMadeByHostOS = NFileHeader::NHostOS::kFAT; -static const Byte kExtractHostOS = NFileHeader::NHostOS::kFAT; +static const Byte kHostOS = + #ifdef _WIN32 + NFileHeader::NHostOS::kFAT; + #else + NFileHeader::NHostOS::kUnix; + #endif + +static const Byte kMadeByHostOS = kHostOS; +static const Byte kExtractHostOS = kHostOS; static const Byte kMethodForDirectory = NFileHeader::NCompressionMethod::kStored; static const Byte kExtractVersionForDirectory = NFileHeader::NCompressionMethod::kStoreExtractVersion; -static HRESULT CopyBlockToArchive(ISequentialInStream *inStream, +static HRESULT CopyBlockToArchive(ISequentialInStream *inStream, COutArchive &outArchive, ICompressProgressInfo *progress) { CMyComPtr<ISequentialOutStream> outStream; @@ -45,7 +52,7 @@ static HRESULT CopyBlockToArchive(ISequentialInStream *inStream, return copyCoder->Code(inStream, outStream, NULL, NULL, progress); } -static HRESULT WriteRange(IInStream *inStream, COutArchive &outArchive, +static HRESULT WriteRange(IInStream *inStream, COutArchive &outArchive, const CUpdateRange &range, ICompressProgressInfo *progress) { UInt64 position; @@ -61,30 +68,30 @@ static HRESULT WriteRange(IInStream *inStream, COutArchive &outArchive, } static void SetFileHeader( - COutArchive &archive, + COutArchive &archive, const CCompressionMethodMode &options, - const CUpdateItem &updateItem, + const CUpdateItem &ui, CItem &item) { - item.UnPackSize = updateItem.Size; - bool isDirectory; + item.UnPackSize = ui.Size; + bool isDir; item.ClearFlags(); - if (updateItem.NewProperties) + if (ui.NewProperties) { - isDirectory = updateItem.IsDirectory; - item.Name = updateItem.Name; - item.SetUtf8(updateItem.IsUtf8); - item.ExternalAttributes = updateItem.Attributes; - item.Time = updateItem.Time; - item.NtfsMTime = updateItem.NtfsMTime; - item.NtfsATime = updateItem.NtfsATime; - item.NtfsCTime = updateItem.NtfsCTime; - item.NtfsTimeIsDefined = updateItem.NtfsTimeIsDefined; + isDir = ui.IsDir; + item.Name = ui.Name; + item.SetUtf8(ui.IsUtf8); + item.ExternalAttributes = ui.Attributes; + item.Time = ui.Time; + item.NtfsMTime = ui.NtfsMTime; + item.NtfsATime = ui.NtfsATime; + item.NtfsCTime = ui.NtfsCTime; + item.NtfsTimeIsDefined = ui.NtfsTimeIsDefined; } else - isDirectory = item.IsDirectory(); + isDir = item.IsDir(); item.LocalHeaderPosition = archive.GetCurrentPosition(); item.MadeByVersion.HostOS = kMadeByHostOS; @@ -93,8 +100,8 @@ static void SetFileHeader( item.ExtractVersion.HostOS = kExtractHostOS; item.InternalAttributes = 0; // test it - item.SetEncrypted(!isDirectory && options.PasswordIsDefined); - if (isDirectory) + item.SetEncrypted(!isDir && options.PasswordIsDefined); + if (isDir) { item.ExtractVersion.Version = kExtractVersionForDirectory; item.CompressionMethod = kMethodForDirectory; @@ -103,7 +110,7 @@ static void SetFileHeader( } } -static void SetItemInfoFromCompressingResult(const CCompressingResult &compressingResult, +static void SetItemInfoFromCompressingResult(const CCompressingResult &compressingResult, bool isAesMode, Byte aesKeyMode, CItem &item) { item.ExtractVersion.Version = compressingResult.ExtractVersion; @@ -196,7 +203,7 @@ void CThreadInfo::WaitAndCode() return; Result = Coder.Compress( #ifdef EXTERNAL_CODECS - _codecsInfo, _externalCodecs, + _codecsInfo, _externalCodecs, #endif InStream, OutStream, Progress, CompressingResult); if (Result == S_OK && Progress) @@ -289,7 +296,7 @@ HRESULT CMtProgressMixer2::SetRatioInfo(int index, const UInt64 *inSize, const U InSizes[index] = *inSize; if (outSize != 0) OutSizes[index] = *outSize; - UInt64 v = ProgressOffset + (_inSizeIsMain ? + UInt64 v = ProgressOffset + (_inSizeIsMain ? (InSizes[0] + InSizes[1]) : (OutSizes[0] + OutSizes[1])); return Progress->SetCompleted(&v); @@ -300,7 +307,7 @@ STDMETHODIMP CMtProgressMixer2::SetRatioInfo(const UInt64 *inSize, const UInt64 return SetRatioInfo(0, inSize, outSize); } -class CMtProgressMixer: +class CMtProgressMixer: public ICompressProgressInfo, public CMyUnknownImp { @@ -328,14 +335,14 @@ STDMETHODIMP CMtProgressMixer::SetRatioInfo(const UInt64 *inSize, const UInt64 * #endif -static HRESULT UpdateItemOldData(COutArchive &archive, +static HRESULT UpdateItemOldData(COutArchive &archive, IInStream *inStream, - const CUpdateItem &updateItem, CItemEx &item, + const CUpdateItem &ui, CItemEx &item, /* bool izZip64, */ ICompressProgressInfo *progress, UInt64 &complexity) { - if (updateItem.NewProperties) + if (ui.NewProperties) { if (item.HasDescriptor()) return E_NOTIMPL; @@ -344,15 +351,15 @@ static HRESULT UpdateItemOldData(COutArchive &archive, // CUpdateRange range(item.GetLocalExtraPosition(), item.LocalExtraSize + item.PackSize); CUpdateRange range(item.GetDataPosition(), item.PackSize); - // item.ExternalAttributes = updateItem.Attributes; + // item.ExternalAttributes = ui.Attributes; // Test it - item.Name = updateItem.Name; - item.SetUtf8(updateItem.IsUtf8); - item.Time = updateItem.Time; - item.NtfsMTime = updateItem.NtfsMTime; - item.NtfsATime = updateItem.NtfsATime; - item.NtfsCTime = updateItem.NtfsCTime; - item.NtfsTimeIsDefined = updateItem.NtfsTimeIsDefined; + item.Name = ui.Name; + item.SetUtf8(ui.IsUtf8); + item.Time = ui.Time; + item.NtfsMTime = ui.NtfsMTime; + item.NtfsATime = ui.NtfsATime; + item.NtfsCTime = ui.NtfsCTime; + item.NtfsTimeIsDefined = ui.NtfsTimeIsDefined; item.CentralExtra.RemoveUnknownSubBlocks(); item.LocalExtra.RemoveUnknownSubBlocks(); @@ -369,7 +376,7 @@ static HRESULT UpdateItemOldData(COutArchive &archive, CUpdateRange range(item.LocalHeaderPosition, item.GetLocalFullSize()); // set new header position - item.LocalHeaderPosition = archive.GetCurrentPosition(); + item.LocalHeaderPosition = archive.GetCurrentPosition(); RINOK(WriteRange(inStream, archive, range, progress)); complexity += range.Size; @@ -379,21 +386,21 @@ static HRESULT UpdateItemOldData(COutArchive &archive, } static void WriteDirHeader(COutArchive &archive, const CCompressionMethodMode *options, - const CUpdateItem &updateItem, CItemEx &item) + const CUpdateItem &ui, CItemEx &item) { - SetFileHeader(archive, *options, updateItem, item); - archive.PrepareWriteCompressedData((UInt16)item.Name.Length(), updateItem.Size, options->IsAesMode); + SetFileHeader(archive, *options, ui, item); + archive.PrepareWriteCompressedData((UInt16)item.Name.Length(), ui.Size, options->IsAesMode); archive.WriteLocalHeader(item); } static HRESULT Update2St( DECL_EXTERNAL_CODECS_LOC_VARS - COutArchive &archive, + COutArchive &archive, CInArchive *inArchive, IInStream *inStream, const CObjectVector<CItemEx> &inputItems, const CObjectVector<CUpdateItem> &updateItems, - const CCompressionMethodMode *options, + const CCompressionMethodMode *options, const CByteBuffer &comment, IArchiveUpdateCallback *updateCallback) { @@ -411,37 +418,37 @@ static HRESULT Update2St( lps->InSize = unpackSizeTotal; lps->OutSize = packSizeTotal; RINOK(lps->SetCur()); - const CUpdateItem &updateItem = updateItems[itemIndex]; + const CUpdateItem &ui = updateItems[itemIndex]; CItemEx item; - if (!updateItem.NewProperties || !updateItem.NewData) + if (!ui.NewProperties || !ui.NewData) { - item = inputItems[updateItem.IndexInArchive]; + item = inputItems[ui.IndexInArchive]; if (inArchive->ReadLocalItemAfterCdItemFull(item) != S_OK) return E_NOTIMPL; } - if (updateItem.NewData) + if (ui.NewData) { - bool isDirectory = ((updateItem.NewProperties) ? updateItem.IsDirectory : item.IsDirectory()); - if (isDirectory) + bool isDir = ((ui.NewProperties) ? ui.IsDir : item.IsDir()); + if (isDir) { - WriteDirHeader(archive, options, updateItem, item); + WriteDirHeader(archive, options, ui, item); } else { CMyComPtr<ISequentialInStream> fileInStream; - HRESULT res = updateCallback->GetStream(updateItem.IndexInClient, &fileInStream); + HRESULT res = updateCallback->GetStream(ui.IndexInClient, &fileInStream); if (res == S_FALSE) { - lps->ProgressOffset += updateItem.Size; + lps->ProgressOffset += ui.Size; RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); continue; } RINOK(res); // file Size can be 64-bit !!! - SetFileHeader(archive, *options, updateItem, item); - archive.PrepareWriteCompressedData((UInt16)item.Name.Length(), updateItem.Size, options->IsAesMode); + SetFileHeader(archive, *options, ui, item); + archive.PrepareWriteCompressedData((UInt16)item.Name.Length(), ui.Size, options->IsAesMode); CCompressingResult compressingResult; CMyComPtr<IOutStream> outStream; archive.CreateStreamForCompressing(&outStream); @@ -459,7 +466,7 @@ static HRESULT Update2St( { UInt64 complexity = 0; lps->SendRatio = false; - RINOK(UpdateItemOldData(archive, inStream, updateItem, item, progress, complexity)); + RINOK(UpdateItemOldData(archive, inStream, ui, item, progress, complexity)); lps->SendRatio = true; lps->ProgressOffset += complexity; } @@ -472,12 +479,12 @@ static HRESULT Update2St( static HRESULT Update2( DECL_EXTERNAL_CODECS_LOC_VARS - COutArchive &archive, + COutArchive &archive, CInArchive *inArchive, IInStream *inStream, const CObjectVector<CItemEx> &inputItems, const CObjectVector<CUpdateItem> &updateItems, - const CCompressionMethodMode *options, + const CCompressionMethodMode *options, const CByteBuffer &comment, IArchiveUpdateCallback *updateCallback) { @@ -488,20 +495,20 @@ static HRESULT Update2( int i; for(i = 0; i < updateItems.Size(); i++) { - const CUpdateItem &updateItem = updateItems[i]; - if (updateItem.NewData) + const CUpdateItem &ui = updateItems[i]; + if (ui.NewData) { - complexity += updateItem.Size; - numBytesToCompress += updateItem.Size; + complexity += ui.Size; + numBytesToCompress += ui.Size; numFilesToCompress++; /* - if (updateItem.Commented) - complexity += updateItem.CommentRange.Size; + if (ui.Commented) + complexity += ui.CommentRange.Size; */ } else { - CItemEx inputItem = inputItems[updateItem.IndexInArchive]; + CItemEx inputItem = inputItems[ui.IndexInArchive]; if (inArchive->ReadLocalItemAfterCdItemFull(inputItem) != S_OK) return E_NOTIMPL; complexity += inputItem.GetLocalFullSize(); @@ -580,7 +587,7 @@ static HRESULT Update2( mtProgressMixerSpec->Create(updateCallback, true); CMtCompressProgressMixer mtCompressProgressMixer; - mtCompressProgressMixer.Init(numThreads, mtProgressMixerSpec->RatioProgress); + mtCompressProgressMixer.Init(numThreads, mtProgressMixerSpec->RatioProgress); CMemBlockManagerMt memManager(kBlockSize); CMemRefs refs(&memManager); @@ -625,30 +632,30 @@ static HRESULT Update2( { if ((UInt32)threadIndices.Size() < numThreads && mtItemIndex < updateItems.Size()) { - const CUpdateItem &updateItem = updateItems[mtItemIndex++]; - if (!updateItem.NewData) + const CUpdateItem &ui = updateItems[mtItemIndex++]; + if (!ui.NewData) continue; CItemEx item; - if (updateItem.NewProperties) + if (ui.NewProperties) { - if (updateItem.IsDirectory) + if (ui.IsDir) continue; } else { - item = inputItems[updateItem.IndexInArchive]; + item = inputItems[ui.IndexInArchive]; if (inArchive->ReadLocalItemAfterCdItemFull(item) != S_OK) return E_NOTIMPL; - if (item.IsDirectory()) + if (item.IsDir()) continue; } CMyComPtr<ISequentialInStream> fileInStream; { NWindows::NSynchronization::CCriticalSectionLock lock(mtProgressMixerSpec->Mixer2->CriticalSection); - HRESULT res = updateCallback->GetStream(updateItem.IndexInClient, &fileInStream); + HRESULT res = updateCallback->GetStream(ui.IndexInClient, &fileInStream); if (res == S_FALSE) { - complexity += updateItem.Size; + complexity += ui.Size; complexity += NFileHeader::kLocalBlockSize; mtProgressMixerSpec->Mixer2->SetProgressOffset(complexity); RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); @@ -667,9 +674,9 @@ static HRESULT Update2( threadInfo.IsFree = false; threadInfo.InStream = fileInStream; - // !!!!! we must release ref before sending event + // !!!!! we must release ref before sending event // BUG was here in v4.43 and v4.44. It could change ref counter in two threads in same time - fileInStream.Release(); + fileInStream.Release(); threadInfo.OutStreamSpec->Init(); threadInfo.ProgressSpec->Reinit(); @@ -690,31 +697,31 @@ static HRESULT Update2( continue; } - const CUpdateItem &updateItem = updateItems[itemIndex]; + const CUpdateItem &ui = updateItems[itemIndex]; CItemEx item; - if (!updateItem.NewProperties || !updateItem.NewData) + if (!ui.NewProperties || !ui.NewData) { - item = inputItems[updateItem.IndexInArchive]; + item = inputItems[ui.IndexInArchive]; if (inArchive->ReadLocalItemAfterCdItemFull(item) != S_OK) return E_NOTIMPL; } - if (updateItem.NewData) + if (ui.NewData) { - bool isDirectory = ((updateItem.NewProperties) ? updateItem.IsDirectory : item.IsDirectory()); - if (isDirectory) + bool isDir = ((ui.NewProperties) ? ui.IsDir : item.IsDir()); + if (isDir) { - WriteDirHeader(archive, options, updateItem, item); + WriteDirHeader(archive, options, ui, item); } else { if (lastRealStreamItemIndex < itemIndex) { lastRealStreamItemIndex = itemIndex; - SetFileHeader(archive, *options, updateItem, item); + SetFileHeader(archive, *options, ui, item); // file Size can be 64-bit !!! - archive.PrepareWriteCompressedData((UInt16)item.Name.Length(), updateItem.Size, options->IsAesMode); + archive.PrepareWriteCompressedData((UInt16)item.Name.Length(), ui.Size, options->IsAesMode); } CMemBlocks2 &memRef = refs.Refs[itemIndex]; @@ -725,7 +732,7 @@ static HRESULT Update2( memRef.WriteToStream(memManager.GetBlockSize(), outStream); SetItemInfoFromCompressingResult(memRef.CompressingResult, options->IsAesMode, options->AesKeyMode, item); - SetFileHeader(archive, *options, updateItem, item); + SetFileHeader(archive, *options, ui, item); archive.WriteLocalHeader(item); // RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); memRef.FreeOpt(&memManager); @@ -743,7 +750,7 @@ static HRESULT Update2( } } - DWORD result = ::WaitForMultipleObjects(compressingCompletedEvents.Size(), + DWORD result = ::WaitForMultipleObjects(compressingCompletedEvents.Size(), &compressingCompletedEvents.Front(), FALSE, INFINITE); int t = (int)(result - WAIT_OBJECT_0); CThreadInfo &threadInfo = threads.Threads[threadIndices[t]]; @@ -756,9 +763,9 @@ static HRESULT Update2( { RINOK(threadInfo.OutStreamSpec->WriteToRealStream()); threadInfo.OutStreamSpec->ReleaseOutStream(); - SetItemInfoFromCompressingResult(threadInfo.CompressingResult, + SetItemInfoFromCompressingResult(threadInfo.CompressingResult, options->IsAesMode, options->AesKeyMode, item); - SetFileHeader(archive, *options, updateItem, item); + SetFileHeader(archive, *options, ui, item); archive.WriteLocalHeader(item); } else @@ -774,7 +781,7 @@ static HRESULT Update2( } else { - RINOK(UpdateItemOldData(archive, inStream, updateItem, item, progress, complexity)); + RINOK(UpdateItemOldData(archive, inStream, ui, item, progress, complexity)); } items.Add(item); complexity += NFileHeader::kLocalBlockSize; @@ -783,10 +790,10 @@ static HRESULT Update2( } archive.WriteCentralDir(items, comment); return S_OK; - #endif + #endif } -HRESULT Update( +HRESULT Update( DECL_EXTERNAL_CODECS_LOC_VARS const CObjectVector<CItemEx> &inputItems, const CObjectVector<CUpdateItem> &updateItems, @@ -825,9 +832,9 @@ HRESULT Update( return Update2( EXTERNAL_CODECS_LOC_VARS - outArchive, inArchive, inStream, - inputItems, updateItems, - compressionMethodMode, + outArchive, inArchive, inStream, + inputItems, updateItems, + compressionMethodMode, archiveInfo.Comment, updateCallback); } diff --git a/CPP/7zip/Archive/Zip/ZipUpdate.h b/CPP/7zip/Archive/Zip/ZipUpdate.h index 5e67bead..eee16738 100755 --- a/CPP/7zip/Archive/Zip/ZipUpdate.h +++ b/CPP/7zip/Archive/Zip/ZipUpdate.h @@ -16,7 +16,7 @@ namespace NZip { struct CUpdateRange { - UInt64 Position; + UInt64 Position; UInt64 Size; CUpdateRange() {}; CUpdateRange(UInt64 position, UInt64 size): Position(position), Size(size) {}; @@ -26,7 +26,7 @@ struct CUpdateItem { bool NewData; bool NewProperties; - bool IsDirectory; + bool IsDir; bool NtfsTimeIsDefined; bool IsUtf8; int IndexInArchive; |