This commit is contained in:
Igor Pavlov
2010-11-02 00:00:00 +00:00
committed by Kornel Lesiński
parent 2eb60a0598
commit c65230d858
101 changed files with 4557 additions and 541 deletions
+1 -2
View File
@@ -1,7 +1,6 @@
/* 7zAlloc.c -- Allocation functions /* 7zAlloc.c -- Allocation functions
2008-10-04 : Igor Pavlov : Public domain */ 2010-10-29 : Igor Pavlov : Public domain */
#include <stdlib.h>
#include "7zAlloc.h" #include "7zAlloc.h"
/* #define _SZ_ALLOC_DEBUG */ /* #define _SZ_ALLOC_DEBUG */
+2 -10
View File
@@ -1,14 +1,10 @@
/* 7zAlloc.h -- Allocation functions /* 7zAlloc.h -- Allocation functions
2009-02-07 : Igor Pavlov : Public domain */ 2010-10-29 : Igor Pavlov : Public domain */
#ifndef __7Z_ALLOC_H #ifndef __7Z_ALLOC_H
#define __7Z_ALLOC_H #define __7Z_ALLOC_H
#include <stddef.h> #include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
void *SzAlloc(void *p, size_t size); void *SzAlloc(void *p, size_t size);
void SzFree(void *p, void *address); void SzFree(void *p, void *address);
@@ -16,8 +12,4 @@ void SzFree(void *p, void *address);
void *SzAllocTemp(void *p, size_t size); void *SzAllocTemp(void *p, size_t size);
void SzFreeTemp(void *p, void *address); void SzFreeTemp(void *p, void *address);
#ifdef __cplusplus
}
#endif
#endif #endif
+43 -17
View File
@@ -1,5 +1,5 @@
/* 7zDec.c -- Decoding from 7z folder /* 7zDec.c -- Decoding from 7z folder
2010-03-15 : Igor Pavlov : Public domain */ 2010-11-02 : Igor Pavlov : Public domain */
#include <string.h> #include <string.h>
@@ -18,9 +18,13 @@
#define k_Copy 0 #define k_Copy 0
#define k_LZMA2 0x21 #define k_LZMA2 0x21
#define k_LZMA 0x30101 #define k_LZMA 0x30101
#define k_BCJ 0x03030103 #define k_BCJ 0x03030103
#define k_BCJ2 0x0303011B #define k_PPC 0x03030205
#define k_ARM 0x03030501
#define k_ARMT 0x03030701
#define k_SPARC 0x03030805
#define k_BCJ2 0x0303011B
#ifdef _7ZIP_PPMD_SUPPPORT #ifdef _7ZIP_PPMD_SUPPPORT
@@ -260,7 +264,6 @@ static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c)
IS_MAIN_METHOD((UInt32)c->MethodID); 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) #define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumInStreams == 4 && (c)->NumOutStreams == 1)
static SRes CheckSupportedFolder(const CSzFolder *f) static SRes CheckSupportedFolder(const CSzFolder *f)
@@ -277,11 +280,24 @@ static SRes CheckSupportedFolder(const CSzFolder *f)
} }
if (f->NumCoders == 2) if (f->NumCoders == 2)
{ {
if (!IS_BCJ(&f->Coders[1]) || CSzCoderInfo *c = &f->Coders[1];
f->NumPackStreams != 1 || f->PackStreams[0] != 0 || if (c->MethodID > (UInt32)0xFFFFFFFF ||
c->NumInStreams != 1 ||
c->NumOutStreams != 1 ||
f->NumPackStreams != 1 ||
f->PackStreams[0] != 0 ||
f->NumBindPairs != 1 || 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; return SZ_ERROR_UNSUPPORTED;
switch ((UInt32)c->MethodID)
{
case k_BCJ:
case k_ARM:
break;
default:
return SZ_ERROR_UNSUPPORTED;
}
return SZ_OK; return SZ_OK;
} }
if (f->NumCoders == 4) if (f->NumCoders == 4)
@@ -314,6 +330,8 @@ static UInt64 GetSum(const UInt64 *values, UInt32 index)
return sum; 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, static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
ILookInStream *inStream, UInt64 startPos, ILookInStream *inStream, UInt64 startPos,
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain, Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain,
@@ -391,14 +409,6 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
#endif #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) else if (coder->MethodID == k_BCJ2)
{ {
UInt64 offset = GetSum(packSizes, 1); UInt64 offset = GetSum(packSizes, 1);
@@ -425,7 +435,23 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
RINOK(res) RINOK(res)
} }
else 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; return SZ_OK;
} }
+10 -6
View File
@@ -1,5 +1,5 @@
/* 7zIn.c -- 7z Input functions /* 7zIn.c -- 7z Input functions
2010-03-11 : Igor Pavlov : Public domain */ 2010-10-29 : Igor Pavlov : Public domain */
#include <string.h> #include <string.h>
@@ -1218,12 +1218,16 @@ static SRes SzArEx_Open2(
ISzAlloc *allocTemp) ISzAlloc *allocTemp)
{ {
Byte header[k7zStartHeaderSize]; Byte header[k7zStartHeaderSize];
Int64 startArcPos;
UInt64 nextHeaderOffset, nextHeaderSize; UInt64 nextHeaderOffset, nextHeaderSize;
size_t nextHeaderSizeT; size_t nextHeaderSizeT;
UInt32 nextHeaderCRC; UInt32 nextHeaderCRC;
CBuf buffer; CBuf buffer;
SRes res; SRes res;
startArcPos = 0;
RINOK(inStream->Seek(inStream, &startArcPos, SZ_SEEK_CUR));
RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE)); RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE));
if (!TestSignatureCandidate(header)) if (!TestSignatureCandidate(header))
@@ -1235,7 +1239,7 @@ static SRes SzArEx_Open2(
nextHeaderSize = GetUi64(header + 20); nextHeaderSize = GetUi64(header + 20);
nextHeaderCRC = GetUi32(header + 28); nextHeaderCRC = GetUi32(header + 28);
p->startPosAfterHeader = k7zStartHeaderSize; p->startPosAfterHeader = startArcPos + k7zStartHeaderSize;
if (CrcCalc(header + 12, 20) != GetUi32(header + 8)) if (CrcCalc(header + 12, 20) != GetUi32(header + 8))
return SZ_ERROR_CRC; return SZ_ERROR_CRC;
@@ -1252,13 +1256,13 @@ static SRes SzArEx_Open2(
{ {
Int64 pos = 0; Int64 pos = 0;
RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END)); RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END));
if ((UInt64)pos < nextHeaderOffset || if ((UInt64)pos < startArcPos + nextHeaderOffset ||
(UInt64)pos < k7zStartHeaderSize + nextHeaderOffset || (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset ||
(UInt64)pos < k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize) (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)
return SZ_ERROR_INPUT_EOF; return SZ_ERROR_INPUT_EOF;
} }
RINOK(LookInStream_SeekTo(inStream, k7zStartHeaderSize + nextHeaderOffset)); RINOK(LookInStream_SeekTo(inStream, startArcPos + k7zStartHeaderSize + nextHeaderOffset));
if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp)) if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp))
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
+3 -3
View File
@@ -1,7 +1,7 @@
#define MY_VER_MAJOR 9 #define MY_VER_MAJOR 9
#define MY_VER_MINOR 17 #define MY_VER_MINOR 18
#define MY_VER_BUILD 0 #define MY_VER_BUILD 0
#define MY_VERSION "9.17 beta" #define MY_VERSION "9.18 beta"
#define MY_DATE "2010-10-04" #define MY_DATE "2010-11-02"
#define MY_COPYRIGHT ": Igor Pavlov : Public domain" #define MY_COPYRIGHT ": Igor Pavlov : Public domain"
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE #define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE
+8 -8
View File
@@ -1,5 +1,5 @@
/* CpuArch.c -- CPU specific code /* CpuArch.c -- CPU specific code
2009-12-12: Igor Pavlov : Public domain */ 2010-10-26: Igor Pavlov : Public domain */
#include "CpuArch.h" #include "CpuArch.h"
@@ -72,13 +72,13 @@ static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
#else #else
__asm__ __volatile__ ( __asm__ __volatile__ (
"cpuid" "cpuid"
: "=a" (*a) , : "=a" (*a) ,
"=b" (*b) , "=b" (*b) ,
"=c" (*c) , "=c" (*c) ,
"=d" (*d) "=d" (*d)
: "0" (function)) ; : "0" (function)) ;
#endif #endif
+14 -2
View File
@@ -1,5 +1,5 @@
/* CpuArch.h -- CPU specific code /* CpuArch.h -- CPU specific code
2010-05-20: Igor Pavlov : Public domain */ 2010-10-26: Igor Pavlov : Public domain */
#ifndef __CPU_ARCH_H #ifndef __CPU_ARCH_H
#define __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 #define MY_CPU_ARM_LE
#endif #endif
#if defined(_WIN32) && defined(_M_IA64)
#define MY_CPU_IA64_LE
#endif
#if defined(MY_CPU_X86_OR_AMD64) #if defined(MY_CPU_X86_OR_AMD64)
#define MY_CPU_LE_UNALIGN #define MY_CPU_LE_UNALIGN
#endif #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 #define MY_CPU_LE
#endif #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 #ifdef MY_CPU_LE_UNALIGN
#define GetUi16(p) (*(const UInt16 *)(p)) #define GetUi16(p) (*(const UInt16 *)(p))
+17 -1
View File
@@ -1,5 +1,5 @@
/* Types.h -- Basic types /* Types.h -- Basic types
2010-04-16 : Igor Pavlov : Public domain */ 2010-10-09 : Igor Pavlov : Public domain */
#ifndef __7Z_TYPES_H #ifndef __7Z_TYPES_H
#define __7Z_TYPES_H #define __7Z_TYPES_H
@@ -233,6 +233,22 @@ typedef struct
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size) #define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
#define IAlloc_Free(p, a) (p)->Free((p), a) #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 EXTERN_C_END
#endif #endif
+12 -8
View File
@@ -92,6 +92,14 @@ SOURCE=..\..\7z.h
# End Source File # End Source File
# Begin 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 SOURCE=..\..\7zBuf.c
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -141,6 +149,10 @@ SOURCE=..\..\Bcj2.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Bra.c
# End Source File
# Begin Source File
SOURCE=..\..\Bra.h SOURCE=..\..\Bra.h
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -196,14 +208,6 @@ SOURCE=..\..\Types.h
# End Group # End Group
# Begin Source File # Begin Source File
SOURCE=.\7zAlloc.c
# End Source File
# Begin Source File
SOURCE=.\7zAlloc.h
# End Source File
# Begin Source File
SOURCE=.\7zMain.c SOURCE=.\7zMain.c
# End Source File # End Source File
# End Target # End Target
+10 -10
View File
@@ -1,16 +1,15 @@
/* 7zMain.c - Test application for 7z Decoder /* 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 <stdio.h>
#include <string.h> #include <string.h>
#include "../../7z.h" #include "../../7z.h"
#include "../../7zAlloc.h"
#include "../../7zCrc.h" #include "../../7zCrc.h"
#include "../../7zFile.h" #include "../../7zFile.h"
#include "../../7zVersion.h" #include "../../7zVersion.h"
#include "7zAlloc.h"
#ifndef USE_WINDOWS_FILE #ifndef USE_WINDOWS_FILE
/* for mkdir */ /* for mkdir */
#ifdef _WIN32 #ifdef _WIN32
@@ -21,12 +20,6 @@
#endif #endif
#endif #endif
#ifdef _WIN32
#define CHAR_PATH_SEPARATOR '\\'
#else
#define CHAR_PATH_SEPARATOR '/'
#endif
static ISzAlloc g_Alloc = { SzAlloc, SzFree }; static ISzAlloc g_Alloc = { SzAlloc, SzFree };
static int Buf_EnsureSize(CBuf *dest, size_t size) 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 = '_'; char defaultChar = '_';
BOOL defUsed; 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); 0, s, len, (char *)buf->data, size, &defaultChar, &defUsed);
if (numChars == 0 || numChars >= size) if (numChars == 0 || numChars >= size)
return SZ_ERROR_FAIL; return SZ_ERROR_FAIL;
+2 -1
View File
@@ -4,6 +4,7 @@ CFLAGS = $(CFLAGS) -D_7ZIP_PPMD_SUPPPORT
PROG = 7zDec.exe PROG = 7zDec.exe
C_OBJS = \ C_OBJS = \
$O\7zAlloc.obj \
$O\7zBuf.obj \ $O\7zBuf.obj \
$O\7zBuf2.obj \ $O\7zBuf2.obj \
$O\7zCrc.obj \ $O\7zCrc.obj \
@@ -13,6 +14,7 @@ C_OBJS = \
$O\7zIn.obj \ $O\7zIn.obj \
$O\7zStream.obj \ $O\7zStream.obj \
$O\Bcj2.obj \ $O\Bcj2.obj \
$O\Bra.obj \
$O\Bra86.obj \ $O\Bra86.obj \
$O\CpuArch.obj \ $O\CpuArch.obj \
$O\Lzma2Dec.obj \ $O\Lzma2Dec.obj \
@@ -21,7 +23,6 @@ C_OBJS = \
$O\Ppmd7Dec.obj \ $O\Ppmd7Dec.obj \
7Z_OBJS = \ 7Z_OBJS = \
$O\7zAlloc.obj \
$O\7zMain.obj \ $O\7zMain.obj \
OBJS = \ OBJS = \
+5 -2
View File
@@ -4,7 +4,7 @@ LIB =
RM = rm -f RM = rm -f
CFLAGS = -c -O2 -Wall 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) all: $(PROG)
@@ -15,7 +15,7 @@ $(PROG): $(OBJS)
$(CXX) $(CFLAGS) 7zMain.c $(CXX) $(CFLAGS) 7zMain.c
7zAlloc.o: 7zAlloc.c 7zAlloc.o: 7zAlloc.c
$(CXX) $(CFLAGS) 7zAlloc.c $(CXX) $(CFLAGS) ../../7zAlloc.c
7zBuf.o: ../../7zBuf.c 7zBuf.o: ../../7zBuf.c
$(CXX) $(CFLAGS) ../../7zBuf.c $(CXX) $(CFLAGS) ../../7zBuf.c
@@ -44,6 +44,9 @@ LzmaDec.o: ../../LzmaDec.c
Lzma2Dec.o: ../../Lzma2Dec.c Lzma2Dec.o: ../../Lzma2Dec.c
$(CXX) $(CFLAGS) ../../Lzma2Dec.c $(CXX) $(CFLAGS) ../../Lzma2Dec.c
Bra.o: ../../Bra.c
$(CXX) $(CFLAGS) ../../Bra.c
Bra86.o: ../../Bra86.c Bra86.o: ../../Bra86.c
$(CXX) $(CFLAGS) ../../Bra86.c $(CXX) $(CFLAGS) ../../Bra86.c
+591
View File
@@ -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;
}
+198
View File
@@ -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
+29
View File
@@ -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>
{{{
}}}
###############################################################################
+35
View File
@@ -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)
+35
View File
@@ -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)
+6
View File
@@ -0,0 +1,6 @@
#include "../../../CPP/7zip/MyVersionInfo.rc"
MY_VERSION_INFO_APP("7z Setup SFX small", "7zS2.sfx")
1 ICON "setup.ico"
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

+5 -10
View File
@@ -193,11 +193,9 @@ HRESULT CEncoder::Encode(
// UInt64 outStreamStartPos; // UInt64 outStreamStartPos;
// RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos)); // RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos));
CSequentialInStreamSizeCount2 *inStreamSizeCountSpec = CSequentialInStreamSizeCount2 *inStreamSizeCountSpec = new CSequentialInStreamSizeCount2;
new CSequentialInStreamSizeCount2;
CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec; CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec;
CSequentialOutStreamSizeCount *outStreamSizeCountSpec = CSequentialOutStreamSizeCount *outStreamSizeCountSpec = new CSequentialOutStreamSizeCount;
new CSequentialOutStreamSizeCount;
CMyComPtr<ISequentialOutStream> outStreamSizeCount = outStreamSizeCountSpec; CMyComPtr<ISequentialOutStream> outStreamSizeCount = outStreamSizeCountSpec;
inStreamSizeCountSpec->Init(inStream); inStreamSizeCountSpec->Init(inStream);
@@ -226,13 +224,11 @@ HRESULT CEncoder::Encode(
_mixerCoderSpec->_coders[i].QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties); _mixerCoderSpec->_coders[i].QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties);
if (writeCoderProperties != NULL) if (writeCoderProperties != NULL)
{ {
CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp; CDynBufSeqOutStream *outStreamSpec = new CDynBufSeqOutStream;
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec); CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
outStreamSpec->Init(); outStreamSpec->Init();
writeCoderProperties->WriteCoderProperties(outStream); writeCoderProperties->WriteCoderProperties(outStream);
size_t size = outStreamSpec->GetSize(); outStreamSpec->CopyToBuffer(encodingInfo.Props);
encodingInfo.Props.SetCapacity(size);
memmove(encodingInfo.Props, outStreamSpec->GetBuffer(), size);
} }
} }
@@ -250,8 +246,7 @@ HRESULT CEncoder::Encode(
RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1, RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1,
&outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress)); &outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress));
ConvertBindInfoToFolderItemInfo(_decompressBindInfo, _decompressionMethods, ConvertBindInfoToFolderItemInfo(_decompressBindInfo, _decompressionMethods, folderItem);
folderItem);
packSizes.Add(outStreamSizeCountSpec->GetSize()); packSizes.Add(outStreamSizeCountSpec->GetSize());
+36 -17
View File
@@ -280,28 +280,46 @@ void CInByte2::ReadString(UString &s)
_pos += rem + 2; _pos += rem + 2;
} }
static inline bool TestSignatureCandidate(const Byte *p) static inline bool TestSignature(const Byte *p)
{ {
for (int i = 0; i < kSignatureSize; i++) for (int i = 0; i < kSignatureSize; i++)
if (p[i] != kSignature[i]) if (p[i] != kSignature[i])
return false; 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) HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
{ {
RINOK(ReadStream_FALSE(stream, _header, kHeaderSize)); RINOK(ReadStream_FALSE(stream, _header, kHeaderSize));
if (TestSignatureCandidate(_header)) if (TestSignature2(_header))
return S_OK; return S_OK;
CByteBuffer byteBuffer; CByteBuffer byteBuffer;
const UInt32 kBufferSize = (1 << 16); const UInt32 kBufferSize = (1 << 16);
byteBuffer.SetCapacity(kBufferSize); byteBuffer.SetCapacity(kBufferSize);
Byte *buffer = byteBuffer; Byte *buffer = byteBuffer;
UInt32 numPrevBytes = kHeaderSize - 1; UInt32 numPrevBytes = kHeaderSize;
memcpy(buffer, _header + 1, numPrevBytes); memcpy(buffer, _header, kHeaderSize);
UInt64 curTestPos = _arhiveBeginStreamPosition + 1; UInt64 curTestPos = _arhiveBeginStreamPosition;
for (;;) for (;;)
{ {
if (searchHeaderSizeLimit != NULL) if (searchHeaderSizeLimit != NULL)
@@ -316,14 +334,14 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search
if (processedSize == 0) if (processedSize == 0)
return S_FALSE; return S_FALSE;
} }
while (numPrevBytes < kHeaderSize); while (numPrevBytes <= kHeaderSize);
UInt32 numTests = numPrevBytes - kHeaderSize + 1; UInt32 numTests = numPrevBytes - kHeaderSize;
for (UInt32 pos = 0; pos < numTests; pos++) for (UInt32 pos = 0; pos < numTests; pos++)
{ {
for (; buffer[pos] != '7' && pos < numTests; pos++); for (; buffer[pos] != '7' && pos < numTests; pos++);
if (pos == numTests) if (pos == numTests)
break; break;
if (TestSignatureCandidate(buffer + pos)) if (TestSignature(buffer + pos))
{ {
memcpy(_header, buffer + pos, kHeaderSize); memcpy(_header, buffer + pos, kHeaderSize);
curTestPos += pos; curTestPos += pos;
@@ -812,7 +830,7 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
ThrowUnsupported(); ThrowUnsupported();
data.SetCapacity(unpackSize); data.SetCapacity(unpackSize);
CSequentialOutStreamImp2 *outStreamSpec = new CSequentialOutStreamImp2; CBufPtrSeqOutStream *outStreamSpec = new CBufPtrSeqOutStream;
CMyComPtr<ISequentialOutStream> outStream = outStreamSpec; CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
outStreamSpec->Init(data, unpackSize); outStreamSpec->Init(data, unpackSize);
@@ -1164,23 +1182,24 @@ HRESULT CInArchive::ReadDatabase2(
nextHeaderCRC = CrcCalc(buf + i, (size_t)nextHeaderSize); nextHeaderCRC = CrcCalc(buf + i, (size_t)nextHeaderSize);
RINOK(_stream->Seek(cur, STREAM_SEEK_SET, NULL)); RINOK(_stream->Seek(cur, STREAM_SEEK_SET, NULL));
} }
else
#endif #endif
{
#ifdef FORMAT_7Z_RECOVERY if (crc != crcFromArchive)
crcFromArchive = crc; ThrowIncorrect();
#endif }
db.ArchiveInfo.StartPositionAfterHeader = _arhiveBeginStreamPosition + kHeaderSize; db.ArchiveInfo.StartPositionAfterHeader = _arhiveBeginStreamPosition + kHeaderSize;
if (crc != crcFromArchive)
ThrowIncorrect();
if (nextHeaderSize == 0) if (nextHeaderSize == 0)
return S_OK; return S_OK;
if (nextHeaderSize > (UInt64)0xFFFFFFFF) if (nextHeaderSize > (UInt64)0xFFFFFFFF)
return S_FALSE; return S_FALSE;
if ((Int64)nextHeaderOffset < 0)
return S_FALSE;
RINOK(_stream->Seek(nextHeaderOffset, STREAM_SEEK_CUR, NULL)); RINOK(_stream->Seek(nextHeaderOffset, STREAM_SEEK_CUR, NULL));
CByteBuffer buffer2; CByteBuffer buffer2;
@@ -2,6 +2,8 @@
#include "StdAfx.h" #include "StdAfx.h"
#include "../../../../C/Types.h"
#include "ItemNameUtils.h" #include "ItemNameUtils.h"
namespace NArchive { namespace NArchive {
+44 -55
View File
@@ -6,72 +6,61 @@
STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize) STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{ {
if(processedSize != NULL) if (processedSize)
*processedSize = 0; *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]; int left = 0, mid = _streamIndex, right = Streams.Size();
if (_pos == s.Size) for (;;)
{ {
_streamIndex++; CSubStreamInfo &m = Streams[mid];
_pos = 0; if (_pos < m.GlobalOffset)
continue; 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)); _streamIndex = mid;
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;
} }
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, STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
UInt64 *newPosition)
{ {
UInt64 newPos;
switch(seekOrigin) switch(seekOrigin)
{ {
case STREAM_SEEK_SET: case STREAM_SEEK_SET: _pos = offset; break;
newPos = offset; case STREAM_SEEK_CUR: _pos = _pos + offset; break;
break; case STREAM_SEEK_END: _pos = _totalLength + offset; break;
case STREAM_SEEK_CUR: default: return STG_E_INVALIDFUNCTION;
newPos = _seekPos + offset;
break;
case STREAM_SEEK_END:
newPos = _totalLength + offset;
break;
default:
return STG_E_INVALIDFUNCTION;
} }
_seekPos = 0; if (newPosition != 0)
for (_streamIndex = 0; _streamIndex < Streams.Size(); _streamIndex++) *newPosition = _pos;
{ return S_OK;
UInt64 size = Streams[_streamIndex].Size;
if (newPos < _seekPos + size)
{
_pos = newPos - _seekPos;
_seekPos += _pos;
if (newPosition != 0)
*newPosition = newPos;
return S_OK;
}
_seekPos += size;
}
if (newPos == _seekPos)
{
if (newPosition != 0)
*newPosition = newPos;
return S_OK;
}
return E_FAIL;
} }
+20 -12
View File
@@ -1,36 +1,44 @@
// MultiStream.h // MultiStream.h
#ifndef __MULTISTREAM_H #ifndef __MULTI_STREAM_H
#define __MULTISTREAM_H #define __MULTI_STREAM_H
#include "../../../Common/MyCom.h" #include "../../../Common/MyCom.h"
#include "../../../Common/MyVector.h" #include "../../../Common/MyVector.h"
#include "../../Archive/IArchive.h"
#include "../../IStream.h"
class CMultiStream: class CMultiStream:
public IInStream, public IInStream,
public CMyUnknownImp public CMyUnknownImp
{ {
int _streamIndex;
UInt64 _pos; UInt64 _pos;
UInt64 _seekPos;
UInt64 _totalLength; UInt64 _totalLength;
int _streamIndex;
public: public:
struct CSubStreamInfo struct CSubStreamInfo
{ {
CMyComPtr<IInStream> Stream; CMyComPtr<IInStream> Stream;
UInt64 Pos;
UInt64 Size; UInt64 Size;
UInt64 GlobalOffset;
UInt64 LocalPos;
}; };
CObjectVector<CSubStreamInfo> Streams; CObjectVector<CSubStreamInfo> Streams;
void Init()
HRESULT Init()
{ {
_streamIndex = 0; UInt64 total = 0;
_pos = 0;
_seekPos = 0;
_totalLength = 0;
for (int i = 0; i < Streams.Size(); i++) 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) MY_UNKNOWN_IMP1(IInStream)
+644
View File
@@ -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)
}}
+3 -3
View File
@@ -277,9 +277,9 @@ static const CUInt32PCharPair g_AbiOS[] =
static const CUInt32PCharPair g_SegmentFlags[] = static const CUInt32PCharPair g_SegmentFlags[] =
{ {
{ 1 << 0, "Execute" }, { 0, "Execute" },
{ 1 << 1, "Write" }, { 1, "Write" },
{ 1 << 2, "Read" } { 2, "Read" }
}; };
static const char *g_Types[] = static const char *g_Types[] =
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

+68 -18
View File
@@ -24,7 +24,7 @@ using namespace NTime;
namespace NArchive { namespace NArchive {
namespace NIso { namespace NIso {
static STATPROPSTG kProps[] = static const STATPROPSTG kProps[] =
{ {
{ NULL, kpidPath, VT_BSTR}, { NULL, kpidPath, VT_BSTR},
{ NULL, kpidIsDir, VT_BOOL}, { NULL, kpidIsDir, VT_BOOL},
@@ -33,8 +33,17 @@ static STATPROPSTG kProps[] =
{ NULL, kpidMTime, VT_FILETIME} { 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_Props
IMP_IInArchive_ArcProps_NO IMP_IInArchive_ArcProps
STDMETHODIMP CHandler::Open(IInStream *stream, STDMETHODIMP CHandler::Open(IInStream *stream,
const UInt64 * /* maxCheckStartPosition */, const UInt64 * /* maxCheckStartPosition */,
@@ -66,6 +75,58 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
return S_OK; 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) STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
@@ -87,9 +148,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
prop = (const wchar_t *)s; prop = (const wchar_t *)s;
break; break;
} }
case kpidIsDir: case kpidIsDir: prop = false; break;
prop = false;
break;
case kpidSize: case kpidSize:
case kpidPackSize: case kpidPackSize:
prop = (UInt64)_archive.GetBootItemSize(index); 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); prop = (const wchar_t *)NItemName::GetOSName2(s);
} }
break; break;
case kpidIsDir: case kpidIsDir: prop = item.IsDir(); break;
prop = item.IsDir();
break;
case kpidSize: case kpidSize:
case kpidPackSize: case kpidPackSize:
if (!item.IsDir()) if (!item.IsDir())
@@ -131,16 +188,9 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
break; break;
case kpidMTime: case kpidMTime:
{ {
FILETIME utcFileTime; FILETIME utc;
if (item.DateTime.GetFileTime(utcFileTime)) if (item.DateTime.GetFileTime(utc))
prop = utcFileTime; prop = utc;
/*
else
{
utcFileTime.dwLowDateTime = 0;
utcFileTime.dwHighDateTime = 0;
}
*/
break; break;
} }
} }
+2 -1
View File
@@ -65,7 +65,7 @@ UInt16 CInArchive::ReadUInt16()
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
{ {
if (b[i] != b[3 - i]) if (b[i] != b[3 - i])
throw 1; IncorrectBigEndian = true;
value |= ((UInt16)(b[i]) << (8 * i)); value |= ((UInt16)(b[i]) << (8 * i));
} }
return (UInt16)value; return (UInt16)value;
@@ -440,6 +440,7 @@ HRESULT CInArchive::Open(IInStream *inStream)
void CInArchive::Clear() void CInArchive::Clear()
{ {
IncorrectBigEndian = false;
Refs.Clear(); Refs.Clear();
_rootDir.Clear(); _rootDir.Clear();
VolDescs.Clear(); VolDescs.Clear();
+15
View File
@@ -111,6 +111,20 @@ struct CDateTime
signed char GmtOffset; // min intervals from -48 (West) to +52 (East) recorded. signed char GmtOffset; // min intervals from -48 (West) to +52 (East) recorded.
bool NotSpecified() const { return Year == 0 && Month == 0 && Day == 0 && bool NotSpecified() const { return Year == 0 && Month == 0 && Day == 0 &&
Hour == 0 && Minute == 0 && Second == 0 && GmtOffset == 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 struct CBootRecordDescriptor
@@ -268,6 +282,7 @@ public:
int MainVolDescIndex; int MainVolDescIndex;
UInt32 BlockSize; UInt32 BlockSize;
CObjectVector<CBootInitialEntry> BootEntries; CObjectVector<CBootInitialEntry> BootEntries;
bool IncorrectBigEndian;
bool IsJoliet() const { return VolDescs[MainVolDescIndex].IsJoliet(); } bool IsJoliet() const { return VolDescs[MainVolDescIndex].IsJoliet(); }
+1 -1
View File
@@ -266,7 +266,7 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
return (startHeader[0] == 0) ? S_OK: S_FALSE; return (startHeader[0] == 0) ? S_OK: S_FALSE;
const Byte *p = header; const Byte *p = header;
memmove(item.Method, p, kMethodIdSize); memcpy(item.Method, p, kMethodIdSize);
if (!item.IsValidMethod()) if (!item.IsValidMethod())
return S_OK; return S_OK;
p += kMethodIdSize; p += kMethodIdSize;
+10 -10
View File
@@ -77,16 +77,16 @@ static const char *g_FileTypes[] =
static const CUInt32PCharPair g_Flags[] = static const CUInt32PCharPair g_Flags[] =
{ {
{ (UInt32)1 << 31, "PURE_INSTRUCTIONS" }, { 31, "PURE_INSTRUCTIONS" },
{ 1 << 30, "NO_TOC" }, { 30, "NO_TOC" },
{ 1 << 29, "STRIP_STATIC_SYMS" }, { 29, "STRIP_STATIC_SYMS" },
{ 1 << 28, "NO_DEAD_STRIP" }, { 28, "NO_DEAD_STRIP" },
{ 1 << 27, "LIVE_SUPPORT" }, { 27, "LIVE_SUPPORT" },
{ 1 << 26, "SELF_MODIFYING_CODE" }, { 26, "SELF_MODIFYING_CODE" },
{ 1 << 25, "DEBUG" }, { 25, "DEBUG" },
{ 1 << 10, "SOME_INSTRUCTIONS" }, { 10, "SOME_INSTRUCTIONS" },
{ 1 << 9, "EXT_RELOC" }, { 9, "EXT_RELOC" },
{ 1 << 8, "LOC_RELOC" } { 8, "LOC_RELOC" }
}; };
static const CUInt32PCharPair g_MachinePairs[] = static const CUInt32PCharPair g_MachinePairs[] =
+47 -39
View File
@@ -300,53 +300,53 @@ void CSection::Parse(const Byte *p)
static const CUInt32PCharPair g_HeaderCharacts[] = static const CUInt32PCharPair g_HeaderCharacts[] =
{ {
{ 1 << 1, "Executable" }, { 1, "Executable" },
{ 1 << 13, "DLL" }, { 13, "DLL" },
{ 1 << 8, "32-bit" }, { 8, "32-bit" },
{ 1 << 5, "LargeAddress" }, { 5, "LargeAddress" },
{ 1 << 0, "NoRelocs" }, { 0, "NoRelocs" },
{ 1 << 2, "NoLineNums" }, { 2, "NoLineNums" },
{ 1 << 3, "NoLocalSyms" }, { 3, "NoLocalSyms" },
{ 1 << 4, "AggressiveWsTrim" }, { 4, "AggressiveWsTrim" },
{ 1 << 9, "NoDebugInfo" }, { 9, "NoDebugInfo" },
{ 1 << 10, "RemovableRun" }, { 10, "RemovableRun" },
{ 1 << 11, "NetRun" }, { 11, "NetRun" },
{ 1 << 12, "System" }, { 12, "System" },
{ 1 << 14, "UniCPU" }, { 14, "UniCPU" },
{ 1 << 7, "Little-Endian" }, { 7, "Little-Endian" },
{ 1 << 15, "Big-Endian" } { 15, "Big-Endian" }
}; };
static const CUInt32PCharPair g_DllCharacts[] = static const CUInt32PCharPair g_DllCharacts[] =
{ {
{ 1 << 6, "Relocated" }, { 6, "Relocated" },
{ 1 << 7, "Integrity" }, { 7, "Integrity" },
{ 1 << 8, "NX-Compatible" }, { 8, "NX-Compatible" },
{ 1 << 9, "NoIsolation" }, { 9, "NoIsolation" },
{ 1 << 10, "NoSEH" }, { 10, "NoSEH" },
{ 1 << 11, "NoBind" }, { 11, "NoBind" },
{ 1 << 13, "WDM" }, { 13, "WDM" },
{ 1 << 15, "TerminalServerAware" } { 15, "TerminalServerAware" }
}; };
static const CUInt32PCharPair g_SectFlags[] = static const CUInt32PCharPair g_SectFlags[] =
{ {
{ 1 << 3, "NoPad" }, { 3, "NoPad" },
{ 1 << 5, "Code" }, { 5, "Code" },
{ 1 << 6, "InitializedData" }, { 6, "InitializedData" },
{ 1 << 7, "UninitializedData" }, { 7, "UninitializedData" },
{ 1 << 9, "Comments" }, { 9, "Comments" },
{ 1 << 11, "Remove" }, { 11, "Remove" },
{ 1 << 12, "COMDAT" }, { 12, "COMDAT" },
{ 1 << 15, "GP" }, { 15, "GP" },
{ 1 << 24, "ExtendedRelocations" }, { 24, "ExtendedRelocations" },
{ 1 << 25, "Discardable" }, { 25, "Discardable" },
{ 1 << 26, "NotCached" }, { 26, "NotCached" },
{ 1 << 27, "NotPaged" }, { 27, "NotPaged" },
{ 1 << 28, "Shared" }, { 28, "Shared" },
{ 1 << 29, "Execute" }, { 29, "Execute" },
{ 1 << 30, "Read" }, { 30, "Read" },
{ (UInt32)1 << 31, "Write" } { 31, "Write" }
}; };
static const CUInt32PCharPair g_MachinePairs[] = static const CUInt32PCharPair g_MachinePairs[] =
@@ -1723,6 +1723,14 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
size_t offset = item.Offset - sect.Va; size_t offset = item.Offset - sect.Va;
if (!CheckItem(sect, item, offset)) if (!CheckItem(sect, item, offset))
return S_FALSE; 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); referenceBuf->Buf.SetCapacity(item.HeaderSize + item.Size);
memcpy(referenceBuf->Buf, item.Header, item.HeaderSize); memcpy(referenceBuf->Buf, item.Header, item.HeaderSize);
memcpy(referenceBuf->Buf + item.HeaderSize, _buf + offset, item.Size); memcpy(referenceBuf->Buf + item.HeaderSize, _buf + offset, item.Size);
+14 -5
View File
@@ -46,7 +46,7 @@ static const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]);
static const wchar_t *kUnknownOS = L"Unknown"; static const wchar_t *kUnknownOS = L"Unknown";
STATPROPSTG kProps[] = static const STATPROPSTG kProps[] =
{ {
{ NULL, kpidPath, VT_BSTR}, { NULL, kpidPath, VT_BSTR},
{ NULL, kpidIsDir, VT_BOOL}, { NULL, kpidIsDir, VT_BOOL},
@@ -68,7 +68,7 @@ STATPROPSTG kProps[] =
{ NULL, kpidUnpackVer, VT_UI1} { NULL, kpidUnpackVer, VT_UI1}
}; };
STATPROPSTG kArcProps[] = static const STATPROPSTG kArcProps[] =
{ {
{ NULL, kpidSolid, VT_BOOL}, { NULL, kpidSolid, VT_BOOL},
{ NULL, kpidNumBlocks, VT_UI4}, { NULL, kpidNumBlocks, VT_UI4},
@@ -93,7 +93,7 @@ UInt64 CHandler::GetPackSize(int refIndex) const
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{ {
// COM_TRY_BEGIN COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop; NWindows::NCOM::CPropVariant prop;
switch(propID) switch(propID)
{ {
@@ -112,10 +112,11 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
prop = (UInt32)numBlocks; prop = (UInt32)numBlocks;
break; break;
} }
case kpidError: if (!_errorMessage.IsEmpty()) prop = _errorMessage; break;
} }
prop.Detach(value); prop.Detach(value);
return S_OK; return S_OK;
// COM_TRY_END COM_TRY_END
} }
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
@@ -396,7 +397,14 @@ HRESULT CHandler::Open2(IInStream *stream,
for (;;) for (;;)
{ {
bool decryptionError; 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 (result == S_FALSE)
{ {
if (decryptionError && _items.IsEmpty()) if (decryptionError && _items.IsEmpty())
@@ -461,6 +469,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
STDMETHODIMP CHandler::Close() STDMETHODIMP CHandler::Close()
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
_errorMessage.Empty();
_refItems.Clear(); _refItems.Clear();
_items.Clear(); _items.Clear();
_archives.Clear(); _archives.Clear();
+1
View File
@@ -32,6 +32,7 @@ private:
CObjectVector<CItemEx> _items; CObjectVector<CItemEx> _items;
CObjectVector<CInArchive> _archives; CObjectVector<CInArchive> _archives;
NArchive::NRar::CInArchiveInfo _archiveInfo; NArchive::NRar::CInArchiveInfo _archiveInfo;
AString _errorMessage;
DECL_EXTERNAL_CODECS_VARS DECL_EXTERNAL_CODECS_VARS
+10 -10
View File
@@ -18,16 +18,16 @@ namespace NBlockType
{ {
enum EBlockType enum EBlockType
{ {
kMarker = 0x72, kMarker = 0x72,
kArchiveHeader = 0x73, kArchiveHeader,
kFileHeader = 0x74, kFileHeader,
kCommentHeader = 0x75, kCommentHeader,
kOldAuthenticity = 0x76, kOldAuthenticity,
kSubBlock = 0x77, kOldSubBlock,
kRecoveryRecord = 0x78, kRecoveryRecord,
kAuthenticity = 0x79, kAuthenticity,
kSubBlock,
kEndOfArchive = 0x7B // Is not safe kEndOfArchive
}; };
} }
+6 -3
View File
@@ -372,14 +372,14 @@ void CInArchive::AddToSeekValue(UInt64 addValue)
m_Position += 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; decryptionError = false;
if (m_SeekOnArchiveComment) if (m_SeekOnArchiveComment)
SkipArchiveComment(); SkipArchiveComment();
for (;;) for (;;)
{ {
if(!SeekInArchive(m_Position)) if (!SeekInArchive(m_Position))
return S_FALSE; return S_FALSE;
if (!m_CryptoMode && (m_ArchiveHeader.Flags & if (!m_CryptoMode && (m_ArchiveHeader.Flags &
NHeader::NArchive::kBlockHeadersAreEncrypted) != 0) NHeader::NArchive::kBlockHeadersAreEncrypted) != 0)
@@ -438,8 +438,11 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa
} }
m_FileHeaderData.EnsureCapacity(7); m_FileHeaderData.EnsureCapacity(7);
if(!ReadBytesAndTestSize((Byte *)m_FileHeaderData, 7)) if (!ReadBytesAndTestSize((Byte *)m_FileHeaderData, 7))
{
errorMessage = "Unexpected end of archive";
return S_FALSE; return S_FALSE;
}
m_CurData = (Byte *)m_FileHeaderData; m_CurData = (Byte *)m_FileHeaderData;
m_CurPos = 0; m_CurPos = 0;
+1 -1
View File
@@ -110,7 +110,7 @@ class CInArchive
public: public:
HRESULT Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit); HRESULT Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit);
void Close(); void Close();
HRESULT GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPassword, bool &decryptionError); HRESULT GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPassword, bool &decryptionError, AString &errorMessage);
void SkipArchiveComment(); void SkipArchiveComment();
+3 -3
View File
@@ -79,7 +79,7 @@ static HRESULT RedSigHeaderSig(IInStream *inStream, CSigHeaderSig &h)
char dat[kCSigHeaderSigSize]; char dat[kCSigHeaderSigSize];
char *cur = dat; char *cur = dat;
RINOK(ReadStream_FALSE(inStream, dat, kCSigHeaderSigSize)); RINOK(ReadStream_FALSE(inStream, dat, kCSigHeaderSigSize));
memmove(h.Magic, cur, 4); memcpy(h.Magic, cur, 4);
cur += 4; cur += 4;
cur += 4; cur += 4;
h.IndexLen = Get32(cur); h.IndexLen = Get32(cur);
@@ -95,7 +95,7 @@ HRESULT OpenArchive(IInStream *inStream)
char *cur = leadData; char *cur = leadData;
CLead lead; CLead lead;
RINOK(ReadStream_FALSE(inStream, leadData, kLeadSize)); RINOK(ReadStream_FALSE(inStream, leadData, kLeadSize));
memmove(lead.Magic, cur, 4); memcpy(lead.Magic, cur, 4);
cur += 4; cur += 4;
lead.Major = *cur++; lead.Major = *cur++;
lead.Minor = *cur++; lead.Minor = *cur++;
@@ -103,7 +103,7 @@ HRESULT OpenArchive(IInStream *inStream)
cur += 2; cur += 2;
lead.ArchNum = Get16(cur); lead.ArchNum = Get16(cur);
cur += 2; cur += 2;
memmove(lead.Name, cur, sizeof(lead.Name)); memcpy(lead.Name, cur, sizeof(lead.Name));
cur += sizeof(lead.Name); cur += sizeof(lead.Name);
lead.OSNum = Get16(cur); lead.OSNum = Get16(cur);
cur += 2; cur += 2;
-1
View File
@@ -347,7 +347,6 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
{ {
CMultiStream::CSubStreamInfo subStreamInfo; CMultiStream::CSubStreamInfo subStreamInfo;
subStreamInfo.Stream = _streams[i]; subStreamInfo.Stream = _streams[i];
subStreamInfo.Pos = 0;
subStreamInfo.Size = _sizes[i]; subStreamInfo.Size = _sizes[i];
streamSpec->Streams.Add(subStreamInfo); streamSpec->Streams.Add(subStreamInfo);
} }
+1959
View File
File diff suppressed because it is too large Load Diff
+79 -28
View File
@@ -10,6 +10,8 @@
#include "../../Common/LimitedStreams.h" #include "../../Common/LimitedStreams.h"
#include "../../Common/ProgressUtils.h" #include "../../Common/ProgressUtils.h"
#include "../../Common/StreamObjects.h"
#include "../../Common/StreamUtils.h"
#include "../Common/ItemNameUtils.h" #include "../Common/ItemNameUtils.h"
@@ -21,7 +23,9 @@ using namespace NWindows;
namespace NArchive { namespace NArchive {
namespace NTar { namespace NTar {
static STATPROPSTG kProps[] = static const char *kUnexpectedEnd = "Unexpected end of archive";
static const STATPROPSTG kProps[] =
{ {
{ NULL, kpidPath, VT_BSTR}, { NULL, kpidPath, VT_BSTR},
{ NULL, kpidIsDir, VT_BOOL}, { NULL, kpidIsDir, VT_BOOL},
@@ -34,8 +38,14 @@ static STATPROPSTG kProps[] =
{ NULL, kpidLink, VT_BSTR} { NULL, kpidLink, VT_BSTR}
}; };
static const STATPROPSTG kArcProps[] =
{
{ NULL, kpidPhySize, VT_UI8},
{ NULL, kpidHeadersSize, VT_UI8}
};
IMP_IInArchive_Props IMP_IInArchive_Props
IMP_IInArchive_ArcProps_NO_Table IMP_IInArchive_ArcProps
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{ {
@@ -43,11 +53,22 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
switch(propID) switch(propID)
{ {
case kpidPhySize: if (_phySizeDefined) prop = _phySize; break; 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); prop.Detach(value);
return S_OK; 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) HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
{ {
UInt64 endPos = 0; UInt64 endPos = 0;
@@ -56,26 +77,29 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
} }
_isGood = true; _phySizeDefined = true;
UInt64 pos = 0;
for (;;) for (;;)
{ {
CItemEx item; CItemEx item;
bool filled; bool filled;
item.HeaderPosition = pos; RINOK(ReadItem2(stream, filled, item));
RINOK(ReadItem(stream, filled, item));
if (!filled) if (!filled)
break; break;
_items.Add(item); _items.Add(item);
RINOK(stream->Seek(item.GetPackSize(), STREAM_SEEK_CUR, &pos)); RINOK(stream->Seek(item.GetPackSize(), STREAM_SEEK_CUR, &_phySize));
if (pos > endPos) if (_phySize > endPos)
return S_FALSE;
if (pos == endPos)
{ {
_isGood = false; _errorMessage = kUnexpectedEnd;
break; break;
} }
/*
if (_phySize == endPos)
{
_errorMessage = "There are no trailing zero-filled records";
break;
}
*/
if (callback != NULL) if (callback != NULL)
{ {
if (_items.Size() == 1) if (_items.Size() == 1)
@@ -85,7 +109,7 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
if (_items.Size() % 100 == 0) if (_items.Size() % 100 == 0)
{ {
UInt64 numFiles = _items.Size(); 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() STDMETHODIMP CHandler::Close()
{ {
_errorMessage.Empty();
_phySizeDefined = false; _phySizeDefined = false;
_phySize = 0;
_headersSize = 0;
_curIndex = 0; _curIndex = 0;
_latestIsRead = false; _latestIsRead = false;
_items.Clear(); _items.Clear();
@@ -161,16 +188,24 @@ HRESULT CHandler::SkipTo(UInt32 index)
{ {
UInt64 packSize = _latestItem.GetPackSize(); UInt64 packSize = _latestItem.GetPackSize();
RINOK(copyCoderSpec->Code(_seqStream, NULL, &packSize, &packSize, NULL)); RINOK(copyCoderSpec->Code(_seqStream, NULL, &packSize, &packSize, NULL));
_phySize += copyCoderSpec->TotalSize;
if (copyCoderSpec->TotalSize != packSize)
{
_errorMessage = kUnexpectedEnd;
return S_FALSE;
}
_latestIsRead = false; _latestIsRead = false;
_curIndex++; _curIndex++;
} }
else else
{ {
bool filled; bool filled;
// item.HeaderPosition = pos; RINOK(ReadItem2(_seqStream, filled, _latestItem));
RINOK(ReadItem(_seqStream, filled, _latestItem));
if (!filled) if (!filled)
{
_phySizeDefined = true;
return E_INVALIDARG; return E_INVALIDARG;
}
_latestIsRead = true; _latestIsRead = true;
} }
} }
@@ -203,10 +238,10 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
switch(propID) switch(propID)
{ {
case kpidPath: prop = NItemName::GetOSName2(TarStringToUnicode(item->Name)); break; case kpidPath: prop = NItemName::GetOSName2(TarStringToUnicode(item->Name)); break;
case kpidIsDir: prop = item->IsDir(); break; case kpidIsDir: prop = item->IsDir(); break;
case kpidSize: prop = item->Size; break; case kpidSize: prop = item->GetUnpackSize(); break;
case kpidPackSize: prop = item->GetPackSize(); break; case kpidPackSize: prop = item->GetPackSize(); break;
case kpidMTime: case kpidMTime:
if (item->MTime != 0) if (item->MTime != 0)
{ {
@@ -216,9 +251,9 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
} }
break; break;
case kpidPosixAttrib: prop = item->Mode; break; case kpidPosixAttrib: prop = item->Mode; break;
case kpidUser: prop = TarStringToUnicode(item->User); break; case kpidUser: prop = TarStringToUnicode(item->User); break;
case kpidGroup: prop = TarStringToUnicode(item->Group); break; case kpidGroup: prop = TarStringToUnicode(item->Group); break;
case kpidLink: prop = TarStringToUnicode(item->LinkName); break; case kpidLink: prop = TarStringToUnicode(item->LinkName); break;
} }
prop.Detach(value); prop.Detach(value);
return S_OK; return S_OK;
@@ -242,7 +277,7 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
UInt64 totalSize = 0; UInt64 totalSize = 0;
UInt32 i; UInt32 i;
for (i = 0; i < numItems; i++) for (i = 0; i < numItems; i++)
totalSize += _items[allFilesMode ? i : indices[i]].Size; totalSize += _items[allFilesMode ? i : indices[i]].GetUnpackSize();
extractCallback->SetTotal(totalSize); extractCallback->SetTotal(totalSize);
UInt64 totalPackSize; UInt64 totalPackSize;
@@ -282,7 +317,8 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
item = &_items[index]; item = &_items[index];
RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
totalSize += item->Size; UInt64 unpackSize = item->GetUnpackSize();
totalSize += unpackSize;
totalPackSize += item->GetPackSize(); totalPackSize += item->GetPackSize();
if (item->IsDir()) if (item->IsDir())
{ {
@@ -302,14 +338,21 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
outStreamSpec->SetStream(realOutStream); outStreamSpec->SetStream(realOutStream);
realOutStream.Release(); realOutStream.Release();
outStreamSpec->Init(skipMode ? 0 : item->Size, true); outStreamSpec->Init(skipMode ? 0 : unpackSize, true);
if (!seqMode) if (item->IsLink())
{ {
RINOK(_stream->Seek(item->GetDataPosition(), STREAM_SEEK_SET, NULL)); RINOK(WriteStream(outStreamSpec, (const char *)item->LinkName, item->LinkName.Length()));
}
else
{
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) if (seqMode)
{ {
_latestIsRead = false; _latestIsRead = false;
@@ -328,6 +371,14 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
const CItemEx &item = _items[index]; 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); return CreateLimitedInStream(_stream, item.GetDataPosition(), item.Size, stream);
COM_TRY_END COM_TRY_END
} }
+3 -1
View File
@@ -23,18 +23,20 @@ class CHandler:
CObjectVector<CItemEx> _items; CObjectVector<CItemEx> _items;
CMyComPtr<IInStream> _stream; CMyComPtr<IInStream> _stream;
CMyComPtr<ISequentialInStream> _seqStream; CMyComPtr<ISequentialInStream> _seqStream;
bool _isGood;
UInt32 _curIndex; UInt32 _curIndex;
bool _latestIsRead; bool _latestIsRead;
CItemEx _latestItem; CItemEx _latestItem;
UInt64 _phySize; UInt64 _phySize;
UInt64 _headersSize;
bool _phySizeDefined; bool _phySizeDefined;
AString _errorMessage;
NCompress::CCopyCoder *copyCoderSpec; NCompress::CCopyCoder *copyCoderSpec;
CMyComPtr<ICompressCoder> copyCoder; CMyComPtr<ICompressCoder> copyCoder;
HRESULT ReadItem2(ISequentialInStream *stream, bool &filled, CItemEx &itemInfo);
HRESULT Open2(IInStream *stream, IArchiveOpenCallback *callback); HRESULT Open2(IInStream *stream, IArchiveOpenCallback *callback);
HRESULT SkipTo(UInt32 index); HRESULT SkipTo(UInt32 index);
+1 -1
View File
@@ -37,7 +37,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
IArchiveUpdateCallback *callback) IArchiveUpdateCallback *callback)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
if ((_stream && !_isGood) || _seqStream) if ((_stream && !_errorMessage.IsEmpty()) || _seqStream)
return E_NOTIMPL; return E_NOTIMPL;
CObjectVector<CUpdateItem> updateItems; CObjectVector<CUpdateItem> updateItems;
for (UInt32 i = 0; i < numItems; i++) for (UInt32 i = 0; i < numItems; i++)
+58 -52
View File
@@ -63,29 +63,40 @@ static void ReadString(const char *s, int size, AString &result)
result = temp; 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 buf[NFileHeader::kRecordSize];
char *p = buf; char *p = buf;
error.Empty();
filled = false; filled = false;
bool thereAreEmptyRecords = false; bool thereAreEmptyRecords = false;
for (;;) for (;;)
{ {
processedSize = NFileHeader::kRecordSize; size_t processedSize = NFileHeader::kRecordSize;
RINOK(ReadStream(stream, buf, &processedSize)); RINOK(ReadStream(stream, buf, &processedSize));
if (processedSize == 0) if (processedSize == 0)
{
if (!thereAreEmptyRecords )
error = "There are no trailing zero-filled records";
return S_OK; return S_OK;
}
if (processedSize != NFileHeader::kRecordSize) 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)) if (!IsRecordLast(buf))
break; break;
thereAreEmptyRecords = true; thereAreEmptyRecords = true;
} }
if (thereAreEmptyRecords) 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; ReadString(p, NFileHeader::kNameSize, item.Name); p += NFileHeader::kNameSize;
@@ -143,59 +154,54 @@ static HRESULT GetNextItemReal(ISequentialInStream *stream, bool &filled, CItemE
return S_OK; return S_OK;
} }
HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &item) HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &item, AString &error)
{ {
size_t processedSize; item.HeaderSize = 0;
RINOK(GetNextItemReal(stream, filled, item, processedSize)); bool flagL = false;
if (!filled) bool flagK = false;
return S_OK; AString nameL;
// GNUtar extension AString nameK;
if (item.LinkFlag == 'L' || // NEXT file has a long name for (;;)
item.LinkFlag == 'K') // NEXT file has a long linkname
{ {
if (item.Name.Compare(NFileHeader::kLongLink) != 0) RINOK(GetNextItemReal(stream, filled, item, error));
if (item.Name.Compare(NFileHeader::kLongLink2) != 0) 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; return S_FALSE;
if (item.Size > (1 << 14))
AString fullName; return S_FALSE;
if (item.Size > (1 << 15)) 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')
{
// pax Extended Header
}
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; return S_FALSE;
int packSize = (int)item.GetPackSize(); if (flagL) item.Name = nameL;
char *buffer = fullName.GetBuffer(packSize + 1); if (flagK) item.LinkName = nameK;
RINOK(ReadStream_FALSE(stream, buffer, packSize));
processedSize += packSize;
buffer[item.Size] = '\0';
fullName.ReleaseBuffer();
UInt64 headerPosition = item.HeaderPosition;
if (item.LinkFlag == 'L')
{
size_t processedSize2;
RINOK(GetNextItemReal(stream, filled, item, processedSize2));
item.LongLinkSize = (unsigned)processedSize;
}
else
{
item.LongLinkSize = (unsigned)processedSize - NFileHeader::kRecordSize;
item.Size = 0;
}
item.Name = fullName;
item.HeaderPosition = headerPosition;
}
else if (item.LinkFlag == 'g' || item.LinkFlag == 'x' || item.LinkFlag == 'X')
{
// pax Extended Header
return S_OK; return S_OK;
} }
else if (item.LinkFlag == NFileHeader::NLinkFlag::kDumpDir)
{
// GNU Extensions to the Archive Format
return S_OK;
}
else if (item.LinkFlag > '7' || (item.LinkFlag < '0' && item.LinkFlag != 0))
return S_FALSE;
return S_OK;
} }
}} }}
+2 -3
View File
@@ -1,9 +1,8 @@
// Archive/TarIn.h // TarIn.h
#ifndef __ARCHIVE_TAR_IN_H #ifndef __ARCHIVE_TAR_IN_H
#define __ARCHIVE_TAR_IN_H #define __ARCHIVE_TAR_IN_H
#include "Common/MyCom.h"
#include "../../IStream.h" #include "../../IStream.h"
#include "TarItem.h" #include "TarItem.h"
@@ -11,7 +10,7 @@
namespace NArchive { namespace NArchive {
namespace NTar { namespace NTar {
HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &itemInfo); HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &itemInfo, AString &error);
}} }}
+7 -4
View File
@@ -31,6 +31,9 @@ struct CItem
bool DeviceMajorDefined; bool DeviceMajorDefined;
bool DeviceMinorDefined; bool DeviceMinorDefined;
bool IsLink() const { return LinkFlag == NFileHeader::NLinkFlag::kSymbolicLink && (Size == 0); }
UInt64 GetUnpackSize() const { return IsLink() ? LinkName.Length() : Size; }
bool IsDir() const bool IsDir() const
{ {
switch(LinkFlag) switch(LinkFlag)
@@ -58,10 +61,10 @@ struct CItem
struct CItemEx: public CItem struct CItemEx: public CItem
{ {
UInt64 HeaderPosition; UInt64 HeaderPos;
unsigned LongLinkSize; unsigned HeaderSize;
UInt64 GetDataPosition() const { return HeaderPosition + LongLinkSize + NFileHeader::kRecordSize; } UInt64 GetDataPosition() const { return HeaderPos + HeaderSize; }
UInt64 GetFullSize() const { return LongLinkSize + NFileHeader::kRecordSize + Size; } UInt64 GetFullSize() const { return HeaderSize + Size; }
}; };
}} }}
+6 -6
View File
@@ -111,25 +111,25 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
} }
else else
{ {
const CItemEx &existItemInfo = inputItems[ui.IndexInArchive]; const CItemEx &existItem = inputItems[ui.IndexInArchive];
UInt64 size; UInt64 size;
if (ui.NewProps) if (ui.NewProps)
{ {
RINOK(outArchive.WriteHeader(item)); RINOK(outArchive.WriteHeader(item));
RINOK(inStream->Seek(existItemInfo.GetDataPosition(), STREAM_SEEK_SET, NULL)); RINOK(inStream->Seek(existItem.GetDataPosition(), STREAM_SEEK_SET, NULL));
size = existItemInfo.Size; size = existItem.Size;
} }
else else
{ {
RINOK(inStream->Seek(existItemInfo.HeaderPosition, STREAM_SEEK_SET, NULL)); RINOK(inStream->Seek(existItem.HeaderPos, STREAM_SEEK_SET, NULL));
size = existItemInfo.GetFullSize(); size = existItem.GetFullSize();
} }
streamSpec->Init(size); streamSpec->Init(size);
RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress)); RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress));
if (copyCoderSpec->TotalSize != size) if (copyCoderSpec->TotalSize != size)
return E_FAIL; return E_FAIL;
RINOK(outArchive.FillDataResidual(existItemInfo.Size)); RINOK(outArchive.FillDataResidual(existItem.Size));
complexity += size; complexity += size;
} }
} }
+2 -14
View File
@@ -323,25 +323,13 @@ static void AddTagUInt64(AString &s, const char *name, UInt64 value)
AddTag(s, name, temp); 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) static AString TimeToXml(FILETIME &ft)
{ {
AString res; AString res;
char temp[16] = { '0', 'x' }; char temp[16] = { '0', 'x' };
ConvertUInt32ToHex(ft.dwHighDateTime, temp + 2); ConvertUInt32ToHexWithZeros(ft.dwHighDateTime, temp + 2);
AddTag(res, "HIGHPART", temp); AddTag(res, "HIGHPART", temp);
ConvertUInt32ToHex(ft.dwLowDateTime, temp + 2); ConvertUInt32ToHexWithZeros(ft.dwLowDateTime, temp + 2);
AddTag(res, "LOWPART", temp); AddTag(res, "LOWPART", temp);
return res; return res;
} }
+1 -1
View File
@@ -240,7 +240,7 @@ static HRESULT UnpackData(IInStream *inStream, const CResource &resource, bool l
buf.Free(); buf.Free();
buf.SetCapacity(size); buf.SetCapacity(size);
CSequentialOutStreamImp2 *outStreamSpec = new CSequentialOutStreamImp2(); CBufPtrSeqOutStream *outStreamSpec = new CBufPtrSeqOutStream();
CMyComPtr<ISequentialOutStream> outStream = outStreamSpec; CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
outStreamSpec->Init((Byte *)buf, size); outStreamSpec->Init((Byte *)buf, size);
+1 -1
View File
@@ -268,7 +268,7 @@ HRESULT CHandler::Open2(IInStream *stream)
inStreamLimSpec->SetStream(stream); inStreamLimSpec->SetStream(stream);
inStreamLimSpec->Init(packSize); inStreamLimSpec->Init(packSize);
CSequentialOutStreamImp2 *outStreamLimSpec = new CSequentialOutStreamImp2; CBufPtrSeqOutStream *outStreamLimSpec = new CBufPtrSeqOutStream;
CMyComPtr<ISequentialOutStream> outStreamLim(outStreamLimSpec); CMyComPtr<ISequentialOutStream> outStreamLim(outStreamLimSpec);
outStreamLimSpec->Init((Byte *)ss, (size_t)unpackSize); outStreamLimSpec->Init((Byte *)ss, (size_t)unpackSize);
+3 -4
View File
@@ -53,18 +53,17 @@ HRESULT CLzmaEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIAN
EncoderSpec = new NCompress::NLzma::CEncoder; EncoderSpec = new NCompress::NLzma::CEncoder;
Encoder = EncoderSpec; Encoder = EncoderSpec;
} }
CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp; CBufPtrSeqOutStream *outStreamSpec = new CBufPtrSeqOutStream;
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec); CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
outStreamSpec->Init(); outStreamSpec->Init(Header + 4, kLzmaPropsSize);
RINOK(EncoderSpec->SetCoderProperties(propIDs, props, numProps)); RINOK(EncoderSpec->SetCoderProperties(propIDs, props, numProps));
RINOK(EncoderSpec->WriteCoderProperties(outStream)); RINOK(EncoderSpec->WriteCoderProperties(outStream));
if (outStreamSpec->GetSize() != kLzmaPropsSize) if (outStreamSpec->GetPos() != kLzmaPropsSize)
return E_FAIL; return E_FAIL;
Header[0] = MY_VER_MAJOR; Header[0] = MY_VER_MAJOR;
Header[1] = MY_VER_MINOR; Header[1] = MY_VER_MINOR;
Header[2] = kLzmaPropsSize; Header[2] = kLzmaPropsSize;
Header[3] = 0; Header[3] = 0;
memcpy(Header + 4, outStreamSpec->GetBuffer(), kLzmaPropsSize);
return S_OK; return S_OK;
} }
+2
View File
@@ -160,6 +160,7 @@ AR_OBJS = \
$O\ArjHandler.obj \ $O\ArjHandler.obj \
$O\Bz2Handler.obj \ $O\Bz2Handler.obj \
$O\CpioHandler.obj \ $O\CpioHandler.obj \
$O\CramfsHandler.obj \
$O\DebHandler.obj \ $O\DebHandler.obj \
$O\DeflateProps.obj \ $O\DeflateProps.obj \
$O\DmgHandler.obj \ $O\DmgHandler.obj \
@@ -178,6 +179,7 @@ AR_OBJS = \
$O\PpmdHandler.obj \ $O\PpmdHandler.obj \
$O\RpmHandler.obj \ $O\RpmHandler.obj \
$O\SplitHandler.obj \ $O\SplitHandler.obj \
$O\SquashfsHandler.obj \
$O\SwfHandler.obj \ $O\SwfHandler.obj \
$O\VhdHandler.obj \ $O\VhdHandler.obj \
$O\XarHandler.obj \ $O\XarHandler.obj \
+13 -1
View File
@@ -43,7 +43,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 1 # PROP Ignore_Export_Lib 1
# PROP Target_Dir "" # 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 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 BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x419 /d "NDEBUG" # ADD BASE RSC /l 0x419 /d "NDEBUG"
@@ -164,6 +164,10 @@ SOURCE=..\..\Archive\Icons\split.ico
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Archive\Icons\squashfs.ico
# End Source File
# Begin Source File
SOURCE=..\..\Archive\Icons\tar.ico SOURCE=..\..\Archive\Icons\tar.ico
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -2330,6 +2334,10 @@ SOURCE=..\..\Archive\CpioHandler.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Archive\CramfsHandler.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\DebHandler.cpp SOURCE=..\..\Archive\DebHandler.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -2420,6 +2428,10 @@ SOURCE=..\..\Archive\SplitHandler.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Archive\SquashfsHandler.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\SwfHandler.cpp SOURCE=..\..\Archive\SwfHandler.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
+2
View File
@@ -58,6 +58,7 @@ AR_OBJS = \
$O\ArjHandler.obj \ $O\ArjHandler.obj \
$O\Bz2Handler.obj \ $O\Bz2Handler.obj \
$O\CpioHandler.obj \ $O\CpioHandler.obj \
$O\CramfsHandler.obj \
$O\DebHandler.obj \ $O\DebHandler.obj \
$O\DeflateProps.obj \ $O\DeflateProps.obj \
$O\DmgHandler.obj \ $O\DmgHandler.obj \
@@ -77,6 +78,7 @@ AR_OBJS = \
$O\RpmHandler.obj \ $O\RpmHandler.obj \
$O\SplitHandler.obj \ $O\SplitHandler.obj \
$O\SwfHandler.obj \ $O\SwfHandler.obj \
$O\SquashfsHandler.obj \
$O\VhdHandler.obj \ $O\VhdHandler.obj \
$O\XarHandler.obj \ $O\XarHandler.obj \
$O\XzHandler.obj \ $O\XzHandler.obj \
+2 -1
View File
@@ -27,10 +27,11 @@ MY_VERSION_INFO_DLL("7z Standalone Plugin", "7za")
21 ICON "../../Archive/Icons/fat.ico" 21 ICON "../../Archive/Icons/fat.ico"
22 ICON "../../Archive/Icons/ntfs.ico" 22 ICON "../../Archive/Icons/ntfs.ico"
23 ICON "../../Archive/Icons/xz.ico" 23 ICON "../../Archive/Icons/xz.ico"
24 ICON "../../Archive/Icons/squashfs.ico"
STRINGTABLE STRINGTABLE
BEGIN 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 END
+1
View File
@@ -17,6 +17,7 @@ class CLimitedSequentialInStream:
bool _wasFinished; bool _wasFinished;
public: public:
void SetStream(ISequentialInStream *stream) { _stream = stream; } void SetStream(ISequentialInStream *stream) { _stream = stream; }
void ReleaseStream() { _stream.Release(); }
void Init(UInt64 streamSize) void Init(UInt64 streamSize)
{ {
_size = streamSize; _size = streamSize;
+164 -27
View File
@@ -2,20 +2,24 @@
#include "StdAfx.h" #include "StdAfx.h"
#include "../../../C/Alloc.h"
#include "StreamObjects.h" #include "StreamObjects.h"
STDMETHODIMP CBufInStream::Read(void *data, UInt32 size, UInt32 *processedSize) STDMETHODIMP CBufInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{ {
if (processedSize != NULL) if (processedSize)
*processedSize = 0; *processedSize = 0;
if (size == 0)
return S_OK;
if (_pos > _size) if (_pos > _size)
return E_FAIL; return E_FAIL;
size_t rem = _size - (size_t)_pos; size_t rem = _size - (size_t)_pos;
if (size < rem) if (rem > size)
rem = (size_t)size; rem = (size_t)size;
memcpy(data, _data + (size_t)_pos, rem); memcpy(data, _data + (size_t)_pos, rem);
_pos += rem; _pos += rem;
if (processedSize != NULL) if (processedSize)
*processedSize = (UInt32)rem; *processedSize = (UInt32)rem;
return S_OK; return S_OK;
} }
@@ -34,43 +38,75 @@ STDMETHODIMP CBufInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosi
return S_OK; return S_OK;
} }
void CByteDynBuffer::Free()
void CWriteBuffer::Write(const void *data, size_t size)
{ {
size_t newCapacity = _size + size; free(_buf);
_buffer.EnsureCapacity(newCapacity); _buf = 0;
memcpy(_buffer + _size, data, size); _capacity = 0;
_size += size;
} }
STDMETHODIMP CSequentialOutStreamImp::Write(const void *data, UInt32 size, UInt32 *processedSize) bool CByteDynBuffer::EnsureCapacity(size_t cap)
{ {
_writeBuffer.Write(data, (size_t)size); if (cap <= _capacity)
if(processedSize != NULL) 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 CDynBufSeqOutStream::CopyToBuffer(CByteBuffer &dest) const
{
dest.SetCapacity(_size);
memcpy(dest, _buffer, _size);
}
STDMETHODIMP CDynBufSeqOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
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; *processedSize = size;
return S_OK; 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; size_t rem = _size - _pos;
if (size < rem) if (rem > size)
rem = (size_t)size; rem = (size_t)size;
memcpy(_buffer + _pos, data, rem); memcpy(_buffer + _pos, data, rem);
_pos += rem; _pos += rem;
if (processedSize != NULL) if (processedSize)
*processedSize = (UInt32)rem; *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)
{
UInt32 realProcessedSize;
HRESULT result = _stream->Read(data, size, &realProcessedSize);
_size += realProcessedSize;
if (processedSize != 0)
*processedSize = realProcessedSize;
return result;
} }
STDMETHODIMP CSequentialOutStreamSizeCount::Write(const void *data, UInt32 size, UInt32 *processedSize) STDMETHODIMP CSequentialOutStreamSizeCount::Write(const void *data, UInt32 size, UInt32 *processedSize)
@@ -78,7 +114,108 @@ STDMETHODIMP CSequentialOutStreamSizeCount::Write(const void *data, UInt32 size,
UInt32 realProcessedSize; UInt32 realProcessedSize;
HRESULT result = _stream->Write(data, size, &realProcessedSize); HRESULT result = _stream->Write(data, size, &realProcessedSize);
_size += realProcessedSize; _size += realProcessedSize;
if (processedSize != 0) if (processedSize)
*processedSize = realProcessedSize; *processedSize = realProcessedSize;
return result; return result;
} }
static const UInt64 kEmptyTag = (UInt64)(Int64)-1;
void CCachedInStream::Free()
{
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;
}
+48 -40
View File
@@ -3,7 +3,7 @@
#ifndef __STREAM_OBJECTS_H #ifndef __STREAM_OBJECTS_H
#define __STREAM_OBJECTS_H #define __STREAM_OBJECTS_H
#include "../../Common/DynamicBuffer.h" #include "../../Common/Buffer.h"
#include "../../Common/MyCom.h" #include "../../Common/MyCom.h"
#include "../IStream.h" #include "../IStream.h"
@@ -34,39 +34,45 @@ public:
void Init(CReferenceBuf *ref) { Init(ref->Buf, ref->Buf.GetCapacity(), ref); } void Init(CReferenceBuf *ref) { Init(ref->Buf, ref->Buf.GetCapacity(), ref); }
MY_UNKNOWN_IMP1(IInStream) MY_UNKNOWN_IMP1(IInStream)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
}; };
class CWriteBuffer class CByteDynBuffer
{ {
CByteDynamicBuffer _buffer; size_t _capacity;
size_t _size; Byte *_buf;
public: public:
CWriteBuffer(): _size(0) {} CByteDynBuffer(): _capacity(0), _buf(0) {};
void Init() { _size = 0; } // there is no copy constructor. So don't copy this object.
void Write(const void *data, size_t size); ~CByteDynBuffer() { Free(); }
size_t GetSize() const { return _size; } void Free();
const CByteDynamicBuffer& GetBuffer() const { return _buffer; } 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 ISequentialOutStream,
public CMyUnknownImp public CMyUnknownImp
{ {
CWriteBuffer _writeBuffer; CByteDynBuffer _buffer;
size_t _size;
public: public:
void Init() { _writeBuffer.Init(); } CDynBufSeqOutStream(): _size(0) {}
size_t GetSize() const { return _writeBuffer.GetSize(); } void Init() { _size = 0; }
const CByteDynamicBuffer& GetBuffer() const { return _writeBuffer.GetBuffer(); } 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 MY_UNKNOWN_IMP
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
}; };
class CSequentialOutStreamImp2: class CBufPtrSeqOutStream:
public ISequentialOutStream, public ISequentialOutStream,
public CMyUnknownImp public CMyUnknownImp
{ {
@@ -74,40 +80,18 @@ class CSequentialOutStreamImp2:
size_t _size; size_t _size;
size_t _pos; size_t _pos;
public: public:
void Init(Byte *buffer, size_t size) void Init(Byte *buffer, size_t size)
{ {
_buffer = buffer; _buffer = buffer;
_pos = 0; _pos = 0;
_size = size; _size = size;
} }
size_t GetPos() const { return _pos; } size_t GetPos() const { return _pos; }
MY_UNKNOWN_IMP MY_UNKNOWN_IMP
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
}; };
class CSequentialInStreamSizeCount:
public ISequentialInStream,
public CMyUnknownImp
{
CMyComPtr<ISequentialInStream> _stream;
UInt64 _size;
public:
void Init(ISequentialInStream *stream)
{
_stream = stream;
_size = 0;
}
UInt64 GetSize() const { return _size; }
MY_UNKNOWN_IMP
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
};
class CSequentialOutStreamSizeCount: class CSequentialOutStreamSizeCount:
public ISequentialOutStream, public ISequentialOutStream,
public CMyUnknownImp public CMyUnknownImp
@@ -120,8 +104,32 @@ public:
UInt64 GetSize() const { return _size; } UInt64 GetSize() const { return _size; }
MY_UNKNOWN_IMP MY_UNKNOWN_IMP
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
}; };
class CCachedInStream:
public IInStream,
public CMyUnknownImp
{
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:
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);
MY_UNKNOWN_IMP2(ISequentialInStream, IInStream)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
};
#endif #endif
+2
View File
@@ -128,6 +128,8 @@ Handler GUIDs:
0C xz 0C xz
0D ppmd 0D ppmd
D2 SquashFS
D3 CramFS
D4 APM D4 APM
D5 Mslz D5 Mslz
D6 Flv D6 Flv
+4 -4
View File
@@ -1,8 +1,8 @@
#define MY_VER_MAJOR 9 #define MY_VER_MAJOR 9
#define MY_VER_MINOR 17 #define MY_VER_MINOR 18
#define MY_VER_BUILD 0 #define MY_VER_BUILD 0
#define MY_VERSION "9.17 beta" #define MY_VERSION "9.18 beta"
#define MY_7ZIP_VERSION "7-Zip 9.17 beta" #define MY_7ZIP_VERSION "7-Zip 9.18 beta"
#define MY_DATE "2010-10-04" #define MY_DATE "2010-11-02"
#define MY_COPYRIGHT "Copyright (c) 1999-2010 Igor Pavlov" #define MY_COPYRIGHT "Copyright (c) 1999-2010 Igor Pavlov"
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " " MY_DATE #define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " " MY_DATE
+1
View File
@@ -60,6 +60,7 @@ enum
kpidSectorSize, kpidSectorSize,
kpidPosixAttrib, kpidPosixAttrib,
kpidLink, kpidLink,
kpidError,
kpidTotalSize = 0x1100, kpidTotalSize = 0x1100,
kpidFreeSpace, kpidFreeSpace,
+1 -1
View File
@@ -609,7 +609,7 @@ STDMETHODIMP CAgent::GetArcProp(UInt32 level, PROPID propID, PROPVARIANT *value)
CArc &arc = _archiveLink.Arcs[level]; CArc &arc = _archiveLink.Arcs[level];
switch(propID) switch(propID)
{ {
case kpidType: prop = _codecs->Formats[arc.FormatIndex].Name; break; case kpidType: prop = GetTypeOfArc(arc); break;
case kpidPath: prop = arc.Path; break; case kpidPath: prop = arc.Path; break;
default: return arc.Archive->GetArchiveProperty(propID, value); default: return arc.Archive->GetArchiveProperty(propID, value);
} }
+21
View File
@@ -206,6 +206,27 @@ public:
const CArc &GetArc() { return _archiveLink.Arcs.Back(); } const CArc &GetArc() { return _archiveLink.Arcs.Back(); }
IInArchive *GetArchive() { if ( _archiveLink.Arcs.IsEmpty()) return 0; return GetArc().Archive; } IInArchive *GetArchive() { if ( _archiveLink.Arcs.IsEmpty()) return 0; return GetArc().Archive; }
bool CanUpdate() const { return _archiveLink.Arcs.Size() <= 1; } 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 #ifdef NEW_FOLDER_INTERFACE
+9
View File
@@ -228,6 +228,15 @@ HRESULT DecompressArchives(
} }
#endif #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(); CArc &arc = archiveLink.Arcs.Back();
arc.MTimeDefined = (!options.StdInMode && !fi.IsDevice); arc.MTimeDefined = (!options.StdInMode && !fi.IsDevice);
arc.MTime = fi.MTime; arc.MTime = fi.MTime;
@@ -2,6 +2,8 @@
#include "StdAfx.h" #include "StdAfx.h"
#include "../../../../C/Types.h"
#include "Common/Wildcard.h" #include "Common/Wildcard.h"
#include "ExtractingFilePath.h" #include "ExtractingFilePath.h"
+8
View File
@@ -111,6 +111,7 @@ HRESULT CArc::OpenStream(
IArchiveOpenCallback *callback) IArchiveOpenCallback *callback)
{ {
Archive.Release(); Archive.Release();
ErrorMessage.Empty();
const UString fileName = ExtractFileNameFromPath(Path); const UString fileName = ExtractFileNameFromPath(Path);
UString extension; UString extension;
{ {
@@ -298,6 +299,13 @@ HRESULT CArc::OpenStream(
if (result == S_FALSE) if (result == S_FALSE)
continue; continue;
RINOK(result); 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; Archive = archive;
const CArcInfoEx &format = codecs->Formats[FormatIndex]; const CArcInfoEx &format = codecs->Formats[FormatIndex];
+1
View File
@@ -24,6 +24,7 @@ struct CArc
int SubfileIndex; int SubfileIndex;
FILETIME MTime; FILETIME MTime;
bool MTimeDefined; bool MTimeDefined;
UString ErrorMessage;
CArc(): MTimeDefined(false) {} CArc(): MTimeDefined(false) {}
+8 -3
View File
@@ -45,6 +45,7 @@ static const char g_WinAttrib[17] = "RHS8DAdNTsrCOnE_";
16 VIRTUAL 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'-'; #define MY_ATTR_CHAR(a, n, c) ((a )& (1 << (n))) ? c : L'-';
UString ConvertPropertyToString(const PROPVARIANT &prop, PROPID propID, bool full) UString ConvertPropertyToString(const PROPVARIANT &prop, PROPID propID, bool full)
@@ -92,17 +93,21 @@ UString ConvertPropertyToString(const PROPVARIANT &prop, PROPID propID, bool ful
UString res; UString res;
UInt32 a = prop.ulVal; UInt32 a = prop.ulVal;
wchar_t temp[16]; 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) for (int i = 6; i >= 0; i -= 3)
{ {
temp[7 - i] = MY_ATTR_CHAR(a, i + 2, L'r'); temp[7 - i] = MY_ATTR_CHAR(a, i + 2, L'r');
temp[8 - i] = MY_ATTR_CHAR(a, i + 1, L'w'); temp[8 - i] = MY_ATTR_CHAR(a, i + 1, L'w');
temp[9 - i] = MY_ATTR_CHAR(a, i + 0, L'x'); 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; temp[10] = 0;
res = temp; res = temp;
a &= ~0x1FF;
a &= ~0xC000; a &= ~(UInt32)0xFFFF;
if (a != 0) if (a != 0)
{ {
ConvertUInt32ToHex(a, temp); ConvertUInt32ToHex(a, temp);
+4 -1
View File
@@ -29,7 +29,7 @@ struct CPropIdToName
const wchar_t *Name; const wchar_t *Name;
}; };
static CPropIdToName kPropIdToName[] = static const CPropIdToName kPropIdToName[] =
{ {
{ kpidPath, L"Path" }, { kpidPath, L"Path" },
{ kpidName, L"Name" }, { kpidName, L"Name" },
@@ -82,6 +82,7 @@ static CPropIdToName kPropIdToName[] =
{ kpidSectorSize, L"Sector Size" }, { kpidSectorSize, L"Sector Size" },
{ kpidPosixAttrib, L"Mode" }, { kpidPosixAttrib, L"Mode" },
{ kpidLink, L"Link" }, { kpidLink, L"Link" },
{ kpidError, L"Error" },
{ kpidTotalSize, L"Total Size" }, { kpidTotalSize, L"Total Size" },
{ kpidFreeSpace, L"Free Space" }, { kpidFreeSpace, L"Free Space" },
@@ -505,6 +506,8 @@ HRESULT ListArchives(CCodecs *codecs, const CIntVector &formatIndices,
g_StdOut << "--\n"; g_StdOut << "--\n";
PrintPropPair(L"Path", arc.Path); PrintPropPair(L"Path", arc.Path);
PrintPropPair(L"Type", codecs->Formats[arc.FormatIndex].Name); PrintPropPair(L"Type", codecs->Formats[arc.FormatIndex].Name);
if (!arc.ErrorMessage.IsEmpty())
PrintPropPair(L"Error", arc.ErrorMessage);
UInt32 numProps; UInt32 numProps;
IInArchive *archive = arc.Archive; IInArchive *archive = arc.Archive;
if (archive->GetNumberOfArchiveProperties(&numProps) == S_OK) if (archive->GetNumberOfArchiveProperties(&numProps) == S_OK)
+2 -3
View File
@@ -26,7 +26,6 @@
#ifdef EXTERNAL_CODECS #ifdef EXTERNAL_CODECS
#include "../Common/LoadCodecs.h" #include "../Common/LoadCodecs.h"
#endif #endif
#include "../Common/PropIDUtils.h"
#include "BenchCon.h" #include "BenchCon.h"
#include "ExtractCallbackConsole.h" #include "ExtractCallbackConsole.h"
@@ -457,8 +456,8 @@ int Main2(
<< "Compressed: " << stat.PackSize << endl; << "Compressed: " << stat.PackSize << endl;
if (options.CalcCrc) if (options.CalcCrc)
{ {
wchar_t s[16]; char s[16];
ConvertUInt32ToHex(stat.CrcSum, s); ConvertUInt32ToHexWithZeros(stat.CrcSum, s);
stdStream << "CRC: " << s << endl; stdStream << "CRC: " << s << endl;
} }
} }
+2 -2
View File
@@ -53,7 +53,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo # ADD BSC32 /nologo
LINK32=link.exe 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 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 # SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "Far - Win32 Debug" !ELSEIF "$(CFG)" == "Far - Win32 Debug"
@@ -80,7 +80,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo # ADD BSC32 /nologo
LINK32=link.exe 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 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 !ENDIF
+29 -29
View File
@@ -61,7 +61,7 @@ struct PluginPanelItem
char **CustomColumnData; char **CustomColumnData;
int CustomColumnNumber; int CustomColumnNumber;
DWORD_PTR UserData; DWORD_PTR UserData;
DWORD CRC32; DWORD CRC32;
DWORD_PTR Reserved[2]; DWORD_PTR Reserved[2];
}; };
@@ -484,34 +484,34 @@ enum OPERATION_MODES {
/* /*
EXTERN_C_BEGIN EXTERN_C_BEGIN
void WINAPI _export ClosePluginW(HANDLE hPlugin); 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 CompareW(HANDLE hPlugin,const struct PluginPanelItem *Item1,const struct PluginPanelItem *Item2,unsigned int Mode);
int WINAPI _export ConfigureW(int ItemNumber); int WINAPI _export ConfigureW(int ItemNumber);
int WINAPI _export DeleteFilesW(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber,int OpMode); int WINAPI _export DeleteFilesW(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber,int OpMode);
void WINAPI _export ExitFARW(void); void WINAPI _export ExitFARW(void);
void WINAPI _export FreeFindDataW(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber); void WINAPI _export FreeFindDataW(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber);
void WINAPI _export FreeVirtualFindDataW(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 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 GetFindDataW(HANDLE hPlugin,struct PluginPanelItem **pPanelItem,int *pItemsNumber,int OpMode);
int WINAPI _export GetMinFarVersionW(void); int WINAPI _export GetMinFarVersionW(void);
void WINAPI _export GetOpenPluginInfoW(HANDLE hPlugin,struct OpenPluginInfo *Info); void WINAPI _export GetOpenPluginInfoW(HANDLE hPlugin,struct OpenPluginInfo *Info);
void WINAPI _export GetPluginInfoW(struct PluginInfo *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 GetVirtualFindDataW(HANDLE hPlugin,struct PluginPanelItem **pPanelItem,int *pItemsNumber,const wchar_t *Path);
int WINAPI _export MakeDirectoryW(HANDLE hPlugin,const wchar_t **Name,int OpMode); 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 OpenFilePluginW(const wchar_t *Name,const unsigned char *Data,int DataSize,int OpMode);
HANDLE WINAPI _export OpenPluginW(int OpenFrom,INT_PTR Item); HANDLE WINAPI _export OpenPluginW(int OpenFrom,INT_PTR Item);
int WINAPI _export ProcessDialogEventW(int Event,void *Param); int WINAPI _export ProcessDialogEventW(int Event,void *Param);
int WINAPI _export ProcessEditorEventW(int Event,void *Param); int WINAPI _export ProcessEditorEventW(int Event,void *Param);
int WINAPI _export ProcessEditorInputW(const INPUT_RECORD *Rec); int WINAPI _export ProcessEditorInputW(const INPUT_RECORD *Rec);
int WINAPI _export ProcessEventW(HANDLE hPlugin,int Event,void *Param); 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 ProcessHostFileW(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber,int OpMode);
int WINAPI _export ProcessKeyW(HANDLE hPlugin,int Key,unsigned int ControlState); int WINAPI _export ProcessKeyW(HANDLE hPlugin,int Key,unsigned int ControlState);
int WINAPI _export ProcessSynchroEventW(int Event,void *Param); int WINAPI _export ProcessSynchroEventW(int Event,void *Param);
int WINAPI _export ProcessViewerEventW(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 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 SetDirectoryW(HANDLE hPlugin,const wchar_t *Dir,int OpMode);
int WINAPI _export SetFindListW(HANDLE hPlugin,const struct PluginPanelItem *PanelItem,int ItemsNumber); int WINAPI _export SetFindListW(HANDLE hPlugin,const struct PluginPanelItem *PanelItem,int ItemsNumber);
void WINAPI _export SetStartupInfoW(const struct PluginStartupInfo *Info); void WINAPI _export SetStartupInfoW(const struct PluginStartupInfo *Info);
EXTERN_C_END EXTERN_C_END
*/ */
+6 -1
View File
@@ -366,7 +366,8 @@ static HANDLE MyOpenFilePluginW(const wchar_t *name)
// ::OutputDebugStringA("before OpenArchive\n"); // ::OutputDebugStringA("before OpenArchive\n");
archiveHandler = new CAgent; CAgent *agent = new CAgent;
archiveHandler = agent;
CMyComBSTR archiveType; CMyComBSTR archiveType;
HRESULT result = archiveHandler->Open(NULL, HRESULT result = archiveHandler->Open(NULL,
GetUnicodeString(fullName, CP_OEMCP), UString(), &archiveType, openArchiveCallback); GetUnicodeString(fullName, CP_OEMCP), UString(), &archiveType, openArchiveCallback);
@@ -381,6 +382,10 @@ static HANDLE MyOpenFilePluginW(const wchar_t *name)
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
UString errorMessage = agent->GetErrorMessage();
if (!errorMessage.IsEmpty())
PrintErrorMessage("7-Zip", UnicodeStringToMultiByte(errorMessage, CP_OEMCP));
// ::OutputDebugStringA("after OpenArchive\n"); // ::OutputDebugStringA("after OpenArchive\n");
CPlugin *plugin = new CPlugin( CPlugin *plugin = new CPlugin(
+12 -8
View File
@@ -326,7 +326,8 @@ static CPROPIDToName kPROPIDToName[] =
{ kpidSectorSize, NMessageID::kSectorSize }, { kpidSectorSize, NMessageID::kSectorSize },
{ kpidPosixAttrib, NMessageID::kPosixAttrib }, { kpidPosixAttrib, NMessageID::kPosixAttrib },
{ kpidLink, NMessageID::kLink }, { kpidLink, NMessageID::kLink },
{ kpidError, NMessageID::kError },
{ kpidTotalSize, NMessageID::kTotalSize }, { kpidTotalSize, NMessageID::kTotalSize },
{ kpidFreeSpace, NMessageID::kFreeSpace }, { kpidFreeSpace, NMessageID::kFreeSpace },
{ kpidClusterSize, NMessageID::kClusterSize }, { kpidClusterSize, NMessageID::kClusterSize },
@@ -628,17 +629,20 @@ void CPlugin::GetOpenPluginInfo(struct OpenPluginInfo *info)
if (getProps->GetArcNumProps(level, &numProps) == S_OK) if (getProps->GetArcNumProps(level, &numProps) == S_OK)
{ {
InsertSeparator(m_InfoLines, numItems); 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; CMyComBSTR name;
PROPID propID; PROPID propID;
VARTYPE vt; VARTYPE vt;
if (i == -2) switch (i)
propID = kpidPath; {
else if (i == -1) case -3: propID = kpidPath; break;
propID = kpidType; case -2: propID = kpidType; break;
else if (getProps->GetArcPropInfo(level, i, &name, &propID, &vt) != S_OK) case -1: propID = kpidError; break;
continue; default:
if (getProps->GetArcPropInfo(level, i, &name, &propID, &vt) != S_OK)
continue;
}
NCOM::CPropVariant prop; NCOM::CPropVariant prop;
if (getProps->GetArcProp(level, propID, &prop) != S_OK) if (getProps->GetArcProp(level, propID, &prop) != S_OK)
continue; continue;
+41
View File
@@ -9,6 +9,7 @@
#include "Windows/FileDir.h" #include "Windows/FileDir.h"
#include "Windows/FileFind.h" #include "Windows/FileFind.h"
#include "Windows/Process.h" #include "Windows/Process.h"
#include "Windows/PropVariant.h"
#include "Windows/Thread.h" #include "Windows/Thread.h"
#include "../Common/ExtractingFilePath.h" #include "../Common/ExtractingFilePath.h"
@@ -113,6 +114,46 @@ HRESULT CPanel::OpenItemAsArchive(IInStream *inStream,
_flatMode = _flatModeForArc; _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; return S_OK;
} }
+10 -7
View File
@@ -188,17 +188,20 @@ void CPanel::Properties()
if (getProps->GetArcNumProps(level, &numProps) == S_OK) if (getProps->GetArcNumProps(level, &numProps) == S_OK)
{ {
message += kSeparator; message += kSeparator;
for (Int32 i = -2; i < (Int32)numProps; i++) for (Int32 i = -3; i < (Int32)numProps; i++)
{ {
CMyComBSTR name; CMyComBSTR name;
PROPID propID; PROPID propID;
VARTYPE vt; VARTYPE vt;
if (i == -2) switch (i)
propID = kpidPath; {
else if (i == -1) case -3: propID = kpidPath; break;
propID = kpidType; case -2: propID = kpidType; break;
else if (getProps->GetArcPropInfo(level, i, &name, &propID, &vt) != S_OK) case -1: propID = kpidError; break;
continue; default:
if (getProps->GetArcPropInfo(level, i, &name, &propID, &vt) != S_OK)
continue;
}
NCOM::CPropVariant prop; NCOM::CPropVariant prop;
if (getProps->GetArcProp(level, propID, &prop) != S_OK) if (getProps->GetArcProp(level, propID, &prop) != S_OK)
continue; continue;
+10 -8
View File
@@ -61,17 +61,19 @@ int CALLBACK CompareItems2(LPARAM lParam1, LPARAM lParam2, LPARAM lpData)
// PROPID propID = panel->_properties[panel->_sortIndex].ID; // PROPID propID = panel->_properties[panel->_sortIndex].ID;
PROPID propID = panel->_sortID; PROPID propID = panel->_sortID;
NCOM::CPropVariant propVariant1, propVariant2; NCOM::CPropVariant prop1, prop2;
// Name must be first property // Name must be first property
panel->_folder->GetProperty((UINT32)lParam1, propID, &propVariant1); panel->_folder->GetProperty((UINT32)lParam1, propID, &prop1);
panel->_folder->GetProperty((UINT32)lParam2, propID, &propVariant2); panel->_folder->GetProperty((UINT32)lParam2, propID, &prop2);
if (propVariant1.vt != propVariant2.vt) if (prop1.vt != prop2.vt)
return 0; // It means some BUG
if (propVariant1.vt == VT_BSTR)
{ {
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; // return 0;
} }
+2 -1
View File
@@ -2,6 +2,8 @@
#include "StdAfx.h" #include "StdAfx.h"
#include "../../../../C/Types.h"
#include "ProgramLocation.h" #include "ProgramLocation.h"
#include "Windows/DLL.h" #include "Windows/DLL.h"
@@ -20,4 +22,3 @@ bool GetProgramFolderPath(UString &folder)
folder = folder.Left(pos + 1); folder = folder.Left(pos + 1);
return true; return true;
} }
+1
View File
@@ -75,6 +75,7 @@ static CPropertyIDNamePair kPropertyIDNamePairs[] =
{ kpidSectorSize, IDS_PROP_SECTOR_SIZE, 0x02000234 }, { kpidSectorSize, IDS_PROP_SECTOR_SIZE, 0x02000234 },
{ kpidPosixAttrib, IDS_PROP_POSIX_ATTRIB, 0x02000235 }, { kpidPosixAttrib, IDS_PROP_POSIX_ATTRIB, 0x02000235 },
{ kpidLink, IDS_PROP_LINK, 0x02000236 }, { kpidLink, IDS_PROP_LINK, 0x02000236 },
{ kpidError, IDS_PROP_ERROR, 0x02000605 },
{ kpidTotalSize, IDS_PROP_TOTAL_SIZE, 0x03031100 }, { kpidTotalSize, IDS_PROP_TOTAL_SIZE, 0x03031100 },
{ kpidFreeSpace, IDS_PROP_FREE_SPACE, 0x03031101 }, { kpidFreeSpace, IDS_PROP_FREE_SPACE, 0x03031101 },
+1
View File
@@ -56,4 +56,5 @@ BEGIN
IDS_PROP_SECTOR_SIZE "Sector Size" IDS_PROP_SECTOR_SIZE "Sector Size"
IDS_PROP_POSIX_ATTRIB "Mode" IDS_PROP_POSIX_ATTRIB "Mode"
IDS_PROP_LINK "Link" IDS_PROP_LINK "Link"
IDS_PROP_ERROR "Error"
END END
@@ -50,3 +50,4 @@
#define IDS_PROP_SECTOR_SIZE 52 #define IDS_PROP_SECTOR_SIZE 52
#define IDS_PROP_POSIX_ATTRIB 53 #define IDS_PROP_POSIX_ATTRIB 53
#define IDS_PROP_LINK 54 #define IDS_PROP_LINK 54
#define IDS_PROP_ERROR 55
+7 -1
View File
@@ -1038,7 +1038,13 @@ void CCompressDialog::SetDictionary()
if (i == 20 && j > 0) if (i == 20 && j > 0)
continue; continue;
UInt32 dictionary = (1 << i) + (j << (i - 1)); UInt32 dictionary = (1 << i) + (j << (i - 1));
if (dictionary > (1 << 30)) if (dictionary >
#ifdef _WIN64
(1 << 30)
#else
(1 << 29)
#endif
)
continue; continue;
AddDictionarySize(dictionary); AddDictionarySize(dictionary);
UInt64 decomprSize; UInt64 decomprSize;
+6 -3
View File
@@ -1,7 +1,7 @@
// Common/DynamicBuffer.h // Common/DynamicBuffer.h
#ifndef __COMMON_DYNAMICBUFFER_H #ifndef __COMMON_DYNAMIC_BUFFER_H
#define __COMMON_DYNAMICBUFFER_H #define __COMMON_DYNAMIC_BUFFER_H
#include "Buffer.h" #include "Buffer.h"
@@ -17,7 +17,10 @@ template <class T> class CDynamicBuffer: public CBuffer<T>
else else
delta = 4; delta = 4;
delta = MyMax(delta, size); delta = MyMax(delta, size);
SetCapacity(this->_capacity + delta); size_t newCap = this->_capacity + delta;
if (newCap < delta)
newCap = this->_capacity + size;
SetCapacity(newCap);
} }
public: public:
CDynamicBuffer(): CBuffer<T>() {}; CDynamicBuffer(): CBuffer<T>() {};
+11
View File
@@ -64,3 +64,14 @@ void ConvertInt64ToString(Int64 value, wchar_t *s)
} }
ConvertUInt64ToString(value, 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';
}
+2
View File
@@ -14,4 +14,6 @@ void ConvertInt64ToString(Int64 value, wchar_t *s);
void ConvertUInt32ToString(UInt32 value, char *s); void ConvertUInt32ToString(UInt32 value, char *s);
void ConvertUInt32ToString(UInt32 value, wchar_t *s); void ConvertUInt32ToString(UInt32 value, wchar_t *s);
void ConvertUInt32ToHexWithZeros(UInt32 value, char *s);
#endif #endif
-4
View File
@@ -7,10 +7,6 @@
#include "MyVector.h" #include "MyVector.h"
#ifdef _WIN32
#include "MyWindows.h"
#endif
template <class T> template <class T>
inline int MyStringLen(const T *s) inline int MyStringLen(const T *s)
{ {
+16
View File
@@ -78,6 +78,22 @@ public:
operator[](j) = temp; 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 FindInSorted(const T& item) const
{ {
int left = 0, right = Size(); int left = 0, right = Size();
-10
View File
@@ -7,18 +7,8 @@
#include <windows.h> #include <windows.h>
#define CHAR_PATH_SEPARATOR '\\'
#define WCHAR_PATH_SEPARATOR L'\\'
#define STRING_PATH_SEPARATOR "\\"
#define WSTRING_PATH_SEPARATOR L"\\"
#else #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 <stddef.h> // for wchar_t
#include <string.h> #include <string.h>
+2
View File
@@ -2,6 +2,8 @@
#include "StdAfx.h" #include "StdAfx.h"
#include "../../C/Types.h"
#include "Wildcard.h" #include "Wildcard.h"
bool g_CaseSensitive = bool g_CaseSensitive =
+2 -2
View File
@@ -103,7 +103,7 @@ bool IsDialogSizeOK(int xSize, int ySize)
void CDialog::NormalizeSize(bool fullNormalize) void CDialog::NormalizeSize(bool fullNormalize)
{ {
RECT workRect; RECT workRect;
GetWorkAreaRect(&workRect); GetWorkAreaRect(&workRect);
int xSize = RECT_SIZE_X(workRect); int xSize = RECT_SIZE_X(workRect);
int ySize = RECT_SIZE_Y(workRect); int ySize = RECT_SIZE_Y(workRect);
RECT rect; RECT rect;
@@ -135,7 +135,7 @@ void CDialog::NormalizeSize(bool fullNormalize)
void CDialog::NormalizePosition() void CDialog::NormalizePosition()
{ {
RECT workRect, rect; RECT workRect, rect;
GetWorkAreaRect(&workRect); GetWorkAreaRect(&workRect);
GetWindowRect(&rect); GetWindowRect(&rect);
if (rect.bottom > workRect.bottom && rect.top > workRect.top) if (rect.bottom > workRect.bottom && rect.top > workRect.top)
Move(rect.left, workRect.top, RECT_SIZE_X(rect), RECT_SIZE_Y(rect), true); Move(rect.left, workRect.top, RECT_SIZE_X(rect), RECT_SIZE_Y(rect), true);
+2
View File
@@ -3,6 +3,8 @@
#ifndef __WINDOWS_FILENAME_H #ifndef __WINDOWS_FILENAME_H
#define __WINDOWS_FILENAME_H #define __WINDOWS_FILENAME_H
#include "../../C/Types.h"
#include "../Common/MyString.h" #include "../Common/MyString.h"
namespace NWindows { namespace NWindows {
+1 -1
View File
@@ -218,7 +218,7 @@ void CPropVariant::InternalCopy(const PROPVARIANT *pSrc)
int CPropVariant::Compare(const CPropVariant &a) int CPropVariant::Compare(const CPropVariant &a)
{ {
if (vt != a.vt) if (vt != a.vt)
return 0; // it's bug case return MyCompare(vt, a.vt);
switch (vt) switch (vt)
{ {
case VT_EMPTY: return 0; case VT_EMPTY: return 0;
+3 -2
View File
@@ -53,13 +53,14 @@ AString FlagsToString(const CUInt32PCharPair *pairs, unsigned num, UInt32 flags)
for (unsigned i = 0; i < num; i++) for (unsigned i = 0; i < num; i++)
{ {
const CUInt32PCharPair &p = pairs[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()) if (!s.IsEmpty())
s += ' '; s += ' ';
s += p.Name; s += p.Name;
} }
flags &= ~p.Value; flags &= ~flag;
} }
if (flags != 0) if (flags != 0)
{ {
+4 -2
View File
@@ -10,8 +10,8 @@ AppName = "7-Zip"
InstallDir = %CE1%\%AppName% InstallDir = %CE1%\%AppName%
[Strings] [Strings]
AppVer = "9.17" AppVer = "9.18"
AppDate = "2010-10-04" AppDate = "2010-11-02"
[CEDevice] [CEDevice]
; ProcessorType = 2577 ; ARM ; ProcessorType = 2577 ; ARM
@@ -32,6 +32,7 @@ CEShortcuts = Shortcuts
[SourceDisksFiles] [SourceDisksFiles]
7zFM.exe = 1 7zFM.exe = 1
7z.sfx = 1 7z.sfx = 1
7zS2.sfx = 1
ru.txt = 2 ru.txt = 2
[DestinationDirs] [DestinationDirs]
@@ -43,6 +44,7 @@ Shortcuts = ,%CE11%
[CopyFilesSection] [CopyFilesSection]
7zFM.exe 7zFM.exe
7z.sfx 7z.sfx
7zS2.sfx
[CopyFilesSection.Lang] [CopyFilesSection.Lang]
ru.txt ru.txt
+1 -1
View File
@@ -2,7 +2,7 @@
;Defines ;Defines
!define VERSION_MAJOR 9 !define VERSION_MAJOR 9
!define VERSION_MINOR 17 !define VERSION_MINOR 18
!define VERSION_POSTFIX_FULL " beta" !define VERSION_POSTFIX_FULL " beta"
!ifdef WIN64 !ifdef WIN64
!ifdef IA64 !ifdef IA64
+1 -1
View File
@@ -1,7 +1,7 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<?define VerMajor = "9" ?> <?define VerMajor = "9" ?>
<?define VerMinor = "17" ?> <?define VerMinor = "18" ?>
<?define VerBuild = "00" ?> <?define VerBuild = "00" ?>
<?define MmVer = "$(var.VerMajor).$(var.VerMinor)" ?> <?define MmVer = "$(var.VerMajor).$(var.VerMinor)" ?>
<?define MmHex = "0$(var.VerMajor)$(var.VerMinor)" ?> <?define MmHex = "0$(var.VerMajor)$(var.VerMinor)" ?>
+7 -1
View File
@@ -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). Each compression or crypto method in 7z has unique binary value (ID).
@@ -77,7 +77,13 @@ List of defined IDs
06 - Implode 06 - Implode
08 - Deflate 08 - Deflate
09 - Deflate64 09 - Deflate64
10 - Imploding
12 - BZip2 (not used). Use {04 02 02} instead 12 - BZip2 (not used). Use {04 02 02} instead
14 - LZMA
60 - Jpeg
61 - WavPack
62 - PPMd
63 - wzAES
02 - BZip 02 - BZip
02 - BZip2 02 - BZip2
03 - Rar 03 - Rar
+5
View File
@@ -1,6 +1,11 @@
Sources history of the 7-Zip 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 9.17 2010-10-04
------------------------- -------------------------
- IStream.h::IOutStream:: - IStream.h::IOutStream::
+1 -1
View File
@@ -1,4 +1,4 @@
LZMA SDK 9.17 LZMA SDK 9.18
------------- -------------
LZMA SDK provides the documentation, samples, header files, libraries, LZMA SDK provides the documentation, samples, header files, libraries,

Some files were not shown because too many files have changed in this diff Show More