mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-08 06:06:59 -06:00
9.06 beta
This commit is contained in:
committed by
Kornel Lesiński
parent
829409452d
commit
c99f3ebdd6
201
C/7z.h
Executable file
201
C/7z.h
Executable file
@@ -0,0 +1,201 @@
|
|||||||
|
/* 7z.h -- 7z interface
|
||||||
|
2009-08-17 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __7Z_H
|
||||||
|
#define __7Z_H
|
||||||
|
|
||||||
|
#include "7zBuf.h"
|
||||||
|
|
||||||
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
|
#define k7zStartHeaderSize 0x20
|
||||||
|
#define k7zSignatureSize 6
|
||||||
|
extern Byte k7zSignature[k7zSignatureSize];
|
||||||
|
#define k7zMajorVersion 0
|
||||||
|
|
||||||
|
enum EIdEnum
|
||||||
|
{
|
||||||
|
k7zIdEnd,
|
||||||
|
k7zIdHeader,
|
||||||
|
k7zIdArchiveProperties,
|
||||||
|
k7zIdAdditionalStreamsInfo,
|
||||||
|
k7zIdMainStreamsInfo,
|
||||||
|
k7zIdFilesInfo,
|
||||||
|
k7zIdPackInfo,
|
||||||
|
k7zIdUnpackInfo,
|
||||||
|
k7zIdSubStreamsInfo,
|
||||||
|
k7zIdSize,
|
||||||
|
k7zIdCRC,
|
||||||
|
k7zIdFolder,
|
||||||
|
k7zIdCodersUnpackSize,
|
||||||
|
k7zIdNumUnpackStream,
|
||||||
|
k7zIdEmptyStream,
|
||||||
|
k7zIdEmptyFile,
|
||||||
|
k7zIdAnti,
|
||||||
|
k7zIdName,
|
||||||
|
k7zIdCTime,
|
||||||
|
k7zIdATime,
|
||||||
|
k7zIdMTime,
|
||||||
|
k7zIdWinAttributes,
|
||||||
|
k7zIdComment,
|
||||||
|
k7zIdEncodedHeader,
|
||||||
|
k7zIdStartPos,
|
||||||
|
k7zIdDummy
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
UInt32 NumInStreams;
|
||||||
|
UInt32 NumOutStreams;
|
||||||
|
UInt64 MethodID;
|
||||||
|
CBuf Props;
|
||||||
|
} CSzCoderInfo;
|
||||||
|
|
||||||
|
void SzCoderInfo_Init(CSzCoderInfo *p);
|
||||||
|
void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
UInt32 InIndex;
|
||||||
|
UInt32 OutIndex;
|
||||||
|
} CSzBindPair;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
CSzCoderInfo *Coders;
|
||||||
|
CSzBindPair *BindPairs;
|
||||||
|
UInt32 *PackStreams;
|
||||||
|
UInt64 *UnpackSizes;
|
||||||
|
UInt32 NumCoders;
|
||||||
|
UInt32 NumBindPairs;
|
||||||
|
UInt32 NumPackStreams;
|
||||||
|
int UnpackCRCDefined;
|
||||||
|
UInt32 UnpackCRC;
|
||||||
|
|
||||||
|
UInt32 NumUnpackStreams;
|
||||||
|
} CSzFolder;
|
||||||
|
|
||||||
|
void SzFolder_Init(CSzFolder *p);
|
||||||
|
UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
|
||||||
|
int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex);
|
||||||
|
UInt32 SzFolder_GetNumOutStreams(CSzFolder *p);
|
||||||
|
UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
|
||||||
|
|
||||||
|
SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes,
|
||||||
|
ILookInStream *stream, UInt64 startPos,
|
||||||
|
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
UInt32 Low;
|
||||||
|
UInt32 High;
|
||||||
|
} CNtfsFileTime;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
CNtfsFileTime MTime;
|
||||||
|
UInt64 Size;
|
||||||
|
UInt32 Crc;
|
||||||
|
Byte HasStream;
|
||||||
|
Byte IsDir;
|
||||||
|
Byte IsAnti;
|
||||||
|
Byte CrcDefined;
|
||||||
|
Byte MTimeDefined;
|
||||||
|
} CSzFileItem;
|
||||||
|
|
||||||
|
void SzFile_Init(CSzFileItem *p);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
UInt64 *PackSizes;
|
||||||
|
Byte *PackCRCsDefined;
|
||||||
|
UInt32 *PackCRCs;
|
||||||
|
CSzFolder *Folders;
|
||||||
|
CSzFileItem *Files;
|
||||||
|
UInt32 NumPackStreams;
|
||||||
|
UInt32 NumFolders;
|
||||||
|
UInt32 NumFiles;
|
||||||
|
} CSzAr;
|
||||||
|
|
||||||
|
void SzAr_Init(CSzAr *p);
|
||||||
|
void SzAr_Free(CSzAr *p, ISzAlloc *alloc);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
SzExtract extracts file from archive
|
||||||
|
|
||||||
|
*outBuffer must be 0 before first call for each new archive.
|
||||||
|
|
||||||
|
Extracting cache:
|
||||||
|
If you need to decompress more than one file, you can send
|
||||||
|
these values from previous call:
|
||||||
|
*blockIndex,
|
||||||
|
*outBuffer,
|
||||||
|
*outBufferSize
|
||||||
|
You can consider "*outBuffer" as cache of solid block. If your archive is solid,
|
||||||
|
it will increase decompression speed.
|
||||||
|
|
||||||
|
If you use external function, you can declare these 3 cache variables
|
||||||
|
(blockIndex, outBuffer, outBufferSize) as static in that external function.
|
||||||
|
|
||||||
|
Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
CSzAr db;
|
||||||
|
|
||||||
|
UInt64 startPosAfterHeader;
|
||||||
|
UInt64 dataPos;
|
||||||
|
|
||||||
|
UInt32 *FolderStartPackStreamIndex;
|
||||||
|
UInt64 *PackStreamStartPositions;
|
||||||
|
UInt32 *FolderStartFileIndex;
|
||||||
|
UInt32 *FileIndexToFolderIndexMap;
|
||||||
|
|
||||||
|
size_t *FileNameOffsets; /* in 2-byte steps */
|
||||||
|
CBuf FileNames; /* UTF-16-LE */
|
||||||
|
} CSzArEx;
|
||||||
|
|
||||||
|
void SzArEx_Init(CSzArEx *p);
|
||||||
|
void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc);
|
||||||
|
UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);
|
||||||
|
int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize);
|
||||||
|
|
||||||
|
/*
|
||||||
|
if dest == NULL, the return value specifies the required size of the buffer,
|
||||||
|
in 16-bit characters, including the null-terminating character.
|
||||||
|
if dest != NULL, the return value specifies the number of 16-bit characters that
|
||||||
|
are written to the dest, including the null-terminating character. */
|
||||||
|
|
||||||
|
size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
|
||||||
|
|
||||||
|
SRes SzArEx_Extract(
|
||||||
|
const CSzArEx *db,
|
||||||
|
ILookInStream *inStream,
|
||||||
|
UInt32 fileIndex, /* index of file */
|
||||||
|
UInt32 *blockIndex, /* index of solid block */
|
||||||
|
Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
|
||||||
|
size_t *outBufferSize, /* buffer size for output buffer */
|
||||||
|
size_t *offset, /* offset of stream for required file in *outBuffer */
|
||||||
|
size_t *outSizeProcessed, /* size of file in *outBuffer */
|
||||||
|
ISzAlloc *allocMain,
|
||||||
|
ISzAlloc *allocTemp);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
SzArEx_Open Errors:
|
||||||
|
SZ_ERROR_NO_ARCHIVE
|
||||||
|
SZ_ERROR_ARCHIVE
|
||||||
|
SZ_ERROR_UNSUPPORTED
|
||||||
|
SZ_ERROR_MEM
|
||||||
|
SZ_ERROR_CRC
|
||||||
|
SZ_ERROR_INPUT_EOF
|
||||||
|
SZ_ERROR_FAIL
|
||||||
|
*/
|
||||||
|
|
||||||
|
SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp);
|
||||||
|
|
||||||
|
EXTERN_C_END
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
/* 7zDecode.c -- Decoding from 7z folder
|
/* 7zDec.c -- Decoding from 7z folder
|
||||||
2009-05-03 : Igor Pavlov : Public domain */
|
2009-08-16 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "../../Bcj2.h"
|
#include "7z.h"
|
||||||
#include "../../Bra.h"
|
|
||||||
#include "../../LzmaDec.h"
|
|
||||||
#include "../../Lzma2Dec.h"
|
|
||||||
|
|
||||||
#include "7zDecode.h"
|
#include "Bcj2.h"
|
||||||
|
#include "Bra.h"
|
||||||
|
#include "LzmaDec.h"
|
||||||
|
#include "Lzma2Dec.h"
|
||||||
|
|
||||||
#define k_Copy 0
|
#define k_Copy 0
|
||||||
#define k_LZMA2 0x21
|
#define k_LZMA2 0x21
|
||||||
@@ -137,7 +137,7 @@ static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer
|
|||||||
#define IS_NO_BCJ(c) (c.MethodID != k_BCJ || c.NumInStreams != 1 || c.NumOutStreams != 1)
|
#define IS_NO_BCJ(c) (c.MethodID != k_BCJ || c.NumInStreams != 1 || c.NumOutStreams != 1)
|
||||||
#define IS_NO_BCJ2(c) (c.MethodID != k_BCJ2 || c.NumInStreams != 4 || c.NumOutStreams != 1)
|
#define IS_NO_BCJ2(c) (c.MethodID != k_BCJ2 || c.NumInStreams != 4 || c.NumOutStreams != 1)
|
||||||
|
|
||||||
SRes CheckSupportedFolder(const CSzFolder *f)
|
static SRes CheckSupportedFolder(const CSzFolder *f)
|
||||||
{
|
{
|
||||||
if (f->NumCoders < 1 || f->NumCoders > 4)
|
if (f->NumCoders < 1 || f->NumCoders > 4)
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
@@ -179,7 +179,7 @@ SRes CheckSupportedFolder(const CSzFolder *f)
|
|||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt64 GetSum(const UInt64 *values, UInt32 index)
|
static UInt64 GetSum(const UInt64 *values, UInt32 index)
|
||||||
{
|
{
|
||||||
UInt64 sum = 0;
|
UInt64 sum = 0;
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
@@ -188,7 +188,7 @@ UInt64 GetSum(const UInt64 *values, UInt32 index)
|
|||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes SzDecode2(const UInt64 *packSizes, const CSzFolder *folder,
|
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,
|
||||||
Byte *tempBuf[])
|
Byte *tempBuf[])
|
||||||
@@ -296,13 +296,13 @@ SRes SzDecode2(const UInt64 *packSizes, const CSzFolder *folder,
|
|||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes SzDecode(const UInt64 *packSizes, const CSzFolder *folder,
|
SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes,
|
||||||
ILookInStream *inStream, UInt64 startPos,
|
ILookInStream *inStream, UInt64 startPos,
|
||||||
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
|
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
|
||||||
{
|
{
|
||||||
Byte *tempBuf[3] = { 0, 0, 0};
|
Byte *tempBuf[3] = { 0, 0, 0};
|
||||||
int i;
|
int i;
|
||||||
SRes res = SzDecode2(packSizes, folder, inStream, startPos,
|
SRes res = SzFolder_Decode2(folder, packSizes, inStream, startPos,
|
||||||
outBuffer, (SizeT)outSize, allocMain, tempBuf);
|
outBuffer, (SizeT)outSize, allocMain, tempBuf);
|
||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < 3; i++)
|
||||||
IAlloc_Free(allocMain, tempBuf[i]);
|
IAlloc_Free(allocMain, tempBuf[i]);
|
||||||
16
C/7zFile.c
16
C/7zFile.c
@@ -1,5 +1,5 @@
|
|||||||
/* 7zFile.c -- File IO
|
/* 7zFile.c -- File IO
|
||||||
2008-11-22 : Igor Pavlov : Public domain */
|
2009-08-16 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "7zFile.h"
|
#include "7zFile.h"
|
||||||
|
|
||||||
@@ -52,6 +52,20 @@ static WRes File_Open(CSzFile *p, const char *name, int writeMode)
|
|||||||
WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); }
|
WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); }
|
||||||
WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); }
|
WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); }
|
||||||
|
|
||||||
|
#ifdef USE_WINDOWS_FILE
|
||||||
|
static WRes File_OpenW(CSzFile *p, const WCHAR *name, int writeMode)
|
||||||
|
{
|
||||||
|
p->handle = CreateFileW(name,
|
||||||
|
writeMode ? GENERIC_WRITE : GENERIC_READ,
|
||||||
|
FILE_SHARE_READ, NULL,
|
||||||
|
writeMode ? CREATE_ALWAYS : OPEN_EXISTING,
|
||||||
|
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();
|
||||||
|
}
|
||||||
|
WRes InFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 0); }
|
||||||
|
WRes OutFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 1); }
|
||||||
|
#endif
|
||||||
|
|
||||||
WRes File_Close(CSzFile *p)
|
WRes File_Close(CSzFile *p)
|
||||||
{
|
{
|
||||||
#ifdef USE_WINDOWS_FILE
|
#ifdef USE_WINDOWS_FILE
|
||||||
|
|||||||
15
C/7zFile.h
15
C/7zFile.h
@@ -1,5 +1,5 @@
|
|||||||
/* 7zFile.h -- File IO
|
/* 7zFile.h -- File IO
|
||||||
2009-02-07 : Igor Pavlov : Public domain */
|
2009-08-16 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __7Z_FILE_H
|
#ifndef __7Z_FILE_H
|
||||||
#define __7Z_FILE_H
|
#define __7Z_FILE_H
|
||||||
@@ -16,10 +16,7 @@
|
|||||||
|
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
EXTERN_C_BEGIN
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* ---------- File ---------- */
|
/* ---------- File ---------- */
|
||||||
|
|
||||||
@@ -35,6 +32,10 @@ typedef struct
|
|||||||
void File_Construct(CSzFile *p);
|
void File_Construct(CSzFile *p);
|
||||||
WRes InFile_Open(CSzFile *p, const char *name);
|
WRes InFile_Open(CSzFile *p, const char *name);
|
||||||
WRes OutFile_Open(CSzFile *p, const char *name);
|
WRes OutFile_Open(CSzFile *p, const char *name);
|
||||||
|
#ifdef USE_WINDOWS_FILE
|
||||||
|
WRes InFile_OpenW(CSzFile *p, const WCHAR *name);
|
||||||
|
WRes OutFile_OpenW(CSzFile *p, const WCHAR *name);
|
||||||
|
#endif
|
||||||
WRes File_Close(CSzFile *p);
|
WRes File_Close(CSzFile *p);
|
||||||
|
|
||||||
/* reads max(*size, remain file's size) bytes */
|
/* reads max(*size, remain file's size) bytes */
|
||||||
@@ -75,8 +76,6 @@ typedef struct
|
|||||||
|
|
||||||
void FileOutStream_CreateVTable(CFileOutStream *p);
|
void FileOutStream_CreateVTable(CFileOutStream *p);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
EXTERN_C_END
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,17 +1,134 @@
|
|||||||
/* 7zIn.c -- 7z Input functions
|
/* 7zIn.c -- 7z Input functions
|
||||||
2008-12-31 : Igor Pavlov : Public domain */
|
2009-08-17 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "../../7zCrc.h"
|
#include <string.h>
|
||||||
#include "../../CpuArch.h"
|
|
||||||
|
|
||||||
#include "7zDecode.h"
|
#include "7z.h"
|
||||||
#include "7zIn.h"
|
#include "7zCrc.h"
|
||||||
|
#include "CpuArch.h"
|
||||||
|
|
||||||
|
Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
|
||||||
|
|
||||||
#define RINOM(x) { if ((x) == 0) return SZ_ERROR_MEM; }
|
#define RINOM(x) { if ((x) == 0) return SZ_ERROR_MEM; }
|
||||||
|
|
||||||
#define NUM_FOLDER_CODERS_MAX 32
|
#define NUM_FOLDER_CODERS_MAX 32
|
||||||
#define NUM_CODER_STREAMS_MAX 32
|
#define NUM_CODER_STREAMS_MAX 32
|
||||||
|
|
||||||
|
void SzCoderInfo_Init(CSzCoderInfo *p)
|
||||||
|
{
|
||||||
|
Buf_Init(&p->Props);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
Buf_Free(&p->Props, alloc);
|
||||||
|
SzCoderInfo_Init(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SzFolder_Init(CSzFolder *p)
|
||||||
|
{
|
||||||
|
p->Coders = 0;
|
||||||
|
p->BindPairs = 0;
|
||||||
|
p->PackStreams = 0;
|
||||||
|
p->UnpackSizes = 0;
|
||||||
|
p->NumCoders = 0;
|
||||||
|
p->NumBindPairs = 0;
|
||||||
|
p->NumPackStreams = 0;
|
||||||
|
p->UnpackCRCDefined = 0;
|
||||||
|
p->UnpackCRC = 0;
|
||||||
|
p->NumUnpackStreams = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
UInt32 i;
|
||||||
|
if (p->Coders)
|
||||||
|
for (i = 0; i < p->NumCoders; i++)
|
||||||
|
SzCoderInfo_Free(&p->Coders[i], alloc);
|
||||||
|
IAlloc_Free(alloc, p->Coders);
|
||||||
|
IAlloc_Free(alloc, p->BindPairs);
|
||||||
|
IAlloc_Free(alloc, p->PackStreams);
|
||||||
|
IAlloc_Free(alloc, p->UnpackSizes);
|
||||||
|
SzFolder_Init(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt32 SzFolder_GetNumOutStreams(CSzFolder *p)
|
||||||
|
{
|
||||||
|
UInt32 result = 0;
|
||||||
|
UInt32 i;
|
||||||
|
for (i = 0; i < p->NumCoders; i++)
|
||||||
|
result += p->Coders[i].NumOutStreams;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex)
|
||||||
|
{
|
||||||
|
UInt32 i;
|
||||||
|
for (i = 0; i < p->NumBindPairs; i++)
|
||||||
|
if (p->BindPairs[i].InIndex == inStreamIndex)
|
||||||
|
return i;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int SzFolder_FindBindPairForOutStream(CSzFolder *p, UInt32 outStreamIndex)
|
||||||
|
{
|
||||||
|
UInt32 i;
|
||||||
|
for (i = 0; i < p->NumBindPairs; i++)
|
||||||
|
if (p->BindPairs[i].OutIndex == outStreamIndex)
|
||||||
|
return i;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt64 SzFolder_GetUnpackSize(CSzFolder *p)
|
||||||
|
{
|
||||||
|
int i = (int)SzFolder_GetNumOutStreams(p);
|
||||||
|
if (i == 0)
|
||||||
|
return 0;
|
||||||
|
for (i--; i >= 0; i--)
|
||||||
|
if (SzFolder_FindBindPairForOutStream(p, i) < 0)
|
||||||
|
return p->UnpackSizes[i];
|
||||||
|
/* throw 1; */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SzFile_Init(CSzFileItem *p)
|
||||||
|
{
|
||||||
|
p->HasStream = 1;
|
||||||
|
p->IsDir = 0;
|
||||||
|
p->IsAnti = 0;
|
||||||
|
p->CrcDefined = 0;
|
||||||
|
p->MTimeDefined = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SzAr_Init(CSzAr *p)
|
||||||
|
{
|
||||||
|
p->PackSizes = 0;
|
||||||
|
p->PackCRCsDefined = 0;
|
||||||
|
p->PackCRCs = 0;
|
||||||
|
p->Folders = 0;
|
||||||
|
p->Files = 0;
|
||||||
|
p->NumPackStreams = 0;
|
||||||
|
p->NumFolders = 0;
|
||||||
|
p->NumFiles = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SzAr_Free(CSzAr *p, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
UInt32 i;
|
||||||
|
if (p->Folders)
|
||||||
|
for (i = 0; i < p->NumFolders; i++)
|
||||||
|
SzFolder_Free(&p->Folders[i], alloc);
|
||||||
|
|
||||||
|
IAlloc_Free(alloc, p->PackSizes);
|
||||||
|
IAlloc_Free(alloc, p->PackCRCsDefined);
|
||||||
|
IAlloc_Free(alloc, p->PackCRCs);
|
||||||
|
IAlloc_Free(alloc, p->Folders);
|
||||||
|
IAlloc_Free(alloc, p->Files);
|
||||||
|
SzAr_Init(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SzArEx_Init(CSzArEx *p)
|
void SzArEx_Init(CSzArEx *p)
|
||||||
{
|
{
|
||||||
SzAr_Init(&p->db);
|
SzAr_Init(&p->db);
|
||||||
@@ -19,6 +136,8 @@ void SzArEx_Init(CSzArEx *p)
|
|||||||
p->PackStreamStartPositions = 0;
|
p->PackStreamStartPositions = 0;
|
||||||
p->FolderStartFileIndex = 0;
|
p->FolderStartFileIndex = 0;
|
||||||
p->FileIndexToFolderIndexMap = 0;
|
p->FileIndexToFolderIndexMap = 0;
|
||||||
|
p->FileNameOffsets = 0;
|
||||||
|
Buf_Init(&p->FileNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc)
|
void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc)
|
||||||
@@ -27,6 +146,10 @@ void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc)
|
|||||||
IAlloc_Free(alloc, p->PackStreamStartPositions);
|
IAlloc_Free(alloc, p->PackStreamStartPositions);
|
||||||
IAlloc_Free(alloc, p->FolderStartFileIndex);
|
IAlloc_Free(alloc, p->FolderStartFileIndex);
|
||||||
IAlloc_Free(alloc, p->FileIndexToFolderIndexMap);
|
IAlloc_Free(alloc, p->FileIndexToFolderIndexMap);
|
||||||
|
|
||||||
|
IAlloc_Free(alloc, p->FileNameOffsets);
|
||||||
|
Buf_Free(&p->FileNames, alloc);
|
||||||
|
|
||||||
SzAr_Free(&p->db, alloc);
|
SzAr_Free(&p->db, alloc);
|
||||||
SzArEx_Init(p);
|
SzArEx_Init(p);
|
||||||
}
|
}
|
||||||
@@ -488,11 +611,11 @@ static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc)
|
|||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
|
||||||
folder->NumBindPairs = numBindPairs = numOutStreams - 1;
|
folder->NumBindPairs = numBindPairs = numOutStreams - 1;
|
||||||
MY_ALLOC(CBindPair, folder->BindPairs, (size_t)numBindPairs, alloc);
|
MY_ALLOC(CSzBindPair, folder->BindPairs, (size_t)numBindPairs, alloc);
|
||||||
|
|
||||||
for (i = 0; i < numBindPairs; i++)
|
for (i = 0; i < numBindPairs; i++)
|
||||||
{
|
{
|
||||||
CBindPair *bp = folder->BindPairs + i;
|
CSzBindPair *bp = folder->BindPairs + i;
|
||||||
RINOK(SzReadNumber32(sd, &bp->InIndex));
|
RINOK(SzReadNumber32(sd, &bp->InIndex));
|
||||||
RINOK(SzReadNumber32(sd, &bp->OutIndex));
|
RINOK(SzReadNumber32(sd, &bp->OutIndex));
|
||||||
}
|
}
|
||||||
@@ -780,81 +903,38 @@ static SRes SzReadStreamsInfo(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
|
size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest)
|
||||||
|
{
|
||||||
|
size_t len = p->FileNameOffsets[fileIndex + 1] - p->FileNameOffsets[fileIndex];
|
||||||
|
if (dest != 0)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
const Byte *src = p->FileNames.data + (p->FileNameOffsets[fileIndex] * 2);
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
dest[i] = GetUi16(src + i * 2);
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
static SRes SzReadFileNames(CSzData *sd, UInt32 numFiles, CSzFileItem *files, ISzAlloc *alloc)
|
static SRes SzReadFileNames(const Byte *p, size_t size, UInt32 numFiles, size_t *sizes)
|
||||||
{
|
{
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
|
size_t pos = 0;
|
||||||
for (i = 0; i < numFiles; i++)
|
for (i = 0; i < numFiles; i++)
|
||||||
{
|
{
|
||||||
UInt32 len = 0;
|
sizes[i] = pos;
|
||||||
UInt32 pos = 0;
|
for (;;)
|
||||||
CSzFileItem *file = files + i;
|
|
||||||
while (pos + 2 <= sd->Size)
|
|
||||||
{
|
{
|
||||||
int numAdds;
|
if (pos >= size)
|
||||||
UInt32 value = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8));
|
|
||||||
pos += 2;
|
|
||||||
len++;
|
|
||||||
if (value == 0)
|
|
||||||
break;
|
|
||||||
if (value < 0x80)
|
|
||||||
continue;
|
|
||||||
if (value >= 0xD800 && value < 0xE000)
|
|
||||||
{
|
|
||||||
UInt32 c2;
|
|
||||||
if (value >= 0xDC00)
|
|
||||||
return SZ_ERROR_ARCHIVE;
|
return SZ_ERROR_ARCHIVE;
|
||||||
if (pos + 2 > sd->Size)
|
if (p[pos * 2] == 0 && p[pos * 2 + 1] == 0)
|
||||||
return SZ_ERROR_ARCHIVE;
|
|
||||||
c2 = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8));
|
|
||||||
pos += 2;
|
|
||||||
if (c2 < 0xDC00 || c2 >= 0xE000)
|
|
||||||
return SZ_ERROR_ARCHIVE;
|
|
||||||
value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
|
|
||||||
}
|
|
||||||
for (numAdds = 1; numAdds < 5; numAdds++)
|
|
||||||
if (value < (((UInt32)1) << (numAdds * 5 + 6)))
|
|
||||||
break;
|
break;
|
||||||
len += numAdds;
|
pos++;
|
||||||
}
|
}
|
||||||
|
pos++;
|
||||||
MY_ALLOC(char, file->Name, (size_t)len, alloc);
|
|
||||||
|
|
||||||
len = 0;
|
|
||||||
while (2 <= sd->Size)
|
|
||||||
{
|
|
||||||
int numAdds;
|
|
||||||
UInt32 value = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8));
|
|
||||||
SzSkeepDataSize(sd, 2);
|
|
||||||
if (value < 0x80)
|
|
||||||
{
|
|
||||||
file->Name[len++] = (char)value;
|
|
||||||
if (value == 0)
|
|
||||||
break;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
if (value >= 0xD800 && value < 0xE000)
|
sizes[i] = pos;
|
||||||
{
|
return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE;
|
||||||
UInt32 c2 = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8));
|
|
||||||
SzSkeepDataSize(sd, 2);
|
|
||||||
value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
|
|
||||||
}
|
|
||||||
for (numAdds = 1; numAdds < 5; numAdds++)
|
|
||||||
if (value < (((UInt32)1) << (numAdds * 5 + 6)))
|
|
||||||
break;
|
|
||||||
file->Name[len++] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));
|
|
||||||
do
|
|
||||||
{
|
|
||||||
numAdds--;
|
|
||||||
file->Name[len++] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));
|
|
||||||
}
|
|
||||||
while (numAdds > 0);
|
|
||||||
|
|
||||||
len += numAdds;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return SZ_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes SzReadHeader2(
|
static SRes SzReadHeader2(
|
||||||
@@ -920,7 +1000,8 @@ static SRes SzReadHeader2(
|
|||||||
if (type == k7zIdEnd)
|
if (type == k7zIdEnd)
|
||||||
break;
|
break;
|
||||||
RINOK(SzReadNumber(sd, &size));
|
RINOK(SzReadNumber(sd, &size));
|
||||||
|
if (size > sd->Size)
|
||||||
|
return SZ_ERROR_ARCHIVE;
|
||||||
if ((UInt64)(int)type != type)
|
if ((UInt64)(int)type != type)
|
||||||
{
|
{
|
||||||
RINOK(SzSkeepDataSize(sd, size));
|
RINOK(SzSkeepDataSize(sd, size));
|
||||||
@@ -930,8 +1011,16 @@ static SRes SzReadHeader2(
|
|||||||
{
|
{
|
||||||
case k7zIdName:
|
case k7zIdName:
|
||||||
{
|
{
|
||||||
|
size_t namesSize;
|
||||||
RINOK(SzReadSwitch(sd));
|
RINOK(SzReadSwitch(sd));
|
||||||
RINOK(SzReadFileNames(sd, numFiles, files, allocMain))
|
namesSize = (size_t)size - 1;
|
||||||
|
if ((namesSize & 1) != 0)
|
||||||
|
return SZ_ERROR_ARCHIVE;
|
||||||
|
if (!Buf_Create(&p->FileNames, namesSize, allocMain))
|
||||||
|
return SZ_ERROR_MEM;
|
||||||
|
MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain);
|
||||||
|
memcpy(p->FileNames.data, sd->Data, namesSize);
|
||||||
|
RINOK(SzReadFileNames(sd->Data, namesSize >> 1, numFiles, p->FileNameOffsets))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case k7zIdEmptyStream:
|
case k7zIdEmptyStream:
|
||||||
@@ -988,8 +1077,8 @@ static SRes SzReadHeader2(
|
|||||||
{
|
{
|
||||||
file->IsDir = 0;
|
file->IsDir = 0;
|
||||||
file->Size = (*unpackSizes)[sizeIndex];
|
file->Size = (*unpackSizes)[sizeIndex];
|
||||||
file->FileCRC = (*digests)[sizeIndex];
|
file->Crc = (*digests)[sizeIndex];
|
||||||
file->FileCRCDefined = (Byte)(*digestsDefined)[sizeIndex];
|
file->CrcDefined = (Byte)(*digestsDefined)[sizeIndex];
|
||||||
sizeIndex++;
|
sizeIndex++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1000,7 +1089,8 @@ static SRes SzReadHeader2(
|
|||||||
file->IsDir = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1);
|
file->IsDir = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1);
|
||||||
emptyFileIndex++;
|
emptyFileIndex++;
|
||||||
file->Size = 0;
|
file->Size = 0;
|
||||||
file->FileCRCDefined = 0;
|
file->Crc = 0;
|
||||||
|
file->CrcDefined = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1066,7 +1156,7 @@ static SRes SzReadAndDecodePackedStreams2(
|
|||||||
if (!Buf_Create(outBuffer, (size_t)unpackSize, allocTemp))
|
if (!Buf_Create(outBuffer, (size_t)unpackSize, allocTemp))
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
|
|
||||||
res = SzDecode(p->PackSizes, folder,
|
res = SzFolder_Decode(folder, p->PackSizes,
|
||||||
inStream, dataStartPos,
|
inStream, dataStartPos,
|
||||||
outBuffer->data, (size_t)unpackSize, allocTemp);
|
outBuffer->data, (size_t)unpackSize, allocTemp);
|
||||||
RINOK(res);
|
RINOK(res);
|
||||||
@@ -1202,3 +1292,85 @@ SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAl
|
|||||||
SzArEx_Free(p, allocMain);
|
SzArEx_Free(p, allocMain);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SRes SzArEx_Extract(
|
||||||
|
const CSzArEx *p,
|
||||||
|
ILookInStream *inStream,
|
||||||
|
UInt32 fileIndex,
|
||||||
|
UInt32 *blockIndex,
|
||||||
|
Byte **outBuffer,
|
||||||
|
size_t *outBufferSize,
|
||||||
|
size_t *offset,
|
||||||
|
size_t *outSizeProcessed,
|
||||||
|
ISzAlloc *allocMain,
|
||||||
|
ISzAlloc *allocTemp)
|
||||||
|
{
|
||||||
|
UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex];
|
||||||
|
SRes res = SZ_OK;
|
||||||
|
*offset = 0;
|
||||||
|
*outSizeProcessed = 0;
|
||||||
|
if (folderIndex == (UInt32)-1)
|
||||||
|
{
|
||||||
|
IAlloc_Free(allocMain, *outBuffer);
|
||||||
|
*blockIndex = folderIndex;
|
||||||
|
*outBuffer = 0;
|
||||||
|
*outBufferSize = 0;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*outBuffer == 0 || *blockIndex != folderIndex)
|
||||||
|
{
|
||||||
|
CSzFolder *folder = p->db.Folders + folderIndex;
|
||||||
|
UInt64 unpackSizeSpec = SzFolder_GetUnpackSize(folder);
|
||||||
|
size_t unpackSize = (size_t)unpackSizeSpec;
|
||||||
|
UInt64 startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0);
|
||||||
|
|
||||||
|
if (unpackSize != unpackSizeSpec)
|
||||||
|
return SZ_ERROR_MEM;
|
||||||
|
*blockIndex = folderIndex;
|
||||||
|
IAlloc_Free(allocMain, *outBuffer);
|
||||||
|
*outBuffer = 0;
|
||||||
|
|
||||||
|
RINOK(LookInStream_SeekTo(inStream, startOffset));
|
||||||
|
|
||||||
|
if (res == SZ_OK)
|
||||||
|
{
|
||||||
|
*outBufferSize = unpackSize;
|
||||||
|
if (unpackSize != 0)
|
||||||
|
{
|
||||||
|
*outBuffer = (Byte *)IAlloc_Alloc(allocMain, unpackSize);
|
||||||
|
if (*outBuffer == 0)
|
||||||
|
res = SZ_ERROR_MEM;
|
||||||
|
}
|
||||||
|
if (res == SZ_OK)
|
||||||
|
{
|
||||||
|
res = SzFolder_Decode(folder,
|
||||||
|
p->db.PackSizes + p->FolderStartPackStreamIndex[folderIndex],
|
||||||
|
inStream, startOffset,
|
||||||
|
*outBuffer, unpackSize, allocTemp);
|
||||||
|
if (res == SZ_OK)
|
||||||
|
{
|
||||||
|
if (folder->UnpackCRCDefined)
|
||||||
|
{
|
||||||
|
if (CrcCalc(*outBuffer, unpackSize) != folder->UnpackCRC)
|
||||||
|
res = SZ_ERROR_CRC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (res == SZ_OK)
|
||||||
|
{
|
||||||
|
UInt32 i;
|
||||||
|
CSzFileItem *fileItem = p->db.Files + fileIndex;
|
||||||
|
*offset = 0;
|
||||||
|
for (i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
|
||||||
|
*offset += (UInt32)p->db.Files[i].Size;
|
||||||
|
*outSizeProcessed = (size_t)fileItem->Size;
|
||||||
|
if (*offset + *outSizeProcessed > *outBufferSize)
|
||||||
|
return SZ_ERROR_FAIL;
|
||||||
|
if (fileItem->CrcDefined && CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->Crc)
|
||||||
|
res = SZ_ERROR_CRC;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#define MY_VER_MAJOR 9
|
#define MY_VER_MAJOR 9
|
||||||
#define MY_VER_MINOR 04
|
#define MY_VER_MINOR 06
|
||||||
#define MY_VER_BUILD 0
|
#define MY_VER_BUILD 0
|
||||||
#define MY_VERSION "9.04 beta"
|
#define MY_VERSION "9.06 beta"
|
||||||
#define MY_DATE "2009-05-30"
|
#define MY_DATE "2009-08-17"
|
||||||
#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
C/Aes.c
8
C/Aes.c
@@ -1,7 +1,5 @@
|
|||||||
/* Aes.c -- AES encryption / decryption
|
/* Aes.c -- AES encryption / decryption
|
||||||
2008-08-05
|
2009-06-10 : Igor Pavlov : Public domain */
|
||||||
Igor Pavlov
|
|
||||||
Public domain */
|
|
||||||
|
|
||||||
#include "Aes.h"
|
#include "Aes.h"
|
||||||
#include "CpuArch.h"
|
#include "CpuArch.h"
|
||||||
@@ -49,7 +47,7 @@ void AesGenTables(void)
|
|||||||
{
|
{
|
||||||
UInt32 a1 = Sbox[i];
|
UInt32 a1 = Sbox[i];
|
||||||
UInt32 a2 = xtime(a1);
|
UInt32 a2 = xtime(a1);
|
||||||
UInt32 a3 = xtime(a1) ^ a1;
|
UInt32 a3 = a2 ^ a1;
|
||||||
T[ i] = Ui32(a2, a1, a1, a3);
|
T[ i] = Ui32(a2, a1, a1, a3);
|
||||||
T[0x100 + i] = Ui32(a3, a2, a1, a1);
|
T[0x100 + i] = Ui32(a3, a2, a1, a1);
|
||||||
T[0x200 + i] = Ui32(a1, a3, a2, a1);
|
T[0x200 + i] = Ui32(a1, a3, a2, a1);
|
||||||
@@ -115,7 +113,7 @@ void Aes_SetKeyEncode(CAes *p, const Byte *key, unsigned keySize)
|
|||||||
w = p->rkey;
|
w = p->rkey;
|
||||||
|
|
||||||
for (i = 0; i < keySize; i++, key += 4)
|
for (i = 0; i < keySize; i++, key += 4)
|
||||||
w[i] = Ui32(key[0], key[1], key[2], key[3]);
|
w[i] = GetUi32(key);
|
||||||
|
|
||||||
for (; i < wSize; i++)
|
for (; i < wSize; i++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
/* 7zDecode.h -- Decoding from 7z folder
|
|
||||||
2009-02-07 : Igor Pavlov : Public domain */
|
|
||||||
|
|
||||||
#ifndef __7Z_DECODE_H
|
|
||||||
#define __7Z_DECODE_H
|
|
||||||
|
|
||||||
#include "7zItem.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SRes SzDecode(const UInt64 *packSizes, const CSzFolder *folder,
|
|
||||||
ILookInStream *stream, UInt64 startPos,
|
|
||||||
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
/* 7zExtract.c -- Extracting from 7z archive
|
|
||||||
2008-11-23 : Igor Pavlov : Public domain */
|
|
||||||
|
|
||||||
#include "../../7zCrc.h"
|
|
||||||
#include "7zDecode.h"
|
|
||||||
#include "7zExtract.h"
|
|
||||||
|
|
||||||
SRes SzAr_Extract(
|
|
||||||
const CSzArEx *p,
|
|
||||||
ILookInStream *inStream,
|
|
||||||
UInt32 fileIndex,
|
|
||||||
UInt32 *blockIndex,
|
|
||||||
Byte **outBuffer,
|
|
||||||
size_t *outBufferSize,
|
|
||||||
size_t *offset,
|
|
||||||
size_t *outSizeProcessed,
|
|
||||||
ISzAlloc *allocMain,
|
|
||||||
ISzAlloc *allocTemp)
|
|
||||||
{
|
|
||||||
UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex];
|
|
||||||
SRes res = SZ_OK;
|
|
||||||
*offset = 0;
|
|
||||||
*outSizeProcessed = 0;
|
|
||||||
if (folderIndex == (UInt32)-1)
|
|
||||||
{
|
|
||||||
IAlloc_Free(allocMain, *outBuffer);
|
|
||||||
*blockIndex = folderIndex;
|
|
||||||
*outBuffer = 0;
|
|
||||||
*outBufferSize = 0;
|
|
||||||
return SZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*outBuffer == 0 || *blockIndex != folderIndex)
|
|
||||||
{
|
|
||||||
CSzFolder *folder = p->db.Folders + folderIndex;
|
|
||||||
UInt64 unpackSizeSpec = SzFolder_GetUnpackSize(folder);
|
|
||||||
size_t unpackSize = (size_t)unpackSizeSpec;
|
|
||||||
UInt64 startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0);
|
|
||||||
|
|
||||||
if (unpackSize != unpackSizeSpec)
|
|
||||||
return SZ_ERROR_MEM;
|
|
||||||
*blockIndex = folderIndex;
|
|
||||||
IAlloc_Free(allocMain, *outBuffer);
|
|
||||||
*outBuffer = 0;
|
|
||||||
|
|
||||||
RINOK(LookInStream_SeekTo(inStream, startOffset));
|
|
||||||
|
|
||||||
if (res == SZ_OK)
|
|
||||||
{
|
|
||||||
*outBufferSize = unpackSize;
|
|
||||||
if (unpackSize != 0)
|
|
||||||
{
|
|
||||||
*outBuffer = (Byte *)IAlloc_Alloc(allocMain, unpackSize);
|
|
||||||
if (*outBuffer == 0)
|
|
||||||
res = SZ_ERROR_MEM;
|
|
||||||
}
|
|
||||||
if (res == SZ_OK)
|
|
||||||
{
|
|
||||||
res = SzDecode(p->db.PackSizes +
|
|
||||||
p->FolderStartPackStreamIndex[folderIndex], folder,
|
|
||||||
inStream, startOffset,
|
|
||||||
*outBuffer, unpackSize, allocTemp);
|
|
||||||
if (res == SZ_OK)
|
|
||||||
{
|
|
||||||
if (folder->UnpackCRCDefined)
|
|
||||||
{
|
|
||||||
if (CrcCalc(*outBuffer, unpackSize) != folder->UnpackCRC)
|
|
||||||
res = SZ_ERROR_CRC;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (res == SZ_OK)
|
|
||||||
{
|
|
||||||
UInt32 i;
|
|
||||||
CSzFileItem *fileItem = p->db.Files + fileIndex;
|
|
||||||
*offset = 0;
|
|
||||||
for (i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
|
|
||||||
*offset += (UInt32)p->db.Files[i].Size;
|
|
||||||
*outSizeProcessed = (size_t)fileItem->Size;
|
|
||||||
if (*offset + *outSizeProcessed > *outBufferSize)
|
|
||||||
return SZ_ERROR_FAIL;
|
|
||||||
{
|
|
||||||
if (fileItem->FileCRCDefined)
|
|
||||||
{
|
|
||||||
if (CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->FileCRC)
|
|
||||||
res = SZ_ERROR_CRC;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
/* 7zExtract.h -- Extracting from 7z archive
|
|
||||||
2009-02-07 : Igor Pavlov : Public domain */
|
|
||||||
|
|
||||||
#ifndef __7Z_EXTRACT_H
|
|
||||||
#define __7Z_EXTRACT_H
|
|
||||||
|
|
||||||
#include "7zIn.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
SzExtract extracts file from archive
|
|
||||||
|
|
||||||
*outBuffer must be 0 before first call for each new archive.
|
|
||||||
|
|
||||||
Extracting cache:
|
|
||||||
If you need to decompress more than one file, you can send
|
|
||||||
these values from previous call:
|
|
||||||
*blockIndex,
|
|
||||||
*outBuffer,
|
|
||||||
*outBufferSize
|
|
||||||
You can consider "*outBuffer" as cache of solid block. If your archive is solid,
|
|
||||||
it will increase decompression speed.
|
|
||||||
|
|
||||||
If you use external function, you can declare these 3 cache variables
|
|
||||||
(blockIndex, outBuffer, outBufferSize) as static in that external function.
|
|
||||||
|
|
||||||
Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
|
|
||||||
*/
|
|
||||||
|
|
||||||
SRes SzAr_Extract(
|
|
||||||
const CSzArEx *db,
|
|
||||||
ILookInStream *inStream,
|
|
||||||
UInt32 fileIndex, /* index of file */
|
|
||||||
UInt32 *blockIndex, /* index of solid block */
|
|
||||||
Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
|
|
||||||
size_t *outBufferSize, /* buffer size for output buffer */
|
|
||||||
size_t *offset, /* offset of stream for required file in *outBuffer */
|
|
||||||
size_t *outSizeProcessed, /* size of file in *outBuffer */
|
|
||||||
ISzAlloc *allocMain,
|
|
||||||
ISzAlloc *allocTemp);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
/* 7zHeader.c -- 7z Headers
|
|
||||||
2008-10-04 : Igor Pavlov : Public domain */
|
|
||||||
|
|
||||||
#include "7zHeader.h"
|
|
||||||
|
|
||||||
Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
/* 7zHeader.h -- 7z Headers
|
|
||||||
2009-02-07 : Igor Pavlov : Public domain */
|
|
||||||
|
|
||||||
#ifndef __7Z_HEADER_H
|
|
||||||
#define __7Z_HEADER_H
|
|
||||||
|
|
||||||
#include "../../Types.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define k7zSignatureSize 6
|
|
||||||
extern Byte k7zSignature[k7zSignatureSize];
|
|
||||||
|
|
||||||
#define k7zMajorVersion 0
|
|
||||||
|
|
||||||
#define k7zStartHeaderSize 0x20
|
|
||||||
|
|
||||||
enum EIdEnum
|
|
||||||
{
|
|
||||||
k7zIdEnd,
|
|
||||||
|
|
||||||
k7zIdHeader,
|
|
||||||
|
|
||||||
k7zIdArchiveProperties,
|
|
||||||
|
|
||||||
k7zIdAdditionalStreamsInfo,
|
|
||||||
k7zIdMainStreamsInfo,
|
|
||||||
k7zIdFilesInfo,
|
|
||||||
|
|
||||||
k7zIdPackInfo,
|
|
||||||
k7zIdUnpackInfo,
|
|
||||||
k7zIdSubStreamsInfo,
|
|
||||||
|
|
||||||
k7zIdSize,
|
|
||||||
k7zIdCRC,
|
|
||||||
|
|
||||||
k7zIdFolder,
|
|
||||||
|
|
||||||
k7zIdCodersUnpackSize,
|
|
||||||
k7zIdNumUnpackStream,
|
|
||||||
|
|
||||||
k7zIdEmptyStream,
|
|
||||||
k7zIdEmptyFile,
|
|
||||||
k7zIdAnti,
|
|
||||||
|
|
||||||
k7zIdName,
|
|
||||||
k7zIdCTime,
|
|
||||||
k7zIdATime,
|
|
||||||
k7zIdMTime,
|
|
||||||
k7zIdWinAttributes,
|
|
||||||
k7zIdComment,
|
|
||||||
|
|
||||||
k7zIdEncodedHeader,
|
|
||||||
|
|
||||||
k7zIdStartPos,
|
|
||||||
k7zIdDummy
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
/* 7zIn.h -- 7z Input
|
|
||||||
2009-02-07 : Igor Pavlov : Public domain */
|
|
||||||
|
|
||||||
#ifndef __7Z_IN_H
|
|
||||||
#define __7Z_IN_H
|
|
||||||
|
|
||||||
#include "7zHeader.h"
|
|
||||||
#include "7zItem.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
CSzAr db;
|
|
||||||
|
|
||||||
UInt64 startPosAfterHeader;
|
|
||||||
UInt64 dataPos;
|
|
||||||
|
|
||||||
UInt32 *FolderStartPackStreamIndex;
|
|
||||||
UInt64 *PackStreamStartPositions;
|
|
||||||
UInt32 *FolderStartFileIndex;
|
|
||||||
UInt32 *FileIndexToFolderIndexMap;
|
|
||||||
} CSzArEx;
|
|
||||||
|
|
||||||
void SzArEx_Init(CSzArEx *p);
|
|
||||||
void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc);
|
|
||||||
UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);
|
|
||||||
int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Errors:
|
|
||||||
SZ_ERROR_NO_ARCHIVE
|
|
||||||
SZ_ERROR_ARCHIVE
|
|
||||||
SZ_ERROR_UNSUPPORTED
|
|
||||||
SZ_ERROR_MEM
|
|
||||||
SZ_ERROR_CRC
|
|
||||||
SZ_ERROR_INPUT_EOF
|
|
||||||
SZ_ERROR_FAIL
|
|
||||||
*/
|
|
||||||
|
|
||||||
SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
/* 7zItem.c -- 7z Items
|
|
||||||
2008-10-04 : Igor Pavlov : Public domain */
|
|
||||||
|
|
||||||
#include "7zItem.h"
|
|
||||||
|
|
||||||
void SzCoderInfo_Init(CSzCoderInfo *p)
|
|
||||||
{
|
|
||||||
Buf_Init(&p->Props);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc)
|
|
||||||
{
|
|
||||||
Buf_Free(&p->Props, alloc);
|
|
||||||
SzCoderInfo_Init(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SzFolder_Init(CSzFolder *p)
|
|
||||||
{
|
|
||||||
p->Coders = 0;
|
|
||||||
p->BindPairs = 0;
|
|
||||||
p->PackStreams = 0;
|
|
||||||
p->UnpackSizes = 0;
|
|
||||||
p->NumCoders = 0;
|
|
||||||
p->NumBindPairs = 0;
|
|
||||||
p->NumPackStreams = 0;
|
|
||||||
p->UnpackCRCDefined = 0;
|
|
||||||
p->UnpackCRC = 0;
|
|
||||||
p->NumUnpackStreams = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc)
|
|
||||||
{
|
|
||||||
UInt32 i;
|
|
||||||
if (p->Coders)
|
|
||||||
for (i = 0; i < p->NumCoders; i++)
|
|
||||||
SzCoderInfo_Free(&p->Coders[i], alloc);
|
|
||||||
IAlloc_Free(alloc, p->Coders);
|
|
||||||
IAlloc_Free(alloc, p->BindPairs);
|
|
||||||
IAlloc_Free(alloc, p->PackStreams);
|
|
||||||
IAlloc_Free(alloc, p->UnpackSizes);
|
|
||||||
SzFolder_Init(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt32 SzFolder_GetNumOutStreams(CSzFolder *p)
|
|
||||||
{
|
|
||||||
UInt32 result = 0;
|
|
||||||
UInt32 i;
|
|
||||||
for (i = 0; i < p->NumCoders; i++)
|
|
||||||
result += p->Coders[i].NumOutStreams;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex)
|
|
||||||
{
|
|
||||||
UInt32 i;
|
|
||||||
for (i = 0; i < p->NumBindPairs; i++)
|
|
||||||
if (p->BindPairs[i].InIndex == inStreamIndex)
|
|
||||||
return i;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int SzFolder_FindBindPairForOutStream(CSzFolder *p, UInt32 outStreamIndex)
|
|
||||||
{
|
|
||||||
UInt32 i;
|
|
||||||
for (i = 0; i < p->NumBindPairs; i++)
|
|
||||||
if (p->BindPairs[i].OutIndex == outStreamIndex)
|
|
||||||
return i;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt64 SzFolder_GetUnpackSize(CSzFolder *p)
|
|
||||||
{
|
|
||||||
int i = (int)SzFolder_GetNumOutStreams(p);
|
|
||||||
if (i == 0)
|
|
||||||
return 0;
|
|
||||||
for (i--; i >= 0; i--)
|
|
||||||
if (SzFolder_FindBindPairForOutStream(p, i) < 0)
|
|
||||||
return p->UnpackSizes[i];
|
|
||||||
/* throw 1; */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SzFile_Init(CSzFileItem *p)
|
|
||||||
{
|
|
||||||
p->HasStream = 1;
|
|
||||||
p->IsDir = 0;
|
|
||||||
p->IsAnti = 0;
|
|
||||||
p->FileCRCDefined = 0;
|
|
||||||
p->MTimeDefined = 0;
|
|
||||||
p->Name = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void SzFile_Free(CSzFileItem *p, ISzAlloc *alloc)
|
|
||||||
{
|
|
||||||
IAlloc_Free(alloc, p->Name);
|
|
||||||
SzFile_Init(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SzAr_Init(CSzAr *p)
|
|
||||||
{
|
|
||||||
p->PackSizes = 0;
|
|
||||||
p->PackCRCsDefined = 0;
|
|
||||||
p->PackCRCs = 0;
|
|
||||||
p->Folders = 0;
|
|
||||||
p->Files = 0;
|
|
||||||
p->NumPackStreams = 0;
|
|
||||||
p->NumFolders = 0;
|
|
||||||
p->NumFiles = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SzAr_Free(CSzAr *p, ISzAlloc *alloc)
|
|
||||||
{
|
|
||||||
UInt32 i;
|
|
||||||
if (p->Folders)
|
|
||||||
for (i = 0; i < p->NumFolders; i++)
|
|
||||||
SzFolder_Free(&p->Folders[i], alloc);
|
|
||||||
if (p->Files)
|
|
||||||
for (i = 0; i < p->NumFiles; i++)
|
|
||||||
SzFile_Free(&p->Files[i], alloc);
|
|
||||||
IAlloc_Free(alloc, p->PackSizes);
|
|
||||||
IAlloc_Free(alloc, p->PackCRCsDefined);
|
|
||||||
IAlloc_Free(alloc, p->PackCRCs);
|
|
||||||
IAlloc_Free(alloc, p->Folders);
|
|
||||||
IAlloc_Free(alloc, p->Files);
|
|
||||||
SzAr_Init(p);
|
|
||||||
}
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
/* 7zItem.h -- 7z Items
|
|
||||||
2009-02-07 : Igor Pavlov : Public domain */
|
|
||||||
|
|
||||||
#ifndef __7Z_ITEM_H
|
|
||||||
#define __7Z_ITEM_H
|
|
||||||
|
|
||||||
#include "../../7zBuf.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
UInt32 NumInStreams;
|
|
||||||
UInt32 NumOutStreams;
|
|
||||||
UInt64 MethodID;
|
|
||||||
CBuf Props;
|
|
||||||
} CSzCoderInfo;
|
|
||||||
|
|
||||||
void SzCoderInfo_Init(CSzCoderInfo *p);
|
|
||||||
void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc);
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
UInt32 InIndex;
|
|
||||||
UInt32 OutIndex;
|
|
||||||
} CBindPair;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
CSzCoderInfo *Coders;
|
|
||||||
CBindPair *BindPairs;
|
|
||||||
UInt32 *PackStreams;
|
|
||||||
UInt64 *UnpackSizes;
|
|
||||||
UInt32 NumCoders;
|
|
||||||
UInt32 NumBindPairs;
|
|
||||||
UInt32 NumPackStreams;
|
|
||||||
int UnpackCRCDefined;
|
|
||||||
UInt32 UnpackCRC;
|
|
||||||
|
|
||||||
UInt32 NumUnpackStreams;
|
|
||||||
} CSzFolder;
|
|
||||||
|
|
||||||
void SzFolder_Init(CSzFolder *p);
|
|
||||||
UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
|
|
||||||
int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex);
|
|
||||||
UInt32 SzFolder_GetNumOutStreams(CSzFolder *p);
|
|
||||||
UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
UInt32 Low;
|
|
||||||
UInt32 High;
|
|
||||||
} CNtfsFileTime;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
CNtfsFileTime MTime;
|
|
||||||
UInt64 Size;
|
|
||||||
char *Name;
|
|
||||||
UInt32 FileCRC;
|
|
||||||
|
|
||||||
Byte HasStream;
|
|
||||||
Byte IsDir;
|
|
||||||
Byte IsAnti;
|
|
||||||
Byte FileCRCDefined;
|
|
||||||
Byte MTimeDefined;
|
|
||||||
} CSzFileItem;
|
|
||||||
|
|
||||||
void SzFile_Init(CSzFileItem *p);
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
UInt64 *PackSizes;
|
|
||||||
Byte *PackCRCsDefined;
|
|
||||||
UInt32 *PackCRCs;
|
|
||||||
CSzFolder *Folders;
|
|
||||||
CSzFileItem *Files;
|
|
||||||
UInt32 NumPackStreams;
|
|
||||||
UInt32 NumFolders;
|
|
||||||
UInt32 NumFiles;
|
|
||||||
} CSzAr;
|
|
||||||
|
|
||||||
void SzAr_Init(CSzAr *p);
|
|
||||||
void SzAr_Free(CSzAr *p, ISzAlloc *alloc);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
16
C/CpuArch.h
16
C/CpuArch.h
@@ -1,5 +1,5 @@
|
|||||||
/* CpuArch.h
|
/* CpuArch.h
|
||||||
2009-03-22 : Igor Pavlov : Public domain */
|
2009-08-11 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __CPU_ARCH_H
|
#ifndef __CPU_ARCH_H
|
||||||
#define __CPU_ARCH_H
|
#define __CPU_ARCH_H
|
||||||
@@ -16,7 +16,19 @@ if LITTLE_ENDIAN_UNALIGN is not defined, it means that we don't know
|
|||||||
about these properties of platform.
|
about these properties of platform.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || defined(__i386__) || defined(__x86_64__)
|
#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__)
|
||||||
|
#define MY_CPU_AMD64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MY_CPU_AMD64) || defined(_M_IA64)
|
||||||
|
#define MY_CPU_64BIT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_M_IX86) || defined(__i386__) || defined(MY_CPU_AMD64)
|
||||||
|
#define MY_CPU_X86_OR_AMD64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MY_CPU_X86_OR_AMD64)
|
||||||
#define LITTLE_ENDIAN_UNALIGN
|
#define LITTLE_ENDIAN_UNALIGN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
/* Lzma86Enc.h -- LZMA + x86 (BCJ) Filter Encoder
|
/* Lzma86.h -- LZMA + x86 (BCJ) Filter
|
||||||
2009-02-07 : Igor Pavlov : Public domain */
|
2009-08-14 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __LZMA86_ENC_H
|
#ifndef __LZMA86_H
|
||||||
#define __LZMA86_ENC_H
|
#define __LZMA86_H
|
||||||
|
|
||||||
#include "../Types.h"
|
#include "Types.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
EXTERN_C_BEGIN
|
||||||
extern "C" {
|
|
||||||
#endif
|
#define LZMA86_SIZE_OFFSET (1 + 5)
|
||||||
|
#define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
It's an example for LZMA + x86 Filter use.
|
It's an example for LZMA + x86 Filter use.
|
||||||
@@ -16,8 +17,8 @@ You can use .lzma86 extension, if you write that stream to file.
|
|||||||
.lzma86 header adds one additional byte to standard .lzma header.
|
.lzma86 header adds one additional byte to standard .lzma header.
|
||||||
.lzma86 header (14 bytes):
|
.lzma86 header (14 bytes):
|
||||||
Offset Size Description
|
Offset Size Description
|
||||||
0 1 = 0 - no filter,
|
0 1 = 0 - no filter, pure LZMA
|
||||||
= 1 - x86 filter
|
= 1 - x86 filter + LZMA
|
||||||
1 1 lc, lp and pb in encoded form
|
1 1 lc, lp and pb in encoded form
|
||||||
2 4 dictSize (little endian)
|
2 4 dictSize (little endian)
|
||||||
6 8 uncompressed size (little endian)
|
6 8 uncompressed size (little endian)
|
||||||
@@ -27,7 +28,6 @@ Lzma86_Encode
|
|||||||
-------------
|
-------------
|
||||||
level - compression level: 0 <= level <= 9, the default value for "level" is 5.
|
level - compression level: 0 <= level <= 9, the default value for "level" is 5.
|
||||||
|
|
||||||
|
|
||||||
dictSize - The dictionary size in bytes. The maximum value is
|
dictSize - The dictionary size in bytes. The maximum value is
|
||||||
128 MB = (1 << 27) bytes for 32-bit version
|
128 MB = (1 << 27) bytes for 32-bit version
|
||||||
1 GB = (1 << 30) bytes for 64-bit version
|
1 GB = (1 << 30) bytes for 64-bit version
|
||||||
@@ -71,8 +71,41 @@ enum ESzFilterMode
|
|||||||
SRes Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
|
SRes Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
|
||||||
int level, UInt32 dictSize, int filterMode);
|
int level, UInt32 dictSize, int filterMode);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
/*
|
||||||
#endif
|
Lzma86_GetUnpackSize:
|
||||||
|
In:
|
||||||
|
src - input data
|
||||||
|
srcLen - input data size
|
||||||
|
Out:
|
||||||
|
unpackSize - size of uncompressed stream
|
||||||
|
Return code:
|
||||||
|
SZ_OK - OK
|
||||||
|
SZ_ERROR_INPUT_EOF - Error in headers
|
||||||
|
*/
|
||||||
|
|
||||||
|
SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Lzma86_Decode:
|
||||||
|
In:
|
||||||
|
dest - output data
|
||||||
|
destLen - output data size
|
||||||
|
src - input data
|
||||||
|
srcLen - input data size
|
||||||
|
Out:
|
||||||
|
destLen - processed output size
|
||||||
|
srcLen - processed input size
|
||||||
|
Return code:
|
||||||
|
SZ_OK - OK
|
||||||
|
SZ_ERROR_DATA - Data error
|
||||||
|
SZ_ERROR_MEM - Memory allocation error
|
||||||
|
SZ_ERROR_UNSUPPORTED - unsupported file
|
||||||
|
SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer
|
||||||
|
*/
|
||||||
|
|
||||||
|
SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen);
|
||||||
|
|
||||||
|
EXTERN_C_END
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,20 +1,14 @@
|
|||||||
/* Lzma86Dec.c -- LZMA + x86 (BCJ) Filter Decoder
|
/* Lzma86Dec.c -- LZMA + x86 (BCJ) Filter Decoder
|
||||||
2008-04-07
|
2009-08-14 : Igor Pavlov : Public domain */
|
||||||
Igor Pavlov
|
|
||||||
Public domain */
|
|
||||||
|
|
||||||
#include "Lzma86Dec.h"
|
#include "Lzma86.h"
|
||||||
|
|
||||||
#include "../Alloc.h"
|
#include "Alloc.h"
|
||||||
#include "../Bra.h"
|
#include "Bra.h"
|
||||||
#include "../LzmaDec.h"
|
#include "LzmaDec.h"
|
||||||
|
|
||||||
#define LZMA86_SIZE_OFFSET (1 + LZMA_PROPS_SIZE)
|
|
||||||
#define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8)
|
|
||||||
|
|
||||||
static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
|
static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
|
||||||
static void SzFree(void *p, void *address) { p = p; MyFree(address); }
|
static void SzFree(void *p, void *address) { p = p; MyFree(address); }
|
||||||
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
|
||||||
|
|
||||||
SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize)
|
SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize)
|
||||||
{
|
{
|
||||||
@@ -29,6 +23,7 @@ SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize)
|
|||||||
|
|
||||||
SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen)
|
SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen)
|
||||||
{
|
{
|
||||||
|
ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
||||||
SRes res;
|
SRes res;
|
||||||
int useFilter;
|
int useFilter;
|
||||||
SizeT inSizePure;
|
SizeT inSizePure;
|
||||||
@@ -1,28 +1,23 @@
|
|||||||
/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder
|
/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder
|
||||||
2008-08-05
|
2009-08-14 : Igor Pavlov : Public domain */
|
||||||
Igor Pavlov
|
|
||||||
Public domain */
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "Lzma86Enc.h"
|
#include "Lzma86.h"
|
||||||
|
|
||||||
#include "../Alloc.h"
|
#include "Alloc.h"
|
||||||
#include "../Bra.h"
|
#include "Bra.h"
|
||||||
#include "../LzmaEnc.h"
|
#include "LzmaEnc.h"
|
||||||
|
|
||||||
#define SZE_OUT_OVERFLOW SZE_DATA_ERROR
|
#define SZE_OUT_OVERFLOW SZE_DATA_ERROR
|
||||||
|
|
||||||
static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
|
static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
|
||||||
static void SzFree(void *p, void *address) { p = p; MyFree(address); }
|
static void SzFree(void *p, void *address) { p = p; MyFree(address); }
|
||||||
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
|
||||||
|
|
||||||
#define LZMA86_SIZE_OFFSET (1 + LZMA_PROPS_SIZE)
|
|
||||||
#define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8)
|
|
||||||
|
|
||||||
int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
|
int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
|
||||||
int level, UInt32 dictSize, int filterMode)
|
int level, UInt32 dictSize, int filterMode)
|
||||||
{
|
{
|
||||||
|
ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
||||||
size_t outSize2 = *destLen;
|
size_t outSize2 = *destLen;
|
||||||
Byte *filteredStream;
|
Byte *filteredStream;
|
||||||
Bool useFilter;
|
Bool useFilter;
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
/* Lzma86Dec.h -- LZMA + x86 (BCJ) Filter Decoder
|
|
||||||
2009-02-07 : Igor Pavlov : Public domain */
|
|
||||||
|
|
||||||
#ifndef __LZMA86_DEC_H
|
|
||||||
#define __LZMA86_DEC_H
|
|
||||||
|
|
||||||
#include "../Types.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
Lzma86_GetUnpackSize:
|
|
||||||
In:
|
|
||||||
src - input data
|
|
||||||
srcLen - input data size
|
|
||||||
Out:
|
|
||||||
unpackSize - size of uncompressed stream
|
|
||||||
Return code:
|
|
||||||
SZ_OK - OK
|
|
||||||
SZ_ERROR_INPUT_EOF - Error in headers
|
|
||||||
*/
|
|
||||||
|
|
||||||
SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Lzma86_Decode:
|
|
||||||
In:
|
|
||||||
dest - output data
|
|
||||||
destLen - output data size
|
|
||||||
src - input data
|
|
||||||
srcLen - input data size
|
|
||||||
Out:
|
|
||||||
destLen - processed output size
|
|
||||||
srcLen - processed input size
|
|
||||||
Return code:
|
|
||||||
SZ_OK - OK
|
|
||||||
SZ_ERROR_DATA - Data error
|
|
||||||
SZ_ERROR_MEM - Memory allocation error
|
|
||||||
SZ_ERROR_UNSUPPORTED - unsupported file
|
|
||||||
SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer
|
|
||||||
*/
|
|
||||||
|
|
||||||
SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
PROG = lzma
|
|
||||||
CXX = g++
|
|
||||||
LIB =
|
|
||||||
RM = rm -f
|
|
||||||
CFLAGS = -c -O2 -Wall
|
|
||||||
|
|
||||||
OBJS = \
|
|
||||||
LzmaUtil.o \
|
|
||||||
Alloc.o \
|
|
||||||
LzFind.o \
|
|
||||||
LzmaDec.o \
|
|
||||||
LzmaEnc.o \
|
|
||||||
7zFile.o \
|
|
||||||
7zStream.o \
|
|
||||||
|
|
||||||
|
|
||||||
all: $(PROG)
|
|
||||||
|
|
||||||
$(PROG): $(OBJS)
|
|
||||||
$(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB) $(LIB2)
|
|
||||||
|
|
||||||
LzmaUtil.o: LzmaUtil.c
|
|
||||||
$(CXX) $(CFLAGS) LzmaUtil.c
|
|
||||||
|
|
||||||
Alloc.o: ../Alloc.c
|
|
||||||
$(CXX) $(CFLAGS) ../Alloc.c
|
|
||||||
|
|
||||||
LzFind.o: ../LzFind.c
|
|
||||||
$(CXX) $(CFLAGS) ../LzFind.c
|
|
||||||
|
|
||||||
LzmaDec.o: ../LzmaDec.c
|
|
||||||
$(CXX) $(CFLAGS) ../LzmaDec.c
|
|
||||||
|
|
||||||
LzmaEnc.o: ../LzmaEnc.c
|
|
||||||
$(CXX) $(CFLAGS) ../LzmaEnc.c
|
|
||||||
|
|
||||||
7zFile.o: ../7zFile.c
|
|
||||||
$(CXX) $(CFLAGS) ../7zFile.c
|
|
||||||
|
|
||||||
7zStream.o: ../7zStream.c
|
|
||||||
$(CXX) $(CFLAGS) ../7zStream.c
|
|
||||||
|
|
||||||
clean:
|
|
||||||
-$(RM) $(PROG) $(OBJS)
|
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
/* Threads.c -- multithreading library
|
/* Threads.c -- multithreading library
|
||||||
2009-03-27 : Igor Pavlov : Public domain */
|
2009-07-20 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef _WIN32_WCE
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "Threads.h"
|
#include "Threads.h"
|
||||||
|
|
||||||
@@ -29,8 +31,11 @@ WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param)
|
|||||||
{
|
{
|
||||||
unsigned threadId; /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */
|
unsigned threadId; /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */
|
||||||
*p =
|
*p =
|
||||||
/* CreateThread(0, 0, startAddress, param, 0, &threadId); */
|
#ifdef UNDER_CE
|
||||||
|
CreateThread(0, 0, func, param, 0, &threadId);
|
||||||
|
#else
|
||||||
(HANDLE)_beginthreadex(NULL, 0, func, param, 0, &threadId);
|
(HANDLE)_beginthreadex(NULL, 0, func, param, 0, &threadId);
|
||||||
|
#endif
|
||||||
/* maybe we must use errno here, but probably GetLastError() is also OK. */
|
/* maybe we must use errno here, but probably GetLastError() is also OK. */
|
||||||
return HandleToWRes(*p);
|
return HandleToWRes(*p);
|
||||||
}
|
}
|
||||||
|
|||||||
16
C/Types.h
16
C/Types.h
@@ -1,5 +1,5 @@
|
|||||||
/* Types.h -- Basic types
|
/* Types.h -- Basic types
|
||||||
2009-02-07 : Igor Pavlov : Public domain */
|
2009-08-14 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __7Z_TYPES_H
|
#ifndef __7Z_TYPES_H
|
||||||
#define __7Z_TYPES_H
|
#define __7Z_TYPES_H
|
||||||
@@ -10,9 +10,17 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef EXTERN_C_BEGIN
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
#define EXTERN_C_BEGIN extern "C" {
|
||||||
|
#define EXTERN_C_END }
|
||||||
|
#else
|
||||||
|
#define EXTERN_C_BEGIN
|
||||||
|
#define EXTERN_C_END
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
#define SZ_OK 0
|
#define SZ_OK 0
|
||||||
|
|
||||||
@@ -209,8 +217,6 @@ 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 __cplusplus
|
EXTERN_C_END
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ RSC=rc.exe
|
|||||||
# PROP Ignore_Export_Lib 0
|
# PROP Ignore_Export_Lib 0
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||||
# ADD CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FAs /YX /FD /c
|
# ADD CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /FAs /YX /FD /c
|
||||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||||
# ADD RSC /l 0x419 /d "NDEBUG"
|
# ADD RSC /l 0x419 /d "NDEBUG"
|
||||||
BSC32=bscmake.exe
|
BSC32=bscmake.exe
|
||||||
@@ -67,7 +67,7 @@ LINK32=link.exe
|
|||||||
# PROP Ignore_Export_Lib 0
|
# PROP Ignore_Export_Lib 0
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||||
# ADD CPP /nologo /W4 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_SZ_ALLOC_DEBUG2" /D "_SZ_NO_INT_64_A" /YX /FD /GZ /c
|
# ADD CPP /nologo /W4 /Gm /GX /ZI /Od /D "_DEBUG" /D "_SZ_ALLOC_DEBUG2" /D "_SZ_NO_INT_64_A" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /YX /FD /GZ /c
|
||||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||||
# ADD RSC /l 0x419 /d "_DEBUG"
|
# ADD RSC /l 0x419 /d "_DEBUG"
|
||||||
BSC32=bscmake.exe
|
BSC32=bscmake.exe
|
||||||
@@ -132,6 +132,10 @@ SOURCE=..\..\Bra86.c
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\CpuArch.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\..\Lzma2Dec.c
|
SOURCE=..\..\Lzma2Dec.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
@@ -153,6 +157,10 @@ SOURCE=..\..\Types.h
|
|||||||
# End Group
|
# End Group
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\7z.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\7zAlloc.c
|
SOURCE=.\7zAlloc.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
@@ -161,43 +169,11 @@ SOURCE=.\7zAlloc.h
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\7zDecode.c
|
SOURCE=..\..\7zDec.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\7zDecode.h
|
SOURCE=..\..\7zIn.c
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\7zExtract.c
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\7zExtract.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\7zHeader.c
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\7zHeader.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\7zIn.c
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\7zIn.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\7zItem.c
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\7zItem.h
|
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
@@ -1,17 +1,16 @@
|
|||||||
/* 7zMain.c - Test application for 7z Decoder
|
/* 7zMain.c - Test application for 7z Decoder
|
||||||
2009-04-04 : Igor Pavlov : Public domain */
|
2009-08-17 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "../../7z.h"
|
||||||
#include "../../7zCrc.h"
|
#include "../../7zCrc.h"
|
||||||
#include "../../7zFile.h"
|
#include "../../7zFile.h"
|
||||||
#include "../../7zVersion.h"
|
#include "../../7zVersion.h"
|
||||||
|
|
||||||
#include "7zAlloc.h"
|
#include "7zAlloc.h"
|
||||||
#include "7zExtract.h"
|
|
||||||
#include "7zIn.h"
|
|
||||||
|
|
||||||
#ifndef USE_WINDOWS_FILE
|
#ifndef USE_WINDOWS_FILE
|
||||||
/* for mkdir */
|
/* for mkdir */
|
||||||
@@ -29,20 +28,162 @@
|
|||||||
#define CHAR_PATH_SEPARATOR '/'
|
#define CHAR_PATH_SEPARATOR '/'
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static WRes MyCreateDir(const char *name)
|
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
||||||
|
|
||||||
|
static int Buf_EnsureSize(CBuf *dest, size_t size)
|
||||||
|
{
|
||||||
|
if (dest->size >= size)
|
||||||
|
return 1;
|
||||||
|
Buf_Free(dest, &g_Alloc);
|
||||||
|
return Buf_Create(dest, size, &g_Alloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
|
||||||
|
static Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
|
||||||
|
|
||||||
|
static Bool Utf16_To_Utf8(Byte *dest, size_t *destLen, const UInt16 *src, size_t srcLen)
|
||||||
|
{
|
||||||
|
size_t destPos = 0, srcPos = 0;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
unsigned numAdds;
|
||||||
|
UInt32 value;
|
||||||
|
if (srcPos == srcLen)
|
||||||
|
{
|
||||||
|
*destLen = destPos;
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
value = src[srcPos++];
|
||||||
|
if (value < 0x80)
|
||||||
|
{
|
||||||
|
if (dest)
|
||||||
|
dest[destPos] = (char)value;
|
||||||
|
destPos++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (value >= 0xD800 && value < 0xE000)
|
||||||
|
{
|
||||||
|
UInt32 c2;
|
||||||
|
if (value >= 0xDC00 || srcPos == srcLen)
|
||||||
|
break;
|
||||||
|
c2 = src[srcPos++];
|
||||||
|
if (c2 < 0xDC00 || c2 >= 0xE000)
|
||||||
|
break;
|
||||||
|
value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
|
||||||
|
}
|
||||||
|
for (numAdds = 1; numAdds < 5; numAdds++)
|
||||||
|
if (value < (((UInt32)1) << (numAdds * 5 + 6)))
|
||||||
|
break;
|
||||||
|
if (dest)
|
||||||
|
dest[destPos] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));
|
||||||
|
destPos++;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
numAdds--;
|
||||||
|
if (dest)
|
||||||
|
dest[destPos] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));
|
||||||
|
destPos++;
|
||||||
|
}
|
||||||
|
while (numAdds != 0);
|
||||||
|
}
|
||||||
|
*destLen = destPos;
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRes Utf16_To_Utf8Buf(CBuf *dest, const UInt16 *src, size_t srcLen)
|
||||||
|
{
|
||||||
|
size_t destLen = 0;
|
||||||
|
Bool res;
|
||||||
|
Utf16_To_Utf8(NULL, &destLen, src, srcLen);
|
||||||
|
destLen += 1;
|
||||||
|
if (!Buf_EnsureSize(dest, destLen))
|
||||||
|
return SZ_ERROR_MEM;
|
||||||
|
res = Utf16_To_Utf8(dest->data, &destLen, src, srcLen);
|
||||||
|
dest->data[destLen] = 0;
|
||||||
|
return res ? SZ_OK : SZ_ERROR_FAIL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static WRes Utf16_To_Char(CBuf *buf, const UInt16 *s, int fileMode)
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
for (len = 0; s[len] != '\0'; len++);
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
{
|
||||||
|
int size = len * 3 + 100;
|
||||||
|
if (!Buf_EnsureSize(buf, size))
|
||||||
|
return SZ_ERROR_MEM;
|
||||||
|
{
|
||||||
|
char defaultChar = '_';
|
||||||
|
BOOL defUsed;
|
||||||
|
int numChars = WideCharToMultiByte(fileMode ? (AreFileApisANSI() ? CP_ACP : CP_OEMCP) : CP_OEMCP,
|
||||||
|
0, s, len, (char *)buf->data, size, &defaultChar, &defUsed);
|
||||||
|
if (numChars == 0 || numChars >= size)
|
||||||
|
return SZ_ERROR_FAIL;
|
||||||
|
buf->data[numChars] = 0;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
fileMode = fileMode;
|
||||||
|
return Utf16_To_Utf8Buf(buf, s, len);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static WRes MyCreateDir(const UInt16 *name)
|
||||||
{
|
{
|
||||||
#ifdef USE_WINDOWS_FILE
|
#ifdef USE_WINDOWS_FILE
|
||||||
return CreateDirectoryA(name, NULL) ? 0 : GetLastError();
|
|
||||||
|
return CreateDirectoryW(name, NULL) ? 0 : GetLastError();
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
CBuf buf;
|
||||||
|
WRes res;
|
||||||
|
Buf_Init(&buf);
|
||||||
|
RINOK(Utf16_To_Char(&buf, name, 1));
|
||||||
|
|
||||||
|
res =
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
return _mkdir(name)
|
_mkdir((const char *)buf.data)
|
||||||
#else
|
#else
|
||||||
return mkdir(name, 0777)
|
mkdir((const char *)buf.data, 0777)
|
||||||
#endif
|
#endif
|
||||||
== 0 ? 0 : errno;
|
== 0 ? 0 : errno;
|
||||||
|
Buf_Free(&buf, &g_Alloc);
|
||||||
|
return res;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static WRes OutFile_OpenUtf16(CSzFile *p, const UInt16 *name)
|
||||||
|
{
|
||||||
|
#ifdef USE_WINDOWS_FILE
|
||||||
|
return OutFile_OpenW(p, name);
|
||||||
|
#else
|
||||||
|
CBuf buf;
|
||||||
|
WRes res;
|
||||||
|
Buf_Init(&buf);
|
||||||
|
RINOK(Utf16_To_Char(&buf, name, 1));
|
||||||
|
res = OutFile_Open(p, (const char *)buf.data);
|
||||||
|
Buf_Free(&buf, &g_Alloc);
|
||||||
|
return res;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PrintString(const UInt16 *s)
|
||||||
|
{
|
||||||
|
CBuf buf;
|
||||||
|
Buf_Init(&buf);
|
||||||
|
if (Utf16_To_Char(&buf, s, 0) == 0)
|
||||||
|
{
|
||||||
|
printf("%s", buf.data);
|
||||||
|
Buf_Free(&buf, &g_Alloc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void ConvertNumberToString(UInt64 value, char *s)
|
static void ConvertNumberToString(UInt64 value, char *s)
|
||||||
{
|
{
|
||||||
@@ -128,7 +269,7 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
SRes res;
|
SRes res;
|
||||||
ISzAlloc allocImp;
|
ISzAlloc allocImp;
|
||||||
ISzAlloc allocTempImp;
|
ISzAlloc allocTempImp;
|
||||||
char *temp = NULL;
|
UInt16 *temp = NULL;
|
||||||
size_t tempSize = 0;
|
size_t tempSize = 0;
|
||||||
|
|
||||||
printf("\n7z ANSI-C Decoder " MY_VERSION_COPYRIGHT_DATE "\n\n");
|
printf("\n7z ANSI-C Decoder " MY_VERSION_COPYRIGHT_DATE "\n\n");
|
||||||
@@ -149,25 +290,24 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
allocImp.Alloc = SzAlloc;
|
||||||
|
allocImp.Free = SzFree;
|
||||||
|
|
||||||
|
allocTempImp.Alloc = SzAllocTemp;
|
||||||
|
allocTempImp.Free = SzFreeTemp;
|
||||||
|
|
||||||
if (InFile_Open(&archiveStream.file, args[2]))
|
if (InFile_Open(&archiveStream.file, args[2]))
|
||||||
{
|
{
|
||||||
PrintError("can not open input file");
|
PrintError("can not open input file");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FileInStream_CreateVTable(&archiveStream);
|
FileInStream_CreateVTable(&archiveStream);
|
||||||
LookToRead_CreateVTable(&lookStream, False);
|
LookToRead_CreateVTable(&lookStream, False);
|
||||||
|
|
||||||
lookStream.realStream = &archiveStream.s;
|
lookStream.realStream = &archiveStream.s;
|
||||||
LookToRead_Init(&lookStream);
|
LookToRead_Init(&lookStream);
|
||||||
|
|
||||||
allocImp.Alloc = SzAlloc;
|
|
||||||
allocImp.Free = SzFree;
|
|
||||||
|
|
||||||
allocTempImp.Alloc = SzAllocTemp;
|
|
||||||
allocTempImp.Free = SzFreeTemp;
|
|
||||||
|
|
||||||
CrcGenerateTable();
|
CrcGenerateTable();
|
||||||
|
|
||||||
SzArEx_Init(&db);
|
SzArEx_Init(&db);
|
||||||
@@ -180,27 +320,13 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
else if (strcmp(command, "t") == 0) testCommand = 1;
|
else if (strcmp(command, "t") == 0) testCommand = 1;
|
||||||
else if (strcmp(command, "e") == 0) extractCommand = 1;
|
else if (strcmp(command, "e") == 0) extractCommand = 1;
|
||||||
else if (strcmp(command, "x") == 0) { extractCommand = 1; fullPaths = 1; }
|
else if (strcmp(command, "x") == 0) { extractCommand = 1; fullPaths = 1; }
|
||||||
|
|
||||||
if (listCommand)
|
|
||||||
{
|
|
||||||
UInt32 i;
|
|
||||||
for (i = 0; i < db.db.NumFiles; i++)
|
|
||||||
{
|
|
||||||
const CSzFileItem *f = db.db.Files + i;
|
|
||||||
char s[32], t[32];
|
|
||||||
ConvertNumberToString(f->Size, s);
|
|
||||||
if (f->MTimeDefined)
|
|
||||||
ConvertFileTimeToString(&f->MTime, t);
|
|
||||||
else
|
else
|
||||||
strcpy(t, " ");
|
{
|
||||||
|
PrintError("incorrect command");
|
||||||
|
res = SZ_ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
printf("%s %10s %s", t, s, f->Name);
|
if (res == SZ_OK)
|
||||||
if (f->IsDir)
|
|
||||||
printf("/");
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (testCommand || extractCommand)
|
|
||||||
{
|
{
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
|
|
||||||
@@ -214,20 +340,52 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
|
|
||||||
for (i = 0; i < db.db.NumFiles; i++)
|
for (i = 0; i < db.db.NumFiles; i++)
|
||||||
{
|
{
|
||||||
size_t offset;
|
size_t offset = 0;
|
||||||
size_t outSizeProcessed;
|
size_t outSizeProcessed = 0;
|
||||||
const CSzFileItem *f = db.db.Files + i;
|
const CSzFileItem *f = db.db.Files + i;
|
||||||
if (f->IsDir && !fullPaths)
|
size_t len;
|
||||||
|
if (listCommand == 0 && f->IsDir && !fullPaths)
|
||||||
continue;
|
continue;
|
||||||
|
len = SzArEx_GetFileNameUtf16(&db, i, NULL);
|
||||||
|
|
||||||
|
if (len > tempSize)
|
||||||
|
{
|
||||||
|
SzFree(NULL, temp);
|
||||||
|
tempSize = len;
|
||||||
|
temp = (UInt16 *)SzAlloc(NULL, tempSize * sizeof(temp[0]));
|
||||||
|
if (temp == 0)
|
||||||
|
{
|
||||||
|
res = SZ_ERROR_MEM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SzArEx_GetFileNameUtf16(&db, i, temp);
|
||||||
|
if (listCommand)
|
||||||
|
{
|
||||||
|
char s[32], t[32];
|
||||||
|
ConvertNumberToString(f->Size, s);
|
||||||
|
if (f->MTimeDefined)
|
||||||
|
ConvertFileTimeToString(&f->MTime, t);
|
||||||
|
else
|
||||||
|
strcpy(t, " ");
|
||||||
|
|
||||||
|
printf("%s %10s ", t, s);
|
||||||
|
PrintString(temp);
|
||||||
|
if (f->IsDir)
|
||||||
|
printf("/");
|
||||||
|
printf("\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
printf(testCommand ?
|
printf(testCommand ?
|
||||||
"Testing ":
|
"Testing ":
|
||||||
"Extracting");
|
"Extracting ");
|
||||||
printf(" %s", f->Name);
|
PrintString(temp);
|
||||||
if (f->IsDir)
|
if (f->IsDir)
|
||||||
printf("/");
|
printf("/");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
res = SzAr_Extract(&db, &lookStream.s, i,
|
res = SzArEx_Extract(&db, &lookStream.s, i,
|
||||||
&blockIndex, &outBuffer, &outBufferSize,
|
&blockIndex, &outBuffer, &outBufferSize,
|
||||||
&offset, &outSizeProcessed,
|
&offset, &outSizeProcessed,
|
||||||
&allocImp, &allocTempImp);
|
&allocImp, &allocTempImp);
|
||||||
@@ -238,32 +396,20 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
{
|
{
|
||||||
CSzFile outFile;
|
CSzFile outFile;
|
||||||
size_t processedSize;
|
size_t processedSize;
|
||||||
size_t j, nameLen = strlen(f->Name);
|
size_t j;
|
||||||
const char *destPath;
|
UInt16 *name = (UInt16 *)temp;
|
||||||
if (nameLen + 1 > tempSize)
|
const UInt16 *destPath = (const UInt16 *)name;
|
||||||
{
|
for (j = 0; name[j] != 0; j++)
|
||||||
SzFree(NULL, temp);
|
if (name[j] == '/')
|
||||||
tempSize = nameLen + 1;
|
|
||||||
temp = (char *)SzAlloc(NULL, tempSize);
|
|
||||||
if (temp == 0)
|
|
||||||
{
|
|
||||||
res = SZ_ERROR_MEM;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
destPath = temp;
|
|
||||||
strcpy(temp, f->Name);
|
|
||||||
for (j = 0; j < nameLen; j++)
|
|
||||||
if (temp[j] == '/')
|
|
||||||
{
|
{
|
||||||
if (fullPaths)
|
if (fullPaths)
|
||||||
{
|
{
|
||||||
temp[j] = 0;
|
name[j] = 0;
|
||||||
MyCreateDir(temp);
|
MyCreateDir(name);
|
||||||
temp[j] = CHAR_PATH_SEPARATOR;
|
name[j] = CHAR_PATH_SEPARATOR;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
destPath = temp + j + 1;
|
destPath = name + j + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f->IsDir)
|
if (f->IsDir)
|
||||||
@@ -272,15 +418,14 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (OutFile_Open(&outFile, destPath))
|
else if (OutFile_OpenUtf16(&outFile, destPath))
|
||||||
{
|
{
|
||||||
PrintError("can not open output file");
|
PrintError("can not open output file");
|
||||||
res = SZ_ERROR_FAIL;
|
res = SZ_ERROR_FAIL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
processedSize = outSizeProcessed;
|
processedSize = outSizeProcessed;
|
||||||
if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 ||
|
if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed)
|
||||||
processedSize != outSizeProcessed)
|
|
||||||
{
|
{
|
||||||
PrintError("can not write output file");
|
PrintError("can not write output file");
|
||||||
res = SZ_ERROR_FAIL;
|
res = SZ_ERROR_FAIL;
|
||||||
@@ -297,11 +442,6 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
}
|
}
|
||||||
IAlloc_Free(&allocImp, outBuffer);
|
IAlloc_Free(&allocImp, outBuffer);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
PrintError("incorrect command");
|
|
||||||
res = SZ_ERROR_FAIL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
SzArEx_Free(&db, &allocImp);
|
SzArEx_Free(&db, &allocImp);
|
||||||
SzFree(NULL, temp);
|
SzFree(NULL, temp);
|
||||||
@@ -6,20 +6,17 @@ C_OBJS = \
|
|||||||
$O\7zBuf.obj \
|
$O\7zBuf.obj \
|
||||||
$O\7zBuf2.obj \
|
$O\7zBuf2.obj \
|
||||||
$O\7zCrc.obj \
|
$O\7zCrc.obj \
|
||||||
$O\LzmaDec.obj \
|
|
||||||
$O\Lzma2Dec.obj \
|
|
||||||
$O\Bra86.obj \
|
|
||||||
$O\Bcj2.obj \
|
|
||||||
$O\7zFile.obj \
|
$O\7zFile.obj \
|
||||||
|
$O\7zDec.obj \
|
||||||
|
$O\7zIn.obj \
|
||||||
$O\7zStream.obj \
|
$O\7zStream.obj \
|
||||||
|
$O\Bcj2.obj \
|
||||||
|
$O\Bra86.obj \
|
||||||
|
$O\Lzma2Dec.obj \
|
||||||
|
$O\LzmaDec.obj \
|
||||||
|
|
||||||
7Z_OBJS = \
|
7Z_OBJS = \
|
||||||
$O\7zAlloc.obj \
|
$O\7zAlloc.obj \
|
||||||
$O\7zDecode.obj \
|
|
||||||
$O\7zExtract.obj \
|
|
||||||
$O\7zHeader.obj \
|
|
||||||
$O\7zIn.obj \
|
|
||||||
$O\7zItem.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 = 7zAlloc.o 7zBuf.o 7zBuf2.o 7zCrc.o 7zDecode.o 7zExtract.o 7zHeader.o 7zIn.o 7zItem.o 7zMain.o LzmaDec.o Lzma2Dec.o Bra86.o Bcj2.o 7zFile.o 7zStream.o
|
OBJS = 7zAlloc.o 7zBuf.o 7zBuf2.o 7zCrc.o 7zDec.o 7zIn.o 7zMain.o LzmaDec.o Lzma2Dec.o Bra86.o Bcj2.o 7zFile.o 7zStream.o
|
||||||
|
|
||||||
all: $(PROG)
|
all: $(PROG)
|
||||||
|
|
||||||
@@ -23,20 +23,11 @@ $(PROG): $(OBJS)
|
|||||||
7zCrc.o: ../../7zCrc.c
|
7zCrc.o: ../../7zCrc.c
|
||||||
$(CXX) $(CFLAGS) ../../7zCrc.c
|
$(CXX) $(CFLAGS) ../../7zCrc.c
|
||||||
|
|
||||||
7zDecode.o: 7zDecode.c
|
7zDec.o: ../../7zDec.c
|
||||||
$(CXX) $(CFLAGS) 7zDecode.c
|
$(CXX) $(CFLAGS) ../../7zDec.c
|
||||||
|
|
||||||
7zExtract.o: 7zExtract.c
|
7zIn.o: ../../7zIn.c
|
||||||
$(CXX) $(CFLAGS) 7zExtract.c
|
$(CXX) $(CFLAGS) ../../7zIn.c
|
||||||
|
|
||||||
7zHeader.o: 7zHeader.c
|
|
||||||
$(CXX) $(CFLAGS) 7zHeader.c
|
|
||||||
|
|
||||||
7zIn.o: 7zIn.c
|
|
||||||
$(CXX) $(CFLAGS) 7zIn.c
|
|
||||||
|
|
||||||
7zItem.o: 7zItem.c
|
|
||||||
$(CXX) $(CFLAGS) 7zItem.c
|
|
||||||
|
|
||||||
7zMain.o: 7zMain.c
|
7zMain.o: 7zMain.c
|
||||||
$(CXX) $(CFLAGS) 7zMain.c
|
$(CXX) $(CFLAGS) 7zMain.c
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/* LzmaUtil.c -- Test application for LZMA compression
|
/* LzmaUtil.c -- Test application for LZMA compression
|
||||||
2008-11-23 : Igor Pavlov : Public domain */
|
2009-08-14 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
|
|
||||||
@@ -7,11 +7,11 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "../Alloc.h"
|
#include "../../Alloc.h"
|
||||||
#include "../7zFile.h"
|
#include "../../7zFile.h"
|
||||||
#include "../7zVersion.h"
|
#include "../../7zVersion.h"
|
||||||
#include "../LzmaDec.h"
|
#include "../../LzmaDec.h"
|
||||||
#include "../LzmaEnc.h"
|
#include "../../LzmaEnc.h"
|
||||||
|
|
||||||
const char *kCantReadMessage = "Can not read input file";
|
const char *kCantReadMessage = "Can not read input file";
|
||||||
const char *kCantWriteMessage = "Can not write output file";
|
const char *kCantWriteMessage = "Can not write output file";
|
||||||
@@ -51,7 +51,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 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:console /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 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:console /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 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:console /machine:I386 /out:"c:\util\lzmac.exe"
|
# 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 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:console /machine:I386 /out:"c:\util\7lzma.exe"
|
||||||
|
|
||||||
!ELSEIF "$(CFG)" == "LzmaUtil - Win32 Debug"
|
!ELSEIF "$(CFG)" == "LzmaUtil - Win32 Debug"
|
||||||
|
|
||||||
@@ -76,7 +76,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 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:console /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 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:console /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 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:console /debug /machine:I386 /out:"c:\util\lzmac.exe" /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 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:console /debug /machine:I386 /out:"c:\util\7lzma.exe" /pdbtype:sept
|
||||||
|
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
@@ -86,67 +86,67 @@ LINK32=link.exe
|
|||||||
# Name "LzmaUtil - Win32 Debug"
|
# Name "LzmaUtil - Win32 Debug"
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\7zFile.c
|
SOURCE=..\..\7zFile.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\7zFile.h
|
SOURCE=..\..\7zFile.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\7zStream.c
|
SOURCE=..\..\7zStream.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\7zVersion.h
|
SOURCE=..\..\7zVersion.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\Alloc.c
|
SOURCE=..\..\Alloc.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\Alloc.h
|
SOURCE=..\..\Alloc.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\CpuArch.h
|
SOURCE=..\..\CpuArch.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\LzFind.c
|
SOURCE=..\..\LzFind.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\LzFind.h
|
SOURCE=..\..\LzFind.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\LzFindMt.c
|
SOURCE=..\..\LzFindMt.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\LzFindMt.h
|
SOURCE=..\..\LzFindMt.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\LzHash.h
|
SOURCE=..\..\LzHash.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\LzmaDec.c
|
SOURCE=..\..\LzmaDec.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\LzmaDec.h
|
SOURCE=..\..\LzmaDec.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\LzmaEnc.c
|
SOURCE=..\..\LzmaEnc.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\LzmaEnc.h
|
SOURCE=..\..\LzmaEnc.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
@@ -154,15 +154,15 @@ SOURCE=.\LzmaUtil.c
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\Threads.c
|
SOURCE=..\..\Threads.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\Threads.h
|
SOURCE=..\..\Threads.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\Types.h
|
SOURCE=..\..\Types.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# End Target
|
# End Target
|
||||||
# End Project
|
# End Project
|
||||||
@@ -21,9 +21,9 @@ OBJS = \
|
|||||||
$(LIB_OBJS) \
|
$(LIB_OBJS) \
|
||||||
$(C_OBJS) \
|
$(C_OBJS) \
|
||||||
|
|
||||||
!include "../../CPP/Build.mak"
|
!include "../../../CPP/Build.mak"
|
||||||
|
|
||||||
$(LIB_OBJS): $(*B).c
|
$(LIB_OBJS): $(*B).c
|
||||||
$(COMPL_O2)
|
$(COMPL_O2)
|
||||||
$(C_OBJS): ../$(*B).c
|
$(C_OBJS): ../../$(*B).c
|
||||||
$(COMPL_O2)
|
$(COMPL_O2)
|
||||||
44
C/Util/Lzma/makefile.gcc
Executable file
44
C/Util/Lzma/makefile.gcc
Executable file
@@ -0,0 +1,44 @@
|
|||||||
|
PROG = lzma
|
||||||
|
CXX = g++
|
||||||
|
LIB =
|
||||||
|
RM = rm -f
|
||||||
|
CFLAGS = -c -O2 -Wall
|
||||||
|
|
||||||
|
OBJS = \
|
||||||
|
LzmaUtil.o \
|
||||||
|
Alloc.o \
|
||||||
|
LzFind.o \
|
||||||
|
LzmaDec.o \
|
||||||
|
LzmaEnc.o \
|
||||||
|
7zFile.o \
|
||||||
|
7zStream.o \
|
||||||
|
|
||||||
|
|
||||||
|
all: $(PROG)
|
||||||
|
|
||||||
|
$(PROG): $(OBJS)
|
||||||
|
$(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB) $(LIB2)
|
||||||
|
|
||||||
|
LzmaUtil.o: LzmaUtil.c
|
||||||
|
$(CXX) $(CFLAGS) LzmaUtil.c
|
||||||
|
|
||||||
|
Alloc.o: ../../Alloc.c
|
||||||
|
$(CXX) $(CFLAGS) ../../Alloc.c
|
||||||
|
|
||||||
|
LzFind.o: ../../LzFind.c
|
||||||
|
$(CXX) $(CFLAGS) ../../LzFind.c
|
||||||
|
|
||||||
|
LzmaDec.o: ../../LzmaDec.c
|
||||||
|
$(CXX) $(CFLAGS) ../../LzmaDec.c
|
||||||
|
|
||||||
|
LzmaEnc.o: ../../LzmaEnc.c
|
||||||
|
$(CXX) $(CFLAGS) ../../LzmaEnc.c
|
||||||
|
|
||||||
|
7zFile.o: ../../7zFile.c
|
||||||
|
$(CXX) $(CFLAGS) ../../7zFile.c
|
||||||
|
|
||||||
|
7zStream.o: ../../7zStream.c
|
||||||
|
$(CXX) $(CFLAGS) ../../7zStream.c
|
||||||
|
|
||||||
|
clean:
|
||||||
|
-$(RM) $(PROG) $(OBJS)
|
||||||
@@ -104,59 +104,59 @@ SOURCE=.\LzmaLibExports.c
|
|||||||
# End Group
|
# End Group
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\Alloc.c
|
SOURCE=..\..\Alloc.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\Alloc.h
|
SOURCE=..\..\Alloc.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\IStream.h
|
SOURCE=..\..\IStream.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\LzFind.c
|
SOURCE=..\..\LzFind.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\LzFind.h
|
SOURCE=..\..\LzFind.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\LzFindMt.c
|
SOURCE=..\..\LzFindMt.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\LzFindMt.h
|
SOURCE=..\..\LzFindMt.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\LzHash.h
|
SOURCE=..\..\LzHash.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\LzmaDec.c
|
SOURCE=..\..\LzmaDec.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\LzmaDec.h
|
SOURCE=..\..\LzmaDec.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\LzmaEnc.c
|
SOURCE=..\..\LzmaEnc.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\LzmaEnc.h
|
SOURCE=..\..\LzmaEnc.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\LzmaLib.c
|
SOURCE=..\..\LzmaLib.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\LzmaLib.h
|
SOURCE=..\..\LzmaLib.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
@@ -164,15 +164,15 @@ SOURCE=.\resource.rc
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\Threads.c
|
SOURCE=..\..\Threads.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\Threads.h
|
SOURCE=..\..\Threads.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\Types.h
|
SOURCE=..\..\Types.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# End Target
|
# End Target
|
||||||
# End Project
|
# End Project
|
||||||
@@ -7,8 +7,6 @@ DEF_FILE = LzmaLib.def
|
|||||||
CFLAGS = $(CFLAGS) \
|
CFLAGS = $(CFLAGS) \
|
||||||
-DCOMPRESS_MF_MT \
|
-DCOMPRESS_MF_MT \
|
||||||
|
|
||||||
LIBS = $(LIBS) oleaut32.lib
|
|
||||||
|
|
||||||
LIB_OBJS = \
|
LIB_OBJS = \
|
||||||
$O\LzmaLibExports.obj \
|
$O\LzmaLibExports.obj \
|
||||||
|
|
||||||
@@ -26,12 +24,12 @@ OBJS = \
|
|||||||
$(C_OBJS) \
|
$(C_OBJS) \
|
||||||
$O\resource.res
|
$O\resource.res
|
||||||
|
|
||||||
!include "../../CPP/Build.mak"
|
!include "../../../CPP/Build.mak"
|
||||||
|
|
||||||
$(SLIBPATH): $O $(OBJS)
|
$(SLIBPATH): $O $(OBJS)
|
||||||
lib -out:$(SLIBPATH) $(OBJS) $(LIBS)
|
lib -out:$(SLIBPATH) $(OBJS) $(LIBS)
|
||||||
|
|
||||||
$(LIB_OBJS): $(*B).c
|
$(LIB_OBJS): $(*B).c
|
||||||
$(COMPL_O2)
|
$(COMPL_O2)
|
||||||
$(C_OBJS): ../$(*B).c
|
$(C_OBJS): ../../$(*B).c
|
||||||
$(COMPL_O2)
|
$(COMPL_O2)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "../../CPP/7zip/MyVersionInfo.rc"
|
#include "../../../CPP/7zip/MyVersionInfo.rc"
|
||||||
|
|
||||||
MY_VERSION_INFO_DLL("LZMA library", "LZMA")
|
MY_VERSION_INFO_DLL("LZMA library", "LZMA")
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/* XzDec.c -- Xz Decode
|
/* XzDec.c -- Xz Decode
|
||||||
2009-05-29 : Igor Pavlov : Public domain */
|
2009-06-08 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
/* #define XZ_DUMP */
|
/* #define XZ_DUMP */
|
||||||
|
|
||||||
@@ -291,9 +291,10 @@ static void Lzma2State_Init(void *pp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static SRes Lzma2State_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
static SRes Lzma2State_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||||
int srcWasFinished, ELzmaFinishMode finishMode, int *wasFinished)
|
int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished)
|
||||||
{
|
{
|
||||||
ELzmaStatus status;
|
ELzmaStatus status;
|
||||||
|
/* ELzmaFinishMode fm = (finishMode == LZMA_FINISH_ANY) ? LZMA_FINISH_ANY : LZMA_FINISH_END; */
|
||||||
SRes res = Lzma2Dec_DecodeToBuf((CLzma2Dec *)pp, dest, destLen, src, srcLen, finishMode, &status);
|
SRes res = Lzma2Dec_DecodeToBuf((CLzma2Dec *)pp, dest, destLen, src, srcLen, finishMode, &status);
|
||||||
srcWasFinished = srcWasFinished;
|
srcWasFinished = srcWasFinished;
|
||||||
*wasFinished = (status == LZMA_STATUS_FINISHED_WITH_MARK);
|
*wasFinished = (status == LZMA_STATUS_FINISHED_WITH_MARK);
|
||||||
@@ -373,7 +374,7 @@ SRes MixCoder_SetFromMethod(CMixCoder *p, int coderIndex, UInt64 methodId)
|
|||||||
|
|
||||||
SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
|
SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
|
||||||
const Byte *src, SizeT *srcLen, int srcWasFinished,
|
const Byte *src, SizeT *srcLen, int srcWasFinished,
|
||||||
ELzmaFinishMode finishMode, ECoderStatus *status)
|
ECoderFinishMode finishMode, ECoderStatus *status)
|
||||||
{
|
{
|
||||||
SizeT destLenOrig = *destLen;
|
SizeT destLenOrig = *destLen;
|
||||||
SizeT srcLenOrig = *srcLen;
|
SizeT srcLenOrig = *srcLen;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* XzEnc.c -- Xz Encode
|
/* XzEnc.c -- Xz Encode
|
||||||
2009-05-26 : Igor Pavlov : Public domain */
|
2009-06-04 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -442,7 +442,7 @@ static SRes Xz_Compress(CXzStream *xz,
|
|||||||
|
|
||||||
{
|
{
|
||||||
UInt64 packPos = seqSizeOutStream.processed;
|
UInt64 packPos = seqSizeOutStream.processed;
|
||||||
HRESULT res = Lzma2Enc_Encode(lzmaf->lzma2, &seqSizeOutStream.p,
|
SRes res = Lzma2Enc_Encode(lzmaf->lzma2, &seqSizeOutStream.p,
|
||||||
#ifdef USE_SUBBLOCK
|
#ifdef USE_SUBBLOCK
|
||||||
useSubblock ? &lzmaf->sb.p:
|
useSubblock ? &lzmaf->sb.p:
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
5
C/XzIn.c
5
C/XzIn.c
@@ -1,10 +1,11 @@
|
|||||||
/* XzIn.c - Xz input
|
/* XzIn.c - Xz input
|
||||||
2009-04-15 : Igor Pavlov : Public domain */
|
2009-06-19 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Xz.h"
|
#include <string.h>
|
||||||
|
|
||||||
#include "7zCrc.h"
|
#include "7zCrc.h"
|
||||||
#include "CpuArch.h"
|
#include "CpuArch.h"
|
||||||
|
#include "Xz.h"
|
||||||
|
|
||||||
SRes Xz_ReadHeader(CXzStreamFlags *p, ISeqInStream *inStream)
|
SRes Xz_ReadHeader(CXzStreamFlags *p, ISeqInStream *inStream)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -164,8 +164,7 @@ HRESULT CEncoder::Encode(
|
|||||||
}
|
}
|
||||||
for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
|
for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
|
||||||
{
|
{
|
||||||
CSequentialOutTempBufferImp *tempBufferSpec =
|
CSequentialOutTempBufferImp *tempBufferSpec = new CSequentialOutTempBufferImp;
|
||||||
new CSequentialOutTempBufferImp;
|
|
||||||
CMyComPtr<ISequentialOutStream> tempBuffer = tempBufferSpec;
|
CMyComPtr<ISequentialOutStream> tempBuffer = tempBufferSpec;
|
||||||
tempBufferSpec->Init(&inOutTempBuffers[i - 1]);
|
tempBufferSpec->Init(&inOutTempBuffers[i - 1]);
|
||||||
tempBuffers.Add(tempBuffer);
|
tempBuffers.Add(tempBuffer);
|
||||||
@@ -260,9 +259,7 @@ HRESULT CEncoder::Encode(
|
|||||||
for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
|
for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
|
||||||
{
|
{
|
||||||
CInOutTempBuffer &inOutTempBuffer = inOutTempBuffers[i - 1];
|
CInOutTempBuffer &inOutTempBuffer = inOutTempBuffers[i - 1];
|
||||||
inOutTempBuffer.FlushWrite();
|
RINOK(inOutTempBuffer.WriteToStream(outStream));
|
||||||
inOutTempBuffer.InitReading();
|
|
||||||
inOutTempBuffer.WriteToStream(outStream);
|
|
||||||
packSizes.Add(inOutTempBuffer.GetDataSize());
|
packSizes.Add(inOutTempBuffer.GetDataSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ struct CExtractFolderInfo
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec)
|
Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
@@ -52,7 +52,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
|
CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
|
||||||
UInt64 importantTotalUnpacked = 0;
|
UInt64 importantTotalUnpacked = 0;
|
||||||
|
|
||||||
bool allFilesMode = (numItems == UInt32(-1));
|
bool allFilesMode = (numItems == (UInt32)-1);
|
||||||
if (allFilesMode)
|
if (allFilesMode)
|
||||||
numItems =
|
numItems =
|
||||||
#ifdef _7Z_VOL
|
#ifdef _7Z_VOL
|
||||||
@@ -244,25 +244,25 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
|
|
||||||
if (result == S_FALSE)
|
if (result == S_FALSE)
|
||||||
{
|
{
|
||||||
RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError));
|
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (result == E_NOTIMPL)
|
if (result == E_NOTIMPL)
|
||||||
{
|
{
|
||||||
RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kUnSupportedMethod));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (result != S_OK)
|
if (result != S_OK)
|
||||||
return result;
|
return result;
|
||||||
if (folderOutStream->WasWritingFinished() != S_OK)
|
if (folderOutStream->WasWritingFinished() != S_OK)
|
||||||
{
|
{
|
||||||
RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError));
|
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError));
|
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,9 +37,9 @@ HRESULT CFolderOutStream::Init(
|
|||||||
HRESULT CFolderOutStream::OpenFile()
|
HRESULT CFolderOutStream::OpenFile()
|
||||||
{
|
{
|
||||||
Int32 askMode = ((*_extractStatuses)[_currentIndex]) ? (_testMode ?
|
Int32 askMode = ((*_extractStatuses)[_currentIndex]) ? (_testMode ?
|
||||||
NArchive::NExtract::NAskMode::kTest :
|
NExtract::NAskMode::kTest :
|
||||||
NArchive::NExtract::NAskMode::kExtract):
|
NExtract::NAskMode::kExtract) :
|
||||||
NArchive::NExtract::NAskMode::kSkip;
|
NExtract::NAskMode::kSkip;
|
||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
UInt32 index = _startIndex + _currentIndex;
|
UInt32 index = _startIndex + _currentIndex;
|
||||||
RINOK(_extractCallback->GetStream(_ref2Offset + index, &realOutStream, askMode));
|
RINOK(_extractCallback->GetStream(_ref2Offset + index, &realOutStream, askMode));
|
||||||
@@ -48,9 +48,9 @@ HRESULT CFolderOutStream::OpenFile()
|
|||||||
_fileIsOpen = true;
|
_fileIsOpen = true;
|
||||||
const CFileItem &fi = _db->Files[index];
|
const CFileItem &fi = _db->Files[index];
|
||||||
_rem = fi.Size;
|
_rem = fi.Size;
|
||||||
if (askMode == NArchive::NExtract::NAskMode::kExtract && !realOutStream &&
|
if (askMode == NExtract::NAskMode::kExtract && !realOutStream &&
|
||||||
!_db->IsItemAnti(index) && !fi.IsDir)
|
!_db->IsItemAnti(index) && !fi.IsDir)
|
||||||
askMode = NArchive::NExtract::NAskMode::kSkip;
|
askMode = NExtract::NAskMode::kSkip;
|
||||||
return _extractCallback->PrepareOperation(askMode);
|
return _extractCallback->PrepareOperation(askMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,8 +67,8 @@ HRESULT CFolderOutStream::CloseFileAndSetResult()
|
|||||||
const CFileItem &fi = _db->Files[_startIndex + _currentIndex];
|
const CFileItem &fi = _db->Files[_startIndex + _currentIndex];
|
||||||
return CloseFileAndSetResult(
|
return CloseFileAndSetResult(
|
||||||
(fi.IsDir || !fi.CrcDefined || !_checkCrc || fi.Crc == _crcStreamSpec->GetCRC()) ?
|
(fi.IsDir || !fi.CrcDefined || !_checkCrc || fi.Crc == _crcStreamSpec->GetCRC()) ?
|
||||||
NArchive::NExtract::NOperationResult::kOK :
|
NExtract::NOperationResult::kOK :
|
||||||
NArchive::NExtract::NOperationResult::kCRCError);
|
NExtract::NOperationResult::kCRCError);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CFolderOutStream::ProcessEmptyFiles()
|
HRESULT CFolderOutStream::ProcessEmptyFiles()
|
||||||
|
|||||||
@@ -300,11 +300,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
|||||||
else if (coder.MethodID == k_PPMD && coder.Props.GetCapacity() == 5)
|
else if (coder.MethodID == k_PPMD && coder.Props.GetCapacity() == 5)
|
||||||
{
|
{
|
||||||
Byte order = *(const Byte *)coder.Props;
|
Byte order = *(const Byte *)coder.Props;
|
||||||
methodsString += L'o';
|
propsString = L'o';
|
||||||
methodsString += ConvertUInt32ToString(order);
|
propsString += ConvertUInt32ToString(order);
|
||||||
methodsString += L":mem";
|
propsString += L":mem";
|
||||||
UInt32 dicSize = GetUi32((const Byte *)coder.Props + 1);
|
UInt32 dicSize = GetUi32((const Byte *)coder.Props + 1);
|
||||||
propsString = GetStringForSizeValue(dicSize);
|
propsString += GetStringForSizeValue(dicSize);
|
||||||
}
|
}
|
||||||
else if (coder.MethodID == k_AES && coder.Props.GetCapacity() >= 1)
|
else if (coder.MethodID == k_AES && coder.Props.GetCapacity() >= 1)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -27,7 +27,13 @@ static const wchar_t *kDefaultMethodName = kLZMAMethodName;
|
|||||||
|
|
||||||
static const UInt32 kLzmaAlgorithmX5 = 1;
|
static const UInt32 kLzmaAlgorithmX5 = 1;
|
||||||
static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2";
|
static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2";
|
||||||
static const UInt32 kDictionaryForHeaders = 1 << 20;
|
static const UInt32 kDictionaryForHeaders =
|
||||||
|
#ifdef UNDER_CE
|
||||||
|
1 << 18
|
||||||
|
#else
|
||||||
|
1 << 20
|
||||||
|
#endif
|
||||||
|
;
|
||||||
static const UInt32 kNumFastBytesForHeaders = 273;
|
static const UInt32 kNumFastBytesForHeaders = 273;
|
||||||
static const UInt32 kAlgorithmForHeaders = kLzmaAlgorithmX5;
|
static const UInt32 kAlgorithmForHeaders = kLzmaAlgorithmX5;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// 7z/Header.cpp
|
// 7zHeader.cpp
|
||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
#include "7zHeader.h"
|
#include "7zHeader.h"
|
||||||
@@ -6,22 +6,9 @@
|
|||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace N7z {
|
namespace N7z {
|
||||||
|
|
||||||
Byte kSignature[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C};
|
Byte kSignature[kSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
|
||||||
#ifdef _7Z_VOL
|
#ifdef _7Z_VOL
|
||||||
Byte kFinishSignature[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C + 1};
|
Byte kFinishSignature[kSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C + 1};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class SignatureInitializer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SignatureInitializer()
|
|
||||||
{
|
|
||||||
kSignature[0]--;
|
|
||||||
#ifdef _7Z_VOL
|
|
||||||
kFinishSignature[0]--;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
} g_SignatureInitializer;
|
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
|||||||
@@ -541,16 +541,16 @@ void COutArchive::WriteUInt64DefVector(const CUInt64DefVector &v, Byte type)
|
|||||||
|
|
||||||
HRESULT COutArchive::EncodeStream(
|
HRESULT COutArchive::EncodeStream(
|
||||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||||
CEncoder &encoder, const Byte *data, size_t dataSize,
|
CEncoder &encoder, const CByteBuffer &data,
|
||||||
CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders)
|
CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders)
|
||||||
{
|
{
|
||||||
CSequentialInStreamImp *streamSpec = new CSequentialInStreamImp;
|
CBufInStream *streamSpec = new CBufInStream;
|
||||||
CMyComPtr<ISequentialInStream> stream = streamSpec;
|
CMyComPtr<ISequentialInStream> stream = streamSpec;
|
||||||
streamSpec->Init(data, dataSize);
|
streamSpec->Init(data, data.GetCapacity());
|
||||||
CFolder folderItem;
|
CFolder folderItem;
|
||||||
folderItem.UnpackCRCDefined = true;
|
folderItem.UnpackCRCDefined = true;
|
||||||
folderItem.UnpackCRC = CrcCalc(data, dataSize);
|
folderItem.UnpackCRC = CrcCalc(data, data.GetCapacity());
|
||||||
UInt64 dataSize64 = dataSize;
|
UInt64 dataSize64 = data.GetCapacity();
|
||||||
RINOK(encoder.Encode(
|
RINOK(encoder.Encode(
|
||||||
EXTERNAL_CODECS_LOC_VARS
|
EXTERNAL_CODECS_LOC_VARS
|
||||||
stream, NULL, &dataSize64, folderItem, SeqStream, packSizes, NULL))
|
stream, NULL, &dataSize64, folderItem, SeqStream, packSizes, NULL))
|
||||||
@@ -558,16 +558,6 @@ HRESULT COutArchive::EncodeStream(
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT COutArchive::EncodeStream(
|
|
||||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
|
||||||
CEncoder &encoder, const CByteBuffer &data,
|
|
||||||
CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders)
|
|
||||||
{
|
|
||||||
return EncodeStream(
|
|
||||||
EXTERNAL_CODECS_LOC_VARS
|
|
||||||
encoder, data, data.GetCapacity(), packSizes, folders);
|
|
||||||
}
|
|
||||||
|
|
||||||
void COutArchive::WriteHeader(
|
void COutArchive::WriteHeader(
|
||||||
const CArchiveDatabase &db,
|
const CArchiveDatabase &db,
|
||||||
const CHeaderOptions &headerOptions,
|
const CHeaderOptions &headerOptions,
|
||||||
@@ -804,8 +794,8 @@ HRESULT COutArchive::WriteDatabase(
|
|||||||
CObjectVector<CFolder> folders;
|
CObjectVector<CFolder> folders;
|
||||||
RINOK(EncodeStream(
|
RINOK(EncodeStream(
|
||||||
EXTERNAL_CODECS_LOC_VARS
|
EXTERNAL_CODECS_LOC_VARS
|
||||||
encoder, (const Byte *)buf,
|
encoder, buf,
|
||||||
_countSize, packSizes, folders));
|
packSizes, folders));
|
||||||
|
|
||||||
_writeToStream = true;
|
_writeToStream = true;
|
||||||
|
|
||||||
|
|||||||
@@ -98,10 +98,6 @@ class COutArchive
|
|||||||
void WriteAlignedBoolHeader(const CBoolVector &v, int numDefined, Byte type, unsigned itemSize);
|
void WriteAlignedBoolHeader(const CBoolVector &v, int numDefined, Byte type, unsigned itemSize);
|
||||||
void WriteUInt64DefVector(const CUInt64DefVector &v, Byte type);
|
void WriteUInt64DefVector(const CUInt64DefVector &v, Byte type);
|
||||||
|
|
||||||
HRESULT EncodeStream(
|
|
||||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
|
||||||
CEncoder &encoder, const Byte *data, size_t dataSize,
|
|
||||||
CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders);
|
|
||||||
HRESULT EncodeStream(
|
HRESULT EncodeStream(
|
||||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||||
CEncoder &encoder, const CByteBuffer &data,
|
CEncoder &encoder, const CByteBuffer &data,
|
||||||
|
|||||||
@@ -13,6 +13,6 @@ static IOutArchive *CreateArcOut() { return new NArchive::N7z::CHandler; }
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static CArcInfo g_ArcInfo =
|
static CArcInfo g_ArcInfo =
|
||||||
{ L"7z", L"7z", 0, 7, {'7' + 1 , 'z', 0xBC, 0xAF, 0x27, 0x1C}, 6, false, CreateArc, CreateArcOut };
|
{ L"7z", L"7z", 0, 7, {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}, 6, false, CreateArc, CreateArcOut };
|
||||||
|
|
||||||
REGISTER_ARC_DEC_SIG(7z)
|
REGISTER_ARC_DEC_SIG(7z)
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
#include "../../../../C/CpuArch.h"
|
||||||
|
|
||||||
#include "../../Common/LimitedStreams.h"
|
#include "../../Common/LimitedStreams.h"
|
||||||
#include "../../Common/ProgressUtils.h"
|
#include "../../Common/ProgressUtils.h"
|
||||||
|
|
||||||
@@ -32,6 +34,10 @@ static const UInt32 kDictionaryForBCJ2_LZMA = 1 << 20;
|
|||||||
static const UInt32 kAlgorithmForBCJ2_LZMA = 1;
|
static const UInt32 kAlgorithmForBCJ2_LZMA = 1;
|
||||||
static const UInt32 kNumFastBytesForBCJ2_LZMA = 64;
|
static const UInt32 kNumFastBytesForBCJ2_LZMA = 64;
|
||||||
|
|
||||||
|
#ifdef MY_CPU_X86_OR_AMD64
|
||||||
|
#define USE_86_FILTER
|
||||||
|
#endif
|
||||||
|
|
||||||
static HRESULT WriteRange(IInStream *inStream, ISequentialOutStream *outStream,
|
static HRESULT WriteRange(IInStream *inStream, ISequentialOutStream *outStream,
|
||||||
UInt64 position, UInt64 size, ICompressProgressInfo *progress)
|
UInt64 position, UInt64 size, ICompressProgressInfo *progress)
|
||||||
{
|
{
|
||||||
@@ -122,7 +128,7 @@ static int CompareFiles(const CFileItem &f1, const CFileItem &f2)
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const struct CFolderRepack
|
struct CFolderRepack
|
||||||
{
|
{
|
||||||
int FolderIndex;
|
int FolderIndex;
|
||||||
int Group;
|
int Group;
|
||||||
@@ -334,7 +340,9 @@ static bool IsExeExt(const UString &ext)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GetMethodFull(UInt64 methodID, UInt32 numInStreams, CMethodFull &methodResult)
|
#ifdef USE_86_FILTER
|
||||||
|
|
||||||
|
static inline void GetMethodFull(UInt64 methodID, UInt32 numInStreams, CMethodFull &methodResult)
|
||||||
{
|
{
|
||||||
methodResult.Id = methodID;
|
methodResult.Id = methodID;
|
||||||
methodResult.NumInStreams = numInStreams;
|
methodResult.NumInStreams = numInStreams;
|
||||||
@@ -409,6 +417,8 @@ static void MakeExeMethod(const CCompressionMethodMode &method,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static void FromUpdateItemToFileItem(const CUpdateItem &ui,
|
static void FromUpdateItemToFileItem(const CUpdateItem &ui,
|
||||||
CFileItem &file, CFileItem2 &file2)
|
CFileItem &file, CFileItem2 &file2)
|
||||||
{
|
{
|
||||||
@@ -665,7 +675,9 @@ STDMETHODIMP CCryptoGetTextPassword::CryptoGetTextPassword(BSTR *password)
|
|||||||
|
|
||||||
static const int kNumGroupsMax = 4;
|
static const int kNumGroupsMax = 4;
|
||||||
|
|
||||||
|
#ifdef USE_86_FILTER
|
||||||
static bool Is86Group(int group) { return (group & 1) != 0; }
|
static bool Is86Group(int group) { return (group & 1) != 0; }
|
||||||
|
#endif
|
||||||
static bool IsEncryptedGroup(int group) { return (group & 2) != 0; }
|
static bool IsEncryptedGroup(int group) { return (group & 2) != 0; }
|
||||||
static int GetGroupIndex(bool encrypted, int bcjFiltered)
|
static int GetGroupIndex(bool encrypted, int bcjFiltered)
|
||||||
{ return (encrypted ? 2 : 0) + (bcjFiltered ? 1 : 0); }
|
{ return (encrypted ? 2 : 0) + (bcjFiltered ? 1 : 0); }
|
||||||
@@ -865,9 +877,11 @@ HRESULT Update(
|
|||||||
const CSolidGroup &group = groups[groupIndex];
|
const CSolidGroup &group = groups[groupIndex];
|
||||||
|
|
||||||
CCompressionMethodMode method;
|
CCompressionMethodMode method;
|
||||||
|
#ifdef USE_86_FILTER
|
||||||
if (Is86Group(groupIndex))
|
if (Is86Group(groupIndex))
|
||||||
MakeExeMethod(*options.Method, options.MaxFilter, method);
|
MakeExeMethod(*options.Method, options.MaxFilter, method);
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
method = *options.Method;
|
method = *options.Method;
|
||||||
|
|
||||||
if (IsEncryptedGroup(groupIndex))
|
if (IsEncryptedGroup(groupIndex))
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ CFLAGS = $(CFLAGS) -I ../../../ \
|
|||||||
-DCOMPRESS_MT \
|
-DCOMPRESS_MT \
|
||||||
-DEXTERNAL_CODECS \
|
-DEXTERNAL_CODECS \
|
||||||
|
|
||||||
LIBS = $(LIBS) oleaut32.lib user32.lib
|
|
||||||
|
|
||||||
AR_OBJS = \
|
AR_OBJS = \
|
||||||
$O\ArchiveExports.obj \
|
$O\ArchiveExports.obj \
|
||||||
$O\DllExports.obj \
|
$O\DllExports.obj \
|
||||||
|
|||||||
@@ -10,11 +10,17 @@
|
|||||||
|
|
||||||
static const unsigned int kNumArcsMax = 48;
|
static const unsigned int kNumArcsMax = 48;
|
||||||
static unsigned int g_NumArcs = 0;
|
static unsigned int g_NumArcs = 0;
|
||||||
|
static unsigned int g_DefaultArcIndex = 0;
|
||||||
static const CArcInfo *g_Arcs[kNumArcsMax];
|
static const CArcInfo *g_Arcs[kNumArcsMax];
|
||||||
void RegisterArc(const CArcInfo *arcInfo)
|
void RegisterArc(const CArcInfo *arcInfo)
|
||||||
{
|
{
|
||||||
if (g_NumArcs < kNumArcsMax)
|
if (g_NumArcs < kNumArcsMax)
|
||||||
|
{
|
||||||
|
const wchar_t *p = arcInfo->Name;
|
||||||
|
if (p[0] == '7' && p[1] == 'z' && p[2] == 0)
|
||||||
|
g_DefaultArcIndex = g_NumArcs;
|
||||||
g_Arcs[g_NumArcs++] = arcInfo;
|
g_Arcs[g_NumArcs++] = arcInfo;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_GUID(CLSID_CArchiveHandler,
|
DEFINE_GUID(CLSID_CArchiveHandler,
|
||||||
@@ -117,7 +123,7 @@ STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value
|
|||||||
|
|
||||||
STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
|
STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
|
||||||
{
|
{
|
||||||
return GetHandlerProperty2(0, propID, value);
|
return GetHandlerProperty2(g_DefaultArcIndex, propID, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
STDAPI GetNumberOfFormats(UINT32 *numFormats)
|
STDAPI GetNumberOfFormats(UINT32 *numFormats)
|
||||||
|
|||||||
@@ -652,13 +652,12 @@ STDMETHODIMP CHandler::Close()
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
Int32 testModeSpec, IArchiveExtractCallback *extractCallback)
|
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
bool testMode = (testModeSpec != 0);
|
|
||||||
UInt64 totalUnpacked = 0, totalPacked = 0;
|
UInt64 totalUnpacked = 0, totalPacked = 0;
|
||||||
bool allFilesMode = (numItems == UInt32(-1));
|
bool allFilesMode = (numItems == (UInt32)-1);
|
||||||
if (allFilesMode)
|
if (allFilesMode)
|
||||||
numItems = _items.Size();
|
numItems = _items.Size();
|
||||||
if (numItems == 0)
|
if (numItems == 0)
|
||||||
@@ -714,7 +713,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!testMode && (!realOutStream))
|
if (!testMode && !realOutStream)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
|
|||||||
@@ -154,28 +154,23 @@ STDMETHODIMP CHandler::Close()
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
bool allFilesMode = (numItems == (UInt32)-1);
|
|
||||||
if (!allFilesMode)
|
|
||||||
{
|
|
||||||
if (numItems == 0)
|
if (numItems == 0)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
if (numItems != 1 || indices[0] != 0)
|
if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0))
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
}
|
|
||||||
|
|
||||||
bool testMode = (_aTestMode != 0);
|
|
||||||
if (_stream)
|
if (_stream)
|
||||||
extractCallback->SetTotal(_packSize);
|
extractCallback->SetTotal(_packSize);
|
||||||
UInt64 currentTotalPacked = 0;
|
UInt64 currentTotalPacked = 0;
|
||||||
RINOK(extractCallback->SetCompleted(¤tTotalPacked));
|
RINOK(extractCallback->SetCompleted(¤tTotalPacked));
|
||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
Int32 askMode = testMode ?
|
Int32 askMode = testMode ?
|
||||||
NArchive::NExtract::NAskMode::kTest :
|
NExtract::NAskMode::kTest :
|
||||||
NArchive::NExtract::NAskMode::kExtract;
|
NExtract::NAskMode::kExtract;
|
||||||
RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
|
RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
|
||||||
if (!testMode && !realOutStream)
|
if (!testMode && !realOutStream)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
@@ -421,7 +416,7 @@ static IOutArchive *CreateArcOut() { return new CHandler; }
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static CArcInfo g_ArcInfo =
|
static CArcInfo g_ArcInfo =
|
||||||
{ L"BZip2", L"bz2 bzip2 tbz2 tbz", L"* * .tar .tar", 2, { 'B', 'Z', 'h' }, 3, true, CreateArc, CreateArcOut };
|
{ L"bzip2", L"bz2 bzip2 tbz2 tbz", L"* * .tar .tar", 2, { 'B', 'Z', 'h' }, 3, true, CreateArc, CreateArcOut };
|
||||||
|
|
||||||
REGISTER_ARC(BZip2)
|
REGISTER_ARC(BZip2)
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
#include "Common/Buffer.h"
|
||||||
#include "Common/ComTry.h"
|
#include "Common/ComTry.h"
|
||||||
#include "Common/Defs.h"
|
#include "Common/Defs.h"
|
||||||
#include "Common/IntToString.h"
|
#include "Common/IntToString.h"
|
||||||
@@ -12,6 +13,7 @@
|
|||||||
#include "Windows/Time.h"
|
#include "Windows/Time.h"
|
||||||
|
|
||||||
#include "../../Common/ProgressUtils.h"
|
#include "../../Common/ProgressUtils.h"
|
||||||
|
#include "../../Common/StreamUtils.h"
|
||||||
|
|
||||||
#include "../../Compress/CopyCoder.h"
|
#include "../../Compress/CopyCoder.h"
|
||||||
#include "../../Compress/DeflateDecoder.h"
|
#include "../../Compress/DeflateDecoder.h"
|
||||||
@@ -30,6 +32,8 @@ namespace NCab {
|
|||||||
|
|
||||||
// #define _CAB_DETAILS
|
// #define _CAB_DETAILS
|
||||||
|
|
||||||
|
static const UInt32 kMaxTempBufSize = 1 << 20;
|
||||||
|
|
||||||
#ifdef _CAB_DETAILS
|
#ifdef _CAB_DETAILS
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@@ -279,7 +283,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
|||||||
{
|
{
|
||||||
const CInArchiveInfo &ai = m_Database.Volumes.Front().ArchiveInfo;
|
const CInArchiveInfo &ai = m_Database.Volumes.Front().ArchiveInfo;
|
||||||
if (ai.IsTherePrev())
|
if (ai.IsTherePrev())
|
||||||
otherArchive = &ai.PreviousArchive;
|
otherArchive = &ai.PrevArc;
|
||||||
else
|
else
|
||||||
prevChecked = true;
|
prevChecked = true;
|
||||||
}
|
}
|
||||||
@@ -287,7 +291,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
|||||||
{
|
{
|
||||||
const CInArchiveInfo &ai = m_Database.Volumes.Back().ArchiveInfo;
|
const CInArchiveInfo &ai = m_Database.Volumes.Back().ArchiveInfo;
|
||||||
if (ai.IsThereNext())
|
if (ai.IsThereNext())
|
||||||
otherArchive = &ai.NextArchive;
|
otherArchive = &ai.NextArc;
|
||||||
}
|
}
|
||||||
if (!otherArchive)
|
if (!otherArchive)
|
||||||
break;
|
break;
|
||||||
@@ -328,7 +332,7 @@ STDMETHODIMP CHandler::Close()
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
class CCabFolderOutStream:
|
class CFolderOutStream:
|
||||||
public ISequentialOutStream,
|
public ISequentialOutStream,
|
||||||
public CMyUnknownImp
|
public CMyUnknownImp
|
||||||
{
|
{
|
||||||
@@ -339,6 +343,12 @@ public:
|
|||||||
private:
|
private:
|
||||||
const CMvDatabaseEx *m_Database;
|
const CMvDatabaseEx *m_Database;
|
||||||
const CRecordVector<bool> *m_ExtractStatuses;
|
const CRecordVector<bool> *m_ExtractStatuses;
|
||||||
|
|
||||||
|
CByteBuffer TempBuf;
|
||||||
|
bool TempBufMode;
|
||||||
|
bool IsSupported;
|
||||||
|
UInt32 m_BufStartFolderOffset;
|
||||||
|
|
||||||
int m_StartIndex;
|
int m_StartIndex;
|
||||||
int m_CurrentIndex;
|
int m_CurrentIndex;
|
||||||
CMyComPtr<IArchiveExtractCallback> m_ExtractCallback;
|
CMyComPtr<IArchiveExtractCallback> m_ExtractCallback;
|
||||||
@@ -348,11 +358,12 @@ private:
|
|||||||
|
|
||||||
bool m_IsOk;
|
bool m_IsOk;
|
||||||
bool m_FileIsOpen;
|
bool m_FileIsOpen;
|
||||||
UInt64 m_RemainFileSize;
|
UInt32 m_RemainFileSize;
|
||||||
UInt64 m_FolderSize;
|
UInt64 m_FolderSize;
|
||||||
UInt64 m_PosInFolder;
|
UInt64 m_PosInFolder;
|
||||||
|
|
||||||
HRESULT OpenFile();
|
HRESULT OpenFile();
|
||||||
|
HRESULT CloseFile();
|
||||||
HRESULT Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK);
|
HRESULT Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK);
|
||||||
public:
|
public:
|
||||||
HRESULT WriteEmptyFiles();
|
HRESULT WriteEmptyFiles();
|
||||||
@@ -371,7 +382,7 @@ public:
|
|||||||
UInt64 GetPosInFolder() const { return m_PosInFolder; }
|
UInt64 GetPosInFolder() const { return m_PosInFolder; }
|
||||||
};
|
};
|
||||||
|
|
||||||
void CCabFolderOutStream::Init(
|
void CFolderOutStream::Init(
|
||||||
const CMvDatabaseEx *database,
|
const CMvDatabaseEx *database,
|
||||||
const CRecordVector<bool> *extractStatuses,
|
const CRecordVector<bool> *extractStatuses,
|
||||||
int startIndex,
|
int startIndex,
|
||||||
@@ -391,25 +402,66 @@ void CCabFolderOutStream::Init(
|
|||||||
m_PosInFolder = 0;
|
m_PosInFolder = 0;
|
||||||
m_FileIsOpen = false;
|
m_FileIsOpen = false;
|
||||||
m_IsOk = true;
|
m_IsOk = true;
|
||||||
|
TempBufMode = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CCabFolderOutStream::OpenFile()
|
HRESULT CFolderOutStream::CloseFile()
|
||||||
|
{
|
||||||
|
m_RealOutStream.Release();
|
||||||
|
HRESULT res = m_ExtractCallback->SetOperationResult(m_IsOk ?
|
||||||
|
NExtract::NOperationResult::kOK:
|
||||||
|
NExtract::NOperationResult::kDataError);
|
||||||
|
m_FileIsOpen = false;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CFolderOutStream::OpenFile()
|
||||||
{
|
{
|
||||||
Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? (m_TestMode ?
|
Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? (m_TestMode ?
|
||||||
NExtract::NAskMode::kTest :
|
NExtract::NAskMode::kTest :
|
||||||
NExtract::NAskMode::kExtract) :
|
NExtract::NAskMode::kExtract) :
|
||||||
NExtract::NAskMode::kSkip;
|
NExtract::NAskMode::kSkip;
|
||||||
|
|
||||||
|
if (!TempBufMode)
|
||||||
|
{
|
||||||
|
const CMvItem &mvItem = m_Database->Items[m_StartIndex + m_CurrentIndex];
|
||||||
|
const CItem &item = m_Database->Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
|
||||||
|
int curIndex = m_CurrentIndex + 1;
|
||||||
|
for (; curIndex < m_ExtractStatuses->Size(); curIndex++)
|
||||||
|
if ((*m_ExtractStatuses)[curIndex])
|
||||||
|
{
|
||||||
|
const CMvItem &mvItem2 = m_Database->Items[m_StartIndex + curIndex];
|
||||||
|
const CItem &item2 = m_Database->Volumes[mvItem2.VolumeIndex].Items[mvItem2.ItemIndex];
|
||||||
|
if (item.Offset != item2.Offset ||
|
||||||
|
item.Size != item2.Size ||
|
||||||
|
item.Size == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (curIndex > m_CurrentIndex + 1)
|
||||||
|
{
|
||||||
|
size_t oldCapacity = TempBuf.GetCapacity();
|
||||||
|
IsSupported = (item.Size <= kMaxTempBufSize);
|
||||||
|
if (item.Size > oldCapacity && IsSupported)
|
||||||
|
{
|
||||||
|
TempBuf.SetCapacity(0);
|
||||||
|
TempBuf.SetCapacity(item.Size);
|
||||||
|
}
|
||||||
|
TempBufMode = true;
|
||||||
|
m_BufStartFolderOffset = item.Offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RINOK(m_ExtractCallback->GetStream(m_StartIndex + m_CurrentIndex, &m_RealOutStream, askMode));
|
RINOK(m_ExtractCallback->GetStream(m_StartIndex + m_CurrentIndex, &m_RealOutStream, askMode));
|
||||||
if (!m_RealOutStream && !m_TestMode)
|
if (!m_RealOutStream && !m_TestMode)
|
||||||
askMode = NArchive::NExtract::NAskMode::kSkip;
|
askMode = NExtract::NAskMode::kSkip;
|
||||||
return m_ExtractCallback->PrepareOperation(askMode);
|
return m_ExtractCallback->PrepareOperation(askMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CCabFolderOutStream::WriteEmptyFiles()
|
HRESULT CFolderOutStream::WriteEmptyFiles()
|
||||||
{
|
{
|
||||||
if (m_FileIsOpen)
|
if (m_FileIsOpen)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
for(;m_CurrentIndex < m_ExtractStatuses->Size(); m_CurrentIndex++)
|
for (; m_CurrentIndex < m_ExtractStatuses->Size(); m_CurrentIndex++)
|
||||||
{
|
{
|
||||||
const CMvItem &mvItem = m_Database->Items[m_StartIndex + m_CurrentIndex];
|
const CMvItem &mvItem = m_Database->Items[m_StartIndex + m_CurrentIndex];
|
||||||
const CItem &item = m_Database->Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
|
const CItem &item = m_Database->Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
|
||||||
@@ -419,22 +471,23 @@ HRESULT CCabFolderOutStream::WriteEmptyFiles()
|
|||||||
HRESULT result = OpenFile();
|
HRESULT result = OpenFile();
|
||||||
m_RealOutStream.Release();
|
m_RealOutStream.Release();
|
||||||
RINOK(result);
|
RINOK(result);
|
||||||
RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
RINOK(m_ExtractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is Write function
|
// This is Write function
|
||||||
HRESULT CCabFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK)
|
HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK)
|
||||||
{
|
{
|
||||||
|
COM_TRY_BEGIN
|
||||||
UInt32 realProcessed = 0;
|
UInt32 realProcessed = 0;
|
||||||
if (processedSize != NULL)
|
if (processedSize != NULL)
|
||||||
*processedSize = 0;
|
*processedSize = 0;
|
||||||
while(size != 0)
|
while (size != 0)
|
||||||
{
|
{
|
||||||
if (m_FileIsOpen)
|
if (m_FileIsOpen)
|
||||||
{
|
{
|
||||||
UInt32 numBytesToWrite = (UInt32)MyMin(m_RemainFileSize, (UInt64)(size));
|
UInt32 numBytesToWrite = MyMin(m_RemainFileSize, size);
|
||||||
HRESULT res = S_OK;
|
HRESULT res = S_OK;
|
||||||
if (numBytesToWrite > 0)
|
if (numBytesToWrite > 0)
|
||||||
{
|
{
|
||||||
@@ -446,6 +499,8 @@ HRESULT CCabFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *proce
|
|||||||
res = m_RealOutStream->Write((const Byte *)data, numBytesToWrite, &processedSizeLocal);
|
res = m_RealOutStream->Write((const Byte *)data, numBytesToWrite, &processedSizeLocal);
|
||||||
numBytesToWrite = processedSizeLocal;
|
numBytesToWrite = processedSizeLocal;
|
||||||
}
|
}
|
||||||
|
if (TempBufMode && IsSupported)
|
||||||
|
memcpy(TempBuf + (m_PosInFolder - m_BufStartFolderOffset), data, numBytesToWrite);
|
||||||
}
|
}
|
||||||
realProcessed += numBytesToWrite;
|
realProcessed += numBytesToWrite;
|
||||||
if (processedSize != NULL)
|
if (processedSize != NULL)
|
||||||
@@ -459,12 +514,38 @@ HRESULT CCabFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *proce
|
|||||||
if (m_RemainFileSize == 0)
|
if (m_RemainFileSize == 0)
|
||||||
{
|
{
|
||||||
m_RealOutStream.Release();
|
m_RealOutStream.Release();
|
||||||
RINOK(m_ExtractCallback->SetOperationResult(
|
RINOK(CloseFile());
|
||||||
m_IsOk ?
|
|
||||||
NArchive::NExtract::NOperationResult::kOK:
|
if (TempBufMode)
|
||||||
NArchive::NExtract::NOperationResult::kDataError));
|
{
|
||||||
|
while (m_CurrentIndex < m_ExtractStatuses->Size())
|
||||||
|
{
|
||||||
|
const CMvItem &mvItem = m_Database->Items[m_StartIndex + m_CurrentIndex];
|
||||||
|
const CItem &item = m_Database->Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
|
||||||
|
if (item.Offset != m_BufStartFolderOffset)
|
||||||
|
break;
|
||||||
|
HRESULT result = OpenFile();
|
||||||
|
m_FileIsOpen = true;
|
||||||
|
m_CurrentIndex++;
|
||||||
|
m_IsOk = true;
|
||||||
|
if (result == S_OK && m_RealOutStream && IsSupported)
|
||||||
|
result = WriteStream(m_RealOutStream, TempBuf, item.Size);
|
||||||
|
|
||||||
|
if (IsSupported)
|
||||||
|
{
|
||||||
|
RINOK(CloseFile());
|
||||||
|
RINOK(result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_RealOutStream.Release();
|
||||||
|
RINOK(m_ExtractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod));
|
||||||
m_FileIsOpen = false;
|
m_FileIsOpen = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
TempBufMode = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (realProcessed > 0)
|
if (realProcessed > 0)
|
||||||
break; // with this break this function works as Write-Part
|
break; // with this break this function works as Write-Part
|
||||||
}
|
}
|
||||||
@@ -483,7 +564,7 @@ HRESULT CCabFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *proce
|
|||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
if (fileOffset > m_PosInFolder)
|
if (fileOffset > m_PosInFolder)
|
||||||
{
|
{
|
||||||
UInt32 numBytesToWrite = (UInt32)MyMin((UInt64)fileOffset - m_PosInFolder, UInt64(size));
|
UInt32 numBytesToWrite = MyMin(fileOffset - (UInt32)m_PosInFolder, size);
|
||||||
realProcessed += numBytesToWrite;
|
realProcessed += numBytesToWrite;
|
||||||
if (processedSize != NULL)
|
if (processedSize != NULL)
|
||||||
*processedSize = realProcessed;
|
*processedSize = realProcessed;
|
||||||
@@ -501,14 +582,15 @@ HRESULT CCabFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *proce
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return WriteEmptyFiles();
|
return WriteEmptyFiles();
|
||||||
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CCabFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||||||
{
|
{
|
||||||
return Write2(data, size, processedSize, true);
|
return Write2(data, size, processedSize, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CCabFolderOutStream::FlushCorrupted()
|
HRESULT CFolderOutStream::FlushCorrupted()
|
||||||
{
|
{
|
||||||
const UInt32 kBufferSize = (1 << 10);
|
const UInt32 kBufferSize = (1 << 10);
|
||||||
Byte buffer[kBufferSize];
|
Byte buffer[kBufferSize];
|
||||||
@@ -525,7 +607,7 @@ HRESULT CCabFolderOutStream::FlushCorrupted()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CCabFolderOutStream::Unsupported()
|
HRESULT CFolderOutStream::Unsupported()
|
||||||
{
|
{
|
||||||
while(m_CurrentIndex < m_ExtractStatuses->Size())
|
while(m_CurrentIndex < m_ExtractStatuses->Size())
|
||||||
{
|
{
|
||||||
@@ -533,23 +615,23 @@ HRESULT CCabFolderOutStream::Unsupported()
|
|||||||
if (result != S_FALSE && result != S_OK)
|
if (result != S_FALSE && result != S_OK)
|
||||||
return result;
|
return result;
|
||||||
m_RealOutStream.Release();
|
m_RealOutStream.Release();
|
||||||
RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
RINOK(m_ExtractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod));
|
||||||
m_CurrentIndex++;
|
m_CurrentIndex++;
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
Int32 testModeSpec, IArchiveExtractCallback *extractCallback)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
bool allFilesMode = (numItems == (UInt32)(-1));
|
bool allFilesMode = (numItems == (UInt32)-1);
|
||||||
if (allFilesMode)
|
if (allFilesMode)
|
||||||
numItems = m_Database.Items.Size();
|
numItems = m_Database.Items.Size();
|
||||||
if(numItems == 0)
|
if(numItems == 0)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
bool testMode = (_aTestMode != 0);
|
bool testMode = (testModeSpec != 0);
|
||||||
UInt64 totalUnPacked = 0;
|
UInt64 totalUnPacked = 0;
|
||||||
|
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
@@ -610,14 +692,14 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
i++;
|
i++;
|
||||||
if (item.IsDir())
|
if (item.IsDir())
|
||||||
{
|
{
|
||||||
Int32 askMode= testMode ?
|
Int32 askMode = testMode ?
|
||||||
NArchive::NExtract::NAskMode::kTest :
|
NExtract::NAskMode::kTest :
|
||||||
NArchive::NExtract::NAskMode::kExtract;
|
NExtract::NAskMode::kExtract;
|
||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
realOutStream.Release();
|
realOutStream.Release();
|
||||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int folderIndex = m_Database.GetFolderIndex(&mvItem);
|
int folderIndex = m_Database.GetFolderIndex(&mvItem);
|
||||||
@@ -625,13 +707,13 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
{
|
{
|
||||||
// If we need previous archive
|
// If we need previous archive
|
||||||
Int32 askMode= testMode ?
|
Int32 askMode= testMode ?
|
||||||
NArchive::NExtract::NAskMode::kTest :
|
NExtract::NAskMode::kTest :
|
||||||
NArchive::NExtract::NAskMode::kExtract;
|
NExtract::NAskMode::kExtract;
|
||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
realOutStream.Release();
|
realOutStream.Release();
|
||||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError));
|
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kDataError));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int startIndex2 = m_Database.FolderStartFileIndex[folderIndex];
|
int startIndex2 = m_Database.FolderStartFileIndex[folderIndex];
|
||||||
@@ -664,7 +746,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
lps->InSize = totalPacked;
|
lps->InSize = totalPacked;
|
||||||
RINOK(lps->SetCur());
|
RINOK(lps->SetCur());
|
||||||
|
|
||||||
CCabFolderOutStream *cabFolderOutStream = new CCabFolderOutStream;
|
CFolderOutStream *cabFolderOutStream = new CFolderOutStream;
|
||||||
CMyComPtr<ISequentialOutStream> outStream(cabFolderOutStream);
|
CMyComPtr<ISequentialOutStream> outStream(cabFolderOutStream);
|
||||||
|
|
||||||
const CFolder &folder = db.Folders[item.GetFolderIndex(db.Folders.Size())];
|
const CFolder &folder = db.Folders[item.GetFolderIndex(db.Folders.Size())];
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
// Archive/Cab/Header.h
|
// CabHeader.cpp
|
||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
#include "CabHeader.h"
|
#include "CabHeader.h"
|
||||||
|
|
||||||
namespace NArchive{
|
namespace NArchive {
|
||||||
namespace NCab{
|
namespace NCab {
|
||||||
namespace NHeader{
|
namespace NHeader {
|
||||||
|
|
||||||
Byte kMarker[kMarkerSize] = {'M' + 1, 'S', 'C', 'F', 0, 0, 0, 0 };
|
Byte kMarker[kMarkerSize] = {'M', 'S', 'C', 'F', 0, 0, 0, 0 };
|
||||||
|
|
||||||
struct SignatureInitializer { SignatureInitializer() { kMarker[0]--; }; } g_SignatureInitializer;
|
// struct CSignatureInitializer { CSignatureInitializer() { kMarker[0]--; }; } g_SignatureInitializer;
|
||||||
|
|
||||||
}}}
|
}}}
|
||||||
|
|||||||
@@ -2,14 +2,14 @@
|
|||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
#include "CabIn.h"
|
|
||||||
|
|
||||||
#include "../Common/FindSignature.h"
|
#include "../Common/FindSignature.h"
|
||||||
|
|
||||||
|
#include "CabIn.h"
|
||||||
|
|
||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace NCab {
|
namespace NCab {
|
||||||
|
|
||||||
Byte CInArchive::ReadByte()
|
Byte CInArchive::Read8()
|
||||||
{
|
{
|
||||||
Byte b;
|
Byte b;
|
||||||
if (!inBuffer.ReadByte(b))
|
if (!inBuffer.ReadByte(b))
|
||||||
@@ -17,23 +17,23 @@ Byte CInArchive::ReadByte()
|
|||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt16 CInArchive::ReadUInt16()
|
UInt16 CInArchive::Read16()
|
||||||
{
|
{
|
||||||
UInt16 value = 0;
|
UInt16 value = 0;
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
Byte b = ReadByte();
|
Byte b = Read8();
|
||||||
value |= (UInt16(b) << (8 * i));
|
value |= (UInt16(b) << (8 * i));
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt32 CInArchive::ReadUInt32()
|
UInt32 CInArchive::Read32()
|
||||||
{
|
{
|
||||||
UInt32 value = 0;
|
UInt32 value = 0;
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
Byte b = ReadByte();
|
Byte b = Read8();
|
||||||
value |= (UInt32(b) << (8 * i));
|
value |= (UInt32(b) << (8 * i));
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
@@ -44,7 +44,7 @@ AString CInArchive::SafeReadName()
|
|||||||
AString name;
|
AString name;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
Byte b = ReadByte();
|
Byte b = Read8();
|
||||||
if (b == 0)
|
if (b == 0)
|
||||||
return name;
|
return name;
|
||||||
name += (char)b;
|
name += (char)b;
|
||||||
@@ -57,61 +57,60 @@ void CInArchive::ReadOtherArchive(COtherArchive &oa)
|
|||||||
oa.DiskName = SafeReadName();
|
oa.DiskName = SafeReadName();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CInArchive::Skip(size_t size)
|
void CInArchive::Skip(UInt32 size)
|
||||||
{
|
{
|
||||||
while (size-- != 0)
|
while (size-- != 0)
|
||||||
ReadByte();
|
Read8();
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CInArchive::Open2(IInStream *stream,
|
HRESULT CInArchive::Open(const UInt64 *searchHeaderSizeLimit, CDatabaseEx &db)
|
||||||
const UInt64 *searchHeaderSizeLimit,
|
|
||||||
CDatabase &database)
|
|
||||||
{
|
{
|
||||||
database.Clear();
|
IInStream *stream = db.Stream;
|
||||||
RINOK(stream->Seek(0, STREAM_SEEK_SET, &database.StartPosition));
|
db.Clear();
|
||||||
|
RINOK(stream->Seek(0, STREAM_SEEK_SET, &db.StartPosition));
|
||||||
|
|
||||||
RINOK(FindSignatureInStream(stream, NHeader::kMarker, NHeader::kMarkerSize,
|
RINOK(FindSignatureInStream(stream, NHeader::kMarker, NHeader::kMarkerSize,
|
||||||
searchHeaderSizeLimit, database.StartPosition));
|
searchHeaderSizeLimit, db.StartPosition));
|
||||||
|
|
||||||
RINOK(stream->Seek(database.StartPosition + NHeader::kMarkerSize, STREAM_SEEK_SET, NULL));
|
RINOK(stream->Seek(db.StartPosition + NHeader::kMarkerSize, STREAM_SEEK_SET, NULL));
|
||||||
if (!inBuffer.Create(1 << 17))
|
if (!inBuffer.Create(1 << 17))
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
inBuffer.SetStream(stream);
|
inBuffer.SetStream(stream);
|
||||||
inBuffer.Init();
|
inBuffer.Init();
|
||||||
|
|
||||||
CInArchiveInfo &ai = database.ArchiveInfo;
|
CInArchiveInfo &ai = db.ArchiveInfo;
|
||||||
|
|
||||||
ai.Size = ReadUInt32();
|
ai.Size = Read32();
|
||||||
if (ReadUInt32() != 0)
|
if (Read32() != 0)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
ai.FileHeadersOffset = ReadUInt32();
|
ai.FileHeadersOffset = Read32();
|
||||||
if (ReadUInt32() != 0)
|
if (Read32() != 0)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
|
||||||
ai.VersionMinor = ReadByte();
|
ai.VersionMinor = Read8();
|
||||||
ai.VersionMajor = ReadByte();
|
ai.VersionMajor = Read8();
|
||||||
ai.NumFolders = ReadUInt16();
|
ai.NumFolders = Read16();
|
||||||
ai.NumFiles = ReadUInt16();
|
ai.NumFiles = Read16();
|
||||||
ai.Flags = ReadUInt16();
|
ai.Flags = Read16();
|
||||||
if (ai.Flags > 7)
|
if (ai.Flags > 7)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
ai.SetID = ReadUInt16();
|
ai.SetID = Read16();
|
||||||
ai.CabinetNumber = ReadUInt16();
|
ai.CabinetNumber = Read16();
|
||||||
|
|
||||||
if (ai.ReserveBlockPresent())
|
if (ai.ReserveBlockPresent())
|
||||||
{
|
{
|
||||||
ai.PerCabinetAreaSize = ReadUInt16();
|
ai.PerCabinetAreaSize = Read16();
|
||||||
ai.PerFolderAreaSize = ReadByte();
|
ai.PerFolderAreaSize = Read8();
|
||||||
ai.PerDataBlockAreaSize = ReadByte();
|
ai.PerDataBlockAreaSize = Read8();
|
||||||
|
|
||||||
Skip(ai.PerCabinetAreaSize);
|
Skip(ai.PerCabinetAreaSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
if (ai.IsTherePrev())
|
if (ai.IsTherePrev())
|
||||||
ReadOtherArchive(ai.PreviousArchive);
|
ReadOtherArchive(ai.PrevArc);
|
||||||
if (ai.IsThereNext())
|
if (ai.IsThereNext())
|
||||||
ReadOtherArchive(ai.NextArchive);
|
ReadOtherArchive(ai.NextArc);
|
||||||
}
|
}
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
@@ -119,54 +118,40 @@ HRESULT CInArchive::Open2(IInStream *stream,
|
|||||||
{
|
{
|
||||||
CFolder folder;
|
CFolder folder;
|
||||||
|
|
||||||
folder.DataStart = ReadUInt32();
|
folder.DataStart = Read32();
|
||||||
folder.NumDataBlocks = ReadUInt16();
|
folder.NumDataBlocks = Read16();
|
||||||
folder.CompressionTypeMajor = ReadByte();
|
folder.CompressionTypeMajor = Read8();
|
||||||
folder.CompressionTypeMinor = ReadByte();
|
folder.CompressionTypeMinor = Read8();
|
||||||
|
|
||||||
Skip(ai.PerFolderAreaSize);
|
Skip(ai.PerFolderAreaSize);
|
||||||
database.Folders.Add(folder);
|
db.Folders.Add(folder);
|
||||||
}
|
}
|
||||||
|
|
||||||
RINOK(stream->Seek(database.StartPosition + ai.FileHeadersOffset, STREAM_SEEK_SET, NULL));
|
RINOK(stream->Seek(db.StartPosition + ai.FileHeadersOffset, STREAM_SEEK_SET, NULL));
|
||||||
|
|
||||||
inBuffer.SetStream(stream);
|
inBuffer.SetStream(stream);
|
||||||
inBuffer.Init();
|
inBuffer.Init();
|
||||||
for (i = 0; i < ai.NumFiles; i++)
|
for (i = 0; i < ai.NumFiles; i++)
|
||||||
{
|
{
|
||||||
CItem item;
|
CItem item;
|
||||||
item.Size = ReadUInt32();
|
item.Size = Read32();
|
||||||
item.Offset = ReadUInt32();
|
item.Offset = Read32();
|
||||||
item.FolderIndex = ReadUInt16();
|
item.FolderIndex = Read16();
|
||||||
UInt16 pureDate = ReadUInt16();
|
UInt16 pureDate = Read16();
|
||||||
UInt16 pureTime = ReadUInt16();
|
UInt16 pureTime = Read16();
|
||||||
item.Time = ((UInt32(pureDate) << 16)) | pureTime;
|
item.Time = ((UInt32(pureDate) << 16)) | pureTime;
|
||||||
item.Attributes = ReadUInt16();
|
item.Attributes = Read16();
|
||||||
item.Name = SafeReadName();
|
item.Name = SafeReadName();
|
||||||
int folderIndex = item.GetFolderIndex(database.Folders.Size());
|
int folderIndex = item.GetFolderIndex(db.Folders.Size());
|
||||||
if (folderIndex >= database.Folders.Size())
|
if (folderIndex >= db.Folders.Size())
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
database.Items.Add(item);
|
db.Items.Add(item);
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
|
#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
|
||||||
|
|
||||||
HRESULT CInArchive::Open(
|
|
||||||
const UInt64 *searchHeaderSizeLimit,
|
|
||||||
CDatabaseEx &database)
|
|
||||||
{
|
|
||||||
return Open2(database.Stream, searchHeaderSizeLimit, database);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int CompareMvItems2(const CMvItem *p1, const CMvItem *p2)
|
|
||||||
{
|
|
||||||
RINOZ(MyCompare(p1->VolumeIndex, p2->VolumeIndex));
|
|
||||||
return MyCompare(p1->ItemIndex, p2->ItemIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int CompareMvItems(const CMvItem *p1, const CMvItem *p2, void *param)
|
static int CompareMvItems(const CMvItem *p1, const CMvItem *p2, void *param)
|
||||||
{
|
{
|
||||||
const CMvDatabaseEx &mvDb = *(const CMvDatabaseEx *)param;
|
const CMvDatabaseEx &mvDb = *(const CMvDatabaseEx *)param;
|
||||||
@@ -185,7 +170,8 @@ static int CompareMvItems(const CMvItem *p1, const CMvItem *p2, void *param)
|
|||||||
RINOZ(MyCompare(f1, f2));
|
RINOZ(MyCompare(f1, f2));
|
||||||
RINOZ(MyCompare(item1.Offset, item2.Offset));
|
RINOZ(MyCompare(item1.Offset, item2.Offset));
|
||||||
RINOZ(MyCompare(item1.Size, item2.Size));
|
RINOZ(MyCompare(item1.Size, item2.Size));
|
||||||
return CompareMvItems2(p1, p2);
|
RINOZ(MyCompare(p1->VolumeIndex, p2->VolumeIndex));
|
||||||
|
return MyCompare(p1->ItemIndex, p2->ItemIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CMvDatabaseEx::AreItemsEqual(int i1, int i2)
|
bool CMvDatabaseEx::AreItemsEqual(int i1, int i2)
|
||||||
@@ -236,8 +222,7 @@ void CMvDatabaseEx::FillSortAndShrink()
|
|||||||
|
|
||||||
for (i = 0; i < Items.Size(); i++)
|
for (i = 0; i < Items.Size(); i++)
|
||||||
{
|
{
|
||||||
const CMvItem &mvItem = Items[i];
|
int folderIndex = GetFolderIndex(&Items[i]);
|
||||||
int folderIndex = GetFolderIndex(&mvItem);
|
|
||||||
if (folderIndex >= FolderStartFileIndex.Size())
|
if (folderIndex >= FolderStartFileIndex.Size())
|
||||||
FolderStartFileIndex.Add(i);
|
FolderStartFileIndex.Add(i);
|
||||||
}
|
}
|
||||||
@@ -260,7 +245,8 @@ bool CMvDatabaseEx::Check()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UInt64 maxPos = 0;
|
UInt32 beginPos = 0;
|
||||||
|
UInt64 endPos = 0;
|
||||||
int prevFolder = -2;
|
int prevFolder = -2;
|
||||||
for (int i = 0; i < Items.Size(); i++)
|
for (int i = 0; i < Items.Size(); i++)
|
||||||
{
|
{
|
||||||
@@ -273,16 +259,12 @@ bool CMvDatabaseEx::Check()
|
|||||||
continue;
|
continue;
|
||||||
int folderIndex = GetFolderIndex(&mvItem);
|
int folderIndex = GetFolderIndex(&mvItem);
|
||||||
if (folderIndex != prevFolder)
|
if (folderIndex != prevFolder)
|
||||||
{
|
|
||||||
prevFolder = folderIndex;
|
prevFolder = folderIndex;
|
||||||
maxPos = 0;
|
else if (item.Offset < endPos &&
|
||||||
continue;
|
(item.Offset != beginPos || item.GetEndOffset() != endPos))
|
||||||
}
|
|
||||||
if (item.Offset < maxPos)
|
|
||||||
return false;
|
|
||||||
maxPos = item.GetEndOffset();
|
|
||||||
if (maxPos < item.Offset)
|
|
||||||
return false;
|
return false;
|
||||||
|
beginPos = item.Offset;
|
||||||
|
endPos = item.GetEndOffset();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,8 +50,8 @@ struct CArchiveInfo
|
|||||||
|
|
||||||
Byte GetDataBlockReserveSize() const { return (Byte)(ReserveBlockPresent() ? PerDataBlockAreaSize : 0); }
|
Byte GetDataBlockReserveSize() const { return (Byte)(ReserveBlockPresent() ? PerDataBlockAreaSize : 0); }
|
||||||
|
|
||||||
COtherArchive PreviousArchive;
|
COtherArchive PrevArc;
|
||||||
COtherArchive NextArchive;
|
COtherArchive NextArc;
|
||||||
|
|
||||||
CArchiveInfo()
|
CArchiveInfo()
|
||||||
{
|
{
|
||||||
@@ -73,13 +73,13 @@ struct CInArchiveInfo: public CArchiveInfo
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class CDatabase
|
struct CDatabase
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
UInt64 StartPosition;
|
UInt64 StartPosition;
|
||||||
CInArchiveInfo ArchiveInfo;
|
CInArchiveInfo ArchiveInfo;
|
||||||
CObjectVector<CFolder> Folders;
|
CObjectVector<CFolder> Folders;
|
||||||
CObjectVector<CItem> Items;
|
CObjectVector<CItem> Items;
|
||||||
|
|
||||||
void Clear()
|
void Clear()
|
||||||
{
|
{
|
||||||
ArchiveInfo.Clear();
|
ArchiveInfo.Clear();
|
||||||
@@ -104,9 +104,8 @@ public:
|
|||||||
UInt32 GetFileSize(int index) const { return Items[index].Size; }
|
UInt32 GetFileSize(int index) const { return Items[index].Size; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class CDatabaseEx: public CDatabase
|
struct CDatabaseEx: public CDatabase
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
CMyComPtr<IInStream> Stream;
|
CMyComPtr<IInStream> Stream;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -124,6 +123,7 @@ public:
|
|||||||
CRecordVector<CMvItem> Items;
|
CRecordVector<CMvItem> Items;
|
||||||
CRecordVector<int> StartFolderOfVol;
|
CRecordVector<int> StartFolderOfVol;
|
||||||
CRecordVector<int> FolderStartFileIndex;
|
CRecordVector<int> FolderStartFileIndex;
|
||||||
|
|
||||||
int GetFolderIndex(const CMvItem *mvi) const
|
int GetFolderIndex(const CMvItem *mvi) const
|
||||||
{
|
{
|
||||||
const CDatabaseEx &db = Volumes[mvi->VolumeIndex];
|
const CDatabaseEx &db = Volumes[mvi->VolumeIndex];
|
||||||
@@ -145,20 +145,15 @@ class CInArchive
|
|||||||
{
|
{
|
||||||
CInBuffer inBuffer;
|
CInBuffer inBuffer;
|
||||||
|
|
||||||
Byte ReadByte();
|
Byte Read8();
|
||||||
UInt16 ReadUInt16();
|
UInt16 Read16();
|
||||||
UInt32 ReadUInt32();
|
UInt32 Read32();
|
||||||
AString SafeReadName();
|
AString SafeReadName();
|
||||||
void Skip(size_t size);
|
void Skip(UInt32 size);
|
||||||
void ReadOtherArchive(COtherArchive &oa);
|
void ReadOtherArchive(COtherArchive &oa);
|
||||||
|
|
||||||
HRESULT Open2(IInStream *inStream,
|
|
||||||
const UInt64 *searchHeaderSizeLimit,
|
|
||||||
CDatabase &database);
|
|
||||||
public:
|
public:
|
||||||
HRESULT Open(
|
HRESULT Open(const UInt64 *searchHeaderSizeLimit, CDatabaseEx &db);
|
||||||
const UInt64 *searchHeaderSizeLimit,
|
|
||||||
CDatabaseEx &database);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -275,7 +275,7 @@ HRESULT CChmFolderOutStream::OpenFile()
|
|||||||
m_RealOutStream.Release();
|
m_RealOutStream.Release();
|
||||||
RINOK(m_ExtractCallback->GetStream(m_StartIndex + m_CurrentIndex, &m_RealOutStream, askMode));
|
RINOK(m_ExtractCallback->GetStream(m_StartIndex + m_CurrentIndex, &m_RealOutStream, askMode));
|
||||||
if (!m_RealOutStream && !m_TestMode)
|
if (!m_RealOutStream && !m_TestMode)
|
||||||
askMode = NArchive::NExtract::NAskMode::kSkip;
|
askMode = NExtract::NAskMode::kSkip;
|
||||||
return m_ExtractCallback->PrepareOperation(askMode);
|
return m_ExtractCallback->PrepareOperation(askMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,7 +291,7 @@ HRESULT CChmFolderOutStream::WriteEmptyFiles()
|
|||||||
HRESULT result = OpenFile();
|
HRESULT result = OpenFile();
|
||||||
m_RealOutStream.Release();
|
m_RealOutStream.Release();
|
||||||
RINOK(result);
|
RINOK(result);
|
||||||
RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
RINOK(m_ExtractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
@@ -334,8 +334,8 @@ HRESULT CChmFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *proce
|
|||||||
m_RealOutStream.Release();
|
m_RealOutStream.Release();
|
||||||
RINOK(m_ExtractCallback->SetOperationResult(
|
RINOK(m_ExtractCallback->SetOperationResult(
|
||||||
m_IsOk ?
|
m_IsOk ?
|
||||||
NArchive::NExtract::NOperationResult::kOK:
|
NExtract::NOperationResult::kOK:
|
||||||
NArchive::NExtract::NOperationResult::kDataError));
|
NExtract::NOperationResult::kDataError));
|
||||||
m_FileIsOpen = false;
|
m_FileIsOpen = false;
|
||||||
}
|
}
|
||||||
if (realProcessed > 0)
|
if (realProcessed > 0)
|
||||||
@@ -398,11 +398,11 @@ HRESULT CChmFolderOutStream::FlushCorrupted(UInt64 maxSize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
Int32 testModeSpec, IArchiveExtractCallback *extractCallback)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
bool allFilesMode = (numItems == UInt32(-1));
|
bool allFilesMode = (numItems == (UInt32)-1);
|
||||||
|
|
||||||
if (allFilesMode)
|
if (allFilesMode)
|
||||||
numItems = m_Database.NewFormat ? 1:
|
numItems = m_Database.NewFormat ? 1:
|
||||||
@@ -411,7 +411,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
m_Database.Indices.Size());
|
m_Database.Indices.Size());
|
||||||
if (numItems == 0)
|
if (numItems == 0)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
bool testMode = (_aTestMode != 0);
|
bool testMode = (testModeSpec != 0);
|
||||||
|
|
||||||
UInt64 currentTotalSize = 0;
|
UInt64 currentTotalSize = 0;
|
||||||
|
|
||||||
@@ -447,8 +447,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
RINOK(lps->SetCur());
|
RINOK(lps->SetCur());
|
||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
Int32 askMode= testMode ?
|
Int32 askMode= testMode ?
|
||||||
NArchive::NExtract::NAskMode::kTest :
|
NExtract::NAskMode::kTest :
|
||||||
NArchive::NExtract::NAskMode::kExtract;
|
NExtract::NAskMode::kExtract;
|
||||||
Int32 index = allFilesMode ? i : indices[i];
|
Int32 index = allFilesMode ? i : indices[i];
|
||||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||||
|
|
||||||
@@ -456,32 +456,32 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
{
|
{
|
||||||
if (index != 0)
|
if (index != 0)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
if (!testMode && (!realOutStream))
|
if (!testMode && !realOutStream)
|
||||||
continue;
|
continue;
|
||||||
if (!testMode)
|
if (!testMode)
|
||||||
{
|
{
|
||||||
UInt32 size = m_Database.NewFormatString.Length();
|
UInt32 size = m_Database.NewFormatString.Length();
|
||||||
RINOK(WriteStream(realOutStream, (const char *)m_Database.NewFormatString, size));
|
RINOK(WriteStream(realOutStream, (const char *)m_Database.NewFormatString, size));
|
||||||
}
|
}
|
||||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const CItem &item = m_Database.Items[index];
|
const CItem &item = m_Database.Items[index];
|
||||||
|
|
||||||
currentItemSize = item.Size;
|
currentItemSize = item.Size;
|
||||||
|
|
||||||
if (!testMode && (!realOutStream))
|
if (!testMode && !realOutStream)
|
||||||
continue;
|
continue;
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
if (item.Section != 0)
|
if (item.Section != 0)
|
||||||
{
|
{
|
||||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (testMode)
|
if (testMode)
|
||||||
{
|
{
|
||||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -491,8 +491,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
|
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
|
||||||
realOutStream.Release();
|
realOutStream.Release();
|
||||||
RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ?
|
RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ?
|
||||||
NArchive::NExtract::NOperationResult::kOK:
|
NExtract::NOperationResult::kOK:
|
||||||
NArchive::NExtract::NOperationResult::kDataError));
|
NExtract::NOperationResult::kDataError));
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
@@ -543,15 +543,15 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
const CItem &item = m_Database.Items[entryIndex];
|
const CItem &item = m_Database.Items[entryIndex];
|
||||||
UInt64 sectionIndex = item.Section;
|
UInt64 sectionIndex = item.Section;
|
||||||
Int32 askMode= testMode ?
|
Int32 askMode= testMode ?
|
||||||
NArchive::NExtract::NAskMode::kTest :
|
NExtract::NAskMode::kTest :
|
||||||
NArchive::NExtract::NAskMode::kExtract;
|
NExtract::NAskMode::kExtract;
|
||||||
if (item.IsDir())
|
if (item.IsDir())
|
||||||
{
|
{
|
||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
realOutStream.Release();
|
realOutStream.Release();
|
||||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -562,17 +562,17 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
{
|
{
|
||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||||
if (!testMode && (!realOutStream))
|
if (!testMode && !realOutStream)
|
||||||
continue;
|
continue;
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
Int32 opRes = NArchive::NExtract::NOperationResult::kOK;
|
Int32 opRes = NExtract::NOperationResult::kOK;
|
||||||
if (!testMode && item.Size != 0)
|
if (!testMode && item.Size != 0)
|
||||||
{
|
{
|
||||||
RINOK(m_Stream->Seek(m_Database.ContentOffset + item.Offset, STREAM_SEEK_SET, NULL));
|
RINOK(m_Stream->Seek(m_Database.ContentOffset + item.Offset, STREAM_SEEK_SET, NULL));
|
||||||
streamSpec->Init(item.Size);
|
streamSpec->Init(item.Size);
|
||||||
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
|
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
|
||||||
if (copyCoderSpec->TotalSize != item.Size)
|
if (copyCoderSpec->TotalSize != item.Size)
|
||||||
opRes = NArchive::NExtract::NOperationResult::kDataError;
|
opRes = NExtract::NOperationResult::kDataError;
|
||||||
}
|
}
|
||||||
realOutStream.Release();
|
realOutStream.Release();
|
||||||
RINOK(extractCallback->SetOperationResult(opRes));
|
RINOK(extractCallback->SetOperationResult(opRes));
|
||||||
@@ -586,10 +586,10 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
{
|
{
|
||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||||
if(!testMode && (!realOutStream))
|
if (!testMode && !realOutStream)
|
||||||
continue;
|
continue;
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -603,7 +603,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
|
|
||||||
chmFolderOutStream->Init(&m_Database, extractCallback, testMode);
|
chmFolderOutStream->Init(&m_Database, extractCallback, testMode);
|
||||||
|
|
||||||
if(lzxDecoderSpec == NULL)
|
if (lzxDecoderSpec == NULL)
|
||||||
{
|
{
|
||||||
lzxDecoderSpec = new NCompress::NLzx::CDecoder;
|
lzxDecoderSpec = new NCompress::NLzx::CDecoder;
|
||||||
lzxDecoder = lzxDecoderSpec;
|
lzxDecoder = lzxDecoderSpec;
|
||||||
|
|||||||
@@ -95,12 +95,11 @@ STDMETHODIMP CHandler::Close()
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
bool testMode = (_aTestMode != 0);
|
bool allFilesMode = (numItems == (UInt32)-1);
|
||||||
bool allFilesMode = (numItems == UInt32(-1));
|
|
||||||
if (allFilesMode)
|
if (allFilesMode)
|
||||||
numItems = _db.Refs.Size();
|
numItems = _db.Refs.Size();
|
||||||
if (numItems == 0)
|
if (numItems == 0)
|
||||||
@@ -135,30 +134,30 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
|
|
||||||
CMyComPtr<ISequentialOutStream> outStream;
|
CMyComPtr<ISequentialOutStream> outStream;
|
||||||
Int32 askMode = testMode ?
|
Int32 askMode = testMode ?
|
||||||
NArchive::NExtract::NAskMode::kTest :
|
NExtract::NAskMode::kTest :
|
||||||
NArchive::NExtract::NAskMode::kExtract;
|
NExtract::NAskMode::kExtract;
|
||||||
RINOK(extractCallback->GetStream(index, &outStream, askMode));
|
RINOK(extractCallback->GetStream(index, &outStream, askMode));
|
||||||
|
|
||||||
if (item.IsDir())
|
if (item.IsDir())
|
||||||
{
|
{
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
totalPackSize += _db.GetItemPackSize(item.Size);
|
totalPackSize += _db.GetItemPackSize(item.Size);
|
||||||
totalSize += item.Size;
|
totalSize += item.Size;
|
||||||
|
|
||||||
if (!testMode && (!outStream))
|
if (!testMode && !outStream)
|
||||||
continue;
|
continue;
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
Int32 res = NArchive::NExtract::NOperationResult::kDataError;
|
Int32 res = NExtract::NOperationResult::kDataError;
|
||||||
CMyComPtr<ISequentialInStream> inStream;
|
CMyComPtr<ISequentialInStream> inStream;
|
||||||
HRESULT hres = GetStream(index, &inStream);
|
HRESULT hres = GetStream(index, &inStream);
|
||||||
if (hres == S_FALSE)
|
if (hres == S_FALSE)
|
||||||
res = NArchive::NExtract::NOperationResult::kDataError;
|
res = NExtract::NOperationResult::kDataError;
|
||||||
else if (hres == E_NOTIMPL)
|
else if (hres == E_NOTIMPL)
|
||||||
res = NArchive::NExtract::NOperationResult::kUnSupportedMethod;
|
res = NExtract::NOperationResult::kUnSupportedMethod;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RINOK(hres);
|
RINOK(hres);
|
||||||
@@ -166,7 +165,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
{
|
{
|
||||||
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
|
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
|
||||||
if (copyCoderSpec->TotalSize == item.Size)
|
if (copyCoderSpec->TotalSize == item.Size)
|
||||||
res = NArchive::NExtract::NOperationResult::kOK;
|
res = NExtract::NOperationResult::kOK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
outStream.Release();
|
outStream.Release();
|
||||||
|
|||||||
@@ -8,6 +8,6 @@
|
|||||||
static IInArchive *CreateArc() { return new NArchive::NCom::CHandler; }
|
static IInArchive *CreateArc() { return new NArchive::NCom::CHandler; }
|
||||||
|
|
||||||
static CArcInfo g_ArcInfo =
|
static CArcInfo g_ArcInfo =
|
||||||
{ L"Compound", L"msi doc xls ppt", 0, 0xE5, { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 }, 8, false, CreateArc, 0 };
|
{ L"Compound", L"msi msp doc xls ppt", 0, 0xE5, { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 }, 8, false, CreateArc, 0 };
|
||||||
|
|
||||||
REGISTER_ARC(Com)
|
REGISTER_ARC(Com)
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ bool HasTailSlash(const AString &name, UINT codePage)
|
|||||||
if (name.IsEmpty())
|
if (name.IsEmpty())
|
||||||
return false;
|
return false;
|
||||||
LPCSTR prev =
|
LPCSTR prev =
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||||
CharPrevExA((WORD)codePage, name, &name[name.Length()], 0);
|
CharPrevExA((WORD)codePage, name, &name[name.Length()], 0);
|
||||||
#else
|
#else
|
||||||
(LPCSTR)(name) + (name.Length() - 1);
|
(LPCSTR)(name) + (name.Length() - 1);
|
||||||
|
|||||||
@@ -540,12 +540,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
|||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
bool testMode = (_aTestMode != 0);
|
bool allFilesMode = (numItems == (UInt32)-1);
|
||||||
bool allFilesMode = (numItems == UInt32(-1));
|
|
||||||
if (allFilesMode)
|
if (allFilesMode)
|
||||||
numItems = _items.Size();
|
numItems = _items.Size();
|
||||||
if (numItems == 0)
|
if (numItems == 0)
|
||||||
@@ -575,8 +574,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
RINOK(lps->SetCur());
|
RINOK(lps->SetCur());
|
||||||
CMyComPtr<ISequentialOutStream> outStream;
|
CMyComPtr<ISequentialOutStream> outStream;
|
||||||
Int32 askMode = testMode ?
|
Int32 askMode = testMode ?
|
||||||
NArchive::NExtract::NAskMode::kTest :
|
NExtract::NAskMode::kTest :
|
||||||
NArchive::NExtract::NAskMode::kExtract;
|
NExtract::NAskMode::kExtract;
|
||||||
Int32 index = allFilesMode ? i : indices[i];
|
Int32 index = allFilesMode ? i : indices[i];
|
||||||
const CItemEx &item = _items[index];
|
const CItemEx &item = _items[index];
|
||||||
RINOK(extractCallback->GetStream(index, &outStream, askMode));
|
RINOK(extractCallback->GetStream(index, &outStream, askMode));
|
||||||
@@ -584,7 +583,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
if (item.IsDir())
|
if (item.IsDir())
|
||||||
{
|
{
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!testMode && !outStream)
|
if (!testMode && !outStream)
|
||||||
@@ -592,7 +591,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
if (testMode)
|
if (testMode)
|
||||||
{
|
{
|
||||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
RINOK(_stream->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL));
|
RINOK(_stream->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL));
|
||||||
@@ -600,8 +599,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
|
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
|
||||||
outStream.Release();
|
outStream.Release();
|
||||||
RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ?
|
RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ?
|
||||||
NArchive::NExtract::NOperationResult::kOK:
|
NExtract::NOperationResult::kOK:
|
||||||
NArchive::NExtract::NOperationResult::kDataError));
|
NExtract::NOperationResult::kDataError));
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
|
|||||||
@@ -236,7 +236,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
|
|||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
{
|
{
|
||||||
CInArchive archive;
|
CInArchive archive;
|
||||||
if(archive.Open(stream) != S_OK)
|
if (archive.Open(stream) != S_OK)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
_items.Clear();
|
_items.Clear();
|
||||||
|
|
||||||
@@ -314,12 +314,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
|||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
bool testMode = (_aTestMode != 0);
|
bool allFilesMode = (numItems == (UInt32)-1);
|
||||||
bool allFilesMode = (numItems == UInt32(-1));
|
|
||||||
if (allFilesMode)
|
if (allFilesMode)
|
||||||
numItems = _items.Size();
|
numItems = _items.Size();
|
||||||
if (numItems == 0)
|
if (numItems == 0)
|
||||||
@@ -349,19 +348,19 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
RINOK(lps->SetCur());
|
RINOK(lps->SetCur());
|
||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
Int32 askMode = testMode ?
|
Int32 askMode = testMode ?
|
||||||
NArchive::NExtract::NAskMode::kTest :
|
NExtract::NAskMode::kTest :
|
||||||
NArchive::NExtract::NAskMode::kExtract;
|
NExtract::NAskMode::kExtract;
|
||||||
Int32 index = allFilesMode ? i : indices[i];
|
Int32 index = allFilesMode ? i : indices[i];
|
||||||
const CItem &item = _items[index];
|
const CItem &item = _items[index];
|
||||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||||
currentTotalSize += item.Size;
|
currentTotalSize += item.Size;
|
||||||
|
|
||||||
if (!testMode && (!realOutStream))
|
if (!testMode && !realOutStream)
|
||||||
continue;
|
continue;
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
if (testMode)
|
if (testMode)
|
||||||
{
|
{
|
||||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
RINOK(_stream->Seek(item.GetDataPos(), STREAM_SEEK_SET, NULL));
|
RINOK(_stream->Seek(item.GetDataPos(), STREAM_SEEK_SET, NULL));
|
||||||
@@ -369,8 +368,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
|
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
|
||||||
realOutStream.Release();
|
realOutStream.Release();
|
||||||
RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ?
|
RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ?
|
||||||
NArchive::NExtract::NOperationResult::kOK:
|
NExtract::NOperationResult::kOK:
|
||||||
NArchive::NExtract::NOperationResult::kDataError));
|
NExtract::NOperationResult::kDataError));
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
|
|||||||
118
CPP/7zip/Archive/DeflateProps.cpp
Executable file
118
CPP/7zip/Archive/DeflateProps.cpp
Executable file
@@ -0,0 +1,118 @@
|
|||||||
|
// DeflateProps.cpp
|
||||||
|
|
||||||
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
#include "Windows/PropVariant.h"
|
||||||
|
|
||||||
|
#include "Common/ParseProperties.h"
|
||||||
|
|
||||||
|
#include "DeflateProps.h"
|
||||||
|
|
||||||
|
namespace NArchive {
|
||||||
|
|
||||||
|
static const UInt32 kAlgo1 = 0;
|
||||||
|
static const UInt32 kAlgo5 = 1;
|
||||||
|
|
||||||
|
static const UInt32 kPasses1 = 1;
|
||||||
|
static const UInt32 kPasses7 = 3;
|
||||||
|
static const UInt32 kPasses9 = 10;
|
||||||
|
|
||||||
|
static const UInt32 kFb1 = 32;
|
||||||
|
static const UInt32 kFb7 = 64;
|
||||||
|
static const UInt32 kFb9 = 128;
|
||||||
|
|
||||||
|
void CDeflateProps::Normalize()
|
||||||
|
{
|
||||||
|
UInt32 level = Level;
|
||||||
|
if (level == 0xFFFFFFFF)
|
||||||
|
level = 5;
|
||||||
|
|
||||||
|
if (Algo == 0xFFFFFFFF)
|
||||||
|
Algo = (level >= 5 ?
|
||||||
|
kAlgo5 :
|
||||||
|
kAlgo1);
|
||||||
|
|
||||||
|
if (NumPasses == 0xFFFFFFFF)
|
||||||
|
NumPasses =
|
||||||
|
(level >= 9 ? kPasses9 :
|
||||||
|
(level >= 7 ? kPasses7 :
|
||||||
|
kPasses1));
|
||||||
|
if (Fb == 0xFFFFFFFF)
|
||||||
|
Fb =
|
||||||
|
(level >= 9 ? kFb9 :
|
||||||
|
(level >= 7 ? kFb7 :
|
||||||
|
kFb1));
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CDeflateProps::SetCoderProperties(ICompressSetCoderProperties *setCoderProperties)
|
||||||
|
{
|
||||||
|
Normalize();
|
||||||
|
|
||||||
|
NWindows::NCOM::CPropVariant props[] =
|
||||||
|
{
|
||||||
|
Algo,
|
||||||
|
NumPasses,
|
||||||
|
Fb,
|
||||||
|
Mc
|
||||||
|
};
|
||||||
|
PROPID propIDs[] =
|
||||||
|
{
|
||||||
|
NCoderPropID::kAlgorithm,
|
||||||
|
NCoderPropID::kNumPasses,
|
||||||
|
NCoderPropID::kNumFastBytes,
|
||||||
|
NCoderPropID::kMatchFinderCycles
|
||||||
|
};
|
||||||
|
int numProps = sizeof(propIDs) / sizeof(propIDs[0]);
|
||||||
|
if (!McDefined)
|
||||||
|
numProps--;
|
||||||
|
return setCoderProperties->SetCoderProperties(propIDs, props, numProps);
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CDeflateProps::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
for (int i = 0; i < numProps; i++)
|
||||||
|
{
|
||||||
|
UString name = names[i];
|
||||||
|
name.MakeUpper();
|
||||||
|
if (name.IsEmpty())
|
||||||
|
return E_INVALIDARG;
|
||||||
|
const PROPVARIANT &prop = values[i];
|
||||||
|
if (name[0] == L'X')
|
||||||
|
{
|
||||||
|
UInt32 a = 9;
|
||||||
|
RINOK(ParsePropValue(name.Mid(1), prop, a));
|
||||||
|
Level = a;
|
||||||
|
}
|
||||||
|
else if (name.Left(1) == L"A")
|
||||||
|
{
|
||||||
|
UInt32 a = kAlgo5;
|
||||||
|
RINOK(ParsePropValue(name.Mid(1), prop, a));
|
||||||
|
Algo = a;
|
||||||
|
}
|
||||||
|
else if (name.Left(4) == L"PASS")
|
||||||
|
{
|
||||||
|
UInt32 a = kPasses9;
|
||||||
|
RINOK(ParsePropValue(name.Mid(4), prop, a));
|
||||||
|
NumPasses = a;
|
||||||
|
}
|
||||||
|
else if (name.Left(2) == L"FB")
|
||||||
|
{
|
||||||
|
UInt32 a = kFb9;
|
||||||
|
RINOK(ParsePropValue(name.Mid(2), prop, a));
|
||||||
|
Fb = a;
|
||||||
|
}
|
||||||
|
else if (name.Left(2) == L"MC")
|
||||||
|
{
|
||||||
|
UInt32 a = 0xFFFFFFFF;
|
||||||
|
RINOK(ParsePropValue(name.Mid(2), prop, a));
|
||||||
|
Mc = a;
|
||||||
|
McDefined = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
35
CPP/7zip/Archive/DeflateProps.h
Executable file
35
CPP/7zip/Archive/DeflateProps.h
Executable file
@@ -0,0 +1,35 @@
|
|||||||
|
// DeflateProps.h
|
||||||
|
|
||||||
|
#ifndef __DEFLATE_PROPS_H
|
||||||
|
#define __DEFLATE_PROPS_H
|
||||||
|
|
||||||
|
#include "../ICoder.h"
|
||||||
|
|
||||||
|
namespace NArchive {
|
||||||
|
|
||||||
|
class CDeflateProps
|
||||||
|
{
|
||||||
|
UInt32 Level;
|
||||||
|
UInt32 NumPasses;
|
||||||
|
UInt32 Fb;
|
||||||
|
UInt32 Algo;
|
||||||
|
UInt32 Mc;
|
||||||
|
bool McDefined;
|
||||||
|
|
||||||
|
void Init()
|
||||||
|
{
|
||||||
|
Level = NumPasses = Fb = Algo = Mc = 0xFFFFFFFF;
|
||||||
|
McDefined = false;
|
||||||
|
}
|
||||||
|
void Normalize();
|
||||||
|
public:
|
||||||
|
CDeflateProps() { Init(); }
|
||||||
|
bool IsMaximum() const { return Algo > 0; }
|
||||||
|
|
||||||
|
HRESULT SetCoderProperties(ICompressSetCoderProperties *setCoderProperties);
|
||||||
|
HRESULT SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -5,6 +5,8 @@
|
|||||||
#include "../../Common/MyInitGuid.h"
|
#include "../../Common/MyInitGuid.h"
|
||||||
#include "../../Common/ComTry.h"
|
#include "../../Common/ComTry.h"
|
||||||
#include "../../Common/Types.h"
|
#include "../../Common/Types.h"
|
||||||
|
|
||||||
|
#include "../../Windows/NtCheck.h"
|
||||||
#include "../../Windows/PropVariant.h"
|
#include "../../Windows/PropVariant.h"
|
||||||
|
|
||||||
#include "IArchive.h"
|
#include "IArchive.h"
|
||||||
@@ -12,17 +14,8 @@
|
|||||||
#include "../IPassword.h"
|
#include "../IPassword.h"
|
||||||
|
|
||||||
HINSTANCE g_hInstance;
|
HINSTANCE g_hInstance;
|
||||||
#ifndef _UNICODE
|
|
||||||
bool g_IsNT = false;
|
#define NT_CHECK_FAIL_ACTION return FALSE;
|
||||||
static bool IsItWindowsNT()
|
|
||||||
{
|
|
||||||
OSVERSIONINFO versionInfo;
|
|
||||||
versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
|
|
||||||
if (!::GetVersionEx(&versionInfo))
|
|
||||||
return false;
|
|
||||||
return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
||||||
@@ -30,9 +23,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
|||||||
if (dwReason == DLL_PROCESS_ATTACH)
|
if (dwReason == DLL_PROCESS_ATTACH)
|
||||||
{
|
{
|
||||||
g_hInstance = hInstance;
|
g_hInstance = hInstance;
|
||||||
#ifndef _UNICODE
|
NT_CHECK;
|
||||||
g_IsNT = IsItWindowsNT();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,43 +3,38 @@
|
|||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
#include "../../Common/MyInitGuid.h"
|
#include "../../Common/MyInitGuid.h"
|
||||||
#include "../../Common/ComTry.h"
|
|
||||||
#include "../../Common/Types.h"
|
|
||||||
#include "../../Windows/PropVariant.h"
|
|
||||||
#if defined(_WIN32) && defined(_7ZIP_LARGE_PAGES)
|
#if defined(_WIN32) && defined(_7ZIP_LARGE_PAGES)
|
||||||
#include "../../../C/Alloc.h"
|
#include "../../../C/Alloc.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "IArchive.h"
|
#include "../../Common/ComTry.h"
|
||||||
|
|
||||||
|
#include "../../Windows/NtCheck.h"
|
||||||
|
#include "../../Windows/PropVariant.h"
|
||||||
|
|
||||||
#include "../ICoder.h"
|
#include "../ICoder.h"
|
||||||
#include "../IPassword.h"
|
#include "../IPassword.h"
|
||||||
|
|
||||||
|
#include "IArchive.h"
|
||||||
|
|
||||||
HINSTANCE g_hInstance;
|
HINSTANCE g_hInstance;
|
||||||
#ifndef _UNICODE
|
|
||||||
#ifdef _WIN32
|
#define NT_CHECK_FAIL_ACTION return FALSE;
|
||||||
bool g_IsNT = false;
|
|
||||||
static bool IsItWindowsNT()
|
|
||||||
{
|
|
||||||
OSVERSIONINFO versionInfo;
|
|
||||||
versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
|
|
||||||
if (!::GetVersionEx(&versionInfo))
|
|
||||||
return false;
|
|
||||||
return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
BOOL WINAPI DllMain(
|
||||||
|
#ifdef UNDER_CE
|
||||||
|
HANDLE
|
||||||
|
#else
|
||||||
|
HINSTANCE
|
||||||
|
#endif
|
||||||
|
hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
||||||
{
|
{
|
||||||
if (dwReason == DLL_PROCESS_ATTACH)
|
if (dwReason == DLL_PROCESS_ATTACH)
|
||||||
{
|
{
|
||||||
g_hInstance = hInstance;
|
g_hInstance = (HINSTANCE)hInstance;
|
||||||
#ifndef _UNICODE
|
NT_CHECK;
|
||||||
#ifdef _WIN32
|
|
||||||
g_IsNT = IsItWindowsNT();
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -573,12 +573,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
|||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
bool testMode = (_aTestMode != 0);
|
bool allFilesMode = (numItems == (UInt32)-1);
|
||||||
bool allFilesMode = (numItems == UInt32(-1));
|
|
||||||
if (allFilesMode)
|
if (allFilesMode)
|
||||||
numItems = _files.Size();
|
numItems = _files.Size();
|
||||||
if (numItems == 0)
|
if (numItems == 0)
|
||||||
@@ -635,14 +634,14 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
RINOK(lps->SetCur());
|
RINOK(lps->SetCur());
|
||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
Int32 askMode = testMode ?
|
Int32 askMode = testMode ?
|
||||||
NArchive::NExtract::NAskMode::kTest :
|
NExtract::NAskMode::kTest :
|
||||||
NArchive::NExtract::NAskMode::kExtract;
|
NExtract::NAskMode::kExtract;
|
||||||
Int32 index = allFilesMode ? i : indices[i];
|
Int32 index = allFilesMode ? i : indices[i];
|
||||||
// const CItemEx &item = _files[index];
|
// const CItemEx &item = _files[index];
|
||||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||||
|
|
||||||
|
|
||||||
if (!testMode && (!realOutStream))
|
if (!testMode && !realOutStream)
|
||||||
continue;
|
continue;
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
|
|
||||||
@@ -652,7 +651,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
|
|
||||||
realOutStream.Release();
|
realOutStream.Release();
|
||||||
|
|
||||||
Int32 opRes = NArchive::NExtract::NOperationResult::kOK;
|
Int32 opRes = NExtract::NOperationResult::kOK;
|
||||||
#ifdef DMG_SHOW_RAW
|
#ifdef DMG_SHOW_RAW
|
||||||
if (index > _fileIndices.Size())
|
if (index > _fileIndices.Size())
|
||||||
{
|
{
|
||||||
@@ -688,7 +687,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
packPos += block.PackSize;
|
packPos += block.PackSize;
|
||||||
if (block.UnpPos != unpPos)
|
if (block.UnpPos != unpPos)
|
||||||
{
|
{
|
||||||
opRes = NArchive::NExtract::NOperationResult::kDataError;
|
opRes = NExtract::NOperationResult::kDataError;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -705,13 +704,13 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
case METHOD_ZERO_2:
|
case METHOD_ZERO_2:
|
||||||
realMethod = false;
|
realMethod = false;
|
||||||
if (block.PackSize != 0)
|
if (block.PackSize != 0)
|
||||||
opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod;
|
opRes = NExtract::NOperationResult::kUnSupportedMethod;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case METHOD_COPY:
|
case METHOD_COPY:
|
||||||
if (block.UnpSize != block.PackSize)
|
if (block.UnpSize != block.PackSize)
|
||||||
{
|
{
|
||||||
opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod;
|
opRes = NExtract::NOperationResult::kUnSupportedMethod;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
res = copyCoder->Code(inStream, outStream, NULL, NULL, progress);
|
res = copyCoder->Code(inStream, outStream, NULL, NULL, progress);
|
||||||
@@ -730,26 +729,26 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
res = bzip2Coder->Code(inStream, outStream, NULL, NULL, progress);
|
res = bzip2Coder->Code(inStream, outStream, NULL, NULL, progress);
|
||||||
if (res == S_OK)
|
if (res == S_OK)
|
||||||
if (streamSpec->GetSize() != block.PackSize)
|
if (streamSpec->GetSize() != block.PackSize)
|
||||||
opRes = NArchive::NExtract::NOperationResult::kDataError;
|
opRes = NExtract::NOperationResult::kDataError;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod;
|
opRes = NExtract::NOperationResult::kUnSupportedMethod;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (res != S_OK)
|
if (res != S_OK)
|
||||||
{
|
{
|
||||||
if (res != S_FALSE)
|
if (res != S_FALSE)
|
||||||
return res;
|
return res;
|
||||||
if (opRes == NArchive::NExtract::NOperationResult::kOK)
|
if (opRes == NExtract::NOperationResult::kOK)
|
||||||
opRes = NArchive::NExtract::NOperationResult::kDataError;
|
opRes = NExtract::NOperationResult::kDataError;
|
||||||
}
|
}
|
||||||
unpPos += block.UnpSize;
|
unpPos += block.UnpSize;
|
||||||
if (!outStreamSpec->IsFinishedOK())
|
if (!outStreamSpec->IsFinishedOK())
|
||||||
{
|
{
|
||||||
if (realMethod && opRes == NArchive::NExtract::NOperationResult::kOK)
|
if (realMethod && opRes == NExtract::NOperationResult::kOK)
|
||||||
opRes = NArchive::NExtract::NOperationResult::kDataError;
|
opRes = NExtract::NOperationResult::kDataError;
|
||||||
|
|
||||||
while (outStreamSpec->GetRem() != 0)
|
while (outStreamSpec->GetRem() != 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -466,12 +466,11 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
bool testMode = (_aTestMode != 0);
|
bool allFilesMode = (numItems == (UInt32)-1);
|
||||||
bool allFilesMode = (numItems == UInt32(-1));
|
|
||||||
if (allFilesMode)
|
if (allFilesMode)
|
||||||
numItems = _sections.Size();
|
numItems = _sections.Size();
|
||||||
if (numItems == 0)
|
if (numItems == 0)
|
||||||
@@ -501,8 +500,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
lps->InSize = lps->OutSize = currentTotalSize;
|
lps->InSize = lps->OutSize = currentTotalSize;
|
||||||
RINOK(lps->SetCur());
|
RINOK(lps->SetCur());
|
||||||
Int32 askMode = testMode ?
|
Int32 askMode = testMode ?
|
||||||
NArchive::NExtract::NAskMode::kTest :
|
NExtract::NAskMode::kTest :
|
||||||
NArchive::NExtract::NAskMode::kExtract;
|
NExtract::NAskMode::kExtract;
|
||||||
UInt32 index = allFilesMode ? i : indices[i];
|
UInt32 index = allFilesMode ? i : indices[i];
|
||||||
const CSegment &item = _sections[index];
|
const CSegment &item = _sections[index];
|
||||||
currentItemSize = item.PSize;
|
currentItemSize = item.PSize;
|
||||||
@@ -518,8 +517,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
|
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
|
||||||
outStream.Release();
|
outStream.Release();
|
||||||
RINOK(extractCallback->SetOperationResult(copyCoderSpec->TotalSize == currentItemSize ?
|
RINOK(extractCallback->SetOperationResult(copyCoderSpec->TotalSize == currentItemSize ?
|
||||||
NArchive::NExtract::NOperationResult::kOK:
|
NExtract::NOperationResult::kOK:
|
||||||
NArchive::NExtract::NOperationResult::kDataError));
|
NExtract::NOperationResult::kDataError));
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
|
|||||||
@@ -456,8 +456,11 @@ HRESULT CDatabase::ReadDir(Int32 parent, UInt32 cluster, int level)
|
|||||||
const Byte *p = ByteBuf + pos;
|
const Byte *p = ByteBuf + pos;
|
||||||
if (p[0] == 0)
|
if (p[0] == 0)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
// FreeDOS formats FAT partition with cluster chain longer than required.
|
||||||
if (clusterMode && !Header.IsEoc(cluster))
|
if (clusterMode && !Header.IsEoc(cluster))
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
*/
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (p[0] == 0xE5)
|
if (p[0] == 0xE5)
|
||||||
@@ -883,12 +886,11 @@ STDMETHODIMP CHandler::Close()
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
bool testMode = (_aTestMode != 0);
|
bool allFilesMode = (numItems == (UInt32)-1);
|
||||||
bool allFilesMode = (numItems == UInt32(-1));
|
|
||||||
if (allFilesMode)
|
if (allFilesMode)
|
||||||
numItems = Items.Size();
|
numItems = Items.Size();
|
||||||
if (numItems == 0)
|
if (numItems == 0)
|
||||||
@@ -923,8 +925,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
RINOK(lps->SetCur());
|
RINOK(lps->SetCur());
|
||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
Int32 askMode = testMode ?
|
Int32 askMode = testMode ?
|
||||||
NArchive::NExtract::NAskMode::kTest :
|
NExtract::NAskMode::kTest :
|
||||||
NArchive::NExtract::NAskMode::kExtract;
|
NExtract::NAskMode::kExtract;
|
||||||
Int32 index = allFilesMode ? i : indices[i];
|
Int32 index = allFilesMode ? i : indices[i];
|
||||||
const CItem &item = Items[index];
|
const CItem &item = Items[index];
|
||||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||||
@@ -932,14 +934,14 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
if (item.IsDir())
|
if (item.IsDir())
|
||||||
{
|
{
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
totalPackSize += Header.GetFilePackSize(item.Size);
|
totalPackSize += Header.GetFilePackSize(item.Size);
|
||||||
totalSize += item.Size;
|
totalSize += item.Size;
|
||||||
|
|
||||||
if (!testMode && (!realOutStream))
|
if (!testMode && !realOutStream)
|
||||||
continue;
|
continue;
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
|
|
||||||
@@ -947,7 +949,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
realOutStream.Release();
|
realOutStream.Release();
|
||||||
outStreamSpec->Init();
|
outStreamSpec->Init();
|
||||||
|
|
||||||
int res = NArchive::NExtract::NOperationResult::kDataError;
|
int res = NExtract::NOperationResult::kDataError;
|
||||||
CMyComPtr<ISequentialInStream> inStream;
|
CMyComPtr<ISequentialInStream> inStream;
|
||||||
HRESULT hres = GetStream(index, &inStream);
|
HRESULT hres = GetStream(index, &inStream);
|
||||||
if (hres != S_FALSE)
|
if (hres != S_FALSE)
|
||||||
@@ -957,7 +959,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
{
|
{
|
||||||
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
|
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
|
||||||
if (copyCoderSpec->TotalSize == item.Size)
|
if (copyCoderSpec->TotalSize == item.Size)
|
||||||
res = NArchive::NExtract::NOperationResult::kOK;
|
res = NExtract::NOperationResult::kOK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
outStreamSpec->ReleaseStream();
|
outStreamSpec->ReleaseStream();
|
||||||
|
|||||||
544
CPP/7zip/Archive/FlvHandler.cpp
Executable file
544
CPP/7zip/Archive/FlvHandler.cpp
Executable file
@@ -0,0 +1,544 @@
|
|||||||
|
// FlvHandler.cpp
|
||||||
|
|
||||||
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
#include "../../../C/CpuArch.h"
|
||||||
|
|
||||||
|
#include "Common/Buffer.h"
|
||||||
|
#include "Common/ComTry.h"
|
||||||
|
// #include "Common/Defs.h"
|
||||||
|
#include "Common/MyString.h"
|
||||||
|
|
||||||
|
#include "Windows/PropVariant.h"
|
||||||
|
|
||||||
|
#include "../Common/ProgressUtils.h"
|
||||||
|
#include "../Common/RegisterArc.h"
|
||||||
|
#include "../Common/StreamObjects.h"
|
||||||
|
#include "../Common/StreamUtils.h"
|
||||||
|
|
||||||
|
#define GetBe24(p) ( \
|
||||||
|
((UInt32)((const Byte *)(p))[0] << 16) | \
|
||||||
|
((UInt32)((const Byte *)(p))[1] << 8) | \
|
||||||
|
((const Byte *)(p))[2] )
|
||||||
|
|
||||||
|
#define Get16(p) GetBe16(p)
|
||||||
|
#define Get24(p) GetBe24(p)
|
||||||
|
#define Get32(p) GetBe32(p)
|
||||||
|
|
||||||
|
namespace NArchive {
|
||||||
|
namespace NFlv {
|
||||||
|
|
||||||
|
static const UInt32 kFileSizeMax = (UInt32)1 << 30;
|
||||||
|
static const int kNumChunksMax = (UInt32)1 << 23;
|
||||||
|
|
||||||
|
const UInt32 kTagHeaderSize = 11;
|
||||||
|
|
||||||
|
static const Byte kFlag_Video = 1;
|
||||||
|
static const Byte kFlag_Audio = 4;
|
||||||
|
|
||||||
|
static const Byte kType_Audio = 8;
|
||||||
|
static const Byte kType_Video = 9;
|
||||||
|
static const Byte kType_Meta = 18;
|
||||||
|
static const int kNumTypes = 19;
|
||||||
|
|
||||||
|
struct CItem
|
||||||
|
{
|
||||||
|
UInt32 Offset;
|
||||||
|
UInt32 Size;
|
||||||
|
// UInt32 Time;
|
||||||
|
Byte Type;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CItem2
|
||||||
|
{
|
||||||
|
Byte Type;
|
||||||
|
Byte SubType;
|
||||||
|
Byte Props;
|
||||||
|
bool SameSubTypes;
|
||||||
|
int NumChunks;
|
||||||
|
size_t Size;
|
||||||
|
|
||||||
|
CReferenceBuf *BufSpec;
|
||||||
|
CMyComPtr<IUnknown> RefBuf;
|
||||||
|
|
||||||
|
bool IsAudio() const { return Type == kType_Audio; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class CHandler:
|
||||||
|
public IInArchive,
|
||||||
|
public IInArchiveGetStream,
|
||||||
|
public CMyUnknownImp
|
||||||
|
{
|
||||||
|
int _isRaw;
|
||||||
|
CMyComPtr<IInStream> _stream;
|
||||||
|
CObjectVector<CItem2> _items2;
|
||||||
|
// CByteBuffer _metadata;
|
||||||
|
HRESULT Open2(IInStream *stream, IArchiveOpenCallback *callback);
|
||||||
|
AString GetComment();
|
||||||
|
public:
|
||||||
|
MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream)
|
||||||
|
INTERFACE_IInArchive(;)
|
||||||
|
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
|
||||||
|
};
|
||||||
|
|
||||||
|
STATPROPSTG kProps[] =
|
||||||
|
{
|
||||||
|
{ NULL, kpidSize, VT_UI8},
|
||||||
|
{ NULL, kpidNumBlocks, VT_UI4},
|
||||||
|
{ NULL, kpidComment, VT_BSTR}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
STATPROPSTG kArcProps[] =
|
||||||
|
{
|
||||||
|
{ NULL, kpidComment, VT_BSTR}
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
|
IMP_IInArchive_Props
|
||||||
|
IMP_IInArchive_ArcProps_NO
|
||||||
|
|
||||||
|
static const char *g_AudioTypes[16] =
|
||||||
|
{
|
||||||
|
"pcm",
|
||||||
|
"adpcm",
|
||||||
|
"mp3",
|
||||||
|
"pcm_le",
|
||||||
|
"nellymoser16",
|
||||||
|
"nellymoser8",
|
||||||
|
"nellymoser",
|
||||||
|
"g711a",
|
||||||
|
"g711m",
|
||||||
|
"audio9",
|
||||||
|
"aac",
|
||||||
|
"speex",
|
||||||
|
"audio12",
|
||||||
|
"audio13",
|
||||||
|
"mp3",
|
||||||
|
"audio15"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *g_VideoTypes[16] =
|
||||||
|
{
|
||||||
|
"video0",
|
||||||
|
"jpeg",
|
||||||
|
"h263",
|
||||||
|
"screen",
|
||||||
|
"vp6",
|
||||||
|
"vp6alpha",
|
||||||
|
"screen2",
|
||||||
|
"avc",
|
||||||
|
"video8",
|
||||||
|
"video9",
|
||||||
|
"video10",
|
||||||
|
"video11",
|
||||||
|
"video12",
|
||||||
|
"video13",
|
||||||
|
"video14",
|
||||||
|
"video15"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *g_Rates[4] =
|
||||||
|
{
|
||||||
|
"5.5 kHz",
|
||||||
|
"11 kHz",
|
||||||
|
"22 kHz",
|
||||||
|
"44 kHz"
|
||||||
|
};
|
||||||
|
|
||||||
|
static void MyStrCat(char *d, const char *s)
|
||||||
|
{
|
||||||
|
MyStringCopy(d + MyStringLen(d), s);
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||||
|
{
|
||||||
|
NWindows::NCOM::CPropVariant prop;
|
||||||
|
const CItem2 &item = _items2[index];
|
||||||
|
switch(propID)
|
||||||
|
{
|
||||||
|
case kpidExtension:
|
||||||
|
prop = _isRaw ?
|
||||||
|
(item.IsAudio() ? g_AudioTypes[item.SubType] : g_VideoTypes[item.SubType]) :
|
||||||
|
(item.IsAudio() ? "audio.flv" : "video.flv");
|
||||||
|
break;
|
||||||
|
case kpidSize:
|
||||||
|
case kpidPackSize:
|
||||||
|
prop = (UInt64)item.Size;
|
||||||
|
break;
|
||||||
|
case kpidNumBlocks: prop = (UInt32)item.NumChunks; break;
|
||||||
|
case kpidComment:
|
||||||
|
{
|
||||||
|
char sz[64];
|
||||||
|
MyStringCopy(sz, (item.IsAudio() ? g_AudioTypes[item.SubType] : g_VideoTypes[item.SubType]) );
|
||||||
|
if (item.IsAudio())
|
||||||
|
{
|
||||||
|
MyStrCat(sz, " ");
|
||||||
|
MyStrCat(sz, g_Rates[(item.Props >> 2) & 3]);
|
||||||
|
MyStrCat(sz, (item.Props & 2) ? " 16-bit" : " 8-bit");
|
||||||
|
MyStrCat(sz, (item.Props & 1) ? " stereo" : " mono");
|
||||||
|
}
|
||||||
|
prop = sz;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prop.Detach(value);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
AString CHandler::GetComment()
|
||||||
|
{
|
||||||
|
const Byte *p = _metadata;
|
||||||
|
size_t size = _metadata.GetCapacity();
|
||||||
|
AString res;
|
||||||
|
if (size > 0)
|
||||||
|
{
|
||||||
|
p++;
|
||||||
|
size--;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (size < 2)
|
||||||
|
break;
|
||||||
|
int len = Get16(p);
|
||||||
|
p += 2;
|
||||||
|
size -= 2;
|
||||||
|
if (len == 0 || (size_t)len > size)
|
||||||
|
break;
|
||||||
|
{
|
||||||
|
AString temp;
|
||||||
|
char *sz = temp.GetBuffer(len);
|
||||||
|
memcpy(sz, p, len);
|
||||||
|
sz[len] = 0;
|
||||||
|
temp.ReleaseBuffer();
|
||||||
|
if (!res.IsEmpty())
|
||||||
|
res += '\n';
|
||||||
|
res += temp;
|
||||||
|
}
|
||||||
|
p += len;
|
||||||
|
size -= len;
|
||||||
|
if (size < 1)
|
||||||
|
break;
|
||||||
|
Byte type = *p++;
|
||||||
|
size--;
|
||||||
|
bool ok = false;
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
if (size < 8)
|
||||||
|
break;
|
||||||
|
ok = true;
|
||||||
|
Byte reverse[8];
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
bool little_endian = 1;
|
||||||
|
if (little_endian)
|
||||||
|
reverse[i] = p[7 - i];
|
||||||
|
else
|
||||||
|
reverse[i] = p[i];
|
||||||
|
}
|
||||||
|
double d = *(double *)reverse;
|
||||||
|
char temp[32];
|
||||||
|
sprintf(temp, " = %.3f", d);
|
||||||
|
res += temp;
|
||||||
|
p += 8;
|
||||||
|
size -= 8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 8:
|
||||||
|
{
|
||||||
|
if (size < 4)
|
||||||
|
break;
|
||||||
|
ok = true;
|
||||||
|
// UInt32 numItems = Get32(p);
|
||||||
|
p += 4;
|
||||||
|
size -= 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!ok)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||||
|
{
|
||||||
|
COM_TRY_BEGIN
|
||||||
|
NWindows::NCOM::CPropVariant prop;
|
||||||
|
switch(propID)
|
||||||
|
{
|
||||||
|
case kpidComment: prop = GetComment(); break;
|
||||||
|
}
|
||||||
|
prop.Detach(value);
|
||||||
|
return S_OK;
|
||||||
|
COM_TRY_END
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
|
||||||
|
{
|
||||||
|
CRecordVector<CItem> items;
|
||||||
|
|
||||||
|
const UInt32 kHeaderSize = 13;
|
||||||
|
Byte header[kHeaderSize];
|
||||||
|
RINOK(ReadStream_FALSE(stream, header, kHeaderSize));
|
||||||
|
if (header[0] != 'F' ||
|
||||||
|
header[1] != 'L' ||
|
||||||
|
header[2] != 'V' ||
|
||||||
|
header[3] != 1 ||
|
||||||
|
(header[4] & 0xFA) != 0)
|
||||||
|
return S_FALSE;
|
||||||
|
UInt32 offset = Get32(header + 5);
|
||||||
|
if (offset != 9 || Get32(header + 9) != 0)
|
||||||
|
return S_FALSE;
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
CByteBuffer inBuf;
|
||||||
|
size_t fileSize;
|
||||||
|
{
|
||||||
|
UInt64 fileSize64;
|
||||||
|
RINOK(stream->Seek(0, STREAM_SEEK_END, &fileSize64));
|
||||||
|
if (fileSize64 > kFileSizeMax)
|
||||||
|
return S_FALSE;
|
||||||
|
|
||||||
|
if (callback)
|
||||||
|
RINOK(callback->SetTotal(NULL, &fileSize64))
|
||||||
|
|
||||||
|
RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
|
||||||
|
fileSize = (size_t)fileSize64;
|
||||||
|
inBuf.SetCapacity(fileSize);
|
||||||
|
for (size_t pos = 0; pos < fileSize;)
|
||||||
|
{
|
||||||
|
UInt64 offset64 = pos;
|
||||||
|
if (callback)
|
||||||
|
RINOK(callback->SetCompleted(NULL, &offset64))
|
||||||
|
size_t rem = MyMin(fileSize - pos, (size_t)(1 << 20));
|
||||||
|
RINOK(ReadStream_FALSE(stream, inBuf + pos, rem));
|
||||||
|
pos += rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int lasts[kNumTypes];
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < kNumTypes; i++)
|
||||||
|
lasts[i] = -1;
|
||||||
|
|
||||||
|
while (offset < fileSize)
|
||||||
|
{
|
||||||
|
CItem item;
|
||||||
|
item.Offset = offset;
|
||||||
|
const Byte *buf = inBuf + offset;
|
||||||
|
offset += kTagHeaderSize;
|
||||||
|
if (offset > fileSize)
|
||||||
|
return S_FALSE;
|
||||||
|
|
||||||
|
item.Type = buf[0];
|
||||||
|
UInt32 size = Get24(buf + 1);
|
||||||
|
if (size < 1)
|
||||||
|
return S_FALSE;
|
||||||
|
// item.Time = Get24(buf + 4);
|
||||||
|
// item.Time |= (UInt32)buf[7] << 24;
|
||||||
|
if (Get24(buf + 8) != 0) // streamID
|
||||||
|
return S_FALSE;
|
||||||
|
|
||||||
|
UInt32 curSize = kTagHeaderSize + size + 4;
|
||||||
|
item.Size = curSize;
|
||||||
|
|
||||||
|
offset += curSize - kTagHeaderSize;
|
||||||
|
if (offset > fileSize)
|
||||||
|
return S_FALSE;
|
||||||
|
|
||||||
|
if (Get32(buf + kTagHeaderSize + size) != kTagHeaderSize + size)
|
||||||
|
return S_FALSE;
|
||||||
|
|
||||||
|
// printf("\noffset = %6X type = %2d time = %6d size = %6d", (UInt32)offset, item.Type, item.Time, item.Size);
|
||||||
|
|
||||||
|
if (item.Type == kType_Meta)
|
||||||
|
{
|
||||||
|
// _metadata = item.Buf;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (item.Type != kType_Audio && item.Type != kType_Video)
|
||||||
|
return S_FALSE;
|
||||||
|
if (items.Size() >= kNumChunksMax)
|
||||||
|
return S_FALSE;
|
||||||
|
Byte firstByte = buf[kTagHeaderSize];
|
||||||
|
Byte subType, props;
|
||||||
|
if (item.Type == kType_Audio)
|
||||||
|
{
|
||||||
|
subType = firstByte >> 4;
|
||||||
|
props = firstByte & 0xF;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
subType = firstByte & 0xF;
|
||||||
|
props = firstByte >> 4;
|
||||||
|
}
|
||||||
|
int last = lasts[item.Type];
|
||||||
|
if (last < 0)
|
||||||
|
{
|
||||||
|
CItem2 item2;
|
||||||
|
item2.RefBuf = item2.BufSpec = new CReferenceBuf;
|
||||||
|
item2.Size = curSize;
|
||||||
|
item2.Type = item.Type;
|
||||||
|
item2.SubType = subType;
|
||||||
|
item2.Props = props;
|
||||||
|
item2.NumChunks = 1;
|
||||||
|
item2.SameSubTypes = true;
|
||||||
|
lasts[item.Type] = _items2.Add(item2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CItem2 &item2 = _items2[last];
|
||||||
|
if (subType != item2.SubType)
|
||||||
|
item2.SameSubTypes = false;
|
||||||
|
item2.Size += curSize;
|
||||||
|
item2.NumChunks++;
|
||||||
|
}
|
||||||
|
items.Add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_isRaw = (_items2.Size() == 1);
|
||||||
|
for (i = 0; i < _items2.Size(); i++)
|
||||||
|
{
|
||||||
|
CItem2 &item2 = _items2[i];
|
||||||
|
CByteBuffer &itemBuf = item2.BufSpec->Buf;
|
||||||
|
if (_isRaw)
|
||||||
|
{
|
||||||
|
if (!item2.SameSubTypes)
|
||||||
|
return S_FALSE;
|
||||||
|
itemBuf.SetCapacity((size_t)item2.Size - (kTagHeaderSize + 4 + 1) * item2.NumChunks);
|
||||||
|
item2.Size = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
itemBuf.SetCapacity(kHeaderSize + (size_t)item2.Size);
|
||||||
|
memcpy(itemBuf, header, kHeaderSize);
|
||||||
|
itemBuf[4] = item2.IsAudio() ? kFlag_Audio : kFlag_Video;
|
||||||
|
item2.Size = kHeaderSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < items.Size(); i++)
|
||||||
|
{
|
||||||
|
const CItem &item = items[i];
|
||||||
|
CItem2 &item2 = _items2[lasts[item.Type]];
|
||||||
|
size_t size = item.Size;
|
||||||
|
const Byte *src = inBuf + item.Offset;
|
||||||
|
if (_isRaw)
|
||||||
|
{
|
||||||
|
src += kTagHeaderSize + 1;
|
||||||
|
size -= (kTagHeaderSize + 4 + 1);
|
||||||
|
}
|
||||||
|
memcpy(item2.BufSpec->Buf + item2.Size, src, size);
|
||||||
|
item2.Size += size;
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *callback)
|
||||||
|
{
|
||||||
|
COM_TRY_BEGIN
|
||||||
|
Close();
|
||||||
|
HRESULT res;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
res = Open2(inStream, callback);
|
||||||
|
if (res == S_OK)
|
||||||
|
_stream = inStream;
|
||||||
|
}
|
||||||
|
catch(...) { res = S_FALSE; }
|
||||||
|
if (res != S_OK)
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
return S_FALSE;
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
COM_TRY_END
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::Close()
|
||||||
|
{
|
||||||
|
_stream.Release();
|
||||||
|
_items2.Clear();
|
||||||
|
// _metadata.SetCapacity(0);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||||
|
{
|
||||||
|
*numItems = _items2.Size();
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
|
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||||
|
{
|
||||||
|
COM_TRY_BEGIN
|
||||||
|
bool allFilesMode = (numItems == (UInt32)-1);
|
||||||
|
if (allFilesMode)
|
||||||
|
numItems = _items2.Size();
|
||||||
|
if (numItems == 0)
|
||||||
|
return S_OK;
|
||||||
|
UInt64 totalSize = 0;
|
||||||
|
UInt32 i;
|
||||||
|
for (i = 0; i < numItems; i++)
|
||||||
|
totalSize += _items2[allFilesMode ? i : indices[i]].Size;
|
||||||
|
extractCallback->SetTotal(totalSize);
|
||||||
|
|
||||||
|
totalSize = 0;
|
||||||
|
|
||||||
|
CLocalProgress *lps = new CLocalProgress;
|
||||||
|
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||||
|
lps->Init(extractCallback, false);
|
||||||
|
|
||||||
|
for (i = 0; i < numItems; i++)
|
||||||
|
{
|
||||||
|
lps->InSize = 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 CItem2 &item = _items2[index];
|
||||||
|
RINOK(extractCallback->GetStream(index, &outStream, askMode));
|
||||||
|
totalSize += item.Size;
|
||||||
|
if (!testMode && !outStream)
|
||||||
|
continue;
|
||||||
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
|
if (outStream)
|
||||||
|
{
|
||||||
|
RINOK(WriteStream(outStream, item.BufSpec->Buf, item.BufSpec->Buf.GetCapacity()));
|
||||||
|
}
|
||||||
|
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
COM_TRY_END
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
|
||||||
|
{
|
||||||
|
COM_TRY_BEGIN
|
||||||
|
*stream = 0;
|
||||||
|
CBufInStream *streamSpec = new CBufInStream;
|
||||||
|
CMyComPtr<ISequentialInStream> streamTemp = streamSpec;
|
||||||
|
streamSpec->Init(_items2[index].BufSpec);
|
||||||
|
*stream = streamTemp.Detach();
|
||||||
|
return S_OK;
|
||||||
|
COM_TRY_END
|
||||||
|
}
|
||||||
|
|
||||||
|
static IInArchive *CreateArc() { return new CHandler; }
|
||||||
|
|
||||||
|
static CArcInfo g_ArcInfo =
|
||||||
|
{ L"FLV", L"flv", 0, 0xD6, { 'F', 'L', 'V' }, 3, false, CreateArc, 0 };
|
||||||
|
|
||||||
|
REGISTER_ARC(Flv)
|
||||||
|
|
||||||
|
}}
|
||||||
@@ -20,7 +20,8 @@
|
|||||||
|
|
||||||
#include "Common/InStreamWithCRC.h"
|
#include "Common/InStreamWithCRC.h"
|
||||||
#include "Common/OutStreamWithCRC.h"
|
#include "Common/OutStreamWithCRC.h"
|
||||||
#include "Common/ParseProperties.h"
|
|
||||||
|
#include "DeflateProps.h"
|
||||||
|
|
||||||
#define Get32(p) GetUi32(p)
|
#define Get32(p) GetUi32(p)
|
||||||
|
|
||||||
@@ -288,54 +289,6 @@ HRESULT CItem::WriteFooter(ISequentialOutStream *stream)
|
|||||||
return WriteStream(stream, buf, 8);
|
return WriteStream(stream, buf, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const UInt32 kAlgoX1 = 0;
|
|
||||||
static const UInt32 kAlgoX5 = 1;
|
|
||||||
|
|
||||||
static const UInt32 kNumPassesX1 = 1;
|
|
||||||
static const UInt32 kNumPassesX7 = 3;
|
|
||||||
static const UInt32 kNumPassesX9 = 10;
|
|
||||||
|
|
||||||
static const UInt32 kNumFastBytesX1 = 32;
|
|
||||||
static const UInt32 kNumFastBytesX7 = 64;
|
|
||||||
static const UInt32 kNumFastBytesX9 = 128;
|
|
||||||
|
|
||||||
struct CCompressMode
|
|
||||||
{
|
|
||||||
UInt32 NumPasses;
|
|
||||||
UInt32 NumFastBytes;
|
|
||||||
UInt32 Algo;
|
|
||||||
UInt32 Mc;
|
|
||||||
bool McDefined;
|
|
||||||
|
|
||||||
bool IsMaximum() const { return Algo > 0; }
|
|
||||||
|
|
||||||
void Init()
|
|
||||||
{
|
|
||||||
NumPasses = NumFastBytes = Mc = Algo = 0xFFFFFFFF;
|
|
||||||
McDefined = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Normalize(UInt32 level)
|
|
||||||
{
|
|
||||||
if (level == 0xFFFFFFFF)
|
|
||||||
level = 5;
|
|
||||||
if (NumPasses == 0xFFFFFFFF)
|
|
||||||
NumPasses =
|
|
||||||
(level >= 9 ? kNumPassesX9 :
|
|
||||||
(level >= 7 ? kNumPassesX7 :
|
|
||||||
kNumPassesX1));
|
|
||||||
if (NumFastBytes == 0xFFFFFFFF)
|
|
||||||
NumFastBytes =
|
|
||||||
(level >= 9 ? kNumFastBytesX9 :
|
|
||||||
(level >= 7 ? kNumFastBytesX7 :
|
|
||||||
kNumFastBytesX1));
|
|
||||||
if (Algo == 0xFFFFFFFF)
|
|
||||||
Algo = (level >= 5 ?
|
|
||||||
kAlgoX5 :
|
|
||||||
kAlgoX1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CHandler:
|
class CHandler:
|
||||||
public IInArchive,
|
public IInArchive,
|
||||||
public IArchiveOpenSeq,
|
public IArchiveOpenSeq,
|
||||||
@@ -352,14 +305,7 @@ class CHandler:
|
|||||||
CMyComPtr<ICompressCoder> _decoder;
|
CMyComPtr<ICompressCoder> _decoder;
|
||||||
NCompress::NDeflate::NDecoder::CCOMCoder *_decoderSpec;
|
NCompress::NDeflate::NDecoder::CCOMCoder *_decoderSpec;
|
||||||
|
|
||||||
CCompressMode _method;
|
CDeflateProps _method;
|
||||||
UInt32 _level;
|
|
||||||
|
|
||||||
void InitMethodProperties()
|
|
||||||
{
|
|
||||||
_level = 0xFFFFFFFF;
|
|
||||||
_method.Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MY_UNKNOWN_IMP4(IInArchive, IArchiveOpenSeq, IOutArchive, ISetProperties)
|
MY_UNKNOWN_IMP4(IInArchive, IArchiveOpenSeq, IOutArchive, ISetProperties)
|
||||||
@@ -370,7 +316,6 @@ public:
|
|||||||
|
|
||||||
CHandler()
|
CHandler()
|
||||||
{
|
{
|
||||||
InitMethodProperties();
|
|
||||||
_decoderSpec = new NCompress::NDeflate::NDecoder::CCOMCoder;
|
_decoderSpec = new NCompress::NDeflate::NDecoder::CCOMCoder;
|
||||||
_decoder = _decoderSpec;
|
_decoder = _decoderSpec;
|
||||||
}
|
}
|
||||||
@@ -496,28 +441,23 @@ STDMETHODIMP CHandler::Close()
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
bool allFilesMode = (numItems == (UInt32)-1);
|
|
||||||
if (!allFilesMode)
|
|
||||||
{
|
|
||||||
if (numItems == 0)
|
if (numItems == 0)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
if (numItems != 1 || indices[0] != 0)
|
if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0))
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
}
|
|
||||||
|
|
||||||
bool testMode = (_aTestMode != 0);
|
|
||||||
if (_stream)
|
if (_stream)
|
||||||
extractCallback->SetTotal(_packSize);
|
extractCallback->SetTotal(_packSize);
|
||||||
UInt64 currentTotalPacked = 0;
|
UInt64 currentTotalPacked = 0;
|
||||||
RINOK(extractCallback->SetCompleted(¤tTotalPacked));
|
RINOK(extractCallback->SetCompleted(¤tTotalPacked));
|
||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
Int32 askMode = testMode ?
|
Int32 askMode = testMode ?
|
||||||
NArchive::NExtract::NAskMode::kTest :
|
NExtract::NAskMode::kTest :
|
||||||
NArchive::NExtract::NAskMode::kExtract;
|
NExtract::NAskMode::kExtract;
|
||||||
RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
|
RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
|
||||||
if (!testMode && !realOutStream)
|
if (!testMode && !realOutStream)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
@@ -557,8 +497,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
if (result != S_FALSE)
|
if (result != S_FALSE)
|
||||||
return result;
|
return result;
|
||||||
opRes = firstItem ?
|
opRes = firstItem ?
|
||||||
NArchive::NExtract::NOperationResult::kDataError :
|
NExtract::NOperationResult::kDataError :
|
||||||
NArchive::NExtract::NOperationResult::kOK;
|
NExtract::NOperationResult::kOK;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -572,20 +512,20 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
{
|
{
|
||||||
if (result != S_FALSE)
|
if (result != S_FALSE)
|
||||||
return result;
|
return result;
|
||||||
opRes = NArchive::NExtract::NOperationResult::kDataError;
|
opRes = NExtract::NOperationResult::kDataError;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_decoderSpec->AlignToByte();
|
_decoderSpec->AlignToByte();
|
||||||
if (item.ReadFooter1(_decoderSpec) != S_OK)
|
if (item.ReadFooter1(_decoderSpec) != S_OK)
|
||||||
{
|
{
|
||||||
opRes = NArchive::NExtract::NOperationResult::kDataError;
|
opRes = NExtract::NOperationResult::kDataError;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (item.Crc != outStreamSpec->GetCRC() ||
|
if (item.Crc != outStreamSpec->GetCRC() ||
|
||||||
item.Size32 != (UInt32)(outStreamSpec->GetSize() - startOffset))
|
item.Size32 != (UInt32)(outStreamSpec->GetSize() - startOffset))
|
||||||
{
|
{
|
||||||
opRes = NArchive::NExtract::NOperationResult::kCRCError;
|
opRes = NExtract::NOperationResult::kCRCError;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -605,7 +545,7 @@ static HRESULT UpdateArchive(
|
|||||||
ISequentialOutStream *outStream,
|
ISequentialOutStream *outStream,
|
||||||
UInt64 unpackSize,
|
UInt64 unpackSize,
|
||||||
const CItem &newItem,
|
const CItem &newItem,
|
||||||
const CCompressMode &compressionMode,
|
CDeflateProps &deflateProps,
|
||||||
IArchiveUpdateCallback *updateCallback)
|
IArchiveUpdateCallback *updateCallback)
|
||||||
{
|
{
|
||||||
UInt64 complexity = 0;
|
UInt64 complexity = 0;
|
||||||
@@ -627,7 +567,7 @@ static HRESULT UpdateArchive(
|
|||||||
|
|
||||||
CItem item = newItem;
|
CItem item = newItem;
|
||||||
item.Method = NHeader::NCompressionMethod::kDeflate;
|
item.Method = NHeader::NCompressionMethod::kDeflate;
|
||||||
item.ExtraFlags = compressionMode.IsMaximum() ?
|
item.ExtraFlags = deflateProps.IsMaximum() ?
|
||||||
NHeader::NExtraFlags::kMaximum :
|
NHeader::NExtraFlags::kMaximum :
|
||||||
NHeader::NExtraFlags::kFastest;
|
NHeader::NExtraFlags::kFastest;
|
||||||
|
|
||||||
@@ -637,26 +577,7 @@ static HRESULT UpdateArchive(
|
|||||||
|
|
||||||
NCompress::NDeflate::NEncoder::CCOMCoder *deflateEncoderSpec = new NCompress::NDeflate::NEncoder::CCOMCoder;
|
NCompress::NDeflate::NEncoder::CCOMCoder *deflateEncoderSpec = new NCompress::NDeflate::NEncoder::CCOMCoder;
|
||||||
CMyComPtr<ICompressCoder> deflateEncoder = deflateEncoderSpec;
|
CMyComPtr<ICompressCoder> deflateEncoder = deflateEncoderSpec;
|
||||||
{
|
RINOK(deflateProps.SetCoderProperties(deflateEncoderSpec));
|
||||||
NWindows::NCOM::CPropVariant props[] =
|
|
||||||
{
|
|
||||||
compressionMode.Algo,
|
|
||||||
compressionMode.NumPasses,
|
|
||||||
compressionMode.NumFastBytes,
|
|
||||||
compressionMode.Mc
|
|
||||||
};
|
|
||||||
PROPID propIDs[] =
|
|
||||||
{
|
|
||||||
NCoderPropID::kAlgorithm,
|
|
||||||
NCoderPropID::kNumPasses,
|
|
||||||
NCoderPropID::kNumFastBytes,
|
|
||||||
NCoderPropID::kMatchFinderCycles
|
|
||||||
};
|
|
||||||
int numProps = sizeof(propIDs) / sizeof(propIDs[0]);
|
|
||||||
if (!compressionMode.McDefined)
|
|
||||||
numProps--;
|
|
||||||
RINOK(deflateEncoderSpec->SetCoderProperties(propIDs, props, numProps));
|
|
||||||
}
|
|
||||||
RINOK(deflateEncoder->Code(crcStream, outStream, NULL, NULL, progress));
|
RINOK(deflateEncoder->Code(crcStream, outStream, NULL, NULL, progress));
|
||||||
|
|
||||||
item.Crc = inStreamSpec->GetCRC();
|
item.Crc = inStreamSpec->GetCRC();
|
||||||
@@ -738,7 +659,6 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
size = prop.uhVal.QuadPart;
|
size = prop.uhVal.QuadPart;
|
||||||
}
|
}
|
||||||
|
|
||||||
_method.Normalize(_level);
|
|
||||||
return UpdateArchive(outStream, size, newItem, _method, updateCallback);
|
return UpdateArchive(outStream, size, newItem, _method, updateCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -760,49 +680,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
|
|
||||||
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
|
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
|
||||||
{
|
{
|
||||||
InitMethodProperties();
|
return _method.SetProperties(names, values, numProps);
|
||||||
for (int i = 0; i < numProps; i++)
|
|
||||||
{
|
|
||||||
UString name = names[i];
|
|
||||||
name.MakeUpper();
|
|
||||||
if (name.IsEmpty())
|
|
||||||
return E_INVALIDARG;
|
|
||||||
const PROPVARIANT &prop = values[i];
|
|
||||||
if (name[0] == L'X')
|
|
||||||
{
|
|
||||||
UInt32 level = 9;
|
|
||||||
RINOK(ParsePropValue(name.Mid(1), prop, level));
|
|
||||||
_level = level;
|
|
||||||
}
|
|
||||||
else if (name.Left(4) == L"PASS")
|
|
||||||
{
|
|
||||||
UInt32 num = kNumPassesX9;
|
|
||||||
RINOK(ParsePropValue(name.Mid(4), prop, num));
|
|
||||||
_method.NumPasses = num;
|
|
||||||
}
|
|
||||||
else if (name.Left(2) == L"FB")
|
|
||||||
{
|
|
||||||
UInt32 num = kNumFastBytesX9;
|
|
||||||
RINOK(ParsePropValue(name.Mid(2), prop, num));
|
|
||||||
_method.NumFastBytes = num;
|
|
||||||
}
|
|
||||||
else if (name.Left(2) == L"MC")
|
|
||||||
{
|
|
||||||
UInt32 num = 0xFFFFFFFF;
|
|
||||||
RINOK(ParsePropValue(name.Mid(2), prop, num));
|
|
||||||
_method.Mc = num;
|
|
||||||
_method.McDefined = true;
|
|
||||||
}
|
|
||||||
else if (name.Left(1) == L"A")
|
|
||||||
{
|
|
||||||
UInt32 num = kAlgoX5;
|
|
||||||
RINOK(ParsePropValue(name.Mid(1), prop, num));
|
|
||||||
_method.Algo = num;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static IInArchive *CreateArc() { return new CHandler; }
|
static IInArchive *CreateArc() { return new CHandler; }
|
||||||
@@ -813,7 +691,7 @@ static IOutArchive *CreateArcOut() { return new CHandler; }
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static CArcInfo g_ArcInfo =
|
static CArcInfo g_ArcInfo =
|
||||||
{ L"GZip", L"gz gzip tgz tpz", L"* * .tar .tar", 0xEF, { 0x1F, 0x8B, 8 }, 3, true, CreateArc, CreateArcOut };
|
{ L"gzip", L"gz gzip tgz tpz", L"* * .tar .tar", 0xEF, { 0x1F, 0x8B, 8 }, 3, true, CreateArc, CreateArcOut };
|
||||||
|
|
||||||
REGISTER_ARC(GZip)
|
REGISTER_ARC(GZip)
|
||||||
|
|
||||||
|
|||||||
@@ -137,12 +137,11 @@ STDMETHODIMP CHandler::Close()
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
bool testMode = (_aTestMode != 0);
|
bool allFilesMode = (numItems == (UInt32)-1);
|
||||||
bool allFilesMode = (numItems == UInt32(-1));
|
|
||||||
if (allFilesMode)
|
if (allFilesMode)
|
||||||
numItems = _db.Items.Size();
|
numItems = _db.Items.Size();
|
||||||
if (numItems == 0)
|
if (numItems == 0)
|
||||||
@@ -174,27 +173,27 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
|
|
||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
Int32 askMode = testMode ?
|
Int32 askMode = testMode ?
|
||||||
NArchive::NExtract::NAskMode::kTest :
|
NExtract::NAskMode::kTest :
|
||||||
NArchive::NExtract::NAskMode::kExtract;
|
NExtract::NAskMode::kExtract;
|
||||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||||
|
|
||||||
if (item.IsDir())
|
if (item.IsDir())
|
||||||
{
|
{
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!testMode && (!realOutStream))
|
if (!testMode && !realOutStream)
|
||||||
continue;
|
continue;
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
UInt64 pos = 0;
|
UInt64 pos = 0;
|
||||||
int res = NArchive::NExtract::NOperationResult::kOK;
|
int res = NExtract::NOperationResult::kOK;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < item.Extents.Size(); i++)
|
for (i = 0; i < item.Extents.Size(); i++)
|
||||||
{
|
{
|
||||||
if (item.Size == pos)
|
if (item.Size == pos)
|
||||||
break;
|
break;
|
||||||
if (res != NArchive::NExtract::NOperationResult::kOK)
|
if (res != NExtract::NOperationResult::kOK)
|
||||||
break;
|
break;
|
||||||
const CExtent &e = item.Extents[i];
|
const CExtent &e = item.Extents[i];
|
||||||
RINOK(_stream->Seek((UInt64)e.Pos << _db.Header.BlockSizeLog, STREAM_SEEK_SET, NULL));
|
RINOK(_stream->Seek((UInt64)e.Pos << _db.Header.BlockSizeLog, STREAM_SEEK_SET, NULL));
|
||||||
@@ -207,7 +206,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
if (rem == 0)
|
if (rem == 0)
|
||||||
{
|
{
|
||||||
if (extentSize >= (UInt64)((UInt32)1 << _db.Header.BlockSizeLog))
|
if (extentSize >= (UInt64)((UInt32)1 << _db.Header.BlockSizeLog))
|
||||||
res = NArchive::NExtract::NOperationResult::kDataError;
|
res = NExtract::NOperationResult::kDataError;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
UInt32 curSize = kBufSize;
|
UInt32 curSize = kBufSize;
|
||||||
@@ -227,7 +226,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i != item.Extents.Size() || item.Size != pos)
|
if (i != item.Extents.Size() || item.Size != pos)
|
||||||
res = NArchive::NExtract::NOperationResult::kDataError;
|
res = NExtract::NOperationResult::kDataError;
|
||||||
realOutStream.Release();
|
realOutStream.Release();
|
||||||
RINOK(extractCallback->SetOperationResult(res));
|
RINOK(extractCallback->SetOperationResult(res));
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
@@ -152,12 +152,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
|||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
bool testMode = (_aTestMode != 0);
|
bool allFilesMode = (numItems == (UInt32)-1);
|
||||||
bool allFilesMode = (numItems == UInt32(-1));
|
|
||||||
if (allFilesMode)
|
if (allFilesMode)
|
||||||
numItems = _archive.Refs.Size();
|
numItems = _archive.Refs.Size();
|
||||||
if (numItems == 0)
|
if (numItems == 0)
|
||||||
@@ -203,8 +202,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
RINOK(lps->SetCur());
|
RINOK(lps->SetCur());
|
||||||
currentItemSize = 0;
|
currentItemSize = 0;
|
||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
Int32 askMode;
|
Int32 askMode = testMode ?
|
||||||
askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract;
|
NExtract::NAskMode::kTest :
|
||||||
|
NExtract::NAskMode::kExtract;
|
||||||
UInt32 index = allFilesMode ? i : indices[i];
|
UInt32 index = allFilesMode ? i : indices[i];
|
||||||
|
|
||||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||||
@@ -217,7 +217,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
if (item.IsDir())
|
if (item.IsDir())
|
||||||
{
|
{
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
currentItemSize = item.DataLength;
|
currentItemSize = item.DataLength;
|
||||||
@@ -231,7 +231,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
blockIndex = be.LoadRBA;
|
blockIndex = be.LoadRBA;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!testMode && (!realOutStream))
|
if (!testMode && !realOutStream)
|
||||||
continue;
|
continue;
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
outStreamSpec->SetStream(realOutStream);
|
outStreamSpec->SetStream(realOutStream);
|
||||||
@@ -242,8 +242,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
|
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
|
||||||
outStreamSpec->ReleaseStream();
|
outStreamSpec->ReleaseStream();
|
||||||
RINOK(extractCallback->SetOperationResult(outStreamSpec->IsFinishedOK() ?
|
RINOK(extractCallback->SetOperationResult(outStreamSpec->IsFinishedOK() ?
|
||||||
NArchive::NExtract::NOperationResult::kOK:
|
NExtract::NOperationResult::kOK:
|
||||||
NArchive::NExtract::NOperationResult::kDataError));
|
NExtract::NOperationResult::kDataError));
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
|
|||||||
@@ -168,13 +168,11 @@ struct CItem
|
|||||||
AString GetName() const
|
AString GetName() const
|
||||||
{
|
{
|
||||||
AString dirName = GetDirName();
|
AString dirName = GetDirName();
|
||||||
dirName.Replace((char)(unsigned char)0xFF, '\\');
|
const char kDirSeparator = '\\';
|
||||||
if (!dirName.IsEmpty())
|
// check kDirSeparator in Linux
|
||||||
{
|
dirName.Replace((char)(unsigned char)0xFF, kDirSeparator);
|
||||||
char c = dirName[dirName.Length() - 1];
|
if (!dirName.IsEmpty() && dirName.Back() != kDirSeparator)
|
||||||
if (c != '\\')
|
dirName += kDirSeparator;
|
||||||
dirName += '\\';
|
|
||||||
}
|
|
||||||
return dirName + GetFileName();
|
return dirName + GetFileName();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -469,7 +467,7 @@ STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *pro
|
|||||||
{
|
{
|
||||||
UInt32 realProcessedSize;
|
UInt32 realProcessedSize;
|
||||||
HRESULT result;
|
HRESULT result;
|
||||||
if(!_stream)
|
if (!_stream)
|
||||||
{
|
{
|
||||||
realProcessedSize = size;
|
realProcessedSize = size;
|
||||||
result = S_OK;
|
result = S_OK;
|
||||||
@@ -477,7 +475,7 @@ STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *pro
|
|||||||
else
|
else
|
||||||
result = _stream->Write(data, size, &realProcessedSize);
|
result = _stream->Write(data, size, &realProcessedSize);
|
||||||
_crc.Update(data, realProcessedSize);
|
_crc.Update(data, realProcessedSize);
|
||||||
if(processedSize != NULL)
|
if (processedSize != NULL)
|
||||||
*processedSize = realProcessedSize;
|
*processedSize = realProcessedSize;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -630,24 +628,19 @@ STDMETHODIMP CHandler::Close()
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
|
|
||||||
//////////////////////////////////////
|
|
||||||
// CHandler::DecompressItems
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|
||||||
Int32 testModeSpec, IArchiveExtractCallback *extractCallback)
|
Int32 testModeSpec, IArchiveExtractCallback *extractCallback)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
bool testMode = (testModeSpec != 0);
|
bool testMode = (testModeSpec != 0);
|
||||||
UInt64 totalUnPacked = 0, totalPacked = 0;
|
UInt64 totalUnPacked = 0, totalPacked = 0;
|
||||||
bool allFilesMode = (numItems == UInt32(-1));
|
bool allFilesMode = (numItems == (UInt32)-1);
|
||||||
if (allFilesMode)
|
if (allFilesMode)
|
||||||
numItems = _items.Size();
|
numItems = _items.Size();
|
||||||
if(numItems == 0)
|
if (numItems == 0)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
for(i = 0; i < numItems; i++)
|
for (i = 0; i < numItems; i++)
|
||||||
{
|
{
|
||||||
const CItemEx &item = _items[allFilesMode ? i : indices[i]];
|
const CItemEx &item = _items[allFilesMode ? i : indices[i]];
|
||||||
totalUnPacked += item.Size;
|
totalUnPacked += item.Size;
|
||||||
@@ -674,7 +667,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
CMyComPtr<ISequentialInStream> inStream(streamSpec);
|
CMyComPtr<ISequentialInStream> inStream(streamSpec);
|
||||||
streamSpec->SetStream(_stream);
|
streamSpec->SetStream(_stream);
|
||||||
|
|
||||||
for(i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked,
|
for (i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked,
|
||||||
currentTotalPacked += currentItemPacked)
|
currentTotalPacked += currentItemPacked)
|
||||||
{
|
{
|
||||||
currentItemUnPacked = 0;
|
currentItemUnPacked = 0;
|
||||||
@@ -702,7 +695,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!testMode && (!realOutStream))
|
if (!testMode && !realOutStream)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
|
|||||||
@@ -319,28 +319,23 @@ STDMETHODIMP CHandler::Close()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
bool allFilesMode = (numItems == (UInt32)-1);
|
|
||||||
if (!allFilesMode)
|
|
||||||
{
|
|
||||||
if (numItems == 0)
|
if (numItems == 0)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
if (numItems != 1 || indices[0] != 0)
|
if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0))
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
}
|
|
||||||
|
|
||||||
bool testMode = (_aTestMode != 0);
|
|
||||||
if (_stream)
|
if (_stream)
|
||||||
extractCallback->SetTotal(_packSize);
|
extractCallback->SetTotal(_packSize);
|
||||||
|
|
||||||
|
|
||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
Int32 askMode = testMode ?
|
Int32 askMode = testMode ?
|
||||||
NArchive::NExtract::NAskMode::kTest :
|
NExtract::NAskMode::kTest :
|
||||||
NArchive::NExtract::NAskMode::kExtract;
|
NExtract::NAskMode::kExtract;
|
||||||
RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
|
RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
|
||||||
if (!testMode && !realOutStream)
|
if (!testMode && !realOutStream)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
@@ -368,7 +363,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
_lzma86, _seqStream);
|
_lzma86, _seqStream);
|
||||||
RINOK(result);
|
RINOK(result);
|
||||||
|
|
||||||
Int32 opRes = NArchive::NExtract::NOperationResult::kOK;
|
Int32 opRes = NExtract::NOperationResult::kOK;
|
||||||
bool firstItem = true;
|
bool firstItem = true;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
@@ -395,12 +390,12 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
result = decoder.Code(st, outStream, progress);
|
result = decoder.Code(st, outStream, progress);
|
||||||
if (result == E_NOTIMPL)
|
if (result == E_NOTIMPL)
|
||||||
{
|
{
|
||||||
opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod;
|
opRes = NExtract::NOperationResult::kUnSupportedMethod;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (result == S_FALSE)
|
if (result == S_FALSE)
|
||||||
{
|
{
|
||||||
opRes = NArchive::NExtract::NOperationResult::kDataError;
|
opRes = NExtract::NOperationResult::kDataError;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
RINOK(result);
|
RINOK(result);
|
||||||
|
|||||||
@@ -399,12 +399,11 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
bool testMode = (_aTestMode != 0);
|
bool allFilesMode = (numItems == (UInt32)-1);
|
||||||
bool allFilesMode = (numItems == UInt32(-1));
|
|
||||||
if (allFilesMode)
|
if (allFilesMode)
|
||||||
numItems = _sections.Size();
|
numItems = _sections.Size();
|
||||||
if (numItems == 0)
|
if (numItems == 0)
|
||||||
@@ -434,8 +433,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
lps->InSize = lps->OutSize = currentTotalSize;
|
lps->InSize = lps->OutSize = currentTotalSize;
|
||||||
RINOK(lps->SetCur());
|
RINOK(lps->SetCur());
|
||||||
Int32 askMode = testMode ?
|
Int32 askMode = testMode ?
|
||||||
NArchive::NExtract::NAskMode::kTest :
|
NExtract::NAskMode::kTest :
|
||||||
NArchive::NExtract::NAskMode::kExtract;
|
NExtract::NAskMode::kExtract;
|
||||||
UInt32 index = allFilesMode ? i : indices[i];
|
UInt32 index = allFilesMode ? i : indices[i];
|
||||||
const CSection &item = _sections[index];
|
const CSection &item = _sections[index];
|
||||||
currentItemSize = item.GetPackSize();
|
currentItemSize = item.GetPackSize();
|
||||||
@@ -451,8 +450,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
|
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
|
||||||
outStream.Release();
|
outStream.Release();
|
||||||
RINOK(extractCallback->SetOperationResult(copyCoderSpec->TotalSize == currentItemSize ?
|
RINOK(extractCallback->SetOperationResult(copyCoderSpec->TotalSize == currentItemSize ?
|
||||||
NArchive::NExtract::NOperationResult::kOK:
|
NExtract::NOperationResult::kOK:
|
||||||
NArchive::NExtract::NOperationResult::kDataError));
|
NExtract::NOperationResult::kDataError));
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
|
|||||||
@@ -431,12 +431,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
|||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
bool testMode = (_aTestMode != 0);
|
bool allFilesMode = (numItems == (UInt32)-1);
|
||||||
bool allFilesMode = (numItems == UInt32(-1));
|
|
||||||
if (allFilesMode)
|
if (allFilesMode)
|
||||||
numItems = _items.Size();
|
numItems = _items.Size();
|
||||||
if (numItems == 0)
|
if (numItems == 0)
|
||||||
@@ -467,14 +466,14 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
RINOK(lps->SetCur());
|
RINOK(lps->SetCur());
|
||||||
CMyComPtr<ISequentialOutStream> outStream;
|
CMyComPtr<ISequentialOutStream> outStream;
|
||||||
Int32 askMode = testMode ?
|
Int32 askMode = testMode ?
|
||||||
NArchive::NExtract::NAskMode::kTest :
|
NExtract::NAskMode::kTest :
|
||||||
NArchive::NExtract::NAskMode::kExtract;
|
NExtract::NAskMode::kExtract;
|
||||||
Int32 index = allFilesMode ? i : indices[i];
|
Int32 index = allFilesMode ? i : indices[i];
|
||||||
const CItem &item = _items[index];
|
const CItem &item = _items[index];
|
||||||
const CPartition &part = item.Part;
|
const CPartition &part = item.Part;
|
||||||
RINOK(extractCallback->GetStream(index, &outStream, askMode));
|
RINOK(extractCallback->GetStream(index, &outStream, askMode));
|
||||||
totalSize += item.Size;
|
totalSize += item.Size;
|
||||||
if (!testMode && (!outStream))
|
if (!testMode && !outStream)
|
||||||
continue;
|
continue;
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
|
|
||||||
@@ -483,8 +482,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
|
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
|
||||||
outStream.Release();
|
outStream.Release();
|
||||||
RINOK(extractCallback->SetOperationResult(copyCoderSpec->TotalSize == item.Size ?
|
RINOK(extractCallback->SetOperationResult(copyCoderSpec->TotalSize == item.Size ?
|
||||||
NArchive::NExtract::NOperationResult::kOK:
|
NExtract::NOperationResult::kOK:
|
||||||
NArchive::NExtract::NOperationResult::kDataError));
|
NExtract::NOperationResult::kDataError));
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
|
|||||||
257
CPP/7zip/Archive/MslzHandler.cpp
Executable file
257
CPP/7zip/Archive/MslzHandler.cpp
Executable file
@@ -0,0 +1,257 @@
|
|||||||
|
// MslzHandler.cpp
|
||||||
|
|
||||||
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
#include "../../../C/CpuArch.h"
|
||||||
|
|
||||||
|
#include "Common/ComTry.h"
|
||||||
|
#include "Common/MyString.h"
|
||||||
|
|
||||||
|
#include "Windows/PropVariant.h"
|
||||||
|
|
||||||
|
#include "../Common/InBuffer.h"
|
||||||
|
#include "../Common/ProgressUtils.h"
|
||||||
|
#include "../Common/RegisterArc.h"
|
||||||
|
#include "../Common/StreamUtils.h"
|
||||||
|
|
||||||
|
#include "Common/DummyOutStream.h"
|
||||||
|
|
||||||
|
namespace NArchive {
|
||||||
|
namespace NMslz {
|
||||||
|
|
||||||
|
class CHandler:
|
||||||
|
public IInArchive,
|
||||||
|
public CMyUnknownImp
|
||||||
|
{
|
||||||
|
CMyComPtr<IInStream> _stream;
|
||||||
|
UInt32 _size;
|
||||||
|
UInt64 _packSize;
|
||||||
|
UString _name;
|
||||||
|
public:
|
||||||
|
MY_UNKNOWN_IMP1(IInArchive)
|
||||||
|
INTERFACE_IInArchive(;)
|
||||||
|
};
|
||||||
|
|
||||||
|
STATPROPSTG kProps[] =
|
||||||
|
{
|
||||||
|
{ NULL, kpidPath, VT_BSTR},
|
||||||
|
{ NULL, kpidSize, VT_UI8},
|
||||||
|
{ NULL, kpidPackSize, VT_UI8},
|
||||||
|
};
|
||||||
|
|
||||||
|
IMP_IInArchive_Props
|
||||||
|
IMP_IInArchive_ArcProps_NO
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||||
|
{
|
||||||
|
*numItems = 1;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
|
||||||
|
{
|
||||||
|
COM_TRY_BEGIN
|
||||||
|
NWindows::NCOM::CPropVariant prop;
|
||||||
|
switch(propID)
|
||||||
|
{
|
||||||
|
case kpidPath: if (!_name.IsEmpty()) prop = _name; break;
|
||||||
|
case kpidSize: prop = _size; break;
|
||||||
|
case kpidPackSize: prop = _packSize; break;
|
||||||
|
}
|
||||||
|
prop.Detach(value);
|
||||||
|
return S_OK;
|
||||||
|
COM_TRY_END
|
||||||
|
}
|
||||||
|
|
||||||
|
static const unsigned kSignatureSize = 9;
|
||||||
|
static const unsigned kHeaderSize = kSignatureSize + 1 + 4;
|
||||||
|
#define MSLZ_SIGNATURE { 0x53, 0x5A, 0x44, 0x44, 0x88, 0xF0, 0x27, 0x33, 0x41 }
|
||||||
|
// old signature: 53 5A 20 88 F0 27 33
|
||||||
|
static const Byte signature[kSignatureSize] = MSLZ_SIGNATURE;
|
||||||
|
|
||||||
|
static const wchar_t *g_Exts[] =
|
||||||
|
{
|
||||||
|
L"dll",
|
||||||
|
L"exe",
|
||||||
|
L"kmd",
|
||||||
|
L"sys"
|
||||||
|
};
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 * /* maxCheckStartPosition */,
|
||||||
|
IArchiveOpenCallback *callback)
|
||||||
|
{
|
||||||
|
COM_TRY_BEGIN
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
Byte buffer[kHeaderSize];
|
||||||
|
RINOK(ReadStream_FALSE(stream, buffer, kHeaderSize));
|
||||||
|
if (memcmp(buffer, signature, kSignatureSize) != 0)
|
||||||
|
return S_FALSE;
|
||||||
|
_size = GetUi32(buffer + 10);
|
||||||
|
if (_size > 0xFFFFFFE0)
|
||||||
|
return S_FALSE;
|
||||||
|
RINOK(stream->Seek(0, STREAM_SEEK_END, &_packSize));
|
||||||
|
|
||||||
|
if (callback)
|
||||||
|
{
|
||||||
|
CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
|
||||||
|
callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback);
|
||||||
|
if (openVolumeCallback)
|
||||||
|
{
|
||||||
|
NWindows::NCOM::CPropVariant prop;
|
||||||
|
if (openVolumeCallback->GetProperty(kpidName, &prop) == S_OK && prop.vt == VT_BSTR)
|
||||||
|
{
|
||||||
|
UString baseName = prop.bstrVal;
|
||||||
|
if (!baseName.IsEmpty() && baseName.Back() == L'_')
|
||||||
|
{
|
||||||
|
baseName.DeleteBack();
|
||||||
|
Byte replaceByte = buffer[kSignatureSize];
|
||||||
|
if (replaceByte == 0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < sizeof(g_Exts) / sizeof(g_Exts[0]); i++)
|
||||||
|
{
|
||||||
|
UString s = g_Exts[i];
|
||||||
|
int len = s.Length();
|
||||||
|
Byte b = (Byte)s.Back();
|
||||||
|
s.DeleteBack();
|
||||||
|
if (baseName.Length() >= len &&
|
||||||
|
baseName[baseName.Length() - len] == '.' &&
|
||||||
|
s.CompareNoCase(baseName.Right(len - 1)) == 0)
|
||||||
|
{
|
||||||
|
replaceByte = b;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (replaceByte >= 0x20 && replaceByte < 0x80)
|
||||||
|
_name = baseName + (wchar_t)replaceByte;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_stream = stream;
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
COM_TRY_END
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::Close()
|
||||||
|
{
|
||||||
|
_stream.Release();
|
||||||
|
_name.Empty();
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MslzDec is modified LZSS algorithm of Haruhiko Okumura:
|
||||||
|
// maxLen = 18; Okumura
|
||||||
|
// maxLen = 16; MS
|
||||||
|
|
||||||
|
#define PROGRESS_AND_WRITE \
|
||||||
|
if ((dest & kMask) == 0) { RINOK(WriteStream(outStream, buf, kBufSize)); \
|
||||||
|
if ((dest & ((1 << 20) - 1)) == 0) \
|
||||||
|
{ UInt64 inSize = inStream.GetProcessedSize(); UInt64 outSize = dest; \
|
||||||
|
RINOK(progress->SetRatioInfo(&inSize, &outSize)); }}
|
||||||
|
|
||||||
|
static HRESULT MslzDec(CInBuffer &inStream, ISequentialOutStream *outStream, UInt32 unpackSize, ICompressProgressInfo *progress)
|
||||||
|
{
|
||||||
|
const unsigned kBufSize = (1 << 12);
|
||||||
|
const unsigned kMask = kBufSize - 1;
|
||||||
|
Byte buf[kBufSize];
|
||||||
|
UInt32 dest = 0;
|
||||||
|
memset(buf, ' ', kBufSize);
|
||||||
|
while (dest < unpackSize)
|
||||||
|
{
|
||||||
|
Byte b;
|
||||||
|
if (!inStream.ReadByte(b))
|
||||||
|
return S_FALSE;
|
||||||
|
for (unsigned mask = (unsigned)b | 0x100; mask > 1 && dest < unpackSize; mask >>= 1)
|
||||||
|
{
|
||||||
|
if (!inStream.ReadByte(b))
|
||||||
|
return S_FALSE;
|
||||||
|
if (mask & 1)
|
||||||
|
{
|
||||||
|
buf[dest++ & kMask] = b;
|
||||||
|
PROGRESS_AND_WRITE
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Byte b1;
|
||||||
|
if (!inStream.ReadByte(b1))
|
||||||
|
return S_FALSE;
|
||||||
|
const unsigned kMaxLen = 16; // 18 in Okumura's code.
|
||||||
|
unsigned src = (((((unsigned)b1 & 0xF0) << 4) | b) + kMaxLen) & kMask;
|
||||||
|
unsigned len = (b1 & 0xF) + 3;
|
||||||
|
if (len > kMaxLen || dest + len > unpackSize)
|
||||||
|
return S_FALSE;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
buf[dest++ & kMask] = buf[src++ & kMask];
|
||||||
|
PROGRESS_AND_WRITE
|
||||||
|
}
|
||||||
|
while (--len != 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return WriteStream(outStream, buf, dest & kMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
|
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||||
|
{
|
||||||
|
COM_TRY_BEGIN
|
||||||
|
if (numItems == 0)
|
||||||
|
return S_OK;
|
||||||
|
if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0))
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
extractCallback->SetTotal(_size);
|
||||||
|
|
||||||
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
|
Int32 askMode = testMode ?
|
||||||
|
NExtract::NAskMode::kTest :
|
||||||
|
NExtract::NAskMode::kExtract;
|
||||||
|
RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
|
||||||
|
if (!testMode && !realOutStream)
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
|
extractCallback->PrepareOperation(askMode);
|
||||||
|
|
||||||
|
CDummyOutStream *outStreamSpec = new CDummyOutStream;
|
||||||
|
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
|
||||||
|
outStreamSpec->SetStream(realOutStream);
|
||||||
|
outStreamSpec->Init();
|
||||||
|
realOutStream.Release();
|
||||||
|
|
||||||
|
CLocalProgress *lps = new CLocalProgress;
|
||||||
|
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||||
|
lps->Init(extractCallback, false);
|
||||||
|
|
||||||
|
RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL));
|
||||||
|
CInBuffer s;
|
||||||
|
if (!s.Create(1 << 20))
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
s.SetStream(_stream);
|
||||||
|
s.Init();
|
||||||
|
Byte buffer[kHeaderSize];
|
||||||
|
Int32 opRes = NExtract::NOperationResult::kDataError;
|
||||||
|
if (s.ReadBytes(buffer, kHeaderSize) == kHeaderSize)
|
||||||
|
{
|
||||||
|
HRESULT result = MslzDec(s, outStream, _size, progress);
|
||||||
|
if (result == S_OK)
|
||||||
|
opRes = NExtract::NOperationResult::kOK;
|
||||||
|
else if (result != S_FALSE)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
outStream.Release();
|
||||||
|
return extractCallback->SetOperationResult(opRes);
|
||||||
|
COM_TRY_END
|
||||||
|
}
|
||||||
|
|
||||||
|
static IInArchive *CreateArc() { return new CHandler; }
|
||||||
|
|
||||||
|
static CArcInfo g_ArcInfo =
|
||||||
|
{ L"MsLZ", L"", 0, 0xD5, MSLZ_SIGNATURE, kSignatureSize, false, CreateArc, 0 };
|
||||||
|
|
||||||
|
REGISTER_ARC(Mslz)
|
||||||
|
|
||||||
|
}}
|
||||||
@@ -187,12 +187,11 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
bool testMode = (_aTestMode != 0);
|
bool allFilesMode = (numItems == (UInt32)-1);
|
||||||
bool allFilesMode = (numItems == UInt32(-1));
|
|
||||||
if (allFilesMode)
|
if (allFilesMode)
|
||||||
numItems = _numItems;
|
numItems = _numItems;
|
||||||
if (numItems == 0)
|
if (numItems == 0)
|
||||||
@@ -222,19 +221,19 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
RINOK(lps->SetCur());
|
RINOK(lps->SetCur());
|
||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
Int32 askMode = testMode ?
|
Int32 askMode = testMode ?
|
||||||
NArchive::NExtract::NAskMode::kTest :
|
NExtract::NAskMode::kTest :
|
||||||
NArchive::NExtract::NAskMode::kExtract;
|
NExtract::NAskMode::kExtract;
|
||||||
UInt32 index = allFilesMode ? i : indices[i];
|
UInt32 index = allFilesMode ? i : indices[i];
|
||||||
const CItem &item = _items[index];
|
const CItem &item = _items[index];
|
||||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||||
currentTotalSize += item.Size;
|
currentTotalSize += item.Size;
|
||||||
|
|
||||||
if (!testMode && (!realOutStream))
|
if (!testMode && !realOutStream)
|
||||||
continue;
|
continue;
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
if (testMode)
|
if (testMode)
|
||||||
{
|
{
|
||||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
RINOK(_stream->Seek(_startPos + item.Offset, STREAM_SEEK_SET, NULL));
|
RINOK(_stream->Seek(_startPos + item.Offset, STREAM_SEEK_SET, NULL));
|
||||||
@@ -242,8 +241,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
|
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
|
||||||
realOutStream.Release();
|
realOutStream.Release();
|
||||||
RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ?
|
RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ?
|
||||||
NArchive::NExtract::NOperationResult::kOK:
|
NExtract::NOperationResult::kOK:
|
||||||
NArchive::NExtract::NOperationResult::kDataError));
|
NExtract::NOperationResult::kDataError));
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
|
|||||||
@@ -263,12 +263,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
|||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
bool testMode = (_aTestMode != 0);
|
bool allFilesMode = (numItems == (UInt32)-1);
|
||||||
bool allFilesMode = (numItems == UInt32(-1));
|
|
||||||
if (allFilesMode)
|
if (allFilesMode)
|
||||||
GetNumberOfItems(&numItems);
|
GetNumberOfItems(&numItems);
|
||||||
if(numItems == 0)
|
if(numItems == 0)
|
||||||
@@ -326,8 +325,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
currentItemSize = 0;
|
currentItemSize = 0;
|
||||||
RINOK(extractCallback->SetCompleted(¤tTotalSize));
|
RINOK(extractCallback->SetCompleted(¤tTotalSize));
|
||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
Int32 askMode;
|
Int32 askMode = testMode ?
|
||||||
askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract;
|
NExtract::NAskMode::kTest :
|
||||||
|
NExtract::NAskMode::kExtract;
|
||||||
UInt32 index = allFilesMode ? i : indices[i];
|
UInt32 index = allFilesMode ? i : indices[i];
|
||||||
|
|
||||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||||
@@ -336,7 +336,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
if (index >= (UInt32)_archive.Items.Size())
|
if (index >= (UInt32)_archive.Items.Size())
|
||||||
{
|
{
|
||||||
currentItemSize = _archive.Script.Length();
|
currentItemSize = _archive.Script.Length();
|
||||||
if(!testMode && (!realOutStream))
|
if(!testMode && !realOutStream)
|
||||||
continue;
|
continue;
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
if (!testMode)
|
if (!testMode)
|
||||||
@@ -352,7 +352,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
else
|
else
|
||||||
GetCompressedSize(index, currentItemSize);
|
GetCompressedSize(index, currentItemSize);
|
||||||
|
|
||||||
if(!testMode && (!realOutStream))
|
if(!testMode && !realOutStream)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
@@ -477,8 +477,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
}
|
}
|
||||||
realOutStream.Release();
|
realOutStream.Release();
|
||||||
RINOK(extractCallback->SetOperationResult(dataError ?
|
RINOK(extractCallback->SetOperationResult(dataError ?
|
||||||
NArchive::NExtract::NOperationResult::kDataError :
|
NExtract::NOperationResult::kDataError :
|
||||||
NArchive::NExtract::NOperationResult::kOK));
|
NExtract::NOperationResult::kOK));
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
|
|||||||
@@ -1,30 +1,21 @@
|
|||||||
// Archive/NsisIn.cpp
|
// NsisIn.cpp
|
||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
// #include <stdio.h>
|
#include "../../../../C/CpuArch.h"
|
||||||
|
|
||||||
#include "NsisIn.h"
|
#include "Common/IntToString.h"
|
||||||
#include "NsisDecode.h"
|
|
||||||
|
|
||||||
#include "Windows/Defs.h"
|
|
||||||
|
|
||||||
#include "../../Common/StreamUtils.h"
|
#include "../../Common/StreamUtils.h"
|
||||||
|
|
||||||
#include "Common/StringConvert.h"
|
#include "NsisIn.h"
|
||||||
#include "Common/IntToString.h"
|
|
||||||
|
|
||||||
#include "../../../../C/CpuArch.h"
|
|
||||||
|
|
||||||
#define Get32(p) GetUi32(p)
|
#define Get32(p) GetUi32(p)
|
||||||
|
|
||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace NNsis {
|
namespace NNsis {
|
||||||
|
|
||||||
Byte kSignature[kSignatureSize] = { 0xEF + 1, 0xBE, 0xAD, 0xDE,
|
Byte kSignature[kSignatureSize] = NSIS_SIGNATURE;
|
||||||
0x4E, 0x75, 0x6C, 0x6C, 0x73, 0x6F, 0x66, 0x74, 0x49, 0x6E, 0x73, 0x74};
|
|
||||||
|
|
||||||
struct CSignatureInit { CSignatureInit() { kSignature[0]--; } } g_SignatureInit;
|
|
||||||
|
|
||||||
#ifdef NSIS_SCRIPT
|
#ifdef NSIS_SCRIPT
|
||||||
static const char *kCrLf = "\x0D\x0A";
|
static const char *kCrLf = "\x0D\x0A";
|
||||||
|
|||||||
@@ -1,17 +1,12 @@
|
|||||||
// Archive/NsisIn.h
|
// NsisIn.h
|
||||||
|
|
||||||
#ifndef __ARCHIVE_NSIS_IN_H
|
#ifndef __ARCHIVE_NSIS_IN_H
|
||||||
#define __ARCHIVE_NSIS_IN_H
|
#define __ARCHIVE_NSIS_IN_H
|
||||||
|
|
||||||
#include "Common/Buffer.h"
|
#include "Common/Buffer.h"
|
||||||
#include "Common/IntToString.h"
|
|
||||||
#include "Common/MyCom.h"
|
#include "Common/MyCom.h"
|
||||||
#include "Common/StringConvert.h"
|
#include "Common/StringConvert.h"
|
||||||
|
|
||||||
#include "../../Common/CreateCoder.h"
|
|
||||||
|
|
||||||
#include "../../IStream.h"
|
|
||||||
|
|
||||||
#include "NsisDecode.h"
|
#include "NsisDecode.h"
|
||||||
|
|
||||||
// #define NSIS_SCRIPT
|
// #define NSIS_SCRIPT
|
||||||
@@ -20,6 +15,8 @@ namespace NArchive {
|
|||||||
namespace NNsis {
|
namespace NNsis {
|
||||||
|
|
||||||
const int kSignatureSize = 16;
|
const int kSignatureSize = 16;
|
||||||
|
#define NSIS_SIGNATURE { 0xEF, 0xBE, 0xAD, 0xDE, 0x4E, 0x75, 0x6C, 0x6C, 0x73, 0x6F, 0x66, 0x74, 0x49, 0x6E, 0x73, 0x74}
|
||||||
|
|
||||||
extern Byte kSignature[kSignatureSize];
|
extern Byte kSignature[kSignatureSize];
|
||||||
|
|
||||||
const UInt32 kFlagsMask = 0xF;
|
const UInt32 kFlagsMask = 0xF;
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
static IInArchive *CreateArc() { return new NArchive::NNsis::CHandler; }
|
static IInArchive *CreateArc() { return new NArchive::NNsis::CHandler; }
|
||||||
|
|
||||||
static CArcInfo g_ArcInfo =
|
static CArcInfo g_ArcInfo =
|
||||||
{ L"Nsis", 0, 0, 0x9, { 0xEF, 0xBE, 0xAD, 0xDE,
|
{ L"Nsis", L"", 0, 0x9, NSIS_SIGNATURE, NArchive::NNsis::kSignatureSize, false, CreateArc, 0 };
|
||||||
0x4E, 0x75, 0x6C, 0x6C, 0x73, 0x6F, 0x66, 0x74, 0x49, 0x6E, 0x73, 0x74}, 16, false, CreateArc, 0 };
|
|
||||||
|
|
||||||
REGISTER_ARC(Nsis)
|
REGISTER_ARC(Nsis)
|
||||||
|
|||||||
@@ -124,7 +124,11 @@ bool CHeader::Parse(const Byte *p)
|
|||||||
// DriveNumber = p[0x24];
|
// DriveNumber = p[0x24];
|
||||||
if (p[0x25] != 0) // CurrentHead
|
if (p[0x25] != 0) // CurrentHead
|
||||||
return false;
|
return false;
|
||||||
if (p[0x26] != 0x80) // ExtendedBootSig
|
/*
|
||||||
|
NTFS-HDD: p[0x26] = 0x80
|
||||||
|
NTFS-FLASH: p[0x26] = 0
|
||||||
|
*/
|
||||||
|
if (p[0x26] != 0x80 && p[0x26] != 0) // ExtendedBootSig
|
||||||
return false;
|
return false;
|
||||||
if (p[0x27] != 0) // reserved
|
if (p[0x27] != 0) // reserved
|
||||||
return false;
|
return false;
|
||||||
@@ -916,6 +920,9 @@ struct CDataRef
|
|||||||
int Num;
|
int Num;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const UInt32 kMagic_FILE = 0x454c4946;
|
||||||
|
static const UInt32 kMagic_BAAD = 0x44414142;
|
||||||
|
|
||||||
struct CMftRec
|
struct CMftRec
|
||||||
{
|
{
|
||||||
UInt32 Magic;
|
UInt32 Magic;
|
||||||
@@ -934,7 +941,6 @@ struct CMftRec
|
|||||||
|
|
||||||
CSiAttr SiAttr;
|
CSiAttr SiAttr;
|
||||||
|
|
||||||
|
|
||||||
void MoveAttrsFrom(CMftRec &src)
|
void MoveAttrsFrom(CMftRec &src)
|
||||||
{
|
{
|
||||||
DataAttrs += src.DataAttrs;
|
DataAttrs += src.DataAttrs;
|
||||||
@@ -954,6 +960,8 @@ struct CMftRec
|
|||||||
bool Parse(Byte *p, int sectorSizeLog, UInt32 numSectors, UInt32 recNumber, CObjectVector<CAttr> *attrs);
|
bool Parse(Byte *p, int sectorSizeLog, UInt32 numSectors, UInt32 recNumber, CObjectVector<CAttr> *attrs);
|
||||||
|
|
||||||
bool IsEmpty() const { return (Magic <= 2); }
|
bool IsEmpty() const { return (Magic <= 2); }
|
||||||
|
bool IsFILE() const { return (Magic == kMagic_FILE); }
|
||||||
|
bool IsBAAD() const { return (Magic == kMagic_BAAD); }
|
||||||
|
|
||||||
bool InUse() const { return (Flags & 1) != 0; }
|
bool InUse() const { return (Flags & 1) != 0; }
|
||||||
bool IsDir() const { return (Flags & 2) != 0; }
|
bool IsDir() const { return (Flags & 2) != 0; }
|
||||||
@@ -1032,10 +1040,8 @@ bool CMftRec::Parse(Byte *p, int sectorSizeLog, UInt32 numSectors, UInt32 recNum
|
|||||||
CObjectVector<CAttr> *attrs)
|
CObjectVector<CAttr> *attrs)
|
||||||
{
|
{
|
||||||
G32(p, Magic);
|
G32(p, Magic);
|
||||||
if (IsEmpty())
|
if (!IsFILE())
|
||||||
return true;
|
return IsEmpty() || IsBAAD();
|
||||||
if (Magic != 0x454c4946)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
UInt32 usaOffset;
|
UInt32 usaOffset;
|
||||||
UInt32 numUsaItems;
|
UInt32 numUsaItems;
|
||||||
@@ -1246,7 +1252,7 @@ HRESULT CDatabase::Open()
|
|||||||
numSectorsInRec = 1 << (recSizeLog - Header.SectorSizeLog);
|
numSectorsInRec = 1 << (recSizeLog - Header.SectorSizeLog);
|
||||||
if (!mftRec.Parse(ByteBuf, Header.SectorSizeLog, numSectorsInRec, NULL, 0))
|
if (!mftRec.Parse(ByteBuf, Header.SectorSizeLog, numSectorsInRec, NULL, 0))
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
if (mftRec.IsEmpty())
|
if (!mftRec.IsFILE())
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
mftRec.ParseDataNames();
|
mftRec.ParseDataNames();
|
||||||
if (mftRec.DataRefs.IsEmpty())
|
if (mftRec.DataRefs.IsEmpty())
|
||||||
@@ -1331,7 +1337,7 @@ HRESULT CDatabase::Open()
|
|||||||
for (i = 0; i < Recs.Size(); i++)
|
for (i = 0; i < Recs.Size(); i++)
|
||||||
{
|
{
|
||||||
CMftRec &rec = Recs[i];
|
CMftRec &rec = Recs[i];
|
||||||
if (rec.IsEmpty() || !rec.BaseMftRef.IsBaseItself())
|
if (!rec.IsFILE() || !rec.BaseMftRef.IsBaseItself())
|
||||||
continue;
|
continue;
|
||||||
int numNames = 0;
|
int numNames = 0;
|
||||||
// printf("\n%4d: ", i);
|
// printf("\n%4d: ", i);
|
||||||
@@ -1610,12 +1616,11 @@ STDMETHODIMP CHandler::Close()
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
bool testMode = (_aTestMode != 0);
|
bool allFilesMode = (numItems == (UInt32)-1);
|
||||||
bool allFilesMode = (numItems == UInt32(-1));
|
|
||||||
if (allFilesMode)
|
if (allFilesMode)
|
||||||
numItems = Items.Size();
|
numItems = Items.Size();
|
||||||
if (numItems == 0)
|
if (numItems == 0)
|
||||||
@@ -1655,8 +1660,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
RINOK(lps->SetCur());
|
RINOK(lps->SetCur());
|
||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
Int32 askMode = testMode ?
|
Int32 askMode = testMode ?
|
||||||
NArchive::NExtract::NAskMode::kTest :
|
NExtract::NAskMode::kTest :
|
||||||
NArchive::NExtract::NAskMode::kExtract;
|
NExtract::NAskMode::kExtract;
|
||||||
Int32 index = allFilesMode ? i : indices[i];
|
Int32 index = allFilesMode ? i : indices[i];
|
||||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||||
|
|
||||||
@@ -1664,11 +1669,11 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
if (item.IsDir())
|
if (item.IsDir())
|
||||||
{
|
{
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!testMode && (!realOutStream))
|
if (!testMode && !realOutStream)
|
||||||
continue;
|
continue;
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
|
|
||||||
@@ -1679,12 +1684,12 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
const CMftRec &rec = Recs[item.RecIndex];
|
const CMftRec &rec = Recs[item.RecIndex];
|
||||||
const CAttr &data = rec.DataAttrs[rec.DataRefs[item.DataIndex].Start];
|
const CAttr &data = rec.DataAttrs[rec.DataRefs[item.DataIndex].Start];
|
||||||
|
|
||||||
int res = NArchive::NExtract::NOperationResult::kDataError;
|
int res = NExtract::NOperationResult::kDataError;
|
||||||
{
|
{
|
||||||
CMyComPtr<IInStream> inStream;
|
CMyComPtr<IInStream> inStream;
|
||||||
HRESULT hres = rec.GetStream(InStream, item.DataIndex, Header.ClusterSizeLog, Header.NumClusters, &inStream);
|
HRESULT hres = rec.GetStream(InStream, item.DataIndex, Header.ClusterSizeLog, Header.NumClusters, &inStream);
|
||||||
if (hres == S_FALSE)
|
if (hres == S_FALSE)
|
||||||
res = NArchive::NExtract::NOperationResult::kUnSupportedMethod;
|
res = NExtract::NOperationResult::kUnSupportedMethod;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RINOK(hres);
|
RINOK(hres);
|
||||||
@@ -1696,7 +1701,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
RINOK(hres);
|
RINOK(hres);
|
||||||
}
|
}
|
||||||
if (/* copyCoderSpec->TotalSize == item.GetSize() && */ hres == S_OK)
|
if (/* copyCoderSpec->TotalSize == item.GetSize() && */ hres == S_OK)
|
||||||
res = NArchive::NExtract::NOperationResult::kOK;
|
res = NExtract::NOperationResult::kOK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -350,7 +350,7 @@ HRESULT CHandler::Open2(IInStream *stream,
|
|||||||
if (!openVolumeCallback)
|
if (!openVolumeCallback)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if(_archives.Size() == 1)
|
if (_archives.Size() == 1)
|
||||||
{
|
{
|
||||||
if (!_archiveInfo.IsVolume())
|
if (!_archiveInfo.IsVolume())
|
||||||
break;
|
break;
|
||||||
@@ -395,9 +395,14 @@ HRESULT CHandler::Open2(IInStream *stream,
|
|||||||
CItemEx item;
|
CItemEx item;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
HRESULT result = archive.GetNextItem(item, getTextPassword);
|
bool decryptionError;
|
||||||
|
HRESULT result = archive.GetNextItem(item, getTextPassword, decryptionError);
|
||||||
if (result == S_FALSE)
|
if (result == S_FALSE)
|
||||||
|
{
|
||||||
|
if (decryptionError && _items.IsEmpty())
|
||||||
|
return S_FALSE;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
RINOK(result);
|
RINOK(result);
|
||||||
if (item.IgnoreItem())
|
if (item.IgnoreItem())
|
||||||
continue;
|
continue;
|
||||||
@@ -470,27 +475,25 @@ struct CMethodItem
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
Int32 _aTestMode, IArchiveExtractCallback *_anExtractCallback)
|
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
|
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
|
||||||
bool testMode = (_aTestMode != 0);
|
|
||||||
CMyComPtr<IArchiveExtractCallback> extractCallback = _anExtractCallback;
|
|
||||||
UInt64 censoredTotalUnPacked = 0,
|
UInt64 censoredTotalUnPacked = 0,
|
||||||
// censoredTotalPacked = 0,
|
// censoredTotalPacked = 0,
|
||||||
importantTotalUnPacked = 0;
|
importantTotalUnPacked = 0;
|
||||||
// importantTotalPacked = 0;
|
// importantTotalPacked = 0;
|
||||||
bool allFilesMode = (numItems == UInt32(-1));
|
bool allFilesMode = (numItems == (UInt32)-1);
|
||||||
if (allFilesMode)
|
if (allFilesMode)
|
||||||
numItems = _refItems.Size();
|
numItems = _refItems.Size();
|
||||||
if(numItems == 0)
|
if (numItems == 0)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
int lastIndex = 0;
|
int lastIndex = 0;
|
||||||
CRecordVector<int> importantIndexes;
|
CRecordVector<int> importantIndexes;
|
||||||
CRecordVector<bool> extractStatuses;
|
CRecordVector<bool> extractStatuses;
|
||||||
|
|
||||||
for(UInt32 t = 0; t < numItems; t++)
|
for (UInt32 t = 0; t < numItems; t++)
|
||||||
{
|
{
|
||||||
int index = allFilesMode ? t : indices[t];
|
int index = allFilesMode ? t : indices[t];
|
||||||
const CRefItem &refItem = _refItems[index];
|
const CRefItem &refItem = _refItems[index];
|
||||||
@@ -498,11 +501,11 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
censoredTotalUnPacked += item.Size;
|
censoredTotalUnPacked += item.Size;
|
||||||
// censoredTotalPacked += item.PackSize;
|
// censoredTotalPacked += item.PackSize;
|
||||||
int j;
|
int j;
|
||||||
for(j = lastIndex; j <= index; j++)
|
for (j = lastIndex; j <= index; j++)
|
||||||
// if(!_items[_refItems[j].ItemIndex].IsSolid())
|
// if (!_items[_refItems[j].ItemIndex].IsSolid())
|
||||||
if(!IsSolid(j))
|
if (!IsSolid(j))
|
||||||
lastIndex = j;
|
lastIndex = j;
|
||||||
for(j = lastIndex; j <= index; j++)
|
for (j = lastIndex; j <= index; j++)
|
||||||
{
|
{
|
||||||
const CRefItem &refItem = _refItems[j];
|
const CRefItem &refItem = _refItems[j];
|
||||||
const CItemEx &item = _items[refItem.ItemIndex];
|
const CItemEx &item = _items[refItem.ItemIndex];
|
||||||
@@ -543,7 +546,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
lps->Init(extractCallback, false);
|
lps->Init(extractCallback, false);
|
||||||
|
|
||||||
bool solidStart = true;
|
bool solidStart = true;
|
||||||
for(int i = 0; i < importantIndexes.Size(); i++,
|
for (int i = 0; i < importantIndexes.Size(); i++,
|
||||||
currentImportantTotalUnPacked += currentUnPackSize,
|
currentImportantTotalUnPacked += currentUnPackSize,
|
||||||
currentImportantTotalPacked += currentPackSize)
|
currentImportantTotalPacked += currentPackSize)
|
||||||
{
|
{
|
||||||
@@ -553,12 +556,12 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
|
|
||||||
Int32 askMode;
|
Int32 askMode;
|
||||||
if(extractStatuses[i])
|
if (extractStatuses[i])
|
||||||
askMode = testMode ?
|
askMode = testMode ?
|
||||||
NArchive::NExtract::NAskMode::kTest :
|
NExtract::NAskMode::kTest :
|
||||||
NArchive::NExtract::NAskMode::kExtract;
|
NExtract::NAskMode::kExtract;
|
||||||
else
|
else
|
||||||
askMode = NArchive::NExtract::NAskMode::kSkip;
|
askMode = NExtract::NAskMode::kSkip;
|
||||||
|
|
||||||
UInt32 index = importantIndexes[i];
|
UInt32 index = importantIndexes[i];
|
||||||
|
|
||||||
@@ -569,22 +572,22 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
|
|
||||||
currentPackSize = GetPackSize(index);
|
currentPackSize = GetPackSize(index);
|
||||||
|
|
||||||
if(item.IgnoreItem())
|
if (item.IgnoreItem())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||||
|
|
||||||
if (!IsSolid(index))
|
if (!IsSolid(index))
|
||||||
solidStart = true;
|
solidStart = true;
|
||||||
if(item.IsDir())
|
if (item.IsDir())
|
||||||
{
|
{
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mustBeProcessedAnywhere = false;
|
bool mustBeProcessedAnywhere = false;
|
||||||
if(i < importantIndexes.Size() - 1)
|
if (i < importantIndexes.Size() - 1)
|
||||||
{
|
{
|
||||||
// const CRefItem &nextRefItem = _refItems[importantIndexes[i + 1]];
|
// const CRefItem &nextRefItem = _refItems[importantIndexes[i + 1]];
|
||||||
// const CItemEx &nextItemInfo = _items[nextRefItem.ItemIndex];
|
// const CItemEx &nextItemInfo = _items[nextRefItem.ItemIndex];
|
||||||
@@ -596,7 +599,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!realOutStream && !testMode)
|
if (!realOutStream && !testMode)
|
||||||
askMode = NArchive::NExtract::NAskMode::kSkip;
|
askMode = NExtract::NAskMode::kSkip;
|
||||||
|
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
|
|
||||||
@@ -664,15 +667,14 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
outStream.Release();
|
outStream.Release();
|
||||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
RINOK(filterStreamSpec->Filter.QueryInterface(IID_ICryptoSetPassword,
|
RINOK(filterStreamSpec->Filter.QueryInterface(IID_ICryptoSetPassword,
|
||||||
&cryptoSetPassword));
|
&cryptoSetPassword));
|
||||||
|
|
||||||
if (!getTextPassword)
|
if (!getTextPassword)
|
||||||
extractCallback.QueryInterface(IID_ICryptoGetTextPassword,
|
extractCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getTextPassword);
|
||||||
&getTextPassword);
|
|
||||||
if (getTextPassword)
|
if (getTextPassword)
|
||||||
{
|
{
|
||||||
CMyComBSTR password;
|
CMyComBSTR password;
|
||||||
@@ -729,7 +731,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
if (item.UnPackVersion >= 29)
|
if (item.UnPackVersion >= 29)
|
||||||
{
|
{
|
||||||
outStream.Release();
|
outStream.Release();
|
||||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
@@ -758,7 +760,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
if (mi.Coder == 0)
|
if (mi.Coder == 0)
|
||||||
{
|
{
|
||||||
outStream.Release();
|
outStream.Release();
|
||||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -785,7 +787,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
outStream.Release();
|
outStream.Release();
|
||||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
HRESULT result = commonCoder->Code(inStream, outStream, &packSize, &item.Size, progress);
|
HRESULT result = commonCoder->Code(inStream, outStream, &packSize, &item.Size, progress);
|
||||||
@@ -794,7 +796,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
if (result == S_FALSE)
|
if (result == S_FALSE)
|
||||||
{
|
{
|
||||||
outStream.Release();
|
outStream.Release();
|
||||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError));
|
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kDataError));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (result != S_OK)
|
if (result != S_OK)
|
||||||
@@ -808,8 +810,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
const CItemEx &lastItem = _items[refItem.ItemIndex + refItem.NumItems - 1];
|
const CItemEx &lastItem = _items[refItem.ItemIndex + refItem.NumItems - 1];
|
||||||
bool crcOK = outStreamSpec->GetCRC() == lastItem.FileCRC;
|
bool crcOK = outStreamSpec->GetCRC() == lastItem.FileCRC;
|
||||||
outStream.Release();
|
outStream.Release();
|
||||||
RINOK(extractCallback->SetOperationResult(crcOK ? NArchive::NExtract::NOperationResult::kOK:
|
RINOK(extractCallback->SetOperationResult(crcOK ?
|
||||||
NArchive::NExtract::NOperationResult::kCRCError));
|
NExtract::NOperationResult::kOK:
|
||||||
|
NExtract::NOperationResult::kCRCError));
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
else
|
else
|
||||||
@@ -824,8 +827,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RINOK(extractCallback->SetOperationResult(crcOK ? NArchive::NExtract::NOperationResult::kOK:
|
RINOK(extractCallback->SetOperationResult(crcOK ?
|
||||||
NArchive::NExtract::NOperationResult::kCRCError));
|
NExtract::NOperationResult::kOK:
|
||||||
|
NExtract::NOperationResult::kCRCError));
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -372,8 +372,9 @@ void CInArchive::AddToSeekValue(UInt64 addValue)
|
|||||||
m_Position += addValue;
|
m_Position += addValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPassword)
|
HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPassword, bool &decryptionError)
|
||||||
{
|
{
|
||||||
|
decryptionError = false;
|
||||||
if (m_SeekOnArchiveComment)
|
if (m_SeekOnArchiveComment)
|
||||||
SkipArchiveComment();
|
SkipArchiveComment();
|
||||||
for (;;)
|
for (;;)
|
||||||
@@ -469,8 +470,11 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa
|
|||||||
AddToSeekValue(item.PackSize); // m_Position points to next header;
|
AddToSeekValue(item.PackSize); // m_Position points to next header;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
if (m_CryptoMode && m_BlockHeader.HeadSize > (1 << 12))
|
if (m_CryptoMode && m_BlockHeader.HeadSize > (1 << 10))
|
||||||
return E_FAIL; // it's for bad passwords
|
{
|
||||||
|
decryptionError = true;
|
||||||
|
return S_FALSE;
|
||||||
|
}
|
||||||
if ((m_BlockHeader.Flags & NHeader::NBlock::kLongBlock) != 0)
|
if ((m_BlockHeader.Flags & NHeader::NBlock::kLongBlock) != 0)
|
||||||
{
|
{
|
||||||
m_FileHeaderData.EnsureCapacity(7 + 4);
|
m_FileHeaderData.EnsureCapacity(7 + 4);
|
||||||
@@ -480,7 +484,10 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa
|
|||||||
UInt32 dataSize = ReadUInt32();
|
UInt32 dataSize = ReadUInt32();
|
||||||
AddToSeekValue(dataSize);
|
AddToSeekValue(dataSize);
|
||||||
if (m_CryptoMode && dataSize > (1 << 27))
|
if (m_CryptoMode && dataSize > (1 << 27))
|
||||||
return E_FAIL; // it's for bad passwords
|
{
|
||||||
|
decryptionError = true;
|
||||||
|
return S_FALSE;
|
||||||
|
}
|
||||||
m_CryptoPos = m_BlockHeader.HeadSize;
|
m_CryptoPos = m_BlockHeader.HeadSize;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ protected:
|
|||||||
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);
|
HRESULT GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPassword, bool &decryptionError);
|
||||||
|
|
||||||
void SkipArchiveComment();
|
void SkipArchiveComment();
|
||||||
|
|
||||||
|
|||||||
@@ -243,30 +243,25 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIAN
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
if (numItems == UInt32(-1))
|
|
||||||
numItems = 1;
|
|
||||||
if (numItems == 0)
|
if (numItems == 0)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
if (numItems != 1 || indices[0] != 0)
|
if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0))
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
|
||||||
bool testMode = (_aTestMode != 0);
|
|
||||||
|
|
||||||
RINOK(extractCallback->SetTotal(_size));
|
RINOK(extractCallback->SetTotal(_size));
|
||||||
CMyComPtr<ISequentialOutStream> outStream;
|
CMyComPtr<ISequentialOutStream> outStream;
|
||||||
Int32 askMode = testMode ?
|
Int32 askMode = testMode ?
|
||||||
NArchive::NExtract::NAskMode::kTest :
|
NExtract::NAskMode::kTest :
|
||||||
NArchive::NExtract::NAskMode::kExtract;
|
NExtract::NAskMode::kExtract;
|
||||||
RINOK(extractCallback->GetStream(0, &outStream, askMode));
|
RINOK(extractCallback->GetStream(0, &outStream, askMode));
|
||||||
if (!testMode && !outStream)
|
if (!testMode && !outStream)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
|
|
||||||
|
|
||||||
CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
|
CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
|
||||||
|
|
||||||
CLocalProgress *lps = new CLocalProgress;
|
CLocalProgress *lps = new CLocalProgress;
|
||||||
@@ -276,7 +271,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
RINOK(_stream->Seek(_pos, STREAM_SEEK_SET, NULL));
|
RINOK(_stream->Seek(_pos, STREAM_SEEK_SET, NULL));
|
||||||
RINOK(copyCoder->Code(_stream, outStream, NULL, NULL, progress));
|
RINOK(copyCoder->Code(_stream, outStream, NULL, NULL, progress));
|
||||||
outStream.Release();
|
outStream.Release();
|
||||||
return extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK);
|
return extractCallback->SetOperationResult(NExtract::NOperationResult::kOK);
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -294,24 +294,21 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIAN
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
if (numItems == UInt32(-1))
|
|
||||||
numItems = 1;
|
|
||||||
if (numItems == 0)
|
if (numItems == 0)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
if (numItems != 1 || indices[0] != 0)
|
if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0))
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
|
||||||
bool testMode = (_aTestMode != 0);
|
|
||||||
UInt64 currentTotalSize = 0;
|
UInt64 currentTotalSize = 0;
|
||||||
RINOK(extractCallback->SetTotal(_totalSize));
|
RINOK(extractCallback->SetTotal(_totalSize));
|
||||||
CMyComPtr<ISequentialOutStream> outStream;
|
CMyComPtr<ISequentialOutStream> outStream;
|
||||||
Int32 askMode = testMode ?
|
Int32 askMode = testMode ?
|
||||||
NArchive::NExtract::NAskMode::kTest :
|
NExtract::NAskMode::kTest :
|
||||||
NArchive::NExtract::NAskMode::kExtract;
|
NExtract::NAskMode::kExtract;
|
||||||
RINOK(extractCallback->GetStream(0, &outStream, askMode));
|
RINOK(extractCallback->GetStream(0, &outStream, askMode));
|
||||||
if (!testMode && !outStream)
|
if (!testMode && !outStream)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
@@ -334,7 +331,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
currentTotalSize += copyCoderSpec->TotalSize;
|
currentTotalSize += copyCoderSpec->TotalSize;
|
||||||
}
|
}
|
||||||
outStream.Release();
|
outStream.Release();
|
||||||
return extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK);
|
return extractCallback->SetOperationResult(NExtract::NOperationResult::kOK);
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
706
CPP/7zip/Archive/SwfHandler.cpp
Executable file
706
CPP/7zip/Archive/SwfHandler.cpp
Executable file
@@ -0,0 +1,706 @@
|
|||||||
|
// SwfHandler.cpp
|
||||||
|
|
||||||
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
#include "../../../C/CpuArch.h"
|
||||||
|
|
||||||
|
#include "Common/Buffer.h"
|
||||||
|
#include "Common/ComTry.h"
|
||||||
|
#include "Common/IntToString.h"
|
||||||
|
#include "Common/MyString.h"
|
||||||
|
|
||||||
|
#include "Windows/PropVariant.h"
|
||||||
|
|
||||||
|
#include "../Common/InBuffer.h"
|
||||||
|
#include "../Common/ProgressUtils.h"
|
||||||
|
#include "../Common/RegisterArc.h"
|
||||||
|
#include "../Common/StreamUtils.h"
|
||||||
|
|
||||||
|
#include "../Compress/CopyCoder.h"
|
||||||
|
#include "../Compress/ZlibDecoder.h"
|
||||||
|
#include "../Compress/ZlibEncoder.h"
|
||||||
|
|
||||||
|
#include "Common/DummyOutStream.h"
|
||||||
|
|
||||||
|
#include "DeflateProps.h"
|
||||||
|
|
||||||
|
using namespace NWindows;
|
||||||
|
|
||||||
|
namespace NArchive {
|
||||||
|
namespace NSwfc {
|
||||||
|
|
||||||
|
static const UInt32 kHeaderSize = 8;
|
||||||
|
|
||||||
|
static const Byte SWF_UNCOMPRESSED = 'F';
|
||||||
|
static const Byte SWF_COMPRESSED = 'C';
|
||||||
|
static const Byte SWF_MIN_COMPRESSED_VER = 6;
|
||||||
|
|
||||||
|
struct CItem
|
||||||
|
{
|
||||||
|
Byte Buf[kHeaderSize];
|
||||||
|
|
||||||
|
UInt32 GetSize() const { return GetUi32(Buf + 4); }
|
||||||
|
bool IsSwf(Byte c) const { return (Buf[0] == c && Buf[1] == 'W' && Buf[2] == 'S' && Buf[3] < 32); }
|
||||||
|
bool IsUncompressed() const { return IsSwf(SWF_UNCOMPRESSED); }
|
||||||
|
bool IsCompressed() const { return IsSwf(SWF_COMPRESSED); }
|
||||||
|
|
||||||
|
void MakeUncompressed() { Buf[0] = SWF_UNCOMPRESSED; }
|
||||||
|
void MakeCompressed()
|
||||||
|
{
|
||||||
|
Buf[0] = SWF_COMPRESSED;
|
||||||
|
if (Buf[3] < SWF_MIN_COMPRESSED_VER)
|
||||||
|
Buf[3] = SWF_MIN_COMPRESSED_VER;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT ReadHeader(ISequentialInStream *stream) { return ReadStream_FALSE(stream, Buf, kHeaderSize); }
|
||||||
|
HRESULT WriteHeader(ISequentialOutStream *stream) { return WriteStream(stream, Buf, kHeaderSize); }
|
||||||
|
};
|
||||||
|
|
||||||
|
class CHandler:
|
||||||
|
public IInArchive,
|
||||||
|
public IArchiveOpenSeq,
|
||||||
|
public IOutArchive,
|
||||||
|
public ISetProperties,
|
||||||
|
public CMyUnknownImp
|
||||||
|
{
|
||||||
|
CItem _item;
|
||||||
|
UInt64 _packSize;
|
||||||
|
bool _packSizeDefined;
|
||||||
|
CMyComPtr<ISequentialInStream> _seqStream;
|
||||||
|
CMyComPtr<IInStream> _stream;
|
||||||
|
|
||||||
|
CDeflateProps _method;
|
||||||
|
|
||||||
|
public:
|
||||||
|
MY_UNKNOWN_IMP4(IInArchive, IArchiveOpenSeq, IOutArchive, ISetProperties)
|
||||||
|
INTERFACE_IInArchive(;)
|
||||||
|
INTERFACE_IOutArchive(;)
|
||||||
|
STDMETHOD(OpenSeq)(ISequentialInStream *stream);
|
||||||
|
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProps);
|
||||||
|
};
|
||||||
|
|
||||||
|
STATPROPSTG kProps[] =
|
||||||
|
{
|
||||||
|
{ NULL, kpidSize, VT_UI8},
|
||||||
|
{ NULL, kpidPackSize, VT_UI8}
|
||||||
|
};
|
||||||
|
|
||||||
|
IMP_IInArchive_Props
|
||||||
|
IMP_IInArchive_ArcProps_NO_Table
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||||
|
{
|
||||||
|
NCOM::CPropVariant prop;
|
||||||
|
switch(propID)
|
||||||
|
{
|
||||||
|
case kpidPhySize: if (_packSizeDefined) prop = _packSize; break;
|
||||||
|
}
|
||||||
|
prop.Detach(value);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||||
|
{
|
||||||
|
*numItems = 1;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
|
||||||
|
{
|
||||||
|
NWindows::NCOM::CPropVariant prop;
|
||||||
|
switch(propID)
|
||||||
|
{
|
||||||
|
case kpidSize: prop = (UInt64)_item.GetSize(); break;
|
||||||
|
case kpidPackSize: if (_packSizeDefined) prop = _packSize; break;
|
||||||
|
}
|
||||||
|
prop.Detach(value);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *)
|
||||||
|
{
|
||||||
|
RINOK(OpenSeq(stream));
|
||||||
|
_stream = stream;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream)
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
HRESULT res = _item.ReadHeader(stream);
|
||||||
|
if (res == S_OK)
|
||||||
|
if (_item.IsCompressed())
|
||||||
|
_seqStream = stream;
|
||||||
|
else
|
||||||
|
res = S_FALSE;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::Close()
|
||||||
|
{
|
||||||
|
_packSizeDefined = false;
|
||||||
|
_seqStream.Release();
|
||||||
|
_stream.Release();
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
|
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||||
|
{
|
||||||
|
COM_TRY_BEGIN
|
||||||
|
if (numItems == 0)
|
||||||
|
return S_OK;
|
||||||
|
if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0))
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
extractCallback->SetTotal(_item.GetSize());
|
||||||
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
|
Int32 askMode = testMode ?
|
||||||
|
NExtract::NAskMode::kTest :
|
||||||
|
NExtract::NAskMode::kExtract;
|
||||||
|
RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
|
||||||
|
if (!testMode && !realOutStream)
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
|
extractCallback->PrepareOperation(askMode);
|
||||||
|
|
||||||
|
NCompress::NZlib::CDecoder *_decoderSpec = new NCompress::NZlib::CDecoder;
|
||||||
|
CMyComPtr<ICompressCoder> _decoder = _decoderSpec;
|
||||||
|
|
||||||
|
CDummyOutStream *outStreamSpec = new CDummyOutStream;
|
||||||
|
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
|
||||||
|
outStreamSpec->SetStream(realOutStream);
|
||||||
|
outStreamSpec->Init();
|
||||||
|
realOutStream.Release();
|
||||||
|
|
||||||
|
CLocalProgress *lps = new CLocalProgress;
|
||||||
|
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||||
|
lps->Init(extractCallback, false);
|
||||||
|
|
||||||
|
lps->InSize = kHeaderSize;
|
||||||
|
lps->OutSize = outStreamSpec->GetSize();
|
||||||
|
RINOK(lps->SetCur());
|
||||||
|
|
||||||
|
CItem item = _item;
|
||||||
|
item.MakeUncompressed();
|
||||||
|
RINOK(item.WriteHeader(outStream));
|
||||||
|
if (_stream)
|
||||||
|
RINOK(_stream->Seek(kHeaderSize, STREAM_SEEK_SET, NULL));
|
||||||
|
HRESULT result = _decoderSpec->Code(_seqStream, outStream, NULL, NULL, progress);
|
||||||
|
Int32 opRes = NExtract::NOperationResult::kDataError;
|
||||||
|
if (result == S_OK)
|
||||||
|
{
|
||||||
|
if (_item.GetSize() == outStreamSpec->GetSize())
|
||||||
|
{
|
||||||
|
_packSizeDefined = true;
|
||||||
|
_packSize = _decoderSpec->GetInputProcessedSize() + kHeaderSize;
|
||||||
|
opRes = NExtract::NOperationResult::kOK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (result != S_FALSE)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
outStream.Release();
|
||||||
|
return extractCallback->SetOperationResult(opRes);
|
||||||
|
COM_TRY_END
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT UpdateArchive(ISequentialOutStream *outStream,
|
||||||
|
UInt64 size, CDeflateProps &deflateProps,
|
||||||
|
IArchiveUpdateCallback *updateCallback)
|
||||||
|
{
|
||||||
|
UInt64 complexity = 0;
|
||||||
|
RINOK(updateCallback->SetTotal(size));
|
||||||
|
RINOK(updateCallback->SetCompleted(&complexity));
|
||||||
|
|
||||||
|
CMyComPtr<ISequentialInStream> fileInStream;
|
||||||
|
RINOK(updateCallback->GetStream(0, &fileInStream));
|
||||||
|
|
||||||
|
CItem item;
|
||||||
|
HRESULT res = item.ReadHeader(fileInStream);
|
||||||
|
if (res == S_FALSE)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
RINOK(res);
|
||||||
|
if (!item.IsUncompressed() || size != item.GetSize())
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
item.MakeCompressed();
|
||||||
|
item.WriteHeader(outStream);
|
||||||
|
|
||||||
|
CLocalProgress *lps = new CLocalProgress;
|
||||||
|
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||||
|
lps->Init(updateCallback, true);
|
||||||
|
|
||||||
|
NCompress::NZlib::CEncoder *encoderSpec = new NCompress::NZlib::CEncoder;
|
||||||
|
CMyComPtr<ICompressCoder> encoder = encoderSpec;
|
||||||
|
encoderSpec->Create();
|
||||||
|
RINOK(deflateProps.SetCoderProperties(encoderSpec->DeflateEncoderSpec));
|
||||||
|
RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, progress));
|
||||||
|
if (encoderSpec->GetInputProcessedSize() + kHeaderSize != size)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
return updateCallback->SetOperationResult(NUpdate::NOperationResult::kOK);
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType)
|
||||||
|
{
|
||||||
|
*timeType = NFileTimeType::kUnix;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
|
||||||
|
IArchiveUpdateCallback *updateCallback)
|
||||||
|
{
|
||||||
|
if (numItems != 1)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
Int32 newData, newProps;
|
||||||
|
UInt32 indexInArchive;
|
||||||
|
if (!updateCallback)
|
||||||
|
return E_FAIL;
|
||||||
|
RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive));
|
||||||
|
|
||||||
|
if (IntToBool(newProps))
|
||||||
|
{
|
||||||
|
{
|
||||||
|
NCOM::CPropVariant prop;
|
||||||
|
RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop));
|
||||||
|
if (prop.vt == VT_BOOL)
|
||||||
|
{
|
||||||
|
if (prop.boolVal != VARIANT_FALSE)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
else if (prop.vt != VT_EMPTY)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IntToBool(newData))
|
||||||
|
{
|
||||||
|
UInt64 size;
|
||||||
|
{
|
||||||
|
NCOM::CPropVariant prop;
|
||||||
|
RINOK(updateCallback->GetProperty(0, kpidSize, &prop));
|
||||||
|
if (prop.vt != VT_UI8)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
size = prop.uhVal.QuadPart;
|
||||||
|
}
|
||||||
|
return UpdateArchive(outStream, size, _method, updateCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (indexInArchive != 0)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
if (!_seqStream)
|
||||||
|
return E_NOTIMPL;
|
||||||
|
|
||||||
|
if (_stream)
|
||||||
|
{
|
||||||
|
RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_item.WriteHeader(outStream);
|
||||||
|
return NCompress::CopyStream(_seqStream, outStream, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
|
||||||
|
{
|
||||||
|
return _method.SetProperties(names, values, numProps);
|
||||||
|
}
|
||||||
|
|
||||||
|
static IInArchive *CreateArc() { return new CHandler; }
|
||||||
|
#ifndef EXTRACT_ONLY
|
||||||
|
static IOutArchive *CreateArcOut() { return new CHandler; }
|
||||||
|
#else
|
||||||
|
#define CreateArcOut 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static CArcInfo g_ArcInfo =
|
||||||
|
{ L"SWFc", L"swf", L"~.swf", 0xD8, { 'C', 'W', 'S' }, 3, true, CreateArc, CreateArcOut };
|
||||||
|
|
||||||
|
REGISTER_ARC(Swfc)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace NSwf {
|
||||||
|
|
||||||
|
static const UInt32 kFileSizeMax = (UInt32)1 << 30;
|
||||||
|
static const int kNumTagsMax = (UInt32)1 << 23;
|
||||||
|
|
||||||
|
struct CTag
|
||||||
|
{
|
||||||
|
UInt32 Type;
|
||||||
|
CByteBuffer Buf;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CHandler:
|
||||||
|
public IInArchive,
|
||||||
|
public IArchiveOpenSeq,
|
||||||
|
public CMyUnknownImp
|
||||||
|
{
|
||||||
|
CObjectVector<CTag> _tags;
|
||||||
|
NSwfc::CItem _item;
|
||||||
|
UInt64 _packSize;
|
||||||
|
|
||||||
|
HRESULT OpenSeq3(ISequentialInStream *stream, IArchiveOpenCallback *callback);
|
||||||
|
HRESULT OpenSeq2(ISequentialInStream *stream, IArchiveOpenCallback *callback);
|
||||||
|
public:
|
||||||
|
MY_UNKNOWN_IMP2(IInArchive, IArchiveOpenSeq)
|
||||||
|
INTERFACE_IInArchive(;)
|
||||||
|
|
||||||
|
STDMETHOD(OpenSeq)(ISequentialInStream *stream);
|
||||||
|
};
|
||||||
|
|
||||||
|
STATPROPSTG kProps[] =
|
||||||
|
{
|
||||||
|
{ NULL, kpidPath, VT_BSTR},
|
||||||
|
{ NULL, kpidSize, VT_UI8},
|
||||||
|
{ NULL, kpidComment, VT_BSTR}
|
||||||
|
};
|
||||||
|
|
||||||
|
IMP_IInArchive_Props
|
||||||
|
IMP_IInArchive_ArcProps_NO_Table
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||||
|
{
|
||||||
|
NCOM::CPropVariant prop;
|
||||||
|
switch(propID)
|
||||||
|
{
|
||||||
|
case kpidPhySize: prop = _packSize; break;
|
||||||
|
}
|
||||||
|
prop.Detach(value);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||||
|
{
|
||||||
|
*numItems = _tags.Size();
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *g_TagDesc[92] =
|
||||||
|
{
|
||||||
|
"End",
|
||||||
|
"ShowFrame",
|
||||||
|
"DefineShape",
|
||||||
|
NULL,
|
||||||
|
"PlaceObject",
|
||||||
|
"RemoveObject",
|
||||||
|
"DefineBits",
|
||||||
|
"DefineButton",
|
||||||
|
"JPEGTables",
|
||||||
|
"SetBackgroundColor",
|
||||||
|
"DefineFont",
|
||||||
|
"DefineText",
|
||||||
|
"DoAction",
|
||||||
|
"DefineFontInfo",
|
||||||
|
"DefineSound",
|
||||||
|
"StartSound",
|
||||||
|
NULL,
|
||||||
|
"DefineButtonSound",
|
||||||
|
"SoundStreamHead",
|
||||||
|
"SoundStreamBlock",
|
||||||
|
"DefineBitsLossless",
|
||||||
|
"DefineBitsJPEG2",
|
||||||
|
"DefineShape2",
|
||||||
|
"DefineButtonCxform",
|
||||||
|
"Protect",
|
||||||
|
NULL,
|
||||||
|
"PlaceObject2",
|
||||||
|
NULL,
|
||||||
|
"RemoveObject2",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
"DefineShape3",
|
||||||
|
"DefineText2",
|
||||||
|
"DefineButton2",
|
||||||
|
"DefineBitsJPEG3",
|
||||||
|
"DefineBitsLossless2",
|
||||||
|
"DefineEditText",
|
||||||
|
NULL,
|
||||||
|
"DefineSprite",
|
||||||
|
NULL,
|
||||||
|
"41",
|
||||||
|
NULL,
|
||||||
|
"FrameLabel",
|
||||||
|
NULL,
|
||||||
|
"SoundStreamHead2",
|
||||||
|
"DefineMorphShape",
|
||||||
|
NULL,
|
||||||
|
"DefineFont2",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
"ExportAssets",
|
||||||
|
"ImportAssets",
|
||||||
|
"EnableDebugger",
|
||||||
|
"DoInitAction",
|
||||||
|
"DefineVideoStream",
|
||||||
|
"VideoFrame",
|
||||||
|
"DefineFontInfo2",
|
||||||
|
NULL,
|
||||||
|
"EnableDebugger2",
|
||||||
|
"ScriptLimits",
|
||||||
|
"SetTabIndex",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
"FileAttributes",
|
||||||
|
"PlaceObject3",
|
||||||
|
"ImportAssets2",
|
||||||
|
NULL,
|
||||||
|
"DefineFontAlignZones",
|
||||||
|
"CSMTextSettings",
|
||||||
|
"DefineFont3",
|
||||||
|
"SymbolClass",
|
||||||
|
"Metadata",
|
||||||
|
"DefineScalingGrid",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
"DoABC",
|
||||||
|
"DefineShape4",
|
||||||
|
"DefineMorphShape2",
|
||||||
|
NULL,
|
||||||
|
"DefineSceneAndFrameLabelData",
|
||||||
|
"DefineBinaryData",
|
||||||
|
"DefineFontName",
|
||||||
|
"StartSound2",
|
||||||
|
"DefineBitsJPEG4",
|
||||||
|
"DefineFont4"
|
||||||
|
};
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||||
|
{
|
||||||
|
NWindows::NCOM::CPropVariant prop;
|
||||||
|
const CTag &tag = _tags[index];
|
||||||
|
switch(propID)
|
||||||
|
{
|
||||||
|
case kpidPath:
|
||||||
|
{
|
||||||
|
char s[32];
|
||||||
|
ConvertUInt32ToString(index, s);
|
||||||
|
size_t i = strlen(s);
|
||||||
|
s[i++] = '.';
|
||||||
|
ConvertUInt32ToString(tag.Type, s + i);
|
||||||
|
prop = s;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case kpidSize:
|
||||||
|
case kpidPackSize:
|
||||||
|
prop = (UInt64)tag.Buf.GetCapacity(); break;
|
||||||
|
case kpidComment:
|
||||||
|
if (tag.Type < sizeof(g_TagDesc) / sizeof(g_TagDesc[0]))
|
||||||
|
{
|
||||||
|
const char *s = g_TagDesc[tag.Type];
|
||||||
|
if (s != NULL)
|
||||||
|
prop = s;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prop.Detach(value);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback)
|
||||||
|
{
|
||||||
|
return OpenSeq2(stream, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
static UInt16 Read16(CInBuffer &stream)
|
||||||
|
{
|
||||||
|
UInt16 res = 0;
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
Byte b;
|
||||||
|
if (!stream.ReadByte(b))
|
||||||
|
throw 1;
|
||||||
|
res |= (UInt16)b << (i * 8);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UInt32 Read32(CInBuffer &stream)
|
||||||
|
{
|
||||||
|
UInt32 res = 0;
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
Byte b;
|
||||||
|
if (!stream.ReadByte(b))
|
||||||
|
throw 1;
|
||||||
|
res |= (UInt32)b << (i * 8);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CBitReader
|
||||||
|
{
|
||||||
|
CInBuffer *stream;
|
||||||
|
unsigned NumBits;
|
||||||
|
Byte Val;
|
||||||
|
|
||||||
|
CBitReader(): NumBits(0), Val(0) {}
|
||||||
|
|
||||||
|
UInt32 ReadBits(unsigned numBits);
|
||||||
|
};
|
||||||
|
|
||||||
|
UInt32 CBitReader::ReadBits(unsigned numBits)
|
||||||
|
{
|
||||||
|
UInt32 res = 0;
|
||||||
|
while (numBits > 0)
|
||||||
|
{
|
||||||
|
if (NumBits == 0)
|
||||||
|
{
|
||||||
|
Val = stream->ReadByte();
|
||||||
|
NumBits = 8;
|
||||||
|
}
|
||||||
|
if (numBits <= NumBits)
|
||||||
|
{
|
||||||
|
res <<= numBits;
|
||||||
|
NumBits -= numBits;
|
||||||
|
res |= (Val >> NumBits);
|
||||||
|
Val &= (1 << NumBits) - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
res <<= NumBits;
|
||||||
|
res |= Val;
|
||||||
|
numBits -= NumBits;
|
||||||
|
NumBits = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CHandler::OpenSeq3(ISequentialInStream *stream, IArchiveOpenCallback *callback)
|
||||||
|
{
|
||||||
|
RINOK(_item.ReadHeader(stream))
|
||||||
|
if (!_item.IsUncompressed())
|
||||||
|
return S_FALSE;
|
||||||
|
|
||||||
|
CInBuffer s;
|
||||||
|
if (!s.Create(1 << 20))
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
s.SetStream(stream);
|
||||||
|
s.Init();
|
||||||
|
{
|
||||||
|
CBitReader br;
|
||||||
|
br.stream = &s;
|
||||||
|
unsigned numBits = br.ReadBits(5);
|
||||||
|
/* UInt32 xMin = */ br.ReadBits(numBits);
|
||||||
|
/* UInt32 xMax = */ br.ReadBits(numBits);
|
||||||
|
/* UInt32 yMin = */ br.ReadBits(numBits);
|
||||||
|
/* UInt32 yMax = */ br.ReadBits(numBits);
|
||||||
|
}
|
||||||
|
/* UInt32 frameDelay = */ Read16(s);
|
||||||
|
/* UInt32 numFrames = */ Read16(s);
|
||||||
|
|
||||||
|
_tags.Clear();
|
||||||
|
UInt64 offsetPrev = 0;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
UInt32 pair = Read16(s);
|
||||||
|
UInt32 type = pair >> 6;
|
||||||
|
UInt32 length = pair & 0x3F;
|
||||||
|
if (length == 0x3F)
|
||||||
|
length = Read32(s);
|
||||||
|
if (type == 0)
|
||||||
|
break;
|
||||||
|
UInt64 offset = s.GetProcessedSize() + NSwfc::kHeaderSize + length;
|
||||||
|
if (offset > kFileSizeMax || _tags.Size() >= kNumTagsMax)
|
||||||
|
return S_FALSE;
|
||||||
|
_tags.Add(CTag());
|
||||||
|
CTag &tag = _tags.Back();
|
||||||
|
tag.Type = type;
|
||||||
|
tag.Buf.SetCapacity(length);
|
||||||
|
if (s.ReadBytes(tag.Buf, length) != length)
|
||||||
|
return S_FALSE;
|
||||||
|
if (callback && offset >= offsetPrev + (1 << 20))
|
||||||
|
{
|
||||||
|
UInt64 numItems = _tags.Size();
|
||||||
|
RINOK(callback->SetCompleted(&numItems, &offset));
|
||||||
|
offsetPrev = offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_packSize = s.GetProcessedSize() + NSwfc::kHeaderSize;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CHandler::OpenSeq2(ISequentialInStream *stream, IArchiveOpenCallback *callback)
|
||||||
|
{
|
||||||
|
HRESULT res;
|
||||||
|
try { res = OpenSeq3(stream, callback); }
|
||||||
|
catch(...) { res = S_FALSE; }
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream)
|
||||||
|
{
|
||||||
|
return OpenSeq2(stream, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::Close()
|
||||||
|
{
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
|
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||||
|
{
|
||||||
|
COM_TRY_BEGIN
|
||||||
|
bool allFilesMode = (numItems == (UInt32)-1);
|
||||||
|
if (allFilesMode)
|
||||||
|
numItems = _tags.Size();
|
||||||
|
if (numItems == 0)
|
||||||
|
return S_OK;
|
||||||
|
UInt64 totalSize = 0;
|
||||||
|
UInt32 i;
|
||||||
|
for (i = 0; i < numItems; i++)
|
||||||
|
totalSize += _tags[allFilesMode ? i : indices[i]].Buf.GetCapacity();
|
||||||
|
extractCallback->SetTotal(totalSize);
|
||||||
|
|
||||||
|
CLocalProgress *lps = new CLocalProgress;
|
||||||
|
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||||
|
lps->Init(extractCallback, false);
|
||||||
|
|
||||||
|
totalSize = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < numItems; i++)
|
||||||
|
{
|
||||||
|
lps->InSize = lps->OutSize = totalSize;
|
||||||
|
RINOK(lps->SetCur());
|
||||||
|
Int32 askMode = testMode ?
|
||||||
|
NExtract::NAskMode::kTest :
|
||||||
|
NExtract::NAskMode::kExtract;
|
||||||
|
UInt32 index = allFilesMode ? i : indices[i];
|
||||||
|
const CByteBuffer &buf = _tags[index].Buf;
|
||||||
|
totalSize += buf.GetCapacity();
|
||||||
|
|
||||||
|
CMyComPtr<ISequentialOutStream> outStream;
|
||||||
|
RINOK(extractCallback->GetStream(index, &outStream, askMode));
|
||||||
|
if (!testMode && !outStream)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
|
if (outStream)
|
||||||
|
RINOK(WriteStream(outStream, buf, buf.GetCapacity()));
|
||||||
|
outStream.Release();
|
||||||
|
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
COM_TRY_END
|
||||||
|
}
|
||||||
|
|
||||||
|
static IInArchive *CreateArc() { return new CHandler; }
|
||||||
|
|
||||||
|
static CArcInfo g_ArcInfo =
|
||||||
|
{ L"SWF", L"swf", 0, 0xD7, { 'F', 'W', 'S' }, 3, true, CreateArc, 0 };
|
||||||
|
|
||||||
|
REGISTER_ARC(Swf)
|
||||||
|
|
||||||
|
}}
|
||||||
@@ -227,8 +227,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
|||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
ISequentialInStream *stream = _seqStream;
|
ISequentialInStream *stream = _seqStream;
|
||||||
@@ -236,7 +236,6 @@ HRESULT CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
if (!seqMode)
|
if (!seqMode)
|
||||||
stream = _stream;
|
stream = _stream;
|
||||||
|
|
||||||
bool testMode = (_aTestMode != 0);
|
|
||||||
bool allFilesMode = (numItems == (UInt32)-1);
|
bool allFilesMode = (numItems == (UInt32)-1);
|
||||||
if (allFilesMode)
|
if (allFilesMode)
|
||||||
numItems = _items.Size();
|
numItems = _items.Size();
|
||||||
@@ -269,8 +268,8 @@ HRESULT CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
RINOK(lps->SetCur());
|
RINOK(lps->SetCur());
|
||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
Int32 askMode = testMode ?
|
Int32 askMode = testMode ?
|
||||||
NArchive::NExtract::NAskMode::kTest :
|
NExtract::NAskMode::kTest :
|
||||||
NArchive::NExtract::NAskMode::kExtract;
|
NExtract::NAskMode::kExtract;
|
||||||
Int32 index = allFilesMode ? i : indices[i];
|
Int32 index = allFilesMode ? i : indices[i];
|
||||||
const CItemEx *item;
|
const CItemEx *item;
|
||||||
if (seqMode)
|
if (seqMode)
|
||||||
@@ -290,7 +289,7 @@ HRESULT CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
if (item->IsDir())
|
if (item->IsDir())
|
||||||
{
|
{
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
bool skipMode = false;
|
bool skipMode = false;
|
||||||
@@ -299,7 +298,7 @@ HRESULT CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
if (!seqMode)
|
if (!seqMode)
|
||||||
continue;
|
continue;
|
||||||
skipMode = true;
|
skipMode = true;
|
||||||
askMode = NArchive::NExtract::NAskMode::kSkip;
|
askMode = NExtract::NAskMode::kSkip;
|
||||||
}
|
}
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
|
|
||||||
@@ -320,8 +319,8 @@ HRESULT CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
}
|
}
|
||||||
outStreamSpec->ReleaseStream();
|
outStreamSpec->ReleaseStream();
|
||||||
RINOK(extractCallback->SetOperationResult(outStreamSpec->GetRem() == 0 ?
|
RINOK(extractCallback->SetOperationResult(outStreamSpec->GetRem() == 0 ?
|
||||||
NArchive::NExtract::NOperationResult::kOK:
|
NExtract::NOperationResult::kOK:
|
||||||
NArchive::NExtract::NOperationResult::kDataError));
|
NExtract::NOperationResult::kDataError));
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
|
|||||||
@@ -13,6 +13,6 @@ static IOutArchive *CreateArcOut() { return new NArchive::NTar::CHandler; }
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static CArcInfo g_ArcInfo =
|
static CArcInfo g_ArcInfo =
|
||||||
{ L"Tar", L"tar", 0, 0xEE, { 'u', 's', 't', 'a', 'r' }, 5, false, CreateArc, CreateArcOut };
|
{ L"tar", L"tar", 0, 0xEE, { 'u', 's', 't', 'a', 'r' }, 5, false, CreateArc, CreateArcOut };
|
||||||
|
|
||||||
REGISTER_ARC(Tar)
|
REGISTER_ARC(Tar)
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user