Example #1
0
void CDirItems::EnumerateDirItems2(const FString &phyPrefix, const UString &logPrefix,
    const FStringVector &filePaths, FStringVector &errorPaths, CRecordVector<DWORD> &errorCodes)
{
  int phyParent = phyPrefix.IsEmpty() ? -1 : AddPrefix(-1, -1, fs2us(phyPrefix));
  int logParent = logPrefix.IsEmpty() ? -1 : AddPrefix(-1, -1, logPrefix);

  for (int i = 0; i < filePaths.Size(); i++)
  {
    const FString &filePath = filePaths[i];
    NFind::CFileInfo fi;
    const FString phyPath = phyPrefix + filePath;
    if (!fi.Find(phyPath))
    {
      errorCodes.Add(::GetLastError());
      errorPaths.Add(phyPath);
      continue;
    }
    int delimiter = filePath.ReverseFind(FCHAR_PATH_SEPARATOR);
    FString phyPrefixCur;
    int phyParentCur = phyParent;
    if (delimiter >= 0)
    {
      phyPrefixCur = filePath.Left(delimiter + 1);
      phyParentCur = AddPrefix(phyParent, logParent, fs2us(phyPrefixCur));
    }
    AddDirFileInfo(phyParentCur, logParent, fi, Items);
    if (fi.IsDir())
    {
      const FString name2 = fi.Name + FCHAR_PATH_SEPARATOR;
      int parent = AddPrefix(phyParentCur, logParent, fs2us(name2));
      EnumerateDirectory(parent, parent, phyPrefix + phyPrefixCur + name2, errorPaths, errorCodes);
    }
  }
  ReserveDown();
}
Example #2
0
HRESULT CDirEnumerator::GetNextFile(NFind::CFileInfo &fileInfo, bool &filled, FString &resPath)
{
  filled = false;
  for (;;)
  {
    if (Enumerators.IsEmpty())
    {
      if (Index >= FileNames.Size())
        return S_OK;
      const FString &path = FileNames[Index];
      int pos = path.ReverseFind(FCHAR_PATH_SEPARATOR);
      resPath.Empty();
      if (pos >= 0)
        resPath = path.Left(pos + 1);

      #ifdef _WIN32
      // it's for "c:" paths/
      if (BasePrefix.IsEmpty() && path.Length() == 2 && path[1] == ':')
      {
        fileInfo.Name = path;
        fileInfo.Attrib = FILE_ATTRIBUTE_DIRECTORY;
        fileInfo.Size = 0;
      }
      else
      #endif
      if (!fileInfo.Find(BasePrefix + path))
      {
        WRes errorCode = GetNormalizedError();
        resPath = path;
        return errorCode;
      }
      Index++;
      break;
    }
    bool found;
    if (!Enumerators.Back().Next(fileInfo, found))
    {
      HRESULT errorCode = GetNormalizedError();
      resPath = Prefixes.Back();
      return errorCode;
    }
    if (found)
    {
      resPath = Prefixes.Back();
      break;
    }
    Enumerators.DeleteBack();
    Prefixes.DeleteBack();
  }
  resPath += fileInfo.Name;
  if (!FlatMode && fileInfo.IsDir())
  {
    FString prefix = resPath + FCHAR_PATH_SEPARATOR;
    Enumerators.Add(NFind::CEnumerator(BasePrefix + prefix + FCHAR_ANY_MASK));
    Prefixes.Add(prefix);
  }
  filled = true;
  return S_OK;
}
Example #3
0
STDMETHODIMP CFSDrives::LoadItems()
{
    _drives.Clear();

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

        const FString &driveName = driveStrings[i];

        di.FullSystemName = driveName;
        if (!driveName.IsEmpty())
            di.Name = driveName.Left(driveName.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)
        {
            DWORD volumeSerialNumber, maximumComponentLength, fileSystemFlags;
            NFile::NSystem::MyGetVolumeInformation(driveName,
                                                   di.VolumeName,
                                                   &volumeSerialNumber, &maximumComponentLength, &fileSystemFlags,
                                                   di.FileSystemName);

            NFile::NSystem::MyGetDiskFreeSpace(driveName,
                                               di.ClusterSize, di.DriveSize, di.FreeSpace);
            di.KnownSizes = true;
        }
        _drives.Add(di);
    }
    return S_OK;
}
Example #4
0
void CDirItems::EnumerateDirectory(int phyParent, int logParent, const FString &phyPrefix,
    FStringVector &errorPaths, CRecordVector<DWORD> &errorCodes)
{
  NFind::CEnumerator enumerator(phyPrefix + FCHAR_ANY_MASK);
  for (;;)
  {
    NFind::CFileInfo fi;
    bool found;
    if (!enumerator.Next(fi, found))
    {
      errorCodes.Add(::GetLastError());
      errorPaths.Add(phyPrefix);
      return;
    }
    if (!found)
      break;
    AddDirFileInfo(phyParent, logParent, fi, Items);
    if (fi.IsDir())
    {
      const FString name2 = fi.Name + FCHAR_PATH_SEPARATOR;
      int parent = AddPrefix(phyParent, logParent, fs2us(name2));
      EnumerateDirectory(parent, parent, phyPrefix + name2, errorPaths, errorCodes);
    }
  }
}
bool CPanel::OnComboBoxCommand(UINT code, LPARAM /* param */, LRESULT &result)
{
  result = FALSE;
  switch (code)
  {
    case CBN_DROPDOWN:
    {
      ComboBoxPaths.Clear();
      _headerComboBox.ResetContent();
      
      unsigned i;
      UStringVector pathParts;
      
      SplitPathToParts(_currentFolderPrefix, pathParts);
      UString sumPass;
      if (!pathParts.IsEmpty())
        pathParts.DeleteBack();
      for (i = 0; i < pathParts.Size(); i++)
      {
        UString name = pathParts[i];
        sumPass += name;
        sumPass.Add_PathSepar();
        CFileInfo info;
        DWORD attrib = FILE_ATTRIBUTE_DIRECTORY;
        if (info.Find(us2fs(sumPass)))
          attrib = info.Attrib;
        AddComboBoxItem(name.IsEmpty() ? L"\\" : name, GetRealIconIndex(us2fs(sumPass), attrib), i, false);
        ComboBoxPaths.Add(sumPass);
      }

      #ifndef UNDER_CE

      int iconIndex;
      UString name;
      name = RootFolder_GetName_Documents(iconIndex);
      AddComboBoxItem(name, iconIndex, 0, true);

      name = RootFolder_GetName_Computer(iconIndex);
      AddComboBoxItem(name, iconIndex, 0, true);
        
      FStringVector driveStrings;
      MyGetLogicalDriveStrings(driveStrings);
      for (i = 0; i < driveStrings.Size(); i++)
      {
        FString s = driveStrings[i];
        ComboBoxPaths.Add(fs2us(s));
        int iconIndex = GetRealIconIndex(s, 0);
        if (s.Len() > 0 && s.Back() == FCHAR_PATH_SEPARATOR)
          s.DeleteBack();
        AddComboBoxItem(fs2us(s), iconIndex, 1, false);
      }

      name = RootFolder_GetName_Network(iconIndex);
      AddComboBoxItem(name, iconIndex, 0, true);

      #endif
    
      return false;
    }

    case CBN_SELENDOK:
    {
      code = code;
      int index = _headerComboBox.GetCurSel();
      if (index >= 0)
      {
        UString pass = ComboBoxPaths[index];
        _headerComboBox.SetCurSel(-1);
        // _headerComboBox.SetText(pass); // it's fix for seclecting by mouse.
        if (BindToPathAndRefresh(pass) == S_OK)
        {
          PostMsg(kSetFocusToListView);
          #ifdef UNDER_CE
          PostMsg(kRefresh_HeaderComboBox);
          #endif
          return true;
        }
      }
      return false;
    }
    /*
    case CBN_CLOSEUP:
    {
      LoadFullPathAndShow();
      true;

    }
    case CBN_SELCHANGE:
    {
      // LoadFullPathAndShow();
      return true;
    }
    */
  }
  return false;
}
Example #6
0
static HRESULT EnumerateDirItems(const NWildcard::CCensorNode &curNode,
    int phyParent, int logParent, const FString &phyPrefix,
    const UStringVector &addArchivePrefix,  // prefix from curNode
    CDirItems &dirItems,
    bool enterToSubFolders,
    IEnumDirItemCallback *callback,
    FStringVector &errorPaths,
    CRecordVector<DWORD> &errorCodes)
{
  if (!enterToSubFolders)
    if (curNode.NeedCheckSubDirs())
      enterToSubFolders = true;
  if (callback)
    RINOK(callback->ScanProgress(dirItems.GetNumFolders(), dirItems.Items.Size(), fs2us(phyPrefix)));

  // try direct_names case at first
  if (addArchivePrefix.IsEmpty() && !enterToSubFolders)
  {
    // check that all names are direct
    int i;
    for (i = 0; i < curNode.IncludeItems.Size(); i++)
    {
      const NWildcard::CItem &item = curNode.IncludeItems[i];
      if (item.Recursive || item.PathParts.Size() != 1)
        break;
      const UString &name = item.PathParts.Front();
      if (name.IsEmpty() || DoesNameContainWildCard(name))
        break;
    }
    if (i == curNode.IncludeItems.Size())
    {
      // all names are direct (no wildcards)
      // so we don't need file_system's dir enumerator
      CRecordVector<bool> needEnterVector;
      for (i = 0; i < curNode.IncludeItems.Size(); i++)
      {
        const NWildcard::CItem &item = curNode.IncludeItems[i];
        const UString &name = item.PathParts.Front();
        const FString fullPath = phyPrefix + us2fs(name);
        NFind::CFileInfo fi;
        if (!fi.Find(fullPath))
        {
          errorCodes.Add(::GetLastError());
          errorPaths.Add(fullPath);
          continue;
        }
        bool isDir = fi.IsDir();
        if (isDir && !item.ForDir || !isDir && !item.ForFile)
        {
          errorCodes.Add((DWORD)E_FAIL);
          errorPaths.Add(fullPath);
          continue;
        }
        {
          UStringVector pathParts;
          pathParts.Add(fs2us(fi.Name));
          if (curNode.CheckPathToRoot(false, pathParts, !isDir))
            continue;
        }
        AddDirFileInfo(phyParent, logParent, fi, dirItems.Items);
        if (!isDir)
          continue;
        
        UStringVector addArchivePrefixNew;
        const NWildcard::CCensorNode *nextNode = 0;
        int index = curNode.FindSubNode(name);
        if (index >= 0)
        {
          for (int t = needEnterVector.Size(); t <= index; t++)
            needEnterVector.Add(true);
          needEnterVector[index] = false;
          nextNode = &curNode.SubNodes[index];
        }
        else
        {
          nextNode = &curNode;
          addArchivePrefixNew.Add(name); // don't change it to fi.Name. It's for shortnames support
        }

        RINOK(EnumerateDirItems_Spec(*nextNode, phyParent, logParent, fi.Name, phyPrefix,
            addArchivePrefixNew, dirItems, true, callback, errorPaths, errorCodes));
      }
      for (i = 0; i < curNode.SubNodes.Size(); i++)
      {
        if (i < needEnterVector.Size())
          if (!needEnterVector[i])
            continue;
        const NWildcard::CCensorNode &nextNode = curNode.SubNodes[i];
        const FString fullPath = phyPrefix + us2fs(nextNode.Name);
        NFind::CFileInfo fi;
        if (!fi.Find(fullPath))
        {
          if (!nextNode.AreThereIncludeItems())
            continue;
          errorCodes.Add(::GetLastError());
          errorPaths.Add(fullPath);
          continue;
        }
        if (!fi.IsDir())
        {
          errorCodes.Add((DWORD)E_FAIL);
          errorPaths.Add(fullPath);
          continue;
        }

        RINOK(EnumerateDirItems_Spec(nextNode, phyParent, logParent, fi.Name, phyPrefix,
            UStringVector(), dirItems, false, callback, errorPaths, errorCodes));
      }
      return S_OK;
    }
  }


  NFind::CEnumerator enumerator(phyPrefix + FCHAR_ANY_MASK);
  for (int ttt = 0; ; ttt++)
  {
    NFind::CFileInfo fi;
    bool found;
    if (!enumerator.Next(fi, found))
    {
      errorCodes.Add(::GetLastError());
      errorPaths.Add(phyPrefix);
      break;
    }
    if (!found)
      break;

    if (callback && (ttt & 0xFF) == 0xFF)
      RINOK(callback->ScanProgress(dirItems.GetNumFolders(), dirItems.Items.Size(), fs2us(phyPrefix)));
    const UString &name = fs2us(fi.Name);
    bool enterToSubFolders2 = enterToSubFolders;
    UStringVector addArchivePrefixNew = addArchivePrefix;
    addArchivePrefixNew.Add(name);
    {
      UStringVector addArchivePrefixNewTemp(addArchivePrefixNew);
      if (curNode.CheckPathToRoot(false, addArchivePrefixNewTemp, !fi.IsDir()))
        continue;
    }
    if (curNode.CheckPathToRoot(true, addArchivePrefixNew, !fi.IsDir()))
    {
      AddDirFileInfo(phyParent, logParent, fi, dirItems.Items);
      if (fi.IsDir())
        enterToSubFolders2 = true;
    }
    if (!fi.IsDir())
      continue;

    const NWildcard::CCensorNode *nextNode = 0;
    if (addArchivePrefix.IsEmpty())
    {
      int index = curNode.FindSubNode(name);
      if (index >= 0)
        nextNode = &curNode.SubNodes[index];
    }
    if (!enterToSubFolders2 && nextNode == 0)
      continue;

    addArchivePrefixNew = addArchivePrefix;
    if (nextNode == 0)
    {
      nextNode = &curNode;
      addArchivePrefixNew.Add(name);
    }

    RINOK(EnumerateDirItems_Spec(*nextNode, phyParent, logParent, fi.Name, phyPrefix,
        addArchivePrefixNew, dirItems, enterToSubFolders2, callback, errorPaths, errorCodes));
  }
  return S_OK;
}
Example #7
0
DWORD CDirEnumerator::GetNextFile(NFind::CFileInfo &fi, bool &filled, FString &resPath)
{
  filled = false;
  resPath.Empty();

  for (;;)
  {
    #if defined(_WIN32) && !defined(UNDER_CE)
    bool isRootPrefix = (BasePrefix.IsEmpty() || (NName::IsSuperPath(BasePrefix) && BasePrefix[NName::kSuperPathPrefixSize] == 0));
    #endif

    if (Enumerators.IsEmpty())
    {
      if (Index >= FilePaths.Size())
        return S_OK;
      const FString &path = FilePaths[Index++];
      int pos = path.ReverseFind_PathSepar();
      if (pos >= 0)
        resPath.SetFrom(path, pos + 1);

      #if defined(_WIN32) && !defined(UNDER_CE)
      if (isRootPrefix && path.Len() == 2 && NName::IsDrivePath2(path))
      {
        // we use "c:" item as directory item
        fi.ClearBase();
        fi.Name = path;
        fi.SetAsDir();
        fi.Size = 0;
      }
      else
      #endif
      if (!fi.Find(BasePrefix + path))
      {
        DWORD error = GetNormalizedError();
        resPath = path;
        return error;
      }

      break;
    }

    bool found;

    if (Enumerators.Back().Next(fi, found))
    {
      if (found)
      {
        resPath = Prefixes.Back();
        break;
      }
    }
    else
    {
      DWORD error = GetNormalizedError();
      resPath = Prefixes.Back();
      Enumerators.DeleteBack();
      Prefixes.DeleteBack();
      return error;
    }

    Enumerators.DeleteBack();
    Prefixes.DeleteBack();
  }

  resPath += fi.Name;

  if (EnterToDirs && fi.IsDir())
  {
    FString s = resPath;
    s.Add_PathSepar();
    Prefixes.Add(s);
    s += FCHAR_ANY_MASK;
    Enumerators.Add(NFind::CEnumerator(BasePrefix + s));
  }
  filled = true;
  return S_OK;
}
Example #8
0
void CDirEnumerator::Init()
{
  Enumerators.Clear();
  Prefixes.Clear();
  Index = 0;
}
Example #9
0
DWORD CDirEnumerator::GetNextFile(NFind::CFileInfo &fi, bool &filled, FString &resPath)
{
  filled = false;
  resPath.Empty();
  for (;;)
  {
    if (Enumerators.IsEmpty())
    {
      if (Index >= FilePaths.Size())
        return S_OK;
      const FString &path = FilePaths[Index++];
      int pos = path.ReverseFind(FCHAR_PATH_SEPARATOR);
      if (pos >= 0)
        resPath.SetFrom(path, pos + 1);

      #ifdef _WIN32
      if (BasePrefix.IsEmpty() && path.Len() == 2 && path[1] == ':')
      {
        // we use "c:" item as directory item
        fi.Clear();
        fi.Name = path;
        fi.SetAsDir();
        fi.Size = 0;
      }
      else
      #endif
      if (!fi.Find(BasePrefix + path))
      {
        DWORD error = GetNormalizedError();
        resPath = path;
        return error;
      }
      break;
    }
    bool found;
    if (Enumerators.Back().Next(fi, found))
    {
      if (found)
      {
        resPath = Prefixes.Back();
        break;
      }
    }
    else
    {
      DWORD error = GetNormalizedError();
      resPath = Prefixes.Back();
      Enumerators.DeleteBack();
      Prefixes.DeleteBack();
      return error;
    }
    Enumerators.DeleteBack();
    Prefixes.DeleteBack();
  }
  resPath += fi.Name;
  if (EnterToDirs && fi.IsDir())
  {
    FString s = resPath;
    s += FCHAR_PATH_SEPARATOR;
    Prefixes.Add(s);
    s += FCHAR_ANY_MASK;
    Enumerators.Add(NFind::CEnumerator(BasePrefix + s));
  }
  filled = true;
  return S_OK;
}
Example #10
0
HRESULT CAgentFolder::CommonUpdateOperation(
    AGENT_OP operation,
    bool moveMode,
    const wchar_t *newItemName,
    const NUpdateArchive::CActionSet *actionSet,
    const UInt32 *indices, UInt32 numItems,
    IProgress *progress)
{
  if (!_agentSpec->CanUpdate())
    return E_NOTIMPL;

  CMyComPtr<IFolderArchiveUpdateCallback> updateCallback100;
  if (progress)
    progress->QueryInterface(IID_IFolderArchiveUpdateCallback, (void **)&updateCallback100);

  try
  {

  RINOK(_agentSpec->SetFolder(this));

  // ---------- Save FolderItem ----------

  UStringVector pathParts;
  bool isAltStreamFolder = false;
  GetPathParts(pathParts, isAltStreamFolder);

  FStringVector requestedPaths;
  FStringVector processedPaths;

  CWorkDirTempFile tempFile;
  RINOK(tempFile.CreateTempFile(us2fs(_agentSpec->_archiveFilePath)));
  {
    CMyComPtr<IOutStream> tailStream;
    const CArc &arc = *_agentSpec->_archiveLink.GetArc();

    if (arc.ArcStreamOffset == 0)
      tailStream = tempFile.OutStream;
    else
    {
      if (arc.Offset < 0)
        return E_NOTIMPL;
      RINOK(arc.InStream->Seek(0, STREAM_SEEK_SET, NULL));
      RINOK(NCompress::CopyStream_ExactSize(arc.InStream, tempFile.OutStream, arc.ArcStreamOffset, NULL));
      CTailOutStream *tailStreamSpec = new CTailOutStream;
      tailStream = tailStreamSpec;
      tailStreamSpec->Stream = tempFile.OutStream;
      tailStreamSpec->Offset = arc.ArcStreamOffset;
      tailStreamSpec->Init();
    }
    
    HRESULT result;

    switch (operation)
    {
      case AGENT_OP_Delete:
        result = _agentSpec->DeleteItems(tailStream, indices, numItems, updateCallback100);
        break;
      case AGENT_OP_CreateFolder:
        result = _agentSpec->CreateFolder(tailStream, newItemName, updateCallback100);
        break;
      case AGENT_OP_Rename:
        result = _agentSpec->RenameItem(tailStream, indices, numItems, newItemName, updateCallback100);
        break;
      case AGENT_OP_Comment:
        result = _agentSpec->CommentItem(tailStream, indices, numItems, newItemName, updateCallback100);
        break;
      case AGENT_OP_CopyFromFile:
        result = _agentSpec->UpdateOneFile(tailStream, indices, numItems, newItemName, updateCallback100);
        break;
      case AGENT_OP_Uni:
        {
          Byte actionSetByte[NUpdateArchive::NPairState::kNumValues];
          for (int i = 0; i < NUpdateArchive::NPairState::kNumValues; i++)
            actionSetByte[i] = (Byte)actionSet->StateActions[i];
          result = _agentSpec->DoOperation2(
              moveMode ? &requestedPaths : NULL,
              moveMode ? &processedPaths : NULL,
              tailStream, actionSetByte, NULL, updateCallback100);
          break;
        }
      default:
        return E_FAIL;
    }
    
    RINOK(result);
  }

  _agentSpec->KeepModeForNextOpen();
  _agentSpec->Close();
  
  // before 9.26: if there was error for MoveToOriginal archive was closed.
  // now: we reopen archive after close

  // m_FolderItem = NULL;
  
  HRESULT res = tempFile.MoveToOriginal(true);

  // RINOK(res);
  if (res == S_OK)
  {
    if (moveMode)
    {
      unsigned i;
      for (i = 0; i < processedPaths.Size(); i++)
      {
        DeleteFileAlways(processedPaths[i]);
      }
      for (i = 0; i < requestedPaths.Size(); i++)
      {
        const FString &fs = requestedPaths[i];
        if (NFind::DoesDirExist(fs))
          DeleteEmptyFolderAndEmptySubFolders(fs);
      }
    }
  }

  {
    CMyComPtr<IArchiveOpenCallback> openCallback;
    if (updateCallback100)
      updateCallback100->QueryInterface(IID_IArchiveOpenCallback, (void **)&openCallback);
    RINOK(_agentSpec->ReOpen(openCallback));
  }
   
  // CAgent::ReOpen() deletes _proxy and _proxy2
  _items.Clear();
  _proxy = NULL;
  _proxy2 = NULL;
  _proxyDirIndex = k_Proxy_RootDirIndex;
  _isAltStreamFolder = false;
  
  
  // ---------- Restore FolderItem ----------

  CMyComPtr<IFolderFolder> archiveFolder;
  RINOK(_agentSpec->BindToRootFolder(&archiveFolder));

  // CAgent::BindToRootFolder() changes _proxy and _proxy2
  _proxy = _agentSpec->_proxy;
  _proxy2 = _agentSpec->_proxy2;

  if (_proxy)
  {
    FOR_VECTOR (i, pathParts)
    {
      int next = _proxy->FindSubDir(_proxyDirIndex, pathParts[i]);
      if (next < 0)
        break;
      _proxyDirIndex = next;
    }
  }
  
  if (_proxy2)
  {
    if (pathParts.IsEmpty() && isAltStreamFolder)
    {
      _proxyDirIndex = k_Proxy2_AltRootDirIndex;
    }
    else FOR_VECTOR (i, pathParts)
    {
      bool dirOnly = (i + 1 < pathParts.Size() || !isAltStreamFolder);
      int index = _proxy2->FindItem(_proxyDirIndex, pathParts[i], dirOnly);
      if (index < 0)
        break;
      
      const CProxyFile2 &file = _proxy2->Files[_proxy2->Dirs[_proxyDirIndex].Items[index]];
  
      if (dirOnly)
        _proxyDirIndex = file.DirIndex;
      else
      {
        if (file.AltDirIndex >= 0)
          _proxyDirIndex = file.AltDirIndex;
        break;
      }
    }
  }