mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-06 21:14:58 -06:00
18.06
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -55,5 +55,6 @@ C_OBJS = \
|
||||
$O\Threads.obj \
|
||||
|
||||
!include "../../Crc.mak"
|
||||
!include "../../LzmaDec.mak"
|
||||
|
||||
!include "../../7zip.mak"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -189,6 +189,7 @@ class CDecoder:
|
||||
NVm::CVm _vm;
|
||||
CRecordVector<CFilter *> _filters;
|
||||
CRecordVector<CTempFilter *> _tempFilters;
|
||||
unsigned _numEmptyTempFilters;
|
||||
UInt32 _lastFilter;
|
||||
|
||||
bool _isSolid;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
!IF "$(CPU)" == "AMD64"
|
||||
!IF "$(PLATFORM)" == "x64"
|
||||
CFLAGS_C_SPEC = -D_LZMA_DEC_OPT
|
||||
ASM_OBJS = $(ASM_OBJS) \
|
||||
$O\LzmaDecOpt.obj
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
{
|
||||
|
||||
@@ -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() == ':')
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user