// try to replace volume GUID (if present) with drive letter // used by ConvertNameToReal() only static string TryConvertVolumeGuidToDrivePath(string_view const Path, const string_view AbsPath = {}) { string Result(Path); size_t DirectoryOffset; if (ParsePath(Path, &DirectoryOffset) == root_type::volume) { if (imports.GetVolumePathNamesForVolumeNameW) { string VolumePathNames; if (os::fs::GetVolumePathNamesForVolumeName(ExtractPathRoot(Path), VolumePathNames)) { for(const auto& i: enum_substrings(VolumePathNames.c_str())) { if (!AbsPath.empty() && starts_with_icase(AbsPath, i)) return string(i); if (IsRootPath(i)) { Result.replace(0, DirectoryOffset, i.data(), i.size()); break; } } } if (!AbsPath.empty()) Result.clear(); } else if (!AbsPath.empty()) Result.clear(); else { string strVolumeGuid; const os::fs::enum_drives Enumerator(os::fs::get_logical_drives()); const auto ItemIterator = std::find_if(ALL_CONST_RANGE(Enumerator), [&](const auto& i) { return os::fs::GetVolumeNameForVolumeMountPoint(os::fs::get_root_directory(i), strVolumeGuid) && starts_with(Path, string_view(strVolumeGuid).substr(0, DirectoryOffset)); }); if (ItemIterator != Enumerator.cend()) { Result.replace(0, DirectoryOffset, os::fs::get_drive(*ItemIterator)); } } } else if (!AbsPath.empty()) Result.clear(); return Result; }
void Panel::InitCurDir(const string& CurDir) { if (!equal_icase(m_CurDir, CurDir) || !equal_icase(os::fs::GetCurrentDirectory(), CurDir)) { m_CurDir = CurDir; if (m_PanelMode != panel_mode::PLUGIN_PANEL) { PrepareDiskPath(m_CurDir); if(!IsRootPath(m_CurDir)) { DeleteEndSlash(m_CurDir); } } } }
/* Преобразует Src в полный РЕАЛЬНЫЙ путь с учетом reparse point. Note that Src can be partially non-existent. */ string ConvertNameToReal(string_view const Object) { SCOPED_ACTION(elevation::suppress); // Получим сначала полный путь до объекта обычным способом const auto FullPath = ConvertNameToFull(Object); auto strDest = FullPath; string Path = FullPath; os::fs::file File; for (;;) { if (File.Open(Path, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING)) break; if (IsRootPath(Path)) break; Path = ExtractFilePath(Path); } if (File) { string FinalFilePath; File.GetFinalPathName(FinalFilePath); File.Close(); //assert(!FinalFilePath.empty()); if (!FinalFilePath.empty()) { // append non-existent path part (if present) DeleteEndSlash(Path); if (FullPath.size() > Path.size() + 1) path::append(FinalFilePath, string_view(FullPath).substr(Path.size() + 1)); FinalFilePath = TryConvertVolumeGuidToDrivePath(FinalFilePath); strDest = FinalFilePath; } } return strDest; }
void UserMenu::ProcessUserMenu(bool ChoiceMenuType) { // Путь к текущему каталогу с файлом LocalMenuFileName string strMenuFilePath; CtrlObject->CmdLine->GetCurDir(strMenuFilePath); // по умолчанию меню - это FarMenu.ini MenuMode = MM_LOCAL; MenuModified = MenuNeedRefresh = false; if (ChoiceMenuType) { int EditChoice=Message(0,3,MSG(MUserMenuTitle),MSG(MChooseMenuType),MSG(MChooseMenuMain),MSG(MChooseMenuLocal),MSG(MCancel)); if (EditChoice<0 || EditChoice==2) return; if (!EditChoice) { MenuMode = MM_GLOBAL; strMenuFilePath = Opt.GlobalUserMenuDir; } } // основной цикл обработки bool FirstRun=true; int ExitCode = 0; while ((ExitCode != EC_CLOSE_LEVEL) && (ExitCode != EC_CLOSE_MENU) && (ExitCode != EC_COMMAND_SELECTED)) { string strMenuFileFullPath = strMenuFilePath; AddEndSlash(strMenuFileFullPath); strMenuFileFullPath += LocalMenuFileName; Menu.Clear(); // Пытаемся открыть файл на локальном диске File MenuFile; bool FileOpened = PathCanHoldRegularFile(strMenuFilePath) ? MenuFile.Open(strMenuFileFullPath,GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING) : false; if (FileOpened) { GetFileString GetStr(MenuFile); MenuFileToList(&Menu, MenuFile, GetStr); MenuFile.Close(); } else if (MenuMode != MM_USER) { // Файл не открылся. Смотрим дальше. if (MenuMode == MM_GLOBAL) // был в %FARHOME%? { MenuMode = MM_USER; strMenuFilePath = Opt.ProfilePath; continue; } else if (!ChoiceMenuType) { if (!FirstRun) { // подымаемся выше... if(!IsRootPath(strMenuFilePath)) { size_t pos; if (FindLastSlash(pos,strMenuFilePath)) { strMenuFilePath.SetLength(pos--); continue; } } } FirstRun = false; MenuMode = MM_GLOBAL; strMenuFilePath = Opt.GlobalUserMenuDir; continue; } } int PrevMacroMode=CtrlObject->Macro.GetMode(); int _CurrentFrame=FrameManager->GetCurrentFrame()->GetType(); CtrlObject->Macro.SetMode(MACRO_USERMENU); // вызываем меню ExitCode=ProcessSingleMenu(&Menu, 0, &Menu, strMenuFileFullPath); if (_CurrentFrame == FrameManager->GetCurrentFrame()->GetType()) //??? CtrlObject->Macro.SetMode(PrevMacroMode); // ...запишем изменения обратно в файл SaveMenu(strMenuFileFullPath); // что было после вызова меню? switch (ExitCode) { // Показать меню родительского каталога case EC_PARENT_MENU: { if (MenuMode == MM_LOCAL) { if(!IsRootPath(strMenuFilePath)) { size_t pos; if (FindLastSlash(pos,strMenuFilePath)) { strMenuFilePath.SetLength(pos--); continue; } } MenuMode = MM_GLOBAL; strMenuFilePath = Opt.GlobalUserMenuDir; } else { MenuMode = MM_USER; strMenuFilePath = Opt.ProfilePath; } break; } // Показать главное меню case EC_MAIN_MENU: { // $ 14.07.2000 VVM: Shift+F2 переключает Главное меню/локальное в цикле switch (MenuMode) { case MM_LOCAL: MenuMode = MM_GLOBAL; strMenuFilePath = Opt.GlobalUserMenuDir; break; case MM_GLOBAL: MenuMode = MM_USER; strMenuFilePath = Opt.ProfilePath; break; default: // MM_USER CtrlObject->CmdLine->GetCurDir(strMenuFilePath); MenuMode=MM_LOCAL; } break; } } } if (FrameManager->IsPanelsActive() && (ExitCode == EC_COMMAND_SELECTED || MenuModified)) ShellUpdatePanels(CtrlObject->Cp()->ActivePanel,FALSE); }
assert(ExtractFileName(L"path\\") == L""); assert(ExtractFileName(L"path\\file") == L"file"); assert(ExtractFileName(L"C:") == L""); assert(ExtractFileName(L"C:\\") == L""); assert(ExtractFileName(L"C:\\file") == L"file"); assert(ExtractFileName(L"C:\\path\\file") == L"file"); assert(ExtractFileName(L"\\\\?\\Volume{01e45c83-9ce4-11db-b27f-806d6172696f}") == L""); assert(ExtractFileName(L"\\\\?\\Volume{01e45c83-9ce4-11db-b27f-806d6172696f}\\") == L""); assert(ExtractFileName(L"\\\\?\\Volume{01e45c83-9ce4-11db-b27f-806d6172696f}\\file") == L"file"); assert(ExtractFileName(L"\\\\?\\Volume{01e45c83-9ce4-11db-b27f-806d6172696f}\\path\\file") == L"file"); assert(ExtractFileName(L"\\\\server\\share") == L""); assert(ExtractFileName(L"\\\\server\\share\\") == L""); assert(ExtractFileName(L"\\\\server\\share\\file") == L"file"); assert(ExtractFileName(L"\\\\server\\share\\path\\file") == L"file"); assert(ExtractFileName(L"\\\\?\\UNC\\server\\share") == L""); assert(ExtractFileName(L"\\\\?\\UNC\\server\\share\\") == L""); assert(ExtractFileName(L"\\\\?\\UNC\\server\\share\\file") == L"file"); assert(ExtractFileName(L"\\\\?\\UNC\\server\\share\\path\\file") == L"file"); assert(IsRootPath(L"C:")); assert(IsRootPath(L"C:\\")); assert(IsRootPath(L"\\")); assert(!IsRootPath(L"C:\\path")); assert(PathStartsWith(L"C:\\path\\file", L"C:\\path")); assert(PathStartsWith(L"C:\\path\\file", L"C:\\path\\")); assert(!PathStartsWith(L"C:\\path\\file", L"C:\\pat")); assert(PathStartsWith(L"\\", L"")); assert(!PathStartsWith(L"C:\\path\\file", L"")); )