static void AddToCensorFromNonSwitchesStrings(
    int startIndex,
    NWildcard::CCensor &wildcardCensor,
    const UStringVector &nonSwitchStrings, NRecursedType::EEnum type,
    bool thereAreSwitchIncludes, UINT codePage)
{
  if (nonSwitchStrings.Size() == startIndex && (!thereAreSwitchIncludes))
    AddNameToCensor(wildcardCensor, kUniversalWildcard, true, type);
  for (int i = startIndex; i < nonSwitchStrings.Size(); i++)
  {
    const UString &s = nonSwitchStrings[i];
    if (s[0] == kFileListID)
      AddToCensorFromListFile(wildcardCensor, s.Mid(1), true, type, codePage);
    else
      AddNameToCensor(wildcardCensor, s, true, type);
  }
}
void CParser::ParseStrings(const CSwitchForm *switchForms, 
  const UStringVector &commandStrings)
{
  int numCommandStrings = commandStrings.Size();
  for (int i = 0; i < numCommandStrings; i++)
    if (!ParseString(commandStrings[i], switchForms))
      NonSwitchStrings.Add(commandStrings[i]);
}
void EnumerateDirItemsAndSort(NWildcard::CCensor &wildcardCensor,
    UStringVector &sortedPaths,
    UStringVector &sortedFullPaths)
{
  UStringVector paths;
  {
    CDirItems dirItems;
    {
      UStringVector errorPaths;
      CRecordVector<DWORD> errorCodes;
      HRESULT res = EnumerateItems(wildcardCensor, dirItems, NULL, errorPaths, errorCodes);
      if (res != S_OK || errorPaths.Size() > 0)
        throw "cannot find archive";
    }
    for (int i = 0; i < dirItems.Items.Size(); i++)
    {
      const CDirItem &dirItem = dirItems.Items[i];
      if (!dirItem.IsDir())
        paths.Add(dirItems.GetPhyPath(i));
    }
  }
  
  if (paths.Size() == 0)
    throw "there is no such archive";
  
  UStringVector fullPaths;
  
  int i;
  for (i = 0; i < paths.Size(); i++)
  {
    UString fullPath;
    NFile::NDirectory::MyGetFullPathName(paths[i], fullPath);
    fullPaths.Add(fullPath);
  }
  CIntVector indices;
  SortFileNames(fullPaths, indices);
  sortedPaths.Reserve(indices.Size());
  sortedFullPaths.Reserve(indices.Size());
  for (i = 0; i < indices.Size(); i++)
  {
    int index = indices[i];
    sortedPaths.Add(paths[index]);
    sortedFullPaths.Add(fullPaths[index]);
  }
}
Exemple #4
0
void SortFileNames(const UStringVector &strings, CIntVector &indices)
{
  indices.Clear();
  int numItems = strings.Size();
  indices.Reserve(numItems);
  for(int i = 0; i < numItems; i++)
    indices.Add(i);
  indices.Sort(CompareStrings, (void *)&strings);
}
static void AddToCensorFromListFile(NWildcard::CCensor &wildcardCensor,
    LPCWSTR fileName, bool include, NRecursedType::EEnum type, UINT codePage)
{
  UStringVector names;
  if (!ReadNamesFromListFile(fileName, names, codePage))
    throw kIncorrectListFile;
  for (int i = 0; i < names.Size(); i++)
    AddNameToCensor(wildcardCensor, names[i], include, type);
}
Exemple #6
0
void AddUniqueStringToHeadOfList(UStringVector &list, const UString &s)
{
  for (unsigned i = 0; i < list.Size();)
    if (s.IsEqualTo_NoCase(list[i]))
      list.Delete(i);
    else
      i++;
  list.Insert(0, s);
}
Exemple #7
0
static void AddToCensorFromNonSwitchesStrings(
    CObjectVector<CRenamePair> *renamePairs,
    unsigned startIndex,
    NWildcard::CCensor &censor,
    const UStringVector &nonSwitchStrings, NRecursedType::EEnum type,
    bool wildcardMatching,
    bool thereAreSwitchIncludes, Int32 codePage)
{
  if ((renamePairs || nonSwitchStrings.Size() == startIndex) && !thereAreSwitchIncludes)
    AddNameToCensor(censor, kUniversalWildcard, true, type,
        true // wildcardMatching
        );

  int oldIndex = -1;
  
  for (unsigned i = startIndex; i < nonSwitchStrings.Size(); i++)
  {
    const UString &s = nonSwitchStrings[i];
    if (s.IsEmpty())
      throw CArcCmdLineException(kEmptyFilePath);
    if (s[0] == kFileListID)
      AddToCensorFromListFile(renamePairs, censor, s.Ptr(1), true, type, wildcardMatching, codePage);
    else if (renamePairs)
    {
      if (oldIndex == -1)
        oldIndex = i;
      else
      {
        // NRecursedType::EEnum type is used for global wildcard (-i! switches)
        AddRenamePair(renamePairs, nonSwitchStrings[oldIndex], s, NRecursedType::kNonRecursed, wildcardMatching);
        // AddRenamePair(renamePairs, nonSwitchStrings[oldIndex], s, type);
        oldIndex = -1;
      }
    }
    else
      AddNameToCensor(censor, s, true, type, wildcardMatching);
  }
  
  if (oldIndex != -1)
  {
    throw CArcCmdLineException("There is no second file name for rename pair:", nonSwitchStrings[oldIndex]);
  }
}
void CExtractCallbackImp::CreateComplexDirectory(const UStringVector &dirPathParts)
{
  UString fullPath = _directoryPath;
  for(int i = 0; i < dirPathParts.Size(); i++)
  {
    fullPath += dirPathParts[i];
    NDirectory::MyCreateDirectory(fullPath);
    fullPath += NName::kDirDelimiter;
  }
}
HRESULT CThreadCombine::ProcessVirt()
{
  NFile::NIO::COutFile outFile;
  if (!outFile.Create(OutputPath, false))
  {
    HRESULT res = GetLastError();
    ErrorPath1 = OutputPath;
    return res;
  }
  
  CProgressSync &sync = ProgressDialog.Sync;
  sync.SetProgress(TotalSize, 0);
  
  CMyBuffer bufferObject;
  if (!bufferObject.Allocate(kBufSize))
    return E_OUTOFMEMORY;
  Byte *buffer = (Byte *)(void *)bufferObject;
  UInt64 pos = 0;
  for (int i = 0; i < Names.Size(); i++)
  {
    NFile::NIO::CInFile inFile;
    const UString nextName = InputDirPrefix + Names[i];
    if (!inFile.Open(nextName))
    {
      HRESULT res = GetLastError();
      ErrorPath1 = nextName;
      return res;
    }
    sync.SetCurrentFileName(nextName);
    for (;;)
    {
      UInt32 processedSize;
      if (!inFile.Read(buffer, kBufSize, processedSize))
      {
        HRESULT res = GetLastError();
        ErrorPath1 = nextName;
        return res;
      }
      if (processedSize == 0)
        break;
      UInt32 needSize = processedSize;
      if (!outFile.Write(buffer, needSize, processedSize))
      {
        HRESULT res = GetLastError();
        ErrorPath1 = OutputPath;
        return res;
      }
      if (needSize != processedSize)
        throw g_Message_FileWriteError;
      pos += processedSize;
      RINOK(sync.SetPosAndCheckPaused(pos));
    }
  }
  return S_OK;
}
Exemple #10
0
UString CParsedPath::MergePath() const
{
  UString result = Prefix;
  for (int i = 0; i < PathParts.Size(); i++)
  {
    if (i != 0)
      result += kDirDelimiter;
    result += PathParts[i];
  }
  return result;
}
UString MakePathNameFromParts(const UStringVector &parts)
{
  UString result;
  for (int i = 0; i < parts.Size(); i++)
  {
    if (i != 0)
      result += WCHAR_PATH_SEPARATOR;
    result += parts[i];
  }
  return result;
}
Exemple #12
0
UString JoinStrings(const UStringVector &srcStrings)
{
  UString destString;
  for (int i = 0; i < srcStrings.Size(); i++)
  {
    if (i != 0)
      destString += L' ';
    destString += srcStrings[i];
  }
  return destString;
}
Exemple #13
0
void CPlugin::GetCurrentDir()
{
  m_CurrentDir.Empty();
  UStringVector pathParts;
  GetPathParts(pathParts);
  for (int i = 0; i < pathParts.Size(); i++)
  {
    m_CurrentDir += WCHAR_PATH_SEPARATOR;
    m_CurrentDir += pathParts[i];
  }
}
Exemple #14
0
void SortFileNames(const UStringVector &strings, CUIntVector &indices)
{
  const unsigned numItems = strings.Size();
  indices.ClearAndSetSize(numItems);
  if (numItems == 0)
    return;
  unsigned *vals = &indices[0];
  for (unsigned i = 0; i < numItems; i++)
    vals[i] = i;
  indices.Sort(CompareStrings, (void *)&strings);
}
void MakeCorrectPath(UStringVector &pathParts)
{
  for (int i = 0; i < pathParts.Size();)
  {
    UString &s = pathParts[i];
    s = GetCorrectFileName(s);
    if (s.IsEmpty())
      pathParts.Delete(i);
    else
      i++;
  }
}
Exemple #16
0
HRESULT DecompressArchives(
    UStringVector &archivePaths, UStringVector &archivePathsFull,    
    const NWildcard::CCensorNode &wildcardCensor,
    const CExtractOptions &optionsSpec,
    IOpenCallbackUI *openCallback,
    IExtractCallbackUI *extractCallback)
{
  CExtractOptions options = optionsSpec;
  for (int i = 0; i < archivePaths.Size(); i++)
  {
    const UString &archivePath = archivePaths[i];
    NFile::NFind::CFileInfoW archiveFileInfo;
    if (!NFile::NFind::FindFile(archivePath, archiveFileInfo))
      throw "there is no such archive";

    if (archiveFileInfo.IsDirectory())
      throw "there is no such archive";

    options.ArchiveFileInfo = archiveFileInfo;

    RINOK(extractCallback->BeforeOpen(archivePath));
    CArchiveLink archiveLink;
    HRESULT result = MyOpenArchive(archivePath, archiveLink, openCallback);
    RINOK(extractCallback->OpenResult(archivePath, result));
    if (result != S_OK)
      continue;

    for (int v = 0; v < archiveLink.VolumePaths.Size(); v++)
    {
      int index = archivePathsFull.FindInSorted(archiveLink.VolumePaths[v]);
      if (index >= 0 && index > i)
      {
        archivePaths.Delete(index);
        archivePathsFull.Delete(index);
      }
    }

    #ifndef _NO_CRYPTO
    UString password;
    RINOK(openCallback->GetPasswordIfAny(password));
    if (!password.IsEmpty())
    {
      RINOK(extractCallback->SetPassword(password));
    }
    #endif

    options.DefaultItemName = archiveLink.GetDefaultItemName();
    RINOK(DecompressArchive(
        archiveLink.GetArchive(), archiveLink.GetDefaultItemName(),
        wildcardCensor, options, extractCallback));
  }
  return S_OK;
}
Exemple #17
0
STDMETHODIMP CFSDrives::LoadItems()
{
  _drives.Clear();

  UStringVector driveStrings;
  MyGetLogicalDriveStrings(driveStrings);
  for (int i = 0; i < driveStrings.Size(); i++)
  {
    CDriveInfo di;

    const UString &driveName = driveStrings[i];

    di.FullSystemName = driveName;

    di.Name = di.FullSystemName.Left(di.FullSystemName.Length() - 1);
    di.ClusterSize = 0;
    di.DriveSize = 0;
    di.FreeSpace = 0;
    di.DriveType = NFile::NSystem::MyGetDriveType(driveName);
    bool needRead = true;
    if (di.DriveType == DRIVE_CDROM || di.DriveType == DRIVE_REMOVABLE)
    {
      /*
      DWORD dwSerialNumber;`
      if (!::GetVolumeInformation(di.FullSystemName,
          NULL, 0, &dwSerialNumber, NULL, NULL, NULL, 0))
      */
      di.KnownSizes = false;
      {
        needRead = false;
      }
    }
    if (needRead)
    {
      UString volumeName, fileSystemName;
      DWORD volumeSerialNumber, maximumComponentLength, fileSystemFlags;
      NFile::NSystem::MyGetVolumeInformation(driveName,
          volumeName,
          &volumeSerialNumber, &maximumComponentLength, &fileSystemFlags,
          fileSystemName);
      di.VolumeName = volumeName;
      di.FileSystemName = fileSystemName;

      NFile::NSystem::MyGetDiskFreeSpace(driveName,
          di.ClusterSize, di.DriveSize, di.FreeSpace);
      di.KnownSizes = true;
    }
    _drives.Add(di);
  }
  return S_OK;
}
HRESULT SetProperties(IUnknown *unknown, const CObjectVector<CProperty> &properties)
{
  if (properties.IsEmpty())
    return S_OK;
  CMyComPtr<ISetProperties> setProperties;
  unknown->QueryInterface(IID_ISetProperties, (void **)&setProperties);
  if (!setProperties)
    return S_OK;

  UStringVector realNames;
  CPropVariant *values = new CPropVariant[properties.Size()];
  try
  {
    int i;
    for(i = 0; i < properties.Size(); i++)
    {
      const CProperty &property = properties[i];
      NCOM::CPropVariant propVariant;
      UString name = property.Name;
      if (property.Value.IsEmpty())
      {
        if (!name.IsEmpty())
        {
          wchar_t c = name.Back();
          if (c == L'-')
            propVariant = false;
          else if (c == L'+')
            propVariant = true;
          if (propVariant.vt != VT_EMPTY)
            name.DeleteBack();
        }
      }
      else
        ParseNumberString(property.Value, propVariant);
      realNames.Add(name);
      values[i] = propVariant;
    }
    CRecordVector<const wchar_t *> names;
    for(i = 0; i < realNames.Size(); i++)
      names.Add((const wchar_t *)realNames[i]);
    
    RINOK(setProperties->SetProperties(&names.Front(), values, names.Size()));
  }
  catch(...)
  {
    delete []values;
    throw;
  }
  delete []values;
  return S_OK;
}
Exemple #19
0
bool ParseVolumeSizes(const UString &s, CRecordVector<UInt64> &values)
{
  values.Clear();
  UStringVector destStrings;
  SplitString(s, destStrings);
  bool prevIsNumber = false;
  for (int i = 0; i < destStrings.Size(); i++)
  {
    UString subString = destStrings[i];
    subString.MakeUpper();
    if (subString.IsEmpty())
      return false;
    if (subString == L"-")
      return true;
    if (prevIsNumber)
    {
      wchar_t c = subString[0];
      UInt64 &value = values.Back();
      prevIsNumber = false;
      switch(c)
      {
        case L'B':
          continue;
        case L'K':
          value <<= 10;
          continue;
        case L'M':
          value <<= 20;
          continue;
        case L'G':
          value <<= 30;
          continue;
      }
    }
    const wchar_t *start = subString;
    const wchar_t *end;
    UInt64 value = ConvertStringToUInt64(start, &end);
    if (start == end)
      return false;
    if (value == 0)
      return false;
    values.Add(value);
    prevIsNumber = true;
    UString rem = subString.Mid((int)(end - start));
    if (!rem.IsEmpty())
      destStrings.Insert(i + 1, rem);
  }
  return true;
}
Exemple #20
0
static HRESULT SetOutProperties(IOutFolderArchive *outArchive, UINT32 method)
{
  CMyComPtr<ISetProperties> setProperties;
  if (outArchive->QueryInterface(IID_ISetProperties, (void **)&setProperties) == S_OK)
  {
    UStringVector realNames;
    realNames.Add(UString(L"x"));
    NCOM::CPropVariant value = (UInt32)method;
    CRecordVector<const wchar_t *> names;
    for (int i = 0; i < realNames.Size(); i++)
      names.Add(realNames[i]);
    RINOK(setProperties->SetProperties(&names.Front(), &value, names.Size()));
  }
  return S_OK;
}
Exemple #21
0
static void AddToCensorFromListFile(
    CObjectVector<CRenamePair> *renamePairs,
    NWildcard::CCensor &censor,
    LPCWSTR fileName, bool include, NRecursedType::EEnum type, bool wildcardMatching, Int32 codePage)
{
  UStringVector names;
  if (!NFind::DoesFileExist(us2fs(fileName)))
    throw CArcCmdLineException(kCannotFindListFile, fileName);
  if (!ReadNamesFromListFile(us2fs(fileName), names, codePage))
    throw CArcCmdLineException(kIncorrectListFile, fileName);
  if (renamePairs)
  {
    if ((names.Size() & 1) != 0)
      throw CArcCmdLineException(kIncorrectListFile, fileName);
    for (unsigned i = 0; i < names.Size(); i += 2)
    {
      // change type !!!!
      AddRenamePair(renamePairs, names[i], names[i + 1], type, wildcardMatching);
    }
  }
  else
    FOR_VECTOR (i, names)
      AddNameToCensor(censor, names[i], include, type, wildcardMatching);
}
bool CDirEnumerator::GetNextFile(NFind::CFileInfoW &fileInfo, bool &filled, UString &resPath, DWORD &errorCode)
{
    filled = false;
    for (;;)
    {
        if (Enumerators.IsEmpty())
        {
            if (Index >= FileNames.Size())
                return true;
            const UString &path = FileNames[Index];
            int pos = path.ReverseFind(WCHAR_PATH_SEPARATOR);
            resPath.Empty();
            if (pos >= 0)
                resPath = path.Left(pos + 1);
            if (!NFind::FindFile(BasePrefix + path, fileInfo))
            {
                errorCode = ::GetLastError();
                resPath = path;
                return false;
            }
            Index++;
            break;
        }
        bool found;
        if (!Enumerators.Back().Next(fileInfo, found))
        {
            errorCode = ::GetLastError();
            resPath = Prefixes.Back();
            return false;
        }
        if (found)
        {
            resPath = Prefixes.Back();
            break;
        }
        Enumerators.DeleteBack();
        Prefixes.DeleteBack();
    }
    resPath += fileInfo.Name;
    if (!FlatMode && fileInfo.IsDir())
    {
        UString prefix = resPath + (UString)(wchar_t)kDirDelimiter;
        Enumerators.Add(NFind::CEnumeratorW(BasePrefix + prefix + (UString)(wchar_t)kAnyStringWildcard));
        Prefixes.Add(prefix);
    }
    filled = true;
    return true;
}
UString GetCorrectFullFsPath(const UString &path)
{
  UStringVector parts;
  SplitPathToParts(path, parts);
  for (int i = 0; i < parts.Size(); i++)
  {
    UString &s = parts[i];
    #ifdef _WIN32
    while (!s.IsEmpty() && s[s.Length() - 1] == '.')
      s.Delete(s.Length() - 1);
    if (!IsSupportedName(s))
      s = (UString)L"_" + s;
    #endif
  }
  return MakePathNameFromParts(parts);
}
Exemple #24
0
static void OpenDefaultLang()
{
  LANGID sysLang = GetSystemDefaultLangID(); // "Language for non-Unicode programs" in XP64
  LANGID userLang = GetUserDefaultLangID(); // "Standards and formats" language in XP64

  if (sysLang != userLang)
    return;
  LANGID langID = userLang;
  
  /*
  LANGID sysUILang; // english  in XP64
  LANGID userUILang; // english  in XP64

  GetUserDefaultUILanguageP fn = (GetUserDefaultUILanguageP)GetProcAddress(
      GetModuleHandle("kernel32"), "GetUserDefaultUILanguage");
  if (fn)
    userUILang = fn();
  fn = (GetUserDefaultUILanguageP)GetProcAddress(
      GetModuleHandle("kernel32"), "GetSystemDefaultUILanguage");
  if (fn)
    sysUILang = fn();
  */

  WORD primLang = (WORD)(PRIMARYLANGID(langID));
  WORD subLang = (WORD)(SUBLANGID(langID));
  {
    UStringVector names;
    FindShortNames(primLang, names);
    const FString dirPrefix = GetLangDirPrefix();
    for (unsigned i = 0; i < 2; i++)
    {
      unsigned index = (i == 0 ? subLang : 0);
      if (index < names.Size())
      {
        const UString &name = names[index];
        if (!name.IsEmpty())
        {
          if (LangOpen(g_Lang, dirPrefix + us2fs(name) + FTEXT(".txt")))
          {
            g_LangID = name;
            return;
          }
        }
      }
    }
  }
}
Exemple #25
0
static HRESULT ExtractGroupCommand(const UStringVector &arcPaths,
    bool showDialog, const UString &outFolder, bool testMode)
{
  HRESULT result;
  MY_TRY_BEGIN
  CREATE_CODECS

  CExtractOptions eo;
  eo.OutputDir = outFolder;
  eo.TestMode = testMode;

  CExtractCallbackImp *ecs = new CExtractCallbackImp;
  CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
  
  ecs->Init();
  
  // eo.CalcCrc = options.CalcCrc;
  
  UStringVector arcPathsSorted;
  UStringVector arcFullPathsSorted;
  {
    NWildcard::CCensor acrCensor;
    for (int i = 0; i < arcPaths.Size(); i++)
      acrCensor.AddItem(true, arcPaths[i], false);
    EnumerateDirItemsAndSort(acrCensor, arcPathsSorted, arcFullPathsSorted);
  }
  
  CIntVector formatIndices;

  NWildcard::CCensor censor;
  censor.AddItem(true, L"*", false);
  
  bool messageWasDisplayed = false;
  result = ExtractGUI(codecs, formatIndices, arcPathsSorted, arcFullPathsSorted,
      censor.Pairs.Front().Head, eo, showDialog, messageWasDisplayed, ecs, g_HWND);
  if (result != S_OK)
  {
    if (result != E_ABORT && messageWasDisplayed)
      return E_FAIL;
    throw CSystemException(result);
  }
  return ecs->IsOK() ? S_OK : E_FAIL;
  MY_TRY_FINISH
  return result;
}
void CParser::ParseStrings(const CSwitchForm *switchForms,
  const UStringVector &commandStrings)
{
  int numCommandStrings = commandStrings.Size();
  bool stopSwitch = false;
  for (int i = 0; i < numCommandStrings; i++)
  {
    const UString &s = commandStrings[i];
    if (stopSwitch)
      NonSwitchStrings.Add(s);
    else
      if (s == kStopSwitchParsing)
        stopSwitch = true;
      else
        if (!ParseString(s, switchForms))
          NonSwitchStrings.Add(s);
  }
}
void MakeCorrectPath(UStringVector &pathParts)
{
  for (int i = 0; i < pathParts.Size();)
  {
    UString &s = pathParts[i];
    s = GetCorrectFileName(s);
    if (s.IsEmpty())
      pathParts.Delete(i);
    else
    {
      #ifdef _WIN32
      if (!IsSupportedName(s))
        s = (UString)L"_" + s;
      #endif
      i++;
    }
  }
}
static void ParseUpdateCommandString(CUpdateOptions &options,
    const UStringVector &updatePostStrings,
    const NUpdateArchive::CActionSet &defaultActionSet)
{
  for (int i = 0; i < updatePostStrings.Size(); i++)
  {
    const UString &updateString = updatePostStrings[i];
    if (updateString.CompareNoCase(kUpdateIgnoreItselfPostStringID) == 0)
    {
      if (options.UpdateArchiveItself)
      {
        options.UpdateArchiveItself = false;
        options.Commands.Delete(0);
      }
    }
    else
    {
      NUpdateArchive::CActionSet actionSet = defaultActionSet;

      UString postString;
      if (!ParseUpdateCommandString2(updateString, actionSet, postString))
        ThrowUserErrorException();
      if (postString.IsEmpty())
      {
        if (options.UpdateArchiveItself)
          options.Commands[0].ActionSet = actionSet;
      }
      else
      {
        if (MyCharUpper(postString[0]) != kUpdateNewArchivePostCharID)
          ThrowUserErrorException();
        CUpdateArchiveCommand uc;
        UString archivePath = postString.Mid(1);
        if (archivePath.IsEmpty())
          ThrowUserErrorException();
        uc.UserArchivePath = archivePath;
        uc.ActionSet = actionSet;
        options.Commands.Add(uc);
      }
    }
  }
}
Exemple #29
0
static void ParseAndAddPropertires(CObjectVector<CProperty> &properties,
    const UString &propertiesString)
{
  UStringVector strings;
  SplitString(propertiesString, strings);
  for (int i = 0; i < strings.Size(); i++)
  {
    const UString &s = strings[i];
    CProperty property;
    int index = s.Find(L'=');
    if (index < 0)
      property.Name = s;
    else
    {
      property.Name = s.Left(index);
      property.Value = s.Mid(index + 1);
    }
    properties.Add(property);
  }
}
Exemple #30
0
HRESULT CPlugin::AfterUpdate(CWorkDirTempFile &tempFile, const UStringVector &pathVector)
{
  _folder.Release();
  m_ArchiveHandler->Close();
  
  RINOK(tempFile.MoveToOriginal(true));
  
  RINOK(m_ArchiveHandler->ReOpen(NULL)); // check it

  m_ArchiveHandler->BindToRootFolder(&_folder);
  for (int i = 0; i < pathVector.Size(); i++)
  {
    CMyComPtr<IFolderFolder> newFolder;
    _folder->BindToFolder(pathVector[i], &newFolder);
    if (!newFolder)
      break;
    _folder = newFolder;
  }
  return S_OK;
}