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; }
UString CContentsView::GetDriveOrNetworkPrefix() const { if (!IsFSFolder()) return UString(); UString drive = GetFsPath(); drive.DeleteFrom(NFile::NName::GetRootPrefixSize(drive)); return drive; }
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; }
// 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); } }
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); }
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); }
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; }
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); }
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; }
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; }
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 }