This commit is contained in:
Igor Pavlov
2018-12-30 14:01:47 +00:00
committed by Kornel
parent 18dc2b4161
commit 5b2a99c548
113 changed files with 1805 additions and 932 deletions

View File

@@ -1,7 +1,7 @@
C_OBJS = $(C_OBJS) \
$O\Aes.obj
!IF "$(CPU)" != "IA64" && "$(CPU)" != "MIPS" && "$(CPU)" != "ARM" && "$(CPU)" != "ARM64"
!IF "$(PLATFORM)" != "ia64" && "$(PLATFORM)" != "mips" && "$(PLATFORM)" != "arm" && "$(PLATFORM)" != "arm64"
ASM_OBJS = $(ASM_OBJS) \
$O\AesOpt.obj
!ENDIF

View File

@@ -236,6 +236,13 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
prop = v;
break;
}
case kpidReadOnly:
{
if (!_db.CanUpdate())
prop = true;
break;
}
}
prop.Detach(value);
return S_OK;

View File

@@ -267,6 +267,9 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
db = &_db;
#endif
if (db && !db->CanUpdate())
return E_NOTIMPL;
/*
CMyComPtr<IArchiveGetRawProps> getRawProps;
updateCallback->QueryInterface(IID_IArchiveGetRawProps, (void **)&getRawProps);

View File

@@ -1465,21 +1465,24 @@ void CDbEx::FillLinks()
}
if (indexInFolder != 0)
{
folderIndex++;
/*
if (indexInFolder != 0)
ThrowIncorrect();
*/
// 18.06
ThereIsHeaderError = true;
// ThrowIncorrect();
}
for (;;)
{
if (folderIndex >= NumFolders)
return;
FolderStartFileIndex[folderIndex] = i;
/*
if (NumUnpackStreamsVector[folderIndex] != 0)
ThrowIncorrect();;
*/
{
// 18.06
ThereIsHeaderError = true;
// ThrowIncorrect();
}
folderIndex++;
}
}

View File

@@ -257,6 +257,16 @@ struct CDbEx: public CDatabase
PhySize = 0;
}
bool CanUpdate() const
{
if (ThereIsHeaderError
|| UnexpectedEnd
|| StartHeaderWasRecovered
|| UnsupportedFeatureError)
return false;
return true;
}
void FillLinks();
UInt64 GetFolderStreamPos(CNum folderIndex, unsigned indexInFolder) const

View File

@@ -124,13 +124,13 @@ static int Parse_EXE(const Byte *buf, size_t size, CFilterMode *filterMode)
#define ELF_DATA_2LSB 1
#define ELF_DATA_2MSB 2
static UInt16 Get16(const Byte *p, Bool be) { if (be) return (UInt16)GetBe16(p); return (UInt16)GetUi16(p); }
static UInt32 Get32(const Byte *p, Bool be) { if (be) return GetBe32(p); return GetUi32(p); }
// static UInt64 Get64(const Byte *p, Bool be) { if (be) return GetBe64(p); return GetUi64(p); }
static UInt16 Get16(const Byte *p, BoolInt be) { if (be) return (UInt16)GetBe16(p); return (UInt16)GetUi16(p); }
static UInt32 Get32(const Byte *p, BoolInt be) { if (be) return GetBe32(p); return GetUi32(p); }
// static UInt64 Get64(const Byte *p, BoolInt be) { if (be) return GetBe64(p); return GetUi64(p); }
static int Parse_ELF(const Byte *buf, size_t size, CFilterMode *filterMode)
{
Bool /* is32, */ be;
BoolInt /* is32, */ be;
UInt32 filterId;
if (size < 512 || buf[6] != 1) /* ver */
@@ -200,7 +200,7 @@ static unsigned Parse_MACH(const Byte *buf, size_t size, CFilterMode *filterMode
if (size < 512)
return 0;
Bool /* mode64, */ be;
BoolInt /* mode64, */ be;
switch (GetUi32(buf))
{
case MACH_SIG_BE_32: /* mode64 = False; */ be = True; break;
@@ -239,7 +239,7 @@ static unsigned Parse_MACH(const Byte *buf, size_t size, CFilterMode *filterMode
#define RIFF_SIG 0x46464952
static Bool Parse_WAV(const Byte *buf, size_t size, CFilterMode *filterMode)
static BoolInt Parse_WAV(const Byte *buf, size_t size, CFilterMode *filterMode)
{
UInt32 subChunkSize, pos;
if (size < 0x2C)
@@ -285,7 +285,7 @@ static Bool Parse_WAV(const Byte *buf, size_t size, CFilterMode *filterMode)
return False;
}
static Bool ParseFile(const Byte *buf, size_t size, CFilterMode *filterMode)
static BoolInt ParseFile(const Byte *buf, size_t size, CFilterMode *filterMode)
{
filterMode->Id = 0;
filterMode->Delta = 0;
@@ -894,7 +894,7 @@ HRESULT CAnalysis::GetFilterGroup(UInt32 index, const CUpdateItem &ui, CFilterMo
// RINOK(Callback->SetOperationResult2(index, NUpdate::NOperationResult::kOK));
if (result == S_OK)
{
Bool parseRes = ParseFile(Buffer, size, &filterModeTemp);
BoolInt parseRes = ParseFile(Buffer, size, &filterModeTemp);
if (parseRes && filterModeTemp.Delta == 0)
{
filterModeTemp.SetDelta();
@@ -1648,6 +1648,9 @@ HRESULT Update(
for (CNum fi = db->FolderStartFileIndex[i]; indexInFolder < numUnpackStreams; fi++)
{
if (fi >= db->Files.Size())
return E_FAIL;
const CFileItem &file = db->Files[fi];
if (file.HasStream)
{

View File

@@ -170,8 +170,8 @@ static bool OctalToNumber32(const char *s, unsigned size, UInt32 &res)
res = 0;
char sz[32];
size = RemoveTailSpaces(sz, s, size);
if (size == 0)
return true; // some items doesn't contaion any numbers
if (size == 0 || strcmp(sz, "-1") == 0)
return true; // some items don't contain any numbers
const char *end;
UInt64 res64 = ConvertOctStringToUInt64(sz, &end);
if ((unsigned)(end - sz) != size)
@@ -185,8 +185,8 @@ static bool DecimalToNumber(const char *s, unsigned size, UInt64 &res)
res = 0;
char sz[32];
size = RemoveTailSpaces(sz, s, size);
if (size == 0)
return true; // some items doesn't contaion any numbers
if (size == 0 || strcmp(sz, "-1") == 0)
return true; // some items don't contain any numbers
const char *end;
res = ConvertStringToUInt64(sz, &end);
return ((unsigned)(end - sz) == size);

View File

@@ -366,7 +366,13 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
return E_INVALIDARG;
size = prop.uhVal.QuadPart;
}
return UpdateArchive(size, outStream, _props, updateCallback);
CMethodProps props2 = _props;
#ifndef _7ZIP_ST
props2.AddProp_NumThreads(_props._numThreads);
#endif
return UpdateArchive(size, outStream, props2, updateCallback);
}
if (indexInArchive != 0)

View File

@@ -91,6 +91,7 @@ HRESULT CCoder::CheckDataAfterEnd(bool &dataAfterEnd_Error /* , bool &InternalPa
{
CMyComPtr<ICompressGetInStreamProcessedSize2> getInStreamProcessedSize2;
Coder2.QueryInterface(IID_ICompressGetInStreamProcessedSize2, (void **)&getInStreamProcessedSize2);
if (getInStreamProcessedSize2)
FOR_VECTOR (i, PackSizePointers)
{
if (!PackSizePointers[i])

View File

@@ -788,9 +788,21 @@ HRESULT CHandler::Open2(IInStream *stream)
if (headSize != RSRC_HEAD_SIZE
|| footerOffset >= rsrcPair.Len
|| mainDataSize >= rsrcPair.Len
|| footerOffset + footerSize != rsrcPair.Len
|| footerOffset < mainDataSize
|| footerOffset != headSize + mainDataSize)
return S_FALSE;
const UInt32 footerEnd = footerOffset + footerSize;
if (footerEnd != rsrcPair.Len)
{
// there is rare case dmg example, where there are 4 additional bytes
UInt64 rem = rsrcPair.Len - footerOffset;
if (rem < footerSize
|| rem - footerSize != 4
|| Get32(p + footerEnd) != 0)
return S_FALSE;
}
if (footerSize < 16)
return S_FALSE;
if (memcmp(p, p + footerOffset, 16) != 0)

View File

@@ -1596,6 +1596,17 @@ STDMETHODIMP CHandler::Close()
}
static void ChangeSeparatorsInName(char *s, unsigned num)
{
for (unsigned i = 0; i < num; i++)
{
char c = s[i];
if (c == CHAR_PATH_SEPARATOR || c == '/')
s[i] = '_';
}
}
void CHandler::GetPath(unsigned index, AString &s) const
{
s.Empty();
@@ -1612,6 +1623,8 @@ void CHandler::GetPath(unsigned index, AString &s) const
if (!s.IsEmpty())
s.InsertAtFront(CHAR_PATH_SEPARATOR);
s.Insert(0, item.Name);
// 18.06
ChangeSeparatorsInName(s.GetBuf(), item.Name.Len());
if (item.ParentNode == k_INODE_ROOT)
return;

View File

@@ -161,7 +161,8 @@ bool CHeader::Parse(const Byte *p)
return false;
// we also support images that contain 0 in offset field.
bool isOkOffset = (codeOffset == 0 || (p[0] == 0xEB && p[1] == 0));
bool isOkOffset = (codeOffset == 0)
|| (codeOffset == (p[0] == 0xEB ? 2 : 3));
UInt16 numRootDirEntries = Get16(p + 17);
if (numRootDirEntries == 0)

View File

@@ -419,7 +419,13 @@ void CDatabase::GetItemPath(unsigned index, NWindows::NCOM::CPropVariant &path)
const wchar_t *src = (const wchar_t *)*s;
wchar_t *dest = p + len;
for (unsigned j = 0; j < curLen; j++)
dest[j] = src[j];
{
wchar_t c = src[j];
// 18.06
if (c == CHAR_PATH_SEPARATOR || c == '/')
c = '_';
dest[j] = c;
}
if (len == 0)
break;

View File

@@ -131,13 +131,7 @@ HRESULT CDecoder::Code(const CHeader &header, ISequentialOutStream *outStream,
if (header.FilterID > 1)
return E_NOTIMPL;
{
CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
_lzmaDecoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties);
if (!setDecoderProperties)
return E_NOTIMPL;
RINOK(setDecoderProperties->SetDecoderProperties2(header.LzmaProps, 5));
}
RINOK(_lzmaDecoderSpec->SetDecoderProperties2(header.LzmaProps, 5));
bool filteredMode = (header.FilterID == 1);
@@ -357,24 +351,54 @@ API_FUNC_static_IsArc IsArc_Lzma86(const Byte *p, size_t size)
}
}
STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *)
{
Close();
const UInt32 kBufSize = 1 + 5 + 8 + 2;
const unsigned headerSize = GetHeaderSize();
const UInt32 kBufSize = 1 << 7;
Byte buf[kBufSize];
RINOK(ReadStream_FALSE(inStream, buf, kBufSize));
size_t processedSize = kBufSize;
RINOK(ReadStream(inStream, buf, &processedSize));
if (processedSize < headerSize + 2)
return S_FALSE;
if (!_header.Parse(buf, _lzma86))
return S_FALSE;
const Byte *start = buf + GetHeaderSize();
const Byte *start = buf + headerSize;
if (start[0] != 0 /* || (start[1] & 0x80) != 0 */ ) // empty stream with EOS is not 0x80
return S_FALSE;
RINOK(inStream->Seek(0, STREAM_SEEK_END, &_packSize));
if (_packSize >= 24 && _header.Size == 0 && _header.FilterID == 0 && _header.LzmaProps[0] == 0)
SizeT srcLen = processedSize - headerSize;
if (srcLen > 10
&& _header.Size == 0
// && _header.FilterID == 0
&& _header.LzmaProps[0] == 0
)
return S_FALSE;
CDecoder state;
const UInt32 outLimit = 1 << 11;
Byte outBuf[outLimit];
SizeT outSize = outLimit;
if (outSize > _header.Size)
outSize = (SizeT)_header.Size;
SizeT destLen = outSize;
ELzmaStatus status;
SRes res = LzmaDecode(outBuf, &destLen, start, &srcLen,
_header.LzmaProps, 5, LZMA_FINISH_ANY,
&status, &g_Alloc);
if (res != SZ_OK)
if (res != SZ_ERROR_INPUT_EOF)
return S_FALSE;
_isArc = true;
_stream = inStream;
_seqStream = inStream;

View File

@@ -2445,23 +2445,24 @@ void CInArchive::DetectNsisType(const CBlockHeader &bh, const Byte *p)
bool strongPark = false;
bool strongNsis = false;
if (NumStringChars > 2)
{
const Byte *strData = _data + _stringsPos;
if (IsUnicode)
{
UInt32 num = NumStringChars;
UInt32 num = NumStringChars - 2;
for (UInt32 i = 0; i < num; i++)
{
if (Get16(strData + i * 2) == 0)
{
unsigned c2 = Get16(strData + 2 + i * 2);
// it can be TXT/RTF with marker char (1 or 2). so we must check next char
// if (c2 <= NS_3_CODE_SKIP && c2 != NS_3_CODE_SHELL)
if (c2 == NS_3_CODE_VAR)
{
// it can be TXT/RTF string with marker char (1 or 2). so we must next char
// const wchar_t *p2 = (const wchar_t *)(strData + i * 2 + 2);
// p2 = p2;
if ((Get16(strData + 3 + i * 2) & 0x8000) != 0)
// 18.06: fixed: is it correct ?
// if ((Get16(strData + 3 + i * 2) & 0x8000) != 0)
if ((Get16(strData + 4 + i * 2) & 0x8080) == 0x8080)
{
NsisType = k_NsisType_Nsis3;
strongNsis = true;
@@ -2478,7 +2479,7 @@ void CInArchive::DetectNsisType(const CBlockHeader &bh, const Byte *p)
}
else
{
UInt32 num = NumStringChars;
UInt32 num = NumStringChars - 2;
for (UInt32 i = 0; i < num; i++)
{
if (strData[i] == 0)

View File

@@ -1475,6 +1475,21 @@ void CDatabase::ClearAndClose()
InStream.Release();
}
static void CopyName(wchar_t *dest, const wchar_t *src)
{
for (;;)
{
wchar_t c = *src++;
// 18.06
if (c == '\\' || c == '/')
c = '_';
*dest++ = c;
if (c == 0)
return;
}
}
void CDatabase::GetItemPath(unsigned index, NCOM::CPropVariant &path) const
{
const CItem *item = &Items[index];
@@ -1492,7 +1507,7 @@ void CDatabase::GetItemPath(unsigned index, NCOM::CPropVariant &path) const
wchar_t *s = path.AllocBstr(data.Name.Len() + 1);
s[0] = L':';
if (!data.Name.IsEmpty())
MyStringCopy(s + 1, data.Name.GetRawPtr());
CopyName(s + 1, data.Name.GetRawPtr());
return;
}
@@ -1541,7 +1556,7 @@ void CDatabase::GetItemPath(unsigned index, NCOM::CPropVariant &path) const
if (!name.IsEmpty())
{
size -= name.Len();
MyStringCopy(s + size, name.GetRawPtr());
CopyName(s + size, name.GetRawPtr());
}
s[--size] = ':';
needColon = true;
@@ -1551,7 +1566,7 @@ void CDatabase::GetItemPath(unsigned index, NCOM::CPropVariant &path) const
const UString2 &name = rec.FileNames[item->NameIndex].Name;
unsigned len = name.Len();
if (len != 0)
MyStringCopy(s + size - len, name.GetRawPtr());
CopyName(s + size - len, name.GetRawPtr());
if (needColon)
s[size] = ':';
size -= len;
@@ -1575,7 +1590,7 @@ void CDatabase::GetItemPath(unsigned index, NCOM::CPropVariant &path) const
if (len != 0)
{
size -= len;
MyStringCopy(s + size, name.GetRawPtr());
CopyName(s + size, name.GetRawPtr());
}
s[size + len] = WCHAR_PATH_SEPARATOR;
continue;

View File

@@ -1000,7 +1000,7 @@ bool CInArchive::ReadFileHeader(const CHeader &header, CItem &item)
struct CLinkFile
{
unsigned Index;
unsigned NumLinks;
unsigned NumLinks; // the number of links to Data
CByteBuffer Data;
HRESULT Res;
bool crcOK;
@@ -1015,7 +1015,7 @@ struct CUnpacker
CMyComPtr<ICompressCoder> copyCoder;
CMyComPtr<ICompressCoder> LzCoders[2];
bool NeedClearSolid[2];
bool SolidAllowed;
CFilterCoder *filterStreamSpec;
CMyComPtr<ISequentialInStream> filterStream;
@@ -1032,7 +1032,7 @@ struct CUnpacker
CLinkFile *linkFile;
CUnpacker(): linkFile(NULL) { NeedClearSolid[0] = NeedClearSolid[1] = true; }
CUnpacker(): linkFile(NULL) { SolidAllowed = false; }
HRESULT Create(DECL_EXTERNAL_CODECS_LOC_VARS const CItem &item, bool isSolid, bool &wrongPassword);
@@ -1142,7 +1142,9 @@ HRESULT CUnpacker::Code(const CItem &item, const CItem &lastItem, UInt64 packSiz
if (method > kLzMethodMax)
return E_NOTIMPL;
if (linkFile && !lastItem.Is_UnknownSize())
bool needBuf = (linkFile && linkFile->NumLinks != 0);
if (needBuf && !lastItem.Is_UnknownSize())
{
size_t dataSize = (size_t)lastItem.Size;
if (dataSize != lastItem.Size)
@@ -1167,15 +1169,15 @@ HRESULT CUnpacker::Code(const CItem &item, const CItem &lastItem, UInt64 packSiz
ICompressCoder *commonCoder = (method == 0) ? copyCoder : LzCoders[item.IsService() ? 1 : 0];
outStreamSpec->SetStream(realOutStream);
outStreamSpec->Init(lastItem, (linkFile ? (Byte *)linkFile->Data : NULL));
NeedClearSolid[item.IsService() ? 1 : 0] = false;
outStreamSpec->Init(lastItem, (needBuf ? (Byte *)linkFile->Data : NULL));
HRESULT res = S_OK;
if (packSize != 0 || lastItem.Is_UnknownSize() || lastItem.Size != 0)
{
res = commonCoder->Code(inStream, outStream, &packSize,
lastItem.Is_UnknownSize() ? NULL : &lastItem.Size, progress);
if (!item.IsService())
SolidAllowed = true;
}
else
{
@@ -1210,7 +1212,9 @@ HRESULT CUnpacker::Code(const CItem &item, const CItem &lastItem, UInt64 packSiz
{
linkFile->Res = res;
linkFile->crcOK = isCrcOK;
if (!lastItem.Is_UnknownSize() && processedSize != lastItem.Size)
if (needBuf
&& !lastItem.Is_UnknownSize()
&& processedSize != lastItem.Size)
linkFile->Data.ChangeSize_KeepData((size_t)processedSize, (size_t)processedSize);
}
@@ -2578,6 +2582,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
const Byte kStatus_Skip = 1 << 1;
const Byte kStatus_Link = 1 << 2;
/*
In original RAR:
1) service streams are not allowed to be solid,
and solid flag must be ignored for service streams.
2) If RAR creates new solid block and first file in solid block is Link file,
then it can clear solid flag for Link file and
clear solid flag for first non-Link file after Link file.
*/
CObjectVector<CLinkFile> linkFiles;
{
@@ -2603,13 +2616,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
if (ref.Link >= 0)
{
if (!testMode)
// 18.06 fixed: we use links for Test mode too
// if (!testMode)
{
if ((unsigned)ref.Link < index)
{
const CRefItem &linkRef = _refs[(unsigned)ref.Link];
const CItem &linkItem = _items[linkRef.Item];
if (linkItem.IsSolid() && linkItem.Size <= k_CopyLinkFile_MaxSize)
if (linkItem.IsSolid())
if (testMode || linkItem.Size <= k_CopyLinkFile_MaxSize)
{
if (extractStatuses[(unsigned)ref.Link] == 0)
{
@@ -2664,19 +2679,25 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
{
unsigned solidLimit = 0;
FOR_VECTOR(i, _refs)
FOR_VECTOR (i, _refs)
{
if ((extractStatuses[i] & kStatus_Link) == 0)
continue;
// We use CLinkFile for testMode too.
// So we can show errors for copy files.
// if (!testMode)
{
CLinkFile &linkFile = linkFiles.AddNew();
linkFile.Index = i;
}
const CItem &item = _items[_refs[i].Item];
/*
if (item.IsService())
continue;
*/
CLinkFile &linkFile = linkFiles.AddNew();
linkFile.Index = i;
if (item.IsSolid())
{
unsigned j = i;
@@ -2707,6 +2728,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
solidLimit = i + 1;
}
if (!testMode)
for (UInt32 t = 0; t < numItems; t++)
{
unsigned index = allFilesMode ? t : indices[t];
@@ -2748,7 +2770,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
// bool needClearSolid = true;
FOR_VECTOR(i, _refs)
FOR_VECTOR (i, _refs)
{
if (extractStatuses[i] == 0)
continue;
@@ -2761,15 +2783,19 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
CMyComPtr<ISequentialOutStream> realOutStream;
// isExtract means that we don't skip that item. So we need read data.
bool isExtract = ((extractStatuses[i] & kStatus_Extract) != 0);
Int32 askMode =
((extractStatuses[i] & kStatus_Extract) != 0) ? (testMode ?
isExtract ? (testMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract) :
NExtract::NAskMode::kSkip;
unpacker.linkFile = NULL;
if (((extractStatuses[i] & kStatus_Link) != 0))
// if (!testMode)
if ((extractStatuses[i] & kStatus_Link) != 0)
{
int bufIndex = FindLinkBuf(linkFiles, i);
if (bufIndex < 0)
@@ -2791,13 +2817,12 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
bool isSolid;
bool isSolid = false;
if (!item->IsService())
{
bool &needClearSolid = unpacker.NeedClearSolid[item->IsService() ? 1 : 0];
isSolid = (item->IsSolid() && !needClearSolid);
if (item->IsService())
isSolid = false;
needClearSolid = !item->IsSolid();
if (item->IsSolid())
isSolid = unpacker.SolidAllowed;
unpacker.SolidAllowed = isSolid;
}
if (item->IsDir())
@@ -2826,18 +2851,30 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
curUnpackSize = 0;
curPackSize = GetPackSize(index2);
}
else if ((unsigned)index2 < index)
bufIndex = FindLinkBuf(linkFiles, index2);
else
{
if ((unsigned)index2 < index)
bufIndex = FindLinkBuf(linkFiles, index2);
}
}
bool needCallback = true;
if (!realOutStream)
{
if (testMode)
{
if (item->NeedUse_as_CopyLink_or_HardLink())
{
Int32 opRes = NExtract::NOperationResult::kOK;
if (bufIndex >= 0)
{
const CLinkFile &linkFile = linkFiles[bufIndex];
opRes = DecoderRes_to_OpRes(linkFile.Res, linkFile.crcOK);
}
RINOK(extractCallback->PrepareOperation(askMode));
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
RINOK(extractCallback->SetOperationResult(opRes));
continue;
}
}
@@ -2846,10 +2883,10 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
if (item->IsService())
continue;
if (item->NeedUse_as_HardLink())
continue;
needCallback = false;
bool needDecode = false;
if (!item->NeedUse_as_HardLink())
if (index2 < 0)
for (unsigned n = i + 1; n < _refs.Size(); n++)
{
@@ -2860,41 +2897,56 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
break;
if (extractStatuses[i] != 0)
{
needDecode = true;
needCallback = true;
break;
}
}
if (!needDecode)
continue;
askMode = NExtract::NAskMode::kSkip;
}
}
RINOK(extractCallback->PrepareOperation(askMode));
if (needCallback)
{
RINOK(extractCallback->PrepareOperation(askMode));
}
if (bufIndex >= 0)
{
CLinkFile &linkFile = linkFiles[bufIndex];
if (linkFile.NumLinks == 0)
return E_FAIL;
if (realOutStream)
if (isExtract)
{
RINOK(CopyData_with_Progress(linkFile.Data, linkFile.Data.Size(), realOutStream, progress));
if (linkFile.NumLinks == 0)
return E_FAIL;
if (needCallback)
if (realOutStream)
{
RINOK(CopyData_with_Progress(linkFile.Data, linkFile.Data.Size(), realOutStream, progress));
}
if (--linkFile.NumLinks == 0)
linkFile.Data.Free();
}
if (needCallback)
{
RINOK(extractCallback->SetOperationResult(DecoderRes_to_OpRes(linkFile.Res, linkFile.crcOK)));
}
if (--linkFile.NumLinks == 0)
linkFile.Data.Free();
RINOK(extractCallback->SetOperationResult(DecoderRes_to_OpRes(linkFile.Res, linkFile.crcOK)));
continue;
}
if (!needCallback)
continue;
if (item->NeedUse_as_CopyLink())
{
RINOK(extractCallback->SetOperationResult(
realOutStream ?
NExtract::NOperationResult::kUnsupportedMethod:
NExtract::NOperationResult::kOK));
int opRes = realOutStream ?
NExtract::NOperationResult::kUnsupportedMethod:
NExtract::NOperationResult::kOK;
realOutStream.Release();
RINOK(extractCallback->SetOperationResult(opRes));
continue;
}
@@ -2941,7 +2993,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
}
{
FOR_VECTOR(i, linkFiles)
FOR_VECTOR (i, linkFiles)
if (linkFiles[i].NumLinks != 0)
return E_FAIL;
}

View File

@@ -415,6 +415,8 @@ bool CInArchive::ReadHeaderReal(const Byte *p, unsigned size, CItem &item)
if (size < 8)
return false;
item.PackSize |= ((UInt64)Get32(p) << 32);
if (item.PackSize >= ((UInt64)1 << 63))
return false;
item.Size |= ((UInt64)Get32(p + 4) << 32);
p += 8;
size -= 8;
@@ -667,7 +669,8 @@ HRESULT CInArchive::GetNextItem(CItem &item, ICryptoGetTextPassword *getTextPass
{
if (processed < offset + 2)
error = k_ErrorType_Corrupted;
ArcInfo.VolNumber = (UInt32)Get16(m_FileHeaderData + offset);
else
ArcInfo.VolNumber = (UInt32)Get16(m_FileHeaderData + offset);
}
ArcInfo.EndOfArchive_was_Read = true;

View File

@@ -4,6 +4,7 @@
#include "../../../C/Alloc.h"
#include "../../../C/CpuArch.h"
#include "../../../C/LzmaDec.h"
#include "../../../C/Xz.h"
#include "../../Common/ComTry.h"
@@ -24,7 +25,7 @@
#include "../Compress/CopyCoder.h"
#include "../Compress/ZlibDecoder.h"
#include "../Compress/LzmaDecoder.h"
// #include "../Compress/LzmaDecoder.h"
namespace NArchive {
namespace NSquashfs {
@@ -866,8 +867,8 @@ class CHandler:
CBufPtrSeqOutStream *_outStreamSpec;
CMyComPtr<ISequentialOutStream> _outStream;
NCompress::NLzma::CDecoder *_lzmaDecoderSpec;
CMyComPtr<ICompressCoder> _lzmaDecoder;
// NCompress::NLzma::CDecoder *_lzmaDecoderSpec;
// CMyComPtr<ICompressCoder> _lzmaDecoder;
NCompress::NZlib::CDecoder *_zlibDecoderSpec;
CMyComPtr<ICompressCoder> _zlibDecoder;
@@ -1155,12 +1156,13 @@ HRESULT CHandler::Decompress(ISequentialOutStream *outStream, Byte *outBuf, bool
if (inSize != _zlibDecoderSpec->GetInputProcessedSize())
return S_FALSE;
}
/*
else if (method == kMethod_LZMA)
{
if (!_lzmaDecoder)
{
_lzmaDecoderSpec = new NCompress::NLzma::CDecoder();
_lzmaDecoderSpec->FinishStream = true;
// _lzmaDecoderSpec->FinishStream = true;
_lzmaDecoder = _lzmaDecoderSpec;
}
const UInt32 kPropsSize = LZMA_PROPS_SIZE + 8;
@@ -1187,6 +1189,7 @@ HRESULT CHandler::Decompress(ISequentialOutStream *outStream, Byte *outBuf, bool
if (inSize != propsSize + _lzmaDecoderSpec->GetInputProcessedSize())
return S_FALSE;
}
*/
else
{
if (_inputBuffer.Size() < inSize)
@@ -1200,11 +1203,49 @@ HRESULT CHandler::Decompress(ISequentialOutStream *outStream, Byte *outBuf, bool
if (!dest)
return E_OUTOFMEMORY;
}
SizeT destLen = outSizeMax, srcLen = inSize;
if (method == kMethod_LZO)
{
RINOK(LzoDecode(dest, &destLen, _inputBuffer, &srcLen));
}
else if (method == kMethod_LZMA)
{
Byte props[5];
const Byte *src = _inputBuffer;
if (_noPropsLZMA)
{
props[0] = 0x5D;
SetUi32(&props[1], _h.BlockSize);
}
else
{
const UInt32 kPropsSize = LZMA_PROPS_SIZE + 8;
if (inSize < kPropsSize)
return S_FALSE;
memcpy(props, src, LZMA_PROPS_SIZE);
UInt64 outSize = GetUi64(src + LZMA_PROPS_SIZE);
if (outSize > outSizeMax)
return S_FALSE;
destLen = (SizeT)outSize;
src += kPropsSize;
inSize -= kPropsSize;
srcLen = inSize;
}
ELzmaStatus status;
SRes res = LzmaDecode(dest, &destLen,
src, &srcLen,
props, LZMA_PROPS_SIZE,
LZMA_FINISH_END,
&status, &g_Alloc);
if (res != 0)
return SResToHRESULT(res);
if (status != LZMA_STATUS_FINISHED_WITH_MARK)
return S_FALSE;
}
else
{
ECoderStatus status;
@@ -1217,6 +1258,7 @@ HRESULT CHandler::Decompress(ISequentialOutStream *outStream, Byte *outBuf, bool
if (status != CODER_STATUS_NEEDS_MORE_INPUT || !XzUnpacker_IsStreamWasFinished(&_xz))
return S_FALSE;
}
if (inSize != srcLen)
return S_FALSE;
if (outBuf)

View File

@@ -46,7 +46,7 @@ static const Byte SWF_COMPRESSED_LZMA = 'Z';
static const Byte SWF_MIN_COMPRESSED_ZLIB_VER = 6;
static const Byte SWF_MIN_COMPRESSED_LZMA_VER = 13;
static const Byte kVerLim = 20;
static const Byte kVerLim = 64;
API_FUNC_static_IsArc IsArc_Swf(const Byte *p, size_t size)
{

View File

@@ -443,14 +443,14 @@ HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &item, EErro
case 'X':
{
// pax Extended Header
if (item.Name.IsPrefixedBy("PaxHeader/"))
if (item.Name.IsPrefixedBy("PaxHeader/")
|| item.Name.Find("PaxHeaders.4467/") >= 0)
{
RINOK(ReadDataToString(stream, item, pax, error));
if (error != k_ErrorType_OK)
return S_OK;
continue;
}
break;
}
case NFileHeader::NLinkFlag::kDumpDir:
@@ -488,7 +488,11 @@ HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &item, EErro
if (ParsePaxLongName(pax, name))
item.Name = name;
else
error = k_ErrorType_Warning;
{
// no "path" property is allowed in pax4467
// error = k_ErrorType_Warning;
}
pax.Empty();
}
return S_OK;

View File

@@ -111,7 +111,9 @@ HRESULT CUnpacker::UnpackChunk(
}
else if (method == NMethod::kLZX)
{
lzxDecoderSpec->SetExternalWindow(unpackBuf.Data, chunkSizeBits);
res = lzxDecoderSpec->SetExternalWindow(unpackBuf.Data, chunkSizeBits);
if (res != S_OK)
return E_NOTIMPL;
lzxDecoderSpec->KeepHistoryForNext = false;
lzxDecoderSpec->SetKeepHistory(false);
res = lzxDecoderSpec->Code(packBuf.Data, inSize, (UInt32)outSize);
@@ -563,7 +565,13 @@ void CDatabase::GetItemPath(unsigned index1, bool showImageNumber, NWindows::NCO
wchar_t *dest = s + size;
meta += 2;
for (unsigned i = 0; i < len; i++)
dest[i] = Get16(meta + i * 2);
{
wchar_t c = Get16(meta + i * 2);
// 18.06
if (c == CHAR_PATH_SEPARATOR || c == '/')
c = '_';
dest[i] = c;
}
}
if (index < 0)
return;
@@ -866,7 +874,11 @@ HRESULT CDatabase::ParseImageDirs(CByteBuffer &buf, int parent)
if (DirProcessed == DirSize - 8 && Get64(p + DirSize - 8) != 0)
return S_OK;
return S_FALSE;
// 18.06: we support cases, when some old dism can capture images
// where DirProcessed much smaller than DirSize
HeadersError = true;
return S_OK;
// return S_FALSE;
}

View File

@@ -468,7 +468,7 @@ public:
int ExludedItem; // -1 : if there are no exclude items
CUIntVector VirtualRoots; // we use them for old 1.10 WIM archives
bool ThereIsError() const { return RefCountError; }
bool ThereIsError() const { return RefCountError || HeadersError; }
unsigned GetNumUserItemsInImage(unsigned imageIndex) const
{
@@ -544,7 +544,10 @@ public:
HeadersError = false;
}
CDatabase(): RefCountError(false) {}
CDatabase():
RefCountError(false),
HeadersError(false)
{}
void GetShortName(unsigned index, NWindows::NCOM::CPropVariant &res) const;
void GetItemName(unsigned index1, NWindows::NCOM::CPropVariant &res) const;

View File

@@ -488,7 +488,7 @@ HRESULT CHandler::Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCal
{
CXzBlock block;
Bool isIndex;
BoolInt isIndex;
UInt32 headerSizeRes;
SRes res2 = XzBlock_ReadHeader(&block, &inStreamWrap.vt, &isIndex, &headerSizeRes);
if (res2 == SZ_OK && !isIndex)
@@ -820,7 +820,7 @@ static HRESULT DecodeBlock(CXzUnpackerCPP2 &xzu,
packRem -= inLen;
Bool blockFinished = XzUnpacker_IsBlockFinished(&xzu.p);
BoolInt blockFinished = XzUnpacker_IsBlockFinished(&xzu.p);
if ((inLen == 0 && outLen == 0) || blockFinished)
{

View File

@@ -599,8 +599,12 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidHostOS:
{
const Byte hostOS = item.GetHostOS();
TYPE_TO_PROP(kHostOS, hostOS, prop);
if (item.FromCentral)
{
// 18.06: now we use HostOS only from Central::MadeByVersion
const Byte hostOS = item.MadeByVersion.HostOS;
TYPE_TO_PROP(kHostOS, hostOS, prop);
}
break;
}

View File

@@ -155,6 +155,7 @@ void CInArchive::Close()
HeadersError = false;
HeadersWarning = false;
ExtraMinorError = false;
UnexpectedEnd = false;
LocalsWereRead = false;
LocalsCenterMerged = false;
@@ -1729,6 +1730,9 @@ HRESULT CInArchive::FindCd(bool checkOffsetMode)
HRESULT CInArchive::TryReadCd(CObjectVector<CItemEx> &items, const CCdInfo &cdInfo, UInt64 cdOffset, UInt64 cdSize)
{
items.Clear();
// _startLocalFromCd_Disk = (UInt32)(Int32)-1;
// _startLocalFromCd_Offset = (UInt64)(Int64)-1;
RINOK(SeekToVol(IsMultiVol ? cdInfo.CdDisk : -1, cdOffset));
@@ -1752,6 +1756,17 @@ HRESULT CInArchive::TryReadCd(CObjectVector<CItemEx> &items, const CCdInfo &cdIn
{
CItemEx cdItem;
RINOK(ReadCdItem(cdItem));
/*
if (cdItem.Disk < _startLocalFromCd_Disk ||
cdItem.Disk == _startLocalFromCd_Disk &&
cdItem.LocalHeaderPos < _startLocalFromCd_Offset)
{
_startLocalFromCd_Disk = cdItem.Disk;
_startLocalFromCd_Offset = cdItem.LocalHeaderPos;
}
*/
items.Add(cdItem);
}
if (Callback && (items.Size() & 0xFFF) == 0)
@@ -2509,6 +2524,8 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
{
ArcInfo.CdWasRead = true;
ArcInfo.FirstItemRelatOffset = items[0].LocalHeaderPos;
// ArcInfo.FirstItemRelatOffset = _startLocalFromCd_Offset;
}
}
}
@@ -2535,6 +2552,10 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
items.Clear();
localsWereRead = true;
HeadersError = false;
HeadersWarning = false;
ExtraMinorError = false;
// we can use any mode: with buffer and without buffer
// without buffer : skips packed data : fast for big files : slow for small files
// with buffer : reads packed data : slow for big files : fast for small files

View File

@@ -250,6 +250,9 @@ class CInArchive
UInt64 _streamPos;
UInt64 _cnt;
// UInt32 _startLocalFromCd_Disk;
// UInt64 _startLocalFromCd_Offset;
size_t GetAvail() const { return _bufCached - _bufPos; }
void InitBuf() { _bufPos = 0; _bufCached = 0; }
@@ -383,6 +386,9 @@ public:
UInt64 GetEmbeddedStubSize() const
{
// it's possible that first item in CD doesn refers to first local item
// so FirstItemRelatOffset is not first local item
if (ArcInfo.CdWasRead)
return ArcInfo.FirstItemRelatOffset;
if (IsMultiVol)

View File

@@ -214,6 +214,12 @@ class CLocalItem
public:
UInt16 Flags;
UInt16 Method;
/*
Zip specification doesn't mention that ExtractVersion field uses HostOS subfield.
18.06: 7-Zip now doesn't use ExtractVersion::HostOS to detect codePage
*/
CVersion ExtractVersion;
UInt64 Size;
@@ -309,7 +315,8 @@ public:
UInt32 GetWinAttrib() const;
bool GetPosixAttrib(UInt32 &attrib) const;
Byte GetHostOS() const { return FromCentral ? MadeByVersion.HostOS : ExtractVersion.HostOS; }
// 18.06: 0 instead of ExtractVersion.HostOS for local item
Byte GetHostOS() const { return FromCentral ? MadeByVersion.HostOS : (Byte)0; }
void GetUnicodeString(UString &res, const AString &s, bool isComment, bool useSpecifiedCodePage, UINT codePage) const;
@@ -326,7 +333,10 @@ public:
UINT GetCodePage() const
{
Byte hostOS = GetHostOS();
// 18.06: now we use HostOS only from Central::MadeByVersion
if (!FromCentral)
return CP_OEMCP;
Byte hostOS = MadeByVersion.HostOS;
return (UINT)((
hostOS == NFileHeader::NHostOS::kFAT
|| hostOS == NFileHeader::NHostOS::kNTFS

View File

@@ -40,7 +40,10 @@ static const Byte kHostOS =
#endif
static const Byte kMadeByHostOS = kHostOS;
static const Byte kExtractHostOS = kHostOS;
// 18.06: now we always write zero to high byte of ExtractVersion field.
// Previous versions of p7zip wrote (NFileHeader::NHostOS::kUnix) there, that is not correct
static const Byte kExtractHostOS = 0;
static const Byte kMethodForDirectory = NFileHeader::NCompressionMethod::kStore;

View File

@@ -55,5 +55,6 @@ C_OBJS = \
$O\Threads.obj \
!include "../../Crc.mak"
!include "../../LzmaDec.mak"
!include "../../7zip.mak"

View File

@@ -446,6 +446,14 @@ void CCoder::SetOutStreamSizeResume(const UInt64 *outSize)
STDMETHODIMP CCoder::SetOutStreamSize(const UInt64 *outSize)
{
/*
18.06:
We want to support GetInputProcessedSize() before CCoder::Read()
So we call m_InBitStream.Init() even before buffer allocations
m_InBitStream.Init() just sets variables to default values
But later we will call m_InBitStream.Init() again with real buffer pointers
*/
m_InBitStream.Init();
_needInitInStream = true;
SetOutStreamSizeResume(outSize);
return S_OK;

View File

@@ -517,9 +517,9 @@ HRESULT CDecoder::CodeReal(const Byte *in, size_t inSize, Byte *_win, size_t out
if (len > outSize - _pos)
return S_FALSE;
if (dist > _pos)
return S_FALSE;
size_t span = (size_t)1 << power;
if ((UInt64)dist + span > _pos)
return S_FALSE;
Byte *dest = _win + _pos - span;
const Byte *src = dest - dist;
_pos += len;

View File

@@ -148,7 +148,8 @@ void CDecoder::ExecuteFilter(unsigned tempFilterIndex, NVm::CBlockRef &outBlockR
if (!_vm.Execute(filter, tempFilter, outBlockRef, filter->GlobalData))
_unsupportedFilter = true;
delete tempFilter;
_tempFilters[tempFilterIndex] = 0;
_tempFilters[tempFilterIndex] = NULL;
_numEmptyTempFilters++;
}
HRESULT CDecoder::WriteBuf()
@@ -225,6 +226,7 @@ HRESULT CDecoder::WriteBuf()
void CDecoder::InitFilters()
{
_lastFilter = 0;
_numEmptyTempFilters = 0;
unsigned i;
for (i = 0; i < _tempFilters.Size(); i++)
delete _tempFilters[i];
@@ -274,24 +276,27 @@ bool CDecoder::AddVmCode(UInt32 firstByte, UInt32 codeSize)
filter->ExecCount++;
}
unsigned numEmptyItems = 0;
if (_numEmptyTempFilters != 0)
{
FOR_VECTOR (i, _tempFilters)
unsigned num = _tempFilters.Size();
CTempFilter **tempFilters = &_tempFilters.Front();
unsigned w = 0;
for (unsigned i = 0; i < num; i++)
{
_tempFilters[i - numEmptyItems] = _tempFilters[i];
if (!_tempFilters[i])
numEmptyItems++;
if (numEmptyItems != 0)
_tempFilters[i] = NULL;
CTempFilter *tf = tempFilters[i];
if (tf)
tempFilters[w++] = tf;
}
_tempFilters.DeleteFrom(w);
_numEmptyTempFilters = 0;
}
if (numEmptyItems == 0)
{
_tempFilters.Add(NULL);
numEmptyItems = 1;
}
if (_tempFilters.Size() > MAX_UNPACK_FILTERS)
return false;
CTempFilter *tempFilter = new CTempFilter;
_tempFilters[_tempFilters.Size() - numEmptyItems] = tempFilter;
_tempFilters.Add(tempFilter);
tempFilter->FilterIndex = filterIndex;
UInt32 blockStart = inp.ReadEncodedUInt32();

View File

@@ -189,6 +189,7 @@ class CDecoder:
NVm::CVm _vm;
CRecordVector<CFilter *> _filters;
CRecordVector<CTempFilter *> _tempFilters;
unsigned _numEmptyTempFilters;
UInt32 _lastFilter;
bool _isSolid;

View File

@@ -33,10 +33,11 @@ struct CBitStream
bs.Value = (bs.Value << 16) | GetUi16(in); \
in += 2; bs.BitPos += 16; }
const unsigned kNumHuffBits = 15;
const unsigned kNumLenSlots = 16;
const unsigned kNumPosSlots = 16;
const unsigned kNumSyms = 256 + kNumPosSlots * kNumLenSlots;
static const unsigned kNumHuffBits = 15;
static const unsigned kNumLenBits = 4;
static const unsigned kLenMask = (1 << kNumLenBits) - 1;
static const unsigned kNumPosSlots = 16;
static const unsigned kNumSyms = 256 + (kNumPosSlots << kNumLenBits);
HRESULT Decode(const Byte *in, size_t inSize, Byte *out, size_t outSize)
{
@@ -83,10 +84,10 @@ HRESULT Decode(const Byte *in, size_t inSize, Byte *out, size_t outSize)
else
{
sym -= 256;
UInt32 dist = sym / kNumLenSlots;
UInt32 len = sym & (kNumLenSlots - 1);
UInt32 dist = sym >> kNumLenBits;
UInt32 len = sym & kLenMask;
if (len == kNumLenSlots - 1)
if (len == kLenMask)
{
if (in > lim)
return S_FALSE;
@@ -99,7 +100,7 @@ HRESULT Decode(const Byte *in, size_t inSize, Byte *out, size_t outSize)
in += 2;
}
else
len += kNumLenSlots - 1;
len += kLenMask;
}
bs.BitPos -= dist;
@@ -108,7 +109,7 @@ HRESULT Decode(const Byte *in, size_t inSize, Byte *out, size_t outSize)
BIT_STREAM_NORMALIZE
if (len > outSize - pos)
if (len + 3 > outSize - pos)
return S_FALSE;
if (dist > pos)
return S_FALSE;

View File

@@ -1,6 +1,6 @@
C_OBJS = $(C_OBJS) \
$O\7zCrc.obj
!IF "$(CPU)" == "IA64" || "$(CPU)" == "MIPS" || "$(CPU)" == "ARM" || "$(CPU)" == "ARM64"
!IF "$(PLATFORM)" == "ia64" || "$(PLATFORM)" == "mips" || "$(PLATFORM)" == "arm" || "$(PLATFORM)" == "arm64"
C_OBJS = $(C_OBJS) \
!ELSE
ASM_OBJS = $(ASM_OBJS) \

View File

@@ -1,6 +1,6 @@
C_OBJS = $(C_OBJS) \
$O\XzCrc64.obj
!IF "$(CPU)" == "IA64" || "$(CPU)" == "MIPS" || "$(CPU)" == "ARM" || "$(CPU)" == "ARM64"
!IF "$(PLATFORM)" == "ia64" || "$(PLATFORM)" == "mips" || "$(PLATFORM)" == "arm" || "$(PLATFORM)" == "arm64"
C_OBJS = $(C_OBJS) \
!ELSE
ASM_OBJS = $(ASM_OBJS) \

View File

@@ -1,4 +1,4 @@
!IF "$(CPU)" == "AMD64"
!IF "$(PLATFORM)" == "x64"
CFLAGS_C_SPEC = -D_LZMA_DEC_OPT
ASM_OBJS = $(ASM_OBJS) \
$O\LzmaDecOpt.obj

View File

@@ -23,6 +23,7 @@
#include "../../../Common/StringConvert.h"
#include "../../../Common/StringToInt.h"
#include "../../../Windows/ErrorMsg.h"
#include "../../../Windows/FileDir.h"
#include "../../../Windows/FileName.h"
#ifdef _WIN32
@@ -39,7 +40,9 @@
extern bool g_CaseSensitive;
extern bool g_PathTrailReplaceMode;
#ifdef _7ZIP_LARGE_PAGES
bool g_LargePagesMode = false;
#endif
#ifdef UNDER_CE
@@ -410,8 +413,19 @@ static void AddToCensorFromListFile(
UStringVector names;
if (!NFind::DoesFileExist(us2fs(fileName)))
throw CArcCmdLineException(kCannotFindListFile, fileName);
if (!ReadNamesFromListFile(us2fs(fileName), names, codePage))
DWORD lastError = 0;
if (!ReadNamesFromListFile2(us2fs(fileName), names, codePage, lastError))
{
if (lastError != 0)
{
UString m;
m = "The file operation error for listfile";
m.Add_LF();
m += NError::MyFormatMessage(lastError);
throw CArcCmdLineException(m, fileName);
}
throw CArcCmdLineException(kIncorrectListFile, fileName);
}
if (renamePairs)
{
if ((names.Size() & 1) != 0)

View File

@@ -1182,7 +1182,9 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
bool needDelete = true;
if (needDelete)
{
if (NFind::DoesFileExist(fullProcessedPath))
if (!DeleteFileAlways(fullProcessedPath))
if (GetLastError() != ERROR_FILE_NOT_FOUND)
{
RINOK(SendMessageError_with_LastError(kCantDeleteOutputFile, fullProcessedPath));
return S_OK;
@@ -1368,13 +1370,35 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
// UInt64 ticks = GetCpuTicks();
bool res = _outFileStreamSpec->File.SetLength(_curSize);
_fileLengthWasSet = res;
_outFileStreamSpec->File.SeekToBegin();
// ticks = GetCpuTicks() - ticks;
// printf("\nticks = %10d\n", (unsigned)ticks);
if (!res)
{
RINOK(SendMessageError_with_LastError(kCantSetFileLen, fullProcessedPath));
}
/*
_outFileStreamSpec->File.Close();
ticks = GetCpuTicks() - ticks;
printf("\nticks = %10d\n", (unsigned)ticks);
return S_FALSE;
*/
/*
File.SetLength() on FAT (xp64): is fast, but then File.Close() can be slow,
if we don't write any data.
File.SetLength() for remote share file (exFAT) can be slow in some cases,
and the Windows can return "network error" after 1 minute,
while remote file still can grow.
We need some way to detect such bad cases and disable PreAllocateOutFile mode.
*/
res = _outFileStreamSpec->File.SeekToBegin();
if (!res)
{
RINOK(SendMessageError_with_LastError("Can not seek to begin of file", fullProcessedPath));
}
}
#ifdef SUPPORT_ALT_STREAMS

View File

@@ -2,6 +2,8 @@
#include "StdAfx.h"
#include "../../../Common/Wildcard.h"
#include "../../../Windows/FileDir.h"
#include "../../../Windows/FileName.h"
@@ -11,7 +13,7 @@
using namespace NWindows;
using namespace NFile;
UString CreateArchiveName(const NFind::CFileInfo &fi, bool keepName)
static UString CreateArchiveName(const NFind::CFileInfo &fi, bool keepName)
{
FString resultName = fi.Name;
if (!fi.IsDir() && !keepName)
@@ -72,7 +74,75 @@ static FString CreateArchiveName2(const FString &path, bool fromPrev, bool keepN
return resultName;
}
UString CreateArchiveName(const UString &path, bool fromPrev, bool keepName)
UString CreateArchiveName(const UStringVector &paths, const NFind::CFileInfo *fi)
{
return Get_Correct_FsFile_Name(fs2us(CreateArchiveName2(us2fs(path), fromPrev, keepName)));
bool keepName = false;
/*
if (paths.Size() == 1)
{
const UString &name = paths[0];
if (name.Len() > 4)
if (CompareFileNames(name.RightPtr(4), L".tar") == 0)
keepName = true;
}
*/
UString name;
if (fi)
name = CreateArchiveName(*fi, keepName);
else
{
if (paths.IsEmpty())
return L"archive";
bool fromPrev = (paths.Size() > 1);
name = Get_Correct_FsFile_Name(fs2us(CreateArchiveName2(us2fs(paths.Front()), fromPrev, keepName)));
}
UString postfix;
UInt32 index = 1;
for (;;)
{
// we don't want cases when we include archive to itself.
// so we find first available name for archive
const UString name2 = name + postfix;
const UString name2_zip = name2 + L".zip";
const UString name2_7z = name2 + L".7z";
const UString name2_tar = name2 + L".tar";
const UString name2_wim = name2 + L".wim";
unsigned i = 0;
for (i = 0; i < paths.Size(); i++)
{
const UString &fn = paths[i];
NFind::CFileInfo fi2;
const NFind::CFileInfo *fp;
if (fi && paths.Size() == 1)
fp = fi;
else
{
if (!fi2.Find(us2fs(fn)))
continue;
fp = &fi2;
}
const UString fname = fs2us(fp->Name);
if ( 0 == CompareFileNames(fname, name2_zip)
|| 0 == CompareFileNames(fname, name2_7z)
|| 0 == CompareFileNames(fname, name2_tar)
|| 0 == CompareFileNames(fname, name2_wim))
break;
}
if (i == paths.Size())
break;
index++;
postfix = "_";
postfix.Add_UInt32(index);
}
name += postfix;
return name;
}

View File

@@ -3,11 +3,8 @@
#ifndef __ARCHIVE_NAME_H
#define __ARCHIVE_NAME_H
#include "../../../Common/MyString.h"
#include "../../../Windows/FileFind.h"
UString CreateArchiveName(const UString &path, bool fromPrev, bool keepName);
UString CreateArchiveName(const NWindows::NFile::NFind::CFileInfo &fileInfo, bool keepName);
UString CreateArchiveName(const UStringVector &paths, const NWindows::NFile::NFind::CFileInfo *fi = NULL);
#endif

View File

@@ -522,10 +522,9 @@ class CBenchProgressInfo:
{
public:
CBenchProgressStatus *Status;
HRESULT Res;
IBenchCallback *Callback;
CBenchProgressInfo(): Callback(0) {}
CBenchProgressInfo(): Callback(NULL) {}
MY_UNKNOWN_IMP
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
};
@@ -758,7 +757,7 @@ struct CEncoderInfo
fileData(NULL),
CheckCrc_Enc(true),
CheckCrc_Dec(true),
outStreamSpec(0), callback(0), printCallback(0), propStreamSpec(0) {}
outStreamSpec(NULL), callback(NULL), printCallback(NULL), propStreamSpec(NULL) {}
#ifndef _7ZIP_ST
@@ -1144,7 +1143,7 @@ static const UInt32 kNumThreadsMax = (1 << 12);
struct CBenchEncoders
{
CEncoderInfo *encoders;
CBenchEncoders(UInt32 num): encoders(0) { encoders = new CEncoderInfo[num]; }
CBenchEncoders(UInt32 num): encoders(NULL) { encoders = new CEncoderInfo[num]; }
~CBenchEncoders() { delete []encoders; }
};
@@ -1545,7 +1544,7 @@ struct CFreqThreads
CFreqInfo *Items;
UInt32 NumThreads;
CFreqThreads(): Items(0), NumThreads(0) {}
CFreqThreads(): Items(NULL), NumThreads(0) {}
void WaitAll()
{
for (UInt32 i = 0; i < NumThreads; i++)
@@ -1603,7 +1602,7 @@ struct CCrcThreads
CCrcInfo *Items;
UInt32 NumThreads;
CCrcThreads(): Items(0), NumThreads(0) {}
CCrcThreads(): Items(NULL), NumThreads(0) {}
void WaitAll()
{
for (UInt32 i = 0; i < NumThreads; i++)
@@ -1885,8 +1884,51 @@ AString GetProcessThreadsInfo(const NSystem::CProcessAffinity &ti)
}
static void PrintSize(AString &s, UInt64 v)
{
char c = 0;
if ((v & 0x3FF) == 0) { v >>= 10; c = 'K';
if ((v & 0x3FF) == 0) { v >>= 10; c = 'M';
if ((v & 0x3FF) == 0) { v >>= 10; c = 'G';
if ((v & 0x3FF) == 0) { v >>= 10; c = 'T';
}}}}
else
{
PrintHex(s, v);
return;
}
char temp[32];
ConvertUInt64ToString(v, temp);
s += temp;
if (c)
s += c;
}
#ifdef _7ZIP_LARGE_PAGES
extern bool g_LargePagesMode;
extern "C"
{
extern SIZE_T g_LargePageSize;
}
void Add_LargePages_String(AString &s)
{
if (g_LargePagesMode || g_LargePageSize != 0)
{
s += " (LP-";
PrintSize(s, g_LargePageSize);
if (!g_LargePagesMode)
s += "-NA";
s += ")";
}
}
#endif
static void PrintRequirements(IBenchPrintCallback &f, const char *sizeString,
bool size_Defined, UInt64 size, const char *threadsString, UInt32 numThreads)
@@ -1898,8 +1940,15 @@ static void PrintRequirements(IBenchPrintCallback &f, const char *sizeString,
else
f.Print(" ?");
f.Print(" MB");
if (g_LargePagesMode)
f.Print(" LP");
#ifdef _7ZIP_LARGE_PAGES
{
AString s;
Add_LargePages_String(s);
f.Print(s);
}
#endif
f.Print(", # ");
f.Print(threadsString);
PrintNumber(f, numThreads, 3);
@@ -2539,26 +2588,7 @@ static const char * const k_PF[] =
#endif
static void PrintSize(AString &s, UInt64 v)
{
char c = 0;
if ((v & 0x3FF) == 0) { v >>= 10; c = 'K';
if ((v & 0x3FF) == 0) { v >>= 10; c = 'M';
if ((v & 0x3FF) == 0) { v >>= 10; c = 'G';
if ((v & 0x3FF) == 0) { v >>= 10; c = 'T';
}}}}
else
{
PrintHex(s, v);
return;
}
char temp[32];
ConvertUInt64ToString(v, temp);
s += temp;
if (c)
s += c;
}
static void PrintPage(AString &s, UInt32 v)
{
@@ -2707,8 +2737,9 @@ void GetCpuName(AString &s)
#endif
if (g_LargePagesMode)
s += " (LP)";
#ifdef _7ZIP_LARGE_PAGES
Add_LargePages_String(s);
#endif
}
@@ -2968,6 +2999,9 @@ HRESULT Bench(
UInt64 start = ::GetTimeCount();
UInt32 sum = (UInt32)start;
sum = CountCpuFreq(sum, (UInt32)(numMilCommands * 1000000 / kNumFreqCommands), g_BenchCpuFreqTemp);
if (sum == 0xF1541213)
if (printCallback)
printCallback->Print("");
const UInt64 realDelta = ::GetTimeCount() - start;
start = realDelta;
if (start == 0)
@@ -2984,7 +3018,7 @@ HRESULT Bench(
else
{
// PrintNumber(*printCallback, start, 0);
PrintNumber(*printCallback, mipsVal, 5 + ((sum == 0xF1541213) ? 1 : 0));
PrintNumber(*printCallback, mipsVal, 5);
}
}
/*

View File

@@ -68,5 +68,10 @@ void GetSysInfo(AString &s1, AString &s2);
void GetCpuName(AString &s);
void GetCpuFeatures(AString &s);
#ifdef _7ZIP_LARGE_PAGES
void Add_LargePages_String(AString &s);
#else
// #define Add_LargePages_String
#endif
#endif

View File

@@ -1084,3 +1084,13 @@ CMessagePathException::CMessagePathException(const char *a, const wchar_t *u)
(*this) += u;
}
}
CMessagePathException::CMessagePathException(const wchar_t *a, const wchar_t *u)
{
(*this) += a;
if (u)
{
Add_LF();
(*this) += u;
}
}

View File

@@ -22,6 +22,7 @@ HRESULT EnumerateItems(
struct CMessagePathException: public UString
{
CMessagePathException(const char *a, const wchar_t *u = NULL);
CMessagePathException(const wchar_t *a, const wchar_t *u = NULL);
};

View File

@@ -230,7 +230,7 @@ HRESULT HashCalc(
unsigned i;
CHashBundle hb;
RINOK(hb.SetMethods(EXTERNAL_CODECS_LOC_VARS options.Methods));
hb.Init();
// hb.Init();
hb.NumErrors = dirItems.Stat.NumErrors;

View File

@@ -51,9 +51,13 @@ struct CHashBundle: public IHashCalc
UInt64 CurSize;
UString MainName;
UString FirstFileName;
HRESULT SetMethods(DECL_EXTERNAL_CODECS_LOC_VARS const UStringVector &methods);
void Init()
// void Init() {}
CHashBundle()
{
NumDirs = NumFiles = NumAltStreams = FilesSize = AltStreamsSize = NumErrors = 0;
}
@@ -76,7 +80,7 @@ struct CHashBundle: public IHashCalc
virtual HRESULT GetStream(const wchar_t *name, bool isFolder) x; \
virtual HRESULT OpenFileError(const FString &path, DWORD systemError) x; \
virtual HRESULT SetOperationResult(UInt64 fileSize, const CHashBundle &hb, bool showHash) x; \
virtual HRESULT AfterLastFile(const CHashBundle &hb) x; \
virtual HRESULT AfterLastFile(CHashBundle &hb) x; \
struct IHashCallbackUI: public IDirItemsCallback
{

View File

@@ -563,6 +563,8 @@ HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &pa
UInt32 parentType = 0;
RINOK(GetRawProps->GetParent(curIndex, &curParent, &parentType));
// 18.06: fixed : we don't want to split name to parts
/*
if (parentType != NParentType::kAltStream)
{
for (;;)
@@ -576,6 +578,7 @@ HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &pa
s.DeleteFrom(pos);
}
}
*/
parts.Insert(0, s);
@@ -2013,7 +2016,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
}
else
{
const CArcInfoEx &ai = op.codecs->Formats[formatIndex];
const CArcInfoEx &ai = op.codecs->Formats[(unsigned)formatIndex];
if (ai.FindExtension(extension) >= 0)
{
if (ai.Flags_FindSignature() && searchMarkerInHandler)

View File

@@ -288,29 +288,27 @@ void CArchivePath::ParseFromPath(const UString &path, EArcNameMode mode)
if (mode == k_ArcNameMode_Add)
return;
if (mode == k_ArcNameMode_Exact)
{
BaseExtension.Empty();
return;
}
int dotPos = Name.ReverseFind_Dot();
if (dotPos < 0)
return;
if ((unsigned)dotPos == Name.Len() - 1)
if (mode != k_ArcNameMode_Exact)
{
Name.DeleteBack();
BaseExtension.Empty();
return;
int dotPos = Name.ReverseFind_Dot();
if (dotPos < 0)
return;
if ((unsigned)dotPos == Name.Len() - 1)
Name.DeleteBack();
else
{
const UString ext = Name.Ptr(dotPos + 1);
if (BaseExtension.IsEqualTo_NoCase(ext))
{
BaseExtension = ext;
Name.DeleteFrom(dotPos);
return;
}
}
}
const UString ext = Name.Ptr(dotPos + 1);
if (BaseExtension.IsEqualTo_NoCase(ext))
{
BaseExtension = ext;
Name.DeleteFrom(dotPos);
}
else
BaseExtension.Empty();
BaseExtension.Empty();
}
UString CArchivePath::GetFinalPath() const
@@ -327,6 +325,7 @@ UString CArchivePath::GetFinalPath() const
UString CArchivePath::GetFinalVolPath() const
{
UString path = GetPathWithoutExt();
// if BaseExtension is empty, we must ignore VolExtension also.
if (!BaseExtension.IsEmpty())
{
path += '.';
@@ -1166,7 +1165,7 @@ HRESULT UpdateArchive(
{
errorInfo.SystemError = ERROR_ACCESS_DENIED;
errorInfo.Message = "The file is read-only";
errorInfo.FileNames.Add(arcPath);
errorInfo.FileNames.Add(us2fs(arcPath));
return errorInfo.Get_HRESULT_Error();
}
@@ -1377,6 +1376,31 @@ HRESULT UpdateArchive(
unsigned ci;
// self including protection
if (options.DeleteAfterCompressing)
{
for (ci = 0; ci < options.Commands.Size(); ci++)
{
CArchivePath &ap = options.Commands[ci].ArchivePath;
const FString path = us2fs(ap.GetFinalPath());
// maybe we must compare absolute paths path here
FOR_VECTOR (i, dirItems.Items)
{
const FString phyPath = dirItems.GetPhyPath(i);
if (phyPath == path)
{
UString s;
s = "It is not allowed to include archive to itself";
s.Add_LF();
s += path;
throw s;
}
}
}
}
for (ci = 0; ci < options.Commands.Size(); ci++)
{
CArchivePath &ap = options.Commands[ci].ArchivePath;
@@ -1562,26 +1586,39 @@ HRESULT UpdateArchive(
}
CCurrentDirRestorer curDirRestorer;
AStringVector paths;
AStringVector names;
for (i = 0; i < fullPaths.Size(); i++)
{
const UString arcPath2 = fs2us(fullPaths[i]);
const UString fileName = ExtractFileNameFromPath(arcPath2);
const AString path (GetAnsiString(arcPath2));
const AString name (GetAnsiString(fileName));
paths.Add(GetAnsiString(arcPath2));
names.Add(GetAnsiString(fileName));
// const AString path (GetAnsiString(arcPath2));
// const AString name (GetAnsiString(fileName));
// Warning!!! MAPISendDocuments function changes Current directory
// fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0);
}
MapiFileDesc f;
CRecordVector<MapiFileDesc> files;
files.ClearAndSetSize(paths.Size());
for (i = 0; i < paths.Size(); i++)
{
MapiFileDesc &f = files[i];
memset(&f, 0, sizeof(f));
f.nPosition = 0xFFFFFFFF;
f.lpszPathName = (char *)(const char *)path;
f.lpszFileName = (char *)(const char *)name;
f.lpszPathName = (char *)(const char *)paths[i];
f.lpszFileName = (char *)(const char *)names[i];
}
{
MapiMessage m;
memset(&m, 0, sizeof(m));
m.nFileCount = 1;
m.lpFiles = &f;
m.nFileCount = files.Size();
m.lpFiles = &files.Front();
const AString addr (GetAnsiString(options.EMailAddress));
MapiRecipDesc rec;

View File

@@ -332,7 +332,7 @@ void CHashCallbackConsole::PrintProperty(const char *name, UInt64 value)
*_so << name << s << endl;
}
HRESULT CHashCallbackConsole::AfterLastFile(const CHashBundle &hb)
HRESULT CHashCallbackConsole::AfterLastFile(CHashBundle &hb)
{
ClosePercents2();

View File

@@ -1072,18 +1072,24 @@ HRESULT ListArchives(CCodecs *codecs,
errorCode = ERROR_FILE_NOT_FOUND;
lastError = HRESULT_FROM_WIN32(lastError);;
g_StdOut.Flush();
*g_ErrStream << endl << kError << NError::MyFormatMessage(errorCode) << endl;
g_ErrStream->NormalizePrint_UString(arcPath);
*g_ErrStream << endl << endl;
if (g_ErrStream)
{
*g_ErrStream << endl << kError << NError::MyFormatMessage(errorCode) << endl;
g_ErrStream->NormalizePrint_UString(arcPath);
*g_ErrStream << endl << endl;
}
numErrors++;
continue;
}
if (fi.IsDir())
{
g_StdOut.Flush();
*g_ErrStream << endl << kError;
g_ErrStream->NormalizePrint_UString(arcPath);
*g_ErrStream << " is not a file" << endl << endl;
if (g_ErrStream)
{
*g_ErrStream << endl << kError;
g_ErrStream->NormalizePrint_UString(arcPath);
*g_ErrStream << " is not a file" << endl << endl;
}
numErrors++;
continue;
}
@@ -1133,24 +1139,28 @@ HRESULT ListArchives(CCodecs *codecs,
{
if (result == E_ABORT)
return result;
g_StdOut.Flush();
*g_ErrStream << endl << kError;
g_ErrStream->NormalizePrint_UString(arcPath);
*g_ErrStream << " : ";
if (result == S_FALSE)
{
Print_OpenArchive_Error(*g_ErrStream, codecs, arcLink);
}
else
{
if (result != S_FALSE)
lastError = result;
*g_ErrStream << "opening : ";
if (result == E_OUTOFMEMORY)
*g_ErrStream << "Can't allocate required memory";
g_StdOut.Flush();
if (g_ErrStream)
{
*g_ErrStream << endl << kError;
g_ErrStream->NormalizePrint_UString(arcPath);
*g_ErrStream << " : ";
if (result == S_FALSE)
{
Print_OpenArchive_Error(*g_ErrStream, codecs, arcLink);
}
else
*g_ErrStream << NError::MyFormatMessage(result);
{
*g_ErrStream << "opening : ";
if (result == E_OUTOFMEMORY)
*g_ErrStream << "Can't allocate required memory";
else
*g_ErrStream << NError::MyFormatMessage(result);
}
*g_ErrStream << endl;
}
*g_ErrStream << endl;
numErrors++;
continue;
}

View File

@@ -24,6 +24,7 @@
#include "../../../Windows/TimeUtils.h"
#include "../Common/ArchiveCommandLine.h"
#include "../Common/Bench.h"
#include "../Common/ExitCode.h"
#include "../Common/Extract.h"
@@ -56,8 +57,6 @@ using namespace NCommandLineParser;
HINSTANCE g_hInstance = 0;
#endif
extern bool g_LargePagesMode;
extern CStdOutStream *g_StdStream;
extern CStdOutStream *g_ErrStream;
@@ -236,7 +235,7 @@ static void PrintWarningsPaths(const CErrorPathCodes &pc, CStdOutStream &so)
{
FOR_VECTOR(i, pc.Paths)
{
so.NormalizePrint_UString(pc.Paths[i]);
so.NormalizePrint_UString(fs2us(pc.Paths[i]));
so << " : ";
so << NError::MyFormatMessage(pc.Codes[i]) << endl;
}
@@ -376,8 +375,13 @@ static void PrintMemUsage(const char *s, UInt64 val)
*g_StdStream << " " << s << " Memory =";
PrintNum(SHIFT_SIZE_VALUE(val, 20), 7);
*g_StdStream << " MB";
if (g_LargePagesMode)
*g_StdStream << " (LP)";
#ifdef _7ZIP_LARGE_PAGES
AString lp;
Add_LargePages_String(lp);
if (!lp.IsEmpty())
*g_StdStream << lp;
#endif
}
EXTERN_C_BEGIN
@@ -911,7 +915,7 @@ int Main2(
{
hashCalc = &hb;
ThrowException_if_Error(hb.SetMethods(EXTERNAL_CODECS_VARS_L options.HashMethods));
hb.Init();
// hb.Init();
}
hresultMain = Extract(

View File

@@ -582,7 +582,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
}
}
const UString &fileName = _fileNames.Front();
// const UString &fileName = _fileNames.Front();
if (needExtract)
{
@@ -639,12 +639,8 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
}
}
UString arcName;
if (_fileNames.Size() == 1)
arcName = CreateArchiveName(fi0, false);
else
arcName = CreateArchiveName(fileName, _fileNames.Size() > 1, false);
const UString arcName = CreateArchiveName(_fileNames, _fileNames.Size() == 1 ? &fi0 : NULL);
UString arcName7z = arcName;
arcName7z += ".7z";
UString arcNameZip = arcName;

View File

@@ -327,7 +327,7 @@ HRESULT OpenArchive(const CSysString &fileName,
}
*/
static HANDLE MyOpenFilePluginW(const wchar_t *name)
static HANDLE MyOpenFilePluginW(const wchar_t *name, bool isAbortCodeSupported)
{
FString normalizedName = us2fs(name);
normalizedName.Trim();
@@ -373,7 +373,12 @@ static HANDLE MyOpenFilePluginW(const wchar_t *name)
archiverInfoResult, defaultName, openArchiveCallback);
*/
if (result == E_ABORT)
return (HANDLE)-2;
{
// fixed 18.06:
// OpenFilePlugin() is allowed to return (HANDLE)-2 as abort code
// OpenPlugin() is not allowed to return (HANDLE)-2.
return isAbortCodeSupported ? (HANDLE)-2 : INVALID_HANDLE_VALUE;
}
UString errorMessage = agent->GetErrorMessage();
if (!errorMessage.IsEmpty())
@@ -403,7 +408,7 @@ static HANDLE MyOpenFilePluginW(const wchar_t *name)
return (HANDLE)(plugin);
}
static HANDLE MyOpenFilePlugin(const char *name)
static HANDLE MyOpenFilePlugin(const char *name, bool isAbortCodeSupported)
{
UINT codePage =
#ifdef UNDER_CE
@@ -411,7 +416,7 @@ static HANDLE MyOpenFilePlugin(const char *name)
#else
::AreFileApisANSI() ? CP_ACP : CP_OEMCP;
#endif
return MyOpenFilePluginW(GetUnicodeString(name, codePage));
return MyOpenFilePluginW(GetUnicodeString(name, codePage), isAbortCodeSupported);
}
EXTERN_C HANDLE WINAPI OpenFilePlugin(char *name, const unsigned char * /* data */, int /* dataSize */)
@@ -423,7 +428,7 @@ EXTERN_C HANDLE WINAPI OpenFilePlugin(char *name, const unsigned char * /* data
// if (!Opt.ProcessShiftF1)
return(INVALID_HANDLE_VALUE);
}
return MyOpenFilePlugin(name);
return MyOpenFilePlugin(name, true); // isAbortCodeSupported
MY_TRY_END2("OpenFilePlugin", INVALID_HANDLE_VALUE);
}
@@ -458,7 +463,7 @@ EXTERN_C HANDLE WINAPI OpenPlugin(int openFrom, INT_PTR item)
fileName.DeleteBack();
fileName.DeleteFrontal(1);
}
return MyOpenFilePlugin(fileName);
return MyOpenFilePlugin(fileName, false); // isAbortCodeSupported
}
if (openFrom == OPEN_PLUGINSMENU)
@@ -470,7 +475,7 @@ EXTERN_C HANDLE WINAPI OpenPlugin(int openFrom, INT_PTR item)
PluginPanelItem pluginPanelItem;
if (!g_StartupInfo.ControlGetActivePanelCurrentItemInfo(pluginPanelItem))
throw 142134;
return MyOpenFilePlugin(pluginPanelItem.FindData.cFileName);
return MyOpenFilePlugin(pluginPanelItem.FindData.cFileName, false); // isAbortCodeSupported
}
case 1:

View File

@@ -468,7 +468,7 @@ static HRESULT UpdateFile(NFsFolder::CCopyStateIO &state, CFSTR inPath, CFSTR ou
{
if (NFind::DoesFileOrDirExist(outPath))
{
RINOK(SendMessageError(callback, NError::MyFormatMessage(ERROR_ALREADY_EXISTS), outPath));
RINOK(SendMessageError(callback, NError::MyFormatMessage(ERROR_ALREADY_EXISTS), FString(outPath)));
CFileInfo fi;
if (fi.Find(inPath))
{

View File

@@ -759,11 +759,15 @@ STDMETHODIMP CExtractCallbackImp::AskWrite(
destPathResultTemp = fs2us(destPathSys);
}
else
{
if (NFind::DoesFileExist(destPathSys))
if (!NDir::DeleteFileAlways(destPathSys))
if (GetLastError() != ERROR_FILE_NOT_FOUND)
{
RINOK(MessageError("can not delete output file", destPathSys));
return E_ABORT;
}
}
}
*writeAnswer = BoolToInt(true);
return StringToBstr(destPathResultTemp, destPathResult);

View File

@@ -213,6 +213,12 @@ void CListViewDialog::ShowItemInfo()
if (index < Values.Size())
dlg.Text = Values[index];
}
#ifdef _WIN32
if (dlg.Text.Find(L'\r') < 0)
dlg.Text.Replace(L"\n", L"\r\n");
#endif
dlg.Create(*this);
}

View File

@@ -879,8 +879,9 @@ void CPanel::AddToArchive()
FOR_VECTOR (i, indices)
names.Add(curPrefix + GetItemRelPath2(indices[i]));
bool fromPrev = (names.Size() > 1);
const UString arcName = CreateArchiveName(names.Front(), fromPrev, false);
const UString arcName = CreateArchiveName(names);
HRESULT res = CompressFiles(destCurDirPrefix, arcName, L"",
true, // addExtension
names, false, true, false);

View File

@@ -29,7 +29,7 @@ public:
CMyComPtr<IFolderOperationsExtractCallback> ExtractCallback;
CHashBundle Hash;
UString FirstFilePath;
// UString FirstFilePath;
HRESULT Result;
@@ -48,7 +48,7 @@ void CPanelCopyThread::ShowFinalResults(HWND hwnd)
if (!ResultsWereShown)
{
ResultsWereShown = true;
ShowHashResults(Hash, fs2us(FirstFilePath), hwnd);
ShowHashResults(Hash, hwnd);
}
}
@@ -100,7 +100,7 @@ HRESULT CPanelCopyThread::ProcessVirt()
else if (options->testMode)
{
CProgressMessageBoxPair &pair = GetMessagePair(false); // GetMessagePair(ExtractCallbackSpec->Hash.NumErrors != 0);
AddHashBundleRes(pair.Message, Hash, FirstFilePath);
AddHashBundleRes(pair.Message, Hash);
}
}
@@ -158,7 +158,10 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
if (indices.Size() == 1)
extracter.FirstFilePath = GetItemRelPath(indices[0]);
{
extracter.Hash.FirstFileName = GetItemRelPath(indices[0]);
extracter.Hash.MainName = extracter.Hash.FirstFileName;
}
if (options.VirtFileSystem)
{
@@ -186,7 +189,7 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
extracter.ExtractCallbackSpec->SetHashCalc(&extracter.Hash);
}
extracter.Hash.Init();
// extracter.Hash.Init();
UString title;
{

View File

@@ -147,7 +147,7 @@ class CThreadCrc: public CProgressThreadVirt
public:
CDirEnumerator Enumerator;
CHashBundle Hash;
FString FirstFilePath;
// FString FirstFilePath;
void SetStatus(const UString &s);
void AddErrorMessage(DWORD systemError, const FChar *name);
@@ -165,7 +165,7 @@ void CThreadCrc::ShowFinalResults(HWND hwnd)
if (!ResultsWereShown)
{
ResultsWereShown = true;
ShowHashResults(Hash, fs2us(FirstFilePath), hwnd);
ShowHashResults(Hash, hwnd);
}
}
@@ -193,7 +193,7 @@ void CThreadCrc::SetStatus(const UString &s2)
HRESULT CThreadCrc::ProcessVirt()
{
Hash.Init();
// Hash.Init();
CMyBuffer buf;
if (!buf.Allocate(kBufSize))
@@ -289,7 +289,7 @@ HRESULT CThreadCrc::ProcessVirt()
}
if (isFirstFile)
{
FirstFilePath = path;
Hash.FirstFileName = path;
isFirstFile = false;
}
sync.Set_FilePath(fs2us(path));
@@ -370,9 +370,13 @@ HRESULT CApp::CalculateCrc2(const UString &methodName)
methods.Add(methodName);
RINOK(t.Hash.SetMethods(EXTERNAL_CODECS_VARS_G methods));
}
FOR_VECTOR (i, indices)
t.Enumerator.FilePaths.Add(us2fs(srcPanel.GetItemRelPath(indices[i])));
if (t.Enumerator.FilePaths.Size() == 1)
t.Hash.MainName = t.Enumerator.FilePaths[0];
UString basePrefix = srcPanel.GetFsPath();
UString basePrefix2 = basePrefix;
if (basePrefix2.Back() == ':')

View File

@@ -940,8 +940,10 @@ void CPanel::CompressDropFiles(const UStringVector &fileNames, const UString &fo
if (IsFolderInTemp(folderPath2F))
folderPath2 = ROOT_FS_FOLDER;
}
const UString archiveName = CreateArchiveName(fileNames.Front(), (fileNames.Size() > 1), false);
CompressFiles(folderPath2, archiveName, L"",
const UString arcName = CreateArchiveName(fileNames);
CompressFiles(folderPath2, arcName, L"",
true, // addExtension
fileNames,
false, // email

View File

@@ -324,7 +324,6 @@ static void PrintSize_MB(UString &s, UInt64 size)
s += kMB;
}
extern bool g_LargePagesMode;
UInt32 CBenchmarkDialog::OnChangeDictionary()
{
@@ -338,8 +337,14 @@ UInt32 CBenchmarkDialog::OnChangeDictionary()
s += " / ";
PrintSize_MB(s, ramSize);
}
if (g_LargePagesMode)
s += " LP";
#ifdef _7ZIP_LARGE_PAGES
{
AString s2;
Add_LargePages_String(s2);
s += s2;
}
#endif
SetItemText(IDT_BENCH_MEMORY_VAL, s);

View File

@@ -99,8 +99,10 @@ HRESULT CThreadExtracting::ProcessVirt()
CDecompressStat Stat;
#ifndef _SFX
/*
if (HashBundle)
HashBundle->Init();
*/
#endif
HRESULT res = Extract(codecs,
@@ -119,7 +121,7 @@ HRESULT CThreadExtracting::ProcessVirt()
{
AddValuePair(Pairs, IDS_ARCHIVES_COLON, Stat.NumArchives);
AddSizeValuePair(Pairs, IDS_PROP_PACKED_SIZE, Stat.PackSize);
AddHashBundleRes(Pairs, *HashBundle, UString());
AddHashBundleRes(Pairs, *HashBundle);
}
else if (Options->TestMode)
{

View File

@@ -27,6 +27,7 @@ class CHashCallbackGUI: public CProgressThreadVirt, public IHashCallbackUI
UInt64 NumFiles;
bool _curIsFolder;
UString FirstFileName;
// UString MainPath;
CPropNameValPairs PropNameValPairs;
@@ -71,9 +72,9 @@ void AddSizeValue(UString &s, UInt64 value)
if (value >= (1 << 10))
{
char c;
if (value >= ((UInt64)10 << 30)) { value >>= 30; c = 'G'; }
if (value >= (10 << 20)) { value >>= 20; c = 'M'; }
else { value >>= 10; c = 'K'; }
if (value >= ((UInt64)10 << 30)) { value >>= 30; c = 'G'; }
else if (value >= (10 << 20)) { value >>= 20; c = 'M'; }
else { value >>= 10; c = 'K'; }
char sz[32];
ConvertUInt64ToString(value, sz);
s += " (";
@@ -192,19 +193,25 @@ static void AddHashResString(CPropNameValPairs &s, const CHasherState &h, unsign
}
void AddHashBundleRes(CPropNameValPairs &s, const CHashBundle &hb, const UString &firstFileName)
void AddHashBundleRes(CPropNameValPairs &s, const CHashBundle &hb)
{
if (hb.NumErrors != 0)
AddValuePair(s, IDS_PROP_NUM_ERRORS, hb.NumErrors);
if (hb.NumFiles == 1 && hb.NumDirs == 0 && !firstFileName.IsEmpty())
if (hb.NumFiles == 1 && hb.NumDirs == 0 && !hb.FirstFileName.IsEmpty())
{
CProperty &pair = s.AddNew();
LangString(IDS_PROP_NAME, pair.Name);
pair.Value = firstFileName;
pair.Value = hb.FirstFileName;
}
else
{
if (!hb.MainName.IsEmpty())
{
CProperty &pair = s.AddNew();
LangString(IDS_PROP_NAME, pair.Name);
pair.Value = hb.MainName;
}
if (hb.NumDirs != 0)
AddValuePair(s, IDS_PROP_FOLDERS, hb.NumDirs);
AddValuePair(s, IDS_PROP_FILES, hb.NumFiles);
@@ -240,10 +247,10 @@ void AddHashBundleRes(CPropNameValPairs &s, const CHashBundle &hb, const UString
}
void AddHashBundleRes(UString &s, const CHashBundle &hb, const UString &firstFileName)
void AddHashBundleRes(UString &s, const CHashBundle &hb)
{
CPropNameValPairs pairs;
AddHashBundleRes(pairs, hb, firstFileName);
AddHashBundleRes(pairs, hb);
FOR_VECTOR (i, pairs)
{
@@ -263,9 +270,11 @@ void AddHashBundleRes(UString &s, const CHashBundle &hb, const UString &firstFil
}
HRESULT CHashCallbackGUI::AfterLastFile(const CHashBundle &hb)
HRESULT CHashCallbackGUI::AfterLastFile(CHashBundle &hb)
{
AddHashBundleRes(PropNameValPairs, hb, FirstFileName);
hb.FirstFileName = FirstFileName;
// MainPath
AddHashBundleRes(PropNameValPairs, hb);
CProgressSync &sync = Sync;
sync.Set_NumFilesCur(hb.NumFiles);
@@ -335,10 +344,10 @@ void ShowHashResults(const CPropNameValPairs &propPairs, HWND hwnd)
}
void ShowHashResults(const CHashBundle &hb, const UString &firstFileName, HWND hwnd)
void ShowHashResults(const CHashBundle &hb, HWND hwnd)
{
CPropNameValPairs propPairs;
AddHashBundleRes(propPairs, hb, firstFileName);
AddHashBundleRes(propPairs, hb);
ShowHashResults(propPairs, hwnd);
}

View File

@@ -18,10 +18,10 @@ void AddValuePair(CPropNameValPairs &pairs, UINT resourceID, UInt64 value);
void AddSizeValue(UString &s, UInt64 value);
void AddSizeValuePair(CPropNameValPairs &pairs, UINT resourceID, UInt64 value);
void AddHashBundleRes(CPropNameValPairs &s, const CHashBundle &hb, const UString &firstFileName);
void AddHashBundleRes(UString &s, const CHashBundle &hb, const UString &firstFileName);
void AddHashBundleRes(CPropNameValPairs &s, const CHashBundle &hb);
void AddHashBundleRes(UString &s, const CHashBundle &hb);
void ShowHashResults(const CPropNameValPairs &propPairs, HWND hwnd);
void ShowHashResults(const CHashBundle &hb, const UString &firstFileName, HWND hwnd);
void ShowHashResults(const CHashBundle &hb, HWND hwnd);
#endif