Beispiel #1
0
static const char *ParseMapWithPaths(
    NWildcard::CCensor &censor,
    const UString &s2, bool include,
    NRecursedType::EEnum commonRecursedType,
    bool wildcardMatching)
{
  UString s = s2;
  int pos = s.Find(L':');
  if (pos < 0)
    return k_IncorrectMapCommand;
  int pos2 = s.Find(L':', pos + 1);
  if (pos2 < 0)
    return k_IncorrectMapCommand;

  CEventSetEnd eventSetEnd((const wchar_t *)s + ((unsigned)pos2 + 1));
  s.DeleteFrom(pos2);
  UInt32 size;
  if (!StringToUInt32(s.Ptr(pos + 1), size)
      || size < sizeof(wchar_t)
      || size > ((UInt32)1 << 31)
      || size % sizeof(wchar_t) != 0)
    return "Unsupported Map data size";

  s.DeleteFrom(pos);
  CFileMapping map;
  if (map.Open(FILE_MAP_READ, GetSystemString(s)) != 0)
    return "Can not open mapping";
  LPVOID data = map.Map(FILE_MAP_READ, 0, size);
  if (!data)
    return "MapViewOfFile error";
  CFileUnmapper unmapper(data);

  UString name;
  const wchar_t *p = (const wchar_t *)data;
  if (*p != 0) // data format marker
    return "Unsupported Map data";
  UInt32 numChars = size / sizeof(wchar_t);
  for (UInt32 i = 1; i < numChars; i++)
  {
    wchar_t c = p[i];
    if (c == 0)
    {
      // MessageBoxW(0, name, L"7-Zip", 0);
      AddNameToCensor(censor, name, include, commonRecursedType, wildcardMatching);
      name.Empty();
    }
    else
      name += c;
  }
  if (!name.IsEmpty())
    return "Map data error";

  return NULL;
}
Beispiel #2
0
UString CContentsView::GetDriveOrNetworkPrefix() const
{
  if (!IsFSFolder())
    return UString();
  UString drive = GetFsPath();
  drive.DeleteFrom(NFile::NName::GetRootPrefixSize(drive));
  return drive;
}
Beispiel #3
0
static UString GetSubFolderNameForExtract(const UString &arcPath)
{
  UString s = arcPath;
  int slashPos = s.ReverseFind_PathSepar();
  int dotPos = s.ReverseFind_Dot();
  if (dotPos <= slashPos + 1)
    s += L'~';
  else
  {
    s.DeleteFrom(dotPos);
    s.TrimRight();
  }
  return s;
}
Beispiel #4
0
// reduces path to part that exists on disk (or root prefix of path)
// output path is normalized (with WCHAR_PATH_SEPARATOR)
static void ReducePathToRealFileSystemPath(UString &path)
{
  unsigned prefixSize = GetRootPrefixSize(path);

  while (!path.IsEmpty())
  {
    if (NFind::DoesDirExist(us2fs(path)))
    {
      NName::NormalizeDirPathPrefix(path);
      break;
    }
    int pos = path.ReverseFind_PathSepar();
    if (pos < 0)
    {
      path.Empty();
      break;
    }
    path.DeleteFrom(pos + 1);
    if ((unsigned)pos + 1 == prefixSize)
      break;
    path.DeleteFrom(pos);
  }
}
Beispiel #5
0
HRESULT COneMethodInfo::ParseMethodFromString(const UString &s)
{
  MethodName.Empty();
  int splitPos = s.Find(L':');
  {
    UString temp = s;
    if (splitPos >= 0)
      temp.DeleteFrom(splitPos);
    if (!temp.IsAscii())
      return E_INVALIDARG;
    MethodName.SetFromWStr_if_Ascii(temp);
  }
  if (splitPos < 0)
    return S_OK;
  PropsString = s.Ptr(splitPos + 1);
  return ParseParamsFromString(PropsString);
}
Beispiel #6
0
UString GetSubFolderNameForExtract(const UString &arcName)
{
  int dotPos = arcName.ReverseFind_Dot();
  if (dotPos < 0)
    return Get_Correct_FsFile_Name(arcName) + L'~';

  const UString ext = arcName.Ptr(dotPos + 1);
  UString res = arcName.Left(dotPos);
  res.TrimRight();
  dotPos = res.ReverseFind_Dot();
  if (dotPos > 0)
  {
    const UString ext2 = res.Ptr(dotPos + 1);
    if (ext.IsEqualTo_Ascii_NoCase("001") && IsItArcExt(ext2)
        || ext.IsEqualTo_Ascii_NoCase("rar") &&
          (  ext2.IsEqualTo_Ascii_NoCase("part001")
          || ext2.IsEqualTo_Ascii_NoCase("part01")
          || ext2.IsEqualTo_Ascii_NoCase("part1")))
      res.DeleteFrom(dotPos);
    res.TrimRight();
  }
  return Get_Correct_FsFile_Name(res);
}
Beispiel #7
0
bool GetFullPath(CFSTR dirPrefix, CFSTR s, FString &res)
{
  res = s;

  #ifdef UNDER_CE

  if (s[0] != CHAR_PATH_SEPARATOR)
  {
    if (!dirPrefix)
      return false;
    res = dirPrefix;
    res += s;
  }

  #else

  unsigned prefixSize = GetRootPrefixSize(s);
  if (prefixSize != 0)
  {
    if (!AreThereDotsFolders(s + prefixSize))
      return true;
    
    UString rem = fs2us(s + prefixSize);
    if (!ResolveDotsFolders(rem))
      return true; // maybe false;
    res.DeleteFrom(prefixSize);
    res += us2fs(rem);
    return true;
  }

  /*
  FChar c = s[0];
  if (c == 0)
    return true;
  if (c == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0)))
    return true;
  if (c == CHAR_PATH_SEPARATOR && s[1] == CHAR_PATH_SEPARATOR)
    return true;
  if (IsDrivePath(s))
    return true;
  */

  UString curDir;
  if (dirPrefix)
    curDir = fs2us(dirPrefix);
  else
  {
    if (!GetCurDir(curDir))
      return false;
  }
  if (!curDir.IsEmpty() && curDir.Back() != WCHAR_PATH_SEPARATOR)
    curDir += WCHAR_PATH_SEPARATOR;

  unsigned fixedSize = 0;

    if (IsDrivePath(curDir))
      fixedSize = kDrivePrefixSize;
  
  UString temp;
  if (s[0] == CHAR_PATH_SEPARATOR)
  {
    temp = fs2us(s + 1);
  }
  else
  {
    temp += curDir.Ptr(fixedSize);
    temp += fs2us(s);
  }
  if (!ResolveDotsFolders(temp))
    return false;
  curDir.DeleteFrom(fixedSize);
  res = us2fs(curDir);
  res += us2fs(temp);
  
  #endif // UNDER_CE

  return true;
}
Beispiel #8
0
static bool GetSuperPathBase(CFSTR s, UString &res)
{
  res.Empty();
  
  FChar c = s[0];
  if (c == 0)
    return true;
  if (c == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0)))
    return true;
  
  if (IsSuperOrDevicePath(s))
  {
    #ifdef LONG_PATH_DOTS_FOLDERS_PARSING
    
    if ((s)[2] == '.')
      return true;

    // we will return true here, so we will try to use these problem paths.

    if (!AreThereDotsFolders(s + kSuperPathPrefixSize))
      return true;
    
    UString temp = fs2us(s);
    unsigned fixedSize = GetRootPrefixSize_Of_SuperPath(temp);
    if (fixedSize == 0)
      return true;

    UString rem = &temp[fixedSize];
    if (!ResolveDotsFolders(rem))
      return true;

    temp.DeleteFrom(fixedSize);
    res += temp;
    res += rem;
    
    #endif

    return true;
  }

  if (c == CHAR_PATH_SEPARATOR)
  {
    if (s[1] == CHAR_PATH_SEPARATOR)
    {
      UString temp = fs2us(s + 2);
      unsigned fixedSize = GetRootPrefixSize_Of_NetworkPath(temp);
      if (fixedSize == 0) // maybe we must ignore that error to allow short network paths?
        return false;
      UString rem = &temp[fixedSize];
      if (!ResolveDotsFolders(rem))
        return false;
      res += kSuperUncPrefix;
      temp.DeleteFrom(fixedSize);
      res += temp;
      res += rem;
      return true;
    }
  }
  else
  {
    if (IsDrivePath(s))
    {
      UString temp = fs2us(s);
      UString rem = &temp[kDrivePrefixSize];
      if (!ResolveDotsFolders(rem))
        return true;
      res += kSuperPathPrefix;
      temp.DeleteFrom(kDrivePrefixSize);
      res += temp;
      res += rem;
      return true;
    }
  }

  UString curDir;
  if (!GetCurDir(curDir))
    return false;
  if (curDir.Back() != WCHAR_PATH_SEPARATOR)
    curDir += WCHAR_PATH_SEPARATOR;

  unsigned fixedSizeStart = 0;
  unsigned fixedSize = 0;
  const wchar_t *superMarker = NULL;
  if (IsSuperPath(curDir))
  {
    fixedSize = GetRootPrefixSize_Of_SuperPath(curDir);
    if (fixedSize == 0)
      return false;
  }
  else
  {
    if (IsDrivePath(curDir))
    {
      superMarker = kSuperPathPrefix;
      fixedSize = kDrivePrefixSize;
    }
    else
    {
      if (curDir[0] != CHAR_PATH_SEPARATOR || curDir[1] != CHAR_PATH_SEPARATOR)
        return false;
      fixedSizeStart = 2;
      fixedSize = GetRootPrefixSize_Of_NetworkPath(&curDir[2]);
      if (fixedSize == 0)
        return false;
      superMarker = kSuperUncPrefix;
    }
  }
  
  UString temp;
  if (c == CHAR_PATH_SEPARATOR)
  {
    temp = fs2us(s + 1);
  }
  else
  {
    temp += &curDir[fixedSizeStart + fixedSize];
    temp += fs2us(s);
  }
  if (!ResolveDotsFolders(temp))
    return false;
  if (superMarker)
    res += superMarker;
  res += curDir.Mid(fixedSizeStart, fixedSize);
  res += temp;
  return true;
}
HRESULT CPanel::BindToPath(const UString &fullPath, const UString &arcFormat, bool &archiveIsOpened, bool &encrypted)
{
  UString path = fullPath;
  #ifdef _WIN32
  path.Replace(L'/', WCHAR_PATH_SEPARATOR);
  #endif

  archiveIsOpened = false;
  encrypted = false;
  
  CDisableTimerProcessing disableTimerProcessing(*this);
  CDisableNotify disableNotify(*this);

  for (; !_parentFolders.IsEmpty(); CloseOneLevel())
  {
    // ---------- we try to use open archive ----------

    const CFolderLink &link = _parentFolders.Back();
    const UString &virtPath = link.VirtualPath;
    if (!path.IsPrefixedBy(virtPath))
      continue;
    UString relatPath = path.Ptr(virtPath.Len());
    if (!relatPath.IsEmpty())
    {
      if (!IS_PATH_SEPAR(relatPath[0]))
        continue;
      else
        relatPath.Delete(0);
    }
    
    UString relatPath2 = relatPath;
    if (!relatPath2.IsEmpty() && !IS_PATH_SEPAR(relatPath2.Back()))
      relatPath2.Add_PathSepar();

    for (;;)
    {
      const UString foldPath = GetFolderPath(_folder);
      if (relatPath2 == foldPath)
        break;
      if (relatPath.IsPrefixedBy(foldPath))
      {
        path = relatPath.Ptr(foldPath.Len());
        break;
      }
      CMyComPtr<IFolderFolder> newFolder;
      if (_folder->BindToParentFolder(&newFolder) != S_OK)
        throw 20140918;
      if (!newFolder) // we exit from loop above if (relatPath.IsPrefixedBy(empty path for root folder)
        throw 20140918;
      SetNewFolder(newFolder);
    }
    break;
  }

  if (_parentFolders.IsEmpty())
  {
    // ---------- we open file or folder from file system ----------

    CloseOpenFolders();
    UString sysPath = path;
    
    unsigned prefixSize = NName::GetRootPrefixSize(sysPath);
    if (prefixSize == 0 || sysPath[prefixSize] == 0)
      sysPath.Empty();
    
    #if defined(_WIN32) && !defined(UNDER_CE)
    if (!sysPath.IsEmpty() && sysPath.Back() == ':' &&
      (sysPath.Len() != 2 || !NName::IsDrivePath2(sysPath)))
    {
      UString baseFile = sysPath;
      baseFile.DeleteBack();
      if (NFind::DoesFileOrDirExist(us2fs(baseFile)))
        sysPath.Empty();
    }
    #endif
    
    CFileInfo fileInfo;
    
    while (!sysPath.IsEmpty())
    {
      if (fileInfo.Find(us2fs(sysPath)))
        break;
      int pos = sysPath.ReverseFind_PathSepar();
      if (pos < 0)
        sysPath.Empty();
      else
      {
        /*
        if (reducedParts.Size() > 0 || pos < (int)sysPath.Len() - 1)
          reducedParts.Add(sysPath.Ptr(pos + 1));
        */
        #if defined(_WIN32) && !defined(UNDER_CE)
        if (pos == 2 && NName::IsDrivePath2(sysPath) && sysPath.Len() > 3)
          pos++;
        #endif

        sysPath.DeleteFrom(pos);
      }
    }
    
    SetToRootFolder();

    CMyComPtr<IFolderFolder> newFolder;
  
    if (sysPath.IsEmpty())
    {
      _folder->BindToFolder(path, &newFolder);
    }
    else if (fileInfo.IsDir())
    {
      NName::NormalizeDirPathPrefix(sysPath);
      _folder->BindToFolder(sysPath, &newFolder);
    }
    else
    {
      FString dirPrefix, fileName;
      NDir::GetFullPathAndSplit(us2fs(sysPath), dirPrefix, fileName);
      HRESULT res;
      // = OpenAsArc(fs2us(fileName), arcFormat, encrypted);
      {
        CTempFileInfo tfi;
        tfi.RelPath = fs2us(fileName);
        tfi.FolderPath = dirPrefix;
        tfi.FilePath = us2fs(sysPath);
        res = OpenAsArc(NULL, tfi, sysPath, arcFormat, encrypted);
      }
      
      if (res == S_FALSE)
        _folder->BindToFolder(fs2us(dirPrefix), &newFolder);
      else
      {
        RINOK(res);
        archiveIsOpened = true;
        _parentFolders.Back().ParentFolderPath = fs2us(dirPrefix);
        path.DeleteFrontal(sysPath.Len());
        if (!path.IsEmpty() && IS_PATH_SEPAR(path[0]))
          path.Delete(0);
      }
    }
    
    if (newFolder)
    {
      SetNewFolder(newFolder);
      // LoadFullPath();
      return S_OK;
    }
  }
  
  {
    // ---------- we open folder remPath in archive and sub archives ----------

    for (unsigned curPos = 0; curPos != path.Len();)
    {
      UString s = path.Ptr(curPos);
      int slashPos = NName::FindSepar(s);
      unsigned skipLen = s.Len();
      if (slashPos >= 0)
      {
        s.DeleteFrom(slashPos);
        skipLen = slashPos + 1;
      }

      CMyComPtr<IFolderFolder> newFolder;
      _folder->BindToFolder(s, &newFolder);
      if (newFolder)
        curPos += skipLen;
      else if (_folderAltStreams)
      {
        int pos = s.Find(L':');
        if (pos >= 0)
        {
          UString baseName = s;
          baseName.DeleteFrom(pos);
          if (_folderAltStreams->BindToAltStreams(baseName, &newFolder) == S_OK && newFolder)
            curPos += pos + 1;
        }
      }
      
      if (!newFolder)
        break;

      SetNewFolder(newFolder);
    }
  }

  return S_OK;
}
void CPanel::OpenParentFolder()
{
  LoadFullPath(); // Maybe we don't need it ??
  
  UString parentFolderPrefix;
  UString focusedName;
  
  if (!_currentFolderPrefix.IsEmpty())
  {
    wchar_t c = _currentFolderPrefix.Back();
    if (c == WCHAR_PATH_SEPARATOR || c == ':')
    {
      focusedName = _currentFolderPrefix;
      focusedName.DeleteBack();
      /*
      if (c == ':' && !focusedName.IsEmpty() && focusedName.Back() == WCHAR_PATH_SEPARATOR)
      {
        focusedName.DeleteBack();
      }
      else
      */
      if (focusedName != L"\\\\." &&
          focusedName != L"\\\\?")
      {
        int pos = focusedName.ReverseFind_PathSepar();
        if (pos >= 0)
        {
          parentFolderPrefix = focusedName;
          parentFolderPrefix.DeleteFrom(pos + 1);
          focusedName.DeleteFrontal(pos + 1);
        }
      }
    }
  }

  CDisableTimerProcessing disableTimerProcessing(*this);
  CDisableNotify disableNotify(*this);
  
  CMyComPtr<IFolderFolder> newFolder;
  _folder->BindToParentFolder(&newFolder);

  // newFolder.Release(); // for test
  
  if (newFolder)
    SetNewFolder(newFolder);
  else
  {
    bool needSetFolder = true;
    if (!_parentFolders.IsEmpty())
    {
      {
        const CFolderLink &link = _parentFolders.Back();
        parentFolderPrefix = link.ParentFolderPath;
        focusedName = link.RelPath;
      }
      CloseOneLevel();
      needSetFolder = (!_folder);
    }
    
    if (needSetFolder)
    {
      {
        bool archiveIsOpened;
        bool encrypted;
        BindToPath(parentFolderPrefix, UString(), archiveIsOpened, encrypted);
      }
    }
  }
    
  UStringVector selectedItems;
  /*
  if (!focusedName.IsEmpty())
    selectedItems.Add(focusedName);
  */
  LoadFullPath();
  // ::SetCurrentDirectory(::_currentFolderPrefix);
  RefreshListCtrl(focusedName, -1, true, selectedItems);
  // _listView.EnsureVisible(_listView.GetFocusedItem(), false);
}
Beispiel #11
0
HRESULT CPanel::BindToPath(const UString &fullPath, const UString &arcFormat, bool &archiveIsOpened, bool &encrypted)
{
  archiveIsOpened = false;
  encrypted = false;
  CDisableTimerProcessing disableTimerProcessing(*this);
  CDisableNotify disableNotify(*this);

  if (_parentFolders.Size() > 0)
  {
    const UString &virtPath = _parentFolders.Back().VirtualPath;
    if (fullPath.IsPrefixedBy(virtPath))
    {
      for (;;)
      {
        CMyComPtr<IFolderFolder> newFolder;
        HRESULT res = _folder->BindToParentFolder(&newFolder);
        if (!newFolder || res != S_OK)
          break;
        SetNewFolder(newFolder);
      }
      UStringVector parts;
      SplitPathToParts(fullPath.Ptr(virtPath.Len()), parts);
      FOR_VECTOR (i, parts)
      {
        const UString &s = parts[i];
        if ((i == 0 || i == parts.Size() - 1) && s.IsEmpty())
          continue;
        CMyComPtr<IFolderFolder> newFolder;
        HRESULT res = _folder->BindToFolder(s, &newFolder);
        if (!newFolder || res != S_OK)
          break;
        SetNewFolder(newFolder);
      }
      return S_OK;
    }
  }

  CloseOpenFolders();
  UString sysPath = fullPath;
  CFileInfo fileInfo;
  UStringVector reducedParts;
  while (!sysPath.IsEmpty())
  {
    if (fileInfo.Find(us2fs(sysPath)))
      break;
    int pos = sysPath.ReverseFind(WCHAR_PATH_SEPARATOR);
    if (pos < 0)
      sysPath.Empty();
    else
    {
      if (reducedParts.Size() > 0 || pos < (int)sysPath.Len() - 1)
        reducedParts.Add(sysPath.Ptr(pos + 1));
      sysPath.DeleteFrom(pos);
    }
  }
  SetToRootFolder();
  CMyComPtr<IFolderFolder> newFolder;
  if (sysPath.IsEmpty())
  {
    if (_folder->BindToFolder(fullPath, &newFolder) == S_OK)
      SetNewFolder(newFolder);
  }
  else if (fileInfo.IsDir())
  {
    NName::NormalizeDirPathPrefix(sysPath);
    if (_folder->BindToFolder(sysPath, &newFolder) == S_OK)
      SetNewFolder(newFolder);
  }
  else
  {
    FString dirPrefix, fileName;
    NDir::GetFullPathAndSplit(us2fs(sysPath), dirPrefix, fileName);
    if (_folder->BindToFolder(fs2us(dirPrefix), &newFolder) == S_OK)
    {
      SetNewFolder(newFolder);
      LoadFullPath();
      {
        HRESULT res = OpenItemAsArchive(fs2us(fileName), arcFormat, encrypted);
        if (res != S_FALSE)
        {
          RINOK(res);
        }
        /*
        if (res == E_ABORT)
          return res;
        */
        if (res == S_OK)
        {
          archiveIsOpened = true;
          for (int i = reducedParts.Size() - 1; i >= 0; i--)
          {
            CMyComPtr<IFolderFolder> newFolder;
            _folder->BindToFolder(reducedParts[i], &newFolder);
            if (!newFolder)
              break;
            SetNewFolder(newFolder);
          }
        }
      }
    }
  }
  return S_OK;
}
Beispiel #12
0
STDMETHODIMP CFSFolder::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
  NCOM::CPropVariant prop;
  /*
  if (index >= (UInt32)Files.Size())
  {
    CAltStream &ss = Streams[index - Files.Size()];
    CDirItem &fi = Files[ss.Parent];
    switch (propID)
    {
      case kpidIsDir: prop = false; break;
      case kpidIsAltStream: prop = true; break;
      case kpidName: prop = fs2us(fi.Name) + ss.Name; break;
      case kpidSize: prop = ss.Size; break;
      case kpidPackSize:
        #ifdef UNDER_CE
        prop = ss.Size;
        #else
        if (!ss.PackSize_Defined)
        {
          ss.PackSize_Defined = true;
          if (!MyGetCompressedFileSizeW(_path + GetRelPath(fi) + us2fs(ss.Name), ss.PackSize))
            ss.PackSize = ss.Size;
        }
        prop = ss.PackSize;
        #endif
        break;
      case kpidComment: break;
      default: index = ss.Parent;
    }
    if (index >= (UInt32)Files.Size())
    {
      prop.Detach(value);
      return S_OK;
    }
  }
  */
  CDirItem &fi = Files[index];
  switch (propID)
  {
    case kpidIsDir: prop = fi.IsDir(); break;
    case kpidIsAltStream: prop = false; break;
    case kpidName: prop = fs2us(fi.Name); break;
    case kpidSize: if (!fi.IsDir() || fi.FolderStat_Defined) prop = fi.Size; break;
    case kpidPackSize:
      #ifdef UNDER_CE
      prop = fi.Size;
      #else
      if (!fi.PackSize_Defined)
      {
        fi.PackSize_Defined = true;
        if (fi.IsDir () || !MyGetCompressedFileSizeW(_path + GetRelPath(fi), fi.PackSize))
          fi.PackSize = fi.Size;
      }
      prop = fi.PackSize;
      #endif
      break;

    #ifdef FS_SHOW_LINKS_INFO

    case kpidLinks:
      #ifdef UNDER_CE
      // prop = fi.NumLinks;
      #else
      if (!fi.FileInfo_WasRequested)
        ReadFileInfo(fi);
      if (fi.FileInfo_Defined)
        prop = fi.NumLinks;
      #endif
      break;
    
    case kpidINode:
      #ifdef UNDER_CE
      // prop = fi.FileIndex;
      #else
      if (!fi.FileInfo_WasRequested)
        ReadFileInfo(fi);
      if (fi.FileInfo_Defined)
        prop = fi.FileIndex;
      #endif
      break;
    
    #endif

    case kpidAttrib: prop = (UInt32)fi.Attrib; break;
    case kpidCTime: prop = fi.CTime; break;
    case kpidATime: prop = fi.ATime; break;
    case kpidMTime: prop = fi.MTime; break;
    case kpidComment:
    {
      if (!_commentsAreLoaded)
        LoadComments();
      UString comment;
      if (_comments.GetValue(fs2us(GetRelPath(fi)), comment))
      {
        int pos = comment.Find((wchar_t)4);
        if (pos >= 0)
          comment.DeleteFrom(pos);
        prop = comment;
      }
      break;
    }
    case kpidPrefix:
      if (fi.Parent >= 0)
        prop = Folders[fi.Parent];
      break;
    case kpidNumSubDirs: if (fi.IsDir() && fi.FolderStat_Defined) prop = fi.NumFolders; break;
    case kpidNumSubFiles: if (fi.IsDir() && fi.FolderStat_Defined) prop = fi.NumFiles; break;
  }
  prop.Detach(value);
  return S_OK;
}
Beispiel #13
0
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
  COM_TRY_BEGIN
  NCOM::CPropVariant prop;
  if (index >= (UInt32)_archive.Refs.Size())
  {
    index -= _archive.Refs.Size();
    const CBootInitialEntry &be = _archive.BootEntries[index];
    switch (propID)
    {
      case kpidPath:
      {
        AString s = "[BOOT]" STRING_PATH_SEPARATOR;
        if (_archive.BootEntries.Size() != 1)
        {
          char temp[16];
          ConvertUInt32ToString(index + 1, temp);
          s += temp;
          s += '-';
        }
        s += be.GetName();
        prop = s;
        break;
      }
      case kpidIsDir: prop = false; break;
      case kpidSize:
      case kpidPackSize:
        prop = (UInt64)_archive.GetBootItemSize(index);
        break;
    }
  }
  else
  {
    const CRef &ref = _archive.Refs[index];
    const CDir &item = ref.Dir->_subItems[ref.Index];
    switch (propID)
    {
      case kpidPath:
        // if (item.FileId.GetCapacity() >= 0)
        {
          UString s;
          if (_archive.IsJoliet())
            item.GetPathU(s);
          else
            s = MultiByteToUnicodeString(item.GetPath(_archive.IsSusp, _archive.SuspSkipSize), CP_OEMCP);

          if (s.Len() >= 2 && s[s.Len() - 2] == ';' && s.Back() == '1')
            s.DeleteFrom(s.Len() - 2);
          
          if (!s.IsEmpty() && s.Back() == L'.')
            s.DeleteBack();

          NItemName::ConvertToOSName2(s);
          prop = s;
        }
        break;
      case kpidIsDir: prop = item.IsDir(); break;
      case kpidSize:
      case kpidPackSize:
        if (!item.IsDir())
          prop = (UInt64)ref.TotalSize;
        break;
      case kpidMTime:
      {
        FILETIME utc;
        if (item.DateTime.GetFileTime(utc))
          prop = utc;
        break;
      }
    }
  }
  prop.Detach(value);
  return S_OK;
  COM_TRY_END
}