Beispiel #1
0
bool MyGetLogicalDriveStrings(CObjectVector<FString> &driveStrings)
{
  driveStrings.Clear();
  #ifndef _UNICODE
  if (!g_IsNT)
  {
    driveStrings.Clear();
    UINT32 size = GetLogicalDriveStrings(0, NULL);
    if (size == 0)
      return false;
    CObjArray<char> buf(size);
    UINT32 newSize = GetLogicalDriveStrings(size, buf);
    if (newSize == 0 || newSize > size)
      return false;
    AString s;
    UINT32 prev = 0;
    for (UINT32 i = 0; i < newSize; i++)
    {
      if (buf[i] == 0)
      {
        s = buf + prev;
        prev = i + 1;
        driveStrings.Add(fas2fs(s));
      }
    }
    return prev == newSize;
  }
  else
  #endif
  {
    UINT32 size = GetLogicalDriveStringsW(0, NULL);
    if (size == 0)
      return false;
    CObjArray<wchar_t> buf(size);
    UINT32 newSize = GetLogicalDriveStringsW(size, buf);
    if (newSize == 0 || newSize > size)
      return false;
    UString s;
    UINT32 prev = 0;
    for (UINT32 i = 0; i < newSize; i++)
    {
      if (buf[i] == 0)
      {
        s = buf + prev;
        prev = i + 1;
        driveStrings.Add(us2fs(s));
      }
    }
    return prev == newSize;
  }
}
Beispiel #2
0
void ReadInternalAssociations(CObjectVector<CExtInfo> &items)
{
  items.Clear();
  NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
  CKey associationsKey;
  if (associationsKey.Open(HKEY_CURRENT_USER, kAssociationsPath, KEY_READ) != ERROR_SUCCESS)
    return;
  CSysStringVector extNames;
  associationsKey.EnumKeys(extNames);
  for(int i = 0; i < extNames.Size(); i++)
  {
    const CSysString extName = extNames[i];
    CExtInfo extInfo;
    // extInfo.Enabled = false;
    extInfo.Ext = GetUnicodeString(extName);
    CKey key;
    if (key.Open(associationsKey, extName, KEY_READ) != ERROR_SUCCESS)
      return;
    UString pluginsString;
    key.QueryValue(kExtPlugins, pluginsString);
    SplitString(pluginsString, extInfo.Plugins);
    /*
    if (key.QueryValue(kExtEnabled, extInfo.Enabled) != ERROR_SUCCESS)
      extInfo.Enabled = false;
    */
    items.Add(extInfo);
  }
}
Beispiel #3
0
 void Clear()
 {
   CID.Empty();
   parentCID.Empty();
   createType.Empty();
   Extents.Clear();
 }
Beispiel #4
0
void ReadPluginInfoList(CObjectVector<CPluginInfo> &plugins)
{
  plugins.Clear();

  UString baseFolderPrefix;
  GetProgramFolderPath(baseFolderPrefix);
  {
    CPluginInfo pluginInfo;
    pluginInfo.FilePath = baseFolderPrefix + L"7-zip.dll";
    if (::ReadPluginInfo(pluginInfo, false))
      plugins.Add(pluginInfo);
  }
  UString folderPath = baseFolderPrefix + L"Plugins" WSTRING_PATH_SEPARATOR;
  NFind::CEnumeratorW enumerator(folderPath + L"*");
  NFind::CFileInfoW fileInfo;
  while (enumerator.Next(fileInfo))
  {
    if (fileInfo.IsDir())
      continue;
    CPluginInfo pluginInfo;
    pluginInfo.FilePath = folderPath + fileInfo.Name;
    if (::ReadPluginInfo(pluginInfo, true))
      plugins.Add(pluginInfo);
  }
}
Beispiel #5
0
static bool GetTextPairs(const UString &srcString, CObjectVector<CTextPair> &pairs)
{
  pairs.Clear();
  unsigned pos = 0;
  
  if (srcString.Len() > 0)
  {
    if (srcString[0] == kBOM)
      pos++;
  }
  while (pos < srcString.Len())
  {
    unsigned finishPos;
    UString id = GetIDString((const wchar_t *)srcString + pos, finishPos);
    pos += finishPos;
    if (id.IsEmpty())
      continue;
    UString value = GetValueString((const wchar_t *)srcString + pos, finishPos);
    pos += finishPos;
    if (!id.IsEmpty())
    {
      CTextPair pair;
      pair.ID = id;
      pair.Value = value;
      pairs.Add(pair);
    }
  }
  return true;
}
Beispiel #6
0
bool GetTextConfig(const AString &s, CObjectVector<CTextConfigPair> &pairs)
{
  pairs.Clear();
  unsigned pos = 0;

  /////////////////////
  // read strings

  for (;;)
  {
    if (!SkipSpaces(s, pos))
      break;
    CTextConfigPair pair;
    unsigned finishPos;
    AString temp = GetIDString(((const char *)s) + pos, finishPos);
    if (!ConvertUTF8ToUnicode(temp, pair.ID))
      return false;
    if (finishPos == 0)
      return false;
    pos += finishPos;
    if (!SkipSpaces(s, pos))
      return false;
    if (s[pos] != '=')
      return false;
    pos++;
    if (!SkipSpaces(s, pos))
      return false;
    if (s[pos] != '\"')
      return false;
    pos++;
    AString message;
    for (;;)
    {
      if (pos >= s.Len())
        return false;
      char c = s[pos++];
      if (c == '\"')
        break;
      if (c == '\\')
      {
        c = s[pos++];
        switch (c)
        {
          case 'n': message += '\n'; break;
          case 't': message += '\t'; break;
          case '\\': message += '\\'; break;
          case '\"': message += '\"'; break;
          default: message += '\\'; message += c; break;
        }
      }
      else
        message += c;
    }
    if (!ConvertUTF8ToUnicode(message, pair.String))
      return false;
    pairs.Add(pair);
  }
  return true;
}
Beispiel #7
0
void CInArchive::ReadUnpackInfo(
    const CObjectVector<CByteBuffer> *dataVector,
    CObjectVector<CFolder> &folders)
{
  WaitAttribute(NID::kFolder);
  CNum numFolders = ReadNum();

  {
    CStreamSwitch streamSwitch;
    streamSwitch.Set(this, dataVector);
    folders.Clear();
    folders.Reserve(numFolders);
    for (CNum i = 0; i < numFolders; i++)
    {
      folders.Add(CFolder());
      GetNextFolderItem(folders.Back());
    }
  }

  WaitAttribute(NID::kCodersUnpackSize);

  CNum i;
  for (i = 0; i < numFolders; i++)
  {
    CFolder &folder = folders[i];
    CNum numOutStreams = folder.GetNumOutStreams();
    folder.UnpackSizes.Reserve(numOutStreams);
    for (CNum j = 0; j < numOutStreams; j++)
      folder.UnpackSizes.Add(ReadNumber());
  }

  for (;;)
  {
    UInt64 type = ReadID();
    if (type == NID::kEnd)
      return;
    if (type == NID::kCRC)
    {
      CBoolVector crcsDefined;
      CRecordVector<UInt32> crcs;
      ReadHashDigests(numFolders, crcsDefined, crcs);
      for (i = 0; i < numFolders; i++)
      {
        CFolder &folder = folders[i];
        folder.UnpackCRCDefined = crcsDefined[i];
        folder.UnpackCRC = crcs[i];
      }
      continue;
    }
    SkipData();
  }
}
Beispiel #8
0
bool CStartupInfo::ControlGetActivePanelSelectedOrCurrentItems(
    CObjectVector<PluginPanelItem> &pluginPanelItems)
{
  pluginPanelItems.Clear();
  PanelInfo panelInfo;
  if(!ControlGetActivePanelInfo(panelInfo))
    return false;
  if(panelInfo.ItemsNumber <= 0)
    throw "There are no items";
  if (panelInfo.SelectedItemsNumber == 0)
    pluginPanelItems.Add(panelInfo.PanelItems[panelInfo.CurrentItem]);
  else
    for (int i = 0; i < panelInfo.SelectedItemsNumber; i++)
      pluginPanelItems.Add(panelInfo.SelectedItems[i]);
  return true;
}
static void SplitFilesToGroups(
    const CCompressionMethodMode &method, 
    bool useFilters, bool maxFilter,
    const CObjectVector<CUpdateItem> &updateItems,
    CObjectVector<CSolidGroup> &groups)
{
  if (method.Methods.Size() != 1 || method.Binds.Size() != 0)
    useFilters = false;
  groups.Clear();
  groups.Add(CSolidGroup());
  groups.Add(CSolidGroup());
  CSolidGroup &generalGroup = groups[0];
  CSolidGroup &exeGroup = groups[1];
  generalGroup.Method = method;
  int i;
  for (i = 0; i < updateItems.Size(); i++)
  {
    const CUpdateItem &updateItem = updateItems[i];
    if (!updateItem.NewData)
      continue;
    if (!updateItem.HasStream())
      continue;
    if (useFilters)
    {
      const UString name = updateItem.Name;
      int dotPos = name.ReverseFind(L'.');
      if (dotPos >= 0)
      {
        UString ext = name.Mid(dotPos + 1);
        if (IsExeFile(ext))
        {
          exeGroup.Indices.Add(i);
          continue;
        }
      }
    }
    generalGroup.Indices.Add(i);
  }
  if (exeGroup.Indices.Size() > 0)
    if (!MakeExeMethod(method, maxFilter, exeGroup.Method))
      exeGroup.Method = method;
  for (i = 0; i < groups.Size();)
    if (groups[i].Indices.Size() == 0)
      groups.Delete(i);
    else
      i++;
}
Beispiel #10
0
HRESULT CInArchive::TryReadCd(CObjectVector<CItemEx> &items, UInt64 cdOffset, UInt64 cdSize, CProgressVirt *progress)
{
  items.Clear();
  RINOK(Stream->Seek(cdOffset, STREAM_SEEK_SET, &m_Position));
  if (m_Position != cdOffset)
    return S_FALSE;

  _inBuffer.Init();
  _inBufMode = true;

  while (m_Position - cdOffset < cdSize)
  {
    if (ReadUInt32() != NSignature::kCentralFileHeader)
      return S_FALSE;
    CItemEx cdItem;
    RINOK(ReadCdItem(cdItem));
    items.Add(cdItem);
    if (progress && items.Size() % 1 == 0)
      RINOK(progress->SetCompletedCD(items.Size()));
  }
  return (m_Position - cdOffset == cdSize) ? S_OK : S_FALSE;
}
Beispiel #11
0
static void GetSnapshot(CObjectVector<CSnapshotProcess> &items)
{
  items.Clear();

  CProcessSnapshot snapshot;
  if (!snapshot.Create())
    return;

  DEBUG_PRINT("snapshot.Create() OK");
  PROCESSENTRY32 pe;
  CSnapshotProcess item;
  memset(&pe, 0, sizeof(pe));
  pe.dwSize = sizeof(pe);
  BOOL res = snapshot.GetFirstProcess(&pe);
  while (res)
  {
    item.Id = pe.th32ProcessID;
    item.ParentId = pe.th32ParentProcessID;
    item.Name = GetUnicodeString(pe.szExeFile);
    items.Add(item);
    res = snapshot.GetNextProcess(&pe);
  }
}
Beispiel #12
0
HRESULT CInArchive::ReadLocals(
    CObjectVector<CItemEx> &items, CProgressVirt *progress)
{
  items.Clear();
  while (m_Signature == NSignature::kLocalFileHeader)
  {
    CItemEx item;
    item.LocalHeaderPos = m_Position - 4 - ArcInfo.MarkerPos;
    // we write ralative LocalHeaderPos here. Later we can correct it to real Base.
    try
    {
      ReadLocalItem(item);
      item.FromLocal = true;
      if (item.HasDescriptor())
        ReadLocalItemDescriptor(item);
      else
      {
        RINOK(IncreaseRealPosition(item.PackSize));
      }
      items.Add(item);
      m_Signature = ReadUInt32();
    }
    catch (CUnexpectEnd &)
    {
      if (items.IsEmpty() || items.Size() == 1 && IsStrangeItem(items[0]))
        return S_FALSE;
      throw;
    }
    if (progress && items.Size() % 1 == 0)
      RINOK(progress->SetCompletedLocal(items.Size(), item.LocalHeaderPos));
  }

  if (items.Size() == 1 && m_Signature != NSignature::kCentralFileHeader)
    if (IsStrangeItem(items[0]))
      return S_FALSE;
  return S_OK;
}
Beispiel #13
0
void ReadPluginInfoList(CObjectVector<CPluginInfo> &plugins)
{
  plugins.Clear();

  FString baseFolderPrefix = NDLL::GetModuleDirPrefix();
  {
    CPluginInfo pluginInfo;
    pluginInfo.FilePath = baseFolderPrefix + FTEXT("7-zip.dll");
    if (::ReadPluginInfo(pluginInfo, false))
      plugins.Add(pluginInfo);
  }
  FString folderPath = baseFolderPrefix + FTEXT("Plugins") FSTRING_PATH_SEPARATOR;
  NFind::CEnumerator enumerator(folderPath + FCHAR_ANY_MASK);
  NFind::CFileInfo fileInfo;
  while (enumerator.Next(fileInfo))
  {
    if (fileInfo.IsDir())
      continue;
    CPluginInfo pluginInfo;
    pluginInfo.FilePath = folderPath + fileInfo.Name;
    if (::ReadPluginInfo(pluginInfo, true))
      plugins.Add(pluginInfo);
  }
}
HRESULT CHashBundle::SetMethods(DECL_EXTERNAL_CODECS_LOC_VARS const UStringVector &hashMethods)
{
  UStringVector names = hashMethods;
  if (names.IsEmpty())
  {
    UString s;
    s.SetFromAscii(k_DefaultHashMethod);
    names.Add(s);
  }

  CRecordVector<CMethodId> ids;
  CObjectVector<COneMethodInfo> methods;
  
  unsigned i;
  for (i = 0; i < names.Size(); i++)
  {
    COneMethodInfo m;
    RINOK(m.ParseMethodFromString(names[i]));

    if (m.MethodName.IsEmpty())
      m.MethodName = k_DefaultHashMethod;
    
    if (m.MethodName == "*")
    {
      CRecordVector<CMethodId> tempMethods;
      GetHashMethods(EXTERNAL_CODECS_LOC_VARS tempMethods);
      methods.Clear();
      ids.Clear();
      FOR_VECTOR (t, tempMethods)
      {
        unsigned index = ids.AddToUniqueSorted(tempMethods[t]);
        if (ids.Size() != methods.Size())
          methods.Insert(index, m);
      }
      break;
    }
Beispiel #15
0
void CDirEnumerator::Init()
{
    Enumerators.Clear();
    Prefixes.Clear();
    Index = 0;
}
Beispiel #16
0
HRESULT CInArchive::ReadHeaders2(CObjectVector<CItemEx> &items, CProgressVirt *progress)
{
  items.Clear();

  // m_Signature must be kLocalFileHeader or kEcd
  // m_Position points to next byte after signature
  RINOK(Stream->Seek(m_Position, STREAM_SEEK_SET, NULL));

  if (!_inBuffer.Create(1 << 15))
    return E_OUTOFMEMORY;
  _inBuffer.SetStream(Stream);

  bool needReadCd = true;
  bool localsWereRead = false;
  if (m_Signature == NSignature::kEcd)
  {
    // It must be empty archive or backware archive
    // we don't support backware archive still

    const unsigned kBufSize = kEcdSize - 4;
    Byte buf[kBufSize];
    SafeReadBytes(buf, kBufSize);
    CEcd ecd;
    ecd.Parse(buf);
    // if (ecd.cdSize != 0)
    // Do we need also to support the case where empty zip archive with PK00 uses cdOffset = 4 ??
    if (!ecd.IsEmptyArc())
      return S_FALSE;

    ArcInfo.Base = ArcInfo.MarkerPos;
    needReadCd = false;
    IsArc = true; // check it: we need more tests?
    RINOK(Stream->Seek(ArcInfo.MarkerPos2 + 4, STREAM_SEEK_SET, &m_Position));
  }

  UInt64 cdSize = 0, cdRelatOffset = 0, cdAbsOffset = 0;
  HRESULT res = S_OK;

  if (needReadCd)
  {
    CItemEx firstItem;
    // try
    {
      try
      {
        if (!ReadLocalItem(firstItem))
          return S_FALSE;
      }
      catch(CUnexpectEnd &)
      {
        return S_FALSE;
      }

      IsArc = true;
      res = ReadCd(items, cdRelatOffset, cdSize, progress);
      if (res == S_OK)
        m_Signature = ReadUInt32();
    }
    // catch() { res = S_FALSE; }
    if (res != S_FALSE && res != S_OK)
      return res;

    if (res == S_OK && items.Size() == 0)
      res = S_FALSE;

    if (res == S_OK)
    {
      // we can't read local items here to keep _inBufMode state
      firstItem.LocalHeaderPos = ArcInfo.MarkerPos2 - ArcInfo.Base;
      int index = FindItem(items, firstItem.LocalHeaderPos);
      if (index == -1)
        res = S_FALSE;
      else if (!AreItemsEqual(firstItem, items[index]))
        res = S_FALSE;
      ArcInfo.CdWasRead = true;
      ArcInfo.FirstItemRelatOffset = items[0].LocalHeaderPos;
    }
  }

  CObjectVector<CItemEx> cdItems;

  bool needSetBase = false;
  unsigned numCdItems = items.Size();

  if (res == S_FALSE)
  {
    // CD doesn't match firstItem so we clear items and read Locals.
    items.Clear();
    localsWereRead = true;
    _inBufMode = false;
    ArcInfo.Base = ArcInfo.MarkerPos;
    RINOK(Stream->Seek(ArcInfo.MarkerPos2, STREAM_SEEK_SET, &m_Position));
    m_Signature = ReadUInt32();

    RINOK(ReadLocals(items, progress));

    if (m_Signature != NSignature::kCentralFileHeader)
    {
      m_Position -= 4;
      NoCentralDir = true;
      HeadersError = true;
      return S_OK;
    }
    _inBufMode = true;
    _inBuffer.Init();
    cdAbsOffset = m_Position - 4;
    for (;;)
    {
      CItemEx cdItem;
      RINOK(ReadCdItem(cdItem));
      cdItems.Add(cdItem);
      if (progress && cdItems.Size() % 1 == 0)
        RINOK(progress->SetCompletedCD(items.Size()));
      m_Signature = ReadUInt32();
      if (m_Signature != NSignature::kCentralFileHeader)
        break;
    }

    cdSize = (m_Position - 4) - cdAbsOffset;
    needSetBase = true;
    numCdItems = cdItems.Size();

    if (!cdItems.IsEmpty())
    {
      ArcInfo.CdWasRead = true;
      ArcInfo.FirstItemRelatOffset = cdItems[0].LocalHeaderPos;
    }
  }

  CEcd64 ecd64;
  bool isZip64 = false;
  UInt64 ecd64AbsOffset = m_Position - 4;
  if (m_Signature == NSignature::kEcd64)
  {
    IsZip64 = isZip64 = true;
    UInt64 recordSize = ReadUInt64();

    const unsigned kBufSize = kEcd64_MainSize;
    Byte buf[kBufSize];
    SafeReadBytes(buf, kBufSize);
    ecd64.Parse(buf);

    Skip64(recordSize - kEcd64_MainSize);
    m_Signature = ReadUInt32();

    if (ecd64.thisDiskNumber != 0 || ecd64.startCDDiskNumber != 0)
      return E_NOTIMPL;

    if (needSetBase)
    {
      ArcInfo.Base = cdAbsOffset - ecd64.cdStartOffset;
      cdRelatOffset = ecd64.cdStartOffset;
      needSetBase = false;
    }

    if (ecd64.numEntriesInCDOnThisDisk != numCdItems ||
        ecd64.numEntriesInCD != numCdItems ||
        ecd64.cdSize != cdSize ||
        (ecd64.cdStartOffset != cdRelatOffset &&
        (!items.IsEmpty())))
      return S_FALSE;
  }
  if (m_Signature == NSignature::kEcd64Locator)
  {
    if (!isZip64)
      return S_FALSE;
    /* UInt32 startEndCDDiskNumber = */ ReadUInt32();
    UInt64 ecd64RelatOffset = ReadUInt64();
    /* UInt32 numberOfDisks = */ ReadUInt32();
    if (ecd64AbsOffset != ArcInfo.Base + ecd64RelatOffset)
      return S_FALSE;
    m_Signature = ReadUInt32();
  }
  if (m_Signature != NSignature::kEcd)
    return S_FALSE;

  const unsigned kBufSize = kEcdSize - 4;
  Byte buf[kBufSize];
  SafeReadBytes(buf, kBufSize);
  CEcd ecd;
  ecd.Parse(buf);

  COPY_ECD_ITEM_16(thisDiskNumber);
  COPY_ECD_ITEM_16(startCDDiskNumber);
  COPY_ECD_ITEM_16(numEntriesInCDOnThisDisk);
  COPY_ECD_ITEM_16(numEntriesInCD);
  COPY_ECD_ITEM_32(cdSize);
  COPY_ECD_ITEM_32(cdStartOffset);

  if (needSetBase)
  {
    ArcInfo.Base = cdAbsOffset - ecd64.cdStartOffset;
    cdRelatOffset = ecd64.cdStartOffset;
    needSetBase = false;
  }

  if (localsWereRead && (UInt64)ArcInfo.Base != ArcInfo.MarkerPos)
  {
    UInt64 delta = ArcInfo.MarkerPos - ArcInfo.Base;
    for (unsigned i = 0; i < items.Size(); i++)
      items[i].LocalHeaderPos += delta;
  }


  // ---------- merge Central Directory Items ----------

  if (!cdItems.IsEmpty())
  {
    for (unsigned i = 0; i < cdItems.Size(); i++)
    {
      const CItemEx &cdItem = cdItems[i];
      int index = FindItem(items, cdItem.LocalHeaderPos);
      if (index == -1)
      {
        items.Add(cdItem);
        continue;
      }
      CItemEx &item = items[index];
      if (item.Name != cdItem.Name
          // || item.Name.Len() != cdItem.Name.Len()
          || item.PackSize != cdItem.PackSize
          || item.Size != cdItem.Size
          // item.ExtractVersion != cdItem.ExtractVersion
          || !FlagsAreSame(item, cdItem)
          || item.Crc != cdItem.Crc)
        continue;

      // item.LocalHeaderPos = cdItem.LocalHeaderPos;
      // item.Name = cdItem.Name;
      item.MadeByVersion = cdItem.MadeByVersion;
      item.CentralExtra = cdItem.CentralExtra;
      item.InternalAttrib = cdItem.InternalAttrib;
      item.ExternalAttrib = cdItem.ExternalAttrib;
      item.Comment = cdItem.Comment;
      item.FromCentral = cdItem.FromCentral;
    }
  }

  if (ecd64.thisDiskNumber != 0 || ecd64.startCDDiskNumber != 0)
    return E_NOTIMPL;

  if (isZip64)
  {
    if (ecd64.numEntriesInCDOnThisDisk != items.Size())
      HeadersError = true;
  }
  else
  {
    // old 7-zip could store 32-bit number of CD items to 16-bit field.
    if ((UInt16)ecd64.numEntriesInCDOnThisDisk != (UInt16)numCdItems ||
        (UInt16)ecd64.numEntriesInCDOnThisDisk != (UInt16)items.Size())
      HeadersError = true;
  }

  ReadBuffer(ArcInfo.Comment, ecd.commentSize);
  _inBufMode = false;
  _inBuffer.Free();

  if (
      (UInt16)ecd64.numEntriesInCD != ((UInt16)numCdItems) ||
      (UInt32)ecd64.cdSize != (UInt32)cdSize ||
      ((UInt32)(ecd64.cdStartOffset) != (UInt32)cdRelatOffset &&
        (!items.IsEmpty())))
    return S_FALSE;

  // printf("\nOpen OK");
  return S_OK;
}
Beispiel #17
0
 void Clear() { _fields.Clear(); }
Beispiel #18
0
 void Clear() { _fields.Clear(); LinesString.Empty(); }
void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers)
{
  archivers.Clear();
  
  #ifdef EXCLUDE_COM
  
  #ifdef FORMAT_7Z
  {
    CArchiverInfo item;
    item.UpdateEnabled = true;
    item.Name = L"7z";
    item.Extensions.Add(CArchiverExtInfo(L"7z"));
    #ifndef _SFX
    const unsigned char kSig[] = {'7' , 'z', 0xBC, 0xAF, 0x27, 0x1C};
    SetBuffer(item.StartSignature, kSig, 6);
    #endif
    archivers.Add(item);
  }
  #endif

  #ifdef FORMAT_BZIP2
  {
    CArchiverInfo item;
    item.UpdateEnabled = true;
    item.KeepName = true;
    item.Name = L"BZip2";
    item.Extensions.Add(CArchiverExtInfo(L"bz2"));
    item.Extensions.Add(CArchiverExtInfo(L"tbz2", L".tar"));
    #ifndef _SFX
    const unsigned char sig[] = {'B' , 'Z', 'h' };
    SetBuffer(item.StartSignature, sig, 3);
    #endif
    archivers.Add(item);
  }
  #endif

  #ifdef FORMAT_GZIP
  {
    CArchiverInfo item;
    item.UpdateEnabled = true;
    item.Name = L"GZip";
    item.Extensions.Add(CArchiverExtInfo(L"gz"));
    item.Extensions.Add(CArchiverExtInfo(L"tgz", L".tar"));
    #ifndef _SFX
    const unsigned char sig[] = { 0x1F, 0x8B };
    SetBuffer(item.StartSignature, sig, 2);
    #endif
    archivers.Add(item);
  }
  #endif

  #ifdef FORMAT_SPLIT
  {
    CArchiverInfo item;
    item.UpdateEnabled = false;
    item.KeepName = true;
    item.Name = L"Split";
    item.Extensions.Add(CArchiverExtInfo(L"001"));
    archivers.Add(item);
  }
  #endif

  #ifdef FORMAT_TAR
  {
    CArchiverInfo item;
    item.UpdateEnabled = true;
    item.Name = L"Tar";
    item.Extensions.Add(CArchiverExtInfo(L"tar"));
    archivers.Add(item);
  }
  #endif

  #ifdef FORMAT_ZIP
  {
    CArchiverInfo item;
    item.UpdateEnabled = true;
    item.Name = L"Zip";
    item.Extensions.Add(CArchiverExtInfo(L"zip"));
    #ifndef _SFX
    const unsigned char sig[] = { 0x50, 0x4B, 0x03, 0x04 };
    SetBuffer(item.StartSignature, sig, 4);
    #endif
    archivers.Add(item);
  }
  #endif

  #ifdef FORMAT_CPIO
  {
    CArchiverInfo item;
    item.Name = L"Cpio";
    item.Extensions.Add(CArchiverExtInfo(L"cpio"));
    archivers.Add(item);
  }
  #endif

  #ifdef FORMAT_RPM
  {
    CArchiverInfo item;
    item.Name = L"Rpm";
    item.Extensions.Add(CArchiverExtInfo(L"rpm", L".cpio.gz"));
    archivers.Add(item);
  }
  #endif

  #ifdef FORMAT_ARJ
  {
    CArchiverInfo item;
    item.Name = L"Arj";
    item.Extensions.Add(CArchiverExtInfo(L"arj"));
    #ifndef _SFX
    const unsigned char sig[] = { 0x60, 0xEA };
    SetBuffer(item.StartSignature, sig, 2);
    #endif
    archivers.Add(item);
  }
  #endif

  #ifdef FORMAT_Z
  {
    CArchiverInfo item;
    item.Name = L"Z";
    item.Extensions.Add(CArchiverExtInfo(L"Z"));
    #ifndef _SFX
    const unsigned char sig[] = { 0x1F, 0x9D };
    SetBuffer(item.StartSignature, sig, 2);
    #endif
    archivers.Add(item);
  }
  #endif
  
  #else

  UString folderPath = GetBaseFolderPrefixFromRegistry() + 
      (UString)kFormatFolderName + (UString)WSTRING_PATH_SEPARATOR;
  NFind::CEnumeratorW enumerator(folderPath + L"*");
  NFind::CFileInfoW fileInfo;
  while (enumerator.Next(fileInfo))
  {
    if (fileInfo.IsDirectory())
      continue;
    UString filePath = folderPath + fileInfo.Name;
    {
      NDLL::CLibrary library;
      if (!library.LoadEx(filePath, LOAD_LIBRARY_AS_DATAFILE))
        continue;
    }

    NDLL::CLibrary library;
    if (!library.Load(filePath))
      continue;
    GetHandlerPropertyFunc getHandlerProperty = (GetHandlerPropertyFunc)
        library.GetProcAddress("GetHandlerProperty");
    if (getHandlerProperty == NULL)
      continue;

    CArchiverInfo item;
    item.FilePath = filePath;
    
    NWindows::NCOM::CPropVariant prop;
    if (getHandlerProperty(NArchive::kName, &prop) != S_OK)
      continue;
    if (prop.vt != VT_BSTR)
      continue;
    item.Name = prop.bstrVal;
    prop.Clear();

    if (getHandlerProperty(NArchive::kClassID, &prop) != S_OK)
      continue;
    if (prop.vt != VT_BSTR)
      continue;
    item.ClassID = *(const GUID *)prop.bstrVal;
    prop.Clear();

    if (getHandlerProperty(NArchive::kExtension, &prop) != S_OK)
      continue;
    if (prop.vt != VT_BSTR)
      continue;

    UString ext  = prop.bstrVal;
    UString addExt;

    prop.Clear();

    if (getHandlerProperty(NArchive::kAddExtension, &prop) != S_OK)
      continue;
    if (prop.vt == VT_BSTR)
    {
      addExt = prop.bstrVal;
    }
    else if (prop.vt != VT_EMPTY)
      continue;
    prop.Clear();

    UStringVector exts, addExts;
    SplitString(ext, exts);
    SplitString(addExt, addExts);

    prop.Clear();
    for (int i = 0; i < exts.Size(); i++)
    {
      CArchiverExtInfo extInfo;
      extInfo.Ext = exts[i];
      if (addExts.Size() > 0)
        extInfo.AddExt = addExts[i];
      if (extInfo.AddExt == L"*")
        extInfo.AddExt.Empty();
      item.Extensions.Add(extInfo);
    }

    if (getHandlerProperty(NArchive::kUpdate, &prop) == S_OK)
      if (prop.vt == VT_BOOL)
        item.UpdateEnabled = VARIANT_BOOLToBool(prop.boolVal);
    prop.Clear();

    if (item.UpdateEnabled)
    {
      if (getHandlerProperty(NArchive::kKeepName, &prop) == S_OK)
        if (prop.vt == VT_BOOL)
          item.KeepName = VARIANT_BOOLToBool(prop.boolVal);
      prop.Clear();
    }

    if (getHandlerProperty(NArchive::kStartSignature, &prop) == S_OK)
    {
      if (prop.vt == VT_BSTR)
      {
        UINT len = ::SysStringByteLen(prop.bstrVal);
        item.StartSignature.SetCapacity(len);
        memmove(item.StartSignature, prop.bstrVal, len);
      }
    }
    prop.Clear();

    if (getHandlerProperty(NArchive::kAssociate, &prop) == S_OK)
      if (prop.vt == VT_BOOL)
        item.Associate = VARIANT_BOOLToBool(prop.boolVal);
    prop.Clear();


    archivers.Add(item);
  }

  #endif
}