1370b324cSopenharmony_ci// OpenArchive.cpp 2370b324cSopenharmony_ci 3370b324cSopenharmony_ci#include "StdAfx.h" 4370b324cSopenharmony_ci 5370b324cSopenharmony_ci// #define SHOW_DEBUG_INFO 6370b324cSopenharmony_ci 7370b324cSopenharmony_ci#ifdef SHOW_DEBUG_INFO 8370b324cSopenharmony_ci#include <stdio.h> 9370b324cSopenharmony_ci#endif 10370b324cSopenharmony_ci 11370b324cSopenharmony_ci#include "../../../../C/CpuArch.h" 12370b324cSopenharmony_ci 13370b324cSopenharmony_ci#include "../../../Common/ComTry.h" 14370b324cSopenharmony_ci#include "../../../Common/IntToString.h" 15370b324cSopenharmony_ci#include "../../../Common/StringConvert.h" 16370b324cSopenharmony_ci#include "../../../Common/StringToInt.h" 17370b324cSopenharmony_ci#include "../../../Common/UTFConvert.h" 18370b324cSopenharmony_ci#include "../../../Common/Wildcard.h" 19370b324cSopenharmony_ci 20370b324cSopenharmony_ci#include "../../../Windows/FileDir.h" 21370b324cSopenharmony_ci 22370b324cSopenharmony_ci#include "../../Common/FileStreams.h" 23370b324cSopenharmony_ci#include "../../Common/LimitedStreams.h" 24370b324cSopenharmony_ci#include "../../Common/ProgressUtils.h" 25370b324cSopenharmony_ci#include "../../Common/StreamUtils.h" 26370b324cSopenharmony_ci 27370b324cSopenharmony_ci#include "../../Compress/CopyCoder.h" 28370b324cSopenharmony_ci 29370b324cSopenharmony_ci#include "DefaultName.h" 30370b324cSopenharmony_ci#include "OpenArchive.h" 31370b324cSopenharmony_ci 32370b324cSopenharmony_ci#ifndef Z7_SFX 33370b324cSopenharmony_ci#include "SetProperties.h" 34370b324cSopenharmony_ci#endif 35370b324cSopenharmony_ci 36370b324cSopenharmony_ci#ifndef Z7_SFX 37370b324cSopenharmony_ci#ifdef SHOW_DEBUG_INFO 38370b324cSopenharmony_ci#define PRF(x) x 39370b324cSopenharmony_ci#else 40370b324cSopenharmony_ci#define PRF(x) 41370b324cSopenharmony_ci#endif 42370b324cSopenharmony_ci#endif 43370b324cSopenharmony_ci 44370b324cSopenharmony_ci// increase it, if you need to support larger SFX stubs 45370b324cSopenharmony_cistatic const UInt64 kMaxCheckStartPosition = 1 << 23; 46370b324cSopenharmony_ci 47370b324cSopenharmony_ci/* 48370b324cSopenharmony_ciOpen: 49370b324cSopenharmony_ci - formatIndex >= 0 (exact Format) 50370b324cSopenharmony_ci 1) Open with main type. Archive handler is allowed to use archive start finder. 51370b324cSopenharmony_ci Warning, if there is tail. 52370b324cSopenharmony_ci 53370b324cSopenharmony_ci - formatIndex = -1 (Parser:0) (default) 54370b324cSopenharmony_ci - same as #1 but doesn't return Parser 55370b324cSopenharmony_ci 56370b324cSopenharmony_ci - formatIndex = -2 (#1) 57370b324cSopenharmony_ci - file has supported extension (like a.7z) 58370b324cSopenharmony_ci Open with that main type (only starting from start of file). 59370b324cSopenharmony_ci - open OK: 60370b324cSopenharmony_ci - if there is no tail - return OK 61370b324cSopenharmony_ci - if there is tail: 62370b324cSopenharmony_ci - archive is not "Self Exe" - return OK with Warning, that there is tail 63370b324cSopenharmony_ci - archive is "Self Exe" 64370b324cSopenharmony_ci ignore "Self Exe" stub, and tries to open tail 65370b324cSopenharmony_ci - tail can be open as archive - shows that archive and stub size property. 66370b324cSopenharmony_ci - tail can't be open as archive - shows Parser ??? 67370b324cSopenharmony_ci - open FAIL: 68370b324cSopenharmony_ci Try to open with all other types from offset 0 only. 69370b324cSopenharmony_ci If some open type is OK and physical archive size is uequal or larger 70370b324cSopenharmony_ci than file size, then return that archive with warning that cannot be open as [extension type]. 71370b324cSopenharmony_ci If extension was EXE, it will try to open as unknown_extension case 72370b324cSopenharmony_ci - file has unknown extension (like a.hhh) 73370b324cSopenharmony_ci It tries to open via parser code. 74370b324cSopenharmony_ci - if there is full archive or tail archive and unknown block or "Self Exe" 75370b324cSopenharmony_ci at front, it shows tail archive and stub size property. 76370b324cSopenharmony_ci - in another cases, if there is some archive inside file, it returns parser/ 77370b324cSopenharmony_ci - in another cases, it retuens S_FALSE 78370b324cSopenharmony_ci 79370b324cSopenharmony_ci 80370b324cSopenharmony_ci - formatIndex = -3 (#2) 81370b324cSopenharmony_ci - same as #1, but 82370b324cSopenharmony_ci - stub (EXE) + archive is open in Parser 83370b324cSopenharmony_ci 84370b324cSopenharmony_ci - formatIndex = -4 (#3) 85370b324cSopenharmony_ci - returns only Parser. skip full file archive. And show other sub-archives 86370b324cSopenharmony_ci 87370b324cSopenharmony_ci - formatIndex = -5 (#4) 88370b324cSopenharmony_ci - returns only Parser. skip full file archive. And show other sub-archives for each byte pos 89370b324cSopenharmony_ci 90370b324cSopenharmony_ci*/ 91370b324cSopenharmony_ci 92370b324cSopenharmony_ci 93370b324cSopenharmony_ci 94370b324cSopenharmony_ci 95370b324cSopenharmony_ciusing namespace NWindows; 96370b324cSopenharmony_ci 97370b324cSopenharmony_ci/* 98370b324cSopenharmony_ci#ifdef Z7_SFX 99370b324cSopenharmony_ci#define OPEN_PROPS_PARAM 100370b324cSopenharmony_ci#else 101370b324cSopenharmony_ci#define OPEN_PROPS_PARAM , props 102370b324cSopenharmony_ci#endif 103370b324cSopenharmony_ci*/ 104370b324cSopenharmony_ci 105370b324cSopenharmony_ci/* 106370b324cSopenharmony_ciCArc::~CArc() 107370b324cSopenharmony_ci{ 108370b324cSopenharmony_ci GetRawProps.Release(); 109370b324cSopenharmony_ci Archive.Release(); 110370b324cSopenharmony_ci printf("\nCArc::~CArc()\n"); 111370b324cSopenharmony_ci} 112370b324cSopenharmony_ci*/ 113370b324cSopenharmony_ci 114370b324cSopenharmony_ci#ifndef Z7_SFX 115370b324cSopenharmony_ci 116370b324cSopenharmony_cinamespace NArchive { 117370b324cSopenharmony_cinamespace NParser { 118370b324cSopenharmony_ci 119370b324cSopenharmony_cistruct CParseItem 120370b324cSopenharmony_ci{ 121370b324cSopenharmony_ci UInt64 Offset; 122370b324cSopenharmony_ci UInt64 Size; 123370b324cSopenharmony_ci // UInt64 OkSize; 124370b324cSopenharmony_ci UString Name; 125370b324cSopenharmony_ci UString Extension; 126370b324cSopenharmony_ci FILETIME FileTime; 127370b324cSopenharmony_ci UString Comment; 128370b324cSopenharmony_ci UString ArcType; 129370b324cSopenharmony_ci 130370b324cSopenharmony_ci bool FileTime_Defined; 131370b324cSopenharmony_ci bool UnpackSize_Defined; 132370b324cSopenharmony_ci bool NumSubDirs_Defined; 133370b324cSopenharmony_ci bool NumSubFiles_Defined; 134370b324cSopenharmony_ci 135370b324cSopenharmony_ci bool IsSelfExe; 136370b324cSopenharmony_ci bool IsNotArcType; 137370b324cSopenharmony_ci 138370b324cSopenharmony_ci UInt64 UnpackSize; 139370b324cSopenharmony_ci UInt64 NumSubDirs; 140370b324cSopenharmony_ci UInt64 NumSubFiles; 141370b324cSopenharmony_ci 142370b324cSopenharmony_ci int FormatIndex; 143370b324cSopenharmony_ci 144370b324cSopenharmony_ci bool LenIsUnknown; 145370b324cSopenharmony_ci 146370b324cSopenharmony_ci CParseItem(): 147370b324cSopenharmony_ci // OkSize(0), 148370b324cSopenharmony_ci FileTime_Defined(false), 149370b324cSopenharmony_ci UnpackSize_Defined(false), 150370b324cSopenharmony_ci NumSubDirs_Defined(false), 151370b324cSopenharmony_ci NumSubFiles_Defined(false), 152370b324cSopenharmony_ci IsSelfExe(false), 153370b324cSopenharmony_ci IsNotArcType(false), 154370b324cSopenharmony_ci LenIsUnknown(false) 155370b324cSopenharmony_ci {} 156370b324cSopenharmony_ci 157370b324cSopenharmony_ci /* 158370b324cSopenharmony_ci bool IsEqualTo(const CParseItem &item) const 159370b324cSopenharmony_ci { 160370b324cSopenharmony_ci return Offset == item.Offset && Size == item.Size; 161370b324cSopenharmony_ci } 162370b324cSopenharmony_ci */ 163370b324cSopenharmony_ci 164370b324cSopenharmony_ci void NormalizeOffset() 165370b324cSopenharmony_ci { 166370b324cSopenharmony_ci if ((Int64)Offset < 0) 167370b324cSopenharmony_ci { 168370b324cSopenharmony_ci Size += Offset; 169370b324cSopenharmony_ci // OkSize += Offset; 170370b324cSopenharmony_ci Offset = 0; 171370b324cSopenharmony_ci } 172370b324cSopenharmony_ci } 173370b324cSopenharmony_ci}; 174370b324cSopenharmony_ci 175370b324cSopenharmony_ciZ7_CLASS_IMP_CHandler_IInArchive_1( 176370b324cSopenharmony_ci IInArchiveGetStream 177370b324cSopenharmony_ci) 178370b324cSopenharmony_cipublic: 179370b324cSopenharmony_ci CObjectVector<CParseItem> _items; 180370b324cSopenharmony_ci UInt64 _maxEndOffset; 181370b324cSopenharmony_ci CMyComPtr<IInStream> _stream; 182370b324cSopenharmony_ci 183370b324cSopenharmony_ci UInt64 GetLastEnd() const 184370b324cSopenharmony_ci { 185370b324cSopenharmony_ci if (_items.IsEmpty()) 186370b324cSopenharmony_ci return 0; 187370b324cSopenharmony_ci const CParseItem &back = _items.Back(); 188370b324cSopenharmony_ci return back.Offset + back.Size; 189370b324cSopenharmony_ci } 190370b324cSopenharmony_ci 191370b324cSopenharmony_ci void AddUnknownItem(UInt64 next); 192370b324cSopenharmony_ci int FindInsertPos(const CParseItem &item) const; 193370b324cSopenharmony_ci void AddItem(const CParseItem &item); 194370b324cSopenharmony_ci 195370b324cSopenharmony_ci CHandler(): _maxEndOffset(0) {} 196370b324cSopenharmony_ci}; 197370b324cSopenharmony_ci 198370b324cSopenharmony_ciint CHandler::FindInsertPos(const CParseItem &item) const 199370b324cSopenharmony_ci{ 200370b324cSopenharmony_ci unsigned left = 0, right = _items.Size(); 201370b324cSopenharmony_ci while (left != right) 202370b324cSopenharmony_ci { 203370b324cSopenharmony_ci const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); 204370b324cSopenharmony_ci const CParseItem &midItem = _items[mid]; 205370b324cSopenharmony_ci if (item.Offset < midItem.Offset) 206370b324cSopenharmony_ci right = mid; 207370b324cSopenharmony_ci else if (item.Offset > midItem.Offset) 208370b324cSopenharmony_ci left = mid + 1; 209370b324cSopenharmony_ci else if (item.Size < midItem.Size) 210370b324cSopenharmony_ci right = mid; 211370b324cSopenharmony_ci /* 212370b324cSopenharmony_ci else if (item.Size > midItem.Size) 213370b324cSopenharmony_ci left = mid + 1; 214370b324cSopenharmony_ci */ 215370b324cSopenharmony_ci else 216370b324cSopenharmony_ci { 217370b324cSopenharmony_ci left = mid + 1; 218370b324cSopenharmony_ci // return -1; 219370b324cSopenharmony_ci } 220370b324cSopenharmony_ci } 221370b324cSopenharmony_ci return (int)left; 222370b324cSopenharmony_ci} 223370b324cSopenharmony_ci 224370b324cSopenharmony_civoid CHandler::AddUnknownItem(UInt64 next) 225370b324cSopenharmony_ci{ 226370b324cSopenharmony_ci /* 227370b324cSopenharmony_ci UInt64 prevEnd = 0; 228370b324cSopenharmony_ci if (!_items.IsEmpty()) 229370b324cSopenharmony_ci { 230370b324cSopenharmony_ci const CParseItem &back = _items.Back(); 231370b324cSopenharmony_ci prevEnd = back.Offset + back.Size; 232370b324cSopenharmony_ci } 233370b324cSopenharmony_ci */ 234370b324cSopenharmony_ci if (_maxEndOffset < next) 235370b324cSopenharmony_ci { 236370b324cSopenharmony_ci CParseItem item2; 237370b324cSopenharmony_ci item2.Offset = _maxEndOffset; 238370b324cSopenharmony_ci item2.Size = next - _maxEndOffset; 239370b324cSopenharmony_ci _maxEndOffset = next; 240370b324cSopenharmony_ci _items.Add(item2); 241370b324cSopenharmony_ci } 242370b324cSopenharmony_ci else if (_maxEndOffset > next && !_items.IsEmpty()) 243370b324cSopenharmony_ci { 244370b324cSopenharmony_ci CParseItem &back = _items.Back(); 245370b324cSopenharmony_ci if (back.LenIsUnknown) 246370b324cSopenharmony_ci { 247370b324cSopenharmony_ci back.Size = next - back.Offset; 248370b324cSopenharmony_ci _maxEndOffset = next; 249370b324cSopenharmony_ci } 250370b324cSopenharmony_ci } 251370b324cSopenharmony_ci} 252370b324cSopenharmony_ci 253370b324cSopenharmony_civoid CHandler::AddItem(const CParseItem &item) 254370b324cSopenharmony_ci{ 255370b324cSopenharmony_ci AddUnknownItem(item.Offset); 256370b324cSopenharmony_ci const int pos = FindInsertPos(item); 257370b324cSopenharmony_ci if (pos != -1) 258370b324cSopenharmony_ci { 259370b324cSopenharmony_ci _items.Insert((unsigned)pos, item); 260370b324cSopenharmony_ci UInt64 next = item.Offset + item.Size; 261370b324cSopenharmony_ci if (_maxEndOffset < next) 262370b324cSopenharmony_ci _maxEndOffset = next; 263370b324cSopenharmony_ci } 264370b324cSopenharmony_ci} 265370b324cSopenharmony_ci 266370b324cSopenharmony_ci/* 267370b324cSopenharmony_cistatic const CStatProp kProps[] = 268370b324cSopenharmony_ci{ 269370b324cSopenharmony_ci { NULL, kpidPath, VT_BSTR}, 270370b324cSopenharmony_ci { NULL, kpidSize, VT_UI8}, 271370b324cSopenharmony_ci { NULL, kpidMTime, VT_FILETIME}, 272370b324cSopenharmony_ci { NULL, kpidType, VT_BSTR}, 273370b324cSopenharmony_ci { NULL, kpidComment, VT_BSTR}, 274370b324cSopenharmony_ci { NULL, kpidOffset, VT_UI8}, 275370b324cSopenharmony_ci { NULL, kpidUnpackSize, VT_UI8}, 276370b324cSopenharmony_ci// { NULL, kpidNumSubDirs, VT_UI8}, 277370b324cSopenharmony_ci}; 278370b324cSopenharmony_ci*/ 279370b324cSopenharmony_ci 280370b324cSopenharmony_cistatic const Byte kProps[] = 281370b324cSopenharmony_ci{ 282370b324cSopenharmony_ci kpidPath, 283370b324cSopenharmony_ci kpidSize, 284370b324cSopenharmony_ci kpidMTime, 285370b324cSopenharmony_ci kpidType, 286370b324cSopenharmony_ci kpidComment, 287370b324cSopenharmony_ci kpidOffset, 288370b324cSopenharmony_ci kpidUnpackSize 289370b324cSopenharmony_ci}; 290370b324cSopenharmony_ci 291370b324cSopenharmony_ciIMP_IInArchive_Props 292370b324cSopenharmony_ciIMP_IInArchive_ArcProps_NO 293370b324cSopenharmony_ci 294370b324cSopenharmony_ciZ7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback * /* openArchiveCallback */)) 295370b324cSopenharmony_ci{ 296370b324cSopenharmony_ci COM_TRY_BEGIN 297370b324cSopenharmony_ci { 298370b324cSopenharmony_ci Close(); 299370b324cSopenharmony_ci _stream = stream; 300370b324cSopenharmony_ci } 301370b324cSopenharmony_ci return S_OK; 302370b324cSopenharmony_ci COM_TRY_END 303370b324cSopenharmony_ci} 304370b324cSopenharmony_ci 305370b324cSopenharmony_ciZ7_COM7F_IMF(CHandler::Close()) 306370b324cSopenharmony_ci{ 307370b324cSopenharmony_ci _items.Clear(); 308370b324cSopenharmony_ci _stream.Release(); 309370b324cSopenharmony_ci return S_OK; 310370b324cSopenharmony_ci} 311370b324cSopenharmony_ci 312370b324cSopenharmony_ciZ7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) 313370b324cSopenharmony_ci{ 314370b324cSopenharmony_ci *numItems = _items.Size(); 315370b324cSopenharmony_ci return S_OK; 316370b324cSopenharmony_ci} 317370b324cSopenharmony_ci 318370b324cSopenharmony_ciZ7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) 319370b324cSopenharmony_ci{ 320370b324cSopenharmony_ci COM_TRY_BEGIN 321370b324cSopenharmony_ci NCOM::CPropVariant prop; 322370b324cSopenharmony_ci 323370b324cSopenharmony_ci const CParseItem &item = _items[index]; 324370b324cSopenharmony_ci 325370b324cSopenharmony_ci switch (propID) 326370b324cSopenharmony_ci { 327370b324cSopenharmony_ci case kpidPath: 328370b324cSopenharmony_ci { 329370b324cSopenharmony_ci char sz[32]; 330370b324cSopenharmony_ci ConvertUInt32ToString(index + 1, sz); 331370b324cSopenharmony_ci UString s(sz); 332370b324cSopenharmony_ci if (!item.Name.IsEmpty()) 333370b324cSopenharmony_ci { 334370b324cSopenharmony_ci s.Add_Dot(); 335370b324cSopenharmony_ci s += item.Name; 336370b324cSopenharmony_ci } 337370b324cSopenharmony_ci if (!item.Extension.IsEmpty()) 338370b324cSopenharmony_ci { 339370b324cSopenharmony_ci s.Add_Dot(); 340370b324cSopenharmony_ci s += item.Extension; 341370b324cSopenharmony_ci } 342370b324cSopenharmony_ci prop = s; break; 343370b324cSopenharmony_ci } 344370b324cSopenharmony_ci case kpidSize: 345370b324cSopenharmony_ci case kpidPackSize: prop = item.Size; break; 346370b324cSopenharmony_ci case kpidOffset: prop = item.Offset; break; 347370b324cSopenharmony_ci case kpidUnpackSize: if (item.UnpackSize_Defined) prop = item.UnpackSize; break; 348370b324cSopenharmony_ci case kpidNumSubFiles: if (item.NumSubFiles_Defined) prop = item.NumSubFiles; break; 349370b324cSopenharmony_ci case kpidNumSubDirs: if (item.NumSubDirs_Defined) prop = item.NumSubDirs; break; 350370b324cSopenharmony_ci case kpidMTime: if (item.FileTime_Defined) prop = item.FileTime; break; 351370b324cSopenharmony_ci case kpidComment: if (!item.Comment.IsEmpty()) prop = item.Comment; break; 352370b324cSopenharmony_ci case kpidType: if (!item.ArcType.IsEmpty()) prop = item.ArcType; break; 353370b324cSopenharmony_ci } 354370b324cSopenharmony_ci prop.Detach(value); 355370b324cSopenharmony_ci return S_OK; 356370b324cSopenharmony_ci COM_TRY_END 357370b324cSopenharmony_ci} 358370b324cSopenharmony_ci 359370b324cSopenharmony_ciZ7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, 360370b324cSopenharmony_ci Int32 testMode, IArchiveExtractCallback *extractCallback)) 361370b324cSopenharmony_ci{ 362370b324cSopenharmony_ci COM_TRY_BEGIN 363370b324cSopenharmony_ci 364370b324cSopenharmony_ci const bool allFilesMode = (numItems == (UInt32)(Int32)-1); 365370b324cSopenharmony_ci if (allFilesMode) 366370b324cSopenharmony_ci numItems = _items.Size(); 367370b324cSopenharmony_ci if (_stream && numItems == 0) 368370b324cSopenharmony_ci return S_OK; 369370b324cSopenharmony_ci UInt64 totalSize = 0; 370370b324cSopenharmony_ci UInt32 i; 371370b324cSopenharmony_ci for (i = 0; i < numItems; i++) 372370b324cSopenharmony_ci totalSize += _items[allFilesMode ? i : indices[i]].Size; 373370b324cSopenharmony_ci extractCallback->SetTotal(totalSize); 374370b324cSopenharmony_ci 375370b324cSopenharmony_ci totalSize = 0; 376370b324cSopenharmony_ci 377370b324cSopenharmony_ci CLocalProgress *lps = new CLocalProgress; 378370b324cSopenharmony_ci CMyComPtr<ICompressProgressInfo> progress = lps; 379370b324cSopenharmony_ci lps->Init(extractCallback, false); 380370b324cSopenharmony_ci 381370b324cSopenharmony_ci CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; 382370b324cSopenharmony_ci CMyComPtr<ISequentialInStream> inStream(streamSpec); 383370b324cSopenharmony_ci streamSpec->SetStream(_stream); 384370b324cSopenharmony_ci 385370b324cSopenharmony_ci CLimitedSequentialOutStream *outStreamSpec = new CLimitedSequentialOutStream; 386370b324cSopenharmony_ci CMyComPtr<ISequentialOutStream> outStream(outStreamSpec); 387370b324cSopenharmony_ci 388370b324cSopenharmony_ci NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); 389370b324cSopenharmony_ci CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; 390370b324cSopenharmony_ci 391370b324cSopenharmony_ci for (i = 0; i < numItems; i++) 392370b324cSopenharmony_ci { 393370b324cSopenharmony_ci lps->InSize = totalSize; 394370b324cSopenharmony_ci lps->OutSize = totalSize; 395370b324cSopenharmony_ci RINOK(lps->SetCur()) 396370b324cSopenharmony_ci CMyComPtr<ISequentialOutStream> realOutStream; 397370b324cSopenharmony_ci const Int32 askMode = testMode ? 398370b324cSopenharmony_ci NExtract::NAskMode::kTest : 399370b324cSopenharmony_ci NExtract::NAskMode::kExtract; 400370b324cSopenharmony_ci const UInt32 index = allFilesMode ? i : indices[i]; 401370b324cSopenharmony_ci const CParseItem &item = _items[index]; 402370b324cSopenharmony_ci 403370b324cSopenharmony_ci RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) 404370b324cSopenharmony_ci UInt64 unpackSize = item.Size; 405370b324cSopenharmony_ci totalSize += unpackSize; 406370b324cSopenharmony_ci bool skipMode = false; 407370b324cSopenharmony_ci if (!testMode && !realOutStream) 408370b324cSopenharmony_ci continue; 409370b324cSopenharmony_ci RINOK(extractCallback->PrepareOperation(askMode)) 410370b324cSopenharmony_ci 411370b324cSopenharmony_ci outStreamSpec->SetStream(realOutStream); 412370b324cSopenharmony_ci realOutStream.Release(); 413370b324cSopenharmony_ci outStreamSpec->Init(skipMode ? 0 : unpackSize, true); 414370b324cSopenharmony_ci 415370b324cSopenharmony_ci Int32 opRes = NExtract::NOperationResult::kOK; 416370b324cSopenharmony_ci RINOK(InStream_SeekSet(_stream, item.Offset)) 417370b324cSopenharmony_ci streamSpec->Init(unpackSize); 418370b324cSopenharmony_ci RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)) 419370b324cSopenharmony_ci 420370b324cSopenharmony_ci if (outStreamSpec->GetRem() != 0) 421370b324cSopenharmony_ci opRes = NExtract::NOperationResult::kDataError; 422370b324cSopenharmony_ci outStreamSpec->ReleaseStream(); 423370b324cSopenharmony_ci RINOK(extractCallback->SetOperationResult(opRes)) 424370b324cSopenharmony_ci } 425370b324cSopenharmony_ci 426370b324cSopenharmony_ci return S_OK; 427370b324cSopenharmony_ci 428370b324cSopenharmony_ci COM_TRY_END 429370b324cSopenharmony_ci} 430370b324cSopenharmony_ci 431370b324cSopenharmony_ci 432370b324cSopenharmony_ciZ7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) 433370b324cSopenharmony_ci{ 434370b324cSopenharmony_ci COM_TRY_BEGIN 435370b324cSopenharmony_ci const CParseItem &item = _items[index]; 436370b324cSopenharmony_ci return CreateLimitedInStream(_stream, item.Offset, item.Size, stream); 437370b324cSopenharmony_ci COM_TRY_END 438370b324cSopenharmony_ci} 439370b324cSopenharmony_ci 440370b324cSopenharmony_ci}} 441370b324cSopenharmony_ci 442370b324cSopenharmony_ci#endif 443370b324cSopenharmony_ci 444370b324cSopenharmony_ciHRESULT Archive_GetItemBoolProp(IInArchive *arc, UInt32 index, PROPID propID, bool &result) throw() 445370b324cSopenharmony_ci{ 446370b324cSopenharmony_ci NCOM::CPropVariant prop; 447370b324cSopenharmony_ci result = false; 448370b324cSopenharmony_ci RINOK(arc->GetProperty(index, propID, &prop)) 449370b324cSopenharmony_ci if (prop.vt == VT_BOOL) 450370b324cSopenharmony_ci result = VARIANT_BOOLToBool(prop.boolVal); 451370b324cSopenharmony_ci else if (prop.vt != VT_EMPTY) 452370b324cSopenharmony_ci return E_FAIL; 453370b324cSopenharmony_ci return S_OK; 454370b324cSopenharmony_ci} 455370b324cSopenharmony_ci 456370b324cSopenharmony_ciHRESULT Archive_IsItem_Dir(IInArchive *arc, UInt32 index, bool &result) throw() 457370b324cSopenharmony_ci{ 458370b324cSopenharmony_ci return Archive_GetItemBoolProp(arc, index, kpidIsDir, result); 459370b324cSopenharmony_ci} 460370b324cSopenharmony_ci 461370b324cSopenharmony_ciHRESULT Archive_IsItem_Aux(IInArchive *arc, UInt32 index, bool &result) throw() 462370b324cSopenharmony_ci{ 463370b324cSopenharmony_ci return Archive_GetItemBoolProp(arc, index, kpidIsAux, result); 464370b324cSopenharmony_ci} 465370b324cSopenharmony_ci 466370b324cSopenharmony_ciHRESULT Archive_IsItem_AltStream(IInArchive *arc, UInt32 index, bool &result) throw() 467370b324cSopenharmony_ci{ 468370b324cSopenharmony_ci return Archive_GetItemBoolProp(arc, index, kpidIsAltStream, result); 469370b324cSopenharmony_ci} 470370b324cSopenharmony_ci 471370b324cSopenharmony_ciHRESULT Archive_IsItem_Deleted(IInArchive *arc, UInt32 index, bool &result) throw() 472370b324cSopenharmony_ci{ 473370b324cSopenharmony_ci return Archive_GetItemBoolProp(arc, index, kpidIsDeleted, result); 474370b324cSopenharmony_ci} 475370b324cSopenharmony_ci 476370b324cSopenharmony_cistatic HRESULT Archive_GetArcProp_Bool(IInArchive *arc, PROPID propid, bool &result) throw() 477370b324cSopenharmony_ci{ 478370b324cSopenharmony_ci NCOM::CPropVariant prop; 479370b324cSopenharmony_ci result = false; 480370b324cSopenharmony_ci RINOK(arc->GetArchiveProperty(propid, &prop)) 481370b324cSopenharmony_ci if (prop.vt == VT_BOOL) 482370b324cSopenharmony_ci result = VARIANT_BOOLToBool(prop.boolVal); 483370b324cSopenharmony_ci else if (prop.vt != VT_EMPTY) 484370b324cSopenharmony_ci return E_FAIL; 485370b324cSopenharmony_ci return S_OK; 486370b324cSopenharmony_ci} 487370b324cSopenharmony_ci 488370b324cSopenharmony_cistatic HRESULT Archive_GetArcProp_UInt(IInArchive *arc, PROPID propid, UInt64 &result, bool &defined) 489370b324cSopenharmony_ci{ 490370b324cSopenharmony_ci defined = false; 491370b324cSopenharmony_ci NCOM::CPropVariant prop; 492370b324cSopenharmony_ci RINOK(arc->GetArchiveProperty(propid, &prop)) 493370b324cSopenharmony_ci switch (prop.vt) 494370b324cSopenharmony_ci { 495370b324cSopenharmony_ci case VT_UI4: result = prop.ulVal; break; 496370b324cSopenharmony_ci case VT_I4: result = (UInt64)(Int64)prop.lVal; break; 497370b324cSopenharmony_ci case VT_UI8: result = (UInt64)prop.uhVal.QuadPart; break; 498370b324cSopenharmony_ci case VT_I8: result = (UInt64)prop.hVal.QuadPart; break; 499370b324cSopenharmony_ci case VT_EMPTY: return S_OK; 500370b324cSopenharmony_ci default: return E_FAIL; 501370b324cSopenharmony_ci } 502370b324cSopenharmony_ci defined = true; 503370b324cSopenharmony_ci return S_OK; 504370b324cSopenharmony_ci} 505370b324cSopenharmony_ci 506370b324cSopenharmony_cistatic HRESULT Archive_GetArcProp_Int(IInArchive *arc, PROPID propid, Int64 &result, bool &defined) 507370b324cSopenharmony_ci{ 508370b324cSopenharmony_ci defined = false; 509370b324cSopenharmony_ci NCOM::CPropVariant prop; 510370b324cSopenharmony_ci RINOK(arc->GetArchiveProperty(propid, &prop)) 511370b324cSopenharmony_ci switch (prop.vt) 512370b324cSopenharmony_ci { 513370b324cSopenharmony_ci case VT_UI4: result = prop.ulVal; break; 514370b324cSopenharmony_ci case VT_I4: result = prop.lVal; break; 515370b324cSopenharmony_ci case VT_UI8: result = (Int64)prop.uhVal.QuadPart; break; 516370b324cSopenharmony_ci case VT_I8: result = (Int64)prop.hVal.QuadPart; break; 517370b324cSopenharmony_ci case VT_EMPTY: return S_OK; 518370b324cSopenharmony_ci default: return E_FAIL; 519370b324cSopenharmony_ci } 520370b324cSopenharmony_ci defined = true; 521370b324cSopenharmony_ci return S_OK; 522370b324cSopenharmony_ci} 523370b324cSopenharmony_ci 524370b324cSopenharmony_ci#ifndef Z7_SFX 525370b324cSopenharmony_ci 526370b324cSopenharmony_ciHRESULT CArc::GetItem_PathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const 527370b324cSopenharmony_ci{ 528370b324cSopenharmony_ci if (!GetRawProps) 529370b324cSopenharmony_ci return E_FAIL; 530370b324cSopenharmony_ci if (index == parent) 531370b324cSopenharmony_ci return S_OK; 532370b324cSopenharmony_ci UInt32 curIndex = index; 533370b324cSopenharmony_ci 534370b324cSopenharmony_ci UString s; 535370b324cSopenharmony_ci 536370b324cSopenharmony_ci bool prevWasAltStream = false; 537370b324cSopenharmony_ci 538370b324cSopenharmony_ci for (;;) 539370b324cSopenharmony_ci { 540370b324cSopenharmony_ci #ifdef MY_CPU_LE 541370b324cSopenharmony_ci const void *p; 542370b324cSopenharmony_ci UInt32 size; 543370b324cSopenharmony_ci UInt32 propType; 544370b324cSopenharmony_ci RINOK(GetRawProps->GetRawProp(curIndex, kpidName, &p, &size, &propType)) 545370b324cSopenharmony_ci if (p && propType == PROP_DATA_TYPE_wchar_t_PTR_Z_LE) 546370b324cSopenharmony_ci s = (const wchar_t *)p; 547370b324cSopenharmony_ci else 548370b324cSopenharmony_ci #endif 549370b324cSopenharmony_ci { 550370b324cSopenharmony_ci NCOM::CPropVariant prop; 551370b324cSopenharmony_ci RINOK(Archive->GetProperty(curIndex, kpidName, &prop)) 552370b324cSopenharmony_ci if (prop.vt == VT_BSTR && prop.bstrVal) 553370b324cSopenharmony_ci s.SetFromBstr(prop.bstrVal); 554370b324cSopenharmony_ci else if (prop.vt == VT_EMPTY) 555370b324cSopenharmony_ci s.Empty(); 556370b324cSopenharmony_ci else 557370b324cSopenharmony_ci return E_FAIL; 558370b324cSopenharmony_ci } 559370b324cSopenharmony_ci 560370b324cSopenharmony_ci UInt32 curParent = (UInt32)(Int32)-1; 561370b324cSopenharmony_ci UInt32 parentType = 0; 562370b324cSopenharmony_ci RINOK(GetRawProps->GetParent(curIndex, &curParent, &parentType)) 563370b324cSopenharmony_ci 564370b324cSopenharmony_ci // 18.06: fixed : we don't want to split name to parts 565370b324cSopenharmony_ci /* 566370b324cSopenharmony_ci if (parentType != NParentType::kAltStream) 567370b324cSopenharmony_ci { 568370b324cSopenharmony_ci for (;;) 569370b324cSopenharmony_ci { 570370b324cSopenharmony_ci int pos = s.ReverseFind_PathSepar(); 571370b324cSopenharmony_ci if (pos < 0) 572370b324cSopenharmony_ci { 573370b324cSopenharmony_ci break; 574370b324cSopenharmony_ci } 575370b324cSopenharmony_ci parts.Insert(0, s.Ptr(pos + 1)); 576370b324cSopenharmony_ci s.DeleteFrom(pos); 577370b324cSopenharmony_ci } 578370b324cSopenharmony_ci } 579370b324cSopenharmony_ci */ 580370b324cSopenharmony_ci 581370b324cSopenharmony_ci parts.Insert(0, s); 582370b324cSopenharmony_ci 583370b324cSopenharmony_ci if (prevWasAltStream) 584370b324cSopenharmony_ci { 585370b324cSopenharmony_ci { 586370b324cSopenharmony_ci UString &s2 = parts[parts.Size() - 2]; 587370b324cSopenharmony_ci s2 += ':'; 588370b324cSopenharmony_ci s2 += parts.Back(); 589370b324cSopenharmony_ci } 590370b324cSopenharmony_ci parts.DeleteBack(); 591370b324cSopenharmony_ci } 592370b324cSopenharmony_ci 593370b324cSopenharmony_ci if (parent == curParent) 594370b324cSopenharmony_ci return S_OK; 595370b324cSopenharmony_ci 596370b324cSopenharmony_ci prevWasAltStream = false; 597370b324cSopenharmony_ci if (parentType == NParentType::kAltStream) 598370b324cSopenharmony_ci prevWasAltStream = true; 599370b324cSopenharmony_ci 600370b324cSopenharmony_ci if (curParent == (UInt32)(Int32)-1) 601370b324cSopenharmony_ci return E_FAIL; 602370b324cSopenharmony_ci curIndex = curParent; 603370b324cSopenharmony_ci } 604370b324cSopenharmony_ci} 605370b324cSopenharmony_ci 606370b324cSopenharmony_ci#endif 607370b324cSopenharmony_ci 608370b324cSopenharmony_ci 609370b324cSopenharmony_ci 610370b324cSopenharmony_ciHRESULT CArc::GetItem_Path(UInt32 index, UString &result) const 611370b324cSopenharmony_ci{ 612370b324cSopenharmony_ci #ifdef MY_CPU_LE 613370b324cSopenharmony_ci if (GetRawProps) 614370b324cSopenharmony_ci { 615370b324cSopenharmony_ci const void *p; 616370b324cSopenharmony_ci UInt32 size; 617370b324cSopenharmony_ci UInt32 propType; 618370b324cSopenharmony_ci if (!IsTree) 619370b324cSopenharmony_ci { 620370b324cSopenharmony_ci if (GetRawProps->GetRawProp(index, kpidPath, &p, &size, &propType) == S_OK && 621370b324cSopenharmony_ci propType == NPropDataType::kUtf16z) 622370b324cSopenharmony_ci { 623370b324cSopenharmony_ci unsigned len = size / 2 - 1; 624370b324cSopenharmony_ci // (len) doesn't include null terminator 625370b324cSopenharmony_ci 626370b324cSopenharmony_ci /* 627370b324cSopenharmony_ci #if WCHAR_MAX > 0xffff 628370b324cSopenharmony_ci len = (unsigned)Utf16LE__Get_Num_WCHARs(p, len); 629370b324cSopenharmony_ci 630370b324cSopenharmony_ci wchar_t *s = result.GetBuf(len); 631370b324cSopenharmony_ci wchar_t *sEnd = Utf16LE__To_WCHARs_Sep(p, len, s); 632370b324cSopenharmony_ci if (s + len != sEnd) return E_FAIL; 633370b324cSopenharmony_ci *sEnd = 0; 634370b324cSopenharmony_ci 635370b324cSopenharmony_ci #else 636370b324cSopenharmony_ci */ 637370b324cSopenharmony_ci 638370b324cSopenharmony_ci wchar_t *s = result.GetBuf(len); 639370b324cSopenharmony_ci for (unsigned i = 0; i < len; i++) 640370b324cSopenharmony_ci { 641370b324cSopenharmony_ci wchar_t c = GetUi16(p); 642370b324cSopenharmony_ci p = (const void *)((const Byte *)p + 2); 643370b324cSopenharmony_ci 644370b324cSopenharmony_ci #if WCHAR_PATH_SEPARATOR != L'/' 645370b324cSopenharmony_ci if (c == L'/') 646370b324cSopenharmony_ci c = WCHAR_PATH_SEPARATOR; 647370b324cSopenharmony_ci else if (c == L'\\') 648370b324cSopenharmony_ci c = WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT; // WSL scheme 649370b324cSopenharmony_ci #endif 650370b324cSopenharmony_ci 651370b324cSopenharmony_ci *s++ = c; 652370b324cSopenharmony_ci } 653370b324cSopenharmony_ci *s = 0; 654370b324cSopenharmony_ci 655370b324cSopenharmony_ci // #endif 656370b324cSopenharmony_ci 657370b324cSopenharmony_ci result.ReleaseBuf_SetLen(len); 658370b324cSopenharmony_ci 659370b324cSopenharmony_ci Convert_UnicodeEsc16_To_UnicodeEscHigh(result); 660370b324cSopenharmony_ci if (len != 0) 661370b324cSopenharmony_ci return S_OK; 662370b324cSopenharmony_ci } 663370b324cSopenharmony_ci } 664370b324cSopenharmony_ci /* 665370b324cSopenharmony_ci else if (GetRawProps->GetRawProp(index, kpidName, &p, &size, &propType) == S_OK && 666370b324cSopenharmony_ci p && propType == NPropDataType::kUtf16z) 667370b324cSopenharmony_ci { 668370b324cSopenharmony_ci size -= 2; 669370b324cSopenharmony_ci UInt32 totalSize = size; 670370b324cSopenharmony_ci bool isOK = false; 671370b324cSopenharmony_ci 672370b324cSopenharmony_ci { 673370b324cSopenharmony_ci UInt32 index2 = index; 674370b324cSopenharmony_ci for (;;) 675370b324cSopenharmony_ci { 676370b324cSopenharmony_ci UInt32 parent = (UInt32)(Int32)-1; 677370b324cSopenharmony_ci UInt32 parentType = 0; 678370b324cSopenharmony_ci if (GetRawProps->GetParent(index2, &parent, &parentType) != S_OK) 679370b324cSopenharmony_ci break; 680370b324cSopenharmony_ci if (parent == (UInt32)(Int32)-1) 681370b324cSopenharmony_ci { 682370b324cSopenharmony_ci if (parentType != 0) 683370b324cSopenharmony_ci totalSize += 2; 684370b324cSopenharmony_ci isOK = true; 685370b324cSopenharmony_ci break; 686370b324cSopenharmony_ci } 687370b324cSopenharmony_ci index2 = parent; 688370b324cSopenharmony_ci UInt32 size2; 689370b324cSopenharmony_ci const void *p2; 690370b324cSopenharmony_ci if (GetRawProps->GetRawProp(index2, kpidName, &p2, &size2, &propType) != S_OK && 691370b324cSopenharmony_ci p2 && propType == NPropDataType::kUtf16z) 692370b324cSopenharmony_ci break; 693370b324cSopenharmony_ci totalSize += size2; 694370b324cSopenharmony_ci } 695370b324cSopenharmony_ci } 696370b324cSopenharmony_ci 697370b324cSopenharmony_ci if (isOK) 698370b324cSopenharmony_ci { 699370b324cSopenharmony_ci wchar_t *sz = result.GetBuf_SetEnd(totalSize / 2); 700370b324cSopenharmony_ci UInt32 pos = totalSize - size; 701370b324cSopenharmony_ci memcpy((Byte *)sz + pos, p, size); 702370b324cSopenharmony_ci UInt32 index2 = index; 703370b324cSopenharmony_ci for (;;) 704370b324cSopenharmony_ci { 705370b324cSopenharmony_ci UInt32 parent = (UInt32)(Int32)-1; 706370b324cSopenharmony_ci UInt32 parentType = 0; 707370b324cSopenharmony_ci if (GetRawProps->GetParent(index2, &parent, &parentType) != S_OK) 708370b324cSopenharmony_ci break; 709370b324cSopenharmony_ci if (parent == (UInt32)(Int32)-1) 710370b324cSopenharmony_ci { 711370b324cSopenharmony_ci if (parentType != 0) 712370b324cSopenharmony_ci sz[pos / 2 - 1] = L':'; 713370b324cSopenharmony_ci break; 714370b324cSopenharmony_ci } 715370b324cSopenharmony_ci index2 = parent; 716370b324cSopenharmony_ci UInt32 size2; 717370b324cSopenharmony_ci const void *p2; 718370b324cSopenharmony_ci if (GetRawProps->GetRawProp(index2, kpidName, &p2, &size2, &propType) != S_OK) 719370b324cSopenharmony_ci break; 720370b324cSopenharmony_ci pos -= size2; 721370b324cSopenharmony_ci memcpy((Byte *)sz + pos, p2, size2); 722370b324cSopenharmony_ci sz[(pos + size2 - 2) / 2] = (parentType == 0) ? WCHAR_PATH_SEPARATOR : L':'; 723370b324cSopenharmony_ci } 724370b324cSopenharmony_ci #ifdef _WIN32 725370b324cSopenharmony_ci // result.Replace(L'/', WCHAR_PATH_SEPARATOR); 726370b324cSopenharmony_ci #endif 727370b324cSopenharmony_ci return S_OK; 728370b324cSopenharmony_ci } 729370b324cSopenharmony_ci } 730370b324cSopenharmony_ci */ 731370b324cSopenharmony_ci } 732370b324cSopenharmony_ci #endif 733370b324cSopenharmony_ci 734370b324cSopenharmony_ci { 735370b324cSopenharmony_ci NCOM::CPropVariant prop; 736370b324cSopenharmony_ci RINOK(Archive->GetProperty(index, kpidPath, &prop)) 737370b324cSopenharmony_ci if (prop.vt == VT_BSTR && prop.bstrVal) 738370b324cSopenharmony_ci result.SetFromBstr(prop.bstrVal); 739370b324cSopenharmony_ci else if (prop.vt == VT_EMPTY) 740370b324cSopenharmony_ci result.Empty(); 741370b324cSopenharmony_ci else 742370b324cSopenharmony_ci return E_FAIL; 743370b324cSopenharmony_ci } 744370b324cSopenharmony_ci 745370b324cSopenharmony_ci if (result.IsEmpty()) 746370b324cSopenharmony_ci return GetItem_DefaultPath(index, result); 747370b324cSopenharmony_ci 748370b324cSopenharmony_ci Convert_UnicodeEsc16_To_UnicodeEscHigh(result); 749370b324cSopenharmony_ci return S_OK; 750370b324cSopenharmony_ci} 751370b324cSopenharmony_ci 752370b324cSopenharmony_ciHRESULT CArc::GetItem_DefaultPath(UInt32 index, UString &result) const 753370b324cSopenharmony_ci{ 754370b324cSopenharmony_ci result.Empty(); 755370b324cSopenharmony_ci bool isDir; 756370b324cSopenharmony_ci RINOK(Archive_IsItem_Dir(Archive, index, isDir)) 757370b324cSopenharmony_ci if (!isDir) 758370b324cSopenharmony_ci { 759370b324cSopenharmony_ci result = DefaultName; 760370b324cSopenharmony_ci NCOM::CPropVariant prop; 761370b324cSopenharmony_ci RINOK(Archive->GetProperty(index, kpidExtension, &prop)) 762370b324cSopenharmony_ci if (prop.vt == VT_BSTR) 763370b324cSopenharmony_ci { 764370b324cSopenharmony_ci result.Add_Dot(); 765370b324cSopenharmony_ci result += prop.bstrVal; 766370b324cSopenharmony_ci } 767370b324cSopenharmony_ci else if (prop.vt != VT_EMPTY) 768370b324cSopenharmony_ci return E_FAIL; 769370b324cSopenharmony_ci } 770370b324cSopenharmony_ci return S_OK; 771370b324cSopenharmony_ci} 772370b324cSopenharmony_ci 773370b324cSopenharmony_ciHRESULT CArc::GetItem_Path2(UInt32 index, UString &result) const 774370b324cSopenharmony_ci{ 775370b324cSopenharmony_ci RINOK(GetItem_Path(index, result)) 776370b324cSopenharmony_ci if (Ask_Deleted) 777370b324cSopenharmony_ci { 778370b324cSopenharmony_ci bool isDeleted = false; 779370b324cSopenharmony_ci RINOK(Archive_IsItem_Deleted(Archive, index, isDeleted)) 780370b324cSopenharmony_ci if (isDeleted) 781370b324cSopenharmony_ci result.Insert(0, L"[DELETED]" WSTRING_PATH_SEPARATOR); 782370b324cSopenharmony_ci } 783370b324cSopenharmony_ci return S_OK; 784370b324cSopenharmony_ci} 785370b324cSopenharmony_ci 786370b324cSopenharmony_ci#ifdef SUPPORT_ALT_STREAMS 787370b324cSopenharmony_ci 788370b324cSopenharmony_ciint FindAltStreamColon_in_Path(const wchar_t *path) 789370b324cSopenharmony_ci{ 790370b324cSopenharmony_ci unsigned i = 0; 791370b324cSopenharmony_ci int colonPos = -1; 792370b324cSopenharmony_ci for (;; i++) 793370b324cSopenharmony_ci { 794370b324cSopenharmony_ci wchar_t c = path[i]; 795370b324cSopenharmony_ci if (c == 0) 796370b324cSopenharmony_ci return colonPos; 797370b324cSopenharmony_ci if (c == ':') 798370b324cSopenharmony_ci { 799370b324cSopenharmony_ci if (colonPos < 0) 800370b324cSopenharmony_ci colonPos = (int)i; 801370b324cSopenharmony_ci continue; 802370b324cSopenharmony_ci } 803370b324cSopenharmony_ci if (c == WCHAR_PATH_SEPARATOR) 804370b324cSopenharmony_ci colonPos = -1; 805370b324cSopenharmony_ci } 806370b324cSopenharmony_ci} 807370b324cSopenharmony_ci 808370b324cSopenharmony_ci#endif 809370b324cSopenharmony_ci 810370b324cSopenharmony_ciHRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const 811370b324cSopenharmony_ci{ 812370b324cSopenharmony_ci #ifdef SUPPORT_ALT_STREAMS 813370b324cSopenharmony_ci item.IsAltStream = false; 814370b324cSopenharmony_ci item.AltStreamName.Empty(); 815370b324cSopenharmony_ci item.MainPath.Empty(); 816370b324cSopenharmony_ci #endif 817370b324cSopenharmony_ci 818370b324cSopenharmony_ci item.IsDir = false; 819370b324cSopenharmony_ci item.Path.Empty(); 820370b324cSopenharmony_ci item.ParentIndex = (UInt32)(Int32)-1; 821370b324cSopenharmony_ci 822370b324cSopenharmony_ci item.PathParts.Clear(); 823370b324cSopenharmony_ci 824370b324cSopenharmony_ci RINOK(Archive_IsItem_Dir(Archive, index, item.IsDir)) 825370b324cSopenharmony_ci item.MainIsDir = item.IsDir; 826370b324cSopenharmony_ci 827370b324cSopenharmony_ci RINOK(GetItem_Path2(index, item.Path)) 828370b324cSopenharmony_ci 829370b324cSopenharmony_ci #ifndef Z7_SFX 830370b324cSopenharmony_ci UInt32 mainIndex = index; 831370b324cSopenharmony_ci #endif 832370b324cSopenharmony_ci 833370b324cSopenharmony_ci #ifdef SUPPORT_ALT_STREAMS 834370b324cSopenharmony_ci 835370b324cSopenharmony_ci item.MainPath = item.Path; 836370b324cSopenharmony_ci if (Ask_AltStream) 837370b324cSopenharmony_ci { 838370b324cSopenharmony_ci RINOK(Archive_IsItem_AltStream(Archive, index, item.IsAltStream)) 839370b324cSopenharmony_ci } 840370b324cSopenharmony_ci 841370b324cSopenharmony_ci bool needFindAltStream = false; 842370b324cSopenharmony_ci 843370b324cSopenharmony_ci if (item.IsAltStream) 844370b324cSopenharmony_ci { 845370b324cSopenharmony_ci needFindAltStream = true; 846370b324cSopenharmony_ci if (GetRawProps) 847370b324cSopenharmony_ci { 848370b324cSopenharmony_ci UInt32 parentType = 0; 849370b324cSopenharmony_ci UInt32 parentIndex; 850370b324cSopenharmony_ci RINOK(GetRawProps->GetParent(index, &parentIndex, &parentType)) 851370b324cSopenharmony_ci if (parentType == NParentType::kAltStream) 852370b324cSopenharmony_ci { 853370b324cSopenharmony_ci NCOM::CPropVariant prop; 854370b324cSopenharmony_ci RINOK(Archive->GetProperty(index, kpidName, &prop)) 855370b324cSopenharmony_ci if (prop.vt == VT_BSTR && prop.bstrVal) 856370b324cSopenharmony_ci item.AltStreamName.SetFromBstr(prop.bstrVal); 857370b324cSopenharmony_ci else if (prop.vt != VT_EMPTY) 858370b324cSopenharmony_ci return E_FAIL; 859370b324cSopenharmony_ci else 860370b324cSopenharmony_ci { 861370b324cSopenharmony_ci // item.IsAltStream = false; 862370b324cSopenharmony_ci } 863370b324cSopenharmony_ci /* 864370b324cSopenharmony_ci if (item.AltStreamName.IsEmpty()) 865370b324cSopenharmony_ci item.IsAltStream = false; 866370b324cSopenharmony_ci */ 867370b324cSopenharmony_ci 868370b324cSopenharmony_ci needFindAltStream = false; 869370b324cSopenharmony_ci item.ParentIndex = parentIndex; 870370b324cSopenharmony_ci mainIndex = parentIndex; 871370b324cSopenharmony_ci 872370b324cSopenharmony_ci if (parentIndex == (UInt32)(Int32)-1) 873370b324cSopenharmony_ci { 874370b324cSopenharmony_ci item.MainPath.Empty(); 875370b324cSopenharmony_ci item.MainIsDir = true; 876370b324cSopenharmony_ci } 877370b324cSopenharmony_ci else 878370b324cSopenharmony_ci { 879370b324cSopenharmony_ci RINOK(GetItem_Path2(parentIndex, item.MainPath)) 880370b324cSopenharmony_ci RINOK(Archive_IsItem_Dir(Archive, parentIndex, item.MainIsDir)) 881370b324cSopenharmony_ci } 882370b324cSopenharmony_ci } 883370b324cSopenharmony_ci } 884370b324cSopenharmony_ci } 885370b324cSopenharmony_ci 886370b324cSopenharmony_ci if (item.WriteToAltStreamIfColon || needFindAltStream) 887370b324cSopenharmony_ci { 888370b324cSopenharmony_ci /* Good handler must support GetRawProps::GetParent for alt streams. 889370b324cSopenharmony_ci So the following code currently is not used */ 890370b324cSopenharmony_ci int colon = FindAltStreamColon_in_Path(item.Path); 891370b324cSopenharmony_ci if (colon >= 0) 892370b324cSopenharmony_ci { 893370b324cSopenharmony_ci item.MainPath.DeleteFrom((unsigned)colon); 894370b324cSopenharmony_ci item.AltStreamName = item.Path.Ptr((unsigned)(colon + 1)); 895370b324cSopenharmony_ci item.MainIsDir = (colon == 0 || IsPathSepar(item.Path[(unsigned)colon - 1])); 896370b324cSopenharmony_ci item.IsAltStream = true; 897370b324cSopenharmony_ci } 898370b324cSopenharmony_ci } 899370b324cSopenharmony_ci 900370b324cSopenharmony_ci #endif 901370b324cSopenharmony_ci 902370b324cSopenharmony_ci #ifndef Z7_SFX 903370b324cSopenharmony_ci if (item._use_baseParentFolder_mode) 904370b324cSopenharmony_ci { 905370b324cSopenharmony_ci RINOK(GetItem_PathToParent(mainIndex, (unsigned)item._baseParentFolder, item.PathParts)) 906370b324cSopenharmony_ci 907370b324cSopenharmony_ci #ifdef SUPPORT_ALT_STREAMS 908370b324cSopenharmony_ci if ((item.WriteToAltStreamIfColon || needFindAltStream) && !item.PathParts.IsEmpty()) 909370b324cSopenharmony_ci { 910370b324cSopenharmony_ci int colon; 911370b324cSopenharmony_ci { 912370b324cSopenharmony_ci UString &s = item.PathParts.Back(); 913370b324cSopenharmony_ci colon = FindAltStreamColon_in_Path(s); 914370b324cSopenharmony_ci if (colon >= 0) 915370b324cSopenharmony_ci { 916370b324cSopenharmony_ci item.AltStreamName = s.Ptr((unsigned)(colon + 1)); 917370b324cSopenharmony_ci item.MainIsDir = (colon == 0 || IsPathSepar(s[(unsigned)colon - 1])); 918370b324cSopenharmony_ci item.IsAltStream = true; 919370b324cSopenharmony_ci s.DeleteFrom((unsigned)colon); 920370b324cSopenharmony_ci } 921370b324cSopenharmony_ci } 922370b324cSopenharmony_ci if (colon == 0) 923370b324cSopenharmony_ci item.PathParts.DeleteBack(); 924370b324cSopenharmony_ci } 925370b324cSopenharmony_ci #endif 926370b324cSopenharmony_ci 927370b324cSopenharmony_ci } 928370b324cSopenharmony_ci else 929370b324cSopenharmony_ci #endif 930370b324cSopenharmony_ci SplitPathToParts( 931370b324cSopenharmony_ci #ifdef SUPPORT_ALT_STREAMS 932370b324cSopenharmony_ci item.MainPath 933370b324cSopenharmony_ci #else 934370b324cSopenharmony_ci item.Path 935370b324cSopenharmony_ci #endif 936370b324cSopenharmony_ci , item.PathParts); 937370b324cSopenharmony_ci 938370b324cSopenharmony_ci return S_OK; 939370b324cSopenharmony_ci} 940370b324cSopenharmony_ci 941370b324cSopenharmony_ci#ifndef Z7_SFX 942370b324cSopenharmony_ci 943370b324cSopenharmony_cistatic HRESULT Archive_GetItem_Size(IInArchive *archive, UInt32 index, UInt64 &size, bool &defined) 944370b324cSopenharmony_ci{ 945370b324cSopenharmony_ci NCOM::CPropVariant prop; 946370b324cSopenharmony_ci defined = false; 947370b324cSopenharmony_ci size = 0; 948370b324cSopenharmony_ci RINOK(archive->GetProperty(index, kpidSize, &prop)) 949370b324cSopenharmony_ci switch (prop.vt) 950370b324cSopenharmony_ci { 951370b324cSopenharmony_ci case VT_UI1: size = prop.bVal; break; 952370b324cSopenharmony_ci case VT_UI2: size = prop.uiVal; break; 953370b324cSopenharmony_ci case VT_UI4: size = prop.ulVal; break; 954370b324cSopenharmony_ci case VT_UI8: size = (UInt64)prop.uhVal.QuadPart; break; 955370b324cSopenharmony_ci case VT_EMPTY: return S_OK; 956370b324cSopenharmony_ci default: return E_FAIL; 957370b324cSopenharmony_ci } 958370b324cSopenharmony_ci defined = true; 959370b324cSopenharmony_ci return S_OK; 960370b324cSopenharmony_ci} 961370b324cSopenharmony_ci 962370b324cSopenharmony_ci#endif 963370b324cSopenharmony_ci 964370b324cSopenharmony_ciHRESULT CArc::GetItem_Size(UInt32 index, UInt64 &size, bool &defined) const 965370b324cSopenharmony_ci{ 966370b324cSopenharmony_ci NCOM::CPropVariant prop; 967370b324cSopenharmony_ci defined = false; 968370b324cSopenharmony_ci size = 0; 969370b324cSopenharmony_ci RINOK(Archive->GetProperty(index, kpidSize, &prop)) 970370b324cSopenharmony_ci switch (prop.vt) 971370b324cSopenharmony_ci { 972370b324cSopenharmony_ci case VT_UI1: size = prop.bVal; break; 973370b324cSopenharmony_ci case VT_UI2: size = prop.uiVal; break; 974370b324cSopenharmony_ci case VT_UI4: size = prop.ulVal; break; 975370b324cSopenharmony_ci case VT_UI8: size = (UInt64)prop.uhVal.QuadPart; break; 976370b324cSopenharmony_ci case VT_EMPTY: return S_OK; 977370b324cSopenharmony_ci default: return E_FAIL; 978370b324cSopenharmony_ci } 979370b324cSopenharmony_ci defined = true; 980370b324cSopenharmony_ci return S_OK; 981370b324cSopenharmony_ci} 982370b324cSopenharmony_ci 983370b324cSopenharmony_ciHRESULT CArc::GetItem_MTime(UInt32 index, CArcTime &at) const 984370b324cSopenharmony_ci{ 985370b324cSopenharmony_ci at.Clear(); 986370b324cSopenharmony_ci NCOM::CPropVariant prop; 987370b324cSopenharmony_ci RINOK(Archive->GetProperty(index, kpidMTime, &prop)) 988370b324cSopenharmony_ci 989370b324cSopenharmony_ci if (prop.vt == VT_FILETIME) 990370b324cSopenharmony_ci { 991370b324cSopenharmony_ci /* 992370b324cSopenharmony_ci // for debug 993370b324cSopenharmony_ci if (FILETIME_IsZero(prop.at) && MTime.Def) 994370b324cSopenharmony_ci { 995370b324cSopenharmony_ci at = MTime; 996370b324cSopenharmony_ci return S_OK; 997370b324cSopenharmony_ci } 998370b324cSopenharmony_ci */ 999370b324cSopenharmony_ci at.Set_From_Prop(prop); 1000370b324cSopenharmony_ci if (at.Prec == 0) 1001370b324cSopenharmony_ci { 1002370b324cSopenharmony_ci // (at.Prec == 0) before version 22. 1003370b324cSopenharmony_ci // so kpidTimeType is required for that code 1004370b324cSopenharmony_ci prop.Clear(); 1005370b324cSopenharmony_ci RINOK(Archive->GetProperty(index, kpidTimeType, &prop)) 1006370b324cSopenharmony_ci if (prop.vt == VT_UI4) 1007370b324cSopenharmony_ci { 1008370b324cSopenharmony_ci UInt32 val = prop.ulVal; 1009370b324cSopenharmony_ci if (val == NFileTimeType::kWindows) 1010370b324cSopenharmony_ci val = k_PropVar_TimePrec_100ns; 1011370b324cSopenharmony_ci /* 1012370b324cSopenharmony_ci else if (val > k_PropVar_TimePrec_1ns) 1013370b324cSopenharmony_ci { 1014370b324cSopenharmony_ci val = k_PropVar_TimePrec_100ns; 1015370b324cSopenharmony_ci // val = k_PropVar_TimePrec_1ns; 1016370b324cSopenharmony_ci // return E_FAIL; // for debug 1017370b324cSopenharmony_ci } 1018370b324cSopenharmony_ci */ 1019370b324cSopenharmony_ci at.Prec = (UInt16)val; 1020370b324cSopenharmony_ci } 1021370b324cSopenharmony_ci } 1022370b324cSopenharmony_ci return S_OK; 1023370b324cSopenharmony_ci } 1024370b324cSopenharmony_ci 1025370b324cSopenharmony_ci if (prop.vt != VT_EMPTY) 1026370b324cSopenharmony_ci return E_FAIL; 1027370b324cSopenharmony_ci if (MTime.Def) 1028370b324cSopenharmony_ci at = MTime; 1029370b324cSopenharmony_ci return S_OK; 1030370b324cSopenharmony_ci} 1031370b324cSopenharmony_ci 1032370b324cSopenharmony_ci#ifndef Z7_SFX 1033370b324cSopenharmony_ci 1034370b324cSopenharmony_cistatic inline bool TestSignature(const Byte *p1, const Byte *p2, size_t size) 1035370b324cSopenharmony_ci{ 1036370b324cSopenharmony_ci for (size_t i = 0; i < size; i++) 1037370b324cSopenharmony_ci if (p1[i] != p2[i]) 1038370b324cSopenharmony_ci return false; 1039370b324cSopenharmony_ci return true; 1040370b324cSopenharmony_ci} 1041370b324cSopenharmony_ci 1042370b324cSopenharmony_ci 1043370b324cSopenharmony_cistatic void MakeCheckOrder(CCodecs *codecs, 1044370b324cSopenharmony_ci CIntVector &orderIndices, unsigned numTypes, CIntVector &orderIndices2, 1045370b324cSopenharmony_ci const Byte *data, size_t dataSize) 1046370b324cSopenharmony_ci{ 1047370b324cSopenharmony_ci for (unsigned i = 0; i < numTypes; i++) 1048370b324cSopenharmony_ci { 1049370b324cSopenharmony_ci const int index = orderIndices[i]; 1050370b324cSopenharmony_ci if (index < 0) 1051370b324cSopenharmony_ci continue; 1052370b324cSopenharmony_ci const CArcInfoEx &ai = codecs->Formats[(unsigned)index]; 1053370b324cSopenharmony_ci if (ai.SignatureOffset == 0) 1054370b324cSopenharmony_ci { 1055370b324cSopenharmony_ci if (ai.Signatures.IsEmpty()) 1056370b324cSopenharmony_ci { 1057370b324cSopenharmony_ci if (dataSize != 0) // 21.04: no Signature means Empty Signature 1058370b324cSopenharmony_ci continue; 1059370b324cSopenharmony_ci } 1060370b324cSopenharmony_ci else 1061370b324cSopenharmony_ci { 1062370b324cSopenharmony_ci unsigned k; 1063370b324cSopenharmony_ci const CObjectVector<CByteBuffer> &sigs = ai.Signatures; 1064370b324cSopenharmony_ci for (k = 0; k < sigs.Size(); k++) 1065370b324cSopenharmony_ci { 1066370b324cSopenharmony_ci const CByteBuffer &sig = sigs[k]; 1067370b324cSopenharmony_ci if (sig.Size() <= dataSize && TestSignature(data, sig, sig.Size())) 1068370b324cSopenharmony_ci break; 1069370b324cSopenharmony_ci } 1070370b324cSopenharmony_ci if (k == sigs.Size()) 1071370b324cSopenharmony_ci continue; 1072370b324cSopenharmony_ci } 1073370b324cSopenharmony_ci } 1074370b324cSopenharmony_ci orderIndices2.Add(index); 1075370b324cSopenharmony_ci orderIndices[i] = -1; 1076370b324cSopenharmony_ci } 1077370b324cSopenharmony_ci} 1078370b324cSopenharmony_ci 1079370b324cSopenharmony_ci#ifdef UNDER_CE 1080370b324cSopenharmony_ci static const unsigned kNumHashBytes = 1; 1081370b324cSopenharmony_ci #define HASH_VAL(buf) ((buf)[0]) 1082370b324cSopenharmony_ci#else 1083370b324cSopenharmony_ci static const unsigned kNumHashBytes = 2; 1084370b324cSopenharmony_ci // #define HASH_VAL(buf) ((buf)[0] | ((UInt32)(buf)[1] << 8)) 1085370b324cSopenharmony_ci #define HASH_VAL(buf) GetUi16(buf) 1086370b324cSopenharmony_ci#endif 1087370b324cSopenharmony_ci 1088370b324cSopenharmony_cistatic bool IsExeExt(const UString &ext) 1089370b324cSopenharmony_ci{ 1090370b324cSopenharmony_ci return ext.IsEqualTo_Ascii_NoCase("exe"); 1091370b324cSopenharmony_ci} 1092370b324cSopenharmony_ci 1093370b324cSopenharmony_cistatic const char * const k_PreArcFormats[] = 1094370b324cSopenharmony_ci{ 1095370b324cSopenharmony_ci "pe" 1096370b324cSopenharmony_ci , "elf" 1097370b324cSopenharmony_ci , "macho" 1098370b324cSopenharmony_ci , "mub" 1099370b324cSopenharmony_ci , "te" 1100370b324cSopenharmony_ci}; 1101370b324cSopenharmony_ci 1102370b324cSopenharmony_cistatic bool IsNameFromList(const UString &s, const char * const names[], size_t num) 1103370b324cSopenharmony_ci{ 1104370b324cSopenharmony_ci for (unsigned i = 0; i < num; i++) 1105370b324cSopenharmony_ci if (StringsAreEqualNoCase_Ascii(s, names[i])) 1106370b324cSopenharmony_ci return true; 1107370b324cSopenharmony_ci return false; 1108370b324cSopenharmony_ci} 1109370b324cSopenharmony_ci 1110370b324cSopenharmony_ci 1111370b324cSopenharmony_cistatic bool IsPreArcFormat(const CArcInfoEx &ai) 1112370b324cSopenharmony_ci{ 1113370b324cSopenharmony_ci if (ai.Flags_PreArc()) 1114370b324cSopenharmony_ci return true; 1115370b324cSopenharmony_ci return IsNameFromList(ai.Name, k_PreArcFormats, Z7_ARRAY_SIZE(k_PreArcFormats)); 1116370b324cSopenharmony_ci} 1117370b324cSopenharmony_ci 1118370b324cSopenharmony_cistatic const char * const k_Formats_with_simple_signuature[] = 1119370b324cSopenharmony_ci{ 1120370b324cSopenharmony_ci "7z" 1121370b324cSopenharmony_ci , "xz" 1122370b324cSopenharmony_ci , "rar" 1123370b324cSopenharmony_ci , "bzip2" 1124370b324cSopenharmony_ci , "gzip" 1125370b324cSopenharmony_ci , "cab" 1126370b324cSopenharmony_ci , "wim" 1127370b324cSopenharmony_ci , "rpm" 1128370b324cSopenharmony_ci , "vhd" 1129370b324cSopenharmony_ci , "xar" 1130370b324cSopenharmony_ci}; 1131370b324cSopenharmony_ci 1132370b324cSopenharmony_cistatic bool IsNewStyleSignature(const CArcInfoEx &ai) 1133370b324cSopenharmony_ci{ 1134370b324cSopenharmony_ci // if (ai.Version >= 0x91F) 1135370b324cSopenharmony_ci if (ai.NewInterface) 1136370b324cSopenharmony_ci return true; 1137370b324cSopenharmony_ci return IsNameFromList(ai.Name, k_Formats_with_simple_signuature, Z7_ARRAY_SIZE(k_Formats_with_simple_signuature)); 1138370b324cSopenharmony_ci} 1139370b324cSopenharmony_ci 1140370b324cSopenharmony_ci 1141370b324cSopenharmony_ci 1142370b324cSopenharmony_ciclass CArchiveOpenCallback_Offset Z7_final: 1143370b324cSopenharmony_ci public IArchiveOpenCallback, 1144370b324cSopenharmony_ci public IArchiveOpenVolumeCallback, 1145370b324cSopenharmony_ci #ifndef Z7_NO_CRYPTO 1146370b324cSopenharmony_ci public ICryptoGetTextPassword, 1147370b324cSopenharmony_ci #endif 1148370b324cSopenharmony_ci public CMyUnknownImp 1149370b324cSopenharmony_ci{ 1150370b324cSopenharmony_ci Z7_COM_QI_BEGIN2(IArchiveOpenCallback) 1151370b324cSopenharmony_ci Z7_COM_QI_ENTRY(IArchiveOpenVolumeCallback) 1152370b324cSopenharmony_ci #ifndef Z7_NO_CRYPTO 1153370b324cSopenharmony_ci Z7_COM_QI_ENTRY(ICryptoGetTextPassword) 1154370b324cSopenharmony_ci #endif 1155370b324cSopenharmony_ci Z7_COM_QI_END 1156370b324cSopenharmony_ci Z7_COM_ADDREF_RELEASE 1157370b324cSopenharmony_ci 1158370b324cSopenharmony_ci Z7_IFACE_COM7_IMP(IArchiveOpenCallback) 1159370b324cSopenharmony_ci Z7_IFACE_COM7_IMP(IArchiveOpenVolumeCallback) 1160370b324cSopenharmony_ci #ifndef Z7_NO_CRYPTO 1161370b324cSopenharmony_ci Z7_IFACE_COM7_IMP(ICryptoGetTextPassword) 1162370b324cSopenharmony_ci #endif 1163370b324cSopenharmony_ci 1164370b324cSopenharmony_cipublic: 1165370b324cSopenharmony_ci CMyComPtr<IArchiveOpenCallback> Callback; 1166370b324cSopenharmony_ci CMyComPtr<IArchiveOpenVolumeCallback> OpenVolumeCallback; 1167370b324cSopenharmony_ci UInt64 Files; 1168370b324cSopenharmony_ci UInt64 Offset; 1169370b324cSopenharmony_ci 1170370b324cSopenharmony_ci #ifndef Z7_NO_CRYPTO 1171370b324cSopenharmony_ci CMyComPtr<ICryptoGetTextPassword> GetTextPassword; 1172370b324cSopenharmony_ci #endif 1173370b324cSopenharmony_ci}; 1174370b324cSopenharmony_ci 1175370b324cSopenharmony_ci#ifndef Z7_NO_CRYPTO 1176370b324cSopenharmony_ciZ7_COM7F_IMF(CArchiveOpenCallback_Offset::CryptoGetTextPassword(BSTR *password)) 1177370b324cSopenharmony_ci{ 1178370b324cSopenharmony_ci COM_TRY_BEGIN 1179370b324cSopenharmony_ci if (GetTextPassword) 1180370b324cSopenharmony_ci return GetTextPassword->CryptoGetTextPassword(password); 1181370b324cSopenharmony_ci return E_NOTIMPL; 1182370b324cSopenharmony_ci COM_TRY_END 1183370b324cSopenharmony_ci} 1184370b324cSopenharmony_ci#endif 1185370b324cSopenharmony_ci 1186370b324cSopenharmony_ciZ7_COM7F_IMF(CArchiveOpenCallback_Offset::SetTotal(const UInt64 *, const UInt64 *)) 1187370b324cSopenharmony_ci{ 1188370b324cSopenharmony_ci return S_OK; 1189370b324cSopenharmony_ci} 1190370b324cSopenharmony_ci 1191370b324cSopenharmony_ciZ7_COM7F_IMF(CArchiveOpenCallback_Offset::SetCompleted(const UInt64 *, const UInt64 *bytes)) 1192370b324cSopenharmony_ci{ 1193370b324cSopenharmony_ci if (!Callback) 1194370b324cSopenharmony_ci return S_OK; 1195370b324cSopenharmony_ci UInt64 value = Offset; 1196370b324cSopenharmony_ci if (bytes) 1197370b324cSopenharmony_ci value += *bytes; 1198370b324cSopenharmony_ci return Callback->SetCompleted(&Files, &value); 1199370b324cSopenharmony_ci} 1200370b324cSopenharmony_ci 1201370b324cSopenharmony_ciZ7_COM7F_IMF(CArchiveOpenCallback_Offset::GetProperty(PROPID propID, PROPVARIANT *value)) 1202370b324cSopenharmony_ci{ 1203370b324cSopenharmony_ci if (OpenVolumeCallback) 1204370b324cSopenharmony_ci return OpenVolumeCallback->GetProperty(propID, value); 1205370b324cSopenharmony_ci NCOM::PropVariant_Clear(value); 1206370b324cSopenharmony_ci return S_OK; 1207370b324cSopenharmony_ci // return E_NOTIMPL; 1208370b324cSopenharmony_ci} 1209370b324cSopenharmony_ci 1210370b324cSopenharmony_ciZ7_COM7F_IMF(CArchiveOpenCallback_Offset::GetStream(const wchar_t *name, IInStream **inStream)) 1211370b324cSopenharmony_ci{ 1212370b324cSopenharmony_ci if (OpenVolumeCallback) 1213370b324cSopenharmony_ci return OpenVolumeCallback->GetStream(name, inStream); 1214370b324cSopenharmony_ci return S_FALSE; 1215370b324cSopenharmony_ci} 1216370b324cSopenharmony_ci 1217370b324cSopenharmony_ci#endif 1218370b324cSopenharmony_ci 1219370b324cSopenharmony_ci 1220370b324cSopenharmony_ciUInt32 GetOpenArcErrorFlags(const NCOM::CPropVariant &prop, bool *isDefinedProp) 1221370b324cSopenharmony_ci{ 1222370b324cSopenharmony_ci if (isDefinedProp != NULL) 1223370b324cSopenharmony_ci *isDefinedProp = false; 1224370b324cSopenharmony_ci 1225370b324cSopenharmony_ci switch (prop.vt) 1226370b324cSopenharmony_ci { 1227370b324cSopenharmony_ci case VT_UI8: if (isDefinedProp) *isDefinedProp = true; return (UInt32)prop.uhVal.QuadPart; 1228370b324cSopenharmony_ci case VT_UI4: if (isDefinedProp) *isDefinedProp = true; return prop.ulVal; 1229370b324cSopenharmony_ci case VT_EMPTY: return 0; 1230370b324cSopenharmony_ci default: throw 151199; 1231370b324cSopenharmony_ci } 1232370b324cSopenharmony_ci} 1233370b324cSopenharmony_ci 1234370b324cSopenharmony_civoid CArcErrorInfo::ClearErrors() 1235370b324cSopenharmony_ci{ 1236370b324cSopenharmony_ci // ErrorFormatIndex = -1; // we don't need to clear ErrorFormatIndex here !!! 1237370b324cSopenharmony_ci 1238370b324cSopenharmony_ci ThereIsTail = false; 1239370b324cSopenharmony_ci UnexpecedEnd = false; 1240370b324cSopenharmony_ci IgnoreTail = false; 1241370b324cSopenharmony_ci // NonZerosTail = false; 1242370b324cSopenharmony_ci ErrorFlags_Defined = false; 1243370b324cSopenharmony_ci ErrorFlags = 0; 1244370b324cSopenharmony_ci WarningFlags = 0; 1245370b324cSopenharmony_ci TailSize = 0; 1246370b324cSopenharmony_ci 1247370b324cSopenharmony_ci ErrorMessage.Empty(); 1248370b324cSopenharmony_ci WarningMessage.Empty(); 1249370b324cSopenharmony_ci} 1250370b324cSopenharmony_ci 1251370b324cSopenharmony_ciHRESULT CArc::ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openRes) 1252370b324cSopenharmony_ci{ 1253370b324cSopenharmony_ci // OkPhySize_Defined = false; 1254370b324cSopenharmony_ci PhySize_Defined = false; 1255370b324cSopenharmony_ci PhySize = 0; 1256370b324cSopenharmony_ci Offset = 0; 1257370b324cSopenharmony_ci AvailPhySize = FileSize - startPos; 1258370b324cSopenharmony_ci 1259370b324cSopenharmony_ci ErrorInfo.ClearErrors(); 1260370b324cSopenharmony_ci { 1261370b324cSopenharmony_ci NCOM::CPropVariant prop; 1262370b324cSopenharmony_ci RINOK(archive->GetArchiveProperty(kpidErrorFlags, &prop)) 1263370b324cSopenharmony_ci ErrorInfo.ErrorFlags = GetOpenArcErrorFlags(prop, &ErrorInfo.ErrorFlags_Defined); 1264370b324cSopenharmony_ci } 1265370b324cSopenharmony_ci { 1266370b324cSopenharmony_ci NCOM::CPropVariant prop; 1267370b324cSopenharmony_ci RINOK(archive->GetArchiveProperty(kpidWarningFlags, &prop)) 1268370b324cSopenharmony_ci ErrorInfo.WarningFlags = GetOpenArcErrorFlags(prop); 1269370b324cSopenharmony_ci } 1270370b324cSopenharmony_ci 1271370b324cSopenharmony_ci { 1272370b324cSopenharmony_ci NCOM::CPropVariant prop; 1273370b324cSopenharmony_ci RINOK(archive->GetArchiveProperty(kpidError, &prop)) 1274370b324cSopenharmony_ci if (prop.vt != VT_EMPTY) 1275370b324cSopenharmony_ci ErrorInfo.ErrorMessage = (prop.vt == VT_BSTR ? prop.bstrVal : L"Unknown error"); 1276370b324cSopenharmony_ci } 1277370b324cSopenharmony_ci 1278370b324cSopenharmony_ci { 1279370b324cSopenharmony_ci NCOM::CPropVariant prop; 1280370b324cSopenharmony_ci RINOK(archive->GetArchiveProperty(kpidWarning, &prop)) 1281370b324cSopenharmony_ci if (prop.vt != VT_EMPTY) 1282370b324cSopenharmony_ci ErrorInfo.WarningMessage = (prop.vt == VT_BSTR ? prop.bstrVal : L"Unknown warning"); 1283370b324cSopenharmony_ci } 1284370b324cSopenharmony_ci 1285370b324cSopenharmony_ci if (openRes == S_OK || ErrorInfo.IsArc_After_NonOpen()) 1286370b324cSopenharmony_ci { 1287370b324cSopenharmony_ci RINOK(Archive_GetArcProp_UInt(archive, kpidPhySize, PhySize, PhySize_Defined)) 1288370b324cSopenharmony_ci /* 1289370b324cSopenharmony_ci RINOK(Archive_GetArcProp_UInt(archive, kpidOkPhySize, OkPhySize, OkPhySize_Defined)); 1290370b324cSopenharmony_ci if (!OkPhySize_Defined) 1291370b324cSopenharmony_ci { 1292370b324cSopenharmony_ci OkPhySize_Defined = PhySize_Defined; 1293370b324cSopenharmony_ci OkPhySize = PhySize; 1294370b324cSopenharmony_ci } 1295370b324cSopenharmony_ci */ 1296370b324cSopenharmony_ci 1297370b324cSopenharmony_ci bool offsetDefined; 1298370b324cSopenharmony_ci RINOK(Archive_GetArcProp_Int(archive, kpidOffset, Offset, offsetDefined)) 1299370b324cSopenharmony_ci 1300370b324cSopenharmony_ci Int64 globalOffset = (Int64)startPos + Offset; 1301370b324cSopenharmony_ci AvailPhySize = (UInt64)((Int64)FileSize - globalOffset); 1302370b324cSopenharmony_ci if (PhySize_Defined) 1303370b324cSopenharmony_ci { 1304370b324cSopenharmony_ci UInt64 endPos = (UInt64)(globalOffset + (Int64)PhySize); 1305370b324cSopenharmony_ci if (endPos < FileSize) 1306370b324cSopenharmony_ci { 1307370b324cSopenharmony_ci AvailPhySize = PhySize; 1308370b324cSopenharmony_ci ErrorInfo.ThereIsTail = true; 1309370b324cSopenharmony_ci ErrorInfo.TailSize = FileSize - endPos; 1310370b324cSopenharmony_ci } 1311370b324cSopenharmony_ci else if (endPos > FileSize) 1312370b324cSopenharmony_ci ErrorInfo.UnexpecedEnd = true; 1313370b324cSopenharmony_ci } 1314370b324cSopenharmony_ci } 1315370b324cSopenharmony_ci 1316370b324cSopenharmony_ci return S_OK; 1317370b324cSopenharmony_ci} 1318370b324cSopenharmony_ci 1319370b324cSopenharmony_ci/* 1320370b324cSopenharmony_cistatic void PrintNumber(const char *s, int n) 1321370b324cSopenharmony_ci{ 1322370b324cSopenharmony_ci char temp[100]; 1323370b324cSopenharmony_ci sprintf(temp, "%s %d", s, n); 1324370b324cSopenharmony_ci // OutputDebugStringA(temp); 1325370b324cSopenharmony_ci printf(temp); 1326370b324cSopenharmony_ci} 1327370b324cSopenharmony_ci*/ 1328370b324cSopenharmony_ci 1329370b324cSopenharmony_ciHRESULT CArc::PrepareToOpen(const COpenOptions &op, unsigned formatIndex, CMyComPtr<IInArchive> &archive) 1330370b324cSopenharmony_ci{ 1331370b324cSopenharmony_ci // OutputDebugStringA("a1"); 1332370b324cSopenharmony_ci // PrintNumber("formatIndex", formatIndex); 1333370b324cSopenharmony_ci 1334370b324cSopenharmony_ci RINOK(op.codecs->CreateInArchive(formatIndex, archive)) 1335370b324cSopenharmony_ci // OutputDebugStringA("a2"); 1336370b324cSopenharmony_ci if (!archive) 1337370b324cSopenharmony_ci return S_OK; 1338370b324cSopenharmony_ci 1339370b324cSopenharmony_ci #ifdef Z7_EXTERNAL_CODECS 1340370b324cSopenharmony_ci if (op.codecs->NeedSetLibCodecs) 1341370b324cSopenharmony_ci { 1342370b324cSopenharmony_ci const CArcInfoEx &ai = op.codecs->Formats[formatIndex]; 1343370b324cSopenharmony_ci if (ai.LibIndex >= 0 ? 1344370b324cSopenharmony_ci !op.codecs->Libs[(unsigned)ai.LibIndex].SetCodecs : 1345370b324cSopenharmony_ci !op.codecs->Libs.IsEmpty()) 1346370b324cSopenharmony_ci { 1347370b324cSopenharmony_ci CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo; 1348370b324cSopenharmony_ci archive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); 1349370b324cSopenharmony_ci if (setCompressCodecsInfo) 1350370b324cSopenharmony_ci { 1351370b324cSopenharmony_ci RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(op.codecs)) 1352370b324cSopenharmony_ci } 1353370b324cSopenharmony_ci } 1354370b324cSopenharmony_ci } 1355370b324cSopenharmony_ci #endif 1356370b324cSopenharmony_ci 1357370b324cSopenharmony_ci 1358370b324cSopenharmony_ci #ifndef Z7_SFX 1359370b324cSopenharmony_ci 1360370b324cSopenharmony_ci const CArcInfoEx &ai = op.codecs->Formats[formatIndex]; 1361370b324cSopenharmony_ci 1362370b324cSopenharmony_ci // OutputDebugStringW(ai.Name); 1363370b324cSopenharmony_ci // OutputDebugStringA("a3"); 1364370b324cSopenharmony_ci 1365370b324cSopenharmony_ci if (ai.Flags_PreArc()) 1366370b324cSopenharmony_ci { 1367370b324cSopenharmony_ci /* we notify parsers that extract executables, that they don't need 1368370b324cSopenharmony_ci to open archive, if there is tail after executable (for SFX cases) */ 1369370b324cSopenharmony_ci CMyComPtr<IArchiveAllowTail> allowTail; 1370370b324cSopenharmony_ci archive.QueryInterface(IID_IArchiveAllowTail, (void **)&allowTail); 1371370b324cSopenharmony_ci if (allowTail) 1372370b324cSopenharmony_ci allowTail->AllowTail(BoolToInt(true)); 1373370b324cSopenharmony_ci } 1374370b324cSopenharmony_ci 1375370b324cSopenharmony_ci if (op.props) 1376370b324cSopenharmony_ci { 1377370b324cSopenharmony_ci /* 1378370b324cSopenharmony_ci FOR_VECTOR (y, op.props) 1379370b324cSopenharmony_ci { 1380370b324cSopenharmony_ci const COptionalOpenProperties &optProps = (*op.props)[y]; 1381370b324cSopenharmony_ci if (optProps.FormatName.IsEmpty() || optProps.FormatName.CompareNoCase(ai.Name) == 0) 1382370b324cSopenharmony_ci { 1383370b324cSopenharmony_ci RINOK(SetProperties(archive, optProps.Props)); 1384370b324cSopenharmony_ci break; 1385370b324cSopenharmony_ci } 1386370b324cSopenharmony_ci } 1387370b324cSopenharmony_ci */ 1388370b324cSopenharmony_ci RINOK(SetProperties(archive, *op.props)) 1389370b324cSopenharmony_ci } 1390370b324cSopenharmony_ci 1391370b324cSopenharmony_ci #endif 1392370b324cSopenharmony_ci return S_OK; 1393370b324cSopenharmony_ci} 1394370b324cSopenharmony_ci 1395370b324cSopenharmony_ci#ifndef Z7_SFX 1396370b324cSopenharmony_ci 1397370b324cSopenharmony_cistatic HRESULT ReadParseItemProps(IInArchive *archive, const CArcInfoEx &ai, NArchive::NParser::CParseItem &pi) 1398370b324cSopenharmony_ci{ 1399370b324cSopenharmony_ci pi.Extension = ai.GetMainExt(); 1400370b324cSopenharmony_ci pi.FileTime_Defined = false; 1401370b324cSopenharmony_ci pi.ArcType = ai.Name; 1402370b324cSopenharmony_ci 1403370b324cSopenharmony_ci RINOK(Archive_GetArcProp_Bool(archive, kpidIsNotArcType, pi.IsNotArcType)) 1404370b324cSopenharmony_ci 1405370b324cSopenharmony_ci // RINOK(Archive_GetArcProp_Bool(archive, kpidIsSelfExe, pi.IsSelfExe)); 1406370b324cSopenharmony_ci pi.IsSelfExe = ai.Flags_PreArc(); 1407370b324cSopenharmony_ci 1408370b324cSopenharmony_ci { 1409370b324cSopenharmony_ci NCOM::CPropVariant prop; 1410370b324cSopenharmony_ci RINOK(archive->GetArchiveProperty(kpidMTime, &prop)) 1411370b324cSopenharmony_ci if (prop.vt == VT_FILETIME) 1412370b324cSopenharmony_ci { 1413370b324cSopenharmony_ci pi.FileTime_Defined = true; 1414370b324cSopenharmony_ci pi.FileTime = prop.filetime; 1415370b324cSopenharmony_ci } 1416370b324cSopenharmony_ci } 1417370b324cSopenharmony_ci 1418370b324cSopenharmony_ci if (!pi.FileTime_Defined) 1419370b324cSopenharmony_ci { 1420370b324cSopenharmony_ci NCOM::CPropVariant prop; 1421370b324cSopenharmony_ci RINOK(archive->GetArchiveProperty(kpidCTime, &prop)) 1422370b324cSopenharmony_ci if (prop.vt == VT_FILETIME) 1423370b324cSopenharmony_ci { 1424370b324cSopenharmony_ci pi.FileTime_Defined = true; 1425370b324cSopenharmony_ci pi.FileTime = prop.filetime; 1426370b324cSopenharmony_ci } 1427370b324cSopenharmony_ci } 1428370b324cSopenharmony_ci 1429370b324cSopenharmony_ci { 1430370b324cSopenharmony_ci NCOM::CPropVariant prop; 1431370b324cSopenharmony_ci RINOK(archive->GetArchiveProperty(kpidName, &prop)) 1432370b324cSopenharmony_ci if (prop.vt == VT_BSTR) 1433370b324cSopenharmony_ci { 1434370b324cSopenharmony_ci pi.Name.SetFromBstr(prop.bstrVal); 1435370b324cSopenharmony_ci pi.Extension.Empty(); 1436370b324cSopenharmony_ci } 1437370b324cSopenharmony_ci else 1438370b324cSopenharmony_ci { 1439370b324cSopenharmony_ci RINOK(archive->GetArchiveProperty(kpidExtension, &prop)) 1440370b324cSopenharmony_ci if (prop.vt == VT_BSTR) 1441370b324cSopenharmony_ci pi.Extension.SetFromBstr(prop.bstrVal); 1442370b324cSopenharmony_ci } 1443370b324cSopenharmony_ci } 1444370b324cSopenharmony_ci 1445370b324cSopenharmony_ci { 1446370b324cSopenharmony_ci NCOM::CPropVariant prop; 1447370b324cSopenharmony_ci RINOK(archive->GetArchiveProperty(kpidShortComment, &prop)) 1448370b324cSopenharmony_ci if (prop.vt == VT_BSTR) 1449370b324cSopenharmony_ci pi.Comment.SetFromBstr(prop.bstrVal); 1450370b324cSopenharmony_ci } 1451370b324cSopenharmony_ci 1452370b324cSopenharmony_ci 1453370b324cSopenharmony_ci UInt32 numItems; 1454370b324cSopenharmony_ci RINOK(archive->GetNumberOfItems(&numItems)) 1455370b324cSopenharmony_ci 1456370b324cSopenharmony_ci // pi.NumSubFiles = numItems; 1457370b324cSopenharmony_ci // RINOK(Archive_GetArcProp_UInt(archive, kpidUnpackSize, pi.UnpackSize, pi.UnpackSize_Defined)); 1458370b324cSopenharmony_ci // if (!pi.UnpackSize_Defined) 1459370b324cSopenharmony_ci { 1460370b324cSopenharmony_ci pi.NumSubFiles = 0; 1461370b324cSopenharmony_ci pi.NumSubDirs = 0; 1462370b324cSopenharmony_ci pi.UnpackSize = 0; 1463370b324cSopenharmony_ci for (UInt32 i = 0; i < numItems; i++) 1464370b324cSopenharmony_ci { 1465370b324cSopenharmony_ci UInt64 size = 0; 1466370b324cSopenharmony_ci bool defined = false; 1467370b324cSopenharmony_ci Archive_GetItem_Size(archive, i, size, defined); 1468370b324cSopenharmony_ci if (defined) 1469370b324cSopenharmony_ci { 1470370b324cSopenharmony_ci pi.UnpackSize_Defined = true; 1471370b324cSopenharmony_ci pi.UnpackSize += size; 1472370b324cSopenharmony_ci } 1473370b324cSopenharmony_ci 1474370b324cSopenharmony_ci bool isDir = false; 1475370b324cSopenharmony_ci Archive_IsItem_Dir(archive, i, isDir); 1476370b324cSopenharmony_ci if (isDir) 1477370b324cSopenharmony_ci pi.NumSubDirs++; 1478370b324cSopenharmony_ci else 1479370b324cSopenharmony_ci pi.NumSubFiles++; 1480370b324cSopenharmony_ci } 1481370b324cSopenharmony_ci if (pi.NumSubDirs != 0) 1482370b324cSopenharmony_ci pi.NumSubDirs_Defined = true; 1483370b324cSopenharmony_ci pi.NumSubFiles_Defined = true; 1484370b324cSopenharmony_ci } 1485370b324cSopenharmony_ci 1486370b324cSopenharmony_ci return S_OK; 1487370b324cSopenharmony_ci} 1488370b324cSopenharmony_ci 1489370b324cSopenharmony_ci#endif 1490370b324cSopenharmony_ci 1491370b324cSopenharmony_ciHRESULT CArc::CheckZerosTail(const COpenOptions &op, UInt64 offset) 1492370b324cSopenharmony_ci{ 1493370b324cSopenharmony_ci if (!op.stream) 1494370b324cSopenharmony_ci return S_OK; 1495370b324cSopenharmony_ci RINOK(InStream_SeekSet(op.stream, offset)) 1496370b324cSopenharmony_ci const UInt32 kBufSize = 1 << 11; 1497370b324cSopenharmony_ci Byte buf[kBufSize]; 1498370b324cSopenharmony_ci 1499370b324cSopenharmony_ci for (;;) 1500370b324cSopenharmony_ci { 1501370b324cSopenharmony_ci UInt32 processed = 0; 1502370b324cSopenharmony_ci RINOK(op.stream->Read(buf, kBufSize, &processed)) 1503370b324cSopenharmony_ci if (processed == 0) 1504370b324cSopenharmony_ci { 1505370b324cSopenharmony_ci // ErrorInfo.NonZerosTail = false; 1506370b324cSopenharmony_ci ErrorInfo.IgnoreTail = true; 1507370b324cSopenharmony_ci return S_OK; 1508370b324cSopenharmony_ci } 1509370b324cSopenharmony_ci for (size_t i = 0; i < processed; i++) 1510370b324cSopenharmony_ci { 1511370b324cSopenharmony_ci if (buf[i] != 0) 1512370b324cSopenharmony_ci { 1513370b324cSopenharmony_ci // ErrorInfo.IgnoreTail = false; 1514370b324cSopenharmony_ci // ErrorInfo.NonZerosTail = true; 1515370b324cSopenharmony_ci return S_OK; 1516370b324cSopenharmony_ci } 1517370b324cSopenharmony_ci } 1518370b324cSopenharmony_ci } 1519370b324cSopenharmony_ci} 1520370b324cSopenharmony_ci 1521370b324cSopenharmony_ci 1522370b324cSopenharmony_ci 1523370b324cSopenharmony_ci#ifndef Z7_SFX 1524370b324cSopenharmony_ci 1525370b324cSopenharmony_ciZ7_CLASS_IMP_COM_2( 1526370b324cSopenharmony_ci CExtractCallback_To_OpenCallback 1527370b324cSopenharmony_ci , IArchiveExtractCallback 1528370b324cSopenharmony_ci , ICompressProgressInfo 1529370b324cSopenharmony_ci) 1530370b324cSopenharmony_ci Z7_IFACE_COM7_IMP(IProgress) 1531370b324cSopenharmony_cipublic: 1532370b324cSopenharmony_ci CMyComPtr<IArchiveOpenCallback> Callback; 1533370b324cSopenharmony_ci UInt64 Files; 1534370b324cSopenharmony_ci UInt64 Offset; 1535370b324cSopenharmony_ci 1536370b324cSopenharmony_ci void Init(IArchiveOpenCallback *callback) 1537370b324cSopenharmony_ci { 1538370b324cSopenharmony_ci Callback = callback; 1539370b324cSopenharmony_ci Files = 0; 1540370b324cSopenharmony_ci Offset = 0; 1541370b324cSopenharmony_ci } 1542370b324cSopenharmony_ci}; 1543370b324cSopenharmony_ci 1544370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallback_To_OpenCallback::SetTotal(UInt64 /* size */)) 1545370b324cSopenharmony_ci{ 1546370b324cSopenharmony_ci return S_OK; 1547370b324cSopenharmony_ci} 1548370b324cSopenharmony_ci 1549370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallback_To_OpenCallback::SetCompleted(const UInt64 * /* completeValue */)) 1550370b324cSopenharmony_ci{ 1551370b324cSopenharmony_ci return S_OK; 1552370b324cSopenharmony_ci} 1553370b324cSopenharmony_ci 1554370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallback_To_OpenCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */)) 1555370b324cSopenharmony_ci{ 1556370b324cSopenharmony_ci if (Callback) 1557370b324cSopenharmony_ci { 1558370b324cSopenharmony_ci UInt64 value = Offset; 1559370b324cSopenharmony_ci if (inSize) 1560370b324cSopenharmony_ci value += *inSize; 1561370b324cSopenharmony_ci return Callback->SetCompleted(&Files, &value); 1562370b324cSopenharmony_ci } 1563370b324cSopenharmony_ci return S_OK; 1564370b324cSopenharmony_ci} 1565370b324cSopenharmony_ci 1566370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallback_To_OpenCallback::GetStream(UInt32 /* index */, ISequentialOutStream **outStream, Int32 /* askExtractMode */)) 1567370b324cSopenharmony_ci{ 1568370b324cSopenharmony_ci *outStream = NULL; 1569370b324cSopenharmony_ci return S_OK; 1570370b324cSopenharmony_ci} 1571370b324cSopenharmony_ci 1572370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallback_To_OpenCallback::PrepareOperation(Int32 /* askExtractMode */)) 1573370b324cSopenharmony_ci{ 1574370b324cSopenharmony_ci return S_OK; 1575370b324cSopenharmony_ci} 1576370b324cSopenharmony_ci 1577370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallback_To_OpenCallback::SetOperationResult(Int32 /* operationResult */)) 1578370b324cSopenharmony_ci{ 1579370b324cSopenharmony_ci return S_OK; 1580370b324cSopenharmony_ci} 1581370b324cSopenharmony_ci 1582370b324cSopenharmony_ci 1583370b324cSopenharmony_cistatic HRESULT OpenArchiveSpec(IInArchive *archive, bool needPhySize, 1584370b324cSopenharmony_ci IInStream *stream, const UInt64 *maxCheckStartPosition, 1585370b324cSopenharmony_ci IArchiveOpenCallback *openCallback, 1586370b324cSopenharmony_ci IArchiveExtractCallback *extractCallback) 1587370b324cSopenharmony_ci{ 1588370b324cSopenharmony_ci /* 1589370b324cSopenharmony_ci if (needPhySize) 1590370b324cSopenharmony_ci { 1591370b324cSopenharmony_ci Z7_DECL_CMyComPtr_QI_FROM( 1592370b324cSopenharmony_ci IArchiveOpen2, 1593370b324cSopenharmony_ci open2, archive) 1594370b324cSopenharmony_ci if (open2) 1595370b324cSopenharmony_ci return open2->ArcOpen2(stream, kOpenFlags_RealPhySize, openCallback); 1596370b324cSopenharmony_ci } 1597370b324cSopenharmony_ci */ 1598370b324cSopenharmony_ci RINOK(archive->Open(stream, maxCheckStartPosition, openCallback)) 1599370b324cSopenharmony_ci if (needPhySize) 1600370b324cSopenharmony_ci { 1601370b324cSopenharmony_ci bool phySize_Defined = false; 1602370b324cSopenharmony_ci UInt64 phySize = 0; 1603370b324cSopenharmony_ci RINOK(Archive_GetArcProp_UInt(archive, kpidPhySize, phySize, phySize_Defined)) 1604370b324cSopenharmony_ci if (phySize_Defined) 1605370b324cSopenharmony_ci return S_OK; 1606370b324cSopenharmony_ci 1607370b324cSopenharmony_ci bool phySizeCantBeDetected = false; 1608370b324cSopenharmony_ci RINOK(Archive_GetArcProp_Bool(archive, kpidPhySizeCantBeDetected, phySizeCantBeDetected)) 1609370b324cSopenharmony_ci 1610370b324cSopenharmony_ci if (!phySizeCantBeDetected) 1611370b324cSopenharmony_ci { 1612370b324cSopenharmony_ci PRF(printf("\n-- !phySize_Defined after Open, call archive->Extract()")); 1613370b324cSopenharmony_ci // It's for bzip2/gz and some xz archives, where Open operation doesn't know phySize. 1614370b324cSopenharmony_ci // But the Handler will know phySize after full archive testing. 1615370b324cSopenharmony_ci RINOK(archive->Extract(NULL, (UInt32)(Int32)-1, BoolToInt(true), extractCallback)) 1616370b324cSopenharmony_ci PRF(printf("\n-- OK")); 1617370b324cSopenharmony_ci } 1618370b324cSopenharmony_ci } 1619370b324cSopenharmony_ci return S_OK; 1620370b324cSopenharmony_ci} 1621370b324cSopenharmony_ci 1622370b324cSopenharmony_ci 1623370b324cSopenharmony_ci 1624370b324cSopenharmony_cistatic int FindFormatForArchiveType(CCodecs *codecs, CIntVector orderIndices, const char *name) 1625370b324cSopenharmony_ci{ 1626370b324cSopenharmony_ci FOR_VECTOR (i, orderIndices) 1627370b324cSopenharmony_ci { 1628370b324cSopenharmony_ci int oi = orderIndices[i]; 1629370b324cSopenharmony_ci if (oi >= 0) 1630370b324cSopenharmony_ci if (StringsAreEqualNoCase_Ascii(codecs->Formats[(unsigned)oi].Name, name)) 1631370b324cSopenharmony_ci return (int)i; 1632370b324cSopenharmony_ci } 1633370b324cSopenharmony_ci return -1; 1634370b324cSopenharmony_ci} 1635370b324cSopenharmony_ci 1636370b324cSopenharmony_ci#endif 1637370b324cSopenharmony_ci 1638370b324cSopenharmony_ciHRESULT CArc::OpenStream2(const COpenOptions &op) 1639370b324cSopenharmony_ci{ 1640370b324cSopenharmony_ci // fprintf(stdout, "\nOpen: %S", Path); fflush(stdout); 1641370b324cSopenharmony_ci 1642370b324cSopenharmony_ci Archive.Release(); 1643370b324cSopenharmony_ci GetRawProps.Release(); 1644370b324cSopenharmony_ci GetRootProps.Release(); 1645370b324cSopenharmony_ci 1646370b324cSopenharmony_ci ErrorInfo.ClearErrors(); 1647370b324cSopenharmony_ci ErrorInfo.ErrorFormatIndex = -1; 1648370b324cSopenharmony_ci 1649370b324cSopenharmony_ci IsParseArc = false; 1650370b324cSopenharmony_ci ArcStreamOffset = 0; 1651370b324cSopenharmony_ci 1652370b324cSopenharmony_ci // OutputDebugStringA("1"); 1653370b324cSopenharmony_ci // OutputDebugStringW(Path); 1654370b324cSopenharmony_ci 1655370b324cSopenharmony_ci const UString fileName = ExtractFileNameFromPath(Path); 1656370b324cSopenharmony_ci UString extension; 1657370b324cSopenharmony_ci { 1658370b324cSopenharmony_ci const int dotPos = fileName.ReverseFind_Dot(); 1659370b324cSopenharmony_ci if (dotPos >= 0) 1660370b324cSopenharmony_ci extension = fileName.Ptr((unsigned)(dotPos + 1)); 1661370b324cSopenharmony_ci } 1662370b324cSopenharmony_ci 1663370b324cSopenharmony_ci CIntVector orderIndices; 1664370b324cSopenharmony_ci 1665370b324cSopenharmony_ci bool searchMarkerInHandler = false; 1666370b324cSopenharmony_ci #ifdef Z7_SFX 1667370b324cSopenharmony_ci searchMarkerInHandler = true; 1668370b324cSopenharmony_ci #endif 1669370b324cSopenharmony_ci 1670370b324cSopenharmony_ci CBoolArr isMainFormatArr(op.codecs->Formats.Size()); 1671370b324cSopenharmony_ci { 1672370b324cSopenharmony_ci FOR_VECTOR(i, op.codecs->Formats) 1673370b324cSopenharmony_ci isMainFormatArr[i] = false; 1674370b324cSopenharmony_ci } 1675370b324cSopenharmony_ci 1676370b324cSopenharmony_ci const UInt64 maxStartOffset = 1677370b324cSopenharmony_ci op.openType.MaxStartOffset_Defined ? 1678370b324cSopenharmony_ci op.openType.MaxStartOffset : 1679370b324cSopenharmony_ci kMaxCheckStartPosition; 1680370b324cSopenharmony_ci 1681370b324cSopenharmony_ci #ifndef Z7_SFX 1682370b324cSopenharmony_ci bool isUnknownExt = false; 1683370b324cSopenharmony_ci #endif 1684370b324cSopenharmony_ci 1685370b324cSopenharmony_ci #ifndef Z7_SFX 1686370b324cSopenharmony_ci bool isForced = false; 1687370b324cSopenharmony_ci #endif 1688370b324cSopenharmony_ci 1689370b324cSopenharmony_ci unsigned numMainTypes = 0; 1690370b324cSopenharmony_ci const int formatIndex = op.openType.FormatIndex; 1691370b324cSopenharmony_ci 1692370b324cSopenharmony_ci if (formatIndex >= 0) 1693370b324cSopenharmony_ci { 1694370b324cSopenharmony_ci #ifndef Z7_SFX 1695370b324cSopenharmony_ci isForced = true; 1696370b324cSopenharmony_ci #endif 1697370b324cSopenharmony_ci orderIndices.Add(formatIndex); 1698370b324cSopenharmony_ci numMainTypes = 1; 1699370b324cSopenharmony_ci isMainFormatArr[(unsigned)formatIndex] = true; 1700370b324cSopenharmony_ci 1701370b324cSopenharmony_ci searchMarkerInHandler = true; 1702370b324cSopenharmony_ci } 1703370b324cSopenharmony_ci else 1704370b324cSopenharmony_ci { 1705370b324cSopenharmony_ci unsigned numFinded = 0; 1706370b324cSopenharmony_ci #ifndef Z7_SFX 1707370b324cSopenharmony_ci bool isPrearcExt = false; 1708370b324cSopenharmony_ci #endif 1709370b324cSopenharmony_ci 1710370b324cSopenharmony_ci { 1711370b324cSopenharmony_ci #ifndef Z7_SFX 1712370b324cSopenharmony_ci 1713370b324cSopenharmony_ci bool isZip = false; 1714370b324cSopenharmony_ci bool isRar = false; 1715370b324cSopenharmony_ci 1716370b324cSopenharmony_ci const wchar_t c = extension[0]; 1717370b324cSopenharmony_ci if (c == 'z' || c == 'Z' || c == 'r' || c == 'R') 1718370b324cSopenharmony_ci { 1719370b324cSopenharmony_ci bool isNumber = false; 1720370b324cSopenharmony_ci for (unsigned k = 1;; k++) 1721370b324cSopenharmony_ci { 1722370b324cSopenharmony_ci const wchar_t d = extension[k]; 1723370b324cSopenharmony_ci if (d == 0) 1724370b324cSopenharmony_ci break; 1725370b324cSopenharmony_ci if (d < '0' || d > '9') 1726370b324cSopenharmony_ci { 1727370b324cSopenharmony_ci isNumber = false; 1728370b324cSopenharmony_ci break; 1729370b324cSopenharmony_ci } 1730370b324cSopenharmony_ci isNumber = true; 1731370b324cSopenharmony_ci } 1732370b324cSopenharmony_ci if (isNumber) 1733370b324cSopenharmony_ci { 1734370b324cSopenharmony_ci if (c == 'z' || c == 'Z') 1735370b324cSopenharmony_ci isZip = true; 1736370b324cSopenharmony_ci else 1737370b324cSopenharmony_ci isRar = true; 1738370b324cSopenharmony_ci } 1739370b324cSopenharmony_ci } 1740370b324cSopenharmony_ci 1741370b324cSopenharmony_ci #endif 1742370b324cSopenharmony_ci 1743370b324cSopenharmony_ci FOR_VECTOR (i, op.codecs->Formats) 1744370b324cSopenharmony_ci { 1745370b324cSopenharmony_ci const CArcInfoEx &ai = op.codecs->Formats[i]; 1746370b324cSopenharmony_ci 1747370b324cSopenharmony_ci if (IgnoreSplit || !op.openType.CanReturnArc) 1748370b324cSopenharmony_ci if (ai.Is_Split()) 1749370b324cSopenharmony_ci continue; 1750370b324cSopenharmony_ci if (op.excludedFormats->FindInSorted((int)i) >= 0) 1751370b324cSopenharmony_ci continue; 1752370b324cSopenharmony_ci 1753370b324cSopenharmony_ci #ifndef Z7_SFX 1754370b324cSopenharmony_ci if (IsPreArcFormat(ai)) 1755370b324cSopenharmony_ci isPrearcExt = true; 1756370b324cSopenharmony_ci #endif 1757370b324cSopenharmony_ci 1758370b324cSopenharmony_ci if (ai.FindExtension(extension) >= 0 1759370b324cSopenharmony_ci #ifndef Z7_SFX 1760370b324cSopenharmony_ci || (isZip && ai.Is_Zip()) 1761370b324cSopenharmony_ci || (isRar && ai.Is_Rar()) 1762370b324cSopenharmony_ci #endif 1763370b324cSopenharmony_ci ) 1764370b324cSopenharmony_ci { 1765370b324cSopenharmony_ci // PrintNumber("orderIndices.Insert", i); 1766370b324cSopenharmony_ci orderIndices.Insert(numFinded++, (int)i); 1767370b324cSopenharmony_ci isMainFormatArr[i] = true; 1768370b324cSopenharmony_ci } 1769370b324cSopenharmony_ci else 1770370b324cSopenharmony_ci orderIndices.Add((int)i); 1771370b324cSopenharmony_ci } 1772370b324cSopenharmony_ci } 1773370b324cSopenharmony_ci 1774370b324cSopenharmony_ci if (!op.stream) 1775370b324cSopenharmony_ci { 1776370b324cSopenharmony_ci if (numFinded != 1) 1777370b324cSopenharmony_ci return E_NOTIMPL; 1778370b324cSopenharmony_ci orderIndices.DeleteFrom(1); 1779370b324cSopenharmony_ci } 1780370b324cSopenharmony_ci // PrintNumber("numFinded", numFinded ); 1781370b324cSopenharmony_ci 1782370b324cSopenharmony_ci /* 1783370b324cSopenharmony_ci if (op.openOnlySpecifiedByExtension) 1784370b324cSopenharmony_ci { 1785370b324cSopenharmony_ci if (numFinded != 0 && !IsExeExt(extension)) 1786370b324cSopenharmony_ci orderIndices.DeleteFrom(numFinded); 1787370b324cSopenharmony_ci } 1788370b324cSopenharmony_ci */ 1789370b324cSopenharmony_ci 1790370b324cSopenharmony_ci #ifndef Z7_SFX 1791370b324cSopenharmony_ci 1792370b324cSopenharmony_ci if (op.stream && orderIndices.Size() >= 2) 1793370b324cSopenharmony_ci { 1794370b324cSopenharmony_ci RINOK(InStream_SeekToBegin(op.stream)) 1795370b324cSopenharmony_ci CByteBuffer byteBuffer; 1796370b324cSopenharmony_ci CIntVector orderIndices2; 1797370b324cSopenharmony_ci if (numFinded == 0 || IsExeExt(extension)) 1798370b324cSopenharmony_ci { 1799370b324cSopenharmony_ci // signature search was here 1800370b324cSopenharmony_ci } 1801370b324cSopenharmony_ci else if (extension.IsEqualTo("000") || extension.IsEqualTo("001")) 1802370b324cSopenharmony_ci { 1803370b324cSopenharmony_ci const int i = FindFormatForArchiveType(op.codecs, orderIndices, "rar"); 1804370b324cSopenharmony_ci if (i >= 0) 1805370b324cSopenharmony_ci { 1806370b324cSopenharmony_ci const size_t kBufSize = (1 << 10); 1807370b324cSopenharmony_ci byteBuffer.Alloc(kBufSize); 1808370b324cSopenharmony_ci size_t processedSize = kBufSize; 1809370b324cSopenharmony_ci RINOK(ReadStream(op.stream, byteBuffer, &processedSize)) 1810370b324cSopenharmony_ci if (processedSize >= 16) 1811370b324cSopenharmony_ci { 1812370b324cSopenharmony_ci const Byte *buf = byteBuffer; 1813370b324cSopenharmony_ci const Byte kRarHeader[] = { 0x52 , 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00 }; 1814370b324cSopenharmony_ci if (TestSignature(buf, kRarHeader, 7) && buf[9] == 0x73 && (buf[10] & 1) != 0) 1815370b324cSopenharmony_ci { 1816370b324cSopenharmony_ci orderIndices2.Add(orderIndices[(unsigned)i]); 1817370b324cSopenharmony_ci orderIndices[(unsigned)i] = -1; 1818370b324cSopenharmony_ci if (i >= (int)numFinded) 1819370b324cSopenharmony_ci numFinded++; 1820370b324cSopenharmony_ci } 1821370b324cSopenharmony_ci } 1822370b324cSopenharmony_ci } 1823370b324cSopenharmony_ci } 1824370b324cSopenharmony_ci else 1825370b324cSopenharmony_ci { 1826370b324cSopenharmony_ci const size_t kBufSize = (1 << 10); 1827370b324cSopenharmony_ci byteBuffer.Alloc(kBufSize); 1828370b324cSopenharmony_ci size_t processedSize = kBufSize; 1829370b324cSopenharmony_ci RINOK(ReadStream(op.stream, byteBuffer, &processedSize)) 1830370b324cSopenharmony_ci if (processedSize == 0) 1831370b324cSopenharmony_ci return S_FALSE; 1832370b324cSopenharmony_ci 1833370b324cSopenharmony_ci /* 1834370b324cSopenharmony_ci check type order: 1835370b324cSopenharmony_ci 0) matched_extension && Backward 1836370b324cSopenharmony_ci 1) matched_extension && (no_signuature || SignatureOffset != 0) 1837370b324cSopenharmony_ci 2) matched_extension && (matched_signature) 1838370b324cSopenharmony_ci // 3) no signuature 1839370b324cSopenharmony_ci // 4) matched signuature 1840370b324cSopenharmony_ci */ 1841370b324cSopenharmony_ci // we move index from orderIndices to orderIndices2 for priority handlers. 1842370b324cSopenharmony_ci 1843370b324cSopenharmony_ci for (unsigned i = 0; i < numFinded; i++) 1844370b324cSopenharmony_ci { 1845370b324cSopenharmony_ci const int index = orderIndices[i]; 1846370b324cSopenharmony_ci if (index < 0) 1847370b324cSopenharmony_ci continue; 1848370b324cSopenharmony_ci const CArcInfoEx &ai = op.codecs->Formats[(unsigned)index]; 1849370b324cSopenharmony_ci if (ai.Flags_BackwardOpen()) 1850370b324cSopenharmony_ci { 1851370b324cSopenharmony_ci // backward doesn't need start signatures 1852370b324cSopenharmony_ci orderIndices2.Add(index); 1853370b324cSopenharmony_ci orderIndices[i] = -1; 1854370b324cSopenharmony_ci } 1855370b324cSopenharmony_ci } 1856370b324cSopenharmony_ci 1857370b324cSopenharmony_ci MakeCheckOrder(op.codecs, orderIndices, numFinded, orderIndices2, NULL, 0); 1858370b324cSopenharmony_ci MakeCheckOrder(op.codecs, orderIndices, numFinded, orderIndices2, byteBuffer, processedSize); 1859370b324cSopenharmony_ci // MakeCheckOrder(op.codecs, orderIndices, orderIndices.Size(), orderIndices2, NULL, 0); 1860370b324cSopenharmony_ci // MakeCheckOrder(op.codecs, orderIndices, orderIndices.Size(), orderIndices2, byteBuffer, processedSize); 1861370b324cSopenharmony_ci } 1862370b324cSopenharmony_ci 1863370b324cSopenharmony_ci FOR_VECTOR (i, orderIndices) 1864370b324cSopenharmony_ci { 1865370b324cSopenharmony_ci const int val = orderIndices[i]; 1866370b324cSopenharmony_ci if (val != -1) 1867370b324cSopenharmony_ci orderIndices2.Add(val); 1868370b324cSopenharmony_ci } 1869370b324cSopenharmony_ci orderIndices = orderIndices2; 1870370b324cSopenharmony_ci } 1871370b324cSopenharmony_ci 1872370b324cSopenharmony_ci if (orderIndices.Size() >= 2) 1873370b324cSopenharmony_ci { 1874370b324cSopenharmony_ci const int iIso = FindFormatForArchiveType(op.codecs, orderIndices, "iso"); 1875370b324cSopenharmony_ci const int iUdf = FindFormatForArchiveType(op.codecs, orderIndices, "udf"); 1876370b324cSopenharmony_ci if (iUdf > iIso && iIso >= 0) 1877370b324cSopenharmony_ci { 1878370b324cSopenharmony_ci const int isoIndex = orderIndices[(unsigned)iIso]; 1879370b324cSopenharmony_ci const int udfIndex = orderIndices[(unsigned)iUdf]; 1880370b324cSopenharmony_ci orderIndices[(unsigned)iUdf] = isoIndex; 1881370b324cSopenharmony_ci orderIndices[(unsigned)iIso] = udfIndex; 1882370b324cSopenharmony_ci } 1883370b324cSopenharmony_ci } 1884370b324cSopenharmony_ci 1885370b324cSopenharmony_ci numMainTypes = numFinded; 1886370b324cSopenharmony_ci isUnknownExt = (numMainTypes == 0) || isPrearcExt; 1887370b324cSopenharmony_ci 1888370b324cSopenharmony_ci #else // Z7_SFX 1889370b324cSopenharmony_ci 1890370b324cSopenharmony_ci numMainTypes = orderIndices.Size(); 1891370b324cSopenharmony_ci 1892370b324cSopenharmony_ci // we need correct numMainTypes for mutlivolume SFX (if some volume is missing) 1893370b324cSopenharmony_ci if (numFinded != 0) 1894370b324cSopenharmony_ci numMainTypes = numFinded; 1895370b324cSopenharmony_ci 1896370b324cSopenharmony_ci #endif 1897370b324cSopenharmony_ci } 1898370b324cSopenharmony_ci 1899370b324cSopenharmony_ci UInt64 fileSize = 0; 1900370b324cSopenharmony_ci if (op.stream) 1901370b324cSopenharmony_ci { 1902370b324cSopenharmony_ci RINOK(InStream_GetSize_SeekToBegin(op.stream, fileSize)) 1903370b324cSopenharmony_ci } 1904370b324cSopenharmony_ci FileSize = fileSize; 1905370b324cSopenharmony_ci 1906370b324cSopenharmony_ci 1907370b324cSopenharmony_ci #ifndef Z7_SFX 1908370b324cSopenharmony_ci 1909370b324cSopenharmony_ci CBoolArr skipFrontalFormat(op.codecs->Formats.Size()); 1910370b324cSopenharmony_ci { 1911370b324cSopenharmony_ci FOR_VECTOR(i, op.codecs->Formats) 1912370b324cSopenharmony_ci skipFrontalFormat[i] = false; 1913370b324cSopenharmony_ci } 1914370b324cSopenharmony_ci 1915370b324cSopenharmony_ci #endif 1916370b324cSopenharmony_ci 1917370b324cSopenharmony_ci const COpenType &mode = op.openType; 1918370b324cSopenharmony_ci 1919370b324cSopenharmony_ci 1920370b324cSopenharmony_ci 1921370b324cSopenharmony_ci 1922370b324cSopenharmony_ci 1923370b324cSopenharmony_ci if (mode.CanReturnArc) 1924370b324cSopenharmony_ci { 1925370b324cSopenharmony_ci // ---------- OPEN main type by extenssion ---------- 1926370b324cSopenharmony_ci 1927370b324cSopenharmony_ci unsigned numCheckTypes = orderIndices.Size(); 1928370b324cSopenharmony_ci if (formatIndex >= 0) 1929370b324cSopenharmony_ci numCheckTypes = numMainTypes; 1930370b324cSopenharmony_ci 1931370b324cSopenharmony_ci for (unsigned i = 0; i < numCheckTypes; i++) 1932370b324cSopenharmony_ci { 1933370b324cSopenharmony_ci FormatIndex = orderIndices[i]; 1934370b324cSopenharmony_ci 1935370b324cSopenharmony_ci // orderIndices[] item cannot be negative here 1936370b324cSopenharmony_ci 1937370b324cSopenharmony_ci bool exactOnly = false; 1938370b324cSopenharmony_ci 1939370b324cSopenharmony_ci #ifndef Z7_SFX 1940370b324cSopenharmony_ci 1941370b324cSopenharmony_ci const CArcInfoEx &ai = op.codecs->Formats[(unsigned)FormatIndex]; 1942370b324cSopenharmony_ci // OutputDebugStringW(ai.Name); 1943370b324cSopenharmony_ci if (i >= numMainTypes) 1944370b324cSopenharmony_ci { 1945370b324cSopenharmony_ci // here we allow mismatched extension only for backward handlers 1946370b324cSopenharmony_ci if (!ai.Flags_BackwardOpen() 1947370b324cSopenharmony_ci // && !ai.Flags_PureStartOpen() 1948370b324cSopenharmony_ci ) 1949370b324cSopenharmony_ci continue; 1950370b324cSopenharmony_ci exactOnly = true; 1951370b324cSopenharmony_ci } 1952370b324cSopenharmony_ci 1953370b324cSopenharmony_ci #endif 1954370b324cSopenharmony_ci 1955370b324cSopenharmony_ci // Some handlers do not set total bytes. So we set it here 1956370b324cSopenharmony_ci if (op.callback) 1957370b324cSopenharmony_ci RINOK(op.callback->SetTotal(NULL, &fileSize)) 1958370b324cSopenharmony_ci 1959370b324cSopenharmony_ci if (op.stream) 1960370b324cSopenharmony_ci { 1961370b324cSopenharmony_ci RINOK(InStream_SeekToBegin(op.stream)) 1962370b324cSopenharmony_ci } 1963370b324cSopenharmony_ci 1964370b324cSopenharmony_ci CMyComPtr<IInArchive> archive; 1965370b324cSopenharmony_ci 1966370b324cSopenharmony_ci RINOK(PrepareToOpen(op, (unsigned)FormatIndex, archive)) 1967370b324cSopenharmony_ci if (!archive) 1968370b324cSopenharmony_ci continue; 1969370b324cSopenharmony_ci 1970370b324cSopenharmony_ci HRESULT result; 1971370b324cSopenharmony_ci if (op.stream) 1972370b324cSopenharmony_ci { 1973370b324cSopenharmony_ci UInt64 searchLimit = (!exactOnly && searchMarkerInHandler) ? maxStartOffset: 0; 1974370b324cSopenharmony_ci result = archive->Open(op.stream, &searchLimit, op.callback); 1975370b324cSopenharmony_ci } 1976370b324cSopenharmony_ci else 1977370b324cSopenharmony_ci { 1978370b324cSopenharmony_ci CMyComPtr<IArchiveOpenSeq> openSeq; 1979370b324cSopenharmony_ci archive.QueryInterface(IID_IArchiveOpenSeq, (void **)&openSeq); 1980370b324cSopenharmony_ci if (!openSeq) 1981370b324cSopenharmony_ci return E_NOTIMPL; 1982370b324cSopenharmony_ci result = openSeq->OpenSeq(op.seqStream); 1983370b324cSopenharmony_ci } 1984370b324cSopenharmony_ci 1985370b324cSopenharmony_ci RINOK(ReadBasicProps(archive, 0, result)) 1986370b324cSopenharmony_ci 1987370b324cSopenharmony_ci if (result == S_FALSE) 1988370b324cSopenharmony_ci { 1989370b324cSopenharmony_ci bool isArc = ErrorInfo.IsArc_After_NonOpen(); 1990370b324cSopenharmony_ci 1991370b324cSopenharmony_ci #ifndef Z7_SFX 1992370b324cSopenharmony_ci // if it's archive, we allow another open attempt for parser 1993370b324cSopenharmony_ci if (!mode.CanReturnParser || !isArc) 1994370b324cSopenharmony_ci skipFrontalFormat[(unsigned)FormatIndex] = true; 1995370b324cSopenharmony_ci #endif 1996370b324cSopenharmony_ci 1997370b324cSopenharmony_ci if (exactOnly) 1998370b324cSopenharmony_ci continue; 1999370b324cSopenharmony_ci 2000370b324cSopenharmony_ci if (i == 0 && numMainTypes == 1) 2001370b324cSopenharmony_ci { 2002370b324cSopenharmony_ci // we set NonOpenErrorInfo, only if there is only one main format (defined by extension). 2003370b324cSopenharmony_ci ErrorInfo.ErrorFormatIndex = FormatIndex; 2004370b324cSopenharmony_ci NonOpen_ErrorInfo = ErrorInfo; 2005370b324cSopenharmony_ci 2006370b324cSopenharmony_ci if (!mode.CanReturnParser && isArc) 2007370b324cSopenharmony_ci { 2008370b324cSopenharmony_ci // if (formatIndex < 0 && !searchMarkerInHandler) 2009370b324cSopenharmony_ci { 2010370b324cSopenharmony_ci // if bad archive was detected, we don't need additional open attempts 2011370b324cSopenharmony_ci #ifndef Z7_SFX 2012370b324cSopenharmony_ci if (!IsPreArcFormat(ai) /* || !mode.SkipSfxStub */) 2013370b324cSopenharmony_ci #endif 2014370b324cSopenharmony_ci return S_FALSE; 2015370b324cSopenharmony_ci } 2016370b324cSopenharmony_ci } 2017370b324cSopenharmony_ci } 2018370b324cSopenharmony_ci 2019370b324cSopenharmony_ci /* 2020370b324cSopenharmony_ci #ifndef Z7_SFX 2021370b324cSopenharmony_ci if (IsExeExt(extension) || ai.Flags_PreArc()) 2022370b324cSopenharmony_ci { 2023370b324cSopenharmony_ci // openOnlyFullArc = false; 2024370b324cSopenharmony_ci // canReturnTailArc = true; 2025370b324cSopenharmony_ci // limitSignatureSearch = true; 2026370b324cSopenharmony_ci } 2027370b324cSopenharmony_ci #endif 2028370b324cSopenharmony_ci */ 2029370b324cSopenharmony_ci 2030370b324cSopenharmony_ci continue; 2031370b324cSopenharmony_ci } 2032370b324cSopenharmony_ci 2033370b324cSopenharmony_ci RINOK(result) 2034370b324cSopenharmony_ci 2035370b324cSopenharmony_ci #ifndef Z7_SFX 2036370b324cSopenharmony_ci 2037370b324cSopenharmony_ci bool isMainFormat = isMainFormatArr[(unsigned)FormatIndex]; 2038370b324cSopenharmony_ci const COpenSpecFlags &specFlags = mode.GetSpec(isForced, isMainFormat, isUnknownExt); 2039370b324cSopenharmony_ci 2040370b324cSopenharmony_ci bool thereIsTail = ErrorInfo.ThereIsTail; 2041370b324cSopenharmony_ci if (thereIsTail && mode.ZerosTailIsAllowed) 2042370b324cSopenharmony_ci { 2043370b324cSopenharmony_ci RINOK(CheckZerosTail(op, (UInt64)(Offset + (Int64)PhySize))) 2044370b324cSopenharmony_ci if (ErrorInfo.IgnoreTail) 2045370b324cSopenharmony_ci thereIsTail = false; 2046370b324cSopenharmony_ci } 2047370b324cSopenharmony_ci 2048370b324cSopenharmony_ci if (Offset > 0) 2049370b324cSopenharmony_ci { 2050370b324cSopenharmony_ci if (exactOnly 2051370b324cSopenharmony_ci || !searchMarkerInHandler 2052370b324cSopenharmony_ci || !specFlags.CanReturn_NonStart() 2053370b324cSopenharmony_ci || (mode.MaxStartOffset_Defined && (UInt64)Offset > mode.MaxStartOffset)) 2054370b324cSopenharmony_ci continue; 2055370b324cSopenharmony_ci } 2056370b324cSopenharmony_ci if (thereIsTail) 2057370b324cSopenharmony_ci { 2058370b324cSopenharmony_ci if (Offset > 0) 2059370b324cSopenharmony_ci { 2060370b324cSopenharmony_ci if (!specFlags.CanReturnMid) 2061370b324cSopenharmony_ci continue; 2062370b324cSopenharmony_ci } 2063370b324cSopenharmony_ci else if (!specFlags.CanReturnFrontal) 2064370b324cSopenharmony_ci continue; 2065370b324cSopenharmony_ci } 2066370b324cSopenharmony_ci 2067370b324cSopenharmony_ci if (Offset > 0 || thereIsTail) 2068370b324cSopenharmony_ci { 2069370b324cSopenharmony_ci if (formatIndex < 0) 2070370b324cSopenharmony_ci { 2071370b324cSopenharmony_ci if (IsPreArcFormat(ai)) 2072370b324cSopenharmony_ci { 2073370b324cSopenharmony_ci // openOnlyFullArc = false; 2074370b324cSopenharmony_ci // canReturnTailArc = true; 2075370b324cSopenharmony_ci /* 2076370b324cSopenharmony_ci if (mode.SkipSfxStub) 2077370b324cSopenharmony_ci limitSignatureSearch = true; 2078370b324cSopenharmony_ci */ 2079370b324cSopenharmony_ci // if (mode.SkipSfxStub) 2080370b324cSopenharmony_ci { 2081370b324cSopenharmony_ci // skipFrontalFormat[FormatIndex] = true; 2082370b324cSopenharmony_ci continue; 2083370b324cSopenharmony_ci } 2084370b324cSopenharmony_ci } 2085370b324cSopenharmony_ci } 2086370b324cSopenharmony_ci } 2087370b324cSopenharmony_ci 2088370b324cSopenharmony_ci #endif 2089370b324cSopenharmony_ci 2090370b324cSopenharmony_ci Archive = archive; 2091370b324cSopenharmony_ci return S_OK; 2092370b324cSopenharmony_ci } 2093370b324cSopenharmony_ci } 2094370b324cSopenharmony_ci 2095370b324cSopenharmony_ci 2096370b324cSopenharmony_ci 2097370b324cSopenharmony_ci #ifndef Z7_SFX 2098370b324cSopenharmony_ci 2099370b324cSopenharmony_ci if (!op.stream) 2100370b324cSopenharmony_ci return S_FALSE; 2101370b324cSopenharmony_ci 2102370b324cSopenharmony_ci if (formatIndex >= 0 && !mode.CanReturnParser) 2103370b324cSopenharmony_ci { 2104370b324cSopenharmony_ci if (mode.MaxStartOffset_Defined) 2105370b324cSopenharmony_ci { 2106370b324cSopenharmony_ci if (mode.MaxStartOffset == 0) 2107370b324cSopenharmony_ci return S_FALSE; 2108370b324cSopenharmony_ci } 2109370b324cSopenharmony_ci else 2110370b324cSopenharmony_ci { 2111370b324cSopenharmony_ci const CArcInfoEx &ai = op.codecs->Formats[(unsigned)formatIndex]; 2112370b324cSopenharmony_ci if (ai.FindExtension(extension) >= 0) 2113370b324cSopenharmony_ci { 2114370b324cSopenharmony_ci if (ai.Flags_FindSignature() && searchMarkerInHandler) 2115370b324cSopenharmony_ci return S_FALSE; 2116370b324cSopenharmony_ci } 2117370b324cSopenharmony_ci } 2118370b324cSopenharmony_ci } 2119370b324cSopenharmony_ci 2120370b324cSopenharmony_ci NArchive::NParser::CHandler *handlerSpec = new NArchive::NParser::CHandler; 2121370b324cSopenharmony_ci CMyComPtr<IInArchive> handler = handlerSpec; 2122370b324cSopenharmony_ci 2123370b324cSopenharmony_ci CExtractCallback_To_OpenCallback *extractCallback_To_OpenCallback_Spec = new CExtractCallback_To_OpenCallback; 2124370b324cSopenharmony_ci CMyComPtr<IArchiveExtractCallback> extractCallback_To_OpenCallback = extractCallback_To_OpenCallback_Spec; 2125370b324cSopenharmony_ci extractCallback_To_OpenCallback_Spec->Init(op.callback); 2126370b324cSopenharmony_ci 2127370b324cSopenharmony_ci { 2128370b324cSopenharmony_ci // ---------- Check all possible START archives ---------- 2129370b324cSopenharmony_ci // this code is better for full file archives than Parser's code. 2130370b324cSopenharmony_ci 2131370b324cSopenharmony_ci CByteBuffer byteBuffer; 2132370b324cSopenharmony_ci bool endOfFile = false; 2133370b324cSopenharmony_ci size_t processedSize; 2134370b324cSopenharmony_ci { 2135370b324cSopenharmony_ci size_t bufSize = 1 << 20; // it must be larger than max signature offset or IsArcFunc offset ((1 << 19) + x for UDF) 2136370b324cSopenharmony_ci if (bufSize > fileSize) 2137370b324cSopenharmony_ci { 2138370b324cSopenharmony_ci bufSize = (size_t)fileSize; 2139370b324cSopenharmony_ci endOfFile = true; 2140370b324cSopenharmony_ci } 2141370b324cSopenharmony_ci byteBuffer.Alloc(bufSize); 2142370b324cSopenharmony_ci RINOK(InStream_SeekToBegin(op.stream)) 2143370b324cSopenharmony_ci processedSize = bufSize; 2144370b324cSopenharmony_ci RINOK(ReadStream(op.stream, byteBuffer, &processedSize)) 2145370b324cSopenharmony_ci if (processedSize == 0) 2146370b324cSopenharmony_ci return S_FALSE; 2147370b324cSopenharmony_ci if (processedSize < bufSize) 2148370b324cSopenharmony_ci endOfFile = true; 2149370b324cSopenharmony_ci } 2150370b324cSopenharmony_ci CUIntVector sortedFormats; 2151370b324cSopenharmony_ci 2152370b324cSopenharmony_ci unsigned i; 2153370b324cSopenharmony_ci 2154370b324cSopenharmony_ci int splitIndex = -1; 2155370b324cSopenharmony_ci 2156370b324cSopenharmony_ci for (i = 0; i < orderIndices.Size(); i++) 2157370b324cSopenharmony_ci { 2158370b324cSopenharmony_ci // orderIndices[] item cannot be negative here 2159370b324cSopenharmony_ci unsigned form = (unsigned)orderIndices[i]; 2160370b324cSopenharmony_ci if (skipFrontalFormat[form]) 2161370b324cSopenharmony_ci continue; 2162370b324cSopenharmony_ci 2163370b324cSopenharmony_ci const CArcInfoEx &ai = op.codecs->Formats[form]; 2164370b324cSopenharmony_ci 2165370b324cSopenharmony_ci if (ai.Is_Split()) 2166370b324cSopenharmony_ci { 2167370b324cSopenharmony_ci splitIndex = (int)form; 2168370b324cSopenharmony_ci continue; 2169370b324cSopenharmony_ci } 2170370b324cSopenharmony_ci 2171370b324cSopenharmony_ci if (ai.Flags_ByExtOnlyOpen()) 2172370b324cSopenharmony_ci continue; 2173370b324cSopenharmony_ci 2174370b324cSopenharmony_ci if (ai.IsArcFunc) 2175370b324cSopenharmony_ci { 2176370b324cSopenharmony_ci UInt32 isArcRes = ai.IsArcFunc(byteBuffer, processedSize); 2177370b324cSopenharmony_ci if (isArcRes == k_IsArc_Res_NO) 2178370b324cSopenharmony_ci continue; 2179370b324cSopenharmony_ci if (isArcRes == k_IsArc_Res_NEED_MORE && endOfFile) 2180370b324cSopenharmony_ci continue; 2181370b324cSopenharmony_ci // if (isArcRes == k_IsArc_Res_YES_LOW_PROB) continue; 2182370b324cSopenharmony_ci sortedFormats.Insert(0, form); 2183370b324cSopenharmony_ci continue; 2184370b324cSopenharmony_ci } 2185370b324cSopenharmony_ci 2186370b324cSopenharmony_ci const bool isNewStyleSignature = IsNewStyleSignature(ai); 2187370b324cSopenharmony_ci bool needCheck = !isNewStyleSignature 2188370b324cSopenharmony_ci || ai.Signatures.IsEmpty() 2189370b324cSopenharmony_ci || ai.Flags_PureStartOpen() 2190370b324cSopenharmony_ci || ai.Flags_StartOpen() 2191370b324cSopenharmony_ci || ai.Flags_BackwardOpen(); 2192370b324cSopenharmony_ci 2193370b324cSopenharmony_ci if (isNewStyleSignature && !ai.Signatures.IsEmpty()) 2194370b324cSopenharmony_ci { 2195370b324cSopenharmony_ci unsigned k; 2196370b324cSopenharmony_ci for (k = 0; k < ai.Signatures.Size(); k++) 2197370b324cSopenharmony_ci { 2198370b324cSopenharmony_ci const CByteBuffer &sig = ai.Signatures[k]; 2199370b324cSopenharmony_ci if (processedSize < ai.SignatureOffset + sig.Size()) 2200370b324cSopenharmony_ci { 2201370b324cSopenharmony_ci if (!endOfFile) 2202370b324cSopenharmony_ci needCheck = true; 2203370b324cSopenharmony_ci } 2204370b324cSopenharmony_ci else if (TestSignature(sig, byteBuffer + ai.SignatureOffset, sig.Size())) 2205370b324cSopenharmony_ci break; 2206370b324cSopenharmony_ci } 2207370b324cSopenharmony_ci if (k != ai.Signatures.Size()) 2208370b324cSopenharmony_ci { 2209370b324cSopenharmony_ci sortedFormats.Insert(0, form); 2210370b324cSopenharmony_ci continue; 2211370b324cSopenharmony_ci } 2212370b324cSopenharmony_ci } 2213370b324cSopenharmony_ci if (needCheck) 2214370b324cSopenharmony_ci sortedFormats.Add(form); 2215370b324cSopenharmony_ci } 2216370b324cSopenharmony_ci 2217370b324cSopenharmony_ci if (splitIndex >= 0) 2218370b324cSopenharmony_ci sortedFormats.Insert(0, (unsigned)splitIndex); 2219370b324cSopenharmony_ci 2220370b324cSopenharmony_ci for (i = 0; i < sortedFormats.Size(); i++) 2221370b324cSopenharmony_ci { 2222370b324cSopenharmony_ci FormatIndex = (int)sortedFormats[i]; 2223370b324cSopenharmony_ci const CArcInfoEx &ai = op.codecs->Formats[(unsigned)FormatIndex]; 2224370b324cSopenharmony_ci 2225370b324cSopenharmony_ci if (op.callback) 2226370b324cSopenharmony_ci RINOK(op.callback->SetTotal(NULL, &fileSize)) 2227370b324cSopenharmony_ci 2228370b324cSopenharmony_ci RINOK(InStream_SeekToBegin(op.stream)) 2229370b324cSopenharmony_ci 2230370b324cSopenharmony_ci CMyComPtr<IInArchive> archive; 2231370b324cSopenharmony_ci RINOK(PrepareToOpen(op, (unsigned)FormatIndex, archive)) 2232370b324cSopenharmony_ci if (!archive) 2233370b324cSopenharmony_ci continue; 2234370b324cSopenharmony_ci 2235370b324cSopenharmony_ci PRF(printf("\nSorted Open %S", (const wchar_t *)ai.Name)); 2236370b324cSopenharmony_ci HRESULT result; 2237370b324cSopenharmony_ci { 2238370b324cSopenharmony_ci UInt64 searchLimit = 0; 2239370b324cSopenharmony_ci /* 2240370b324cSopenharmony_ci if (mode.CanReturnArc) 2241370b324cSopenharmony_ci result = archive->Open(op.stream, &searchLimit, op.callback); 2242370b324cSopenharmony_ci else 2243370b324cSopenharmony_ci */ 2244370b324cSopenharmony_ci // if (!CanReturnArc), it's ParserMode, and we need phy size 2245370b324cSopenharmony_ci result = OpenArchiveSpec(archive, 2246370b324cSopenharmony_ci !mode.CanReturnArc, // needPhySize 2247370b324cSopenharmony_ci op.stream, &searchLimit, op.callback, extractCallback_To_OpenCallback); 2248370b324cSopenharmony_ci } 2249370b324cSopenharmony_ci 2250370b324cSopenharmony_ci if (result == S_FALSE) 2251370b324cSopenharmony_ci { 2252370b324cSopenharmony_ci skipFrontalFormat[(unsigned)FormatIndex] = true; 2253370b324cSopenharmony_ci // FIXME: maybe we must use LenIsUnknown. 2254370b324cSopenharmony_ci // printf(" OpenForSize Error"); 2255370b324cSopenharmony_ci continue; 2256370b324cSopenharmony_ci } 2257370b324cSopenharmony_ci RINOK(result) 2258370b324cSopenharmony_ci 2259370b324cSopenharmony_ci RINOK(ReadBasicProps(archive, 0, result)) 2260370b324cSopenharmony_ci 2261370b324cSopenharmony_ci if (Offset > 0) 2262370b324cSopenharmony_ci { 2263370b324cSopenharmony_ci continue; // good handler doesn't return such Offset > 0 2264370b324cSopenharmony_ci // but there are some cases like false prefixed PK00 archive, when 2265370b324cSopenharmony_ci // we can support it? 2266370b324cSopenharmony_ci } 2267370b324cSopenharmony_ci 2268370b324cSopenharmony_ci NArchive::NParser::CParseItem pi; 2269370b324cSopenharmony_ci pi.Offset = (UInt64)Offset; 2270370b324cSopenharmony_ci pi.Size = AvailPhySize; 2271370b324cSopenharmony_ci 2272370b324cSopenharmony_ci // bool needScan = false; 2273370b324cSopenharmony_ci 2274370b324cSopenharmony_ci if (!PhySize_Defined) 2275370b324cSopenharmony_ci { 2276370b324cSopenharmony_ci // it's for Z format 2277370b324cSopenharmony_ci pi.LenIsUnknown = true; 2278370b324cSopenharmony_ci // needScan = true; 2279370b324cSopenharmony_ci // phySize = arcRem; 2280370b324cSopenharmony_ci // nextNeedCheckStartOpen = false; 2281370b324cSopenharmony_ci } 2282370b324cSopenharmony_ci 2283370b324cSopenharmony_ci /* 2284370b324cSopenharmony_ci if (OkPhySize_Defined) 2285370b324cSopenharmony_ci pi.OkSize = pi.OkPhySize; 2286370b324cSopenharmony_ci else 2287370b324cSopenharmony_ci pi.OkSize = pi.Size; 2288370b324cSopenharmony_ci */ 2289370b324cSopenharmony_ci 2290370b324cSopenharmony_ci pi.NormalizeOffset(); 2291370b324cSopenharmony_ci // printf(" phySize = %8d", (unsigned)phySize); 2292370b324cSopenharmony_ci 2293370b324cSopenharmony_ci 2294370b324cSopenharmony_ci if (mode.CanReturnArc) 2295370b324cSopenharmony_ci { 2296370b324cSopenharmony_ci const bool isMainFormat = isMainFormatArr[(unsigned)FormatIndex]; 2297370b324cSopenharmony_ci const COpenSpecFlags &specFlags = mode.GetSpec(isForced, isMainFormat, isUnknownExt); 2298370b324cSopenharmony_ci bool openCur = false; 2299370b324cSopenharmony_ci 2300370b324cSopenharmony_ci if (!ErrorInfo.ThereIsTail) 2301370b324cSopenharmony_ci openCur = true; 2302370b324cSopenharmony_ci else 2303370b324cSopenharmony_ci { 2304370b324cSopenharmony_ci if (mode.ZerosTailIsAllowed) 2305370b324cSopenharmony_ci { 2306370b324cSopenharmony_ci RINOK(CheckZerosTail(op, (UInt64)(Offset + (Int64)PhySize))) 2307370b324cSopenharmony_ci if (ErrorInfo.IgnoreTail) 2308370b324cSopenharmony_ci openCur = true; 2309370b324cSopenharmony_ci } 2310370b324cSopenharmony_ci if (!openCur) 2311370b324cSopenharmony_ci { 2312370b324cSopenharmony_ci openCur = specFlags.CanReturnFrontal; 2313370b324cSopenharmony_ci if (formatIndex < 0) // format is not forced 2314370b324cSopenharmony_ci { 2315370b324cSopenharmony_ci if (IsPreArcFormat(ai)) 2316370b324cSopenharmony_ci { 2317370b324cSopenharmony_ci // if (mode.SkipSfxStub) 2318370b324cSopenharmony_ci { 2319370b324cSopenharmony_ci openCur = false; 2320370b324cSopenharmony_ci } 2321370b324cSopenharmony_ci } 2322370b324cSopenharmony_ci } 2323370b324cSopenharmony_ci } 2324370b324cSopenharmony_ci } 2325370b324cSopenharmony_ci 2326370b324cSopenharmony_ci if (openCur) 2327370b324cSopenharmony_ci { 2328370b324cSopenharmony_ci InStream = op.stream; 2329370b324cSopenharmony_ci Archive = archive; 2330370b324cSopenharmony_ci return S_OK; 2331370b324cSopenharmony_ci } 2332370b324cSopenharmony_ci } 2333370b324cSopenharmony_ci 2334370b324cSopenharmony_ci skipFrontalFormat[(unsigned)FormatIndex] = true; 2335370b324cSopenharmony_ci 2336370b324cSopenharmony_ci 2337370b324cSopenharmony_ci // if (!mode.CanReturnArc) 2338370b324cSopenharmony_ci /* 2339370b324cSopenharmony_ci if (!ErrorInfo.ThereIsTail) 2340370b324cSopenharmony_ci continue; 2341370b324cSopenharmony_ci */ 2342370b324cSopenharmony_ci if (pi.Offset == 0 && !pi.LenIsUnknown && pi.Size >= FileSize) 2343370b324cSopenharmony_ci continue; 2344370b324cSopenharmony_ci 2345370b324cSopenharmony_ci // printf("\nAdd offset = %d", (int)pi.Offset); 2346370b324cSopenharmony_ci RINOK(ReadParseItemProps(archive, ai, pi)) 2347370b324cSopenharmony_ci handlerSpec->AddItem(pi); 2348370b324cSopenharmony_ci } 2349370b324cSopenharmony_ci } 2350370b324cSopenharmony_ci 2351370b324cSopenharmony_ci 2352370b324cSopenharmony_ci 2353370b324cSopenharmony_ci 2354370b324cSopenharmony_ci 2355370b324cSopenharmony_ci // ---------- PARSER ---------- 2356370b324cSopenharmony_ci 2357370b324cSopenharmony_ci CUIntVector arc2sig; // formatIndex to signatureIndex 2358370b324cSopenharmony_ci CUIntVector sig2arc; // signatureIndex to formatIndex; 2359370b324cSopenharmony_ci { 2360370b324cSopenharmony_ci unsigned sum = 0; 2361370b324cSopenharmony_ci FOR_VECTOR (i, op.codecs->Formats) 2362370b324cSopenharmony_ci { 2363370b324cSopenharmony_ci arc2sig.Add(sum); 2364370b324cSopenharmony_ci const CObjectVector<CByteBuffer> &sigs = op.codecs->Formats[i].Signatures; 2365370b324cSopenharmony_ci sum += sigs.Size(); 2366370b324cSopenharmony_ci FOR_VECTOR (k, sigs) 2367370b324cSopenharmony_ci sig2arc.Add(i); 2368370b324cSopenharmony_ci } 2369370b324cSopenharmony_ci } 2370370b324cSopenharmony_ci 2371370b324cSopenharmony_ci { 2372370b324cSopenharmony_ci const size_t kBeforeSize = 1 << 16; 2373370b324cSopenharmony_ci const size_t kAfterSize = 1 << 20; 2374370b324cSopenharmony_ci const size_t kBufSize = 1 << 22; // it must be more than kBeforeSize + kAfterSize 2375370b324cSopenharmony_ci 2376370b324cSopenharmony_ci const UInt32 kNumVals = (UInt32)1 << (kNumHashBytes * 8); 2377370b324cSopenharmony_ci CByteArr hashBuffer(kNumVals); 2378370b324cSopenharmony_ci Byte *hash = hashBuffer; 2379370b324cSopenharmony_ci memset(hash, 0xFF, kNumVals); 2380370b324cSopenharmony_ci Byte prevs[256]; 2381370b324cSopenharmony_ci memset(prevs, 0xFF, sizeof(prevs)); 2382370b324cSopenharmony_ci if (sig2arc.Size() >= 0xFF) 2383370b324cSopenharmony_ci return S_FALSE; 2384370b324cSopenharmony_ci 2385370b324cSopenharmony_ci CUIntVector difficultFormats; 2386370b324cSopenharmony_ci CBoolArr difficultBools(256); 2387370b324cSopenharmony_ci { 2388370b324cSopenharmony_ci for (unsigned i = 0; i < 256; i++) 2389370b324cSopenharmony_ci difficultBools[i] = false; 2390370b324cSopenharmony_ci } 2391370b324cSopenharmony_ci 2392370b324cSopenharmony_ci bool thereAreHandlersForSearch = false; 2393370b324cSopenharmony_ci 2394370b324cSopenharmony_ci // UInt32 maxSignatureEnd = 0; 2395370b324cSopenharmony_ci 2396370b324cSopenharmony_ci FOR_VECTOR (i, orderIndices) 2397370b324cSopenharmony_ci { 2398370b324cSopenharmony_ci int index = orderIndices[i]; 2399370b324cSopenharmony_ci if (index < 0) 2400370b324cSopenharmony_ci continue; 2401370b324cSopenharmony_ci const CArcInfoEx &ai = op.codecs->Formats[(unsigned)index]; 2402370b324cSopenharmony_ci if (ai.Flags_ByExtOnlyOpen()) 2403370b324cSopenharmony_ci continue; 2404370b324cSopenharmony_ci bool isDifficult = false; 2405370b324cSopenharmony_ci // if (ai.Version < 0x91F) // we don't use parser with old DLL (before 9.31) 2406370b324cSopenharmony_ci if (!ai.NewInterface) 2407370b324cSopenharmony_ci isDifficult = true; 2408370b324cSopenharmony_ci else 2409370b324cSopenharmony_ci { 2410370b324cSopenharmony_ci if (ai.Flags_StartOpen()) 2411370b324cSopenharmony_ci isDifficult = true; 2412370b324cSopenharmony_ci FOR_VECTOR (k, ai.Signatures) 2413370b324cSopenharmony_ci { 2414370b324cSopenharmony_ci const CByteBuffer &sig = ai.Signatures[k]; 2415370b324cSopenharmony_ci /* 2416370b324cSopenharmony_ci UInt32 signatureEnd = ai.SignatureOffset + (UInt32)sig.Size(); 2417370b324cSopenharmony_ci if (maxSignatureEnd < signatureEnd) 2418370b324cSopenharmony_ci maxSignatureEnd = signatureEnd; 2419370b324cSopenharmony_ci */ 2420370b324cSopenharmony_ci if (sig.Size() < kNumHashBytes) 2421370b324cSopenharmony_ci { 2422370b324cSopenharmony_ci isDifficult = true; 2423370b324cSopenharmony_ci continue; 2424370b324cSopenharmony_ci } 2425370b324cSopenharmony_ci thereAreHandlersForSearch = true; 2426370b324cSopenharmony_ci UInt32 v = HASH_VAL(sig); 2427370b324cSopenharmony_ci unsigned sigIndex = arc2sig[(unsigned)index] + k; 2428370b324cSopenharmony_ci prevs[sigIndex] = hash[v]; 2429370b324cSopenharmony_ci hash[v] = (Byte)sigIndex; 2430370b324cSopenharmony_ci } 2431370b324cSopenharmony_ci } 2432370b324cSopenharmony_ci if (isDifficult) 2433370b324cSopenharmony_ci { 2434370b324cSopenharmony_ci difficultFormats.Add((unsigned)index); 2435370b324cSopenharmony_ci difficultBools[(unsigned)index] = true; 2436370b324cSopenharmony_ci } 2437370b324cSopenharmony_ci } 2438370b324cSopenharmony_ci 2439370b324cSopenharmony_ci if (!thereAreHandlersForSearch) 2440370b324cSopenharmony_ci { 2441370b324cSopenharmony_ci // openOnlyFullArc = true; 2442370b324cSopenharmony_ci // canReturnTailArc = true; 2443370b324cSopenharmony_ci } 2444370b324cSopenharmony_ci 2445370b324cSopenharmony_ci RINOK(InStream_SeekToBegin(op.stream)) 2446370b324cSopenharmony_ci 2447370b324cSopenharmony_ci CLimitedCachedInStream *limitedStreamSpec = new CLimitedCachedInStream; 2448370b324cSopenharmony_ci CMyComPtr<IInStream> limitedStream = limitedStreamSpec; 2449370b324cSopenharmony_ci limitedStreamSpec->SetStream(op.stream); 2450370b324cSopenharmony_ci 2451370b324cSopenharmony_ci CArchiveOpenCallback_Offset *openCallback_Offset_Spec = NULL; 2452370b324cSopenharmony_ci CMyComPtr<IArchiveOpenCallback> openCallback_Offset; 2453370b324cSopenharmony_ci if (op.callback) 2454370b324cSopenharmony_ci { 2455370b324cSopenharmony_ci openCallback_Offset_Spec = new CArchiveOpenCallback_Offset; 2456370b324cSopenharmony_ci openCallback_Offset = openCallback_Offset_Spec; 2457370b324cSopenharmony_ci openCallback_Offset_Spec->Callback = op.callback; 2458370b324cSopenharmony_ci openCallback_Offset_Spec->Callback.QueryInterface(IID_IArchiveOpenVolumeCallback, &openCallback_Offset_Spec->OpenVolumeCallback); 2459370b324cSopenharmony_ci #ifndef Z7_NO_CRYPTO 2460370b324cSopenharmony_ci openCallback_Offset_Spec->Callback.QueryInterface(IID_ICryptoGetTextPassword, &openCallback_Offset_Spec->GetTextPassword); 2461370b324cSopenharmony_ci #endif 2462370b324cSopenharmony_ci } 2463370b324cSopenharmony_ci 2464370b324cSopenharmony_ci if (op.callback) 2465370b324cSopenharmony_ci RINOK(op.callback->SetTotal(NULL, &fileSize)) 2466370b324cSopenharmony_ci 2467370b324cSopenharmony_ci CByteBuffer &byteBuffer = limitedStreamSpec->Buffer; 2468370b324cSopenharmony_ci byteBuffer.Alloc(kBufSize); 2469370b324cSopenharmony_ci 2470370b324cSopenharmony_ci UInt64 callbackPrev = 0; 2471370b324cSopenharmony_ci bool needCheckStartOpen = true; // = true, if we need to test all archives types for current pos. 2472370b324cSopenharmony_ci 2473370b324cSopenharmony_ci bool endOfFile = false; 2474370b324cSopenharmony_ci UInt64 bufPhyPos = 0; 2475370b324cSopenharmony_ci size_t bytesInBuf = 0; 2476370b324cSopenharmony_ci // UInt64 prevPos = 0; 2477370b324cSopenharmony_ci 2478370b324cSopenharmony_ci // ---------- Main Scan Loop ---------- 2479370b324cSopenharmony_ci 2480370b324cSopenharmony_ci UInt64 pos = 0; 2481370b324cSopenharmony_ci 2482370b324cSopenharmony_ci if (!mode.EachPos && handlerSpec->_items.Size() == 1) 2483370b324cSopenharmony_ci { 2484370b324cSopenharmony_ci NArchive::NParser::CParseItem &pi = handlerSpec->_items[0]; 2485370b324cSopenharmony_ci if (!pi.LenIsUnknown && pi.Offset == 0) 2486370b324cSopenharmony_ci pos = pi.Size; 2487370b324cSopenharmony_ci } 2488370b324cSopenharmony_ci 2489370b324cSopenharmony_ci for (;;) 2490370b324cSopenharmony_ci { 2491370b324cSopenharmony_ci // printf("\nPos = %d", (int)pos); 2492370b324cSopenharmony_ci UInt64 posInBuf = pos - bufPhyPos; 2493370b324cSopenharmony_ci 2494370b324cSopenharmony_ci // if (pos > ((UInt64)1 << 35)) break; 2495370b324cSopenharmony_ci 2496370b324cSopenharmony_ci if (!endOfFile) 2497370b324cSopenharmony_ci { 2498370b324cSopenharmony_ci if (bytesInBuf < kBufSize) 2499370b324cSopenharmony_ci { 2500370b324cSopenharmony_ci size_t processedSize = kBufSize - bytesInBuf; 2501370b324cSopenharmony_ci // printf("\nRead ask = %d", (unsigned)processedSize); 2502370b324cSopenharmony_ci UInt64 seekPos = bufPhyPos + bytesInBuf; 2503370b324cSopenharmony_ci RINOK(InStream_SeekSet(op.stream, bufPhyPos + bytesInBuf)) 2504370b324cSopenharmony_ci RINOK(ReadStream(op.stream, byteBuffer + bytesInBuf, &processedSize)) 2505370b324cSopenharmony_ci // printf(" processed = %d", (unsigned)processedSize); 2506370b324cSopenharmony_ci if (processedSize == 0) 2507370b324cSopenharmony_ci { 2508370b324cSopenharmony_ci fileSize = seekPos; 2509370b324cSopenharmony_ci endOfFile = true; 2510370b324cSopenharmony_ci } 2511370b324cSopenharmony_ci else 2512370b324cSopenharmony_ci { 2513370b324cSopenharmony_ci bytesInBuf += processedSize; 2514370b324cSopenharmony_ci limitedStreamSpec->SetCache(processedSize, (size_t)bufPhyPos); 2515370b324cSopenharmony_ci } 2516370b324cSopenharmony_ci continue; 2517370b324cSopenharmony_ci } 2518370b324cSopenharmony_ci 2519370b324cSopenharmony_ci if (bytesInBuf < posInBuf) 2520370b324cSopenharmony_ci { 2521370b324cSopenharmony_ci UInt64 skipSize = posInBuf - bytesInBuf; 2522370b324cSopenharmony_ci if (skipSize <= kBeforeSize) 2523370b324cSopenharmony_ci { 2524370b324cSopenharmony_ci size_t keepSize = (size_t)(kBeforeSize - skipSize); 2525370b324cSopenharmony_ci // printf("\nmemmove skip = %d", (int)keepSize); 2526370b324cSopenharmony_ci memmove(byteBuffer, byteBuffer + bytesInBuf - keepSize, keepSize); 2527370b324cSopenharmony_ci bytesInBuf = keepSize; 2528370b324cSopenharmony_ci bufPhyPos = pos - keepSize; 2529370b324cSopenharmony_ci continue; 2530370b324cSopenharmony_ci } 2531370b324cSopenharmony_ci // printf("\nSkip %d", (int)(skipSize - kBeforeSize)); 2532370b324cSopenharmony_ci // RINOK(op.stream->Seek(skipSize - kBeforeSize, STREAM_SEEK_CUR, NULL)); 2533370b324cSopenharmony_ci bytesInBuf = 0; 2534370b324cSopenharmony_ci bufPhyPos = pos - kBeforeSize; 2535370b324cSopenharmony_ci continue; 2536370b324cSopenharmony_ci } 2537370b324cSopenharmony_ci 2538370b324cSopenharmony_ci if (bytesInBuf - posInBuf < kAfterSize) 2539370b324cSopenharmony_ci { 2540370b324cSopenharmony_ci size_t beg = (size_t)posInBuf - kBeforeSize; 2541370b324cSopenharmony_ci // printf("\nmemmove for after beg = %d", (int)beg); 2542370b324cSopenharmony_ci memmove(byteBuffer, byteBuffer + beg, bytesInBuf - beg); 2543370b324cSopenharmony_ci bufPhyPos += beg; 2544370b324cSopenharmony_ci bytesInBuf -= beg; 2545370b324cSopenharmony_ci continue; 2546370b324cSopenharmony_ci } 2547370b324cSopenharmony_ci } 2548370b324cSopenharmony_ci 2549370b324cSopenharmony_ci if (bytesInBuf <= (size_t)posInBuf) 2550370b324cSopenharmony_ci break; 2551370b324cSopenharmony_ci 2552370b324cSopenharmony_ci bool useOffsetCallback = false; 2553370b324cSopenharmony_ci if (openCallback_Offset) 2554370b324cSopenharmony_ci { 2555370b324cSopenharmony_ci openCallback_Offset_Spec->Files = handlerSpec->_items.Size(); 2556370b324cSopenharmony_ci openCallback_Offset_Spec->Offset = pos; 2557370b324cSopenharmony_ci 2558370b324cSopenharmony_ci useOffsetCallback = (!op.openType.CanReturnArc || handlerSpec->_items.Size() > 1); 2559370b324cSopenharmony_ci 2560370b324cSopenharmony_ci if (pos >= callbackPrev + (1 << 23)) 2561370b324cSopenharmony_ci { 2562370b324cSopenharmony_ci RINOK(openCallback_Offset->SetCompleted(NULL, NULL)) 2563370b324cSopenharmony_ci callbackPrev = pos; 2564370b324cSopenharmony_ci } 2565370b324cSopenharmony_ci } 2566370b324cSopenharmony_ci 2567370b324cSopenharmony_ci { 2568370b324cSopenharmony_ci UInt64 endPos = bufPhyPos + bytesInBuf; 2569370b324cSopenharmony_ci if (fileSize < endPos) 2570370b324cSopenharmony_ci { 2571370b324cSopenharmony_ci FileSize = fileSize; // why ???? 2572370b324cSopenharmony_ci fileSize = endPos; 2573370b324cSopenharmony_ci } 2574370b324cSopenharmony_ci } 2575370b324cSopenharmony_ci 2576370b324cSopenharmony_ci const size_t availSize = bytesInBuf - (size_t)posInBuf; 2577370b324cSopenharmony_ci if (availSize < kNumHashBytes) 2578370b324cSopenharmony_ci break; 2579370b324cSopenharmony_ci size_t scanSize = availSize - 2580370b324cSopenharmony_ci ((availSize >= kAfterSize) ? kAfterSize : kNumHashBytes); 2581370b324cSopenharmony_ci 2582370b324cSopenharmony_ci { 2583370b324cSopenharmony_ci /* 2584370b324cSopenharmony_ci UInt64 scanLimit = openOnlyFullArc ? 2585370b324cSopenharmony_ci maxSignatureEnd : 2586370b324cSopenharmony_ci op.openType.ScanSize + maxSignatureEnd; 2587370b324cSopenharmony_ci */ 2588370b324cSopenharmony_ci if (!mode.CanReturnParser) 2589370b324cSopenharmony_ci { 2590370b324cSopenharmony_ci if (pos > maxStartOffset) 2591370b324cSopenharmony_ci break; 2592370b324cSopenharmony_ci UInt64 remScan = maxStartOffset - pos; 2593370b324cSopenharmony_ci if (scanSize > remScan) 2594370b324cSopenharmony_ci scanSize = (size_t)remScan; 2595370b324cSopenharmony_ci } 2596370b324cSopenharmony_ci } 2597370b324cSopenharmony_ci 2598370b324cSopenharmony_ci scanSize++; 2599370b324cSopenharmony_ci 2600370b324cSopenharmony_ci const Byte *buf = byteBuffer + (size_t)posInBuf; 2601370b324cSopenharmony_ci const Byte *bufLimit = buf + scanSize; 2602370b324cSopenharmony_ci size_t ppp = 0; 2603370b324cSopenharmony_ci 2604370b324cSopenharmony_ci if (!needCheckStartOpen) 2605370b324cSopenharmony_ci { 2606370b324cSopenharmony_ci for (; buf < bufLimit && hash[HASH_VAL(buf)] == 0xFF; buf++); 2607370b324cSopenharmony_ci ppp = (size_t)(buf - (byteBuffer + (size_t)posInBuf)); 2608370b324cSopenharmony_ci pos += ppp; 2609370b324cSopenharmony_ci if (buf == bufLimit) 2610370b324cSopenharmony_ci continue; 2611370b324cSopenharmony_ci } 2612370b324cSopenharmony_ci 2613370b324cSopenharmony_ci UInt32 v = HASH_VAL(buf); 2614370b324cSopenharmony_ci bool nextNeedCheckStartOpen = true; 2615370b324cSopenharmony_ci unsigned i = hash[v]; 2616370b324cSopenharmony_ci unsigned indexOfDifficult = 0; 2617370b324cSopenharmony_ci 2618370b324cSopenharmony_ci // ---------- Open Loop for Current Pos ---------- 2619370b324cSopenharmony_ci bool wasOpen = false; 2620370b324cSopenharmony_ci 2621370b324cSopenharmony_ci for (;;) 2622370b324cSopenharmony_ci { 2623370b324cSopenharmony_ci unsigned index; 2624370b324cSopenharmony_ci bool isDifficult; 2625370b324cSopenharmony_ci if (needCheckStartOpen && indexOfDifficult < difficultFormats.Size()) 2626370b324cSopenharmony_ci { 2627370b324cSopenharmony_ci index = difficultFormats[indexOfDifficult++]; 2628370b324cSopenharmony_ci isDifficult = true; 2629370b324cSopenharmony_ci } 2630370b324cSopenharmony_ci else 2631370b324cSopenharmony_ci { 2632370b324cSopenharmony_ci if (i == 0xFF) 2633370b324cSopenharmony_ci break; 2634370b324cSopenharmony_ci index = sig2arc[i]; 2635370b324cSopenharmony_ci unsigned sigIndex = i - arc2sig[index]; 2636370b324cSopenharmony_ci i = prevs[i]; 2637370b324cSopenharmony_ci if (needCheckStartOpen && difficultBools[index]) 2638370b324cSopenharmony_ci continue; 2639370b324cSopenharmony_ci const CArcInfoEx &ai = op.codecs->Formats[index]; 2640370b324cSopenharmony_ci 2641370b324cSopenharmony_ci if (pos < ai.SignatureOffset) 2642370b324cSopenharmony_ci continue; 2643370b324cSopenharmony_ci 2644370b324cSopenharmony_ci /* 2645370b324cSopenharmony_ci if (openOnlyFullArc) 2646370b324cSopenharmony_ci if (pos != ai.SignatureOffset) 2647370b324cSopenharmony_ci continue; 2648370b324cSopenharmony_ci */ 2649370b324cSopenharmony_ci 2650370b324cSopenharmony_ci const CByteBuffer &sig = ai.Signatures[sigIndex]; 2651370b324cSopenharmony_ci 2652370b324cSopenharmony_ci if (ppp + sig.Size() > availSize 2653370b324cSopenharmony_ci || !TestSignature(buf, sig, sig.Size())) 2654370b324cSopenharmony_ci continue; 2655370b324cSopenharmony_ci // printf("\nSignature OK: %10S %8x %5d", (const wchar_t *)ai.Name, (int)pos, (int)(pos - prevPos)); 2656370b324cSopenharmony_ci // prevPos = pos; 2657370b324cSopenharmony_ci isDifficult = false; 2658370b324cSopenharmony_ci } 2659370b324cSopenharmony_ci 2660370b324cSopenharmony_ci const CArcInfoEx &ai = op.codecs->Formats[index]; 2661370b324cSopenharmony_ci 2662370b324cSopenharmony_ci 2663370b324cSopenharmony_ci if ((isDifficult && pos == 0) || ai.SignatureOffset == pos) 2664370b324cSopenharmony_ci { 2665370b324cSopenharmony_ci // we don't check same archive second time */ 2666370b324cSopenharmony_ci if (skipFrontalFormat[index]) 2667370b324cSopenharmony_ci continue; 2668370b324cSopenharmony_ci } 2669370b324cSopenharmony_ci 2670370b324cSopenharmony_ci UInt64 startArcPos = pos; 2671370b324cSopenharmony_ci if (!isDifficult) 2672370b324cSopenharmony_ci { 2673370b324cSopenharmony_ci if (pos < ai.SignatureOffset) 2674370b324cSopenharmony_ci continue; 2675370b324cSopenharmony_ci startArcPos = pos - ai.SignatureOffset; 2676370b324cSopenharmony_ci /* 2677370b324cSopenharmony_ci // we don't need the check for Z files 2678370b324cSopenharmony_ci if (startArcPos < handlerSpec->GetLastEnd()) 2679370b324cSopenharmony_ci continue; 2680370b324cSopenharmony_ci */ 2681370b324cSopenharmony_ci } 2682370b324cSopenharmony_ci 2683370b324cSopenharmony_ci if (ai.IsArcFunc && startArcPos >= bufPhyPos) 2684370b324cSopenharmony_ci { 2685370b324cSopenharmony_ci const size_t offsetInBuf = (size_t)(startArcPos - bufPhyPos); 2686370b324cSopenharmony_ci if (offsetInBuf < bytesInBuf) 2687370b324cSopenharmony_ci { 2688370b324cSopenharmony_ci const UInt32 isArcRes = ai.IsArcFunc(byteBuffer + offsetInBuf, bytesInBuf - offsetInBuf); 2689370b324cSopenharmony_ci if (isArcRes == k_IsArc_Res_NO) 2690370b324cSopenharmony_ci continue; 2691370b324cSopenharmony_ci if (isArcRes == k_IsArc_Res_NEED_MORE && endOfFile) 2692370b324cSopenharmony_ci continue; 2693370b324cSopenharmony_ci /* 2694370b324cSopenharmony_ci if (isArcRes == k_IsArc_Res_YES_LOW_PROB) 2695370b324cSopenharmony_ci { 2696370b324cSopenharmony_ci // if (pos != ai.SignatureOffset) 2697370b324cSopenharmony_ci continue; 2698370b324cSopenharmony_ci } 2699370b324cSopenharmony_ci */ 2700370b324cSopenharmony_ci } 2701370b324cSopenharmony_ci // printf("\nIsArc OK: %S", (const wchar_t *)ai.Name); 2702370b324cSopenharmony_ci } 2703370b324cSopenharmony_ci 2704370b324cSopenharmony_ci PRF(printf("\npos = %9I64d : %S", pos, (const wchar_t *)ai.Name)); 2705370b324cSopenharmony_ci 2706370b324cSopenharmony_ci const bool isMainFormat = isMainFormatArr[index]; 2707370b324cSopenharmony_ci const COpenSpecFlags &specFlags = mode.GetSpec(isForced, isMainFormat, isUnknownExt); 2708370b324cSopenharmony_ci 2709370b324cSopenharmony_ci CMyComPtr<IInArchive> archive; 2710370b324cSopenharmony_ci RINOK(PrepareToOpen(op, index, archive)) 2711370b324cSopenharmony_ci if (!archive) 2712370b324cSopenharmony_ci return E_FAIL; 2713370b324cSopenharmony_ci 2714370b324cSopenharmony_ci // OutputDebugStringW(ai.Name); 2715370b324cSopenharmony_ci 2716370b324cSopenharmony_ci const UInt64 rem = fileSize - startArcPos; 2717370b324cSopenharmony_ci 2718370b324cSopenharmony_ci UInt64 arcStreamOffset = 0; 2719370b324cSopenharmony_ci 2720370b324cSopenharmony_ci if (ai.Flags_UseGlobalOffset()) 2721370b324cSopenharmony_ci { 2722370b324cSopenharmony_ci RINOK(limitedStreamSpec->InitAndSeek(0, fileSize)) 2723370b324cSopenharmony_ci RINOK(InStream_SeekSet(limitedStream, startArcPos)) 2724370b324cSopenharmony_ci } 2725370b324cSopenharmony_ci else 2726370b324cSopenharmony_ci { 2727370b324cSopenharmony_ci RINOK(limitedStreamSpec->InitAndSeek(startArcPos, rem)) 2728370b324cSopenharmony_ci arcStreamOffset = startArcPos; 2729370b324cSopenharmony_ci } 2730370b324cSopenharmony_ci 2731370b324cSopenharmony_ci UInt64 maxCheckStartPosition = 0; 2732370b324cSopenharmony_ci 2733370b324cSopenharmony_ci if (openCallback_Offset) 2734370b324cSopenharmony_ci { 2735370b324cSopenharmony_ci openCallback_Offset_Spec->Files = handlerSpec->_items.Size(); 2736370b324cSopenharmony_ci openCallback_Offset_Spec->Offset = startArcPos; 2737370b324cSopenharmony_ci } 2738370b324cSopenharmony_ci 2739370b324cSopenharmony_ci // HRESULT result = archive->Open(limitedStream, &maxCheckStartPosition, openCallback_Offset); 2740370b324cSopenharmony_ci extractCallback_To_OpenCallback_Spec->Files = 0; 2741370b324cSopenharmony_ci extractCallback_To_OpenCallback_Spec->Offset = startArcPos; 2742370b324cSopenharmony_ci 2743370b324cSopenharmony_ci HRESULT result = OpenArchiveSpec(archive, 2744370b324cSopenharmony_ci true, // needPhySize 2745370b324cSopenharmony_ci limitedStream, &maxCheckStartPosition, 2746370b324cSopenharmony_ci useOffsetCallback ? (IArchiveOpenCallback *)openCallback_Offset : (IArchiveOpenCallback *)op.callback, 2747370b324cSopenharmony_ci extractCallback_To_OpenCallback); 2748370b324cSopenharmony_ci 2749370b324cSopenharmony_ci RINOK(ReadBasicProps(archive, ai.Flags_UseGlobalOffset() ? 0 : startArcPos, result)) 2750370b324cSopenharmony_ci 2751370b324cSopenharmony_ci bool isOpen = false; 2752370b324cSopenharmony_ci 2753370b324cSopenharmony_ci if (result == S_FALSE) 2754370b324cSopenharmony_ci { 2755370b324cSopenharmony_ci if (!mode.CanReturnParser) 2756370b324cSopenharmony_ci { 2757370b324cSopenharmony_ci if (formatIndex < 0 && ErrorInfo.IsArc_After_NonOpen()) 2758370b324cSopenharmony_ci { 2759370b324cSopenharmony_ci ErrorInfo.ErrorFormatIndex = (int)index; 2760370b324cSopenharmony_ci NonOpen_ErrorInfo = ErrorInfo; 2761370b324cSopenharmony_ci // if archive was detected, we don't need additional open attempts 2762370b324cSopenharmony_ci return S_FALSE; 2763370b324cSopenharmony_ci } 2764370b324cSopenharmony_ci continue; 2765370b324cSopenharmony_ci } 2766370b324cSopenharmony_ci if (!ErrorInfo.IsArc_After_NonOpen() || !PhySize_Defined || PhySize == 0) 2767370b324cSopenharmony_ci continue; 2768370b324cSopenharmony_ci } 2769370b324cSopenharmony_ci else 2770370b324cSopenharmony_ci { 2771370b324cSopenharmony_ci if (PhySize_Defined && PhySize == 0) 2772370b324cSopenharmony_ci { 2773370b324cSopenharmony_ci PRF(printf(" phySize_Defined && PhySize == 0 ")); 2774370b324cSopenharmony_ci // we skip that epmty archive case with unusual unexpected (PhySize == 0) from Code function. 2775370b324cSopenharmony_ci continue; 2776370b324cSopenharmony_ci } 2777370b324cSopenharmony_ci isOpen = true; 2778370b324cSopenharmony_ci RINOK(result) 2779370b324cSopenharmony_ci PRF(printf(" OK ")); 2780370b324cSopenharmony_ci } 2781370b324cSopenharmony_ci 2782370b324cSopenharmony_ci // fprintf(stderr, "\n %8X %S", startArcPos, Path); 2783370b324cSopenharmony_ci // printf("\nOpen OK: %S", ai.Name); 2784370b324cSopenharmony_ci 2785370b324cSopenharmony_ci 2786370b324cSopenharmony_ci NArchive::NParser::CParseItem pi; 2787370b324cSopenharmony_ci pi.Offset = startArcPos; 2788370b324cSopenharmony_ci 2789370b324cSopenharmony_ci if (ai.Flags_UseGlobalOffset()) 2790370b324cSopenharmony_ci pi.Offset = (UInt64)Offset; 2791370b324cSopenharmony_ci else if (Offset != 0) 2792370b324cSopenharmony_ci return E_FAIL; 2793370b324cSopenharmony_ci 2794370b324cSopenharmony_ci const UInt64 arcRem = FileSize - pi.Offset; 2795370b324cSopenharmony_ci UInt64 phySize = arcRem; 2796370b324cSopenharmony_ci const bool phySize_Defined = PhySize_Defined; 2797370b324cSopenharmony_ci if (phySize_Defined) 2798370b324cSopenharmony_ci { 2799370b324cSopenharmony_ci if (pi.Offset + PhySize > FileSize) 2800370b324cSopenharmony_ci { 2801370b324cSopenharmony_ci // ErrorInfo.ThereIsTail = true; 2802370b324cSopenharmony_ci PhySize = FileSize - pi.Offset; 2803370b324cSopenharmony_ci } 2804370b324cSopenharmony_ci phySize = PhySize; 2805370b324cSopenharmony_ci } 2806370b324cSopenharmony_ci if (phySize == 0 || (UInt64)phySize > ((UInt64)1 << 63)) 2807370b324cSopenharmony_ci return E_FAIL; 2808370b324cSopenharmony_ci 2809370b324cSopenharmony_ci /* 2810370b324cSopenharmony_ci if (!ai.UseGlobalOffset) 2811370b324cSopenharmony_ci { 2812370b324cSopenharmony_ci if (phySize > arcRem) 2813370b324cSopenharmony_ci { 2814370b324cSopenharmony_ci ThereIsTail = true; 2815370b324cSopenharmony_ci phySize = arcRem; 2816370b324cSopenharmony_ci } 2817370b324cSopenharmony_ci } 2818370b324cSopenharmony_ci */ 2819370b324cSopenharmony_ci 2820370b324cSopenharmony_ci bool needScan = false; 2821370b324cSopenharmony_ci 2822370b324cSopenharmony_ci 2823370b324cSopenharmony_ci if (isOpen && !phySize_Defined) 2824370b324cSopenharmony_ci { 2825370b324cSopenharmony_ci // it's for Z format, or bzip2,gz,xz with phySize that was not detected 2826370b324cSopenharmony_ci pi.LenIsUnknown = true; 2827370b324cSopenharmony_ci needScan = true; 2828370b324cSopenharmony_ci phySize = arcRem; 2829370b324cSopenharmony_ci nextNeedCheckStartOpen = false; 2830370b324cSopenharmony_ci } 2831370b324cSopenharmony_ci 2832370b324cSopenharmony_ci pi.Size = phySize; 2833370b324cSopenharmony_ci /* 2834370b324cSopenharmony_ci if (OkPhySize_Defined) 2835370b324cSopenharmony_ci pi.OkSize = OkPhySize; 2836370b324cSopenharmony_ci */ 2837370b324cSopenharmony_ci pi.NormalizeOffset(); 2838370b324cSopenharmony_ci // printf(" phySize = %8d", (unsigned)phySize); 2839370b324cSopenharmony_ci 2840370b324cSopenharmony_ci /* 2841370b324cSopenharmony_ci if (needSkipFullArc) 2842370b324cSopenharmony_ci if (pi.Offset == 0 && phySize_Defined && pi.Size >= fileSize) 2843370b324cSopenharmony_ci continue; 2844370b324cSopenharmony_ci */ 2845370b324cSopenharmony_ci if (pi.Offset == 0 && !pi.LenIsUnknown && pi.Size >= FileSize) 2846370b324cSopenharmony_ci { 2847370b324cSopenharmony_ci // it's possible for dmg archives 2848370b324cSopenharmony_ci if (!mode.CanReturnArc) 2849370b324cSopenharmony_ci continue; 2850370b324cSopenharmony_ci } 2851370b324cSopenharmony_ci 2852370b324cSopenharmony_ci if (mode.EachPos) 2853370b324cSopenharmony_ci pos++; 2854370b324cSopenharmony_ci else if (needScan) 2855370b324cSopenharmony_ci { 2856370b324cSopenharmony_ci pos++; 2857370b324cSopenharmony_ci /* 2858370b324cSopenharmony_ci if (!OkPhySize_Defined) 2859370b324cSopenharmony_ci pos++; 2860370b324cSopenharmony_ci else 2861370b324cSopenharmony_ci pos = pi.Offset + pi.OkSize; 2862370b324cSopenharmony_ci */ 2863370b324cSopenharmony_ci } 2864370b324cSopenharmony_ci else 2865370b324cSopenharmony_ci pos = pi.Offset + pi.Size; 2866370b324cSopenharmony_ci 2867370b324cSopenharmony_ci 2868370b324cSopenharmony_ci RINOK(ReadParseItemProps(archive, ai, pi)) 2869370b324cSopenharmony_ci 2870370b324cSopenharmony_ci if (pi.Offset < startArcPos && !mode.EachPos /* && phySize_Defined */) 2871370b324cSopenharmony_ci { 2872370b324cSopenharmony_ci /* It's for DMG format. 2873370b324cSopenharmony_ci This code deletes all previous items that are included to current item */ 2874370b324cSopenharmony_ci 2875370b324cSopenharmony_ci while (!handlerSpec->_items.IsEmpty()) 2876370b324cSopenharmony_ci { 2877370b324cSopenharmony_ci { 2878370b324cSopenharmony_ci const NArchive::NParser::CParseItem &back = handlerSpec->_items.Back(); 2879370b324cSopenharmony_ci if (back.Offset < pi.Offset) 2880370b324cSopenharmony_ci break; 2881370b324cSopenharmony_ci if (back.Offset + back.Size > pi.Offset + pi.Size) 2882370b324cSopenharmony_ci break; 2883370b324cSopenharmony_ci } 2884370b324cSopenharmony_ci handlerSpec->_items.DeleteBack(); 2885370b324cSopenharmony_ci } 2886370b324cSopenharmony_ci } 2887370b324cSopenharmony_ci 2888370b324cSopenharmony_ci 2889370b324cSopenharmony_ci if (isOpen && mode.CanReturnArc && phySize_Defined) 2890370b324cSopenharmony_ci { 2891370b324cSopenharmony_ci // if (pi.Offset + pi.Size >= fileSize) 2892370b324cSopenharmony_ci bool openCur = false; 2893370b324cSopenharmony_ci 2894370b324cSopenharmony_ci bool thereIsTail = ErrorInfo.ThereIsTail; 2895370b324cSopenharmony_ci if (thereIsTail && mode.ZerosTailIsAllowed) 2896370b324cSopenharmony_ci { 2897370b324cSopenharmony_ci RINOK(CheckZerosTail(op, (UInt64)((Int64)arcStreamOffset + Offset + (Int64)PhySize))) 2898370b324cSopenharmony_ci if (ErrorInfo.IgnoreTail) 2899370b324cSopenharmony_ci thereIsTail = false; 2900370b324cSopenharmony_ci } 2901370b324cSopenharmony_ci 2902370b324cSopenharmony_ci if (pi.Offset != 0) 2903370b324cSopenharmony_ci { 2904370b324cSopenharmony_ci if (!pi.IsNotArcType) 2905370b324cSopenharmony_ci { 2906370b324cSopenharmony_ci if (thereIsTail) 2907370b324cSopenharmony_ci openCur = specFlags.CanReturnMid; 2908370b324cSopenharmony_ci else 2909370b324cSopenharmony_ci openCur = specFlags.CanReturnTail; 2910370b324cSopenharmony_ci } 2911370b324cSopenharmony_ci } 2912370b324cSopenharmony_ci else 2913370b324cSopenharmony_ci { 2914370b324cSopenharmony_ci if (!thereIsTail) 2915370b324cSopenharmony_ci openCur = true; 2916370b324cSopenharmony_ci else 2917370b324cSopenharmony_ci openCur = specFlags.CanReturnFrontal; 2918370b324cSopenharmony_ci 2919370b324cSopenharmony_ci if (formatIndex >= -2) 2920370b324cSopenharmony_ci openCur = true; 2921370b324cSopenharmony_ci } 2922370b324cSopenharmony_ci 2923370b324cSopenharmony_ci if (formatIndex < 0 && pi.IsSelfExe /* && mode.SkipSfxStub */) 2924370b324cSopenharmony_ci openCur = false; 2925370b324cSopenharmony_ci 2926370b324cSopenharmony_ci // We open file as SFX, if there is front archive or first archive is "Self Executable" 2927370b324cSopenharmony_ci if (!openCur && !pi.IsSelfExe && !thereIsTail && 2928370b324cSopenharmony_ci (!pi.IsNotArcType || pi.Offset == 0)) 2929370b324cSopenharmony_ci { 2930370b324cSopenharmony_ci if (handlerSpec->_items.IsEmpty()) 2931370b324cSopenharmony_ci { 2932370b324cSopenharmony_ci if (specFlags.CanReturnTail) 2933370b324cSopenharmony_ci openCur = true; 2934370b324cSopenharmony_ci } 2935370b324cSopenharmony_ci else if (handlerSpec->_items.Size() == 1) 2936370b324cSopenharmony_ci { 2937370b324cSopenharmony_ci if (handlerSpec->_items[0].IsSelfExe) 2938370b324cSopenharmony_ci { 2939370b324cSopenharmony_ci if (mode.SpecUnknownExt.CanReturnTail) 2940370b324cSopenharmony_ci openCur = true; 2941370b324cSopenharmony_ci } 2942370b324cSopenharmony_ci } 2943370b324cSopenharmony_ci } 2944370b324cSopenharmony_ci 2945370b324cSopenharmony_ci if (openCur) 2946370b324cSopenharmony_ci { 2947370b324cSopenharmony_ci InStream = op.stream; 2948370b324cSopenharmony_ci Archive = archive; 2949370b324cSopenharmony_ci FormatIndex = (int)index; 2950370b324cSopenharmony_ci ArcStreamOffset = arcStreamOffset; 2951370b324cSopenharmony_ci return S_OK; 2952370b324cSopenharmony_ci } 2953370b324cSopenharmony_ci } 2954370b324cSopenharmony_ci 2955370b324cSopenharmony_ci /* 2956370b324cSopenharmony_ci if (openOnlyFullArc) 2957370b324cSopenharmony_ci { 2958370b324cSopenharmony_ci ErrorInfo.ClearErrors(); 2959370b324cSopenharmony_ci return S_FALSE; 2960370b324cSopenharmony_ci } 2961370b324cSopenharmony_ci */ 2962370b324cSopenharmony_ci 2963370b324cSopenharmony_ci pi.FormatIndex = (int)index; 2964370b324cSopenharmony_ci 2965370b324cSopenharmony_ci // printf("\nAdd offset = %d", (int)pi.Offset); 2966370b324cSopenharmony_ci handlerSpec->AddItem(pi); 2967370b324cSopenharmony_ci wasOpen = true; 2968370b324cSopenharmony_ci break; 2969370b324cSopenharmony_ci } 2970370b324cSopenharmony_ci // ---------- End of Open Loop for Current Pos ---------- 2971370b324cSopenharmony_ci 2972370b324cSopenharmony_ci if (!wasOpen) 2973370b324cSopenharmony_ci pos++; 2974370b324cSopenharmony_ci needCheckStartOpen = (nextNeedCheckStartOpen && wasOpen); 2975370b324cSopenharmony_ci } 2976370b324cSopenharmony_ci // ---------- End of Main Scan Loop ---------- 2977370b324cSopenharmony_ci 2978370b324cSopenharmony_ci /* 2979370b324cSopenharmony_ci if (handlerSpec->_items.Size() == 1) 2980370b324cSopenharmony_ci { 2981370b324cSopenharmony_ci const NArchive::NParser::CParseItem &pi = handlerSpec->_items[0]; 2982370b324cSopenharmony_ci if (pi.Size == fileSize && pi.Offset == 0) 2983370b324cSopenharmony_ci { 2984370b324cSopenharmony_ci Archive = archive; 2985370b324cSopenharmony_ci FormatIndex2 = pi.FormatIndex; 2986370b324cSopenharmony_ci return S_OK; 2987370b324cSopenharmony_ci } 2988370b324cSopenharmony_ci } 2989370b324cSopenharmony_ci */ 2990370b324cSopenharmony_ci 2991370b324cSopenharmony_ci if (mode.CanReturnParser) 2992370b324cSopenharmony_ci { 2993370b324cSopenharmony_ci bool returnParser = (handlerSpec->_items.Size() == 1); // it's possible if fileSize was not correct at start of parsing 2994370b324cSopenharmony_ci handlerSpec->AddUnknownItem(fileSize); 2995370b324cSopenharmony_ci if (handlerSpec->_items.Size() == 0) 2996370b324cSopenharmony_ci return S_FALSE; 2997370b324cSopenharmony_ci if (returnParser || handlerSpec->_items.Size() != 1) 2998370b324cSopenharmony_ci { 2999370b324cSopenharmony_ci // return S_FALSE; 3000370b324cSopenharmony_ci handlerSpec->_stream = op.stream; 3001370b324cSopenharmony_ci Archive = handler; 3002370b324cSopenharmony_ci ErrorInfo.ClearErrors(); 3003370b324cSopenharmony_ci IsParseArc = true; 3004370b324cSopenharmony_ci FormatIndex = -1; // It's parser 3005370b324cSopenharmony_ci Offset = 0; 3006370b324cSopenharmony_ci return S_OK; 3007370b324cSopenharmony_ci } 3008370b324cSopenharmony_ci } 3009370b324cSopenharmony_ci } 3010370b324cSopenharmony_ci 3011370b324cSopenharmony_ci #endif 3012370b324cSopenharmony_ci 3013370b324cSopenharmony_ci if (!Archive) 3014370b324cSopenharmony_ci return S_FALSE; 3015370b324cSopenharmony_ci return S_OK; 3016370b324cSopenharmony_ci} 3017370b324cSopenharmony_ci 3018370b324cSopenharmony_ci 3019370b324cSopenharmony_ci 3020370b324cSopenharmony_ci 3021370b324cSopenharmony_ciHRESULT CArc::OpenStream(const COpenOptions &op) 3022370b324cSopenharmony_ci{ 3023370b324cSopenharmony_ci RINOK(OpenStream2(op)) 3024370b324cSopenharmony_ci // PrintNumber("op.formatIndex 3", op.formatIndex); 3025370b324cSopenharmony_ci 3026370b324cSopenharmony_ci if (Archive) 3027370b324cSopenharmony_ci { 3028370b324cSopenharmony_ci GetRawProps.Release(); 3029370b324cSopenharmony_ci GetRootProps.Release(); 3030370b324cSopenharmony_ci Archive->QueryInterface(IID_IArchiveGetRawProps, (void **)&GetRawProps); 3031370b324cSopenharmony_ci Archive->QueryInterface(IID_IArchiveGetRootProps, (void **)&GetRootProps); 3032370b324cSopenharmony_ci 3033370b324cSopenharmony_ci RINOK(Archive_GetArcProp_Bool(Archive, kpidIsTree, IsTree)) 3034370b324cSopenharmony_ci RINOK(Archive_GetArcProp_Bool(Archive, kpidIsDeleted, Ask_Deleted)) 3035370b324cSopenharmony_ci RINOK(Archive_GetArcProp_Bool(Archive, kpidIsAltStream, Ask_AltStream)) 3036370b324cSopenharmony_ci RINOK(Archive_GetArcProp_Bool(Archive, kpidIsAux, Ask_Aux)) 3037370b324cSopenharmony_ci RINOK(Archive_GetArcProp_Bool(Archive, kpidINode, Ask_INode)) 3038370b324cSopenharmony_ci RINOK(Archive_GetArcProp_Bool(Archive, kpidReadOnly, IsReadOnly)) 3039370b324cSopenharmony_ci 3040370b324cSopenharmony_ci const UString fileName = ExtractFileNameFromPath(Path); 3041370b324cSopenharmony_ci UString extension; 3042370b324cSopenharmony_ci { 3043370b324cSopenharmony_ci int dotPos = fileName.ReverseFind_Dot(); 3044370b324cSopenharmony_ci if (dotPos >= 0) 3045370b324cSopenharmony_ci extension = fileName.Ptr((unsigned)(dotPos + 1)); 3046370b324cSopenharmony_ci } 3047370b324cSopenharmony_ci 3048370b324cSopenharmony_ci DefaultName.Empty(); 3049370b324cSopenharmony_ci if (FormatIndex >= 0) 3050370b324cSopenharmony_ci { 3051370b324cSopenharmony_ci const CArcInfoEx &ai = op.codecs->Formats[(unsigned)FormatIndex]; 3052370b324cSopenharmony_ci if (ai.Exts.Size() == 0) 3053370b324cSopenharmony_ci DefaultName = GetDefaultName2(fileName, UString(), UString()); 3054370b324cSopenharmony_ci else 3055370b324cSopenharmony_ci { 3056370b324cSopenharmony_ci int subExtIndex = ai.FindExtension(extension); 3057370b324cSopenharmony_ci if (subExtIndex < 0) 3058370b324cSopenharmony_ci subExtIndex = 0; 3059370b324cSopenharmony_ci const CArcExtInfo &extInfo = ai.Exts[(unsigned)subExtIndex]; 3060370b324cSopenharmony_ci DefaultName = GetDefaultName2(fileName, extInfo.Ext, extInfo.AddExt); 3061370b324cSopenharmony_ci } 3062370b324cSopenharmony_ci } 3063370b324cSopenharmony_ci } 3064370b324cSopenharmony_ci 3065370b324cSopenharmony_ci return S_OK; 3066370b324cSopenharmony_ci} 3067370b324cSopenharmony_ci 3068370b324cSopenharmony_ci#ifdef Z7_SFX 3069370b324cSopenharmony_ci 3070370b324cSopenharmony_ci#ifdef _WIN32 3071370b324cSopenharmony_ci #define k_ExeExt ".exe" 3072370b324cSopenharmony_ci static const unsigned k_ExeExt_Len = 4; 3073370b324cSopenharmony_ci#else 3074370b324cSopenharmony_ci #define k_ExeExt "" 3075370b324cSopenharmony_ci static const unsigned k_ExeExt_Len = 0; 3076370b324cSopenharmony_ci#endif 3077370b324cSopenharmony_ci 3078370b324cSopenharmony_ci#endif 3079370b324cSopenharmony_ci 3080370b324cSopenharmony_ciHRESULT CArc::OpenStreamOrFile(COpenOptions &op) 3081370b324cSopenharmony_ci{ 3082370b324cSopenharmony_ci CMyComPtr<IInStream> fileStream; 3083370b324cSopenharmony_ci CMyComPtr<ISequentialInStream> seqStream; 3084370b324cSopenharmony_ci CInFileStream *fileStreamSpec = NULL; 3085370b324cSopenharmony_ci 3086370b324cSopenharmony_ci if (op.stdInMode) 3087370b324cSopenharmony_ci { 3088370b324cSopenharmony_ci seqStream = new CStdInFileStream; 3089370b324cSopenharmony_ci op.seqStream = seqStream; 3090370b324cSopenharmony_ci } 3091370b324cSopenharmony_ci else if (!op.stream) 3092370b324cSopenharmony_ci { 3093370b324cSopenharmony_ci fileStreamSpec = new CInFileStream; 3094370b324cSopenharmony_ci fileStream = fileStreamSpec; 3095370b324cSopenharmony_ci Path = filePath; 3096370b324cSopenharmony_ci if (!fileStreamSpec->Open(us2fs(Path))) 3097370b324cSopenharmony_ci return GetLastError_noZero_HRESULT(); 3098370b324cSopenharmony_ci op.stream = fileStream; 3099370b324cSopenharmony_ci #ifdef Z7_SFX 3100370b324cSopenharmony_ci IgnoreSplit = true; 3101370b324cSopenharmony_ci #endif 3102370b324cSopenharmony_ci } 3103370b324cSopenharmony_ci 3104370b324cSopenharmony_ci /* 3105370b324cSopenharmony_ci if (callback) 3106370b324cSopenharmony_ci { 3107370b324cSopenharmony_ci UInt64 fileSize; 3108370b324cSopenharmony_ci RINOK(InStream_GetSize_SeekToEnd(op.stream, fileSize)); 3109370b324cSopenharmony_ci RINOK(op.callback->SetTotal(NULL, &fileSize)) 3110370b324cSopenharmony_ci } 3111370b324cSopenharmony_ci */ 3112370b324cSopenharmony_ci 3113370b324cSopenharmony_ci HRESULT res = OpenStream(op); 3114370b324cSopenharmony_ci IgnoreSplit = false; 3115370b324cSopenharmony_ci 3116370b324cSopenharmony_ci #ifdef Z7_SFX 3117370b324cSopenharmony_ci 3118370b324cSopenharmony_ci if (res != S_FALSE 3119370b324cSopenharmony_ci || !fileStreamSpec 3120370b324cSopenharmony_ci || !op.callbackSpec 3121370b324cSopenharmony_ci || NonOpen_ErrorInfo.IsArc_After_NonOpen()) 3122370b324cSopenharmony_ci return res; 3123370b324cSopenharmony_ci 3124370b324cSopenharmony_ci { 3125370b324cSopenharmony_ci if (filePath.Len() > k_ExeExt_Len 3126370b324cSopenharmony_ci && StringsAreEqualNoCase_Ascii(filePath.RightPtr(k_ExeExt_Len), k_ExeExt)) 3127370b324cSopenharmony_ci { 3128370b324cSopenharmony_ci const UString path2 = filePath.Left(filePath.Len() - k_ExeExt_Len); 3129370b324cSopenharmony_ci FOR_VECTOR (i, op.codecs->Formats) 3130370b324cSopenharmony_ci { 3131370b324cSopenharmony_ci const CArcInfoEx &ai = op.codecs->Formats[i]; 3132370b324cSopenharmony_ci if (ai.Is_Split()) 3133370b324cSopenharmony_ci continue; 3134370b324cSopenharmony_ci UString path3 = path2; 3135370b324cSopenharmony_ci path3.Add_Dot(); 3136370b324cSopenharmony_ci path3 += ai.GetMainExt(); // "7z" for SFX. 3137370b324cSopenharmony_ci Path = path3; 3138370b324cSopenharmony_ci Path += ".001"; 3139370b324cSopenharmony_ci bool isOk = op.callbackSpec->SetSecondFileInfo(us2fs(Path)); 3140370b324cSopenharmony_ci if (!isOk) 3141370b324cSopenharmony_ci { 3142370b324cSopenharmony_ci Path = path3; 3143370b324cSopenharmony_ci isOk = op.callbackSpec->SetSecondFileInfo(us2fs(Path)); 3144370b324cSopenharmony_ci } 3145370b324cSopenharmony_ci if (isOk) 3146370b324cSopenharmony_ci { 3147370b324cSopenharmony_ci if (fileStreamSpec->Open(us2fs(Path))) 3148370b324cSopenharmony_ci { 3149370b324cSopenharmony_ci op.stream = fileStream; 3150370b324cSopenharmony_ci NonOpen_ErrorInfo.ClearErrors_Full(); 3151370b324cSopenharmony_ci if (OpenStream(op) == S_OK) 3152370b324cSopenharmony_ci return S_OK; 3153370b324cSopenharmony_ci } 3154370b324cSopenharmony_ci } 3155370b324cSopenharmony_ci } 3156370b324cSopenharmony_ci } 3157370b324cSopenharmony_ci } 3158370b324cSopenharmony_ci 3159370b324cSopenharmony_ci #endif 3160370b324cSopenharmony_ci 3161370b324cSopenharmony_ci return res; 3162370b324cSopenharmony_ci} 3163370b324cSopenharmony_ci 3164370b324cSopenharmony_civoid CArchiveLink::KeepModeForNextOpen() 3165370b324cSopenharmony_ci{ 3166370b324cSopenharmony_ci for (unsigned i = Arcs.Size(); i != 0;) 3167370b324cSopenharmony_ci { 3168370b324cSopenharmony_ci i--; 3169370b324cSopenharmony_ci CMyComPtr<IArchiveKeepModeForNextOpen> keep; 3170370b324cSopenharmony_ci Arcs[i].Archive->QueryInterface(IID_IArchiveKeepModeForNextOpen, (void **)&keep); 3171370b324cSopenharmony_ci if (keep) 3172370b324cSopenharmony_ci keep->KeepModeForNextOpen(); 3173370b324cSopenharmony_ci } 3174370b324cSopenharmony_ci} 3175370b324cSopenharmony_ci 3176370b324cSopenharmony_ciHRESULT CArchiveLink::Close() 3177370b324cSopenharmony_ci{ 3178370b324cSopenharmony_ci for (unsigned i = Arcs.Size(); i != 0;) 3179370b324cSopenharmony_ci { 3180370b324cSopenharmony_ci i--; 3181370b324cSopenharmony_ci RINOK(Arcs[i].Close()) 3182370b324cSopenharmony_ci } 3183370b324cSopenharmony_ci IsOpen = false; 3184370b324cSopenharmony_ci // ErrorsText.Empty(); 3185370b324cSopenharmony_ci return S_OK; 3186370b324cSopenharmony_ci} 3187370b324cSopenharmony_ci 3188370b324cSopenharmony_civoid CArchiveLink::Release() 3189370b324cSopenharmony_ci{ 3190370b324cSopenharmony_ci // NonOpenErrorFormatIndex = -1; 3191370b324cSopenharmony_ci NonOpen_ErrorInfo.ClearErrors(); 3192370b324cSopenharmony_ci NonOpen_ArcPath.Empty(); 3193370b324cSopenharmony_ci while (!Arcs.IsEmpty()) 3194370b324cSopenharmony_ci Arcs.DeleteBack(); 3195370b324cSopenharmony_ci} 3196370b324cSopenharmony_ci 3197370b324cSopenharmony_ci/* 3198370b324cSopenharmony_civoid CArchiveLink::Set_ErrorsText() 3199370b324cSopenharmony_ci{ 3200370b324cSopenharmony_ci FOR_VECTOR(i, Arcs) 3201370b324cSopenharmony_ci { 3202370b324cSopenharmony_ci const CArc &arc = Arcs[i]; 3203370b324cSopenharmony_ci if (!arc.ErrorFlagsText.IsEmpty()) 3204370b324cSopenharmony_ci { 3205370b324cSopenharmony_ci if (!ErrorsText.IsEmpty()) 3206370b324cSopenharmony_ci ErrorsText.Add_LF(); 3207370b324cSopenharmony_ci ErrorsText += GetUnicodeString(arc.ErrorFlagsText); 3208370b324cSopenharmony_ci } 3209370b324cSopenharmony_ci if (!arc.ErrorMessage.IsEmpty()) 3210370b324cSopenharmony_ci { 3211370b324cSopenharmony_ci if (!ErrorsText.IsEmpty()) 3212370b324cSopenharmony_ci ErrorsText.Add_LF(); 3213370b324cSopenharmony_ci ErrorsText += arc.ErrorMessage; 3214370b324cSopenharmony_ci } 3215370b324cSopenharmony_ci 3216370b324cSopenharmony_ci if (!arc.WarningMessage.IsEmpty()) 3217370b324cSopenharmony_ci { 3218370b324cSopenharmony_ci if (!ErrorsText.IsEmpty()) 3219370b324cSopenharmony_ci ErrorsText.Add_LF(); 3220370b324cSopenharmony_ci ErrorsText += arc.WarningMessage; 3221370b324cSopenharmony_ci } 3222370b324cSopenharmony_ci } 3223370b324cSopenharmony_ci} 3224370b324cSopenharmony_ci*/ 3225370b324cSopenharmony_ci 3226370b324cSopenharmony_ciHRESULT CArchiveLink::Open(COpenOptions &op) 3227370b324cSopenharmony_ci{ 3228370b324cSopenharmony_ci Release(); 3229370b324cSopenharmony_ci if (op.types->Size() >= 32) 3230370b324cSopenharmony_ci return E_NOTIMPL; 3231370b324cSopenharmony_ci 3232370b324cSopenharmony_ci HRESULT resSpec; 3233370b324cSopenharmony_ci 3234370b324cSopenharmony_ci for (;;) 3235370b324cSopenharmony_ci { 3236370b324cSopenharmony_ci resSpec = S_OK; 3237370b324cSopenharmony_ci 3238370b324cSopenharmony_ci op.openType = COpenType(); 3239370b324cSopenharmony_ci if (op.types->Size() >= 1) 3240370b324cSopenharmony_ci { 3241370b324cSopenharmony_ci COpenType latest; 3242370b324cSopenharmony_ci if (Arcs.Size() < op.types->Size()) 3243370b324cSopenharmony_ci latest = (*op.types)[op.types->Size() - Arcs.Size() - 1]; 3244370b324cSopenharmony_ci else 3245370b324cSopenharmony_ci { 3246370b324cSopenharmony_ci latest = (*op.types)[0]; 3247370b324cSopenharmony_ci if (!latest.Recursive) 3248370b324cSopenharmony_ci break; 3249370b324cSopenharmony_ci } 3250370b324cSopenharmony_ci op.openType = latest; 3251370b324cSopenharmony_ci } 3252370b324cSopenharmony_ci else if (Arcs.Size() >= 32) 3253370b324cSopenharmony_ci break; 3254370b324cSopenharmony_ci 3255370b324cSopenharmony_ci /* 3256370b324cSopenharmony_ci op.formatIndex = -1; 3257370b324cSopenharmony_ci if (op.types->Size() >= 1) 3258370b324cSopenharmony_ci { 3259370b324cSopenharmony_ci int latest; 3260370b324cSopenharmony_ci if (Arcs.Size() < op.types->Size()) 3261370b324cSopenharmony_ci latest = (*op.types)[op.types->Size() - Arcs.Size() - 1]; 3262370b324cSopenharmony_ci else 3263370b324cSopenharmony_ci { 3264370b324cSopenharmony_ci latest = (*op.types)[0]; 3265370b324cSopenharmony_ci if (latest != -2 && latest != -3) 3266370b324cSopenharmony_ci break; 3267370b324cSopenharmony_ci } 3268370b324cSopenharmony_ci if (latest >= 0) 3269370b324cSopenharmony_ci op.formatIndex = latest; 3270370b324cSopenharmony_ci else if (latest == -1 || latest == -2) 3271370b324cSopenharmony_ci { 3272370b324cSopenharmony_ci // default 3273370b324cSopenharmony_ci } 3274370b324cSopenharmony_ci else if (latest == -3) 3275370b324cSopenharmony_ci op.formatIndex = -2; 3276370b324cSopenharmony_ci else 3277370b324cSopenharmony_ci op.formatIndex = latest + 2; 3278370b324cSopenharmony_ci } 3279370b324cSopenharmony_ci else if (Arcs.Size() >= 32) 3280370b324cSopenharmony_ci break; 3281370b324cSopenharmony_ci */ 3282370b324cSopenharmony_ci 3283370b324cSopenharmony_ci if (Arcs.IsEmpty()) 3284370b324cSopenharmony_ci { 3285370b324cSopenharmony_ci CArc arc; 3286370b324cSopenharmony_ci arc.filePath = op.filePath; 3287370b324cSopenharmony_ci arc.Path = op.filePath; 3288370b324cSopenharmony_ci arc.SubfileIndex = (UInt32)(Int32)-1; 3289370b324cSopenharmony_ci HRESULT result = arc.OpenStreamOrFile(op); 3290370b324cSopenharmony_ci if (result != S_OK) 3291370b324cSopenharmony_ci { 3292370b324cSopenharmony_ci if (result == S_FALSE) 3293370b324cSopenharmony_ci { 3294370b324cSopenharmony_ci NonOpen_ErrorInfo = arc.NonOpen_ErrorInfo; 3295370b324cSopenharmony_ci // NonOpenErrorFormatIndex = arc.ErrorFormatIndex; 3296370b324cSopenharmony_ci NonOpen_ArcPath = arc.Path; 3297370b324cSopenharmony_ci } 3298370b324cSopenharmony_ci return result; 3299370b324cSopenharmony_ci } 3300370b324cSopenharmony_ci Arcs.Add(arc); 3301370b324cSopenharmony_ci continue; 3302370b324cSopenharmony_ci } 3303370b324cSopenharmony_ci 3304370b324cSopenharmony_ci // PrintNumber("op.formatIndex 11", op.formatIndex); 3305370b324cSopenharmony_ci 3306370b324cSopenharmony_ci const CArc &arc = Arcs.Back(); 3307370b324cSopenharmony_ci 3308370b324cSopenharmony_ci if (op.types->Size() > Arcs.Size()) 3309370b324cSopenharmony_ci resSpec = E_NOTIMPL; 3310370b324cSopenharmony_ci 3311370b324cSopenharmony_ci UInt32 mainSubfile; 3312370b324cSopenharmony_ci { 3313370b324cSopenharmony_ci NCOM::CPropVariant prop; 3314370b324cSopenharmony_ci RINOK(arc.Archive->GetArchiveProperty(kpidMainSubfile, &prop)) 3315370b324cSopenharmony_ci if (prop.vt == VT_UI4) 3316370b324cSopenharmony_ci mainSubfile = prop.ulVal; 3317370b324cSopenharmony_ci else 3318370b324cSopenharmony_ci break; 3319370b324cSopenharmony_ci UInt32 numItems; 3320370b324cSopenharmony_ci RINOK(arc.Archive->GetNumberOfItems(&numItems)) 3321370b324cSopenharmony_ci if (mainSubfile >= numItems) 3322370b324cSopenharmony_ci break; 3323370b324cSopenharmony_ci } 3324370b324cSopenharmony_ci 3325370b324cSopenharmony_ci 3326370b324cSopenharmony_ci CMyComPtr<IInArchiveGetStream> getStream; 3327370b324cSopenharmony_ci if (arc.Archive->QueryInterface(IID_IInArchiveGetStream, (void **)&getStream) != S_OK || !getStream) 3328370b324cSopenharmony_ci break; 3329370b324cSopenharmony_ci 3330370b324cSopenharmony_ci CMyComPtr<ISequentialInStream> subSeqStream; 3331370b324cSopenharmony_ci if (getStream->GetStream(mainSubfile, &subSeqStream) != S_OK || !subSeqStream) 3332370b324cSopenharmony_ci break; 3333370b324cSopenharmony_ci 3334370b324cSopenharmony_ci CMyComPtr<IInStream> subStream; 3335370b324cSopenharmony_ci if (subSeqStream.QueryInterface(IID_IInStream, &subStream) != S_OK || !subStream) 3336370b324cSopenharmony_ci break; 3337370b324cSopenharmony_ci 3338370b324cSopenharmony_ci CArc arc2; 3339370b324cSopenharmony_ci RINOK(arc.GetItem_Path(mainSubfile, arc2.Path)) 3340370b324cSopenharmony_ci 3341370b324cSopenharmony_ci bool zerosTailIsAllowed; 3342370b324cSopenharmony_ci RINOK(Archive_GetItemBoolProp(arc.Archive, mainSubfile, kpidZerosTailIsAllowed, zerosTailIsAllowed)) 3343370b324cSopenharmony_ci 3344370b324cSopenharmony_ci 3345370b324cSopenharmony_ci if (op.callback) 3346370b324cSopenharmony_ci { 3347370b324cSopenharmony_ci Z7_DECL_CMyComPtr_QI_FROM( 3348370b324cSopenharmony_ci IArchiveOpenSetSubArchiveName, 3349370b324cSopenharmony_ci setSubArchiveName, op.callback) 3350370b324cSopenharmony_ci if (setSubArchiveName) 3351370b324cSopenharmony_ci setSubArchiveName->SetSubArchiveName(arc2.Path); 3352370b324cSopenharmony_ci } 3353370b324cSopenharmony_ci 3354370b324cSopenharmony_ci arc2.SubfileIndex = mainSubfile; 3355370b324cSopenharmony_ci 3356370b324cSopenharmony_ci // CIntVector incl; 3357370b324cSopenharmony_ci CIntVector excl; 3358370b324cSopenharmony_ci 3359370b324cSopenharmony_ci COpenOptions op2; 3360370b324cSopenharmony_ci #ifndef Z7_SFX 3361370b324cSopenharmony_ci op2.props = op.props; 3362370b324cSopenharmony_ci #endif 3363370b324cSopenharmony_ci op2.codecs = op.codecs; 3364370b324cSopenharmony_ci // op2.types = &incl; 3365370b324cSopenharmony_ci op2.openType = op.openType; 3366370b324cSopenharmony_ci op2.openType.ZerosTailIsAllowed = zerosTailIsAllowed; 3367370b324cSopenharmony_ci op2.excludedFormats = ! 3368370b324cSopenharmony_ci op2.stdInMode = false; 3369370b324cSopenharmony_ci op2.stream = subStream; 3370370b324cSopenharmony_ci op2.filePath = arc2.Path; 3371370b324cSopenharmony_ci op2.callback = op.callback; 3372370b324cSopenharmony_ci op2.callbackSpec = op.callbackSpec; 3373370b324cSopenharmony_ci 3374370b324cSopenharmony_ci 3375370b324cSopenharmony_ci HRESULT result = arc2.OpenStream(op2); 3376370b324cSopenharmony_ci resSpec = (op.types->Size() == 0 ? S_OK : S_FALSE); 3377370b324cSopenharmony_ci if (result == S_FALSE) 3378370b324cSopenharmony_ci { 3379370b324cSopenharmony_ci NonOpen_ErrorInfo = arc2.ErrorInfo; 3380370b324cSopenharmony_ci NonOpen_ArcPath = arc2.Path; 3381370b324cSopenharmony_ci break; 3382370b324cSopenharmony_ci } 3383370b324cSopenharmony_ci RINOK(result) 3384370b324cSopenharmony_ci RINOK(arc.GetItem_MTime(mainSubfile, arc2.MTime)) 3385370b324cSopenharmony_ci Arcs.Add(arc2); 3386370b324cSopenharmony_ci } 3387370b324cSopenharmony_ci IsOpen = !Arcs.IsEmpty(); 3388370b324cSopenharmony_ci return resSpec; 3389370b324cSopenharmony_ci} 3390370b324cSopenharmony_ci 3391370b324cSopenharmony_ciHRESULT CArchiveLink::Open2(COpenOptions &op, IOpenCallbackUI *callbackUI) 3392370b324cSopenharmony_ci{ 3393370b324cSopenharmony_ci VolumesSize = 0; 3394370b324cSopenharmony_ci COpenCallbackImp *openCallbackSpec = new COpenCallbackImp; 3395370b324cSopenharmony_ci CMyComPtr<IArchiveOpenCallback> callback = openCallbackSpec; 3396370b324cSopenharmony_ci openCallbackSpec->Callback = callbackUI; 3397370b324cSopenharmony_ci 3398370b324cSopenharmony_ci FString prefix, name; 3399370b324cSopenharmony_ci 3400370b324cSopenharmony_ci if (!op.stream && !op.stdInMode) 3401370b324cSopenharmony_ci { 3402370b324cSopenharmony_ci NFile::NDir::GetFullPathAndSplit(us2fs(op.filePath), prefix, name); 3403370b324cSopenharmony_ci RINOK(openCallbackSpec->Init2(prefix, name)) 3404370b324cSopenharmony_ci } 3405370b324cSopenharmony_ci else 3406370b324cSopenharmony_ci { 3407370b324cSopenharmony_ci openCallbackSpec->SetSubArchiveName(op.filePath); 3408370b324cSopenharmony_ci } 3409370b324cSopenharmony_ci 3410370b324cSopenharmony_ci op.callback = callback; 3411370b324cSopenharmony_ci op.callbackSpec = openCallbackSpec; 3412370b324cSopenharmony_ci 3413370b324cSopenharmony_ci HRESULT res = Open(op); 3414370b324cSopenharmony_ci 3415370b324cSopenharmony_ci PasswordWasAsked = openCallbackSpec->PasswordWasAsked; 3416370b324cSopenharmony_ci // Password = openCallbackSpec->Password; 3417370b324cSopenharmony_ci 3418370b324cSopenharmony_ci RINOK(res) 3419370b324cSopenharmony_ci // VolumePaths.Add(fs2us(prefix + name)); 3420370b324cSopenharmony_ci 3421370b324cSopenharmony_ci FOR_VECTOR (i, openCallbackSpec->FileNames_WasUsed) 3422370b324cSopenharmony_ci { 3423370b324cSopenharmony_ci if (openCallbackSpec->FileNames_WasUsed[i]) 3424370b324cSopenharmony_ci { 3425370b324cSopenharmony_ci VolumePaths.Add(fs2us(prefix) + openCallbackSpec->FileNames[i]); 3426370b324cSopenharmony_ci VolumesSize += openCallbackSpec->FileSizes[i]; 3427370b324cSopenharmony_ci } 3428370b324cSopenharmony_ci } 3429370b324cSopenharmony_ci // VolumesSize = openCallbackSpec->TotalSize; 3430370b324cSopenharmony_ci return S_OK; 3431370b324cSopenharmony_ci} 3432370b324cSopenharmony_ci 3433370b324cSopenharmony_ciHRESULT CArc::ReOpen(const COpenOptions &op, IArchiveOpenCallback *openCallback_Additional) 3434370b324cSopenharmony_ci{ 3435370b324cSopenharmony_ci ErrorInfo.ClearErrors(); 3436370b324cSopenharmony_ci ErrorInfo.ErrorFormatIndex = -1; 3437370b324cSopenharmony_ci 3438370b324cSopenharmony_ci UInt64 fileSize = 0; 3439370b324cSopenharmony_ci if (op.stream) 3440370b324cSopenharmony_ci { 3441370b324cSopenharmony_ci RINOK(InStream_SeekToBegin(op.stream)) 3442370b324cSopenharmony_ci RINOK(InStream_AtBegin_GetSize(op.stream, fileSize)) 3443370b324cSopenharmony_ci // RINOK(InStream_GetSize_SeekToBegin(op.stream, fileSize)) 3444370b324cSopenharmony_ci } 3445370b324cSopenharmony_ci FileSize = fileSize; 3446370b324cSopenharmony_ci 3447370b324cSopenharmony_ci CMyComPtr<IInStream> stream2; 3448370b324cSopenharmony_ci Int64 globalOffset = GetGlobalOffset(); 3449370b324cSopenharmony_ci if (globalOffset <= 0) 3450370b324cSopenharmony_ci stream2 = op.stream; 3451370b324cSopenharmony_ci else 3452370b324cSopenharmony_ci { 3453370b324cSopenharmony_ci CTailInStream *tailStreamSpec = new CTailInStream; 3454370b324cSopenharmony_ci stream2 = tailStreamSpec; 3455370b324cSopenharmony_ci tailStreamSpec->Stream = op.stream; 3456370b324cSopenharmony_ci tailStreamSpec->Offset = (UInt64)globalOffset; 3457370b324cSopenharmony_ci tailStreamSpec->Init(); 3458370b324cSopenharmony_ci RINOK(tailStreamSpec->SeekToStart()) 3459370b324cSopenharmony_ci } 3460370b324cSopenharmony_ci 3461370b324cSopenharmony_ci // There are archives with embedded STUBs (like ZIP), so we must support signature scanning 3462370b324cSopenharmony_ci // But for another archives we can use 0 here. So the code can be fixed !!! 3463370b324cSopenharmony_ci UInt64 maxStartPosition = kMaxCheckStartPosition; 3464370b324cSopenharmony_ci IArchiveOpenCallback *openCallback = openCallback_Additional; 3465370b324cSopenharmony_ci if (!openCallback) 3466370b324cSopenharmony_ci openCallback = op.callback; 3467370b324cSopenharmony_ci HRESULT res = Archive->Open(stream2, &maxStartPosition, openCallback); 3468370b324cSopenharmony_ci 3469370b324cSopenharmony_ci if (res == S_OK) 3470370b324cSopenharmony_ci { 3471370b324cSopenharmony_ci RINOK(ReadBasicProps(Archive, (UInt64)globalOffset, res)) 3472370b324cSopenharmony_ci ArcStreamOffset = (UInt64)globalOffset; 3473370b324cSopenharmony_ci if (ArcStreamOffset != 0) 3474370b324cSopenharmony_ci InStream = op.stream; 3475370b324cSopenharmony_ci } 3476370b324cSopenharmony_ci return res; 3477370b324cSopenharmony_ci} 3478370b324cSopenharmony_ci 3479370b324cSopenharmony_ciHRESULT CArchiveLink::Open3(COpenOptions &op, IOpenCallbackUI *callbackUI) 3480370b324cSopenharmony_ci{ 3481370b324cSopenharmony_ci HRESULT res = Open2(op, callbackUI); 3482370b324cSopenharmony_ci if (callbackUI) 3483370b324cSopenharmony_ci { 3484370b324cSopenharmony_ci RINOK(callbackUI->Open_Finished()) 3485370b324cSopenharmony_ci } 3486370b324cSopenharmony_ci return res; 3487370b324cSopenharmony_ci} 3488370b324cSopenharmony_ci 3489370b324cSopenharmony_ciHRESULT CArchiveLink::ReOpen(COpenOptions &op) 3490370b324cSopenharmony_ci{ 3491370b324cSopenharmony_ci if (Arcs.Size() > 1) 3492370b324cSopenharmony_ci return E_NOTIMPL; 3493370b324cSopenharmony_ci 3494370b324cSopenharmony_ci CObjectVector<COpenType> inc; 3495370b324cSopenharmony_ci CIntVector excl; 3496370b324cSopenharmony_ci 3497370b324cSopenharmony_ci op.types = &inc; 3498370b324cSopenharmony_ci op.excludedFormats = ! 3499370b324cSopenharmony_ci op.stdInMode = false; 3500370b324cSopenharmony_ci op.stream = NULL; 3501370b324cSopenharmony_ci if (Arcs.Size() == 0) // ??? 3502370b324cSopenharmony_ci return Open2(op, NULL); 3503370b324cSopenharmony_ci 3504370b324cSopenharmony_ci /* if archive is multivolume (unsupported here still) 3505370b324cSopenharmony_ci COpenCallbackImp object will exist after Open stage. */ 3506370b324cSopenharmony_ci COpenCallbackImp *openCallbackSpec = new COpenCallbackImp; 3507370b324cSopenharmony_ci CMyComPtr<IArchiveOpenCallback> openCallbackNew = openCallbackSpec; 3508370b324cSopenharmony_ci 3509370b324cSopenharmony_ci openCallbackSpec->Callback = NULL; 3510370b324cSopenharmony_ci openCallbackSpec->ReOpenCallback = op.callback; 3511370b324cSopenharmony_ci { 3512370b324cSopenharmony_ci FString dirPrefix, fileName; 3513370b324cSopenharmony_ci NFile::NDir::GetFullPathAndSplit(us2fs(op.filePath), dirPrefix, fileName); 3514370b324cSopenharmony_ci RINOK(openCallbackSpec->Init2(dirPrefix, fileName)) 3515370b324cSopenharmony_ci } 3516370b324cSopenharmony_ci 3517370b324cSopenharmony_ci 3518370b324cSopenharmony_ci CInFileStream *fileStreamSpec = new CInFileStream; 3519370b324cSopenharmony_ci CMyComPtr<IInStream> stream(fileStreamSpec); 3520370b324cSopenharmony_ci if (!fileStreamSpec->Open(us2fs(op.filePath))) 3521370b324cSopenharmony_ci return GetLastError_noZero_HRESULT(); 3522370b324cSopenharmony_ci op.stream = stream; 3523370b324cSopenharmony_ci 3524370b324cSopenharmony_ci CArc &arc = Arcs[0]; 3525370b324cSopenharmony_ci const HRESULT res = arc.ReOpen(op, openCallbackNew); 3526370b324cSopenharmony_ci 3527370b324cSopenharmony_ci openCallbackSpec->ReOpenCallback = NULL; 3528370b324cSopenharmony_ci 3529370b324cSopenharmony_ci PasswordWasAsked = openCallbackSpec->PasswordWasAsked; 3530370b324cSopenharmony_ci // Password = openCallbackSpec->Password; 3531370b324cSopenharmony_ci 3532370b324cSopenharmony_ci IsOpen = (res == S_OK); 3533370b324cSopenharmony_ci return res; 3534370b324cSopenharmony_ci} 3535370b324cSopenharmony_ci 3536370b324cSopenharmony_ci#ifndef Z7_SFX 3537370b324cSopenharmony_ci 3538370b324cSopenharmony_cibool ParseComplexSize(const wchar_t *s, UInt64 &result); 3539370b324cSopenharmony_cibool ParseComplexSize(const wchar_t *s, UInt64 &result) 3540370b324cSopenharmony_ci{ 3541370b324cSopenharmony_ci result = 0; 3542370b324cSopenharmony_ci const wchar_t *end; 3543370b324cSopenharmony_ci UInt64 number = ConvertStringToUInt64(s, &end); 3544370b324cSopenharmony_ci if (end == s) 3545370b324cSopenharmony_ci return false; 3546370b324cSopenharmony_ci if (*end == 0) 3547370b324cSopenharmony_ci { 3548370b324cSopenharmony_ci result = number; 3549370b324cSopenharmony_ci return true; 3550370b324cSopenharmony_ci } 3551370b324cSopenharmony_ci if (end[1] != 0) 3552370b324cSopenharmony_ci return false; 3553370b324cSopenharmony_ci unsigned numBits; 3554370b324cSopenharmony_ci switch (MyCharLower_Ascii(*end)) 3555370b324cSopenharmony_ci { 3556370b324cSopenharmony_ci case 'b': result = number; return true; 3557370b324cSopenharmony_ci case 'k': numBits = 10; break; 3558370b324cSopenharmony_ci case 'm': numBits = 20; break; 3559370b324cSopenharmony_ci case 'g': numBits = 30; break; 3560370b324cSopenharmony_ci case 't': numBits = 40; break; 3561370b324cSopenharmony_ci default: return false; 3562370b324cSopenharmony_ci } 3563370b324cSopenharmony_ci if (number >= ((UInt64)1 << (64 - numBits))) 3564370b324cSopenharmony_ci return false; 3565370b324cSopenharmony_ci result = number << numBits; 3566370b324cSopenharmony_ci return true; 3567370b324cSopenharmony_ci} 3568370b324cSopenharmony_ci 3569370b324cSopenharmony_cistatic bool ParseTypeParams(const UString &s, COpenType &type) 3570370b324cSopenharmony_ci{ 3571370b324cSopenharmony_ci if (s[0] == 0) 3572370b324cSopenharmony_ci return true; 3573370b324cSopenharmony_ci if (s[1] == 0) 3574370b324cSopenharmony_ci { 3575370b324cSopenharmony_ci switch ((unsigned)(Byte)s[0]) 3576370b324cSopenharmony_ci { 3577370b324cSopenharmony_ci case 'e': type.EachPos = true; return true; 3578370b324cSopenharmony_ci case 'a': type.CanReturnArc = true; return true; 3579370b324cSopenharmony_ci case 'r': type.Recursive = true; return true; 3580370b324cSopenharmony_ci } 3581370b324cSopenharmony_ci return false; 3582370b324cSopenharmony_ci } 3583370b324cSopenharmony_ci if (s[0] == 's') 3584370b324cSopenharmony_ci { 3585370b324cSopenharmony_ci UInt64 result; 3586370b324cSopenharmony_ci if (!ParseComplexSize(s.Ptr(1), result)) 3587370b324cSopenharmony_ci return false; 3588370b324cSopenharmony_ci type.MaxStartOffset = result; 3589370b324cSopenharmony_ci type.MaxStartOffset_Defined = true; 3590370b324cSopenharmony_ci return true; 3591370b324cSopenharmony_ci } 3592370b324cSopenharmony_ci 3593370b324cSopenharmony_ci return false; 3594370b324cSopenharmony_ci} 3595370b324cSopenharmony_ci 3596370b324cSopenharmony_cistatic bool ParseType(CCodecs &codecs, const UString &s, COpenType &type) 3597370b324cSopenharmony_ci{ 3598370b324cSopenharmony_ci int pos2 = s.Find(L':'); 3599370b324cSopenharmony_ci 3600370b324cSopenharmony_ci { 3601370b324cSopenharmony_ci UString name; 3602370b324cSopenharmony_ci if (pos2 < 0) 3603370b324cSopenharmony_ci { 3604370b324cSopenharmony_ci name = s; 3605370b324cSopenharmony_ci pos2 = (int)s.Len(); 3606370b324cSopenharmony_ci } 3607370b324cSopenharmony_ci else 3608370b324cSopenharmony_ci { 3609370b324cSopenharmony_ci name = s.Left((unsigned)pos2); 3610370b324cSopenharmony_ci pos2++; 3611370b324cSopenharmony_ci } 3612370b324cSopenharmony_ci 3613370b324cSopenharmony_ci int index = codecs.FindFormatForArchiveType(name); 3614370b324cSopenharmony_ci type.Recursive = false; 3615370b324cSopenharmony_ci 3616370b324cSopenharmony_ci if (index < 0) 3617370b324cSopenharmony_ci { 3618370b324cSopenharmony_ci if (name[0] == '*') 3619370b324cSopenharmony_ci { 3620370b324cSopenharmony_ci if (name[1] != 0) 3621370b324cSopenharmony_ci return false; 3622370b324cSopenharmony_ci } 3623370b324cSopenharmony_ci else if (name[0] == '#') 3624370b324cSopenharmony_ci { 3625370b324cSopenharmony_ci if (name[1] != 0) 3626370b324cSopenharmony_ci return false; 3627370b324cSopenharmony_ci type.CanReturnArc = false; 3628370b324cSopenharmony_ci type.CanReturnParser = true; 3629370b324cSopenharmony_ci } 3630370b324cSopenharmony_ci else if (name.IsEqualTo_Ascii_NoCase("hash")) 3631370b324cSopenharmony_ci { 3632370b324cSopenharmony_ci // type.CanReturnArc = false; 3633370b324cSopenharmony_ci // type.CanReturnParser = false; 3634370b324cSopenharmony_ci type.IsHashType = true; 3635370b324cSopenharmony_ci } 3636370b324cSopenharmony_ci else 3637370b324cSopenharmony_ci return false; 3638370b324cSopenharmony_ci } 3639370b324cSopenharmony_ci 3640370b324cSopenharmony_ci type.FormatIndex = index; 3641370b324cSopenharmony_ci 3642370b324cSopenharmony_ci } 3643370b324cSopenharmony_ci 3644370b324cSopenharmony_ci for (unsigned i = (unsigned)pos2; i < s.Len();) 3645370b324cSopenharmony_ci { 3646370b324cSopenharmony_ci int next = s.Find(L':', i); 3647370b324cSopenharmony_ci if (next < 0) 3648370b324cSopenharmony_ci next = (int)s.Len(); 3649370b324cSopenharmony_ci const UString name = s.Mid(i, (unsigned)next - i); 3650370b324cSopenharmony_ci if (name.IsEmpty()) 3651370b324cSopenharmony_ci return false; 3652370b324cSopenharmony_ci if (!ParseTypeParams(name, type)) 3653370b324cSopenharmony_ci return false; 3654370b324cSopenharmony_ci i = (unsigned)next + 1; 3655370b324cSopenharmony_ci } 3656370b324cSopenharmony_ci 3657370b324cSopenharmony_ci return true; 3658370b324cSopenharmony_ci} 3659370b324cSopenharmony_ci 3660370b324cSopenharmony_cibool ParseOpenTypes(CCodecs &codecs, const UString &s, CObjectVector<COpenType> &types) 3661370b324cSopenharmony_ci{ 3662370b324cSopenharmony_ci types.Clear(); 3663370b324cSopenharmony_ci bool isHashType = false; 3664370b324cSopenharmony_ci for (unsigned pos = 0; pos < s.Len();) 3665370b324cSopenharmony_ci { 3666370b324cSopenharmony_ci int pos2 = s.Find(L'.', pos); 3667370b324cSopenharmony_ci if (pos2 < 0) 3668370b324cSopenharmony_ci pos2 = (int)s.Len(); 3669370b324cSopenharmony_ci UString name = s.Mid(pos, (unsigned)pos2 - pos); 3670370b324cSopenharmony_ci if (name.IsEmpty()) 3671370b324cSopenharmony_ci return false; 3672370b324cSopenharmony_ci COpenType type; 3673370b324cSopenharmony_ci if (!ParseType(codecs, name, type)) 3674370b324cSopenharmony_ci return false; 3675370b324cSopenharmony_ci if (isHashType) 3676370b324cSopenharmony_ci return false; 3677370b324cSopenharmony_ci if (type.IsHashType) 3678370b324cSopenharmony_ci isHashType = true; 3679370b324cSopenharmony_ci types.Add(type); 3680370b324cSopenharmony_ci pos = (unsigned)pos2 + 1; 3681370b324cSopenharmony_ci } 3682370b324cSopenharmony_ci return true; 3683370b324cSopenharmony_ci} 3684370b324cSopenharmony_ci 3685370b324cSopenharmony_ci/* 3686370b324cSopenharmony_cibool IsHashType(const CObjectVector<COpenType> &types) 3687370b324cSopenharmony_ci{ 3688370b324cSopenharmony_ci if (types.Size() != 1) 3689370b324cSopenharmony_ci return false; 3690370b324cSopenharmony_ci return types[0].IsHashType; 3691370b324cSopenharmony_ci} 3692370b324cSopenharmony_ci*/ 3693370b324cSopenharmony_ci 3694370b324cSopenharmony_ci 3695370b324cSopenharmony_ci#endif 3696