diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2008-05-05 04:00:00 +0400 |
---|---|---|
committer | Kornel LesiĆski <kornel@geekhood.net> | 2016-05-28 02:15:55 +0300 |
commit | 3901bf0ab88106a5b031cba7bc18d60cdebf7eef (patch) | |
tree | 808a2489abed822223b118b64e0553db80af6087 /CPP/7zip/Archive | |
parent | bd1fa36322ac27f5715433b388742893d6524516 (diff) |
4.58 beta
Diffstat (limited to 'CPP/7zip/Archive')
67 files changed, 1283 insertions, 1208 deletions
diff --git a/CPP/7zip/Archive/7z/7z.dsp b/CPP/7zip/Archive/7z/7z.dsp deleted file mode 100755 index fc4c3698..00000000 --- a/CPP/7zip/Archive/7z/7z.dsp +++ /dev/null @@ -1,644 +0,0 @@ -# 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 -# Begin Source File - -SOURCE=.\7z.ico -# End Source File -# End Target -# End Project diff --git a/CPP/7zip/Archive/7z/7z.dsw b/CPP/7zip/Archive/7z/7z.dsw deleted file mode 100755 index 702a86c7..00000000 --- a/CPP/7zip/Archive/7z/7z.dsw +++ /dev/null @@ -1,29 +0,0 @@ -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/7zIn.cpp b/CPP/7zip/Archive/7z/7zIn.cpp index a4292545..f892e0cd 100755 --- a/CPP/7zip/Archive/7z/7zIn.cpp +++ b/CPP/7zip/Archive/7z/7zIn.cpp @@ -9,6 +9,7 @@ extern "C" { #include "../../../../C/7zCrc.h" +#include "../../../../C/CpuArch.h" } // define FORMAT_7Z_RECOVERY if you want to recover multivolume archives with empty StartHeader @@ -96,11 +97,7 @@ void CStreamSwitch::Set(CInArchive *archive, const CObjectVector<CByteBuffer> *d } } -#if defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || defined(__i386__) || defined(__x86_64__) -#define SZ_LITTLE_ENDIAN_UNALIGN -#endif - -#ifdef SZ_LITTLE_ENDIAN_UNALIGN +#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; } @@ -220,10 +217,8 @@ static inline bool TestSignatureCandidate(const Byte *p) HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit) { - UInt32 processedSize; - RINOK(ReadStream(stream, _header, kHeaderSize, &processedSize)); - if (processedSize != kHeaderSize) - return S_FALSE; + RINOK(ReadStream_FALSE(stream, _header, kHeaderSize)); + if (TestSignatureCandidate(_header)) return S_OK; @@ -240,6 +235,7 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search 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) diff --git a/CPP/7zip/Archive/7z/7zProperties.cpp b/CPP/7zip/Archive/7z/7zProperties.cpp index 3452a030..f5b5ba98 100755 --- a/CPP/7zip/Archive/7z/7zProperties.cpp +++ b/CPP/7zip/Archive/7z/7zProperties.cpp @@ -40,8 +40,9 @@ CPropMap kPropMap[] = { NID::kCRC, NULL, kpidCRC, VT_UI4}, { NID::kAnti, NULL, kpidIsAnti, VT_BOOL}, - // { 97, NULL, kpidSolid, VT_BOOL}, + #ifndef _SFX + { 97, NULL, kpidEncrypted, VT_BOOL}, { 98, NULL, kpidMethod, VT_BSTR}, { 99, NULL, kpidBlock, VT_UI4} #endif @@ -119,6 +120,7 @@ void CHandler::FillPopIDs() _fileInfoPopIDs += fileInfoPopIDs; #ifndef _SFX + _fileInfoPopIDs.Add(97); _fileInfoPopIDs.Add(98); _fileInfoPopIDs.Add(99); #endif @@ -144,10 +146,9 @@ STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) return S_OK; } -STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType) +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) { - if((int)index >= _fileInfoPopIDs.Size()) + if ((int)index >= _fileInfoPopIDs.Size()) return E_INVALIDARG; int indexInMap = FindPropInMap(_fileInfoPopIDs[index]); if (indexInMap == -1) diff --git a/CPP/7zip/Archive/7z/makefile b/CPP/7zip/Archive/7z/makefile deleted file mode 100755 index 1a72da0e..00000000 --- a/CPP/7zip/Archive/7z/makefile +++ /dev/null @@ -1,111 +0,0 @@ -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 deleted file mode 100755 index 8868173c..00000000 --- a/CPP/7zip/Archive/7z/resource.rc +++ /dev/null @@ -1,5 +0,0 @@ -#include "../../MyVersionInfo.rc" - -MY_VERSION_INFO_DLL("7z Plugin", "7z") - -101 ICON "7z.ico" diff --git a/CPP/7zip/Archive/ArchiveExports.cpp b/CPP/7zip/Archive/ArchiveExports.cpp index a60303a5..3c51a3f5 100755 --- a/CPP/7zip/Archive/ArchiveExports.cpp +++ b/CPP/7zip/Archive/ArchiveExports.cpp @@ -44,9 +44,9 @@ int FindFormatCalssId(const GUID *clsID) if (cls != CLSID_CArchiveHandler) return -1; Byte id = CLS_ARC_ID_ITEM(*clsID); - for (UInt32 i = 0; i < g_NumArcs; i++) + for (unsigned i = 0; i < g_NumArcs; i++) if (g_Arcs[i]->ClassId == id) - return i; + return (int)i; return -1; } diff --git a/CPP/7zip/Archive/Arj/ArjIn.cpp b/CPP/7zip/Archive/Arj/ArjIn.cpp index 146f4f09..cc7cde49 100755 --- a/CPP/7zip/Archive/Arj/ArjIn.cpp +++ b/CPP/7zip/Archive/Arj/ArjIn.cpp @@ -19,10 +19,10 @@ namespace NArj { HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize) { - UInt32 realProcessedSize; - HRESULT result = ReadStream(_stream, data, size, &realProcessedSize); - if(processedSize != NULL) - *processedSize = realProcessedSize; + size_t realProcessedSize = size; + HRESULT result = ReadStream(_stream, data, &realProcessedSize); + if (processedSize != NULL) + *processedSize = (UInt32)realProcessedSize; IncreasePositionValue(realProcessedSize); return result; } diff --git a/CPP/7zip/Archive/BZip2/BZip2Handler.cpp b/CPP/7zip/Archive/BZip2/BZip2Handler.cpp index 0b790c68..c88c883f 100755 --- a/CPP/7zip/Archive/BZip2/BZip2Handler.cpp +++ b/CPP/7zip/Archive/BZip2/BZip2Handler.cpp @@ -56,10 +56,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream, RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_streamStartPosition)); const int kSignatureSize = 3; Byte buffer[kSignatureSize]; - UInt32 processedSize; - RINOK(ReadStream(stream, buffer, kSignatureSize, &processedSize)); - if (processedSize != kSignatureSize) - return S_FALSE; + RINOK(ReadStream_FALSE(stream, buffer, kSignatureSize)); if (buffer[0] != 'B' || buffer[1] != 'Z' || buffer[2] != 'h') return S_FALSE; @@ -166,9 +163,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, const int kSignatureSize = 3; Byte buffer[kSignatureSize]; - UInt32 processedSize; - RINOK(ReadStream(_stream, buffer, kSignatureSize, &processedSize)); - if (processedSize < kSignatureSize) + size_t processedSize = kSignatureSize; + RINOK(ReadStream(_stream, buffer, &processedSize)); + if (processedSize != kSignatureSize) { if (firstItem) return E_FAIL; diff --git a/CPP/7zip/Archive/Cab/CabBlockInStream.cpp b/CPP/7zip/Archive/Cab/CabBlockInStream.cpp index 570ce058..343ef821 100755 --- a/CPP/7zip/Archive/Cab/CabBlockInStream.cpp +++ b/CPP/7zip/Archive/Cab/CabBlockInStream.cpp @@ -116,19 +116,14 @@ HRESULT CCabBlockInStream::PreRead(UInt32 &packSize, UInt32 &unpackSize) { CTempCabInBuffer2 inBuffer; inBuffer.Pos = 0; - UInt32 processedSizeLoc; - RINOK(ReadStream(_stream, inBuffer.Buffer, kDataBlockHeaderSize, &processedSizeLoc)) - if (processedSizeLoc != kDataBlockHeaderSize) - return S_FALSE; // bad block + RINOK(ReadStream_FALSE(_stream, inBuffer.Buffer, kDataBlockHeaderSize)) UInt32 checkSum = inBuffer.ReadUInt32(); packSize = inBuffer.ReadUInt16(); unpackSize = inBuffer.ReadUInt16(); if (ReservedSize != 0) { - RINOK(ReadStream(_stream, _buffer, ReservedSize, &processedSizeLoc)); - if(ReservedSize != processedSizeLoc) - return S_FALSE; // bad block; + RINOK(ReadStream_FALSE(_stream, _buffer, ReservedSize)); } _pos = 0; CCheckSum2 checkSumCalc; @@ -139,9 +134,7 @@ HRESULT CCabBlockInStream::PreRead(UInt32 &packSize, UInt32 &unpackSize) if (packSize < 2) return S_FALSE; // bad block; Byte sig[2]; - RINOK(ReadStream(_stream, sig, 2, &processedSizeLoc)); - if(processedSizeLoc != 2) - return S_FALSE; + RINOK(ReadStream_FALSE(_stream, sig, 2)); if (sig[0] != 0x43 || sig[1] != 0x4B) return S_FALSE; packSize2 -= 2; @@ -154,9 +147,10 @@ HRESULT CCabBlockInStream::PreRead(UInt32 &packSize, UInt32 &unpackSize) UInt32 curSize = packSize2; if (curSize != 0) { - RINOK(ReadStream(_stream, _buffer + _size, curSize, &processedSizeLoc)); - checkSumCalc.Update(_buffer + _size, processedSizeLoc); - _size += processedSizeLoc; + size_t processedSizeLoc = curSize; + RINOK(ReadStream(_stream, _buffer + _size, &processedSizeLoc)); + checkSumCalc.Update(_buffer + _size, (UInt32)processedSizeLoc); + _size += (UInt32)processedSizeLoc; if (processedSizeLoc != curSize) return S_FALSE; } diff --git a/CPP/7zip/Archive/Chm/ChmHandler.cpp b/CPP/7zip/Archive/Chm/ChmHandler.cpp index d1499328..7f3b1837 100755 --- a/CPP/7zip/Archive/Chm/ChmHandler.cpp +++ b/CPP/7zip/Archive/Chm/ChmHandler.cpp @@ -473,7 +473,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, if (!testMode) { UInt32 size = m_Database.NewFormatString.Length(); - RINOK(WriteStream(realOutStream, (const char *)m_Database.NewFormatString, size, 0)); + RINOK(WriteStream(realOutStream, (const char *)m_Database.NewFormatString, size)); } RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); continue; diff --git a/CPP/7zip/Archive/Com/ComHandler.cpp b/CPP/7zip/Archive/Com/ComHandler.cpp index aa9bf859..2255c021 100755 --- a/CPP/7zip/Archive/Com/ComHandler.cpp +++ b/CPP/7zip/Archive/Com/ComHandler.cpp @@ -217,16 +217,14 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, size = (UInt32)rem; RINOK(_stream->Seek(offset, STREAM_SEEK_SET, NULL)); - UInt32 realProcessedSize; - RINOK(ReadStream(_stream, sect, size, &realProcessedSize)); + size_t realProcessedSize = size; + RINOK(ReadStream(_stream, sect, &realProcessedSize)); if (realProcessedSize != size) break; if (realOutStream) { - RINOK(WriteStream(realOutStream, sect, size, &realProcessedSize)); - if (realProcessedSize != size) - break; + RINOK(WriteStream(realOutStream, sect, size)); } pos += size; } diff --git a/CPP/7zip/Archive/Com/ComIn.cpp b/CPP/7zip/Archive/Com/ComIn.cpp index c3549609..b8dfdb81 100755 --- a/CPP/7zip/Archive/Com/ComIn.cpp +++ b/CPP/7zip/Archive/Com/ComIn.cpp @@ -7,6 +7,8 @@ extern "C" #include "../../../../C/Alloc.h" } +#include "../../../../C/CpuArch.h" + #include "Common/MyCom.h" #include "../../Common/StreamUtils.h" #include "Common/IntToString.h" @@ -19,22 +21,6 @@ namespace NCom{ static const UInt32 kSignatureSize = 8; static const Byte kSignature[kSignatureSize] = { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 }; -static HRESULT ReadBytes(ISequentialInStream *inStream, void *data, UInt32 size) -{ - UInt32 realProcessedSize; - RINOK(ReadStream(inStream, data, size, &realProcessedSize)); - return (realProcessedSize == size) ? S_OK : S_FALSE; -} - -#ifdef LITTLE_ENDIAN_UNALIGN -#define GetUi16(p) (*(const UInt16 *)(p)) -#define GetUi32(p) (*(const UInt32 *)(p)) -#else -#define GetUi16(p) ((p)[0] | ((UInt16)(p)[1] << 8)) -#define GetUi32(p) ((p)[0] | ((UInt32)(p)[1] << 8) | ((UInt32)(p)[2] << 16) | ((UInt32)(p)[3] << 24)) -#endif - - void CUInt32Buf::Free() { MyFree(_buf); @@ -56,7 +42,7 @@ bool CUInt32Buf::Allocate(UInt32 numItems) static HRESULT ReadSector(IInStream *inStream, Byte *buf, int sectorSizeBits, UInt32 sid) { RINOK(inStream->Seek((((UInt64)sid + 1) << sectorSizeBits), STREAM_SEEK_SET, NULL)); - return ReadBytes(inStream, buf, (UInt32)1 << sectorSizeBits); + return ReadStream_FALSE(inStream, buf, (UInt32)1 << sectorSizeBits); } static HRESULT ReadIDs(IInStream *inStream, Byte *buf, int sectorSizeBits, UInt32 sid, UInt32 *dest) @@ -219,7 +205,7 @@ HRESULT OpenArchive(IInStream *inStream, CDatabase &db) { static const UInt32 kHeaderSize = 512; Byte p[kHeaderSize]; - RINOK(ReadBytes(inStream, p, kHeaderSize)); + RINOK(ReadStream_FALSE(inStream, p, kHeaderSize)); if (memcmp(p, kSignature, kSignatureSize) != 0) return S_FALSE; UInt16 majorVer = GetUi16(p + 0x1A); diff --git a/CPP/7zip/Archive/Common/CoderMixer2MT.cpp b/CPP/7zip/Archive/Common/CoderMixer2MT.cpp index 2ef1fa95..e1030976 100755 --- a/CPP/7zip/Archive/Common/CoderMixer2MT.cpp +++ b/CPP/7zip/Archive/Common/CoderMixer2MT.cpp @@ -208,14 +208,16 @@ STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams, RINOK(ReturnIfError(E_ABORT)); RINOK(ReturnIfError(E_OUTOFMEMORY)); - RINOK(ReturnIfError(S_FALSE)); for (i = 0; i < _coders.Size(); i++) { HRESULT result = _coders[i].Result; - if (result != S_OK && result != E_FAIL) + if (result != S_OK && result != E_FAIL && result != S_FALSE) return result; } + + RINOK(ReturnIfError(S_FALSE)); + for (i = 0; i < _coders.Size(); i++) { HRESULT result = _coders[i].Result; diff --git a/CPP/7zip/Archive/Common/CoderMixerMT.cpp b/CPP/7zip/Archive/Common/CoderMixerMT.cpp index 6319c5da..85cf0a52 100755 --- a/CPP/7zip/Archive/Common/CoderMixerMT.cpp +++ b/CPP/7zip/Archive/Common/CoderMixerMT.cpp @@ -77,14 +77,16 @@ STDMETHODIMP CCoderMixerMT::Code(ISequentialInStream *inStream, RINOK(ReturnIfError(E_ABORT)); RINOK(ReturnIfError(E_OUTOFMEMORY)); - RINOK(ReturnIfError(S_FALSE)); for (i = 0; i < _coders.Size(); i++) { HRESULT result = _coders[i].Result; - if (result != S_OK && result != E_FAIL) + if (result != S_OK && result != E_FAIL && result != S_FALSE) return result; } + + RINOK(ReturnIfError(S_FALSE)); + for (i = 0; i < _coders.Size(); i++) { HRESULT result = _coders[i].Result; diff --git a/CPP/7zip/Archive/Common/HandlerOut.cpp b/CPP/7zip/Archive/Common/HandlerOut.cpp index 0dcf449e..082a484d 100755 --- a/CPP/7zip/Archive/Common/HandlerOut.cpp +++ b/CPP/7zip/Archive/Common/HandlerOut.cpp @@ -380,15 +380,6 @@ HRESULT COutHandler::SetParams(COneMethodInfo &oneMethodInfo, const UString &src HRESULT COutHandler::SetSolidSettings(const UString &s) { - bool res; - if (StringToBool(s, res)) - { - if (res) - InitSolid(); - else - _numSolidFiles = 1; - return S_OK; - } UString s2 = s; s2.MakeUpper(); for (int i = 0; i < s2.Length();) @@ -439,16 +430,27 @@ HRESULT COutHandler::SetSolidSettings(const UString &s) HRESULT COutHandler::SetSolidSettings(const PROPVARIANT &value) { + bool isSolid; switch(value.vt) { case VT_EMPTY: - InitSolid(); - return S_OK; + isSolid = true; + break; + case VT_BOOL: + isSolid = (value.boolVal != VARIANT_FALSE); + break; case VT_BSTR: + if (StringToBool(value.bstrVal, isSolid)) + break; return SetSolidSettings(value.bstrVal); default: return E_INVALIDARG; } + if (isSolid) + InitSolid(); + else + _numSolidFiles = 1; + return S_OK; } void COutHandler::Init() @@ -587,6 +589,14 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val if (number <= mainDicMethodIndex) mainDicSize = dicSize; } + else if (realName.Left(1).CompareNoCase(L"B") == 0) + { + UInt32 blockSize; + RINOK(ParsePropDictionaryValue(realName.Mid(1), value, blockSize)); + property.Id = NCoderPropID::kBlockSize; + property.Value = blockSize; + oneMethodInfo.Properties.Add(property); + } else if (realName.Left(3).CompareNoCase(L"MEM") == 0) { UInt32 dicSize; diff --git a/CPP/7zip/Archive/Common/ParseProperties.cpp b/CPP/7zip/Archive/Common/ParseProperties.cpp index f0d4e29c..83d51241 100755 --- a/CPP/7zip/Archive/Common/ParseProperties.cpp +++ b/CPP/7zip/Archive/Common/ParseProperties.cpp @@ -99,12 +99,12 @@ HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, U bool StringToBool(const UString &s, bool &res) { - if (s.IsEmpty() || s.CompareNoCase(L"ON") == 0) + if (s.IsEmpty() || s.CompareNoCase(L"ON") == 0 || s.Compare(L"+") == 0) { res = true; return true; } - if (s.CompareNoCase(L"OFF") == 0) + if (s.CompareNoCase(L"OFF") == 0 || s.Compare(L"-") == 0) { res = false; return true; @@ -119,6 +119,9 @@ HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value) case VT_EMPTY: dest = true; return S_OK; + case VT_BOOL: + dest = (value.boolVal != VARIANT_FALSE); + return S_OK; /* case VT_UI4: dest = (value.ulVal != 0); diff --git a/CPP/7zip/Archive/Cpio/CpioIn.cpp b/CPP/7zip/Archive/Cpio/CpioIn.cpp index 91399362..4732a32e 100755 --- a/CPP/7zip/Archive/Cpio/CpioIn.cpp +++ b/CPP/7zip/Archive/Cpio/CpioIn.cpp @@ -16,7 +16,9 @@ namespace NCpio { HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize) { - RINOK(ReadStream(m_Stream, data, size, &processedSize)); + size_t realProcessedSize = size; + RINOK(ReadStream(m_Stream, data, &realProcessedSize)); + processedSize = (UInt32)realProcessedSize; m_Position += processedSize; return S_OK; } @@ -240,8 +242,7 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item) } if (nameSize == 0 || nameSize >= (1 << 27)) return E_FAIL; - RINOK(ReadBytes(item.Name.GetBuffer(nameSize), - nameSize, processedSize)); + RINOK(ReadBytes(item.Name.GetBuffer(nameSize), nameSize, processedSize)); if (processedSize != nameSize) return E_FAIL; item.Name.ReleaseBuffer(); diff --git a/CPP/7zip/Archive/Deb/DebIn.cpp b/CPP/7zip/Archive/Deb/DebIn.cpp index c2221d12..41aaeb8a 100755 --- a/CPP/7zip/Archive/Deb/DebIn.cpp +++ b/CPP/7zip/Archive/Deb/DebIn.cpp @@ -15,22 +15,12 @@ namespace NDeb { using namespace NHeader; -HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize) -{ - RINOK(ReadStream(m_Stream, data, size, &processedSize)); - m_Position += processedSize; - return S_OK; -} - HRESULT CInArchive::Open(IInStream *inStream) { RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_Position)); char signature[kSignatureLen]; - UInt32 processedSize; - RINOK(ReadStream(inStream, signature, kSignatureLen, &processedSize)); - m_Position += processedSize; - if (processedSize != kSignatureLen) - return S_FALSE; + RINOK(ReadStream_FALSE(inStream, signature, kSignatureLen)); + m_Position += kSignatureLen; if (memcmp(signature, kSignature, kSignatureLen) != 0) return S_FALSE; m_Stream = inStream; @@ -100,10 +90,11 @@ HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item) char header[NHeader::kHeaderSize]; const char *cur = header; - UInt32 processedSize; + size_t processedSize = sizeof(header); item.HeaderPosition = m_Position; - RINOK(ReadBytes(header, sizeof(header), processedSize)); - if (processedSize < sizeof(header)) + RINOK(ReadStream(m_Stream, header, &processedSize)); + m_Position += processedSize; + if (processedSize != sizeof(header)) return S_OK; char tempString[kNameSize + 1]; diff --git a/CPP/7zip/Archive/Deb/DebIn.h b/CPP/7zip/Archive/Deb/DebIn.h index c1b72b6e..7d33fa59 100755 --- a/CPP/7zip/Archive/Deb/DebIn.h +++ b/CPP/7zip/Archive/Deb/DebIn.h @@ -15,7 +15,6 @@ class CInArchive CMyComPtr<IInStream> m_Stream; UInt64 m_Position; - HRESULT ReadBytes(void *data, UInt32 size, UInt32 &processedSize); HRESULT GetNextItemReal(bool &filled, CItemEx &itemInfo); HRESULT Skeep(UInt64 numBytes); public: diff --git a/CPP/7zip/Archive/GZip/GZipIn.cpp b/CPP/7zip/Archive/GZip/GZipIn.cpp index 44ed62f6..33b0ac47 100755 --- a/CPP/7zip/Archive/GZip/GZipIn.cpp +++ b/CPP/7zip/Archive/GZip/GZipIn.cpp @@ -20,11 +20,8 @@ namespace NGZip { HRESULT CInArchive::ReadBytes(ISequentialInStream *inStream, void *data, UInt32 size) { - UInt32 realProcessedSize; - RINOK(ReadStream(inStream, data, size, &realProcessedSize)); - m_Position += realProcessedSize; - if(realProcessedSize != size) - return S_FALSE; + RINOK(ReadStream_FALSE(inStream, data, size)); + m_Position += size; return S_OK; } diff --git a/CPP/7zip/Archive/GZip/GZipOut.cpp b/CPP/7zip/Archive/GZip/GZipOut.cpp index af01c79f..3d0d4f7a 100755 --- a/CPP/7zip/Archive/GZip/GZipOut.cpp +++ b/CPP/7zip/Archive/GZip/GZipOut.cpp @@ -12,11 +12,7 @@ namespace NGZip { HRESULT COutArchive::WriteBytes(const void *buffer, UInt32 size) { - UInt32 processedSize; - RINOK(WriteStream(m_Stream, buffer, size, &processedSize)); - if(processedSize != size) - return E_FAIL; - return S_OK; + return WriteStream(m_Stream, buffer, size); } HRESULT COutArchive::WriteByte(Byte value) diff --git a/CPP/7zip/Archive/Iso/IsoIn.cpp b/CPP/7zip/Archive/Iso/IsoIn.cpp index 213b3014..f4896d37 100755 --- a/CPP/7zip/Archive/Iso/IsoIn.cpp +++ b/CPP/7zip/Archive/Iso/IsoIn.cpp @@ -12,19 +12,14 @@ namespace NArchive { namespace NIso { -HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize) -{ - return ReadStream(_stream, data, size, &processedSize); -} - Byte CInArchive::ReadByte() { if (m_BufferPos >= BlockSize) m_BufferPos = 0; if (m_BufferPos == 0) { - UInt32 processedSize; - if (ReadBytes(m_Buffer, BlockSize, processedSize) != S_OK) + size_t processedSize = BlockSize; + if (ReadStream(_stream, m_Buffer, &processedSize) != S_OK) throw 1; if (processedSize != BlockSize) throw 1; @@ -192,7 +187,10 @@ 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; ReadDirRecord2(r, len); } diff --git a/CPP/7zip/Archive/Iso/IsoIn.h b/CPP/7zip/Archive/Iso/IsoIn.h index ab850bd9..4f9705c4 100755 --- a/CPP/7zip/Archive/Iso/IsoIn.h +++ b/CPP/7zip/Archive/Iso/IsoIn.h @@ -232,7 +232,6 @@ class CInArchive bool _bootIsDefined; CBootRecordDescriptor _bootDesc; - HRESULT ReadBytes(void *data, UInt32 size, UInt32 &processedSize); void Skeep(size_t size); void SkeepZeros(size_t size); Byte ReadByte(); diff --git a/CPP/7zip/Archive/Iso/IsoItem.h b/CPP/7zip/Archive/Iso/IsoItem.h index e899d616..fcb9531f 100755 --- a/CPP/7zip/Archive/Iso/IsoItem.h +++ b/CPP/7zip/Archive/Iso/IsoItem.h @@ -36,9 +36,9 @@ struct CRecordingDateTime if (!SystemTimeToFileTime(&st, &ft)) return false; UInt64 value = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime; - value += (UInt64)((Int64)(int)GmtOffset * 15 * 60); + value -= (UInt64)((Int64)GmtOffset * 15 * 60 * 10000000); ft.dwLowDateTime = (DWORD)value; - ft.dwHighDateTime = DWORD(value >> 32); + ft.dwHighDateTime = (DWORD)(value >> 32); return true; } }; diff --git a/CPP/7zip/Archive/Lzh/LzhIn.cpp b/CPP/7zip/Archive/Lzh/LzhIn.cpp index 9c531848..6783654c 100755 --- a/CPP/7zip/Archive/Lzh/LzhIn.cpp +++ b/CPP/7zip/Archive/Lzh/LzhIn.cpp @@ -14,7 +14,9 @@ namespace NLzh { HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize) { - RINOK(ReadStream(m_Stream, data, size, &processedSize)); + size_t realProcessedSize = size; + RINOK(ReadStream(m_Stream, data, &realProcessedSize)); + processedSize = (UInt32)realProcessedSize; m_Position += processedSize; return S_OK; } diff --git a/CPP/7zip/Archive/Lzma/LzmaArcRegister.cpp b/CPP/7zip/Archive/Lzma/LzmaArcRegister.cpp new file mode 100755 index 00000000..bbeb177b --- /dev/null +++ b/CPP/7zip/Archive/Lzma/LzmaArcRegister.cpp @@ -0,0 +1,14 @@ +// LzmaArcRegister.cpp + +#include "StdAfx.h" + +#include "../../Common/RegisterArc.h" + +#include "LzmaHandler.h" + +static IInArchive *CreateArc() { return new NArchive::NLzma::CHandler; } + +static CArcInfo g_ArcInfo = + { L"Lzma", L"lzma lzma86", 0, 0xA, {0 }, 0, true, CreateArc, NULL }; + +REGISTER_ARC(Lzma) diff --git a/CPP/7zip/Archive/Lzma/LzmaFiltersDecode.cpp b/CPP/7zip/Archive/Lzma/LzmaFiltersDecode.cpp new file mode 100755 index 00000000..d3450616 --- /dev/null +++ b/CPP/7zip/Archive/Lzma/LzmaFiltersDecode.cpp @@ -0,0 +1,86 @@ +// LzmaFiltersDecode.cpp + +#include "StdAfx.h" + +#include "LzmaFiltersDecode.h" + +namespace NArchive { +namespace NLzma { + +static const UInt64 k_LZMA = 0x030101; +static const UInt64 k_BCJ = 0x03030103; + +HRESULT CDecoder::Code( + DECL_EXTERNAL_CODECS_LOC_VARS + const CHeader &block, + ISequentialInStream *inStream, ISequentialOutStream *outStream, + UInt64 *inProcessedSize, ICompressProgressInfo *progress) +{ + *inProcessedSize = (UInt64)(Int64)-1; + + if (block.FilterMethod > 1) + return E_NOTIMPL; + + if (!_lzmaDecoder) + { + RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS k_LZMA, _lzmaDecoder, false)); + if (_lzmaDecoder == 0) + return E_NOTIMPL; + } + + { + CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties; + _lzmaDecoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties); + if (!setDecoderProperties) + return E_NOTIMPL; + RINOK(setDecoderProperties->SetDecoderProperties2(block.LzmaProps, 5)); + } + + bool filteredMode = (block.FilterMethod == 1); + + CMyComPtr<ICompressSetOutStream> setOutStream; + + if (filteredMode) + { + if (!_bcjStream) + { + CMyComPtr<ICompressCoder> coder; + RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS k_BCJ, coder, false)); + if (!coder) + return E_NOTIMPL; + coder.QueryInterface(IID_ISequentialOutStream, &_bcjStream); + if (!_bcjStream) + return E_NOTIMPL; + } + + _bcjStream.QueryInterface(IID_ICompressSetOutStream, &setOutStream); + if (!setOutStream) + return E_NOTIMPL; + RINOK(setOutStream->SetOutStream(outStream)); + outStream = _bcjStream; + } + + const UInt64 *unpackSize = block.HasUnpackSize() ? &block.UnpackSize : NULL; + RINOK(_lzmaDecoder->Code(inStream, outStream, NULL, unpackSize, progress)); + + if (filteredMode) + { + CMyComPtr<IOutStreamFlush> flush; + _bcjStream.QueryInterface(IID_IOutStreamFlush, &flush); + if (flush) + { + RINOK(flush->Flush()); + } + RINOK(setOutStream->ReleaseOutStream()); + } + + CMyComPtr<ICompressGetInStreamProcessedSize> getInStreamProcessedSize; + _lzmaDecoder.QueryInterface(IID_ICompressGetInStreamProcessedSize, &getInStreamProcessedSize); + if (getInStreamProcessedSize) + { + RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(inProcessedSize)); + } + return S_OK; +} + +}} diff --git a/CPP/7zip/Archive/Lzma/LzmaFiltersDecode.h b/CPP/7zip/Archive/Lzma/LzmaFiltersDecode.h new file mode 100755 index 00000000..a9f4927b --- /dev/null +++ b/CPP/7zip/Archive/Lzma/LzmaFiltersDecode.h @@ -0,0 +1,26 @@ +// LzmaFiltersDecode.h + +#ifndef __LZMA_FILTERS_DECODE_H +#define __LZMA_FILTERS_DECODE_H + +#include "../../Common/CreateCoder.h" + +#include "LzmaItem.h" + +namespace NArchive { +namespace NLzma { + +class CDecoder +{ + CMyComPtr<ICompressCoder> _lzmaDecoder; + CMyComPtr<ISequentialOutStream> _bcjStream; +public: + HRESULT Code(DECL_EXTERNAL_CODECS_LOC_VARS + const CHeader &block, + ISequentialInStream *inStream, ISequentialOutStream *outStream, + UInt64 *inProcessedSize, ICompressProgressInfo *progress); +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Lzma/LzmaHandler.cpp b/CPP/7zip/Archive/Lzma/LzmaHandler.cpp new file mode 100755 index 00000000..70126aa4 --- /dev/null +++ b/CPP/7zip/Archive/Lzma/LzmaHandler.cpp @@ -0,0 +1,243 @@ +// LzmaHandler.cpp + +#include "StdAfx.h" + +#include "LzmaHandler.h" + +#include "Common/Defs.h" +#include "Common/StringConvert.h" +#include "Common/ComTry.h" +#include "Common/IntToString.h" + +#include "Windows/PropVariant.h" + +#include "../../Common/ProgressUtils.h" +#include "../../Common/StreamUtils.h" +#include "../Common/DummyOutStream.h" + +#include "LzmaFiltersDecode.h" + +namespace NArchive { +namespace NLzma { + +STATPROPSTG kProps[] = +{ + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackedSize, VT_UI8}, + { NULL, kpidMethod, VT_UI1} +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = 1; + return S_OK; +} + +static void ConvertUInt32ToString(UInt32 value, wchar_t *s) +{ + ConvertUInt64ToString(value, s + MyStringLen(s)); +} + +static void DictSizeToString(UInt32 value, wchar_t *s) +{ + for (int i = 0; i <= 31; i++) + if ((UInt32(1) << i) == value) + { + ConvertUInt32ToString(i, s); + return; + } + wchar_t c = L'b'; + if ((value & ((1 << 20) - 1)) == 0) + { + value >>= 20; + c = L'm'; + } + else if ((value & ((1 << 10) - 1)) == 0) + { + value >>= 10; + c = L'k'; + } + ConvertUInt32ToString(value, s); + int p = MyStringLen(s); + s[p++] = c; + s[p++] = L'\0'; +} + +static void MyStrCat(wchar_t *d, const wchar_t *s) +{ + MyStringCopy(d + MyStringLen(d), s); +} + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + if (index != 0) + return E_INVALIDARG; + NWindows::NCOM::CPropVariant propVariant; + switch(propID) + { + case kpidSize: + if (m_StreamInfo.HasUnpackSize()) + propVariant = (UInt64)m_StreamInfo.UnpackSize; + break; + case kpidPackedSize: + propVariant = (UInt64)m_PackSize; + break; + case kpidMethod: + { + wchar_t s[64]; + s[0] = '\0'; + if (m_StreamInfo.IsThereFilter) + { + const wchar_t *f; + if (m_StreamInfo.FilterMethod == 0) + f = L"Copy"; + else if (m_StreamInfo.FilterMethod == 1) + f = L"BCJ"; + else + f = L"Unknown"; + MyStrCat(s, f); + MyStrCat(s, L" "); + } + MyStrCat(s, L"LZMA:"); + DictSizeToString(m_StreamInfo.GetDicSize(), s); + propVariant = s; + break; + } + } + propVariant.Detach(value); + return S_OK; +} + +STDMETHODIMP CHandler::Open(IInStream *inStream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback * /* openArchiveCallback */) +{ + { + RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_StreamStartPosition)); + + HRESULT res = ReadStreamHeader(inStream, m_StreamInfo); + if (res != S_OK) + return S_FALSE; + + Byte b; + RINOK(ReadStream_FALSE(inStream, &b, 1)); + if (b != 0) + return S_FALSE; + + UInt64 endPos; + RINOK(inStream->Seek(0, STREAM_SEEK_END, &endPos)); + m_PackSize = endPos - m_StreamStartPosition - m_StreamInfo.GetHeaderSize(); + + m_Stream = inStream; + } + return S_OK; +} + +STDMETHODIMP CHandler::Close() +{ + m_Stream.Release(); + 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) + { + if (numItems == 0) + return S_OK; + if (numItems != 1) + return E_INVALIDARG; + if (indices[0] != 0) + return E_INVALIDARG; + } + + bool testMode = (_aTestMode != 0); + + RINOK(extractCallback->SetTotal(m_PackSize)); + + UInt64 currentTotalPacked = 0; + + CDummyOutStream *outStreamSpec = new CDummyOutStream; + CMyComPtr<ISequentialOutStream> outStream(outStreamSpec); + + { + CMyComPtr<ISequentialOutStream> realOutStream; + Int32 askMode = testMode ? + NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + + RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); + + outStreamSpec->SetStream(realOutStream); + outStreamSpec->Init(); + if(!testMode && !realOutStream) + return S_OK; + extractCallback->PrepareOperation(askMode); + } + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr<ICompressProgressInfo> progress = lps; + lps->Init(extractCallback, true); + + CDecoder decoder; + RINOK(m_Stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL)); + UInt64 streamPos = m_StreamStartPosition; + Int32 opRes = NArchive::NExtract::NOperationResult::kOK; + bool firstItem = true; + for (;;) + { + CHeader st; + HRESULT result = ReadStreamHeader(m_Stream, st); + if (result != S_OK) + { + if (firstItem) + return E_FAIL; + break; + } + firstItem = false; + + lps->OutSize = outStreamSpec->GetSize(); + lps->InSize = currentTotalPacked; + RINOK(lps->SetCur()); + + streamPos += st.GetHeaderSize(); + UInt64 packProcessed; + + { + result = decoder.Code( + EXTERNAL_CODECS_VARS + st, m_Stream, outStream, &packProcessed, progress); + if (result == E_NOTIMPL) + { + opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + break; + } + if (result == S_FALSE) + { + opRes = NArchive::NExtract::NOperationResult::kDataError; + break; + } + RINOK(result); + } + + if (packProcessed == (UInt64)(Int64)-1) + break; + RINOK(m_Stream->Seek(streamPos + packProcessed, STREAM_SEEK_SET, NULL)); + currentTotalPacked += packProcessed; + streamPos += packProcessed; + } + outStream.Release(); + return extractCallback->SetOperationResult(opRes); + COM_TRY_END +} + +IMPL_ISetCompressCodecsInfo + +}} diff --git a/CPP/7zip/Archive/Lzma/LzmaHandler.h b/CPP/7zip/Archive/Lzma/LzmaHandler.h new file mode 100755 index 00000000..e4078309 --- /dev/null +++ b/CPP/7zip/Archive/Lzma/LzmaHandler.h @@ -0,0 +1,69 @@ +// Lzma/Handler.h + +#ifndef __GZIP_HANDLER_H +#define __GZIP_HANDLER_H + +#include "Common/MyCom.h" + +#include "../IArchive.h" +#include "../../Common/CreateCoder.h" + +#include "LzmaIn.h" + +namespace NArchive { +namespace NLzma { + +// const UInt64 k_LZMA = 0x030101; + +class CHandler: + public IInArchive, + PUBLIC_ISetCompressCodecsInfo + public CMyUnknownImp +{ +public: + MY_QUERYINTERFACE_BEGIN + MY_QUERYINTERFACE_ENTRY(IInArchive) + QUERY_ENTRY_ISetCompressCodecsInfo + MY_QUERYINTERFACE_END + MY_ADDREF_RELEASE + + STDMETHOD(Open)(IInStream *inStream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openArchiveCallback); + STDMETHOD(Close)(); + + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback); + + STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); + + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + UString GetMethodString(); +public: + CHandler() { } + +private: + CHeader m_StreamInfo; + UInt64 m_StreamStartPosition; + UInt64 m_PackSize; + + CMyComPtr<IInStream> m_Stream; + + DECL_EXTERNAL_CODECS_VARS + + DECL_ISetCompressCodecsInfo + +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Lzma/LzmaIn.cpp b/CPP/7zip/Archive/Lzma/LzmaIn.cpp new file mode 100755 index 00000000..342b01e1 --- /dev/null +++ b/CPP/7zip/Archive/Lzma/LzmaIn.cpp @@ -0,0 +1,56 @@ +// Archive/LzmaIn.cpp + +#include "StdAfx.h" + +#include "LzmaIn.h" + +#include "../../Common/StreamUtils.h" + +namespace NArchive { +namespace NLzma { + +static bool CheckDictSize(const Byte *p) +{ + UInt32 dicSize = GetUi32(p); + int i; + for (i = 1; i <= 30; i++) + if (dicSize == ((UInt32)2 << i) || dicSize == ((UInt32)3 << i)) + return true; + return false; +} + +HRESULT ReadStreamHeader(ISequentialInStream *inStream, CHeader &block) +{ + Byte sig[5 + 9]; + RINOK(ReadStream_FALSE(inStream, sig, 5 + 8)); + + const Byte kMaxProp0Val = 5 * 5 * 9 - 1; + if (sig[0] > kMaxProp0Val) + return S_FALSE; + + for (int i = 0; i < 5; i++) + block.LzmaProps[i] = sig[i]; + + block.IsThereFilter = false; + block.FilterMethod = 0; + + if (!CheckDictSize(sig + 1)) + { + if (sig[0] > 1 || sig[1] > kMaxProp0Val) + return S_FALSE; + block.IsThereFilter = true; + block.FilterMethod = sig[0]; + for (int i = 0; i < 5; i++) + block.LzmaProps[i] = sig[i + 1]; + if (!CheckDictSize(block.LzmaProps + 1)) + return S_FALSE; + RINOK(ReadStream_FALSE(inStream, sig + 5 + 8, 1)); + } + UInt32 unpOffset = 5 + (block.IsThereFilter ? 1 : 0); + block.UnpackSize = GetUi64(sig + unpOffset); + if (block.HasUnpackSize() && block.UnpackSize >= ((UInt64)1 << 56)) + return S_FALSE; + return S_OK; +} + +}} diff --git a/CPP/7zip/Archive/Lzma/LzmaIn.h b/CPP/7zip/Archive/Lzma/LzmaIn.h new file mode 100755 index 00000000..6f237f2d --- /dev/null +++ b/CPP/7zip/Archive/Lzma/LzmaIn.h @@ -0,0 +1,16 @@ +// Archive/LzmaIn.h + +#ifndef __ARCHIVE_LZMA_IN_H +#define __ARCHIVE_LZMA_IN_H + +#include "LzmaItem.h" +#include "../../IStream.h" + +namespace NArchive { +namespace NLzma { + +HRESULT ReadStreamHeader(ISequentialInStream *inStream, CHeader &st); + +}} + +#endif diff --git a/CPP/7zip/Archive/Lzma/LzmaItem.h b/CPP/7zip/Archive/Lzma/LzmaItem.h new file mode 100755 index 00000000..8fcae210 --- /dev/null +++ b/CPP/7zip/Archive/Lzma/LzmaItem.h @@ -0,0 +1,27 @@ +// Archive/LzmaItem.h + +#ifndef __ARCHIVE_LZMA_ITEM_H +#define __ARCHIVE_LZMA_ITEM_H + +#include "Common/Types.h" + +#include "../../../../C/CpuArch.h" + +namespace NArchive { +namespace NLzma { + +struct CHeader +{ + UInt64 UnpackSize; + bool IsThereFilter; + Byte FilterMethod; + Byte LzmaProps[5]; + + UInt32 GetDicSize() const { return GetUi32(LzmaProps + 1); } + bool HasUnpackSize() const { return (UnpackSize != (UInt64)(Int64)-1); } + unsigned GetHeaderSize() const { return 5 + 8 + (IsThereFilter ? 1 : 0); } +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Lzma/StdAfx.h b/CPP/7zip/Archive/Lzma/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Archive/Lzma/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Archive/Lzma/lzma.ico b/CPP/7zip/Archive/Lzma/lzma.ico Binary files differnew file mode 100755 index 00000000..1f4f754c --- /dev/null +++ b/CPP/7zip/Archive/Lzma/lzma.ico diff --git a/CPP/7zip/Archive/Nsis/NsisDecode.cpp b/CPP/7zip/Archive/Nsis/NsisDecode.cpp index b50ec5e0..7e126bd4 100755 --- a/CPP/7zip/Archive/Nsis/NsisDecode.cpp +++ b/CPP/7zip/Archive/Nsis/NsisDecode.cpp @@ -133,9 +133,9 @@ HRESULT CDecoder::Init( return S_OK; } -HRESULT CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) +HRESULT CDecoder::Read(void *data, size_t *processedSize) { - return ReadStream(_decoderInStream, data, size, processedSize);; + return ReadStream(_decoderInStream, data, processedSize);; } }} diff --git a/CPP/7zip/Archive/Nsis/NsisDecode.h b/CPP/7zip/Archive/Nsis/NsisDecode.h index 1a2fa41f..36aeb2b1 100755 --- a/CPP/7zip/Archive/Nsis/NsisDecode.h +++ b/CPP/7zip/Archive/Nsis/NsisDecode.h @@ -39,7 +39,7 @@ public: HRESULT Init( DECL_EXTERNAL_CODECS_LOC_VARS IInStream *inStream, NMethodType::EEnum method, bool thereIsFilterFlag, bool &useFilter); - HRESULT Read(void *data, UInt32 size, UInt32 *processedSize); + HRESULT Read(void *data, size_t *processedSize); }; }} diff --git a/CPP/7zip/Archive/Nsis/NsisHandler.cpp b/CPP/7zip/Archive/Nsis/NsisHandler.cpp index 62c7ab38..b24d966d 100755 --- a/CPP/7zip/Archive/Nsis/NsisHandler.cpp +++ b/CPP/7zip/Archive/Nsis/NsisHandler.cpp @@ -12,6 +12,7 @@ #include "Windows/PropVariant.h" #include "../Common/ItemNameUtils.h" +#include "../../Common/StreamUtils.h" using namespace NWindows; @@ -233,8 +234,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val { case kpidPath: { - const UString s = NItemName::WinNameToOSName(MultiByteToUnicodeString(item.GetReducedName(), CP_ACP)); - prop = (const wchar_t *)s; + UString s; + if (_archive.IsUnicode) + s = item.GetReducedNameU(); + else + s = MultiByteToUnicodeString(item.GetReducedNameA(), CP_ACP); + s = NItemName::WinNameToOSName(s); + if (!s.IsEmpty()) + prop = (const wchar_t *)s; break; } case kpidIsFolder: @@ -348,7 +355,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, continue; RINOK(extractCallback->PrepareOperation(askMode)); if (!testMode) - RINOK(realOutStream->Write((const char *)_archive.Script, (UInt32)_archive.Script.Length(), NULL)); + RINOK(WriteStream(realOutStream, (const char *)_archive.Script, (UInt32)_archive.Script.Length())); } else #endif @@ -379,9 +386,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, UInt64 pos = _archive.GetPosOfSolidItem(index); while(streamPos < pos) { - UInt32 curSize = (UInt32)MyMin(pos - streamPos, (UInt64)kBufferLength); - UInt32 processedSize; - HRESULT res = _archive.Decoder.Read(buffer, curSize, &processedSize); + size_t processedSize = (UInt32)MyMin(pos - streamPos, (UInt64)kBufferLength); + HRESULT res = _archive.Decoder.Read(buffer, &processedSize); if (res != S_OK) { if (res != S_FALSE) @@ -398,8 +404,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, } if (streamPos == pos) { - UInt32 processedSize; - RINOK(_archive.Decoder.Read(buffer, 4, &processedSize)); + size_t processedSize = 4; + RINOK(_archive.Decoder.Read(buffer, &processedSize)); if (processedSize != 4) return E_FAIL; streamPos += processedSize; @@ -433,8 +439,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, UInt32 curSize = kBufferLength; if (sizeIsKnown && curSize > fullSize) curSize = fullSize; - UInt32 processedSize; - HRESULT res = _archive.Decoder.Read(buffer, curSize, &processedSize); + size_t processedSize = curSize; + HRESULT res = _archive.Decoder.Read(buffer, &processedSize); if (res != S_OK) { if (res != S_FALSE) @@ -449,7 +455,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, break; } - fullSize -= processedSize; + fullSize -= (UInt32)processedSize; streamPos += processedSize; offset += processedSize; @@ -460,7 +466,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, completed = currentTotalSize + offset; RINOK(extractCallback->SetCompleted(&completed)); if (!testMode) - RINOK(realOutStream->Write(buffer, processedSize, NULL)); + RINOK(WriteStream(realOutStream, buffer, processedSize)); } } else @@ -478,7 +484,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, fullSize -= processedSize; streamPos += processedSize; if (!testMode) - RINOK(realOutStream->Write(buffer, processedSize, 0)); + RINOK(WriteStream(realOutStream, buffer, processedSize)); } } } diff --git a/CPP/7zip/Archive/Nsis/NsisIn.cpp b/CPP/7zip/Archive/Nsis/NsisIn.cpp index 83080448..5c5c872f 100755 --- a/CPP/7zip/Archive/Nsis/NsisIn.cpp +++ b/CPP/7zip/Archive/Nsis/NsisIn.cpp @@ -2,6 +2,8 @@ #include "StdAfx.h" +// #include <stdio.h> + #include "NsisIn.h" #include "NsisDecode.h" @@ -9,6 +11,7 @@ #include "../../Common/StreamUtils.h" +#include "Common/StringConvert.h" #include "Common/IntToString.h" namespace NArchive { @@ -27,6 +30,14 @@ public: static const char *kCrLf = "\x0D\x0A"; #endif +#define NS_UN_SKIP_CODE 0xE000 +#define NS_UN_VAR_CODE 0xE001 +#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); @@ -60,12 +71,20 @@ static int CompareItems(void *const *p1, void *const *p2, void * /* param */) const CItem &i1 = **(CItem **)p1; const CItem &i2 = **(CItem **)p2; RINOZ(MyCompare(i1.Pos, i2.Pos)); - RINOZ(i1.Prefix.Compare(i2.Prefix)); - RINOZ(i1.Name.Compare(i2.Name)); + if (i1.IsUnicode) + { + RINOZ(i1.PrefixU.Compare(i2.PrefixU)); + RINOZ(i1.NameU.Compare(i2.NameU)); + } + else + { + RINOZ(i1.PrefixA.Compare(i2.PrefixA)); + RINOZ(i1.NameA.Compare(i2.NameA)); + } return 0; } -AString CInArchive::ReadString(UInt32 pos) +AString CInArchive::ReadStringA(UInt32 pos) { AString s; UInt32 offset = GetOffset() + _stringsPos + pos; @@ -81,6 +100,24 @@ AString CInArchive::ReadString(UInt32 pos) return s; } +UString CInArchive::ReadStringU(UInt32 pos) +{ + UString s; + UInt32 offset = GetOffset() + _stringsPos + (pos * 2); + for (;;) + { + if (offset >= _size || offset + 1 >= _size) + throw 1; + char c0 = _data[offset++]; + char c1 = _data[offset++]; + wchar_t c = (c0 | ((wchar_t)c1 << 8)); + if (c == 0) + break; + s += c; + } + return s; +} + /* static AString ParsePrefix(const AString &prefix) { @@ -466,13 +503,27 @@ static AString GetVar(UInt32 index) return res; } -// $0..$9, $INSTDIR, etc are encoded as ASCII bytes starting from this value. #define NS_SKIP_CODE 252 #define NS_VAR_CODE 253 #define NS_SHELL_CODE 254 #define NS_LANG_CODE 255 #define NS_CODES_START NS_SKIP_CODE +static AString GetShellString(int index) +{ + AString res = "$"; + if (index < kNumShellStrings) + { + const char *sz = kShellStrings[index]; + if (sz[0] != 0) + return res + sz; + } + res += "SHELL["; + res += UIntToString(index); + res += "]"; + return res; +} + // Based on Dave Laundon's simplified process_string AString GetNsisString(const AString &s) { @@ -487,26 +538,7 @@ AString GetNsisString(const AString &s) nData |= (((int)(c1 & 0x7F)) << 7); if (nVarIdx == NS_SHELL_CODE) - { - UInt32 index = c1; - bool needPrint = true; - res += "$"; - if (index < kNumShellStrings) - { - const char *sz = kShellStrings[index]; - if (sz[0] != 0) - { - res += sz; - needPrint = false; - } - } - if (needPrint) - { - res += "SHELL["; - res += UIntToString(index); - res += "]"; - } - } + res += GetShellString(c1); else if (nVarIdx == NS_VAR_CODE) res += GetVar(nData); else if (nVarIdx == NS_LANG_CODE) @@ -523,9 +555,53 @@ AString GetNsisString(const AString &s) return res; } +UString GetNsisString(const UString &s) +{ + UString res; + for (int i = 0; i < s.Length();) + { + wchar_t nVarIdx = s[i++]; + if (nVarIdx > NS_UN_CODES_START && nVarIdx <= NS_UN_CODES_END) + { + if (i == s.Length()) + break; + int nData = s[i++] & 0x7FFF; + + if (nVarIdx == NS_UN_SHELL_CODE) + res += GetUnicodeString(GetShellString(nData >> 8)); + else if (nVarIdx == NS_UN_VAR_CODE) + res += GetUnicodeString(GetVar(nData)); + else if (nVarIdx == NS_UN_LANG_CODE) + res += L"NS_LANG_CODE"; + } + else if (nVarIdx == NS_UN_SKIP_CODE) + { + if (i == s.Length()) + break; + res += s[i++]; + } + else // Normal char + res += (char)nVarIdx; + } + return res; +} + +AString CInArchive::ReadString2A(UInt32 pos) +{ + return GetNsisString(ReadStringA(pos)); +} + +UString CInArchive::ReadString2U(UInt32 pos) +{ + return GetNsisString(ReadStringU(pos)); +} + AString CInArchive::ReadString2(UInt32 pos) { - return GetNsisString(ReadString(pos)); + if (IsUnicode) + return UnicodeStringToMultiByte(ReadString2U(pos)); + else + return ReadString2A(pos); } #define DEL_DIR 1 @@ -566,7 +642,8 @@ AString CEntry::GetParamsString(int numParams) HRESULT CInArchive::ReadEntries(const CBlockHeader &bh) { _posInData = bh.Offset + GetOffset(); - AString prefix; + AString prefixA; + UString prefixU; for (UInt32 i = 0; i < bh.Num; i++) { CEntry e; @@ -585,11 +662,22 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh) { case EW_CREATEDIR: { - prefix.Empty(); - prefix = ReadString2(e.Params[0]); + if (IsUnicode) + { + prefixU.Empty(); + prefixU = ReadString2U(e.Params[0]); + } + else + { + prefixA.Empty(); + prefixA = ReadString2A(e.Params[0]); + } #ifdef NSIS_SCRIPT Script += " "; - Script += prefix; + if (IsUnicode) + Script += UnicodeStringToMultiByte(prefixU); + else + Script += prefixA; #endif break; } @@ -597,9 +685,18 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh) case EW_EXTRACTFILE: { CItem item; - item.Prefix = prefix; + item.IsUnicode = IsUnicode; + if (IsUnicode) + { + item.PrefixU = prefixU; + item.NameU = ReadString2U(e.Params[1]); + } + else + { + item.PrefixA = prefixA; + item.NameA = ReadString2A(e.Params[1]); + } /* UInt32 overwriteFlag = e.Params[0]; */ - item.Name = ReadString2(e.Params[1]); item.Pos = e.Params[2]; item.DateTime.dwLowDateTime = e.Params[3]; item.DateTime.dwHighDateTime = e.Params[4]; @@ -614,7 +711,11 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh) Items.Add(item); #ifdef NSIS_SCRIPT Script += " "; - Script += item.Name; + + if (IsUnicode) + Script += UnicodeStringToMultiByte(item.NameU); + else + Script += item.NameA; #endif break; } @@ -908,7 +1009,10 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh) // if (IsSolid) for (i = 0; i + 1 < Items.Size();) { - if (Items[i].Pos == Items[i + 1].Pos && (IsSolid || Items[i].Name == Items[i + 1].Name)) + bool sameName = IsUnicode ? + (Items[i].NameU == Items[i + 1].NameU) : + (Items[i].NameA == Items[i + 1].NameA); + if (Items[i].Pos == Items[i + 1].Pos && (IsSolid || sameName)) Items.Delete(i + 1); else i++; @@ -927,8 +1031,8 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh) RINOK(_stream->Seek(GetPosOfNonSolidItem(i), STREAM_SEEK_SET, NULL)); const UInt32 kSigSize = 4 + 1 + 5; BYTE sig[kSigSize]; - UInt32 processedSize; - RINOK(ReadStream(_stream, sig, kSigSize, &processedSize)); + size_t processedSize = kSigSize; + RINOK(ReadStream(_stream, sig, &processedSize)); if (processedSize < 4) return S_FALSE; UInt32 size = GetUInt32FromMemLE(sig); @@ -977,7 +1081,37 @@ HRESULT CInArchive::Parse() ReadBlockHeader(bhData); _stringsPos = bhStrings.Offset; + UInt32 pos = GetOffset() + _stringsPos; + int numZeros0 = 0; + int numZeros1 = 0; + int i; + const kBlockSize = 256; + for (i = 0; i < kBlockSize; i++) + { + if (pos >= _size || pos + 1 >= _size) + break; + char c0 = _data[pos++]; + char c1 = _data[pos++]; + wchar_t c = (c0 | ((wchar_t)c1 << 8)); + if (c >= NS_UN_CODES_START && c < NS_UN_CODES_END) + { + if (pos >= _size || pos + 1 >= _size) + break; + pos += 2; + numZeros1++; + } + else + { + if (c0 == 0 && c1 != 0) + numZeros0++; + if (c1 == 0) + numZeros1++; + } + // printf("\nnumZeros0 = %2x %2x", _data[pos + 0], _data[pos + 1]); + } + IsUnicode = (numZeros1 > numZeros0 * 3 + kBlockSize / 16); + // printf("\nnumZeros0 = %3d numZeros1 = %3d", numZeros0, numZeros1); return ReadEntries(bhEntries); } @@ -1010,10 +1144,7 @@ HRESULT CInArchive::Open2( const UInt32 kSigSize = 4 + 1 + 5 + 1; // size, flag, lzma props, lzma first byte BYTE sig[kSigSize]; - UInt32 processedSize; - RINOK(ReadStream(_stream, sig, kSigSize, &processedSize)); - if (processedSize != kSigSize) - return S_FALSE; + RINOK(ReadStream_FALSE(_stream, sig, kSigSize)); UInt64 position; RINOK(_stream->Seek(StreamOffset, STREAM_SEEK_SET, &position)); @@ -1065,11 +1196,11 @@ HRESULT CInArchive::Open2( RINOK(Decoder.Init( EXTERNAL_CODECS_LOC_VARS _stream, Method, FilterFlag, UseFilter)); - UInt32 processedSize; - RINOK(Decoder.Read(_data, unpackSize, &processedSize)); + size_t processedSize = unpackSize; + RINOK(Decoder.Read(_data, &processedSize)); if (processedSize != unpackSize) return S_FALSE; - _size = (size_t)processedSize; + _size = processedSize; if (IsSolid) { UInt32 size2 = ReadUInt32(); @@ -1081,9 +1212,7 @@ HRESULT CInArchive::Open2( { _data.SetCapacity(unpackSize); _size = (size_t)unpackSize; - RINOK(ReadStream(_stream, (Byte *)_data, unpackSize, &processedSize)); - if (processedSize != unpackSize) - return S_FALSE; + RINOK(ReadStream_FALSE(_stream, (Byte *)_data, unpackSize)); } return Parse(); } @@ -1138,22 +1267,17 @@ HRESULT CInArchive::Open( UInt64 headerPosition = 0; while (position <= maxSize) { - UInt32 processedSize; - RINOK(ReadStream(inStream, buffer, kStartHeaderSize, &processedSize)); - if (processedSize != kStartHeaderSize) - return S_FALSE; + RINOK(ReadStream_FALSE(inStream, buffer, kStartHeaderSize)); headerPosition = position; - position += processedSize; + position += kStartHeaderSize; if(memcmp(buffer + 4, kSignature, kSignatureSize) == 0) { found = true; break; } const UInt32 kRem = kStep - kStartHeaderSize; - RINOK(ReadStream(inStream, buffer + kStartHeaderSize, kRem, &processedSize)); - if (processedSize != kRem) - return S_FALSE; - position += processedSize; + RINOK(ReadStream_FALSE(inStream, buffer + kStartHeaderSize, kRem)); + position += kRem; } if (!found) return S_FALSE; diff --git a/CPP/7zip/Archive/Nsis/NsisIn.h b/CPP/7zip/Archive/Nsis/NsisIn.h index 22c050f1..e7908862 100755 --- a/CPP/7zip/Archive/Nsis/NsisIn.h +++ b/CPP/7zip/Archive/Nsis/NsisIn.h @@ -56,41 +56,56 @@ struct CBlockHeader struct CItem { - AString Prefix; - AString Name; - UInt32 Pos; + AString PrefixA; + UString PrefixU; + AString NameA; + UString NameU; + FILETIME DateTime; + bool IsUnicode; + bool UseFilter; + bool IsCompressed; bool SizeIsDefined; bool CompressedSizeIsDefined; bool EstimatedSizeIsDefined; + UInt32 Pos; UInt32 Size; UInt32 CompressedSize; UInt32 EstimatedSize; - FILETIME DateTime; UInt32 DictionarySize; - bool IsCompressed; - bool UseFilter; - CItem(): UseFilter(false), SizeIsDefined(false), EstimatedSizeIsDefined(false), - IsCompressed(true), CompressedSizeIsDefined(false), Size(0) {} + + CItem(): IsUnicode(false), UseFilter(false), IsCompressed(true), SizeIsDefined(false), + CompressedSizeIsDefined(false), EstimatedSizeIsDefined(false), Size(0) {} bool IsINSTDIR() const { - if (Prefix.Length() < 3) - return false; - return true; + return (PrefixA.Length() >= 3 || PrefixU.Length() >= 3); } - AString GetReducedName() const + AString GetReducedNameA() const { - AString prefix = Prefix; + AString prefix = PrefixA; if (prefix.Length() > 0) if (prefix[prefix.Length() - 1] != '\\') prefix += '\\'; - AString s2 = prefix + Name; + AString s2 = prefix + NameA; const int len = 9; if (s2.Left(len).CompareNoCase("$INSTDIR\\") == 0) s2 = s2.Mid(len); return s2; } + + UString GetReducedNameU() const + { + UString prefix = PrefixU; + if (prefix.Length() > 0) + if (prefix[prefix.Length() - 1] != L'\\') + prefix += L'\\'; + UString s2 = prefix + NameU; + const int len = 9; + if (s2.Left(len).CompareNoCase(L"$INSTDIR\\") == 0) + s2 = s2.Mid(len); + return s2; + } }; @@ -105,7 +120,10 @@ class CInArchive DECL_EXTERNAL_CODECS_LOC_VARS2 ); void ReadBlockHeader(CBlockHeader &bh); - AString ReadString(UInt32 pos); + AString ReadStringA(UInt32 pos); + UString ReadStringU(UInt32 pos); + AString ReadString2A(UInt32 pos); + UString ReadString2U(UInt32 pos); AString ReadString2(UInt32 pos); HRESULT ReadEntries(const CBlockHeader &bh); HRESULT Parse(); @@ -129,12 +147,13 @@ public: UInt64 StreamOffset; CDecoder Decoder; CObjectVector<CItem> Items; - bool IsSolid; CFirstHeader FirstHeader; NMethodType::EEnum Method; - bool UseFilter; UInt32 DictionarySize; + bool IsSolid; + bool UseFilter; bool FilterFlag; + bool IsUnicode; #ifdef NSIS_SCRIPT AString Script; diff --git a/CPP/7zip/Archive/RPM/RpmHandler.cpp b/CPP/7zip/Archive/RPM/RpmHandler.cpp index 7cd881a1..9a9f9af4 100755 --- a/CPP/7zip/Archive/RPM/RpmHandler.cpp +++ b/CPP/7zip/Archive/RPM/RpmHandler.cpp @@ -5,20 +5,15 @@ #include "RpmHandler.h" #include "RpmIn.h" -#include "Common/Defs.h" -#include "Common/StringConvert.h" -#include "Common/NewHandler.h" #include "Common/ComTry.h" +#include "Common/MyString.h" #include "Windows/PropVariant.h" -#include "Windows/Defs.h" -#include "../../Common/StreamObjects.h" #include "../../Common/ProgressUtils.h" -#include "../../Common/LimitedStreams.h" +#include "../../Common/StreamUtils.h" #include "../../Compress/Copy/CopyCoder.h" -#include "../Common/ItemNameUtils.h" using namespace NWindows; @@ -44,10 +39,14 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, if(OpenArchive(inStream) != S_OK) return S_FALSE; RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_Pos)); - m_InStream = inStream; 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(...) @@ -78,6 +77,21 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIAN 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; diff --git a/CPP/7zip/Archive/RPM/RpmHandler.h b/CPP/7zip/Archive/RPM/RpmHandler.h index c78e8ce3..92efc107 100755 --- a/CPP/7zip/Archive/RPM/RpmHandler.h +++ b/CPP/7zip/Archive/RPM/RpmHandler.h @@ -22,6 +22,7 @@ private: CMyComPtr<IInStream> m_InStream; UInt64 m_Pos; UInt64 m_Size; + Byte _sig[4]; }; }} diff --git a/CPP/7zip/Archive/RPM/RpmIn.cpp b/CPP/7zip/Archive/RPM/RpmIn.cpp index c1600894..db7a6f63 100755 --- a/CPP/7zip/Archive/RPM/RpmIn.cpp +++ b/CPP/7zip/Archive/RPM/RpmIn.cpp @@ -32,10 +32,7 @@ static HRESULT RedSigHeaderSig(IInStream *inStream, CSigHeaderSig &h) { char dat[kCSigHeaderSigSize]; char *cur = dat; - UInt32 processedSize; - RINOK(ReadStream(inStream, dat, kCSigHeaderSigSize, &processedSize)); - if (kCSigHeaderSigSize != processedSize) - return S_FALSE; + RINOK(ReadStream_FALSE(inStream, dat, kCSigHeaderSigSize)); memmove(h.Magic, cur, 4); cur += 4; cur += 4; @@ -51,10 +48,7 @@ HRESULT OpenArchive(IInStream *inStream) char leadData[kLeadSize]; char *cur = leadData; CLead lead; - UInt32 processedSize; - RINOK(ReadStream(inStream, leadData, kLeadSize, &processedSize)); - if (kLeadSize != processedSize) - return S_FALSE; + RINOK(ReadStream_FALSE(inStream, leadData, kLeadSize)); memmove(lead.Magic, cur, 4); cur += 4; lead.Major = *cur++; diff --git a/CPP/7zip/Archive/RPM/RpmRegister.cpp b/CPP/7zip/Archive/RPM/RpmRegister.cpp index 76eb2470..61082bac 100755 --- a/CPP/7zip/Archive/RPM/RpmRegister.cpp +++ b/CPP/7zip/Archive/RPM/RpmRegister.cpp @@ -8,6 +8,6 @@ static IInArchive *CreateArc() { return new NArchive::NRpm::CHandler; } static CArcInfo g_ArcInfo = - { L"Rpm", L"rpm", L".cpio.gz", 0xEB, { 0}, 0, false, CreateArc, 0 }; + { L"Rpm", L"rpm", 0, 0xEB, { 0}, 0, false, CreateArc, 0 }; REGISTER_ARC(Rpm) diff --git a/CPP/7zip/Archive/Rar/RarHandler.cpp b/CPP/7zip/Archive/Rar/RarHandler.cpp index fd0952d1..435c5c17 100755 --- a/CPP/7zip/Archive/Rar/RarHandler.cpp +++ b/CPP/7zip/Archive/Rar/RarHandler.cpp @@ -167,7 +167,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va case kpidIsFolder: prop = item.IsDirectory(); break; case kpidSize: prop = item.UnPackSize; break; case kpidPackedSize: prop = GetPackSize(index); break; - case kpidLastWriteTime: RarTimeToProp(item.LastWriteTime, prop); + 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; @@ -243,6 +243,17 @@ public: { _afterPart = L".rar"; basePart = name.Left(dotPos); + } + else if (!_newStyle) + { + if (ext.CompareNoCase(L"000") == 0 || ext.CompareNoCase(L"001") == 0) + { + _afterPart.Empty(); + _first = false; + _changedPart = ext; + _unchangedPart = name.Left(dotPos + 1); + return true; + } } } diff --git a/CPP/7zip/Archive/Rar/RarIn.cpp b/CPP/7zip/Archive/Rar/RarIn.cpp index 0af72a48..efb87fb7 100755 --- a/CPP/7zip/Archive/Rar/RarIn.cpp +++ b/CPP/7zip/Archive/Rar/RarIn.cpp @@ -118,9 +118,7 @@ bool CInArchive::ReadBytesAndTestSize(void *data, UInt32 size) ((Byte *)data)[i] = bufData[m_CryptoPos++]; return (i == size); } - UInt32 processedSize; - ReadStream(m_Stream, data, size, &processedSize); - return (processedSize == size); + return (ReadStream_FALSE(m_Stream, data, size) == S_OK); } void CInArchive::ReadBytesAndTestResult(void *data, UInt32 size) @@ -131,10 +129,10 @@ void CInArchive::ReadBytesAndTestResult(void *data, UInt32 size) HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize) { - UInt32 realProcessedSize; - HRESULT result = ReadStream(m_Stream, data, size, &realProcessedSize); - if(processedSize != NULL) - *processedSize = realProcessedSize; + size_t realProcessedSize = size; + HRESULT result = ReadStream(m_Stream, data, &realProcessedSize); + if (processedSize != NULL) + *processedSize = (UInt32)realProcessedSize; AddToSeekValue(realProcessedSize); return result; } @@ -465,7 +463,9 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa m_DecryptedData.SetCapacity(kDecryptedBufferSize); } RINOK(m_RarAES->Init()); - RINOK(ReadStream(m_Stream, (Byte *)m_DecryptedData, kDecryptedBufferSize, &m_DecryptedDataSize)); + size_t decryptedDataSizeT = kDecryptedBufferSize; + RINOK(ReadStream(m_Stream, (Byte *)m_DecryptedData, &decryptedDataSizeT)); + m_DecryptedDataSize = (UInt32)decryptedDataSizeT; m_DecryptedDataSize = m_RarAES->Filter((Byte *)m_DecryptedData, m_DecryptedDataSize); m_CryptoMode = true; @@ -529,11 +529,6 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa } } -void CInArchive::DirectGetBytes(void *data, UInt32 size) -{ - ReadStream(m_Stream, data, size, NULL); -} - bool CInArchive::SeekInArchive(UInt64 position) { UInt64 newPosition; diff --git a/CPP/7zip/Archive/Rar/RarIn.h b/CPP/7zip/Archive/Rar/RarIn.h index f1dee321..94cea223 100755 --- a/CPP/7zip/Archive/Rar/RarIn.h +++ b/CPP/7zip/Archive/Rar/RarIn.h @@ -112,8 +112,6 @@ public: void GetArchiveInfo(CInArchiveInfo &archiveInfo) const; - void DirectGetBytes(void *data, UInt32 size); - bool SeekInArchive(UInt64 position); ISequentialInStream *CreateLimitedStream(UInt64 position, UInt64 size); }; diff --git a/CPP/7zip/Archive/Tar/TarHeader.h b/CPP/7zip/Archive/Tar/TarHeader.h index 0ab31e52..19bb1cac 100755 --- a/CPP/7zip/Archive/Tar/TarHeader.h +++ b/CPP/7zip/Archive/Tar/TarHeader.h @@ -75,6 +75,15 @@ namespace NFileHeader const char kDirectory = '5'; // Directory const char kFIFO = '6'; // FIFO special file const char kContiguous = '7'; // Contiguous file + + 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 + the last file name. */ + } // Further link types may be defined later. diff --git a/CPP/7zip/Archive/Tar/TarIn.cpp b/CPP/7zip/Archive/Tar/TarIn.cpp index bae1db86..1318613a 100755 --- a/CPP/7zip/Archive/Tar/TarIn.cpp +++ b/CPP/7zip/Archive/Tar/TarIn.cpp @@ -13,9 +13,10 @@ namespace NArchive { namespace NTar { -HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize) +HRESULT CInArchive::ReadBytes(void *data, size_t size, size_t &processedSize) { - RINOK(ReadStream(m_Stream, data, size, &processedSize)); + processedSize = size; + RINOK(ReadStream(m_Stream, data, &processedSize)); m_Position += processedSize; return S_OK; } @@ -93,7 +94,7 @@ HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item) filled = false; - UInt32 processedSize; + size_t processedSize; item.HeaderPosition = m_Position; RINOK(ReadBytes(record, NFileHeader::kRecordSize, processedSize)); if (processedSize == 0 || @@ -174,7 +175,8 @@ HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item) AString prefix; ReadString(cur, NFileHeader::kPrefixSize, prefix); cur += NFileHeader::kPrefixSize; - if (!prefix.IsEmpty() && item.IsMagic()) + if (!prefix.IsEmpty() && item.IsMagic() && + (item.LinkFlag != 'L' /* || prefix != "00000000000" */ )) item.Name = prefix + AString('/') + item.Name; if (item.LinkFlag == NFileHeader::NLinkFlag::kLink) @@ -205,10 +207,12 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item) return S_FALSE; UInt64 headerPosition = item.HeaderPosition; - UInt32 processedSize; + size_t processedSize; AString fullName; - char *buffer = fullName.GetBuffer((UInt32)item.Size + 1); - RINOK(ReadBytes(buffer, (UInt32)item.Size, processedSize)); + if (item.Size > (1 << 15)) + return S_FALSE; + char *buffer = fullName.GetBuffer((int)item.Size + 1); + RINOK(ReadBytes(buffer, (size_t)item.Size, processedSize)); buffer[item.Size] = '\0'; fullName.ReleaseBuffer(); if (processedSize != item.Size) @@ -224,6 +228,11 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item) // pax Extended Header return S_OK; } + else if (item.LinkFlag == NFileHeader::NLinkFlag::kDumpDir) + { + // GNU Extensions to the Archive Format + return S_OK; + } else if (item.LinkFlag > '7' || (item.LinkFlag < '0' && item.LinkFlag != 0)) return S_FALSE; return S_OK; diff --git a/CPP/7zip/Archive/Tar/TarIn.h b/CPP/7zip/Archive/Tar/TarIn.h index 28781375..20c030ef 100755 --- a/CPP/7zip/Archive/Tar/TarIn.h +++ b/CPP/7zip/Archive/Tar/TarIn.h @@ -16,7 +16,7 @@ class CInArchive CMyComPtr<IInStream> m_Stream; UInt64 m_Position; - HRESULT ReadBytes(void *data, UInt32 size, UInt32 &processedSize); + HRESULT ReadBytes(void *data, size_t size, size_t &processedSize); public: HRESULT Open(IInStream *inStream); HRESULT GetNextItemReal(bool &filled, CItemEx &itemInfo); diff --git a/CPP/7zip/Archive/Tar/TarItem.h b/CPP/7zip/Archive/Tar/TarItem.h index 10b57cd0..451d74bc 100755 --- a/CPP/7zip/Archive/Tar/TarItem.h +++ b/CPP/7zip/Archive/Tar/TarItem.h @@ -35,16 +35,18 @@ public: UInt32 DeviceMinor; bool IsDirectory() const - { - if (LinkFlag == NFileHeader::NLinkFlag::kDirectory) + { + switch(LinkFlag) + { + case NFileHeader::NLinkFlag::kDirectory: + case NFileHeader::NLinkFlag::kDumpDir: return true; - if (LinkFlag == NFileHeader::NLinkFlag::kOldNormal || - LinkFlag == NFileHeader::NLinkFlag::kNormal) - { + case NFileHeader::NLinkFlag::kOldNormal: + case NFileHeader::NLinkFlag::kNormal: return NItemName::HasTailSlash(Name, CP_OEMCP); - } - return false; } + return false; + } bool IsMagic() const { diff --git a/CPP/7zip/Archive/Tar/TarOut.cpp b/CPP/7zip/Archive/Tar/TarOut.cpp index e278edda..a697b4d2 100755 --- a/CPP/7zip/Archive/Tar/TarOut.cpp +++ b/CPP/7zip/Archive/Tar/TarOut.cpp @@ -14,11 +14,7 @@ namespace NTar { HRESULT COutArchive::WriteBytes(const void *buffer, UInt32 size) { - UInt32 processedSize; - RINOK(WriteStream(m_Stream, buffer, size, &processedSize)); - if(processedSize != size) - return E_FAIL; - return S_OK; + return WriteStream(m_Stream, buffer, size); } void COutArchive::Create(ISequentialOutStream *outStream) diff --git a/CPP/7zip/Archive/Wim/WimHandler.cpp b/CPP/7zip/Archive/Wim/WimHandler.cpp index 38c1c6ae..baa2c824 100755 --- a/CPP/7zip/Archive/Wim/WimHandler.cpp +++ b/CPP/7zip/Archive/Wim/WimHandler.cpp @@ -76,7 +76,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) { UInt16 volIndex = m_Xmls[0].VolIndex; if (volIndex < m_Volumes.Size()) - prop = m_Volumes[volIndex].Header.PartNumber; + prop = (UInt32)m_Volumes[volIndex].Header.PartNumber; } break; case kpidNumVolumes: if (m_Volumes.Size() > 0) prop = (UInt32)(m_Volumes.Size() - 1); @@ -413,7 +413,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, currentItemUnPacked = data.GetCapacity(); if (realOutStream) { - RINOK(WriteStream(realOutStream, (const Byte *)data, (UInt32)data.GetCapacity(), NULL)); + RINOK(WriteStream(realOutStream, (const Byte *)data, data.GetCapacity())); realOutStream.Release(); } RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); diff --git a/CPP/7zip/Archive/Wim/WimIn.cpp b/CPP/7zip/Archive/Wim/WimIn.cpp index 951fc79b..e9efdaa4 100755 --- a/CPP/7zip/Archive/Wim/WimIn.cpp +++ b/CPP/7zip/Archive/Wim/WimIn.cpp @@ -21,27 +21,10 @@ namespace NWim{ static const int kChunkSizeBits = 15; static const UInt32 kChunkSize = (1 << kChunkSizeBits); -static HRESULT ReadBytes(ISequentialInStream *inStream, void *data, UInt32 size) -{ - UInt32 realProcessedSize; - RINOK(ReadStream(inStream, data, size, &realProcessedSize)); - return (realProcessedSize == size) ? S_OK : S_FALSE; -} - -#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 UInt16 GetUInt16FromMem(const Byte *p) { return p[0] | ((UInt16)p[1] << 8); } -static UInt32 GetUInt32FromMem(const Byte *p) { return p[0] | ((UInt32)p[1] << 8) | ((UInt32)p[2] << 16) | ((UInt32)p[3] << 24); } -static UInt64 GetUInt64FromMem(const Byte *p) { return GetUInt32FromMem(p) | ((UInt64)GetUInt32FromMem(p + 4) << 32); } -#endif - static void GetFileTimeFromMem(const Byte *p, FILETIME *ft) { - ft->dwLowDateTime = GetUInt32FromMem(p); - ft->dwHighDateTime = GetUInt32FromMem(p + 4); + ft->dwLowDateTime = GetUi32(p); + ft->dwHighDateTime = GetUi32(p + 4); } HRESULT CUnpacker::Unpack(IInStream *inStream, const CResource &resource, @@ -70,7 +53,7 @@ HRESULT CUnpacker::Unpack(IInStream *inStream, const CResource &resource, UInt64 numChunks = (resource.UnpackSize + kChunkSize - 1) >> kChunkSizeBits; unsigned entrySize = ((resource.UnpackSize > (UInt64)1 << 32) ? 8 : 4); UInt64 sizesBufSize64 = entrySize * (numChunks - 1); - UInt32 sizesBufSize = (UInt32)sizesBufSize64; + size_t sizesBufSize = (size_t)sizesBufSize64; if (sizesBufSize != sizesBufSize64) return E_OUTOFMEMORY; if (sizesBufSize > sizesBuf.GetCapacity()) @@ -78,7 +61,7 @@ HRESULT CUnpacker::Unpack(IInStream *inStream, const CResource &resource, sizesBuf.Free(); sizesBuf.SetCapacity(sizesBufSize); } - RINOK(ReadBytes(inStream, (Byte *)sizesBuf, sizesBufSize)); + RINOK(ReadStream_FALSE(inStream, (Byte *)sizesBuf, sizesBufSize)); const Byte *p = (const Byte *)sizesBuf; if (!lzxDecoder) @@ -96,17 +79,17 @@ HRESULT CUnpacker::Unpack(IInStream *inStream, const CResource &resource, if (i > 0) { if (entrySize == 4) - offset = GetUInt32FromMem(p); + offset = GetUi32(p); else - offset = GetUInt64FromMem(p); + offset = GetUi64(p); p += entrySize; } UInt64 nextOffset = resource.PackSize - sizesBufSize64; if (i + 1 < (UInt32)numChunks) if (entrySize == 4) - nextOffset = GetUInt32FromMem(p); + nextOffset = GetUi32(p); else - nextOffset = GetUInt64FromMem(p); + nextOffset = GetUi64(p); if (nextOffset < offset) return S_FALSE; @@ -166,16 +149,16 @@ static const Byte kSignature[kSignatureSize] = { 'M', 'S', 'W', 'I', 'M', 0, 0, static void GetResource(const Byte *p, CResource &res) { res.Flags = p[7]; - res.PackSize = GetUInt64FromMem(p) & (((UInt64)1 << 56) - 1); - res.Offset = GetUInt64FromMem(p + 8); - res.UnpackSize = GetUInt64FromMem(p + 16); + res.PackSize = GetUi64(p) & (((UInt64)1 << 56) - 1); + res.Offset = GetUi64(p + 8); + res.UnpackSize = GetUi64(p + 16); } static void GetStream(const Byte *p, CStreamInfo &s) { GetResource(p, s.Resource); - s.PartNumber = GetUInt16FromMem(p + 24); - s.RefCount = GetUInt32FromMem(p + 26); + s.PartNumber = GetUi16(p + 24); + s.RefCount = GetUi32(p + 26); memcpy(s.Hash, p + 30, kHashSize); } @@ -187,22 +170,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 = GetUInt64FromMem(p); + UInt64 length = GetUi64(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 = GetUInt32FromMem(p + 8); - // item.SecurityId = GetUInt32FromMem(p + 0xC); - UInt64 subdirOffset = GetUInt64FromMem(p + 0x10); + 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); memcpy(item.Hash, p + 0x40, kHashSize); - // UInt16 shortNameLen = GetUInt16FromMem(p + 98); - UInt16 fileNameLen = GetUInt16FromMem(p + 100); + // UInt16 shortNameLen = GetUi16(p + 98); + UInt16 fileNameLen = GetUi16(p + 100); size_t tempPos = pos + 102; if (tempPos + fileNameLen > size) @@ -212,7 +195,7 @@ 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++ = GetUInt16FromMem(base + tempPos + i); + *sz++ = GetUi16(base + tempPos + i); *sz++ = '\0'; item.Name.ReleaseBuffer(); if (fileNameLen == 0 && item.IsDirectory() && !item.HasStream()) @@ -238,8 +221,8 @@ static HRESULT ParseDir(const Byte *base, size_t size, if (pos + 8 > size) return S_FALSE; const Byte *p = base + pos; - UInt32 totalLength = GetUInt32FromMem(p); - // UInt32 numEntries = GetUInt32FromMem(p + 4); + UInt32 totalLength = GetUi32(p); + // UInt32 numEntries = GetUi32(p + 4); pos += 8; { /* @@ -249,7 +232,7 @@ static HRESULT ParseDir(const Byte *base, size_t size, { if (pos + 8 > size) return S_FALSE; - UInt64 len = GetUInt64FromMem(p + pos); + UInt64 len = GetUi64(p + pos); entryLens.Add(len); sum += len; pos += 8; @@ -322,25 +305,25 @@ HRESULT ReadHeader(IInStream *inStream, CHeader &h) { const UInt32 kHeaderSizeMax = 0xD0; Byte p[kHeaderSizeMax]; - RINOK(ReadBytes(inStream, p, kHeaderSizeMax)); - UInt32 haderSize = GetUInt32FromMem(p + 8); + RINOK(ReadStream_FALSE(inStream, p, kHeaderSizeMax)); + UInt32 haderSize = GetUi32(p + 8); if (memcmp(p, kSignature, kSignatureSize) != 0) return S_FALSE; if (haderSize < 0x74) return S_FALSE; - h.Version = GetUInt32FromMem(p + 0x0C); - h.Flags = GetUInt32FromMem(p + 0x10); + h.Version = GetUi32(p + 0x0C); + h.Flags = GetUi32(p + 0x10); if (!h.IsSupported()) return S_FALSE; - if (GetUInt32FromMem(p + 0x14) != kChunkSize) + if (GetUi32(p + 0x14) != kChunkSize) return S_FALSE; memcpy(h.Guid, p + 0x18, 16); - h.PartNumber = GetUInt16FromMem(p + 0x28); - h.NumParts = GetUInt16FromMem(p + 0x2A); + h.PartNumber = GetUi16(p + 0x28); + h.NumParts = GetUi16(p + 0x2A); int offset = 0x2C; if (h.IsNewVersion()) { - h.NumImages = GetUInt32FromMem(p + offset); + h.NumImages = GetUi32(p + offset); offset += 4; } GetResource(p + offset, h.OffsetResource); @@ -352,7 +335,7 @@ HRESULT ReadHeader(IInStream *inStream, CHeader &h) if (haderSize < 0xD0) return S_FALSE; GetResource(p + offset + 0x4C, h.IntegrityResource); - h.BootIndex = GetUInt32FromMem(p + 0x48); + h.BootIndex = GetUi32(p + 0x48); } */ return S_OK; diff --git a/CPP/7zip/Archive/Z/ZHandler.cpp b/CPP/7zip/Archive/Z/ZHandler.cpp index 73f391f7..81289050 100755 --- a/CPP/7zip/Archive/Z/ZHandler.cpp +++ b/CPP/7zip/Archive/Z/ZHandler.cpp @@ -55,10 +55,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream, { RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_streamStartPosition)); Byte buffer[kSignatureSize]; - UInt32 processedSize; - RINOK(ReadStream(stream, buffer, kSignatureSize, &processedSize)); - if (processedSize != kSignatureSize) - return S_FALSE; + RINOK(ReadStream_FALSE(stream, buffer, kSignatureSize)); if (buffer[0] != 0x1F || buffer[1] != 0x9D) return S_FALSE; _properties = buffer[2]; diff --git a/CPP/7zip/Archive/Zip/ZipAddCommon.cpp b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp index 0344f776..0f76b04a 100755 --- a/CPP/7zip/Archive/Zip/ZipAddCommon.cpp +++ b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp @@ -43,7 +43,7 @@ static HRESULT GetStreamCRC(ISequentialInStream *inStream, UInt32 &resultCRC) resultCRC = CRC_GET_DIGEST(crc); return S_OK; } - crc = CrcUpdate(crc, buffer, realProcessedSize); + crc = CrcUpdate(crc, buffer, (size_t)realProcessedSize); } } diff --git a/CPP/7zip/Archive/Zip/ZipHandler.cpp b/CPP/7zip/Archive/Zip/ZipHandler.cpp index c3576eeb..7d478a36 100755 --- a/CPP/7zip/Archive/Zip/ZipHandler.cpp +++ b/CPP/7zip/Archive/Zip/ZipHandler.cpp @@ -81,6 +81,9 @@ STATPROPSTG kProps[] = { 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, kpidEncrypted, VT_BOOL}, @@ -150,17 +153,18 @@ CHandler::CHandler(): InitMethodProperties(); } -static void StringToProp(const CByteBuffer &data, UINT codePage, NWindows::NCOM::CPropVariant &prop) +static AString BytesToString(const CByteBuffer &data) { - int size = (int)data.GetCapacity(); - if (size <= 0) - return; AString s; - char *p = s.GetBuffer(size + 1); - memcpy(p, (const Byte *)data, size); - p[size] = '\0'; - s.ReleaseBuffer(); - prop = MultiByteToUnicodeString(s, codePage); + int size = (int)data.GetCapacity(); + if (size > 0) + { + char *p = s.GetBuffer(size + 1); + memcpy(p, (const Byte *)data, size); + p[size] = '\0'; + s.ReleaseBuffer(); + } + return s; } IMP_IInArchive_Props @@ -173,10 +177,8 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) switch(propID) { case kpidComment: - { - StringToProp(m_Archive.m_ArchiveInfo.Comment, CP_ACP, prop); + prop = MultiByteToUnicodeString(BytesToString(m_Archive.m_ArchiveInfo.Comment), CP_ACP); break; - } } prop.Detach(value); COM_TRY_END @@ -197,8 +199,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val switch(propID) { case kpidPath: - prop = NItemName::GetOSName2( - MultiByteToUnicodeString(item.Name, item.GetCodePage())); + prop = NItemName::GetOSName2(item.GetUnicodeString(item.Name)); break; case kpidIsFolder: prop = item.IsDirectory(); @@ -209,16 +210,39 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val case kpidPackedSize: prop = item.PackSize; break; + case kpidTimeType: + FILETIME utcFileTime; + if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kTagTime, utcFileTime)) + prop = (UInt32)NFileTimeType::kWindows; + break; + case kpidCreationTime: + { + FILETIME ft; + if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kCTime, ft)) + prop = ft; + break; + } + case kpidLastAccessTime: + { + FILETIME ft; + if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kATime, ft)) + prop = ft; + break; + } case kpidLastWriteTime: { - FILETIME localFileTime, utcFileTime; - if (DosTimeToFileTime(item.Time, localFileTime)) + FILETIME utcFileTime; + if (!item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, utcFileTime)) { - if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime)) + FILETIME localFileTime; + if (DosTimeToFileTime(item.Time, localFileTime)) + { + if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime)) + utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; + } + else utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; } - else - utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; prop = utcFileTime; break; } @@ -230,7 +254,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val break; case kpidComment: { - StringToProp(item.Comment, item.GetCodePage(), prop); + prop = item.GetUnicodeString(BytesToString(item.Comment)); break; } case kpidCRC: diff --git a/CPP/7zip/Archive/Zip/ZipHandler.h b/CPP/7zip/Archive/Zip/ZipHandler.h index 28f44196..c8fa392c 100755 --- a/CPP/7zip/Archive/Zip/ZipHandler.h +++ b/CPP/7zip/Archive/Zip/ZipHandler.h @@ -59,6 +59,10 @@ private: bool m_IsAesMode; Byte m_AesKeyMode; + bool m_WriteNtfsTimeExtra; + bool m_ForseLocal; + bool m_ForseUtf8; + #ifdef COMPRESS_MT UInt32 _numThreads; #endif @@ -77,6 +81,9 @@ private: m_NumMatchFinderCyclesDefined = false; m_IsAesMode = false; m_AesKeyMode = 3; // aes-256 + m_WriteNtfsTimeExtra = false; + m_ForseLocal = false; + m_ForseUtf8 = false; #ifdef COMPRESS_MT _numThreads = NWindows::NSystem::GetNumberOfProcessors();; #endif diff --git a/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp index 453c37a3..2846c988 100755 --- a/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp +++ b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp @@ -66,138 +66,179 @@ static bool IsAsciiString(const UString &s) catch(const CSystemException &e) { return e.ErrorCode; } \ catch(...) { return E_OUTOFMEMORY; } +static HRESULT GetTime(IArchiveUpdateCallback *callback, int index, PROPID propID, FILETIME &filetime) +{ + filetime.dwHighDateTime = filetime.dwLowDateTime = 0; + NCOM::CPropVariant prop; + RINOK(callback->GetProperty(index, propID, &prop)); + if (prop.vt == VT_FILETIME) + filetime = prop.filetime; + else if (prop.vt != VT_EMPTY) + return E_INVALIDARG; + return S_OK; +} + STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, - IArchiveUpdateCallback *updateCallback) + IArchiveUpdateCallback *callback) { COM_TRY_BEGIN2 CObjectVector<CUpdateItem> updateItems; for(UInt32 i = 0; i < numItems; i++) { - CUpdateItem updateItem; + CUpdateItem ui; Int32 newData; Int32 newProperties; UInt32 indexInArchive; - if (!updateCallback) + if (!callback) return E_FAIL; - RINOK(updateCallback->GetUpdateItemInfo(i, + RINOK(callback->GetUpdateItemInfo(i, &newData, // 1 - compress 0 - copy &newProperties, &indexInArchive)); - updateItem.NewProperties = IntToBool(newProperties); - updateItem.NewData = IntToBool(newData); - updateItem.IndexInArchive = indexInArchive; - updateItem.IndexInClient = i; + ui.NewProperties = IntToBool(newProperties); + ui.NewData = IntToBool(newData); + ui.IndexInArchive = indexInArchive; + ui.IndexInClient = i; // bool existInArchive = (indexInArchive != UInt32(-1)); if (IntToBool(newProperties)) { - FILETIME utcFileTime; UString name; bool isDirectoryStatusDefined; { - NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(i, kpidAttributes, &propVariant)); - if (propVariant.vt == VT_EMPTY) - updateItem.Attributes = 0; - else if (propVariant.vt != VT_UI4) + NCOM::CPropVariant prop; + RINOK(callback->GetProperty(i, kpidAttributes, &prop)); + if (prop.vt == VT_EMPTY) + ui.Attributes = 0; + else if (prop.vt != VT_UI4) return E_INVALIDARG; else - updateItem.Attributes = propVariant.ulVal; - } - { - NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(i, kpidLastWriteTime, &propVariant)); - if (propVariant.vt != VT_FILETIME) - return E_INVALIDARG; - utcFileTime = propVariant.filetime; + ui.Attributes = prop.ulVal; } + { - NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(i, kpidPath, &propVariant)); - if (propVariant.vt == VT_EMPTY) + NCOM::CPropVariant prop; + RINOK(callback->GetProperty(i, kpidPath, &prop)); + if (prop.vt == VT_EMPTY) name.Empty(); - else if (propVariant.vt != VT_BSTR) + else if (prop.vt != VT_BSTR) return E_INVALIDARG; else - name = propVariant.bstrVal; + name = prop.bstrVal; } { - NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(i, kpidIsFolder, &propVariant)); - if (propVariant.vt == VT_EMPTY) + NCOM::CPropVariant prop; + RINOK(callback->GetProperty(i, kpidIsFolder, &prop)); + if (prop.vt == VT_EMPTY) isDirectoryStatusDefined = false; - else if (propVariant.vt != VT_BOOL) + else if (prop.vt != VT_BOOL) return E_INVALIDARG; else { - updateItem.IsDirectory = (propVariant.boolVal != VARIANT_FALSE); + ui.IsDirectory = (prop.boolVal != VARIANT_FALSE); isDirectoryStatusDefined = true; } } - FILETIME localFileTime; - if(!FileTimeToLocalFileTime(&utcFileTime, &localFileTime)) - return E_INVALIDARG; - if(!FileTimeToDosTime(localFileTime, updateItem.Time)) + + { + CPropVariant prop; + RINOK(callback->GetProperty(i, kpidTimeType, &prop)); + if (prop.vt == VT_UI4) + ui.NtfsTimeIsDefined = (prop.ulVal == NFileTimeType::kWindows); + 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)); + { - // return E_INVALIDARG; + FILETIME localFileTime = { 0, 0 }; + if (ui.NtfsMTime.dwHighDateTime != 0 || + ui.NtfsMTime.dwLowDateTime != 0) + if (!FileTimeToLocalFileTime(&ui.NtfsMTime, &localFileTime)) + return E_INVALIDARG; + FileTimeToDosTime(localFileTime, ui.Time); } if (!isDirectoryStatusDefined) - updateItem.IsDirectory = ((updateItem.Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0); + ui.IsDirectory = ((ui.Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0); name = NItemName::MakeLegalName(name); - bool needSlash = updateItem.IsDirectory; + bool needSlash = ui.IsDirectory; const wchar_t kSlash = L'/'; if (!name.IsEmpty()) { if (name[name.Length() - 1] == kSlash) { - if (!updateItem.IsDirectory) + if (!ui.IsDirectory) return E_INVALIDARG; needSlash = false; } } if (needSlash) name += kSlash; - updateItem.Name = UnicodeStringToMultiByte(name, CP_OEMCP); - if (updateItem.Name.Length() > 0xFFFF) + + bool tryUtf8 = true; + if (m_ForseLocal || !m_ForseUtf8) + { + bool defaultCharWasUsed; + ui.Name = UnicodeStringToMultiByte(name, CP_OEMCP, '_', defaultCharWasUsed); + tryUtf8 = (!m_ForseLocal && defaultCharWasUsed); + } + + if (tryUtf8) + { + bool needUtf = false; + for (int i = 0; i < name.Length(); i++) + if ((unsigned)name[i] >= 0x80) + { + needUtf = true; + break; + } + ui.IsUtf8 = needUtf; + if (!ConvertUnicodeToUTF8(name, ui.Name)) + return E_INVALIDARG; + } + + if (ui.Name.Length() > 0xFFFF) return E_INVALIDARG; - updateItem.IndexInClient = i; + ui.IndexInClient = i; /* if(existInArchive) { const CItemEx &itemInfo = m_Items[indexInArchive]; - // updateItem.Commented = itemInfo.IsCommented(); - updateItem.Commented = false; - if(updateItem.Commented) + // ui.Commented = itemInfo.IsCommented(); + ui.Commented = false; + if(ui.Commented) { - updateItem.CommentRange.Position = itemInfo.GetCommentPosition(); - updateItem.CommentRange.Size = itemInfo.CommentSize; + ui.CommentRange.Position = itemInfo.GetCommentPosition(); + ui.CommentRange.Size = itemInfo.CommentSize; } } else - updateItem.Commented = false; + ui.Commented = false; */ } if (IntToBool(newData)) { UInt64 size; { - NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(i, kpidSize, &propVariant)); - if (propVariant.vt != VT_UI8) + NCOM::CPropVariant prop; + RINOK(callback->GetProperty(i, kpidSize, &prop)); + if (prop.vt != VT_UI8) return E_INVALIDARG; - size = propVariant.uhVal.QuadPart; + size = prop.uhVal.QuadPart; } - updateItem.Size = size; + ui.Size = size; } - updateItems.Add(updateItem); + updateItems.Add(ui); } CMyComPtr<ICryptoGetTextPassword2> getTextPassword; if (!getTextPassword) { - CMyComPtr<IArchiveUpdateCallback> udateCallBack2(updateCallback); + CMyComPtr<IArchiveUpdateCallback> udateCallBack2(callback); udateCallBack2.QueryInterface(IID_ICryptoGetTextPassword2, &getTextPassword); } CCompressionMethodMode options; @@ -281,7 +322,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt return Update( EXTERNAL_CODECS_VARS m_Items, updateItems, outStream, - m_ArchiveIsOpen ? &m_Archive : NULL, &options, updateCallback); + m_ArchiveIsOpen ? &m_Archive : NULL, &options, callback); COM_TRY_END2 } @@ -406,6 +447,22 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v RINOK(ParsePropValue(name.Mid(1), prop, num)); m_Algo = num; } + else if (name.CompareNoCase(L"TC") == 0) + return SetBoolProperty(m_WriteNtfsTimeExtra, prop); + else if (name.CompareNoCase(L"CL") == 0) + { + RINOK(SetBoolProperty(m_ForseLocal, prop)); + if (m_ForseLocal) + m_ForseUtf8 = false; + return S_OK; + } + else if (name.CompareNoCase(L"CU") == 0) + { + RINOK(SetBoolProperty(m_ForseUtf8, prop)); + if (m_ForseUtf8) + m_ForseLocal = false; + return S_OK; + } else return E_INVALIDARG; } diff --git a/CPP/7zip/Archive/Zip/ZipHeader.h b/CPP/7zip/Archive/Zip/ZipHeader.h index 98ad17a3..0c978a7c 100755 --- a/CPP/7zip/Archive/Zip/ZipHeader.h +++ b/CPP/7zip/Archive/Zip/ZipHeader.h @@ -86,11 +86,23 @@ namespace NFileHeader enum { kZip64 = 0x01, + kNTFS = 0x0A, kStrongEncrypt = 0x17, kWzAES = 0x9901 }; } + namespace NNtfsExtra + { + const UInt16 kTagTime = 1; + enum + { + kMTime = 0, + kATime = 1, + kCTime = 2 + }; + } + const UInt32 kLocalBlockSize = 26; /* struct CLocalBlock @@ -156,13 +168,11 @@ namespace NFileHeader namespace NFlags { - const int kNumUsedBits = 4; - const int kUsedBitsMask = (1 << kNumUsedBits) - 1; - const int kEncrypted = 1 << 0; const int kDescriptorUsedMask = 1 << 3; const int kStrongEncrypted = 1 << 6; - + const int kUtf8 = 1 << 11; + const int kImplodeDictionarySizeMask = 1 << 1; const int kImplodeLiteralsOnMask = 1 << 2; diff --git a/CPP/7zip/Archive/Zip/ZipIn.cpp b/CPP/7zip/Archive/Zip/ZipIn.cpp index b579f9b4..f8e81c59 100755 --- a/CPP/7zip/Archive/Zip/ZipIn.cpp +++ b/CPP/7zip/Archive/Zip/ZipIn.cpp @@ -114,10 +114,10 @@ bool CInArchive::FindAndReadMarker(const UInt64 *searchHeaderSizeLimit) HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize) { - UInt32 realProcessedSize; - HRESULT result = ReadStream(m_Stream, data, size, &realProcessedSize); + size_t realProcessedSize = size; + HRESULT result = ReadStream(m_Stream, data, &realProcessedSize); if(processedSize != NULL) - *processedSize = realProcessedSize; + *processedSize = (UInt32)realProcessedSize; m_Position += realProcessedSize; return result; } @@ -304,7 +304,7 @@ HRESULT CInArchive::ReadLocalItem(CItemEx &item) { item.ExtractVersion.Version = ReadByte(); item.ExtractVersion.HostOS = ReadByte(); - item.Flags = ReadUInt16(); // & NFileHeader::NFlags::kUsedBitsMask; + item.Flags = ReadUInt16(); item.CompressionMethod = ReadUInt16(); item.Time = ReadUInt32(); item.FileCRC = ReadUInt32(); @@ -467,7 +467,7 @@ HRESULT CInArchive::ReadCdItem(CItemEx &item) item.MadeByVersion.HostOS = ReadByte(); item.ExtractVersion.Version = ReadByte(); item.ExtractVersion.HostOS = ReadByte(); - item.Flags = ReadUInt16(); // & NFileHeader::NFlags::kUsedBitsMask; + item.Flags = ReadUInt16(); item.CompressionMethod = ReadUInt16(); item.Time = ReadUInt32(); item.FileCRC = ReadUInt32(); @@ -772,7 +772,7 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *pr return S_FALSE; UInt16 thisDiskNumber16 = ReadUInt16(); - if (!isZip64 || thisDiskNumber16) + if (!isZip64 || thisDiskNumber16 != 0xFFFF) thisDiskNumber = thisDiskNumber16; UInt16 startCDDiskNumber16 = ReadUInt16(); diff --git a/CPP/7zip/Archive/Zip/ZipItem.cpp b/CPP/7zip/Archive/Zip/ZipItem.cpp index 480a1abb..484696f5 100755 --- a/CPP/7zip/Archive/Zip/ZipItem.cpp +++ b/CPP/7zip/Archive/Zip/ZipItem.cpp @@ -5,6 +5,7 @@ #include "ZipHeader.h" #include "ZipItem.h" #include "../Common/ItemNameUtils.h" +#include "../../../../C/CpuArch.h" namespace NArchive { namespace NZip { @@ -19,6 +20,37 @@ bool operator!=(const CVersion &v1, const CVersion &v2) return !(v1 == v2); } +bool CExtraSubBlock::ExtractNtfsTime(int index, FILETIME &ft) const +{ + ft.dwHighDateTime = ft.dwLowDateTime = 0; + UInt32 size = (UInt32)Data.GetCapacity(); + if (ID != NFileHeader::NExtraID::kNTFS || size < 32) + return false; + const Byte *p = (const Byte *)Data; + p += 4; // for reserved + size -= 4; + while (size > 4) + { + UInt16 tag = GetUi16(p); + UInt32 attrSize = GetUi16(p + 2); + p += 4; + size -= 4; + if (attrSize > size) + attrSize = size; + + if (tag == NFileHeader::NNtfsExtra::kTagTime && attrSize >= 24) + { + p += 8 * index; + ft.dwLowDateTime = GetUi32(p); + ft.dwHighDateTime = GetUi32(p + 4); + return true; + } + p += attrSize; + size -= attrSize; + } + return false; +} + bool CLocalItem::IsImplodeBigDictionary() const { if (CompressionMethod != NFileHeader::NCompressionMethod::kImploded) @@ -126,5 +158,7 @@ void CLocalItem::SetBitMask(int bitMask, bool enable) void CLocalItem::SetEncrypted(bool encrypted) { SetBitMask(NFileHeader::NFlags::kEncrypted, encrypted); } +void CLocalItem::SetUtf8(bool isUtf8) + { SetBitMask(NFileHeader::NFlags::kUtf8, isUtf8); } }} diff --git a/CPP/7zip/Archive/Zip/ZipItem.h b/CPP/7zip/Archive/Zip/ZipItem.h index 350e81b6..8d7cc3b4 100755 --- a/CPP/7zip/Archive/Zip/ZipItem.h +++ b/CPP/7zip/Archive/Zip/ZipItem.h @@ -6,6 +6,8 @@ #include "Common/Types.h" #include "Common/MyString.h" #include "Common/Buffer.h" +#include "Common/UTFConvert.h" +#include "Common/StringConvert.h" #include "ZipHeader.h" @@ -25,6 +27,7 @@ struct CExtraSubBlock { UInt16 ID; CByteBuffer Data; + bool ExtractNtfsTime(int index, FILETIME &ft) const; }; struct CWzAesExtraField @@ -137,6 +140,17 @@ struct CExtraBlock return GetWzAesField(aesField); } + bool GetNtfsTime(int index, FILETIME &ft) const + { + for (int i = 0; i < SubBlocks.Size(); i++) + { + const CExtraSubBlock &sb = SubBlocks[i]; + if (sb.ID == NFileHeader::NExtraID::kNTFS) + return sb.ExtractNtfsTime(index, ft); + } + return false; + } + /* bool HasStrongCryptoField() const { @@ -147,14 +161,9 @@ struct CExtraBlock void RemoveUnknownSubBlocks() { - for (int i = SubBlocks.Size() - 1; i >= 0;) - { - const CExtraSubBlock &subBlock = SubBlocks[i]; - if (subBlock.ID != NFileHeader::NExtraID::kWzAES) + for (int i = SubBlocks.Size() - 1; i >= 0; i--) + if (SubBlocks[i].ID != NFileHeader::NExtraID::kWzAES) SubBlocks.Delete(i); - else - i--; - } } }; @@ -173,6 +182,8 @@ public: AString Name; CExtraBlock LocalExtra; + + bool IsUtf8() const { return (Flags & NFileHeader::NFlags::kUtf8) != 0; } bool IsEncrypted() const { return (Flags & NFileHeader::NFlags::kEncrypted) != 0; } bool IsStrongEncrypted() const { return IsEncrypted() && (Flags & NFileHeader::NFlags::kStrongEncrypted) != 0; }; @@ -186,6 +197,16 @@ public: bool HasDescriptor() const { return (Flags & NFileHeader::NFlags::kDescriptorUsedMask) != 0; } + UString GetUnicodeString(const AString &s) const + { + UString res; + if (IsUtf8()) + if (!ConvertUTF8ToUnicode(s, res)) + res.Empty(); + if (res.IsEmpty()) + res = MultiByteToUnicodeString(s, GetCodePage()); + return res; + } private: void SetFlagBits(int startBitNumber, int numBits, int value); @@ -193,11 +214,9 @@ private: public: void ClearFlags() { Flags = 0; } void SetEncrypted(bool encrypted); + void SetUtf8(bool isUtf8); - WORD GetCodePage() const - { - return CP_OEMCP; - } + WORD GetCodePage() const { return CP_OEMCP; } }; class CItem: public CLocalItem @@ -209,11 +228,16 @@ public: UInt64 LocalHeaderPosition; + FILETIME NtfsMTime; + FILETIME NtfsATime; + FILETIME NtfsCTime; + CExtraBlock CentralExtra; CByteBuffer Comment; bool FromLocal; bool FromCentral; + bool NtfsTimeIsDefined; bool IsDirectory() const; UInt32 GetWinAttributes() const; @@ -235,7 +259,7 @@ public: || MadeByVersion.HostOS == NFileHeader::NHostOS::kNTFS ) ? CP_OEMCP : CP_ACP); } - CItem() : FromLocal(false), FromCentral(false) {} + CItem() : FromLocal(false), FromCentral(false), NtfsTimeIsDefined(false) {} }; }} diff --git a/CPP/7zip/Archive/Zip/ZipOut.cpp b/CPP/7zip/Archive/Zip/ZipOut.cpp index d5e6895e..fd89b1e8 100755 --- a/CPP/7zip/Archive/Zip/ZipOut.cpp +++ b/CPP/7zip/Archive/Zip/ZipOut.cpp @@ -172,7 +172,8 @@ void COutArchive::WriteCentralHeader(const CItem &item) WriteUInt32(isUnPack64 ? 0xFFFFFFFF: (UInt32)item.UnPackSize); WriteUInt16((UInt16)item.Name.Length()); UInt16 zip64ExtraSize = (UInt16)((isUnPack64 ? 8: 0) + (isPack64 ? 8: 0) + (isPosition64 ? 8: 0)); - UInt16 centralExtraSize = (UInt16)(isZip64 ? (4 + zip64ExtraSize) : 0); + const UInt16 kNtfsExtraSize = 4 + 2 + 2 + (3 * 8); + UInt16 centralExtraSize = (UInt16)(isZip64 ? (4 + zip64ExtraSize) : 0) + (item.NtfsTimeIsDefined ? (4 + kNtfsExtraSize) : 0); centralExtraSize = (UInt16)(centralExtraSize + item.CentralExtra.GetSize()); WriteUInt16(centralExtraSize); // test it; WriteUInt16((UInt16)item.Comment.GetCapacity()); @@ -192,6 +193,20 @@ void COutArchive::WriteCentralHeader(const CItem &item) if(isPosition64) WriteUInt64(item.LocalHeaderPosition); } + if (item.NtfsTimeIsDefined) + { + WriteUInt16(NFileHeader::NExtraID::kNTFS); + WriteUInt16(kNtfsExtraSize); + WriteUInt32(0); // reserved + WriteUInt16(NFileHeader::NNtfsExtra::kTagTime); + WriteUInt16(8 * 3); + WriteUInt32(item.NtfsMTime.dwLowDateTime); + WriteUInt32(item.NtfsMTime.dwHighDateTime); + WriteUInt32(item.NtfsATime.dwLowDateTime); + WriteUInt32(item.NtfsATime.dwHighDateTime); + WriteUInt32(item.NtfsCTime.dwLowDateTime); + WriteUInt32(item.NtfsCTime.dwHighDateTime); + } WriteExtra(item.CentralExtra); if (item.Comment.GetCapacity() > 0) WriteBytes(item.Comment, (UInt32)item.Comment.GetCapacity()); diff --git a/CPP/7zip/Archive/Zip/ZipUpdate.cpp b/CPP/7zip/Archive/Zip/ZipUpdate.cpp index 6cfa64e2..2ec08981 100755 --- a/CPP/7zip/Archive/Zip/ZipUpdate.cpp +++ b/CPP/7zip/Archive/Zip/ZipUpdate.cpp @@ -69,12 +69,19 @@ static void SetFileHeader( item.UnPackSize = updateItem.Size; bool isDirectory; + item.ClearFlags(); + if (updateItem.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; } else isDirectory = item.IsDirectory(); @@ -86,7 +93,6 @@ static void SetFileHeader( item.ExtractVersion.HostOS = kExtractHostOS; item.InternalAttributes = 0; // test it - item.ClearFlags(); item.SetEncrypted(!isDirectory && options.PasswordIsDefined); if (isDirectory) { @@ -341,7 +347,13 @@ static HRESULT UpdateItemOldData(COutArchive &archive, // item.ExternalAttributes = updateItem.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.CentralExtra.RemoveUnknownSubBlocks(); item.LocalExtra.RemoveUnknownSubBlocks(); diff --git a/CPP/7zip/Archive/Zip/ZipUpdate.h b/CPP/7zip/Archive/Zip/ZipUpdate.h index 168eedd6..5e67bead 100755 --- a/CPP/7zip/Archive/Zip/ZipUpdate.h +++ b/CPP/7zip/Archive/Zip/ZipUpdate.h @@ -27,6 +27,8 @@ struct CUpdateItem bool NewData; bool NewProperties; bool IsDirectory; + bool NtfsTimeIsDefined; + bool IsUtf8; int IndexInArchive; int IndexInClient; UInt32 Attributes; @@ -35,7 +37,11 @@ struct CUpdateItem AString Name; // bool Commented; // CUpdateRange CommentRange; - CUpdateItem(): Size(0) {} + FILETIME NtfsMTime; + FILETIME NtfsATime; + FILETIME NtfsCTime; + + CUpdateItem(): NtfsTimeIsDefined(false), IsUtf8(false), Size(0) {} }; HRESULT Update( |