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
2008-03-13
2008-08-05
Igor Pavlov
Public domain */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
/* CpuArch.h
2008-03-26
2008-08-05
Igor Pavlov
Public domain */
@@ -23,19 +23,19 @@ about these properties of platform.
#define GetUi16(p) (*(const UInt16 *)(p))
#define GetUi32(p) (*(const UInt32 *)(p))
#define GetUi64(p) (*(const UInt64 *)(p))
#define SetUi32(p, d) *(UInt32 *)(p) = d;
#define SetUi32(p, d) *(UInt32 *)(p) = (d);
#else
#define GetUi16(p) (((const Byte *)(p))[0] | \
((UInt16)((const Byte *)(p))[1] << 8))
#define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8))
#define GetUi32(p) (((const Byte *)(p))[0] | \
#define GetUi32(p) ( \
((const Byte *)(p))[0] | \
((UInt32)((const Byte *)(p))[1] << 8) | \
((UInt32)((const Byte *)(p))[2] << 16) | \
((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); \
((Byte *)(p))[0] = (Byte)_x_; \
@@ -45,4 +45,25 @@ about these properties of platform.
#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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
/* LzmaDec.c -- LZMA Decoder
2008-04-29
2008-08-05
Copyright (c) 1999-2008 Igor Pavlov
Read LzmaDec.h for license options */
@@ -120,7 +120,7 @@ StopCompilingDueBUG
#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,
7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
/* 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.
Igor Pavlov
Public domain */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -10,9 +10,6 @@
#include "../../../Windows/Defs.h"
#include "../Common/ItemNameUtils.h"
#ifdef _7Z_VOL
#include "../Common/MultiStream.h"
#endif
#ifdef __7Z_SET_PROPERTIES
#ifdef EXTRACT_ONLY
@@ -35,9 +32,13 @@ CHandler::CHandler()
{
_crcSize = 4;
#ifndef _NO_CRYPTO
_passwordIsDefined = false;
#endif
#ifdef EXTRACT_ONLY
#ifdef COMPRESS_MT
_numThreads = NWindows::NSystem::GetNumberOfProcessors();
_numThreads = NSystem::GetNumberOfProcessors();
#endif
#else
Init();
@@ -46,12 +47,7 @@ CHandler::CHandler()
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{
*numItems =
#ifdef _7Z_VOL
_refs.Size();
#else
*numItems = _database.Files.Size();
#endif
*numItems = _db.Files.Size();
return S_OK;
}
@@ -77,13 +73,16 @@ STATPROPSTG kArcProps[] =
{
{ NULL, kpidMethod, VT_BSTR},
{ 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)
{
COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop;
NCOM::CPropVariant prop;
switch(propID)
{
case kpidMethod:
@@ -91,9 +90,9 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
UString resString;
CRecordVector<UInt64> ids;
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--)
ids.AddToUniqueSorted(f.Coders[j].MethodID);
}
@@ -112,8 +111,11 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
prop = resString;
break;
}
case kpidSolid: prop = _database.IsSolid(); break;
case kpidNumBlocks: prop = (UInt32)_database.Folders.Size(); break;
case kpidSolid: prop = _db.IsSolid(); 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);
return S_OK;
@@ -124,10 +126,16 @@ IMP_IInArchive_ArcProps
#endif
static void MySetFileTime(bool timeDefined, FILETIME unixTime, NWindows::NCOM::CPropVariant &prop)
static void SetPropFromUInt64Def(CUInt64DefVector &v, int index, NCOM::CPropVariant &prop)
{
if (timeDefined)
prop = unixTime;
UInt64 value;
if (v.GetItem(index, value))
{
FILETIME ft;
ft.dwLowDateTime = (DWORD)value;
ft.dwHighDateTime = (DWORD)(value >> 32);
prop = ft;
}
}
#ifndef _SFX
@@ -192,10 +200,10 @@ static inline UInt32 GetUInt32FromMemLE(const Byte *p)
bool CHandler::IsEncrypted(UInt32 index2) const
{
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
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--)
if (folderInfo.Coders[i].MethodID == k_AES)
return true;
@@ -206,7 +214,7 @@ bool CHandler::IsEncrypted(UInt32 index2) const
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop;
NCOM::CPropVariant prop;
/*
const CRef2 &ref2 = _refs[index];
@@ -215,54 +223,31 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
const CRef &ref = ref2.Refs.Front();
*/
#ifdef _7Z_VOL
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];
const CFileItem &item = _db.Files[index];
UInt32 index2 = index;
#endif
switch(propID)
{
case kpidPath:
{
if (!item.Name.IsEmpty())
prop = NItemName::GetOSName(item.Name);
break;
}
case kpidIsFolder:
prop = item.IsDirectory;
break;
case kpidIsDir: prop = item.IsDir; break;
case kpidSize:
{
prop = item.UnPackSize;
// prop = ref2.UnPackSize;
prop = item.Size;
// prop = ref2.Size;
break;
}
case kpidPosition:
{
/*
if (ref2.Refs.Size() > 1)
prop = ref2.StartPos;
else
*/
if (item.IsStartPosDefined)
prop = item.StartPos;
break;
}
case kpidPackedSize:
case kpidPackSize:
{
// prop = ref2.PackSize;
{
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
if (folderIndex != kNumNoIndex)
{
if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2)
prop = _database.GetFolderFullPackSize(folderIndex);
if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2)
prop = _db.GetFolderFullPackSize(folderIndex);
/*
else
prop = (UInt64)0;
@@ -273,35 +258,21 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
}
break;
}
case kpidLastAccessTime:
MySetFileTime(item.IsLastAccessTimeDefined, item.LastAccessTime, prop);
break;
case kpidCreationTime:
MySetFileTime(item.IsCreationTimeDefined, item.CreationTime, prop);
break;
case kpidLastWriteTime:
MySetFileTime(item.IsLastWriteTimeDefined, item.LastWriteTime, prop);
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;
}
case kpidPosition: { UInt64 v; if (_db.StartPos.GetItem(index2, v)) prop = v; break; }
case kpidCTime: SetPropFromUInt64Def(_db.CTime, index2, prop); break;
case kpidATime: SetPropFromUInt64Def(_db.ATime, index2, prop); break;
case kpidMTime: SetPropFromUInt64Def(_db.MTime, index2, prop); break;
case kpidAttrib: if (item.AttribDefined) prop = item.Attrib; break;
case kpidCRC: if (item.CrcDefined) prop = item.Crc; break;
case kpidEncrypted: prop = IsEncrypted(index2); break;
case kpidIsAnti: prop = _db.IsItemAnti(index2); break;
#ifndef _SFX
case kpidMethod:
{
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
if (folderIndex != kNumNoIndex)
{
const CFolder &folderInfo = _database.Folders[folderIndex];
const CFolder &folderInfo = _db.Folders[folderIndex];
UString methodsString;
for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--)
{
@@ -398,7 +369,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
break;
case kpidBlock:
{
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
if (folderIndex != kNumNoIndex)
prop = (UInt32)folderIndex;
}
@@ -409,14 +380,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
case kpidPackedSize3:
case kpidPackedSize4:
{
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
if (folderIndex != kNumNoIndex)
{
const CFolder &folderInfo = _database.Folders[folderIndex];
if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2 &&
const CFolder &folderInfo = _db.Folders[folderIndex];
if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2 &&
folderInfo.PackStreams.Size() > (int)(propID - kpidPackedSize0))
{
prop = _database.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0);
prop = _db.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0);
}
else
prop = (UInt64)0;
@@ -426,95 +397,12 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
}
break;
#endif
case kpidIsAnti:
prop = item.IsAnti;
break;
}
prop.Detach(value);
return S_OK;
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,
const UInt64 *maxCheckStartPosition,
IArchiveOpenCallback *openArchiveCallback)
@@ -527,11 +415,6 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
try
{
CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = openArchiveCallback;
#ifdef _7Z_VOL
CVolumeName seqName;
CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
#endif
#ifndef _NO_CRYPTO
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
@@ -541,127 +424,22 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
IID_ICryptoGetTextPassword, &getTextPassword);
}
#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;
RINOK(archive.Open(stream, maxCheckStartPosition));
#ifndef _NO_CRYPTO
_passwordIsDefined = false;
UString password;
#endif
HRESULT result = archive.ReadDatabase(
EXTERNAL_CODECS_VARS
_database
_db
#ifndef _NO_CRYPTO
, getTextPassword
, getTextPassword, _passwordIsDefined
#endif
);
RINOK(result);
_database.Fill();
_db.Fill();
_inStream = stream;
#endif
}
catch(...)
{
@@ -679,75 +457,12 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
STDMETHODIMP CHandler::Close()
{
COM_TRY_BEGIN
#ifdef _7Z_VOL
_volumes.Clear();
_refs.Clear();
#else
_inStream.Release();
_database.Clear();
#endif
_db.Clear();
return S_OK;
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 EXTRACT_ONLY

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -35,19 +35,19 @@ struct CFolder
CObjectVector<CCoderInfo> Coders;
CRecordVector<CBindPair> BindPairs;
CRecordVector<CNum> PackStreams;
CRecordVector<UInt64> UnPackSizes;
UInt32 UnPackCRC;
bool UnPackCRCDefined;
CRecordVector<UInt64> UnpackSizes;
UInt32 UnpackCRC;
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;
for (int i = UnPackSizes.Size() - 1; i >= 0; i--)
for (int i = UnpackSizes.Size() - 1; i >= 0; i--)
if (FindBindPairForOutStream(i) < 0)
return UnPackSizes[i];
return UnpackSizes[i];
throw 1;
}
@@ -82,66 +82,86 @@ struct CFolder
}
};
typedef FILETIME CArchiveFileTime;
class CFileItem
struct CUInt64DefVector
{
public:
CArchiveFileTime CreationTime;
CArchiveFileTime LastWriteTime;
CArchiveFileTime LastAccessTime;
UInt64 UnPackSize;
UInt64 StartPos;
UInt32 Attributes;
UInt32 FileCRC;
CRecordVector<UInt64> Values;
CRecordVector<bool> Defined;
void Clear()
{
Values.Clear();
Defined.Clear();
}
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;
bool HasStream; // Test it !!! it means that there is
// stream in some folder. It can be empty stream
bool IsDirectory;
bool IsAnti;
bool IsFileCRCDefined;
bool AreAttributesDefined;
bool IsCreationTimeDefined;
bool IsLastWriteTimeDefined;
bool IsLastAccessTimeDefined;
bool IsStartPosDefined;
bool IsDir;
bool CrcDefined;
bool AttribDefined;
/*
const bool HasStream() const {
return !IsDirectory && !IsAnti && UnPackSize != 0; }
*/
CFileItem():
HasStream(true),
IsDirectory(false),
IsAnti(false),
IsFileCRCDefined(false),
AreAttributesDefined(false),
IsCreationTimeDefined(false),
IsLastWriteTimeDefined(false),
IsLastAccessTimeDefined(false),
IsStartPosDefined(false)
IsDir(false),
CrcDefined(false),
AttribDefined(false)
{}
void SetAttributes(UInt32 attributes)
void SetAttrib(UInt32 attrib)
{
AreAttributesDefined = true;
Attributes = attributes;
AttribDefined = true;
Attrib = attrib;
}
void SetCreationTime(const CArchiveFileTime &creationTime)
};
struct CFileItem2
{
IsCreationTimeDefined = true;
CreationTime = creationTime;
}
void SetLastWriteTime(const CArchiveFileTime &lastWriteTime)
{
IsLastWriteTimeDefined = true;
LastWriteTime = lastWriteTime;
}
void SetLastAccessTime(const CArchiveFileTime &lastAccessTime)
{
IsLastAccessTimeDefined = true;
LastAccessTime = lastAccessTime;
}
UInt64 CTime;
UInt64 ATime;
UInt64 MTime;
UInt64 StartPos;
bool CTimeDefined;
bool ATimeDefined;
bool MTimeDefined;
bool StartPosDefined;
bool IsAnti;
};
struct CArchiveDatabase
@@ -150,33 +170,83 @@ struct CArchiveDatabase
CRecordVector<bool> PackCRCsDefined;
CRecordVector<UInt32> PackCRCs;
CObjectVector<CFolder> Folders;
CRecordVector<CNum> NumUnPackStreamsVector;
CRecordVector<CNum> NumUnpackStreamsVector;
CObjectVector<CFileItem> Files;
CUInt64DefVector CTime;
CUInt64DefVector ATime;
CUInt64DefVector MTime;
CUInt64DefVector StartPos;
CRecordVector<bool> IsAnti;
void Clear()
{
PackSizes.Clear();
PackCRCsDefined.Clear();
PackCRCs.Clear();
Folders.Clear();
NumUnPackStreamsVector.Clear();
NumUnpackStreamsVector.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
{
return (PackSizes.IsEmpty() &&
PackCRCsDefined.IsEmpty() &&
PackCRCs.IsEmpty() &&
Folders.IsEmpty() &&
NumUnPackStreamsVector.IsEmpty() &&
NumUnpackStreamsVector.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
{
for (int i = 0; i < NumUnPackStreamsVector.Size(); i++)
if (NumUnPackStreamsVector[i] > 1)
for (int i = 0; i < NumUnpackStreamsVector.Size(); i++)
if (NumUnpackStreamsVector[i] > 1)
return true;
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 "../../Common/OutBuffer.h"
#include "../../../Common/DynamicBuffer.h"
namespace NArchive {
namespace N7z {
@@ -23,56 +22,39 @@ public:
CWriteBufferLoc(): _size(0), _pos(0) {}
void Init(Byte *data, size_t size)
{
_pos = 0;
_data = data;
_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;
}
void Write(const void *data, size_t size)
void WriteBytes(const void *data, size_t size)
{
if (_pos + size > _buffer.GetCapacity())
_buffer.EnsureCapacity(_pos + size);
memmove(((Byte *)_buffer) +_pos, data, size);
if (size > _size - _pos)
throw 1;
memcpy(_data + _pos, data, size);
_pos += size;
}
operator Byte *() { return (Byte *)_buffer; };
operator const Byte *() const { return (const Byte *)_buffer; };
size_t GetSize() const { return _pos; }
void WriteByte(Byte b)
{
if (_size == _pos)
throw 1;
_data[_pos++] = b;
}
size_t GetPos() const { return _pos; }
};
struct CHeaderOptions
{
// bool UseAdditionalHeaderStreams;
bool CompressMainHeader;
bool WriteModified;
bool WriteCreated;
bool WriteAccessed;
bool WriteCTime;
bool WriteATime;
bool WriteMTime;
CHeaderOptions():
// UseAdditionalHeaderStreams(false),
CompressMainHeader(true),
WriteModified(true),
WriteCreated(false),
WriteAccessed(false) {}
WriteCTime(false),
WriteATime(false),
WriteMTime(true)
{}
};
class COutArchive
@@ -80,56 +62,41 @@ class COutArchive
UInt64 _prefixHeaderPos;
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);
HRESULT WriteBytes(const CByteBuffer &data);
HRESULT WriteByte(Byte b);
HRESULT WriteUInt32(UInt32 value);
HRESULT WriteNumber(UInt64 value);
HRESULT WriteID(UInt64 value) { return WriteNumber(value); }
UInt64 GetPos() const;
void WriteBytes(const void *data, size_t size);
void WriteBytes(const CByteBuffer &data) { WriteBytes(data, data.GetCapacity()); }
void WriteByte(Byte b);
void WriteUInt32(UInt32 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 WriteBoolVector(const CBoolVector &boolVector);
HRESULT WriteHashDigests(
void WriteBoolVector(const CBoolVector &boolVector);
void WriteHashDigests(
const CRecordVector<bool> &digestsDefined,
const CRecordVector<UInt32> &hashDigests);
HRESULT WritePackInfo(
void WritePackInfo(
UInt64 dataOffset,
const CRecordVector<UInt64> &packSizes,
const CRecordVector<bool> &packCRCsDefined,
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 CRecordVector<CNum> &numUnPackStreamsInFolders,
const CRecordVector<UInt64> &unPackSizes,
const CRecordVector<CNum> &numUnpackStreamsInFolders,
const CRecordVector<UInt64> &unpackSizes,
const CRecordVector<bool> &digestsDefined,
const CRecordVector<UInt32> &hashDigests);
/*
HRESULT WriteStreamsInfo(
UInt64 dataOffset,
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);
void SkipAlign(unsigned pos, unsigned alignSize);
void WriteAlignedBoolHeader(const CBoolVector &v, int numDefined, Byte type, unsigned itemSize);
void WriteUInt64DefVector(const CUInt64DefVector &v, Byte type);
HRESULT EncodeStream(
DECL_EXTERNAL_CODECS_LOC_VARS
@@ -139,21 +106,17 @@ class COutArchive
DECL_EXTERNAL_CODECS_LOC_VARS
CEncoder &encoder, const CByteBuffer &data,
CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders);
HRESULT WriteHeader(
const CArchiveDatabase &database,
void WriteHeader(
const CArchiveDatabase &db,
const CHeaderOptions &headerOptions,
UInt64 &headerOffset);
bool _mainMode;
bool _dynamicMode;
bool _countMode;
bool _writeToStream;
size_t _countSize;
UInt32 _crc;
COutBuffer _outByte;
CWriteBufferLoc _outByte2;
CWriteDynamicBuffer _dynamicBuffer;
UInt32 _crc;
#ifdef _7Z_VOL
bool _endMarker;
@@ -177,7 +140,7 @@ public:
HRESULT SkeepPrefixArchiveHeader();
HRESULT WriteDatabase(
DECL_EXTERNAL_CODECS_LOC_VARS
const CArchiveDatabase &database,
const CArchiveDatabase &db,
const CCompressionMethodMode *options,
const CHeaderOptions &headerOptions);

View File

@@ -21,7 +21,7 @@ CPropMap kPropMap[] =
{
{ NID::kName, NULL, kpidPath, VT_BSTR},
{ NID::kSize, NULL, kpidSize, VT_UI8},
{ NID::kPackInfo, NULL, kpidPackedSize, VT_UI8},
{ NID::kPackInfo, NULL, kpidPackSize, VT_UI8},
#ifdef _MULTI_PACK
{ 100, L"Pack0", kpidPackedSize0, VT_UI8},
@@ -31,10 +31,10 @@ CPropMap kPropMap[] =
{ 104, L"Pack4", kpidPackedSize4, VT_UI8},
#endif
{ NID::kCreationTime, NULL, kpidCreationTime, VT_FILETIME},
{ NID::kLastWriteTime, NULL, kpidLastWriteTime, VT_FILETIME},
{ NID::kLastAccessTime, NULL, kpidLastAccessTime, VT_FILETIME},
{ NID::kWinAttributes, NULL, kpidAttributes, VT_UI4},
{ NID::kCTime, NULL, kpidCTime, VT_FILETIME},
{ NID::kMTime, NULL, kpidMTime, VT_FILETIME},
{ NID::kATime, NULL, kpidATime, VT_FILETIME},
{ NID::kWinAttributes, NULL, kpidAttrib, VT_UI4},
{ NID::kStartPos, NULL, kpidPosition, VT_UI4},
{ NID::kCRC, NULL, kpidCRC, VT_UI4},
@@ -99,10 +99,10 @@ void CHandler::FillPopIDs()
if(_volumes.Size() < 1)
return;
const CVolume &volume = _volumes.Front();
const CArchiveDatabaseEx &_database = volume.Database;
const CArchiveDatabaseEx &_db = volume.Database;
#endif
CRecordVector<UInt64> fileInfoPopIDs = _database.ArchiveInfo.FileInfoPopIDs;
CRecordVector<UInt64> fileInfoPopIDs = _db.ArchiveInfo.FileInfoPopIDs;
RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream);
RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile);
@@ -111,9 +111,9 @@ void CHandler::FillPopIDs()
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kAnti);
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kSize);
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kPackInfo);
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCreationTime);
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kLastWriteTime);
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kLastAccessTime);
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCTime);
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kMTime);
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kATime);
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kWinAttributes);
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCRC);
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kComment);
@@ -133,7 +133,7 @@ void CHandler::FillPopIDs()
#endif
#ifndef _SFX
InsertToHead(_fileInfoPopIDs, NID::kLastWriteTime);
InsertToHead(_fileInfoPopIDs, NID::kMTime);
InsertToHead(_fileInfoPopIDs, NID::kPackInfo);
InsertToHead(_fileInfoPopIDs, NID::kSize);
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[i2]));
RINOZ(MyCompare(
db.NumUnPackStreamsVector[i1],
db.NumUnPackStreamsVector[i2]));
if (db.NumUnPackStreamsVector[i1] == 0)
db.NumUnpackStreamsVector[i1],
db.NumUnpackStreamsVector[i2]));
if (db.NumUnpackStreamsVector[i1] == 0)
return 0;
return CompareFiles(
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 CUpdateItem &u1 = updateItems[*p1];
const CUpdateItem &u2 = updateItems[*p2];
if (u1.IsDirectory != u2.IsDirectory)
return (u1.IsDirectory) ? 1 : -1;
if (u1.IsDirectory)
if (u1.IsDir != u2.IsDir)
return (u1.IsDir) ? 1 : -1;
if (u1.IsDir)
{
if (u1.IsAnti != u2.IsAnti)
return (u1.IsAnti ? 1 : -1);
@@ -212,29 +212,29 @@ int GetExtIndex(const char *ext)
struct CRefItem
{
UInt32 Index;
const CUpdateItem *UpdateItem;
UInt32 Index;
UInt32 ExtensionPos;
UInt32 NamePos;
int ExtensionIndex;
CRefItem(UInt32 index, const CUpdateItem &updateItem, bool sortByType):
CRefItem(UInt32 index, const CUpdateItem &ui, bool sortByType):
UpdateItem(&ui),
Index(index),
UpdateItem(&updateItem),
ExtensionPos(0),
NamePos(0),
ExtensionIndex(0)
{
if (sortByType)
{
int slashPos = GetReverseSlashPos(updateItem.Name);
int slashPos = GetReverseSlashPos(ui.Name);
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))
ExtensionPos = updateItem.Name.Length();
ExtensionPos = ui.Name.Length();
else
{
ExtensionPos = dotPos + 1;
UString us = updateItem.Name.Mid(ExtensionPos);
UString us = ui.Name.Mid(ExtensionPos);
if (!us.IsEmpty())
{
us.MakeLower();
@@ -264,9 +264,9 @@ static int CompareUpdateItems(const CRefItem *p1, const CRefItem *p2, void *para
const CUpdateItem &u1 = *a1.UpdateItem;
const CUpdateItem &u2 = *a2.UpdateItem;
int n;
if (u1.IsDirectory != u2.IsDirectory)
return (u1.IsDirectory) ? 1 : -1;
if (u1.IsDirectory)
if (u1.IsDir != u2.IsDir)
return (u1.IsDir) ? 1 : -1;
if (u1.IsDir)
{
if (u1.IsAnti != u2.IsAnti)
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(MyStringCompareNoCase(u1.Name + a1.ExtensionPos, u2.Name + a2.ExtensionPos));
RINOZ(MyStringCompareNoCase(u1.Name + a1.NamePos, u2.Name + a2.NamePos));
if (u1.IsLastWriteTimeDefined && u2.IsLastWriteTimeDefined)
RINOZ(CompareFileTime(&u1.LastWriteTime, &u2.LastWriteTime));
if (!u1.MTimeDefined && u2.MTimeDefined) return 1;
if (u1.MTimeDefined && !u2.MTimeDefined) return -1;
if (u1.MTimeDefined && u2.MTimeDefined) RINOZ(MyCompare(u1.MTime, u2.MTime));
RINOZ(MyCompare(u1.Size, u2.Size))
}
return MyStringCompareNoCase(u1.Name, u2.Name);
@@ -411,14 +412,14 @@ static void SplitFilesToGroups(
int i;
for (i = 0; i < updateItems.Size(); i++)
{
const CUpdateItem &updateItem = updateItems[i];
if (!updateItem.NewData)
const CUpdateItem &ui = updateItems[i];
if (!ui.NewData)
continue;
if (!updateItem.HasStream())
if (!ui.HasStream())
continue;
if (useFilters)
{
const UString name = updateItem.Name;
const UString name = ui.Name;
int dotPos = name.ReverseFind(L'.');
if (dotPos >= 0)
{
@@ -442,31 +443,31 @@ static void SplitFilesToGroups(
i++;
}
static void FromUpdateItemToFileItem(const CUpdateItem &updateItem,
CFileItem &file)
static void FromUpdateItemToFileItem(const CUpdateItem &ui,
CFileItem &file, CFileItem2 &file2)
{
file.Name = NItemName::MakeLegalName(updateItem.Name);
if (updateItem.AttributesAreDefined)
file.SetAttributes(updateItem.Attributes);
file.Name = NItemName::MakeLegalName(ui.Name);
if (ui.AttribDefined)
file.SetAttrib(ui.Attrib);
if (updateItem.IsCreationTimeDefined)
file.SetCreationTime(updateItem.CreationTime);
if (updateItem.IsLastWriteTimeDefined)
file.SetLastWriteTime(updateItem.LastWriteTime);
if (updateItem.IsLastAccessTimeDefined)
file.SetLastAccessTime(updateItem.LastAccessTime);
file2.CTime = ui.CTime; file2.CTimeDefined = ui.CTimeDefined;
file2.ATime = ui.ATime; file2.ATimeDefined = ui.ATimeDefined;
file2.MTime = ui.MTime; file2.MTimeDefined = ui.MTimeDefined;
file2.IsAnti = ui.IsAnti;
file2.StartPosDefined = false;
file.UnPackSize = updateItem.Size;
file.IsDirectory = updateItem.IsDirectory;
file.IsAnti = updateItem.IsAnti;
file.HasStream = updateItem.HasStream();
file.Size = ui.Size;
file.IsDir = ui.IsDir;
file.HasStream = ui.HasStream();
}
static HRESULT Update2(
DECL_EXTERNAL_CODECS_LOC_VARS
IInStream *inStream,
const CArchiveDatabaseEx *database,
const CArchiveDatabaseEx *db,
const CObjectVector<CUpdateItem> &updateItems,
COutArchive &archive,
CArchiveDatabase &newDatabase,
ISequentialOutStream *seqOutStream,
IArchiveUpdateCallback *updateCallback,
const CUpdateOptions &options)
@@ -481,17 +482,17 @@ static HRESULT Update2(
return E_NOTIMPL;
*/
UInt64 startBlockSize = database != 0 ? database->ArchiveInfo.StartPosition: 0;
UInt64 startBlockSize = db != 0 ? db->ArchiveInfo.StartPosition: 0;
if (startBlockSize > 0 && !options.RemoveSfxBlock)
{
RINOK(WriteRange(inStream, seqOutStream, 0, startBlockSize, NULL));
}
CRecordVector<int> fileIndexToUpdateIndexMap;
if (database != 0)
if (db != 0)
{
fileIndexToUpdateIndexMap.Reserve(database->Files.Size());
for (int i = 0; i < database->Files.Size(); i++)
fileIndexToUpdateIndexMap.Reserve(db->Files.Size());
for (int i = 0; i < db->Files.Size(); i++)
fileIndexToUpdateIndexMap.Add(-1);
}
int i;
@@ -503,17 +504,17 @@ static HRESULT Update2(
}
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 numCopyItems = 0;
CNum numUnPackStreams = database->NumUnPackStreamsVector[i];
for (CNum fileIndex = database->FolderStartFileIndex[i];
indexInFolder < numUnPackStreams; fileIndex++)
CNum numUnpackStreams = db->NumUnpackStreamsVector[i];
for (CNum fileIndex = db->FolderStartFileIndex[i];
indexInFolder < numUnpackStreams; fileIndex++)
{
if (database->Files[fileIndex].HasStream)
if (db->Files[fileIndex].HasStream)
{
indexInFolder++;
int updateIndex = fileIndexToUpdateIndexMap[fileIndex];
@@ -522,38 +523,35 @@ static HRESULT Update2(
numCopyItems++;
}
}
if (numCopyItems != numUnPackStreams && numCopyItems != 0)
if (numCopyItems != numUnpackStreams && numCopyItems != 0)
return E_NOTIMPL; // It needs repacking !!!
if (numCopyItems > 0)
folderRefs.Add(i);
}
folderRefs.Sort(CompareFolderRefs, (void *)database);
folderRefs.Sort(CompareFolderRefs, (void *)db);
}
CArchiveDatabase newDatabase;
////////////////////////////
COutArchive archive;
RINOK(archive.Create(seqOutStream, false));
RINOK(archive.SkeepPrefixArchiveHeader());
UInt64 complexity = 0;
for(i = 0; i < folderRefs.Size(); i++)
complexity += database->GetFolderFullPackSize(folderRefs[i]);
complexity += db->GetFolderFullPackSize(folderRefs[i]);
UInt64 inSizeForReduce = 0;
for(i = 0; i < updateItems.Size(); i++)
{
const CUpdateItem &updateItem = updateItems[i];
if (updateItem.NewData)
const CUpdateItem &ui = updateItems[i];
if (ui.NewData)
{
complexity += updateItem.Size;
complexity += ui.Size;
if (numSolidFiles == 1)
{
if (updateItem.Size > inSizeForReduce)
inSizeForReduce = updateItem.Size;
if (ui.Size > inSizeForReduce)
inSizeForReduce = ui.Size;
}
else
inSizeForReduce += updateItem.Size;
inSizeForReduce += ui.Size;
}
}
RINOK(updateCallback->SetTotal(complexity));
@@ -573,52 +571,57 @@ static HRESULT Update2(
int folderIndex = folderRefs[i];
lps->ProgressOffset = complexity;
UInt64 packSize = database->GetFolderFullPackSize(folderIndex);
UInt64 packSize = db->GetFolderFullPackSize(folderIndex);
RINOK(WriteRange(inStream, archive.SeqStream,
database->GetFolderStreamPos(folderIndex, 0), packSize, progress));
db->GetFolderStreamPos(folderIndex, 0), packSize, progress));
complexity += packSize;
const CFolder &folder = database->Folders[folderIndex];
CNum startIndex = database->FolderStartPackStreamIndex[folderIndex];
const CFolder &folder = db->Folders[folderIndex];
CNum startIndex = db->FolderStartPackStreamIndex[folderIndex];
for (int j = 0; j < folder.PackStreams.Size(); j++)
{
newDatabase.PackSizes.Add(database->PackSizes[startIndex + j]);
// newDatabase.PackCRCsDefined.Add(database.PackCRCsDefined[startIndex + j]);
// newDatabase.PackCRCs.Add(database.PackCRCs[startIndex + j]);
newDatabase.PackSizes.Add(db->PackSizes[startIndex + j]);
// newDatabase.PackCRCsDefined.Add(db.PackCRCsDefined[startIndex + j]);
// newDatabase.PackCRCs.Add(db.PackCRCs[startIndex + j]);
}
newDatabase.Folders.Add(folder);
CNum numUnPackStreams = database->NumUnPackStreamsVector[folderIndex];
newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams);
CNum numUnpackStreams = db->NumUnpackStreamsVector[folderIndex];
newDatabase.NumUnpackStreamsVector.Add(numUnpackStreams);
CNum indexInFolder = 0;
for (CNum fi = database->FolderStartFileIndex[folderIndex];
indexInFolder < numUnPackStreams; fi++)
for (CNum fi = db->FolderStartFileIndex[folderIndex];
indexInFolder < numUnpackStreams; fi++)
{
CFileItem file = database->Files[fi];
CFileItem file;
CFileItem2 file2;
db->GetFile(fi, file, file2);
if (file.HasStream)
{
indexInFolder++;
int updateIndex = fileIndexToUpdateIndexMap[fi];
if (updateIndex >= 0)
{
const CUpdateItem &updateItem = updateItems[updateIndex];
if (updateItem.NewProperties)
const CUpdateItem &ui = updateItems[updateIndex];
if (ui.NewProperties)
{
CFileItem file2;
FromUpdateItemToFileItem(updateItem, file2);
file2.UnPackSize = file.UnPackSize;
file2.FileCRC = file.FileCRC;
file2.IsFileCRCDefined = file.IsFileCRCDefined;
file2.HasStream = file.HasStream;
file = file2;
CFileItem uf;
FromUpdateItemToFileItem(ui, uf, file2);
uf.Size = file.Size;
uf.Crc = file.Crc;
uf.CrcDefined = file.CrcDefined;
uf.HasStream = file.HasStream;
file = uf;
}
}
newDatabase.Files.Add(file);
newDatabase.AddFile(file, file2);
}
}
}
folderRefs.ClearAndFree();
fileIndexToUpdateIndexMap.ClearAndFree();
/////////////////////////////////////////
// Compress New Files
@@ -651,13 +654,13 @@ static HRESULT Update2(
UInt32 index = refItems[i].Index;
indices.Add(index);
/*
const CUpdateItem &updateItem = updateItems[index];
const CUpdateItem &ui = updateItems[index];
CFileItem file;
if (updateItem.NewProperties)
FromUpdateItemToFileItem(updateItem, file);
if (ui.NewProperties)
FromUpdateItemToFileItem(ui, file);
else
file = database.Files[updateItem.IndexInArchive];
if (file.IsAnti || file.IsDirectory)
file = db.Files[ui.IndexInArchive];
if (file.IsAnti || file.IsDir)
return E_FAIL;
newDatabase.Files.Add(file);
*/
@@ -673,13 +676,13 @@ static HRESULT Update2(
for (numSubFiles = 0; i + numSubFiles < numFiles &&
numSubFiles < numSolidFiles; numSubFiles++)
{
const CUpdateItem &updateItem = updateItems[indices[i + numSubFiles]];
totalSize += updateItem.Size;
const CUpdateItem &ui = updateItems[indices[i + numSubFiles]];
totalSize += ui.Size;
if (totalSize > options.NumSolidBytes)
break;
if (options.SolidExtension)
{
UString ext = updateItem.GetExtension();
UString ext = ui.GetExtension();
if (numSubFiles == 0)
prevExtension = ext;
else
@@ -705,23 +708,24 @@ static HRESULT Update2(
for (; startPackIndex < newDatabase.PackSizes.Size(); startPackIndex++)
lps->OutSize += newDatabase.PackSizes[startPackIndex];
lps->InSize += folderItem.GetUnPackSize();
lps->InSize += folderItem.GetUnpackSize();
// for()
// newDatabase.PackCRCsDefined.Add(false);
// newDatabase.PackCRCs.Add(0);
newDatabase.Folders.Add(folderItem);
CNum numUnPackStreams = 0;
CNum numUnpackStreams = 0;
for (int subIndex = 0; subIndex < numSubFiles; subIndex++)
{
const CUpdateItem &updateItem = updateItems[indices[i + subIndex]];
const CUpdateItem &ui = updateItems[indices[i + subIndex]];
CFileItem file;
if (updateItem.NewProperties)
FromUpdateItemToFileItem(updateItem, file);
CFileItem2 file2;
if (ui.NewProperties)
FromUpdateItemToFileItem(ui, file, file2);
else
file = database->Files[updateItem.IndexInArchive];
if (file.IsAnti || file.IsDirectory)
db->GetFile(ui.IndexInArchive, file, file2);
if (file2.IsAnti || file.IsDir)
return E_FAIL;
/*
@@ -734,28 +738,30 @@ static HRESULT Update2(
// file.Name += L".locked";
}
file.FileCRC = inStreamSpec->CRCs[subIndex];
file.UnPackSize = inStreamSpec->Sizes[subIndex];
if (file.UnPackSize != 0)
file.Crc = inStreamSpec->CRCs[subIndex];
file.Size = inStreamSpec->Sizes[subIndex];
if (file.Size != 0)
{
file.IsFileCRCDefined = true;
file.CrcDefined = true;
file.HasStream = true;
numUnPackStreams++;
numUnpackStreams++;
}
else
{
file.IsFileCRCDefined = false;
file.CrcDefined = 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.
newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams);
newDatabase.NumUnpackStreamsVector.Add(numUnpackStreams);
i += numSubFiles;
}
}
groups.ClearAndFree();
{
/////////////////////////////////////////
// Write Empty Files & Folders
@@ -763,267 +769,51 @@ static HRESULT Update2(
CRecordVector<int> emptyRefs;
for(i = 0; i < updateItems.Size(); i++)
{
const CUpdateItem &updateItem = updateItems[i];
if (updateItem.NewData)
const CUpdateItem &ui = updateItems[i];
if (ui.NewData)
{
if (updateItem.HasStream())
if (ui.HasStream())
continue;
}
else
if (updateItem.IndexInArchive != -1)
if (database->Files[updateItem.IndexInArchive].HasStream)
if (ui.IndexInArchive != -1)
if (db->Files[ui.IndexInArchive].HasStream)
continue;
emptyRefs.Add(i);
}
emptyRefs.Sort(CompareEmptyItems, (void *)&updateItems);
for (i = 0; i < emptyRefs.Size(); i++)
{
const CUpdateItem &updateItem = updateItems[emptyRefs[i]];
const CUpdateItem &ui = updateItems[emptyRefs[i]];
CFileItem file;
if (updateItem.NewProperties)
FromUpdateItemToFileItem(updateItem, file);
CFileItem2 file2;
if (ui.NewProperties)
FromUpdateItemToFileItem(ui, file, file2);
else
file = database->Files[updateItem.IndexInArchive];
newDatabase.Files.Add(file);
db->GetFile(ui.IndexInArchive, file, file2);
newDatabase.AddFile(file, file2);
}
}
/*
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;
}
newDatabase.ReserveDown();
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(
DECL_EXTERNAL_CODECS_LOC_VARS
IInStream *inStream,
const CArchiveDatabaseEx *database,
const CArchiveDatabaseEx *db,
const CObjectVector<CUpdateItem> &updateItems,
COutArchive &archive,
CArchiveDatabase &newDatabase,
ISequentialOutStream *seqOutStream,
IArchiveUpdateCallback *updateCallback,
const CUpdateOptions &options)
{
#ifdef _7Z_VOL
if (seqOutStream)
#endif
return Update2(
EXTERNAL_CODECS_LOC_VARS
inStream, database, updateItems,
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
inStream, db, updateItems,
archive, newDatabase, seqOutStream, updateCallback, options);
}
}}

View File

@@ -14,38 +14,40 @@ namespace N7z {
struct CUpdateItem
{
bool NewData;
bool NewProperties;
int IndexInArchive;
int IndexInClient;
UInt32 Attributes;
FILETIME CreationTime;
FILETIME LastWriteTime;
FILETIME LastAccessTime;
UInt64 CTime;
UInt64 ATime;
UInt64 MTime;
UInt64 Size;
UString Name;
UInt32 Attrib;
bool NewData;
bool NewProperties;
bool IsAnti;
bool IsDirectory;
bool IsDir;
bool IsCreationTimeDefined;
bool IsLastWriteTimeDefined;
bool IsLastAccessTimeDefined;
bool AttributesAreDefined;
bool AttribDefined;
bool CTimeDefined;
bool ATimeDefined;
bool MTimeDefined;
bool HasStream() const { return !IsDir && !IsAnti && Size != 0; }
bool HasStream() const
{ return !IsDirectory && !IsAnti && Size != 0; }
CUpdateItem():
IsAnti(false),
AttributesAreDefined(false),
IsCreationTimeDefined(false),
IsLastWriteTimeDefined(false),
IsLastAccessTimeDefined(false)
IsDir(false),
AttribDefined(false),
CTimeDefined(false),
ATimeDefined(false),
MTimeDefined(false)
{}
void SetDirectoryStatusFromAttributes()
{ IsDirectory = ((Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0); };
void SetDirStatusFromAttrib() { IsDir = ((Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0); };
int GetExtensionPos() const;
UString GetExtension() const;
@@ -70,8 +72,10 @@ struct CUpdateOptions
HRESULT Update(
DECL_EXTERNAL_CODECS_LOC_VARS
IInStream *inStream,
const CArchiveDatabaseEx *database,
const CArchiveDatabaseEx *db,
const CObjectVector<CUpdateItem> &updateItems,
COutArchive &archive,
CArchiveDatabase &newDatabase,
ISequentialOutStream *seqOutStream,
IArchiveUpdateCallback *updateCallback,
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[] =
{
{ NULL, kpidPackedSize, VT_UI8}
{ NULL, kpidPackSize, VT_UI8}
};
IMP_IInArchive_Props
@@ -40,7 +40,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIA
NWindows::NCOM::CPropVariant prop;
switch(propID)
{
case kpidPackedSize: prop = _item.PackSize; break;
case kpidPackSize: prop = _item.PackSize; break;
}
prop.Detach(value);
return S_OK;

View File

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

View File

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

View File

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

View File

@@ -2,12 +2,9 @@
#include "StdAfx.h"
#include "Common/StringConvert.h"
#include "Common/MyCom.h"
#include "CabIn.h"
#include "Windows/Defs.h"
#include "../../Common/StreamUtils.h"
#include "../Common/FindSignature.h"
namespace NArchive {
namespace NCab {
@@ -94,39 +91,21 @@ void CInArchive::Skeep(size_t size)
ReadByte();
}
HRESULT CInArchive::Open2(IInStream *inStream,
HRESULT CInArchive::Open2(IInStream *stream,
const UInt64 *searchHeaderSizeLimit,
CDatabase &database)
{
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))
return E_OUTOFMEMORY;
inBuffer.SetStream(inStream);
inBuffer.SetStream(stream);
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;
@@ -141,7 +120,9 @@ HRESULT CInArchive::Open2(IInStream *inStream,
archiveInfo.VersionMajor = ReadByte(); // cabinet file format version, major
archiveInfo.NumFolders = ReadUInt16(); // number of CFFOLDER 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.CabinetNumber = ReadUInt16(); // number of this cabinet file in a set
@@ -175,9 +156,9 @@ HRESULT CInArchive::Open2(IInStream *inStream,
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();
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 CItem &item1 = db1.Items[p1->ItemIndex];
const CItem &item2 = db2.Items[p2->ItemIndex];;
bool isDir1 = item1.IsDirectory();
bool isDir2 = item2.IsDirectory();
bool isDir1 = item1.IsDir();
bool isDir2 = item2.IsDir();
if (isDir1 && !isDir2)
return -1;
if (isDir2 && !isDir1)
@@ -322,7 +303,7 @@ bool CMvDatabaseEx::Check()
if (fIndex >= FolderStartFileIndex.Size())
return false;
const CItem &item = Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
if (item.IsDirectory())
if (item.IsDir())
continue;
int folderIndex = GetFolderIndex(&mvItem);
if (folderIndex != prevFolder)

View File

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

View File

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

View File

@@ -42,7 +42,6 @@ enum
STATPROPSTG kProps[] =
{
{ NULL, kpidPath, VT_BSTR},
// { NULL, kpidIsFolder, VT_BOOL},
{ NULL, kpidSize, VT_UI8},
{ NULL, kpidMethod, VT_BSTR},
{ NULL, kpidBlock, VT_UI4}
@@ -132,15 +131,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
}
break;
}
case kpidIsFolder:
prop = item.IsDirectory();
break;
case kpidSize:
prop = item.Size;
break;
case kpidIsDir: prop = item.IsDir(); break;
case kpidSize: prop = item.Size; break;
case kpidMethod:
{
if (!item.IsDirectory())
if (!item.IsDir())
if (item.Section == 0)
prop = L"Copy";
else if (item.Section < m_Database.Sections.Size())
@@ -156,12 +151,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
#ifdef _CHM_DETAILS
case kpidSection:
prop = (UInt32)item.Section;
break;
case kpidOffset:
prop = (UInt32)item.Offset;
break;
case kpidSection: prop = (UInt32)item.Section; break;
case kpidOffset: prop = (UInt32)item.Offset; break;
#endif
}
@@ -170,41 +161,39 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
COM_TRY_END
}
class CPropgressImp: public CProgressVirt
class CProgressImp: public CProgressVirt
{
CMyComPtr<IArchiveOpenCallback> m_OpenArchiveCallback;
CMyComPtr<IArchiveOpenCallback> _callback;
public:
STDMETHOD(SetTotal)(const UInt64 *numFiles);
STDMETHOD(SetCompleted)(const UInt64 *numFiles);
void Init(IArchiveOpenCallback *openArchiveCallback)
{ m_OpenArchiveCallback = openArchiveCallback; }
CProgressImp(IArchiveOpenCallback *callback): _callback(callback) {};
};
STDMETHODIMP CPropgressImp::SetTotal(const UInt64 *numFiles)
STDMETHODIMP CProgressImp::SetTotal(const UInt64 *numFiles)
{
if (m_OpenArchiveCallback)
return m_OpenArchiveCallback->SetCompleted(numFiles, NULL);
if (_callback)
return _callback->SetCompleted(numFiles, NULL);
return S_OK;
}
STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles)
STDMETHODIMP CProgressImp::SetCompleted(const UInt64 *numFiles)
{
if (m_OpenArchiveCallback)
return m_OpenArchiveCallback->SetCompleted(numFiles, NULL);
if (_callback)
return _callback->SetCompleted(numFiles, NULL);
return S_OK;
}
STDMETHODIMP CHandler::Open(IInStream *inStream,
const UInt64 *maxCheckStartPosition,
IArchiveOpenCallback *openArchiveCallback)
IArchiveOpenCallback * /* openArchiveCallback */)
{
COM_TRY_BEGIN
m_Stream.Release();
try
{
CInArchive archive;
CPropgressImp progressImp;
progressImp.Init(openArchiveCallback);
// CProgressImp progressImp(openArchiveCallback);
RINOK(archive.Open(inStream, maxCheckStartPosition, m_Database));
/*
if (m_Database.LowLevel)
@@ -516,7 +505,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
int entryIndex = m_Database.Indices[index];
const CItem &item = m_Database.Items[entryIndex];
UInt64 sectionIndex = item.Section;
if (item.IsDirectory() || item.Size == 0)
if (item.IsDir() || item.Size == 0)
continue;
if (sectionIndex == 0)
{
@@ -557,7 +546,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
Int32 askMode= testMode ?
NArchive::NExtract::NAskMode::kTest :
NArchive::NExtract::NAskMode::kExtract;
if (item.IsDirectory())
if (item.IsDir())
{
CMyComPtr<ISequentialOutStream> realOutStream;
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 CItem &item1 = items[*p1];
const CItem &item2 = items[*p2];
bool isDir1 = item1.IsDirectory();
bool isDir2 = item2.IsDirectory();
bool isDir1 = item1.IsDir();
bool isDir2 = item2.IsDir();
if (isDir1 && !isDir2)
return -1;
if (isDir2)
@@ -663,7 +663,7 @@ bool CFilesDatabase::Check()
for(int i = 0; i < Indices.Size(); i++)
{
const CItem &item = Items[Indices[i]];
if (item.Section == 0 || item.IsDirectory())
if (item.Section == 0 || item.IsDir())
continue;
if (item.Section != prevSection)
{
@@ -864,6 +864,11 @@ HRESULT CInArchive::Open2(IInStream *inStream,
const int kSignatureSize = 8;
UInt64 hxsSignature = NHeader::GetHxsSignature();
UInt64 chmSignature = ((UInt64)chmVersion << 32)| NHeader::kItsfSignature;
UInt64 limit = 1 << 18;
if (searchHeaderSizeLimit)
if (limit > *searchHeaderSizeLimit)
limit = *searchHeaderSizeLimit;
for (;;)
{
Byte b;
@@ -880,8 +885,7 @@ HRESULT CInArchive::Open2(IInStream *inStream,
database.Help2Format = true;
break;
}
if (searchHeaderSizeLimit != NULL)
if (_inBuffer.GetProcessedSize() > (*searchHeaderSizeLimit))
if (_inBuffer.GetProcessedSize() > limit)
return S_FALSE;
}
}

View File

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

View File

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

View File

@@ -13,12 +13,12 @@ namespace NCom {
STATPROPSTG kProps[] =
{
{ NULL, kpidPath, VT_BSTR},
{ NULL, kpidIsFolder, VT_BOOL},
{ NULL, kpidIsDir, VT_BOOL},
{ NULL, kpidSize, VT_UI8},
// { NULL, kpidAttributes, VT_UI4},
{ NULL, kpidPackedSize, VT_UI8},
{ NULL, kpidCreationTime, VT_FILETIME},
{ NULL, kpidLastWriteTime, VT_FILETIME}
{ NULL, kpidPackSize, VT_UI8},
{ NULL, kpidCTime, VT_FILETIME},
{ NULL, kpidMTime, VT_FILETIME}
};
@@ -58,21 +58,15 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
prop = name;
break;
}
case kpidIsFolder:
prop = item.IsDir();
break;
case kpidCreationTime:
prop = item.CreationTime;
break;
case kpidLastWriteTime:
prop = item.LastWriteTime;
break;
case kpidIsDir: prop = item.IsDir(); break;
case kpidCTime: prop = item.CTime; break;
case kpidMTime: prop = item.MTime; break;
/*
case kpidAttributes:
prop = item.Falgs;
break;
*/
case kpidPackedSize:
case kpidPackSize:
if (!item.IsDir())
{
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.SonDid = GetUi32(p + 76);
// item.Flags = GetUi32(p + 96);
GetFileTimeFromMem(p + 100, &item.CreationTime);
GetFileTimeFromMem(p + 108, &item.LastWriteTime);
GetFileTimeFromMem(p + 100, &item.CTime);
GetFileTimeFromMem(p + 108, &item.MTime);
item.Sid = GetUi32(p + 116);
item.Size = GetUi32(p + 120);
if (mode64bit)

View File

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

View File

@@ -14,6 +14,7 @@ class CDummyOutStream:
UInt64 _size;
public:
void SetStream(ISequentialOutStream *outStream) { _stream = outStream; }
void ReleaseStream() { _stream.Release(); }
void Init() { _size = 0; }
MY_UNKNOWN_IMP
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;
_compressHeaders = true;
_encryptHeadersSpecified = false;
_encryptHeaders = false;
WriteModified = true;
WriteCreated = false;
WriteAccessed = false;
WriteCTime = false;
WriteATime = false;
WriteMTime = true;
#ifdef COMPRESS_MT
_numThreads = NWindows::NSystem::GetNumberOfProcessors();
@@ -530,12 +531,9 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
#endif
return S_OK;
}
if (name.CompareNoCase(L"RSFX") == 0)
return SetBoolProperty(_removeSfxBlock, value);
if (name.CompareNoCase(L"F") == 0)
return SetBoolProperty(_autoFilter, value);
if (name.CompareNoCase(L"HC") == 0)
return SetBoolProperty(_compressHeaders, value);
if (name.CompareNoCase(L"RSFX") == 0) return SetBoolProperty(_removeSfxBlock, value);
if (name.CompareNoCase(L"F") == 0) return SetBoolProperty(_autoFilter, value);
if (name.CompareNoCase(L"HC") == 0) return SetBoolProperty(_compressHeaders, value);
if (name.CompareNoCase(L"HCF") == 0)
{
bool compressHeadersFull = true;
@@ -545,15 +543,15 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
return S_OK;
}
if (name.CompareNoCase(L"HE") == 0)
return SetBoolProperty(_encryptHeaders, value);
if (name.CompareNoCase(L"TM") == 0)
return SetBoolProperty(WriteModified, value);
if (name.CompareNoCase(L"TC") == 0)
return SetBoolProperty(WriteCreated, value);
if (name.CompareNoCase(L"TA") == 0)
return SetBoolProperty(WriteAccessed, value);
if (name.CompareNoCase(L"V") == 0)
return SetBoolProperty(_volumeMode, value);
{
RINOK(SetBoolProperty(_encryptHeaders, value));
_encryptHeadersSpecified = true;
return S_OK;
}
if (name.CompareNoCase(L"TC") == 0) return SetBoolProperty(WriteCTime, value);
if (name.CompareNoCase(L"TA") == 0) return SetBoolProperty(WriteATime, value);
if (name.CompareNoCase(L"TM") == 0) return SetBoolProperty(WriteMTime, value);
if (name.CompareNoCase(L"V") == 0) return SetBoolProperty(_volumeMode, value);
number = 0;
}
if (number > 10000)

View File

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

View File

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

View File

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