This commit is contained in:
Igor Pavlov
2016-05-10 00:00:00 +00:00
committed by Kornel Lesiński
parent c20d013055
commit 66ac98bb02
92 changed files with 2462 additions and 925 deletions

View File

@@ -1,5 +1,5 @@
/* 7zArcIn.c -- 7z Input functions /* 7zArcIn.c -- 7z Input functions
2015-11-18 : Igor Pavlov : Public domain */ 2016-03-31 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -788,13 +788,9 @@ static SRes ReadUnpackInfo(CSzAr *p,
numCodersOutStreams += numCoders; numCodersOutStreams += numCoders;
if (numCodersOutStreams < numCoders) if (numCodersOutStreams < numCoders)
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
if (numPackStreams > p->NumPackStreams - packStreamIndex)
packStreamIndex += numPackStreams;
if (packStreamIndex < numPackStreams)
return SZ_ERROR_UNSUPPORTED;
if (packStreamIndex > p->NumPackStreams)
return SZ_ERROR_ARCHIVE; return SZ_ERROR_ARCHIVE;
packStreamIndex += numPackStreams;
} }
} }

View File

@@ -1,14 +1,14 @@
#define MY_VER_MAJOR 15 #define MY_VER_MAJOR 16
#define MY_VER_MINOR 14 #define MY_VER_MINOR 00
#define MY_VER_BUILD 0 #define MY_VER_BUILD 0
#define MY_VERSION_NUMBERS "15.14" #define MY_VERSION_NUMBERS "16.00"
#define MY_VERSION "15.14" #define MY_VERSION "16.00"
#define MY_DATE "2015-12-31" #define MY_DATE "2016-05-10"
#undef MY_COPYRIGHT #undef MY_COPYRIGHT
#undef MY_VERSION_COPYRIGHT_DATE #undef MY_VERSION_COPYRIGHT_DATE
#define MY_AUTHOR_NAME "Igor Pavlov" #define MY_AUTHOR_NAME "Igor Pavlov"
#define MY_COPYRIGHT_PD "Igor Pavlov : Public domain" #define MY_COPYRIGHT_PD "Igor Pavlov : Public domain"
#define MY_COPYRIGHT_CR "Copyright (c) 1999-2015 Igor Pavlov" #define MY_COPYRIGHT_CR "Copyright (c) 1999-2016 Igor Pavlov"
#ifdef USE_COPYRIGHT_CR #ifdef USE_COPYRIGHT_CR
#define MY_COPYRIGHT MY_COPYRIGHT_CR #define MY_COPYRIGHT MY_COPYRIGHT_CR

View File

@@ -1,5 +1,5 @@
/* CpuArch.c -- CPU specific code /* CpuArch.c -- CPU specific code
2015-03-25: Igor Pavlov : Public domain */ 2016-02-25: Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -45,7 +45,8 @@ static UInt32 CheckFlag(UInt32 flag)
"push %%EDX\n\t" "push %%EDX\n\t"
"popf\n\t" "popf\n\t"
"andl %%EAX, %0\n\t": "andl %%EAX, %0\n\t":
"=c" (flag) : "c" (flag)); "=c" (flag) : "c" (flag) :
"%eax", "%edx");
#endif #endif
return flag; return flag;
} }
@@ -79,7 +80,13 @@ void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
#else #else
__asm__ __volatile__ ( __asm__ __volatile__ (
#if defined(MY_CPU_X86) && defined(__PIC__) #if defined(MY_CPU_AMD64) && defined(__PIC__)
"mov %%rbx, %%rdi;"
"cpuid;"
"xchg %%rbx, %%rdi;"
: "=a" (*a) ,
"=D" (*b) ,
#elif defined(MY_CPU_X86) && defined(__PIC__)
"mov %%ebx, %%edi;" "mov %%ebx, %%edi;"
"cpuid;" "cpuid;"
"xchgl %%ebx, %%edi;" "xchgl %%ebx, %%edi;"

View File

@@ -1,5 +1,5 @@
/* Sha1.c -- SHA-1 Hash /* Sha1.c -- SHA-1 Hash
2015-05-10 : Igor Pavlov : Public domain 2016-02-09 : Igor Pavlov : Public domain
This code is based on public domain code of Steve Reid from Wei Dai's Crypto++ library. */ This code is based on public domain code of Steve Reid from Wei Dai's Crypto++ library. */
#include "Precomp.h" #include "Precomp.h"
@@ -151,18 +151,23 @@ void Sha1_Update(CSha1 *p, const Byte *data, size_t size)
if (pos2 != 0) if (pos2 != 0)
{ {
UInt32 w = ((UInt32)data[0]) << 24; UInt32 w;
if (--size && pos2 < 3) pos2 = (3 - pos2) * 8;
w = ((UInt32)*data++) << pos2;
if (--size && pos2)
{ {
w |= ((UInt32)data[1]) << 16; pos2 -= 8;
if (--size && pos2 < 2) w |= ((UInt32)*data++) << pos2;
if (--size && pos2)
{ {
w |= ((UInt32)data[2]) << 8; pos2 -= 8;
--size; w |= ((UInt32)*data++) << pos2;
size--;
} }
} }
data += 4 - pos2; p->buffer[pos] |= w;
p->buffer[pos++] |= (w >> (8 * pos2)); if (pos2 == 0)
pos++;
} }
for (;;) for (;;)

View File

@@ -93,6 +93,8 @@ void CStreamSwitch::Set(CInArchive *archive, const CObjectVector<CByteBuffer> *d
Byte external = archive->ReadByte(); Byte external = archive->ReadByte();
if (external != 0) if (external != 0)
{ {
if (!dataVector)
ThrowIncorrect();
CNum dataIndex = archive->ReadNum(); CNum dataIndex = archive->ReadNum();
if (dataIndex >= dataVector->Size()) if (dataIndex >= dataVector->Size())
ThrowIncorrect(); ThrowIncorrect();
@@ -761,6 +763,8 @@ void CInArchive::ReadUnpackInfo(
folders.FoToCoderUnpackSizes[fo] = numCodersOutStreams; folders.FoToCoderUnpackSizes[fo] = numCodersOutStreams;
numCodersOutStreams += numCoders; numCodersOutStreams += numCoders;
folders.FoStartPackStreamIndex[fo] = packStreamIndex; folders.FoStartPackStreamIndex[fo] = packStreamIndex;
if (numPackStreams > folders.NumPackStreams - packStreamIndex)
ThrowIncorrect();
packStreamIndex += numPackStreams; packStreamIndex += numPackStreams;
folders.FoToMainUnpackSizeIndex[fo] = (Byte)indexOfMainStream; folders.FoToMainUnpackSizeIndex[fo] = (Byte)indexOfMainStream;
} }
@@ -770,6 +774,8 @@ void CInArchive::ReadUnpackInfo(
folders.FoStartPackStreamIndex[fo] = packStreamIndex; folders.FoStartPackStreamIndex[fo] = packStreamIndex;
folders.FoCodersDataOffset[fo] = _inByteBack->GetPtr() - startBufPtr; folders.FoCodersDataOffset[fo] = _inByteBack->GetPtr() - startBufPtr;
folders.CodersData.CopyFrom(startBufPtr, dataSize); folders.CodersData.CopyFrom(startBufPtr, dataSize);
// if (folders.NumPackStreams != packStreamIndex) ThrowUnsupported();
} }
WaitId(NID::kCodersUnpackSize); WaitId(NID::kCodersUnpackSize);

View File

@@ -380,29 +380,33 @@ static inline bool IsExeFilter(CMethodId m)
return false; return false;
} }
static unsigned Get_FilterGroup_for_Folder(CRecordVector<CFilterMode2> &filters, const CFolderEx &f) static unsigned Get_FilterGroup_for_Folder(
CRecordVector<CFilterMode2> &filters, const CFolderEx &f, bool extractFilter)
{ {
CFilterMode2 m; CFilterMode2 m;
m.Id = 0; m.Id = 0;
m.Delta = 0; m.Delta = 0;
m.Encrypted = f.IsEncrypted(); m.Encrypted = f.IsEncrypted();
const CCoderInfo &coder = f.Coders[f.UnpackCoder]; if (extractFilter)
{
const CCoderInfo &coder = f.Coders[f.UnpackCoder];
if (coder.MethodID == k_Delta) if (coder.MethodID == k_Delta)
{
if (coder.Props.Size() == 1)
{ {
m.Delta = (unsigned)coder.Props[0] + 1; if (coder.Props.Size() == 1)
m.Id = k_Delta; {
m.Delta = (unsigned)coder.Props[0] + 1;
m.Id = k_Delta;
}
}
else if (IsExeFilter(coder.MethodID))
{
m.Id = (UInt32)coder.MethodID;
if (m.Id == k_BCJ2)
m.Id = k_BCJ;
m.SetDelta();
} }
}
else if (IsExeFilter(coder.MethodID))
{
m.Id = (UInt32)coder.MethodID;
if (m.Id == k_BCJ2)
m.Id = k_BCJ;
m.SetDelta();
} }
return GetGroup(filters, m); return GetGroup(filters, m);
@@ -1577,7 +1581,7 @@ HRESULT Update(
return E_NOTIMPL; return E_NOTIMPL;
*/ */
UInt64 startBlockSize = db != 0 ? db->ArcInfo.StartPosition: 0; UInt64 startBlockSize = db ? db->ArcInfo.StartPosition: 0;
if (startBlockSize > 0 && !options.RemoveSfxBlock) if (startBlockSize > 0 && !options.RemoveSfxBlock)
{ {
RINOK(WriteRange(inStream, seqOutStream, 0, startBlockSize, NULL)); RINOK(WriteRange(inStream, seqOutStream, 0, startBlockSize, NULL));
@@ -1591,8 +1595,21 @@ HRESULT Update(
CRecordVector<CFilterMode2> filters; CRecordVector<CFilterMode2> filters;
CObjectVector<CSolidGroup> groups; CObjectVector<CSolidGroup> groups;
bool thereAreRepacks = false; bool thereAreRepacks = false;
bool useFilters = options.UseFilters;
if (useFilters)
{
const CCompressionMethodMode &method = *options.Method;
FOR_VECTOR (i, method.Methods)
if (IsFilterMethod(method.Methods[i].Id))
{
useFilters = false;
break;
}
}
if (db != 0) if (db)
{ {
fileIndexToUpdateIndexMap.Alloc(db->Files.Size()); fileIndexToUpdateIndexMap.Alloc(db->Files.Size());
unsigned i; unsigned i;
@@ -1638,16 +1655,18 @@ HRESULT Update(
CFolderEx f; CFolderEx f;
db->ParseFolderEx(i, f); db->ParseFolderEx(i, f);
bool isEncrypted = f.IsEncrypted(); const bool isEncrypted = f.IsEncrypted();
const bool needCopy = (numCopyItems == numUnpackStreams);
unsigned groupIndex = Get_FilterGroup_for_Folder(filters, f); const bool extractFilter = (useFilters || needCopy);
unsigned groupIndex = Get_FilterGroup_for_Folder(filters, f, extractFilter);
while (groupIndex >= groups.Size()) while (groupIndex >= groups.Size())
groups.AddNew(); groups.AddNew();
groups[groupIndex].folderRefs.Add(rep); groups[groupIndex].folderRefs.Add(rep);
if (numCopyItems == numUnpackStreams) if (needCopy)
complexity += db->GetFolderFullPackSize(i); complexity += db->GetFolderFullPackSize(i);
else else
{ {
@@ -1732,22 +1751,8 @@ HRESULT Update(
// ---------- Split files to groups ---------- // ---------- Split files to groups ----------
bool useFilters = options.UseFilters;
const CCompressionMethodMode &method = *options.Method; const CCompressionMethodMode &method = *options.Method;
if (useFilters)
for (i = 0; i < method.Methods.Size(); i++)
if (IsFilterMethod(method.Methods[i].Id))
{
useFilters = false;
break;
}
/*
if (!method.Bonds.IsEmpty())
useFilters = false;
*/
for (i = 0; i < updateItems.Size(); i++) for (i = 0; i < updateItems.Size(); i++)
{ {
const CUpdateItem &ui = updateItems[i]; const CUpdateItem &ui = updateItems[i];
@@ -2156,7 +2161,13 @@ HRESULT Update(
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
if (options.MultiThreadMixer) if (options.MultiThreadMixer)
{ {
// 16.00: hang was fixed : for case if decoding was not finished.
// We close CBinderInStream and it calls CStreamBinder::CloseRead()
inStreamSizeCount.Release();
sbInStream.Release();
threadDecoder.WaitExecuteFinish(); threadDecoder.WaitExecuteFinish();
HRESULT decodeRes = threadDecoder.Result; HRESULT decodeRes = threadDecoder.Result;
// if (res == k_My_HRESULT_CRC_ERROR) // if (res == k_My_HRESULT_CRC_ERROR)
if (decodeRes == S_FALSE) if (decodeRes == S_FALSE)

View File

@@ -348,15 +348,19 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
CMyComPtr<IInStream> nextStream = inStream; CMyComPtr<IInStream> nextStream = inStream;
bool prevChecked = false; bool prevChecked = false;
UString startVolName;
bool startVolName_was_Requested = false;
UInt64 numItems = 0; UInt64 numItems = 0;
unsigned numTempVolumes = 0; unsigned numTempVolumes = 0;
// try // try
{ {
while (nextStream != NULL) while (nextStream)
{ {
CDatabaseEx db; CDatabaseEx db;
db.Stream = nextStream; db.Stream = nextStream;
HRESULT res = archive.Open(db, maxCheckStartPosition); HRESULT res = archive.Open(db, maxCheckStartPosition);
_errorInHeaders |= archive.HeaderError; _errorInHeaders |= archive.HeaderError;
_errorInHeaders |= archive.ErrorInNames; _errorInHeaders |= archive.ErrorInNames;
_unexpectedEnd |= archive.UnexpectedEnd; _unexpectedEnd |= archive.UnexpectedEnd;
@@ -426,6 +430,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
for (;;) for (;;)
{ {
const COtherArc *otherArc = NULL; const COtherArc *otherArc = NULL;
if (!prevChecked) if (!prevChecked)
{ {
if (numTempVolumes == 0) if (numTempVolumes == 0)
@@ -449,18 +454,35 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
} }
} }
} }
if (!otherArc) if (!otherArc)
{ {
const CInArcInfo &ai = m_Database.Volumes.Back().ArcInfo; const CInArcInfo &ai = m_Database.Volumes.Back().ArcInfo;
if (ai.IsThereNext()) if (ai.IsThereNext())
otherArc = &ai.NextArc; otherArc = &ai.NextArc;
} }
if (!otherArc) if (!otherArc)
break; break;
if (!openVolumeCallback) if (!openVolumeCallback)
break; break;
// printf("\n%s", otherArc->FileName); // printf("\n%s", otherArc->FileName);
const UString fullName = MultiByteToUnicodeString(otherArc->FileName, CP_ACP); const UString fullName = MultiByteToUnicodeString(otherArc->FileName, CP_ACP);
if (!startVolName_was_Requested)
{
// some "bad" cab example can contain the link to itself.
startVolName_was_Requested = true;
{
NCOM::CPropVariant prop;
RINOK(openVolumeCallback->GetProperty(kpidName, &prop));
if (prop.vt == VT_BSTR)
startVolName = prop.bstrVal;
}
if (fullName == startVolName)
break;
}
HRESULT result = openVolumeCallback->GetStream(fullName, &nextStream); HRESULT result = openVolumeCallback->GetStream(fullName, &nextStream);
if (result == S_OK) if (result == S_OK)
break; break;

View File

@@ -578,14 +578,16 @@ HRESULT CDatabase::Open(IInStream *inStream)
if (item.IsDir() || numCabs > 1) if (item.IsDir() || numCabs > 1)
continue; continue;
bool isMsiName; bool isMsiName;
UString msiName = ConvertName(item.Name, isMsiName); const UString msiName = ConvertName(item.Name, isMsiName);
if (isMsiName && !msiName.IsEmpty()) if (isMsiName && !msiName.IsEmpty())
{ {
bool isThereExt = (msiName.Find(L'.') >= 0); // bool isThereExt = (msiName.Find(L'.') >= 0);
bool isMsiSpec = (msiName[0] == k_Msi_SpecChar); bool isMsiSpec = (msiName[0] == k_Msi_SpecChar);
if (msiName.Len() >= 4 && StringsAreEqualNoCase_Ascii(msiName.RightPtr(4), ".cab") if (msiName.Len() >= 4 && StringsAreEqualNoCase_Ascii(msiName.RightPtr(4), ".cab")
|| !isMsiSpec && msiName.Len() >= 3 && StringsAreEqualNoCase_Ascii(msiName.RightPtr(3), "exe") || !isMsiSpec && msiName.Len() >= 3 && StringsAreEqualNoCase_Ascii(msiName.RightPtr(3), "exe")
|| !isMsiSpec && !isThereExt) // || !isMsiSpec && !isThereExt
)
{ {
numCabs++; numCabs++;
MainSubfile = i; MainSubfile = i;

View File

@@ -34,48 +34,35 @@
static const Byte k_Base64Table[256] = static const Byte k_Base64Table[256] =
{ {
64,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, 66,77,77,77,77,77,77,77,77,65,65,77,77,65,77,77,
77,77,77,77,77,77,77,77,77,77,77,62,77,64,77,63,52,53,54,55,56,57,58,59,60,61,77,77,77,77,77,77, 77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
77, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,77,77,77,77,77, 65,77,77,77,77,77,77,77,77,77,77,62,77,77,77,63,
77,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,77,77,77,77,77, 52,53,54,55,56,57,58,59,60,61,77,77,77,64,77,77,
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, 77, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, 15,16,17,18,19,20,21,22,23,24,25,77,77,77,77,77,
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, 77,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77 41,42,43,44,45,46,47,48,49,50,51,77,77,77,77,77,
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77
}; };
static Byte *Base64ToBin(Byte *dest, const char *src) static Byte *Base64ToBin(Byte *dest, const char *src)
{ {
UInt32 val = 1; UInt32 val = 1;
UInt32 c = k_Base64Table[(Byte)(*src++)];
for (;;) for (;;)
{ {
/* UInt32 c = k_Base64Table[(Byte)(*src++)];
UInt32 c = (Byte)(*src++);
if (c >= 'A')
{
if (c <= 'Z') c -= 'A';
else if (c >= 'a' && c <= 'z') c -= 'a' - 26;
else continue;
}
else if (c >= '0')
{
if (c <= '9') c += 52 - '0';
else if (c == '=') break;
else continue;
}
else if (c == '+') c = 62;
else if (c == '/') c = 63;
else if (c == 0) break;
else continue;
*/
// UInt32 c = k_Base64Table[(Byte)(*src++)];
if (c < 64) if (c < 64)
{ {
val = (val << 6) | c; val = (val << 6) | c;
c = k_Base64Table[(Byte)(*src++)];
if ((val & ((UInt32)1 << 24)) == 0) if ((val & ((UInt32)1 << 24)) == 0)
continue; continue;
dest[0] = (Byte)(val >> 16); dest[0] = (Byte)(val >> 16);
@@ -85,19 +72,41 @@ static Byte *Base64ToBin(Byte *dest, const char *src)
val = 1; val = 1;
continue; continue;
} }
if (c == 64)
if (c == 65) // space
continue;
if (c == 64) // '='
break; break;
c = k_Base64Table[(Byte)(*src++)];
if (c == 66 && val == 1) // end of string
return dest;
return NULL;
} }
if (val >= ((UInt32)1 << 12)) if (val < (1 << 12))
return NULL;
if (val & (1 << 18))
{ {
if (val >= ((UInt32)1 << 18)) *dest++ = (Byte)(val >> 10);
*dest++ = (Byte)(val >> 16); *dest++ = (Byte)(val >> 2);
*dest++ = (Byte)(val); }
else if (k_Base64Table[(Byte)(*src++)] != 64) // '='
return NULL;
else
*dest++ = (Byte)(val >> 4);
for (;;)
{
Byte c = k_Base64Table[(Byte)(*src++)];
if (c == 65) // space
continue;
if (c == 66) // end of string
return dest;
return NULL;
} }
return dest;
} }
@@ -720,7 +729,13 @@ HRESULT CHandler::Open2(IInStream *stream)
return S_FALSE; return S_FALSE;
destLen = dataString->Len() / 4 * 3 + 4; destLen = dataString->Len() / 4 * 3 + 4;
rawBuf.Alloc(destLen); rawBuf.Alloc(destLen);
destLen = (unsigned)(Base64ToBin(rawBuf, *dataString) - rawBuf); {
const Byte *endPtr = Base64ToBin(rawBuf, *dataString);
if (!endPtr)
return S_FALSE;
destLen = (unsigned)(endPtr - rawBuf);
}
#ifdef DMG_SHOW_RAW #ifdef DMG_SHOW_RAW
CExtraFile &extra = _extras.AddNew(); CExtraFile &extra = _extras.AddNew();
{ {

View File

@@ -87,6 +87,9 @@ struct CPartType
static const CPartType kPartTypes[] = static const CPartType kPartTypes[] =
{ {
// { 0x0, 0, "Unused" }, // { 0x0, 0, "Unused" },
{ 0x21686148, 0, "BIOS Boot" },
{ 0xC12A7328, 0, "EFI System" }, { 0xC12A7328, 0, "EFI System" },
{ 0x024DEE41, 0, "MBR" }, { 0x024DEE41, 0, "MBR" },
@@ -98,10 +101,13 @@ static const CPartType kPartTypes[] =
// { 0x37AFFC90, 0, "IBM GPFS" }, // { 0x37AFFC90, 0, "IBM GPFS" },
// { 0xE75CAF8F, 0, "Windows Storage Spaces" }, // { 0xE75CAF8F, 0, "Windows Storage Spaces" },
{ 0x83BD6B9D, 0, "FreeBSD Boot" }, { 0x0FC63DAF, 0, "Linux Data" },
{ 0x0657FD6D, 0, "Linux Swap" },
{ 0x83BD6B9D, 0, "FreeBSD Boot" },
{ 0x516E7CB4, 0, "FreeBSD Data" }, { 0x516E7CB4, 0, "FreeBSD Data" },
{ 0x516E7CB5, 0, "FreeBSD Swap" }, { 0x516E7CB5, 0, "FreeBSD Swap" },
{ 0x516E7CB6, "ufs", "FreeBSD UFS" }, { 0x516E7CB6, "ufs", "FreeBSD UFS" },
{ 0x516E7CB8, 0, "FreeBSD Vinum" }, { 0x516E7CB8, 0, "FreeBSD Vinum" },
{ 0x516E7CB8, "zfs", "FreeBSD ZFS" }, { 0x516E7CB8, "zfs", "FreeBSD ZFS" },
@@ -335,6 +341,12 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
break; break;
s += c; s += c;
} }
if (s.IsEmpty())
{
char temp[16];
ConvertUInt32ToString(index, temp);
s.AddAscii(temp);
}
{ {
int typeIndex = FindPartType(item.Type); int typeIndex = FindPartType(item.Type);
s += L'.'; s += L'.';

View File

@@ -987,7 +987,9 @@ HRESULT CDatabase::LoadCatalog(const CFork &fork, const CObjectVector<CIdExtents
item.GroupID = Get32(r + 0x24); item.GroupID = Get32(r + 0x24);
item.AdminFlags = r[0x28]; item.AdminFlags = r[0x28];
item.OwnerFlags = r[0x29]; item.OwnerFlags = r[0x29];
*/
item.FileMode = Get16(r + 0x2A); item.FileMode = Get16(r + 0x2A);
/*
item.special.iNodeNum = Get16(r + 0x2C); // or .linkCount item.special.iNodeNum = Get16(r + 0x2C); // or .linkCount
item.FileType = Get32(r + 0x30); item.FileType = Get32(r + 0x30);
item.FileCreator = Get32(r + 0x34); item.FileCreator = Get32(r + 0x34);
@@ -1572,6 +1574,9 @@ HRESULT CHandler::ExtractZlibFile(
UInt32 size = GetUi32(tableBuf + i * 8 + 4); UInt32 size = GetUi32(tableBuf + i * 8 + 4);
if (size > buf.Size() || size > kCompressionBlockSize + 1)
return S_FALSE;
RINOK(ReadStream_FALSE(inStream, buf, size)); RINOK(ReadStream_FALSE(inStream, buf, size));
if ((buf[0] & 0xF) == 0xF) if ((buf[0] & 0xF) == 0xF)

View File

@@ -79,7 +79,7 @@ struct CDirRecord
while (rem >= 5) while (rem >= 5)
{ {
unsigned len = p[2]; unsigned len = p[2];
if (len > rem) if (len < 3 || len > rem)
return 0; return 0;
if (p[0] == 'N' && p[1] == 'M' && p[3] == 1) if (p[0] == 'N' && p[1] == 'M' && p[3] == 1)
{ {

View File

@@ -110,7 +110,7 @@ HRESULT CDecoder::Create(bool filteredMode, ISequentialInStream *inStream)
{ {
_filterCoder = new CFilterCoder(false); _filterCoder = new CFilterCoder(false);
CMyComPtr<ICompressCoder> coder = _filterCoder; CMyComPtr<ICompressCoder> coder = _filterCoder;
_filterCoder->Filter = new CBcjCoder(false); _filterCoder->Filter = new NCompress::NBcj::CCoder(false);
_bcjStream = _filterCoder; _bcjStream = _filterCoder;
} }
} }

View File

@@ -59,7 +59,7 @@ HRESULT CDecoder::Init(ISequentialInStream *inStream, bool &useFilter)
{ {
_filter = new CFilterCoder(false); _filter = new CFilterCoder(false);
_filterInStream = _filter; _filterInStream = _filter;
_filter->Filter = new CBcjCoder(false); _filter->Filter = new NCompress::NBcj::CCoder(false);
} }
RINOK(_filter->SetInStream(_codecInStream)); RINOK(_filter->SetInStream(_codecInStream));
_decoderInStream = _filterInStream; _decoderInStream = _filterInStream;

View File

@@ -88,7 +88,7 @@ enum
EW_SENDMESSAGE, // SendMessage EW_SENDMESSAGE, // SendMessage
EW_ISWINDOW, // IsWindow EW_ISWINDOW, // IsWindow
EW_GETDLGITEM, // GetDlgItem EW_GETDLGITEM, // GetDlgItem
EW_SETCTLCOLORS, // SerCtlColors EW_SETCTLCOLORS, // SetCtlColors
EW_SETBRANDINGIMAGE, // SetBrandingImage EW_SETBRANDINGIMAGE, // SetBrandingImage
EW_CREATEFONT, // CreateFont EW_CREATEFONT, // CreateFont
EW_SHOWWINDOW, // ShowWindow, EnableWindow, HideWindow EW_SHOWWINDOW, // ShowWindow, EnableWindow, HideWindow
@@ -1155,9 +1155,13 @@ bool CInArchive::IsGoodString(UInt32 param) const
if (param == 0) if (param == 0)
return true; return true;
const Byte *p = _data + _stringsPos; const Byte *p = _data + _stringsPos;
unsigned c;
if (IsUnicode) if (IsUnicode)
return (Get16(p + param * 2 - 2)) == 0; c = Get16(p + param * 2 - 2);
return p[param - 1] == 0; else
c = p[param - 1];
// some files have '\\' character before string?
return (c == 0 || c == '\\');
} }
bool CInArchive::AreTwoParamStringsEqual(UInt32 param1, UInt32 param2) const bool CInArchive::AreTwoParamStringsEqual(UInt32 param1, UInt32 param2) const
@@ -1509,7 +1513,7 @@ static const UInt32 CMD_REF_Pre = (1 << 2);
static const UInt32 CMD_REF_Show = (1 << 3); static const UInt32 CMD_REF_Show = (1 << 3);
static const UInt32 CMD_REF_Leave = (1 << 4); static const UInt32 CMD_REF_Leave = (1 << 4);
static const UInt32 CMD_REF_OnFunc = (1 << 5); static const UInt32 CMD_REF_OnFunc = (1 << 5);
static const UInt32 CMD_REF_Section = (1 << 6); static const UInt32 CMD_REF_Section = (1 << 6);
static const UInt32 CMD_REF_InitPluginDir = (1 << 7); static const UInt32 CMD_REF_InitPluginDir = (1 << 7);
// static const UInt32 CMD_REF_Creator = (1 << 5); // _Pre is used instead // static const UInt32 CMD_REF_Creator = (1 << 5); // _Pre is used instead
static const unsigned CMD_REF_OnFunc_NumShifts = 28; // it uses for onFunc too static const unsigned CMD_REF_OnFunc_NumShifts = 28; // it uses for onFunc too
@@ -3357,7 +3361,7 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
#ifdef NSIS_SCRIPT #ifdef NSIS_SCRIPT
s += isSetOutPath ? "SetOutPath" : "CreateDirectory"; s += isSetOutPath ? "SetOutPath" : "CreateDirectory";
AddParam(params[0]); AddParam(params[0]);
#endif #endif
break; break;
@@ -3571,15 +3575,16 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
AddParam(params[0]); AddParam(params[0]);
SmallSpaceComment();
/* /*
for (int i = 1; i < 3; i++) for (int i = 1; i < 3; i++)
AddParam_UInt(params[i]); AddParam_UInt(params[i]);
*/ */
if (params[3] != 0) if (params[3] != 0)
{
SmallSpaceComment();
AddParam(params[3]); AddParam(params[3]);
}
#endif #endif

View File

@@ -421,7 +421,11 @@ public:
const char *kRemoveStr = "$INSTDIR\\"; const char *kRemoveStr = "$INSTDIR\\";
if (s.IsPrefixedBy_Ascii_NoCase(kRemoveStr)) if (s.IsPrefixedBy_Ascii_NoCase(kRemoveStr))
{
s.Delete(0, MyStringLen(kRemoveStr)); s.Delete(0, MyStringLen(kRemoveStr));
if (s[0] == L'\\')
s.DeleteFrontal(1);
}
if (item.IsUninstaller && ExeStub.Size() == 0) if (item.IsUninstaller && ExeStub.Size() == 0)
s += L".nsis"; s += L".nsis";
return s; return s;

View File

@@ -1148,8 +1148,16 @@ bool CMftRec::Parse(Byte *p, unsigned sectorSizeLog, UInt32 numSectors, UInt32 r
return false; return false;
if (usaOffset >= 0x30) // NTFS 3.1+ if (usaOffset >= 0x30) // NTFS 3.1+
if (Get32(p + 0x2C) != recNumber) {
return false; UInt32 iii = Get32(p + 0x2C);
if (iii != recNumber)
{
// ntfs-3g probably writes 0 (that probably is incorrect value) to this field for unused records.
// so we support that "bad" case.
if (iii != 0)
return false;
}
}
UInt16 usn = Get16(p + usaOffset); UInt16 usn = Get16(p + usaOffset);
// PRF(printf("\nusn = %d", usn)); // PRF(printf("\nusn = %d", usn));

View File

@@ -347,8 +347,8 @@ struct CSection
CSection(): IsRealSect(false), IsDebug(false), IsAdditionalSection(false) {} CSection(): IsRealSect(false), IsDebug(false), IsAdditionalSection(false) {}
// const UInt32 GetSize() const { return PSize; } const UInt32 GetSizeExtract() const { return PSize; }
const UInt32 GetSize() const { return MyMin(PSize, VSize); } const UInt32 GetSizeMin() const { return MyMin(PSize, VSize); }
void UpdateTotalSize(UInt32 &totalSize) const void UpdateTotalSize(UInt32 &totalSize) const
{ {
@@ -362,8 +362,8 @@ struct CSection
int Compare(const CSection &s) const int Compare(const CSection &s) const
{ {
RINOZ(MyCompare(Pa, s.Pa)); RINOZ(MyCompare(Pa, s.Pa));
UInt32 size1 = GetSize(); UInt32 size1 = GetSizeExtract();
UInt32 size2 = s.GetSize(); UInt32 size2 = s.GetSizeExtract();
return MyCompare(size1, size2); return MyCompare(size1, size2);
} }
}; };
@@ -1045,7 +1045,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
switch (propID) switch (propID)
{ {
case kpidPath: prop = MultiByteToUnicodeString(item.Name); break; case kpidPath: prop = MultiByteToUnicodeString(item.Name); break;
case kpidSize: prop = (UInt64)item.GetSize(); break; case kpidSize: prop = (UInt64)item.PSize; break;
case kpidPackSize: prop = (UInt64)item.PSize; break; case kpidPackSize: prop = (UInt64)item.PSize; break;
case kpidVirtualSize: prop = (UInt64)item.VSize; break; case kpidVirtualSize: prop = (UInt64)item.VSize; break;
case kpidOffset: prop = item.Pa; break; case kpidOffset: prop = item.Pa; break;
@@ -1898,7 +1898,7 @@ static bool ParseVersion(const Byte *p, UInt32 size, CTextFile &f, CObjectVector
HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchiveOpenCallback *callback) HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchiveOpenCallback *callback)
{ {
const CSection &sect = _sections[sectionIndex]; const CSection &sect = _sections[sectionIndex];
const size_t fileSize = sect.GetSize(); const size_t fileSize = sect.GetSizeMin();
if (fileSize > kFileSizeMax) if (fileSize > kFileSizeMax)
return S_FALSE; return S_FALSE;
@@ -1926,6 +1926,7 @@ HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchi
_oneLang = true; _oneLang = true;
bool stringsOk = true; bool stringsOk = true;
size_t maxOffset = 0; size_t maxOffset = 0;
FOR_VECTOR (i, specItems) FOR_VECTOR (i, specItems)
{ {
const CTableItem &item1 = specItems[i]; const CTableItem &item1 = specItems[i];
@@ -2007,6 +2008,7 @@ HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchi
} }
// PrintError("ver.Parse error"); // PrintError("ver.Parse error");
} }
item.Enabled = true; item.Enabled = true;
_items.Add(item); _items.Add(item);
} }
@@ -2041,7 +2043,10 @@ HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchi
UInt32 mask = (1 << numBits) - 1; UInt32 mask = (1 << numBits) - 1;
size_t end = ((maxOffset + mask) & ~mask); size_t end = ((maxOffset + mask) & ~mask);
if (/* end < sect.VSize && */ end <= sect.GetSize()) // PSize can be much larger than VSize in some exe installers.
// it contains archive data after PE resources.
// So we need to use PSize here!
if (/* end < sect.VSize && */ end <= sect.PSize)
{ {
CSection sect2; CSection sect2;
sect2.Flags = 0; sect2.Flags = 0;
@@ -2059,7 +2064,7 @@ HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchi
// 9.29: we use sect.PSize instead of sect.VSize to support some CAB-SFX // 9.29: we use sect.PSize instead of sect.VSize to support some CAB-SFX
// the code for .rsrc_2 is commented. // the code for .rsrc_2 is commented.
sect2.PSize = sect.GetSize() - (UInt32)maxOffset; sect2.PSize = sect.PSize - (UInt32)maxOffset;
if (sect2.PSize != 0) if (sect2.PSize != 0)
{ {
@@ -2473,7 +2478,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
else if (mixItem.ResourceIndex >= 0) else if (mixItem.ResourceIndex >= 0)
size = _items[mixItem.ResourceIndex].GetSize(); size = _items[mixItem.ResourceIndex].GetSize();
else else
size = _sections[mixItem.SectionIndex].GetSize(); size = _sections[mixItem.SectionIndex].GetSizeExtract();
totalSize += size; totalSize += size;
} }
extractCallback->SetTotal(totalSize); extractCallback->SetTotal(totalSize);
@@ -2549,7 +2554,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
} }
else else
{ {
currentItemSize = sect.GetSize(); currentItemSize = sect.GetSizeExtract();
if (!testMode && !outStream) if (!testMode && !outStream)
continue; continue;

View File

@@ -2333,6 +2333,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
{ {
UInt64 total = 0; UInt64 total = 0;
bool isThereUndefinedSize = false;
bool thereAreLinks = false; bool thereAreLinks = false;
{ {
@@ -2342,9 +2343,14 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
unsigned index = allFilesMode ? t : indices[t]; unsigned index = allFilesMode ? t : indices[t];
const CRefItem &ref = _refs[index]; const CRefItem &ref = _refs[index];
const CItem &item = _items[ref.Item]; const CItem &item = _items[ref.Item];
const CItem &lastItem = _items[ref.Last];
extractStatuses[index] |= kStatus_Extract; extractStatuses[index] |= kStatus_Extract;
total += item.Size;
if (!lastItem.Is_UnknownSize())
total += lastItem.Size;
else
isThereUndefinedSize = true;
if (ref.Link >= 0) if (ref.Link >= 0)
{ {
@@ -2352,11 +2358,18 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
{ {
if ((unsigned)ref.Link < index) if ((unsigned)ref.Link < index)
{ {
const CItem &linkItem = _items[_refs[(unsigned)ref.Link].Item]; const CRefItem &linkRef = _refs[(unsigned)ref.Link];
const CItem &linkItem = _items[linkRef.Item];
if (linkItem.IsSolid() && linkItem.Size <= k_CopyLinkFile_MaxSize) if (linkItem.IsSolid() && linkItem.Size <= k_CopyLinkFile_MaxSize)
{ {
if (extractStatuses[(unsigned)ref.Link] == 0) if (extractStatuses[(unsigned)ref.Link] == 0)
total += linkItem.Size; {
const CItem &lastLinkItem = _items[linkRef.Last];
if (!lastLinkItem.Is_UnknownSize())
total += lastLinkItem.Size;
else
isThereUndefinedSize = true;
}
extractStatuses[(unsigned)ref.Link] |= kStatus_Link; extractStatuses[(unsigned)ref.Link] |= kStatus_Link;
thereAreLinks = true; thereAreLinks = true;
} }
@@ -2375,11 +2388,18 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
while (j > solidLimit) while (j > solidLimit)
{ {
j--; j--;
const CItem &item2 = _items[_refs[j].Item]; const CRefItem &ref2 = _refs[j];
const CItem &item2 = _items[ref2.Item];
if (!item2.IsService()) if (!item2.IsService())
{ {
if (extractStatuses[j] == 0) if (extractStatuses[j] == 0)
total += item2.Size; {
const CItem &lastItem2 = _items[ref2.Last];
if (!lastItem2.Is_UnknownSize())
total += lastItem2.Size;
else
isThereUndefinedSize = true;
}
extractStatuses[j] |= kStatus_Skip; extractStatuses[j] |= kStatus_Skip;
if (!item2.IsSolid()) if (!item2.IsSolid())
break; break;
@@ -2415,13 +2435,20 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
while (j > solidLimit) while (j > solidLimit)
{ {
j--; j--;
const CItem &item2 = _items[_refs[j].Item]; const CRefItem &ref2 = _refs[j];
const CItem &item2 = _items[ref2.Item];
if (!item2.IsService()) if (!item2.IsService())
{ {
if (extractStatuses[j] != 0) if (extractStatuses[j] != 0)
break; break;
extractStatuses[j] = kStatus_Skip; extractStatuses[j] = kStatus_Skip;
total += item2.Size; {
const CItem &lastItem2 = _items[ref2.Last];
if (!lastItem2.Is_UnknownSize())
total += lastItem2.Size;
else
isThereUndefinedSize = true;
}
if (!item2.IsSolid()) if (!item2.IsSolid())
break; break;
} }
@@ -2449,7 +2476,10 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
} }
} }
RINOK(extractCallback->SetTotal(total)); if (total != 0 || !isThereUndefinedSize)
{
RINOK(extractCallback->SetTotal(total));
}
} }
@@ -2502,8 +2532,12 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
const CRefItem *ref = &_refs[index]; const CRefItem *ref = &_refs[index];
const CItem *item = &_items[ref->Item]; const CItem *item = &_items[ref->Item];
const CItem &lastItem = _items[ref->Last];
curUnpackSize = 0;
if (!lastItem.Is_UnknownSize())
curUnpackSize = lastItem.Size;
curUnpackSize = item->Size;
curPackSize = GetPackSize(index); curPackSize = GetPackSize(index);
RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
@@ -2532,11 +2566,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
{ {
const CRefItem &ref2 = _refs[index2]; const CRefItem &ref2 = _refs[index2];
const CItem &item2 = _items[ref2.Item]; const CItem &item2 = _items[ref2.Item];
const CItem &lastItem2 = _items[ref2.Last];
if (!item2.IsSolid()) if (!item2.IsSolid())
{ {
item = &item2; item = &item2;
ref = &ref2; ref = &ref2;
curUnpackSize = item->Size; if (!lastItem2.Is_UnknownSize())
curUnpackSize = lastItem2.Size;
else
curUnpackSize = 0;
curPackSize = GetPackSize(index2); curPackSize = GetPackSize(index2);
} }
else if ((unsigned)index2 < index) else if ((unsigned)index2 < index)

View File

@@ -953,6 +953,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
NCOM::CPropVariant prop; NCOM::CPropVariant prop;
const CRefItem &refItem = _refItems[index]; const CRefItem &refItem = _refItems[index];
const CItem &item = _items[refItem.ItemIndex]; const CItem &item = _items[refItem.ItemIndex];
const CItem &lastItem = _items[refItem.ItemIndex + refItem.NumItems - 1];
/* /*
const CItem *mainItem = &item; const CItem *mainItem = &item;
if (item.BaseFileIndex >= 0) if (item.BaseFileIndex >= 0)
@@ -972,7 +974,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
break; break;
} }
case kpidIsDir: prop = item.IsDir(); break; case kpidIsDir: prop = item.IsDir(); break;
case kpidSize: prop = item.Size; break; case kpidSize: if (lastItem.Is_Size_Defined()) prop = lastItem.Size; break;
case kpidPackSize: prop = GetPackSize(index); break; case kpidPackSize: prop = GetPackSize(index); break;
case kpidMTime: RarTimeToProp(item.MTime, prop); break; case kpidMTime: RarTimeToProp(item.MTime, prop); break;
case kpidCTime: if (item.CTimeDefined) RarTimeToProp(item.CTime, prop); break; case kpidCTime: if (item.CTimeDefined) RarTimeToProp(item.CTime, prop); break;
@@ -985,7 +987,6 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidSplitAfter: prop = _items[refItem.ItemIndex + refItem.NumItems - 1].IsSplitAfter(); break; case kpidSplitAfter: prop = _items[refItem.ItemIndex + refItem.NumItems - 1].IsSplitAfter(); break;
case kpidCRC: case kpidCRC:
{ {
const CItem &lastItem = _items[refItem.ItemIndex + refItem.NumItems - 1];
prop = ((lastItem.IsSplitAfter()) ? item.FileCRC : lastItem.FileCRC); prop = ((lastItem.IsSplitAfter()) ? item.FileCRC : lastItem.FileCRC);
break; break;
} }
@@ -1378,34 +1379,52 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
CRecordVector<unsigned> importantIndexes; CRecordVector<unsigned> importantIndexes;
CRecordVector<bool> extractStatuses; CRecordVector<bool> extractStatuses;
bool isThereUndefinedSize = false;
for (UInt32 t = 0; t < numItems; t++) for (UInt32 t = 0; t < numItems; t++)
{ {
unsigned index = allFilesMode ? t : indices[t]; unsigned index = allFilesMode ? t : indices[t];
const CRefItem &refItem = _refItems[index];
const CItem &item = _items[refItem.ItemIndex]; {
censoredTotalUnPacked += item.Size; const CRefItem &refItem = _refItems[index];
// censoredTotalPacked += item.PackSize; const CItem &item = _items[refItem.ItemIndex + refItem.NumItems - 1];
if (item.Is_Size_Defined())
censoredTotalUnPacked += item.Size;
else
isThereUndefinedSize = true;
// censoredTotalPacked += item.PackSize;
}
unsigned j; unsigned j;
for (j = lastIndex; j <= index; j++) for (j = lastIndex; j <= index; j++)
// if (!_items[_refItems[j].ItemIndex].IsSolid()) // if (!_items[_refItems[j].ItemIndex].IsSolid())
if (!IsSolid(j)) if (!IsSolid(j))
lastIndex = j; lastIndex = j;
for (j = lastIndex; j <= index; j++) for (j = lastIndex; j <= index; j++)
{ {
const CRefItem &refItem = _refItems[j]; const CRefItem &refItem = _refItems[j];
const CItem &item = _items[refItem.ItemIndex]; const CItem &item = _items[refItem.ItemIndex + refItem.NumItems - 1];
// const CItem &item = _items[j]; if (item.Is_Size_Defined())
importantTotalUnPacked += item.Size;
importantTotalUnPacked += item.Size; else
isThereUndefinedSize = true;
// importantTotalPacked += item.PackSize; // importantTotalPacked += item.PackSize;
importantIndexes.Add(j); importantIndexes.Add(j);
extractStatuses.Add(j == index); extractStatuses.Add(j == index);
} }
lastIndex = index + 1; lastIndex = index + 1;
} }
RINOK(extractCallback->SetTotal(importantTotalUnPacked)); if (importantTotalUnPacked != 0 || !isThereUndefinedSize)
{
RINOK(extractCallback->SetTotal(importantTotalUnPacked));
}
UInt64 currentImportantTotalUnPacked = 0; UInt64 currentImportantTotalUnPacked = 0;
UInt64 currentImportantTotalPacked = 0; UInt64 currentImportantTotalPacked = 0;
UInt64 currentUnPackSize, currentPackSize; UInt64 currentUnPackSize, currentPackSize;
@@ -1431,13 +1450,19 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
lps->Init(extractCallback, false); lps->Init(extractCallback, false);
bool solidStart = true; bool solidStart = true;
for (unsigned i = 0; i < importantIndexes.Size(); i++,
for (unsigned i = 0;;
i++,
currentImportantTotalUnPacked += currentUnPackSize, currentImportantTotalUnPacked += currentUnPackSize,
currentImportantTotalPacked += currentPackSize) currentImportantTotalPacked += currentPackSize)
{ {
lps->InSize = currentImportantTotalPacked; lps->InSize = currentImportantTotalPacked;
lps->OutSize = currentImportantTotalUnPacked; lps->OutSize = currentImportantTotalUnPacked;
RINOK(lps->SetCur()); RINOK(lps->SetCur());
if (i >= importantIndexes.Size())
break;
CMyComPtr<ISequentialOutStream> realOutStream; CMyComPtr<ISequentialOutStream> realOutStream;
Int32 askMode; Int32 askMode;
@@ -1452,8 +1477,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
const CRefItem &refItem = _refItems[index]; const CRefItem &refItem = _refItems[index];
const CItem &item = _items[refItem.ItemIndex]; const CItem &item = _items[refItem.ItemIndex];
const CItem &lastItem = _items[refItem.ItemIndex + refItem.NumItems - 1];
currentUnPackSize = item.Size;
UInt64 outSize = (UInt64)(Int64)-1;
currentUnPackSize = 0;
if (lastItem.Is_Size_Defined())
{
outSize = lastItem.Size;
currentUnPackSize = outSize;
}
currentPackSize = GetPackSize(index); currentPackSize = GetPackSize(index);
@@ -1678,12 +1710,14 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
continue; continue;
} }
HRESULT result = commonCoder->Code(inStream, outStream, &packSize, &item.Size, progress); HRESULT result = commonCoder->Code(inStream, outStream, &packSize, &outSize, progress);
if (item.IsEncrypted()) if (item.IsEncrypted())
filterStreamSpec->ReleaseInStream(); filterStreamSpec->ReleaseInStream();
const CItem &lastItem = _items[refItem.ItemIndex + refItem.NumItems - 1]; if (outSize == (UInt64)(Int64)-1)
currentUnPackSize = outStreamSpec->GetSize();
int opRes = (volsInStreamSpec->CrcIsOK && outStreamSpec->GetCRC() == lastItem.FileCRC) ? int opRes = (volsInStreamSpec->CrcIsOK && outStreamSpec->GetCRC() == lastItem.FileCRC) ?
NExtract::NOperationResult::kOK: NExtract::NOperationResult::kOK:
NExtract::NOperationResult::kCRCError; NExtract::NOperationResult::kCRCError;

View File

@@ -42,6 +42,8 @@ struct CItem
Byte Salt[8]; Byte Salt[8];
bool Is_Size_Defined() const { return Size != (UInt64)(Int64)-1; }
bool IsEncrypted() const { return (Flags & NHeader::NFile::kEncrypted) != 0; } bool IsEncrypted() const { return (Flags & NHeader::NFile::kEncrypted) != 0; }
bool IsSolid() const { return (Flags & NHeader::NFile::kSolid) != 0; } bool IsSolid() const { return (Flags & NHeader::NFile::kSolid) != 0; }
bool IsCommented() const { return (Flags & NHeader::NFile::kComment) != 0; } bool IsCommented() const { return (Flags & NHeader::NFile::kComment) != 0; }

View File

@@ -187,11 +187,15 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
UInt64 size; UInt64 size;
{ {
/*
NCOM::CPropVariant prop; NCOM::CPropVariant prop;
RINOK(volumeCallback->GetProperty(kpidSize, &prop)); RINOK(volumeCallback->GetProperty(kpidSize, &prop));
if (prop.vt != VT_UI8) if (prop.vt != VT_UI8)
return E_INVALIDARG; return E_INVALIDARG;
size = prop.uhVal.QuadPart; size = prop.uhVal.QuadPart;
*/
RINOK(stream->Seek(0, STREAM_SEEK_END, &size));
RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
} }
_totalSize += size; _totalSize += size;
@@ -217,11 +221,15 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
if (!stream) if (!stream)
break; break;
{ {
/*
NCOM::CPropVariant prop; NCOM::CPropVariant prop;
RINOK(volumeCallback->GetProperty(kpidSize, &prop)); RINOK(volumeCallback->GetProperty(kpidSize, &prop));
if (prop.vt != VT_UI8) if (prop.vt != VT_UI8)
return E_INVALIDARG; return E_INVALIDARG;
size = prop.uhVal.QuadPart; size = prop.uhVal.QuadPart;
*/
RINOK(stream->Seek(0, STREAM_SEEK_END, &size));
RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
} }
_totalSize += size; _totalSize += size;
_sizes.Add(size); _sizes.Add(size);

View File

@@ -389,7 +389,10 @@ HRESULT CInArchive::ReadFileItem(int volIndex, int fsIndex, const CLongAllocDesc
return S_FALSE; return S_FALSE;
CFile &file = Files.Back(); CFile &file = Files.Back();
const CLogVol &vol = LogVols[volIndex]; const CLogVol &vol = LogVols[volIndex];
CPartition &partition = Partitions[vol.PartitionMaps[lad.Location.PartitionRef].PartitionIndex]; unsigned partitionRef = lad.Location.PartitionRef;
if (partitionRef >= vol.PartitionMaps.Size())
return S_FALSE;
CPartition &partition = Partitions[vol.PartitionMaps[partitionRef].PartitionIndex];
UInt32 key = lad.Location.Pos; UInt32 key = lad.Location.Pos;
UInt32 value; UInt32 value;

View File

@@ -475,14 +475,10 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidPackSize: case kpidPackSize:
{ {
UInt64 size = 0;
if (si) if (si)
{ {
if (!si->Resource.IsSolidSmall()) if (!si->Resource.IsSolidSmall())
{ prop = si->Resource.PackSize;
size = si->Resource.PackSize;
prop = size;
}
else else
{ {
if (si->Resource.SolidIndex >= 0) if (si->Resource.SolidIndex >= 0)
@@ -493,12 +489,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
} }
} }
} }
else if (!item.IsDir)
prop = (UInt64)0;
break; break;
} }
case kpidSize: case kpidSize:
{ {
UInt64 size = 0;
if (si) if (si)
{ {
if (si->Resource.IsSolid()) if (si->Resource.IsSolid())
@@ -507,22 +505,19 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{ {
if (si->Resource.SolidIndex >= 0) if (si->Resource.SolidIndex >= 0)
{ {
CSolid &ss = _db.Solids[(unsigned)si->Resource.SolidIndex]; const CSolid &ss = _db.Solids[(unsigned)si->Resource.SolidIndex];
prop = ss.UnpackSize; prop = ss.UnpackSize;
} }
} }
else else
{ prop = si->Resource.PackSize;
size = si->Resource.PackSize;
prop = size;
}
} }
else else
{ prop = si->Resource.UnpackSize;
size = si->Resource.UnpackSize;
prop = size;
}
} }
else if (!item.IsDir)
prop = (UInt64)0;
break; break;
} }

View File

@@ -10,6 +10,8 @@
#include "../../Common/Defs.h" #include "../../Common/Defs.h"
#include "../../Common/IntToString.h" #include "../../Common/IntToString.h"
#include "../../Windows/PropVariant.h"
#include "../ICoder.h" #include "../ICoder.h"
#include "../Common/CWrappers.h" #include "../Common/CWrappers.h"
@@ -21,7 +23,9 @@
#include "IArchive.h" #include "IArchive.h"
#ifndef EXTRACT_ONLY
#include "Common/HandlerOut.h" #include "Common/HandlerOut.h"
#endif
#include "XzHandler.h" #include "XzHandler.h"
@@ -83,14 +87,19 @@ class CHandler:
CMyComPtr<IInStream> _stream; CMyComPtr<IInStream> _stream;
CMyComPtr<ISequentialInStream> _seqStream; CMyComPtr<ISequentialInStream> _seqStream;
UInt32 _filterId;
AString _methodsString; AString _methodsString;
#ifndef EXTRACT_ONLY
UInt32 _filterId;
void Init() void Init()
{ {
_filterId = 0; _filterId = 0;
CMultiMethodProps::Init(); CMultiMethodProps::Init();
} }
#endif
HRESULT Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCallback *callback); HRESULT Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCallback *callback);
@@ -126,9 +135,12 @@ public:
CHandler::CHandler() CHandler::CHandler()
{ {
#ifndef EXTRACT_ONLY
Init(); Init();
#endif
} }
static const Byte kProps[] = static const Byte kProps[] =
{ {
kpidSize, kpidSize,

View File

@@ -12,6 +12,7 @@
#include "../../IPassword.h" #include "../../IPassword.h"
#include "../../Common/FilterCoder.h" #include "../../Common/FilterCoder.h"
#include "../../Common/LimitedStreams.h"
#include "../../Common/ProgressUtils.h" #include "../../Common/ProgressUtils.h"
#include "../../Common/StreamObjects.h" #include "../../Common/StreamObjects.h"
#include "../../Common/StreamUtils.h" #include "../../Common/StreamUtils.h"
@@ -142,14 +143,19 @@ static const Byte kProps[] =
kpidCRC, kpidCRC,
kpidMethod, kpidMethod,
kpidHostOS, kpidHostOS,
kpidUnpackVer kpidUnpackVer,
kpidVolumeIndex
}; };
static const Byte kArcProps[] = static const Byte kArcProps[] =
{ {
kpidEmbeddedStubSize, kpidEmbeddedStubSize,
kpidBit64, kpidBit64,
kpidComment kpidComment,
kpidTotalPhySize,
kpidIsVolume,
kpidVolumeIndex,
kpidNumVolumes
}; };
CHandler::CHandler() CHandler::CHandler()
@@ -175,18 +181,23 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{ {
case kpidBit64: if (m_Archive.IsZip64) prop = m_Archive.IsZip64; break; case kpidBit64: if (m_Archive.IsZip64) prop = m_Archive.IsZip64; break;
case kpidComment: if (m_Archive.ArcInfo.Comment.Size() != 0) prop = MultiByteToUnicodeString(BytesToString(m_Archive.ArcInfo.Comment), CP_ACP); break; case kpidComment: if (m_Archive.ArcInfo.Comment.Size() != 0) prop = MultiByteToUnicodeString(BytesToString(m_Archive.ArcInfo.Comment), CP_ACP); break;
case kpidPhySize: prop = m_Archive.ArcInfo.GetPhySize(); break;
case kpidOffset: /* if (m_Archive.ArcInfo.Base != 0) */ case kpidPhySize: prop = m_Archive.GetPhySize(); break;
prop = m_Archive.ArcInfo.Base; break; case kpidOffset: prop = m_Archive.GetOffset(); break;
case kpidEmbeddedStubSize: case kpidEmbeddedStubSize:
{ {
UInt64 stubSize = m_Archive.ArcInfo.GetEmbeddedStubSize(); UInt64 stubSize = m_Archive.GetEmbeddedStubSize();
if (stubSize != 0) if (stubSize != 0)
prop = stubSize; prop = stubSize;
break; break;
} }
case kpidTotalPhySize: if (m_Archive.IsMultiVol) prop = m_Archive.Vols.GetTotalSize(); break;
case kpidVolumeIndex: if (m_Archive.IsMultiVol) prop = (UInt32)m_Archive.Vols.StartVolIndex; break;
case kpidIsVolume: if (m_Archive.IsMultiVol) prop = true; break;
case kpidNumVolumes: if (m_Archive.IsMultiVol) prop = (UInt32)m_Archive.Vols.Streams.Size(); break;
case kpidWarningFlags: case kpidWarningFlags:
{ {
UInt32 v = 0; UInt32 v = 0;
@@ -197,6 +208,18 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
break; break;
} }
case kpidError:
{
if (!m_Archive.Vols.MissingName.IsEmpty())
{
UString s;
s.SetFromAscii("Missing volume : ");
s += m_Archive.Vols.MissingName;
prop = s;
}
break;
}
case kpidErrorFlags: case kpidErrorFlags:
{ {
UInt32 v = 0; UInt32 v = 0;
@@ -209,7 +232,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
but the stream has access only to zip part. but the stream has access only to zip part.
In that case we ignore UnavailableStart error. In that case we ignore UnavailableStart error.
maybe we must show warning in that case. */ maybe we must show warning in that case. */
UInt64 stubSize = m_Archive.ArcInfo.GetEmbeddedStubSize(); UInt64 stubSize = m_Archive.GetEmbeddedStubSize();
if (stubSize < (UInt64)-m_Archive.ArcInfo.Base) if (stubSize < (UInt64)-m_Archive.ArcInfo.Base)
v |= kpv_ErrorFlags_UnavailableStart; v |= kpv_ErrorFlags_UnavailableStart;
} }
@@ -429,6 +452,10 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidUnpackVer: case kpidUnpackVer:
prop = (UInt32)item.ExtractVersion.Version; prop = (UInt32)item.ExtractVersion.Version;
break; break;
case kpidVolumeIndex:
prop = item.Disk;
break;
} }
prop.Detach(value); prop.Detach(value);
@@ -436,30 +463,6 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
COM_TRY_END COM_TRY_END
} }
class CProgressImp: public CProgressVirt
{
CMyComPtr<IArchiveOpenCallback> _callback;
public:
virtual HRESULT SetCompletedLocal(UInt64 numFiles, UInt64 numBytes);
virtual HRESULT SetTotalCD(UInt64 numFiles);
virtual HRESULT SetCompletedCD(UInt64 numFiles);
CProgressImp(IArchiveOpenCallback *callback): _callback(callback) {}
};
HRESULT CProgressImp::SetCompletedLocal(UInt64 numFiles, UInt64 numBytes)
{
return _callback->SetCompleted(&numFiles, &numBytes);
}
HRESULT CProgressImp::SetTotalCD(UInt64 numFiles)
{
return _callback->SetTotal(&numFiles, NULL);
}
HRESULT CProgressImp::SetCompletedCD(UInt64 numFiles)
{
return _callback->SetCompleted(&numFiles, NULL);
}
STDMETHODIMP CHandler::Open(IInStream *inStream, STDMETHODIMP CHandler::Open(IInStream *inStream,
const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback) const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback)
@@ -468,9 +471,13 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
try try
{ {
Close(); Close();
RINOK(m_Archive.Open(inStream, maxCheckStartPosition)); HRESULT res = m_Archive.Open(inStream, maxCheckStartPosition, callback, m_Items);
CProgressImp progressImp(callback); if (res != S_OK)
return m_Archive.ReadHeaders(m_Items, callback ? &progressImp : NULL); {
m_Items.Clear();
m_Archive.ClearRefs();
}
return res;
} }
catch(...) { Close(); throw; } catch(...) { Close(); throw; }
COM_TRY_END COM_TRY_END
@@ -483,8 +490,6 @@ STDMETHODIMP CHandler::Close()
return S_OK; return S_OK;
} }
//////////////////////////////////////
// CHandler::DecompressItems
class CLzmaDecoder: class CLzmaDecoder:
public ICompressCoder, public ICompressCoder,
@@ -550,6 +555,8 @@ struct CMethodItem
CMyComPtr<ICompressCoder> Coder; CMyComPtr<ICompressCoder> Coder;
}; };
class CZipDecoder class CZipDecoder
{ {
NCrypto::NZip::CDecoder *_zipCryptoDecoderSpec; NCrypto::NZip::CDecoder *_zipCryptoDecoderSpec;
@@ -584,6 +591,24 @@ public:
Int32 &res); Int32 &res);
}; };
static HRESULT SkipStreamData(ISequentialInStream *stream, UInt64 size)
{
const size_t kBufSize = 1 << 12;
Byte buf[kBufSize];
for (;;)
{
if (size == 0)
return S_OK;
size_t curSize = kBufSize;
if (curSize > size)
curSize = (size_t)size;
RINOK(ReadStream_FALSE(stream, buf, curSize));
size -= curSize;
}
}
HRESULT CZipDecoder::Decode( HRESULT CZipDecoder::Decode(
DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS
CInArchive &archive, const CItemEx &item, CInArchive &archive, const CItemEx &item,
@@ -634,9 +659,11 @@ HRESULT CZipDecoder::Decode(
outStreamSpec->SetStream(realOutStream); outStreamSpec->SetStream(realOutStream);
outStreamSpec->Init(needCRC); outStreamSpec->Init(needCRC);
UInt64 authenticationPos; CMyComPtr<ISequentialInStream> packStream;
CMyComPtr<ISequentialInStream> inStream; CLimitedSequentialInStream *limitedStreamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream(limitedStreamSpec);
{ {
UInt64 packSize = item.PackSize; UInt64 packSize = item.PackSize;
if (wzAesMode) if (wzAesMode)
@@ -645,9 +672,14 @@ HRESULT CZipDecoder::Decode(
return S_OK; return S_OK;
packSize -= NCrypto::NWzAes::kMacSize; packSize -= NCrypto::NWzAes::kMacSize;
} }
UInt64 dataPos = item.GetDataPosition(); RINOK(archive.GetItemStream(item, true, packStream));
inStream.Attach(archive.CreateLimitedStream(dataPos, packSize)); if (!packStream)
authenticationPos = dataPos + packSize; {
res = NExtract::NOperationResult::kUnavailable;
return S_OK;
}
limitedStreamSpec->SetStream(packStream);
limitedStreamSpec->Init(packSize);
} }
CMyComPtr<ICompressFilter> cryptoFilter; CMyComPtr<ICompressFilter> cryptoFilter;
@@ -912,9 +944,15 @@ HRESULT CZipDecoder::Decode(
bool authOk = true; bool authOk = true;
if (needCRC) if (needCRC)
crcOK = (outStreamSpec->GetCRC() == item.Crc); crcOK = (outStreamSpec->GetCRC() == item.Crc);
if (wzAesMode) if (wzAesMode)
{ {
inStream.Attach(archive.CreateLimitedStream(authenticationPos, NCrypto::NWzAes::kMacSize)); const UInt64 rem = limitedStreamSpec->GetRem();
if (rem != 0)
if (SkipStreamData(inStream, rem) != S_OK)
authOk = false;
limitedStreamSpec->Init(NCrypto::NWzAes::kMacSize);
if (_wzAesDecoderSpec->CheckMac(inStream, authOk) != S_OK) if (_wzAesDecoderSpec->CheckMac(inStream, authOk) != S_OK)
authOk = false; authOk = false;
} }
@@ -988,16 +1026,21 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnavailable)); RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnavailable));
continue; continue;
} }
if (!item.FromLocal) if (!item.FromLocal)
{ {
HRESULT res = m_Archive.ReadLocalItemAfterCdItem(item); bool isAvail = true;
HRESULT res = m_Archive.ReadLocalItemAfterCdItem(item, isAvail);
if (res == S_FALSE) if (res == S_FALSE)
{ {
if (item.IsDir() || realOutStream || testMode) if (item.IsDir() || realOutStream || testMode)
{ {
RINOK(extractCallback->PrepareOperation(askMode)); RINOK(extractCallback->PrepareOperation(askMode));
realOutStream.Release(); realOutStream.Release();
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kHeadersError)); RINOK(extractCallback->SetOperationResult(
isAvail ?
NExtract::NOperationResult::kHeadersError :
NExtract::NOperationResult::kUnavailable));
} }
continue; continue;
} }
@@ -1034,6 +1077,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
RINOK(extractCallback->SetOperationResult(res)) RINOK(extractCallback->SetOperationResult(res))
} }
lps->InSize = currentTotalPacked; lps->InSize = currentTotalPacked;
lps->OutSize = currentTotalUnPacked; lps->OutSize = currentTotalUnPacked;
return lps->SetCur(); return lps->SetCur();

View File

@@ -18,9 +18,8 @@ namespace NSignature
const UInt32 kEcd = 0x06054B50; const UInt32 kEcd = 0x06054B50;
const UInt32 kEcd64 = 0x06064B50; const UInt32 kEcd64 = 0x06064B50;
const UInt32 kEcd64Locator = 0x07064B50; const UInt32 kEcd64Locator = 0x07064B50;
const UInt32 kSpan = 0x08074B50;
// const UInt32 kSpan = 0x08074B50; const UInt32 kNoSpan = 0x30304B50; // PK00, replaces kSpan, if there is only 1 segment
const UInt32 kNoSpan = 0x30304b50; // PK00, replaces kSpan, if there is only 1 segment
} }
const unsigned kLocalHeaderSize = 4 + 26; // including signature const unsigned kLocalHeaderSize = 4 + 26; // including signature

View File

File diff suppressed because it is too large Load Diff

View File

@@ -28,6 +28,7 @@ public:
{ return LocalHeaderPos + LocalFullHeaderSize; } { return LocalHeaderPos + LocalFullHeaderSize; }
}; };
struct CInArchiveInfo struct CInArchiveInfo
{ {
Int64 Base; /* Base offset of start of archive in stream. Int64 Base; /* Base offset of start of archive in stream.
@@ -40,74 +41,195 @@ struct CInArchiveInfo
Base = ArcInfo.MarkerPos; */ Base = ArcInfo.MarkerPos; */
/* The following *Pos variables contain absolute offsets in Stream */ /* The following *Pos variables contain absolute offsets in Stream */
UInt64 MarkerPos; /* Pos of first signature, it can point to PK00 signature
UInt64 MarkerPos; /* Pos of first signature, it can point to kSpan/kNoSpan signature
= MarkerPos2 in most archives = MarkerPos2 in most archives
= MarkerPos2 - 4 if there is PK00 signature */ = MarkerPos2 - 4 if there is kSpan/kNoSpan signature */
UInt64 MarkerPos2; // Pos of first local item signature in stream UInt64 MarkerPos2; // Pos of first local item signature in stream
UInt64 FinishPos; // Finish pos of archive data UInt64 FinishPos; // Finish pos of archive data in starting volume
UInt64 FileEndPos; // Finish pos of stream UInt64 FileEndPos; // Finish pos of stream
UInt64 FirstItemRelatOffset; /* Relative offset of first local (read from cd) (relative to Base). UInt64 FirstItemRelatOffset; /* Relative offset of first local (read from cd) (relative to Base).
= 0 in most archives = 0 in most archives
= size of stub for some SFXs */ = size of stub for some SFXs */
bool CdWasRead; bool CdWasRead;
bool IsSpanMode;
bool ThereIsTail;
// UInt32 BaseVolIndex;
CByteBuffer Comment; CByteBuffer Comment;
CInArchiveInfo(): Base(0), MarkerPos(0), MarkerPos2(0), FinishPos(0), FileEndPos(0),
FirstItemRelatOffset(0), CdWasRead(false) {}
UInt64 GetPhySize() const { return FinishPos - Base; }
UInt64 GetEmbeddedStubSize() const
{
if (CdWasRead)
return FirstItemRelatOffset;
return MarkerPos2 - Base;
}
bool ThereIsTail() const { return FileEndPos > FinishPos; }
CInArchiveInfo():
Base(0),
MarkerPos(0),
MarkerPos2(0),
FinishPos(0),
FileEndPos(0),
FirstItemRelatOffset(0),
CdWasRead(false),
IsSpanMode(false),
ThereIsTail(false)
// BaseVolIndex(0)
{}
void Clear() void Clear()
{ {
// BaseVolIndex = 0;
Base = 0; Base = 0;
MarkerPos = 0; MarkerPos = 0;
MarkerPos2 = 0; MarkerPos2 = 0;
FinishPos = 0; FinishPos = 0;
FileEndPos = 0; FileEndPos = 0;
ThereIsTail = false;
FirstItemRelatOffset = 0; FirstItemRelatOffset = 0;
CdWasRead = false; CdWasRead = false;
IsSpanMode = false;
Comment.Free(); Comment.Free();
} }
}; };
struct CProgressVirt
{
virtual HRESULT SetCompletedLocal(UInt64 numFiles, UInt64 numBytes) = 0;
virtual HRESULT SetTotalCD(UInt64 numFiles) = 0;
virtual HRESULT SetCompletedCD(UInt64 numFiles) = 0;
};
struct CCdInfo struct CCdInfo
{ {
// 64
UInt16 VersionMade;
UInt16 VersionNeedExtract;
// old zip
UInt32 ThisDisk;
UInt32 CdDisk;
UInt64 NumEntries_in_ThisDisk;
UInt64 NumEntries; UInt64 NumEntries;
UInt64 Size; UInt64 Size;
UInt64 Offset; UInt64 Offset;
void ParseEcd(const Byte *p); UInt16 CommentSize;
void ParseEcd64(const Byte *p);
CCdInfo() { memset(this, 0, sizeof(*this)); }
void ParseEcd32(const Byte *p); // (p) includes signature
void ParseEcd64e(const Byte *p); // (p) exclude signature
}; };
class CVols
{
public:
struct CSubStreamInfo
{
CMyComPtr<IInStream> Stream;
UInt64 Size;
CSubStreamInfo(): Size(0) {}
};
CObjectVector<CSubStreamInfo> Streams;
int StreamIndex;
bool NeedSeek;
CMyComPtr<IInStream> ZipStream;
bool StartIsExe; // is .exe
bool StartIsZ; // is .zip or .zNN
bool StartIsZip; // is .zip
bool IsUpperCase;
Int32 StartVolIndex; // = (NN - 1), if StartStream is .zNN
Int32 StartParsingVol; // if we need local parsing, we must use that stream
unsigned NumVols;
int EndVolIndex; // index of last volume (ecd volume),
// -1, if is not multivol
UString BaseName; // including '.'
UString MissingName;
CCdInfo ecd;
bool ecd_wasRead;
void Clear()
{
StreamIndex = -1;
NeedSeek = false;
StartIsExe = false;
StartIsZ = false;
StartIsZip = false;
IsUpperCase = false;
StartVolIndex = -1;
StartParsingVol = 0;
NumVols = 0;
EndVolIndex = -1;
BaseName.Empty();
MissingName.Empty();
ecd_wasRead = false;
Streams.Clear();
ZipStream.Release();
}
HRESULT ParseArcName(IArchiveOpenVolumeCallback *volCallback);
HRESULT Read(void *data, UInt32 size, UInt32 *processedSize);
UInt64 GetTotalSize() const
{
UInt64 total = 0;
FOR_VECTOR (i, Streams)
total += Streams[i].Size;
return total;
}
};
class CVolStream:
public ISequentialInStream,
public CMyUnknownImp
{
public:
CVols *Vols;
MY_UNKNOWN_IMP1(ISequentialInStream)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
};
class CInArchive class CInArchive
{ {
CInBuffer _inBuffer; CInBuffer _inBuffer;
bool _inBufMode; bool _inBufMode;
UInt32 m_Signature; UInt32 m_Signature;
UInt64 m_Position; UInt64 m_Position;
UInt64 _processedCnt;
bool CanStartNewVol;
CMyComPtr<IInStream> StreamRef;
IInStream *Stream;
IInStream *StartStream;
bool IsArcOpen;
HRESULT ReadVols2(IArchiveOpenVolumeCallback *volCallback,
unsigned start, int lastDisk, int zipDisk, unsigned numMissingVolsMax, unsigned &numMissingVols);
HRESULT ReadVols();
HRESULT Seek(UInt64 offset); HRESULT Seek(UInt64 offset);
HRESULT FindAndReadMarker(IInStream *stream, const UInt64 *searchHeaderSizeLimit); HRESULT FindMarker(IInStream *stream, const UInt64 *searchLimit);
HRESULT IncreaseRealPosition(Int64 addValue); HRESULT IncreaseRealPosition(Int64 addValue, bool &isFinished);
HRESULT ReadBytes(void *data, UInt32 size, UInt32 *processedSize); HRESULT ReadBytes(void *data, UInt32 size, UInt32 *processedSize);
void SafeReadBytes(void *data, unsigned size); void SafeReadBytes(void *data, unsigned size);
@@ -126,12 +248,14 @@ class CInArchive
HRESULT ReadLocalItemDescriptor(CItemEx &item); HRESULT ReadLocalItemDescriptor(CItemEx &item);
HRESULT ReadCdItem(CItemEx &item); HRESULT ReadCdItem(CItemEx &item);
HRESULT TryEcd64(UInt64 offset, CCdInfo &cdInfo); HRESULT TryEcd64(UInt64 offset, CCdInfo &cdInfo);
HRESULT FindCd(CCdInfo &cdInfo); HRESULT FindCd(bool checkOffsetMode);
HRESULT TryReadCd(CObjectVector<CItemEx> &items, UInt64 cdOffset, UInt64 cdSize, CProgressVirt *progress); HRESULT TryReadCd(CObjectVector<CItemEx> &items, const CCdInfo &cdInfo, UInt64 cdOffset, UInt64 cdSize);
HRESULT ReadCd(CObjectVector<CItemEx> &items, UInt64 &cdOffset, UInt64 &cdSize, CProgressVirt *progress); HRESULT ReadCd(CObjectVector<CItemEx> &items, UInt32 &cdDisk, UInt64 &cdOffset, UInt64 &cdSize);
HRESULT ReadLocals(CObjectVector<CItemEx> &localItems, CProgressVirt *progress); HRESULT ReadLocals(CObjectVector<CItemEx> &localItems);
HRESULT ReadHeaders2(CObjectVector<CItemEx> &items, CProgressVirt *progress); HRESULT ReadHeaders2(CObjectVector<CItemEx> &items);
HRESULT GetVolStream(unsigned vol, UInt64 pos, CMyComPtr<ISequentialInStream> &stream);
public: public:
CInArchiveInfo ArcInfo; CInArchiveInfo ArcInfo;
@@ -142,46 +266,87 @@ public:
bool ExtraMinorError; bool ExtraMinorError;
bool UnexpectedEnd; bool UnexpectedEnd;
bool NoCentralDir; bool NoCentralDir;
CMyComPtr<IInStream> Stream;
void Close();
HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit);
HRESULT ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *progress);
bool IsOpen() const { return Stream != NULL; } bool MarkerIsFound;
bool AreThereErrors() const { return HeadersError || UnexpectedEnd; }
bool IsMultiVol;
bool UseDisk_in_SingleVol;
UInt32 EcdVolIndex;
CVols Vols;
IArchiveOpenCallback *Callback;
CInArchive(): Stream(NULL), Callback(NULL), IsArcOpen(false) {}
UInt64 GetPhySize() const
{
if (IsMultiVol)
return ArcInfo.FinishPos;
else
return ArcInfo.FinishPos - ArcInfo.Base;
}
UInt64 GetOffset() const
{
if (IsMultiVol)
return 0;
else
return ArcInfo.Base;
}
void ClearRefs();
void Close();
HRESULT Open(IInStream *stream, const UInt64 *searchLimit, IArchiveOpenCallback *callback, CObjectVector<CItemEx> &items);
HRESULT ReadHeaders(CObjectVector<CItemEx> &items);
bool IsOpen() const { return IsArcOpen; }
bool AreThereErrors() const
{
return HeadersError
|| UnexpectedEnd
|| !Vols.MissingName.IsEmpty();
}
bool IsLocalOffsetOK(const CItemEx &item) const bool IsLocalOffsetOK(const CItemEx &item) const
{ {
if (item.FromLocal) if (item.FromLocal)
return true; return true;
return /* ArcInfo.Base >= 0 || */ ArcInfo.Base + (Int64)item.LocalHeaderPos >= 0; return (Int64)GetOffset() + (Int64)item.LocalHeaderPos >= 0;
} }
HRESULT ReadLocalItemAfterCdItem(CItemEx &item); UInt64 GetEmbeddedStubSize() const
{
if (ArcInfo.CdWasRead)
return ArcInfo.FirstItemRelatOffset;
if (IsMultiVol)
return 0;
return ArcInfo.MarkerPos2 - ArcInfo.Base;
}
HRESULT ReadLocalItemAfterCdItem(CItemEx &item, bool &isAvail);
HRESULT ReadLocalItemAfterCdItemFull(CItemEx &item); HRESULT ReadLocalItemAfterCdItemFull(CItemEx &item);
ISequentialInStream *CreateLimitedStream(UInt64 position, UInt64 size); HRESULT GetItemStream(const CItemEx &item, bool seekPackData, CMyComPtr<ISequentialInStream> &stream);
UInt64 GetOffsetInStream(UInt64 offsetFromArc) const { return ArcInfo.Base + offsetFromArc; } IInStream *GetBaseStream() { return StreamRef; }
bool CanUpdate() const bool CanUpdate() const
{ {
if (AreThereErrors()) if (AreThereErrors()
return false; || IsMultiVol
if (ArcInfo.Base < 0) || ArcInfo.Base < 0
return false; || (Int64)ArcInfo.MarkerPos2 < ArcInfo.Base
if ((Int64)ArcInfo.MarkerPos2 < ArcInfo.Base) || ArcInfo.ThereIsTail
|| GetEmbeddedStubSize() != 0)
return false; return false;
// 7-zip probably can update archives with embedded stubs. // 7-zip probably can update archives with embedded stubs.
// we just disable that feature for more safety. // we just disable that feature for more safety.
if (ArcInfo.GetEmbeddedStubSize() != 0)
return false;
if (ArcInfo.ThereIsTail())
return false;
return true; return true;
} }
}; };

View File

@@ -199,6 +199,8 @@ public:
UInt64 PackSize; UInt64 PackSize;
UInt32 Time; UInt32 Time;
UInt32 Crc; UInt32 Crc;
UInt32 Disk;
AString Name; AString Name;

View File

@@ -12,10 +12,11 @@ namespace NZip {
static const Byte k_Signature[] = { static const Byte k_Signature[] = {
4, 0x50, 0x4B, 0x03, 0x04, 4, 0x50, 0x4B, 0x03, 0x04,
4, 0x50, 0x4B, 0x05, 0x06, 4, 0x50, 0x4B, 0x05, 0x06,
6, 0x50, 0x4B, 0x07, 0x08, 0x50, 0x4B,
6, 0x50, 0x4B, 0x30, 0x30, 0x50, 0x4B }; 6, 0x50, 0x4B, 0x30, 0x30, 0x50, 0x4B };
REGISTER_ARC_IO( REGISTER_ARC_IO(
"zip", "zip zipx jar xpi odt ods docx xlsx epub", 0, 1, "zip", "zip z01 zipx jar xpi odt ods docx xlsx epub", 0, 1,
k_Signature, k_Signature,
0, 0,
NArcInfoFlags::kFindSignature | NArcInfoFlags::kFindSignature |

View File

@@ -52,16 +52,6 @@ static HRESULT CopyBlockToArchive(ISequentialInStream *inStream, UInt64 size,
return NCompress::CopyStream_ExactSize(inStream, outStream, size, progress); return NCompress::CopyStream_ExactSize(inStream, outStream, size, progress);
} }
static HRESULT WriteRange(IInStream *inStream, COutArchive &outArchive,
const CUpdateRange &range, ICompressProgressInfo *progress)
{
UInt64 position;
RINOK(inStream->Seek(range.Position, STREAM_SEEK_SET, &position));
RINOK(CopyBlockToArchive(inStream, range.Size, outArchive, progress));
return progress->SetRatioInfo(&range.Size, &range.Size);
}
static void SetFileHeader( static void SetFileHeader(
COutArchive &archive, COutArchive &archive,
const CCompressionMethodMode &options, const CCompressionMethodMode &options,
@@ -358,9 +348,12 @@ static HRESULT UpdateItemOldData(
return E_NOTIMPL; return E_NOTIMPL;
// use old name size. // use old name size.
// CUpdateRange range(item.GetLocalExtraPosition(), item.LocalExtraSize + item.PackSize);
CUpdateRange range(inArchive->GetOffsetInStream(itemEx.GetDataPosition()), itemEx.PackSize);
CMyComPtr<ISequentialInStream> packStream;
RINOK(inArchive->GetItemStream(itemEx, true, packStream));
if (!packStream)
return E_NOTIMPL;
// we keep ExternalAttrib and some another properties from old archive // we keep ExternalAttrib and some another properties from old archive
// item.ExternalAttrib = ui.Attrib; // item.ExternalAttrib = ui.Attrib;
@@ -378,19 +371,27 @@ static HRESULT UpdateItemOldData(
archive.PrepareWriteCompressedData2(item.Name.Len(), item.Size, item.PackSize, item.LocalExtra.HasWzAes()); archive.PrepareWriteCompressedData2(item.Name.Len(), item.Size, item.PackSize, item.LocalExtra.HasWzAes());
archive.WriteLocalHeader(item); archive.WriteLocalHeader(item);
RINOK(WriteRange(inArchive->Stream, archive, range, progress));
complexity += range.Size; RINOK(CopyBlockToArchive(packStream, itemEx.PackSize, archive, progress));
complexity += itemEx.PackSize;
} }
else else
{ {
CUpdateRange range(inArchive->GetOffsetInStream(itemEx.LocalHeaderPos), itemEx.GetLocalFullSize()); CMyComPtr<ISequentialInStream> packStream;
RINOK(inArchive->GetItemStream(itemEx, false, packStream));
if (!packStream)
return E_NOTIMPL;
// set new header position // set new header position
item.LocalHeaderPos = archive.GetCurPos(); item.LocalHeaderPos = archive.GetCurPos();
RINOK(WriteRange(inArchive->Stream, archive, range, progress)); const UInt64 rangeSize = itemEx.GetLocalFullSize();
complexity += range.Size;
archive.MoveCurPos(range.Size); RINOK(CopyBlockToArchive(packStream, rangeSize, archive, progress));
complexity += rangeSize;
archive.MoveCurPos(rangeSize);
} }
return S_OK; return S_OK;
@@ -1191,10 +1192,11 @@ HRESULT Update(
if (inArchive) if (inArchive)
{ {
if (inArchive->ArcInfo.Base > 0 && !removeSfx) if (!inArchive->IsMultiVol && inArchive->ArcInfo.Base > 0 && !removeSfx)
{ {
RINOK(inArchive->Stream->Seek(0, STREAM_SEEK_SET, NULL)); IInStream *baseStream = inArchive->GetBaseStream();
RINOK(NCompress::CopyStream_ExactSize(inArchive->Stream, outStreamReal, inArchive->ArcInfo.Base, NULL)); RINOK(baseStream->Seek(0, STREAM_SEEK_SET, NULL));
RINOK(NCompress::CopyStream_ExactSize(baseStream, outStreamReal, inArchive->ArcInfo.Base, NULL));
} }
} }
@@ -1210,11 +1212,12 @@ HRESULT Update(
if (inArchive) if (inArchive)
{ {
if ((Int64)inArchive->ArcInfo.MarkerPos2 > inArchive->ArcInfo.Base) if (!inArchive->IsMultiVol && (Int64)inArchive->ArcInfo.MarkerPos2 > inArchive->ArcInfo.Base)
{ {
RINOK(inArchive->Stream->Seek(inArchive->ArcInfo.Base, STREAM_SEEK_SET, NULL)); IInStream *baseStream = inArchive->GetBaseStream();
RINOK(baseStream->Seek(inArchive->ArcInfo.Base, STREAM_SEEK_SET, NULL));
UInt64 embStubSize = inArchive->ArcInfo.MarkerPos2 - inArchive->ArcInfo.Base; UInt64 embStubSize = inArchive->ArcInfo.MarkerPos2 - inArchive->ArcInfo.Base;
RINOK(NCompress::CopyStream_ExactSize(inArchive->Stream, outStream, embStubSize, NULL)); RINOK(NCompress::CopyStream_ExactSize(baseStream, outStream, embStubSize, NULL));
outArchive.MoveCurPos(embStubSize); outArchive.MoveCurPos(embStubSize);
} }
} }

View File

@@ -5,16 +5,19 @@
#include <string.h> #include <string.h>
#include "LimitedStreams.h" #include "LimitedStreams.h"
#include "../../Common/Defs.h"
STDMETHODIMP CLimitedSequentialInStream::Read(void *data, UInt32 size, UInt32 *processedSize) STDMETHODIMP CLimitedSequentialInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{ {
UInt32 realProcessedSize = 0; UInt32 realProcessedSize = 0;
UInt32 sizeToRead = (UInt32)MyMin((_size - _pos), (UInt64)size);
HRESULT result = S_OK;
if (sizeToRead > 0)
{ {
result = _stream->Read(data, sizeToRead, &realProcessedSize); const UInt64 rem = _size - _pos;
if (size > rem)
size = (UInt32)rem;
}
HRESULT result = S_OK;
if (size != 0)
{
result = _stream->Read(data, size, &realProcessedSize);
_pos += realProcessedSize; _pos += realProcessedSize;
if (realProcessedSize == 0) if (realProcessedSize == 0)
_wasFinished = true; _wasFinished = true;
@@ -34,9 +37,11 @@ STDMETHODIMP CLimitedInStream::Read(void *data, UInt32 size, UInt32 *processedSi
return S_OK; return S_OK;
// return (_virtPos == _size) ? S_OK: E_FAIL; // ERROR_HANDLE_EOF // return (_virtPos == _size) ? S_OK: E_FAIL; // ERROR_HANDLE_EOF
} }
UInt64 rem = _size - _virtPos; {
if (rem < size) const UInt64 rem = _size - _virtPos;
size = (UInt32)rem; if (size > rem)
size = (UInt32)rem;
}
UInt64 newPos = _startOffset + _virtPos; UInt64 newPos = _startOffset + _virtPos;
if (newPos != _physPos) if (newPos != _physPos)
{ {

View File

@@ -30,6 +30,7 @@ public:
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
UInt64 GetSize() const { return _pos; } UInt64 GetSize() const { return _pos; }
UInt64 GetRem() const { return _size - _pos; }
bool WasFinished() const { return _wasFinished; } bool WasFinished() const { return _wasFinished; }
}; };

View File

@@ -783,7 +783,7 @@ void CState::ThreadFunc()
} }
packSize = Decoder->Base.BitDecoder.GetProcessedSize(); packSize = Decoder->Base.BitDecoder.GetProcessedSize();
} }
catch(const CInBufferException &e) { res = e.ErrorCode; if (res != S_OK) res = E_FAIL; } catch(const CInBufferException &e) { res = e.ErrorCode; if (res == S_OK) res = E_FAIL; }
catch(...) { res = E_FAIL; } catch(...) { res = E_FAIL; }
if (res != S_OK) if (res != S_OK)
{ {
@@ -809,7 +809,7 @@ void CState::ThreadFunc()
res = S_FALSE; res = S_FALSE;
} }
} }
catch(const COutBufferException &e) { res = e.ErrorCode; if (res != S_OK) res = E_FAIL; } catch(const COutBufferException &e) { res = e.ErrorCode; if (res == S_OK) res = E_FAIL; }
catch(...) { res = E_FAIL; } catch(...) { res = E_FAIL; }
if (res != S_OK) if (res != S_OK)
{ {

View File

@@ -214,11 +214,13 @@ public:
HRESULT Flush() { return m_OutStream.Flush(); } HRESULT Flush() { return m_OutStream.Flush(); }
MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
MY_UNKNOWN_IMP2(ICompressSetCoderMt, ICompressSetCoderProperties) MY_QUERYINTERFACE_ENTRY(ICompressSetCoderMt)
#else
MY_UNKNOWN_IMP1(ICompressSetCoderProperties)
#endif #endif
MY_QUERYINTERFACE_ENTRY(ICompressSetCoderProperties)
MY_QUERYINTERFACE_END
MY_ADDREF_RELEASE
HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);

View File

@@ -5,14 +5,21 @@
#include "../Common/RegisterCodec.h" #include "../Common/RegisterCodec.h"
#include "BZip2Decoder.h" #include "BZip2Decoder.h"
REGISTER_CODEC_CREATE(CreateDec, NCompress::NBZip2::CDecoder)
#if !defined(EXTRACT_ONLY) && !defined(BZIP2_EXTRACT_ONLY) #if !defined(EXTRACT_ONLY) && !defined(BZIP2_EXTRACT_ONLY)
#include "BZip2Encoder.h" #include "BZip2Encoder.h"
REGISTER_CODEC_CREATE(CreateEnc, NCompress::NBZip2::CEncoder) #endif
namespace NCompress {
namespace NBZip2 {
REGISTER_CODEC_CREATE(CreateDec, CDecoder)
#if !defined(EXTRACT_ONLY) && !defined(BZIP2_EXTRACT_ONLY)
REGISTER_CODEC_CREATE(CreateEnc, CEncoder)
#else #else
#define CreateEnc NULL #define CreateEnc NULL
#endif #endif
REGISTER_CODEC_2(BZip2, CreateDec, CreateEnc, 0x40202, "BZip2") REGISTER_CODEC_2(BZip2, CreateDec, CreateEnc, 0x40202, "BZip2")
}}

View File

@@ -6,9 +6,12 @@
#include "Bcj2Coder.h" #include "Bcj2Coder.h"
REGISTER_CODEC_CREATE_2(CreateCodec, NCompress::NBcj2::CDecoder(), ICompressCoder2) namespace NCompress {
namespace NBcj2 {
REGISTER_CODEC_CREATE_2(CreateCodec, CDecoder(), ICompressCoder2)
#ifndef EXTRACT_ONLY #ifndef EXTRACT_ONLY
REGISTER_CODEC_CREATE_2(CreateCodecOut, NCompress::NBcj2::CEncoder(), ICompressCoder2) REGISTER_CODEC_CREATE_2(CreateCodecOut, CEncoder(), ICompressCoder2)
#else #else
#define CreateCodecOut NULL #define CreateCodecOut NULL
#endif #endif
@@ -17,3 +20,5 @@ REGISTER_CODEC_VAR
{ CreateCodec, CreateCodecOut, 0x303011B, "BCJ2", 4, false }; { CreateCodec, CreateCodecOut, 0x303011B, "BCJ2", 4, false };
REGISTER_CODEC(BCJ2) REGISTER_CODEC(BCJ2)
}}

View File

@@ -4,16 +4,21 @@
#include "BcjCoder.h" #include "BcjCoder.h"
STDMETHODIMP CBcjCoder::Init() namespace NCompress {
namespace NBcj {
STDMETHODIMP CCoder::Init()
{ {
_bufferPos = 0; _bufferPos = 0;
x86_Convert_Init(_prevMask); x86_Convert_Init(_prevMask);
return S_OK; return S_OK;
} }
STDMETHODIMP_(UInt32) CBcjCoder::Filter(Byte *data, UInt32 size) STDMETHODIMP_(UInt32) CCoder::Filter(Byte *data, UInt32 size)
{ {
UInt32 processed = (UInt32)::x86_Convert(data, size, _bufferPos, &_prevMask, _encode); UInt32 processed = (UInt32)::x86_Convert(data, size, _bufferPos, &_prevMask, _encode);
_bufferPos += processed; _bufferPos += processed;
return processed; return processed;
} }
}}

View File

@@ -9,7 +9,10 @@
#include "../ICoder.h" #include "../ICoder.h"
class CBcjCoder: namespace NCompress {
namespace NBcj {
class CCoder:
public ICompressFilter, public ICompressFilter,
public CMyUnknownImp public CMyUnknownImp
{ {
@@ -17,10 +20,12 @@ class CBcjCoder:
UInt32 _prevMask; UInt32 _prevMask;
int _encode; int _encode;
public: public:
MY_UNKNOWN_IMP; MY_UNKNOWN_IMP1(ICompressFilter);
INTERFACE_ICompressFilter(;) INTERFACE_ICompressFilter(;)
CBcjCoder(int encode): _bufferPos(0), _encode(encode) { x86_Convert_Init(_prevMask); } CCoder(int encode): _bufferPos(0), _encode(encode) { x86_Convert_Init(_prevMask); }
}; };
}}
#endif #endif

View File

@@ -6,7 +6,12 @@
#include "BcjCoder.h" #include "BcjCoder.h"
namespace NCompress {
namespace NBcj {
REGISTER_FILTER_E(BCJ, REGISTER_FILTER_E(BCJ,
CBcjCoder(false), CCoder(false),
CBcjCoder(true), CCoder(true),
0x3030103, "BCJ") 0x3030103, "BCJ")
}}

View File

@@ -4,15 +4,20 @@
#include "BranchMisc.h" #include "BranchMisc.h"
STDMETHODIMP CBranchCoder::Init() namespace NCompress {
namespace NBranch {
STDMETHODIMP CCoder::Init()
{ {
_bufferPos = 0; _bufferPos = 0;
return S_OK; return S_OK;
} }
STDMETHODIMP_(UInt32) CBranchCoder::Filter(Byte *data, UInt32 size) STDMETHODIMP_(UInt32) CCoder::Filter(Byte *data, UInt32 size)
{ {
UInt32 processed = (UInt32)BraFunc(data, size, _bufferPos, _encode); UInt32 processed = (UInt32)BraFunc(data, size, _bufferPos, _encode);
_bufferPos += processed; _bufferPos += processed;
return processed; return processed;
} }
}}

View File

@@ -13,7 +13,10 @@ typedef SizeT (*Func_Bra)(Byte *data, SizeT size, UInt32 ip, int encoding);
EXTERN_C_END EXTERN_C_END
class CBranchCoder: namespace NCompress {
namespace NBranch {
class CCoder:
public ICompressFilter, public ICompressFilter,
public CMyUnknownImp public CMyUnknownImp
{ {
@@ -21,10 +24,12 @@ class CBranchCoder:
int _encode; int _encode;
Func_Bra BraFunc; Func_Bra BraFunc;
public: public:
MY_UNKNOWN_IMP; MY_UNKNOWN_IMP1(ICompressFilter);
INTERFACE_ICompressFilter(;) INTERFACE_ICompressFilter(;)
CBranchCoder(Func_Bra bra, int encode): _bufferPos(0), _encode(encode), BraFunc(bra) {} CCoder(Func_Bra bra, int encode): _bufferPos(0), _encode(encode), BraFunc(bra) {}
}; };
}}
#endif #endif

View File

@@ -8,9 +8,12 @@
#include "BranchMisc.h" #include "BranchMisc.h"
namespace NCompress {
namespace NBranch {
#define CREATE_BRA(n) \ #define CREATE_BRA(n) \
REGISTER_FILTER_CREATE(CreateBra_Decoder_ ## n, CBranchCoder(n ## _Convert, false)) \ REGISTER_FILTER_CREATE(CreateBra_Decoder_ ## n, CCoder(n ## _Convert, false)) \
REGISTER_FILTER_CREATE(CreateBra_Encoder_ ## n, CBranchCoder(n ## _Convert, true)) \ REGISTER_FILTER_CREATE(CreateBra_Encoder_ ## n, CCoder(n ## _Convert, true)) \
CREATE_BRA(PPC) CREATE_BRA(PPC)
CREATE_BRA(IA64) CREATE_BRA(IA64)
@@ -34,3 +37,5 @@ REGISTER_CODECS_VAR
}; };
REGISTER_CODECS(Branch) REGISTER_CODECS(Branch)
}}

View File

@@ -8,12 +8,15 @@
#include "../Common/RegisterCodec.h" #include "../Common/RegisterCodec.h"
namespace NCompress {
namespace NByteSwap {
class CByteSwap2: class CByteSwap2:
public ICompressFilter, public ICompressFilter,
public CMyUnknownImp public CMyUnknownImp
{ {
public: public:
MY_UNKNOWN_IMP MY_UNKNOWN_IMP1(ICompressFilter);
INTERFACE_ICompressFilter(;) INTERFACE_ICompressFilter(;)
}; };
@@ -22,7 +25,7 @@ class CByteSwap4:
public CMyUnknownImp public CMyUnknownImp
{ {
public: public:
MY_UNKNOWN_IMP MY_UNKNOWN_IMP1(ICompressFilter);
INTERFACE_ICompressFilter(;) INTERFACE_ICompressFilter(;)
}; };
@@ -85,3 +88,5 @@ REGISTER_CODECS_VAR
}; };
REGISTER_CODECS(ByteSwap) REGISTER_CODECS(ByteSwap)
}}

View File

@@ -6,6 +6,10 @@
#include "CopyCoder.h" #include "CopyCoder.h"
REGISTER_CODEC_CREATE(CreateCodec, NCompress::CCopyCoder()) namespace NCompress {
REGISTER_CODEC_CREATE(CreateCodec, CCopyCoder())
REGISTER_CODEC_2(Copy, CreateCodec, CreateCodec, 0, "Copy") REGISTER_CODEC_2(Copy, CreateCodec, CreateCodec, 0, "Copy")
}

View File

@@ -6,13 +6,21 @@
#include "DeflateDecoder.h" #include "DeflateDecoder.h"
REGISTER_CODEC_CREATE(CreateDec, NCompress::NDeflate::NDecoder::CCOMCoder64())
#if !defined(EXTRACT_ONLY) && !defined(DEFLATE_EXTRACT_ONLY) #if !defined(EXTRACT_ONLY) && !defined(DEFLATE_EXTRACT_ONLY)
#include "DeflateEncoder.h" #include "DeflateEncoder.h"
REGISTER_CODEC_CREATE(CreateEnc, NCompress::NDeflate::NEncoder::CCOMCoder64()) #endif
namespace NCompress {
namespace NDeflate {
REGISTER_CODEC_CREATE(CreateDec, NDecoder::CCOMCoder64())
#if !defined(EXTRACT_ONLY) && !defined(DEFLATE_EXTRACT_ONLY)
REGISTER_CODEC_CREATE(CreateEnc, NEncoder::CCOMCoder64())
#else #else
#define CreateEnc NULL #define CreateEnc NULL
#endif #endif
REGISTER_CODEC_2(Deflate64, CreateDec, CreateEnc, 0x40109, "Deflate64") REGISTER_CODEC_2(Deflate64, CreateDec, CreateEnc, 0x40109, "Deflate64")
}}

View File

@@ -92,14 +92,16 @@ public:
const UInt64 *outSize, ICompressProgressInfo *progress); const UInt64 *outSize, ICompressProgressInfo *progress);
#ifndef NO_READ_FROM_CODER #ifndef NO_READ_FROM_CODER
MY_UNKNOWN_IMP4( MY_UNKNOWN_IMP5(
ICompressCoder,
ICompressGetInStreamProcessedSize, ICompressGetInStreamProcessedSize,
ICompressSetInStream, ICompressSetInStream,
ICompressSetOutStreamSize, ICompressSetOutStreamSize,
ISequentialInStream ISequentialInStream
) )
#else #else
MY_UNKNOWN_IMP1( MY_UNKNOWN_IMP2(
ICompressCoder,
ICompressGetInStreamProcessedSize) ICompressGetInStreamProcessedSize)
#endif #endif

View File

@@ -190,7 +190,7 @@ class CCOMCoder :
public CCoder public CCoder
{ {
public: public:
MY_UNKNOWN_IMP1(ICompressSetCoderProperties) MY_UNKNOWN_IMP2(ICompressCoder, ICompressSetCoderProperties)
CCOMCoder(): CCoder(false) {}; CCOMCoder(): CCoder(false) {};
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
@@ -204,7 +204,7 @@ class CCOMCoder64 :
public CCoder public CCoder
{ {
public: public:
MY_UNKNOWN_IMP1(ICompressSetCoderProperties) MY_UNKNOWN_IMP2(ICompressCoder, ICompressSetCoderProperties)
CCOMCoder64(): CCoder(true) {}; CCOMCoder64(): CCoder(true) {};
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);

View File

@@ -5,14 +5,21 @@
#include "../Common/RegisterCodec.h" #include "../Common/RegisterCodec.h"
#include "DeflateDecoder.h" #include "DeflateDecoder.h"
REGISTER_CODEC_CREATE(CreateDec, NCompress::NDeflate::NDecoder::CCOMCoder)
#if !defined(EXTRACT_ONLY) && !defined(DEFLATE_EXTRACT_ONLY) #if !defined(EXTRACT_ONLY) && !defined(DEFLATE_EXTRACT_ONLY)
#include "DeflateEncoder.h" #include "DeflateEncoder.h"
REGISTER_CODEC_CREATE(CreateEnc, NCompress::NDeflate::NEncoder::CCOMCoder) #endif
namespace NCompress {
namespace NDeflate {
REGISTER_CODEC_CREATE(CreateDec, NDecoder::CCOMCoder)
#if !defined(EXTRACT_ONLY) && !defined(DEFLATE_EXTRACT_ONLY)
REGISTER_CODEC_CREATE(CreateEnc, NEncoder::CCOMCoder)
#else #else
#define CreateEnc NULL #define CreateEnc NULL
#endif #endif
REGISTER_CODEC_2(Deflate, CreateDec, CreateEnc, 0x40108, "Deflate") REGISTER_CODEC_2(Deflate, CreateDec, CreateEnc, 0x40108, "Deflate")
}}

View File

@@ -10,6 +10,9 @@
#include "../Common/RegisterCodec.h" #include "../Common/RegisterCodec.h"
namespace NCompress {
namespace NDelta {
struct CDelta struct CDelta
{ {
unsigned _delta; unsigned _delta;
@@ -22,7 +25,7 @@ struct CDelta
#ifndef EXTRACT_ONLY #ifndef EXTRACT_ONLY
class CDeltaEncoder: class CEncoder:
public ICompressFilter, public ICompressFilter,
public ICompressSetCoderProperties, public ICompressSetCoderProperties,
public ICompressWriteCoderProperties, public ICompressWriteCoderProperties,
@@ -30,25 +33,25 @@ class CDeltaEncoder:
public CMyUnknownImp public CMyUnknownImp
{ {
public: public:
MY_UNKNOWN_IMP2(ICompressSetCoderProperties, ICompressWriteCoderProperties) MY_UNKNOWN_IMP3(ICompressFilter, ICompressSetCoderProperties, ICompressWriteCoderProperties)
INTERFACE_ICompressFilter(;) INTERFACE_ICompressFilter(;)
STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
}; };
STDMETHODIMP CDeltaEncoder::Init() STDMETHODIMP CEncoder::Init()
{ {
DeltaInit(); DeltaInit();
return S_OK; return S_OK;
} }
STDMETHODIMP_(UInt32) CDeltaEncoder::Filter(Byte *data, UInt32 size) STDMETHODIMP_(UInt32) CEncoder::Filter(Byte *data, UInt32 size)
{ {
Delta_Encode(_state, _delta, data, size); Delta_Encode(_state, _delta, data, size);
return size; return size;
} }
STDMETHODIMP CDeltaEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps) STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)
{ {
UInt32 delta = _delta; UInt32 delta = _delta;
for (UInt32 i = 0; i < numProps; i++) for (UInt32 i = 0; i < numProps; i++)
@@ -75,7 +78,7 @@ STDMETHODIMP CDeltaEncoder::SetCoderProperties(const PROPID *propIDs, const PROP
return S_OK; return S_OK;
} }
STDMETHODIMP CDeltaEncoder::WriteCoderProperties(ISequentialOutStream *outStream) STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
{ {
Byte prop = (Byte)(_delta - 1); Byte prop = (Byte)(_delta - 1);
return outStream->Write(&prop, 1, NULL); return outStream->Write(&prop, 1, NULL);
@@ -84,31 +87,31 @@ STDMETHODIMP CDeltaEncoder::WriteCoderProperties(ISequentialOutStream *outStream
#endif #endif
class CDeltaDecoder: class CDecoder:
public ICompressFilter, public ICompressFilter,
public ICompressSetDecoderProperties2, public ICompressSetDecoderProperties2,
CDelta, CDelta,
public CMyUnknownImp public CMyUnknownImp
{ {
public: public:
MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) MY_UNKNOWN_IMP2(ICompressFilter, ICompressSetDecoderProperties2)
INTERFACE_ICompressFilter(;) INTERFACE_ICompressFilter(;)
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
}; };
STDMETHODIMP CDeltaDecoder::Init() STDMETHODIMP CDecoder::Init()
{ {
DeltaInit(); DeltaInit();
return S_OK; return S_OK;
} }
STDMETHODIMP_(UInt32) CDeltaDecoder::Filter(Byte *data, UInt32 size) STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size)
{ {
Delta_Decode(_state, _delta, data, size); Delta_Decode(_state, _delta, data, size);
return size; return size;
} }
STDMETHODIMP CDeltaDecoder::SetDecoderProperties2(const Byte *props, UInt32 size) STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *props, UInt32 size)
{ {
if (size != 1) if (size != 1)
return E_INVALIDARG; return E_INVALIDARG;
@@ -118,6 +121,8 @@ STDMETHODIMP CDeltaDecoder::SetDecoderProperties2(const Byte *props, UInt32 size
REGISTER_FILTER_E(Delta, REGISTER_FILTER_E(Delta,
CDeltaDecoder(), CDecoder(),
CDeltaEncoder(), CEncoder(),
3, "Delta") 3, "Delta")
}}

View File

@@ -20,7 +20,7 @@ class CEncoder:
{ {
CLzma2EncHandle _encoder; CLzma2EncHandle _encoder;
public: public:
MY_UNKNOWN_IMP2(ICompressSetCoderProperties, ICompressWriteCoderProperties) MY_UNKNOWN_IMP3(ICompressCoder, ICompressSetCoderProperties, ICompressWriteCoderProperties)
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);

View File

@@ -10,8 +10,13 @@
#include "Lzma2Encoder.h" #include "Lzma2Encoder.h"
#endif #endif
namespace NCompress {
namespace NLzma2 {
REGISTER_CODEC_E(LZMA2, REGISTER_CODEC_E(LZMA2,
NCompress::NLzma2::CDecoder(), CDecoder(),
NCompress::NLzma2::CEncoder(), CEncoder(),
0x21, 0x21,
"LZMA2") "LZMA2")
}}

View File

@@ -21,7 +21,7 @@ class CEncoder:
CLzmaEncHandle _encoder; CLzmaEncHandle _encoder;
UInt64 _inputProcessed; UInt64 _inputProcessed;
public: public:
MY_UNKNOWN_IMP2(ICompressSetCoderProperties, ICompressWriteCoderProperties) MY_UNKNOWN_IMP3(ICompressCoder, ICompressSetCoderProperties, ICompressWriteCoderProperties)
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);

View File

@@ -10,8 +10,13 @@
#include "LzmaEncoder.h" #include "LzmaEncoder.h"
#endif #endif
namespace NCompress {
namespace NLzma {
REGISTER_CODEC_E(LZMA, REGISTER_CODEC_E(LZMA,
NCompress::NLzma::CDecoder(), CDecoder(),
NCompress::NLzma::CEncoder(), CEncoder(),
0x30101, 0x30101,
"LZMA") "LZMA")
}}

View File

@@ -41,7 +41,8 @@ class CEncoder :
CPpmd7 _ppmd; CPpmd7 _ppmd;
CEncProps _props; CEncProps _props;
public: public:
MY_UNKNOWN_IMP2( MY_UNKNOWN_IMP3(
ICompressCoder,
ICompressSetCoderProperties, ICompressSetCoderProperties,
ICompressWriteCoderProperties) ICompressWriteCoderProperties)
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,

View File

@@ -10,8 +10,13 @@
#include "PpmdEncoder.h" #include "PpmdEncoder.h"
#endif #endif
namespace NCompress {
namespace NPpmd {
REGISTER_CODEC_E(PPMD, REGISTER_CODEC_E(PPMD,
NCompress::NPpmd::CDecoder(), CDecoder(),
NCompress::NPpmd::CEncoder(), CEncoder(),
0x30401, 0x30401,
"PPMD") "PPMD")
}}

View File

@@ -154,7 +154,7 @@ HRESULT CDecoder::WriteBuf()
FOR_VECTOR (i, _tempFilters) FOR_VECTOR (i, _tempFilters)
{ {
CTempFilter *filter = _tempFilters[i]; CTempFilter *filter = _tempFilters[i];
if (filter == NULL) if (!filter)
continue; continue;
if (filter->NextWindow) if (filter->NextWindow)
{ {
@@ -187,8 +187,10 @@ HRESULT CDecoder::WriteBuf()
while (i + 1 < _tempFilters.Size()) while (i + 1 < _tempFilters.Size())
{ {
CTempFilter *nextFilter = _tempFilters[i + 1]; CTempFilter *nextFilter = _tempFilters[i + 1];
if (nextFilter == NULL || nextFilter->BlockStart != blockStart || if (!nextFilter
nextFilter->BlockSize != outBlockRef.Size || nextFilter->NextWindow) || nextFilter->BlockStart != blockStart
|| nextFilter->BlockSize != outBlockRef.Size
|| nextFilter->NextWindow)
break; break;
_vm.SetMemory(0, _vm.GetDataPointer(outBlockRef.Offset), outBlockRef.Size); _vm.SetMemory(0, _vm.GetDataPointer(outBlockRef.Offset), outBlockRef.Size);
ExecuteFilter(++i, outBlockRef); ExecuteFilter(++i, outBlockRef);
@@ -203,7 +205,7 @@ HRESULT CDecoder::WriteBuf()
for (unsigned j = i; j < _tempFilters.Size(); j++) for (unsigned j = i; j < _tempFilters.Size(); j++)
{ {
CTempFilter *filter = _tempFilters[j]; CTempFilter *filter = _tempFilters[j];
if (filter != NULL && filter->NextWindow) if (filter && filter->NextWindow)
filter->NextWindow = false; filter->NextWindow = false;
} }
_wrPtr = writtenBorder; _wrPtr = writtenBorder;
@@ -273,7 +275,7 @@ bool CDecoder::AddVmCode(UInt32 firstByte, UInt32 codeSize)
for (i = 0; i < _tempFilters.Size(); i++) for (i = 0; i < _tempFilters.Size(); i++)
{ {
_tempFilters[i - numEmptyItems] = _tempFilters[i]; _tempFilters[i - numEmptyItems] = _tempFilters[i];
if (_tempFilters[i] == NULL) if (!_tempFilters[i])
numEmptyItems++; numEmptyItems++;
if (numEmptyItems > 0) if (numEmptyItems > 0)
_tempFilters[i] = NULL; _tempFilters[i] = NULL;
@@ -865,21 +867,21 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
{ {
try try
{ {
if (inSize == NULL || outSize == NULL) if (!inSize)
return E_INVALIDARG; return E_INVALIDARG;
if (_vmData == 0) if (!_vmData)
{ {
_vmData = (Byte *)::MidAlloc(kVmDataSizeMax + kVmCodeSizeMax); _vmData = (Byte *)::MidAlloc(kVmDataSizeMax + kVmCodeSizeMax);
if (_vmData == 0) if (!_vmData)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
_vmCode = _vmData + kVmDataSizeMax; _vmCode = _vmData + kVmDataSizeMax;
} }
if (_window == 0) if (!_window)
{ {
_window = (Byte *)::MidAlloc(kWindowSize); _window = (Byte *)::MidAlloc(kWindowSize);
if (_window == 0) if (!_window)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
if (!m_InBitStream.BitDecoder.Create(1 << 20)) if (!m_InBitStream.BitDecoder.Create(1 << 20))
@@ -893,7 +895,7 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
_outStream = outStream; _outStream = outStream;
// CCoderReleaser coderReleaser(this); // CCoderReleaser coderReleaser(this);
_unpackSize = *outSize; _unpackSize = outSize ? *outSize : (UInt64)(Int64)-1;
return CodeReal(progress); return CodeReal(progress);
} }
catch(const CInBufferException &e) { return e.ErrorCode; } catch(const CInBufferException &e) { return e.ErrorCode; }

View File

@@ -9,7 +9,9 @@
#include "Rar3Decoder.h" #include "Rar3Decoder.h"
#include "Rar5Decoder.h" #include "Rar5Decoder.h"
#define CREATE_CODEC(x) REGISTER_CODEC_CREATE(CreateCodec ## x, NCompress::NRar ## x::CDecoder()) namespace NCompress {
#define CREATE_CODEC(x) REGISTER_CODEC_CREATE(CreateCodec ## x, NRar ## x::CDecoder())
CREATE_CODEC(1) CREATE_CODEC(1)
CREATE_CODEC(2) CREATE_CODEC(2)
@@ -27,3 +29,5 @@ REGISTER_CODECS_VAR
}; };
REGISTER_CODECS(Rar) REGISTER_CODECS(Rar)
}

View File

@@ -1,7 +1,10 @@
// ShrinkDecoder.cpp // ShrinkDecoder.cpp
#include "StdAfx.h" #include "StdAfx.h"
#include <stdio.h>
#include "../../../C/Alloc.h" #include "../../../C/Alloc.h"
#include "../Common/InBuffer.h" #include "../Common/InBuffer.h"
@@ -13,8 +16,8 @@
namespace NCompress { namespace NCompress {
namespace NShrink { namespace NShrink {
static const UInt32 kBufferSize = (1 << 20); static const UInt32 kBufferSize = (1 << 18);
static const int kNumMinBits = 9; static const unsigned kNumMinBits = 9;
HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
@@ -32,109 +35,121 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
outBuffer.SetStream(outStream); outBuffer.SetStream(outStream);
outBuffer.Init(); outBuffer.Init();
UInt64 prevPos = 0; {
int numBits = kNumMinBits; unsigned i;
UInt32 head = 257; for (i = 0; i < 257; i++)
bool needPrev = false; _parents[i] = (UInt16)i;
UInt32 lastSymbol = 0; for (; i < kNumItems; i++)
_parents[i] = kNumItems;
for (i = 0; i < kNumItems; i++)
_suffixes[i] = 0;
}
int i; UInt64 prevPos = 0;
for (i = 0; i < kNumItems; i++) unsigned numBits = kNumMinBits;
_parents[i] = 0; unsigned head = 257;
for (i = 0; i < kNumItems; i++) int lastSym = -1;
_suffixes[i] = 0; Byte lastChar2 = 0;
for (i = 0; i < 257; i++)
_isFree[i] = false;
for (; i < kNumItems; i++)
_isFree[i] = true;
for (;;) for (;;)
{ {
UInt32 symbol = inBuffer.ReadBits(numBits); UInt32 sym = inBuffer.ReadBits(numBits);
if (inBuffer.ExtraBitsWereRead()) if (inBuffer.ExtraBitsWereRead())
break; break;
if (_isFree[symbol])
return S_FALSE; if (sym == 256)
if (symbol == 256)
{ {
UInt32 symbol = inBuffer.ReadBits(numBits); sym = inBuffer.ReadBits(numBits);
if (symbol == 1) if (sym == 1)
{ {
if (numBits < kNumMaxBits) if (numBits >= kNumMaxBits)
numBits++; return S_FALSE;
numBits++;
continue;
} }
else if (symbol == 2) if (sym != 2)
{
if (needPrev)
_isFree[head - 1] = true;
for (i = 257; i < kNumItems; i++)
_isParent[i] = false;
for (i = 257; i < kNumItems; i++)
if (!_isFree[i])
_isParent[_parents[i]] = true;
for (i = 257; i < kNumItems; i++)
if (!_isParent[i])
_isFree[i] = true;
head = 257;
while (head < kNumItems && !_isFree[head])
head++;
if (head < kNumItems)
{
needPrev = true;
_isFree[head] = false;
_parents[head] = (UInt16)lastSymbol;
head++;
}
}
else
return S_FALSE; return S_FALSE;
continue; {
unsigned i;
for (i = 257; i < kNumItems; i++)
_stack[i] = 0;
for (i = 257; i < kNumItems; i++)
{
unsigned par = _parents[i];
if (par != kNumItems)
_stack[par] = 1;
}
for (i = 257; i < kNumItems; i++)
if (_stack[i] == 0)
_parents[i] = kNumItems;
head = 257;
continue;
}
} }
UInt32 cur = symbol;
i = 0; bool needPrev = false;
int corectionIndex = -1; if (head < kNumItems && lastSym >= 0)
{
while (head < kNumItems && _parents[head] != kNumItems)
head++;
if (head < kNumItems)
{
if (head == (unsigned)lastSym)
{
// we need to fix the code for that case
// _parents[head] is not allowed to link to itself
return E_NOTIMPL;
}
needPrev = true;
_parents[head] = (UInt16)lastSym;
_suffixes[head] = (Byte)lastChar2;
head++;
}
}
if (_parents[sym] == kNumItems)
return S_FALSE;
lastSym = sym;
unsigned cur = sym;
unsigned i = 0;
while (cur >= 256) while (cur >= 256)
{ {
if (cur == head - 1)
corectionIndex = i;
_stack[i++] = _suffixes[cur]; _stack[i++] = _suffixes[cur];
cur = _parents[cur]; cur = _parents[cur];
} }
_stack[i++] = (Byte)cur; _stack[i++] = (Byte)cur;
if (needPrev) lastChar2 = (Byte)cur;
{
_suffixes[head - 1] = (Byte)cur;
if (corectionIndex >= 0)
_stack[corectionIndex] = (Byte)cur;
}
while (i > 0)
outBuffer.WriteByte((_stack[--i]));
while (head < kNumItems && !_isFree[head])
head++;
if (head < kNumItems)
{
needPrev = true;
_isFree[head] = false;
_parents[head] = (UInt16)symbol;
head++;
}
else
needPrev = false;
lastSymbol = symbol;
UInt64 nowPos = outBuffer.GetProcessedSize(); if (needPrev)
if (progress != NULL && nowPos - prevPos > (1 << 18)) _suffixes[head - 1] = (Byte)cur;
do
outBuffer.WriteByte(_stack[--i]);
while (i);
if (progress)
{ {
prevPos = nowPos; const UInt64 nowPos = outBuffer.GetProcessedSize();
UInt64 packSize = inBuffer.GetProcessedSize(); if (nowPos - prevPos >= (1 << 18))
RINOK(progress->SetRatioInfo(&packSize, &nowPos)); {
prevPos = nowPos;
const UInt64 packSize = inBuffer.GetProcessedSize();
RINOK(progress->SetRatioInfo(&packSize, &nowPos));
}
} }
} }
return outBuffer.Flush(); return outBuffer.Flush();
} }
STDMETHODIMP CDecoder ::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, STDMETHODIMP CDecoder ::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
{ {
try { return CodeReal(inStream, outStream, inSize, outSize, progress); } try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
catch(const CInBufferException &e) { return e.ErrorCode; } catch(const CInBufferException &e) { return e.ErrorCode; }

View File

@@ -10,8 +10,8 @@
namespace NCompress { namespace NCompress {
namespace NShrink { namespace NShrink {
const int kNumMaxBits = 13; const unsigned kNumMaxBits = 13;
const UInt32 kNumItems = 1 << kNumMaxBits; const unsigned kNumItems = 1 << kNumMaxBits;
class CDecoder : class CDecoder :
public ICompressCoder, public ICompressCoder,
@@ -20,8 +20,6 @@ class CDecoder :
UInt16 _parents[kNumItems]; UInt16 _parents[kNumItems];
Byte _suffixes[kNumItems]; Byte _suffixes[kNumItems];
Byte _stack[kNumItems]; Byte _stack[kNumItems];
bool _isFree[kNumItems];
bool _isParent[kNumItems];
public: public:
MY_UNKNOWN_IMP MY_UNKNOWN_IMP

View File

@@ -86,7 +86,8 @@ class CEncoder:
public ICryptoResetInitVector public ICryptoResetInitVector
{ {
public: public:
MY_UNKNOWN_IMP3( MY_UNKNOWN_IMP4(
ICompressFilter,
ICryptoSetPassword, ICryptoSetPassword,
ICompressWriteCoderProperties, ICompressWriteCoderProperties,
// ICryptoResetSalt, // ICryptoResetSalt,
@@ -104,7 +105,8 @@ class CDecoder:
public ICompressSetDecoderProperties2 public ICompressSetDecoderProperties2
{ {
public: public:
MY_UNKNOWN_IMP2( MY_UNKNOWN_IMP3(
ICompressFilter,
ICryptoSetPassword, ICryptoSetPassword,
ICompressSetDecoderProperties2) ICompressSetDecoderProperties2)
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);

View File

@@ -6,7 +6,12 @@
#include "7zAes.h" #include "7zAes.h"
namespace NCrypto {
namespace N7z {
REGISTER_FILTER_E(7zAES, REGISTER_FILTER_E(7zAES,
NCrypto::N7z::CDecoder(), CDecoder(),
NCrypto::N7z::CEncoder(), CEncoder(),
0x6F10701, "7zAES") 0x6F10701, "7zAES")
}}

View File

@@ -30,7 +30,7 @@ class CAesCbcCoder:
public: public:
CAesCbcCoder(bool encodeMode, unsigned keySize); CAesCbcCoder(bool encodeMode, unsigned keySize);
MY_UNKNOWN_IMP2(ICryptoProperties, ICompressSetCoderProperties) MY_UNKNOWN_IMP3(ICompressFilter, ICryptoProperties, ICompressSetCoderProperties)
INTERFACE_ICompressFilter(;) INTERFACE_ICompressFilter(;)

View File

@@ -6,7 +6,11 @@
#include "MyAes.h" #include "MyAes.h"
namespace NCrypto {
REGISTER_FILTER_E(AES256CBC, REGISTER_FILTER_E(AES256CBC,
NCrypto::CAesCbcDecoder(32), CAesCbcDecoder(32),
NCrypto::CAesCbcEncoder(32), CAesCbcEncoder(32),
0x6F00181, "AES256CBC") 0x6F00181, "AES256CBC")
}

View File

@@ -304,14 +304,25 @@ HRESULT CProxyArc::Load(const CArc &arc, IProgress *progress)
*/ */
unsigned namePos = 0; unsigned namePos = 0;
unsigned numLevels = 0;
for (unsigned j = 0; j < len; j++) for (unsigned j = 0; j < len; j++)
{ {
wchar_t c = s[j]; wchar_t c = s[j];
if (c == WCHAR_PATH_SEPARATOR || c == L'/') if (c == WCHAR_PATH_SEPARATOR || c == L'/')
{ {
name.SetFrom(s + namePos, j - namePos); const unsigned kLevelLimit = 1 << 10;
curItem = AddDir(curItem, -1, name); if (numLevels <= kLevelLimit)
{
if (numLevels == kLevelLimit)
name.SetFromAscii("[LONG_PATH]");
else
name.SetFrom(s + namePos, j - namePos);
curItem = AddDir(curItem, -1, name);
}
namePos = j + 1; namePos = j + 1;
numLevels++;
} }
} }

View File

@@ -1053,7 +1053,7 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
const UStringVector &nonSwitchStrings = parser.NonSwitchStrings; const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
unsigned numNonSwitchStrings = nonSwitchStrings.Size(); unsigned numNonSwitchStrings = nonSwitchStrings.Size();
if (numNonSwitchStrings < kMinNonSwitchWords) if (numNonSwitchStrings < kMinNonSwitchWords)
throw CArcCmdLineException("The command must be spcified"); throw CArcCmdLineException("The command must be specified");
if (!ParseArchiveCommand(nonSwitchStrings[kCommandIndex], options.Command)) if (!ParseArchiveCommand(nonSwitchStrings[kCommandIndex], options.Command))
throw CArcCmdLineException("Unsupported command:", nonSwitchStrings[kCommandIndex]); throw CArcCmdLineException("Unsupported command:", nonSwitchStrings[kCommandIndex]);

View File

@@ -43,6 +43,7 @@ STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value)
switch (propID) switch (propID)
{ {
case kpidName: prop = _subArchiveName; break; case kpidName: prop = _subArchiveName; break;
// case kpidSize: prop = _subArchiveSize; break; // we don't use it now
} }
else else
switch (propID) switch (propID)

View File

@@ -1632,6 +1632,36 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
#endif #endif
{ {
#ifndef _SFX
bool isZip = false;
bool isRar = false;
const wchar_t c = extension[0];
if (c == 'z' || c == 'Z' || c == 'r' || c == 'R')
{
bool isNumber = false;
for (unsigned k = 1;; k++)
{
const wchar_t d = extension[k];
if (d == 0)
break;
if (d < '0' || d > '9')
{
isNumber = false;
break;
}
isNumber = true;
}
if (isNumber)
if (c == 'z' || c == 'Z')
isZip = true;
else
isRar = true;
}
#endif
FOR_VECTOR (i, op.codecs->Formats) FOR_VECTOR (i, op.codecs->Formats)
{ {
const CArcInfoEx &ai = op.codecs->Formats[i]; const CArcInfoEx &ai = op.codecs->Formats[i];
@@ -1647,7 +1677,12 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
isPrearcExt = true; isPrearcExt = true;
#endif #endif
if (ai.FindExtension(extension) >= 0) if (ai.FindExtension(extension) >= 0
#ifndef _SFX
|| isZip && StringsAreEqualNoCase_Ascii(ai.Name, "zip")
|| isRar && StringsAreEqualNoCase_Ascii(ai.Name, "rar")
#endif
)
{ {
// PrintNumber("orderIndices.Insert", i); // PrintNumber("orderIndices.Insert", i);
orderIndices.Insert(numFinded++, i); orderIndices.Insert(numFinded++, i);

View File

@@ -98,6 +98,8 @@ void CInfo::Load()
OverwriteMode = NOverwriteMode::kAsk; OverwriteMode = NOverwriteMode::kAsk;
OverwriteMode_Force = false; OverwriteMode_Force = false;
SplitDest.Val = true;
Paths.Clear(); Paths.Clear();
CS_LOCK CS_LOCK

View File

@@ -295,7 +295,7 @@ static bool IsItArcExt(const UString &ext)
return false; return false;
} }
static UString GetSubFolderNameForExtract(const UString &arcName) UString GetSubFolderNameForExtract(const UString &arcName)
{ {
int dotPos = arcName.ReverseFind_Dot(); int dotPos = arcName.ReverseFind_Dot();
if (dotPos < 0) if (dotPos < 0)

View File

@@ -46,7 +46,7 @@ void CPanelCallbackImp::OnTab()
_app->RefreshTitle(); _app->RefreshTitle();
} }
void CPanelCallbackImp::SetFocusToPath(int index) void CPanelCallbackImp::SetFocusToPath(unsigned index)
{ {
int newPanelIndex = index; int newPanelIndex = index;
if (g_App.NumPanels == 1) if (g_App.NumPanels == 1)
@@ -60,10 +60,10 @@ void CPanelCallbackImp::SetFocusToPath(int index)
void CPanelCallbackImp::OnCopy(bool move, bool copyToSame) { _app->OnCopy(move, copyToSame, _index); } void CPanelCallbackImp::OnCopy(bool move, bool copyToSame) { _app->OnCopy(move, copyToSame, _index); }
void CPanelCallbackImp::OnSetSameFolder() { _app->OnSetSameFolder(_index); } void CPanelCallbackImp::OnSetSameFolder() { _app->OnSetSameFolder(_index); }
void CPanelCallbackImp::OnSetSubFolder() { _app->OnSetSubFolder(_index); } void CPanelCallbackImp::OnSetSubFolder() { _app->OnSetSubFolder(_index); }
void CPanelCallbackImp::PanelWasFocused() { _app->SetFocusedPanel(_index); _app->RefreshTitle(_index); } void CPanelCallbackImp::PanelWasFocused() { _app->SetFocusedPanel(_index); _app->RefreshTitlePanel(_index); }
void CPanelCallbackImp::DragBegin() { _app->DragBegin(_index); } void CPanelCallbackImp::DragBegin() { _app->DragBegin(_index); }
void CPanelCallbackImp::DragEnd() { _app->DragEnd(); } void CPanelCallbackImp::DragEnd() { _app->DragEnd(); }
void CPanelCallbackImp::RefreshTitle(bool always) { _app->RefreshTitle(_index, always); } void CPanelCallbackImp::RefreshTitle(bool always) { _app->RefreshTitlePanel(_index, always); }
void CApp::ReloadLang() void CApp::ReloadLang()
{ {
@@ -115,11 +115,14 @@ void CApp::SetListSettings()
#endif #endif
HRESULT CApp::CreateOnePanel(int panelIndex, const UString &mainPath, const UString &arcFormat, HRESULT CApp::CreateOnePanel(int panelIndex, const UString &mainPath, const UString &arcFormat,
bool &archiveIsOpened, bool &encrypted) bool needOpenArc,
bool &archiveIsOpened, bool &encrypted)
{ {
if (PanelsCreated[panelIndex]) if (Panels[panelIndex].PanelCreated)
return S_OK; return S_OK;
m_PanelCallbackImp[panelIndex].Init(this, panelIndex); m_PanelCallbackImp[panelIndex].Init(this, panelIndex);
UString path; UString path;
if (mainPath.IsEmpty()) if (mainPath.IsEmpty())
{ {
@@ -128,13 +131,16 @@ HRESULT CApp::CreateOnePanel(int panelIndex, const UString &mainPath, const UStr
} }
else else
path = mainPath; path = mainPath;
int id = 1000 + 100 * panelIndex; int id = 1000 + 100 * panelIndex;
RINOK(Panels[panelIndex].Create(_window, _window,
id, path, arcFormat, &m_PanelCallbackImp[panelIndex], &AppState, archiveIsOpened, encrypted)); return Panels[panelIndex].Create(_window, _window,
PanelsCreated[panelIndex] = true; id, path, arcFormat, &m_PanelCallbackImp[panelIndex], &AppState,
return S_OK; needOpenArc,
archiveIsOpened, encrypted);
} }
static void CreateToolbar(HWND parent, static void CreateToolbar(HWND parent,
NControl::CImageList &imageList, NControl::CImageList &imageList,
NControl::CToolBar &toolBar, NControl::CToolBar &toolBar,
@@ -165,6 +171,7 @@ static void CreateToolbar(HWND parent,
toolBar.SetImageList(0, imageList); toolBar.SetImageList(0, imageList);
} }
struct CButtonInfo struct CButtonInfo
{ {
int CommandID; int CommandID;
@@ -273,9 +280,11 @@ void CApp::SaveToolbarChanges()
MoveSubWindows(); MoveSubWindows();
} }
void MyLoadMenu(); void MyLoadMenu();
HRESULT CApp::Create(HWND hwnd, const UString &mainPath, const UString &arcFormat, int xSizes[2], bool &archiveIsOpened, bool &encrypted)
HRESULT CApp::Create(HWND hwnd, const UString &mainPath, const UString &arcFormat, int xSizes[2], bool needOpenArc, bool &archiveIsOpened, bool &encrypted)
{ {
_window.Attach(hwnd); _window.Attach(hwnd);
@@ -292,9 +301,9 @@ HRESULT CApp::Create(HWND hwnd, const UString &mainPath, const UString &arcForma
ReadToolbar(); ReadToolbar();
ReloadToolbars(); ReloadToolbars();
int i; unsigned i;
for (i = 0; i < kNumPanelsMax; i++) for (i = 0; i < kNumPanelsMax; i++)
PanelsCreated[i] = false; Panels[i].PanelCreated = false;
AppState.Read(); AppState.Read();
@@ -316,33 +325,52 @@ HRESULT CApp::Create(HWND hwnd, const UString &mainPath, const UString &arcForma
} }
for (i = 0; i < kNumPanelsMax; i++) for (i = 0; i < kNumPanelsMax; i++)
if (NumPanels > 1 || i == LastFocusedPanel) {
unsigned panelIndex = i;
if (needOpenArc && LastFocusedPanel == 1)
panelIndex = 1 - i;
bool isMainPanel = (panelIndex == LastFocusedPanel);
if (NumPanels > 1 || isMainPanel)
{ {
if (NumPanels == 1) if (NumPanels == 1)
Panels[i]._xSize = xSizes[0] + xSizes[1]; Panels[panelIndex]._xSize = xSizes[0] + xSizes[1];
bool archiveIsOpened2 = false; bool archiveIsOpened2 = false;
bool encrypted2 = false; bool encrypted2 = false;
bool mainPanel = (i == LastFocusedPanel); UString path;
RINOK(CreateOnePanel(i, mainPanel ? mainPath : L"", arcFormat, archiveIsOpened2, encrypted2)); if (isMainPanel)
if (mainPanel) path = mainPath;
RINOK(CreateOnePanel(panelIndex, path, arcFormat,
isMainPanel && needOpenArc,
archiveIsOpened2, encrypted2));
if (isMainPanel)
{ {
archiveIsOpened = archiveIsOpened2; archiveIsOpened = archiveIsOpened2;
encrypted = encrypted2; encrypted = encrypted2;
if (needOpenArc && !archiveIsOpened2)
return S_OK;
} }
} }
}
SetFocusedPanel(LastFocusedPanel); SetFocusedPanel(LastFocusedPanel);
Panels[LastFocusedPanel].SetFocusToList(); Panels[LastFocusedPanel].SetFocusToList();
return S_OK; return S_OK;
} }
HRESULT CApp::SwitchOnOffOnePanel() HRESULT CApp::SwitchOnOffOnePanel()
{ {
if (NumPanels == 1) if (NumPanels == 1)
{ {
NumPanels++; NumPanels++;
bool archiveIsOpened, encrypted; bool archiveIsOpened, encrypted;
RINOK(CreateOnePanel(1 - LastFocusedPanel, UString(), UString(), archiveIsOpened, encrypted)); RINOK(CreateOnePanel(1 - LastFocusedPanel, UString(), UString(),
false, // needOpenArc
archiveIsOpened, encrypted));
Panels[1 - LastFocusedPanel].Enable(true); Panels[1 - LastFocusedPanel].Enable(true);
Panels[1 - LastFocusedPanel].Show(SW_SHOWNORMAL); Panels[1 - LastFocusedPanel].Show(SW_SHOWNORMAL);
} }
@@ -530,7 +558,7 @@ static bool IsFsPath(const FString &path)
void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex) void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex)
{ {
int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex); unsigned destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex);
CPanel &srcPanel = Panels[srcPanelIndex]; CPanel &srcPanel = Panels[srcPanelIndex];
CPanel &destPanel = Panels[destPanelIndex]; CPanel &destPanel = Panels[destPanelIndex];
@@ -854,7 +882,7 @@ int CApp::GetFocusedPanelIndex() const
{ {
if (hwnd == 0) if (hwnd == 0)
return 0; return 0;
for (int i = 0; i < kNumPanelsMax; i++) for (unsigned i = 0; i < kNumPanelsMax; i++)
{ {
if (PanelsCreated[i] && if (PanelsCreated[i] &&
((HWND)Panels[i] == hwnd || Panels[i]._listView == hwnd)) ((HWND)Panels[i] == hwnd || Panels[i]._listView == hwnd))
@@ -906,7 +934,7 @@ void CApp::RefreshTitle(bool always)
NWindows::MySetWindowText(_window, path); NWindows::MySetWindowText(_window, path);
} }
void CApp::RefreshTitle(int panelIndex, bool always) void CApp::RefreshTitlePanel(unsigned panelIndex, bool always)
{ {
if (panelIndex != GetFocusedPanelIndex()) if (panelIndex != GetFocusedPanelIndex())
return; return;

View File

@@ -14,7 +14,7 @@ class CApp;
extern CApp g_App; extern CApp g_App;
extern HWND g_HWND; extern HWND g_HWND;
const int kNumPanelsMax = 2; const unsigned kNumPanelsMax = 2;
extern bool g_IsSmallScreen; extern bool g_IsSmallScreen;
@@ -32,15 +32,15 @@ enum
class CPanelCallbackImp: public CPanelCallback class CPanelCallbackImp: public CPanelCallback
{ {
CApp *_app; CApp *_app;
int _index; unsigned _index;
public: public:
void Init(CApp *app, int index) void Init(CApp *app, unsigned index)
{ {
_app = app; _app = app;
_index = index; _index = index;
} }
virtual void OnTab(); virtual void OnTab();
virtual void SetFocusToPath(int index); virtual void SetFocusToPath(unsigned index);
virtual void OnCopy(bool move, bool copyToSame); virtual void OnCopy(bool move, bool copyToSame);
virtual void OnSetSameFolder(); virtual void OnSetSameFolder();
virtual void OnSetSubFolder(); virtual void OnSetSubFolder();
@@ -111,8 +111,8 @@ public:
NWindows::CWindow _window; NWindows::CWindow _window;
bool ShowSystemMenu; bool ShowSystemMenu;
// bool ShowDeletedFiles; // bool ShowDeletedFiles;
int NumPanels; unsigned NumPanels;
int LastFocusedPanel; unsigned LastFocusedPanel;
bool ShowStandardToolbar; bool ShowStandardToolbar;
bool ShowArchiveToolbar; bool ShowArchiveToolbar;
@@ -122,7 +122,6 @@ public:
CAppState AppState; CAppState AppState;
CPanelCallbackImp m_PanelCallbackImp[kNumPanelsMax]; CPanelCallbackImp m_PanelCallbackImp[kNumPanelsMax];
CPanel Panels[kNumPanelsMax]; CPanel Panels[kNumPanelsMax];
bool PanelsCreated[kNumPanelsMax];
NWindows::NControl::CImageList _buttonsImageList; NWindows::NControl::CImageList _buttonsImageList;
@@ -151,13 +150,13 @@ public:
_dropTargetSpec->App = (this); _dropTargetSpec->App = (this);
} }
void SetFocusedPanel(int index) void SetFocusedPanel(unsigned index)
{ {
LastFocusedPanel = index; LastFocusedPanel = index;
_dropTargetSpec->TargetPanelIndex = LastFocusedPanel; _dropTargetSpec->TargetPanelIndex = LastFocusedPanel;
} }
void DragBegin(int panelIndex) void DragBegin(unsigned panelIndex)
{ {
_dropTargetSpec->TargetPanelIndex = (NumPanels > 1) ? 1 - panelIndex : panelIndex; _dropTargetSpec->TargetPanelIndex = (NumPanels > 1) ? 1 - panelIndex : panelIndex;
_dropTargetSpec->SrcPanelIndex = panelIndex; _dropTargetSpec->SrcPanelIndex = panelIndex;
@@ -174,16 +173,16 @@ public:
void OnSetSameFolder(int srcPanelIndex); void OnSetSameFolder(int srcPanelIndex);
void OnSetSubFolder(int srcPanelIndex); void OnSetSubFolder(int srcPanelIndex);
HRESULT CreateOnePanel(int panelIndex, const UString &mainPath, const UString &arcFormat, bool &archiveIsOpened, bool &encrypted); HRESULT CreateOnePanel(int panelIndex, const UString &mainPath, const UString &arcFormat, bool needOpenArc, bool &archiveIsOpened, bool &encrypted);
HRESULT Create(HWND hwnd, const UString &mainPath, const UString &arcFormat, int xSizes[2], bool &archiveIsOpened, bool &encrypted); HRESULT Create(HWND hwnd, const UString &mainPath, const UString &arcFormat, int xSizes[2], bool needOpenArc, bool &archiveIsOpened, bool &encrypted);
void Read(); void Read();
void Save(); void Save();
void Release(); void Release();
// void SetFocus(int panelIndex) { Panels[panelIndex].SetFocusToList(); } // void SetFocus(int panelIndex) { Panels[panelIndex].SetFocusToList(); }
void SetFocusToLastItem() { Panels[LastFocusedPanel].SetFocusToLastRememberedItem(); } void SetFocusToLastItem() { Panels[LastFocusedPanel].SetFocusToLastRememberedItem(); }
int GetFocusedPanelIndex() const { return LastFocusedPanel; } unsigned GetFocusedPanelIndex() const { return LastFocusedPanel; }
bool IsPanelVisible(int index) const { return (NumPanels > 1 || index == LastFocusedPanel); } bool IsPanelVisible(unsigned index) const { return (NumPanels > 1 || index == LastFocusedPanel); }
CPanel &GetFocusedPanel() { return Panels[GetFocusedPanelIndex()]; } CPanel &GetFocusedPanel() { return Panels[GetFocusedPanelIndex()]; }
// File Menu // File Menu
@@ -235,9 +234,9 @@ public:
void RefreshView() { GetFocusedPanel().OnReload(); } void RefreshView() { GetFocusedPanel().OnReload(); }
void RefreshAllPanels() void RefreshAllPanels()
{ {
for (int i = 0; i < NumPanels; i++) for (unsigned i = 0; i < NumPanels; i++)
{ {
int index = i; unsigned index = i;
if (NumPanels == 1) if (NumPanels == 1)
index = LastFocusedPanel; index = LastFocusedPanel;
Panels[index].OnReload(); Panels[index].OnReload();
@@ -247,9 +246,9 @@ public:
/* /*
void SysIconsWereChanged() void SysIconsWereChanged()
{ {
for (int i = 0; i < NumPanels; i++) for (unsigned i = 0; i < NumPanels; i++)
{ {
int index = i; unsigned index = i;
if (NumPanels == 1) if (NumPanels == 1)
index = LastFocusedPanel; index = LastFocusedPanel;
Panels[index].SysIconsWereChanged(); Panels[index].SysIconsWereChanged();
@@ -280,7 +279,7 @@ public:
} }
void SetPanels_AutoRefresh_Mode() void SetPanels_AutoRefresh_Mode()
{ {
for (int i = 0; i < kNumPanelsMax; i++) for (unsigned i = 0; i < kNumPanelsMax; i++)
Panels[i].Set_AutoRefresh_Mode(AutoRefresh_Mode); Panels[i].Set_AutoRefresh_Mode(AutoRefresh_Mode);
} }
@@ -347,7 +346,7 @@ public:
UString PrevTitle; UString PrevTitle;
void RefreshTitle(bool always = false); void RefreshTitle(bool always = false);
void RefreshTitleAlways() { RefreshTitle(true); } void RefreshTitleAlways() { RefreshTitle(true); }
void RefreshTitle(int panelIndex, bool always = false); void RefreshTitlePanel(unsigned panelIndex, bool always = false);
void MoveSubWindows(); void MoveSubWindows();
}; };

View File

@@ -157,6 +157,7 @@ static bool g_CanChangeSplitter = false;
static UInt32 g_SplitterPos = 0; static UInt32 g_SplitterPos = 0;
static CSplitterPos g_Splitter; static CSplitterPos g_Splitter;
static bool g_PanelsInfoDefined = false; static bool g_PanelsInfoDefined = false;
static bool g_WindowWasCreated = false;
static int g_StartCaptureMousePos; static int g_StartCaptureMousePos;
static int g_StartCaptureSplitterPos; static int g_StartCaptureSplitterPos;
@@ -238,8 +239,9 @@ static BOOL InitInstance(int nCmdShow)
if (windowPosIsRead) if (windowPosIsRead)
{ {
// x = rect.left; x = info.rect.left;
// y = rect.top; y = info.rect.top;
xSize = RECT_SIZE_X(info.rect); xSize = RECT_SIZE_X(info.rect);
ySize = RECT_SIZE_Y(info.rect); ySize = RECT_SIZE_Y(info.rect);
} }
@@ -258,6 +260,7 @@ static BOOL InitInstance(int nCmdShow)
info.numPanels = kNumDefaultPanels; info.numPanels = kNumDefaultPanels;
info.currentPanel = 0; info.currentPanel = 0;
} }
g_App.NumPanels = info.numPanels; g_App.NumPanels = info.numPanels;
g_App.LastFocusedPanel = info.currentPanel; g_App.LastFocusedPanel = info.currentPanel;
@@ -832,7 +835,9 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
needOpenFile = true; needOpenFile = true;
} }
HRESULT res = g_App.Create(hWnd, fullPath, g_ArcFormat, xSizes, archiveIsOpened, encrypted); HRESULT res = g_App.Create(hWnd, fullPath, g_ArcFormat, xSizes,
needOpenFile,
archiveIsOpened, encrypted);
if (res == E_ABORT) if (res == E_ABORT)
return -1; return -1;
@@ -852,6 +857,8 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
ErrorMessage(message); ErrorMessage(message);
return -1; return -1;
} }
g_WindowWasCreated = true;
// g_SplitterPos = 0; // g_SplitterPos = 0;
@@ -867,9 +874,13 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
RevokeDragDrop(hWnd); RevokeDragDrop(hWnd);
g_App._dropTarget.Release(); g_App._dropTarget.Release();
g_App.Save(); if (g_WindowWasCreated)
g_App.Save();
g_App.Release(); g_App.Release();
SaveWindowInfo(hWnd);
if (g_WindowWasCreated)
SaveWindowInfo(hWnd);
g_ExitEventLauncher.Exit(true); g_ExitEventLauncher.Exit(true);
PostQuitMessage(0); PostQuitMessage(0);

View File

@@ -333,7 +333,7 @@ void CApp::Link()
const UString srcPath = fsPrefix + srcPanel.GetItemPrefix(index); const UString srcPath = fsPrefix + srcPanel.GetItemPrefix(index);
UString path = srcPath; UString path = srcPath;
{ {
int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex); unsigned destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex);
CPanel &destPanel = Panels[destPanelIndex]; CPanel &destPanel = Panels[destPanelIndex];
if (NumPanels > 1) if (NumPanels > 1)
if (destPanel.IsFSFolder()) if (destPanel.IsFSFolder())

View File

@@ -74,6 +74,7 @@ HRESULT CPanel::Create(HWND mainWindow, HWND parentWindow, UINT id,
const UString &currentFolderPrefix, const UString &currentFolderPrefix,
const UString &arcFormat, const UString &arcFormat,
CPanelCallback *panelCallback, CAppState *appState, CPanelCallback *panelCallback, CAppState *appState,
bool needOpenArc,
bool &archiveIsOpened, bool &encrypted) bool &archiveIsOpened, bool &encrypted)
{ {
_mainWindow = mainWindow; _mainWindow = mainWindow;
@@ -100,10 +101,15 @@ HRESULT CPanel::Create(HWND mainWindow, HWND parentWindow, UINT id,
RINOK(BindToPath(cfp, arcFormat, archiveIsOpened, encrypted)); RINOK(BindToPath(cfp, arcFormat, archiveIsOpened, encrypted));
if (needOpenArc && !archiveIsOpened)
return S_OK;
if (!CreateEx(0, kClassName, 0, WS_CHILD | WS_VISIBLE, if (!CreateEx(0, kClassName, 0, WS_CHILD | WS_VISIBLE,
0, 0, _xSize, 260, 0, 0, _xSize, 260,
parentWindow, (HMENU)(UINT_PTR)id, g_hInstance)) parentWindow, (HMENU)(UINT_PTR)id, g_hInstance))
return E_FAIL; return E_FAIL;
PanelCreated = true;
return S_OK; return S_OK;
} }
@@ -525,7 +531,7 @@ bool CPanel::OnCreate(CREATESTRUCT * /* createStruct */)
_statusBar.Create(WS_CHILD | WS_VISIBLE, L"Status", (*this), _statusBarID); _statusBar.Create(WS_CHILD | WS_VISIBLE, L"Status", (*this), _statusBarID);
// _statusBar2.Create(WS_CHILD | WS_VISIBLE, L"Status", (*this), _statusBarID + 1); // _statusBar2.Create(WS_CHILD | WS_VISIBLE, L"Status", (*this), _statusBarID + 1);
int sizes[] = {160, 250, 350, -1}; const int sizes[] = {220, 320, 420, -1};
_statusBar.SetParts(4, sizes); _statusBar.SetParts(4, sizes);
// _statusBar2.SetParts(5, sizes); // _statusBar2.SetParts(5, sizes);
@@ -834,18 +840,20 @@ void CPanel::AddToArchive()
// KillSelection(); // KillSelection();
} }
static UString GetSubFolderNameForExtract(const UString &arcPath) // function from ContextMenu.cpp
UString GetSubFolderNameForExtract(const UString &arcPath);
static UString GetSubFolderNameForExtract2(const UString &arcPath)
{ {
UString s = arcPath; int slashPos = arcPath.ReverseFind_PathSepar();
int slashPos = s.ReverseFind_PathSepar(); UString s;
int dotPos = s.ReverseFind_Dot(); UString name = arcPath;
if (dotPos <= slashPos + 1) if (slashPos >= 0)
s += L'~';
else
{ {
s.DeleteFrom(dotPos); s = arcPath.Left(slashPos + 1);
s.TrimRight(); name = arcPath.Ptr(slashPos + 1);
} }
s += GetSubFolderNameForExtract(name);
return s; return s;
} }
@@ -885,7 +893,7 @@ void CPanel::ExtractArchives()
UString outFolder = GetFsPath(); UString outFolder = GetFsPath();
if (indices.Size() == 1) if (indices.Size() == 1)
outFolder += GetSubFolderNameForExtract(GetItemRelPath(indices[0])); outFolder += GetSubFolderNameForExtract2(GetItemRelPath(indices[0]));
else else
outFolder += L'*'; outFolder += L'*';
outFolder.Add_PathSepar(); outFolder.Add_PathSepar();

View File

@@ -57,7 +57,7 @@ const int kParentIndex = -1;
struct CPanelCallback struct CPanelCallback
{ {
virtual void OnTab() = 0; virtual void OnTab() = 0;
virtual void SetFocusToPath(int index) = 0; virtual void SetFocusToPath(unsigned index) = 0;
virtual void OnCopy(bool move, bool copyToSame) = 0; virtual void OnCopy(bool move, bool copyToSame) = 0;
virtual void OnSetSameFolder() = 0; virtual void OnSetSameFolder() = 0;
virtual void OnSetSubFolder() = 0; virtual void OnSetSubFolder() = 0;
@@ -222,6 +222,7 @@ struct CSelectedState
UString FocusedName; UString FocusedName;
bool SelectFocused; bool SelectFocused;
UStringVector SelectedNames; UStringVector SelectedNames;
CSelectedState(): FocusedItem(-1), SelectFocused(false) {} CSelectedState(): FocusedItem(-1), SelectFocused(false) {}
}; };
@@ -377,6 +378,8 @@ public:
bool _thereAreDeletedItems; bool _thereAreDeletedItems;
bool _markDeletedItems; bool _markDeletedItems;
bool PanelCreated;
HWND GetParent(); HWND GetParent();
UInt32 GetRealIndex(const LVITEMW &item) const UInt32 GetRealIndex(const LVITEMW &item) const
@@ -460,8 +463,8 @@ public:
HRESULT BindToPathAndRefresh(const UString &path); HRESULT BindToPathAndRefresh(const UString &path);
void OpenDrivesFolder(); void OpenDrivesFolder();
void SetBookmark(int index); void SetBookmark(unsigned index);
void OpenBookmark(int index); void OpenBookmark(unsigned index);
void LoadFullPath(); void LoadFullPath();
void LoadFullPathAndShow(); void LoadFullPathAndShow();
@@ -477,7 +480,9 @@ public:
const UString &currentFolderPrefix, const UString &currentFolderPrefix,
const UString &arcFormat, const UString &arcFormat,
CPanelCallback *panelCallback, CPanelCallback *panelCallback,
CAppState *appState, bool &archiveIsOpened, bool &encrypted); CAppState *appState,
bool needOpenArc,
bool &archiveIsOpened, bool &encrypted);
void SetFocusToList(); void SetFocusToList();
void SetFocusToLastRememberedItem(); void SetFocusToLastRememberedItem();
@@ -496,6 +501,7 @@ public:
_flatMode(false), _flatMode(false),
_flatModeForDisk(false), _flatModeForDisk(false),
_flatModeForArc(false), _flatModeForArc(false),
PanelCreated(false),
// _showNtfsStrems_Mode(false), // _showNtfsStrems_Mode(false),
// _showNtfsStrems_ModeForDisk(false), // _showNtfsStrems_ModeForDisk(false),

View File

@@ -16,6 +16,7 @@
#include "../Common/ArchiveName.h" #include "../Common/ArchiveName.h"
#include "../Common/CompressCall.h" #include "../Common/CompressCall.h"
#include "../Common/ExtractingFilePath.h"
#include "MessagesDialog.h" #include "MessagesDialog.h"
@@ -350,7 +351,10 @@ void CPanel::OnDrag(LPNMLISTVIEW /* nmListView */)
if (isFSFolder) if (isFSFolder)
s = GetItemRelPath(index); s = GetItemRelPath(index);
else else
{
s = GetItemName(index); s = GetItemName(index);
s = Get_Correct_FsFile_Name(s);
}
names.Add(fs2us(dirPrefix) + s); names.Add(fs2us(dirPrefix) + s);
} }
if (!CopyNamesToHGlobal(dataObjectSpec->hGlobal, names)) if (!CopyNamesToHGlobal(dataObjectSpec->hGlobal, names))
@@ -470,7 +474,7 @@ void CDropTarget::PositionCursor(POINTL ptl)
{ {
POINT pt2 = pt; POINT pt2 = pt;
App->_window.ScreenToClient(&pt2); App->_window.ScreenToClient(&pt2);
for (int i = 0; i < kNumPanelsMax; i++) for (unsigned i = 0; i < kNumPanelsMax; i++)
if (App->IsPanelVisible(i)) if (App->IsPanelVisible(i))
if (App->Panels[i].IsEnabled()) if (App->Panels[i].IsEnabled())
if (ChildWindowFromPointEx(App->_window, pt2, if (ChildWindowFromPointEx(App->_window, pt2,
@@ -478,7 +482,7 @@ void CDropTarget::PositionCursor(POINTL ptl)
{ {
m_Panel = &App->Panels[i]; m_Panel = &App->Panels[i];
m_IsAppTarget = false; m_IsAppTarget = false;
if (i == SrcPanelIndex) if ((int)i == SrcPanelIndex)
{ {
m_PanelDropIsAllowed = false; m_PanelDropIsAllowed = false;
return; return;

View File

@@ -263,12 +263,12 @@ HRESULT CPanel::BindToPathAndRefresh(const UString &path)
return S_OK; return S_OK;
} }
void CPanel::SetBookmark(int index) void CPanel::SetBookmark(unsigned index)
{ {
_appState->FastFolders.SetString(index, _currentFolderPrefix); _appState->FastFolders.SetString(index, _currentFolderPrefix);
} }
void CPanel::OpenBookmark(int index) void CPanel::OpenBookmark(unsigned index)
{ {
BindToPathAndRefresh(_appState->FastFolders.GetString(index)); BindToPathAndRefresh(_appState->FastFolders.GetString(index));
} }

View File

@@ -189,7 +189,7 @@ void CApp::Split()
UString srcPath = srcPanel.GetFsPath() + srcPanel.GetItemPrefix(index); UString srcPath = srcPanel.GetFsPath() + srcPanel.GetItemPrefix(index);
UString path = srcPath; UString path = srcPath;
int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex); unsigned destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex);
CPanel &destPanel = Panels[destPanelIndex]; CPanel &destPanel = Panels[destPanelIndex];
if (NumPanels > 1) if (NumPanels > 1)
if (destPanel.IsFSFolder()) if (destPanel.IsFSFolder())
@@ -367,7 +367,7 @@ void CApp::Combine()
UString srcPath = srcPanel.GetFsPath() + srcPanel.GetItemPrefix(index); UString srcPath = srcPanel.GetFsPath() + srcPanel.GetItemPrefix(index);
UString path = srcPath; UString path = srcPath;
int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex); unsigned destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex);
CPanel &destPanel = Panels[destPanelIndex]; CPanel &destPanel = Panels[destPanelIndex];
if (NumPanels > 1) if (NumPanels > 1)
if (destPanel.IsFSFolder()) if (destPanel.IsFSFolder())

View File

@@ -34,7 +34,7 @@ class CCrcHasher:
public: public:
CCrcHasher(): _crc(CRC_INIT_VAL) { SetFunctions(0); } CCrcHasher(): _crc(CRC_INIT_VAL) { SetFunctions(0); }
MY_UNKNOWN_IMP1(ICompressSetCoderProperties) MY_UNKNOWN_IMP2(IHasher, ICompressSetCoderProperties)
INTERFACE_IHasher(;) INTERFACE_IHasher(;)
STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
}; };

View File

@@ -71,7 +71,7 @@ CDynLimBuf &CDynLimBuf::operator+=(const char *s) throw()
size_t n = _pos + len; size_t n = _pos + len;
if (n - _size < _size) if (n - _size < _size)
{ {
size_t n = _sizeLimit; n = _sizeLimit;
if (n - _size > _size) if (n - _size > _size)
n = _size * 2; n = _size * 2;
} }

View File

@@ -18,7 +18,7 @@ class CSha1Hasher:
public: public:
CSha1Hasher() { Sha1_Init(&_sha); } CSha1Hasher() { Sha1_Init(&_sha); }
MY_UNKNOWN_IMP MY_UNKNOWN_IMP1(IHasher)
INTERFACE_IHasher(;) INTERFACE_IHasher(;)
}; };

View File

@@ -18,7 +18,7 @@ class CSha256Hasher:
public: public:
CSha256Hasher() { Sha256_Init(&_sha); } CSha256Hasher() { Sha256_Init(&_sha); }
MY_UNKNOWN_IMP MY_UNKNOWN_IMP1(IHasher)
INTERFACE_IHasher(;) INTERFACE_IHasher(;)
}; };

View File

@@ -19,7 +19,7 @@ class CXzCrc64Hasher:
public: public:
CXzCrc64Hasher(): _crc(CRC64_INIT_VAL) {} CXzCrc64Hasher(): _crc(CRC64_INIT_VAL) {}
MY_UNKNOWN_IMP MY_UNKNOWN_IMP1(IHasher)
INTERFACE_IHasher(;) INTERFACE_IHasher(;)
}; };

View File

@@ -10,8 +10,8 @@ AppName = "7-Zip"
InstallDir = %CE1%\%AppName% InstallDir = %CE1%\%AppName%
[Strings] [Strings]
AppVer = "15.14" AppVer = "16.00"
AppDate = "2015-12-31" AppDate = "2016-05-10"
[CEDevice] [CEDevice]
; ProcessorType = 2577 ; ARM ; ProcessorType = 2577 ; ARM

View File

@@ -1,8 +1,8 @@
;-------------------------------- ;--------------------------------
;Defines ;Defines
!define VERSION_MAJOR 15 !define VERSION_MAJOR 16
!define VERSION_MINOR 14 !define VERSION_MINOR 00
!define VERSION_POSTFIX_FULL "" !define VERSION_POSTFIX_FULL ""
!ifdef WIN64 !ifdef WIN64
!ifdef IA64 !ifdef IA64

View File

@@ -1,7 +1,7 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<?define VerMajor = "15" ?> <?define VerMajor = "16" ?>
<?define VerMinor = "14" ?> <?define VerMinor = "00" ?>
<?define VerBuild = "00" ?> <?define VerBuild = "00" ?>
<?define MmVer = "$(var.VerMajor).$(var.VerMinor)" ?> <?define MmVer = "$(var.VerMajor).$(var.VerMinor)" ?>
<?define MmHex = "$(var.VerMajor)$(var.VerMinor)" ?> <?define MmHex = "$(var.VerMajor)$(var.VerMinor)" ?>

View File

@@ -3,7 +3,7 @@
License for use and distribution License for use and distribution
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7-Zip Copyright (C) 1999-2015 Igor Pavlov. 7-Zip Copyright (C) 1999-2016 Igor Pavlov.
Licenses for files are: Licenses for files are:

View File

@@ -1,8 +1,8 @@
GNU LESSER GENERAL PUBLIC LICENSE GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999 Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc. Copyright (C) 1991, 1999 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed. of this license document, but changing it is not allowed.
@@ -10,7 +10,7 @@
as the successor of the GNU Library Public License, version 2, hence as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.] the version number 2.1.]
Preamble Preamble
The licenses for most software are designed to take away your The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public freedom to share and change it. By contrast, the GNU General Public
@@ -112,7 +112,7 @@ modification follow. Pay close attention to the difference between a
former contains code derived from the library, whereas the latter must former contains code derived from the library, whereas the latter must
be combined with the library in order to run. be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other 0. This License Agreement applies to any software library or other
@@ -146,7 +146,7 @@ such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does. and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's 1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an you conspicuously and appropriately publish on each copy an
@@ -432,7 +432,7 @@ decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing of all derivatives of our free software and of promoting the sharing
and reuse of software generally. and reuse of software generally.
NO WARRANTY NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
@@ -455,7 +455,7 @@ FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES. DAMAGES.
END OF TERMS AND CONDITIONS END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries How to Apply These Terms to Your New Libraries
@@ -485,7 +485,7 @@ convey the exclusion of warranty; and each file should have at least the
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail. Also add information on how to contact you by electronic and paper mail.
@@ -500,5 +500,3 @@ necessary. Here is a sample; alter the names:
Ty Coon, President of Vice Ty Coon, President of Vice
That's all there is to it! That's all there is to it!

View File

@@ -1,9 +1,9 @@
7-Zip 15.14 Sources 7-Zip 16.00 Sources
------------------- -------------------
7-Zip is a file archiver for Windows. 7-Zip is a file archiver for Windows.
7-Zip Copyright (C) 1999-2015 Igor Pavlov. 7-Zip Copyright (C) 1999-2016 Igor Pavlov.
License Info License Info

View File

@@ -1,6 +1,12 @@
HISTORY of the 7-Zip source code HISTORY of the 7-Zip source code
-------------------------------- --------------------------------
16.00 2016-05-10
-------------------------
- 7-Zip now can extract multivolume ZIP archives (z01, z02, ... , zip).
- Some bugs were fixed,
15.12 2015-11-19 15.12 2015-11-19
------------------------- -------------------------
- The BUG in C version of 7z decoder was fixed: - The BUG in C version of 7z decoder was fixed: