9.06 beta

This commit is contained in:
Igor Pavlov
2009-08-17 00:00:00 +00:00
committed by Kornel Lesiński
parent 829409452d
commit c99f3ebdd6
445 changed files with 15246 additions and 8133 deletions

201
C/7z.h Executable file
View 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

View File

@@ -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]);

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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++)
{

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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};

View File

@@ -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

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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)

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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

View File

View 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);

View File

@@ -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 = \

View File

@@ -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

View File

@@ -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";

View 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

View File

@@ -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
View 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)

View File

@@ -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

View File

@@ -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)

View File

@@ -1,4 +1,4 @@
#include "../../CPP/7zip/MyVersionInfo.rc"
#include "../../../CPP/7zip/MyVersionInfo.rc"
MY_VERSION_INFO_DLL("LZMA library", "LZMA")

View File

@@ -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;

View File

@@ -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

View File

@@ -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)
{

View File

@@ -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());
}

View File

@@ -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;
}
}

View File

@@ -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()

View File

@@ -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)
{

View File

@@ -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;

View File

@@ -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;
}}

View File

@@ -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;

View File

@@ -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,

View File

@@ -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)

View File

@@ -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))

View File

@@ -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 \

View File

@@ -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)

View File

@@ -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 };

View File

@@ -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(&currentTotalPacked));
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)

View File

@@ -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())];

View File

@@ -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;
}}}

View File

@@ -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;
}

View File

@@ -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);
};
}}

View File

@@ -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 };

View File

@@ -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;

View File

@@ -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 };

View File

@@ -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();

View File

@@ -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)

View File

@@ -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);

View File

@@ -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 };

View File

@@ -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
View 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
View 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

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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)
{

View File

@@ -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

View File

@@ -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
View 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)
}}

View File

@@ -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(&currentTotalPacked));
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)

View File

@@ -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));
}

View File

@@ -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 };

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@@ -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

View File

@@ -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 };

View File

@@ -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 };

View File

@@ -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);

View File

@@ -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

View File

@@ -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
View 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)
}}

View File

@@ -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

View File

@@ -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(&currentTotalSize));
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

View File

@@ -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";

View File

@@ -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;

View File

@@ -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)

View File

@@ -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 };

View File

File diff suppressed because it is too large Load Diff

View File

@@ -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));
}
*/
}

View File

@@ -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

View File

@@ -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();

View File

@@ -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