Skip to content

Commit

Permalink
gh-758: Show all reparse point tags in Attributes dialog
Browse files Browse the repository at this point in the history
  • Loading branch information
alabuzhev committed Dec 7, 2023
1 parent a699a8f commit 8545e07
Show file tree
Hide file tree
Showing 9 changed files with 143 additions and 93 deletions.
5 changes: 5 additions & 0 deletions far/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
--------------------------------------------------------------------------------
drkns 2023-12-07 19:52:27+00:00 - build 6222

1. gh-758: Show all reparse point tags in Attributes dialog.

--------------------------------------------------------------------------------
drkns 2023-11-30 17:25:47+00:00 - build 6221

Expand Down
52 changes: 26 additions & 26 deletions far/farlang.templ.m4
Original file line number Diff line number Diff line change
Expand Up @@ -16259,6 +16259,20 @@ l:
"Хуткі прагляд"
"Vaizdas"

MQuickViewReparsePoint
"Точка повторного анализа"
"&Reparse point"
"Reparse point"
"Analysepunkt"
upd:"Reparse point"
"Punkt &analizy"
"Punto de análisis"
"Reparse point"
"P&unto Di Reparse"
"Точка повторного аналізу"
"Кропка паўторнай апрацоўкі"
upd:"&Reparse point"

MQuickViewUnknownReparsePoint
"Неизвестная точка повторного анализа"
"Unknown reparse point"
Expand All @@ -16273,20 +16287,6 @@ upd:"Unknown reparse point"
"Невядомая кропка паўторнага аналізу"
upd:"Unknown reparse point"

MQuickViewNoData
"(нет данных)"
"(data not available)"
"(data nejsou k dispozici)"
"(nicht verfügbar)"
"(adat nem elérhető)"
"(dane niedostępne)"
"(dato no disponible)"
"(dáta nie sú k dispozícii)"
"(dati sconosciuti)"
"(нема даних)"
"(няма дадзеных)"
upd:"(data not available)"

MQuickViewFolders
"Папок:"
"Folders:"
Expand Down Expand Up @@ -16513,18 +16513,18 @@ MSetAttrAppExecLink
"Programos slapyvardis :"

MSetAttrUnknownReparsePoint
"(нет данных)"
"(data not available)"
"(data nejsou k dispozici)"
"(nicht verfügbar)"
"(adat nem elérhető)"
"(dane niedostępne)"
"(datos no disponibles)"
"(dáta nie sú k dispozícii)"
"(dati sconosciuti)"
"(нема даних)"
"(няма дадзеных)"
upd:"(data not available)"
"Неизвестная точка повторного анализа"
"Unknown reparse point"
upd:"Unknown reparse point"
"Unbekannter Analysepunkt"
upd:"Unknown reparse point"
"Nieznany punkt powiązania"
"Punto de análisis desconocido"
"Neznáme rozšírené informácie (ReparsePoint)"
"Punto Reparse Ignoto"
"Невідома точка повторного аналізу"
"Невядомая кропка паўторнага аналізу"
upd:"Unknown reparse point"

MSetAttrReadOnly
"&Только для чтения"
Expand Down
15 changes: 7 additions & 8 deletions far/flink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -695,13 +695,9 @@ static string_view reparse_tag_to_string(DWORD ReparseTag)
{
default: return {};

// Localised
case IO_REPARSE_TAG_MOUNT_POINT: return msg(lng::MListJunction);
case IO_REPARSE_TAG_SYMLINK: return msg(lng::MListSymlink);

// Generated
#define TAG_STR(name) case IO_REPARSE_TAG_##name: return WIDE_SV(#name);
// MS tags:
TAG_STR(MOUNT_POINT)
TAG_STR(HSM)
TAG_STR(DRIVE_EXTENDER)
TAG_STR(HSM2)
Expand All @@ -710,6 +706,7 @@ static string_view reparse_tag_to_string(DWORD ReparseTag)
TAG_STR(CSV)
TAG_STR(DFS)
TAG_STR(FILTER_MANAGER)
TAG_STR(SYMLINK)
TAG_STR(IIS_CACHE)
TAG_STR(DFSR)
TAG_STR(DEDUP)
Expand Down Expand Up @@ -853,14 +850,16 @@ static string_view reparse_tag_to_string(DWORD ReparseTag)
}
}

bool reparse_tag_to_string(DWORD ReparseTag, string& Str)
bool reparse_tag_to_string(DWORD ReparseTag, string& Str, bool const ShowUnknown)
{
Str = reparse_tag_to_string(ReparseTag);

if (!Str.empty())
return true;

Str = far::format(L":{:0>8X}"sv, ReparseTag);
if (ShowUnknown)
Str = far::format(L":{:0>8X}"sv, ReparseTag);

return false;
}

Expand Down Expand Up @@ -980,7 +979,7 @@ TEST_CASE("reparse_tag_to_string")
string Str;
for (const auto& i: Tests)
{
REQUIRE(reparse_tag_to_string(i.Tag, Str) == i.Known);
REQUIRE(reparse_tag_to_string(i.Tag, Str, true) == i.Known);
REQUIRE(Str == i.Str);
}
}
Expand Down
2 changes: 1 addition & 1 deletion far/flink.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,6 @@ void NormalizeSymlinkName(string &strLinkName);

bool MkSymLink(string_view Target, string_view LinkName, ReparsePointTypes LinkType, std::optional<error_state_ex>& ErrorState, bool Silent = false, bool HoldTarget = false);

bool reparse_tag_to_string(DWORD ReparseTag, string& Str);
bool reparse_tag_to_string(DWORD ReparseTag, string& Str, bool ShowUnknown);

#endif // FLINK_HPP_76B08BB3_29AE_4BCA_B01B_C600603A2996
17 changes: 9 additions & 8 deletions far/panelmix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -728,23 +728,24 @@ string FormatStr_Size(
auto ID_Msg = lng::MListJunction;
if (Global->Opt->PanelDetailedJunction && !CurDir.empty())
{
string strLinkName;
if (GetReparsePointInfo(path::join(CurDir, PointToName(strName)), strLinkName))
if (string strLinkName; GetReparsePointInfo(path::join(CurDir, PointToName(strName)), strLinkName))
{
NormalizeSymlinkName(strLinkName);
bool Root;
if(ParsePath(strLinkName, nullptr, &Root) == root_type::volume && Root)
{

if(bool Root; ParsePath(strLinkName, nullptr, &Root) == root_type::volume && Root)
ID_Msg = lng::MListVolMount;
}
}
}
TypeName=msg(ID_Msg);
TypeName = msg(ID_Msg);
}
break;

case IO_REPARSE_TAG_SYMLINK:
TypeName = msg(lng::MListSymlink);
break;

default:
if (!reparse_tag_to_string(ReparseTag, TypeName) && !Global->Opt->ShowUnknownReparsePoint)
if (!reparse_tag_to_string(ReparseTag, TypeName, Global->Opt->ShowUnknownReparsePoint) && TypeName.empty())
TypeName = msg(lng::MListUnknownReparsePoint);
break;
}
Expand Down
37 changes: 22 additions & 15 deletions far/qview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,43 +155,50 @@ void QuickView::DisplayObject()
const auto currAttr = os::fs::get_file_attributes(strCurFileName); // обламывается, если нет доступа
if (currAttr != INVALID_FILE_ATTRIBUTES && (currAttr&FILE_ATTRIBUTE_REPARSE_POINT))
{
string Target;
DWORD ReparseTag=0;
string TypeName;
string TypeName, Target;
bool KnownReparseTag = false;

if (GetReparsePointInfo(strCurFileName, Target, &ReparseTag))
{
KnownReparseTag = true;
NormalizeSymlinkName(Target);
switch(ReparseTag)

switch (ReparseTag)
{
// Directory Junction or Volume Mount Point
case IO_REPARSE_TAG_MOUNT_POINT:
{
auto ID_Msg = lng::MListJunction;
bool Root;
if(ParsePath(Target, nullptr, &Root) == root_type::volume && Root)
{
if (bool Root; ParsePath(Target, nullptr, &Root) == root_type::volume && Root)
ID_Msg = lng::MListVolMount;
}

TypeName = msg(ID_Msg);
}
break;

default:
if (!reparse_tag_to_string(ReparseTag, TypeName) && !Global->Opt->ShowUnknownReparsePoint)
TypeName = msg(lng::MQuickViewUnknownReparsePoint);
case IO_REPARSE_TAG_SYMLINK:
TypeName = msg(lng::MListSymlink);
break;
}

inplace::truncate_path(Target, std::max(size_t{}, m_Where.width() - 2 - TypeName.size() - 5));
}
else
else if (reparse_tag_to_string(ReparseTag, TypeName, Global->Opt->ShowUnknownReparsePoint))
{
TypeName = far::format(L"{} {}"sv, msg(lng::MQuickViewReparsePoint), TypeName);
KnownReparseTag = true;
}
else if (TypeName.empty())
{
TypeName = msg(lng::MQuickViewUnknownReparsePoint);
Target = msg(lng::MQuickViewNoData);
}

inplace::truncate_path(Target, std::max(size_t{}, m_Where.width() - 2 - TypeName.size() - 5));
SetColor(COL_PANELTEXT);
GotoXY(m_Where.left + 2, m_Where.top + 3);
PrintText(far::format(LR"({} "{}")", TypeName, Target));
PrintText(KnownReparseTag?
far::format(LR"({} "{}")", TypeName, Target) :
msg(lng::MQuickViewUnknownReparsePoint)
);
}

const auto bytes_suffix = upper(msg(lng::MListBytes));
Expand Down
92 changes: 58 additions & 34 deletions far/setattr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -891,28 +891,56 @@ static bool ShellSetFileAttributesImpl(Panel* SrcPanel, const string* Object)

if ((SingleSelFindData.Attributes != INVALID_FILE_ATTRIBUTES && (SingleSelFindData.Attributes & FILE_ATTRIBUTE_REPARSE_POINT)) || IsMountPoint)
{
LinkPresent = true;

auto ID_Msg = IsMountPoint? lng::MSetAttrVolMount : lng::MSetAttrSymlink;
DWORD ReparseTag = SingleSelFindData.ReparseTag;
bool KnownReparsePoint = false;
bool KnownReparseTag = false;

if (!DlgParam.Plugin)
{
if (IsMountPoint)
{
// BUGBUG, cheating
ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
KnownReparsePoint = os::fs::GetVolumeNameForVolumeMountPoint(SingleSelFileName, strLinkName);
KnownReparseTag = true;
(void)os::fs::GetVolumeNameForVolumeMountPoint(SingleSelFileName, strLinkName);
}
else
{
DWORD ReparseTagAlternative = 0;
KnownReparsePoint = GetReparsePointInfo(SingleSelFileName, strLinkName, &ReparseTagAlternative);
KnownReparseTag = GetReparsePointInfo(SingleSelFileName, strLinkName, &ReparseTagAlternative);
if (ReparseTagAlternative && !ReparseTag)
{
ReparseTag = ReparseTagAlternative;
}
}

if (KnownReparseTag)
{
NormalizeSymlinkName(strLinkName);

if (!KnownReparsePoint)
switch (ReparseTag)
{
case IO_REPARSE_TAG_MOUNT_POINT:
ID_Msg = lng::MSetAttrJunction;

if (bool Root; !IsMountPoint && ParsePath(strLinkName, nullptr, &Root) == root_type::volume && Root)
ID_Msg = lng::MSetAttrVolMount;

break;

case IO_REPARSE_TAG_SYMLINK:
ID_Msg = lng::MSetAttrSymlink;
break;

case IO_REPARSE_TAG_APPEXECLINK:
ID_Msg = lng::MSetAttrAppExecLink;
break;
}
}
else
{
if (ReparseTag == IO_REPARSE_TAG_DFS)
{
const auto path = path::join(SrcPanel->GetCurDir(), SingleSelFileName);
Expand All @@ -922,7 +950,7 @@ static bool ShellSetFileAttributesImpl(Panel* SrcPanel, const string* Object)
Result = imports.NetDfsGetClientInfo(UNSAFE_CSTR(path), nullptr, nullptr, 3, edit_as<BYTE**>(&ptr_setter(DfsInfo)));
if (Result == NERR_Success)
{
KnownReparsePoint = true;
KnownReparseTag = true;

const span DfsStorages(DfsInfo->Storage, DfsInfo->NumberOfStorages);
ListItems.resize(DfsStorages.size());
Expand All @@ -939,13 +967,15 @@ static bool ShellSetFileAttributesImpl(Panel* SrcPanel, const string* Object)

NameList.Items = ListItems.data();
NameList.ItemsNumber = DfsInfo->NumberOfStorages;

AttrDlg[SA_EDIT_REPARSE_POINT].Flags |= DIF_HIDDEN;
AttrDlg[SA_COMBO_REPARSE_POINT].Flags &= ~DIF_HIDDEN;
AttrDlg[SA_COMBO_REPARSE_POINT].ListItems = &NameList;
AttrDlg[SA_COMBO_REPARSE_POINT].strData = concat(msg(lng::MSetAttrDfsTargets), L" ("sv, str(NameList.ItemsNumber), L')');
}
}

if (!KnownReparseTag)
{
if (reparse_tag_to_string(ReparseTag, strLinkName, Global->Opt->ShowUnknownReparsePoint) || !strLinkName.empty())
strLinkName = far::format(L"{} {}"sv, replace(msg(lng::MSetAttrReparsePoint), L"&"sv, L""sv), strLinkName);
else
strLinkName = msg(lng::MSetAttrUnknownReparsePoint);
}
}
}
Expand All @@ -961,40 +991,34 @@ static bool ShellSetFileAttributesImpl(Panel* SrcPanel, const string* Object)
}
}

LinkPresent=true;
NormalizeSymlinkName(strLinkName);
AttrDlg[SA_TEXT_REPARSE_POINT].Flags &= ~DIF_HIDDEN;

if (!IsMountPoint && ReparseTag==IO_REPARSE_TAG_MOUNT_POINT)
if (KnownReparseTag)
{
bool Root;
if(ParsePath(strLinkName, nullptr, &Root) == root_type::volume && Root)
AttrDlg[SA_TEXT_REPARSE_POINT].strData = msg(ID_Msg);

if (ReparseTag == IO_REPARSE_TAG_DFS)
{
ID_Msg = lng::MSetAttrVolMount;
AttrDlg[SA_EDIT_REPARSE_POINT].Flags |= DIF_HIDDEN;
AttrDlg[SA_COMBO_REPARSE_POINT].Flags &= ~DIF_HIDDEN;
AttrDlg[SA_COMBO_REPARSE_POINT].ListItems = &NameList;
AttrDlg[SA_COMBO_REPARSE_POINT].strData = concat(msg(lng::MSetAttrDfsTargets), L" ("sv, str(NameList.ItemsNumber), L')');
}
else
{
ID_Msg = lng::MSetAttrJunction;
AttrDlg[SA_EDIT_REPARSE_POINT].Flags &= ~DIF_HIDDEN;
AttrDlg[SA_EDIT_REPARSE_POINT].strData = strLinkName;
}
}
else if (ReparseTag == IO_REPARSE_TAG_APPEXECLINK)
{
ID_Msg = lng::MSetAttrAppExecLink;
}

if (!KnownReparsePoint)
strLinkName=msg(lng::MSetAttrUnknownReparsePoint);

AttrDlg[SA_TEXT_REPARSE_POINT].Flags &= ~DIF_HIDDEN;
AttrDlg[SA_TEXT_REPARSE_POINT].strData = msg(ID_Msg);

if (ReparseTag != IO_REPARSE_TAG_DFS)
if (IsMountPoint || none_of(ReparseTag, IO_REPARSE_TAG_MOUNT_POINT, IO_REPARSE_TAG_SYMLINK))
AttrDlg[SA_EDIT_REPARSE_POINT].Flags |= DIF_READONLY;
}
else
{
AttrDlg[SA_EDIT_REPARSE_POINT].Flags &= ~DIF_HIDDEN;
AttrDlg[SA_EDIT_REPARSE_POINT].strData = strLinkName;
AttrDlg[SA_TEXT_REPARSE_POINT].X2 = AttrDlg[SA_EDIT_REPARSE_POINT].X2;
AttrDlg[SA_TEXT_REPARSE_POINT].Flags |= DIF_CENTERTEXT;
AttrDlg[SA_TEXT_REPARSE_POINT].strData = strLinkName;
}

if (IsMountPoint || none_of(ReparseTag, IO_REPARSE_TAG_MOUNT_POINT, IO_REPARSE_TAG_SYMLINK))
AttrDlg[SA_EDIT_REPARSE_POINT].Flags |= DIF_READONLY;
}

// обработка случая "несколько хардлинков"
Expand Down
Loading

0 comments on commit 8545e07

Please sign in to comment.