mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-06 07:14:55 -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
|
||||
2009-05-03 : Igor Pavlov : Public domain */
|
||||
/* 7zDec.c -- Decoding from 7z folder
|
||||
2009-08-16 : Igor Pavlov : Public domain */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "../../Bcj2.h"
|
||||
#include "../../Bra.h"
|
||||
#include "../../LzmaDec.h"
|
||||
#include "../../Lzma2Dec.h"
|
||||
#include "7z.h"
|
||||
|
||||
#include "7zDecode.h"
|
||||
#include "Bcj2.h"
|
||||
#include "Bra.h"
|
||||
#include "LzmaDec.h"
|
||||
#include "Lzma2Dec.h"
|
||||
|
||||
#define k_Copy 0
|
||||
#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_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)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
@@ -179,7 +179,7 @@ SRes CheckSupportedFolder(const CSzFolder *f)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
UInt64 GetSum(const UInt64 *values, UInt32 index)
|
||||
static UInt64 GetSum(const UInt64 *values, UInt32 index)
|
||||
{
|
||||
UInt64 sum = 0;
|
||||
UInt32 i;
|
||||
@@ -188,7 +188,7 @@ UInt64 GetSum(const UInt64 *values, UInt32 index)
|
||||
return sum;
|
||||
}
|
||||
|
||||
SRes SzDecode2(const UInt64 *packSizes, const CSzFolder *folder,
|
||||
static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
|
||||
ILookInStream *inStream, UInt64 startPos,
|
||||
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain,
|
||||
Byte *tempBuf[])
|
||||
@@ -296,13 +296,13 @@ SRes SzDecode2(const UInt64 *packSizes, const CSzFolder *folder,
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
SRes SzDecode(const UInt64 *packSizes, const CSzFolder *folder,
|
||||
SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes,
|
||||
ILookInStream *inStream, UInt64 startPos,
|
||||
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
|
||||
{
|
||||
Byte *tempBuf[3] = { 0, 0, 0};
|
||||
int i;
|
||||
SRes res = SzDecode2(packSizes, folder, inStream, startPos,
|
||||
SRes res = SzFolder_Decode2(folder, packSizes, inStream, startPos,
|
||||
outBuffer, (SizeT)outSize, allocMain, tempBuf);
|
||||
for (i = 0; i < 3; i++)
|
||||
IAlloc_Free(allocMain, tempBuf[i]);
|
||||
16
C/7zFile.c
16
C/7zFile.c
@@ -1,5 +1,5 @@
|
||||
/* 7zFile.c -- File IO
|
||||
2008-11-22 : Igor Pavlov : Public domain */
|
||||
2009-08-16 : Igor Pavlov : Public domain */
|
||||
|
||||
#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 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)
|
||||
{
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
|
||||
15
C/7zFile.h
15
C/7zFile.h
@@ -1,5 +1,5 @@
|
||||
/* 7zFile.h -- File IO
|
||||
2009-02-07 : Igor Pavlov : Public domain */
|
||||
2009-08-16 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __7Z_FILE_H
|
||||
#define __7Z_FILE_H
|
||||
@@ -16,10 +16,7 @@
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
/* ---------- File ---------- */
|
||||
|
||||
@@ -35,6 +32,10 @@ typedef struct
|
||||
void File_Construct(CSzFile *p);
|
||||
WRes InFile_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);
|
||||
|
||||
/* reads max(*size, remain file's size) bytes */
|
||||
@@ -75,8 +76,6 @@ typedef struct
|
||||
|
||||
void FileOutStream_CreateVTable(CFileOutStream *p);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,17 +1,134 @@
|
||||
/* 7zIn.c -- 7z Input functions
|
||||
2008-12-31 : Igor Pavlov : Public domain */
|
||||
2009-08-17 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "../../7zCrc.h"
|
||||
#include "../../CpuArch.h"
|
||||
#include <string.h>
|
||||
|
||||
#include "7zDecode.h"
|
||||
#include "7zIn.h"
|
||||
#include "7z.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 NUM_FOLDER_CODERS_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)
|
||||
{
|
||||
SzAr_Init(&p->db);
|
||||
@@ -19,6 +136,8 @@ void SzArEx_Init(CSzArEx *p)
|
||||
p->PackStreamStartPositions = 0;
|
||||
p->FolderStartFileIndex = 0;
|
||||
p->FileIndexToFolderIndexMap = 0;
|
||||
p->FileNameOffsets = 0;
|
||||
Buf_Init(&p->FileNames);
|
||||
}
|
||||
|
||||
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->FolderStartFileIndex);
|
||||
IAlloc_Free(alloc, p->FileIndexToFolderIndexMap);
|
||||
|
||||
IAlloc_Free(alloc, p->FileNameOffsets);
|
||||
Buf_Free(&p->FileNames, alloc);
|
||||
|
||||
SzAr_Free(&p->db, alloc);
|
||||
SzArEx_Init(p);
|
||||
}
|
||||
@@ -488,11 +611,11 @@ static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
|
||||
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++)
|
||||
{
|
||||
CBindPair *bp = folder->BindPairs + i;
|
||||
CSzBindPair *bp = folder->BindPairs + i;
|
||||
RINOK(SzReadNumber32(sd, &bp->InIndex));
|
||||
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;
|
||||
size_t pos = 0;
|
||||
for (i = 0; i < numFiles; i++)
|
||||
{
|
||||
UInt32 len = 0;
|
||||
UInt32 pos = 0;
|
||||
CSzFileItem *file = files + i;
|
||||
while (pos + 2 <= sd->Size)
|
||||
sizes[i] = pos;
|
||||
for (;;)
|
||||
{
|
||||
int numAdds;
|
||||
UInt32 value = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8));
|
||||
pos += 2;
|
||||
len++;
|
||||
if (value == 0)
|
||||
if (pos >= size)
|
||||
return SZ_ERROR_ARCHIVE;
|
||||
if (p[pos * 2] == 0 && p[pos * 2 + 1] == 0)
|
||||
break;
|
||||
if (value < 0x80)
|
||||
continue;
|
||||
if (value >= 0xD800 && value < 0xE000)
|
||||
{
|
||||
UInt32 c2;
|
||||
if (value >= 0xDC00)
|
||||
return SZ_ERROR_ARCHIVE;
|
||||
if (pos + 2 > sd->Size)
|
||||
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;
|
||||
len += numAdds;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
pos++;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
return SZ_OK;
|
||||
sizes[i] = pos;
|
||||
return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE;
|
||||
}
|
||||
|
||||
static SRes SzReadHeader2(
|
||||
@@ -920,7 +1000,8 @@ static SRes SzReadHeader2(
|
||||
if (type == k7zIdEnd)
|
||||
break;
|
||||
RINOK(SzReadNumber(sd, &size));
|
||||
|
||||
if (size > sd->Size)
|
||||
return SZ_ERROR_ARCHIVE;
|
||||
if ((UInt64)(int)type != type)
|
||||
{
|
||||
RINOK(SzSkeepDataSize(sd, size));
|
||||
@@ -930,8 +1011,16 @@ static SRes SzReadHeader2(
|
||||
{
|
||||
case k7zIdName:
|
||||
{
|
||||
size_t namesSize;
|
||||
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;
|
||||
}
|
||||
case k7zIdEmptyStream:
|
||||
@@ -988,8 +1077,8 @@ static SRes SzReadHeader2(
|
||||
{
|
||||
file->IsDir = 0;
|
||||
file->Size = (*unpackSizes)[sizeIndex];
|
||||
file->FileCRC = (*digests)[sizeIndex];
|
||||
file->FileCRCDefined = (Byte)(*digestsDefined)[sizeIndex];
|
||||
file->Crc = (*digests)[sizeIndex];
|
||||
file->CrcDefined = (Byte)(*digestsDefined)[sizeIndex];
|
||||
sizeIndex++;
|
||||
}
|
||||
else
|
||||
@@ -1000,7 +1089,8 @@ static SRes SzReadHeader2(
|
||||
file->IsDir = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1);
|
||||
emptyFileIndex++;
|
||||
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))
|
||||
return SZ_ERROR_MEM;
|
||||
|
||||
res = SzDecode(p->PackSizes, folder,
|
||||
res = SzFolder_Decode(folder, p->PackSizes,
|
||||
inStream, dataStartPos,
|
||||
outBuffer->data, (size_t)unpackSize, allocTemp);
|
||||
RINOK(res);
|
||||
@@ -1202,3 +1292,85 @@ SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAl
|
||||
SzArEx_Free(p, allocMain);
|
||||
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_MINOR 04
|
||||
#define MY_VER_MINOR 06
|
||||
#define MY_VER_BUILD 0
|
||||
#define MY_VERSION "9.04 beta"
|
||||
#define MY_DATE "2009-05-30"
|
||||
#define MY_VERSION "9.06 beta"
|
||||
#define MY_DATE "2009-08-17"
|
||||
#define MY_COPYRIGHT ": Igor Pavlov : Public domain"
|
||||
#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
|
||||
2008-08-05
|
||||
Igor Pavlov
|
||||
Public domain */
|
||||
2009-06-10 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Aes.h"
|
||||
#include "CpuArch.h"
|
||||
@@ -49,7 +47,7 @@ void AesGenTables(void)
|
||||
{
|
||||
UInt32 a1 = Sbox[i];
|
||||
UInt32 a2 = xtime(a1);
|
||||
UInt32 a3 = xtime(a1) ^ a1;
|
||||
UInt32 a3 = a2 ^ a1;
|
||||
T[ i] = Ui32(a2, a1, a1, a3);
|
||||
T[0x100 + i] = Ui32(a3, a2, a1, 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;
|
||||
|
||||
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++)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
2009-03-22 : Igor Pavlov : Public domain */
|
||||
2009-08-11 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __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.
|
||||
*/
|
||||
|
||||
#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
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
/* Lzma86Enc.h -- LZMA + x86 (BCJ) Filter Encoder
|
||||
2009-02-07 : Igor Pavlov : Public domain */
|
||||
/* Lzma86.h -- LZMA + x86 (BCJ) Filter
|
||||
2009-08-14 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __LZMA86_ENC_H
|
||||
#define __LZMA86_ENC_H
|
||||
#ifndef __LZMA86_H
|
||||
#define __LZMA86_H
|
||||
|
||||
#include "../Types.h"
|
||||
#include "Types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
#define LZMA86_SIZE_OFFSET (1 + 5)
|
||||
#define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8)
|
||||
|
||||
/*
|
||||
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 (14 bytes):
|
||||
Offset Size Description
|
||||
0 1 = 0 - no filter,
|
||||
= 1 - x86 filter
|
||||
0 1 = 0 - no filter, pure LZMA
|
||||
= 1 - x86 filter + LZMA
|
||||
1 1 lc, lp and pb in encoded form
|
||||
2 4 dictSize (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.
|
||||
|
||||
|
||||
dictSize - The dictionary size in bytes. The maximum value is
|
||||
128 MB = (1 << 27) bytes for 32-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,
|
||||
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
|
||||
@@ -1,20 +1,14 @@
|
||||
/* Lzma86Dec.c -- LZMA + x86 (BCJ) Filter Decoder
|
||||
2008-04-07
|
||||
Igor Pavlov
|
||||
Public domain */
|
||||
2009-08-14 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Lzma86Dec.h"
|
||||
#include "Lzma86.h"
|
||||
|
||||
#include "../Alloc.h"
|
||||
#include "../Bra.h"
|
||||
#include "../LzmaDec.h"
|
||||
|
||||
#define LZMA86_SIZE_OFFSET (1 + LZMA_PROPS_SIZE)
|
||||
#define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8)
|
||||
#include "Alloc.h"
|
||||
#include "Bra.h"
|
||||
#include "LzmaDec.h"
|
||||
|
||||
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 ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
||||
|
||||
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)
|
||||
{
|
||||
ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
||||
SRes res;
|
||||
int useFilter;
|
||||
SizeT inSizePure;
|
||||
@@ -1,28 +1,23 @@
|
||||
/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder
|
||||
2008-08-05
|
||||
Igor Pavlov
|
||||
Public domain */
|
||||
2009-08-14 : Igor Pavlov : Public domain */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "Lzma86Enc.h"
|
||||
#include "Lzma86.h"
|
||||
|
||||
#include "../Alloc.h"
|
||||
#include "../Bra.h"
|
||||
#include "../LzmaEnc.h"
|
||||
#include "Alloc.h"
|
||||
#include "Bra.h"
|
||||
#include "LzmaEnc.h"
|
||||
|
||||
#define SZE_OUT_OVERFLOW SZE_DATA_ERROR
|
||||
|
||||
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 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 level, UInt32 dictSize, int filterMode)
|
||||
{
|
||||
ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
||||
size_t outSize2 = *destLen;
|
||||
Byte *filteredStream;
|
||||
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
|
||||
2009-03-27 : Igor Pavlov : Public domain */
|
||||
2009-07-20 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
#include <process.h>
|
||||
#endif
|
||||
|
||||
#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 */
|
||||
*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);
|
||||
#endif
|
||||
/* maybe we must use errno here, but probably GetLastError() is also OK. */
|
||||
return HandleToWRes(*p);
|
||||
}
|
||||
|
||||
16
C/Types.h
16
C/Types.h
@@ -1,5 +1,5 @@
|
||||
/* Types.h -- Basic types
|
||||
2009-02-07 : Igor Pavlov : Public domain */
|
||||
2009-08-14 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __7Z_TYPES_H
|
||||
#define __7Z_TYPES_H
|
||||
@@ -10,9 +10,17 @@
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifndef EXTERN_C_BEGIN
|
||||
#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
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
#define SZ_OK 0
|
||||
|
||||
@@ -209,8 +217,6 @@ typedef struct
|
||||
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
|
||||
#define IAlloc_Free(p, a) (p)->Free((p), a)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
||||
|
||||
@@ -42,7 +42,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# 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 RSC /l 0x419 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -67,7 +67,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# 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 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 RSC /l 0x419 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -132,6 +132,10 @@ SOURCE=..\..\Bra86.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\CpuArch.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Lzma2Dec.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -153,6 +157,10 @@ SOURCE=..\..\Types.h
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\7z.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zAlloc.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -161,43 +169,11 @@ SOURCE=.\7zAlloc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zDecode.c
|
||||
SOURCE=..\..\7zDec.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zDecode.h
|
||||
# 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
|
||||
SOURCE=..\..\7zIn.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
/* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../../7z.h"
|
||||
#include "../../7zCrc.h"
|
||||
#include "../../7zFile.h"
|
||||
#include "../../7zVersion.h"
|
||||
|
||||
#include "7zAlloc.h"
|
||||
#include "7zExtract.h"
|
||||
#include "7zIn.h"
|
||||
|
||||
#ifndef USE_WINDOWS_FILE
|
||||
/* for mkdir */
|
||||
@@ -29,20 +28,162 @@
|
||||
#define CHAR_PATH_SEPARATOR '/'
|
||||
#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
|
||||
return CreateDirectoryA(name, NULL) ? 0 : GetLastError();
|
||||
|
||||
return CreateDirectoryW(name, NULL) ? 0 : GetLastError();
|
||||
|
||||
#else
|
||||
|
||||
CBuf buf;
|
||||
WRes res;
|
||||
Buf_Init(&buf);
|
||||
RINOK(Utf16_To_Char(&buf, name, 1));
|
||||
|
||||
res =
|
||||
#ifdef _WIN32
|
||||
return _mkdir(name)
|
||||
_mkdir((const char *)buf.data)
|
||||
#else
|
||||
return mkdir(name, 0777)
|
||||
mkdir((const char *)buf.data, 0777)
|
||||
#endif
|
||||
== 0 ? 0 : errno;
|
||||
Buf_Free(&buf, &g_Alloc);
|
||||
return res;
|
||||
|
||||
#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)
|
||||
{
|
||||
@@ -128,7 +269,7 @@ int MY_CDECL main(int numargs, char *args[])
|
||||
SRes res;
|
||||
ISzAlloc allocImp;
|
||||
ISzAlloc allocTempImp;
|
||||
char *temp = NULL;
|
||||
UInt16 *temp = NULL;
|
||||
size_t tempSize = 0;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
allocImp.Alloc = SzAlloc;
|
||||
allocImp.Free = SzFree;
|
||||
|
||||
allocTempImp.Alloc = SzAllocTemp;
|
||||
allocTempImp.Free = SzFreeTemp;
|
||||
|
||||
if (InFile_Open(&archiveStream.file, args[2]))
|
||||
{
|
||||
PrintError("can not open input file");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
FileInStream_CreateVTable(&archiveStream);
|
||||
LookToRead_CreateVTable(&lookStream, False);
|
||||
|
||||
lookStream.realStream = &archiveStream.s;
|
||||
LookToRead_Init(&lookStream);
|
||||
|
||||
allocImp.Alloc = SzAlloc;
|
||||
allocImp.Free = SzFree;
|
||||
|
||||
allocTempImp.Alloc = SzAllocTemp;
|
||||
allocTempImp.Free = SzFreeTemp;
|
||||
|
||||
CrcGenerateTable();
|
||||
|
||||
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, "e") == 0) extractCommand = 1;
|
||||
else if (strcmp(command, "x") == 0) { extractCommand = 1; fullPaths = 1; }
|
||||
|
||||
if (listCommand)
|
||||
else
|
||||
{
|
||||
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
|
||||
strcpy(t, " ");
|
||||
|
||||
printf("%s %10s %s", t, s, f->Name);
|
||||
if (f->IsDir)
|
||||
printf("/");
|
||||
printf("\n");
|
||||
}
|
||||
PrintError("incorrect command");
|
||||
res = SZ_ERROR_FAIL;
|
||||
}
|
||||
else if (testCommand || extractCommand)
|
||||
|
||||
if (res == SZ_OK)
|
||||
{
|
||||
UInt32 i;
|
||||
|
||||
@@ -214,20 +340,52 @@ int MY_CDECL main(int numargs, char *args[])
|
||||
|
||||
for (i = 0; i < db.db.NumFiles; i++)
|
||||
{
|
||||
size_t offset;
|
||||
size_t outSizeProcessed;
|
||||
size_t offset = 0;
|
||||
size_t outSizeProcessed = 0;
|
||||
const CSzFileItem *f = db.db.Files + i;
|
||||
if (f->IsDir && !fullPaths)
|
||||
size_t len;
|
||||
if (listCommand == 0 && f->IsDir && !fullPaths)
|
||||
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 ?
|
||||
"Testing ":
|
||||
"Extracting");
|
||||
printf(" %s", f->Name);
|
||||
"Testing ":
|
||||
"Extracting ");
|
||||
PrintString(temp);
|
||||
if (f->IsDir)
|
||||
printf("/");
|
||||
else
|
||||
{
|
||||
res = SzAr_Extract(&db, &lookStream.s, i,
|
||||
res = SzArEx_Extract(&db, &lookStream.s, i,
|
||||
&blockIndex, &outBuffer, &outBufferSize,
|
||||
&offset, &outSizeProcessed,
|
||||
&allocImp, &allocTempImp);
|
||||
@@ -238,32 +396,20 @@ int MY_CDECL main(int numargs, char *args[])
|
||||
{
|
||||
CSzFile outFile;
|
||||
size_t processedSize;
|
||||
size_t j, nameLen = strlen(f->Name);
|
||||
const char *destPath;
|
||||
if (nameLen + 1 > tempSize)
|
||||
{
|
||||
SzFree(NULL, temp);
|
||||
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] == '/')
|
||||
size_t j;
|
||||
UInt16 *name = (UInt16 *)temp;
|
||||
const UInt16 *destPath = (const UInt16 *)name;
|
||||
for (j = 0; name[j] != 0; j++)
|
||||
if (name[j] == '/')
|
||||
{
|
||||
if (fullPaths)
|
||||
{
|
||||
temp[j] = 0;
|
||||
MyCreateDir(temp);
|
||||
temp[j] = CHAR_PATH_SEPARATOR;
|
||||
name[j] = 0;
|
||||
MyCreateDir(name);
|
||||
name[j] = CHAR_PATH_SEPARATOR;
|
||||
}
|
||||
else
|
||||
destPath = temp + j + 1;
|
||||
destPath = name + j + 1;
|
||||
}
|
||||
|
||||
if (f->IsDir)
|
||||
@@ -272,15 +418,14 @@ int MY_CDECL main(int numargs, char *args[])
|
||||
printf("\n");
|
||||
continue;
|
||||
}
|
||||
else if (OutFile_Open(&outFile, destPath))
|
||||
else if (OutFile_OpenUtf16(&outFile, destPath))
|
||||
{
|
||||
PrintError("can not open output file");
|
||||
res = SZ_ERROR_FAIL;
|
||||
break;
|
||||
}
|
||||
processedSize = outSizeProcessed;
|
||||
if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 ||
|
||||
processedSize != outSizeProcessed)
|
||||
if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed)
|
||||
{
|
||||
PrintError("can not write output file");
|
||||
res = SZ_ERROR_FAIL;
|
||||
@@ -297,11 +442,6 @@ int MY_CDECL main(int numargs, char *args[])
|
||||
}
|
||||
IAlloc_Free(&allocImp, outBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintError("incorrect command");
|
||||
res = SZ_ERROR_FAIL;
|
||||
}
|
||||
}
|
||||
SzArEx_Free(&db, &allocImp);
|
||||
SzFree(NULL, temp);
|
||||
@@ -6,20 +6,17 @@ C_OBJS = \
|
||||
$O\7zBuf.obj \
|
||||
$O\7zBuf2.obj \
|
||||
$O\7zCrc.obj \
|
||||
$O\LzmaDec.obj \
|
||||
$O\Lzma2Dec.obj \
|
||||
$O\Bra86.obj \
|
||||
$O\Bcj2.obj \
|
||||
$O\7zFile.obj \
|
||||
$O\7zDec.obj \
|
||||
$O\7zIn.obj \
|
||||
$O\7zStream.obj \
|
||||
$O\Bcj2.obj \
|
||||
$O\Bra86.obj \
|
||||
$O\Lzma2Dec.obj \
|
||||
$O\LzmaDec.obj \
|
||||
|
||||
7Z_OBJS = \
|
||||
$O\7zAlloc.obj \
|
||||
$O\7zDecode.obj \
|
||||
$O\7zExtract.obj \
|
||||
$O\7zHeader.obj \
|
||||
$O\7zIn.obj \
|
||||
$O\7zItem.obj \
|
||||
$O\7zMain.obj \
|
||||
|
||||
OBJS = \
|
||||
@@ -4,7 +4,7 @@ LIB =
|
||||
RM = rm -f
|
||||
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)
|
||||
|
||||
@@ -23,20 +23,11 @@ $(PROG): $(OBJS)
|
||||
7zCrc.o: ../../7zCrc.c
|
||||
$(CXX) $(CFLAGS) ../../7zCrc.c
|
||||
|
||||
7zDecode.o: 7zDecode.c
|
||||
$(CXX) $(CFLAGS) 7zDecode.c
|
||||
7zDec.o: ../../7zDec.c
|
||||
$(CXX) $(CFLAGS) ../../7zDec.c
|
||||
|
||||
7zExtract.o: 7zExtract.c
|
||||
$(CXX) $(CFLAGS) 7zExtract.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
|
||||
7zIn.o: ../../7zIn.c
|
||||
$(CXX) $(CFLAGS) ../../7zIn.c
|
||||
|
||||
7zMain.o: 7zMain.c
|
||||
$(CXX) $(CFLAGS) 7zMain.c
|
||||
@@ -1,5 +1,5 @@
|
||||
/* 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
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../Alloc.h"
|
||||
#include "../7zFile.h"
|
||||
#include "../7zVersion.h"
|
||||
#include "../LzmaDec.h"
|
||||
#include "../LzmaEnc.h"
|
||||
#include "../../Alloc.h"
|
||||
#include "../../7zFile.h"
|
||||
#include "../../7zVersion.h"
|
||||
#include "../../LzmaDec.h"
|
||||
#include "../../LzmaEnc.h"
|
||||
|
||||
const char *kCantReadMessage = "Can not read input file";
|
||||
const char *kCantWriteMessage = "Can not write output file";
|
||||
@@ -51,7 +51,7 @@ BSC32=bscmake.exe
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib 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"
|
||||
|
||||
@@ -76,7 +76,7 @@ BSC32=bscmake.exe
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib 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
|
||||
|
||||
@@ -86,67 +86,67 @@ LINK32=link.exe
|
||||
# Name "LzmaUtil - Win32 Debug"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\7zFile.c
|
||||
SOURCE=..\..\7zFile.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\7zFile.h
|
||||
SOURCE=..\..\7zFile.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\7zStream.c
|
||||
SOURCE=..\..\7zStream.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\7zVersion.h
|
||||
SOURCE=..\..\7zVersion.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Alloc.c
|
||||
SOURCE=..\..\Alloc.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Alloc.h
|
||||
SOURCE=..\..\Alloc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\CpuArch.h
|
||||
SOURCE=..\..\CpuArch.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LzFind.c
|
||||
SOURCE=..\..\LzFind.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LzFind.h
|
||||
SOURCE=..\..\LzFind.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LzFindMt.c
|
||||
SOURCE=..\..\LzFindMt.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LzFindMt.h
|
||||
SOURCE=..\..\LzFindMt.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LzHash.h
|
||||
SOURCE=..\..\LzHash.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LzmaDec.c
|
||||
SOURCE=..\..\LzmaDec.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LzmaDec.h
|
||||
SOURCE=..\..\LzmaDec.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LzmaEnc.c
|
||||
SOURCE=..\..\LzmaEnc.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LzmaEnc.h
|
||||
SOURCE=..\..\LzmaEnc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -154,15 +154,15 @@ SOURCE=.\LzmaUtil.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Threads.c
|
||||
SOURCE=..\..\Threads.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Threads.h
|
||||
SOURCE=..\..\Threads.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Types.h
|
||||
SOURCE=..\..\Types.h
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -21,9 +21,9 @@ OBJS = \
|
||||
$(LIB_OBJS) \
|
||||
$(C_OBJS) \
|
||||
|
||||
!include "../../CPP/Build.mak"
|
||||
!include "../../../CPP/Build.mak"
|
||||
|
||||
$(LIB_OBJS): $(*B).c
|
||||
$(COMPL_O2)
|
||||
$(C_OBJS): ../$(*B).c
|
||||
$(C_OBJS): ../../$(*B).c
|
||||
$(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
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Alloc.c
|
||||
SOURCE=..\..\Alloc.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Alloc.h
|
||||
SOURCE=..\..\Alloc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\IStream.h
|
||||
SOURCE=..\..\IStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LzFind.c
|
||||
SOURCE=..\..\LzFind.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LzFind.h
|
||||
SOURCE=..\..\LzFind.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LzFindMt.c
|
||||
SOURCE=..\..\LzFindMt.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LzFindMt.h
|
||||
SOURCE=..\..\LzFindMt.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LzHash.h
|
||||
SOURCE=..\..\LzHash.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LzmaDec.c
|
||||
SOURCE=..\..\LzmaDec.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LzmaDec.h
|
||||
SOURCE=..\..\LzmaDec.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LzmaEnc.c
|
||||
SOURCE=..\..\LzmaEnc.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LzmaEnc.h
|
||||
SOURCE=..\..\LzmaEnc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LzmaLib.c
|
||||
SOURCE=..\..\LzmaLib.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LzmaLib.h
|
||||
SOURCE=..\..\LzmaLib.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -164,15 +164,15 @@ SOURCE=.\resource.rc
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Threads.c
|
||||
SOURCE=..\..\Threads.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Threads.h
|
||||
SOURCE=..\..\Threads.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Types.h
|
||||
SOURCE=..\..\Types.h
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -7,8 +7,6 @@ DEF_FILE = LzmaLib.def
|
||||
CFLAGS = $(CFLAGS) \
|
||||
-DCOMPRESS_MF_MT \
|
||||
|
||||
LIBS = $(LIBS) oleaut32.lib
|
||||
|
||||
LIB_OBJS = \
|
||||
$O\LzmaLibExports.obj \
|
||||
|
||||
@@ -26,12 +24,12 @@ OBJS = \
|
||||
$(C_OBJS) \
|
||||
$O\resource.res
|
||||
|
||||
!include "../../CPP/Build.mak"
|
||||
!include "../../../CPP/Build.mak"
|
||||
|
||||
$(SLIBPATH): $O $(OBJS)
|
||||
lib -out:$(SLIBPATH) $(OBJS) $(LIBS)
|
||||
|
||||
$(LIB_OBJS): $(*B).c
|
||||
$(COMPL_O2)
|
||||
$(C_OBJS): ../$(*B).c
|
||||
$(C_OBJS): ../../$(*B).c
|
||||
$(COMPL_O2)
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "../../CPP/7zip/MyVersionInfo.rc"
|
||||
#include "../../../CPP/7zip/MyVersionInfo.rc"
|
||||
|
||||
MY_VERSION_INFO_DLL("LZMA library", "LZMA")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* XzDec.c -- Xz Decode
|
||||
2009-05-29 : Igor Pavlov : Public domain */
|
||||
2009-06-08 : Igor Pavlov : Public domain */
|
||||
|
||||
/* #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,
|
||||
int srcWasFinished, ELzmaFinishMode finishMode, int *wasFinished)
|
||||
int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished)
|
||||
{
|
||||
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);
|
||||
srcWasFinished = srcWasFinished;
|
||||
*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,
|
||||
const Byte *src, SizeT *srcLen, int srcWasFinished,
|
||||
ELzmaFinishMode finishMode, ECoderStatus *status)
|
||||
ECoderFinishMode finishMode, ECoderStatus *status)
|
||||
{
|
||||
SizeT destLenOrig = *destLen;
|
||||
SizeT srcLenOrig = *srcLen;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* XzEnc.c -- Xz Encode
|
||||
2009-05-26 : Igor Pavlov : Public domain */
|
||||
2009-06-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -442,7 +442,7 @@ static SRes Xz_Compress(CXzStream *xz,
|
||||
|
||||
{
|
||||
UInt64 packPos = seqSizeOutStream.processed;
|
||||
HRESULT res = Lzma2Enc_Encode(lzmaf->lzma2, &seqSizeOutStream.p,
|
||||
SRes res = Lzma2Enc_Encode(lzmaf->lzma2, &seqSizeOutStream.p,
|
||||
#ifdef USE_SUBBLOCK
|
||||
useSubblock ? &lzmaf->sb.p:
|
||||
#endif
|
||||
|
||||
5
C/XzIn.c
5
C/XzIn.c
@@ -1,10 +1,11 @@
|
||||
/* 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 "CpuArch.h"
|
||||
#include "Xz.h"
|
||||
|
||||
SRes Xz_ReadHeader(CXzStreamFlags *p, ISeqInStream *inStream)
|
||||
{
|
||||
|
||||
@@ -164,8 +164,7 @@ HRESULT CEncoder::Encode(
|
||||
}
|
||||
for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
|
||||
{
|
||||
CSequentialOutTempBufferImp *tempBufferSpec =
|
||||
new CSequentialOutTempBufferImp;
|
||||
CSequentialOutTempBufferImp *tempBufferSpec = new CSequentialOutTempBufferImp;
|
||||
CMyComPtr<ISequentialOutStream> tempBuffer = tempBufferSpec;
|
||||
tempBufferSpec->Init(&inOutTempBuffers[i - 1]);
|
||||
tempBuffers.Add(tempBuffer);
|
||||
@@ -260,9 +259,7 @@ HRESULT CEncoder::Encode(
|
||||
for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
|
||||
{
|
||||
CInOutTempBuffer &inOutTempBuffer = inOutTempBuffers[i - 1];
|
||||
inOutTempBuffer.FlushWrite();
|
||||
inOutTempBuffer.InitReading();
|
||||
inOutTempBuffer.WriteToStream(outStream);
|
||||
RINOK(inOutTempBuffer.WriteToStream(outStream));
|
||||
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)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
@@ -52,7 +52,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
|
||||
UInt64 importantTotalUnpacked = 0;
|
||||
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
bool allFilesMode = (numItems == (UInt32)-1);
|
||||
if (allFilesMode)
|
||||
numItems =
|
||||
#ifdef _7Z_VOL
|
||||
@@ -244,25 +244,25 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
|
||||
if (result == S_FALSE)
|
||||
{
|
||||
RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError));
|
||||
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));
|
||||
continue;
|
||||
}
|
||||
if (result == E_NOTIMPL)
|
||||
{
|
||||
RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
||||
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kUnSupportedMethod));
|
||||
continue;
|
||||
}
|
||||
if (result != S_OK)
|
||||
return result;
|
||||
if (folderOutStream->WasWritingFinished() != S_OK)
|
||||
{
|
||||
RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError));
|
||||
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError));
|
||||
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,9 +37,9 @@ HRESULT CFolderOutStream::Init(
|
||||
HRESULT CFolderOutStream::OpenFile()
|
||||
{
|
||||
Int32 askMode = ((*_extractStatuses)[_currentIndex]) ? (_testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract):
|
||||
NArchive::NExtract::NAskMode::kSkip;
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract) :
|
||||
NExtract::NAskMode::kSkip;
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
UInt32 index = _startIndex + _currentIndex;
|
||||
RINOK(_extractCallback->GetStream(_ref2Offset + index, &realOutStream, askMode));
|
||||
@@ -48,9 +48,9 @@ HRESULT CFolderOutStream::OpenFile()
|
||||
_fileIsOpen = true;
|
||||
const CFileItem &fi = _db->Files[index];
|
||||
_rem = fi.Size;
|
||||
if (askMode == NArchive::NExtract::NAskMode::kExtract && !realOutStream &&
|
||||
if (askMode == NExtract::NAskMode::kExtract && !realOutStream &&
|
||||
!_db->IsItemAnti(index) && !fi.IsDir)
|
||||
askMode = NArchive::NExtract::NAskMode::kSkip;
|
||||
askMode = NExtract::NAskMode::kSkip;
|
||||
return _extractCallback->PrepareOperation(askMode);
|
||||
}
|
||||
|
||||
@@ -67,8 +67,8 @@ HRESULT CFolderOutStream::CloseFileAndSetResult()
|
||||
const CFileItem &fi = _db->Files[_startIndex + _currentIndex];
|
||||
return CloseFileAndSetResult(
|
||||
(fi.IsDir || !fi.CrcDefined || !_checkCrc || fi.Crc == _crcStreamSpec->GetCRC()) ?
|
||||
NArchive::NExtract::NOperationResult::kOK :
|
||||
NArchive::NExtract::NOperationResult::kCRCError);
|
||||
NExtract::NOperationResult::kOK :
|
||||
NExtract::NOperationResult::kCRCError);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
Byte order = *(const Byte *)coder.Props;
|
||||
methodsString += L'o';
|
||||
methodsString += ConvertUInt32ToString(order);
|
||||
methodsString += L":mem";
|
||||
propsString = L'o';
|
||||
propsString += ConvertUInt32ToString(order);
|
||||
propsString += L":mem";
|
||||
UInt32 dicSize = GetUi32((const Byte *)coder.Props + 1);
|
||||
propsString = GetStringForSizeValue(dicSize);
|
||||
propsString += GetStringForSizeValue(dicSize);
|
||||
}
|
||||
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 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 kAlgorithmForHeaders = kLzmaAlgorithmX5;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// 7z/Header.cpp
|
||||
// 7zHeader.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "7zHeader.h"
|
||||
@@ -6,22 +6,9 @@
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
Byte kSignature[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C};
|
||||
Byte kSignature[kSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
|
||||
#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
|
||||
|
||||
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(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
CEncoder &encoder, const Byte *data, size_t dataSize,
|
||||
CEncoder &encoder, const CByteBuffer &data,
|
||||
CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders)
|
||||
{
|
||||
CSequentialInStreamImp *streamSpec = new CSequentialInStreamImp;
|
||||
CBufInStream *streamSpec = new CBufInStream;
|
||||
CMyComPtr<ISequentialInStream> stream = streamSpec;
|
||||
streamSpec->Init(data, dataSize);
|
||||
streamSpec->Init(data, data.GetCapacity());
|
||||
CFolder folderItem;
|
||||
folderItem.UnpackCRCDefined = true;
|
||||
folderItem.UnpackCRC = CrcCalc(data, dataSize);
|
||||
UInt64 dataSize64 = dataSize;
|
||||
folderItem.UnpackCRC = CrcCalc(data, data.GetCapacity());
|
||||
UInt64 dataSize64 = data.GetCapacity();
|
||||
RINOK(encoder.Encode(
|
||||
EXTERNAL_CODECS_LOC_VARS
|
||||
stream, NULL, &dataSize64, folderItem, SeqStream, packSizes, NULL))
|
||||
@@ -558,16 +558,6 @@ HRESULT COutArchive::EncodeStream(
|
||||
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(
|
||||
const CArchiveDatabase &db,
|
||||
const CHeaderOptions &headerOptions,
|
||||
@@ -804,8 +794,8 @@ HRESULT COutArchive::WriteDatabase(
|
||||
CObjectVector<CFolder> folders;
|
||||
RINOK(EncodeStream(
|
||||
EXTERNAL_CODECS_LOC_VARS
|
||||
encoder, (const Byte *)buf,
|
||||
_countSize, packSizes, folders));
|
||||
encoder, buf,
|
||||
packSizes, folders));
|
||||
|
||||
_writeToStream = true;
|
||||
|
||||
|
||||
@@ -98,10 +98,6 @@ class COutArchive
|
||||
void WriteAlignedBoolHeader(const CBoolVector &v, int numDefined, Byte type, unsigned itemSize);
|
||||
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(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
CEncoder &encoder, const CByteBuffer &data,
|
||||
|
||||
@@ -5,14 +5,14 @@
|
||||
#include "../../Common/RegisterArc.h"
|
||||
|
||||
#include "7zHandler.h"
|
||||
static IInArchive *CreateArc() { return new NArchive::N7z::CHandler; }
|
||||
static IInArchive *CreateArc() { return new NArchive::N7z::CHandler; }
|
||||
#ifndef EXTRACT_ONLY
|
||||
static IOutArchive *CreateArcOut() { return new NArchive::N7z::CHandler; }
|
||||
static IOutArchive *CreateArcOut() { return new NArchive::N7z::CHandler; }
|
||||
#else
|
||||
#define CreateArcOut 0
|
||||
#endif
|
||||
|
||||
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)
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../../../C/CpuArch.h"
|
||||
|
||||
#include "../../Common/LimitedStreams.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 kNumFastBytesForBCJ2_LZMA = 64;
|
||||
|
||||
#ifdef MY_CPU_X86_OR_AMD64
|
||||
#define USE_86_FILTER
|
||||
#endif
|
||||
|
||||
static HRESULT WriteRange(IInStream *inStream, ISequentialOutStream *outStream,
|
||||
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 Group;
|
||||
@@ -334,7 +340,9 @@ static bool IsExeExt(const UString &ext)
|
||||
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.NumInStreams = numInStreams;
|
||||
@@ -409,6 +417,8 @@ static void MakeExeMethod(const CCompressionMethodMode &method,
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void FromUpdateItemToFileItem(const CUpdateItem &ui,
|
||||
CFileItem &file, CFileItem2 &file2)
|
||||
{
|
||||
@@ -665,7 +675,9 @@ STDMETHODIMP CCryptoGetTextPassword::CryptoGetTextPassword(BSTR *password)
|
||||
|
||||
static const int kNumGroupsMax = 4;
|
||||
|
||||
#ifdef USE_86_FILTER
|
||||
static bool Is86Group(int group) { return (group & 1) != 0; }
|
||||
#endif
|
||||
static bool IsEncryptedGroup(int group) { return (group & 2) != 0; }
|
||||
static int GetGroupIndex(bool encrypted, int bcjFiltered)
|
||||
{ return (encrypted ? 2 : 0) + (bcjFiltered ? 1 : 0); }
|
||||
@@ -865,9 +877,11 @@ HRESULT Update(
|
||||
const CSolidGroup &group = groups[groupIndex];
|
||||
|
||||
CCompressionMethodMode method;
|
||||
#ifdef USE_86_FILTER
|
||||
if (Is86Group(groupIndex))
|
||||
MakeExeMethod(*options.Method, options.MaxFilter, method);
|
||||
else
|
||||
#endif
|
||||
method = *options.Method;
|
||||
|
||||
if (IsEncryptedGroup(groupIndex))
|
||||
|
||||
@@ -4,8 +4,6 @@ CFLAGS = $(CFLAGS) -I ../../../ \
|
||||
-DCOMPRESS_MT \
|
||||
-DEXTERNAL_CODECS \
|
||||
|
||||
LIBS = $(LIBS) oleaut32.lib user32.lib
|
||||
|
||||
AR_OBJS = \
|
||||
$O\ArchiveExports.obj \
|
||||
$O\DllExports.obj \
|
||||
|
||||
@@ -10,11 +10,17 @@
|
||||
|
||||
static const unsigned int kNumArcsMax = 48;
|
||||
static unsigned int g_NumArcs = 0;
|
||||
static unsigned int g_DefaultArcIndex = 0;
|
||||
static const CArcInfo *g_Arcs[kNumArcsMax];
|
||||
void RegisterArc(const CArcInfo *arcInfo)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_GUID(CLSID_CArchiveHandler,
|
||||
@@ -117,7 +123,7 @@ STDAPI GetHandlerProperty2(UInt32 formatIndex, 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)
|
||||
|
||||
@@ -652,13 +652,12 @@ STDMETHODIMP CHandler::Close()
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
Int32 testModeSpec, IArchiveExtractCallback *extractCallback)
|
||||
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool testMode = (testModeSpec != 0);
|
||||
UInt64 totalUnpacked = 0, totalPacked = 0;
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
bool allFilesMode = (numItems == (UInt32)-1);
|
||||
if (allFilesMode)
|
||||
numItems = _items.Size();
|
||||
if (numItems == 0)
|
||||
@@ -714,7 +713,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!testMode && (!realOutStream))
|
||||
if (!testMode && !realOutStream)
|
||||
continue;
|
||||
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
@@ -789,7 +788,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
static IInArchive *CreateArc() { return new CHandler; }
|
||||
static IInArchive *CreateArc() { return new CHandler; }
|
||||
|
||||
static CArcInfo g_ArcInfo =
|
||||
{ L"Arj", L"arj", 0, 4, { 0x60, 0xEA }, 2, false, CreateArc, 0 };
|
||||
|
||||
@@ -154,28 +154,23 @@ STDMETHODIMP CHandler::Close()
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
||||
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool allFilesMode = (numItems == (UInt32)-1);
|
||||
if (!allFilesMode)
|
||||
{
|
||||
if (numItems == 0)
|
||||
return S_OK;
|
||||
if (numItems != 1 || indices[0] != 0)
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
if (numItems == 0)
|
||||
return S_OK;
|
||||
if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0))
|
||||
return E_INVALIDARG;
|
||||
|
||||
bool testMode = (_aTestMode != 0);
|
||||
if (_stream)
|
||||
extractCallback->SetTotal(_packSize);
|
||||
UInt64 currentTotalPacked = 0;
|
||||
RINOK(extractCallback->SetCompleted(¤tTotalPacked));
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode = testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract;
|
||||
RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
|
||||
if (!testMode && !realOutStream)
|
||||
return S_OK;
|
||||
@@ -421,7 +416,7 @@ static IOutArchive *CreateArcOut() { return new CHandler; }
|
||||
#endif
|
||||
|
||||
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)
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/Buffer.h"
|
||||
#include "Common/ComTry.h"
|
||||
#include "Common/Defs.h"
|
||||
#include "Common/IntToString.h"
|
||||
@@ -12,6 +13,7 @@
|
||||
#include "Windows/Time.h"
|
||||
|
||||
#include "../../Common/ProgressUtils.h"
|
||||
#include "../../Common/StreamUtils.h"
|
||||
|
||||
#include "../../Compress/CopyCoder.h"
|
||||
#include "../../Compress/DeflateDecoder.h"
|
||||
@@ -30,6 +32,8 @@ namespace NCab {
|
||||
|
||||
// #define _CAB_DETAILS
|
||||
|
||||
static const UInt32 kMaxTempBufSize = 1 << 20;
|
||||
|
||||
#ifdef _CAB_DETAILS
|
||||
enum
|
||||
{
|
||||
@@ -279,7 +283,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
{
|
||||
const CInArchiveInfo &ai = m_Database.Volumes.Front().ArchiveInfo;
|
||||
if (ai.IsTherePrev())
|
||||
otherArchive = &ai.PreviousArchive;
|
||||
otherArchive = &ai.PrevArc;
|
||||
else
|
||||
prevChecked = true;
|
||||
}
|
||||
@@ -287,7 +291,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
{
|
||||
const CInArchiveInfo &ai = m_Database.Volumes.Back().ArchiveInfo;
|
||||
if (ai.IsThereNext())
|
||||
otherArchive = &ai.NextArchive;
|
||||
otherArchive = &ai.NextArc;
|
||||
}
|
||||
if (!otherArchive)
|
||||
break;
|
||||
@@ -328,7 +332,7 @@ STDMETHODIMP CHandler::Close()
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
class CCabFolderOutStream:
|
||||
class CFolderOutStream:
|
||||
public ISequentialOutStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
@@ -339,6 +343,12 @@ public:
|
||||
private:
|
||||
const CMvDatabaseEx *m_Database;
|
||||
const CRecordVector<bool> *m_ExtractStatuses;
|
||||
|
||||
CByteBuffer TempBuf;
|
||||
bool TempBufMode;
|
||||
bool IsSupported;
|
||||
UInt32 m_BufStartFolderOffset;
|
||||
|
||||
int m_StartIndex;
|
||||
int m_CurrentIndex;
|
||||
CMyComPtr<IArchiveExtractCallback> m_ExtractCallback;
|
||||
@@ -348,11 +358,12 @@ private:
|
||||
|
||||
bool m_IsOk;
|
||||
bool m_FileIsOpen;
|
||||
UInt64 m_RemainFileSize;
|
||||
UInt32 m_RemainFileSize;
|
||||
UInt64 m_FolderSize;
|
||||
UInt64 m_PosInFolder;
|
||||
|
||||
HRESULT OpenFile();
|
||||
HRESULT CloseFile();
|
||||
HRESULT Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK);
|
||||
public:
|
||||
HRESULT WriteEmptyFiles();
|
||||
@@ -371,7 +382,7 @@ public:
|
||||
UInt64 GetPosInFolder() const { return m_PosInFolder; }
|
||||
};
|
||||
|
||||
void CCabFolderOutStream::Init(
|
||||
void CFolderOutStream::Init(
|
||||
const CMvDatabaseEx *database,
|
||||
const CRecordVector<bool> *extractStatuses,
|
||||
int startIndex,
|
||||
@@ -391,25 +402,66 @@ void CCabFolderOutStream::Init(
|
||||
m_PosInFolder = 0;
|
||||
m_FileIsOpen = false;
|
||||
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 ?
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract) :
|
||||
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));
|
||||
if (!m_RealOutStream && !m_TestMode)
|
||||
askMode = NArchive::NExtract::NAskMode::kSkip;
|
||||
askMode = NExtract::NAskMode::kSkip;
|
||||
return m_ExtractCallback->PrepareOperation(askMode);
|
||||
}
|
||||
|
||||
HRESULT CCabFolderOutStream::WriteEmptyFiles()
|
||||
HRESULT CFolderOutStream::WriteEmptyFiles()
|
||||
{
|
||||
if (m_FileIsOpen)
|
||||
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 CItem &item = m_Database->Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
|
||||
@@ -419,22 +471,23 @@ HRESULT CCabFolderOutStream::WriteEmptyFiles()
|
||||
HRESULT result = OpenFile();
|
||||
m_RealOutStream.Release();
|
||||
RINOK(result);
|
||||
RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
RINOK(m_ExtractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// 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;
|
||||
if (processedSize != NULL)
|
||||
*processedSize = 0;
|
||||
while(size != 0)
|
||||
while (size != 0)
|
||||
{
|
||||
if (m_FileIsOpen)
|
||||
{
|
||||
UInt32 numBytesToWrite = (UInt32)MyMin(m_RemainFileSize, (UInt64)(size));
|
||||
UInt32 numBytesToWrite = MyMin(m_RemainFileSize, size);
|
||||
HRESULT res = S_OK;
|
||||
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);
|
||||
numBytesToWrite = processedSizeLocal;
|
||||
}
|
||||
if (TempBufMode && IsSupported)
|
||||
memcpy(TempBuf + (m_PosInFolder - m_BufStartFolderOffset), data, numBytesToWrite);
|
||||
}
|
||||
realProcessed += numBytesToWrite;
|
||||
if (processedSize != NULL)
|
||||
@@ -459,11 +514,37 @@ HRESULT CCabFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *proce
|
||||
if (m_RemainFileSize == 0)
|
||||
{
|
||||
m_RealOutStream.Release();
|
||||
RINOK(m_ExtractCallback->SetOperationResult(
|
||||
m_IsOk ?
|
||||
NArchive::NExtract::NOperationResult::kOK:
|
||||
NArchive::NExtract::NOperationResult::kDataError));
|
||||
m_FileIsOpen = false;
|
||||
RINOK(CloseFile());
|
||||
|
||||
if (TempBufMode)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
TempBufMode = false;
|
||||
}
|
||||
}
|
||||
if (realProcessed > 0)
|
||||
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;
|
||||
if (fileOffset > m_PosInFolder)
|
||||
{
|
||||
UInt32 numBytesToWrite = (UInt32)MyMin((UInt64)fileOffset - m_PosInFolder, UInt64(size));
|
||||
UInt32 numBytesToWrite = MyMin(fileOffset - (UInt32)m_PosInFolder, size);
|
||||
realProcessed += numBytesToWrite;
|
||||
if (processedSize != NULL)
|
||||
*processedSize = realProcessed;
|
||||
@@ -501,14 +582,15 @@ HRESULT CCabFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *proce
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
HRESULT CCabFolderOutStream::FlushCorrupted()
|
||||
HRESULT CFolderOutStream::FlushCorrupted()
|
||||
{
|
||||
const UInt32 kBufferSize = (1 << 10);
|
||||
Byte buffer[kBufferSize];
|
||||
@@ -525,7 +607,7 @@ HRESULT CCabFolderOutStream::FlushCorrupted()
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT CCabFolderOutStream::Unsupported()
|
||||
HRESULT CFolderOutStream::Unsupported()
|
||||
{
|
||||
while(m_CurrentIndex < m_ExtractStatuses->Size())
|
||||
{
|
||||
@@ -533,23 +615,23 @@ HRESULT CCabFolderOutStream::Unsupported()
|
||||
if (result != S_FALSE && result != S_OK)
|
||||
return result;
|
||||
m_RealOutStream.Release();
|
||||
RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
||||
RINOK(m_ExtractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod));
|
||||
m_CurrentIndex++;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
||||
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
Int32 testModeSpec, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool allFilesMode = (numItems == (UInt32)(-1));
|
||||
bool allFilesMode = (numItems == (UInt32)-1);
|
||||
if (allFilesMode)
|
||||
numItems = m_Database.Items.Size();
|
||||
if(numItems == 0)
|
||||
return S_OK;
|
||||
bool testMode = (_aTestMode != 0);
|
||||
bool testMode = (testModeSpec != 0);
|
||||
UInt64 totalUnPacked = 0;
|
||||
|
||||
UInt32 i;
|
||||
@@ -610,14 +692,14 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
i++;
|
||||
if (item.IsDir())
|
||||
{
|
||||
Int32 askMode= testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
Int32 askMode = testMode ?
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract;
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||
continue;
|
||||
}
|
||||
int folderIndex = m_Database.GetFolderIndex(&mvItem);
|
||||
@@ -625,13 +707,13 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
{
|
||||
// If we need previous archive
|
||||
Int32 askMode= testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract;
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError));
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kDataError));
|
||||
continue;
|
||||
}
|
||||
int startIndex2 = m_Database.FolderStartFileIndex[folderIndex];
|
||||
@@ -664,7 +746,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
lps->InSize = totalPacked;
|
||||
RINOK(lps->SetCur());
|
||||
|
||||
CCabFolderOutStream *cabFolderOutStream = new CCabFolderOutStream;
|
||||
CFolderOutStream *cabFolderOutStream = new CFolderOutStream;
|
||||
CMyComPtr<ISequentialOutStream> outStream(cabFolderOutStream);
|
||||
|
||||
const CFolder &folder = db.Folders[item.GetFolderIndex(db.Folders.Size())];
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
// Archive/Cab/Header.h
|
||||
// CabHeader.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "CabHeader.h"
|
||||
|
||||
namespace NArchive{
|
||||
namespace NCab{
|
||||
namespace NHeader{
|
||||
namespace NArchive {
|
||||
namespace NCab {
|
||||
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 "CabIn.h"
|
||||
|
||||
#include "../Common/FindSignature.h"
|
||||
|
||||
#include "CabIn.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NCab {
|
||||
|
||||
Byte CInArchive::ReadByte()
|
||||
Byte CInArchive::Read8()
|
||||
{
|
||||
Byte b;
|
||||
if (!inBuffer.ReadByte(b))
|
||||
@@ -17,23 +17,23 @@ Byte CInArchive::ReadByte()
|
||||
return b;
|
||||
}
|
||||
|
||||
UInt16 CInArchive::ReadUInt16()
|
||||
UInt16 CInArchive::Read16()
|
||||
{
|
||||
UInt16 value = 0;
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
Byte b = ReadByte();
|
||||
Byte b = Read8();
|
||||
value |= (UInt16(b) << (8 * i));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
UInt32 CInArchive::ReadUInt32()
|
||||
UInt32 CInArchive::Read32()
|
||||
{
|
||||
UInt32 value = 0;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
Byte b = ReadByte();
|
||||
Byte b = Read8();
|
||||
value |= (UInt32(b) << (8 * i));
|
||||
}
|
||||
return value;
|
||||
@@ -44,7 +44,7 @@ AString CInArchive::SafeReadName()
|
||||
AString name;
|
||||
for (;;)
|
||||
{
|
||||
Byte b = ReadByte();
|
||||
Byte b = Read8();
|
||||
if (b == 0)
|
||||
return name;
|
||||
name += (char)b;
|
||||
@@ -57,61 +57,60 @@ void CInArchive::ReadOtherArchive(COtherArchive &oa)
|
||||
oa.DiskName = SafeReadName();
|
||||
}
|
||||
|
||||
void CInArchive::Skip(size_t size)
|
||||
void CInArchive::Skip(UInt32 size)
|
||||
{
|
||||
while (size-- != 0)
|
||||
ReadByte();
|
||||
Read8();
|
||||
}
|
||||
|
||||
HRESULT CInArchive::Open2(IInStream *stream,
|
||||
const UInt64 *searchHeaderSizeLimit,
|
||||
CDatabase &database)
|
||||
HRESULT CInArchive::Open(const UInt64 *searchHeaderSizeLimit, CDatabaseEx &db)
|
||||
{
|
||||
database.Clear();
|
||||
RINOK(stream->Seek(0, STREAM_SEEK_SET, &database.StartPosition));
|
||||
IInStream *stream = db.Stream;
|
||||
db.Clear();
|
||||
RINOK(stream->Seek(0, STREAM_SEEK_SET, &db.StartPosition));
|
||||
|
||||
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))
|
||||
return E_OUTOFMEMORY;
|
||||
inBuffer.SetStream(stream);
|
||||
inBuffer.Init();
|
||||
|
||||
CInArchiveInfo &ai = database.ArchiveInfo;
|
||||
CInArchiveInfo &ai = db.ArchiveInfo;
|
||||
|
||||
ai.Size = ReadUInt32();
|
||||
if (ReadUInt32() != 0)
|
||||
ai.Size = Read32();
|
||||
if (Read32() != 0)
|
||||
return S_FALSE;
|
||||
ai.FileHeadersOffset = ReadUInt32();
|
||||
if (ReadUInt32() != 0)
|
||||
ai.FileHeadersOffset = Read32();
|
||||
if (Read32() != 0)
|
||||
return S_FALSE;
|
||||
|
||||
ai.VersionMinor = ReadByte();
|
||||
ai.VersionMajor = ReadByte();
|
||||
ai.NumFolders = ReadUInt16();
|
||||
ai.NumFiles = ReadUInt16();
|
||||
ai.Flags = ReadUInt16();
|
||||
ai.VersionMinor = Read8();
|
||||
ai.VersionMajor = Read8();
|
||||
ai.NumFolders = Read16();
|
||||
ai.NumFiles = Read16();
|
||||
ai.Flags = Read16();
|
||||
if (ai.Flags > 7)
|
||||
return S_FALSE;
|
||||
ai.SetID = ReadUInt16();
|
||||
ai.CabinetNumber = ReadUInt16();
|
||||
ai.SetID = Read16();
|
||||
ai.CabinetNumber = Read16();
|
||||
|
||||
if (ai.ReserveBlockPresent())
|
||||
{
|
||||
ai.PerCabinetAreaSize = ReadUInt16();
|
||||
ai.PerFolderAreaSize = ReadByte();
|
||||
ai.PerDataBlockAreaSize = ReadByte();
|
||||
ai.PerCabinetAreaSize = Read16();
|
||||
ai.PerFolderAreaSize = Read8();
|
||||
ai.PerDataBlockAreaSize = Read8();
|
||||
|
||||
Skip(ai.PerCabinetAreaSize);
|
||||
}
|
||||
|
||||
{
|
||||
if (ai.IsTherePrev())
|
||||
ReadOtherArchive(ai.PreviousArchive);
|
||||
ReadOtherArchive(ai.PrevArc);
|
||||
if (ai.IsThereNext())
|
||||
ReadOtherArchive(ai.NextArchive);
|
||||
ReadOtherArchive(ai.NextArc);
|
||||
}
|
||||
|
||||
int i;
|
||||
@@ -119,54 +118,40 @@ HRESULT CInArchive::Open2(IInStream *stream,
|
||||
{
|
||||
CFolder folder;
|
||||
|
||||
folder.DataStart = ReadUInt32();
|
||||
folder.NumDataBlocks = ReadUInt16();
|
||||
folder.CompressionTypeMajor = ReadByte();
|
||||
folder.CompressionTypeMinor = ReadByte();
|
||||
folder.DataStart = Read32();
|
||||
folder.NumDataBlocks = Read16();
|
||||
folder.CompressionTypeMajor = Read8();
|
||||
folder.CompressionTypeMinor = Read8();
|
||||
|
||||
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.Init();
|
||||
for (i = 0; i < ai.NumFiles; i++)
|
||||
{
|
||||
CItem item;
|
||||
item.Size = ReadUInt32();
|
||||
item.Offset = ReadUInt32();
|
||||
item.FolderIndex = ReadUInt16();
|
||||
UInt16 pureDate = ReadUInt16();
|
||||
UInt16 pureTime = ReadUInt16();
|
||||
item.Size = Read32();
|
||||
item.Offset = Read32();
|
||||
item.FolderIndex = Read16();
|
||||
UInt16 pureDate = Read16();
|
||||
UInt16 pureTime = Read16();
|
||||
item.Time = ((UInt32(pureDate) << 16)) | pureTime;
|
||||
item.Attributes = ReadUInt16();
|
||||
item.Attributes = Read16();
|
||||
item.Name = SafeReadName();
|
||||
int folderIndex = item.GetFolderIndex(database.Folders.Size());
|
||||
if (folderIndex >= database.Folders.Size())
|
||||
int folderIndex = item.GetFolderIndex(db.Folders.Size());
|
||||
if (folderIndex >= db.Folders.Size())
|
||||
return S_FALSE;
|
||||
database.Items.Add(item);
|
||||
db.Items.Add(item);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#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)
|
||||
{
|
||||
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(item1.Offset, item2.Offset));
|
||||
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)
|
||||
@@ -236,8 +222,7 @@ void CMvDatabaseEx::FillSortAndShrink()
|
||||
|
||||
for (i = 0; i < Items.Size(); i++)
|
||||
{
|
||||
const CMvItem &mvItem = Items[i];
|
||||
int folderIndex = GetFolderIndex(&mvItem);
|
||||
int folderIndex = GetFolderIndex(&Items[i]);
|
||||
if (folderIndex >= FolderStartFileIndex.Size())
|
||||
FolderStartFileIndex.Add(i);
|
||||
}
|
||||
@@ -260,7 +245,8 @@ bool CMvDatabaseEx::Check()
|
||||
return false;
|
||||
}
|
||||
}
|
||||
UInt64 maxPos = 0;
|
||||
UInt32 beginPos = 0;
|
||||
UInt64 endPos = 0;
|
||||
int prevFolder = -2;
|
||||
for (int i = 0; i < Items.Size(); i++)
|
||||
{
|
||||
@@ -273,16 +259,12 @@ bool CMvDatabaseEx::Check()
|
||||
continue;
|
||||
int folderIndex = GetFolderIndex(&mvItem);
|
||||
if (folderIndex != prevFolder)
|
||||
{
|
||||
prevFolder = folderIndex;
|
||||
maxPos = 0;
|
||||
continue;
|
||||
}
|
||||
if (item.Offset < maxPos)
|
||||
return false;
|
||||
maxPos = item.GetEndOffset();
|
||||
if (maxPos < item.Offset)
|
||||
else if (item.Offset < endPos &&
|
||||
(item.Offset != beginPos || item.GetEndOffset() != endPos))
|
||||
return false;
|
||||
beginPos = item.Offset;
|
||||
endPos = item.GetEndOffset();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -50,8 +50,8 @@ struct CArchiveInfo
|
||||
|
||||
Byte GetDataBlockReserveSize() const { return (Byte)(ReserveBlockPresent() ? PerDataBlockAreaSize : 0); }
|
||||
|
||||
COtherArchive PreviousArchive;
|
||||
COtherArchive NextArchive;
|
||||
COtherArchive PrevArc;
|
||||
COtherArchive NextArc;
|
||||
|
||||
CArchiveInfo()
|
||||
{
|
||||
@@ -63,7 +63,7 @@ struct CArchiveInfo
|
||||
PerCabinetAreaSize = 0;
|
||||
PerFolderAreaSize = 0;
|
||||
PerDataBlockAreaSize = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct CInArchiveInfo: public CArchiveInfo
|
||||
@@ -73,13 +73,13 @@ struct CInArchiveInfo: public CArchiveInfo
|
||||
};
|
||||
|
||||
|
||||
class CDatabase
|
||||
struct CDatabase
|
||||
{
|
||||
public:
|
||||
UInt64 StartPosition;
|
||||
CInArchiveInfo ArchiveInfo;
|
||||
CObjectVector<CFolder> Folders;
|
||||
CObjectVector<CItem> Items;
|
||||
|
||||
void Clear()
|
||||
{
|
||||
ArchiveInfo.Clear();
|
||||
@@ -104,9 +104,8 @@ public:
|
||||
UInt32 GetFileSize(int index) const { return Items[index].Size; }
|
||||
};
|
||||
|
||||
class CDatabaseEx: public CDatabase
|
||||
struct CDatabaseEx: public CDatabase
|
||||
{
|
||||
public:
|
||||
CMyComPtr<IInStream> Stream;
|
||||
};
|
||||
|
||||
@@ -124,6 +123,7 @@ public:
|
||||
CRecordVector<CMvItem> Items;
|
||||
CRecordVector<int> StartFolderOfVol;
|
||||
CRecordVector<int> FolderStartFileIndex;
|
||||
|
||||
int GetFolderIndex(const CMvItem *mvi) const
|
||||
{
|
||||
const CDatabaseEx &db = Volumes[mvi->VolumeIndex];
|
||||
@@ -145,20 +145,15 @@ class CInArchive
|
||||
{
|
||||
CInBuffer inBuffer;
|
||||
|
||||
Byte ReadByte();
|
||||
UInt16 ReadUInt16();
|
||||
UInt32 ReadUInt32();
|
||||
Byte Read8();
|
||||
UInt16 Read16();
|
||||
UInt32 Read32();
|
||||
AString SafeReadName();
|
||||
void Skip(size_t size);
|
||||
void Skip(UInt32 size);
|
||||
void ReadOtherArchive(COtherArchive &oa);
|
||||
|
||||
HRESULT Open2(IInStream *inStream,
|
||||
const UInt64 *searchHeaderSizeLimit,
|
||||
CDatabase &database);
|
||||
public:
|
||||
HRESULT Open(
|
||||
const UInt64 *searchHeaderSizeLimit,
|
||||
CDatabaseEx &database);
|
||||
HRESULT Open(const UInt64 *searchHeaderSizeLimit, CDatabaseEx &db);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "../../Common/RegisterArc.h"
|
||||
|
||||
#include "CabHandler.h"
|
||||
static IInArchive *CreateArc() { return new NArchive::NCab::CHandler; }
|
||||
static IInArchive *CreateArc() { return new NArchive::NCab::CHandler; }
|
||||
|
||||
static CArcInfo g_ArcInfo =
|
||||
{ L"Cab", L"cab", 0, 8, { 0x4D, 0x53, 0x43, 0x46 }, 4, false, CreateArc, 0 };
|
||||
|
||||
@@ -275,7 +275,7 @@ HRESULT CChmFolderOutStream::OpenFile()
|
||||
m_RealOutStream.Release();
|
||||
RINOK(m_ExtractCallback->GetStream(m_StartIndex + m_CurrentIndex, &m_RealOutStream, askMode));
|
||||
if (!m_RealOutStream && !m_TestMode)
|
||||
askMode = NArchive::NExtract::NAskMode::kSkip;
|
||||
askMode = NExtract::NAskMode::kSkip;
|
||||
return m_ExtractCallback->PrepareOperation(askMode);
|
||||
}
|
||||
|
||||
@@ -291,7 +291,7 @@ HRESULT CChmFolderOutStream::WriteEmptyFiles()
|
||||
HRESULT result = OpenFile();
|
||||
m_RealOutStream.Release();
|
||||
RINOK(result);
|
||||
RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
RINOK(m_ExtractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
@@ -334,8 +334,8 @@ HRESULT CChmFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *proce
|
||||
m_RealOutStream.Release();
|
||||
RINOK(m_ExtractCallback->SetOperationResult(
|
||||
m_IsOk ?
|
||||
NArchive::NExtract::NOperationResult::kOK:
|
||||
NArchive::NExtract::NOperationResult::kDataError));
|
||||
NExtract::NOperationResult::kOK:
|
||||
NExtract::NOperationResult::kDataError));
|
||||
m_FileIsOpen = false;
|
||||
}
|
||||
if (realProcessed > 0)
|
||||
@@ -398,11 +398,11 @@ HRESULT CChmFolderOutStream::FlushCorrupted(UInt64 maxSize)
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
||||
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
Int32 testModeSpec, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
bool allFilesMode = (numItems == (UInt32)-1);
|
||||
|
||||
if (allFilesMode)
|
||||
numItems = m_Database.NewFormat ? 1:
|
||||
@@ -411,7 +411,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
m_Database.Indices.Size());
|
||||
if (numItems == 0)
|
||||
return S_OK;
|
||||
bool testMode = (_aTestMode != 0);
|
||||
bool testMode = (testModeSpec != 0);
|
||||
|
||||
UInt64 currentTotalSize = 0;
|
||||
|
||||
@@ -447,8 +447,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
RINOK(lps->SetCur());
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode= testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract;
|
||||
Int32 index = allFilesMode ? i : indices[i];
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
|
||||
@@ -456,32 +456,32 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
{
|
||||
if (index != 0)
|
||||
return E_FAIL;
|
||||
if (!testMode && (!realOutStream))
|
||||
if (!testMode && !realOutStream)
|
||||
continue;
|
||||
if (!testMode)
|
||||
{
|
||||
UInt32 size = m_Database.NewFormatString.Length();
|
||||
RINOK(WriteStream(realOutStream, (const char *)m_Database.NewFormatString, size));
|
||||
}
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||
continue;
|
||||
}
|
||||
const CItem &item = m_Database.Items[index];
|
||||
|
||||
currentItemSize = item.Size;
|
||||
|
||||
if (!testMode && (!realOutStream))
|
||||
if (!testMode && !realOutStream)
|
||||
continue;
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
if (item.Section != 0)
|
||||
{
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (testMode)
|
||||
{
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -491,8 +491,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ?
|
||||
NArchive::NExtract::NOperationResult::kOK:
|
||||
NArchive::NExtract::NOperationResult::kDataError));
|
||||
NExtract::NOperationResult::kOK:
|
||||
NExtract::NOperationResult::kDataError));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
@@ -543,15 +543,15 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
const CItem &item = m_Database.Items[entryIndex];
|
||||
UInt64 sectionIndex = item.Section;
|
||||
Int32 askMode= testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract;
|
||||
if (item.IsDir())
|
||||
{
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -562,17 +562,17 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
{
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
if (!testMode && (!realOutStream))
|
||||
if (!testMode && !realOutStream)
|
||||
continue;
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
Int32 opRes = NArchive::NExtract::NOperationResult::kOK;
|
||||
Int32 opRes = NExtract::NOperationResult::kOK;
|
||||
if (!testMode && item.Size != 0)
|
||||
{
|
||||
RINOK(m_Stream->Seek(m_Database.ContentOffset + item.Offset, STREAM_SEEK_SET, NULL));
|
||||
streamSpec->Init(item.Size);
|
||||
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
|
||||
if (copyCoderSpec->TotalSize != item.Size)
|
||||
opRes = NArchive::NExtract::NOperationResult::kDataError;
|
||||
opRes = NExtract::NOperationResult::kDataError;
|
||||
}
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(opRes));
|
||||
@@ -586,10 +586,10 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
{
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
if(!testMode && (!realOutStream))
|
||||
if (!testMode && !realOutStream)
|
||||
continue;
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -603,7 +603,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
|
||||
chmFolderOutStream->Init(&m_Database, extractCallback, testMode);
|
||||
|
||||
if(lzxDecoderSpec == NULL)
|
||||
if (lzxDecoderSpec == NULL)
|
||||
{
|
||||
lzxDecoderSpec = new NCompress::NLzx::CDecoder;
|
||||
lzxDecoder = lzxDecoderSpec;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "../../Common/RegisterArc.h"
|
||||
|
||||
#include "ChmHandler.h"
|
||||
static IInArchive *CreateArc() { return new NArchive::NChm::CHandler; }
|
||||
static IInArchive *CreateArc() { return new NArchive::NChm::CHandler; }
|
||||
|
||||
static CArcInfo g_ArcInfo =
|
||||
{ L"Chm", L"chm chi chq chw hxs hxi hxr hxq hxw lit", 0, 0xE9, { 'I', 'T', 'S', 'F' }, 4, false, CreateArc, 0 };
|
||||
|
||||
@@ -95,12 +95,11 @@ STDMETHODIMP CHandler::Close()
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
||||
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool testMode = (_aTestMode != 0);
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
bool allFilesMode = (numItems == (UInt32)-1);
|
||||
if (allFilesMode)
|
||||
numItems = _db.Refs.Size();
|
||||
if (numItems == 0)
|
||||
@@ -135,30 +134,30 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
|
||||
CMyComPtr<ISequentialOutStream> outStream;
|
||||
Int32 askMode = testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract;
|
||||
RINOK(extractCallback->GetStream(index, &outStream, askMode));
|
||||
|
||||
if (item.IsDir())
|
||||
{
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||
continue;
|
||||
}
|
||||
|
||||
totalPackSize += _db.GetItemPackSize(item.Size);
|
||||
totalSize += item.Size;
|
||||
|
||||
if (!testMode && (!outStream))
|
||||
if (!testMode && !outStream)
|
||||
continue;
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
Int32 res = NArchive::NExtract::NOperationResult::kDataError;
|
||||
Int32 res = NExtract::NOperationResult::kDataError;
|
||||
CMyComPtr<ISequentialInStream> inStream;
|
||||
HRESULT hres = GetStream(index, &inStream);
|
||||
if (hres == S_FALSE)
|
||||
res = NArchive::NExtract::NOperationResult::kDataError;
|
||||
res = NExtract::NOperationResult::kDataError;
|
||||
else if (hres == E_NOTIMPL)
|
||||
res = NArchive::NExtract::NOperationResult::kUnSupportedMethod;
|
||||
res = NExtract::NOperationResult::kUnSupportedMethod;
|
||||
else
|
||||
{
|
||||
RINOK(hres);
|
||||
@@ -166,7 +165,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
{
|
||||
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
|
||||
if (copyCoderSpec->TotalSize == item.Size)
|
||||
res = NArchive::NExtract::NOperationResult::kOK;
|
||||
res = NExtract::NOperationResult::kOK;
|
||||
}
|
||||
}
|
||||
outStream.Release();
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
#include "../../Common/RegisterArc.h"
|
||||
|
||||
#include "ComHandler.h"
|
||||
static IInArchive *CreateArc() { return new NArchive::NCom::CHandler; }
|
||||
static IInArchive *CreateArc() { return new NArchive::NCom::CHandler; }
|
||||
|
||||
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)
|
||||
|
||||
@@ -39,7 +39,7 @@ bool HasTailSlash(const AString &name, UINT codePage)
|
||||
if (name.IsEmpty())
|
||||
return false;
|
||||
LPCSTR prev =
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
CharPrevExA((WORD)codePage, name, &name[name.Length()], 0);
|
||||
#else
|
||||
(LPCSTR)(name) + (name.Length() - 1);
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace NFileHeader
|
||||
char ChkSum[8]; // 0 for "new" portable format; for CRC format the sum of all the bytes in the file
|
||||
bool CheckMagic() const
|
||||
{ return memcmp(Magic, NMagic::kMagic1, 6) == 0 ||
|
||||
memcmp(Magic, NMagic::kMagic2, 6) == 0; };
|
||||
memcmp(Magic, NMagic::kMagic2, 6) == 0; };
|
||||
};
|
||||
*/
|
||||
|
||||
@@ -540,12 +540,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
||||
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool testMode = (_aTestMode != 0);
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
bool allFilesMode = (numItems == (UInt32)-1);
|
||||
if (allFilesMode)
|
||||
numItems = _items.Size();
|
||||
if (numItems == 0)
|
||||
@@ -575,8 +574,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
RINOK(lps->SetCur());
|
||||
CMyComPtr<ISequentialOutStream> outStream;
|
||||
Int32 askMode = testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract;
|
||||
Int32 index = allFilesMode ? i : indices[i];
|
||||
const CItemEx &item = _items[index];
|
||||
RINOK(extractCallback->GetStream(index, &outStream, askMode));
|
||||
@@ -584,7 +583,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
if (item.IsDir())
|
||||
{
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||
continue;
|
||||
}
|
||||
if (!testMode && !outStream)
|
||||
@@ -592,7 +591,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
if (testMode)
|
||||
{
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||
continue;
|
||||
}
|
||||
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));
|
||||
outStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ?
|
||||
NArchive::NExtract::NOperationResult::kOK:
|
||||
NArchive::NExtract::NOperationResult::kDataError));
|
||||
NExtract::NOperationResult::kOK:
|
||||
NExtract::NOperationResult::kDataError));
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
@@ -615,7 +614,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
static IInArchive *CreateArc() { return new NArchive::NCpio::CHandler; }
|
||||
static IInArchive *CreateArc() { return new NArchive::NCpio::CHandler; }
|
||||
|
||||
static CArcInfo g_ArcInfo =
|
||||
{ L"Cpio", L"cpio", 0, 0xED, { 0 }, 0, false, CreateArc, 0 };
|
||||
|
||||
@@ -236,7 +236,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
COM_TRY_BEGIN
|
||||
{
|
||||
CInArchive archive;
|
||||
if(archive.Open(stream) != S_OK)
|
||||
if (archive.Open(stream) != S_OK)
|
||||
return S_FALSE;
|
||||
_items.Clear();
|
||||
|
||||
@@ -314,12 +314,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
||||
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool testMode = (_aTestMode != 0);
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
bool allFilesMode = (numItems == (UInt32)-1);
|
||||
if (allFilesMode)
|
||||
numItems = _items.Size();
|
||||
if (numItems == 0)
|
||||
@@ -349,19 +348,19 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
RINOK(lps->SetCur());
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode = testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract;
|
||||
Int32 index = allFilesMode ? i : indices[i];
|
||||
const CItem &item = _items[index];
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
currentTotalSize += item.Size;
|
||||
|
||||
if (!testMode && (!realOutStream))
|
||||
if (!testMode && !realOutStream)
|
||||
continue;
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
if (testMode)
|
||||
{
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||
continue;
|
||||
}
|
||||
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));
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ?
|
||||
NArchive::NExtract::NOperationResult::kOK:
|
||||
NArchive::NExtract::NOperationResult::kDataError));
|
||||
NExtract::NOperationResult::kOK:
|
||||
NExtract::NOperationResult::kDataError));
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
@@ -384,7 +383,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
static IInArchive *CreateArc() { return new NArchive::NDeb::CHandler; }
|
||||
static IInArchive *CreateArc() { return new NArchive::NDeb::CHandler; }
|
||||
|
||||
static CArcInfo g_ArcInfo =
|
||||
{ L"Deb", L"deb", 0, 0xEC, { '!', '<', 'a', 'r', 'c', 'h', '>', '\n' }, 8, false, CreateArc, 0 };
|
||||
|
||||
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/ComTry.h"
|
||||
#include "../../Common/Types.h"
|
||||
|
||||
#include "../../Windows/NtCheck.h"
|
||||
#include "../../Windows/PropVariant.h"
|
||||
|
||||
#include "IArchive.h"
|
||||
@@ -12,17 +14,8 @@
|
||||
#include "../IPassword.h"
|
||||
|
||||
HINSTANCE g_hInstance;
|
||||
#ifndef _UNICODE
|
||||
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
|
||||
|
||||
#define NT_CHECK_FAIL_ACTION return FALSE;
|
||||
|
||||
extern "C"
|
||||
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)
|
||||
{
|
||||
g_hInstance = hInstance;
|
||||
#ifndef _UNICODE
|
||||
g_IsNT = IsItWindowsNT();
|
||||
#endif
|
||||
NT_CHECK;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -3,43 +3,38 @@
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../Common/MyInitGuid.h"
|
||||
#include "../../Common/ComTry.h"
|
||||
#include "../../Common/Types.h"
|
||||
#include "../../Windows/PropVariant.h"
|
||||
|
||||
#if defined(_WIN32) && defined(_7ZIP_LARGE_PAGES)
|
||||
#include "../../../C/Alloc.h"
|
||||
#endif
|
||||
|
||||
#include "IArchive.h"
|
||||
#include "../../Common/ComTry.h"
|
||||
|
||||
#include "../../Windows/NtCheck.h"
|
||||
#include "../../Windows/PropVariant.h"
|
||||
|
||||
#include "../ICoder.h"
|
||||
#include "../IPassword.h"
|
||||
|
||||
#include "IArchive.h"
|
||||
|
||||
HINSTANCE g_hInstance;
|
||||
#ifndef _UNICODE
|
||||
#ifdef _WIN32
|
||||
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
|
||||
|
||||
#define NT_CHECK_FAIL_ACTION return FALSE;
|
||||
|
||||
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)
|
||||
{
|
||||
g_hInstance = hInstance;
|
||||
#ifndef _UNICODE
|
||||
#ifdef _WIN32
|
||||
g_IsNT = IsItWindowsNT();
|
||||
#endif
|
||||
#endif
|
||||
g_hInstance = (HINSTANCE)hInstance;
|
||||
NT_CHECK;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -573,12 +573,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
||||
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool testMode = (_aTestMode != 0);
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
bool allFilesMode = (numItems == (UInt32)-1);
|
||||
if (allFilesMode)
|
||||
numItems = _files.Size();
|
||||
if (numItems == 0)
|
||||
@@ -635,14 +634,14 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
RINOK(lps->SetCur());
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode = testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract;
|
||||
Int32 index = allFilesMode ? i : indices[i];
|
||||
// const CItemEx &item = _files[index];
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
|
||||
|
||||
if (!testMode && (!realOutStream))
|
||||
if (!testMode && !realOutStream)
|
||||
continue;
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
|
||||
@@ -652,7 +651,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
|
||||
realOutStream.Release();
|
||||
|
||||
Int32 opRes = NArchive::NExtract::NOperationResult::kOK;
|
||||
Int32 opRes = NExtract::NOperationResult::kOK;
|
||||
#ifdef DMG_SHOW_RAW
|
||||
if (index > _fileIndices.Size())
|
||||
{
|
||||
@@ -688,7 +687,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
packPos += block.PackSize;
|
||||
if (block.UnpPos != unpPos)
|
||||
{
|
||||
opRes = NArchive::NExtract::NOperationResult::kDataError;
|
||||
opRes = NExtract::NOperationResult::kDataError;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -705,13 +704,13 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
case METHOD_ZERO_2:
|
||||
realMethod = false;
|
||||
if (block.PackSize != 0)
|
||||
opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod;
|
||||
opRes = NExtract::NOperationResult::kUnSupportedMethod;
|
||||
break;
|
||||
|
||||
case METHOD_COPY:
|
||||
if (block.UnpSize != block.PackSize)
|
||||
{
|
||||
opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod;
|
||||
opRes = NExtract::NOperationResult::kUnSupportedMethod;
|
||||
break;
|
||||
}
|
||||
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);
|
||||
if (res == S_OK)
|
||||
if (streamSpec->GetSize() != block.PackSize)
|
||||
opRes = NArchive::NExtract::NOperationResult::kDataError;
|
||||
opRes = NExtract::NOperationResult::kDataError;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod;
|
||||
opRes = NExtract::NOperationResult::kUnSupportedMethod;
|
||||
break;
|
||||
}
|
||||
if (res != S_OK)
|
||||
{
|
||||
if (res != S_FALSE)
|
||||
return res;
|
||||
if (opRes == NArchive::NExtract::NOperationResult::kOK)
|
||||
opRes = NArchive::NExtract::NOperationResult::kDataError;
|
||||
if (opRes == NExtract::NOperationResult::kOK)
|
||||
opRes = NExtract::NOperationResult::kDataError;
|
||||
}
|
||||
unpPos += block.UnpSize;
|
||||
if (!outStreamSpec->IsFinishedOK())
|
||||
{
|
||||
if (realMethod && opRes == NArchive::NExtract::NOperationResult::kOK)
|
||||
opRes = NArchive::NExtract::NOperationResult::kDataError;
|
||||
if (realMethod && opRes == NExtract::NOperationResult::kOK)
|
||||
opRes = NExtract::NOperationResult::kDataError;
|
||||
|
||||
while (outStreamSpec->GetRem() != 0)
|
||||
{
|
||||
|
||||
@@ -466,12 +466,11 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
||||
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool testMode = (_aTestMode != 0);
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
bool allFilesMode = (numItems == (UInt32)-1);
|
||||
if (allFilesMode)
|
||||
numItems = _sections.Size();
|
||||
if (numItems == 0)
|
||||
@@ -501,8 +500,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
lps->InSize = lps->OutSize = currentTotalSize;
|
||||
RINOK(lps->SetCur());
|
||||
Int32 askMode = testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract;
|
||||
UInt32 index = allFilesMode ? i : indices[i];
|
||||
const CSegment &item = _sections[index];
|
||||
currentItemSize = item.PSize;
|
||||
@@ -518,8 +517,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
|
||||
outStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(copyCoderSpec->TotalSize == currentItemSize ?
|
||||
NArchive::NExtract::NOperationResult::kOK:
|
||||
NArchive::NExtract::NOperationResult::kDataError));
|
||||
NExtract::NOperationResult::kOK:
|
||||
NExtract::NOperationResult::kDataError));
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
|
||||
@@ -456,8 +456,11 @@ HRESULT CDatabase::ReadDir(Int32 parent, UInt32 cluster, int level)
|
||||
const Byte *p = ByteBuf + pos;
|
||||
if (p[0] == 0)
|
||||
{
|
||||
/*
|
||||
// FreeDOS formats FAT partition with cluster chain longer than required.
|
||||
if (clusterMode && !Header.IsEoc(cluster))
|
||||
return S_FALSE;
|
||||
*/
|
||||
break;
|
||||
}
|
||||
if (p[0] == 0xE5)
|
||||
@@ -883,12 +886,11 @@ STDMETHODIMP CHandler::Close()
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
||||
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool testMode = (_aTestMode != 0);
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
bool allFilesMode = (numItems == (UInt32)-1);
|
||||
if (allFilesMode)
|
||||
numItems = Items.Size();
|
||||
if (numItems == 0)
|
||||
@@ -923,8 +925,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
RINOK(lps->SetCur());
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode = testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract;
|
||||
Int32 index = allFilesMode ? i : indices[i];
|
||||
const CItem &item = Items[index];
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
@@ -932,14 +934,14 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
if (item.IsDir())
|
||||
{
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||
continue;
|
||||
}
|
||||
|
||||
totalPackSize += Header.GetFilePackSize(item.Size);
|
||||
totalSize += item.Size;
|
||||
|
||||
if (!testMode && (!realOutStream))
|
||||
if (!testMode && !realOutStream)
|
||||
continue;
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
|
||||
@@ -947,7 +949,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
realOutStream.Release();
|
||||
outStreamSpec->Init();
|
||||
|
||||
int res = NArchive::NExtract::NOperationResult::kDataError;
|
||||
int res = NExtract::NOperationResult::kDataError;
|
||||
CMyComPtr<ISequentialInStream> inStream;
|
||||
HRESULT hres = GetStream(index, &inStream);
|
||||
if (hres != S_FALSE)
|
||||
@@ -957,7 +959,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
{
|
||||
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
|
||||
if (copyCoderSpec->TotalSize == item.Size)
|
||||
res = NArchive::NExtract::NOperationResult::kOK;
|
||||
res = NExtract::NOperationResult::kOK;
|
||||
}
|
||||
}
|
||||
outStreamSpec->ReleaseStream();
|
||||
@@ -973,7 +975,7 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static IInArchive *CreateArc() { return new CHandler; }
|
||||
static IInArchive *CreateArc() { return new CHandler; }
|
||||
|
||||
static CArcInfo g_ArcInfo =
|
||||
{ L"FAT", L"fat img", 0, 0xDA, { 0x55, 0xAA }, 2, false, CreateArc, 0 };
|
||||
|
||||
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/OutStreamWithCRC.h"
|
||||
#include "Common/ParseProperties.h"
|
||||
|
||||
#include "DeflateProps.h"
|
||||
|
||||
#define Get32(p) GetUi32(p)
|
||||
|
||||
@@ -288,54 +289,6 @@ HRESULT CItem::WriteFooter(ISequentialOutStream *stream)
|
||||
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:
|
||||
public IInArchive,
|
||||
public IArchiveOpenSeq,
|
||||
@@ -352,14 +305,7 @@ class CHandler:
|
||||
CMyComPtr<ICompressCoder> _decoder;
|
||||
NCompress::NDeflate::NDecoder::CCOMCoder *_decoderSpec;
|
||||
|
||||
CCompressMode _method;
|
||||
UInt32 _level;
|
||||
|
||||
void InitMethodProperties()
|
||||
{
|
||||
_level = 0xFFFFFFFF;
|
||||
_method.Init();
|
||||
}
|
||||
CDeflateProps _method;
|
||||
|
||||
public:
|
||||
MY_UNKNOWN_IMP4(IInArchive, IArchiveOpenSeq, IOutArchive, ISetProperties)
|
||||
@@ -370,7 +316,6 @@ public:
|
||||
|
||||
CHandler()
|
||||
{
|
||||
InitMethodProperties();
|
||||
_decoderSpec = new NCompress::NDeflate::NDecoder::CCOMCoder;
|
||||
_decoder = _decoderSpec;
|
||||
}
|
||||
@@ -496,28 +441,23 @@ STDMETHODIMP CHandler::Close()
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
||||
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool allFilesMode = (numItems == (UInt32)-1);
|
||||
if (!allFilesMode)
|
||||
{
|
||||
if (numItems == 0)
|
||||
return S_OK;
|
||||
if (numItems != 1 || indices[0] != 0)
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
if (numItems == 0)
|
||||
return S_OK;
|
||||
if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0))
|
||||
return E_INVALIDARG;
|
||||
|
||||
bool testMode = (_aTestMode != 0);
|
||||
if (_stream)
|
||||
extractCallback->SetTotal(_packSize);
|
||||
UInt64 currentTotalPacked = 0;
|
||||
RINOK(extractCallback->SetCompleted(¤tTotalPacked));
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode = testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract;
|
||||
RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
|
||||
if (!testMode && !realOutStream)
|
||||
return S_OK;
|
||||
@@ -557,8 +497,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
if (result != S_FALSE)
|
||||
return result;
|
||||
opRes = firstItem ?
|
||||
NArchive::NExtract::NOperationResult::kDataError :
|
||||
NArchive::NExtract::NOperationResult::kOK;
|
||||
NExtract::NOperationResult::kDataError :
|
||||
NExtract::NOperationResult::kOK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -572,20 +512,20 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
{
|
||||
if (result != S_FALSE)
|
||||
return result;
|
||||
opRes = NArchive::NExtract::NOperationResult::kDataError;
|
||||
opRes = NExtract::NOperationResult::kDataError;
|
||||
break;
|
||||
}
|
||||
|
||||
_decoderSpec->AlignToByte();
|
||||
if (item.ReadFooter1(_decoderSpec) != S_OK)
|
||||
{
|
||||
opRes = NArchive::NExtract::NOperationResult::kDataError;
|
||||
opRes = NExtract::NOperationResult::kDataError;
|
||||
break;
|
||||
}
|
||||
if (item.Crc != outStreamSpec->GetCRC() ||
|
||||
item.Size32 != (UInt32)(outStreamSpec->GetSize() - startOffset))
|
||||
{
|
||||
opRes = NArchive::NExtract::NOperationResult::kCRCError;
|
||||
opRes = NExtract::NOperationResult::kCRCError;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -605,7 +545,7 @@ static HRESULT UpdateArchive(
|
||||
ISequentialOutStream *outStream,
|
||||
UInt64 unpackSize,
|
||||
const CItem &newItem,
|
||||
const CCompressMode &compressionMode,
|
||||
CDeflateProps &deflateProps,
|
||||
IArchiveUpdateCallback *updateCallback)
|
||||
{
|
||||
UInt64 complexity = 0;
|
||||
@@ -627,7 +567,7 @@ static HRESULT UpdateArchive(
|
||||
|
||||
CItem item = newItem;
|
||||
item.Method = NHeader::NCompressionMethod::kDeflate;
|
||||
item.ExtraFlags = compressionMode.IsMaximum() ?
|
||||
item.ExtraFlags = deflateProps.IsMaximum() ?
|
||||
NHeader::NExtraFlags::kMaximum :
|
||||
NHeader::NExtraFlags::kFastest;
|
||||
|
||||
@@ -637,26 +577,7 @@ static HRESULT UpdateArchive(
|
||||
|
||||
NCompress::NDeflate::NEncoder::CCOMCoder *deflateEncoderSpec = new NCompress::NDeflate::NEncoder::CCOMCoder;
|
||||
CMyComPtr<ICompressCoder> deflateEncoder = 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(deflateProps.SetCoderProperties(deflateEncoderSpec));
|
||||
RINOK(deflateEncoder->Code(crcStream, outStream, NULL, NULL, progress));
|
||||
|
||||
item.Crc = inStreamSpec->GetCRC();
|
||||
@@ -738,7 +659,6 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
size = prop.uhVal.QuadPart;
|
||||
}
|
||||
|
||||
_method.Normalize(_level);
|
||||
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)
|
||||
{
|
||||
InitMethodProperties();
|
||||
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;
|
||||
return _method.SetProperties(names, values, numProps);
|
||||
}
|
||||
|
||||
static IInArchive *CreateArc() { return new CHandler; }
|
||||
@@ -813,7 +691,7 @@ static IOutArchive *CreateArcOut() { return new CHandler; }
|
||||
#endif
|
||||
|
||||
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)
|
||||
|
||||
|
||||
@@ -137,12 +137,11 @@ STDMETHODIMP CHandler::Close()
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
||||
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool testMode = (_aTestMode != 0);
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
bool allFilesMode = (numItems == (UInt32)-1);
|
||||
if (allFilesMode)
|
||||
numItems = _db.Items.Size();
|
||||
if (numItems == 0)
|
||||
@@ -174,27 +173,27 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode = testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract;
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
|
||||
if (item.IsDir())
|
||||
{
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||
continue;
|
||||
}
|
||||
if (!testMode && (!realOutStream))
|
||||
if (!testMode && !realOutStream)
|
||||
continue;
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
UInt64 pos = 0;
|
||||
int res = NArchive::NExtract::NOperationResult::kOK;
|
||||
int res = NExtract::NOperationResult::kOK;
|
||||
int i;
|
||||
for (i = 0; i < item.Extents.Size(); i++)
|
||||
{
|
||||
if (item.Size == pos)
|
||||
break;
|
||||
if (res != NArchive::NExtract::NOperationResult::kOK)
|
||||
if (res != NExtract::NOperationResult::kOK)
|
||||
break;
|
||||
const CExtent &e = item.Extents[i];
|
||||
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 (extentSize >= (UInt64)((UInt32)1 << _db.Header.BlockSizeLog))
|
||||
res = NArchive::NExtract::NOperationResult::kDataError;
|
||||
res = NExtract::NOperationResult::kDataError;
|
||||
break;
|
||||
}
|
||||
UInt32 curSize = kBufSize;
|
||||
@@ -227,7 +226,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
}
|
||||
}
|
||||
if (i != item.Extents.Size() || item.Size != pos)
|
||||
res = NArchive::NExtract::NOperationResult::kDataError;
|
||||
res = NExtract::NOperationResult::kDataError;
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(res));
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "../../Common/RegisterArc.h"
|
||||
|
||||
#include "HfsHandler.h"
|
||||
static IInArchive *CreateArc() { return new NArchive::NHfs::CHandler; }
|
||||
static IInArchive *CreateArc() { return new NArchive::NHfs::CHandler; }
|
||||
|
||||
static CArcInfo g_ArcInfo =
|
||||
{ L"HFS", L"hfs", 0, 0xE3, { 'H', '+', 0, 4 }, 4, false, CreateArc, 0 };
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
||||
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool testMode = (_aTestMode != 0);
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
bool allFilesMode = (numItems == (UInt32)-1);
|
||||
if (allFilesMode)
|
||||
numItems = _archive.Refs.Size();
|
||||
if (numItems == 0)
|
||||
@@ -203,8 +202,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
RINOK(lps->SetCur());
|
||||
currentItemSize = 0;
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode;
|
||||
askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract;
|
||||
Int32 askMode = testMode ?
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract;
|
||||
UInt32 index = allFilesMode ? i : indices[i];
|
||||
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
@@ -217,7 +217,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
if (item.IsDir())
|
||||
{
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||
continue;
|
||||
}
|
||||
currentItemSize = item.DataLength;
|
||||
@@ -231,7 +231,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
blockIndex = be.LoadRBA;
|
||||
}
|
||||
|
||||
if (!testMode && (!realOutStream))
|
||||
if (!testMode && !realOutStream)
|
||||
continue;
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
outStreamSpec->SetStream(realOutStream);
|
||||
@@ -242,8 +242,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
|
||||
outStreamSpec->ReleaseStream();
|
||||
RINOK(extractCallback->SetOperationResult(outStreamSpec->IsFinishedOK() ?
|
||||
NArchive::NExtract::NOperationResult::kOK:
|
||||
NArchive::NExtract::NOperationResult::kDataError));
|
||||
NExtract::NOperationResult::kOK:
|
||||
NExtract::NOperationResult::kDataError));
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "../../Common/RegisterArc.h"
|
||||
|
||||
#include "IsoHandler.h"
|
||||
static IInArchive *CreateArc() { return new NArchive::NIso::CHandler; }
|
||||
static IInArchive *CreateArc() { return new NArchive::NIso::CHandler; }
|
||||
|
||||
static CArcInfo g_ArcInfo =
|
||||
{ L"Iso", L"iso", 0, 0xE7, { 'C', 'D', '0', '0', '1', 0x1 }, 7, false, CreateArc, 0 };
|
||||
|
||||
@@ -168,13 +168,11 @@ struct CItem
|
||||
AString GetName() const
|
||||
{
|
||||
AString dirName = GetDirName();
|
||||
dirName.Replace((char)(unsigned char)0xFF, '\\');
|
||||
if (!dirName.IsEmpty())
|
||||
{
|
||||
char c = dirName[dirName.Length() - 1];
|
||||
if (c != '\\')
|
||||
dirName += '\\';
|
||||
}
|
||||
const char kDirSeparator = '\\';
|
||||
// check kDirSeparator in Linux
|
||||
dirName.Replace((char)(unsigned char)0xFF, kDirSeparator);
|
||||
if (!dirName.IsEmpty() && dirName.Back() != kDirSeparator)
|
||||
dirName += kDirSeparator;
|
||||
return dirName + GetFileName();
|
||||
}
|
||||
};
|
||||
@@ -469,7 +467,7 @@ STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *pro
|
||||
{
|
||||
UInt32 realProcessedSize;
|
||||
HRESULT result;
|
||||
if(!_stream)
|
||||
if (!_stream)
|
||||
{
|
||||
realProcessedSize = size;
|
||||
result = S_OK;
|
||||
@@ -477,7 +475,7 @@ STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *pro
|
||||
else
|
||||
result = _stream->Write(data, size, &realProcessedSize);
|
||||
_crc.Update(data, realProcessedSize);
|
||||
if(processedSize != NULL)
|
||||
if (processedSize != NULL)
|
||||
*processedSize = realProcessedSize;
|
||||
return result;
|
||||
}
|
||||
@@ -630,24 +628,19 @@ STDMETHODIMP CHandler::Close()
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////
|
||||
// CHandler::DecompressItems
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
Int32 testModeSpec, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool testMode = (testModeSpec != 0);
|
||||
UInt64 totalUnPacked = 0, totalPacked = 0;
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
bool allFilesMode = (numItems == (UInt32)-1);
|
||||
if (allFilesMode)
|
||||
numItems = _items.Size();
|
||||
if(numItems == 0)
|
||||
if (numItems == 0)
|
||||
return S_OK;
|
||||
UInt32 i;
|
||||
for(i = 0; i < numItems; i++)
|
||||
for (i = 0; i < numItems; i++)
|
||||
{
|
||||
const CItemEx &item = _items[allFilesMode ? i : indices[i]];
|
||||
totalUnPacked += item.Size;
|
||||
@@ -674,7 +667,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
CMyComPtr<ISequentialInStream> inStream(streamSpec);
|
||||
streamSpec->SetStream(_stream);
|
||||
|
||||
for(i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked,
|
||||
for (i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked,
|
||||
currentTotalPacked += currentItemPacked)
|
||||
{
|
||||
currentItemUnPacked = 0;
|
||||
@@ -702,7 +695,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!testMode && (!realOutStream))
|
||||
if (!testMode && !realOutStream)
|
||||
continue;
|
||||
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
@@ -773,7 +766,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
static IInArchive *CreateArc() { return new CHandler; }
|
||||
static IInArchive *CreateArc() { return new CHandler; }
|
||||
|
||||
static CArcInfo g_ArcInfo =
|
||||
{ L"Lzh", L"lzh lha", 0, 6, { '-', 'l' }, 2, false, CreateArc, 0 };
|
||||
|
||||
@@ -319,28 +319,23 @@ STDMETHODIMP CHandler::Close()
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
||||
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool allFilesMode = (numItems == (UInt32)-1);
|
||||
if (!allFilesMode)
|
||||
{
|
||||
if (numItems == 0)
|
||||
return S_OK;
|
||||
if (numItems != 1 || indices[0] != 0)
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
if (numItems == 0)
|
||||
return S_OK;
|
||||
if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0))
|
||||
return E_INVALIDARG;
|
||||
|
||||
bool testMode = (_aTestMode != 0);
|
||||
if (_stream)
|
||||
extractCallback->SetTotal(_packSize);
|
||||
|
||||
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode = testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract;
|
||||
RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
|
||||
if (!testMode && !realOutStream)
|
||||
return S_OK;
|
||||
@@ -368,7 +363,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
_lzma86, _seqStream);
|
||||
RINOK(result);
|
||||
|
||||
Int32 opRes = NArchive::NExtract::NOperationResult::kOK;
|
||||
Int32 opRes = NExtract::NOperationResult::kOK;
|
||||
bool firstItem = true;
|
||||
|
||||
for (;;)
|
||||
@@ -395,12 +390,12 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
result = decoder.Code(st, outStream, progress);
|
||||
if (result == E_NOTIMPL)
|
||||
{
|
||||
opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod;
|
||||
opRes = NExtract::NOperationResult::kUnSupportedMethod;
|
||||
break;
|
||||
}
|
||||
if (result == S_FALSE)
|
||||
{
|
||||
opRes = NArchive::NExtract::NOperationResult::kDataError;
|
||||
opRes = NExtract::NOperationResult::kDataError;
|
||||
break;
|
||||
}
|
||||
RINOK(result);
|
||||
|
||||
@@ -399,12 +399,11 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
||||
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool testMode = (_aTestMode != 0);
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
bool allFilesMode = (numItems == (UInt32)-1);
|
||||
if (allFilesMode)
|
||||
numItems = _sections.Size();
|
||||
if (numItems == 0)
|
||||
@@ -434,8 +433,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
lps->InSize = lps->OutSize = currentTotalSize;
|
||||
RINOK(lps->SetCur());
|
||||
Int32 askMode = testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract;
|
||||
UInt32 index = allFilesMode ? i : indices[i];
|
||||
const CSection &item = _sections[index];
|
||||
currentItemSize = item.GetPackSize();
|
||||
@@ -451,8 +450,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
|
||||
outStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(copyCoderSpec->TotalSize == currentItemSize ?
|
||||
NArchive::NExtract::NOperationResult::kOK:
|
||||
NArchive::NExtract::NOperationResult::kDataError));
|
||||
NExtract::NOperationResult::kOK:
|
||||
NExtract::NOperationResult::kDataError));
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
|
||||
@@ -431,12 +431,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
||||
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool testMode = (_aTestMode != 0);
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
bool allFilesMode = (numItems == (UInt32)-1);
|
||||
if (allFilesMode)
|
||||
numItems = _items.Size();
|
||||
if (numItems == 0)
|
||||
@@ -467,14 +466,14 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
RINOK(lps->SetCur());
|
||||
CMyComPtr<ISequentialOutStream> outStream;
|
||||
Int32 askMode = testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract;
|
||||
Int32 index = allFilesMode ? i : indices[i];
|
||||
const CItem &item = _items[index];
|
||||
const CPartition &part = item.Part;
|
||||
RINOK(extractCallback->GetStream(index, &outStream, askMode));
|
||||
totalSize += item.Size;
|
||||
if (!testMode && (!outStream))
|
||||
if (!testMode && !outStream)
|
||||
continue;
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
|
||||
@@ -483,8 +482,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
|
||||
outStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(copyCoderSpec->TotalSize == item.Size ?
|
||||
NArchive::NExtract::NOperationResult::kOK:
|
||||
NArchive::NExtract::NOperationResult::kDataError));
|
||||
NExtract::NOperationResult::kOK:
|
||||
NExtract::NOperationResult::kDataError));
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
@@ -498,7 +497,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
static IInArchive *CreateArc() { return new CHandler; }
|
||||
static IInArchive *CreateArc() { return new CHandler; }
|
||||
|
||||
static CArcInfo g_ArcInfo =
|
||||
{ L"MBR", L"mbr", 0, 0xDB, { 1, 1, 0 }, 3, false, CreateArc, 0 };
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
||||
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool testMode = (_aTestMode != 0);
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
bool allFilesMode = (numItems == (UInt32)-1);
|
||||
if (allFilesMode)
|
||||
numItems = _numItems;
|
||||
if (numItems == 0)
|
||||
@@ -222,19 +221,19 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
RINOK(lps->SetCur());
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode = testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract;
|
||||
UInt32 index = allFilesMode ? i : indices[i];
|
||||
const CItem &item = _items[index];
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
currentTotalSize += item.Size;
|
||||
|
||||
if (!testMode && (!realOutStream))
|
||||
if (!testMode && !realOutStream)
|
||||
continue;
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
if (testMode)
|
||||
{
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||
continue;
|
||||
}
|
||||
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));
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ?
|
||||
NArchive::NExtract::NOperationResult::kOK:
|
||||
NArchive::NExtract::NOperationResult::kDataError));
|
||||
NExtract::NOperationResult::kOK:
|
||||
NExtract::NOperationResult::kDataError));
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
|
||||
@@ -263,12 +263,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
||||
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool testMode = (_aTestMode != 0);
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
bool allFilesMode = (numItems == (UInt32)-1);
|
||||
if (allFilesMode)
|
||||
GetNumberOfItems(&numItems);
|
||||
if(numItems == 0)
|
||||
@@ -326,8 +325,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
currentItemSize = 0;
|
||||
RINOK(extractCallback->SetCompleted(¤tTotalSize));
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode;
|
||||
askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract;
|
||||
Int32 askMode = testMode ?
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract;
|
||||
UInt32 index = allFilesMode ? i : indices[i];
|
||||
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
@@ -336,7 +336,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
if (index >= (UInt32)_archive.Items.Size())
|
||||
{
|
||||
currentItemSize = _archive.Script.Length();
|
||||
if(!testMode && (!realOutStream))
|
||||
if(!testMode && !realOutStream)
|
||||
continue;
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
if (!testMode)
|
||||
@@ -352,7 +352,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
else
|
||||
GetCompressedSize(index, currentItemSize);
|
||||
|
||||
if(!testMode && (!realOutStream))
|
||||
if(!testMode && !realOutStream)
|
||||
continue;
|
||||
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
@@ -477,8 +477,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
}
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(dataError ?
|
||||
NArchive::NExtract::NOperationResult::kDataError :
|
||||
NArchive::NExtract::NOperationResult::kOK));
|
||||
NExtract::NOperationResult::kDataError :
|
||||
NExtract::NOperationResult::kOK));
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
|
||||
@@ -1,30 +1,21 @@
|
||||
// Archive/NsisIn.cpp
|
||||
// NsisIn.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
// #include <stdio.h>
|
||||
#include "../../../../C/CpuArch.h"
|
||||
|
||||
#include "NsisIn.h"
|
||||
#include "NsisDecode.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
#include "Common/IntToString.h"
|
||||
|
||||
#include "../../Common/StreamUtils.h"
|
||||
|
||||
#include "Common/StringConvert.h"
|
||||
#include "Common/IntToString.h"
|
||||
|
||||
#include "../../../../C/CpuArch.h"
|
||||
#include "NsisIn.h"
|
||||
|
||||
#define Get32(p) GetUi32(p)
|
||||
|
||||
namespace NArchive {
|
||||
namespace NNsis {
|
||||
|
||||
Byte kSignature[kSignatureSize] = { 0xEF + 1, 0xBE, 0xAD, 0xDE,
|
||||
0x4E, 0x75, 0x6C, 0x6C, 0x73, 0x6F, 0x66, 0x74, 0x49, 0x6E, 0x73, 0x74};
|
||||
|
||||
struct CSignatureInit { CSignatureInit() { kSignature[0]--; } } g_SignatureInit;
|
||||
Byte kSignature[kSignatureSize] = NSIS_SIGNATURE;
|
||||
|
||||
#ifdef NSIS_SCRIPT
|
||||
static const char *kCrLf = "\x0D\x0A";
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
// Archive/NsisIn.h
|
||||
// NsisIn.h
|
||||
|
||||
#ifndef __ARCHIVE_NSIS_IN_H
|
||||
#define __ARCHIVE_NSIS_IN_H
|
||||
|
||||
#include "Common/Buffer.h"
|
||||
#include "Common/IntToString.h"
|
||||
#include "Common/MyCom.h"
|
||||
#include "Common/StringConvert.h"
|
||||
|
||||
#include "../../Common/CreateCoder.h"
|
||||
|
||||
#include "../../IStream.h"
|
||||
|
||||
#include "NsisDecode.h"
|
||||
|
||||
// #define NSIS_SCRIPT
|
||||
@@ -20,6 +15,8 @@ namespace NArchive {
|
||||
namespace NNsis {
|
||||
|
||||
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];
|
||||
|
||||
const UInt32 kFlagsMask = 0xF;
|
||||
|
||||
@@ -5,10 +5,9 @@
|
||||
#include "../../Common/RegisterArc.h"
|
||||
|
||||
#include "NsisHandler.h"
|
||||
static IInArchive *CreateArc() { return new NArchive::NNsis::CHandler; }
|
||||
static IInArchive *CreateArc() { return new NArchive::NNsis::CHandler; }
|
||||
|
||||
static CArcInfo g_ArcInfo =
|
||||
{ L"Nsis", 0, 0, 0x9, { 0xEF, 0xBE, 0xAD, 0xDE,
|
||||
0x4E, 0x75, 0x6C, 0x6C, 0x73, 0x6F, 0x66, 0x74, 0x49, 0x6E, 0x73, 0x74}, 16, false, CreateArc, 0 };
|
||||
{ L"Nsis", L"", 0, 0x9, NSIS_SIGNATURE, NArchive::NNsis::kSignatureSize, false, CreateArc, 0 };
|
||||
|
||||
REGISTER_ARC(Nsis)
|
||||
|
||||
@@ -124,7 +124,11 @@ bool CHeader::Parse(const Byte *p)
|
||||
// DriveNumber = p[0x24];
|
||||
if (p[0x25] != 0) // CurrentHead
|
||||
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;
|
||||
if (p[0x27] != 0) // reserved
|
||||
return false;
|
||||
@@ -916,6 +920,9 @@ struct CDataRef
|
||||
int Num;
|
||||
};
|
||||
|
||||
static const UInt32 kMagic_FILE = 0x454c4946;
|
||||
static const UInt32 kMagic_BAAD = 0x44414142;
|
||||
|
||||
struct CMftRec
|
||||
{
|
||||
UInt32 Magic;
|
||||
@@ -934,7 +941,6 @@ struct CMftRec
|
||||
|
||||
CSiAttr SiAttr;
|
||||
|
||||
|
||||
void MoveAttrsFrom(CMftRec &src)
|
||||
{
|
||||
DataAttrs += src.DataAttrs;
|
||||
@@ -954,6 +960,8 @@ struct CMftRec
|
||||
bool Parse(Byte *p, int sectorSizeLog, UInt32 numSectors, UInt32 recNumber, CObjectVector<CAttr> *attrs);
|
||||
|
||||
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 IsDir() const { return (Flags & 2) != 0; }
|
||||
@@ -1032,10 +1040,8 @@ bool CMftRec::Parse(Byte *p, int sectorSizeLog, UInt32 numSectors, UInt32 recNum
|
||||
CObjectVector<CAttr> *attrs)
|
||||
{
|
||||
G32(p, Magic);
|
||||
if (IsEmpty())
|
||||
return true;
|
||||
if (Magic != 0x454c4946)
|
||||
return false;
|
||||
if (!IsFILE())
|
||||
return IsEmpty() || IsBAAD();
|
||||
|
||||
UInt32 usaOffset;
|
||||
UInt32 numUsaItems;
|
||||
@@ -1246,7 +1252,7 @@ HRESULT CDatabase::Open()
|
||||
numSectorsInRec = 1 << (recSizeLog - Header.SectorSizeLog);
|
||||
if (!mftRec.Parse(ByteBuf, Header.SectorSizeLog, numSectorsInRec, NULL, 0))
|
||||
return S_FALSE;
|
||||
if (mftRec.IsEmpty())
|
||||
if (!mftRec.IsFILE())
|
||||
return S_FALSE;
|
||||
mftRec.ParseDataNames();
|
||||
if (mftRec.DataRefs.IsEmpty())
|
||||
@@ -1331,7 +1337,7 @@ HRESULT CDatabase::Open()
|
||||
for (i = 0; i < Recs.Size(); i++)
|
||||
{
|
||||
CMftRec &rec = Recs[i];
|
||||
if (rec.IsEmpty() || !rec.BaseMftRef.IsBaseItself())
|
||||
if (!rec.IsFILE() || !rec.BaseMftRef.IsBaseItself())
|
||||
continue;
|
||||
int numNames = 0;
|
||||
// printf("\n%4d: ", i);
|
||||
@@ -1610,12 +1616,11 @@ STDMETHODIMP CHandler::Close()
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
||||
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool testMode = (_aTestMode != 0);
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
bool allFilesMode = (numItems == (UInt32)-1);
|
||||
if (allFilesMode)
|
||||
numItems = Items.Size();
|
||||
if (numItems == 0)
|
||||
@@ -1655,8 +1660,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
RINOK(lps->SetCur());
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode = testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract;
|
||||
Int32 index = allFilesMode ? i : indices[i];
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
|
||||
@@ -1664,11 +1669,11 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
if (item.IsDir())
|
||||
{
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!testMode && (!realOutStream))
|
||||
if (!testMode && !realOutStream)
|
||||
continue;
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
|
||||
@@ -1679,12 +1684,12 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
const CMftRec &rec = Recs[item.RecIndex];
|
||||
const CAttr &data = rec.DataAttrs[rec.DataRefs[item.DataIndex].Start];
|
||||
|
||||
int res = NArchive::NExtract::NOperationResult::kDataError;
|
||||
int res = NExtract::NOperationResult::kDataError;
|
||||
{
|
||||
CMyComPtr<IInStream> inStream;
|
||||
HRESULT hres = rec.GetStream(InStream, item.DataIndex, Header.ClusterSizeLog, Header.NumClusters, &inStream);
|
||||
if (hres == S_FALSE)
|
||||
res = NArchive::NExtract::NOperationResult::kUnSupportedMethod;
|
||||
res = NExtract::NOperationResult::kUnSupportedMethod;
|
||||
else
|
||||
{
|
||||
RINOK(hres);
|
||||
@@ -1696,7 +1701,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
RINOK(hres);
|
||||
}
|
||||
if (/* copyCoderSpec->TotalSize == item.GetSize() && */ hres == S_OK)
|
||||
res = NArchive::NExtract::NOperationResult::kOK;
|
||||
res = NExtract::NOperationResult::kOK;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1715,7 +1720,7 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static IInArchive *CreateArc() { return new CHandler; }
|
||||
static IInArchive *CreateArc() { return new CHandler; }
|
||||
|
||||
static CArcInfo g_ArcInfo =
|
||||
{ L"NTFS", L"ntfs img", 0, 0xD9, { 'N', 'T', 'F', 'S', ' ', ' ', ' ', ' ', 0 }, 9, false, CreateArc, 0 };
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -350,7 +350,7 @@ HRESULT CHandler::Open2(IInStream *stream,
|
||||
if (!openVolumeCallback)
|
||||
break;
|
||||
|
||||
if(_archives.Size() == 1)
|
||||
if (_archives.Size() == 1)
|
||||
{
|
||||
if (!_archiveInfo.IsVolume())
|
||||
break;
|
||||
@@ -395,9 +395,14 @@ HRESULT CHandler::Open2(IInStream *stream,
|
||||
CItemEx item;
|
||||
for (;;)
|
||||
{
|
||||
HRESULT result = archive.GetNextItem(item, getTextPassword);
|
||||
bool decryptionError;
|
||||
HRESULT result = archive.GetNextItem(item, getTextPassword, decryptionError);
|
||||
if (result == S_FALSE)
|
||||
{
|
||||
if (decryptionError && _items.IsEmpty())
|
||||
return S_FALSE;
|
||||
break;
|
||||
}
|
||||
RINOK(result);
|
||||
if (item.IgnoreItem())
|
||||
continue;
|
||||
@@ -470,27 +475,25 @@ struct CMethodItem
|
||||
};
|
||||
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
Int32 _aTestMode, IArchiveExtractCallback *_anExtractCallback)
|
||||
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
|
||||
bool testMode = (_aTestMode != 0);
|
||||
CMyComPtr<IArchiveExtractCallback> extractCallback = _anExtractCallback;
|
||||
UInt64 censoredTotalUnPacked = 0,
|
||||
// censoredTotalPacked = 0,
|
||||
importantTotalUnPacked = 0;
|
||||
// importantTotalPacked = 0;
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
bool allFilesMode = (numItems == (UInt32)-1);
|
||||
if (allFilesMode)
|
||||
numItems = _refItems.Size();
|
||||
if(numItems == 0)
|
||||
if (numItems == 0)
|
||||
return S_OK;
|
||||
int lastIndex = 0;
|
||||
CRecordVector<int> importantIndexes;
|
||||
CRecordVector<bool> extractStatuses;
|
||||
|
||||
for(UInt32 t = 0; t < numItems; t++)
|
||||
for (UInt32 t = 0; t < numItems; t++)
|
||||
{
|
||||
int index = allFilesMode ? t : indices[t];
|
||||
const CRefItem &refItem = _refItems[index];
|
||||
@@ -498,11 +501,11 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
censoredTotalUnPacked += item.Size;
|
||||
// censoredTotalPacked += item.PackSize;
|
||||
int j;
|
||||
for(j = lastIndex; j <= index; j++)
|
||||
// if(!_items[_refItems[j].ItemIndex].IsSolid())
|
||||
if(!IsSolid(j))
|
||||
for (j = lastIndex; j <= index; j++)
|
||||
// if (!_items[_refItems[j].ItemIndex].IsSolid())
|
||||
if (!IsSolid(j))
|
||||
lastIndex = j;
|
||||
for(j = lastIndex; j <= index; j++)
|
||||
for (j = lastIndex; j <= index; j++)
|
||||
{
|
||||
const CRefItem &refItem = _refItems[j];
|
||||
const CItemEx &item = _items[refItem.ItemIndex];
|
||||
@@ -543,7 +546,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
lps->Init(extractCallback, false);
|
||||
|
||||
bool solidStart = true;
|
||||
for(int i = 0; i < importantIndexes.Size(); i++,
|
||||
for (int i = 0; i < importantIndexes.Size(); i++,
|
||||
currentImportantTotalUnPacked += currentUnPackSize,
|
||||
currentImportantTotalPacked += currentPackSize)
|
||||
{
|
||||
@@ -553,12 +556,12 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
|
||||
Int32 askMode;
|
||||
if(extractStatuses[i])
|
||||
if (extractStatuses[i])
|
||||
askMode = testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract;
|
||||
else
|
||||
askMode = NArchive::NExtract::NAskMode::kSkip;
|
||||
askMode = NExtract::NAskMode::kSkip;
|
||||
|
||||
UInt32 index = importantIndexes[i];
|
||||
|
||||
@@ -569,22 +572,22 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
|
||||
currentPackSize = GetPackSize(index);
|
||||
|
||||
if(item.IgnoreItem())
|
||||
if (item.IgnoreItem())
|
||||
continue;
|
||||
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
|
||||
if (!IsSolid(index))
|
||||
solidStart = true;
|
||||
if(item.IsDir())
|
||||
if (item.IsDir())
|
||||
{
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||
continue;
|
||||
}
|
||||
|
||||
bool mustBeProcessedAnywhere = false;
|
||||
if(i < importantIndexes.Size() - 1)
|
||||
if (i < importantIndexes.Size() - 1)
|
||||
{
|
||||
// const CRefItem &nextRefItem = _refItems[importantIndexes[i + 1]];
|
||||
// const CItemEx &nextItemInfo = _items[nextRefItem.ItemIndex];
|
||||
@@ -596,7 +599,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
continue;
|
||||
|
||||
if (!realOutStream && !testMode)
|
||||
askMode = NArchive::NExtract::NAskMode::kSkip;
|
||||
askMode = NExtract::NAskMode::kSkip;
|
||||
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
|
||||
@@ -664,15 +667,14 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
else
|
||||
{
|
||||
outStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod));
|
||||
continue;
|
||||
}
|
||||
RINOK(filterStreamSpec->Filter.QueryInterface(IID_ICryptoSetPassword,
|
||||
&cryptoSetPassword));
|
||||
|
||||
if (!getTextPassword)
|
||||
extractCallback.QueryInterface(IID_ICryptoGetTextPassword,
|
||||
&getTextPassword);
|
||||
extractCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getTextPassword);
|
||||
if (getTextPassword)
|
||||
{
|
||||
CMyComBSTR password;
|
||||
@@ -729,7 +731,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
if (item.UnPackVersion >= 29)
|
||||
{
|
||||
outStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod));
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
@@ -758,7 +760,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
if (mi.Coder == 0)
|
||||
{
|
||||
outStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -785,7 +787,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
}
|
||||
default:
|
||||
outStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod));
|
||||
continue;
|
||||
}
|
||||
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)
|
||||
{
|
||||
outStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError));
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kDataError));
|
||||
continue;
|
||||
}
|
||||
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];
|
||||
bool crcOK = outStreamSpec->GetCRC() == lastItem.FileCRC;
|
||||
outStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(crcOK ? NArchive::NExtract::NOperationResult::kOK:
|
||||
NArchive::NExtract::NOperationResult::kCRCError));
|
||||
RINOK(extractCallback->SetOperationResult(crcOK ?
|
||||
NExtract::NOperationResult::kOK:
|
||||
NExtract::NOperationResult::kCRCError));
|
||||
}
|
||||
/*
|
||||
else
|
||||
@@ -824,8 +827,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
break;
|
||||
}
|
||||
}
|
||||
RINOK(extractCallback->SetOperationResult(crcOK ? NArchive::NExtract::NOperationResult::kOK:
|
||||
NArchive::NExtract::NOperationResult::kCRCError));
|
||||
RINOK(extractCallback->SetOperationResult(crcOK ?
|
||||
NExtract::NOperationResult::kOK:
|
||||
NExtract::NOperationResult::kCRCError));
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -372,8 +372,9 @@ void CInArchive::AddToSeekValue(UInt64 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)
|
||||
SkipArchiveComment();
|
||||
for (;;)
|
||||
@@ -469,8 +470,11 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa
|
||||
AddToSeekValue(item.PackSize); // m_Position points to next header;
|
||||
return S_OK;
|
||||
}
|
||||
if (m_CryptoMode && m_BlockHeader.HeadSize > (1 << 12))
|
||||
return E_FAIL; // it's for bad passwords
|
||||
if (m_CryptoMode && m_BlockHeader.HeadSize > (1 << 10))
|
||||
{
|
||||
decryptionError = true;
|
||||
return S_FALSE;
|
||||
}
|
||||
if ((m_BlockHeader.Flags & NHeader::NBlock::kLongBlock) != 0)
|
||||
{
|
||||
m_FileHeaderData.EnsureCapacity(7 + 4);
|
||||
@@ -480,7 +484,10 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa
|
||||
UInt32 dataSize = ReadUInt32();
|
||||
AddToSeekValue(dataSize);
|
||||
if (m_CryptoMode && dataSize > (1 << 27))
|
||||
return E_FAIL; // it's for bad passwords
|
||||
{
|
||||
decryptionError = true;
|
||||
return S_FALSE;
|
||||
}
|
||||
m_CryptoPos = m_BlockHeader.HeadSize;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -111,7 +111,7 @@ protected:
|
||||
public:
|
||||
HRESULT Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit);
|
||||
void Close();
|
||||
HRESULT GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPassword);
|
||||
HRESULT GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPassword, bool &decryptionError);
|
||||
|
||||
void SkipArchiveComment();
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "../../Common/RegisterArc.h"
|
||||
|
||||
#include "RarHandler.h"
|
||||
static IInArchive *CreateArc() { return new NArchive::NRar::CHandler; }
|
||||
static IInArchive *CreateArc() { return new NArchive::NRar::CHandler; }
|
||||
|
||||
static CArcInfo g_ArcInfo =
|
||||
{ L"Rar", L"rar r00", 0, 3, {0x52 , 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00}, 7, false, CreateArc, 0, };
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user