mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-08 06:06:59 -06:00
4.59 beta
This commit is contained in:
committed by
Kornel Lesiński
parent
3901bf0ab8
commit
173c07e166
640
CPP/7zip/Archive/7z/7z.dsp
Executable file
640
CPP/7zip/Archive/7z/7z.dsp
Executable file
@@ -0,0 +1,640 @@
|
||||
# Microsoft Developer Studio Project File - Name="7z" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=7z - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "7z.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "7z.mak" CFG="7z - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "7z - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "7z - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "7z - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "COMPRESS_MT" /D "EXTERNAL_CODECS" /Yu"StdAfx.h" /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-zip\Formats\7z.dll" /opt:NOWIN98
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ELSEIF "$(CFG)" == "7z - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "COMPRESS_MT" /D "EXTERNAL_CODECS" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-zip\Formats\7z.dll" /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "7z - Win32 Release"
|
||||
# Name "7z - Win32 Debug"
|
||||
# Begin Group "Spec"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Archive.def
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\ArchiveExports.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\DllExports.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\resource.rc
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.cpp
|
||||
# ADD CPP /Yc"StdAfx.h"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Engine"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zCompressionMode.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zCompressionMode.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zDecode.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zDecode.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zEncode.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zEncode.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zExtract.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zFolderInStream.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zFolderInStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zFolderOutStream.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zFolderOutStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zHandler.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zHandler.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zHandlerOut.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zHeader.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zHeader.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zIn.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zIn.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zItem.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zOut.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zOut.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zProperties.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zProperties.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zRegister.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zSpecStream.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zSpecStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zUpdate.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zUpdate.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Interface"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\IArchive.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\ICoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\IMyUnknown.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\IPassword.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\IProgress.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\IStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\PropID.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Common"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Buffer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\CRC.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\DynamicBuffer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\IntToString.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\IntToString.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\MyString.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\MyString.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\MyVector.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\MyVector.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\NewHandler.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\NewHandler.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\StringConvert.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\StringConvert.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\StringToInt.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\StringToInt.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Archive Common"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\CoderMixer2.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\CoderMixer2.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\CoderMixer2MT.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\CoderMixer2MT.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\CrossThreadProgress.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\CrossThreadProgress.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\HandlerOut.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\HandlerOut.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\InStreamWithCRC.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\InStreamWithCRC.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\ItemNameUtils.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\ItemNameUtils.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\MultiStream.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\MultiStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\OutStreamWithCRC.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\OutStreamWithCRC.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\ParseProperties.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\ParseProperties.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "7-Zip Common"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\CreateCoder.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\CreateCoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\FilterCoder.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\FilterCoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\InOutTempBuffer.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\InOutTempBuffer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\LimitedStreams.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\LimitedStreams.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\LockedStream.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\LockedStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\MethodId.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\MethodId.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\MethodProps.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\MethodProps.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\OutBuffer.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\OutBuffer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\ProgressUtils.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\ProgressUtils.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\RegisterArc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\RegisterCodec.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\StreamBinder.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\StreamBinder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\StreamObjects.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\StreamObjects.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\StreamUtils.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\StreamUtils.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\VirtThread.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\VirtThread.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Windows"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\DLL.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\DLL.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\FileDir.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\FileDir.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\FileFind.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\FileFind.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\FileIO.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\FileIO.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\FileName.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\Handle.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\PropVariant.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\PropVariant.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\Synchronization.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\Synchronization.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\System.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\System.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\Thread.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Compress"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Compress\Copy\CopyCoder.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Compress\Copy\CopyCoder.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "C"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\7zCrc.c
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\7zCrc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Alloc.c
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Alloc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Threads.c
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Threads.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
29
CPP/7zip/Archive/7z/7z.dsw
Executable file
29
CPP/7zip/Archive/7z/7z.dsw
Executable file
@@ -0,0 +1,29 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "7z"=".\7z.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
@@ -40,7 +40,7 @@ struct CCompressionMethodMode
|
||||
bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); }
|
||||
CCompressionMethodMode(): PasswordIsDefined(false)
|
||||
#ifdef COMPRESS_MT
|
||||
, NumThreads(1)
|
||||
, NumThreads(1)
|
||||
#endif
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -44,7 +44,7 @@ static void ConvertFolderItemInfoToBindInfo(const CFolder &folder,
|
||||
bindInfo.InStreams.Add((UInt32)folder.PackStreams[i]);
|
||||
}
|
||||
|
||||
static bool AreCodersEqual(const NCoderMixer::CCoderStreamsInfo &a1,
|
||||
static bool AreCodersEqual(const NCoderMixer::CCoderStreamsInfo &a1,
|
||||
const NCoderMixer::CCoderStreamsInfo &a2)
|
||||
{
|
||||
return (a1.NumInStreams == a2.NumInStreams) &&
|
||||
@@ -94,17 +94,20 @@ HRESULT CDecoder::Decode(
|
||||
IInStream *inStream,
|
||||
UInt64 startPos,
|
||||
const UInt64 *packSizes,
|
||||
const CFolder &folderInfo,
|
||||
const CFolder &folderInfo,
|
||||
ISequentialOutStream *outStream,
|
||||
ICompressProgressInfo *compressProgress
|
||||
#ifndef _NO_CRYPTO
|
||||
, ICryptoGetTextPassword *getTextPassword
|
||||
, ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
|
||||
#endif
|
||||
#ifdef COMPRESS_MT
|
||||
, bool mtMode, UInt32 numThreads
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#ifndef _NO_CRYPTO
|
||||
passwordIsDefined = false;
|
||||
#endif
|
||||
CObjectVector< CMyComPtr<ISequentialInStream> > inStreams;
|
||||
|
||||
CLockedInStream lockedInStream;
|
||||
@@ -112,13 +115,13 @@ HRESULT CDecoder::Decode(
|
||||
|
||||
for (int j = 0; j < folderInfo.PackStreams.Size(); j++)
|
||||
{
|
||||
CLockedSequentialInStreamImp *lockedStreamImpSpec = new
|
||||
CLockedSequentialInStreamImp *lockedStreamImpSpec = new
|
||||
CLockedSequentialInStreamImp;
|
||||
CMyComPtr<ISequentialInStream> lockedStreamImp = lockedStreamImpSpec;
|
||||
lockedStreamImpSpec->Init(&lockedInStream, startPos);
|
||||
startPos += packSizes[j];
|
||||
|
||||
CLimitedSequentialInStream *streamSpec = new
|
||||
CLimitedSequentialInStream *streamSpec = new
|
||||
CLimitedSequentialInStream;
|
||||
CMyComPtr<ISequentialInStream> inStream = streamSpec;
|
||||
streamSpec->SetStream(lockedStreamImp);
|
||||
@@ -212,7 +215,7 @@ HRESULT CDecoder::Decode(
|
||||
int i;
|
||||
_mixerCoderCommon->ReInit();
|
||||
|
||||
UInt32 packStreamIndex = 0, unPackStreamIndex = 0;
|
||||
UInt32 packStreamIndex = 0, unpackStreamIndex = 0;
|
||||
UInt32 coderIndex = 0;
|
||||
// UInt32 coder2Index = 0;
|
||||
|
||||
@@ -257,20 +260,20 @@ HRESULT CDecoder::Decode(
|
||||
{
|
||||
if (getTextPassword == 0)
|
||||
return E_FAIL;
|
||||
CMyComBSTR password;
|
||||
RINOK(getTextPassword->CryptoGetTextPassword(&password));
|
||||
CMyComBSTR passwordBSTR;
|
||||
RINOK(getTextPassword->CryptoGetTextPassword(&passwordBSTR));
|
||||
CByteBuffer buffer;
|
||||
UString unicodePassword(password);
|
||||
const UInt32 sizeInBytes = unicodePassword.Length() * 2;
|
||||
passwordIsDefined = true;
|
||||
UString password = passwordBSTR;
|
||||
const UInt32 sizeInBytes = password.Length() * 2;
|
||||
buffer.SetCapacity(sizeInBytes);
|
||||
for (int i = 0; i < unicodePassword.Length(); i++)
|
||||
for (int i = 0; i < password.Length(); i++)
|
||||
{
|
||||
wchar_t c = unicodePassword[i];
|
||||
wchar_t c = password[i];
|
||||
((Byte *)buffer)[i * 2] = (Byte)c;
|
||||
((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
|
||||
}
|
||||
RINOK(cryptoSetPassword->CryptoSetPassword(
|
||||
(const Byte *)buffer, sizeInBytes));
|
||||
RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, sizeInBytes));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -280,19 +283,19 @@ HRESULT CDecoder::Decode(
|
||||
UInt32 numInStreams = (UInt32)coderInfo.NumInStreams;
|
||||
UInt32 numOutStreams = (UInt32)coderInfo.NumOutStreams;
|
||||
CRecordVector<const UInt64 *> packSizesPointers;
|
||||
CRecordVector<const UInt64 *> unPackSizesPointers;
|
||||
CRecordVector<const UInt64 *> unpackSizesPointers;
|
||||
packSizesPointers.Reserve(numInStreams);
|
||||
unPackSizesPointers.Reserve(numOutStreams);
|
||||
unpackSizesPointers.Reserve(numOutStreams);
|
||||
UInt32 j;
|
||||
for (j = 0; j < numOutStreams; j++, unPackStreamIndex++)
|
||||
unPackSizesPointers.Add(&folderInfo.UnPackSizes[unPackStreamIndex]);
|
||||
for (j = 0; j < numOutStreams; j++, unpackStreamIndex++)
|
||||
unpackSizesPointers.Add(&folderInfo.UnpackSizes[unpackStreamIndex]);
|
||||
|
||||
for (j = 0; j < numInStreams; j++, packStreamIndex++)
|
||||
{
|
||||
int bindPairIndex = folderInfo.FindBindPairForInStream(packStreamIndex);
|
||||
if (bindPairIndex >= 0)
|
||||
packSizesPointers.Add(
|
||||
&folderInfo.UnPackSizes[(UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex]);
|
||||
&folderInfo.UnpackSizes[(UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex]);
|
||||
else
|
||||
{
|
||||
int index = folderInfo.FindPackStreamArrayIndex(packStreamIndex);
|
||||
@@ -302,9 +305,9 @@ HRESULT CDecoder::Decode(
|
||||
}
|
||||
}
|
||||
|
||||
_mixerCoderCommon->SetCoderInfo(i,
|
||||
&packSizesPointers.Front(),
|
||||
&unPackSizesPointers.Front());
|
||||
_mixerCoderCommon->SetCoderInfo(i,
|
||||
&packSizesPointers.Front(),
|
||||
&unpackSizesPointers.Front());
|
||||
}
|
||||
UInt32 mainCoder, temp;
|
||||
bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp);
|
||||
@@ -323,7 +326,7 @@ HRESULT CDecoder::Decode(
|
||||
for (i = 0; i < inStreams.Size(); i++)
|
||||
inStreamPointers.Add(inStreams[i]);
|
||||
ISequentialOutStream *outStreamPointer = outStream;
|
||||
return _mixerCoder->Code(&inStreamPointers.Front(), NULL,
|
||||
return _mixerCoder->Code(&inStreamPointers.Front(), NULL,
|
||||
inStreams.Size(), &outStreamPointer, NULL, 1, compressProgress);
|
||||
}
|
||||
|
||||
|
||||
@@ -51,11 +51,11 @@ public:
|
||||
IInStream *inStream,
|
||||
UInt64 startPos,
|
||||
const UInt64 *packSizes,
|
||||
const CFolder &folder,
|
||||
const CFolder &folder,
|
||||
ISequentialOutStream *outStream,
|
||||
ICompressProgressInfo *compressProgress
|
||||
#ifndef _NO_CRYPTO
|
||||
, ICryptoGetTextPassword *getTextPasswordSpec
|
||||
, ICryptoGetTextPassword *getTextPasswordSpec, bool &passwordIsDefined
|
||||
#endif
|
||||
#ifdef COMPRESS_MT
|
||||
, bool mtMode, UInt32 numThreads
|
||||
|
||||
@@ -164,7 +164,7 @@ HRESULT CEncoder::Encode(
|
||||
}
|
||||
for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
|
||||
{
|
||||
CSequentialOutTempBufferImp *tempBufferSpec =
|
||||
CSequentialOutTempBufferImp *tempBufferSpec =
|
||||
new CSequentialOutTempBufferImp;
|
||||
CMyComPtr<ISequentialOutStream> tempBuffer = tempBufferSpec;
|
||||
tempBufferSpec->Init(&inOutTempBuffers[i - 1]);
|
||||
@@ -195,10 +195,10 @@ HRESULT CEncoder::Encode(
|
||||
// UInt64 outStreamStartPos;
|
||||
// RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos));
|
||||
|
||||
CSequentialInStreamSizeCount2 *inStreamSizeCountSpec =
|
||||
CSequentialInStreamSizeCount2 *inStreamSizeCountSpec =
|
||||
new CSequentialInStreamSizeCount2;
|
||||
CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec;
|
||||
CSequentialOutStreamSizeCount *outStreamSizeCountSpec =
|
||||
CSequentialOutStreamSizeCount *outStreamSizeCountSpec =
|
||||
new CSequentialOutStreamSizeCount;
|
||||
CMyComPtr<ISequentialOutStream> outStreamSizeCount = outStreamSizeCountSpec;
|
||||
|
||||
@@ -275,7 +275,7 @@ HRESULT CEncoder::Encode(
|
||||
streamSize = inStreamSizeCountSpec->GetSize();
|
||||
else
|
||||
streamSize = _mixerCoderSpec->GetWriteProcessedSize(binder);
|
||||
folderItem.UnPackSizes.Add(streamSize);
|
||||
folderItem.UnpackSizes.Add(streamSize);
|
||||
}
|
||||
for (i = numMethods - 1; i >= 0; i--)
|
||||
folderItem.Coders[numMethods - 1 - i].Properties = _codersInfo[i].Properties;
|
||||
|
||||
@@ -23,18 +23,18 @@ struct CExtractFolderInfo
|
||||
CNum FileIndex;
|
||||
CNum FolderIndex;
|
||||
CBoolVector ExtractStatuses;
|
||||
UInt64 UnPackSize;
|
||||
UInt64 UnpackSize;
|
||||
CExtractFolderInfo(
|
||||
#ifdef _7Z_VOL
|
||||
int volumeIndex,
|
||||
int volumeIndex,
|
||||
#endif
|
||||
CNum fileIndex, CNum folderIndex):
|
||||
CNum fileIndex, CNum folderIndex):
|
||||
#ifdef _7Z_VOL
|
||||
VolumeIndex(volumeIndex),
|
||||
#endif
|
||||
FileIndex(fileIndex),
|
||||
FolderIndex(folderIndex),
|
||||
UnPackSize(0)
|
||||
FolderIndex(folderIndex),
|
||||
UnpackSize(0)
|
||||
{
|
||||
if (fileIndex != kNumNoIndex)
|
||||
{
|
||||
@@ -50,15 +50,15 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
COM_TRY_BEGIN
|
||||
bool testMode = (testModeSpec != 0);
|
||||
CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
|
||||
UInt64 importantTotalUnPacked = 0;
|
||||
UInt64 importantTotalUnpacked = 0;
|
||||
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
if (allFilesMode)
|
||||
numItems =
|
||||
numItems =
|
||||
#ifdef _7Z_VOL
|
||||
_refs.Size();
|
||||
#else
|
||||
_database.Files.Size();
|
||||
_db.Files.Size();
|
||||
#endif
|
||||
|
||||
if(numItems == 0)
|
||||
@@ -68,7 +68,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
if(_volumes.Size() != 1)
|
||||
return E_FAIL;
|
||||
const CVolume &volume = _volumes.Front();
|
||||
const CArchiveDatabaseEx &_database = volume.Database;
|
||||
const CArchiveDatabaseEx &_db = volume.Database;
|
||||
IInStream *_inStream = volume.Stream;
|
||||
*/
|
||||
|
||||
@@ -87,25 +87,25 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
|
||||
int volumeIndex = ref.VolumeIndex;
|
||||
const CVolume &volume = _volumes[volumeIndex];
|
||||
const CArchiveDatabaseEx &database = volume.Database;
|
||||
const CArchiveDatabaseEx &db = volume.Database;
|
||||
UInt32 fileIndex = ref.ItemIndex;
|
||||
#else
|
||||
const CArchiveDatabaseEx &database = _database;
|
||||
const CArchiveDatabaseEx &db = _db;
|
||||
UInt32 fileIndex = ref2Index;
|
||||
#endif
|
||||
|
||||
CNum folderIndex = database.FileIndexToFolderIndexMap[fileIndex];
|
||||
CNum folderIndex = db.FileIndexToFolderIndexMap[fileIndex];
|
||||
if (folderIndex == kNumNoIndex)
|
||||
{
|
||||
extractFolderInfoVector.Add(CExtractFolderInfo(
|
||||
#ifdef _7Z_VOL
|
||||
volumeIndex,
|
||||
volumeIndex,
|
||||
#endif
|
||||
fileIndex, kNumNoIndex));
|
||||
continue;
|
||||
}
|
||||
if (extractFolderInfoVector.IsEmpty() ||
|
||||
folderIndex != extractFolderInfoVector.Back().FolderIndex
|
||||
if (extractFolderInfoVector.IsEmpty() ||
|
||||
folderIndex != extractFolderInfoVector.Back().FolderIndex
|
||||
#ifdef _7Z_VOL
|
||||
|| volumeIndex != extractFolderInfoVector.Back().VolumeIndex
|
||||
#endif
|
||||
@@ -113,32 +113,32 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
{
|
||||
extractFolderInfoVector.Add(CExtractFolderInfo(
|
||||
#ifdef _7Z_VOL
|
||||
volumeIndex,
|
||||
volumeIndex,
|
||||
#endif
|
||||
kNumNoIndex, folderIndex));
|
||||
const CFolder &folderInfo = database.Folders[folderIndex];
|
||||
UInt64 unPackSize = folderInfo.GetUnPackSize();
|
||||
importantTotalUnPacked += unPackSize;
|
||||
extractFolderInfoVector.Back().UnPackSize = unPackSize;
|
||||
const CFolder &folderInfo = db.Folders[folderIndex];
|
||||
UInt64 unpackSize = folderInfo.GetUnpackSize();
|
||||
importantTotalUnpacked += unpackSize;
|
||||
extractFolderInfoVector.Back().UnpackSize = unpackSize;
|
||||
}
|
||||
|
||||
CExtractFolderInfo &efi = extractFolderInfoVector.Back();
|
||||
|
||||
// const CFolderInfo &folderInfo = m_dam_Folders[folderIndex];
|
||||
CNum startIndex = database.FolderStartFileIndex[folderIndex];
|
||||
CNum startIndex = db.FolderStartFileIndex[folderIndex];
|
||||
for (CNum index = efi.ExtractStatuses.Size();
|
||||
index <= fileIndex - startIndex; index++)
|
||||
{
|
||||
// UInt64 unPackSize = _database.Files[startIndex + index].UnPackSize;
|
||||
// UInt64 unpackSize = _db.Files[startIndex + index].UnpackSize;
|
||||
// Count partial_folder_size
|
||||
// efi.UnPackSize += unPackSize;
|
||||
// importantTotalUnPacked += unPackSize;
|
||||
// efi.UnpackSize += unpackSize;
|
||||
// importantTotalUnpacked += unpackSize;
|
||||
efi.ExtractStatuses.Add(index == fileIndex - startIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extractCallback->SetTotal(importantTotalUnPacked);
|
||||
extractCallback->SetTotal(importantTotalUnpacked);
|
||||
|
||||
CDecoder decoder(
|
||||
#ifdef _ST_MODE
|
||||
@@ -150,24 +150,24 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
// CDecoder1 decoder;
|
||||
|
||||
UInt64 currentTotalPacked = 0;
|
||||
UInt64 currentTotalUnPacked = 0;
|
||||
UInt64 totalFolderUnPacked;
|
||||
UInt64 currentTotalUnpacked = 0;
|
||||
UInt64 totalFolderUnpacked;
|
||||
UInt64 totalFolderPacked;
|
||||
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(extractCallback, false);
|
||||
|
||||
for(int i = 0; i < extractFolderInfoVector.Size(); i++,
|
||||
currentTotalUnPacked += totalFolderUnPacked,
|
||||
for(int i = 0; i < extractFolderInfoVector.Size(); i++,
|
||||
currentTotalUnpacked += totalFolderUnpacked,
|
||||
currentTotalPacked += totalFolderPacked)
|
||||
{
|
||||
lps->OutSize = currentTotalUnPacked;
|
||||
lps->OutSize = currentTotalUnpacked;
|
||||
lps->InSize = currentTotalPacked;
|
||||
RINOK(lps->SetCur());
|
||||
|
||||
const CExtractFolderInfo &efi = extractFolderInfoVector[i];
|
||||
totalFolderUnPacked = efi.UnPackSize;
|
||||
totalFolderUnpacked = efi.UnpackSize;
|
||||
|
||||
totalFolderPacked = 0;
|
||||
|
||||
@@ -176,25 +176,25 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
|
||||
#ifdef _7Z_VOL
|
||||
const CVolume &volume = _volumes[efi.VolumeIndex];
|
||||
const CArchiveDatabaseEx &database = volume.Database;
|
||||
const CArchiveDatabaseEx &db = volume.Database;
|
||||
#else
|
||||
const CArchiveDatabaseEx &database = _database;
|
||||
const CArchiveDatabaseEx &db = _db;
|
||||
#endif
|
||||
|
||||
CNum startIndex;
|
||||
if (efi.FileIndex != kNumNoIndex)
|
||||
startIndex = efi.FileIndex;
|
||||
else
|
||||
startIndex = database.FolderStartFileIndex[efi.FolderIndex];
|
||||
startIndex = db.FolderStartFileIndex[efi.FolderIndex];
|
||||
|
||||
|
||||
HRESULT result = folderOutStream->Init(&database,
|
||||
HRESULT result = folderOutStream->Init(&db,
|
||||
#ifdef _7Z_VOL
|
||||
volume.StartRef2Index,
|
||||
volume.StartRef2Index,
|
||||
#else
|
||||
0,
|
||||
#endif
|
||||
startIndex,
|
||||
startIndex,
|
||||
&efi.ExtractStatuses, extractCallback, testMode, _crcSize != 0);
|
||||
|
||||
RINOK(result);
|
||||
@@ -203,12 +203,12 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
continue;
|
||||
|
||||
CNum folderIndex = efi.FolderIndex;
|
||||
const CFolder &folderInfo = database.Folders[folderIndex];
|
||||
const CFolder &folderInfo = db.Folders[folderIndex];
|
||||
|
||||
totalFolderPacked = _database.GetFolderFullPackSize(folderIndex);
|
||||
totalFolderPacked = _db.GetFolderFullPackSize(folderIndex);
|
||||
|
||||
CNum packStreamIndex = database.FolderStartPackStreamIndex[folderIndex];
|
||||
UInt64 folderStartPackPos = database.GetFolderStreamPos(folderIndex, 0);
|
||||
CNum packStreamIndex = db.FolderStartPackStreamIndex[folderIndex];
|
||||
UInt64 folderStartPackPos = db.GetFolderStreamPos(folderIndex, 0);
|
||||
|
||||
#ifndef _NO_CRYPTO
|
||||
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
|
||||
@@ -218,6 +218,10 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
|
||||
try
|
||||
{
|
||||
#ifndef _NO_CRYPTO
|
||||
bool passwordIsDefined;
|
||||
#endif
|
||||
|
||||
HRESULT result = decoder.Decode(
|
||||
EXTERNAL_CODECS_VARS
|
||||
#ifdef _7Z_VOL
|
||||
@@ -225,13 +229,13 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
#else
|
||||
_inStream,
|
||||
#endif
|
||||
folderStartPackPos,
|
||||
&database.PackSizes[packStreamIndex],
|
||||
folderStartPackPos,
|
||||
&db.PackSizes[packStreamIndex],
|
||||
folderInfo,
|
||||
outStream,
|
||||
progress
|
||||
#ifndef _NO_CRYPTO
|
||||
, getTextPassword
|
||||
, getTextPassword, passwordIsDefined
|
||||
#endif
|
||||
#ifdef COMPRESS_MT
|
||||
, true, _numThreads
|
||||
|
||||
@@ -13,7 +13,7 @@ CFolderInStream::CFolderInStream()
|
||||
_inStreamWithHash = _inStreamWithHashSpec;
|
||||
}
|
||||
|
||||
void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback,
|
||||
void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback,
|
||||
const UInt32 *fileIndices, UInt32 numFiles)
|
||||
{
|
||||
_updateCallback = updateCallback;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
class CFolderInStream:
|
||||
class CFolderInStream:
|
||||
public ISequentialInStream,
|
||||
public ICompressGetSubStreamSize,
|
||||
public CMyUnknownImp
|
||||
@@ -47,7 +47,7 @@ private:
|
||||
HRESULT CloseStream();
|
||||
void AddDigest();
|
||||
public:
|
||||
void Init(IArchiveUpdateCallback *updateCallback,
|
||||
void Init(IArchiveUpdateCallback *updateCallback,
|
||||
const UInt32 *fileIndices, UInt32 numFiles);
|
||||
CRecordVector<bool> Processed;
|
||||
CRecordVector<UInt32> CRCs;
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
UInt64 GetFullSize() const
|
||||
{
|
||||
UInt64 size = 0;
|
||||
for (int i = 0; i < Sizes.Size(); i++)
|
||||
for (int i = 0; i < Sizes.Size(); i++)
|
||||
size += Sizes[i];
|
||||
return size;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ HRESULT CFolderOutStream::Init(
|
||||
const CArchiveDatabaseEx *archiveDatabase,
|
||||
UInt32 ref2Offset,
|
||||
UInt32 startIndex,
|
||||
const CBoolVector *extractStatuses,
|
||||
const CBoolVector *extractStatuses,
|
||||
IArchiveExtractCallback *extractCallback,
|
||||
bool testMode,
|
||||
bool checkCrc)
|
||||
@@ -41,7 +41,7 @@ HRESULT CFolderOutStream::OpenFile()
|
||||
{
|
||||
Int32 askMode;
|
||||
if((*_extractStatuses)[_currentIndex])
|
||||
askMode = _testMode ?
|
||||
askMode = _testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
else
|
||||
@@ -54,10 +54,10 @@ HRESULT CFolderOutStream::OpenFile()
|
||||
_outStreamWithHashSpec->SetStream(realOutStream);
|
||||
_outStreamWithHashSpec->Init(_checkCrc);
|
||||
if (askMode == NArchive::NExtract::NAskMode::kExtract &&
|
||||
(!realOutStream))
|
||||
(!realOutStream))
|
||||
{
|
||||
const CFileItem &fileInfo = _archiveDatabase->Files[index];
|
||||
if (!fileInfo.IsAnti && !fileInfo.IsDirectory)
|
||||
const CFileItem &fi = _archiveDatabase->Files[index];
|
||||
if (!_archiveDatabase->IsItemAnti(index) && !fi.IsDir)
|
||||
askMode = NArchive::NExtract::NAskMode::kSkip;
|
||||
}
|
||||
return _extractCallback->PrepareOperation(askMode);
|
||||
@@ -68,18 +68,17 @@ HRESULT CFolderOutStream::WriteEmptyFiles()
|
||||
for(;_currentIndex < _extractStatuses->Size(); _currentIndex++)
|
||||
{
|
||||
UInt32 index = _startIndex + _currentIndex;
|
||||
const CFileItem &fileInfo = _archiveDatabase->Files[index];
|
||||
if (!fileInfo.IsAnti && !fileInfo.IsDirectory && fileInfo.UnPackSize != 0)
|
||||
const CFileItem &fi = _archiveDatabase->Files[index];
|
||||
if (!_archiveDatabase->IsItemAnti(index) && !fi.IsDir && fi.Size != 0)
|
||||
return S_OK;
|
||||
RINOK(OpenFile());
|
||||
RINOK(_extractCallback->SetOperationResult(
|
||||
NArchive::NExtract::NOperationResult::kOK));
|
||||
RINOK(_extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
_outStreamWithHashSpec->ReleaseStream();
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CFolderOutStream::Write(const void *data,
|
||||
STDMETHODIMP CFolderOutStream::Write(const void *data,
|
||||
UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
UInt32 realProcessedSize = 0;
|
||||
@@ -88,14 +87,14 @@ STDMETHODIMP CFolderOutStream::Write(const void *data,
|
||||
if (_fileIsOpen)
|
||||
{
|
||||
UInt32 index = _startIndex + _currentIndex;
|
||||
const CFileItem &fileInfo = _archiveDatabase->Files[index];
|
||||
UInt64 fileSize = fileInfo.UnPackSize;
|
||||
const CFileItem &fi = _archiveDatabase->Files[index];
|
||||
UInt64 fileSize = fi.Size;
|
||||
|
||||
UInt32 numBytesToWrite = (UInt32)MyMin(fileSize - _filePos,
|
||||
UInt32 numBytesToWrite = (UInt32)MyMin(fileSize - _filePos,
|
||||
UInt64(size - realProcessedSize));
|
||||
|
||||
UInt32 processedSizeLocal;
|
||||
RINOK(_outStreamWithHash->Write((const Byte *)data + realProcessedSize,
|
||||
RINOK(_outStreamWithHash->Write((const Byte *)data + realProcessedSize,
|
||||
numBytesToWrite, &processedSizeLocal));
|
||||
|
||||
_filePos += processedSizeLocal;
|
||||
@@ -103,13 +102,13 @@ STDMETHODIMP CFolderOutStream::Write(const void *data,
|
||||
if (_filePos == fileSize)
|
||||
{
|
||||
bool digestsAreEqual;
|
||||
if (fileInfo.IsFileCRCDefined && _checkCrc)
|
||||
digestsAreEqual = fileInfo.FileCRC == _outStreamWithHashSpec->GetCRC();
|
||||
if (fi.CrcDefined && _checkCrc)
|
||||
digestsAreEqual = fi.Crc == _outStreamWithHashSpec->GetCRC();
|
||||
else
|
||||
digestsAreEqual = true;
|
||||
|
||||
RINOK(_extractCallback->SetOperationResult(
|
||||
digestsAreEqual ?
|
||||
digestsAreEqual ?
|
||||
NArchive::NExtract::NOperationResult::kOK :
|
||||
NArchive::NExtract::NOperationResult::kCRCError));
|
||||
_outStreamWithHashSpec->ReleaseStream();
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
class CFolderOutStream:
|
||||
class CFolderOutStream:
|
||||
public ISequentialOutStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
@@ -47,7 +47,7 @@ public:
|
||||
const CArchiveDatabaseEx *archiveDatabase,
|
||||
UInt32 ref2Offset,
|
||||
UInt32 startIndex,
|
||||
const CBoolVector *extractStatuses,
|
||||
const CBoolVector *extractStatuses,
|
||||
IArchiveExtractCallback *extractCallback,
|
||||
bool testMode,
|
||||
bool checkCrc);
|
||||
|
||||
@@ -10,9 +10,6 @@
|
||||
#include "../../../Windows/Defs.h"
|
||||
|
||||
#include "../Common/ItemNameUtils.h"
|
||||
#ifdef _7Z_VOL
|
||||
#include "../Common/MultiStream.h"
|
||||
#endif
|
||||
|
||||
#ifdef __7Z_SET_PROPERTIES
|
||||
#ifdef EXTRACT_ONLY
|
||||
@@ -35,9 +32,13 @@ CHandler::CHandler()
|
||||
{
|
||||
_crcSize = 4;
|
||||
|
||||
#ifndef _NO_CRYPTO
|
||||
_passwordIsDefined = false;
|
||||
#endif
|
||||
|
||||
#ifdef EXTRACT_ONLY
|
||||
#ifdef COMPRESS_MT
|
||||
_numThreads = NWindows::NSystem::GetNumberOfProcessors();
|
||||
_numThreads = NSystem::GetNumberOfProcessors();
|
||||
#endif
|
||||
#else
|
||||
Init();
|
||||
@@ -46,12 +47,7 @@ CHandler::CHandler()
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
{
|
||||
*numItems =
|
||||
#ifdef _7Z_VOL
|
||||
_refs.Size();
|
||||
#else
|
||||
*numItems = _database.Files.Size();
|
||||
#endif
|
||||
*numItems = _db.Files.Size();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -64,7 +60,7 @@ STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 * /* numProperties */)
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */,
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */,
|
||||
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
@@ -73,17 +69,20 @@ STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */,
|
||||
|
||||
#else
|
||||
|
||||
STATPROPSTG kArcProps[] =
|
||||
STATPROPSTG kArcProps[] =
|
||||
{
|
||||
{ NULL, kpidMethod, VT_BSTR},
|
||||
{ NULL, kpidSolid, VT_BOOL},
|
||||
{ NULL, kpidNumBlocks, VT_UI4}
|
||||
{ NULL, kpidNumBlocks, VT_UI4},
|
||||
{ NULL, kpidPhySize, VT_UI8},
|
||||
{ NULL, kpidHeadersSize, VT_UI8},
|
||||
{ NULL, kpidOffset, VT_UI8}
|
||||
};
|
||||
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
NCOM::CPropVariant prop;
|
||||
switch(propID)
|
||||
{
|
||||
case kpidMethod:
|
||||
@@ -91,9 +90,9 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
UString resString;
|
||||
CRecordVector<UInt64> ids;
|
||||
int i;
|
||||
for (i = 0; i < _database.Folders.Size(); i++)
|
||||
for (i = 0; i < _db.Folders.Size(); i++)
|
||||
{
|
||||
const CFolder &f = _database.Folders[i];
|
||||
const CFolder &f = _db.Folders[i];
|
||||
for (int j = f.Coders.Size() - 1; j >= 0; j--)
|
||||
ids.AddToUniqueSorted(f.Coders[j].MethodID);
|
||||
}
|
||||
@@ -109,11 +108,14 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
resString += L' ';
|
||||
resString += methodName;
|
||||
}
|
||||
prop = resString;
|
||||
prop = resString;
|
||||
break;
|
||||
}
|
||||
case kpidSolid: prop = _database.IsSolid(); break;
|
||||
case kpidNumBlocks: prop = (UInt32)_database.Folders.Size(); break;
|
||||
case kpidSolid: prop = _db.IsSolid(); break;
|
||||
case kpidNumBlocks: prop = (UInt32)_db.Folders.Size(); break;
|
||||
case kpidHeadersSize: prop = _db.HeadersSize; break;
|
||||
case kpidPhySize: prop = _db.PhySize; break;
|
||||
case kpidOffset: if (_db.ArchiveInfo.StartPosition != 0) prop = _db.ArchiveInfo.StartPosition; break;
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
@@ -124,10 +126,16 @@ IMP_IInArchive_ArcProps
|
||||
|
||||
#endif
|
||||
|
||||
static void MySetFileTime(bool timeDefined, FILETIME unixTime, NWindows::NCOM::CPropVariant &prop)
|
||||
static void SetPropFromUInt64Def(CUInt64DefVector &v, int index, NCOM::CPropVariant &prop)
|
||||
{
|
||||
if (timeDefined)
|
||||
prop = unixTime;
|
||||
UInt64 value;
|
||||
if (v.GetItem(index, value))
|
||||
{
|
||||
FILETIME ft;
|
||||
ft.dwLowDateTime = (DWORD)value;
|
||||
ft.dwHighDateTime = (DWORD)(value >> 32);
|
||||
prop = ft;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef _SFX
|
||||
@@ -192,10 +200,10 @@ static inline UInt32 GetUInt32FromMemLE(const Byte *p)
|
||||
|
||||
bool CHandler::IsEncrypted(UInt32 index2) const
|
||||
{
|
||||
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
|
||||
CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
|
||||
if (folderIndex != kNumNoIndex)
|
||||
{
|
||||
const CFolder &folderInfo = _database.Folders[folderIndex];
|
||||
const CFolder &folderInfo = _db.Folders[folderIndex];
|
||||
for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--)
|
||||
if (folderInfo.Coders[i].MethodID == k_AES)
|
||||
return true;
|
||||
@@ -206,7 +214,7 @@ bool CHandler::IsEncrypted(UInt32 index2) const
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
NCOM::CPropVariant prop;
|
||||
|
||||
/*
|
||||
const CRef2 &ref2 = _refs[index];
|
||||
@@ -215,54 +223,31 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
||||
const CRef &ref = ref2.Refs.Front();
|
||||
*/
|
||||
|
||||
#ifdef _7Z_VOL
|
||||
const CRef &ref = _refs[index];
|
||||
const CVolume &volume = _volumes[ref.VolumeIndex];
|
||||
const CArchiveDatabaseEx &_database = volume.Database;
|
||||
UInt32 index2 = ref.ItemIndex;
|
||||
const CFileItem &item = _database.Files[index2];
|
||||
#else
|
||||
const CFileItem &item = _database.Files[index];
|
||||
const CFileItem &item = _db.Files[index];
|
||||
UInt32 index2 = index;
|
||||
#endif
|
||||
|
||||
switch(propID)
|
||||
{
|
||||
case kpidPath:
|
||||
{
|
||||
if (!item.Name.IsEmpty())
|
||||
prop = NItemName::GetOSName(item.Name);
|
||||
break;
|
||||
}
|
||||
case kpidIsFolder:
|
||||
prop = item.IsDirectory;
|
||||
break;
|
||||
case kpidIsDir: prop = item.IsDir; break;
|
||||
case kpidSize:
|
||||
{
|
||||
prop = item.UnPackSize;
|
||||
// prop = ref2.UnPackSize;
|
||||
prop = item.Size;
|
||||
// prop = ref2.Size;
|
||||
break;
|
||||
}
|
||||
case kpidPosition:
|
||||
{
|
||||
/*
|
||||
if (ref2.Refs.Size() > 1)
|
||||
prop = ref2.StartPos;
|
||||
else
|
||||
*/
|
||||
if (item.IsStartPosDefined)
|
||||
prop = item.StartPos;
|
||||
break;
|
||||
}
|
||||
case kpidPackedSize:
|
||||
case kpidPackSize:
|
||||
{
|
||||
// prop = ref2.PackSize;
|
||||
{
|
||||
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
|
||||
CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
|
||||
if (folderIndex != kNumNoIndex)
|
||||
{
|
||||
if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2)
|
||||
prop = _database.GetFolderFullPackSize(folderIndex);
|
||||
if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2)
|
||||
prop = _db.GetFolderFullPackSize(folderIndex);
|
||||
/*
|
||||
else
|
||||
prop = (UInt64)0;
|
||||
@@ -273,35 +258,21 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kpidLastAccessTime:
|
||||
MySetFileTime(item.IsLastAccessTimeDefined, item.LastAccessTime, prop);
|
||||
break;
|
||||
case kpidCreationTime:
|
||||
MySetFileTime(item.IsCreationTimeDefined, item.CreationTime, prop);
|
||||
break;
|
||||
case kpidLastWriteTime:
|
||||
MySetFileTime(item.IsLastWriteTimeDefined, item.LastWriteTime, prop);
|
||||
break;
|
||||
case kpidAttributes:
|
||||
if (item.AreAttributesDefined)
|
||||
prop = item.Attributes;
|
||||
break;
|
||||
case kpidCRC:
|
||||
if (item.IsFileCRCDefined)
|
||||
prop = item.FileCRC;
|
||||
break;
|
||||
case kpidEncrypted:
|
||||
{
|
||||
prop = IsEncrypted(index2);
|
||||
break;
|
||||
}
|
||||
case kpidPosition: { UInt64 v; if (_db.StartPos.GetItem(index2, v)) prop = v; break; }
|
||||
case kpidCTime: SetPropFromUInt64Def(_db.CTime, index2, prop); break;
|
||||
case kpidATime: SetPropFromUInt64Def(_db.ATime, index2, prop); break;
|
||||
case kpidMTime: SetPropFromUInt64Def(_db.MTime, index2, prop); break;
|
||||
case kpidAttrib: if (item.AttribDefined) prop = item.Attrib; break;
|
||||
case kpidCRC: if (item.CrcDefined) prop = item.Crc; break;
|
||||
case kpidEncrypted: prop = IsEncrypted(index2); break;
|
||||
case kpidIsAnti: prop = _db.IsItemAnti(index2); break;
|
||||
#ifndef _SFX
|
||||
case kpidMethod:
|
||||
{
|
||||
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
|
||||
CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
|
||||
if (folderIndex != kNumNoIndex)
|
||||
{
|
||||
const CFolder &folderInfo = _database.Folders[folderIndex];
|
||||
const CFolder &folderInfo = _db.Folders[folderIndex];
|
||||
UString methodsString;
|
||||
for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--)
|
||||
{
|
||||
@@ -312,7 +283,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
||||
{
|
||||
UString methodName;
|
||||
bool methodIsKnown = FindMethod(
|
||||
EXTERNAL_CODECS_VARS
|
||||
EXTERNAL_CODECS_VARS
|
||||
coderInfo.MethodID, methodName);
|
||||
|
||||
if (methodIsKnown)
|
||||
@@ -398,7 +369,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
||||
break;
|
||||
case kpidBlock:
|
||||
{
|
||||
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
|
||||
CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
|
||||
if (folderIndex != kNumNoIndex)
|
||||
prop = (UInt32)folderIndex;
|
||||
}
|
||||
@@ -409,14 +380,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
||||
case kpidPackedSize3:
|
||||
case kpidPackedSize4:
|
||||
{
|
||||
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
|
||||
CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
|
||||
if (folderIndex != kNumNoIndex)
|
||||
{
|
||||
const CFolder &folderInfo = _database.Folders[folderIndex];
|
||||
if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2 &&
|
||||
const CFolder &folderInfo = _db.Folders[folderIndex];
|
||||
if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2 &&
|
||||
folderInfo.PackStreams.Size() > (int)(propID - kpidPackedSize0))
|
||||
{
|
||||
prop = _database.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0);
|
||||
prop = _db.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0);
|
||||
}
|
||||
else
|
||||
prop = (UInt64)0;
|
||||
@@ -426,97 +397,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case kpidIsAnti:
|
||||
prop = item.IsAnti;
|
||||
break;
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
#ifdef _7Z_VOL
|
||||
|
||||
static const wchar_t *kExt = L"7z";
|
||||
static const wchar_t *kAfterPart = L".7z";
|
||||
|
||||
class CVolumeName
|
||||
{
|
||||
bool _first;
|
||||
UString _unchangedPart;
|
||||
UString _changedPart;
|
||||
UString _afterPart;
|
||||
public:
|
||||
bool InitName(const UString &name)
|
||||
{
|
||||
_first = true;
|
||||
int dotPos = name.ReverseFind('.');
|
||||
UString basePart = name;
|
||||
if (dotPos >= 0)
|
||||
{
|
||||
UString ext = name.Mid(dotPos + 1);
|
||||
if (ext.CompareNoCase(kExt)==0 ||
|
||||
ext.CompareNoCase(L"EXE") == 0)
|
||||
{
|
||||
_afterPart = kAfterPart;
|
||||
basePart = name.Left(dotPos);
|
||||
}
|
||||
}
|
||||
|
||||
int numLetters = 1;
|
||||
bool splitStyle = false;
|
||||
if (basePart.Right(numLetters) == L"1")
|
||||
{
|
||||
while (numLetters < basePart.Length())
|
||||
{
|
||||
if (basePart[basePart.Length() - numLetters - 1] != '0')
|
||||
break;
|
||||
numLetters++;
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
_unchangedPart = basePart.Left(basePart.Length() - numLetters);
|
||||
_changedPart = basePart.Right(numLetters);
|
||||
return true;
|
||||
}
|
||||
|
||||
UString GetNextName()
|
||||
{
|
||||
UString newName;
|
||||
// if (_newStyle || !_first)
|
||||
{
|
||||
int i;
|
||||
int numLetters = _changedPart.Length();
|
||||
for (i = numLetters - 1; i >= 0; i--)
|
||||
{
|
||||
wchar_t c = _changedPart[i];
|
||||
if (c == L'9')
|
||||
{
|
||||
c = L'0';
|
||||
newName = c + newName;
|
||||
if (i == 0)
|
||||
newName = UString(L'1') + newName;
|
||||
continue;
|
||||
}
|
||||
c++;
|
||||
newName = UString(c) + newName;
|
||||
i--;
|
||||
for (; i >= 0; i--)
|
||||
newName = _changedPart[i] + newName;
|
||||
break;
|
||||
}
|
||||
_changedPart = newName;
|
||||
}
|
||||
_first = false;
|
||||
return _unchangedPart + _changedPart + _afterPart;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
const UInt64 *maxCheckStartPosition,
|
||||
const UInt64 *maxCheckStartPosition,
|
||||
IArchiveOpenCallback *openArchiveCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
@@ -527,11 +415,6 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
try
|
||||
{
|
||||
CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = openArchiveCallback;
|
||||
#ifdef _7Z_VOL
|
||||
CVolumeName seqName;
|
||||
|
||||
CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
|
||||
#endif
|
||||
|
||||
#ifndef _NO_CRYPTO
|
||||
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
|
||||
@@ -541,127 +424,22 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
IID_ICryptoGetTextPassword, &getTextPassword);
|
||||
}
|
||||
#endif
|
||||
#ifdef _7Z_VOL
|
||||
if (openArchiveCallback)
|
||||
{
|
||||
openArchiveCallbackTemp.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback);
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
CMyComPtr<IInStream> inStream;
|
||||
if (!_volumes.IsEmpty())
|
||||
{
|
||||
if (!openVolumeCallback)
|
||||
break;
|
||||
if(_volumes.Size() == 1)
|
||||
{
|
||||
UString baseName;
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(openVolumeCallback->GetProperty(kpidName, &prop));
|
||||
if (prop.vt != VT_BSTR)
|
||||
break;
|
||||
baseName = prop.bstrVal;
|
||||
}
|
||||
seqName.InitName(baseName);
|
||||
}
|
||||
|
||||
UString fullName = seqName.GetNextName();
|
||||
HRESULT result = openVolumeCallback->GetStream(fullName, &inStream);
|
||||
if (result == S_FALSE)
|
||||
break;
|
||||
if (result != S_OK)
|
||||
return result;
|
||||
if (!stream)
|
||||
break;
|
||||
}
|
||||
else
|
||||
inStream = stream;
|
||||
|
||||
CInArchive archive;
|
||||
RINOK(archive.Open(inStream, maxCheckStartPosition));
|
||||
|
||||
_volumes.Add(CVolume());
|
||||
CVolume &volume = _volumes.Back();
|
||||
CArchiveDatabaseEx &database = volume.Database;
|
||||
volume.Stream = inStream;
|
||||
volume.StartRef2Index = _refs.Size();
|
||||
|
||||
HRESULT result = archive.ReadDatabase(database
|
||||
#ifndef _NO_CRYPTO
|
||||
, getTextPassword
|
||||
#endif
|
||||
);
|
||||
if (result != S_OK)
|
||||
{
|
||||
_volumes.Clear();
|
||||
return result;
|
||||
}
|
||||
database.Fill();
|
||||
for(int i = 0; i < database.Files.Size(); i++)
|
||||
{
|
||||
CRef refNew;
|
||||
refNew.VolumeIndex = _volumes.Size() - 1;
|
||||
refNew.ItemIndex = i;
|
||||
_refs.Add(refNew);
|
||||
/*
|
||||
const CFileItem &file = database.Files[i];
|
||||
int j;
|
||||
*/
|
||||
/*
|
||||
for (j = _refs.Size() - 1; j >= 0; j--)
|
||||
{
|
||||
CRef2 &ref2 = _refs[j];
|
||||
const CRef &ref = ref2.Refs.Back();
|
||||
const CVolume &volume2 = _volumes[ref.VolumeIndex];
|
||||
const CArchiveDatabaseEx &database2 = volume2.Database;
|
||||
const CFileItem &file2 = database2.Files[ref.ItemIndex];
|
||||
if (file2.Name.CompareNoCase(file.Name) == 0)
|
||||
{
|
||||
if (!file.IsStartPosDefined)
|
||||
continue;
|
||||
if (file.StartPos != ref2.StartPos + ref2.UnPackSize)
|
||||
continue;
|
||||
ref2.Refs.Add(refNew);
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
/*
|
||||
j = -1;
|
||||
if (j < 0)
|
||||
{
|
||||
CRef2 ref2New;
|
||||
ref2New.Refs.Add(refNew);
|
||||
j = _refs.Add(ref2New);
|
||||
}
|
||||
CRef2 &ref2 = _refs[j];
|
||||
ref2.UnPackSize += file.UnPackSize;
|
||||
ref2.PackSize += database.GetFilePackSize(i);
|
||||
if (ref2.Refs.Size() == 1 && file.IsStartPosDefined)
|
||||
ref2.StartPos = file.StartPos;
|
||||
*/
|
||||
}
|
||||
if (database.Files.Size() != 1)
|
||||
break;
|
||||
const CFileItem &file = database.Files.Front();
|
||||
if (!file.IsStartPosDefined)
|
||||
break;
|
||||
}
|
||||
#else
|
||||
CInArchive archive;
|
||||
RINOK(archive.Open(stream, maxCheckStartPosition));
|
||||
#ifndef _NO_CRYPTO
|
||||
_passwordIsDefined = false;
|
||||
UString password;
|
||||
#endif
|
||||
HRESULT result = archive.ReadDatabase(
|
||||
EXTERNAL_CODECS_VARS
|
||||
_database
|
||||
_db
|
||||
#ifndef _NO_CRYPTO
|
||||
, getTextPassword
|
||||
, getTextPassword, _passwordIsDefined
|
||||
#endif
|
||||
);
|
||||
RINOK(result);
|
||||
_database.Fill();
|
||||
_db.Fill();
|
||||
_inStream = stream;
|
||||
#endif
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
@@ -679,75 +457,12 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
STDMETHODIMP CHandler::Close()
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
#ifdef _7Z_VOL
|
||||
_volumes.Clear();
|
||||
_refs.Clear();
|
||||
#else
|
||||
_inStream.Release();
|
||||
_database.Clear();
|
||||
#endif
|
||||
_db.Clear();
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
#ifdef _7Z_VOL
|
||||
STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
|
||||
{
|
||||
if (index != 0)
|
||||
return E_INVALIDARG;
|
||||
*stream = 0;
|
||||
CMultiStream *streamSpec = new CMultiStream;
|
||||
CMyComPtr<ISequentialInStream> streamTemp = streamSpec;
|
||||
|
||||
UInt64 pos = 0;
|
||||
const UString *fileName;
|
||||
for (int i = 0; i < _refs.Size(); i++)
|
||||
{
|
||||
const CRef &ref = _refs[i];
|
||||
const CVolume &volume = _volumes[ref.VolumeIndex];
|
||||
const CArchiveDatabaseEx &database = volume.Database;
|
||||
const CFileItem &file = database.Files[ref.ItemIndex];
|
||||
if (i == 0)
|
||||
fileName = &file.Name;
|
||||
else
|
||||
if (fileName->Compare(file.Name) != 0)
|
||||
return S_FALSE;
|
||||
if (!file.IsStartPosDefined)
|
||||
return S_FALSE;
|
||||
if (file.StartPos != pos)
|
||||
return S_FALSE;
|
||||
CNum folderIndex = database.FileIndexToFolderIndexMap[ref.ItemIndex];
|
||||
if (folderIndex == kNumNoIndex)
|
||||
{
|
||||
if (file.UnPackSize != 0)
|
||||
return E_FAIL;
|
||||
continue;
|
||||
}
|
||||
if (database.NumUnPackStreamsVector[folderIndex] != 1)
|
||||
return S_FALSE;
|
||||
const CFolder &folder = database.Folders[folderIndex];
|
||||
if (folder.Coders.Size() != 1)
|
||||
return S_FALSE;
|
||||
const CCoderInfo &coder = folder.Coders.Front();
|
||||
if (coder.NumInStreams != 1 || coder.NumOutStreams != 1)
|
||||
return S_FALSE;
|
||||
if (coder.MethodID != k_Copy)
|
||||
return S_FALSE;
|
||||
|
||||
pos += file.UnPackSize;
|
||||
CMultiStream::CSubStreamInfo subStreamInfo;
|
||||
subStreamInfo.Stream = volume.Stream;
|
||||
subStreamInfo.Pos = database.GetFolderStreamPos(folderIndex, 0);
|
||||
subStreamInfo.Size = file.UnPackSize;
|
||||
streamSpec->Streams.Add(subStreamInfo);
|
||||
}
|
||||
streamSpec->Init();
|
||||
*stream = streamTemp.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __7Z_SET_PROPERTIES
|
||||
#ifdef EXTRACT_ONLY
|
||||
|
||||
@@ -783,7 +498,7 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -18,56 +18,35 @@
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
#ifdef _7Z_VOL
|
||||
struct CRef
|
||||
{
|
||||
int VolumeIndex;
|
||||
int ItemIndex;
|
||||
};
|
||||
|
||||
struct CVolume
|
||||
{
|
||||
int StartRef2Index;
|
||||
CMyComPtr<IInStream> Stream;
|
||||
CArchiveDatabaseEx Database;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef __7Z_SET_PROPERTIES
|
||||
|
||||
#ifdef EXTRACT_ONLY
|
||||
#ifdef COMPRESS_MT
|
||||
#define __7Z_SET_PROPERTIES
|
||||
#endif
|
||||
#else
|
||||
#else
|
||||
#define __7Z_SET_PROPERTIES
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
class CHandler:
|
||||
class CHandler:
|
||||
#ifndef EXTRACT_ONLY
|
||||
public NArchive::COutHandler,
|
||||
#endif
|
||||
public IInArchive,
|
||||
#ifdef _7Z_VOL
|
||||
public IInArchiveGetStream,
|
||||
#endif
|
||||
#ifdef __7Z_SET_PROPERTIES
|
||||
public ISetProperties,
|
||||
public ISetProperties,
|
||||
#endif
|
||||
#ifndef EXTRACT_ONLY
|
||||
public IOutArchive,
|
||||
public IOutArchive,
|
||||
#endif
|
||||
PUBLIC_ISetCompressCodecsInfo
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
MY_QUERYINTERFACE_BEGIN2(IInArchive)
|
||||
#ifdef _7Z_VOL
|
||||
MY_QUERYINTERFACE_ENTRY(IInArchiveGetStream)
|
||||
#endif
|
||||
#ifdef __7Z_SET_PROPERTIES
|
||||
MY_QUERYINTERFACE_ENTRY(ISetProperties)
|
||||
#endif
|
||||
@@ -80,10 +59,6 @@ public:
|
||||
|
||||
INTERFACE_IInArchive(;)
|
||||
|
||||
#ifdef _7Z_VOL
|
||||
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
|
||||
#endif
|
||||
|
||||
#ifdef __7Z_SET_PROPERTIES
|
||||
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties);
|
||||
#endif
|
||||
@@ -97,12 +72,10 @@ public:
|
||||
CHandler();
|
||||
|
||||
private:
|
||||
#ifdef _7Z_VOL
|
||||
CObjectVector<CVolume> _volumes;
|
||||
CObjectVector<CRef> _refs;
|
||||
#else
|
||||
CMyComPtr<IInStream> _inStream;
|
||||
NArchive::N7z::CArchiveDatabaseEx _database;
|
||||
NArchive::N7z::CArchiveDatabaseEx _db;
|
||||
#ifndef _NO_CRYPTO
|
||||
bool _passwordIsDefined;
|
||||
#endif
|
||||
|
||||
#ifdef EXTRACT_ONLY
|
||||
@@ -139,6 +112,8 @@ private:
|
||||
void FillPopIDs();
|
||||
|
||||
#endif
|
||||
|
||||
DECL_EXTERNAL_CODECS_VARS
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -163,7 +163,7 @@ HRESULT CHandler::SetCompressionMethod(
|
||||
for (int j = 0; j < methodFull.Properties.Size(); j++)
|
||||
{
|
||||
const CProp &prop = methodFull.Properties[j];
|
||||
if ((prop.Id == NCoderPropID::kDictionarySize ||
|
||||
if ((prop.Id == NCoderPropID::kDictionarySize ||
|
||||
prop.Id == NCoderPropID::kUsedMemorySize) && prop.Value.vt == VT_UI4)
|
||||
{
|
||||
_numSolidBytes = ((UInt64)prop.Value.ulVal) << 7;
|
||||
@@ -185,17 +185,20 @@ HRESULT CHandler::SetCompressionMethod(
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, PROPID propID, CArchiveFileTime &filetime, bool &filetimeIsDefined)
|
||||
static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, bool writeTime, PROPID propID, UInt64 &ft, bool &ftDefined)
|
||||
{
|
||||
filetimeIsDefined = false;
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(updateCallback->GetProperty(index, propID, &propVariant));
|
||||
if (propVariant.vt == VT_FILETIME)
|
||||
ft = 0;
|
||||
ftDefined = false;
|
||||
if (!writeTime)
|
||||
return S_OK;
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(updateCallback->GetProperty(index, propID, &prop));
|
||||
if (prop.vt == VT_FILETIME)
|
||||
{
|
||||
filetime = propVariant.filetime;
|
||||
filetimeIsDefined = true;
|
||||
ft = prop.filetime.dwLowDateTime | ((UInt64)prop.filetime.dwHighDateTime << 32);
|
||||
ftDefined = true;
|
||||
}
|
||||
else if (propVariant.vt != VT_EMPTY)
|
||||
else if (prop.vt != VT_EMPTY)
|
||||
return E_INVALIDARG;
|
||||
return S_OK;
|
||||
}
|
||||
@@ -205,7 +208,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
|
||||
const CArchiveDatabaseEx *database = 0;
|
||||
const CArchiveDatabaseEx *db = 0;
|
||||
#ifdef _7Z_VOL
|
||||
if(_volumes.Size() > 1)
|
||||
return E_FAIL;
|
||||
@@ -213,139 +216,131 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
if (_volumes.Size() == 1)
|
||||
{
|
||||
volume = &_volumes.Front();
|
||||
database = &volume->Database;
|
||||
db = &volume->Database;
|
||||
}
|
||||
#else
|
||||
if (_inStream != 0)
|
||||
database = &_database;
|
||||
db = &_db;
|
||||
#endif
|
||||
|
||||
// CRecordVector<bool> compressStatuses;
|
||||
CObjectVector<CUpdateItem> updateItems;
|
||||
// CRecordVector<UInt32> copyIndices;
|
||||
|
||||
// CMyComPtr<IUpdateCallback2> updateCallback2;
|
||||
// updateCallback->QueryInterface(&updateCallback2);
|
||||
|
||||
for(UInt32 i = 0; i < numItems; i++)
|
||||
for (UInt32 i = 0; i < numItems; i++)
|
||||
{
|
||||
Int32 newData;
|
||||
Int32 newProperties;
|
||||
UInt32 indexInArchive;
|
||||
if (!updateCallback)
|
||||
return E_FAIL;
|
||||
RINOK(updateCallback->GetUpdateItemInfo(i,
|
||||
&newData, &newProperties, &indexInArchive));
|
||||
CUpdateItem updateItem;
|
||||
updateItem.NewProperties = IntToBool(newProperties);
|
||||
updateItem.NewData = IntToBool(newData);
|
||||
updateItem.IndexInArchive = indexInArchive;
|
||||
updateItem.IndexInClient = i;
|
||||
updateItem.IsAnti = false;
|
||||
updateItem.Size = 0;
|
||||
RINOK(updateCallback->GetUpdateItemInfo(i, &newData, &newProperties, &indexInArchive));
|
||||
CUpdateItem ui;
|
||||
ui.NewProperties = IntToBool(newProperties);
|
||||
ui.NewData = IntToBool(newData);
|
||||
ui.IndexInArchive = indexInArchive;
|
||||
ui.IndexInClient = i;
|
||||
ui.IsAnti = false;
|
||||
ui.Size = 0;
|
||||
|
||||
if (updateItem.IndexInArchive != -1)
|
||||
if (ui.IndexInArchive != -1)
|
||||
{
|
||||
const CFileItem &fileItem = database->Files[updateItem.IndexInArchive];
|
||||
updateItem.Name = fileItem.Name;
|
||||
updateItem.IsDirectory = fileItem.IsDirectory;
|
||||
updateItem.Size = fileItem.UnPackSize;
|
||||
updateItem.IsAnti = fileItem.IsAnti;
|
||||
const CFileItem &fi = db->Files[ui.IndexInArchive];
|
||||
ui.Name = fi.Name;
|
||||
ui.IsDir = fi.IsDir;
|
||||
ui.Size = fi.Size;
|
||||
ui.IsAnti = db->IsItemAnti(ui.IndexInArchive);
|
||||
|
||||
updateItem.CreationTime = fileItem.CreationTime;
|
||||
updateItem.IsCreationTimeDefined = fileItem.IsCreationTimeDefined;
|
||||
updateItem.LastWriteTime = fileItem.LastWriteTime;
|
||||
updateItem.IsLastWriteTimeDefined = fileItem.IsLastWriteTimeDefined;
|
||||
updateItem.LastAccessTime = fileItem.LastAccessTime;
|
||||
updateItem.IsLastAccessTimeDefined = fileItem.IsLastAccessTimeDefined;
|
||||
ui.CTimeDefined = db->CTime.GetItem(ui.IndexInArchive, ui.CTime);
|
||||
ui.ATimeDefined = db->ATime.GetItem(ui.IndexInArchive, ui.ATime);
|
||||
ui.MTimeDefined = db->MTime.GetItem(ui.IndexInArchive, ui.MTime);
|
||||
}
|
||||
|
||||
if (updateItem.NewProperties)
|
||||
if (ui.NewProperties)
|
||||
{
|
||||
bool nameIsDefined;
|
||||
bool folderStatusIsDefined;
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(updateCallback->GetProperty(i, kpidAttributes, &propVariant));
|
||||
if (propVariant.vt == VT_EMPTY)
|
||||
updateItem.AttributesAreDefined = false;
|
||||
else if (propVariant.vt != VT_UI4)
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(updateCallback->GetProperty(i, kpidAttrib, &prop));
|
||||
if (prop.vt == VT_EMPTY)
|
||||
ui.AttribDefined = false;
|
||||
else if (prop.vt != VT_UI4)
|
||||
return E_INVALIDARG;
|
||||
else
|
||||
{
|
||||
updateItem.Attributes = propVariant.ulVal;
|
||||
updateItem.AttributesAreDefined = true;
|
||||
ui.Attrib = prop.ulVal;
|
||||
ui.AttribDefined = true;
|
||||
}
|
||||
}
|
||||
|
||||
RINOK(GetTime(updateCallback, i, kpidCreationTime, updateItem.CreationTime, updateItem.IsCreationTimeDefined));
|
||||
RINOK(GetTime(updateCallback, i, kpidLastWriteTime, updateItem.LastWriteTime , updateItem.IsLastWriteTimeDefined));
|
||||
RINOK(GetTime(updateCallback, i, kpidLastAccessTime, updateItem.LastAccessTime, updateItem.IsLastAccessTimeDefined));
|
||||
// we need MTime to sort files.
|
||||
RINOK(GetTime(updateCallback, i, WriteCTime, kpidCTime, ui.CTime, ui.CTimeDefined));
|
||||
RINOK(GetTime(updateCallback, i, WriteATime, kpidATime, ui.ATime, ui.ATimeDefined));
|
||||
RINOK(GetTime(updateCallback, i, true, kpidMTime, ui.MTime, ui.MTimeDefined));
|
||||
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(updateCallback->GetProperty(i, kpidPath, &propVariant));
|
||||
if (propVariant.vt == VT_EMPTY)
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(updateCallback->GetProperty(i, kpidPath, &prop));
|
||||
if (prop.vt == VT_EMPTY)
|
||||
nameIsDefined = false;
|
||||
else if (propVariant.vt != VT_BSTR)
|
||||
else if (prop.vt != VT_BSTR)
|
||||
return E_INVALIDARG;
|
||||
else
|
||||
{
|
||||
updateItem.Name = NItemName::MakeLegalName(propVariant.bstrVal);
|
||||
ui.Name = NItemName::MakeLegalName(prop.bstrVal);
|
||||
nameIsDefined = true;
|
||||
}
|
||||
}
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(updateCallback->GetProperty(i, kpidIsFolder, &propVariant));
|
||||
if (propVariant.vt == VT_EMPTY)
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(updateCallback->GetProperty(i, kpidIsDir, &prop));
|
||||
if (prop.vt == VT_EMPTY)
|
||||
folderStatusIsDefined = false;
|
||||
else if (propVariant.vt != VT_BOOL)
|
||||
else if (prop.vt != VT_BOOL)
|
||||
return E_INVALIDARG;
|
||||
else
|
||||
{
|
||||
updateItem.IsDirectory = (propVariant.boolVal != VARIANT_FALSE);
|
||||
ui.IsDir = (prop.boolVal != VARIANT_FALSE);
|
||||
folderStatusIsDefined = true;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(updateCallback->GetProperty(i, kpidIsAnti, &propVariant));
|
||||
if (propVariant.vt == VT_EMPTY)
|
||||
updateItem.IsAnti = false;
|
||||
else if (propVariant.vt != VT_BOOL)
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(updateCallback->GetProperty(i, kpidIsAnti, &prop));
|
||||
if (prop.vt == VT_EMPTY)
|
||||
ui.IsAnti = false;
|
||||
else if (prop.vt != VT_BOOL)
|
||||
return E_INVALIDARG;
|
||||
else
|
||||
updateItem.IsAnti = (propVariant.boolVal != VARIANT_FALSE);
|
||||
ui.IsAnti = (prop.boolVal != VARIANT_FALSE);
|
||||
}
|
||||
|
||||
if (updateItem.IsAnti)
|
||||
if (ui.IsAnti)
|
||||
{
|
||||
updateItem.AttributesAreDefined = false;
|
||||
ui.AttribDefined = false;
|
||||
|
||||
updateItem.IsCreationTimeDefined = false;
|
||||
updateItem.IsLastWriteTimeDefined = false;
|
||||
updateItem.IsLastAccessTimeDefined = false;
|
||||
ui.CTimeDefined = false;
|
||||
ui.ATimeDefined = false;
|
||||
ui.MTimeDefined = false;
|
||||
|
||||
updateItem.Size = 0;
|
||||
ui.Size = 0;
|
||||
}
|
||||
|
||||
if (!folderStatusIsDefined && updateItem.AttributesAreDefined)
|
||||
updateItem.SetDirectoryStatusFromAttributes();
|
||||
if (!folderStatusIsDefined && ui.AttribDefined)
|
||||
ui.SetDirStatusFromAttrib();
|
||||
}
|
||||
|
||||
if (updateItem.NewData)
|
||||
if (ui.NewData)
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(updateCallback->GetProperty(i, kpidSize, &propVariant));
|
||||
if (propVariant.vt != VT_UI8)
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(updateCallback->GetProperty(i, kpidSize, &prop));
|
||||
if (prop.vt != VT_UI8)
|
||||
return E_INVALIDARG;
|
||||
updateItem.Size = (UInt64)propVariant.uhVal.QuadPart;
|
||||
if (updateItem.Size != 0 && updateItem.IsAnti)
|
||||
ui.Size = (UInt64)prop.uhVal.QuadPart;
|
||||
if (ui.Size != 0 && ui.IsAnti)
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
updateItems.Add(updateItem);
|
||||
updateItems.Add(ui);
|
||||
}
|
||||
|
||||
CCompressionMethodMode methodMode, headerMethod;
|
||||
@@ -359,10 +354,18 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
|
||||
bool compressMainHeader = _compressHeaders; // check it
|
||||
|
||||
bool encryptHeaders = false;
|
||||
|
||||
if (methodMode.PasswordIsDefined)
|
||||
{
|
||||
compressMainHeader = true;
|
||||
if(_encryptHeaders)
|
||||
if (_encryptHeadersSpecified)
|
||||
encryptHeaders = _encryptHeaders;
|
||||
#ifndef _NO_CRYPTO
|
||||
else
|
||||
encryptHeaders = _passwordIsDefined;
|
||||
#endif
|
||||
compressMainHeader = true;
|
||||
if(encryptHeaders)
|
||||
RINOK(SetPassword(headerMethod, updateCallback));
|
||||
}
|
||||
|
||||
@@ -371,32 +374,42 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
|
||||
CUpdateOptions options;
|
||||
options.Method = &methodMode;
|
||||
options.HeaderMethod = (_compressHeaders ||
|
||||
(methodMode.PasswordIsDefined && _encryptHeaders)) ?
|
||||
&headerMethod : 0;
|
||||
options.HeaderMethod = (_compressHeaders || encryptHeaders) ? &headerMethod : 0;
|
||||
options.UseFilters = _level != 0 && _autoFilter;
|
||||
options.MaxFilter = _level >= 8;
|
||||
|
||||
options.HeaderOptions.CompressMainHeader = compressMainHeader;
|
||||
options.HeaderOptions.WriteModified = WriteModified;
|
||||
options.HeaderOptions.WriteCreated = WriteCreated;
|
||||
options.HeaderOptions.WriteAccessed = WriteAccessed;
|
||||
options.HeaderOptions.WriteCTime = WriteCTime;
|
||||
options.HeaderOptions.WriteATime = WriteATime;
|
||||
options.HeaderOptions.WriteMTime = WriteMTime;
|
||||
|
||||
options.NumSolidFiles = _numSolidFiles;
|
||||
options.NumSolidBytes = _numSolidBytes;
|
||||
options.SolidExtension = _solidExtension;
|
||||
options.RemoveSfxBlock = _removeSfxBlock;
|
||||
options.VolumeMode = _volumeMode;
|
||||
return Update(
|
||||
|
||||
COutArchive archive;
|
||||
CArchiveDatabase newDatabase;
|
||||
HRESULT res = Update(
|
||||
EXTERNAL_CODECS_VARS
|
||||
#ifdef _7Z_VOL
|
||||
volume ? volume->Stream: 0,
|
||||
volume ? database: 0,
|
||||
volume ? volume->Stream: 0,
|
||||
volume ? db : 0,
|
||||
#else
|
||||
_inStream,
|
||||
database,
|
||||
_inStream,
|
||||
db,
|
||||
#endif
|
||||
updateItems, outStream, updateCallback, options);
|
||||
updateItems,
|
||||
archive, newDatabase, outStream, updateCallback, options);
|
||||
|
||||
RINOK(res);
|
||||
|
||||
updateItems.ClearAndFree();
|
||||
|
||||
return archive.WriteDatabase(EXTERNAL_CODECS_VARS
|
||||
newDatabase, options.HeaderMethod, options.HeaderOptions);
|
||||
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
@@ -459,6 +472,6 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
|
||||
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -14,9 +14,9 @@ Byte kFinishSignature[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C +
|
||||
class SignatureInitializer
|
||||
{
|
||||
public:
|
||||
SignatureInitializer()
|
||||
{
|
||||
kSignature[0]--;
|
||||
SignatureInitializer()
|
||||
{
|
||||
kSignature[0]--;
|
||||
#ifdef _7Z_VOL
|
||||
kFinishSignature[0]--;
|
||||
#endif
|
||||
|
||||
@@ -13,7 +13,7 @@ extern Byte kSignature[kSignatureSize];
|
||||
|
||||
// #define _7Z_VOL
|
||||
// 7z-MultiVolume is not finished yet.
|
||||
// It can work already, but I still do not like some
|
||||
// It can work already, but I still do not like some
|
||||
// things of that new multivolume format.
|
||||
// So please keep it commented.
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace NID
|
||||
kFilesInfo,
|
||||
|
||||
kPackInfo,
|
||||
kUnPackInfo,
|
||||
kUnpackInfo,
|
||||
kSubStreamsInfo,
|
||||
|
||||
kSize,
|
||||
@@ -71,23 +71,24 @@ namespace NID
|
||||
|
||||
kFolder,
|
||||
|
||||
kCodersUnPackSize,
|
||||
kNumUnPackStream,
|
||||
kCodersUnpackSize,
|
||||
kNumUnpackStream,
|
||||
|
||||
kEmptyStream,
|
||||
kEmptyFile,
|
||||
kAnti,
|
||||
|
||||
kName,
|
||||
kCreationTime,
|
||||
kLastAccessTime,
|
||||
kLastWriteTime,
|
||||
kCTime,
|
||||
kATime,
|
||||
kMTime,
|
||||
kWinAttributes,
|
||||
kComment,
|
||||
|
||||
kEncodedHeader,
|
||||
|
||||
kStartPos
|
||||
kStartPos,
|
||||
kDummy
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -6,13 +6,17 @@
|
||||
#include "7zDecode.h"
|
||||
#include "../../Common/StreamObjects.h"
|
||||
#include "../../Common/StreamUtils.h"
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../../C/7zCrc.h"
|
||||
#include "../../../../C/CpuArch.h"
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../../C/7zCrc.h"
|
||||
#include "../../../../C/CpuArch.h"
|
||||
}
|
||||
|
||||
// define FORMAT_7Z_RECOVERY if you want to recover multivolume archives with empty StartHeader
|
||||
#define Get16(p) GetUi16(p)
|
||||
#define Get32(p) GetUi32(p)
|
||||
#define Get64(p) GetUi64(p)
|
||||
|
||||
// define FORMAT_7Z_RECOVERY if you want to recover multivolume archives with empty StartHeader
|
||||
#ifndef _SFX
|
||||
#define FORMAT_7Z_RECOVERY
|
||||
#endif
|
||||
@@ -36,7 +40,7 @@ public:
|
||||
{
|
||||
kUnsupportedVersion = 0,
|
||||
kUnsupported,
|
||||
kIncorrect,
|
||||
kIncorrect,
|
||||
kEndOfData,
|
||||
} Cause;
|
||||
CInArchiveException(CCauseType cause): Cause(cause) {};
|
||||
@@ -97,16 +101,6 @@ void CStreamSwitch::Set(CInArchive *archive, const CObjectVector<CByteBuffer> *d
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef LITTLE_ENDIAN_UNALIGN
|
||||
static inline UInt16 GetUInt16FromMem(const Byte *p) { return *(const UInt16 *)p; }
|
||||
static inline UInt32 GetUInt32FromMem(const Byte *p) { return *(const UInt32 *)p; }
|
||||
static inline UInt64 GetUInt64FromMem(const Byte *p) { return *(const UInt64 *)p; }
|
||||
#else
|
||||
static inline UInt16 GetUInt16FromMem(const Byte *p) { return p[0] | ((UInt16)p[1] << 8); }
|
||||
static inline UInt32 GetUInt32FromMem(const Byte *p) { return p[0] | ((UInt32)p[1] << 8) | ((UInt32)p[2] << 16) | ((UInt32)p[3] << 24); }
|
||||
static inline UInt64 GetUInt64FromMem(const Byte *p) { return GetUInt32FromMem(p) | ((UInt64)GetUInt32FromMem(p + 4) << 32); }
|
||||
#endif
|
||||
|
||||
Byte CInByte2::ReadByte()
|
||||
{
|
||||
if (_pos >= _size)
|
||||
@@ -126,6 +120,7 @@ void CInByte2::SkeepData(UInt64 size)
|
||||
{
|
||||
if (size > _size - _pos)
|
||||
ThrowEndOfData();
|
||||
_pos += (size_t)size;
|
||||
}
|
||||
|
||||
void CInByte2::SkeepData()
|
||||
@@ -157,8 +152,8 @@ UInt64 CInByte2::ReadNumber()
|
||||
}
|
||||
|
||||
CNum CInByte2::ReadNum()
|
||||
{
|
||||
UInt64 value = ReadNumber();
|
||||
{
|
||||
UInt64 value = ReadNumber();
|
||||
if (value > kNumMax)
|
||||
ThrowUnsupported();
|
||||
return (CNum)value;
|
||||
@@ -168,7 +163,7 @@ UInt32 CInByte2::ReadUInt32()
|
||||
{
|
||||
if (_pos + 4 > _size)
|
||||
ThrowEndOfData();
|
||||
UInt32 res = GetUInt32FromMem(_buffer + _pos);
|
||||
UInt32 res = Get32(_buffer + _pos);
|
||||
_pos += 4;
|
||||
return res;
|
||||
}
|
||||
@@ -177,7 +172,7 @@ UInt64 CInByte2::ReadUInt64()
|
||||
{
|
||||
if (_pos + 8 > _size)
|
||||
ThrowEndOfData();
|
||||
UInt64 res = GetUInt64FromMem(_buffer + _pos);
|
||||
UInt64 res = Get64(_buffer + _pos);
|
||||
_pos += 8;
|
||||
return res;
|
||||
}
|
||||
@@ -200,9 +195,8 @@ void CInByte2::ReadString(UString &s)
|
||||
ThrowUnsupported();
|
||||
wchar_t *p = s.GetBuffer(len);
|
||||
int i;
|
||||
for (i = 0; i < len; i++, buf += 2)
|
||||
p[i] = (wchar_t)GetUInt16FromMem(buf);
|
||||
p[i] = 0;
|
||||
for (i = 0; i < len; i++, buf += 2)
|
||||
p[i] = (wchar_t)Get16(buf);
|
||||
s.ReleaseBuffer(len);
|
||||
_pos += rem + 2;
|
||||
}
|
||||
@@ -234,23 +228,32 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search
|
||||
if (searchHeaderSizeLimit != NULL)
|
||||
if (curTestPos - _arhiveBeginStreamPosition > *searchHeaderSizeLimit)
|
||||
break;
|
||||
UInt32 numReadBytes = kBufferSize - numPrevBytes;
|
||||
UInt32 processedSize;
|
||||
RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize));
|
||||
UInt32 numBytesInBuffer = numPrevBytes + processedSize;
|
||||
if (numBytesInBuffer < kHeaderSize)
|
||||
break;
|
||||
UInt32 numTests = numBytesInBuffer - kHeaderSize + 1;
|
||||
for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++)
|
||||
{
|
||||
do
|
||||
{
|
||||
UInt32 numReadBytes = kBufferSize - numPrevBytes;
|
||||
UInt32 processedSize;
|
||||
RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize));
|
||||
numPrevBytes += processedSize;
|
||||
if (processedSize == 0)
|
||||
return S_FALSE;
|
||||
}
|
||||
while (numPrevBytes < kHeaderSize);
|
||||
UInt32 numTests = numPrevBytes - kHeaderSize + 1;
|
||||
for (UInt32 pos = 0; pos < numTests; pos++)
|
||||
{
|
||||
for (; buffer[pos] != '7' && pos < numTests; pos++);
|
||||
if (pos == numTests)
|
||||
break;
|
||||
if (TestSignatureCandidate(buffer + pos))
|
||||
{
|
||||
memcpy(_header, buffer + pos, kHeaderSize);
|
||||
curTestPos += pos;
|
||||
_arhiveBeginStreamPosition = curTestPos;
|
||||
return stream->Seek(curTestPos + kHeaderSize, STREAM_SEEK_SET, NULL);
|
||||
}
|
||||
}
|
||||
numPrevBytes = numBytesInBuffer - numTests;
|
||||
curTestPos += numTests;
|
||||
numPrevBytes -= numTests;
|
||||
memmove(buffer, buffer + numTests, numPrevBytes);
|
||||
}
|
||||
return S_FALSE;
|
||||
@@ -259,6 +262,7 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search
|
||||
// S_FALSE means that file is not archive
|
||||
HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
|
||||
{
|
||||
HeadersSize = 0;
|
||||
Close();
|
||||
RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_arhiveBeginStreamPosition))
|
||||
RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit));
|
||||
@@ -338,7 +342,7 @@ void CInArchive::GetNextFolderItem(CFolder &folder)
|
||||
{
|
||||
CBindPair bindPair;
|
||||
bindPair.InIndex = ReadNum();
|
||||
bindPair.OutIndex = ReadNum();
|
||||
bindPair.OutIndex = ReadNum();
|
||||
folder.BindPairs.Add(bindPair);
|
||||
}
|
||||
|
||||
@@ -354,7 +358,7 @@ void CInArchive::GetNextFolderItem(CFolder &folder)
|
||||
}
|
||||
}
|
||||
else
|
||||
for(i = 0; i < numPackedStreams; i++)
|
||||
for (i = 0; i < numPackedStreams; i++)
|
||||
folder.PackStreams.Add(ReadNum());
|
||||
}
|
||||
|
||||
@@ -372,13 +376,13 @@ void CInArchive::WaitAttribute(UInt64 attribute)
|
||||
}
|
||||
|
||||
void CInArchive::ReadHashDigests(int numItems,
|
||||
CRecordVector<bool> &digestsDefined,
|
||||
CRecordVector<bool> &digestsDefined,
|
||||
CRecordVector<UInt32> &digests)
|
||||
{
|
||||
ReadBoolVector2(numItems, digestsDefined);
|
||||
digests.Clear();
|
||||
digests.Reserve(numItems);
|
||||
for(int i = 0; i < numItems; i++)
|
||||
for (int i = 0; i < numItems; i++)
|
||||
{
|
||||
UInt32 crc = 0;
|
||||
if (digestsDefined[i])
|
||||
@@ -410,7 +414,7 @@ void CInArchive::ReadPackInfo(
|
||||
break;
|
||||
if (type == NID::kCRC)
|
||||
{
|
||||
ReadHashDigests(numPackStreams, packCRCsDefined, packCRCs);
|
||||
ReadHashDigests(numPackStreams, packCRCsDefined, packCRCs);
|
||||
continue;
|
||||
}
|
||||
SkeepData();
|
||||
@@ -421,7 +425,7 @@ void CInArchive::ReadPackInfo(
|
||||
packCRCsDefined.Clear();
|
||||
packCRCs.Reserve(numPackStreams);
|
||||
packCRCs.Clear();
|
||||
for(CNum i = 0; i < numPackStreams; i++)
|
||||
for (CNum i = 0; i < numPackStreams; i++)
|
||||
{
|
||||
packCRCsDefined.Add(false);
|
||||
packCRCs.Add(0);
|
||||
@@ -429,7 +433,7 @@ void CInArchive::ReadPackInfo(
|
||||
}
|
||||
}
|
||||
|
||||
void CInArchive::ReadUnPackInfo(
|
||||
void CInArchive::ReadUnpackInfo(
|
||||
const CObjectVector<CByteBuffer> *dataVector,
|
||||
CObjectVector<CFolder> &folders)
|
||||
{
|
||||
@@ -441,23 +445,23 @@ void CInArchive::ReadUnPackInfo(
|
||||
streamSwitch.Set(this, dataVector);
|
||||
folders.Clear();
|
||||
folders.Reserve(numFolders);
|
||||
for(CNum i = 0; i < numFolders; i++)
|
||||
for (CNum i = 0; i < numFolders; i++)
|
||||
{
|
||||
folders.Add(CFolder());
|
||||
GetNextFolderItem(folders.Back());
|
||||
}
|
||||
}
|
||||
|
||||
WaitAttribute(NID::kCodersUnPackSize);
|
||||
WaitAttribute(NID::kCodersUnpackSize);
|
||||
|
||||
CNum i;
|
||||
for (i = 0; i < numFolders; i++)
|
||||
{
|
||||
CFolder &folder = folders[i];
|
||||
CNum numOutStreams = folder.GetNumOutStreams();
|
||||
folder.UnPackSizes.Reserve(numOutStreams);
|
||||
folder.UnpackSizes.Reserve(numOutStreams);
|
||||
for (CNum j = 0; j < numOutStreams; j++)
|
||||
folder.UnPackSizes.Add(ReadNumber());
|
||||
folder.UnpackSizes.Add(ReadNumber());
|
||||
}
|
||||
|
||||
for (;;)
|
||||
@@ -469,12 +473,12 @@ void CInArchive::ReadUnPackInfo(
|
||||
{
|
||||
CRecordVector<bool> crcsDefined;
|
||||
CRecordVector<UInt32> crcs;
|
||||
ReadHashDigests(numFolders, crcsDefined, crcs);
|
||||
for(i = 0; i < numFolders; i++)
|
||||
ReadHashDigests(numFolders, crcsDefined, crcs);
|
||||
for (i = 0; i < numFolders; i++)
|
||||
{
|
||||
CFolder &folder = folders[i];
|
||||
folder.UnPackCRCDefined = crcsDefined[i];
|
||||
folder.UnPackCRC = crcs[i];
|
||||
folder.UnpackCRCDefined = crcsDefined[i];
|
||||
folder.UnpackCRC = crcs[i];
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -484,21 +488,21 @@ void CInArchive::ReadUnPackInfo(
|
||||
|
||||
void CInArchive::ReadSubStreamsInfo(
|
||||
const CObjectVector<CFolder> &folders,
|
||||
CRecordVector<CNum> &numUnPackStreamsInFolders,
|
||||
CRecordVector<UInt64> &unPackSizes,
|
||||
CRecordVector<bool> &digestsDefined,
|
||||
CRecordVector<CNum> &numUnpackStreamsInFolders,
|
||||
CRecordVector<UInt64> &unpackSizes,
|
||||
CRecordVector<bool> &digestsDefined,
|
||||
CRecordVector<UInt32> &digests)
|
||||
{
|
||||
numUnPackStreamsInFolders.Clear();
|
||||
numUnPackStreamsInFolders.Reserve(folders.Size());
|
||||
numUnpackStreamsInFolders.Clear();
|
||||
numUnpackStreamsInFolders.Reserve(folders.Size());
|
||||
UInt64 type;
|
||||
for (;;)
|
||||
{
|
||||
type = ReadID();
|
||||
if (type == NID::kNumUnPackStream)
|
||||
if (type == NID::kNumUnpackStream)
|
||||
{
|
||||
for(int i = 0; i < folders.Size(); i++)
|
||||
numUnPackStreamsInFolders.Add(ReadNum());
|
||||
for (int i = 0; i < folders.Size(); i++)
|
||||
numUnpackStreamsInFolders.Add(ReadNum());
|
||||
continue;
|
||||
}
|
||||
if (type == NID::kCRC || type == NID::kSize)
|
||||
@@ -508,16 +512,16 @@ void CInArchive::ReadSubStreamsInfo(
|
||||
SkeepData();
|
||||
}
|
||||
|
||||
if (numUnPackStreamsInFolders.IsEmpty())
|
||||
for(int i = 0; i < folders.Size(); i++)
|
||||
numUnPackStreamsInFolders.Add(1);
|
||||
if (numUnpackStreamsInFolders.IsEmpty())
|
||||
for (int i = 0; i < folders.Size(); i++)
|
||||
numUnpackStreamsInFolders.Add(1);
|
||||
|
||||
int i;
|
||||
for(i = 0; i < numUnPackStreamsInFolders.Size(); i++)
|
||||
for (i = 0; i < numUnpackStreamsInFolders.Size(); i++)
|
||||
{
|
||||
// v3.13 incorrectly worked with empty folders
|
||||
// v4.07: we check that folder is empty
|
||||
CNum numSubstreams = numUnPackStreamsInFolders[i];
|
||||
CNum numSubstreams = numUnpackStreamsInFolders[i];
|
||||
if (numSubstreams == 0)
|
||||
continue;
|
||||
UInt64 sum = 0;
|
||||
@@ -525,20 +529,20 @@ void CInArchive::ReadSubStreamsInfo(
|
||||
if (type == NID::kSize)
|
||||
{
|
||||
UInt64 size = ReadNumber();
|
||||
unPackSizes.Add(size);
|
||||
unpackSizes.Add(size);
|
||||
sum += size;
|
||||
}
|
||||
unPackSizes.Add(folders[i].GetUnPackSize() - sum);
|
||||
unpackSizes.Add(folders[i].GetUnpackSize() - sum);
|
||||
}
|
||||
if (type == NID::kSize)
|
||||
type = ReadID();
|
||||
|
||||
int numDigests = 0;
|
||||
int numDigestsTotal = 0;
|
||||
for(i = 0; i < folders.Size(); i++)
|
||||
for (i = 0; i < folders.Size(); i++)
|
||||
{
|
||||
CNum numSubstreams = numUnPackStreamsInFolders[i];
|
||||
if (numSubstreams != 1 || !folders[i].UnPackCRCDefined)
|
||||
CNum numSubstreams = numUnpackStreamsInFolders[i];
|
||||
if (numSubstreams != 1 || !folders[i].UnpackCRCDefined)
|
||||
numDigests += numSubstreams;
|
||||
numDigestsTotal += numSubstreams;
|
||||
}
|
||||
@@ -547,18 +551,18 @@ void CInArchive::ReadSubStreamsInfo(
|
||||
{
|
||||
if (type == NID::kCRC)
|
||||
{
|
||||
CRecordVector<bool> digestsDefined2;
|
||||
CRecordVector<bool> digestsDefined2;
|
||||
CRecordVector<UInt32> digests2;
|
||||
ReadHashDigests(numDigests, digestsDefined2, digests2);
|
||||
int digestIndex = 0;
|
||||
for (i = 0; i < folders.Size(); i++)
|
||||
{
|
||||
CNum numSubstreams = numUnPackStreamsInFolders[i];
|
||||
CNum numSubstreams = numUnpackStreamsInFolders[i];
|
||||
const CFolder &folder = folders[i];
|
||||
if (numSubstreams == 1 && folder.UnPackCRCDefined)
|
||||
if (numSubstreams == 1 && folder.UnpackCRCDefined)
|
||||
{
|
||||
digestsDefined.Add(true);
|
||||
digests.Add(folder.UnPackCRC);
|
||||
digests.Add(folder.UnpackCRC);
|
||||
}
|
||||
else
|
||||
for (CNum j = 0; j < numSubstreams; j++, digestIndex++)
|
||||
@@ -595,9 +599,9 @@ void CInArchive::ReadStreamsInfo(
|
||||
CRecordVector<bool> &packCRCsDefined,
|
||||
CRecordVector<UInt32> &packCRCs,
|
||||
CObjectVector<CFolder> &folders,
|
||||
CRecordVector<CNum> &numUnPackStreamsInFolders,
|
||||
CRecordVector<UInt64> &unPackSizes,
|
||||
CRecordVector<bool> &digestsDefined,
|
||||
CRecordVector<CNum> &numUnpackStreamsInFolders,
|
||||
CRecordVector<UInt64> &unpackSizes,
|
||||
CRecordVector<bool> &digestsDefined,
|
||||
CRecordVector<UInt32> &digests)
|
||||
{
|
||||
for (;;)
|
||||
@@ -614,15 +618,15 @@ void CInArchive::ReadStreamsInfo(
|
||||
ReadPackInfo(dataOffset, packSizes, packCRCsDefined, packCRCs);
|
||||
break;
|
||||
}
|
||||
case NID::kUnPackInfo:
|
||||
case NID::kUnpackInfo:
|
||||
{
|
||||
ReadUnPackInfo(dataVector, folders);
|
||||
ReadUnpackInfo(dataVector, folders);
|
||||
break;
|
||||
}
|
||||
case NID::kSubStreamsInfo:
|
||||
{
|
||||
ReadSubStreamsInfo(folders, numUnPackStreamsInFolders,
|
||||
unPackSizes, digestsDefined, digests);
|
||||
ReadSubStreamsInfo(folders, numUnpackStreamsInFolders,
|
||||
unpackSizes, digestsDefined, digests);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -637,7 +641,7 @@ void CInArchive::ReadBoolVector(int numItems, CBoolVector &v)
|
||||
v.Reserve(numItems);
|
||||
Byte b = 0;
|
||||
Byte mask = 0;
|
||||
for(int i = 0; i < numItems; i++)
|
||||
for (int i = 0; i < numItems; i++)
|
||||
{
|
||||
if (mask == 0)
|
||||
{
|
||||
@@ -663,54 +667,30 @@ void CInArchive::ReadBoolVector2(int numItems, CBoolVector &v)
|
||||
v.Add(true);
|
||||
}
|
||||
|
||||
void CInArchive::ReadTime(const CObjectVector<CByteBuffer> &dataVector,
|
||||
CObjectVector<CFileItem> &files, UInt32 type)
|
||||
void CInArchive::ReadUInt64DefVector(const CObjectVector<CByteBuffer> &dataVector,
|
||||
CUInt64DefVector &v, int numFiles)
|
||||
{
|
||||
CBoolVector boolVector;
|
||||
ReadBoolVector2(files.Size(), boolVector);
|
||||
ReadBoolVector2(numFiles, v.Defined);
|
||||
|
||||
CStreamSwitch streamSwitch;
|
||||
streamSwitch.Set(this, &dataVector);
|
||||
v.Values.Reserve(numFiles);
|
||||
|
||||
for(int i = 0; i < files.Size(); i++)
|
||||
for (int i = 0; i < numFiles; i++)
|
||||
{
|
||||
CFileItem &file = files[i];
|
||||
CArchiveFileTime fileTime;
|
||||
fileTime.dwLowDateTime = 0;
|
||||
fileTime.dwHighDateTime = 0;
|
||||
bool defined = boolVector[i];
|
||||
if (defined)
|
||||
{
|
||||
fileTime.dwLowDateTime = ReadUInt32();
|
||||
fileTime.dwHighDateTime = ReadUInt32();
|
||||
}
|
||||
switch(type)
|
||||
{
|
||||
case NID::kCreationTime:
|
||||
file.IsCreationTimeDefined = defined;
|
||||
if (defined)
|
||||
file.CreationTime = fileTime;
|
||||
break;
|
||||
case NID::kLastWriteTime:
|
||||
file.IsLastWriteTimeDefined = defined;
|
||||
if (defined)
|
||||
file.LastWriteTime = fileTime;
|
||||
break;
|
||||
case NID::kLastAccessTime:
|
||||
file.IsLastAccessTimeDefined = defined;
|
||||
if (defined)
|
||||
file.LastAccessTime = fileTime;
|
||||
break;
|
||||
}
|
||||
UInt64 t = 0;
|
||||
if (v.Defined[i])
|
||||
t = ReadUInt64();
|
||||
v.Values.Add(t);
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT CInArchive::ReadAndDecodePackedStreams(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
UInt64 baseOffset,
|
||||
UInt64 baseOffset,
|
||||
UInt64 &dataOffset, CObjectVector<CByteBuffer> &dataVector
|
||||
#ifndef _NO_CRYPTO
|
||||
, ICryptoGetTextPassword *getTextPassword
|
||||
, ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
|
||||
#endif
|
||||
)
|
||||
{
|
||||
@@ -719,23 +699,23 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
|
||||
CRecordVector<UInt32> packCRCs;
|
||||
CObjectVector<CFolder> folders;
|
||||
|
||||
CRecordVector<CNum> numUnPackStreamsInFolders;
|
||||
CRecordVector<UInt64> unPackSizes;
|
||||
CRecordVector<CNum> numUnpackStreamsInFolders;
|
||||
CRecordVector<UInt64> unpackSizes;
|
||||
CRecordVector<bool> digestsDefined;
|
||||
CRecordVector<UInt32> digests;
|
||||
|
||||
ReadStreamsInfo(NULL,
|
||||
ReadStreamsInfo(NULL,
|
||||
dataOffset,
|
||||
packSizes,
|
||||
packCRCsDefined,
|
||||
packCRCs,
|
||||
packSizes,
|
||||
packCRCsDefined,
|
||||
packCRCs,
|
||||
folders,
|
||||
numUnPackStreamsInFolders,
|
||||
unPackSizes,
|
||||
digestsDefined,
|
||||
numUnpackStreamsInFolders,
|
||||
unpackSizes,
|
||||
digestsDefined,
|
||||
digests);
|
||||
|
||||
// database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader;
|
||||
// db.ArchiveInfo.DataStartPosition2 += db.ArchiveInfo.StartPositionAfterHeader;
|
||||
|
||||
CNum packIndex = 0;
|
||||
CDecoder decoder(
|
||||
@@ -746,27 +726,27 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
|
||||
#endif
|
||||
);
|
||||
UInt64 dataStartPos = baseOffset + dataOffset;
|
||||
for(int i = 0; i < folders.Size(); i++)
|
||||
for (int i = 0; i < folders.Size(); i++)
|
||||
{
|
||||
const CFolder &folder = folders[i];
|
||||
dataVector.Add(CByteBuffer());
|
||||
CByteBuffer &data = dataVector.Back();
|
||||
UInt64 unPackSize64 = folder.GetUnPackSize();
|
||||
size_t unPackSize = (size_t)unPackSize64;
|
||||
if (unPackSize != unPackSize64)
|
||||
UInt64 unpackSize64 = folder.GetUnpackSize();
|
||||
size_t unpackSize = (size_t)unpackSize64;
|
||||
if (unpackSize != unpackSize64)
|
||||
ThrowUnsupported();
|
||||
data.SetCapacity(unPackSize);
|
||||
data.SetCapacity(unpackSize);
|
||||
|
||||
CSequentialOutStreamImp2 *outStreamSpec = new CSequentialOutStreamImp2;
|
||||
CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
|
||||
outStreamSpec->Init(data, unPackSize);
|
||||
outStreamSpec->Init(data, unpackSize);
|
||||
|
||||
HRESULT result = decoder.Decode(
|
||||
EXTERNAL_CODECS_LOC_VARS
|
||||
_stream, dataStartPos,
|
||||
_stream, dataStartPos,
|
||||
&packSizes[packIndex], folder, outStream, NULL
|
||||
#ifndef _NO_CRYPTO
|
||||
, getTextPassword
|
||||
, getTextPassword, passwordIsDefined
|
||||
#endif
|
||||
#ifdef COMPRESS_MT
|
||||
, false, 1
|
||||
@@ -774,20 +754,24 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
|
||||
);
|
||||
RINOK(result);
|
||||
|
||||
if (folder.UnPackCRCDefined)
|
||||
if (CrcCalc(data, unPackSize) != folder.UnPackCRC)
|
||||
if (folder.UnpackCRCDefined)
|
||||
if (CrcCalc(data, unpackSize) != folder.UnpackCRC)
|
||||
ThrowIncorrect();
|
||||
for (int j = 0; j < folder.PackStreams.Size(); j++)
|
||||
dataStartPos += packSizes[packIndex++];
|
||||
for (int j = 0; j < folder.PackStreams.Size(); j++)
|
||||
{
|
||||
UInt64 packSize = packSizes[packIndex++];
|
||||
dataStartPos += packSize;
|
||||
HeadersSize += packSize;
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CInArchive::ReadHeader(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
CArchiveDatabaseEx &database
|
||||
CArchiveDatabaseEx &db
|
||||
#ifndef _NO_CRYPTO
|
||||
, ICryptoGetTextPassword *getTextPassword
|
||||
, ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
|
||||
#endif
|
||||
)
|
||||
{
|
||||
@@ -795,7 +779,7 @@ HRESULT CInArchive::ReadHeader(
|
||||
|
||||
if (type == NID::kArchiveProperties)
|
||||
{
|
||||
ReadArchiveProperties(database.ArchiveInfo);
|
||||
ReadArchiveProperties(db.ArchiveInfo);
|
||||
type = ReadID();
|
||||
}
|
||||
|
||||
@@ -805,50 +789,50 @@ HRESULT CInArchive::ReadHeader(
|
||||
{
|
||||
HRESULT result = ReadAndDecodePackedStreams(
|
||||
EXTERNAL_CODECS_LOC_VARS
|
||||
database.ArchiveInfo.StartPositionAfterHeader,
|
||||
database.ArchiveInfo.DataStartPosition2,
|
||||
db.ArchiveInfo.StartPositionAfterHeader,
|
||||
db.ArchiveInfo.DataStartPosition2,
|
||||
dataVector
|
||||
#ifndef _NO_CRYPTO
|
||||
, getTextPassword
|
||||
, getTextPassword, passwordIsDefined
|
||||
#endif
|
||||
);
|
||||
RINOK(result);
|
||||
database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader;
|
||||
db.ArchiveInfo.DataStartPosition2 += db.ArchiveInfo.StartPositionAfterHeader;
|
||||
type = ReadID();
|
||||
}
|
||||
|
||||
CRecordVector<UInt64> unPackSizes;
|
||||
CRecordVector<UInt64> unpackSizes;
|
||||
CRecordVector<bool> digestsDefined;
|
||||
CRecordVector<UInt32> digests;
|
||||
|
||||
if (type == NID::kMainStreamsInfo)
|
||||
{
|
||||
ReadStreamsInfo(&dataVector,
|
||||
database.ArchiveInfo.DataStartPosition,
|
||||
database.PackSizes,
|
||||
database.PackCRCsDefined,
|
||||
database.PackCRCs,
|
||||
database.Folders,
|
||||
database.NumUnPackStreamsVector,
|
||||
unPackSizes,
|
||||
db.ArchiveInfo.DataStartPosition,
|
||||
db.PackSizes,
|
||||
db.PackCRCsDefined,
|
||||
db.PackCRCs,
|
||||
db.Folders,
|
||||
db.NumUnpackStreamsVector,
|
||||
unpackSizes,
|
||||
digestsDefined,
|
||||
digests);
|
||||
database.ArchiveInfo.DataStartPosition += database.ArchiveInfo.StartPositionAfterHeader;
|
||||
db.ArchiveInfo.DataStartPosition += db.ArchiveInfo.StartPositionAfterHeader;
|
||||
type = ReadID();
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int i = 0; i < database.Folders.Size(); i++)
|
||||
for (int i = 0; i < db.Folders.Size(); i++)
|
||||
{
|
||||
database.NumUnPackStreamsVector.Add(1);
|
||||
CFolder &folder = database.Folders[i];
|
||||
unPackSizes.Add(folder.GetUnPackSize());
|
||||
digestsDefined.Add(folder.UnPackCRCDefined);
|
||||
digests.Add(folder.UnPackCRC);
|
||||
db.NumUnpackStreamsVector.Add(1);
|
||||
CFolder &folder = db.Folders[i];
|
||||
unpackSizes.Add(folder.GetUnpackSize());
|
||||
digestsDefined.Add(folder.UnpackCRCDefined);
|
||||
digests.Add(folder.UnpackCRC);
|
||||
}
|
||||
}
|
||||
|
||||
database.Files.Clear();
|
||||
db.Files.Clear();
|
||||
|
||||
if (type == NID::kEnd)
|
||||
return S_OK;
|
||||
@@ -856,20 +840,20 @@ HRESULT CInArchive::ReadHeader(
|
||||
ThrowIncorrect();
|
||||
|
||||
CNum numFiles = ReadNum();
|
||||
database.Files.Reserve(numFiles);
|
||||
db.Files.Reserve(numFiles);
|
||||
CNum i;
|
||||
for(i = 0; i < numFiles; i++)
|
||||
database.Files.Add(CFileItem());
|
||||
for (i = 0; i < numFiles; i++)
|
||||
db.Files.Add(CFileItem());
|
||||
|
||||
database.ArchiveInfo.FileInfoPopIDs.Add(NID::kSize);
|
||||
if (!database.PackSizes.IsEmpty())
|
||||
database.ArchiveInfo.FileInfoPopIDs.Add(NID::kPackInfo);
|
||||
db.ArchiveInfo.FileInfoPopIDs.Add(NID::kSize);
|
||||
if (!db.PackSizes.IsEmpty())
|
||||
db.ArchiveInfo.FileInfoPopIDs.Add(NID::kPackInfo);
|
||||
if (numFiles > 0 && !digests.IsEmpty())
|
||||
database.ArchiveInfo.FileInfoPopIDs.Add(NID::kCRC);
|
||||
db.ArchiveInfo.FileInfoPopIDs.Add(NID::kCRC);
|
||||
|
||||
CBoolVector emptyStreamVector;
|
||||
emptyStreamVector.Reserve((int)numFiles);
|
||||
for(i = 0; i < numFiles; i++)
|
||||
for (i = 0; i < numFiles; i++)
|
||||
emptyStreamVector.Add(false);
|
||||
CBoolVector emptyFileVector;
|
||||
CBoolVector antiFileVector;
|
||||
@@ -881,6 +865,8 @@ HRESULT CInArchive::ReadHeader(
|
||||
if (type == NID::kEnd)
|
||||
break;
|
||||
UInt64 size = ReadNumber();
|
||||
size_t ppp = _inByteBack->_pos;
|
||||
bool addPropIdToList = true;
|
||||
bool isKnownType = true;
|
||||
if (type > ((UInt32)1 << 30))
|
||||
isKnownType = false;
|
||||
@@ -890,37 +876,22 @@ HRESULT CInArchive::ReadHeader(
|
||||
{
|
||||
CStreamSwitch streamSwitch;
|
||||
streamSwitch.Set(this, &dataVector);
|
||||
for(int i = 0; i < database.Files.Size(); i++)
|
||||
_inByteBack->ReadString(database.Files[i].Name);
|
||||
for (int i = 0; i < db.Files.Size(); i++)
|
||||
_inByteBack->ReadString(db.Files[i].Name);
|
||||
break;
|
||||
}
|
||||
case NID::kWinAttributes:
|
||||
{
|
||||
CBoolVector boolVector;
|
||||
ReadBoolVector2(database.Files.Size(), boolVector);
|
||||
ReadBoolVector2(db.Files.Size(), boolVector);
|
||||
CStreamSwitch streamSwitch;
|
||||
streamSwitch.Set(this, &dataVector);
|
||||
for(i = 0; i < numFiles; i++)
|
||||
for (i = 0; i < numFiles; i++)
|
||||
{
|
||||
CFileItem &file = database.Files[i];
|
||||
file.AreAttributesDefined = boolVector[i];
|
||||
if (file.AreAttributesDefined)
|
||||
file.Attributes = ReadUInt32();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NID::kStartPos:
|
||||
{
|
||||
CBoolVector boolVector;
|
||||
ReadBoolVector2(database.Files.Size(), boolVector);
|
||||
CStreamSwitch streamSwitch;
|
||||
streamSwitch.Set(this, &dataVector);
|
||||
for(i = 0; i < numFiles; i++)
|
||||
{
|
||||
CFileItem &file = database.Files[i];
|
||||
file.IsStartPosDefined = boolVector[i];
|
||||
if (file.IsStartPosDefined)
|
||||
file.StartPos = ReadUInt64();
|
||||
CFileItem &file = db.Files[i];
|
||||
file.AttribDefined = boolVector[i];
|
||||
if (file.AttribDefined)
|
||||
file.Attrib = ReadUInt32();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -939,55 +910,68 @@ HRESULT CInArchive::ReadHeader(
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NID::kEmptyFile:
|
||||
case NID::kEmptyFile: ReadBoolVector(numEmptyStreams, emptyFileVector); break;
|
||||
case NID::kAnti: ReadBoolVector(numEmptyStreams, antiFileVector); break;
|
||||
case NID::kStartPos: ReadUInt64DefVector(dataVector, db.StartPos, (int)numFiles); break;
|
||||
case NID::kCTime: ReadUInt64DefVector(dataVector, db.CTime, (int)numFiles); break;
|
||||
case NID::kATime: ReadUInt64DefVector(dataVector, db.ATime, (int)numFiles); break;
|
||||
case NID::kMTime: ReadUInt64DefVector(dataVector, db.MTime, (int)numFiles); break;
|
||||
case NID::kDummy:
|
||||
{
|
||||
ReadBoolVector(numEmptyStreams, emptyFileVector);
|
||||
break;
|
||||
}
|
||||
case NID::kAnti:
|
||||
{
|
||||
ReadBoolVector(numEmptyStreams, antiFileVector);
|
||||
break;
|
||||
}
|
||||
case NID::kCreationTime:
|
||||
case NID::kLastWriteTime:
|
||||
case NID::kLastAccessTime:
|
||||
{
|
||||
ReadTime(dataVector, database.Files, (UInt32)type);
|
||||
for (UInt64 j = 0; j < size; j++)
|
||||
if (ReadByte() != 0)
|
||||
ThrowIncorrect();
|
||||
addPropIdToList = false;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
isKnownType = false;
|
||||
addPropIdToList = isKnownType = false;
|
||||
}
|
||||
if (isKnownType)
|
||||
database.ArchiveInfo.FileInfoPopIDs.Add(type);
|
||||
{
|
||||
if(addPropIdToList)
|
||||
db.ArchiveInfo.FileInfoPopIDs.Add(type);
|
||||
}
|
||||
else
|
||||
SkeepData(size);
|
||||
bool checkRecordsSize = (db.ArchiveInfo.Version.Major > 0 ||
|
||||
db.ArchiveInfo.Version.Minor > 2);
|
||||
if (checkRecordsSize && _inByteBack->_pos - ppp != size)
|
||||
ThrowIncorrect();
|
||||
}
|
||||
|
||||
CNum emptyFileIndex = 0;
|
||||
CNum sizeIndex = 0;
|
||||
for(i = 0; i < numFiles; i++)
|
||||
|
||||
CNum numAntiItems = 0;
|
||||
for (i = 0; i < numEmptyStreams; i++)
|
||||
if (antiFileVector[i])
|
||||
numAntiItems++;
|
||||
|
||||
for (i = 0; i < numFiles; i++)
|
||||
{
|
||||
CFileItem &file = database.Files[i];
|
||||
CFileItem &file = db.Files[i];
|
||||
bool isAnti;
|
||||
file.HasStream = !emptyStreamVector[i];
|
||||
if(file.HasStream)
|
||||
if (file.HasStream)
|
||||
{
|
||||
file.IsDirectory = false;
|
||||
file.IsAnti = false;
|
||||
file.UnPackSize = unPackSizes[sizeIndex];
|
||||
file.FileCRC = digests[sizeIndex];
|
||||
file.IsFileCRCDefined = digestsDefined[sizeIndex];
|
||||
file.IsDir = false;
|
||||
isAnti = false;
|
||||
file.Size = unpackSizes[sizeIndex];
|
||||
file.Crc = digests[sizeIndex];
|
||||
file.CrcDefined = digestsDefined[sizeIndex];
|
||||
sizeIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
file.IsDirectory = !emptyFileVector[emptyFileIndex];
|
||||
file.IsAnti = antiFileVector[emptyFileIndex];
|
||||
file.IsDir = !emptyFileVector[emptyFileIndex];
|
||||
isAnti = antiFileVector[emptyFileIndex];
|
||||
emptyFileIndex++;
|
||||
file.UnPackSize = 0;
|
||||
file.IsFileCRCDefined = false;
|
||||
file.Size = 0;
|
||||
file.CrcDefined = false;
|
||||
}
|
||||
if (numAntiItems != 0)
|
||||
db.IsAnti.Add(isAnti);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
@@ -998,7 +982,7 @@ void CArchiveDatabaseEx::FillFolderStartPackStream()
|
||||
FolderStartPackStreamIndex.Clear();
|
||||
FolderStartPackStreamIndex.Reserve(Folders.Size());
|
||||
CNum startPos = 0;
|
||||
for(int i = 0; i < Folders.Size(); i++)
|
||||
for (int i = 0; i < Folders.Size(); i++)
|
||||
{
|
||||
FolderStartPackStreamIndex.Add(startPos);
|
||||
startPos += (CNum)Folders[i].PackStreams.Size();
|
||||
@@ -1010,7 +994,7 @@ void CArchiveDatabaseEx::FillStartPos()
|
||||
PackStreamStartPositions.Clear();
|
||||
PackStreamStartPositions.Reserve(PackSizes.Size());
|
||||
UInt64 startPos = 0;
|
||||
for(int i = 0; i < PackSizes.Size(); i++)
|
||||
for (int i = 0; i < PackSizes.Size(); i++)
|
||||
{
|
||||
PackStreamStartPositions.Add(startPos);
|
||||
startPos += PackSizes[i];
|
||||
@@ -1044,7 +1028,7 @@ void CArchiveDatabaseEx::FillFolderStartFileIndex()
|
||||
if (folderIndex >= Folders.Size())
|
||||
ThrowIncorrect();
|
||||
FolderStartFileIndex.Add(i); // check it
|
||||
if (NumUnPackStreamsVector[folderIndex] != 0)
|
||||
if (NumUnpackStreamsVector[folderIndex] != 0)
|
||||
break;
|
||||
folderIndex++;
|
||||
}
|
||||
@@ -1053,7 +1037,7 @@ void CArchiveDatabaseEx::FillFolderStartFileIndex()
|
||||
if (emptyStream)
|
||||
continue;
|
||||
indexInFolder++;
|
||||
if (indexInFolder >= NumUnPackStreamsVector[folderIndex])
|
||||
if (indexInFolder >= NumUnpackStreamsVector[folderIndex])
|
||||
{
|
||||
folderIndex++;
|
||||
indexInFolder = 0;
|
||||
@@ -1063,25 +1047,25 @@ void CArchiveDatabaseEx::FillFolderStartFileIndex()
|
||||
|
||||
HRESULT CInArchive::ReadDatabase2(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
CArchiveDatabaseEx &database
|
||||
CArchiveDatabaseEx &db
|
||||
#ifndef _NO_CRYPTO
|
||||
, ICryptoGetTextPassword *getTextPassword
|
||||
, ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
|
||||
#endif
|
||||
)
|
||||
{
|
||||
database.Clear();
|
||||
database.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition;
|
||||
db.Clear();
|
||||
db.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition;
|
||||
|
||||
database.ArchiveInfo.Version.Major = _header[6];
|
||||
database.ArchiveInfo.Version.Minor = _header[7];
|
||||
db.ArchiveInfo.Version.Major = _header[6];
|
||||
db.ArchiveInfo.Version.Minor = _header[7];
|
||||
|
||||
if (database.ArchiveInfo.Version.Major != kMajorVersion)
|
||||
if (db.ArchiveInfo.Version.Major != kMajorVersion)
|
||||
ThrowUnsupportedVersion();
|
||||
|
||||
UInt32 crcFromArchive = GetUInt32FromMem(_header + 8);
|
||||
UInt64 nextHeaderOffset = GetUInt64FromMem(_header + 0xC);
|
||||
UInt64 nextHeaderSize = GetUInt64FromMem(_header + 0x14);
|
||||
UInt32 nextHeaderCRC = GetUInt32FromMem(_header + 0x1C);
|
||||
UInt32 crcFromArchive = Get32(_header + 8);
|
||||
UInt64 nextHeaderOffset = Get64(_header + 0xC);
|
||||
UInt64 nextHeaderSize = Get64(_header + 0x14);
|
||||
UInt32 nextHeaderCRC = Get32(_header + 0x1C);
|
||||
UInt32 crc = CrcCalc(_header + 0xC, 20);
|
||||
|
||||
#ifdef FORMAT_7Z_RECOVERY
|
||||
@@ -1097,16 +1081,15 @@ HRESULT CInArchive::ReadDatabase2(
|
||||
checkSize = (int)(cur2 - cur);
|
||||
RINOK(_stream->Seek(-checkSize, STREAM_SEEK_END, &cur2));
|
||||
|
||||
UInt32 realProcessedSize;
|
||||
RINOK(_stream->Read(buf, (UInt32)kCheckSize, &realProcessedSize));
|
||||
RINOK(ReadStream_FALSE(_stream, buf, (size_t)checkSize));
|
||||
|
||||
int i;
|
||||
for (i = (int)realProcessedSize - 2; i >= 0; i--)
|
||||
for (i = (int)checkSize - 2; i >= 0; i--)
|
||||
if (buf[i] == 0x17 && buf[i + 1] == 0x6 || buf[i] == 0x01 && buf[i + 1] == 0x04)
|
||||
break;
|
||||
if (i < 0)
|
||||
return S_FALSE;
|
||||
nextHeaderSize = realProcessedSize - i;
|
||||
nextHeaderSize = checkSize - i;
|
||||
nextHeaderOffset = cur2 - cur + i;
|
||||
nextHeaderCRC = CrcCalc(buf + i, (size_t)nextHeaderSize);
|
||||
RINOK(_stream->Seek(cur, STREAM_SEEK_SET, NULL));
|
||||
@@ -1117,7 +1100,7 @@ HRESULT CInArchive::ReadDatabase2(
|
||||
crcFromArchive = crc;
|
||||
#endif
|
||||
|
||||
database.ArchiveInfo.StartPositionAfterHeader = _arhiveBeginStreamPosition + kHeaderSize;
|
||||
db.ArchiveInfo.StartPositionAfterHeader = _arhiveBeginStreamPosition + kHeaderSize;
|
||||
|
||||
if (crc != crcFromArchive)
|
||||
ThrowIncorrect();
|
||||
@@ -1133,10 +1116,10 @@ HRESULT CInArchive::ReadDatabase2(
|
||||
CByteBuffer buffer2;
|
||||
buffer2.SetCapacity((size_t)nextHeaderSize);
|
||||
|
||||
UInt32 realProcessedSize;
|
||||
RINOK(_stream->Read(buffer2, (UInt32)nextHeaderSize, &realProcessedSize));
|
||||
if (realProcessedSize != (UInt32)nextHeaderSize)
|
||||
return S_FALSE;
|
||||
RINOK(ReadStream_FALSE(_stream, buffer2, (size_t)nextHeaderSize));
|
||||
HeadersSize += kHeaderSize + nextHeaderSize;
|
||||
db.PhySize = kHeaderSize + nextHeaderOffset + nextHeaderSize;
|
||||
|
||||
if (CrcCalc(buffer2, (UInt32)nextHeaderSize) != nextHeaderCRC)
|
||||
ThrowIncorrect();
|
||||
|
||||
@@ -1145,20 +1128,18 @@ HRESULT CInArchive::ReadDatabase2(
|
||||
|
||||
CObjectVector<CByteBuffer> dataVector;
|
||||
|
||||
for (;;)
|
||||
UInt64 type = ReadID();
|
||||
if (type != NID::kHeader)
|
||||
{
|
||||
UInt64 type = ReadID();
|
||||
if (type == NID::kHeader)
|
||||
break;
|
||||
if (type != NID::kEncodedHeader)
|
||||
ThrowIncorrect();
|
||||
HRESULT result = ReadAndDecodePackedStreams(
|
||||
EXTERNAL_CODECS_LOC_VARS
|
||||
database.ArchiveInfo.StartPositionAfterHeader,
|
||||
database.ArchiveInfo.DataStartPosition2,
|
||||
db.ArchiveInfo.StartPositionAfterHeader,
|
||||
db.ArchiveInfo.DataStartPosition2,
|
||||
dataVector
|
||||
#ifndef _NO_CRYPTO
|
||||
, getTextPassword
|
||||
, getTextPassword, passwordIsDefined
|
||||
#endif
|
||||
);
|
||||
RINOK(result);
|
||||
@@ -1168,31 +1149,35 @@ HRESULT CInArchive::ReadDatabase2(
|
||||
ThrowIncorrect();
|
||||
streamSwitch.Remove();
|
||||
streamSwitch.Set(this, dataVector.Front());
|
||||
if (ReadID() != NID::kHeader)
|
||||
ThrowIncorrect();
|
||||
}
|
||||
|
||||
db.HeadersSize = HeadersSize;
|
||||
|
||||
return ReadHeader(
|
||||
EXTERNAL_CODECS_LOC_VARS
|
||||
database
|
||||
db
|
||||
#ifndef _NO_CRYPTO
|
||||
, getTextPassword
|
||||
, getTextPassword, passwordIsDefined
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
HRESULT CInArchive::ReadDatabase(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
CArchiveDatabaseEx &database
|
||||
CArchiveDatabaseEx &db
|
||||
#ifndef _NO_CRYPTO
|
||||
, ICryptoGetTextPassword *getTextPassword
|
||||
, ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
|
||||
#endif
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
return ReadDatabase2(
|
||||
EXTERNAL_CODECS_LOC_VARS database
|
||||
EXTERNAL_CODECS_LOC_VARS db
|
||||
#ifndef _NO_CRYPTO
|
||||
, getTextPassword
|
||||
, getTextPassword, passwordIsDefined
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
@@ -36,6 +36,9 @@ struct CArchiveDatabaseEx: public CArchiveDatabase
|
||||
CRecordVector<CNum> FolderStartFileIndex;
|
||||
CRecordVector<CNum> FileIndexToFolderIndexMap;
|
||||
|
||||
UInt64 HeadersSize;
|
||||
UInt64 PhySize;
|
||||
|
||||
void Clear()
|
||||
{
|
||||
CArchiveDatabase::Clear();
|
||||
@@ -44,6 +47,9 @@ struct CArchiveDatabaseEx: public CArchiveDatabase
|
||||
FolderStartPackStreamIndex.Clear();
|
||||
FolderStartFileIndex.Clear();
|
||||
FileIndexToFolderIndexMap.Clear();
|
||||
|
||||
HeadersSize = 0;
|
||||
PhySize = 0;
|
||||
}
|
||||
|
||||
void FillFolderStartPackStream();
|
||||
@@ -63,7 +69,7 @@ struct CArchiveDatabaseEx: public CArchiveDatabase
|
||||
PackStreamStartPositions[FolderStartPackStreamIndex[folderIndex] + indexInFolder];
|
||||
}
|
||||
|
||||
UInt64 GetFolderFullPackSize(int folderIndex) const
|
||||
UInt64 GetFolderFullPackSize(int folderIndex) const
|
||||
{
|
||||
CNum packStreamIndex = FolderStartPackStreamIndex[folderIndex];
|
||||
const CFolder &folder = Folders[folderIndex];
|
||||
@@ -73,7 +79,7 @@ struct CArchiveDatabaseEx: public CArchiveDatabase
|
||||
return size;
|
||||
}
|
||||
|
||||
UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const
|
||||
UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const
|
||||
{
|
||||
return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
|
||||
}
|
||||
@@ -92,8 +98,8 @@ class CInByte2
|
||||
{
|
||||
const Byte *_buffer;
|
||||
size_t _size;
|
||||
size_t _pos;
|
||||
public:
|
||||
size_t _pos;
|
||||
void Init(const Byte *buffer, size_t size)
|
||||
{
|
||||
_buffer = buffer;
|
||||
@@ -128,6 +134,8 @@ class CInArchive
|
||||
|
||||
Byte _header[kHeaderSize];
|
||||
|
||||
UInt64 HeadersSize;
|
||||
|
||||
void AddByteStream(const Byte *buffer, size_t size)
|
||||
{
|
||||
_inByteVector.Add(CInByte2());
|
||||
@@ -167,15 +175,15 @@ private:
|
||||
CRecordVector<bool> &packCRCsDefined,
|
||||
CRecordVector<UInt32> &packCRCs);
|
||||
|
||||
void ReadUnPackInfo(
|
||||
void ReadUnpackInfo(
|
||||
const CObjectVector<CByteBuffer> *dataVector,
|
||||
CObjectVector<CFolder> &folders);
|
||||
|
||||
void ReadSubStreamsInfo(
|
||||
const CObjectVector<CFolder> &folders,
|
||||
CRecordVector<CNum> &numUnPackStreamsInFolders,
|
||||
CRecordVector<UInt64> &unPackSizes,
|
||||
CRecordVector<bool> &digestsDefined,
|
||||
CRecordVector<CNum> &numUnpackStreamsInFolders,
|
||||
CRecordVector<UInt64> &unpackSizes,
|
||||
CRecordVector<bool> &digestsDefined,
|
||||
CRecordVector<UInt32> &digests);
|
||||
|
||||
void ReadStreamsInfo(
|
||||
@@ -185,36 +193,36 @@ private:
|
||||
CRecordVector<bool> &packCRCsDefined,
|
||||
CRecordVector<UInt32> &packCRCs,
|
||||
CObjectVector<CFolder> &folders,
|
||||
CRecordVector<CNum> &numUnPackStreamsInFolders,
|
||||
CRecordVector<UInt64> &unPackSizes,
|
||||
CRecordVector<bool> &digestsDefined,
|
||||
CRecordVector<CNum> &numUnpackStreamsInFolders,
|
||||
CRecordVector<UInt64> &unpackSizes,
|
||||
CRecordVector<bool> &digestsDefined,
|
||||
CRecordVector<UInt32> &digests);
|
||||
|
||||
|
||||
void ReadBoolVector(int numItems, CBoolVector &v);
|
||||
void ReadBoolVector2(int numItems, CBoolVector &v);
|
||||
void ReadTime(const CObjectVector<CByteBuffer> &dataVector,
|
||||
CObjectVector<CFileItem> &files, UInt32 type);
|
||||
void ReadUInt64DefVector(const CObjectVector<CByteBuffer> &dataVector,
|
||||
CUInt64DefVector &v, int numFiles);
|
||||
HRESULT ReadAndDecodePackedStreams(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
UInt64 baseOffset, UInt64 &dataOffset,
|
||||
CObjectVector<CByteBuffer> &dataVector
|
||||
#ifndef _NO_CRYPTO
|
||||
, ICryptoGetTextPassword *getTextPassword
|
||||
, ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
|
||||
#endif
|
||||
);
|
||||
HRESULT ReadHeader(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
CArchiveDatabaseEx &database
|
||||
CArchiveDatabaseEx &db
|
||||
#ifndef _NO_CRYPTO
|
||||
,ICryptoGetTextPassword *getTextPassword
|
||||
,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
|
||||
#endif
|
||||
);
|
||||
HRESULT ReadDatabase2(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
CArchiveDatabaseEx &database
|
||||
CArchiveDatabaseEx &db
|
||||
#ifndef _NO_CRYPTO
|
||||
,ICryptoGetTextPassword *getTextPassword
|
||||
,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
|
||||
#endif
|
||||
);
|
||||
public:
|
||||
@@ -223,9 +231,9 @@ public:
|
||||
|
||||
HRESULT ReadDatabase(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
CArchiveDatabaseEx &database
|
||||
CArchiveDatabaseEx &db
|
||||
#ifndef _NO_CRYPTO
|
||||
,ICryptoGetTextPassword *getTextPassword
|
||||
,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
|
||||
#endif
|
||||
);
|
||||
};
|
||||
|
||||
@@ -35,19 +35,19 @@ struct CFolder
|
||||
CObjectVector<CCoderInfo> Coders;
|
||||
CRecordVector<CBindPair> BindPairs;
|
||||
CRecordVector<CNum> PackStreams;
|
||||
CRecordVector<UInt64> UnPackSizes;
|
||||
UInt32 UnPackCRC;
|
||||
bool UnPackCRCDefined;
|
||||
CRecordVector<UInt64> UnpackSizes;
|
||||
UInt32 UnpackCRC;
|
||||
bool UnpackCRCDefined;
|
||||
|
||||
CFolder(): UnPackCRCDefined(false) {}
|
||||
CFolder(): UnpackCRCDefined(false) {}
|
||||
|
||||
UInt64 GetUnPackSize() const // test it
|
||||
{
|
||||
if (UnPackSizes.IsEmpty())
|
||||
UInt64 GetUnpackSize() const // test it
|
||||
{
|
||||
if (UnpackSizes.IsEmpty())
|
||||
return 0;
|
||||
for (int i = UnPackSizes.Size() - 1; i >= 0; i--)
|
||||
for (int i = UnpackSizes.Size() - 1; i >= 0; i--)
|
||||
if (FindBindPairForOutStream(i) < 0)
|
||||
return UnPackSizes[i];
|
||||
return UnpackSizes[i];
|
||||
throw 1;
|
||||
}
|
||||
|
||||
@@ -82,101 +82,171 @@ struct CFolder
|
||||
}
|
||||
};
|
||||
|
||||
typedef FILETIME CArchiveFileTime;
|
||||
|
||||
class CFileItem
|
||||
struct CUInt64DefVector
|
||||
{
|
||||
public:
|
||||
CArchiveFileTime CreationTime;
|
||||
CArchiveFileTime LastWriteTime;
|
||||
CArchiveFileTime LastAccessTime;
|
||||
UInt64 UnPackSize;
|
||||
UInt64 StartPos;
|
||||
UInt32 Attributes;
|
||||
UInt32 FileCRC;
|
||||
CRecordVector<UInt64> Values;
|
||||
CRecordVector<bool> Defined;
|
||||
|
||||
void Clear()
|
||||
{
|
||||
Values.Clear();
|
||||
Defined.Clear();
|
||||
}
|
||||
|
||||
void ReserveDown()
|
||||
{
|
||||
Values.ReserveDown();
|
||||
Values.ReserveDown();
|
||||
}
|
||||
|
||||
bool GetItem(int index, UInt64 &value) const
|
||||
{
|
||||
if (index < Defined.Size() && Defined[index])
|
||||
{
|
||||
value = Values[index];
|
||||
return true;
|
||||
}
|
||||
value = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
void SetItem(int index, bool defined, UInt64 value)
|
||||
{
|
||||
while (index >= Defined.Size())
|
||||
Defined.Add(false);
|
||||
Defined[index] = defined;
|
||||
if (!defined)
|
||||
return;
|
||||
while (index >= Values.Size())
|
||||
Values.Add(0);
|
||||
Values[index] = value;
|
||||
}
|
||||
|
||||
bool CheckSize(int size) const { return Defined.Size() == size || Defined.Size() == 0; }
|
||||
};
|
||||
|
||||
struct CFileItem
|
||||
{
|
||||
UInt64 Size;
|
||||
UInt32 Attrib;
|
||||
UInt32 Crc;
|
||||
UString Name;
|
||||
|
||||
bool HasStream; // Test it !!! it means that there is
|
||||
bool HasStream; // Test it !!! it means that there is
|
||||
// stream in some folder. It can be empty stream
|
||||
bool IsDirectory;
|
||||
bool IsAnti;
|
||||
bool IsFileCRCDefined;
|
||||
bool AreAttributesDefined;
|
||||
bool IsCreationTimeDefined;
|
||||
bool IsLastWriteTimeDefined;
|
||||
bool IsLastAccessTimeDefined;
|
||||
bool IsStartPosDefined;
|
||||
bool IsDir;
|
||||
bool CrcDefined;
|
||||
bool AttribDefined;
|
||||
|
||||
/*
|
||||
const bool HasStream() const {
|
||||
return !IsDirectory && !IsAnti && UnPackSize != 0; }
|
||||
*/
|
||||
CFileItem():
|
||||
CFileItem():
|
||||
HasStream(true),
|
||||
IsDirectory(false),
|
||||
IsAnti(false),
|
||||
IsFileCRCDefined(false),
|
||||
AreAttributesDefined(false),
|
||||
IsCreationTimeDefined(false),
|
||||
IsLastWriteTimeDefined(false),
|
||||
IsLastAccessTimeDefined(false),
|
||||
IsStartPosDefined(false)
|
||||
IsDir(false),
|
||||
CrcDefined(false),
|
||||
AttribDefined(false)
|
||||
{}
|
||||
void SetAttributes(UInt32 attributes)
|
||||
{
|
||||
AreAttributesDefined = true;
|
||||
Attributes = attributes;
|
||||
}
|
||||
void SetCreationTime(const CArchiveFileTime &creationTime)
|
||||
{
|
||||
IsCreationTimeDefined = true;
|
||||
CreationTime = creationTime;
|
||||
}
|
||||
void SetLastWriteTime(const CArchiveFileTime &lastWriteTime)
|
||||
void SetAttrib(UInt32 attrib)
|
||||
{
|
||||
IsLastWriteTimeDefined = true;
|
||||
LastWriteTime = lastWriteTime;
|
||||
}
|
||||
void SetLastAccessTime(const CArchiveFileTime &lastAccessTime)
|
||||
{
|
||||
IsLastAccessTimeDefined = true;
|
||||
LastAccessTime = lastAccessTime;
|
||||
AttribDefined = true;
|
||||
Attrib = attrib;
|
||||
}
|
||||
};
|
||||
|
||||
struct CFileItem2
|
||||
{
|
||||
UInt64 CTime;
|
||||
UInt64 ATime;
|
||||
UInt64 MTime;
|
||||
UInt64 StartPos;
|
||||
bool CTimeDefined;
|
||||
bool ATimeDefined;
|
||||
bool MTimeDefined;
|
||||
bool StartPosDefined;
|
||||
bool IsAnti;
|
||||
};
|
||||
|
||||
struct CArchiveDatabase
|
||||
{
|
||||
CRecordVector<UInt64> PackSizes;
|
||||
CRecordVector<bool> PackCRCsDefined;
|
||||
CRecordVector<UInt32> PackCRCs;
|
||||
CObjectVector<CFolder> Folders;
|
||||
CRecordVector<CNum> NumUnPackStreamsVector;
|
||||
CRecordVector<CNum> NumUnpackStreamsVector;
|
||||
CObjectVector<CFileItem> Files;
|
||||
|
||||
CUInt64DefVector CTime;
|
||||
CUInt64DefVector ATime;
|
||||
CUInt64DefVector MTime;
|
||||
CUInt64DefVector StartPos;
|
||||
CRecordVector<bool> IsAnti;
|
||||
|
||||
void Clear()
|
||||
{
|
||||
PackSizes.Clear();
|
||||
PackCRCsDefined.Clear();
|
||||
PackCRCs.Clear();
|
||||
Folders.Clear();
|
||||
NumUnPackStreamsVector.Clear();
|
||||
NumUnpackStreamsVector.Clear();
|
||||
Files.Clear();
|
||||
CTime.Clear();
|
||||
ATime.Clear();
|
||||
MTime.Clear();
|
||||
StartPos.Clear();
|
||||
IsAnti.Clear();
|
||||
}
|
||||
|
||||
void ReserveDown()
|
||||
{
|
||||
PackSizes.ReserveDown();
|
||||
PackCRCsDefined.ReserveDown();
|
||||
PackCRCs.ReserveDown();
|
||||
Folders.ReserveDown();
|
||||
NumUnpackStreamsVector.ReserveDown();
|
||||
Files.ReserveDown();
|
||||
CTime.ReserveDown();
|
||||
ATime.ReserveDown();
|
||||
MTime.ReserveDown();
|
||||
StartPos.ReserveDown();
|
||||
IsAnti.ReserveDown();
|
||||
}
|
||||
|
||||
bool IsEmpty() const
|
||||
{
|
||||
return (PackSizes.IsEmpty() &&
|
||||
PackCRCsDefined.IsEmpty() &&
|
||||
PackCRCs.IsEmpty() &&
|
||||
Folders.IsEmpty() &&
|
||||
NumUnPackStreamsVector.IsEmpty() &&
|
||||
return (PackSizes.IsEmpty() &&
|
||||
PackCRCsDefined.IsEmpty() &&
|
||||
PackCRCs.IsEmpty() &&
|
||||
Folders.IsEmpty() &&
|
||||
NumUnpackStreamsVector.IsEmpty() &&
|
||||
Files.IsEmpty());
|
||||
}
|
||||
|
||||
bool CheckNumFiles() const
|
||||
{
|
||||
int size = Files.Size();
|
||||
return (
|
||||
CTime.CheckSize(size) &&
|
||||
ATime.CheckSize(size) &&
|
||||
MTime.CheckSize(size) &&
|
||||
StartPos.CheckSize(size) &&
|
||||
(size == IsAnti.Size() || IsAnti.Size() == 0));
|
||||
}
|
||||
|
||||
bool IsSolid() const
|
||||
{
|
||||
for (int i = 0; i < NumUnPackStreamsVector.Size(); i++)
|
||||
if (NumUnPackStreamsVector[i] > 1)
|
||||
for (int i = 0; i < NumUnpackStreamsVector.Size(); i++)
|
||||
if (NumUnpackStreamsVector[i] > 1)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
bool IsItemAnti(int index) const { return (index < IsAnti.Size() && IsAnti[index]); }
|
||||
void SetItemAnti(int index, bool isAnti)
|
||||
{
|
||||
while (index >= IsAnti.Size())
|
||||
IsAnti.Add(false);
|
||||
IsAnti[index] = isAnti;
|
||||
}
|
||||
|
||||
void GetFile(int index, CFileItem &file, CFileItem2 &file2) const;
|
||||
void AddFile(const CFileItem &file, const CFileItem2 &file2);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,6 @@
|
||||
#include "7zEncode.h"
|
||||
|
||||
#include "../../Common/OutBuffer.h"
|
||||
#include "../../../Common/DynamicBuffer.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
@@ -21,58 +20,41 @@ class CWriteBufferLoc
|
||||
size_t _pos;
|
||||
public:
|
||||
CWriteBufferLoc(): _size(0), _pos(0) {}
|
||||
void Init(Byte *data, size_t size)
|
||||
{
|
||||
_pos = 0;
|
||||
void Init(Byte *data, size_t size)
|
||||
{
|
||||
_data = data;
|
||||
_size = size;
|
||||
}
|
||||
HRESULT Write(const void *data, size_t size)
|
||||
{
|
||||
if (_pos + size > _size)
|
||||
return E_FAIL;
|
||||
memmove(_data + _pos, data, size);
|
||||
_pos += size;
|
||||
return S_OK;
|
||||
}
|
||||
};
|
||||
|
||||
class CWriteDynamicBuffer
|
||||
{
|
||||
CByteDynamicBuffer _buffer;
|
||||
size_t _pos;
|
||||
public:
|
||||
CWriteDynamicBuffer(): _pos(0) {}
|
||||
void Init()
|
||||
{
|
||||
_size = size;
|
||||
_pos = 0;
|
||||
}
|
||||
void Write(const void *data, size_t size)
|
||||
void WriteBytes(const void *data, size_t size)
|
||||
{
|
||||
if (_pos + size > _buffer.GetCapacity())
|
||||
_buffer.EnsureCapacity(_pos + size);
|
||||
memmove(((Byte *)_buffer) +_pos, data, size);
|
||||
if (size > _size - _pos)
|
||||
throw 1;
|
||||
memcpy(_data + _pos, data, size);
|
||||
_pos += size;
|
||||
}
|
||||
operator Byte *() { return (Byte *)_buffer; };
|
||||
operator const Byte *() const { return (const Byte *)_buffer; };
|
||||
size_t GetSize() const { return _pos; }
|
||||
void WriteByte(Byte b)
|
||||
{
|
||||
if (_size == _pos)
|
||||
throw 1;
|
||||
_data[_pos++] = b;
|
||||
}
|
||||
size_t GetPos() const { return _pos; }
|
||||
};
|
||||
|
||||
struct CHeaderOptions
|
||||
{
|
||||
// bool UseAdditionalHeaderStreams;
|
||||
bool CompressMainHeader;
|
||||
bool WriteModified;
|
||||
bool WriteCreated;
|
||||
bool WriteAccessed;
|
||||
bool WriteCTime;
|
||||
bool WriteATime;
|
||||
bool WriteMTime;
|
||||
|
||||
CHeaderOptions():
|
||||
// UseAdditionalHeaderStreams(false),
|
||||
CHeaderOptions():
|
||||
CompressMainHeader(true),
|
||||
WriteModified(true),
|
||||
WriteCreated(false),
|
||||
WriteAccessed(false) {}
|
||||
WriteCTime(false),
|
||||
WriteATime(false),
|
||||
WriteMTime(true)
|
||||
{}
|
||||
};
|
||||
|
||||
class COutArchive
|
||||
@@ -80,56 +62,41 @@ class COutArchive
|
||||
UInt64 _prefixHeaderPos;
|
||||
|
||||
HRESULT WriteDirect(const void *data, UInt32 size);
|
||||
HRESULT WriteDirectByte(Byte b) { return WriteDirect(&b, 1); }
|
||||
HRESULT WriteDirectUInt32(UInt32 value);
|
||||
HRESULT WriteDirectUInt64(UInt64 value);
|
||||
|
||||
HRESULT WriteBytes(const void *data, size_t size);
|
||||
HRESULT WriteBytes(const CByteBuffer &data);
|
||||
HRESULT WriteByte(Byte b);
|
||||
HRESULT WriteUInt32(UInt32 value);
|
||||
HRESULT WriteNumber(UInt64 value);
|
||||
HRESULT WriteID(UInt64 value) { return WriteNumber(value); }
|
||||
UInt64 GetPos() const;
|
||||
void WriteBytes(const void *data, size_t size);
|
||||
void WriteBytes(const CByteBuffer &data) { WriteBytes(data, data.GetCapacity()); }
|
||||
void WriteByte(Byte b);
|
||||
void WriteUInt32(UInt32 value);
|
||||
void WriteUInt64(UInt64 value);
|
||||
void WriteNumber(UInt64 value);
|
||||
void WriteID(UInt64 value) { WriteNumber(value); }
|
||||
|
||||
HRESULT WriteFolder(const CFolder &folder);
|
||||
void WriteFolder(const CFolder &folder);
|
||||
HRESULT WriteFileHeader(const CFileItem &itemInfo);
|
||||
HRESULT WriteBoolVector(const CBoolVector &boolVector);
|
||||
HRESULT WriteHashDigests(
|
||||
void WriteBoolVector(const CBoolVector &boolVector);
|
||||
void WriteHashDigests(
|
||||
const CRecordVector<bool> &digestsDefined,
|
||||
const CRecordVector<UInt32> &hashDigests);
|
||||
|
||||
HRESULT WritePackInfo(
|
||||
void WritePackInfo(
|
||||
UInt64 dataOffset,
|
||||
const CRecordVector<UInt64> &packSizes,
|
||||
const CRecordVector<bool> &packCRCsDefined,
|
||||
const CRecordVector<UInt32> &packCRCs);
|
||||
|
||||
HRESULT WriteUnPackInfo(const CObjectVector<CFolder> &folders);
|
||||
void WriteUnpackInfo(const CObjectVector<CFolder> &folders);
|
||||
|
||||
HRESULT WriteSubStreamsInfo(
|
||||
void WriteSubStreamsInfo(
|
||||
const CObjectVector<CFolder> &folders,
|
||||
const CRecordVector<CNum> &numUnPackStreamsInFolders,
|
||||
const CRecordVector<UInt64> &unPackSizes,
|
||||
const CRecordVector<CNum> &numUnpackStreamsInFolders,
|
||||
const CRecordVector<UInt64> &unpackSizes,
|
||||
const CRecordVector<bool> &digestsDefined,
|
||||
const CRecordVector<UInt32> &hashDigests);
|
||||
|
||||
/*
|
||||
HRESULT WriteStreamsInfo(
|
||||
UInt64 dataOffset,
|
||||
const CRecordVector<UInt64> &packSizes,
|
||||
const CRecordVector<bool> &packCRCsDefined,
|
||||
const CRecordVector<UInt32> &packCRCs,
|
||||
bool externalFolders,
|
||||
UInt64 externalFoldersStreamIndex,
|
||||
const CObjectVector<CFolder> &folders,
|
||||
const CRecordVector<CNum> &numUnPackStreamsInFolders,
|
||||
const CRecordVector<UInt64> &unPackSizes,
|
||||
const CRecordVector<bool> &digestsDefined,
|
||||
const CRecordVector<UInt32> &hashDigests);
|
||||
*/
|
||||
|
||||
|
||||
HRESULT WriteTime(const CObjectVector<CFileItem> &files, Byte type);
|
||||
void SkipAlign(unsigned pos, unsigned alignSize);
|
||||
void WriteAlignedBoolHeader(const CBoolVector &v, int numDefined, Byte type, unsigned itemSize);
|
||||
void WriteUInt64DefVector(const CUInt64DefVector &v, Byte type);
|
||||
|
||||
HRESULT EncodeStream(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
@@ -137,23 +104,19 @@ class COutArchive
|
||||
CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders);
|
||||
HRESULT EncodeStream(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
CEncoder &encoder, const CByteBuffer &data,
|
||||
CEncoder &encoder, const CByteBuffer &data,
|
||||
CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders);
|
||||
HRESULT WriteHeader(
|
||||
const CArchiveDatabase &database,
|
||||
void WriteHeader(
|
||||
const CArchiveDatabase &db,
|
||||
const CHeaderOptions &headerOptions,
|
||||
UInt64 &headerOffset);
|
||||
|
||||
bool _mainMode;
|
||||
|
||||
bool _dynamicMode;
|
||||
|
||||
bool _countMode;
|
||||
bool _writeToStream;
|
||||
size_t _countSize;
|
||||
UInt32 _crc;
|
||||
COutBuffer _outByte;
|
||||
CWriteBufferLoc _outByte2;
|
||||
CWriteDynamicBuffer _dynamicBuffer;
|
||||
UInt32 _crc;
|
||||
|
||||
#ifdef _7Z_VOL
|
||||
bool _endMarker;
|
||||
@@ -177,8 +140,8 @@ public:
|
||||
HRESULT SkeepPrefixArchiveHeader();
|
||||
HRESULT WriteDatabase(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
const CArchiveDatabase &database,
|
||||
const CCompressionMethodMode *options,
|
||||
const CArchiveDatabase &db,
|
||||
const CCompressionMethodMode *options,
|
||||
const CHeaderOptions &headerOptions);
|
||||
|
||||
#ifdef _7Z_VOL
|
||||
|
||||
@@ -17,11 +17,11 @@ struct CPropMap
|
||||
STATPROPSTG StatPROPSTG;
|
||||
};
|
||||
|
||||
CPropMap kPropMap[] =
|
||||
CPropMap kPropMap[] =
|
||||
{
|
||||
{ NID::kName, NULL, kpidPath, VT_BSTR},
|
||||
{ NID::kSize, NULL, kpidSize, VT_UI8},
|
||||
{ NID::kPackInfo, NULL, kpidPackedSize, VT_UI8},
|
||||
{ NID::kPackInfo, NULL, kpidPackSize, VT_UI8},
|
||||
|
||||
#ifdef _MULTI_PACK
|
||||
{ 100, L"Pack0", kpidPackedSize0, VT_UI8},
|
||||
@@ -31,10 +31,10 @@ CPropMap kPropMap[] =
|
||||
{ 104, L"Pack4", kpidPackedSize4, VT_UI8},
|
||||
#endif
|
||||
|
||||
{ NID::kCreationTime, NULL, kpidCreationTime, VT_FILETIME},
|
||||
{ NID::kLastWriteTime, NULL, kpidLastWriteTime, VT_FILETIME},
|
||||
{ NID::kLastAccessTime, NULL, kpidLastAccessTime, VT_FILETIME},
|
||||
{ NID::kWinAttributes, NULL, kpidAttributes, VT_UI4},
|
||||
{ NID::kCTime, NULL, kpidCTime, VT_FILETIME},
|
||||
{ NID::kMTime, NULL, kpidMTime, VT_FILETIME},
|
||||
{ NID::kATime, NULL, kpidATime, VT_FILETIME},
|
||||
{ NID::kWinAttributes, NULL, kpidAttrib, VT_UI4},
|
||||
{ NID::kStartPos, NULL, kpidPosition, VT_UI4},
|
||||
|
||||
{ NID::kCRC, NULL, kpidCRC, VT_UI4},
|
||||
@@ -58,7 +58,7 @@ static int FindPropInMap(UInt64 filePropID)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void CopyOneItem(CRecordVector<UInt64> &src,
|
||||
static void CopyOneItem(CRecordVector<UInt64> &src,
|
||||
CRecordVector<UInt64> &dest, UInt32 item)
|
||||
{
|
||||
for (int i = 0; i < src.Size(); i++)
|
||||
@@ -92,17 +92,17 @@ static void InsertToHead(CRecordVector<UInt64> &dest, UInt32 item)
|
||||
}
|
||||
|
||||
void CHandler::FillPopIDs()
|
||||
{
|
||||
{
|
||||
_fileInfoPopIDs.Clear();
|
||||
|
||||
#ifdef _7Z_VOL
|
||||
if(_volumes.Size() < 1)
|
||||
return;
|
||||
const CVolume &volume = _volumes.Front();
|
||||
const CArchiveDatabaseEx &_database = volume.Database;
|
||||
const CArchiveDatabaseEx &_db = volume.Database;
|
||||
#endif
|
||||
|
||||
CRecordVector<UInt64> fileInfoPopIDs = _database.ArchiveInfo.FileInfoPopIDs;
|
||||
CRecordVector<UInt64> fileInfoPopIDs = _db.ArchiveInfo.FileInfoPopIDs;
|
||||
|
||||
RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream);
|
||||
RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile);
|
||||
@@ -111,13 +111,13 @@ void CHandler::FillPopIDs()
|
||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kAnti);
|
||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kSize);
|
||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kPackInfo);
|
||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCreationTime);
|
||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kLastWriteTime);
|
||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kLastAccessTime);
|
||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCTime);
|
||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kMTime);
|
||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kATime);
|
||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kWinAttributes);
|
||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCRC);
|
||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kComment);
|
||||
_fileInfoPopIDs += fileInfoPopIDs;
|
||||
_fileInfoPopIDs += fileInfoPopIDs;
|
||||
|
||||
#ifndef _SFX
|
||||
_fileInfoPopIDs.Add(97);
|
||||
@@ -133,7 +133,7 @@ void CHandler::FillPopIDs()
|
||||
#endif
|
||||
|
||||
#ifndef _SFX
|
||||
InsertToHead(_fileInfoPopIDs, NID::kLastWriteTime);
|
||||
InsertToHead(_fileInfoPopIDs, NID::kMTime);
|
||||
InsertToHead(_fileInfoPopIDs, NID::kPackInfo);
|
||||
InsertToHead(_fileInfoPopIDs, NID::kSize);
|
||||
InsertToHead(_fileInfoPopIDs, NID::kName);
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace N7z {
|
||||
enum
|
||||
{
|
||||
kpidPackedSize0 = kpidUserDefined,
|
||||
kpidPackedSize1,
|
||||
kpidPackedSize1,
|
||||
kpidPackedSize2,
|
||||
kpidPackedSize3,
|
||||
kpidPackedSize4
|
||||
|
||||
@@ -11,7 +11,7 @@ STDMETHODIMP CSequentialInStreamSizeCount2::Read(void *data, UInt32 size, UInt32
|
||||
_size += realProcessedSize;
|
||||
if (processedSize != 0)
|
||||
*processedSize = realProcessedSize;
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize(
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "../../ICoder.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
|
||||
class CSequentialInStreamSizeCount2:
|
||||
class CSequentialInStreamSizeCount2:
|
||||
public ISequentialInStream,
|
||||
public ICompressGetSubStreamSize,
|
||||
public CMyUnknownImp
|
||||
|
||||
@@ -22,7 +22,7 @@ static const UInt32 kDictionaryForBCJ2_LZMA = 1 << 20;
|
||||
static const UInt32 kAlgorithmForBCJ2_LZMA = 1;
|
||||
static const UInt32 kNumFastBytesForBCJ2_LZMA = 64;
|
||||
|
||||
static HRESULT WriteRange(IInStream *inStream, ISequentialOutStream *outStream,
|
||||
static HRESULT WriteRange(IInStream *inStream, ISequentialOutStream *outStream,
|
||||
UInt64 position, UInt64 size, ICompressProgressInfo *progress)
|
||||
{
|
||||
RINOK(inStream->Seek(position, STREAM_SEEK_SET, 0));
|
||||
@@ -117,9 +117,9 @@ static int CompareFolderRefs(const int *p1, const int *p2, void *param)
|
||||
db.Folders[i1],
|
||||
db.Folders[i2]));
|
||||
RINOZ(MyCompare(
|
||||
db.NumUnPackStreamsVector[i1],
|
||||
db.NumUnPackStreamsVector[i2]));
|
||||
if (db.NumUnPackStreamsVector[i1] == 0)
|
||||
db.NumUnpackStreamsVector[i1],
|
||||
db.NumUnpackStreamsVector[i2]));
|
||||
if (db.NumUnpackStreamsVector[i1] == 0)
|
||||
return 0;
|
||||
return CompareFiles(
|
||||
db.Files[db.FolderStartFileIndex[i1]],
|
||||
@@ -133,9 +133,9 @@ static int CompareEmptyItems(const int *p1, const int *p2, void *param)
|
||||
const CObjectVector<CUpdateItem> &updateItems = *(const CObjectVector<CUpdateItem> *)param;
|
||||
const CUpdateItem &u1 = updateItems[*p1];
|
||||
const CUpdateItem &u2 = updateItems[*p2];
|
||||
if (u1.IsDirectory != u2.IsDirectory)
|
||||
return (u1.IsDirectory) ? 1 : -1;
|
||||
if (u1.IsDirectory)
|
||||
if (u1.IsDir != u2.IsDir)
|
||||
return (u1.IsDir) ? 1 : -1;
|
||||
if (u1.IsDir)
|
||||
{
|
||||
if (u1.IsAnti != u2.IsAnti)
|
||||
return (u1.IsAnti ? 1 : -1);
|
||||
@@ -147,8 +147,8 @@ static int CompareEmptyItems(const int *p1, const int *p2, void *param)
|
||||
return MyStringCompareNoCase(u1.Name, u2.Name);
|
||||
}
|
||||
|
||||
static const char *g_Exts =
|
||||
" lzma 7z ace arc arj bz bz2 deb lzo lzx gz pak rpm sit tgz tbz tbz2 tgz cab ha lha lzh rar zoo"
|
||||
static const char *g_Exts =
|
||||
" lzma 7z ace arc arj bz bz2 deb lzo lzx gz pak rpm sit tgz tbz tbz2 tgz cab ha lha lzh rar zoo"
|
||||
" zip jar ear war msi"
|
||||
" 3gp avi mov mpeg mpg mpe wmv"
|
||||
" aac ape fla flac la mp3 m4a mp4 ofr ogg pac ra rm rka shn swa tta wv wma wav"
|
||||
@@ -161,7 +161,7 @@ static const char *g_Exts =
|
||||
" iso bin nrg mdf img pdi tar cpio xpi"
|
||||
" vfd vhd vud vmc vsv"
|
||||
" vmdk dsk nvram vmem vmsd vmsn vmss vmtm"
|
||||
" inl inc idl acf asa h hpp hxx c cpp cxx rc java cs pas bas vb cls ctl frm dlg def"
|
||||
" inl inc idl acf asa h hpp hxx c cpp cxx rc java cs pas bas vb cls ctl frm dlg def"
|
||||
" f77 f f90 f95"
|
||||
" asm sql manifest dep "
|
||||
" mak clw csproj vcproj sln dsp dsw "
|
||||
@@ -212,29 +212,29 @@ int GetExtIndex(const char *ext)
|
||||
|
||||
struct CRefItem
|
||||
{
|
||||
UInt32 Index;
|
||||
const CUpdateItem *UpdateItem;
|
||||
UInt32 Index;
|
||||
UInt32 ExtensionPos;
|
||||
UInt32 NamePos;
|
||||
int ExtensionIndex;
|
||||
CRefItem(UInt32 index, const CUpdateItem &updateItem, bool sortByType):
|
||||
CRefItem(UInt32 index, const CUpdateItem &ui, bool sortByType):
|
||||
UpdateItem(&ui),
|
||||
Index(index),
|
||||
UpdateItem(&updateItem),
|
||||
ExtensionPos(0),
|
||||
NamePos(0),
|
||||
ExtensionIndex(0)
|
||||
{
|
||||
if (sortByType)
|
||||
{
|
||||
int slashPos = GetReverseSlashPos(updateItem.Name);
|
||||
int slashPos = GetReverseSlashPos(ui.Name);
|
||||
NamePos = ((slashPos >= 0) ? (slashPos + 1) : 0);
|
||||
int dotPos = updateItem.Name.ReverseFind(L'.');
|
||||
int dotPos = ui.Name.ReverseFind(L'.');
|
||||
if (dotPos < 0 || (dotPos < slashPos && slashPos >= 0))
|
||||
ExtensionPos = updateItem.Name.Length();
|
||||
else
|
||||
ExtensionPos = ui.Name.Length();
|
||||
else
|
||||
{
|
||||
ExtensionPos = dotPos + 1;
|
||||
UString us = updateItem.Name.Mid(ExtensionPos);
|
||||
UString us = ui.Name.Mid(ExtensionPos);
|
||||
if (!us.IsEmpty())
|
||||
{
|
||||
us.MakeLower();
|
||||
@@ -264,9 +264,9 @@ static int CompareUpdateItems(const CRefItem *p1, const CRefItem *p2, void *para
|
||||
const CUpdateItem &u1 = *a1.UpdateItem;
|
||||
const CUpdateItem &u2 = *a2.UpdateItem;
|
||||
int n;
|
||||
if (u1.IsDirectory != u2.IsDirectory)
|
||||
return (u1.IsDirectory) ? 1 : -1;
|
||||
if (u1.IsDirectory)
|
||||
if (u1.IsDir != u2.IsDir)
|
||||
return (u1.IsDir) ? 1 : -1;
|
||||
if (u1.IsDir)
|
||||
{
|
||||
if (u1.IsAnti != u2.IsAnti)
|
||||
return (u1.IsAnti ? 1 : -1);
|
||||
@@ -279,8 +279,9 @@ static int CompareUpdateItems(const CRefItem *p1, const CRefItem *p2, void *para
|
||||
RINOZ(MyCompare(a1.ExtensionIndex, a2.ExtensionIndex))
|
||||
RINOZ(MyStringCompareNoCase(u1.Name + a1.ExtensionPos, u2.Name + a2.ExtensionPos));
|
||||
RINOZ(MyStringCompareNoCase(u1.Name + a1.NamePos, u2.Name + a2.NamePos));
|
||||
if (u1.IsLastWriteTimeDefined && u2.IsLastWriteTimeDefined)
|
||||
RINOZ(CompareFileTime(&u1.LastWriteTime, &u2.LastWriteTime));
|
||||
if (!u1.MTimeDefined && u2.MTimeDefined) return 1;
|
||||
if (u1.MTimeDefined && !u2.MTimeDefined) return -1;
|
||||
if (u1.MTimeDefined && u2.MTimeDefined) RINOZ(MyCompare(u1.MTime, u2.MTime));
|
||||
RINOZ(MyCompare(u1.Size, u2.Size))
|
||||
}
|
||||
return MyStringCompareNoCase(u1.Name, u2.Name);
|
||||
@@ -313,7 +314,7 @@ static const UInt64 k_LZMA = 0x030101;
|
||||
static const UInt64 k_BCJ = 0x03030103;
|
||||
static const UInt64 k_BCJ2 = 0x0303011B;
|
||||
|
||||
static bool GetMethodFull(UInt64 methodID,
|
||||
static bool GetMethodFull(UInt64 methodID,
|
||||
UInt32 numInStreams, CMethodFull &methodResult)
|
||||
{
|
||||
methodResult.Id = methodID;
|
||||
@@ -322,7 +323,7 @@ static bool GetMethodFull(UInt64 methodID,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool MakeExeMethod(const CCompressionMethodMode &method,
|
||||
static bool MakeExeMethod(const CCompressionMethodMode &method,
|
||||
bool bcj2Filter, CCompressionMethodMode &exeMethod)
|
||||
{
|
||||
exeMethod = method;
|
||||
@@ -392,10 +393,10 @@ static bool MakeExeMethod(const CCompressionMethodMode &method,
|
||||
exeMethod.Binds.Add(bind);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static void SplitFilesToGroups(
|
||||
const CCompressionMethodMode &method,
|
||||
const CCompressionMethodMode &method,
|
||||
bool useFilters, bool maxFilter,
|
||||
const CObjectVector<CUpdateItem> &updateItems,
|
||||
CObjectVector<CSolidGroup> &groups)
|
||||
@@ -411,14 +412,14 @@ static void SplitFilesToGroups(
|
||||
int i;
|
||||
for (i = 0; i < updateItems.Size(); i++)
|
||||
{
|
||||
const CUpdateItem &updateItem = updateItems[i];
|
||||
if (!updateItem.NewData)
|
||||
const CUpdateItem &ui = updateItems[i];
|
||||
if (!ui.NewData)
|
||||
continue;
|
||||
if (!updateItem.HasStream())
|
||||
if (!ui.HasStream())
|
||||
continue;
|
||||
if (useFilters)
|
||||
{
|
||||
const UString name = updateItem.Name;
|
||||
const UString name = ui.Name;
|
||||
int dotPos = name.ReverseFind(L'.');
|
||||
if (dotPos >= 0)
|
||||
{
|
||||
@@ -442,31 +443,31 @@ static void SplitFilesToGroups(
|
||||
i++;
|
||||
}
|
||||
|
||||
static void FromUpdateItemToFileItem(const CUpdateItem &updateItem,
|
||||
CFileItem &file)
|
||||
static void FromUpdateItemToFileItem(const CUpdateItem &ui,
|
||||
CFileItem &file, CFileItem2 &file2)
|
||||
{
|
||||
file.Name = NItemName::MakeLegalName(updateItem.Name);
|
||||
if (updateItem.AttributesAreDefined)
|
||||
file.SetAttributes(updateItem.Attributes);
|
||||
file.Name = NItemName::MakeLegalName(ui.Name);
|
||||
if (ui.AttribDefined)
|
||||
file.SetAttrib(ui.Attrib);
|
||||
|
||||
if (updateItem.IsCreationTimeDefined)
|
||||
file.SetCreationTime(updateItem.CreationTime);
|
||||
if (updateItem.IsLastWriteTimeDefined)
|
||||
file.SetLastWriteTime(updateItem.LastWriteTime);
|
||||
if (updateItem.IsLastAccessTimeDefined)
|
||||
file.SetLastAccessTime(updateItem.LastAccessTime);
|
||||
|
||||
file.UnPackSize = updateItem.Size;
|
||||
file.IsDirectory = updateItem.IsDirectory;
|
||||
file.IsAnti = updateItem.IsAnti;
|
||||
file.HasStream = updateItem.HasStream();
|
||||
file2.CTime = ui.CTime; file2.CTimeDefined = ui.CTimeDefined;
|
||||
file2.ATime = ui.ATime; file2.ATimeDefined = ui.ATimeDefined;
|
||||
file2.MTime = ui.MTime; file2.MTimeDefined = ui.MTimeDefined;
|
||||
file2.IsAnti = ui.IsAnti;
|
||||
file2.StartPosDefined = false;
|
||||
|
||||
file.Size = ui.Size;
|
||||
file.IsDir = ui.IsDir;
|
||||
file.HasStream = ui.HasStream();
|
||||
}
|
||||
|
||||
static HRESULT Update2(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
IInStream *inStream,
|
||||
const CArchiveDatabaseEx *database,
|
||||
const CArchiveDatabaseEx *db,
|
||||
const CObjectVector<CUpdateItem> &updateItems,
|
||||
COutArchive &archive,
|
||||
CArchiveDatabase &newDatabase,
|
||||
ISequentialOutStream *seqOutStream,
|
||||
IArchiveUpdateCallback *updateCallback,
|
||||
const CUpdateOptions &options)
|
||||
@@ -481,17 +482,17 @@ static HRESULT Update2(
|
||||
return E_NOTIMPL;
|
||||
*/
|
||||
|
||||
UInt64 startBlockSize = database != 0 ? database->ArchiveInfo.StartPosition: 0;
|
||||
UInt64 startBlockSize = db != 0 ? db->ArchiveInfo.StartPosition: 0;
|
||||
if (startBlockSize > 0 && !options.RemoveSfxBlock)
|
||||
{
|
||||
RINOK(WriteRange(inStream, seqOutStream, 0, startBlockSize, NULL));
|
||||
}
|
||||
|
||||
CRecordVector<int> fileIndexToUpdateIndexMap;
|
||||
if (database != 0)
|
||||
if (db != 0)
|
||||
{
|
||||
fileIndexToUpdateIndexMap.Reserve(database->Files.Size());
|
||||
for (int i = 0; i < database->Files.Size(); i++)
|
||||
fileIndexToUpdateIndexMap.Reserve(db->Files.Size());
|
||||
for (int i = 0; i < db->Files.Size(); i++)
|
||||
fileIndexToUpdateIndexMap.Add(-1);
|
||||
}
|
||||
int i;
|
||||
@@ -503,17 +504,17 @@ static HRESULT Update2(
|
||||
}
|
||||
|
||||
CRecordVector<int> folderRefs;
|
||||
if (database != 0)
|
||||
if (db != 0)
|
||||
{
|
||||
for(i = 0; i < database->Folders.Size(); i++)
|
||||
for(i = 0; i < db->Folders.Size(); i++)
|
||||
{
|
||||
CNum indexInFolder = 0;
|
||||
CNum numCopyItems = 0;
|
||||
CNum numUnPackStreams = database->NumUnPackStreamsVector[i];
|
||||
for (CNum fileIndex = database->FolderStartFileIndex[i];
|
||||
indexInFolder < numUnPackStreams; fileIndex++)
|
||||
CNum numUnpackStreams = db->NumUnpackStreamsVector[i];
|
||||
for (CNum fileIndex = db->FolderStartFileIndex[i];
|
||||
indexInFolder < numUnpackStreams; fileIndex++)
|
||||
{
|
||||
if (database->Files[fileIndex].HasStream)
|
||||
if (db->Files[fileIndex].HasStream)
|
||||
{
|
||||
indexInFolder++;
|
||||
int updateIndex = fileIndexToUpdateIndexMap[fileIndex];
|
||||
@@ -522,38 +523,35 @@ static HRESULT Update2(
|
||||
numCopyItems++;
|
||||
}
|
||||
}
|
||||
if (numCopyItems != numUnPackStreams && numCopyItems != 0)
|
||||
if (numCopyItems != numUnpackStreams && numCopyItems != 0)
|
||||
return E_NOTIMPL; // It needs repacking !!!
|
||||
if (numCopyItems > 0)
|
||||
folderRefs.Add(i);
|
||||
}
|
||||
folderRefs.Sort(CompareFolderRefs, (void *)database);
|
||||
folderRefs.Sort(CompareFolderRefs, (void *)db);
|
||||
}
|
||||
|
||||
CArchiveDatabase newDatabase;
|
||||
|
||||
////////////////////////////
|
||||
|
||||
COutArchive archive;
|
||||
RINOK(archive.Create(seqOutStream, false));
|
||||
RINOK(archive.SkeepPrefixArchiveHeader());
|
||||
UInt64 complexity = 0;
|
||||
for(i = 0; i < folderRefs.Size(); i++)
|
||||
complexity += database->GetFolderFullPackSize(folderRefs[i]);
|
||||
complexity += db->GetFolderFullPackSize(folderRefs[i]);
|
||||
UInt64 inSizeForReduce = 0;
|
||||
for(i = 0; i < updateItems.Size(); i++)
|
||||
{
|
||||
const CUpdateItem &updateItem = updateItems[i];
|
||||
if (updateItem.NewData)
|
||||
const CUpdateItem &ui = updateItems[i];
|
||||
if (ui.NewData)
|
||||
{
|
||||
complexity += updateItem.Size;
|
||||
complexity += ui.Size;
|
||||
if (numSolidFiles == 1)
|
||||
{
|
||||
if (updateItem.Size > inSizeForReduce)
|
||||
inSizeForReduce = updateItem.Size;
|
||||
if (ui.Size > inSizeForReduce)
|
||||
inSizeForReduce = ui.Size;
|
||||
}
|
||||
else
|
||||
inSizeForReduce += updateItem.Size;
|
||||
inSizeForReduce += ui.Size;
|
||||
}
|
||||
}
|
||||
RINOK(updateCallback->SetTotal(complexity));
|
||||
@@ -573,57 +571,62 @@ static HRESULT Update2(
|
||||
int folderIndex = folderRefs[i];
|
||||
|
||||
lps->ProgressOffset = complexity;
|
||||
UInt64 packSize = database->GetFolderFullPackSize(folderIndex);
|
||||
UInt64 packSize = db->GetFolderFullPackSize(folderIndex);
|
||||
RINOK(WriteRange(inStream, archive.SeqStream,
|
||||
database->GetFolderStreamPos(folderIndex, 0), packSize, progress));
|
||||
db->GetFolderStreamPos(folderIndex, 0), packSize, progress));
|
||||
complexity += packSize;
|
||||
|
||||
const CFolder &folder = database->Folders[folderIndex];
|
||||
CNum startIndex = database->FolderStartPackStreamIndex[folderIndex];
|
||||
const CFolder &folder = db->Folders[folderIndex];
|
||||
CNum startIndex = db->FolderStartPackStreamIndex[folderIndex];
|
||||
for (int j = 0; j < folder.PackStreams.Size(); j++)
|
||||
{
|
||||
newDatabase.PackSizes.Add(database->PackSizes[startIndex + j]);
|
||||
// newDatabase.PackCRCsDefined.Add(database.PackCRCsDefined[startIndex + j]);
|
||||
// newDatabase.PackCRCs.Add(database.PackCRCs[startIndex + j]);
|
||||
newDatabase.PackSizes.Add(db->PackSizes[startIndex + j]);
|
||||
// newDatabase.PackCRCsDefined.Add(db.PackCRCsDefined[startIndex + j]);
|
||||
// newDatabase.PackCRCs.Add(db.PackCRCs[startIndex + j]);
|
||||
}
|
||||
newDatabase.Folders.Add(folder);
|
||||
|
||||
CNum numUnPackStreams = database->NumUnPackStreamsVector[folderIndex];
|
||||
newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams);
|
||||
CNum numUnpackStreams = db->NumUnpackStreamsVector[folderIndex];
|
||||
newDatabase.NumUnpackStreamsVector.Add(numUnpackStreams);
|
||||
|
||||
CNum indexInFolder = 0;
|
||||
for (CNum fi = database->FolderStartFileIndex[folderIndex];
|
||||
indexInFolder < numUnPackStreams; fi++)
|
||||
for (CNum fi = db->FolderStartFileIndex[folderIndex];
|
||||
indexInFolder < numUnpackStreams; fi++)
|
||||
{
|
||||
CFileItem file = database->Files[fi];
|
||||
CFileItem file;
|
||||
CFileItem2 file2;
|
||||
db->GetFile(fi, file, file2);
|
||||
if (file.HasStream)
|
||||
{
|
||||
indexInFolder++;
|
||||
int updateIndex = fileIndexToUpdateIndexMap[fi];
|
||||
if (updateIndex >= 0)
|
||||
{
|
||||
const CUpdateItem &updateItem = updateItems[updateIndex];
|
||||
if (updateItem.NewProperties)
|
||||
const CUpdateItem &ui = updateItems[updateIndex];
|
||||
if (ui.NewProperties)
|
||||
{
|
||||
CFileItem file2;
|
||||
FromUpdateItemToFileItem(updateItem, file2);
|
||||
file2.UnPackSize = file.UnPackSize;
|
||||
file2.FileCRC = file.FileCRC;
|
||||
file2.IsFileCRCDefined = file.IsFileCRCDefined;
|
||||
file2.HasStream = file.HasStream;
|
||||
file = file2;
|
||||
CFileItem uf;
|
||||
FromUpdateItemToFileItem(ui, uf, file2);
|
||||
uf.Size = file.Size;
|
||||
uf.Crc = file.Crc;
|
||||
uf.CrcDefined = file.CrcDefined;
|
||||
uf.HasStream = file.HasStream;
|
||||
file = uf;
|
||||
}
|
||||
}
|
||||
newDatabase.Files.Add(file);
|
||||
newDatabase.AddFile(file, file2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
folderRefs.ClearAndFree();
|
||||
fileIndexToUpdateIndexMap.ClearAndFree();
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Compress New Files
|
||||
|
||||
CObjectVector<CSolidGroup> groups;
|
||||
SplitFilesToGroups(*options.Method, options.UseFilters, options.MaxFilter,
|
||||
SplitFilesToGroups(*options.Method, options.UseFilters, options.MaxFilter,
|
||||
updateItems, groups);
|
||||
|
||||
const UInt32 kMinReduceSize = (1 << 16);
|
||||
@@ -651,13 +654,13 @@ static HRESULT Update2(
|
||||
UInt32 index = refItems[i].Index;
|
||||
indices.Add(index);
|
||||
/*
|
||||
const CUpdateItem &updateItem = updateItems[index];
|
||||
const CUpdateItem &ui = updateItems[index];
|
||||
CFileItem file;
|
||||
if (updateItem.NewProperties)
|
||||
FromUpdateItemToFileItem(updateItem, file);
|
||||
if (ui.NewProperties)
|
||||
FromUpdateItemToFileItem(ui, file);
|
||||
else
|
||||
file = database.Files[updateItem.IndexInArchive];
|
||||
if (file.IsAnti || file.IsDirectory)
|
||||
file = db.Files[ui.IndexInArchive];
|
||||
if (file.IsAnti || file.IsDir)
|
||||
return E_FAIL;
|
||||
newDatabase.Files.Add(file);
|
||||
*/
|
||||
@@ -670,16 +673,16 @@ static HRESULT Update2(
|
||||
UInt64 totalSize = 0;
|
||||
int numSubFiles;
|
||||
UString prevExtension;
|
||||
for (numSubFiles = 0; i + numSubFiles < numFiles &&
|
||||
for (numSubFiles = 0; i + numSubFiles < numFiles &&
|
||||
numSubFiles < numSolidFiles; numSubFiles++)
|
||||
{
|
||||
const CUpdateItem &updateItem = updateItems[indices[i + numSubFiles]];
|
||||
totalSize += updateItem.Size;
|
||||
const CUpdateItem &ui = updateItems[indices[i + numSubFiles]];
|
||||
totalSize += ui.Size;
|
||||
if (totalSize > options.NumSolidBytes)
|
||||
break;
|
||||
if (options.SolidExtension)
|
||||
{
|
||||
UString ext = updateItem.GetExtension();
|
||||
UString ext = ui.GetExtension();
|
||||
if (numSubFiles == 0)
|
||||
prevExtension = ext;
|
||||
else
|
||||
@@ -699,29 +702,30 @@ static HRESULT Update2(
|
||||
int startPackIndex = newDatabase.PackSizes.Size();
|
||||
RINOK(encoder.Encode(
|
||||
EXTERNAL_CODECS_LOC_VARS
|
||||
solidInStream, NULL, &inSizeForReduce, folderItem,
|
||||
solidInStream, NULL, &inSizeForReduce, folderItem,
|
||||
archive.SeqStream, newDatabase.PackSizes, progress));
|
||||
|
||||
for (; startPackIndex < newDatabase.PackSizes.Size(); startPackIndex++)
|
||||
lps->OutSize += newDatabase.PackSizes[startPackIndex];
|
||||
|
||||
lps->InSize += folderItem.GetUnPackSize();
|
||||
lps->InSize += folderItem.GetUnpackSize();
|
||||
// for()
|
||||
// newDatabase.PackCRCsDefined.Add(false);
|
||||
// newDatabase.PackCRCs.Add(0);
|
||||
|
||||
newDatabase.Folders.Add(folderItem);
|
||||
|
||||
CNum numUnPackStreams = 0;
|
||||
CNum numUnpackStreams = 0;
|
||||
for (int subIndex = 0; subIndex < numSubFiles; subIndex++)
|
||||
{
|
||||
const CUpdateItem &updateItem = updateItems[indices[i + subIndex]];
|
||||
const CUpdateItem &ui = updateItems[indices[i + subIndex]];
|
||||
CFileItem file;
|
||||
if (updateItem.NewProperties)
|
||||
FromUpdateItemToFileItem(updateItem, file);
|
||||
CFileItem2 file2;
|
||||
if (ui.NewProperties)
|
||||
FromUpdateItemToFileItem(ui, file, file2);
|
||||
else
|
||||
file = database->Files[updateItem.IndexInArchive];
|
||||
if (file.IsAnti || file.IsDirectory)
|
||||
db->GetFile(ui.IndexInArchive, file, file2);
|
||||
if (file2.IsAnti || file.IsDir)
|
||||
return E_FAIL;
|
||||
|
||||
/*
|
||||
@@ -734,28 +738,30 @@ static HRESULT Update2(
|
||||
// file.Name += L".locked";
|
||||
}
|
||||
|
||||
file.FileCRC = inStreamSpec->CRCs[subIndex];
|
||||
file.UnPackSize = inStreamSpec->Sizes[subIndex];
|
||||
if (file.UnPackSize != 0)
|
||||
file.Crc = inStreamSpec->CRCs[subIndex];
|
||||
file.Size = inStreamSpec->Sizes[subIndex];
|
||||
if (file.Size != 0)
|
||||
{
|
||||
file.IsFileCRCDefined = true;
|
||||
file.CrcDefined = true;
|
||||
file.HasStream = true;
|
||||
numUnPackStreams++;
|
||||
numUnpackStreams++;
|
||||
}
|
||||
else
|
||||
{
|
||||
file.IsFileCRCDefined = false;
|
||||
file.CrcDefined = false;
|
||||
file.HasStream = false;
|
||||
}
|
||||
newDatabase.Files.Add(file);
|
||||
newDatabase.AddFile(file, file2);
|
||||
}
|
||||
// numUnPackStreams = 0 is very bad case for locked files
|
||||
// numUnpackStreams = 0 is very bad case for locked files
|
||||
// v3.13 doesn't understand it.
|
||||
newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams);
|
||||
newDatabase.NumUnpackStreamsVector.Add(numUnpackStreams);
|
||||
i += numSubFiles;
|
||||
}
|
||||
}
|
||||
|
||||
groups.ClearAndFree();
|
||||
|
||||
{
|
||||
/////////////////////////////////////////
|
||||
// Write Empty Files & Folders
|
||||
@@ -763,267 +769,51 @@ static HRESULT Update2(
|
||||
CRecordVector<int> emptyRefs;
|
||||
for(i = 0; i < updateItems.Size(); i++)
|
||||
{
|
||||
const CUpdateItem &updateItem = updateItems[i];
|
||||
if (updateItem.NewData)
|
||||
const CUpdateItem &ui = updateItems[i];
|
||||
if (ui.NewData)
|
||||
{
|
||||
if (updateItem.HasStream())
|
||||
if (ui.HasStream())
|
||||
continue;
|
||||
}
|
||||
else
|
||||
if (updateItem.IndexInArchive != -1)
|
||||
if (database->Files[updateItem.IndexInArchive].HasStream)
|
||||
if (ui.IndexInArchive != -1)
|
||||
if (db->Files[ui.IndexInArchive].HasStream)
|
||||
continue;
|
||||
emptyRefs.Add(i);
|
||||
}
|
||||
emptyRefs.Sort(CompareEmptyItems, (void *)&updateItems);
|
||||
for(i = 0; i < emptyRefs.Size(); i++)
|
||||
for (i = 0; i < emptyRefs.Size(); i++)
|
||||
{
|
||||
const CUpdateItem &updateItem = updateItems[emptyRefs[i]];
|
||||
const CUpdateItem &ui = updateItems[emptyRefs[i]];
|
||||
CFileItem file;
|
||||
if (updateItem.NewProperties)
|
||||
FromUpdateItemToFileItem(updateItem, file);
|
||||
CFileItem2 file2;
|
||||
if (ui.NewProperties)
|
||||
FromUpdateItemToFileItem(ui, file, file2);
|
||||
else
|
||||
file = database->Files[updateItem.IndexInArchive];
|
||||
newDatabase.Files.Add(file);
|
||||
db->GetFile(ui.IndexInArchive, file, file2);
|
||||
newDatabase.AddFile(file, file2);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if (newDatabase.Files.Size() != updateItems.Size())
|
||||
return E_FAIL;
|
||||
*/
|
||||
|
||||
return archive.WriteDatabase(EXTERNAL_CODECS_LOC_VARS
|
||||
newDatabase, options.HeaderMethod, options.HeaderOptions);
|
||||
}
|
||||
|
||||
#ifdef _7Z_VOL
|
||||
|
||||
static const UInt64 k_Copy = 0x0;
|
||||
|
||||
static HRESULT WriteVolumeHeader(COutArchive &archive, CFileItem &file, const CUpdateOptions &options)
|
||||
{
|
||||
CCoderInfo coder;
|
||||
coder.NumInStreams = coder.NumOutStreams = 1;
|
||||
coder.MethodID = k_Copy;
|
||||
|
||||
CFolder folder;
|
||||
folder.Coders.Add(coder);
|
||||
folder.PackStreams.Add(0);
|
||||
|
||||
CNum numUnPackStreams = 0;
|
||||
if (file.UnPackSize != 0)
|
||||
{
|
||||
file.IsFileCRCDefined = true;
|
||||
file.HasStream = true;
|
||||
numUnPackStreams++;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw 1;
|
||||
file.IsFileCRCDefined = false;
|
||||
file.HasStream = false;
|
||||
}
|
||||
folder.UnPackSizes.Add(file.UnPackSize);
|
||||
|
||||
CArchiveDatabase newDatabase;
|
||||
newDatabase.Files.Add(file);
|
||||
newDatabase.Folders.Add(folder);
|
||||
newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams);
|
||||
newDatabase.PackSizes.Add(file.UnPackSize);
|
||||
newDatabase.PackCRCsDefined.Add(false);
|
||||
newDatabase.PackCRCs.Add(file.FileCRC);
|
||||
|
||||
return archive.WriteDatabase(newDatabase,
|
||||
options.HeaderMethod,
|
||||
false,
|
||||
false);
|
||||
}
|
||||
|
||||
HRESULT UpdateVolume(
|
||||
IInStream *inStream,
|
||||
const CArchiveDatabaseEx *database,
|
||||
CObjectVector<CUpdateItem> &updateItems,
|
||||
ISequentialOutStream *seqOutStream,
|
||||
IArchiveUpdateCallback *updateCallback,
|
||||
const CUpdateOptions &options)
|
||||
{
|
||||
if (updateItems.Size() != 1)
|
||||
return E_NOTIMPL;
|
||||
|
||||
CMyComPtr<IArchiveUpdateCallback2> volumeCallback;
|
||||
RINOK(updateCallback->QueryInterface(IID_IArchiveUpdateCallback2, (void **)&volumeCallback));
|
||||
if (!volumeCallback)
|
||||
return E_NOTIMPL;
|
||||
|
||||
CMyComPtr<ISequentialInStream> fileStream;
|
||||
HRESULT result = updateCallback->GetStream(0, &fileStream);
|
||||
if (result != S_OK && result != S_FALSE)
|
||||
return result;
|
||||
if (result == S_FALSE)
|
||||
return E_FAIL;
|
||||
|
||||
CFileItem file;
|
||||
|
||||
const CUpdateItem &updateItem = updateItems[0];
|
||||
if (updateItem.NewProperties)
|
||||
FromUpdateItemToFileItem(updateItem, file);
|
||||
else
|
||||
file = database->Files[updateItem.IndexInArchive];
|
||||
if (file.IsAnti || file.IsDirectory)
|
||||
return E_FAIL;
|
||||
|
||||
UInt64 complexity = 0;
|
||||
file.IsStartPosDefined = true;
|
||||
file.StartPos = 0;
|
||||
for (UInt64 volumeIndex = 0; true; volumeIndex++)
|
||||
{
|
||||
UInt64 volSize;
|
||||
RINOK(volumeCallback->GetVolumeSize(volumeIndex, &volSize));
|
||||
UInt64 pureSize = COutArchive::GetVolPureSize(volSize, file.Name.Length(), true);
|
||||
CMyComPtr<ISequentialOutStream> volumeStream;
|
||||
RINOK(volumeCallback->GetVolumeStream(volumeIndex, &volumeStream));
|
||||
|
||||
COutArchive archive;
|
||||
RINOK(archive.Create(volumeStream, true));
|
||||
RINOK(archive.SkeepPrefixArchiveHeader());
|
||||
|
||||
CSequentialInStreamWithCRC *inCrcStreamSpec = new CSequentialInStreamWithCRC;
|
||||
CMyComPtr<ISequentialInStream> inCrcStream = inCrcStreamSpec;
|
||||
inCrcStreamSpec->Init(fileStream);
|
||||
|
||||
RINOK(WriteRange(inCrcStream, volumeStream, pureSize, updateCallback, complexity));
|
||||
file.UnPackSize = inCrcStreamSpec->GetSize();
|
||||
if (file.UnPackSize == 0)
|
||||
break;
|
||||
file.FileCRC = inCrcStreamSpec->GetCRC();
|
||||
RINOK(WriteVolumeHeader(archive, file, options));
|
||||
file.StartPos += file.UnPackSize;
|
||||
if (file.UnPackSize < pureSize)
|
||||
break;
|
||||
}
|
||||
newDatabase.ReserveDown();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
class COutVolumeStream:
|
||||
public ISequentialOutStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
int _volIndex;
|
||||
UInt64 _volSize;
|
||||
UInt64 _curPos;
|
||||
CMyComPtr<ISequentialOutStream> _volumeStream;
|
||||
COutArchive _archive;
|
||||
CCRC _crc;
|
||||
|
||||
public:
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
CFileItem _file;
|
||||
CUpdateOptions _options;
|
||||
CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;
|
||||
void Init(IArchiveUpdateCallback2 *volumeCallback,
|
||||
const UString &name)
|
||||
{
|
||||
_file.Name = name;
|
||||
_file.IsStartPosDefined = true;
|
||||
_file.StartPos = 0;
|
||||
|
||||
VolumeCallback = volumeCallback;
|
||||
_volIndex = 0;
|
||||
_volSize = 0;
|
||||
}
|
||||
|
||||
HRESULT Flush();
|
||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
};
|
||||
|
||||
HRESULT COutVolumeStream::Flush()
|
||||
{
|
||||
if (_volumeStream)
|
||||
{
|
||||
_file.UnPackSize = _curPos;
|
||||
_file.FileCRC = _crc.GetDigest();
|
||||
RINOK(WriteVolumeHeader(_archive, _file, _options));
|
||||
_archive.Close();
|
||||
_volumeStream.Release();
|
||||
_file.StartPos += _file.UnPackSize;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP COutVolumeStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
if(processedSize != NULL)
|
||||
*processedSize = 0;
|
||||
while(size > 0)
|
||||
{
|
||||
if (!_volumeStream)
|
||||
{
|
||||
RINOK(VolumeCallback->GetVolumeSize(_volIndex, &_volSize));
|
||||
RINOK(VolumeCallback->GetVolumeStream(_volIndex, &_volumeStream));
|
||||
_volIndex++;
|
||||
_curPos = 0;
|
||||
RINOK(_archive.Create(_volumeStream, true));
|
||||
RINOK(_archive.SkeepPrefixArchiveHeader());
|
||||
_crc.Init();
|
||||
continue;
|
||||
}
|
||||
UInt64 pureSize = COutArchive::GetVolPureSize(_volSize, _file.Name.Length());
|
||||
UInt32 curSize = (UInt32)MyMin(UInt64(size), pureSize - _curPos);
|
||||
|
||||
_crc.Update(data, curSize);
|
||||
UInt32 realProcessed;
|
||||
RINOK(_volumeStream->Write(data, curSize, &realProcessed))
|
||||
data = (void *)((Byte *)data + realProcessed);
|
||||
size -= realProcessed;
|
||||
if(processedSize != NULL)
|
||||
*processedSize += realProcessed;
|
||||
_curPos += realProcessed;
|
||||
if (realProcessed != curSize && realProcessed == 0)
|
||||
return E_FAIL;
|
||||
if (_curPos == pureSize)
|
||||
{
|
||||
RINOK(Flush());
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
HRESULT Update(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
IInStream *inStream,
|
||||
const CArchiveDatabaseEx *database,
|
||||
const CArchiveDatabaseEx *db,
|
||||
const CObjectVector<CUpdateItem> &updateItems,
|
||||
COutArchive &archive,
|
||||
CArchiveDatabase &newDatabase,
|
||||
ISequentialOutStream *seqOutStream,
|
||||
IArchiveUpdateCallback *updateCallback,
|
||||
const CUpdateOptions &options)
|
||||
{
|
||||
#ifdef _7Z_VOL
|
||||
if (seqOutStream)
|
||||
#endif
|
||||
return Update2(
|
||||
return Update2(
|
||||
EXTERNAL_CODECS_LOC_VARS
|
||||
inStream, database, updateItems,
|
||||
seqOutStream, updateCallback, options);
|
||||
#ifdef _7Z_VOL
|
||||
if (options.VolumeMode)
|
||||
return UpdateVolume(inStream, database, updateItems,
|
||||
seqOutStream, updateCallback, options);
|
||||
COutVolumeStream *volStreamSpec = new COutVolumeStream;
|
||||
CMyComPtr<ISequentialOutStream> volStream = volStreamSpec;
|
||||
CMyComPtr<IArchiveUpdateCallback2> volumeCallback;
|
||||
RINOK(updateCallback->QueryInterface(IID_IArchiveUpdateCallback2, (void **)&volumeCallback));
|
||||
if (!volumeCallback)
|
||||
return E_NOTIMPL;
|
||||
volStreamSpec->Init(volumeCallback, L"a.7z");
|
||||
volStreamSpec->_options = options;
|
||||
RINOK(Update2(inStream, database, updateItems,
|
||||
volStream, updateCallback, options));
|
||||
return volStreamSpec->Flush();
|
||||
#endif
|
||||
inStream, db, updateItems,
|
||||
archive, newDatabase, seqOutStream, updateCallback, options);
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -14,38 +14,40 @@ namespace N7z {
|
||||
|
||||
struct CUpdateItem
|
||||
{
|
||||
bool NewData;
|
||||
bool NewProperties;
|
||||
int IndexInArchive;
|
||||
int IndexInClient;
|
||||
|
||||
UInt32 Attributes;
|
||||
FILETIME CreationTime;
|
||||
FILETIME LastWriteTime;
|
||||
FILETIME LastAccessTime;
|
||||
UInt64 CTime;
|
||||
UInt64 ATime;
|
||||
UInt64 MTime;
|
||||
|
||||
UInt64 Size;
|
||||
UString Name;
|
||||
|
||||
UInt32 Attrib;
|
||||
|
||||
bool NewData;
|
||||
bool NewProperties;
|
||||
|
||||
bool IsAnti;
|
||||
bool IsDirectory;
|
||||
bool IsDir;
|
||||
|
||||
bool IsCreationTimeDefined;
|
||||
bool IsLastWriteTimeDefined;
|
||||
bool IsLastAccessTimeDefined;
|
||||
bool AttributesAreDefined;
|
||||
bool AttribDefined;
|
||||
bool CTimeDefined;
|
||||
bool ATimeDefined;
|
||||
bool MTimeDefined;
|
||||
|
||||
bool HasStream() const
|
||||
{ return !IsDirectory && !IsAnti && Size != 0; }
|
||||
CUpdateItem():
|
||||
IsAnti(false),
|
||||
AttributesAreDefined(false),
|
||||
IsCreationTimeDefined(false),
|
||||
IsLastWriteTimeDefined(false),
|
||||
IsLastAccessTimeDefined(false)
|
||||
bool HasStream() const { return !IsDir && !IsAnti && Size != 0; }
|
||||
|
||||
CUpdateItem():
|
||||
IsAnti(false),
|
||||
IsDir(false),
|
||||
AttribDefined(false),
|
||||
CTimeDefined(false),
|
||||
ATimeDefined(false),
|
||||
MTimeDefined(false)
|
||||
{}
|
||||
void SetDirectoryStatusFromAttributes()
|
||||
{ IsDirectory = ((Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0); };
|
||||
void SetDirStatusFromAttrib() { IsDir = ((Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0); };
|
||||
|
||||
int GetExtensionPos() const;
|
||||
UString GetExtension() const;
|
||||
@@ -70,8 +72,10 @@ struct CUpdateOptions
|
||||
HRESULT Update(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
IInStream *inStream,
|
||||
const CArchiveDatabaseEx *database,
|
||||
const CArchiveDatabaseEx *db,
|
||||
const CObjectVector<CUpdateItem> &updateItems,
|
||||
COutArchive &archive,
|
||||
CArchiveDatabase &newDatabase,
|
||||
ISequentialOutStream *seqOutStream,
|
||||
IArchiveUpdateCallback *updateCallback,
|
||||
const CUpdateOptions &options);
|
||||
|
||||
111
CPP/7zip/Archive/7z/makefile
Executable file
111
CPP/7zip/Archive/7z/makefile
Executable file
@@ -0,0 +1,111 @@
|
||||
PROG = 7z.dll
|
||||
DEF_FILE = ../Archive.def
|
||||
CFLAGS = $(CFLAGS) -I ../../../ \
|
||||
-DCOMPRESS_MT \
|
||||
-DEXTERNAL_CODECS \
|
||||
|
||||
LIBS = $(LIBS) oleaut32.lib user32.lib
|
||||
|
||||
AR_OBJS = \
|
||||
$O\ArchiveExports.obj \
|
||||
$O\DllExports.obj \
|
||||
|
||||
7Z_OBJS = \
|
||||
$O\7zCompressionMode.obj \
|
||||
$O\7zDecode.obj \
|
||||
$O\7zEncode.obj \
|
||||
$O\7zExtract.obj \
|
||||
$O\7zFolderInStream.obj \
|
||||
$O\7zFolderOutStream.obj \
|
||||
$O\7zHandler.obj \
|
||||
$O\7zHandlerOut.obj \
|
||||
$O\7zHeader.obj \
|
||||
$O\7zIn.obj \
|
||||
$O\7zOut.obj \
|
||||
$O\7zProperties.obj \
|
||||
$O\7zSpecStream.obj \
|
||||
$O\7zUpdate.obj \
|
||||
$O\7zRegister.obj \
|
||||
|
||||
COMMON_OBJS = \
|
||||
$O\CRC.obj \
|
||||
$O\IntToString.obj \
|
||||
$O\NewHandler.obj \
|
||||
$O\MyString.obj \
|
||||
$O\StringConvert.obj \
|
||||
$O\StringToInt.obj \
|
||||
$O\MyVector.obj \
|
||||
|
||||
WIN_OBJS = \
|
||||
$O\DLL.obj \
|
||||
$O\FileDir.obj \
|
||||
$O\FileFind.obj \
|
||||
$O\FileIO.obj \
|
||||
$O\PropVariant.obj \
|
||||
$O\Synchronization.obj \
|
||||
$O\System.obj \
|
||||
|
||||
7ZIP_COMMON_OBJS = \
|
||||
$O\CreateCoder.obj \
|
||||
$O\InOutTempBuffer.obj \
|
||||
$O\FilterCoder.obj \
|
||||
$O\LimitedStreams.obj \
|
||||
$O\LockedStream.obj \
|
||||
$O\MethodId.obj \
|
||||
$O\MethodProps.obj \
|
||||
$O\OutBuffer.obj \
|
||||
$O\ProgressUtils.obj \
|
||||
$O\StreamBinder.obj \
|
||||
$O\StreamObjects.obj \
|
||||
$O\StreamUtils.obj \
|
||||
$O\VirtThread.obj \
|
||||
|
||||
AR_COMMON_OBJS = \
|
||||
$O\CoderMixer2.obj \
|
||||
$O\CoderMixer2MT.obj \
|
||||
$O\CrossThreadProgress.obj \
|
||||
$O\HandlerOut.obj \
|
||||
$O\InStreamWithCRC.obj \
|
||||
$O\ItemNameUtils.obj \
|
||||
$O\MultiStream.obj \
|
||||
$O\OutStreamWithCRC.obj \
|
||||
$O\ParseProperties.obj \
|
||||
|
||||
C_OBJS = \
|
||||
$O\Alloc.obj \
|
||||
$O\Threads.obj \
|
||||
|
||||
!include "../../Crc2.mak"
|
||||
|
||||
OBJS = \
|
||||
$O\StdAfx.obj \
|
||||
$(AR_OBJS) \
|
||||
$(7Z_OBJS) \
|
||||
$(COMMON_OBJS) \
|
||||
$(WIN_OBJS) \
|
||||
$(7ZIP_COMMON_OBJS) \
|
||||
$(AR_COMMON_OBJS) \
|
||||
$O\CopyCoder.obj \
|
||||
$(C_OBJS) \
|
||||
$(CRC_OBJS) \
|
||||
$O\resource.res
|
||||
|
||||
!include "../../../Build.mak"
|
||||
|
||||
$(AR_OBJS): ../$(*B).cpp
|
||||
$(COMPL)
|
||||
$(7Z_OBJS): $(*B).cpp
|
||||
$(COMPL)
|
||||
$(COMMON_OBJS): ../../../Common/$(*B).cpp
|
||||
$(COMPL)
|
||||
$(WIN_OBJS): ../../../Windows/$(*B).cpp
|
||||
$(COMPL)
|
||||
$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
|
||||
$(COMPL)
|
||||
$(AR_COMMON_OBJS): ../Common/$(*B).cpp
|
||||
$(COMPL)
|
||||
$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
|
||||
$(COMPL)
|
||||
$(C_OBJS): ../../../../C/$(*B).c
|
||||
$(COMPL_O2)
|
||||
!include "../../Crc.mak"
|
||||
11
CPP/7zip/Archive/7z/resource.rc
Executable file
11
CPP/7zip/Archive/7z/resource.rc
Executable file
@@ -0,0 +1,11 @@
|
||||
#include "../../MyVersionInfo.rc"
|
||||
|
||||
MY_VERSION_INFO_DLL("7z Plugin", "7z")
|
||||
|
||||
0 ICON "../Icons/7z.ico"
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
100 "7z:0"
|
||||
END
|
||||
|
||||
@@ -13,14 +13,14 @@
|
||||
|
||||
static const unsigned int kNumArcsMax = 32;
|
||||
static unsigned int g_NumArcs = 0;
|
||||
static const CArcInfo *g_Arcs[kNumArcsMax];
|
||||
void RegisterArc(const CArcInfo *arcInfo)
|
||||
{
|
||||
static const CArcInfo *g_Arcs[kNumArcsMax];
|
||||
void RegisterArc(const CArcInfo *arcInfo)
|
||||
{
|
||||
if (g_NumArcs < kNumArcsMax)
|
||||
g_Arcs[g_NumArcs++] = arcInfo;
|
||||
g_Arcs[g_NumArcs++] = arcInfo;
|
||||
}
|
||||
|
||||
DEFINE_GUID(CLSID_CArchiveHandler,
|
||||
DEFINE_GUID(CLSID_CArchiveHandler,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00);
|
||||
|
||||
#define CLS_ARC_ID_ITEM(cls) ((cls).Data4[5])
|
||||
|
||||
@@ -1,311 +0,0 @@
|
||||
// ArjHandler.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/Defs.h"
|
||||
#include "Common/StringConvert.h"
|
||||
#include "Common/ComTry.h"
|
||||
|
||||
#include "Windows/Time.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
|
||||
#include "ArjHandler.h"
|
||||
|
||||
#include "../../ICoder.h"
|
||||
|
||||
#include "../../Common/StreamObjects.h"
|
||||
#include "../../Common/ProgressUtils.h"
|
||||
#include "../../Common/LimitedStreams.h"
|
||||
|
||||
#include "../../Compress/Copy/CopyCoder.h"
|
||||
#include "../../Compress/Arj/ArjDecoder1.h"
|
||||
#include "../../Compress/Arj/ArjDecoder2.h"
|
||||
|
||||
#include "../Common/ItemNameUtils.h"
|
||||
#include "../Common/OutStreamWithCRC.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NTime;
|
||||
|
||||
namespace NArchive {
|
||||
namespace NArj{
|
||||
|
||||
const wchar_t *kHostOS[] =
|
||||
{
|
||||
L"MSDOS",
|
||||
L"PRIMOS",
|
||||
L"Unix",
|
||||
L"AMIGA",
|
||||
L"Mac",
|
||||
L"OS/2",
|
||||
L"APPLE GS",
|
||||
L"Atari ST",
|
||||
L"Next",
|
||||
L"VAX VMS",
|
||||
L"WIN95"
|
||||
};
|
||||
|
||||
|
||||
const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]);
|
||||
|
||||
const wchar_t *kUnknownOS = L"Unknown";
|
||||
|
||||
|
||||
STATPROPSTG kProps[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
{ NULL, kpidIsFolder, VT_BOOL},
|
||||
{ NULL, kpidSize, VT_UI8},
|
||||
{ NULL, kpidPackedSize, VT_UI8},
|
||||
{ NULL, kpidLastWriteTime, VT_FILETIME},
|
||||
{ NULL, kpidAttributes, VT_UI4},
|
||||
{ NULL, kpidEncrypted, VT_BOOL},
|
||||
{ NULL, kpidCRC, VT_UI4},
|
||||
{ NULL, kpidMethod, VT_UI1},
|
||||
// { NULL, kpidUnpackVer, VT_UI1},
|
||||
{ NULL, kpidHostOS, VT_BSTR}
|
||||
};
|
||||
|
||||
IMP_IInArchive_Props
|
||||
IMP_IInArchive_ArcProps_NO
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
{
|
||||
*numItems = _items.Size();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
const CItemEx &item = _items[index];
|
||||
switch(propID)
|
||||
{
|
||||
case kpidPath: prop = NItemName::GetOSName(MultiByteToUnicodeString(item.Name, CP_OEMCP)); break;
|
||||
case kpidIsFolder: prop = item.IsDirectory(); break;
|
||||
case kpidSize: prop = item.Size; break;
|
||||
case kpidPackedSize: prop = item.PackSize; break;
|
||||
case kpidAttributes: prop = item.GetWinAttributes(); break;
|
||||
case kpidEncrypted: prop = item.IsEncrypted(); break;
|
||||
case kpidCRC: prop = item.FileCRC; break;
|
||||
case kpidMethod: prop = item.Method; break;
|
||||
case kpidHostOS: prop = (item.HostOS < kNumHostOSes) ? (kHostOS[item.HostOS]) : kUnknownOS; break;
|
||||
case kpidLastWriteTime:
|
||||
{
|
||||
FILETIME localFileTime, utcFileTime;
|
||||
if (DosTimeToFileTime(item.ModifiedTime, localFileTime))
|
||||
{
|
||||
if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime))
|
||||
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
|
||||
}
|
||||
else
|
||||
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
|
||||
prop = utcFileTime;
|
||||
break;
|
||||
}
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
try
|
||||
{
|
||||
_items.Clear();
|
||||
CInArchive archive;
|
||||
if(!archive.Open(inStream, maxCheckStartPosition))
|
||||
return S_FALSE;
|
||||
if (callback != NULL)
|
||||
{
|
||||
RINOK(callback->SetTotal(NULL, NULL));
|
||||
UInt64 numFiles = _items.Size();
|
||||
RINOK(callback->SetCompleted(&numFiles, NULL));
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
CItemEx item;
|
||||
bool filled;
|
||||
HRESULT result = archive.GetNextItem(filled, item);
|
||||
if (result == S_FALSE)
|
||||
return S_FALSE;
|
||||
if (result != S_OK)
|
||||
return S_FALSE;
|
||||
if (!filled)
|
||||
break;
|
||||
_items.Add(item);
|
||||
archive.IncreaseRealPosition(item.PackSize);
|
||||
if (callback != NULL)
|
||||
{
|
||||
UInt64 numFiles = _items.Size();
|
||||
RINOK(callback->SetCompleted(&numFiles, NULL));
|
||||
}
|
||||
}
|
||||
_stream = inStream;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
COM_TRY_END
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Close()
|
||||
{
|
||||
_items.Clear();
|
||||
_stream.Release();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////
|
||||
// CHandler::DecompressItems
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
Int32 testModeSpec, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool testMode = (testModeSpec != 0);
|
||||
UInt64 totalUnPacked = 0, totalPacked = 0;
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
if (allFilesMode)
|
||||
numItems = _items.Size();
|
||||
if(numItems == 0)
|
||||
return S_OK;
|
||||
UInt32 i;
|
||||
for(i = 0; i < numItems; i++)
|
||||
{
|
||||
const CItemEx &item = _items[allFilesMode ? i : indices[i]];
|
||||
totalUnPacked += item.Size;
|
||||
totalPacked += item.PackSize;
|
||||
}
|
||||
extractCallback->SetTotal(totalUnPacked);
|
||||
|
||||
UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0;
|
||||
UInt64 currentItemUnPacked, currentItemPacked;
|
||||
|
||||
CMyComPtr<ICompressCoder> arj1Decoder;
|
||||
CMyComPtr<ICompressCoder> arj2Decoder;
|
||||
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
|
||||
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
|
||||
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(extractCallback, false);
|
||||
|
||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
||||
CMyComPtr<ISequentialInStream> inStream(streamSpec);
|
||||
streamSpec->SetStream(_stream);
|
||||
|
||||
for(i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked,
|
||||
currentTotalPacked += currentItemPacked)
|
||||
{
|
||||
lps->InSize = currentTotalPacked;
|
||||
lps->OutSize = currentTotalUnPacked;
|
||||
RINOK(lps->SetCur());
|
||||
|
||||
currentItemUnPacked = currentItemPacked = 0;
|
||||
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode = testMode ?
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract;
|
||||
Int32 index = allFilesMode ? i : indices[i];
|
||||
const CItemEx &item = _items[index];
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
|
||||
if(item.IsDirectory())
|
||||
{
|
||||
// if (!testMode)
|
||||
{
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!testMode && (!realOutStream))
|
||||
continue;
|
||||
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
currentItemUnPacked = item.Size;
|
||||
currentItemPacked = item.PackSize;
|
||||
|
||||
{
|
||||
COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;
|
||||
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
|
||||
outStreamSpec->SetStream(realOutStream);
|
||||
outStreamSpec->Init();
|
||||
realOutStream.Release();
|
||||
|
||||
streamSpec->Init(item.PackSize);
|
||||
|
||||
UInt64 pos;
|
||||
_stream->Seek(item.DataPosition, STREAM_SEEK_SET, &pos);
|
||||
|
||||
HRESULT result = S_OK;
|
||||
Int32 opRes = NExtract::NOperationResult::kOK;
|
||||
|
||||
if (item.IsEncrypted())
|
||||
{
|
||||
opRes = NExtract::NOperationResult::kUnSupportedMethod;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(item.Method)
|
||||
{
|
||||
case NFileHeader::NCompressionMethod::kStored:
|
||||
{
|
||||
result = copyCoder->Code(inStream, outStream, NULL, NULL, progress);
|
||||
if (result == S_OK && copyCoderSpec->TotalSize != item.PackSize)
|
||||
result = S_FALSE;
|
||||
break;
|
||||
}
|
||||
case NFileHeader::NCompressionMethod::kCompressed1a:
|
||||
case NFileHeader::NCompressionMethod::kCompressed1b:
|
||||
case NFileHeader::NCompressionMethod::kCompressed1c:
|
||||
{
|
||||
if (!arj1Decoder)
|
||||
arj1Decoder = new NCompress::NArj::NDecoder1::CCoder;
|
||||
result = arj1Decoder->Code(inStream, outStream, NULL, ¤tItemUnPacked, progress);
|
||||
break;
|
||||
}
|
||||
case NFileHeader::NCompressionMethod::kCompressed2:
|
||||
{
|
||||
if (!arj2Decoder)
|
||||
arj2Decoder = new NCompress::NArj::NDecoder2::CCoder;
|
||||
result = arj2Decoder->Code(inStream, outStream, NULL, ¤tItemUnPacked, progress);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
opRes = NExtract::NOperationResult::kUnSupportedMethod;
|
||||
}
|
||||
}
|
||||
if (opRes == NExtract::NOperationResult::kOK)
|
||||
{
|
||||
if (result == S_FALSE)
|
||||
opRes = NExtract::NOperationResult::kDataError;
|
||||
else
|
||||
{
|
||||
RINOK(result);
|
||||
opRes = (outStreamSpec->GetCRC() == item.FileCRC) ?
|
||||
NExtract::NOperationResult::kOK:
|
||||
NExtract::NOperationResult::kCRCError;
|
||||
}
|
||||
}
|
||||
outStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(opRes));
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
@@ -1,121 +0,0 @@
|
||||
// Archive/Arj/Header.h
|
||||
|
||||
#ifndef __ARCHIVE_ARJ_HEADER_H
|
||||
#define __ARCHIVE_ARJ_HEADER_H
|
||||
|
||||
#include "Common/Types.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NArj {
|
||||
|
||||
const int kMaxBlockSize = 2600;
|
||||
|
||||
namespace NSignature
|
||||
{
|
||||
const Byte kSig0 = 0x60;
|
||||
const Byte kSig1 = 0xEA;
|
||||
}
|
||||
|
||||
/*
|
||||
struct CArchiveHeader
|
||||
{
|
||||
// UInt16 BasicHeaderSize;
|
||||
Byte FirstHeaderSize;
|
||||
Byte Version;
|
||||
Byte ExtractVersion;
|
||||
Byte HostOS;
|
||||
Byte Flags;
|
||||
Byte SecuryVersion;
|
||||
Byte FileType;
|
||||
Byte Reserved;
|
||||
UInt32 CreatedTime;
|
||||
UInt32 ModifiedTime;
|
||||
UInt32 ArchiveSize;
|
||||
UInt32 SecurityEnvelopeFilePosition;
|
||||
UInt16 FilespecPositionInFilename;
|
||||
UInt16 LengthOfSecurityEnvelopeSata;
|
||||
Byte EncryptionVersion;
|
||||
Byte LastChapter;
|
||||
};
|
||||
*/
|
||||
|
||||
namespace NFileHeader
|
||||
{
|
||||
namespace NCompressionMethod
|
||||
{
|
||||
enum EType
|
||||
{
|
||||
kStored = 0,
|
||||
kCompressed1a = 1,
|
||||
kCompressed1b = 2,
|
||||
kCompressed1c = 3,
|
||||
kCompressed2 = 4,
|
||||
kNoDataNoCRC = 8,
|
||||
kNoData = 9
|
||||
};
|
||||
}
|
||||
namespace NFileType
|
||||
{
|
||||
enum EType
|
||||
{
|
||||
kBinary = 0,
|
||||
k7BitText = 1,
|
||||
kDirectory = 3,
|
||||
kVolumeLablel = 4,
|
||||
kChapterLabel = 5
|
||||
};
|
||||
}
|
||||
namespace NFlags
|
||||
{
|
||||
const Byte kGarbled = 1;
|
||||
const Byte kVolume = 4;
|
||||
const Byte kExtFile = 8;
|
||||
const Byte kPathSym = 0x10;
|
||||
const Byte kBackup= 0x20;
|
||||
}
|
||||
|
||||
/*
|
||||
struct CHeader
|
||||
{
|
||||
Byte FirstHeaderSize;
|
||||
Byte Version;
|
||||
Byte ExtractVersion;
|
||||
Byte HostOS;
|
||||
Byte Flags;
|
||||
Byte Method;
|
||||
Byte FileType;
|
||||
Byte Reserved;
|
||||
UInt32 ModifiedTime;
|
||||
UInt32 PackSize;
|
||||
UInt32 Size;
|
||||
UInt32 FileCRC;
|
||||
UInt16 FilespecPositionInFilename;
|
||||
UInt16 FileAccessMode;
|
||||
Byte FirstChapter;
|
||||
Byte LastChapter;
|
||||
};
|
||||
*/
|
||||
|
||||
namespace NHostOS
|
||||
{
|
||||
enum EEnum
|
||||
{
|
||||
kMSDOS = 0, // filesystem used by MS-DOS, OS/2, Win32
|
||||
// pkarj 2.50 (FAT / VFAT / FAT32 file systems)
|
||||
kPRIMOS = 1,
|
||||
kUnix = 2, // VAX/VMS
|
||||
kAMIGA = 3,
|
||||
kMac = 4,
|
||||
kOS_2 = 5, // what if it's a minix filesystem? [cjh]
|
||||
kAPPLE_GS = 6, // filesystem used by OS/2 (and NT 3.x)
|
||||
kAtari_ST = 7,
|
||||
kNext = 8,
|
||||
kVAX_VMS = 9,
|
||||
kWIN95 = 10
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -1,287 +0,0 @@
|
||||
// Archive/arj/InEngine.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/StringConvert.h"
|
||||
#include "Common/Buffer.h"
|
||||
|
||||
#include "../../Common/StreamUtils.h"
|
||||
|
||||
#include "ArjIn.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../../C/7zCrc.h"
|
||||
}
|
||||
|
||||
namespace NArchive {
|
||||
namespace NArj {
|
||||
|
||||
HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
size_t realProcessedSize = size;
|
||||
HRESULT result = ReadStream(_stream, data, &realProcessedSize);
|
||||
if (processedSize != NULL)
|
||||
*processedSize = (UInt32)realProcessedSize;
|
||||
IncreasePositionValue(realProcessedSize);
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline UInt16 GetUInt16FromMemLE(const Byte *p)
|
||||
{
|
||||
return (UInt16)(p[0] | (((UInt16)p[1]) << 8));
|
||||
}
|
||||
|
||||
static inline UInt32 GetUInt32FromMemLE(const Byte *p)
|
||||
{
|
||||
return p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24);
|
||||
}
|
||||
|
||||
inline bool TestMarkerCandidate(const void *testBytes, UInt32 maxSize)
|
||||
{
|
||||
if (maxSize < 2 + 2 + 4)
|
||||
return false;
|
||||
const Byte *block = ((const Byte *)(testBytes));
|
||||
if (block[0] != NSignature::kSig0 || block[1] != NSignature::kSig1)
|
||||
return false;
|
||||
UInt32 blockSize = GetUInt16FromMemLE(block + 2);
|
||||
if (maxSize < 2 + 2 + blockSize + 4)
|
||||
return false;
|
||||
block += 4;
|
||||
if (blockSize == 0 || blockSize > 2600)
|
||||
return false;
|
||||
UInt32 crcFromFile = GetUInt32FromMemLE(block + blockSize);
|
||||
return (crcFromFile == CrcCalc(block, blockSize));
|
||||
}
|
||||
|
||||
bool CInArchive::FindAndReadMarker(const UInt64 *searchHeaderSizeLimit)
|
||||
{
|
||||
// _archiveInfo.StartPosition = 0;
|
||||
_position = _streamStartPosition;
|
||||
if(_stream->Seek(_streamStartPosition, STREAM_SEEK_SET, NULL) != S_OK)
|
||||
return false;
|
||||
|
||||
const int kMarkerSizeMax = 2 + 2 + kMaxBlockSize + 4;
|
||||
|
||||
CByteBuffer byteBuffer;
|
||||
static const UInt32 kSearchMarkerBufferSize = 0x10000;
|
||||
byteBuffer.SetCapacity(kSearchMarkerBufferSize);
|
||||
Byte *buffer = byteBuffer;
|
||||
|
||||
UInt32 processedSize;
|
||||
ReadBytes(buffer, kMarkerSizeMax, &processedSize);
|
||||
if (processedSize == 0)
|
||||
return false;
|
||||
if (TestMarkerCandidate(buffer, processedSize))
|
||||
{
|
||||
_position = _streamStartPosition;
|
||||
if(_stream->Seek(_position, STREAM_SEEK_SET, NULL) != S_OK)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
UInt32 numBytesPrev = processedSize - 1;
|
||||
memmove(buffer, buffer + 1, numBytesPrev);
|
||||
UInt64 curTestPos = _streamStartPosition + 1;
|
||||
for (;;)
|
||||
{
|
||||
if (searchHeaderSizeLimit != NULL)
|
||||
if (curTestPos - _streamStartPosition > *searchHeaderSizeLimit)
|
||||
return false;
|
||||
UInt32 numReadBytes = kSearchMarkerBufferSize - numBytesPrev;
|
||||
ReadBytes(buffer + numBytesPrev, numReadBytes, &processedSize);
|
||||
UInt32 numBytesInBuffer = numBytesPrev + processedSize;
|
||||
if (numBytesInBuffer < 1)
|
||||
return false;
|
||||
UInt32 numTests = numBytesInBuffer;
|
||||
for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++)
|
||||
{
|
||||
if (TestMarkerCandidate(buffer + pos, numBytesInBuffer - pos))
|
||||
{
|
||||
// _archiveInfo.StartPosition = curTestPos;
|
||||
_position = curTestPos;
|
||||
if(_stream->Seek(_position, STREAM_SEEK_SET, NULL) != S_OK)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
numBytesPrev = numBytesInBuffer - numTests;
|
||||
memmove(buffer, buffer + numTests, numBytesPrev);
|
||||
}
|
||||
}
|
||||
|
||||
void CInArchive::IncreasePositionValue(UInt64 addValue)
|
||||
{
|
||||
_position += addValue;
|
||||
}
|
||||
|
||||
void CInArchive::IncreaseRealPosition(UInt64 addValue)
|
||||
{
|
||||
if(_stream->Seek(addValue, STREAM_SEEK_CUR, &_position) != S_OK)
|
||||
throw CInArchiveException(CInArchiveException::kSeekStreamError);
|
||||
}
|
||||
|
||||
bool CInArchive::ReadBytesAndTestSize(void *data, UInt32 size)
|
||||
{
|
||||
UInt32 realProcessedSize;
|
||||
if(ReadBytes(data, size, &realProcessedSize) != S_OK)
|
||||
throw CInArchiveException(CInArchiveException::kReadStreamError);
|
||||
return (realProcessedSize == size);
|
||||
}
|
||||
|
||||
void CInArchive::SafeReadBytes(void *data, UInt32 size)
|
||||
{
|
||||
if(!ReadBytesAndTestSize(data, size))
|
||||
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
|
||||
}
|
||||
|
||||
Byte CInArchive::SafeReadByte()
|
||||
{
|
||||
Byte b;
|
||||
SafeReadBytes(&b, 1);
|
||||
return b;
|
||||
}
|
||||
|
||||
UInt16 CInArchive::SafeReadUInt16()
|
||||
{
|
||||
UInt16 value = 0;
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
Byte b = SafeReadByte();
|
||||
value |= (UInt16(b) << (8 * i));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
UInt32 CInArchive::SafeReadUInt32()
|
||||
{
|
||||
UInt32 value = 0;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
Byte b = SafeReadByte();
|
||||
value |= (UInt32(b) << (8 * i));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
bool CInArchive::ReadBlock()
|
||||
{
|
||||
_blockPos = 0;
|
||||
_blockSize = SafeReadUInt16();
|
||||
if (_blockSize == 0 || _blockSize > kMaxBlockSize)
|
||||
return false;
|
||||
SafeReadBytes(_block, _blockSize);
|
||||
UInt32 crcFromFile = SafeReadUInt32();
|
||||
if (crcFromFile != CrcCalc(_block, _blockSize))
|
||||
throw CInArchiveException(CInArchiveException::kCRCError);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CInArchive::ReadBlock2()
|
||||
{
|
||||
Byte id[2];
|
||||
ReadBytesAndTestSize(id, 2);
|
||||
if (id[0] != NSignature::kSig0 || id[1] != NSignature::kSig1)
|
||||
throw CInArchiveException(CInArchiveException::kIncorrectArchive);
|
||||
return ReadBlock();
|
||||
}
|
||||
|
||||
bool CInArchive::Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit)
|
||||
{
|
||||
_stream = inStream;
|
||||
if(_stream->Seek(0, STREAM_SEEK_CUR, &_streamStartPosition) != S_OK)
|
||||
return false;
|
||||
_position = _streamStartPosition;
|
||||
if (!FindAndReadMarker(searchHeaderSizeLimit))
|
||||
return false;
|
||||
if (!ReadBlock2())
|
||||
return false;
|
||||
for (;;)
|
||||
if (!ReadBlock())
|
||||
break;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CInArchive::Close()
|
||||
{
|
||||
_stream.Release();
|
||||
}
|
||||
|
||||
void CInArchive::ThrowIncorrectArchiveException()
|
||||
{
|
||||
throw CInArchiveException(CInArchiveException::kIncorrectArchive);
|
||||
}
|
||||
|
||||
Byte CInArchive::ReadByte()
|
||||
{
|
||||
if (_blockPos >= _blockSize)
|
||||
ThrowIncorrectArchiveException();
|
||||
return _block[_blockPos++];
|
||||
}
|
||||
|
||||
UInt16 CInArchive::ReadUInt16()
|
||||
{
|
||||
UInt16 value = 0;
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
Byte b = ReadByte();
|
||||
value |= (UInt16(b) << (8 * i));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
UInt32 CInArchive::ReadUInt32()
|
||||
{
|
||||
UInt32 value = 0;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
Byte b = ReadByte();
|
||||
value |= (UInt32(b) << (8 * i));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
|
||||
{
|
||||
filled = false;
|
||||
if (!ReadBlock2())
|
||||
return S_OK;
|
||||
|
||||
Byte firstHeaderSize = ReadByte();
|
||||
item.Version = ReadByte();
|
||||
item.ExtractVersion = ReadByte();
|
||||
item.HostOS = ReadByte();
|
||||
item.Flags = ReadByte();
|
||||
item.Method = ReadByte();
|
||||
item.FileType = ReadByte();
|
||||
ReadByte(); // Reserved
|
||||
item.ModifiedTime = ReadUInt32();
|
||||
item.PackSize = ReadUInt32();
|
||||
item.Size = ReadUInt32();
|
||||
item.FileCRC = ReadUInt32();
|
||||
ReadUInt16(); // FilespecPositionInFilename
|
||||
item.FileAccessMode = ReadUInt16();
|
||||
ReadByte(); // FirstChapter
|
||||
ReadByte(); // LastChapter
|
||||
|
||||
/*
|
||||
UInt32 extraData;
|
||||
if ((header.Flags & NFileHeader::NFlags::kExtFile) != 0)
|
||||
extraData = GetUInt32FromMemLE(_block + pos);
|
||||
*/
|
||||
_blockPos = firstHeaderSize;
|
||||
|
||||
for (; _blockPos < _blockSize;)
|
||||
item.Name += (char)ReadByte();
|
||||
|
||||
for (;;)
|
||||
if (!ReadBlock())
|
||||
break;
|
||||
|
||||
item.DataPosition = _position;
|
||||
|
||||
filled = true;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -1,75 +0,0 @@
|
||||
// Archive/ArjIn.h
|
||||
|
||||
#ifndef __ARCHIVE_ARJIN_H
|
||||
#define __ARCHIVE_ARJIN_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "../../IStream.h"
|
||||
|
||||
#include "ArjItem.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NArj {
|
||||
|
||||
class CInArchiveException
|
||||
{
|
||||
public:
|
||||
enum CCauseType
|
||||
{
|
||||
kUnexpectedEndOfArchive = 0,
|
||||
kCRCError,
|
||||
kIncorrectArchive,
|
||||
kReadStreamError,
|
||||
kSeekStreamError
|
||||
}
|
||||
Cause;
|
||||
CInArchiveException(CCauseType cause): Cause(cause) {};
|
||||
};
|
||||
|
||||
class CProgressVirt
|
||||
{
|
||||
public:
|
||||
STDMETHOD(SetCompleted)(const UInt64 *numFiles) PURE;
|
||||
};
|
||||
|
||||
class CInArchive
|
||||
{
|
||||
CMyComPtr<IInStream> _stream;
|
||||
UInt64 _streamStartPosition;
|
||||
UInt64 _position;
|
||||
UInt16 _blockSize;
|
||||
Byte _block[kMaxBlockSize];
|
||||
UInt32 _blockPos;
|
||||
|
||||
|
||||
bool FindAndReadMarker(const UInt64 *searchHeaderSizeLimit);
|
||||
|
||||
bool ReadBlock();
|
||||
bool ReadBlock2();
|
||||
|
||||
Byte ReadByte();
|
||||
UInt16 ReadUInt16();
|
||||
UInt32 ReadUInt32();
|
||||
|
||||
HRESULT ReadBytes(void *data, UInt32 size, UInt32 *processedSize);
|
||||
bool ReadBytesAndTestSize(void *data, UInt32 size);
|
||||
void SafeReadBytes(void *data, UInt32 size);
|
||||
Byte SafeReadByte();
|
||||
UInt16 SafeReadUInt16();
|
||||
UInt32 SafeReadUInt32();
|
||||
|
||||
void IncreasePositionValue(UInt64 addValue);
|
||||
void ThrowIncorrectArchiveException();
|
||||
|
||||
public:
|
||||
HRESULT GetNextItem(bool &filled, CItemEx &item);
|
||||
|
||||
bool Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit);
|
||||
void Close();
|
||||
|
||||
void IncreaseRealPosition(UInt64 addValue);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -1,75 +0,0 @@
|
||||
// Archive/ArjItem.h
|
||||
|
||||
#ifndef __ARCHIVE_ARJ_ITEM_H
|
||||
#define __ARCHIVE_ARJ_ITEM_H
|
||||
|
||||
#include "Common/Types.h"
|
||||
#include "Common/MyString.h"
|
||||
#include "ArjHeader.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NArj {
|
||||
|
||||
struct CVersion
|
||||
{
|
||||
Byte Version;
|
||||
Byte HostOS;
|
||||
};
|
||||
|
||||
inline bool operator==(const CVersion &v1, const CVersion &v2)
|
||||
{ return (v1.Version == v2.Version) && (v1.HostOS == v2.HostOS); }
|
||||
inline bool operator!=(const CVersion &v1, const CVersion &v2)
|
||||
{ return !(v1 == v2); }
|
||||
|
||||
class CItem
|
||||
{
|
||||
public:
|
||||
Byte Version;
|
||||
Byte ExtractVersion;
|
||||
Byte HostOS;
|
||||
Byte Flags;
|
||||
Byte Method;
|
||||
Byte FileType;
|
||||
UInt32 ModifiedTime;
|
||||
UInt32 PackSize;
|
||||
UInt32 Size;
|
||||
UInt32 FileCRC;
|
||||
|
||||
// UInt16 FilespecPositionInFilename;
|
||||
UInt16 FileAccessMode;
|
||||
// Byte FirstChapter;
|
||||
// Byte LastChapter;
|
||||
|
||||
AString Name;
|
||||
|
||||
bool IsEncrypted() const { return (Flags & NFileHeader::NFlags::kGarbled) != 0; }
|
||||
bool IsDirectory() const { return (FileType == NFileHeader::NFileType::kDirectory); }
|
||||
UInt32 GetWinAttributes() const
|
||||
{
|
||||
UInt32 winAtrributes;
|
||||
switch(HostOS)
|
||||
{
|
||||
case NFileHeader::NHostOS::kMSDOS:
|
||||
case NFileHeader::NHostOS::kWIN95:
|
||||
winAtrributes = FileAccessMode;
|
||||
break;
|
||||
default:
|
||||
winAtrributes = 0;
|
||||
}
|
||||
if (IsDirectory())
|
||||
winAtrributes |= FILE_ATTRIBUTE_DIRECTORY;
|
||||
return winAtrributes;
|
||||
}
|
||||
};
|
||||
|
||||
class CItemEx: public CItem
|
||||
{
|
||||
public:
|
||||
UInt64 DataPosition;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
// ArjRegister.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../Common/RegisterArc.h"
|
||||
|
||||
#include "ArjHandler.h"
|
||||
static IInArchive *CreateArc() { return new NArchive::NArj::CHandler; }
|
||||
|
||||
static CArcInfo g_ArcInfo =
|
||||
{ L"Arj", L"arj", 0, 4, { 0x60, 0xEA }, 2, false, CreateArc, 0 };
|
||||
|
||||
REGISTER_ARC(Arj)
|
||||
@@ -1,3 +0,0 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
792
CPP/7zip/Archive/ArjHandler.cpp
Executable file
792
CPP/7zip/Archive/ArjHandler.cpp
Executable file
@@ -0,0 +1,792 @@
|
||||
// ArjHandler.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/ComTry.h"
|
||||
#include "Common/StringConvert.h"
|
||||
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "Windows/Time.h"
|
||||
|
||||
#include "../../../C/CpuArch.h"
|
||||
|
||||
#include "../Common/LimitedStreams.h"
|
||||
#include "../Common/ProgressUtils.h"
|
||||
#include "../Common/RegisterArc.h"
|
||||
#include "../Common/StreamObjects.h"
|
||||
#include "../Common/StreamUtils.h"
|
||||
|
||||
#include "../Compress/Arj/ArjDecoder1.h"
|
||||
#include "../Compress/Arj/ArjDecoder2.h"
|
||||
#include "../Compress/Copy/CopyCoder.h"
|
||||
|
||||
#include "IArchive.h"
|
||||
|
||||
#include "Common/ItemNameUtils.h"
|
||||
#include "Common/OutStreamWithCRC.h"
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
#define Get16(p) GetUi16(p)
|
||||
#define Get32(p) GetUi32(p)
|
||||
|
||||
namespace NArchive {
|
||||
namespace NArj {
|
||||
|
||||
const int kBlockSizeMin = 30;
|
||||
const int kBlockSizeMax = 2600;
|
||||
|
||||
namespace NSignature
|
||||
{
|
||||
const Byte kSig0 = 0x60;
|
||||
const Byte kSig1 = 0xEA;
|
||||
}
|
||||
|
||||
namespace NFileHeader
|
||||
{
|
||||
namespace NCompressionMethod
|
||||
{
|
||||
enum
|
||||
{
|
||||
kStored = 0,
|
||||
kCompressed1a = 1,
|
||||
kCompressed1b = 2,
|
||||
kCompressed1c = 3,
|
||||
kCompressed2 = 4,
|
||||
kNoDataNoCRC = 8,
|
||||
kNoData = 9
|
||||
};
|
||||
}
|
||||
|
||||
namespace NFileType
|
||||
{
|
||||
enum
|
||||
{
|
||||
kBinary = 0,
|
||||
k7BitText = 1,
|
||||
kArchiveHeader = 2,
|
||||
kDirectory = 3,
|
||||
kVolumeLablel = 4,
|
||||
kChapterLabel = 5
|
||||
};
|
||||
}
|
||||
|
||||
namespace NFlags
|
||||
{
|
||||
const Byte kGarbled = 1;
|
||||
const Byte kVolume = 4;
|
||||
const Byte kExtFile = 8;
|
||||
const Byte kPathSym = 0x10;
|
||||
const Byte kBackup = 0x20;
|
||||
}
|
||||
|
||||
namespace NHostOS
|
||||
{
|
||||
enum EEnum
|
||||
{
|
||||
kMSDOS = 0, // filesystem used by MS-DOS, OS/2, Win32
|
||||
// pkarj 2.50 (FAT / VFAT / FAT32 file systems)
|
||||
kPRIMOS,
|
||||
kUnix,
|
||||
kAMIGA,
|
||||
kMac,
|
||||
kOS_2,
|
||||
kAPPLE_GS,
|
||||
kAtari_ST,
|
||||
kNext,
|
||||
kVAX_VMS,
|
||||
kWIN95
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
struct CArchiveHeader
|
||||
{
|
||||
// Byte ArchiverVersion;
|
||||
// Byte ExtractVersion;
|
||||
Byte HostOS;
|
||||
// Byte Flags;
|
||||
// Byte SecuryVersion;
|
||||
// Byte FileType;
|
||||
// Byte Reserved;
|
||||
UInt32 CTime;
|
||||
UInt32 MTime;
|
||||
UInt32 ArchiveSize;
|
||||
// UInt32 SecurityEnvelopeFilePosition;
|
||||
// UInt16 FilespecPositionInFilename;
|
||||
// UInt16 LengthOfSecurityEnvelopeSata;
|
||||
// Byte EncryptionVersion;
|
||||
// Byte LastChapter;
|
||||
AString Name;
|
||||
AString Comment;
|
||||
|
||||
HRESULT Parse(const Byte *p, unsigned size);
|
||||
};
|
||||
|
||||
static HRESULT ReadString(const Byte *p, unsigned &size, AString &res)
|
||||
{
|
||||
AString s;
|
||||
for (unsigned i = 0; i < size;)
|
||||
{
|
||||
char c = (char)p[i++];
|
||||
if (c == 0)
|
||||
{
|
||||
size = i;
|
||||
res = s;
|
||||
return S_OK;
|
||||
}
|
||||
s += c;
|
||||
}
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
HRESULT CArchiveHeader::Parse(const Byte *p, unsigned size)
|
||||
{
|
||||
if (size < kBlockSizeMin)
|
||||
return S_FALSE;
|
||||
Byte firstHeaderSize = p[0];
|
||||
if (firstHeaderSize > size)
|
||||
return S_FALSE;
|
||||
// ArchiverVersion = p[1];
|
||||
// ExtractVersion = p[2];
|
||||
HostOS = p[3];
|
||||
// Flags = p[4];
|
||||
// SecuryVersion = p[5];
|
||||
if (p[6] != NFileHeader::NFileType::kArchiveHeader)
|
||||
return S_FALSE;
|
||||
// Reserved = p[7];
|
||||
CTime = Get32(p + 8);
|
||||
MTime = Get32(p + 12);
|
||||
ArchiveSize = Get32(p + 16);
|
||||
// SecurityEnvelopeFilePosition = Get32(p + 20);
|
||||
// UInt16 filespecPositionInFilename = Get16(p + 24);
|
||||
// LengthOfSecurityEnvelopeSata = Get16(p + 26);
|
||||
// EncryptionVersion = p[28];
|
||||
// LastChapter = p[29];
|
||||
unsigned pos = firstHeaderSize;
|
||||
unsigned size1 = size - pos;
|
||||
RINOK(ReadString(p + pos, size1, Name));
|
||||
pos += size1;
|
||||
size1 = size - pos;
|
||||
RINOK(ReadString(p + pos, size1, Comment));
|
||||
pos += size1;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
struct CItem
|
||||
{
|
||||
AString Name;
|
||||
AString Comment;
|
||||
|
||||
UInt32 MTime;
|
||||
UInt32 PackSize;
|
||||
UInt32 Size;
|
||||
UInt32 FileCRC;
|
||||
|
||||
Byte Version;
|
||||
Byte ExtractVersion;
|
||||
Byte HostOS;
|
||||
Byte Flags;
|
||||
Byte Method;
|
||||
Byte FileType;
|
||||
|
||||
// UInt16 FilespecPositionInFilename;
|
||||
UInt16 FileAccessMode;
|
||||
// Byte FirstChapter;
|
||||
// Byte LastChapter;
|
||||
|
||||
UInt64 DataPosition;
|
||||
|
||||
bool IsEncrypted() const { return (Flags & NFileHeader::NFlags::kGarbled) != 0; }
|
||||
bool IsDir() const { return (FileType == NFileHeader::NFileType::kDirectory); }
|
||||
UInt32 GetWinAttributes() const
|
||||
{
|
||||
UInt32 winAtrributes;
|
||||
switch(HostOS)
|
||||
{
|
||||
case NFileHeader::NHostOS::kMSDOS:
|
||||
case NFileHeader::NHostOS::kWIN95:
|
||||
winAtrributes = FileAccessMode;
|
||||
break;
|
||||
default:
|
||||
winAtrributes = 0;
|
||||
}
|
||||
if (IsDir())
|
||||
winAtrributes |= FILE_ATTRIBUTE_DIRECTORY;
|
||||
return winAtrributes;
|
||||
}
|
||||
|
||||
HRESULT Parse(const Byte *p, unsigned size);
|
||||
};
|
||||
|
||||
HRESULT CItem::Parse(const Byte *p, unsigned size)
|
||||
{
|
||||
if (size < kBlockSizeMin)
|
||||
return S_FALSE;
|
||||
|
||||
Byte firstHeaderSize = p[0];
|
||||
|
||||
Version = p[1];
|
||||
ExtractVersion = p[2];
|
||||
HostOS = p[3];
|
||||
Flags = p[4];
|
||||
Method = p[5];
|
||||
FileType = p[6];
|
||||
// Reserved = p[7];
|
||||
MTime = Get32(p + 8);
|
||||
PackSize = Get32(p + 12);
|
||||
Size = Get32(p + 16);
|
||||
FileCRC = Get32(p + 20);
|
||||
// FilespecPositionInFilename = Get16(p + 24);
|
||||
FileAccessMode = Get16(p + 26);
|
||||
// FirstChapter = p[28];
|
||||
// FirstChapter = p[29];
|
||||
|
||||
unsigned pos = firstHeaderSize;
|
||||
unsigned size1 = size - pos;
|
||||
RINOK(ReadString(p + pos, size1, Name));
|
||||
pos += size1;
|
||||
size1 = size - pos;
|
||||
RINOK(ReadString(p + pos, size1, Comment));
|
||||
pos += size1;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
struct CInArchiveException
|
||||
{
|
||||
enum CCauseType
|
||||
{
|
||||
kUnexpectedEndOfArchive = 0,
|
||||
kCRCError,
|
||||
kIncorrectArchive,
|
||||
}
|
||||
Cause;
|
||||
CInArchiveException(CCauseType cause): Cause(cause) {};
|
||||
};
|
||||
|
||||
class CInArchive
|
||||
{
|
||||
UInt32 _blockSize;
|
||||
Byte _block[kBlockSizeMax + 4];
|
||||
|
||||
HRESULT ReadBlock(bool &filled);
|
||||
HRESULT ReadSignatureAndBlock(bool &filled);
|
||||
HRESULT SkeepExtendedHeaders();
|
||||
|
||||
HRESULT SafeReadBytes(void *data, UInt32 size);
|
||||
|
||||
public:
|
||||
CArchiveHeader Header;
|
||||
|
||||
IInStream *Stream;
|
||||
IArchiveOpenCallback *Callback;
|
||||
UInt64 NumFiles;
|
||||
UInt64 NumBytes;
|
||||
|
||||
HRESULT Open(const UInt64 *searchHeaderSizeLimit);
|
||||
HRESULT GetNextItem(bool &filled, CItem &item);
|
||||
};
|
||||
|
||||
static inline bool TestMarkerCandidate(const Byte *p, unsigned maxSize)
|
||||
{
|
||||
if (p[0] != NSignature::kSig0 || p[1] != NSignature::kSig1)
|
||||
return false;
|
||||
UInt32 blockSize = Get16(p + 2);
|
||||
p += 4;
|
||||
if (p[6] != NFileHeader::NFileType::kArchiveHeader ||
|
||||
p[0] > blockSize ||
|
||||
maxSize < 2 + 2 + blockSize + 4 ||
|
||||
blockSize < kBlockSizeMin || blockSize > kBlockSizeMax ||
|
||||
p[28] > 8) // EncryptionVersion
|
||||
return false;
|
||||
// return (Get32(p + blockSize) == CrcCalc(p, blockSize));
|
||||
return true;
|
||||
}
|
||||
|
||||
static HRESULT FindAndReadMarker(ISequentialInStream *stream, const UInt64 *searchHeaderSizeLimit, UInt64 &position)
|
||||
{
|
||||
position = 0;
|
||||
|
||||
const int kMarkerSizeMin = 2 + 2 + kBlockSizeMin + 4;
|
||||
const int kMarkerSizeMax = 2 + 2 + kBlockSizeMax + 4;
|
||||
|
||||
CByteBuffer byteBuffer;
|
||||
const UInt32 kBufSize = 1 << 16;
|
||||
byteBuffer.SetCapacity(kBufSize);
|
||||
Byte *buf = byteBuffer;
|
||||
|
||||
size_t processedSize = kMarkerSizeMax;
|
||||
RINOK(ReadStream(stream, buf, &processedSize));
|
||||
if (processedSize < kMarkerSizeMin)
|
||||
return S_FALSE;
|
||||
if (TestMarkerCandidate(buf, (unsigned)processedSize))
|
||||
return S_OK;
|
||||
|
||||
UInt32 numBytesPrev = (UInt32)processedSize - 1;
|
||||
memmove(buf, buf + 1, numBytesPrev);
|
||||
UInt64 curTestPos = 1;
|
||||
for (;;)
|
||||
{
|
||||
if (searchHeaderSizeLimit != NULL)
|
||||
if (curTestPos > *searchHeaderSizeLimit)
|
||||
return S_FALSE;
|
||||
processedSize = kBufSize - numBytesPrev;
|
||||
RINOK(ReadStream(stream, buf + numBytesPrev, &processedSize));
|
||||
UInt32 numBytesInBuffer = numBytesPrev + (UInt32)processedSize;
|
||||
if (numBytesInBuffer < kMarkerSizeMin)
|
||||
return S_FALSE;
|
||||
UInt32 numTests = numBytesInBuffer - kMarkerSizeMin + 1;
|
||||
UInt32 pos;
|
||||
for (pos = 0; pos < numTests; pos++)
|
||||
{
|
||||
for (; buf[pos] != NSignature::kSig0 && pos < numTests; pos++);
|
||||
if (pos == numTests)
|
||||
break;
|
||||
if (TestMarkerCandidate(buf + pos, numBytesInBuffer - pos))
|
||||
{
|
||||
position = curTestPos + pos;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
curTestPos += pos;
|
||||
numBytesPrev = numBytesInBuffer - numTests;
|
||||
memmove(buf, buf + numTests, numBytesPrev);
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT CInArchive::SafeReadBytes(void *data, UInt32 size)
|
||||
{
|
||||
size_t processed = size;
|
||||
RINOK(ReadStream(Stream, data, &processed));
|
||||
if (processed != size)
|
||||
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CInArchive::ReadBlock(bool &filled)
|
||||
{
|
||||
filled = false;
|
||||
Byte buf[2];
|
||||
RINOK(SafeReadBytes(buf, 2));
|
||||
_blockSize = Get16(buf);
|
||||
if (_blockSize == 0)
|
||||
return S_OK;
|
||||
if (_blockSize > kBlockSizeMax)
|
||||
throw CInArchiveException(CInArchiveException::kIncorrectArchive);
|
||||
RINOK(SafeReadBytes(_block, _blockSize + 4));
|
||||
NumBytes += _blockSize + 6;
|
||||
if (Get32(_block + _blockSize) != CrcCalc(_block, _blockSize))
|
||||
throw CInArchiveException(CInArchiveException::kCRCError);
|
||||
filled = true;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CInArchive::ReadSignatureAndBlock(bool &filled)
|
||||
{
|
||||
Byte id[2];
|
||||
RINOK(SafeReadBytes(id, 2));
|
||||
if (id[0] != NSignature::kSig0 || id[1] != NSignature::kSig1)
|
||||
throw CInArchiveException(CInArchiveException::kIncorrectArchive);
|
||||
return ReadBlock(filled);
|
||||
}
|
||||
|
||||
HRESULT CInArchive::SkeepExtendedHeaders()
|
||||
{
|
||||
for (UInt32 i = 0;; i++)
|
||||
{
|
||||
bool filled;
|
||||
RINOK(ReadBlock(filled));
|
||||
if (!filled)
|
||||
return S_OK;
|
||||
if (Callback && (i & 0xFF) == 0)
|
||||
RINOK(Callback->SetCompleted(&NumFiles, &NumBytes));
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT CInArchive::Open(const UInt64 *searchHeaderSizeLimit)
|
||||
{
|
||||
UInt64 position = 0;
|
||||
RINOK(FindAndReadMarker(Stream, searchHeaderSizeLimit, position));
|
||||
RINOK(Stream->Seek(position, STREAM_SEEK_SET, NULL));
|
||||
bool filled;
|
||||
RINOK(ReadSignatureAndBlock(filled));
|
||||
if (!filled)
|
||||
return S_FALSE;
|
||||
RINOK(Header.Parse(_block, _blockSize));
|
||||
return SkeepExtendedHeaders();
|
||||
}
|
||||
|
||||
HRESULT CInArchive::GetNextItem(bool &filled, CItem &item)
|
||||
{
|
||||
RINOK(ReadSignatureAndBlock(filled));
|
||||
if (!filled)
|
||||
return S_OK;
|
||||
filled = false;
|
||||
RINOK(item.Parse(_block, _blockSize));
|
||||
/*
|
||||
UInt32 extraData;
|
||||
if ((header.Flags & NFileHeader::NFlags::kExtFile) != 0)
|
||||
extraData = GetUInt32FromMemLE(_block + pos);
|
||||
*/
|
||||
|
||||
RINOK(SkeepExtendedHeaders());
|
||||
filled = true;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
class CHandler:
|
||||
public IInArchive,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
MY_UNKNOWN_IMP1(IInArchive)
|
||||
|
||||
INTERFACE_IInArchive(;)
|
||||
|
||||
HRESULT Open2(IInStream *inStream, const UInt64 *maxCheckStartPosition,
|
||||
IArchiveOpenCallback *callback);
|
||||
private:
|
||||
CInArchive _archive;
|
||||
CObjectVector<CItem> _items;
|
||||
CMyComPtr<IInStream> _stream;
|
||||
};
|
||||
|
||||
const wchar_t *kHostOS[] =
|
||||
{
|
||||
L"MSDOS",
|
||||
L"PRIMOS",
|
||||
L"UNIX",
|
||||
L"AMIGA",
|
||||
L"MAC",
|
||||
L"OS/2",
|
||||
L"APPLE GS",
|
||||
L"ATARI ST",
|
||||
L"NEXT",
|
||||
L"VAX VMS",
|
||||
L"WIN95"
|
||||
};
|
||||
|
||||
const wchar_t *kUnknownOS = L"Unknown";
|
||||
|
||||
const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]);
|
||||
|
||||
STATPROPSTG kArcProps[] =
|
||||
{
|
||||
{ NULL, kpidName, VT_BSTR},
|
||||
{ NULL, kpidCTime, VT_BSTR},
|
||||
{ NULL, kpidMTime, VT_BSTR},
|
||||
{ NULL, kpidHostOS, VT_BSTR},
|
||||
{ NULL, kpidComment, VT_BSTR}
|
||||
};
|
||||
|
||||
STATPROPSTG kProps[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
{ NULL, kpidIsDir, VT_BOOL},
|
||||
{ NULL, kpidSize, VT_UI8},
|
||||
{ NULL, kpidPackSize, VT_UI8},
|
||||
{ NULL, kpidMTime, VT_FILETIME},
|
||||
{ NULL, kpidAttrib, VT_UI4},
|
||||
{ NULL, kpidEncrypted, VT_BOOL},
|
||||
{ NULL, kpidCRC, VT_UI4},
|
||||
{ NULL, kpidMethod, VT_UI1},
|
||||
{ NULL, kpidHostOS, VT_BSTR},
|
||||
{ NULL, kpidComment, VT_BSTR}
|
||||
};
|
||||
|
||||
IMP_IInArchive_Props
|
||||
IMP_IInArchive_ArcProps
|
||||
|
||||
static void SetTime(UInt32 dosTime, NWindows::NCOM::CPropVariant &prop)
|
||||
{
|
||||
if (dosTime == 0)
|
||||
return;
|
||||
FILETIME localFileTime, utc;
|
||||
if (NTime::DosTimeToFileTime(dosTime, localFileTime))
|
||||
{
|
||||
if (!LocalFileTimeToFileTime(&localFileTime, &utc))
|
||||
utc.dwHighDateTime = utc.dwLowDateTime = 0;
|
||||
}
|
||||
else
|
||||
utc.dwHighDateTime = utc.dwLowDateTime = 0;
|
||||
prop = utc;
|
||||
}
|
||||
|
||||
static void SetHostOS(Byte hostOS, NWindows::NCOM::CPropVariant &prop)
|
||||
{
|
||||
prop = hostOS < kNumHostOSes ? kHostOS[hostOS] : kUnknownOS;
|
||||
}
|
||||
|
||||
static void SetUnicodeString(const AString &s, NWindows::NCOM::CPropVariant &prop)
|
||||
{
|
||||
if (!s.IsEmpty())
|
||||
prop = MultiByteToUnicodeString(s, CP_OEMCP);
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
switch(propID)
|
||||
{
|
||||
case kpidName: SetUnicodeString(_archive.Header.Name, prop); break;
|
||||
case kpidCTime: SetTime(_archive.Header.CTime, prop); break;
|
||||
case kpidMTime: SetTime(_archive.Header.MTime, prop); break;
|
||||
case kpidHostOS: SetHostOS(_archive.Header.HostOS, prop); break;
|
||||
case kpidComment: SetUnicodeString(_archive.Header.Comment, prop); break;
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
{
|
||||
*numItems = _items.Size();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
const CItem &item = _items[index];
|
||||
switch(propID)
|
||||
{
|
||||
case kpidPath: prop = NItemName::GetOSName(MultiByteToUnicodeString(item.Name, CP_OEMCP)); break;
|
||||
case kpidIsDir: prop = item.IsDir(); break;
|
||||
case kpidSize: prop = item.Size; break;
|
||||
case kpidPackSize: prop = item.PackSize; break;
|
||||
case kpidAttrib: prop = item.GetWinAttributes(); break;
|
||||
case kpidEncrypted: prop = item.IsEncrypted(); break;
|
||||
case kpidCRC: prop = item.FileCRC; break;
|
||||
case kpidMethod: prop = item.Method; break;
|
||||
case kpidHostOS: SetHostOS(item.HostOS, prop); break;
|
||||
case kpidMTime: SetTime(item.MTime, prop); break;
|
||||
case kpidComment: SetUnicodeString(item.Comment, prop); break;
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
HRESULT CHandler::Open2(IInStream *inStream, const UInt64 *maxCheckStartPosition,
|
||||
IArchiveOpenCallback *callback)
|
||||
{
|
||||
Close();
|
||||
|
||||
UInt64 endPos = 0;
|
||||
if (callback != NULL)
|
||||
{
|
||||
RINOK(inStream->Seek(0, STREAM_SEEK_END, &endPos));
|
||||
RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
|
||||
}
|
||||
|
||||
_archive.Stream = inStream;
|
||||
_archive.Callback = callback;
|
||||
_archive.NumFiles = _archive.NumBytes = 0;
|
||||
|
||||
RINOK(_archive.Open(maxCheckStartPosition));
|
||||
if (callback != NULL)
|
||||
RINOK(callback->SetTotal(NULL, &endPos));
|
||||
for (;;)
|
||||
{
|
||||
CItem item;
|
||||
bool filled;
|
||||
|
||||
|
||||
RINOK(_archive.GetNextItem(filled, item));
|
||||
|
||||
RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &item.DataPosition));
|
||||
|
||||
if (!filled)
|
||||
break;
|
||||
_items.Add(item);
|
||||
|
||||
if (inStream->Seek(item.PackSize, STREAM_SEEK_CUR, NULL) != S_OK)
|
||||
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
|
||||
|
||||
_archive.NumFiles = _items.Size();
|
||||
_archive.NumBytes = item.DataPosition;
|
||||
|
||||
if (callback != NULL && _items.Size() % 100 == 0)
|
||||
{
|
||||
RINOK(callback->SetCompleted(&_archive.NumFiles, &_archive.NumBytes));
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
HRESULT res;
|
||||
try
|
||||
{
|
||||
res = Open2(inStream, maxCheckStartPosition, callback);
|
||||
if (res == S_OK)
|
||||
{
|
||||
_stream = inStream;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
catch(const CInArchiveException &) { res = S_FALSE; }
|
||||
Close();
|
||||
return res;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Close()
|
||||
{
|
||||
_items.Clear();
|
||||
_stream.Release();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
Int32 testModeSpec, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool testMode = (testModeSpec != 0);
|
||||
UInt64 totalUnpacked = 0, totalPacked = 0;
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
if (allFilesMode)
|
||||
numItems = _items.Size();
|
||||
if (numItems == 0)
|
||||
return S_OK;
|
||||
UInt32 i;
|
||||
for (i = 0; i < numItems; i++)
|
||||
{
|
||||
const CItem &item = _items[allFilesMode ? i : indices[i]];
|
||||
totalUnpacked += item.Size;
|
||||
totalPacked += item.PackSize;
|
||||
}
|
||||
extractCallback->SetTotal(totalUnpacked);
|
||||
|
||||
totalUnpacked = totalPacked = 0;
|
||||
UInt64 curUnpacked, curPacked;
|
||||
|
||||
CMyComPtr<ICompressCoder> arj1Decoder;
|
||||
CMyComPtr<ICompressCoder> arj2Decoder;
|
||||
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
|
||||
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
|
||||
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(extractCallback, false);
|
||||
|
||||
CLimitedSequentialInStream *inStreamSpec = new CLimitedSequentialInStream;
|
||||
CMyComPtr<ISequentialInStream> inStream(inStreamSpec);
|
||||
inStreamSpec->SetStream(_stream);
|
||||
|
||||
for (i = 0; i < numItems; i++, totalUnpacked += curUnpacked, totalPacked += curPacked)
|
||||
{
|
||||
lps->InSize = totalPacked;
|
||||
lps->OutSize = totalUnpacked;
|
||||
RINOK(lps->SetCur());
|
||||
|
||||
curUnpacked = curPacked = 0;
|
||||
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode = testMode ?
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract;
|
||||
Int32 index = allFilesMode ? i : indices[i];
|
||||
const CItem &item = _items[index];
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
|
||||
if (item.IsDir())
|
||||
{
|
||||
// if (!testMode)
|
||||
{
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!testMode && (!realOutStream))
|
||||
continue;
|
||||
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
curUnpacked = item.Size;
|
||||
curPacked = item.PackSize;
|
||||
|
||||
{
|
||||
COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;
|
||||
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
|
||||
outStreamSpec->SetStream(realOutStream);
|
||||
realOutStream.Release();
|
||||
outStreamSpec->Init();
|
||||
|
||||
inStreamSpec->Init(item.PackSize);
|
||||
|
||||
UInt64 pos;
|
||||
_stream->Seek(item.DataPosition, STREAM_SEEK_SET, &pos);
|
||||
|
||||
HRESULT result = S_OK;
|
||||
Int32 opRes = NExtract::NOperationResult::kOK;
|
||||
|
||||
if (item.IsEncrypted())
|
||||
opRes = NExtract::NOperationResult::kUnSupportedMethod;
|
||||
else
|
||||
{
|
||||
switch(item.Method)
|
||||
{
|
||||
case NFileHeader::NCompressionMethod::kStored:
|
||||
{
|
||||
result = copyCoder->Code(inStream, outStream, NULL, NULL, progress);
|
||||
if (result == S_OK && copyCoderSpec->TotalSize != item.PackSize)
|
||||
result = S_FALSE;
|
||||
break;
|
||||
}
|
||||
case NFileHeader::NCompressionMethod::kCompressed1a:
|
||||
case NFileHeader::NCompressionMethod::kCompressed1b:
|
||||
case NFileHeader::NCompressionMethod::kCompressed1c:
|
||||
{
|
||||
if (!arj1Decoder)
|
||||
arj1Decoder = new NCompress::NArj::NDecoder1::CCoder;
|
||||
result = arj1Decoder->Code(inStream, outStream, NULL, &curUnpacked, progress);
|
||||
break;
|
||||
}
|
||||
case NFileHeader::NCompressionMethod::kCompressed2:
|
||||
{
|
||||
if (!arj2Decoder)
|
||||
arj2Decoder = new NCompress::NArj::NDecoder2::CCoder;
|
||||
result = arj2Decoder->Code(inStream, outStream, NULL, &curUnpacked, progress);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
opRes = NExtract::NOperationResult::kUnSupportedMethod;
|
||||
}
|
||||
}
|
||||
if (opRes == NExtract::NOperationResult::kOK)
|
||||
{
|
||||
if (result == S_FALSE)
|
||||
opRes = NExtract::NOperationResult::kDataError;
|
||||
else
|
||||
{
|
||||
RINOK(result);
|
||||
opRes = (outStreamSpec->GetCRC() == item.FileCRC) ?
|
||||
NExtract::NOperationResult::kOK:
|
||||
NExtract::NOperationResult::kCRCError;
|
||||
}
|
||||
}
|
||||
outStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(opRes));
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
static IInArchive *CreateArc() { return new CHandler; }
|
||||
|
||||
static CArcInfo g_ArcInfo =
|
||||
{ L"Arj", L"arj", 0, 4, { 0x60, 0xEA }, 2, false, CreateArc, 0 };
|
||||
|
||||
REGISTER_ARC(Arj)
|
||||
|
||||
}}
|
||||
@@ -21,9 +21,9 @@ namespace NBZip2 {
|
||||
|
||||
static const CMethodId kMethodId_BZip2 = 0x040202;
|
||||
|
||||
STATPROPSTG kProps[] =
|
||||
STATPROPSTG kProps[] =
|
||||
{
|
||||
{ NULL, kpidPackedSize, VT_UI8}
|
||||
{ NULL, kpidPackSize, VT_UI8}
|
||||
};
|
||||
|
||||
IMP_IInArchive_Props
|
||||
@@ -40,13 +40,13 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIA
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
switch(propID)
|
||||
{
|
||||
case kpidPackedSize: prop = _item.PackSize; break;
|
||||
case kpidPackSize: prop = _item.PackSize; break;
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
const UInt64 * /* maxCheckStartPosition */,
|
||||
IArchiveOpenCallback * /* openArchiveCallback */)
|
||||
{
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
namespace NArchive {
|
||||
namespace NBZip2 {
|
||||
|
||||
class CHandler:
|
||||
class CHandler:
|
||||
public IInArchive,
|
||||
public IOutArchive,
|
||||
public ISetProperties,
|
||||
@@ -35,11 +35,11 @@ class CHandler:
|
||||
|
||||
DECL_EXTERNAL_CODECS_VARS
|
||||
|
||||
void InitMethodProperties()
|
||||
{
|
||||
void InitMethodProperties()
|
||||
{
|
||||
_level = 5;
|
||||
_dicSize =
|
||||
_numPasses = 0xFFFFFFFF;
|
||||
_dicSize =
|
||||
_numPasses = 0xFFFFFFFF;
|
||||
#ifdef COMPRESS_MT
|
||||
_numThreads = NWindows::NSystem::GetNumberOfProcessors();;
|
||||
#endif
|
||||
|
||||
@@ -55,7 +55,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
{
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(updateCallback->GetProperty(0, kpidIsFolder, &prop));
|
||||
RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop));
|
||||
if (prop.vt == VT_BOOL)
|
||||
{
|
||||
if (prop.boolVal != VARIANT_FALSE)
|
||||
@@ -79,21 +79,21 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
|
||||
UInt32 dicSize = _dicSize;
|
||||
if (dicSize == 0xFFFFFFFF)
|
||||
dicSize = (_level >= 5 ? kDicSizeX5 :
|
||||
(_level >= 3 ? kDicSizeX3 :
|
||||
dicSize = (_level >= 5 ? kDicSizeX5 :
|
||||
(_level >= 3 ? kDicSizeX3 :
|
||||
kDicSizeX1));
|
||||
|
||||
UInt32 numPasses = _numPasses;
|
||||
if (numPasses == 0xFFFFFFFF)
|
||||
numPasses = (_level >= 9 ? kNumPassesX9 :
|
||||
(_level >= 7 ? kNumPassesX7 :
|
||||
numPasses = (_level >= 9 ? kNumPassesX9 :
|
||||
(_level >= 7 ? kNumPassesX7 :
|
||||
kNumPassesX1));
|
||||
|
||||
return UpdateArchive(
|
||||
EXTERNAL_CODECS_VARS
|
||||
size, outStream, 0, dicSize, numPasses,
|
||||
size, outStream, 0, dicSize, numPasses,
|
||||
#ifdef COMPRESS_MT
|
||||
_numThreads,
|
||||
_numThreads,
|
||||
#endif
|
||||
updateCallback);
|
||||
}
|
||||
@@ -151,6 +151,6 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -47,15 +47,15 @@ HRESULT UpdateArchive(
|
||||
encoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties);
|
||||
if (setCoderProperties)
|
||||
{
|
||||
NWindows::NCOM::CPropVariant properties[] =
|
||||
NWindows::NCOM::CPropVariant properties[] =
|
||||
{
|
||||
dictionary,
|
||||
dictionary,
|
||||
numPasses
|
||||
#ifdef COMPRESS_MT
|
||||
, numThreads
|
||||
#endif
|
||||
};
|
||||
PROPID propIDs[] =
|
||||
PROPID propIDs[] =
|
||||
{
|
||||
NCoderPropID::kDictionarySize,
|
||||
NCoderPropID::kNumPasses
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../../C/Alloc.h"
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public:
|
||||
m_Value ^= ((UInt32)(m_Hist[i])) << (8 * (m_Pos - i - 1));
|
||||
}
|
||||
void UpdateUInt32(UInt32 v) { m_Value ^= v; }
|
||||
UInt32 GetResult() const { return m_Value; }
|
||||
UInt32 GetResult() const { return m_Value; }
|
||||
};
|
||||
|
||||
void CCheckSum2::Update(const void *data, UInt32 size)
|
||||
@@ -65,7 +65,7 @@ void CCheckSum2::Update(const void *data, UInt32 size)
|
||||
|
||||
int numWords = size / 4;
|
||||
|
||||
while (numWords-- != 0)
|
||||
while (numWords-- != 0)
|
||||
{
|
||||
UInt32 temp = *dataPointer++;
|
||||
temp |= ((UInt32)(*dataPointer++)) << 8;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
namespace NArchive {
|
||||
namespace NCab {
|
||||
|
||||
class CCabBlockInStream:
|
||||
class CCabBlockInStream:
|
||||
public ISequentialInStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
|
||||
@@ -31,19 +31,18 @@ namespace NCab {
|
||||
// #define _CAB_DETAILS
|
||||
|
||||
#ifdef _CAB_DETAILS
|
||||
enum
|
||||
enum
|
||||
{
|
||||
kpidBlockReal = kpidUserDefined
|
||||
};
|
||||
#endif
|
||||
|
||||
STATPROPSTG kProps[] =
|
||||
STATPROPSTG kProps[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
// { NULL, kpidIsFolder, VT_BOOL},
|
||||
{ NULL, kpidSize, VT_UI8},
|
||||
{ NULL, kpidLastWriteTime, VT_FILETIME},
|
||||
{ NULL, kpidAttributes, VT_UI4},
|
||||
{ NULL, kpidMTime, VT_FILETIME},
|
||||
{ NULL, kpidAttrib, VT_UI4},
|
||||
{ NULL, kpidMethod, VT_BSTR},
|
||||
{ NULL, kpidBlock, VT_I4}
|
||||
#ifdef _CAB_DETAILS
|
||||
@@ -54,7 +53,7 @@ STATPROPSTG kProps[] =
|
||||
#endif
|
||||
};
|
||||
|
||||
static const wchar_t *kMethods[] =
|
||||
static const wchar_t *kMethods[] =
|
||||
{
|
||||
L"None",
|
||||
L"MSZip",
|
||||
@@ -65,7 +64,7 @@ static const wchar_t *kMethods[] =
|
||||
static const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]);
|
||||
static const wchar_t *kUnknownMethod = L"Unknown";
|
||||
|
||||
STATPROPSTG kArcProps[] =
|
||||
STATPROPSTG kArcProps[] =
|
||||
{
|
||||
{ NULL, kpidMethod, VT_BSTR},
|
||||
// { NULL, kpidSolid, VT_BOOL},
|
||||
@@ -101,7 +100,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
resString += L' ';
|
||||
resString += method;
|
||||
}
|
||||
prop = resString;
|
||||
prop = resString;
|
||||
break;
|
||||
}
|
||||
// case kpidSolid: prop = _database.IsSolid(); break;
|
||||
@@ -145,13 +144,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
||||
prop = (const wchar_t *)NItemName::WinNameToOSName(unicodeName);
|
||||
break;
|
||||
}
|
||||
case kpidIsFolder:
|
||||
prop = item.IsDirectory();
|
||||
break;
|
||||
case kpidSize:
|
||||
prop = item.Size;
|
||||
break;
|
||||
case kpidLastWriteTime:
|
||||
case kpidIsDir: prop = item.IsDir(); break;
|
||||
case kpidSize: prop = item.Size; break;
|
||||
case kpidAttrib: prop = item.GetWinAttributes(); break;
|
||||
|
||||
case kpidMTime:
|
||||
{
|
||||
FILETIME localFileTime, utcFileTime;
|
||||
if (NTime::DosTimeToFileTime(item.Time, localFileTime))
|
||||
@@ -164,9 +161,6 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
||||
prop = utcFileTime;
|
||||
break;
|
||||
}
|
||||
case kpidAttributes:
|
||||
prop = item.GetWinAttributes();
|
||||
break;
|
||||
|
||||
case kpidMethod:
|
||||
{
|
||||
@@ -174,7 +168,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
||||
const CFolder &folder = db.Folders[realFolderIndex];
|
||||
int methodIndex = folder.GetCompressionMethod();
|
||||
UString method = (methodIndex < kNumMethods) ? kMethods[methodIndex] : kUnknownMethod;
|
||||
if (methodIndex == NHeader::NCompressionMethodMajor::kLZX ||
|
||||
if (methodIndex == NHeader::NCompressionMethodMajor::kLZX ||
|
||||
methodIndex == NHeader::NCompressionMethodMajor::kQuantum)
|
||||
{
|
||||
method += L":";
|
||||
@@ -185,21 +179,13 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
||||
prop = method;
|
||||
break;
|
||||
}
|
||||
case kpidBlock:
|
||||
prop = (Int32)m_Database.GetFolderIndex(&mvItem);
|
||||
break;
|
||||
case kpidBlock: prop = (Int32)m_Database.GetFolderIndex(&mvItem); break;
|
||||
|
||||
#ifdef _CAB_DETAILS
|
||||
|
||||
case kpidBlockReal:
|
||||
prop = UInt32(item.FolderIndex);
|
||||
break;
|
||||
case kpidOffset:
|
||||
prop = (UInt32)item.Offset;
|
||||
break;
|
||||
case kpidVolume:
|
||||
prop = (UInt32)mvItem.VolumeIndex;
|
||||
break;
|
||||
case kpidBlockReal: prop = (UInt32)item.FolderIndex; break;
|
||||
case kpidOffset: prop = (UInt32)item.Offset; break;
|
||||
case kpidVolume: prop = (UInt32)mvItem.VolumeIndex; break;
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -209,7 +195,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
||||
}
|
||||
|
||||
/*
|
||||
class CPropgressImp: public CProgressVirt
|
||||
class CProgressImp: public CProgressVirt
|
||||
{
|
||||
CMyComPtr<IArchiveOpenCallback> m_OpenArchiveCallback;
|
||||
public:
|
||||
@@ -219,14 +205,14 @@ public:
|
||||
{ m_OpenArchiveCallback = openArchiveCallback; }
|
||||
};
|
||||
|
||||
STDMETHODIMP CPropgressImp::SetTotal(const UInt64 *numFiles)
|
||||
STDMETHODIMP CProgressImp::SetTotal(const UInt64 *numFiles)
|
||||
{
|
||||
if (m_OpenArchiveCallback)
|
||||
return m_OpenArchiveCallback->SetCompleted(numFiles, NULL);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles)
|
||||
STDMETHODIMP CProgressImp::SetCompleted(const UInt64 *numFiles)
|
||||
{
|
||||
if (m_OpenArchiveCallback)
|
||||
return m_OpenArchiveCallback->SetCompleted(numFiles, NULL);
|
||||
@@ -234,9 +220,9 @@ STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles)
|
||||
}
|
||||
*/
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
const UInt64 *maxCheckStartPosition,
|
||||
IArchiveOpenCallback *openArchiveCallback)
|
||||
IArchiveOpenCallback *callback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
Close();
|
||||
@@ -244,7 +230,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
CInArchive archive;
|
||||
CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
|
||||
{
|
||||
CMyComPtr<IArchiveOpenCallback> openArchiveCallbackWrap = openArchiveCallback;
|
||||
CMyComPtr<IArchiveOpenCallback> openArchiveCallbackWrap = callback;
|
||||
openArchiveCallbackWrap.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback);
|
||||
}
|
||||
|
||||
@@ -264,7 +250,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
{
|
||||
const CDatabaseEx &dbPrev = m_Database.Volumes[prevChecked ? m_Database.Volumes.Size() - 1 : 0];
|
||||
if (dbPrev.ArchiveInfo.SetID != db.ArchiveInfo.SetID ||
|
||||
dbPrev.ArchiveInfo.CabinetNumber + (prevChecked ? 1: - 1) !=
|
||||
dbPrev.ArchiveInfo.CabinetNumber + (prevChecked ? 1: - 1) !=
|
||||
db.ArchiveInfo.CabinetNumber)
|
||||
res = S_FALSE;
|
||||
}
|
||||
@@ -273,7 +259,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
m_Database.Volumes.Insert(prevChecked ? m_Database.Volumes.Size() : 0, db);
|
||||
else if (res != S_FALSE)
|
||||
return res;
|
||||
else
|
||||
else
|
||||
{
|
||||
if (m_Database.Volumes.IsEmpty())
|
||||
return S_FALSE;
|
||||
@@ -283,7 +269,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
}
|
||||
|
||||
numItems += db.Items.Size();
|
||||
RINOK(openArchiveCallback->SetCompleted(&numItems, NULL));
|
||||
RINOK(callback->SetCompleted(&numItems, NULL));
|
||||
|
||||
nextStream = 0;
|
||||
for (;;)
|
||||
@@ -342,7 +328,7 @@ STDMETHODIMP CHandler::Close()
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
class CCabFolderOutStream:
|
||||
class CCabFolderOutStream:
|
||||
public ISequentialOutStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
@@ -373,8 +359,8 @@ public:
|
||||
|
||||
void Init(
|
||||
const CMvDatabaseEx *database,
|
||||
const CRecordVector<bool> *extractStatuses,
|
||||
int startIndex,
|
||||
const CRecordVector<bool> *extractStatuses,
|
||||
int startIndex,
|
||||
UInt64 folderSize,
|
||||
IArchiveExtractCallback *extractCallback,
|
||||
bool testMode);
|
||||
@@ -387,8 +373,8 @@ public:
|
||||
|
||||
void CCabFolderOutStream::Init(
|
||||
const CMvDatabaseEx *database,
|
||||
const CRecordVector<bool> *extractStatuses,
|
||||
int startIndex,
|
||||
const CRecordVector<bool> *extractStatuses,
|
||||
int startIndex,
|
||||
UInt64 folderSize,
|
||||
IArchiveExtractCallback *extractCallback,
|
||||
bool testMode)
|
||||
@@ -409,7 +395,7 @@ void CCabFolderOutStream::Init(
|
||||
|
||||
HRESULT CCabFolderOutStream::OpenFile()
|
||||
{
|
||||
Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? (m_TestMode ?
|
||||
Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? (m_TestMode ?
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract) :
|
||||
NExtract::NAskMode::kSkip;
|
||||
@@ -474,7 +460,7 @@ HRESULT CCabFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *proce
|
||||
{
|
||||
m_RealOutStream.Release();
|
||||
RINOK(m_ExtractCallback->SetOperationResult(
|
||||
m_IsOk ?
|
||||
m_IsOk ?
|
||||
NArchive::NExtract::NOperationResult::kOK:
|
||||
NArchive::NExtract::NOperationResult::kDataError));
|
||||
m_FileIsOpen = false;
|
||||
@@ -574,7 +560,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
int index = allFilesMode ? i : indices[i];
|
||||
const CMvItem &mvItem = m_Database.Items[index];
|
||||
const CItem &item = m_Database.Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
|
||||
if (item.IsDirectory())
|
||||
if (item.IsDir())
|
||||
continue;
|
||||
int folderIndex = m_Database.GetFolderIndex(&mvItem);
|
||||
if (folderIndex != lastFolder)
|
||||
@@ -622,9 +608,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
const CItem &item = db.Items[itemIndex];
|
||||
|
||||
i++;
|
||||
if (item.IsDirectory())
|
||||
if (item.IsDir())
|
||||
{
|
||||
Int32 askMode= testMode ?
|
||||
Int32 askMode= testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
@@ -638,7 +624,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
if (folderIndex < 0)
|
||||
{
|
||||
// If we need previous archive
|
||||
Int32 askMode= testMode ?
|
||||
Int32 askMode= testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
@@ -661,7 +647,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
int indexNext = allFilesMode ? i : indices[i];
|
||||
const CMvItem &mvItem = m_Database.Items[indexNext];
|
||||
const CItem &item = m_Database.Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
|
||||
if (item.IsDirectory())
|
||||
if (item.IsDir())
|
||||
continue;
|
||||
int newFolderIndex = m_Database.GetFolderIndex(&mvItem);
|
||||
|
||||
@@ -683,7 +669,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
|
||||
const CFolder &folder = db.Folders[item.GetFolderIndex(db.Folders.Size())];
|
||||
|
||||
cabFolderOutStream->Init(&m_Database, &extractStatuses, startIndex2,
|
||||
cabFolderOutStream->Init(&m_Database, &extractStatuses, startIndex2,
|
||||
curUnpack, extractCallback, testMode);
|
||||
|
||||
cabBlockInStreamSpec->MsZip = false;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
namespace NArchive {
|
||||
namespace NCab {
|
||||
|
||||
class CHandler:
|
||||
class CHandler:
|
||||
public IInArchive,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
|
||||
@@ -8,12 +8,8 @@ namespace NArchive{
|
||||
namespace NCab{
|
||||
namespace NHeader{
|
||||
|
||||
namespace NArchive {
|
||||
Byte kMarker[kMarkerSize] = {'M' + 1, 'S', 'C', 'F', 0, 0, 0, 0 };
|
||||
|
||||
UInt32 kSignature = 0x4643534d + 1;
|
||||
static class CSignatureInitializer
|
||||
{ public: CSignatureInitializer() { kSignature--; }} g_SignatureInitializer;
|
||||
|
||||
}
|
||||
struct SignatureInitializer { SignatureInitializer() { kMarker[0]--; }; } g_SignatureInitializer;
|
||||
|
||||
}}}
|
||||
|
||||
@@ -7,11 +7,13 @@
|
||||
|
||||
namespace NArchive {
|
||||
namespace NCab {
|
||||
namespace NHeader{
|
||||
namespace NHeader {
|
||||
|
||||
namespace NArchive
|
||||
const unsigned kMarkerSize = 8;
|
||||
extern Byte kMarker[kMarkerSize];
|
||||
|
||||
namespace NArchive
|
||||
{
|
||||
extern UInt32 kSignature;
|
||||
namespace NFlags
|
||||
{
|
||||
const int kPrevCabinet = 0x0001;
|
||||
|
||||
@@ -2,15 +2,12 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/StringConvert.h"
|
||||
#include "Common/MyCom.h"
|
||||
#include "CabIn.h"
|
||||
#include "Windows/Defs.h"
|
||||
|
||||
#include "../../Common/StreamUtils.h"
|
||||
#include "../Common/FindSignature.h"
|
||||
|
||||
namespace NArchive{
|
||||
namespace NCab{
|
||||
namespace NArchive {
|
||||
namespace NCab {
|
||||
|
||||
/*
|
||||
static HRESULT ReadBytes(IInStream *inStream, void *data, UInt32 size)
|
||||
@@ -94,39 +91,21 @@ void CInArchive::Skeep(size_t size)
|
||||
ReadByte();
|
||||
}
|
||||
|
||||
HRESULT CInArchive::Open2(IInStream *inStream,
|
||||
HRESULT CInArchive::Open2(IInStream *stream,
|
||||
const UInt64 *searchHeaderSizeLimit,
|
||||
CDatabase &database)
|
||||
{
|
||||
database.Clear();
|
||||
RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &database.StartPosition));
|
||||
RINOK(stream->Seek(0, STREAM_SEEK_SET, &database.StartPosition));
|
||||
|
||||
{
|
||||
if (!inBuffer.Create(1 << 17))
|
||||
return E_OUTOFMEMORY;
|
||||
inBuffer.SetStream(inStream);
|
||||
inBuffer.Init();
|
||||
UInt64 value = 0;
|
||||
const int kSignatureSize = 8;
|
||||
UInt64 kSignature64 = NHeader::NArchive::kSignature;
|
||||
for (;;)
|
||||
{
|
||||
Byte b;
|
||||
if (!inBuffer.ReadByte(b))
|
||||
return S_FALSE;
|
||||
value >>= 8;
|
||||
value |= ((UInt64)b) << ((kSignatureSize - 1) * 8);
|
||||
if (inBuffer.GetProcessedSize() >= kSignatureSize)
|
||||
{
|
||||
if (value == kSignature64)
|
||||
break;
|
||||
if (searchHeaderSizeLimit != NULL)
|
||||
if (inBuffer.GetProcessedSize() > (*searchHeaderSizeLimit))
|
||||
return S_FALSE;
|
||||
}
|
||||
}
|
||||
database.StartPosition += inBuffer.GetProcessedSize() - kSignatureSize;
|
||||
}
|
||||
RINOK(FindSignatureInStream(stream, NHeader::kMarker, NHeader::kMarkerSize,
|
||||
searchHeaderSizeLimit, database.StartPosition));
|
||||
|
||||
RINOK(stream->Seek(database.StartPosition + NHeader::kMarkerSize, STREAM_SEEK_SET, NULL));
|
||||
if (!inBuffer.Create(1 << 17))
|
||||
return E_OUTOFMEMORY;
|
||||
inBuffer.SetStream(stream);
|
||||
inBuffer.Init();
|
||||
|
||||
CInArchiveInfo &archiveInfo = database.ArchiveInfo;
|
||||
|
||||
@@ -141,7 +120,9 @@ HRESULT CInArchive::Open2(IInStream *inStream,
|
||||
archiveInfo.VersionMajor = ReadByte(); // cabinet file format version, major
|
||||
archiveInfo.NumFolders = ReadUInt16(); // number of CFFOLDER entries in this cabinet
|
||||
archiveInfo.NumFiles = ReadUInt16(); // number of CFFILE entries in this cabinet
|
||||
archiveInfo.Flags = ReadUInt16(); // number of CFFILE entries in this cabinet
|
||||
archiveInfo.Flags = ReadUInt16();
|
||||
if (archiveInfo.Flags > 7)
|
||||
return S_FALSE;
|
||||
archiveInfo.SetID = ReadUInt16(); // must be the same for all cabinets in a set
|
||||
archiveInfo.CabinetNumber = ReadUInt16(); // number of this cabinet file in a set
|
||||
|
||||
@@ -175,9 +156,9 @@ HRESULT CInArchive::Open2(IInStream *inStream,
|
||||
database.Folders.Add(folder);
|
||||
}
|
||||
|
||||
RINOK(inStream->Seek(database.StartPosition + archiveInfo.FileHeadersOffset, STREAM_SEEK_SET, NULL));
|
||||
RINOK(stream->Seek(database.StartPosition + archiveInfo.FileHeadersOffset, STREAM_SEEK_SET, NULL));
|
||||
|
||||
inBuffer.SetStream(inStream);
|
||||
inBuffer.SetStream(stream);
|
||||
inBuffer.Init();
|
||||
for(i = 0; i < archiveInfo.NumFiles; i++)
|
||||
{
|
||||
@@ -221,8 +202,8 @@ static int CompareMvItems(const CMvItem *p1, const CMvItem *p2, void *param)
|
||||
const CDatabaseEx &db2 = mvDb.Volumes[p2->VolumeIndex];
|
||||
const CItem &item1 = db1.Items[p1->ItemIndex];
|
||||
const CItem &item2 = db2.Items[p2->ItemIndex];;
|
||||
bool isDir1 = item1.IsDirectory();
|
||||
bool isDir2 = item2.IsDirectory();
|
||||
bool isDir1 = item1.IsDir();
|
||||
bool isDir2 = item2.IsDir();
|
||||
if (isDir1 && !isDir2)
|
||||
return -1;
|
||||
if (isDir2 && !isDir1)
|
||||
@@ -322,7 +303,7 @@ bool CMvDatabaseEx::Check()
|
||||
if (fIndex >= FolderStartFileIndex.Size())
|
||||
return false;
|
||||
const CItem &item = Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
|
||||
if (item.IsDirectory())
|
||||
if (item.IsDir())
|
||||
continue;
|
||||
int folderIndex = GetFolderIndex(&mvItem);
|
||||
if (folderIndex != prevFolder)
|
||||
|
||||
@@ -93,7 +93,7 @@ public:
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
int GetNumberOfNewFolders() const
|
||||
int GetNumberOfNewFolders() const
|
||||
{
|
||||
int res = Folders.Size();
|
||||
if (IsTherePrevFolder())
|
||||
@@ -124,10 +124,10 @@ public:
|
||||
CRecordVector<CMvItem> Items;
|
||||
CRecordVector<int> StartFolderOfVol;
|
||||
CRecordVector<int> FolderStartFileIndex;
|
||||
int GetFolderIndex(const CMvItem *mvi) const
|
||||
int GetFolderIndex(const CMvItem *mvi) const
|
||||
{
|
||||
const CDatabaseEx &db = Volumes[mvi->VolumeIndex];
|
||||
return StartFolderOfVol[mvi->VolumeIndex] +
|
||||
return StartFolderOfVol[mvi->VolumeIndex] +
|
||||
db.Items[mvi->ItemIndex].GetFolderIndex(db.Folders.Size());
|
||||
}
|
||||
void Clear()
|
||||
@@ -152,7 +152,7 @@ class CInArchive
|
||||
void Skeep(size_t size);
|
||||
void ReadOtherArchive(COtherArchive &oa);
|
||||
|
||||
HRESULT Open2(IInStream *inStream,
|
||||
HRESULT Open2(IInStream *inStream,
|
||||
const UInt64 *searchHeaderSizeLimit,
|
||||
CDatabase &database);
|
||||
public:
|
||||
|
||||
@@ -19,9 +19,8 @@ struct CFolder
|
||||
Byte GetCompressionMethod() const { return (Byte)(CompressionTypeMajor & 0xF); }
|
||||
};
|
||||
|
||||
class CItem
|
||||
struct CItem
|
||||
{
|
||||
public:
|
||||
AString Name;
|
||||
UInt32 Offset;
|
||||
UInt32 Size;
|
||||
@@ -29,26 +28,28 @@ public:
|
||||
UInt16 FolderIndex;
|
||||
UInt16 Flags;
|
||||
UInt16 Attributes;
|
||||
|
||||
UInt64 GetEndOffset() const { return (UInt64)Offset + Size; }
|
||||
UInt32 GetWinAttributes() const { return (Attributes & ~NHeader::kFileNameIsUTFAttributeMask); }
|
||||
bool IsNameUTF() const { return (Attributes & NHeader::kFileNameIsUTFAttributeMask) != 0; }
|
||||
bool IsDirectory() const { return (Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; }
|
||||
bool IsDir() const { return (Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; }
|
||||
|
||||
bool ContinuedFromPrev() const
|
||||
{
|
||||
return
|
||||
bool ContinuedFromPrev() const
|
||||
{
|
||||
return
|
||||
(FolderIndex == NHeader::NFolderIndex::kContinuedFromPrev) ||
|
||||
(FolderIndex == NHeader::NFolderIndex::kContinuedPrevAndNext);
|
||||
}
|
||||
bool ContinuedToNext() const
|
||||
{
|
||||
return
|
||||
|
||||
bool ContinuedToNext() const
|
||||
{
|
||||
return
|
||||
(FolderIndex == NHeader::NFolderIndex::kContinuedToNext) ||
|
||||
(FolderIndex == NHeader::NFolderIndex::kContinuedPrevAndNext);
|
||||
}
|
||||
|
||||
int GetFolderIndex(int numFolders) const
|
||||
{
|
||||
int GetFolderIndex(int numFolders) const
|
||||
{
|
||||
if (ContinuedFromPrev())
|
||||
return 0;
|
||||
if (ContinuedToNext())
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
@@ -32,17 +32,16 @@ namespace NChm {
|
||||
|
||||
#ifdef _CHM_DETAILS
|
||||
|
||||
enum
|
||||
enum
|
||||
{
|
||||
kpidSection = kpidUserDefined
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
STATPROPSTG kProps[] =
|
||||
STATPROPSTG kProps[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
// { NULL, kpidIsFolder, VT_BOOL},
|
||||
{ NULL, kpidSize, VT_UI8},
|
||||
{ NULL, kpidMethod, VT_BSTR},
|
||||
{ NULL, kpidBlock, VT_UI4}
|
||||
@@ -54,7 +53,7 @@ STATPROPSTG kProps[] =
|
||||
#endif
|
||||
};
|
||||
|
||||
STATPROPSTG kArcProps[] =
|
||||
STATPROPSTG kArcProps[] =
|
||||
{
|
||||
{ NULL, kpidNumBlocks, VT_UI8}
|
||||
};
|
||||
@@ -71,7 +70,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
switch(propID)
|
||||
{
|
||||
case kpidNumBlocks:
|
||||
case kpidNumBlocks:
|
||||
{
|
||||
UInt64 numBlocks = 0;
|
||||
for (int i = 0; i < m_Database.Sections.Size(); i++)
|
||||
@@ -84,7 +83,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
numBlocks += m.LzxInfo.ResetTable.GetNumBlocks();
|
||||
}
|
||||
}
|
||||
prop = numBlocks;
|
||||
prop = numBlocks;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -132,15 +131,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kpidIsFolder:
|
||||
prop = item.IsDirectory();
|
||||
break;
|
||||
case kpidSize:
|
||||
prop = item.Size;
|
||||
break;
|
||||
case kpidIsDir: prop = item.IsDir(); break;
|
||||
case kpidSize: prop = item.Size; break;
|
||||
case kpidMethod:
|
||||
{
|
||||
if (!item.IsDirectory())
|
||||
if (!item.IsDir())
|
||||
if (item.Section == 0)
|
||||
prop = L"Copy";
|
||||
else if (item.Section < m_Database.Sections.Size())
|
||||
@@ -156,12 +151,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
||||
|
||||
#ifdef _CHM_DETAILS
|
||||
|
||||
case kpidSection:
|
||||
prop = (UInt32)item.Section;
|
||||
break;
|
||||
case kpidOffset:
|
||||
prop = (UInt32)item.Offset;
|
||||
break;
|
||||
case kpidSection: prop = (UInt32)item.Section; break;
|
||||
case kpidOffset: prop = (UInt32)item.Offset; break;
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -170,41 +161,39 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
class CPropgressImp: public CProgressVirt
|
||||
class CProgressImp: public CProgressVirt
|
||||
{
|
||||
CMyComPtr<IArchiveOpenCallback> m_OpenArchiveCallback;
|
||||
CMyComPtr<IArchiveOpenCallback> _callback;
|
||||
public:
|
||||
STDMETHOD(SetTotal)(const UInt64 *numFiles);
|
||||
STDMETHOD(SetCompleted)(const UInt64 *numFiles);
|
||||
void Init(IArchiveOpenCallback *openArchiveCallback)
|
||||
{ m_OpenArchiveCallback = openArchiveCallback; }
|
||||
CProgressImp(IArchiveOpenCallback *callback): _callback(callback) {};
|
||||
};
|
||||
|
||||
STDMETHODIMP CPropgressImp::SetTotal(const UInt64 *numFiles)
|
||||
STDMETHODIMP CProgressImp::SetTotal(const UInt64 *numFiles)
|
||||
{
|
||||
if (m_OpenArchiveCallback)
|
||||
return m_OpenArchiveCallback->SetCompleted(numFiles, NULL);
|
||||
if (_callback)
|
||||
return _callback->SetCompleted(numFiles, NULL);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles)
|
||||
STDMETHODIMP CProgressImp::SetCompleted(const UInt64 *numFiles)
|
||||
{
|
||||
if (m_OpenArchiveCallback)
|
||||
return m_OpenArchiveCallback->SetCompleted(numFiles, NULL);
|
||||
if (_callback)
|
||||
return _callback->SetCompleted(numFiles, NULL);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
const UInt64 *maxCheckStartPosition,
|
||||
IArchiveOpenCallback *openArchiveCallback)
|
||||
IArchiveOpenCallback * /* openArchiveCallback */)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
m_Stream.Release();
|
||||
try
|
||||
{
|
||||
CInArchive archive;
|
||||
CPropgressImp progressImp;
|
||||
progressImp.Init(openArchiveCallback);
|
||||
// CProgressImp progressImp(openArchiveCallback);
|
||||
RINOK(archive.Open(inStream, maxCheckStartPosition, m_Database));
|
||||
/*
|
||||
if (m_Database.LowLevel)
|
||||
@@ -227,7 +216,7 @@ STDMETHODIMP CHandler::Close()
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
class CChmFolderOutStream:
|
||||
class CChmFolderOutStream:
|
||||
public ISequentialOutStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
@@ -280,7 +269,7 @@ void CChmFolderOutStream::Init(
|
||||
|
||||
HRESULT CChmFolderOutStream::OpenFile()
|
||||
{
|
||||
Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? (m_TestMode ?
|
||||
Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? (m_TestMode ?
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract) :
|
||||
NExtract::NAskMode::kSkip;
|
||||
@@ -345,7 +334,7 @@ HRESULT CChmFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *proce
|
||||
{
|
||||
m_RealOutStream.Release();
|
||||
RINOK(m_ExtractCallback->SetOperationResult(
|
||||
m_IsOk ?
|
||||
m_IsOk ?
|
||||
NArchive::NExtract::NOperationResult::kOK:
|
||||
NArchive::NExtract::NOperationResult::kDataError));
|
||||
m_FileIsOpen = false;
|
||||
@@ -356,7 +345,7 @@ HRESULT CChmFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *proce
|
||||
else
|
||||
{
|
||||
if (m_CurrentIndex >= m_NumFiles)
|
||||
return E_FAIL;
|
||||
return E_FAIL;
|
||||
int fullIndex = m_StartIndex + m_CurrentIndex;
|
||||
m_RemainFileSize = m_Database->GetFileSize(fullIndex);
|
||||
UInt64 fileOffset = m_Database->GetFileOffset(fullIndex);
|
||||
@@ -458,7 +447,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
|
||||
RINOK(lps->SetCur());
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode= testMode ?
|
||||
Int32 askMode= testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
Int32 index = allFilesMode ? i : indices[i];
|
||||
@@ -502,7 +491,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
|
||||
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ?
|
||||
RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ?
|
||||
NArchive::NExtract::NOperationResult::kOK:
|
||||
NArchive::NExtract::NOperationResult::kDataError));
|
||||
}
|
||||
@@ -516,7 +505,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
int entryIndex = m_Database.Indices[index];
|
||||
const CItem &item = m_Database.Items[entryIndex];
|
||||
UInt64 sectionIndex = item.Section;
|
||||
if (item.IsDirectory() || item.Size == 0)
|
||||
if (item.IsDir() || item.Size == 0)
|
||||
continue;
|
||||
if (sectionIndex == 0)
|
||||
{
|
||||
@@ -554,10 +543,10 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
int entryIndex = m_Database.Indices[index];
|
||||
const CItem &item = m_Database.Items[entryIndex];
|
||||
UInt64 sectionIndex = item.Section;
|
||||
Int32 askMode= testMode ?
|
||||
Int32 askMode= testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
if (item.IsDirectory())
|
||||
if (item.IsDir())
|
||||
{
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
namespace NArchive {
|
||||
namespace NChm {
|
||||
|
||||
class CHandler:
|
||||
class CHandler:
|
||||
public IInArchive,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
|
||||
@@ -11,11 +11,11 @@ namespace NHeader{
|
||||
UInt32 kItsfSignature = 0x46535449 + 1;
|
||||
UInt32 kItolSignature = 0x4C4F5449 + 1;
|
||||
static class CSignatureInitializer
|
||||
{
|
||||
public:
|
||||
{
|
||||
public:
|
||||
CSignatureInitializer()
|
||||
{
|
||||
kItsfSignature--;
|
||||
{
|
||||
kItsfSignature--;
|
||||
kItolSignature--;
|
||||
}
|
||||
}g_SignatureInitializer;
|
||||
|
||||
@@ -17,16 +17,16 @@ namespace NChm{
|
||||
// define CHM_LOW, if you want to see low level items
|
||||
// #define CHM_LOW
|
||||
|
||||
static const GUID kChmLzxGuid =
|
||||
static const GUID kChmLzxGuid =
|
||||
{ 0x7FC28940, 0x9D31, 0x11D0, 0x9B, 0x27, 0x00, 0xA0, 0xC9, 0x1E, 0x9C, 0x7C };
|
||||
static const GUID kHelp2LzxGuid =
|
||||
static const GUID kHelp2LzxGuid =
|
||||
{ 0x0A9007C6, 0x4076, 0x11D3, 0x87, 0x89, 0x00, 0x00, 0xF8, 0x10, 0x57, 0x54 };
|
||||
static const GUID kDesGuid =
|
||||
static const GUID kDesGuid =
|
||||
{ 0x67F6E4A2, 0x60BF, 0x11D3, 0x85, 0x40, 0x00, 0xC0, 0x4F, 0x58, 0xC3, 0xCF };
|
||||
|
||||
static bool AreGuidsEqual(REFGUID g1, REFGUID g2)
|
||||
{
|
||||
if (g1.Data1 != g2.Data1 ||
|
||||
{
|
||||
if (g1.Data1 != g2.Data1 ||
|
||||
g1.Data2 != g2.Data2 ||
|
||||
g1.Data3 != g2.Data3)
|
||||
return false;
|
||||
@@ -60,7 +60,7 @@ static void PrintUInt32(UInt32 v, AString &s)
|
||||
}
|
||||
|
||||
AString CMethodInfo::GetGuidString() const
|
||||
{
|
||||
{
|
||||
AString s;
|
||||
s += '{';
|
||||
PrintUInt32(Guid.Data1, s);
|
||||
@@ -278,9 +278,9 @@ HRESULT CInArchive::OpenChm(IInStream *inStream, CDatabase &database)
|
||||
if (unknown1 != 0 && unknown1 != 1) // it's 0 in one .sll file
|
||||
return S_FALSE;
|
||||
/* UInt32 timeStamp = */ ReadUInt32();
|
||||
// Considered as a big-endian DWORD, it appears to contain seconds (MSB) and
|
||||
// fractional seconds (second byte).
|
||||
// The third and fourth bytes may contain even more fractional bits.
|
||||
// Considered as a big-endian DWORD, it appears to contain seconds (MSB) and
|
||||
// fractional seconds (second byte).
|
||||
// The third and fourth bytes may contain even more fractional bits.
|
||||
// The 4 least significant bits in the last byte are constant.
|
||||
/* UInt32 lang = */ ReadUInt32();
|
||||
GUID g;
|
||||
@@ -326,12 +326,12 @@ HRESULT CInArchive::OpenChm(IInStream *inStream, CDatabase &database)
|
||||
if (dirChunkSize < 32)
|
||||
return S_FALSE;
|
||||
/* UInt32 density = */ ReadUInt32(); // "Density" of quickref section, usually 2.
|
||||
/* UInt32 depth = */ ReadUInt32(); // Depth of the index tree: 1 there is no index,
|
||||
/* UInt32 depth = */ ReadUInt32(); // Depth of the index tree: 1 there is no index,
|
||||
// 2 if there is one level of PMGI chunks.
|
||||
|
||||
/* UInt32 chunkNumber = */ ReadUInt32(); // Chunk number of root index chunk, -1 if there is none
|
||||
// (though at least one file has 0 despite there being no
|
||||
// index chunk, probably a bug.)
|
||||
// (though at least one file has 0 despite there being no
|
||||
// index chunk, probably a bug.)
|
||||
/* UInt32 firstPmglChunkNumber = */ ReadUInt32(); // Chunk number of first PMGL (listing) chunk
|
||||
/* UInt32 lastPmglChunkNumber = */ ReadUInt32(); // Chunk number of last PMGL (listing) chunk
|
||||
ReadUInt32(); // -1 (unknown)
|
||||
@@ -348,11 +348,11 @@ HRESULT CInArchive::OpenChm(IInStream *inStream, CDatabase &database)
|
||||
UInt64 chunkPos = _inBuffer.GetProcessedSize();
|
||||
if (ReadUInt32() == NHeader::kPmglSignature)
|
||||
{
|
||||
// The quickref area is written backwards from the end of the chunk.
|
||||
// One quickref entry exists for every n entries in the file, where n
|
||||
// is calculated as 1 + (1 << quickref density). So for density = 2, n = 5.
|
||||
// The quickref area is written backwards from the end of the chunk.
|
||||
// One quickref entry exists for every n entries in the file, where n
|
||||
// is calculated as 1 + (1 << quickref density). So for density = 2, n = 5.
|
||||
|
||||
UInt32 quickrefLength = ReadUInt32(); // Length of free space and/or quickref area at end of directory chunk
|
||||
UInt32 quickrefLength = ReadUInt32(); // Length of free space and/or quickref area at end of directory chunk
|
||||
if (quickrefLength > dirChunkSize || quickrefLength < 2)
|
||||
return S_FALSE;
|
||||
ReadUInt32(); // Always 0
|
||||
@@ -393,10 +393,10 @@ HRESULT CInArchive::OpenHelp2(IInStream *inStream, CDatabase &database)
|
||||
if (numHeaderSections != kNumHeaderSectionsMax)
|
||||
return S_FALSE;
|
||||
ReadUInt32(); // Length of post-header table
|
||||
GUID g;
|
||||
GUID g;
|
||||
ReadGUID(g); // {0A9007C1-4076-11D3-8789-0000F8105754}
|
||||
|
||||
// header section table
|
||||
// header section table
|
||||
UInt64 sectionOffsets[kNumHeaderSectionsMax];
|
||||
UInt64 sectionSizes[kNumHeaderSectionsMax];
|
||||
UInt32 i;
|
||||
@@ -434,9 +434,9 @@ HRESULT CInArchive::OpenHelp2(IInStream *inStream, CDatabase &database)
|
||||
ReadUInt64(); // Number of directory index entries (same as number of AOLL
|
||||
// chunks in main directory)
|
||||
|
||||
// (The obvious guess for the following two fields, which recur in a number
|
||||
// of places, is they are maximum sizes for the directory and directory index.
|
||||
// However, I have seen no direct evidence that this is the case.)
|
||||
// (The obvious guess for the following two fields, which recur in a number
|
||||
// of places, is they are maximum sizes for the directory and directory index.
|
||||
// However, I have seen no direct evidence that this is the case.)
|
||||
|
||||
ReadUInt32(); // $100000 (Same as field following chunk size in directory)
|
||||
ReadUInt32(); // $20000 (Same as field following chunk size in directory index)
|
||||
@@ -480,8 +480,8 @@ HRESULT CInArchive::OpenHelp2(IInStream *inStream, CDatabase &database)
|
||||
if (unknown != 0 && unknown != 1) // = 0 for some HxW files, 1 in other cases;
|
||||
return S_FALSE;
|
||||
database.ContentOffset = _startPosition + ReadUInt64();
|
||||
/* UInt32 timeStamp = */ ReadUInt32();
|
||||
// A timestamp of some sort.
|
||||
/* UInt32 timeStamp = */ ReadUInt32();
|
||||
// A timestamp of some sort.
|
||||
// Considered as a big-endian DWORD, it appears to contain
|
||||
// seconds (MSB) and fractional seconds (second byte).
|
||||
// The third and fourth bytes may contain even more fractional
|
||||
@@ -527,7 +527,7 @@ HRESULT CInArchive::OpenHelp2(IInStream *inStream, CDatabase &database)
|
||||
UInt32 quickrefLength = ReadUInt32(); // Length of quickref area at end of directory chunk
|
||||
if (quickrefLength > dirChunkSize || quickrefLength < 2)
|
||||
return S_FALSE;
|
||||
ReadUInt64(); // Directory chunk number
|
||||
ReadUInt64(); // Directory chunk number
|
||||
// This must match physical position in file, that is
|
||||
// the chunk size times the chunk number must be the
|
||||
// offset from the end of the directory header.
|
||||
@@ -625,8 +625,8 @@ static int CompareFiles(const int *p1, const int *p2, void *param)
|
||||
const CObjectVector<CItem> &items = *(const CObjectVector<CItem> *)param;
|
||||
const CItem &item1 = items[*p1];
|
||||
const CItem &item2 = items[*p2];
|
||||
bool isDir1 = item1.IsDirectory();
|
||||
bool isDir2 = item2.IsDirectory();
|
||||
bool isDir1 = item1.IsDir();
|
||||
bool isDir2 = item2.IsDir();
|
||||
if (isDir1 && !isDir2)
|
||||
return -1;
|
||||
if (isDir2)
|
||||
@@ -663,7 +663,7 @@ bool CFilesDatabase::Check()
|
||||
for(int i = 0; i < Indices.Size(); i++)
|
||||
{
|
||||
const CItem &item = Items[Indices[i]];
|
||||
if (item.Section == 0 || item.IsDirectory())
|
||||
if (item.Section == 0 || item.IsDir())
|
||||
continue;
|
||||
if (item.Section != prevSection)
|
||||
{
|
||||
@@ -718,7 +718,7 @@ HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
|
||||
AString transformPrefix = sectionPrefix + kTransform;
|
||||
if (database.Help2Format)
|
||||
{
|
||||
// Transform List
|
||||
// Transform List
|
||||
RINOK(DecompressStream(inStream, database, transformPrefix + kTransformList));
|
||||
if ((_chunkSize & 0xF) != 0)
|
||||
return S_FALSE;
|
||||
@@ -760,21 +760,21 @@ HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
|
||||
li.WindowSize = ReadUInt32();
|
||||
li.CacheSize = ReadUInt32();
|
||||
if (
|
||||
li.ResetInterval != 1 &&
|
||||
li.ResetInterval != 2 &&
|
||||
li.ResetInterval != 4 &&
|
||||
li.ResetInterval != 8 &&
|
||||
li.ResetInterval != 16 &&
|
||||
li.ResetInterval != 32 &&
|
||||
li.ResetInterval != 1 &&
|
||||
li.ResetInterval != 2 &&
|
||||
li.ResetInterval != 4 &&
|
||||
li.ResetInterval != 8 &&
|
||||
li.ResetInterval != 16 &&
|
||||
li.ResetInterval != 32 &&
|
||||
li.ResetInterval != 64)
|
||||
return S_FALSE;
|
||||
if (
|
||||
li.WindowSize != 1 &&
|
||||
li.WindowSize != 2 &&
|
||||
li.WindowSize != 4 &&
|
||||
li.WindowSize != 8 &&
|
||||
li.WindowSize != 16 &&
|
||||
li.WindowSize != 32 &&
|
||||
li.WindowSize != 1 &&
|
||||
li.WindowSize != 2 &&
|
||||
li.WindowSize != 4 &&
|
||||
li.WindowSize != 8 &&
|
||||
li.WindowSize != 16 &&
|
||||
li.WindowSize != 32 &&
|
||||
li.WindowSize != 64)
|
||||
return S_FALSE;
|
||||
numDWORDS -= 5;
|
||||
@@ -803,7 +803,7 @@ HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
|
||||
if (method.IsLzx())
|
||||
{
|
||||
// ResetTable;
|
||||
RINOK(DecompressStream(inStream, database, transformPrefix +
|
||||
RINOK(DecompressStream(inStream, database, transformPrefix +
|
||||
method.GetGuidString() + kResetTable));
|
||||
CResetTable &rt = method.LzxInfo.ResetTable;
|
||||
if (_chunkSize < 4)
|
||||
@@ -845,7 +845,7 @@ HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
|
||||
return database.Check() ? S_OK : S_FALSE;
|
||||
}
|
||||
|
||||
HRESULT CInArchive::Open2(IInStream *inStream,
|
||||
HRESULT CInArchive::Open2(IInStream *inStream,
|
||||
const UInt64 *searchHeaderSizeLimit,
|
||||
CFilesDatabase &database)
|
||||
{
|
||||
@@ -864,6 +864,11 @@ HRESULT CInArchive::Open2(IInStream *inStream,
|
||||
const int kSignatureSize = 8;
|
||||
UInt64 hxsSignature = NHeader::GetHxsSignature();
|
||||
UInt64 chmSignature = ((UInt64)chmVersion << 32)| NHeader::kItsfSignature;
|
||||
UInt64 limit = 1 << 18;
|
||||
if (searchHeaderSizeLimit)
|
||||
if (limit > *searchHeaderSizeLimit)
|
||||
limit = *searchHeaderSizeLimit;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Byte b;
|
||||
@@ -880,9 +885,8 @@ HRESULT CInArchive::Open2(IInStream *inStream,
|
||||
database.Help2Format = true;
|
||||
break;
|
||||
}
|
||||
if (searchHeaderSizeLimit != NULL)
|
||||
if (_inBuffer.GetProcessedSize() > (*searchHeaderSizeLimit))
|
||||
return S_FALSE;
|
||||
if (_inBuffer.GetProcessedSize() > limit)
|
||||
return S_FALSE;
|
||||
}
|
||||
}
|
||||
_startPosition += _inBuffer.GetProcessedSize() - kSignatureSize;
|
||||
@@ -919,7 +923,7 @@ HRESULT CInArchive::Open2(IInStream *inStream,
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CInArchive::Open(IInStream *inStream,
|
||||
HRESULT CInArchive::Open(IInStream *inStream,
|
||||
const UInt64 *searchHeaderSizeLimit,
|
||||
CFilesDatabase &database)
|
||||
{
|
||||
|
||||
@@ -19,21 +19,21 @@ struct CItem
|
||||
UInt64 Size;
|
||||
AString Name;
|
||||
|
||||
bool IsFormatRelatedItem() const
|
||||
bool IsFormatRelatedItem() const
|
||||
{
|
||||
if (Name.Length() < 2)
|
||||
return false;
|
||||
return Name[0] == ':' && Name[1] == ':';
|
||||
}
|
||||
|
||||
bool IsUserItem() const
|
||||
bool IsUserItem() const
|
||||
{
|
||||
if (Name.Length() < 2)
|
||||
return false;
|
||||
return Name[0] == '/';
|
||||
}
|
||||
|
||||
bool IsDirectory() const
|
||||
bool IsDir() const
|
||||
{
|
||||
if (Name.Length() == 0)
|
||||
return false;
|
||||
@@ -57,12 +57,12 @@ struct CDatabase
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
void Clear()
|
||||
{
|
||||
NewFormat = false;
|
||||
NewFormatString.Empty();
|
||||
Help2Format = false;
|
||||
Items.Clear();
|
||||
Items.Clear();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -72,7 +72,7 @@ struct CResetTable
|
||||
UInt64 CompressedSize;
|
||||
UInt64 BlockSize;
|
||||
CRecordVector<UInt64> ResetOffsets;
|
||||
bool GetCompressedSizeOfBlocks(UInt64 blockIndex, UInt32 numBlocks, UInt64 &size) const
|
||||
bool GetCompressedSizeOfBlocks(UInt64 blockIndex, UInt32 numBlocks, UInt64 &size) const
|
||||
{
|
||||
if (blockIndex >= ResetOffsets.Size())
|
||||
return false;
|
||||
@@ -83,11 +83,11 @@ struct CResetTable
|
||||
size = ResetOffsets[(int)(blockIndex + numBlocks)] - startPos;
|
||||
return true;
|
||||
}
|
||||
bool GetCompressedSizeOfBlock(UInt64 blockIndex, UInt64 &size) const
|
||||
bool GetCompressedSizeOfBlock(UInt64 blockIndex, UInt64 &size) const
|
||||
{
|
||||
return GetCompressedSizeOfBlocks(blockIndex, 1, size);
|
||||
}
|
||||
UInt64 GetNumBlocks(UInt64 size) const
|
||||
UInt64 GetNumBlocks(UInt64 size) const
|
||||
{
|
||||
return (size + BlockSize - 1) / BlockSize;
|
||||
}
|
||||
@@ -116,16 +116,16 @@ struct CLzxInfo
|
||||
UInt64 GetFolder(UInt64 offset) const { return offset / GetFolderSize(); };
|
||||
UInt64 GetFolderPos(UInt64 folderIndex) const { return folderIndex * GetFolderSize(); };
|
||||
UInt64 GetBlockIndexFromFolderIndex(UInt64 folderIndex) const { return folderIndex * ResetInterval; };
|
||||
bool GetOffsetOfFolder(UInt64 folderIndex, UInt64 &offset) const
|
||||
{
|
||||
bool GetOffsetOfFolder(UInt64 folderIndex, UInt64 &offset) const
|
||||
{
|
||||
UInt64 blockIndex = GetBlockIndexFromFolderIndex(folderIndex);
|
||||
if (blockIndex >= ResetTable.ResetOffsets.Size())
|
||||
return false;
|
||||
offset = ResetTable.ResetOffsets[(int)blockIndex];
|
||||
return true;
|
||||
}
|
||||
bool GetCompressedSizeOfFolder(UInt64 folderIndex, UInt64 &size) const
|
||||
{
|
||||
bool GetCompressedSizeOfFolder(UInt64 folderIndex, UInt64 &size) const
|
||||
{
|
||||
UInt64 blockIndex = GetBlockIndexFromFolderIndex(folderIndex);
|
||||
return ResetTable.GetCompressedSizeOfBlocks(blockIndex, ResetInterval, size);
|
||||
}
|
||||
@@ -165,8 +165,8 @@ public:
|
||||
UInt64 GetFileSize(int fileIndex) const { return Items[Indices[fileIndex]].Size; }
|
||||
UInt64 GetFileOffset(int fileIndex) const { return Items[Indices[fileIndex]].Offset; }
|
||||
|
||||
UInt64 GetFolder(int fileIndex) const
|
||||
{
|
||||
UInt64 GetFolder(int fileIndex) const
|
||||
{
|
||||
const CItem &item = Items[Indices[fileIndex]];
|
||||
const CSectionInfo §ion = Sections[(int)item.Section];
|
||||
if (section.IsLzx())
|
||||
@@ -174,8 +174,8 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
UInt64 GetLastFolder(int fileIndex) const
|
||||
{
|
||||
UInt64 GetLastFolder(int fileIndex) const
|
||||
{
|
||||
const CItem &item = Items[Indices[fileIndex]];
|
||||
const CSectionInfo §ion = Sections[(int)item.Section];
|
||||
if (section.IsLzx())
|
||||
@@ -183,16 +183,16 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HighLevelClear()
|
||||
{
|
||||
void HighLevelClear()
|
||||
{
|
||||
LowLevel = true;
|
||||
Indices.Clear();
|
||||
Sections.Clear();
|
||||
Indices.Clear();
|
||||
Sections.Clear();
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
CDatabase::Clear();
|
||||
void Clear()
|
||||
{
|
||||
CDatabase::Clear();
|
||||
HighLevelClear();
|
||||
}
|
||||
void SetIndices();
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
@@ -10,19 +10,19 @@
|
||||
namespace NArchive {
|
||||
namespace NCom {
|
||||
|
||||
STATPROPSTG kProps[] =
|
||||
STATPROPSTG kProps[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
{ NULL, kpidIsFolder, VT_BOOL},
|
||||
{ NULL, kpidIsDir, VT_BOOL},
|
||||
{ NULL, kpidSize, VT_UI8},
|
||||
// { NULL, kpidAttributes, VT_UI4},
|
||||
{ NULL, kpidPackedSize, VT_UI8},
|
||||
{ NULL, kpidCreationTime, VT_FILETIME},
|
||||
{ NULL, kpidLastWriteTime, VT_FILETIME}
|
||||
{ NULL, kpidPackSize, VT_UI8},
|
||||
{ NULL, kpidCTime, VT_FILETIME},
|
||||
{ NULL, kpidMTime, VT_FILETIME}
|
||||
};
|
||||
|
||||
|
||||
STATPROPSTG kArcProps[] =
|
||||
STATPROPSTG kArcProps[] =
|
||||
{
|
||||
{ NULL, kpidClusterSize, VT_UI4}
|
||||
};
|
||||
@@ -58,25 +58,19 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
prop = name;
|
||||
break;
|
||||
}
|
||||
case kpidIsFolder:
|
||||
prop = item.IsDir();
|
||||
break;
|
||||
case kpidCreationTime:
|
||||
prop = item.CreationTime;
|
||||
break;
|
||||
case kpidLastWriteTime:
|
||||
prop = item.LastWriteTime;
|
||||
break;
|
||||
case kpidIsDir: prop = item.IsDir(); break;
|
||||
case kpidCTime: prop = item.CTime; break;
|
||||
case kpidMTime: prop = item.MTime; break;
|
||||
/*
|
||||
case kpidAttributes:
|
||||
prop = item.Falgs;
|
||||
break;
|
||||
*/
|
||||
case kpidPackedSize:
|
||||
case kpidPackSize:
|
||||
if (!item.IsDir())
|
||||
{
|
||||
int numBits = _db.IsLargeStream(item.Size) ?
|
||||
_db.SectorSizeBits :
|
||||
int numBits = _db.IsLargeStream(item.Size) ?
|
||||
_db.SectorSizeBits :
|
||||
_db.MiniSectorSizeBits;
|
||||
prop = (item.Size + ((UInt64)1 << numBits) - 1) >> numBits << numBits;
|
||||
break;
|
||||
@@ -91,7 +85,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
const UInt64 * /* maxCheckStartPosition */,
|
||||
IArchiveOpenCallback * /* openArchiveCallback */)
|
||||
{
|
||||
@@ -150,7 +144,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
currentItemSize = item.Size;
|
||||
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode = testMode ?
|
||||
Int32 askMode = testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
@@ -204,7 +198,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
if (fid >= _db.NumSectorsInMiniStream)
|
||||
break;
|
||||
size = 1 << _db.MiniSectorSizeBits;
|
||||
offset = (((UInt64)_db.MiniSids[fid] + 1) << _db.SectorSizeBits) +
|
||||
offset = (((UInt64)_db.MiniSids[fid] + 1) << _db.SectorSizeBits) +
|
||||
((sid & ((1 << subBits) - 1)) << _db.MiniSectorSizeBits);
|
||||
if (sid >= _db.MatSize)
|
||||
break;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
namespace NArchive {
|
||||
namespace NCom {
|
||||
|
||||
class CHandler:
|
||||
class CHandler:
|
||||
public IInArchive,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../../C/Alloc.h"
|
||||
}
|
||||
|
||||
@@ -69,8 +69,8 @@ static void ReadItem(Byte *p, CItem &item, bool mode64bit)
|
||||
item.RightDid = GetUi32(p + 72);
|
||||
item.SonDid = GetUi32(p + 76);
|
||||
// item.Flags = GetUi32(p + 96);
|
||||
GetFileTimeFromMem(p + 100, &item.CreationTime);
|
||||
GetFileTimeFromMem(p + 108, &item.LastWriteTime);
|
||||
GetFileTimeFromMem(p + 100, &item.CTime);
|
||||
GetFileTimeFromMem(p + 108, &item.MTime);
|
||||
item.Sid = GetUi32(p + 116);
|
||||
item.Size = GetUi32(p + 120);
|
||||
if (mode64bit)
|
||||
@@ -127,7 +127,7 @@ static UString CompoundNameToFileName(const UString &s)
|
||||
}
|
||||
else
|
||||
res += c;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -219,7 +219,7 @@ HRESULT OpenArchive(IInStream *inStream, CDatabase &db)
|
||||
db.SectorSizeBits = sectorSizeBits;
|
||||
db.MiniSectorSizeBits = miniSectorSizeBits;
|
||||
|
||||
if (sectorSizeBits > 28 || miniSectorSizeBits > 28 ||
|
||||
if (sectorSizeBits > 28 || miniSectorSizeBits > 28 ||
|
||||
sectorSizeBits < 7 || miniSectorSizeBits < 2 || miniSectorSizeBits > sectorSizeBits)
|
||||
return S_FALSE;
|
||||
UInt32 numSectorsForFAT = GetUi32(p + 0x2C);
|
||||
|
||||
@@ -46,8 +46,8 @@ struct CItem
|
||||
Byte Name[kNameSizeMax];
|
||||
// UInt16 NameSize;
|
||||
// UInt32 Flags;
|
||||
FILETIME CreationTime;
|
||||
FILETIME LastWriteTime;
|
||||
FILETIME CTime;
|
||||
FILETIME MTime;
|
||||
UInt64 Size;
|
||||
UInt32 LeftDid;
|
||||
UInt32 RightDid;
|
||||
|
||||
@@ -16,4 +16,4 @@ void CCoderInfo::SetCoderInfo(const UInt64 *inSize, const UInt64 *outSize)
|
||||
OutSizeValue = *outSize;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ void CBindReverseConverter::CreateReverseBindInfo(CBindInfo &destBindInfo)
|
||||
destBindInfo.InStreams.Add(_srcOutToDestInMap[_srcBindInfo.OutStreams[i]]);
|
||||
}
|
||||
|
||||
CCoderInfo2::CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams):
|
||||
CCoderInfo2::CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams):
|
||||
NumInStreams(numInStreams),
|
||||
NumOutStreams(numOutStreams)
|
||||
{
|
||||
@@ -91,7 +91,7 @@ CCoderInfo2::CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams):
|
||||
OutSizePointers.Reserve(NumOutStreams);
|
||||
}
|
||||
|
||||
static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes,
|
||||
static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes,
|
||||
CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems)
|
||||
{
|
||||
sizes.Clear();
|
||||
@@ -118,4 +118,4 @@ void CCoderInfo2::SetCoderInfo(const UInt64 **inSizes,
|
||||
SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ struct CBindInfo
|
||||
}
|
||||
|
||||
|
||||
void FindInStream(UInt32 streamIndex, UInt32 &coderIndex,
|
||||
void FindInStream(UInt32 streamIndex, UInt32 &coderIndex,
|
||||
UInt32 &coderStreamIndex) const
|
||||
{
|
||||
for (coderIndex = 0; coderIndex < (UInt32)Coders.Size(); coderIndex++)
|
||||
@@ -107,7 +107,7 @@ struct CBindInfo
|
||||
}
|
||||
throw 1;
|
||||
}
|
||||
void FindOutStream(UInt32 streamIndex, UInt32 &coderIndex,
|
||||
void FindOutStream(UInt32 streamIndex, UInt32 &coderIndex,
|
||||
UInt32 &coderStreamIndex) const
|
||||
{
|
||||
for (coderIndex = 0; coderIndex < (UInt32)Coders.Size(); coderIndex++)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
namespace NCoderMixer {
|
||||
|
||||
CCoder2::CCoder2(UInt32 numInStreams, UInt32 numOutStreams):
|
||||
CCoder2::CCoder2(UInt32 numInStreams, UInt32 numOutStreams):
|
||||
CCoderInfo2(numInStreams, numOutStreams)
|
||||
{
|
||||
InStreams.Reserve(NumInStreams);
|
||||
@@ -35,7 +35,7 @@ void CCoder2::Code(ICompressProgressInfo *progress)
|
||||
OutStreamPointers.Add((ISequentialOutStream *)OutStreams[i]);
|
||||
}
|
||||
if (Coder)
|
||||
Result = Coder->Code(InStreamPointers[0], OutStreamPointers[0],
|
||||
Result = Coder->Code(InStreamPointers[0], OutStreamPointers[0],
|
||||
InSizePointers[0], OutSizePointers[0], progress);
|
||||
else
|
||||
Result = Coder2->Code(&InStreamPointers.Front(), &InSizePointers.Front(), NumInStreams,
|
||||
@@ -49,7 +49,7 @@ void CCoder2::Code(ICompressProgressInfo *progress)
|
||||
}
|
||||
}
|
||||
|
||||
static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes,
|
||||
static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes,
|
||||
CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems)
|
||||
{
|
||||
sizes.Clear();
|
||||
@@ -80,8 +80,8 @@ void CCoder2::SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes)
|
||||
// CCoderMixer2MT
|
||||
|
||||
HRESULT CCoderMixer2MT::SetBindInfo(const CBindInfo &bindInfo)
|
||||
{
|
||||
_bindInfo = bindInfo;
|
||||
{
|
||||
_bindInfo = bindInfo;
|
||||
_streamBinders.Clear();
|
||||
for(int i = 0; i < _bindInfo.BindPairs.Size(); i++)
|
||||
{
|
||||
@@ -118,7 +118,7 @@ void CCoderMixer2MT::ReInit()
|
||||
}
|
||||
|
||||
|
||||
HRESULT CCoderMixer2MT::Init(ISequentialInStream **inStreams, ISequentialOutStream **outStreams)
|
||||
HRESULT CCoderMixer2MT::Init(ISequentialInStream **inStreams, ISequentialOutStream **outStreams)
|
||||
{
|
||||
/*
|
||||
if (_coders.Size() != _bindInfo.Coders.Size())
|
||||
@@ -176,9 +176,9 @@ HRESULT CCoderMixer2MT::ReturnIfError(HRESULT code)
|
||||
}
|
||||
|
||||
STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams,
|
||||
const UInt64 ** /* inSizes */,
|
||||
const UInt64 ** /* inSizes */,
|
||||
UInt32 numInStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
const UInt64 ** /* outSizes */,
|
||||
UInt32 numOutStreams,
|
||||
ICompressProgressInfo *progress)
|
||||
@@ -227,4 +227,4 @@ STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams,
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ struct CCoder2: public CCoderInfo2, public CVirtThread
|
||||
{
|
||||
ReInit()
|
||||
for each coder
|
||||
SetCoderInfo
|
||||
SetCoderInfo
|
||||
Code
|
||||
}
|
||||
*/
|
||||
@@ -57,9 +57,9 @@ public:
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream **inStreams,
|
||||
const UInt64 **inSizes,
|
||||
const UInt64 **inSizes,
|
||||
UInt32 numInStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
const UInt64 **outSizes,
|
||||
UInt32 numOutStreams,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
@@ -11,9 +11,9 @@ CCoderMixer2ST::CCoderMixer2ST() {}
|
||||
CCoderMixer2ST::~CCoderMixer2ST(){ }
|
||||
|
||||
HRESULT CCoderMixer2ST::SetBindInfo(const CBindInfo &bindInfo)
|
||||
{
|
||||
_bindInfo = bindInfo;
|
||||
return S_OK;
|
||||
{
|
||||
_bindInfo = bindInfo;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void CCoderMixer2ST::AddCoderCommon(bool isMain)
|
||||
@@ -37,7 +37,7 @@ void CCoderMixer2ST::AddCoder2(ICompressCoder2 *coder, bool isMain)
|
||||
void CCoderMixer2ST::ReInit() { }
|
||||
|
||||
HRESULT CCoderMixer2ST::GetInStream(
|
||||
ISequentialInStream **inStreams, const UInt64 **inSizes,
|
||||
ISequentialInStream **inStreams, const UInt64 **inSizes,
|
||||
UInt32 streamIndex, ISequentialInStream **inStreamRes)
|
||||
{
|
||||
CMyComPtr<ISequentialInStream> seqInStream;
|
||||
@@ -54,7 +54,7 @@ HRESULT CCoderMixer2ST::GetInStream(
|
||||
return E_INVALIDARG;
|
||||
|
||||
UInt32 coderIndex, coderStreamIndex;
|
||||
_bindInfo.FindOutStream(_bindInfo.BindPairs[binderIndex].OutIndex,
|
||||
_bindInfo.FindOutStream(_bindInfo.BindPairs[binderIndex].OutIndex,
|
||||
coderIndex, coderStreamIndex);
|
||||
|
||||
CCoderInfo &coder = _coders[coderIndex];
|
||||
@@ -86,7 +86,7 @@ HRESULT CCoderMixer2ST::GetInStream(
|
||||
}
|
||||
|
||||
HRESULT CCoderMixer2ST::GetOutStream(
|
||||
ISequentialOutStream **outStreams, const UInt64 **outSizes,
|
||||
ISequentialOutStream **outStreams, const UInt64 **outSizes,
|
||||
UInt32 streamIndex, ISequentialOutStream **outStreamRes)
|
||||
{
|
||||
CMyComPtr<ISequentialOutStream> seqOutStream;
|
||||
@@ -103,7 +103,7 @@ HRESULT CCoderMixer2ST::GetOutStream(
|
||||
return E_INVALIDARG;
|
||||
|
||||
UInt32 coderIndex, coderStreamIndex;
|
||||
_bindInfo.FindInStream(_bindInfo.BindPairs[binderIndex].InIndex,
|
||||
_bindInfo.FindInStream(_bindInfo.BindPairs[binderIndex].InIndex,
|
||||
coderIndex, coderStreamIndex);
|
||||
|
||||
CCoderInfo &coder = _coders[coderIndex];
|
||||
@@ -136,9 +136,9 @@ HRESULT CCoderMixer2ST::GetOutStream(
|
||||
|
||||
|
||||
STDMETHODIMP CCoderMixer2ST::Code(ISequentialInStream **inStreams,
|
||||
const UInt64 **inSizes,
|
||||
const UInt64 **inSizes,
|
||||
UInt32 numInStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
const UInt64 **outSizes,
|
||||
UInt32 numOutStreams,
|
||||
ICompressProgressInfo *progress)
|
||||
@@ -216,9 +216,9 @@ STDMETHODIMP CCoderMixer2ST::Code(ISequentialInStream **inStreams,
|
||||
else
|
||||
{
|
||||
RINOK(mainCoder.Coder2->Code(
|
||||
&seqInStreamsSpec.Front(),
|
||||
&seqInStreamsSpec.Front(),
|
||||
&mainCoder.InSizePointers.Front(), mainCoder.NumInStreams,
|
||||
&seqOutStreamsSpec.Front(),
|
||||
&seqOutStreamsSpec.Front(),
|
||||
&mainCoder.OutSizePointers.Front(), mainCoder.NumOutStreams,
|
||||
progress));
|
||||
}
|
||||
@@ -236,4 +236,4 @@ UInt64 CCoderMixer2ST::GetWriteProcessedSize(UInt32 binderIndex) const
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,13 +14,13 @@ namespace NCoderMixer2 {
|
||||
// {
|
||||
// AddCoder[2]()
|
||||
// }
|
||||
//
|
||||
//
|
||||
// for each file
|
||||
// {
|
||||
// ReInit()
|
||||
// for each coder
|
||||
// {
|
||||
// SetCoderInfo
|
||||
// SetCoderInfo
|
||||
// }
|
||||
// SetProgressIndex(UInt32 coderIndex);
|
||||
// Code
|
||||
@@ -41,16 +41,16 @@ class CCoderMixer2ST:
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
HRESULT GetInStream(
|
||||
ISequentialInStream **inStreams, const UInt64 **inSizes,
|
||||
ISequentialInStream **inStreams, const UInt64 **inSizes,
|
||||
UInt32 streamIndex, ISequentialInStream **inStreamRes);
|
||||
HRESULT GetOutStream(
|
||||
ISequentialOutStream **outStreams, const UInt64 **outSizes,
|
||||
ISequentialOutStream **outStreams, const UInt64 **outSizes,
|
||||
UInt32 streamIndex, ISequentialOutStream **outStreamRes);
|
||||
public:
|
||||
STDMETHOD(Code)(ISequentialInStream **inStreams,
|
||||
const UInt64 **inSizes,
|
||||
const UInt64 **inSizes,
|
||||
UInt32 numInStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
const UInt64 **outSizes,
|
||||
UInt32 numOutStreams,
|
||||
ICompressProgressInfo *progress);
|
||||
@@ -63,13 +63,13 @@ public:
|
||||
|
||||
void ReInit();
|
||||
void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes)
|
||||
{
|
||||
{
|
||||
{ _coders[coderIndex].SetCoderInfo(inSizes, outSizes); }
|
||||
}
|
||||
|
||||
void SetProgressCoderIndex(UInt32 /*coderIndex*/)
|
||||
{
|
||||
// _progressCoderIndex = coderIndex;
|
||||
{
|
||||
// _progressCoderIndex = coderIndex;
|
||||
}
|
||||
|
||||
// UInt64 GetWriteProcessedSize(UInt32 binderIndex) const;
|
||||
|
||||
@@ -10,9 +10,9 @@ void CCoder::Execute() { Code(NULL); }
|
||||
|
||||
void CCoder::Code(ICompressProgressInfo *progress)
|
||||
{
|
||||
Result = Coder->Code(InStream, OutStream,
|
||||
InSizeAssigned ? &InSizeValue : NULL,
|
||||
OutSizeAssigned ? &OutSizeValue : NULL,
|
||||
Result = Coder->Code(InStream, OutStream,
|
||||
InSizeAssigned ? &InSizeValue : NULL,
|
||||
OutSizeAssigned ? &OutSizeValue : NULL,
|
||||
progress);
|
||||
InStream.Release();
|
||||
OutStream.Release();
|
||||
@@ -39,7 +39,7 @@ HRESULT CCoderMixerMT::ReturnIfError(HRESULT code)
|
||||
}
|
||||
|
||||
STDMETHODIMP CCoderMixerMT::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
ISequentialOutStream *outStream,
|
||||
const UInt64 * /* inSize */, const UInt64 * /* outSize */,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
@@ -96,4 +96,4 @@ STDMETHODIMP CCoderMixerMT::Code(ISequentialInStream *inStream,
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ struct CCoder: public CCoderInfo, public CVirtThread
|
||||
{
|
||||
ReInit()
|
||||
for each coder
|
||||
SetCoderInfo
|
||||
SetCoderInfo
|
||||
Code
|
||||
}
|
||||
*/
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
ISequentialOutStream *outStream,
|
||||
const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "../../../Windows/Synchronization.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
|
||||
class CCrossThreadProgress:
|
||||
class CCrossThreadProgress:
|
||||
public ICompressProgressInfo,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "../../IStream.h"
|
||||
#include "Common/MyCom.h"
|
||||
|
||||
class CDummyOutStream:
|
||||
class CDummyOutStream:
|
||||
public ISequentialOutStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
@@ -14,6 +14,7 @@ class CDummyOutStream:
|
||||
UInt64 _size;
|
||||
public:
|
||||
void SetStream(ISequentialOutStream *outStream) { _stream = outStream; }
|
||||
void ReleaseStream() { _stream.Release(); }
|
||||
void Init() { _size = 0; }
|
||||
MY_UNKNOWN_IMP
|
||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
|
||||
62
CPP/7zip/Archive/Common/FindSignature.cpp
Executable file
62
CPP/7zip/Archive/Common/FindSignature.cpp
Executable file
@@ -0,0 +1,62 @@
|
||||
// FindSignature.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/Buffer.h"
|
||||
|
||||
#include "FindSignature.h"
|
||||
|
||||
#include "../../Common/StreamUtils.h"
|
||||
|
||||
HRESULT FindSignatureInStream(ISequentialInStream *stream,
|
||||
const Byte *signature, unsigned signatureSize,
|
||||
const UInt64 *limit, UInt64 &resPos)
|
||||
{
|
||||
resPos = 0;
|
||||
CByteBuffer byteBuffer2;
|
||||
byteBuffer2.SetCapacity(signatureSize);
|
||||
RINOK(ReadStream_FALSE(stream, byteBuffer2, signatureSize));
|
||||
|
||||
if (memcmp(byteBuffer2, signature, signatureSize) == 0)
|
||||
return S_OK;
|
||||
|
||||
const UInt32 kBufferSize = (1 << 16);
|
||||
CByteBuffer byteBuffer;
|
||||
byteBuffer.SetCapacity(kBufferSize);
|
||||
Byte *buffer = byteBuffer;
|
||||
UInt32 numPrevBytes = signatureSize - 1;
|
||||
memcpy(buffer, (const Byte *)byteBuffer2 + 1, numPrevBytes);
|
||||
resPos = 1;
|
||||
for (;;)
|
||||
{
|
||||
if (limit != NULL)
|
||||
if (resPos > *limit)
|
||||
return S_FALSE;
|
||||
do
|
||||
{
|
||||
UInt32 numReadBytes = kBufferSize - numPrevBytes;
|
||||
UInt32 processedSize;
|
||||
RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize));
|
||||
numPrevBytes += processedSize;
|
||||
if (processedSize == 0)
|
||||
return S_FALSE;
|
||||
}
|
||||
while (numPrevBytes < signatureSize);
|
||||
UInt32 numTests = numPrevBytes - signatureSize + 1;
|
||||
for (UInt32 pos = 0; pos < numTests; pos++)
|
||||
{
|
||||
Byte b = signature[0];
|
||||
for (; buffer[pos] != b && pos < numTests; pos++);
|
||||
if (pos == numTests)
|
||||
break;
|
||||
if (memcmp(buffer + pos, signature, signatureSize) == 0)
|
||||
{
|
||||
resPos += pos;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
resPos += numTests;
|
||||
numPrevBytes -= numTests;
|
||||
memmove(buffer, buffer + numTests, numPrevBytes);
|
||||
}
|
||||
}
|
||||
12
CPP/7zip/Archive/Common/FindSignature.h
Executable file
12
CPP/7zip/Archive/Common/FindSignature.h
Executable file
@@ -0,0 +1,12 @@
|
||||
// FindSignature.h
|
||||
|
||||
#ifndef __FINDSIGNATURE_H
|
||||
#define __FINDSIGNATURE_H
|
||||
|
||||
#include "../../IStream.h"
|
||||
|
||||
HRESULT FindSignatureInStream(ISequentialInStream *stream,
|
||||
const Byte *signature, unsigned signatureSize,
|
||||
const UInt64 *limit, UInt64 &resPos);
|
||||
|
||||
#endif
|
||||
@@ -79,10 +79,10 @@ static bool AreEqual(const UString &methodName, const wchar_t *s)
|
||||
{ return (methodName.CompareNoCase(s) == 0); }
|
||||
|
||||
static inline bool IsLZMAMethod(const UString &methodName)
|
||||
{
|
||||
return
|
||||
AreEqual(methodName, kLZMAMethodName) ||
|
||||
AreEqual(methodName, kLZMA2MethodName);
|
||||
{
|
||||
return
|
||||
AreEqual(methodName, kLZMAMethodName) ||
|
||||
AreEqual(methodName, kLZMA2MethodName);
|
||||
}
|
||||
|
||||
static inline bool IsBZip2Method(const UString &methodName)
|
||||
@@ -92,10 +92,10 @@ static inline bool IsPpmdMethod(const UString &methodName)
|
||||
{ return AreEqual(methodName, kPpmdMethodName); }
|
||||
|
||||
static inline bool IsDeflateMethod(const UString &methodName)
|
||||
{
|
||||
return
|
||||
AreEqual(methodName, kDeflateMethodName) ||
|
||||
AreEqual(methodName, kDeflate64MethodName);
|
||||
{
|
||||
return
|
||||
AreEqual(methodName, kDeflateMethodName) ||
|
||||
AreEqual(methodName, kDeflate64MethodName);
|
||||
}
|
||||
|
||||
struct CNameToPropID
|
||||
@@ -105,7 +105,7 @@ struct CNameToPropID
|
||||
const wchar_t *Name;
|
||||
};
|
||||
|
||||
CNameToPropID g_NameToPropID[] =
|
||||
CNameToPropID g_NameToPropID[] =
|
||||
{
|
||||
{ NCoderPropID::kOrder, VT_UI4, L"O" },
|
||||
{ NCoderPropID::kPosStateBits, VT_UI4, L"PB" },
|
||||
@@ -158,7 +158,7 @@ static int FindPropIdFromStringName(const UString &name)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void SetOneMethodProp(COneMethodInfo &oneMethodInfo, PROPID propID,
|
||||
static void SetOneMethodProp(COneMethodInfo &oneMethodInfo, PROPID propID,
|
||||
const NWindows::NCOM::CPropVariant &value)
|
||||
{
|
||||
for (int j = 0; j < oneMethodInfo.Properties.Size(); j++)
|
||||
@@ -182,24 +182,24 @@ void COutHandler::SetCompressionMethod2(COneMethodInfo &oneMethodInfo
|
||||
|
||||
if (IsLZMAMethod(oneMethodInfo.MethodName))
|
||||
{
|
||||
UInt32 dicSize =
|
||||
(level >= 9 ? kLzmaDicSizeX9 :
|
||||
(level >= 7 ? kLzmaDicSizeX7 :
|
||||
(level >= 5 ? kLzmaDicSizeX5 :
|
||||
(level >= 3 ? kLzmaDicSizeX3 :
|
||||
kLzmaDicSizeX1))));
|
||||
UInt32 dicSize =
|
||||
(level >= 9 ? kLzmaDicSizeX9 :
|
||||
(level >= 7 ? kLzmaDicSizeX7 :
|
||||
(level >= 5 ? kLzmaDicSizeX5 :
|
||||
(level >= 3 ? kLzmaDicSizeX3 :
|
||||
kLzmaDicSizeX1))));
|
||||
|
||||
UInt32 algo =
|
||||
(level >= 5 ? kLzmaAlgoX5 :
|
||||
kLzmaAlgoX1);
|
||||
UInt32 algo =
|
||||
(level >= 5 ? kLzmaAlgoX5 :
|
||||
kLzmaAlgoX1);
|
||||
|
||||
UInt32 fastBytes =
|
||||
(level >= 7 ? kLzmaFastBytesX7 :
|
||||
kLzmaFastBytesX1);
|
||||
UInt32 fastBytes =
|
||||
(level >= 7 ? kLzmaFastBytesX7 :
|
||||
kLzmaFastBytesX1);
|
||||
|
||||
const wchar_t *matchFinder =
|
||||
(level >= 5 ? kLzmaMatchFinderX5 :
|
||||
kLzmaMatchFinderX1);
|
||||
const wchar_t *matchFinder =
|
||||
(level >= 5 ? kLzmaMatchFinderX5 :
|
||||
kLzmaMatchFinderX1);
|
||||
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize);
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algo);
|
||||
@@ -211,19 +211,19 @@ void COutHandler::SetCompressionMethod2(COneMethodInfo &oneMethodInfo
|
||||
}
|
||||
else if (IsDeflateMethod(oneMethodInfo.MethodName))
|
||||
{
|
||||
UInt32 fastBytes =
|
||||
(level >= 9 ? kDeflateFastBytesX9 :
|
||||
(level >= 7 ? kDeflateFastBytesX7 :
|
||||
UInt32 fastBytes =
|
||||
(level >= 9 ? kDeflateFastBytesX9 :
|
||||
(level >= 7 ? kDeflateFastBytesX7 :
|
||||
kDeflateFastBytesX1));
|
||||
|
||||
UInt32 numPasses =
|
||||
(level >= 9 ? kDeflatePassesX9 :
|
||||
(level >= 7 ? kDeflatePassesX7 :
|
||||
UInt32 numPasses =
|
||||
(level >= 9 ? kDeflatePassesX9 :
|
||||
(level >= 7 ? kDeflatePassesX7 :
|
||||
kDeflatePassesX1));
|
||||
|
||||
UInt32 algo =
|
||||
(level >= 5 ? kDeflateAlgoX5 :
|
||||
kDeflateAlgoX1);
|
||||
UInt32 algo =
|
||||
(level >= 5 ? kDeflateAlgoX5 :
|
||||
kDeflateAlgoX1);
|
||||
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algo);
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes);
|
||||
@@ -231,14 +231,14 @@ void COutHandler::SetCompressionMethod2(COneMethodInfo &oneMethodInfo
|
||||
}
|
||||
else if (IsBZip2Method(oneMethodInfo.MethodName))
|
||||
{
|
||||
UInt32 numPasses =
|
||||
(level >= 9 ? kBZip2NumPassesX9 :
|
||||
(level >= 7 ? kBZip2NumPassesX7 :
|
||||
UInt32 numPasses =
|
||||
(level >= 9 ? kBZip2NumPassesX9 :
|
||||
(level >= 7 ? kBZip2NumPassesX7 :
|
||||
kBZip2NumPassesX1));
|
||||
|
||||
UInt32 dicSize =
|
||||
(level >= 5 ? kBZip2DicSizeX5 :
|
||||
(level >= 3 ? kBZip2DicSizeX3 :
|
||||
UInt32 dicSize =
|
||||
(level >= 5 ? kBZip2DicSizeX5 :
|
||||
(level >= 3 ? kBZip2DicSizeX3 :
|
||||
kBZip2DicSizeX1));
|
||||
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses);
|
||||
@@ -249,16 +249,16 @@ void COutHandler::SetCompressionMethod2(COneMethodInfo &oneMethodInfo
|
||||
}
|
||||
else if (IsPpmdMethod(oneMethodInfo.MethodName))
|
||||
{
|
||||
UInt32 useMemSize =
|
||||
(level >= 9 ? kPpmdMemSizeX9 :
|
||||
(level >= 7 ? kPpmdMemSizeX7 :
|
||||
(level >= 5 ? kPpmdMemSizeX5 :
|
||||
UInt32 useMemSize =
|
||||
(level >= 9 ? kPpmdMemSizeX9 :
|
||||
(level >= 7 ? kPpmdMemSizeX7 :
|
||||
(level >= 5 ? kPpmdMemSizeX5 :
|
||||
kPpmdMemSizeX1)));
|
||||
|
||||
UInt32 order =
|
||||
(level >= 9 ? kPpmdOrderX9 :
|
||||
(level >= 7 ? kPpmdOrderX7 :
|
||||
(level >= 5 ? kPpmdOrderX5 :
|
||||
UInt32 order =
|
||||
(level >= 9 ? kPpmdOrderX9 :
|
||||
(level >= 7 ? kPpmdOrderX7 :
|
||||
(level >= 5 ? kPpmdOrderX5 :
|
||||
kPpmdOrderX1)));
|
||||
|
||||
SetOneMethodProp(oneMethodInfo, NCoderPropID::kUsedMemorySize, useMemSize);
|
||||
@@ -313,7 +313,7 @@ HRESULT COutHandler::SetParam(COneMethodInfo &oneMethodInfo, const UString &name
|
||||
{
|
||||
CProp property;
|
||||
if (
|
||||
name.CompareNoCase(L"D") == 0 ||
|
||||
name.CompareNoCase(L"D") == 0 ||
|
||||
name.CompareNoCase(L"MEM") == 0)
|
||||
{
|
||||
UInt32 dicSize;
|
||||
@@ -457,11 +457,12 @@ void COutHandler::Init()
|
||||
{
|
||||
_removeSfxBlock = false;
|
||||
_compressHeaders = true;
|
||||
_encryptHeadersSpecified = false;
|
||||
_encryptHeaders = false;
|
||||
|
||||
WriteModified = true;
|
||||
WriteCreated = false;
|
||||
WriteAccessed = false;
|
||||
WriteCTime = false;
|
||||
WriteATime = false;
|
||||
WriteMTime = true;
|
||||
|
||||
#ifdef COMPRESS_MT
|
||||
_numThreads = NWindows::NSystem::GetNumberOfProcessors();
|
||||
@@ -530,12 +531,9 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
|
||||
#endif
|
||||
return S_OK;
|
||||
}
|
||||
if (name.CompareNoCase(L"RSFX") == 0)
|
||||
return SetBoolProperty(_removeSfxBlock, value);
|
||||
if (name.CompareNoCase(L"F") == 0)
|
||||
return SetBoolProperty(_autoFilter, value);
|
||||
if (name.CompareNoCase(L"HC") == 0)
|
||||
return SetBoolProperty(_compressHeaders, value);
|
||||
if (name.CompareNoCase(L"RSFX") == 0) return SetBoolProperty(_removeSfxBlock, value);
|
||||
if (name.CompareNoCase(L"F") == 0) return SetBoolProperty(_autoFilter, value);
|
||||
if (name.CompareNoCase(L"HC") == 0) return SetBoolProperty(_compressHeaders, value);
|
||||
if (name.CompareNoCase(L"HCF") == 0)
|
||||
{
|
||||
bool compressHeadersFull = true;
|
||||
@@ -545,15 +543,15 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
|
||||
return S_OK;
|
||||
}
|
||||
if (name.CompareNoCase(L"HE") == 0)
|
||||
return SetBoolProperty(_encryptHeaders, value);
|
||||
if (name.CompareNoCase(L"TM") == 0)
|
||||
return SetBoolProperty(WriteModified, value);
|
||||
if (name.CompareNoCase(L"TC") == 0)
|
||||
return SetBoolProperty(WriteCreated, value);
|
||||
if (name.CompareNoCase(L"TA") == 0)
|
||||
return SetBoolProperty(WriteAccessed, value);
|
||||
if (name.CompareNoCase(L"V") == 0)
|
||||
return SetBoolProperty(_volumeMode, value);
|
||||
{
|
||||
RINOK(SetBoolProperty(_encryptHeaders, value));
|
||||
_encryptHeadersSpecified = true;
|
||||
return S_OK;
|
||||
}
|
||||
if (name.CompareNoCase(L"TC") == 0) return SetBoolProperty(WriteCTime, value);
|
||||
if (name.CompareNoCase(L"TA") == 0) return SetBoolProperty(WriteATime, value);
|
||||
if (name.CompareNoCase(L"TM") == 0) return SetBoolProperty(WriteMTime, value);
|
||||
if (name.CompareNoCase(L"V") == 0) return SetBoolProperty(_volumeMode, value);
|
||||
number = 0;
|
||||
}
|
||||
if (number > 10000)
|
||||
@@ -623,6 +621,6 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#define __HANDLER_OUT_H
|
||||
|
||||
#include "../../Common/MethodProps.h"
|
||||
#include "../../Common/CreateCoder.h"
|
||||
#include "../../../Common/MyString.h"
|
||||
|
||||
namespace NArchive {
|
||||
|
||||
@@ -31,17 +31,18 @@ public:
|
||||
CObjectVector<COneMethodInfo> _methods;
|
||||
bool _removeSfxBlock;
|
||||
|
||||
UInt64 _numSolidFiles;
|
||||
UInt64 _numSolidFiles;
|
||||
UInt64 _numSolidBytes;
|
||||
bool _numSolidBytesDefined;
|
||||
bool _solidExtension;
|
||||
|
||||
bool _compressHeaders;
|
||||
bool _encryptHeadersSpecified;
|
||||
bool _encryptHeaders;
|
||||
|
||||
bool WriteModified;
|
||||
bool WriteCreated;
|
||||
bool WriteAccessed;
|
||||
bool WriteCTime;
|
||||
bool WriteATime;
|
||||
bool WriteMTime;
|
||||
|
||||
bool _autoFilter;
|
||||
UInt32 _level;
|
||||
@@ -77,8 +78,6 @@ public:
|
||||
UInt32 numProcessors;
|
||||
UInt32 mainDicSize;
|
||||
UInt32 mainDicMethodIndex;
|
||||
|
||||
DECL_EXTERNAL_CODECS_VARS
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
#include "../../../Common/MyCom.h"
|
||||
#include "../../IStream.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../../C/7zCrc.h"
|
||||
}
|
||||
|
||||
class CSequentialInStreamWithCRC:
|
||||
class CSequentialInStreamWithCRC:
|
||||
public ISequentialInStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
@@ -38,7 +38,7 @@ public:
|
||||
bool WasFinished() const { return _wasFinished; }
|
||||
};
|
||||
|
||||
class CInStreamWithCRC:
|
||||
class CInStreamWithCRC:
|
||||
public IInStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
|
||||
@@ -38,7 +38,7 @@ bool HasTailSlash(const AString &name, UINT codePage)
|
||||
{
|
||||
if (name.IsEmpty())
|
||||
return false;
|
||||
LPCSTR prev =
|
||||
LPCSTR prev =
|
||||
#ifdef _WIN32
|
||||
CharPrevExA((WORD)codePage, name, &name[name.Length()], 0);
|
||||
#else
|
||||
|
||||
@@ -33,7 +33,7 @@ STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin,
|
||||
STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin,
|
||||
UInt64 *newPosition)
|
||||
{
|
||||
UInt64 newPos;
|
||||
@@ -76,7 +76,7 @@ STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin,
|
||||
|
||||
|
||||
/*
|
||||
class COutVolumeStream:
|
||||
class COutVolumeStream:
|
||||
public ISequentialOutStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
@@ -93,9 +93,9 @@ public:
|
||||
CFileItem _file;
|
||||
CUpdateOptions _options;
|
||||
CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;
|
||||
void Init(IArchiveUpdateCallback2 *volumeCallback,
|
||||
const UString &name)
|
||||
{
|
||||
void Init(IArchiveUpdateCallback2 *volumeCallback,
|
||||
const UString &name)
|
||||
{
|
||||
_file.Name = name;
|
||||
_file.IsStartPosDefined = true;
|
||||
_file.StartPos = 0;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "../../../Common/MyVector.h"
|
||||
#include "../../Archive/IArchive.h"
|
||||
|
||||
class CMultiStream:
|
||||
class CMultiStream:
|
||||
public IInStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
};
|
||||
|
||||
/*
|
||||
class COutMultiStream:
|
||||
class COutMultiStream:
|
||||
public IOutStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
#include "../../../Common/MyCom.h"
|
||||
#include "../../IStream.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../../C/7zCrc.h"
|
||||
}
|
||||
|
||||
class COutStreamWithCRC:
|
||||
class COutStreamWithCRC:
|
||||
public ISequentialOutStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "../../Crypto/Hash/Sha1.h"
|
||||
|
||||
|
||||
class COutStreamWithSha1:
|
||||
class COutStreamWithSha1:
|
||||
public ISequentialOutStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
|
||||
@@ -138,7 +138,7 @@ int ParseStringToUInt32(const UString &srcString, UInt32 &number)
|
||||
const wchar_t *start = srcString;
|
||||
const wchar_t *end;
|
||||
UInt64 number64 = ConvertStringToUInt64(start, &end);
|
||||
if (number64 > 0xFFFFFFFF)
|
||||
if (number64 > 0xFFFFFFFF)
|
||||
{
|
||||
number = 0;
|
||||
return 0;
|
||||
@@ -158,7 +158,7 @@ HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 default
|
||||
break;
|
||||
default:
|
||||
{
|
||||
bool val;
|
||||
bool val;
|
||||
RINOK(SetBoolProperty(val, prop));
|
||||
numThreads = (val ? defaultNumThreads : 1);
|
||||
break;
|
||||
|
||||
@@ -27,20 +27,20 @@ namespace NArchive {
|
||||
namespace NCpio {
|
||||
|
||||
/*
|
||||
enum // PropID
|
||||
enum
|
||||
{
|
||||
kpidinode = kpidUserDefined,
|
||||
kpidiChkSum
|
||||
};
|
||||
*/
|
||||
|
||||
STATPROPSTG kProps[] =
|
||||
STATPROPSTG kProps[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
{ NULL, kpidIsFolder, VT_BOOL},
|
||||
{ NULL, kpidIsDir, VT_BOOL},
|
||||
{ NULL, kpidSize, VT_UI8},
|
||||
{ NULL, kpidPackedSize, VT_UI8},
|
||||
{ NULL, kpidLastWriteTime, VT_FILETIME},
|
||||
{ NULL, kpidPackSize, VT_UI8},
|
||||
{ NULL, kpidMTime, VT_FILETIME},
|
||||
// { NULL, kpidUser, VT_BSTR},
|
||||
// { NULL, kpidGroup, VT_BSTR},
|
||||
// { L"inode", kpidinode, VT_UI4}
|
||||
@@ -50,27 +50,28 @@ STATPROPSTG kProps[] =
|
||||
IMP_IInArchive_Props
|
||||
IMP_IInArchive_ArcProps_NO
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
const UInt64 * /* maxCheckStartPosition */,
|
||||
IArchiveOpenCallback *openArchiveCallback)
|
||||
IArchiveOpenCallback *callback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
// try
|
||||
{
|
||||
CInArchive archive;
|
||||
|
||||
if (archive.Open(stream) != S_OK)
|
||||
return S_FALSE;
|
||||
UInt64 endPos = 0;
|
||||
bool needSetTotal = true;
|
||||
|
||||
if (callback != NULL)
|
||||
{
|
||||
RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos));
|
||||
RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
|
||||
}
|
||||
|
||||
RINOK(archive.Open(stream));
|
||||
|
||||
_items.Clear();
|
||||
|
||||
if (openArchiveCallback != NULL)
|
||||
{
|
||||
RINOK(openArchiveCallback->SetTotal(NULL, NULL));
|
||||
UInt64 numFiles = _items.Size();
|
||||
RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
CItemEx item;
|
||||
@@ -84,10 +85,19 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
break;
|
||||
_items.Add(item);
|
||||
archive.SkeepDataRecords(item.Size, item.Align);
|
||||
if (openArchiveCallback != NULL)
|
||||
if (callback != NULL)
|
||||
{
|
||||
UInt64 numFiles = _items.Size();
|
||||
RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
|
||||
if (needSetTotal)
|
||||
{
|
||||
RINOK(callback->SetTotal(NULL, &endPos));
|
||||
needSetTotal = false;
|
||||
}
|
||||
if (_items.Size() % 100 == 0)
|
||||
{
|
||||
UInt64 numFiles = _items.Size();
|
||||
UInt64 numBytes = item.HeaderPosition;
|
||||
RINOK(callback->SetCompleted(&numFiles, &numBytes));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_items.Size() == 0)
|
||||
@@ -127,17 +137,16 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
switch(propID)
|
||||
{
|
||||
case kpidPath:
|
||||
prop = (const wchar_t *)NItemName::GetOSName(
|
||||
MultiByteToUnicodeString(item.Name, CP_OEMCP));
|
||||
prop = NItemName::GetOSName(MultiByteToUnicodeString(item.Name, CP_OEMCP));
|
||||
break;
|
||||
case kpidIsFolder:
|
||||
prop = item.IsDirectory();
|
||||
case kpidIsDir:
|
||||
prop = item.IsDir();
|
||||
break;
|
||||
case kpidSize:
|
||||
case kpidPackedSize:
|
||||
case kpidPackSize:
|
||||
prop = (UInt64)item.Size;
|
||||
break;
|
||||
case kpidLastWriteTime:
|
||||
case kpidMTime:
|
||||
{
|
||||
FILETIME utcFileTime;
|
||||
if (item.ModificationTime != 0)
|
||||
@@ -151,12 +160,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
break;
|
||||
}
|
||||
/*
|
||||
case kpidinode:
|
||||
prop = item.inode;
|
||||
break;
|
||||
case kpidiChkSum:
|
||||
prop = item.ChkSum;
|
||||
break;
|
||||
case kpidinode: prop = item.inode; break;
|
||||
case kpidiChkSum: prop = item.ChkSum; break;
|
||||
*/
|
||||
}
|
||||
prop.Detach(value);
|
||||
@@ -199,14 +204,14 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
lps->InSize = lps->OutSize = currentTotalSize;
|
||||
RINOK(lps->SetCur());
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode = testMode ?
|
||||
Int32 askMode = testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
Int32 index = allFilesMode ? i : indices[i];
|
||||
const CItemEx &item = _items[index];
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
currentItemSize = item.Size;
|
||||
if (item.IsDirectory())
|
||||
if (item.IsDir())
|
||||
{
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
@@ -224,7 +229,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
streamSpec->Init(item.Size);
|
||||
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ?
|
||||
RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ?
|
||||
NArchive::NExtract::NOperationResult::kOK:
|
||||
NArchive::NExtract::NOperationResult::kDataError));
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
namespace NArchive {
|
||||
namespace NCpio {
|
||||
|
||||
class CHandler:
|
||||
class CHandler:
|
||||
public IInArchive,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace NArchive {
|
||||
namespace NCpio {
|
||||
namespace NFileHeader {
|
||||
|
||||
namespace NMagic
|
||||
namespace NMagic
|
||||
{
|
||||
extern const char *kMagic1 = "070701";
|
||||
extern const char *kMagic2 = "070702";
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace NCpio {
|
||||
|
||||
namespace NFileHeader
|
||||
{
|
||||
namespace NMagic
|
||||
namespace NMagic
|
||||
{
|
||||
extern const char *kMagic1;
|
||||
extern const char *kMagic2;
|
||||
@@ -56,7 +56,7 @@ namespace NFileHeader
|
||||
char NameSize[8]; // count includes terminating NUL in pathname
|
||||
char ChkSum[8]; // 0 for "new" portable format; for CRC format the sum of all the bytes in the file
|
||||
bool CheckMagic() const
|
||||
{ return memcmp(Magic, NMagic::kMagic1, 6) == 0 ||
|
||||
{ return memcmp(Magic, NMagic::kMagic1, 6) == 0 ||
|
||||
memcmp(Magic, NMagic::kMagic2, 6) == 0; };
|
||||
};
|
||||
*/
|
||||
|
||||
@@ -140,12 +140,12 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
|
||||
|
||||
UInt32 nameSize;
|
||||
|
||||
bool oldBE =
|
||||
bool oldBE =
|
||||
_block[0] == NFileHeader::NMagic::kMagicForRecord2[1] &&
|
||||
_block[1] == NFileHeader::NMagic::kMagicForRecord2[0];
|
||||
|
||||
bool binMode = (_block[0] == NFileHeader::NMagic::kMagicForRecord2[0] &&
|
||||
_block[1] == NFileHeader::NMagic::kMagicForRecord2[1]) ||
|
||||
_block[1] == NFileHeader::NMagic::kMagicForRecord2[1]) ||
|
||||
oldBE;
|
||||
|
||||
if (binMode)
|
||||
@@ -175,7 +175,7 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
|
||||
item.ChkSum = 0;
|
||||
item.HeaderSize = GetAlignedSize(
|
||||
nameSize + NFileHeader::kRecord2Size, item.Align);
|
||||
nameSize = item.HeaderSize - NFileHeader::kRecord2Size;
|
||||
nameSize = item.HeaderSize - NFileHeader::kRecord2Size;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -183,8 +183,8 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
|
||||
if (processedSize != 4)
|
||||
return S_FALSE;
|
||||
|
||||
bool magicOK =
|
||||
memcmp(_block, NFileHeader::NMagic::kMagic1, 6) == 0 ||
|
||||
bool magicOK =
|
||||
memcmp(_block, NFileHeader::NMagic::kMagic1, 6) == 0 ||
|
||||
memcmp(_block, NFileHeader::NMagic::kMagic2, 6) == 0;
|
||||
_blockPos = 6;
|
||||
if (magicOK)
|
||||
@@ -211,7 +211,7 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
|
||||
GetFromHex(item.ChkSum);
|
||||
item.HeaderSize = GetAlignedSize(
|
||||
nameSize + NFileHeader::kRecordSize, item.Align);
|
||||
nameSize = item.HeaderSize - NFileHeader::kRecordSize;
|
||||
nameSize = item.HeaderSize - NFileHeader::kRecordSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -237,7 +237,7 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
|
||||
GetFromOct11(item.Size); // ?????
|
||||
item.HeaderSize = GetAlignedSize(
|
||||
nameSize + NFileHeader::kOctRecordSize, item.Align);
|
||||
nameSize = item.HeaderSize - NFileHeader::kOctRecordSize;
|
||||
nameSize = item.HeaderSize - NFileHeader::kOctRecordSize;
|
||||
}
|
||||
}
|
||||
if (nameSize == 0 || nameSize >= (1 << 27))
|
||||
|
||||
@@ -34,7 +34,7 @@ struct CItem
|
||||
|
||||
UInt32 Align;
|
||||
|
||||
bool IsDirectory() const
|
||||
bool IsDir() const
|
||||
#ifdef _WIN32
|
||||
{ return (Mode & _S_IFMT) == _S_IFDIR; }
|
||||
#else
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
@@ -1,202 +0,0 @@
|
||||
// DebHandler.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "DebHandler.h"
|
||||
#include "DebIn.h"
|
||||
|
||||
#include "Common/Defs.h"
|
||||
#include "Common/StringConvert.h"
|
||||
#include "Common/NewHandler.h"
|
||||
#include "Common/ComTry.h"
|
||||
|
||||
#include "Windows/Time.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
|
||||
#include "../../Common/ProgressUtils.h"
|
||||
#include "../../Common/LimitedStreams.h"
|
||||
|
||||
#include "../../Compress/Copy/CopyCoder.h"
|
||||
|
||||
#include "../Common/ItemNameUtils.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NTime;
|
||||
|
||||
namespace NArchive {
|
||||
namespace NDeb {
|
||||
|
||||
STATPROPSTG kProps[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
{ NULL, kpidSize, VT_UI8},
|
||||
{ NULL, kpidPackedSize, VT_UI8},
|
||||
{ NULL, kpidLastWriteTime, VT_FILETIME}
|
||||
};
|
||||
|
||||
IMP_IInArchive_Props
|
||||
IMP_IInArchive_ArcProps_NO
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
const UInt64 * /* maxCheckStartPosition */,
|
||||
IArchiveOpenCallback *openArchiveCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
{
|
||||
CInArchive archive;
|
||||
if(archive.Open(stream) != S_OK)
|
||||
return S_FALSE;
|
||||
_items.Clear();
|
||||
|
||||
if (openArchiveCallback != NULL)
|
||||
{
|
||||
RINOK(openArchiveCallback->SetTotal(NULL, NULL));
|
||||
UInt64 numFiles = _items.Size();
|
||||
RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
CItemEx item;
|
||||
bool filled;
|
||||
HRESULT result = archive.GetNextItem(filled, item);
|
||||
if (result == S_FALSE)
|
||||
return S_FALSE;
|
||||
if (result != S_OK)
|
||||
return S_FALSE;
|
||||
if (!filled)
|
||||
break;
|
||||
_items.Add(item);
|
||||
archive.SkeepData(item.Size);
|
||||
if (openArchiveCallback != NULL)
|
||||
{
|
||||
UInt64 numFiles = _items.Size();
|
||||
RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
|
||||
}
|
||||
}
|
||||
_inStream = stream;
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Close()
|
||||
{
|
||||
_inStream.Release();
|
||||
_items.Clear();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
{
|
||||
*numItems = _items.Size();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
const CItemEx &item = _items[index];
|
||||
|
||||
switch(propID)
|
||||
{
|
||||
case kpidPath:
|
||||
prop = (const wchar_t *)NItemName::GetOSName2(
|
||||
MultiByteToUnicodeString(item.Name, CP_OEMCP));
|
||||
break;
|
||||
case kpidIsFolder:
|
||||
prop = false;
|
||||
break;
|
||||
case kpidSize:
|
||||
case kpidPackedSize:
|
||||
prop = item.Size;
|
||||
break;
|
||||
case kpidLastWriteTime:
|
||||
{
|
||||
FILETIME utcFileTime;
|
||||
if (item.ModificationTime != 0)
|
||||
NTime::UnixTimeToFileTime(item.ModificationTime, utcFileTime);
|
||||
else
|
||||
{
|
||||
utcFileTime.dwLowDateTime = 0;
|
||||
utcFileTime.dwHighDateTime = 0;
|
||||
}
|
||||
prop = utcFileTime;
|
||||
break;
|
||||
}
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool testMode = (_aTestMode != 0);
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
if (allFilesMode)
|
||||
numItems = _items.Size();
|
||||
if (numItems == 0)
|
||||
return S_OK;
|
||||
UInt64 totalSize = 0;
|
||||
UInt32 i;
|
||||
for (i = 0; i < numItems; i++)
|
||||
totalSize += _items[allFilesMode ? i : indices[i]].Size;
|
||||
extractCallback->SetTotal(totalSize);
|
||||
|
||||
UInt64 currentTotalSize = 0;
|
||||
UInt64 currentItemSize;
|
||||
|
||||
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
|
||||
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
|
||||
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(extractCallback, false);
|
||||
|
||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
||||
CMyComPtr<ISequentialInStream> inStream(streamSpec);
|
||||
streamSpec->SetStream(_inStream);
|
||||
|
||||
for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize)
|
||||
{
|
||||
lps->InSize = lps->OutSize = currentTotalSize;
|
||||
RINOK(lps->SetCur());
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode = testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
Int32 index = allFilesMode ? i : indices[i];
|
||||
const CItemEx &item = _items[index];
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
currentItemSize = item.Size;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (!testMode && (!realOutStream))
|
||||
continue;
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
if (testMode)
|
||||
{
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
continue;
|
||||
}
|
||||
RINOK(_inStream->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL));
|
||||
streamSpec->Init(item.Size);
|
||||
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ?
|
||||
NArchive::NExtract::NOperationResult::kOK:
|
||||
NArchive::NExtract::NOperationResult::kDataError));
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -1,13 +0,0 @@
|
||||
// Archive/Deb/Header.h
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "DebHeader.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NDeb {
|
||||
namespace NHeader {
|
||||
|
||||
const char *kSignature = "!<arch>\n";
|
||||
|
||||
}}}
|
||||
@@ -1,38 +0,0 @@
|
||||
// Archive/Deb/Header.h
|
||||
|
||||
#ifndef __ARCHIVE_DEB_HEADER_H
|
||||
#define __ARCHIVE_DEB_HEADER_H
|
||||
|
||||
#include "Common/Types.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NDeb {
|
||||
|
||||
namespace NHeader
|
||||
{
|
||||
const int kSignatureLen = 8;
|
||||
extern const char *kSignature;
|
||||
const int kNameSize = 16;
|
||||
const int kTimeSize = 12;
|
||||
const int kModeSize = 8;
|
||||
const int kSizeSize = 10;
|
||||
|
||||
/*
|
||||
struct CHeader
|
||||
{
|
||||
char Name[kNameSize];
|
||||
char ModificationTime[kTimeSize];
|
||||
char Number0[6];
|
||||
char Number1[6];
|
||||
char Mode[kModeSize];
|
||||
char Size[kSizeSize];
|
||||
char Quote;
|
||||
char NewLine;
|
||||
};
|
||||
*/
|
||||
const int kHeaderSize = kNameSize + kTimeSize + 6 + 6 + kModeSize + kSizeSize + 1 + 1;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -1,156 +0,0 @@
|
||||
// Archive/DebIn.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "DebIn.h"
|
||||
#include "DebHeader.h"
|
||||
|
||||
#include "Common/StringToInt.h"
|
||||
#include "Windows/Defs.h"
|
||||
|
||||
#include "../../Common/StreamUtils.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NDeb {
|
||||
|
||||
using namespace NHeader;
|
||||
|
||||
HRESULT CInArchive::Open(IInStream *inStream)
|
||||
{
|
||||
RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_Position));
|
||||
char signature[kSignatureLen];
|
||||
RINOK(ReadStream_FALSE(inStream, signature, kSignatureLen));
|
||||
m_Position += kSignatureLen;
|
||||
if (memcmp(signature, kSignature, kSignatureLen) != 0)
|
||||
return S_FALSE;
|
||||
m_Stream = inStream;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static void MyStrNCpy(char *dest, const char *src, int size)
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
char c = src[i];
|
||||
dest[i] = c;
|
||||
if (c == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static bool OctalToNumber(const char *s, int size, UInt64 &res)
|
||||
{
|
||||
char sz[32];
|
||||
MyStrNCpy(sz, s, size);
|
||||
sz[size] = 0;
|
||||
const char *end;
|
||||
int i;
|
||||
for (i = 0; sz[i] == ' '; i++);
|
||||
res = ConvertOctStringToUInt64(sz + i, &end);
|
||||
return (*end == ' ' || *end == 0);
|
||||
}
|
||||
|
||||
static bool OctalToNumber32(const char *s, int size, UInt32 &res)
|
||||
{
|
||||
UInt64 res64;
|
||||
if (!OctalToNumber(s, size, res64))
|
||||
return false;
|
||||
res = (UInt32)res64;
|
||||
return (res64 <= 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
static bool DecimalToNumber(const char *s, int size, UInt64 &res)
|
||||
{
|
||||
char sz[32];
|
||||
MyStrNCpy(sz, s, size);
|
||||
sz[size] = 0;
|
||||
const char *end;
|
||||
int i;
|
||||
for (i = 0; sz[i] == ' '; i++);
|
||||
res = ConvertStringToUInt64(sz + i, &end);
|
||||
return (*end == ' ' || *end == 0);
|
||||
}
|
||||
|
||||
static bool DecimalToNumber32(const char *s, int size, UInt32 &res)
|
||||
{
|
||||
UInt64 res64;
|
||||
if (!DecimalToNumber(s, size, res64))
|
||||
return false;
|
||||
res = (UInt32)res64;
|
||||
return (res64 <= 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
#define RIF(x) { if (!(x)) return S_FALSE; }
|
||||
|
||||
|
||||
HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item)
|
||||
{
|
||||
filled = false;
|
||||
|
||||
char header[NHeader::kHeaderSize];
|
||||
const char *cur = header;
|
||||
|
||||
size_t processedSize = sizeof(header);
|
||||
item.HeaderPosition = m_Position;
|
||||
RINOK(ReadStream(m_Stream, header, &processedSize));
|
||||
m_Position += processedSize;
|
||||
if (processedSize != sizeof(header))
|
||||
return S_OK;
|
||||
|
||||
char tempString[kNameSize + 1];
|
||||
MyStrNCpy(tempString, cur, kNameSize);
|
||||
cur += kNameSize;
|
||||
tempString[kNameSize] = '\0';
|
||||
item.Name = tempString;
|
||||
item.Name.Trim();
|
||||
|
||||
for (int i = 0; i < item.Name.Length(); i++)
|
||||
if (((Byte)item.Name[i]) < 0x20)
|
||||
return S_FALSE;
|
||||
|
||||
RIF(DecimalToNumber32(cur, kTimeSize, item.ModificationTime));
|
||||
cur += kTimeSize;
|
||||
|
||||
cur += 6 + 6;
|
||||
|
||||
RIF(OctalToNumber32(cur, kModeSize, item.Mode));
|
||||
cur += kModeSize;
|
||||
|
||||
RIF(DecimalToNumber(cur, kSizeSize, item.Size));
|
||||
cur += kSizeSize;
|
||||
|
||||
filled = true;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
RINOK(GetNextItemReal(filled, item));
|
||||
if (!filled)
|
||||
return S_OK;
|
||||
if (item.Name.CompareNoCase("debian-binary") != 0)
|
||||
return S_OK;
|
||||
if (item.Size != 4)
|
||||
return S_OK;
|
||||
SkeepData(item.Size);
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT CInArchive::Skeep(UInt64 numBytes)
|
||||
{
|
||||
UInt64 newPostion;
|
||||
RINOK(m_Stream->Seek(numBytes, STREAM_SEEK_CUR, &newPostion));
|
||||
m_Position += numBytes;
|
||||
if (m_Position != newPostion)
|
||||
return E_FAIL;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CInArchive::SkeepData(UInt64 dataSize)
|
||||
{
|
||||
return Skeep((dataSize + 1) & (~((UInt64)0x1)));
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -1,28 +0,0 @@
|
||||
// Archive/DebIn.h
|
||||
|
||||
#ifndef __ARCHIVE_DEB_IN_H
|
||||
#define __ARCHIVE_DEB_IN_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "../../IStream.h"
|
||||
#include "DebItem.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NDeb {
|
||||
|
||||
class CInArchive
|
||||
{
|
||||
CMyComPtr<IInStream> m_Stream;
|
||||
UInt64 m_Position;
|
||||
|
||||
HRESULT GetNextItemReal(bool &filled, CItemEx &itemInfo);
|
||||
HRESULT Skeep(UInt64 numBytes);
|
||||
public:
|
||||
HRESULT Open(IInStream *inStream);
|
||||
HRESULT GetNextItem(bool &filled, CItemEx &itemInfo);
|
||||
HRESULT SkeepData(UInt64 dataSize);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -1,32 +0,0 @@
|
||||
// Archive/Deb/ItemInfo.h
|
||||
|
||||
#ifndef __ARCHIVE_DEB_ITEMINFO_H
|
||||
#define __ARCHIVE_DEB_ITEMINFO_H
|
||||
|
||||
#include "Common/Types.h"
|
||||
#include "Common/MyString.h"
|
||||
#include "DebHeader.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NDeb {
|
||||
|
||||
class CItem
|
||||
{
|
||||
public:
|
||||
AString Name;
|
||||
UInt64 Size;
|
||||
UInt32 ModificationTime;
|
||||
UInt32 Mode;
|
||||
};
|
||||
|
||||
class CItemEx: public CItem
|
||||
{
|
||||
public:
|
||||
UInt64 HeaderPosition;
|
||||
UInt64 GetDataPosition() const { return HeaderPosition + NHeader::kHeaderSize; };
|
||||
// UInt64 GetFullSize() const { return NFileHeader::kRecordSize + Size; };
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -1,13 +0,0 @@
|
||||
// DebRegister.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../Common/RegisterArc.h"
|
||||
|
||||
#include "DebHandler.h"
|
||||
static IInArchive *CreateArc() { return new NArchive::NDeb::CHandler; }
|
||||
|
||||
static CArcInfo g_ArcInfo =
|
||||
{ L"Deb", L"deb", 0, 0xEC, { '!', '<', 'a', 'r', 'c', 'h', '>', '\n' }, 8, false, CreateArc, 0 };
|
||||
|
||||
REGISTER_ARC(Deb)
|
||||
@@ -1,3 +0,0 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user