4.59 beta

This commit is contained in:
Igor Pavlov
2008-08-13 00:00:00 +00:00
committed by Kornel Lesiński
parent 3901bf0ab8
commit 173c07e166
781 changed files with 22124 additions and 13650 deletions

View File

@@ -1,5 +1,5 @@
/* 7zCrc.c -- CRC32 calculation /* 7zCrc.c -- CRC32 calculation
2008-03-13 2008-08-05
Igor Pavlov Igor Pavlov
Public domain */ Public domain */

View File

@@ -1,5 +1,5 @@
/* Aes.c -- AES encryption / decryption /* Aes.c -- AES encryption / decryption
2008-03-26 2008-08-05
Igor Pavlov Igor Pavlov
Public domain */ Public domain */

View File

@@ -1,5 +1,5 @@
/* Aes.h -- AES encryption / decryption /* Aes.h -- AES encryption / decryption
2008-03-26 2008-08-05
Igor Pavlov Igor Pavlov
Public domain */ Public domain */

View File

@@ -1,5 +1,5 @@
/* Alloc.c -- Memory allocation functions /* Alloc.c -- Memory allocation functions
2008-03-13 2008-08-05
Igor Pavlov Igor Pavlov
Public domain */ Public domain */

View File

@@ -1,5 +1,5 @@
/* 7zDecode.c Decoding from 7z folder /* 7zDecode.c Decoding from 7z folder
2008-04-09 2008-08-05
Igor Pavlov Igor Pavlov
Copyright (c) 1999-2008 Igor Pavlov Copyright (c) 1999-2008 Igor Pavlov
Read 7zDecode.h for license options */ Read 7zDecode.h for license options */
@@ -184,7 +184,7 @@ SRes SzDecode2(const CFileSize *packSizes, const CSzFolder *folder,
if (folder->NumCoders == 4) if (folder->NumCoders == 4)
{ {
UInt32 indices[] = { 3, 2, 0 }; UInt32 indices[] = { 3, 2, 0 };
CFileSize unpackSize = folder->UnPackSizes[ci]; CFileSize unpackSize = folder->UnpackSizes[ci];
si = indices[ci]; si = indices[ci];
if (ci < 2) if (ci < 2)
{ {

View File

@@ -1,5 +1,5 @@
/* 7zExtract.c -- Extracting from 7z archive /* 7zExtract.c -- Extracting from 7z archive
2008-04-09 2008-08-05
Igor Pavlov Igor Pavlov
Copyright (c) 1999-2008 Igor Pavlov Copyright (c) 1999-2008 Igor Pavlov
Read 7zExtract.h for license options */ Read 7zExtract.h for license options */
@@ -36,11 +36,11 @@ SRes SzAr_Extract(
if (*outBuffer == 0 || *blockIndex != folderIndex) if (*outBuffer == 0 || *blockIndex != folderIndex)
{ {
CSzFolder *folder = p->db.Folders + folderIndex; CSzFolder *folder = p->db.Folders + folderIndex;
CFileSize unPackSizeSpec = SzFolder_GetUnPackSize(folder); CFileSize unpackSizeSpec = SzFolder_GetUnpackSize(folder);
size_t unPackSize = (size_t)unPackSizeSpec; size_t unpackSize = (size_t)unpackSizeSpec;
CFileSize startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0); CFileSize startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0);
if (unPackSize != unPackSizeSpec) if (unpackSize != unpackSizeSpec)
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
*blockIndex = folderIndex; *blockIndex = folderIndex;
IAlloc_Free(allocMain, *outBuffer); IAlloc_Free(allocMain, *outBuffer);
@@ -50,10 +50,10 @@ SRes SzAr_Extract(
if (res == SZ_OK) if (res == SZ_OK)
{ {
*outBufferSize = unPackSize; *outBufferSize = unpackSize;
if (unPackSize != 0) if (unpackSize != 0)
{ {
*outBuffer = (Byte *)IAlloc_Alloc(allocMain, unPackSize); *outBuffer = (Byte *)IAlloc_Alloc(allocMain, unpackSize);
if (*outBuffer == 0) if (*outBuffer == 0)
res = SZ_ERROR_MEM; res = SZ_ERROR_MEM;
} }
@@ -62,12 +62,12 @@ SRes SzAr_Extract(
res = SzDecode(p->db.PackSizes + res = SzDecode(p->db.PackSizes +
p->FolderStartPackStreamIndex[folderIndex], folder, p->FolderStartPackStreamIndex[folderIndex], folder,
inStream, startOffset, inStream, startOffset,
*outBuffer, unPackSize, allocTemp); *outBuffer, unpackSize, allocTemp);
if (res == SZ_OK) if (res == SZ_OK)
{ {
if (folder->UnPackCRCDefined) if (folder->UnpackCRCDefined)
{ {
if (CrcCalc(*outBuffer, unPackSize) != folder->UnPackCRC) if (CrcCalc(*outBuffer, unpackSize) != folder->UnpackCRC)
res = SZ_ERROR_CRC; res = SZ_ERROR_CRC;
} }
} }
@@ -85,7 +85,7 @@ SRes SzAr_Extract(
if (*offset + *outSizeProcessed > *outBufferSize) if (*offset + *outSizeProcessed > *outBufferSize)
return SZ_ERROR_FAIL; return SZ_ERROR_FAIL;
{ {
if (fileItem->IsFileCRCDefined) if (fileItem->FileCRCDefined)
{ {
if (CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->FileCRC) if (CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->FileCRC)
res = SZ_ERROR_CRC; res = SZ_ERROR_CRC;

View File

@@ -1,5 +1,5 @@
/* 7zExtract.h -- Extracting from 7z archive /* 7zExtract.h -- Extracting from 7z archive
2008-04-09 2008-08-05
Igor Pavlov Igor Pavlov
Copyright (c) 1999-2008 Igor Pavlov Copyright (c) 1999-2008 Igor Pavlov
Read 7zItem.h for license options */ Read 7zItem.h for license options */

View File

@@ -1,5 +1,5 @@
/* 7zHeader.h -- 7z Headers /* 7zHeader.h -- 7z Headers
2008-03-17 2008-07-14
Copyright (c) 1999-2008 Igor Pavlov Copyright (c) 1999-2008 Igor Pavlov
Read LzmaDec.h for license options */ Read LzmaDec.h for license options */
@@ -28,7 +28,7 @@ enum EIdEnum
k7zIdFilesInfo, k7zIdFilesInfo,
k7zIdPackInfo, k7zIdPackInfo,
k7zIdUnPackInfo, k7zIdUnpackInfo,
k7zIdSubStreamsInfo, k7zIdSubStreamsInfo,
k7zIdSize, k7zIdSize,
@@ -36,23 +36,24 @@ enum EIdEnum
k7zIdFolder, k7zIdFolder,
k7zIdCodersUnPackSize, k7zIdCodersUnpackSize,
k7zIdNumUnPackStream, k7zIdNumUnpackStream,
k7zIdEmptyStream, k7zIdEmptyStream,
k7zIdEmptyFile, k7zIdEmptyFile,
k7zIdAnti, k7zIdAnti,
k7zIdName, k7zIdName,
k7zIdCreationTime, k7zIdCTime,
k7zIdLastAccessTime, k7zIdATime,
k7zIdLastWriteTime, k7zIdMTime,
k7zIdWinAttributes, k7zIdWinAttributes,
k7zIdComment, k7zIdComment,
k7zIdEncodedHeader, k7zIdEncodedHeader,
k7zIdStartPos k7zIdStartPos,
k7zIdDummy
}; };
#endif #endif

View File

@@ -1,5 +1,5 @@
/* 7zIn.c -- 7z Input functions /* 7zIn.c -- 7z Input functions
2008-04-09 2008-08-05
Igor Pavlov Igor Pavlov
Copyright (c) 1999-2008 Igor Pavlov Copyright (c) 1999-2008 Igor Pavlov
Read 7zIn.h for license options */ Read 7zIn.h for license options */
@@ -96,7 +96,7 @@ static SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc)
if (folderIndex >= p->db.NumFolders) if (folderIndex >= p->db.NumFolders)
return SZ_ERROR_ARCHIVE; return SZ_ERROR_ARCHIVE;
p->FolderStartFileIndex[folderIndex] = i; p->FolderStartFileIndex[folderIndex] = i;
if (p->db.Folders[folderIndex].NumUnPackStreams != 0) if (p->db.Folders[folderIndex].NumUnpackStreams != 0)
break; break;
folderIndex++; folderIndex++;
} }
@@ -105,7 +105,7 @@ static SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc)
if (emptyStream) if (emptyStream)
continue; continue;
indexInFolder++; indexInFolder++;
if (indexInFolder >= p->db.Folders[folderIndex].NumUnPackStreams) if (indexInFolder >= p->db.Folders[folderIndex].NumUnpackStreams)
{ {
folderIndex++; folderIndex++;
indexInFolder = 0; indexInFolder = 0;
@@ -164,21 +164,9 @@ SRes SzReadTime(const CObjectVector<CBuf> &dataVector,
} }
switch(type) switch(type)
{ {
case k7zIdCreationTime: case k7zIdCTime: file.IsCTimeDefined = defined; if (defined) file.CTime = fileTime; break;
file.IsCreationTimeDefined = defined; case k7zIdATime: file.IsATimeDefined = defined; if (defined) file.ATime = fileTime; break;
if (defined) case k7zIdMTime: file.IsMTimeDefined = defined; if (defined) file.MTime = fileTime; break;
file.CreationTime = fileTime;
break;
case k7zIdLastWriteTime:
file.IsLastWriteTimeDefined = defined;
if (defined)
file.LastWriteTime = fileTime;
break;
case k7zIdLastAccessTime:
file.IsLastAccessTimeDefined = defined;
if (defined)
file.LastAccessTime = fileTime;
break;
} }
} }
return SZ_OK; return SZ_OK;
@@ -589,7 +577,7 @@ static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc)
return SZ_OK; return SZ_OK;
} }
static SRes SzReadUnPackInfo( static SRes SzReadUnpackInfo(
CSzData *sd, CSzData *sd,
UInt32 *numFolders, UInt32 *numFolders,
CSzFolder **folders, /* for alloc */ CSzFolder **folders, /* for alloc */
@@ -613,7 +601,7 @@ static SRes SzReadUnPackInfo(
} }
} }
RINOK(SzWaitAttribute(sd, k7zIdCodersUnPackSize)); RINOK(SzWaitAttribute(sd, k7zIdCodersUnpackSize));
for (i = 0; i < *numFolders; i++) for (i = 0; i < *numFolders; i++)
{ {
@@ -621,11 +609,11 @@ static SRes SzReadUnPackInfo(
CSzFolder *folder = (*folders) + i; CSzFolder *folder = (*folders) + i;
UInt32 numOutStreams = SzFolder_GetNumOutStreams(folder); UInt32 numOutStreams = SzFolder_GetNumOutStreams(folder);
MY_ALLOC(CFileSize, folder->UnPackSizes, (size_t)numOutStreams, alloc); MY_ALLOC(CFileSize, folder->UnpackSizes, (size_t)numOutStreams, alloc);
for (j = 0; j < numOutStreams; j++) for (j = 0; j < numOutStreams; j++)
{ {
RINOK(SzReadSize(sd, folder->UnPackSizes + j)); RINOK(SzReadSize(sd, folder->UnpackSizes + j));
} }
} }
@@ -646,8 +634,8 @@ static SRes SzReadUnPackInfo(
for (i = 0; i < *numFolders; i++) for (i = 0; i < *numFolders; i++)
{ {
CSzFolder *folder = (*folders) + i; CSzFolder *folder = (*folders) + i;
folder->UnPackCRCDefined = crcsDefined[i]; folder->UnpackCRCDefined = crcsDefined[i];
folder->UnPackCRC = crcs[i]; folder->UnpackCRC = crcs[i];
} }
} }
IAlloc_Free(allocTemp, crcs); IAlloc_Free(allocTemp, crcs);
@@ -663,8 +651,8 @@ static SRes SzReadSubStreamsInfo(
CSzData *sd, CSzData *sd,
UInt32 numFolders, UInt32 numFolders,
CSzFolder *folders, CSzFolder *folders,
UInt32 *numUnPackStreams, UInt32 *numUnpackStreams,
CFileSize **unPackSizes, CFileSize **unpackSizes,
Byte **digestsDefined, Byte **digestsDefined,
UInt32 **digests, UInt32 **digests,
ISzAlloc *allocTemp) ISzAlloc *allocTemp)
@@ -675,21 +663,21 @@ static SRes SzReadSubStreamsInfo(
UInt32 numDigests = 0; UInt32 numDigests = 0;
for (i = 0; i < numFolders; i++) for (i = 0; i < numFolders; i++)
folders[i].NumUnPackStreams = 1; folders[i].NumUnpackStreams = 1;
*numUnPackStreams = numFolders; *numUnpackStreams = numFolders;
for (;;) for (;;)
{ {
RINOK(SzReadID(sd, &type)); RINOK(SzReadID(sd, &type));
if (type == k7zIdNumUnPackStream) if (type == k7zIdNumUnpackStream)
{ {
*numUnPackStreams = 0; *numUnpackStreams = 0;
for (i = 0; i < numFolders; i++) for (i = 0; i < numFolders; i++)
{ {
UInt32 numStreams; UInt32 numStreams;
RINOK(SzReadNumber32(sd, &numStreams)); RINOK(SzReadNumber32(sd, &numStreams));
folders[i].NumUnPackStreams = numStreams; folders[i].NumUnpackStreams = numStreams;
*numUnPackStreams += numStreams; *numUnpackStreams += numStreams;
} }
continue; continue;
} }
@@ -700,19 +688,19 @@ static SRes SzReadSubStreamsInfo(
RINOK(SzSkeepData(sd)); RINOK(SzSkeepData(sd));
} }
if (*numUnPackStreams == 0) if (*numUnpackStreams == 0)
{ {
*unPackSizes = 0; *unpackSizes = 0;
*digestsDefined = 0; *digestsDefined = 0;
*digests = 0; *digests = 0;
} }
else else
{ {
*unPackSizes = (CFileSize *)IAlloc_Alloc(allocTemp, (size_t)*numUnPackStreams * sizeof(CFileSize)); *unpackSizes = (CFileSize *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(CFileSize));
RINOM(*unPackSizes); RINOM(*unpackSizes);
*digestsDefined = (Byte *)IAlloc_Alloc(allocTemp, (size_t)*numUnPackStreams * sizeof(Byte)); *digestsDefined = (Byte *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(Byte));
RINOM(*digestsDefined); RINOM(*digestsDefined);
*digests = (UInt32 *)IAlloc_Alloc(allocTemp, (size_t)*numUnPackStreams * sizeof(UInt32)); *digests = (UInt32 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt32));
RINOM(*digests); RINOM(*digests);
} }
@@ -724,7 +712,7 @@ static SRes SzReadSubStreamsInfo(
*/ */
CFileSize sum = 0; CFileSize sum = 0;
UInt32 j; UInt32 j;
UInt32 numSubstreams = folders[i].NumUnPackStreams; UInt32 numSubstreams = folders[i].NumUnpackStreams;
if (numSubstreams == 0) if (numSubstreams == 0)
continue; continue;
if (type == k7zIdSize) if (type == k7zIdSize)
@@ -732,17 +720,17 @@ static SRes SzReadSubStreamsInfo(
{ {
CFileSize size; CFileSize size;
RINOK(SzReadSize(sd, &size)); RINOK(SzReadSize(sd, &size));
(*unPackSizes)[si++] = size; (*unpackSizes)[si++] = size;
sum += size; sum += size;
} }
(*unPackSizes)[si++] = SzFolder_GetUnPackSize(folders + i) - sum; (*unpackSizes)[si++] = SzFolder_GetUnpackSize(folders + i) - sum;
} }
if (type == k7zIdSize) if (type == k7zIdSize)
{ {
RINOK(SzReadID(sd, &type)); RINOK(SzReadID(sd, &type));
} }
for (i = 0; i < *numUnPackStreams; i++) for (i = 0; i < *numUnpackStreams; i++)
{ {
(*digestsDefined)[i] = 0; (*digestsDefined)[i] = 0;
(*digests)[i] = 0; (*digests)[i] = 0;
@@ -751,8 +739,8 @@ static SRes SzReadSubStreamsInfo(
for (i = 0; i < numFolders; i++) for (i = 0; i < numFolders; i++)
{ {
UInt32 numSubstreams = folders[i].NumUnPackStreams; UInt32 numSubstreams = folders[i].NumUnpackStreams;
if (numSubstreams != 1 || !folders[i].UnPackCRCDefined) if (numSubstreams != 1 || !folders[i].UnpackCRCDefined)
numDigests += numSubstreams; numDigests += numSubstreams;
} }
@@ -771,11 +759,11 @@ static SRes SzReadSubStreamsInfo(
for (i = 0; i < numFolders; i++) for (i = 0; i < numFolders; i++)
{ {
CSzFolder *folder = folders + i; CSzFolder *folder = folders + i;
UInt32 numSubstreams = folder->NumUnPackStreams; UInt32 numSubstreams = folder->NumUnpackStreams;
if (numSubstreams == 1 && folder->UnPackCRCDefined) if (numSubstreams == 1 && folder->UnpackCRCDefined)
{ {
(*digestsDefined)[si] = 1; (*digestsDefined)[si] = 1;
(*digests)[si] = folder->UnPackCRC; (*digests)[si] = folder->UnpackCRC;
si++; si++;
} }
else else
@@ -809,8 +797,8 @@ static SRes SzReadStreamsInfo(
CSzData *sd, CSzData *sd,
CFileSize *dataOffset, CFileSize *dataOffset,
CSzAr *p, CSzAr *p,
UInt32 *numUnPackStreams, UInt32 *numUnpackStreams,
CFileSize **unPackSizes, /* allocTemp */ CFileSize **unpackSizes, /* allocTemp */
Byte **digestsDefined, /* allocTemp */ Byte **digestsDefined, /* allocTemp */
UInt32 **digests, /* allocTemp */ UInt32 **digests, /* allocTemp */
ISzAlloc *alloc, ISzAlloc *alloc,
@@ -832,15 +820,15 @@ static SRes SzReadStreamsInfo(
&p->PackSizes, &p->PackCRCsDefined, &p->PackCRCs, alloc)); &p->PackSizes, &p->PackCRCsDefined, &p->PackCRCs, alloc));
break; break;
} }
case k7zIdUnPackInfo: case k7zIdUnpackInfo:
{ {
RINOK(SzReadUnPackInfo(sd, &p->NumFolders, &p->Folders, alloc, allocTemp)); RINOK(SzReadUnpackInfo(sd, &p->NumFolders, &p->Folders, alloc, allocTemp));
break; break;
} }
case k7zIdSubStreamsInfo: case k7zIdSubStreamsInfo:
{ {
RINOK(SzReadSubStreamsInfo(sd, p->NumFolders, p->Folders, RINOK(SzReadSubStreamsInfo(sd, p->NumFolders, p->Folders,
numUnPackStreams, unPackSizes, digestsDefined, digests, allocTemp)); numUnpackStreams, unpackSizes, digestsDefined, digests, allocTemp));
break; break;
} }
default: default:
@@ -929,7 +917,7 @@ static SRes SzReadFileNames(CSzData *sd, UInt32 numFiles, CSzFileItem *files, IS
static SRes SzReadHeader2( static SRes SzReadHeader2(
CSzArEx *p, /* allocMain */ CSzArEx *p, /* allocMain */
CSzData *sd, CSzData *sd,
CFileSize **unPackSizes, /* allocTemp */ CFileSize **unpackSizes, /* allocTemp */
Byte **digestsDefined, /* allocTemp */ Byte **digestsDefined, /* allocTemp */
UInt32 **digests, /* allocTemp */ UInt32 **digests, /* allocTemp */
Byte **emptyStreamVector, /* allocTemp */ Byte **emptyStreamVector, /* allocTemp */
@@ -939,7 +927,7 @@ static SRes SzReadHeader2(
ISzAlloc *allocTemp) ISzAlloc *allocTemp)
{ {
UInt64 type; UInt64 type;
UInt32 numUnPackStreams = 0; UInt32 numUnpackStreams = 0;
UInt32 numFiles = 0; UInt32 numFiles = 0;
CSzFileItem *files = 0; CSzFileItem *files = 0;
UInt32 numEmptyStreams = 0; UInt32 numEmptyStreams = 0;
@@ -959,8 +947,8 @@ static SRes SzReadHeader2(
RINOK(SzReadStreamsInfo(sd, RINOK(SzReadStreamsInfo(sd,
&p->ArchiveInfo.DataStartPosition, &p->ArchiveInfo.DataStartPosition,
&p->db, &p->db,
&numUnPackStreams, &numUnpackStreams,
unPackSizes, unpackSizes,
digestsDefined, digestsDefined,
digests, allocMain, allocTemp)); digests, allocMain, allocTemp));
p->ArchiveInfo.DataStartPosition += p->ArchiveInfo.StartPositionAfterHeader; p->ArchiveInfo.DataStartPosition += p->ArchiveInfo.StartPositionAfterHeader;
@@ -1017,7 +1005,7 @@ static SRes SzReadHeader2(
RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp)); RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp));
break; break;
} }
case k7zIdLastWriteTime: case k7zIdMTime:
{ {
RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp)); RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp));
RINOK(SzReadSwitch(sd)); RINOK(SzReadSwitch(sd));
@@ -1025,12 +1013,12 @@ static SRes SzReadHeader2(
{ {
CSzFileItem *f = &files[i]; CSzFileItem *f = &files[i];
Byte defined = (*lwtVector)[i]; Byte defined = (*lwtVector)[i];
f->IsLastWriteTimeDefined = defined; f->MTimeDefined = defined;
f->LastWriteTime.Low = f->LastWriteTime.High = 0; f->MTime.Low = f->MTime.High = 0;
if (defined) if (defined)
{ {
RINOK(SzReadUInt32(sd, &f->LastWriteTime.Low)); RINOK(SzReadUInt32(sd, &f->MTime.Low));
RINOK(SzReadUInt32(sd, &f->LastWriteTime.High)); RINOK(SzReadUInt32(sd, &f->MTime.High));
} }
} }
break; break;
@@ -1055,21 +1043,21 @@ static SRes SzReadHeader2(
file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1); file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1);
if(file->HasStream) if(file->HasStream)
{ {
file->IsDirectory = 0; file->IsDir = 0;
file->Size = (*unPackSizes)[sizeIndex]; file->Size = (*unpackSizes)[sizeIndex];
file->FileCRC = (*digests)[sizeIndex]; file->FileCRC = (*digests)[sizeIndex];
file->IsFileCRCDefined = (Byte)(*digestsDefined)[sizeIndex]; file->FileCRCDefined = (Byte)(*digestsDefined)[sizeIndex];
sizeIndex++; sizeIndex++;
} }
else else
{ {
if (*emptyFileVector == 0) if (*emptyFileVector == 0)
file->IsDirectory = 1; file->IsDir = 1;
else else
file->IsDirectory = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1); file->IsDir = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1);
emptyFileIndex++; emptyFileIndex++;
file->Size = 0; file->Size = 0;
file->IsFileCRCDefined = 0; file->FileCRCDefined = 0;
} }
} }
} }
@@ -1082,17 +1070,17 @@ static SRes SzReadHeader(
ISzAlloc *allocMain, ISzAlloc *allocMain,
ISzAlloc *allocTemp) ISzAlloc *allocTemp)
{ {
CFileSize *unPackSizes = 0; CFileSize *unpackSizes = 0;
Byte *digestsDefined = 0; Byte *digestsDefined = 0;
UInt32 *digests = 0; UInt32 *digests = 0;
Byte *emptyStreamVector = 0; Byte *emptyStreamVector = 0;
Byte *emptyFileVector = 0; Byte *emptyFileVector = 0;
Byte *lwtVector = 0; Byte *lwtVector = 0;
SRes res = SzReadHeader2(p, sd, SRes res = SzReadHeader2(p, sd,
&unPackSizes, &digestsDefined, &digests, &unpackSizes, &digestsDefined, &digests,
&emptyStreamVector, &emptyFileVector, &lwtVector, &emptyStreamVector, &emptyFileVector, &lwtVector,
allocMain, allocTemp); allocMain, allocTemp);
IAlloc_Free(allocTemp, unPackSizes); IAlloc_Free(allocTemp, unpackSizes);
IAlloc_Free(allocTemp, digestsDefined); IAlloc_Free(allocTemp, digestsDefined);
IAlloc_Free(allocTemp, digests); IAlloc_Free(allocTemp, digests);
IAlloc_Free(allocTemp, emptyStreamVector); IAlloc_Free(allocTemp, emptyStreamVector);
@@ -1107,20 +1095,20 @@ static SRes SzReadAndDecodePackedStreams2(
CBuf *outBuffer, CBuf *outBuffer,
CFileSize baseOffset, CFileSize baseOffset,
CSzAr *p, CSzAr *p,
CFileSize **unPackSizes, CFileSize **unpackSizes,
Byte **digestsDefined, Byte **digestsDefined,
UInt32 **digests, UInt32 **digests,
ISzAlloc *allocTemp) ISzAlloc *allocTemp)
{ {
UInt32 numUnPackStreams = 0; UInt32 numUnpackStreams = 0;
CFileSize dataStartPos; CFileSize dataStartPos;
CSzFolder *folder; CSzFolder *folder;
CFileSize unPackSize; CFileSize unpackSize;
SRes res; SRes res;
RINOK(SzReadStreamsInfo(sd, &dataStartPos, p, RINOK(SzReadStreamsInfo(sd, &dataStartPos, p,
&numUnPackStreams, unPackSizes, digestsDefined, digests, &numUnpackStreams, unpackSizes, digestsDefined, digests,
allocTemp, allocTemp)); allocTemp, allocTemp));
dataStartPos += baseOffset; dataStartPos += baseOffset;
@@ -1128,19 +1116,19 @@ static SRes SzReadAndDecodePackedStreams2(
return SZ_ERROR_ARCHIVE; return SZ_ERROR_ARCHIVE;
folder = p->Folders; folder = p->Folders;
unPackSize = SzFolder_GetUnPackSize(folder); unpackSize = SzFolder_GetUnpackSize(folder);
RINOK(inStream->Seek(inStream, dataStartPos, SZ_SEEK_SET)); RINOK(inStream->Seek(inStream, dataStartPos, SZ_SEEK_SET));
if (!Buf_Create(outBuffer, (size_t)unPackSize, allocTemp)) if (!Buf_Create(outBuffer, (size_t)unpackSize, allocTemp))
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
res = SzDecode(p->PackSizes, folder, res = SzDecode(p->PackSizes, folder,
inStream, dataStartPos, inStream, dataStartPos,
outBuffer->data, (size_t)unPackSize, allocTemp); outBuffer->data, (size_t)unpackSize, allocTemp);
RINOK(res); RINOK(res);
if (folder->UnPackCRCDefined) if (folder->UnpackCRCDefined)
if (CrcCalc(outBuffer->data, (size_t)unPackSize) != folder->UnPackCRC) if (CrcCalc(outBuffer->data, (size_t)unpackSize) != folder->UnpackCRC)
return SZ_ERROR_CRC; return SZ_ERROR_CRC;
return SZ_OK; return SZ_OK;
} }
@@ -1153,16 +1141,16 @@ static SRes SzReadAndDecodePackedStreams(
ISzAlloc *allocTemp) ISzAlloc *allocTemp)
{ {
CSzAr p; CSzAr p;
CFileSize *unPackSizes = 0; CFileSize *unpackSizes = 0;
Byte *digestsDefined = 0; Byte *digestsDefined = 0;
UInt32 *digests = 0; UInt32 *digests = 0;
SRes res; SRes res;
SzAr_Init(&p); SzAr_Init(&p);
res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset, res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset,
&p, &unPackSizes, &digestsDefined, &digests, &p, &unpackSizes, &digestsDefined, &digests,
allocTemp); allocTemp);
SzAr_Free(&p, allocTemp); SzAr_Free(&p, allocTemp);
IAlloc_Free(allocTemp, unPackSizes); IAlloc_Free(allocTemp, unpackSizes);
IAlloc_Free(allocTemp, digestsDefined); IAlloc_Free(allocTemp, digestsDefined);
IAlloc_Free(allocTemp, digests); IAlloc_Free(allocTemp, digests);
return res; return res;

View File

@@ -1,5 +1,5 @@
/* 7zIn.h -- 7z Input functions /* 7zIn.h -- 7z Input functions
2008-05-05 2008-08-05
Igor Pavlov Igor Pavlov
Copyright (c) 1999-2008 Igor Pavlov Copyright (c) 1999-2008 Igor Pavlov
Read 7zItem.h for license options */ Read 7zItem.h for license options */

View File

@@ -1,5 +1,5 @@
/* 7zItem.c -- 7z Items /* 7zItem.c -- 7z Items
2008-04-09 2008-08-05
Igor Pavlov Igor Pavlov
Copyright (c) 1999-2008 Igor Pavlov Copyright (c) 1999-2008 Igor Pavlov
Read 7zItem.h for license options */ Read 7zItem.h for license options */
@@ -22,13 +22,13 @@ void SzFolder_Init(CSzFolder *p)
p->Coders = 0; p->Coders = 0;
p->BindPairs = 0; p->BindPairs = 0;
p->PackStreams = 0; p->PackStreams = 0;
p->UnPackSizes = 0; p->UnpackSizes = 0;
p->NumCoders = 0; p->NumCoders = 0;
p->NumBindPairs = 0; p->NumBindPairs = 0;
p->NumPackStreams = 0; p->NumPackStreams = 0;
p->UnPackCRCDefined = 0; p->UnpackCRCDefined = 0;
p->UnPackCRC = 0; p->UnpackCRC = 0;
p->NumUnPackStreams = 0; p->NumUnpackStreams = 0;
} }
void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc) void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc)
@@ -40,7 +40,7 @@ void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc)
IAlloc_Free(alloc, p->Coders); IAlloc_Free(alloc, p->Coders);
IAlloc_Free(alloc, p->BindPairs); IAlloc_Free(alloc, p->BindPairs);
IAlloc_Free(alloc, p->PackStreams); IAlloc_Free(alloc, p->PackStreams);
IAlloc_Free(alloc, p->UnPackSizes); IAlloc_Free(alloc, p->UnpackSizes);
SzFolder_Init(p); SzFolder_Init(p);
} }
@@ -72,25 +72,25 @@ int SzFolder_FindBindPairForOutStream(CSzFolder *p, UInt32 outStreamIndex)
return -1; return -1;
} }
CFileSize SzFolder_GetUnPackSize(CSzFolder *p) CFileSize SzFolder_GetUnpackSize(CSzFolder *p)
{ {
int i = (int)SzFolder_GetNumOutStreams(p); int i = (int)SzFolder_GetNumOutStreams(p);
if (i == 0) if (i == 0)
return 0; return 0;
for (i--; i >= 0; i--) for (i--; i >= 0; i--)
if (SzFolder_FindBindPairForOutStream(p, i) < 0) if (SzFolder_FindBindPairForOutStream(p, i) < 0)
return p->UnPackSizes[i]; return p->UnpackSizes[i];
/* throw 1; */ /* throw 1; */
return 0; return 0;
} }
void SzFile_Init(CSzFileItem *p) void SzFile_Init(CSzFileItem *p)
{ {
p->IsFileCRCDefined = 0;
p->HasStream = 1; p->HasStream = 1;
p->IsDirectory = 0; p->IsDir = 0;
p->IsAnti = 0; p->IsAnti = 0;
p->IsLastWriteTimeDefined = 0; p->FileCRCDefined = 0;
p->MTimeDefined = 0;
p->Name = 0; p->Name = 0;
} }

View File

@@ -1,5 +1,5 @@
/* 7zItem.h -- 7z Items /* 7zItem.h -- 7z Items
2008-05-01 2008-07-09
Igor Pavlov Igor Pavlov
Copyright (c) 1999-2008 Igor Pavlov Copyright (c) 1999-2008 Igor Pavlov
Read LzmaDec.h for license options */ Read LzmaDec.h for license options */
@@ -42,21 +42,21 @@ typedef struct
CSzCoderInfo *Coders; CSzCoderInfo *Coders;
CBindPair *BindPairs; CBindPair *BindPairs;
UInt32 *PackStreams; UInt32 *PackStreams;
CFileSize *UnPackSizes; CFileSize *UnpackSizes;
UInt32 NumCoders; UInt32 NumCoders;
UInt32 NumBindPairs; UInt32 NumBindPairs;
UInt32 NumPackStreams; UInt32 NumPackStreams;
int UnPackCRCDefined; int UnpackCRCDefined;
UInt32 UnPackCRC; UInt32 UnpackCRC;
UInt32 NumUnPackStreams; UInt32 NumUnpackStreams;
} CSzFolder; } CSzFolder;
void SzFolder_Init(CSzFolder *p); void SzFolder_Init(CSzFolder *p);
CFileSize SzFolder_GetUnPackSize(CSzFolder *p); CFileSize SzFolder_GetUnpackSize(CSzFolder *p);
int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex); int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex);
UInt32 SzFolder_GetNumOutStreams(CSzFolder *p); UInt32 SzFolder_GetNumOutStreams(CSzFolder *p);
CFileSize SzFolder_GetUnPackSize(CSzFolder *p); CFileSize SzFolder_GetUnpackSize(CSzFolder *p);
typedef struct typedef struct
{ {
@@ -66,25 +66,16 @@ typedef struct
typedef struct typedef struct
{ {
CNtfsFileTime LastWriteTime; CNtfsFileTime MTime;
/*
CFileSize StartPos;
UInt32 Attributes;
*/
CFileSize Size; CFileSize Size;
char *Name; char *Name;
UInt32 FileCRC; UInt32 FileCRC;
Byte IsFileCRCDefined;
Byte HasStream; Byte HasStream;
Byte IsDirectory; Byte IsDir;
Byte IsAnti; Byte IsAnti;
Byte IsLastWriteTimeDefined; Byte FileCRCDefined;
/* Byte MTimeDefined;
int AreAttributesDefined;
int IsLastWriteTimeDefined;
int IsStartPosDefined;
*/
} CSzFileItem; } CSzFileItem;
void SzFile_Init(CSzFileItem *p); void SzFile_Init(CSzFileItem *p);

View File

@@ -1,5 +1,5 @@
/* 7zMain.c - Test application for 7z Decoder /* 7zMain.c - Test application for 7z Decoder
2008-04-09 2008-08-05
Igor Pavlov Igor Pavlov
Public domain */ Public domain */
@@ -246,7 +246,7 @@ int MY_CDECL main(int numargs, char *args[])
ISzAlloc allocImp; ISzAlloc allocImp;
ISzAlloc allocTempImp; ISzAlloc allocTempImp;
printf("\n7z ANSI-C Decoder 4.58 Copyright (c) 1999-2008 Igor Pavlov 2008-04-09\n"); printf("\n7z ANSI-C Decoder 4.59 Copyright (c) 1999-2008 Igor Pavlov 2008-07-09\n");
if (numargs == 1) if (numargs == 1)
{ {
printf( printf(
@@ -311,8 +311,8 @@ int MY_CDECL main(int numargs, char *args[])
CSzFileItem *f = db.db.Files + i; CSzFileItem *f = db.db.Files + i;
char s[32], t[32]; char s[32], t[32];
ConvertNumberToString(f->Size, s); ConvertNumberToString(f->Size, s);
if (f->IsLastWriteTimeDefined) if (f->MTimeDefined)
ConvertFileTimeToString(&f->LastWriteTime, t); ConvertFileTimeToString(&f->MTime, t);
else else
strcpy(t, " "); strcpy(t, " ");
@@ -337,14 +337,14 @@ int MY_CDECL main(int numargs, char *args[])
size_t offset; size_t offset;
size_t outSizeProcessed; size_t outSizeProcessed;
CSzFileItem *f = db.db.Files + i; CSzFileItem *f = db.db.Files + i;
if (f->IsDirectory) if (f->IsDir)
printf("Directory "); printf("Directory ");
else else
printf(testCommand ? printf(testCommand ?
"Testing ": "Testing ":
"Extracting"); "Extracting");
printf(" %s", f->Name); printf(" %s", f->Name);
if (f->IsDirectory) if (f->IsDir)
{ {
printf("\n"); printf("\n");
continue; continue;

View File

@@ -1,12 +1,10 @@
/* Bcj2.c -- Converter for x86 code (BCJ2) /* Bcj2.c -- Converter for x86 code (BCJ2)
2008-04-11 2008-08-05
Copyright (c) 1999-2008 Igor Pavlov Copyright (c) 1999-2008 Igor Pavlov
Read Bra.h for license options */ Read Bra.h for license options */
#include "Bcj2.h" #include "Bcj2.h"
#include "Alloc.h"
#ifdef _LZMA_PROB32 #ifdef _LZMA_PROB32
#define CProb UInt32 #define CProb UInt32
#else #else

View File

@@ -1,5 +1,5 @@
/* Bcj2.h -- Converter for x86 code (BCJ2) /* Bcj2.h -- Converter for x86 code (BCJ2)
2008-04-11 2008-08-05
Copyright (c) 1999-2008 Igor Pavlov Copyright (c) 1999-2008 Igor Pavlov
Read Bra.h for license options */ Read Bra.h for license options */

View File

@@ -1,5 +1,5 @@
/* Bra.c -- converters for RISC code /* Bra.c -- converters for RISC code
2008-03-19 2008-08-05
Copyright (c) 1999-2008 Igor Pavlov Copyright (c) 1999-2008 Igor Pavlov
Read Bra.h for license options */ Read Bra.h for license options */

View File

@@ -1,5 +1,5 @@
/* Bra.h -- Branch converters for executables /* Bra.h -- Branch converters for executables
2008-03-19 2008-08-05
Copyright (c) 1999-2008 Igor Pavlov Copyright (c) 1999-2008 Igor Pavlov
Read LzmaDec.h for license options */ Read LzmaDec.h for license options */

View File

@@ -1,5 +1,5 @@
/* BraIA64.c -- converter for IA-64 code /* BraIA64.c -- converter for IA-64 code
2008-03-19 2008-08-05
Copyright (c) 1999-2008 Igor Pavlov Copyright (c) 1999-2008 Igor Pavlov
Read Bra.h for license options */ Read Bra.h for license options */

View File

@@ -1,5 +1,5 @@
/* BwtSort.c -- BWT block sorting /* BwtSort.c -- BWT block sorting
2008-03-26 2008-08-05
Igor Pavlov Igor Pavlov
Public domain */ Public domain */

View File

@@ -1,5 +1,5 @@
/* CpuArch.h /* CpuArch.h
2008-03-26 2008-08-05
Igor Pavlov Igor Pavlov
Public domain */ Public domain */
@@ -23,19 +23,19 @@ about these properties of platform.
#define GetUi16(p) (*(const UInt16 *)(p)) #define GetUi16(p) (*(const UInt16 *)(p))
#define GetUi32(p) (*(const UInt32 *)(p)) #define GetUi32(p) (*(const UInt32 *)(p))
#define GetUi64(p) (*(const UInt64 *)(p)) #define GetUi64(p) (*(const UInt64 *)(p))
#define SetUi32(p, d) *(UInt32 *)(p) = d; #define SetUi32(p, d) *(UInt32 *)(p) = (d);
#else #else
#define GetUi16(p) (((const Byte *)(p))[0] | \ #define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8))
((UInt16)((const Byte *)(p))[1] << 8))
#define GetUi32(p) (((const Byte *)(p))[0] | \ #define GetUi32(p) ( \
((UInt32)((const Byte *)(p))[1] << 8 ) | \ ((const Byte *)(p))[0] | \
((UInt32)((const Byte *)(p))[1] << 8) | \
((UInt32)((const Byte *)(p))[2] << 16) | \ ((UInt32)((const Byte *)(p))[2] << 16) | \
((UInt32)((const Byte *)(p))[3] << 24)) ((UInt32)((const Byte *)(p))[3] << 24))
#define GetUi64(p) (GetUi32(p) | (UInt64)GetUi32(((const Byte *)(p)) + 4) << 32) #define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
#define SetUi32(p, d) { UInt32 _x_ = (d); \ #define SetUi32(p, d) { UInt32 _x_ = (d); \
((Byte *)(p))[0] = (Byte)_x_; \ ((Byte *)(p))[0] = (Byte)_x_; \
@@ -45,4 +45,25 @@ about these properties of platform.
#endif #endif
#if defined(LITTLE_ENDIAN_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300)
#pragma intrinsic(_byteswap_ulong)
#pragma intrinsic(_byteswap_uint64)
#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
#else
#define GetBe32(p) ( \
((UInt32)((const Byte *)(p))[0] << 24) | \
((UInt32)((const Byte *)(p))[1] << 16) | \
((UInt32)((const Byte *)(p))[2] << 8) | \
((const Byte *)(p))[3] )
#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
#endif
#define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1])
#endif #endif

View File

@@ -1,5 +1,5 @@
/* HuffEnc.c -- functions for Huffman encoding /* HuffEnc.c -- functions for Huffman encoding
2008-03-26 2008-08-05
Igor Pavlov Igor Pavlov
Public domain */ Public domain */

View File

@@ -1,5 +1,5 @@
/* LzFind.c -- Match finder for LZ algorithms /* LzFind.c -- Match finder for LZ algorithms
2008-04-04 2008-08-05
Copyright (c) 1999-2008 Igor Pavlov Copyright (c) 1999-2008 Igor Pavlov
Read LzFind.h for license options */ Read LzFind.h for license options */

View File

@@ -1,5 +1,5 @@
/* LzFind.h -- Match finder for LZ algorithms /* LzFind.h -- Match finder for LZ algorithms
2008-04-04 2008-08-05
Copyright (c) 1999-2008 Igor Pavlov Copyright (c) 1999-2008 Igor Pavlov
You can use any of the following license options: You can use any of the following license options:
1) GNU Lesser General Public License (GNU LGPL) 1) GNU Lesser General Public License (GNU LGPL)

View File

@@ -1,5 +1,5 @@
/* LzFindMt.c -- multithreaded Match finder for LZ algorithms /* LzFindMt.c -- multithreaded Match finder for LZ algorithms
2008-04-11 2008-08-05
Copyright (c) 1999-2008 Igor Pavlov Copyright (c) 1999-2008 Igor Pavlov
Read LzFind.h for license options */ Read LzFind.h for license options */

View File

@@ -1,5 +1,5 @@
/* LzFindMt.h -- multithreaded Match finder for LZ algorithms /* LzFindMt.h -- multithreaded Match finder for LZ algorithms
2008-04-04 2008-08-05
Copyright (c) 1999-2008 Igor Pavlov Copyright (c) 1999-2008 Igor Pavlov
Read LzFind.h for license options */ Read LzFind.h for license options */

View File

@@ -1,5 +1,5 @@
/* LzmaDec.c -- LZMA Decoder /* LzmaDec.c -- LZMA Decoder
2008-04-29 2008-08-05
Copyright (c) 1999-2008 Igor Pavlov Copyright (c) 1999-2008 Igor Pavlov
Read LzmaDec.h for license options */ Read LzmaDec.h for license options */
@@ -120,7 +120,7 @@ StopCompilingDueBUG
#define LZMA_SPEC_LEN_OFFSET (-3) #define LZMA_SPEC_LEN_OFFSET (-3)
*/ */
Byte kLiteralNextStates[kNumStates * 2] = const Byte kLiteralNextStates[kNumStates * 2] =
{ {
0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5,
7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10

View File

@@ -1,5 +1,5 @@
/* LzmaDec.h -- LZMA Decoder /* LzmaDec.h -- LZMA Decoder
2008-04-29 2008-08-05
Copyright (c) 1999-2008 Igor Pavlov Copyright (c) 1999-2008 Igor Pavlov
You can use any of the following license options: You can use any of the following license options:
1) GNU Lesser General Public License (GNU LGPL) 1) GNU Lesser General Public License (GNU LGPL)

View File

@@ -1,11 +1,17 @@
/* LzmaEnc.c -- LZMA Encoder /* LzmaEnc.c -- LZMA Encoder
2008-04-28 2008-08-13
Copyright (c) 1999-2008 Igor Pavlov Copyright (c) 1999-2008 Igor Pavlov
Read LzmaEnc.h for license options */ Read LzmaEnc.h for license options */
#include <stdio.h>
#include <string.h> #include <string.h>
/* #define SHOW_STAT */
/* #define SHOW_STAT2 */
#if defined(SHOW_STAT) || defined(SHOW_STAT2)
#include <stdio.h>
#endif
#include "LzmaEnc.h" #include "LzmaEnc.h"
#include "LzFind.h" #include "LzFind.h"
@@ -13,9 +19,6 @@ Read LzmaEnc.h for license options */
#include "LzFindMt.h" #include "LzFindMt.h"
#endif #endif
/* #define SHOW_STAT */
/* #define SHOW_STAT2 */
#ifdef SHOW_STAT #ifdef SHOW_STAT
static int ttt = 0; static int ttt = 0;
#endif #endif
@@ -286,10 +289,9 @@ typedef struct _CLzmaEnc
UInt32 optimumEndIndex; UInt32 optimumEndIndex;
UInt32 optimumCurrentIndex; UInt32 optimumCurrentIndex;
Bool longestMatchWasFound;
UInt32 longestMatchLength; UInt32 longestMatchLength;
UInt32 numDistancePairs; UInt32 numPairs;
UInt32 numAvail;
COptimal opt[kNumOpts]; COptimal opt[kNumOpts];
#ifndef LZMA_LOG_BSR #ifndef LZMA_LOG_BSR
@@ -297,7 +299,7 @@ typedef struct _CLzmaEnc
#endif #endif
UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
UInt32 matchDistances[LZMA_MATCH_LEN_MAX * 2 + 2 + 1]; UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1];
UInt32 numFastBytes; UInt32 numFastBytes;
UInt32 additionalOffset; UInt32 additionalOffset;
UInt32 reps[LZMA_NUM_REPS]; UInt32 reps[LZMA_NUM_REPS];
@@ -462,16 +464,8 @@ static const int kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10,
static const int kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11}; static const int kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11}; static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
/*
void UpdateChar() { Index = kLiteralNextStates[Index]; }
void UpdateMatch() { Index = kMatchNextStates[Index]; }
void UpdateRep() { Index = kRepNextStates[Index]; }
void UpdateShortRep() { Index = kShortRepNextStates[Index]; }
*/
#define IsCharState(s) ((s) < 7) #define IsCharState(s) ((s) < 7)
#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1) #define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1)
#define kInfinityPrice (1 << 30) #define kInfinityPrice (1 << 30)
@@ -667,7 +661,7 @@ static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *Pro
} }
while (symbol < 0x10000); while (symbol < 0x10000);
return price; return price;
}; }
static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices) static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices)
{ {
@@ -683,14 +677,14 @@ static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt
} }
while (symbol < 0x10000); while (symbol < 0x10000);
return price; return price;
}; }
static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
{ {
UInt32 m = 1; UInt32 m = 1;
int i; int i;
for (i = numBitLevels; i != 0 ;) for (i = numBitLevels; i != 0;)
{ {
UInt32 bit; UInt32 bit;
i--; i--;
@@ -698,7 +692,7 @@ static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UIn
RangeEnc_EncodeBit(rc, probs + m, bit); RangeEnc_EncodeBit(rc, probs + m, bit);
m = (m << 1) | bit; m = (m << 1) | bit;
} }
}; }
static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
{ {
@@ -838,31 +832,28 @@ static void MovePos(CLzmaEnc *p, UInt32 num)
static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes) static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
{ {
UInt32 lenRes = 0, numDistancePairs; UInt32 lenRes = 0, numPairs;
numDistancePairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matchDistances); p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches);
#ifdef SHOW_STAT #ifdef SHOW_STAT
printf("\n i = %d numPairs = %d ", ttt, numDistancePairs / 2); printf("\n i = %d numPairs = %d ", ttt, numPairs / 2);
if (ttt >= 61994)
ttt = ttt;
ttt++; ttt++;
{ {
UInt32 i; UInt32 i;
for (i = 0; i < numDistancePairs; i += 2) for (i = 0; i < numPairs; i += 2)
printf("%2d %6d | ", p->matchDistances[i], p->matchDistances[i + 1]); printf("%2d %6d | ", p->matches[i], p->matches[i + 1]);
} }
#endif #endif
if (numDistancePairs > 0) if (numPairs > 0)
{ {
lenRes = p->matchDistances[numDistancePairs - 2]; lenRes = p->matches[numPairs - 2];
if (lenRes == p->numFastBytes) if (lenRes == p->numFastBytes)
{ {
UInt32 numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) + 1;
const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
UInt32 distance = p->matchDistances[numDistancePairs - 1] + 1; UInt32 distance = p->matches[numPairs - 1] + 1;
UInt32 numAvail = p->numAvail;
if (numAvail > LZMA_MATCH_LEN_MAX) if (numAvail > LZMA_MATCH_LEN_MAX)
numAvail = LZMA_MATCH_LEN_MAX; numAvail = LZMA_MATCH_LEN_MAX;
{ {
const Byte *pby2 = pby - distance; const Byte *pby2 = pby - distance;
for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++); for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++);
@@ -870,7 +861,7 @@ static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
} }
} }
p->additionalOffset++; p->additionalOffset++;
*numDistancePairsRes = numDistancePairs; *numDistancePairsRes = numPairs;
return lenRes; return lenRes;
} }
@@ -954,19 +945,12 @@ static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
{ {
UInt32 numAvailableBytes, lenMain, numDistancePairs; UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, lenEnd, len, cur;
UInt32 matchPrice, repMatchPrice, normalMatchPrice;
UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS];
UInt32 *matches;
const Byte *data; const Byte *data;
UInt32 reps[LZMA_NUM_REPS]; Byte curByte, matchByte;
UInt32 repLens[LZMA_NUM_REPS];
UInt32 repMaxIndex, i;
UInt32 *matchDistances;
Byte currentByte, matchByte;
UInt32 posState;
UInt32 matchPrice, repMatchPrice;
UInt32 lenEnd;
UInt32 len;
UInt32 normalMatchPrice;
UInt32 cur;
if (p->optimumEndIndex != p->optimumCurrentIndex) if (p->optimumEndIndex != p->optimumCurrentIndex)
{ {
const COptimal *opt = &p->opt[p->optimumCurrentIndex]; const COptimal *opt = &p->opt[p->optimumCurrentIndex];
@@ -977,28 +961,24 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
} }
p->optimumCurrentIndex = p->optimumEndIndex = 0; p->optimumCurrentIndex = p->optimumEndIndex = 0;
numAvailableBytes = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); if (p->additionalOffset == 0)
mainLen = ReadMatchDistances(p, &numPairs);
if (!p->longestMatchWasFound)
{
lenMain = ReadMatchDistances(p, &numDistancePairs);
}
else else
{ {
lenMain = p->longestMatchLength; mainLen = p->longestMatchLength;
numDistancePairs = p->numDistancePairs; numPairs = p->numPairs;
p->longestMatchWasFound = False;
} }
data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; numAvail = p->numAvail;
if (numAvailableBytes < 2) if (numAvail < 2)
{ {
*backRes = (UInt32)(-1); *backRes = (UInt32)(-1);
return 1; return 1;
} }
if (numAvailableBytes > LZMA_MATCH_LEN_MAX) if (numAvail > LZMA_MATCH_LEN_MAX)
numAvailableBytes = LZMA_MATCH_LEN_MAX; numAvail = LZMA_MATCH_LEN_MAX;
data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
repMaxIndex = 0; repMaxIndex = 0;
for (i = 0; i < LZMA_NUM_REPS; i++) for (i = 0; i < LZMA_NUM_REPS; i++)
{ {
@@ -1011,7 +991,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
repLens[i] = 0; repLens[i] = 0;
continue; continue;
} }
for (lenTest = 2; lenTest < numAvailableBytes && data[lenTest] == data2[lenTest]; lenTest++); for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);
repLens[i] = lenTest; repLens[i] = lenTest;
if (lenTest > repLens[repMaxIndex]) if (lenTest > repLens[repMaxIndex])
repMaxIndex = i; repMaxIndex = i;
@@ -1025,17 +1005,17 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
return lenRes; return lenRes;
} }
matchDistances = p->matchDistances; matches = p->matches;
if (lenMain >= p->numFastBytes) if (mainLen >= p->numFastBytes)
{ {
*backRes = matchDistances[numDistancePairs - 1] + LZMA_NUM_REPS; *backRes = matches[numPairs - 1] + LZMA_NUM_REPS;
MovePos(p, lenMain - 1); MovePos(p, mainLen - 1);
return lenMain; return mainLen;
} }
currentByte = *data; curByte = *data;
matchByte = *(data - (reps[0] + 1)); matchByte = *(data - (reps[0] + 1));
if (lenMain < 2 && currentByte != matchByte && repLens[repMaxIndex] < 2) if (mainLen < 2 && curByte != matchByte && repLens[repMaxIndex] < 2)
{ {
*backRes = (UInt32)-1; *backRes = (UInt32)-1;
return 1; return 1;
@@ -1049,8 +1029,8 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) + p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) +
(!IsCharState(p->state) ? (!IsCharState(p->state) ?
LitEnc_GetPriceMatched(probs, currentByte, matchByte, p->ProbPrices) : LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) :
LitEnc_GetPrice(probs, currentByte, p->ProbPrices)); LitEnc_GetPrice(probs, curByte, p->ProbPrices));
} }
MakeAsChar(&p->opt[1]); MakeAsChar(&p->opt[1]);
@@ -1058,7 +1038,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]); matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]);
repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]); repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]);
if (matchByte == currentByte) if (matchByte == curByte)
{ {
UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState); UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState);
if (shortRepPrice < p->opt[1].price) if (shortRepPrice < p->opt[1].price)
@@ -1067,7 +1047,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
MakeAsShortRep(&p->opt[1]); MakeAsShortRep(&p->opt[1]);
} }
} }
lenEnd = ((lenMain >= repLens[repMaxIndex]) ? lenMain : repLens[repMaxIndex]); lenEnd = ((mainLen >= repLens[repMaxIndex]) ? mainLen : repLens[repMaxIndex]);
if (lenEnd < 2) if (lenEnd < 2)
{ {
@@ -1109,15 +1089,15 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]); normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]);
len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2); len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);
if (len <= lenMain) if (len <= mainLen)
{ {
UInt32 offs = 0; UInt32 offs = 0;
while (len > matchDistances[offs]) while (len > matches[offs])
offs += 2; offs += 2;
for (; ; len++) for (; ; len++)
{ {
COptimal *opt; COptimal *opt;
UInt32 distance = matchDistances[offs + 1]; UInt32 distance = matches[offs + 1];
UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN]; UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN];
UInt32 lenToPosState = GetLenToPosState(len); UInt32 lenToPosState = GetLenToPosState(len);
@@ -1137,10 +1117,10 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
opt->backPrev = distance + LZMA_NUM_REPS; opt->backPrev = distance + LZMA_NUM_REPS;
opt->prev1IsChar = False; opt->prev1IsChar = False;
} }
if (len == matchDistances[offs]) if (len == matches[offs])
{ {
offs += 2; offs += 2;
if (offs == numDistancePairs) if (offs == numPairs)
break; break;
} }
} }
@@ -1160,32 +1140,23 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
for (;;) for (;;)
{ {
UInt32 numAvailableBytesFull, newLen, numDistancePairs; UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen;
COptimal *curOpt; UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice;
UInt32 posPrev;
UInt32 state;
UInt32 curPrice;
Bool nextIsChar; Bool nextIsChar;
Byte curByte, matchByte;
const Byte *data; const Byte *data;
Byte currentByte, matchByte; COptimal *curOpt;
UInt32 posState;
UInt32 curAnd1Price;
COptimal *nextOpt; COptimal *nextOpt;
UInt32 matchPrice, repMatchPrice;
UInt32 numAvailableBytes;
UInt32 startLen;
cur++; cur++;
if (cur == lenEnd) if (cur == lenEnd)
return Backward(p, backRes, cur); return Backward(p, backRes, cur);
numAvailableBytesFull = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); newLen = ReadMatchDistances(p, &numPairs);
newLen = ReadMatchDistances(p, &numDistancePairs);
if (newLen >= p->numFastBytes) if (newLen >= p->numFastBytes)
{ {
p->numDistancePairs = numDistancePairs; p->numPairs = numPairs;
p->longestMatchLength = newLen; p->longestMatchLength = newLen;
p->longestMatchWasFound = True;
return Backward(p, backRes, cur); return Backward(p, backRes, cur);
} }
position++; position++;
@@ -1261,7 +1232,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
curPrice = curOpt->price; curPrice = curOpt->price;
nextIsChar = False; nextIsChar = False;
data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
currentByte = *data; curByte = *data;
matchByte = *(data - (reps[0] + 1)); matchByte = *(data - (reps[0] + 1));
posState = (position & p->pbMask); posState = (position & p->pbMask);
@@ -1271,8 +1242,8 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
curAnd1Price += curAnd1Price +=
(!IsCharState(state) ? (!IsCharState(state) ?
LitEnc_GetPriceMatched(probs, currentByte, matchByte, p->ProbPrices) : LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) :
LitEnc_GetPrice(probs, currentByte, p->ProbPrices)); LitEnc_GetPrice(probs, curByte, p->ProbPrices));
} }
nextOpt = &p->opt[cur + 1]; nextOpt = &p->opt[cur + 1];
@@ -1288,7 +1259,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]); matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]);
repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]); repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]);
if (matchByte == currentByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0)) if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0))
{ {
UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState); UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState);
if (shortRepPrice <= nextOpt->price) if (shortRepPrice <= nextOpt->price)
@@ -1299,27 +1270,26 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
nextIsChar = True; nextIsChar = True;
} }
} }
numAvailFull = p->numAvail;
{ {
UInt32 temp = kNumOpts - 1 - cur; UInt32 temp = kNumOpts - 1 - cur;
if (temp < numAvailableBytesFull) if (temp < numAvailFull)
numAvailableBytesFull = temp; numAvailFull = temp;
} }
numAvailableBytes = numAvailableBytesFull;
if (numAvailableBytes < 2) if (numAvailFull < 2)
continue; continue;
if (numAvailableBytes > p->numFastBytes) numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes);
numAvailableBytes = p->numFastBytes;
if (!nextIsChar && matchByte != currentByte) /* speed optimization */ if (!nextIsChar && matchByte != curByte) /* speed optimization */
{ {
/* try Literal + rep0 */ /* try Literal + rep0 */
UInt32 temp; UInt32 temp;
UInt32 lenTest2; UInt32 lenTest2;
const Byte *data2 = data - (reps[0] + 1); const Byte *data2 = data - (reps[0] + 1);
UInt32 limit = p->numFastBytes + 1; UInt32 limit = p->numFastBytes + 1;
if (limit > numAvailableBytesFull) if (limit > numAvailFull)
limit = numAvailableBytesFull; limit = numAvailFull;
for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++); for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++);
lenTest2 = temp - 1; lenTest2 = temp - 1;
@@ -1362,7 +1332,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
const Byte *data2 = data - (reps[repIndex] + 1); const Byte *data2 = data - (reps[repIndex] + 1);
if (data[0] != data2[0] || data[1] != data2[1]) if (data[0] != data2[0] || data[1] != data2[1])
continue; continue;
for (lenTest = 2; lenTest < numAvailableBytes && data[lenTest] == data2[lenTest]; lenTest++); for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);
while (lenEnd < cur + lenTest) while (lenEnd < cur + lenTest)
p->opt[++lenEnd].price = kInfinityPrice; p->opt[++lenEnd].price = kInfinityPrice;
lenTestTemp = lenTest; lenTestTemp = lenTest;
@@ -1390,8 +1360,8 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
UInt32 lenTest2 = lenTest + 1; UInt32 lenTest2 = lenTest + 1;
UInt32 limit = lenTest2 + p->numFastBytes; UInt32 limit = lenTest2 + p->numFastBytes;
UInt32 nextRepMatchPrice; UInt32 nextRepMatchPrice;
if (limit > numAvailableBytesFull) if (limit > numAvailFull)
limit = numAvailableBytesFull; limit = numAvailFull;
for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
lenTest2 -= lenTest + 1; lenTest2 -= lenTest + 1;
if (lenTest2 >= 2) if (lenTest2 >= 2)
@@ -1434,12 +1404,12 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
} }
} }
/* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */ /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */
if (newLen > numAvailableBytes) if (newLen > numAvail)
{ {
newLen = numAvailableBytes; newLen = numAvail;
for (numDistancePairs = 0; newLen > matchDistances[numDistancePairs]; numDistancePairs += 2); for (numPairs = 0; newLen > matches[numPairs]; numPairs += 2);
matchDistances[numDistancePairs] = newLen; matches[numPairs] = newLen;
numDistancePairs += 2; numPairs += 2;
} }
if (newLen >= startLen) if (newLen >= startLen)
{ {
@@ -1450,9 +1420,9 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
p->opt[++lenEnd].price = kInfinityPrice; p->opt[++lenEnd].price = kInfinityPrice;
offs = 0; offs = 0;
while (startLen > matchDistances[offs]) while (startLen > matches[offs])
offs += 2; offs += 2;
curBack = matchDistances[offs + 1]; curBack = matches[offs + 1];
GetPosSlot2(curBack, posSlot); GetPosSlot2(curBack, posSlot);
for (lenTest = /*2*/ startLen; ; lenTest++) for (lenTest = /*2*/ startLen; ; lenTest++)
{ {
@@ -1473,15 +1443,15 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
opt->prev1IsChar = False; opt->prev1IsChar = False;
} }
if (/*_maxMode && */lenTest == matchDistances[offs]) if (/*_maxMode && */lenTest == matches[offs])
{ {
/* Try Match + Literal + Rep0 */ /* Try Match + Literal + Rep0 */
const Byte *data2 = data - (curBack + 1); const Byte *data2 = data - (curBack + 1);
UInt32 lenTest2 = lenTest + 1; UInt32 lenTest2 = lenTest + 1;
UInt32 limit = lenTest2 + p->numFastBytes; UInt32 limit = lenTest2 + p->numFastBytes;
UInt32 nextRepMatchPrice; UInt32 nextRepMatchPrice;
if (limit > numAvailableBytesFull) if (limit > numAvailFull)
limit = numAvailableBytesFull; limit = numAvailFull;
for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
lenTest2 -= lenTest + 1; lenTest2 -= lenTest + 1;
if (lenTest2 >= 2) if (lenTest2 >= 2)
@@ -1520,9 +1490,9 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
} }
} }
offs += 2; offs += 2;
if (offs == numDistancePairs) if (offs == numPairs)
break; break;
curBack = matchDistances[offs + 1]; curBack = matches[offs + 1];
if (curBack >= kNumFullDistances) if (curBack >= kNumFullDistances)
GetPosSlot2(curBack, posSlot); GetPosSlot2(curBack, posSlot);
} }
@@ -1535,136 +1505,110 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes) static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
{ {
UInt32 numAvailableBytes = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); UInt32 numAvail, mainLen, mainDist, numPairs, repIndex, repLen, i;
UInt32 lenMain, numDistancePairs;
const Byte *data; const Byte *data;
UInt32 repLens[LZMA_NUM_REPS]; const UInt32 *matches;
UInt32 repMaxIndex, i;
UInt32 *matchDistances;
UInt32 backMain;
if (!p->longestMatchWasFound) if (p->additionalOffset == 0)
{ mainLen = ReadMatchDistances(p, &numPairs);
lenMain = ReadMatchDistances(p, &numDistancePairs);
}
else else
{ {
lenMain = p->longestMatchLength; mainLen = p->longestMatchLength;
numDistancePairs = p->numDistancePairs; numPairs = p->numPairs;
p->longestMatchWasFound = False;
} }
data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; numAvail = p->numAvail;
if (numAvailableBytes > LZMA_MATCH_LEN_MAX) *backRes = (UInt32)-1;
numAvailableBytes = LZMA_MATCH_LEN_MAX; if (numAvail < 2)
if (numAvailableBytes < 2)
{
*backRes = (UInt32)(-1);
return 1; return 1;
} if (numAvail > LZMA_MATCH_LEN_MAX)
numAvail = LZMA_MATCH_LEN_MAX;
repMaxIndex = 0; data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
repLen = repIndex = 0;
for (i = 0; i < LZMA_NUM_REPS; i++) for (i = 0; i < LZMA_NUM_REPS; i++)
{ {
const Byte *data2 = data - (p->reps[i] + 1);
UInt32 len; UInt32 len;
const Byte *data2 = data - (p->reps[i] + 1);
if (data[0] != data2[0] || data[1] != data2[1]) if (data[0] != data2[0] || data[1] != data2[1])
{
repLens[i] = 0;
continue; continue;
} for (len = 2; len < numAvail && data[len] == data2[len]; len++);
for (len = 2; len < numAvailableBytes && data[len] == data2[len]; len++);
if (len >= p->numFastBytes) if (len >= p->numFastBytes)
{ {
*backRes = i; *backRes = i;
MovePos(p, len - 1); MovePos(p, len - 1);
return len; return len;
} }
repLens[i] = len; if (len > repLen)
if (len > repLens[repMaxIndex])
repMaxIndex = i;
}
matchDistances = p->matchDistances;
if (lenMain >= p->numFastBytes)
{ {
*backRes = matchDistances[numDistancePairs - 1] + LZMA_NUM_REPS; repIndex = i;
MovePos(p, lenMain - 1); repLen = len;
return lenMain; }
} }
backMain = 0; /* for GCC */ matches = p->matches;
if (lenMain >= 2) if (mainLen >= p->numFastBytes)
{ {
backMain = matchDistances[numDistancePairs - 1]; *backRes = matches[numPairs - 1] + LZMA_NUM_REPS;
while (numDistancePairs > 2 && lenMain == matchDistances[numDistancePairs - 4] + 1) MovePos(p, mainLen - 1);
return mainLen;
}
mainDist = 0; /* for GCC */
if (mainLen >= 2)
{ {
if (!ChangePair(matchDistances[numDistancePairs - 3], backMain)) mainDist = matches[numPairs - 1];
while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1)
{
if (!ChangePair(matches[numPairs - 3], mainDist))
break; break;
numDistancePairs -= 2; numPairs -= 2;
lenMain = matchDistances[numDistancePairs - 2]; mainLen = matches[numPairs - 2];
backMain = matchDistances[numDistancePairs - 1]; mainDist = matches[numPairs - 1];
} }
if (lenMain == 2 && backMain >= 0x80) if (mainLen == 2 && mainDist >= 0x80)
lenMain = 1; mainLen = 1;
} }
if (repLens[repMaxIndex] >= 2) if (repLen >= 2 && (
(repLen + 1 >= mainLen) ||
(repLen + 2 >= mainLen && mainDist >= (1 << 9)) ||
(repLen + 3 >= mainLen && mainDist >= (1 << 15))))
{ {
if (repLens[repMaxIndex] + 1 >= lenMain || *backRes = repIndex;
(repLens[repMaxIndex] + 2 >= lenMain && (backMain > (1 << 9))) || MovePos(p, repLen - 1);
(repLens[repMaxIndex] + 3 >= lenMain && (backMain > (1 << 15)))) return repLen;
{
UInt32 lenRes;
*backRes = repMaxIndex;
lenRes = repLens[repMaxIndex];
MovePos(p, lenRes - 1);
return lenRes;
}
} }
if (lenMain >= 2 && numAvailableBytes > 2) if (mainLen < 2 || numAvail <= 2)
{ return 1;
UInt32 i;
numAvailableBytes = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); p->longestMatchLength = ReadMatchDistances(p, &p->numPairs);
p->longestMatchLength = ReadMatchDistances(p, &p->numDistancePairs);
if (p->longestMatchLength >= 2) if (p->longestMatchLength >= 2)
{ {
UInt32 newDistance = matchDistances[p->numDistancePairs - 1]; UInt32 newDistance = matches[p->numPairs - 1];
if ((p->longestMatchLength >= lenMain && newDistance < backMain) || if ((p->longestMatchLength >= mainLen && newDistance < mainDist) ||
(p->longestMatchLength == lenMain + 1 && !ChangePair(backMain, newDistance)) || (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) ||
(p->longestMatchLength > lenMain + 1) || (p->longestMatchLength > mainLen + 1) ||
(p->longestMatchLength + 1 >= lenMain && lenMain >= 3 && ChangePair(newDistance, backMain))) (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist)))
{
p->longestMatchWasFound = True;
*backRes = (UInt32)(-1);
return 1; return 1;
} }
}
data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
for (i = 0; i < LZMA_NUM_REPS; i++) for (i = 0; i < LZMA_NUM_REPS; i++)
{ {
UInt32 len; UInt32 len, limit;
const Byte *data2 = data - (p->reps[i] + 1); const Byte *data2 = data - (p->reps[i] + 1);
if (data[1] != data2[1] || data[2] != data2[2]) if (data[0] != data2[0] || data[1] != data2[1])
{
repLens[i] = 0;
continue; continue;
} limit = mainLen - 1;
for (len = 2; len < numAvailableBytes && data[len] == data2[len]; len++); for (len = 2; len < limit && data[len] == data2[len]; len++);
if (len + 1 >= lenMain) if (len >= limit)
{
p->longestMatchWasFound = True;
*backRes = (UInt32)(-1);
return 1; return 1;
} }
} *backRes = mainDist + LZMA_NUM_REPS;
*backRes = backMain + LZMA_NUM_REPS; MovePos(p, mainLen - 2);
MovePos(p, lenMain - 2); return mainLen;
return lenMain;
}
*backRes = (UInt32)(-1);
return 1;
} }
static void WriteEndMarker(CLzmaEnc *p, UInt32 posState) static void WriteEndMarker(CLzmaEnc *p, UInt32 posState)
@@ -1822,11 +1766,11 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
if (p->nowPos64 == 0) if (p->nowPos64 == 0)
{ {
UInt32 numDistancePairs; UInt32 numPairs;
Byte curByte; Byte curByte;
if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
return Flush(p, nowPos32); return Flush(p, nowPos32);
ReadMatchDistances(p, &numDistancePairs); ReadMatchDistances(p, &numPairs);
RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0); RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0);
p->state = kLiteralNextStates[p->state]; p->state = kLiteralNextStates[p->state];
curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset); curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset);
@@ -1850,7 +1794,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
#endif #endif
posState = nowPos32 & p->pbMask; posState = nowPos32 & p->pbMask;
if (len == 1 && pos == 0xFFFFFFFF) if (len == 1 && pos == (UInt32)-1)
{ {
Byte curByte; Byte curByte;
CLzmaProb *probs; CLzmaProb *probs;
@@ -2068,7 +2012,6 @@ void LzmaEnc_Init(CLzmaEnc *p)
for (i = 0; i < (1 << kNumAlignBits); i++) for (i = 0; i < (1 << kNumAlignBits); i++)
p->posAlignEncoder[i] = kProbInitValue; p->posAlignEncoder[i] = kProbInitValue;
p->longestMatchWasFound = False;
p->optimumEndIndex = 0; p->optimumEndIndex = 0;
p->optimumCurrentIndex = 0; p->optimumCurrentIndex = 0;
p->additionalOffset = 0; p->additionalOffset = 0;

View File

@@ -1,5 +1,5 @@
/* LzmaEnc.h -- LZMA Encoder /* LzmaEnc.h -- LZMA Encoder
2008-04-27 2008-08-05
Copyright (c) 1999-2008 Igor Pavlov Copyright (c) 1999-2008 Igor Pavlov
Read LzFind.h for license options */ Read LzFind.h for license options */

View File

@@ -1,5 +1,5 @@
/* LzmaLib.c -- LZMA library wrapper /* LzmaLib.c -- LZMA library wrapper
2008-04-07 2008-08-05
Igor Pavlov Igor Pavlov
Public domain */ Public domain */

View File

@@ -1,5 +1,5 @@
/* LzmaLib.h -- LZMA library interface /* LzmaLib.h -- LZMA library interface
2008-04-11 2008-08-05
Igor Pavlov Igor Pavlov
Public domain */ Public domain */

View File

@@ -1,5 +1,5 @@
/* Lzma86Dec.h -- LZMA + x86 (BCJ) Filter Decoder /* Lzma86Dec.h -- LZMA + x86 (BCJ) Filter Decoder
2008-04-07 2008-08-05
Igor Pavlov Igor Pavlov
Public domain */ Public domain */

View File

@@ -1,5 +1,5 @@
/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder /* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder
2008-04-07 2008-08-05
Igor Pavlov Igor Pavlov
Public domain */ Public domain */

View File

@@ -1,5 +1,5 @@
/* Lzma86Enc.h -- LZMA + x86 (BCJ) Filter Encoder /* Lzma86Enc.h -- LZMA + x86 (BCJ) Filter Encoder
2008-04-07 2008-08-05
Igor Pavlov Igor Pavlov
Public domain */ Public domain */

View File

@@ -1,5 +1,5 @@
/* LzmaUtil.c -- Test application for LZMA compression /* LzmaUtil.c -- Test application for LZMA compression
2008-04-29 2008-08-05
Igor Pavlov Igor Pavlov
public domain */ public domain */

View File

@@ -1,5 +1,5 @@
/* RotateDefs.h -- Rotate functions /* RotateDefs.h -- Rotate functions
2008-03-24 2008-08-05
Igor Pavlov Igor Pavlov
Public domain */ Public domain */

View File

@@ -1,5 +1,5 @@
/* Crypto/Sha256.c -- SHA-256 Hash function /* Crypto/Sha256.c -- SHA-256 Hash function
2008-03-24 2008-08-05
This code is based on public domain code from Wei Dai's Crypto++ library. This code is based on public domain code from Wei Dai's Crypto++ library.
Igor Pavlov Igor Pavlov
Public domain */ Public domain */

View File

@@ -1,5 +1,5 @@
/* Crypto/Sha256.h -- SHA-256 Hash function /* Crypto/Sha256.h -- SHA-256 Hash function
2008-03-24 2008-08-05
Igor Pavlov Igor Pavlov
Public domain */ Public domain */

View File

@@ -1,5 +1,5 @@
/* Threads.c -- multithreading library /* Threads.c -- multithreading library
2008-04-04 2008-08-05
Igor Pavlov Igor Pavlov
Public domain */ Public domain */

View File

@@ -1,5 +1,5 @@
/* Types.h -- Basic types /* Types.h -- Basic types
2008-04-11 2008-08-05
Igor Pavlov Igor Pavlov
Public domain */ Public domain */

640
CPP/7zip/Archive/7z/7z.dsp Executable file
View File

@@ -0,0 +1,640 @@
# Microsoft Developer Studio Project File - Name="7z" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=7z - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "7z.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "7z.mak" CFG="7z - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "7z - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "7z - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "7z - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 1
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /c
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "COMPRESS_MT" /D "EXTERNAL_CODECS" /Yu"StdAfx.h" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-zip\Formats\7z.dll" /opt:NOWIN98
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "7z - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 1
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "COMPRESS_MT" /D "EXTERNAL_CODECS" /Yu"StdAfx.h" /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x419 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-zip\Formats\7z.dll" /pdbtype:sept
!ENDIF
# Begin Target
# Name "7z - Win32 Release"
# Name "7z - Win32 Debug"
# Begin Group "Spec"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\Archive.def
# End Source File
# Begin Source File
SOURCE=..\ArchiveExports.cpp
# End Source File
# Begin Source File
SOURCE=..\DllExports.cpp
# End Source File
# Begin Source File
SOURCE=.\resource.rc
# End Source File
# Begin Source File
SOURCE=.\StdAfx.cpp
# ADD CPP /Yc"StdAfx.h"
# End Source File
# Begin Source File
SOURCE=.\StdAfx.h
# End Source File
# End Group
# Begin Group "Engine"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\7zCompressionMode.cpp
# End Source File
# Begin Source File
SOURCE=.\7zCompressionMode.h
# End Source File
# Begin Source File
SOURCE=.\7zDecode.cpp
# End Source File
# Begin Source File
SOURCE=.\7zDecode.h
# End Source File
# Begin Source File
SOURCE=.\7zEncode.cpp
# End Source File
# Begin Source File
SOURCE=.\7zEncode.h
# End Source File
# Begin Source File
SOURCE=.\7zExtract.cpp
# End Source File
# Begin Source File
SOURCE=.\7zFolderInStream.cpp
# End Source File
# Begin Source File
SOURCE=.\7zFolderInStream.h
# End Source File
# Begin Source File
SOURCE=.\7zFolderOutStream.cpp
# End Source File
# Begin Source File
SOURCE=.\7zFolderOutStream.h
# End Source File
# Begin Source File
SOURCE=.\7zHandler.cpp
# End Source File
# Begin Source File
SOURCE=.\7zHandler.h
# End Source File
# Begin Source File
SOURCE=.\7zHandlerOut.cpp
# End Source File
# Begin Source File
SOURCE=.\7zHeader.cpp
# End Source File
# Begin Source File
SOURCE=.\7zHeader.h
# End Source File
# Begin Source File
SOURCE=.\7zIn.cpp
# End Source File
# Begin Source File
SOURCE=.\7zIn.h
# End Source File
# Begin Source File
SOURCE=.\7zItem.h
# End Source File
# Begin Source File
SOURCE=.\7zOut.cpp
# End Source File
# Begin Source File
SOURCE=.\7zOut.h
# End Source File
# Begin Source File
SOURCE=.\7zProperties.cpp
# End Source File
# Begin Source File
SOURCE=.\7zProperties.h
# End Source File
# Begin Source File
SOURCE=.\7zRegister.cpp
# End Source File
# Begin Source File
SOURCE=.\7zSpecStream.cpp
# End Source File
# Begin Source File
SOURCE=.\7zSpecStream.h
# End Source File
# Begin Source File
SOURCE=.\7zUpdate.cpp
# End Source File
# Begin Source File
SOURCE=.\7zUpdate.h
# End Source File
# End Group
# Begin Group "Interface"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\IArchive.h
# End Source File
# Begin Source File
SOURCE=..\..\ICoder.h
# End Source File
# Begin Source File
SOURCE=..\..\IMyUnknown.h
# End Source File
# Begin Source File
SOURCE=..\..\IPassword.h
# End Source File
# Begin Source File
SOURCE=..\..\IProgress.h
# End Source File
# Begin Source File
SOURCE=..\..\IStream.h
# End Source File
# Begin Source File
SOURCE=..\..\PropID.h
# End Source File
# End Group
# Begin Group "Common"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\..\Common\Buffer.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\CRC.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\DynamicBuffer.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\IntToString.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\IntToString.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\MyString.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\MyString.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\MyVector.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\MyVector.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\NewHandler.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\NewHandler.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\StringConvert.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\StringConvert.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\StringToInt.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\StringToInt.h
# End Source File
# End Group
# Begin Group "Archive Common"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\Common\CoderMixer2.cpp
# End Source File
# Begin Source File
SOURCE=..\Common\CoderMixer2.h
# End Source File
# Begin Source File
SOURCE=..\Common\CoderMixer2MT.cpp
# End Source File
# Begin Source File
SOURCE=..\Common\CoderMixer2MT.h
# End Source File
# Begin Source File
SOURCE=..\Common\CrossThreadProgress.cpp
# End Source File
# Begin Source File
SOURCE=..\Common\CrossThreadProgress.h
# End Source File
# Begin Source File
SOURCE=..\Common\HandlerOut.cpp
# End Source File
# Begin Source File
SOURCE=..\Common\HandlerOut.h
# End Source File
# Begin Source File
SOURCE=..\Common\InStreamWithCRC.cpp
# End Source File
# Begin Source File
SOURCE=..\Common\InStreamWithCRC.h
# End Source File
# Begin Source File
SOURCE=..\Common\ItemNameUtils.cpp
# End Source File
# Begin Source File
SOURCE=..\Common\ItemNameUtils.h
# End Source File
# Begin Source File
SOURCE=..\Common\MultiStream.cpp
# End Source File
# Begin Source File
SOURCE=..\Common\MultiStream.h
# End Source File
# Begin Source File
SOURCE=..\Common\OutStreamWithCRC.cpp
# End Source File
# Begin Source File
SOURCE=..\Common\OutStreamWithCRC.h
# End Source File
# Begin Source File
SOURCE=..\Common\ParseProperties.cpp
# End Source File
# Begin Source File
SOURCE=..\Common\ParseProperties.h
# End Source File
# End Group
# Begin Group "7-Zip Common"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\Common\CreateCoder.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Common\CreateCoder.h
# End Source File
# Begin Source File
SOURCE=..\..\Common\FilterCoder.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Common\FilterCoder.h
# End Source File
# Begin Source File
SOURCE=..\..\Common\InOutTempBuffer.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Common\InOutTempBuffer.h
# End Source File
# Begin Source File
SOURCE=..\..\Common\LimitedStreams.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Common\LimitedStreams.h
# End Source File
# Begin Source File
SOURCE=..\..\Common\LockedStream.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Common\LockedStream.h
# End Source File
# Begin Source File
SOURCE=..\..\Common\MethodId.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Common\MethodId.h
# End Source File
# Begin Source File
SOURCE=..\..\Common\MethodProps.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Common\MethodProps.h
# End Source File
# Begin Source File
SOURCE=..\..\Common\OutBuffer.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Common\OutBuffer.h
# End Source File
# Begin Source File
SOURCE=..\..\Common\ProgressUtils.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Common\ProgressUtils.h
# End Source File
# Begin Source File
SOURCE=..\..\Common\RegisterArc.h
# End Source File
# Begin Source File
SOURCE=..\..\Common\RegisterCodec.h
# End Source File
# Begin Source File
SOURCE=..\..\Common\StreamBinder.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Common\StreamBinder.h
# End Source File
# Begin Source File
SOURCE=..\..\Common\StreamObjects.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Common\StreamObjects.h
# End Source File
# Begin Source File
SOURCE=..\..\Common\StreamUtils.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Common\StreamUtils.h
# End Source File
# Begin Source File
SOURCE=..\..\Common\VirtThread.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Common\VirtThread.h
# End Source File
# End Group
# Begin Group "Windows"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\..\Windows\DLL.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\DLL.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\FileDir.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\FileDir.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\FileFind.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\FileFind.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\FileIO.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\FileIO.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\FileName.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\Handle.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\PropVariant.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\PropVariant.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\Synchronization.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\Synchronization.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\System.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\System.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\Thread.h
# End Source File
# End Group
# Begin Group "Compress"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\Compress\Copy\CopyCoder.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Compress\Copy\CopyCoder.h
# End Source File
# End Group
# Begin Group "C"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\..\..\C\7zCrc.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\7zCrc.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Alloc.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Alloc.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Threads.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Threads.h
# End Source File
# End Group
# End Target
# End Project

29
CPP/7zip/Archive/7z/7z.dsw Executable file
View File

@@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "7z"=".\7z.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

@@ -98,13 +98,16 @@ HRESULT CDecoder::Decode(
ISequentialOutStream *outStream, ISequentialOutStream *outStream,
ICompressProgressInfo *compressProgress ICompressProgressInfo *compressProgress
#ifndef _NO_CRYPTO #ifndef _NO_CRYPTO
, ICryptoGetTextPassword *getTextPassword , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
#endif #endif
#ifdef COMPRESS_MT #ifdef COMPRESS_MT
, bool mtMode, UInt32 numThreads , bool mtMode, UInt32 numThreads
#endif #endif
) )
{ {
#ifndef _NO_CRYPTO
passwordIsDefined = false;
#endif
CObjectVector< CMyComPtr<ISequentialInStream> > inStreams; CObjectVector< CMyComPtr<ISequentialInStream> > inStreams;
CLockedInStream lockedInStream; CLockedInStream lockedInStream;
@@ -212,7 +215,7 @@ HRESULT CDecoder::Decode(
int i; int i;
_mixerCoderCommon->ReInit(); _mixerCoderCommon->ReInit();
UInt32 packStreamIndex = 0, unPackStreamIndex = 0; UInt32 packStreamIndex = 0, unpackStreamIndex = 0;
UInt32 coderIndex = 0; UInt32 coderIndex = 0;
// UInt32 coder2Index = 0; // UInt32 coder2Index = 0;
@@ -257,20 +260,20 @@ HRESULT CDecoder::Decode(
{ {
if (getTextPassword == 0) if (getTextPassword == 0)
return E_FAIL; return E_FAIL;
CMyComBSTR password; CMyComBSTR passwordBSTR;
RINOK(getTextPassword->CryptoGetTextPassword(&password)); RINOK(getTextPassword->CryptoGetTextPassword(&passwordBSTR));
CByteBuffer buffer; CByteBuffer buffer;
UString unicodePassword(password); passwordIsDefined = true;
const UInt32 sizeInBytes = unicodePassword.Length() * 2; UString password = passwordBSTR;
const UInt32 sizeInBytes = password.Length() * 2;
buffer.SetCapacity(sizeInBytes); buffer.SetCapacity(sizeInBytes);
for (int i = 0; i < unicodePassword.Length(); i++) for (int i = 0; i < password.Length(); i++)
{ {
wchar_t c = unicodePassword[i]; wchar_t c = password[i];
((Byte *)buffer)[i * 2] = (Byte)c; ((Byte *)buffer)[i * 2] = (Byte)c;
((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8); ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
} }
RINOK(cryptoSetPassword->CryptoSetPassword( RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, sizeInBytes));
(const Byte *)buffer, sizeInBytes));
} }
} }
#endif #endif
@@ -280,19 +283,19 @@ HRESULT CDecoder::Decode(
UInt32 numInStreams = (UInt32)coderInfo.NumInStreams; UInt32 numInStreams = (UInt32)coderInfo.NumInStreams;
UInt32 numOutStreams = (UInt32)coderInfo.NumOutStreams; UInt32 numOutStreams = (UInt32)coderInfo.NumOutStreams;
CRecordVector<const UInt64 *> packSizesPointers; CRecordVector<const UInt64 *> packSizesPointers;
CRecordVector<const UInt64 *> unPackSizesPointers; CRecordVector<const UInt64 *> unpackSizesPointers;
packSizesPointers.Reserve(numInStreams); packSizesPointers.Reserve(numInStreams);
unPackSizesPointers.Reserve(numOutStreams); unpackSizesPointers.Reserve(numOutStreams);
UInt32 j; UInt32 j;
for (j = 0; j < numOutStreams; j++, unPackStreamIndex++) for (j = 0; j < numOutStreams; j++, unpackStreamIndex++)
unPackSizesPointers.Add(&folderInfo.UnPackSizes[unPackStreamIndex]); unpackSizesPointers.Add(&folderInfo.UnpackSizes[unpackStreamIndex]);
for (j = 0; j < numInStreams; j++, packStreamIndex++) for (j = 0; j < numInStreams; j++, packStreamIndex++)
{ {
int bindPairIndex = folderInfo.FindBindPairForInStream(packStreamIndex); int bindPairIndex = folderInfo.FindBindPairForInStream(packStreamIndex);
if (bindPairIndex >= 0) if (bindPairIndex >= 0)
packSizesPointers.Add( packSizesPointers.Add(
&folderInfo.UnPackSizes[(UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex]); &folderInfo.UnpackSizes[(UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex]);
else else
{ {
int index = folderInfo.FindPackStreamArrayIndex(packStreamIndex); int index = folderInfo.FindPackStreamArrayIndex(packStreamIndex);
@@ -304,7 +307,7 @@ HRESULT CDecoder::Decode(
_mixerCoderCommon->SetCoderInfo(i, _mixerCoderCommon->SetCoderInfo(i,
&packSizesPointers.Front(), &packSizesPointers.Front(),
&unPackSizesPointers.Front()); &unpackSizesPointers.Front());
} }
UInt32 mainCoder, temp; UInt32 mainCoder, temp;
bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp); bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp);

View File

@@ -55,7 +55,7 @@ public:
ISequentialOutStream *outStream, ISequentialOutStream *outStream,
ICompressProgressInfo *compressProgress ICompressProgressInfo *compressProgress
#ifndef _NO_CRYPTO #ifndef _NO_CRYPTO
, ICryptoGetTextPassword *getTextPasswordSpec , ICryptoGetTextPassword *getTextPasswordSpec, bool &passwordIsDefined
#endif #endif
#ifdef COMPRESS_MT #ifdef COMPRESS_MT
, bool mtMode, UInt32 numThreads , bool mtMode, UInt32 numThreads

View File

@@ -275,7 +275,7 @@ HRESULT CEncoder::Encode(
streamSize = inStreamSizeCountSpec->GetSize(); streamSize = inStreamSizeCountSpec->GetSize();
else else
streamSize = _mixerCoderSpec->GetWriteProcessedSize(binder); streamSize = _mixerCoderSpec->GetWriteProcessedSize(binder);
folderItem.UnPackSizes.Add(streamSize); folderItem.UnpackSizes.Add(streamSize);
} }
for (i = numMethods - 1; i >= 0; i--) for (i = numMethods - 1; i >= 0; i--)
folderItem.Coders[numMethods - 1 - i].Properties = _codersInfo[i].Properties; folderItem.Coders[numMethods - 1 - i].Properties = _codersInfo[i].Properties;

View File

@@ -23,7 +23,7 @@ struct CExtractFolderInfo
CNum FileIndex; CNum FileIndex;
CNum FolderIndex; CNum FolderIndex;
CBoolVector ExtractStatuses; CBoolVector ExtractStatuses;
UInt64 UnPackSize; UInt64 UnpackSize;
CExtractFolderInfo( CExtractFolderInfo(
#ifdef _7Z_VOL #ifdef _7Z_VOL
int volumeIndex, int volumeIndex,
@@ -34,7 +34,7 @@ struct CExtractFolderInfo
#endif #endif
FileIndex(fileIndex), FileIndex(fileIndex),
FolderIndex(folderIndex), FolderIndex(folderIndex),
UnPackSize(0) UnpackSize(0)
{ {
if (fileIndex != kNumNoIndex) if (fileIndex != kNumNoIndex)
{ {
@@ -50,7 +50,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
COM_TRY_BEGIN COM_TRY_BEGIN
bool testMode = (testModeSpec != 0); bool testMode = (testModeSpec != 0);
CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec; CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
UInt64 importantTotalUnPacked = 0; UInt64 importantTotalUnpacked = 0;
bool allFilesMode = (numItems == UInt32(-1)); bool allFilesMode = (numItems == UInt32(-1));
if (allFilesMode) if (allFilesMode)
@@ -58,7 +58,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
#ifdef _7Z_VOL #ifdef _7Z_VOL
_refs.Size(); _refs.Size();
#else #else
_database.Files.Size(); _db.Files.Size();
#endif #endif
if(numItems == 0) if(numItems == 0)
@@ -68,7 +68,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
if(_volumes.Size() != 1) if(_volumes.Size() != 1)
return E_FAIL; return E_FAIL;
const CVolume &volume = _volumes.Front(); const CVolume &volume = _volumes.Front();
const CArchiveDatabaseEx &_database = volume.Database; const CArchiveDatabaseEx &_db = volume.Database;
IInStream *_inStream = volume.Stream; IInStream *_inStream = volume.Stream;
*/ */
@@ -87,14 +87,14 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
int volumeIndex = ref.VolumeIndex; int volumeIndex = ref.VolumeIndex;
const CVolume &volume = _volumes[volumeIndex]; const CVolume &volume = _volumes[volumeIndex];
const CArchiveDatabaseEx &database = volume.Database; const CArchiveDatabaseEx &db = volume.Database;
UInt32 fileIndex = ref.ItemIndex; UInt32 fileIndex = ref.ItemIndex;
#else #else
const CArchiveDatabaseEx &database = _database; const CArchiveDatabaseEx &db = _db;
UInt32 fileIndex = ref2Index; UInt32 fileIndex = ref2Index;
#endif #endif
CNum folderIndex = database.FileIndexToFolderIndexMap[fileIndex]; CNum folderIndex = db.FileIndexToFolderIndexMap[fileIndex];
if (folderIndex == kNumNoIndex) if (folderIndex == kNumNoIndex)
{ {
extractFolderInfoVector.Add(CExtractFolderInfo( extractFolderInfoVector.Add(CExtractFolderInfo(
@@ -116,29 +116,29 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
volumeIndex, volumeIndex,
#endif #endif
kNumNoIndex, folderIndex)); kNumNoIndex, folderIndex));
const CFolder &folderInfo = database.Folders[folderIndex]; const CFolder &folderInfo = db.Folders[folderIndex];
UInt64 unPackSize = folderInfo.GetUnPackSize(); UInt64 unpackSize = folderInfo.GetUnpackSize();
importantTotalUnPacked += unPackSize; importantTotalUnpacked += unpackSize;
extractFolderInfoVector.Back().UnPackSize = unPackSize; extractFolderInfoVector.Back().UnpackSize = unpackSize;
} }
CExtractFolderInfo &efi = extractFolderInfoVector.Back(); CExtractFolderInfo &efi = extractFolderInfoVector.Back();
// const CFolderInfo &folderInfo = m_dam_Folders[folderIndex]; // const CFolderInfo &folderInfo = m_dam_Folders[folderIndex];
CNum startIndex = database.FolderStartFileIndex[folderIndex]; CNum startIndex = db.FolderStartFileIndex[folderIndex];
for (CNum index = efi.ExtractStatuses.Size(); for (CNum index = efi.ExtractStatuses.Size();
index <= fileIndex - startIndex; index++) index <= fileIndex - startIndex; index++)
{ {
// UInt64 unPackSize = _database.Files[startIndex + index].UnPackSize; // UInt64 unpackSize = _db.Files[startIndex + index].UnpackSize;
// Count partial_folder_size // Count partial_folder_size
// efi.UnPackSize += unPackSize; // efi.UnpackSize += unpackSize;
// importantTotalUnPacked += unPackSize; // importantTotalUnpacked += unpackSize;
efi.ExtractStatuses.Add(index == fileIndex - startIndex); efi.ExtractStatuses.Add(index == fileIndex - startIndex);
} }
} }
} }
extractCallback->SetTotal(importantTotalUnPacked); extractCallback->SetTotal(importantTotalUnpacked);
CDecoder decoder( CDecoder decoder(
#ifdef _ST_MODE #ifdef _ST_MODE
@@ -150,8 +150,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
// CDecoder1 decoder; // CDecoder1 decoder;
UInt64 currentTotalPacked = 0; UInt64 currentTotalPacked = 0;
UInt64 currentTotalUnPacked = 0; UInt64 currentTotalUnpacked = 0;
UInt64 totalFolderUnPacked; UInt64 totalFolderUnpacked;
UInt64 totalFolderPacked; UInt64 totalFolderPacked;
CLocalProgress *lps = new CLocalProgress; CLocalProgress *lps = new CLocalProgress;
@@ -159,15 +159,15 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
lps->Init(extractCallback, false); lps->Init(extractCallback, false);
for(int i = 0; i < extractFolderInfoVector.Size(); i++, for(int i = 0; i < extractFolderInfoVector.Size(); i++,
currentTotalUnPacked += totalFolderUnPacked, currentTotalUnpacked += totalFolderUnpacked,
currentTotalPacked += totalFolderPacked) currentTotalPacked += totalFolderPacked)
{ {
lps->OutSize = currentTotalUnPacked; lps->OutSize = currentTotalUnpacked;
lps->InSize = currentTotalPacked; lps->InSize = currentTotalPacked;
RINOK(lps->SetCur()); RINOK(lps->SetCur());
const CExtractFolderInfo &efi = extractFolderInfoVector[i]; const CExtractFolderInfo &efi = extractFolderInfoVector[i];
totalFolderUnPacked = efi.UnPackSize; totalFolderUnpacked = efi.UnpackSize;
totalFolderPacked = 0; totalFolderPacked = 0;
@@ -176,19 +176,19 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
#ifdef _7Z_VOL #ifdef _7Z_VOL
const CVolume &volume = _volumes[efi.VolumeIndex]; const CVolume &volume = _volumes[efi.VolumeIndex];
const CArchiveDatabaseEx &database = volume.Database; const CArchiveDatabaseEx &db = volume.Database;
#else #else
const CArchiveDatabaseEx &database = _database; const CArchiveDatabaseEx &db = _db;
#endif #endif
CNum startIndex; CNum startIndex;
if (efi.FileIndex != kNumNoIndex) if (efi.FileIndex != kNumNoIndex)
startIndex = efi.FileIndex; startIndex = efi.FileIndex;
else else
startIndex = database.FolderStartFileIndex[efi.FolderIndex]; startIndex = db.FolderStartFileIndex[efi.FolderIndex];
HRESULT result = folderOutStream->Init(&database, HRESULT result = folderOutStream->Init(&db,
#ifdef _7Z_VOL #ifdef _7Z_VOL
volume.StartRef2Index, volume.StartRef2Index,
#else #else
@@ -203,12 +203,12 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
continue; continue;
CNum folderIndex = efi.FolderIndex; CNum folderIndex = efi.FolderIndex;
const CFolder &folderInfo = database.Folders[folderIndex]; const CFolder &folderInfo = db.Folders[folderIndex];
totalFolderPacked = _database.GetFolderFullPackSize(folderIndex); totalFolderPacked = _db.GetFolderFullPackSize(folderIndex);
CNum packStreamIndex = database.FolderStartPackStreamIndex[folderIndex]; CNum packStreamIndex = db.FolderStartPackStreamIndex[folderIndex];
UInt64 folderStartPackPos = database.GetFolderStreamPos(folderIndex, 0); UInt64 folderStartPackPos = db.GetFolderStreamPos(folderIndex, 0);
#ifndef _NO_CRYPTO #ifndef _NO_CRYPTO
CMyComPtr<ICryptoGetTextPassword> getTextPassword; CMyComPtr<ICryptoGetTextPassword> getTextPassword;
@@ -218,6 +218,10 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
try try
{ {
#ifndef _NO_CRYPTO
bool passwordIsDefined;
#endif
HRESULT result = decoder.Decode( HRESULT result = decoder.Decode(
EXTERNAL_CODECS_VARS EXTERNAL_CODECS_VARS
#ifdef _7Z_VOL #ifdef _7Z_VOL
@@ -226,12 +230,12 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
_inStream, _inStream,
#endif #endif
folderStartPackPos, folderStartPackPos,
&database.PackSizes[packStreamIndex], &db.PackSizes[packStreamIndex],
folderInfo, folderInfo,
outStream, outStream,
progress progress
#ifndef _NO_CRYPTO #ifndef _NO_CRYPTO
, getTextPassword , getTextPassword, passwordIsDefined
#endif #endif
#ifdef COMPRESS_MT #ifdef COMPRESS_MT
, true, _numThreads , true, _numThreads

View File

@@ -56,8 +56,8 @@ HRESULT CFolderOutStream::OpenFile()
if (askMode == NArchive::NExtract::NAskMode::kExtract && if (askMode == NArchive::NExtract::NAskMode::kExtract &&
(!realOutStream)) (!realOutStream))
{ {
const CFileItem &fileInfo = _archiveDatabase->Files[index]; const CFileItem &fi = _archiveDatabase->Files[index];
if (!fileInfo.IsAnti && !fileInfo.IsDirectory) if (!_archiveDatabase->IsItemAnti(index) && !fi.IsDir)
askMode = NArchive::NExtract::NAskMode::kSkip; askMode = NArchive::NExtract::NAskMode::kSkip;
} }
return _extractCallback->PrepareOperation(askMode); return _extractCallback->PrepareOperation(askMode);
@@ -68,12 +68,11 @@ HRESULT CFolderOutStream::WriteEmptyFiles()
for(;_currentIndex < _extractStatuses->Size(); _currentIndex++) for(;_currentIndex < _extractStatuses->Size(); _currentIndex++)
{ {
UInt32 index = _startIndex + _currentIndex; UInt32 index = _startIndex + _currentIndex;
const CFileItem &fileInfo = _archiveDatabase->Files[index]; const CFileItem &fi = _archiveDatabase->Files[index];
if (!fileInfo.IsAnti && !fileInfo.IsDirectory && fileInfo.UnPackSize != 0) if (!_archiveDatabase->IsItemAnti(index) && !fi.IsDir && fi.Size != 0)
return S_OK; return S_OK;
RINOK(OpenFile()); RINOK(OpenFile());
RINOK(_extractCallback->SetOperationResult( RINOK(_extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
NArchive::NExtract::NOperationResult::kOK));
_outStreamWithHashSpec->ReleaseStream(); _outStreamWithHashSpec->ReleaseStream();
} }
return S_OK; return S_OK;
@@ -88,8 +87,8 @@ STDMETHODIMP CFolderOutStream::Write(const void *data,
if (_fileIsOpen) if (_fileIsOpen)
{ {
UInt32 index = _startIndex + _currentIndex; UInt32 index = _startIndex + _currentIndex;
const CFileItem &fileInfo = _archiveDatabase->Files[index]; const CFileItem &fi = _archiveDatabase->Files[index];
UInt64 fileSize = fileInfo.UnPackSize; UInt64 fileSize = fi.Size;
UInt32 numBytesToWrite = (UInt32)MyMin(fileSize - _filePos, UInt32 numBytesToWrite = (UInt32)MyMin(fileSize - _filePos,
UInt64(size - realProcessedSize)); UInt64(size - realProcessedSize));
@@ -103,8 +102,8 @@ STDMETHODIMP CFolderOutStream::Write(const void *data,
if (_filePos == fileSize) if (_filePos == fileSize)
{ {
bool digestsAreEqual; bool digestsAreEqual;
if (fileInfo.IsFileCRCDefined && _checkCrc) if (fi.CrcDefined && _checkCrc)
digestsAreEqual = fileInfo.FileCRC == _outStreamWithHashSpec->GetCRC(); digestsAreEqual = fi.Crc == _outStreamWithHashSpec->GetCRC();
else else
digestsAreEqual = true; digestsAreEqual = true;

View File

@@ -10,9 +10,6 @@
#include "../../../Windows/Defs.h" #include "../../../Windows/Defs.h"
#include "../Common/ItemNameUtils.h" #include "../Common/ItemNameUtils.h"
#ifdef _7Z_VOL
#include "../Common/MultiStream.h"
#endif
#ifdef __7Z_SET_PROPERTIES #ifdef __7Z_SET_PROPERTIES
#ifdef EXTRACT_ONLY #ifdef EXTRACT_ONLY
@@ -35,9 +32,13 @@ CHandler::CHandler()
{ {
_crcSize = 4; _crcSize = 4;
#ifndef _NO_CRYPTO
_passwordIsDefined = false;
#endif
#ifdef EXTRACT_ONLY #ifdef EXTRACT_ONLY
#ifdef COMPRESS_MT #ifdef COMPRESS_MT
_numThreads = NWindows::NSystem::GetNumberOfProcessors(); _numThreads = NSystem::GetNumberOfProcessors();
#endif #endif
#else #else
Init(); Init();
@@ -46,12 +47,7 @@ CHandler::CHandler()
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{ {
*numItems = *numItems = _db.Files.Size();
#ifdef _7Z_VOL
_refs.Size();
#else
*numItems = _database.Files.Size();
#endif
return S_OK; return S_OK;
} }
@@ -77,13 +73,16 @@ STATPROPSTG kArcProps[] =
{ {
{ NULL, kpidMethod, VT_BSTR}, { NULL, kpidMethod, VT_BSTR},
{ NULL, kpidSolid, VT_BOOL}, { NULL, kpidSolid, VT_BOOL},
{ NULL, kpidNumBlocks, VT_UI4} { NULL, kpidNumBlocks, VT_UI4},
{ NULL, kpidPhySize, VT_UI8},
{ NULL, kpidHeadersSize, VT_UI8},
{ NULL, kpidOffset, VT_UI8}
}; };
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop; NCOM::CPropVariant prop;
switch(propID) switch(propID)
{ {
case kpidMethod: case kpidMethod:
@@ -91,9 +90,9 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
UString resString; UString resString;
CRecordVector<UInt64> ids; CRecordVector<UInt64> ids;
int i; int i;
for (i = 0; i < _database.Folders.Size(); i++) for (i = 0; i < _db.Folders.Size(); i++)
{ {
const CFolder &f = _database.Folders[i]; const CFolder &f = _db.Folders[i];
for (int j = f.Coders.Size() - 1; j >= 0; j--) for (int j = f.Coders.Size() - 1; j >= 0; j--)
ids.AddToUniqueSorted(f.Coders[j].MethodID); ids.AddToUniqueSorted(f.Coders[j].MethodID);
} }
@@ -112,8 +111,11 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
prop = resString; prop = resString;
break; break;
} }
case kpidSolid: prop = _database.IsSolid(); break; case kpidSolid: prop = _db.IsSolid(); break;
case kpidNumBlocks: prop = (UInt32)_database.Folders.Size(); break; case kpidNumBlocks: prop = (UInt32)_db.Folders.Size(); break;
case kpidHeadersSize: prop = _db.HeadersSize; break;
case kpidPhySize: prop = _db.PhySize; break;
case kpidOffset: if (_db.ArchiveInfo.StartPosition != 0) prop = _db.ArchiveInfo.StartPosition; break;
} }
prop.Detach(value); prop.Detach(value);
return S_OK; return S_OK;
@@ -124,10 +126,16 @@ IMP_IInArchive_ArcProps
#endif #endif
static void MySetFileTime(bool timeDefined, FILETIME unixTime, NWindows::NCOM::CPropVariant &prop) static void SetPropFromUInt64Def(CUInt64DefVector &v, int index, NCOM::CPropVariant &prop)
{ {
if (timeDefined) UInt64 value;
prop = unixTime; if (v.GetItem(index, value))
{
FILETIME ft;
ft.dwLowDateTime = (DWORD)value;
ft.dwHighDateTime = (DWORD)(value >> 32);
prop = ft;
}
} }
#ifndef _SFX #ifndef _SFX
@@ -192,10 +200,10 @@ static inline UInt32 GetUInt32FromMemLE(const Byte *p)
bool CHandler::IsEncrypted(UInt32 index2) const bool CHandler::IsEncrypted(UInt32 index2) const
{ {
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2]; CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
if (folderIndex != kNumNoIndex) if (folderIndex != kNumNoIndex)
{ {
const CFolder &folderInfo = _database.Folders[folderIndex]; const CFolder &folderInfo = _db.Folders[folderIndex];
for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--) for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--)
if (folderInfo.Coders[i].MethodID == k_AES) if (folderInfo.Coders[i].MethodID == k_AES)
return true; return true;
@@ -206,7 +214,7 @@ bool CHandler::IsEncrypted(UInt32 index2) const
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop; NCOM::CPropVariant prop;
/* /*
const CRef2 &ref2 = _refs[index]; const CRef2 &ref2 = _refs[index];
@@ -215,54 +223,31 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
const CRef &ref = ref2.Refs.Front(); const CRef &ref = ref2.Refs.Front();
*/ */
#ifdef _7Z_VOL const CFileItem &item = _db.Files[index];
const CRef &ref = _refs[index];
const CVolume &volume = _volumes[ref.VolumeIndex];
const CArchiveDatabaseEx &_database = volume.Database;
UInt32 index2 = ref.ItemIndex;
const CFileItem &item = _database.Files[index2];
#else
const CFileItem &item = _database.Files[index];
UInt32 index2 = index; UInt32 index2 = index;
#endif
switch(propID) switch(propID)
{ {
case kpidPath: case kpidPath:
{
if (!item.Name.IsEmpty()) if (!item.Name.IsEmpty())
prop = NItemName::GetOSName(item.Name); prop = NItemName::GetOSName(item.Name);
break; break;
} case kpidIsDir: prop = item.IsDir; break;
case kpidIsFolder:
prop = item.IsDirectory;
break;
case kpidSize: case kpidSize:
{ {
prop = item.UnPackSize; prop = item.Size;
// prop = ref2.UnPackSize; // prop = ref2.Size;
break; break;
} }
case kpidPosition: case kpidPackSize:
{
/*
if (ref2.Refs.Size() > 1)
prop = ref2.StartPos;
else
*/
if (item.IsStartPosDefined)
prop = item.StartPos;
break;
}
case kpidPackedSize:
{ {
// prop = ref2.PackSize; // prop = ref2.PackSize;
{ {
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2]; CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
if (folderIndex != kNumNoIndex) if (folderIndex != kNumNoIndex)
{ {
if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2) if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2)
prop = _database.GetFolderFullPackSize(folderIndex); prop = _db.GetFolderFullPackSize(folderIndex);
/* /*
else else
prop = (UInt64)0; prop = (UInt64)0;
@@ -273,35 +258,21 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
} }
break; break;
} }
case kpidLastAccessTime: case kpidPosition: { UInt64 v; if (_db.StartPos.GetItem(index2, v)) prop = v; break; }
MySetFileTime(item.IsLastAccessTimeDefined, item.LastAccessTime, prop); case kpidCTime: SetPropFromUInt64Def(_db.CTime, index2, prop); break;
break; case kpidATime: SetPropFromUInt64Def(_db.ATime, index2, prop); break;
case kpidCreationTime: case kpidMTime: SetPropFromUInt64Def(_db.MTime, index2, prop); break;
MySetFileTime(item.IsCreationTimeDefined, item.CreationTime, prop); case kpidAttrib: if (item.AttribDefined) prop = item.Attrib; break;
break; case kpidCRC: if (item.CrcDefined) prop = item.Crc; break;
case kpidLastWriteTime: case kpidEncrypted: prop = IsEncrypted(index2); break;
MySetFileTime(item.IsLastWriteTimeDefined, item.LastWriteTime, prop); case kpidIsAnti: prop = _db.IsItemAnti(index2); break;
break;
case kpidAttributes:
if (item.AreAttributesDefined)
prop = item.Attributes;
break;
case kpidCRC:
if (item.IsFileCRCDefined)
prop = item.FileCRC;
break;
case kpidEncrypted:
{
prop = IsEncrypted(index2);
break;
}
#ifndef _SFX #ifndef _SFX
case kpidMethod: case kpidMethod:
{ {
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2]; CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
if (folderIndex != kNumNoIndex) if (folderIndex != kNumNoIndex)
{ {
const CFolder &folderInfo = _database.Folders[folderIndex]; const CFolder &folderInfo = _db.Folders[folderIndex];
UString methodsString; UString methodsString;
for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--) for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--)
{ {
@@ -398,7 +369,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
break; break;
case kpidBlock: case kpidBlock:
{ {
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2]; CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
if (folderIndex != kNumNoIndex) if (folderIndex != kNumNoIndex)
prop = (UInt32)folderIndex; prop = (UInt32)folderIndex;
} }
@@ -409,14 +380,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
case kpidPackedSize3: case kpidPackedSize3:
case kpidPackedSize4: case kpidPackedSize4:
{ {
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2]; CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
if (folderIndex != kNumNoIndex) if (folderIndex != kNumNoIndex)
{ {
const CFolder &folderInfo = _database.Folders[folderIndex]; const CFolder &folderInfo = _db.Folders[folderIndex];
if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2 && if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2 &&
folderInfo.PackStreams.Size() > (int)(propID - kpidPackedSize0)) folderInfo.PackStreams.Size() > (int)(propID - kpidPackedSize0))
{ {
prop = _database.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0); prop = _db.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0);
} }
else else
prop = (UInt64)0; prop = (UInt64)0;
@@ -426,95 +397,12 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
} }
break; break;
#endif #endif
case kpidIsAnti:
prop = item.IsAnti;
break;
} }
prop.Detach(value); prop.Detach(value);
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END
} }
#ifdef _7Z_VOL
static const wchar_t *kExt = L"7z";
static const wchar_t *kAfterPart = L".7z";
class CVolumeName
{
bool _first;
UString _unchangedPart;
UString _changedPart;
UString _afterPart;
public:
bool InitName(const UString &name)
{
_first = true;
int dotPos = name.ReverseFind('.');
UString basePart = name;
if (dotPos >= 0)
{
UString ext = name.Mid(dotPos + 1);
if (ext.CompareNoCase(kExt)==0 ||
ext.CompareNoCase(L"EXE") == 0)
{
_afterPart = kAfterPart;
basePart = name.Left(dotPos);
}
}
int numLetters = 1;
bool splitStyle = false;
if (basePart.Right(numLetters) == L"1")
{
while (numLetters < basePart.Length())
{
if (basePart[basePart.Length() - numLetters - 1] != '0')
break;
numLetters++;
}
}
else
return false;
_unchangedPart = basePart.Left(basePart.Length() - numLetters);
_changedPart = basePart.Right(numLetters);
return true;
}
UString GetNextName()
{
UString newName;
// if (_newStyle || !_first)
{
int i;
int numLetters = _changedPart.Length();
for (i = numLetters - 1; i >= 0; i--)
{
wchar_t c = _changedPart[i];
if (c == L'9')
{
c = L'0';
newName = c + newName;
if (i == 0)
newName = UString(L'1') + newName;
continue;
}
c++;
newName = UString(c) + newName;
i--;
for (; i >= 0; i--)
newName = _changedPart[i] + newName;
break;
}
_changedPart = newName;
}
_first = false;
return _unchangedPart + _changedPart + _afterPart;
}
};
#endif
STDMETHODIMP CHandler::Open(IInStream *stream, STDMETHODIMP CHandler::Open(IInStream *stream,
const UInt64 *maxCheckStartPosition, const UInt64 *maxCheckStartPosition,
IArchiveOpenCallback *openArchiveCallback) IArchiveOpenCallback *openArchiveCallback)
@@ -527,11 +415,6 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
try try
{ {
CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = openArchiveCallback; CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = openArchiveCallback;
#ifdef _7Z_VOL
CVolumeName seqName;
CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
#endif
#ifndef _NO_CRYPTO #ifndef _NO_CRYPTO
CMyComPtr<ICryptoGetTextPassword> getTextPassword; CMyComPtr<ICryptoGetTextPassword> getTextPassword;
@@ -541,127 +424,22 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
IID_ICryptoGetTextPassword, &getTextPassword); IID_ICryptoGetTextPassword, &getTextPassword);
} }
#endif #endif
#ifdef _7Z_VOL
if (openArchiveCallback)
{
openArchiveCallbackTemp.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback);
}
for (;;)
{
CMyComPtr<IInStream> inStream;
if (!_volumes.IsEmpty())
{
if (!openVolumeCallback)
break;
if(_volumes.Size() == 1)
{
UString baseName;
{
NCOM::CPropVariant prop;
RINOK(openVolumeCallback->GetProperty(kpidName, &prop));
if (prop.vt != VT_BSTR)
break;
baseName = prop.bstrVal;
}
seqName.InitName(baseName);
}
UString fullName = seqName.GetNextName();
HRESULT result = openVolumeCallback->GetStream(fullName, &inStream);
if (result == S_FALSE)
break;
if (result != S_OK)
return result;
if (!stream)
break;
}
else
inStream = stream;
CInArchive archive;
RINOK(archive.Open(inStream, maxCheckStartPosition));
_volumes.Add(CVolume());
CVolume &volume = _volumes.Back();
CArchiveDatabaseEx &database = volume.Database;
volume.Stream = inStream;
volume.StartRef2Index = _refs.Size();
HRESULT result = archive.ReadDatabase(database
#ifndef _NO_CRYPTO
, getTextPassword
#endif
);
if (result != S_OK)
{
_volumes.Clear();
return result;
}
database.Fill();
for(int i = 0; i < database.Files.Size(); i++)
{
CRef refNew;
refNew.VolumeIndex = _volumes.Size() - 1;
refNew.ItemIndex = i;
_refs.Add(refNew);
/*
const CFileItem &file = database.Files[i];
int j;
*/
/*
for (j = _refs.Size() - 1; j >= 0; j--)
{
CRef2 &ref2 = _refs[j];
const CRef &ref = ref2.Refs.Back();
const CVolume &volume2 = _volumes[ref.VolumeIndex];
const CArchiveDatabaseEx &database2 = volume2.Database;
const CFileItem &file2 = database2.Files[ref.ItemIndex];
if (file2.Name.CompareNoCase(file.Name) == 0)
{
if (!file.IsStartPosDefined)
continue;
if (file.StartPos != ref2.StartPos + ref2.UnPackSize)
continue;
ref2.Refs.Add(refNew);
break;
}
}
*/
/*
j = -1;
if (j < 0)
{
CRef2 ref2New;
ref2New.Refs.Add(refNew);
j = _refs.Add(ref2New);
}
CRef2 &ref2 = _refs[j];
ref2.UnPackSize += file.UnPackSize;
ref2.PackSize += database.GetFilePackSize(i);
if (ref2.Refs.Size() == 1 && file.IsStartPosDefined)
ref2.StartPos = file.StartPos;
*/
}
if (database.Files.Size() != 1)
break;
const CFileItem &file = database.Files.Front();
if (!file.IsStartPosDefined)
break;
}
#else
CInArchive archive; CInArchive archive;
RINOK(archive.Open(stream, maxCheckStartPosition)); RINOK(archive.Open(stream, maxCheckStartPosition));
#ifndef _NO_CRYPTO
_passwordIsDefined = false;
UString password;
#endif
HRESULT result = archive.ReadDatabase( HRESULT result = archive.ReadDatabase(
EXTERNAL_CODECS_VARS EXTERNAL_CODECS_VARS
_database _db
#ifndef _NO_CRYPTO #ifndef _NO_CRYPTO
, getTextPassword , getTextPassword, _passwordIsDefined
#endif #endif
); );
RINOK(result); RINOK(result);
_database.Fill(); _db.Fill();
_inStream = stream; _inStream = stream;
#endif
} }
catch(...) catch(...)
{ {
@@ -679,75 +457,12 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
STDMETHODIMP CHandler::Close() STDMETHODIMP CHandler::Close()
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
#ifdef _7Z_VOL
_volumes.Clear();
_refs.Clear();
#else
_inStream.Release(); _inStream.Release();
_database.Clear(); _db.Clear();
#endif
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END
} }
#ifdef _7Z_VOL
STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
{
if (index != 0)
return E_INVALIDARG;
*stream = 0;
CMultiStream *streamSpec = new CMultiStream;
CMyComPtr<ISequentialInStream> streamTemp = streamSpec;
UInt64 pos = 0;
const UString *fileName;
for (int i = 0; i < _refs.Size(); i++)
{
const CRef &ref = _refs[i];
const CVolume &volume = _volumes[ref.VolumeIndex];
const CArchiveDatabaseEx &database = volume.Database;
const CFileItem &file = database.Files[ref.ItemIndex];
if (i == 0)
fileName = &file.Name;
else
if (fileName->Compare(file.Name) != 0)
return S_FALSE;
if (!file.IsStartPosDefined)
return S_FALSE;
if (file.StartPos != pos)
return S_FALSE;
CNum folderIndex = database.FileIndexToFolderIndexMap[ref.ItemIndex];
if (folderIndex == kNumNoIndex)
{
if (file.UnPackSize != 0)
return E_FAIL;
continue;
}
if (database.NumUnPackStreamsVector[folderIndex] != 1)
return S_FALSE;
const CFolder &folder = database.Folders[folderIndex];
if (folder.Coders.Size() != 1)
return S_FALSE;
const CCoderInfo &coder = folder.Coders.Front();
if (coder.NumInStreams != 1 || coder.NumOutStreams != 1)
return S_FALSE;
if (coder.MethodID != k_Copy)
return S_FALSE;
pos += file.UnPackSize;
CMultiStream::CSubStreamInfo subStreamInfo;
subStreamInfo.Stream = volume.Stream;
subStreamInfo.Pos = database.GetFolderStreamPos(folderIndex, 0);
subStreamInfo.Size = file.UnPackSize;
streamSpec->Streams.Add(subStreamInfo);
}
streamSpec->Init();
*stream = streamTemp.Detach();
return S_OK;
}
#endif
#ifdef __7Z_SET_PROPERTIES #ifdef __7Z_SET_PROPERTIES
#ifdef EXTRACT_ONLY #ifdef EXTRACT_ONLY

View File

@@ -18,21 +18,6 @@
namespace NArchive { namespace NArchive {
namespace N7z { namespace N7z {
#ifdef _7Z_VOL
struct CRef
{
int VolumeIndex;
int ItemIndex;
};
struct CVolume
{
int StartRef2Index;
CMyComPtr<IInStream> Stream;
CArchiveDatabaseEx Database;
};
#endif
#ifndef __7Z_SET_PROPERTIES #ifndef __7Z_SET_PROPERTIES
#ifdef EXTRACT_ONLY #ifdef EXTRACT_ONLY
@@ -51,9 +36,6 @@ class CHandler:
public NArchive::COutHandler, public NArchive::COutHandler,
#endif #endif
public IInArchive, public IInArchive,
#ifdef _7Z_VOL
public IInArchiveGetStream,
#endif
#ifdef __7Z_SET_PROPERTIES #ifdef __7Z_SET_PROPERTIES
public ISetProperties, public ISetProperties,
#endif #endif
@@ -65,9 +47,6 @@ class CHandler:
{ {
public: public:
MY_QUERYINTERFACE_BEGIN2(IInArchive) MY_QUERYINTERFACE_BEGIN2(IInArchive)
#ifdef _7Z_VOL
MY_QUERYINTERFACE_ENTRY(IInArchiveGetStream)
#endif
#ifdef __7Z_SET_PROPERTIES #ifdef __7Z_SET_PROPERTIES
MY_QUERYINTERFACE_ENTRY(ISetProperties) MY_QUERYINTERFACE_ENTRY(ISetProperties)
#endif #endif
@@ -80,10 +59,6 @@ public:
INTERFACE_IInArchive(;) INTERFACE_IInArchive(;)
#ifdef _7Z_VOL
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
#endif
#ifdef __7Z_SET_PROPERTIES #ifdef __7Z_SET_PROPERTIES
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties); STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties);
#endif #endif
@@ -97,12 +72,10 @@ public:
CHandler(); CHandler();
private: private:
#ifdef _7Z_VOL
CObjectVector<CVolume> _volumes;
CObjectVector<CRef> _refs;
#else
CMyComPtr<IInStream> _inStream; CMyComPtr<IInStream> _inStream;
NArchive::N7z::CArchiveDatabaseEx _database; NArchive::N7z::CArchiveDatabaseEx _db;
#ifndef _NO_CRYPTO
bool _passwordIsDefined;
#endif #endif
#ifdef EXTRACT_ONLY #ifdef EXTRACT_ONLY
@@ -139,6 +112,8 @@ private:
void FillPopIDs(); void FillPopIDs();
#endif #endif
DECL_EXTERNAL_CODECS_VARS
}; };
}} }}

View File

@@ -185,17 +185,20 @@ HRESULT CHandler::SetCompressionMethod(
return S_OK; return S_OK;
} }
static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, PROPID propID, CArchiveFileTime &filetime, bool &filetimeIsDefined) static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, bool writeTime, PROPID propID, UInt64 &ft, bool &ftDefined)
{ {
filetimeIsDefined = false; ft = 0;
NCOM::CPropVariant propVariant; ftDefined = false;
RINOK(updateCallback->GetProperty(index, propID, &propVariant)); if (!writeTime)
if (propVariant.vt == VT_FILETIME) return S_OK;
NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(index, propID, &prop));
if (prop.vt == VT_FILETIME)
{ {
filetime = propVariant.filetime; ft = prop.filetime.dwLowDateTime | ((UInt64)prop.filetime.dwHighDateTime << 32);
filetimeIsDefined = true; ftDefined = true;
} }
else if (propVariant.vt != VT_EMPTY) else if (prop.vt != VT_EMPTY)
return E_INVALIDARG; return E_INVALIDARG;
return S_OK; return S_OK;
} }
@@ -205,7 +208,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
const CArchiveDatabaseEx *database = 0; const CArchiveDatabaseEx *db = 0;
#ifdef _7Z_VOL #ifdef _7Z_VOL
if(_volumes.Size() > 1) if(_volumes.Size() > 1)
return E_FAIL; return E_FAIL;
@@ -213,139 +216,131 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (_volumes.Size() == 1) if (_volumes.Size() == 1)
{ {
volume = &_volumes.Front(); volume = &_volumes.Front();
database = &volume->Database; db = &volume->Database;
} }
#else #else
if (_inStream != 0) if (_inStream != 0)
database = &_database; db = &_db;
#endif #endif
// CRecordVector<bool> compressStatuses;
CObjectVector<CUpdateItem> updateItems; CObjectVector<CUpdateItem> updateItems;
// CRecordVector<UInt32> copyIndices;
// CMyComPtr<IUpdateCallback2> updateCallback2; for (UInt32 i = 0; i < numItems; i++)
// updateCallback->QueryInterface(&updateCallback2);
for(UInt32 i = 0; i < numItems; i++)
{ {
Int32 newData; Int32 newData;
Int32 newProperties; Int32 newProperties;
UInt32 indexInArchive; UInt32 indexInArchive;
if (!updateCallback) if (!updateCallback)
return E_FAIL; return E_FAIL;
RINOK(updateCallback->GetUpdateItemInfo(i, RINOK(updateCallback->GetUpdateItemInfo(i, &newData, &newProperties, &indexInArchive));
&newData, &newProperties, &indexInArchive)); CUpdateItem ui;
CUpdateItem updateItem; ui.NewProperties = IntToBool(newProperties);
updateItem.NewProperties = IntToBool(newProperties); ui.NewData = IntToBool(newData);
updateItem.NewData = IntToBool(newData); ui.IndexInArchive = indexInArchive;
updateItem.IndexInArchive = indexInArchive; ui.IndexInClient = i;
updateItem.IndexInClient = i; ui.IsAnti = false;
updateItem.IsAnti = false; ui.Size = 0;
updateItem.Size = 0;
if (updateItem.IndexInArchive != -1) if (ui.IndexInArchive != -1)
{ {
const CFileItem &fileItem = database->Files[updateItem.IndexInArchive]; const CFileItem &fi = db->Files[ui.IndexInArchive];
updateItem.Name = fileItem.Name; ui.Name = fi.Name;
updateItem.IsDirectory = fileItem.IsDirectory; ui.IsDir = fi.IsDir;
updateItem.Size = fileItem.UnPackSize; ui.Size = fi.Size;
updateItem.IsAnti = fileItem.IsAnti; ui.IsAnti = db->IsItemAnti(ui.IndexInArchive);
updateItem.CreationTime = fileItem.CreationTime; ui.CTimeDefined = db->CTime.GetItem(ui.IndexInArchive, ui.CTime);
updateItem.IsCreationTimeDefined = fileItem.IsCreationTimeDefined; ui.ATimeDefined = db->ATime.GetItem(ui.IndexInArchive, ui.ATime);
updateItem.LastWriteTime = fileItem.LastWriteTime; ui.MTimeDefined = db->MTime.GetItem(ui.IndexInArchive, ui.MTime);
updateItem.IsLastWriteTimeDefined = fileItem.IsLastWriteTimeDefined;
updateItem.LastAccessTime = fileItem.LastAccessTime;
updateItem.IsLastAccessTimeDefined = fileItem.IsLastAccessTimeDefined;
} }
if (updateItem.NewProperties) if (ui.NewProperties)
{ {
bool nameIsDefined; bool nameIsDefined;
bool folderStatusIsDefined; bool folderStatusIsDefined;
{ {
NCOM::CPropVariant propVariant; NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(i, kpidAttributes, &propVariant)); RINOK(updateCallback->GetProperty(i, kpidAttrib, &prop));
if (propVariant.vt == VT_EMPTY) if (prop.vt == VT_EMPTY)
updateItem.AttributesAreDefined = false; ui.AttribDefined = false;
else if (propVariant.vt != VT_UI4) else if (prop.vt != VT_UI4)
return E_INVALIDARG; return E_INVALIDARG;
else else
{ {
updateItem.Attributes = propVariant.ulVal; ui.Attrib = prop.ulVal;
updateItem.AttributesAreDefined = true; ui.AttribDefined = true;
} }
} }
RINOK(GetTime(updateCallback, i, kpidCreationTime, updateItem.CreationTime, updateItem.IsCreationTimeDefined)); // we need MTime to sort files.
RINOK(GetTime(updateCallback, i, kpidLastWriteTime, updateItem.LastWriteTime , updateItem.IsLastWriteTimeDefined)); RINOK(GetTime(updateCallback, i, WriteCTime, kpidCTime, ui.CTime, ui.CTimeDefined));
RINOK(GetTime(updateCallback, i, kpidLastAccessTime, updateItem.LastAccessTime, updateItem.IsLastAccessTimeDefined)); RINOK(GetTime(updateCallback, i, WriteATime, kpidATime, ui.ATime, ui.ATimeDefined));
RINOK(GetTime(updateCallback, i, true, kpidMTime, ui.MTime, ui.MTimeDefined));
{ {
NCOM::CPropVariant propVariant; NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(i, kpidPath, &propVariant)); RINOK(updateCallback->GetProperty(i, kpidPath, &prop));
if (propVariant.vt == VT_EMPTY) if (prop.vt == VT_EMPTY)
nameIsDefined = false; nameIsDefined = false;
else if (propVariant.vt != VT_BSTR) else if (prop.vt != VT_BSTR)
return E_INVALIDARG; return E_INVALIDARG;
else else
{ {
updateItem.Name = NItemName::MakeLegalName(propVariant.bstrVal); ui.Name = NItemName::MakeLegalName(prop.bstrVal);
nameIsDefined = true; nameIsDefined = true;
} }
} }
{ {
NCOM::CPropVariant propVariant; NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(i, kpidIsFolder, &propVariant)); RINOK(updateCallback->GetProperty(i, kpidIsDir, &prop));
if (propVariant.vt == VT_EMPTY) if (prop.vt == VT_EMPTY)
folderStatusIsDefined = false; folderStatusIsDefined = false;
else if (propVariant.vt != VT_BOOL) else if (prop.vt != VT_BOOL)
return E_INVALIDARG; return E_INVALIDARG;
else else
{ {
updateItem.IsDirectory = (propVariant.boolVal != VARIANT_FALSE); ui.IsDir = (prop.boolVal != VARIANT_FALSE);
folderStatusIsDefined = true; folderStatusIsDefined = true;
} }
} }
{ {
NCOM::CPropVariant propVariant; NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(i, kpidIsAnti, &propVariant)); RINOK(updateCallback->GetProperty(i, kpidIsAnti, &prop));
if (propVariant.vt == VT_EMPTY) if (prop.vt == VT_EMPTY)
updateItem.IsAnti = false; ui.IsAnti = false;
else if (propVariant.vt != VT_BOOL) else if (prop.vt != VT_BOOL)
return E_INVALIDARG; return E_INVALIDARG;
else else
updateItem.IsAnti = (propVariant.boolVal != VARIANT_FALSE); ui.IsAnti = (prop.boolVal != VARIANT_FALSE);
} }
if (updateItem.IsAnti) if (ui.IsAnti)
{ {
updateItem.AttributesAreDefined = false; ui.AttribDefined = false;
updateItem.IsCreationTimeDefined = false; ui.CTimeDefined = false;
updateItem.IsLastWriteTimeDefined = false; ui.ATimeDefined = false;
updateItem.IsLastAccessTimeDefined = false; ui.MTimeDefined = false;
updateItem.Size = 0; ui.Size = 0;
} }
if (!folderStatusIsDefined && updateItem.AttributesAreDefined) if (!folderStatusIsDefined && ui.AttribDefined)
updateItem.SetDirectoryStatusFromAttributes(); ui.SetDirStatusFromAttrib();
} }
if (updateItem.NewData) if (ui.NewData)
{ {
NCOM::CPropVariant propVariant; NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(i, kpidSize, &propVariant)); RINOK(updateCallback->GetProperty(i, kpidSize, &prop));
if (propVariant.vt != VT_UI8) if (prop.vt != VT_UI8)
return E_INVALIDARG; return E_INVALIDARG;
updateItem.Size = (UInt64)propVariant.uhVal.QuadPart; ui.Size = (UInt64)prop.uhVal.QuadPart;
if (updateItem.Size != 0 && updateItem.IsAnti) if (ui.Size != 0 && ui.IsAnti)
return E_INVALIDARG; return E_INVALIDARG;
} }
updateItems.Add(updateItem); updateItems.Add(ui);
} }
CCompressionMethodMode methodMode, headerMethod; CCompressionMethodMode methodMode, headerMethod;
@@ -359,10 +354,18 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
bool compressMainHeader = _compressHeaders; // check it bool compressMainHeader = _compressHeaders; // check it
bool encryptHeaders = false;
if (methodMode.PasswordIsDefined) if (methodMode.PasswordIsDefined)
{ {
if (_encryptHeadersSpecified)
encryptHeaders = _encryptHeaders;
#ifndef _NO_CRYPTO
else
encryptHeaders = _passwordIsDefined;
#endif
compressMainHeader = true; compressMainHeader = true;
if(_encryptHeaders) if(encryptHeaders)
RINOK(SetPassword(headerMethod, updateCallback)); RINOK(SetPassword(headerMethod, updateCallback));
} }
@@ -371,32 +374,42 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
CUpdateOptions options; CUpdateOptions options;
options.Method = &methodMode; options.Method = &methodMode;
options.HeaderMethod = (_compressHeaders || options.HeaderMethod = (_compressHeaders || encryptHeaders) ? &headerMethod : 0;
(methodMode.PasswordIsDefined && _encryptHeaders)) ?
&headerMethod : 0;
options.UseFilters = _level != 0 && _autoFilter; options.UseFilters = _level != 0 && _autoFilter;
options.MaxFilter = _level >= 8; options.MaxFilter = _level >= 8;
options.HeaderOptions.CompressMainHeader = compressMainHeader; options.HeaderOptions.CompressMainHeader = compressMainHeader;
options.HeaderOptions.WriteModified = WriteModified; options.HeaderOptions.WriteCTime = WriteCTime;
options.HeaderOptions.WriteCreated = WriteCreated; options.HeaderOptions.WriteATime = WriteATime;
options.HeaderOptions.WriteAccessed = WriteAccessed; options.HeaderOptions.WriteMTime = WriteMTime;
options.NumSolidFiles = _numSolidFiles; options.NumSolidFiles = _numSolidFiles;
options.NumSolidBytes = _numSolidBytes; options.NumSolidBytes = _numSolidBytes;
options.SolidExtension = _solidExtension; options.SolidExtension = _solidExtension;
options.RemoveSfxBlock = _removeSfxBlock; options.RemoveSfxBlock = _removeSfxBlock;
options.VolumeMode = _volumeMode; options.VolumeMode = _volumeMode;
return Update(
COutArchive archive;
CArchiveDatabase newDatabase;
HRESULT res = Update(
EXTERNAL_CODECS_VARS EXTERNAL_CODECS_VARS
#ifdef _7Z_VOL #ifdef _7Z_VOL
volume ? volume->Stream: 0, volume ? volume->Stream: 0,
volume ? database: 0, volume ? db : 0,
#else #else
_inStream, _inStream,
database, db,
#endif #endif
updateItems, outStream, updateCallback, options); updateItems,
archive, newDatabase, outStream, updateCallback, options);
RINOK(res);
updateItems.ClearAndFree();
return archive.WriteDatabase(EXTERNAL_CODECS_VARS
newDatabase, options.HeaderMethod, options.HeaderOptions);
COM_TRY_END COM_TRY_END
} }

View File

@@ -63,7 +63,7 @@ namespace NID
kFilesInfo, kFilesInfo,
kPackInfo, kPackInfo,
kUnPackInfo, kUnpackInfo,
kSubStreamsInfo, kSubStreamsInfo,
kSize, kSize,
@@ -71,23 +71,24 @@ namespace NID
kFolder, kFolder,
kCodersUnPackSize, kCodersUnpackSize,
kNumUnPackStream, kNumUnpackStream,
kEmptyStream, kEmptyStream,
kEmptyFile, kEmptyFile,
kAnti, kAnti,
kName, kName,
kCreationTime, kCTime,
kLastAccessTime, kATime,
kLastWriteTime, kMTime,
kWinAttributes, kWinAttributes,
kComment, kComment,
kEncodedHeader, kEncodedHeader,
kStartPos kStartPos,
kDummy
}; };
} }

View File

@@ -8,10 +8,14 @@
#include "../../Common/StreamUtils.h" #include "../../Common/StreamUtils.h"
extern "C" extern "C"
{ {
#include "../../../../C/7zCrc.h" #include "../../../../C/7zCrc.h"
#include "../../../../C/CpuArch.h" #include "../../../../C/CpuArch.h"
} }
#define Get16(p) GetUi16(p)
#define Get32(p) GetUi32(p)
#define Get64(p) GetUi64(p)
// define FORMAT_7Z_RECOVERY if you want to recover multivolume archives with empty StartHeader // define FORMAT_7Z_RECOVERY if you want to recover multivolume archives with empty StartHeader
#ifndef _SFX #ifndef _SFX
#define FORMAT_7Z_RECOVERY #define FORMAT_7Z_RECOVERY
@@ -97,16 +101,6 @@ void CStreamSwitch::Set(CInArchive *archive, const CObjectVector<CByteBuffer> *d
} }
} }
#ifdef LITTLE_ENDIAN_UNALIGN
static inline UInt16 GetUInt16FromMem(const Byte *p) { return *(const UInt16 *)p; }
static inline UInt32 GetUInt32FromMem(const Byte *p) { return *(const UInt32 *)p; }
static inline UInt64 GetUInt64FromMem(const Byte *p) { return *(const UInt64 *)p; }
#else
static inline UInt16 GetUInt16FromMem(const Byte *p) { return p[0] | ((UInt16)p[1] << 8); }
static inline UInt32 GetUInt32FromMem(const Byte *p) { return p[0] | ((UInt32)p[1] << 8) | ((UInt32)p[2] << 16) | ((UInt32)p[3] << 24); }
static inline UInt64 GetUInt64FromMem(const Byte *p) { return GetUInt32FromMem(p) | ((UInt64)GetUInt32FromMem(p + 4) << 32); }
#endif
Byte CInByte2::ReadByte() Byte CInByte2::ReadByte()
{ {
if (_pos >= _size) if (_pos >= _size)
@@ -126,6 +120,7 @@ void CInByte2::SkeepData(UInt64 size)
{ {
if (size > _size - _pos) if (size > _size - _pos)
ThrowEndOfData(); ThrowEndOfData();
_pos += (size_t)size;
} }
void CInByte2::SkeepData() void CInByte2::SkeepData()
@@ -168,7 +163,7 @@ UInt32 CInByte2::ReadUInt32()
{ {
if (_pos + 4 > _size) if (_pos + 4 > _size)
ThrowEndOfData(); ThrowEndOfData();
UInt32 res = GetUInt32FromMem(_buffer + _pos); UInt32 res = Get32(_buffer + _pos);
_pos += 4; _pos += 4;
return res; return res;
} }
@@ -177,7 +172,7 @@ UInt64 CInByte2::ReadUInt64()
{ {
if (_pos + 8 > _size) if (_pos + 8 > _size)
ThrowEndOfData(); ThrowEndOfData();
UInt64 res = GetUInt64FromMem(_buffer + _pos); UInt64 res = Get64(_buffer + _pos);
_pos += 8; _pos += 8;
return res; return res;
} }
@@ -201,8 +196,7 @@ void CInByte2::ReadString(UString &s)
wchar_t *p = s.GetBuffer(len); wchar_t *p = s.GetBuffer(len);
int i; int i;
for (i = 0; i < len; i++, buf += 2) for (i = 0; i < len; i++, buf += 2)
p[i] = (wchar_t)GetUInt16FromMem(buf); p[i] = (wchar_t)Get16(buf);
p[i] = 0;
s.ReleaseBuffer(len); s.ReleaseBuffer(len);
_pos += rem + 2; _pos += rem + 2;
} }
@@ -234,23 +228,32 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search
if (searchHeaderSizeLimit != NULL) if (searchHeaderSizeLimit != NULL)
if (curTestPos - _arhiveBeginStreamPosition > *searchHeaderSizeLimit) if (curTestPos - _arhiveBeginStreamPosition > *searchHeaderSizeLimit)
break; break;
do
{
UInt32 numReadBytes = kBufferSize - numPrevBytes; UInt32 numReadBytes = kBufferSize - numPrevBytes;
UInt32 processedSize; UInt32 processedSize;
RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize)); RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize));
UInt32 numBytesInBuffer = numPrevBytes + processedSize; numPrevBytes += processedSize;
if (numBytesInBuffer < kHeaderSize) if (processedSize == 0)
break; return S_FALSE;
UInt32 numTests = numBytesInBuffer - kHeaderSize + 1; }
for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++) while (numPrevBytes < kHeaderSize);
UInt32 numTests = numPrevBytes - kHeaderSize + 1;
for (UInt32 pos = 0; pos < numTests; pos++)
{ {
for (; buffer[pos] != '7' && pos < numTests; pos++);
if (pos == numTests)
break;
if (TestSignatureCandidate(buffer + pos)) if (TestSignatureCandidate(buffer + pos))
{ {
memcpy(_header, buffer + pos, kHeaderSize); memcpy(_header, buffer + pos, kHeaderSize);
curTestPos += pos;
_arhiveBeginStreamPosition = curTestPos; _arhiveBeginStreamPosition = curTestPos;
return stream->Seek(curTestPos + kHeaderSize, STREAM_SEEK_SET, NULL); return stream->Seek(curTestPos + kHeaderSize, STREAM_SEEK_SET, NULL);
} }
} }
numPrevBytes = numBytesInBuffer - numTests; curTestPos += numTests;
numPrevBytes -= numTests;
memmove(buffer, buffer + numTests, numPrevBytes); memmove(buffer, buffer + numTests, numPrevBytes);
} }
return S_FALSE; return S_FALSE;
@@ -259,6 +262,7 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search
// S_FALSE means that file is not archive // S_FALSE means that file is not archive
HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit) HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
{ {
HeadersSize = 0;
Close(); Close();
RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_arhiveBeginStreamPosition)) RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_arhiveBeginStreamPosition))
RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit)); RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit));
@@ -354,7 +358,7 @@ void CInArchive::GetNextFolderItem(CFolder &folder)
} }
} }
else else
for(i = 0; i < numPackedStreams; i++) for (i = 0; i < numPackedStreams; i++)
folder.PackStreams.Add(ReadNum()); folder.PackStreams.Add(ReadNum());
} }
@@ -378,7 +382,7 @@ void CInArchive::ReadHashDigests(int numItems,
ReadBoolVector2(numItems, digestsDefined); ReadBoolVector2(numItems, digestsDefined);
digests.Clear(); digests.Clear();
digests.Reserve(numItems); digests.Reserve(numItems);
for(int i = 0; i < numItems; i++) for (int i = 0; i < numItems; i++)
{ {
UInt32 crc = 0; UInt32 crc = 0;
if (digestsDefined[i]) if (digestsDefined[i])
@@ -421,7 +425,7 @@ void CInArchive::ReadPackInfo(
packCRCsDefined.Clear(); packCRCsDefined.Clear();
packCRCs.Reserve(numPackStreams); packCRCs.Reserve(numPackStreams);
packCRCs.Clear(); packCRCs.Clear();
for(CNum i = 0; i < numPackStreams; i++) for (CNum i = 0; i < numPackStreams; i++)
{ {
packCRCsDefined.Add(false); packCRCsDefined.Add(false);
packCRCs.Add(0); packCRCs.Add(0);
@@ -429,7 +433,7 @@ void CInArchive::ReadPackInfo(
} }
} }
void CInArchive::ReadUnPackInfo( void CInArchive::ReadUnpackInfo(
const CObjectVector<CByteBuffer> *dataVector, const CObjectVector<CByteBuffer> *dataVector,
CObjectVector<CFolder> &folders) CObjectVector<CFolder> &folders)
{ {
@@ -441,23 +445,23 @@ void CInArchive::ReadUnPackInfo(
streamSwitch.Set(this, dataVector); streamSwitch.Set(this, dataVector);
folders.Clear(); folders.Clear();
folders.Reserve(numFolders); folders.Reserve(numFolders);
for(CNum i = 0; i < numFolders; i++) for (CNum i = 0; i < numFolders; i++)
{ {
folders.Add(CFolder()); folders.Add(CFolder());
GetNextFolderItem(folders.Back()); GetNextFolderItem(folders.Back());
} }
} }
WaitAttribute(NID::kCodersUnPackSize); WaitAttribute(NID::kCodersUnpackSize);
CNum i; CNum i;
for (i = 0; i < numFolders; i++) for (i = 0; i < numFolders; i++)
{ {
CFolder &folder = folders[i]; CFolder &folder = folders[i];
CNum numOutStreams = folder.GetNumOutStreams(); CNum numOutStreams = folder.GetNumOutStreams();
folder.UnPackSizes.Reserve(numOutStreams); folder.UnpackSizes.Reserve(numOutStreams);
for (CNum j = 0; j < numOutStreams; j++) for (CNum j = 0; j < numOutStreams; j++)
folder.UnPackSizes.Add(ReadNumber()); folder.UnpackSizes.Add(ReadNumber());
} }
for (;;) for (;;)
@@ -470,11 +474,11 @@ void CInArchive::ReadUnPackInfo(
CRecordVector<bool> crcsDefined; CRecordVector<bool> crcsDefined;
CRecordVector<UInt32> crcs; CRecordVector<UInt32> crcs;
ReadHashDigests(numFolders, crcsDefined, crcs); ReadHashDigests(numFolders, crcsDefined, crcs);
for(i = 0; i < numFolders; i++) for (i = 0; i < numFolders; i++)
{ {
CFolder &folder = folders[i]; CFolder &folder = folders[i];
folder.UnPackCRCDefined = crcsDefined[i]; folder.UnpackCRCDefined = crcsDefined[i];
folder.UnPackCRC = crcs[i]; folder.UnpackCRC = crcs[i];
} }
continue; continue;
} }
@@ -484,21 +488,21 @@ void CInArchive::ReadUnPackInfo(
void CInArchive::ReadSubStreamsInfo( void CInArchive::ReadSubStreamsInfo(
const CObjectVector<CFolder> &folders, const CObjectVector<CFolder> &folders,
CRecordVector<CNum> &numUnPackStreamsInFolders, CRecordVector<CNum> &numUnpackStreamsInFolders,
CRecordVector<UInt64> &unPackSizes, CRecordVector<UInt64> &unpackSizes,
CRecordVector<bool> &digestsDefined, CRecordVector<bool> &digestsDefined,
CRecordVector<UInt32> &digests) CRecordVector<UInt32> &digests)
{ {
numUnPackStreamsInFolders.Clear(); numUnpackStreamsInFolders.Clear();
numUnPackStreamsInFolders.Reserve(folders.Size()); numUnpackStreamsInFolders.Reserve(folders.Size());
UInt64 type; UInt64 type;
for (;;) for (;;)
{ {
type = ReadID(); type = ReadID();
if (type == NID::kNumUnPackStream) if (type == NID::kNumUnpackStream)
{ {
for(int i = 0; i < folders.Size(); i++) for (int i = 0; i < folders.Size(); i++)
numUnPackStreamsInFolders.Add(ReadNum()); numUnpackStreamsInFolders.Add(ReadNum());
continue; continue;
} }
if (type == NID::kCRC || type == NID::kSize) if (type == NID::kCRC || type == NID::kSize)
@@ -508,16 +512,16 @@ void CInArchive::ReadSubStreamsInfo(
SkeepData(); SkeepData();
} }
if (numUnPackStreamsInFolders.IsEmpty()) if (numUnpackStreamsInFolders.IsEmpty())
for(int i = 0; i < folders.Size(); i++) for (int i = 0; i < folders.Size(); i++)
numUnPackStreamsInFolders.Add(1); numUnpackStreamsInFolders.Add(1);
int i; int i;
for(i = 0; i < numUnPackStreamsInFolders.Size(); i++) for (i = 0; i < numUnpackStreamsInFolders.Size(); i++)
{ {
// v3.13 incorrectly worked with empty folders // v3.13 incorrectly worked with empty folders
// v4.07: we check that folder is empty // v4.07: we check that folder is empty
CNum numSubstreams = numUnPackStreamsInFolders[i]; CNum numSubstreams = numUnpackStreamsInFolders[i];
if (numSubstreams == 0) if (numSubstreams == 0)
continue; continue;
UInt64 sum = 0; UInt64 sum = 0;
@@ -525,20 +529,20 @@ void CInArchive::ReadSubStreamsInfo(
if (type == NID::kSize) if (type == NID::kSize)
{ {
UInt64 size = ReadNumber(); UInt64 size = ReadNumber();
unPackSizes.Add(size); unpackSizes.Add(size);
sum += size; sum += size;
} }
unPackSizes.Add(folders[i].GetUnPackSize() - sum); unpackSizes.Add(folders[i].GetUnpackSize() - sum);
} }
if (type == NID::kSize) if (type == NID::kSize)
type = ReadID(); type = ReadID();
int numDigests = 0; int numDigests = 0;
int numDigestsTotal = 0; int numDigestsTotal = 0;
for(i = 0; i < folders.Size(); i++) for (i = 0; i < folders.Size(); i++)
{ {
CNum numSubstreams = numUnPackStreamsInFolders[i]; CNum numSubstreams = numUnpackStreamsInFolders[i];
if (numSubstreams != 1 || !folders[i].UnPackCRCDefined) if (numSubstreams != 1 || !folders[i].UnpackCRCDefined)
numDigests += numSubstreams; numDigests += numSubstreams;
numDigestsTotal += numSubstreams; numDigestsTotal += numSubstreams;
} }
@@ -553,12 +557,12 @@ void CInArchive::ReadSubStreamsInfo(
int digestIndex = 0; int digestIndex = 0;
for (i = 0; i < folders.Size(); i++) for (i = 0; i < folders.Size(); i++)
{ {
CNum numSubstreams = numUnPackStreamsInFolders[i]; CNum numSubstreams = numUnpackStreamsInFolders[i];
const CFolder &folder = folders[i]; const CFolder &folder = folders[i];
if (numSubstreams == 1 && folder.UnPackCRCDefined) if (numSubstreams == 1 && folder.UnpackCRCDefined)
{ {
digestsDefined.Add(true); digestsDefined.Add(true);
digests.Add(folder.UnPackCRC); digests.Add(folder.UnpackCRC);
} }
else else
for (CNum j = 0; j < numSubstreams; j++, digestIndex++) for (CNum j = 0; j < numSubstreams; j++, digestIndex++)
@@ -595,8 +599,8 @@ void CInArchive::ReadStreamsInfo(
CRecordVector<bool> &packCRCsDefined, CRecordVector<bool> &packCRCsDefined,
CRecordVector<UInt32> &packCRCs, CRecordVector<UInt32> &packCRCs,
CObjectVector<CFolder> &folders, CObjectVector<CFolder> &folders,
CRecordVector<CNum> &numUnPackStreamsInFolders, CRecordVector<CNum> &numUnpackStreamsInFolders,
CRecordVector<UInt64> &unPackSizes, CRecordVector<UInt64> &unpackSizes,
CRecordVector<bool> &digestsDefined, CRecordVector<bool> &digestsDefined,
CRecordVector<UInt32> &digests) CRecordVector<UInt32> &digests)
{ {
@@ -614,15 +618,15 @@ void CInArchive::ReadStreamsInfo(
ReadPackInfo(dataOffset, packSizes, packCRCsDefined, packCRCs); ReadPackInfo(dataOffset, packSizes, packCRCsDefined, packCRCs);
break; break;
} }
case NID::kUnPackInfo: case NID::kUnpackInfo:
{ {
ReadUnPackInfo(dataVector, folders); ReadUnpackInfo(dataVector, folders);
break; break;
} }
case NID::kSubStreamsInfo: case NID::kSubStreamsInfo:
{ {
ReadSubStreamsInfo(folders, numUnPackStreamsInFolders, ReadSubStreamsInfo(folders, numUnpackStreamsInFolders,
unPackSizes, digestsDefined, digests); unpackSizes, digestsDefined, digests);
break; break;
} }
default: default:
@@ -637,7 +641,7 @@ void CInArchive::ReadBoolVector(int numItems, CBoolVector &v)
v.Reserve(numItems); v.Reserve(numItems);
Byte b = 0; Byte b = 0;
Byte mask = 0; Byte mask = 0;
for(int i = 0; i < numItems; i++) for (int i = 0; i < numItems; i++)
{ {
if (mask == 0) if (mask == 0)
{ {
@@ -663,45 +667,21 @@ void CInArchive::ReadBoolVector2(int numItems, CBoolVector &v)
v.Add(true); v.Add(true);
} }
void CInArchive::ReadTime(const CObjectVector<CByteBuffer> &dataVector, void CInArchive::ReadUInt64DefVector(const CObjectVector<CByteBuffer> &dataVector,
CObjectVector<CFileItem> &files, UInt32 type) CUInt64DefVector &v, int numFiles)
{ {
CBoolVector boolVector; ReadBoolVector2(numFiles, v.Defined);
ReadBoolVector2(files.Size(), boolVector);
CStreamSwitch streamSwitch; CStreamSwitch streamSwitch;
streamSwitch.Set(this, &dataVector); streamSwitch.Set(this, &dataVector);
v.Values.Reserve(numFiles);
for(int i = 0; i < files.Size(); i++) for (int i = 0; i < numFiles; i++)
{ {
CFileItem &file = files[i]; UInt64 t = 0;
CArchiveFileTime fileTime; if (v.Defined[i])
fileTime.dwLowDateTime = 0; t = ReadUInt64();
fileTime.dwHighDateTime = 0; v.Values.Add(t);
bool defined = boolVector[i];
if (defined)
{
fileTime.dwLowDateTime = ReadUInt32();
fileTime.dwHighDateTime = ReadUInt32();
}
switch(type)
{
case NID::kCreationTime:
file.IsCreationTimeDefined = defined;
if (defined)
file.CreationTime = fileTime;
break;
case NID::kLastWriteTime:
file.IsLastWriteTimeDefined = defined;
if (defined)
file.LastWriteTime = fileTime;
break;
case NID::kLastAccessTime:
file.IsLastAccessTimeDefined = defined;
if (defined)
file.LastAccessTime = fileTime;
break;
}
} }
} }
@@ -710,7 +690,7 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
UInt64 baseOffset, UInt64 baseOffset,
UInt64 &dataOffset, CObjectVector<CByteBuffer> &dataVector UInt64 &dataOffset, CObjectVector<CByteBuffer> &dataVector
#ifndef _NO_CRYPTO #ifndef _NO_CRYPTO
, ICryptoGetTextPassword *getTextPassword , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
#endif #endif
) )
{ {
@@ -719,8 +699,8 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
CRecordVector<UInt32> packCRCs; CRecordVector<UInt32> packCRCs;
CObjectVector<CFolder> folders; CObjectVector<CFolder> folders;
CRecordVector<CNum> numUnPackStreamsInFolders; CRecordVector<CNum> numUnpackStreamsInFolders;
CRecordVector<UInt64> unPackSizes; CRecordVector<UInt64> unpackSizes;
CRecordVector<bool> digestsDefined; CRecordVector<bool> digestsDefined;
CRecordVector<UInt32> digests; CRecordVector<UInt32> digests;
@@ -730,12 +710,12 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
packCRCsDefined, packCRCsDefined,
packCRCs, packCRCs,
folders, folders,
numUnPackStreamsInFolders, numUnpackStreamsInFolders,
unPackSizes, unpackSizes,
digestsDefined, digestsDefined,
digests); digests);
// database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader; // db.ArchiveInfo.DataStartPosition2 += db.ArchiveInfo.StartPositionAfterHeader;
CNum packIndex = 0; CNum packIndex = 0;
CDecoder decoder( CDecoder decoder(
@@ -746,27 +726,27 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
#endif #endif
); );
UInt64 dataStartPos = baseOffset + dataOffset; UInt64 dataStartPos = baseOffset + dataOffset;
for(int i = 0; i < folders.Size(); i++) for (int i = 0; i < folders.Size(); i++)
{ {
const CFolder &folder = folders[i]; const CFolder &folder = folders[i];
dataVector.Add(CByteBuffer()); dataVector.Add(CByteBuffer());
CByteBuffer &data = dataVector.Back(); CByteBuffer &data = dataVector.Back();
UInt64 unPackSize64 = folder.GetUnPackSize(); UInt64 unpackSize64 = folder.GetUnpackSize();
size_t unPackSize = (size_t)unPackSize64; size_t unpackSize = (size_t)unpackSize64;
if (unPackSize != unPackSize64) if (unpackSize != unpackSize64)
ThrowUnsupported(); ThrowUnsupported();
data.SetCapacity(unPackSize); data.SetCapacity(unpackSize);
CSequentialOutStreamImp2 *outStreamSpec = new CSequentialOutStreamImp2; CSequentialOutStreamImp2 *outStreamSpec = new CSequentialOutStreamImp2;
CMyComPtr<ISequentialOutStream> outStream = outStreamSpec; CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
outStreamSpec->Init(data, unPackSize); outStreamSpec->Init(data, unpackSize);
HRESULT result = decoder.Decode( HRESULT result = decoder.Decode(
EXTERNAL_CODECS_LOC_VARS EXTERNAL_CODECS_LOC_VARS
_stream, dataStartPos, _stream, dataStartPos,
&packSizes[packIndex], folder, outStream, NULL &packSizes[packIndex], folder, outStream, NULL
#ifndef _NO_CRYPTO #ifndef _NO_CRYPTO
, getTextPassword , getTextPassword, passwordIsDefined
#endif #endif
#ifdef COMPRESS_MT #ifdef COMPRESS_MT
, false, 1 , false, 1
@@ -774,20 +754,24 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
); );
RINOK(result); RINOK(result);
if (folder.UnPackCRCDefined) if (folder.UnpackCRCDefined)
if (CrcCalc(data, unPackSize) != folder.UnPackCRC) if (CrcCalc(data, unpackSize) != folder.UnpackCRC)
ThrowIncorrect(); ThrowIncorrect();
for (int j = 0; j < folder.PackStreams.Size(); j++) for (int j = 0; j < folder.PackStreams.Size(); j++)
dataStartPos += packSizes[packIndex++]; {
UInt64 packSize = packSizes[packIndex++];
dataStartPos += packSize;
HeadersSize += packSize;
}
} }
return S_OK; return S_OK;
} }
HRESULT CInArchive::ReadHeader( HRESULT CInArchive::ReadHeader(
DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS
CArchiveDatabaseEx &database CArchiveDatabaseEx &db
#ifndef _NO_CRYPTO #ifndef _NO_CRYPTO
, ICryptoGetTextPassword *getTextPassword , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
#endif #endif
) )
{ {
@@ -795,7 +779,7 @@ HRESULT CInArchive::ReadHeader(
if (type == NID::kArchiveProperties) if (type == NID::kArchiveProperties)
{ {
ReadArchiveProperties(database.ArchiveInfo); ReadArchiveProperties(db.ArchiveInfo);
type = ReadID(); type = ReadID();
} }
@@ -805,50 +789,50 @@ HRESULT CInArchive::ReadHeader(
{ {
HRESULT result = ReadAndDecodePackedStreams( HRESULT result = ReadAndDecodePackedStreams(
EXTERNAL_CODECS_LOC_VARS EXTERNAL_CODECS_LOC_VARS
database.ArchiveInfo.StartPositionAfterHeader, db.ArchiveInfo.StartPositionAfterHeader,
database.ArchiveInfo.DataStartPosition2, db.ArchiveInfo.DataStartPosition2,
dataVector dataVector
#ifndef _NO_CRYPTO #ifndef _NO_CRYPTO
, getTextPassword , getTextPassword, passwordIsDefined
#endif #endif
); );
RINOK(result); RINOK(result);
database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader; db.ArchiveInfo.DataStartPosition2 += db.ArchiveInfo.StartPositionAfterHeader;
type = ReadID(); type = ReadID();
} }
CRecordVector<UInt64> unPackSizes; CRecordVector<UInt64> unpackSizes;
CRecordVector<bool> digestsDefined; CRecordVector<bool> digestsDefined;
CRecordVector<UInt32> digests; CRecordVector<UInt32> digests;
if (type == NID::kMainStreamsInfo) if (type == NID::kMainStreamsInfo)
{ {
ReadStreamsInfo(&dataVector, ReadStreamsInfo(&dataVector,
database.ArchiveInfo.DataStartPosition, db.ArchiveInfo.DataStartPosition,
database.PackSizes, db.PackSizes,
database.PackCRCsDefined, db.PackCRCsDefined,
database.PackCRCs, db.PackCRCs,
database.Folders, db.Folders,
database.NumUnPackStreamsVector, db.NumUnpackStreamsVector,
unPackSizes, unpackSizes,
digestsDefined, digestsDefined,
digests); digests);
database.ArchiveInfo.DataStartPosition += database.ArchiveInfo.StartPositionAfterHeader; db.ArchiveInfo.DataStartPosition += db.ArchiveInfo.StartPositionAfterHeader;
type = ReadID(); type = ReadID();
} }
else else
{ {
for(int i = 0; i < database.Folders.Size(); i++) for (int i = 0; i < db.Folders.Size(); i++)
{ {
database.NumUnPackStreamsVector.Add(1); db.NumUnpackStreamsVector.Add(1);
CFolder &folder = database.Folders[i]; CFolder &folder = db.Folders[i];
unPackSizes.Add(folder.GetUnPackSize()); unpackSizes.Add(folder.GetUnpackSize());
digestsDefined.Add(folder.UnPackCRCDefined); digestsDefined.Add(folder.UnpackCRCDefined);
digests.Add(folder.UnPackCRC); digests.Add(folder.UnpackCRC);
} }
} }
database.Files.Clear(); db.Files.Clear();
if (type == NID::kEnd) if (type == NID::kEnd)
return S_OK; return S_OK;
@@ -856,20 +840,20 @@ HRESULT CInArchive::ReadHeader(
ThrowIncorrect(); ThrowIncorrect();
CNum numFiles = ReadNum(); CNum numFiles = ReadNum();
database.Files.Reserve(numFiles); db.Files.Reserve(numFiles);
CNum i; CNum i;
for(i = 0; i < numFiles; i++) for (i = 0; i < numFiles; i++)
database.Files.Add(CFileItem()); db.Files.Add(CFileItem());
database.ArchiveInfo.FileInfoPopIDs.Add(NID::kSize); db.ArchiveInfo.FileInfoPopIDs.Add(NID::kSize);
if (!database.PackSizes.IsEmpty()) if (!db.PackSizes.IsEmpty())
database.ArchiveInfo.FileInfoPopIDs.Add(NID::kPackInfo); db.ArchiveInfo.FileInfoPopIDs.Add(NID::kPackInfo);
if (numFiles > 0 && !digests.IsEmpty()) if (numFiles > 0 && !digests.IsEmpty())
database.ArchiveInfo.FileInfoPopIDs.Add(NID::kCRC); db.ArchiveInfo.FileInfoPopIDs.Add(NID::kCRC);
CBoolVector emptyStreamVector; CBoolVector emptyStreamVector;
emptyStreamVector.Reserve((int)numFiles); emptyStreamVector.Reserve((int)numFiles);
for(i = 0; i < numFiles; i++) for (i = 0; i < numFiles; i++)
emptyStreamVector.Add(false); emptyStreamVector.Add(false);
CBoolVector emptyFileVector; CBoolVector emptyFileVector;
CBoolVector antiFileVector; CBoolVector antiFileVector;
@@ -881,6 +865,8 @@ HRESULT CInArchive::ReadHeader(
if (type == NID::kEnd) if (type == NID::kEnd)
break; break;
UInt64 size = ReadNumber(); UInt64 size = ReadNumber();
size_t ppp = _inByteBack->_pos;
bool addPropIdToList = true;
bool isKnownType = true; bool isKnownType = true;
if (type > ((UInt32)1 << 30)) if (type > ((UInt32)1 << 30))
isKnownType = false; isKnownType = false;
@@ -890,37 +876,22 @@ HRESULT CInArchive::ReadHeader(
{ {
CStreamSwitch streamSwitch; CStreamSwitch streamSwitch;
streamSwitch.Set(this, &dataVector); streamSwitch.Set(this, &dataVector);
for(int i = 0; i < database.Files.Size(); i++) for (int i = 0; i < db.Files.Size(); i++)
_inByteBack->ReadString(database.Files[i].Name); _inByteBack->ReadString(db.Files[i].Name);
break; break;
} }
case NID::kWinAttributes: case NID::kWinAttributes:
{ {
CBoolVector boolVector; CBoolVector boolVector;
ReadBoolVector2(database.Files.Size(), boolVector); ReadBoolVector2(db.Files.Size(), boolVector);
CStreamSwitch streamSwitch; CStreamSwitch streamSwitch;
streamSwitch.Set(this, &dataVector); streamSwitch.Set(this, &dataVector);
for(i = 0; i < numFiles; i++) for (i = 0; i < numFiles; i++)
{ {
CFileItem &file = database.Files[i]; CFileItem &file = db.Files[i];
file.AreAttributesDefined = boolVector[i]; file.AttribDefined = boolVector[i];
if (file.AreAttributesDefined) if (file.AttribDefined)
file.Attributes = ReadUInt32(); file.Attrib = ReadUInt32();
}
break;
}
case NID::kStartPos:
{
CBoolVector boolVector;
ReadBoolVector2(database.Files.Size(), boolVector);
CStreamSwitch streamSwitch;
streamSwitch.Set(this, &dataVector);
for(i = 0; i < numFiles; i++)
{
CFileItem &file = database.Files[i];
file.IsStartPosDefined = boolVector[i];
if (file.IsStartPosDefined)
file.StartPos = ReadUInt64();
} }
break; break;
} }
@@ -939,55 +910,68 @@ HRESULT CInArchive::ReadHeader(
} }
break; break;
} }
case NID::kEmptyFile: case NID::kEmptyFile: ReadBoolVector(numEmptyStreams, emptyFileVector); break;
case NID::kAnti: ReadBoolVector(numEmptyStreams, antiFileVector); break;
case NID::kStartPos: ReadUInt64DefVector(dataVector, db.StartPos, (int)numFiles); break;
case NID::kCTime: ReadUInt64DefVector(dataVector, db.CTime, (int)numFiles); break;
case NID::kATime: ReadUInt64DefVector(dataVector, db.ATime, (int)numFiles); break;
case NID::kMTime: ReadUInt64DefVector(dataVector, db.MTime, (int)numFiles); break;
case NID::kDummy:
{ {
ReadBoolVector(numEmptyStreams, emptyFileVector); for (UInt64 j = 0; j < size; j++)
break; if (ReadByte() != 0)
} ThrowIncorrect();
case NID::kAnti: addPropIdToList = false;
{
ReadBoolVector(numEmptyStreams, antiFileVector);
break;
}
case NID::kCreationTime:
case NID::kLastWriteTime:
case NID::kLastAccessTime:
{
ReadTime(dataVector, database.Files, (UInt32)type);
break; break;
} }
default: default:
isKnownType = false; addPropIdToList = isKnownType = false;
} }
if (isKnownType) if (isKnownType)
database.ArchiveInfo.FileInfoPopIDs.Add(type); {
if(addPropIdToList)
db.ArchiveInfo.FileInfoPopIDs.Add(type);
}
else else
SkeepData(size); SkeepData(size);
bool checkRecordsSize = (db.ArchiveInfo.Version.Major > 0 ||
db.ArchiveInfo.Version.Minor > 2);
if (checkRecordsSize && _inByteBack->_pos - ppp != size)
ThrowIncorrect();
} }
CNum emptyFileIndex = 0; CNum emptyFileIndex = 0;
CNum sizeIndex = 0; CNum sizeIndex = 0;
for(i = 0; i < numFiles; i++)
CNum numAntiItems = 0;
for (i = 0; i < numEmptyStreams; i++)
if (antiFileVector[i])
numAntiItems++;
for (i = 0; i < numFiles; i++)
{ {
CFileItem &file = database.Files[i]; CFileItem &file = db.Files[i];
bool isAnti;
file.HasStream = !emptyStreamVector[i]; file.HasStream = !emptyStreamVector[i];
if(file.HasStream) if (file.HasStream)
{ {
file.IsDirectory = false; file.IsDir = false;
file.IsAnti = false; isAnti = false;
file.UnPackSize = unPackSizes[sizeIndex]; file.Size = unpackSizes[sizeIndex];
file.FileCRC = digests[sizeIndex]; file.Crc = digests[sizeIndex];
file.IsFileCRCDefined = digestsDefined[sizeIndex]; file.CrcDefined = digestsDefined[sizeIndex];
sizeIndex++; sizeIndex++;
} }
else else
{ {
file.IsDirectory = !emptyFileVector[emptyFileIndex]; file.IsDir = !emptyFileVector[emptyFileIndex];
file.IsAnti = antiFileVector[emptyFileIndex]; isAnti = antiFileVector[emptyFileIndex];
emptyFileIndex++; emptyFileIndex++;
file.UnPackSize = 0; file.Size = 0;
file.IsFileCRCDefined = false; file.CrcDefined = false;
} }
if (numAntiItems != 0)
db.IsAnti.Add(isAnti);
} }
return S_OK; return S_OK;
} }
@@ -998,7 +982,7 @@ void CArchiveDatabaseEx::FillFolderStartPackStream()
FolderStartPackStreamIndex.Clear(); FolderStartPackStreamIndex.Clear();
FolderStartPackStreamIndex.Reserve(Folders.Size()); FolderStartPackStreamIndex.Reserve(Folders.Size());
CNum startPos = 0; CNum startPos = 0;
for(int i = 0; i < Folders.Size(); i++) for (int i = 0; i < Folders.Size(); i++)
{ {
FolderStartPackStreamIndex.Add(startPos); FolderStartPackStreamIndex.Add(startPos);
startPos += (CNum)Folders[i].PackStreams.Size(); startPos += (CNum)Folders[i].PackStreams.Size();
@@ -1010,7 +994,7 @@ void CArchiveDatabaseEx::FillStartPos()
PackStreamStartPositions.Clear(); PackStreamStartPositions.Clear();
PackStreamStartPositions.Reserve(PackSizes.Size()); PackStreamStartPositions.Reserve(PackSizes.Size());
UInt64 startPos = 0; UInt64 startPos = 0;
for(int i = 0; i < PackSizes.Size(); i++) for (int i = 0; i < PackSizes.Size(); i++)
{ {
PackStreamStartPositions.Add(startPos); PackStreamStartPositions.Add(startPos);
startPos += PackSizes[i]; startPos += PackSizes[i];
@@ -1044,7 +1028,7 @@ void CArchiveDatabaseEx::FillFolderStartFileIndex()
if (folderIndex >= Folders.Size()) if (folderIndex >= Folders.Size())
ThrowIncorrect(); ThrowIncorrect();
FolderStartFileIndex.Add(i); // check it FolderStartFileIndex.Add(i); // check it
if (NumUnPackStreamsVector[folderIndex] != 0) if (NumUnpackStreamsVector[folderIndex] != 0)
break; break;
folderIndex++; folderIndex++;
} }
@@ -1053,7 +1037,7 @@ void CArchiveDatabaseEx::FillFolderStartFileIndex()
if (emptyStream) if (emptyStream)
continue; continue;
indexInFolder++; indexInFolder++;
if (indexInFolder >= NumUnPackStreamsVector[folderIndex]) if (indexInFolder >= NumUnpackStreamsVector[folderIndex])
{ {
folderIndex++; folderIndex++;
indexInFolder = 0; indexInFolder = 0;
@@ -1063,25 +1047,25 @@ void CArchiveDatabaseEx::FillFolderStartFileIndex()
HRESULT CInArchive::ReadDatabase2( HRESULT CInArchive::ReadDatabase2(
DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS
CArchiveDatabaseEx &database CArchiveDatabaseEx &db
#ifndef _NO_CRYPTO #ifndef _NO_CRYPTO
, ICryptoGetTextPassword *getTextPassword , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
#endif #endif
) )
{ {
database.Clear(); db.Clear();
database.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition; db.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition;
database.ArchiveInfo.Version.Major = _header[6]; db.ArchiveInfo.Version.Major = _header[6];
database.ArchiveInfo.Version.Minor = _header[7]; db.ArchiveInfo.Version.Minor = _header[7];
if (database.ArchiveInfo.Version.Major != kMajorVersion) if (db.ArchiveInfo.Version.Major != kMajorVersion)
ThrowUnsupportedVersion(); ThrowUnsupportedVersion();
UInt32 crcFromArchive = GetUInt32FromMem(_header + 8); UInt32 crcFromArchive = Get32(_header + 8);
UInt64 nextHeaderOffset = GetUInt64FromMem(_header + 0xC); UInt64 nextHeaderOffset = Get64(_header + 0xC);
UInt64 nextHeaderSize = GetUInt64FromMem(_header + 0x14); UInt64 nextHeaderSize = Get64(_header + 0x14);
UInt32 nextHeaderCRC = GetUInt32FromMem(_header + 0x1C); UInt32 nextHeaderCRC = Get32(_header + 0x1C);
UInt32 crc = CrcCalc(_header + 0xC, 20); UInt32 crc = CrcCalc(_header + 0xC, 20);
#ifdef FORMAT_7Z_RECOVERY #ifdef FORMAT_7Z_RECOVERY
@@ -1097,16 +1081,15 @@ HRESULT CInArchive::ReadDatabase2(
checkSize = (int)(cur2 - cur); checkSize = (int)(cur2 - cur);
RINOK(_stream->Seek(-checkSize, STREAM_SEEK_END, &cur2)); RINOK(_stream->Seek(-checkSize, STREAM_SEEK_END, &cur2));
UInt32 realProcessedSize; RINOK(ReadStream_FALSE(_stream, buf, (size_t)checkSize));
RINOK(_stream->Read(buf, (UInt32)kCheckSize, &realProcessedSize));
int i; int i;
for (i = (int)realProcessedSize - 2; i >= 0; i--) for (i = (int)checkSize - 2; i >= 0; i--)
if (buf[i] == 0x17 && buf[i + 1] == 0x6 || buf[i] == 0x01 && buf[i + 1] == 0x04) if (buf[i] == 0x17 && buf[i + 1] == 0x6 || buf[i] == 0x01 && buf[i + 1] == 0x04)
break; break;
if (i < 0) if (i < 0)
return S_FALSE; return S_FALSE;
nextHeaderSize = realProcessedSize - i; nextHeaderSize = checkSize - i;
nextHeaderOffset = cur2 - cur + i; nextHeaderOffset = cur2 - cur + i;
nextHeaderCRC = CrcCalc(buf + i, (size_t)nextHeaderSize); nextHeaderCRC = CrcCalc(buf + i, (size_t)nextHeaderSize);
RINOK(_stream->Seek(cur, STREAM_SEEK_SET, NULL)); RINOK(_stream->Seek(cur, STREAM_SEEK_SET, NULL));
@@ -1117,7 +1100,7 @@ HRESULT CInArchive::ReadDatabase2(
crcFromArchive = crc; crcFromArchive = crc;
#endif #endif
database.ArchiveInfo.StartPositionAfterHeader = _arhiveBeginStreamPosition + kHeaderSize; db.ArchiveInfo.StartPositionAfterHeader = _arhiveBeginStreamPosition + kHeaderSize;
if (crc != crcFromArchive) if (crc != crcFromArchive)
ThrowIncorrect(); ThrowIncorrect();
@@ -1133,10 +1116,10 @@ HRESULT CInArchive::ReadDatabase2(
CByteBuffer buffer2; CByteBuffer buffer2;
buffer2.SetCapacity((size_t)nextHeaderSize); buffer2.SetCapacity((size_t)nextHeaderSize);
UInt32 realProcessedSize; RINOK(ReadStream_FALSE(_stream, buffer2, (size_t)nextHeaderSize));
RINOK(_stream->Read(buffer2, (UInt32)nextHeaderSize, &realProcessedSize)); HeadersSize += kHeaderSize + nextHeaderSize;
if (realProcessedSize != (UInt32)nextHeaderSize) db.PhySize = kHeaderSize + nextHeaderOffset + nextHeaderSize;
return S_FALSE;
if (CrcCalc(buffer2, (UInt32)nextHeaderSize) != nextHeaderCRC) if (CrcCalc(buffer2, (UInt32)nextHeaderSize) != nextHeaderCRC)
ThrowIncorrect(); ThrowIncorrect();
@@ -1145,20 +1128,18 @@ HRESULT CInArchive::ReadDatabase2(
CObjectVector<CByteBuffer> dataVector; CObjectVector<CByteBuffer> dataVector;
for (;;)
{
UInt64 type = ReadID(); UInt64 type = ReadID();
if (type == NID::kHeader) if (type != NID::kHeader)
break; {
if (type != NID::kEncodedHeader) if (type != NID::kEncodedHeader)
ThrowIncorrect(); ThrowIncorrect();
HRESULT result = ReadAndDecodePackedStreams( HRESULT result = ReadAndDecodePackedStreams(
EXTERNAL_CODECS_LOC_VARS EXTERNAL_CODECS_LOC_VARS
database.ArchiveInfo.StartPositionAfterHeader, db.ArchiveInfo.StartPositionAfterHeader,
database.ArchiveInfo.DataStartPosition2, db.ArchiveInfo.DataStartPosition2,
dataVector dataVector
#ifndef _NO_CRYPTO #ifndef _NO_CRYPTO
, getTextPassword , getTextPassword, passwordIsDefined
#endif #endif
); );
RINOK(result); RINOK(result);
@@ -1168,31 +1149,35 @@ HRESULT CInArchive::ReadDatabase2(
ThrowIncorrect(); ThrowIncorrect();
streamSwitch.Remove(); streamSwitch.Remove();
streamSwitch.Set(this, dataVector.Front()); streamSwitch.Set(this, dataVector.Front());
if (ReadID() != NID::kHeader)
ThrowIncorrect();
} }
db.HeadersSize = HeadersSize;
return ReadHeader( return ReadHeader(
EXTERNAL_CODECS_LOC_VARS EXTERNAL_CODECS_LOC_VARS
database db
#ifndef _NO_CRYPTO #ifndef _NO_CRYPTO
, getTextPassword , getTextPassword, passwordIsDefined
#endif #endif
); );
} }
HRESULT CInArchive::ReadDatabase( HRESULT CInArchive::ReadDatabase(
DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS
CArchiveDatabaseEx &database CArchiveDatabaseEx &db
#ifndef _NO_CRYPTO #ifndef _NO_CRYPTO
, ICryptoGetTextPassword *getTextPassword , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
#endif #endif
) )
{ {
try try
{ {
return ReadDatabase2( return ReadDatabase2(
EXTERNAL_CODECS_LOC_VARS database EXTERNAL_CODECS_LOC_VARS db
#ifndef _NO_CRYPTO #ifndef _NO_CRYPTO
, getTextPassword , getTextPassword, passwordIsDefined
#endif #endif
); );
} }

View File

@@ -36,6 +36,9 @@ struct CArchiveDatabaseEx: public CArchiveDatabase
CRecordVector<CNum> FolderStartFileIndex; CRecordVector<CNum> FolderStartFileIndex;
CRecordVector<CNum> FileIndexToFolderIndexMap; CRecordVector<CNum> FileIndexToFolderIndexMap;
UInt64 HeadersSize;
UInt64 PhySize;
void Clear() void Clear()
{ {
CArchiveDatabase::Clear(); CArchiveDatabase::Clear();
@@ -44,6 +47,9 @@ struct CArchiveDatabaseEx: public CArchiveDatabase
FolderStartPackStreamIndex.Clear(); FolderStartPackStreamIndex.Clear();
FolderStartFileIndex.Clear(); FolderStartFileIndex.Clear();
FileIndexToFolderIndexMap.Clear(); FileIndexToFolderIndexMap.Clear();
HeadersSize = 0;
PhySize = 0;
} }
void FillFolderStartPackStream(); void FillFolderStartPackStream();
@@ -92,8 +98,8 @@ class CInByte2
{ {
const Byte *_buffer; const Byte *_buffer;
size_t _size; size_t _size;
size_t _pos;
public: public:
size_t _pos;
void Init(const Byte *buffer, size_t size) void Init(const Byte *buffer, size_t size)
{ {
_buffer = buffer; _buffer = buffer;
@@ -128,6 +134,8 @@ class CInArchive
Byte _header[kHeaderSize]; Byte _header[kHeaderSize];
UInt64 HeadersSize;
void AddByteStream(const Byte *buffer, size_t size) void AddByteStream(const Byte *buffer, size_t size)
{ {
_inByteVector.Add(CInByte2()); _inByteVector.Add(CInByte2());
@@ -167,14 +175,14 @@ private:
CRecordVector<bool> &packCRCsDefined, CRecordVector<bool> &packCRCsDefined,
CRecordVector<UInt32> &packCRCs); CRecordVector<UInt32> &packCRCs);
void ReadUnPackInfo( void ReadUnpackInfo(
const CObjectVector<CByteBuffer> *dataVector, const CObjectVector<CByteBuffer> *dataVector,
CObjectVector<CFolder> &folders); CObjectVector<CFolder> &folders);
void ReadSubStreamsInfo( void ReadSubStreamsInfo(
const CObjectVector<CFolder> &folders, const CObjectVector<CFolder> &folders,
CRecordVector<CNum> &numUnPackStreamsInFolders, CRecordVector<CNum> &numUnpackStreamsInFolders,
CRecordVector<UInt64> &unPackSizes, CRecordVector<UInt64> &unpackSizes,
CRecordVector<bool> &digestsDefined, CRecordVector<bool> &digestsDefined,
CRecordVector<UInt32> &digests); CRecordVector<UInt32> &digests);
@@ -185,36 +193,36 @@ private:
CRecordVector<bool> &packCRCsDefined, CRecordVector<bool> &packCRCsDefined,
CRecordVector<UInt32> &packCRCs, CRecordVector<UInt32> &packCRCs,
CObjectVector<CFolder> &folders, CObjectVector<CFolder> &folders,
CRecordVector<CNum> &numUnPackStreamsInFolders, CRecordVector<CNum> &numUnpackStreamsInFolders,
CRecordVector<UInt64> &unPackSizes, CRecordVector<UInt64> &unpackSizes,
CRecordVector<bool> &digestsDefined, CRecordVector<bool> &digestsDefined,
CRecordVector<UInt32> &digests); CRecordVector<UInt32> &digests);
void ReadBoolVector(int numItems, CBoolVector &v); void ReadBoolVector(int numItems, CBoolVector &v);
void ReadBoolVector2(int numItems, CBoolVector &v); void ReadBoolVector2(int numItems, CBoolVector &v);
void ReadTime(const CObjectVector<CByteBuffer> &dataVector, void ReadUInt64DefVector(const CObjectVector<CByteBuffer> &dataVector,
CObjectVector<CFileItem> &files, UInt32 type); CUInt64DefVector &v, int numFiles);
HRESULT ReadAndDecodePackedStreams( HRESULT ReadAndDecodePackedStreams(
DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS
UInt64 baseOffset, UInt64 &dataOffset, UInt64 baseOffset, UInt64 &dataOffset,
CObjectVector<CByteBuffer> &dataVector CObjectVector<CByteBuffer> &dataVector
#ifndef _NO_CRYPTO #ifndef _NO_CRYPTO
, ICryptoGetTextPassword *getTextPassword , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
#endif #endif
); );
HRESULT ReadHeader( HRESULT ReadHeader(
DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS
CArchiveDatabaseEx &database CArchiveDatabaseEx &db
#ifndef _NO_CRYPTO #ifndef _NO_CRYPTO
,ICryptoGetTextPassword *getTextPassword ,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
#endif #endif
); );
HRESULT ReadDatabase2( HRESULT ReadDatabase2(
DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS
CArchiveDatabaseEx &database CArchiveDatabaseEx &db
#ifndef _NO_CRYPTO #ifndef _NO_CRYPTO
,ICryptoGetTextPassword *getTextPassword ,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
#endif #endif
); );
public: public:
@@ -223,9 +231,9 @@ public:
HRESULT ReadDatabase( HRESULT ReadDatabase(
DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS
CArchiveDatabaseEx &database CArchiveDatabaseEx &db
#ifndef _NO_CRYPTO #ifndef _NO_CRYPTO
,ICryptoGetTextPassword *getTextPassword ,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
#endif #endif
); );
}; };

View File

@@ -35,19 +35,19 @@ struct CFolder
CObjectVector<CCoderInfo> Coders; CObjectVector<CCoderInfo> Coders;
CRecordVector<CBindPair> BindPairs; CRecordVector<CBindPair> BindPairs;
CRecordVector<CNum> PackStreams; CRecordVector<CNum> PackStreams;
CRecordVector<UInt64> UnPackSizes; CRecordVector<UInt64> UnpackSizes;
UInt32 UnPackCRC; UInt32 UnpackCRC;
bool UnPackCRCDefined; bool UnpackCRCDefined;
CFolder(): UnPackCRCDefined(false) {} CFolder(): UnpackCRCDefined(false) {}
UInt64 GetUnPackSize() const // test it UInt64 GetUnpackSize() const // test it
{ {
if (UnPackSizes.IsEmpty()) if (UnpackSizes.IsEmpty())
return 0; return 0;
for (int i = UnPackSizes.Size() - 1; i >= 0; i--) for (int i = UnpackSizes.Size() - 1; i >= 0; i--)
if (FindBindPairForOutStream(i) < 0) if (FindBindPairForOutStream(i) < 0)
return UnPackSizes[i]; return UnpackSizes[i];
throw 1; throw 1;
} }
@@ -82,101 +82,171 @@ struct CFolder
} }
}; };
typedef FILETIME CArchiveFileTime; struct CUInt64DefVector
class CFileItem
{ {
public: CRecordVector<UInt64> Values;
CArchiveFileTime CreationTime; CRecordVector<bool> Defined;
CArchiveFileTime LastWriteTime;
CArchiveFileTime LastAccessTime; void Clear()
UInt64 UnPackSize; {
UInt64 StartPos; Values.Clear();
UInt32 Attributes; Defined.Clear();
UInt32 FileCRC; }
void ReserveDown()
{
Values.ReserveDown();
Values.ReserveDown();
}
bool GetItem(int index, UInt64 &value) const
{
if (index < Defined.Size() && Defined[index])
{
value = Values[index];
return true;
}
value = 0;
return false;
}
void SetItem(int index, bool defined, UInt64 value)
{
while (index >= Defined.Size())
Defined.Add(false);
Defined[index] = defined;
if (!defined)
return;
while (index >= Values.Size())
Values.Add(0);
Values[index] = value;
}
bool CheckSize(int size) const { return Defined.Size() == size || Defined.Size() == 0; }
};
struct CFileItem
{
UInt64 Size;
UInt32 Attrib;
UInt32 Crc;
UString Name; UString Name;
bool HasStream; // Test it !!! it means that there is bool HasStream; // Test it !!! it means that there is
// stream in some folder. It can be empty stream // stream in some folder. It can be empty stream
bool IsDirectory; bool IsDir;
bool IsAnti; bool CrcDefined;
bool IsFileCRCDefined; bool AttribDefined;
bool AreAttributesDefined;
bool IsCreationTimeDefined;
bool IsLastWriteTimeDefined;
bool IsLastAccessTimeDefined;
bool IsStartPosDefined;
/*
const bool HasStream() const {
return !IsDirectory && !IsAnti && UnPackSize != 0; }
*/
CFileItem(): CFileItem():
HasStream(true), HasStream(true),
IsDirectory(false), IsDir(false),
IsAnti(false), CrcDefined(false),
IsFileCRCDefined(false), AttribDefined(false)
AreAttributesDefined(false),
IsCreationTimeDefined(false),
IsLastWriteTimeDefined(false),
IsLastAccessTimeDefined(false),
IsStartPosDefined(false)
{} {}
void SetAttributes(UInt32 attributes) void SetAttrib(UInt32 attrib)
{ {
AreAttributesDefined = true; AttribDefined = true;
Attributes = attributes; Attrib = attrib;
}
void SetCreationTime(const CArchiveFileTime &creationTime)
{
IsCreationTimeDefined = true;
CreationTime = creationTime;
}
void SetLastWriteTime(const CArchiveFileTime &lastWriteTime)
{
IsLastWriteTimeDefined = true;
LastWriteTime = lastWriteTime;
}
void SetLastAccessTime(const CArchiveFileTime &lastAccessTime)
{
IsLastAccessTimeDefined = true;
LastAccessTime = lastAccessTime;
} }
}; };
struct CFileItem2
{
UInt64 CTime;
UInt64 ATime;
UInt64 MTime;
UInt64 StartPos;
bool CTimeDefined;
bool ATimeDefined;
bool MTimeDefined;
bool StartPosDefined;
bool IsAnti;
};
struct CArchiveDatabase struct CArchiveDatabase
{ {
CRecordVector<UInt64> PackSizes; CRecordVector<UInt64> PackSizes;
CRecordVector<bool> PackCRCsDefined; CRecordVector<bool> PackCRCsDefined;
CRecordVector<UInt32> PackCRCs; CRecordVector<UInt32> PackCRCs;
CObjectVector<CFolder> Folders; CObjectVector<CFolder> Folders;
CRecordVector<CNum> NumUnPackStreamsVector; CRecordVector<CNum> NumUnpackStreamsVector;
CObjectVector<CFileItem> Files; CObjectVector<CFileItem> Files;
CUInt64DefVector CTime;
CUInt64DefVector ATime;
CUInt64DefVector MTime;
CUInt64DefVector StartPos;
CRecordVector<bool> IsAnti;
void Clear() void Clear()
{ {
PackSizes.Clear(); PackSizes.Clear();
PackCRCsDefined.Clear(); PackCRCsDefined.Clear();
PackCRCs.Clear(); PackCRCs.Clear();
Folders.Clear(); Folders.Clear();
NumUnPackStreamsVector.Clear(); NumUnpackStreamsVector.Clear();
Files.Clear(); Files.Clear();
CTime.Clear();
ATime.Clear();
MTime.Clear();
StartPos.Clear();
IsAnti.Clear();
} }
void ReserveDown()
{
PackSizes.ReserveDown();
PackCRCsDefined.ReserveDown();
PackCRCs.ReserveDown();
Folders.ReserveDown();
NumUnpackStreamsVector.ReserveDown();
Files.ReserveDown();
CTime.ReserveDown();
ATime.ReserveDown();
MTime.ReserveDown();
StartPos.ReserveDown();
IsAnti.ReserveDown();
}
bool IsEmpty() const bool IsEmpty() const
{ {
return (PackSizes.IsEmpty() && return (PackSizes.IsEmpty() &&
PackCRCsDefined.IsEmpty() && PackCRCsDefined.IsEmpty() &&
PackCRCs.IsEmpty() && PackCRCs.IsEmpty() &&
Folders.IsEmpty() && Folders.IsEmpty() &&
NumUnPackStreamsVector.IsEmpty() && NumUnpackStreamsVector.IsEmpty() &&
Files.IsEmpty()); Files.IsEmpty());
} }
bool CheckNumFiles() const
{
int size = Files.Size();
return (
CTime.CheckSize(size) &&
ATime.CheckSize(size) &&
MTime.CheckSize(size) &&
StartPos.CheckSize(size) &&
(size == IsAnti.Size() || IsAnti.Size() == 0));
}
bool IsSolid() const bool IsSolid() const
{ {
for (int i = 0; i < NumUnPackStreamsVector.Size(); i++) for (int i = 0; i < NumUnpackStreamsVector.Size(); i++)
if (NumUnPackStreamsVector[i] > 1) if (NumUnpackStreamsVector[i] > 1)
return true; return true;
return false; return false;
} }
bool IsItemAnti(int index) const { return (index < IsAnti.Size() && IsAnti[index]); }
void SetItemAnti(int index, bool isAnti)
{
while (index >= IsAnti.Size())
IsAnti.Add(false);
IsAnti[index] = isAnti;
}
void GetFile(int index, CFileItem &file, CFileItem2 &file2) const;
void AddFile(const CFileItem &file, const CFileItem2 &file2);
}; };
}} }}

View File

File diff suppressed because it is too large Load Diff

View File

@@ -9,7 +9,6 @@
#include "7zEncode.h" #include "7zEncode.h"
#include "../../Common/OutBuffer.h" #include "../../Common/OutBuffer.h"
#include "../../../Common/DynamicBuffer.h"
namespace NArchive { namespace NArchive {
namespace N7z { namespace N7z {
@@ -23,56 +22,39 @@ public:
CWriteBufferLoc(): _size(0), _pos(0) {} CWriteBufferLoc(): _size(0), _pos(0) {}
void Init(Byte *data, size_t size) void Init(Byte *data, size_t size)
{ {
_pos = 0;
_data = data; _data = data;
_size = size; _size = size;
}
HRESULT Write(const void *data, size_t size)
{
if (_pos + size > _size)
return E_FAIL;
memmove(_data + _pos, data, size);
_pos += size;
return S_OK;
}
};
class CWriteDynamicBuffer
{
CByteDynamicBuffer _buffer;
size_t _pos;
public:
CWriteDynamicBuffer(): _pos(0) {}
void Init()
{
_pos = 0; _pos = 0;
} }
void Write(const void *data, size_t size) void WriteBytes(const void *data, size_t size)
{ {
if (_pos + size > _buffer.GetCapacity()) if (size > _size - _pos)
_buffer.EnsureCapacity(_pos + size); throw 1;
memmove(((Byte *)_buffer) +_pos, data, size); memcpy(_data + _pos, data, size);
_pos += size; _pos += size;
} }
operator Byte *() { return (Byte *)_buffer; }; void WriteByte(Byte b)
operator const Byte *() const { return (const Byte *)_buffer; }; {
size_t GetSize() const { return _pos; } if (_size == _pos)
throw 1;
_data[_pos++] = b;
}
size_t GetPos() const { return _pos; }
}; };
struct CHeaderOptions struct CHeaderOptions
{ {
// bool UseAdditionalHeaderStreams;
bool CompressMainHeader; bool CompressMainHeader;
bool WriteModified; bool WriteCTime;
bool WriteCreated; bool WriteATime;
bool WriteAccessed; bool WriteMTime;
CHeaderOptions(): CHeaderOptions():
// UseAdditionalHeaderStreams(false),
CompressMainHeader(true), CompressMainHeader(true),
WriteModified(true), WriteCTime(false),
WriteCreated(false), WriteATime(false),
WriteAccessed(false) {} WriteMTime(true)
{}
}; };
class COutArchive class COutArchive
@@ -80,56 +62,41 @@ class COutArchive
UInt64 _prefixHeaderPos; UInt64 _prefixHeaderPos;
HRESULT WriteDirect(const void *data, UInt32 size); HRESULT WriteDirect(const void *data, UInt32 size);
HRESULT WriteDirectByte(Byte b) { return WriteDirect(&b, 1); }
HRESULT WriteDirectUInt32(UInt32 value);
HRESULT WriteDirectUInt64(UInt64 value);
HRESULT WriteBytes(const void *data, size_t size); UInt64 GetPos() const;
HRESULT WriteBytes(const CByteBuffer &data); void WriteBytes(const void *data, size_t size);
HRESULT WriteByte(Byte b); void WriteBytes(const CByteBuffer &data) { WriteBytes(data, data.GetCapacity()); }
HRESULT WriteUInt32(UInt32 value); void WriteByte(Byte b);
HRESULT WriteNumber(UInt64 value); void WriteUInt32(UInt32 value);
HRESULT WriteID(UInt64 value) { return WriteNumber(value); } void WriteUInt64(UInt64 value);
void WriteNumber(UInt64 value);
void WriteID(UInt64 value) { WriteNumber(value); }
HRESULT WriteFolder(const CFolder &folder); void WriteFolder(const CFolder &folder);
HRESULT WriteFileHeader(const CFileItem &itemInfo); HRESULT WriteFileHeader(const CFileItem &itemInfo);
HRESULT WriteBoolVector(const CBoolVector &boolVector); void WriteBoolVector(const CBoolVector &boolVector);
HRESULT WriteHashDigests( void WriteHashDigests(
const CRecordVector<bool> &digestsDefined, const CRecordVector<bool> &digestsDefined,
const CRecordVector<UInt32> &hashDigests); const CRecordVector<UInt32> &hashDigests);
HRESULT WritePackInfo( void WritePackInfo(
UInt64 dataOffset, UInt64 dataOffset,
const CRecordVector<UInt64> &packSizes, const CRecordVector<UInt64> &packSizes,
const CRecordVector<bool> &packCRCsDefined, const CRecordVector<bool> &packCRCsDefined,
const CRecordVector<UInt32> &packCRCs); const CRecordVector<UInt32> &packCRCs);
HRESULT WriteUnPackInfo(const CObjectVector<CFolder> &folders); void WriteUnpackInfo(const CObjectVector<CFolder> &folders);
HRESULT WriteSubStreamsInfo( void WriteSubStreamsInfo(
const CObjectVector<CFolder> &folders, const CObjectVector<CFolder> &folders,
const CRecordVector<CNum> &numUnPackStreamsInFolders, const CRecordVector<CNum> &numUnpackStreamsInFolders,
const CRecordVector<UInt64> &unPackSizes, const CRecordVector<UInt64> &unpackSizes,
const CRecordVector<bool> &digestsDefined, const CRecordVector<bool> &digestsDefined,
const CRecordVector<UInt32> &hashDigests); const CRecordVector<UInt32> &hashDigests);
/* void SkipAlign(unsigned pos, unsigned alignSize);
HRESULT WriteStreamsInfo( void WriteAlignedBoolHeader(const CBoolVector &v, int numDefined, Byte type, unsigned itemSize);
UInt64 dataOffset, void WriteUInt64DefVector(const CUInt64DefVector &v, Byte type);
const CRecordVector<UInt64> &packSizes,
const CRecordVector<bool> &packCRCsDefined,
const CRecordVector<UInt32> &packCRCs,
bool externalFolders,
UInt64 externalFoldersStreamIndex,
const CObjectVector<CFolder> &folders,
const CRecordVector<CNum> &numUnPackStreamsInFolders,
const CRecordVector<UInt64> &unPackSizes,
const CRecordVector<bool> &digestsDefined,
const CRecordVector<UInt32> &hashDigests);
*/
HRESULT WriteTime(const CObjectVector<CFileItem> &files, Byte type);
HRESULT EncodeStream( HRESULT EncodeStream(
DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS
@@ -139,21 +106,17 @@ class COutArchive
DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS
CEncoder &encoder, const CByteBuffer &data, CEncoder &encoder, const CByteBuffer &data,
CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders); CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders);
HRESULT WriteHeader( void WriteHeader(
const CArchiveDatabase &database, const CArchiveDatabase &db,
const CHeaderOptions &headerOptions, const CHeaderOptions &headerOptions,
UInt64 &headerOffset); UInt64 &headerOffset);
bool _mainMode;
bool _dynamicMode;
bool _countMode; bool _countMode;
bool _writeToStream;
size_t _countSize; size_t _countSize;
UInt32 _crc;
COutBuffer _outByte; COutBuffer _outByte;
CWriteBufferLoc _outByte2; CWriteBufferLoc _outByte2;
CWriteDynamicBuffer _dynamicBuffer;
UInt32 _crc;
#ifdef _7Z_VOL #ifdef _7Z_VOL
bool _endMarker; bool _endMarker;
@@ -177,7 +140,7 @@ public:
HRESULT SkeepPrefixArchiveHeader(); HRESULT SkeepPrefixArchiveHeader();
HRESULT WriteDatabase( HRESULT WriteDatabase(
DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS
const CArchiveDatabase &database, const CArchiveDatabase &db,
const CCompressionMethodMode *options, const CCompressionMethodMode *options,
const CHeaderOptions &headerOptions); const CHeaderOptions &headerOptions);

View File

@@ -21,7 +21,7 @@ CPropMap kPropMap[] =
{ {
{ NID::kName, NULL, kpidPath, VT_BSTR}, { NID::kName, NULL, kpidPath, VT_BSTR},
{ NID::kSize, NULL, kpidSize, VT_UI8}, { NID::kSize, NULL, kpidSize, VT_UI8},
{ NID::kPackInfo, NULL, kpidPackedSize, VT_UI8}, { NID::kPackInfo, NULL, kpidPackSize, VT_UI8},
#ifdef _MULTI_PACK #ifdef _MULTI_PACK
{ 100, L"Pack0", kpidPackedSize0, VT_UI8}, { 100, L"Pack0", kpidPackedSize0, VT_UI8},
@@ -31,10 +31,10 @@ CPropMap kPropMap[] =
{ 104, L"Pack4", kpidPackedSize4, VT_UI8}, { 104, L"Pack4", kpidPackedSize4, VT_UI8},
#endif #endif
{ NID::kCreationTime, NULL, kpidCreationTime, VT_FILETIME}, { NID::kCTime, NULL, kpidCTime, VT_FILETIME},
{ NID::kLastWriteTime, NULL, kpidLastWriteTime, VT_FILETIME}, { NID::kMTime, NULL, kpidMTime, VT_FILETIME},
{ NID::kLastAccessTime, NULL, kpidLastAccessTime, VT_FILETIME}, { NID::kATime, NULL, kpidATime, VT_FILETIME},
{ NID::kWinAttributes, NULL, kpidAttributes, VT_UI4}, { NID::kWinAttributes, NULL, kpidAttrib, VT_UI4},
{ NID::kStartPos, NULL, kpidPosition, VT_UI4}, { NID::kStartPos, NULL, kpidPosition, VT_UI4},
{ NID::kCRC, NULL, kpidCRC, VT_UI4}, { NID::kCRC, NULL, kpidCRC, VT_UI4},
@@ -99,10 +99,10 @@ void CHandler::FillPopIDs()
if(_volumes.Size() < 1) if(_volumes.Size() < 1)
return; return;
const CVolume &volume = _volumes.Front(); const CVolume &volume = _volumes.Front();
const CArchiveDatabaseEx &_database = volume.Database; const CArchiveDatabaseEx &_db = volume.Database;
#endif #endif
CRecordVector<UInt64> fileInfoPopIDs = _database.ArchiveInfo.FileInfoPopIDs; CRecordVector<UInt64> fileInfoPopIDs = _db.ArchiveInfo.FileInfoPopIDs;
RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream); RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream);
RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile); RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile);
@@ -111,9 +111,9 @@ void CHandler::FillPopIDs()
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kAnti); CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kAnti);
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kSize); CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kSize);
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kPackInfo); CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kPackInfo);
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCreationTime); CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCTime);
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kLastWriteTime); CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kMTime);
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kLastAccessTime); CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kATime);
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kWinAttributes); CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kWinAttributes);
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCRC); CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCRC);
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kComment); CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kComment);
@@ -133,7 +133,7 @@ void CHandler::FillPopIDs()
#endif #endif
#ifndef _SFX #ifndef _SFX
InsertToHead(_fileInfoPopIDs, NID::kLastWriteTime); InsertToHead(_fileInfoPopIDs, NID::kMTime);
InsertToHead(_fileInfoPopIDs, NID::kPackInfo); InsertToHead(_fileInfoPopIDs, NID::kPackInfo);
InsertToHead(_fileInfoPopIDs, NID::kSize); InsertToHead(_fileInfoPopIDs, NID::kSize);
InsertToHead(_fileInfoPopIDs, NID::kName); InsertToHead(_fileInfoPopIDs, NID::kName);

View File

@@ -117,9 +117,9 @@ static int CompareFolderRefs(const int *p1, const int *p2, void *param)
db.Folders[i1], db.Folders[i1],
db.Folders[i2])); db.Folders[i2]));
RINOZ(MyCompare( RINOZ(MyCompare(
db.NumUnPackStreamsVector[i1], db.NumUnpackStreamsVector[i1],
db.NumUnPackStreamsVector[i2])); db.NumUnpackStreamsVector[i2]));
if (db.NumUnPackStreamsVector[i1] == 0) if (db.NumUnpackStreamsVector[i1] == 0)
return 0; return 0;
return CompareFiles( return CompareFiles(
db.Files[db.FolderStartFileIndex[i1]], db.Files[db.FolderStartFileIndex[i1]],
@@ -133,9 +133,9 @@ static int CompareEmptyItems(const int *p1, const int *p2, void *param)
const CObjectVector<CUpdateItem> &updateItems = *(const CObjectVector<CUpdateItem> *)param; const CObjectVector<CUpdateItem> &updateItems = *(const CObjectVector<CUpdateItem> *)param;
const CUpdateItem &u1 = updateItems[*p1]; const CUpdateItem &u1 = updateItems[*p1];
const CUpdateItem &u2 = updateItems[*p2]; const CUpdateItem &u2 = updateItems[*p2];
if (u1.IsDirectory != u2.IsDirectory) if (u1.IsDir != u2.IsDir)
return (u1.IsDirectory) ? 1 : -1; return (u1.IsDir) ? 1 : -1;
if (u1.IsDirectory) if (u1.IsDir)
{ {
if (u1.IsAnti != u2.IsAnti) if (u1.IsAnti != u2.IsAnti)
return (u1.IsAnti ? 1 : -1); return (u1.IsAnti ? 1 : -1);
@@ -212,29 +212,29 @@ int GetExtIndex(const char *ext)
struct CRefItem struct CRefItem
{ {
UInt32 Index;
const CUpdateItem *UpdateItem; const CUpdateItem *UpdateItem;
UInt32 Index;
UInt32 ExtensionPos; UInt32 ExtensionPos;
UInt32 NamePos; UInt32 NamePos;
int ExtensionIndex; int ExtensionIndex;
CRefItem(UInt32 index, const CUpdateItem &updateItem, bool sortByType): CRefItem(UInt32 index, const CUpdateItem &ui, bool sortByType):
UpdateItem(&ui),
Index(index), Index(index),
UpdateItem(&updateItem),
ExtensionPos(0), ExtensionPos(0),
NamePos(0), NamePos(0),
ExtensionIndex(0) ExtensionIndex(0)
{ {
if (sortByType) if (sortByType)
{ {
int slashPos = GetReverseSlashPos(updateItem.Name); int slashPos = GetReverseSlashPos(ui.Name);
NamePos = ((slashPos >= 0) ? (slashPos + 1) : 0); NamePos = ((slashPos >= 0) ? (slashPos + 1) : 0);
int dotPos = updateItem.Name.ReverseFind(L'.'); int dotPos = ui.Name.ReverseFind(L'.');
if (dotPos < 0 || (dotPos < slashPos && slashPos >= 0)) if (dotPos < 0 || (dotPos < slashPos && slashPos >= 0))
ExtensionPos = updateItem.Name.Length(); ExtensionPos = ui.Name.Length();
else else
{ {
ExtensionPos = dotPos + 1; ExtensionPos = dotPos + 1;
UString us = updateItem.Name.Mid(ExtensionPos); UString us = ui.Name.Mid(ExtensionPos);
if (!us.IsEmpty()) if (!us.IsEmpty())
{ {
us.MakeLower(); us.MakeLower();
@@ -264,9 +264,9 @@ static int CompareUpdateItems(const CRefItem *p1, const CRefItem *p2, void *para
const CUpdateItem &u1 = *a1.UpdateItem; const CUpdateItem &u1 = *a1.UpdateItem;
const CUpdateItem &u2 = *a2.UpdateItem; const CUpdateItem &u2 = *a2.UpdateItem;
int n; int n;
if (u1.IsDirectory != u2.IsDirectory) if (u1.IsDir != u2.IsDir)
return (u1.IsDirectory) ? 1 : -1; return (u1.IsDir) ? 1 : -1;
if (u1.IsDirectory) if (u1.IsDir)
{ {
if (u1.IsAnti != u2.IsAnti) if (u1.IsAnti != u2.IsAnti)
return (u1.IsAnti ? 1 : -1); return (u1.IsAnti ? 1 : -1);
@@ -279,8 +279,9 @@ static int CompareUpdateItems(const CRefItem *p1, const CRefItem *p2, void *para
RINOZ(MyCompare(a1.ExtensionIndex, a2.ExtensionIndex)) RINOZ(MyCompare(a1.ExtensionIndex, a2.ExtensionIndex))
RINOZ(MyStringCompareNoCase(u1.Name + a1.ExtensionPos, u2.Name + a2.ExtensionPos)); RINOZ(MyStringCompareNoCase(u1.Name + a1.ExtensionPos, u2.Name + a2.ExtensionPos));
RINOZ(MyStringCompareNoCase(u1.Name + a1.NamePos, u2.Name + a2.NamePos)); RINOZ(MyStringCompareNoCase(u1.Name + a1.NamePos, u2.Name + a2.NamePos));
if (u1.IsLastWriteTimeDefined && u2.IsLastWriteTimeDefined) if (!u1.MTimeDefined && u2.MTimeDefined) return 1;
RINOZ(CompareFileTime(&u1.LastWriteTime, &u2.LastWriteTime)); if (u1.MTimeDefined && !u2.MTimeDefined) return -1;
if (u1.MTimeDefined && u2.MTimeDefined) RINOZ(MyCompare(u1.MTime, u2.MTime));
RINOZ(MyCompare(u1.Size, u2.Size)) RINOZ(MyCompare(u1.Size, u2.Size))
} }
return MyStringCompareNoCase(u1.Name, u2.Name); return MyStringCompareNoCase(u1.Name, u2.Name);
@@ -411,14 +412,14 @@ static void SplitFilesToGroups(
int i; int i;
for (i = 0; i < updateItems.Size(); i++) for (i = 0; i < updateItems.Size(); i++)
{ {
const CUpdateItem &updateItem = updateItems[i]; const CUpdateItem &ui = updateItems[i];
if (!updateItem.NewData) if (!ui.NewData)
continue; continue;
if (!updateItem.HasStream()) if (!ui.HasStream())
continue; continue;
if (useFilters) if (useFilters)
{ {
const UString name = updateItem.Name; const UString name = ui.Name;
int dotPos = name.ReverseFind(L'.'); int dotPos = name.ReverseFind(L'.');
if (dotPos >= 0) if (dotPos >= 0)
{ {
@@ -442,31 +443,31 @@ static void SplitFilesToGroups(
i++; i++;
} }
static void FromUpdateItemToFileItem(const CUpdateItem &updateItem, static void FromUpdateItemToFileItem(const CUpdateItem &ui,
CFileItem &file) CFileItem &file, CFileItem2 &file2)
{ {
file.Name = NItemName::MakeLegalName(updateItem.Name); file.Name = NItemName::MakeLegalName(ui.Name);
if (updateItem.AttributesAreDefined) if (ui.AttribDefined)
file.SetAttributes(updateItem.Attributes); file.SetAttrib(ui.Attrib);
if (updateItem.IsCreationTimeDefined) file2.CTime = ui.CTime; file2.CTimeDefined = ui.CTimeDefined;
file.SetCreationTime(updateItem.CreationTime); file2.ATime = ui.ATime; file2.ATimeDefined = ui.ATimeDefined;
if (updateItem.IsLastWriteTimeDefined) file2.MTime = ui.MTime; file2.MTimeDefined = ui.MTimeDefined;
file.SetLastWriteTime(updateItem.LastWriteTime); file2.IsAnti = ui.IsAnti;
if (updateItem.IsLastAccessTimeDefined) file2.StartPosDefined = false;
file.SetLastAccessTime(updateItem.LastAccessTime);
file.UnPackSize = updateItem.Size; file.Size = ui.Size;
file.IsDirectory = updateItem.IsDirectory; file.IsDir = ui.IsDir;
file.IsAnti = updateItem.IsAnti; file.HasStream = ui.HasStream();
file.HasStream = updateItem.HasStream();
} }
static HRESULT Update2( static HRESULT Update2(
DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS
IInStream *inStream, IInStream *inStream,
const CArchiveDatabaseEx *database, const CArchiveDatabaseEx *db,
const CObjectVector<CUpdateItem> &updateItems, const CObjectVector<CUpdateItem> &updateItems,
COutArchive &archive,
CArchiveDatabase &newDatabase,
ISequentialOutStream *seqOutStream, ISequentialOutStream *seqOutStream,
IArchiveUpdateCallback *updateCallback, IArchiveUpdateCallback *updateCallback,
const CUpdateOptions &options) const CUpdateOptions &options)
@@ -481,17 +482,17 @@ static HRESULT Update2(
return E_NOTIMPL; return E_NOTIMPL;
*/ */
UInt64 startBlockSize = database != 0 ? database->ArchiveInfo.StartPosition: 0; UInt64 startBlockSize = db != 0 ? db->ArchiveInfo.StartPosition: 0;
if (startBlockSize > 0 && !options.RemoveSfxBlock) if (startBlockSize > 0 && !options.RemoveSfxBlock)
{ {
RINOK(WriteRange(inStream, seqOutStream, 0, startBlockSize, NULL)); RINOK(WriteRange(inStream, seqOutStream, 0, startBlockSize, NULL));
} }
CRecordVector<int> fileIndexToUpdateIndexMap; CRecordVector<int> fileIndexToUpdateIndexMap;
if (database != 0) if (db != 0)
{ {
fileIndexToUpdateIndexMap.Reserve(database->Files.Size()); fileIndexToUpdateIndexMap.Reserve(db->Files.Size());
for (int i = 0; i < database->Files.Size(); i++) for (int i = 0; i < db->Files.Size(); i++)
fileIndexToUpdateIndexMap.Add(-1); fileIndexToUpdateIndexMap.Add(-1);
} }
int i; int i;
@@ -503,17 +504,17 @@ static HRESULT Update2(
} }
CRecordVector<int> folderRefs; CRecordVector<int> folderRefs;
if (database != 0) if (db != 0)
{ {
for(i = 0; i < database->Folders.Size(); i++) for(i = 0; i < db->Folders.Size(); i++)
{ {
CNum indexInFolder = 0; CNum indexInFolder = 0;
CNum numCopyItems = 0; CNum numCopyItems = 0;
CNum numUnPackStreams = database->NumUnPackStreamsVector[i]; CNum numUnpackStreams = db->NumUnpackStreamsVector[i];
for (CNum fileIndex = database->FolderStartFileIndex[i]; for (CNum fileIndex = db->FolderStartFileIndex[i];
indexInFolder < numUnPackStreams; fileIndex++) indexInFolder < numUnpackStreams; fileIndex++)
{ {
if (database->Files[fileIndex].HasStream) if (db->Files[fileIndex].HasStream)
{ {
indexInFolder++; indexInFolder++;
int updateIndex = fileIndexToUpdateIndexMap[fileIndex]; int updateIndex = fileIndexToUpdateIndexMap[fileIndex];
@@ -522,38 +523,35 @@ static HRESULT Update2(
numCopyItems++; numCopyItems++;
} }
} }
if (numCopyItems != numUnPackStreams && numCopyItems != 0) if (numCopyItems != numUnpackStreams && numCopyItems != 0)
return E_NOTIMPL; // It needs repacking !!! return E_NOTIMPL; // It needs repacking !!!
if (numCopyItems > 0) if (numCopyItems > 0)
folderRefs.Add(i); folderRefs.Add(i);
} }
folderRefs.Sort(CompareFolderRefs, (void *)database); folderRefs.Sort(CompareFolderRefs, (void *)db);
} }
CArchiveDatabase newDatabase;
//////////////////////////// ////////////////////////////
COutArchive archive;
RINOK(archive.Create(seqOutStream, false)); RINOK(archive.Create(seqOutStream, false));
RINOK(archive.SkeepPrefixArchiveHeader()); RINOK(archive.SkeepPrefixArchiveHeader());
UInt64 complexity = 0; UInt64 complexity = 0;
for(i = 0; i < folderRefs.Size(); i++) for(i = 0; i < folderRefs.Size(); i++)
complexity += database->GetFolderFullPackSize(folderRefs[i]); complexity += db->GetFolderFullPackSize(folderRefs[i]);
UInt64 inSizeForReduce = 0; UInt64 inSizeForReduce = 0;
for(i = 0; i < updateItems.Size(); i++) for(i = 0; i < updateItems.Size(); i++)
{ {
const CUpdateItem &updateItem = updateItems[i]; const CUpdateItem &ui = updateItems[i];
if (updateItem.NewData) if (ui.NewData)
{ {
complexity += updateItem.Size; complexity += ui.Size;
if (numSolidFiles == 1) if (numSolidFiles == 1)
{ {
if (updateItem.Size > inSizeForReduce) if (ui.Size > inSizeForReduce)
inSizeForReduce = updateItem.Size; inSizeForReduce = ui.Size;
} }
else else
inSizeForReduce += updateItem.Size; inSizeForReduce += ui.Size;
} }
} }
RINOK(updateCallback->SetTotal(complexity)); RINOK(updateCallback->SetTotal(complexity));
@@ -573,52 +571,57 @@ static HRESULT Update2(
int folderIndex = folderRefs[i]; int folderIndex = folderRefs[i];
lps->ProgressOffset = complexity; lps->ProgressOffset = complexity;
UInt64 packSize = database->GetFolderFullPackSize(folderIndex); UInt64 packSize = db->GetFolderFullPackSize(folderIndex);
RINOK(WriteRange(inStream, archive.SeqStream, RINOK(WriteRange(inStream, archive.SeqStream,
database->GetFolderStreamPos(folderIndex, 0), packSize, progress)); db->GetFolderStreamPos(folderIndex, 0), packSize, progress));
complexity += packSize; complexity += packSize;
const CFolder &folder = database->Folders[folderIndex]; const CFolder &folder = db->Folders[folderIndex];
CNum startIndex = database->FolderStartPackStreamIndex[folderIndex]; CNum startIndex = db->FolderStartPackStreamIndex[folderIndex];
for (int j = 0; j < folder.PackStreams.Size(); j++) for (int j = 0; j < folder.PackStreams.Size(); j++)
{ {
newDatabase.PackSizes.Add(database->PackSizes[startIndex + j]); newDatabase.PackSizes.Add(db->PackSizes[startIndex + j]);
// newDatabase.PackCRCsDefined.Add(database.PackCRCsDefined[startIndex + j]); // newDatabase.PackCRCsDefined.Add(db.PackCRCsDefined[startIndex + j]);
// newDatabase.PackCRCs.Add(database.PackCRCs[startIndex + j]); // newDatabase.PackCRCs.Add(db.PackCRCs[startIndex + j]);
} }
newDatabase.Folders.Add(folder); newDatabase.Folders.Add(folder);
CNum numUnPackStreams = database->NumUnPackStreamsVector[folderIndex]; CNum numUnpackStreams = db->NumUnpackStreamsVector[folderIndex];
newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams); newDatabase.NumUnpackStreamsVector.Add(numUnpackStreams);
CNum indexInFolder = 0; CNum indexInFolder = 0;
for (CNum fi = database->FolderStartFileIndex[folderIndex]; for (CNum fi = db->FolderStartFileIndex[folderIndex];
indexInFolder < numUnPackStreams; fi++) indexInFolder < numUnpackStreams; fi++)
{ {
CFileItem file = database->Files[fi]; CFileItem file;
CFileItem2 file2;
db->GetFile(fi, file, file2);
if (file.HasStream) if (file.HasStream)
{ {
indexInFolder++; indexInFolder++;
int updateIndex = fileIndexToUpdateIndexMap[fi]; int updateIndex = fileIndexToUpdateIndexMap[fi];
if (updateIndex >= 0) if (updateIndex >= 0)
{ {
const CUpdateItem &updateItem = updateItems[updateIndex]; const CUpdateItem &ui = updateItems[updateIndex];
if (updateItem.NewProperties) if (ui.NewProperties)
{ {
CFileItem file2; CFileItem uf;
FromUpdateItemToFileItem(updateItem, file2); FromUpdateItemToFileItem(ui, uf, file2);
file2.UnPackSize = file.UnPackSize; uf.Size = file.Size;
file2.FileCRC = file.FileCRC; uf.Crc = file.Crc;
file2.IsFileCRCDefined = file.IsFileCRCDefined; uf.CrcDefined = file.CrcDefined;
file2.HasStream = file.HasStream; uf.HasStream = file.HasStream;
file = file2; file = uf;
} }
} }
newDatabase.Files.Add(file); newDatabase.AddFile(file, file2);
} }
} }
} }
folderRefs.ClearAndFree();
fileIndexToUpdateIndexMap.ClearAndFree();
///////////////////////////////////////// /////////////////////////////////////////
// Compress New Files // Compress New Files
@@ -651,13 +654,13 @@ static HRESULT Update2(
UInt32 index = refItems[i].Index; UInt32 index = refItems[i].Index;
indices.Add(index); indices.Add(index);
/* /*
const CUpdateItem &updateItem = updateItems[index]; const CUpdateItem &ui = updateItems[index];
CFileItem file; CFileItem file;
if (updateItem.NewProperties) if (ui.NewProperties)
FromUpdateItemToFileItem(updateItem, file); FromUpdateItemToFileItem(ui, file);
else else
file = database.Files[updateItem.IndexInArchive]; file = db.Files[ui.IndexInArchive];
if (file.IsAnti || file.IsDirectory) if (file.IsAnti || file.IsDir)
return E_FAIL; return E_FAIL;
newDatabase.Files.Add(file); newDatabase.Files.Add(file);
*/ */
@@ -673,13 +676,13 @@ static HRESULT Update2(
for (numSubFiles = 0; i + numSubFiles < numFiles && for (numSubFiles = 0; i + numSubFiles < numFiles &&
numSubFiles < numSolidFiles; numSubFiles++) numSubFiles < numSolidFiles; numSubFiles++)
{ {
const CUpdateItem &updateItem = updateItems[indices[i + numSubFiles]]; const CUpdateItem &ui = updateItems[indices[i + numSubFiles]];
totalSize += updateItem.Size; totalSize += ui.Size;
if (totalSize > options.NumSolidBytes) if (totalSize > options.NumSolidBytes)
break; break;
if (options.SolidExtension) if (options.SolidExtension)
{ {
UString ext = updateItem.GetExtension(); UString ext = ui.GetExtension();
if (numSubFiles == 0) if (numSubFiles == 0)
prevExtension = ext; prevExtension = ext;
else else
@@ -705,23 +708,24 @@ static HRESULT Update2(
for (; startPackIndex < newDatabase.PackSizes.Size(); startPackIndex++) for (; startPackIndex < newDatabase.PackSizes.Size(); startPackIndex++)
lps->OutSize += newDatabase.PackSizes[startPackIndex]; lps->OutSize += newDatabase.PackSizes[startPackIndex];
lps->InSize += folderItem.GetUnPackSize(); lps->InSize += folderItem.GetUnpackSize();
// for() // for()
// newDatabase.PackCRCsDefined.Add(false); // newDatabase.PackCRCsDefined.Add(false);
// newDatabase.PackCRCs.Add(0); // newDatabase.PackCRCs.Add(0);
newDatabase.Folders.Add(folderItem); newDatabase.Folders.Add(folderItem);
CNum numUnPackStreams = 0; CNum numUnpackStreams = 0;
for (int subIndex = 0; subIndex < numSubFiles; subIndex++) for (int subIndex = 0; subIndex < numSubFiles; subIndex++)
{ {
const CUpdateItem &updateItem = updateItems[indices[i + subIndex]]; const CUpdateItem &ui = updateItems[indices[i + subIndex]];
CFileItem file; CFileItem file;
if (updateItem.NewProperties) CFileItem2 file2;
FromUpdateItemToFileItem(updateItem, file); if (ui.NewProperties)
FromUpdateItemToFileItem(ui, file, file2);
else else
file = database->Files[updateItem.IndexInArchive]; db->GetFile(ui.IndexInArchive, file, file2);
if (file.IsAnti || file.IsDirectory) if (file2.IsAnti || file.IsDir)
return E_FAIL; return E_FAIL;
/* /*
@@ -734,28 +738,30 @@ static HRESULT Update2(
// file.Name += L".locked"; // file.Name += L".locked";
} }
file.FileCRC = inStreamSpec->CRCs[subIndex]; file.Crc = inStreamSpec->CRCs[subIndex];
file.UnPackSize = inStreamSpec->Sizes[subIndex]; file.Size = inStreamSpec->Sizes[subIndex];
if (file.UnPackSize != 0) if (file.Size != 0)
{ {
file.IsFileCRCDefined = true; file.CrcDefined = true;
file.HasStream = true; file.HasStream = true;
numUnPackStreams++; numUnpackStreams++;
} }
else else
{ {
file.IsFileCRCDefined = false; file.CrcDefined = false;
file.HasStream = false; file.HasStream = false;
} }
newDatabase.Files.Add(file); newDatabase.AddFile(file, file2);
} }
// numUnPackStreams = 0 is very bad case for locked files // numUnpackStreams = 0 is very bad case for locked files
// v3.13 doesn't understand it. // v3.13 doesn't understand it.
newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams); newDatabase.NumUnpackStreamsVector.Add(numUnpackStreams);
i += numSubFiles; i += numSubFiles;
} }
} }
groups.ClearAndFree();
{ {
///////////////////////////////////////// /////////////////////////////////////////
// Write Empty Files & Folders // Write Empty Files & Folders
@@ -763,267 +769,51 @@ static HRESULT Update2(
CRecordVector<int> emptyRefs; CRecordVector<int> emptyRefs;
for(i = 0; i < updateItems.Size(); i++) for(i = 0; i < updateItems.Size(); i++)
{ {
const CUpdateItem &updateItem = updateItems[i]; const CUpdateItem &ui = updateItems[i];
if (updateItem.NewData) if (ui.NewData)
{ {
if (updateItem.HasStream()) if (ui.HasStream())
continue; continue;
} }
else else
if (updateItem.IndexInArchive != -1) if (ui.IndexInArchive != -1)
if (database->Files[updateItem.IndexInArchive].HasStream) if (db->Files[ui.IndexInArchive].HasStream)
continue; continue;
emptyRefs.Add(i); emptyRefs.Add(i);
} }
emptyRefs.Sort(CompareEmptyItems, (void *)&updateItems); emptyRefs.Sort(CompareEmptyItems, (void *)&updateItems);
for(i = 0; i < emptyRefs.Size(); i++) for (i = 0; i < emptyRefs.Size(); i++)
{ {
const CUpdateItem &updateItem = updateItems[emptyRefs[i]]; const CUpdateItem &ui = updateItems[emptyRefs[i]];
CFileItem file; CFileItem file;
if (updateItem.NewProperties) CFileItem2 file2;
FromUpdateItemToFileItem(updateItem, file); if (ui.NewProperties)
FromUpdateItemToFileItem(ui, file, file2);
else else
file = database->Files[updateItem.IndexInArchive]; db->GetFile(ui.IndexInArchive, file, file2);
newDatabase.Files.Add(file); newDatabase.AddFile(file, file2);
} }
} }
/* newDatabase.ReserveDown();
if (newDatabase.Files.Size() != updateItems.Size())
return E_FAIL;
*/
return archive.WriteDatabase(EXTERNAL_CODECS_LOC_VARS
newDatabase, options.HeaderMethod, options.HeaderOptions);
}
#ifdef _7Z_VOL
static const UInt64 k_Copy = 0x0;
static HRESULT WriteVolumeHeader(COutArchive &archive, CFileItem &file, const CUpdateOptions &options)
{
CCoderInfo coder;
coder.NumInStreams = coder.NumOutStreams = 1;
coder.MethodID = k_Copy;
CFolder folder;
folder.Coders.Add(coder);
folder.PackStreams.Add(0);
CNum numUnPackStreams = 0;
if (file.UnPackSize != 0)
{
file.IsFileCRCDefined = true;
file.HasStream = true;
numUnPackStreams++;
}
else
{
throw 1;
file.IsFileCRCDefined = false;
file.HasStream = false;
}
folder.UnPackSizes.Add(file.UnPackSize);
CArchiveDatabase newDatabase;
newDatabase.Files.Add(file);
newDatabase.Folders.Add(folder);
newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams);
newDatabase.PackSizes.Add(file.UnPackSize);
newDatabase.PackCRCsDefined.Add(false);
newDatabase.PackCRCs.Add(file.FileCRC);
return archive.WriteDatabase(newDatabase,
options.HeaderMethod,
false,
false);
}
HRESULT UpdateVolume(
IInStream *inStream,
const CArchiveDatabaseEx *database,
CObjectVector<CUpdateItem> &updateItems,
ISequentialOutStream *seqOutStream,
IArchiveUpdateCallback *updateCallback,
const CUpdateOptions &options)
{
if (updateItems.Size() != 1)
return E_NOTIMPL;
CMyComPtr<IArchiveUpdateCallback2> volumeCallback;
RINOK(updateCallback->QueryInterface(IID_IArchiveUpdateCallback2, (void **)&volumeCallback));
if (!volumeCallback)
return E_NOTIMPL;
CMyComPtr<ISequentialInStream> fileStream;
HRESULT result = updateCallback->GetStream(0, &fileStream);
if (result != S_OK && result != S_FALSE)
return result;
if (result == S_FALSE)
return E_FAIL;
CFileItem file;
const CUpdateItem &updateItem = updateItems[0];
if (updateItem.NewProperties)
FromUpdateItemToFileItem(updateItem, file);
else
file = database->Files[updateItem.IndexInArchive];
if (file.IsAnti || file.IsDirectory)
return E_FAIL;
UInt64 complexity = 0;
file.IsStartPosDefined = true;
file.StartPos = 0;
for (UInt64 volumeIndex = 0; true; volumeIndex++)
{
UInt64 volSize;
RINOK(volumeCallback->GetVolumeSize(volumeIndex, &volSize));
UInt64 pureSize = COutArchive::GetVolPureSize(volSize, file.Name.Length(), true);
CMyComPtr<ISequentialOutStream> volumeStream;
RINOK(volumeCallback->GetVolumeStream(volumeIndex, &volumeStream));
COutArchive archive;
RINOK(archive.Create(volumeStream, true));
RINOK(archive.SkeepPrefixArchiveHeader());
CSequentialInStreamWithCRC *inCrcStreamSpec = new CSequentialInStreamWithCRC;
CMyComPtr<ISequentialInStream> inCrcStream = inCrcStreamSpec;
inCrcStreamSpec->Init(fileStream);
RINOK(WriteRange(inCrcStream, volumeStream, pureSize, updateCallback, complexity));
file.UnPackSize = inCrcStreamSpec->GetSize();
if (file.UnPackSize == 0)
break;
file.FileCRC = inCrcStreamSpec->GetCRC();
RINOK(WriteVolumeHeader(archive, file, options));
file.StartPos += file.UnPackSize;
if (file.UnPackSize < pureSize)
break;
}
return S_OK; return S_OK;
} }
class COutVolumeStream:
public ISequentialOutStream,
public CMyUnknownImp
{
int _volIndex;
UInt64 _volSize;
UInt64 _curPos;
CMyComPtr<ISequentialOutStream> _volumeStream;
COutArchive _archive;
CCRC _crc;
public:
MY_UNKNOWN_IMP
CFileItem _file;
CUpdateOptions _options;
CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;
void Init(IArchiveUpdateCallback2 *volumeCallback,
const UString &name)
{
_file.Name = name;
_file.IsStartPosDefined = true;
_file.StartPos = 0;
VolumeCallback = volumeCallback;
_volIndex = 0;
_volSize = 0;
}
HRESULT Flush();
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
};
HRESULT COutVolumeStream::Flush()
{
if (_volumeStream)
{
_file.UnPackSize = _curPos;
_file.FileCRC = _crc.GetDigest();
RINOK(WriteVolumeHeader(_archive, _file, _options));
_archive.Close();
_volumeStream.Release();
_file.StartPos += _file.UnPackSize;
}
return S_OK;
}
STDMETHODIMP COutVolumeStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
if(processedSize != NULL)
*processedSize = 0;
while(size > 0)
{
if (!_volumeStream)
{
RINOK(VolumeCallback->GetVolumeSize(_volIndex, &_volSize));
RINOK(VolumeCallback->GetVolumeStream(_volIndex, &_volumeStream));
_volIndex++;
_curPos = 0;
RINOK(_archive.Create(_volumeStream, true));
RINOK(_archive.SkeepPrefixArchiveHeader());
_crc.Init();
continue;
}
UInt64 pureSize = COutArchive::GetVolPureSize(_volSize, _file.Name.Length());
UInt32 curSize = (UInt32)MyMin(UInt64(size), pureSize - _curPos);
_crc.Update(data, curSize);
UInt32 realProcessed;
RINOK(_volumeStream->Write(data, curSize, &realProcessed))
data = (void *)((Byte *)data + realProcessed);
size -= realProcessed;
if(processedSize != NULL)
*processedSize += realProcessed;
_curPos += realProcessed;
if (realProcessed != curSize && realProcessed == 0)
return E_FAIL;
if (_curPos == pureSize)
{
RINOK(Flush());
}
}
return S_OK;
}
#endif
HRESULT Update( HRESULT Update(
DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS
IInStream *inStream, IInStream *inStream,
const CArchiveDatabaseEx *database, const CArchiveDatabaseEx *db,
const CObjectVector<CUpdateItem> &updateItems, const CObjectVector<CUpdateItem> &updateItems,
COutArchive &archive,
CArchiveDatabase &newDatabase,
ISequentialOutStream *seqOutStream, ISequentialOutStream *seqOutStream,
IArchiveUpdateCallback *updateCallback, IArchiveUpdateCallback *updateCallback,
const CUpdateOptions &options) const CUpdateOptions &options)
{ {
#ifdef _7Z_VOL
if (seqOutStream)
#endif
return Update2( return Update2(
EXTERNAL_CODECS_LOC_VARS EXTERNAL_CODECS_LOC_VARS
inStream, database, updateItems, inStream, db, updateItems,
seqOutStream, updateCallback, options); archive, newDatabase, seqOutStream, updateCallback, options);
#ifdef _7Z_VOL
if (options.VolumeMode)
return UpdateVolume(inStream, database, updateItems,
seqOutStream, updateCallback, options);
COutVolumeStream *volStreamSpec = new COutVolumeStream;
CMyComPtr<ISequentialOutStream> volStream = volStreamSpec;
CMyComPtr<IArchiveUpdateCallback2> volumeCallback;
RINOK(updateCallback->QueryInterface(IID_IArchiveUpdateCallback2, (void **)&volumeCallback));
if (!volumeCallback)
return E_NOTIMPL;
volStreamSpec->Init(volumeCallback, L"a.7z");
volStreamSpec->_options = options;
RINOK(Update2(inStream, database, updateItems,
volStream, updateCallback, options));
return volStreamSpec->Flush();
#endif
} }
}} }}

View File

@@ -14,38 +14,40 @@ namespace N7z {
struct CUpdateItem struct CUpdateItem
{ {
bool NewData;
bool NewProperties;
int IndexInArchive; int IndexInArchive;
int IndexInClient; int IndexInClient;
UInt32 Attributes; UInt64 CTime;
FILETIME CreationTime; UInt64 ATime;
FILETIME LastWriteTime; UInt64 MTime;
FILETIME LastAccessTime;
UInt64 Size; UInt64 Size;
UString Name; UString Name;
UInt32 Attrib;
bool NewData;
bool NewProperties;
bool IsAnti; bool IsAnti;
bool IsDirectory; bool IsDir;
bool IsCreationTimeDefined; bool AttribDefined;
bool IsLastWriteTimeDefined; bool CTimeDefined;
bool IsLastAccessTimeDefined; bool ATimeDefined;
bool AttributesAreDefined; bool MTimeDefined;
bool HasStream() const { return !IsDir && !IsAnti && Size != 0; }
bool HasStream() const
{ return !IsDirectory && !IsAnti && Size != 0; }
CUpdateItem(): CUpdateItem():
IsAnti(false), IsAnti(false),
AttributesAreDefined(false), IsDir(false),
IsCreationTimeDefined(false), AttribDefined(false),
IsLastWriteTimeDefined(false), CTimeDefined(false),
IsLastAccessTimeDefined(false) ATimeDefined(false),
MTimeDefined(false)
{} {}
void SetDirectoryStatusFromAttributes() void SetDirStatusFromAttrib() { IsDir = ((Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0); };
{ IsDirectory = ((Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0); };
int GetExtensionPos() const; int GetExtensionPos() const;
UString GetExtension() const; UString GetExtension() const;
@@ -70,8 +72,10 @@ struct CUpdateOptions
HRESULT Update( HRESULT Update(
DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS
IInStream *inStream, IInStream *inStream,
const CArchiveDatabaseEx *database, const CArchiveDatabaseEx *db,
const CObjectVector<CUpdateItem> &updateItems, const CObjectVector<CUpdateItem> &updateItems,
COutArchive &archive,
CArchiveDatabase &newDatabase,
ISequentialOutStream *seqOutStream, ISequentialOutStream *seqOutStream,
IArchiveUpdateCallback *updateCallback, IArchiveUpdateCallback *updateCallback,
const CUpdateOptions &options); const CUpdateOptions &options);

111
CPP/7zip/Archive/7z/makefile Executable file
View File

@@ -0,0 +1,111 @@
PROG = 7z.dll
DEF_FILE = ../Archive.def
CFLAGS = $(CFLAGS) -I ../../../ \
-DCOMPRESS_MT \
-DEXTERNAL_CODECS \
LIBS = $(LIBS) oleaut32.lib user32.lib
AR_OBJS = \
$O\ArchiveExports.obj \
$O\DllExports.obj \
7Z_OBJS = \
$O\7zCompressionMode.obj \
$O\7zDecode.obj \
$O\7zEncode.obj \
$O\7zExtract.obj \
$O\7zFolderInStream.obj \
$O\7zFolderOutStream.obj \
$O\7zHandler.obj \
$O\7zHandlerOut.obj \
$O\7zHeader.obj \
$O\7zIn.obj \
$O\7zOut.obj \
$O\7zProperties.obj \
$O\7zSpecStream.obj \
$O\7zUpdate.obj \
$O\7zRegister.obj \
COMMON_OBJS = \
$O\CRC.obj \
$O\IntToString.obj \
$O\NewHandler.obj \
$O\MyString.obj \
$O\StringConvert.obj \
$O\StringToInt.obj \
$O\MyVector.obj \
WIN_OBJS = \
$O\DLL.obj \
$O\FileDir.obj \
$O\FileFind.obj \
$O\FileIO.obj \
$O\PropVariant.obj \
$O\Synchronization.obj \
$O\System.obj \
7ZIP_COMMON_OBJS = \
$O\CreateCoder.obj \
$O\InOutTempBuffer.obj \
$O\FilterCoder.obj \
$O\LimitedStreams.obj \
$O\LockedStream.obj \
$O\MethodId.obj \
$O\MethodProps.obj \
$O\OutBuffer.obj \
$O\ProgressUtils.obj \
$O\StreamBinder.obj \
$O\StreamObjects.obj \
$O\StreamUtils.obj \
$O\VirtThread.obj \
AR_COMMON_OBJS = \
$O\CoderMixer2.obj \
$O\CoderMixer2MT.obj \
$O\CrossThreadProgress.obj \
$O\HandlerOut.obj \
$O\InStreamWithCRC.obj \
$O\ItemNameUtils.obj \
$O\MultiStream.obj \
$O\OutStreamWithCRC.obj \
$O\ParseProperties.obj \
C_OBJS = \
$O\Alloc.obj \
$O\Threads.obj \
!include "../../Crc2.mak"
OBJS = \
$O\StdAfx.obj \
$(AR_OBJS) \
$(7Z_OBJS) \
$(COMMON_OBJS) \
$(WIN_OBJS) \
$(7ZIP_COMMON_OBJS) \
$(AR_COMMON_OBJS) \
$O\CopyCoder.obj \
$(C_OBJS) \
$(CRC_OBJS) \
$O\resource.res
!include "../../../Build.mak"
$(AR_OBJS): ../$(*B).cpp
$(COMPL)
$(7Z_OBJS): $(*B).cpp
$(COMPL)
$(COMMON_OBJS): ../../../Common/$(*B).cpp
$(COMPL)
$(WIN_OBJS): ../../../Windows/$(*B).cpp
$(COMPL)
$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
$(COMPL)
$(AR_COMMON_OBJS): ../Common/$(*B).cpp
$(COMPL)
$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
$(COMPL)
$(C_OBJS): ../../../../C/$(*B).c
$(COMPL_O2)
!include "../../Crc.mak"

11
CPP/7zip/Archive/7z/resource.rc Executable file
View File

@@ -0,0 +1,11 @@
#include "../../MyVersionInfo.rc"
MY_VERSION_INFO_DLL("7z Plugin", "7z")
0 ICON "../Icons/7z.ico"
STRINGTABLE
BEGIN
100 "7z:0"
END

View File

@@ -1,311 +0,0 @@
// ArjHandler.cpp
#include "StdAfx.h"
#include "Common/Defs.h"
#include "Common/StringConvert.h"
#include "Common/ComTry.h"
#include "Windows/Time.h"
#include "Windows/PropVariant.h"
#include "ArjHandler.h"
#include "../../ICoder.h"
#include "../../Common/StreamObjects.h"
#include "../../Common/ProgressUtils.h"
#include "../../Common/LimitedStreams.h"
#include "../../Compress/Copy/CopyCoder.h"
#include "../../Compress/Arj/ArjDecoder1.h"
#include "../../Compress/Arj/ArjDecoder2.h"
#include "../Common/ItemNameUtils.h"
#include "../Common/OutStreamWithCRC.h"
using namespace NWindows;
using namespace NTime;
namespace NArchive {
namespace NArj{
const wchar_t *kHostOS[] =
{
L"MSDOS",
L"PRIMOS",
L"Unix",
L"AMIGA",
L"Mac",
L"OS/2",
L"APPLE GS",
L"Atari ST",
L"Next",
L"VAX VMS",
L"WIN95"
};
const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]);
const wchar_t *kUnknownOS = L"Unknown";
STATPROPSTG kProps[] =
{
{ NULL, kpidPath, VT_BSTR},
{ NULL, kpidIsFolder, VT_BOOL},
{ NULL, kpidSize, VT_UI8},
{ NULL, kpidPackedSize, VT_UI8},
{ NULL, kpidLastWriteTime, VT_FILETIME},
{ NULL, kpidAttributes, VT_UI4},
{ NULL, kpidEncrypted, VT_BOOL},
{ NULL, kpidCRC, VT_UI4},
{ NULL, kpidMethod, VT_UI1},
// { NULL, kpidUnpackVer, VT_UI1},
{ NULL, kpidHostOS, VT_BSTR}
};
IMP_IInArchive_Props
IMP_IInArchive_ArcProps_NO
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{
*numItems = _items.Size();
return S_OK;
}
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop;
const CItemEx &item = _items[index];
switch(propID)
{
case kpidPath: prop = NItemName::GetOSName(MultiByteToUnicodeString(item.Name, CP_OEMCP)); break;
case kpidIsFolder: prop = item.IsDirectory(); break;
case kpidSize: prop = item.Size; break;
case kpidPackedSize: prop = item.PackSize; break;
case kpidAttributes: prop = item.GetWinAttributes(); break;
case kpidEncrypted: prop = item.IsEncrypted(); break;
case kpidCRC: prop = item.FileCRC; break;
case kpidMethod: prop = item.Method; break;
case kpidHostOS: prop = (item.HostOS < kNumHostOSes) ? (kHostOS[item.HostOS]) : kUnknownOS; break;
case kpidLastWriteTime:
{
FILETIME localFileTime, utcFileTime;
if (DosTimeToFileTime(item.ModifiedTime, localFileTime))
{
if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime))
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
}
else
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
prop = utcFileTime;
break;
}
}
prop.Detach(value);
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::Open(IInStream *inStream,
const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback)
{
COM_TRY_BEGIN
try
{
_items.Clear();
CInArchive archive;
if(!archive.Open(inStream, maxCheckStartPosition))
return S_FALSE;
if (callback != NULL)
{
RINOK(callback->SetTotal(NULL, NULL));
UInt64 numFiles = _items.Size();
RINOK(callback->SetCompleted(&numFiles, NULL));
}
for (;;)
{
CItemEx item;
bool filled;
HRESULT result = archive.GetNextItem(filled, item);
if (result == S_FALSE)
return S_FALSE;
if (result != S_OK)
return S_FALSE;
if (!filled)
break;
_items.Add(item);
archive.IncreaseRealPosition(item.PackSize);
if (callback != NULL)
{
UInt64 numFiles = _items.Size();
RINOK(callback->SetCompleted(&numFiles, NULL));
}
}
_stream = inStream;
}
catch(...)
{
return S_FALSE;
}
COM_TRY_END
return S_OK;
}
STDMETHODIMP CHandler::Close()
{
_items.Clear();
_stream.Release();
return S_OK;
}
//////////////////////////////////////
// CHandler::DecompressItems
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));
if (allFilesMode)
numItems = _items.Size();
if(numItems == 0)
return S_OK;
UInt32 i;
for(i = 0; i < numItems; i++)
{
const CItemEx &item = _items[allFilesMode ? i : indices[i]];
totalUnPacked += item.Size;
totalPacked += item.PackSize;
}
extractCallback->SetTotal(totalUnPacked);
UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0;
UInt64 currentItemUnPacked, currentItemPacked;
CMyComPtr<ICompressCoder> arj1Decoder;
CMyComPtr<ICompressCoder> arj2Decoder;
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, false);
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream(streamSpec);
streamSpec->SetStream(_stream);
for(i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked,
currentTotalPacked += currentItemPacked)
{
lps->InSize = currentTotalPacked;
lps->OutSize = currentTotalUnPacked;
RINOK(lps->SetCur());
currentItemUnPacked = currentItemPacked = 0;
CMyComPtr<ISequentialOutStream> realOutStream;
Int32 askMode = testMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract;
Int32 index = allFilesMode ? i : indices[i];
const CItemEx &item = _items[index];
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
if(item.IsDirectory())
{
// if (!testMode)
{
RINOK(extractCallback->PrepareOperation(askMode));
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
}
continue;
}
if (!testMode && (!realOutStream))
continue;
RINOK(extractCallback->PrepareOperation(askMode));
currentItemUnPacked = item.Size;
currentItemPacked = item.PackSize;
{
COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
outStreamSpec->SetStream(realOutStream);
outStreamSpec->Init();
realOutStream.Release();
streamSpec->Init(item.PackSize);
UInt64 pos;
_stream->Seek(item.DataPosition, STREAM_SEEK_SET, &pos);
HRESULT result = S_OK;
Int32 opRes = NExtract::NOperationResult::kOK;
if (item.IsEncrypted())
{
opRes = NExtract::NOperationResult::kUnSupportedMethod;
}
else
{
switch(item.Method)
{
case NFileHeader::NCompressionMethod::kStored:
{
result = copyCoder->Code(inStream, outStream, NULL, NULL, progress);
if (result == S_OK && copyCoderSpec->TotalSize != item.PackSize)
result = S_FALSE;
break;
}
case NFileHeader::NCompressionMethod::kCompressed1a:
case NFileHeader::NCompressionMethod::kCompressed1b:
case NFileHeader::NCompressionMethod::kCompressed1c:
{
if (!arj1Decoder)
arj1Decoder = new NCompress::NArj::NDecoder1::CCoder;
result = arj1Decoder->Code(inStream, outStream, NULL, &currentItemUnPacked, progress);
break;
}
case NFileHeader::NCompressionMethod::kCompressed2:
{
if (!arj2Decoder)
arj2Decoder = new NCompress::NArj::NDecoder2::CCoder;
result = arj2Decoder->Code(inStream, outStream, NULL, &currentItemUnPacked, progress);
break;
}
default:
opRes = NExtract::NOperationResult::kUnSupportedMethod;
}
}
if (opRes == NExtract::NOperationResult::kOK)
{
if (result == S_FALSE)
opRes = NExtract::NOperationResult::kDataError;
else
{
RINOK(result);
opRes = (outStreamSpec->GetCRC() == item.FileCRC) ?
NExtract::NOperationResult::kOK:
NExtract::NOperationResult::kCRCError;
}
}
outStream.Release();
RINOK(extractCallback->SetOperationResult(opRes));
}
}
return S_OK;
COM_TRY_END
}
}}

View File

@@ -1,121 +0,0 @@
// Archive/Arj/Header.h
#ifndef __ARCHIVE_ARJ_HEADER_H
#define __ARCHIVE_ARJ_HEADER_H
#include "Common/Types.h"
namespace NArchive {
namespace NArj {
const int kMaxBlockSize = 2600;
namespace NSignature
{
const Byte kSig0 = 0x60;
const Byte kSig1 = 0xEA;
}
/*
struct CArchiveHeader
{
// UInt16 BasicHeaderSize;
Byte FirstHeaderSize;
Byte Version;
Byte ExtractVersion;
Byte HostOS;
Byte Flags;
Byte SecuryVersion;
Byte FileType;
Byte Reserved;
UInt32 CreatedTime;
UInt32 ModifiedTime;
UInt32 ArchiveSize;
UInt32 SecurityEnvelopeFilePosition;
UInt16 FilespecPositionInFilename;
UInt16 LengthOfSecurityEnvelopeSata;
Byte EncryptionVersion;
Byte LastChapter;
};
*/
namespace NFileHeader
{
namespace NCompressionMethod
{
enum EType
{
kStored = 0,
kCompressed1a = 1,
kCompressed1b = 2,
kCompressed1c = 3,
kCompressed2 = 4,
kNoDataNoCRC = 8,
kNoData = 9
};
}
namespace NFileType
{
enum EType
{
kBinary = 0,
k7BitText = 1,
kDirectory = 3,
kVolumeLablel = 4,
kChapterLabel = 5
};
}
namespace NFlags
{
const Byte kGarbled = 1;
const Byte kVolume = 4;
const Byte kExtFile = 8;
const Byte kPathSym = 0x10;
const Byte kBackup= 0x20;
}
/*
struct CHeader
{
Byte FirstHeaderSize;
Byte Version;
Byte ExtractVersion;
Byte HostOS;
Byte Flags;
Byte Method;
Byte FileType;
Byte Reserved;
UInt32 ModifiedTime;
UInt32 PackSize;
UInt32 Size;
UInt32 FileCRC;
UInt16 FilespecPositionInFilename;
UInt16 FileAccessMode;
Byte FirstChapter;
Byte LastChapter;
};
*/
namespace NHostOS
{
enum EEnum
{
kMSDOS = 0, // filesystem used by MS-DOS, OS/2, Win32
// pkarj 2.50 (FAT / VFAT / FAT32 file systems)
kPRIMOS = 1,
kUnix = 2, // VAX/VMS
kAMIGA = 3,
kMac = 4,
kOS_2 = 5, // what if it's a minix filesystem? [cjh]
kAPPLE_GS = 6, // filesystem used by OS/2 (and NT 3.x)
kAtari_ST = 7,
kNext = 8,
kVAX_VMS = 9,
kWIN95 = 10
};
}
}
}}
#endif

View File

@@ -1,287 +0,0 @@
// Archive/arj/InEngine.cpp
#include "StdAfx.h"
#include "Common/StringConvert.h"
#include "Common/Buffer.h"
#include "../../Common/StreamUtils.h"
#include "ArjIn.h"
extern "C"
{
#include "../../../../C/7zCrc.h"
}
namespace NArchive {
namespace NArj {
HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize)
{
size_t realProcessedSize = size;
HRESULT result = ReadStream(_stream, data, &realProcessedSize);
if (processedSize != NULL)
*processedSize = (UInt32)realProcessedSize;
IncreasePositionValue(realProcessedSize);
return result;
}
static inline UInt16 GetUInt16FromMemLE(const Byte *p)
{
return (UInt16)(p[0] | (((UInt16)p[1]) << 8));
}
static inline UInt32 GetUInt32FromMemLE(const Byte *p)
{
return p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24);
}
inline bool TestMarkerCandidate(const void *testBytes, UInt32 maxSize)
{
if (maxSize < 2 + 2 + 4)
return false;
const Byte *block = ((const Byte *)(testBytes));
if (block[0] != NSignature::kSig0 || block[1] != NSignature::kSig1)
return false;
UInt32 blockSize = GetUInt16FromMemLE(block + 2);
if (maxSize < 2 + 2 + blockSize + 4)
return false;
block += 4;
if (blockSize == 0 || blockSize > 2600)
return false;
UInt32 crcFromFile = GetUInt32FromMemLE(block + blockSize);
return (crcFromFile == CrcCalc(block, blockSize));
}
bool CInArchive::FindAndReadMarker(const UInt64 *searchHeaderSizeLimit)
{
// _archiveInfo.StartPosition = 0;
_position = _streamStartPosition;
if(_stream->Seek(_streamStartPosition, STREAM_SEEK_SET, NULL) != S_OK)
return false;
const int kMarkerSizeMax = 2 + 2 + kMaxBlockSize + 4;
CByteBuffer byteBuffer;
static const UInt32 kSearchMarkerBufferSize = 0x10000;
byteBuffer.SetCapacity(kSearchMarkerBufferSize);
Byte *buffer = byteBuffer;
UInt32 processedSize;
ReadBytes(buffer, kMarkerSizeMax, &processedSize);
if (processedSize == 0)
return false;
if (TestMarkerCandidate(buffer, processedSize))
{
_position = _streamStartPosition;
if(_stream->Seek(_position, STREAM_SEEK_SET, NULL) != S_OK)
return false;
return true;
}
UInt32 numBytesPrev = processedSize - 1;
memmove(buffer, buffer + 1, numBytesPrev);
UInt64 curTestPos = _streamStartPosition + 1;
for (;;)
{
if (searchHeaderSizeLimit != NULL)
if (curTestPos - _streamStartPosition > *searchHeaderSizeLimit)
return false;
UInt32 numReadBytes = kSearchMarkerBufferSize - numBytesPrev;
ReadBytes(buffer + numBytesPrev, numReadBytes, &processedSize);
UInt32 numBytesInBuffer = numBytesPrev + processedSize;
if (numBytesInBuffer < 1)
return false;
UInt32 numTests = numBytesInBuffer;
for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++)
{
if (TestMarkerCandidate(buffer + pos, numBytesInBuffer - pos))
{
// _archiveInfo.StartPosition = curTestPos;
_position = curTestPos;
if(_stream->Seek(_position, STREAM_SEEK_SET, NULL) != S_OK)
return false;
return true;
}
}
numBytesPrev = numBytesInBuffer - numTests;
memmove(buffer, buffer + numTests, numBytesPrev);
}
}
void CInArchive::IncreasePositionValue(UInt64 addValue)
{
_position += addValue;
}
void CInArchive::IncreaseRealPosition(UInt64 addValue)
{
if(_stream->Seek(addValue, STREAM_SEEK_CUR, &_position) != S_OK)
throw CInArchiveException(CInArchiveException::kSeekStreamError);
}
bool CInArchive::ReadBytesAndTestSize(void *data, UInt32 size)
{
UInt32 realProcessedSize;
if(ReadBytes(data, size, &realProcessedSize) != S_OK)
throw CInArchiveException(CInArchiveException::kReadStreamError);
return (realProcessedSize == size);
}
void CInArchive::SafeReadBytes(void *data, UInt32 size)
{
if(!ReadBytesAndTestSize(data, size))
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
}
Byte CInArchive::SafeReadByte()
{
Byte b;
SafeReadBytes(&b, 1);
return b;
}
UInt16 CInArchive::SafeReadUInt16()
{
UInt16 value = 0;
for (int i = 0; i < 2; i++)
{
Byte b = SafeReadByte();
value |= (UInt16(b) << (8 * i));
}
return value;
}
UInt32 CInArchive::SafeReadUInt32()
{
UInt32 value = 0;
for (int i = 0; i < 4; i++)
{
Byte b = SafeReadByte();
value |= (UInt32(b) << (8 * i));
}
return value;
}
bool CInArchive::ReadBlock()
{
_blockPos = 0;
_blockSize = SafeReadUInt16();
if (_blockSize == 0 || _blockSize > kMaxBlockSize)
return false;
SafeReadBytes(_block, _blockSize);
UInt32 crcFromFile = SafeReadUInt32();
if (crcFromFile != CrcCalc(_block, _blockSize))
throw CInArchiveException(CInArchiveException::kCRCError);
return true;
}
bool CInArchive::ReadBlock2()
{
Byte id[2];
ReadBytesAndTestSize(id, 2);
if (id[0] != NSignature::kSig0 || id[1] != NSignature::kSig1)
throw CInArchiveException(CInArchiveException::kIncorrectArchive);
return ReadBlock();
}
bool CInArchive::Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit)
{
_stream = inStream;
if(_stream->Seek(0, STREAM_SEEK_CUR, &_streamStartPosition) != S_OK)
return false;
_position = _streamStartPosition;
if (!FindAndReadMarker(searchHeaderSizeLimit))
return false;
if (!ReadBlock2())
return false;
for (;;)
if (!ReadBlock())
break;
return true;
}
void CInArchive::Close()
{
_stream.Release();
}
void CInArchive::ThrowIncorrectArchiveException()
{
throw CInArchiveException(CInArchiveException::kIncorrectArchive);
}
Byte CInArchive::ReadByte()
{
if (_blockPos >= _blockSize)
ThrowIncorrectArchiveException();
return _block[_blockPos++];
}
UInt16 CInArchive::ReadUInt16()
{
UInt16 value = 0;
for (int i = 0; i < 2; i++)
{
Byte b = ReadByte();
value |= (UInt16(b) << (8 * i));
}
return value;
}
UInt32 CInArchive::ReadUInt32()
{
UInt32 value = 0;
for (int i = 0; i < 4; i++)
{
Byte b = ReadByte();
value |= (UInt32(b) << (8 * i));
}
return value;
}
HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
{
filled = false;
if (!ReadBlock2())
return S_OK;
Byte firstHeaderSize = ReadByte();
item.Version = ReadByte();
item.ExtractVersion = ReadByte();
item.HostOS = ReadByte();
item.Flags = ReadByte();
item.Method = ReadByte();
item.FileType = ReadByte();
ReadByte(); // Reserved
item.ModifiedTime = ReadUInt32();
item.PackSize = ReadUInt32();
item.Size = ReadUInt32();
item.FileCRC = ReadUInt32();
ReadUInt16(); // FilespecPositionInFilename
item.FileAccessMode = ReadUInt16();
ReadByte(); // FirstChapter
ReadByte(); // LastChapter
/*
UInt32 extraData;
if ((header.Flags & NFileHeader::NFlags::kExtFile) != 0)
extraData = GetUInt32FromMemLE(_block + pos);
*/
_blockPos = firstHeaderSize;
for (; _blockPos < _blockSize;)
item.Name += (char)ReadByte();
for (;;)
if (!ReadBlock())
break;
item.DataPosition = _position;
filled = true;
return S_OK;
}
}}

View File

@@ -1,75 +0,0 @@
// Archive/ArjIn.h
#ifndef __ARCHIVE_ARJIN_H
#define __ARCHIVE_ARJIN_H
#include "Common/MyCom.h"
#include "../../IStream.h"
#include "ArjItem.h"
namespace NArchive {
namespace NArj {
class CInArchiveException
{
public:
enum CCauseType
{
kUnexpectedEndOfArchive = 0,
kCRCError,
kIncorrectArchive,
kReadStreamError,
kSeekStreamError
}
Cause;
CInArchiveException(CCauseType cause): Cause(cause) {};
};
class CProgressVirt
{
public:
STDMETHOD(SetCompleted)(const UInt64 *numFiles) PURE;
};
class CInArchive
{
CMyComPtr<IInStream> _stream;
UInt64 _streamStartPosition;
UInt64 _position;
UInt16 _blockSize;
Byte _block[kMaxBlockSize];
UInt32 _blockPos;
bool FindAndReadMarker(const UInt64 *searchHeaderSizeLimit);
bool ReadBlock();
bool ReadBlock2();
Byte ReadByte();
UInt16 ReadUInt16();
UInt32 ReadUInt32();
HRESULT ReadBytes(void *data, UInt32 size, UInt32 *processedSize);
bool ReadBytesAndTestSize(void *data, UInt32 size);
void SafeReadBytes(void *data, UInt32 size);
Byte SafeReadByte();
UInt16 SafeReadUInt16();
UInt32 SafeReadUInt32();
void IncreasePositionValue(UInt64 addValue);
void ThrowIncorrectArchiveException();
public:
HRESULT GetNextItem(bool &filled, CItemEx &item);
bool Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit);
void Close();
void IncreaseRealPosition(UInt64 addValue);
};
}}
#endif

View File

@@ -1,75 +0,0 @@
// Archive/ArjItem.h
#ifndef __ARCHIVE_ARJ_ITEM_H
#define __ARCHIVE_ARJ_ITEM_H
#include "Common/Types.h"
#include "Common/MyString.h"
#include "ArjHeader.h"
namespace NArchive {
namespace NArj {
struct CVersion
{
Byte Version;
Byte HostOS;
};
inline bool operator==(const CVersion &v1, const CVersion &v2)
{ return (v1.Version == v2.Version) && (v1.HostOS == v2.HostOS); }
inline bool operator!=(const CVersion &v1, const CVersion &v2)
{ return !(v1 == v2); }
class CItem
{
public:
Byte Version;
Byte ExtractVersion;
Byte HostOS;
Byte Flags;
Byte Method;
Byte FileType;
UInt32 ModifiedTime;
UInt32 PackSize;
UInt32 Size;
UInt32 FileCRC;
// UInt16 FilespecPositionInFilename;
UInt16 FileAccessMode;
// Byte FirstChapter;
// Byte LastChapter;
AString Name;
bool IsEncrypted() const { return (Flags & NFileHeader::NFlags::kGarbled) != 0; }
bool IsDirectory() const { return (FileType == NFileHeader::NFileType::kDirectory); }
UInt32 GetWinAttributes() const
{
UInt32 winAtrributes;
switch(HostOS)
{
case NFileHeader::NHostOS::kMSDOS:
case NFileHeader::NHostOS::kWIN95:
winAtrributes = FileAccessMode;
break;
default:
winAtrributes = 0;
}
if (IsDirectory())
winAtrributes |= FILE_ATTRIBUTE_DIRECTORY;
return winAtrributes;
}
};
class CItemEx: public CItem
{
public:
UInt64 DataPosition;
};
}}
#endif

View File

@@ -1,13 +0,0 @@
// ArjRegister.cpp
#include "StdAfx.h"
#include "../../Common/RegisterArc.h"
#include "ArjHandler.h"
static IInArchive *CreateArc() { return new NArchive::NArj::CHandler; }
static CArcInfo g_ArcInfo =
{ L"Arj", L"arj", 0, 4, { 0x60, 0xEA }, 2, false, CreateArc, 0 };
REGISTER_ARC(Arj)

View File

@@ -1,3 +0,0 @@
// StdAfx.cpp
#include "StdAfx.h"

792
CPP/7zip/Archive/ArjHandler.cpp Executable file
View File

@@ -0,0 +1,792 @@
// ArjHandler.cpp
#include "StdAfx.h"
#include "Common/ComTry.h"
#include "Common/StringConvert.h"
#include "Windows/PropVariant.h"
#include "Windows/Time.h"
#include "../../../C/CpuArch.h"
#include "../Common/LimitedStreams.h"
#include "../Common/ProgressUtils.h"
#include "../Common/RegisterArc.h"
#include "../Common/StreamObjects.h"
#include "../Common/StreamUtils.h"
#include "../Compress/Arj/ArjDecoder1.h"
#include "../Compress/Arj/ArjDecoder2.h"
#include "../Compress/Copy/CopyCoder.h"
#include "IArchive.h"
#include "Common/ItemNameUtils.h"
#include "Common/OutStreamWithCRC.h"
using namespace NWindows;
#define Get16(p) GetUi16(p)
#define Get32(p) GetUi32(p)
namespace NArchive {
namespace NArj {
const int kBlockSizeMin = 30;
const int kBlockSizeMax = 2600;
namespace NSignature
{
const Byte kSig0 = 0x60;
const Byte kSig1 = 0xEA;
}
namespace NFileHeader
{
namespace NCompressionMethod
{
enum
{
kStored = 0,
kCompressed1a = 1,
kCompressed1b = 2,
kCompressed1c = 3,
kCompressed2 = 4,
kNoDataNoCRC = 8,
kNoData = 9
};
}
namespace NFileType
{
enum
{
kBinary = 0,
k7BitText = 1,
kArchiveHeader = 2,
kDirectory = 3,
kVolumeLablel = 4,
kChapterLabel = 5
};
}
namespace NFlags
{
const Byte kGarbled = 1;
const Byte kVolume = 4;
const Byte kExtFile = 8;
const Byte kPathSym = 0x10;
const Byte kBackup = 0x20;
}
namespace NHostOS
{
enum EEnum
{
kMSDOS = 0, // filesystem used by MS-DOS, OS/2, Win32
// pkarj 2.50 (FAT / VFAT / FAT32 file systems)
kPRIMOS,
kUnix,
kAMIGA,
kMac,
kOS_2,
kAPPLE_GS,
kAtari_ST,
kNext,
kVAX_VMS,
kWIN95
};
}
}
struct CArchiveHeader
{
// Byte ArchiverVersion;
// Byte ExtractVersion;
Byte HostOS;
// Byte Flags;
// Byte SecuryVersion;
// Byte FileType;
// Byte Reserved;
UInt32 CTime;
UInt32 MTime;
UInt32 ArchiveSize;
// UInt32 SecurityEnvelopeFilePosition;
// UInt16 FilespecPositionInFilename;
// UInt16 LengthOfSecurityEnvelopeSata;
// Byte EncryptionVersion;
// Byte LastChapter;
AString Name;
AString Comment;
HRESULT Parse(const Byte *p, unsigned size);
};
static HRESULT ReadString(const Byte *p, unsigned &size, AString &res)
{
AString s;
for (unsigned i = 0; i < size;)
{
char c = (char)p[i++];
if (c == 0)
{
size = i;
res = s;
return S_OK;
}
s += c;
}
return S_FALSE;
}
HRESULT CArchiveHeader::Parse(const Byte *p, unsigned size)
{
if (size < kBlockSizeMin)
return S_FALSE;
Byte firstHeaderSize = p[0];
if (firstHeaderSize > size)
return S_FALSE;
// ArchiverVersion = p[1];
// ExtractVersion = p[2];
HostOS = p[3];
// Flags = p[4];
// SecuryVersion = p[5];
if (p[6] != NFileHeader::NFileType::kArchiveHeader)
return S_FALSE;
// Reserved = p[7];
CTime = Get32(p + 8);
MTime = Get32(p + 12);
ArchiveSize = Get32(p + 16);
// SecurityEnvelopeFilePosition = Get32(p + 20);
// UInt16 filespecPositionInFilename = Get16(p + 24);
// LengthOfSecurityEnvelopeSata = Get16(p + 26);
// EncryptionVersion = p[28];
// LastChapter = p[29];
unsigned pos = firstHeaderSize;
unsigned size1 = size - pos;
RINOK(ReadString(p + pos, size1, Name));
pos += size1;
size1 = size - pos;
RINOK(ReadString(p + pos, size1, Comment));
pos += size1;
return S_OK;
}
struct CItem
{
AString Name;
AString Comment;
UInt32 MTime;
UInt32 PackSize;
UInt32 Size;
UInt32 FileCRC;
Byte Version;
Byte ExtractVersion;
Byte HostOS;
Byte Flags;
Byte Method;
Byte FileType;
// UInt16 FilespecPositionInFilename;
UInt16 FileAccessMode;
// Byte FirstChapter;
// Byte LastChapter;
UInt64 DataPosition;
bool IsEncrypted() const { return (Flags & NFileHeader::NFlags::kGarbled) != 0; }
bool IsDir() const { return (FileType == NFileHeader::NFileType::kDirectory); }
UInt32 GetWinAttributes() const
{
UInt32 winAtrributes;
switch(HostOS)
{
case NFileHeader::NHostOS::kMSDOS:
case NFileHeader::NHostOS::kWIN95:
winAtrributes = FileAccessMode;
break;
default:
winAtrributes = 0;
}
if (IsDir())
winAtrributes |= FILE_ATTRIBUTE_DIRECTORY;
return winAtrributes;
}
HRESULT Parse(const Byte *p, unsigned size);
};
HRESULT CItem::Parse(const Byte *p, unsigned size)
{
if (size < kBlockSizeMin)
return S_FALSE;
Byte firstHeaderSize = p[0];
Version = p[1];
ExtractVersion = p[2];
HostOS = p[3];
Flags = p[4];
Method = p[5];
FileType = p[6];
// Reserved = p[7];
MTime = Get32(p + 8);
PackSize = Get32(p + 12);
Size = Get32(p + 16);
FileCRC = Get32(p + 20);
// FilespecPositionInFilename = Get16(p + 24);
FileAccessMode = Get16(p + 26);
// FirstChapter = p[28];
// FirstChapter = p[29];
unsigned pos = firstHeaderSize;
unsigned size1 = size - pos;
RINOK(ReadString(p + pos, size1, Name));
pos += size1;
size1 = size - pos;
RINOK(ReadString(p + pos, size1, Comment));
pos += size1;
return S_OK;
}
struct CInArchiveException
{
enum CCauseType
{
kUnexpectedEndOfArchive = 0,
kCRCError,
kIncorrectArchive,
}
Cause;
CInArchiveException(CCauseType cause): Cause(cause) {};
};
class CInArchive
{
UInt32 _blockSize;
Byte _block[kBlockSizeMax + 4];
HRESULT ReadBlock(bool &filled);
HRESULT ReadSignatureAndBlock(bool &filled);
HRESULT SkeepExtendedHeaders();
HRESULT SafeReadBytes(void *data, UInt32 size);
public:
CArchiveHeader Header;
IInStream *Stream;
IArchiveOpenCallback *Callback;
UInt64 NumFiles;
UInt64 NumBytes;
HRESULT Open(const UInt64 *searchHeaderSizeLimit);
HRESULT GetNextItem(bool &filled, CItem &item);
};
static inline bool TestMarkerCandidate(const Byte *p, unsigned maxSize)
{
if (p[0] != NSignature::kSig0 || p[1] != NSignature::kSig1)
return false;
UInt32 blockSize = Get16(p + 2);
p += 4;
if (p[6] != NFileHeader::NFileType::kArchiveHeader ||
p[0] > blockSize ||
maxSize < 2 + 2 + blockSize + 4 ||
blockSize < kBlockSizeMin || blockSize > kBlockSizeMax ||
p[28] > 8) // EncryptionVersion
return false;
// return (Get32(p + blockSize) == CrcCalc(p, blockSize));
return true;
}
static HRESULT FindAndReadMarker(ISequentialInStream *stream, const UInt64 *searchHeaderSizeLimit, UInt64 &position)
{
position = 0;
const int kMarkerSizeMin = 2 + 2 + kBlockSizeMin + 4;
const int kMarkerSizeMax = 2 + 2 + kBlockSizeMax + 4;
CByteBuffer byteBuffer;
const UInt32 kBufSize = 1 << 16;
byteBuffer.SetCapacity(kBufSize);
Byte *buf = byteBuffer;
size_t processedSize = kMarkerSizeMax;
RINOK(ReadStream(stream, buf, &processedSize));
if (processedSize < kMarkerSizeMin)
return S_FALSE;
if (TestMarkerCandidate(buf, (unsigned)processedSize))
return S_OK;
UInt32 numBytesPrev = (UInt32)processedSize - 1;
memmove(buf, buf + 1, numBytesPrev);
UInt64 curTestPos = 1;
for (;;)
{
if (searchHeaderSizeLimit != NULL)
if (curTestPos > *searchHeaderSizeLimit)
return S_FALSE;
processedSize = kBufSize - numBytesPrev;
RINOK(ReadStream(stream, buf + numBytesPrev, &processedSize));
UInt32 numBytesInBuffer = numBytesPrev + (UInt32)processedSize;
if (numBytesInBuffer < kMarkerSizeMin)
return S_FALSE;
UInt32 numTests = numBytesInBuffer - kMarkerSizeMin + 1;
UInt32 pos;
for (pos = 0; pos < numTests; pos++)
{
for (; buf[pos] != NSignature::kSig0 && pos < numTests; pos++);
if (pos == numTests)
break;
if (TestMarkerCandidate(buf + pos, numBytesInBuffer - pos))
{
position = curTestPos + pos;
return S_OK;
}
}
curTestPos += pos;
numBytesPrev = numBytesInBuffer - numTests;
memmove(buf, buf + numTests, numBytesPrev);
}
}
HRESULT CInArchive::SafeReadBytes(void *data, UInt32 size)
{
size_t processed = size;
RINOK(ReadStream(Stream, data, &processed));
if (processed != size)
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
return S_OK;
}
HRESULT CInArchive::ReadBlock(bool &filled)
{
filled = false;
Byte buf[2];
RINOK(SafeReadBytes(buf, 2));
_blockSize = Get16(buf);
if (_blockSize == 0)
return S_OK;
if (_blockSize > kBlockSizeMax)
throw CInArchiveException(CInArchiveException::kIncorrectArchive);
RINOK(SafeReadBytes(_block, _blockSize + 4));
NumBytes += _blockSize + 6;
if (Get32(_block + _blockSize) != CrcCalc(_block, _blockSize))
throw CInArchiveException(CInArchiveException::kCRCError);
filled = true;
return S_OK;
}
HRESULT CInArchive::ReadSignatureAndBlock(bool &filled)
{
Byte id[2];
RINOK(SafeReadBytes(id, 2));
if (id[0] != NSignature::kSig0 || id[1] != NSignature::kSig1)
throw CInArchiveException(CInArchiveException::kIncorrectArchive);
return ReadBlock(filled);
}
HRESULT CInArchive::SkeepExtendedHeaders()
{
for (UInt32 i = 0;; i++)
{
bool filled;
RINOK(ReadBlock(filled));
if (!filled)
return S_OK;
if (Callback && (i & 0xFF) == 0)
RINOK(Callback->SetCompleted(&NumFiles, &NumBytes));
}
}
HRESULT CInArchive::Open(const UInt64 *searchHeaderSizeLimit)
{
UInt64 position = 0;
RINOK(FindAndReadMarker(Stream, searchHeaderSizeLimit, position));
RINOK(Stream->Seek(position, STREAM_SEEK_SET, NULL));
bool filled;
RINOK(ReadSignatureAndBlock(filled));
if (!filled)
return S_FALSE;
RINOK(Header.Parse(_block, _blockSize));
return SkeepExtendedHeaders();
}
HRESULT CInArchive::GetNextItem(bool &filled, CItem &item)
{
RINOK(ReadSignatureAndBlock(filled));
if (!filled)
return S_OK;
filled = false;
RINOK(item.Parse(_block, _blockSize));
/*
UInt32 extraData;
if ((header.Flags & NFileHeader::NFlags::kExtFile) != 0)
extraData = GetUInt32FromMemLE(_block + pos);
*/
RINOK(SkeepExtendedHeaders());
filled = true;
return S_OK;
}
class CHandler:
public IInArchive,
public CMyUnknownImp
{
public:
MY_UNKNOWN_IMP1(IInArchive)
INTERFACE_IInArchive(;)
HRESULT Open2(IInStream *inStream, const UInt64 *maxCheckStartPosition,
IArchiveOpenCallback *callback);
private:
CInArchive _archive;
CObjectVector<CItem> _items;
CMyComPtr<IInStream> _stream;
};
const wchar_t *kHostOS[] =
{
L"MSDOS",
L"PRIMOS",
L"UNIX",
L"AMIGA",
L"MAC",
L"OS/2",
L"APPLE GS",
L"ATARI ST",
L"NEXT",
L"VAX VMS",
L"WIN95"
};
const wchar_t *kUnknownOS = L"Unknown";
const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]);
STATPROPSTG kArcProps[] =
{
{ NULL, kpidName, VT_BSTR},
{ NULL, kpidCTime, VT_BSTR},
{ NULL, kpidMTime, VT_BSTR},
{ NULL, kpidHostOS, VT_BSTR},
{ NULL, kpidComment, VT_BSTR}
};
STATPROPSTG kProps[] =
{
{ NULL, kpidPath, VT_BSTR},
{ NULL, kpidIsDir, VT_BOOL},
{ NULL, kpidSize, VT_UI8},
{ NULL, kpidPackSize, VT_UI8},
{ NULL, kpidMTime, VT_FILETIME},
{ NULL, kpidAttrib, VT_UI4},
{ NULL, kpidEncrypted, VT_BOOL},
{ NULL, kpidCRC, VT_UI4},
{ NULL, kpidMethod, VT_UI1},
{ NULL, kpidHostOS, VT_BSTR},
{ NULL, kpidComment, VT_BSTR}
};
IMP_IInArchive_Props
IMP_IInArchive_ArcProps
static void SetTime(UInt32 dosTime, NWindows::NCOM::CPropVariant &prop)
{
if (dosTime == 0)
return;
FILETIME localFileTime, utc;
if (NTime::DosTimeToFileTime(dosTime, localFileTime))
{
if (!LocalFileTimeToFileTime(&localFileTime, &utc))
utc.dwHighDateTime = utc.dwLowDateTime = 0;
}
else
utc.dwHighDateTime = utc.dwLowDateTime = 0;
prop = utc;
}
static void SetHostOS(Byte hostOS, NWindows::NCOM::CPropVariant &prop)
{
prop = hostOS < kNumHostOSes ? kHostOS[hostOS] : kUnknownOS;
}
static void SetUnicodeString(const AString &s, NWindows::NCOM::CPropVariant &prop)
{
if (!s.IsEmpty())
prop = MultiByteToUnicodeString(s, CP_OEMCP);
}
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop;
switch(propID)
{
case kpidName: SetUnicodeString(_archive.Header.Name, prop); break;
case kpidCTime: SetTime(_archive.Header.CTime, prop); break;
case kpidMTime: SetTime(_archive.Header.MTime, prop); break;
case kpidHostOS: SetHostOS(_archive.Header.HostOS, prop); break;
case kpidComment: SetUnicodeString(_archive.Header.Comment, prop); break;
}
prop.Detach(value);
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{
*numItems = _items.Size();
return S_OK;
}
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop;
const CItem &item = _items[index];
switch(propID)
{
case kpidPath: prop = NItemName::GetOSName(MultiByteToUnicodeString(item.Name, CP_OEMCP)); break;
case kpidIsDir: prop = item.IsDir(); break;
case kpidSize: prop = item.Size; break;
case kpidPackSize: prop = item.PackSize; break;
case kpidAttrib: prop = item.GetWinAttributes(); break;
case kpidEncrypted: prop = item.IsEncrypted(); break;
case kpidCRC: prop = item.FileCRC; break;
case kpidMethod: prop = item.Method; break;
case kpidHostOS: SetHostOS(item.HostOS, prop); break;
case kpidMTime: SetTime(item.MTime, prop); break;
case kpidComment: SetUnicodeString(item.Comment, prop); break;
}
prop.Detach(value);
return S_OK;
COM_TRY_END
}
HRESULT CHandler::Open2(IInStream *inStream, const UInt64 *maxCheckStartPosition,
IArchiveOpenCallback *callback)
{
Close();
UInt64 endPos = 0;
if (callback != NULL)
{
RINOK(inStream->Seek(0, STREAM_SEEK_END, &endPos));
RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
}
_archive.Stream = inStream;
_archive.Callback = callback;
_archive.NumFiles = _archive.NumBytes = 0;
RINOK(_archive.Open(maxCheckStartPosition));
if (callback != NULL)
RINOK(callback->SetTotal(NULL, &endPos));
for (;;)
{
CItem item;
bool filled;
RINOK(_archive.GetNextItem(filled, item));
RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &item.DataPosition));
if (!filled)
break;
_items.Add(item);
if (inStream->Seek(item.PackSize, STREAM_SEEK_CUR, NULL) != S_OK)
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
_archive.NumFiles = _items.Size();
_archive.NumBytes = item.DataPosition;
if (callback != NULL && _items.Size() % 100 == 0)
{
RINOK(callback->SetCompleted(&_archive.NumFiles, &_archive.NumBytes));
}
}
return S_OK;
}
STDMETHODIMP CHandler::Open(IInStream *inStream,
const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback)
{
COM_TRY_BEGIN
HRESULT res;
try
{
res = Open2(inStream, maxCheckStartPosition, callback);
if (res == S_OK)
{
_stream = inStream;
return S_OK;
}
}
catch(const CInArchiveException &) { res = S_FALSE; }
Close();
return res;
COM_TRY_END
}
STDMETHODIMP CHandler::Close()
{
_items.Clear();
_stream.Release();
return S_OK;
}
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));
if (allFilesMode)
numItems = _items.Size();
if (numItems == 0)
return S_OK;
UInt32 i;
for (i = 0; i < numItems; i++)
{
const CItem &item = _items[allFilesMode ? i : indices[i]];
totalUnpacked += item.Size;
totalPacked += item.PackSize;
}
extractCallback->SetTotal(totalUnpacked);
totalUnpacked = totalPacked = 0;
UInt64 curUnpacked, curPacked;
CMyComPtr<ICompressCoder> arj1Decoder;
CMyComPtr<ICompressCoder> arj2Decoder;
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, false);
CLimitedSequentialInStream *inStreamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream(inStreamSpec);
inStreamSpec->SetStream(_stream);
for (i = 0; i < numItems; i++, totalUnpacked += curUnpacked, totalPacked += curPacked)
{
lps->InSize = totalPacked;
lps->OutSize = totalUnpacked;
RINOK(lps->SetCur());
curUnpacked = curPacked = 0;
CMyComPtr<ISequentialOutStream> realOutStream;
Int32 askMode = testMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract;
Int32 index = allFilesMode ? i : indices[i];
const CItem &item = _items[index];
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
if (item.IsDir())
{
// if (!testMode)
{
RINOK(extractCallback->PrepareOperation(askMode));
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
}
continue;
}
if (!testMode && (!realOutStream))
continue;
RINOK(extractCallback->PrepareOperation(askMode));
curUnpacked = item.Size;
curPacked = item.PackSize;
{
COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
outStreamSpec->SetStream(realOutStream);
realOutStream.Release();
outStreamSpec->Init();
inStreamSpec->Init(item.PackSize);
UInt64 pos;
_stream->Seek(item.DataPosition, STREAM_SEEK_SET, &pos);
HRESULT result = S_OK;
Int32 opRes = NExtract::NOperationResult::kOK;
if (item.IsEncrypted())
opRes = NExtract::NOperationResult::kUnSupportedMethod;
else
{
switch(item.Method)
{
case NFileHeader::NCompressionMethod::kStored:
{
result = copyCoder->Code(inStream, outStream, NULL, NULL, progress);
if (result == S_OK && copyCoderSpec->TotalSize != item.PackSize)
result = S_FALSE;
break;
}
case NFileHeader::NCompressionMethod::kCompressed1a:
case NFileHeader::NCompressionMethod::kCompressed1b:
case NFileHeader::NCompressionMethod::kCompressed1c:
{
if (!arj1Decoder)
arj1Decoder = new NCompress::NArj::NDecoder1::CCoder;
result = arj1Decoder->Code(inStream, outStream, NULL, &curUnpacked, progress);
break;
}
case NFileHeader::NCompressionMethod::kCompressed2:
{
if (!arj2Decoder)
arj2Decoder = new NCompress::NArj::NDecoder2::CCoder;
result = arj2Decoder->Code(inStream, outStream, NULL, &curUnpacked, progress);
break;
}
default:
opRes = NExtract::NOperationResult::kUnSupportedMethod;
}
}
if (opRes == NExtract::NOperationResult::kOK)
{
if (result == S_FALSE)
opRes = NExtract::NOperationResult::kDataError;
else
{
RINOK(result);
opRes = (outStreamSpec->GetCRC() == item.FileCRC) ?
NExtract::NOperationResult::kOK:
NExtract::NOperationResult::kCRCError;
}
}
outStream.Release();
RINOK(extractCallback->SetOperationResult(opRes));
}
}
return S_OK;
COM_TRY_END
}
static IInArchive *CreateArc() { return new CHandler; }
static CArcInfo g_ArcInfo =
{ L"Arj", L"arj", 0, 4, { 0x60, 0xEA }, 2, false, CreateArc, 0 };
REGISTER_ARC(Arj)
}}

View File

@@ -23,7 +23,7 @@ static const CMethodId kMethodId_BZip2 = 0x040202;
STATPROPSTG kProps[] = STATPROPSTG kProps[] =
{ {
{ NULL, kpidPackedSize, VT_UI8} { NULL, kpidPackSize, VT_UI8}
}; };
IMP_IInArchive_Props IMP_IInArchive_Props
@@ -40,7 +40,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIA
NWindows::NCOM::CPropVariant prop; NWindows::NCOM::CPropVariant prop;
switch(propID) switch(propID)
{ {
case kpidPackedSize: prop = _item.PackSize; break; case kpidPackSize: prop = _item.PackSize; break;
} }
prop.Detach(value); prop.Detach(value);
return S_OK; return S_OK;

View File

@@ -55,7 +55,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
{ {
{ {
NCOM::CPropVariant prop; NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(0, kpidIsFolder, &prop)); RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop));
if (prop.vt == VT_BOOL) if (prop.vt == VT_BOOL)
{ {
if (prop.boolVal != VARIANT_FALSE) if (prop.boolVal != VARIANT_FALSE)

View File

@@ -1,3 +0,0 @@
// StdAfx.cpp
#include "StdAfx.h"

View File

@@ -40,10 +40,9 @@ enum
STATPROPSTG kProps[] = STATPROPSTG kProps[] =
{ {
{ NULL, kpidPath, VT_BSTR}, { NULL, kpidPath, VT_BSTR},
// { NULL, kpidIsFolder, VT_BOOL},
{ NULL, kpidSize, VT_UI8}, { NULL, kpidSize, VT_UI8},
{ NULL, kpidLastWriteTime, VT_FILETIME}, { NULL, kpidMTime, VT_FILETIME},
{ NULL, kpidAttributes, VT_UI4}, { NULL, kpidAttrib, VT_UI4},
{ NULL, kpidMethod, VT_BSTR}, { NULL, kpidMethod, VT_BSTR},
{ NULL, kpidBlock, VT_I4} { NULL, kpidBlock, VT_I4}
#ifdef _CAB_DETAILS #ifdef _CAB_DETAILS
@@ -145,13 +144,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
prop = (const wchar_t *)NItemName::WinNameToOSName(unicodeName); prop = (const wchar_t *)NItemName::WinNameToOSName(unicodeName);
break; break;
} }
case kpidIsFolder: case kpidIsDir: prop = item.IsDir(); break;
prop = item.IsDirectory(); case kpidSize: prop = item.Size; break;
break; case kpidAttrib: prop = item.GetWinAttributes(); break;
case kpidSize:
prop = item.Size; case kpidMTime:
break;
case kpidLastWriteTime:
{ {
FILETIME localFileTime, utcFileTime; FILETIME localFileTime, utcFileTime;
if (NTime::DosTimeToFileTime(item.Time, localFileTime)) if (NTime::DosTimeToFileTime(item.Time, localFileTime))
@@ -164,9 +161,6 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
prop = utcFileTime; prop = utcFileTime;
break; break;
} }
case kpidAttributes:
prop = item.GetWinAttributes();
break;
case kpidMethod: case kpidMethod:
{ {
@@ -185,21 +179,13 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
prop = method; prop = method;
break; break;
} }
case kpidBlock: case kpidBlock: prop = (Int32)m_Database.GetFolderIndex(&mvItem); break;
prop = (Int32)m_Database.GetFolderIndex(&mvItem);
break;
#ifdef _CAB_DETAILS #ifdef _CAB_DETAILS
case kpidBlockReal: case kpidBlockReal: prop = (UInt32)item.FolderIndex; break;
prop = UInt32(item.FolderIndex); case kpidOffset: prop = (UInt32)item.Offset; break;
break; case kpidVolume: prop = (UInt32)mvItem.VolumeIndex; break;
case kpidOffset:
prop = (UInt32)item.Offset;
break;
case kpidVolume:
prop = (UInt32)mvItem.VolumeIndex;
break;
#endif #endif
} }
@@ -209,7 +195,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
} }
/* /*
class CPropgressImp: public CProgressVirt class CProgressImp: public CProgressVirt
{ {
CMyComPtr<IArchiveOpenCallback> m_OpenArchiveCallback; CMyComPtr<IArchiveOpenCallback> m_OpenArchiveCallback;
public: public:
@@ -219,14 +205,14 @@ public:
{ m_OpenArchiveCallback = openArchiveCallback; } { m_OpenArchiveCallback = openArchiveCallback; }
}; };
STDMETHODIMP CPropgressImp::SetTotal(const UInt64 *numFiles) STDMETHODIMP CProgressImp::SetTotal(const UInt64 *numFiles)
{ {
if (m_OpenArchiveCallback) if (m_OpenArchiveCallback)
return m_OpenArchiveCallback->SetCompleted(numFiles, NULL); return m_OpenArchiveCallback->SetCompleted(numFiles, NULL);
return S_OK; return S_OK;
} }
STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles) STDMETHODIMP CProgressImp::SetCompleted(const UInt64 *numFiles)
{ {
if (m_OpenArchiveCallback) if (m_OpenArchiveCallback)
return m_OpenArchiveCallback->SetCompleted(numFiles, NULL); return m_OpenArchiveCallback->SetCompleted(numFiles, NULL);
@@ -236,7 +222,7 @@ STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles)
STDMETHODIMP CHandler::Open(IInStream *inStream, STDMETHODIMP CHandler::Open(IInStream *inStream,
const UInt64 *maxCheckStartPosition, const UInt64 *maxCheckStartPosition,
IArchiveOpenCallback *openArchiveCallback) IArchiveOpenCallback *callback)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
Close(); Close();
@@ -244,7 +230,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
CInArchive archive; CInArchive archive;
CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback; CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
{ {
CMyComPtr<IArchiveOpenCallback> openArchiveCallbackWrap = openArchiveCallback; CMyComPtr<IArchiveOpenCallback> openArchiveCallbackWrap = callback;
openArchiveCallbackWrap.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback); openArchiveCallbackWrap.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback);
} }
@@ -283,7 +269,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
} }
numItems += db.Items.Size(); numItems += db.Items.Size();
RINOK(openArchiveCallback->SetCompleted(&numItems, NULL)); RINOK(callback->SetCompleted(&numItems, NULL));
nextStream = 0; nextStream = 0;
for (;;) for (;;)
@@ -574,7 +560,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
int index = allFilesMode ? i : indices[i]; int index = allFilesMode ? i : indices[i];
const CMvItem &mvItem = m_Database.Items[index]; const CMvItem &mvItem = m_Database.Items[index];
const CItem &item = m_Database.Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; const CItem &item = m_Database.Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
if (item.IsDirectory()) if (item.IsDir())
continue; continue;
int folderIndex = m_Database.GetFolderIndex(&mvItem); int folderIndex = m_Database.GetFolderIndex(&mvItem);
if (folderIndex != lastFolder) if (folderIndex != lastFolder)
@@ -622,7 +608,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
const CItem &item = db.Items[itemIndex]; const CItem &item = db.Items[itemIndex];
i++; i++;
if (item.IsDirectory()) if (item.IsDir())
{ {
Int32 askMode= testMode ? Int32 askMode= testMode ?
NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kTest :
@@ -661,7 +647,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
int indexNext = allFilesMode ? i : indices[i]; int indexNext = allFilesMode ? i : indices[i];
const CMvItem &mvItem = m_Database.Items[indexNext]; const CMvItem &mvItem = m_Database.Items[indexNext];
const CItem &item = m_Database.Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; const CItem &item = m_Database.Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
if (item.IsDirectory()) if (item.IsDir())
continue; continue;
int newFolderIndex = m_Database.GetFolderIndex(&mvItem); int newFolderIndex = m_Database.GetFolderIndex(&mvItem);

View File

@@ -8,12 +8,8 @@ namespace NArchive{
namespace NCab{ namespace NCab{
namespace NHeader{ namespace NHeader{
namespace NArchive { Byte kMarker[kMarkerSize] = {'M' + 1, 'S', 'C', 'F', 0, 0, 0, 0 };
UInt32 kSignature = 0x4643534d + 1; struct SignatureInitializer { SignatureInitializer() { kMarker[0]--; }; } g_SignatureInitializer;
static class CSignatureInitializer
{ public: CSignatureInitializer() { kSignature--; }} g_SignatureInitializer;
}
}}} }}}

View File

@@ -7,11 +7,13 @@
namespace NArchive { namespace NArchive {
namespace NCab { namespace NCab {
namespace NHeader{ namespace NHeader {
const unsigned kMarkerSize = 8;
extern Byte kMarker[kMarkerSize];
namespace NArchive namespace NArchive
{ {
extern UInt32 kSignature;
namespace NFlags namespace NFlags
{ {
const int kPrevCabinet = 0x0001; const int kPrevCabinet = 0x0001;

View File

@@ -2,15 +2,12 @@
#include "StdAfx.h" #include "StdAfx.h"
#include "Common/StringConvert.h"
#include "Common/MyCom.h"
#include "CabIn.h" #include "CabIn.h"
#include "Windows/Defs.h"
#include "../../Common/StreamUtils.h" #include "../Common/FindSignature.h"
namespace NArchive{ namespace NArchive {
namespace NCab{ namespace NCab {
/* /*
static HRESULT ReadBytes(IInStream *inStream, void *data, UInt32 size) static HRESULT ReadBytes(IInStream *inStream, void *data, UInt32 size)
@@ -94,39 +91,21 @@ void CInArchive::Skeep(size_t size)
ReadByte(); ReadByte();
} }
HRESULT CInArchive::Open2(IInStream *inStream, HRESULT CInArchive::Open2(IInStream *stream,
const UInt64 *searchHeaderSizeLimit, const UInt64 *searchHeaderSizeLimit,
CDatabase &database) CDatabase &database)
{ {
database.Clear(); database.Clear();
RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &database.StartPosition)); RINOK(stream->Seek(0, STREAM_SEEK_SET, &database.StartPosition));
{ RINOK(FindSignatureInStream(stream, NHeader::kMarker, NHeader::kMarkerSize,
searchHeaderSizeLimit, database.StartPosition));
RINOK(stream->Seek(database.StartPosition + NHeader::kMarkerSize, STREAM_SEEK_SET, NULL));
if (!inBuffer.Create(1 << 17)) if (!inBuffer.Create(1 << 17))
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
inBuffer.SetStream(inStream); inBuffer.SetStream(stream);
inBuffer.Init(); inBuffer.Init();
UInt64 value = 0;
const int kSignatureSize = 8;
UInt64 kSignature64 = NHeader::NArchive::kSignature;
for (;;)
{
Byte b;
if (!inBuffer.ReadByte(b))
return S_FALSE;
value >>= 8;
value |= ((UInt64)b) << ((kSignatureSize - 1) * 8);
if (inBuffer.GetProcessedSize() >= kSignatureSize)
{
if (value == kSignature64)
break;
if (searchHeaderSizeLimit != NULL)
if (inBuffer.GetProcessedSize() > (*searchHeaderSizeLimit))
return S_FALSE;
}
}
database.StartPosition += inBuffer.GetProcessedSize() - kSignatureSize;
}
CInArchiveInfo &archiveInfo = database.ArchiveInfo; CInArchiveInfo &archiveInfo = database.ArchiveInfo;
@@ -141,7 +120,9 @@ HRESULT CInArchive::Open2(IInStream *inStream,
archiveInfo.VersionMajor = ReadByte(); // cabinet file format version, major archiveInfo.VersionMajor = ReadByte(); // cabinet file format version, major
archiveInfo.NumFolders = ReadUInt16(); // number of CFFOLDER entries in this cabinet archiveInfo.NumFolders = ReadUInt16(); // number of CFFOLDER entries in this cabinet
archiveInfo.NumFiles = ReadUInt16(); // number of CFFILE entries in this cabinet archiveInfo.NumFiles = ReadUInt16(); // number of CFFILE entries in this cabinet
archiveInfo.Flags = ReadUInt16(); // number of CFFILE entries in this cabinet archiveInfo.Flags = ReadUInt16();
if (archiveInfo.Flags > 7)
return S_FALSE;
archiveInfo.SetID = ReadUInt16(); // must be the same for all cabinets in a set archiveInfo.SetID = ReadUInt16(); // must be the same for all cabinets in a set
archiveInfo.CabinetNumber = ReadUInt16(); // number of this cabinet file in a set archiveInfo.CabinetNumber = ReadUInt16(); // number of this cabinet file in a set
@@ -175,9 +156,9 @@ HRESULT CInArchive::Open2(IInStream *inStream,
database.Folders.Add(folder); database.Folders.Add(folder);
} }
RINOK(inStream->Seek(database.StartPosition + archiveInfo.FileHeadersOffset, STREAM_SEEK_SET, NULL)); RINOK(stream->Seek(database.StartPosition + archiveInfo.FileHeadersOffset, STREAM_SEEK_SET, NULL));
inBuffer.SetStream(inStream); inBuffer.SetStream(stream);
inBuffer.Init(); inBuffer.Init();
for(i = 0; i < archiveInfo.NumFiles; i++) for(i = 0; i < archiveInfo.NumFiles; i++)
{ {
@@ -221,8 +202,8 @@ static int CompareMvItems(const CMvItem *p1, const CMvItem *p2, void *param)
const CDatabaseEx &db2 = mvDb.Volumes[p2->VolumeIndex]; const CDatabaseEx &db2 = mvDb.Volumes[p2->VolumeIndex];
const CItem &item1 = db1.Items[p1->ItemIndex]; const CItem &item1 = db1.Items[p1->ItemIndex];
const CItem &item2 = db2.Items[p2->ItemIndex];; const CItem &item2 = db2.Items[p2->ItemIndex];;
bool isDir1 = item1.IsDirectory(); bool isDir1 = item1.IsDir();
bool isDir2 = item2.IsDirectory(); bool isDir2 = item2.IsDir();
if (isDir1 && !isDir2) if (isDir1 && !isDir2)
return -1; return -1;
if (isDir2 && !isDir1) if (isDir2 && !isDir1)
@@ -322,7 +303,7 @@ bool CMvDatabaseEx::Check()
if (fIndex >= FolderStartFileIndex.Size()) if (fIndex >= FolderStartFileIndex.Size())
return false; return false;
const CItem &item = Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; const CItem &item = Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
if (item.IsDirectory()) if (item.IsDir())
continue; continue;
int folderIndex = GetFolderIndex(&mvItem); int folderIndex = GetFolderIndex(&mvItem);
if (folderIndex != prevFolder) if (folderIndex != prevFolder)

View File

@@ -19,9 +19,8 @@ struct CFolder
Byte GetCompressionMethod() const { return (Byte)(CompressionTypeMajor & 0xF); } Byte GetCompressionMethod() const { return (Byte)(CompressionTypeMajor & 0xF); }
}; };
class CItem struct CItem
{ {
public:
AString Name; AString Name;
UInt32 Offset; UInt32 Offset;
UInt32 Size; UInt32 Size;
@@ -29,10 +28,11 @@ public:
UInt16 FolderIndex; UInt16 FolderIndex;
UInt16 Flags; UInt16 Flags;
UInt16 Attributes; UInt16 Attributes;
UInt64 GetEndOffset() const { return (UInt64)Offset + Size; } UInt64 GetEndOffset() const { return (UInt64)Offset + Size; }
UInt32 GetWinAttributes() const { return (Attributes & ~NHeader::kFileNameIsUTFAttributeMask); } UInt32 GetWinAttributes() const { return (Attributes & ~NHeader::kFileNameIsUTFAttributeMask); }
bool IsNameUTF() const { return (Attributes & NHeader::kFileNameIsUTFAttributeMask) != 0; } bool IsNameUTF() const { return (Attributes & NHeader::kFileNameIsUTFAttributeMask) != 0; }
bool IsDirectory() const { return (Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; } bool IsDir() const { return (Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; }
bool ContinuedFromPrev() const bool ContinuedFromPrev() const
{ {
@@ -40,6 +40,7 @@ public:
(FolderIndex == NHeader::NFolderIndex::kContinuedFromPrev) || (FolderIndex == NHeader::NFolderIndex::kContinuedFromPrev) ||
(FolderIndex == NHeader::NFolderIndex::kContinuedPrevAndNext); (FolderIndex == NHeader::NFolderIndex::kContinuedPrevAndNext);
} }
bool ContinuedToNext() const bool ContinuedToNext() const
{ {
return return

View File

@@ -1,3 +0,0 @@
// StdAfx.cpp
#include "StdAfx.h"

View File

@@ -42,7 +42,6 @@ enum
STATPROPSTG kProps[] = STATPROPSTG kProps[] =
{ {
{ NULL, kpidPath, VT_BSTR}, { NULL, kpidPath, VT_BSTR},
// { NULL, kpidIsFolder, VT_BOOL},
{ NULL, kpidSize, VT_UI8}, { NULL, kpidSize, VT_UI8},
{ NULL, kpidMethod, VT_BSTR}, { NULL, kpidMethod, VT_BSTR},
{ NULL, kpidBlock, VT_UI4} { NULL, kpidBlock, VT_UI4}
@@ -132,15 +131,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
} }
break; break;
} }
case kpidIsFolder: case kpidIsDir: prop = item.IsDir(); break;
prop = item.IsDirectory(); case kpidSize: prop = item.Size; break;
break;
case kpidSize:
prop = item.Size;
break;
case kpidMethod: case kpidMethod:
{ {
if (!item.IsDirectory()) if (!item.IsDir())
if (item.Section == 0) if (item.Section == 0)
prop = L"Copy"; prop = L"Copy";
else if (item.Section < m_Database.Sections.Size()) else if (item.Section < m_Database.Sections.Size())
@@ -156,12 +151,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
#ifdef _CHM_DETAILS #ifdef _CHM_DETAILS
case kpidSection: case kpidSection: prop = (UInt32)item.Section; break;
prop = (UInt32)item.Section; case kpidOffset: prop = (UInt32)item.Offset; break;
break;
case kpidOffset:
prop = (UInt32)item.Offset;
break;
#endif #endif
} }
@@ -170,41 +161,39 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
COM_TRY_END COM_TRY_END
} }
class CPropgressImp: public CProgressVirt class CProgressImp: public CProgressVirt
{ {
CMyComPtr<IArchiveOpenCallback> m_OpenArchiveCallback; CMyComPtr<IArchiveOpenCallback> _callback;
public: public:
STDMETHOD(SetTotal)(const UInt64 *numFiles); STDMETHOD(SetTotal)(const UInt64 *numFiles);
STDMETHOD(SetCompleted)(const UInt64 *numFiles); STDMETHOD(SetCompleted)(const UInt64 *numFiles);
void Init(IArchiveOpenCallback *openArchiveCallback) CProgressImp(IArchiveOpenCallback *callback): _callback(callback) {};
{ m_OpenArchiveCallback = openArchiveCallback; }
}; };
STDMETHODIMP CPropgressImp::SetTotal(const UInt64 *numFiles) STDMETHODIMP CProgressImp::SetTotal(const UInt64 *numFiles)
{ {
if (m_OpenArchiveCallback) if (_callback)
return m_OpenArchiveCallback->SetCompleted(numFiles, NULL); return _callback->SetCompleted(numFiles, NULL);
return S_OK; return S_OK;
} }
STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles) STDMETHODIMP CProgressImp::SetCompleted(const UInt64 *numFiles)
{ {
if (m_OpenArchiveCallback) if (_callback)
return m_OpenArchiveCallback->SetCompleted(numFiles, NULL); return _callback->SetCompleted(numFiles, NULL);
return S_OK; return S_OK;
} }
STDMETHODIMP CHandler::Open(IInStream *inStream, STDMETHODIMP CHandler::Open(IInStream *inStream,
const UInt64 *maxCheckStartPosition, const UInt64 *maxCheckStartPosition,
IArchiveOpenCallback *openArchiveCallback) IArchiveOpenCallback * /* openArchiveCallback */)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
m_Stream.Release(); m_Stream.Release();
try try
{ {
CInArchive archive; CInArchive archive;
CPropgressImp progressImp; // CProgressImp progressImp(openArchiveCallback);
progressImp.Init(openArchiveCallback);
RINOK(archive.Open(inStream, maxCheckStartPosition, m_Database)); RINOK(archive.Open(inStream, maxCheckStartPosition, m_Database));
/* /*
if (m_Database.LowLevel) if (m_Database.LowLevel)
@@ -516,7 +505,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
int entryIndex = m_Database.Indices[index]; int entryIndex = m_Database.Indices[index];
const CItem &item = m_Database.Items[entryIndex]; const CItem &item = m_Database.Items[entryIndex];
UInt64 sectionIndex = item.Section; UInt64 sectionIndex = item.Section;
if (item.IsDirectory() || item.Size == 0) if (item.IsDir() || item.Size == 0)
continue; continue;
if (sectionIndex == 0) if (sectionIndex == 0)
{ {
@@ -557,7 +546,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
Int32 askMode= testMode ? Int32 askMode= testMode ?
NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kTest :
NArchive::NExtract::NAskMode::kExtract; NArchive::NExtract::NAskMode::kExtract;
if (item.IsDirectory()) if (item.IsDir())
{ {
CMyComPtr<ISequentialOutStream> realOutStream; CMyComPtr<ISequentialOutStream> realOutStream;
RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); RINOK(extractCallback->GetStream(index, &realOutStream, askMode));

View File

@@ -625,8 +625,8 @@ static int CompareFiles(const int *p1, const int *p2, void *param)
const CObjectVector<CItem> &items = *(const CObjectVector<CItem> *)param; const CObjectVector<CItem> &items = *(const CObjectVector<CItem> *)param;
const CItem &item1 = items[*p1]; const CItem &item1 = items[*p1];
const CItem &item2 = items[*p2]; const CItem &item2 = items[*p2];
bool isDir1 = item1.IsDirectory(); bool isDir1 = item1.IsDir();
bool isDir2 = item2.IsDirectory(); bool isDir2 = item2.IsDir();
if (isDir1 && !isDir2) if (isDir1 && !isDir2)
return -1; return -1;
if (isDir2) if (isDir2)
@@ -663,7 +663,7 @@ bool CFilesDatabase::Check()
for(int i = 0; i < Indices.Size(); i++) for(int i = 0; i < Indices.Size(); i++)
{ {
const CItem &item = Items[Indices[i]]; const CItem &item = Items[Indices[i]];
if (item.Section == 0 || item.IsDirectory()) if (item.Section == 0 || item.IsDir())
continue; continue;
if (item.Section != prevSection) if (item.Section != prevSection)
{ {
@@ -864,6 +864,11 @@ HRESULT CInArchive::Open2(IInStream *inStream,
const int kSignatureSize = 8; const int kSignatureSize = 8;
UInt64 hxsSignature = NHeader::GetHxsSignature(); UInt64 hxsSignature = NHeader::GetHxsSignature();
UInt64 chmSignature = ((UInt64)chmVersion << 32)| NHeader::kItsfSignature; UInt64 chmSignature = ((UInt64)chmVersion << 32)| NHeader::kItsfSignature;
UInt64 limit = 1 << 18;
if (searchHeaderSizeLimit)
if (limit > *searchHeaderSizeLimit)
limit = *searchHeaderSizeLimit;
for (;;) for (;;)
{ {
Byte b; Byte b;
@@ -880,8 +885,7 @@ HRESULT CInArchive::Open2(IInStream *inStream,
database.Help2Format = true; database.Help2Format = true;
break; break;
} }
if (searchHeaderSizeLimit != NULL) if (_inBuffer.GetProcessedSize() > limit)
if (_inBuffer.GetProcessedSize() > (*searchHeaderSizeLimit))
return S_FALSE; return S_FALSE;
} }
} }

View File

@@ -33,7 +33,7 @@ struct CItem
return Name[0] == '/'; return Name[0] == '/';
} }
bool IsDirectory() const bool IsDir() const
{ {
if (Name.Length() == 0) if (Name.Length() == 0)
return false; return false;

View File

@@ -1,3 +0,0 @@
// StdAfx.cpp
#include "StdAfx.h"

View File

@@ -13,12 +13,12 @@ namespace NCom {
STATPROPSTG kProps[] = STATPROPSTG kProps[] =
{ {
{ NULL, kpidPath, VT_BSTR}, { NULL, kpidPath, VT_BSTR},
{ NULL, kpidIsFolder, VT_BOOL}, { NULL, kpidIsDir, VT_BOOL},
{ NULL, kpidSize, VT_UI8}, { NULL, kpidSize, VT_UI8},
// { NULL, kpidAttributes, VT_UI4}, // { NULL, kpidAttributes, VT_UI4},
{ NULL, kpidPackedSize, VT_UI8}, { NULL, kpidPackSize, VT_UI8},
{ NULL, kpidCreationTime, VT_FILETIME}, { NULL, kpidCTime, VT_FILETIME},
{ NULL, kpidLastWriteTime, VT_FILETIME} { NULL, kpidMTime, VT_FILETIME}
}; };
@@ -58,21 +58,15 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
prop = name; prop = name;
break; break;
} }
case kpidIsFolder: case kpidIsDir: prop = item.IsDir(); break;
prop = item.IsDir(); case kpidCTime: prop = item.CTime; break;
break; case kpidMTime: prop = item.MTime; break;
case kpidCreationTime:
prop = item.CreationTime;
break;
case kpidLastWriteTime:
prop = item.LastWriteTime;
break;
/* /*
case kpidAttributes: case kpidAttributes:
prop = item.Falgs; prop = item.Falgs;
break; break;
*/ */
case kpidPackedSize: case kpidPackSize:
if (!item.IsDir()) if (!item.IsDir())
{ {
int numBits = _db.IsLargeStream(item.Size) ? int numBits = _db.IsLargeStream(item.Size) ?

View File

@@ -69,8 +69,8 @@ static void ReadItem(Byte *p, CItem &item, bool mode64bit)
item.RightDid = GetUi32(p + 72); item.RightDid = GetUi32(p + 72);
item.SonDid = GetUi32(p + 76); item.SonDid = GetUi32(p + 76);
// item.Flags = GetUi32(p + 96); // item.Flags = GetUi32(p + 96);
GetFileTimeFromMem(p + 100, &item.CreationTime); GetFileTimeFromMem(p + 100, &item.CTime);
GetFileTimeFromMem(p + 108, &item.LastWriteTime); GetFileTimeFromMem(p + 108, &item.MTime);
item.Sid = GetUi32(p + 116); item.Sid = GetUi32(p + 116);
item.Size = GetUi32(p + 120); item.Size = GetUi32(p + 120);
if (mode64bit) if (mode64bit)

View File

@@ -46,8 +46,8 @@ struct CItem
Byte Name[kNameSizeMax]; Byte Name[kNameSizeMax];
// UInt16 NameSize; // UInt16 NameSize;
// UInt32 Flags; // UInt32 Flags;
FILETIME CreationTime; FILETIME CTime;
FILETIME LastWriteTime; FILETIME MTime;
UInt64 Size; UInt64 Size;
UInt32 LeftDid; UInt32 LeftDid;
UInt32 RightDid; UInt32 RightDid;

View File

@@ -14,6 +14,7 @@ class CDummyOutStream:
UInt64 _size; UInt64 _size;
public: public:
void SetStream(ISequentialOutStream *outStream) { _stream = outStream; } void SetStream(ISequentialOutStream *outStream) { _stream = outStream; }
void ReleaseStream() { _stream.Release(); }
void Init() { _size = 0; } void Init() { _size = 0; }
MY_UNKNOWN_IMP MY_UNKNOWN_IMP
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);

View File

@@ -0,0 +1,62 @@
// FindSignature.cpp
#include "StdAfx.h"
#include "Common/Buffer.h"
#include "FindSignature.h"
#include "../../Common/StreamUtils.h"
HRESULT FindSignatureInStream(ISequentialInStream *stream,
const Byte *signature, unsigned signatureSize,
const UInt64 *limit, UInt64 &resPos)
{
resPos = 0;
CByteBuffer byteBuffer2;
byteBuffer2.SetCapacity(signatureSize);
RINOK(ReadStream_FALSE(stream, byteBuffer2, signatureSize));
if (memcmp(byteBuffer2, signature, signatureSize) == 0)
return S_OK;
const UInt32 kBufferSize = (1 << 16);
CByteBuffer byteBuffer;
byteBuffer.SetCapacity(kBufferSize);
Byte *buffer = byteBuffer;
UInt32 numPrevBytes = signatureSize - 1;
memcpy(buffer, (const Byte *)byteBuffer2 + 1, numPrevBytes);
resPos = 1;
for (;;)
{
if (limit != NULL)
if (resPos > *limit)
return S_FALSE;
do
{
UInt32 numReadBytes = kBufferSize - numPrevBytes;
UInt32 processedSize;
RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize));
numPrevBytes += processedSize;
if (processedSize == 0)
return S_FALSE;
}
while (numPrevBytes < signatureSize);
UInt32 numTests = numPrevBytes - signatureSize + 1;
for (UInt32 pos = 0; pos < numTests; pos++)
{
Byte b = signature[0];
for (; buffer[pos] != b && pos < numTests; pos++);
if (pos == numTests)
break;
if (memcmp(buffer + pos, signature, signatureSize) == 0)
{
resPos += pos;
return S_OK;
}
}
resPos += numTests;
numPrevBytes -= numTests;
memmove(buffer, buffer + numTests, numPrevBytes);
}
}

View File

@@ -0,0 +1,12 @@
// FindSignature.h
#ifndef __FINDSIGNATURE_H
#define __FINDSIGNATURE_H
#include "../../IStream.h"
HRESULT FindSignatureInStream(ISequentialInStream *stream,
const Byte *signature, unsigned signatureSize,
const UInt64 *limit, UInt64 &resPos);
#endif

View File

@@ -457,11 +457,12 @@ void COutHandler::Init()
{ {
_removeSfxBlock = false; _removeSfxBlock = false;
_compressHeaders = true; _compressHeaders = true;
_encryptHeadersSpecified = false;
_encryptHeaders = false; _encryptHeaders = false;
WriteModified = true; WriteCTime = false;
WriteCreated = false; WriteATime = false;
WriteAccessed = false; WriteMTime = true;
#ifdef COMPRESS_MT #ifdef COMPRESS_MT
_numThreads = NWindows::NSystem::GetNumberOfProcessors(); _numThreads = NWindows::NSystem::GetNumberOfProcessors();
@@ -530,12 +531,9 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
#endif #endif
return S_OK; return S_OK;
} }
if (name.CompareNoCase(L"RSFX") == 0) if (name.CompareNoCase(L"RSFX") == 0) return SetBoolProperty(_removeSfxBlock, value);
return SetBoolProperty(_removeSfxBlock, value); if (name.CompareNoCase(L"F") == 0) return SetBoolProperty(_autoFilter, value);
if (name.CompareNoCase(L"F") == 0) if (name.CompareNoCase(L"HC") == 0) return SetBoolProperty(_compressHeaders, value);
return SetBoolProperty(_autoFilter, value);
if (name.CompareNoCase(L"HC") == 0)
return SetBoolProperty(_compressHeaders, value);
if (name.CompareNoCase(L"HCF") == 0) if (name.CompareNoCase(L"HCF") == 0)
{ {
bool compressHeadersFull = true; bool compressHeadersFull = true;
@@ -545,15 +543,15 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
return S_OK; return S_OK;
} }
if (name.CompareNoCase(L"HE") == 0) if (name.CompareNoCase(L"HE") == 0)
return SetBoolProperty(_encryptHeaders, value); {
if (name.CompareNoCase(L"TM") == 0) RINOK(SetBoolProperty(_encryptHeaders, value));
return SetBoolProperty(WriteModified, value); _encryptHeadersSpecified = true;
if (name.CompareNoCase(L"TC") == 0) return S_OK;
return SetBoolProperty(WriteCreated, value); }
if (name.CompareNoCase(L"TA") == 0) if (name.CompareNoCase(L"TC") == 0) return SetBoolProperty(WriteCTime, value);
return SetBoolProperty(WriteAccessed, value); if (name.CompareNoCase(L"TA") == 0) return SetBoolProperty(WriteATime, value);
if (name.CompareNoCase(L"V") == 0) if (name.CompareNoCase(L"TM") == 0) return SetBoolProperty(WriteMTime, value);
return SetBoolProperty(_volumeMode, value); if (name.CompareNoCase(L"V") == 0) return SetBoolProperty(_volumeMode, value);
number = 0; number = 0;
} }
if (number > 10000) if (number > 10000)

View File

@@ -4,7 +4,7 @@
#define __HANDLER_OUT_H #define __HANDLER_OUT_H
#include "../../Common/MethodProps.h" #include "../../Common/MethodProps.h"
#include "../../Common/CreateCoder.h" #include "../../../Common/MyString.h"
namespace NArchive { namespace NArchive {
@@ -37,11 +37,12 @@ public:
bool _solidExtension; bool _solidExtension;
bool _compressHeaders; bool _compressHeaders;
bool _encryptHeadersSpecified;
bool _encryptHeaders; bool _encryptHeaders;
bool WriteModified; bool WriteCTime;
bool WriteCreated; bool WriteATime;
bool WriteAccessed; bool WriteMTime;
bool _autoFilter; bool _autoFilter;
UInt32 _level; UInt32 _level;
@@ -77,8 +78,6 @@ public:
UInt32 numProcessors; UInt32 numProcessors;
UInt32 mainDicSize; UInt32 mainDicSize;
UInt32 mainDicMethodIndex; UInt32 mainDicMethodIndex;
DECL_EXTERNAL_CODECS_VARS
}; };
} }

View File

@@ -27,7 +27,7 @@ namespace NArchive {
namespace NCpio { namespace NCpio {
/* /*
enum // PropID enum
{ {
kpidinode = kpidUserDefined, kpidinode = kpidUserDefined,
kpidiChkSum kpidiChkSum
@@ -37,10 +37,10 @@ enum // PropID
STATPROPSTG kProps[] = STATPROPSTG kProps[] =
{ {
{ NULL, kpidPath, VT_BSTR}, { NULL, kpidPath, VT_BSTR},
{ NULL, kpidIsFolder, VT_BOOL}, { NULL, kpidIsDir, VT_BOOL},
{ NULL, kpidSize, VT_UI8}, { NULL, kpidSize, VT_UI8},
{ NULL, kpidPackedSize, VT_UI8}, { NULL, kpidPackSize, VT_UI8},
{ NULL, kpidLastWriteTime, VT_FILETIME}, { NULL, kpidMTime, VT_FILETIME},
// { NULL, kpidUser, VT_BSTR}, // { NULL, kpidUser, VT_BSTR},
// { NULL, kpidGroup, VT_BSTR}, // { NULL, kpidGroup, VT_BSTR},
// { L"inode", kpidinode, VT_UI4} // { L"inode", kpidinode, VT_UI4}
@@ -52,25 +52,26 @@ IMP_IInArchive_ArcProps_NO
STDMETHODIMP CHandler::Open(IInStream *stream, STDMETHODIMP CHandler::Open(IInStream *stream,
const UInt64 * /* maxCheckStartPosition */, const UInt64 * /* maxCheckStartPosition */,
IArchiveOpenCallback *openArchiveCallback) IArchiveOpenCallback *callback)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
// try // try
{ {
CInArchive archive; CInArchive archive;
if (archive.Open(stream) != S_OK) UInt64 endPos = 0;
return S_FALSE; bool needSetTotal = true;
if (callback != NULL)
{
RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos));
RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
}
RINOK(archive.Open(stream));
_items.Clear(); _items.Clear();
if (openArchiveCallback != NULL)
{
RINOK(openArchiveCallback->SetTotal(NULL, NULL));
UInt64 numFiles = _items.Size();
RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
}
for (;;) for (;;)
{ {
CItemEx item; CItemEx item;
@@ -84,10 +85,19 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
break; break;
_items.Add(item); _items.Add(item);
archive.SkeepDataRecords(item.Size, item.Align); archive.SkeepDataRecords(item.Size, item.Align);
if (openArchiveCallback != NULL) if (callback != NULL)
{
if (needSetTotal)
{
RINOK(callback->SetTotal(NULL, &endPos));
needSetTotal = false;
}
if (_items.Size() % 100 == 0)
{ {
UInt64 numFiles = _items.Size(); UInt64 numFiles = _items.Size();
RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); UInt64 numBytes = item.HeaderPosition;
RINOK(callback->SetCompleted(&numFiles, &numBytes));
}
} }
} }
if (_items.Size() == 0) if (_items.Size() == 0)
@@ -127,17 +137,16 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
switch(propID) switch(propID)
{ {
case kpidPath: case kpidPath:
prop = (const wchar_t *)NItemName::GetOSName( prop = NItemName::GetOSName(MultiByteToUnicodeString(item.Name, CP_OEMCP));
MultiByteToUnicodeString(item.Name, CP_OEMCP));
break; break;
case kpidIsFolder: case kpidIsDir:
prop = item.IsDirectory(); prop = item.IsDir();
break; break;
case kpidSize: case kpidSize:
case kpidPackedSize: case kpidPackSize:
prop = (UInt64)item.Size; prop = (UInt64)item.Size;
break; break;
case kpidLastWriteTime: case kpidMTime:
{ {
FILETIME utcFileTime; FILETIME utcFileTime;
if (item.ModificationTime != 0) if (item.ModificationTime != 0)
@@ -151,12 +160,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
break; break;
} }
/* /*
case kpidinode: case kpidinode: prop = item.inode; break;
prop = item.inode; case kpidiChkSum: prop = item.ChkSum; break;
break;
case kpidiChkSum:
prop = item.ChkSum;
break;
*/ */
} }
prop.Detach(value); prop.Detach(value);
@@ -206,7 +211,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
const CItemEx &item = _items[index]; const CItemEx &item = _items[index];
RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
currentItemSize = item.Size; currentItemSize = item.Size;
if (item.IsDirectory()) if (item.IsDir())
{ {
RINOK(extractCallback->PrepareOperation(askMode)); RINOK(extractCallback->PrepareOperation(askMode));
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));

View File

@@ -34,7 +34,7 @@ struct CItem
UInt32 Align; UInt32 Align;
bool IsDirectory() const bool IsDir() const
#ifdef _WIN32 #ifdef _WIN32
{ return (Mode & _S_IFMT) == _S_IFDIR; } { return (Mode & _S_IFMT) == _S_IFDIR; }
#else #else

View File

@@ -1,3 +0,0 @@
// StdAfx.cpp
#include "StdAfx.h"

View File

@@ -1,202 +0,0 @@
// DebHandler.cpp
#include "StdAfx.h"
#include "DebHandler.h"
#include "DebIn.h"
#include "Common/Defs.h"
#include "Common/StringConvert.h"
#include "Common/NewHandler.h"
#include "Common/ComTry.h"
#include "Windows/Time.h"
#include "Windows/PropVariant.h"
#include "../../Common/ProgressUtils.h"
#include "../../Common/LimitedStreams.h"
#include "../../Compress/Copy/CopyCoder.h"
#include "../Common/ItemNameUtils.h"
using namespace NWindows;
using namespace NTime;
namespace NArchive {
namespace NDeb {
STATPROPSTG kProps[] =
{
{ NULL, kpidPath, VT_BSTR},
{ NULL, kpidSize, VT_UI8},
{ NULL, kpidPackedSize, VT_UI8},
{ NULL, kpidLastWriteTime, VT_FILETIME}
};
IMP_IInArchive_Props
IMP_IInArchive_ArcProps_NO
STDMETHODIMP CHandler::Open(IInStream *stream,
const UInt64 * /* maxCheckStartPosition */,
IArchiveOpenCallback *openArchiveCallback)
{
COM_TRY_BEGIN
{
CInArchive archive;
if(archive.Open(stream) != S_OK)
return S_FALSE;
_items.Clear();
if (openArchiveCallback != NULL)
{
RINOK(openArchiveCallback->SetTotal(NULL, NULL));
UInt64 numFiles = _items.Size();
RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
}
for (;;)
{
CItemEx item;
bool filled;
HRESULT result = archive.GetNextItem(filled, item);
if (result == S_FALSE)
return S_FALSE;
if (result != S_OK)
return S_FALSE;
if (!filled)
break;
_items.Add(item);
archive.SkeepData(item.Size);
if (openArchiveCallback != NULL)
{
UInt64 numFiles = _items.Size();
RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
}
}
_inStream = stream;
}
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::Close()
{
_inStream.Release();
_items.Clear();
return S_OK;
}
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{
*numItems = _items.Size();
return S_OK;
}
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop;
const CItemEx &item = _items[index];
switch(propID)
{
case kpidPath:
prop = (const wchar_t *)NItemName::GetOSName2(
MultiByteToUnicodeString(item.Name, CP_OEMCP));
break;
case kpidIsFolder:
prop = false;
break;
case kpidSize:
case kpidPackedSize:
prop = item.Size;
break;
case kpidLastWriteTime:
{
FILETIME utcFileTime;
if (item.ModificationTime != 0)
NTime::UnixTimeToFileTime(item.ModificationTime, utcFileTime);
else
{
utcFileTime.dwLowDateTime = 0;
utcFileTime.dwHighDateTime = 0;
}
prop = utcFileTime;
break;
}
}
prop.Detach(value);
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
{
COM_TRY_BEGIN
bool testMode = (_aTestMode != 0);
bool allFilesMode = (numItems == UInt32(-1));
if (allFilesMode)
numItems = _items.Size();
if (numItems == 0)
return S_OK;
UInt64 totalSize = 0;
UInt32 i;
for (i = 0; i < numItems; i++)
totalSize += _items[allFilesMode ? i : indices[i]].Size;
extractCallback->SetTotal(totalSize);
UInt64 currentTotalSize = 0;
UInt64 currentItemSize;
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, false);
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream(streamSpec);
streamSpec->SetStream(_inStream);
for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize)
{
lps->InSize = lps->OutSize = currentTotalSize;
RINOK(lps->SetCur());
CMyComPtr<ISequentialOutStream> realOutStream;
Int32 askMode = testMode ?
NArchive::NExtract::NAskMode::kTest :
NArchive::NExtract::NAskMode::kExtract;
Int32 index = allFilesMode ? i : indices[i];
const CItemEx &item = _items[index];
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
currentItemSize = item.Size;
if (!testMode && (!realOutStream))
continue;
RINOK(extractCallback->PrepareOperation(askMode));
if (testMode)
{
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
continue;
}
RINOK(_inStream->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL));
streamSpec->Init(item.Size);
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));
}
return S_OK;
COM_TRY_END
}
}}

View File

@@ -1,13 +0,0 @@
// Archive/Deb/Header.h
#include "StdAfx.h"
#include "DebHeader.h"
namespace NArchive {
namespace NDeb {
namespace NHeader {
const char *kSignature = "!<arch>\n";
}}}

View File

@@ -1,38 +0,0 @@
// Archive/Deb/Header.h
#ifndef __ARCHIVE_DEB_HEADER_H
#define __ARCHIVE_DEB_HEADER_H
#include "Common/Types.h"
namespace NArchive {
namespace NDeb {
namespace NHeader
{
const int kSignatureLen = 8;
extern const char *kSignature;
const int kNameSize = 16;
const int kTimeSize = 12;
const int kModeSize = 8;
const int kSizeSize = 10;
/*
struct CHeader
{
char Name[kNameSize];
char ModificationTime[kTimeSize];
char Number0[6];
char Number1[6];
char Mode[kModeSize];
char Size[kSizeSize];
char Quote;
char NewLine;
};
*/
const int kHeaderSize = kNameSize + kTimeSize + 6 + 6 + kModeSize + kSizeSize + 1 + 1;
}
}}
#endif

View File

@@ -1,156 +0,0 @@
// Archive/DebIn.cpp
#include "StdAfx.h"
#include "DebIn.h"
#include "DebHeader.h"
#include "Common/StringToInt.h"
#include "Windows/Defs.h"
#include "../../Common/StreamUtils.h"
namespace NArchive {
namespace NDeb {
using namespace NHeader;
HRESULT CInArchive::Open(IInStream *inStream)
{
RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_Position));
char signature[kSignatureLen];
RINOK(ReadStream_FALSE(inStream, signature, kSignatureLen));
m_Position += kSignatureLen;
if (memcmp(signature, kSignature, kSignatureLen) != 0)
return S_FALSE;
m_Stream = inStream;
return S_OK;
}
static void MyStrNCpy(char *dest, const char *src, int size)
{
for (int i = 0; i < size; i++)
{
char c = src[i];
dest[i] = c;
if (c == 0)
break;
}
}
static bool OctalToNumber(const char *s, int size, UInt64 &res)
{
char sz[32];
MyStrNCpy(sz, s, size);
sz[size] = 0;
const char *end;
int i;
for (i = 0; sz[i] == ' '; i++);
res = ConvertOctStringToUInt64(sz + i, &end);
return (*end == ' ' || *end == 0);
}
static bool OctalToNumber32(const char *s, int size, UInt32 &res)
{
UInt64 res64;
if (!OctalToNumber(s, size, res64))
return false;
res = (UInt32)res64;
return (res64 <= 0xFFFFFFFF);
}
static bool DecimalToNumber(const char *s, int size, UInt64 &res)
{
char sz[32];
MyStrNCpy(sz, s, size);
sz[size] = 0;
const char *end;
int i;
for (i = 0; sz[i] == ' '; i++);
res = ConvertStringToUInt64(sz + i, &end);
return (*end == ' ' || *end == 0);
}
static bool DecimalToNumber32(const char *s, int size, UInt32 &res)
{
UInt64 res64;
if (!DecimalToNumber(s, size, res64))
return false;
res = (UInt32)res64;
return (res64 <= 0xFFFFFFFF);
}
#define RIF(x) { if (!(x)) return S_FALSE; }
HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item)
{
filled = false;
char header[NHeader::kHeaderSize];
const char *cur = header;
size_t processedSize = sizeof(header);
item.HeaderPosition = m_Position;
RINOK(ReadStream(m_Stream, header, &processedSize));
m_Position += processedSize;
if (processedSize != sizeof(header))
return S_OK;
char tempString[kNameSize + 1];
MyStrNCpy(tempString, cur, kNameSize);
cur += kNameSize;
tempString[kNameSize] = '\0';
item.Name = tempString;
item.Name.Trim();
for (int i = 0; i < item.Name.Length(); i++)
if (((Byte)item.Name[i]) < 0x20)
return S_FALSE;
RIF(DecimalToNumber32(cur, kTimeSize, item.ModificationTime));
cur += kTimeSize;
cur += 6 + 6;
RIF(OctalToNumber32(cur, kModeSize, item.Mode));
cur += kModeSize;
RIF(DecimalToNumber(cur, kSizeSize, item.Size));
cur += kSizeSize;
filled = true;
return S_OK;
}
HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
{
for (;;)
{
RINOK(GetNextItemReal(filled, item));
if (!filled)
return S_OK;
if (item.Name.CompareNoCase("debian-binary") != 0)
return S_OK;
if (item.Size != 4)
return S_OK;
SkeepData(item.Size);
}
}
HRESULT CInArchive::Skeep(UInt64 numBytes)
{
UInt64 newPostion;
RINOK(m_Stream->Seek(numBytes, STREAM_SEEK_CUR, &newPostion));
m_Position += numBytes;
if (m_Position != newPostion)
return E_FAIL;
return S_OK;
}
HRESULT CInArchive::SkeepData(UInt64 dataSize)
{
return Skeep((dataSize + 1) & (~((UInt64)0x1)));
}
}}

View File

@@ -1,28 +0,0 @@
// Archive/DebIn.h
#ifndef __ARCHIVE_DEB_IN_H
#define __ARCHIVE_DEB_IN_H
#include "Common/MyCom.h"
#include "../../IStream.h"
#include "DebItem.h"
namespace NArchive {
namespace NDeb {
class CInArchive
{
CMyComPtr<IInStream> m_Stream;
UInt64 m_Position;
HRESULT GetNextItemReal(bool &filled, CItemEx &itemInfo);
HRESULT Skeep(UInt64 numBytes);
public:
HRESULT Open(IInStream *inStream);
HRESULT GetNextItem(bool &filled, CItemEx &itemInfo);
HRESULT SkeepData(UInt64 dataSize);
};
}}
#endif

View File

@@ -1,32 +0,0 @@
// Archive/Deb/ItemInfo.h
#ifndef __ARCHIVE_DEB_ITEMINFO_H
#define __ARCHIVE_DEB_ITEMINFO_H
#include "Common/Types.h"
#include "Common/MyString.h"
#include "DebHeader.h"
namespace NArchive {
namespace NDeb {
class CItem
{
public:
AString Name;
UInt64 Size;
UInt32 ModificationTime;
UInt32 Mode;
};
class CItemEx: public CItem
{
public:
UInt64 HeaderPosition;
UInt64 GetDataPosition() const { return HeaderPosition + NHeader::kHeaderSize; };
// UInt64 GetFullSize() const { return NFileHeader::kRecordSize + Size; };
};
}}
#endif

View File

@@ -1,13 +0,0 @@
// DebRegister.cpp
#include "StdAfx.h"
#include "../../Common/RegisterArc.h"
#include "DebHandler.h"
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 };
REGISTER_ARC(Deb)

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