mirror of
https://github.com/Xevion/easy7zip.git
synced 2026-01-31 08:24:11 -06:00
9.18
This commit is contained in:
committed by
Kornel Lesiński
parent
2eb60a0598
commit
c65230d858
@@ -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 */
|
||||||
@@ -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
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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))
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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 = \
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
Executable
+591
@@ -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;
|
||||||
|
}
|
||||||
Executable
+198
@@ -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
|
||||||
Executable
+29
@@ -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>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
Executable
+35
@@ -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)
|
||||||
Executable
+35
@@ -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)
|
||||||
Executable
+6
@@ -0,0 +1,6 @@
|
|||||||
|
#include "../../../CPP/7zip/MyVersionInfo.rc"
|
||||||
|
|
||||||
|
MY_VERSION_INFO_APP("7z Setup SFX small", "7zS2.sfx")
|
||||||
|
|
||||||
|
1 ICON "setup.ico"
|
||||||
|
|
||||||
Executable
BIN
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
@@ -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());
|
||||||
|
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Executable
+644
@@ -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)
|
||||||
|
|
||||||
|
}}
|
||||||
@@ -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[] =
|
||||||
|
|||||||
Executable
BIN
Binary file not shown.
|
After Width: | Height: | Size: 3.6 KiB |
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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(); }
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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[] =
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
Executable
+1959
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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++)
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
|||||||
@@ -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; }
|
||||||
};
|
};
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 \
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 \
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ enum
|
|||||||
kpidSectorSize,
|
kpidSectorSize,
|
||||||
kpidPosixAttrib,
|
kpidPosixAttrib,
|
||||||
kpidLink,
|
kpidLink,
|
||||||
|
kpidError,
|
||||||
|
|
||||||
kpidTotalSize = 0x1100,
|
kpidTotalSize = 0x1100,
|
||||||
kpidFreeSpace,
|
kpidFreeSpace,
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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];
|
||||||
|
|||||||
@@ -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) {}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 },
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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>() {};
|
||||||
|
|||||||
@@ -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';
|
||||||
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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,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 =
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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
Reference in New Issue
Block a user