// OpenArchive.cpp

#include "StdAfx.h"

// #define SHOW_DEBUG_INFO

#ifdef SHOW_DEBUG_INFO
#include <stdio.h>
#endif

#include "../../../../C/CpuArch.h"

#include "../../../Common/ComTry.h"
#include "../../../Common/IntToString.h"
#include "../../../Common/StringConvert.h"
#include "../../../Common/StringToInt.h"
#include "../../../Common/Wildcard.h"

#include "../../../Windows/FileDir.h"

#include "../../Common/FileStreams.h"
#include "../../Common/LimitedStreams.h"
#include "../../Common/ProgressUtils.h"
#include "../../Common/StreamUtils.h"

#include "../../Compress/CopyCoder.h"

#include "DefaultName.h"
#include "OpenArchive.h"

#ifndef _SFX
#include "SetProperties.h"
#endif

#ifdef SHOW_DEBUG_INFO
#define PRF(x) x
#else
#define PRF(x)
#endif

// increase it, if you need to support larger SFX stubs
static const UInt64 kMaxCheckStartPosition = 1 << 22;

/*
Open:
  - formatIndex >= 0 (exact Format)
       1) Open with main type. Archive handler is allowed to use archive start finder.
          Warning, if there is tail.
  
  - formatIndex = -1 (Parser:0) (default)
    - same as #1 but doesn't return Parser

  - formatIndex = -2 (#1)
    - file has supported extension (like a.7z)
      Open with that main type (only starting from start of file).
        - open OK:
            - if there is no tail - return OK
            - if there is tail:
              - archive is not "Self Exe" - return OK with Warning, that there is tail
              - archive is "Self Exe"
                ignore "Self Exe" stub, and tries to open tail
                  - tail can be open as archive - shows that archive and stub size property.
                  - tail can't be open as archive - shows Parser ???
        - open FAIL:
           Try to open with all other types from offset 0 only.
           If some open type is OK and physical archive size is uequal or larger
           than file size, then return that archive with warning that can not be open as [extension type].
           If extension was EXE, it will try to open as unknown_extension case
    - file has unknown extension (like a.hhh)
       It tries to open via parser code.
         - if there is full archive or tail archive and unknown block or "Self Exe"
           at front, it shows tail archive and stub size property.
         - in another cases, if there is some archive inside file, it returns parser/
         - in another cases, it retuens S_FALSE

       
  - formatIndex = -3 (#2)
    - same as #1, but
    - stub (EXE) + archive is open in Parser

  - formatIndex = -4 (#3)
    - returns only Parser. skip full file archive. And show other sub-archives

  - formatIndex = -5 (#4)
    - returns only Parser. skip full file archive. And show other sub-archives for each byte pos

*/




using namespace NWindows;

/*
#ifdef _SFX
#define OPEN_PROPS_PARAM
#else
#define OPEN_PROPS_PARAM  , props
#endif
*/

/*
CArc::~CArc()
{
  GetRawProps.Release();
  Archive.Release();
  printf("\nCArc::~CArc()\n");
}
*/

#ifndef _SFX

namespace NArchive {
namespace NParser {

struct CParseItem
{
  UInt64 Offset;
  UInt64 Size;
  // UInt64 OkSize;
  UString Name;
  UString Extension;
  FILETIME FileTime;
  UString Comment;
  UString ArcType;
  
  bool FileTime_Defined;
  bool UnpackSize_Defined;
  bool NumSubDirs_Defined;
  bool NumSubFiles_Defined;

  bool IsSelfExe;
  bool IsNotArcType;
  
  UInt64 UnpackSize;
  UInt64 NumSubDirs;
  UInt64 NumSubFiles;

  int FormatIndex;

  bool LenIsUnknown;

  CParseItem():
      LenIsUnknown(false),
      FileTime_Defined(false),
      UnpackSize_Defined(false),
      NumSubFiles_Defined(false),
      NumSubDirs_Defined(false),
      IsSelfExe(false),
      IsNotArcType(false)
      // OkSize(0)
    {}

  /*
  bool IsEqualTo(const CParseItem &item) const
  {
    return Offset == item.Offset && Size == item.Size;
  }
  */

  void NormalizeOffset()
  {
    if ((Int64)Offset < 0)
    {
      Size += Offset;
      // OkSize += Offset;
      Offset = 0;
    }
  }
};

class CHandler:
  public IInArchive,
  public IInArchiveGetStream,
  public CMyUnknownImp
{
public:
  CObjectVector<CParseItem> _items;
  UInt64 _maxEndOffset;
  CMyComPtr<IInStream> _stream;

  MY_UNKNOWN_IMP2(
    IInArchive,
    IInArchiveGetStream)

  INTERFACE_IInArchive(;)
  STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);

  UInt64 GetLastEnd() const
  {
    if (_items.IsEmpty())
      return 0;
    const CParseItem &back = _items.Back();
    return back.Offset + back.Size;
  }

  void AddUnknownItem(UInt64 next);
  int FindInsertPos(const CParseItem &item);
  void AddItem(const CParseItem &item);
  // void Init();
  
  CHandler()
  {
    _maxEndOffset = 0;
  }
};

int CHandler::FindInsertPos(const CParseItem &item)
{
  unsigned left = 0, right = _items.Size();
  while (left != right)
  {
    unsigned mid = (left + right) / 2;
    const CParseItem & midItem = _items[mid];
    if (item.Offset < midItem.Offset)
      right = mid;
    else if (item.Offset > midItem.Offset)
      left = mid + 1;
    else if (item.Size < midItem.Size)
      right = mid;
    else if (item.Size > midItem.Size)
      left = mid + 1;
    else
    {
      left = mid + 1;
      // return -1;
    }
  }
  return left;
}

void CHandler::AddUnknownItem(UInt64 next)
{
  /*
  UInt64 prevEnd = 0;
  if (!_items.IsEmpty())
  {
    const CParseItem &back = _items.Back();
    prevEnd = back.Offset + back.Size;
  }
  */
  if (_maxEndOffset < next)
  {
    CParseItem item2;
    item2.Offset = _maxEndOffset;
    item2.Size = next - _maxEndOffset;
    _maxEndOffset = next;
    _items.Add(item2);
  }
  else if (_maxEndOffset > next && !_items.IsEmpty())
  {
    CParseItem &back = _items.Back();
    if (back.LenIsUnknown)
    {
      back.Size = next - back.Offset;
      _maxEndOffset = next;
    }
  }
}

void CHandler::AddItem(const CParseItem &item)
{
  AddUnknownItem(item.Offset);
  int pos = FindInsertPos(item);
  if (pos >= 0)
  {
    _items.Insert(pos, item);
    UInt64 next = item.Offset + item.Size;
    if (_maxEndOffset < next)
      _maxEndOffset = next;
  }
}

/*
static const STATPROPSTG kProps[] =
{
  { NULL, kpidPath, VT_BSTR},
  { NULL, kpidSize, VT_UI8},
  { NULL, kpidMTime, VT_FILETIME},
  { NULL, kpidType, VT_BSTR},
  { NULL, kpidComment, VT_BSTR},
  { NULL, kpidOffset, VT_UI8},
  { NULL, kpidUnpackSize, VT_UI8},
//   { NULL, kpidNumSubDirs, VT_UI8},
};
*/

static const Byte kProps[] =
{
  kpidPath,
  kpidSize,
  kpidMTime,
  kpidType,
  kpidComment,
  kpidOffset,
  kpidUnpackSize
};

IMP_IInArchive_Props
IMP_IInArchive_ArcProps_NO

STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback * /* openArchiveCallback */)
{
  COM_TRY_BEGIN
  {
    Close();
    _stream = stream;
  }
  return S_OK;
  COM_TRY_END
}

STDMETHODIMP CHandler::Close()
{
  _items.Clear();
  _stream.Release();
  return S_OK;
}

STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{
  *numItems = _items.Size();
  return S_OK;
}

STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
  COM_TRY_BEGIN
  NCOM::CPropVariant prop;

  const CParseItem &item = _items[index];

  switch (propID)
  {
    case kpidPath:
    {
      wchar_t sz[32];
      ConvertUInt32ToString(index + 1, sz);
      UString s = sz;
      if (!item.Name.IsEmpty())
      {
        s += L'.';
        s += item.Name;
      }
      if (!item.Extension.IsEmpty())
      {
        s += L'.';
        s += item.Extension;
      }
      prop = s; break;
    }
    case kpidSize:
    case kpidPackSize: prop = item.Size; break;
    case kpidOffset: prop = item.Offset; break;
    case kpidUnpackSize: if (item.UnpackSize_Defined) prop = item.UnpackSize; break;
    case kpidNumSubFiles: if (item.NumSubFiles_Defined) prop = item.NumSubFiles; break;
    case kpidNumSubDirs: if (item.NumSubDirs_Defined) prop = item.NumSubDirs; break;
    case kpidMTime: if (item.FileTime_Defined) prop = item.FileTime; break;
    case kpidComment: if (!item.Comment.IsEmpty()) prop = item.Comment; break;
    case kpidType: if (!item.ArcType.IsEmpty()) prop = item.ArcType; break;
  }
  prop.Detach(value);
  return S_OK;
  COM_TRY_END
}

HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
    Int32 testMode, IArchiveExtractCallback *extractCallback)
{
  COM_TRY_BEGIN
  bool allFilesMode = (numItems == (UInt32)(Int32)-1);
  if (allFilesMode)
    numItems = _items.Size();
  if (_stream && numItems == 0)
    return S_OK;
  UInt64 totalSize = 0;
  UInt32 i;
  for (i = 0; i < numItems; i++)
    totalSize += _items[allFilesMode ? i : indices[i]].Size;
  extractCallback->SetTotal(totalSize);

  totalSize = 0;
  
  CLocalProgress *lps = new CLocalProgress;
  CMyComPtr<ICompressProgressInfo> progress = lps;
  lps->Init(extractCallback, false);

  CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
  CMyComPtr<ISequentialInStream> inStream(streamSpec);
  streamSpec->SetStream(_stream);

  CLimitedSequentialOutStream *outStreamSpec = new CLimitedSequentialOutStream;
  CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);

  NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
  CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;

  for (i = 0; i < numItems; i++)
  {
    lps->InSize = totalSize;
    lps->OutSize = totalSize;
    RINOK(lps->SetCur());
    CMyComPtr<ISequentialOutStream> realOutStream;
    Int32 askMode = testMode ?
        NExtract::NAskMode::kTest :
        NExtract::NAskMode::kExtract;
    Int32 index = allFilesMode ? i : indices[i];
    const CParseItem &item = _items[index];

    RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
    UInt64 unpackSize = item.Size;
    totalSize += unpackSize;
    bool skipMode = false;
    if (!testMode && !realOutStream)
      continue;
    RINOK(extractCallback->PrepareOperation(askMode));

    outStreamSpec->SetStream(realOutStream);
    realOutStream.Release();
    outStreamSpec->Init(skipMode ? 0 : unpackSize, true);

    Int32 opRes = NExtract::NOperationResult::kOK;
    RINOK(_stream->Seek(item.Offset, STREAM_SEEK_SET, NULL));
    streamSpec->Init(unpackSize);
    RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));

    if (outStreamSpec->GetRem() != 0)
      opRes = NExtract::NOperationResult::kDataError;
    outStreamSpec->ReleaseStream();
    RINOK(extractCallback->SetOperationResult(opRes));
  }
  return S_OK;
  COM_TRY_END
}


STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
{
  COM_TRY_BEGIN
  const CParseItem &item = _items[index];
  return CreateLimitedInStream(_stream, item.Offset, item.Size, stream);
  COM_TRY_END
}

}}

#endif

HRESULT Archive_GetItemBoolProp(IInArchive *arc, UInt32 index, PROPID propID, bool &result) throw()
{
  NCOM::CPropVariant prop;
  result = false;
  RINOK(arc->GetProperty(index, propID, &prop));
  if (prop.vt == VT_BOOL)
    result = VARIANT_BOOLToBool(prop.boolVal);
  else if (prop.vt != VT_EMPTY)
    return E_FAIL;
  return S_OK;
}

HRESULT Archive_IsItem_Folder(IInArchive *arc, UInt32 index, bool &result) throw()
{
  return Archive_GetItemBoolProp(arc, index, kpidIsDir, result);
}

HRESULT Archive_IsItem_Aux(IInArchive *arc, UInt32 index, bool &result) throw()
{
  return Archive_GetItemBoolProp(arc, index, kpidIsAux, result);
}

HRESULT Archive_IsItem_AltStream(IInArchive *arc, UInt32 index, bool &result) throw()
{
  return Archive_GetItemBoolProp(arc, index, kpidIsAltStream, result);
}

HRESULT Archive_IsItem_Deleted(IInArchive *arc, UInt32 index, bool &result) throw()
{
  return Archive_GetItemBoolProp(arc, index, kpidIsDeleted, result);
}

static HRESULT Archive_GetArcBoolProp(IInArchive *arc, PROPID propid, bool &result)
{
  NCOM::CPropVariant prop;
  result = false;
  RINOK(arc->GetArchiveProperty(propid, &prop));
  if (prop.vt == VT_BOOL)
    result = VARIANT_BOOLToBool(prop.boolVal);
  else if (prop.vt != VT_EMPTY)
    return E_FAIL;
  return S_OK;
}

static HRESULT Archive_GetArcProp_UInt(IInArchive *arc, PROPID propid, UInt64 &result, bool &defined)
{
  defined = false;
  NCOM::CPropVariant prop;
  RINOK(arc->GetArchiveProperty(propid, &prop));
  switch (prop.vt)
  {
    case VT_UI4: result = prop.ulVal; defined = true; break;
    case VT_I4: result = prop.lVal; defined = true; break;
    case VT_UI8: result = (UInt64)prop.uhVal.QuadPart; defined = true; break;
    case VT_I8: result = (UInt64)prop.hVal.QuadPart; defined = true; break;
    case VT_EMPTY: break;
    default: return E_FAIL;
  }
  return S_OK;
}

static HRESULT Archive_GetArcProp_Int(IInArchive *arc, PROPID propid, Int64 &result, bool &defined)
{
  defined = false;
  NCOM::CPropVariant prop;
  RINOK(arc->GetArchiveProperty(propid, &prop));
  switch (prop.vt)
  {
    case VT_UI4: result = prop.ulVal; defined = true; break;
    case VT_I4: result = prop.lVal; defined = true; break;
    case VT_UI8: result = (Int64)prop.uhVal.QuadPart; defined = true; break;
    case VT_I8: result = (Int64)prop.hVal.QuadPart; defined = true; break;
    case VT_EMPTY: break;
    default: return E_FAIL;
  }
  return S_OK;
}

HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const
{
  if (!GetRawProps)
    return E_FAIL;
  UInt32 curIndex = index;
  bool prevWasAltStream = false;
  for (;;)
  {
    UString s;
    
    #ifdef MY_CPU_LE
    const void *p;
    UInt32 size;
    UInt32 propType;
    RINOK(GetRawProps->GetRawProp(curIndex, kpidName, &p, &size, &propType));
    if (p && propType == PROP_DATA_TYPE_wchar_t_PTR_Z_LE)
      s = (const wchar_t *)p;
    else
    #endif
    {
      NCOM::CPropVariant prop;
      RINOK(Archive->GetProperty(curIndex, kpidName, &prop));
      if (prop.vt == VT_BSTR)
        s = prop.bstrVal;
      else if (prop.vt == VT_EMPTY)
        s = L"[Content]";
      else
        return E_FAIL;
    }
    
    if (prevWasAltStream)
      parts[0] = s + L":" + parts[0];
    else
      parts.Insert(0, s);

    UInt32 curParent = (UInt32)(Int32)-1;
    UInt32 parentType = 0;
    RINOK(GetRawProps->GetParent(curIndex, &curParent, &parentType));
    if (parent == curParent)
      return S_OK;
    if (curParent == (UInt32)(Int32)-1)
      return E_FAIL;
    prevWasAltStream = (parentType == NParentType::kAltStream);
    curIndex = curParent;
  }
}

HRESULT CArc::GetItemPath(UInt32 index, UString &result) const
{
  #ifdef MY_CPU_LE
  if (GetRawProps)
  {
    const void *p;
    UInt32 size;
    UInt32 propType;
    if (!IsTree)
    {
      if (GetRawProps->GetRawProp(index, kpidPath, &p, &size, &propType) == S_OK &&
          propType == NPropDataType::kUtf16z)
      {
        unsigned len = size / 2 - 1;
        wchar_t *s = result.GetBuffer(len);
        for (unsigned i = 0; i < len; i++)
        {
          wchar_t c = GetUi16(p);
          p = (const void *)((const Byte *)p + 2);
          #if WCHAR_PATH_SEPARATOR != L'/'
          if (c == L'/')
            c = WCHAR_PATH_SEPARATOR;
          #endif
          *s++ = c;
        }
        result.ReleaseBuffer(len);
        if (len != 0)
          return S_OK;
      }
    }
    /*
    else if (GetRawProps->GetRawProp(index, kpidName, &p, &size, &propType) == S_OK &&
        p && propType == NPropDataType::kUtf16z)
    {
      UInt32 totalSize = size;
      bool isOK = false;
      {
        UInt32 index2 = index;
        for (;;)
        {
          UInt32 parent = (UInt32)(Int32)-1;
          UInt32 parentType = 0;
          if (GetRawProps->GetParent(index2, &parent, &parentType) != S_OK)
            break;
          if (parent == (UInt32)(Int32)-1)
          {
            isOK = true;
            break;
          }
          index2 = parent;
          UInt32 size2;
          const void *p2;
          if (GetRawProps->GetRawProp(index2, kpidName, &p2, &size2, &propType) != S_OK)
            break;
          totalSize += size2;
        }
      }

      if (isOK)
      {
        wchar_t *sz = result.GetBuffer(totalSize / 2);
        UInt32 pos = totalSize - size;
        memcpy((Byte *)sz + pos, p, size - 2);
        UInt32 index2 = index;
        for (;;)
        {
          UInt32 parent = (UInt32)(Int32)-1;
          UInt32 parentType = 0;
          if (GetRawProps->GetParent(index2, &parent, &parentType) != S_OK)
            break;
          if (parent == (UInt32)(Int32)-1)
            break;
          index2 = parent;
          UInt32 size2;
          const void *p2;
          if (GetRawProps->GetRawProp(index2, kpidName, &p2, &size2, &propType) != S_OK)
            break;
          pos -= size2;
          memcpy((Byte *)sz + pos, p2, size2);
          sz[(pos + size2 - 2) / 2] = (parentType == 0) ? WCHAR_PATH_SEPARATOR : L':';
        }
        result.ReleaseBuffer((totalSize - 2) / 2);
        #ifdef _WIN32
        // result.Replace(L'/', WCHAR_PATH_SEPARATOR);
        #endif
        return S_OK;
      }
    }
    */
  }
  #endif
  
  {
    NCOM::CPropVariant prop;
    RINOK(Archive->GetProperty(index, kpidPath, &prop));
    if (prop.vt == VT_BSTR)
      result = prop.bstrVal;
    else if (prop.vt == VT_EMPTY)
      result.Empty();
    else
      return E_FAIL;
  }
  
  if (result.IsEmpty())
  {
    result = DefaultName;
    NCOM::CPropVariant prop;
    RINOK(Archive->GetProperty(index, kpidExtension, &prop));
    if (prop.vt == VT_BSTR)
    {
      result += L'.';
      result += prop.bstrVal;
    }
    else if (prop.vt != VT_EMPTY)
      return E_FAIL;
  }
  return S_OK;
}

HRESULT CArc::GetItemPath2(UInt32 index, UString &result) const
{
  RINOK(GetItemPath(index, result));
  if (Ask_Deleted)
  {
    bool isDeleted = false;
    RINOK(Archive_IsItem_Deleted(Archive, index, isDeleted));
    if (isDeleted)
      result.Insert(0, L"[DELETED]" WSTRING_PATH_SEPARATOR);
  }
  return S_OK;
}

#ifndef _SFX

static HRESULT Archive_GetItem_Size(IInArchive *archive, UInt32 index, UInt64 &size, bool &defined)
{
  NCOM::CPropVariant prop;
  defined = false;
  size = 0;
  RINOK(archive->GetProperty(index, kpidSize, &prop));
  switch (prop.vt)
  {
    case VT_UI1: size = prop.bVal; break;
    case VT_UI2: size = prop.uiVal; break;
    case VT_UI4: size = prop.ulVal; break;
    case VT_UI8: size = (UInt64)prop.uhVal.QuadPart; break;
    case VT_EMPTY: return S_OK;
    default: return E_FAIL;
  }
  defined = true;
  return S_OK;
}

#endif

HRESULT CArc::GetItemSize(UInt32 index, UInt64 &size, bool &defined) const
{
  NCOM::CPropVariant prop;
  defined = false;
  size = 0;
  RINOK(Archive->GetProperty(index, kpidSize, &prop));
  switch (prop.vt)
  {
    case VT_UI1: size = prop.bVal; break;
    case VT_UI2: size = prop.uiVal; break;
    case VT_UI4: size = prop.ulVal; break;
    case VT_UI8: size = (UInt64)prop.uhVal.QuadPart; break;
    case VT_EMPTY: return S_OK;
    default: return E_FAIL;
  }
  defined = true;
  return S_OK;
}

HRESULT CArc::GetItemMTime(UInt32 index, FILETIME &ft, bool &defined) const
{
  NCOM::CPropVariant prop;
  defined = false;
  ft.dwHighDateTime = ft.dwLowDateTime = 0;
  RINOK(Archive->GetProperty(index, kpidMTime, &prop));
  if (prop.vt == VT_FILETIME)
  {
    ft = prop.filetime;
    defined = true;
  }
  else if (prop.vt != VT_EMPTY)
    return E_FAIL;
  else if (MTimeDefined)
  {
    ft = MTime;
    defined = true;
  }
  return S_OK;
}

#ifndef _SFX

static inline bool TestSignature(const Byte *p1, const Byte *p2, size_t size)
{
  for (size_t i = 0; i < size; i++)
    if (p1[i] != p2[i])
      return false;
  return true;
}

static void MakeCheckOrder(CCodecs *codecs,
    CIntVector &orderIndices, unsigned numTypes, CIntVector &orderIndices2,
    const Byte *data, size_t dataSize)
{
  for (unsigned i = 0; i < numTypes; i++)
  {
    int index = orderIndices[i];
    if (index < 0)
      continue;
    const CArcInfoEx &ai = codecs->Formats[index];
    if (ai.SignatureOffset != 0)
    {
      orderIndices2.Add(index);
      orderIndices[i] = -1;
      continue;
    }

    const CObjectVector<CByteBuffer> &sigs = ai.Signatures;
    FOR_VECTOR (k, sigs)
    {
      const CByteBuffer &sig = sigs[k];
      if (sig.Size() == 0 && dataSize == 0 ||
          sig.Size() != 0 && sig.Size() <= dataSize &&
          TestSignature(data, sig, sig.Size()))
      {
        orderIndices2.Add(index);
        orderIndices[i] = -1;
        break;
      }
    }
  }
}

#endif

#ifdef UNDER_CE
  static const unsigned kNumHashBytes = 1;
  #define HASH_VAL(buf, pos) ((buf)[pos])
#else
  static const unsigned kNumHashBytes = 2;
  #define HASH_VAL(buf, pos) ((buf)[pos] | ((UInt32)(buf)[pos + 1] << 8))
#endif


#ifndef _SFX

static bool IsExeExt(const UString &ext)
{
  return ext.IsEqualToNoCase(L"exe");
}

static const char *k_PreArcFormats[] =
{
    "pe"
  , "elf"
  , "macho"
  , "mub"
  , "te"
};

static bool IsNameFromList(const UString &s, const char *names[], size_t num)
{
  for (unsigned i = 0; i < num; i++)
    if (StringsAreEqualNoCase_Ascii(s, names[i]))
      return true;
  return false;
}


static bool IsPreArcFormat(const CArcInfoEx &ai)
{
  if (ai.Flags_PreArc())
    return true;
  return IsNameFromList(ai.Name, k_PreArcFormats, ARRAY_SIZE(k_PreArcFormats));
}

static const char *k_Formats_with_simple_signuature[] =
{
    "7z"
  , "xz"
  , "rar"
  , "bzip2"
  , "gzip"
  , "cab"
  , "wim"
  , "rpm"
  , "vhd"
  , "xar"
};

static bool IsNewStyleSignature(const CArcInfoEx &ai)
{
  // if (ai.Version >= 0x91F)
  if (ai.NewInterface)
    return true;
  return IsNameFromList(ai.Name, k_Formats_with_simple_signuature, ARRAY_SIZE(k_Formats_with_simple_signuature));
}

class CArchiveOpenCallback_Offset:
  public IArchiveOpenCallback,
  #ifndef _NO_CRYPTO
  public ICryptoGetTextPassword,
  #endif
  public CMyUnknownImp
{
public:
  CMyComPtr<IArchiveOpenCallback> Callback;
  UInt64 Files;
  UInt64 Offset;
  
  #ifndef _NO_CRYPTO
  CMyComPtr<ICryptoGetTextPassword> GetTextPassword;
  MY_UNKNOWN_IMP2(
      IArchiveOpenCallback,
      ICryptoGetTextPassword)
  #else
  MY_UNKNOWN_IMP1(IArchiveOpenCallback)
  #endif
  STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes);
  STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes);
  #ifndef _NO_CRYPTO
  STDMETHOD(CryptoGetTextPassword)(BSTR *password);
  #endif
};

#ifndef _NO_CRYPTO
STDMETHODIMP CArchiveOpenCallback_Offset::CryptoGetTextPassword(BSTR *password)
{
  COM_TRY_BEGIN
  if (GetTextPassword)
    return GetTextPassword->CryptoGetTextPassword(password);
  return E_NOTIMPL;
  COM_TRY_END
}
#endif

STDMETHODIMP CArchiveOpenCallback_Offset::SetTotal(const UInt64 * /* files */, const UInt64 * /* bytes */)
{
  return S_OK;
}

STDMETHODIMP CArchiveOpenCallback_Offset::SetCompleted(const UInt64 * /* files */, const UInt64 *bytes)
{
  if (!Callback)
    return S_OK;
  UInt64 value = Offset;
  if (bytes)
    value += *bytes;
  return Callback->SetCompleted(&Files, &value);
}

#endif

UInt32 GetOpenArcErrorFlags(const NCOM::CPropVariant &prop, bool *isDefinedProp)
{
  if (isDefinedProp != NULL)
    *isDefinedProp = false;

  switch (prop.vt)
  {
    case VT_UI8: if (isDefinedProp) *isDefinedProp = true; return (UInt32)prop.uhVal.QuadPart;
    case VT_UI4: if (isDefinedProp) *isDefinedProp = true; return prop.ulVal;
    case VT_EMPTY: return 0;
    default: throw 151199;
  }
}

void CArcErrorInfo::ClearErrors()
{
  // ErrorFormatIndex = -1; // we don't need to clear ErrorFormatIndex here !!!

  ThereIsTail = false;
  UnexpecedEnd = false;
  IgnoreTail = false;
  // NonZerosTail = false;
  ErrorFlags_Defined = false;
  ErrorFlags = 0;
  WarningFlags = 0;
  TailSize = 0;

  ErrorMessage.Empty();
  WarningMessage.Empty();
}

HRESULT CArc::ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openRes)
{
  // OkPhySize_Defined = false;
  PhySizeDefined = false;
  PhySize = 0;
  Offset = 0;
  AvailPhySize = FileSize - startPos;

  ErrorInfo.ClearErrors();
  {
    NCOM::CPropVariant prop;
    RINOK(archive->GetArchiveProperty(kpidErrorFlags, &prop));
    ErrorInfo.ErrorFlags = GetOpenArcErrorFlags(prop, &ErrorInfo.ErrorFlags_Defined);
  }
  {
    NCOM::CPropVariant prop;
    RINOK(archive->GetArchiveProperty(kpidWarningFlags, &prop));
    ErrorInfo.WarningFlags = GetOpenArcErrorFlags(prop);
  }

  {
    NCOM::CPropVariant prop;
    RINOK(archive->GetArchiveProperty(kpidError, &prop));
    if (prop.vt != VT_EMPTY)
      ErrorInfo.ErrorMessage = (prop.vt == VT_BSTR) ? prop.bstrVal : L"Unknown error";
  }
  
  {
    NCOM::CPropVariant prop;
    RINOK(archive->GetArchiveProperty(kpidWarning, &prop));
    if (prop.vt != VT_EMPTY)
      ErrorInfo.WarningMessage = (prop.vt == VT_BSTR) ? prop.bstrVal : L"Unknown warning";
  }
  
  if (openRes == S_OK || ErrorInfo.IsArc_After_NonOpen())
  {
    RINOK(Archive_GetArcProp_UInt(archive, kpidPhySize, PhySize, PhySizeDefined));
    /*
    RINOK(Archive_GetArcProp_UInt(archive, kpidOkPhySize, OkPhySize, OkPhySize_Defined));
    if (!OkPhySize_Defined)
    {
      OkPhySize_Defined = PhySizeDefined;
      OkPhySize = PhySize;
    }
    */

    bool offsetDefined;
    RINOK(Archive_GetArcProp_Int(archive, kpidOffset, Offset, offsetDefined));

    Int64 globalOffset = startPos + Offset;
    AvailPhySize = FileSize - globalOffset;
    if (PhySizeDefined)
    {
      UInt64 endPos = globalOffset + PhySize;
      if (endPos < FileSize)
      {
        AvailPhySize = PhySize;
        ErrorInfo.ThereIsTail = true;
        ErrorInfo.TailSize = FileSize - endPos;
      }
      else if (endPos > FileSize)
        ErrorInfo.UnexpecedEnd = true;
    }
  }

  return S_OK;
}

/*
static PrintNumber(const char *s, int n)
{
  char temp[100];
  sprintf(temp, "%s %d", s, n);
  OutputDebugStringA(temp);
}
*/

HRESULT CArc::PrepareToOpen(const COpenOptions &op, unsigned formatIndex, CMyComPtr<IInArchive> &archive)
{
  // OutputDebugStringW(L"a1");
  // PrintNumber("formatIndex", formatIndex);
    
  RINOK(op.codecs->CreateInArchive(formatIndex, archive));
  // OutputDebugStringW(L"a2");
  if (!archive)
    return S_OK;

  #ifdef EXTERNAL_CODECS
  {
    CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
    archive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
    if (setCompressCodecsInfo)
    {
      RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(op.codecs));
    }
  }
  #endif
  
  // OutputDebugStringW(ai.Name);
  // OutputDebugStringW(L"a3");
  
  #ifndef _SFX
  const CArcInfoEx &ai = op.codecs->Formats[formatIndex];
  if (ai.Flags_PreArc())
  {
    /* we notify parsers that extract executables, that they don't need
       to open archive, if there is tail after executable (for SFX cases) */
    CMyComPtr<IArchiveAllowTail> allowTail;
    archive.QueryInterface(IID_IArchiveAllowTail, (void **)&allowTail);
    if (allowTail)
      allowTail->AllowTail(BoolToInt(true));
  }
  if (op.props)
  {
    /*
    FOR_VECTOR (y, op.props)
    {
      const COptionalOpenProperties &optProps = (*op.props)[y];
      if (optProps.FormatName.IsEmpty() || optProps.FormatName.CompareNoCase(ai.Name) == 0)
      {
        RINOK(SetProperties(archive, optProps.Props));
        break;
      }
    }
    */
    RINOK(SetProperties(archive, *op.props));
  }
  #endif
  return S_OK;
}

#ifndef _SFX

static HRESULT ReadParseItemProps(IInArchive *archive, const CArcInfoEx &ai, NArchive::NParser::CParseItem &pi)
{
  pi.Extension = ai.GetMainExt();
  pi.FileTime_Defined = false;
  pi.ArcType = ai.Name;
  
  RINOK(Archive_GetArcBoolProp(archive, kpidIsNotArcType, pi.IsNotArcType));

  // RINOK(Archive_GetArcBoolProp(archive, kpidIsSelfExe, pi.IsSelfExe));
  pi.IsSelfExe = ai.Flags_PreArc();
  
  {
    NCOM::CPropVariant prop;
    RINOK(archive->GetArchiveProperty(kpidMTime, &prop));
    if (prop.vt == VT_FILETIME)
    {
      pi.FileTime_Defined = true;
      pi.FileTime = prop.filetime;
    }
  }
  
  if (!pi.FileTime_Defined)
  {
    NCOM::CPropVariant prop;
    RINOK(archive->GetArchiveProperty(kpidCTime, &prop));
    if (prop.vt == VT_FILETIME)
    {
      pi.FileTime_Defined = true;
      pi.FileTime = prop.filetime;
    }
  }
  
  {
    NCOM::CPropVariant prop;
    RINOK(archive->GetArchiveProperty(kpidName, &prop));
    if (prop.vt == VT_BSTR)
    {
      pi.Name = prop.bstrVal;
      pi.Extension.Empty();
    }
    else
    {
      RINOK(archive->GetArchiveProperty(kpidExtension, &prop));
      if (prop.vt == VT_BSTR)
        pi.Extension = prop.bstrVal;
    }
  }
  
  {
    NCOM::CPropVariant prop;
    RINOK(archive->GetArchiveProperty(kpidShortComment, &prop));
    if (prop.vt == VT_BSTR)
      pi.Comment = prop.bstrVal;
  }


  UInt32 numItems;
  RINOK(archive->GetNumberOfItems(&numItems));
  
  // pi.NumSubFiles = numItems;
  // RINOK(Archive_GetArcProp_UInt(archive, kpidUnpackSize, pi.UnpackSize, pi.UnpackSize_Defined));
  // if (!pi.UnpackSize_Defined)
  {
    pi.NumSubFiles = 0;
    pi.NumSubDirs = 0;
    pi.UnpackSize = 0;
    for (UInt32 i = 0; i < numItems; i++)
    {
      UInt64 size = 0;
      bool defined = false;
      Archive_GetItem_Size(archive, i, size, defined);
      if (defined)
      {
        pi.UnpackSize_Defined = true;
        pi.UnpackSize += size;
      }

      bool isDir = false;
      Archive_IsItem_Folder(archive, i, isDir);
      if (isDir)
        pi.NumSubDirs++;
      else
        pi.NumSubFiles++;
    }
    if (pi.NumSubDirs != 0)
      pi.NumSubDirs_Defined = true;
    pi.NumSubFiles_Defined = true;
  }

  return S_OK;
}

#endif

HRESULT CArc::CheckZerosTail(const COpenOptions &op, UInt64 offset)
{
  if (!op.stream)
    return S_OK;
  RINOK(op.stream->Seek(offset, STREAM_SEEK_SET, NULL));
  const UInt32 kBufSize = 1 << 11;
  Byte buf[kBufSize];
  
  for (;;)
  {
    UInt32 processed = 0;
    RINOK(op.stream->Read(buf, kBufSize, &processed));
    if (processed == 0)
    {
      // ErrorInfo.NonZerosTail = false;
      ErrorInfo.IgnoreTail = true;
      return S_OK;
    }
    for (size_t i = 0; i < processed; i++)
    {
      if (buf[i] != 0)
      {
        // ErrorInfo.IgnoreTail = false;
        // ErrorInfo.NonZerosTail = true;
        return S_OK;
      }
    }
  }
}

#ifndef _SFX

class CExtractCallback_To_OpenCallback:
  public IArchiveExtractCallback,
  public ICompressProgressInfo,
  public CMyUnknownImp
{
public:
  CMyComPtr<IArchiveOpenCallback> Callback;
  UInt64 Files;
  UInt64 Offset;

  MY_UNKNOWN_IMP2(IArchiveExtractCallback, ICompressProgressInfo)
  INTERFACE_IArchiveExtractCallback(;)
  STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
  void Init(IArchiveOpenCallback *callback)
  {
    Callback = callback;
    Files = 0;
    Offset = 0;
  }
};

STDMETHODIMP CExtractCallback_To_OpenCallback::SetTotal(UInt64 /* size */)
{
  return S_OK;
}

STDMETHODIMP CExtractCallback_To_OpenCallback::SetCompleted(const UInt64 * /* completeValue */)
{
  return S_OK;
}

STDMETHODIMP CExtractCallback_To_OpenCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */)
{
  if (Callback)
  {
    UInt64 value = Offset;
    if (inSize)
      value += *inSize;
    return Callback->SetCompleted(&Files, &value);
  }
  return S_OK;
}

STDMETHODIMP CExtractCallback_To_OpenCallback::GetStream(UInt32 /* index */, ISequentialOutStream **outStream, Int32 /* askExtractMode */)
{
  *outStream = 0;
  return S_OK;
}

STDMETHODIMP CExtractCallback_To_OpenCallback::PrepareOperation(Int32 /* askExtractMode */)
{
  return S_OK;
}

STDMETHODIMP CExtractCallback_To_OpenCallback::SetOperationResult(Int32 /* operationResult */)
{
  return S_OK;
}

static HRESULT OpenArchiveSpec(IInArchive *archive, bool needPhySize,
    IInStream *stream, const UInt64 *maxCheckStartPosition,
    IArchiveOpenCallback *openCallback,
    IArchiveExtractCallback *extractCallback)
{
  /*
  if (needPhySize)
  {
    CMyComPtr<IArchiveOpen2> open2;
    archive->QueryInterface(IID_IArchiveOpen2, (void **)&open2);
    if (open2)
      return open2->ArcOpen2(stream, kOpenFlags_RealPhySize, openCallback);
  }
  */
  RINOK(archive->Open(stream, maxCheckStartPosition, openCallback));
  if (needPhySize)
  {
    bool phySize_Defined = false;
    UInt64 phySize = 0;
    RINOK(Archive_GetArcProp_UInt(archive, kpidPhySize, phySize, phySize_Defined));
    if (phySize_Defined)
      return S_OK;

    bool phySizeCantBeDetected = false;;
    RINOK(Archive_GetArcBoolProp(archive, kpidPhySizeCantBeDetected, phySizeCantBeDetected));

    if (!phySizeCantBeDetected)
    {
      RINOK(archive->Extract(0, (UInt32)(Int32)-1, BoolToInt(true), extractCallback));
    }
  }
  return S_OK;
}

static int FindFormatForArchiveType(CCodecs *codecs, CIntVector orderIndices, const char *name)
{
  FOR_VECTOR (i, orderIndices)
    if (StringsAreEqualNoCase_Ascii(codecs->Formats[orderIndices[i]].Name, name))
      return i;
  return -1;
}

#endif

HRESULT CArc::OpenStream2(const COpenOptions &op)
{
  // fprintf(stdout, "\nOpen: %S", Path); fflush(stdout);

  Archive.Release();
  GetRawProps.Release();
  GetRootProps.Release();

  ErrorInfo.ClearErrors();
  ErrorInfo.ErrorFormatIndex = -1;

  IsParseArc = false;
  ArcStreamOffset = 0;
  
  // OutputDebugStringW(L"1");
  // OutputDebugStringW(Path);

  const UString fileName = ExtractFileNameFromPath(Path);
  UString extension;
  {
    int dotPos = fileName.ReverseFind(L'.');
    if (dotPos >= 0)
      extension = fileName.Ptr(dotPos + 1);
  }
  
  CIntVector orderIndices;
  
  bool searchMarkerInHandler = false;
  #ifdef _SFX
    searchMarkerInHandler = true;
  #endif

  CBoolArr isMainFormatArr(op.codecs->Formats.Size());
  {
    FOR_VECTOR(i, op.codecs->Formats)
      isMainFormatArr[i] = false;
  }

  UInt64 maxStartOffset =
      op.openType.MaxStartOffset_Defined ?
      op.openType.MaxStartOffset :
      kMaxCheckStartPosition;

  #ifndef _SFX
  bool isUnknownExt = false;
  #endif

  bool isForced = false;
  unsigned numMainTypes = 0;
  int formatIndex = op.openType.FormatIndex;

  if (formatIndex >= 0)
  {
    isForced = true;
    orderIndices.Add(formatIndex);
    numMainTypes = 1;
    isMainFormatArr[formatIndex] = true;

    searchMarkerInHandler = true;
  }
  else
  {
    unsigned numFinded = 0;
    #ifndef _SFX
    bool isPrearcExt = false;
    #endif
    
    {
      FOR_VECTOR (i, op.codecs->Formats)
      {
        const CArcInfoEx &ai = op.codecs->Formats[i];

        if (IgnoreSplit || !op.openType.CanReturnArc)
          if (ai.IsSplit())
            continue;
        if (op.excludedFormats->FindInSorted(i) >= 0)
          continue;

        #ifndef _SFX
        if (IsPreArcFormat(ai))
          isPrearcExt = true;
        #endif

        if (ai.FindExtension(extension) >= 0)
        {
          // PrintNumber("orderIndices.Insert", i);
          orderIndices.Insert(numFinded++, i);
          isMainFormatArr[i] = true;
        }
        else
          orderIndices.Add(i);
      }
    }
  
    if (!op.stream)
    {
      if (numFinded != 1)
        return E_NOTIMPL;
      orderIndices.DeleteFrom(1);
    }
    // PrintNumber("numFinded", numFinded );

    /*
    if (op.openOnlySpecifiedByExtension)
    {
      if (numFinded != 0 && !IsExeExt(extension))
        orderIndices.DeleteFrom(numFinded);
    }
    */

    #ifndef _SFX

      if (op.stream && orderIndices.Size() >= 2)
      {
        RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL));
        CByteBuffer byteBuffer;
        CIntVector orderIndices2;
        if (numFinded == 0 || IsExeExt(extension))
        {
          // signature search was here
        }
        else if (extension == L"000" || extension == L"001")
        {
          int i = FindFormatForArchiveType(op.codecs, orderIndices, "rar");
          if (i >= 0)
          {
            const size_t kBufSize = (1 << 10);
            byteBuffer.Alloc(kBufSize);
            size_t processedSize = kBufSize;
            RINOK(ReadStream(op.stream, byteBuffer, &processedSize));
            if (processedSize >= 16)
            {
              const Byte *buf = byteBuffer;
              const Byte kRarHeader[] = { 0x52 , 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00 };
              if (TestSignature(buf, kRarHeader, 7) && buf[9] == 0x73 && (buf[10] & 1) != 0)
              {
                orderIndices2.Add(orderIndices[i]);
                orderIndices[i] = -1;
                if (i >= (int)numFinded)
                  numFinded++;
              }
            }
          }
        }
        else
        {
          const size_t kBufSize = (1 << 10);
          byteBuffer.Alloc(kBufSize);
          size_t processedSize = kBufSize;
          RINOK(ReadStream(op.stream, byteBuffer, &processedSize));
          if (processedSize == 0)
            return S_FALSE;
          
          /*
          check type order:
            1) matched extension, no signuature
            2) matched extension, matched signuature
            // 3) no signuature
            // 4) matched signuature
          */

          MakeCheckOrder(op.codecs, orderIndices, numFinded, orderIndices2, NULL, 0);
          MakeCheckOrder(op.codecs, orderIndices, numFinded, orderIndices2, byteBuffer, processedSize);
          // MakeCheckOrder(op.codecs, orderIndices, orderIndices.Size(), orderIndices2, NULL, 0);
          // MakeCheckOrder(op.codecs, orderIndices, orderIndices.Size(), orderIndices2, byteBuffer, processedSize);
        }
      
        FOR_VECTOR (i, orderIndices)
        {
          int val = orderIndices[i];
          if (val != -1)
            orderIndices2.Add(val);
        }
        orderIndices = orderIndices2;
      }
      
      if (orderIndices.Size() >= 2)
      {
        int iIso = FindFormatForArchiveType(op.codecs, orderIndices, "iso");
        int iUdf = FindFormatForArchiveType(op.codecs, orderIndices, "udf");
        if (iUdf > iIso && iIso >= 0)
        {
          int isoIndex = orderIndices[iIso];
          int udfIndex = orderIndices[iUdf];
          orderIndices[iUdf] = isoIndex;
          orderIndices[iIso] = udfIndex;
        }
      }

      numMainTypes = numFinded;
      isUnknownExt = (numMainTypes == 0) || isPrearcExt;

    #else // _SFX

      numMainTypes = orderIndices.Size();
    
    #endif
  }

  UInt64 fileSize = 0;
  if (op.stream)
  {
    RINOK(op.stream->Seek(0, STREAM_SEEK_END, &fileSize));
    RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL));
  }
  FileSize = fileSize;


  #ifndef _SFX

  CBoolArr skipFrontalFormat(op.codecs->Formats.Size());
  {
    FOR_VECTOR(i, op.codecs->Formats)
      skipFrontalFormat[i] = false;
  }
  
  #endif

  const COpenType &mode = op.openType;

  
  

  
  if (mode.CanReturnArc)
  {
    // ---------- OPEN main type by extenssion ----------
  
    unsigned numCheckTypes = orderIndices.Size();
    if (formatIndex >= 0)
      numCheckTypes = numMainTypes;
    
    for (unsigned i = 0; i < numCheckTypes; i++)
    {
      FormatIndex = orderIndices[i];
      const CArcInfoEx &ai = op.codecs->Formats[FormatIndex];
      // OutputDebugStringW(ai.Name);
      
      bool exactOnly = false;
      if (i >= numMainTypes)
      {
        if (!ai.Flags_BackwardOpen()
            // && !ai.Flags_PureStartOpen()
            )
          continue;
        exactOnly = true;
      }
      
      // Some handlers do not set total bytes. So we set it here
      RINOK(op.callback->SetTotal(NULL, &fileSize));
      if (op.stream)
      {
        RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL));
      }
      
      CMyComPtr<IInArchive> archive;
      
      RINOK(PrepareToOpen(op, FormatIndex, archive));
      if (!archive)
        continue;
      
      HRESULT result;
      if (op.stream)
      {
        UInt64 searchLimit = (!exactOnly && searchMarkerInHandler) ? maxStartOffset: 0;
        result = archive->Open(op.stream, &searchLimit, op.callback);
      }
      else
      {
        CMyComPtr<IArchiveOpenSeq> openSeq;
        archive.QueryInterface(IID_IArchiveOpenSeq, (void **)&openSeq);
        if (!openSeq)
          return E_NOTIMPL;
        result = openSeq->OpenSeq(op.seqStream);
      }
      
      RINOK(ReadBasicProps(archive, 0, result));
      
      if (result == S_FALSE)
      {
        bool isArc = ErrorInfo.IsArc_After_NonOpen();

        #ifndef _SFX
        // if it's archive, we allow another open attempt for parser
        if (!mode.CanReturnParser || !isArc)
          skipFrontalFormat[FormatIndex] = true;
        #endif
        
        if (exactOnly)
          continue;
        
        if (i == 0 && numMainTypes == 1)
        {
          // we set NonOpenErrorInfo, only if there is only one main format (defined by extension).
          ErrorInfo.ErrorFormatIndex = FormatIndex;
          NonOpen_ErrorInfo = ErrorInfo;
       
          if (!mode.CanReturnParser && isArc)
          {
            // if (formatIndex < 0 && !searchMarkerInHandler)
            {
              // if bad archive was detected, we don't need additional open attempts
              #ifndef _SFX
              if (!IsPreArcFormat(ai) /* || !mode.SkipSfxStub */)
              #endif
                return S_FALSE;
            }
          }
        }
        
        /*
        #ifndef _SFX
        if (IsExeExt(extension) || ai.Flags_PreArc())
        {
        // openOnlyFullArc = false;
        // canReturnTailArc = true;
        // limitSignatureSearch = true;
        }
        #endif
        */
        
        continue;
      }
      
      RINOK(result);
      
      #ifndef _SFX

      bool isMainFormat = isMainFormatArr[FormatIndex];
      const COpenSpecFlags &specFlags = mode.GetSpec(isForced, isMainFormat, isUnknownExt);

      bool thereIsTail = ErrorInfo.ThereIsTail;
      if (thereIsTail && mode.ZerosTailIsAllowed)
      {
        RINOK(CheckZerosTail(op, Offset + PhySize));
        if (ErrorInfo.IgnoreTail)
          thereIsTail = false;
      }

      if (Offset > 0)
      {
        if (exactOnly
            || !searchMarkerInHandler
            || !specFlags.CanReturn_NonStart()
            || (mode.MaxStartOffset_Defined && (UInt64)Offset > mode.MaxStartOffset))
          continue;
      }
      if (thereIsTail)
      {
        if (Offset > 0)
        {
          if (!specFlags.CanReturnMid)
            continue;
        }
        else if (!specFlags.CanReturnFrontal)
          continue;
      }

      if (Offset > 0 || thereIsTail)
      {
        if (formatIndex < 0)
        {
          if (IsPreArcFormat(ai))
          {
            // openOnlyFullArc = false;
            // canReturnTailArc = true;
            /*
            if (mode.SkipSfxStub)
            limitSignatureSearch = true;
            */
            // if (mode.SkipSfxStub)
            {
              // skipFrontalFormat[FormatIndex] = true;
              continue;
            }
          }
        }
      }
     
      #endif

      Archive = archive;
      return S_OK;
    }
  }

  

  #ifndef _SFX

  if (!op.stream)
    return S_FALSE;

  if (formatIndex >= 0 && !mode.CanReturnParser)
  {
    if (mode.MaxStartOffset_Defined)
    {
      if (mode.MaxStartOffset == 0)
        return S_FALSE;
    }
    else
    {
      const CArcInfoEx &ai = op.codecs->Formats[formatIndex];
      if (ai.FindExtension(extension) >= 0)
      {
        const CArcInfoEx &ai = op.codecs->Formats[formatIndex];
        if (ai.Flags_FindSignature() && searchMarkerInHandler)
          return S_FALSE;
      }
    }
  }

  NArchive::NParser::CHandler *handlerSpec = new NArchive::NParser::CHandler;
  CMyComPtr<IInArchive> handler = handlerSpec;

  CExtractCallback_To_OpenCallback *extractCallback_To_OpenCallback_Spec = new CExtractCallback_To_OpenCallback;
  CMyComPtr<IArchiveExtractCallback> extractCallback_To_OpenCallback = extractCallback_To_OpenCallback_Spec;
  extractCallback_To_OpenCallback_Spec->Init(op.callback);

  {
    // ---------- Check all possible START archives ----------
    // this code is better for full file archives than Parser's code.

    CByteBuffer byteBuffer;
    bool endOfFile = false;
    size_t processedSize;
    {
      size_t bufSize = 1 << 20; // it must be larger than max signature offset or IsArcFunc offset ((1 << 19) + x for UDF)
      if (bufSize > fileSize)
      {
        bufSize = (size_t)fileSize;
        endOfFile = true;
      }
      byteBuffer.Alloc(bufSize);
      RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL));
      processedSize = bufSize;
      RINOK(ReadStream(op.stream, byteBuffer, &processedSize));
      if (processedSize == 0)
        return S_FALSE;
      if (processedSize < bufSize)
        endOfFile = true;
    }
    CUIntVector sortedFormats;

    unsigned i;

    int splitIndex = -1;

    for (i = 0; i < orderIndices.Size(); i++)
    {
      unsigned form = orderIndices[i];
      if (skipFrontalFormat[form])
        continue;
      const CArcInfoEx &ai = op.codecs->Formats[form];
      if (ai.IsSplit())
      {
        splitIndex = form;
        continue;
      }

      if (ai.IsArcFunc)
      {
        UInt32 isArcRes = ai.IsArcFunc(byteBuffer, processedSize);
        if (isArcRes == k_IsArc_Res_NO)
          continue;
        if (isArcRes == k_IsArc_Res_NEED_MORE && endOfFile)
          continue;
        // if (isArcRes == k_IsArc_Res_YES_LOW_PROB) continue;
        sortedFormats.Insert(0, form);
        continue;
      }

      bool isNewStyleSignature = IsNewStyleSignature(ai);
      bool needCheck = !isNewStyleSignature
          || ai.Signatures.IsEmpty()
          || ai.Flags_PureStartOpen()
          || ai.Flags_StartOpen()
          || ai.Flags_BackwardOpen();
    
      if (isNewStyleSignature && !ai.Signatures.IsEmpty())
      {
        unsigned k;
        for (k = 0; k < ai.Signatures.Size(); k++)
        {
          const CByteBuffer &sig = ai.Signatures[k];
          UInt32 signatureEnd = ai.SignatureOffset + (UInt32)sig.Size();
          if (processedSize < signatureEnd)
          {
            if (!endOfFile)
              needCheck = true;
          }
          else if (memcmp(sig, byteBuffer + ai.SignatureOffset, sig.Size()) == 0)
            break;
        }
        if (k != ai.Signatures.Size())
        {
          sortedFormats.Insert(0, form);
          continue;
        }
      }
      if (needCheck)
        sortedFormats.Add(form);
    }

    if (splitIndex >= 0)
      sortedFormats.Insert(0, splitIndex);

    for (i = 0; i < sortedFormats.Size(); i++)
    {
      FormatIndex = sortedFormats[i];
      const CArcInfoEx &ai = op.codecs->Formats[FormatIndex];

      RINOK(op.callback->SetTotal(NULL, &fileSize));
      RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL));

      CMyComPtr<IInArchive> archive;
      RINOK(PrepareToOpen(op, FormatIndex, archive));
      if (!archive)
        continue;
      
      PRF(printf("\nSorted Open %S", (const wchar_t *)ai.Name));
      HRESULT result;
      {
        UInt64 searchLimit = 0;
        /*
        if (mode.CanReturnArc)
          result = archive->Open(op.stream, &searchLimit, op.callback);
        else
        */
        result = OpenArchiveSpec(archive, !mode.CanReturnArc, op.stream, &searchLimit, op.callback, extractCallback_To_OpenCallback);
      }
      
      if (result == S_FALSE)
      {
        skipFrontalFormat[FormatIndex] = true;
        // FIXME: maybe we must use LenIsUnknown.
        // printf("  OpenForSize Error");
        continue;
      }
      RINOK(result);

      RINOK(ReadBasicProps(archive, 0, result));

      if (Offset > 0)
      {
        continue; // good handler doesn't return such Offset > 0
        // but there are some cases like false prefixed PK00 archive, when
        // we can support it?
      }

      NArchive::NParser::CParseItem pi;
      pi.Offset = Offset;
      pi.Size = AvailPhySize;
      
      // bool needScan = false;

      if (!PhySizeDefined)
      {
        // it's for Z format
        pi.LenIsUnknown = true;
        // needScan = true;
        // phySize = arcRem;
        // nextNeedCheckStartOpen = false;
      }

      /*
      if (OkPhySize_Defined)
        pi.OkSize = pi.OkPhySize;
      else
        pi.OkSize = pi.Size;
      */

      pi.NormalizeOffset();
      // printf("  phySize = %8d", (unsigned)phySize);


      if (mode.CanReturnArc)
      {
        bool isMainFormat = isMainFormatArr[FormatIndex];
        const COpenSpecFlags &specFlags = mode.GetSpec(isForced, isMainFormat, isUnknownExt);
        bool openCur = false;

        if (!ErrorInfo.ThereIsTail)
          openCur = true;
        else
        {
          if (mode.ZerosTailIsAllowed)
          {
            RINOK(CheckZerosTail(op, Offset + PhySize));
            if (ErrorInfo.IgnoreTail)
              openCur = true;
          }
          if (!openCur)
          {
            openCur = specFlags.CanReturnFrontal;
            if (formatIndex < 0) // format is not forced
            {
              if (IsPreArcFormat(ai))
              {
                // if (mode.SkipSfxStub)
                {
                  openCur = false;
                }
              }
            }
          }
        }
        
        if (openCur)
        {
          InStream = op.stream;
          Archive = archive;
          return S_OK;
        }
      }
        
      skipFrontalFormat[FormatIndex] = true;


      // if (!mode.CanReturnArc)
      /*
      if (!ErrorInfo.ThereIsTail)
          continue;
      */
      if (pi.Offset == 0 && !pi.LenIsUnknown && pi.Size >= FileSize)
        continue;

      // printf("\nAdd offset = %d", (int)pi.Offset);
      RINOK(ReadParseItemProps(archive, ai, pi));
      handlerSpec->AddItem(pi);
    }
  }

  

  
  
  // ---------- PARSER ----------

  CUIntVector arc2sig; // formatIndex to signatureIndex
  CUIntVector sig2arc; // signatureIndex to formatIndex;
  {
    unsigned sum = 0;
    FOR_VECTOR (i, op.codecs->Formats)
    {
      arc2sig.Add(sum);
      const CObjectVector<CByteBuffer> &sigs = op.codecs->Formats[i].Signatures;
      sum += sigs.Size();
      FOR_VECTOR (k, sigs)
        sig2arc.Add(i);
    }
  }
  
  {
    CArchiveOpenCallback_Offset *openCallback_Offset_Spec = new CArchiveOpenCallback_Offset;
    CMyComPtr<IArchiveOpenCallback> openCallback_Offset = openCallback_Offset_Spec;

    const size_t kBeforeSize = 1 << 16;
    const size_t kAfterSize  = 1 << 20;
    const size_t kBufSize = 1 << 22; // it must be more than kBeforeSize + kAfterSize

    const UInt32 kNumVals = (UInt32)1 << (kNumHashBytes * 8);
    CByteArr hashBuffer(kNumVals);
    Byte *hash = hashBuffer;
    memset(hash, 0xFF, kNumVals);
    Byte prevs[256];
    memset(prevs, 0xFF, sizeof(prevs));
    if (sig2arc.Size() >= 0xFF)
      return S_FALSE;

    CUIntVector difficultFormats;
    CBoolArr difficultBools(256);
    {
      for (unsigned i = 0; i < 256; i++)
        difficultBools[i] = false;
    }

    bool thereAreHandlersForSearch = false;

    // UInt32 maxSignatureEnd = 0;
    
    FOR_VECTOR (i, orderIndices)
    {
      int index = orderIndices[i];
      if (index < 0)
        continue;
      const CArcInfoEx &ai = op.codecs->Formats[index];
      bool isDifficult = false;
      // if (ai.Version < 0x91F) // we don't use parser with old DLL (before 9.31)
      if (!ai.NewInterface)
        isDifficult = true;
      else
      {
        if (ai.Flags_StartOpen())
          isDifficult = true;
        FOR_VECTOR (k, ai.Signatures)
        {
          const CByteBuffer &sig = ai.Signatures[k];
          /*
          UInt32 signatureEnd = ai.SignatureOffset + (UInt32)sig.Size();
          if (maxSignatureEnd < signatureEnd)
            maxSignatureEnd = signatureEnd;
          */
          if (sig.Size() < kNumHashBytes)
          {
            isDifficult = true;
            continue;
          }
          thereAreHandlersForSearch = true;
          UInt32 v = HASH_VAL(sig, 0);
          unsigned sigIndex = arc2sig[index] + k;
          prevs[sigIndex] = hash[v];
          hash[v] = (Byte)sigIndex;
        }
      }
      if (isDifficult)
      {
        difficultFormats.Add(index);
        difficultBools[index] = true;
      }
    }
    
    if (!thereAreHandlersForSearch)
    {
      // openOnlyFullArc = true;
      // canReturnTailArc = true;
    }
    
    RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL));

    CLimitedCachedInStream *limitedStreamSpec = new CLimitedCachedInStream;
    CMyComPtr<IInStream> limitedStream = limitedStreamSpec;
    limitedStreamSpec->SetStream(op.stream);

    openCallback_Offset_Spec->Callback = op.callback;

    #ifndef _NO_CRYPTO
    if (op.callback)
    {
      openCallback_Offset_Spec->Callback.QueryInterface(IID_ICryptoGetTextPassword, &openCallback_Offset_Spec->GetTextPassword);
    }
    #endif

    RINOK(op.callback->SetTotal(NULL, &fileSize));
    CByteBuffer &byteBuffer = limitedStreamSpec->Buffer;
    byteBuffer.Alloc(kBufSize);

    UInt64 callbackPrev = 0;
    bool needCheckStartOpen = true; // = true, if we need to test all archives types for current pos.

    bool endOfFile = false;
    UInt64 bufPhyPos = 0;
    size_t bytesInBuf = 0;
    // UInt64 prevPos = 0;
    
    // ---------- Main Scan Loop ----------

    UInt64 pos = 0;

    if (!mode.EachPos && handlerSpec->_items.Size() == 1)
    {
      NArchive::NParser::CParseItem &pi = handlerSpec->_items[0];
      if (!pi.LenIsUnknown && pi.Offset == 0)
        pos = pi.Size;
    }

    for (;;)
    {
      // printf("\nPos = %d", (int)pos);
      UInt64 posInBuf = pos - bufPhyPos;
      
      // if (pos > ((UInt64)1 << 35)) break;
      
      if (!endOfFile)
      {
        if (bytesInBuf < kBufSize)
        {
          size_t processedSize = kBufSize - bytesInBuf;
          // printf("\nRead ask = %d", (unsigned)processedSize);
          UInt64 seekPos = bufPhyPos + bytesInBuf;
          RINOK(op.stream->Seek(bufPhyPos + bytesInBuf, STREAM_SEEK_SET, NULL));
          RINOK(ReadStream(op.stream, byteBuffer + bytesInBuf, &processedSize));
          // printf("   processed = %d", (unsigned)processedSize);
          if (processedSize == 0)
          {
            fileSize = seekPos;
            endOfFile = true;
          }
          else
          {
            bytesInBuf += processedSize;
            limitedStreamSpec->SetCache(processedSize, (size_t)bufPhyPos);
          }
          continue;
        }
        
        if (bytesInBuf < posInBuf)
        {
          UInt64 skipSize = posInBuf - bytesInBuf;
          if (skipSize <= kBeforeSize)
          {
            size_t keepSize = (size_t)(kBeforeSize - skipSize);
            // printf("\nmemmove skip = %d", (int)keepSize);
            memmove(byteBuffer, byteBuffer + bytesInBuf - keepSize, keepSize);
            bytesInBuf = keepSize;
            bufPhyPos = pos - keepSize;
            continue;
          }
          // printf("\nSkip %d", (int)(skipSize - kBeforeSize));
          // RINOK(op.stream->Seek(skipSize - kBeforeSize, STREAM_SEEK_CUR, NULL));
          bytesInBuf = 0;
          bufPhyPos = pos - kBeforeSize;
          continue;
        }
        
        if (bytesInBuf - posInBuf < kAfterSize)
        {
          size_t beg = (size_t)posInBuf - kBeforeSize;
          // printf("\nmemmove for after beg = %d", (int)beg);
          memmove(byteBuffer, byteBuffer + beg, bytesInBuf - beg);
          bufPhyPos += beg;
          bytesInBuf -= beg;
          continue;
        }
      }

      if (pos >= callbackPrev + (1 << 23))
      {
        openCallback_Offset_Spec->Files = handlerSpec->_items.Size();
        openCallback_Offset_Spec->Offset = pos;
        RINOK(openCallback_Offset->SetCompleted(NULL, NULL));
        callbackPrev = pos;
      }

      {
        UInt64 endPos = bufPhyPos + bytesInBuf;
        if (fileSize < endPos)
        {
          FileSize = fileSize; // why ????
          fileSize = endPos;
        }
      }

      size_t availSize = bytesInBuf - (size_t)posInBuf;
      if (availSize < kNumHashBytes)
        break;
      size_t scanSize = availSize -
          ((availSize >= kAfterSize) ? kAfterSize : kNumHashBytes);
  
      {
        /*
        UInt64 scanLimit = openOnlyFullArc ?
            maxSignatureEnd :
            op.openType.ScanSize + maxSignatureEnd;
        */
        if (!mode.CanReturnParser)
        {
          if (pos > maxStartOffset)
            break;
          UInt64 remScan = maxStartOffset - pos;
          if (scanSize > remScan)
            scanSize = (size_t)remScan;
        }
      }

      scanSize++;

      const Byte *buf = byteBuffer + (size_t)posInBuf;
      size_t ppp = 0;
      
      if (!needCheckStartOpen)
      {
        for (; ppp < scanSize && hash[HASH_VAL(buf, ppp)] == 0xFF; ppp++);
        pos += ppp;
        if (ppp == scanSize)
          continue;
      }
      
      UInt32 v = HASH_VAL(buf, ppp);
      bool nextNeedCheckStartOpen = true;
      unsigned i = hash[v];
      unsigned indexOfDifficult = 0;

      // ---------- Open Loop for Current Pos ----------
      bool wasOpen = false;
      
      for (;;)
      {
        unsigned index;
        bool isDifficult;
        if (needCheckStartOpen && indexOfDifficult < difficultFormats.Size())
        {
          index = difficultFormats[indexOfDifficult++];
          isDifficult = true;
        }
        else
        {
          if (i == 0xFF)
            break;
          index = sig2arc[i];
          unsigned sigIndex = i - arc2sig[index];
          i = prevs[i];
          if (needCheckStartOpen && difficultBools[index])
            continue;
          const CArcInfoEx &ai = op.codecs->Formats[index];

          if (pos < ai.SignatureOffset)
            continue;

          /*
          if (openOnlyFullArc)
            if (pos != ai.SignatureOffset)
              continue;
          */
  
          const CByteBuffer &sig = ai.Signatures[sigIndex];

          if (ppp + sig.Size() > availSize
              || !TestSignature(buf + ppp, sig, sig.Size()))
            continue;
          // printf("\nSignature OK: %10S %8x %5d", (const wchar_t *)ai.Name, (int)pos, (int)(pos - prevPos));
          // prevPos = pos;
          isDifficult = false;
        }

        const CArcInfoEx &ai = op.codecs->Formats[index];


        if ((isDifficult && pos == 0) || ai.SignatureOffset == pos)
        {
          // we don't check same archive second time */
          if (skipFrontalFormat[index])
            continue;
        }

        UInt64 startArcPos = pos;
        if (!isDifficult)
        {
          if (pos < ai.SignatureOffset)
            continue;
          startArcPos = pos - ai.SignatureOffset;
          /*
          // we don't need the check for Z files
          if (startArcPos < handlerSpec->GetLastEnd())
            continue;
          */
        }
        
        if (ai.IsArcFunc && startArcPos >= bufPhyPos)
        {
          size_t offsetInBuf = (size_t)(startArcPos - bufPhyPos);
          if (offsetInBuf < bytesInBuf)
          {
            UInt32 isArcRes = ai.IsArcFunc(byteBuffer + offsetInBuf, bytesInBuf - offsetInBuf);
            if (isArcRes == k_IsArc_Res_NO)
              continue;
            if (isArcRes == k_IsArc_Res_NEED_MORE && endOfFile)
              continue;
            /*
            if (isArcRes == k_IsArc_Res_YES_LOW_PROB)
            {
              // if (pos != ai.SignatureOffset)
              continue;
            }
            */
          }
          // printf("\nIsArc OK: %S", (const wchar_t *)ai.Name);
        }
        
        /*
        if (pos == 67109888)
          pos = pos;
        */
        PRF(printf("\npos = %9I64d : %S", pos, (const wchar_t *)ai.Name));

        bool isMainFormat = isMainFormatArr[index];
        const COpenSpecFlags &specFlags = mode.GetSpec(isForced, isMainFormat, isUnknownExt);
        
        CMyComPtr<IInArchive> archive;
        RINOK(PrepareToOpen(op, index, archive));
        if (!archive)
          return E_FAIL;
        
        // OutputDebugStringW(ai.Name);
        
        UInt64 rem = fileSize - startArcPos;
        
        UInt64 arcStreamOffset = 0;

        if (ai.Flags_UseGlobalOffset())
        {
          limitedStreamSpec->InitAndSeek(0, fileSize);
          limitedStream->Seek(startArcPos, STREAM_SEEK_SET, NULL);
        }
        else
        {
          limitedStreamSpec->InitAndSeek(startArcPos, rem);
          arcStreamOffset = startArcPos;
        }
        
        UInt64 maxCheckStartPosition = 0;
        openCallback_Offset_Spec->Files = handlerSpec->_items.Size();
        openCallback_Offset_Spec->Offset = startArcPos;
        // HRESULT result = archive->Open(limitedStream, &maxCheckStartPosition, openCallback_Offset);
        extractCallback_To_OpenCallback_Spec->Files = 0;
        extractCallback_To_OpenCallback_Spec->Offset = startArcPos;

        HRESULT result = OpenArchiveSpec(archive, true, limitedStream, &maxCheckStartPosition, openCallback_Offset, extractCallback_To_OpenCallback);
     
        RINOK(ReadBasicProps(archive, ai.Flags_UseGlobalOffset() ? 0 : startArcPos, result));

        bool isOpen = false;
        if (result == S_FALSE)
        {
          if (!mode.CanReturnParser)
          {
            if (formatIndex < 0 && ErrorInfo.IsArc_After_NonOpen())
            {
              ErrorInfo.ErrorFormatIndex = index;
              NonOpen_ErrorInfo = ErrorInfo;
              // if archive was detected, we don't need additional open attempts
              return S_FALSE;
            }
            continue;
          }
          if (!ErrorInfo.IsArc_After_NonOpen() || !PhySizeDefined || PhySize == 0)
            continue;
        }
        else
        {
          isOpen = true;
          RINOK(result);
          PRF(printf("  OK "));
        }

        // fprintf(stderr, "\n %8X  %S", startArcPos, Path);
        // printf("\nOpen OK: %S", ai.Name);
        
        
        NArchive::NParser::CParseItem pi;
        pi.Offset = startArcPos;

        if (ai.Flags_UseGlobalOffset())
          pi.Offset = Offset;
        else if (Offset != 0)
          return E_FAIL;
        UInt64 arcRem = FileSize - pi.Offset;
        UInt64 phySize = arcRem;
        bool phySizeDefined = PhySizeDefined;
        if (phySizeDefined)
        {
          if (pi.Offset + PhySize > FileSize)
          {
            // ErrorInfo.ThereIsTail = true;
            PhySize = FileSize - pi.Offset;
          }
          phySize = PhySize;
        }
        if (phySize == 0 || (UInt64)phySize > ((UInt64)1 << 63))
          return E_FAIL;

        /*
        if (!ai.UseGlobalOffset)
        {
          if (phySize > arcRem)
          {
            ThereIsTail = true;
            phySize = arcRem;
          }
        }
        */
        
        bool needScan = false;

 
        if (isOpen && !phySizeDefined)
        {
          // it's for Z format
          pi.LenIsUnknown = true;
          needScan = true;
          phySize = arcRem;
          nextNeedCheckStartOpen = false;
        }

        pi.Size = phySize;
        /*
        if (OkPhySize_Defined)
          pi.OkSize = OkPhySize;
        */
        pi.NormalizeOffset();
        // printf("  phySize = %8d", (unsigned)phySize);

        /*
        if (needSkipFullArc)
          if (pi.Offset == 0 && phySizeDefined && pi.Size >= fileSize)
            continue;
        */
        if (pi.Offset == 0 && !pi.LenIsUnknown && pi.Size >= FileSize)
        {
          // it's possible for dmg archives
          if (!mode.CanReturnArc)
            continue;
        }

        if (mode.EachPos)
          pos++;
        else if (needScan)
        {
          pos++;
          /*
          if (!OkPhySize_Defined)
            pos++;
          else
            pos = pi.Offset + pi.OkSize;
          */
        }
        else
          pos = pi.Offset + pi.Size;

       
        RINOK(ReadParseItemProps(archive, ai, pi));

        if (pi.Offset < startArcPos && !mode.EachPos /* && phySizeDefined */)
        {
          /* It's for DMG format.
          This code deletes all previous items that are included to current item */
            
          while (!handlerSpec->_items.IsEmpty())
          {
            {
              const NArchive::NParser::CParseItem &back = handlerSpec->_items.Back();
              if (back.Offset < pi.Offset)
                break;
              if (back.Offset + back.Size > pi.Offset + pi.Size)
                break;
            }
            handlerSpec->_items.DeleteBack();
          }
        }
        

        if (isOpen && mode.CanReturnArc && phySizeDefined)
        {
          // if (pi.Offset + pi.Size >= fileSize)
          bool openCur = false;

          bool thereIsTail = ErrorInfo.ThereIsTail;
          if (thereIsTail && mode.ZerosTailIsAllowed)
          {
            RINOK(CheckZerosTail(op, arcStreamOffset + Offset + PhySize));
            if (ErrorInfo.IgnoreTail)
              thereIsTail = false;
          }

          if (pi.Offset != 0)
          {
            if (!pi.IsNotArcType)
              if (thereIsTail)
                openCur = specFlags.CanReturnMid;
              else
                openCur = specFlags.CanReturnTail;
          }
          else
          {
            if (!thereIsTail)
              openCur = true;
            else
              openCur = specFlags.CanReturnFrontal;
              

            if (formatIndex >= -2)
              openCur = true;
          }
          if (formatIndex < 0 && pi.IsSelfExe /* && mode.SkipSfxStub */)
            openCur = false;

          // We open file as SFX, if there is front archive or first archive is "Self Executable"
          if (!openCur && !pi.IsSelfExe && !thereIsTail &&
              (!pi.IsNotArcType || pi.Offset == 0))
          {
            if (handlerSpec->_items.IsEmpty())
            {
              if (specFlags.CanReturnTail)
                openCur = true;
            }
            else if (handlerSpec->_items.Size() == 1)
            {
              if (handlerSpec->_items[0].IsSelfExe)
              {
                if (mode.SpecUnknownExt.CanReturnTail)
                  openCur = true;
              }
            }
          }

          if (openCur)
          {
            InStream = op.stream;
            Archive = archive;
            FormatIndex = index;
            ArcStreamOffset = arcStreamOffset;
            return S_OK;
          }
        }

        /*
        if (openOnlyFullArc)
        {
          ErrorInfo.ClearErrors();
          return S_FALSE;
        }
        */

        pi.FormatIndex = index;

        // printf("\nAdd offset = %d", (int)pi.Offset);
        handlerSpec->AddItem(pi);
        wasOpen = true;
        break;
      }
      // ---------- End of Open Loop for Current Pos ----------
     
      if (!wasOpen)
        pos++;
      needCheckStartOpen = (nextNeedCheckStartOpen && wasOpen);
    }
    // ---------- End of Main Scan Loop ----------

    /*
    if (handlerSpec->_items.Size() == 1)
    {
      const NArchive::NParser::CParseItem &pi = handlerSpec->_items[0];
      if (pi.Size == fileSize && pi.Offset == 0)
      {
        Archive = archive;
        FormatIndex2 = pi.FormatIndex;
        return S_OK;
      }
    }
    */

    if (mode.CanReturnParser)
    {
      bool returnParser = (handlerSpec->_items.Size() == 1); // it's possible if fileSize was not correct at start of parsing
      handlerSpec->AddUnknownItem(fileSize);
      if (handlerSpec->_items.Size() == 0)
        return S_FALSE;
      if (returnParser || handlerSpec->_items.Size() != 1)
      {
        // return S_FALSE;
        handlerSpec->_stream = op.stream;
        Archive = handler;
        ErrorInfo.ClearErrors();
        IsParseArc = true;
        FormatIndex = -1; // It's parser
        Offset = 0;
        return S_OK;
      }
    }
  }

  #endif

  if (!Archive)
    return S_FALSE;
  return S_OK;
}

HRESULT CArc::OpenStream(const COpenOptions &op)
{
  RINOK(OpenStream2(op));
  // PrintNumber("op.formatIndex 3", op.formatIndex);

  if (Archive)
  {
    GetRawProps.Release();
    GetRootProps.Release();
    Archive->QueryInterface(IID_IArchiveGetRawProps, (void **)&GetRawProps);
    Archive->QueryInterface(IID_IArchiveGetRootProps, (void **)&GetRootProps);

    RINOK(Archive_GetArcBoolProp(Archive, kpidIsTree, IsTree));
    RINOK(Archive_GetArcBoolProp(Archive, kpidIsDeleted, Ask_Deleted));
    RINOK(Archive_GetArcBoolProp(Archive, kpidIsAltStream, Ask_AltStream));
    RINOK(Archive_GetArcBoolProp(Archive, kpidIsAux, Ask_Aux));
    RINOK(Archive_GetArcBoolProp(Archive, kpidINode, Ask_INode));

    const UString fileName = ExtractFileNameFromPath(Path);
    UString extension;
    {
      int dotPos = fileName.ReverseFind(L'.');
      if (dotPos >= 0)
        extension = fileName.Ptr(dotPos + 1);
    }
    
    DefaultName.Empty();
    if (FormatIndex >= 0)
    {
      const CArcInfoEx &ai = op.codecs->Formats[FormatIndex];
      if (ai.Exts.Size() == 0)
        DefaultName = GetDefaultName2(fileName, L"", L"");
      else
      {
        int subExtIndex = ai.FindExtension(extension);
        if (subExtIndex < 0)
          subExtIndex = 0;
        const CArcExtInfo &extInfo = ai.Exts[subExtIndex];
        DefaultName = GetDefaultName2(fileName, extInfo.Ext, extInfo.AddExt);
      }
    }
  }

  return S_OK;
}

#ifdef _SFX

#ifdef _WIN32
  static const wchar_t *k_ExeExt = L".exe";
  static const unsigned k_ExeExt_Len = 4;
#else
  static const wchar_t *k_ExeExt = L"";
  static const unsigned k_ExeExt_Len = 0;
#endif

#endif

HRESULT CArc::OpenStreamOrFile(COpenOptions &op)
{
  CMyComPtr<IInStream> fileStream;
  CMyComPtr<ISequentialInStream> seqStream;
  CInFileStream *fileStreamSpec = NULL;
  if (op.stdInMode)
  {
    seqStream = new CStdInFileStream;
    op.seqStream = seqStream;
  }
  else if (!op.stream)
  {
    fileStreamSpec = new CInFileStream;
    fileStream = fileStreamSpec;
    Path = filePath;
    if (!fileStreamSpec->Open(us2fs(Path)))
    {
      return GetLastError();
    }
    op.stream = fileStream;
    #ifdef _SFX
    IgnoreSplit = true;
    #endif
  }

  /*
  if (callback)
  {
    UInt64 fileSize;
    RINOK(op.stream->Seek(0, STREAM_SEEK_END, &fileSize));
    RINOK(op.callback->SetTotal(NULL, &fileSize))
  }
  */

  HRESULT res = OpenStream(op);
  IgnoreSplit = false;
  
  #ifdef _SFX
  
  if (res != S_FALSE
      || !fileStreamSpec
      || !op.callbackSpec
      || NonOpen_ErrorInfo.IsArc_After_NonOpen())
    return res;
  {
    if (filePath.Len() > k_ExeExt_Len
        && MyStringCompareNoCase(filePath.RightPtr(k_ExeExt_Len), k_ExeExt) == 0)
    {
      const UString path2 = filePath.Left(filePath.Len() - k_ExeExt_Len);
      FOR_VECTOR (i, op.codecs->Formats)
      {
        const CArcInfoEx &ai = op.codecs->Formats[i];
        if (ai.IsSplit())
          continue;
        UString path3 = path2;
        path3 += L".";
        path3 += ai.GetMainExt(); // "7z"  for SFX.
        Path = path3 + L".001";
        bool isOk = op.callbackSpec->SetSecondFileInfo(us2fs(Path));
        if (!isOk)
        {
          Path = path3;
          isOk = op.callbackSpec->SetSecondFileInfo(us2fs(Path));
        }
        if (isOk)
        {
          if (fileStreamSpec->Open(us2fs(Path)))
          {
            op.stream = fileStream;
            NonOpen_ErrorInfo.ClearErrors_Full();
            if (OpenStream(op) == S_OK)
              return S_OK;
          }
        }
      }
    }
  }
  
  #endif

  return res;
}

void CArchiveLink::KeepModeForNextOpen()
{
  for (int i = Arcs.Size() - 1; i >= 0; i--)
  {
    CMyComPtr<IArchiveKeepModeForNextOpen> keep;
    Arcs[i].Archive->QueryInterface(IID_IArchiveKeepModeForNextOpen, (void **)&keep);
    if (keep)
      keep->KeepModeForNextOpen();
  }
}

HRESULT CArchiveLink::Close()
{
  for (int i = Arcs.Size() - 1; i >= 0; i--)
  {
    RINOK(Arcs[i].Close());
  }
  IsOpen = false;
  // ErrorsText.Empty();
  return S_OK;
}

void CArchiveLink::Release()
{
  // NonOpenErrorFormatIndex = -1;
  NonOpen_ErrorInfo.ClearErrors();
  NonOpen_ArcPath.Empty();
  while (!Arcs.IsEmpty())
    Arcs.DeleteBack();
}

/*
void CArchiveLink::Set_ErrorsText()
{
  FOR_VECTOR(i, Arcs)
  {
    const CArc &arc = Arcs[i];
    if (!arc.ErrorFlagsText.IsEmpty())
    {
      if (!ErrorsText.IsEmpty())
        ErrorsText += L'\n';
      ErrorsText += GetUnicodeString(arc.ErrorFlagsText);
    }
    if (!arc.ErrorMessage.IsEmpty())
    {
      if (!ErrorsText.IsEmpty())
        ErrorsText += L'\n';
      ErrorsText += arc.ErrorMessage;
    }

    if (!arc.WarningMessage.IsEmpty())
    {
      if (!ErrorsText.IsEmpty())
        ErrorsText += L'\n';
      ErrorsText += arc.WarningMessage;
    }
  }
}
*/

HRESULT CArchiveLink::Open(COpenOptions &op)
{
  Release();
  if (op.types->Size() >= 32)
    return E_NOTIMPL;
  
  HRESULT resSpec;

  for (;;)
  {
    resSpec = S_OK;

    op.openType = COpenType();
    if (op.types->Size() >= 1)
    {
      COpenType latest;
      if (Arcs.Size() < op.types->Size())
        latest = (*op.types)[op.types->Size() - Arcs.Size() - 1];
      else
      {
        latest = (*op.types)[0];
        if (!latest.Recursive)
          break;
      }
      op.openType = latest;
    }
    else if (Arcs.Size() >= 32)
      break;

    /*
    op.formatIndex = -1;
    if (op.types->Size() >= 1)
    {
      int latest;
      if (Arcs.Size() < op.types->Size())
        latest = (*op.types)[op.types->Size() - Arcs.Size() - 1];
      else
      {
        latest = (*op.types)[0];
        if (latest != -2 && latest != -3)
          break;
      }
      if (latest >= 0)
        op.formatIndex = latest;
      else if (latest == -1 || latest == -2)
      {
        // default
      }
      else if (latest == -3)
        op.formatIndex = -2;
      else
        op.formatIndex = latest + 2;
    }
    else if (Arcs.Size() >= 32)
      break;
    */

    if (Arcs.IsEmpty())
    {
      CArc arc;
      arc.filePath = op.filePath;
      arc.Path = op.filePath;
      arc.SubfileIndex = (UInt32)(Int32)-1;
      HRESULT result = arc.OpenStreamOrFile(op);
      if (result != S_OK)
      {
        if (result == S_FALSE)
        {
          NonOpen_ErrorInfo = arc.NonOpen_ErrorInfo;
          // NonOpenErrorFormatIndex = arc.ErrorFormatIndex;
          NonOpen_ArcPath = arc.Path;
        }
        return result;
      }
      Arcs.Add(arc);
      continue;
    }
    
    // PrintNumber("op.formatIndex 11", op.formatIndex);

    const CArc &arc = Arcs.Back();
    
    if (op.types->Size() > Arcs.Size())
      resSpec = E_NOTIMPL;
    
    UInt32 mainSubfile;
    {
      NCOM::CPropVariant prop;
      RINOK(arc.Archive->GetArchiveProperty(kpidMainSubfile, &prop));
      if (prop.vt == VT_UI4)
        mainSubfile = prop.ulVal;
      else
        break;
      UInt32 numItems;
      RINOK(arc.Archive->GetNumberOfItems(&numItems));
      if (mainSubfile >= numItems)
        break;
    }

  
    CMyComPtr<IInArchiveGetStream> getStream;
    if (arc.Archive->QueryInterface(IID_IInArchiveGetStream, (void **)&getStream) != S_OK || !getStream)
      break;
    
    CMyComPtr<ISequentialInStream> subSeqStream;
    if (getStream->GetStream(mainSubfile, &subSeqStream) != S_OK || !subSeqStream)
      break;
    
    CMyComPtr<IInStream> subStream;
    if (subSeqStream.QueryInterface(IID_IInStream, &subStream) != S_OK || !subStream)
      break;
    
    CArc arc2;
    RINOK(arc.GetItemPath(mainSubfile, arc2.Path));

    bool zerosTailIsAllowed;
    RINOK(Archive_GetItemBoolProp(arc.Archive, mainSubfile, kpidZerosTailIsAllowed, zerosTailIsAllowed));

    CMyComPtr<IArchiveOpenSetSubArchiveName> setSubArchiveName;
    op.callback->QueryInterface(IID_IArchiveOpenSetSubArchiveName, (void **)&setSubArchiveName);
    if (setSubArchiveName)
      setSubArchiveName->SetSubArchiveName(arc2.Path);
    
    arc2.SubfileIndex = mainSubfile;

    // CIntVector incl;
    CIntVector excl;

    COpenOptions op2;
    #ifndef _SFX
    op2.props = op.props;
    #endif
    op2.codecs = op.codecs;
    // op2.types = &incl;
    op2.openType = op.openType;
    op2.openType.ZerosTailIsAllowed = zerosTailIsAllowed;
    op2.excludedFormats = &excl;
    op2.stdInMode = false;
    op2.stream = subStream;
    op2.filePath = arc2.Path;
    op2.callback = op.callback;
    op2.callbackSpec = op.callbackSpec;


    HRESULT result = arc2.OpenStream(op2);
    resSpec = (op.types->Size() == 0 ? S_OK : S_FALSE);
    if (result == S_FALSE)
    {
      NonOpen_ErrorInfo = arc2.ErrorInfo;
      NonOpen_ArcPath = arc2.Path;
      break;
    }
    RINOK(result);
    RINOK(arc.GetItemMTime(mainSubfile, arc2.MTime, arc2.MTimeDefined));
    Arcs.Add(arc2);
  }
  IsOpen = !Arcs.IsEmpty();
  return resSpec;
}

static void SetCallback(const FString &filePath,
    IOpenCallbackUI *callbackUI,
    IArchiveOpenCallback *reOpenCallback,
    CMyComPtr<IArchiveOpenCallback> &callback)
{
  COpenCallbackImp *openCallbackSpec = new COpenCallbackImp;
  callback = openCallbackSpec;
  openCallbackSpec->Callback = callbackUI;
  openCallbackSpec->ReOpenCallback = reOpenCallback;

  FString dirPrefix, fileName;
  NFile::NDir::GetFullPathAndSplit(filePath, dirPrefix, fileName);
  openCallbackSpec->Init(dirPrefix, fileName);
}

HRESULT CArchiveLink::Open2(COpenOptions &op,
    IOpenCallbackUI *callbackUI)
{
  VolumesSize = 0;
  COpenCallbackImp *openCallbackSpec = new COpenCallbackImp;
  CMyComPtr<IArchiveOpenCallback> callback = openCallbackSpec;
  openCallbackSpec->Callback = callbackUI;

  FString prefix, name;
  if (!op.stream && !op.stdInMode)
  {
    NFile::NDir::GetFullPathAndSplit(us2fs(op.filePath), prefix, name);
    openCallbackSpec->Init(prefix, name);
  }
  else
  {
    openCallbackSpec->SetSubArchiveName(op.filePath);
  }

  op.callback = callback;
  op.callbackSpec = openCallbackSpec;
  RINOK(Open(op));
  // VolumePaths.Add(fs2us(prefix + name));

  FOR_VECTOR (i, openCallbackSpec->FileNames_WasUsed)
  {
    if (openCallbackSpec->FileNames_WasUsed[i])
    {
      VolumePaths.Add(fs2us(prefix) + openCallbackSpec->FileNames[i]);
      VolumesSize += openCallbackSpec->FileSizes[i];
    }
  }
  // VolumesSize = openCallbackSpec->TotalSize;
  return S_OK;
}

HRESULT CArc::ReOpen(const COpenOptions &op)
{
  ErrorInfo.ClearErrors();
  ErrorInfo.ErrorFormatIndex = -1;

  UInt64 fileSize = 0;
  if (op.stream)
  {
    RINOK(op.stream->Seek(0, STREAM_SEEK_END, &fileSize));
    RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL));
  }
  FileSize = fileSize;

  CMyComPtr<IInStream> stream2;
  Int64 globalOffset = GetGlobalOffset();
  if (globalOffset <= 0)
    stream2 = op.stream;
  else
  {
    CTailInStream *tailStreamSpec = new CTailInStream;
    stream2 = tailStreamSpec;
    tailStreamSpec->Stream = op.stream;
    tailStreamSpec->Offset = globalOffset;
    tailStreamSpec->Init();
    RINOK(tailStreamSpec->SeekToStart());
  }

  // There are archives with embedded STUBs (like ZIP), so we must support signature scanning
  // But for another archives we can use 0 here. So the code can be fixed !!!
  UInt64 maxStartPosition = kMaxCheckStartPosition;
  HRESULT res = Archive->Open(stream2, &maxStartPosition, op.callback);
  
  if (res == S_OK)
  {
    RINOK(ReadBasicProps(Archive, globalOffset, res));
    ArcStreamOffset = globalOffset;
    if (ArcStreamOffset != 0)
      InStream = op.stream;
  }
  return res;
}


HRESULT CArchiveLink::ReOpen(COpenOptions &op)
{
  if (Arcs.Size() > 1)
    return E_NOTIMPL;

  CObjectVector<COpenType> inc;
  CIntVector excl;

  op.types = &inc;
  op.excludedFormats = &excl;
  op.stdInMode = false;
  op.stream = NULL;
  if (Arcs.Size() == 0) // ???
    return Open2(op, NULL);

  CMyComPtr<IArchiveOpenCallback> openCallbackNew;
  SetCallback(us2fs(op.filePath), NULL, op.callback, openCallbackNew);

  CInFileStream *fileStreamSpec = new CInFileStream;
  CMyComPtr<IInStream> stream(fileStreamSpec);
  if (!fileStreamSpec->Open(us2fs(op.filePath)))
    return GetLastError();
  op.stream = stream;

  CArc &arc = Arcs[0];
  HRESULT res = arc.ReOpen(op);
  IsOpen = (res == S_OK);
  return res;
}

#ifndef _SFX

bool ParseComplexSize(const wchar_t *s, UInt64 &result)
{
  result = 0;
  const wchar_t *end;
  UInt64 number = ConvertStringToUInt64(s, &end);
  if (end == s)
    return false;
  if (*end == 0)
  {
    result = number;
    return true;
  }
  if (end[1] != 0)
    return false;
  unsigned numBits;
  switch (MyCharLower_Ascii(*end))
  {
    case 'b': result = number; return true;
    case 'k': numBits = 10; break;
    case 'm': numBits = 20; break;
    case 'g': numBits = 30; break;
    case 't': numBits = 40; break;
    default: return false;
  }
  if (number >= ((UInt64)1 << (64 - numBits)))
    return false;
  result = number << numBits;
  return true;
}

static bool ParseTypeParams(const UString &s, COpenType &type)
{
  if (s[0] == 0)
    return true;
  if (s[1] == 0)
  {
    switch ((unsigned)(Byte)s[0])
    {
      case 'e': type.EachPos = true; return true;
      case 'a': type.CanReturnArc = true; return true;
      case 'r': type.Recursive = true; return true;
    }
    return false;
  }
  if (s[0] == 's')
  {
    UInt64 result;
    if (!ParseComplexSize(s.Ptr(1), result))
      return false;
    type.MaxStartOffset = result;
    type.MaxStartOffset_Defined = true;
    return true;
  }

  return false;
}

bool ParseType(CCodecs &codecs, const UString &s, COpenType &type)
{
  int pos2 = s.Find(':');
  UString name;
  if (pos2 < 0)
  {
    name = s;
    pos2 = s.Len();
  }
  else
  {
    name = s.Left(pos2);
    pos2++;
  }

  int index = codecs.FindFormatForArchiveType(name);
  type.Recursive = false;

  if (index < 0)
  {
    if (name[0] == '*')
    {
      if (name[1] != 0)
        return false;
    }
    else if (name[0] == '#')
    {
      if (name[1] != 0)
        return false;
      type.CanReturnArc = false;
      type.CanReturnParser = true;
    }
    else
      return false;
  }
  
  type.FormatIndex = index;
 
  for (unsigned i = pos2; i < s.Len();)
  {
    int next = s.Find(':', i);
    if (next < 0)
      next = s.Len();
    UString name = s.Mid(i, next - i);
    if (name.IsEmpty())
      return false;
    if (!ParseTypeParams(name, type))
      return false;
    i = next + 1;
  }
  
  return true;
}

bool ParseOpenTypes(CCodecs &codecs, const UString &s, CObjectVector<COpenType> &types)
{
  types.Clear();
  for (unsigned pos = 0; pos < s.Len();)
  {
    int pos2 = s.Find('.', pos);
    if (pos2 < 0)
      pos2 = s.Len();
    UString name = s.Mid(pos, pos2 - pos);
    if (name.IsEmpty())
      return false;
    COpenType type;
    if (!ParseType(codecs, name, type))
      return false;
    types.Add(type);
    pos = pos2 + 1;
  }
  return true;
}

#endif
