mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-10 12:07:08 -06:00
3.13
This commit is contained in:
122
7zip/Archive/Zip/DllExports.cpp
Executable file
122
7zip/Archive/Zip/DllExports.cpp
Executable file
@@ -0,0 +1,122 @@
|
||||
// DLLExports.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include <initguid.h>
|
||||
|
||||
#include "Common/ComTry.h"
|
||||
#include "ZipHandler.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "../../ICoder.h"
|
||||
#include "../../IPassword.h"
|
||||
|
||||
// {23170F69-40C1-278B-0401-080000000100}
|
||||
DEFINE_GUID(CLSID_CCompressDeflateEncoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00);
|
||||
|
||||
// {23170F69-40C1-278B-0401-080000000000}
|
||||
DEFINE_GUID(CLSID_CCompressDeflateDecoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
|
||||
// {23170F69-40C1-278B-0401-090000000100}
|
||||
DEFINE_GUID(CLSID_CCompressDeflate64Encoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00);
|
||||
|
||||
// {23170F69-40C1-278B-0401-090000000000}
|
||||
DEFINE_GUID(CLSID_CCompressDeflate64Decoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
|
||||
// {23170F69-40C1-278B-0402-020000000100}
|
||||
DEFINE_GUID(CLSID_CCompressBZip2Encoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00);
|
||||
|
||||
// {23170F69-40C1-278B-0402-020000000000}
|
||||
DEFINE_GUID(CLSID_CCompressBZip2Decoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
|
||||
// {23170F69-40C1-278B-0401-060000000000}
|
||||
DEFINE_GUID(CLSID_CCompressImplodeDecoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
|
||||
// {23170F69-40C1-278B-06F1-0101000000100}
|
||||
DEFINE_GUID(CLSID_CCryptoZipEncoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00);
|
||||
|
||||
// {23170F69-40C1-278B-06F1-0101000000000}
|
||||
DEFINE_GUID(CLSID_CCryptoZipDecoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00);
|
||||
|
||||
// {23170F69-40C1-278A-1000-000110010000}
|
||||
DEFINE_GUID(CLSID_CZipHandler,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x01, 0x00, 0x00);
|
||||
|
||||
HINSTANCE g_hInstance;
|
||||
|
||||
extern "C"
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
||||
{
|
||||
if (dwReason == DLL_PROCESS_ATTACH)
|
||||
g_hInstance = hInstance;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
STDAPI CreateObject(
|
||||
const GUID *classID,
|
||||
const GUID *interfaceID,
|
||||
void **outObject)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
*outObject = 0;
|
||||
if (*classID != CLSID_CZipHandler)
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
int needIn = *interfaceID == IID_IInArchive;
|
||||
int needOut = *interfaceID == IID_IOutArchive;
|
||||
if (needIn || needOut)
|
||||
{
|
||||
NArchive::NZip::CHandler *temp = new NArchive::NZip::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"Zip";
|
||||
break;
|
||||
case NArchive::kClassID:
|
||||
{
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen(
|
||||
(const char *)&CLSID_CZipHandler, sizeof(GUID))) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
}
|
||||
case NArchive::kExtension:
|
||||
propVariant = L"zip jar xpi";
|
||||
break;
|
||||
case NArchive::kUpdate:
|
||||
propVariant = true;
|
||||
break;
|
||||
case NArchive::kKeepName:
|
||||
propVariant = false;
|
||||
break;
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
3
7zip/Archive/Zip/StdAfx.cpp
Executable file
3
7zip/Archive/Zip/StdAfx.cpp
Executable file
@@ -0,0 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "stdafx.h"
|
||||
31
7zip/Archive/Zip/StdAfx.h
Executable file
31
7zip/Archive/Zip/StdAfx.h
Executable file
@@ -0,0 +1,31 @@
|
||||
// stdafx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include <windows.h>
|
||||
#include <time.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
/*
|
||||
#define _ATL_APARTMENT_THREADED
|
||||
// #define _ATL_FREE_THREADED
|
||||
|
||||
|
||||
#define _ATL_NO_UUIDOF
|
||||
|
||||
#include <atlbase.h>
|
||||
|
||||
extern CComModule _Module;
|
||||
|
||||
#include <atlcom.h>
|
||||
#include <shlobj.h>
|
||||
#include <shlguid.h>
|
||||
|
||||
#include <new.h>
|
||||
|
||||
*/
|
||||
|
||||
#endif
|
||||
7
7zip/Archive/Zip/Zip.def
Executable file
7
7zip/Archive/Zip/Zip.def
Executable file
@@ -0,0 +1,7 @@
|
||||
; Zip.def
|
||||
|
||||
LIBRARY Zip.dll
|
||||
|
||||
EXPORTS
|
||||
CreateObject PRIVATE
|
||||
GetHandlerProperty PRIVATE
|
||||
441
7zip/Archive/Zip/Zip.dsp
Executable file
441
7zip/Archive/Zip/Zip.dsp
Executable file
@@ -0,0 +1,441 @@
|
||||
# Microsoft Developer Studio Project File - Name="Zip" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=Zip - 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 "Zip.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 "Zip.mak" CFG="Zip - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "Zip - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "Zip - 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)" == "Zip - 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 "ZIP_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZIP_EXPORTS" /D "CRYPTO_ZIP" /Yu"StdAfx.h" /FD /c
|
||||
# ADD 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\zip.dll" /opt:NOWIN98
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ELSEIF "$(CFG)" == "Zip - 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 "ZIP_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZIP_EXPORTS" /D "CRYPTO_ZIP" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD 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\zip.dll" /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "Zip - Win32 Release"
|
||||
# Name "Zip - Win32 Debug"
|
||||
# Begin Group "spec"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DllExports.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\resource.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\resource.rc
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.cpp
|
||||
# ADD CPP /Yc
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Zip.def
|
||||
# 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\Random.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Random.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 "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\FileFind.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\FileFind.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\PropVariant.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\PropVariant.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\Synchronization.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\Synchronization.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Archive Common"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\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\CoderMixer.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\CoderMixer.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 "7zip common"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# 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\OffsetStream.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\OffsetStream.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 "Engine"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipAddCommon.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipAddCommon.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipCompressionMode.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipHandler.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipHandler.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipHandlerOut.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipHeader.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipHeader.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipIn.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipIn.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipItem.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipItem.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipItemEx.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipOut.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipOut.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipUpdate.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipUpdate.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "copy"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Compress\Copy\CopyCoder.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Compress\Copy\CopyCoder.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Format Common"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# End Group
|
||||
# Begin Group "Crypto"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Crypto\Zip\ZipCipher.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Crypto\Zip\ZipCipher.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Crypto\Zip\ZipCrypto.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Crypto\Zip\ZipCrypto.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "7z"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\7z\7zMethods.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\7z\7zMethods.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\7-zip.ico"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zip.ico
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zip1.ico
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
29
7zip/Archive/Zip/Zip.dsw
Executable file
29
7zip/Archive/Zip/Zip.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: "Zip"=.\Zip.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
270
7zip/Archive/Zip/ZipAddCommon.cpp
Executable file
270
7zip/Archive/Zip/ZipAddCommon.cpp
Executable file
@@ -0,0 +1,270 @@
|
||||
// AddCommon.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/CRC.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "Windows/Defs.h"
|
||||
#include "../../ICoder.h"
|
||||
#include "../../IPassword.h"
|
||||
#include "../7z/7zMethods.h"
|
||||
|
||||
#include "ZipAddCommon.h"
|
||||
#include "ZipHeader.h"
|
||||
|
||||
#ifdef COMPRESS_DEFLATE
|
||||
#include "../../Compress/Deflate/DeflateEncoder.h"
|
||||
#else
|
||||
// {23170F69-40C1-278B-0401-080000000100}
|
||||
DEFINE_GUID(CLSID_CCompressDeflateEncoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00);
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_DEFLATE64
|
||||
#include "../../Compress/Deflate/DeflateEncoder.h"
|
||||
#else
|
||||
// {23170F69-40C1-278B-0401-090000000100}
|
||||
DEFINE_GUID(CLSID_CCompressDeflate64Encoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00);
|
||||
#endif
|
||||
|
||||
#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);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CRYPTO_ZIP
|
||||
#include "../../Crypto/Zip/ZipCipher.h"
|
||||
#else
|
||||
// {23170F69-40C1-278B-06F1-0101000000100}
|
||||
DEFINE_GUID(CLSID_CCryptoZipEncoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00);
|
||||
#endif
|
||||
|
||||
namespace NArchive {
|
||||
namespace NZip {
|
||||
|
||||
static const BYTE kMethodIDForEmptyStream = NFileHeader::NCompressionMethod::kStored;
|
||||
static const BYTE kExtractVersionForEmptyStream = NFileHeader::NCompressionMethod::kStoreExtractVersion;
|
||||
|
||||
CAddCommon::CAddCommon(const CCompressionMethodMode &options):
|
||||
_options(options),
|
||||
_copyCoderSpec(NULL),
|
||||
_mixerCoderSpec(0)
|
||||
{}
|
||||
|
||||
static HRESULT GetStreamCRC(IInStream *inStream, UINT32 &resultCRC)
|
||||
{
|
||||
CCRC crc;
|
||||
crc.Init();
|
||||
const UINT32 kBufferSize = (1 << 14);
|
||||
BYTE buffer[kBufferSize];
|
||||
while(true)
|
||||
{
|
||||
UINT32 realProcessedSize;
|
||||
RINOK(inStream->Read(buffer, kBufferSize, &realProcessedSize));
|
||||
if(realProcessedSize == 0)
|
||||
{
|
||||
resultCRC = crc.GetDigest();
|
||||
return S_OK;
|
||||
}
|
||||
crc.Update(buffer, realProcessedSize);
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT CAddCommon::Compress(IInStream *inStream, IOutStream *outStream,
|
||||
UINT64 inSize, ICompressProgressInfo *progress, CCompressingResult &operationResult)
|
||||
{
|
||||
/*
|
||||
if(inSize == 0)
|
||||
{
|
||||
operationResult.PackSize = 0;
|
||||
operationResult.Method = kMethodIDForEmptyStream;
|
||||
operationResult.ExtractVersion = kExtractVersionForEmptyStream;
|
||||
return S_OK;
|
||||
}
|
||||
*/
|
||||
int numTestMethods = _options.MethodSequence.Size();
|
||||
BYTE method;
|
||||
UINT64 resultSize = 0;
|
||||
for(int i = 0; i < numTestMethods; i++)
|
||||
{
|
||||
if (_options.PasswordIsDefined)
|
||||
{
|
||||
if (!_cryptoEncoder)
|
||||
{
|
||||
#ifdef CRYPTO_ZIP
|
||||
_cryptoEncoder = new NCrypto::NZip::CEncoder;
|
||||
#else
|
||||
// change it;
|
||||
/*
|
||||
RINOK(_cryptoLib.LoadAndCreateCoder(
|
||||
GetBaseFolderPrefix() + TEXT("\\Crypto\\Zip.dll"),
|
||||
CLSID_CCryptoZipEncoder, &_cryptoEncoder));
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
|
||||
RINOK(_cryptoEncoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword));
|
||||
RINOK(cryptoSetPassword->CryptoSetPassword(
|
||||
(const BYTE *)(const char *)_options.Password, _options.Password.Length()));
|
||||
UINT32 crc;
|
||||
RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
|
||||
RINOK(GetStreamCRC(inStream, crc));
|
||||
CMyComPtr<ICryptoSetCRC> cryptoSetCRC;
|
||||
RINOK(_cryptoEncoder.QueryInterface(IID_ICryptoSetCRC, &cryptoSetCRC));
|
||||
RINOK(cryptoSetCRC->CryptoSetCRC(crc));
|
||||
}
|
||||
|
||||
RINOK(outStream->Seek(0, STREAM_SEEK_SET, NULL));
|
||||
RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
|
||||
|
||||
method = _options.MethodSequence[i];
|
||||
switch(method)
|
||||
{
|
||||
case NFileHeader::NCompressionMethod::kStored:
|
||||
{
|
||||
if(_copyCoderSpec == NULL)
|
||||
{
|
||||
_copyCoderSpec = new NCompress::CCopyCoder;
|
||||
_copyCoder = _copyCoderSpec;
|
||||
}
|
||||
if (_options.PasswordIsDefined)
|
||||
{
|
||||
if (!_mixerCoder || _mixerCoderMethod != method)
|
||||
{
|
||||
_mixerCoder.Release();
|
||||
_mixerCoderSpec = new CCoderMixer;
|
||||
_mixerCoder = _mixerCoderSpec;
|
||||
_mixerCoderSpec->AddCoder(_copyCoder);
|
||||
_mixerCoderSpec->AddCoder(_cryptoEncoder);
|
||||
_mixerCoderSpec->FinishAddingCoders();
|
||||
_mixerCoderMethod = method;
|
||||
}
|
||||
_mixerCoderSpec->ReInit();
|
||||
_mixerCoderSpec->SetCoderInfo(0, NULL, NULL);
|
||||
_mixerCoderSpec->SetCoderInfo(1, NULL, NULL);
|
||||
_mixerCoderSpec->SetProgressCoderIndex(0);
|
||||
RINOK(_mixerCoder->Code(inStream, outStream,
|
||||
NULL, NULL, progress));
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(_copyCoder->Code(inStream, outStream,
|
||||
NULL, NULL, progress));
|
||||
}
|
||||
operationResult.ExtractVersion = NFileHeader::NCompressionMethod::kStoreExtractVersion;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if(!_compressEncoder)
|
||||
{
|
||||
// RINOK(m_MatchFinder.CoCreateInstance(CLSID_CMatchFinderBT3));
|
||||
#ifndef COMPRESS_DEFLATE
|
||||
UString methodName;
|
||||
N7z::LoadMethodMap();
|
||||
#endif
|
||||
switch(method)
|
||||
{
|
||||
case NFileHeader::NCompressionMethod::kDeflated:
|
||||
{
|
||||
#ifdef COMPRESS_DEFLATE
|
||||
_compressEncoder = new NCompress::NDeflate::NEncoder::CCOMCoder;
|
||||
#else
|
||||
methodName = L"Deflate";
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case NFileHeader::NCompressionMethod::kDeflated64:
|
||||
{
|
||||
#ifdef COMPRESS_DEFLATE64
|
||||
_compressEncoder = new NCompress::NDeflate::NEncoder::CCOMCoder64;
|
||||
#else
|
||||
methodName = L"Deflate64";
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case NFileHeader::NCompressionMethod::kBZip2:
|
||||
{
|
||||
#ifdef COMPRESS_BZIP2
|
||||
_compressEncoder = new NCompress::NBZip2::CEncoder;
|
||||
#else
|
||||
methodName = L"BZip2";
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifndef COMPRESS_DEFLATE
|
||||
N7z::CMethodInfo2 methodInfo;
|
||||
if (!N7z::GetMethodInfo(methodName, methodInfo))
|
||||
return E_NOTIMPL;
|
||||
RINOK(_compressLib.LoadAndCreateCoder(
|
||||
methodInfo.FilePath, methodInfo.Encoder, &_compressEncoder));
|
||||
#endif
|
||||
|
||||
if (method == NFileHeader::NCompressionMethod::kDeflated ||
|
||||
method == NFileHeader::NCompressionMethod::kDeflated64)
|
||||
{
|
||||
NWindows::NCOM::CPropVariant properties[2] =
|
||||
{
|
||||
_options.NumPasses, _options.NumFastBytes
|
||||
};
|
||||
PROPID propIDs[2] =
|
||||
{
|
||||
NCoderPropID::kNumPasses,
|
||||
NCoderPropID::kNumFastBytes
|
||||
};
|
||||
CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
|
||||
RINOK(_compressEncoder.QueryInterface(
|
||||
IID_ICompressSetCoderProperties, &setCoderProperties));
|
||||
setCoderProperties->SetCoderProperties(propIDs, properties, 2);
|
||||
}
|
||||
}
|
||||
if (_options.PasswordIsDefined)
|
||||
{
|
||||
if (!_mixerCoder || _mixerCoderMethod != method)
|
||||
{
|
||||
_mixerCoder.Release();
|
||||
_mixerCoderSpec = new CCoderMixer;
|
||||
_mixerCoder = _mixerCoderSpec;
|
||||
_mixerCoderSpec->AddCoder(_compressEncoder);
|
||||
_mixerCoderSpec->AddCoder(_cryptoEncoder);
|
||||
_mixerCoderSpec->FinishAddingCoders();
|
||||
_mixerCoderMethod = method;
|
||||
}
|
||||
_mixerCoderSpec->ReInit();
|
||||
_mixerCoderSpec->SetCoderInfo(0, NULL, NULL);
|
||||
_mixerCoderSpec->SetCoderInfo(1, NULL, NULL);
|
||||
_mixerCoderSpec->SetProgressCoderIndex(0);
|
||||
RINOK(_mixerCoder->Code(inStream, outStream,
|
||||
NULL, NULL, progress));
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(_compressEncoder->Code(inStream, outStream, NULL, NULL, progress));
|
||||
}
|
||||
operationResult.ExtractVersion = NFileHeader::NCompressionMethod::kDeflateExtractVersion;
|
||||
break;
|
||||
}
|
||||
}
|
||||
outStream->Seek(0, STREAM_SEEK_CUR, &resultSize);
|
||||
if (_options.PasswordIsDefined)
|
||||
{
|
||||
if(resultSize < inSize + 12)
|
||||
break;
|
||||
}
|
||||
else if(resultSize < inSize)
|
||||
break;
|
||||
}
|
||||
outStream->SetSize(resultSize);
|
||||
operationResult.PackSize = resultSize;
|
||||
operationResult.Method = method;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}}
|
||||
56
7zip/Archive/Zip/ZipAddCommon.h
Executable file
56
7zip/Archive/Zip/ZipAddCommon.h
Executable file
@@ -0,0 +1,56 @@
|
||||
// Zip/AddCommon.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ZIP_ADDCOMMON_H
|
||||
#define __ZIP_ADDCOMMON_H
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../IProgress.h"
|
||||
#include "../../Compress/Copy/CopyCoder.h"
|
||||
#include "../Common/CoderMixer.h"
|
||||
#ifndef COMPRESS_DEFLATE
|
||||
#include "../Common/CoderLoader.h"
|
||||
#endif
|
||||
#include "ZipCompressionMode.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NZip {
|
||||
|
||||
struct CCompressingResult
|
||||
{
|
||||
BYTE Method;
|
||||
UINT64 PackSize;
|
||||
BYTE ExtractVersion;
|
||||
};
|
||||
|
||||
class CAddCommon
|
||||
{
|
||||
CCompressionMethodMode _options;
|
||||
NCompress::CCopyCoder *_copyCoderSpec;
|
||||
CMyComPtr<ICompressCoder> _copyCoder;
|
||||
|
||||
#ifndef COMPRESS_DEFLATE
|
||||
CCoderLibrary _compressLib;
|
||||
#endif
|
||||
CMyComPtr<ICompressCoder> _compressEncoder;
|
||||
|
||||
#ifndef CRYPTO_ZIP
|
||||
CCoderLibrary _cryptoLib;
|
||||
#endif
|
||||
CMyComPtr<ICompressCoder> _cryptoEncoder;
|
||||
CCoderMixer *_mixerCoderSpec;
|
||||
CMyComPtr<ICompressCoder> _mixerCoder;
|
||||
BYTE _mixerCoderMethod;
|
||||
// CMyComPtr<ICryptoGetTextPassword> getTextPassword;
|
||||
|
||||
|
||||
public:
|
||||
CAddCommon(const CCompressionMethodMode &options);
|
||||
HRESULT Compress(IInStream *inStream, IOutStream *outStream,
|
||||
UINT64 inSize, ICompressProgressInfo *progress, CCompressingResult &operationResult);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
26
7zip/Archive/Zip/ZipCompressionMode.h
Executable file
26
7zip/Archive/Zip/ZipCompressionMode.h
Executable file
@@ -0,0 +1,26 @@
|
||||
// CompressionMode.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ZIP_COMPRESSIONMETHOD_H
|
||||
#define __ZIP_COMPRESSIONMETHOD_H
|
||||
|
||||
#include "Common/Vector.h"
|
||||
#include "Common/String.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NZip {
|
||||
|
||||
struct CCompressionMethodMode
|
||||
{
|
||||
CRecordVector<BYTE> MethodSequence;
|
||||
// bool MaximizeRatio;
|
||||
UINT32 NumPasses;
|
||||
UINT32 NumFastBytes;
|
||||
bool PasswordIsDefined;
|
||||
AString Password;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
612
7zip/Archive/Zip/ZipHandler.cpp
Executable file
612
7zip/Archive/Zip/ZipHandler.cpp
Executable file
@@ -0,0 +1,612 @@
|
||||
// Zip/Handler.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "ZipHandler.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 "../../IPassword.h"
|
||||
// #include "../../../Compress/Interface/CompressInterface.h"
|
||||
|
||||
#include "../../Common/ProgressUtils.h"
|
||||
#include "../../Common/StreamObjects.h"
|
||||
// #include "Interface/EnumStatProp.h"
|
||||
#include "../../Common/StreamObjects.h"
|
||||
|
||||
#include "../../Compress/Copy/CopyCoder.h"
|
||||
|
||||
|
||||
#include "../Common/ItemNameUtils.h"
|
||||
#include "../Common/OutStreamWithCRC.h"
|
||||
#include "../Common/CoderMixer.h"
|
||||
#include "../7z/7zMethods.h"
|
||||
|
||||
|
||||
#ifdef COMPRESS_DEFLATE
|
||||
#include "../../Compress/Deflate/DeflateDecoder.h"
|
||||
#else
|
||||
// {23170F69-40C1-278B-0401-080000000000}
|
||||
DEFINE_GUID(CLSID_CCompressDeflateDecoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_DEFLATE64
|
||||
#include "../../Compress/Deflate/DeflateDecoder.h"
|
||||
#else
|
||||
// {23170F69-40C1-278B-0401-090000000000}
|
||||
DEFINE_GUID(CLSID_CCompressDeflate64Decoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_IMPLODE
|
||||
#include "../../Compress/Implode/ImplodeDecoder.h"
|
||||
#else
|
||||
// {23170F69-40C1-278B-0401-060000000000}
|
||||
DEFINE_GUID(CLSID_CCompressImplodeDecoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_BZIP2
|
||||
#include "../../Compress/BZip2/BZip2Decoder.h"
|
||||
#else
|
||||
// {23170F69-40C1-278B-0402-020000000000}
|
||||
DEFINE_GUID(CLSID_CCompressBZip2Decoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
#endif
|
||||
|
||||
#ifdef CRYPTO_ZIP
|
||||
#include "../../Crypto/Zip/ZipCipher.h"
|
||||
#else
|
||||
// {23170F69-40C1-278B-06F1-0101000000000}
|
||||
DEFINE_GUID(CLSID_CCryptoZipDecoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00);
|
||||
#endif
|
||||
|
||||
#ifndef EXCLUDE_COM
|
||||
#include "../Common/CoderLoader.h"
|
||||
#endif
|
||||
|
||||
// using namespace std;
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NTime;
|
||||
|
||||
namespace NArchive {
|
||||
namespace NZip {
|
||||
|
||||
const wchar_t *kHostOS[] =
|
||||
{
|
||||
L"FAT",
|
||||
L"AMIGA",
|
||||
L"VMS",
|
||||
L"Unix",
|
||||
L"VM_CMS",
|
||||
L"Atari", // what if it's a minix filesystem? [cjh]
|
||||
L"HPFS", // filesystem used by OS/2 (and NT 3.x)
|
||||
L"Mac",
|
||||
L"Z_System",
|
||||
L"CPM",
|
||||
L"TOPS20", // pkzip 2.50 NTFS
|
||||
L"NTFS", // filesystem used by Windows NT
|
||||
L"QDOS ", // SMS/QDOS
|
||||
L"Acorn", // Archimedes Acorn RISC OS
|
||||
L"VFAT", // filesystem used by Windows 95, NT
|
||||
L"MVS",
|
||||
L"BeOS", // hybrid POSIX/database filesystem
|
||||
// BeBOX or PowerMac
|
||||
L"Tandem",
|
||||
L"THEOS"
|
||||
};
|
||||
|
||||
|
||||
static const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]);
|
||||
|
||||
static const wchar_t *kUnknownOS = L"Unknown";
|
||||
|
||||
|
||||
/*
|
||||
enum // PropID
|
||||
{
|
||||
kpidUnPackVersion,
|
||||
};
|
||||
*/
|
||||
|
||||
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_BSTR},
|
||||
{ NULL, kpidHostOS, VT_BSTR}
|
||||
|
||||
// { L"UnPack Version", kpidUnPackVersion, VT_UI1},
|
||||
};
|
||||
|
||||
const wchar_t *kMethods[] =
|
||||
{
|
||||
L"Store",
|
||||
L"Shrunk",
|
||||
L"Reduced1",
|
||||
L"Reduced2",
|
||||
L"Reduced2",
|
||||
L"Reduced3",
|
||||
L"Implode",
|
||||
L"Tokenizing",
|
||||
L"Deflate",
|
||||
L"Deflate64",
|
||||
L"PKImploding",
|
||||
L"Unknown",
|
||||
L"BZip2"
|
||||
};
|
||||
|
||||
const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]);
|
||||
const wchar_t *kUnknownMethod = L"Unknown";
|
||||
|
||||
CHandler::CHandler():
|
||||
m_ArchiveIsOpen(false)
|
||||
{
|
||||
InitMethodProperties();
|
||||
m_Method.MethodSequence.Add(NFileHeader::NCompressionMethod::kDeflated);
|
||||
m_Method.MethodSequence.Add(NFileHeader::NCompressionMethod::kStored);
|
||||
}
|
||||
|
||||
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 = m_Items.Size();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID aPropID, PROPVARIANT *aValue)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
const CItemEx &item = m_Items[index];
|
||||
switch(aPropID)
|
||||
{
|
||||
case kpidPath:
|
||||
propVariant = NItemName::GetOSName2(
|
||||
MultiByteToUnicodeString(item.Name, item.GetCodePage()));
|
||||
break;
|
||||
case kpidIsFolder:
|
||||
propVariant = item.IsDirectory();
|
||||
break;
|
||||
case kpidSize:
|
||||
propVariant = item.UnPackSize;
|
||||
break;
|
||||
case kpidPackedSize:
|
||||
propVariant = item.PackSize;
|
||||
break;
|
||||
case kpidLastWriteTime:
|
||||
{
|
||||
FILETIME aLocalFileTime, anUTCFileTime;
|
||||
if (DosTimeToFileTime(item.Time, aLocalFileTime))
|
||||
{
|
||||
if (!LocalFileTimeToFileTime(&aLocalFileTime, &anUTCFileTime))
|
||||
anUTCFileTime.dwHighDateTime = anUTCFileTime.dwLowDateTime = 0;
|
||||
}
|
||||
else
|
||||
anUTCFileTime.dwHighDateTime = anUTCFileTime.dwLowDateTime = 0;
|
||||
propVariant = anUTCFileTime;
|
||||
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:
|
||||
{
|
||||
UString method;
|
||||
if (item.CompressionMethod < kNumMethods)
|
||||
method = kMethods[item.CompressionMethod];
|
||||
else
|
||||
method = kUnknownMethod;
|
||||
propVariant = method;
|
||||
// propVariant = item.CompressionMethod;
|
||||
break;
|
||||
}
|
||||
case kpidHostOS:
|
||||
propVariant = (item.MadeByVersion.HostOS < kNumHostOSes) ?
|
||||
(kHostOS[item.MadeByVersion.HostOS]) : kUnknownOS;
|
||||
break;
|
||||
}
|
||||
propVariant.Detach(aValue);
|
||||
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
|
||||
{
|
||||
if(!m_Archive.Open(inStream, maxCheckStartPosition))
|
||||
return S_FALSE;
|
||||
m_ArchiveIsOpen = true;
|
||||
m_Items.Clear();
|
||||
if (openArchiveCallback != NULL)
|
||||
{
|
||||
RINOK(openArchiveCallback->SetTotal(NULL, NULL));
|
||||
}
|
||||
CPropgressImp propgressImp;
|
||||
propgressImp.Init(openArchiveCallback);
|
||||
RINOK(m_Archive.ReadHeaders(m_Items, &propgressImp));
|
||||
}
|
||||
/*
|
||||
catch(...)
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
*/
|
||||
COM_TRY_END
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Close()
|
||||
{
|
||||
m_Archive.Close();
|
||||
m_ArchiveIsOpen = false;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
// CHandler::DecompressItems
|
||||
|
||||
struct CMethodItem
|
||||
{
|
||||
BYTE ZipMethod;
|
||||
CMyComPtr<ICompressCoder> Coder;
|
||||
};
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
|
||||
INT32 _aTestMode, IArchiveExtractCallback *_anExtractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
|
||||
bool testMode = (_aTestMode != 0);
|
||||
CMyComPtr<IArchiveExtractCallback> extractCallback = _anExtractCallback;
|
||||
UINT64 totalUnPacked = 0, totalPacked = 0;
|
||||
bool allFilesMode = (numItems == UINT32(-1));
|
||||
if (allFilesMode)
|
||||
numItems = m_Items.Size();
|
||||
if(numItems == 0)
|
||||
return S_OK;
|
||||
UINT32 i;
|
||||
for(i = 0; i < numItems; i++)
|
||||
{
|
||||
const CItemEx &item = m_Items[allFilesMode ? i : indices[i]];
|
||||
totalUnPacked += item.UnPackSize;
|
||||
totalPacked += item.PackSize;
|
||||
}
|
||||
extractCallback->SetTotal(totalUnPacked);
|
||||
|
||||
UINT64 currentTotalUnPacked = 0, currentTotalPacked = 0;
|
||||
UINT64 currentItemUnPacked, currentItemPacked;
|
||||
|
||||
|
||||
#ifndef EXCLUDE_COM
|
||||
N7z::LoadMethodMap();
|
||||
CCoderLibraries libraries;
|
||||
#endif
|
||||
CObjectVector<CMethodItem> methodItems;
|
||||
/*
|
||||
CCoderLibraries _libraries;
|
||||
#ifndef COMPRESS_IMPLODE
|
||||
CCoderLibrary implodeLib;
|
||||
#endif
|
||||
|
||||
|
||||
CMyComPtr<ICompressCoder> implodeDecoder;
|
||||
CMyComPtr<ICompressCoder> deflateDecoder;
|
||||
CMyComPtr<ICompressCoder> deflate64Decoder;
|
||||
CMyComPtr<ICompressCoder> bzip2Decoder;
|
||||
|
||||
#ifndef CRYPTO_ZIP
|
||||
CCoderLibrary cryptoLib;
|
||||
#endif
|
||||
*/
|
||||
|
||||
CMyComPtr<ICompressCoder> cryptoDecoder;
|
||||
CCoderMixer *mixerCoderSpec;
|
||||
CMyComPtr<ICompressCoder> mixerCoder;
|
||||
|
||||
UINT16 mixerCoderMethod;
|
||||
|
||||
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 &item = m_Items[index];
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
|
||||
if(item.IsDirectory() || item.IgnoreItem())
|
||||
{
|
||||
// if (!testMode)
|
||||
{
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!testMode && (!realOutStream))
|
||||
continue;
|
||||
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
currentItemUnPacked = item.UnPackSize;
|
||||
currentItemPacked = item.PackSize;
|
||||
|
||||
{
|
||||
COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;
|
||||
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
|
||||
outStreamSpec->Init(realOutStream);
|
||||
realOutStream.Release();
|
||||
|
||||
CMyComPtr<ISequentialInStream> inStream;
|
||||
inStream.Attach(m_Archive.CreateLimitedStream(item.GetDataPosition(),
|
||||
item.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 (item.IsEncrypted())
|
||||
{
|
||||
if (!cryptoDecoder)
|
||||
{
|
||||
#ifdef CRYPTO_ZIP
|
||||
cryptoDecoder = new NCrypto::NZip::CDecoder;
|
||||
#else
|
||||
RINOK(cryptoLib.LoadAndCreateCoder(
|
||||
GetBaseFolderPrefix() + TEXT("\\Crypto\\Zip.dll"),
|
||||
CLSID_CCryptoZipDecoder, &cryptoDecoder));
|
||||
#endif
|
||||
}
|
||||
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
|
||||
RINOK(cryptoDecoder.QueryInterface(
|
||||
IID_ICryptoSetPassword, &cryptoSetPassword));
|
||||
|
||||
if (!getTextPassword)
|
||||
extractCallback.QueryInterface(
|
||||
IID_ICryptoGetTextPassword, &getTextPassword);
|
||||
|
||||
if (getTextPassword)
|
||||
{
|
||||
CMyComBSTR password;
|
||||
RINOK(getTextPassword->CryptoGetTextPassword(&password));
|
||||
AString anOemPassword = UnicodeStringToMultiByte(
|
||||
(const wchar_t *)password, CP_OEMCP);
|
||||
RINOK(cryptoSetPassword->CryptoSetPassword(
|
||||
(const BYTE *)(const char *)anOemPassword, anOemPassword.Length()));
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(cryptoSetPassword->CryptoSetPassword(0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
int m;
|
||||
for (m = 0; m < methodItems.Size(); m++)
|
||||
if (methodItems[m].ZipMethod == item.CompressionMethod)
|
||||
break;
|
||||
if (m == methodItems.Size())
|
||||
{
|
||||
CMethodItem mi;
|
||||
mi.ZipMethod = item.CompressionMethod;
|
||||
#ifdef EXCLUDE_COM
|
||||
switch(item.CompressionMethod)
|
||||
{
|
||||
case NFileHeader::NCompressionMethod::kStored:
|
||||
mi.Coder = new NCompress::CCopyCoder;
|
||||
break;
|
||||
case NFileHeader::NCompressionMethod::kImploded:
|
||||
mi.Coder = new NCompress::NImplode::NDecoder::CCoder;
|
||||
break;
|
||||
case NFileHeader::NCompressionMethod::kDeflated:
|
||||
mi.Coder = new NCompress::NDeflate::NDecoder::CCOMCoder;
|
||||
break;
|
||||
case NFileHeader::NCompressionMethod::kDeflated64:
|
||||
mi.Coder = new NCompress::NDeflate::NDecoder::CCOMCoder64;
|
||||
break;
|
||||
case NFileHeader::NCompressionMethod::kBZip2:
|
||||
mi.Coder = new NCompress::NBZip2::CDecoder;
|
||||
break;
|
||||
default:
|
||||
RINOK(extractCallback->SetOperationResult(
|
||||
NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
N7z::CMethodID methodID = { { 0x04, 0x01 } , 3 };
|
||||
methodID.ID[2] = item.CompressionMethod;
|
||||
if (item.CompressionMethod == NFileHeader::NCompressionMethod::kStored)
|
||||
{
|
||||
methodID.ID[0] = 0;
|
||||
methodID.IDSize = 1;
|
||||
}
|
||||
else if (item.CompressionMethod == NFileHeader::NCompressionMethod::kBZip2)
|
||||
{
|
||||
methodID.ID[1] = 0x02;
|
||||
methodID.ID[2] = 0x02;
|
||||
}
|
||||
|
||||
N7z::CMethodInfo methodInfo;
|
||||
if (!N7z::GetMethodInfo(methodID, methodInfo))
|
||||
{
|
||||
RINOK(extractCallback->SetOperationResult(
|
||||
NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
||||
continue;
|
||||
}
|
||||
RINOK(libraries.CreateCoder(methodInfo.FilePath,
|
||||
methodInfo.Decoder, &mi.Coder));
|
||||
#endif
|
||||
m = methodItems.Add(mi);
|
||||
}
|
||||
ICompressCoder *coder = methodItems[m].Coder;
|
||||
|
||||
CMyComPtr<ICompressSetDecoderProperties> compressSetDecoderProperties;
|
||||
if (coder->QueryInterface(IID_ICompressSetDecoderProperties, (void **)&compressSetDecoderProperties) == S_OK)
|
||||
{
|
||||
// BYTE properties = (item.Flags & 6);
|
||||
BYTE properties = item.Flags;
|
||||
CSequentialInStreamImp *inStreamSpec = new CSequentialInStreamImp;
|
||||
CMyComPtr<ISequentialInStream> inStreamProperties(inStreamSpec);
|
||||
inStreamSpec->Init(&properties, 1);
|
||||
RINOK(compressSetDecoderProperties->SetDecoderProperties(inStreamProperties));
|
||||
}
|
||||
|
||||
// case NFileHeader::NCompressionMethod::kImploded:
|
||||
// switch(item.CompressionMethod)
|
||||
try
|
||||
{
|
||||
HRESULT result;
|
||||
if (item.IsEncrypted())
|
||||
{
|
||||
if (!mixerCoder || mixerCoderMethod != item.CompressionMethod)
|
||||
{
|
||||
mixerCoder.Release();
|
||||
mixerCoderSpec = new CCoderMixer;
|
||||
mixerCoder = mixerCoderSpec;
|
||||
mixerCoderSpec->AddCoder(cryptoDecoder);
|
||||
mixerCoderSpec->AddCoder(coder);
|
||||
mixerCoderSpec->FinishAddingCoders();
|
||||
mixerCoderMethod = item.CompressionMethod;
|
||||
}
|
||||
mixerCoderSpec->ReInit();
|
||||
|
||||
switch(item.CompressionMethod)
|
||||
{
|
||||
case NFileHeader::NCompressionMethod::kStored:
|
||||
mixerCoderSpec->SetCoderInfo(0, ¤tItemPacked,
|
||||
¤tItemUnPacked);
|
||||
mixerCoderSpec->SetCoderInfo(1, NULL, NULL);
|
||||
break;
|
||||
default:
|
||||
mixerCoderSpec->SetCoderInfo(0, ¤tItemPacked, NULL);
|
||||
mixerCoderSpec->SetCoderInfo(1, NULL, ¤tItemUnPacked);
|
||||
break;
|
||||
}
|
||||
|
||||
mixerCoderSpec->SetProgressCoderIndex(1);
|
||||
result = mixerCoder->Code(inStream, outStream,
|
||||
NULL, NULL, compressProgress);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = coder->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;
|
||||
}
|
||||
bool crcOK = outStreamSpec->GetCRC() == item.FileCRC;
|
||||
outStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(crcOK ? NArchive::NExtract::NOperationResult::kOK :
|
||||
NArchive::NExtract::NOperationResult::kCRCError))
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
}}
|
||||
73
7zip/Archive/Zip/ZipHandler.h
Executable file
73
7zip/Archive/Zip/ZipHandler.h
Executable file
@@ -0,0 +1,73 @@
|
||||
// Zip/Handler.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ZIP_HANDLER_H
|
||||
#define __ZIP_HANDLER_H
|
||||
|
||||
#include "Common/DynamicBuffer.h"
|
||||
#include "../../ICoder.h"
|
||||
#include "../IArchive.h"
|
||||
|
||||
#include "ZipIn.h"
|
||||
#include "ZipCompressionMode.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NZip {
|
||||
|
||||
class CHandler:
|
||||
public IInArchive,
|
||||
public IOutArchive,
|
||||
public ISetProperties,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
MY_UNKNOWN_IMP3(
|
||||
IInArchive,
|
||||
IOutArchive,
|
||||
ISetProperties
|
||||
)
|
||||
|
||||
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);
|
||||
|
||||
// IOutArchive
|
||||
STDMETHOD(UpdateItems)(IOutStream *outStream, UINT32 numItems,
|
||||
IArchiveUpdateCallback *updateCallback);
|
||||
STDMETHOD(GetFileTimeType)(UINT32 *timeType);
|
||||
|
||||
// ISetProperties
|
||||
STDMETHOD(SetProperties)(const BSTR *names, const PROPVARIANT *values, INT32 numProperties);
|
||||
|
||||
CHandler();
|
||||
private:
|
||||
CObjectVector<CItemEx> m_Items;
|
||||
CInArchive m_Archive;
|
||||
bool m_ArchiveIsOpen;
|
||||
CCompressionMethodMode m_Method;
|
||||
void InitMethodProperties()
|
||||
{
|
||||
m_Method.NumPasses = 1;
|
||||
m_Method.NumFastBytes = 32;
|
||||
}
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
284
7zip/Archive/Zip/ZipHandlerOut.cpp
Executable file
284
7zip/Archive/Zip/ZipHandlerOut.cpp
Executable file
@@ -0,0 +1,284 @@
|
||||
// Zip/HandlerOut.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "ZipHandler.h"
|
||||
#include "ZipUpdate.h"
|
||||
|
||||
#include "Common/StringConvert.h"
|
||||
#include "Common/ComTry.h"
|
||||
#include "Common/StringToInt.h"
|
||||
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "Windows/Time.h"
|
||||
|
||||
#include "../../IPassword.h"
|
||||
#include "../Common/ItemNameUtils.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NCOM;
|
||||
using namespace NTime;
|
||||
|
||||
namespace NArchive {
|
||||
namespace NZip {
|
||||
|
||||
STDMETHODIMP CHandler::GetFileTimeType(UINT32 *timeType)
|
||||
{
|
||||
*timeType = NFileTimeType::kDOS;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems,
|
||||
IArchiveUpdateCallback *updateCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
CObjectVector<CUpdateItem> updateItems;
|
||||
for(int i = 0; i < numItems; i++)
|
||||
{
|
||||
CUpdateItem updateItem;
|
||||
INT32 newData;
|
||||
INT32 newProperties;
|
||||
UINT32 indexInArchive;
|
||||
if (!updateCallback)
|
||||
return E_FAIL;
|
||||
RINOK(updateCallback->GetUpdateItemInfo(i,
|
||||
&newData, // 1 - compress 0 - copy
|
||||
&newProperties,
|
||||
&indexInArchive));
|
||||
updateItem.NewProperties = IntToBool(newProperties);
|
||||
updateItem.NewData = IntToBool(newData);
|
||||
updateItem.IndexInArchive = indexInArchive;
|
||||
updateItem.IndexInClient = i;
|
||||
bool existInArchive = (indexInArchive != UINT32(-1));
|
||||
if (IntToBool(newProperties))
|
||||
{
|
||||
FILETIME utcFileTime;
|
||||
UString name;
|
||||
bool isDirectoryStatusDefined;
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(updateCallback->GetProperty(i, kpidAttributes, &propVariant));
|
||||
if (propVariant.vt == VT_EMPTY)
|
||||
updateItem.Attributes = 0;
|
||||
else if (propVariant.vt != VT_UI4)
|
||||
return E_INVALIDARG;
|
||||
else
|
||||
updateItem.Attributes = propVariant.ulVal;
|
||||
}
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(updateCallback->GetProperty(i, kpidLastWriteTime, &propVariant));
|
||||
if (propVariant.vt != VT_FILETIME)
|
||||
return E_INVALIDARG;
|
||||
utcFileTime = propVariant.filetime;
|
||||
}
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(updateCallback->GetProperty(i, kpidPath, &propVariant));
|
||||
if (propVariant.vt == VT_EMPTY)
|
||||
name.Empty();
|
||||
else if (propVariant.vt != VT_BSTR)
|
||||
return E_INVALIDARG;
|
||||
else
|
||||
name = propVariant.bstrVal;
|
||||
}
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(updateCallback->GetProperty(i, kpidIsFolder, &propVariant));
|
||||
if (propVariant.vt == VT_EMPTY)
|
||||
isDirectoryStatusDefined = false;
|
||||
else if (propVariant.vt != VT_BOOL)
|
||||
return E_INVALIDARG;
|
||||
else
|
||||
{
|
||||
updateItem.IsDirectory = (propVariant.boolVal != VARIANT_FALSE);
|
||||
isDirectoryStatusDefined = true;
|
||||
}
|
||||
}
|
||||
FILETIME localFileTime;
|
||||
if(!FileTimeToLocalFileTime(&utcFileTime, &localFileTime))
|
||||
return E_INVALIDARG;
|
||||
if(!FileTimeToDosTime(localFileTime, updateItem.Time))
|
||||
return E_INVALIDARG;
|
||||
updateItem.Name = UnicodeStringToMultiByte(
|
||||
NItemName::MakeLegalName(name), CP_OEMCP);
|
||||
if (!isDirectoryStatusDefined)
|
||||
updateItem.IsDirectory = ((updateItem.Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0);
|
||||
if (updateItem.IsDirectory)
|
||||
updateItem.Name += '/';
|
||||
updateItem.IndexInClient = i;
|
||||
if(existInArchive)
|
||||
{
|
||||
const CItemEx &itemInfo = m_Items[indexInArchive];
|
||||
// updateItem.Commented = itemInfo.IsCommented();
|
||||
updateItem.Commented = false;
|
||||
if(updateItem.Commented)
|
||||
{
|
||||
updateItem.CommentRange.Position = itemInfo.GetCommentPosition();
|
||||
updateItem.CommentRange.Size = itemInfo.CommentSize;
|
||||
}
|
||||
}
|
||||
else
|
||||
updateItem.Commented = false;
|
||||
}
|
||||
if (IntToBool(newData))
|
||||
{
|
||||
UINT64 size;
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(updateCallback->GetProperty(i, kpidSize, &propVariant));
|
||||
if (propVariant.vt != VT_UI8)
|
||||
return E_INVALIDARG;
|
||||
size = *(UINT64 *)(&propVariant.uhVal);
|
||||
}
|
||||
if(size > 0xFFFFFFFF)
|
||||
return E_NOTIMPL;
|
||||
updateItem.Size = size;
|
||||
}
|
||||
updateItems.Add(updateItem);
|
||||
}
|
||||
|
||||
CMyComPtr<ICryptoGetTextPassword2> getTextPassword;
|
||||
if (!getTextPassword)
|
||||
{
|
||||
CMyComPtr<IArchiveUpdateCallback> udateCallBack2(updateCallback);
|
||||
udateCallBack2.QueryInterface(IID_ICryptoGetTextPassword2, &getTextPassword);
|
||||
}
|
||||
if (getTextPassword)
|
||||
{
|
||||
CMyComBSTR password;
|
||||
INT32 passwordIsDefined;
|
||||
RINOK(getTextPassword->CryptoGetTextPassword2(
|
||||
&passwordIsDefined, &password));
|
||||
if (m_Method.PasswordIsDefined = IntToBool(passwordIsDefined))
|
||||
m_Method.Password = UnicodeStringToMultiByte(
|
||||
(const wchar_t *)password, CP_OEMCP);
|
||||
}
|
||||
else
|
||||
m_Method.PasswordIsDefined = false;
|
||||
|
||||
return Update(m_Items, updateItems, outStream,
|
||||
m_ArchiveIsOpen ? &m_Archive : NULL, &m_Method, updateCallback);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
static const UINT32 kNumPassesNormal = 1;
|
||||
static const UINT32 kNumPassesMX = 3;
|
||||
|
||||
static const UINT32 kMatchFastLenNormal = 32;
|
||||
static const UINT32 kMatchFastLenMX = 64;
|
||||
|
||||
STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *values, INT32 numProperties)
|
||||
{
|
||||
InitMethodProperties();
|
||||
BYTE mainMethod = NFileHeader::NCompressionMethod::kDeflated;
|
||||
for (int i = 0; i < numProperties; i++)
|
||||
{
|
||||
UString name = UString(names[i]);
|
||||
name.MakeUpper();
|
||||
const PROPVARIANT &value = values[i];
|
||||
|
||||
if (name[0] == 'X')
|
||||
{
|
||||
name.Delete(0);
|
||||
UINT32 level = 9;
|
||||
if (value.vt == VT_UI4)
|
||||
{
|
||||
if (!name.IsEmpty())
|
||||
return E_INVALIDARG;
|
||||
level = value.ulVal;
|
||||
}
|
||||
else if (value.vt == VT_EMPTY)
|
||||
{
|
||||
if(!name.IsEmpty())
|
||||
{
|
||||
const wchar_t *start = name;
|
||||
const wchar_t *end;
|
||||
UINT64 v = ConvertStringToUINT64(start, &end);
|
||||
if (end - start != name.Length())
|
||||
return E_INVALIDARG;
|
||||
level = (UINT32)v;
|
||||
}
|
||||
}
|
||||
else
|
||||
return E_INVALIDARG;
|
||||
if (level == 0)
|
||||
{
|
||||
mainMethod = NFileHeader::NCompressionMethod::kStored;
|
||||
}
|
||||
else if (level < 7)
|
||||
{
|
||||
InitMethodProperties();
|
||||
if (mainMethod == NFileHeader::NCompressionMethod::kStored)
|
||||
mainMethod = NFileHeader::NCompressionMethod::kDeflated;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Method.NumPasses = kNumPassesMX;
|
||||
m_Method.NumFastBytes = kMatchFastLenMX;
|
||||
if (mainMethod == NFileHeader::NCompressionMethod::kStored)
|
||||
mainMethod = NFileHeader::NCompressionMethod::kDeflated;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if (name == L"M")
|
||||
{
|
||||
if (value.vt == VT_BSTR)
|
||||
{
|
||||
UString valueString = value.bstrVal;
|
||||
valueString.MakeUpper();
|
||||
if (valueString == L"COPY")
|
||||
mainMethod = NFileHeader::NCompressionMethod::kStored;
|
||||
else if (valueString == L"DEFLATE")
|
||||
mainMethod = NFileHeader::NCompressionMethod::kDeflated;
|
||||
else if (valueString == L"DEFLATE64")
|
||||
mainMethod = NFileHeader::NCompressionMethod::kDeflated64;
|
||||
else if (valueString == L"BZIP2")
|
||||
mainMethod = NFileHeader::NCompressionMethod::kBZip2;
|
||||
else
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
else if (value.vt == VT_UI4)
|
||||
{
|
||||
switch(value.ulVal)
|
||||
{
|
||||
case NFileHeader::NCompressionMethod::kStored:
|
||||
case NFileHeader::NCompressionMethod::kDeflated:
|
||||
case NFileHeader::NCompressionMethod::kDeflated64:
|
||||
case NFileHeader::NCompressionMethod::kBZip2:
|
||||
mainMethod = value.ulVal;
|
||||
break;
|
||||
default:
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
else
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
else if (name == L"PASS")
|
||||
{
|
||||
if (value.vt != VT_UI4)
|
||||
return E_INVALIDARG;
|
||||
m_Method.NumPasses = value.ulVal;
|
||||
if (m_Method.NumPasses < 1 || m_Method.NumPasses > 4)
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
else if (name == L"FB")
|
||||
{
|
||||
if (value.vt != VT_UI4)
|
||||
return E_INVALIDARG;
|
||||
m_Method.NumFastBytes = value.ulVal;
|
||||
if (m_Method.NumFastBytes < 3 || m_Method.NumFastBytes > 255)
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
else
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
m_Method.MethodSequence.Clear();
|
||||
if (mainMethod != NFileHeader::NCompressionMethod::kStored)
|
||||
m_Method.MethodSequence.Add(mainMethod);
|
||||
m_Method.MethodSequence.Add(NFileHeader::NCompressionMethod::kStored);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}}
|
||||
32
7zip/Archive/Zip/ZipHeader.cpp
Executable file
32
7zip/Archive/Zip/ZipHeader.cpp
Executable file
@@ -0,0 +1,32 @@
|
||||
// Archive/Zip/Header.h
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "ZipHeader.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NZip {
|
||||
|
||||
namespace NSignature
|
||||
{
|
||||
UINT32 kLocalFileHeader = 0x04034B50 + 1;
|
||||
UINT32 kDataDescriptor = 0x08074B50 + 1;
|
||||
UINT32 kCentralFileHeader = 0x02014B50 + 1;
|
||||
UINT32 kEndOfCentralDir = 0x06054B50 + 1;
|
||||
|
||||
class CMarkersInitializer
|
||||
{
|
||||
public:
|
||||
CMarkersInitializer()
|
||||
{
|
||||
kLocalFileHeader--;
|
||||
kDataDescriptor--;
|
||||
kCentralFileHeader--;
|
||||
kEndOfCentralDir--;
|
||||
}
|
||||
};
|
||||
static CMarkersInitializer g_MarkerInitializer;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
227
7zip/Archive/Zip/ZipHeader.h
Executable file
227
7zip/Archive/Zip/ZipHeader.h
Executable file
@@ -0,0 +1,227 @@
|
||||
// Archive/Zip/Header.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARCHIVE_ZIP_HEADER_H
|
||||
#define __ARCHIVE_ZIP_HEADER_H
|
||||
|
||||
#include "Common/Types.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NZip {
|
||||
|
||||
#pragma pack( push, PragmaZipHeaders)
|
||||
#pragma pack( push, 1)
|
||||
|
||||
namespace NSignature
|
||||
{
|
||||
extern UINT32 kLocalFileHeader;
|
||||
extern UINT32 kDataDescriptor;
|
||||
extern UINT32 kCentralFileHeader;
|
||||
extern UINT32 kEndOfCentralDir;
|
||||
|
||||
static const UINT32 kMarkerSize = 4;
|
||||
}
|
||||
|
||||
struct CEndOfCentralDirectoryRecord
|
||||
{
|
||||
UINT16 ThisDiskNumber;
|
||||
UINT16 StartCentralDirectoryDiskNumber;
|
||||
UINT16 NumEntriesInCentaralDirectoryOnThisDisk;
|
||||
UINT16 NumEntriesInCentaralDirectory;
|
||||
UINT32 CentralDirectorySize;
|
||||
UINT32 CentralDirectoryStartOffset;
|
||||
UINT16 CommentSize;
|
||||
};
|
||||
|
||||
struct CEndOfCentralDirectoryRecordFull
|
||||
{
|
||||
UINT32 Signature;
|
||||
CEndOfCentralDirectoryRecord Header;
|
||||
};
|
||||
|
||||
namespace NFileHeader
|
||||
{
|
||||
struct CVersion
|
||||
{
|
||||
BYTE Version;
|
||||
BYTE HostOS;
|
||||
};
|
||||
|
||||
namespace NCompressionMethod
|
||||
{
|
||||
enum EType
|
||||
{
|
||||
kStored = 0,
|
||||
kShrunk = 1,
|
||||
kReduced1 = 2,
|
||||
kReduced2 = 3,
|
||||
kReduced3 = 4,
|
||||
kReduced4 = 5,
|
||||
kImploded = 6,
|
||||
kReservedTokenizing = 7, // reserved for tokenizing
|
||||
kDeflated = 8,
|
||||
kDeflated64 = 9,
|
||||
kPKImploding = 10,
|
||||
|
||||
kBZip2 = 12
|
||||
};
|
||||
const int kNumCompressionMethods = 11;
|
||||
const BYTE kMadeByProgramVersion = 20;
|
||||
|
||||
const BYTE kDeflateExtractVersion = 20;
|
||||
const BYTE kStoreExtractVersion = 10;
|
||||
|
||||
const BYTE kSupportedVersion = 20;
|
||||
}
|
||||
|
||||
struct CLocalBlock
|
||||
{
|
||||
CVersion ExtractVersion;
|
||||
|
||||
UINT16 Flags;
|
||||
UINT16 CompressionMethod;
|
||||
UINT32 Time;
|
||||
UINT32 FileCRC;
|
||||
UINT32 PackSize;
|
||||
UINT32 UnPackSize;
|
||||
UINT16 NameSize;
|
||||
UINT16 ExtraSize;
|
||||
};
|
||||
|
||||
struct CDataDescriptor
|
||||
{
|
||||
UINT32 Signature;
|
||||
UINT32 FileCRC;
|
||||
UINT32 PackSize;
|
||||
UINT32 UnPackSize;
|
||||
};
|
||||
|
||||
struct CLocalBlockFull
|
||||
{
|
||||
UINT32 Signature;
|
||||
CLocalBlock Header;
|
||||
};
|
||||
|
||||
struct CBlock
|
||||
{
|
||||
CVersion MadeByVersion;
|
||||
CVersion ExtractVersion;
|
||||
UINT16 Flags;
|
||||
UINT16 CompressionMethod;
|
||||
UINT32 Time;
|
||||
UINT32 FileCRC;
|
||||
UINT32 PackSize;
|
||||
UINT32 UnPackSize;
|
||||
UINT16 NameSize;
|
||||
UINT16 ExtraSize;
|
||||
UINT16 CommentSize;
|
||||
UINT16 DiskNumberStart;
|
||||
UINT16 InternalAttributes;
|
||||
UINT32 ExternalAttributes;
|
||||
UINT32 LocalHeaderOffset;
|
||||
};
|
||||
|
||||
struct CBlockFull
|
||||
{
|
||||
UINT32 Signature;
|
||||
CBlock Header;
|
||||
};
|
||||
|
||||
namespace NFlags
|
||||
{
|
||||
const int kNumUsedBits = 4;
|
||||
const int kUsedBitsMask = (1 << kNumUsedBits) - 1;
|
||||
|
||||
const int kEncryptedMask = 1 << 0;
|
||||
const int kDescriptorUsedMask = 1 << 3;
|
||||
|
||||
const int kImplodeDictionarySizeMask = 1 << 1;
|
||||
const int kImplodeLiteralsOnMask = 1 << 2;
|
||||
|
||||
const int kDeflateTypeBitStart = 1;
|
||||
const int kNumDeflateTypeBits = 2;
|
||||
const int kNumDeflateTypes = (1 << kNumDeflateTypeBits);
|
||||
const int kDeflateTypeMask = (1 << kNumDeflateTypeBits) - 1;
|
||||
}
|
||||
|
||||
namespace NHostOS
|
||||
{
|
||||
enum EEnum
|
||||
{
|
||||
kFAT = 0, // filesystem used by MS-DOS, OS/2, Win32
|
||||
// pkzip 2.50 (FAT / VFAT / FAT32 file systems)
|
||||
kAMIGA = 1,
|
||||
kVMS = 2, // VAX/VMS
|
||||
kUnix = 3,
|
||||
kVM_CMS = 4,
|
||||
kAtari = 5, // what if it's a minix filesystem? [cjh]
|
||||
kHPFS = 6, // filesystem used by OS/2 (and NT 3.x)
|
||||
kMac = 7,
|
||||
kZ_System = 8,
|
||||
kCPM = 9,
|
||||
kTOPS20 = 10, // pkzip 2.50 NTFS
|
||||
kNTFS = 11, // filesystem used by Windows NT
|
||||
kQDOS = 12, // SMS/QDOS
|
||||
kAcorn = 13, // Archimedes Acorn RISC OS
|
||||
kVFAT = 14, // filesystem used by Windows 95, NT
|
||||
kMVS = 15,
|
||||
kBeOS = 16, // hybrid POSIX/database filesystem
|
||||
// BeBOX or PowerMac
|
||||
kTandem = 17,
|
||||
kTHEOS = 18
|
||||
};
|
||||
// const int kNumHostSystems = 19;
|
||||
}
|
||||
namespace NUnixAttribute
|
||||
{
|
||||
const UINT32 kIFMT = 0170000; /* Unix file type mask */
|
||||
|
||||
const UINT32 kIFDIR = 0040000; /* Unix directory */
|
||||
const UINT32 kIFREG = 0100000; /* Unix regular file */
|
||||
const UINT32 kIFSOCK = 0140000; /* Unix socket (BSD, not SysV or Amiga) */
|
||||
const UINT32 kIFLNK = 0120000; /* Unix symbolic link (not SysV, Amiga) */
|
||||
const UINT32 kIFBLK = 0060000; /* Unix block special (not Amiga) */
|
||||
const UINT32 kIFCHR = 0020000; /* Unix character special (not Amiga) */
|
||||
const UINT32 kIFIFO = 0010000; /* Unix fifo (BCC, not MSC or Amiga) */
|
||||
|
||||
const UINT32 kISUID = 04000; /* Unix set user id on execution */
|
||||
const UINT32 kISGID = 02000; /* Unix set group id on execution */
|
||||
const UINT32 kISVTX = 01000; /* Unix directory permissions control */
|
||||
const UINT32 kENFMT = kISGID; /* Unix record locking enforcement flag */
|
||||
const UINT32 kIRWXU = 00700; /* Unix read, write, execute: owner */
|
||||
const UINT32 kIRUSR = 00400; /* Unix read permission: owner */
|
||||
const UINT32 kIWUSR = 00200; /* Unix write permission: owner */
|
||||
const UINT32 kIXUSR = 00100; /* Unix execute permission: owner */
|
||||
const UINT32 kIRWXG = 00070; /* Unix read, write, execute: group */
|
||||
const UINT32 kIRGRP = 00040; /* Unix read permission: group */
|
||||
const UINT32 kIWGRP = 00020; /* Unix write permission: group */
|
||||
const UINT32 kIXGRP = 00010; /* Unix execute permission: group */
|
||||
const UINT32 kIRWXO = 00007; /* Unix read, write, execute: other */
|
||||
const UINT32 kIROTH = 00004; /* Unix read permission: other */
|
||||
const UINT32 kIWOTH = 00002; /* Unix write permission: other */
|
||||
const UINT32 kIXOTH = 00001; /* Unix execute permission: other */
|
||||
}
|
||||
|
||||
namespace NAmigaAttribute
|
||||
{
|
||||
const UINT32 kIFMT = 06000; /* Amiga file type mask */
|
||||
const UINT32 kIFDIR = 04000; /* Amiga directory */
|
||||
const UINT32 kIFREG = 02000; /* Amiga regular file */
|
||||
const UINT32 kIHIDDEN = 00200; /* to be supported in AmigaDOS 3.x */
|
||||
const UINT32 kISCRIPT = 00100; /* executable script (text command file) */
|
||||
const UINT32 kIPURE = 00040; /* allow loading into resident memory */
|
||||
const UINT32 kIARCHIVE = 00020; /* not modified since bit was last set */
|
||||
const UINT32 kIREAD = 00010; /* can be opened for reading */
|
||||
const UINT32 kIWRITE = 00004; /* can be opened for writing */
|
||||
const UINT32 kIEXECUTE = 00002; /* executable image, a loadable runfile */
|
||||
const UINT32 kIDELETE = 00001; /* can be deleted */
|
||||
}
|
||||
}
|
||||
|
||||
#pragma pack(pop)
|
||||
#pragma pack(pop, PragmaZipHeaders)
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
376
7zip/Archive/Zip/ZipIn.cpp
Executable file
376
7zip/Archive/Zip/ZipIn.cpp
Executable file
@@ -0,0 +1,376 @@
|
||||
// Archive/ZipIn.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "ZipIn.h"
|
||||
#include "Windows/Defs.h"
|
||||
#include "Common/StringConvert.h"
|
||||
#include "Common/DynamicBuffer.h"
|
||||
#include "../../Common/LimitedStreams.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NZip {
|
||||
|
||||
// static const char kEndOfString = '\0';
|
||||
|
||||
bool CInArchive::Open(IInStream *inStream, const UINT64 *searchHeaderSizeLimit)
|
||||
{
|
||||
m_Stream = inStream;
|
||||
if(m_Stream->Seek(0, STREAM_SEEK_CUR, &m_StreamStartPosition) != S_OK)
|
||||
return false;
|
||||
m_Position = m_StreamStartPosition;
|
||||
return FindAndReadMarker(searchHeaderSizeLimit);
|
||||
}
|
||||
|
||||
void CInArchive::Close()
|
||||
{
|
||||
m_Stream.Release();
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
// Markers
|
||||
|
||||
inline bool TestMarkerCandidate(const void *testBytes, UINT32 &value)
|
||||
{
|
||||
value = *((const UINT32 *)(testBytes));
|
||||
return (value == NSignature::kLocalFileHeader) ||
|
||||
(value == NSignature::kEndOfCentralDir);
|
||||
}
|
||||
|
||||
bool CInArchive::FindAndReadMarker(const UINT64 *searchHeaderSizeLimit)
|
||||
{
|
||||
m_ArchiveInfo.StartPosition = 0;
|
||||
m_Position = m_StreamStartPosition;
|
||||
if(m_Stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL) != S_OK)
|
||||
return false;
|
||||
|
||||
BYTE marker[NSignature::kMarkerSize];
|
||||
UINT32 processedSize;
|
||||
ReadBytes(marker, NSignature::kMarkerSize, &processedSize);
|
||||
if(processedSize != NSignature::kMarkerSize)
|
||||
return false;
|
||||
if (TestMarkerCandidate(marker, m_Signature))
|
||||
return true;
|
||||
|
||||
CByteDynamicBuffer dynamicBuffer;
|
||||
static const UINT32 kSearchMarkerBufferSize = 0x10000;
|
||||
dynamicBuffer.EnsureCapacity(kSearchMarkerBufferSize);
|
||||
BYTE *buffer = dynamicBuffer;
|
||||
UINT32 numBytesPrev = NSignature::kMarkerSize - 1;
|
||||
memmove(buffer, marker + 1, numBytesPrev);
|
||||
UINT64 curTestPos = m_StreamStartPosition + 1;
|
||||
while(true)
|
||||
{
|
||||
if (searchHeaderSizeLimit != NULL)
|
||||
if (curTestPos - m_StreamStartPosition > *searchHeaderSizeLimit)
|
||||
return false;
|
||||
UINT32 numReadBytes = kSearchMarkerBufferSize - numBytesPrev;
|
||||
ReadBytes(buffer + numBytesPrev, numReadBytes, &processedSize);
|
||||
UINT32 numBytesInBuffer = numBytesPrev + processedSize;
|
||||
if (numBytesInBuffer < NSignature::kMarkerSize)
|
||||
return false;
|
||||
UINT32 numTests = numBytesInBuffer - NSignature::kMarkerSize + 1;
|
||||
for(UINT32 pos = 0; pos < numTests; pos++, curTestPos++)
|
||||
{
|
||||
if (TestMarkerCandidate(buffer + pos, m_Signature))
|
||||
{
|
||||
m_ArchiveInfo.StartPosition = curTestPos;
|
||||
m_Position = curTestPos + NSignature::kMarkerSize;
|
||||
if(m_Stream->Seek(m_Position, STREAM_SEEK_SET, NULL) != S_OK)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
numBytesPrev = numBytesInBuffer - numTests;
|
||||
memmove(buffer, buffer + numTests, numBytesPrev);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
// Read Operations
|
||||
|
||||
HRESULT CInArchive::ReadBytes(void *data, UINT32 size, UINT32 *processedSize)
|
||||
{
|
||||
UINT32 realProcessedSize;
|
||||
HRESULT result = m_Stream->Read(data, size, &realProcessedSize);
|
||||
if(processedSize != NULL)
|
||||
*processedSize = realProcessedSize;
|
||||
IncreasePositionValue(realProcessedSize);
|
||||
return result;
|
||||
}
|
||||
|
||||
void CInArchive::IncreasePositionValue(UINT64 addValue)
|
||||
{
|
||||
m_Position += addValue;
|
||||
}
|
||||
|
||||
void CInArchive::IncreaseRealPosition(UINT64 addValue)
|
||||
{
|
||||
if(m_Stream->Seek(addValue, STREAM_SEEK_CUR, &m_Position) != S_OK)
|
||||
throw CInArchiveException(CInArchiveException::kSeekStreamError);
|
||||
}
|
||||
|
||||
bool CInArchive::ReadBytesAndTestSize(void *data, UINT32 size)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////
|
||||
// Read headers
|
||||
|
||||
bool CInArchive::ReadSignature(UINT32 &signature)
|
||||
{
|
||||
return ReadBytesAndTestSize(&signature, sizeof(signature));
|
||||
}
|
||||
|
||||
AString CInArchive::ReadFileName(UINT32 nameSize)
|
||||
{
|
||||
if (nameSize == 0)
|
||||
return AString();
|
||||
SafeReadBytes(m_NameBuffer.GetBuffer(nameSize), nameSize);
|
||||
m_NameBuffer.ReleaseBuffer(nameSize);
|
||||
return m_NameBuffer;
|
||||
}
|
||||
|
||||
void CInArchive::GetArchiveInfo(CInArchiveInfo &archiveInfo) const
|
||||
{
|
||||
archiveInfo = m_ArchiveInfo;
|
||||
}
|
||||
|
||||
void CInArchive::ThrowIncorrectArchiveException()
|
||||
{
|
||||
throw CInArchiveException(CInArchiveException::kIncorrectArchive);
|
||||
}
|
||||
|
||||
HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *progress)
|
||||
{
|
||||
// m_Signature must be kLocalFileHeaderSignature or
|
||||
// kEndOfCentralDirSignature
|
||||
// m_Position points to next byte after signature
|
||||
|
||||
items.Clear();
|
||||
|
||||
if (progress != 0)
|
||||
{
|
||||
UINT64 numItems = items.Size();
|
||||
RINOK(progress->SetCompleted(&numItems));
|
||||
}
|
||||
// FSeek -= sizeof(UINT32); // atention it's not real position
|
||||
|
||||
while(m_Signature == NSignature::kLocalFileHeader)
|
||||
{
|
||||
// FSeek points to next byte after signature
|
||||
NFileHeader::CLocalBlock localHeader;
|
||||
CItemEx itemInfo;
|
||||
itemInfo.LocalHeaderPosition =
|
||||
UINT32(m_Position - m_StreamStartPosition - sizeof(UINT32)); // points to signature;
|
||||
SafeReadBytes(&localHeader, sizeof(localHeader));
|
||||
UINT32 fileNameSize = localHeader.NameSize;
|
||||
itemInfo.Name = ReadFileName(fileNameSize);
|
||||
/*
|
||||
if (!NItemName::IsNameLegal(itemInfo.Name))
|
||||
ThrowIncorrectArchiveException();
|
||||
*/
|
||||
itemInfo.ExtractVersion.Version = localHeader.ExtractVersion.Version;
|
||||
itemInfo.ExtractVersion.HostOS = localHeader.ExtractVersion.HostOS;
|
||||
itemInfo.Flags = localHeader.Flags & NFileHeader::NFlags::kUsedBitsMask;
|
||||
itemInfo.CompressionMethod = localHeader.CompressionMethod;
|
||||
itemInfo.Time = localHeader.Time;
|
||||
itemInfo.FileCRC = localHeader.FileCRC;
|
||||
itemInfo.PackSize = localHeader.PackSize;
|
||||
itemInfo.UnPackSize = localHeader.UnPackSize;
|
||||
|
||||
itemInfo.LocalExtraSize = localHeader.ExtraSize;
|
||||
itemInfo.FileHeaderWithNameSize = sizeof(UINT32) + sizeof(localHeader) + fileNameSize;
|
||||
|
||||
IncreaseRealPosition(localHeader.ExtraSize);
|
||||
|
||||
if (itemInfo.HasDescriptor())
|
||||
{
|
||||
const int kBufferSize = (1 << 12);
|
||||
BYTE buffer[kBufferSize];
|
||||
UINT32 numBytesInBuffer = 0;
|
||||
UINT32 packedSize = 0;
|
||||
|
||||
bool descriptorWasFound = false;
|
||||
while (true)
|
||||
{
|
||||
UINT32 processedSize;
|
||||
RINOK(ReadBytes(buffer + numBytesInBuffer,
|
||||
kBufferSize - numBytesInBuffer, &processedSize));
|
||||
numBytesInBuffer += processedSize;
|
||||
if (numBytesInBuffer < sizeof(NFileHeader::CDataDescriptor))
|
||||
ThrowIncorrectArchiveException();
|
||||
int i;
|
||||
for (i = 0; i <= numBytesInBuffer -
|
||||
sizeof(NFileHeader::CDataDescriptor); i++)
|
||||
{
|
||||
const NFileHeader::CDataDescriptor &descriptor =
|
||||
*(NFileHeader::CDataDescriptor *)(buffer + i);
|
||||
if (descriptor.Signature == NSignature::kDataDescriptor &&
|
||||
descriptor.PackSize == packedSize + i)
|
||||
{
|
||||
descriptorWasFound = true;
|
||||
itemInfo.FileCRC = descriptor.FileCRC;
|
||||
itemInfo.PackSize = descriptor.PackSize;
|
||||
itemInfo.UnPackSize = descriptor.UnPackSize;
|
||||
IncreaseRealPosition(INT64(INT32(0 - (numBytesInBuffer - i -
|
||||
sizeof(NFileHeader::CDataDescriptor)))));
|
||||
break;
|
||||
};
|
||||
}
|
||||
if (descriptorWasFound)
|
||||
break;
|
||||
packedSize += i;
|
||||
int j;
|
||||
for (j = 0; i < numBytesInBuffer; i++, j++)
|
||||
buffer[j] = buffer[i];
|
||||
numBytesInBuffer = j;
|
||||
}
|
||||
}
|
||||
else
|
||||
IncreaseRealPosition(localHeader.PackSize);
|
||||
|
||||
items.Add(itemInfo);
|
||||
if (progress != 0)
|
||||
{
|
||||
UINT64 numItems = items.Size();
|
||||
RINOK(progress->SetCompleted(&numItems));
|
||||
}
|
||||
if (!ReadSignature(m_Signature))
|
||||
break;
|
||||
}
|
||||
UINT32 centralDirectorySize = 0;
|
||||
UINT64 centralDirectoryStartOffset = m_Position - sizeof(UINT32);
|
||||
for(int i = 0; i < items.Size(); i++)
|
||||
{
|
||||
if (progress != 0)
|
||||
{
|
||||
UINT64 numItems = items.Size();
|
||||
RINOK(progress->SetCompleted(&numItems));
|
||||
}
|
||||
// if(m_Signature == NSignature::kEndOfCentralDir)
|
||||
// break;
|
||||
if(m_Signature != NSignature::kCentralFileHeader)
|
||||
ThrowIncorrectArchiveException();
|
||||
|
||||
NFileHeader::CBlock header;
|
||||
SafeReadBytes(&header, sizeof(header));
|
||||
UINT32 localHeaderOffset = header.LocalHeaderOffset;
|
||||
header.Flags &= NFileHeader::NFlags::kUsedBitsMask;
|
||||
|
||||
int index;
|
||||
int left = 0, right = items.Size();
|
||||
while(true)
|
||||
{
|
||||
if (left >= right)
|
||||
ThrowIncorrectArchiveException();
|
||||
index = (left + right) / 2;
|
||||
UINT32 position = items[index].LocalHeaderPosition;
|
||||
if (localHeaderOffset == position)
|
||||
break;
|
||||
if (localHeaderOffset < position)
|
||||
right = index;
|
||||
else
|
||||
left = index + 1;
|
||||
}
|
||||
CItemEx &itemInfo = items[index];
|
||||
itemInfo.MadeByVersion.Version = header.MadeByVersion.Version;
|
||||
itemInfo.MadeByVersion.HostOS = header.MadeByVersion.HostOS;
|
||||
|
||||
CVersion centalHeaderExtractVersion;
|
||||
centalHeaderExtractVersion.Version = header.ExtractVersion.Version;
|
||||
centalHeaderExtractVersion.HostOS = header.ExtractVersion.HostOS;
|
||||
|
||||
if (
|
||||
// itemInfo.ExtractVersion != centalHeaderExtractVersion ||
|
||||
itemInfo.Flags != header.Flags ||
|
||||
itemInfo.CompressionMethod != header.CompressionMethod ||
|
||||
// itemInfo.Time != header.Time ||
|
||||
itemInfo.FileCRC != header.FileCRC ||
|
||||
itemInfo.PackSize != header.PackSize ||
|
||||
itemInfo.UnPackSize != header.UnPackSize)
|
||||
ThrowIncorrectArchiveException();
|
||||
|
||||
AString centralName = ReadFileName(header.NameSize);
|
||||
if (itemInfo.Name.Length() != centralName.Length())
|
||||
ThrowIncorrectArchiveException(); // test it maybe better compare names
|
||||
itemInfo.Name = centralName;
|
||||
|
||||
itemInfo.CentralExtraPosition = m_Position;
|
||||
itemInfo.CentralExtraSize = header.ExtraSize;
|
||||
itemInfo.CommentSize = header.CommentSize;
|
||||
if (header.DiskNumberStart != 0)
|
||||
throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported);
|
||||
itemInfo.InternalAttributes = header.InternalAttributes;
|
||||
itemInfo.ExternalAttributes = header.ExternalAttributes;
|
||||
|
||||
// May be these strings must be deleted
|
||||
if (itemInfo.IsDirectory())
|
||||
{
|
||||
// if (itemInfo.PackSize != 0 /* || itemInfo.UnPackSize != 0 */)
|
||||
// ThrowIncorrectArchiveException();
|
||||
itemInfo.UnPackSize = 0;
|
||||
}
|
||||
|
||||
UINT32 currentRecordSize = sizeof(UINT32) + sizeof(header) +
|
||||
header.NameSize + header.ExtraSize + header.CommentSize;
|
||||
|
||||
centralDirectorySize += currentRecordSize;
|
||||
IncreaseRealPosition(header.ExtraSize + header.CommentSize);
|
||||
if (!ReadSignature(m_Signature))
|
||||
break;
|
||||
}
|
||||
if(m_Signature != NSignature::kEndOfCentralDir)
|
||||
ThrowIncorrectArchiveException();
|
||||
CEndOfCentralDirectoryRecord endOfCentralDirHeader;
|
||||
SafeReadBytes(&endOfCentralDirHeader, sizeof(endOfCentralDirHeader));
|
||||
if (endOfCentralDirHeader.ThisDiskNumber != 0 ||
|
||||
endOfCentralDirHeader.StartCentralDirectoryDiskNumber != 0)
|
||||
throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported);
|
||||
if (endOfCentralDirHeader.NumEntriesInCentaralDirectoryOnThisDisk != ((UINT16)items.Size()) ||
|
||||
endOfCentralDirHeader.NumEntriesInCentaralDirectory != ((UINT16)items.Size()) ||
|
||||
endOfCentralDirHeader.CentralDirectorySize != centralDirectorySize ||
|
||||
(endOfCentralDirHeader.CentralDirectoryStartOffset != centralDirectoryStartOffset &&
|
||||
(!items.IsEmpty())))
|
||||
ThrowIncorrectArchiveException();
|
||||
|
||||
m_ArchiveInfo.CommentPosition = m_Position;
|
||||
m_ArchiveInfo.CommentSize = endOfCentralDirHeader.CommentSize;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
ISequentialInStream* CInArchive::CreateLimitedStream(UINT64 position, UINT64 size)
|
||||
{
|
||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
||||
CMyComPtr<ISequentialInStream> inStream(streamSpec);
|
||||
SeekInArchive(position);
|
||||
streamSpec->Init(m_Stream, size);
|
||||
return inStream.Detach();
|
||||
}
|
||||
|
||||
IInStream* CInArchive::CreateStream()
|
||||
{
|
||||
CMyComPtr<IInStream> inStream = m_Stream;
|
||||
return inStream.Detach();
|
||||
}
|
||||
|
||||
bool CInArchive::SeekInArchive(UINT64 position)
|
||||
{
|
||||
UINT64 newPosition;
|
||||
if(m_Stream->Seek(position, STREAM_SEEK_SET, &newPosition) != S_OK)
|
||||
return false;
|
||||
return (newPosition == position);
|
||||
}
|
||||
|
||||
}}
|
||||
84
7zip/Archive/Zip/ZipIn.h
Executable file
84
7zip/Archive/Zip/ZipIn.h
Executable file
@@ -0,0 +1,84 @@
|
||||
// Archive/ZipIn.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ZIP_IN_H
|
||||
#define __ZIP_IN_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "../../IStream.h"
|
||||
|
||||
#include "ZipHeader.h"
|
||||
#include "ZipItemEx.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NZip {
|
||||
|
||||
class CInArchiveException
|
||||
{
|
||||
public:
|
||||
enum CCauseType
|
||||
{
|
||||
kUnexpectedEndOfArchive = 0,
|
||||
kArchiceHeaderCRCError,
|
||||
kFileHeaderCRCError,
|
||||
kIncorrectArchive,
|
||||
kDataDescroptorsAreNotSupported,
|
||||
kMultiVolumeArchiveAreNotSupported,
|
||||
kReadStreamError,
|
||||
kSeekStreamError
|
||||
}
|
||||
Cause;
|
||||
CInArchiveException(CCauseType cause): Cause(cause) {}
|
||||
};
|
||||
|
||||
class CInArchiveInfo
|
||||
{
|
||||
public:
|
||||
UINT64 StartPosition;
|
||||
UINT64 CommentPosition;
|
||||
UINT16 CommentSize;
|
||||
bool IsCommented() const { return (CommentSize != 0); };
|
||||
};
|
||||
|
||||
class CProgressVirt
|
||||
{
|
||||
public:
|
||||
STDMETHOD(SetCompleted)(const UINT64 *numFiles) PURE;
|
||||
};
|
||||
|
||||
class CInArchive
|
||||
{
|
||||
CMyComPtr<IInStream> m_Stream;
|
||||
UINT32 m_Signature;
|
||||
UINT64 m_StreamStartPosition;
|
||||
UINT64 m_Position;
|
||||
CInArchiveInfo m_ArchiveInfo;
|
||||
AString m_NameBuffer;
|
||||
|
||||
bool FindAndReadMarker(const UINT64 *searchHeaderSizeLimit);
|
||||
bool ReadSignature(UINT32 &signature);
|
||||
AString ReadFileName(UINT32 nameSize);
|
||||
|
||||
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 IncreaseRealPosition(UINT64 addValue);
|
||||
void ThrowIncorrectArchiveException();
|
||||
|
||||
public:
|
||||
HRESULT ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *progress);
|
||||
bool Open(IInStream *inStream, const UINT64 *searchHeaderSizeLimit);
|
||||
void Close();
|
||||
void GetArchiveInfo(CInArchiveInfo &archiveInfo) const;
|
||||
void DirectGetBytes(void *data, UINT32 num);
|
||||
bool SeekInArchive(UINT64 position);
|
||||
ISequentialInStream *CreateLimitedStream(UINT64 position, UINT64 size);
|
||||
IInStream* CreateStream();
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
132
7zip/Archive/Zip/ZipItem.cpp
Executable file
132
7zip/Archive/Zip/ZipItem.cpp
Executable file
@@ -0,0 +1,132 @@
|
||||
// Archive/ZipItem.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "ZipHeader.h"
|
||||
#include "ZipItem.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NZip {
|
||||
|
||||
bool operator==(const CVersion &v1, const CVersion &v2)
|
||||
{
|
||||
return (v1.Version == v2.Version) && (v1.HostOS == v2.HostOS);
|
||||
}
|
||||
|
||||
bool operator!=(const CVersion &v1, const CVersion &v2)
|
||||
{
|
||||
return !(v1 == v2);
|
||||
}
|
||||
|
||||
bool CItem::IsEncrypted() const
|
||||
{ return (Flags & NFileHeader::NFlags::kEncryptedMask) != 0; }
|
||||
bool CItem::HasDescriptor() const
|
||||
{ return (Flags & NFileHeader::NFlags::kDescriptorUsedMask) != 0; }
|
||||
|
||||
bool CItem::IsImplodeBigDictionary() const
|
||||
{
|
||||
if (CompressionMethod != NFileHeader::NCompressionMethod::kImploded)
|
||||
throw 12312212;
|
||||
return (Flags & NFileHeader::NFlags::kImplodeDictionarySizeMask) != 0;
|
||||
}
|
||||
|
||||
bool CItem::IsImplodeLiteralsOn() const
|
||||
{
|
||||
if (CompressionMethod != NFileHeader::NCompressionMethod::kImploded)
|
||||
throw 12312213;
|
||||
return (Flags & NFileHeader::NFlags::kImplodeLiteralsOnMask) != 0;
|
||||
}
|
||||
|
||||
static const char *kUnknownAttributes = "Unknown file attributes";
|
||||
|
||||
bool CItem::IsDirectory() const
|
||||
{
|
||||
if (!Name.IsEmpty())
|
||||
{
|
||||
#ifdef WIN32
|
||||
LPCSTR prev = CharPrevExA(GetCodePage(), Name, &Name[Name.Length()], 0);
|
||||
if (*prev == '/')
|
||||
return true;
|
||||
#else
|
||||
if (Name[Name.Length() - 1) == '/')
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
WORD highAttributes = WORD((ExternalAttributes >> 16 ) & 0xFFFF);
|
||||
switch(MadeByVersion.HostOS)
|
||||
{
|
||||
case NFileHeader::NHostOS::kAMIGA:
|
||||
switch (highAttributes & NFileHeader::NAmigaAttribute::kIFMT)
|
||||
{
|
||||
case NFileHeader::NAmigaAttribute::kIFDIR:
|
||||
return true;
|
||||
case NFileHeader::NAmigaAttribute::kIFREG:
|
||||
return false;
|
||||
default:
|
||||
return false; // change it throw kUnknownAttributes;
|
||||
}
|
||||
case NFileHeader::NHostOS::kFAT:
|
||||
case NFileHeader::NHostOS::kNTFS:
|
||||
case NFileHeader::NHostOS::kHPFS:
|
||||
case NFileHeader::NHostOS::kVFAT:
|
||||
return ((ExternalAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0);
|
||||
case NFileHeader::NHostOS::kAtari:
|
||||
case NFileHeader::NHostOS::kMac:
|
||||
case NFileHeader::NHostOS::kVMS:
|
||||
case NFileHeader::NHostOS::kVM_CMS:
|
||||
case NFileHeader::NHostOS::kAcorn:
|
||||
case NFileHeader::NHostOS::kMVS:
|
||||
return false; // change it throw kUnknownAttributes;
|
||||
default:
|
||||
/*
|
||||
switch (highAttributes & NFileHeader::NUnixAttribute::kIFMT)
|
||||
{
|
||||
case NFileHeader::NUnixAttribute::kIFDIR:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
UINT32 CItem::GetWinAttributes() const
|
||||
{
|
||||
DWORD winAttributes;
|
||||
switch(MadeByVersion.HostOS)
|
||||
{
|
||||
case NFileHeader::NHostOS::kFAT:
|
||||
case NFileHeader::NHostOS::kNTFS:
|
||||
winAttributes = ExternalAttributes;
|
||||
break;
|
||||
default:
|
||||
winAttributes = 0; // must be converted from unix value;;
|
||||
}
|
||||
if (IsDirectory()) // test it;
|
||||
winAttributes |= FILE_ATTRIBUTE_DIRECTORY;
|
||||
return winAttributes;
|
||||
}
|
||||
|
||||
void CItem::ClearFlags()
|
||||
{ Flags = 0; }
|
||||
|
||||
void CItem::SetFlagBits(int startBitNumber, int numBits, int value)
|
||||
{
|
||||
WORD mask = ((1 << numBits) - 1) << startBitNumber;
|
||||
Flags &= ~mask;
|
||||
Flags |= value << startBitNumber;
|
||||
}
|
||||
|
||||
void CItem::SetBitMask(int bitMask, bool enable)
|
||||
{
|
||||
if(enable)
|
||||
Flags |= bitMask;
|
||||
else
|
||||
Flags &= ~bitMask;
|
||||
}
|
||||
|
||||
void CItem::SetEncrypted(bool encrypted)
|
||||
{ SetBitMask(NFileHeader::NFlags::kEncryptedMask, encrypted); }
|
||||
|
||||
}}
|
||||
72
7zip/Archive/Zip/ZipItem.h
Executable file
72
7zip/Archive/Zip/ZipItem.h
Executable file
@@ -0,0 +1,72 @@
|
||||
// Archive/ZipItem.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARCHIVE_ZIP_ITEM_H
|
||||
#define __ARCHIVE_ZIP_ITEM_H
|
||||
|
||||
#include "Common/Types.h"
|
||||
#include "Common/String.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NZip {
|
||||
|
||||
struct CVersion
|
||||
{
|
||||
BYTE Version;
|
||||
BYTE HostOS;
|
||||
};
|
||||
|
||||
bool operator==(const CVersion &v1, const CVersion &v2);
|
||||
bool operator!=(const CVersion &v1, const CVersion &v2);
|
||||
|
||||
class CItem
|
||||
{
|
||||
public:
|
||||
CVersion MadeByVersion;
|
||||
CVersion ExtractVersion;
|
||||
UINT16 Flags;
|
||||
UINT16 CompressionMethod;
|
||||
UINT32 Time;
|
||||
UINT32 FileCRC;
|
||||
UINT32 PackSize;
|
||||
UINT32 UnPackSize;
|
||||
UINT16 InternalAttributes;
|
||||
UINT32 ExternalAttributes;
|
||||
|
||||
AString Name;
|
||||
|
||||
UINT32 LocalHeaderPosition;
|
||||
UINT16 LocalExtraSize;
|
||||
UINT16 CentralExtraSize;
|
||||
UINT16 CommentSize;
|
||||
|
||||
bool IsEncrypted() const;
|
||||
|
||||
bool IsImplodeBigDictionary() const;
|
||||
bool IsImplodeLiteralsOn() const;
|
||||
|
||||
bool IsDirectory() const;
|
||||
bool IgnoreItem() const { return false; }
|
||||
UINT32 GetWinAttributes() const;
|
||||
|
||||
bool HasDescriptor() const;
|
||||
|
||||
#ifdef WIN32
|
||||
WORD GetCodePage() const
|
||||
{ return (MadeByVersion.HostOS == NFileHeader::NHostOS::kFAT) ? CP_OEMCP : CP_ACP; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
void SetFlagBits(int startBitNumber, int numBits, int value);
|
||||
void SetBitMask(int bitMask, bool enable);
|
||||
public:
|
||||
void ClearFlags();
|
||||
void SetEncrypted(bool encrypted);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
47
7zip/Archive/Zip/ZipItemEx.h
Executable file
47
7zip/Archive/Zip/ZipItemEx.h
Executable file
@@ -0,0 +1,47 @@
|
||||
// Archive/ZipItemEx.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARCHIVE_ZIP_ITEMEX_H
|
||||
#define __ARCHIVE_ZIP_ITEMEX_H
|
||||
|
||||
#include "Common/Vector.h"
|
||||
|
||||
#include "ZipHeader.h"
|
||||
#include "ZipItem.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NZip {
|
||||
|
||||
class CItemEx: public CItem
|
||||
{
|
||||
public:
|
||||
UINT16 FileHeaderWithNameSize;
|
||||
UINT64 CentralExtraPosition;
|
||||
|
||||
UINT32 GetLocalFullSize() const
|
||||
{ return FileHeaderWithNameSize + LocalExtraSize + PackSize +
|
||||
(HasDescriptor() ? sizeof(NFileHeader::CDataDescriptor) : 0); };
|
||||
|
||||
UINT32 GetCentralExtraPlusCommentSize() const
|
||||
{ return CentralExtraSize + CommentSize; };
|
||||
|
||||
UINT64 GetCommentPosition() const
|
||||
{ return CentralExtraPosition + CentralExtraSize; };
|
||||
|
||||
bool IsCommented() const
|
||||
{ return CommentSize != 0; };
|
||||
|
||||
UINT64 GetLocalExtraPosition() const
|
||||
{ return LocalHeaderPosition + FileHeaderWithNameSize; };
|
||||
|
||||
UINT64 GetDataPosition() const
|
||||
{ return GetLocalExtraPosition() + LocalExtraSize; };
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
134
7zip/Archive/Zip/ZipOut.cpp
Executable file
134
7zip/Archive/Zip/ZipOut.cpp
Executable file
@@ -0,0 +1,134 @@
|
||||
// ZipOut.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "ZipOut.h"
|
||||
#include "Common/StringConvert.h"
|
||||
#include "Common/CRC.h"
|
||||
#include "../../Common/OffsetStream.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NZip {
|
||||
|
||||
void COutArchive::Create(IOutStream *outStream)
|
||||
{
|
||||
m_Stream = outStream;
|
||||
m_BasePosition = 0;
|
||||
}
|
||||
|
||||
void COutArchive::MoveBasePosition(UINT32 distanceToMove)
|
||||
{
|
||||
m_BasePosition += distanceToMove; // test overflow
|
||||
}
|
||||
|
||||
void COutArchive::PrepareWriteCompressedData(UINT16 fileNameLength)
|
||||
{
|
||||
m_LocalFileHeaderSize = sizeof(NFileHeader::CLocalBlockFull) + fileNameLength;
|
||||
}
|
||||
|
||||
void COutArchive::WriteBytes(const void *buffer, UINT32 size)
|
||||
{
|
||||
UINT32 processedSize;
|
||||
if(m_Stream->Write(buffer, size, &processedSize) != S_OK)
|
||||
throw 0;
|
||||
if(processedSize != size)
|
||||
throw 0;
|
||||
m_BasePosition += size;
|
||||
}
|
||||
|
||||
void COutArchive::WriteLocalHeader(const CItem &item)
|
||||
{
|
||||
NFileHeader::CLocalBlockFull fileHeader;
|
||||
fileHeader.Signature = NSignature::kLocalFileHeader;
|
||||
NFileHeader::CLocalBlock &header = fileHeader.Header;
|
||||
|
||||
header.ExtractVersion.HostOS = item.ExtractVersion.HostOS;
|
||||
header.ExtractVersion.Version = item.ExtractVersion.Version;
|
||||
header.Flags = item.Flags;
|
||||
header.CompressionMethod = item.CompressionMethod;
|
||||
header.Time = item.Time;
|
||||
header.FileCRC = item.FileCRC;
|
||||
header.PackSize = item.PackSize;
|
||||
header.UnPackSize = item.UnPackSize;
|
||||
|
||||
header.NameSize = item.Name.Length();
|
||||
header.ExtraSize = item.LocalExtraSize; // test it;
|
||||
|
||||
m_Stream->Seek(m_BasePosition, STREAM_SEEK_SET, NULL);
|
||||
WriteBytes(&fileHeader, sizeof(fileHeader));
|
||||
WriteBytes((const char *)item.Name, header.NameSize);
|
||||
MoveBasePosition(header.ExtraSize + header.PackSize);
|
||||
m_Stream->Seek(m_BasePosition, STREAM_SEEK_SET, NULL);
|
||||
}
|
||||
|
||||
void COutArchive::WriteCentralHeader(const CItem &item)
|
||||
{
|
||||
NFileHeader::CBlockFull fileHeader;
|
||||
fileHeader.Signature = NSignature::kCentralFileHeader;
|
||||
NFileHeader::CBlock &header = fileHeader.Header;
|
||||
|
||||
header.MadeByVersion.HostOS = item.MadeByVersion.HostOS;
|
||||
header.MadeByVersion.Version = item.MadeByVersion.Version;
|
||||
header.ExtractVersion.HostOS = item.ExtractVersion.HostOS;
|
||||
header.ExtractVersion.Version = item.ExtractVersion.Version;
|
||||
header.Flags = item.Flags;
|
||||
header.CompressionMethod = item.CompressionMethod;
|
||||
header.Time = item.Time;
|
||||
header.FileCRC = item.FileCRC;
|
||||
header.PackSize = item.PackSize;
|
||||
header.UnPackSize = item.UnPackSize;
|
||||
|
||||
header.NameSize = item.Name.Length();
|
||||
|
||||
header.ExtraSize = item.CentralExtraSize; // test it;
|
||||
header.CommentSize = item.CommentSize;
|
||||
header.DiskNumberStart = 0;
|
||||
header.InternalAttributes = item.InternalAttributes;
|
||||
header.ExternalAttributes = item.ExternalAttributes;
|
||||
header.LocalHeaderOffset = item.LocalHeaderPosition;
|
||||
|
||||
m_Stream->Seek(m_BasePosition, STREAM_SEEK_SET, NULL);
|
||||
WriteBytes(&fileHeader, sizeof(fileHeader));
|
||||
WriteBytes((const char *)item.Name, header.NameSize);
|
||||
}
|
||||
|
||||
void COutArchive::WriteEndOfCentralDir(const COutArchiveInfo &archiveInfo)
|
||||
{
|
||||
CEndOfCentralDirectoryRecordFull fileHeader;
|
||||
fileHeader.Signature = NSignature::kEndOfCentralDir;
|
||||
CEndOfCentralDirectoryRecord &header = fileHeader.Header;
|
||||
|
||||
header.ThisDiskNumber = 0;
|
||||
header.StartCentralDirectoryDiskNumber = 0;
|
||||
|
||||
header.NumEntriesInCentaralDirectoryOnThisDisk = archiveInfo.NumEntriesInCentaralDirectory;
|
||||
header.NumEntriesInCentaralDirectory = archiveInfo.NumEntriesInCentaralDirectory;
|
||||
|
||||
header.CentralDirectorySize = archiveInfo.CentralDirectorySize;
|
||||
header.CentralDirectoryStartOffset = archiveInfo.CentralDirectoryStartOffset;
|
||||
header.CommentSize = archiveInfo.CommentSize;
|
||||
|
||||
m_Stream->Seek(m_BasePosition, STREAM_SEEK_SET, NULL);
|
||||
WriteBytes(&fileHeader, sizeof(fileHeader));
|
||||
}
|
||||
|
||||
void COutArchive::CreateStreamForCompressing(IOutStream **outStream)
|
||||
{
|
||||
COffsetOutStream *streamSpec = new COffsetOutStream;
|
||||
CMyComPtr<IOutStream> tempStream(streamSpec);
|
||||
streamSpec->Init(m_Stream, m_BasePosition + m_LocalFileHeaderSize);
|
||||
*outStream = tempStream.Detach();
|
||||
}
|
||||
|
||||
void COutArchive::SeekToPackedDataPosition()
|
||||
{
|
||||
m_Stream->Seek(m_BasePosition + m_LocalFileHeaderSize, STREAM_SEEK_SET, NULL);
|
||||
}
|
||||
|
||||
void COutArchive::CreateStreamForCopying(ISequentialOutStream **outStream)
|
||||
{
|
||||
CMyComPtr<ISequentialOutStream> tempStream(m_Stream);
|
||||
*outStream = tempStream.Detach();
|
||||
}
|
||||
|
||||
}}
|
||||
53
7zip/Archive/Zip/ZipOut.h
Executable file
53
7zip/Archive/Zip/ZipOut.h
Executable file
@@ -0,0 +1,53 @@
|
||||
// ZipOut.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ZIP_OUT_H
|
||||
#define __ZIP_OUT_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
|
||||
#include "../../IStream.h"
|
||||
|
||||
#include "ZipHeader.h"
|
||||
#include "ZipItem.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NZip {
|
||||
|
||||
class COutArchiveInfo
|
||||
{
|
||||
public:
|
||||
UINT16 NumEntriesInCentaralDirectory;
|
||||
UINT32 CentralDirectorySize;
|
||||
UINT32 CentralDirectoryStartOffset;
|
||||
UINT16 CommentSize;
|
||||
};
|
||||
|
||||
class COutArchive
|
||||
{
|
||||
CMyComPtr<IOutStream> m_Stream;
|
||||
|
||||
UINT32 m_BasePosition;
|
||||
UINT32 m_LocalFileHeaderSize;
|
||||
|
||||
void WriteBytes(const void *buffer, UINT32 size);
|
||||
|
||||
public:
|
||||
void Create(IOutStream *outStream);
|
||||
void MoveBasePosition(UINT32 distanceToMove);
|
||||
UINT32 GetCurrentPosition() const { return m_BasePosition; };
|
||||
void PrepareWriteCompressedData(UINT16 fileNameLength);
|
||||
void WriteLocalHeader(const CItem &item);
|
||||
|
||||
void WriteCentralHeader(const CItem &item);
|
||||
void WriteEndOfCentralDir(const COutArchiveInfo &archiveInfo);
|
||||
|
||||
void CreateStreamForCompressing(IOutStream **outStream);
|
||||
void CreateStreamForCopying(ISequentialOutStream **outStream);
|
||||
void SeekToPackedDataPosition();
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
357
7zip/Archive/Zip/ZipUpdate.cpp
Executable file
357
7zip/Archive/Zip/ZipUpdate.cpp
Executable file
@@ -0,0 +1,357 @@
|
||||
// ZipUpdate.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "ZipUpdate.h"
|
||||
#include "ZipAddCommon.h"
|
||||
#include "ZipOut.h"
|
||||
|
||||
#include "Common/Defs.h"
|
||||
#include "Common/StringConvert.h"
|
||||
#include "Windows/Defs.h"
|
||||
|
||||
#include "../../Common/ProgressUtils.h"
|
||||
#include "../../Common/LimitedStreams.h"
|
||||
#include "../../Compress/Copy/CopyCoder.h"
|
||||
|
||||
#include "../Common/InStreamWithCRC.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace NArchive {
|
||||
namespace NZip {
|
||||
|
||||
static const BYTE kMadeByHostOS = NFileHeader::NHostOS::kFAT;
|
||||
static const BYTE kExtractHostOS = NFileHeader::NHostOS::kFAT;
|
||||
|
||||
static const BYTE kMethodForDirectory = NFileHeader::NCompressionMethod::kStored;
|
||||
static const BYTE kExtractVersionForDirectory = NFileHeader::NCompressionMethod::kStoreExtractVersion;
|
||||
|
||||
static HRESULT CopyBlock(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, ICompressProgressInfo *progress)
|
||||
{
|
||||
CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
|
||||
return copyCoder->Code(inStream, outStream, NULL, NULL, progress);
|
||||
}
|
||||
|
||||
HRESULT CopyBlockToArchive(ISequentialInStream *inStream,
|
||||
COutArchive &outArchive, ICompressProgressInfo *progress)
|
||||
{
|
||||
CMyComPtr<ISequentialOutStream> outStream;
|
||||
outArchive.CreateStreamForCopying(&outStream);
|
||||
return CopyBlock(inStream, outStream, progress);
|
||||
}
|
||||
|
||||
static HRESULT WriteRange(IInStream *inStream,
|
||||
COutArchive &outArchive,
|
||||
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 = CopyBlockToArchive(inStreamLimited, outArchive, compressProgress);
|
||||
currentComplexity += range.Size;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static HRESULT UpdateOneFile(IInStream *inStream,
|
||||
COutArchive &archive,
|
||||
const CCompressionMethodMode &options,
|
||||
CAddCommon &compressor,
|
||||
const CUpdateItem &updateItem,
|
||||
UINT64 ¤tComplexity,
|
||||
IArchiveUpdateCallback *updateCallback,
|
||||
CItemEx &fileHeader)
|
||||
{
|
||||
CMyComPtr<IInStream> fileInStream;
|
||||
RINOK(updateCallback->GetStream(updateItem.IndexInClient, &fileInStream));
|
||||
|
||||
bool isDirectory;
|
||||
UINT32 fileSize = updateItem.Size;
|
||||
fileHeader.UnPackSize = fileSize;
|
||||
|
||||
if (updateItem.NewProperties)
|
||||
{
|
||||
isDirectory = updateItem.IsDirectory;
|
||||
fileHeader.Name = updateItem.Name;
|
||||
fileHeader.ExternalAttributes = updateItem.Attributes;
|
||||
fileHeader.Time = updateItem.Time;
|
||||
}
|
||||
else
|
||||
isDirectory = fileHeader.IsDirectory();
|
||||
|
||||
archive.PrepareWriteCompressedData(fileHeader.Name.Length());
|
||||
|
||||
fileHeader.LocalHeaderPosition = archive.GetCurrentPosition();
|
||||
fileHeader.MadeByVersion.HostOS = kMadeByHostOS;
|
||||
fileHeader.MadeByVersion.Version = NFileHeader::NCompressionMethod::kMadeByProgramVersion;
|
||||
|
||||
fileHeader.ExtractVersion.HostOS = kExtractHostOS;
|
||||
|
||||
fileHeader.InternalAttributes = 0; // test it
|
||||
fileHeader.ClearFlags();
|
||||
if(isDirectory)
|
||||
{
|
||||
fileHeader.ExtractVersion.Version = kExtractVersionForDirectory;
|
||||
fileHeader.CompressionMethod = kMethodForDirectory;
|
||||
|
||||
fileHeader.PackSize = 0;
|
||||
fileHeader.FileCRC = 0; // test it
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
CInStreamWithCRC *inStreamSpec = new CInStreamWithCRC;
|
||||
CMyComPtr<IInStream> inStream(inStreamSpec);
|
||||
inStreamSpec->Init(fileInStream);
|
||||
CCompressingResult compressingResult;
|
||||
CMyComPtr<IOutStream> outStream;
|
||||
archive.CreateStreamForCompressing(&outStream);
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
|
||||
localProgressSpec->Init(updateCallback, true);
|
||||
|
||||
CLocalCompressProgressInfo *localCompressProgressSpec =
|
||||
new CLocalCompressProgressInfo;
|
||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
||||
|
||||
localCompressProgressSpec->Init(localProgress, ¤tComplexity, NULL);
|
||||
|
||||
RINOK(compressor.Compress(inStream, outStream,
|
||||
fileSize, compressProgress, compressingResult));
|
||||
|
||||
fileHeader.PackSize = (UINT32)compressingResult.PackSize;
|
||||
fileHeader.CompressionMethod = compressingResult.Method;
|
||||
fileHeader.ExtractVersion.Version = compressingResult.ExtractVersion;
|
||||
fileHeader.FileCRC = inStreamSpec->GetCRC();
|
||||
fileHeader.UnPackSize = (UINT32)inStreamSpec->GetSize();
|
||||
}
|
||||
}
|
||||
fileHeader.SetEncrypted(options.PasswordIsDefined);
|
||||
fileHeader.CommentSize = (updateItem.Commented) ?
|
||||
WORD(updateItem.CommentRange.Size) : 0;
|
||||
|
||||
fileHeader.LocalExtraSize = 0;
|
||||
fileHeader.CentralExtraSize = 0;
|
||||
|
||||
archive.WriteLocalHeader(fileHeader);
|
||||
currentComplexity += fileSize;
|
||||
return updateCallback->SetOperationResult(
|
||||
NArchive::NUpdate::NOperationResult::kOK);
|
||||
}
|
||||
|
||||
static HRESULT Update2(COutArchive &archive,
|
||||
IInStream *inStream,
|
||||
const CObjectVector<CItemEx> &inputItems,
|
||||
const CObjectVector<CUpdateItem> &updateItems,
|
||||
const CCompressionMethodMode *options,
|
||||
bool commentRangeAssigned,
|
||||
const CUpdateRange &commentRange,
|
||||
IArchiveUpdateCallback *updateCallback)
|
||||
{
|
||||
UINT64 complexity = 0;
|
||||
UINT64 estimatedArchiveSize = (1<<20); // sfx part
|
||||
|
||||
int i;
|
||||
for(i = 0; i < updateItems.Size(); i++)
|
||||
{
|
||||
const CUpdateItem &updateItem = updateItems[i];
|
||||
if (updateItem.NewData)
|
||||
{
|
||||
complexity += updateItem.Size;
|
||||
if (updateItem.Commented)
|
||||
complexity += updateItem.CommentRange.Size;
|
||||
estimatedArchiveSize += updateItem.Name.Length() * 2 + 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
const CItemEx &inputItem = inputItems[updateItem.IndexInArchive];
|
||||
complexity += inputItem.GetLocalFullSize();
|
||||
complexity += inputItem.GetCentralExtraPlusCommentSize();
|
||||
}
|
||||
}
|
||||
|
||||
complexity += updateItems.Size();
|
||||
complexity += updateItems.Size();
|
||||
|
||||
estimatedArchiveSize += complexity;
|
||||
if (estimatedArchiveSize > 0xFFFFFFFF)
|
||||
return E_NOTIMPL;
|
||||
|
||||
if (commentRangeAssigned)
|
||||
complexity += commentRange.Size;
|
||||
|
||||
complexity++; // end of central
|
||||
|
||||
updateCallback->SetTotal(complexity);
|
||||
auto_ptr<CAddCommon> compressor;
|
||||
|
||||
complexity = 0;
|
||||
|
||||
CObjectVector<CItemEx> items;
|
||||
|
||||
for(i = 0; i < updateItems.Size(); i++)
|
||||
{
|
||||
const CUpdateItem &updateItem = updateItems[i];
|
||||
RINOK(updateCallback->SetCompleted(&complexity));
|
||||
|
||||
CItemEx item;
|
||||
if (!updateItem.NewProperties || !updateItem.NewData)
|
||||
item = inputItems[updateItem.IndexInArchive];
|
||||
|
||||
if (updateItem.NewData)
|
||||
{
|
||||
if(compressor.get() == NULL)
|
||||
{
|
||||
compressor = auto_ptr<CAddCommon>(new CAddCommon(*options));
|
||||
}
|
||||
RINOK(UpdateOneFile(inStream, archive, *options,
|
||||
*compressor, updateItem, complexity, updateCallback, item));
|
||||
}
|
||||
else
|
||||
{
|
||||
// item = inputItems[copyIndices[copyIndexIndex++]];
|
||||
if (updateItem.NewProperties)
|
||||
{
|
||||
if (item.HasDescriptor())
|
||||
return E_NOTIMPL;
|
||||
|
||||
// use old name size.
|
||||
// CUpdateRange range(item.GetLocalExtraPosition(), item.LocalExtraSize + item.PackSize);
|
||||
CUpdateRange range(item.GetDataPosition(), item.PackSize);
|
||||
|
||||
// item.ExternalAttributes = updateItem.Attributes;
|
||||
// Test it
|
||||
item.Name = updateItem.Name;
|
||||
item.Time = updateItem.Time;
|
||||
item.CentralExtraSize = 0;
|
||||
item.LocalExtraSize = 0;
|
||||
|
||||
archive.PrepareWriteCompressedData(item.Name.Length());
|
||||
item.LocalHeaderPosition = archive.GetCurrentPosition();
|
||||
archive.SeekToPackedDataPosition();
|
||||
RINOK(WriteRange(inStream, archive, range,
|
||||
updateCallback, complexity));
|
||||
archive.WriteLocalHeader(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
CUpdateRange range(item.LocalHeaderPosition, item.GetLocalFullSize());
|
||||
|
||||
// set new header position
|
||||
item.LocalHeaderPosition = archive.GetCurrentPosition();
|
||||
|
||||
RINOK(WriteRange(inStream, archive, range,
|
||||
updateCallback, complexity));
|
||||
archive.MoveBasePosition(range.Size);
|
||||
}
|
||||
}
|
||||
items.Add(item);
|
||||
complexity++;
|
||||
}
|
||||
DWORD centralDirStartPosition = archive.GetCurrentPosition();
|
||||
for(i = 0; i < items.Size(); i++)
|
||||
{
|
||||
archive.WriteCentralHeader(items[i]);
|
||||
const CUpdateItem &updateItem = updateItems[i];
|
||||
if (updateItem.NewProperties)
|
||||
{
|
||||
if (updateItem.Commented)
|
||||
{
|
||||
const CUpdateRange range = updateItem.CommentRange;
|
||||
RINOK(WriteRange(inStream, archive, range,
|
||||
updateCallback, complexity));
|
||||
archive.MoveBasePosition(range.Size);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const CItemEx item = items[i];
|
||||
CUpdateRange range(item.CentralExtraPosition,
|
||||
item.GetCentralExtraPlusCommentSize());
|
||||
RINOK(WriteRange(inStream, archive, range,
|
||||
updateCallback, complexity));
|
||||
archive.MoveBasePosition(range.Size);
|
||||
}
|
||||
complexity++;
|
||||
}
|
||||
COutArchiveInfo archiveInfo;
|
||||
archiveInfo.NumEntriesInCentaralDirectory = items.Size();
|
||||
archiveInfo.CentralDirectorySize = archive.GetCurrentPosition() -
|
||||
centralDirStartPosition;
|
||||
archiveInfo.CentralDirectoryStartOffset = centralDirStartPosition;
|
||||
archiveInfo.CommentSize = commentRangeAssigned ? WORD(commentRange.Size) : 0;
|
||||
archive.WriteEndOfCentralDir(archiveInfo);
|
||||
if (commentRangeAssigned)
|
||||
RINOK(WriteRange(inStream, archive, commentRange,
|
||||
updateCallback, complexity));
|
||||
complexity++; // end of central
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT Update(
|
||||
const CObjectVector<CItemEx> &inputItems,
|
||||
const CObjectVector<CUpdateItem> &updateItems,
|
||||
IOutStream *outStream,
|
||||
CInArchive *inArchive,
|
||||
CCompressionMethodMode *compressionMethodMode,
|
||||
IArchiveUpdateCallback *updateCallback)
|
||||
{
|
||||
DWORD startBlockSize;
|
||||
bool commentRangeAssigned;
|
||||
CUpdateRange commentRange;
|
||||
if(inArchive != 0)
|
||||
{
|
||||
CInArchiveInfo archiveInfo;
|
||||
inArchive->GetArchiveInfo(archiveInfo);
|
||||
startBlockSize = archiveInfo.StartPosition;
|
||||
commentRangeAssigned = archiveInfo.IsCommented();
|
||||
if (commentRangeAssigned)
|
||||
{
|
||||
commentRange.Position = archiveInfo.CommentPosition;
|
||||
commentRange.Size = archiveInfo.CommentSize;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
startBlockSize = 0;
|
||||
commentRangeAssigned = false;
|
||||
}
|
||||
|
||||
COutArchive outArchive;
|
||||
outArchive.Create(outStream);
|
||||
if (startBlockSize > 0)
|
||||
{
|
||||
CMyComPtr<ISequentialInStream> inStream;
|
||||
inStream.Attach(inArchive->CreateLimitedStream(0, startBlockSize));
|
||||
RINOK(CopyBlockToArchive(inStream, outArchive, NULL));
|
||||
outArchive.MoveBasePosition(startBlockSize);
|
||||
}
|
||||
CMyComPtr<IInStream> inStream;
|
||||
if(inArchive != 0)
|
||||
inStream.Attach(inArchive->CreateStream());
|
||||
|
||||
return Update2(outArchive, inStream,
|
||||
inputItems, updateItems,
|
||||
compressionMethodMode,
|
||||
commentRangeAssigned, commentRange, updateCallback);
|
||||
}
|
||||
|
||||
}}
|
||||
59
7zip/Archive/Zip/ZipUpdate.h
Executable file
59
7zip/Archive/Zip/ZipUpdate.h
Executable file
@@ -0,0 +1,59 @@
|
||||
// Zip/Update.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ZIP_UPDATE_H
|
||||
#define __ZIP_UPDATE_H
|
||||
|
||||
#include "Common/Vector.h"
|
||||
#include "Common/Types.h"
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../IArchive.h"
|
||||
|
||||
#include "ZipCompressionMode.h"
|
||||
#include "ZipIn.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NZip {
|
||||
|
||||
struct CUpdateRange
|
||||
{
|
||||
UINT32 Position;
|
||||
UINT32 Size;
|
||||
CUpdateRange() {};
|
||||
CUpdateRange(UINT32 position, UINT32 size):
|
||||
Position(position), Size(size) {};
|
||||
};
|
||||
|
||||
struct CUpdateItem
|
||||
{
|
||||
bool NewData;
|
||||
bool NewProperties;
|
||||
bool IsDirectory;
|
||||
int IndexInArchive;
|
||||
int IndexInClient;
|
||||
UINT32 Attributes;
|
||||
UINT32 Time;
|
||||
UINT32 Size;
|
||||
AString Name;
|
||||
// bool ExistInArchive;
|
||||
bool Commented;
|
||||
CUpdateRange CommentRange;
|
||||
/*
|
||||
bool IsDirectory() const
|
||||
{ return ((Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0); };
|
||||
*/
|
||||
};
|
||||
|
||||
HRESULT Update(
|
||||
const CObjectVector<CItemEx> &inputItems,
|
||||
const CObjectVector<CUpdateItem> &updateItems,
|
||||
IOutStream *outStream,
|
||||
CInArchive *inArchive,
|
||||
CCompressionMethodMode *compressionMethodMode,
|
||||
IArchiveUpdateCallback *updateCallback);
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
16
7zip/Archive/Zip/resource.h
Executable file
16
7zip/Archive/Zip/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/Zip/resource.rc
Executable file
130
7zip/Archive/Zip/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 "zip.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", "Zip Plugin for 7-Zip\0"
|
||||
VALUE "FileVersion", "3, 12, 0, 0\0"
|
||||
VALUE "InternalName", "zip\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "zip.dll\0"
|
||||
VALUE "PrivateBuild", "\0"
|
||||
VALUE "ProductName", "7-Zip\0"
|
||||
VALUE "ProductVersion", "3, 12, 0, 0\0"
|
||||
VALUE "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
|
||||
|
||||
BIN
7zip/Archive/Zip/zip.ico
Executable file
BIN
7zip/Archive/Zip/zip.ico
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 3.6 KiB |
Reference in New Issue
Block a user