Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Pavlov <ipavlov@users.sourceforge.net>2010-11-02 03:00:00 +0300
committerKornel LesiƄski <kornel@geekhood.net>2016-05-28 02:16:04 +0300
commitc65230d8585317f7cd58ae2982067385269fdee9 (patch)
tree436513094ff5034da4c88def9609f0ea376065c6
parent2eb60a059819da595efb8e1de49f04c241f5b981 (diff)
9.189.18
-rwxr-xr-xC/7zAlloc.c (renamed from C/Util/7z/7zAlloc.c)3
-rwxr-xr-xC/7zAlloc.h (renamed from C/Util/7z/7zAlloc.h)12
-rwxr-xr-xC/7zDec.c60
-rwxr-xr-xC/7zIn.c16
-rwxr-xr-xC/7zVersion.h6
-rwxr-xr-xC/CpuArch.c16
-rwxr-xr-xC/CpuArch.h16
-rwxr-xr-xC/Types.h18
-rwxr-xr-xC/Util/7z/7z.dsp20
-rwxr-xr-xC/Util/7z/7zMain.c20
-rwxr-xr-xC/Util/7z/makefile3
-rwxr-xr-xC/Util/7z/makefile.gcc7
-rwxr-xr-xC/Util/SfxSetup/SfxSetup.c591
-rwxr-xr-xC/Util/SfxSetup/SfxSetup.dsp198
-rwxr-xr-xC/Util/SfxSetup/SfxSetup.dsw29
-rwxr-xr-xC/Util/SfxSetup/makefile35
-rwxr-xr-xC/Util/SfxSetup/makefile_con35
-rwxr-xr-xC/Util/SfxSetup/resource.rc6
-rwxr-xr-xC/Util/SfxSetup/setup.icobin0 -> 1078 bytes
-rwxr-xr-xCPP/7zip/Archive/7z/7zEncode.cpp15
-rwxr-xr-xCPP/7zip/Archive/7z/7zIn.cpp53
-rwxr-xr-xCPP/7zip/Archive/Common/ItemNameUtils.cpp2
-rwxr-xr-xCPP/7zip/Archive/Common/MultiStream.cpp99
-rwxr-xr-xCPP/7zip/Archive/Common/MultiStream.h32
-rwxr-xr-xCPP/7zip/Archive/CramfsHandler.cpp644
-rwxr-xr-xCPP/7zip/Archive/ElfHandler.cpp6
-rwxr-xr-xCPP/7zip/Archive/Icons/squashfs.icobin0 -> 3638 bytes
-rwxr-xr-xCPP/7zip/Archive/Iso/IsoHandler.cpp86
-rwxr-xr-xCPP/7zip/Archive/Iso/IsoIn.cpp3
-rwxr-xr-xCPP/7zip/Archive/Iso/IsoIn.h15
-rwxr-xr-xCPP/7zip/Archive/LzhHandler.cpp2
-rwxr-xr-xCPP/7zip/Archive/MachoHandler.cpp20
-rwxr-xr-xCPP/7zip/Archive/PeHandler.cpp86
-rwxr-xr-xCPP/7zip/Archive/Rar/RarHandler.cpp19
-rwxr-xr-xCPP/7zip/Archive/Rar/RarHandler.h1
-rwxr-xr-xCPP/7zip/Archive/Rar/RarHeader.h20
-rwxr-xr-xCPP/7zip/Archive/Rar/RarIn.cpp9
-rwxr-xr-xCPP/7zip/Archive/Rar/RarIn.h2
-rwxr-xr-xCPP/7zip/Archive/RpmHandler.cpp6
-rwxr-xr-xCPP/7zip/Archive/SplitHandler.cpp1
-rwxr-xr-xCPP/7zip/Archive/SquashfsHandler.cpp1959
-rwxr-xr-xCPP/7zip/Archive/Tar/TarHandler.cpp107
-rwxr-xr-xCPP/7zip/Archive/Tar/TarHandler.h4
-rwxr-xr-xCPP/7zip/Archive/Tar/TarHandlerOut.cpp2
-rwxr-xr-xCPP/7zip/Archive/Tar/TarIn.cpp104
-rwxr-xr-xCPP/7zip/Archive/Tar/TarIn.h5
-rwxr-xr-xCPP/7zip/Archive/Tar/TarItem.h11
-rwxr-xr-xCPP/7zip/Archive/Tar/TarUpdate.cpp12
-rwxr-xr-xCPP/7zip/Archive/Wim/WimHandlerOut.cpp16
-rwxr-xr-xCPP/7zip/Archive/Wim/WimIn.cpp2
-rwxr-xr-xCPP/7zip/Archive/XarHandler.cpp2
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipAddCommon.cpp7
-rwxr-xr-xCPP/7zip/Bundles/Fm/makefile2
-rwxr-xr-xCPP/7zip/Bundles/Format7zF/Format7z.dsp14
-rwxr-xr-xCPP/7zip/Bundles/Format7zF/makefile2
-rwxr-xr-xCPP/7zip/Bundles/Format7zF/resource.rc3
-rwxr-xr-xCPP/7zip/Common/LimitedStreams.h1
-rwxr-xr-xCPP/7zip/Common/StreamObjects.cpp187
-rwxr-xr-xCPP/7zip/Common/StreamObjects.h86
-rwxr-xr-xCPP/7zip/Guid.txt2
-rwxr-xr-xCPP/7zip/MyVersion.h8
-rwxr-xr-xCPP/7zip/PropID.h1
-rwxr-xr-xCPP/7zip/UI/Agent/Agent.cpp2
-rwxr-xr-xCPP/7zip/UI/Agent/Agent.h21
-rwxr-xr-xCPP/7zip/UI/Common/Extract.cpp9
-rwxr-xr-xCPP/7zip/UI/Common/ExtractingFilePath.cpp2
-rwxr-xr-xCPP/7zip/UI/Common/OpenArchive.cpp8
-rwxr-xr-xCPP/7zip/UI/Common/OpenArchive.h1
-rwxr-xr-xCPP/7zip/UI/Common/PropIDUtils.cpp11
-rwxr-xr-xCPP/7zip/UI/Console/List.cpp5
-rwxr-xr-xCPP/7zip/UI/Console/Main.cpp5
-rwxr-xr-xCPP/7zip/UI/Far/Far.dsp4
-rwxr-xr-xCPP/7zip/UI/Far/FarPlugin.h58
-rwxr-xr-xCPP/7zip/UI/Far/Main.cpp7
-rwxr-xr-xCPP/7zip/UI/Far/Plugin.cpp20
-rwxr-xr-xCPP/7zip/UI/FileManager/PanelItemOpen.cpp41
-rwxr-xr-xCPP/7zip/UI/FileManager/PanelMenu.cpp17
-rwxr-xr-xCPP/7zip/UI/FileManager/PanelSort.cpp18
-rwxr-xr-xCPP/7zip/UI/FileManager/ProgramLocation.cpp3
-rwxr-xr-xCPP/7zip/UI/FileManager/PropertyName.cpp1
-rwxr-xr-xCPP/7zip/UI/FileManager/PropertyName.rc1
-rwxr-xr-xCPP/7zip/UI/FileManager/PropertyNameRes.h1
-rwxr-xr-xCPP/7zip/UI/GUI/CompressDialog.cpp8
-rwxr-xr-xCPP/Common/DynamicBuffer.h9
-rwxr-xr-xCPP/Common/IntToString.cpp11
-rwxr-xr-xCPP/Common/IntToString.h2
-rwxr-xr-xCPP/Common/MyString.h4
-rwxr-xr-xCPP/Common/MyVector.h16
-rwxr-xr-xCPP/Common/MyWindows.h10
-rwxr-xr-xCPP/Common/Wildcard.cpp2
-rwxr-xr-xCPP/Windows/Control/Dialog.cpp4
-rwxr-xr-xCPP/Windows/FileName.h2
-rwxr-xr-xCPP/Windows/PropVariant.cpp2
-rwxr-xr-xCPP/Windows/PropVariantUtils.cpp5
-rwxr-xr-xDOC/7zip.inf6
-rwxr-xr-xDOC/7zip.nsi2
-rwxr-xr-xDOC/7zip.wxs2
-rwxr-xr-xDOC/Methods.txt8
-rwxr-xr-xDOC/history.txt5
-rwxr-xr-xDOC/lzma.txt2
-rwxr-xr-xDOC/readme.txt2
101 files changed, 4551 insertions, 535 deletions
diff --git a/C/Util/7z/7zAlloc.c b/C/7zAlloc.c
index 4bfaf42a..964b28db 100755
--- a/C/Util/7z/7zAlloc.c
+++ b/C/7zAlloc.c
@@ -1,7 +1,6 @@
/* 7zAlloc.c -- Allocation functions
-2008-10-04 : Igor Pavlov : Public domain */
+2010-10-29 : Igor Pavlov : Public domain */
-#include <stdlib.h>
#include "7zAlloc.h"
/* #define _SZ_ALLOC_DEBUG */
diff --git a/C/Util/7z/7zAlloc.h b/C/7zAlloc.h
index a5e88e47..3344e937 100755
--- a/C/Util/7z/7zAlloc.h
+++ b/C/7zAlloc.h
@@ -1,14 +1,10 @@
/* 7zAlloc.h -- Allocation functions
-2009-02-07 : Igor Pavlov : Public domain */
+2010-10-29 : Igor Pavlov : Public domain */
#ifndef __7Z_ALLOC_H
#define __7Z_ALLOC_H
-#include <stddef.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include <stdlib.h>
void *SzAlloc(void *p, size_t size);
void SzFree(void *p, void *address);
@@ -16,8 +12,4 @@ void SzFree(void *p, void *address);
void *SzAllocTemp(void *p, size_t size);
void SzFreeTemp(void *p, void *address);
-#ifdef __cplusplus
-}
-#endif
-
#endif
diff --git a/C/7zDec.c b/C/7zDec.c
index 0df807b1..b6d80995 100755
--- a/C/7zDec.c
+++ b/C/7zDec.c
@@ -1,5 +1,5 @@
/* 7zDec.c -- Decoding from 7z folder
-2010-03-15 : Igor Pavlov : Public domain */
+2010-11-02 : Igor Pavlov : Public domain */
#include <string.h>
@@ -18,9 +18,13 @@
#define k_Copy 0
#define k_LZMA2 0x21
-#define k_LZMA 0x30101
-#define k_BCJ 0x03030103
-#define k_BCJ2 0x0303011B
+#define k_LZMA 0x30101
+#define k_BCJ 0x03030103
+#define k_PPC 0x03030205
+#define k_ARM 0x03030501
+#define k_ARMT 0x03030701
+#define k_SPARC 0x03030805
+#define k_BCJ2 0x0303011B
#ifdef _7ZIP_PPMD_SUPPPORT
@@ -260,7 +264,6 @@ static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c)
IS_MAIN_METHOD((UInt32)c->MethodID);
}
-#define IS_BCJ(c) ((c)->MethodID == k_BCJ && (c)->NumInStreams == 1 && (c)->NumOutStreams == 1)
#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumInStreams == 4 && (c)->NumOutStreams == 1)
static SRes CheckSupportedFolder(const CSzFolder *f)
@@ -277,11 +280,24 @@ static SRes CheckSupportedFolder(const CSzFolder *f)
}
if (f->NumCoders == 2)
{
- if (!IS_BCJ(&f->Coders[1]) ||
- f->NumPackStreams != 1 || f->PackStreams[0] != 0 ||
+ CSzCoderInfo *c = &f->Coders[1];
+ if (c->MethodID > (UInt32)0xFFFFFFFF ||
+ c->NumInStreams != 1 ||
+ c->NumOutStreams != 1 ||
+ f->NumPackStreams != 1 ||
+ f->PackStreams[0] != 0 ||
f->NumBindPairs != 1 ||
- f->BindPairs[0].InIndex != 1 || f->BindPairs[0].OutIndex != 0)
+ f->BindPairs[0].InIndex != 1 ||
+ f->BindPairs[0].OutIndex != 0)
return SZ_ERROR_UNSUPPORTED;
+ switch ((UInt32)c->MethodID)
+ {
+ case k_BCJ:
+ case k_ARM:
+ break;
+ default:
+ return SZ_ERROR_UNSUPPORTED;
+ }
return SZ_OK;
}
if (f->NumCoders == 4)
@@ -314,6 +330,8 @@ static UInt64 GetSum(const UInt64 *values, UInt32 index)
return sum;
}
+#define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break;
+
static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
ILookInStream *inStream, UInt64 startPos,
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain,
@@ -391,14 +409,6 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
#endif
}
}
- else if (coder->MethodID == k_BCJ)
- {
- UInt32 state;
- if (ci != 1)
- return SZ_ERROR_UNSUPPORTED;
- x86_Convert_Init(state);
- x86_Convert(outBuffer, outSize, 0, &state, 0);
- }
else if (coder->MethodID == k_BCJ2)
{
UInt64 offset = GetSum(packSizes, 1);
@@ -425,7 +435,23 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
RINOK(res)
}
else
- return SZ_ERROR_UNSUPPORTED;
+ {
+ if (ci != 1)
+ return SZ_ERROR_UNSUPPORTED;
+ switch(coder->MethodID)
+ {
+ case k_BCJ:
+ {
+ UInt32 state;
+ x86_Convert_Init(state);
+ x86_Convert(outBuffer, outSize, 0, &state, 0);
+ break;
+ }
+ CASE_BRA_CONV(ARM)
+ default:
+ return SZ_ERROR_UNSUPPORTED;
+ }
+ }
}
return SZ_OK;
}
diff --git a/C/7zIn.c b/C/7zIn.c
index 35c056d6..ec93a43f 100755
--- a/C/7zIn.c
+++ b/C/7zIn.c
@@ -1,5 +1,5 @@
/* 7zIn.c -- 7z Input functions
-2010-03-11 : Igor Pavlov : Public domain */
+2010-10-29 : Igor Pavlov : Public domain */
#include <string.h>
@@ -1218,12 +1218,16 @@ static SRes SzArEx_Open2(
ISzAlloc *allocTemp)
{
Byte header[k7zStartHeaderSize];
+ Int64 startArcPos;
UInt64 nextHeaderOffset, nextHeaderSize;
size_t nextHeaderSizeT;
UInt32 nextHeaderCRC;
CBuf buffer;
SRes res;
+ startArcPos = 0;
+ RINOK(inStream->Seek(inStream, &startArcPos, SZ_SEEK_CUR));
+
RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE));
if (!TestSignatureCandidate(header))
@@ -1235,7 +1239,7 @@ static SRes SzArEx_Open2(
nextHeaderSize = GetUi64(header + 20);
nextHeaderCRC = GetUi32(header + 28);
- p->startPosAfterHeader = k7zStartHeaderSize;
+ p->startPosAfterHeader = startArcPos + k7zStartHeaderSize;
if (CrcCalc(header + 12, 20) != GetUi32(header + 8))
return SZ_ERROR_CRC;
@@ -1252,13 +1256,13 @@ static SRes SzArEx_Open2(
{
Int64 pos = 0;
RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END));
- if ((UInt64)pos < nextHeaderOffset ||
- (UInt64)pos < k7zStartHeaderSize + nextHeaderOffset ||
- (UInt64)pos < k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)
+ if ((UInt64)pos < startArcPos + nextHeaderOffset ||
+ (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset ||
+ (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)
return SZ_ERROR_INPUT_EOF;
}
- RINOK(LookInStream_SeekTo(inStream, k7zStartHeaderSize + nextHeaderOffset));
+ RINOK(LookInStream_SeekTo(inStream, startArcPos + k7zStartHeaderSize + nextHeaderOffset));
if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp))
return SZ_ERROR_MEM;
diff --git a/C/7zVersion.h b/C/7zVersion.h
index 1ac7a662..eee6be7d 100755
--- a/C/7zVersion.h
+++ b/C/7zVersion.h
@@ -1,7 +1,7 @@
#define MY_VER_MAJOR 9
-#define MY_VER_MINOR 17
+#define MY_VER_MINOR 18
#define MY_VER_BUILD 0
-#define MY_VERSION "9.17 beta"
-#define MY_DATE "2010-10-04"
+#define MY_VERSION "9.18 beta"
+#define MY_DATE "2010-11-02"
#define MY_COPYRIGHT ": Igor Pavlov : Public domain"
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE
diff --git a/C/CpuArch.c b/C/CpuArch.c
index 5298e006..260cc1f4 100755
--- a/C/CpuArch.c
+++ b/C/CpuArch.c
@@ -1,5 +1,5 @@
/* CpuArch.c -- CPU specific code
-2009-12-12: Igor Pavlov : Public domain */
+2010-10-26: Igor Pavlov : Public domain */
#include "CpuArch.h"
@@ -72,13 +72,13 @@ static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
#else
- __asm__ __volatile__ (
- "cpuid"
- : "=a" (*a) ,
- "=b" (*b) ,
- "=c" (*c) ,
- "=d" (*d)
- : "0" (function)) ;
+ __asm__ __volatile__ (
+ "cpuid"
+ : "=a" (*a) ,
+ "=b" (*b) ,
+ "=c" (*c) ,
+ "=d" (*d)
+ : "0" (function)) ;
#endif
diff --git a/C/CpuArch.h b/C/CpuArch.h
index aec3c416..01930c7e 100755
--- a/C/CpuArch.h
+++ b/C/CpuArch.h
@@ -1,5 +1,5 @@
/* CpuArch.h -- CPU specific code
-2010-05-20: Igor Pavlov : Public domain */
+2010-10-26: Igor Pavlov : Public domain */
#ifndef __CPU_ARCH_H
#define __CPU_ARCH_H
@@ -40,14 +40,26 @@ If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of pla
#define MY_CPU_ARM_LE
#endif
+#if defined(_WIN32) && defined(_M_IA64)
+#define MY_CPU_IA64_LE
+#endif
+
#if defined(MY_CPU_X86_OR_AMD64)
#define MY_CPU_LE_UNALIGN
#endif
-#if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_LE)
+#if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_LE) || defined(MY_CPU_IA64_LE) || defined(__ARMEL__) || defined(__MIPSEL__) || defined(__LITTLE_ENDIAN__)
#define MY_CPU_LE
#endif
+#if defined(__BIG_ENDIAN__)
+#define MY_CPU_BE
+#endif
+
+#if defined(MY_CPU_LE) && defined(MY_CPU_BE)
+Stop_Compiling_Bad_Endian
+#endif
+
#ifdef MY_CPU_LE_UNALIGN
#define GetUi16(p) (*(const UInt16 *)(p))
diff --git a/C/Types.h b/C/Types.h
index 07e1aa78..7732c240 100755
--- a/C/Types.h
+++ b/C/Types.h
@@ -1,5 +1,5 @@
/* Types.h -- Basic types
-2010-04-16 : Igor Pavlov : Public domain */
+2010-10-09 : Igor Pavlov : Public domain */
#ifndef __7Z_TYPES_H
#define __7Z_TYPES_H
@@ -233,6 +233,22 @@ typedef struct
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
#define IAlloc_Free(p, a) (p)->Free((p), a)
+#ifdef _WIN32
+
+#define CHAR_PATH_SEPARATOR '\\'
+#define WCHAR_PATH_SEPARATOR L'\\'
+#define STRING_PATH_SEPARATOR "\\"
+#define WSTRING_PATH_SEPARATOR L"\\"
+
+#else
+
+#define CHAR_PATH_SEPARATOR '/'
+#define WCHAR_PATH_SEPARATOR L'/'
+#define STRING_PATH_SEPARATOR "/"
+#define WSTRING_PATH_SEPARATOR L"/"
+
+#endif
+
EXTERN_C_END
#endif
diff --git a/C/Util/7z/7z.dsp b/C/Util/7z/7z.dsp
index 0d4d04c8..21dd5995 100755
--- a/C/Util/7z/7z.dsp
+++ b/C/Util/7z/7z.dsp
@@ -92,6 +92,14 @@ SOURCE=..\..\7z.h
# End Source File
# Begin Source File
+SOURCE=..\..\7zAlloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\7zAlloc.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\7zBuf.c
# End Source File
# Begin Source File
@@ -141,6 +149,10 @@ SOURCE=..\..\Bcj2.h
# End Source File
# Begin Source File
+SOURCE=..\..\Bra.c
+# End Source File
+# Begin Source File
+
SOURCE=..\..\Bra.h
# End Source File
# Begin Source File
@@ -196,14 +208,6 @@ SOURCE=..\..\Types.h
# End Group
# Begin Source File
-SOURCE=.\7zAlloc.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\7zAlloc.h
-# End Source File
-# Begin Source File
-
SOURCE=.\7zMain.c
# End Source File
# End Target
diff --git a/C/Util/7z/7zMain.c b/C/Util/7z/7zMain.c
index 2e6c6622..9496dc07 100755
--- a/C/Util/7z/7zMain.c
+++ b/C/Util/7z/7zMain.c
@@ -1,16 +1,15 @@
/* 7zMain.c - Test application for 7z Decoder
-2010-09-20 : Igor Pavlov : Public domain */
+2010-10-28 : Igor Pavlov : Public domain */
#include <stdio.h>
#include <string.h>
#include "../../7z.h"
+#include "../../7zAlloc.h"
#include "../../7zCrc.h"
#include "../../7zFile.h"
#include "../../7zVersion.h"
-#include "7zAlloc.h"
-
#ifndef USE_WINDOWS_FILE
/* for mkdir */
#ifdef _WIN32
@@ -21,12 +20,6 @@
#endif
#endif
-#ifdef _WIN32
-#define CHAR_PATH_SEPARATOR '\\'
-#else
-#define CHAR_PATH_SEPARATOR '/'
-#endif
-
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
static int Buf_EnsureSize(CBuf *dest, size_t size)
@@ -117,7 +110,14 @@ static SRes Utf16_To_Char(CBuf *buf, const UInt16 *s, int fileMode)
{
char defaultChar = '_';
BOOL defUsed;
- int numChars = WideCharToMultiByte(fileMode ? (AreFileApisANSI() ? CP_ACP : CP_OEMCP) : CP_OEMCP,
+ int numChars = WideCharToMultiByte(fileMode ?
+ (
+ #ifdef UNDER_CE
+ CP_ACP
+ #else
+ AreFileApisANSI() ? CP_ACP : CP_OEMCP
+ #endif
+ ) : CP_OEMCP,
0, s, len, (char *)buf->data, size, &defaultChar, &defUsed);
if (numChars == 0 || numChars >= size)
return SZ_ERROR_FAIL;
diff --git a/C/Util/7z/makefile b/C/Util/7z/makefile
index 3b762e65..96edda42 100755
--- a/C/Util/7z/makefile
+++ b/C/Util/7z/makefile
@@ -4,6 +4,7 @@ CFLAGS = $(CFLAGS) -D_7ZIP_PPMD_SUPPPORT
PROG = 7zDec.exe
C_OBJS = \
+ $O\7zAlloc.obj \
$O\7zBuf.obj \
$O\7zBuf2.obj \
$O\7zCrc.obj \
@@ -13,6 +14,7 @@ C_OBJS = \
$O\7zIn.obj \
$O\7zStream.obj \
$O\Bcj2.obj \
+ $O\Bra.obj \
$O\Bra86.obj \
$O\CpuArch.obj \
$O\Lzma2Dec.obj \
@@ -21,7 +23,6 @@ C_OBJS = \
$O\Ppmd7Dec.obj \
7Z_OBJS = \
- $O\7zAlloc.obj \
$O\7zMain.obj \
OBJS = \
diff --git a/C/Util/7z/makefile.gcc b/C/Util/7z/makefile.gcc
index 8f95f890..364c6474 100755
--- a/C/Util/7z/makefile.gcc
+++ b/C/Util/7z/makefile.gcc
@@ -4,7 +4,7 @@ LIB =
RM = rm -f
CFLAGS = -c -O2 -Wall
-OBJS = 7zMain.o 7zAlloc.o 7zBuf.o 7zBuf2.o 7zCrc.o 7zCrcOpt.o 7zDec.o 7zIn.o CpuArch.o LzmaDec.o Lzma2Dec.o Bra86.o Bcj2.o Ppmd7.o Ppmd7Dec.o 7zFile.o 7zStream.o
+OBJS = 7zMain.o 7zAlloc.o 7zBuf.o 7zBuf2.o 7zCrc.o 7zCrcOpt.o 7zDec.o 7zIn.o CpuArch.o LzmaDec.o Lzma2Dec.o Bra.o Bra86.o Bcj2.o Ppmd7.o Ppmd7Dec.o 7zFile.o 7zStream.o
all: $(PROG)
@@ -15,7 +15,7 @@ $(PROG): $(OBJS)
$(CXX) $(CFLAGS) 7zMain.c
7zAlloc.o: 7zAlloc.c
- $(CXX) $(CFLAGS) 7zAlloc.c
+ $(CXX) $(CFLAGS) ../../7zAlloc.c
7zBuf.o: ../../7zBuf.c
$(CXX) $(CFLAGS) ../../7zBuf.c
@@ -44,6 +44,9 @@ LzmaDec.o: ../../LzmaDec.c
Lzma2Dec.o: ../../Lzma2Dec.c
$(CXX) $(CFLAGS) ../../Lzma2Dec.c
+Bra.o: ../../Bra.c
+ $(CXX) $(CFLAGS) ../../Bra.c
+
Bra86.o: ../../Bra86.c
$(CXX) $(CFLAGS) ../../Bra86.c
diff --git a/C/Util/SfxSetup/SfxSetup.c b/C/Util/SfxSetup/SfxSetup.c
new file mode 100755
index 00000000..1a64c6e8
--- /dev/null
+++ b/C/Util/SfxSetup/SfxSetup.c
@@ -0,0 +1,591 @@
+/* SfxSetup.c - 7z SFX Setup
+2010-11-02 : Igor Pavlov : Public domain */
+
+#ifndef UNICODE
+#define UNICODE
+#endif
+
+#ifndef _UNICODE
+#define _UNICODE
+#endif
+
+#ifdef _CONSOLE
+#include <stdio.h>
+#endif
+
+#include "../../7z.h"
+#include "../../7zAlloc.h"
+#include "../../7zCrc.h"
+#include "../../7zFile.h"
+#include "../../CpuArch.h"
+
+#define k_EXE_ExtIndex 1
+
+static const char *kExts[] =
+{
+ "bat",
+ "exe",
+ "inf",
+ "msi",
+ #ifdef UNDER_CE
+ "cab",
+ #endif
+ "html",
+ "htm"
+};
+
+static const char *kNames[] =
+{
+ "setup",
+ "install",
+ "run",
+ "start"
+};
+
+static unsigned FindExt(const wchar_t *s, unsigned *extLen)
+{
+ unsigned len = (unsigned)wcslen(s);
+ unsigned i;
+ for (i = len; i > 0; i--)
+ {
+ if (s[i - 1] == '.')
+ {
+ *extLen = len - i;
+ return i - 1;
+ }
+ }
+ *extLen = 0;
+ return len;
+}
+
+#define MAKE_CHAR_UPPER(c) ((((c) >= 'a' && (c) <= 'z') ? (c) -= 0x20 : (c)))
+
+static unsigned FindItem(const char **items, unsigned num, const wchar_t *s, unsigned len)
+{
+ unsigned i;
+ for (i = 0; i < num; i++)
+ {
+ const char *item = items[i];
+ unsigned itemLen = (unsigned)strlen(item);
+ unsigned j;
+ if (len != itemLen)
+ continue;
+ for (j = 0; j < len; j++)
+ {
+ unsigned c = item[j];
+ if (c != s[j] && MAKE_CHAR_UPPER(c) != s[j])
+ break;
+ }
+ if (j == len)
+ return i;
+ }
+ return i;
+}
+
+#ifdef _CONSOLE
+static BOOL WINAPI HandlerRoutine(DWORD ctrlType)
+{
+ ctrlType = ctrlType;
+ return TRUE;
+}
+#endif
+
+static void PrintErrorMessage(const char *message)
+{
+ #ifdef _CONSOLE
+ printf("\n7-Zip Error: %s\n", message);
+ #else
+ #ifdef UNDER_CE
+ WCHAR messageW[256 + 4];
+ unsigned i;
+ for (i = 0; i < 256 && message[i] != 0; i++)
+ messageW[i] = message[i];
+ messageW[i] = 0;
+ MessageBoxW(0, messageW, L"7-Zip Error", MB_ICONERROR);
+ #else
+ MessageBoxA(0, message, "7-Zip Error", MB_ICONERROR);
+ #endif
+ #endif
+}
+
+static WRes MyCreateDir(const WCHAR *name)
+{
+ return CreateDirectoryW(name, NULL) ? 0 : GetLastError();
+}
+
+#ifdef UNDER_CE
+#define kBufferSize (1 << 13)
+#else
+#define kBufferSize (1 << 15)
+#endif
+
+#define kSignatureSearchLimit (1 << 22)
+
+static Bool FindSignature(CSzFile *stream, UInt64 *resPos)
+{
+ Byte buf[kBufferSize];
+ size_t numPrevBytes = 0;
+ *resPos = 0;
+ for (;;)
+ {
+ size_t numTests, pos;
+ if (*resPos > kSignatureSearchLimit)
+ return False;
+
+ do
+ {
+ size_t processed = kBufferSize - numPrevBytes;
+ if (File_Read(stream, buf + numPrevBytes, &processed) != 0)
+ return False;
+ if (processed == 0)
+ return False;
+ numPrevBytes += processed;
+ }
+ while (numPrevBytes <= k7zStartHeaderSize);
+
+ numTests = numPrevBytes - k7zStartHeaderSize;
+ for (pos = 0; pos < numTests; pos++)
+ {
+ for (; buf[pos] != '7' && pos < numTests; pos++);
+ if (pos == numTests)
+ break;
+ if (memcmp(buf + pos, k7zSignature, k7zSignatureSize) == 0)
+ if (CrcCalc(buf + pos + 12, 20) == GetUi32(buf + pos + 8))
+ {
+ *resPos += pos;
+ return True;
+ }
+ }
+ *resPos += numTests;
+ numPrevBytes -= numTests;
+ memmove(buf, buf + numTests, numPrevBytes);
+ }
+}
+
+static Bool DoesFileOrDirExist(const WCHAR *path)
+{
+ WIN32_FIND_DATAW fd;
+ HANDLE handle;
+ handle = FindFirstFileW(path, &fd);
+ if (handle == INVALID_HANDLE_VALUE)
+ return False;
+ FindClose(handle);
+ return True;
+}
+
+static WRes RemoveDirWithSubItems(WCHAR *path)
+{
+ WIN32_FIND_DATAW fd;
+ HANDLE handle;
+ WRes res = 0;
+ size_t len = wcslen(path);
+ wcscpy(path + len, L"*");
+ handle = FindFirstFileW(path, &fd);
+ path[len] = L'\0';
+ if (handle == INVALID_HANDLE_VALUE)
+ return GetLastError();
+ for (;;)
+ {
+ if (wcscmp(fd.cFileName, L".") != 0 &&
+ wcscmp(fd.cFileName, L"..") != 0)
+ {
+ wcscpy(path + len, fd.cFileName);
+ if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
+ {
+ wcscat(path, L"\\");
+ res = RemoveDirWithSubItems(path);
+ }
+ else
+ {
+ SetFileAttributesW(path, 0);
+ if (DeleteFileW(path) == 0)
+ res = GetLastError();
+ }
+ if (res != 0)
+ break;
+ }
+ if (!FindNextFileW(handle, &fd))
+ {
+ res = GetLastError();
+ if (res == ERROR_NO_MORE_FILES)
+ res = 0;
+ break;
+ }
+ }
+ path[len] = L'\0';
+ FindClose(handle);
+ if (res == 0)
+ {
+ if (!RemoveDirectoryW(path))
+ res = GetLastError();
+ }
+ return res;
+}
+
+#ifdef _CONSOLE
+int MY_CDECL main()
+#else
+int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
+ #ifdef UNDER_CE
+ LPWSTR
+ #else
+ LPSTR
+ #endif
+ lpCmdLine, int nCmdShow)
+#endif
+{
+ CFileInStream archiveStream;
+ CLookToRead lookStream;
+ CSzArEx db;
+ SRes res = SZ_OK;
+ ISzAlloc allocImp;
+ ISzAlloc allocTempImp;
+ WCHAR sfxPath[MAX_PATH + 2];
+ WCHAR path[MAX_PATH * 3 + 2];
+ size_t pathLen;
+ DWORD winRes;
+ const wchar_t *cmdLineParams;
+ const char *errorMessage = NULL;
+ Bool useShellExecute = True;
+
+ #ifdef _CONSOLE
+ SetConsoleCtrlHandler(HandlerRoutine, TRUE);
+ #else
+ hInstance = hInstance;
+ hPrevInstance = hPrevInstance;
+ lpCmdLine = lpCmdLine;
+ nCmdShow = nCmdShow;
+ #endif
+
+ CrcGenerateTable();
+
+ allocImp.Alloc = SzAlloc;
+ allocImp.Free = SzFree;
+
+ allocTempImp.Alloc = SzAllocTemp;
+ allocTempImp.Free = SzFreeTemp;
+
+ FileInStream_CreateVTable(&archiveStream);
+ LookToRead_CreateVTable(&lookStream, False);
+
+ winRes = GetModuleFileNameW(NULL, sfxPath, MAX_PATH);
+ if (winRes == 0 || winRes > MAX_PATH)
+ return 1;
+ {
+ cmdLineParams = GetCommandLineW();
+ #ifndef UNDER_CE
+ {
+ Bool quoteMode = False;
+ for (;; cmdLineParams++)
+ {
+ wchar_t c = *cmdLineParams;
+ if (c == L'\"')
+ quoteMode = !quoteMode;
+ else if (c == 0 || (c == L' ' && !quoteMode))
+ break;
+ }
+ }
+ #endif
+ }
+
+ {
+ unsigned i;
+ DWORD d;
+ winRes = GetTempPathW(MAX_PATH, path);
+ if (winRes == 0 || winRes > MAX_PATH)
+ return 1;
+ pathLen = wcslen(path);
+ d = (GetTickCount() << 12) ^ (GetCurrentThreadId() << 14) ^ GetCurrentProcessId();
+ for (i = 0;; i++, d += GetTickCount())
+ {
+ if (i >= 100)
+ {
+ res = SZ_ERROR_FAIL;
+ break;
+ }
+ wcscpy(path + pathLen, L"7z");
+
+ {
+ wchar_t *s = path + wcslen(path);
+ UInt32 value = d;
+ unsigned k;
+ for (k = 0; k < 8; k++)
+ {
+ unsigned t = value & 0xF;
+ value >>= 4;
+ s[7 - k] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
+ }
+ s[k] = '\0';
+ }
+
+ if (DoesFileOrDirExist(path))
+ continue;
+ if (CreateDirectoryW(path, NULL))
+ {
+ wcscat(path, L"\\");
+ pathLen = wcslen(path);
+ break;
+ }
+ if (GetLastError() != ERROR_ALREADY_EXISTS)
+ {
+ res = SZ_ERROR_FAIL;
+ break;
+ }
+ }
+ if (res != SZ_OK)
+ errorMessage = "Can't create temp folder";
+ }
+
+ if (res != SZ_OK)
+ {
+ if (!errorMessage)
+ errorMessage = "Error";
+ PrintErrorMessage(errorMessage);
+ return 1;
+ }
+
+ if (InFile_OpenW(&archiveStream.file, sfxPath) != 0)
+ {
+ errorMessage = "can not open input file";
+ res = SZ_ERROR_FAIL;
+ }
+ else
+ {
+ UInt64 pos = 0;
+ if (!FindSignature(&archiveStream.file, &pos))
+ res = SZ_ERROR_FAIL;
+ else if (File_Seek(&archiveStream.file, (Int64 *)&pos, SZ_SEEK_SET) != 0)
+ res = SZ_ERROR_FAIL;
+ if (res != 0)
+ errorMessage = "Can't find 7z archive";
+ }
+
+ if (res == SZ_OK)
+ {
+ lookStream.realStream = &archiveStream.s;
+ LookToRead_Init(&lookStream);
+ }
+
+ SzArEx_Init(&db);
+ if (res == SZ_OK)
+ {
+ res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
+ }
+ if (res == SZ_OK)
+ {
+ UInt32 executeFileIndex = (UInt32)(Int32)-1;
+ UInt32 minPrice = 1 << 30;
+ UInt32 i;
+ UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */
+ Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */
+ size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */
+
+ for (i = 0; i < db.db.NumFiles; i++)
+ {
+ size_t offset = 0;
+ size_t outSizeProcessed = 0;
+ const CSzFileItem *f = db.db.Files + i;
+ size_t len;
+ WCHAR *temp;
+ len = SzArEx_GetFileNameUtf16(&db, i, NULL);
+
+ if (len >= MAX_PATH)
+ {
+ res = SZ_ERROR_FAIL;
+ break;
+ }
+
+ temp = path + pathLen;
+
+ SzArEx_GetFileNameUtf16(&db, i, temp);
+ {
+ res = SzArEx_Extract(&db, &lookStream.s, i,
+ &blockIndex, &outBuffer, &outBufferSize,
+ &offset, &outSizeProcessed,
+ &allocImp, &allocTempImp);
+ if (res != SZ_OK)
+ break;
+ }
+ {
+ CSzFile outFile;
+ size_t processedSize;
+ size_t j;
+ size_t nameStartPos = 0;
+ for (j = 0; temp[j] != 0; j++)
+ {
+ if (temp[j] == '/')
+ {
+ temp[j] = 0;
+ MyCreateDir(path);
+ temp[j] = CHAR_PATH_SEPARATOR;
+ nameStartPos = j + 1;
+ }
+ }
+
+ if (f->IsDir)
+ {
+ MyCreateDir(path);
+ continue;
+ }
+ else
+ {
+ unsigned extLen;
+ const WCHAR *name = temp + nameStartPos;
+ unsigned len = (unsigned)wcslen(name);
+ unsigned nameLen = FindExt(temp + nameStartPos, &extLen);
+ unsigned extPrice = FindItem(kExts, sizeof(kExts) / sizeof(kExts[0]), name + len - extLen, extLen);
+ unsigned namePrice = FindItem(kNames, sizeof(kNames) / sizeof(kNames[0]), name, nameLen);
+
+ unsigned price = namePrice + extPrice * 64 + (nameStartPos == 0 ? 0 : (1 << 12));
+ if (minPrice > price)
+ {
+ minPrice = price;
+ executeFileIndex = i;
+ useShellExecute = (extPrice != k_EXE_ExtIndex);
+ }
+
+ if (DoesFileOrDirExist(path))
+ {
+ errorMessage = "Duplicate file";
+ res = SZ_ERROR_FAIL;
+ break;
+ }
+ if (OutFile_OpenW(&outFile, path))
+ {
+ errorMessage = "Can't open output file";
+ res = SZ_ERROR_FAIL;
+ break;
+ }
+ }
+ processedSize = outSizeProcessed;
+ if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed)
+ {
+ errorMessage = "Can't write output file";
+ res = SZ_ERROR_FAIL;
+ }
+
+ #ifdef USE_WINDOWS_FILE
+ if (f->MTimeDefined)
+ {
+ FILETIME mTime;
+ mTime.dwLowDateTime = f->MTime.Low;
+ mTime.dwHighDateTime = f->MTime.High;
+ SetFileTime(outFile.handle, NULL, NULL, &mTime);
+ }
+ #endif
+
+ {
+ SRes res2 = File_Close(&outFile);
+ if (res != SZ_OK)
+ break;
+ if (res2 != SZ_OK)
+ {
+ res = res2;
+ break;
+ }
+ }
+ #ifdef USE_WINDOWS_FILE
+ if (f->AttribDefined)
+ SetFileAttributesW(path, f->Attrib);
+ #endif
+ }
+ }
+
+ if (res == SZ_OK)
+ {
+ if (executeFileIndex == (UInt32)(Int32)-1)
+ {
+ errorMessage = "There is no file to execute";
+ res = SZ_ERROR_FAIL;
+ }
+ else
+ {
+ WCHAR *temp = path + pathLen;
+ UInt32 j;
+ SzArEx_GetFileNameUtf16(&db, executeFileIndex, temp);
+ for (j = 0; temp[j] != 0; j++)
+ if (temp[j] == '/')
+ temp[j] = CHAR_PATH_SEPARATOR;
+ }
+ }
+ IAlloc_Free(&allocImp, outBuffer);
+ }
+ SzArEx_Free(&db, &allocImp);
+
+ File_Close(&archiveStream.file);
+
+ if (res == SZ_OK)
+ {
+ HANDLE hProcess = 0;
+ if (useShellExecute)
+ {
+ SHELLEXECUTEINFO ei;
+ UINT32 executeRes;
+ BOOL success;
+
+ memset(&ei, 0, sizeof(ei));
+ ei.cbSize = sizeof(ei);
+ ei.lpFile = path;
+ ei.fMask = SEE_MASK_NOCLOSEPROCESS
+ #ifndef UNDER_CE
+ | SEE_MASK_FLAG_DDEWAIT
+ #endif
+ ;
+ if (wcslen(cmdLineParams) != 0)
+ ei.lpParameters = cmdLineParams;
+ ei.nShow = SW_SHOWNORMAL;
+ success = ShellExecuteEx(&ei);
+ executeRes = (UINT32)(UINT_PTR)ei.hInstApp;
+ if (!success || (executeRes <= 32 && executeRes != 0)) /* executeRes = 0 in Windows CE */
+ res = SZ_ERROR_FAIL;
+ else
+ hProcess = ei.hProcess;
+ }
+ else
+ {
+ STARTUPINFOW si;
+ PROCESS_INFORMATION pi;
+ WCHAR cmdLine[MAX_PATH * 3];
+
+ wcscpy(cmdLine, path);
+ wcscat(cmdLine, cmdLineParams);
+ memset(&si, 0, sizeof(si));
+ si.cb = sizeof(si);
+ if (CreateProcessW(NULL, cmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi) == 0)
+ res = SZ_ERROR_FAIL;
+ else
+ {
+ CloseHandle(pi.hThread);
+ hProcess = pi.hProcess;
+ }
+ }
+ if (hProcess != 0)
+ {
+ WaitForSingleObject(hProcess, INFINITE);
+ CloseHandle(hProcess);
+ }
+ }
+
+ path[pathLen] = L'\0';
+ RemoveDirWithSubItems(path);
+
+ if (res == SZ_OK)
+ return 0;
+
+ {
+ if (res == SZ_ERROR_UNSUPPORTED)
+ errorMessage = "Decoder doesn't support this archive";
+ else if (res == SZ_ERROR_MEM)
+ errorMessage = "Can't allocate required memory";
+ else if (res == SZ_ERROR_CRC)
+ errorMessage = "CRC error";
+ else
+ {
+ if (!errorMessage)
+ errorMessage = "ERROR";
+ }
+ if (errorMessage)
+ PrintErrorMessage(errorMessage);
+ }
+ return 1;
+}
diff --git a/C/Util/SfxSetup/SfxSetup.dsp b/C/Util/SfxSetup/SfxSetup.dsp
new file mode 100755
index 00000000..39f876d4
--- /dev/null
+++ b/C/Util/SfxSetup/SfxSetup.dsp
@@ -0,0 +1,198 @@
+# Microsoft Developer Studio Project File - Name="SfxSetup" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=SfxSetup - 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 "SfxSetup.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 "SfxSetup.mak" CFG="SfxSetup - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "SfxSetup - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "SfxSetup - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "SfxSetup - 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 Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /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 /subsystem:windows /machine:I386
+
+!ELSEIF "$(CFG)" == "SfxSetup - 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 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /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 /subsystem:windows /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "SfxSetup - Win32 Release"
+# Name "SfxSetup - Win32 Debug"
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\7z.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\7zAlloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\7zAlloc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\7zBuf.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\7zBuf.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\7zCrc.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\7zCrc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\7zCrcOpt.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\7zDec.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\7zFile.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\7zFile.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\7zIn.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\7zStream.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Bcj2.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Bcj2.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Bra.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Bra.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Bra86.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\CpuArch.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\CpuArch.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Lzma2Dec.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Lzma2Dec.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\LzmaDec.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\LzmaDec.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Types.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\SfxSetup.c
+# End Source File
+# End Target
+# End Project
diff --git a/C/Util/SfxSetup/SfxSetup.dsw b/C/Util/SfxSetup/SfxSetup.dsw
new file mode 100755
index 00000000..ea231112
--- /dev/null
+++ b/C/Util/SfxSetup/SfxSetup.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "SfxSetup"=.\SfxSetup.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/C/Util/SfxSetup/makefile b/C/Util/SfxSetup/makefile
new file mode 100755
index 00000000..f3f78c81
--- /dev/null
+++ b/C/Util/SfxSetup/makefile
@@ -0,0 +1,35 @@
+PROG = 7zS2.sfx
+LIBS = $(LIBS)
+CFLAGS = $(CFLAGS) -DUNICODE -D_UNICODE
+
+C_OBJS = \
+ $O\7zAlloc.obj \
+ $O\7zBuf.obj \
+ $O\7zBuf2.obj \
+ $O\7zCrc.obj \
+ $O\7zCrcOpt.obj \
+ $O\7zFile.obj \
+ $O\7zDec.obj \
+ $O\7zIn.obj \
+ $O\7zStream.obj \
+ $O\Bcj2.obj \
+ $O\Bra.obj \
+ $O\Bra86.obj \
+ $O\CpuArch.obj \
+ $O\Lzma2Dec.obj \
+ $O\LzmaDec.obj \
+
+7Z_OBJS = \
+ $O\SfxSetup.obj \
+
+OBJS = \
+ $(7Z_OBJS) \
+ $(C_OBJS) \
+ $O\resource.res
+
+!include "../../../CPP/Build.mak"
+
+$(7Z_OBJS): $(*B).c
+ $(COMPL_O1)
+$(C_OBJS): ../../$(*B).c
+ $(COMPL_O1)
diff --git a/C/Util/SfxSetup/makefile_con b/C/Util/SfxSetup/makefile_con
new file mode 100755
index 00000000..8e1a050d
--- /dev/null
+++ b/C/Util/SfxSetup/makefile_con
@@ -0,0 +1,35 @@
+PROG = 7zS2con.sfx
+LIBS = $(LIBS)
+CFLAGS = $(CFLAGS) -DUNICODE -D_UNICODE -D_CONSOLE
+
+C_OBJS = \
+ $O\7zAlloc.obj \
+ $O\7zBuf.obj \
+ $O\7zBuf2.obj \
+ $O\7zCrc.obj \
+ $O\7zCrcOpt.obj \
+ $O\7zFile.obj \
+ $O\7zDec.obj \
+ $O\7zIn.obj \
+ $O\7zStream.obj \
+ $O\Bcj2.obj \
+ $O\Bra.obj \
+ $O\Bra86.obj \
+ $O\CpuArch.obj \
+ $O\Lzma2Dec.obj \
+ $O\LzmaDec.obj \
+
+7Z_OBJS = \
+ $O\SfxSetup.obj \
+
+OBJS = \
+ $(7Z_OBJS) \
+ $(C_OBJS) \
+ $O\resource.res
+
+!include "../../../CPP/Build.mak"
+
+$(7Z_OBJS): $(*B).c
+ $(COMPL_O1)
+$(C_OBJS): ../../$(*B).c
+ $(COMPL_O1)
diff --git a/C/Util/SfxSetup/resource.rc b/C/Util/SfxSetup/resource.rc
new file mode 100755
index 00000000..fc1f014e
--- /dev/null
+++ b/C/Util/SfxSetup/resource.rc
@@ -0,0 +1,6 @@
+#include "../../../CPP/7zip/MyVersionInfo.rc"
+
+MY_VERSION_INFO_APP("7z Setup SFX small", "7zS2.sfx")
+
+1 ICON "setup.ico"
+
diff --git a/C/Util/SfxSetup/setup.ico b/C/Util/SfxSetup/setup.ico
new file mode 100755
index 00000000..dbb6ca8b
--- /dev/null
+++ b/C/Util/SfxSetup/setup.ico
Binary files differ
diff --git a/CPP/7zip/Archive/7z/7zEncode.cpp b/CPP/7zip/Archive/7z/7zEncode.cpp
index ec0b5af4..87996bc0 100755
--- a/CPP/7zip/Archive/7z/7zEncode.cpp
+++ b/CPP/7zip/Archive/7z/7zEncode.cpp
@@ -193,11 +193,9 @@ HRESULT CEncoder::Encode(
// UInt64 outStreamStartPos;
// RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos));
- CSequentialInStreamSizeCount2 *inStreamSizeCountSpec =
- new CSequentialInStreamSizeCount2;
+ CSequentialInStreamSizeCount2 *inStreamSizeCountSpec = new CSequentialInStreamSizeCount2;
CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec;
- CSequentialOutStreamSizeCount *outStreamSizeCountSpec =
- new CSequentialOutStreamSizeCount;
+ CSequentialOutStreamSizeCount *outStreamSizeCountSpec = new CSequentialOutStreamSizeCount;
CMyComPtr<ISequentialOutStream> outStreamSizeCount = outStreamSizeCountSpec;
inStreamSizeCountSpec->Init(inStream);
@@ -226,13 +224,11 @@ HRESULT CEncoder::Encode(
_mixerCoderSpec->_coders[i].QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties);
if (writeCoderProperties != NULL)
{
- CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp;
+ CDynBufSeqOutStream *outStreamSpec = new CDynBufSeqOutStream;
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
outStreamSpec->Init();
writeCoderProperties->WriteCoderProperties(outStream);
- size_t size = outStreamSpec->GetSize();
- encodingInfo.Props.SetCapacity(size);
- memmove(encodingInfo.Props, outStreamSpec->GetBuffer(), size);
+ outStreamSpec->CopyToBuffer(encodingInfo.Props);
}
}
@@ -250,8 +246,7 @@ HRESULT CEncoder::Encode(
RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1,
&outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress));
- ConvertBindInfoToFolderItemInfo(_decompressBindInfo, _decompressionMethods,
- folderItem);
+ ConvertBindInfoToFolderItemInfo(_decompressBindInfo, _decompressionMethods, folderItem);
packSizes.Add(outStreamSizeCountSpec->GetSize());
diff --git a/CPP/7zip/Archive/7z/7zIn.cpp b/CPP/7zip/Archive/7z/7zIn.cpp
index 686bb288..0feb81d2 100755
--- a/CPP/7zip/Archive/7z/7zIn.cpp
+++ b/CPP/7zip/Archive/7z/7zIn.cpp
@@ -280,28 +280,46 @@ void CInByte2::ReadString(UString &s)
_pos += rem + 2;
}
-static inline bool TestSignatureCandidate(const Byte *p)
+static inline bool TestSignature(const Byte *p)
{
for (int i = 0; i < kSignatureSize; i++)
if (p[i] != kSignature[i])
return false;
- return (p[0x1A] == 0 && p[0x1B] == 0);
+ return CrcCalc(p + 12, 20) == GetUi32(p + 8);
}
+#ifdef FORMAT_7Z_RECOVERY
+static inline bool TestSignature2(const Byte *p)
+{
+ int i;
+ for (i = 0; i < kSignatureSize; i++)
+ if (p[i] != kSignature[i])
+ return false;
+ if (CrcCalc(p + 12, 20) == GetUi32(p + 8))
+ return true;
+ for (i = 8; i < kHeaderSize; i++)
+ if (p[i] != 0)
+ return false;
+ return (p[6] != 0 || p[7] != 0);
+}
+#else
+#define TestSignature2(p) TestSignature(p)
+#endif
+
HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
{
RINOK(ReadStream_FALSE(stream, _header, kHeaderSize));
- if (TestSignatureCandidate(_header))
+ if (TestSignature2(_header))
return S_OK;
CByteBuffer byteBuffer;
const UInt32 kBufferSize = (1 << 16);
byteBuffer.SetCapacity(kBufferSize);
Byte *buffer = byteBuffer;
- UInt32 numPrevBytes = kHeaderSize - 1;
- memcpy(buffer, _header + 1, numPrevBytes);
- UInt64 curTestPos = _arhiveBeginStreamPosition + 1;
+ UInt32 numPrevBytes = kHeaderSize;
+ memcpy(buffer, _header, kHeaderSize);
+ UInt64 curTestPos = _arhiveBeginStreamPosition;
for (;;)
{
if (searchHeaderSizeLimit != NULL)
@@ -316,14 +334,14 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search
if (processedSize == 0)
return S_FALSE;
}
- while (numPrevBytes < kHeaderSize);
- UInt32 numTests = numPrevBytes - kHeaderSize + 1;
+ while (numPrevBytes <= kHeaderSize);
+ UInt32 numTests = numPrevBytes - kHeaderSize;
for (UInt32 pos = 0; pos < numTests; pos++)
{
for (; buffer[pos] != '7' && pos < numTests; pos++);
if (pos == numTests)
break;
- if (TestSignatureCandidate(buffer + pos))
+ if (TestSignature(buffer + pos))
{
memcpy(_header, buffer + pos, kHeaderSize);
curTestPos += pos;
@@ -812,7 +830,7 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
ThrowUnsupported();
data.SetCapacity(unpackSize);
- CSequentialOutStreamImp2 *outStreamSpec = new CSequentialOutStreamImp2;
+ CBufPtrSeqOutStream *outStreamSpec = new CBufPtrSeqOutStream;
CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
outStreamSpec->Init(data, unpackSize);
@@ -1164,23 +1182,24 @@ HRESULT CInArchive::ReadDatabase2(
nextHeaderCRC = CrcCalc(buf + i, (size_t)nextHeaderSize);
RINOK(_stream->Seek(cur, STREAM_SEEK_SET, NULL));
}
+ else
#endif
-
- #ifdef FORMAT_7Z_RECOVERY
- crcFromArchive = crc;
- #endif
+ {
+ if (crc != crcFromArchive)
+ ThrowIncorrect();
+ }
db.ArchiveInfo.StartPositionAfterHeader = _arhiveBeginStreamPosition + kHeaderSize;
- if (crc != crcFromArchive)
- ThrowIncorrect();
-
if (nextHeaderSize == 0)
return S_OK;
if (nextHeaderSize > (UInt64)0xFFFFFFFF)
return S_FALSE;
+ if ((Int64)nextHeaderOffset < 0)
+ return S_FALSE;
+
RINOK(_stream->Seek(nextHeaderOffset, STREAM_SEEK_CUR, NULL));
CByteBuffer buffer2;
diff --git a/CPP/7zip/Archive/Common/ItemNameUtils.cpp b/CPP/7zip/Archive/Common/ItemNameUtils.cpp
index 71996a63..a5e0dc0b 100755
--- a/CPP/7zip/Archive/Common/ItemNameUtils.cpp
+++ b/CPP/7zip/Archive/Common/ItemNameUtils.cpp
@@ -2,6 +2,8 @@
#include "StdAfx.h"
+#include "../../../../C/Types.h"
+
#include "ItemNameUtils.h"
namespace NArchive {
diff --git a/CPP/7zip/Archive/Common/MultiStream.cpp b/CPP/7zip/Archive/Common/MultiStream.cpp
index cf7dc050..04d11caf 100755
--- a/CPP/7zip/Archive/Common/MultiStream.cpp
+++ b/CPP/7zip/Archive/Common/MultiStream.cpp
@@ -6,72 +6,61 @@
STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
- if(processedSize != NULL)
+ if (processedSize)
*processedSize = 0;
- while(_streamIndex < Streams.Size() && size > 0)
+ if (size == 0)
+ return S_OK;
+ if (_pos >= _totalLength)
+ return (_pos == _totalLength) ? S_OK : E_FAIL;
+
{
- CSubStreamInfo &s = Streams[_streamIndex];
- if (_pos == s.Size)
+ int left = 0, mid = _streamIndex, right = Streams.Size();
+ for (;;)
{
- _streamIndex++;
- _pos = 0;
- continue;
+ CSubStreamInfo &m = Streams[mid];
+ if (_pos < m.GlobalOffset)
+ right = mid;
+ else if (_pos >= m.GlobalOffset + m.Size)
+ left = mid + 1;
+ else
+ {
+ _streamIndex = mid;
+ break;
+ }
+ mid = (left + right) / 2;
}
- RINOK(s.Stream->Seek(s.Pos + _pos, STREAM_SEEK_SET, 0));
- UInt32 sizeToRead = UInt32(MyMin((UInt64)size, s.Size - _pos));
- UInt32 realProcessed;
- HRESULT result = s.Stream->Read(data, sizeToRead, &realProcessed);
- data = (void *)((Byte *)data + realProcessed);
- size -= realProcessed;
- if(processedSize != NULL)
- *processedSize += realProcessed;
- _pos += realProcessed;
- _seekPos += realProcessed;
- RINOK(result);
- break;
+ _streamIndex = mid;
}
- return S_OK;
+
+ CSubStreamInfo &s = Streams[_streamIndex];
+ UInt64 localPos = _pos - s.GlobalOffset;
+ if (localPos != s.LocalPos)
+ {
+ RINOK(s.Stream->Seek(localPos, STREAM_SEEK_SET, &s.LocalPos));
+ }
+ UInt64 rem = s.Size - localPos;
+ if (size > rem)
+ size = (UInt32)rem;
+ HRESULT result = s.Stream->Read(data, size, &size);
+ _pos += size;
+ s.LocalPos += size;
+ if (processedSize)
+ *processedSize = size;
+ return result;
}
-STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin,
- UInt64 *newPosition)
+STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
- UInt64 newPos;
switch(seekOrigin)
{
- case STREAM_SEEK_SET:
- newPos = offset;
- break;
- case STREAM_SEEK_CUR:
- newPos = _seekPos + offset;
- break;
- case STREAM_SEEK_END:
- newPos = _totalLength + offset;
- break;
- default:
- return STG_E_INVALIDFUNCTION;
- }
- _seekPos = 0;
- for (_streamIndex = 0; _streamIndex < Streams.Size(); _streamIndex++)
- {
- UInt64 size = Streams[_streamIndex].Size;
- if (newPos < _seekPos + size)
- {
- _pos = newPos - _seekPos;
- _seekPos += _pos;
- if (newPosition != 0)
- *newPosition = newPos;
- return S_OK;
- }
- _seekPos += size;
+ case STREAM_SEEK_SET: _pos = offset; break;
+ case STREAM_SEEK_CUR: _pos = _pos + offset; break;
+ case STREAM_SEEK_END: _pos = _totalLength + offset; break;
+ default: return STG_E_INVALIDFUNCTION;
}
- if (newPos == _seekPos)
- {
- if (newPosition != 0)
- *newPosition = newPos;
- return S_OK;
- }
- return E_FAIL;
+ if (newPosition != 0)
+ *newPosition = _pos;
+ return S_OK;
}
diff --git a/CPP/7zip/Archive/Common/MultiStream.h b/CPP/7zip/Archive/Common/MultiStream.h
index 137c9400..3fceb7cc 100755
--- a/CPP/7zip/Archive/Common/MultiStream.h
+++ b/CPP/7zip/Archive/Common/MultiStream.h
@@ -1,36 +1,44 @@
// MultiStream.h
-#ifndef __MULTISTREAM_H
-#define __MULTISTREAM_H
+#ifndef __MULTI_STREAM_H
+#define __MULTI_STREAM_H
#include "../../../Common/MyCom.h"
#include "../../../Common/MyVector.h"
-#include "../../Archive/IArchive.h"
+
+#include "../../IStream.h"
class CMultiStream:
public IInStream,
public CMyUnknownImp
{
- int _streamIndex;
UInt64 _pos;
- UInt64 _seekPos;
UInt64 _totalLength;
+ int _streamIndex;
public:
struct CSubStreamInfo
{
CMyComPtr<IInStream> Stream;
- UInt64 Pos;
UInt64 Size;
+ UInt64 GlobalOffset;
+ UInt64 LocalPos;
};
CObjectVector<CSubStreamInfo> Streams;
- void Init()
+
+ HRESULT Init()
{
- _streamIndex = 0;
- _pos = 0;
- _seekPos = 0;
- _totalLength = 0;
+ UInt64 total = 0;
for (int i = 0; i < Streams.Size(); i++)
- _totalLength += Streams[i].Size;
+ {
+ CSubStreamInfo &s = Streams[i];
+ s.GlobalOffset = total;
+ total += Streams[i].Size;
+ RINOK(s.Stream->Seek(0, STREAM_SEEK_CUR, &s.LocalPos));
+ }
+ _totalLength = total;
+ _pos = 0;
+ _streamIndex = 0;
+ return S_OK;
}
MY_UNKNOWN_IMP1(IInStream)
diff --git a/CPP/7zip/Archive/CramfsHandler.cpp b/CPP/7zip/Archive/CramfsHandler.cpp
new file mode 100755
index 00000000..a55e3743
--- /dev/null
+++ b/CPP/7zip/Archive/CramfsHandler.cpp
@@ -0,0 +1,644 @@
+// CramfsHandler.cpp
+
+#include "StdAfx.h"
+
+#include "../../../C/7zCrc.h"
+#include "../../../C/CpuArch.h"
+#include "../../../C/Alloc.h"
+
+#include "Common/ComTry.h"
+#include "Common/StringConvert.h"
+
+#include "Windows/PropVariantUtils.h"
+
+#include "../Common/LimitedStreams.h"
+#include "../Common/ProgressUtils.h"
+#include "../Common/RegisterArc.h"
+#include "../Common/StreamObjects.h"
+#include "../Common/StreamUtils.h"
+
+#include "../Compress/CopyCoder.h"
+#include "../Compress/ZlibDecoder.h"
+
+namespace NArchive {
+namespace NCramfs {
+
+#define SIGNATURE { 'C','o','m','p','r','e','s','s','e','d',' ','R','O','M','F','S' }
+
+static const UInt32 kSignatureSize = 16;
+static const char kSignature[kSignatureSize] = SIGNATURE;
+
+static const UInt32 kArcSizeMax = (256 + 16) << 20;
+static const UInt32 kNumFilesMax = (1 << 19);
+static const unsigned kNumDirLevelsMax = (1 << 8);
+
+static const UInt32 kHeaderSize = 0x40;
+static const unsigned kHeaderNameSize = 16;
+static const UInt32 kNodeSize = 12;
+
+static const UInt32 kFlag_FsVer2 = (1 << 0);
+
+static const CUInt32PCharPair k_Flags[] =
+{
+ { 0, "Ver2" },
+ { 1, "SortedDirs" },
+ { 8, "Holes" },
+ { 9, "WrongSignature" },
+ { 10, "ShiftedRootOffset" }
+};
+
+static const unsigned kBlockSizeLog = 12;
+static const UInt32 kBlockSize = 1 << kBlockSizeLog;
+
+/*
+struct CNode
+{
+ UInt16 Mode;
+ UInt16 Uid;
+ UInt32 Size;
+ Byte Gid;
+ UInt32 NameLen;
+ UInt32 Offset;
+
+ void Parse(const Byte *p)
+ {
+ Mode = GetUi16(p);
+ Uid = GetUi16(p + 2);
+ Size = Get32(p + 4) & 0xFFFFFF;
+ Gid = p[7];
+ NameLen = p[8] & 0x3F;
+ Offset = Get32(p + 8) >> 6;
+ }
+};
+*/
+
+#define Get32(p) (be ? GetBe32(p) : GetUi32(p))
+
+static UInt32 GetMode(const Byte *p, bool be) { return be ? GetBe16(p) : GetUi16(p); }
+static bool IsDir(const Byte *p, bool be) { return (GetMode(p, be) & 0xF000) == 0x4000; }
+
+static UInt32 GetSize(const Byte *p, bool be)
+{
+ if (be)
+ return GetBe32(p + 4) >> 8;
+ else
+ return GetUi32(p + 4) & 0xFFFFFF;
+}
+
+static UInt32 GetNameLen(const Byte *p, bool be)
+{
+ if (be)
+ return (p[8] & 0xFC);
+ else
+ return (p[8] & 0x3F) << 2;
+}
+
+static UInt32 GetOffset(const Byte *p, bool be)
+{
+ if (be)
+ return (GetBe32(p + 8) & 0x03FFFFFF) << 2;
+ else
+ return GetUi32(p + 8) >> 6 << 2;
+}
+
+struct CItem
+{
+ UInt32 Offset;
+ int Parent;
+};
+
+struct CHeader
+{
+ bool be;
+ UInt32 Size;
+ UInt32 Flags;
+ // UInt32 Future;
+ UInt32 Crc;
+ // UInt32 Edition;
+ UInt32 NumBlocks;
+ UInt32 NumFiles;
+ char Name[kHeaderNameSize];
+
+ bool Parse(const Byte *p)
+ {
+ if (memcmp(p + 16, kSignature, kSignatureSize) != 0)
+ return false;
+ switch(GetUi32(p))
+ {
+ case 0x28CD3D45: be = false; break;
+ case 0x453DCD28: be = true; break;
+ default: return false;
+ }
+ Size = Get32(p + 4);
+ Flags = Get32(p + 8);
+ // Future = Get32(p + 0xC);
+ Crc = Get32(p + 0x20);
+ // Edition = Get32(p + 0x24);
+ NumBlocks = Get32(p + 0x28);
+ NumFiles = Get32(p + 0x2C);
+ memcpy(Name, p + 0x30, kHeaderNameSize);
+ return true;
+ }
+
+ bool IsVer2() const { return (Flags & kFlag_FsVer2) != 0; }
+};
+
+class CHandler:
+ public IInArchive,
+ public IInArchiveGetStream,
+ public CMyUnknownImp
+{
+ CRecordVector<CItem> _items;
+ CMyComPtr<IInStream> _stream;
+ Byte *_data;
+ UInt32 _size;
+ UInt32 _headersSize;
+ AString _errorMessage;
+ CHeader _h;
+
+ // Current file
+
+ NCompress::NZlib::CDecoder *_zlibDecoderSpec;
+ CMyComPtr<ICompressCoder> _zlibDecoder;
+
+ CBufInStream *_inStreamSpec;
+ CMyComPtr<ISequentialInStream> _inStream;
+
+ CBufPtrSeqOutStream *_outStreamSpec;
+ CMyComPtr<ISequentialOutStream> _outStream;
+
+ UInt32 _curBlocksOffset;
+ UInt32 _curNumBlocks;
+
+ HRESULT OpenDir(int parent, UInt32 baseOffsetBase, unsigned level);
+ HRESULT Open2(IInStream *inStream);
+ AString GetPath(int index) const;
+ bool GetPackSize(int index, UInt32 &res) const;
+ void Free();
+public:
+ CHandler(): _data(0) {}
+ ~CHandler() { Free(); }
+ MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream)
+ INTERFACE_IInArchive(;)
+ STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
+ HRESULT ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize);
+};
+
+static const STATPROPSTG kProps[] =
+{
+ { NULL, kpidPath, VT_BSTR},
+ { NULL, kpidIsDir, VT_BOOL},
+ { NULL, kpidSize, VT_UI4},
+ { NULL, kpidPackSize, VT_UI4},
+ { NULL, kpidPosixAttrib, VT_UI4}
+ // { NULL, kpidOffset, VT_UI4}
+};
+
+static const STATPROPSTG kArcProps[] =
+{
+ { NULL, kpidName, VT_BSTR},
+ { NULL, kpidBigEndian, VT_BOOL},
+ { NULL, kpidCharacts, VT_BSTR},
+ { NULL, kpidPhySize, VT_UI4},
+ { NULL, kpidHeadersSize, VT_UI4},
+ { NULL, kpidNumSubFiles, VT_UI4},
+ { NULL, kpidNumBlocks, VT_UI4}
+};
+
+IMP_IInArchive_Props
+IMP_IInArchive_ArcProps
+
+HRESULT CHandler::OpenDir(int parent, UInt32 baseOffset, unsigned level)
+{
+ const Byte *p = _data + baseOffset;
+ bool be = _h.be;
+ if (!IsDir(p, be))
+ return S_OK;
+ UInt32 offset = GetOffset(p, be);
+ UInt32 size = GetSize(p, be);
+ if (offset == 0 && size == 0)
+ return S_OK;
+ UInt32 end = offset + size;
+ if (offset < kHeaderSize || end > _size || level > kNumDirLevelsMax)
+ return S_FALSE;
+ if (end > _headersSize)
+ _headersSize = end;
+
+ int startIndex = _items.Size();
+
+ while (size != 0)
+ {
+ if (size < kNodeSize || (UInt32)_items.Size() >= kNumFilesMax)
+ return S_FALSE;
+ CItem item;
+ item.Parent = parent;
+ item.Offset = offset;
+ _items.Add(item);
+ UInt32 nodeLen = kNodeSize + GetNameLen(_data + offset, be);
+ if (size < nodeLen)
+ return S_FALSE;
+ offset += nodeLen;
+ size -= nodeLen;
+ }
+
+ int endIndex = _items.Size();
+ for (int i = startIndex; i < endIndex; i++)
+ {
+ RINOK(OpenDir(i, _items[i].Offset, level + 1));
+ }
+ return S_OK;
+}
+
+HRESULT CHandler::Open2(IInStream *inStream)
+{
+ Byte buf[kHeaderSize];
+ RINOK(ReadStream_FALSE(inStream, buf, kHeaderSize));
+ if (!_h.Parse(buf))
+ return S_FALSE;
+ if (_h.IsVer2())
+ {
+ if (_h.Size < kHeaderSize || _h.Size > kArcSizeMax || _h.NumFiles > kNumFilesMax)
+ return S_FALSE;
+ }
+ else
+ {
+ UInt64 size;
+ RINOK(inStream->Seek(0, STREAM_SEEK_END, &size));
+ if (size > kArcSizeMax)
+ return S_FALSE;
+ _h.Size = (UInt32)size;
+ RINOK(inStream->Seek(kHeaderSize, STREAM_SEEK_SET, NULL));
+ }
+ _data = (Byte *)MidAlloc(_h.Size);
+ if (_data == 0)
+ return E_OUTOFMEMORY;
+ memcpy(_data, buf, kHeaderSize);
+ size_t processed = _h.Size - kHeaderSize;
+ RINOK(ReadStream(inStream, _data + kHeaderSize, &processed));
+ if (processed < kNodeSize)
+ return S_FALSE;
+ _size = kHeaderSize + (UInt32)processed;
+ if (_size != _h.Size)
+ _errorMessage = "Unexpected end of archive";
+ else
+ {
+ SetUi32(_data + 0x20, 0);
+ if (_h.IsVer2())
+ if (CrcCalc(_data, _h.Size) != _h.Crc)
+ _errorMessage = "CRC error";
+ }
+ if (_h.IsVer2())
+ _items.Reserve(_h.NumFiles - 1);
+ return OpenDir(-1, kHeaderSize, 0);
+}
+
+AString CHandler::GetPath(int index) const
+{
+ unsigned len = 0;
+ int indexMem = index;
+ do
+ {
+ const CItem &item = _items[index];
+ index = item.Parent;
+ const Byte *p = _data + item.Offset;
+ unsigned size = GetNameLen(p, _h.be);
+ p += kNodeSize;
+ unsigned i;
+ for (i = 0; i < size && p[i]; i++);
+ len += i + 1;
+ }
+ while (index >= 0);
+ len--;
+
+ AString path;
+ char *dest = path.GetBuffer(len) + len;
+ index = indexMem;
+ for (;;)
+ {
+ const CItem &item = _items[index];
+ index = item.Parent;
+ const Byte *p = _data + item.Offset;
+ unsigned size = GetNameLen(p, _h.be);
+ p += kNodeSize;
+ unsigned i;
+ for (i = 0; i < size && p[i]; i++);
+ dest -= i;
+ memcpy(dest, p, i);
+ if (index < 0)
+ break;
+ *(--dest) = CHAR_PATH_SEPARATOR;
+ }
+ path.ReleaseBuffer(len);
+ return path;
+}
+
+bool CHandler::GetPackSize(int index, UInt32 &res) const
+{
+ const CItem &item = _items[index];
+ const Byte *p = _data + item.Offset;
+ bool be = _h.be;
+ UInt32 offset = GetOffset(p, be);
+ if (offset < kHeaderSize)
+ return false;
+ UInt32 numBlocks = (GetSize(p, be) + kBlockSize - 1) >> kBlockSizeLog;
+ UInt32 start = offset + numBlocks * 4;
+ if (start > _size)
+ return false;
+ UInt32 end = Get32(_data + start - 4);
+ if (end < start)
+ return false;
+ res = end - start;
+ return true;
+}
+
+STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback * /* callback */)
+{
+ COM_TRY_BEGIN
+ {
+ Close();
+ RINOK(Open2(stream));
+ _stream = stream;
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+void CHandler::Free()
+{
+ MidFree(_data);
+ _data = 0;
+}
+
+STDMETHODIMP CHandler::Close()
+{
+ _headersSize = 0;
+ _items.Clear();
+ _stream.Release();
+ _errorMessage.Empty();
+ Free();
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = _items.Size();
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant prop;
+ switch(propID)
+ {
+ case kpidName:
+ {
+ char dest[kHeaderNameSize + 4];
+ memcpy(dest, _h.Name, kHeaderNameSize);
+ dest[kHeaderNameSize] = 0;
+ prop = dest;
+ break;
+ }
+ case kpidBigEndian: prop = _h.be; break;
+ case kpidCharacts: FLAGS_TO_PROP(k_Flags, _h.Flags, prop); break;
+ case kpidNumBlocks: if (_h.IsVer2()) prop = _h.NumBlocks; break;
+ case kpidNumSubFiles: if (_h.IsVer2()) prop = _h.NumFiles; break;
+ case kpidPhySize: if (_h.IsVer2()) prop = _h.Size; break;
+ case kpidHeadersSize: prop = _headersSize; break;
+ case kpidError: if (!_errorMessage.IsEmpty()) prop = _errorMessage; break;
+ }
+ prop.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant prop;
+ const CItem &item = _items[index];
+ const Byte *p = _data + item.Offset;
+ bool be = _h.be;
+ bool isDir = IsDir(p, be);
+ switch(propID)
+ {
+ case kpidPath: prop = MultiByteToUnicodeString(GetPath(index), CP_OEMCP); break;
+ case kpidIsDir: prop = isDir; break;
+ // case kpidOffset: prop = (UInt32)GetOffset(p, be); break;
+ case kpidSize: if (!isDir) prop = GetSize(p, be); break;
+ case kpidPackSize:
+ if (!isDir)
+ {
+ UInt32 size;
+ if (GetPackSize(index, size))
+ prop = size;
+ }
+ break;
+ case kpidPosixAttrib: prop = (UInt32)GetMode(p, be); break;
+ }
+ prop.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+class CCramfsInStream: public CCachedInStream
+{
+ HRESULT ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize);
+public:
+ CHandler *Handler;
+};
+
+HRESULT CCramfsInStream::ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize)
+{
+ return Handler->ReadBlock(blockIndex, dest, blockSize);
+}
+
+HRESULT CHandler::ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize)
+{
+ if (!_zlibDecoder)
+ {
+ _zlibDecoderSpec = new NCompress::NZlib::CDecoder();
+ _zlibDecoder = _zlibDecoderSpec;
+ }
+ if (!_inStream)
+ {
+ _inStreamSpec = new CBufInStream();
+ _inStream = _inStreamSpec;
+ }
+ if (!_outStream)
+ {
+ _outStreamSpec = new CBufPtrSeqOutStream();
+ _outStream = _outStreamSpec;
+ }
+ bool be = _h.be;
+ const Byte *p = _data + (_curBlocksOffset + (UInt32)blockIndex * 4);
+ UInt32 start = (blockIndex == 0 ? _curBlocksOffset + _curNumBlocks * 4: Get32(p - 4));
+ UInt32 end = Get32(p);
+ if (end < start || end > _size)
+ return S_FALSE;
+ UInt32 inSize = end - start;
+ _inStreamSpec->Init(_data + start, inSize);
+ _outStreamSpec->Init(dest, blockSize);
+ RINOK(_zlibDecoder->Code(_inStream, _outStream, NULL, NULL, NULL));
+ return (_zlibDecoderSpec->GetInputProcessedSize() == inSize &&
+ _outStreamSpec->GetPos() == blockSize) ? S_OK : S_FALSE;
+}
+
+STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
+ Int32 testMode, IArchiveExtractCallback *extractCallback)
+{
+ COM_TRY_BEGIN
+ bool allFilesMode = (numItems == (UInt32)-1);
+ if (allFilesMode)
+ numItems = _items.Size();
+ if (numItems == 0)
+ return S_OK;
+ bool be = _h.be;
+ UInt64 totalSize = 0;
+ UInt32 i;
+ for (i = 0; i < numItems; i++)
+ {
+ const Byte *p = _data + _items[allFilesMode ? i : indices[i]].Offset;
+ if (!IsDir(p, be))
+ totalSize += GetSize(p, be);
+ }
+ extractCallback->SetTotal(totalSize);
+
+ UInt64 totalPackSize;
+ totalSize = totalPackSize = 0;
+
+ NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
+ CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
+
+ CLocalProgress *lps = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> progress = lps;
+ lps->Init(extractCallback, false);
+
+ CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
+ CMyComPtr<ISequentialInStream> inStream(streamSpec);
+ streamSpec->SetStream(_stream);
+
+ for (i = 0; i < numItems; i++)
+ {
+ lps->InSize = totalPackSize;
+ lps->OutSize = totalSize;
+ RINOK(lps->SetCur());
+ CMyComPtr<ISequentialOutStream> outStream;
+ Int32 askMode = testMode ?
+ NExtract::NAskMode::kTest :
+ NExtract::NAskMode::kExtract;
+ UInt32 index = allFilesMode ? i : indices[i];
+ const CItem &item = _items[index];
+ RINOK(extractCallback->GetStream(index, &outStream, askMode));
+ const Byte *p = _data + item.Offset;
+
+ if (IsDir(p, be))
+ {
+ RINOK(extractCallback->PrepareOperation(askMode));
+ RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
+ continue;
+ }
+ UInt32 curSize = GetSize(p, be);
+ totalSize += curSize;
+ UInt32 packSize;
+ if (GetPackSize(index, packSize))
+ totalPackSize += packSize;
+
+ if (!testMode && !outStream)
+ continue;
+ RINOK(extractCallback->PrepareOperation(askMode));
+
+ UInt32 offset = GetOffset(p, be);
+ if (offset < kHeaderSize)
+ curSize = 0;
+
+ int res = NExtract::NOperationResult::kDataError;
+ {
+ CMyComPtr<ISequentialInStream> inSeqStream;
+ CMyComPtr<IInStream> inStream;
+ HRESULT hres = GetStream(index, &inSeqStream);
+ if (inSeqStream)
+ inSeqStream.QueryInterface(IID_IInStream, &inStream);
+ if (hres == E_OUTOFMEMORY)
+ return E_OUTOFMEMORY;
+ if (hres == S_FALSE || !inStream)
+ res = NExtract::NOperationResult::kUnSupportedMethod;
+ else
+ {
+ RINOK(hres);
+ if (inStream)
+ {
+ HRESULT hres = copyCoder->Code(inStream, outStream, NULL, NULL, progress);
+ if (hres != S_OK && hres != S_FALSE)
+ {
+ RINOK(hres);
+ }
+ if (copyCoderSpec->TotalSize == curSize && hres == S_OK)
+ res = NExtract::NOperationResult::kOK;
+ }
+ }
+ }
+ RINOK(extractCallback->SetOperationResult(res));
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
+{
+ COM_TRY_BEGIN
+
+ const CItem &item = _items[index];
+ const Byte *p = _data + item.Offset;
+
+ bool be = _h.be;
+ if (IsDir(p, be))
+ return E_FAIL;
+
+ UInt32 size = GetSize(p, be);
+ UInt32 numBlocks = (size + kBlockSize - 1) >> kBlockSizeLog;
+ UInt32 offset = GetOffset(p, be);
+ if (offset < kHeaderSize)
+ {
+ if (offset != 0)
+ return S_FALSE;
+ CBufInStream *streamSpec = new CBufInStream;
+ CMyComPtr<IInStream> streamTemp = streamSpec;
+ streamSpec->Init(NULL, 0);
+ *stream = streamTemp.Detach();
+ return S_OK;
+ }
+
+ if (offset + numBlocks * 4 > _size)
+ return S_FALSE;
+ UInt32 prev = offset;
+ for (UInt32 i = 0; i < numBlocks; i++)
+ {
+ UInt32 next = Get32(_data + offset + i * 4);
+ if (next < prev || next > _size)
+ return S_FALSE;
+ prev = next;
+ }
+
+ CCramfsInStream *streamSpec = new CCramfsInStream;
+ CMyComPtr<IInStream> streamTemp = streamSpec;
+ _curNumBlocks = numBlocks;
+ _curBlocksOffset = offset;
+ streamSpec->Handler = this;
+ if (!streamSpec->Alloc(kBlockSizeLog, 21 - kBlockSizeLog))
+ return E_OUTOFMEMORY;
+ streamSpec->Init(size);
+ *stream = streamTemp.Detach();
+
+ return S_OK;
+ COM_TRY_END
+}
+
+static IInArchive *CreateArc() { return new NArchive::NCramfs::CHandler; }
+
+static CArcInfo g_ArcInfo =
+ { L"CramFS", L"cramfs", 0, 0xD3, SIGNATURE, kSignatureSize, false, CreateArc, 0 };
+
+REGISTER_ARC(Cramfs)
+
+}}
diff --git a/CPP/7zip/Archive/ElfHandler.cpp b/CPP/7zip/Archive/ElfHandler.cpp
index 6f5a6776..c4ad78e9 100755
--- a/CPP/7zip/Archive/ElfHandler.cpp
+++ b/CPP/7zip/Archive/ElfHandler.cpp
@@ -277,9 +277,9 @@ static const CUInt32PCharPair g_AbiOS[] =
static const CUInt32PCharPair g_SegmentFlags[] =
{
- { 1 << 0, "Execute" },
- { 1 << 1, "Write" },
- { 1 << 2, "Read" }
+ { 0, "Execute" },
+ { 1, "Write" },
+ { 2, "Read" }
};
static const char *g_Types[] =
diff --git a/CPP/7zip/Archive/Icons/squashfs.ico b/CPP/7zip/Archive/Icons/squashfs.ico
new file mode 100755
index 00000000..551a7439
--- /dev/null
+++ b/CPP/7zip/Archive/Icons/squashfs.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Iso/IsoHandler.cpp b/CPP/7zip/Archive/Iso/IsoHandler.cpp
index dc20c240..4bfb7dc6 100755
--- a/CPP/7zip/Archive/Iso/IsoHandler.cpp
+++ b/CPP/7zip/Archive/Iso/IsoHandler.cpp
@@ -24,7 +24,7 @@ using namespace NTime;
namespace NArchive {
namespace NIso {
-static STATPROPSTG kProps[] =
+static const STATPROPSTG kProps[] =
{
{ NULL, kpidPath, VT_BSTR},
{ NULL, kpidIsDir, VT_BOOL},
@@ -33,8 +33,17 @@ static STATPROPSTG kProps[] =
{ NULL, kpidMTime, VT_FILETIME}
};
+static const STATPROPSTG kArcProps[] =
+{
+ { NULL, kpidComment, VT_BSTR},
+ { NULL, kpidCTime, VT_FILETIME},
+ { NULL, kpidMTime, VT_FILETIME}
+ // { NULL, kpidPhySize, VT_UI8},
+ // { NULL, kpidHeadersSize, VT_UI8}
+};
+
IMP_IInArchive_Props
-IMP_IInArchive_ArcProps_NO
+IMP_IInArchive_ArcProps
STDMETHODIMP CHandler::Open(IInStream *stream,
const UInt64 * /* maxCheckStartPosition */,
@@ -66,6 +75,58 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
return S_OK;
}
+static void AddString(AString &s, const char *name, const Byte *p, int size)
+{
+ int i;
+ for (i = 0; i < size && p[i]; i++);
+ for (; i > 0 && p[i - 1] == ' '; i--);
+ if (i != 0)
+ {
+ AString d;
+ memcpy(d.GetBuffer(i), p, i);
+ d.ReleaseBuffer(i);
+ s += '\n';
+ s += name;
+ s += ": ";
+ s += d;
+ }
+}
+
+#define ADD_STRING(n, v) AddString(s, n, vol. ## v, sizeof(vol. ## v))
+
+STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant prop;
+ const CVolumeDescriptor &vol = _archive.VolDescs[_archive.MainVolDescIndex];
+ switch(propID)
+ {
+ case kpidComment:
+ {
+ AString s;
+ ADD_STRING("System", SystemId);
+ ADD_STRING("Volume", VolumeId);
+ ADD_STRING("VolumeSet", VolumeSetId);
+ ADD_STRING("Publisher", PublisherId);
+ ADD_STRING("Preparer", DataPreparerId);
+ ADD_STRING("Application", ApplicationId);
+ ADD_STRING("Copyright", CopyrightFileId);
+ ADD_STRING("Abstract", AbstractFileId);
+ ADD_STRING("Bib", BibFileId);
+ prop = s;
+ break;
+ }
+ case kpidCTime: { FILETIME utc; if (vol.CTime.GetFileTime(utc)) prop = utc; break; }
+ case kpidMTime: { FILETIME utc; if (vol.MTime.GetFileTime(utc)) prop = utc; break; }
+ // case kpidPhySize: break;
+ // case kpidHeadersSize: break;
+ case kpidError: if (_archive.IncorrectBigEndian) prop = "Incorrect big-endian headers"; break;
+ }
+ prop.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
@@ -87,9 +148,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
prop = (const wchar_t *)s;
break;
}
- case kpidIsDir:
- prop = false;
- break;
+ case kpidIsDir: prop = false; break;
case kpidSize:
case kpidPackSize:
prop = (UInt64)_archive.GetBootItemSize(index);
@@ -121,9 +180,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
prop = (const wchar_t *)NItemName::GetOSName2(s);
}
break;
- case kpidIsDir:
- prop = item.IsDir();
- break;
+ case kpidIsDir: prop = item.IsDir(); break;
case kpidSize:
case kpidPackSize:
if (!item.IsDir())
@@ -131,16 +188,9 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
break;
case kpidMTime:
{
- FILETIME utcFileTime;
- if (item.DateTime.GetFileTime(utcFileTime))
- prop = utcFileTime;
- /*
- else
- {
- utcFileTime.dwLowDateTime = 0;
- utcFileTime.dwHighDateTime = 0;
- }
- */
+ FILETIME utc;
+ if (item.DateTime.GetFileTime(utc))
+ prop = utc;
break;
}
}
diff --git a/CPP/7zip/Archive/Iso/IsoIn.cpp b/CPP/7zip/Archive/Iso/IsoIn.cpp
index 84143348..7ed618d2 100755
--- a/CPP/7zip/Archive/Iso/IsoIn.cpp
+++ b/CPP/7zip/Archive/Iso/IsoIn.cpp
@@ -65,7 +65,7 @@ UInt16 CInArchive::ReadUInt16()
for (int i = 0; i < 2; i++)
{
if (b[i] != b[3 - i])
- throw 1;
+ IncorrectBigEndian = true;
value |= ((UInt16)(b[i]) << (8 * i));
}
return (UInt16)value;
@@ -440,6 +440,7 @@ HRESULT CInArchive::Open(IInStream *inStream)
void CInArchive::Clear()
{
+ IncorrectBigEndian = false;
Refs.Clear();
_rootDir.Clear();
VolDescs.Clear();
diff --git a/CPP/7zip/Archive/Iso/IsoIn.h b/CPP/7zip/Archive/Iso/IsoIn.h
index 49687e27..f9c6f640 100755
--- a/CPP/7zip/Archive/Iso/IsoIn.h
+++ b/CPP/7zip/Archive/Iso/IsoIn.h
@@ -111,6 +111,20 @@ struct CDateTime
signed char GmtOffset; // min intervals from -48 (West) to +52 (East) recorded.
bool NotSpecified() const { return Year == 0 && Month == 0 && Day == 0 &&
Hour == 0 && Minute == 0 && Second == 0 && GmtOffset == 0; }
+
+ bool GetFileTime(FILETIME &ft) const
+ {
+ UInt64 value;
+ bool res = NWindows::NTime::GetSecondsSince1601(Year, Month, Day, Hour, Minute, Second, value);
+ if (res)
+ {
+ value -= (UInt64)((Int64)GmtOffset * 15 * 60);
+ value *= 10000000;
+ }
+ ft.dwLowDateTime = (DWORD)value;
+ ft.dwHighDateTime = (DWORD)(value >> 32);
+ return res;
+ }
};
struct CBootRecordDescriptor
@@ -268,6 +282,7 @@ public:
int MainVolDescIndex;
UInt32 BlockSize;
CObjectVector<CBootInitialEntry> BootEntries;
+ bool IncorrectBigEndian;
bool IsJoliet() const { return VolDescs[MainVolDescIndex].IsJoliet(); }
diff --git a/CPP/7zip/Archive/LzhHandler.cpp b/CPP/7zip/Archive/LzhHandler.cpp
index c568ee4c..95efc501 100755
--- a/CPP/7zip/Archive/LzhHandler.cpp
+++ b/CPP/7zip/Archive/LzhHandler.cpp
@@ -266,7 +266,7 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
return (startHeader[0] == 0) ? S_OK: S_FALSE;
const Byte *p = header;
- memmove(item.Method, p, kMethodIdSize);
+ memcpy(item.Method, p, kMethodIdSize);
if (!item.IsValidMethod())
return S_OK;
p += kMethodIdSize;
diff --git a/CPP/7zip/Archive/MachoHandler.cpp b/CPP/7zip/Archive/MachoHandler.cpp
index ad4a5afb..a6261f34 100755
--- a/CPP/7zip/Archive/MachoHandler.cpp
+++ b/CPP/7zip/Archive/MachoHandler.cpp
@@ -77,16 +77,16 @@ static const char *g_FileTypes[] =
static const CUInt32PCharPair g_Flags[] =
{
- { (UInt32)1 << 31, "PURE_INSTRUCTIONS" },
- { 1 << 30, "NO_TOC" },
- { 1 << 29, "STRIP_STATIC_SYMS" },
- { 1 << 28, "NO_DEAD_STRIP" },
- { 1 << 27, "LIVE_SUPPORT" },
- { 1 << 26, "SELF_MODIFYING_CODE" },
- { 1 << 25, "DEBUG" },
- { 1 << 10, "SOME_INSTRUCTIONS" },
- { 1 << 9, "EXT_RELOC" },
- { 1 << 8, "LOC_RELOC" }
+ { 31, "PURE_INSTRUCTIONS" },
+ { 30, "NO_TOC" },
+ { 29, "STRIP_STATIC_SYMS" },
+ { 28, "NO_DEAD_STRIP" },
+ { 27, "LIVE_SUPPORT" },
+ { 26, "SELF_MODIFYING_CODE" },
+ { 25, "DEBUG" },
+ { 10, "SOME_INSTRUCTIONS" },
+ { 9, "EXT_RELOC" },
+ { 8, "LOC_RELOC" }
};
static const CUInt32PCharPair g_MachinePairs[] =
diff --git a/CPP/7zip/Archive/PeHandler.cpp b/CPP/7zip/Archive/PeHandler.cpp
index 506e944a..c64067aa 100755
--- a/CPP/7zip/Archive/PeHandler.cpp
+++ b/CPP/7zip/Archive/PeHandler.cpp
@@ -300,53 +300,53 @@ void CSection::Parse(const Byte *p)
static const CUInt32PCharPair g_HeaderCharacts[] =
{
- { 1 << 1, "Executable" },
- { 1 << 13, "DLL" },
- { 1 << 8, "32-bit" },
- { 1 << 5, "LargeAddress" },
- { 1 << 0, "NoRelocs" },
- { 1 << 2, "NoLineNums" },
- { 1 << 3, "NoLocalSyms" },
- { 1 << 4, "AggressiveWsTrim" },
- { 1 << 9, "NoDebugInfo" },
- { 1 << 10, "RemovableRun" },
- { 1 << 11, "NetRun" },
- { 1 << 12, "System" },
- { 1 << 14, "UniCPU" },
- { 1 << 7, "Little-Endian" },
- { 1 << 15, "Big-Endian" }
+ { 1, "Executable" },
+ { 13, "DLL" },
+ { 8, "32-bit" },
+ { 5, "LargeAddress" },
+ { 0, "NoRelocs" },
+ { 2, "NoLineNums" },
+ { 3, "NoLocalSyms" },
+ { 4, "AggressiveWsTrim" },
+ { 9, "NoDebugInfo" },
+ { 10, "RemovableRun" },
+ { 11, "NetRun" },
+ { 12, "System" },
+ { 14, "UniCPU" },
+ { 7, "Little-Endian" },
+ { 15, "Big-Endian" }
};
static const CUInt32PCharPair g_DllCharacts[] =
{
- { 1 << 6, "Relocated" },
- { 1 << 7, "Integrity" },
- { 1 << 8, "NX-Compatible" },
- { 1 << 9, "NoIsolation" },
- { 1 << 10, "NoSEH" },
- { 1 << 11, "NoBind" },
- { 1 << 13, "WDM" },
- { 1 << 15, "TerminalServerAware" }
+ { 6, "Relocated" },
+ { 7, "Integrity" },
+ { 8, "NX-Compatible" },
+ { 9, "NoIsolation" },
+ { 10, "NoSEH" },
+ { 11, "NoBind" },
+ { 13, "WDM" },
+ { 15, "TerminalServerAware" }
};
static const CUInt32PCharPair g_SectFlags[] =
{
- { 1 << 3, "NoPad" },
- { 1 << 5, "Code" },
- { 1 << 6, "InitializedData" },
- { 1 << 7, "UninitializedData" },
- { 1 << 9, "Comments" },
- { 1 << 11, "Remove" },
- { 1 << 12, "COMDAT" },
- { 1 << 15, "GP" },
- { 1 << 24, "ExtendedRelocations" },
- { 1 << 25, "Discardable" },
- { 1 << 26, "NotCached" },
- { 1 << 27, "NotPaged" },
- { 1 << 28, "Shared" },
- { 1 << 29, "Execute" },
- { 1 << 30, "Read" },
- { (UInt32)1 << 31, "Write" }
+ { 3, "NoPad" },
+ { 5, "Code" },
+ { 6, "InitializedData" },
+ { 7, "UninitializedData" },
+ { 9, "Comments" },
+ { 11, "Remove" },
+ { 12, "COMDAT" },
+ { 15, "GP" },
+ { 24, "ExtendedRelocations" },
+ { 25, "Discardable" },
+ { 26, "NotCached" },
+ { 27, "NotPaged" },
+ { 28, "Shared" },
+ { 29, "Execute" },
+ { 30, "Read" },
+ { 31, "Write" }
};
static const CUInt32PCharPair g_MachinePairs[] =
@@ -1723,6 +1723,14 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
size_t offset = item.Offset - sect.Va;
if (!CheckItem(sect, item, offset))
return S_FALSE;
+ if (item.HeaderSize == 0)
+ {
+ CBufInStream *streamSpec = new CBufInStream;
+ CMyComPtr<IInStream> streamTemp2 = streamSpec;
+ streamSpec->Init(_buf + offset, item.Size, (IInArchive *)this);
+ *stream = streamTemp2.Detach();
+ return S_OK;
+ }
referenceBuf->Buf.SetCapacity(item.HeaderSize + item.Size);
memcpy(referenceBuf->Buf, item.Header, item.HeaderSize);
memcpy(referenceBuf->Buf + item.HeaderSize, _buf + offset, item.Size);
diff --git a/CPP/7zip/Archive/Rar/RarHandler.cpp b/CPP/7zip/Archive/Rar/RarHandler.cpp
index 8906614a..54709f6c 100755
--- a/CPP/7zip/Archive/Rar/RarHandler.cpp
+++ b/CPP/7zip/Archive/Rar/RarHandler.cpp
@@ -46,7 +46,7 @@ static const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]);
static const wchar_t *kUnknownOS = L"Unknown";
-STATPROPSTG kProps[] =
+static const STATPROPSTG kProps[] =
{
{ NULL, kpidPath, VT_BSTR},
{ NULL, kpidIsDir, VT_BOOL},
@@ -68,7 +68,7 @@ STATPROPSTG kProps[] =
{ NULL, kpidUnpackVer, VT_UI1}
};
-STATPROPSTG kArcProps[] =
+static const STATPROPSTG kArcProps[] =
{
{ NULL, kpidSolid, VT_BOOL},
{ NULL, kpidNumBlocks, VT_UI4},
@@ -93,7 +93,7 @@ UInt64 CHandler::GetPackSize(int refIndex) const
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
- // COM_TRY_BEGIN
+ COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop;
switch(propID)
{
@@ -112,10 +112,11 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
prop = (UInt32)numBlocks;
break;
}
+ case kpidError: if (!_errorMessage.IsEmpty()) prop = _errorMessage; break;
}
prop.Detach(value);
return S_OK;
- // COM_TRY_END
+ COM_TRY_END
}
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
@@ -396,7 +397,14 @@ HRESULT CHandler::Open2(IInStream *stream,
for (;;)
{
bool decryptionError;
- HRESULT result = archive.GetNextItem(item, getTextPassword, decryptionError);
+ AString errorMessageLoc;
+ HRESULT result = archive.GetNextItem(item, getTextPassword, decryptionError, errorMessageLoc);
+ if (errorMessageLoc)
+ {
+ if (!_errorMessage.IsEmpty())
+ _errorMessage += '\n';
+ _errorMessage += errorMessageLoc;
+ }
if (result == S_FALSE)
{
if (decryptionError && _items.IsEmpty())
@@ -461,6 +469,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
STDMETHODIMP CHandler::Close()
{
COM_TRY_BEGIN
+ _errorMessage.Empty();
_refItems.Clear();
_items.Clear();
_archives.Clear();
diff --git a/CPP/7zip/Archive/Rar/RarHandler.h b/CPP/7zip/Archive/Rar/RarHandler.h
index 58e3fefc..c8015b2a 100755
--- a/CPP/7zip/Archive/Rar/RarHandler.h
+++ b/CPP/7zip/Archive/Rar/RarHandler.h
@@ -32,6 +32,7 @@ private:
CObjectVector<CItemEx> _items;
CObjectVector<CInArchive> _archives;
NArchive::NRar::CInArchiveInfo _archiveInfo;
+ AString _errorMessage;
DECL_EXTERNAL_CODECS_VARS
diff --git a/CPP/7zip/Archive/Rar/RarHeader.h b/CPP/7zip/Archive/Rar/RarHeader.h
index 4df42e62..8bb1da21 100755
--- a/CPP/7zip/Archive/Rar/RarHeader.h
+++ b/CPP/7zip/Archive/Rar/RarHeader.h
@@ -18,16 +18,16 @@ namespace NBlockType
{
enum EBlockType
{
- kMarker = 0x72,
- kArchiveHeader = 0x73,
- kFileHeader = 0x74,
- kCommentHeader = 0x75,
- kOldAuthenticity = 0x76,
- kSubBlock = 0x77,
- kRecoveryRecord = 0x78,
- kAuthenticity = 0x79,
-
- kEndOfArchive = 0x7B // Is not safe
+ kMarker = 0x72,
+ kArchiveHeader,
+ kFileHeader,
+ kCommentHeader,
+ kOldAuthenticity,
+ kOldSubBlock,
+ kRecoveryRecord,
+ kAuthenticity,
+ kSubBlock,
+ kEndOfArchive
};
}
diff --git a/CPP/7zip/Archive/Rar/RarIn.cpp b/CPP/7zip/Archive/Rar/RarIn.cpp
index c5d30fac..7d64c6fd 100755
--- a/CPP/7zip/Archive/Rar/RarIn.cpp
+++ b/CPP/7zip/Archive/Rar/RarIn.cpp
@@ -372,14 +372,14 @@ void CInArchive::AddToSeekValue(UInt64 addValue)
m_Position += addValue;
}
-HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPassword, bool &decryptionError)
+HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPassword, bool &decryptionError, AString &errorMessage)
{
decryptionError = false;
if (m_SeekOnArchiveComment)
SkipArchiveComment();
for (;;)
{
- if(!SeekInArchive(m_Position))
+ if (!SeekInArchive(m_Position))
return S_FALSE;
if (!m_CryptoMode && (m_ArchiveHeader.Flags &
NHeader::NArchive::kBlockHeadersAreEncrypted) != 0)
@@ -438,8 +438,11 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa
}
m_FileHeaderData.EnsureCapacity(7);
- if(!ReadBytesAndTestSize((Byte *)m_FileHeaderData, 7))
+ if (!ReadBytesAndTestSize((Byte *)m_FileHeaderData, 7))
+ {
+ errorMessage = "Unexpected end of archive";
return S_FALSE;
+ }
m_CurData = (Byte *)m_FileHeaderData;
m_CurPos = 0;
diff --git a/CPP/7zip/Archive/Rar/RarIn.h b/CPP/7zip/Archive/Rar/RarIn.h
index 5d9f67a3..75c98cc4 100755
--- a/CPP/7zip/Archive/Rar/RarIn.h
+++ b/CPP/7zip/Archive/Rar/RarIn.h
@@ -110,7 +110,7 @@ class CInArchive
public:
HRESULT Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit);
void Close();
- HRESULT GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPassword, bool &decryptionError);
+ HRESULT GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPassword, bool &decryptionError, AString &errorMessage);
void SkipArchiveComment();
diff --git a/CPP/7zip/Archive/RpmHandler.cpp b/CPP/7zip/Archive/RpmHandler.cpp
index f533e78f..1d31d451 100755
--- a/CPP/7zip/Archive/RpmHandler.cpp
+++ b/CPP/7zip/Archive/RpmHandler.cpp
@@ -79,7 +79,7 @@ static HRESULT RedSigHeaderSig(IInStream *inStream, CSigHeaderSig &h)
char dat[kCSigHeaderSigSize];
char *cur = dat;
RINOK(ReadStream_FALSE(inStream, dat, kCSigHeaderSigSize));
- memmove(h.Magic, cur, 4);
+ memcpy(h.Magic, cur, 4);
cur += 4;
cur += 4;
h.IndexLen = Get32(cur);
@@ -95,7 +95,7 @@ HRESULT OpenArchive(IInStream *inStream)
char *cur = leadData;
CLead lead;
RINOK(ReadStream_FALSE(inStream, leadData, kLeadSize));
- memmove(lead.Magic, cur, 4);
+ memcpy(lead.Magic, cur, 4);
cur += 4;
lead.Major = *cur++;
lead.Minor = *cur++;
@@ -103,7 +103,7 @@ HRESULT OpenArchive(IInStream *inStream)
cur += 2;
lead.ArchNum = Get16(cur);
cur += 2;
- memmove(lead.Name, cur, sizeof(lead.Name));
+ memcpy(lead.Name, cur, sizeof(lead.Name));
cur += sizeof(lead.Name);
lead.OSNum = Get16(cur);
cur += 2;
diff --git a/CPP/7zip/Archive/SplitHandler.cpp b/CPP/7zip/Archive/SplitHandler.cpp
index e3129c6a..5d84de4e 100755
--- a/CPP/7zip/Archive/SplitHandler.cpp
+++ b/CPP/7zip/Archive/SplitHandler.cpp
@@ -347,7 +347,6 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
{
CMultiStream::CSubStreamInfo subStreamInfo;
subStreamInfo.Stream = _streams[i];
- subStreamInfo.Pos = 0;
subStreamInfo.Size = _sizes[i];
streamSpec->Streams.Add(subStreamInfo);
}
diff --git a/CPP/7zip/Archive/SquashfsHandler.cpp b/CPP/7zip/Archive/SquashfsHandler.cpp
new file mode 100755
index 00000000..e09c09de
--- /dev/null
+++ b/CPP/7zip/Archive/SquashfsHandler.cpp
@@ -0,0 +1,1959 @@
+// SquashfsHandler.cpp
+
+#include "StdAfx.h"
+
+#include "../../../C/7zCrc.h"
+#include "../../../C/Alloc.h"
+#include "../../../C/CpuArch.h"
+
+#include "Common/ComTry.h"
+#include "Common/IntToString.h"
+#include "Common/StringConvert.h"
+
+#include "Windows/PropVariantUtils.h"
+#include "Windows/Time.h"
+
+#include "../Common/LimitedStreams.h"
+#include "../Common/ProgressUtils.h"
+#include "../Common/RegisterArc.h"
+#include "../Common/StreamObjects.h"
+#include "../Common/StreamUtils.h"
+
+#include "../Compress/CopyCoder.h"
+#include "../Compress/ZlibDecoder.h"
+#include "../Compress/LzmaDecoder.h"
+
+namespace NArchive {
+namespace NSquashfs {
+
+static const UInt32 kNumFilesMax = (1 << 28);
+static const unsigned kNumDirLevelsMax = (1 << 10);
+
+// Layout: Header, Data, inodes, Directories, Fragments, UIDs, GIDs
+
+/*
+#define Get16(p) (be ? GetBe16(p) : GetUi16(p))
+#define Get32(p) (be ? GetBe32(p) : GetUi32(p))
+#define Get64(p) (be ? GetBe64(p) : GetUi64(p))
+*/
+
+UInt16 Get16b(const Byte *p, bool be) { return be ? GetBe16(p) : GetUi16(p); }
+UInt32 Get32b(const Byte *p, bool be) { return be ? GetBe32(p) : GetUi32(p); }
+UInt64 Get64b(const Byte *p, bool be) { return be ? GetBe64(p) : GetUi64(p); }
+
+#define Get16(p) Get16b(p, be)
+#define Get32(p) Get32b(p, be)
+#define Get64(p) Get64b(p, be)
+
+#define LE_16(offs, dest) dest = GetUi16(p + (offs));
+#define LE_32(offs, dest) dest = GetUi32(p + (offs));
+#define LE_64(offs, dest) dest = GetUi64(p + (offs));
+
+#define GET_16(offs, dest) dest = Get16(p + (offs));
+#define GET_32(offs, dest) dest = Get32(p + (offs));
+#define GET_64(offs, dest) dest = Get64(p + (offs));
+
+static const UInt32 kSignatureSize = 4;
+#define SIGNATURE { 'h', 's', 'q', 's' }
+static const UInt32 kSignature32_LE = 0x73717368;
+static const UInt32 kSignature32_BE = 0x68737173;
+static const UInt32 kSignature32_LZ = 0x71736873;
+
+#define kMethod_ZLIB 1
+#define kMethod_LZMA 2
+#define kMethod_LZO 3
+
+static const char *k_Methods[] =
+{
+ "Unknown",
+ "ZLIB",
+ "LZMA",
+ "LZO"
+};
+
+static const UInt32 kMetadataBlockSizeLog = 13;
+static const UInt32 kMetadataBlockSize = (1 << kMetadataBlockSizeLog);
+
+#define MY_S_IFIFO 0x1000
+#define MY_S_IFCHR 0x2000
+#define MY_S_IFDIR 0x4000
+#define MY_S_IFBLK 0x6000
+#define MY_S_IFREG 0x8000
+#define MY_S_IFLNK 0xA000
+#define MY_S_IFSOCK 0xC000
+
+enum
+{
+ kType_IPC,
+ kType_DIR,
+ kType_FILE,
+ kType_LNK,
+ kType_BLK,
+ kType_CHR,
+ kType_FIFO,
+ kType_SOCK
+};
+
+static const UInt32 k_TypeToMode[] =
+{
+ 0,
+ MY_S_IFDIR, MY_S_IFREG, MY_S_IFLNK, MY_S_IFBLK, MY_S_IFCHR, MY_S_IFIFO, MY_S_IFSOCK,
+ MY_S_IFDIR, MY_S_IFREG, MY_S_IFLNK, MY_S_IFBLK, MY_S_IFCHR, MY_S_IFIFO, MY_S_IFSOCK
+};
+
+
+enum
+{
+ kFlag_UNC_INODES,
+ kFlag_UNC_DATA,
+ kFlag_CHECK,
+ kFlag_UNC_FRAGS,
+ kFlag_NO_FRAGS,
+ kFlag_ALWAYS_FRAG,
+ kFlag_DUPLICATE,
+ kFlag_EXPORT
+};
+
+static const CUInt32PCharPair k_Flags[] =
+{
+ { kFlag_UNC_INODES, "UNCOMPRESSED_INODES" },
+ { kFlag_UNC_DATA, "UNCOMPRESSED_DATA" },
+ { kFlag_CHECK, "CHECK" },
+ { kFlag_UNC_FRAGS, "UNCOMPRESSED_FRAGMENTS" },
+ { kFlag_NO_FRAGS, "NO_FRAGMENTS" },
+ { kFlag_ALWAYS_FRAG, "ALWAYS_FRAGMENTS" },
+ { kFlag_DUPLICATE, "DUPLICATES_REMOVED" },
+ { kFlag_EXPORT, "EXPORTABLE" }
+};
+
+static const UInt32 kNotCompressedBit16 = (1 << 15);
+static const UInt32 kNotCompressedBit32 = (1 << 24);
+
+#define GET_COMPRESSED_BLOCK_SIZE(size) ((size) & ~kNotCompressedBit32)
+#define IS_COMPRESSED_BLOCK(size) (((size) & kNotCompressedBit32) == 0)
+
+static const UInt32 kHeaderSize1 = 0x33;
+static const UInt32 kHeaderSize2 = 0x3F;
+static const UInt32 kHeaderSize3 = 0x77;
+static const UInt32 kHeaderSize4 = 0x60;
+
+struct CHeader
+{
+ bool be;
+ bool SeveralMethods;
+ Byte NumUids;
+ Byte NumGids;
+
+ UInt32 NumInodes;
+ UInt32 CTime;
+ UInt32 BlockSize;
+ UInt32 NumFrags;
+ UInt16 Method;
+ UInt16 BlockSizeLog;
+ UInt16 Flags;
+ UInt16 NumIDs;
+ UInt16 Major;
+ UInt16 Minor;
+ UInt64 RootInode;
+ UInt64 Size;
+ UInt64 UidTable;
+ UInt64 GidTable;
+ UInt64 XattrIdTable;
+ UInt64 InodeTable;
+ UInt64 DirTable;
+ UInt64 FragTable;
+ UInt64 LookupTable;
+
+ void Parse3(const Byte *p)
+ {
+ Method = kMethod_ZLIB;
+ GET_32 (0x08, Size);
+ GET_32 (0x0C, UidTable);
+ GET_32 (0x10, GidTable);
+ GET_32 (0x14, InodeTable);
+ GET_32 (0x18, DirTable);
+ GET_16 (0x20, BlockSize);
+ GET_16 (0x22, BlockSizeLog);
+ Flags = p[0x24];
+ NumUids = p[0x25];
+ NumGids = p[0x26];
+ GET_32 (0x27, CTime);
+ GET_64 (0x2B, RootInode);
+ NumFrags = 0;
+ FragTable = UidTable;
+
+ if (Major >= 2)
+ {
+ GET_32 (0x33, BlockSize);
+ GET_32 (0x37, NumFrags);
+ GET_32 (0x3B, FragTable);
+ if (Major == 3)
+ {
+ GET_64 (0x3F, Size);
+ GET_64 (0x47, UidTable);
+ GET_64 (0x4F, GidTable);
+ GET_64 (0x57, InodeTable);
+ GET_64 (0x5F, DirTable);
+ GET_64 (0x67, FragTable);
+ GET_64 (0x6F, LookupTable);
+ }
+ }
+ }
+
+ void Parse4(const Byte *p)
+ {
+ LE_32 (0x08, CTime);
+ LE_32 (0x0C, BlockSize);
+ LE_32 (0x10, NumFrags);
+ LE_16 (0x14, Method);
+ LE_16 (0x16, BlockSizeLog);
+ LE_16 (0x18, Flags);
+ LE_16 (0x1A, NumIDs);
+ LE_64 (0x20, RootInode);
+ LE_64 (0x28, Size);
+ LE_64 (0x30, UidTable);
+ LE_64 (0x38, XattrIdTable);
+ LE_64 (0x40, InodeTable);
+ LE_64 (0x48, DirTable);
+ LE_64 (0x50, FragTable);
+ LE_64 (0x58, LookupTable);
+ GidTable = 0;
+ }
+
+ bool Parse(const Byte *p)
+ {
+ be = false;
+ SeveralMethods = false;
+ switch (GetUi32(p))
+ {
+ case kSignature32_LE: break;
+ case kSignature32_BE: be = true; break;
+ case kSignature32_LZ: SeveralMethods = true; break;
+ default: return false;
+ }
+ GET_32 (4, NumInodes);
+ GET_16 (0x1C, Major);
+ GET_16 (0x1E, Minor);
+ if (Major <= 3)
+ Parse3(p);
+ else
+ {
+ if (be)
+ return false;
+ Parse4(p);
+ }
+ return
+ InodeTable < DirTable &&
+ DirTable <= FragTable &&
+ FragTable <= Size &&
+ UidTable <= Size &&
+ BlockSizeLog >= 12 &&
+ BlockSizeLog < 31 &&
+ BlockSize == ((UInt32)1 << BlockSizeLog);
+ }
+
+ bool IsSupported() const { return Major > 0 && Major <= 4 && BlockSizeLog <= 23; }
+ bool IsOldVersion() const { return Major < 4; }
+ bool NeedCheckData() const { return (Flags & (1 << kFlag_CHECK)) != 0; }
+ unsigned GetFileNameOffset() const { return Major <= 2 ? 3 : (Major == 3 ? 5 : 8); }
+ unsigned GetSymLinkOffset() const { return Major <= 1 ? 5: (Major <= 2 ? 6: (Major == 3 ? 18 : 24)); }
+ unsigned GetSpecGuidIndex() const { return Major <= 1 ? 0xF: 0xFF; }
+};
+
+static const UInt32 kFrag_Empty = (UInt32)(Int32)-1;
+// static const UInt32 kXattr_Empty = (UInt32)(Int32)-1;
+
+struct CNode
+{
+ UInt16 Type;
+ UInt16 Mode;
+ UInt16 Uid;
+ UInt16 Gid;
+ UInt32 Frag;
+ UInt32 Offset;
+ // UInt32 MTime;
+ // UInt32 Number;
+ // UInt32 NumLinks;
+ // UInt32 RDev;
+ // UInt32 Xattr;
+ // UInt32 Parent;
+
+ UInt64 FileSize;
+ UInt64 StartBlock;
+ // UInt64 Sparse;
+
+ UInt32 Parse1(const Byte *p, UInt32 size, const CHeader &_h);
+ UInt32 Parse2(const Byte *p, UInt32 size, const CHeader &_h);
+ UInt32 Parse3(const Byte *p, UInt32 size, const CHeader &_h);
+ UInt32 Parse4(const Byte *p, UInt32 size, const CHeader &_h);
+
+ bool IsDir() const { return (Type == kType_DIR || Type == kType_DIR + 7); }
+ bool IsLink() const { return (Type == kType_LNK || Type == kType_LNK + 7); }
+ UInt64 GetSize() const { return IsDir() ? 0 : FileSize; }
+
+ bool ThereAreFrags() const { return Frag != kFrag_Empty; }
+ UInt64 GetNumBlocks(const CHeader &_h) const
+ {
+ return (FileSize >> _h.BlockSizeLog) +
+ (!ThereAreFrags() && (FileSize & (_h.BlockSize - 1)) != 0);
+ }
+};
+
+UInt32 CNode::Parse1(const Byte *p, UInt32 size, const CHeader &_h)
+{
+ bool be = _h.be;
+ if (size < 4)
+ return 0;
+ UInt16 t = Get16(p);
+ if (be)
+ {
+ Type = t >> 12;
+ Mode = t & 0xFFF;
+ Uid = p[2] >> 4;
+ Gid = p[2] & 0xF;
+ }
+ else
+ {
+ Type = t & 0xF;
+ Mode = t >> 4;
+ Uid = p[2] & 0xF;
+ Gid = p[2] >> 4;
+ }
+
+ // Xattr = kXattr_Empty;
+ // MTime = 0;
+ FileSize = 0;
+ StartBlock = 0;
+ Frag = kFrag_Empty;
+
+ if (Type == 0)
+ {
+ Byte t = p[3];
+ if (be)
+ {
+ Type = t >> 4;
+ Offset = t & 0xF;
+ }
+ else
+ {
+ Type = t & 0xF;
+ Offset = t >> 4;
+ }
+ return (Type == kType_FIFO || Type == kType_SOCK) ? 4 : 0;
+ }
+
+ Type--;
+ Uid += (Type / 5) * 16;
+ Type = (Type % 5) + 1;
+
+ if (Type == kType_FILE)
+ {
+ if (size < 15)
+ return 0;
+ // GET_32 (3, MTime);
+ GET_32 (7, StartBlock);
+ UInt32 t;
+ GET_32 (11, t);
+ FileSize = t;
+ UInt32 numBlocks = t >> _h.BlockSizeLog;
+ if ((t & (_h.BlockSize - 1)) != 0)
+ numBlocks++;
+ UInt32 pos = numBlocks * 2 + 15;
+ return (pos <= size) ? pos : 0;
+ }
+
+ if (Type == kType_DIR)
+ {
+ if (size < 14)
+ return 0;
+ UInt32 t = Get32(p + 3);
+ if (be)
+ {
+ FileSize = t >> 13;
+ Offset = t & 0x1FFF;
+ }
+ else
+ {
+ FileSize = t & 0x7FFFF;
+ Offset = t >> 19;
+ }
+ // GET_32 (7, MTime);
+ GET_32 (10, StartBlock);
+ if (be)
+ StartBlock &= 0xFFFFFF;
+ else
+ StartBlock >>= 8;
+ return 14;
+ }
+
+ if (size < 5)
+ return 0;
+
+ if (Type == kType_LNK)
+ {
+ UInt32 len;
+ GET_16 (3, len);
+ FileSize = len;
+ len += 5;
+ return (len <= size) ? len : 0;
+ }
+
+ // GET_32 (3, RDev);
+ return 5;
+}
+
+UInt32 CNode::Parse2(const Byte *p, UInt32 size, const CHeader &_h)
+{
+ bool be = _h.be;
+ if (size < 4)
+ return 0;
+ UInt16 t = Get16(p);
+ if (be)
+ {
+ Type = t >> 12;
+ Mode = t & 0xFFF;
+ }
+ else
+ {
+ Type = t & 0xF;
+ Mode = t >> 4;
+ }
+ Uid = p[2];
+ Gid = p[3];
+
+ // Xattr = kXattr_Empty;
+
+ if (Type == kType_FILE)
+ {
+ if (size < 24)
+ return 0;
+ // GET_32 (4, MTime);
+ GET_32 (8, StartBlock);
+ GET_32 (12, Frag);
+ GET_32 (16, Offset);
+ UInt32 t;
+ GET_32 (20, t);
+ FileSize = t;
+ UInt32 numBlocks = t >> _h.BlockSizeLog;
+ if (!ThereAreFrags() && (t & (_h.BlockSize - 1)) != 0)
+ numBlocks++;
+ UInt32 pos = numBlocks * 4 + 24;
+ return (pos <= size) ? (UInt32)pos : 0;
+ }
+
+ FileSize = 0;
+ // MTime = 0;
+ StartBlock = 0;
+ Frag = kFrag_Empty;
+
+ if (Type == kType_DIR)
+ {
+ if (size < 15)
+ return 0;
+ UInt32 t = Get32(p + 4);
+ if (be)
+ {
+ FileSize = t >> 13;
+ Offset = t & 0x1FFF;
+ }
+ else
+ {
+ FileSize = t & 0x7FFFF;
+ Offset = t >> 19;
+ }
+ // GET_32 (8, MTime);
+ GET_32 (11, StartBlock);
+ if (be)
+ StartBlock &= 0xFFFFFF;
+ else
+ StartBlock >>= 8;
+ return 15;
+ }
+
+ if (Type == kType_DIR + 7)
+ {
+ if (size < 18)
+ return 0;
+ UInt32 t = Get32(p + 4);
+ UInt32 t2 = Get16(p + 7);
+ if (be)
+ {
+ FileSize = t >> 5;
+ Offset = t2 & 0x1FFF;
+ }
+ else
+ {
+ FileSize = t & 0x7FFFFFF;
+ Offset = t2 >> 3;
+ }
+ // GET_32 (9, MTime);
+ GET_32 (12, StartBlock);
+ if (be)
+ StartBlock &= 0xFFFFFF;
+ else
+ StartBlock >>= 8;
+ UInt32 iCount;
+ GET_16 (16, iCount);
+ UInt32 pos = 18;
+ for (UInt32 i = 0; i < iCount; i++)
+ {
+ // 27 bits: index
+ // 29 bits: startBlock
+ if (pos + 8 > size)
+ return 0;
+ pos += 8 + (UInt32)p[pos + 7] + 1; // nameSize
+ if (pos > size)
+ return 0;
+ }
+ return pos;
+ }
+
+ if (Type == kType_FIFO || Type == kType_SOCK)
+ return 4;
+
+ if (size < 6)
+ return 0;
+
+ if (Type == kType_LNK)
+ {
+ UInt32 len;
+ GET_16 (4, len);
+ FileSize = len;
+ len += 6;
+ return (len <= size) ? len : 0;
+ }
+
+ if (Type == kType_BLK || Type == kType_CHR)
+ {
+ // GET_16 (4, RDev);
+ return 6;
+ }
+
+ return 0;
+}
+
+UInt32 CNode::Parse3(const Byte *p, UInt32 size, const CHeader &_h)
+{
+ bool be = _h.be;
+ if (size < 12)
+ return 0;
+ UInt16 t = Get16(p);
+ if (be)
+ {
+ Type = t >> 12;
+ Mode = t & 0xFFF;
+ }
+ else
+ {
+ Type = t & 0xF;
+ Mode = t >> 4;
+ }
+ Uid = p[2];
+ Gid = p[3];
+ // GET_32 (4, MTime);
+ // GET_32 (8, Number);
+ // Xattr = kXattr_Empty;
+ FileSize = 0;
+ StartBlock = 0;
+
+ if (Type == kType_FILE || Type == kType_FILE + 7)
+ {
+ UInt32 offset;
+ if (Type == kType_FILE)
+ {
+ if (size < 32)
+ return 0;
+ GET_64 (12, StartBlock);
+ GET_32 (20, Frag);
+ GET_32 (24, Offset);
+ GET_32 (28, FileSize);
+ offset = 32;
+ }
+ else
+ {
+ if (size < 40)
+ return 0;
+ // GET_32 (12, NumLinks);
+ GET_64 (16, StartBlock);
+ GET_32 (24, Frag);
+ GET_32 (28, Offset);
+ GET_64 (32, FileSize);
+ offset = 40;
+ }
+ UInt64 pos = GetNumBlocks(_h) * 4 + offset;
+ return (pos <= size) ? (UInt32)pos : 0;
+ }
+
+ if (size < 16)
+ return 0;
+ // GET_32 (12, NumLinks);
+
+ if (Type == kType_DIR)
+ {
+ if (size < 28)
+ return 0;
+ UInt32 t = Get32(p + 16);
+ if (be)
+ {
+ FileSize = t >> 13;
+ Offset = t & 0x1FFF;
+ }
+ else
+ {
+ FileSize = t & 0x7FFFF;
+ Offset = t >> 19;
+ }
+ GET_32 (20, StartBlock);
+ // GET_32 (24, Parent);
+ return 28;
+ }
+
+ if (Type == kType_DIR + 7)
+ {
+ if (size < 31)
+ return 0;
+ UInt32 t = Get32(p + 16);
+ UInt32 t2 = Get16(p + 19);
+ if (be)
+ {
+ FileSize = t >> 5;
+ Offset = t2 & 0x1FFF;
+ }
+ else
+ {
+ FileSize = t & 0x7FFFFFF;
+ Offset = t2 >> 3;
+ }
+ GET_32 (21, StartBlock);
+ UInt32 iCount;
+ GET_16 (25, iCount);
+ // GET_32 (27, Parent);
+ UInt32 pos = 31;
+ for (UInt32 i = 0; i < iCount; i++)
+ {
+ // UInt32 index
+ // UInt32 startBlock
+ if (pos + 9 > size)
+ return 0;
+ pos += 9 + (unsigned)p[pos + 8] + 1; // nameSize
+ if (pos > size)
+ return 0;
+ }
+ return pos;
+ }
+
+ if (Type == kType_FIFO || Type == kType_SOCK)
+ return 16;
+
+ if (size < 18)
+ return 0;
+ if (Type == kType_LNK)
+ {
+ UInt32 len;
+ GET_16 (16, len);
+ FileSize = len;
+ len += 18;
+ return (len <= size) ? len : 0;
+ }
+
+ if (Type == kType_BLK || Type == kType_CHR)
+ {
+ // GET_16 (16, RDev);
+ return 18;
+ }
+
+ return 0;
+}
+
+UInt32 CNode::Parse4(const Byte *p, UInt32 size, const CHeader &_h)
+{
+ if (size < 20)
+ return 0;
+ LE_16 (0, Type);
+ LE_16 (2, Mode);
+ LE_16 (4, Uid);
+ LE_16 (6, Gid);
+ // LE_32 (8, MTime);
+ // LE_32 (12, Number);
+
+ // Xattr = kXattr_Empty;
+ FileSize = 0;
+ StartBlock = 0;
+
+ if (Type == kType_FILE || Type == kType_FILE + 7)
+ {
+ UInt32 offset;
+ if (Type == kType_FILE)
+ {
+ if (size < 32)
+ return 0;
+ LE_32 (16, StartBlock);
+ LE_32 (20, Frag);
+ LE_32 (24, Offset);
+ LE_32 (28, FileSize);
+ offset = 32;
+ }
+ else
+ {
+ if (size < 56)
+ return 0;
+ LE_64 (16, StartBlock);
+ LE_64 (24, FileSize);
+ // LE_64 (32, Sparse);
+ // LE_32 (40, NumLinks);
+ LE_32 (44, Frag);
+ LE_32 (48, Offset);
+ // LE_32 (52, Xattr);
+ offset = 56;
+ }
+ UInt64 pos = GetNumBlocks(_h) * 4 + offset;
+ return (pos <= size) ? (UInt32)pos : 0;
+ }
+
+ if (Type == kType_DIR)
+ {
+ if (size < 32)
+ return 0;
+ LE_32 (16, StartBlock);
+ // LE_32 (20, NumLinks);
+ LE_16 (24, FileSize);
+ LE_16 (26, Offset);
+ // LE_32 (28, Parent);
+ return 32;
+ }
+
+ // LE_32 (16, NumLinks);
+
+ if (Type == kType_DIR + 7)
+ {
+ if (size < 40)
+ return 0;
+ LE_32 (20, FileSize);
+ LE_32 (24, StartBlock);
+ // LE_32 (28, Parent);
+ UInt32 iCount;
+ LE_16 (32, iCount);
+ LE_16 (34, Offset);
+ // LE_32 (36, Xattr);
+
+ UInt32 pos = 40;
+ for (UInt32 i = 0; i < iCount; i++)
+ {
+ // UInt32 index
+ // UInt32 startBlock
+ if (pos + 12 > size)
+ return 0;
+ UInt32 nameLen = GetUi32(p + pos + 8);
+ pos += 12 + nameLen + 1;
+ if (pos > size || nameLen > (1 << 10))
+ return 0;
+ }
+ return pos;
+ }
+
+ unsigned offset = 20;
+ switch(Type)
+ {
+ case kType_FIFO: case kType_FIFO + 7:
+ case kType_SOCK: case kType_SOCK + 7:
+ break;
+ case kType_LNK: case kType_LNK + 7:
+ {
+ if (size < 24)
+ return 0;
+ UInt32 len;
+ LE_32 (20, len);
+ FileSize = len;
+ offset = len + 24;
+ if (size < offset || len > (1 << 30))
+ return 0;
+ break;
+ }
+ case kType_BLK: case kType_BLK + 7:
+ case kType_CHR: case kType_CHR + 7:
+ if (size < 24)
+ return 0;
+ // LE_32 (20, RDev);
+ offset = 24;
+ break;
+ default:
+ return 0;
+ }
+
+ if (Type >= 8)
+ {
+ if (size < offset + 4)
+ return 0;
+ // LE_32 (offset, Xattr);
+ offset += 4;
+ }
+ return offset;
+}
+
+struct CItem
+{
+ int Node;
+ int Parent;
+ UInt32 Ptr;
+};
+
+struct CData
+{
+ CByteBuffer Data;
+ CRecordVector<UInt32> PackPos;
+ CRecordVector<UInt32> UnpackPos; // additional item at the end contains TotalUnpackSize
+
+ UInt32 GetNumBlocks() const { return PackPos.Size(); }
+ void Clear()
+ {
+ Data.Free();
+ PackPos.Clear();
+ UnpackPos.Clear();
+ }
+};
+
+struct CFrag
+{
+ UInt64 StartBlock;
+ UInt32 Size;
+};
+
+class CHandler:
+ public IInArchive,
+ public IInArchiveGetStream,
+ public CMyUnknownImp
+{
+ CRecordVector<CItem> _items;
+ CRecordVector<CNode> _nodes;
+ CRecordVector<UInt32> _nodesPos;
+ CRecordVector<UInt32> _blockToNode;
+ CData _inodesData;
+ CData _dirs;
+ CRecordVector<CFrag> _frags;
+ // CByteBuffer _uids;
+ // CByteBuffer _gids;
+ CHeader _h;
+
+ CMyComPtr<IInStream> _stream;
+ UInt64 _sizeCalculated;
+
+ IArchiveOpenCallback *_openCallback;
+
+ int _nodeIndex;
+ CRecordVector<bool> _blockCompressed;
+ CRecordVector<UInt64> _blockOffsets;
+
+ CByteBuffer _cachedBlock;
+ UInt64 _cachedBlockStartPos;
+ UInt32 _cachedPackBlockSize;
+ UInt32 _cachedUnpackBlockSize;
+
+ CLimitedSequentialInStream *_limitedInStreamSpec;
+ CMyComPtr<ISequentialInStream> _limitedInStream;
+
+ CBufPtrSeqOutStream *_outStreamSpec;
+ CMyComPtr<ISequentialOutStream> _outStream;
+
+ NCompress::NLzma::CDecoder *_lzmaDecoderSpec;
+ CMyComPtr<ICompressCoder> _lzmaDecoder;
+
+ NCompress::NZlib::CDecoder *_zlibDecoderSpec;
+ CMyComPtr<ICompressCoder> _zlibDecoder;
+
+ CDynBufSeqOutStream *_dynOutStreamSpec;
+ CMyComPtr<ISequentialOutStream> _dynOutStream;
+
+ void ClearCache()
+ {
+ _cachedBlockStartPos = 0;
+ _cachedPackBlockSize = 0;
+ _cachedUnpackBlockSize = 0;
+ }
+
+ HRESULT Decompress(ISequentialOutStream *outStream, UInt32 inSize, UInt32 outSizeMax);
+ HRESULT ReadMetadataBlock(UInt32 &packSize);
+ HRESULT ReadData(CData &data, UInt64 start, UInt64 end);
+
+ HRESULT OpenDir(int parent, UInt32 startBlock, UInt32 offset, unsigned level, int &nodeIndex);
+ HRESULT ScanInodes(UInt64 ptr);
+ // HRESULT ReadUids(UInt64 start, UInt32 num, CByteBuffer &ids);
+ HRESULT Open2(IInStream *inStream);
+ AString GetPath(int index) const;
+ bool GetPackSize(int index, UInt64 &res, bool fillOffsets);
+
+public:
+ CHandler();
+ MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream)
+ INTERFACE_IInArchive(;)
+ STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
+
+ HRESULT ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize);
+};
+
+CHandler::CHandler()
+{
+ _limitedInStreamSpec = new CLimitedSequentialInStream;
+ _limitedInStream = _limitedInStreamSpec;
+
+ _outStreamSpec = new CBufPtrSeqOutStream();
+ _outStream = _outStreamSpec;
+
+ _dynOutStreamSpec = new CDynBufSeqOutStream;
+ _dynOutStream = _dynOutStreamSpec;
+}
+
+static const STATPROPSTG kProps[] =
+{
+ { NULL, kpidPath, VT_BSTR},
+ { NULL, kpidIsDir, VT_BOOL},
+ { NULL, kpidSize, VT_UI8},
+ { NULL, kpidPackSize, VT_UI8},
+ { NULL, kpidMTime, VT_FILETIME},
+ { NULL, kpidPosixAttrib, VT_UI4}
+ // { NULL, kpidUser, VT_BSTR},
+ // { NULL, kpidGroup, VT_BSTR},
+ // { NULL, kpidLinks, VT_UI4},
+ // { NULL, kpidOffset, VT_UI4}
+};
+
+static const STATPROPSTG kArcProps[] =
+{
+ { NULL, kpidFileSystem, VT_BSTR},
+ { NULL, kpidMethod, VT_BSTR},
+ { NULL, kpidBlock, VT_UI4},
+ { NULL, kpidPhySize, VT_UI8},
+ { NULL, kpidHeadersSize, VT_UI8},
+ { NULL, kpidBigEndian, VT_BOOL},
+ { NULL, kpidCTime, VT_FILETIME},
+ { NULL, kpidCharacts, VT_BSTR}
+ // { NULL, kpidNumBlocks, VT_UI4}
+};
+
+IMP_IInArchive_Props
+IMP_IInArchive_ArcProps
+
+HRESULT CHandler::Decompress(ISequentialOutStream *outStream, UInt32 inSize, UInt32 outSizeMax)
+{
+ UInt32 method = _h.Method;
+ if (_h.SeveralMethods)
+ {
+ Byte props[1];
+ RINOK(ReadStream_FALSE(_stream, props, 1));
+ method = (props[0] == 0x5D ? kMethod_LZMA : kMethod_ZLIB);
+ RINOK(_stream->Seek(-1, STREAM_SEEK_CUR, NULL));
+ }
+
+ if (method == kMethod_LZMA)
+ {
+ if (!_lzmaDecoder)
+ {
+ _lzmaDecoderSpec = new NCompress::NLzma::CDecoder();
+ _lzmaDecoder = _lzmaDecoderSpec;
+ }
+ const UInt32 kPropsSize = 5 + 8;
+ Byte props[kPropsSize];
+ ReadStream_FALSE(_limitedInStream, props, kPropsSize);
+ RINOK(_lzmaDecoderSpec->SetDecoderProperties2(props, 5));
+ UInt64 outSize = GetUi64(props + 5);
+ if (outSize > outSizeMax)
+ return S_FALSE;
+ RINOK(_lzmaDecoder->Code(_limitedInStream, outStream, NULL, &outSize, NULL));
+ if (inSize != kPropsSize + _lzmaDecoderSpec->GetInputProcessedSize())
+ return S_FALSE;
+ }
+ else
+ {
+ if (!_zlibDecoder)
+ {
+ _zlibDecoderSpec = new NCompress::NZlib::CDecoder();
+ _zlibDecoder = _zlibDecoderSpec;
+ }
+ RINOK(_zlibDecoder->Code(_limitedInStream, outStream, NULL, NULL, NULL));
+ if (inSize != _zlibDecoderSpec->GetInputProcessedSize())
+ return S_FALSE;
+ }
+ return S_OK;
+}
+
+HRESULT CHandler::ReadMetadataBlock(UInt32 &packSize)
+{
+ Byte temp[3];
+ unsigned offset = _h.NeedCheckData() ? 3 : 2;
+ if (offset > packSize)
+ return S_FALSE;
+ RINOK(ReadStream_FALSE(_stream, temp, offset));
+ // if (NeedCheckData && Major < 4) checkByte must be = 0xFF
+ bool be = _h.be;
+ UInt32 size = Get16(temp);
+ bool isCompressed = ((size & kNotCompressedBit16) == 0);
+ if (size != kNotCompressedBit16)
+ size &= ~kNotCompressedBit16;
+
+ if (size > kMetadataBlockSize || offset + size > packSize)
+ return S_FALSE;
+ packSize = offset + size;
+ if (isCompressed)
+ {
+ _limitedInStreamSpec->Init(size);
+ RINOK(Decompress(_dynOutStream, size, kMetadataBlockSize));
+ }
+ else
+ {
+ // size != 0 here
+ Byte *buf = _dynOutStreamSpec->GetBufPtrForWriting(size);
+ if (!buf)
+ return E_OUTOFMEMORY;
+ RINOK(ReadStream_FALSE(_stream, buf, size));
+ _dynOutStreamSpec->UpdateSize(size);
+ }
+ return S_OK;
+}
+
+HRESULT CHandler::ReadData(CData &data, UInt64 start, UInt64 end)
+{
+ if (end < start || end - start >= ((UInt64)1 << 32))
+ return S_FALSE;
+ UInt32 size = (UInt32)(end - start);
+ RINOK(_stream->Seek(start, STREAM_SEEK_SET, NULL));
+ _dynOutStreamSpec->Init();
+ UInt32 packPos = 0;
+ while (packPos != size)
+ {
+ data.PackPos.Add(packPos);
+ data.UnpackPos.Add((UInt32)_dynOutStreamSpec->GetSize());
+ if (packPos > size)
+ return S_FALSE;
+ UInt32 packSize = size - packPos;
+ RINOK(ReadMetadataBlock(packSize));
+ if (_dynOutStreamSpec->GetSize() >= ((UInt64)1 << 32))
+ return S_FALSE;
+ packPos += packSize;
+ }
+ data.UnpackPos.Add((UInt32)_dynOutStreamSpec->GetSize());
+ _dynOutStreamSpec->CopyToBuffer(data.Data);
+ return S_OK;
+}
+
+struct CTempItem
+{
+ UInt32 StartBlock;
+ // UInt32 iNodeNumber1;
+ UInt32 Offset;
+ // UInt16 iNodeNumber2;
+ UInt16 Type;
+};
+
+HRESULT CHandler::OpenDir(int parent, UInt32 startBlock, UInt32 offset, unsigned level, int &nodeIndex)
+{
+ if (level > kNumDirLevelsMax)
+ return S_FALSE;
+
+ int blockIndex = _inodesData.PackPos.FindInSorted(startBlock);
+ if (blockIndex < 0)
+ return S_FALSE;
+ UInt32 unpackPos = _inodesData.UnpackPos[blockIndex] + offset;
+ if (unpackPos < offset)
+ return S_FALSE;
+
+ nodeIndex = _nodesPos.FindInSorted(unpackPos, _blockToNode[blockIndex], _blockToNode[blockIndex + 1]);
+ // nodeIndex = _nodesPos.FindInSorted(unpackPos);
+ if (nodeIndex < 0)
+ return S_FALSE;
+
+ const CNode &n = _nodes[nodeIndex];
+ if (!n.IsDir())
+ return S_OK;
+ blockIndex = _dirs.PackPos.FindInSorted((UInt32)n.StartBlock);
+ if (blockIndex < 0)
+ return S_FALSE;
+ unpackPos = _dirs.UnpackPos[blockIndex] + n.Offset;
+ if (unpackPos < n.Offset || unpackPos > _dirs.Data.GetCapacity())
+ return S_FALSE;
+
+ UInt32 rem = (UInt32)_dirs.Data.GetCapacity() - unpackPos;
+ const Byte *p = _dirs.Data + unpackPos;
+ UInt32 fileSize = (UInt32)n.FileSize;
+
+ if (fileSize > rem)
+ return S_FALSE;
+ rem = fileSize;
+ if (_h.Major >= 3)
+ {
+ if (rem < 3)
+ return S_FALSE;
+ rem -= 3;
+ }
+
+ CRecordVector<CTempItem> tempItems;
+ while (rem != 0)
+ {
+ bool be = _h.be;
+ UInt32 count;
+ CTempItem tempItem;
+ if (_h.Major <= 2)
+ {
+ if (rem < 4)
+ return S_FALSE;
+ count = p[0];
+ tempItem.StartBlock = Get32(p);
+ if (be)
+ tempItem.StartBlock &= 0xFFFFFF;
+ else
+ tempItem.StartBlock >>= 8;
+ p += 4;
+ rem -= 4;
+ }
+ else
+ {
+ if (_h.Major == 3)
+ {
+ if (rem < 9)
+ return S_FALSE;
+ count = p[0];
+ p += 1;
+ rem -= 1;
+ }
+ else
+ {
+ if (rem < 12)
+ return S_FALSE;
+ count = GetUi32(p);
+ p += 4;
+ rem -= 4;
+ }
+ GET_32 (0, tempItem.StartBlock);
+ // GET_32 (4, tempItem.iNodeNumber1);
+ p += 8;
+ rem -= 8;
+ }
+ count++;
+
+ for (UInt32 i = 0; i < count; i++)
+ {
+ if (rem == 0)
+ return S_FALSE;
+
+ UInt32 nameOffset = _h.GetFileNameOffset();
+ if (rem < nameOffset)
+ return S_FALSE;
+
+ if ((UInt32)_items.Size() >= kNumFilesMax)
+ return S_FALSE;
+ if (_openCallback)
+ {
+ UInt64 numFiles = _items.Size();
+ if ((numFiles & 0xFFFF) == 0)
+ {
+ RINOK(_openCallback->SetCompleted(&numFiles, NULL));
+ }
+ }
+
+ CItem item;
+ item.Ptr = (UInt32)(p - _dirs.Data);
+
+ UInt32 size;
+ if (_h.IsOldVersion())
+ {
+ UInt32 t = Get16(p);
+ if (be)
+ {
+ tempItem.Offset = t >> 3;
+ tempItem.Type = (UInt16)(t & 0x7);
+ }
+ else
+ {
+ tempItem.Offset = t & 0x1FFF;
+ tempItem.Type = (UInt16)(t >> 13);
+ }
+ size = (UInt32)p[2];
+ /*
+ if (_h.Major > 2)
+ tempItem.iNodeNumber2 = Get16(p + 3);
+ */
+ }
+ else
+ {
+ GET_16 (0, tempItem.Offset);
+ // GET_16 (2, tempItem.iNodeNumber2);
+ GET_16 (4, tempItem.Type);
+ GET_16 (6, size);
+ }
+ p += nameOffset;
+ rem -= nameOffset;
+ size++;
+ if (rem < size)
+ return S_FALSE;
+ p += size;
+ rem -= size;
+ item.Parent = parent;
+ _items.Add(item);
+ tempItems.Add(tempItem);
+ }
+ }
+
+ int startItemIndex = _items.Size() - tempItems.Size();
+ for (int i = 0; i < tempItems.Size(); i++)
+ {
+ const CTempItem &tempItem = tempItems[i];
+ int index = startItemIndex + i;
+ CItem &item = _items[index];
+ RINOK(OpenDir(index, tempItem.StartBlock, tempItem.Offset, level + 1, item.Node));
+ }
+
+ return S_OK;
+}
+
+/*
+HRESULT CHandler::ReadUids(UInt64 start, UInt32 num, CByteBuffer &ids)
+{
+ size_t size = num * 4;
+ ids.SetCapacity(size);
+ RINOK(_stream->Seek(start, STREAM_SEEK_SET, NULL));
+ return ReadStream_FALSE(_stream, ids, size);
+}
+*/
+
+HRESULT CHandler::Open2(IInStream *inStream)
+{
+ {
+ Byte buf[kHeaderSize3];
+ RINOK(ReadStream_FALSE(inStream, buf, kHeaderSize3));
+ if (!_h.Parse(buf))
+ return S_FALSE;
+ if (!_h.IsSupported())
+ return E_NOTIMPL;
+
+ switch (_h.Method)
+ {
+ case kMethod_ZLIB:
+ case kMethod_LZMA:
+ break;
+ default:
+ return E_NOTIMPL;
+ }
+ }
+
+ _stream = inStream;
+
+ if (_h.NumFrags != 0)
+ {
+ if (_h.NumFrags > kNumFilesMax)
+ return S_FALSE;
+ _frags.Reserve(_h.NumFrags);
+ CByteBuffer data;
+ unsigned bigFrag = (_h.Major > 2);
+
+ unsigned fragPtrsInBlockLog = kMetadataBlockSizeLog - (3 + bigFrag);
+ UInt32 numBlocks = (_h.NumFrags + (1 << fragPtrsInBlockLog) - 1) >> fragPtrsInBlockLog;
+ size_t numBlocksBytes = (size_t)numBlocks << (2 + bigFrag);
+ data.SetCapacity(numBlocksBytes);
+ RINOK(inStream->Seek(_h.FragTable, STREAM_SEEK_SET, NULL));
+ RINOK(ReadStream_FALSE(inStream, data, numBlocksBytes));
+ bool be = _h.be;
+
+ for (UInt32 i = 0; i < numBlocks; i++)
+ {
+ UInt64 offset = bigFrag ? Get64(data + i * 8) : Get32(data + i * 4);
+ RINOK(_stream->Seek(offset, STREAM_SEEK_SET, NULL));
+ _dynOutStreamSpec->Init();
+ UInt32 packSize = kMetadataBlockSize + 3;
+ RINOK(ReadMetadataBlock(packSize));
+ UInt32 unpackSize = (UInt32)_dynOutStreamSpec->GetSize();
+ if (unpackSize != kMetadataBlockSize)
+ if (i != numBlocks - 1 || unpackSize != ((_h.NumFrags << (3 + bigFrag)) & (kMetadataBlockSize - 1)))
+ return S_FALSE;
+ const Byte *buf = _dynOutStreamSpec->GetBuffer();
+ for (UInt32 j = 0; j < kMetadataBlockSize && j < unpackSize;)
+ {
+ CFrag frag;
+ if (bigFrag)
+ {
+ frag.StartBlock = Get64(buf + j);
+ frag.Size = Get32(buf + j + 8);
+ // some archives contain nonzero in unused (buf + j + 12)
+ j += 16;
+ }
+ else
+ {
+ frag.StartBlock = Get32(buf + j);
+ frag.Size = Get32(buf + j + 4);
+ j += 8;
+ }
+ _frags.Add(frag);
+ }
+ }
+ if ((UInt32)_frags.Size() != _h.NumFrags)
+ return S_FALSE;
+ }
+
+ // RINOK(inStream->Seek(_h.InodeTable, STREAM_SEEK_SET, NULL));
+
+ RINOK(ReadData(_inodesData, _h.InodeTable, _h.DirTable));
+ RINOK(ReadData(_dirs, _h.DirTable, _h.FragTable));
+
+ UInt64 absOffset = _h.RootInode >> 16;
+ if (absOffset >= ((UInt64)1 << 32))
+ return S_FALSE;
+ {
+ UInt32 pos = 0;
+ UInt32 totalSize = (UInt32)_inodesData.Data.GetCapacity();
+ _nodesPos.Reserve(_h.NumInodes);
+ _nodes.Reserve(_h.NumInodes);
+ // we use _blockToNode for binary search seed optimizations
+ _blockToNode.Reserve(_inodesData.GetNumBlocks() + 1);
+ int curBlock = 0;
+ for (UInt32 i = 0; i < _h.NumInodes; i++)
+ {
+ CNode n;
+ const Byte *p = _inodesData.Data + pos;
+ UInt32 size = totalSize - pos;
+
+ switch(_h.Major)
+ {
+ case 1: size = n.Parse1(p, size, _h); break;
+ case 2: size = n.Parse2(p, size, _h); break;
+ case 3: size = n.Parse3(p, size, _h); break;
+ default: size = n.Parse4(p, size, _h); break;
+ }
+ if (size == 0)
+ return S_FALSE;
+ while (pos >= _inodesData.UnpackPos[curBlock])
+ {
+ _blockToNode.Add(_nodesPos.Size());
+ curBlock++;
+ }
+ _nodesPos.Add(pos);
+ _nodes.Add(n);
+ pos += size;
+ }
+ _blockToNode.Add(_nodesPos.Size());
+ if (pos != totalSize)
+ return S_FALSE;
+ }
+ int rootNodeIndex;
+ RINOK(OpenDir(-1, (UInt32)absOffset, (UInt32)_h.RootInode & 0xFFFF, 0, rootNodeIndex));
+
+ /*
+ if (_h.Major < 4)
+ {
+ RINOK(ReadUids(_h.UidTable, _h.NumUids, _uids));
+ RINOK(ReadUids(_h.GidTable, _h.NumGids, _gids));
+ }
+ else
+ {
+ UInt32 size = _h.NumIDs * 4;
+ _uids.SetCapacity(size);
+
+ UInt32 numBlocks = (size + kMetadataBlockSize - 1) / kMetadataBlockSize;
+ UInt32 numBlocksBytes = numBlocks << 3;
+ CByteBuffer data;
+ data.SetCapacity(numBlocksBytes);
+ RINOK(inStream->Seek(_h.UidTable, STREAM_SEEK_SET, NULL));
+ RINOK(ReadStream_FALSE(inStream, data, numBlocksBytes));
+
+ for (UInt32 i = 0; i < numBlocks; i++)
+ {
+ UInt64 offset = GetUi64(data + i * 8);
+ UInt32 unpackSize, packSize;
+ RINOK(_stream->Seek(offset, STREAM_SEEK_SET, NULL));
+ RINOK(ReadMetadataBlock(NULL, _uids + kMetadataBlockSize * i, packSize, unpackSize));
+ if (unpackSize != kMetadataBlockSize)
+ if (i != numBlocks - 1 || unpackSize != (size & (kMetadataBlockSize - 1)))
+ return S_FALSE;
+ }
+ }
+ */
+
+ {
+ const UInt32 alignSize = 1 << 12;
+ Byte buf[alignSize];
+ RINOK(inStream->Seek(_h.Size, STREAM_SEEK_SET, NULL));
+ UInt32 rem = (UInt32)(0 - _h.Size) & (alignSize - 1);
+ _sizeCalculated = _h.Size;
+ if (rem != 0)
+ {
+ if (ReadStream_FALSE(_stream, buf, rem) == S_OK)
+ {
+ size_t i;
+ for (i = 0; i < rem && buf[i] == 0; i++);
+ if (i == rem)
+ _sizeCalculated = _h.Size + rem;
+ }
+ }
+ }
+ return S_OK;
+}
+
+AString CHandler::GetPath(int index) const
+{
+ unsigned len = 0;
+ int indexMem = index;
+ bool be = _h.be;
+ do
+ {
+ const CItem &item = _items[index];
+ index = item.Parent;
+ const Byte *p = _dirs.Data + item.Ptr;
+ unsigned size = (_h.IsOldVersion() ? (unsigned)p[2] : (unsigned)Get16(p + 6)) + 1;
+ p += _h.GetFileNameOffset();
+ unsigned i;
+ for (i = 0; i < size && p[i]; i++);
+ len += i + 1;
+ }
+ while (index >= 0);
+ len--;
+
+ AString path;
+ char *dest = path.GetBuffer(len) + len;
+ index = indexMem;
+ for (;;)
+ {
+ const CItem &item = _items[index];
+ index = item.Parent;
+
+ const Byte *p = _dirs.Data + item.Ptr;
+ unsigned size = (_h.IsOldVersion() ? (unsigned)p[2] : (unsigned)Get16(p + 6)) + 1;
+ p += _h.GetFileNameOffset();
+ unsigned i;
+ for (i = 0; i < size && p[i]; i++);
+ dest -= i;
+ memcpy(dest, p, i);
+ if (index < 0)
+ break;
+ *(--dest) = CHAR_PATH_SEPARATOR;
+ }
+ path.ReleaseBuffer(len);
+ return path;
+}
+
+STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback)
+{
+ COM_TRY_BEGIN
+ {
+ Close();
+ _limitedInStreamSpec->SetStream(stream);
+ HRESULT res;
+ try
+ {
+ RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
+ _openCallback = callback;
+ res = Open2(stream);
+ }
+ catch(...)
+ {
+ Close();
+ throw;
+ }
+ if (res != S_OK)
+ {
+ Close();
+ return res;
+ }
+ _stream = stream;
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::Close()
+{
+ _limitedInStreamSpec->ReleaseStream();
+ _stream.Release();
+
+ _items.Clear();
+ _nodes.Clear();
+ _nodesPos.Clear();
+ _blockToNode.Clear();
+ _frags.Clear();
+ _inodesData.Clear();
+ _dirs.Clear();
+
+ // _uids.Free();
+ // _gids.Free();;
+
+ _cachedBlock.Free();
+ ClearCache();
+
+ return S_OK;
+}
+
+bool CHandler::GetPackSize(int index, UInt64 &totalPack, bool fillOffsets)
+{
+ totalPack = 0;
+ const CItem &item = _items[index];
+ const CNode &node = _nodes[item.Node];
+ UInt32 ptr = _nodesPos[item.Node];
+ const Byte *p = _inodesData.Data + ptr;
+ bool be = _h.be;
+
+ UInt32 type = node.Type;
+ UInt32 offset;
+ if (node.IsLink() || node.FileSize == 0)
+ {
+ totalPack = node.FileSize;
+ return true;
+ }
+
+ UInt32 numBlocks = (UInt32)node.GetNumBlocks(_h);
+
+ if (fillOffsets)
+ {
+ _blockOffsets.Clear();
+ _blockCompressed.Clear();
+ _blockOffsets.Add(totalPack);
+ }
+
+ if (_h.Major <= 1)
+ {
+ offset = 15;
+ p += offset;
+
+ for (UInt32 i = 0; i < numBlocks; i++)
+ {
+ UInt32 t = Get16(p + i * 2);
+ if (fillOffsets)
+ _blockCompressed.Add((t & kNotCompressedBit16) == 0);
+ if (t != kNotCompressedBit16)
+ t &= ~kNotCompressedBit16;
+ totalPack += t;
+ if (fillOffsets)
+ _blockOffsets.Add(totalPack);
+ }
+ }
+ else
+ {
+ if (_h.Major <= 2)
+ offset = 24;
+ else if (type == kType_FILE)
+ offset = 32;
+ else if (type == kType_FILE + 7)
+ offset = (_h.Major <= 3 ? 40 : 56);
+ else
+ return false;
+
+ p += offset;
+
+ for (UInt64 i = 0; i < numBlocks; i++)
+ {
+ UInt32 t = Get32(p + i * 4);
+ if (fillOffsets)
+ _blockCompressed.Add(IS_COMPRESSED_BLOCK(t));
+ UInt32 size = GET_COMPRESSED_BLOCK_SIZE(t);
+ if (size > _h.BlockSize)
+ return false;
+ totalPack += size;
+ if (fillOffsets)
+ _blockOffsets.Add(totalPack);
+ }
+
+ if (node.ThereAreFrags())
+ {
+ if (node.Frag >= (UInt32)_frags.Size())
+ return false;
+ const CFrag &frag = _frags[node.Frag];
+ if (node.Offset == 0)
+ {
+ UInt32 size = GET_COMPRESSED_BLOCK_SIZE(frag.Size);
+ if (size > _h.BlockSize)
+ return false;
+ totalPack += size;
+ }
+ }
+ }
+ return true;
+}
+
+
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = _items.Size();
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant prop;
+ switch(propID)
+ {
+ case kpidMethod:
+ {
+ const char *s;
+ if (_h.SeveralMethods)
+ s = "LZMA ZLIB";
+ else
+ {
+ s = k_Methods[0];
+ if (_h.Method < sizeof(k_Methods) / sizeof(k_Methods[0]))
+ s = k_Methods[_h.Method];
+ }
+ prop = s;
+ break;
+ }
+ case kpidFileSystem:
+ {
+ AString res = "SquashFS";
+ if (_h.SeveralMethods)
+ res += "-LZMA";
+ res += ' ';
+ char s[16];
+ ConvertUInt32ToString(_h.Major, s);
+ res += s;
+ res += '.';
+ ConvertUInt32ToString(_h.Minor, s);
+ res += s;
+ prop = res;
+ break;
+ }
+ case kpidBlock: prop = _h.BlockSize; break;
+ case kpidBigEndian: prop = _h.be; break;
+ case kpidCTime:
+ if (_h.CTime != 0)
+ {
+ FILETIME ft;
+ NWindows::NTime::UnixTimeToFileTime(_h.CTime, ft);
+ prop = ft;
+ }
+ break;
+ case kpidCharacts: FLAGS_TO_PROP(k_Flags, _h.Flags, prop); break;
+ // case kpidNumBlocks: prop = _h.NumFrags; break;
+ case kpidPhySize: prop = _sizeCalculated; break;
+ case kpidHeadersSize:
+ if (_sizeCalculated >= _h.InodeTable)
+ prop = _sizeCalculated - _h.InodeTable;
+ break;
+ }
+ prop.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant prop;
+ const CItem &item = _items[index];
+ const CNode &node = _nodes[item.Node];
+ bool isDir = node.IsDir();
+ bool be = _h.be;
+
+ switch(propID)
+ {
+ case kpidPath: prop = MultiByteToUnicodeString(GetPath(index), CP_OEMCP); break;
+ case kpidIsDir: prop = isDir; break;
+ // case kpidOffset: if (!node.IsLink()) prop = (UInt64)node.StartBlock; break;
+ case kpidSize: if (!isDir) prop = node.GetSize(); break;
+ case kpidPackSize:
+ if (!isDir)
+ {
+ UInt64 size;
+ if (GetPackSize(index, size, false))
+ prop = size;
+ }
+ break;
+ case kpidMTime:
+ {
+ UInt32 offset = 0;
+ switch(_h.Major)
+ {
+ case 1:
+ if (node.Type == kType_FILE)
+ offset = 3;
+ else if (node.Type == kType_DIR)
+ offset = 7;
+ break;
+ case 2:
+ if (node.Type == kType_FILE)
+ offset = 4;
+ else if (node.Type == kType_DIR)
+ offset = 8;
+ else if (node.Type == kType_DIR + 7)
+ offset = 9;
+ break;
+ case 3: offset = 4; break;
+ case 4: offset = 8; break;
+ }
+ if (offset != 0)
+ {
+ const Byte *p = _inodesData.Data + _nodesPos[item.Node] + offset;
+ FILETIME ft;
+ NWindows::NTime::UnixTimeToFileTime(Get32(p), ft);
+ prop = ft;
+ }
+ break;
+ }
+ case kpidPosixAttrib:
+ {
+ if (node.Type != 0 && node.Type < sizeof(k_TypeToMode) / sizeof(k_TypeToMode[0]))
+ prop = (UInt32)(node.Mode & 0xFFF) | k_TypeToMode[node.Type];
+ break;
+ }
+ /*
+ case kpidUser:
+ {
+ UInt32 offset = node.Uid * 4;
+ if (offset < _uids.GetCapacity())
+ prop = (UInt32)Get32(_uids + offset);
+ break;
+ }
+ case kpidGroup:
+ {
+ if (_h.Major == 4 || node.Gid == _h.GetSpecGuidIndex())
+ {
+ UInt32 offset = node.Uid * 4;
+ if (offset < _uids.GetCapacity())
+ prop = (UInt32)Get32(_uids + offset);
+ }
+ else
+ {
+ UInt32 offset = node.Gid * 4;
+ if (offset < _gids.GetCapacity())
+ prop = (UInt32)Get32(_gids + offset);
+ }
+ break;
+ }
+ */
+ /*
+ case kpidLinks:
+ if (_h.Major >= 3 && node.Type != kType_FILE)
+ prop = node.NumLinks;
+ break;
+ */
+ }
+ prop.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+class CSquashfsInStream: public CCachedInStream
+{
+ HRESULT ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize);
+public:
+ CHandler *Handler;
+};
+
+HRESULT CSquashfsInStream::ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize)
+{
+ return Handler->ReadBlock(blockIndex, dest, blockSize);
+}
+
+HRESULT CHandler::ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize)
+{
+ const CNode &node = _nodes[_nodeIndex];
+ UInt64 blockOffset;
+ UInt32 packBlockSize;
+ UInt32 offsetInBlock = 0;
+ bool compressed;
+ if (blockIndex < _blockCompressed.Size())
+ {
+ compressed = _blockCompressed[(int)blockIndex];
+ blockOffset = _blockOffsets[(int)blockIndex];
+ packBlockSize = (UInt32)(_blockOffsets[(int)blockIndex + 1] - blockOffset);
+ blockOffset += node.StartBlock;
+ }
+ else
+ {
+ if (!node.ThereAreFrags())
+ return S_FALSE;
+ const CFrag &frag = _frags[node.Frag];
+ offsetInBlock = node.Offset;
+ blockOffset = frag.StartBlock;
+ packBlockSize = GET_COMPRESSED_BLOCK_SIZE(frag.Size);
+ compressed = IS_COMPRESSED_BLOCK(frag.Size);
+ }
+
+ if (packBlockSize == 0)
+ {
+ // sparse file ???
+ memset(dest, 0, blockSize);
+ return S_OK;
+ }
+
+ if (blockOffset != _cachedBlockStartPos ||
+ packBlockSize != _cachedPackBlockSize)
+ {
+ ClearCache();
+ RINOK(_stream->Seek(blockOffset, STREAM_SEEK_SET, NULL));
+ _limitedInStreamSpec->Init(packBlockSize);
+
+ if (compressed)
+ {
+ _outStreamSpec->Init((Byte *)_cachedBlock, _h.BlockSize);
+ HRESULT res = Decompress(_outStream, packBlockSize, _h.BlockSize);
+ _cachedUnpackBlockSize = (UInt32)_outStreamSpec->GetPos();
+ RINOK(res);
+ }
+ else
+ {
+ RINOK(ReadStream_FALSE(_limitedInStream, _cachedBlock, packBlockSize));
+ _cachedUnpackBlockSize = packBlockSize;
+ }
+ _cachedBlockStartPos = blockOffset;
+ _cachedPackBlockSize = packBlockSize;
+ }
+ if (offsetInBlock + blockSize > _cachedUnpackBlockSize)
+ return S_FALSE;
+ memcpy(dest, _cachedBlock + offsetInBlock, blockSize);
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
+ Int32 testMode, IArchiveExtractCallback *extractCallback)
+{
+ COM_TRY_BEGIN
+ bool allFilesMode = (numItems == (UInt32)-1);
+ if (allFilesMode)
+ numItems = _items.Size();
+ if (numItems == 0)
+ return S_OK;
+ UInt64 totalSize = 0;
+ UInt32 i;
+ for (i = 0; i < numItems; i++)
+ {
+ const CItem &item = _items[allFilesMode ? i : indices[i]];
+ const CNode &node = _nodes[item.Node];
+ totalSize += node.GetSize();
+ }
+ extractCallback->SetTotal(totalSize);
+
+ UInt64 totalPackSize;
+ totalSize = totalPackSize = 0;
+
+ NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
+ CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
+
+ CLocalProgress *lps = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> progress = lps;
+ lps->Init(extractCallback, false);
+
+ for (i = 0; i < numItems; i++)
+ {
+ lps->InSize = totalPackSize;
+ lps->OutSize = totalSize;
+ RINOK(lps->SetCur());
+ CMyComPtr<ISequentialOutStream> outStream;
+ Int32 askMode = testMode ?
+ NExtract::NAskMode::kTest :
+ NExtract::NAskMode::kExtract;
+ UInt32 index = allFilesMode ? i : indices[i];
+ const CItem &item = _items[index];
+ const CNode &node = _nodes[item.Node];
+ RINOK(extractCallback->GetStream(index, &outStream, askMode));
+ // const Byte *p = _data + item.Offset;
+
+ if (node.IsDir())
+ {
+ RINOK(extractCallback->PrepareOperation(askMode));
+ RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
+ continue;
+ }
+ UInt64 unpackSize = node.GetSize();
+ totalSize += unpackSize;
+ UInt64 packSize;
+ if (GetPackSize(index, packSize, false))
+ totalPackSize += packSize;
+
+ if (!testMode && !outStream)
+ continue;
+ RINOK(extractCallback->PrepareOperation(askMode));
+
+ int res = NExtract::NOperationResult::kDataError;
+ {
+ CMyComPtr<ISequentialInStream> inSeqStream;
+ CMyComPtr<IInStream> inStream;
+ HRESULT hres = GetStream(index, &inSeqStream);
+ if (inSeqStream)
+ inSeqStream.QueryInterface(IID_IInStream, &inStream);
+ if (hres == S_FALSE || !inStream)
+ {
+ if (hres == E_OUTOFMEMORY)
+ return hres;
+ res = NExtract::NOperationResult::kUnSupportedMethod;
+ }
+ else
+ {
+ RINOK(hres);
+ if (inStream)
+ {
+ HRESULT hres = copyCoder->Code(inStream, outStream, NULL, NULL, progress);
+ if (hres != S_OK && hres != S_FALSE)
+ {
+ RINOK(hres);
+ }
+ if (copyCoderSpec->TotalSize == unpackSize && hres == S_OK)
+ res = NExtract::NOperationResult::kOK;
+ else
+ {
+ res = res;
+ }
+ }
+ }
+ }
+ RINOK(extractCallback->SetOperationResult(res));
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+
+STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
+{
+ COM_TRY_BEGIN
+
+ const CItem &item = _items[index];
+ const CNode &node = _nodes[item.Node];
+
+ if (node.IsDir())
+ return E_FAIL;
+
+ const Byte *p = _inodesData.Data + _nodesPos[item.Node];
+
+ if (node.FileSize == 0 || node.IsLink())
+ {
+ CBufInStream *streamSpec = new CBufInStream;
+ CMyComPtr<IInStream> streamTemp = streamSpec;
+ if (node.IsLink())
+ streamSpec->Init(p + _h.GetSymLinkOffset(), (size_t)node.FileSize);
+ else
+ streamSpec->Init(NULL, 0);
+ *stream = streamTemp.Detach();
+ return S_OK;
+ }
+
+ UInt64 packSize;
+ if (!GetPackSize(index, packSize, true))
+ return S_FALSE;
+
+ _nodeIndex = item.Node;
+
+ size_t cacheSize = _h.BlockSize;
+ if (_cachedBlock.GetCapacity() != cacheSize)
+ {
+ ClearCache();
+ _cachedBlock.SetCapacity(cacheSize);
+ }
+
+ CSquashfsInStream *streamSpec = new CSquashfsInStream;
+ CMyComPtr<IInStream> streamTemp = streamSpec;
+ streamSpec->Handler = this;
+ unsigned cacheSizeLog = 22;
+ if (cacheSizeLog <= _h.BlockSizeLog)
+ cacheSizeLog = _h.BlockSizeLog + 1;
+ if (!streamSpec->Alloc(_h.BlockSizeLog, cacheSizeLog - _h.BlockSizeLog))
+ return E_OUTOFMEMORY;
+ streamSpec->Init(node.FileSize);
+ *stream = streamTemp.Detach();
+
+ return S_OK;
+
+ COM_TRY_END
+}
+
+static IInArchive *CreateArc() { return new NArchive::NSquashfs::CHandler; }
+
+static CArcInfo g_ArcInfo =
+ { L"SquashFS", L"squashfs", 0, 0xD2, SIGNATURE, kSignatureSize, false, CreateArc, 0 };
+
+REGISTER_ARC(Cramfs)
+
+}}
diff --git a/CPP/7zip/Archive/Tar/TarHandler.cpp b/CPP/7zip/Archive/Tar/TarHandler.cpp
index e25463de..4db0cae8 100755
--- a/CPP/7zip/Archive/Tar/TarHandler.cpp
+++ b/CPP/7zip/Archive/Tar/TarHandler.cpp
@@ -10,6 +10,8 @@
#include "../../Common/LimitedStreams.h"
#include "../../Common/ProgressUtils.h"
+#include "../../Common/StreamObjects.h"
+#include "../../Common/StreamUtils.h"
#include "../Common/ItemNameUtils.h"
@@ -21,7 +23,9 @@ using namespace NWindows;
namespace NArchive {
namespace NTar {
-static STATPROPSTG kProps[] =
+static const char *kUnexpectedEnd = "Unexpected end of archive";
+
+static const STATPROPSTG kProps[] =
{
{ NULL, kpidPath, VT_BSTR},
{ NULL, kpidIsDir, VT_BOOL},
@@ -34,8 +38,14 @@ static STATPROPSTG kProps[] =
{ NULL, kpidLink, VT_BSTR}
};
+static const STATPROPSTG kArcProps[] =
+{
+ { NULL, kpidPhySize, VT_UI8},
+ { NULL, kpidHeadersSize, VT_UI8}
+};
+
IMP_IInArchive_Props
-IMP_IInArchive_ArcProps_NO_Table
+IMP_IInArchive_ArcProps
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
@@ -43,11 +53,22 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
switch(propID)
{
case kpidPhySize: if (_phySizeDefined) prop = _phySize; break;
+ case kpidHeadersSize: if (_phySizeDefined) prop = _headersSize; break;
+ case kpidError: if (!_errorMessage.IsEmpty()) prop = _errorMessage; break;
}
prop.Detach(value);
return S_OK;
}
+HRESULT CHandler::ReadItem2(ISequentialInStream *stream, bool &filled, CItemEx &item)
+{
+ item.HeaderPos = _phySize;
+ RINOK(ReadItem(stream, filled, item, _errorMessage));
+ _phySize += item.HeaderSize;
+ _headersSize += item.HeaderSize;
+ return S_OK;
+}
+
HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
{
UInt64 endPos = 0;
@@ -56,26 +77,29 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
}
- _isGood = true;
- UInt64 pos = 0;
+ _phySizeDefined = true;
for (;;)
{
CItemEx item;
bool filled;
- item.HeaderPosition = pos;
- RINOK(ReadItem(stream, filled, item));
+ RINOK(ReadItem2(stream, filled, item));
if (!filled)
break;
_items.Add(item);
- RINOK(stream->Seek(item.GetPackSize(), STREAM_SEEK_CUR, &pos));
- if (pos > endPos)
- return S_FALSE;
- if (pos == endPos)
+ RINOK(stream->Seek(item.GetPackSize(), STREAM_SEEK_CUR, &_phySize));
+ if (_phySize > endPos)
+ {
+ _errorMessage = kUnexpectedEnd;
+ break;
+ }
+ /*
+ if (_phySize == endPos)
{
- _isGood = false;
+ _errorMessage = "There are no trailing zero-filled records";
break;
}
+ */
if (callback != NULL)
{
if (_items.Size() == 1)
@@ -85,7 +109,7 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
if (_items.Size() % 100 == 0)
{
UInt64 numFiles = _items.Size();
- RINOK(callback->SetCompleted(&numFiles, &pos));
+ RINOK(callback->SetCompleted(&numFiles, &_phySize));
}
}
}
@@ -132,7 +156,10 @@ STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream)
STDMETHODIMP CHandler::Close()
{
+ _errorMessage.Empty();
_phySizeDefined = false;
+ _phySize = 0;
+ _headersSize = 0;
_curIndex = 0;
_latestIsRead = false;
_items.Clear();
@@ -161,16 +188,24 @@ HRESULT CHandler::SkipTo(UInt32 index)
{
UInt64 packSize = _latestItem.GetPackSize();
RINOK(copyCoderSpec->Code(_seqStream, NULL, &packSize, &packSize, NULL));
+ _phySize += copyCoderSpec->TotalSize;
+ if (copyCoderSpec->TotalSize != packSize)
+ {
+ _errorMessage = kUnexpectedEnd;
+ return S_FALSE;
+ }
_latestIsRead = false;
_curIndex++;
}
else
{
bool filled;
- // item.HeaderPosition = pos;
- RINOK(ReadItem(_seqStream, filled, _latestItem));
+ RINOK(ReadItem2(_seqStream, filled, _latestItem));
if (!filled)
+ {
+ _phySizeDefined = true;
return E_INVALIDARG;
+ }
_latestIsRead = true;
}
}
@@ -203,10 +238,10 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
switch(propID)
{
- case kpidPath: prop = NItemName::GetOSName2(TarStringToUnicode(item->Name)); break;
- case kpidIsDir: prop = item->IsDir(); break;
- case kpidSize: prop = item->Size; break;
- case kpidPackSize: prop = item->GetPackSize(); break;
+ case kpidPath: prop = NItemName::GetOSName2(TarStringToUnicode(item->Name)); break;
+ case kpidIsDir: prop = item->IsDir(); break;
+ case kpidSize: prop = item->GetUnpackSize(); break;
+ case kpidPackSize: prop = item->GetPackSize(); break;
case kpidMTime:
if (item->MTime != 0)
{
@@ -216,9 +251,9 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
}
break;
case kpidPosixAttrib: prop = item->Mode; break;
- case kpidUser: prop = TarStringToUnicode(item->User); break;
- case kpidGroup: prop = TarStringToUnicode(item->Group); break;
- case kpidLink: prop = TarStringToUnicode(item->LinkName); break;
+ case kpidUser: prop = TarStringToUnicode(item->User); break;
+ case kpidGroup: prop = TarStringToUnicode(item->Group); break;
+ case kpidLink: prop = TarStringToUnicode(item->LinkName); break;
}
prop.Detach(value);
return S_OK;
@@ -242,7 +277,7 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
UInt64 totalSize = 0;
UInt32 i;
for (i = 0; i < numItems; i++)
- totalSize += _items[allFilesMode ? i : indices[i]].Size;
+ totalSize += _items[allFilesMode ? i : indices[i]].GetUnpackSize();
extractCallback->SetTotal(totalSize);
UInt64 totalPackSize;
@@ -282,7 +317,8 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
item = &_items[index];
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
- totalSize += item->Size;
+ UInt64 unpackSize = item->GetUnpackSize();
+ totalSize += unpackSize;
totalPackSize += item->GetPackSize();
if (item->IsDir())
{
@@ -302,14 +338,21 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
outStreamSpec->SetStream(realOutStream);
realOutStream.Release();
- outStreamSpec->Init(skipMode ? 0 : item->Size, true);
+ outStreamSpec->Init(skipMode ? 0 : unpackSize, true);
- if (!seqMode)
+ if (item->IsLink())
+ {
+ RINOK(WriteStream(outStreamSpec, (const char *)item->LinkName, item->LinkName.Length()));
+ }
+ else
{
- RINOK(_stream->Seek(item->GetDataPosition(), STREAM_SEEK_SET, NULL));
+ if (!seqMode)
+ {
+ RINOK(_stream->Seek(item->GetDataPosition(), STREAM_SEEK_SET, NULL));
+ }
+ streamSpec->Init(item->GetPackSize());
+ RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
}
- streamSpec->Init(item->GetPackSize());
- RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
if (seqMode)
{
_latestIsRead = false;
@@ -328,6 +371,14 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
{
COM_TRY_BEGIN
const CItemEx &item = _items[index];
+ if (item.IsLink())
+ {
+ CBufInStream *streamSpec = new CBufInStream;
+ CMyComPtr<IInStream> streamTemp = streamSpec;
+ streamSpec->Init((const Byte *)(const char *)item.LinkName, item.LinkName.Length(), (IInArchive *)this);
+ *stream = streamTemp.Detach();
+ return S_OK;
+ }
return CreateLimitedInStream(_stream, item.GetDataPosition(), item.Size, stream);
COM_TRY_END
}
diff --git a/CPP/7zip/Archive/Tar/TarHandler.h b/CPP/7zip/Archive/Tar/TarHandler.h
index d2def9a1..b1967061 100755
--- a/CPP/7zip/Archive/Tar/TarHandler.h
+++ b/CPP/7zip/Archive/Tar/TarHandler.h
@@ -23,18 +23,20 @@ class CHandler:
CObjectVector<CItemEx> _items;
CMyComPtr<IInStream> _stream;
CMyComPtr<ISequentialInStream> _seqStream;
- bool _isGood;
UInt32 _curIndex;
bool _latestIsRead;
CItemEx _latestItem;
UInt64 _phySize;
+ UInt64 _headersSize;
bool _phySizeDefined;
+ AString _errorMessage;
NCompress::CCopyCoder *copyCoderSpec;
CMyComPtr<ICompressCoder> copyCoder;
+ HRESULT ReadItem2(ISequentialInStream *stream, bool &filled, CItemEx &itemInfo);
HRESULT Open2(IInStream *stream, IArchiveOpenCallback *callback);
HRESULT SkipTo(UInt32 index);
diff --git a/CPP/7zip/Archive/Tar/TarHandlerOut.cpp b/CPP/7zip/Archive/Tar/TarHandlerOut.cpp
index a999f838..ffdf2b13 100755
--- a/CPP/7zip/Archive/Tar/TarHandlerOut.cpp
+++ b/CPP/7zip/Archive/Tar/TarHandlerOut.cpp
@@ -37,7 +37,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
IArchiveUpdateCallback *callback)
{
COM_TRY_BEGIN
- if ((_stream && !_isGood) || _seqStream)
+ if ((_stream && !_errorMessage.IsEmpty()) || _seqStream)
return E_NOTIMPL;
CObjectVector<CUpdateItem> updateItems;
for (UInt32 i = 0; i < numItems; i++)
diff --git a/CPP/7zip/Archive/Tar/TarIn.cpp b/CPP/7zip/Archive/Tar/TarIn.cpp
index c9c3c422..5ceaa509 100755
--- a/CPP/7zip/Archive/Tar/TarIn.cpp
+++ b/CPP/7zip/Archive/Tar/TarIn.cpp
@@ -63,29 +63,40 @@ static void ReadString(const char *s, int size, AString &result)
result = temp;
}
-static HRESULT GetNextItemReal(ISequentialInStream *stream, bool &filled, CItemEx &item, size_t &processedSize)
+static HRESULT GetNextItemReal(ISequentialInStream *stream, bool &filled, CItemEx &item, AString &error)
{
- item.LongLinkSize = 0;
char buf[NFileHeader::kRecordSize];
char *p = buf;
+ error.Empty();
filled = false;
bool thereAreEmptyRecords = false;
for (;;)
{
- processedSize = NFileHeader::kRecordSize;
+ size_t processedSize = NFileHeader::kRecordSize;
RINOK(ReadStream(stream, buf, &processedSize));
if (processedSize == 0)
+ {
+ if (!thereAreEmptyRecords )
+ error = "There are no trailing zero-filled records";
return S_OK;
+ }
if (processedSize != NFileHeader::kRecordSize)
- return S_FALSE;
+ {
+ error = "There is no correct record at the end of archive";
+ return S_OK;
+ }
+ item.HeaderSize += NFileHeader::kRecordSize;
if (!IsRecordLast(buf))
break;
thereAreEmptyRecords = true;
}
if (thereAreEmptyRecords)
- return S_FALSE;
+ {
+ error = "There are data after end of archive";
+ return S_OK;
+ }
ReadString(p, NFileHeader::kNameSize, item.Name); p += NFileHeader::kNameSize;
@@ -143,59 +154,54 @@ static HRESULT GetNextItemReal(ISequentialInStream *stream, bool &filled, CItemE
return S_OK;
}
-HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &item)
+HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &item, AString &error)
{
- size_t processedSize;
- RINOK(GetNextItemReal(stream, filled, item, processedSize));
- if (!filled)
- return S_OK;
- // GNUtar extension
- if (item.LinkFlag == 'L' || // NEXT file has a long name
- item.LinkFlag == 'K') // NEXT file has a long linkname
+ item.HeaderSize = 0;
+ bool flagL = false;
+ bool flagK = false;
+ AString nameL;
+ AString nameK;
+ for (;;)
{
- if (item.Name.Compare(NFileHeader::kLongLink) != 0)
- if (item.Name.Compare(NFileHeader::kLongLink2) != 0)
+ RINOK(GetNextItemReal(stream, filled, item, error));
+ if (!filled)
+ return S_OK;
+ if (item.LinkFlag == 'L' || // NEXT file has a long name
+ item.LinkFlag == 'K') // NEXT file has a long linkname
+ {
+ AString *name;
+ if (item.LinkFlag == 'L')
+ { if (flagL) return S_FALSE; flagL = true; name = &nameL; }
+ else
+ { if (flagK) return S_FALSE; flagK = true; name = &nameK; }
+
+ if (item.Name.Compare(NFileHeader::kLongLink) != 0 &&
+ item.Name.Compare(NFileHeader::kLongLink2) != 0)
return S_FALSE;
-
- AString fullName;
- if (item.Size > (1 << 15))
- return S_FALSE;
- int packSize = (int)item.GetPackSize();
- char *buffer = fullName.GetBuffer(packSize + 1);
-
- RINOK(ReadStream_FALSE(stream, buffer, packSize));
- processedSize += packSize;
- buffer[item.Size] = '\0';
- fullName.ReleaseBuffer();
-
- UInt64 headerPosition = item.HeaderPosition;
- if (item.LinkFlag == 'L')
+ if (item.Size > (1 << 14))
+ return S_FALSE;
+ int packSize = (int)item.GetPackSize();
+ char *buf = name->GetBuffer(packSize);
+ RINOK(ReadStream_FALSE(stream, buf, packSize));
+ item.HeaderSize += packSize;
+ buf[(size_t)item.Size] = '\0';
+ name->ReleaseBuffer();
+ continue;
+ }
+ if (item.LinkFlag == 'g' || item.LinkFlag == 'x' || item.LinkFlag == 'X')
{
- size_t processedSize2;
- RINOK(GetNextItemReal(stream, filled, item, processedSize2));
- item.LongLinkSize = (unsigned)processedSize;
+ // pax Extended Header
}
- else
+ else if (item.LinkFlag == NFileHeader::NLinkFlag::kDumpDir)
{
- item.LongLinkSize = (unsigned)processedSize - NFileHeader::kRecordSize;
- item.Size = 0;
+ // GNU Extensions to the Archive Format
}
- item.Name = fullName;
- item.HeaderPosition = headerPosition;
- }
- else if (item.LinkFlag == 'g' || item.LinkFlag == 'x' || item.LinkFlag == 'X')
- {
- // pax Extended Header
- return S_OK;
- }
- else if (item.LinkFlag == NFileHeader::NLinkFlag::kDumpDir)
- {
- // GNU Extensions to the Archive Format
+ else if (item.LinkFlag > '7' || (item.LinkFlag < '0' && item.LinkFlag != 0))
+ return S_FALSE;
+ if (flagL) item.Name = nameL;
+ if (flagK) item.LinkName = nameK;
return S_OK;
}
- else if (item.LinkFlag > '7' || (item.LinkFlag < '0' && item.LinkFlag != 0))
- return S_FALSE;
- return S_OK;
}
}}
diff --git a/CPP/7zip/Archive/Tar/TarIn.h b/CPP/7zip/Archive/Tar/TarIn.h
index cc6e3f5b..a5491ebe 100755
--- a/CPP/7zip/Archive/Tar/TarIn.h
+++ b/CPP/7zip/Archive/Tar/TarIn.h
@@ -1,9 +1,8 @@
-// Archive/TarIn.h
+// TarIn.h
#ifndef __ARCHIVE_TAR_IN_H
#define __ARCHIVE_TAR_IN_H
-#include "Common/MyCom.h"
#include "../../IStream.h"
#include "TarItem.h"
@@ -11,7 +10,7 @@
namespace NArchive {
namespace NTar {
-HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &itemInfo);
+HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &itemInfo, AString &error);
}}
diff --git a/CPP/7zip/Archive/Tar/TarItem.h b/CPP/7zip/Archive/Tar/TarItem.h
index afe8997d..859e66dd 100755
--- a/CPP/7zip/Archive/Tar/TarItem.h
+++ b/CPP/7zip/Archive/Tar/TarItem.h
@@ -31,6 +31,9 @@ struct CItem
bool DeviceMajorDefined;
bool DeviceMinorDefined;
+ bool IsLink() const { return LinkFlag == NFileHeader::NLinkFlag::kSymbolicLink && (Size == 0); }
+ UInt64 GetUnpackSize() const { return IsLink() ? LinkName.Length() : Size; }
+
bool IsDir() const
{
switch(LinkFlag)
@@ -58,10 +61,10 @@ struct CItem
struct CItemEx: public CItem
{
- UInt64 HeaderPosition;
- unsigned LongLinkSize;
- UInt64 GetDataPosition() const { return HeaderPosition + LongLinkSize + NFileHeader::kRecordSize; }
- UInt64 GetFullSize() const { return LongLinkSize + NFileHeader::kRecordSize + Size; }
+ UInt64 HeaderPos;
+ unsigned HeaderSize;
+ UInt64 GetDataPosition() const { return HeaderPos + HeaderSize; }
+ UInt64 GetFullSize() const { return HeaderSize + Size; }
};
}}
diff --git a/CPP/7zip/Archive/Tar/TarUpdate.cpp b/CPP/7zip/Archive/Tar/TarUpdate.cpp
index 0577848f..c1633218 100755
--- a/CPP/7zip/Archive/Tar/TarUpdate.cpp
+++ b/CPP/7zip/Archive/Tar/TarUpdate.cpp
@@ -111,25 +111,25 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
}
else
{
- const CItemEx &existItemInfo = inputItems[ui.IndexInArchive];
+ const CItemEx &existItem = inputItems[ui.IndexInArchive];
UInt64 size;
if (ui.NewProps)
{
RINOK(outArchive.WriteHeader(item));
- RINOK(inStream->Seek(existItemInfo.GetDataPosition(), STREAM_SEEK_SET, NULL));
- size = existItemInfo.Size;
+ RINOK(inStream->Seek(existItem.GetDataPosition(), STREAM_SEEK_SET, NULL));
+ size = existItem.Size;
}
else
{
- RINOK(inStream->Seek(existItemInfo.HeaderPosition, STREAM_SEEK_SET, NULL));
- size = existItemInfo.GetFullSize();
+ RINOK(inStream->Seek(existItem.HeaderPos, STREAM_SEEK_SET, NULL));
+ size = existItem.GetFullSize();
}
streamSpec->Init(size);
RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress));
if (copyCoderSpec->TotalSize != size)
return E_FAIL;
- RINOK(outArchive.FillDataResidual(existItemInfo.Size));
+ RINOK(outArchive.FillDataResidual(existItem.Size));
complexity += size;
}
}
diff --git a/CPP/7zip/Archive/Wim/WimHandlerOut.cpp b/CPP/7zip/Archive/Wim/WimHandlerOut.cpp
index c7eb9980..50b879e7 100755
--- a/CPP/7zip/Archive/Wim/WimHandlerOut.cpp
+++ b/CPP/7zip/Archive/Wim/WimHandlerOut.cpp
@@ -323,25 +323,13 @@ static void AddTagUInt64(AString &s, const char *name, UInt64 value)
AddTag(s, name, temp);
}
-static void ConvertUInt32ToHex(UInt32 value, char *s)
-{
- for (int i = 0; i < 8; i++)
- {
- int t = value & 0xF;
- value >>= 4;
- s[7 - i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
- }
- s[8] = '\0';
-}
-
-
static AString TimeToXml(FILETIME &ft)
{
AString res;
char temp[16] = { '0', 'x' };
- ConvertUInt32ToHex(ft.dwHighDateTime, temp + 2);
+ ConvertUInt32ToHexWithZeros(ft.dwHighDateTime, temp + 2);
AddTag(res, "HIGHPART", temp);
- ConvertUInt32ToHex(ft.dwLowDateTime, temp + 2);
+ ConvertUInt32ToHexWithZeros(ft.dwLowDateTime, temp + 2);
AddTag(res, "LOWPART", temp);
return res;
}
diff --git a/CPP/7zip/Archive/Wim/WimIn.cpp b/CPP/7zip/Archive/Wim/WimIn.cpp
index 5edfacc5..c210804d 100755
--- a/CPP/7zip/Archive/Wim/WimIn.cpp
+++ b/CPP/7zip/Archive/Wim/WimIn.cpp
@@ -240,7 +240,7 @@ static HRESULT UnpackData(IInStream *inStream, const CResource &resource, bool l
buf.Free();
buf.SetCapacity(size);
- CSequentialOutStreamImp2 *outStreamSpec = new CSequentialOutStreamImp2();
+ CBufPtrSeqOutStream *outStreamSpec = new CBufPtrSeqOutStream();
CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
outStreamSpec->Init((Byte *)buf, size);
diff --git a/CPP/7zip/Archive/XarHandler.cpp b/CPP/7zip/Archive/XarHandler.cpp
index 56570230..e7d88b6c 100755
--- a/CPP/7zip/Archive/XarHandler.cpp
+++ b/CPP/7zip/Archive/XarHandler.cpp
@@ -268,7 +268,7 @@ HRESULT CHandler::Open2(IInStream *stream)
inStreamLimSpec->SetStream(stream);
inStreamLimSpec->Init(packSize);
- CSequentialOutStreamImp2 *outStreamLimSpec = new CSequentialOutStreamImp2;
+ CBufPtrSeqOutStream *outStreamLimSpec = new CBufPtrSeqOutStream;
CMyComPtr<ISequentialOutStream> outStreamLim(outStreamLimSpec);
outStreamLimSpec->Init((Byte *)ss, (size_t)unpackSize);
diff --git a/CPP/7zip/Archive/Zip/ZipAddCommon.cpp b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp
index ae75a1a2..4c5fd38d 100755
--- a/CPP/7zip/Archive/Zip/ZipAddCommon.cpp
+++ b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp
@@ -53,18 +53,17 @@ HRESULT CLzmaEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIAN
EncoderSpec = new NCompress::NLzma::CEncoder;
Encoder = EncoderSpec;
}
- CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp;
+ CBufPtrSeqOutStream *outStreamSpec = new CBufPtrSeqOutStream;
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
- outStreamSpec->Init();
+ outStreamSpec->Init(Header + 4, kLzmaPropsSize);
RINOK(EncoderSpec->SetCoderProperties(propIDs, props, numProps));
RINOK(EncoderSpec->WriteCoderProperties(outStream));
- if (outStreamSpec->GetSize() != kLzmaPropsSize)
+ if (outStreamSpec->GetPos() != kLzmaPropsSize)
return E_FAIL;
Header[0] = MY_VER_MAJOR;
Header[1] = MY_VER_MINOR;
Header[2] = kLzmaPropsSize;
Header[3] = 0;
- memcpy(Header + 4, outStreamSpec->GetBuffer(), kLzmaPropsSize);
return S_OK;
}
diff --git a/CPP/7zip/Bundles/Fm/makefile b/CPP/7zip/Bundles/Fm/makefile
index e9e30d6f..02ee7af1 100755
--- a/CPP/7zip/Bundles/Fm/makefile
+++ b/CPP/7zip/Bundles/Fm/makefile
@@ -160,6 +160,7 @@ AR_OBJS = \
$O\ArjHandler.obj \
$O\Bz2Handler.obj \
$O\CpioHandler.obj \
+ $O\CramfsHandler.obj \
$O\DebHandler.obj \
$O\DeflateProps.obj \
$O\DmgHandler.obj \
@@ -178,6 +179,7 @@ AR_OBJS = \
$O\PpmdHandler.obj \
$O\RpmHandler.obj \
$O\SplitHandler.obj \
+ $O\SquashfsHandler.obj \
$O\SwfHandler.obj \
$O\VhdHandler.obj \
$O\XarHandler.obj \
diff --git a/CPP/7zip/Bundles/Format7zF/Format7z.dsp b/CPP/7zip/Bundles/Format7zF/Format7z.dsp
index 52edc93f..b13ea42a 100755
--- a/CPP/7zip/Bundles/Format7zF/Format7z.dsp
+++ b/CPP/7zip/Bundles/Format7zF/Format7z.dsp
@@ -43,7 +43,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 1
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /c
-# ADD CPP /nologo /Gr /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "NO_REGISTRY" /D "EXTERNAL_CODECS" /D "_7ZIP_LARGE_PAGES" /FAcs /Yu"StdAfx.h" /FD /c
+# ADD CPP /nologo /Gr /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "NO_REGISTRY" /D "EXTERNAL_CODECS" /D "_7ZIP_LARGE_PAGES" /FAs /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"
@@ -164,6 +164,10 @@ SOURCE=..\..\Archive\Icons\split.ico
# End Source File
# Begin Source File
+SOURCE=..\..\Archive\Icons\squashfs.ico
+# End Source File
+# Begin Source File
+
SOURCE=..\..\Archive\Icons\tar.ico
# End Source File
# Begin Source File
@@ -2330,6 +2334,10 @@ SOURCE=..\..\Archive\CpioHandler.cpp
# End Source File
# Begin Source File
+SOURCE=..\..\Archive\CramfsHandler.cpp
+# End Source File
+# Begin Source File
+
SOURCE=..\..\Archive\DebHandler.cpp
# End Source File
# Begin Source File
@@ -2420,6 +2428,10 @@ SOURCE=..\..\Archive\SplitHandler.cpp
# End Source File
# Begin Source File
+SOURCE=..\..\Archive\SquashfsHandler.cpp
+# End Source File
+# Begin Source File
+
SOURCE=..\..\Archive\SwfHandler.cpp
# End Source File
# Begin Source File
diff --git a/CPP/7zip/Bundles/Format7zF/makefile b/CPP/7zip/Bundles/Format7zF/makefile
index 8199dd79..11c74872 100755
--- a/CPP/7zip/Bundles/Format7zF/makefile
+++ b/CPP/7zip/Bundles/Format7zF/makefile
@@ -58,6 +58,7 @@ AR_OBJS = \
$O\ArjHandler.obj \
$O\Bz2Handler.obj \
$O\CpioHandler.obj \
+ $O\CramfsHandler.obj \
$O\DebHandler.obj \
$O\DeflateProps.obj \
$O\DmgHandler.obj \
@@ -77,6 +78,7 @@ AR_OBJS = \
$O\RpmHandler.obj \
$O\SplitHandler.obj \
$O\SwfHandler.obj \
+ $O\SquashfsHandler.obj \
$O\VhdHandler.obj \
$O\XarHandler.obj \
$O\XzHandler.obj \
diff --git a/CPP/7zip/Bundles/Format7zF/resource.rc b/CPP/7zip/Bundles/Format7zF/resource.rc
index c6edfecc..df492020 100755
--- a/CPP/7zip/Bundles/Format7zF/resource.rc
+++ b/CPP/7zip/Bundles/Format7zF/resource.rc
@@ -27,10 +27,11 @@ MY_VERSION_INFO_DLL("7z Standalone Plugin", "7za")
21 ICON "../../Archive/Icons/fat.ico"
22 ICON "../../Archive/Icons/ntfs.ico"
23 ICON "../../Archive/Icons/xz.ico"
+24 ICON "../../Archive/Icons/squashfs.ico"
STRINGTABLE
BEGIN
- 100 "7z:0 zip:1 bz2:2 bzip2:2 tbz2:2 tbz:2 rar:3 arj:4 z:5 taz:5 lzh:6 lha:6 cab:7 iso:8 001:9 rpm:10 deb:11 cpio:12 tar:13 gz:14 gzip:14 tgz:14 tpz:14 wim:15 swm:15 lzma:16 dmg:17 hfs:18 xar:19 vhd:20 fat:21 ntfs:22 xz:23 txz:23"
+ 100 "7z:0 zip:1 bz2:2 bzip2:2 tbz2:2 tbz:2 rar:3 arj:4 z:5 taz:5 lzh:6 lha:6 cab:7 iso:8 001:9 rpm:10 deb:11 cpio:12 tar:13 gz:14 gzip:14 tgz:14 tpz:14 wim:15 swm:15 lzma:16 dmg:17 hfs:18 xar:19 vhd:20 fat:21 ntfs:22 xz:23 txz:23 squashfs:24"
END
diff --git a/CPP/7zip/Common/LimitedStreams.h b/CPP/7zip/Common/LimitedStreams.h
index f6900d51..2cbe18e4 100755
--- a/CPP/7zip/Common/LimitedStreams.h
+++ b/CPP/7zip/Common/LimitedStreams.h
@@ -17,6 +17,7 @@ class CLimitedSequentialInStream:
bool _wasFinished;
public:
void SetStream(ISequentialInStream *stream) { _stream = stream; }
+ void ReleaseStream() { _stream.Release(); }
void Init(UInt64 streamSize)
{
_size = streamSize;
diff --git a/CPP/7zip/Common/StreamObjects.cpp b/CPP/7zip/Common/StreamObjects.cpp
index 2237b930..3c86c3ae 100755
--- a/CPP/7zip/Common/StreamObjects.cpp
+++ b/CPP/7zip/Common/StreamObjects.cpp
@@ -2,20 +2,24 @@
#include "StdAfx.h"
+#include "../../../C/Alloc.h"
+
#include "StreamObjects.h"
STDMETHODIMP CBufInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = 0;
+ if (size == 0)
+ return S_OK;
if (_pos > _size)
return E_FAIL;
size_t rem = _size - (size_t)_pos;
- if (size < rem)
+ if (rem > size)
rem = (size_t)size;
memcpy(data, _data + (size_t)_pos, rem);
_pos += rem;
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = (UInt32)rem;
return S_OK;
}
@@ -34,51 +38,184 @@ STDMETHODIMP CBufInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosi
return S_OK;
}
+void CByteDynBuffer::Free()
+{
+ free(_buf);
+ _buf = 0;
+ _capacity = 0;
+}
+
+bool CByteDynBuffer::EnsureCapacity(size_t cap)
+{
+ if (cap <= _capacity)
+ return true;
+ size_t delta;
+ if (_capacity > 64)
+ delta = _capacity / 4;
+ else if (_capacity > 8)
+ delta = 16;
+ else
+ delta = 4;
+ cap = MyMax(_capacity + delta, cap);
+ Byte *buf = (Byte *)realloc(_buf, cap);
+ if (!buf)
+ return false;
+ _buf = buf;
+ _capacity = cap;
+ return true;
+}
+
+Byte *CDynBufSeqOutStream::GetBufPtrForWriting(size_t addSize)
+{
+ addSize += _size;
+ if (addSize < _size)
+ return NULL;
+ if (!_buffer.EnsureCapacity(addSize))
+ return NULL;
+ return (Byte *)_buffer + _size;
+}
-void CWriteBuffer::Write(const void *data, size_t size)
+void CDynBufSeqOutStream::CopyToBuffer(CByteBuffer &dest) const
{
- size_t newCapacity = _size + size;
- _buffer.EnsureCapacity(newCapacity);
- memcpy(_buffer + _size, data, size);
- _size += size;
+ dest.SetCapacity(_size);
+ memcpy(dest, _buffer, _size);
}
-STDMETHODIMP CSequentialOutStreamImp::Write(const void *data, UInt32 size, UInt32 *processedSize)
+STDMETHODIMP CDynBufSeqOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
- _writeBuffer.Write(data, (size_t)size);
- if(processedSize != NULL)
+ if (processedSize)
+ *processedSize = 0;
+ if (size == 0)
+ return S_OK;
+ Byte *buf = GetBufPtrForWriting(size);
+ if (!buf)
+ return E_OUTOFMEMORY;
+ memcpy(buf, data, size);
+ UpdateSize(size);
+ if (processedSize)
*processedSize = size;
return S_OK;
}
-STDMETHODIMP CSequentialOutStreamImp2::Write(const void *data, UInt32 size, UInt32 *processedSize)
+STDMETHODIMP CBufPtrSeqOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
size_t rem = _size - _pos;
- if (size < rem)
+ if (rem > size)
rem = (size_t)size;
memcpy(_buffer + _pos, data, rem);
_pos += rem;
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = (UInt32)rem;
- return (rem == size ? S_OK : E_FAIL);
+ return (rem != 0 || size == 0) ? S_OK : E_FAIL;
}
-STDMETHODIMP CSequentialInStreamSizeCount::Read(void *data, UInt32 size, UInt32 *processedSize)
+STDMETHODIMP CSequentialOutStreamSizeCount::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 realProcessedSize;
- HRESULT result = _stream->Read(data, size, &realProcessedSize);
+ HRESULT result = _stream->Write(data, size, &realProcessedSize);
_size += realProcessedSize;
- if (processedSize != 0)
+ if (processedSize)
*processedSize = realProcessedSize;
return result;
}
-STDMETHODIMP CSequentialOutStreamSizeCount::Write(const void *data, UInt32 size, UInt32 *processedSize)
+static const UInt64 kEmptyTag = (UInt64)(Int64)-1;
+
+void CCachedInStream::Free()
{
- UInt32 realProcessedSize;
- HRESULT result = _stream->Write(data, size, &realProcessedSize);
- _size += realProcessedSize;
- if (processedSize != 0)
- *processedSize = realProcessedSize;
- return result;
+ MyFree(_tags);
+ _tags = 0;
+ MidFree(_data);
+ _data = 0;
+}
+
+bool CCachedInStream::Alloc(unsigned blockSizeLog, unsigned numBlocksLog)
+{
+ unsigned sizeLog = blockSizeLog + numBlocksLog;
+ if (sizeLog >= sizeof(size_t) * 8)
+ return false;
+ size_t dataSize = (size_t)1 << sizeLog;
+ if (_data == 0 || dataSize != _dataSize)
+ {
+ MidFree(_data);
+ _data = (Byte *)MidAlloc(dataSize);
+ if (_data == 0)
+ return false;
+ _dataSize = dataSize;
+ }
+ if (_tags == 0 || numBlocksLog != _numBlocksLog)
+ {
+ MyFree(_tags);
+ _tags = (UInt64 *)MyAlloc(sizeof(UInt64) << numBlocksLog);
+ if (_tags == 0)
+ return false;
+ _numBlocksLog = numBlocksLog;
+ }
+ _blockSizeLog = blockSizeLog;
+ return true;
+}
+
+void CCachedInStream::Init(UInt64 size)
+{
+ _size = size;
+ _pos = 0;
+ size_t numBlocks = (size_t)1 << _numBlocksLog;
+ for (size_t i = 0; i < numBlocks; i++)
+ _tags[i] = kEmptyTag;
+}
+
+STDMETHODIMP CCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (processedSize)
+ *processedSize = 0;
+ if (size == 0)
+ return S_OK;
+ if (_pos > _size)
+ return E_FAIL;
+
+ {
+ UInt64 rem = _size - _pos;
+ if (size > rem)
+ size = (UInt32)rem;
+ }
+
+ while (size != 0)
+ {
+ UInt64 cacheTag = _pos >> _blockSizeLog;
+ size_t cacheIndex = (size_t)cacheTag & (((size_t)1 << _numBlocksLog) - 1);
+ Byte *p = _data + (cacheIndex << _blockSizeLog);
+ if (_tags[cacheIndex] != cacheTag)
+ {
+ UInt64 remInBlock = _size - (cacheTag << _blockSizeLog);
+ size_t blockSize = (size_t)1 << _blockSizeLog;
+ if (blockSize > remInBlock)
+ blockSize = (size_t)remInBlock;
+ RINOK(ReadBlock(cacheTag, p, blockSize));
+ _tags[cacheIndex] = cacheTag;
+ }
+ size_t offset = (size_t)_pos & (((size_t)1 << _blockSizeLog) - 1);
+ UInt32 cur = (UInt32)MyMin(((size_t)1 << _blockSizeLog) - offset, (size_t)size);
+ memcpy(data, p + offset, cur);
+ if (processedSize)
+ *processedSize += cur;
+ data = (void *)((const Byte *)data + cur);
+ _pos += cur;
+ size -= cur;
+ }
+
+ return S_OK;
+}
+
+STDMETHODIMP CCachedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
+{
+ switch(seekOrigin)
+ {
+ case STREAM_SEEK_SET: _pos = offset; break;
+ case STREAM_SEEK_CUR: _pos = _pos + offset; break;
+ case STREAM_SEEK_END: _pos = _size + offset; break;
+ default: return STG_E_INVALIDFUNCTION;
+ }
+ if (newPosition != 0)
+ *newPosition = _pos;
+ return S_OK;
}
diff --git a/CPP/7zip/Common/StreamObjects.h b/CPP/7zip/Common/StreamObjects.h
index e94513ee..8cd95c70 100755
--- a/CPP/7zip/Common/StreamObjects.h
+++ b/CPP/7zip/Common/StreamObjects.h
@@ -3,7 +3,7 @@
#ifndef __STREAM_OBJECTS_H
#define __STREAM_OBJECTS_H
-#include "../../Common/DynamicBuffer.h"
+#include "../../Common/Buffer.h"
#include "../../Common/MyCom.h"
#include "../IStream.h"
@@ -34,39 +34,45 @@ public:
void Init(CReferenceBuf *ref) { Init(ref->Buf, ref->Buf.GetCapacity(), ref); }
MY_UNKNOWN_IMP1(IInStream)
-
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
};
-class CWriteBuffer
+class CByteDynBuffer
{
- CByteDynamicBuffer _buffer;
- size_t _size;
+ size_t _capacity;
+ Byte *_buf;
public:
- CWriteBuffer(): _size(0) {}
- void Init() { _size = 0; }
- void Write(const void *data, size_t size);
- size_t GetSize() const { return _size; }
- const CByteDynamicBuffer& GetBuffer() const { return _buffer; }
+ CByteDynBuffer(): _capacity(0), _buf(0) {};
+ // there is no copy constructor. So don't copy this object.
+ ~CByteDynBuffer() { Free(); }
+ void Free();
+ size_t GetCapacity() const { return _capacity; }
+ operator Byte*() const { return _buf; };
+ operator const Byte*() const { return _buf; };
+ bool EnsureCapacity(size_t capacity);
};
-class CSequentialOutStreamImp:
+class CDynBufSeqOutStream:
public ISequentialOutStream,
public CMyUnknownImp
{
- CWriteBuffer _writeBuffer;
+ CByteDynBuffer _buffer;
+ size_t _size;
public:
- void Init() { _writeBuffer.Init(); }
- size_t GetSize() const { return _writeBuffer.GetSize(); }
- const CByteDynamicBuffer& GetBuffer() const { return _writeBuffer.GetBuffer(); }
+ CDynBufSeqOutStream(): _size(0) {}
+ void Init() { _size = 0; }
+ size_t GetSize() const { return _size; }
+ const Byte *GetBuffer() const { return _buffer; }
+ void CopyToBuffer(CByteBuffer &dest) const;
+ Byte *GetBufPtrForWriting(size_t addSize);
+ void UpdateSize(size_t addSize) { _size += addSize; }
MY_UNKNOWN_IMP
-
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
};
-class CSequentialOutStreamImp2:
+class CBufPtrSeqOutStream:
public ISequentialOutStream,
public CMyUnknownImp
{
@@ -74,54 +80,56 @@ class CSequentialOutStreamImp2:
size_t _size;
size_t _pos;
public:
-
void Init(Byte *buffer, size_t size)
{
_buffer = buffer;
_pos = 0;
_size = size;
}
-
size_t GetPos() const { return _pos; }
MY_UNKNOWN_IMP
-
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
};
-class CSequentialInStreamSizeCount:
- public ISequentialInStream,
+class CSequentialOutStreamSizeCount:
+ public ISequentialOutStream,
public CMyUnknownImp
{
- CMyComPtr<ISequentialInStream> _stream;
+ CMyComPtr<ISequentialOutStream> _stream;
UInt64 _size;
public:
- void Init(ISequentialInStream *stream)
- {
- _stream = stream;
- _size = 0;
- }
+ void SetStream(ISequentialOutStream *stream) { _stream = stream; }
+ void Init() { _size = 0; }
UInt64 GetSize() const { return _size; }
MY_UNKNOWN_IMP
-
- STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
};
-class CSequentialOutStreamSizeCount:
- public ISequentialOutStream,
+class CCachedInStream:
+ public IInStream,
public CMyUnknownImp
{
- CMyComPtr<ISequentialOutStream> _stream;
+ UInt64 *_tags;
+ Byte *_data;
+ size_t _dataSize;
+ unsigned _blockSizeLog;
+ unsigned _numBlocksLog;
UInt64 _size;
+ UInt64 _pos;
+protected:
+ virtual HRESULT ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize) = 0;
public:
- void SetStream(ISequentialOutStream *stream) { _stream = stream; }
- void Init() { _size = 0; }
- UInt64 GetSize() const { return _size; }
-
- MY_UNKNOWN_IMP
+ CCachedInStream(): _tags(0), _data(0) {}
+ virtual ~CCachedInStream() { Free(); } // the destructor must be virtual (release calls it) !!!
+ void Free();
+ bool Alloc(unsigned blockSizeLog, unsigned numBlocksLog);
+ void Init(UInt64 size);
- STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+ MY_UNKNOWN_IMP2(ISequentialInStream, IInStream)
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
};
#endif
diff --git a/CPP/7zip/Guid.txt b/CPP/7zip/Guid.txt
index 7876a1da..59a743b9 100755
--- a/CPP/7zip/Guid.txt
+++ b/CPP/7zip/Guid.txt
@@ -128,6 +128,8 @@ Handler GUIDs:
0C xz
0D ppmd
+ D2 SquashFS
+ D3 CramFS
D4 APM
D5 Mslz
D6 Flv
diff --git a/CPP/7zip/MyVersion.h b/CPP/7zip/MyVersion.h
index 41e5ddbd..2ca5dbc2 100755
--- a/CPP/7zip/MyVersion.h
+++ b/CPP/7zip/MyVersion.h
@@ -1,8 +1,8 @@
#define MY_VER_MAJOR 9
-#define MY_VER_MINOR 17
+#define MY_VER_MINOR 18
#define MY_VER_BUILD 0
-#define MY_VERSION "9.17 beta"
-#define MY_7ZIP_VERSION "7-Zip 9.17 beta"
-#define MY_DATE "2010-10-04"
+#define MY_VERSION "9.18 beta"
+#define MY_7ZIP_VERSION "7-Zip 9.18 beta"
+#define MY_DATE "2010-11-02"
#define MY_COPYRIGHT "Copyright (c) 1999-2010 Igor Pavlov"
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " " MY_DATE
diff --git a/CPP/7zip/PropID.h b/CPP/7zip/PropID.h
index d6f3a7c1..8f888526 100755
--- a/CPP/7zip/PropID.h
+++ b/CPP/7zip/PropID.h
@@ -60,6 +60,7 @@ enum
kpidSectorSize,
kpidPosixAttrib,
kpidLink,
+ kpidError,
kpidTotalSize = 0x1100,
kpidFreeSpace,
diff --git a/CPP/7zip/UI/Agent/Agent.cpp b/CPP/7zip/UI/Agent/Agent.cpp
index 4db95c87..4a099308 100755
--- a/CPP/7zip/UI/Agent/Agent.cpp
+++ b/CPP/7zip/UI/Agent/Agent.cpp
@@ -609,7 +609,7 @@ STDMETHODIMP CAgent::GetArcProp(UInt32 level, PROPID propID, PROPVARIANT *value)
CArc &arc = _archiveLink.Arcs[level];
switch(propID)
{
- case kpidType: prop = _codecs->Formats[arc.FormatIndex].Name; break;
+ case kpidType: prop = GetTypeOfArc(arc); break;
case kpidPath: prop = arc.Path; break;
default: return arc.Archive->GetArchiveProperty(propID, value);
}
diff --git a/CPP/7zip/UI/Agent/Agent.h b/CPP/7zip/UI/Agent/Agent.h
index c5efb411..454964bc 100755
--- a/CPP/7zip/UI/Agent/Agent.h
+++ b/CPP/7zip/UI/Agent/Agent.h
@@ -206,6 +206,27 @@ public:
const CArc &GetArc() { return _archiveLink.Arcs.Back(); }
IInArchive *GetArchive() { if ( _archiveLink.Arcs.IsEmpty()) return 0; return GetArc().Archive; }
bool CanUpdate() const { return _archiveLink.Arcs.Size() <= 1; }
+
+ UString GetTypeOfArc(const CArc &arc) const { return _codecs->Formats[arc.FormatIndex].Name; }
+ UString GetErrorMessage() const
+ {
+ UString s;
+ for (int i = _archiveLink.Arcs.Size() - 1; i >= 0; i--)
+ {
+ const CArc &arc = _archiveLink.Arcs[i];
+ if (arc.ErrorMessage.IsEmpty())
+ continue;
+ if (!s.IsEmpty())
+ s += L"--------------------\n";
+ s += arc.ErrorMessage;
+ s += L"\n\n[";
+ s += GetTypeOfArc(arc);
+ s += L"] ";
+ s += arc.Path;
+ s += L"\n";
+ }
+ return s;
+ }
};
#ifdef NEW_FOLDER_INTERFACE
diff --git a/CPP/7zip/UI/Common/Extract.cpp b/CPP/7zip/UI/Common/Extract.cpp
index f4c126a4..ca2c8c73 100755
--- a/CPP/7zip/UI/Common/Extract.cpp
+++ b/CPP/7zip/UI/Common/Extract.cpp
@@ -228,6 +228,15 @@ HRESULT DecompressArchives(
}
#endif
+ for (int v = 0; v < archiveLink.Arcs.Size(); v++)
+ {
+ const UString &s = archiveLink.Arcs[v].ErrorMessage;
+ if (!s.IsEmpty())
+ {
+ RINOK(extractCallback->MessageError(s));
+ }
+ }
+
CArc &arc = archiveLink.Arcs.Back();
arc.MTimeDefined = (!options.StdInMode && !fi.IsDevice);
arc.MTime = fi.MTime;
diff --git a/CPP/7zip/UI/Common/ExtractingFilePath.cpp b/CPP/7zip/UI/Common/ExtractingFilePath.cpp
index 67a58372..8f31708b 100755
--- a/CPP/7zip/UI/Common/ExtractingFilePath.cpp
+++ b/CPP/7zip/UI/Common/ExtractingFilePath.cpp
@@ -2,6 +2,8 @@
#include "StdAfx.h"
+#include "../../../../C/Types.h"
+
#include "Common/Wildcard.h"
#include "ExtractingFilePath.h"
diff --git a/CPP/7zip/UI/Common/OpenArchive.cpp b/CPP/7zip/UI/Common/OpenArchive.cpp
index d61c7f17..56a63046 100755
--- a/CPP/7zip/UI/Common/OpenArchive.cpp
+++ b/CPP/7zip/UI/Common/OpenArchive.cpp
@@ -111,6 +111,7 @@ HRESULT CArc::OpenStream(
IArchiveOpenCallback *callback)
{
Archive.Release();
+ ErrorMessage.Empty();
const UString fileName = ExtractFileNameFromPath(Path);
UString extension;
{
@@ -298,6 +299,13 @@ HRESULT CArc::OpenStream(
if (result == S_FALSE)
continue;
RINOK(result);
+
+ {
+ NCOM::CPropVariant prop;
+ archive->GetArchiveProperty(kpidError, &prop);
+ if (prop.vt != VT_EMPTY)
+ ErrorMessage = (prop.vt == VT_BSTR) ? prop.bstrVal : L"Unknown error";
+ }
Archive = archive;
const CArcInfoEx &format = codecs->Formats[FormatIndex];
diff --git a/CPP/7zip/UI/Common/OpenArchive.h b/CPP/7zip/UI/Common/OpenArchive.h
index 92103623..4a003ee6 100755
--- a/CPP/7zip/UI/Common/OpenArchive.h
+++ b/CPP/7zip/UI/Common/OpenArchive.h
@@ -24,6 +24,7 @@ struct CArc
int SubfileIndex;
FILETIME MTime;
bool MTimeDefined;
+ UString ErrorMessage;
CArc(): MTimeDefined(false) {}
diff --git a/CPP/7zip/UI/Common/PropIDUtils.cpp b/CPP/7zip/UI/Common/PropIDUtils.cpp
index daa57ef6..dacaca5f 100755
--- a/CPP/7zip/UI/Common/PropIDUtils.cpp
+++ b/CPP/7zip/UI/Common/PropIDUtils.cpp
@@ -45,6 +45,7 @@ static const char g_WinAttrib[17] = "RHS8DAdNTsrCOnE_";
16 VIRTUAL
*/
+static const char kPosixTypes[16] = { '0', 'p', 'c', '3', 'd', '5', 'b', '7', '-', '9', 'l', 'B', 's', 'D', 'E', 'F' };
#define MY_ATTR_CHAR(a, n, c) ((a )& (1 << (n))) ? c : L'-';
UString ConvertPropertyToString(const PROPVARIANT &prop, PROPID propID, bool full)
@@ -92,17 +93,21 @@ UString ConvertPropertyToString(const PROPVARIANT &prop, PROPID propID, bool ful
UString res;
UInt32 a = prop.ulVal;
wchar_t temp[16];
- temp[0] = MY_ATTR_CHAR(a, 14, L'd');
+
+ temp[0] = kPosixTypes[(a >> 12) & 0xF];
for (int i = 6; i >= 0; i -= 3)
{
temp[7 - i] = MY_ATTR_CHAR(a, i + 2, L'r');
temp[8 - i] = MY_ATTR_CHAR(a, i + 1, L'w');
temp[9 - i] = MY_ATTR_CHAR(a, i + 0, L'x');
}
+ if ((a & 0x800) != 0) temp[3] = ((a & (1 << 6)) ? 's' : 'S');
+ if ((a & 0x400) != 0) temp[6] = ((a & (1 << 3)) ? 's' : 'S');
+ if ((a & 0x200) != 0) temp[9] = ((a & (1 << 0)) ? 't' : 'T');
temp[10] = 0;
res = temp;
- a &= ~0x1FF;
- a &= ~0xC000;
+
+ a &= ~(UInt32)0xFFFF;
if (a != 0)
{
ConvertUInt32ToHex(a, temp);
diff --git a/CPP/7zip/UI/Console/List.cpp b/CPP/7zip/UI/Console/List.cpp
index b06641f2..f747cfda 100755
--- a/CPP/7zip/UI/Console/List.cpp
+++ b/CPP/7zip/UI/Console/List.cpp
@@ -29,7 +29,7 @@ struct CPropIdToName
const wchar_t *Name;
};
-static CPropIdToName kPropIdToName[] =
+static const CPropIdToName kPropIdToName[] =
{
{ kpidPath, L"Path" },
{ kpidName, L"Name" },
@@ -82,6 +82,7 @@ static CPropIdToName kPropIdToName[] =
{ kpidSectorSize, L"Sector Size" },
{ kpidPosixAttrib, L"Mode" },
{ kpidLink, L"Link" },
+ { kpidError, L"Error" },
{ kpidTotalSize, L"Total Size" },
{ kpidFreeSpace, L"Free Space" },
@@ -505,6 +506,8 @@ HRESULT ListArchives(CCodecs *codecs, const CIntVector &formatIndices,
g_StdOut << "--\n";
PrintPropPair(L"Path", arc.Path);
PrintPropPair(L"Type", codecs->Formats[arc.FormatIndex].Name);
+ if (!arc.ErrorMessage.IsEmpty())
+ PrintPropPair(L"Error", arc.ErrorMessage);
UInt32 numProps;
IInArchive *archive = arc.Archive;
if (archive->GetNumberOfArchiveProperties(&numProps) == S_OK)
diff --git a/CPP/7zip/UI/Console/Main.cpp b/CPP/7zip/UI/Console/Main.cpp
index 7cb2a396..9bd451f8 100755
--- a/CPP/7zip/UI/Console/Main.cpp
+++ b/CPP/7zip/UI/Console/Main.cpp
@@ -26,7 +26,6 @@
#ifdef EXTERNAL_CODECS
#include "../Common/LoadCodecs.h"
#endif
-#include "../Common/PropIDUtils.h"
#include "BenchCon.h"
#include "ExtractCallbackConsole.h"
@@ -457,8 +456,8 @@ int Main2(
<< "Compressed: " << stat.PackSize << endl;
if (options.CalcCrc)
{
- wchar_t s[16];
- ConvertUInt32ToHex(stat.CrcSum, s);
+ char s[16];
+ ConvertUInt32ToHexWithZeros(stat.CrcSum, s);
stdStream << "CRC: " << s << endl;
}
}
diff --git a/CPP/7zip/UI/Far/Far.dsp b/CPP/7zip/UI/Far/Far.dsp
index 4609c82c..394977bb 100755
--- a/CPP/7zip/UI/Far/Far.dsp
+++ b/CPP/7zip/UI/Far/Far.dsp
@@ -53,7 +53,7 @@ BSC32=bscmake.exe
# 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\Far2\Plugins\7-Zip\7-ZipFar.dll" /opt:NOWIN98
+# 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\Far\Plugins\7-Zip\7-ZipFar.dll" /opt:NOWIN98
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "Far - Win32 Debug"
@@ -80,7 +80,7 @@ BSC32=bscmake.exe
# 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\Far2\Plugins\7-Zip\7-ZipFar.dll" /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\Far\Plugins\7-Zip\7-ZipFar.dll" /pdbtype:sept
!ENDIF
diff --git a/CPP/7zip/UI/Far/FarPlugin.h b/CPP/7zip/UI/Far/FarPlugin.h
index 1408ef21..d9ea6dca 100755
--- a/CPP/7zip/UI/Far/FarPlugin.h
+++ b/CPP/7zip/UI/Far/FarPlugin.h
@@ -61,7 +61,7 @@ struct PluginPanelItem
char **CustomColumnData;
int CustomColumnNumber;
DWORD_PTR UserData;
- DWORD CRC32;
+ DWORD CRC32;
DWORD_PTR Reserved[2];
};
@@ -484,34 +484,34 @@ enum OPERATION_MODES {
/*
EXTERN_C_BEGIN
- void WINAPI _export ClosePluginW(HANDLE hPlugin);
- int WINAPI _export CompareW(HANDLE hPlugin,const struct PluginPanelItem *Item1,const struct PluginPanelItem *Item2,unsigned int Mode);
- int WINAPI _export ConfigureW(int ItemNumber);
- int WINAPI _export DeleteFilesW(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber,int OpMode);
- void WINAPI _export ExitFARW(void);
- void WINAPI _export FreeFindDataW(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber);
- void WINAPI _export FreeVirtualFindDataW(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber);
- int WINAPI _export GetFilesW(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber,int Move,const wchar_t **DestPath,int OpMode);
- int WINAPI _export GetFindDataW(HANDLE hPlugin,struct PluginPanelItem **pPanelItem,int *pItemsNumber,int OpMode);
- int WINAPI _export GetMinFarVersionW(void);
- void WINAPI _export GetOpenPluginInfoW(HANDLE hPlugin,struct OpenPluginInfo *Info);
- void WINAPI _export GetPluginInfoW(struct PluginInfo *Info);
- int WINAPI _export GetVirtualFindDataW(HANDLE hPlugin,struct PluginPanelItem **pPanelItem,int *pItemsNumber,const wchar_t *Path);
- int WINAPI _export MakeDirectoryW(HANDLE hPlugin,const wchar_t **Name,int OpMode);
- HANDLE WINAPI _export OpenFilePluginW(const wchar_t *Name,const unsigned char *Data,int DataSize,int OpMode);
- HANDLE WINAPI _export OpenPluginW(int OpenFrom,INT_PTR Item);
- int WINAPI _export ProcessDialogEventW(int Event,void *Param);
- int WINAPI _export ProcessEditorEventW(int Event,void *Param);
- int WINAPI _export ProcessEditorInputW(const INPUT_RECORD *Rec);
- int WINAPI _export ProcessEventW(HANDLE hPlugin,int Event,void *Param);
- int WINAPI _export ProcessHostFileW(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber,int OpMode);
- int WINAPI _export ProcessKeyW(HANDLE hPlugin,int Key,unsigned int ControlState);
- int WINAPI _export ProcessSynchroEventW(int Event,void *Param);
- int WINAPI _export ProcessViewerEventW(int Event,void *Param);
- int WINAPI _export PutFilesW(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber,int Move,const wchar_t *SrcPath,int OpMode);
- int WINAPI _export SetDirectoryW(HANDLE hPlugin,const wchar_t *Dir,int OpMode);
- int WINAPI _export SetFindListW(HANDLE hPlugin,const struct PluginPanelItem *PanelItem,int ItemsNumber);
- void WINAPI _export SetStartupInfoW(const struct PluginStartupInfo *Info);
+ void WINAPI _export ClosePluginW(HANDLE hPlugin);
+ int WINAPI _export CompareW(HANDLE hPlugin,const struct PluginPanelItem *Item1,const struct PluginPanelItem *Item2,unsigned int Mode);
+ int WINAPI _export ConfigureW(int ItemNumber);
+ int WINAPI _export DeleteFilesW(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber,int OpMode);
+ void WINAPI _export ExitFARW(void);
+ void WINAPI _export FreeFindDataW(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber);
+ void WINAPI _export FreeVirtualFindDataW(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber);
+ int WINAPI _export GetFilesW(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber,int Move,const wchar_t **DestPath,int OpMode);
+ int WINAPI _export GetFindDataW(HANDLE hPlugin,struct PluginPanelItem **pPanelItem,int *pItemsNumber,int OpMode);
+ int WINAPI _export GetMinFarVersionW(void);
+ void WINAPI _export GetOpenPluginInfoW(HANDLE hPlugin,struct OpenPluginInfo *Info);
+ void WINAPI _export GetPluginInfoW(struct PluginInfo *Info);
+ int WINAPI _export GetVirtualFindDataW(HANDLE hPlugin,struct PluginPanelItem **pPanelItem,int *pItemsNumber,const wchar_t *Path);
+ int WINAPI _export MakeDirectoryW(HANDLE hPlugin,const wchar_t **Name,int OpMode);
+ HANDLE WINAPI _export OpenFilePluginW(const wchar_t *Name,const unsigned char *Data,int DataSize,int OpMode);
+ HANDLE WINAPI _export OpenPluginW(int OpenFrom,INT_PTR Item);
+ int WINAPI _export ProcessDialogEventW(int Event,void *Param);
+ int WINAPI _export ProcessEditorEventW(int Event,void *Param);
+ int WINAPI _export ProcessEditorInputW(const INPUT_RECORD *Rec);
+ int WINAPI _export ProcessEventW(HANDLE hPlugin,int Event,void *Param);
+ int WINAPI _export ProcessHostFileW(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber,int OpMode);
+ int WINAPI _export ProcessKeyW(HANDLE hPlugin,int Key,unsigned int ControlState);
+ int WINAPI _export ProcessSynchroEventW(int Event,void *Param);
+ int WINAPI _export ProcessViewerEventW(int Event,void *Param);
+ int WINAPI _export PutFilesW(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber,int Move,const wchar_t *SrcPath,int OpMode);
+ int WINAPI _export SetDirectoryW(HANDLE hPlugin,const wchar_t *Dir,int OpMode);
+ int WINAPI _export SetFindListW(HANDLE hPlugin,const struct PluginPanelItem *PanelItem,int ItemsNumber);
+ void WINAPI _export SetStartupInfoW(const struct PluginStartupInfo *Info);
EXTERN_C_END
*/
diff --git a/CPP/7zip/UI/Far/Main.cpp b/CPP/7zip/UI/Far/Main.cpp
index 7cd7d5ee..5e017b80 100755
--- a/CPP/7zip/UI/Far/Main.cpp
+++ b/CPP/7zip/UI/Far/Main.cpp
@@ -366,7 +366,8 @@ static HANDLE MyOpenFilePluginW(const wchar_t *name)
// ::OutputDebugStringA("before OpenArchive\n");
- archiveHandler = new CAgent;
+ CAgent *agent = new CAgent;
+ archiveHandler = agent;
CMyComBSTR archiveType;
HRESULT result = archiveHandler->Open(NULL,
GetUnicodeString(fullName, CP_OEMCP), UString(), &archiveType, openArchiveCallback);
@@ -381,6 +382,10 @@ static HANDLE MyOpenFilePluginW(const wchar_t *name)
return INVALID_HANDLE_VALUE;
}
+ UString errorMessage = agent->GetErrorMessage();
+ if (!errorMessage.IsEmpty())
+ PrintErrorMessage("7-Zip", UnicodeStringToMultiByte(errorMessage, CP_OEMCP));
+
// ::OutputDebugStringA("after OpenArchive\n");
CPlugin *plugin = new CPlugin(
diff --git a/CPP/7zip/UI/Far/Plugin.cpp b/CPP/7zip/UI/Far/Plugin.cpp
index 97627517..a19b037c 100755
--- a/CPP/7zip/UI/Far/Plugin.cpp
+++ b/CPP/7zip/UI/Far/Plugin.cpp
@@ -326,7 +326,8 @@ static CPROPIDToName kPROPIDToName[] =
{ kpidSectorSize, NMessageID::kSectorSize },
{ kpidPosixAttrib, NMessageID::kPosixAttrib },
{ kpidLink, NMessageID::kLink },
-
+ { kpidError, NMessageID::kError },
+
{ kpidTotalSize, NMessageID::kTotalSize },
{ kpidFreeSpace, NMessageID::kFreeSpace },
{ kpidClusterSize, NMessageID::kClusterSize },
@@ -628,17 +629,20 @@ void CPlugin::GetOpenPluginInfo(struct OpenPluginInfo *info)
if (getProps->GetArcNumProps(level, &numProps) == S_OK)
{
InsertSeparator(m_InfoLines, numItems);
- for (Int32 i = -2; i < (Int32)numProps && numItems < kNumInfoLinesMax; i++)
+ for (Int32 i = -3; i < (Int32)numProps && numItems < kNumInfoLinesMax; i++)
{
CMyComBSTR name;
PROPID propID;
VARTYPE vt;
- if (i == -2)
- propID = kpidPath;
- else if (i == -1)
- propID = kpidType;
- else if (getProps->GetArcPropInfo(level, i, &name, &propID, &vt) != S_OK)
- continue;
+ switch (i)
+ {
+ case -3: propID = kpidPath; break;
+ case -2: propID = kpidType; break;
+ case -1: propID = kpidError; break;
+ default:
+ if (getProps->GetArcPropInfo(level, i, &name, &propID, &vt) != S_OK)
+ continue;
+ }
NCOM::CPropVariant prop;
if (getProps->GetArcProp(level, propID, &prop) != S_OK)
continue;
diff --git a/CPP/7zip/UI/FileManager/PanelItemOpen.cpp b/CPP/7zip/UI/FileManager/PanelItemOpen.cpp
index 29c99bfd..6b8fdba2 100755
--- a/CPP/7zip/UI/FileManager/PanelItemOpen.cpp
+++ b/CPP/7zip/UI/FileManager/PanelItemOpen.cpp
@@ -9,6 +9,7 @@
#include "Windows/FileDir.h"
#include "Windows/FileFind.h"
#include "Windows/Process.h"
+#include "Windows/PropVariant.h"
#include "Windows/Thread.h"
#include "../Common/ExtractingFilePath.h"
@@ -113,6 +114,46 @@ HRESULT CPanel::OpenItemAsArchive(IInStream *inStream,
_flatMode = _flatModeForArc;
+ CMyComPtr<IGetFolderArcProps> getFolderArcProps;
+ _folder.QueryInterface(IID_IGetFolderArcProps, &getFolderArcProps);
+ if (getFolderArcProps)
+ {
+ CMyComPtr<IFolderArcProps> arcProps;
+ getFolderArcProps->GetFolderArcProps(&arcProps);
+ if (arcProps)
+ {
+ UString s;
+ UInt32 numLevels;
+ if (arcProps->GetArcNumLevels(&numLevels) != S_OK)
+ numLevels = 0;
+ for (UInt32 level2 = 0; level2 < numLevels; level2++)
+ {
+ UInt32 level = numLevels - 1 - level2;
+ PROPID propIDs[] = { kpidError, kpidPath, kpidType } ;
+ UString values[3];
+ for (Int32 i = 0; i < 3; i++)
+ {
+ CMyComBSTR name;
+ NCOM::CPropVariant prop;
+ if (arcProps->GetArcProp(level, propIDs[i], &prop) != S_OK)
+ continue;
+ if (prop.vt != VT_EMPTY)
+ values[i] = (prop.vt == VT_BSTR) ? prop.bstrVal : L"?";
+ }
+ if (!values[0].IsEmpty())
+ {
+ if (!s.IsEmpty())
+ s += L"--------------------\n";
+ s += values[0]; s += L"\n\n[";
+ s += values[2]; s += L"] ";
+ s += values[1]; s += L"\n";
+ }
+ }
+ if (!s.IsEmpty())
+ MessageBox(s);
+ }
+ }
+
return S_OK;
}
diff --git a/CPP/7zip/UI/FileManager/PanelMenu.cpp b/CPP/7zip/UI/FileManager/PanelMenu.cpp
index c60751b5..549b28da 100755
--- a/CPP/7zip/UI/FileManager/PanelMenu.cpp
+++ b/CPP/7zip/UI/FileManager/PanelMenu.cpp
@@ -188,17 +188,20 @@ void CPanel::Properties()
if (getProps->GetArcNumProps(level, &numProps) == S_OK)
{
message += kSeparator;
- for (Int32 i = -2; i < (Int32)numProps; i++)
+ for (Int32 i = -3; i < (Int32)numProps; i++)
{
CMyComBSTR name;
PROPID propID;
VARTYPE vt;
- if (i == -2)
- propID = kpidPath;
- else if (i == -1)
- propID = kpidType;
- else if (getProps->GetArcPropInfo(level, i, &name, &propID, &vt) != S_OK)
- continue;
+ switch (i)
+ {
+ case -3: propID = kpidPath; break;
+ case -2: propID = kpidType; break;
+ case -1: propID = kpidError; break;
+ default:
+ if (getProps->GetArcPropInfo(level, i, &name, &propID, &vt) != S_OK)
+ continue;
+ }
NCOM::CPropVariant prop;
if (getProps->GetArcProp(level, propID, &prop) != S_OK)
continue;
diff --git a/CPP/7zip/UI/FileManager/PanelSort.cpp b/CPP/7zip/UI/FileManager/PanelSort.cpp
index 7eabc9ef..186315b3 100755
--- a/CPP/7zip/UI/FileManager/PanelSort.cpp
+++ b/CPP/7zip/UI/FileManager/PanelSort.cpp
@@ -61,17 +61,19 @@ int CALLBACK CompareItems2(LPARAM lParam1, LPARAM lParam2, LPARAM lpData)
// PROPID propID = panel->_properties[panel->_sortIndex].ID;
PROPID propID = panel->_sortID;
- NCOM::CPropVariant propVariant1, propVariant2;
+ NCOM::CPropVariant prop1, prop2;
// Name must be first property
- panel->_folder->GetProperty((UINT32)lParam1, propID, &propVariant1);
- panel->_folder->GetProperty((UINT32)lParam2, propID, &propVariant2);
- if (propVariant1.vt != propVariant2.vt)
- return 0; // It means some BUG
- if (propVariant1.vt == VT_BSTR)
+ panel->_folder->GetProperty((UINT32)lParam1, propID, &prop1);
+ panel->_folder->GetProperty((UINT32)lParam2, propID, &prop2);
+ if (prop1.vt != prop2.vt)
{
- return _wcsicmp(propVariant1.bstrVal, propVariant2.bstrVal);
+ return MyCompare(prop1.vt, prop2.vt);
}
- return propVariant1.Compare(propVariant2);
+ if (prop1.vt == VT_BSTR)
+ {
+ return _wcsicmp(prop1.bstrVal, prop2.bstrVal);
+ }
+ return prop1.Compare(prop2);
// return 0;
}
diff --git a/CPP/7zip/UI/FileManager/ProgramLocation.cpp b/CPP/7zip/UI/FileManager/ProgramLocation.cpp
index 04c2c98c..ce2d178e 100755
--- a/CPP/7zip/UI/FileManager/ProgramLocation.cpp
+++ b/CPP/7zip/UI/FileManager/ProgramLocation.cpp
@@ -2,6 +2,8 @@
#include "StdAfx.h"
+#include "../../../../C/Types.h"
+
#include "ProgramLocation.h"
#include "Windows/DLL.h"
@@ -20,4 +22,3 @@ bool GetProgramFolderPath(UString &folder)
folder = folder.Left(pos + 1);
return true;
}
-
diff --git a/CPP/7zip/UI/FileManager/PropertyName.cpp b/CPP/7zip/UI/FileManager/PropertyName.cpp
index 79b09300..098bc47d 100755
--- a/CPP/7zip/UI/FileManager/PropertyName.cpp
+++ b/CPP/7zip/UI/FileManager/PropertyName.cpp
@@ -75,6 +75,7 @@ static CPropertyIDNamePair kPropertyIDNamePairs[] =
{ kpidSectorSize, IDS_PROP_SECTOR_SIZE, 0x02000234 },
{ kpidPosixAttrib, IDS_PROP_POSIX_ATTRIB, 0x02000235 },
{ kpidLink, IDS_PROP_LINK, 0x02000236 },
+ { kpidError, IDS_PROP_ERROR, 0x02000605 },
{ kpidTotalSize, IDS_PROP_TOTAL_SIZE, 0x03031100 },
{ kpidFreeSpace, IDS_PROP_FREE_SPACE, 0x03031101 },
diff --git a/CPP/7zip/UI/FileManager/PropertyName.rc b/CPP/7zip/UI/FileManager/PropertyName.rc
index 576b52cb..bdd6c8ed 100755
--- a/CPP/7zip/UI/FileManager/PropertyName.rc
+++ b/CPP/7zip/UI/FileManager/PropertyName.rc
@@ -56,4 +56,5 @@ BEGIN
IDS_PROP_SECTOR_SIZE "Sector Size"
IDS_PROP_POSIX_ATTRIB "Mode"
IDS_PROP_LINK "Link"
+ IDS_PROP_ERROR "Error"
END
diff --git a/CPP/7zip/UI/FileManager/PropertyNameRes.h b/CPP/7zip/UI/FileManager/PropertyNameRes.h
index 00458a24..9cc9f7c5 100755
--- a/CPP/7zip/UI/FileManager/PropertyNameRes.h
+++ b/CPP/7zip/UI/FileManager/PropertyNameRes.h
@@ -50,3 +50,4 @@
#define IDS_PROP_SECTOR_SIZE 52
#define IDS_PROP_POSIX_ATTRIB 53
#define IDS_PROP_LINK 54
+#define IDS_PROP_ERROR 55
diff --git a/CPP/7zip/UI/GUI/CompressDialog.cpp b/CPP/7zip/UI/GUI/CompressDialog.cpp
index ea9d9c2c..da2b7924 100755
--- a/CPP/7zip/UI/GUI/CompressDialog.cpp
+++ b/CPP/7zip/UI/GUI/CompressDialog.cpp
@@ -1038,7 +1038,13 @@ void CCompressDialog::SetDictionary()
if (i == 20 && j > 0)
continue;
UInt32 dictionary = (1 << i) + (j << (i - 1));
- if (dictionary > (1 << 30))
+ if (dictionary >
+ #ifdef _WIN64
+ (1 << 30)
+ #else
+ (1 << 29)
+ #endif
+ )
continue;
AddDictionarySize(dictionary);
UInt64 decomprSize;
diff --git a/CPP/Common/DynamicBuffer.h b/CPP/Common/DynamicBuffer.h
index fd33cec3..bf52a742 100755
--- a/CPP/Common/DynamicBuffer.h
+++ b/CPP/Common/DynamicBuffer.h
@@ -1,7 +1,7 @@
// Common/DynamicBuffer.h
-#ifndef __COMMON_DYNAMICBUFFER_H
-#define __COMMON_DYNAMICBUFFER_H
+#ifndef __COMMON_DYNAMIC_BUFFER_H
+#define __COMMON_DYNAMIC_BUFFER_H
#include "Buffer.h"
@@ -17,7 +17,10 @@ template <class T> class CDynamicBuffer: public CBuffer<T>
else
delta = 4;
delta = MyMax(delta, size);
- SetCapacity(this->_capacity + delta);
+ size_t newCap = this->_capacity + delta;
+ if (newCap < delta)
+ newCap = this->_capacity + size;
+ SetCapacity(newCap);
}
public:
CDynamicBuffer(): CBuffer<T>() {};
diff --git a/CPP/Common/IntToString.cpp b/CPP/Common/IntToString.cpp
index 31070b41..013fee52 100755
--- a/CPP/Common/IntToString.cpp
+++ b/CPP/Common/IntToString.cpp
@@ -64,3 +64,14 @@ void ConvertInt64ToString(Int64 value, wchar_t *s)
}
ConvertUInt64ToString(value, s);
}
+
+void ConvertUInt32ToHexWithZeros(UInt32 value, char *s)
+{
+ for (int i = 0; i < 8; i++)
+ {
+ int t = value & 0xF;
+ value >>= 4;
+ s[7 - i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
+ }
+ s[8] = '\0';
+}
diff --git a/CPP/Common/IntToString.h b/CPP/Common/IntToString.h
index bad17e4a..782f930c 100755
--- a/CPP/Common/IntToString.h
+++ b/CPP/Common/IntToString.h
@@ -14,4 +14,6 @@ void ConvertInt64ToString(Int64 value, wchar_t *s);
void ConvertUInt32ToString(UInt32 value, char *s);
void ConvertUInt32ToString(UInt32 value, wchar_t *s);
+void ConvertUInt32ToHexWithZeros(UInt32 value, char *s);
+
#endif
diff --git a/CPP/Common/MyString.h b/CPP/Common/MyString.h
index e8830092..eb3c52dc 100755
--- a/CPP/Common/MyString.h
+++ b/CPP/Common/MyString.h
@@ -7,10 +7,6 @@
#include "MyVector.h"
-#ifdef _WIN32
-#include "MyWindows.h"
-#endif
-
template <class T>
inline int MyStringLen(const T *s)
{
diff --git a/CPP/Common/MyVector.h b/CPP/Common/MyVector.h
index 28b7e3c8..781b648b 100755
--- a/CPP/Common/MyVector.h
+++ b/CPP/Common/MyVector.h
@@ -78,6 +78,22 @@ public:
operator[](j) = temp;
}
+ int FindInSorted(const T& item, int left, int right) const
+ {
+ while (left != right)
+ {
+ int mid = (left + right) / 2;
+ const T& midValue = (*this)[mid];
+ if (item == midValue)
+ return mid;
+ if (item < midValue)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ return -1;
+ }
+
int FindInSorted(const T& item) const
{
int left = 0, right = Size();
diff --git a/CPP/Common/MyWindows.h b/CPP/Common/MyWindows.h
index 2861ba04..8b0e5c06 100755
--- a/CPP/Common/MyWindows.h
+++ b/CPP/Common/MyWindows.h
@@ -7,18 +7,8 @@
#include <windows.h>
-#define CHAR_PATH_SEPARATOR '\\'
-#define WCHAR_PATH_SEPARATOR L'\\'
-#define STRING_PATH_SEPARATOR "\\"
-#define WSTRING_PATH_SEPARATOR L"\\"
-
#else
-#define CHAR_PATH_SEPARATOR '/'
-#define WCHAR_PATH_SEPARATOR L'/'
-#define STRING_PATH_SEPARATOR "/"
-#define WSTRING_PATH_SEPARATOR L"/"
-
#include <stddef.h> // for wchar_t
#include <string.h>
diff --git a/CPP/Common/Wildcard.cpp b/CPP/Common/Wildcard.cpp
index 141c5dd6..ac77e39b 100755
--- a/CPP/Common/Wildcard.cpp
+++ b/CPP/Common/Wildcard.cpp
@@ -2,6 +2,8 @@
#include "StdAfx.h"
+#include "../../C/Types.h"
+
#include "Wildcard.h"
bool g_CaseSensitive =
diff --git a/CPP/Windows/Control/Dialog.cpp b/CPP/Windows/Control/Dialog.cpp
index dd0cf066..3cfa517a 100755
--- a/CPP/Windows/Control/Dialog.cpp
+++ b/CPP/Windows/Control/Dialog.cpp
@@ -103,7 +103,7 @@ bool IsDialogSizeOK(int xSize, int ySize)
void CDialog::NormalizeSize(bool fullNormalize)
{
RECT workRect;
- GetWorkAreaRect(&workRect);
+ GetWorkAreaRect(&workRect);
int xSize = RECT_SIZE_X(workRect);
int ySize = RECT_SIZE_Y(workRect);
RECT rect;
@@ -135,7 +135,7 @@ void CDialog::NormalizeSize(bool fullNormalize)
void CDialog::NormalizePosition()
{
RECT workRect, rect;
- GetWorkAreaRect(&workRect);
+ GetWorkAreaRect(&workRect);
GetWindowRect(&rect);
if (rect.bottom > workRect.bottom && rect.top > workRect.top)
Move(rect.left, workRect.top, RECT_SIZE_X(rect), RECT_SIZE_Y(rect), true);
diff --git a/CPP/Windows/FileName.h b/CPP/Windows/FileName.h
index 20786e00..d9807902 100755
--- a/CPP/Windows/FileName.h
+++ b/CPP/Windows/FileName.h
@@ -3,6 +3,8 @@
#ifndef __WINDOWS_FILENAME_H
#define __WINDOWS_FILENAME_H
+#include "../../C/Types.h"
+
#include "../Common/MyString.h"
namespace NWindows {
diff --git a/CPP/Windows/PropVariant.cpp b/CPP/Windows/PropVariant.cpp
index 3675778d..90212e08 100755
--- a/CPP/Windows/PropVariant.cpp
+++ b/CPP/Windows/PropVariant.cpp
@@ -218,7 +218,7 @@ void CPropVariant::InternalCopy(const PROPVARIANT *pSrc)
int CPropVariant::Compare(const CPropVariant &a)
{
if (vt != a.vt)
- return 0; // it's bug case
+ return MyCompare(vt, a.vt);
switch (vt)
{
case VT_EMPTY: return 0;
diff --git a/CPP/Windows/PropVariantUtils.cpp b/CPP/Windows/PropVariantUtils.cpp
index 0c9e8f34..0a9cfab7 100755
--- a/CPP/Windows/PropVariantUtils.cpp
+++ b/CPP/Windows/PropVariantUtils.cpp
@@ -53,13 +53,14 @@ AString FlagsToString(const CUInt32PCharPair *pairs, unsigned num, UInt32 flags)
for (unsigned i = 0; i < num; i++)
{
const CUInt32PCharPair &p = pairs[i];
- if ((flags & p.Value) != 0)
+ UInt32 flag = (UInt32)1 << (unsigned)p.Value;
+ if ((flags & flag) != 0)
{
if (!s.IsEmpty())
s += ' ';
s += p.Name;
}
- flags &= ~p.Value;
+ flags &= ~flag;
}
if (flags != 0)
{
diff --git a/DOC/7zip.inf b/DOC/7zip.inf
index 400f7f96..5bceb480 100755
--- a/DOC/7zip.inf
+++ b/DOC/7zip.inf
@@ -10,8 +10,8 @@ AppName = "7-Zip"
InstallDir = %CE1%\%AppName%
[Strings]
-AppVer = "9.17"
-AppDate = "2010-10-04"
+AppVer = "9.18"
+AppDate = "2010-11-02"
[CEDevice]
; ProcessorType = 2577 ; ARM
@@ -32,6 +32,7 @@ CEShortcuts = Shortcuts
[SourceDisksFiles]
7zFM.exe = 1
7z.sfx = 1
+7zS2.sfx = 1
ru.txt = 2
[DestinationDirs]
@@ -43,6 +44,7 @@ Shortcuts = ,%CE11%
[CopyFilesSection]
7zFM.exe
7z.sfx
+7zS2.sfx
[CopyFilesSection.Lang]
ru.txt
diff --git a/DOC/7zip.nsi b/DOC/7zip.nsi
index 54ed3424..42c60aad 100755
--- a/DOC/7zip.nsi
+++ b/DOC/7zip.nsi
@@ -2,7 +2,7 @@
;Defines
!define VERSION_MAJOR 9
-!define VERSION_MINOR 17
+!define VERSION_MINOR 18
!define VERSION_POSTFIX_FULL " beta"
!ifdef WIN64
!ifdef IA64
diff --git a/DOC/7zip.wxs b/DOC/7zip.wxs
index 83465d43..ec6d00e4 100755
--- a/DOC/7zip.wxs
+++ b/DOC/7zip.wxs
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<?define VerMajor = "9" ?>
-<?define VerMinor = "17" ?>
+<?define VerMinor = "18" ?>
<?define VerBuild = "00" ?>
<?define MmVer = "$(var.VerMajor).$(var.VerMinor)" ?>
<?define MmHex = "0$(var.VerMajor)$(var.VerMinor)" ?>
diff --git a/DOC/Methods.txt b/DOC/Methods.txt
index 0415a126..f52e7c31 100755
--- a/DOC/Methods.txt
+++ b/DOC/Methods.txt
@@ -1,4 +1,4 @@
-7-Zip method IDs (9.04)
+7-Zip method IDs (9.18)
-----------------------
Each compression or crypto method in 7z has unique binary value (ID).
@@ -77,7 +77,13 @@ List of defined IDs
06 - Implode
08 - Deflate
09 - Deflate64
+ 10 - Imploding
12 - BZip2 (not used). Use {04 02 02} instead
+ 14 - LZMA
+ 60 - Jpeg
+ 61 - WavPack
+ 62 - PPMd
+ 63 - wzAES
02 - BZip
02 - BZip2
03 - Rar
diff --git a/DOC/history.txt b/DOC/history.txt
index aa383647..05a9a216 100755
--- a/DOC/history.txt
+++ b/DOC/history.txt
@@ -1,6 +1,11 @@
Sources history of the 7-Zip
----------------------------
+9.18 2010-11-02
+-------------------------
+- New small SFX module for installers (C/Util/SfxSetup).
+
+
9.17 2010-10-04
-------------------------
- IStream.h::IOutStream::
diff --git a/DOC/lzma.txt b/DOC/lzma.txt
index 47369042..ae872f3d 100755
--- a/DOC/lzma.txt
+++ b/DOC/lzma.txt
@@ -1,4 +1,4 @@
-LZMA SDK 9.17
+LZMA SDK 9.18
-------------
LZMA SDK provides the documentation, samples, header files, libraries,
diff --git a/DOC/readme.txt b/DOC/readme.txt
index a6d781ca..7e959dc6 100755
--- a/DOC/readme.txt
+++ b/DOC/readme.txt
@@ -1,4 +1,4 @@
-7-Zip 9.17 Sources
+7-Zip 9.18 Sources
------------------
7-Zip is a file archiver for Windows.