Compare commits

...

3 Commits
15.12 ... 16.00

Author SHA1 Message Date
Igor Pavlov
66ac98bb02 16.00 2016-05-28 00:16:59 +01:00
Igor Pavlov
c20d013055 15.14 2016-05-28 00:16:58 +01:00
Igor Pavlov
9608215ad8 15.13 2016-05-28 00:16:58 +01:00
143 changed files with 4299 additions and 1692 deletions

View File

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

View File

@@ -1,14 +1,14 @@
#define MY_VER_MAJOR 15
#define MY_VER_MINOR 12
#define MY_VER_MAJOR 16
#define MY_VER_MINOR 00
#define MY_VER_BUILD 0
#define MY_VERSION_NUMBERS "15.12"
#define MY_VERSION "15.12"
#define MY_DATE "2015-11-19"
#define MY_VERSION_NUMBERS "16.00"
#define MY_VERSION "16.00"
#define MY_DATE "2016-05-10"
#undef MY_COPYRIGHT
#undef MY_VERSION_COPYRIGHT_DATE
#define MY_AUTHOR_NAME "Igor Pavlov"
#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
#define MY_COPYRIGHT MY_COPYRIGHT_CR

View File

@@ -1,5 +1,5 @@
/* CpuArch.c -- CPU specific code
2015-03-25: Igor Pavlov : Public domain */
2016-02-25: Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -45,7 +45,8 @@ static UInt32 CheckFlag(UInt32 flag)
"push %%EDX\n\t"
"popf\n\t"
"andl %%EAX, %0\n\t":
"=c" (flag) : "c" (flag));
"=c" (flag) : "c" (flag) :
"%eax", "%edx");
#endif
return flag;
}
@@ -79,7 +80,13 @@ void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
#else
__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;"
"cpuid;"
"xchgl %%ebx, %%edi;"

View File

@@ -1,5 +1,5 @@
/* CpuArch.h -- CPU specific code
2015-10-31: Igor Pavlov : Public domain */
2015-12-01: Igor Pavlov : Public domain */
#ifndef __CPU_ARCH_H
#define __CPU_ARCH_H
@@ -78,7 +78,9 @@ MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned mem
|| defined(__MIPSEB) \
|| defined(_MIPSEB) \
|| defined(__m68k__) \
|| defined(__s390__) \
|| defined(__s390x__) \
|| defined(__zarch__) \
|| (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
#define MY_CPU_BE
#endif

View File

@@ -1,5 +1,5 @@
/* 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. */
#include "Precomp.h"
@@ -151,18 +151,23 @@ void Sha1_Update(CSha1 *p, const Byte *data, size_t size)
if (pos2 != 0)
{
UInt32 w = ((UInt32)data[0]) << 24;
if (--size && pos2 < 3)
UInt32 w;
pos2 = (3 - pos2) * 8;
w = ((UInt32)*data++) << pos2;
if (--size && pos2)
{
w |= ((UInt32)data[1]) << 16;
if (--size && pos2 < 2)
pos2 -= 8;
w |= ((UInt32)*data++) << pos2;
if (--size && pos2)
{
w |= ((UInt32)data[2]) << 8;
--size;
pos2 -= 8;
w |= ((UInt32)*data++) << pos2;
size--;
}
}
data += 4 - pos2;
p->buffer[pos++] |= (w >> (8 * pos2));
p->buffer[pos] |= w;
if (pos2 == 0)
pos++;
}
for (;;)

View File

@@ -1,5 +1,5 @@
/* 7zipInstall.c - 7-Zip Installer
2015-11-08 : Igor Pavlov : Public domain */
2015-12-09 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -571,6 +571,8 @@ static INT_PTR CALLBACK MyDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM
#endif
break;
}
default: return FALSE;
}
break;
@@ -1011,7 +1013,8 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
BOOL bRet;
MSG msg;
while ((bRet = GetMessage(&msg, g_HWND, 0, 0)) != 0)
// we need messages for all thread windows (including EDITTEXT window in dialog)
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
{
if (bRet == -1)
return retCode;

View File

@@ -1,5 +1,5 @@
/* 7zipUninstall.c - 7-Zip Uninstaller
2015-11-08 : Igor Pavlov : Public domain */
2015-12-26 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -542,7 +542,7 @@ static BOOL RemoveDir()
#define k_Lang L"Lang"
// NUM_LANG_TXT_FILES files are placed before en.ttt
#define NUM_LANG_TXT_FILES 86
#define NUM_LANG_TXT_FILES 87
#ifdef _64BIT_INSTALLER
#define NUM_EXTRA_FILES_64BIT 1
@@ -556,7 +556,7 @@ static const char *k_Names =
"af an ar ast az ba be bg bn br ca co cs cy da de el eo es et eu ext"
" fa fi fr fur fy ga gl gu he hi hr hu hy id io is it ja ka kaa kk ko ku ku-ckb ky"
" lij lt lv mk mn mng mng2 mr ms nb ne nl nn pa-in pl ps pt pt-br ro ru"
" sa si sk sl sq sr-spc sr-spl sv ta th tr tt ug uk uz va vi zh-cn zh-tw"
" sa si sk sl sq sr-spc sr-spl sv ta th tr tt ug uk uz va vi yo zh-cn zh-tw"
" en.ttt"
" descript.ion"
" History.txt"
@@ -771,6 +771,8 @@ static INT_PTR CALLBACK MyDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM
OnClose();
break;
}
default: return FALSE;
}
break;
@@ -1033,7 +1035,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
BOOL bRet;
MSG msg;
while ((bRet = GetMessage(&msg, g_HWND, 0, 0)) != 0)
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
{
if (bRet == -1)
return retCode;

View File

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

View File

@@ -380,29 +380,33 @@ static inline bool IsExeFilter(CMethodId m)
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;
m.Id = 0;
m.Delta = 0;
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.Props.Size() == 1)
if (coder.MethodID == k_Delta)
{
m.Delta = (unsigned)coder.Props[0] + 1;
m.Id = k_Delta;
if (coder.Props.Size() == 1)
{
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);
@@ -567,14 +571,17 @@ static const char *g_Exts =
" iso bin nrg mdf img pdi tar cpio xpi"
" vfd vhd vud vmc vsv"
" vmdk dsk nvram vmem vmsd vmsn vmss vmtm"
" inl inc idl acf asa h hpp hxx c cpp cxx rc java cs pas bas vb cls ctl frm dlg def"
" inl inc idl acf asa"
" h hpp hxx c cpp cxx m mm go swift"
" rc java cs rs pas bas vb cls ctl frm dlg def"
" f77 f f90 f95"
" asm sql manifest dep"
" asm s"
" sql manifest dep"
" mak clw csproj vcproj sln dsp dsw"
" class"
" bat cmd"
" bat cmd bash sh"
" xml xsd xsl xslt hxk hxc htm html xhtml xht mht mhtml htw asp aspx css cgi jsp shtml"
" awk sed hta js php php3 php4 php5 phptml pl pm py pyo rb sh tcl vbs"
" awk sed hta js json php php3 php4 php5 phptml pl pm py pyo rb tcl ts vbs"
" text txt tex ans asc srt reg ini doc docx mcw dot rtf hlp xls xlr xlt xlw ppt pdf"
" sxc sxd sxi sxg sxw stc sti stw stm odt ott odg otg odp otp ods ots odf"
" abw afp cwk lwp wpd wps wpt wrf wri"
@@ -1574,7 +1581,7 @@ HRESULT Update(
return E_NOTIMPL;
*/
UInt64 startBlockSize = db != 0 ? db->ArcInfo.StartPosition: 0;
UInt64 startBlockSize = db ? db->ArcInfo.StartPosition: 0;
if (startBlockSize > 0 && !options.RemoveSfxBlock)
{
RINOK(WriteRange(inStream, seqOutStream, 0, startBlockSize, NULL));
@@ -1588,8 +1595,21 @@ HRESULT Update(
CRecordVector<CFilterMode2> filters;
CObjectVector<CSolidGroup> groups;
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());
unsigned i;
@@ -1635,16 +1655,18 @@ HRESULT Update(
CFolderEx f;
db->ParseFolderEx(i, f);
bool isEncrypted = f.IsEncrypted();
unsigned groupIndex = Get_FilterGroup_for_Folder(filters, f);
const bool isEncrypted = f.IsEncrypted();
const bool needCopy = (numCopyItems == numUnpackStreams);
const bool extractFilter = (useFilters || needCopy);
unsigned groupIndex = Get_FilterGroup_for_Folder(filters, f, extractFilter);
while (groupIndex >= groups.Size())
groups.AddNew();
groups[groupIndex].folderRefs.Add(rep);
if (numCopyItems == numUnpackStreams)
if (needCopy)
complexity += db->GetFolderFullPackSize(i);
else
{
@@ -1729,22 +1751,8 @@ HRESULT Update(
// ---------- Split files to groups ----------
bool useFilters = options.UseFilters;
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++)
{
const CUpdateItem &ui = updateItems[i];
@@ -2153,7 +2161,13 @@ HRESULT Update(
#ifndef _7ZIP_ST
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();
HRESULT decodeRes = threadDecoder.Result;
// if (res == k_My_HRESULT_CRC_ERROR)
if (decodeRes == S_FALSE)

View File

@@ -348,15 +348,19 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
CMyComPtr<IInStream> nextStream = inStream;
bool prevChecked = false;
UString startVolName;
bool startVolName_was_Requested = false;
UInt64 numItems = 0;
unsigned numTempVolumes = 0;
// try
{
while (nextStream != NULL)
while (nextStream)
{
CDatabaseEx db;
db.Stream = nextStream;
HRESULT res = archive.Open(db, maxCheckStartPosition);
_errorInHeaders |= archive.HeaderError;
_errorInHeaders |= archive.ErrorInNames;
_unexpectedEnd |= archive.UnexpectedEnd;
@@ -426,6 +430,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
for (;;)
{
const COtherArc *otherArc = NULL;
if (!prevChecked)
{
if (numTempVolumes == 0)
@@ -449,18 +454,35 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
}
}
}
if (!otherArc)
{
const CInArcInfo &ai = m_Database.Volumes.Back().ArcInfo;
if (ai.IsThereNext())
otherArc = &ai.NextArc;
}
if (!otherArc)
break;
if (!openVolumeCallback)
break;
// printf("\n%s", otherArc->FileName);
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);
if (result == S_OK)
break;
@@ -572,6 +594,7 @@ public:
HRESULT FlushCorrupted(unsigned folderIndex);
HRESULT Unsupported();
bool NeedMoreWrite() const { return (m_FolderSize > m_PosInFolder); }
UInt64 GetRemain() const { return m_FolderSize - m_PosInFolder; }
UInt64 GetPosInFolder() const { return m_PosInFolder; }
};
@@ -781,6 +804,7 @@ HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processe
realProcessed += size;
if (processedSize)
*processedSize = realProcessed;
m_PosInFolder += size;
return S_OK;
// return E_FAIL;
}
@@ -830,9 +854,7 @@ STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *proc
HRESULT CFolderOutStream::FlushCorrupted(unsigned folderIndex)
{
UInt64 remain = GetRemain();
if (remain == 0)
if (!NeedMoreWrite())
{
CMyComPtr<IArchiveExtractCallbackMessage> callbackMessage;
m_ExtractCallback.QueryInterface(IID_IArchiveExtractCallbackMessage, &callbackMessage);
@@ -843,16 +865,16 @@ HRESULT CFolderOutStream::FlushCorrupted(unsigned folderIndex)
return S_OK;
}
const unsigned kBufSize = (1 << 10);
const unsigned kBufSize = (1 << 12);
Byte buf[kBufSize];
for (unsigned i = 0; i < kBufSize; i++)
buf[i] = 0;
for (;;)
{
UInt64 remain = GetRemain();
if (remain == 0)
if (!NeedMoreWrite())
return S_OK;
UInt64 remain = GetRemain();
UInt32 size = (remain < kBufSize ? (UInt32)remain : (UInt32)kBufSize);
UInt32 processedSizeLocal = 0;
RINOK(Write2(buf, size, &processedSizeLocal, false));
@@ -937,8 +959,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
CRecordVector<bool> extractStatuses;
for (i = 0; i < numItems;)
for (i = 0;;)
{
lps->OutSize = totalUnPacked;
lps->InSize = totalPacked;
RINOK(lps->SetCur());
if (i >= numItems)
break;
unsigned index = allFilesMode ? i : indices[i];
const CMvItem &mvItem = m_Database.Items[index];
@@ -1003,10 +1032,6 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
curUnpack = item.GetEndOffset();
}
lps->OutSize = totalUnPacked;
lps->InSize = totalPacked;
RINOK(lps->SetCur());
CFolderOutStream *cabFolderOutStream = new CFolderOutStream;
CMyComPtr<ISequentialOutStream> outStream(cabFolderOutStream);
@@ -1071,7 +1096,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
bool keepInputBuffer = false;
bool thereWasNotAlignedChunk = false;
for (UInt32 bl = 0; cabFolderOutStream->GetRemain() != 0;)
for (UInt32 bl = 0; cabFolderOutStream->NeedMoreWrite();)
{
if (volIndex >= m_Database.Volumes.Size())
{
@@ -1213,7 +1238,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
}
}
if (res != S_OK || cabFolderOutStream->GetRemain() != 0)
if (res != S_OK || cabFolderOutStream->NeedMoreWrite())
{
RINOK(cabFolderOutStream->FlushCorrupted(folderIndex2));
}

View File

@@ -67,6 +67,7 @@ void CInArchive::ReadOtherArc(COtherArc &oa)
ReadName(oa.DiskName);
}
struct CSignatureFinder
{
Byte *Buf;
@@ -100,6 +101,7 @@ struct CSignatureFinder
HRESULT Find();
};
HRESULT CSignatureFinder::Find()
{
for (;;)
@@ -156,6 +158,7 @@ HRESULT CSignatureFinder::Find()
}
}
bool CInArcInfo::Parse(const Byte *p)
{
if (Get32(p + 0x0C) != 0 ||
@@ -177,6 +180,7 @@ bool CInArcInfo::Parse(const Byte *p)
return true;
}
HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
{
IsArc = false;
@@ -286,7 +290,9 @@ HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
if (ai.IsThereNext()) ReadOtherArc(ai.NextArc);
UInt32 i;
db.Folders.ClearAndReserve(ai.NumFolders);
for (i = 0; i < ai.NumFolders; i++)
{
Read(p, 8);
@@ -311,6 +317,7 @@ HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
}
db.Items.ClearAndReserve(ai.NumFiles);
for (i = 0; i < ai.NumFiles; i++)
{
Read(p, 16);
@@ -324,6 +331,7 @@ HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
item.Attributes = Get16(p + 14);
ReadName(item.Name);
if (item.GetFolderIndex(db.Folders.Size()) >= (int)db.Folders.Size())
{
HeaderError = true;
@@ -336,6 +344,7 @@ HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
return S_OK;
}
HRESULT CInArchive::Open(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
{
try
@@ -370,6 +379,7 @@ static int CompareMvItems(const CMvItem *p1, const CMvItem *p2, void *param)
return MyCompare(p1->ItemIndex, p2->ItemIndex);
}
bool CMvDatabaseEx::AreItemsEqual(unsigned i1, unsigned i2)
{
const CMvItem *p1 = &Items[i1];
@@ -384,12 +394,15 @@ bool CMvDatabaseEx::AreItemsEqual(unsigned i1, unsigned i2)
&& item1.Name == item2.Name;
}
void CMvDatabaseEx::FillSortAndShrink()
{
Items.Clear();
StartFolderOfVol.Clear();
FolderStartFileIndex.Clear();
int offset = 0;
FOR_VECTOR (v, Volumes)
{
const CDatabaseEx &db = Volumes[v];
@@ -422,11 +435,12 @@ void CMvDatabaseEx::FillSortAndShrink()
FOR_VECTOR (i, Items)
{
int folderIndex = GetFolderIndex(&Items[i]);
if (folderIndex >= (int)FolderStartFileIndex.Size())
while (folderIndex >= (int)FolderStartFileIndex.Size())
FolderStartFileIndex.Add(i);
}
}
bool CMvDatabaseEx::Check()
{
for (unsigned v = 1; v < Volumes.Size(); v++)
@@ -444,9 +458,11 @@ bool CMvDatabaseEx::Check()
return false;
}
}
UInt32 beginPos = 0;
UInt64 endPos = 0;
int prevFolder = -2;
FOR_VECTOR (i, Items)
{
const CMvItem &mvItem = Items[i];
@@ -456,15 +472,19 @@ bool CMvDatabaseEx::Check()
const CItem &item = Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
if (item.IsDir())
continue;
int folderIndex = GetFolderIndex(&mvItem);
if (folderIndex != prevFolder)
prevFolder = folderIndex;
else if (item.Offset < endPos &&
(item.Offset != beginPos || item.GetEndOffset() != endPos))
return false;
beginPos = item.Offset;
endPos = item.GetEndOffset();
}
return true;
}

View File

@@ -25,6 +25,7 @@ struct COtherArc
}
};
struct CArchInfo
{
Byte VersionMinor; // cabinet file format version, minor
@@ -65,6 +66,7 @@ struct CArchInfo
}
};
struct CInArcInfo: public CArchInfo
{
UInt32 Size; // size of this cabinet file in bytes
@@ -105,17 +107,20 @@ struct CDatabase
}
};
struct CDatabaseEx: public CDatabase
{
CMyComPtr<IInStream> Stream;
};
struct CMvItem
{
unsigned VolumeIndex;
unsigned ItemIndex;
};
class CMvDatabaseEx
{
bool AreItemsEqual(unsigned i1, unsigned i2);

View File

@@ -571,23 +571,30 @@ HRESULT CDatabase::Open(IInStream *inStream)
RINOK(AddNode(-1, root.SonDid));
unsigned numCabs = 0;
FOR_VECTOR (i, Refs)
{
const CItem &item = Items[Refs[i].Did];
if (item.IsDir() || numCabs > 1)
continue;
bool isMsiName;
UString msiName = ConvertName(item.Name, isMsiName);
if (isMsiName)
const UString msiName = ConvertName(item.Name, isMsiName);
if (isMsiName && !msiName.IsEmpty())
{
// bool isThereExt = (msiName.Find(L'.') >= 0);
bool isMsiSpec = (msiName[0] == k_Msi_SpecChar);
if (msiName.Len() >= 4 && StringsAreEqualNoCase_Ascii(msiName.RightPtr(4), ".cab")
|| msiName.Len() >= 3 && msiName[0] != k_Msi_SpecChar && StringsAreEqualNoCase_Ascii(msiName.RightPtr(3), "exe"))
|| !isMsiSpec && msiName.Len() >= 3 && StringsAreEqualNoCase_Ascii(msiName.RightPtr(3), "exe")
// || !isMsiSpec && !isThereExt
)
{
numCabs++;
MainSubfile = i;
}
}
}
if (numCabs > 1)
MainSubfile = -1;

View File

@@ -34,48 +34,35 @@
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,
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, 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,
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,
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
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,77,77,77,77,77,
65,77,77,77,77,77,77,77,77,77,77,62,77,77,77,63,
52,53,54,55,56,57,58,59,60,61,77,77,77,64,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,
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,
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)
{
UInt32 val = 1;
UInt32 c = k_Base64Table[(Byte)(*src++)];
for (;;)
{
/*
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++)];
// UInt32 c = k_Base64Table[(Byte)(*src++)];
if (c < 64)
{
val = (val << 6) | c;
c = k_Base64Table[(Byte)(*src++)];
if ((val & ((UInt32)1 << 24)) == 0)
continue;
dest[0] = (Byte)(val >> 16);
@@ -85,19 +72,41 @@ static Byte *Base64ToBin(Byte *dest, const char *src)
val = 1;
continue;
}
if (c == 64)
if (c == 65) // space
continue;
if (c == 64) // '='
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 >> 16);
*dest++ = (Byte)(val);
*dest++ = (Byte)(val >> 10);
*dest++ = (Byte)(val >> 2);
}
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;
destLen = dataString->Len() / 4 * 3 + 4;
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
CExtraFile &extra = _extras.AddNew();
{

View File

@@ -1118,7 +1118,7 @@ HRESULT CHandler::SeekAndRead(IInStream *inStream, UInt64 block, Byte *data, siz
{
if (block == 0 || block >= _h.NumBlocks)
return S_FALSE;
if (((size + (1 << _h.BlockBits) + 1) >> _h.BlockBits) > _h.NumBlocks - block)
if (((size + ((size_t)1 << _h.BlockBits) - 1) >> _h.BlockBits) > _h.NumBlocks - block)
return S_FALSE;
RINOK(inStream->Seek((UInt64)block << _h.BlockBits, STREAM_SEEK_SET, NULL));
_totalRead += size;
@@ -1167,6 +1167,9 @@ HRESULT CHandler::Open2(IInStream *inStream)
RINOK(_openCallback->SetTotal(NULL, &_phySize));
}
UInt64 fileSize = 0;
RINOK(inStream->Seek(0, STREAM_SEEK_END, &fileSize));
CRecordVector<CGroupDescriptor> groups;
{
@@ -1213,6 +1216,21 @@ HRESULT CHandler::Open2(IInStream *inStream)
if (_h.NumInodes < _h.NumFreeInodes)
return S_FALSE;
UInt32 numNodes = _h.InodesPerGroup;
if (numNodes > _h.NumInodes)
numNodes = _h.NumInodes;
size_t nodesDataSize = (size_t)numNodes * _h.InodeSize;
if (nodesDataSize / _h.InodeSize != numNodes)
return S_FALSE;
// that code to reduce false detecting cases
if (nodesDataSize > fileSize)
{
if (numNodes > (1 << 24))
return S_FALSE;
}
UInt32 numReserveInodes = _h.NumInodes - _h.NumFreeInodes + 1;
// numReserveInodes = _h.NumInodes + 1;
@@ -1222,13 +1240,6 @@ HRESULT CHandler::Open2(IInStream *inStream)
_refs.Reserve(numReserveInodes);
}
UInt32 numNodes = _h.InodesPerGroup;
if (numNodes > _h.NumInodes)
numNodes = _h.NumInodes;
size_t nodesDataSize = numNodes * _h.InodeSize;
if (nodesDataSize / _h.InodeSize != numNodes)
return S_FALSE;
CByteBuffer nodesData;
nodesData.Alloc(nodesDataSize);

View File

@@ -160,10 +160,13 @@ bool CHeader::Parse(const Byte *p)
if (NumFats < 1 || NumFats > 4)
return false;
// we also support images that contain 0 in offset field.
bool isOkOffset = (codeOffset == 0 || (p[0] == 0xEB && p[1] == 0));
UInt16 numRootDirEntries = Get16(p + 17);
if (numRootDirEntries == 0)
{
if (codeOffset < 90)
if (codeOffset < 90 && !isOkOffset)
return false;
NumFatBits = 32;
NumRootDirSectors = 0;
@@ -171,7 +174,7 @@ bool CHeader::Parse(const Byte *p)
else
{
// Some FAT12s don't contain VolFields
if (codeOffset < 62 - 24)
if (codeOffset < 62 - 24 && !isOkOffset)
return false;
NumFatBits = 0;
UInt32 mask = (1 << (SectorSizeLog - 5)) - 1;

View File

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

View File

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

View File

@@ -170,7 +170,7 @@ struct CBootInitialEntry
// Partition Table found in the boot image.
UInt16 SectorCount; // This is the number of virtual/emulated sectors the system
// will store at Load Segment during the initial boot procedure.
UInt32 LoadRBA; // This is the start address of the virtual disk. CD<EFBFBD>s use
UInt32 LoadRBA; // This is the start address of the virtual disk. CDs use
// Relative/Logical block addressing.
Byte VendorSpec[20];

View File

@@ -79,7 +79,7 @@ struct CDirRecord
while (rem >= 5)
{
unsigned len = p[2];
if (len > rem)
if (len < 3 || len > rem)
return 0;
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);
CMyComPtr<ICompressCoder> coder = _filterCoder;
_filterCoder->Filter = new CBcjCoder(false);
_filterCoder->Filter = new NCompress::NBcj::CCoder(false);
_bcjStream = _filterCoder;
}
}

View File

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

View File

@@ -88,7 +88,7 @@ enum
EW_SENDMESSAGE, // SendMessage
EW_ISWINDOW, // IsWindow
EW_GETDLGITEM, // GetDlgItem
EW_SETCTLCOLORS, // SerCtlColors
EW_SETCTLCOLORS, // SetCtlColors
EW_SETBRANDINGIMAGE, // SetBrandingImage
EW_CREATEFONT, // CreateFont
EW_SHOWWINDOW, // ShowWindow, EnableWindow, HideWindow
@@ -1155,9 +1155,13 @@ bool CInArchive::IsGoodString(UInt32 param) const
if (param == 0)
return true;
const Byte *p = _data + _stringsPos;
unsigned c;
if (IsUnicode)
return (Get16(p + param * 2 - 2)) == 0;
return p[param - 1] == 0;
c = Get16(p + param * 2 - 2);
else
c = p[param - 1];
// some files have '\\' character before string?
return (c == 0 || c == '\\');
}
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_Leave = (1 << 4);
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_Creator = (1 << 5); // _Pre is used instead
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
s += isSetOutPath ? "SetOutPath" : "CreateDirectory";
AddParam(params[0]);
AddParam(params[0]);
#endif
break;
@@ -3571,15 +3575,16 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
AddParam(params[0]);
SmallSpaceComment();
/*
for (int i = 1; i < 3; i++)
AddParam_UInt(params[i]);
*/
if (params[3] != 0)
{
SmallSpaceComment();
AddParam(params[3]);
}
#endif

View File

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

View File

@@ -1148,8 +1148,16 @@ bool CMftRec::Parse(Byte *p, unsigned sectorSizeLog, UInt32 numSectors, UInt32 r
return false;
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);
// PRF(printf("\nusn = %d", usn));

View File

@@ -347,18 +347,24 @@ struct CSection
CSection(): IsRealSect(false), IsDebug(false), IsAdditionalSection(false) {}
const UInt32 GetSizeExtract() const { return PSize; }
const UInt32 GetSizeMin() const { return MyMin(PSize, VSize); }
void UpdateTotalSize(UInt32 &totalSize) const
{
UInt32 t = Pa + PSize;
if (totalSize < t)
totalSize = t;
}
void Parse(const Byte *p);
int Compare(const CSection &s) const
{
RINOZ(MyCompare(Pa, s.Pa));
return MyCompare(PSize, s.PSize);
UInt32 size1 = GetSizeExtract();
UInt32 size2 = s.GetSizeExtract();
return MyCompare(size1, size2);
}
};
@@ -1039,7 +1045,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
switch (propID)
{
case kpidPath: prop = MultiByteToUnicodeString(item.Name); break;
case kpidSize: prop = (UInt64)MyMin(item.PSize, item.VSize); break;
case kpidSize: prop = (UInt64)item.PSize; break;
case kpidPackSize: prop = (UInt64)item.PSize; break;
case kpidVirtualSize: prop = (UInt64)item.VSize; break;
case kpidOffset: prop = item.Pa; break;
@@ -1883,14 +1889,17 @@ static bool ParseVersion(const Byte *p, UInt32 size, CTextFile &f, CObjectVector
}
f.CloseBlock(2);
}
f.CloseBlock(0);
return true;
}
HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchiveOpenCallback *callback)
{
const CSection &sect = _sections[sectionIndex];
size_t fileSize = sect.PSize; // Maybe we need sect.VSize here !!!
const size_t fileSize = sect.GetSizeMin();
if (fileSize > kFileSizeMax)
return S_FALSE;
{
@@ -1917,6 +1926,7 @@ HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchi
_oneLang = true;
bool stringsOk = true;
size_t maxOffset = 0;
FOR_VECTOR (i, specItems)
{
const CTableItem &item1 = specItems[i];
@@ -1998,6 +2008,7 @@ HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchi
}
// PrintError("ver.Parse error");
}
item.Enabled = true;
_items.Add(item);
}
@@ -2031,7 +2042,10 @@ HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchi
{
UInt32 mask = (1 << numBits) - 1;
size_t end = ((maxOffset + mask) & ~mask);
// 9.29: we use only PSize. PSize can be larger than VSize
// 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;
@@ -2051,6 +2065,7 @@ HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchi
// 9.29: we use sect.PSize instead of sect.VSize to support some CAB-SFX
// the code for .rsrc_2 is commented.
sect2.PSize = sect.PSize - (UInt32)maxOffset;
if (sect2.PSize != 0)
{
sect2.VSize = sect2.PSize;
@@ -2463,7 +2478,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
else if (mixItem.ResourceIndex >= 0)
size = _items[mixItem.ResourceIndex].GetSize();
else
size = _sections[mixItem.SectionIndex].PSize;
size = _sections[mixItem.SectionIndex].GetSizeExtract();
totalSize += size;
}
extractCallback->SetTotal(totalSize);
@@ -2539,7 +2554,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
}
else
{
currentItemSize = sect.PSize;
currentItemSize = sect.GetSizeExtract();
if (!testMode && !outStream)
continue;

View File

@@ -1,5 +1,5 @@
/* PpmdHandler.c -- PPMd format handler
2010-03-10 : Igor Pavlov : Public domain
/* PpmdHandler.cpp -- PPMd format handler
2015-11-30 : Igor Pavlov : Public domain
This code is based on:
PPMd var.H (2001) / var.I (2002): Dmitry Shkarin : Public domain
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
@@ -349,6 +349,7 @@ struct CPpmdCpp
}
};
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testMode, IArchiveExtractCallback *extractCallback)
{
@@ -386,13 +387,17 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
CPpmdCpp ppmd(_item.Ver);
if (!ppmd.Alloc(_item.MemInMB))
return E_OUTOFMEMORY;
Int32 opRes = NExtract::NOperationResult::kUnsupportedMethod;
if (_item.IsSupported())
{
opRes = NExtract::NOperationResult::kDataError;
ppmd.Init(_item.Order, _item.Restor);
inBuf.Init();
UInt64 outSize = 0;
if (ppmd.InitRc(&inBuf) && !inBuf.Extra && inBuf.Res == S_OK)
for (;;)
{
@@ -431,6 +436,13 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
{
RINOK(WriteStream(realOutStream, outBuf.Buf, i));
}
if (inBuf.Extra)
{
opRes = NExtract::NOperationResult::kUnexpectedEnd;
break;
}
if (sym < 0)
{
if (sym == -1 && ppmd.IsFinishedOK())
@@ -438,12 +450,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
break;
}
}
RINOK(inBuf.Res);
}
realOutStream.Release();
return extractCallback->SetOperationResult(opRes);
}
static const Byte k_Signature[] = { 0x8F, 0xAF, 0xAC, 0x84 };
REGISTER_ARC_I(

View File

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

View File

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

View File

@@ -42,6 +42,8 @@ struct CItem
Byte Salt[8];
bool Is_Size_Defined() const { return Size != (UInt64)(Int64)-1; }
bool IsEncrypted() const { return (Flags & NHeader::NFile::kEncrypted) != 0; }
bool IsSolid() const { return (Flags & NHeader::NFile::kSolid) != 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;
{
/*
NCOM::CPropVariant prop;
RINOK(volumeCallback->GetProperty(kpidSize, &prop));
if (prop.vt != VT_UI8)
return E_INVALIDARG;
size = prop.uhVal.QuadPart;
*/
RINOK(stream->Seek(0, STREAM_SEEK_END, &size));
RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
}
_totalSize += size;
@@ -217,11 +221,15 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
if (!stream)
break;
{
/*
NCOM::CPropVariant prop;
RINOK(volumeCallback->GetProperty(kpidSize, &prop));
if (prop.vt != VT_UI8)
return E_INVALIDARG;
size = prop.uhVal.QuadPart;
*/
RINOK(stream->Seek(0, STREAM_SEEK_END, &size));
RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
}
_totalSize += size;
_sizes.Add(size);

View File

@@ -389,7 +389,10 @@ HRESULT CInArchive::ReadFileItem(int volIndex, int fsIndex, const CLongAllocDesc
return S_FALSE;
CFile &file = Files.Back();
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 value;

View File

@@ -475,14 +475,10 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidPackSize:
{
UInt64 size = 0;
if (si)
{
if (!si->Resource.IsSolidSmall())
{
size = si->Resource.PackSize;
prop = size;
}
prop = si->Resource.PackSize;
else
{
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;
}
case kpidSize:
{
UInt64 size = 0;
if (si)
{
if (si->Resource.IsSolid())
@@ -507,22 +505,19 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
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;
}
}
else
{
size = si->Resource.PackSize;
prop = size;
}
prop = si->Resource.PackSize;
}
else
{
size = si->Resource.UnpackSize;
prop = size;
}
prop = si->Resource.UnpackSize;
}
else if (!item.IsDir)
prop = (UInt64)0;
break;
}

View File

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

View File

@@ -4,6 +4,7 @@
#include "../../../Common/ComTry.h"
#include "../../../Common/IntToString.h"
#include "../../../Common/StringConvert.h"
#include "../../../Windows/PropVariant.h"
#include "../../../Windows/TimeUtils.h"
@@ -11,6 +12,7 @@
#include "../../IPassword.h"
#include "../../Common/FilterCoder.h"
#include "../../Common/LimitedStreams.h"
#include "../../Common/ProgressUtils.h"
#include "../../Common/StreamObjects.h"
#include "../../Common/StreamUtils.h"
@@ -141,14 +143,19 @@ static const Byte kProps[] =
kpidCRC,
kpidMethod,
kpidHostOS,
kpidUnpackVer
kpidUnpackVer,
kpidVolumeIndex
};
static const Byte kArcProps[] =
{
kpidEmbeddedStubSize,
kpidBit64,
kpidComment
kpidComment,
kpidTotalPhySize,
kpidIsVolume,
kpidVolumeIndex,
kpidNumVolumes
};
CHandler::CHandler()
@@ -174,18 +181,23 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
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 kpidPhySize: prop = m_Archive.ArcInfo.GetPhySize(); break;
case kpidOffset: /* if (m_Archive.ArcInfo.Base != 0) */
prop = m_Archive.ArcInfo.Base; break;
case kpidPhySize: prop = m_Archive.GetPhySize(); break;
case kpidOffset: prop = m_Archive.GetOffset(); break;
case kpidEmbeddedStubSize:
{
UInt64 stubSize = m_Archive.ArcInfo.GetEmbeddedStubSize();
UInt64 stubSize = m_Archive.GetEmbeddedStubSize();
if (stubSize != 0)
prop = stubSize;
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:
{
UInt32 v = 0;
@@ -196,6 +208,18 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
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:
{
UInt32 v = 0;
@@ -208,7 +232,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
but the stream has access only to zip part.
In that case we ignore UnavailableStart error.
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)
v |= kpv_ErrorFlags_UnavailableStart;
}
@@ -241,12 +265,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop;
const CItemEx &item = m_Items[index];
const CExtraBlock &extra = item.GetMainExtra();
switch (propID)
{
case kpidPath:
{
UString res;
item.GetUnicodeString(item.Name, res, _forceCodePage, _specifiedCodePage);
item.GetUnicodeString(res, item.Name, false, _forceCodePage, _specifiedCodePage);
NItemName::ConvertToOSName2(res);
prop = res;
break;
@@ -261,9 +287,9 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
FILETIME ft;
UInt32 unixTime;
UInt32 type;
if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, ft))
if (extra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, ft))
type = NFileTimeType::kWindows;
else if (item.CentralExtra.GetUnixTime(true, NFileHeader::NUnixTime::kMTime, unixTime))
else if (extra.GetUnixTime(true, NFileHeader::NUnixTime::kMTime, unixTime))
type = NFileTimeType::kUnix;
else
type = NFileTimeType::kDOS;
@@ -274,7 +300,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidCTime:
{
FILETIME ft;
if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kCTime, ft))
if (extra.GetNtfsTime(NFileHeader::NNtfsExtra::kCTime, ft))
prop = ft;
break;
}
@@ -282,7 +308,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidATime:
{
FILETIME ft;
if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kATime, ft))
if (extra.GetNtfsTime(NFileHeader::NNtfsExtra::kATime, ft))
prop = ft;
break;
}
@@ -291,10 +317,10 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
FILETIME utc;
bool defined = true;
if (!item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, utc))
if (!extra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, utc))
{
UInt32 unixTime = 0;
if (item.CentralExtra.GetUnixTime(true, NFileHeader::NUnixTime::kMTime, unixTime))
if (extra.GetUnixTime(true, NFileHeader::NUnixTime::kMTime, unixTime))
NTime::UnixTimeToFileTime(unixTime, utc);
else
{
@@ -328,7 +354,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
if (item.Comment.Size() != 0)
{
UString res;
item.GetUnicodeString(BytesToString(item.Comment), res, _forceCodePage, _specifiedCodePage);
item.GetUnicodeString(res, BytesToString(item.Comment), true, _forceCodePage, _specifiedCodePage);
prop = res;
}
break;
@@ -347,7 +373,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
m += kMethod_AES;
CWzAesExtra aesField;
if (item.CentralExtra.GetWzAes(aesField))
if (extra.GetWzAes(aesField))
{
char s[16];
s[0] = '-';
@@ -360,7 +386,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
CStrongCryptoExtra f;
f.AlgId = 0;
if (item.CentralExtra.GetStrongCrypto(f))
if (extra.GetStrongCrypto(f))
{
const char *s = FindNameForId(k_StrongCryptoPairs, ARRAY_SIZE(k_StrongCryptoPairs), f.AlgId);
if (s)
@@ -426,36 +452,17 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidUnpackVer:
prop = (UInt32)item.ExtractVersion.Version;
break;
case kpidVolumeIndex:
prop = item.Disk;
break;
}
prop.Detach(value);
return S_OK;
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,
const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback)
@@ -464,9 +471,13 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
try
{
Close();
RINOK(m_Archive.Open(inStream, maxCheckStartPosition));
CProgressImp progressImp(callback);
return m_Archive.ReadHeaders(m_Items, callback ? &progressImp : NULL);
HRESULT res = m_Archive.Open(inStream, maxCheckStartPosition, callback, m_Items);
if (res != S_OK)
{
m_Items.Clear();
m_Archive.ClearRefs();
}
return res;
}
catch(...) { Close(); throw; }
COM_TRY_END
@@ -479,8 +490,6 @@ STDMETHODIMP CHandler::Close()
return S_OK;
}
//////////////////////////////////////
// CHandler::DecompressItems
class CLzmaDecoder:
public ICompressCoder,
@@ -546,6 +555,8 @@ struct CMethodItem
CMyComPtr<ICompressCoder> Coder;
};
class CZipDecoder
{
NCrypto::NZip::CDecoder *_zipCryptoDecoderSpec;
@@ -580,6 +591,24 @@ public:
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(
DECL_EXTERNAL_CODECS_LOC_VARS
CInArchive &archive, const CItemEx &item,
@@ -617,7 +646,7 @@ HRESULT CZipDecoder::Decode(
if (!pkAesMode && id == NFileHeader::NCompressionMethod::kWzAES)
{
CWzAesExtra aesField;
if (item.CentralExtra.GetWzAes(aesField))
if (item.GetMainExtra().GetWzAes(aesField))
{
wzAesMode = true;
needCRC = aesField.NeedCrc();
@@ -630,9 +659,11 @@ HRESULT CZipDecoder::Decode(
outStreamSpec->SetStream(realOutStream);
outStreamSpec->Init(needCRC);
UInt64 authenticationPos;
CMyComPtr<ISequentialInStream> inStream;
CMyComPtr<ISequentialInStream> packStream;
CLimitedSequentialInStream *limitedStreamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream(limitedStreamSpec);
{
UInt64 packSize = item.PackSize;
if (wzAesMode)
@@ -641,9 +672,14 @@ HRESULT CZipDecoder::Decode(
return S_OK;
packSize -= NCrypto::NWzAes::kMacSize;
}
UInt64 dataPos = item.GetDataPosition();
inStream.Attach(archive.CreateLimitedStream(dataPos, packSize));
authenticationPos = dataPos + packSize;
RINOK(archive.GetItemStream(item, true, packStream));
if (!packStream)
{
res = NExtract::NOperationResult::kUnavailable;
return S_OK;
}
limitedStreamSpec->SetStream(packStream);
limitedStreamSpec->Init(packSize);
}
CMyComPtr<ICompressFilter> cryptoFilter;
@@ -653,7 +689,7 @@ HRESULT CZipDecoder::Decode(
if (wzAesMode)
{
CWzAesExtra aesField;
if (!item.CentralExtra.GetWzAes(aesField))
if (!item.GetMainExtra().GetWzAes(aesField))
return S_OK;
id = aesField.Method;
if (!_wzAesDecoder)
@@ -908,9 +944,15 @@ HRESULT CZipDecoder::Decode(
bool authOk = true;
if (needCRC)
crcOK = (outStreamSpec->GetCRC() == item.Crc);
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)
authOk = false;
}
@@ -984,16 +1026,21 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnavailable));
continue;
}
if (!item.FromLocal)
{
HRESULT res = m_Archive.ReadLocalItemAfterCdItem(item);
bool isAvail = true;
HRESULT res = m_Archive.ReadLocalItemAfterCdItem(item, isAvail);
if (res == S_FALSE)
{
if (item.IsDir() || realOutStream || testMode)
{
RINOK(extractCallback->PrepareOperation(askMode));
realOutStream.Release();
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kHeadersError));
RINOK(extractCallback->SetOperationResult(
isAvail ?
NExtract::NOperationResult::kHeadersError :
NExtract::NOperationResult::kUnavailable));
}
continue;
}
@@ -1030,6 +1077,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
RINOK(extractCallback->SetOperationResult(res))
}
lps->InSize = currentTotalPacked;
lps->OutSize = currentTotalUnPacked;
return lps->SetCur();

View File

@@ -18,9 +18,8 @@ namespace NSignature
const UInt32 kEcd = 0x06054B50;
const UInt32 kEcd64 = 0x06064B50;
const UInt32 kEcd64Locator = 0x07064B50;
// const UInt32 kSpan = 0x08074B50;
const UInt32 kNoSpan = 0x30304b50; // PK00, replaces kSpan, if there is only 1 segment
const UInt32 kSpan = 0x08074B50;
const UInt32 kNoSpan = 0x30304B50; // PK00, replaces kSpan, if there is only 1 segment
}
const unsigned kLocalHeaderSize = 4 + 26; // including signature
@@ -84,6 +83,8 @@ namespace NFileHeader
kNTFS = 0x0A,
kStrongEncrypt = 0x17,
kUnixTime = 0x5455,
kIzUnicodeComment = 0x6375,
kIzUnicodeName = 0x7075,
kWzAES = 0x9901
};
}

View File

File diff suppressed because it is too large Load Diff

View File

@@ -28,6 +28,7 @@ public:
{ return LocalHeaderPos + LocalFullHeaderSize; }
};
struct CInArchiveInfo
{
Int64 Base; /* Base offset of start of archive in stream.
@@ -40,74 +41,195 @@ struct CInArchiveInfo
Base = ArcInfo.MarkerPos; */
/* 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 - 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 FinishPos; // Finish pos of archive data
UInt64 FinishPos; // Finish pos of archive data in starting volume
UInt64 FileEndPos; // Finish pos of stream
UInt64 FirstItemRelatOffset; /* Relative offset of first local (read from cd) (relative to Base).
= 0 in most archives
= size of stub for some SFXs */
bool CdWasRead;
bool IsSpanMode;
bool ThereIsTail;
// UInt32 BaseVolIndex;
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()
{
// BaseVolIndex = 0;
Base = 0;
MarkerPos = 0;
MarkerPos2 = 0;
FinishPos = 0;
FileEndPos = 0;
ThereIsTail = false;
FirstItemRelatOffset = 0;
CdWasRead = false;
IsSpanMode = false;
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
{
// 64
UInt16 VersionMade;
UInt16 VersionNeedExtract;
// old zip
UInt32 ThisDisk;
UInt32 CdDisk;
UInt64 NumEntries_in_ThisDisk;
UInt64 NumEntries;
UInt64 Size;
UInt64 Offset;
void ParseEcd(const Byte *p);
void ParseEcd64(const Byte *p);
UInt16 CommentSize;
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
{
CInBuffer _inBuffer;
bool _inBufMode;
UInt32 m_Signature;
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 FindAndReadMarker(IInStream *stream, const UInt64 *searchHeaderSizeLimit);
HRESULT IncreaseRealPosition(Int64 addValue);
HRESULT FindMarker(IInStream *stream, const UInt64 *searchLimit);
HRESULT IncreaseRealPosition(Int64 addValue, bool &isFinished);
HRESULT ReadBytes(void *data, UInt32 size, UInt32 *processedSize);
void SafeReadBytes(void *data, unsigned size);
@@ -126,12 +248,14 @@ class CInArchive
HRESULT ReadLocalItemDescriptor(CItemEx &item);
HRESULT ReadCdItem(CItemEx &item);
HRESULT TryEcd64(UInt64 offset, CCdInfo &cdInfo);
HRESULT FindCd(CCdInfo &cdInfo);
HRESULT TryReadCd(CObjectVector<CItemEx> &items, UInt64 cdOffset, UInt64 cdSize, CProgressVirt *progress);
HRESULT ReadCd(CObjectVector<CItemEx> &items, UInt64 &cdOffset, UInt64 &cdSize, CProgressVirt *progress);
HRESULT ReadLocals(CObjectVector<CItemEx> &localItems, CProgressVirt *progress);
HRESULT FindCd(bool checkOffsetMode);
HRESULT TryReadCd(CObjectVector<CItemEx> &items, const CCdInfo &cdInfo, UInt64 cdOffset, UInt64 cdSize);
HRESULT ReadCd(CObjectVector<CItemEx> &items, UInt32 &cdDisk, UInt64 &cdOffset, UInt64 &cdSize);
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:
CInArchiveInfo ArcInfo;
@@ -142,46 +266,87 @@ public:
bool ExtraMinorError;
bool UnexpectedEnd;
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 AreThereErrors() const { return HeadersError || UnexpectedEnd; }
bool MarkerIsFound;
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
{
if (item.FromLocal)
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);
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
{
if (AreThereErrors())
return false;
if (ArcInfo.Base < 0)
return false;
if ((Int64)ArcInfo.MarkerPos2 < ArcInfo.Base)
if (AreThereErrors()
|| IsMultiVol
|| ArcInfo.Base < 0
|| (Int64)ArcInfo.MarkerPos2 < ArcInfo.Base
|| ArcInfo.ThereIsTail
|| GetEmbeddedStubSize() != 0)
return false;
// 7-zip probably can update archives with embedded stubs.
// we just disable that feature for more safety.
if (ArcInfo.GetEmbeddedStubSize() != 0)
return false;
if (ArcInfo.ThereIsTail())
return false;
return true;
}
};

View File

@@ -3,8 +3,10 @@
#include "StdAfx.h"
#include "../../../../C/CpuArch.h"
#include "../../../../C/7zCrc.h"
#include "../../../Common/MyLinux.h"
#include "../../../Common/StringConvert.h"
#include "../Common/ItemNameUtils.h"
@@ -80,6 +82,30 @@ bool CExtraSubBlock::ExtractUnixTime(bool isCentral, unsigned index, UInt32 &res
return false;
}
bool CExtraBlock::GetNtfsTime(unsigned index, FILETIME &ft) const
{
FOR_VECTOR (i, SubBlocks)
{
const CExtraSubBlock &sb = SubBlocks[i];
if (sb.ID == NFileHeader::NExtraID::kNTFS)
return sb.ExtractNtfsTime(index, ft);
}
return false;
}
bool CExtraBlock::GetUnixTime(bool isCentral, unsigned index, UInt32 &res) const
{
FOR_VECTOR (i, SubBlocks)
{
const CExtraSubBlock &sb = SubBlocks[i];
if (sb.ID == NFileHeader::NExtraID::kUnixTime)
return sb.ExtractUnixTime(isCentral, index, res);
}
return false;
}
bool CLocalItem::IsDir() const
{
return NItemName::HasTailSlash(Name, GetCodePage());
@@ -89,12 +115,29 @@ bool CItem::IsDir() const
{
if (NItemName::HasTailSlash(Name, GetCodePage()))
return true;
Byte hostOS = GetHostOS();
if (Size == 0 && PackSize == 0 && !Name.IsEmpty() && Name.Back() == '\\')
{
// do we need to use CharPrevExA?
// .NET Framework 4.5 : System.IO.Compression::CreateFromDirectory() probably writes backslashes to headers?
// so we support that case
switch (hostOS)
{
case NHostOS::kFAT:
case NHostOS::kNTFS:
case NHostOS::kHPFS:
case NHostOS::kVFAT:
return true;
}
}
if (!FromCentral)
return false;
UInt16 highAttrib = (UInt16)((ExternalAttrib >> 16 ) & 0xFFFF);
Byte hostOS = GetHostOS();
switch (hostOS)
{
case NHostOS::kAMIGA:
@@ -158,4 +201,53 @@ bool CItem::GetPosixAttrib(UInt32 &attrib) const
return false;
}
void CItem::GetUnicodeString(UString &res, const AString &s, bool isComment, bool useSpecifiedCodePage, UINT codePage) const
{
bool isUtf8 = IsUtf8();
bool ignore_Utf8_Errors = true;
if (!isUtf8)
{
{
const unsigned id = isComment ?
NFileHeader::NExtraID::kIzUnicodeComment:
NFileHeader::NExtraID::kIzUnicodeName;
const CObjectVector<CExtraSubBlock> &subBlocks = GetMainExtra().SubBlocks;
FOR_VECTOR (i, subBlocks)
{
const CExtraSubBlock &sb = subBlocks[i];
if (sb.ID == id)
{
AString utf;
if (sb.ExtractIzUnicode(CrcCalc(s, s.Len()), utf))
if (ConvertUTF8ToUnicode(utf, res))
return;
break;
}
}
}
if (useSpecifiedCodePage)
isUtf8 = (codePage == CP_UTF8);
#ifdef _WIN32
else if (GetHostOS() == NFileHeader::NHostOS::kUnix)
{
/* Some ZIP archives in Unix use UTF-8 encoding without Utf8 flag in header.
We try to get name as UTF-8.
Do we need to do it in POSIX version also? */
isUtf8 = true;
ignore_Utf8_Errors = false;
}
#endif
}
if (isUtf8)
if (ConvertUTF8ToUnicode(s, res) || ignore_Utf8_Errors)
return;
MultiByteToUnicodeString2(res, s, useSpecifiedCodePage ? codePage : GetCodePage());
}
}}

View File

@@ -7,7 +7,6 @@
#include "../../../Common/MyBuffer.h"
#include "../../../Common/MyString.h"
#include "../../../Common/StringConvert.h"
#include "../../../Common/UTFConvert.h"
#include "ZipHeader.h"
@@ -28,6 +27,23 @@ struct CExtraSubBlock
bool ExtractNtfsTime(unsigned index, FILETIME &ft) const;
bool ExtractUnixTime(bool isCentral, unsigned index, UInt32 &res) const;
bool ExtractIzUnicode(UInt32 crc, AString &name) const
{
unsigned size = (unsigned)Data.Size();
if (size < 1 + 4)
return false;
const Byte *p = (const Byte *)Data;
if (p[0] > 1)
return false;
if (crc != GetUi32(p + 1))
return false;
size -= 5;
name.SetFrom_CalcLen((const char *)p + 5, size);
if (size != name.Len())
return false;
return CheckUTF8(name, false);
}
};
const unsigned k_WzAesExtra_Size = 7;
@@ -157,27 +173,8 @@ struct CExtraBlock
}
*/
bool GetNtfsTime(unsigned index, FILETIME &ft) const
{
FOR_VECTOR (i, SubBlocks)
{
const CExtraSubBlock &sb = SubBlocks[i];
if (sb.ID == NFileHeader::NExtraID::kNTFS)
return sb.ExtractNtfsTime(index, ft);
}
return false;
}
bool GetUnixTime(bool isCentral, unsigned index, UInt32 &res) const
{
FOR_VECTOR (i, SubBlocks)
{
const CExtraSubBlock &sb = SubBlocks[i];
if (sb.ID == NFileHeader::NExtraID::kUnixTime)
return sb.ExtractUnixTime(isCentral, index, res);
}
return false;
}
bool GetNtfsTime(unsigned index, FILETIME &ft) const;
bool GetUnixTime(bool isCentral, unsigned index, UInt32 &res) const;
void RemoveUnknownSubBlocks()
{
@@ -202,6 +199,8 @@ public:
UInt64 PackSize;
UInt32 Time;
UInt32 Crc;
UInt32 Disk;
AString Name;
@@ -274,45 +273,22 @@ public:
MadeByVersion.HostOS = 0;
}
const CExtraBlock &GetMainExtra() const { return *(FromCentral ? &CentralExtra : &LocalExtra); }
bool IsDir() const;
UInt32 GetWinAttrib() const;
bool GetPosixAttrib(UInt32 &attrib) const;
Byte GetHostOS() const { return FromCentral ? MadeByVersion.HostOS : ExtractVersion.HostOS; }
void GetUnicodeString(const AString &s, UString &res, bool useSpecifiedCodePage, UINT codePage) const
{
bool isUtf8 = IsUtf8();
bool ignore_Utf8_Errors = true;
#ifdef _WIN32
if (!isUtf8)
{
if (useSpecifiedCodePage)
isUtf8 = (codePage == CP_UTF8);
else if (GetHostOS() == NFileHeader::NHostOS::kUnix)
{
/* Some ZIP archives in Unix use UTF-8 encoding without Utf8 flag in header.
We try to get name as UTF-8.
Do we need to do it in POSIX version also? */
isUtf8 = true;
ignore_Utf8_Errors = false;
}
}
#endif
if (isUtf8)
if (ConvertUTF8ToUnicode(s, res) || ignore_Utf8_Errors)
return;
MultiByteToUnicodeString2(res, s, useSpecifiedCodePage ? codePage : GetCodePage());
}
void GetUnicodeString(UString &res, const AString &s, bool isComment, bool useSpecifiedCodePage, UINT codePage) const;
bool IsThereCrc() const
{
if (Method == NFileHeader::NCompressionMethod::kWzAES)
{
CWzAesExtra aesField;
if (CentralExtra.GetWzAes(aesField))
if (GetMainExtra().GetWzAes(aesField))
return aesField.NeedCrc();
}
return (Crc != 0 || !IsDir());
@@ -322,8 +298,10 @@ public:
{
Byte hostOS = GetHostOS();
return (UINT)((
hostOS == NFileHeader::NHostOS::kFAT ||
hostOS == NFileHeader::NHostOS::kNTFS) ? CP_OEMCP : CP_ACP);
hostOS == NFileHeader::NHostOS::kFAT
|| hostOS == NFileHeader::NHostOS::kNTFS
|| hostOS == NFileHeader::NHostOS::kUnix // do we need it?
) ? CP_OEMCP : CP_ACP);
}
};

View File

@@ -12,10 +12,11 @@ namespace NZip {
static const Byte k_Signature[] = {
4, 0x50, 0x4B, 0x03, 0x04,
4, 0x50, 0x4B, 0x05, 0x06,
6, 0x50, 0x4B, 0x07, 0x08, 0x50, 0x4B,
6, 0x50, 0x4B, 0x30, 0x30, 0x50, 0x4B };
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,
0,
NArcInfoFlags::kFindSignature |

View File

@@ -52,16 +52,6 @@ static HRESULT CopyBlockToArchive(ISequentialInStream *inStream, UInt64 size,
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(
COutArchive &archive,
const CCompressionMethodMode &options,
@@ -358,9 +348,12 @@ static HRESULT UpdateItemOldData(
return E_NOTIMPL;
// 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
// item.ExternalAttrib = ui.Attrib;
@@ -378,19 +371,27 @@ static HRESULT UpdateItemOldData(
archive.PrepareWriteCompressedData2(item.Name.Len(), item.Size, item.PackSize, item.LocalExtra.HasWzAes());
archive.WriteLocalHeader(item);
RINOK(WriteRange(inArchive->Stream, archive, range, progress));
complexity += range.Size;
RINOK(CopyBlockToArchive(packStream, itemEx.PackSize, archive, progress));
complexity += itemEx.PackSize;
}
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
item.LocalHeaderPos = archive.GetCurPos();
RINOK(WriteRange(inArchive->Stream, archive, range, progress));
complexity += range.Size;
archive.MoveCurPos(range.Size);
const UInt64 rangeSize = itemEx.GetLocalFullSize();
RINOK(CopyBlockToArchive(packStream, rangeSize, archive, progress));
complexity += rangeSize;
archive.MoveCurPos(rangeSize);
}
return S_OK;
@@ -1191,10 +1192,11 @@ HRESULT Update(
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));
RINOK(NCompress::CopyStream_ExactSize(inArchive->Stream, outStreamReal, inArchive->ArcInfo.Base, NULL));
IInStream *baseStream = inArchive->GetBaseStream();
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 ((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;
RINOK(NCompress::CopyStream_ExactSize(inArchive->Stream, outStream, embStubSize, NULL));
RINOK(NCompress::CopyStream_ExactSize(baseStream, outStream, embStubSize, NULL));
outArchive.MoveCurPos(embStubSize);
}
}

View File

@@ -325,14 +325,6 @@ SOURCE=..\..\UI\FileManager\ComboDialog.h
# End Source File
# Begin Source File
SOURCE=..\..\UI\FileManager\MessagesDialog.cpp
# End Source File
# Begin Source File
SOURCE=..\..\UI\FileManager\MessagesDialog.h
# End Source File
# Begin Source File
SOURCE=..\..\UI\FileManager\OverwriteDialog.cpp
# End Source File
# Begin Source File

View File

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

View File

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

View File

@@ -783,7 +783,7 @@ void CState::ThreadFunc()
}
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; }
if (res != S_OK)
{
@@ -809,7 +809,7 @@ void CState::ThreadFunc()
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; }
if (res != S_OK)
{

View File

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

View File

@@ -5,14 +5,21 @@
#include "../Common/RegisterCodec.h"
#include "BZip2Decoder.h"
REGISTER_CODEC_CREATE(CreateDec, NCompress::NBZip2::CDecoder)
#if !defined(EXTRACT_ONLY) && !defined(BZIP2_EXTRACT_ONLY)
#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
#define CreateEnc NULL
#endif
REGISTER_CODEC_2(BZip2, CreateDec, CreateEnc, 0x40202, "BZip2")
}}

View File

@@ -6,9 +6,12 @@
#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
REGISTER_CODEC_CREATE_2(CreateCodecOut, NCompress::NBcj2::CEncoder(), ICompressCoder2)
REGISTER_CODEC_CREATE_2(CreateCodecOut, CEncoder(), ICompressCoder2)
#else
#define CreateCodecOut NULL
#endif
@@ -17,3 +20,5 @@ REGISTER_CODEC_VAR
{ CreateCodec, CreateCodecOut, 0x303011B, "BCJ2", 4, false };
REGISTER_CODEC(BCJ2)
}}

View File

@@ -4,16 +4,21 @@
#include "BcjCoder.h"
STDMETHODIMP CBcjCoder::Init()
namespace NCompress {
namespace NBcj {
STDMETHODIMP CCoder::Init()
{
_bufferPos = 0;
x86_Convert_Init(_prevMask);
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);
_bufferPos += processed;
return processed;
}
}}

View File

@@ -9,7 +9,10 @@
#include "../ICoder.h"
class CBcjCoder:
namespace NCompress {
namespace NBcj {
class CCoder:
public ICompressFilter,
public CMyUnknownImp
{
@@ -17,10 +20,12 @@ class CBcjCoder:
UInt32 _prevMask;
int _encode;
public:
MY_UNKNOWN_IMP;
MY_UNKNOWN_IMP1(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

View File

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

View File

@@ -4,15 +4,20 @@
#include "BranchMisc.h"
STDMETHODIMP CBranchCoder::Init()
namespace NCompress {
namespace NBranch {
STDMETHODIMP CCoder::Init()
{
_bufferPos = 0;
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);
_bufferPos += processed;
return processed;
}
}}

View File

@@ -13,7 +13,10 @@ typedef SizeT (*Func_Bra)(Byte *data, SizeT size, UInt32 ip, int encoding);
EXTERN_C_END
class CBranchCoder:
namespace NCompress {
namespace NBranch {
class CCoder:
public ICompressFilter,
public CMyUnknownImp
{
@@ -21,10 +24,12 @@ class CBranchCoder:
int _encode;
Func_Bra BraFunc;
public:
MY_UNKNOWN_IMP;
MY_UNKNOWN_IMP1(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

View File

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

View File

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

View File

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

View File

@@ -6,13 +6,21 @@
#include "DeflateDecoder.h"
REGISTER_CODEC_CREATE(CreateDec, NCompress::NDeflate::NDecoder::CCOMCoder64())
#if !defined(EXTRACT_ONLY) && !defined(DEFLATE_EXTRACT_ONLY)
#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
#define CreateEnc NULL
#endif
REGISTER_CODEC_2(Deflate64, CreateDec, CreateEnc, 0x40109, "Deflate64")
}}

View File

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

View File

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

View File

@@ -5,14 +5,21 @@
#include "../Common/RegisterCodec.h"
#include "DeflateDecoder.h"
REGISTER_CODEC_CREATE(CreateDec, NCompress::NDeflate::NDecoder::CCOMCoder)
#if !defined(EXTRACT_ONLY) && !defined(DEFLATE_EXTRACT_ONLY)
#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
#define CreateEnc NULL
#endif
REGISTER_CODEC_2(Deflate, CreateDec, CreateEnc, 0x40108, "Deflate")
}}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -9,7 +9,9 @@
#include "Rar3Decoder.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(2)
@@ -27,3 +29,5 @@ REGISTER_CODECS_VAR
};
REGISTER_CODECS(Rar)
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -917,7 +917,7 @@ void CArcCmdLineParser::Parse1(const UStringVector &commandStrings,
if (parser[NKey::kAffinity].ThereIs)
{
const UString &s = us2fs(parser[NKey::kAffinity].PostStrings[0]);
const UString &s = parser[NKey::kAffinity].PostStrings[0];
if (!s.IsEmpty())
{
UInt32 v = 0;
@@ -1053,7 +1053,7 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
unsigned numNonSwitchStrings = nonSwitchStrings.Size();
if (numNonSwitchStrings < kMinNonSwitchWords)
throw CArcCmdLineException("The command must be spcified");
throw CArcCmdLineException("The command must be specified");
if (!ParseArchiveCommand(nonSwitchStrings[kCommandIndex], options.Command))
throw CArcCmdLineException("Unsupported command:", nonSwitchStrings[kCommandIndex]);

View File

@@ -1265,7 +1265,7 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
CReparseAttr attr;
if (!attr.Parse(data, data.Size()))
{
RINOK(SendMessageError("Internal error for symbolic link file", _item.Path));
RINOK(SendMessageError("Internal error for symbolic link file", us2fs(_item.Path)));
// return E_FAIL;
}
else

View File

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

View File

@@ -2487,7 +2487,7 @@ HRESULT Bench(
#ifdef USE_WIN_FILE
NFile::NIO::CInFile file;
if (!file.Open(property.Value))
if (!file.Open(us2fs(property.Value)))
return E_INVALIDARG;
UInt64 len;
if (!file.GetLength(len))

View File

@@ -39,7 +39,7 @@
#endif
// increase it, if you need to support larger SFX stubs
static const UInt64 kMaxCheckStartPosition = 1 << 22;
static const UInt64 kMaxCheckStartPosition = 1 << 23;
/*
Open:
@@ -1632,6 +1632,36 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
#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)
{
const CArcInfoEx &ai = op.codecs->Formats[i];
@@ -1647,7 +1677,12 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
isPrearcExt = true;
#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);
orderIndices.Insert(numFinded++, i);

View File

@@ -42,6 +42,12 @@ static void Key_Get_BoolPair(CKey &key, LPCTSTR name, CBoolPair &b)
b.Def = (key.GetValue_IfOk(name, b.Val) == ERROR_SUCCESS);
}
static void Key_Get_BoolPair_true(CKey &key, LPCTSTR name, CBoolPair &b)
{
b.Val = true;
b.Def = (key.GetValue_IfOk(name, b.Val) == ERROR_SUCCESS);
}
namespace NExtract
{
@@ -92,6 +98,8 @@ void CInfo::Load()
OverwriteMode = NOverwriteMode::kAsk;
OverwriteMode_Force = false;
SplitDest.Val = true;
Paths.Clear();
CS_LOCK
@@ -112,9 +120,8 @@ void CInfo::Load()
OverwriteMode_Force = true;
}
Key_Get_BoolPair(key, kSplitDest, SplitDest);
if (!SplitDest.Def)
SplitDest.Val = true;
Key_Get_BoolPair_true(key, kSplitDest, SplitDest);
Key_Get_BoolPair(key, kElimDup, ElimDup);
// Key_Get_BoolPair(key, kAltStreams, AltStreams);
Key_Get_BoolPair(key, kNtSecur, NtSecurity);
@@ -348,27 +355,45 @@ void CInfo::Load()
static const TCHAR *kCascadedMenu = TEXT("CascadedMenu");
static const TCHAR *kContextMenu = TEXT("ContextMenu");
static const TCHAR *kMenuIcons = TEXT("MenuIcons");
static const TCHAR *kElimDup = TEXT("ElimDupExtract");
void CContextMenuInfo::Save() const
{
CS_LOCK
CKey key;
CreateMainKey(key, kOptionsInfoKeyName);
key.SetValue(kCascadedMenu, Cascaded);
key.SetValue(kMenuIcons, MenuIcons);
key.SetValue(kContextMenu, Flags);
Key_Set_BoolPair(key, kCascadedMenu, Cascaded);
Key_Set_BoolPair(key, kMenuIcons, MenuIcons);
Key_Set_BoolPair(key, kElimDup, ElimDup);
if (Flags_Def)
key.SetValue(kContextMenu, Flags);
}
void CContextMenuInfo::Load()
{
MenuIcons = false;
Cascaded = true;
Cascaded.Val = true;
Cascaded.Def = false;
MenuIcons.Val = false;
MenuIcons.Def = false;
ElimDup.Val = true;
ElimDup.Def = false;
Flags = (UInt32)(Int32)-1;
Flags_Def = false;
CS_LOCK
CKey key;
if (OpenMainKey(key, kOptionsInfoKeyName) != ERROR_SUCCESS)
return;
key.GetValue_IfOk(kCascadedMenu, Cascaded);
key.GetValue_IfOk(kMenuIcons, MenuIcons);
key.GetValue_IfOk(kContextMenu, Flags);
Key_Get_BoolPair_true(key, kCascadedMenu, Cascaded);
Key_Get_BoolPair_true(key, kElimDup, ElimDup);
Key_Get_BoolPair(key, kMenuIcons, MenuIcons);
Flags_Def = (key.GetValue_IfOk(kContextMenu, Flags) == ERROR_SUCCESS);
}

View File

@@ -111,8 +111,11 @@ namespace NWorkDir
struct CContextMenuInfo
{
bool Cascaded;
bool MenuIcons;
CBoolPair Cascaded;
CBoolPair MenuIcons;
CBoolPair ElimDup;
bool Flags_Def;
UInt32 Flags;
void Save() const;

View File

@@ -241,7 +241,7 @@ static const CHashCommand g_HashCommands[] =
static int FindCommand(CZipContextMenu::ECommandInternalID &id)
{
for (int i = 0; i < ARRAY_SIZE(g_Commands); i++)
for (unsigned i = 0; i < ARRAY_SIZE(g_Commands); i++)
if (g_Commands[i].CommandInternalID == id)
return i;
return -1;
@@ -287,17 +287,15 @@ static const char * const kArcExts[] =
, "zip"
};
static bool IsItArcExt(const UString &ext2)
static bool IsItArcExt(const UString &ext)
{
UString ext = ext2;
ext.MakeLower_Ascii();
for (unsigned i = 0; i < ARRAY_SIZE(kArcExts); i++)
if (ext.IsEqualTo(kArcExts[i]))
if (ext.IsEqualTo_Ascii_NoCase(kArcExts[i]))
return true;
return false;
}
static UString GetSubFolderNameForExtract(const UString &arcName)
UString GetSubFolderNameForExtract(const UString &arcName)
{
int dotPos = arcName.ReverseFind_Dot();
if (dotPos < 0)
@@ -429,6 +427,7 @@ void CZipContextMenu::AddMapItem_ForSubMenu(const wchar_t *verb)
_commandMap.Add(commandMapItem);
}
STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
UINT commandIDFirst, UINT commandIDLast, UINT flags)
{
@@ -451,12 +450,15 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
CContextMenuInfo ci;
ci.Load();
_elimDup = ci.ElimDup;
HBITMAP bitmap = NULL;
if (ci.MenuIcons)
if (ci.MenuIcons.Val)
bitmap = _bitmap;
UINT subIndex = indexMenu;
if (ci.Cascaded)
if (ci.Cascaded.Val)
{
if (!popupMenu.CreatePopup())
return E_FAIL;
@@ -473,15 +475,21 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
else
{
popupMenu.Attach(hMenu);
CMenuItem mi;
mi.fType = MFT_SEPARATOR;
mi.fMask = MIIM_TYPE;
popupMenu.InsertItem(subIndex++, true, mi);
}
UInt32 contextMenuFlags = ci.Flags;
NFind::CFileInfo fi0;
FString folderPrefix;
if (_fileNames.Size() > 0)
{
const UString &fileName = _fileNames.Front();
#if defined(_WIN32) && !defined(UNDER_CE)
if (NName::IsDevicePath(us2fs(fileName)))
{
@@ -505,6 +513,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
}
UString mainString;
if (_fileNames.Size() == 1 && currentCommandID + 14 <= commandIDLast)
{
if (!fi0.IsDir() && DoNeedExtract(fi0.Name))
@@ -565,6 +574,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
if (_fileNames.Size() > 0 && currentCommandID + 10 <= commandIDLast)
{
bool needExtract = (!fi0.IsDir() && DoNeedExtract(fi0.Name));
if (!needExtract)
{
FOR_VECTOR (i, _fileNames)
@@ -579,7 +589,9 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
}
}
}
const UString &fileName = _fileNames.Front();
if (needExtract)
{
// Extract
@@ -629,6 +641,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap);
_commandMap.Add(commandMapItem);
}
// Test
if ((contextMenuFlags & NContextMenuFlags::kTest) != 0)
{
@@ -644,6 +657,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
arcName = CreateArchiveName(fi0, false);
else
arcName = CreateArchiveName(fileName, _fileNames.Size() > 1, false);
UString arcName7z = arcName + L".7z";
UString arcNameZip = arcName + L".zip";
@@ -745,7 +759,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
// PRB: Duplicate Menu Items In the File Menu For a Shell Context Menu Extension
// ID: Q214477
if (ci.Cascaded)
if (ci.Cascaded.Val)
{
CMenuItem mi;
mi.fType = MFT_STRING;
@@ -756,12 +770,20 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
mi.hSubMenu = popupMenu.Detach();
mi.StringValue.SetFromAscii("7-Zip"); // LangString(IDS_CONTEXT_POPUP_CAPTION);
mi.hbmpUnchecked = bitmap;
CMenu menu;
menu.Attach(hMenu);
menuDestroyer.Disable();
menu.InsertItem(indexMenu++, true, mi);
AddMapItem_ForSubMenu(kMainVerb);
}
else
{
popupMenu.Detach();
indexMenu = subIndex;
}
if (!_isMenuForFM &&
((contextMenuFlags & NContextMenuFlags::kCRC) != 0
@@ -771,6 +793,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
// CMenuDestroyer menuDestroyer_CRC;
UINT subIndex_CRC = 0;
if (subMenu.CreatePopup())
{
// menuDestroyer_CRC.Attach(subMenu);
@@ -783,13 +806,15 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
mi.hSubMenu = subMenu;
mi.StringValue.SetFromAscii("CRC SHA");
mi.hbmpUnchecked = bitmap;
CMenu menu;
menu.Attach(hMenu);
// menuDestroyer_CRC.Disable();
menu.InsertItem(indexMenu++, true, mi);
AddMapItem_ForSubMenu(kCheckSumCascadedVerb);
for (int i = 0; i < ARRAY_SIZE(g_HashCommands); i++)
for (unsigned i = 0; i < ARRAY_SIZE(g_HashCommands); i++)
{
const CHashCommand &hc = g_HashCommands[i];
CCommandMapItem commandMapItem;
@@ -799,6 +824,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
MyInsertMenu(subMenu, subIndex_CRC++, currentCommandID++, hc.UserName, bitmap);
_commandMap.Add(commandMapItem);
}
subMenu.Detach();
}
}
@@ -872,7 +898,7 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
{
ExtractArchives(_fileNames, commandMapItem.Folder,
(cmdID == kExtract), // showDialog
(cmdID == kExtractTo) // elimDup
(cmdID == kExtractTo) && _elimDup.Val // elimDup
);
break;
}
@@ -902,12 +928,14 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
_fileNames, email, showDialog, false);
break;
}
case kHash_CRC32:
case kHash_CRC64:
case kHash_SHA1:
case kHash_SHA256:
case kHash_All:
for (int i = 0; i < ARRAY_SIZE(g_HashCommands); i++)
{
for (unsigned i = 0; i < ARRAY_SIZE(g_HashCommands); i++)
{
const CHashCommand &hc = g_HashCommands[i];
if (hc.CommandInternalID == cmdID)
@@ -917,6 +945,7 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
}
}
break;
}
}
}
catch(...)

View File

@@ -74,6 +74,8 @@ private:
HBITMAP _bitmap;
CBoolPair _elimDup;
HRESULT GetFileNames(LPDATAOBJECT dataObject, UStringVector &fileNames);
int FindVerb(const UString &verb);
bool FillCommand(ECommandInternalID id, UString &mainString, CCommandMapItem &commandMapItem);

View File

@@ -10,13 +10,11 @@
#include "../../../Common/MyWindows.h"
#include <ShlGuid.h>
#include <OleCtl.h>
#include "../../../Common/MyInitGuid.h"
#include "../../../Common/ComTry.h"
#include "../../../Common/StringConvert.h"
#include "../../../Windows/DLL.h"
#include "../../../Windows/ErrorMsg.h"
@@ -24,11 +22,15 @@
#include "../../../Windows/Registry.h"
#include "../FileManager/IFolder.h"
#include "../FileManager/LangUtils.h"
#include "ContextMenu.h"
static LPCTSTR k_ShellExtName = TEXT("7-Zip Shell Extension");
static LPCTSTR k_Approved = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved");
// {23170F69-40C1-278A-1000-000100020000}
static LPCTSTR k_Clsid = TEXT("{23170F69-40C1-278A-1000-000100020000}");
DEFINE_GUID(CLSID_CZipContextMenu,
k_7zip_GUID_Data1,
k_7zip_GUID_Data2,
@@ -42,10 +44,6 @@ HWND g_HWND = 0;
LONG g_DllRefCount = 0; // Reference count of this DLL.
static LPCWSTR kShellExtName = L"7-Zip Shell Extension";
static LPCTSTR kClsidMask = TEXT("CLSID\\%s");
static LPCTSTR kClsidInprocMask = TEXT("CLSID\\%s\\InprocServer32");
static LPCTSTR kApprovedKeyPath = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved");
// #define ODS(sz) OutputDebugString(L#sz)
@@ -77,7 +75,7 @@ STDMETHODIMP CShellExtClassFactory::CreateInstance(LPUNKNOWN pUnkOuter,
shellExt = new CZipContextMenu();
}
catch(...) { return E_OUTOFMEMORY; }
if (shellExt == NULL)
if (!shellExt)
return E_OUTOFMEMORY;
HRESULT res = shellExt->QueryInterface(riid, ppvObj);
@@ -117,7 +115,7 @@ BOOL WINAPI DllMain(
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// Used to determine whether the DLL can be unloaded by OLE
STDAPI DllCanUnloadNow(void)
@@ -138,7 +136,7 @@ STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
cf = new CShellExtClassFactory;
}
catch(...) { return E_OUTOFMEMORY; }
if (cf == 0)
if (!cf)
return E_OUTOFMEMORY;
HRESULT res = cf->QueryInterface(riid, ppv);
if (res != S_OK)
@@ -149,66 +147,28 @@ STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
// return _Module.GetClassObject(rclsid, riid, ppv);
}
static BOOL GetStringFromIID(CLSID clsid, LPTSTR s, int size)
{
LPWSTR pwsz;
if (StringFromIID(clsid, &pwsz) != S_OK)
return FALSE;
if (!pwsz)
return FALSE;
#ifdef UNICODE
for (int i = 0; i < size; i++)
{
s[i] = pwsz[i];
if (pwsz[i] == 0)
break;
}
s[size - 1] = 0;
#else
WideCharToMultiByte(CP_ACP, 0, pwsz, -1, s, size, NULL, NULL);
#endif
CoTaskMemFree(pwsz);
s[size - 1] = 0;
return TRUE;
}
typedef struct
static BOOL RegisterServer()
{
HKEY hRootKey;
LPCTSTR SubKey;
LPCWSTR ValueName;
LPCWSTR Data;
} CRegItem;
static BOOL RegisterServer(CLSID clsid, LPCWSTR title)
{
TCHAR clsidString[MAX_PATH];
if (!GetStringFromIID(clsid, clsidString, MAX_PATH))
return FALSE;
FString modulePath;
if (!NDLL::MyGetModuleFileName(modulePath))
return FALSE;
UString modulePathU = fs2us(modulePath);
const UString modulePathU = fs2us(modulePath);
CRegItem clsidEntries[] =
{
HKEY_CLASSES_ROOT, kClsidMask, NULL, title,
HKEY_CLASSES_ROOT, kClsidInprocMask, NULL, modulePathU,
HKEY_CLASSES_ROOT, kClsidInprocMask, L"ThreadingModel", L"Apartment",
NULL, NULL, NULL, NULL
};
CSysString clsidString = k_Clsid;
CSysString s = TEXT("CLSID\\");
s += clsidString;
//register the CLSID entries
for (int i = 0; clsidEntries[i].hRootKey; i++)
{
TCHAR subKey[MAX_PATH];
const CRegItem &r = clsidEntries[i];
wsprintf(subKey, r.SubKey, clsidString);
NRegistry::CKey key;
if (key.Create(r.hRootKey, subKey, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE) != NOERROR)
if (key.Create(HKEY_CLASSES_ROOT, s, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE) != NOERROR)
return FALSE;
key.SetValue(clsidEntries[i].ValueName, clsidEntries[i].Data);
key.SetValue(NULL, k_ShellExtName);
NRegistry::CKey keyInproc;
if (keyInproc.Create(key, TEXT("InprocServer32"), NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE) != NOERROR)
return FALSE;
keyInproc.SetValue(NULL, modulePathU);
keyInproc.SetValue(TEXT("ThreadingModel"), TEXT("Apartment"));
}
#if !defined(_WIN64) && !defined(UNDER_CE)
@@ -216,46 +176,45 @@ static BOOL RegisterServer(CLSID clsid, LPCWSTR title)
#endif
{
NRegistry::CKey key;
if (key.Create(HKEY_LOCAL_MACHINE, kApprovedKeyPath, NULL,
REG_OPTION_NON_VOLATILE, KEY_WRITE) == NOERROR)
key.SetValue(GetUnicodeString(clsidString), title);
if (key.Create(HKEY_LOCAL_MACHINE, k_Approved, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE) == NOERROR)
key.SetValue(clsidString, k_ShellExtName);
}
return TRUE;
}
STDAPI DllRegisterServer(void)
{
return RegisterServer(CLSID_CZipContextMenu, kShellExtName) ? S_OK: SELFREG_E_CLASS;
return RegisterServer() ? S_OK: SELFREG_E_CLASS;
}
static BOOL UnregisterServer(CLSID clsid)
static BOOL UnregisterServer()
{
TCHAR clsidString[MAX_PATH];
if (!GetStringFromIID(clsid, clsidString, MAX_PATH))
return FALSE;
const CSysString clsidString = k_Clsid;
CSysString s = TEXT("CLSID\\");
s += clsidString;
CSysString s2 = s;
s2.AddAscii("\\InprocServer32");
TCHAR subKey[MAX_PATH];
wsprintf(subKey, kClsidInprocMask, clsidString);
RegDeleteKey(HKEY_CLASSES_ROOT, subKey);
wsprintf (subKey, kClsidMask, clsidString);
RegDeleteKey(HKEY_CLASSES_ROOT, subKey);
RegDeleteKey(HKEY_CLASSES_ROOT, s2);
RegDeleteKey(HKEY_CLASSES_ROOT, s);
#if !defined(_WIN64) && !defined(UNDER_CE)
if (IsItWindowsNT())
#endif
{
HKEY hKey;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, kApprovedKeyPath, 0, KEY_SET_VALUE, &hKey) == NOERROR)
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, k_Approved, 0, KEY_SET_VALUE, &hKey) == NOERROR)
{
RegDeleteValue(hKey, clsidString);
RegCloseKey(hKey);
}
}
return TRUE;
}
STDAPI DllUnregisterServer(void)
{
return UnregisterServer(CLSID_CZipContextMenu) ? S_OK: SELFREG_E_CLASS;
return UnregisterServer() ? S_OK: SELFREG_E_CLASS;
}

View File

@@ -538,13 +538,5 @@ SOURCE=".\7-zip.dll.manifest"
SOURCE=.\ContextMenuFlags.h
# End Source File
# Begin Source File
SOURCE=.\RegistryContextMenu.cpp
# End Source File
# Begin Source File
SOURCE=.\RegistryContextMenu.h
# End Source File
# End Target
# End Project

View File

@@ -2,114 +2,218 @@
#include "StdAfx.h"
#include "../../../Common/StringConvert.h"
#include "../../../Windows/Registry.h"
#include "../../../Windows/Synchronization.h"
#include "RegistryContextMenu.h"
using namespace NWindows;
using namespace NRegistry;
namespace NZipRootRegistry {
#ifndef UNDER_CE
static NSynchronization::CCriticalSection g_CS;
static const TCHAR *kContextMenuKeyName = TEXT("\\shellex\\ContextMenuHandlers\\7-Zip");
static const TCHAR *kDragDropMenuKeyName = TEXT("\\shellex\\DragDropHandlers\\7-Zip");
// does extension can work, if Approved is removed ?
// CLISID (and Approved ?) items are separated for 32-bit and 64-bit code.
// shellex items shared by 32-bit and 64-bit code?
static const TCHAR *kExtensionCLSID = TEXT("{23170F69-40C1-278A-1000-000100020000}");
static LPCTSTR k_Clsid = TEXT("{23170F69-40C1-278A-1000-000100020000}");
static LPCTSTR k_ShellExtName = TEXT("7-Zip Shell Extension");
static const TCHAR *kRootKeyNameForFile = TEXT("*");
static const TCHAR *kRootKeyNameForFolder = TEXT("Folder");
static const TCHAR *kRootKeyNameForDirectory = TEXT("Directory");
static const TCHAR *kRootKeyNameForDrive = TEXT("Drive");
static LPCTSTR k_Approved = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved");
static LPCTSTR k_Inproc = TEXT("InprocServer32");
static CSysString GetFullContextMenuKeyName(const CSysString &keyName)
{ return (keyName + kContextMenuKeyName); }
static LPCTSTR k_KeyPostfix_ContextMenu = TEXT("\\shellex\\ContextMenuHandlers\\7-Zip");
static LPCTSTR k_KeyPostfix_DragDrop = TEXT("\\shellex\\DragDropHandlers\\7-Zip");
static CSysString GetFullDragDropMenuKeyName(const CSysString &keyName)
{ return (keyName + kDragDropMenuKeyName); }
static LPCTSTR k_KeyName_File = TEXT("*");
static LPCTSTR k_KeyName_Folder = TEXT("Folder");
static LPCTSTR k_KeyName_Directory = TEXT("Directory");
static LPCTSTR k_KeyName_Drive = TEXT("Drive");
static bool CheckHandlerCommon(const CSysString &keyName)
static LPCTSTR const k_shellex_Prefixes[] =
{
k_KeyName_File,
k_KeyName_Folder,
k_KeyName_Directory,
k_KeyName_Drive
};
static const bool k_shellex_Statuses[2][4] =
{
{ true, true, true, false },
{ false, false, true, true }
};
// can we use static RegDeleteKeyExW in _WIN64 mode?
// is it supported by Windows 2003 x64?
/*
#ifdef _WIN64
#define INIT_REG_WOW
#else
*/
typedef WINADVAPI LONG (APIENTRY *Func_RegDeleteKeyExW)(HKEY hKey, LPCWSTR lpSubKey, REGSAM samDesired, DWORD Reserved);
static Func_RegDeleteKeyExW func_RegDeleteKeyExW;
static void Init_RegDeleteKeyExW()
{
if (!func_RegDeleteKeyExW)
func_RegDeleteKeyExW = (Func_RegDeleteKeyExW)
GetProcAddress(GetModuleHandleW(L"advapi32.dll"), "RegDeleteKeyExW");
}
#define INIT_REG_WOW if (wow != 0) Init_RegDeleteKeyExW();
// #endif
static LONG MyRegistry_DeleteKey(HKEY parentKey, LPCTSTR name, UInt32 wow)
{
if (wow == 0)
return RegDeleteKey(parentKey, name);
/*
#ifdef _WIN64
return RegDeleteKeyExW
#else
*/
if (!func_RegDeleteKeyExW)
return E_NOTIMPL;
return func_RegDeleteKeyExW
// #endif
(parentKey, GetUnicodeString(name), wow, 0);
}
static LONG MyRegistry_DeleteKey_HKCR(LPCTSTR name, UInt32 wow)
{
return MyRegistry_DeleteKey(HKEY_CLASSES_ROOT, name, wow);
}
// static NSynchronization::CCriticalSection g_CS;
static CSysString Get_ContextMenuHandler_KeyName(const CSysString &keyName)
{ return (keyName + k_KeyPostfix_ContextMenu); }
/*
static CSysString Get_DragDropHandler_KeyName(const CSysString &keyName)
{ return (keyName + k_KeyPostfix_DragDrop); }
*/
static bool CheckHandlerCommon(const CSysString &keyName, UInt32 wow)
{
NSynchronization::CCriticalSectionLock lock(g_CS);
CKey key;
if (key.Open(HKEY_CLASSES_ROOT, keyName, KEY_READ) != ERROR_SUCCESS)
if (key.Open(HKEY_CLASSES_ROOT, keyName, KEY_READ | wow) != ERROR_SUCCESS)
return false;
CSysString value;
if (key.QueryValue(NULL, value) != ERROR_SUCCESS)
return false;
return StringsAreEqualNoCase_Ascii(value, kExtensionCLSID);
return StringsAreEqualNoCase_Ascii(value, k_Clsid);
}
bool CheckContextMenuHandler()
bool CheckContextMenuHandler(const UString &path, UInt32 wow)
{
// NSynchronization::CCriticalSectionLock lock(g_CS);
CSysString s = TEXT("CLSID\\");
s += k_Clsid;
s.AddAscii("\\InprocServer32");
{
NRegistry::CKey key;
if (key.Open(HKEY_CLASSES_ROOT, s, KEY_READ | wow) != ERROR_SUCCESS)
return false;
UString regPath;
if (key.QueryValue(NULL, regPath) != ERROR_SUCCESS)
return false;
if (!path.IsEqualTo_NoCase(regPath))
return false;
}
return
// CheckHandlerCommon(GetFullContextMenuKeyName(kRootKeyNameForFolder)) &&
CheckHandlerCommon(GetFullContextMenuKeyName(kRootKeyNameForDirectory)) &&
CheckHandlerCommon(GetFullContextMenuKeyName(kRootKeyNameForFile)) &&
CheckHandlerCommon(GetFullDragDropMenuKeyName(kRootKeyNameForDirectory)) &&
CheckHandlerCommon(GetFullDragDropMenuKeyName(kRootKeyNameForDrive));
CheckHandlerCommon(Get_ContextMenuHandler_KeyName(k_KeyName_File), wow);
/*
&& CheckHandlerCommon(Get_ContextMenuHandler_KeyName(k_KeyName_Directory), wow)
// && CheckHandlerCommon(Get_ContextMenuHandler_KeyName(k_KeyName_Folder))
&& CheckHandlerCommon(Get_DragDropHandler_KeyName(k_KeyName_Directory), wow)
&& CheckHandlerCommon(Get_DragDropHandler_KeyName(k_KeyName_Drive), wow);
*/
}
static void DeleteContextMenuHandlerCommon(const CSysString &keyName)
static LONG MyCreateKey(CKey &key, HKEY parentKey, LPCTSTR keyName, UInt32 wow)
{
CKey rootKey;
rootKey.Attach(HKEY_CLASSES_ROOT);
rootKey.RecurseDeleteKey(GetFullContextMenuKeyName(keyName));
rootKey.Detach();
return key.Create(parentKey, keyName, REG_NONE,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS | wow);
}
static void DeleteDragDropMenuHandlerCommon(const CSysString &keyName)
LONG SetContextMenuHandler(bool setMode, const UString &path, UInt32 wow)
{
CKey rootKey;
rootKey.Attach(HKEY_CLASSES_ROOT);
rootKey.RecurseDeleteKey(GetFullDragDropMenuKeyName(keyName));
rootKey.Detach();
}
// NSynchronization::CCriticalSectionLock lock(g_CS);
void DeleteContextMenuHandler()
{
DeleteContextMenuHandlerCommon(kRootKeyNameForFile);
DeleteContextMenuHandlerCommon(kRootKeyNameForFolder);
DeleteContextMenuHandlerCommon(kRootKeyNameForDirectory);
DeleteContextMenuHandlerCommon(kRootKeyNameForDrive);
DeleteDragDropMenuHandlerCommon(kRootKeyNameForFile);
DeleteDragDropMenuHandlerCommon(kRootKeyNameForFolder);
DeleteDragDropMenuHandlerCommon(kRootKeyNameForDirectory);
DeleteDragDropMenuHandlerCommon(kRootKeyNameForDrive);
}
INIT_REG_WOW
static void AddContextMenuHandlerCommon(const CSysString &keyName)
{
DeleteContextMenuHandlerCommon(keyName);
NSynchronization::CCriticalSectionLock lock(g_CS);
CKey key;
key.Create(HKEY_CLASSES_ROOT, GetFullContextMenuKeyName(keyName));
key.SetValue(NULL, kExtensionCLSID);
}
CSysString s = TEXT("CLSID\\");
s += k_Clsid;
static void AddDragDropMenuHandlerCommon(const CSysString &keyName)
{
DeleteDragDropMenuHandlerCommon(keyName);
NSynchronization::CCriticalSectionLock lock(g_CS);
CKey key;
key.Create(HKEY_CLASSES_ROOT, GetFullDragDropMenuKeyName(keyName));
key.SetValue(NULL, kExtensionCLSID);
}
LONG res;
if (setMode)
{
{
CKey key;
res = MyCreateKey(key, HKEY_CLASSES_ROOT, s, wow);
if (res == ERROR_SUCCESS)
{
key.SetValue(NULL, k_ShellExtName);
CKey keyInproc;
res = MyCreateKey(keyInproc, key, k_Inproc, wow);
if (res == ERROR_SUCCESS)
{
res = keyInproc.SetValue(NULL, path);
keyInproc.SetValue(TEXT("ThreadingModel"), TEXT("Apartment"));
}
}
}
{
CKey key;
if (MyCreateKey(key, HKEY_LOCAL_MACHINE, k_Approved, wow) == ERROR_SUCCESS)
key.SetValue(k_Clsid, k_ShellExtName);
}
}
else
{
CSysString s2 = s;
s2.AddAscii("\\InprocServer32");
void AddContextMenuHandler()
{
AddContextMenuHandlerCommon(kRootKeyNameForFile);
// AddContextMenuHandlerCommon(kRootKeyNameForFolder);
AddContextMenuHandlerCommon(kRootKeyNameForDirectory);
MyRegistry_DeleteKey_HKCR(s2, wow);
res = MyRegistry_DeleteKey_HKCR(s, wow);
}
AddDragDropMenuHandlerCommon(kRootKeyNameForDirectory);
AddDragDropMenuHandlerCommon(kRootKeyNameForDrive);
// shellex items probably are shared beween 32-bit and 64-bit apps. So we don't delete items for delete operation.
if (setMode)
for (unsigned i = 0; i < 2; i++)
{
for (unsigned k = 0; k < ARRAY_SIZE(k_shellex_Prefixes); k++)
{
CSysString s = k_shellex_Prefixes[k];
s += (i == 0 ? k_KeyPostfix_ContextMenu : k_KeyPostfix_DragDrop);
if (k_shellex_Statuses[i][k])
{
CKey key;
MyCreateKey(key, HKEY_CLASSES_ROOT, s, wow);
key.SetValue(NULL, k_Clsid);
}
else
MyRegistry_DeleteKey_HKCR(s, wow);
}
}
return res;
}
#endif
}

View File

@@ -3,14 +3,11 @@
#ifndef __REGISTRY_CONTEXT_MENU_H
#define __REGISTRY_CONTEXT_MENU_H
namespace NZipRootRegistry {
#ifndef UNDER_CE
bool CheckContextMenuHandler();
void AddContextMenuHandler();
void DeleteContextMenuHandler();
#endif
}
bool CheckContextMenuHandler(const UString &path, UInt32 wow = 0);
LONG SetContextMenuHandler(bool setMode, const UString &path, UInt32 wow = 0);
#endif
#endif

View File

@@ -14,7 +14,6 @@ EXPLORER_OBJS = \
$O\DllExportsExplorer.obj \
$O\ContextMenu.obj \
$O\MyMessages.obj \
$O\RegistryContextMenu.obj \
COMMON_OBJS = \
$O\IntToString.obj \

View File

@@ -448,7 +448,7 @@ int PrintErrorMessage(const char *message, const char *text)
}
static void ReduceString(UString &s, unsigned size)
void ReduceString(UString &s, unsigned size)
{
if (s.Len() > size)
{

View File

@@ -190,6 +190,8 @@ int ShowLastErrorMessage();
bool WasEscPressed();
void ReduceString(UString &s, unsigned size);
}
#endif

View File

@@ -68,8 +68,17 @@ NResult::EEnum Execute(const CFileInfo &oldFileInfo, const CFileInfo &newFileInf
SetFileInfoStrings(oldFileInfo, oldFileInfoStrings);
SetFileInfoStrings(newFileInfo, newFileInfoStrings);
AString oldName = UnicodeStringToMultiByte(oldFileInfo.Name, CP_OEMCP);
AString newName = UnicodeStringToMultiByte(newFileInfo.Name, CP_OEMCP);
UString oldName2 = oldFileInfo.Name;
UString newName2 = newFileInfo.Name;
{
const unsigned maxNameLen = kXSize - 9 - 2;
ReduceString(oldName2, maxNameLen);
ReduceString(newName2, maxNameLen);
}
AString oldName = UnicodeStringToMultiByte(oldName2);
AString newName = UnicodeStringToMultiByte(newName2);
struct CInitDialogItem initItems[]={
{ DI_DOUBLEBOX, 3, 1, kXSize - 4, kYSize - 2, false, false, 0, false, NMessageID::kOverwriteTitle, NULL, NULL },

View File

@@ -46,7 +46,7 @@ void CPanelCallbackImp::OnTab()
_app->RefreshTitle();
}
void CPanelCallbackImp::SetFocusToPath(int index)
void CPanelCallbackImp::SetFocusToPath(unsigned index)
{
int newPanelIndex = index;
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::OnSetSameFolder() { _app->OnSetSameFolder(_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::DragEnd() { _app->DragEnd(); }
void CPanelCallbackImp::RefreshTitle(bool always) { _app->RefreshTitle(_index, always); }
void CPanelCallbackImp::RefreshTitle(bool always) { _app->RefreshTitlePanel(_index, always); }
void CApp::ReloadLang()
{
@@ -72,17 +72,18 @@ void CApp::ReloadLang()
void CApp::SetListSettings()
{
bool showDots = ReadShowDots();
bool showRealFileIcons = ReadShowRealFileIcons();
CFmSettings st;
st.Load();
ShowSystemMenu = st.ShowSystemMenu;
DWORD extendedStyle = LVS_EX_HEADERDRAGDROP;
if (ReadFullRow())
if (st.FullRow)
extendedStyle |= LVS_EX_FULLROWSELECT;
if (ReadShowGrid())
if (st.ShowGrid)
extendedStyle |= LVS_EX_GRIDLINES;
bool mySelectionMode = ReadAlternativeSelection();
if (ReadSingleClick())
if (st.SingleClick)
{
extendedStyle |= LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT;
/*
@@ -91,16 +92,16 @@ void CApp::SetListSettings()
*/
}
for (int i = 0; i < kNumPanelsMax; i++)
for (unsigned i = 0; i < kNumPanelsMax; i++)
{
CPanel &panel = Panels[i];
panel._mySelectMode = mySelectionMode;
panel._showDots = showDots;
panel._showRealFileIcons = showRealFileIcons;
panel._mySelectMode = st.AlternativeSelection;
panel._showDots = st.ShowDots;
panel._showRealFileIcons = st.ShowRealFileIcons;
panel._exStyle = extendedStyle;
DWORD style = (DWORD)panel._listView.GetStyle();
if (mySelectionMode)
if (st.AlternativeSelection)
style |= LVS_SINGLESEL;
else
style &= ~LVS_SINGLESEL;
@@ -109,21 +110,19 @@ void CApp::SetListSettings()
}
}
void CApp::SetShowSystemMenu()
{
ShowSystemMenu = Read_ShowSystemMenu();
}
#ifndef ILC_COLOR32
#define ILC_COLOR32 0x0020
#endif
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;
m_PanelCallbackImp[panelIndex].Init(this, panelIndex);
UString path;
if (mainPath.IsEmpty())
{
@@ -132,13 +131,16 @@ HRESULT CApp::CreateOnePanel(int panelIndex, const UString &mainPath, const UStr
}
else
path = mainPath;
int id = 1000 + 100 * panelIndex;
RINOK(Panels[panelIndex].Create(_window, _window,
id, path, arcFormat, &m_PanelCallbackImp[panelIndex], &AppState, archiveIsOpened, encrypted));
PanelsCreated[panelIndex] = true;
return S_OK;
return Panels[panelIndex].Create(_window, _window,
id, path, arcFormat, &m_PanelCallbackImp[panelIndex], &AppState,
needOpenArc,
archiveIsOpened, encrypted);
}
static void CreateToolbar(HWND parent,
NControl::CImageList &imageList,
NControl::CToolBar &toolBar,
@@ -169,6 +171,7 @@ static void CreateToolbar(HWND parent,
toolBar.SetImageList(0, imageList);
}
struct CButtonInfo
{
int CommandID;
@@ -179,7 +182,7 @@ struct CButtonInfo
UString GetText() const { return LangString(StringResID); }
};
static CButtonInfo g_StandardButtons[] =
static const CButtonInfo g_StandardButtons[] =
{
{ IDM_COPY_TO, IDB_COPY, IDB_COPY2, IDS_BUTTON_COPY },
{ IDM_MOVE_TO, IDB_MOVE, IDB_MOVE2, IDS_BUTTON_MOVE },
@@ -187,16 +190,16 @@ static CButtonInfo g_StandardButtons[] =
{ IDM_PROPERTIES, IDB_INFO, IDB_INFO2, IDS_BUTTON_INFO }
};
static CButtonInfo g_ArchiveButtons[] =
static const CButtonInfo g_ArchiveButtons[] =
{
{ kMenuCmdID_Toolbar_Add, IDB_ADD, IDB_ADD2, IDS_ADD },
{ kMenuCmdID_Toolbar_Extract, IDB_EXTRACT, IDB_EXTRACT2, IDS_EXTRACT },
{ kMenuCmdID_Toolbar_Test, IDB_TEST, IDB_TEST2, IDS_TEST }
};
static bool SetButtonText(int commandID, CButtonInfo *buttons, int numButtons, UString &s)
static bool SetButtonText(int commandID, const CButtonInfo *buttons, unsigned numButtons, UString &s)
{
for (int i = 0; i < numButtons; i++)
for (unsigned i = 0; i < numButtons; i++)
{
const CButtonInfo &b = buttons[i];
if (b.CommandID == commandID)
@@ -218,7 +221,7 @@ static void SetButtonText(int commandID, UString &s)
static void AddButton(
NControl::CImageList &imageList,
NControl::CToolBar &toolBar,
CButtonInfo &butInfo, bool showText, bool large)
const CButtonInfo &butInfo, bool showText, bool large)
{
TBBUTTON but;
but.iBitmap = 0;
@@ -258,7 +261,7 @@ void CApp::ReloadToolbars()
if (ShowArchiveToolbar || ShowStandardToolbar)
{
CreateToolbar(_window, _buttonsImageList, _toolBar, LargeButtons);
int i;
unsigned i;
if (ShowArchiveToolbar)
for (i = 0; i < ARRAY_SIZE(g_ArchiveButtons); i++)
AddButton(_buttonsImageList, _toolBar, g_ArchiveButtons[i], ShowButtonsLables, LargeButtons);
@@ -277,15 +280,20 @@ void CApp::SaveToolbarChanges()
MoveSubWindows();
}
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);
#ifdef UNDER_CE
_commandBar.Create(g_hInstance, hwnd, 1);
#endif
MyLoadMenu();
#ifdef UNDER_CE
_commandBar.AutoSize();
#endif
@@ -293,19 +301,21 @@ HRESULT CApp::Create(HWND hwnd, const UString &mainPath, const UString &arcForma
ReadToolbar();
ReloadToolbars();
int i;
unsigned i;
for (i = 0; i < kNumPanelsMax; i++)
PanelsCreated[i] = false;
Panels[i].PanelCreated = false;
AppState.Read();
SetListSettings();
SetShowSystemMenu();
if (LastFocusedPanel >= kNumPanelsMax)
LastFocusedPanel = 0;
// ShowDeletedFiles = Read_ShowDeleted();
CListMode listMode;
listMode.Read();
for (i = 0; i < kNumPanelsMax; i++)
{
CPanel &panel = Panels[i];
@@ -313,33 +323,54 @@ HRESULT CApp::Create(HWND hwnd, const UString &mainPath, const UString &arcForma
panel._xSize = xSizes[i];
panel._flatModeForArc = ReadFlatView(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)
Panels[i]._xSize = xSizes[0] + xSizes[1];
Panels[panelIndex]._xSize = xSizes[0] + xSizes[1];
bool archiveIsOpened2 = false;
bool encrypted2 = false;
bool mainPanel = (i == LastFocusedPanel);
RINOK(CreateOnePanel(i, mainPanel ? mainPath : L"", arcFormat, archiveIsOpened2, encrypted2));
if (mainPanel)
UString path;
if (isMainPanel)
path = mainPath;
RINOK(CreateOnePanel(panelIndex, path, arcFormat,
isMainPanel && needOpenArc,
archiveIsOpened2, encrypted2));
if (isMainPanel)
{
archiveIsOpened = archiveIsOpened2;
encrypted = encrypted2;
if (needOpenArc && !archiveIsOpened2)
return S_OK;
}
}
}
SetFocusedPanel(LastFocusedPanel);
Panels[LastFocusedPanel].SetFocusToList();
return S_OK;
}
HRESULT CApp::SwitchOnOffOnePanel()
{
if (NumPanels == 1)
{
NumPanels++;
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].Show(SW_SHOWNORMAL);
}
@@ -357,7 +388,8 @@ void CApp::Save()
{
AppState.Save();
CListMode listMode;
for (int i = 0; i < kNumPanelsMax; i++)
for (unsigned i = 0; i < kNumPanelsMax; i++)
{
const CPanel &panel = Panels[i];
UString path;
@@ -370,6 +402,7 @@ void CApp::Save()
listMode.Panels[i] = panel.GetListViewMode();
SaveFlatView(i, panel._flatModeForArc);
}
listMode.Save();
// Save_ShowDeleted(ShowDeletedFiles);
}
@@ -377,7 +410,7 @@ void CApp::Save()
void CApp::Release()
{
// It's for unloading COM dll's: don't change it.
for (int i = 0; i < kNumPanelsMax; i++)
for (unsigned i = 0; i < kNumPanelsMax; i++)
Panels[i].Release();
}
@@ -467,6 +500,7 @@ UString CPanel::GetItemsInfoString(const CRecordVector<UInt32> &indices)
UString info;
UInt64 numDirs, numFiles, filesSize, foldersSize;
numDirs = numFiles = filesSize = foldersSize = 0;
unsigned i;
for (i = 0; i < indices.Size(); i++)
{
@@ -524,7 +558,7 @@ static bool IsFsPath(const FString &path)
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 &destPanel = Panels[destPanelIndex];
@@ -848,7 +882,7 @@ int CApp::GetFocusedPanelIndex() const
{
if (hwnd == 0)
return 0;
for (int i = 0; i < kNumPanelsMax; i++)
for (unsigned i = 0; i < kNumPanelsMax; i++)
{
if (PanelsCreated[i] &&
((HWND)Panels[i] == hwnd || Panels[i]._listView == hwnd))
@@ -900,7 +934,7 @@ void CApp::RefreshTitle(bool always)
NWindows::MySetWindowText(_window, path);
}
void CApp::RefreshTitle(int panelIndex, bool always)
void CApp::RefreshTitlePanel(unsigned panelIndex, bool always)
{
if (panelIndex != GetFocusedPanelIndex())
return;

View File

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

View File

@@ -197,9 +197,11 @@ bool CBrowseDialog::OnInit()
#endif
#ifndef _SFX
if (ReadSingleClick())
CFmSettings st;
st.Load();
if (st.SingleClick)
_list.SetExtendedListViewStyle(LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT);
_showDots = ReadShowDots();
_showDots = st.ShowDots;
#endif
{
@@ -999,11 +1001,13 @@ bool CorrectFsPath(const UString &relBase, const UString &path2, UString &result
}
#else
bool CorrectFsPath(const UString & /* relBase */, const UString &path, UString &result)
{
result = path;
return true;
}
#endif
bool Dlg_CreateFolder(HWND wnd, UString &destName)

View File

@@ -27,48 +27,50 @@ static LPCWSTR kEditTopic = L"FM/options.htm#editor";
bool CEditPage::OnInit()
{
_initMode = true;
LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs));
LangSetDlgItems_Colon(*this, kLangIDs_Colon, ARRAY_SIZE(kLangIDs_Colon));
_viewer.Attach(GetItem(IDE_EDIT_VIEWER));
_editor.Attach(GetItem(IDE_EDIT_EDITOR));
_diff.Attach(GetItem(IDE_EDIT_DIFF));
_ctrls[0].Ctrl = IDE_EDIT_VIEWER; _ctrls[0].Button = IDB_EDIT_VIEWER;
_ctrls[1].Ctrl = IDE_EDIT_EDITOR; _ctrls[1].Button = IDB_EDIT_EDITOR;
_ctrls[2].Ctrl = IDE_EDIT_DIFF; _ctrls[2].Button = IDB_EDIT_DIFF;
for (unsigned i = 0; i < 3; i++)
{
CEditPageCtrl &c = _ctrls[i];
c.WasChanged = false;
c.Edit.Attach(GetItem(c.Ctrl));
UString path;
ReadRegEditor(false, path);
_viewer.SetText(path);
}
{
UString path;
ReadRegEditor(true, path);
_editor.SetText(path);
}
{
UString path;
ReadRegDiff(path);
_diff.SetText(path);
if (i < 2)
ReadRegEditor(i > 0, path);
else
ReadRegDiff(path);
c.Edit.SetText(path);
}
_initMode = false;
return CPropertyPage::OnInit();
}
LONG CEditPage::OnApply()
{
for (unsigned i = 0; i < 3; i++)
{
UString path;
_viewer.GetText(path);
SaveRegEditor(false, path);
}
{
UString path;
_editor.GetText(path);
SaveRegEditor(true, path);
}
{
UString path;
_diff.GetText(path);
SaveRegDiff(path);
CEditPageCtrl &c = _ctrls[i];
if (c.WasChanged)
{
UString path;
c.Edit.GetText(path);
if (i < 2)
SaveRegEditor(i > 0, path);
else
SaveRegDiff(path);
c.WasChanged = false;
}
}
return PSNRET_NOERROR;
}
@@ -91,24 +93,34 @@ static void Edit_BrowseForFile(NWindows::NControl::CEdit &edit, HWND hwnd)
bool CEditPage::OnButtonClicked(int buttonID, HWND buttonHWND)
{
switch (buttonID)
for (unsigned i = 0; i < 3; i++)
{
case IDB_EDIT_VIEWER: Edit_BrowseForFile(_viewer, *this); return true;
case IDB_EDIT_EDITOR: Edit_BrowseForFile(_editor, *this); return true;
case IDB_EDIT_DIFF: Edit_BrowseForFile(_diff, *this); return true;
CEditPageCtrl &c = _ctrls[i];
if (buttonID == c.Button)
{
Edit_BrowseForFile(c.Edit, *this);
return true;
}
}
return CPropertyPage::OnButtonClicked(buttonID, buttonHWND);
}
bool CEditPage::OnCommand(int code, int itemID, LPARAM param)
{
if (code == EN_CHANGE && (
itemID == IDE_EDIT_VIEWER ||
itemID == IDE_EDIT_EDITOR ||
itemID == IDE_EDIT_DIFF))
if (!_initMode && code == EN_CHANGE)
{
Changed();
return true;
for (unsigned i = 0; i < 3; i++)
{
CEditPageCtrl &c = _ctrls[i];
if (itemID == c.Ctrl)
{
c.WasChanged = true;
Changed();
return true;
}
}
}
return CPropertyPage::OnCommand(code, itemID, param);
}

View File

@@ -6,11 +6,19 @@
#include "../../../Windows/Control/PropertyPage.h"
#include "../../../Windows/Control/Edit.h"
struct CEditPageCtrl
{
NWindows::NControl::CEdit Edit;
bool WasChanged;
int Ctrl;
int Button;
};
class CEditPage: public NWindows::NControl::CPropertyPage
{
NWindows::NControl::CEdit _viewer;
NWindows::NControl::CEdit _editor;
NWindows::NControl::CEdit _diff;
CEditPageCtrl _ctrls[3];
bool _initMode;
public:
virtual bool OnInit();
virtual void OnNotifyHelp();

View File

@@ -157,6 +157,7 @@ static bool g_CanChangeSplitter = false;
static UInt32 g_SplitterPos = 0;
static CSplitterPos g_Splitter;
static bool g_PanelsInfoDefined = false;
static bool g_WindowWasCreated = false;
static int g_StartCaptureMousePos;
static int g_StartCaptureSplitterPos;
@@ -238,8 +239,9 @@ static BOOL InitInstance(int nCmdShow)
if (windowPosIsRead)
{
// x = rect.left;
// y = rect.top;
x = info.rect.left;
y = info.rect.top;
xSize = RECT_SIZE_X(info.rect);
ySize = RECT_SIZE_Y(info.rect);
}
@@ -258,6 +260,7 @@ static BOOL InitInstance(int nCmdShow)
info.numPanels = kNumDefaultPanels;
info.currentPanel = 0;
}
g_App.NumPanels = info.numPanels;
g_App.LastFocusedPanel = info.currentPanel;
@@ -324,42 +327,44 @@ static void GetCommands(const UString &aCommandLine, UString &aCommands)
}
*/
/*
#ifndef _WIN64
typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
#if defined(_WIN32) && !defined(_WIN64) && !defined(UNDER_CE)
static bool IsWow64()
bool g_Is_Wow64;
typedef BOOL (WINAPI *Func_IsWow64Process)(HANDLE, PBOOL);
static void Set_Wow64()
{
LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(
GetModuleHandle("kernel32"), "IsWow64Process");
if (fnIsWow64Process == NULL)
return false;
BOOL isWow;
if (!fnIsWow64Process(GetCurrentProcess(),&isWow))
return false;
return isWow != FALSE;
g_Is_Wow64 = false;
Func_IsWow64Process fnIsWow64Process = (Func_IsWow64Process)GetProcAddress(
GetModuleHandleA("kernel32.dll"), "IsWow64Process");
if (fnIsWow64Process)
{
BOOL isWow;
if (fnIsWow64Process(GetCurrentProcess(), &isWow))
g_Is_Wow64 = (isWow != FALSE);
}
}
#endif
*/
bool IsLargePageSupported()
{
#ifdef _WIN64
return true;
#else
OSVERSIONINFO versionInfo;
versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
if (!::GetVersionEx(&versionInfo))
OSVERSIONINFO vi;
vi.dwOSVersionInfoSize = sizeof(vi);
if (!::GetVersionEx(&vi))
return false;
if (versionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || versionInfo.dwMajorVersion < 5)
if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT)
return false;
if (versionInfo.dwMajorVersion > 5)
return true;
if (versionInfo.dwMinorVersion < 1)
return false;
if (versionInfo.dwMinorVersion > 1)
return true;
// return IsWow64();
if (vi.dwMajorVersion < 5) return false;
if (vi.dwMajorVersion > 5) return true;
if (vi.dwMinorVersion < 1) return false;
if (vi.dwMinorVersion > 1) return true;
// return g_Is_Wow64;
return false;
#endif
}
@@ -382,11 +387,11 @@ bool g_SymLink_Supported = false;
static void Set_SymLink_Supported()
{
g_SymLink_Supported = false;
OSVERSIONINFO versionInfo;
versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
if (!::GetVersionEx(&versionInfo))
OSVERSIONINFO vi;
vi.dwOSVersionInfoSize = sizeof(vi);
if (!::GetVersionEx(&vi))
return;
if (versionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || versionInfo.dwMajorVersion < 6)
if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT || vi.dwMajorVersion < 6)
return;
g_SymLink_Supported = true;
// if (g_SymLink_Supported)
@@ -468,6 +473,11 @@ static int WINAPI WinMain2(int nCmdShow)
g_LVN_ITEMACTIVATE_Support = (g_ComCtl32Version >= MAKELONG(71, 4));
#endif
#if defined(_WIN32) && !defined(_WIN64) && !defined(UNDER_CE)
Set_Wow64();
#endif
g_IsSmallScreen = !NWindows::NControl::IsDialogSizeOK(200, 200);
// OleInitialize is required for drag and drop.
@@ -635,7 +645,15 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
try
{
return WinMain2(nCmdShow);
try
{
return WinMain2(nCmdShow);
}
catch (...)
{
g_ExitEventLauncher.Exit(true);
throw;
}
}
catch(const CNewException &)
{
@@ -817,7 +835,9 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
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)
return -1;
@@ -837,6 +857,8 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
ErrorMessage(message);
return -1;
}
g_WindowWasCreated = true;
// g_SplitterPos = 0;
@@ -852,18 +874,21 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
RevokeDragDrop(hWnd);
g_App._dropTarget.Release();
g_App.Save();
if (g_WindowWasCreated)
g_App.Save();
g_App.Release();
SaveWindowInfo(hWnd);
if (g_WindowWasCreated)
SaveWindowInfo(hWnd);
g_ExitEventLauncher.Exit(true);
PostQuitMessage(0);
break;
}
/*
case WM_MOVE:
{
break;
}
*/
// case WM_MOVE: break;
case WM_LBUTTONDOWN:
g_StartCaptureMousePos = LOWORD(lParam);
g_StartCaptureSplitterPos = g_Splitter.GetPos();
@@ -993,6 +1018,7 @@ void CApp::MoveSubWindows()
if (xSize == 0)
return;
int headerSize = 0;
#ifdef UNDER_CE
_commandBar.AutoSize();
{
@@ -1000,6 +1026,7 @@ void CApp::MoveSubWindows()
headerSize += _commandBar.Height();
}
#endif
if (_toolBar)
{
_toolBar.AutoSize();
@@ -1009,6 +1036,7 @@ void CApp::MoveSubWindows()
#endif
headerSize += Window_GetRealHeight(_toolBar);
}
int ySize = MyMax((int)(rect.bottom - headerSize), 0);
if (NumPanels > 1)

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