mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-06 05:15:00 -06:00
3.13
This commit is contained in:
4
7zip/Archive/7z/7z.def
Executable file
4
7zip/Archive/7z/7z.def
Executable file
@@ -0,0 +1,4 @@
|
||||
EXPORTS
|
||||
CreateObject PRIVATE
|
||||
GetHandlerProperty PRIVATE
|
||||
|
||||
533
7zip/Archive/7z/7z.dsp
Executable file
533
7zip/Archive/7z/7z.dsp
Executable file
@@ -0,0 +1,533 @@
|
||||
# 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 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /Yu"StdAfx.h" /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
# 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 /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||
# 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=.\7z.def
|
||||
# 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=.\7zMethodID.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zMethodID.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zMethods.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zMethods.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=.\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=..\..\ICoderProperties.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\CRC.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\IntToString.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\IntToString.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\String.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\String.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\StringConvert.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\StringConvert.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\StringToInt.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\StringToInt.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Vector.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Vector.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Archive Common"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\CodecsPath.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\CodecsPath.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\CoderLoader.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\CoderMixer2.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\CoderMixer2.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\CrossThreadProgress.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\CrossThreadProgress.h
|
||||
# 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\OutStreamWithCRC.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\OutStreamWithCRC.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "7-Zip Common"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# 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\MultiStream.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\MultiStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\OutBuffer.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\OutBuffer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\ProgressUtils.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\ProgressUtils.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\StreamBinder.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\StreamBinder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\StreamObjects.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\StreamObjects.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# 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\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 Source File
|
||||
|
||||
SOURCE=.\7z.ico
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
29
7zip/Archive/7z/7z.dsw
Executable file
29
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>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
BIN
7zip/Archive/7z/7z.ico
Executable file
BIN
7zip/Archive/7z/7z.ico
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 4.6 KiB |
3
7zip/Archive/7z/7zCompressionMode.cpp
Executable file
3
7zip/Archive/7z/7zCompressionMode.cpp
Executable file
@@ -0,0 +1,3 @@
|
||||
// CompressionMethod.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
60
7zip/Archive/7z/7zCompressionMode.h
Executable file
60
7zip/Archive/7z/7zCompressionMode.h
Executable file
@@ -0,0 +1,60 @@
|
||||
// 7zCompressionMode.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __7Z_COMPRESSION_MODE_H
|
||||
#define __7Z_COMPRESSION_MODE_H
|
||||
|
||||
#include "../../../Windows/PropVariant.h"
|
||||
|
||||
#include "7zMethodID.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
struct CProperty
|
||||
{
|
||||
PROPID PropID;
|
||||
NWindows::NCOM::CPropVariant Value;
|
||||
};
|
||||
|
||||
struct CMethodFull
|
||||
{
|
||||
CMethodID MethodID;
|
||||
UINT32 NumInStreams;
|
||||
UINT32 NumOutStreams;
|
||||
bool IsSimpleCoder() const
|
||||
{ return (NumInStreams == 1) && (NumOutStreams == 1); }
|
||||
|
||||
#ifdef EXCLUDE_COM
|
||||
#else
|
||||
CLSID EncoderClassID;
|
||||
CSysString FilePath;
|
||||
#endif
|
||||
|
||||
CObjectVector<CProperty> CoderProperties;
|
||||
};
|
||||
|
||||
struct CBind
|
||||
{
|
||||
UINT32 InCoder;
|
||||
UINT32 InStream;
|
||||
UINT32 OutCoder;
|
||||
UINT32 OutStream;
|
||||
};
|
||||
|
||||
struct CCompressionMethodMode
|
||||
{
|
||||
CObjectVector<CMethodFull> Methods;
|
||||
CRecordVector<CBind> Binds;
|
||||
bool MultiThread;
|
||||
bool PasswordIsDefined;
|
||||
UString Password;
|
||||
|
||||
bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); }
|
||||
CCompressionMethodMode(): PasswordIsDefined(false), MultiThread(false) {}
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
377
7zip/Archive/7z/7zDecode.cpp
Executable file
377
7zip/Archive/7z/7zDecode.cpp
Executable file
@@ -0,0 +1,377 @@
|
||||
// Decode.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "7zDecode.h"
|
||||
|
||||
#include "../../Common/MultiStream.h"
|
||||
#include "../../Common/StreamObjects.h"
|
||||
#include "../../Common/ProgressUtils.h"
|
||||
#include "../../Common/LimitedStreams.h"
|
||||
|
||||
#include "7zMethods.h"
|
||||
|
||||
#include "../../IPassword.h"
|
||||
|
||||
|
||||
#ifdef COMPRESS_LZMA
|
||||
#include "../../Compress/LZMA/LZMADecoder.h"
|
||||
static NArchive::N7z::CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_PPMD
|
||||
#include "../../Compress/PPMD/PPMDDecoder.h"
|
||||
static NArchive::N7z::CMethodID k_PPMD = { { 0x3, 0x4, 0x1 }, 3 };
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_BCJ_X86
|
||||
#include "../../Compress/Branch/x86.h"
|
||||
static NArchive::N7z::CMethodID k_BCJ_X86 = { { 0x3, 0x3, 0x1, 0x3 }, 4 };
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_BCJ2
|
||||
#include "../../Compress/Branch/x86_2.h"
|
||||
static NArchive::N7z::CMethodID k_BCJ2 = { { 0x3, 0x3, 0x1, 0x1B }, 4 };
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_DEFLATE
|
||||
#include "../../Compress/Deflate/DeflateDecoder.h"
|
||||
static NArchive::N7z::CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 };
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_BZIP2
|
||||
#include "../../Compress/BZip2/BZip2Decoder.h"
|
||||
static NArchive::N7z::CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 };
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_COPY
|
||||
#include "../../Compress/Copy/CopyCoder.h"
|
||||
static NArchive::N7z::CMethodID k_Copy = { { 0x0 }, 1 };
|
||||
#endif
|
||||
|
||||
#ifdef CRYPTO_7ZAES
|
||||
#include "../../Crypto/7zAES/7zAES.h"
|
||||
static NArchive::N7z::CMethodID k_7zAES = { { 0x6, 0xF1, 0x07, 0x01 }, 4 };
|
||||
#endif
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
static void ConvertFolderItemInfoToBindInfo(const CFolder &folder,
|
||||
CBindInfoEx &bindInfo)
|
||||
{
|
||||
bindInfo.Coders.Clear();
|
||||
bindInfo.CoderMethodIDs.Clear();
|
||||
bindInfo.OutStreams.Clear();
|
||||
bindInfo.InStreams.Clear();
|
||||
bindInfo.BindPairs.Clear();
|
||||
int i;
|
||||
for (i = 0; i < folder.BindPairs.Size(); i++)
|
||||
{
|
||||
NCoderMixer2::CBindPair bindPair;
|
||||
bindPair.InIndex = (UINT32)folder.BindPairs[i].InIndex;
|
||||
bindPair.OutIndex = (UINT32)folder.BindPairs[i].OutIndex;
|
||||
bindInfo.BindPairs.Add(bindPair);
|
||||
}
|
||||
UINT32 outStreamIndex = 0;
|
||||
for (i = 0; i < folder.Coders.Size(); i++)
|
||||
{
|
||||
NCoderMixer2::CCoderStreamsInfo coderStreamsInfo;
|
||||
const CCoderInfo &coderInfo = folder.Coders[i];
|
||||
coderStreamsInfo.NumInStreams = (UINT32)coderInfo.NumInStreams;
|
||||
coderStreamsInfo.NumOutStreams = (UINT32)coderInfo.NumOutStreams;
|
||||
bindInfo.Coders.Add(coderStreamsInfo);
|
||||
const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front();
|
||||
bindInfo.CoderMethodIDs.Add(altCoderInfo.MethodID);
|
||||
for (UINT32 j = 0; j < coderStreamsInfo.NumOutStreams; j++, outStreamIndex++)
|
||||
if (folder.FindBindPairForOutStream(outStreamIndex) < 0)
|
||||
bindInfo.OutStreams.Add(outStreamIndex);
|
||||
}
|
||||
for (i = 0; i < folder.PackStreams.Size(); i++)
|
||||
bindInfo.InStreams.Add((UINT32)folder.PackStreams[i].Index);
|
||||
}
|
||||
|
||||
static bool AreCodersEqual(const NCoderMixer2::CCoderStreamsInfo &a1,
|
||||
const NCoderMixer2::CCoderStreamsInfo &a2)
|
||||
{
|
||||
return (a1.NumInStreams == a2.NumInStreams) &&
|
||||
(a1.NumOutStreams == a2.NumOutStreams);
|
||||
}
|
||||
|
||||
static bool AreBindPairsEqual(const NCoderMixer2::CBindPair &a1, const NCoderMixer2::CBindPair &a2)
|
||||
{
|
||||
return (a1.InIndex == a2.InIndex) &&
|
||||
(a1.OutIndex == a2.OutIndex);
|
||||
}
|
||||
|
||||
static bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2)
|
||||
{
|
||||
if (a1.Coders.Size() != a2.Coders.Size())
|
||||
return false;
|
||||
int i;
|
||||
for (i = 0; i < a1.Coders.Size(); i++)
|
||||
if (!AreCodersEqual(a1.Coders[i], a2.Coders[i]))
|
||||
return false;
|
||||
if (a1.BindPairs.Size() != a2.BindPairs.Size())
|
||||
return false;
|
||||
for (i = 0; i < a1.BindPairs.Size(); i++)
|
||||
if (!AreBindPairsEqual(a1.BindPairs[i], a2.BindPairs[i]))
|
||||
return false;
|
||||
for (i = 0; i < a1.CoderMethodIDs.Size(); i++)
|
||||
if (a1.CoderMethodIDs[i] != a2.CoderMethodIDs[i])
|
||||
return false;
|
||||
if (a1.InStreams.Size() != a2.InStreams.Size())
|
||||
return false;
|
||||
if (a1.OutStreams.Size() != a2.OutStreams.Size())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
CDecoder::CDecoder()
|
||||
{
|
||||
_bindInfoExPrevIsDefinded = false;
|
||||
#ifndef EXCLUDE_COM
|
||||
LoadMethodMap();
|
||||
#endif
|
||||
}
|
||||
|
||||
HRESULT CDecoder::Decode(IInStream *inStream,
|
||||
UINT64 startPos,
|
||||
const UINT64 *packSizes,
|
||||
const CFolder &folderInfo,
|
||||
ISequentialOutStream *outStream,
|
||||
ICompressProgressInfo *compressProgress
|
||||
#ifndef _NO_CRYPTO
|
||||
, ICryptoGetTextPassword *getTextPassword
|
||||
#endif
|
||||
)
|
||||
{
|
||||
CObjectVector< CMyComPtr<ISequentialInStream> > inStreams;
|
||||
|
||||
CLockedInStream lockedInStream;
|
||||
lockedInStream.Init(inStream);
|
||||
|
||||
for (int j = 0; j < folderInfo.PackStreams.Size(); j++)
|
||||
{
|
||||
CLockedSequentialInStreamImp *lockedStreamImpSpec = new
|
||||
CLockedSequentialInStreamImp;
|
||||
CMyComPtr<ISequentialInStream> lockedStreamImp = lockedStreamImpSpec;
|
||||
lockedStreamImpSpec->Init(&lockedInStream, startPos);
|
||||
startPos += packSizes[j];
|
||||
|
||||
CLimitedSequentialInStream *streamSpec = new
|
||||
CLimitedSequentialInStream;
|
||||
CMyComPtr<ISequentialInStream> inStream = streamSpec;
|
||||
streamSpec->Init(lockedStreamImp, packSizes[j]);
|
||||
inStreams.Add(inStream);
|
||||
}
|
||||
|
||||
int numCoders = folderInfo.Coders.Size();
|
||||
|
||||
CBindInfoEx bindInfo;
|
||||
ConvertFolderItemInfoToBindInfo(folderInfo, bindInfo);
|
||||
bool createNewCoders;
|
||||
if (!_bindInfoExPrevIsDefinded)
|
||||
createNewCoders = true;
|
||||
else
|
||||
createNewCoders = !AreBindInfoExEqual(bindInfo, _bindInfoExPrev);
|
||||
if (createNewCoders)
|
||||
{
|
||||
int i;
|
||||
_decoders.Clear();
|
||||
// _decoders2.Clear();
|
||||
|
||||
_mixerCoder.Release();
|
||||
|
||||
_mixerCoderSpec = new NCoderMixer2::CCoderMixer2;
|
||||
_mixerCoder = _mixerCoderSpec;
|
||||
|
||||
_mixerCoderSpec->SetBindInfo(bindInfo);
|
||||
for (i = 0; i < numCoders; i++)
|
||||
{
|
||||
const CCoderInfo &coderInfo = folderInfo.Coders[i];
|
||||
const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front();
|
||||
#ifndef EXCLUDE_COM
|
||||
CMethodInfo methodInfo;
|
||||
if (!GetMethodInfo(altCoderInfo.MethodID, methodInfo))
|
||||
return E_NOTIMPL;
|
||||
#endif
|
||||
|
||||
if (coderInfo.IsSimpleCoder())
|
||||
{
|
||||
CMyComPtr<ICompressCoder> decoder;
|
||||
|
||||
#ifdef COMPRESS_LZMA
|
||||
if (altCoderInfo.MethodID == k_LZMA)
|
||||
decoder = new NCompress::NLZMA::CDecoder;
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_PPMD
|
||||
if (altCoderInfo.MethodID == k_PPMD)
|
||||
decoder = new NCompress::NPPMD::CDecoder;
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_BCJ_X86
|
||||
if (altCoderInfo.MethodID == k_BCJ_X86)
|
||||
decoder = new CBCJ_x86_Decoder;
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_DEFLATE
|
||||
if (altCoderInfo.MethodID == k_Deflate)
|
||||
decoder = new NCompress::NDeflate::NDecoder::CCOMCoder;
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_BZIP2
|
||||
if (altCoderInfo.MethodID == k_BZip2)
|
||||
decoder = new NCompress::NBZip2::CDecoder;
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_COPY
|
||||
if (altCoderInfo.MethodID == k_Copy)
|
||||
decoder = new NCompress::CCopyCoder;
|
||||
#endif
|
||||
|
||||
#ifdef CRYPTO_7ZAES
|
||||
if (altCoderInfo.MethodID == k_7zAES)
|
||||
decoder = new NCrypto::NSevenZ::CDecoder;
|
||||
#endif
|
||||
|
||||
#ifndef EXCLUDE_COM
|
||||
if (decoder == 0)
|
||||
{
|
||||
RINOK(_libraries.CreateCoder(methodInfo.FilePath,
|
||||
methodInfo.Decoder, &decoder));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (decoder == 0)
|
||||
return E_NOTIMPL;
|
||||
|
||||
_decoders.Add((IUnknown *)decoder);
|
||||
|
||||
_mixerCoderSpec->AddCoder(decoder);
|
||||
}
|
||||
else
|
||||
{
|
||||
CMyComPtr<ICompressCoder2> decoder;
|
||||
|
||||
#ifdef COMPRESS_BCJ2
|
||||
if (altCoderInfo.MethodID == k_BCJ2)
|
||||
decoder = new CBCJ2_x86_Decoder;
|
||||
#endif
|
||||
|
||||
#ifndef EXCLUDE_COM
|
||||
if (decoder == 0)
|
||||
{
|
||||
RINOK(_libraries.CreateCoder2(methodInfo.FilePath,
|
||||
methodInfo.Decoder, &decoder));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (decoder == 0)
|
||||
return E_NOTIMPL;
|
||||
|
||||
_decoders.Add((IUnknown *)decoder);
|
||||
_mixerCoderSpec->AddCoder2(decoder);
|
||||
}
|
||||
}
|
||||
_bindInfoExPrev = bindInfo;
|
||||
_bindInfoExPrevIsDefinded = true;
|
||||
}
|
||||
int i;
|
||||
_mixerCoderSpec->ReInit();
|
||||
|
||||
UINT32 packStreamIndex = 0, unPackStreamIndex = 0;
|
||||
UINT32 coderIndex = 0;
|
||||
// UINT32 coder2Index = 0;
|
||||
|
||||
for (i = 0; i < numCoders; i++)
|
||||
{
|
||||
const CCoderInfo &coderInfo = folderInfo.Coders[i];
|
||||
const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front();
|
||||
CMyComPtr<ICompressSetDecoderProperties> compressSetDecoderProperties;
|
||||
HRESULT result = _decoders[coderIndex].QueryInterface(
|
||||
IID_ICompressSetDecoderProperties, &compressSetDecoderProperties);
|
||||
|
||||
if (result == S_OK)
|
||||
{
|
||||
const CByteBuffer &properties = altCoderInfo.Properties;
|
||||
UINT32 size = properties.GetCapacity();
|
||||
if (size > 0)
|
||||
{
|
||||
CSequentialInStreamImp *inStreamSpec = new CSequentialInStreamImp;
|
||||
CMyComPtr<ISequentialInStream> inStream(inStreamSpec);
|
||||
inStreamSpec->Init((const BYTE *)properties, size);
|
||||
RINOK(compressSetDecoderProperties->SetDecoderProperties(inStream));
|
||||
}
|
||||
}
|
||||
else if (result != E_NOINTERFACE)
|
||||
return result;
|
||||
|
||||
#ifndef _NO_CRYPTO
|
||||
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
|
||||
result = _decoders[coderIndex].QueryInterface(
|
||||
IID_ICryptoSetPassword, &cryptoSetPassword);
|
||||
|
||||
if (result == S_OK)
|
||||
{
|
||||
if (getTextPassword == 0)
|
||||
return E_FAIL;
|
||||
CMyComBSTR password;
|
||||
RINOK(getTextPassword->CryptoGetTextPassword(&password));
|
||||
UString unicodePassword(password);
|
||||
RINOK(cryptoSetPassword->CryptoSetPassword(
|
||||
(const BYTE *)(const wchar_t *)unicodePassword,
|
||||
unicodePassword.Length() * sizeof(wchar_t)));
|
||||
}
|
||||
else if (result != E_NOINTERFACE)
|
||||
return result;
|
||||
#endif
|
||||
|
||||
coderIndex++;
|
||||
|
||||
UINT32 numInStreams = (UINT32)coderInfo.NumInStreams;
|
||||
UINT32 numOutStreams = (UINT32)coderInfo.NumOutStreams;
|
||||
CRecordVector<const UINT64 *> packSizesPointers;
|
||||
CRecordVector<const UINT64 *> unPackSizesPointers;
|
||||
packSizesPointers.Reserve(numInStreams);
|
||||
unPackSizesPointers.Reserve(numOutStreams);
|
||||
UINT32 j;
|
||||
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]);
|
||||
else
|
||||
{
|
||||
int index = folderInfo.FindPackStreamArrayIndex(packStreamIndex);
|
||||
if (index < 0)
|
||||
return E_FAIL;
|
||||
packSizesPointers.Add(&packSizes[index]);
|
||||
}
|
||||
}
|
||||
|
||||
_mixerCoderSpec->SetCoderInfo(i,
|
||||
&packSizesPointers.Front(),
|
||||
&unPackSizesPointers.Front());
|
||||
}
|
||||
UINT32 mainCoder, temp;
|
||||
bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp);
|
||||
_mixerCoderSpec->SetProgressCoderIndex(mainCoder);
|
||||
|
||||
if (numCoders == 0)
|
||||
return 0;
|
||||
CRecordVector<ISequentialInStream *> inStreamPointers;
|
||||
inStreamPointers.Reserve(inStreams.Size());
|
||||
for (i = 0; i < inStreams.Size(); i++)
|
||||
inStreamPointers.Add(inStreams[i]);
|
||||
ISequentialOutStream *outStreamPointer = outStream;
|
||||
return _mixerCoderSpec->Code(&inStreamPointers.Front(), NULL,
|
||||
inStreams.Size(), &outStreamPointer, NULL, 1, compressProgress);
|
||||
}
|
||||
|
||||
}}
|
||||
54
7zip/Archive/7z/7zDecode.h
Executable file
54
7zip/Archive/7z/7zDecode.h
Executable file
@@ -0,0 +1,54 @@
|
||||
// 7zDecode.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __7Z_DECODE_H
|
||||
#define __7Z_DECODE_H
|
||||
|
||||
#include "../../IStream.h"
|
||||
#include "../../IPassword.h"
|
||||
|
||||
#include "../Common/CoderMixer2.h"
|
||||
#ifndef EXCLUDE_COM
|
||||
#include "../Common/CoderLoader.h"
|
||||
#endif
|
||||
|
||||
#include "7zItem.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
struct CBindInfoEx: public NCoderMixer2::CBindInfo
|
||||
{
|
||||
CRecordVector<CMethodID> CoderMethodIDs;
|
||||
};
|
||||
|
||||
class CDecoder
|
||||
{
|
||||
#ifndef EXCLUDE_COM
|
||||
CCoderLibraries _libraries;
|
||||
#endif
|
||||
|
||||
bool _bindInfoExPrevIsDefinded;
|
||||
CBindInfoEx _bindInfoExPrev;
|
||||
NCoderMixer2::CCoderMixer2 *_mixerCoderSpec;
|
||||
CMyComPtr<ICompressCoder2> _mixerCoder;
|
||||
CObjectVector<CMyComPtr<IUnknown> > _decoders;
|
||||
// CObjectVector<CMyComPtr<ICompressCoder2> > _decoders2;
|
||||
public:
|
||||
CDecoder();
|
||||
HRESULT Decode(IInStream *inStream,
|
||||
UINT64 startPos,
|
||||
const UINT64 *packSizes,
|
||||
const CFolder &folder,
|
||||
ISequentialOutStream *outStream,
|
||||
ICompressProgressInfo *compressProgress
|
||||
#ifndef _NO_CRYPTO
|
||||
, ICryptoGetTextPassword *getTextPasswordSpec
|
||||
#endif
|
||||
);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
570
7zip/Archive/7z/7zEncode.cpp
Executable file
570
7zip/Archive/7z/7zEncode.cpp
Executable file
@@ -0,0 +1,570 @@
|
||||
// Encode.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "7zEncode.h"
|
||||
#include "7zSpecStream.h"
|
||||
#include "7zMethods.h"
|
||||
|
||||
#include "../../IPassword.h"
|
||||
#include "../../Common/ProgressUtils.h"
|
||||
#include "../../Common/LimitedStreams.h"
|
||||
#include "../../Common/InOutTempBuffer.h"
|
||||
#include "../../Common/StreamObjects.h"
|
||||
|
||||
#ifdef COMPRESS_COPY
|
||||
static NArchive::N7z::CMethodID k_Copy = { { 0x0 }, 1 };
|
||||
#include "../../Compress/Copy/CopyCoder.h"
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_LZMA
|
||||
#include "../../Compress/LZMA/LZMAEncoder.h"
|
||||
static NArchive::N7z::CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_PPMD
|
||||
#include "../../Compress/PPMD/PPMDEncoder.h"
|
||||
static NArchive::N7z::CMethodID k_PPMD = { { 0x3, 0x4, 0x1 }, 3 };
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_BCJ_X86
|
||||
static NArchive::N7z::CMethodID k_BCJ_X86 = { { 0x3, 0x3, 0x1, 0x3 }, 4 };
|
||||
#include "../../Compress/Branch/x86.h"
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_BCJ2
|
||||
static NArchive::N7z::CMethodID k_BCJ2 = { { 0x3, 0x3, 0x1, 0x1B }, 4 };
|
||||
#include "../../Compress/Branch/x86_2.h"
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_DEFLATE
|
||||
#include "../../Compress/Deflate/DeflateEncoder.h"
|
||||
static NArchive::N7z::CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 };
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_BZIP2
|
||||
#include "../../Compress/BZip2/BZip2Encoder.h"
|
||||
static NArchive::N7z::CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 };
|
||||
#endif
|
||||
|
||||
static NArchive::N7z::CMethodID k_AES = { { 0x6, 0xF1, 0x7, 0x1}, 4 };
|
||||
|
||||
#ifndef EXCLUDE_COM
|
||||
static const wchar_t *kCryproMethod = L"7zAES";
|
||||
/*
|
||||
// {23170F69-40C1-278B-06F1-070100000100}
|
||||
DEFINE_GUID(CLSID_CCrypto7zAESEncoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x07, 0x01, 0x00, 0x00, 0x01, 0x00);
|
||||
*/
|
||||
#endif
|
||||
|
||||
#ifdef CRYPTO_7ZAES
|
||||
#include "../../Crypto/7zAES/7zAES.h"
|
||||
#endif
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
static void ConvertBindInfoToFolderItemInfo(const NCoderMixer2::CBindInfo &bindInfo,
|
||||
const CRecordVector<CMethodID> decompressionMethods,
|
||||
CFolder &folder)
|
||||
{
|
||||
folder.Coders.Clear();
|
||||
// bindInfo.CoderMethodIDs.Clear();
|
||||
// folder.OutStreams.Clear();
|
||||
folder.PackStreams.Clear();
|
||||
folder.BindPairs.Clear();
|
||||
int i;
|
||||
for (i = 0; i < bindInfo.BindPairs.Size(); i++)
|
||||
{
|
||||
CBindPair bindPair;
|
||||
bindPair.InIndex = bindInfo.BindPairs[i].InIndex;
|
||||
bindPair.OutIndex = bindInfo.BindPairs[i].OutIndex;
|
||||
folder.BindPairs.Add(bindPair);
|
||||
}
|
||||
for (i = 0; i < bindInfo.Coders.Size(); i++)
|
||||
{
|
||||
CCoderInfo coderInfo;
|
||||
const NCoderMixer2::CCoderStreamsInfo &coderStreamsInfo = bindInfo.Coders[i];
|
||||
coderInfo.NumInStreams = coderStreamsInfo.NumInStreams;
|
||||
coderInfo.NumOutStreams = coderStreamsInfo.NumOutStreams;
|
||||
|
||||
// coderInfo.MethodID = decompressionMethods[i];
|
||||
// if (coderInfo.AltCoders.Size() == 0)
|
||||
coderInfo.AltCoders.Add(CAltCoderInfo());
|
||||
CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front();
|
||||
altCoderInfo.MethodID = decompressionMethods[i];
|
||||
|
||||
folder.Coders.Add(coderInfo);
|
||||
}
|
||||
for (i = 0; i < bindInfo.InStreams.Size(); i++)
|
||||
{
|
||||
CPackStreamInfo packStreamInfo;
|
||||
packStreamInfo.Index = bindInfo.InStreams[i];
|
||||
folder.PackStreams.Add(packStreamInfo);
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT CEncoder::CreateMixerCoder()
|
||||
{
|
||||
_mixerCoderSpec = new NCoderMixer2::CCoderMixer2;
|
||||
_mixerCoder = _mixerCoderSpec;
|
||||
_mixerCoderSpec->SetBindInfo(_bindInfo);
|
||||
for (int i = 0; i < _options.Methods.Size(); i++)
|
||||
{
|
||||
const CMethodFull &methodFull = _options.Methods[i];
|
||||
_codersInfo.Add(CCoderInfo());
|
||||
CCoderInfo &encodingInfo = _codersInfo.Back();
|
||||
CMyComPtr<ICompressCoder> encoder;
|
||||
CMyComPtr<ICompressCoder2> encoder2;
|
||||
|
||||
if (methodFull.IsSimpleCoder())
|
||||
{
|
||||
#ifdef COMPRESS_LZMA
|
||||
if (methodFull.MethodID == k_LZMA)
|
||||
encoder = new NCompress::NLZMA::CEncoder;
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_PPMD
|
||||
if (methodFull.MethodID == k_PPMD)
|
||||
encoder = new NCompress::NPPMD::CEncoder;
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_BCJ_X86
|
||||
if (methodFull.MethodID == k_BCJ_X86)
|
||||
encoder = new CBCJ_x86_Encoder;
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_COPY
|
||||
if (methodFull.MethodID == k_Copy)
|
||||
encoder = new NCompress::CCopyCoder;
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_BZIP2
|
||||
if (methodFull.MethodID == k_BZip2)
|
||||
encoder = new NCompress::NBZip2::CEncoder;
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_DEFLATE
|
||||
if (methodFull.MethodID == k_Deflate)
|
||||
encoder = new NCompress::NDeflate::NEncoder::CCOMCoder;
|
||||
#endif
|
||||
|
||||
#ifdef CRYPTO_7ZAES
|
||||
if (methodFull.MethodID == k_AES)
|
||||
encoder = new NCrypto::NSevenZ::CEncoder;
|
||||
#endif
|
||||
|
||||
#ifndef EXCLUDE_COM
|
||||
if (encoder == 0)
|
||||
{
|
||||
RINOK(_libraries.CreateCoder(methodFull.FilePath,
|
||||
methodFull.EncoderClassID, &encoder));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (encoder == 0)
|
||||
return E_FAIL;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef COMPRESS_BCJ2
|
||||
if (methodFull.MethodID == k_BCJ2)
|
||||
encoder2 = new CBCJ2_x86_Encoder;
|
||||
#endif
|
||||
|
||||
#ifndef EXCLUDE_COM
|
||||
if (encoder2 == 0)
|
||||
{
|
||||
RINOK(_libraries.CreateCoder2(methodFull.FilePath,
|
||||
methodFull.EncoderClassID, &encoder2));
|
||||
}
|
||||
#else
|
||||
|
||||
if (encoder2 == 0)
|
||||
return E_FAIL;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (methodFull.CoderProperties.Size() > 0)
|
||||
{
|
||||
std::vector<NWindows::NCOM::CPropVariant> properties;
|
||||
std::vector<PROPID> propIDs;
|
||||
INT32 numProperties = methodFull.CoderProperties.Size();
|
||||
for (int i = 0; i < numProperties; i++)
|
||||
{
|
||||
const CProperty &property = methodFull.CoderProperties[i];
|
||||
propIDs.push_back(property.PropID);
|
||||
properties.push_back(property.Value);
|
||||
}
|
||||
CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
|
||||
if (methodFull.IsSimpleCoder())
|
||||
{
|
||||
RINOK(encoder.QueryInterface(IID_ICompressSetCoderProperties,
|
||||
&setCoderProperties));
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(encoder2.QueryInterface(IID_ICompressSetCoderProperties,
|
||||
&setCoderProperties));
|
||||
}
|
||||
|
||||
RINOK(setCoderProperties->SetCoderProperties(&propIDs.front(),
|
||||
&properties.front(), numProperties));
|
||||
}
|
||||
|
||||
CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
|
||||
|
||||
if (methodFull.IsSimpleCoder())
|
||||
{
|
||||
encoder.QueryInterface(IID_ICompressWriteCoderProperties,
|
||||
&writeCoderProperties);
|
||||
}
|
||||
else
|
||||
{
|
||||
encoder2.QueryInterface(IID_ICompressWriteCoderProperties,
|
||||
&writeCoderProperties);
|
||||
}
|
||||
|
||||
if (writeCoderProperties != NULL)
|
||||
{
|
||||
CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp;
|
||||
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
|
||||
outStreamSpec->Init();
|
||||
writeCoderProperties->WriteCoderProperties(outStream);
|
||||
|
||||
UINT32 size = outStreamSpec->GetSize();
|
||||
|
||||
// encodingInfo.Properties.SetCapacity(size);
|
||||
if (encodingInfo.AltCoders.Size() == 0)
|
||||
encodingInfo.AltCoders.Add(CAltCoderInfo());
|
||||
CAltCoderInfo &altCoderInfo = encodingInfo.AltCoders.Front();
|
||||
altCoderInfo.Properties.SetCapacity(size);
|
||||
|
||||
memmove(altCoderInfo.Properties, outStreamSpec->GetBuffer(), size);
|
||||
}
|
||||
|
||||
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
|
||||
if (methodFull.IsSimpleCoder())
|
||||
{
|
||||
encoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
|
||||
}
|
||||
else
|
||||
{
|
||||
encoder2.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
|
||||
}
|
||||
|
||||
if (cryptoSetPassword)
|
||||
{
|
||||
RINOK(cryptoSetPassword->CryptoSetPassword(
|
||||
(const BYTE *)(const wchar_t *)_options.Password,
|
||||
_options.Password.Length() * sizeof(wchar_t)));
|
||||
}
|
||||
|
||||
// public ICompressWriteCoderProperties,
|
||||
if (methodFull.IsSimpleCoder())
|
||||
{
|
||||
_mixerCoderSpec->AddCoder(encoder);
|
||||
}
|
||||
else
|
||||
{
|
||||
_mixerCoderSpec->AddCoder2(encoder2);
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CEncoder::Encode(ISequentialInStream *inStream,
|
||||
const UINT64 *inStreamSize,
|
||||
CFolder &folderItem,
|
||||
ISequentialOutStream *outStream,
|
||||
CRecordVector<UINT64> &packSizes,
|
||||
ICompressProgressInfo *compressProgress)
|
||||
{
|
||||
if (_mixerCoderSpec == NULL)
|
||||
{
|
||||
RINOK(CreateMixerCoder());
|
||||
}
|
||||
_mixerCoderSpec->ReInit();
|
||||
// _mixerCoderSpec->SetCoderInfo(0, NULL, NULL, progress);
|
||||
|
||||
CObjectVector<CInOutTempBuffer> inOutTempBuffers;
|
||||
CObjectVector<CSequentialOutTempBufferImp *> tempBufferSpecs;
|
||||
CObjectVector<CMyComPtr<ISequentialOutStream> > tempBuffers;
|
||||
int numMethods = _bindInfo.Coders.Size();
|
||||
int i;
|
||||
for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
|
||||
{
|
||||
inOutTempBuffers.Add(CInOutTempBuffer());
|
||||
inOutTempBuffers.Back().Create();
|
||||
inOutTempBuffers.Back().InitWriting();
|
||||
}
|
||||
for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
|
||||
{
|
||||
CSequentialOutTempBufferImp *tempBufferSpec =
|
||||
new CSequentialOutTempBufferImp;
|
||||
CMyComPtr<ISequentialOutStream> tempBuffer = tempBufferSpec;
|
||||
tempBufferSpec->Init(&inOutTempBuffers[i - 1]);
|
||||
tempBuffers.Add(tempBuffer);
|
||||
tempBufferSpecs.Add(tempBufferSpec);
|
||||
}
|
||||
|
||||
for (i = 0; i < numMethods; i++)
|
||||
_mixerCoderSpec->SetCoderInfo(i, NULL, NULL);
|
||||
|
||||
if (_bindInfo.InStreams.IsEmpty())
|
||||
return E_FAIL;
|
||||
UINT32 mainCoderIndex, mainStreamIndex;
|
||||
_bindInfo.FindInStream(_bindInfo.InStreams[0], mainCoderIndex, mainStreamIndex);
|
||||
_mixerCoderSpec->SetProgressCoderIndex(mainCoderIndex);
|
||||
if (inStreamSize != NULL)
|
||||
{
|
||||
CRecordVector<const UINT64 *> sizePointers;
|
||||
for (int i = 0; i < _bindInfo.Coders[mainCoderIndex].NumInStreams; i++)
|
||||
if (i == mainStreamIndex)
|
||||
sizePointers.Add(inStreamSize);
|
||||
else
|
||||
sizePointers.Add(NULL);
|
||||
_mixerCoderSpec->SetCoderInfo(mainCoderIndex, &sizePointers.Front(), NULL);
|
||||
}
|
||||
|
||||
|
||||
// UINT64 outStreamStartPos;
|
||||
// RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos));
|
||||
|
||||
CSequentialInStreamSizeCount2 *inStreamSizeCountSpec =
|
||||
new CSequentialInStreamSizeCount2;
|
||||
CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec;
|
||||
CSequentialOutStreamSizeCount *outStreamSizeCountSpec =
|
||||
new CSequentialOutStreamSizeCount;
|
||||
CMyComPtr<ISequentialOutStream> outStreamSizeCount = outStreamSizeCountSpec;
|
||||
|
||||
inStreamSizeCountSpec->Init(inStream);
|
||||
outStreamSizeCountSpec->Init(outStream);
|
||||
|
||||
CRecordVector<ISequentialInStream *> inStreamPointers;
|
||||
CRecordVector<ISequentialOutStream *> outStreamPointers;
|
||||
inStreamPointers.Add(inStreamSizeCount);
|
||||
outStreamPointers.Add(outStreamSizeCount);
|
||||
for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
|
||||
outStreamPointers.Add(tempBuffers[i - 1]);
|
||||
|
||||
RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1,
|
||||
&outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress));
|
||||
|
||||
ConvertBindInfoToFolderItemInfo(_decompressBindInfo, _decompressionMethods,
|
||||
folderItem);
|
||||
|
||||
packSizes.Add(outStreamSizeCountSpec->GetSize());
|
||||
|
||||
for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
|
||||
{
|
||||
CInOutTempBuffer &inOutTempBuffer = inOutTempBuffers[i - 1];
|
||||
inOutTempBuffer.FlushWrite();
|
||||
inOutTempBuffer.InitReading();
|
||||
inOutTempBuffer.WriteToStream(outStream);
|
||||
packSizes.Add(inOutTempBuffer.GetDataSize());
|
||||
}
|
||||
|
||||
for (i = 0; i < _bindReverseConverter->NumSrcInStreams; i++)
|
||||
{
|
||||
int binder = _bindInfo.FindBinderForInStream(
|
||||
_bindReverseConverter->DestOutToSrcInMap[i]);
|
||||
UINT64 streamSize;
|
||||
if (binder < 0)
|
||||
streamSize = inStreamSizeCountSpec->GetSize();
|
||||
else
|
||||
streamSize = _mixerCoderSpec->GetWriteProcessedSize(binder);
|
||||
folderItem.UnPackSizes.Add(streamSize);
|
||||
}
|
||||
for (i = numMethods - 1; i >= 0; i--)
|
||||
{
|
||||
// folderItem.Coders[numMethods - 1 - i].Properties = _codersInfo[i].Properties;
|
||||
for (int j = 0; j < _codersInfo[i].AltCoders.Size(); j++)
|
||||
folderItem.Coders[numMethods - 1 - i].AltCoders[j].Properties
|
||||
= _codersInfo[i].AltCoders[j].Properties;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
CEncoder::CEncoder(const CCompressionMethodMode &options):
|
||||
_bindReverseConverter(0)
|
||||
{
|
||||
if (options.IsEmpty())
|
||||
throw 1;
|
||||
|
||||
_options = options;
|
||||
_mixerCoderSpec = NULL;
|
||||
|
||||
if (options.Methods.IsEmpty())
|
||||
{
|
||||
// it has only password method;
|
||||
if (!options.PasswordIsDefined)
|
||||
throw 1;
|
||||
if (!options.Binds.IsEmpty())
|
||||
throw 1;
|
||||
NCoderMixer2::CCoderStreamsInfo coderStreamsInfo;
|
||||
CMethodFull method;
|
||||
|
||||
method.NumInStreams = 1;
|
||||
method.NumOutStreams = 1;
|
||||
coderStreamsInfo.NumInStreams = method.NumOutStreams;
|
||||
coderStreamsInfo.NumOutStreams = method.NumInStreams;
|
||||
method.MethodID = k_AES;
|
||||
|
||||
|
||||
#ifndef EXCLUDE_COM
|
||||
CMethodInfo2 methodInfo;
|
||||
if (!GetMethodInfo(kCryproMethod, methodInfo))
|
||||
throw 2;
|
||||
method.FilePath = methodInfo.FilePath;
|
||||
method.EncoderClassID = methodInfo.Encoder;
|
||||
// method.EncoderClassID = CLSID_CCrypto7zAESEncoder;
|
||||
#endif
|
||||
|
||||
_options.Methods.Add(method);
|
||||
_bindInfo.Coders.Add(coderStreamsInfo);
|
||||
|
||||
_bindInfo.InStreams.Add(0);
|
||||
_bindInfo.OutStreams.Add(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
UINT32 numInStreams = 0, numOutStreams = 0;
|
||||
int i;
|
||||
for (i = 0; i < options.Methods.Size(); i++)
|
||||
{
|
||||
const CMethodFull &methodFull = options.Methods[i];
|
||||
NCoderMixer2::CCoderStreamsInfo coderStreamsInfo;
|
||||
coderStreamsInfo.NumInStreams = methodFull.NumOutStreams;
|
||||
coderStreamsInfo.NumOutStreams = methodFull.NumInStreams;
|
||||
if (options.Binds.IsEmpty())
|
||||
{
|
||||
if (i < options.Methods.Size() - 1)
|
||||
{
|
||||
NCoderMixer2::CBindPair bindPair;
|
||||
bindPair.InIndex = numInStreams + coderStreamsInfo.NumInStreams;
|
||||
bindPair.OutIndex = numOutStreams;
|
||||
_bindInfo.BindPairs.Add(bindPair);
|
||||
}
|
||||
else
|
||||
_bindInfo.OutStreams.Insert(0, numOutStreams);
|
||||
for (UINT32 j = 1; j < coderStreamsInfo.NumOutStreams; j++)
|
||||
_bindInfo.OutStreams.Add(numOutStreams + j);
|
||||
}
|
||||
|
||||
numInStreams += coderStreamsInfo.NumInStreams;
|
||||
numOutStreams += coderStreamsInfo.NumOutStreams;
|
||||
|
||||
_bindInfo.Coders.Add(coderStreamsInfo);
|
||||
}
|
||||
|
||||
if (!options.Binds.IsEmpty())
|
||||
{
|
||||
for (int i = 0; i < options.Binds.Size(); i++)
|
||||
{
|
||||
NCoderMixer2::CBindPair bindPair;
|
||||
const CBind &bind = options.Binds[i];
|
||||
bindPair.InIndex = _bindInfo.GetCoderInStreamIndex(bind.InCoder) + bind.InStream;
|
||||
bindPair.OutIndex = _bindInfo.GetCoderOutStreamIndex(bind.OutCoder) + bind.OutStream;
|
||||
_bindInfo.BindPairs.Add(bindPair);
|
||||
}
|
||||
for (i = 0; i < numOutStreams; i++)
|
||||
if (_bindInfo.FindBinderForOutStream(i) == -1)
|
||||
_bindInfo.OutStreams.Add(i);
|
||||
}
|
||||
|
||||
for (i = 0; i < numInStreams; i++)
|
||||
if (_bindInfo.FindBinderForInStream(i) == -1)
|
||||
_bindInfo.InStreams.Add(i);
|
||||
|
||||
if (_bindInfo.InStreams.IsEmpty())
|
||||
throw 1; // this is error
|
||||
|
||||
// Make main stream first in list
|
||||
int inIndex = _bindInfo.InStreams[0];
|
||||
while (true)
|
||||
{
|
||||
UINT32 coderIndex, coderStreamIndex;
|
||||
_bindInfo.FindInStream(inIndex, coderIndex, coderStreamIndex);
|
||||
UINT32 outIndex = _bindInfo.GetCoderStartOutStream(coderIndex);
|
||||
int binder = _bindInfo.FindBinderForOutStream(outIndex);
|
||||
if (binder >= 0)
|
||||
{
|
||||
inIndex = _bindInfo.BindPairs[binder].InIndex;
|
||||
continue;
|
||||
}
|
||||
for (i = 0; i < _bindInfo.OutStreams.Size(); i++)
|
||||
if (_bindInfo.OutStreams[i] == outIndex)
|
||||
{
|
||||
_bindInfo.OutStreams.Delete(i);
|
||||
_bindInfo.OutStreams.Insert(0, outIndex);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (_options.PasswordIsDefined)
|
||||
{
|
||||
int numCryptoStreams = _bindInfo.OutStreams.Size();
|
||||
|
||||
for (i = 0; i < numCryptoStreams; i++)
|
||||
{
|
||||
NCoderMixer2::CBindPair bindPair;
|
||||
bindPair.InIndex = numInStreams + i;
|
||||
bindPair.OutIndex = _bindInfo.OutStreams[i];
|
||||
_bindInfo.BindPairs.Add(bindPair);
|
||||
}
|
||||
_bindInfo.OutStreams.Clear();
|
||||
|
||||
/*
|
||||
if (numCryptoStreams == 0)
|
||||
numCryptoStreams = 1;
|
||||
*/
|
||||
|
||||
for (i = 0; i < numCryptoStreams; i++)
|
||||
{
|
||||
NCoderMixer2::CCoderStreamsInfo coderStreamsInfo;
|
||||
CMethodFull method;
|
||||
method.NumInStreams = 1;
|
||||
method.NumOutStreams = 1;
|
||||
coderStreamsInfo.NumInStreams = method.NumOutStreams;
|
||||
coderStreamsInfo.NumOutStreams = method.NumInStreams;
|
||||
method.MethodID = k_AES;
|
||||
|
||||
#ifndef EXCLUDE_COM
|
||||
CMethodInfo2 methodInfo;
|
||||
if (!GetMethodInfo(kCryproMethod, methodInfo))
|
||||
throw 2;
|
||||
method.FilePath = methodInfo.FilePath;
|
||||
method.EncoderClassID = methodInfo.Encoder;
|
||||
// method.EncoderClassID = CLSID_CCrypto7zAESEncoder;
|
||||
#endif
|
||||
|
||||
_options.Methods.Add(method);
|
||||
_bindInfo.Coders.Add(coderStreamsInfo);
|
||||
_bindInfo.OutStreams.Add(numOutStreams + i);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (int i = _options.Methods.Size() - 1; i >= 0; i--)
|
||||
{
|
||||
const CMethodFull &methodFull = _options.Methods[i];
|
||||
_decompressionMethods.Add(methodFull.MethodID);
|
||||
}
|
||||
|
||||
_bindReverseConverter = new NCoderMixer2::CBindReverseConverter(_bindInfo);
|
||||
_bindReverseConverter->CreateReverseBindInfo(_decompressBindInfo);
|
||||
}
|
||||
|
||||
CEncoder::~CEncoder()
|
||||
{
|
||||
delete _bindReverseConverter;
|
||||
}
|
||||
|
||||
}}
|
||||
56
7zip/Archive/7z/7zEncode.h
Executable file
56
7zip/Archive/7z/7zEncode.h
Executable file
@@ -0,0 +1,56 @@
|
||||
// 7zEncode.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __7Z_ENCODE_H
|
||||
#define __7Z_ENCODE_H
|
||||
|
||||
// #include "../../Common/StreamObjects.h"
|
||||
|
||||
#include "7zCompressionMode.h"
|
||||
|
||||
#include "../Common/CoderMixer2.h"
|
||||
#ifndef EXCLUDE_COM
|
||||
#include "../Common/CoderLoader.h"
|
||||
#endif
|
||||
#include "7zMethods.h"
|
||||
#include "7zItem.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
class CEncoder
|
||||
{
|
||||
#ifndef EXCLUDE_COM
|
||||
// CMethodMap _methodMap;
|
||||
// it must be in top of objects
|
||||
CCoderLibraries _libraries;
|
||||
#endif
|
||||
|
||||
NCoderMixer2::CCoderMixer2 *_mixerCoderSpec;
|
||||
CMyComPtr<ICompressCoder2> _mixerCoder;
|
||||
|
||||
CObjectVector<CCoderInfo> _codersInfo;
|
||||
|
||||
CCompressionMethodMode _options;
|
||||
NCoderMixer2::CBindInfo _bindInfo;
|
||||
NCoderMixer2::CBindInfo _decompressBindInfo;
|
||||
NCoderMixer2::CBindReverseConverter *_bindReverseConverter;
|
||||
CRecordVector<CMethodID> _decompressionMethods;
|
||||
|
||||
HRESULT CreateMixerCoder();
|
||||
|
||||
public:
|
||||
CEncoder(const CCompressionMethodMode &options);
|
||||
~CEncoder();
|
||||
HRESULT Encode(ISequentialInStream *inStream,
|
||||
const UINT64 *inStreamSize,
|
||||
CFolder &folderItem,
|
||||
ISequentialOutStream *outStream,
|
||||
CRecordVector<UINT64> &packSizes,
|
||||
ICompressProgressInfo *compressProgress);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
204
7zip/Archive/7z/7zExtract.cpp
Executable file
204
7zip/Archive/7z/7zExtract.cpp
Executable file
@@ -0,0 +1,204 @@
|
||||
// 7zExtract.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "7zHandler.h"
|
||||
#include "7zFolderOutStream.h"
|
||||
#include "7zMethods.h"
|
||||
#include "7zDecode.h"
|
||||
|
||||
#include "../../../Common/ComTry.h"
|
||||
#include "../../Common/MultiStream.h"
|
||||
#include "../../Common/StreamObjects.h"
|
||||
#include "../../Common/ProgressUtils.h"
|
||||
#include "../../Common/LimitedStreams.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
struct CExtractFolderInfo
|
||||
{
|
||||
int FileIndex;
|
||||
int FolderIndex;
|
||||
CBoolVector ExtractStatuses;
|
||||
UINT64 UnPackSize;
|
||||
CExtractFolderInfo(int fileIndex, int folderIndex):
|
||||
FileIndex(fileIndex),
|
||||
FolderIndex(folderIndex),
|
||||
UnPackSize(0)
|
||||
{
|
||||
if (fileIndex >= 0)
|
||||
{
|
||||
ExtractStatuses.Reserve(1);
|
||||
ExtractStatuses.Add(true);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
|
||||
INT32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool testMode = (testModeSpec != 0);
|
||||
CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
|
||||
UINT64 importantTotalUnPacked = 0;
|
||||
UINT64 censoredTotalUnPacked = 0, censoredTotalPacked = 0;
|
||||
|
||||
bool allFilesMode = (numItems == UINT32(-1));
|
||||
if (allFilesMode)
|
||||
numItems = _database.Files.Size();
|
||||
|
||||
if(numItems == 0)
|
||||
return S_OK;
|
||||
|
||||
CObjectVector<CExtractFolderInfo> extractFolderInfoVector;
|
||||
for(UINT32 indexIndex = 0; indexIndex < numItems; indexIndex++)
|
||||
{
|
||||
int fileIndex = allFilesMode ? indexIndex : indices[indexIndex];
|
||||
int folderIndex = _database.FileIndexToFolderIndexMap[fileIndex];
|
||||
if (folderIndex < 0)
|
||||
{
|
||||
extractFolderInfoVector.Add(CExtractFolderInfo(fileIndex, -1));
|
||||
continue;
|
||||
}
|
||||
if (extractFolderInfoVector.IsEmpty() ||
|
||||
folderIndex != extractFolderInfoVector.Back().FolderIndex)
|
||||
{
|
||||
extractFolderInfoVector.Add(CExtractFolderInfo(-1, folderIndex));
|
||||
const CFolder &folderInfo = _database.Folders[folderIndex];
|
||||
// Count full_folder_size
|
||||
UINT64 unPackSize = folderInfo.GetUnPackSize();
|
||||
importantTotalUnPacked += unPackSize;
|
||||
extractFolderInfoVector.Back().UnPackSize = unPackSize;
|
||||
}
|
||||
|
||||
CExtractFolderInfo &extractFolderInfo = extractFolderInfoVector.Back();
|
||||
|
||||
// const CFolderInfo &folderInfo = m_dam_Folders[folderIndex];
|
||||
UINT32 startIndex = (UINT32)_database.FolderStartFileIndex[folderIndex];
|
||||
for (UINT32 index = extractFolderInfo.ExtractStatuses.Size();
|
||||
index <= fileIndex - startIndex; index++)
|
||||
{
|
||||
UINT64 unPackSize = _database.Files[startIndex + index].UnPackSize;
|
||||
// Count partial_folder_size
|
||||
// extractFolderInfo.UnPackSize += unPackSize;
|
||||
// importantTotalUnPacked += unPackSize;
|
||||
extractFolderInfo.ExtractStatuses.Add(index == fileIndex - startIndex);
|
||||
}
|
||||
}
|
||||
|
||||
extractCallback->SetTotal(importantTotalUnPacked);
|
||||
|
||||
CDecoder decoder;
|
||||
|
||||
UINT64 currentImportantTotalUnPacked = 0;
|
||||
UINT64 totalFolderUnPacked;
|
||||
|
||||
for(int i = 0; i < extractFolderInfoVector.Size(); i++,
|
||||
currentImportantTotalUnPacked += totalFolderUnPacked)
|
||||
{
|
||||
CExtractFolderInfo &extractFolderInfo = extractFolderInfoVector[i];
|
||||
totalFolderUnPacked = extractFolderInfo.UnPackSize;
|
||||
|
||||
RINOK(extractCallback->SetCompleted(¤tImportantTotalUnPacked));
|
||||
|
||||
CFolderOutStream *folderOutStream = new CFolderOutStream;
|
||||
CMyComPtr<ISequentialOutStream> outStream(folderOutStream);
|
||||
|
||||
UINT32 startIndex;
|
||||
if (extractFolderInfo.FileIndex >= 0)
|
||||
startIndex = extractFolderInfo.FileIndex;
|
||||
else
|
||||
startIndex = (UINT32)_database.FolderStartFileIndex[extractFolderInfo.FolderIndex];
|
||||
|
||||
|
||||
RINOK(folderOutStream->Init(&_database, startIndex,
|
||||
&extractFolderInfo.ExtractStatuses, extractCallback, testMode));
|
||||
|
||||
if (extractFolderInfo.FileIndex >= 0)
|
||||
continue;
|
||||
|
||||
UINT32 folderIndex = extractFolderInfo.FolderIndex;
|
||||
const CFolder &folderInfo = _database.Folders[folderIndex];
|
||||
|
||||
CObjectVector< CMyComPtr<ISequentialInStream> > inStreams;
|
||||
|
||||
CLockedInStream lockedInStream;
|
||||
lockedInStream.Init(_inStream);
|
||||
|
||||
|
||||
UINT64 folderStartPackStreamIndex = _database.FolderStartPackStreamIndex[folderIndex];
|
||||
|
||||
for (int j = 0; j < folderInfo.PackStreams.Size(); j++)
|
||||
{
|
||||
const CPackStreamInfo &packStreamInfo = folderInfo.PackStreams[j];
|
||||
CLockedSequentialInStreamImp *lockedStreamImpSpec = new
|
||||
CLockedSequentialInStreamImp;
|
||||
CMyComPtr<ISequentialInStream> lockedStreamImp = lockedStreamImpSpec;
|
||||
UINT64 streamStartPos = _database.GetFolderStreamPos(folderIndex, j);
|
||||
lockedStreamImpSpec->Init(&lockedInStream, streamStartPos);
|
||||
|
||||
CLimitedSequentialInStream *streamSpec = new
|
||||
CLimitedSequentialInStream;
|
||||
CMyComPtr<ISequentialInStream> inStream = streamSpec;
|
||||
streamSpec->Init(lockedStreamImp,
|
||||
_database.PackSizes[(UINT32)folderStartPackStreamIndex + j]);
|
||||
inStreams.Add(inStream);
|
||||
}
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
|
||||
localProgressSpec->Init(extractCallback, false);
|
||||
|
||||
CLocalCompressProgressInfo *localCompressProgressSpec =
|
||||
new CLocalCompressProgressInfo;
|
||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
||||
localCompressProgressSpec->Init(progress, NULL, ¤tImportantTotalUnPacked);
|
||||
|
||||
UINT32 packStreamIndex = _database.FolderStartPackStreamIndex[folderIndex];
|
||||
UINT64 folderStartPackPos = _database.GetFolderStreamPos(folderIndex, 0);
|
||||
|
||||
#ifndef _NO_CRYPTO
|
||||
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
|
||||
if (extractCallback)
|
||||
extractCallback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword);
|
||||
#endif
|
||||
|
||||
try
|
||||
{
|
||||
HRESULT result = decoder.Decode(_inStream,
|
||||
folderStartPackPos,
|
||||
&_database.PackSizes[packStreamIndex],
|
||||
folderInfo,
|
||||
outStream,
|
||||
compressProgress
|
||||
#ifndef _NO_CRYPTO
|
||||
, getTextPassword
|
||||
#endif
|
||||
);
|
||||
|
||||
if (result == S_FALSE)
|
||||
{
|
||||
RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError));
|
||||
continue;
|
||||
}
|
||||
if (result == E_NOTIMPL)
|
||||
{
|
||||
RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
||||
continue;
|
||||
}
|
||||
if (result != S_OK)
|
||||
return result;
|
||||
RINOK(folderOutStream->WasWritingFinished());
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
}}
|
||||
141
7zip/Archive/7z/7zFolderInStream.cpp
Executable file
141
7zip/Archive/7z/7zFolderInStream.cpp
Executable file
@@ -0,0 +1,141 @@
|
||||
// 7zFolderInStream.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "7zFolderInStream.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
CFolderInStream::CFolderInStream()
|
||||
{
|
||||
_inStreamWithHashSpec = new CInStreamWithCRC;
|
||||
_inStreamWithHash = _inStreamWithHashSpec;
|
||||
}
|
||||
|
||||
void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback,
|
||||
const UINT32 *fileIndices, UINT32 numFiles)
|
||||
{
|
||||
_updateCallback = updateCallback;
|
||||
_numFiles = numFiles;
|
||||
_fileIndex = 0;
|
||||
_fileIndices = fileIndices;
|
||||
CRCs.Clear();
|
||||
Sizes.Clear();
|
||||
_fileIsOpen = false;
|
||||
_currentSizeIsDefined = false;
|
||||
}
|
||||
|
||||
HRESULT CFolderInStream::OpenStream()
|
||||
{
|
||||
_filePos = 0;
|
||||
while (_fileIndex < _numFiles)
|
||||
{
|
||||
_currentSizeIsDefined = false;
|
||||
CMyComPtr<IInStream> stream;
|
||||
RINOK(_updateCallback->GetStream(_fileIndices[_fileIndex], &stream));
|
||||
_fileIndex++;
|
||||
_inStreamWithHashSpec->Init(stream);
|
||||
if (!stream)
|
||||
{
|
||||
RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
||||
Sizes.Add(0);
|
||||
AddDigest();
|
||||
continue;
|
||||
}
|
||||
CMyComPtr<IStreamGetSize> streamGetSize;
|
||||
if (stream.QueryInterface(IID_IStreamGetSize, &streamGetSize) == S_OK)
|
||||
{
|
||||
if(streamGetSize)
|
||||
{
|
||||
_currentSizeIsDefined = true;
|
||||
RINOK(streamGetSize->GetSize(&_currentSize));
|
||||
}
|
||||
}
|
||||
|
||||
_fileIsOpen = true;
|
||||
return S_OK;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void CFolderInStream::AddDigest()
|
||||
{
|
||||
CRCs.Add(_inStreamWithHashSpec->GetCRC());
|
||||
}
|
||||
|
||||
HRESULT CFolderInStream::CloseStream()
|
||||
{
|
||||
RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
||||
_inStreamWithHashSpec->ReleaseStream();
|
||||
_fileIsOpen = false;
|
||||
Sizes.Add(_filePos);
|
||||
AddDigest();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CFolderInStream::ReadPart(void *data, UINT32 size, UINT32 *processedSize)
|
||||
{
|
||||
UINT32 realProcessedSize = 0;
|
||||
while ((_fileIndex < _numFiles || _fileIsOpen) && size > 0)
|
||||
{
|
||||
if (_fileIsOpen)
|
||||
{
|
||||
UINT32 localProcessedSize;
|
||||
RINOK(_inStreamWithHash->Read(
|
||||
((BYTE *)data) + realProcessedSize, size, &localProcessedSize));
|
||||
if (localProcessedSize == 0)
|
||||
{
|
||||
RINOK(CloseStream());
|
||||
continue;
|
||||
}
|
||||
realProcessedSize += localProcessedSize;
|
||||
_filePos += localProcessedSize;
|
||||
size -= localProcessedSize;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(OpenStream());
|
||||
}
|
||||
}
|
||||
if (processedSize != 0)
|
||||
*processedSize = realProcessedSize;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CFolderInStream::Read(void *data, UINT32 size, UINT32 *processedSize)
|
||||
{
|
||||
UINT32 realProcessedSize = 0;
|
||||
while (size > 0)
|
||||
{
|
||||
UINT32 localProcessedSize;
|
||||
RINOK(ReadPart(((BYTE *)data) + realProcessedSize, size, &localProcessedSize));
|
||||
if (localProcessedSize == 0)
|
||||
break;
|
||||
size -= localProcessedSize;
|
||||
realProcessedSize += localProcessedSize;
|
||||
}
|
||||
if (processedSize != 0)
|
||||
*processedSize = realProcessedSize;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CFolderInStream::GetSubStreamSize(UINT64 subStream, UINT64 *value)
|
||||
{
|
||||
*value = 0;
|
||||
if (subStream < Sizes.Size())
|
||||
{
|
||||
*value= Sizes[subStream];
|
||||
return S_OK;
|
||||
}
|
||||
if (subStream > Sizes.Size())
|
||||
return E_FAIL;
|
||||
if (!_currentSizeIsDefined)
|
||||
return S_FALSE;
|
||||
*value = _currentSize;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}}
|
||||
68
7zip/Archive/7z/7zFolderInStream.h
Executable file
68
7zip/Archive/7z/7zFolderInStream.h
Executable file
@@ -0,0 +1,68 @@
|
||||
// 7z/FolderInStream.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __7Z_FOLDERINSTREAM_H
|
||||
#define __7Z_FOLDERINSTREAM_H
|
||||
|
||||
#include "7zItem.h"
|
||||
#include "7zHeader.h"
|
||||
|
||||
#include "../IArchive.h"
|
||||
#include "../Common/InStreamWithCRC.h"
|
||||
#include "../../IStream.h"
|
||||
#include "../../ICoder.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
class CFolderInStream:
|
||||
public ISequentialInStream,
|
||||
public ICompressGetSubStreamSize,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
|
||||
MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)
|
||||
|
||||
CFolderInStream();
|
||||
|
||||
STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize);
|
||||
STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize);
|
||||
|
||||
STDMETHOD(GetSubStreamSize)(UINT64 subStream, UINT64 *value);
|
||||
private:
|
||||
CInStreamWithCRC *_inStreamWithHashSpec;
|
||||
CMyComPtr<ISequentialInStream> _inStreamWithHash;
|
||||
CMyComPtr<IArchiveUpdateCallback> _updateCallback;
|
||||
|
||||
bool _currentSizeIsDefined;
|
||||
UINT64 _currentSize;
|
||||
|
||||
bool _fileIsOpen;
|
||||
UINT64 _filePos;
|
||||
|
||||
const UINT32 *_fileIndices;
|
||||
UINT32 _numFiles;
|
||||
UINT32 _fileIndex;
|
||||
|
||||
HRESULT OpenStream();
|
||||
HRESULT CloseStream();
|
||||
void AddDigest();
|
||||
public:
|
||||
void Init(IArchiveUpdateCallback *updateCallback,
|
||||
const UINT32 *fileIndices, UINT32 numFiles);
|
||||
CRecordVector<UINT32> CRCs;
|
||||
CRecordVector<UINT64> Sizes;
|
||||
UINT64 GetFullSize() const
|
||||
{
|
||||
UINT64 size = 0;
|
||||
for (int i = 0; i < Sizes.Size(); i++)
|
||||
size += Sizes[i];
|
||||
return size;
|
||||
}
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
165
7zip/Archive/7z/7zFolderOutStream.cpp
Executable file
165
7zip/Archive/7z/7zFolderOutStream.cpp
Executable file
@@ -0,0 +1,165 @@
|
||||
// 7zFolderOutStream.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "7zFolderOutStream.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
CFolderOutStream::CFolderOutStream()
|
||||
{
|
||||
_outStreamWithHashSpec = new COutStreamWithCRC;
|
||||
_outStreamWithHash = _outStreamWithHashSpec;
|
||||
}
|
||||
|
||||
HRESULT CFolderOutStream::Init(
|
||||
CArchiveDatabaseEx *archiveDatabase,
|
||||
UINT32 startIndex,
|
||||
const CBoolVector *extractStatuses,
|
||||
IArchiveExtractCallback *extractCallback,
|
||||
bool testMode)
|
||||
{
|
||||
_archiveDatabase = archiveDatabase;
|
||||
_startIndex = startIndex;
|
||||
|
||||
_extractStatuses = extractStatuses;
|
||||
_extractCallback = extractCallback;
|
||||
_testMode = testMode;
|
||||
|
||||
_currentIndex = 0;
|
||||
_fileIsOpen = false;
|
||||
return WriteEmptyFiles();
|
||||
}
|
||||
|
||||
HRESULT CFolderOutStream::OpenFile()
|
||||
{
|
||||
INT32 askMode;
|
||||
if((*_extractStatuses)[_currentIndex])
|
||||
askMode = _testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
else
|
||||
askMode = NArchive::NExtract::NAskMode::kSkip;
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
|
||||
UINT32 index = _startIndex + _currentIndex;
|
||||
RINOK(_extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
|
||||
_outStreamWithHashSpec->Init(realOutStream);
|
||||
if (askMode == NArchive::NExtract::NAskMode::kExtract &&
|
||||
(!realOutStream))
|
||||
{
|
||||
UINT32 index = _startIndex + _currentIndex;
|
||||
const CFileItem &fileInfo = _archiveDatabase->Files[index];
|
||||
if (!fileInfo.IsAnti && !fileInfo.IsDirectory)
|
||||
askMode = NArchive::NExtract::NAskMode::kSkip;
|
||||
}
|
||||
return _extractCallback->PrepareOperation(askMode);
|
||||
}
|
||||
|
||||
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)
|
||||
return S_OK;
|
||||
RINOK(OpenFile());
|
||||
RINOK(_extractCallback->SetOperationResult(
|
||||
NArchive::NExtract::NOperationResult::kOK));
|
||||
_outStreamWithHashSpec->ReleaseStream();
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CFolderOutStream::Write(const void *data,
|
||||
UINT32 size, UINT32 *processedSize)
|
||||
{
|
||||
UINT32 realProcessedSize = 0;
|
||||
while(_currentIndex < _extractStatuses->Size())
|
||||
{
|
||||
if (_fileIsOpen)
|
||||
{
|
||||
UINT32 index = _startIndex + _currentIndex;
|
||||
const CFileItem &fileInfo = _archiveDatabase->Files[index];
|
||||
UINT64 fileSize = fileInfo.UnPackSize;
|
||||
|
||||
UINT32 numBytesToWrite = (UINT32)MyMin(fileSize - _filePos,
|
||||
UINT64(size - realProcessedSize));
|
||||
|
||||
UINT32 processedSizeLocal;
|
||||
RINOK(_outStreamWithHash->Write((const BYTE *)data + realProcessedSize, numBytesToWrite, &processedSizeLocal));
|
||||
|
||||
_filePos += processedSizeLocal;
|
||||
realProcessedSize += processedSizeLocal;
|
||||
if (_filePos == fileSize)
|
||||
{
|
||||
bool digestsAreEqual;
|
||||
if (fileInfo.FileCRCIsDefined)
|
||||
digestsAreEqual = fileInfo.FileCRC == _outStreamWithHashSpec->GetCRC();
|
||||
else
|
||||
digestsAreEqual = true;
|
||||
|
||||
RINOK(_extractCallback->SetOperationResult(
|
||||
digestsAreEqual ?
|
||||
NArchive::NExtract::NOperationResult::kOK :
|
||||
NArchive::NExtract::NOperationResult::kCRCError));
|
||||
_outStreamWithHashSpec->ReleaseStream();
|
||||
_fileIsOpen = false;
|
||||
_currentIndex++;
|
||||
}
|
||||
if (realProcessedSize == size)
|
||||
{
|
||||
if (processedSize != NULL)
|
||||
*processedSize = realProcessedSize;
|
||||
return WriteEmptyFiles();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(OpenFile());
|
||||
_fileIsOpen = true;
|
||||
_filePos = 0;
|
||||
}
|
||||
}
|
||||
if (processedSize != NULL)
|
||||
*processedSize = size;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CFolderOutStream::WritePart(const void *data,
|
||||
UINT32 size, UINT32 *processedSize)
|
||||
{
|
||||
return Write(data, size, processedSize);
|
||||
}
|
||||
|
||||
HRESULT CFolderOutStream::FlushCorrupted(INT32 resultEOperationResult)
|
||||
{
|
||||
while(_currentIndex < _extractStatuses->Size())
|
||||
{
|
||||
if (_fileIsOpen)
|
||||
{
|
||||
RINOK(_extractCallback->SetOperationResult(resultEOperationResult));
|
||||
_outStreamWithHashSpec->ReleaseStream();
|
||||
_fileIsOpen = false;
|
||||
_currentIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(OpenFile());
|
||||
_fileIsOpen = true;
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CFolderOutStream::WasWritingFinished()
|
||||
{
|
||||
if (_currentIndex == _extractStatuses->Size())
|
||||
return S_OK;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
}}
|
||||
58
7zip/Archive/7z/7zFolderOutStream.h
Executable file
58
7zip/Archive/7z/7zFolderOutStream.h
Executable file
@@ -0,0 +1,58 @@
|
||||
// 7zFolderOutStream.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __7Z_FOLDEROUTSTREAM_H
|
||||
#define __7Z_FOLDEROUTSTREAM_H
|
||||
|
||||
#include "7zIn.h"
|
||||
|
||||
#include "../../IStream.h"
|
||||
#include "../IArchive.h"
|
||||
#include "../Common/OutStreamWithCRC.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
class CFolderOutStream:
|
||||
public ISequentialOutStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
CFolderOutStream();
|
||||
|
||||
STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize);
|
||||
STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize);
|
||||
private:
|
||||
|
||||
COutStreamWithCRC *_outStreamWithHashSpec;
|
||||
CMyComPtr<ISequentialOutStream> _outStreamWithHash;
|
||||
CArchiveDatabaseEx *_archiveDatabase;
|
||||
const CBoolVector *_extractStatuses;
|
||||
UINT32 _startIndex;
|
||||
int _currentIndex;
|
||||
// UINT64 _currentDataPos;
|
||||
CMyComPtr<IArchiveExtractCallback> _extractCallback;
|
||||
bool _testMode;
|
||||
|
||||
bool _fileIsOpen;
|
||||
UINT64 _filePos;
|
||||
|
||||
HRESULT OpenFile();
|
||||
HRESULT WriteEmptyFiles();
|
||||
public:
|
||||
HRESULT Init(
|
||||
CArchiveDatabaseEx *archiveDatabase,
|
||||
UINT32 startIndex,
|
||||
const CBoolVector *extractStatuses,
|
||||
IArchiveExtractCallback *extractCallback,
|
||||
bool testMode);
|
||||
HRESULT FlushCorrupted(INT32 resultEOperationResult);
|
||||
HRESULT WasWritingFinished();
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
442
7zip/Archive/7z/7zHandler.cpp
Executable file
442
7zip/Archive/7z/7zHandler.cpp
Executable file
@@ -0,0 +1,442 @@
|
||||
// 7z/Handler.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "7zHandler.h"
|
||||
#include "7zProperties.h"
|
||||
|
||||
#include "../../../Common/IntToString.h"
|
||||
// #include "../../../Common/StringConvert.h"
|
||||
#include "../../../Common/ComTry.h"
|
||||
|
||||
#include "../../../Windows/Defs.h"
|
||||
|
||||
#include "../Common/ItemNameUtils.h"
|
||||
|
||||
// #include "7zMethods.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
CHandler::CHandler()
|
||||
{
|
||||
#ifndef EXTRACT_ONLY
|
||||
Init();
|
||||
#endif
|
||||
#ifndef EXCLUDE_COM
|
||||
LoadMethodMap();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
STDMETHODIMP CHandler::EnumProperties(IEnumSTATPROPSTG **enumerator)
|
||||
{
|
||||
#ifndef _SFX
|
||||
COM_TRY_BEGIN
|
||||
CComObjectNoLock<CEnumArchiveItemProperty> *enumeratorSpec =
|
||||
new CComObjectNoLock<CEnumArchiveItemProperty>;
|
||||
if (enumeratorSpec == NULL)
|
||||
return E_OUTOFMEMORY;
|
||||
CMyComPtr<IEnumSTATPROPSTG> tempEnumerator(enumeratorSpec);
|
||||
enumeratorSpec->Init(_database.ArchiveInfo.FileInfoPopIDs);
|
||||
*enumerator = tempEnumerator.Detach();
|
||||
return S_OK;
|
||||
// return tempEnumerator->QueryInterface(IID_IEnumSTATPROPSTG, (LPVOID*)enumerator);
|
||||
COM_TRY_END
|
||||
#else
|
||||
return E_NOTIMPL;
|
||||
#endif
|
||||
}
|
||||
*/
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfItems(UINT32 *numItems)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
*numItems = _database.Files.Size();
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
value->vt = VT_EMPTY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#ifdef _SFX
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UINT32 *numProperties)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UINT32 *numProperties)
|
||||
{
|
||||
*numProperties = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UINT32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
|
||||
static void MySetFileTime(bool timeDefined, FILETIME unixTime,
|
||||
NWindows::NCOM::CPropVariant &propVariant)
|
||||
{
|
||||
// FILETIME fileTime;
|
||||
if (timeDefined)
|
||||
propVariant = unixTime;
|
||||
// NTime::UnixTimeToFileTime((time_t)unixTime, fileTime);
|
||||
else
|
||||
{
|
||||
return;
|
||||
// fileTime.dwHighDateTime = fileTime.dwLowDateTime = 0;
|
||||
}
|
||||
// propVariant = fileTime;
|
||||
}
|
||||
|
||||
/*
|
||||
inline static wchar_t GetHex(BYTE value)
|
||||
{
|
||||
return (value < 10) ? ('0' + value) : ('A' + (value - 10));
|
||||
}
|
||||
|
||||
static UString ConvertBytesToHexString(const BYTE *data, UINT32 size)
|
||||
{
|
||||
UString result;
|
||||
for (UINT32 i = 0; i < size; i++)
|
||||
{
|
||||
BYTE b = data[i];
|
||||
result += GetHex(b >> 4);
|
||||
result += GetHex(b & 0xF);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _SFX
|
||||
|
||||
static UString ConvertUINT32ToString(UINT32 value)
|
||||
{
|
||||
wchar_t buffer[32];
|
||||
ConvertUINT64ToString(value, buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static UString GetStringForSizeValue(UINT32 value)
|
||||
{
|
||||
for (int i = 31; i >= 0; i--)
|
||||
if ((UINT32(1) << i) == value)
|
||||
return ConvertUINT32ToString(i);
|
||||
UString result;
|
||||
if (value % (1 << 20) == 0)
|
||||
{
|
||||
result += ConvertUINT32ToString(value >> 20);
|
||||
result += L"m";
|
||||
}
|
||||
else if (value % (1 << 10) == 0)
|
||||
{
|
||||
result += ConvertUINT32ToString(value >> 10);
|
||||
result += L"k";
|
||||
}
|
||||
else
|
||||
{
|
||||
result += ConvertUINT32ToString(value);
|
||||
result += L"b";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static CMethodID k_Copy = { { 0x0 }, 1 };
|
||||
static CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
|
||||
static CMethodID k_BCJ = { { 0x3, 0x3, 0x1, 0x3 }, 4 };
|
||||
static CMethodID k_BCJ2 = { { 0x3, 0x3, 0x1, 0x1B }, 4 };
|
||||
static CMethodID k_PPMD = { { 0x3, 0x4, 0x1 }, 3 };
|
||||
static CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 };
|
||||
static CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 };
|
||||
|
||||
static inline char GetHex(BYTE value)
|
||||
{
|
||||
return (value < 10) ? ('0' + value) : ('A' + (value - 10));
|
||||
}
|
||||
static inline UString GetHex2(BYTE value)
|
||||
{
|
||||
UString result;
|
||||
result += GetHex(value >> 4);
|
||||
result += GetHex(value & 0xF);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
const CFileItem &item = _database.Files[index];
|
||||
|
||||
switch(propID)
|
||||
{
|
||||
case kpidPath:
|
||||
{
|
||||
propVariant = NArchive::NItemName::GetOSName(item.Name);
|
||||
break;
|
||||
}
|
||||
case kpidIsFolder:
|
||||
propVariant = item.IsDirectory;
|
||||
break;
|
||||
case kpidSize:
|
||||
propVariant = item.UnPackSize;
|
||||
break;
|
||||
case kpidPackedSize:
|
||||
{
|
||||
{
|
||||
int folderIndex = _database.FileIndexToFolderIndexMap[index];
|
||||
if (folderIndex >= 0)
|
||||
{
|
||||
const CFolder &folderInfo = _database.Folders[folderIndex];
|
||||
if (_database.FolderStartFileIndex[folderIndex] == index)
|
||||
propVariant = _database.GetFolderFullPackSize(folderIndex);
|
||||
else
|
||||
propVariant = UINT64(0);
|
||||
}
|
||||
else
|
||||
propVariant = UINT64(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kpidLastAccessTime:
|
||||
MySetFileTime(item.IsLastAccessTimeDefined, item.LastAccessTime, propVariant);
|
||||
break;
|
||||
case kpidCreationTime:
|
||||
MySetFileTime(item.IsCreationTimeDefined, item.CreationTime, propVariant);
|
||||
break;
|
||||
case kpidLastWriteTime:
|
||||
MySetFileTime(item.IsLastWriteTimeDefined, item.LastWriteTime, propVariant);
|
||||
break;
|
||||
case kpidAttributes:
|
||||
if (item.AreAttributesDefined)
|
||||
propVariant = item.Attributes;
|
||||
break;
|
||||
case kpidCRC:
|
||||
if (item.FileCRCIsDefined)
|
||||
propVariant = item.FileCRC;
|
||||
break;
|
||||
#ifndef _SFX
|
||||
case kpidMethod:
|
||||
{
|
||||
int folderIndex = _database.FileIndexToFolderIndexMap[index];
|
||||
if (folderIndex >= 0)
|
||||
{
|
||||
const CFolder &folderInfo = _database.Folders[folderIndex];
|
||||
UString methodsString;
|
||||
for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--)
|
||||
{
|
||||
const CCoderInfo &coderInfo = folderInfo.Coders[i];
|
||||
if (!methodsString.IsEmpty())
|
||||
methodsString += L' ';
|
||||
CMethodInfo methodInfo;
|
||||
|
||||
bool methodIsKnown;
|
||||
|
||||
for (int j = 0; j < coderInfo.AltCoders.Size(); j++)
|
||||
{
|
||||
if (j > 0)
|
||||
methodsString += L"|";
|
||||
const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders[j];
|
||||
|
||||
UString methodName;
|
||||
#ifdef NO_REGISTRY
|
||||
|
||||
methodIsKnown = true;
|
||||
if (altCoderInfo.MethodID == k_Copy)
|
||||
methodName = L"Copy";
|
||||
else if (altCoderInfo.MethodID == k_LZMA)
|
||||
methodName = L"LZMA";
|
||||
else if (altCoderInfo.MethodID == k_BCJ)
|
||||
methodName = L"BCJ";
|
||||
else if (altCoderInfo.MethodID == k_BCJ2)
|
||||
methodName = L"BCJ2";
|
||||
else if (altCoderInfo.MethodID == k_PPMD)
|
||||
methodName = L"PPMD";
|
||||
else if (altCoderInfo.MethodID == k_Deflate)
|
||||
methodName = L"Deflate";
|
||||
else if (altCoderInfo.MethodID == k_BZip2)
|
||||
methodName = L"BZip2";
|
||||
else
|
||||
methodIsKnown = false;
|
||||
|
||||
#else
|
||||
|
||||
methodIsKnown = GetMethodInfo(
|
||||
altCoderInfo.MethodID, methodInfo);
|
||||
methodName = methodInfo.Name;
|
||||
|
||||
#endif
|
||||
|
||||
if (methodIsKnown)
|
||||
{
|
||||
methodsString += methodName;
|
||||
if (altCoderInfo.MethodID == k_LZMA)
|
||||
{
|
||||
if (altCoderInfo.Properties.GetCapacity() == 5)
|
||||
{
|
||||
methodsString += L":";
|
||||
UINT32 dicSize = *(const UINT32 *)
|
||||
((const BYTE *)altCoderInfo.Properties + 1);
|
||||
methodsString += GetStringForSizeValue(dicSize);
|
||||
}
|
||||
}
|
||||
else if (altCoderInfo.MethodID == k_PPMD)
|
||||
{
|
||||
if (altCoderInfo.Properties.GetCapacity() == 5)
|
||||
{
|
||||
BYTE order = *(const BYTE *)altCoderInfo.Properties;
|
||||
methodsString += L":o";
|
||||
methodsString += ConvertUINT32ToString(order);
|
||||
methodsString += L":mem";
|
||||
UINT32 dicSize = *(const UINT32 *)
|
||||
((const BYTE *)altCoderInfo.Properties + 1);
|
||||
methodsString += GetStringForSizeValue(dicSize);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (altCoderInfo.Properties.GetCapacity() > 0)
|
||||
{
|
||||
methodsString += L":[";
|
||||
for (int bi = 0; bi < altCoderInfo.Properties.GetCapacity(); bi++)
|
||||
{
|
||||
if (bi > 2 && bi + 1 < altCoderInfo.Properties.GetCapacity())
|
||||
{
|
||||
methodsString += L"..";
|
||||
break;
|
||||
}
|
||||
else
|
||||
methodsString += GetHex2(altCoderInfo.Properties[bi]);
|
||||
}
|
||||
methodsString += L"]";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
methodsString += altCoderInfo.MethodID.ConvertToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
propVariant = methodsString;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case kpidBlock:
|
||||
{
|
||||
int folderIndex = _database.FileIndexToFolderIndexMap[index];
|
||||
if (folderIndex >= 0)
|
||||
propVariant = (UINT32)folderIndex;
|
||||
}
|
||||
break;
|
||||
case kpidPackedSize0:
|
||||
case kpidPackedSize1:
|
||||
case kpidPackedSize2:
|
||||
case kpidPackedSize3:
|
||||
case kpidPackedSize4:
|
||||
{
|
||||
int folderIndex = _database.FileIndexToFolderIndexMap[index];
|
||||
if (folderIndex >= 0)
|
||||
{
|
||||
const CFolder &folderInfo = _database.Folders[folderIndex];
|
||||
if (_database.FolderStartFileIndex[folderIndex] == index &&
|
||||
folderInfo.PackStreams.Size() > propID - kpidPackedSize0)
|
||||
{
|
||||
propVariant = _database.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0);
|
||||
}
|
||||
else
|
||||
propVariant = UINT64(0);
|
||||
}
|
||||
else
|
||||
propVariant = UINT64(0);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case kpidIsAnti:
|
||||
propVariant = item.IsAnti;
|
||||
break;
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
const UINT64 *maxCheckStartPosition,
|
||||
IArchiveOpenCallback *openArchiveCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
_inStream.Release();
|
||||
_database.Clear();
|
||||
#ifndef _SFX
|
||||
_fileInfoPopIDs.Clear();
|
||||
#endif
|
||||
try
|
||||
{
|
||||
CInArchive archive;
|
||||
RINOK(archive.Open(stream, maxCheckStartPosition));
|
||||
|
||||
#ifndef _NO_CRYPTO
|
||||
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
|
||||
if (openArchiveCallback)
|
||||
{
|
||||
CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = openArchiveCallback;
|
||||
openArchiveCallbackTemp.QueryInterface(
|
||||
IID_ICryptoGetTextPassword, &getTextPassword);
|
||||
}
|
||||
#endif
|
||||
|
||||
HRESULT result = archive.ReadDatabase(_database
|
||||
#ifndef _NO_CRYPTO
|
||||
, getTextPassword
|
||||
#endif
|
||||
);
|
||||
RINOK(result);
|
||||
result = archive.CheckIntegrity();
|
||||
if (result != S_OK)
|
||||
return E_FAIL;
|
||||
_database.FillFolderStartPackStream();
|
||||
_database.FillStartPos();
|
||||
_database.FillFolderStartFileIndex();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
_inStream = stream;
|
||||
#ifndef _SFX
|
||||
FillPopIDs();
|
||||
#endif
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Close()
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
_inStream.Release();
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
}}
|
||||
208
7zip/Archive/7z/7zHandler.h
Executable file
208
7zip/Archive/7z/7zHandler.h
Executable file
@@ -0,0 +1,208 @@
|
||||
// 7z/Handler.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __7Z_HANDLER_H
|
||||
#define __7Z_HANDLER_H
|
||||
|
||||
#include "../IArchive.h"
|
||||
// #include "../../../Compress/Interface/CompressInterface.h"
|
||||
#include "7zIn.h"
|
||||
|
||||
#include "7zCompressionMode.h"
|
||||
|
||||
#ifndef _SFX
|
||||
#include "7zMethods.h"
|
||||
#endif
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
#ifndef EXTRACT_ONLY
|
||||
|
||||
struct COneMethodInfo
|
||||
{
|
||||
CObjectVector<CProperty> CoderProperties;
|
||||
UString MethodName;
|
||||
};
|
||||
#endif
|
||||
|
||||
// {23170F69-40C1-278A-1000-000110050000}
|
||||
DEFINE_GUID(CLSID_CFormat7z,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x05, 0x00, 0x00);
|
||||
|
||||
class CHandler:
|
||||
public IInArchive,
|
||||
#ifndef EXTRACT_ONLY
|
||||
public IOutArchive,
|
||||
public ISetProperties,
|
||||
#endif
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
#ifdef EXTRACT_ONLY
|
||||
MY_UNKNOWN_IMP
|
||||
#else
|
||||
MY_UNKNOWN_IMP3(
|
||||
IInArchive,
|
||||
IOutArchive,
|
||||
ISetProperties
|
||||
)
|
||||
#endif
|
||||
|
||||
STDMETHOD(Open)(IInStream *stream,
|
||||
const UINT64 *maxCheckStartPosition,
|
||||
IArchiveOpenCallback *openArchiveCallback);
|
||||
STDMETHOD(Close)();
|
||||
|
||||
STDMETHOD(GetNumberOfItems)(UINT32 *numItems);
|
||||
STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value);
|
||||
STDMETHOD(Extract)(const UINT32* indices, UINT32 numItems,
|
||||
INT32 testMode, IArchiveExtractCallback *extractCallback);
|
||||
|
||||
STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value);
|
||||
|
||||
STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties);
|
||||
STDMETHOD(GetPropertyInfo)(UINT32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType);
|
||||
|
||||
STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties);
|
||||
STDMETHOD(GetArchivePropertyInfo)(UINT32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType);
|
||||
|
||||
|
||||
#ifndef EXTRACT_ONLY
|
||||
// IOutArchiveHandler
|
||||
STDMETHOD(UpdateItems)(IOutStream *outStream, UINT32 numItems,
|
||||
IArchiveUpdateCallback *updateCallback);
|
||||
|
||||
STDMETHOD(GetFileTimeType)(UINT32 *type);
|
||||
|
||||
// ISetProperties
|
||||
STDMETHOD(SetProperties)(const BSTR *names, const PROPVARIANT *values, INT32 numProperties);
|
||||
|
||||
HRESULT SetSolidSettings(const UString &s);
|
||||
HRESULT SetSolidSettings(const PROPVARIANT &value);
|
||||
#endif
|
||||
|
||||
CHandler();
|
||||
|
||||
private:
|
||||
CMyComPtr<IInStream> _inStream;
|
||||
|
||||
NArchive::N7z::CArchiveDatabaseEx _database;
|
||||
|
||||
#ifndef EXTRACT_ONLY
|
||||
CObjectVector<COneMethodInfo> _methods;
|
||||
CRecordVector<CBind> _binds;
|
||||
bool _removeSfxBlock;
|
||||
UINT64 _numSolidFiles;
|
||||
UINT64 _numSolidBytes;
|
||||
bool _numSolidBytesDefined;
|
||||
bool _solidExtension;
|
||||
|
||||
bool _compressHeaders;
|
||||
bool _compressHeadersFull;
|
||||
bool _encryptHeaders;
|
||||
|
||||
bool _copyMode;
|
||||
UINT32 _defaultDicSize;
|
||||
UINT32 _defaultAlgorithm;
|
||||
UINT32 _defaultFastBytes;
|
||||
UString _defaultMatchFinder;
|
||||
bool _autoFilter;
|
||||
bool _multiThread;
|
||||
UINT32 _level;
|
||||
|
||||
HRESULT SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value);
|
||||
HRESULT SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString);
|
||||
|
||||
HRESULT SetPassword(CCompressionMethodMode &methodMode,
|
||||
IArchiveUpdateCallback *updateCallback);
|
||||
|
||||
HRESULT SetCompressionMethod(CCompressionMethodMode &method,
|
||||
CObjectVector<COneMethodInfo> &methodsInfo,
|
||||
bool multiThread);
|
||||
|
||||
HRESULT SetCompressionMethod(
|
||||
CCompressionMethodMode &method,
|
||||
CCompressionMethodMode &headerMethod);
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef _SFX
|
||||
|
||||
CRecordVector<UINT64> _fileInfoPopIDs;
|
||||
void FillPopIDs();
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef EXTRACT_ONLY
|
||||
|
||||
UINT64 GetUINT64MAX() const
|
||||
{
|
||||
return
|
||||
#if (__GNUC__)
|
||||
0xFFFFFFFFFFFFFFFFLL
|
||||
#else
|
||||
0xFFFFFFFFFFFFFFFF
|
||||
#endif
|
||||
;
|
||||
}
|
||||
void InitSolidFiles() { _numSolidFiles = GetUINT64MAX(); }
|
||||
void InitSolidSize() { _numSolidBytes = GetUINT64MAX(); }
|
||||
void InitSolid()
|
||||
{
|
||||
InitSolidFiles();
|
||||
InitSolidSize();
|
||||
_solidExtension = false;
|
||||
_numSolidBytesDefined = false;
|
||||
}
|
||||
/*
|
||||
void InitSolidPart()
|
||||
{
|
||||
if (_numSolidFiles <= 1)
|
||||
InitSolidFiles();
|
||||
}
|
||||
*/
|
||||
void SetSolidBytesLimit()
|
||||
{
|
||||
_numSolidBytes = ((UINT64)_defaultDicSize) << 7;
|
||||
const UINT64 kMinSize = (1<<24);
|
||||
if (_numSolidBytes < kMinSize)
|
||||
_numSolidBytes = kMinSize;
|
||||
}
|
||||
void CheckAndSetSolidBytesLimit()
|
||||
{
|
||||
if (!_numSolidBytesDefined)
|
||||
{
|
||||
if (_copyMode)
|
||||
_numSolidBytes = 0;
|
||||
else
|
||||
SetSolidBytesLimit();
|
||||
}
|
||||
}
|
||||
|
||||
void Init()
|
||||
{
|
||||
_removeSfxBlock = false;
|
||||
_compressHeaders = true;
|
||||
_compressHeadersFull = true;
|
||||
_encryptHeaders = false;
|
||||
_multiThread = false;
|
||||
_copyMode = false;
|
||||
_defaultDicSize = (1 << 21);
|
||||
_defaultAlgorithm = 1;
|
||||
_defaultFastBytes = 32;
|
||||
_defaultMatchFinder = L"BT4";
|
||||
_level = 5;
|
||||
_autoFilter = true;
|
||||
InitSolid();
|
||||
SetSolidBytesLimit();
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
1160
7zip/Archive/7z/7zHandlerOut.cpp
Executable file
1160
7zip/Archive/7z/7zHandlerOut.cpp
Executable file
File diff suppressed because it is too large
Load Diff
18
7zip/Archive/7z/7zHeader.cpp
Executable file
18
7zip/Archive/7z/7zHeader.cpp
Executable file
@@ -0,0 +1,18 @@
|
||||
// 7z/Header.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "7zHeader.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
BYTE kSignature[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C};
|
||||
|
||||
class SignatureInitializer
|
||||
{
|
||||
public:
|
||||
SignatureInitializer() { kSignature[0]--; };
|
||||
} g_SignatureInitializer;
|
||||
|
||||
}}
|
||||
|
||||
85
7zip/Archive/7z/7zHeader.h
Executable file
85
7zip/Archive/7z/7zHeader.h
Executable file
@@ -0,0 +1,85 @@
|
||||
// 7z/Header.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __7Z_HEADER_H
|
||||
#define __7Z_HEADER_H
|
||||
|
||||
// #include "Common/Types.h"
|
||||
// #include "../../../Common/CRC.h"
|
||||
|
||||
#include "7zMethodID.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
#pragma pack( push, Pragma7zHeaders)
|
||||
#pragma pack( push, 1)
|
||||
|
||||
const int kSignatureSize = 6;
|
||||
extern BYTE kSignature[kSignatureSize];
|
||||
|
||||
struct CArchiveVersion
|
||||
{
|
||||
BYTE Major;
|
||||
BYTE Minor;
|
||||
};
|
||||
|
||||
struct CStartHeader
|
||||
{
|
||||
UINT64 NextHeaderOffset;
|
||||
UINT64 NextHeaderSize;
|
||||
UINT32 NextHeaderCRC;
|
||||
};
|
||||
|
||||
namespace NID
|
||||
{
|
||||
enum EEnum
|
||||
{
|
||||
kEnd,
|
||||
|
||||
kHeader,
|
||||
|
||||
kArchiveProperties,
|
||||
|
||||
kAdditionalStreamsInfo,
|
||||
kMainStreamsInfo,
|
||||
kFilesInfo,
|
||||
|
||||
kPackInfo,
|
||||
kUnPackInfo,
|
||||
kSubStreamsInfo,
|
||||
|
||||
kSize,
|
||||
kCRC,
|
||||
|
||||
kFolder,
|
||||
|
||||
kCodersUnPackSize,
|
||||
kNumUnPackStream,
|
||||
|
||||
kEmptyStream,
|
||||
kEmptyFile,
|
||||
kAnti,
|
||||
|
||||
kName,
|
||||
kCreationTime,
|
||||
kLastAccessTime,
|
||||
kLastWriteTime,
|
||||
kWinAttributes,
|
||||
kComment,
|
||||
|
||||
kEncodedHeader,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#pragma pack(pop)
|
||||
#pragma pack(pop, Pragma7zHeaders)
|
||||
|
||||
const BYTE kMajorVersion = 0;
|
||||
|
||||
}}
|
||||
|
||||
|
||||
#endif
|
||||
1158
7zip/Archive/7z/7zIn.cpp
Executable file
1158
7zip/Archive/7z/7zIn.cpp
Executable file
File diff suppressed because it is too large
Load Diff
266
7zip/Archive/7z/7zIn.h
Executable file
266
7zip/Archive/7z/7zIn.h
Executable file
@@ -0,0 +1,266 @@
|
||||
// 7zIn.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __7Z_IN_H
|
||||
#define __7Z_IN_H
|
||||
|
||||
#include "../../IStream.h"
|
||||
#include "../../IPassword.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
#include "../../Common/InBuffer.h"
|
||||
|
||||
#include "7zHeader.h"
|
||||
#include "7zItem.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
class CInArchiveException
|
||||
{
|
||||
public:
|
||||
enum CCauseType
|
||||
{
|
||||
kUnsupportedVersion = 0,
|
||||
kUnexpectedEndOfArchive = 0,
|
||||
kIncorrectHeader,
|
||||
} Cause;
|
||||
CInArchiveException(CCauseType cause);
|
||||
};
|
||||
|
||||
struct CInArchiveInfo
|
||||
{
|
||||
CArchiveVersion Version;
|
||||
UINT64 StartPosition;
|
||||
UINT64 StartPositionAfterHeader;
|
||||
UINT64 DataStartPosition;
|
||||
UINT64 DataStartPosition2;
|
||||
CRecordVector<UINT64> FileInfoPopIDs;
|
||||
void Clear()
|
||||
{
|
||||
FileInfoPopIDs.Clear();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct CArchiveDatabaseEx: public CArchiveDatabase
|
||||
{
|
||||
CInArchiveInfo ArchiveInfo;
|
||||
CRecordVector<UINT64> PackStreamStartPositions;
|
||||
CRecordVector<UINT32> FolderStartPackStreamIndex;
|
||||
CRecordVector<UINT64> FolderStartFileIndex;
|
||||
CRecordVector<int> FileIndexToFolderIndexMap;
|
||||
|
||||
void Clear()
|
||||
{
|
||||
CArchiveDatabase::Clear();
|
||||
ArchiveInfo.Clear();
|
||||
PackStreamStartPositions.Clear();
|
||||
FolderStartPackStreamIndex.Clear();
|
||||
FolderStartFileIndex.Clear();
|
||||
FolderStartFileIndex.Clear();
|
||||
}
|
||||
|
||||
void FillFolderStartPackStream();
|
||||
void FillStartPos();
|
||||
void FillFolderStartFileIndex();
|
||||
|
||||
UINT64 GetFolderStreamPos(int folderIndex, int indexInFolder) const
|
||||
{
|
||||
return ArchiveInfo.DataStartPosition +
|
||||
PackStreamStartPositions[FolderStartPackStreamIndex[folderIndex] +
|
||||
indexInFolder];
|
||||
}
|
||||
|
||||
UINT64 GetFolderFullPackSize(int folderIndex) const
|
||||
{
|
||||
UINT32 packStreamIndex = FolderStartPackStreamIndex[folderIndex];
|
||||
const CFolder &folder = Folders[folderIndex];
|
||||
UINT64 size = 0;
|
||||
for (int i = 0; i < folder.PackStreams.Size(); i++)
|
||||
size += PackSizes[packStreamIndex + i];
|
||||
return size;
|
||||
}
|
||||
|
||||
UINT64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const
|
||||
{
|
||||
return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
|
||||
}
|
||||
};
|
||||
|
||||
class CInByte2
|
||||
{
|
||||
const BYTE *_buffer;
|
||||
UINT32 _size;
|
||||
UINT32 _pos;
|
||||
public:
|
||||
void Init(const BYTE *buffer, UINT32 size)
|
||||
{
|
||||
_buffer = buffer;
|
||||
_size = size;
|
||||
_pos = 0;
|
||||
}
|
||||
bool ReadByte(BYTE &b)
|
||||
{
|
||||
if(_pos >= _size)
|
||||
return false;
|
||||
b = _buffer[_pos++];
|
||||
return true;
|
||||
}
|
||||
void ReadBytes(void *data, UINT32 size, UINT32 &processedSize)
|
||||
{
|
||||
for(processedSize = 0; processedSize < size && _pos < _size; processedSize++)
|
||||
((BYTE *)data)[processedSize] = _buffer[_pos++];
|
||||
}
|
||||
|
||||
bool ReadBytes(void *data, UINT32 size)
|
||||
{
|
||||
UINT32 processedSize;
|
||||
ReadBytes(data, size, processedSize);
|
||||
return (processedSize == size);
|
||||
}
|
||||
|
||||
UINT32 GetProcessedSize() const { return _pos; }
|
||||
};
|
||||
|
||||
class CStreamSwitch;
|
||||
class CInArchive
|
||||
{
|
||||
friend class CStreamSwitch;
|
||||
|
||||
CMyComPtr<IInStream> _stream;
|
||||
|
||||
CObjectVector<CInByte2> _inByteVector;
|
||||
CInByte2 *_inByteBack;
|
||||
|
||||
UINT64 _arhiveBeginStreamPosition;
|
||||
UINT64 _position;
|
||||
|
||||
void AddByteStream(const BYTE *buffer, UINT32 size)
|
||||
{
|
||||
_inByteVector.Add(CInByte2());
|
||||
_inByteBack = &_inByteVector.Back();
|
||||
_inByteBack->Init(buffer, size);
|
||||
}
|
||||
|
||||
void DeleteByteStream()
|
||||
{
|
||||
_inByteVector.DeleteBack();
|
||||
if (!_inByteVector.IsEmpty())
|
||||
_inByteBack = &_inByteVector.Back();
|
||||
}
|
||||
|
||||
private:
|
||||
HRESULT FindAndReadSignature(IInStream *stream, const UINT64 *searchHeaderSizeLimit); // S_FALSE means is not archive
|
||||
|
||||
HRESULT ReadFileNames(CObjectVector<CFileItem> &files);
|
||||
|
||||
HRESULT ReadBytes(IInStream *stream, void *data, UINT32 size,
|
||||
UINT32 *processedSize);
|
||||
HRESULT ReadBytes(void *data, UINT32 size, UINT32 *processedSize);
|
||||
HRESULT SafeReadBytes(void *data, UINT32 size);
|
||||
|
||||
HRESULT SafeReadBytes2(void *data, UINT32 size)
|
||||
{
|
||||
if (!_inByteBack->ReadBytes(data, size))
|
||||
return E_FAIL;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT SafeReadByte2(BYTE &b)
|
||||
{
|
||||
if (!_inByteBack->ReadByte(b))
|
||||
return E_FAIL;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT SafeReadWideCharLE(wchar_t &c)
|
||||
{
|
||||
BYTE b1;
|
||||
if (!_inByteBack->ReadByte(b1))
|
||||
return E_FAIL;
|
||||
BYTE b2;
|
||||
if (!_inByteBack->ReadByte(b2))
|
||||
return E_FAIL;
|
||||
c = (int(b2) << 8) + b1;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT ReadNumber(UINT64 &value);
|
||||
|
||||
HRESULT ReadID(UINT64 &value)
|
||||
{
|
||||
return ReadNumber(value);
|
||||
}
|
||||
|
||||
HRESULT SkeepData(UINT64 size);
|
||||
HRESULT SkeepData();
|
||||
HRESULT WaitAttribute(UINT64 attribute);
|
||||
|
||||
HRESULT ReadArchiveProperties(CInArchiveInfo &archiveInfo);
|
||||
HRESULT GetNextFolderItem(CFolder &itemInfo);
|
||||
HRESULT ReadHashDigests(int numItems,
|
||||
CRecordVector<bool> &digestsDefined, CRecordVector<UINT32> &digests);
|
||||
|
||||
HRESULT ReadPackInfo(
|
||||
UINT64 &dataOffset,
|
||||
CRecordVector<UINT64> &packSizes,
|
||||
CRecordVector<bool> &packCRCsDefined,
|
||||
CRecordVector<UINT32> &packCRCs);
|
||||
|
||||
HRESULT ReadUnPackInfo(
|
||||
const CObjectVector<CByteBuffer> *dataVector,
|
||||
CObjectVector<CFolder> &folders);
|
||||
|
||||
HRESULT ReadSubStreamsInfo(
|
||||
const CObjectVector<CFolder> &folders,
|
||||
CRecordVector<UINT64> &numUnPackStreamsInFolders,
|
||||
CRecordVector<UINT64> &unPackSizes,
|
||||
CRecordVector<bool> &digestsDefined,
|
||||
CRecordVector<UINT32> &digests);
|
||||
|
||||
HRESULT CInArchive::ReadStreamsInfo(
|
||||
const CObjectVector<CByteBuffer> *dataVector,
|
||||
UINT64 &dataOffset,
|
||||
CRecordVector<UINT64> &packSizes,
|
||||
CRecordVector<bool> &packCRCsDefined,
|
||||
CRecordVector<UINT32> &packCRCs,
|
||||
CObjectVector<CFolder> &folders,
|
||||
CRecordVector<UINT64> &numUnPackStreamsInFolders,
|
||||
CRecordVector<UINT64> &unPackSizes,
|
||||
CRecordVector<bool> &digestsDefined,
|
||||
CRecordVector<UINT32> &digests);
|
||||
|
||||
|
||||
|
||||
HRESULT GetNextFileItem(CFileItem &itemInfo);
|
||||
HRESULT ReadBoolVector(UINT32 numItems, CBoolVector &vector);
|
||||
HRESULT ReadBoolVector2(UINT32 numItems, CBoolVector &vector);
|
||||
HRESULT ReadTime(const CObjectVector<CByteBuffer> &dataVector,
|
||||
CObjectVector<CFileItem> &files, UINT64 type);
|
||||
HRESULT ReadAndDecodePackedStreams(UINT64 baseOffset, UINT64 &dataOffset,
|
||||
CObjectVector<CByteBuffer> &dataVector
|
||||
#ifndef _NO_CRYPTO
|
||||
, ICryptoGetTextPassword *getTextPassword
|
||||
#endif
|
||||
);
|
||||
HRESULT ReadHeader(CArchiveDatabaseEx &database
|
||||
#ifndef _NO_CRYPTO
|
||||
,ICryptoGetTextPassword *getTextPassword
|
||||
#endif
|
||||
);
|
||||
public:
|
||||
HRESULT Open(IInStream *stream, const UINT64 *searchHeaderSizeLimit); // S_FALSE means is not archive
|
||||
void Close();
|
||||
|
||||
HRESULT ReadDatabase(CArchiveDatabaseEx &database
|
||||
#ifndef _NO_CRYPTO
|
||||
,ICryptoGetTextPassword *getTextPassword
|
||||
#endif
|
||||
);
|
||||
HRESULT CheckIntegrity();
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
195
7zip/Archive/7z/7zItem.h
Executable file
195
7zip/Archive/7z/7zItem.h
Executable file
@@ -0,0 +1,195 @@
|
||||
// 7zItem.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __7Z_ITEM_H
|
||||
#define __7Z_ITEM_H
|
||||
|
||||
#include "../../../Common/Buffer.h"
|
||||
#include "7zMethodID.h"
|
||||
#include "7zHeader.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
struct CAltCoderInfo
|
||||
{
|
||||
CMethodID MethodID;
|
||||
CByteBuffer Properties;
|
||||
};
|
||||
|
||||
struct CCoderInfo
|
||||
{
|
||||
UINT64 NumInStreams;
|
||||
UINT64 NumOutStreams;
|
||||
CObjectVector<CAltCoderInfo> AltCoders;
|
||||
bool IsSimpleCoder() const
|
||||
{ return (NumInStreams == 1) && (NumOutStreams == 1); }
|
||||
};
|
||||
|
||||
struct CPackStreamInfo
|
||||
{
|
||||
UINT64 Index;
|
||||
};
|
||||
|
||||
struct CBindPair
|
||||
{
|
||||
UINT64 InIndex;
|
||||
UINT64 OutIndex;
|
||||
};
|
||||
|
||||
struct CFolder
|
||||
{
|
||||
CObjectVector<CCoderInfo> Coders;
|
||||
CRecordVector<CBindPair> BindPairs;
|
||||
CRecordVector<CPackStreamInfo> PackStreams;
|
||||
CRecordVector<UINT64> UnPackSizes;
|
||||
bool UnPackCRCDefined;
|
||||
UINT32 UnPackCRC;
|
||||
|
||||
CFolder(): UnPackCRCDefined(false) {}
|
||||
|
||||
UINT64 GetUnPackSize() const // test it
|
||||
{
|
||||
if (UnPackSizes.IsEmpty())
|
||||
return 0;
|
||||
for (int i = UnPackSizes.Size() - 1; i >= 0; i--)
|
||||
if (FindBindPairForOutStream(i) < 0)
|
||||
return UnPackSizes[i];
|
||||
throw 1;
|
||||
}
|
||||
UINT64 GetNumOutStreams() const
|
||||
{
|
||||
UINT64 result = 0;
|
||||
for (int i = 0; i < Coders.Size(); i++)
|
||||
result += Coders[i].NumOutStreams;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int FindBindPairForInStream(int inStreamIndex) const
|
||||
{
|
||||
for(int i = 0; i < BindPairs.Size(); i++)
|
||||
if (BindPairs[i].InIndex == inStreamIndex)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
int FindBindPairForOutStream(int outStreamIndex) const
|
||||
{
|
||||
for(int i = 0; i < BindPairs.Size(); i++)
|
||||
if (BindPairs[i].OutIndex == outStreamIndex)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
int FindPackStreamArrayIndex(int inStreamIndex) const
|
||||
{
|
||||
for(int i = 0; i < PackStreams.Size(); i++)
|
||||
if (PackStreams[i].Index == inStreamIndex)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
typedef FILETIME CArchiveFileTime;
|
||||
|
||||
class CFileItem
|
||||
{
|
||||
public:
|
||||
CArchiveFileTime CreationTime;
|
||||
CArchiveFileTime LastWriteTime;
|
||||
CArchiveFileTime LastAccessTime;
|
||||
UINT64 UnPackSize;
|
||||
UINT32 Attributes;
|
||||
UINT32 FileCRC;
|
||||
UString Name;
|
||||
|
||||
bool HasStream; // Test it !!! it means that there is
|
||||
// stream in some folder. It can be empty stream
|
||||
bool IsDirectory;
|
||||
bool IsAnti;
|
||||
bool FileCRCIsDefined;
|
||||
bool AreAttributesDefined;
|
||||
bool IsCreationTimeDefined;
|
||||
bool IsLastWriteTimeDefined;
|
||||
bool IsLastAccessTimeDefined;
|
||||
|
||||
/*
|
||||
const bool HasStream() const {
|
||||
return !IsDirectory && !IsAnti && UnPackSize != 0; }
|
||||
*/
|
||||
CFileItem():
|
||||
AreAttributesDefined(false),
|
||||
IsCreationTimeDefined(false),
|
||||
IsLastWriteTimeDefined(false),
|
||||
IsLastAccessTimeDefined(false),
|
||||
IsDirectory(false),
|
||||
FileCRCIsDefined(false),
|
||||
IsAnti(false),
|
||||
HasStream(true)
|
||||
{}
|
||||
void SetAttributes(UINT32 attributes)
|
||||
{
|
||||
AreAttributesDefined = true;
|
||||
Attributes = attributes;
|
||||
}
|
||||
void SetCreationTime(CArchiveFileTime creationTime)
|
||||
{
|
||||
IsCreationTimeDefined = true;
|
||||
CreationTime = creationTime;
|
||||
}
|
||||
void SetLastWriteTime(CArchiveFileTime lastWriteTime)
|
||||
{
|
||||
IsLastWriteTimeDefined = true;
|
||||
LastWriteTime = lastWriteTime;
|
||||
}
|
||||
void SetLastAccessTime(CArchiveFileTime lastAccessTime)
|
||||
{
|
||||
IsLastAccessTimeDefined = true;
|
||||
LastAccessTime = lastAccessTime;
|
||||
}
|
||||
};
|
||||
|
||||
struct CArchiveDatabase
|
||||
{
|
||||
CRecordVector<UINT64> PackSizes;
|
||||
CRecordVector<bool> PackCRCsDefined;
|
||||
CRecordVector<UINT32> PackCRCs;
|
||||
CObjectVector<CFolder> Folders;
|
||||
CRecordVector<UINT64> NumUnPackStreamsVector;
|
||||
CObjectVector<CFileItem> Files;
|
||||
void Clear()
|
||||
{
|
||||
PackSizes.Clear();
|
||||
PackCRCsDefined.Clear();
|
||||
PackCRCs.Clear();
|
||||
Folders.Clear();
|
||||
NumUnPackStreamsVector.Clear();
|
||||
Files.Clear();
|
||||
}
|
||||
bool IsEmpty() const
|
||||
{
|
||||
return (PackSizes.IsEmpty() &&
|
||||
PackCRCsDefined.IsEmpty() &&
|
||||
PackCRCs.IsEmpty() &&
|
||||
Folders.IsEmpty() &&
|
||||
NumUnPackStreamsVector.IsEmpty() &&
|
||||
Files.IsEmpty());
|
||||
}
|
||||
};
|
||||
|
||||
struct CArchiveHeaderDatabase
|
||||
{
|
||||
CRecordVector<UINT64> PackSizes;
|
||||
CObjectVector<CFolder> Folders;
|
||||
CRecordVector<UINT32> CRCs;
|
||||
void Clear()
|
||||
{
|
||||
PackSizes.Clear();
|
||||
Folders.Clear();
|
||||
CRCs.Clear();
|
||||
}
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
68
7zip/Archive/7z/7zMethodID.cpp
Executable file
68
7zip/Archive/7z/7zMethodID.cpp
Executable file
@@ -0,0 +1,68 @@
|
||||
// 7zMethodID.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "7zMethodID.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
static inline wchar_t GetHex(BYTE value)
|
||||
{
|
||||
return (value < 10) ? ('0' + value) : ('A' + (value - 10));
|
||||
}
|
||||
|
||||
static bool HexCharToInt(wchar_t value, BYTE &result)
|
||||
{
|
||||
if (value >= '0' && value <= '9')
|
||||
result = value - '0';
|
||||
else if (value >= 'a' && value <= 'f')
|
||||
result = 10 + value - 'a';
|
||||
else if (value >= 'A' && value <= 'F')
|
||||
result = 10 + value - 'A';
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool TwoHexCharsToInt(wchar_t valueHigh, wchar_t valueLow, BYTE &result)
|
||||
{
|
||||
BYTE resultHigh, resultLow;
|
||||
if (!HexCharToInt(valueHigh, resultHigh))
|
||||
return false;
|
||||
if (!HexCharToInt(valueLow, resultLow))
|
||||
return false;
|
||||
result = (resultHigh << 4) + resultLow;
|
||||
return true;
|
||||
}
|
||||
|
||||
UString CMethodID::ConvertToString() const
|
||||
{
|
||||
UString result;
|
||||
for (int i = 0; i < IDSize; i++)
|
||||
{
|
||||
BYTE b = ID[i];
|
||||
result += GetHex(b >> 4);
|
||||
result += GetHex(b & 0xF);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool CMethodID::ConvertFromString(const UString &srcString)
|
||||
{
|
||||
int length = srcString.Length();
|
||||
if ((length & 1) != 0)
|
||||
return false;
|
||||
IDSize = length / 2;
|
||||
if (IDSize > kMethodIDSize)
|
||||
return false;
|
||||
UINT32 i;
|
||||
for(i = 0; i < IDSize; i++)
|
||||
if (!TwoHexCharsToInt(srcString[i * 2], srcString[i * 2 + 1], ID[i]))
|
||||
return false;
|
||||
for(i = IDSize; i < kMethodIDSize; i++)
|
||||
ID[i] = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
}}
|
||||
38
7zip/Archive/7z/7zMethodID.h
Executable file
38
7zip/Archive/7z/7zMethodID.h
Executable file
@@ -0,0 +1,38 @@
|
||||
// 7zMethodID.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __7Z_METHOD_ID_H
|
||||
#define __7Z_METHOD_ID_H
|
||||
|
||||
#include "../../../Common/String.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
const int kMethodIDSize = 16;
|
||||
|
||||
struct CMethodID
|
||||
{
|
||||
BYTE ID[kMethodIDSize];
|
||||
UINT32 IDSize;
|
||||
UString ConvertToString() const;
|
||||
bool ConvertFromString(const UString &srcString);
|
||||
};
|
||||
|
||||
inline bool operator==(const CMethodID &a1, const CMethodID &a2)
|
||||
{
|
||||
if (a1.IDSize != a2.IDSize)
|
||||
return false;
|
||||
for (UINT32 i = 0; i < a1.IDSize; i++)
|
||||
if (a1.ID[i] != a2.ID[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool operator!=(const CMethodID &a1, const CMethodID &a2)
|
||||
{ return !(a1 == a2); }
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
174
7zip/Archive/7z/7zMethods.cpp
Executable file
174
7zip/Archive/7z/7zMethods.cpp
Executable file
@@ -0,0 +1,174 @@
|
||||
// 7zMethods.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "7zMethods.h"
|
||||
|
||||
#include "../../../Windows/FileFind.h"
|
||||
#include "../../../Windows/DLL.h"
|
||||
#include "../../../Windows/PropVariant.h"
|
||||
#include "../../../Windows/Synchronization.h"
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../Common/CodecsPath.h"
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
static CObjectVector<CMethodInfo2> g_Methods;
|
||||
static bool g_Loaded = false;
|
||||
|
||||
typedef UINT32 (WINAPI *GetNumberOfMethodsFunc)(UINT32 *numMethods);
|
||||
|
||||
typedef UINT32 (WINAPI *GetMethodPropertyFunc)(
|
||||
UINT32 index, PROPID propID, PROPVARIANT *value);
|
||||
|
||||
static void Load(const CSysString &folderPrefix)
|
||||
{
|
||||
NFile::NFind::CEnumerator enumerator(folderPrefix + CSysString(TEXT("*")));
|
||||
NFile::NFind::CFileInfo fileInfo;
|
||||
while (enumerator.Next(fileInfo))
|
||||
{
|
||||
if (fileInfo.IsDirectory())
|
||||
continue;
|
||||
CSysString filePath = folderPrefix + fileInfo.Name;
|
||||
{
|
||||
NDLL::CLibrary library;
|
||||
if (!library.LoadEx(filePath, LOAD_LIBRARY_AS_DATAFILE))
|
||||
continue;
|
||||
}
|
||||
NDLL::CLibrary library;
|
||||
if (!library.Load(filePath))
|
||||
continue;
|
||||
GetMethodPropertyFunc getMethodProperty = (GetMethodPropertyFunc)
|
||||
library.GetProcAddress("GetMethodProperty");
|
||||
if (getMethodProperty == NULL)
|
||||
continue;
|
||||
|
||||
UINT32 numMethods = 1;
|
||||
GetNumberOfMethodsFunc getNumberOfMethodsFunc = (GetNumberOfMethodsFunc)
|
||||
library.GetProcAddress("GetNumberOfMethods");
|
||||
if (getNumberOfMethodsFunc != NULL)
|
||||
if (getNumberOfMethodsFunc(&numMethods) != S_OK)
|
||||
continue;
|
||||
|
||||
for(UINT32 i = 0; i < numMethods; i++)
|
||||
{
|
||||
CMethodInfo2 info;
|
||||
info.FilePath = filePath;
|
||||
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
if (getMethodProperty(i, NMethodPropID::kID, &propVariant) != S_OK)
|
||||
continue;
|
||||
if (propVariant.vt != VT_BSTR)
|
||||
continue;
|
||||
info.MethodID.IDSize = SysStringByteLen(propVariant.bstrVal);
|
||||
memmove(info.MethodID.ID, propVariant.bstrVal, info.MethodID.IDSize);
|
||||
propVariant.Clear();
|
||||
|
||||
if (getMethodProperty(i, NMethodPropID::kName, &propVariant) != S_OK)
|
||||
continue;
|
||||
if (propVariant.vt == VT_EMPTY)
|
||||
{
|
||||
}
|
||||
else if (propVariant.vt == VT_BSTR)
|
||||
info.Name = propVariant.bstrVal;
|
||||
else
|
||||
continue;
|
||||
propVariant.Clear();
|
||||
|
||||
if (getMethodProperty (i, NMethodPropID::kEncoder, &propVariant) != S_OK)
|
||||
continue;
|
||||
if (propVariant.vt == VT_EMPTY)
|
||||
info.EncoderIsAssigned = false;
|
||||
else if (propVariant.vt == VT_BSTR)
|
||||
{
|
||||
info.EncoderIsAssigned = true;
|
||||
info.Encoder = *(const GUID *)propVariant.bstrVal;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
propVariant.Clear();
|
||||
|
||||
if (getMethodProperty (i, NMethodPropID::kDecoder, &propVariant) != S_OK)
|
||||
continue;
|
||||
if (propVariant.vt == VT_EMPTY)
|
||||
info.DecoderIsAssigned = false;
|
||||
else if (propVariant.vt == VT_BSTR)
|
||||
{
|
||||
info.DecoderIsAssigned = true;
|
||||
info.Decoder = *(const GUID *)propVariant.bstrVal;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
propVariant.Clear();
|
||||
|
||||
if (getMethodProperty (i, NMethodPropID::kInStreams, &propVariant) != S_OK)
|
||||
continue;
|
||||
if (propVariant.vt == VT_EMPTY)
|
||||
info.NumInStreams = 1;
|
||||
else if (propVariant.vt == VT_UI4)
|
||||
info.NumInStreams = propVariant.ulVal;
|
||||
else
|
||||
continue;
|
||||
propVariant.Clear();
|
||||
|
||||
if (getMethodProperty (i, NMethodPropID::kOutStreams, &propVariant) != S_OK)
|
||||
continue;
|
||||
if (propVariant.vt == VT_EMPTY)
|
||||
info.NumOutStreams = 1;
|
||||
else if (propVariant.vt == VT_UI4)
|
||||
info.NumOutStreams = propVariant.ulVal;
|
||||
else
|
||||
continue;
|
||||
propVariant.Clear();
|
||||
|
||||
g_Methods.Add(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static NSynchronization::CCriticalSection g_CriticalSection;
|
||||
|
||||
void LoadMethodMap()
|
||||
{
|
||||
NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
|
||||
if (g_Loaded)
|
||||
return;
|
||||
g_Loaded = true;
|
||||
Load(GetCodecsFolderPrefix());
|
||||
}
|
||||
|
||||
bool GetMethodInfo(const CMethodID &methodID, CMethodInfo &methodInfo)
|
||||
{
|
||||
for(int i = 0; i < g_Methods.Size(); i++)
|
||||
{
|
||||
const CMethodInfo2 &method = g_Methods[i];
|
||||
if (method.MethodID == methodID)
|
||||
{
|
||||
methodInfo = (CMethodInfo)method;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GetMethodInfo(const UString &name, CMethodInfo2 &methodInfo)
|
||||
{
|
||||
for(int i = 0; i < g_Methods.Size(); i++)
|
||||
{
|
||||
const CMethodInfo2 &method = g_Methods[i];
|
||||
if (method.Name.CollateNoCase(name) == 0)
|
||||
{
|
||||
methodInfo = method;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
|
||||
36
7zip/Archive/7z/7zMethods.h
Executable file
36
7zip/Archive/7z/7zMethods.h
Executable file
@@ -0,0 +1,36 @@
|
||||
// 7zMethods.h
|
||||
|
||||
#ifndef __7Z_METHODS_H
|
||||
#define __7Z_METHODS_H
|
||||
|
||||
#include "7zMethodID.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
struct CMethodInfo
|
||||
{
|
||||
UString Name;
|
||||
bool EncoderIsAssigned;
|
||||
bool DecoderIsAssigned;
|
||||
UINT32 NumInStreams;
|
||||
UINT32 NumOutStreams;
|
||||
CLSID Encoder;
|
||||
CLSID Decoder;
|
||||
// UString Description;
|
||||
CSysString FilePath;
|
||||
};
|
||||
|
||||
struct CMethodInfo2: public CMethodInfo
|
||||
{
|
||||
CMethodID MethodID;
|
||||
};
|
||||
|
||||
void LoadMethodMap();
|
||||
bool GetMethodInfo(const CMethodID &methodID, CMethodInfo &methodInfo);
|
||||
bool GetMethodInfo(const UString &name, CMethodInfo2 &methodInfo);
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
853
7zip/Archive/7z/7zOut.cpp
Executable file
853
7zip/Archive/7z/7zOut.cpp
Executable file
@@ -0,0 +1,853 @@
|
||||
// 7zOut.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "7zOut.h"
|
||||
#include "../../Common/StreamObjects.h"
|
||||
|
||||
static HRESULT WriteBytes(IOutStream *stream, const void *data, UINT32 size)
|
||||
{
|
||||
UINT32 processedSize;
|
||||
RINOK(stream->Write(data, size, &processedSize));
|
||||
if(processedSize != size)
|
||||
return E_FAIL;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
HRESULT COutArchive::Create(IOutStream *stream)
|
||||
{
|
||||
Close();
|
||||
RINOK(::WriteBytes(stream, kSignature, kSignatureSize));
|
||||
CArchiveVersion archiveVersion;
|
||||
archiveVersion.Major = kMajorVersion;
|
||||
archiveVersion.Minor = 2;
|
||||
RINOK(::WriteBytes(stream, &archiveVersion, sizeof(archiveVersion)));
|
||||
RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_prefixHeaderPos));
|
||||
Stream = stream;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void COutArchive::Close()
|
||||
{
|
||||
Stream.Release();
|
||||
}
|
||||
|
||||
HRESULT COutArchive::SkeepPrefixArchiveHeader()
|
||||
{
|
||||
return Stream->Seek(sizeof(CStartHeader) + sizeof(UINT32), STREAM_SEEK_CUR, NULL);
|
||||
}
|
||||
|
||||
HRESULT COutArchive::WriteBytes(const void *data, UINT32 size)
|
||||
{
|
||||
return ::WriteBytes(Stream, data, size);
|
||||
}
|
||||
|
||||
|
||||
HRESULT COutArchive::WriteBytes2(const void *data, UINT32 size)
|
||||
{
|
||||
if (_mainMode)
|
||||
{
|
||||
if (_dynamicMode)
|
||||
_dynamicBuffer.Write(data, size);
|
||||
else
|
||||
_outByte.WriteBytes(data, size);
|
||||
_crc.Update(data, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_countMode)
|
||||
_countSize += size;
|
||||
else
|
||||
RINOK(_outByte2.Write(data, size));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT COutArchive::WriteBytes2(const CByteBuffer &data)
|
||||
{
|
||||
return WriteBytes2(data, data.GetCapacity());
|
||||
}
|
||||
|
||||
HRESULT COutArchive::WriteByte2(BYTE b)
|
||||
{
|
||||
return WriteBytes2(&b, 1);
|
||||
}
|
||||
|
||||
HRESULT COutArchive::WriteNumber(UINT64 value)
|
||||
{
|
||||
BYTE firstByte = 0;
|
||||
BYTE mask = 0x80;
|
||||
int i;
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
if (value < ((UINT64(1) << ( 7 * (i + 1)))))
|
||||
{
|
||||
firstByte |= BYTE(value >> (8 * i));
|
||||
break;
|
||||
}
|
||||
firstByte |= mask;
|
||||
mask >>= 1;
|
||||
}
|
||||
RINOK(WriteByte2(firstByte));
|
||||
return WriteBytes2(&value, i);
|
||||
}
|
||||
|
||||
static UINT32 GetBigNumberSize(UINT64 value)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 8; i++)
|
||||
if (value < ((UINT64(1) << ( 7 * (i + 1)))))
|
||||
break;
|
||||
return 1 + i;
|
||||
}
|
||||
|
||||
HRESULT COutArchive::WriteFolderHeader(const CFolder &itemInfo)
|
||||
{
|
||||
RINOK(WriteNumber(itemInfo.Coders.Size()));
|
||||
int i;
|
||||
for (i = 0; i < itemInfo.Coders.Size(); i++)
|
||||
{
|
||||
const CCoderInfo &coderInfo = itemInfo.Coders[i];
|
||||
for (int j = 0; j < coderInfo.AltCoders.Size(); j++)
|
||||
{
|
||||
const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders[j];
|
||||
UINT64 propertiesSize = altCoderInfo.Properties.GetCapacity();
|
||||
|
||||
BYTE b;
|
||||
b = altCoderInfo.MethodID.IDSize & 0xF;
|
||||
bool isComplex = (coderInfo.NumInStreams != 1) ||
|
||||
(coderInfo.NumOutStreams != 1);
|
||||
b |= (isComplex ? 0x10 : 0);
|
||||
b |= ((propertiesSize != 0) ? 0x20 : 0 );
|
||||
b |= ((j == coderInfo.AltCoders.Size() - 1) ? 0 : 0x80 );
|
||||
RINOK(WriteByte2(b));
|
||||
RINOK(WriteBytes2(&altCoderInfo.MethodID.ID[0],
|
||||
altCoderInfo.MethodID.IDSize));
|
||||
if (isComplex)
|
||||
{
|
||||
RINOK(WriteNumber(coderInfo.NumInStreams));
|
||||
RINOK(WriteNumber(coderInfo.NumOutStreams));
|
||||
}
|
||||
if (propertiesSize == 0)
|
||||
continue;
|
||||
RINOK(WriteNumber(propertiesSize));
|
||||
RINOK(WriteBytes2(altCoderInfo.Properties, (UINT32)propertiesSize));
|
||||
}
|
||||
}
|
||||
// RINOK(WriteNumber(itemInfo.BindPairs.Size()));
|
||||
for (i = 0; i < itemInfo.BindPairs.Size(); i++)
|
||||
{
|
||||
const CBindPair &bindPair = itemInfo.BindPairs[i];
|
||||
RINOK(WriteNumber(bindPair.InIndex));
|
||||
RINOK(WriteNumber(bindPair.OutIndex));
|
||||
}
|
||||
if (itemInfo.PackStreams.Size() > 1)
|
||||
for (i = 0; i < itemInfo.PackStreams.Size(); i++)
|
||||
{
|
||||
const CPackStreamInfo &packStreamInfo = itemInfo.PackStreams[i];
|
||||
RINOK(WriteNumber(packStreamInfo.Index));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT COutArchive::WriteBoolVector(const CBoolVector &boolVector)
|
||||
{
|
||||
BYTE b = 0;
|
||||
BYTE mask = 0x80;
|
||||
for(int i = 0; i < boolVector.Size(); i++)
|
||||
{
|
||||
if (boolVector[i])
|
||||
b |= mask;
|
||||
mask >>= 1;
|
||||
if (mask == 0)
|
||||
{
|
||||
RINOK(WriteBytes2(&b, 1));
|
||||
mask = 0x80;
|
||||
b = 0;
|
||||
}
|
||||
}
|
||||
if (mask != 0x80)
|
||||
{
|
||||
RINOK(WriteBytes2(&b, 1));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
HRESULT COutArchive::WriteHashDigests(
|
||||
const CRecordVector<bool> &digestsDefined,
|
||||
const CRecordVector<UINT32> &digests)
|
||||
{
|
||||
int numDefined = 0;
|
||||
int i;
|
||||
for(i = 0; i < digestsDefined.Size(); i++)
|
||||
if (digestsDefined[i])
|
||||
numDefined++;
|
||||
if (numDefined == 0)
|
||||
return S_OK;
|
||||
|
||||
RINOK(WriteByte2(NID::kCRC));
|
||||
if (numDefined == digestsDefined.Size())
|
||||
{
|
||||
RINOK(WriteByte2(1));
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(WriteByte2(0));
|
||||
RINOK(WriteBoolVector(digestsDefined));
|
||||
}
|
||||
for(i = 0; i < digests.Size(); i++)
|
||||
{
|
||||
if(digestsDefined[i])
|
||||
RINOK(WriteBytes2(&digests[i], sizeof(digests[i])));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT COutArchive::WritePackInfo(
|
||||
UINT64 dataOffset,
|
||||
const CRecordVector<UINT64> &packSizes,
|
||||
const CRecordVector<bool> &packCRCsDefined,
|
||||
const CRecordVector<UINT32> &packCRCs)
|
||||
{
|
||||
if (packSizes.IsEmpty())
|
||||
return S_OK;
|
||||
RINOK(WriteByte2(NID::kPackInfo));
|
||||
RINOK(WriteNumber(dataOffset));
|
||||
RINOK(WriteNumber(packSizes.Size()));
|
||||
RINOK(WriteByte2(NID::kSize));
|
||||
for(int i = 0; i < packSizes.Size(); i++)
|
||||
RINOK(WriteNumber(packSizes[i]));
|
||||
|
||||
RINOK(WriteHashDigests(packCRCsDefined, packCRCs));
|
||||
|
||||
return WriteByte2(NID::kEnd);
|
||||
}
|
||||
|
||||
HRESULT COutArchive::WriteUnPackInfo(
|
||||
bool externalFolders,
|
||||
UINT64 externalFoldersStreamIndex,
|
||||
const CObjectVector<CFolder> &folders)
|
||||
{
|
||||
if (folders.IsEmpty())
|
||||
return S_OK;
|
||||
|
||||
RINOK(WriteByte2(NID::kUnPackInfo));
|
||||
|
||||
RINOK(WriteByte2(NID::kFolder));
|
||||
RINOK(WriteNumber(folders.Size()));
|
||||
if (externalFolders)
|
||||
{
|
||||
RINOK(WriteByte2(1));
|
||||
RINOK(WriteNumber(externalFoldersStreamIndex));
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(WriteByte2(0));
|
||||
for(int i = 0; i < folders.Size(); i++)
|
||||
RINOK(WriteFolderHeader(folders[i]));
|
||||
}
|
||||
|
||||
RINOK(WriteByte2(NID::kCodersUnPackSize));
|
||||
int i;
|
||||
for(i = 0; i < folders.Size(); i++)
|
||||
{
|
||||
const CFolder &folder = folders[i];
|
||||
for (int j = 0; j < folder.UnPackSizes.Size(); j++)
|
||||
RINOK(WriteNumber(folder.UnPackSizes[j]));
|
||||
}
|
||||
|
||||
CRecordVector<bool> unPackCRCsDefined;
|
||||
CRecordVector<UINT32> unPackCRCs;
|
||||
for(i = 0; i < folders.Size(); i++)
|
||||
{
|
||||
const CFolder &folder = folders[i];
|
||||
unPackCRCsDefined.Add(folder.UnPackCRCDefined);
|
||||
unPackCRCs.Add(folder.UnPackCRC);
|
||||
}
|
||||
RINOK(WriteHashDigests(unPackCRCsDefined, unPackCRCs));
|
||||
|
||||
return WriteByte2(NID::kEnd);
|
||||
}
|
||||
|
||||
HRESULT COutArchive::WriteSubStreamsInfo(
|
||||
const CObjectVector<CFolder> &folders,
|
||||
const CRecordVector<UINT64> &numUnPackStreamsInFolders,
|
||||
const CRecordVector<UINT64> &unPackSizes,
|
||||
const CRecordVector<bool> &digestsDefined,
|
||||
const CRecordVector<UINT32> &digests)
|
||||
{
|
||||
RINOK(WriteByte2(NID::kSubStreamsInfo));
|
||||
|
||||
int i;
|
||||
for(i = 0; i < numUnPackStreamsInFolders.Size(); i++)
|
||||
{
|
||||
if (numUnPackStreamsInFolders[i] != 1)
|
||||
{
|
||||
RINOK(WriteByte2(NID::kNumUnPackStream));
|
||||
for(i = 0; i < numUnPackStreamsInFolders.Size(); i++)
|
||||
RINOK(WriteNumber(numUnPackStreamsInFolders[i]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UINT32 needFlag = true;
|
||||
UINT32 index = 0;
|
||||
for(i = 0; i < numUnPackStreamsInFolders.Size(); i++)
|
||||
for (UINT32 j = 0; j < numUnPackStreamsInFolders[i]; j++)
|
||||
{
|
||||
if (j + 1 != numUnPackStreamsInFolders[i])
|
||||
{
|
||||
if (needFlag)
|
||||
RINOK(WriteByte2(NID::kSize));
|
||||
needFlag = false;
|
||||
RINOK(WriteNumber(unPackSizes[index]));
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
CRecordVector<bool> digestsDefined2;
|
||||
CRecordVector<UINT32> digests2;
|
||||
|
||||
int digestIndex = 0;
|
||||
for (i = 0; i < folders.Size(); i++)
|
||||
{
|
||||
int numSubStreams = (int)numUnPackStreamsInFolders[i];
|
||||
if (numSubStreams == 1 && folders[i].UnPackCRCDefined)
|
||||
digestIndex++;
|
||||
else
|
||||
for (int j = 0; j < numSubStreams; j++, digestIndex++)
|
||||
{
|
||||
digestsDefined2.Add(digestsDefined[digestIndex]);
|
||||
digests2.Add(digests[digestIndex]);
|
||||
}
|
||||
}
|
||||
RINOK(WriteHashDigests(digestsDefined2, digests2));
|
||||
return WriteByte2(NID::kEnd);
|
||||
}
|
||||
|
||||
HRESULT COutArchive::WriteTime(
|
||||
const CObjectVector<CFileItem> &files, BYTE type,
|
||||
bool isExternal, int externalDataIndex)
|
||||
{
|
||||
/////////////////////////////////////////////////
|
||||
// CreationTime
|
||||
CBoolVector boolVector;
|
||||
boolVector.Reserve(files.Size());
|
||||
bool thereAreDefined = false;
|
||||
bool allDefined = true;
|
||||
int i;
|
||||
for(i = 0; i < files.Size(); i++)
|
||||
{
|
||||
const CFileItem &item = files[i];
|
||||
bool defined;
|
||||
switch(type)
|
||||
{
|
||||
case NID::kCreationTime:
|
||||
defined = item.IsCreationTimeDefined;
|
||||
break;
|
||||
case NID::kLastWriteTime:
|
||||
defined = item.IsLastWriteTimeDefined;
|
||||
break;
|
||||
case NID::kLastAccessTime:
|
||||
defined = item.IsLastAccessTimeDefined;
|
||||
break;
|
||||
default:
|
||||
throw 1;
|
||||
}
|
||||
boolVector.Add(defined);
|
||||
thereAreDefined = (thereAreDefined || defined);
|
||||
allDefined = (allDefined && defined);
|
||||
}
|
||||
if (!thereAreDefined)
|
||||
return S_OK;
|
||||
RINOK(WriteByte2(type));
|
||||
UINT32 dataSize = 1 + 1;
|
||||
if (isExternal)
|
||||
dataSize += GetBigNumberSize(externalDataIndex);
|
||||
else
|
||||
dataSize += files.Size() * sizeof(CArchiveFileTime);
|
||||
if (allDefined)
|
||||
{
|
||||
RINOK(WriteNumber(dataSize));
|
||||
WriteByte2(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(WriteNumber(1 + (boolVector.Size() + 7) / 8 + dataSize));
|
||||
WriteByte2(0);
|
||||
RINOK(WriteBoolVector(boolVector));
|
||||
}
|
||||
if (isExternal)
|
||||
{
|
||||
RINOK(WriteByte2(1));
|
||||
RINOK(WriteNumber(externalDataIndex));
|
||||
return S_OK;
|
||||
}
|
||||
RINOK(WriteByte2(0));
|
||||
for(i = 0; i < files.Size(); i++)
|
||||
{
|
||||
if (boolVector[i])
|
||||
{
|
||||
const CFileItem &item = files[i];
|
||||
CArchiveFileTime timeValue;
|
||||
switch(type)
|
||||
{
|
||||
case NID::kCreationTime:
|
||||
timeValue = item.CreationTime;
|
||||
break;
|
||||
case NID::kLastWriteTime:
|
||||
timeValue = item.LastWriteTime;
|
||||
break;
|
||||
case NID::kLastAccessTime:
|
||||
timeValue = item.LastAccessTime;
|
||||
break;
|
||||
}
|
||||
RINOK(WriteBytes2(&timeValue, sizeof(timeValue)));
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT COutArchive::EncodeStream(CEncoder &encoder, const BYTE *data, UINT32 dataSize,
|
||||
CRecordVector<UINT64> &packSizes, CObjectVector<CFolder> &folders)
|
||||
{
|
||||
CSequentialInStreamImp *streamSpec = new CSequentialInStreamImp;
|
||||
CMyComPtr<ISequentialInStream> stream = streamSpec;
|
||||
streamSpec->Init(data, dataSize);
|
||||
CFolder folderItem;
|
||||
folderItem.UnPackCRCDefined = true;
|
||||
folderItem.UnPackCRC = CCRC::CalculateDigest(data, dataSize);
|
||||
RINOK(encoder.Encode(stream, NULL,
|
||||
folderItem, Stream,
|
||||
packSizes, NULL));
|
||||
folders.Add(folderItem);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT COutArchive::EncodeStream(CEncoder &encoder, const CByteBuffer &data,
|
||||
CRecordVector<UINT64> &packSizes, CObjectVector<CFolder> &folders)
|
||||
{
|
||||
return EncodeStream(encoder, data, data.GetCapacity(), packSizes, folders);
|
||||
}
|
||||
|
||||
|
||||
|
||||
HRESULT COutArchive::WriteHeader(const CArchiveDatabase &database,
|
||||
const CCompressionMethodMode *options, UINT64 &headerOffset)
|
||||
{
|
||||
CObjectVector<CFolder> folders;
|
||||
|
||||
bool compressHeaders = (options != NULL);
|
||||
std::auto_ptr<CEncoder> encoder;
|
||||
if (compressHeaders)
|
||||
encoder = std::auto_ptr<CEncoder>(new CEncoder(*options));
|
||||
|
||||
CRecordVector<UINT64> packSizes;
|
||||
|
||||
UINT64 dataIndex = 0;
|
||||
|
||||
//////////////////////////
|
||||
// Folders
|
||||
|
||||
UINT64 externalFoldersStreamIndex;
|
||||
bool externalFolders = (compressHeaders && database.Folders.Size() > 8);
|
||||
if (externalFolders)
|
||||
{
|
||||
_mainMode = false;
|
||||
_countMode = true;
|
||||
_countSize = 0;
|
||||
int i;
|
||||
for(i = 0; i < database.Folders.Size(); i++)
|
||||
{
|
||||
RINOK(WriteFolderHeader(database.Folders[i]));
|
||||
}
|
||||
|
||||
_countMode = false;
|
||||
|
||||
CByteBuffer foldersData;
|
||||
foldersData.SetCapacity(_countSize);
|
||||
_outByte2.Init(foldersData, foldersData.GetCapacity());
|
||||
|
||||
for(i = 0; i < database.Folders.Size(); i++)
|
||||
{
|
||||
RINOK(WriteFolderHeader(database.Folders[i]));
|
||||
}
|
||||
|
||||
{
|
||||
externalFoldersStreamIndex = dataIndex++;
|
||||
RINOK(EncodeStream(*encoder, foldersData, packSizes, folders));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////
|
||||
// Names
|
||||
|
||||
CByteBuffer namesData;
|
||||
UINT64 externalNamesStreamIndex;
|
||||
bool externalNames = (compressHeaders && database.Files.Size() > 8);
|
||||
{
|
||||
UINT64 namesDataSize = 0;
|
||||
int i;
|
||||
for(i = 0; i < database.Files.Size(); i++)
|
||||
namesDataSize += (database.Files[i].Name.Length() + 1) * sizeof(wchar_t);
|
||||
namesData.SetCapacity(namesDataSize);
|
||||
UINT32 pos = 0;
|
||||
for(i = 0; i < database.Files.Size(); i++)
|
||||
{
|
||||
const UString &name = database.Files[i].Name;
|
||||
int length = name.Length() * sizeof(wchar_t);
|
||||
memmove(namesData + pos, name, length);
|
||||
pos += length;
|
||||
namesData[pos++] = 0;
|
||||
namesData[pos++] = 0;
|
||||
}
|
||||
|
||||
if (externalNames)
|
||||
{
|
||||
externalNamesStreamIndex = dataIndex++;
|
||||
RINOK(EncodeStream(*encoder, namesData, packSizes, folders));
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
// Write Attributes
|
||||
CBoolVector attributesBoolVector;
|
||||
attributesBoolVector.Reserve(database.Files.Size());
|
||||
UINT32 numDefinedAttributes = 0;
|
||||
int i;
|
||||
for(i = 0; i < database.Files.Size(); i++)
|
||||
{
|
||||
bool defined = database.Files[i].AreAttributesDefined;
|
||||
attributesBoolVector.Add(defined);
|
||||
if (defined)
|
||||
numDefinedAttributes++;
|
||||
}
|
||||
|
||||
CByteBuffer attributesData;
|
||||
UINT64 externalAttributesStreamIndex;
|
||||
bool externalAttributes = (compressHeaders && numDefinedAttributes > 8);
|
||||
if (numDefinedAttributes > 0)
|
||||
{
|
||||
attributesData.SetCapacity(numDefinedAttributes * sizeof(UINT32));
|
||||
UINT32 pos = 0;
|
||||
for(i = 0; i < database.Files.Size(); i++)
|
||||
{
|
||||
const CFileItem &file = database.Files[i];
|
||||
if (file.AreAttributesDefined)
|
||||
{
|
||||
memmove(attributesData + pos, &database.Files[i].Attributes, sizeof(UINT32));
|
||||
pos += sizeof(UINT32);
|
||||
}
|
||||
}
|
||||
if (externalAttributes)
|
||||
{
|
||||
externalAttributesStreamIndex = dataIndex++;
|
||||
RINOK(EncodeStream(*encoder, attributesData, packSizes, folders));
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
// Write Last Write Time
|
||||
UINT64 externalLastWriteTimeStreamIndex;
|
||||
bool externalLastWriteTime = false;
|
||||
// /*
|
||||
UINT32 numDefinedLastWriteTimes = 0;
|
||||
for(i = 0; i < database.Files.Size(); i++)
|
||||
if (database.Files[i].IsLastWriteTimeDefined)
|
||||
numDefinedLastWriteTimes++;
|
||||
|
||||
externalLastWriteTime = (compressHeaders && numDefinedLastWriteTimes > 64);
|
||||
if (numDefinedLastWriteTimes > 0)
|
||||
{
|
||||
CByteBuffer lastWriteTimeData;
|
||||
lastWriteTimeData.SetCapacity(numDefinedLastWriteTimes * sizeof(CArchiveFileTime));
|
||||
UINT32 pos = 0;
|
||||
for(i = 0; i < database.Files.Size(); i++)
|
||||
{
|
||||
const CFileItem &file = database.Files[i];
|
||||
if (file.IsLastWriteTimeDefined)
|
||||
{
|
||||
memmove(lastWriteTimeData + pos, &database.Files[i].LastWriteTime, sizeof(CArchiveFileTime));
|
||||
pos += sizeof(CArchiveFileTime);
|
||||
}
|
||||
}
|
||||
if (externalLastWriteTime)
|
||||
{
|
||||
externalLastWriteTimeStreamIndex = dataIndex++;
|
||||
RINOK(EncodeStream(*encoder, lastWriteTimeData, packSizes, folders));
|
||||
}
|
||||
}
|
||||
// */
|
||||
|
||||
|
||||
UINT64 packedSize = 0;
|
||||
for(i = 0; i < database.PackSizes.Size(); i++)
|
||||
packedSize += database.PackSizes[i];
|
||||
UINT64 headerPackSize = 0;
|
||||
for (i = 0; i < packSizes.Size(); i++)
|
||||
headerPackSize += packSizes[i];
|
||||
|
||||
headerOffset = packedSize + headerPackSize;
|
||||
|
||||
_mainMode = true;
|
||||
|
||||
_outByte.Init(Stream);
|
||||
_crc.Init();
|
||||
|
||||
|
||||
RINOK(WriteByte2(NID::kHeader));
|
||||
|
||||
// Archive Properties
|
||||
|
||||
if (folders.Size() > 0)
|
||||
{
|
||||
RINOK(WriteByte2(NID::kAdditionalStreamsInfo));
|
||||
RINOK(WritePackInfo(packedSize, packSizes,
|
||||
CRecordVector<bool>(), CRecordVector<UINT32>()));
|
||||
RINOK(WriteUnPackInfo(false, 0, folders));
|
||||
RINOK(WriteByte2(NID::kEnd));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
if (database.Folders.Size() > 0)
|
||||
{
|
||||
RINOK(WriteByte2(NID::kMainStreamsInfo));
|
||||
RINOK(WritePackInfo(0, database.PackSizes,
|
||||
database.PackCRCsDefined,
|
||||
database.PackCRCs));
|
||||
|
||||
RINOK(WriteUnPackInfo(
|
||||
externalFolders, externalFoldersStreamIndex, database.Folders));
|
||||
|
||||
CRecordVector<UINT64> unPackSizes;
|
||||
CRecordVector<bool> digestsDefined;
|
||||
CRecordVector<UINT32> digests;
|
||||
for (i = 0; i < database.Files.Size(); i++)
|
||||
{
|
||||
const CFileItem &file = database.Files[i];
|
||||
if (!file.HasStream)
|
||||
continue;
|
||||
unPackSizes.Add(file.UnPackSize);
|
||||
digestsDefined.Add(file.FileCRCIsDefined);
|
||||
digests.Add(file.FileCRC);
|
||||
}
|
||||
|
||||
RINOK(WriteSubStreamsInfo(
|
||||
database.Folders,
|
||||
database.NumUnPackStreamsVector,
|
||||
unPackSizes,
|
||||
digestsDefined,
|
||||
digests));
|
||||
RINOK(WriteByte2(NID::kEnd));
|
||||
}
|
||||
|
||||
if (database.Files.IsEmpty())
|
||||
{
|
||||
RINOK(WriteByte2(NID::kEnd));
|
||||
return _outByte.Flush();
|
||||
}
|
||||
|
||||
RINOK(WriteByte2(NID::kFilesInfo));
|
||||
RINOK(WriteNumber(database.Files.Size()));
|
||||
|
||||
CBoolVector emptyStreamVector;
|
||||
emptyStreamVector.Reserve(database.Files.Size());
|
||||
UINT64 numEmptyStreams = 0;
|
||||
for(i = 0; i < database.Files.Size(); i++)
|
||||
if (database.Files[i].HasStream)
|
||||
emptyStreamVector.Add(false);
|
||||
else
|
||||
{
|
||||
emptyStreamVector.Add(true);
|
||||
numEmptyStreams++;
|
||||
}
|
||||
if (numEmptyStreams > 0)
|
||||
{
|
||||
RINOK(WriteByte2(NID::kEmptyStream));
|
||||
RINOK(WriteNumber((emptyStreamVector.Size() + 7) / 8));
|
||||
RINOK(WriteBoolVector(emptyStreamVector));
|
||||
|
||||
CBoolVector emptyFileVector, antiVector;
|
||||
emptyFileVector.Reserve(numEmptyStreams);
|
||||
antiVector.Reserve(numEmptyStreams);
|
||||
UINT64 numEmptyFiles = 0, numAntiItems = 0;
|
||||
for(i = 0; i < database.Files.Size(); i++)
|
||||
{
|
||||
const CFileItem &file = database.Files[i];
|
||||
if (!file.HasStream)
|
||||
{
|
||||
emptyFileVector.Add(!file.IsDirectory);
|
||||
if (!file.IsDirectory)
|
||||
numEmptyFiles++;
|
||||
antiVector.Add(file.IsAnti);
|
||||
if (file.IsAnti)
|
||||
numAntiItems++;
|
||||
}
|
||||
}
|
||||
|
||||
if (numEmptyFiles > 0)
|
||||
{
|
||||
RINOK(WriteByte2(NID::kEmptyFile));
|
||||
RINOK(WriteNumber((emptyFileVector.Size() + 7) / 8));
|
||||
RINOK(WriteBoolVector(emptyFileVector));
|
||||
}
|
||||
|
||||
if (numAntiItems > 0)
|
||||
{
|
||||
RINOK(WriteByte2(NID::kAnti));
|
||||
RINOK(WriteNumber((antiVector.Size() + 7) / 8));
|
||||
RINOK(WriteBoolVector(antiVector));
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
/////////////////////////////////////////////////
|
||||
RINOK(WriteByte2(NID::kName));
|
||||
if (externalNames)
|
||||
{
|
||||
RINOK(WriteNumber(1 +
|
||||
GetBigNumberSize(externalNamesStreamIndex)));
|
||||
RINOK(WriteByte2(1));
|
||||
RINOK(WriteNumber(externalNamesStreamIndex));
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(WriteNumber(1 + namesData.GetCapacity()));
|
||||
RINOK(WriteByte2(0));
|
||||
RINOK(WriteBytes2(namesData));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
RINOK(WriteTime(database.Files, NID::kCreationTime, false, 0));
|
||||
RINOK(WriteTime(database.Files, NID::kLastAccessTime, false, 0));
|
||||
RINOK(WriteTime(database.Files, NID::kLastWriteTime,
|
||||
// false, 0));
|
||||
externalLastWriteTime, externalLastWriteTimeStreamIndex));
|
||||
|
||||
if (numDefinedAttributes > 0)
|
||||
{
|
||||
/////////////////////////////////////////////////
|
||||
RINOK(WriteByte2(NID::kWinAttributes));
|
||||
UINT32 size = 2;
|
||||
if (numDefinedAttributes != database.Files.Size())
|
||||
size += (attributesBoolVector.Size() + 7) / 8 + 1;
|
||||
if (externalAttributes)
|
||||
size += GetBigNumberSize(externalAttributesStreamIndex);
|
||||
else
|
||||
size += attributesData.GetCapacity();
|
||||
|
||||
RINOK(WriteNumber(size));
|
||||
if (numDefinedAttributes == database.Files.Size())
|
||||
{
|
||||
RINOK(WriteByte2(1));
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(WriteByte2(0));
|
||||
RINOK(WriteBoolVector(attributesBoolVector));
|
||||
}
|
||||
|
||||
if (externalAttributes)
|
||||
{
|
||||
RINOK(WriteByte2(1));
|
||||
RINOK(WriteNumber(externalAttributesStreamIndex));
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(WriteByte2(0));
|
||||
RINOK(WriteBytes2(attributesData));
|
||||
}
|
||||
}
|
||||
|
||||
RINOK(WriteByte2(NID::kEnd)); // for files
|
||||
RINOK(WriteByte2(NID::kEnd)); // for headers
|
||||
|
||||
return _outByte.Flush();
|
||||
}
|
||||
|
||||
HRESULT COutArchive::WriteDatabase(const CArchiveDatabase &database,
|
||||
const CCompressionMethodMode *options,
|
||||
bool useAdditionalStreams, bool compressMainHeader)
|
||||
{
|
||||
UINT64 headerOffset;
|
||||
UINT32 headerCRC;
|
||||
UINT64 headerSize;
|
||||
if (database.IsEmpty())
|
||||
{
|
||||
headerSize = 0;
|
||||
headerOffset = 0;
|
||||
headerCRC = CCRC::CalculateDigest(0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
_dynamicBuffer.Init();
|
||||
_dynamicMode = false;
|
||||
|
||||
if (options != 0)
|
||||
if (options->IsEmpty())
|
||||
options = 0;
|
||||
const CCompressionMethodMode *additionalStreamsOptions = options;
|
||||
if (!useAdditionalStreams)
|
||||
additionalStreamsOptions = 0;
|
||||
/*
|
||||
if (database.Files.Size() < 2)
|
||||
compressMainHeader = false;
|
||||
*/
|
||||
if (options != 0)
|
||||
if (options->PasswordIsDefined || compressMainHeader)
|
||||
_dynamicMode = true;
|
||||
RINOK(WriteHeader(database, additionalStreamsOptions, headerOffset));
|
||||
|
||||
if (_dynamicMode)
|
||||
{
|
||||
CCompressionMethodMode encryptOptions;
|
||||
encryptOptions.PasswordIsDefined = options->PasswordIsDefined;
|
||||
encryptOptions.Password = options->Password;
|
||||
CEncoder encoder(compressMainHeader ?
|
||||
*options : encryptOptions);
|
||||
CRecordVector<UINT64> packSizes;
|
||||
CObjectVector<CFolder> folders;
|
||||
RINOK(EncodeStream(encoder, _dynamicBuffer,
|
||||
_dynamicBuffer.GetSize(), packSizes, folders));
|
||||
_dynamicMode = false;
|
||||
_mainMode = true;
|
||||
|
||||
_outByte.Init(Stream);
|
||||
_crc.Init();
|
||||
|
||||
if (folders.Size() == 0)
|
||||
throw 1;
|
||||
|
||||
RINOK(WriteID(NID::kEncodedHeader));
|
||||
RINOK(WritePackInfo(headerOffset, packSizes,
|
||||
CRecordVector<bool>(), CRecordVector<UINT32>()));
|
||||
RINOK(WriteUnPackInfo(false, 0, folders));
|
||||
RINOK(WriteByte2(NID::kEnd));
|
||||
for (int i = 0; i < packSizes.Size(); i++)
|
||||
headerOffset += packSizes[i];
|
||||
RINOK(_outByte.Flush());
|
||||
}
|
||||
headerCRC = _crc.GetDigest();
|
||||
headerSize = _outByte.GetProcessedSize();
|
||||
}
|
||||
RINOK(Stream->Seek(_prefixHeaderPos, STREAM_SEEK_SET, NULL));
|
||||
|
||||
CStartHeader startHeader;
|
||||
startHeader.NextHeaderOffset = headerOffset;
|
||||
startHeader.NextHeaderSize = headerSize;
|
||||
startHeader.NextHeaderCRC = headerCRC;
|
||||
|
||||
UINT32 crc = CCRC::CalculateDigest(&startHeader, sizeof(startHeader));
|
||||
RINOK(WriteBytes(&crc, sizeof(crc)));
|
||||
return WriteBytes(&startHeader, sizeof(startHeader));
|
||||
}
|
||||
|
||||
}}
|
||||
154
7zip/Archive/7z/7zOut.h
Executable file
154
7zip/Archive/7z/7zOut.h
Executable file
@@ -0,0 +1,154 @@
|
||||
// 7z/Out.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __7Z_OUT_H
|
||||
#define __7Z_OUT_H
|
||||
|
||||
#include "7zHeader.h"
|
||||
#include "7zItem.h"
|
||||
#include "7zCompressionMode.h"
|
||||
#include "7zEncode.h"
|
||||
|
||||
#include "../../Common/OutBuffer.h"
|
||||
#include "../../../Common/DynamicBuffer.h"
|
||||
#include "../../../Common/CRC.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
class CWriteBufferLoc
|
||||
{
|
||||
BYTE *_data;
|
||||
UINT32 _size;
|
||||
UINT32 _pos;
|
||||
public:
|
||||
CWriteBufferLoc(): _size(0), _pos(0) {}
|
||||
void Init(BYTE *data, UINT32 size)
|
||||
{
|
||||
_pos = 0;
|
||||
_data = data;
|
||||
_size = size;
|
||||
}
|
||||
HRESULT Write(const void *data, UINT32 size)
|
||||
{
|
||||
if (_pos + size > _size)
|
||||
return E_FAIL;
|
||||
memmove(_data + _pos, data, size);
|
||||
_pos += size;
|
||||
return S_OK;
|
||||
}
|
||||
};
|
||||
|
||||
class CWriteDynamicBuffer
|
||||
{
|
||||
CByteDynamicBuffer _buffer;
|
||||
UINT32 _pos;
|
||||
public:
|
||||
CWriteDynamicBuffer(): _pos(0) {}
|
||||
void Init()
|
||||
{
|
||||
_pos = 0;
|
||||
}
|
||||
void Write(const void *data, UINT32 size)
|
||||
{
|
||||
if (_pos + size > _buffer.GetCapacity())
|
||||
_buffer.EnsureCapacity(_pos + size);
|
||||
memmove(((BYTE *)_buffer) +_pos, data, size);
|
||||
_pos += size;
|
||||
}
|
||||
operator BYTE *() { return (BYTE *)_buffer; };
|
||||
operator const BYTE *() const { return (const BYTE *)_buffer; };
|
||||
UINT32 GetSize() const { return _pos; }
|
||||
};
|
||||
|
||||
|
||||
class COutArchive
|
||||
{
|
||||
UINT64 _prefixHeaderPos;
|
||||
|
||||
HRESULT WriteBytes(const void *data, UINT32 size);
|
||||
HRESULT WriteBytes2(const void *data, UINT32 size);
|
||||
HRESULT WriteBytes2(const CByteBuffer &data);
|
||||
HRESULT WriteByte2(BYTE b);
|
||||
HRESULT WriteNumber(UINT64 value);
|
||||
HRESULT WriteID(UINT64 value)
|
||||
{
|
||||
return WriteNumber(value);
|
||||
}
|
||||
|
||||
HRESULT WriteFolderHeader(const CFolder &itemInfo);
|
||||
HRESULT WriteFileHeader(const CFileItem &itemInfo);
|
||||
HRESULT WriteBoolVector(const CBoolVector &boolVector);
|
||||
HRESULT WriteHashDigests(
|
||||
const CRecordVector<bool> &digestsDefined,
|
||||
const CRecordVector<UINT32> &hashDigests);
|
||||
|
||||
HRESULT WritePackInfo(
|
||||
UINT64 dataOffset,
|
||||
const CRecordVector<UINT64> &packSizes,
|
||||
const CRecordVector<bool> &packCRCsDefined,
|
||||
const CRecordVector<UINT32> &packCRCs);
|
||||
|
||||
HRESULT WriteUnPackInfo(
|
||||
bool externalFolders,
|
||||
UINT64 externalFoldersStreamIndex,
|
||||
const CObjectVector<CFolder> &folders);
|
||||
|
||||
HRESULT WriteSubStreamsInfo(
|
||||
const CObjectVector<CFolder> &folders,
|
||||
const CRecordVector<UINT64> &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<UINT64> &numUnPackStreamsInFolders,
|
||||
const CRecordVector<UINT64> &unPackSizes,
|
||||
const CRecordVector<bool> &digestsDefined,
|
||||
const CRecordVector<UINT32> &hashDigests);
|
||||
|
||||
|
||||
HRESULT WriteTime(const CObjectVector<CFileItem> &files, BYTE type,
|
||||
bool isExternal, int externalDataIndex);
|
||||
|
||||
HRESULT EncodeStream(CEncoder &encoder, const BYTE *data, UINT32 dataSize,
|
||||
CRecordVector<UINT64> &packSizes, CObjectVector<CFolder> &folders);
|
||||
HRESULT EncodeStream(CEncoder &encoder, const CByteBuffer &data,
|
||||
CRecordVector<UINT64> &packSizes, CObjectVector<CFolder> &folders);
|
||||
HRESULT WriteHeader(const CArchiveDatabase &database,
|
||||
const CCompressionMethodMode *options,
|
||||
UINT64 &headerOffset);
|
||||
|
||||
bool _mainMode;
|
||||
|
||||
bool _dynamicMode;
|
||||
|
||||
bool _countMode;
|
||||
UINT32 _countSize;
|
||||
COutBuffer _outByte;
|
||||
CWriteBufferLoc _outByte2;
|
||||
CWriteDynamicBuffer _dynamicBuffer;
|
||||
CCRC _crc;
|
||||
|
||||
public:
|
||||
CMyComPtr<IOutStream> Stream;
|
||||
HRESULT Create(IOutStream *stream);
|
||||
void Close();
|
||||
HRESULT SkeepPrefixArchiveHeader();
|
||||
HRESULT WriteDatabase(const CArchiveDatabase &database,
|
||||
const CCompressionMethodMode *options,
|
||||
bool useAdditionalHeaderStreams,
|
||||
bool compressMainHeader);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
157
7zip/Archive/7z/7zProperties.cpp
Executable file
157
7zip/Archive/7z/7zProperties.cpp
Executable file
@@ -0,0 +1,157 @@
|
||||
// 7zProperties.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "7zProperties.h"
|
||||
#include "7zHeader.h"
|
||||
#include "7zHandler.h"
|
||||
|
||||
// #define _MULTI_PACK
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
struct CPropMap
|
||||
{
|
||||
UINT64 FilePropID;
|
||||
STATPROPSTG StatPROPSTG;
|
||||
};
|
||||
|
||||
CPropMap kPropMap[] =
|
||||
{
|
||||
{ NID::kName, NULL, kpidPath, VT_BSTR},
|
||||
{ NID::kSize, NULL, kpidSize, VT_UI8},
|
||||
{ NID::kPackInfo, NULL, kpidPackedSize, VT_UI8},
|
||||
|
||||
#ifdef _MULTI_PACK
|
||||
{ 100, L"Pack0", kpidPackedSize0, VT_UI8},
|
||||
{ 101, L"Pack1", kpidPackedSize1, VT_UI8},
|
||||
{ 102, L"Pack2", kpidPackedSize2, VT_UI8},
|
||||
{ 103, L"Pack3", kpidPackedSize3, VT_UI8},
|
||||
{ 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::kCRC, NULL, kpidCRC, VT_UI4},
|
||||
|
||||
{ NID::kAnti, L"Anti", kpidIsAnti, VT_BOOL},
|
||||
// { 97, NULL, kpidSolid, VT_BOOL},
|
||||
#ifndef _SFX
|
||||
{ 98, NULL, kpidMethod, VT_BSTR},
|
||||
{ 99, L"Block", kpidBlock, VT_UI4}
|
||||
#endif
|
||||
// { L"ID", kpidID, VT_BSTR},
|
||||
// { L"UnPack Version", kpidUnPackVersion, VT_UI1},
|
||||
// { L"Host OS", kpidHostOS, VT_BSTR}
|
||||
};
|
||||
|
||||
static const int kPropMapSize = sizeof(kPropMap) / sizeof(kPropMap[0]);
|
||||
|
||||
static int FindPropInMap(UINT64 filePropID)
|
||||
{
|
||||
for (int i = 0; i < kPropMapSize; i++)
|
||||
if (kPropMap[i].FilePropID == filePropID)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void CopyOneItem(CRecordVector<UINT64> &src,
|
||||
CRecordVector<UINT64> &dest, UINT32 item)
|
||||
{
|
||||
for (int i = 0; i < src.Size(); i++)
|
||||
if (src[i] == item)
|
||||
{
|
||||
dest.Add(item);
|
||||
src.Delete(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void RemoveOneItem(CRecordVector<UINT64> &src, UINT32 item)
|
||||
{
|
||||
for (int i = 0; i < src.Size(); i++)
|
||||
if (src[i] == item)
|
||||
{
|
||||
src.Delete(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void InsertToHead(CRecordVector<UINT64> &dest, UINT32 item)
|
||||
{
|
||||
for (int i = 0; i < dest.Size(); i++)
|
||||
if (dest[i] == item)
|
||||
{
|
||||
dest.Delete(i);
|
||||
break;
|
||||
}
|
||||
dest.Insert(0, item);
|
||||
}
|
||||
|
||||
void CHandler::FillPopIDs()
|
||||
{
|
||||
_fileInfoPopIDs.Clear();
|
||||
CRecordVector<UINT64> fileInfoPopIDs = _database.ArchiveInfo.FileInfoPopIDs;
|
||||
|
||||
RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream);
|
||||
RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile);
|
||||
|
||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kName);
|
||||
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::kWinAttributes);
|
||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCRC);
|
||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kComment);
|
||||
_fileInfoPopIDs += fileInfoPopIDs;
|
||||
|
||||
#ifndef _SFX
|
||||
_fileInfoPopIDs.Add(98);
|
||||
_fileInfoPopIDs.Add(99);
|
||||
#endif
|
||||
#ifdef _MULTI_PACK
|
||||
_fileInfoPopIDs.Add(100);
|
||||
_fileInfoPopIDs.Add(101);
|
||||
_fileInfoPopIDs.Add(102);
|
||||
_fileInfoPopIDs.Add(103);
|
||||
_fileInfoPopIDs.Add(104);
|
||||
#endif
|
||||
|
||||
#ifndef _SFX
|
||||
InsertToHead(_fileInfoPopIDs, NID::kLastWriteTime);
|
||||
InsertToHead(_fileInfoPopIDs, NID::kPackInfo);
|
||||
InsertToHead(_fileInfoPopIDs, NID::kSize);
|
||||
InsertToHead(_fileInfoPopIDs, NID::kName);
|
||||
#endif
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UINT32 *numProperties)
|
||||
{
|
||||
*numProperties = _fileInfoPopIDs.Size();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
if(index >= _fileInfoPopIDs.Size())
|
||||
return E_INVALIDARG;
|
||||
int indexInMap = FindPropInMap(_fileInfoPopIDs[index]);
|
||||
if (indexInMap == -1)
|
||||
return E_INVALIDARG;
|
||||
const STATPROPSTG &srcItem = kPropMap[indexInMap].StatPROPSTG;
|
||||
*propID = srcItem.propid;
|
||||
*varType = srcItem.vt;
|
||||
*name = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}}
|
||||
51
7zip/Archive/7z/7zProperties.h
Executable file
51
7zip/Archive/7z/7zProperties.h
Executable file
@@ -0,0 +1,51 @@
|
||||
// 7zProperties.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __7Z_PROPERTIES_H
|
||||
#define __7Z_PROPERTIES_H
|
||||
|
||||
#include "../../PropID.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
enum // PropID
|
||||
{
|
||||
kpidPackedSize0 = kpidUserDefined,
|
||||
kpidPackedSize1,
|
||||
kpidPackedSize2,
|
||||
kpidPackedSize3,
|
||||
kpidPackedSize4,
|
||||
};
|
||||
|
||||
/*
|
||||
class CEnumArchiveItemProperty:
|
||||
public IEnumSTATPROPSTG,
|
||||
public CComObjectRoot
|
||||
{
|
||||
CRecordVector<UINT32> _fileInfoPopIDs;
|
||||
int _index;
|
||||
public:
|
||||
|
||||
BEGIN_COM_MAP(CEnumArchiveItemProperty)
|
||||
COM_INTERFACE_ENTRY(IEnumSTATPROPSTG)
|
||||
END_COM_MAP()
|
||||
|
||||
DECLARE_NOT_AGGREGATABLE(CEnumArchiveItemProperty)
|
||||
|
||||
DECLARE_NO_REGISTRY()
|
||||
public:
|
||||
CEnumArchiveItemProperty(): _index(0) {};
|
||||
void Init(const CRecordVector<UINT32> &fileInfoPopIDs);
|
||||
|
||||
STDMETHOD(Next) (ULONG numItems, STATPROPSTG *items, ULONG *numFetched);
|
||||
STDMETHOD(Skip) (ULONG numItems);
|
||||
STDMETHOD(Reset) ();
|
||||
STDMETHOD(Clone) (IEnumSTATPROPSTG **enumerator);
|
||||
};
|
||||
*/
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
34
7zip/Archive/7z/7zSpecStream.cpp
Executable file
34
7zip/Archive/7z/7zSpecStream.cpp
Executable file
@@ -0,0 +1,34 @@
|
||||
// 7zSpecStream.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "7zSpecStream.h"
|
||||
|
||||
STDMETHODIMP CSequentialInStreamSizeCount2::Read(void *data, UINT32 size, UINT32 *processedSize)
|
||||
{
|
||||
UINT32 realProcessedSize;
|
||||
HRESULT result = _stream->Read(data, size, &realProcessedSize);
|
||||
_size += realProcessedSize;
|
||||
if (processedSize != 0)
|
||||
*processedSize = realProcessedSize;
|
||||
return result;
|
||||
}
|
||||
|
||||
STDMETHODIMP CSequentialInStreamSizeCount2::ReadPart(void *data, UINT32 size, UINT32 *processedSize)
|
||||
{
|
||||
UINT32 realProcessedSize;
|
||||
HRESULT result = _stream->ReadPart(data, size, &realProcessedSize);
|
||||
_size += realProcessedSize;
|
||||
if (processedSize != 0)
|
||||
*processedSize = realProcessedSize;
|
||||
return result;
|
||||
}
|
||||
|
||||
STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize(
|
||||
UINT64 subStream, UINT64 *value)
|
||||
{
|
||||
if (_getSubStreamSize == NULL)
|
||||
return E_NOTIMPL;
|
||||
return _getSubStreamSize->GetSubStreamSize(subStream, value);
|
||||
}
|
||||
|
||||
38
7zip/Archive/7z/7zSpecStream.h
Executable file
38
7zip/Archive/7z/7zSpecStream.h
Executable file
@@ -0,0 +1,38 @@
|
||||
// 7zSpecStream.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __7Z_SPEC_STREAM_H
|
||||
#define __7Z_SPEC_STREAM_H
|
||||
|
||||
#include "../../IStream.h"
|
||||
#include "../../ICoder.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
|
||||
class CSequentialInStreamSizeCount2:
|
||||
public ISequentialInStream,
|
||||
public ICompressGetSubStreamSize,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
CMyComPtr<ISequentialInStream> _stream;
|
||||
CMyComPtr<ICompressGetSubStreamSize> _getSubStreamSize;
|
||||
UINT64 _size;
|
||||
public:
|
||||
void Init(ISequentialInStream *stream)
|
||||
{
|
||||
_stream = stream;
|
||||
_getSubStreamSize = 0;
|
||||
_stream.QueryInterface(IID_ICompressGetSubStreamSize, &_getSubStreamSize);
|
||||
_size = 0;
|
||||
}
|
||||
UINT64 GetSize() const { return _size; }
|
||||
|
||||
MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)
|
||||
|
||||
STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize);
|
||||
STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize);
|
||||
|
||||
STDMETHOD(GetSubStreamSize)(UINT64 subStream, UINT64 *value);
|
||||
};
|
||||
|
||||
#endif
|
||||
737
7zip/Archive/7z/7zUpdate.cpp
Executable file
737
7zip/Archive/7z/7zUpdate.cpp
Executable file
@@ -0,0 +1,737 @@
|
||||
// UpdateMain.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "7zUpdate.h"
|
||||
#include "7zFolderInStream.h"
|
||||
#include "7zEncode.h"
|
||||
#include "7zHandler.h"
|
||||
#include "7zOut.h"
|
||||
|
||||
#ifndef EXCLUDE_COM
|
||||
#include "7zMethods.h"
|
||||
#endif
|
||||
|
||||
#include "../../Compress/Copy/CopyCoder.h"
|
||||
#include "../../Common/ProgressUtils.h"
|
||||
#include "../../Common/LimitedStreams.h"
|
||||
#include "../../Common/LimitedStreams.h"
|
||||
#include "../Common/ItemNameUtils.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
static const wchar_t *kMatchFinderForBCJ2_LZMA = L"BT2";
|
||||
static const UINT32 kDictionaryForBCJ2_LZMA = 1 << 20;
|
||||
const UINT32 kAlgorithmForBCJ2_LZMA = 2;
|
||||
const UINT32 kNumFastBytesForBCJ2_LZMA = 64;
|
||||
|
||||
static HRESULT CopyBlock(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, ICompressProgressInfo *progress)
|
||||
{
|
||||
CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
|
||||
return copyCoder->Code(inStream, outStream, NULL, NULL, progress);
|
||||
}
|
||||
|
||||
static HRESULT WriteRange(IInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
const CUpdateRange &range,
|
||||
IProgress *progress,
|
||||
UINT64 ¤tComplexity)
|
||||
{
|
||||
UINT64 position;
|
||||
inStream->Seek(range.Position, STREAM_SEEK_SET, &position);
|
||||
|
||||
CLimitedSequentialInStream *streamSpec = new
|
||||
CLimitedSequentialInStream;
|
||||
CMyComPtr<CLimitedSequentialInStream> inStreamLimited(streamSpec);
|
||||
streamSpec->Init(inStream, range.Size);
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
|
||||
localProgressSpec->Init(progress, true);
|
||||
|
||||
CLocalCompressProgressInfo *localCompressProgressSpec =
|
||||
new CLocalCompressProgressInfo;
|
||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
||||
|
||||
localCompressProgressSpec->Init(localProgress, ¤tComplexity, ¤tComplexity);
|
||||
|
||||
HRESULT result = CopyBlock(inStreamLimited, outStream, compressProgress);
|
||||
currentComplexity += range.Size;
|
||||
return result;
|
||||
}
|
||||
|
||||
int CUpdateItem::GetExtensionPos() const
|
||||
{
|
||||
int slash1Pos = Name.ReverseFind(L'\\');
|
||||
int slash2Pos = Name.ReverseFind(L'/');
|
||||
int slashPos = MyMax(slash1Pos, slash2Pos);
|
||||
int dotPos = Name.ReverseFind(L'.');
|
||||
if (dotPos < 0 || (dotPos < slashPos && slashPos >= 0))
|
||||
return Name.Length();
|
||||
return dotPos + 1;
|
||||
}
|
||||
|
||||
UString CUpdateItem::GetExtension() const
|
||||
{
|
||||
return Name.Mid(GetExtensionPos());
|
||||
}
|
||||
|
||||
struct CFolderRef
|
||||
{
|
||||
const CArchiveDatabaseEx *Database;
|
||||
int FolderIndex;
|
||||
};
|
||||
|
||||
#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
|
||||
|
||||
static int CompareMethodIDs(const CMethodID &a1, const CMethodID &a2)
|
||||
{
|
||||
for (int i = 0; i < a1.IDSize && i < a2.IDSize; i++)
|
||||
RINOZ(MyCompare(a1.ID[i], a2.ID[i]));
|
||||
return MyCompare(a1.IDSize, a2.IDSize);
|
||||
}
|
||||
|
||||
static int CompareBuffers(const CByteBuffer &a1, const CByteBuffer &a2)
|
||||
{
|
||||
int c1 = a1.GetCapacity();
|
||||
int c2 = a2.GetCapacity();
|
||||
RINOZ(MyCompare(c1, c2));
|
||||
for (int i = 0; i < c1; i++)
|
||||
RINOZ(MyCompare(a1[i], a2[i]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int CompareAltCoders(const CAltCoderInfo &a1, const CAltCoderInfo &a2)
|
||||
{
|
||||
RINOZ(CompareMethodIDs(a1.MethodID, a2.MethodID));
|
||||
return CompareBuffers(a1.Properties, a2.Properties);
|
||||
}
|
||||
|
||||
static int CompareCoders(const CCoderInfo &c1, const CCoderInfo &c2)
|
||||
{
|
||||
RINOZ(MyCompare(c1.NumInStreams, c2.NumInStreams));
|
||||
RINOZ(MyCompare(c1.NumOutStreams, c2.NumOutStreams));
|
||||
int s1 = c1.AltCoders.Size();
|
||||
int s2 = c2.AltCoders.Size();
|
||||
RINOZ(MyCompare(s1, s2));
|
||||
for (int i = 0; i < s1; i++)
|
||||
RINOZ(CompareAltCoders(c1.AltCoders[i], c2.AltCoders[i]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int CompareBindPairs(const CBindPair &b1, const CBindPair &b2)
|
||||
{
|
||||
RINOZ(MyCompare(b1.InIndex, b2.InIndex));
|
||||
return MyCompare(b1.OutIndex, b2.OutIndex);
|
||||
}
|
||||
|
||||
static int CompareFolders(const CFolder &f1, const CFolder &f2)
|
||||
{
|
||||
int s1 = f1.Coders.Size();
|
||||
int s2 = f2.Coders.Size();
|
||||
RINOZ(MyCompare(s1, s2));
|
||||
int i;
|
||||
for (i = 0; i < s1; i++)
|
||||
RINOZ(CompareCoders(f1.Coders[i], f2.Coders[i]));
|
||||
s1 = f1.BindPairs.Size();
|
||||
s2 = f2.BindPairs.Size();
|
||||
RINOZ(MyCompare(s1, s2));
|
||||
for (i = 0; i < s1; i++)
|
||||
RINOZ(CompareBindPairs(f1.BindPairs[i], f2.BindPairs[i]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int CompareFiles(const CFileItem &f1, const CFileItem &f2)
|
||||
{
|
||||
return MyStringCollateNoCase(f1.Name, f2.Name);
|
||||
}
|
||||
|
||||
static int __cdecl CompareFolderRefs(const void *p1, const void *p2)
|
||||
{
|
||||
const CFolderRef &a1 = *((const CFolderRef *)p1);
|
||||
const CFolderRef &a2 = *((const CFolderRef *)p2);
|
||||
const CArchiveDatabaseEx &d1 = *a1.Database;
|
||||
const CArchiveDatabaseEx &d2 = *a2.Database;
|
||||
RINOZ(CompareFolders(
|
||||
d1.Folders[a1.FolderIndex],
|
||||
d2.Folders[a2.FolderIndex]));
|
||||
RINOZ(MyCompare(
|
||||
d1.NumUnPackStreamsVector[a1.FolderIndex],
|
||||
d2.NumUnPackStreamsVector[a2.FolderIndex]));
|
||||
if (d1.NumUnPackStreamsVector[a1.FolderIndex] == 0)
|
||||
return 0;
|
||||
return CompareFiles(
|
||||
d1.Files[d1.FolderStartFileIndex[a1.FolderIndex]],
|
||||
d2.Files[d2.FolderStartFileIndex[a2.FolderIndex]]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
static int __cdecl CompareEmptyItems(const void *p1, const void *p2)
|
||||
{
|
||||
const CUpdateItem &u1 = **((CUpdateItem **)p1);
|
||||
const CUpdateItem &u2 = **((CUpdateItem **)p2);
|
||||
if (u1.IsDirectory != u2.IsDirectory)
|
||||
{
|
||||
if (u1.IsDirectory)
|
||||
return u1.IsAnti ? 1: -1;
|
||||
return u2.IsAnti ? -1: 1;
|
||||
}
|
||||
if (u1.IsDirectory)
|
||||
{
|
||||
if (u1.IsAnti != u2.IsAnti)
|
||||
return (u1.IsAnti ? 1 : -1);
|
||||
int n = MyStringCollateNoCase(u1.Name, u2.Name);
|
||||
return (u1.IsAnti ? (-n) : n);
|
||||
}
|
||||
if (u1.IsAnti != u2.IsAnti)
|
||||
return (u1.IsAnti ? 1 : -1);
|
||||
return MyStringCollateNoCase(u1.Name, u2.Name);
|
||||
}
|
||||
|
||||
struct CRefItem
|
||||
{
|
||||
UINT32 Index;
|
||||
const CUpdateItem *UpdateItem;
|
||||
UINT32 ExtensionPos;
|
||||
UINT32 NamePos;
|
||||
bool SortByType;
|
||||
CRefItem(UINT32 index, const CUpdateItem &updateItem, bool sortByType):
|
||||
SortByType(sortByType),
|
||||
Index(index),
|
||||
UpdateItem(&updateItem),
|
||||
ExtensionPos(0),
|
||||
NamePos(0)
|
||||
{
|
||||
if (sortByType)
|
||||
{
|
||||
int slash1Pos = updateItem.Name.ReverseFind(L'\\');
|
||||
int slash2Pos = updateItem.Name.ReverseFind(L'/');
|
||||
int slashPos = MyMax(slash1Pos, slash2Pos);
|
||||
if (slashPos >= 0)
|
||||
NamePos = slashPos + 1;
|
||||
else
|
||||
NamePos = 0;
|
||||
int dotPos = updateItem.Name.ReverseFind(L'.');
|
||||
if (dotPos < 0 || (dotPos < slashPos && slashPos >= 0))
|
||||
ExtensionPos = updateItem.Name.Length();
|
||||
else
|
||||
ExtensionPos = dotPos + 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static int __cdecl CompareUpdateItems(const void *p1, const void *p2)
|
||||
{
|
||||
const CRefItem &a1 = *((CRefItem *)p1);
|
||||
const CRefItem &a2 = *((CRefItem *)p2);
|
||||
const CUpdateItem &u1 = *a1.UpdateItem;
|
||||
const CUpdateItem &u2 = *a2.UpdateItem;
|
||||
int n;
|
||||
if (u1.IsDirectory != u2.IsDirectory)
|
||||
{
|
||||
if (u1.IsDirectory)
|
||||
return u1.IsAnti ? 1: -1;
|
||||
return u2.IsAnti ? -1: 1;
|
||||
}
|
||||
if (u1.IsDirectory)
|
||||
{
|
||||
if (u1.IsAnti != u2.IsAnti)
|
||||
return (u1.IsAnti ? 1 : -1);
|
||||
n = MyStringCollateNoCase(u1.Name, u2.Name);
|
||||
return (u1.IsAnti ? (-n) : n);
|
||||
}
|
||||
if (a1.SortByType)
|
||||
{
|
||||
RINOZ(MyStringCollateNoCase(u1.Name + a1.ExtensionPos, u2.Name + a2.ExtensionPos));
|
||||
RINOZ(MyStringCollateNoCase(u1.Name + a1.NamePos, u2.Name + a2.NamePos));
|
||||
if (u1.LastWriteTimeIsDefined && u2.LastWriteTimeIsDefined)
|
||||
RINOZ(CompareFileTime(&u1.LastWriteTime, &u2.LastWriteTime));
|
||||
RINOZ(MyCompare(u1.Size, u2.Size))
|
||||
}
|
||||
return MyStringCollateNoCase(u1.Name, u2.Name);
|
||||
}
|
||||
|
||||
struct CSolidGroup
|
||||
{
|
||||
CCompressionMethodMode Method;
|
||||
CRecordVector<UINT32> Indices;
|
||||
};
|
||||
|
||||
static wchar_t *g_ExeExts[] =
|
||||
{
|
||||
L"dll",
|
||||
L"exe",
|
||||
L"ocx",
|
||||
L"sfx",
|
||||
L"sys"
|
||||
};
|
||||
|
||||
static bool IsExeFile(const UString &ext)
|
||||
{
|
||||
for (int i = 0; i < sizeof(g_ExeExts) / sizeof(g_ExeExts[0]); i++)
|
||||
if (ext.CompareNoCase(g_ExeExts[i]) == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static CMethodID k_BCJ_X86 = { { 0x3, 0x3, 0x1, 0x3 }, 4 };
|
||||
static CMethodID k_BCJ2 = { { 0x3, 0x3, 0x1, 0x1B }, 4 };
|
||||
static CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
|
||||
|
||||
static bool GetMethodFull(const CMethodID &methodID,
|
||||
UINT32 numInStreams, CMethodFull &methodResult)
|
||||
{
|
||||
methodResult.MethodID = methodID;
|
||||
methodResult.NumInStreams = numInStreams;
|
||||
methodResult.NumOutStreams = 1;
|
||||
|
||||
#ifndef EXCLUDE_COM
|
||||
CMethodInfo methodInfo;
|
||||
if (!GetMethodInfo(methodID, methodInfo))
|
||||
return false;
|
||||
if (!methodInfo.EncoderIsAssigned)
|
||||
return false;
|
||||
methodResult.EncoderClassID = methodInfo.Encoder;
|
||||
methodResult.FilePath = methodInfo.FilePath;
|
||||
if (methodInfo.NumOutStreams != 1 || methodInfo.NumInStreams != numInStreams)
|
||||
return false;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool MakeExeMethod(const CCompressionMethodMode &method,
|
||||
bool bcj2Filter, CCompressionMethodMode &exeMethod)
|
||||
{
|
||||
exeMethod = method;
|
||||
if (bcj2Filter)
|
||||
{
|
||||
CMethodFull methodFull;
|
||||
if (!GetMethodFull(k_BCJ2, 4, methodFull))
|
||||
return false;
|
||||
exeMethod.Methods.Insert(0, methodFull);
|
||||
if (!GetMethodFull(k_LZMA, 1, methodFull))
|
||||
return false;
|
||||
{
|
||||
CProperty property;
|
||||
property.PropID = NCoderPropID::kAlgorithm;
|
||||
property.Value = kAlgorithmForBCJ2_LZMA;
|
||||
methodFull.CoderProperties.Add(property);
|
||||
}
|
||||
{
|
||||
CProperty property;
|
||||
property.PropID = NCoderPropID::kMatchFinder;
|
||||
property.Value = kMatchFinderForBCJ2_LZMA;
|
||||
methodFull.CoderProperties.Add(property);
|
||||
}
|
||||
{
|
||||
CProperty property;
|
||||
property.PropID = NCoderPropID::kDictionarySize;
|
||||
property.Value = kDictionaryForBCJ2_LZMA;
|
||||
methodFull.CoderProperties.Add(property);
|
||||
}
|
||||
{
|
||||
CProperty property;
|
||||
property.PropID = NCoderPropID::kNumFastBytes;
|
||||
property.Value = kNumFastBytesForBCJ2_LZMA;
|
||||
methodFull.CoderProperties.Add(property);
|
||||
}
|
||||
|
||||
exeMethod.Methods.Add(methodFull);
|
||||
exeMethod.Methods.Add(methodFull);
|
||||
CBind bind;
|
||||
|
||||
bind.OutCoder = 0;
|
||||
bind.InStream = 0;
|
||||
|
||||
bind.InCoder = 1;
|
||||
bind.OutStream = 0;
|
||||
exeMethod.Binds.Add(bind);
|
||||
|
||||
bind.InCoder = 2;
|
||||
bind.OutStream = 1;
|
||||
exeMethod.Binds.Add(bind);
|
||||
|
||||
bind.InCoder = 3;
|
||||
bind.OutStream = 2;
|
||||
exeMethod.Binds.Add(bind);
|
||||
}
|
||||
else
|
||||
{
|
||||
CMethodFull methodFull;
|
||||
if (!GetMethodFull(k_BCJ_X86, 1, methodFull))
|
||||
return false;
|
||||
exeMethod.Methods.Insert(0, methodFull);
|
||||
CBind bind;
|
||||
bind.OutCoder = 0;
|
||||
bind.InStream = 0;
|
||||
bind.InCoder = 1;
|
||||
bind.OutStream = 0;
|
||||
exeMethod.Binds.Add(bind);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void SplitFilesToGroups(
|
||||
const CCompressionMethodMode &method,
|
||||
bool useFilters, bool maxFilter,
|
||||
const CObjectVector<CUpdateItem> &updateItems,
|
||||
CObjectVector<CSolidGroup> &groups)
|
||||
{
|
||||
if (method.Methods.Size() != 1 || method.Binds.Size() != 0)
|
||||
useFilters = false;
|
||||
groups.Clear();
|
||||
groups.Add(CSolidGroup());
|
||||
groups.Add(CSolidGroup());
|
||||
CSolidGroup &generalGroup = groups[0];
|
||||
CSolidGroup &exeGroup = groups[1];
|
||||
generalGroup.Method = method;
|
||||
int i;
|
||||
for (i = 0; i < updateItems.Size(); i++)
|
||||
{
|
||||
const CUpdateItem &updateItem = updateItems[i];
|
||||
if (!updateItem.NewData)
|
||||
continue;
|
||||
if (!updateItem.HasStream())
|
||||
continue;
|
||||
if (useFilters)
|
||||
{
|
||||
const UString name = updateItem.Name;
|
||||
int dotPos = name.ReverseFind(L'.');
|
||||
if (dotPos >= 0)
|
||||
{
|
||||
UString ext = name.Mid(dotPos + 1);
|
||||
if (IsExeFile(ext))
|
||||
{
|
||||
exeGroup.Indices.Add(i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
generalGroup.Indices.Add(i);
|
||||
}
|
||||
if (exeGroup.Indices.Size() > 0)
|
||||
if (!MakeExeMethod(method, maxFilter, exeGroup.Method))
|
||||
exeGroup.Method = method;
|
||||
for (i = 0; i < groups.Size();)
|
||||
if (groups[i].Indices.Size() == 0)
|
||||
groups.Delete(i);
|
||||
else
|
||||
i++;
|
||||
}
|
||||
|
||||
static void FromUpdateItemToFileItem(const CUpdateItem &updateItem,
|
||||
CFileItem &file)
|
||||
{
|
||||
file.Name = NItemName::MakeLegalName(updateItem.Name);
|
||||
if (updateItem.AttributesAreDefined)
|
||||
file.SetAttributes(updateItem.Attributes);
|
||||
|
||||
// if (updateItem.CreationTimeIsDefined)
|
||||
// file.SetCreationTime(updateItem.ItemInfo.CreationTime);
|
||||
|
||||
if (updateItem.LastWriteTimeIsDefined)
|
||||
file.SetLastWriteTime(updateItem.LastWriteTime);
|
||||
|
||||
file.UnPackSize = updateItem.Size;
|
||||
file.IsDirectory = updateItem.IsDirectory;
|
||||
file.IsAnti = updateItem.IsAnti;
|
||||
file.HasStream = updateItem.HasStream();
|
||||
}
|
||||
|
||||
HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database,
|
||||
CObjectVector<CUpdateItem> &updateItems,
|
||||
IOutStream *outStream,
|
||||
IInStream *inStream,
|
||||
NArchive::N7z::CInArchiveInfo *inArchiveInfo,
|
||||
const CCompressionMethodMode &method,
|
||||
const CCompressionMethodMode *headerMethod,
|
||||
bool useFilters,
|
||||
bool maxFilter,
|
||||
bool useAdditionalHeaderStreams,
|
||||
bool compressMainHeader,
|
||||
IArchiveUpdateCallback *updateCallback,
|
||||
UINT64 numSolidFiles, UINT64 numSolidBytes, bool solidExtension,
|
||||
bool removeSfxBlock)
|
||||
{
|
||||
if (numSolidFiles == 0)
|
||||
numSolidFiles = 1;
|
||||
|
||||
UINT64 startBlockSize = inArchiveInfo != 0 ?
|
||||
inArchiveInfo->StartPosition: 0;
|
||||
if (startBlockSize > 0 && !removeSfxBlock)
|
||||
{
|
||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
||||
CMyComPtr<ISequentialInStream> limitedStream(streamSpec);
|
||||
RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
|
||||
streamSpec->Init(inStream, startBlockSize);
|
||||
RINOK(CopyBlock(limitedStream, outStream, NULL));
|
||||
}
|
||||
|
||||
CRecordVector<int> fileIndexToUpdateIndexMap;
|
||||
fileIndexToUpdateIndexMap.Reserve(database.Files.Size());
|
||||
int i;
|
||||
for (i = 0; i < database.Files.Size(); i++)
|
||||
fileIndexToUpdateIndexMap.Add(-1);
|
||||
for(i = 0; i < updateItems.Size(); i++)
|
||||
{
|
||||
int index = updateItems[i].IndexInArchive;
|
||||
if (index != -1)
|
||||
fileIndexToUpdateIndexMap[index] = i;
|
||||
}
|
||||
|
||||
CRecordVector<CFolderRef> folderRefs;
|
||||
for(i = 0; i < database.Folders.Size(); i++)
|
||||
{
|
||||
UINT64 indexInFolder = 0;
|
||||
UINT64 numCopyItems = 0;
|
||||
UINT64 numUnPackStreams = database.NumUnPackStreamsVector[i];
|
||||
for (int fileIndex = database.FolderStartFileIndex[i];
|
||||
indexInFolder < numUnPackStreams; fileIndex++)
|
||||
{
|
||||
if (database.Files[fileIndex].HasStream)
|
||||
{
|
||||
indexInFolder++;
|
||||
int updateIndex = fileIndexToUpdateIndexMap[fileIndex];
|
||||
if (updateIndex >= 0)
|
||||
if (!updateItems[updateIndex].NewData)
|
||||
numCopyItems++;
|
||||
}
|
||||
}
|
||||
if (numCopyItems != numUnPackStreams && numCopyItems != 0)
|
||||
return E_NOTIMPL; // It needs repacking !!!
|
||||
if (numCopyItems > 0)
|
||||
{
|
||||
CFolderRef folderRef;
|
||||
folderRef.Database = &database;
|
||||
folderRef.FolderIndex = i;
|
||||
folderRefs.Add(folderRef);
|
||||
}
|
||||
}
|
||||
qsort(&folderRefs.Front(), folderRefs.Size(), sizeof(folderRefs[0]),
|
||||
CompareFolderRefs);
|
||||
|
||||
CArchiveDatabase newDatabase;
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Write Empty Files & Folders
|
||||
|
||||
CRecordVector<const CUpdateItem *> emptyRefs;
|
||||
for(i = 0; i < updateItems.Size(); i++)
|
||||
{
|
||||
const CUpdateItem &updateItem = updateItems[i];
|
||||
if (updateItem.NewData)
|
||||
{
|
||||
if (updateItem.HasStream())
|
||||
continue;
|
||||
}
|
||||
else
|
||||
if (updateItem.IndexInArchive != -1)
|
||||
if (database.Files[updateItem.IndexInArchive].HasStream)
|
||||
continue;
|
||||
emptyRefs.Add(&updateItem);
|
||||
}
|
||||
qsort(&emptyRefs.Front(), emptyRefs.Size(), sizeof(emptyRefs[0]),
|
||||
CompareEmptyItems);
|
||||
for(i = 0; i < emptyRefs.Size(); i++)
|
||||
{
|
||||
const CUpdateItem &updateItem = *emptyRefs[i];
|
||||
CFileItem file;
|
||||
if (updateItem.NewProperties)
|
||||
FromUpdateItemToFileItem(updateItem, file);
|
||||
else
|
||||
file = database.Files[updateItem.IndexInArchive];
|
||||
newDatabase.Files.Add(file);
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
|
||||
COutArchive archive;
|
||||
archive.Create(outStream);
|
||||
RINOK(archive.SkeepPrefixArchiveHeader());
|
||||
UINT64 complexity = 0;
|
||||
for(i = 0; i < folderRefs.Size(); i++)
|
||||
complexity += database.GetFolderFullPackSize(folderRefs[i].FolderIndex);
|
||||
for(i = 0; i < updateItems.Size(); i++)
|
||||
{
|
||||
const CUpdateItem &updateItem = updateItems[i];
|
||||
if (updateItem.NewData)
|
||||
complexity += updateItem.Size;
|
||||
}
|
||||
RINOK(updateCallback->SetTotal(complexity));
|
||||
complexity = 0;
|
||||
RINOK(updateCallback->SetCompleted(&complexity));
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Write Copy Items
|
||||
|
||||
for(i = 0; i < folderRefs.Size(); i++)
|
||||
{
|
||||
int folderIndex = folderRefs[i].FolderIndex;
|
||||
|
||||
RINOK(WriteRange(inStream, archive.Stream,
|
||||
CUpdateRange(database.GetFolderStreamPos(folderIndex, 0),
|
||||
database.GetFolderFullPackSize(folderIndex)),
|
||||
updateCallback, complexity));
|
||||
|
||||
const CFolder &folder = database.Folders[folderIndex];
|
||||
UINT32 startIndex = database.FolderStartPackStreamIndex[folderIndex];
|
||||
int j;
|
||||
for (j = 0; j < folder.PackStreams.Size(); j++)
|
||||
{
|
||||
newDatabase.PackSizes.Add(database.PackSizes[startIndex + j]);
|
||||
// newDatabase.PackCRCsDefined.Add(database.PackCRCsDefined[startIndex + j]);
|
||||
// newDatabase.PackCRCs.Add(database.PackCRCs[startIndex + j]);
|
||||
}
|
||||
newDatabase.Folders.Add(folder);
|
||||
|
||||
UINT64 numUnPackStreams = database.NumUnPackStreamsVector[folderIndex];
|
||||
newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams);
|
||||
|
||||
UINT64 indexInFolder = 0;
|
||||
for (j = database.FolderStartFileIndex[folderIndex];
|
||||
indexInFolder < numUnPackStreams; j++)
|
||||
{
|
||||
CFileItem file = database.Files[j];
|
||||
if (file.HasStream)
|
||||
{
|
||||
indexInFolder++;
|
||||
int updateIndex = fileIndexToUpdateIndexMap[j];
|
||||
if (updateIndex >= 0)
|
||||
{
|
||||
const CUpdateItem &updateItem = updateItems[updateIndex];
|
||||
if (updateItem.NewProperties)
|
||||
{
|
||||
CFileItem file2;
|
||||
FromUpdateItemToFileItem(updateItem, file2);
|
||||
file2.UnPackSize = file.UnPackSize;
|
||||
file2.FileCRC = file.FileCRC;
|
||||
file2.FileCRCIsDefined = file.FileCRCIsDefined;
|
||||
file2.HasStream = file.HasStream;
|
||||
file = file2;
|
||||
}
|
||||
}
|
||||
newDatabase.Files.Add(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Compress New Files
|
||||
|
||||
CObjectVector<CSolidGroup> groups;
|
||||
SplitFilesToGroups(method, useFilters, maxFilter, updateItems, groups);
|
||||
|
||||
for (int groupIndex = 0; groupIndex < groups.Size(); groupIndex++)
|
||||
{
|
||||
const CSolidGroup &group = groups[groupIndex];
|
||||
int numFiles = group.Indices.Size();
|
||||
if (numFiles == 0)
|
||||
continue;
|
||||
CRecordVector<CRefItem> refItems;
|
||||
refItems.Reserve(numFiles);
|
||||
for (i = 0; i < numFiles; i++)
|
||||
refItems.Add(CRefItem(group.Indices[i],
|
||||
updateItems[group.Indices[i]], numSolidFiles > 1));
|
||||
qsort(&refItems.Front(), refItems.Size(), sizeof(refItems[0]), CompareUpdateItems);
|
||||
|
||||
CRecordVector<UINT32> indices;
|
||||
indices.Reserve(numFiles);
|
||||
|
||||
int startFileIndexInDatabase = newDatabase.Files.Size();
|
||||
for (i = 0; i < numFiles; i++)
|
||||
{
|
||||
UINT32 index = refItems[i].Index;
|
||||
indices.Add(index);
|
||||
const CUpdateItem &updateItem = updateItems[index];
|
||||
CFileItem file;
|
||||
if (updateItem.NewProperties)
|
||||
FromUpdateItemToFileItem(updateItem, file);
|
||||
else
|
||||
file = database.Files[updateItem.IndexInArchive];
|
||||
if (file.IsAnti || file.IsDirectory)
|
||||
return E_FAIL;
|
||||
newDatabase.Files.Add(file);
|
||||
}
|
||||
|
||||
CEncoder encoder(group.Method);
|
||||
|
||||
for (i = 0; i < numFiles;)
|
||||
{
|
||||
UINT64 totalSize = 0;
|
||||
int numSubFiles;
|
||||
UString prevExtension;
|
||||
for (numSubFiles = 0; i + numSubFiles < numFiles &&
|
||||
numSubFiles < numSolidFiles; numSubFiles++)
|
||||
{
|
||||
const CUpdateItem &updateItem = updateItems[indices[i + numSubFiles]];
|
||||
totalSize += updateItem.Size;
|
||||
if (totalSize > numSolidBytes)
|
||||
break;
|
||||
if (solidExtension)
|
||||
{
|
||||
UString ext = updateItem.GetExtension();
|
||||
if (numSubFiles == 0)
|
||||
prevExtension = ext;
|
||||
else
|
||||
if (ext.CollateNoCase(prevExtension) != 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (numSubFiles < 1)
|
||||
numSubFiles = 1;
|
||||
|
||||
CFolderInStream *inStreamSpec = new CFolderInStream;
|
||||
CMyComPtr<ISequentialInStream> solidInStream(inStreamSpec);
|
||||
inStreamSpec->Init(updateCallback, &indices[i], numSubFiles);
|
||||
|
||||
CFolder folderItem;
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
|
||||
localProgressSpec->Init(updateCallback, true);
|
||||
CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo;
|
||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
||||
localCompressProgressSpec->Init(localProgress, &complexity, NULL);
|
||||
|
||||
RINOK(encoder.Encode(solidInStream, NULL, folderItem,
|
||||
archive.Stream, newDatabase.PackSizes, compressProgress));
|
||||
// for()
|
||||
// newDatabase.PackCRCsDefined.Add(false);
|
||||
// newDatabase.PackCRCs.Add(0);
|
||||
|
||||
newDatabase.Folders.Add(folderItem);
|
||||
|
||||
UINT32 numUnPackStreams = 0;
|
||||
for (int subIndex = 0; subIndex < numSubFiles; subIndex++)
|
||||
{
|
||||
CFileItem &file = newDatabase.Files[
|
||||
startFileIndexInDatabase + i + subIndex];
|
||||
file.FileCRC = inStreamSpec->CRCs[subIndex];
|
||||
file.UnPackSize = inStreamSpec->Sizes[subIndex];
|
||||
if (file.UnPackSize != 0)
|
||||
{
|
||||
file.FileCRCIsDefined = true;
|
||||
file.HasStream = true;
|
||||
numUnPackStreams++;
|
||||
complexity += file.UnPackSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
file.FileCRCIsDefined = false;
|
||||
file.HasStream = false;
|
||||
}
|
||||
}
|
||||
newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams);
|
||||
i += numSubFiles;
|
||||
}
|
||||
}
|
||||
if (newDatabase.Files.Size() != updateItems.Size())
|
||||
return E_FAIL;
|
||||
|
||||
return archive.WriteDatabase(newDatabase, headerMethod,
|
||||
useAdditionalHeaderStreams, compressMainHeader);
|
||||
}
|
||||
|
||||
}}
|
||||
72
7zip/Archive/7z/7zUpdate.h
Executable file
72
7zip/Archive/7z/7zUpdate.h
Executable file
@@ -0,0 +1,72 @@
|
||||
// 7zUpdate.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __7Z_UPDATE_H
|
||||
#define __7Z_UPDATE_H
|
||||
|
||||
#include "7zIn.h"
|
||||
#include "7zCompressionMode.h"
|
||||
|
||||
#include "../IArchive.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
struct CUpdateRange
|
||||
{
|
||||
UINT64 Position;
|
||||
UINT64 Size;
|
||||
CUpdateRange() {};
|
||||
CUpdateRange(UINT64 position, UINT64 size): Position(position), Size(size) {};
|
||||
};
|
||||
|
||||
struct CUpdateItem
|
||||
{
|
||||
bool NewData;
|
||||
bool NewProperties;
|
||||
int IndexInArchive;
|
||||
int IndexInClient;
|
||||
|
||||
UINT32 Attributes;
|
||||
FILETIME CreationTime;
|
||||
FILETIME LastWriteTime;
|
||||
|
||||
UINT64 Size;
|
||||
UString Name;
|
||||
|
||||
bool IsAnti;
|
||||
bool IsDirectory;
|
||||
|
||||
bool CreationTimeIsDefined;
|
||||
bool LastWriteTimeIsDefined;
|
||||
bool AttributesAreDefined;
|
||||
|
||||
const bool HasStream() const
|
||||
{ return !IsDirectory && !IsAnti && Size != 0; }
|
||||
CUpdateItem(): IsAnti(false) {}
|
||||
void SetDirectoryStatusFromAttributes()
|
||||
{ IsDirectory = ((Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0); };
|
||||
|
||||
int GetExtensionPos() const;
|
||||
UString GetExtension() const;
|
||||
};
|
||||
|
||||
HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database,
|
||||
CObjectVector<CUpdateItem> &updateItems,
|
||||
IOutStream *outStream,
|
||||
IInStream *inStream,
|
||||
CInArchiveInfo *inArchiveInfo,
|
||||
const CCompressionMethodMode &method,
|
||||
const CCompressionMethodMode *headerMethod,
|
||||
bool useFilters,
|
||||
bool maxFilter,
|
||||
bool useAdditionalHeaderStreams,
|
||||
bool compressMainHeader,
|
||||
IArchiveUpdateCallback *updateCallback,
|
||||
UINT64 numSolidFiles, UINT64 numSolidBytes, bool solidExtension,
|
||||
bool removeSfxBlock);
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
90
7zip/Archive/7z/DllExports.cpp
Executable file
90
7zip/Archive/7z/DllExports.cpp
Executable file
@@ -0,0 +1,90 @@
|
||||
// DLLExports.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include <initguid.h>
|
||||
|
||||
#include "7zHandler.h"
|
||||
#include "../../ICoder.h"
|
||||
#include "../../IPassword.h"
|
||||
#include "../../../Common/NewHandler.h"
|
||||
#include "../../../Common/ComTry.h"
|
||||
|
||||
#ifndef EXCLUDE_COM
|
||||
// {23170F69-40C1-278B-06F1-070100000100}
|
||||
DEFINE_GUID(CLSID_CCrypto7zAESEncoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x07, 0x01, 0x00, 0x00, 0x01, 0x00);
|
||||
#else
|
||||
#include "../../Compress/LZ/IMatchFinder.h"
|
||||
#endif
|
||||
|
||||
HINSTANCE g_hInstance;
|
||||
|
||||
extern "C"
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
||||
{
|
||||
if (dwReason == DLL_PROCESS_ATTACH)
|
||||
g_hInstance = hInstance;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
STDAPI CreateObject(
|
||||
const GUID *classID,
|
||||
const GUID *interfaceID,
|
||||
void **outObject)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
*outObject = 0;
|
||||
if (*classID != NArchive::N7z::CLSID_CFormat7z)
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
int needIn = *interfaceID == IID_IInArchive;
|
||||
int needOut = *interfaceID == IID_IOutArchive;
|
||||
if (needIn || needOut)
|
||||
{
|
||||
NArchive::N7z::CHandler *temp = new NArchive::N7z::CHandler;
|
||||
if (needIn)
|
||||
{
|
||||
CMyComPtr<IInArchive> inArchive = (IInArchive *)temp;
|
||||
*outObject = inArchive.Detach();
|
||||
}
|
||||
else
|
||||
{
|
||||
CMyComPtr<IOutArchive> outArchive = (IOutArchive *)temp;
|
||||
*outObject = outArchive.Detach();
|
||||
}
|
||||
}
|
||||
else
|
||||
return E_NOINTERFACE;
|
||||
COM_TRY_END
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
switch(propID)
|
||||
{
|
||||
case NArchive::kName:
|
||||
propVariant = L"7z";
|
||||
break;
|
||||
case NArchive::kClassID:
|
||||
{
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen(
|
||||
(const char *)&NArchive::N7z::CLSID_CFormat7z, sizeof(GUID))) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
}
|
||||
case NArchive::kExtension:
|
||||
propVariant = L"7z";
|
||||
break;
|
||||
case NArchive::kUpdate:
|
||||
propVariant = true;
|
||||
break;
|
||||
case NArchive::kKeepName:
|
||||
propVariant = false;
|
||||
break;
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
3
7zip/Archive/7z/StdAfx.cpp
Executable file
3
7zip/Archive/7z/StdAfx.cpp
Executable file
@@ -0,0 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "stdafx.h"
|
||||
23
7zip/Archive/7z/StdAfx.h
Executable file
23
7zip/Archive/7z/StdAfx.h
Executable file
@@ -0,0 +1,23 @@
|
||||
// stdafx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
/*
|
||||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
#include <atlcom.h>
|
||||
#include <shlobj.h>
|
||||
#include <shlguid.h>
|
||||
|
||||
#include <memory>
|
||||
#include <new.h>
|
||||
|
||||
#include <time.h>
|
||||
*/
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#endif
|
||||
16
7zip/Archive/7z/resource.h
Executable file
16
7zip/Archive/7z/resource.h
Executable file
@@ -0,0 +1,16 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by resource.rc
|
||||
//
|
||||
#define IDI_ICON1 101
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 102
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
130
7zip/Archive/7z/resource.rc
Executable file
130
7zip/Archive/7z/resource.rc
Executable file
@@ -0,0 +1,130 @@
|
||||
//Microsoft Developer Studio generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Russian resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
|
||||
#pragma code_page(1251)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // Russian resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_ICON1 ICON DISCARDABLE "7z.ico"
|
||||
|
||||
#ifndef _MAC
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,12,0,0
|
||||
PRODUCTVERSION 3,12,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "Comments", "\0"
|
||||
VALUE "CompanyName", "Igor Pavlov\0"
|
||||
VALUE "FileDescription", "7z Plugin for 7-Zip\0"
|
||||
VALUE "FileVersion", "3, 12, 0, 0\0"
|
||||
VALUE "InternalName", "7z\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "7z.dll\0"
|
||||
VALUE "PrivateBuild", "\0"
|
||||
VALUE "ProductName", "7-Zip\0"
|
||||
VALUE "ProductVersion", "3, 12, 0, 0\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
#endif // !_MAC
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
7
7zip/Archive/Arj/Arj.def
Executable file
7
7zip/Archive/Arj/Arj.def
Executable file
@@ -0,0 +1,7 @@
|
||||
; Arj.def
|
||||
|
||||
LIBRARY Arj.dll
|
||||
|
||||
EXPORTS
|
||||
CreateObject PRIVATE
|
||||
GetHandlerProperty PRIVATE
|
||||
309
7zip/Archive/Arj/Arj.dsp
Executable file
309
7zip/Archive/Arj/Arj.dsp
Executable file
@@ -0,0 +1,309 @@
|
||||
# Microsoft Developer Studio Project File - Name="arj" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=arj - 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 "arj.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 "arj.mak" CFG="arj - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "arj - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "arj - 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)" == "arj - 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 "ARJ_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ARJ_EXPORTS" /Yu"StdAfx.h" /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
# ADD RSC /l 0x419 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Formats\arj.dll" /opt:NOWIN98
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ELSEIF "$(CFG)" == "arj - 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 "ARJ_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ARJ_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||
# ADD RSC /l 0x419 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Formats\arj.dll" /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "arj - Win32 Release"
|
||||
# Name "arj - Win32 Debug"
|
||||
# Begin Group "spec"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\arj.def
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DllExports.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\resource.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\resource.rc
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.cpp
|
||||
# ADD CPP /Yc
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Common"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\CRC.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\CRC.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\NewHandler.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\NewHandler.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\String.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\String.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\StringConvert.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\StringConvert.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Vector.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Vector.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Windows"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\PropVariant.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\PropVariant.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Engine"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ArjHandler.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ArjHandler.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ArjHeader.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ArjIn.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ArjIn.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ArjItem.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Compression"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# End Group
|
||||
# Begin Group "Compress"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Group "Codecs"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Compress\Arj\Decoder1.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Compress\Arj\Decoder1.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Compress\Arj\Decoder2.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Compress\Arj\Decoder2.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "LZ"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Compress\LZ\LZOutWindow.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Compress\LZ\LZOutWindow.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Copy"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Compress\Copy\CopyCoder.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Compress\Copy\CopyCoder.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Group
|
||||
# Begin Group "7zip common"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\InBuffer.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\InBuffer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\LimitedStreams.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\LimitedStreams.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\ProgressUtils.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\ProgressUtils.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Archive Common"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# 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\OutStreamWithCRC.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\OutStreamWithCRC.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\arj.ico
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
29
7zip/Archive/Arj/Arj.dsw
Executable file
29
7zip/Archive/Arj/Arj.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: "arj"=.\arj.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
482
7zip/Archive/Arj/ArjHandler.cpp
Executable file
482
7zip/Archive/Arj/ArjHandler.cpp
Executable file
@@ -0,0 +1,482 @@
|
||||
// ArjHandler.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/Defs.h"
|
||||
#include "Common/CRC.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/Decoder1.h"
|
||||
#include "../../Compress/Arj/Decoder2.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";
|
||||
|
||||
|
||||
/*
|
||||
enum // PropID
|
||||
{
|
||||
kpidHostOS = kpidUserDefined,
|
||||
kpidUnPackVersion,
|
||||
kpidMethod,
|
||||
};
|
||||
*/
|
||||
|
||||
STATPROPSTG kProperties[] =
|
||||
{
|
||||
{ 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, kpidCommented, VT_BOOL},
|
||||
|
||||
{ NULL, kpidCRC, VT_UI4},
|
||||
|
||||
{ NULL, kpidMethod, VT_UI1},
|
||||
{ NULL, kpidHostOS, VT_BSTR}
|
||||
|
||||
// { L"UnPack Version", kpidUnPackVersion, VT_UI1},
|
||||
// { L"Method", kpidMethod, VT_UI1},
|
||||
// { L"Host OS", kpidHostOS, VT_BSTR}
|
||||
};
|
||||
|
||||
|
||||
CHandler::CHandler()
|
||||
{}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
value->vt = VT_EMPTY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UINT32 *numProperties)
|
||||
{
|
||||
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
|
||||
return E_INVALIDARG;
|
||||
const STATPROPSTG &srcItem = kProperties[index];
|
||||
*propID = srcItem.propid;
|
||||
*varType = srcItem.vt;
|
||||
*name = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UINT32 *numProperties)
|
||||
{
|
||||
*numProperties = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UINT32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
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 propVariant;
|
||||
const CItemEx &item = _items[index];
|
||||
switch(propID)
|
||||
{
|
||||
case kpidPath:
|
||||
propVariant =
|
||||
NItemName::GetOSName(MultiByteToUnicodeString(item.Name, CP_OEMCP));
|
||||
/*
|
||||
NItemName::GetOSName2(
|
||||
MultiByteToUnicodeString(item.Name, item.GetCodePage()));
|
||||
*/
|
||||
break;
|
||||
case kpidIsFolder:
|
||||
propVariant = item.IsDirectory();
|
||||
break;
|
||||
case kpidSize:
|
||||
propVariant = item.Size;
|
||||
break;
|
||||
case kpidPackedSize:
|
||||
propVariant = item.PackSize;
|
||||
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;
|
||||
propVariant = utcFileTime;
|
||||
break;
|
||||
}
|
||||
case kpidAttributes:
|
||||
propVariant = item.GetWinAttributes();
|
||||
break;
|
||||
case kpidEncrypted:
|
||||
propVariant = item.IsEncrypted();
|
||||
break;
|
||||
/*
|
||||
case kpidCommented:
|
||||
propVariant = item.IsCommented();
|
||||
break;
|
||||
*/
|
||||
case kpidCRC:
|
||||
propVariant = item.FileCRC;
|
||||
break;
|
||||
case kpidMethod:
|
||||
propVariant = item.Method;
|
||||
break;
|
||||
case kpidHostOS:
|
||||
propVariant = (item.HostOS < kNumHostOSes) ?
|
||||
(kHostOS[item.HostOS]) : kUnknownOS;
|
||||
break;
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
class CPropgressImp: public CProgressVirt
|
||||
{
|
||||
CMyComPtr<IArchiveOpenCallback> m_OpenArchiveCallBack;
|
||||
public:
|
||||
STDMETHOD(SetCompleted)(const UINT64 *numFiles);
|
||||
void Init(IArchiveOpenCallback *openArchiveCallback)
|
||||
{ m_OpenArchiveCallBack = openArchiveCallback; }
|
||||
};
|
||||
|
||||
STDMETHODIMP CPropgressImp::SetCompleted(const UINT64 *numFiles)
|
||||
{
|
||||
if (m_OpenArchiveCallBack)
|
||||
return m_OpenArchiveCallBack->SetCompleted(numFiles, NULL);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
const UINT64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
try
|
||||
{
|
||||
_items.Clear();
|
||||
CInArchive archive;
|
||||
if(!archive.Open(inStream, maxCheckStartPosition))
|
||||
return S_FALSE;
|
||||
if (openArchiveCallback != NULL)
|
||||
{
|
||||
RINOK(openArchiveCallback->SetTotal(NULL, NULL));
|
||||
UINT64 numFiles = _items.Size();
|
||||
RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
|
||||
}
|
||||
while(true)
|
||||
{
|
||||
CItemEx itemInfo;
|
||||
bool filled;
|
||||
HRESULT result = archive.GetNextItem(filled, itemInfo);
|
||||
if (result == S_FALSE)
|
||||
return S_FALSE;
|
||||
if (result != S_OK)
|
||||
return S_FALSE;
|
||||
if (!filled)
|
||||
break;
|
||||
_items.Add(itemInfo);
|
||||
archive.IncreaseRealPosition(itemInfo.PackSize);
|
||||
if (openArchiveCallback != NULL)
|
||||
{
|
||||
UINT64 numFiles = _items.Size();
|
||||
RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
|
||||
}
|
||||
}
|
||||
_stream = inStream;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
COM_TRY_END
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Close()
|
||||
{
|
||||
_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 &itemInfo = _items[allFilesMode ? i : indices[i]];
|
||||
totalUnPacked += itemInfo.Size;
|
||||
totalPacked += itemInfo.PackSize;
|
||||
}
|
||||
extractCallback->SetTotal(totalUnPacked);
|
||||
|
||||
UINT64 currentTotalUnPacked = 0, currentTotalPacked = 0;
|
||||
UINT64 currentItemUnPacked, currentItemPacked;
|
||||
|
||||
CMyComPtr<ICompressCoder> arj1Decoder;
|
||||
CMyComPtr<ICompressCoder> arj2Decoder;
|
||||
CMyComPtr<ICompressCoder> copyCoder;
|
||||
|
||||
for(i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked,
|
||||
currentTotalPacked += currentItemPacked)
|
||||
{
|
||||
currentItemUnPacked = 0;
|
||||
currentItemPacked = 0;
|
||||
|
||||
RINOK(extractCallback->SetCompleted(¤tTotalUnPacked));
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
INT32 askMode;
|
||||
askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
INT32 index = allFilesMode ? i : indices[i];
|
||||
const CItemEx &itemInfo = _items[index];
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
|
||||
if(itemInfo.IsDirectory())
|
||||
{
|
||||
// if (!testMode)
|
||||
{
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!testMode && (!realOutStream))
|
||||
continue;
|
||||
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
currentItemUnPacked = itemInfo.Size;
|
||||
currentItemPacked = itemInfo.PackSize;
|
||||
|
||||
{
|
||||
COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;
|
||||
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
|
||||
outStreamSpec->Init(realOutStream);
|
||||
realOutStream.Release();
|
||||
|
||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
||||
CMyComPtr<ISequentialInStream> inStream(streamSpec);
|
||||
|
||||
UINT64 pos;
|
||||
_stream->Seek(itemInfo.DataPosition, STREAM_SEEK_SET, &pos);
|
||||
|
||||
streamSpec->Init(_stream, itemInfo.PackSize);
|
||||
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
|
||||
localProgressSpec->Init(extractCallback, false);
|
||||
|
||||
|
||||
CLocalCompressProgressInfo *localCompressProgressSpec =
|
||||
new CLocalCompressProgressInfo;
|
||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
||||
localCompressProgressSpec->Init(progress,
|
||||
¤tTotalPacked,
|
||||
¤tTotalUnPacked);
|
||||
|
||||
if (itemInfo.IsEncrypted())
|
||||
{
|
||||
RINOK(extractCallback->SetOperationResult(
|
||||
NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
||||
continue;
|
||||
}
|
||||
|
||||
HRESULT result;
|
||||
|
||||
switch(itemInfo.Method)
|
||||
{
|
||||
case NFileHeader::NCompressionMethod::kStored:
|
||||
{
|
||||
if(!copyCoder)
|
||||
copyCoder = new NCompress::CCopyCoder;
|
||||
try
|
||||
{
|
||||
if (itemInfo.IsEncrypted())
|
||||
{
|
||||
RINOK(extractCallback->SetOperationResult(
|
||||
NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = copyCoder->Code(inStream, outStream,
|
||||
NULL, NULL, compressProgress);
|
||||
}
|
||||
if (result == S_FALSE)
|
||||
throw "data error";
|
||||
if (result != S_OK)
|
||||
return result;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
outStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(
|
||||
NArchive::NExtract::NOperationResult::kDataError));
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NFileHeader::NCompressionMethod::kCompressed1a:
|
||||
case NFileHeader::NCompressionMethod::kCompressed1b:
|
||||
case NFileHeader::NCompressionMethod::kCompressed1c:
|
||||
{
|
||||
if(!arj1Decoder)
|
||||
{
|
||||
arj1Decoder = new NCompress::NArj::NDecoder1::CCoder;
|
||||
}
|
||||
try
|
||||
{
|
||||
if (itemInfo.IsEncrypted())
|
||||
{
|
||||
RINOK(extractCallback->SetOperationResult(
|
||||
NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = arj1Decoder->Code(inStream, outStream,
|
||||
NULL, ¤tItemUnPacked, compressProgress);
|
||||
}
|
||||
if (result == S_FALSE)
|
||||
throw "data error";
|
||||
if (result != S_OK)
|
||||
return result;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
outStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(
|
||||
NArchive::NExtract::NOperationResult::kDataError));
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NFileHeader::NCompressionMethod::kCompressed2:
|
||||
{
|
||||
if(!arj2Decoder)
|
||||
{
|
||||
arj2Decoder = new NCompress::NArj::NDecoder2::CCoder;
|
||||
}
|
||||
try
|
||||
{
|
||||
if (itemInfo.IsEncrypted())
|
||||
{
|
||||
RINOK(extractCallback->SetOperationResult(
|
||||
NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = arj2Decoder->Code(inStream, outStream,
|
||||
NULL, ¤tItemUnPacked, compressProgress);
|
||||
}
|
||||
if (result == S_FALSE)
|
||||
throw "data error";
|
||||
if (result != S_OK)
|
||||
return result;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
outStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(
|
||||
NArchive::NExtract::NOperationResult::kDataError));
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
RINOK(extractCallback->SetOperationResult(
|
||||
NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
||||
continue;
|
||||
}
|
||||
bool crcOK = outStreamSpec->GetCRC() == itemInfo.FileCRC;
|
||||
outStream.Release();
|
||||
if(crcOK)
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK))
|
||||
else
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kCRCError))
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
49
7zip/Archive/Arj/ArjHandler.h
Executable file
49
7zip/Archive/Arj/ArjHandler.h
Executable file
@@ -0,0 +1,49 @@
|
||||
// ArjHandler.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARJ_HANDLER_H
|
||||
#define __ARJ_HANDLER_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "../IArchive.h"
|
||||
#include "ArjIn.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NArj {
|
||||
|
||||
class CHandler:
|
||||
public IInArchive,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
STDMETHOD(Open)(IInStream *aStream,
|
||||
const UINT64 *aMaxCheckStartPosition,
|
||||
IArchiveOpenCallback *anOpenArchiveCallback);
|
||||
STDMETHOD(Close)();
|
||||
STDMETHOD(GetNumberOfItems)(UINT32 *numItems);
|
||||
STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value);
|
||||
STDMETHOD(Extract)(const UINT32* indices, UINT32 numItems,
|
||||
INT32 testMode, IArchiveExtractCallback *anExtractCallback);
|
||||
|
||||
STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value);
|
||||
|
||||
STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties);
|
||||
STDMETHOD(GetPropertyInfo)(UINT32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType);
|
||||
|
||||
STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties);
|
||||
STDMETHOD(GetArchivePropertyInfo)(UINT32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType);
|
||||
|
||||
CHandler();
|
||||
private:
|
||||
CObjectVector<CItemEx> _items;
|
||||
CMyComPtr<IInStream> _stream;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
124
7zip/Archive/Arj/ArjHeader.h
Executable file
124
7zip/Archive/Arj/ArjHeader.h
Executable file
@@ -0,0 +1,124 @@
|
||||
// Archive/Arj/Header.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
#pragma pack( push, Pragma_Arj_Headers)
|
||||
#pragma pack( push, 1)
|
||||
|
||||
struct CArchiveHeader
|
||||
{
|
||||
// UINT16 BasicHeaderSize;
|
||||
BYTE FirstHeaderSize;
|
||||
BYTE Version;
|
||||
BYTE ExtractVersion;
|
||||
BYTE HostOS;
|
||||
BYTE Flags;
|
||||
BYTE SecuryVersion;
|
||||
BYTE FileType;
|
||||
BYTE Reserved;
|
||||
UINT32 CreatedTime;
|
||||
UINT32 ModifiedTime;
|
||||
UINT32 ArchiveSize;
|
||||
UINT32 SecurityEnvelopeFilePosition;
|
||||
UINT16 FilespecPositionInFilename;
|
||||
UINT16 LengthOfSecurityEnvelopeSata;
|
||||
BYTE EncryptionVersion;
|
||||
BYTE LastChapter;
|
||||
};
|
||||
|
||||
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
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#pragma pack(pop)
|
||||
#pragma pack(pop, Pragma_Arj_Headers)
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
221
7zip/Archive/Arj/ArjIn.cpp
Executable file
221
7zip/Archive/Arj/ArjIn.cpp
Executable file
@@ -0,0 +1,221 @@
|
||||
// Archive/arj/InEngine.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/StringConvert.h"
|
||||
#include "Common/Buffer.h"
|
||||
#include "Common/CRC.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
|
||||
#include "ArjIn.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NArj {
|
||||
|
||||
CInArchiveException::CInArchiveException(CCauseType cause):
|
||||
Cause(cause)
|
||||
{}
|
||||
|
||||
HRESULT CInArchive::ReadBytes(void *data, UINT32 size, UINT32 *processedSize)
|
||||
{
|
||||
UINT32 realProcessedSize;
|
||||
HRESULT result = _stream->Read(data, size, &realProcessedSize);
|
||||
if(processedSize != NULL)
|
||||
*processedSize = realProcessedSize;
|
||||
IncreasePositionValue(realProcessedSize);
|
||||
return result;
|
||||
}
|
||||
|
||||
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 = *((const UINT16 *)(block + 2));
|
||||
if (maxSize < 2 + 2 + blockSize + 4)
|
||||
return false;
|
||||
block += 4;
|
||||
if (blockSize == 0 || blockSize > 2600)
|
||||
return false;
|
||||
UINT32 crcFromFile = *(const UINT32 *)(block + blockSize);
|
||||
return (CCRC::VerifyDigest(crcFromFile, 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 + sizeof(UINT32);
|
||||
|
||||
CByteBuffer byteBuffer;
|
||||
static const UINT32 kSearchMarkerBufferSize = 0x10000;
|
||||
byteBuffer.SetCapacity(kSearchMarkerBufferSize);
|
||||
BYTE *buffer = byteBuffer;
|
||||
|
||||
UINT32 processedSize;
|
||||
ReadBytes(buffer, 2 + 2 + kMaxBlockSize + sizeof(UINT32), &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;
|
||||
while(true)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
bool CInArchive::ReadBlock()
|
||||
{
|
||||
SafeReadBytes(&_blockSize, sizeof(_blockSize));
|
||||
if (_blockSize == 0)
|
||||
return false;
|
||||
SafeReadBytes(_block, _blockSize);
|
||||
UINT32 crcFromFile;
|
||||
ReadBytesAndTestSize(&crcFromFile, sizeof(crcFromFile));
|
||||
if (!CCRC::VerifyDigest(crcFromFile, _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;
|
||||
while(true)
|
||||
if (!ReadBlock())
|
||||
break;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CInArchive::Close()
|
||||
{
|
||||
_stream.Release();
|
||||
}
|
||||
|
||||
void CInArchive::ThrowIncorrectArchiveException()
|
||||
{
|
||||
throw CInArchiveException(CInArchiveException::kIncorrectArchive);
|
||||
}
|
||||
|
||||
HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
|
||||
{
|
||||
filled = false;
|
||||
if (!ReadBlock2())
|
||||
return S_OK;
|
||||
|
||||
const NFileHeader::CHeader &header = *(const NFileHeader::CHeader *)_block;
|
||||
|
||||
item.Version = header.Version;
|
||||
item.ExtractVersion = header.ExtractVersion;
|
||||
item.HostOS = header.HostOS;
|
||||
item.Flags = header.Flags;
|
||||
item.Method = header.Method;
|
||||
item.FileType = header.FileType;
|
||||
item.ModifiedTime = header.ModifiedTime;
|
||||
item.PackSize = header.PackSize;
|
||||
item.Size = header.Size;
|
||||
item.FileCRC = header.FileCRC;
|
||||
item.FileAccessMode = header.FileAccessMode;
|
||||
|
||||
/*
|
||||
UINT32 extraData;
|
||||
if ((header.Flags & NFileHeader::NFlags::kExtFile) != 0)
|
||||
extraData = *(const UINT32 *)(_block + pos);
|
||||
*/
|
||||
int pos = header.FirstHeaderSize;
|
||||
|
||||
for (; pos < _blockSize; pos++)
|
||||
{
|
||||
char aByte = _block[pos];
|
||||
if (aByte == 0)
|
||||
break;
|
||||
item.Name += aByte;
|
||||
}
|
||||
|
||||
while(true)
|
||||
if (!ReadBlock())
|
||||
break;
|
||||
|
||||
item.DataPosition = _position;
|
||||
|
||||
filled = true;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}}
|
||||
70
7zip/Archive/Arj/ArjIn.h
Executable file
70
7zip/Archive/Arj/ArjIn.h
Executable file
@@ -0,0 +1,70 @@
|
||||
// Archive/ArjIn.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARCHIVE_ARJIN_H
|
||||
#define __ARCHIVE_ARJIN_H
|
||||
|
||||
#include "Common/Exception.h"
|
||||
#include "Common/MyCom.h"
|
||||
#include "../../IStream.h"
|
||||
|
||||
#include "Header.h"
|
||||
#include "ArjItem.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NArj {
|
||||
|
||||
class CInArchiveException
|
||||
{
|
||||
public:
|
||||
enum CCauseType
|
||||
{
|
||||
kUnexpectedEndOfArchive = 0,
|
||||
kCRCError,
|
||||
kIncorrectArchive,
|
||||
kReadStreamError,
|
||||
kSeekStreamError
|
||||
}
|
||||
Cause;
|
||||
CInArchiveException(CCauseType cause);
|
||||
};
|
||||
|
||||
class CProgressVirt
|
||||
{
|
||||
public:
|
||||
STDMETHOD(SetCompleted)(const UINT64 *numFiles) PURE;
|
||||
};
|
||||
|
||||
class CInArchive
|
||||
{
|
||||
CMyComPtr<IInStream> _stream;
|
||||
UINT64 _streamStartPosition;
|
||||
UINT64 _position;
|
||||
UINT16 _blockSize;
|
||||
BYTE _block[kMaxBlockSize];
|
||||
|
||||
bool FindAndReadMarker(const UINT64 *searchHeaderSizeLimit);
|
||||
|
||||
bool ReadBlock();
|
||||
bool ReadBlock2();
|
||||
|
||||
HRESULT ReadBytes(void *data, UINT32 size, UINT32 *processedSize);
|
||||
bool ReadBytesAndTestSize(void *data, UINT32 size);
|
||||
void SafeReadBytes(void *data, UINT32 size);
|
||||
|
||||
void IncreasePositionValue(UINT64 addValue);
|
||||
void ThrowIncorrectArchiveException();
|
||||
|
||||
public:
|
||||
HRESULT GetNextItem(bool &filled, CItemEx &item);
|
||||
|
||||
bool Open(IInStream *inStream, const UINT64 *searchHeaderSizeLimit);
|
||||
void Close();
|
||||
|
||||
void IncreaseRealPosition(UINT64 addValue);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
77
7zip/Archive/Arj/ArjItem.h
Executable file
77
7zip/Archive/Arj/ArjItem.h
Executable file
@@ -0,0 +1,77 @@
|
||||
// Archive/Arj/ItemInfo.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARCHIVE_ARJ_ITEMINFO_H
|
||||
#define __ARCHIVE_ARJ_ITEMINFO_H
|
||||
|
||||
#include "Common/Types.h"
|
||||
#include "Common/String.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
|
||||
{
|
||||
DWORD 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
|
||||
|
||||
|
||||
69
7zip/Archive/Arj/DllExports.cpp
Executable file
69
7zip/Archive/Arj/DllExports.cpp
Executable file
@@ -0,0 +1,69 @@
|
||||
// DLLExports.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include <initguid.h>
|
||||
|
||||
#include "Common/ComTry.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "../../ICoder.h"
|
||||
#include "ArjHandler.h"
|
||||
|
||||
// {23170F69-40C1-278A-1000-0001100A0000}
|
||||
DEFINE_GUID(CLSID_CArjHandler,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x0A, 0x00, 0x00);
|
||||
|
||||
extern "C"
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
STDAPI CreateObject(
|
||||
const GUID *classID,
|
||||
const GUID *interfaceID,
|
||||
void **outObject)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
*outObject = 0;
|
||||
if (*classID != CLSID_CArjHandler)
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
if (*interfaceID != IID_IInArchive)
|
||||
return E_NOINTERFACE;
|
||||
CMyComPtr<IInArchive> inArchive = (IInArchive *)new NArchive::NArj::CHandler;
|
||||
*outObject = inArchive.Detach();
|
||||
COM_TRY_END
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
switch(propID)
|
||||
{
|
||||
case NArchive::kName:
|
||||
propVariant = L"Arj";
|
||||
break;
|
||||
case NArchive::kClassID:
|
||||
{
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen(
|
||||
(const char *)&CLSID_CArjHandler, sizeof(GUID))) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
}
|
||||
case NArchive::kExtension:
|
||||
propVariant = L"arj";
|
||||
break;
|
||||
case NArchive::kAddExtension:
|
||||
propVariant = L".cpio.gz";
|
||||
break;
|
||||
case NArchive::kUpdate:
|
||||
propVariant = false;
|
||||
break;
|
||||
case NArchive::kKeepName:
|
||||
propVariant = false;
|
||||
break;
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
3
7zip/Archive/Arj/StdAfx.cpp
Executable file
3
7zip/Archive/Arj/StdAfx.cpp
Executable file
@@ -0,0 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "stdafx.h"
|
||||
9
7zip/Archive/Arj/StdAfx.h
Executable file
9
7zip/Archive/Arj/StdAfx.h
Executable file
@@ -0,0 +1,9 @@
|
||||
// stdafx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include <windows.h>
|
||||
#include <limits.h>
|
||||
|
||||
#endif
|
||||
BIN
7zip/Archive/Arj/arj.ico
Executable file
BIN
7zip/Archive/Arj/arj.ico
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 3.6 KiB |
16
7zip/Archive/Arj/resource.h
Executable file
16
7zip/Archive/Arj/resource.h
Executable file
@@ -0,0 +1,16 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by resource.rc
|
||||
//
|
||||
#define IDI_ICON1 101
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 102
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
130
7zip/Archive/Arj/resource.rc
Executable file
130
7zip/Archive/Arj/resource.rc
Executable file
@@ -0,0 +1,130 @@
|
||||
//Microsoft Developer Studio generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Russian resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
|
||||
#pragma code_page(1251)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // Russian resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_ICON1 ICON DISCARDABLE "arj.ico"
|
||||
|
||||
#ifndef _MAC
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,9,2,0
|
||||
PRODUCTVERSION 3,9,2,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "Comments", "\0"
|
||||
VALUE "CompanyName", "Igor Pavlov\0"
|
||||
VALUE "FileDescription", "Arj Plugin for 7-Zip\0"
|
||||
VALUE "FileVersion", "3, 9, 2, 0\0"
|
||||
VALUE "InternalName", "arj\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "arj.dll\0"
|
||||
VALUE "PrivateBuild", "\0"
|
||||
VALUE "ProductName", "7-Zip\0"
|
||||
VALUE "ProductVersion", "3, 9, 2, 0\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
#endif // !_MAC
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
8
7zip/Archive/BZip2/BZip2.def
Executable file
8
7zip/Archive/BZip2/BZip2.def
Executable file
@@ -0,0 +1,8 @@
|
||||
; BZip2.def
|
||||
|
||||
LIBRARY bz2.dll
|
||||
|
||||
EXPORTS
|
||||
CreateObject PRIVATE
|
||||
GetHandlerProperty PRIVATE
|
||||
|
||||
241
7zip/Archive/BZip2/BZip2.dsp
Executable file
241
7zip/Archive/BZip2/BZip2.dsp
Executable file
@@ -0,0 +1,241 @@
|
||||
# Microsoft Developer Studio Project File - Name="BZip2" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=BZip2 - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "BZip2.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "BZip2.mak" CFG="BZip2 - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "BZip2 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "BZip2 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "BZip2 - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /Yu"StdAfx.h" /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
# ADD RSC /l 0x419 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Formats\bz2.dll" /opt:NOWIN98
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||
# ADD RSC /l 0x419 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Formats\bz2.dll" /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "BZip2 - Win32 Release"
|
||||
# Name "BZip2 - Win32 Debug"
|
||||
# Begin Group "Spec"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BZip2.def
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BZip2.ico
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DllExports.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\resource.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\resource.rc
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.cpp
|
||||
# ADD CPP /Yc"StdAfx.h"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Common"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\NewHandler.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\NewHandler.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\StringConvert.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\StringConvert.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Windows"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\DLL.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\DLL.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\PropVariant.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\PropVariant.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Compression"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Compress\Copy\CopyCoder.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Compress\Copy\CopyCoder.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Archive Common"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\CodecsPath.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\CodecsPath.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\DummyOutStream.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\DummyOutStream.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Engine"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BZip2Handler.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BZip2Handler.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BZip2HandlerOut.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BZip2Item.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BZip2Update.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BZip2Update.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "7zip common"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\ProgressUtils.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\ProgressUtils.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\bz2.ico
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
29
7zip/Archive/BZip2/BZip2.dsw
Executable file
29
7zip/Archive/BZip2/BZip2.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: "BZip2"=.\BZip2.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
215
7zip/Archive/BZip2/BZip2Handler.cpp
Executable file
215
7zip/Archive/BZip2/BZip2Handler.cpp
Executable file
@@ -0,0 +1,215 @@
|
||||
// BZip2Handler.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "BZip2Handler.h"
|
||||
|
||||
#include "Common/Defs.h"
|
||||
|
||||
#include "../../Common/ProgressUtils.h"
|
||||
// #include "Interface/EnumStatProp.h"
|
||||
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "Windows/Defs.h"
|
||||
#include "Common/ComTry.h"
|
||||
|
||||
#include "../Common/DummyOutStream.h"
|
||||
|
||||
#ifdef COMPRESS_BZIP2
|
||||
#include "../../Compress/BZip2/BZip2Decoder.h"
|
||||
#else
|
||||
// {23170F69-40C1-278B-0402-020000000000}
|
||||
DEFINE_GUID(CLSID_CCompressBZip2Decoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
#include "../Common/CoderLoader.h"
|
||||
extern CSysString GetBZip2CodecPath();
|
||||
#endif
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
namespace NArchive {
|
||||
namespace NBZip2 {
|
||||
|
||||
STATPROPSTG kProperties[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
// { NULL, kpidIsFolder, VT_BOOL},
|
||||
// { NULL, kpidSize, VT_UI8},
|
||||
{ NULL, kpidPackedSize, VT_UI8},
|
||||
};
|
||||
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
value->vt = VT_EMPTY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UINT32 *numProperties)
|
||||
{
|
||||
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
|
||||
return E_INVALIDARG;
|
||||
const STATPROPSTG &srcItem = kProperties[index];
|
||||
*propID = srcItem.propid;
|
||||
*varType = srcItem.vt;
|
||||
*name = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UINT32 *numProperties)
|
||||
{
|
||||
*numProperties = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UINT32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfItems(UINT32 *numItems)
|
||||
{
|
||||
*numItems = 1;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
if (index != 0)
|
||||
return E_INVALIDARG;
|
||||
switch(propID)
|
||||
{
|
||||
case kpidIsFolder:
|
||||
propVariant = false;
|
||||
break;
|
||||
case kpidPackedSize:
|
||||
propVariant = _item.PackSize;
|
||||
break;
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
const UINT64 *maxCheckStartPosition,
|
||||
IArchiveOpenCallback *openArchiveCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
try
|
||||
{
|
||||
RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_streamStartPosition));
|
||||
const int kSignatureSize = 3;
|
||||
BYTE buffer[kSignatureSize];
|
||||
UINT32 processedSize;
|
||||
RINOK(stream->Read(buffer, kSignatureSize, &processedSize));
|
||||
if (processedSize != kSignatureSize)
|
||||
return S_FALSE;
|
||||
if (buffer[0] != 'B' || buffer[1] != 'Z' || buffer[2] != 'h')
|
||||
return S_FALSE;
|
||||
|
||||
UINT64 endPosition;
|
||||
RINOK(stream->Seek(0, STREAM_SEEK_END, &endPosition));
|
||||
_item.PackSize = endPosition - _streamStartPosition;
|
||||
|
||||
_stream = stream;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Close()
|
||||
{
|
||||
_stream.Release();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
|
||||
INT32 testModeSpec, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool allFilesMode = (numItems == UINT32(-1));
|
||||
if (!allFilesMode)
|
||||
{
|
||||
if (numItems == 0)
|
||||
return S_OK;
|
||||
if (numItems != 1)
|
||||
return E_INVALIDARG;
|
||||
if (indices[0] != 0)
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
bool testMode = (testModeSpec != 0);
|
||||
|
||||
extractCallback->SetTotal(_item.PackSize);
|
||||
|
||||
UINT64 currentTotalPacked = 0;
|
||||
|
||||
RINOK(extractCallback->SetCompleted(¤tTotalPacked));
|
||||
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
INT32 askMode;
|
||||
askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
|
||||
RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
|
||||
|
||||
if(!testMode && !realOutStream)
|
||||
return S_OK;
|
||||
|
||||
extractCallback->PrepareOperation(askMode);
|
||||
|
||||
CDummyOutStream *outStreamSpec = new CDummyOutStream;
|
||||
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
|
||||
outStreamSpec->Init(realOutStream);
|
||||
|
||||
realOutStream.Release();
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
|
||||
localProgressSpec->Init(extractCallback, true);
|
||||
|
||||
RINOK(_stream->Seek(_streamStartPosition, STREAM_SEEK_SET, NULL));
|
||||
|
||||
#ifndef COMPRESS_BZIP2
|
||||
CCoderLibrary lib;
|
||||
#endif
|
||||
CMyComPtr<ICompressCoder> decoder;
|
||||
#ifdef COMPRESS_BZIP2
|
||||
decoder = new NCompress::NBZip2::CDecoder;
|
||||
#else
|
||||
RINOK(lib.LoadAndCreateCoder(
|
||||
GetBZip2CodecPath(),
|
||||
CLSID_CCompressBZip2Decoder, &decoder));
|
||||
#endif
|
||||
|
||||
HRESULT result = decoder->Code(_stream, outStream, NULL, NULL, progress);
|
||||
outStream.Release();
|
||||
if (result == S_FALSE)
|
||||
RINOK(extractCallback->SetOperationResult(
|
||||
NArchive::NExtract::NOperationResult::kDataError))
|
||||
else if (result == S_OK)
|
||||
RINOK(extractCallback->SetOperationResult(
|
||||
NArchive::NExtract::NOperationResult::kOK))
|
||||
else
|
||||
return result;
|
||||
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
}}
|
||||
61
7zip/Archive/BZip2/BZip2Handler.h
Executable file
61
7zip/Archive/BZip2/BZip2Handler.h
Executable file
@@ -0,0 +1,61 @@
|
||||
// BZip2/Handler.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __BZIP2_HANDLER_H
|
||||
#define __BZIP2_HANDLER_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "../IArchive.h"
|
||||
#include "BZip2Item.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NBZip2 {
|
||||
|
||||
class CHandler:
|
||||
public IInArchive,
|
||||
public IOutArchive,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
MY_UNKNOWN_IMP2(
|
||||
IInArchive,
|
||||
IOutArchive
|
||||
)
|
||||
|
||||
STDMETHOD(Open)(IInStream *stream,
|
||||
const UINT64 *maxCheckStartPosition,
|
||||
IArchiveOpenCallback *openArchiveCallback);
|
||||
STDMETHOD(Close)();
|
||||
STDMETHOD(GetNumberOfItems)(UINT32 *numItems);
|
||||
STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value);
|
||||
STDMETHOD(Extract)(const UINT32* indices, UINT32 numItems,
|
||||
INT32 testMode, IArchiveExtractCallback *extractCallback);
|
||||
|
||||
STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value);
|
||||
|
||||
STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties);
|
||||
STDMETHOD(GetPropertyInfo)(UINT32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType);
|
||||
|
||||
STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties);
|
||||
STDMETHOD(GetArchivePropertyInfo)(UINT32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType);
|
||||
|
||||
|
||||
// IOutArchiveHandler
|
||||
|
||||
STDMETHOD(UpdateItems)(IOutStream *outStream, UINT32 numItems,
|
||||
IArchiveUpdateCallback *updateCallback);
|
||||
|
||||
STDMETHOD(GetFileTimeType)(UINT32 *type);
|
||||
|
||||
private:
|
||||
CMyComPtr<IInStream> _stream;
|
||||
NArchive::NBZip2::CItem _item;
|
||||
UINT64 _streamStartPosition;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
92
7zip/Archive/BZip2/BZip2HandlerOut.cpp
Executable file
92
7zip/Archive/BZip2/BZip2HandlerOut.cpp
Executable file
@@ -0,0 +1,92 @@
|
||||
// BZip2/OutHandler.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "BZip2Handler.h"
|
||||
#include "BZip2Update.h"
|
||||
|
||||
#include "Windows/FileFind.h"
|
||||
#include "Windows/Defs.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
|
||||
#include "../../Compress/Copy/CopyCoder.h"
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
static const int kNumItemInArchive = 1;
|
||||
|
||||
namespace NArchive {
|
||||
namespace NBZip2 {
|
||||
|
||||
STDMETHODIMP CHandler::GetFileTimeType(UINT32 *type)
|
||||
{
|
||||
*type = NFileTimeType::kUnix;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT CopyStreams(IInStream *inStream, IOutStream *outStream,
|
||||
IArchiveUpdateCallback *updateCallback)
|
||||
{
|
||||
CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
|
||||
return copyCoder->Code(inStream, outStream, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems,
|
||||
IArchiveUpdateCallback *updateCallback)
|
||||
{
|
||||
if (numItems != 1)
|
||||
return E_INVALIDARG;
|
||||
|
||||
INT32 newData;
|
||||
INT32 newProperties;
|
||||
UINT32 indexInArchive;
|
||||
if (!updateCallback)
|
||||
return E_FAIL;
|
||||
RINOK(updateCallback->GetUpdateItemInfo(0,
|
||||
&newData, &newProperties, &indexInArchive));
|
||||
|
||||
if (IntToBool(newProperties))
|
||||
{
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(updateCallback->GetProperty(0, kpidAttributes, &propVariant));
|
||||
if (propVariant.vt == VT_UI4)
|
||||
{
|
||||
if (NFile::NFind::NAttributes::IsDirectory(propVariant.ulVal))
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
else if (propVariant.vt != VT_EMPTY)
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(updateCallback->GetProperty(0, kpidIsFolder, &propVariant));
|
||||
if (propVariant.vt == VT_BOOL)
|
||||
{
|
||||
if (propVariant.boolVal != VARIANT_FALSE)
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
else if (propVariant.vt != VT_EMPTY)
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
|
||||
if (IntToBool(newData))
|
||||
{
|
||||
UINT64 size;
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(updateCallback->GetProperty(0, kpidSize, &propVariant));
|
||||
if (propVariant.vt != VT_UI8)
|
||||
return E_INVALIDARG;
|
||||
size = *(UINT64 *)(&propVariant.uhVal);
|
||||
}
|
||||
return UpdateArchive(size, outStream, 0, updateCallback);
|
||||
}
|
||||
if (indexInArchive != 0)
|
||||
return E_INVALIDARG;
|
||||
RINOK(_stream->Seek(_streamStartPosition, STREAM_SEEK_SET, NULL));
|
||||
return CopyStreams(_stream, outStream, updateCallback);
|
||||
}
|
||||
|
||||
}}
|
||||
22
7zip/Archive/BZip2/BZip2Item.h
Executable file
22
7zip/Archive/BZip2/BZip2Item.h
Executable file
@@ -0,0 +1,22 @@
|
||||
// Archive/BZip2Item.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARCHIVE_BZIP2_ITEM_H
|
||||
#define __ARCHIVE_BZIP2_ITEM_H
|
||||
|
||||
namespace NArchive {
|
||||
namespace NBZip2 {
|
||||
|
||||
struct CItem
|
||||
{
|
||||
UINT64 PackSize;
|
||||
UINT64 UnPackSize;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
58
7zip/Archive/BZip2/BZip2Update.cpp
Executable file
58
7zip/Archive/BZip2/BZip2Update.cpp
Executable file
@@ -0,0 +1,58 @@
|
||||
// BZip2Update.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/Defs.h"
|
||||
#include "Windows/Defs.h"
|
||||
#include "../../Common/ProgressUtils.h"
|
||||
|
||||
#include "BZip2Update.h"
|
||||
|
||||
#ifdef COMPRESS_BZIP2
|
||||
#include "../../Compress/BZip2/BZip2Encoder.h"
|
||||
#else
|
||||
// {23170F69-40C1-278B-0402-020000000100}
|
||||
DEFINE_GUID(CLSID_CCompressBZip2Encoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00);
|
||||
#include "../Common/CoderLoader.h"
|
||||
extern CSysString GetBZip2CodecPath();
|
||||
#endif
|
||||
|
||||
namespace NArchive {
|
||||
namespace NBZip2 {
|
||||
|
||||
HRESULT UpdateArchive(UINT64 unpackSize,
|
||||
IOutStream *outStream,
|
||||
int indexInClient,
|
||||
IArchiveUpdateCallback *updateCallback)
|
||||
{
|
||||
RINOK(updateCallback->SetTotal(unpackSize));
|
||||
|
||||
UINT64 complexity = 0;
|
||||
RINOK(updateCallback->SetCompleted(&complexity));
|
||||
|
||||
CMyComPtr<IInStream> fileInStream;
|
||||
|
||||
RINOK(updateCallback->GetStream(indexInClient, &fileInStream));
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
|
||||
localProgressSpec->Init(updateCallback, true);
|
||||
|
||||
#ifndef COMPRESS_BZIP2
|
||||
CCoderLibrary lib;
|
||||
#endif
|
||||
CMyComPtr<ICompressCoder> encoder;
|
||||
#ifdef COMPRESS_BZIP2
|
||||
encoder = new NCompress::NBZip2::CEncoder;
|
||||
#else
|
||||
RINOK(lib.LoadAndCreateCoder(GetBZip2CodecPath(),
|
||||
CLSID_CCompressBZip2Encoder, &encoder));
|
||||
#endif
|
||||
|
||||
RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, localProgress));
|
||||
|
||||
return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
|
||||
}
|
||||
|
||||
}}
|
||||
23
7zip/Archive/BZip2/BZip2Update.h
Executable file
23
7zip/Archive/BZip2/BZip2Update.h
Executable file
@@ -0,0 +1,23 @@
|
||||
// BZip2Update.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __BZIP2_UPDATE_H
|
||||
#define __BZIP2_UPDATE_H
|
||||
|
||||
#include "Common/Types.h"
|
||||
|
||||
#include "../IArchive.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NBZip2 {
|
||||
|
||||
HRESULT UpdateArchive(
|
||||
UINT64 unpackSize,
|
||||
IOutStream *outStream,
|
||||
int indexInClient,
|
||||
IArchiveUpdateCallback *updateCallback);
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
105
7zip/Archive/BZip2/DllExports.cpp
Executable file
105
7zip/Archive/BZip2/DllExports.cpp
Executable file
@@ -0,0 +1,105 @@
|
||||
// DLLExports.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#define INITGUID
|
||||
|
||||
#include "Common/ComTry.h"
|
||||
#include "Common/String.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "BZip2Handler.h"
|
||||
#include "../../ICoder.h"
|
||||
|
||||
// {23170F69-40C1-278B-0402-020000000100}
|
||||
DEFINE_GUID(CLSID_CCompressBZip2Encoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00);
|
||||
|
||||
// {23170F69-40C1-278B-0402-020000000000}
|
||||
DEFINE_GUID(CLSID_CCompressBZip2Decoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
|
||||
// {23170F69-40C1-278A-1000-000110070000}
|
||||
DEFINE_GUID(CLSID_CBZip2Handler,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00);
|
||||
|
||||
HINSTANCE g_hInstance;
|
||||
|
||||
#ifndef COMPRESS_BZIP2
|
||||
#include "../Common/CodecsPath.h"
|
||||
CSysString GetBZip2CodecPath()
|
||||
{
|
||||
return GetCodecsFolderPrefix() + TEXT("BZip2.dll");
|
||||
}
|
||||
#endif
|
||||
|
||||
extern "C"
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
||||
{
|
||||
if (dwReason == DLL_PROCESS_ATTACH)
|
||||
g_hInstance = hInstance;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
STDAPI CreateObject(
|
||||
const GUID *classID,
|
||||
const GUID *interfaceID,
|
||||
void **outObject)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
*outObject = 0;
|
||||
if (*classID != CLSID_CBZip2Handler)
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
int needIn = *interfaceID == IID_IInArchive;
|
||||
int needOut = *interfaceID == IID_IOutArchive;
|
||||
if (needIn || needOut)
|
||||
{
|
||||
NArchive::NBZip2::CHandler *temp = new NArchive::NBZip2::CHandler;
|
||||
if (needIn)
|
||||
{
|
||||
CMyComPtr<IInArchive> inArchive = (IInArchive *)temp;
|
||||
*outObject = inArchive.Detach();
|
||||
}
|
||||
else
|
||||
{
|
||||
CMyComPtr<IOutArchive> outArchive = (IOutArchive *)temp;
|
||||
*outObject = outArchive.Detach();
|
||||
}
|
||||
}
|
||||
else
|
||||
return E_NOINTERFACE;
|
||||
COM_TRY_END
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
switch(propID)
|
||||
{
|
||||
case NArchive::kName:
|
||||
propVariant = L"BZip2";
|
||||
break;
|
||||
case NArchive::kClassID:
|
||||
{
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen(
|
||||
(const char *)&CLSID_CBZip2Handler, sizeof(GUID))) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
}
|
||||
case NArchive::kExtension:
|
||||
propVariant = L"bz2 tbz2";
|
||||
break;
|
||||
case NArchive::kAddExtension:
|
||||
propVariant = L"* .tar";
|
||||
break;
|
||||
case NArchive::kUpdate:
|
||||
propVariant = true;
|
||||
break;
|
||||
case NArchive::kKeepName:
|
||||
propVariant = true;
|
||||
break;
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
3
7zip/Archive/BZip2/StdAfx.cpp
Executable file
3
7zip/Archive/BZip2/StdAfx.cpp
Executable file
@@ -0,0 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "stdafx.h"
|
||||
8
7zip/Archive/BZip2/StdAfx.h
Executable file
8
7zip/Archive/BZip2/StdAfx.h
Executable file
@@ -0,0 +1,8 @@
|
||||
// stdafx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#endif
|
||||
BIN
7zip/Archive/BZip2/bz2.ico
Executable file
BIN
7zip/Archive/BZip2/bz2.ico
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 3.6 KiB |
16
7zip/Archive/BZip2/resource.h
Executable file
16
7zip/Archive/BZip2/resource.h
Executable file
@@ -0,0 +1,16 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by resource.rc
|
||||
//
|
||||
#define IDI_ICON1 101
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 102
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
130
7zip/Archive/BZip2/resource.rc
Executable file
130
7zip/Archive/BZip2/resource.rc
Executable file
@@ -0,0 +1,130 @@
|
||||
//Microsoft Developer Studio generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Russian resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
|
||||
#pragma code_page(1251)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // Russian resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_ICON1 ICON DISCARDABLE "bz2.ico"
|
||||
|
||||
#ifndef _MAC
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,12,0,0
|
||||
PRODUCTVERSION 3,12,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "Comments", "\0"
|
||||
VALUE "CompanyName", "Igor Pavlov\0"
|
||||
VALUE "FileDescription", "BZip2 Plugin for 7-Zip\0"
|
||||
VALUE "FileVersion", "3, 12, 0, 0\0"
|
||||
VALUE "InternalName", "bz2\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "bz.dll\0"
|
||||
VALUE "PrivateBuild", "\0"
|
||||
VALUE "ProductName", "7-Zip\0"
|
||||
VALUE "ProductVersion", "3, 12, 0, 0\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
#endif // !_MAC
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
7
7zip/Archive/Cab/Cab.def
Executable file
7
7zip/Archive/Cab/Cab.def
Executable file
@@ -0,0 +1,7 @@
|
||||
; Cab.def
|
||||
|
||||
LIBRARY cab.dll
|
||||
|
||||
EXPORTS
|
||||
CreateObject PRIVATE
|
||||
GetHandlerProperty PRIVATE
|
||||
325
7zip/Archive/Cab/Cab.dsp
Executable file
325
7zip/Archive/Cab/Cab.dsp
Executable file
@@ -0,0 +1,325 @@
|
||||
# Microsoft Developer Studio Project File - Name="Cab" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=Cab - 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 "Cab.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 "Cab.mak" CFG="Cab - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "Cab - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "Cab - 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)" == "Cab - 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 "CAB_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /Yu"StdAfx.h" /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
# ADD RSC /l 0x419 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Formats\cab.dll" /opt:NOWIN98
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ELSEIF "$(CFG)" == "Cab - 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 "CAB_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||
# ADD RSC /l 0x419 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Formats\cab.dll" /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "Cab - Win32 Release"
|
||||
# Name "Cab - Win32 Debug"
|
||||
# Begin Group "Spec"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Cab.def
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DllExports.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\resource.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\resource.rc
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.cpp
|
||||
# ADD CPP /Yc
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Common"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\NewHandler.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\NewHandler.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\String.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\String.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\StringConvert.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\StringConvert.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\UTFConvert.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\UTFConvert.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Vector.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Vector.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Windows"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\PropVariant.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\PropVariant.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Engine"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CabCopyDecoder.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CabCopyDecoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CabHandler.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CabHandler.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CabHeader.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CabHeader.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CabIn.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CabIn.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CabInBuffer.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CabInBuffer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CabItem.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\LZXBitDecoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\LZXConst.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\LZXDecoder.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\LZXDecoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\LZXExtConst.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\LZXi86Converter.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\LZXi86Converter.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\MSZipConst.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\MSZipDecoder.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\MSZipDecoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\MSZipExtConst.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "7zip Common"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\InBuffer.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\InBuffer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\LSBFDecoder.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\LSBFDecoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\OutBuffer.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\OutBuffer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\ProgressUtils.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\ProgressUtils.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Compress"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Group "LZ"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Compress\LZ\LZOutWindow.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Compress\LZ\LZOutWindow.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cab.ico
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
29
7zip/Archive/Cab/Cab.dsw
Executable file
29
7zip/Archive/Cab/Cab.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: "Cab"=.\Cab.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
67
7zip/Archive/Cab/CabCopyDecoder.cpp
Executable file
67
7zip/Archive/Cab/CabCopyDecoder.cpp
Executable file
@@ -0,0 +1,67 @@
|
||||
// CabCopyDecoder.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "CabCopyDecoder.h"
|
||||
#include "Common/Defs.h"
|
||||
#include "Windows/Defs.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NCab {
|
||||
|
||||
static const UINT32 kBufferSize = 1 << 17;
|
||||
|
||||
/*
|
||||
void CCopyDecoder::ReleaseStreams()
|
||||
{
|
||||
m_InStream.ReleaseStream();
|
||||
m_OutStream.ReleaseStream();
|
||||
}
|
||||
*/
|
||||
class CCopyDecoderFlusher
|
||||
{
|
||||
CCopyDecoder *m_Decoder;
|
||||
public:
|
||||
CCopyDecoderFlusher(CCopyDecoder *aDecoder): m_Decoder(aDecoder) {}
|
||||
~CCopyDecoderFlusher()
|
||||
{
|
||||
m_Decoder->Flush();
|
||||
// m_Decoder->ReleaseStreams();
|
||||
}
|
||||
};
|
||||
|
||||
STDMETHODIMP CCopyDecoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
if (outSize == NULL)
|
||||
return E_INVALIDARG;
|
||||
UINT64 size = *outSize;
|
||||
|
||||
m_InStream.Init(inStream, m_ReservedSize, m_NumInDataBlocks);
|
||||
m_OutStream.Init(outStream);
|
||||
CCopyDecoderFlusher decoderFlusher(this);
|
||||
|
||||
UINT64 nowPos64 = 0;
|
||||
while(nowPos64 < size)
|
||||
{
|
||||
UINT32 blockSize;
|
||||
bool dataAreCorrect;
|
||||
RINOK(m_InStream.ReadBlock(blockSize, dataAreCorrect));
|
||||
if (!dataAreCorrect)
|
||||
{
|
||||
throw 123456;
|
||||
}
|
||||
for (UINT32 i = 0; i < blockSize; i++)
|
||||
m_OutStream.WriteByte(m_InStream.ReadByte());
|
||||
nowPos64 += blockSize;
|
||||
if (progress != NULL)
|
||||
{
|
||||
RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64));
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}}
|
||||
43
7zip/Archive/Cab/CabCopyDecoder.h
Executable file
43
7zip/Archive/Cab/CabCopyDecoder.h
Executable file
@@ -0,0 +1,43 @@
|
||||
// CabCopyDecoder.h
|
||||
|
||||
#ifndef __ARCHIVE_CAB_COPY_DECODER_H
|
||||
#define __ARCHIVE_CAB_COPY_DECODER_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "../../ICoder.h"
|
||||
#include "../../Common/OutBuffer.h"
|
||||
#include "CabInBuffer.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NCab {
|
||||
|
||||
class CCopyDecoder:
|
||||
public ICompressCoder,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
CInBuffer m_InStream;
|
||||
COutBuffer m_OutStream;
|
||||
BYTE m_ReservedSize;
|
||||
UINT32 m_NumInDataBlocks;
|
||||
public:
|
||||
MY_UNKNOWN_IMP
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
// void ReleaseStreams();
|
||||
HRESULT Flush() { return m_OutStream.Flush(); }
|
||||
void SetParams(BYTE reservedSize, UINT32 numInDataBlocks)
|
||||
{
|
||||
m_ReservedSize = reservedSize;
|
||||
m_NumInDataBlocks = numInDataBlocks;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
636
7zip/Archive/Cab/CabHandler.cpp
Executable file
636
7zip/Archive/Cab/CabHandler.cpp
Executable file
@@ -0,0 +1,636 @@
|
||||
// Cab/Handler.cpp
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "Common/StringConvert.h"
|
||||
#include "Common/Defs.h"
|
||||
#include "Common/UTFConvert.h"
|
||||
#include "Common/ComTry.h"
|
||||
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "Windows/Time.h"
|
||||
|
||||
#include "CabCopyDecoder.h"
|
||||
#include "LZXDecoder.h"
|
||||
#include "MSZIPDecoder.h"
|
||||
|
||||
#include "CabHandler.h"
|
||||
|
||||
#include "../../Common/ProgressUtils.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NTime;
|
||||
|
||||
namespace NArchive {
|
||||
namespace NCab {
|
||||
|
||||
STATPROPSTG kProperties[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
{ NULL, kpidIsFolder, VT_BOOL},
|
||||
{ NULL, kpidSize, VT_UI8},
|
||||
{ NULL, kpidLastWriteTime, VT_FILETIME},
|
||||
{ NULL, kpidAttributes, VT_UI4},
|
||||
|
||||
{ NULL, kpidMethod, VT_BSTR},
|
||||
// { NULL, kpidDictionarySize, VT_UI4},
|
||||
|
||||
{ NULL, kpidBlock, VT_UI4}
|
||||
};
|
||||
|
||||
static const int kNumProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
||||
|
||||
static const wchar_t *kMethods[] =
|
||||
{
|
||||
L"None",
|
||||
L"MSZip",
|
||||
L"Quantum",
|
||||
L"LZX"
|
||||
};
|
||||
|
||||
static const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]);
|
||||
static const wchar_t *kUnknownMethod = L"Unknown";
|
||||
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
value->vt = VT_EMPTY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UINT32 *numProperties)
|
||||
{
|
||||
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
|
||||
return E_INVALIDARG;
|
||||
const STATPROPSTG &srcItem = kProperties[index];
|
||||
*propID = srcItem.propid;
|
||||
*varType = srcItem.vt;
|
||||
*name = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UINT32 *numProperties)
|
||||
{
|
||||
*numProperties = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UINT32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
const CItem &fileInfo = m_Files[index];
|
||||
switch(propID)
|
||||
{
|
||||
case kpidPath:
|
||||
if (fileInfo.IsNameUTF())
|
||||
{
|
||||
UString unicodeName;
|
||||
if (!ConvertUTF8ToUnicode(fileInfo.Name, unicodeName))
|
||||
propVariant = L"";
|
||||
else
|
||||
propVariant = unicodeName;
|
||||
}
|
||||
else
|
||||
propVariant = MultiByteToUnicodeString(fileInfo.Name, CP_ACP);
|
||||
break;
|
||||
case kpidIsFolder:
|
||||
propVariant = false;
|
||||
break;
|
||||
case kpidSize:
|
||||
propVariant = fileInfo.UnPackSize;
|
||||
break;
|
||||
case kpidLastWriteTime:
|
||||
{
|
||||
FILETIME localFileTime, utcFileTime;
|
||||
if (DosTimeToFileTime(fileInfo.Time, localFileTime))
|
||||
{
|
||||
if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime))
|
||||
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
|
||||
}
|
||||
else
|
||||
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
|
||||
propVariant = utcFileTime;
|
||||
break;
|
||||
}
|
||||
case kpidAttributes:
|
||||
propVariant = fileInfo.GetWinAttributes();
|
||||
break;
|
||||
|
||||
case kpidMethod:
|
||||
{
|
||||
UINT16 realFolderIndex = NHeader::NFolderIndex::GetRealFolderIndex(
|
||||
m_Folders.Size(), fileInfo.FolderIndex);
|
||||
const NHeader::CFolder &folder = m_Folders[realFolderIndex];
|
||||
UString method;
|
||||
int methodIndex = folder.GetCompressionMethod();
|
||||
if (methodIndex < kNumMethods)
|
||||
method = kMethods[methodIndex];
|
||||
else
|
||||
method = kUnknownMethod;
|
||||
if (methodIndex == NHeader::NCompressionMethodMajor::kLZX)
|
||||
{
|
||||
method += L":";
|
||||
wchar_t temp[32];
|
||||
_itow (folder.CompressionTypeMinor, temp, 10);
|
||||
method += temp;
|
||||
}
|
||||
propVariant = method;
|
||||
break;
|
||||
}
|
||||
case kpidBlock:
|
||||
propVariant = UINT32(fileInfo.FolderIndex);
|
||||
break;
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
class CPropgressImp: public CProgressVirt
|
||||
{
|
||||
CMyComPtr<IArchiveOpenCallback> m_OpenArchiveCallback;
|
||||
public:
|
||||
STDMETHOD(SetTotal)(const UINT64 *numFiles);
|
||||
STDMETHOD(SetCompleted)(const UINT64 *numFiles);
|
||||
void Init(IArchiveOpenCallback *openArchiveCallback)
|
||||
{ m_OpenArchiveCallback = openArchiveCallback; }
|
||||
};
|
||||
|
||||
STDMETHODIMP CPropgressImp::SetTotal(const UINT64 *numFiles)
|
||||
{
|
||||
if (m_OpenArchiveCallback)
|
||||
return m_OpenArchiveCallback->SetCompleted(numFiles, NULL);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CPropgressImp::SetCompleted(const UINT64 *numFiles)
|
||||
{
|
||||
if (m_OpenArchiveCallback)
|
||||
return m_OpenArchiveCallback->SetCompleted(numFiles, NULL);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
const UINT64 *maxCheckStartPosition,
|
||||
IArchiveOpenCallback *openArchiveCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
m_Stream.Release();
|
||||
// try
|
||||
{
|
||||
CInArchive archive;
|
||||
m_Files.Clear();
|
||||
CPropgressImp progressImp;
|
||||
progressImp.Init(openArchiveCallback);
|
||||
RINOK(archive.Open(inStream, maxCheckStartPosition,
|
||||
m_ArchiveInfo, m_Folders, m_Files, &progressImp));
|
||||
m_Stream = inStream;
|
||||
}
|
||||
/*
|
||||
catch(...)
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
*/
|
||||
COM_TRY_END
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Close()
|
||||
{
|
||||
m_Stream.Release();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
class CCabFolderOutStream:
|
||||
public ISequentialOutStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize);
|
||||
STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize);
|
||||
private:
|
||||
const CObjectVector<NHeader::CFolder> *m_Folders;
|
||||
const CObjectVector<CItem> *m_Files;
|
||||
const CRecordVector<int> *m_FileIndexes;
|
||||
const CRecordVector<bool> *m_ExtractStatuses;
|
||||
int m_StartIndex;
|
||||
int m_CurrentIndex;
|
||||
int m_NumFiles;
|
||||
UINT64 m_CurrentDataPos;
|
||||
CMyComPtr<IArchiveExtractCallback> m_ExtractCallback;
|
||||
bool m_TestMode;
|
||||
|
||||
bool m_FileIsOpen;
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
UINT64 m_FilePos;
|
||||
|
||||
HRESULT OpenFile(int indexIndex, ISequentialOutStream **realOutStream);
|
||||
HRESULT WriteEmptyFiles();
|
||||
UINT64 m_StartImportantTotalUnPacked;
|
||||
public:
|
||||
void Init(
|
||||
const CObjectVector<NHeader::CFolder> *folders,
|
||||
const CObjectVector<CItem> *files,
|
||||
const CRecordVector<int> *fileIndices,
|
||||
const CRecordVector<bool> *extractStatuses,
|
||||
int startIndex,
|
||||
int numFiles,
|
||||
IArchiveExtractCallback *extractCallback,
|
||||
UINT64 startImportantTotalUnPacked,
|
||||
bool testMode);
|
||||
HRESULT FlushCorrupted();
|
||||
HRESULT Unsupported();
|
||||
};
|
||||
|
||||
void CCabFolderOutStream::Init(
|
||||
const CObjectVector<NHeader::CFolder> *folders,
|
||||
const CObjectVector<CItem> *files,
|
||||
const CRecordVector<int> *fileIndices,
|
||||
const CRecordVector<bool> *extractStatuses,
|
||||
int startIndex,
|
||||
int numFiles,
|
||||
IArchiveExtractCallback *extractCallback,
|
||||
UINT64 startImportantTotalUnPacked,
|
||||
bool testMode)
|
||||
{
|
||||
m_Folders = folders;
|
||||
m_Files = files;
|
||||
m_FileIndexes = fileIndices;
|
||||
m_ExtractStatuses = extractStatuses;
|
||||
m_StartIndex = startIndex;
|
||||
m_NumFiles = numFiles;
|
||||
m_ExtractCallback = extractCallback;
|
||||
m_StartImportantTotalUnPacked = startImportantTotalUnPacked;
|
||||
m_TestMode = testMode;
|
||||
|
||||
m_CurrentIndex = 0;
|
||||
m_FileIsOpen = false;
|
||||
}
|
||||
|
||||
HRESULT CCabFolderOutStream::OpenFile(int indexIndex, ISequentialOutStream **realOutStream)
|
||||
{
|
||||
// RINOK(m_ExtractCallback->SetCompleted(&m_StartImportantTotalUnPacked));
|
||||
|
||||
int fullIndex = m_StartIndex + indexIndex;
|
||||
|
||||
INT32 askMode;
|
||||
if((*m_ExtractStatuses)[fullIndex])
|
||||
askMode = m_TestMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
else
|
||||
askMode = NArchive::NExtract::NAskMode::kSkip;
|
||||
|
||||
int index = (*m_FileIndexes)[fullIndex];
|
||||
const CItem &fileInfo = (*m_Files)[index];
|
||||
UINT16 realFolderIndex = NHeader::NFolderIndex::GetRealFolderIndex(
|
||||
m_Folders->Size(), fileInfo.FolderIndex);
|
||||
|
||||
RINOK(m_ExtractCallback->GetStream(index, realOutStream, askMode));
|
||||
|
||||
UINT64 currentUnPackSize = fileInfo.UnPackSize;
|
||||
|
||||
bool mustBeProcessedAnywhere = (indexIndex < m_NumFiles - 1);
|
||||
|
||||
if (realOutStream || mustBeProcessedAnywhere)
|
||||
{
|
||||
if (!realOutStream && !m_TestMode)
|
||||
askMode = NArchive::NExtract::NAskMode::kSkip;
|
||||
RINOK(m_ExtractCallback->PrepareOperation(askMode));
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
|
||||
HRESULT CCabFolderOutStream::WriteEmptyFiles()
|
||||
{
|
||||
for(;m_CurrentIndex < m_NumFiles; m_CurrentIndex++)
|
||||
{
|
||||
int index = (*m_FileIndexes)[m_StartIndex + m_CurrentIndex];
|
||||
const CItem &fileInfo = (*m_Files)[index];
|
||||
if (fileInfo.UnPackSize != 0)
|
||||
return S_OK;
|
||||
realOutStream.Release();
|
||||
HRESULT result = OpenFile(m_CurrentIndex, &realOutStream);
|
||||
realOutStream.Release();
|
||||
if (result == S_FALSE)
|
||||
{
|
||||
}
|
||||
else if (result == S_OK)
|
||||
{
|
||||
RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
}
|
||||
else
|
||||
return result;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CCabFolderOutStream::Write(const void *data,
|
||||
UINT32 size, UINT32 *processedSize)
|
||||
{
|
||||
UINT32 processedSizeReal = 0;
|
||||
while(m_CurrentIndex < m_NumFiles)
|
||||
{
|
||||
if (m_FileIsOpen)
|
||||
{
|
||||
int index = (*m_FileIndexes)[m_StartIndex + m_CurrentIndex];
|
||||
const CItem &fileInfo = (*m_Files)[index];
|
||||
UINT64 fileSize = fileInfo.UnPackSize;
|
||||
|
||||
UINT32 numBytesToWrite = (UINT32)MyMin(fileSize - m_FilePos,
|
||||
UINT64(size - processedSizeReal));
|
||||
|
||||
UINT32 processedSizeLocal;
|
||||
if (!realOutStream)
|
||||
{
|
||||
processedSizeLocal = numBytesToWrite;
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(realOutStream->Write((const BYTE *)data + processedSizeReal, numBytesToWrite, &processedSizeLocal));
|
||||
}
|
||||
m_FilePos += processedSizeLocal;
|
||||
processedSizeReal += processedSizeLocal;
|
||||
if (m_FilePos == fileInfo.UnPackSize)
|
||||
{
|
||||
realOutStream.Release();
|
||||
RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
m_FileIsOpen = false;
|
||||
m_CurrentIndex++;
|
||||
}
|
||||
if (processedSizeReal == size)
|
||||
{
|
||||
RINOK(WriteEmptyFiles());
|
||||
if (processedSize != NULL)
|
||||
*processedSize = processedSizeReal;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
HRESULT result = OpenFile(m_CurrentIndex, &realOutStream);
|
||||
if (result != S_FALSE && result != S_OK)
|
||||
return result;
|
||||
m_FileIsOpen = true;
|
||||
m_FilePos = 0;
|
||||
}
|
||||
}
|
||||
if (processedSize != NULL)
|
||||
*processedSize = size;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CCabFolderOutStream::FlushCorrupted()
|
||||
{
|
||||
// UINT32 processedSizeReal = 0;
|
||||
while(m_CurrentIndex < m_NumFiles)
|
||||
{
|
||||
if (m_FileIsOpen)
|
||||
{
|
||||
int index = (*m_FileIndexes)[m_StartIndex + m_CurrentIndex];
|
||||
const CItem &fileInfo = (*m_Files)[index];
|
||||
UINT64 fileSize = fileInfo.UnPackSize;
|
||||
|
||||
realOutStream.Release();
|
||||
RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kCRCError));
|
||||
m_FileIsOpen = false;
|
||||
m_CurrentIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
HRESULT result = OpenFile(m_CurrentIndex, &realOutStream);
|
||||
if (result != S_FALSE && result != S_OK)
|
||||
return result;
|
||||
m_FileIsOpen = true;
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CCabFolderOutStream::Unsupported()
|
||||
{
|
||||
while(m_CurrentIndex < m_NumFiles)
|
||||
{
|
||||
HRESULT result = OpenFile(m_CurrentIndex, &realOutStream);
|
||||
if (result != S_FALSE && result != S_OK)
|
||||
return result;
|
||||
realOutStream.Release();
|
||||
RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
||||
m_CurrentIndex++;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CCabFolderOutStream::WritePart(const void *data,
|
||||
UINT32 size, UINT32 *processedSize)
|
||||
{
|
||||
return Write(data, size, processedSize);
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
|
||||
INT32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool allFilesMode = (numItems == UINT32(-1));
|
||||
if (allFilesMode)
|
||||
numItems = m_Files.Size();
|
||||
if(numItems == 0)
|
||||
return S_OK;
|
||||
bool testMode = (_aTestMode != 0);
|
||||
UINT64 censoredTotalUnPacked = 0, importantTotalUnPacked = 0;
|
||||
int lastIndex = 0;
|
||||
CRecordVector<int> folderIndexes;
|
||||
CRecordVector<int> importantIndices;
|
||||
CRecordVector<bool> extractStatuses;
|
||||
|
||||
UINT32 i;
|
||||
for(i = 0; i < numItems; i++)
|
||||
{
|
||||
int index = allFilesMode ? i : indices[i];
|
||||
const CItem &fileInfo = m_Files[index];
|
||||
censoredTotalUnPacked += fileInfo.UnPackSize;
|
||||
|
||||
int folderIndex = fileInfo.FolderIndex;
|
||||
if (folderIndexes.IsEmpty())
|
||||
folderIndexes.Add(folderIndex);
|
||||
else
|
||||
{
|
||||
if (folderIndex != folderIndexes.Back())
|
||||
folderIndexes.Add(folderIndex);
|
||||
}
|
||||
|
||||
for(int j = index - 1; j >= lastIndex; j--)
|
||||
if(m_Files[j].FolderIndex != folderIndex)
|
||||
break;
|
||||
for(j++; j <= index; j++)
|
||||
{
|
||||
const CItem &fileInfo = m_Files[j];
|
||||
importantTotalUnPacked += fileInfo.UnPackSize;
|
||||
importantIndices.Add(j);
|
||||
extractStatuses.Add(j == index);
|
||||
}
|
||||
lastIndex = index + 1;
|
||||
}
|
||||
|
||||
extractCallback->SetTotal(importantTotalUnPacked);
|
||||
UINT64 currentImportantTotalUnPacked = 0;
|
||||
UINT64 currentImportantTotalPacked = 0;
|
||||
|
||||
CCopyDecoder *storeDecoderSpec = NULL;
|
||||
CMyComPtr<ICompressCoder> storeDecoder;
|
||||
|
||||
NMSZip::CDecoder *msZipDecoderSpec = NULL;
|
||||
CMyComPtr<ICompressCoder> msZipDecoder;
|
||||
|
||||
NLZX::CDecoder *lzxDecoderSpec = NULL;
|
||||
CMyComPtr<ICompressCoder> lzxDecoder;
|
||||
|
||||
|
||||
int curImportantIndexIndex = 0;
|
||||
UINT64 totalFolderUnPacked;
|
||||
for(i = 0; i < (UINT32)folderIndexes.Size(); i++, currentImportantTotalUnPacked += totalFolderUnPacked)
|
||||
{
|
||||
int folderIndex = folderIndexes[i];
|
||||
UINT16 realFolderIndex = NHeader::NFolderIndex::GetRealFolderIndex(
|
||||
m_Folders.Size(), folderIndex);
|
||||
|
||||
RINOK(extractCallback->SetCompleted(¤tImportantTotalUnPacked));
|
||||
totalFolderUnPacked = 0;
|
||||
for (int j = curImportantIndexIndex; j < importantIndices.Size(); j++)
|
||||
{
|
||||
const CItem &fileInfo = m_Files[importantIndices[j]];
|
||||
if (fileInfo.FolderIndex != folderIndex)
|
||||
break;
|
||||
totalFolderUnPacked += fileInfo.UnPackSize;
|
||||
}
|
||||
|
||||
CCabFolderOutStream *cabFolderOutStream = new CCabFolderOutStream;
|
||||
CMyComPtr<ISequentialOutStream> outStream(cabFolderOutStream);
|
||||
|
||||
const NHeader::CFolder &folder = m_Folders[realFolderIndex];
|
||||
|
||||
cabFolderOutStream->Init(&m_Folders, &m_Files, &importantIndices,
|
||||
&extractStatuses, curImportantIndexIndex, j - curImportantIndexIndex,
|
||||
extractCallback, currentImportantTotalUnPacked,
|
||||
folder.GetCompressionMethod() == NHeader::NCompressionMethodMajor::kQuantum?
|
||||
true: testMode);
|
||||
|
||||
curImportantIndexIndex = j;
|
||||
|
||||
UINT64 pos = folder.DataStart; // test it (+ archiveStart)
|
||||
RINOK(m_Stream->Seek(pos, STREAM_SEEK_SET, NULL));
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
|
||||
localProgressSpec->Init(extractCallback, false);
|
||||
|
||||
CLocalCompressProgressInfo *localCompressProgressSpec =
|
||||
new CLocalCompressProgressInfo;
|
||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
||||
localCompressProgressSpec->Init(progress,
|
||||
NULL, ¤tImportantTotalUnPacked);
|
||||
|
||||
BYTE reservedSize = m_ArchiveInfo.ReserveBlockPresent() ?
|
||||
m_ArchiveInfo.PerDataSizes.PerDatablockAreaSize : 0;
|
||||
|
||||
switch(folder.GetCompressionMethod())
|
||||
{
|
||||
case NHeader::NCompressionMethodMajor::kNone:
|
||||
{
|
||||
if(storeDecoderSpec == NULL)
|
||||
{
|
||||
storeDecoderSpec = new CCopyDecoder;
|
||||
storeDecoder = storeDecoderSpec;
|
||||
}
|
||||
try
|
||||
{
|
||||
storeDecoderSpec->SetParams(reservedSize, folder.NumDataBlocks);
|
||||
RINOK(storeDecoder->Code(m_Stream, outStream,
|
||||
NULL, &totalFolderUnPacked, compressProgress));
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
RINOK(cabFolderOutStream->FlushCorrupted());
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NHeader::NCompressionMethodMajor::kMSZip:
|
||||
{
|
||||
if(lzxDecoderSpec == NULL)
|
||||
{
|
||||
msZipDecoderSpec = new NMSZip::CDecoder;
|
||||
msZipDecoder = msZipDecoderSpec;
|
||||
}
|
||||
try
|
||||
{
|
||||
msZipDecoderSpec->SetParams(reservedSize, folder.NumDataBlocks);
|
||||
RINOK(msZipDecoder->Code(m_Stream, outStream,
|
||||
NULL, &totalFolderUnPacked, compressProgress));
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
RINOK(cabFolderOutStream->FlushCorrupted());
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NHeader::NCompressionMethodMajor::kLZX:
|
||||
{
|
||||
if(lzxDecoderSpec == NULL)
|
||||
{
|
||||
lzxDecoderSpec = new NLZX::CDecoder;
|
||||
lzxDecoder = lzxDecoderSpec;
|
||||
}
|
||||
try
|
||||
{
|
||||
lzxDecoderSpec->SetParams(reservedSize, folder.NumDataBlocks,
|
||||
folder.CompressionTypeMinor);
|
||||
RINOK(lzxDecoder->Code(m_Stream, outStream,
|
||||
NULL, &totalFolderUnPacked, compressProgress));
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
RINOK(cabFolderOutStream->FlushCorrupted());
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
RINOK(cabFolderOutStream->Unsupported());
|
||||
// return E_FAIL;
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfItems(UINT32 *numItems)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
*numItems = m_Files.Size();
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
}}
|
||||
50
7zip/Archive/Cab/CabHandler.h
Executable file
50
7zip/Archive/Cab/CabHandler.h
Executable file
@@ -0,0 +1,50 @@
|
||||
// CabHandler.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __CAB_HANDLER_H
|
||||
#define __CAB_HANDLER_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "../IArchive.h"
|
||||
#include "CabIn.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NCab {
|
||||
|
||||
class CHandler:
|
||||
public IInArchive,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
STDMETHOD(Open)(IInStream *stream,
|
||||
const UINT64 *maxCheckStartPosition,
|
||||
IArchiveOpenCallback *openArchiveCallback);
|
||||
STDMETHOD(Close)();
|
||||
STDMETHOD(GetNumberOfItems)(UINT32 *numItems);
|
||||
STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value);
|
||||
STDMETHOD(Extract)(const UINT32* indices, UINT32 numItems,
|
||||
INT32 testMode, IArchiveExtractCallback *extractCallback);
|
||||
|
||||
STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value);
|
||||
|
||||
STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties);
|
||||
STDMETHOD(GetPropertyInfo)(UINT32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType);
|
||||
|
||||
STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties);
|
||||
STDMETHOD(GetArchivePropertyInfo)(UINT32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType);
|
||||
|
||||
private:
|
||||
CObjectVector<NHeader::CFolder> m_Folders;
|
||||
CObjectVector<CItem> m_Files;
|
||||
CInArchiveInfo m_ArchiveInfo;
|
||||
CMyComPtr<IInStream> m_Stream;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
19
7zip/Archive/Cab/CabHeader.cpp
Executable file
19
7zip/Archive/Cab/CabHeader.cpp
Executable file
@@ -0,0 +1,19 @@
|
||||
// Archive/Cab/Header.h
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "CabHeader.h"
|
||||
|
||||
namespace NArchive{
|
||||
namespace NCab{
|
||||
namespace NHeader{
|
||||
|
||||
namespace NArchive {
|
||||
|
||||
UINT32 kSignature = 0x4643534d + 1;
|
||||
static class CSignatureInitializer
|
||||
{ public: CSignatureInitializer() { kSignature--; }} g_SignatureInitializer;
|
||||
|
||||
}
|
||||
|
||||
}}}
|
||||
117
7zip/Archive/Cab/CabHeader.h
Executable file
117
7zip/Archive/Cab/CabHeader.h
Executable file
@@ -0,0 +1,117 @@
|
||||
// Archive/Cab/Header.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARCHIVE_CAB_HEADER_H
|
||||
#define __ARCHIVE_CAB_HEADER_H
|
||||
|
||||
#include "Common/Types.h"
|
||||
|
||||
#pragma pack(push, PragmaCabHeaders)
|
||||
#pragma pack(push, 1)
|
||||
|
||||
namespace NArchive {
|
||||
namespace NCab {
|
||||
namespace NHeader{
|
||||
|
||||
namespace NArchive {
|
||||
|
||||
extern UINT32 kSignature;
|
||||
|
||||
namespace NFlags
|
||||
{
|
||||
const int kPrevCabinet = 0x0001;
|
||||
const int kNextCabinet = 0x0002;
|
||||
const int kReservePresent = 0x0004;
|
||||
}
|
||||
|
||||
struct CBlock
|
||||
{
|
||||
UINT32 Signature; /* cabinet file signature */
|
||||
UINT32 Reserved1; /* reserved */
|
||||
UINT32 Size; /* size of this cabinet file in bytes */
|
||||
UINT32 Reserved2; /* reserved */
|
||||
UINT32 FileOffset; /* offset of the first CFFILE entry */
|
||||
UINT32 Reserved3; /* reserved */
|
||||
BYTE VersionMinor; /* cabinet file format version, minor */
|
||||
BYTE VersionMajor; /* cabinet file format version, major */
|
||||
UINT16 NumFolders; /* number of CFFOLDER entries in this cabinet */
|
||||
UINT16 NumFiles; /* number of CFFILE entries in this cabinet */
|
||||
UINT16 Flags; /* cabinet file option indicators */
|
||||
UINT16 SetID; /* must be the same for all cabinets in a set */
|
||||
UINT16 CabinetNumber; /* number of this cabinet file in a set */
|
||||
};
|
||||
|
||||
struct CPerDataSizes
|
||||
{
|
||||
UINT16 PerCabinetAreaSize; /* (optional) size of per-cabinet reserved area */
|
||||
BYTE PerFolderAreaSize; /* (optional) size of per-folder reserved area */
|
||||
BYTE PerDatablockAreaSize; /* (optional) size of per-datablock reserved area */
|
||||
};
|
||||
|
||||
/*
|
||||
BYTE abReserve[]; // (optional) per-cabinet reserved area
|
||||
BYTE szCabinetPrev[]; // (optional) name of previous cabinet file
|
||||
BYTE szDiskPrev[]; // (optional) name of previous disk
|
||||
BYTE szCabinetNext[]; // (optional) name of next cabinet file
|
||||
BYTE szDiskNext[]; // (optional) name of next disk
|
||||
*/
|
||||
}
|
||||
|
||||
namespace NCompressionMethodMajor
|
||||
{
|
||||
const BYTE kNone = 0;
|
||||
const BYTE kMSZip = 1;
|
||||
const BYTE kQuantum = 2;
|
||||
const BYTE kLZX = 3;
|
||||
}
|
||||
|
||||
struct CFolder
|
||||
{
|
||||
UINT32 DataStart; // offset of the first CFDATA block in this folder
|
||||
UINT16 NumDataBlocks; // number of CFDATA blocks in this folder
|
||||
BYTE CompressionTypeMajor;
|
||||
BYTE CompressionTypeMinor;
|
||||
// BYTE abReserve[]; // (optional) per-folder reserved area
|
||||
BYTE GetCompressionMethod() const { return CompressionTypeMajor & 0xF; }
|
||||
};
|
||||
|
||||
const int kFileNameIsUTFAttributeMask = 0x80;
|
||||
|
||||
namespace NFolderIndex
|
||||
{
|
||||
const int kContinuedFromPrev = 0xFFFD;
|
||||
const int kContinuedToNext = 0xFFFE;
|
||||
const int kContinuedPrevAndNext = 0xFFFF;
|
||||
inline UINT16 GetRealFolderIndex(UINT16 aNumFolders, UINT16 aFolderIndex)
|
||||
{
|
||||
switch(aFolderIndex)
|
||||
{
|
||||
case kContinuedFromPrev:
|
||||
return 0;
|
||||
case kContinuedToNext:
|
||||
case kContinuedPrevAndNext:
|
||||
return aNumFolders - 1;
|
||||
default:
|
||||
return aFolderIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct CFile
|
||||
{
|
||||
UINT32 UnPackSize; /* uncompressed size of this file in bytes */
|
||||
UINT32 UnPackOffset; /* uncompressed offset of this file in the folder */
|
||||
UINT16 FolderIndex; /* index into the CFFOLDER area */
|
||||
UINT16 PureDate;
|
||||
UINT16 PureTime; /* Time */
|
||||
UINT16 Attributes; /* attribute flags for this file */
|
||||
//BYTE szName[]; /* name of this file */
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#pragma pack(pop)
|
||||
#pragma pack(pop, PragmaCabHeaders)
|
||||
|
||||
#endif
|
||||
189
7zip/Archive/Cab/CabIn.cpp
Executable file
189
7zip/Archive/Cab/CabIn.cpp
Executable file
@@ -0,0 +1,189 @@
|
||||
// Archive/CabIn.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/StringConvert.h"
|
||||
#include "Common/MyCom.h"
|
||||
#include "CabIn.h"
|
||||
#include "Windows/Defs.h"
|
||||
#include "../../Common/InBuffer.h"
|
||||
|
||||
namespace NArchive{
|
||||
namespace NCab{
|
||||
|
||||
static HRESULT ReadBytes(IInStream *inStream, void *data, UINT32 size)
|
||||
{
|
||||
UINT32 realProcessedSize;
|
||||
RINOK(inStream->Read(data, size, &realProcessedSize));
|
||||
if(realProcessedSize != size)
|
||||
return S_FALSE;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT SafeRead(IInStream *inStream, void *data, UINT32 size)
|
||||
{
|
||||
UINT32 realProcessedSize;
|
||||
RINOK(inStream->Read(data, size, &realProcessedSize));
|
||||
if(realProcessedSize != size)
|
||||
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static void SafeInByteRead(CInBuffer &inBuffer, void *data, UINT32 size)
|
||||
{
|
||||
UINT32 realProcessedSize;
|
||||
inBuffer.ReadBytes(data, size, realProcessedSize);
|
||||
if(realProcessedSize != size)
|
||||
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
|
||||
}
|
||||
|
||||
static void SafeReadName(CInBuffer &inBuffer, AString &name)
|
||||
{
|
||||
name.Empty();
|
||||
while(true)
|
||||
{
|
||||
BYTE b;
|
||||
if (!inBuffer.ReadByte(b))
|
||||
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
|
||||
if (b == 0)
|
||||
return;
|
||||
name += char(b);
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT CInArchive::Open(IInStream *inStream,
|
||||
const UINT64 *searchHeaderSizeLimit,
|
||||
CInArchiveInfo &inArchiveInfo,
|
||||
CObjectVector<NHeader::CFolder> &folders,
|
||||
CObjectVector<CItem> &files,
|
||||
CProgressVirt *progressVirt)
|
||||
{
|
||||
UINT64 startPosition;
|
||||
RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &startPosition));
|
||||
|
||||
NHeader::NArchive::CBlock archiveHeader;
|
||||
|
||||
{
|
||||
CInBuffer inBuffer;
|
||||
inBuffer.Init(inStream);
|
||||
UINT64 value = 0;
|
||||
const int kSignatureSize = sizeof(value);
|
||||
UINT64 kSignature64 = NHeader::NArchive::kSignature;
|
||||
while(true)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
startPosition += inBuffer.GetProcessedSize() - kSignatureSize;
|
||||
}
|
||||
RINOK(inStream->Seek(startPosition, STREAM_SEEK_SET, NULL));
|
||||
RINOK(ReadBytes(inStream, &archiveHeader, sizeof(archiveHeader)));
|
||||
// if (archiveHeader.Signature != NHeader::NArchive::kSignature)
|
||||
// return S_FALSE;
|
||||
|
||||
if (archiveHeader.Reserved1 != 0 ||
|
||||
archiveHeader.Reserved2 != 0 ||
|
||||
archiveHeader.Reserved3 != 0)
|
||||
throw CInArchiveException(CInArchiveException::kUnsupported);
|
||||
|
||||
inArchiveInfo.VersionMinor = archiveHeader.VersionMinor;
|
||||
inArchiveInfo.VersionMajor = archiveHeader.VersionMajor;
|
||||
inArchiveInfo.NumFolders = archiveHeader.NumFolders;
|
||||
inArchiveInfo.NumFiles = archiveHeader.NumFiles;
|
||||
inArchiveInfo.Flags = archiveHeader.Flags;
|
||||
|
||||
if (inArchiveInfo.ReserveBlockPresent())
|
||||
{
|
||||
RINOK(SafeRead(inStream, &inArchiveInfo.PerDataSizes,
|
||||
sizeof(inArchiveInfo.PerDataSizes)));
|
||||
RINOK(inStream->Seek(inArchiveInfo.PerDataSizes.PerCabinetAreaSize,
|
||||
STREAM_SEEK_CUR, NULL));
|
||||
}
|
||||
|
||||
{
|
||||
UINT64 foldersStartPosition;
|
||||
RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &foldersStartPosition));
|
||||
CInBuffer inBuffer;
|
||||
inBuffer.Init(inStream);
|
||||
if ((archiveHeader.Flags & NHeader::NArchive::NFlags::kPrevCabinet) != 0)
|
||||
{
|
||||
SafeReadName(inBuffer, inArchiveInfo.PreviousCabinetName);
|
||||
SafeReadName(inBuffer, inArchiveInfo.PreviousDiskName);
|
||||
}
|
||||
if ((archiveHeader.Flags & NHeader::NArchive::NFlags::kNextCabinet) != 0)
|
||||
{
|
||||
SafeReadName(inBuffer, inArchiveInfo.NextCabinetName);
|
||||
SafeReadName(inBuffer, inArchiveInfo.NextDiskName);
|
||||
}
|
||||
foldersStartPosition += inBuffer.GetProcessedSize();
|
||||
RINOK(inStream->Seek(foldersStartPosition, STREAM_SEEK_SET, NULL));
|
||||
}
|
||||
|
||||
if (progressVirt != NULL)
|
||||
{
|
||||
UINT64 numFiles = archiveHeader.NumFiles;
|
||||
RINOK(progressVirt->SetTotal(&numFiles));
|
||||
}
|
||||
folders.Clear();
|
||||
for(int i = 0; i < archiveHeader.NumFolders; i++)
|
||||
{
|
||||
if (progressVirt != NULL)
|
||||
{
|
||||
UINT64 numFiles = 0;
|
||||
RINOK(progressVirt->SetCompleted(&numFiles));
|
||||
}
|
||||
NHeader::CFolder folder;
|
||||
RINOK(SafeRead(inStream, &folder, sizeof(folder)));
|
||||
if (inArchiveInfo.ReserveBlockPresent())
|
||||
{
|
||||
RINOK(inStream->Seek(
|
||||
inArchiveInfo.PerDataSizes.PerFolderAreaSize, STREAM_SEEK_CUR, NULL));
|
||||
}
|
||||
folder.DataStart += (UINT32)startPosition;
|
||||
folders.Add(folder);
|
||||
}
|
||||
|
||||
RINOK(inStream->Seek(startPosition + archiveHeader.FileOffset,
|
||||
STREAM_SEEK_SET, NULL));
|
||||
|
||||
CInBuffer inBuffer;
|
||||
inBuffer.Init(inStream);
|
||||
files.Clear();
|
||||
if (progressVirt != NULL)
|
||||
{
|
||||
UINT64 numFiles = files.Size();
|
||||
RINOK(progressVirt->SetCompleted(&numFiles));
|
||||
}
|
||||
for(i = 0; i < archiveHeader.NumFiles; i++)
|
||||
{
|
||||
NHeader::CFile fileHeader;
|
||||
SafeInByteRead(inBuffer, &fileHeader, sizeof(fileHeader));
|
||||
CItem item;
|
||||
item.UnPackSize = fileHeader.UnPackSize;
|
||||
item.UnPackOffset = fileHeader.UnPackOffset;
|
||||
item.FolderIndex = fileHeader.FolderIndex;
|
||||
item.Time = ((UINT32(fileHeader.PureDate) << 16)) | fileHeader.PureTime;
|
||||
item.Attributes = fileHeader.Attributes;
|
||||
SafeReadName(inBuffer, item.Name);
|
||||
files.Add(item);
|
||||
if (progressVirt != NULL)
|
||||
{
|
||||
UINT64 numFiles = files.Size();
|
||||
RINOK(progressVirt->SetCompleted(&numFiles));
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}}
|
||||
68
7zip/Archive/Cab/CabIn.h
Executable file
68
7zip/Archive/Cab/CabIn.h
Executable file
@@ -0,0 +1,68 @@
|
||||
// Archive/CabIn.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARCHIVE_CAB_IN_H
|
||||
#define __ARCHIVE_CAB_IN_H
|
||||
|
||||
#include "../../IStream.h"
|
||||
#include "CabHeader.h"
|
||||
#include "CabItem.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NCab {
|
||||
|
||||
class CInArchiveException
|
||||
{
|
||||
public:
|
||||
enum CCauseType
|
||||
{
|
||||
kUnexpectedEndOfArchive = 0,
|
||||
kIncorrectArchive,
|
||||
kUnsupported,
|
||||
} Cause;
|
||||
CInArchiveException(CCauseType cause) : Cause(cause) {}
|
||||
};
|
||||
|
||||
class CInArchiveInfo
|
||||
{
|
||||
public:
|
||||
UINT32 Size; /* size of this cabinet file in bytes */
|
||||
BYTE VersionMinor; /* cabinet file format version, minor */
|
||||
BYTE VersionMajor; /* cabinet file format version, major */
|
||||
UINT16 NumFolders; /* number of CFFOLDER entries in this cabinet */
|
||||
UINT16 NumFiles; /* number of CFFILE entries in this cabinet */
|
||||
UINT16 Flags; /* cabinet file option indicators */
|
||||
UINT16 SetID; /* must be the same for all cabinets in a set */
|
||||
UINT16 CabinetNumber; /* number of this cabinet file in a set */
|
||||
|
||||
bool ReserveBlockPresent() const { return (Flags & NHeader::NArchive::NFlags::kReservePresent) != 0; }
|
||||
NHeader::NArchive::CPerDataSizes PerDataSizes;
|
||||
|
||||
AString PreviousCabinetName;
|
||||
AString PreviousDiskName;
|
||||
AString NextCabinetName;
|
||||
AString NextDiskName;
|
||||
};
|
||||
|
||||
class CProgressVirt
|
||||
{
|
||||
public:
|
||||
STDMETHOD(SetTotal)(const UINT64 *numFiles) PURE;
|
||||
STDMETHOD(SetCompleted)(const UINT64 *numFiles) PURE;
|
||||
};
|
||||
|
||||
class CInArchive
|
||||
{
|
||||
public:
|
||||
HRESULT Open(IInStream *inStream,
|
||||
const UINT64 *searchHeaderSizeLimit,
|
||||
CInArchiveInfo &inArchiveInfo,
|
||||
CObjectVector<NHeader::CFolder> &folders,
|
||||
CObjectVector<CItem> &aFiles,
|
||||
CProgressVirt *aProgressVirt);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
153
7zip/Archive/Cab/CabInBuffer.cpp
Executable file
153
7zip/Archive/Cab/CabInBuffer.cpp
Executable file
@@ -0,0 +1,153 @@
|
||||
// Archive/CabInBuffer.cpp
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "Common/Types.h"
|
||||
#include "Common/MyCom.h"
|
||||
#include "Windows/Defs.h"
|
||||
#include "CabInBuffer.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NCab {
|
||||
|
||||
#pragma pack(push, PragmaCabDataHeader)
|
||||
#pragma pack(push, 1)
|
||||
|
||||
struct CDataBlockHeader
|
||||
{
|
||||
UINT32 CheckSum; /* checksum of this CFDATA entry */
|
||||
UINT16 PackSize; /* number of compressed bytes in this block */
|
||||
UINT16 UnPackSize; /* number of uncompressed bytes in this block */
|
||||
// BYTE abReserve[]; /* (optional) per-datablock reserved area */
|
||||
// BYTE ab[cbData]; /* compressed data bytes */
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
#pragma pack(pop, PragmaCabDataHeader)
|
||||
|
||||
CInBuffer::CInBuffer(UINT32 bufferSize):
|
||||
m_BufferSize(bufferSize),
|
||||
m_Stream(0)
|
||||
{
|
||||
m_Buffer = new BYTE[m_BufferSize];
|
||||
}
|
||||
|
||||
CInBuffer::~CInBuffer()
|
||||
{
|
||||
delete []m_Buffer;
|
||||
// ReleaseStream();
|
||||
}
|
||||
|
||||
void CInBuffer::Init(ISequentialInStream *inStream, BYTE reservedSize, UINT32 numBlocks)
|
||||
{
|
||||
m_ReservedSize = reservedSize;
|
||||
m_NumBlocks = numBlocks;
|
||||
m_CurrentBlockIndex = 0;
|
||||
// ReleaseStream();
|
||||
m_Stream = inStream;
|
||||
// m_Stream->AddRef();
|
||||
m_ProcessedSize = 0;
|
||||
m_Pos = 0;
|
||||
m_NumReadBytesInBuffer = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
void CInBuffer::ReleaseStream()
|
||||
{
|
||||
if(m_Stream != 0)
|
||||
{
|
||||
m_Stream->Release();
|
||||
m_Stream = 0;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
class CCheckSum
|
||||
{
|
||||
UINT32 m_Value;
|
||||
public:
|
||||
CCheckSum(): m_Value(0){};
|
||||
void Init() { m_Value = 0; }
|
||||
void Update(const void *data, UINT32 size);
|
||||
UINT32 GetResult() const { return m_Value; }
|
||||
};
|
||||
|
||||
void CCheckSum::Update(const void *data, UINT32 size)
|
||||
{
|
||||
UINT32 checkSum = m_Value;
|
||||
const BYTE *aDataPointer = (const BYTE *)data;
|
||||
int numUINT32Words = size / 4; // Number of ULONGs
|
||||
|
||||
// dataPointer += numUINT32Words * 4;
|
||||
|
||||
UINT32 temp;
|
||||
const UINT32 *aDataPointer32 = (const UINT32 *)data;
|
||||
while (numUINT32Words-- > 0)
|
||||
{
|
||||
// temp ^= *aDataPointer32++;
|
||||
temp = *aDataPointer++; // Get low-order byte
|
||||
temp |= (((ULONG)(*aDataPointer++)) << 8); // Add 2nd byte
|
||||
temp |= (((ULONG)(*aDataPointer++)) << 16); // Add 3nd byte
|
||||
temp |= (((ULONG)(*aDataPointer++)) << 24); // Add 4th byte
|
||||
checkSum ^= temp; // Update checksum
|
||||
}
|
||||
|
||||
temp = 0;
|
||||
switch (size % 4)
|
||||
{
|
||||
case 3:
|
||||
temp |= (((ULONG)(*aDataPointer++)) << 16); // Add 3nd byte
|
||||
case 2:
|
||||
temp |= (((ULONG)(*aDataPointer++)) << 8); // Add 2nd byte
|
||||
case 1:
|
||||
temp |= *aDataPointer++; // Get low-order byte
|
||||
default:
|
||||
break;
|
||||
}
|
||||
checkSum ^= temp;
|
||||
m_Value = checkSum;
|
||||
}
|
||||
HRESULT CInBuffer::ReadBlock(UINT32 &uncompressedSize, bool &dataAreCorrect)
|
||||
{
|
||||
if (m_CurrentBlockIndex >= m_NumBlocks)
|
||||
throw "there is no more data blocks";
|
||||
|
||||
m_ProcessedSize += m_NumReadBytesInBuffer;
|
||||
|
||||
CDataBlockHeader dataBlockHeader;
|
||||
UINT32 numProcessedBytes;
|
||||
RINOK(m_Stream->Read(&dataBlockHeader, sizeof(dataBlockHeader), &numProcessedBytes));
|
||||
if (numProcessedBytes != sizeof(dataBlockHeader))
|
||||
throw "bad block";
|
||||
|
||||
if (m_ReservedSize != 0)
|
||||
{
|
||||
BYTE reservedArea[256];
|
||||
RINOK(m_Stream->Read(reservedArea, m_ReservedSize, &numProcessedBytes));
|
||||
if (numProcessedBytes != m_ReservedSize)
|
||||
throw "bad block";
|
||||
}
|
||||
|
||||
RINOK(m_Stream->Read(m_Buffer, dataBlockHeader.PackSize, &m_NumReadBytesInBuffer));
|
||||
if (m_NumReadBytesInBuffer != dataBlockHeader.PackSize)
|
||||
throw "bad block";
|
||||
|
||||
if (dataBlockHeader.CheckSum == 0)
|
||||
dataAreCorrect = true;
|
||||
{
|
||||
CCheckSum checkSum;
|
||||
checkSum.Update(m_Buffer, dataBlockHeader.PackSize);
|
||||
checkSum.Update(&dataBlockHeader.PackSize,
|
||||
sizeof(dataBlockHeader) - sizeof(dataBlockHeader.CheckSum));
|
||||
dataAreCorrect = (checkSum.GetResult() == dataBlockHeader.CheckSum);
|
||||
}
|
||||
|
||||
m_Pos = 0;
|
||||
uncompressedSize = dataBlockHeader.UnPackSize;
|
||||
|
||||
m_CurrentBlockIndex++;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
62
7zip/Archive/Cab/CabInBuffer.h
Executable file
62
7zip/Archive/Cab/CabInBuffer.h
Executable file
@@ -0,0 +1,62 @@
|
||||
// Archive/CabInBuffer.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARCHIVE_CAB_INBUFFER_H
|
||||
#define __ARCHIVE_CAB_INBUFFER_H
|
||||
|
||||
#include "../../IStream.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NCab {
|
||||
|
||||
class CInBuffer
|
||||
{
|
||||
UINT64 m_ProcessedSize;
|
||||
UINT32 m_Pos;
|
||||
UINT32 m_NumReadBytesInBuffer;
|
||||
BYTE *m_Buffer;
|
||||
ISequentialInStream *m_Stream;
|
||||
UINT32 m_BufferSize;
|
||||
|
||||
UINT32 m_NumBlocks;
|
||||
UINT32 m_CurrentBlockIndex;
|
||||
UINT32 m_ReservedSize;
|
||||
|
||||
public:
|
||||
CInBuffer(UINT32 bufferSize = 0x20000);
|
||||
~CInBuffer();
|
||||
|
||||
void Init(ISequentialInStream *inStream, BYTE reservedSize, UINT32 numBlocks);
|
||||
// void ReleaseStream();
|
||||
|
||||
bool ReadByte(BYTE &b)
|
||||
{
|
||||
if(m_Pos >= m_NumReadBytesInBuffer)
|
||||
return false;
|
||||
b = m_Buffer[m_Pos++];
|
||||
return true;
|
||||
}
|
||||
BYTE ReadByte()
|
||||
{
|
||||
if(m_Pos >= m_NumReadBytesInBuffer)
|
||||
return 0;
|
||||
return m_Buffer[m_Pos++];
|
||||
}
|
||||
/*
|
||||
void ReadBytes(void *data, UINT32 size, UINT32 &aProcessedSize)
|
||||
{
|
||||
BYTE *aDataPointer = (BYTE *)data;
|
||||
for(int i = 0; i < size; i++)
|
||||
if (!ReadByte(aDataPointer[i]))
|
||||
break;
|
||||
aProcessedSize = i;
|
||||
}
|
||||
*/
|
||||
HRESULT ReadBlock(UINT32 &uncompressedSize, bool &dataAreCorrect);
|
||||
UINT64 GetProcessedSize() const { return m_ProcessedSize + m_Pos; }
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
33
7zip/Archive/Cab/CabItem.h
Executable file
33
7zip/Archive/Cab/CabItem.h
Executable file
@@ -0,0 +1,33 @@
|
||||
// Archive/Cab/ItemInfo.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARCHIVE_RAR_ITEMINFO_H
|
||||
#define __ARCHIVE_RAR_ITEMINFO_H
|
||||
|
||||
#include "Common/Types.h"
|
||||
#include "Common/String.h"
|
||||
#include "CabHeader.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NCab {
|
||||
|
||||
class CItem
|
||||
{
|
||||
public:
|
||||
UINT16 Flags;
|
||||
UINT64 UnPackSize;
|
||||
UINT32 UnPackOffset;
|
||||
UINT16 FolderIndex;
|
||||
UINT32 Time;
|
||||
UINT16 Attributes;
|
||||
UINT32 GetWinAttributes() const { return Attributes & (Attributes & ~NHeader::kFileNameIsUTFAttributeMask); }
|
||||
bool IsNameUTF() const { return (Attributes & NHeader::kFileNameIsUTFAttributeMask) != 0; }
|
||||
AString Name;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
66
7zip/Archive/Cab/DllExports.cpp
Executable file
66
7zip/Archive/Cab/DllExports.cpp
Executable file
@@ -0,0 +1,66 @@
|
||||
// DLLExports.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#define INITGUID
|
||||
|
||||
#include "Common/ComTry.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "CabHandler.h"
|
||||
#include "../../ICoder.h"
|
||||
|
||||
// {23170F69-40C1-278A-1000-000110060000}
|
||||
DEFINE_GUID(CLSID_CCabHandler,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x06, 0x00, 0x00);
|
||||
|
||||
extern "C"
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
STDAPI CreateObject(
|
||||
const GUID *classID,
|
||||
const GUID *interfaceID,
|
||||
void **outObject)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
*outObject = 0;
|
||||
if (*classID != CLSID_CCabHandler)
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
if (*interfaceID != IID_IInArchive)
|
||||
return E_NOINTERFACE;
|
||||
CMyComPtr<IInArchive> inArchive = (IInArchive *)new NArchive::NCab::CHandler;
|
||||
*outObject = inArchive.Detach();
|
||||
COM_TRY_END
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
switch(propID)
|
||||
{
|
||||
case NArchive::kName:
|
||||
propVariant = L"Cab";
|
||||
break;
|
||||
case NArchive::kClassID:
|
||||
{
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen(
|
||||
(const char *)&CLSID_CCabHandler, sizeof(GUID))) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
}
|
||||
case NArchive::kExtension:
|
||||
propVariant = L"cab";
|
||||
break;
|
||||
case NArchive::kUpdate:
|
||||
propVariant = false;
|
||||
break;
|
||||
case NArchive::kKeepName:
|
||||
propVariant = false;
|
||||
break;
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
112
7zip/Archive/Cab/LZXBitDecoder.h
Executable file
112
7zip/Archive/Cab/LZXBitDecoder.h
Executable file
@@ -0,0 +1,112 @@
|
||||
// Archive/Cab/LZXBitDecoder.h
|
||||
|
||||
#ifndef __ARCHIVE_CAB_LZXBITDECODER_H
|
||||
#define __ARCHIVE_CAB_LZXBITDECODER_H
|
||||
|
||||
#include "CabInBuffer.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NCab {
|
||||
namespace NLZX {
|
||||
namespace NBitStream {
|
||||
|
||||
const int kNumBigValueBits = 8 * 4;
|
||||
|
||||
const int kNumValueBits = 17;
|
||||
const int kBitDecoderValueMask = (1 << kNumValueBits) - 1;
|
||||
|
||||
class CDecoder
|
||||
{
|
||||
protected:
|
||||
CInBuffer m_Stream;
|
||||
UINT32 m_BitPos;
|
||||
UINT32 m_Value;
|
||||
public:
|
||||
void InitStream(ISequentialInStream *aStream, BYTE aReservedSize, UINT32 aNumBlocks)
|
||||
{
|
||||
m_Stream.Init(aStream, aReservedSize, aNumBlocks);
|
||||
}
|
||||
/*
|
||||
void ReleaseStream()
|
||||
{ m_Stream.ReleaseStream(); }
|
||||
*/
|
||||
UINT64 GetProcessedSize() const
|
||||
{ return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; }
|
||||
UINT32 GetBitPosition() const
|
||||
{ return UINT32(m_Stream.GetProcessedSize() * 8 - (kNumBigValueBits - m_BitPos)); }
|
||||
|
||||
void Init()
|
||||
{
|
||||
m_BitPos = kNumBigValueBits;
|
||||
Normalize();
|
||||
}
|
||||
|
||||
void Normalize()
|
||||
{
|
||||
for (;m_BitPos >= 16; m_BitPos -= 16)
|
||||
{
|
||||
BYTE aByte0 = m_Stream.ReadByte();
|
||||
BYTE aByte1 = m_Stream.ReadByte();
|
||||
m_Value = (m_Value << 8) | aByte1;
|
||||
m_Value = (m_Value << 8) | aByte0;
|
||||
}
|
||||
}
|
||||
|
||||
UINT32 GetValue(UINT32 aNumBits)
|
||||
{
|
||||
return ((m_Value >> ((32 - kNumValueBits) - m_BitPos)) & kBitDecoderValueMask) >>
|
||||
(kNumValueBits - aNumBits);
|
||||
}
|
||||
|
||||
void MovePos(UINT32 aNumBits)
|
||||
{
|
||||
m_BitPos += aNumBits;
|
||||
Normalize();
|
||||
}
|
||||
|
||||
UINT32 ReadBits(UINT32 aNumBits)
|
||||
{
|
||||
UINT32 aRes = GetValue(aNumBits);
|
||||
MovePos(aNumBits);
|
||||
return aRes;
|
||||
}
|
||||
UINT32 ReadBitsBig(UINT32 aNumBits)
|
||||
{
|
||||
UINT32 aNumBits0 = aNumBits / 2;
|
||||
UINT32 aNumBits1 = aNumBits - aNumBits0;
|
||||
UINT32 aRes = ReadBits(aNumBits0) << aNumBits1;
|
||||
return aRes + ReadBits(aNumBits1);
|
||||
}
|
||||
|
||||
BYTE DirectReadByte()
|
||||
{
|
||||
if (m_BitPos == kNumBigValueBits)
|
||||
return m_Stream.ReadByte();
|
||||
BYTE aRes;
|
||||
switch(m_BitPos)
|
||||
{
|
||||
case 0:
|
||||
aRes = BYTE(m_Value >> 16);
|
||||
break;
|
||||
case 8:
|
||||
aRes = BYTE(m_Value >> 24);
|
||||
break;
|
||||
case 16:
|
||||
aRes = BYTE(m_Value);
|
||||
break;
|
||||
case 24:
|
||||
aRes = BYTE(m_Value >> 8);
|
||||
break;
|
||||
}
|
||||
m_BitPos += 8;
|
||||
return aRes;
|
||||
}
|
||||
|
||||
HRESULT ReadBlock(UINT32 &anUncompressedSize, bool &aDataAreCorrect)
|
||||
{ return m_Stream.ReadBlock(anUncompressedSize, aDataAreCorrect); }
|
||||
};
|
||||
|
||||
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
112
7zip/Archive/Cab/LZXConst.h
Executable file
112
7zip/Archive/Cab/LZXConst.h
Executable file
@@ -0,0 +1,112 @@
|
||||
// Archive/Cab/LZXConst.h
|
||||
|
||||
#ifndef __ARCHIVE_CAB_LZXCONST_H
|
||||
#define __ARCHIVE_CAB_LZXCONST_H
|
||||
|
||||
#include "LZXExtConst.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NCab {
|
||||
namespace NLZX {
|
||||
|
||||
|
||||
namespace NBlockType
|
||||
{
|
||||
const int kNumBits = 3;
|
||||
enum EEnum
|
||||
{
|
||||
kVerbatim = 1,
|
||||
kAligned = 2,
|
||||
kUncompressed = 3
|
||||
};
|
||||
}
|
||||
|
||||
const int kUncompressedBlockSizeNumBits = 24;
|
||||
|
||||
const UINT32 kLevelTableSize = 20;
|
||||
|
||||
const UINT32 kNumBitsForPreTreeLevel = 4;
|
||||
|
||||
const int kLevelSymbolZeros = 17;
|
||||
const int kLevelSymbolZerosBig = 18;
|
||||
const int kLevelSymbolSame = 19;
|
||||
|
||||
const int kLevelSymbolZerosStartValue = 4;
|
||||
const int kLevelSymbolZerosNumBits = 4;
|
||||
|
||||
const int kLevelSymbolZerosBigStartValue = kLevelSymbolZerosStartValue +
|
||||
(1 << kLevelSymbolZerosNumBits);
|
||||
const int kLevelSymbolZerosBigNumBits = 5;
|
||||
|
||||
const int kNumBitsForAlignLevel = 3;
|
||||
|
||||
const int kLevelSymbolSameNumBits = 1;
|
||||
const int kLevelSymbolSameStartValue = 4;
|
||||
|
||||
// const UINT32 kMainTableSize = 256 + kNumPosLenSlots + 1;
|
||||
|
||||
/*
|
||||
const UINT32 kLenTableSize = 28;
|
||||
|
||||
const UINT32 kLenTableStart = kMainTableSize;
|
||||
const UINT32 kAlignTableStart = kLenTableStart + kLenTableSize;
|
||||
|
||||
const UINT32 kHeapTablesSizesSum = kMainTableSize + kLenTableSize + kAlignTableSize;
|
||||
|
||||
|
||||
const UINT32 kMaxTableSize = kHeapTablesSizesSum;
|
||||
|
||||
const UINT32 kTableDirectLevels = 16;
|
||||
const UINT32 kTableLevelRepNumber = kTableDirectLevels;
|
||||
const UINT32 kTableLevel0Number = kTableLevelRepNumber + 1;
|
||||
const UINT32 kTableLevel0Number2 = kTableLevel0Number + 1;
|
||||
|
||||
const UINT32 kLevelMask = 0xF;
|
||||
|
||||
const UINT32 kPosLenNumber = 256;
|
||||
const UINT32 kReadTableNumber = 256 + kNumPosLenSlots;
|
||||
|
||||
//const UINT32 kMatchNumber = kReadTableNumber + 1;
|
||||
|
||||
const BYTE kLenStart[kLenTableSize] =
|
||||
{0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224};
|
||||
const BYTE kLenDirectBits[kLenTableSize] =
|
||||
{0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5};
|
||||
*/
|
||||
|
||||
const UINT32 kDistStart[] =
|
||||
{ 0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,
|
||||
1536,2048,3072,4096,6144,8192,12288,16384,24576,32768,49152,65536,98304,131072,196608,
|
||||
0x40000,
|
||||
0x60000,
|
||||
0x80000,
|
||||
0xA0000,
|
||||
0xC0000,
|
||||
0xE0000,
|
||||
|
||||
0x100000,
|
||||
0x120000,
|
||||
0x140000,
|
||||
0x160000,
|
||||
0x180000,
|
||||
0x1A0000,
|
||||
0x1C0000,
|
||||
0x1E0000
|
||||
};
|
||||
const BYTE kDistDirectBits[] =
|
||||
{
|
||||
0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,
|
||||
17, 17, 17, 17, 17, 17,
|
||||
17, 17,17, 17, 17, 17, 17, 17
|
||||
};
|
||||
|
||||
/*
|
||||
const BYTE kLevelDirectBits[kLevelTableSize] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7};
|
||||
|
||||
const UINT32 kDistLimit2 = 0x101 - 1;
|
||||
*/
|
||||
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
311
7zip/Archive/Cab/LZXDecoder.cpp
Executable file
311
7zip/Archive/Cab/LZXDecoder.cpp
Executable file
@@ -0,0 +1,311 @@
|
||||
// Archive/Cab/LZXDecoder.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "LZXDecoder.h"
|
||||
|
||||
#include "LZXConst.h"
|
||||
#include "Common/Defs.h"
|
||||
#include "Windows/Defs.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NCab {
|
||||
namespace NLZX {
|
||||
|
||||
static const UINT32 kHistorySize = (1 << 21);
|
||||
|
||||
const int kMainTableSize = 256 + kNumPosSlotLenSlotSymbols;
|
||||
|
||||
CDecoder::CDecoder():
|
||||
m_MainDecoder(kMainTableSize),
|
||||
m_LenDecoder(kNumLenSymbols),
|
||||
m_AlignDecoder(kAlignTableSize),
|
||||
m_LevelDecoder(kLevelTableSize)
|
||||
{
|
||||
m_OutWindowStream.Create(kHistorySize);
|
||||
m_i86TranslationOutStreamSpec = new Ci86TranslationOutStream;
|
||||
m_i86TranslationOutStream = m_i86TranslationOutStreamSpec;
|
||||
}
|
||||
|
||||
void CDecoder::ReleaseStreams()
|
||||
{
|
||||
// m_OutWindowStream.ReleaseStream();
|
||||
// m_InBitStream.ReleaseStream();
|
||||
m_i86TranslationOutStreamSpec->ReleaseStream();
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::Flush()
|
||||
{
|
||||
RINOK(m_OutWindowStream.Flush());
|
||||
return m_i86TranslationOutStreamSpec->Flush();
|
||||
}
|
||||
|
||||
void CDecoder::ReadTable(BYTE *lastLevels, BYTE *newLevels, UINT32 numSymbols)
|
||||
{
|
||||
BYTE levelLevels[kLevelTableSize];
|
||||
UINT32 i;
|
||||
for (i = 0; i < kLevelTableSize; i++)
|
||||
levelLevels[i] = BYTE(m_InBitStream.ReadBits(kNumBitsForPreTreeLevel));
|
||||
m_LevelDecoder.SetCodeLengths(levelLevels);
|
||||
for (i = 0; i < numSymbols;)
|
||||
{
|
||||
UINT32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream);
|
||||
if (number <= kNumHuffmanBits)
|
||||
newLevels[i++] = BYTE((17 + lastLevels[i] - number) % (kNumHuffmanBits + 1));
|
||||
else if (number == kLevelSymbolZeros || number == kLevelSymbolZerosBig)
|
||||
{
|
||||
int num;
|
||||
if (number == kLevelSymbolZeros)
|
||||
num = kLevelSymbolZerosStartValue +
|
||||
m_InBitStream.ReadBits(kLevelSymbolZerosNumBits);
|
||||
else
|
||||
num = kLevelSymbolZerosBigStartValue +
|
||||
m_InBitStream.ReadBits(kLevelSymbolZerosBigNumBits);
|
||||
for (;num > 0 && i < numSymbols; num--, i++)
|
||||
newLevels[i] = 0;
|
||||
}
|
||||
else if (number == kLevelSymbolSame)
|
||||
{
|
||||
int num = kLevelSymbolSameStartValue + m_InBitStream.ReadBits(kLevelSymbolSameNumBits);
|
||||
UINT32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream);
|
||||
if (number > kNumHuffmanBits)
|
||||
throw "bad data";
|
||||
BYTE symbol = BYTE((17 + lastLevels[i] - number) % (kNumHuffmanBits + 1));
|
||||
for (; num > 0 && i < numSymbols; num--, i++)
|
||||
newLevels[i] = symbol;
|
||||
}
|
||||
else
|
||||
throw "bad data";
|
||||
}
|
||||
|
||||
memmove(lastLevels, newLevels, numSymbols);
|
||||
}
|
||||
|
||||
void CDecoder::ReadTables(void)
|
||||
{
|
||||
int blockType = m_InBitStream.ReadBits(NBlockType::kNumBits);
|
||||
|
||||
if (blockType != NBlockType::kVerbatim && blockType != NBlockType::kAligned &&
|
||||
blockType != NBlockType::kUncompressed)
|
||||
throw "bad data";
|
||||
|
||||
m_UnCompressedBlockSize = m_InBitStream.ReadBitsBig(kUncompressedBlockSizeNumBits);
|
||||
|
||||
if (blockType == NBlockType::kUncompressed)
|
||||
{
|
||||
m_UncompressedBlock = true;
|
||||
UINT32 bitPos = m_InBitStream.GetBitPosition() % 16;
|
||||
m_InBitStream.ReadBits(16 - bitPos);
|
||||
for (int i = 0; i < kNumRepDistances; i++)
|
||||
{
|
||||
m_RepDistances[i] = 0;
|
||||
for (int j = 0; j < 4; j++)
|
||||
m_RepDistances[i] |= (m_InBitStream.DirectReadByte()) << (8 * j);
|
||||
m_RepDistances[i]--;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
m_UncompressedBlock = false;
|
||||
|
||||
m_AlignIsUsed = (blockType == NBlockType::kAligned);
|
||||
|
||||
BYTE newLevels[kMaxTableSize];
|
||||
|
||||
if (m_AlignIsUsed)
|
||||
{
|
||||
for(int i = 0; i < kAlignTableSize; i++)
|
||||
newLevels[i] = m_InBitStream.ReadBits(kNumBitsForAlignLevel);
|
||||
m_AlignDecoder.SetCodeLengths(newLevels);
|
||||
}
|
||||
|
||||
ReadTable(m_LastByteLevels, newLevels, 256);
|
||||
ReadTable(m_LastPosLenLevels, newLevels + 256, m_NumPosLenSlots);
|
||||
for (int i = m_NumPosLenSlots; i < kNumPosSlotLenSlotSymbols; i++)
|
||||
newLevels[256 + i] = 0;
|
||||
m_MainDecoder.SetCodeLengths(newLevels);
|
||||
|
||||
ReadTable(m_LastLenLevels, newLevels, kNumLenSymbols);
|
||||
m_LenDecoder.SetCodeLengths(newLevels);
|
||||
|
||||
}
|
||||
|
||||
class CDecoderFlusher
|
||||
{
|
||||
CDecoder *m_Decoder;
|
||||
public:
|
||||
CDecoderFlusher(CDecoder *decoder): m_Decoder(decoder) {}
|
||||
~CDecoderFlusher()
|
||||
{
|
||||
m_Decoder->Flush();
|
||||
m_Decoder->ReleaseStreams();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void CDecoder::ClearPrevLeveles()
|
||||
{
|
||||
memset(m_LastByteLevels, 0, 256);
|
||||
memset(m_LastPosLenLevels, 0, kNumPosSlotLenSlotSymbols);
|
||||
memset(m_LastLenLevels, 0, kNumLenSymbols);
|
||||
};
|
||||
|
||||
|
||||
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
if (outSize == NULL)
|
||||
return E_INVALIDARG;
|
||||
UINT64 size = *outSize;
|
||||
|
||||
|
||||
m_OutWindowStream.Init(m_i86TranslationOutStream);
|
||||
m_InBitStream.InitStream(inStream, m_ReservedSize, m_NumInDataBlocks);
|
||||
|
||||
CDecoderFlusher flusher(this);
|
||||
|
||||
UINT32 uncompressedCFDataBlockSize;
|
||||
bool dataAreCorrect;
|
||||
RINOK(m_InBitStream.ReadBlock(uncompressedCFDataBlockSize, dataAreCorrect));
|
||||
if (!dataAreCorrect)
|
||||
{
|
||||
throw "Data Error";
|
||||
}
|
||||
UINT32 uncompressedCFDataCurrentValue = 0;
|
||||
m_InBitStream.Init();
|
||||
|
||||
ClearPrevLeveles();
|
||||
|
||||
if (m_InBitStream.ReadBits(1) == 0)
|
||||
m_i86TranslationOutStreamSpec->Init(outStream, false, 0);
|
||||
else
|
||||
{
|
||||
UINT32 i86TranslationSize = m_InBitStream.ReadBits(16) << 16;
|
||||
i86TranslationSize |= m_InBitStream.ReadBits(16);
|
||||
m_i86TranslationOutStreamSpec->Init(outStream, true , i86TranslationSize);
|
||||
}
|
||||
|
||||
for(int i = 0 ; i < kNumRepDistances; i++)
|
||||
m_RepDistances[i] = 0;
|
||||
|
||||
UINT64 nowPos64 = 0;
|
||||
while(nowPos64 < size)
|
||||
{
|
||||
if (uncompressedCFDataCurrentValue == uncompressedCFDataBlockSize)
|
||||
{
|
||||
bool dataAreCorrect;
|
||||
RINOK(m_InBitStream.ReadBlock(uncompressedCFDataBlockSize, dataAreCorrect));
|
||||
if (!dataAreCorrect)
|
||||
{
|
||||
throw "Data Error";
|
||||
}
|
||||
m_InBitStream.Init();
|
||||
uncompressedCFDataCurrentValue = 0;
|
||||
}
|
||||
ReadTables();
|
||||
UINT32 nowPos = 0;
|
||||
UINT32 next = (UINT32)MyMin((UINT64)m_UnCompressedBlockSize, size - nowPos64);
|
||||
if (m_UncompressedBlock)
|
||||
{
|
||||
while(nowPos < next)
|
||||
{
|
||||
m_OutWindowStream.PutOneByte(m_InBitStream.DirectReadByte());
|
||||
nowPos++;
|
||||
uncompressedCFDataCurrentValue++;
|
||||
if (uncompressedCFDataCurrentValue == uncompressedCFDataBlockSize)
|
||||
{
|
||||
bool dataAreCorrect;
|
||||
RINOK(m_InBitStream.ReadBlock(uncompressedCFDataBlockSize, dataAreCorrect));
|
||||
if (!dataAreCorrect)
|
||||
{
|
||||
throw "Data Error";
|
||||
}
|
||||
// m_InBitStream.Init();
|
||||
uncompressedCFDataCurrentValue = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
int bitPos = m_InBitStream.GetBitPosition() % 16;
|
||||
if (bitPos == 8)
|
||||
m_InBitStream.DirectReadByte();
|
||||
m_InBitStream.Normalize();
|
||||
}
|
||||
else for (;nowPos < next;)
|
||||
{
|
||||
if (uncompressedCFDataCurrentValue == uncompressedCFDataBlockSize)
|
||||
{
|
||||
bool dataAreCorrect;
|
||||
RINOK(m_InBitStream.ReadBlock(uncompressedCFDataBlockSize, dataAreCorrect));
|
||||
if (!dataAreCorrect)
|
||||
{
|
||||
throw "Data Error";
|
||||
}
|
||||
m_InBitStream.Init();
|
||||
uncompressedCFDataCurrentValue = 0;
|
||||
}
|
||||
UINT32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream);
|
||||
if (number < 256)
|
||||
{
|
||||
m_OutWindowStream.PutOneByte(BYTE(number));
|
||||
nowPos++;
|
||||
uncompressedCFDataCurrentValue++;
|
||||
// continue;
|
||||
}
|
||||
else if (number < 256 + m_NumPosLenSlots)
|
||||
{
|
||||
UINT32 posLenSlot = number - 256;
|
||||
UINT32 posSlot = posLenSlot / kNumLenSlots;
|
||||
UINT32 lenSlot = posLenSlot % kNumLenSlots;
|
||||
UINT32 length = 2 + lenSlot;
|
||||
if (lenSlot == kNumLenSlots - 1)
|
||||
length += m_LenDecoder.DecodeSymbol(&m_InBitStream);
|
||||
|
||||
if (posSlot < kNumRepDistances)
|
||||
{
|
||||
UINT32 distance = m_RepDistances[posSlot];
|
||||
m_OutWindowStream.CopyBackBlock(distance, length);
|
||||
if (posSlot != 0)
|
||||
{
|
||||
m_RepDistances[posSlot] = m_RepDistances[0];
|
||||
m_RepDistances[0] = distance;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT32 pos = kDistStart[posSlot];
|
||||
UINT32 posDirectBits = kDistDirectBits[posSlot];
|
||||
if (m_AlignIsUsed && posDirectBits >= kNumAlignBits)
|
||||
{
|
||||
pos += (m_InBitStream.ReadBits(posDirectBits - kNumAlignBits) << kNumAlignBits);
|
||||
pos += m_AlignDecoder.DecodeSymbol(&m_InBitStream);
|
||||
}
|
||||
else
|
||||
pos += m_InBitStream.ReadBits(posDirectBits);
|
||||
UINT32 distance = pos - kNumRepDistances;
|
||||
if (distance >= nowPos64 + nowPos)
|
||||
throw 777123;
|
||||
m_OutWindowStream.CopyBackBlock(distance, length);
|
||||
m_RepDistances[2] = m_RepDistances[1];
|
||||
m_RepDistances[1] = m_RepDistances[0];
|
||||
m_RepDistances[0] = distance;
|
||||
}
|
||||
nowPos += length;
|
||||
uncompressedCFDataCurrentValue += length;
|
||||
}
|
||||
else
|
||||
throw 98112823;
|
||||
}
|
||||
if (progress != NULL)
|
||||
{
|
||||
UINT64 inSize = m_InBitStream.GetProcessedSize();
|
||||
UINT64 outSize = nowPos64 + nowPos;
|
||||
RINOK(progress->SetRatioInfo(&inSize, &outSize));
|
||||
}
|
||||
nowPos64 += nowPos;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}}}
|
||||
98
7zip/Archive/Cab/LZXDecoder.h
Executable file
98
7zip/Archive/Cab/LZXDecoder.h
Executable file
@@ -0,0 +1,98 @@
|
||||
// Archive/Cab/LZXDecoder.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARCHIVE_CAB_LZXDECODER_H
|
||||
#define __ARCHIVE_CAB_LZXDECODER_H
|
||||
|
||||
#include "../../ICoder.h"
|
||||
|
||||
#include "../../Compress/Huffman/HuffmanDecoder.h"
|
||||
#include "../../Compress/LZ/LZOutWindow.h"
|
||||
|
||||
#include "LZXExtConst.h"
|
||||
#include "LZXBitDecoder.h"
|
||||
|
||||
#include "LZXi86Converter.h"
|
||||
|
||||
// #include "../../../Projects/CompressInterface/CompressInterface.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NCab {
|
||||
namespace NLZX {
|
||||
|
||||
typedef NCompress::NHuffman::CDecoder<kNumHuffmanBits> CMSBFHuffmanDecoder;
|
||||
|
||||
class CDecoder :
|
||||
public ICompressCoder,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
CLZOutWindow m_OutWindowStream;
|
||||
NBitStream::CDecoder m_InBitStream;
|
||||
|
||||
CMSBFHuffmanDecoder m_MainDecoder;
|
||||
CMSBFHuffmanDecoder m_LenDecoder; // for matches with repeated offsets
|
||||
CMSBFHuffmanDecoder m_AlignDecoder; // for matches with repeated offsets
|
||||
CMSBFHuffmanDecoder m_LevelDecoder; // table for decoding other tables;
|
||||
|
||||
UINT32 m_RepDistances[kNumRepDistances];
|
||||
|
||||
BYTE m_LastByteLevels[256];
|
||||
BYTE m_LastPosLenLevels[kNumPosSlotLenSlotSymbols];
|
||||
BYTE m_LastLenLevels[kNumLenSymbols];
|
||||
|
||||
UINT32 m_DictionarySizePowerOf2;
|
||||
UINT32 m_NumPosSlots;
|
||||
UINT32 m_NumPosLenSlots;
|
||||
|
||||
// bool m_i86PreprocessingUsed;
|
||||
// UINT32 m_i86TranslationSize;
|
||||
|
||||
bool m_UncompressedBlock;
|
||||
bool m_AlignIsUsed;
|
||||
|
||||
UINT32 m_UnCompressedBlockSize;
|
||||
|
||||
Ci86TranslationOutStream *m_i86TranslationOutStreamSpec;
|
||||
CMyComPtr<ISequentialOutStream> m_i86TranslationOutStream;
|
||||
|
||||
BYTE m_ReservedSize;
|
||||
UINT32 m_NumInDataBlocks;
|
||||
|
||||
void ReadTable(BYTE *lastLevels, BYTE *newLevels, UINT32 numSymbols);
|
||||
void ReadTables();
|
||||
void ClearPrevLeveles();
|
||||
|
||||
public:
|
||||
CDecoder();
|
||||
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
void ReleaseStreams();
|
||||
STDMETHOD(Flush)();
|
||||
|
||||
// ICompressCoder interface
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
void SetParams(BYTE reservedSize, UINT32 numInDataBlocks,
|
||||
UINT32 dictionarySizePowerOf2)
|
||||
{
|
||||
m_ReservedSize = reservedSize;
|
||||
m_NumInDataBlocks = numInDataBlocks;
|
||||
m_DictionarySizePowerOf2 = dictionarySizePowerOf2;
|
||||
if (dictionarySizePowerOf2 < 20)
|
||||
m_NumPosSlots = 30 + (dictionarySizePowerOf2 - 15) * 2;
|
||||
else if (dictionarySizePowerOf2 == 20)
|
||||
m_NumPosSlots = 42;
|
||||
else
|
||||
m_NumPosSlots = 50;
|
||||
m_NumPosLenSlots = m_NumPosSlots * kNumLenSlots;
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
31
7zip/Archive/Cab/LZXExtConst.h
Executable file
31
7zip/Archive/Cab/LZXExtConst.h
Executable file
@@ -0,0 +1,31 @@
|
||||
// Archive/Cab/LZXExtConst.h
|
||||
|
||||
#ifndef __ARCHIVE_CAB_LZXEXTCONST_H
|
||||
#define __ARCHIVE_CAB_LZXEXTCONST_H
|
||||
|
||||
namespace NArchive {
|
||||
namespace NCab {
|
||||
namespace NLZX {
|
||||
|
||||
const UINT32 kNumRepDistances = 3;
|
||||
|
||||
const UINT32 kNumLenSlots = 8;
|
||||
const UINT32 kMatchMinLen = 2;
|
||||
const UINT32 kNumLenSymbols = 249;
|
||||
const UINT32 kMatchMaxLen = kMatchMinLen + (kNumLenSlots - 1) + kNumLenSymbols - 1;
|
||||
|
||||
const BYTE kNumAlignBits = 3;
|
||||
const UINT32 kAlignTableSize = 1 << kNumAlignBits;
|
||||
|
||||
const UINT32 kNumHuffmanBits = 16;
|
||||
|
||||
const int kNumPosSlotSymbols = 50;
|
||||
const int kNumPosSlotLenSlotSymbols = kNumPosSlotSymbols * kNumLenSlots;
|
||||
|
||||
const int kMaxTableSize = 256 + kNumPosSlotLenSlotSymbols;
|
||||
|
||||
|
||||
|
||||
}}}
|
||||
|
||||
#endif;
|
||||
124
7zip/Archive/Cab/LZXi86Converter.cpp
Executable file
124
7zip/Archive/Cab/LZXi86Converter.cpp
Executable file
@@ -0,0 +1,124 @@
|
||||
// Archive/Cab/LZXi86Converter.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/Defs.h"
|
||||
|
||||
#include "LZXi86Converter.h"
|
||||
#include "Windows/Defs.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NCab {
|
||||
namespace NLZX {
|
||||
|
||||
Ci86TranslationOutStream::Ci86TranslationOutStream():
|
||||
m_Pos(0)
|
||||
{
|
||||
}
|
||||
|
||||
Ci86TranslationOutStream::~Ci86TranslationOutStream()
|
||||
{
|
||||
Flush();
|
||||
}
|
||||
|
||||
void Ci86TranslationOutStream::Init(ISequentialOutStream *aStream,
|
||||
bool aTranslationMode, UINT32 aTranslationSize)
|
||||
{
|
||||
m_Stream = aStream;
|
||||
m_TranslationMode = aTranslationMode;
|
||||
m_TranslationSize = aTranslationSize;
|
||||
m_ProcessedSize = 0;
|
||||
m_Pos = 0;
|
||||
}
|
||||
|
||||
void Ci86TranslationOutStream::ReleaseStream()
|
||||
{
|
||||
m_Stream.Release();
|
||||
}
|
||||
|
||||
inline INT32 Ci86TranslationOutStream::ConvertAbsoluteToOffset(INT32 aPos, INT32 anAbsoluteValue)
|
||||
{
|
||||
}
|
||||
|
||||
static const int kResidue = 6 + 4;
|
||||
|
||||
void Ci86TranslationOutStream::MakeTranslation()
|
||||
{
|
||||
if (m_Pos <= kResidue)
|
||||
return;
|
||||
UINT32 aNumBytes = m_Pos - kResidue;
|
||||
for (UINT32 i = 0; i < aNumBytes;)
|
||||
{
|
||||
if (m_Buffer[i] == 0xE8)
|
||||
{
|
||||
i++;
|
||||
INT32 anAbsoluteValue = 0;
|
||||
for(int j = 0; j < 4; j++)
|
||||
anAbsoluteValue += UINT32(m_Buffer[i + j]) << (j * 8);
|
||||
|
||||
INT32 aPos = m_ProcessedSize + i - 1;
|
||||
UINT32 anOffset;
|
||||
if (anAbsoluteValue < -aPos || anAbsoluteValue >= INT32(m_TranslationSize))
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
anOffset = (anAbsoluteValue >= 0) ?
|
||||
anAbsoluteValue - aPos :
|
||||
anAbsoluteValue + m_TranslationSize;
|
||||
for(j = 0; j < 4; j++)
|
||||
{
|
||||
m_Buffer[i + j] = BYTE(anOffset & 0xFF);
|
||||
anOffset >>= 8;
|
||||
}
|
||||
}
|
||||
i += 4;
|
||||
}
|
||||
else
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
STDMETHODIMP Ci86TranslationOutStream::Write(const void *aData, UINT32 aSize, UINT32 *aProcessedSize)
|
||||
{
|
||||
if (!m_TranslationMode)
|
||||
return m_Stream->Write(aData, aSize, aProcessedSize);
|
||||
|
||||
UINT32 aProcessedSizeReal = 0;
|
||||
|
||||
while (aProcessedSizeReal < aSize)
|
||||
{
|
||||
UINT32 aWriteSize = MyMin(aSize - aProcessedSizeReal, kUncompressedBlockSize - m_Pos);
|
||||
memmove(m_Buffer + m_Pos, (const BYTE *)aData + aProcessedSizeReal, aWriteSize);
|
||||
m_Pos += aWriteSize;
|
||||
aProcessedSizeReal += aWriteSize;
|
||||
if (m_Pos == kUncompressedBlockSize)
|
||||
{
|
||||
RINOK(Flush());
|
||||
}
|
||||
}
|
||||
if (aProcessedSize != NULL)
|
||||
*aProcessedSize = aProcessedSizeReal;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP Ci86TranslationOutStream::WritePart(const void *aData, UINT32 aSize, UINT32 *aProcessedSize)
|
||||
{
|
||||
return Write(aData, aSize, aProcessedSize);
|
||||
}
|
||||
|
||||
HRESULT Ci86TranslationOutStream::Flush()
|
||||
{
|
||||
if (m_Pos == 0)
|
||||
return S_OK;
|
||||
MakeTranslation();
|
||||
RINOK(m_Stream->Write(m_Buffer, m_Pos, NULL));
|
||||
m_ProcessedSize += m_Pos;
|
||||
m_Pos = 0;
|
||||
m_TranslationMode = (m_ProcessedSize < (1 << 30));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
}}}
|
||||
|
||||
46
7zip/Archive/Cab/LZXi86Converter.h
Executable file
46
7zip/Archive/Cab/LZXi86Converter.h
Executable file
@@ -0,0 +1,46 @@
|
||||
// Archive/Cab/LZXi86Converter.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARCHIVE_CAB_LZXI86CONVERTER_H
|
||||
#define __ARCHIVE_CAB_LZXI86CONVERTER_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "../../IStream.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NCab {
|
||||
namespace NLZX {
|
||||
|
||||
const int kUncompressedBlockSize = 1 << 15;
|
||||
|
||||
class Ci86TranslationOutStream:
|
||||
public ISequentialOutStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
bool m_TranslationMode;
|
||||
CMyComPtr<ISequentialOutStream> m_Stream;
|
||||
UINT32 m_ProcessedSize;
|
||||
BYTE m_Buffer[kUncompressedBlockSize];
|
||||
UINT32 m_Pos;
|
||||
UINT32 m_TranslationSize;
|
||||
|
||||
INT32 ConvertAbsoluteToOffset(INT32 aPos, INT32 anAbsoluteValue);
|
||||
void MakeTranslation();
|
||||
public:
|
||||
Ci86TranslationOutStream();
|
||||
~Ci86TranslationOutStream();
|
||||
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
STDMETHOD(Write)(const void *aData, UINT32 aSize, UINT32 *aProcessedSize);
|
||||
STDMETHOD(WritePart)(const void *aData, UINT32 aSize, UINT32 *aProcessedSize);
|
||||
public:
|
||||
void Init(ISequentialOutStream *aStream, bool aTranslationMode, UINT32 aTranslationSize);
|
||||
HRESULT Flush();
|
||||
void ReleaseStream();
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
94
7zip/Archive/Cab/MSZipConst.h
Executable file
94
7zip/Archive/Cab/MSZipConst.h
Executable file
@@ -0,0 +1,94 @@
|
||||
// MSZipConst.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __MSZIP_CONST_H
|
||||
#define __MSZIP_CONST_H
|
||||
|
||||
#include "MSZipExtConst.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NCab {
|
||||
namespace NMSZip {
|
||||
|
||||
const UINT32 kLenTableSize = 29;
|
||||
|
||||
const UINT32 kStaticDistTableSize = 32;
|
||||
const UINT32 kStaticLenTableSize = 31;
|
||||
|
||||
const UINT32 kReadTableNumber = 0x100;
|
||||
const UINT32 kMatchNumber = kReadTableNumber + 1;
|
||||
|
||||
const UINT32 kMainTableSize = kMatchNumber + kLenTableSize; //298;
|
||||
const UINT32 kStaticMainTableSize = kMatchNumber + kStaticLenTableSize; //298;
|
||||
|
||||
const UINT32 kDistTableStart = kMainTableSize;
|
||||
|
||||
const UINT32 kHeapTablesSizesSum = kMainTableSize + kDistTableSize;
|
||||
|
||||
const UINT32 kLevelTableSize = 19;
|
||||
|
||||
const UINT32 kMaxTableSize = kHeapTablesSizesSum; // test it
|
||||
const UINT32 kStaticMaxTableSize = kStaticMainTableSize + kStaticDistTableSize;
|
||||
|
||||
const UINT32 kTableDirectLevels = 16;
|
||||
const UINT32 kTableLevelRepNumber = kTableDirectLevels;
|
||||
const UINT32 kTableLevel0Number = kTableLevelRepNumber + 1;
|
||||
const UINT32 kTableLevel0Number2 = kTableLevel0Number + 1;
|
||||
|
||||
const UINT32 kLevelMask = 0xF;
|
||||
|
||||
const BYTE kLenStart[kLenTableSize] = {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224, 255};
|
||||
const BYTE kLenDirectBits[kLenTableSize] = {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
|
||||
|
||||
|
||||
const UINT32 kDistStart[kDistTableSize] = {0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576};
|
||||
const BYTE kDistDirectBits[kDistTableSize] = {0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
|
||||
|
||||
const BYTE kLevelDirectBits[kLevelTableSize] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7};
|
||||
|
||||
const BYTE kCodeLengthAlphabetOrder[kLevelTableSize] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
|
||||
|
||||
const UINT32 kMatchMinLen = 3;
|
||||
const UINT32 kMatchMaxLen = kNumLenCombinations + kMatchMinLen - 1; //255 + 2; test it
|
||||
|
||||
const int kFinalBlockFieldSize = 1;
|
||||
|
||||
namespace NFinalBlockField
|
||||
{
|
||||
enum
|
||||
{
|
||||
kNotFinalBlock = 0,
|
||||
kFinalBlock = 1
|
||||
};
|
||||
}
|
||||
|
||||
const int kBlockTypeFieldSize = 2;
|
||||
|
||||
namespace NBlockType
|
||||
{
|
||||
enum
|
||||
{
|
||||
kStored = 0,
|
||||
kFixedHuffman = 1,
|
||||
kDynamicHuffman = 2,
|
||||
kReserved = 3
|
||||
};
|
||||
}
|
||||
|
||||
const UINT32 kDeflateNumberOfLengthCodesFieldSize = 5;
|
||||
const UINT32 kDeflateNumberOfDistanceCodesFieldSize = 5;
|
||||
const UINT32 kDeflateNumberOfLevelCodesFieldSize = 4;
|
||||
|
||||
const UINT32 kDeflateNumberOfLitLenCodesMin = 257;
|
||||
|
||||
const UINT32 kDeflateNumberOfDistanceCodesMin = 1;
|
||||
const UINT32 kDeflateNumberOfLevelCodesMin = 4;
|
||||
|
||||
const UINT32 kDeflateLevelCodeFieldSize = 3;
|
||||
|
||||
const UINT32 kDeflateStoredBlockLengthFieldSizeSize = 16;
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
269
7zip/Archive/Cab/MSZipDecoder.cpp
Executable file
269
7zip/Archive/Cab/MSZipDecoder.cpp
Executable file
@@ -0,0 +1,269 @@
|
||||
// Archive/Cab/MSZipDecoder.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "MSZipDecoder.h"
|
||||
#include "MSZipConst.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NCab {
|
||||
namespace NMSZip {
|
||||
|
||||
CDecoder::CDecoder():
|
||||
m_MainDecoder(kStaticMainTableSize),
|
||||
m_DistDecoder(kStaticDistTableSize),
|
||||
m_LevelDecoder(kLevelTableSize)
|
||||
{
|
||||
m_OutWindowStream.Create(kHistorySize);
|
||||
}
|
||||
|
||||
HRESULT CDecoder::Flush()
|
||||
{
|
||||
return m_OutWindowStream.Flush();
|
||||
}
|
||||
|
||||
/*
|
||||
void CDecoder::ReleaseStreams()
|
||||
{
|
||||
m_OutWindowStream.ReleaseStream();
|
||||
m_InBitStream.ReleaseStream();
|
||||
}
|
||||
*/
|
||||
|
||||
void CDecoder::DeCodeLevelTable(BYTE *newLevels, int numLevels)
|
||||
{
|
||||
int i = 0;
|
||||
while (i < numLevels)
|
||||
{
|
||||
UINT32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream);
|
||||
if (number < kTableDirectLevels)
|
||||
newLevels[i++] = BYTE(number);
|
||||
else
|
||||
{
|
||||
if (number == kTableLevelRepNumber)
|
||||
{
|
||||
int t = m_InBitStream.ReadBits(2) + 3;
|
||||
for (int reps = t; reps > 0 && i < numLevels ; reps--, i++)
|
||||
newLevels[i] = newLevels[i - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
int num;
|
||||
if (number == kTableLevel0Number)
|
||||
num = m_InBitStream.ReadBits(3) + 3;
|
||||
else
|
||||
num = m_InBitStream.ReadBits(7) + 11;
|
||||
for (;num > 0 && i < numLevels; num--)
|
||||
newLevels[i++] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CDecoder::ReadTables(void)
|
||||
{
|
||||
if(m_FinalBlock) // test it
|
||||
throw CDecoderException(CDecoderException::kData);
|
||||
|
||||
m_FinalBlock = (m_InBitStream.ReadBits(kFinalBlockFieldSize) == NFinalBlockField::kFinalBlock);
|
||||
|
||||
int blockType = m_InBitStream.ReadBits(kBlockTypeFieldSize);
|
||||
|
||||
switch(blockType)
|
||||
{
|
||||
case NBlockType::kStored:
|
||||
{
|
||||
m_StoredMode = true;
|
||||
UINT32 currentBitPosition = m_InBitStream.GetBitPosition();
|
||||
UINT32 numBitsForAlign = currentBitPosition > 0 ? (8 - currentBitPosition): 0;
|
||||
if (numBitsForAlign > 0)
|
||||
m_InBitStream.ReadBits(numBitsForAlign);
|
||||
m_StoredBlockSize = m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize);
|
||||
WORD onesComplementReverse = ~WORD(m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize));
|
||||
if (m_StoredBlockSize != onesComplementReverse)
|
||||
throw CDecoderException(CDecoderException::kData);
|
||||
break;
|
||||
}
|
||||
case NBlockType::kFixedHuffman:
|
||||
case NBlockType::kDynamicHuffman:
|
||||
{
|
||||
m_StoredMode = false;
|
||||
BYTE litLenLevels[kStaticMainTableSize];
|
||||
BYTE distLevels[kStaticDistTableSize];
|
||||
if (blockType == NBlockType::kFixedHuffman)
|
||||
{
|
||||
int i;
|
||||
|
||||
// Leteral / length levels
|
||||
for (i = 0; i < 144; i++)
|
||||
litLenLevels[i] = 8;
|
||||
for (; i < 256; i++)
|
||||
litLenLevels[i] = 9;
|
||||
for (; i < 280; i++)
|
||||
litLenLevels[i] = 7;
|
||||
for (; i < 288; i++) /* make a complete, but wrong code set */
|
||||
litLenLevels[i] = 8;
|
||||
|
||||
// Distance levels
|
||||
for (i = 0; i < kStaticDistTableSize; i++) // test it: infozip only use kDistTableSize
|
||||
distLevels[i] = 5;
|
||||
}
|
||||
else // in case when (blockType == kDeflateBlockTypeFixedHuffman)
|
||||
{
|
||||
int numLitLenLevels = m_InBitStream.ReadBits(kDeflateNumberOfLengthCodesFieldSize) +
|
||||
kDeflateNumberOfLitLenCodesMin;
|
||||
int numDistLevels = m_InBitStream.ReadBits(kDeflateNumberOfDistanceCodesFieldSize) +
|
||||
kDeflateNumberOfDistanceCodesMin;
|
||||
int numLevelCodes = m_InBitStream.ReadBits(kDeflateNumberOfLevelCodesFieldSize) +
|
||||
kDeflateNumberOfLevelCodesMin;
|
||||
|
||||
int numLevels;
|
||||
numLevels = kHeapTablesSizesSum;
|
||||
|
||||
BYTE levelLevels[kLevelTableSize];
|
||||
int i;
|
||||
for (i = 0; i < kLevelTableSize; i++)
|
||||
{
|
||||
int position = kCodeLengthAlphabetOrder[i];
|
||||
if(i < numLevelCodes)
|
||||
levelLevels[position] = BYTE(m_InBitStream.ReadBits(kDeflateLevelCodeFieldSize));
|
||||
else
|
||||
levelLevels[position] = 0;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
m_LevelDecoder.SetCodeLengths(levelLevels);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
throw CDecoderException(CDecoderException::kData);
|
||||
}
|
||||
|
||||
BYTE tmpLevels[kStaticMaxTableSize];
|
||||
DeCodeLevelTable(tmpLevels, numLitLenLevels + numDistLevels);
|
||||
|
||||
memmove(litLenLevels, tmpLevels, numLitLenLevels);
|
||||
memset(litLenLevels + numLitLenLevels, 0,
|
||||
kStaticMainTableSize - numLitLenLevels);
|
||||
|
||||
memmove(distLevels, tmpLevels + numLitLenLevels, numDistLevels);
|
||||
memset(distLevels + numDistLevels, 0, kStaticDistTableSize - numDistLevels);
|
||||
}
|
||||
try
|
||||
{
|
||||
m_MainDecoder.SetCodeLengths(litLenLevels);
|
||||
m_DistDecoder.SetCodeLengths(distLevels);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
throw CDecoderException(CDecoderException::kData);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw CDecoderException(CDecoderException::kData);
|
||||
}
|
||||
}
|
||||
|
||||
class CCoderReleaser
|
||||
{
|
||||
CDecoder *m_Coder;
|
||||
public:
|
||||
CCoderReleaser(CDecoder *aCoder): m_Coder(aCoder) {}
|
||||
~CCoderReleaser()
|
||||
{
|
||||
m_Coder->Flush();
|
||||
// m_Coder->ReleaseStreams();
|
||||
}
|
||||
};
|
||||
|
||||
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
if (outSize == NULL)
|
||||
return E_INVALIDARG;
|
||||
UINT64 size = *outSize;
|
||||
|
||||
m_OutWindowStream.Init(outStream, false);
|
||||
m_InBitStream.InitMain(inStream, m_ReservedSize, m_NumInDataBlocks);
|
||||
CCoderReleaser coderReleaser(this);
|
||||
|
||||
UINT64 nowPos = 0;
|
||||
while(nowPos < size)
|
||||
{
|
||||
if (progress != NULL)
|
||||
{
|
||||
UINT64 packSize = m_InBitStream.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(&packSize, &nowPos));
|
||||
}
|
||||
UINT32 uncompressedCFDataBlockSize;
|
||||
bool dataAreCorrect;
|
||||
RINOK(m_InBitStream.ReadBlock(uncompressedCFDataBlockSize, dataAreCorrect));
|
||||
if (!dataAreCorrect)
|
||||
{
|
||||
throw "Data Error";
|
||||
}
|
||||
m_InBitStream.Init();
|
||||
if (m_InBitStream.ReadBits(8) != 0x43)
|
||||
throw CDecoderException(CDecoderException::kData);
|
||||
if (m_InBitStream.ReadBits(8) != 0x4B)
|
||||
throw CDecoderException(CDecoderException::kData);
|
||||
UINT32 uncompressedCFDataCurrentValue = 0;
|
||||
m_FinalBlock = false;
|
||||
while (uncompressedCFDataCurrentValue < uncompressedCFDataBlockSize)
|
||||
{
|
||||
ReadTables();
|
||||
if(m_StoredMode)
|
||||
{
|
||||
for (UINT32 i = 0; i < m_StoredBlockSize; i++)
|
||||
m_OutWindowStream.PutOneByte(BYTE(m_InBitStream.ReadBits(8)));
|
||||
nowPos += m_StoredBlockSize;
|
||||
uncompressedCFDataCurrentValue += m_StoredBlockSize;
|
||||
continue;
|
||||
}
|
||||
while(true)
|
||||
{
|
||||
UINT32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream);
|
||||
|
||||
if (number < 256)
|
||||
{
|
||||
m_OutWindowStream.PutOneByte(BYTE(number));
|
||||
nowPos++;
|
||||
uncompressedCFDataCurrentValue++;
|
||||
continue;
|
||||
}
|
||||
else if (number >= kMatchNumber)
|
||||
{
|
||||
number -= kMatchNumber;
|
||||
UINT32 length = UINT32(kLenStart[number]) + kMatchMinLen;
|
||||
UINT32 numBits;
|
||||
if ((numBits = kLenDirectBits[number]) > 0)
|
||||
length += m_InBitStream.ReadBits(numBits);
|
||||
|
||||
number = m_DistDecoder.DecodeSymbol(&m_InBitStream);
|
||||
UINT32 distance = kDistStart[number] + m_InBitStream.ReadBits(kDistDirectBits[number]);
|
||||
/*
|
||||
if (distance >= nowPos)
|
||||
throw "data error";
|
||||
*/
|
||||
m_OutWindowStream.CopyBackBlock(distance, length);
|
||||
nowPos += length;
|
||||
uncompressedCFDataCurrentValue += length;
|
||||
}
|
||||
else if (number == kReadTableNumber)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
throw CDecoderException(CDecoderException::kData);
|
||||
}
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}}}
|
||||
88
7zip/Archive/Cab/MSZipDecoder.h
Executable file
88
7zip/Archive/Cab/MSZipDecoder.h
Executable file
@@ -0,0 +1,88 @@
|
||||
// Archive/Cab/MSZipDecoder.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARCHIVE_CAB_DECODER_H
|
||||
#define __ARCHIVE_CAB_DECODER_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "../../ICoder.h"
|
||||
#include "../../Common/LSBFDecoder.h"
|
||||
#include "../../Compress/Huffman/HuffmanDecoder.h"
|
||||
#include "../../Compress/LZ/LZOutWindow.h"
|
||||
|
||||
#include "CabInBuffer.h"
|
||||
#include "MSZipExtConst.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NCab {
|
||||
namespace NMSZip {
|
||||
|
||||
class CDecoderException
|
||||
{
|
||||
public:
|
||||
enum ECauseType
|
||||
{
|
||||
kData
|
||||
} m_Cause;
|
||||
CDecoderException(ECauseType aCause): m_Cause(aCause) {}
|
||||
};
|
||||
|
||||
class CMSZipBitDecoder: public NStream::NLSBF::CDecoder<NCab::CInBuffer>
|
||||
{
|
||||
public:
|
||||
void InitMain(ISequentialInStream *aStream, BYTE aReservedSize, UINT32 aNumBlocks)
|
||||
{
|
||||
m_Stream.Init(aStream, aReservedSize, aNumBlocks);
|
||||
Init();
|
||||
}
|
||||
HRESULT ReadBlock(UINT32 &anUncompressedSize, bool &aDataAreCorrect)
|
||||
{
|
||||
return m_Stream.ReadBlock(anUncompressedSize, aDataAreCorrect);
|
||||
}
|
||||
};
|
||||
|
||||
typedef NCompress::NHuffman::CDecoder<kNumHuffmanBits> CHuffmanDecoder;
|
||||
|
||||
class CDecoder :
|
||||
public ICompressCoder,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
CLZOutWindow m_OutWindowStream;
|
||||
CMSZipBitDecoder m_InBitStream;
|
||||
CHuffmanDecoder m_MainDecoder;
|
||||
CHuffmanDecoder m_DistDecoder;
|
||||
CHuffmanDecoder m_LevelDecoder; // table for decoding other tables;
|
||||
|
||||
bool m_FinalBlock;
|
||||
bool m_StoredMode;
|
||||
UINT32 m_StoredBlockSize;
|
||||
|
||||
BYTE m_ReservedSize;
|
||||
UINT32 m_NumInDataBlocks;
|
||||
|
||||
void DeCodeLevelTable(BYTE *newLevels, int numLevels);
|
||||
void ReadTables();
|
||||
public:
|
||||
CDecoder();
|
||||
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
HRESULT Flush();
|
||||
// void ReleaseStreams();
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
void SetParams(BYTE aReservedSize, UINT32 aNumInDataBlocks)
|
||||
{
|
||||
m_ReservedSize = aReservedSize;
|
||||
m_NumInDataBlocks = aNumInDataBlocks;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
22
7zip/Archive/Cab/MSZipExtConst.h
Executable file
22
7zip/Archive/Cab/MSZipExtConst.h
Executable file
@@ -0,0 +1,22 @@
|
||||
// DeflateExtConst.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __DEFLATEEXTCONST_H
|
||||
#define __DEFLATEEXTCONST_H
|
||||
|
||||
#include "Common/Types.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NCab {
|
||||
namespace NMSZip {
|
||||
|
||||
const UINT32 kDistTableSize = 30;
|
||||
const UINT32 kHistorySize = 0x8000;
|
||||
const UINT32 kNumLenCombinations = 256;
|
||||
|
||||
const UINT32 kNumHuffmanBits = 15;
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
3
7zip/Archive/Cab/StdAfx.cpp
Executable file
3
7zip/Archive/Cab/StdAfx.cpp
Executable file
@@ -0,0 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "stdafx.h"
|
||||
9
7zip/Archive/Cab/StdAfx.h
Executable file
9
7zip/Archive/Cab/StdAfx.h
Executable file
@@ -0,0 +1,9 @@
|
||||
// stdafx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include <windows.h>
|
||||
#include <time.h>
|
||||
|
||||
#endif
|
||||
BIN
7zip/Archive/Cab/cab.ico
Executable file
BIN
7zip/Archive/Cab/cab.ico
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 3.6 KiB |
16
7zip/Archive/Cab/resource.h
Executable file
16
7zip/Archive/Cab/resource.h
Executable file
@@ -0,0 +1,16 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by resource.rc
|
||||
//
|
||||
#define IDI_ICON1 101
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 102
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user