string ConvertNameToUNC(string_view const Object) { auto strFileName = ConvertNameToFull(Object); // Посмотрим на тип файловой системы string strFileSystemName; os::fs::GetVolumeInformation(GetPathRoot(strFileName), nullptr, nullptr, nullptr, nullptr, &strFileSystemName); DWORD uniSize = 1024; block_ptr<UNIVERSAL_NAME_INFO> uni(uniSize); // применяем WNetGetUniversalName для чего угодно, только не для Novell`а if (!equal_icase(strFileSystemName, L"NWFS"sv)) { switch (WNetGetUniversalName(strFileName.c_str(), UNIVERSAL_NAME_INFO_LEVEL, uni.get(), &uniSize)) { case NO_ERROR: strFileName = uni->lpUniversalName; break; case ERROR_MORE_DATA: uni.reset(uniSize); if (WNetGetUniversalName(strFileName.c_str(),UNIVERSAL_NAME_INFO_LEVEL,uni.get(),&uniSize)==NO_ERROR) strFileName = uni->lpUniversalName; break; } } else if (strFileName.size() > 1 && strFileName[1] == L':') { // BugZ#449 - Неверная работа CtrlAltF с ресурсами Novell DS // Здесь, если не получилось получить UniversalName и если это // мапленный диск - получаем как для меню выбора дисков string strTemp; if (DriveLocalToRemoteName(DRIVE_UNKNOWN,strFileName[0],strTemp)) { const auto SlashPos = FindSlash(strFileName); if (SlashPos != string::npos) path::append(strTemp, string_view(strFileName).substr(SlashPos + 1)); strFileName = strTemp; } } return ConvertNameToReal(strFileName); }
void ConnectToNetworkDrive(const string& NewDir) { string strRemoteName; DriveLocalToRemoteName(DRIVE_REMOTE_NOT_CONNECTED,NewDir[0],strRemoteName); string strUserName, strPassword; GetStoredUserName(NewDir[0], strUserName); NETRESOURCE netResource; netResource.dwType = RESOURCETYPE_DISK; netResource.lpLocalName = UNSAFE_CSTR(NewDir); netResource.lpRemoteName = UNSAFE_CSTR(strRemoteName); netResource.lpProvider = 0; DWORD res = WNetAddConnection2(&netResource, nullptr, EmptyToNull(strUserName.data()), 0); if (res == ERROR_SESSION_CREDENTIAL_CONFLICT) res = WNetAddConnection2(&netResource, nullptr, nullptr, 0); if (res) { for (;;) { if (!GetNameAndPassword(strRemoteName, strUserName, strPassword, nullptr, GNP_USELAST)) break; res = WNetAddConnection2(&netResource, strPassword.data(), EmptyToNull(strUserName.data()), 0); if (!res) break; Global->CatchError(); if (res != ERROR_ACCESS_DENIED && res != ERROR_INVALID_PASSWORD && res != ERROR_LOGON_FAILURE) { Message(MSG_WARNING, 1, MSG(MError), GetErrorString().data(), MSG(MOk)); break; } } } }
std::list<CommandLine::segment> CommandLine::GetPrompt() { FN_RETURN_TYPE(CommandLine::GetPrompt) Result; int NewPromptSize = DEFAULT_CMDLINE_WIDTH; const auto& PrefixColor = colors::PaletteColorToFarColor(COL_COMMANDLINEPREFIX); if (Global->Opt->CmdLine.UsePromptFormat) { const string_view Format = Global->Opt->CmdLine.strPromptFormat.Get(); auto Tail = Format.cbegin(); auto Color = PrefixColor; FOR_CONST_RANGE(Format, Iterator) { bool Stop; auto NewColor = PrefixColor; const auto NextIterator = colors::ExtractColorInNewFormat(Iterator, Format.cend(), NewColor, Stop); if (NextIterator == Iterator) { if (Stop) break; continue; } if (Iterator != Format.cbegin()) { Result.emplace_back(segment{ string(Tail, Iterator), Color }); } Iterator = NextIterator; Tail = Iterator; Color = NewColor; } Result.emplace_back(segment{ string(Tail, Format.cend()), Color }); for (auto Iterator = Result.begin(); Iterator != Result.end(); ++Iterator) { const auto strExpandedDestStr = os::env::expand(Iterator->Text); Iterator->Text.clear(); static const std::pair<wchar_t, wchar_t> ChrFmt[] = { {L'A', L'&'}, // $A - & (Ampersand) {L'B', L'|'}, // $B - | (pipe) {L'C', L'('}, // $C - ( (Left parenthesis) {L'F', L')'}, // $F - ) (Right parenthesis) {L'G', L'>'}, // $G - > (greater-than sign) {L'L', L'<'}, // $L - < (less-than sign) {L'Q', L'='}, // $Q - = (equal sign) {L'S', L' '}, // $S - (space) {L'$', L'$'}, // $$ - $ (dollar sign) }; FOR_CONST_RANGE(strExpandedDestStr, it) { auto& strDestStr = Iterator->Text; if (*it == L'$' && it + 1 != strExpandedDestStr.cend()) { const auto Chr = upper(*++it); const auto ItemIterator = std::find_if(CONST_RANGE(ChrFmt, Item) { return Item.first == Chr; }); if (ItemIterator != std::cend(ChrFmt)) { strDestStr += ItemIterator->second; } else { const auto& AddCollapsible = [&](string&& Str) { if (strDestStr.empty()) { strDestStr = std::move(Str); Iterator->Collapsible = true; } else { Iterator = Result.insert(std::next(Iterator), segment{ std::move(Str), Iterator->Colour, true }); } // No need to introduce a new segment if we're at the very end if (std::next(Iterator) != Result.end() && std::next(it) != strExpandedDestStr.cend()) { Iterator = Result.insert(std::next(Iterator), segment{ {}, Iterator->Colour, false }); } }; switch (Chr) { /* эти не реaлизованы $E - Escape code (ASCII code 27) $V - Windows version number $_ - Carriage return and linefeed */ case L'M': // $M - Отображение полного имени удаленного диска, связанного с именем текущего диска, или пустой строки, если текущий диск не является сетевым. { string strTemp; if (DriveLocalToRemoteName(DRIVE_UNKNOWN, m_CurDir[0], strTemp)) { AddCollapsible(std::move(strTemp)); } break; } case L'+': // $+ - Отображение нужного числа знаков плюс (+) в зависимости от текущей глубины стека каталогов PUSHD, по одному знаку на каждый сохраненный путь. { strDestStr.append(ppstack.size(), L'+'); break; } case L'H': // $H - Backspace (erases previous character) { if (!strDestStr.empty()) { strDestStr.pop_back(); } else { auto Prev = Iterator; while (Prev != Result.begin()) { --Prev; if (!Prev->Text.empty()) { Prev->Text.pop_back(); break; } } } break; } case L'@': // $@xx - Admin { if (it + 1 != strExpandedDestStr.cend()) { const auto lb = *++it; if (it + 1 != strExpandedDestStr.cend()) { const auto rb = *++it; if (os::security::is_admin()) { append(strDestStr, lb, msg(lng::MConfigCmdlinePromptFormatAdmin), rb); } } } break; } case L'D': // $D - Current date case L'T': // $T - Current time { strDestStr += MkStrFTime(Chr == L'D'? L"%D" : L"%T"); break; } case L'N': // $N - Current drive { const auto Type = ParsePath(m_CurDir); if(Type == root_type::drive_letter) strDestStr += upper(m_CurDir[0]); else if(Type == root_type::unc_drive_letter) strDestStr += upper(m_CurDir[4]); else strDestStr += L'?'; break; } case L'W': // $W - Текущий рабочий каталог (без указания пути) { const auto pos = FindLastSlash(m_CurDir); if (pos != string::npos) { AddCollapsible(m_CurDir.substr(pos + 1)); } break; } case L'P': // $P - Current drive and path { AddCollapsible(string{ m_CurDir }); break; } case L'#': //$#nn - max prompt width in % { if (it + 1 != strExpandedDestStr.end()) { size_t pos; if (from_string(string(it + 1, strExpandedDestStr.cend()), NewPromptSize, &pos)) it += pos; // else // bad format, NewPromptSize unchanged // TODO: diagnostics } } } if (it == strExpandedDestStr.cend()) { break; } } } else {