diff options
author | 2023-05-04 02:41:16 +1000 | |
---|---|---|
committer | 2023-05-04 02:41:16 +1000 | |
commit | a504bde3a7462b54fafd5cfc2f52e58d0f3218e1 (patch) | |
tree | 8b3108d572b1a0873a6cdbb4e8af1f17179545c3 /3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.cpp | |
parent | befb9bf4a8cfdb2b693a32e32535b5eac522c5d8 (diff) |
3rdparty/lzma: Updated to LZMA SDK version 22.01
Diffstat (limited to '3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.cpp')
-rw-r--r-- | 3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.cpp | 566 |
1 files changed, 360 insertions, 206 deletions
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.cpp index bf3b982e44e..4a91a2686eb 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.cpp @@ -14,6 +14,7 @@ #include "../../../Common/IntToString.h" #include "../../../Common/StringConvert.h" #include "../../../Common/StringToInt.h" +#include "../../../Common/UTFConvert.h" #include "../../../Common/Wildcard.h" #include "../../../Windows/FileDir.h" @@ -32,11 +33,13 @@ #include "SetProperties.h" #endif +#ifndef _SFX #ifdef SHOW_DEBUG_INFO #define PRF(x) x #else #define PRF(x) #endif +#endif // increase it, if you need to support larger SFX stubs static const UInt64 kMaxCheckStartPosition = 1 << 23; @@ -64,7 +67,7 @@ Open: - open FAIL: Try to open with all other types from offset 0 only. If some open type is OK and physical archive size is uequal or larger - than file size, then return that archive with warning that can not be open as [extension type]. + than file size, then return that archive with warning that cannot be open as [extension type]. If extension was EXE, it will try to open as unknown_extension case - file has unknown extension (like a.hhh) It tries to open via parser code. @@ -141,14 +144,14 @@ struct CParseItem bool LenIsUnknown; CParseItem(): - LenIsUnknown(false), + // OkSize(0), FileTime_Defined(false), UnpackSize_Defined(false), - NumSubFiles_Defined(false), NumSubDirs_Defined(false), + NumSubFiles_Defined(false), IsSelfExe(false), - IsNotArcType(false) - // OkSize(0) + IsNotArcType(false), + LenIsUnknown(false) {} /* @@ -206,23 +209,25 @@ int CHandler::FindInsertPos(const CParseItem &item) const unsigned left = 0, right = _items.Size(); while (left != right) { - unsigned mid = (left + right) / 2; - const CParseItem & midItem = _items[mid]; + const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); + const CParseItem &midItem = _items[mid]; if (item.Offset < midItem.Offset) right = mid; else if (item.Offset > midItem.Offset) left = mid + 1; else if (item.Size < midItem.Size) right = mid; + /* else if (item.Size > midItem.Size) left = mid + 1; + */ else { left = mid + 1; // return -1; } } - return left; + return (int)left; } void CHandler::AddUnknownItem(UInt64 next) @@ -257,10 +262,10 @@ void CHandler::AddUnknownItem(UInt64 next) void CHandler::AddItem(const CParseItem &item) { AddUnknownItem(item.Offset); - int pos = FindInsertPos(item); - if (pos >= 0) + const int pos = FindInsertPos(item); + if (pos != -1) { - _items.Insert(pos, item); + _items.Insert((unsigned)pos, item); UInt64 next = item.Offset + item.Size; if (_maxEndOffset < next) _maxEndOffset = next; @@ -330,17 +335,17 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val { case kpidPath: { - wchar_t sz[32]; + char sz[32]; ConvertUInt32ToString(index + 1, sz); - UString s = sz; + UString s(sz); if (!item.Name.IsEmpty()) { - s += L'.'; + s += '.'; s += item.Name; } if (!item.Extension.IsEmpty()) { - s += L'.'; + s += '.'; s += item.Extension; } prop = s; break; @@ -401,7 +406,7 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems, Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - Int32 index = allFilesMode ? i : indices[i]; + UInt32 index = allFilesMode ? i : indices[i]; const CParseItem &item = _items[index]; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); @@ -417,7 +422,7 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems, outStreamSpec->Init(skipMode ? 0 : unpackSize, true); Int32 opRes = NExtract::NOperationResult::kOK; - RINOK(_stream->Seek(item.Offset, STREAM_SEEK_SET, NULL)); + RINOK(_stream->Seek((Int64)item.Offset, STREAM_SEEK_SET, NULL)); streamSpec->Init(unpackSize); RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); @@ -477,7 +482,7 @@ HRESULT Archive_IsItem_Deleted(IInArchive *arc, UInt32 index, bool &result) thro return Archive_GetItemBoolProp(arc, index, kpidIsDeleted, result); } -static HRESULT Archive_GetArcBoolProp(IInArchive *arc, PROPID propid, bool &result) throw() +static HRESULT Archive_GetArcProp_Bool(IInArchive *arc, PROPID propid, bool &result) throw() { NCOM::CPropVariant prop; result = false; @@ -496,13 +501,14 @@ static HRESULT Archive_GetArcProp_UInt(IInArchive *arc, PROPID propid, UInt64 &r RINOK(arc->GetArchiveProperty(propid, &prop)); switch (prop.vt) { - case VT_UI4: result = prop.ulVal; defined = true; break; - case VT_I4: result = (Int64)prop.lVal; defined = true; break; - case VT_UI8: result = (UInt64)prop.uhVal.QuadPart; defined = true; break; - case VT_I8: result = (UInt64)prop.hVal.QuadPart; defined = true; break; - case VT_EMPTY: break; + case VT_UI4: result = prop.ulVal; break; + case VT_I4: result = (UInt64)(Int64)prop.lVal; break; + case VT_UI8: result = (UInt64)prop.uhVal.QuadPart; break; + case VT_I8: result = (UInt64)prop.hVal.QuadPart; break; + case VT_EMPTY: return S_OK; default: return E_FAIL; } + defined = true; return S_OK; } @@ -513,19 +519,20 @@ static HRESULT Archive_GetArcProp_Int(IInArchive *arc, PROPID propid, Int64 &res RINOK(arc->GetArchiveProperty(propid, &prop)); switch (prop.vt) { - case VT_UI4: result = prop.ulVal; defined = true; break; - case VT_I4: result = prop.lVal; defined = true; break; - case VT_UI8: result = (Int64)prop.uhVal.QuadPart; defined = true; break; - case VT_I8: result = (Int64)prop.hVal.QuadPart; defined = true; break; - case VT_EMPTY: break; + case VT_UI4: result = prop.ulVal; break; + case VT_I4: result = prop.lVal; break; + case VT_UI8: result = (Int64)prop.uhVal.QuadPart; break; + case VT_I8: result = (Int64)prop.hVal.QuadPart; break; + case VT_EMPTY: return S_OK; default: return E_FAIL; } + defined = true; return S_OK; } #ifndef _SFX -HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const +HRESULT CArc::GetItem_PathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const { if (!GetRawProps) return E_FAIL; @@ -563,6 +570,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 +585,7 @@ HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &pa s.DeleteFrom(pos); } } + */ parts.Insert(0, s); @@ -583,7 +593,7 @@ HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &pa { { UString &s2 = parts[parts.Size() - 2]; - s2 += L':'; + s2 += ':'; s2 += parts.Back(); } parts.DeleteBack(); @@ -604,7 +614,9 @@ HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &pa #endif -HRESULT CArc::GetItemPath(UInt32 index, UString &result) const + + +HRESULT CArc::GetItem_Path(UInt32 index, UString &result) const { #ifdef MY_CPU_LE if (GetRawProps) @@ -618,19 +630,42 @@ HRESULT CArc::GetItemPath(UInt32 index, UString &result) const propType == NPropDataType::kUtf16z) { unsigned len = size / 2 - 1; + // (len) doesn't include null terminator + + /* + #if WCHAR_MAX > 0xffff + len = (unsigned)Utf16LE__Get_Num_WCHARs(p, len); + + wchar_t *s = result.GetBuf(len); + wchar_t *sEnd = Utf16LE__To_WCHARs_Sep(p, len, s); + if (s + len != sEnd) return E_FAIL; + *sEnd = 0; + + #else + */ + wchar_t *s = result.GetBuf(len); for (unsigned i = 0; i < len; i++) { wchar_t c = GetUi16(p); p = (const void *)((const Byte *)p + 2); + #if WCHAR_PATH_SEPARATOR != L'/' if (c == L'/') c = WCHAR_PATH_SEPARATOR; + else if (c == L'\\') + c = WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT; // WSL scheme #endif + *s++ = c; } *s = 0; + + // #endif + result.ReleaseBuf_SetLen(len); + + Convert_UnicodeEsc16_To_UnicodeEscHigh(result); if (len != 0) return S_OK; } @@ -717,11 +752,13 @@ HRESULT CArc::GetItemPath(UInt32 index, UString &result) const } if (result.IsEmpty()) - return GetDefaultItemPath(index, result); + return GetItem_DefaultPath(index, result); + + Convert_UnicodeEsc16_To_UnicodeEscHigh(result); return S_OK; } -HRESULT CArc::GetDefaultItemPath(UInt32 index, UString &result) const +HRESULT CArc::GetItem_DefaultPath(UInt32 index, UString &result) const { result.Empty(); bool isDir; @@ -733,7 +770,7 @@ HRESULT CArc::GetDefaultItemPath(UInt32 index, UString &result) const RINOK(Archive->GetProperty(index, kpidExtension, &prop)); if (prop.vt == VT_BSTR) { - result += L'.'; + result += '.'; result += prop.bstrVal; } else if (prop.vt != VT_EMPTY) @@ -742,9 +779,9 @@ HRESULT CArc::GetDefaultItemPath(UInt32 index, UString &result) const return S_OK; } -HRESULT CArc::GetItemPath2(UInt32 index, UString &result) const +HRESULT CArc::GetItem_Path2(UInt32 index, UString &result) const { - RINOK(GetItemPath(index, result)); + RINOK(GetItem_Path(index, result)); if (Ask_Deleted) { bool isDeleted = false; @@ -769,7 +806,7 @@ int FindAltStreamColon_in_Path(const wchar_t *path) if (c == ':') { if (colonPos < 0) - colonPos = i; + colonPos = (int)i; continue; } if (c == WCHAR_PATH_SEPARATOR) @@ -796,7 +833,7 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const RINOK(Archive_IsItem_Dir(Archive, index, item.IsDir)); item.MainIsDir = item.IsDir; - RINOK(GetItemPath2(index, item.Path)); + RINOK(GetItem_Path2(index, item.Path)); #ifndef _SFX UInt32 mainIndex = index; @@ -848,7 +885,7 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const } else { - RINOK(GetItemPath2(parentIndex, item.MainPath)); + RINOK(GetItem_Path2(parentIndex, item.MainPath)); RINOK(Archive_IsItem_Dir(Archive, parentIndex, item.MainIsDir)); } } @@ -857,13 +894,13 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const if (item.WriteToAltStreamIfColon || needFindAltStream) { - /* Good handler must support GetRawProps::GetParent for alt streams./ + /* Good handler must support GetRawProps::GetParent for alt streams. So the following code currently is not used */ int colon = FindAltStreamColon_in_Path(item.Path); if (colon >= 0) { - item.MainPath.DeleteFrom(colon); - item.AltStreamName = item.Path.Ptr(colon + 1); + item.MainPath.DeleteFrom((unsigned)colon); + item.AltStreamName = item.Path.Ptr((unsigned)(colon + 1)); item.MainIsDir = (colon == 0 || IsPathSepar(item.Path[(unsigned)colon - 1])); item.IsAltStream = true; } @@ -874,7 +911,7 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const #ifndef _SFX if (item._use_baseParentFolder_mode) { - RINOK(GetItemPathToParent(mainIndex, item._baseParentFolder, item.PathParts)); + RINOK(GetItem_PathToParent(mainIndex, (unsigned)item._baseParentFolder, item.PathParts)); #ifdef SUPPORT_ALT_STREAMS if ((item.WriteToAltStreamIfColon || needFindAltStream) && !item.PathParts.IsEmpty()) @@ -885,10 +922,10 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const colon = FindAltStreamColon_in_Path(s); if (colon >= 0) { - item.AltStreamName = s.Ptr(colon + 1); + item.AltStreamName = s.Ptr((unsigned)(colon + 1)); item.MainIsDir = (colon == 0 || IsPathSepar(s[(unsigned)colon - 1])); item.IsAltStream = true; - s.DeleteFrom(colon); + s.DeleteFrom((unsigned)colon); } } if (colon == 0) @@ -933,7 +970,7 @@ static HRESULT Archive_GetItem_Size(IInArchive *archive, UInt32 index, UInt64 &s #endif -HRESULT CArc::GetItemSize(UInt32 index, UInt64 &size, bool &defined) const +HRESULT CArc::GetItem_Size(UInt32 index, UInt64 &size, bool &defined) const { NCOM::CPropVariant prop; defined = false; @@ -952,24 +989,52 @@ HRESULT CArc::GetItemSize(UInt32 index, UInt64 &size, bool &defined) const return S_OK; } -HRESULT CArc::GetItemMTime(UInt32 index, FILETIME &ft, bool &defined) const +HRESULT CArc::GetItem_MTime(UInt32 index, CArcTime &at) const { + at.Clear(); NCOM::CPropVariant prop; - defined = false; - ft.dwHighDateTime = ft.dwLowDateTime = 0; RINOK(Archive->GetProperty(index, kpidMTime, &prop)); + if (prop.vt == VT_FILETIME) { - ft = prop.filetime; - defined = true; + /* + // for debug + if (FILETIME_IsZero(prop.at) && MTime.Def) + { + at = MTime; + return S_OK; + } + */ + at.Set_From_Prop(prop); + if (at.Prec == 0) + { + // (at.Prec == 0) before version 22. + // so kpidTimeType is required for that code + prop.Clear(); + RINOK(Archive->GetProperty(index, kpidTimeType, &prop)); + if (prop.vt == VT_UI4) + { + UInt32 val = prop.ulVal; + if (val == NFileTimeType::kWindows) + val = k_PropVar_TimePrec_100ns; + /* + else if (val > k_PropVar_TimePrec_1ns) + { + val = k_PropVar_TimePrec_100ns; + // val = k_PropVar_TimePrec_1ns; + // return E_FAIL; // for debug + } + */ + at.Prec = (UInt16)val; + } + } + return S_OK; } - else if (prop.vt != VT_EMPTY) + + if (prop.vt != VT_EMPTY) return E_FAIL; - else if (MTimeDefined) - { - ft = MTime; - defined = true; - } + if (MTime.Def) + at = MTime; return S_OK; } @@ -983,52 +1048,52 @@ static inline bool TestSignature(const Byte *p1, const Byte *p2, size_t size) return true; } + static void MakeCheckOrder(CCodecs *codecs, CIntVector &orderIndices, unsigned numTypes, CIntVector &orderIndices2, const Byte *data, size_t dataSize) { for (unsigned i = 0; i < numTypes; i++) { - int index = orderIndices[i]; + const int index = orderIndices[i]; if (index < 0) continue; - const CArcInfoEx &ai = codecs->Formats[index]; - if (ai.SignatureOffset != 0) - { - orderIndices2.Add(index); - orderIndices[i] = -1; - continue; - } - - const CObjectVector<CByteBuffer> &sigs = ai.Signatures; - FOR_VECTOR (k, sigs) + const CArcInfoEx &ai = codecs->Formats[(unsigned)index]; + if (ai.SignatureOffset == 0) { - const CByteBuffer &sig = sigs[k]; - if (sig.Size() == 0 && dataSize == 0 || - sig.Size() != 0 && sig.Size() <= dataSize && - TestSignature(data, sig, sig.Size())) + if (ai.Signatures.IsEmpty()) { - orderIndices2.Add(index); - orderIndices[i] = -1; - break; + if (dataSize != 0) // 21.04: no Signature means Empty Signature + continue; + } + else + { + unsigned k; + const CObjectVector<CByteBuffer> &sigs = ai.Signatures; + for (k = 0; k < sigs.Size(); k++) + { + const CByteBuffer &sig = sigs[k]; + if (sig.Size() <= dataSize && TestSignature(data, sig, sig.Size())) + break; + } + if (k == sigs.Size()) + continue; } } + orderIndices2.Add(index); + orderIndices[i] = -1; } } -#endif - #ifdef UNDER_CE static const unsigned kNumHashBytes = 1; - #define HASH_VAL(buf, pos) ((buf)[pos]) + #define HASH_VAL(buf) ((buf)[0]) #else static const unsigned kNumHashBytes = 2; - #define HASH_VAL(buf, pos) ((buf)[pos] | ((UInt32)(buf)[pos + 1] << 8)) + // #define HASH_VAL(buf) ((buf)[0] | ((UInt32)(buf)[1] << 8)) + #define HASH_VAL(buf) GetUi16(buf) #endif - -#ifndef _SFX - static bool IsExeExt(const UString &ext) { return ext.IsEqualTo_Ascii_NoCase("exe"); @@ -1193,7 +1258,7 @@ void CArcErrorInfo::ClearErrors() HRESULT CArc::ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openRes) { // OkPhySize_Defined = false; - PhySizeDefined = false; + PhySize_Defined = false; PhySize = 0; Offset = 0; AvailPhySize = FileSize - startPos; @@ -1226,12 +1291,12 @@ HRESULT CArc::ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openR if (openRes == S_OK || ErrorInfo.IsArc_After_NonOpen()) { - RINOK(Archive_GetArcProp_UInt(archive, kpidPhySize, PhySize, PhySizeDefined)); + RINOK(Archive_GetArcProp_UInt(archive, kpidPhySize, PhySize, PhySize_Defined)); /* RINOK(Archive_GetArcProp_UInt(archive, kpidOkPhySize, OkPhySize, OkPhySize_Defined)); if (!OkPhySize_Defined) { - OkPhySize_Defined = PhySizeDefined; + OkPhySize_Defined = PhySize_Defined; OkPhySize = PhySize; } */ @@ -1239,11 +1304,11 @@ HRESULT CArc::ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openR bool offsetDefined; RINOK(Archive_GetArcProp_Int(archive, kpidOffset, Offset, offsetDefined)); - Int64 globalOffset = startPos + Offset; - AvailPhySize = FileSize - globalOffset; - if (PhySizeDefined) + Int64 globalOffset = (Int64)startPos + Offset; + AvailPhySize = (UInt64)((Int64)FileSize - globalOffset); + if (PhySize_Defined) { - UInt64 endPos = globalOffset + PhySize; + UInt64 endPos = (UInt64)(globalOffset + (Int64)PhySize); if (endPos < FileSize) { AvailPhySize = PhySize; @@ -1259,11 +1324,12 @@ HRESULT CArc::ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openR } /* -static PrintNumber(const char *s, int n) +static void PrintNumber(const char *s, int n) { char temp[100]; sprintf(temp, "%s %d", s, n); - OutputDebugStringA(temp); + // OutputDebugStringA(temp); + printf(temp); } */ @@ -1282,7 +1348,7 @@ HRESULT CArc::PrepareToOpen(const COpenOptions &op, unsigned formatIndex, CMyCom { const CArcInfoEx &ai = op.codecs->Formats[formatIndex]; if (ai.LibIndex >= 0 ? - !op.codecs->Libs[ai.LibIndex].SetCodecs : + !op.codecs->Libs[(unsigned)ai.LibIndex].SetCodecs : !op.codecs->Libs.IsEmpty()) { CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo; @@ -1341,9 +1407,9 @@ static HRESULT ReadParseItemProps(IInArchive *archive, const CArcInfoEx &ai, NAr pi.FileTime_Defined = false; pi.ArcType = ai.Name; - RINOK(Archive_GetArcBoolProp(archive, kpidIsNotArcType, pi.IsNotArcType)); + RINOK(Archive_GetArcProp_Bool(archive, kpidIsNotArcType, pi.IsNotArcType)); - // RINOK(Archive_GetArcBoolProp(archive, kpidIsSelfExe, pi.IsSelfExe)); + // RINOK(Archive_GetArcProp_Bool(archive, kpidIsSelfExe, pi.IsSelfExe)); pi.IsSelfExe = ai.Flags_PreArc(); { @@ -1433,7 +1499,7 @@ HRESULT CArc::CheckZerosTail(const COpenOptions &op, UInt64 offset) { if (!op.stream) return S_OK; - RINOK(op.stream->Seek(offset, STREAM_SEEK_SET, NULL)); + RINOK(op.stream->Seek((Int64)offset, STREAM_SEEK_SET, NULL)); const UInt32 kBufSize = 1 << 11; Byte buf[kBufSize]; @@ -1459,6 +1525,8 @@ HRESULT CArc::CheckZerosTail(const COpenOptions &op, UInt64 offset) } } + + #ifndef _SFX class CExtractCallback_To_OpenCallback: @@ -1506,7 +1574,7 @@ STDMETHODIMP CExtractCallback_To_OpenCallback::SetRatioInfo(const UInt64 *inSize STDMETHODIMP CExtractCallback_To_OpenCallback::GetStream(UInt32 /* index */, ISequentialOutStream **outStream, Int32 /* askExtractMode */) { - *outStream = 0; + *outStream = NULL; return S_OK; } @@ -1520,6 +1588,7 @@ STDMETHODIMP CExtractCallback_To_OpenCallback::SetOperationResult(Int32 /* opera return S_OK; } + static HRESULT OpenArchiveSpec(IInArchive *archive, bool needPhySize, IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback, @@ -1543,22 +1612,32 @@ static HRESULT OpenArchiveSpec(IInArchive *archive, bool needPhySize, if (phySize_Defined) return S_OK; - bool phySizeCantBeDetected = false;; - RINOK(Archive_GetArcBoolProp(archive, kpidPhySizeCantBeDetected, phySizeCantBeDetected)); + bool phySizeCantBeDetected = false; + RINOK(Archive_GetArcProp_Bool(archive, kpidPhySizeCantBeDetected, phySizeCantBeDetected)); if (!phySizeCantBeDetected) { - RINOK(archive->Extract(0, (UInt32)(Int32)-1, BoolToInt(true), extractCallback)); + PRF(printf("\n-- !phySize_Defined after Open, call archive->Extract()")); + // It's for bzip2/gz and some xz archives, where Open operation doesn't know phySize. + // But the Handler will know phySize after full archive testing. + RINOK(archive->Extract(NULL, (UInt32)(Int32)-1, BoolToInt(true), extractCallback)); + PRF(printf("\n-- OK")); } } return S_OK; } + + static int FindFormatForArchiveType(CCodecs *codecs, CIntVector orderIndices, const char *name) { FOR_VECTOR (i, orderIndices) - if (StringsAreEqualNoCase_Ascii(codecs->Formats[orderIndices[i]].Name, name)) - return i; + { + int oi = orderIndices[i]; + if (oi >= 0) + if (StringsAreEqualNoCase_Ascii(codecs->Formats[(unsigned)oi].Name, name)) + return (int)i; + } return -1; } @@ -1586,7 +1665,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) { int dotPos = fileName.ReverseFind_Dot(); if (dotPos >= 0) - extension = fileName.Ptr(dotPos + 1); + extension = fileName.Ptr((unsigned)(dotPos + 1)); } CIntVector orderIndices; @@ -1611,13 +1690,18 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) bool isUnknownExt = false; #endif + #ifndef _SFX bool isForced = false; + #endif + unsigned numMainTypes = 0; int formatIndex = op.openType.FormatIndex; if (formatIndex >= 0) { + #ifndef _SFX isForced = true; + #endif orderIndices.Add(formatIndex); numMainTypes = 1; isMainFormatArr[(unsigned)formatIndex] = true; @@ -1654,10 +1738,12 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) isNumber = true; } if (isNumber) + { if (c == 'z' || c == 'Z') isZip = true; else isRar = true; + } } #endif @@ -1667,9 +1753,9 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) const CArcInfoEx &ai = op.codecs->Formats[i]; if (IgnoreSplit || !op.openType.CanReturnArc) - if (ai.IsSplit()) + if (ai.Is_Split()) continue; - if (op.excludedFormats->FindInSorted(i) >= 0) + if (op.excludedFormats->FindInSorted((int)i) >= 0) continue; #ifndef _SFX @@ -1679,17 +1765,17 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) if (ai.FindExtension(extension) >= 0 #ifndef _SFX - || isZip && StringsAreEqualNoCase_Ascii(ai.Name, "zip") - || isRar && StringsAreEqualNoCase_Ascii(ai.Name, "rar") + || (isZip && ai.Is_Zip()) + || (isRar && ai.Is_Rar()) #endif ) { // PrintNumber("orderIndices.Insert", i); - orderIndices.Insert(numFinded++, i); + orderIndices.Insert(numFinded++, (int)i); isMainFormatArr[i] = true; } else - orderIndices.Add(i); + orderIndices.Add((int)i); } } @@ -1735,8 +1821,8 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) const Byte kRarHeader[] = { 0x52 , 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00 }; if (TestSignature(buf, kRarHeader, 7) && buf[9] == 0x73 && (buf[10] & 1) != 0) { - orderIndices2.Add(orderIndices[i]); - orderIndices[i] = -1; + orderIndices2.Add(orderIndices[(unsigned)i]); + orderIndices[(unsigned)i] = -1; if (i >= (int)numFinded) numFinded++; } @@ -1754,11 +1840,27 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) /* check type order: - 1) matched extension, no signuature - 2) matched extension, matched signuature + 0) matched_extension && Backward + 1) matched_extension && (no_signuature || SignatureOffset != 0) + 2) matched_extension && (matched_signature) // 3) no signuature // 4) matched signuature */ + // we move index from orderIndices to orderIndices2 for priority handlers. + + for (unsigned i = 0; i < numFinded; i++) + { + const int index = orderIndices[i]; + if (index < 0) + continue; + const CArcInfoEx &ai = op.codecs->Formats[(unsigned)index]; + if (ai.Flags_BackwardOpen()) + { + // backward doesn't need start signatures + orderIndices2.Add(index); + orderIndices[i] = -1; + } + } MakeCheckOrder(op.codecs, orderIndices, numFinded, orderIndices2, NULL, 0); MakeCheckOrder(op.codecs, orderIndices, numFinded, orderIndices2, byteBuffer, processedSize); @@ -1781,10 +1883,10 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) int iUdf = FindFormatForArchiveType(op.codecs, orderIndices, "udf"); if (iUdf > iIso && iIso >= 0) { - int isoIndex = orderIndices[iIso]; - int udfIndex = orderIndices[iUdf]; - orderIndices[iUdf] = isoIndex; - orderIndices[iIso] = udfIndex; + int isoIndex = orderIndices[(unsigned)iIso]; + int udfIndex = orderIndices[(unsigned)iUdf]; + orderIndices[(unsigned)iUdf] = isoIndex; + orderIndices[(unsigned)iIso] = udfIndex; } } @@ -1838,15 +1940,18 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) for (unsigned i = 0; i < numCheckTypes; i++) { FormatIndex = orderIndices[i]; + + // orderIndices[] item cannot be negative here bool exactOnly = false; #ifndef _SFX - const CArcInfoEx &ai = op.codecs->Formats[FormatIndex]; + const CArcInfoEx &ai = op.codecs->Formats[(unsigned)FormatIndex]; // OutputDebugStringW(ai.Name); if (i >= numMainTypes) { + // here we allow mismatched extension only for backward handlers if (!ai.Flags_BackwardOpen() // && !ai.Flags_PureStartOpen() ) @@ -1867,7 +1972,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) CMyComPtr<IInArchive> archive; - RINOK(PrepareToOpen(op, FormatIndex, archive)); + RINOK(PrepareToOpen(op, (unsigned)FormatIndex, archive)); if (!archive) continue; @@ -1944,7 +2049,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) bool thereIsTail = ErrorInfo.ThereIsTail; if (thereIsTail && mode.ZerosTailIsAllowed) { - RINOK(CheckZerosTail(op, Offset + PhySize)); + RINOK(CheckZerosTail(op, (UInt64)(Offset + (Int64)PhySize))); if (ErrorInfo.IgnoreTail) thereIsTail = false; } @@ -2012,7 +2117,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) @@ -2059,16 +2164,22 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) for (i = 0; i < orderIndices.Size(); i++) { - unsigned form = orderIndices[i]; + // orderIndices[] item cannot be negative here + unsigned form = (unsigned)orderIndices[i]; if (skipFrontalFormat[form]) continue; + const CArcInfoEx &ai = op.codecs->Formats[form]; - if (ai.IsSplit()) + + if (ai.Is_Split()) { - splitIndex = form; + splitIndex = (int)form; continue; } + if (ai.Flags_ByExtOnlyOpen()) + continue; + if (ai.IsArcFunc) { UInt32 isArcRes = ai.IsArcFunc(byteBuffer, processedSize); @@ -2081,7 +2192,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) continue; } - bool isNewStyleSignature = IsNewStyleSignature(ai); + const bool isNewStyleSignature = IsNewStyleSignature(ai); bool needCheck = !isNewStyleSignature || ai.Signatures.IsEmpty() || ai.Flags_PureStartOpen() @@ -2094,13 +2205,12 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) for (k = 0; k < ai.Signatures.Size(); k++) { const CByteBuffer &sig = ai.Signatures[k]; - UInt32 signatureEnd = ai.SignatureOffset + (UInt32)sig.Size(); - if (processedSize < signatureEnd) + if (processedSize < ai.SignatureOffset + sig.Size()) { if (!endOfFile) needCheck = true; } - else if (memcmp(sig, byteBuffer + ai.SignatureOffset, sig.Size()) == 0) + else if (TestSignature(sig, byteBuffer + ai.SignatureOffset, sig.Size())) break; } if (k != ai.Signatures.Size()) @@ -2114,12 +2224,12 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) } if (splitIndex >= 0) - sortedFormats.Insert(0, splitIndex); + sortedFormats.Insert(0, (unsigned)splitIndex); for (i = 0; i < sortedFormats.Size(); i++) { - FormatIndex = sortedFormats[i]; - const CArcInfoEx &ai = op.codecs->Formats[FormatIndex]; + FormatIndex = (int)sortedFormats[i]; + const CArcInfoEx &ai = op.codecs->Formats[(unsigned)FormatIndex]; if (op.callback) RINOK(op.callback->SetTotal(NULL, &fileSize)); @@ -2127,7 +2237,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL)); CMyComPtr<IInArchive> archive; - RINOK(PrepareToOpen(op, FormatIndex, archive)); + RINOK(PrepareToOpen(op, (unsigned)FormatIndex, archive)); if (!archive) continue; @@ -2140,7 +2250,10 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) result = archive->Open(op.stream, &searchLimit, op.callback); else */ - result = OpenArchiveSpec(archive, !mode.CanReturnArc, op.stream, &searchLimit, op.callback, extractCallback_To_OpenCallback); + // if (!CanReturnArc), it's ParserMode, and we need phy size + result = OpenArchiveSpec(archive, + !mode.CanReturnArc, // needPhySize + op.stream, &searchLimit, op.callback, extractCallback_To_OpenCallback); } if (result == S_FALSE) @@ -2162,12 +2275,12 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) } NArchive::NParser::CParseItem pi; - pi.Offset = Offset; + pi.Offset = (UInt64)Offset; pi.Size = AvailPhySize; // bool needScan = false; - if (!PhySizeDefined) + if (!PhySize_Defined) { // it's for Z format pi.LenIsUnknown = true; @@ -2199,7 +2312,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) { if (mode.ZerosTailIsAllowed) { - RINOK(CheckZerosTail(op, Offset + PhySize)); + RINOK(CheckZerosTail(op, (UInt64)(Offset + (Int64)PhySize))); if (ErrorInfo.IgnoreTail) openCur = true; } @@ -2294,7 +2407,9 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) int index = orderIndices[i]; if (index < 0) continue; - const CArcInfoEx &ai = op.codecs->Formats[index]; + const CArcInfoEx &ai = op.codecs->Formats[(unsigned)index]; + if (ai.Flags_ByExtOnlyOpen()) + continue; bool isDifficult = false; // if (ai.Version < 0x91F) // we don't use parser with old DLL (before 9.31) if (!ai.NewInterface) @@ -2317,7 +2432,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) continue; } thereAreHandlersForSearch = true; - UInt32 v = HASH_VAL(sig, 0); + UInt32 v = HASH_VAL(sig); unsigned sigIndex = arc2sig[(unsigned)index] + k; prevs[sigIndex] = hash[v]; hash[v] = (Byte)sigIndex; @@ -2325,8 +2440,8 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) } if (isDifficult) { - difficultFormats.Add(index); - difficultBools[index] = true; + difficultFormats.Add((unsigned)index); + difficultBools[(unsigned)index] = true; } } @@ -2394,7 +2509,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) size_t processedSize = kBufSize - bytesInBuf; // printf("\nRead ask = %d", (unsigned)processedSize); UInt64 seekPos = bufPhyPos + bytesInBuf; - RINOK(op.stream->Seek(bufPhyPos + bytesInBuf, STREAM_SEEK_SET, NULL)); + RINOK(op.stream->Seek((Int64)(bufPhyPos + bytesInBuf), STREAM_SEEK_SET, NULL)); RINOK(ReadStream(op.stream, byteBuffer + bytesInBuf, &processedSize)); // printf(" processed = %d", (unsigned)processedSize); if (processedSize == 0) @@ -2440,6 +2555,9 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) } } + if (bytesInBuf <= (size_t)posInBuf) + break; + bool useOffsetCallback = false; if (openCallback_Offset) { @@ -2464,7 +2582,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) } } - size_t availSize = bytesInBuf - (size_t)posInBuf; + const size_t availSize = bytesInBuf - (size_t)posInBuf; if (availSize < kNumHashBytes) break; size_t scanSize = availSize - @@ -2489,17 +2607,19 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) scanSize++; const Byte *buf = byteBuffer + (size_t)posInBuf; + const Byte *bufLimit = buf + scanSize; size_t ppp = 0; if (!needCheckStartOpen) { - for (; ppp < scanSize && hash[HASH_VAL(buf, ppp)] == 0xFF; ppp++); + for (; buf < bufLimit && hash[HASH_VAL(buf)] == 0xFF; buf++); + ppp = (size_t)(buf - (byteBuffer + (size_t)posInBuf)); pos += ppp; - if (ppp == scanSize) + if (buf == bufLimit) continue; } - UInt32 v = HASH_VAL(buf, ppp); + UInt32 v = HASH_VAL(buf); bool nextNeedCheckStartOpen = true; unsigned i = hash[v]; unsigned indexOfDifficult = 0; @@ -2539,7 +2659,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) const CByteBuffer &sig = ai.Signatures[sigIndex]; if (ppp + sig.Size() > availSize - || !TestSignature(buf + ppp, sig, sig.Size())) + || !TestSignature(buf, sig, sig.Size())) continue; // printf("\nSignature OK: %10S %8x %5d", (const wchar_t *)ai.Name, (int)pos, (int)(pos - prevPos)); // prevPos = pos; @@ -2590,13 +2710,9 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) // printf("\nIsArc OK: %S", (const wchar_t *)ai.Name); } - /* - if (pos == 67109888) - pos = pos; - */ PRF(printf("\npos = %9I64d : %S", pos, (const wchar_t *)ai.Name)); - bool isMainFormat = isMainFormatArr[index]; + const bool isMainFormat = isMainFormatArr[index]; const COpenSpecFlags &specFlags = mode.GetSpec(isForced, isMainFormat, isUnknownExt); CMyComPtr<IInArchive> archive; @@ -2606,14 +2722,14 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) // OutputDebugStringW(ai.Name); - UInt64 rem = fileSize - startArcPos; + const UInt64 rem = fileSize - startArcPos; UInt64 arcStreamOffset = 0; if (ai.Flags_UseGlobalOffset()) { limitedStreamSpec->InitAndSeek(0, fileSize); - limitedStream->Seek(startArcPos, STREAM_SEEK_SET, NULL); + limitedStream->Seek((Int64)startArcPos, STREAM_SEEK_SET, NULL); } else { @@ -2633,31 +2749,40 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) extractCallback_To_OpenCallback_Spec->Files = 0; extractCallback_To_OpenCallback_Spec->Offset = startArcPos; - HRESULT result = OpenArchiveSpec(archive, true, limitedStream, &maxCheckStartPosition, + HRESULT result = OpenArchiveSpec(archive, + true, // needPhySize + limitedStream, &maxCheckStartPosition, useOffsetCallback ? (IArchiveOpenCallback *)openCallback_Offset : (IArchiveOpenCallback *)op.callback, extractCallback_To_OpenCallback); RINOK(ReadBasicProps(archive, ai.Flags_UseGlobalOffset() ? 0 : startArcPos, result)); bool isOpen = false; + if (result == S_FALSE) { if (!mode.CanReturnParser) { if (formatIndex < 0 && ErrorInfo.IsArc_After_NonOpen()) { - ErrorInfo.ErrorFormatIndex = index; + ErrorInfo.ErrorFormatIndex = (int)index; NonOpen_ErrorInfo = ErrorInfo; // if archive was detected, we don't need additional open attempts return S_FALSE; } continue; } - if (!ErrorInfo.IsArc_After_NonOpen() || !PhySizeDefined || PhySize == 0) + if (!ErrorInfo.IsArc_After_NonOpen() || !PhySize_Defined || PhySize == 0) continue; } else { + if (PhySize_Defined && PhySize == 0) + { + PRF(printf(" phySize_Defined && PhySize == 0 ")); + // we skip that epmty archive case with unusual unexpected (PhySize == 0) from Code function. + continue; + } isOpen = true; RINOK(result); PRF(printf(" OK ")); @@ -2671,13 +2796,14 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) pi.Offset = startArcPos; if (ai.Flags_UseGlobalOffset()) - pi.Offset = Offset; + pi.Offset = (UInt64)Offset; else if (Offset != 0) return E_FAIL; - UInt64 arcRem = FileSize - pi.Offset; + + const UInt64 arcRem = FileSize - pi.Offset; UInt64 phySize = arcRem; - bool phySizeDefined = PhySizeDefined; - if (phySizeDefined) + const bool phySize_Defined = PhySize_Defined; + if (phySize_Defined) { if (pi.Offset + PhySize > FileSize) { @@ -2703,9 +2829,9 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) bool needScan = false; - if (isOpen && !phySizeDefined) + if (isOpen && !phySize_Defined) { - // it's for Z format + // it's for Z format, or bzip2,gz,xz with phySize that was not detected pi.LenIsUnknown = true; needScan = true; phySize = arcRem; @@ -2722,7 +2848,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) /* if (needSkipFullArc) - if (pi.Offset == 0 && phySizeDefined && pi.Size >= fileSize) + if (pi.Offset == 0 && phySize_Defined && pi.Size >= fileSize) continue; */ if (pi.Offset == 0 && !pi.LenIsUnknown && pi.Size >= FileSize) @@ -2750,7 +2876,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) RINOK(ReadParseItemProps(archive, ai, pi)); - if (pi.Offset < startArcPos && !mode.EachPos /* && phySizeDefined */) + if (pi.Offset < startArcPos && !mode.EachPos /* && phySize_Defined */) { /* It's for DMG format. This code deletes all previous items that are included to current item */ @@ -2769,7 +2895,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) } - if (isOpen && mode.CanReturnArc && phySizeDefined) + if (isOpen && mode.CanReturnArc && phySize_Defined) { // if (pi.Offset + pi.Size >= fileSize) bool openCur = false; @@ -2777,7 +2903,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) bool thereIsTail = ErrorInfo.ThereIsTail; if (thereIsTail && mode.ZerosTailIsAllowed) { - RINOK(CheckZerosTail(op, arcStreamOffset + Offset + PhySize)); + RINOK(CheckZerosTail(op, (UInt64)((Int64)arcStreamOffset + Offset + (Int64)PhySize))); if (ErrorInfo.IgnoreTail) thereIsTail = false; } @@ -2785,10 +2911,12 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) if (pi.Offset != 0) { if (!pi.IsNotArcType) + { if (thereIsTail) openCur = specFlags.CanReturnMid; else openCur = specFlags.CanReturnTail; + } } else { @@ -2796,11 +2924,11 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) openCur = true; else openCur = specFlags.CanReturnFrontal; - if (formatIndex >= -2) openCur = true; } + if (formatIndex < 0 && pi.IsSelfExe /* && mode.SkipSfxStub */) openCur = false; @@ -2827,7 +2955,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) { InStream = op.stream; Archive = archive; - FormatIndex = index; + FormatIndex = (int)index; ArcStreamOffset = arcStreamOffset; return S_OK; } @@ -2841,7 +2969,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) } */ - pi.FormatIndex = index; + pi.FormatIndex = (int)index; // printf("\nAdd offset = %d", (int)pi.Offset); handlerSpec->AddItem(pi); @@ -2896,6 +3024,9 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) return S_OK; } + + + HRESULT CArc::OpenStream(const COpenOptions &op) { RINOK(OpenStream2(op)); @@ -2908,25 +3039,25 @@ HRESULT CArc::OpenStream(const COpenOptions &op) Archive->QueryInterface(IID_IArchiveGetRawProps, (void **)&GetRawProps); Archive->QueryInterface(IID_IArchiveGetRootProps, (void **)&GetRootProps); - RINOK(Archive_GetArcBoolProp(Archive, kpidIsTree, IsTree)); - RINOK(Archive_GetArcBoolProp(Archive, kpidIsDeleted, Ask_Deleted)); - RINOK(Archive_GetArcBoolProp(Archive, kpidIsAltStream, Ask_AltStream)); - RINOK(Archive_GetArcBoolProp(Archive, kpidIsAux, Ask_Aux)); - RINOK(Archive_GetArcBoolProp(Archive, kpidINode, Ask_INode)); - RINOK(Archive_GetArcBoolProp(Archive, kpidReadOnly, IsReadOnly)); + RINOK(Archive_GetArcProp_Bool(Archive, kpidIsTree, IsTree)); + RINOK(Archive_GetArcProp_Bool(Archive, kpidIsDeleted, Ask_Deleted)); + RINOK(Archive_GetArcProp_Bool(Archive, kpidIsAltStream, Ask_AltStream)); + RINOK(Archive_GetArcProp_Bool(Archive, kpidIsAux, Ask_Aux)); + RINOK(Archive_GetArcProp_Bool(Archive, kpidINode, Ask_INode)); + RINOK(Archive_GetArcProp_Bool(Archive, kpidReadOnly, IsReadOnly)); const UString fileName = ExtractFileNameFromPath(Path); UString extension; { int dotPos = fileName.ReverseFind_Dot(); if (dotPos >= 0) - extension = fileName.Ptr(dotPos + 1); + extension = fileName.Ptr((unsigned)(dotPos + 1)); } DefaultName.Empty(); if (FormatIndex >= 0) { - const CArcInfoEx &ai = op.codecs->Formats[FormatIndex]; + const CArcInfoEx &ai = op.codecs->Formats[(unsigned)FormatIndex]; if (ai.Exts.Size() == 0) DefaultName = GetDefaultName2(fileName, UString(), UString()); else @@ -2934,7 +3065,7 @@ HRESULT CArc::OpenStream(const COpenOptions &op) int subExtIndex = ai.FindExtension(extension); if (subExtIndex < 0) subExtIndex = 0; - const CArcExtInfo &extInfo = ai.Exts[subExtIndex]; + const CArcExtInfo &extInfo = ai.Exts[(unsigned)subExtIndex]; DefaultName = GetDefaultName2(fileName, extInfo.Ext, extInfo.AddExt); } } @@ -2946,10 +3077,10 @@ HRESULT CArc::OpenStream(const COpenOptions &op) #ifdef _SFX #ifdef _WIN32 - static const char *k_ExeExt = ".exe"; + #define k_ExeExt ".exe" static const unsigned k_ExeExt_Len = 4; #else - static const char *k_ExeExt = ""; + #define k_ExeExt "" static const unsigned k_ExeExt_Len = 0; #endif @@ -2972,9 +3103,7 @@ HRESULT CArc::OpenStreamOrFile(COpenOptions &op) fileStream = fileStreamSpec; Path = filePath; if (!fileStreamSpec->Open(us2fs(Path))) - { - return GetLastError(); - } + return GetLastError_noZero_HRESULT(); op.stream = fileStream; #ifdef _SFX IgnoreSplit = true; @@ -3009,13 +3138,13 @@ HRESULT CArc::OpenStreamOrFile(COpenOptions &op) FOR_VECTOR (i, op.codecs->Formats) { const CArcInfoEx &ai = op.codecs->Formats[i]; - if (ai.IsSplit()) + if (ai.Is_Split()) continue; UString path3 = path2; - path3 += L'.'; + path3 += '.'; path3 += ai.GetMainExt(); // "7z" for SFX. Path = path3; - Path.AddAscii(".001"); + Path += ".001"; bool isOk = op.callbackSpec->SetSecondFileInfo(us2fs(Path)); if (!isOk) { @@ -3216,7 +3345,7 @@ HRESULT CArchiveLink::Open(COpenOptions &op) break; CArc arc2; - RINOK(arc.GetItemPath(mainSubfile, arc2.Path)); + RINOK(arc.GetItem_Path(mainSubfile, arc2.Path)); bool zerosTailIsAllowed; RINOK(Archive_GetItemBoolProp(arc.Archive, mainSubfile, kpidZerosTailIsAllowed, zerosTailIsAllowed)); @@ -3260,7 +3389,7 @@ HRESULT CArchiveLink::Open(COpenOptions &op) break; } RINOK(result); - RINOK(arc.GetItemMTime(mainSubfile, arc2.MTime, arc2.MTimeDefined)); + RINOK(arc.GetItem_MTime(mainSubfile, arc2.MTime)); Arcs.Add(arc2); } IsOpen = !Arcs.IsEmpty(); @@ -3279,7 +3408,7 @@ HRESULT CArchiveLink::Open2(COpenOptions &op, IOpenCallbackUI *callbackUI) if (!op.stream && !op.stdInMode) { NFile::NDir::GetFullPathAndSplit(us2fs(op.filePath), prefix, name); - openCallbackSpec->Init(prefix, name); + RINOK(openCallbackSpec->Init2(prefix, name)); } else { @@ -3309,7 +3438,7 @@ HRESULT CArchiveLink::Open2(COpenOptions &op, IOpenCallbackUI *callbackUI) return S_OK; } -HRESULT CArc::ReOpen(const COpenOptions &op) +HRESULT CArc::ReOpen(const COpenOptions &op, IArchiveOpenCallback *openCallback_Additional) { ErrorInfo.ClearErrors(); ErrorInfo.ErrorFormatIndex = -1; @@ -3331,7 +3460,7 @@ HRESULT CArc::ReOpen(const COpenOptions &op) CTailInStream *tailStreamSpec = new CTailInStream; stream2 = tailStreamSpec; tailStreamSpec->Stream = op.stream; - tailStreamSpec->Offset = globalOffset; + tailStreamSpec->Offset = (UInt64)globalOffset; tailStreamSpec->Init(); RINOK(tailStreamSpec->SeekToStart()); } @@ -3339,12 +3468,15 @@ HRESULT CArc::ReOpen(const COpenOptions &op) // There are archives with embedded STUBs (like ZIP), so we must support signature scanning // But for another archives we can use 0 here. So the code can be fixed !!! UInt64 maxStartPosition = kMaxCheckStartPosition; - HRESULT res = Archive->Open(stream2, &maxStartPosition, op.callback); + IArchiveOpenCallback *openCallback = openCallback_Additional; + if (!openCallback) + openCallback = op.callback; + HRESULT res = Archive->Open(stream2, &maxStartPosition, openCallback); if (res == S_OK) { - RINOK(ReadBasicProps(Archive, globalOffset, res)); - ArcStreamOffset = globalOffset; + RINOK(ReadBasicProps(Archive, (UInt64)globalOffset, res)); + ArcStreamOffset = (UInt64)globalOffset; if (ArcStreamOffset != 0) InStream = op.stream; } @@ -3384,18 +3516,18 @@ HRESULT CArchiveLink::ReOpen(COpenOptions &op) { FString dirPrefix, fileName; NFile::NDir::GetFullPathAndSplit(us2fs(op.filePath), dirPrefix, fileName); - openCallbackSpec->Init(dirPrefix, fileName); + RINOK(openCallbackSpec->Init2(dirPrefix, fileName)); } CInFileStream *fileStreamSpec = new CInFileStream; CMyComPtr<IInStream> stream(fileStreamSpec); if (!fileStreamSpec->Open(us2fs(op.filePath))) - return GetLastError(); + return GetLastError_noZero_HRESULT(); op.stream = stream; CArc &arc = Arcs[0]; - HRESULT res = arc.ReOpen(op); + HRESULT res = arc.ReOpen(op, openCallbackNew); PasswordWasAsked = openCallbackSpec->PasswordWasAsked; // Password = openCallbackSpec->Password; @@ -3406,6 +3538,7 @@ HRESULT CArchiveLink::ReOpen(COpenOptions &op) #ifndef _SFX +bool ParseComplexSize(const wchar_t *s, UInt64 &result); bool ParseComplexSize(const wchar_t *s, UInt64 &result) { result = 0; @@ -3463,7 +3596,7 @@ static bool ParseTypeParams(const UString &s, COpenType &type) return false; } -bool ParseType(CCodecs &codecs, const UString &s, COpenType &type) +static bool ParseType(CCodecs &codecs, const UString &s, COpenType &type) { int pos2 = s.Find(L':'); @@ -3472,11 +3605,11 @@ bool ParseType(CCodecs &codecs, const UString &s, COpenType &type) if (pos2 < 0) { name = s; - pos2 = s.Len(); + pos2 = (int)s.Len(); } else { - name = s.Left(pos2); + name = s.Left((unsigned)pos2); pos2++; } @@ -3497,6 +3630,12 @@ bool ParseType(CCodecs &codecs, const UString &s, COpenType &type) type.CanReturnArc = false; type.CanReturnParser = true; } + else if (name.IsEqualTo_Ascii_NoCase("hash")) + { + // type.CanReturnArc = false; + // type.CanReturnParser = false; + type.IsHashType = true; + } else return false; } @@ -3505,17 +3644,17 @@ bool ParseType(CCodecs &codecs, const UString &s, COpenType &type) } - for (unsigned i = pos2; i < s.Len();) + for (unsigned i = (unsigned)pos2; i < s.Len();) { int next = s.Find(L':', i); if (next < 0) - next = s.Len(); - const UString name = s.Mid(i, next - i); + next = (int)s.Len(); + const UString name = s.Mid(i, (unsigned)next - i); if (name.IsEmpty()) return false; if (!ParseTypeParams(name, type)) return false; - i = next + 1; + i = (unsigned)next + 1; } return true; @@ -3524,21 +3663,36 @@ bool ParseType(CCodecs &codecs, const UString &s, COpenType &type) bool ParseOpenTypes(CCodecs &codecs, const UString &s, CObjectVector<COpenType> &types) { types.Clear(); + bool isHashType = false; for (unsigned pos = 0; pos < s.Len();) { int pos2 = s.Find(L'.', pos); if (pos2 < 0) - pos2 = s.Len(); - UString name = s.Mid(pos, pos2 - pos); + pos2 = (int)s.Len(); + UString name = s.Mid(pos, (unsigned)pos2 - pos); if (name.IsEmpty()) return false; COpenType type; if (!ParseType(codecs, name, type)) return false; + if (isHashType) + return false; + if (type.IsHashType) + isHashType = true; types.Add(type); - pos = pos2 + 1; + pos = (unsigned)pos2 + 1; } return true; } +/* +bool IsHashType(const CObjectVector<COpenType> &types) +{ + if (types.Size() != 1) + return false; + return types[0].IsHashType; +} +*/ + + #endif |