Index: farlang.templ.m4
===================================================================
--- farlang.templ.m4	(revision 6904)
+++ farlang.templ.m4	(working copy)
@@ -19603,6 +19603,15 @@
 "<="
 "<="
 
+MFileHardLinksCount
+"Болee одной жёсткой ссылки"
+"Has more than one hardlink"
+upd:"Has more than one hardlink"
+upd:"Has more than one hardlink"
+upd:"Has more than one hardlink"
+upd:"Has more than one hardlink"
+upd:"Has more than one hardlink"
+
 MFileFilterDate
 "&Дата/Время:"
 "Da&te/Time:"
Index: filefilterparams.cpp
===================================================================
--- filefilterparams.cpp	(revision 6904)
+++ filefilterparams.cpp	(working copy)
@@ -51,11 +51,13 @@
 #include "strmix.hpp"
 #include "mix.hpp"
 #include "console.hpp"
+#include "flink.hpp"
 
 FileFilterParams::FileFilterParams()
 {
 	SetMask(1,L"*");
 	SetSize(0,L"",L"");
+	SetHardLinks(0,0,0);
 	ClearStruct(FDate);
 	ClearStruct(FAttr);
 	ClearStruct(FHighlight.Colors);
@@ -207,6 +209,13 @@
 	FSize.SizeBelowReal=ConvertFileSizeString(FSize.SizeBelow);
 }
 
+void FileFilterParams::SetHardLinks(bool Used, unsigned __int64 HardLinksAbove, unsigned __int64 HardLinksBelow)
+{
+	FHardLinks.Used=Used;
+	FHardLinks.CountAbove=HardLinksAbove;
+	FHardLinks.CountBelow=HardLinksBelow;
+}
+
 void FileFilterParams::SetAttr(bool Used, DWORD AttrSet, DWORD AttrClear)
 {
 	FAttr.Used=Used;
@@ -266,6 +275,16 @@
 	return FSize.Used;
 }
 
+bool FileFilterParams::GetHardLinks(unsigned __int64 *HardLinksAbove, unsigned __int64 *HardLinksBelow) const
+{
+	if (HardLinksAbove)
+		*HardLinksAbove = FHardLinks.CountAbove;
+	if (HardLinksBelow)
+		*HardLinksBelow = FHardLinks.CountBelow;
+	return FHardLinks.Used;
+}
+
+
 bool FileFilterParams::GetAttr(DWORD *AttrSet, DWORD *AttrClear) const
 {
 	if (AttrSet)
@@ -332,6 +351,15 @@
 		}
 	}
 
+	//        ?
+	//  ,   ,     "   "
+	if (FHardLinks.Used)
+	{
+		//if (GetNumberOfLinks(fde.strFileName)<FHardLinks.CountBelow)
+		if (GetNumberOfLinks(fde.strFileName)==1) 
+			return false;
+	}
+
 	//     ?
 	if (FDate.Used)
 	{
@@ -429,16 +457,16 @@
 		FILE_ATTRIBUTE_OFFLINE,
 		FILE_ATTRIBUTE_VIRTUAL,
 	};
-	const wchar_t Format1a[] = L"%-21.21s %c %-26.26s %-2.2s %c %s";
-	const wchar_t Format1b[] = L"%-22.22s %c %-26.26s %-2.2s %c %s";
-	const wchar_t Format1c[] = L"&%c. %-18.18s %c %-26.26s %-2.2s %c %s";
-	const wchar_t Format1d[] = L"   %-18.18s %c %-26.26s %-2.2s %c %s";
-	const wchar_t Format2[]  = L"%-3.3s %c %-26.26s %-3.3s %c %s";
+	const wchar_t Format1a[] = L"%-21.21s %c %-26.26s %-3.3s %c %s";
+	const wchar_t Format1b[] = L"%-22.22s %c %-26.26s %-3.3s %c %s";
+	const wchar_t Format1c[] = L"&%c. %-18.18s %c %-26.26s %-3.3s %c %s";
+	const wchar_t Format1d[] = L"   %-18.18s %c %-26.26s %-3.3s %c %s";
+	const wchar_t Format2[]  = L"%-3.3s %c %-26.26s %-4.4s %c %s";
 	const wchar_t DownArrow=0x2193;
 	const wchar_t *Name, *Mask;
 	wchar_t MarkChar[]=L"\" \"";
 	DWORD IncludeAttr, ExcludeAttr;
-	bool UseMask, UseSize, UseDate, RelativeDate;
+	bool UseMask, UseSize, UseHardLinks, UseDate, RelativeDate;
 
 	if (bPanelType)
 	{
@@ -447,7 +475,7 @@
 		Mask=FMask;
 		IncludeAttr=0;
 		ExcludeAttr=FILE_ATTRIBUTE_DIRECTORY;
-		RelativeDate=UseDate=UseSize=false;
+		RelativeDate=UseDate=UseSize=UseHardLinks=false;
 	}
 	else
 	{
@@ -464,6 +492,7 @@
 
 		UseSize=FF->GetSize(nullptr,nullptr);
 		UseDate=FF->GetDate(nullptr,nullptr,nullptr,&RelativeDate);
+		UseHardLinks=FF->GetHardLinks(nullptr,nullptr);
 	}
 
 	wchar_t Attr[ARRAYSIZE(AttrC)*2] = {};
@@ -481,7 +510,7 @@
 			*Ptr=*(Ptr+1)=L'.';
 	}
 
-	wchar_t SizeDate[4] = L"...";
+	wchar_t SizeDate[5] = L"....";
 
 	if (UseSize)
 	{
@@ -496,16 +525,21 @@
 			SizeDate[1]=L'D';
 	}
 
+	if (UseHardLinks)
+	{
+		SizeDate[2]=L'H';
+	}
+
 	if (bHighlightType)
 	{
 		if (FF->GetContinueProcessing())
-			SizeDate[2]=DownArrow;
+			SizeDate[3]=DownArrow;
 
 		strDest.Format(Format2, MarkChar, BoxSymbols[BS_V1], Attr, SizeDate, BoxSymbols[BS_V1], UseMask ? Mask : L"");
 	}
 	else
 	{
-		SizeDate[2]=0;
+		SizeDate[3]=0;
 
 		if (!Hotkey && !bPanelType)
 		{
@@ -594,6 +628,10 @@
 
 	ID_FF_SEPARATOR5,
 
+	ID_FF_HARDLINKS,
+
+	ID_FF_SEPARATOR6,
+
 	ID_FF_OK,
 	ID_FF_RESET,
 	ID_FF_CANCEL,
@@ -895,7 +933,7 @@
 	strTimeMask.Format(L"99%c99%c99%c999",TimeSeparator,TimeSeparator,DecimalSeparator);
 	FarDialogItem FilterDlgData[]=
 	{
-		{DI_DOUBLEBOX,3,1,76,18,0,nullptr,nullptr,DIF_SHOWAMPERSAND,MSG(MFileFilterTitle)},
+		{DI_DOUBLEBOX,3,1,76,20,0,nullptr,nullptr,DIF_SHOWAMPERSAND,MSG(MFileFilterTitle)},
 
 		{DI_TEXT,5,2,0,2,0,nullptr,nullptr,DIF_FOCUS,MSG(MFileFilterName)},
 		{DI_EDIT,5,2,74,2,0,FilterNameHistoryName,nullptr,DIF_HISTORY,L""},
@@ -966,10 +1004,13 @@
 
 		{DI_TEXT,0,16,0,16,0,nullptr,nullptr,DIF_SEPARATOR,L""},
 
-		{DI_BUTTON,0,17,0,17,0,nullptr,nullptr,DIF_DEFAULTBUTTON|DIF_CENTERGROUP,MSG(MOk)},
-		{DI_BUTTON,0,17,0,17,0,nullptr,nullptr,DIF_CENTERGROUP|DIF_BTNNOCLOSE,MSG(MFileFilterReset)},
-		{DI_BUTTON,0,17,0,17,0,nullptr,nullptr,DIF_CENTERGROUP,MSG(MFileFilterCancel)},
-		{DI_BUTTON,0,17,0,17,0,nullptr,nullptr,DIF_CENTERGROUP|DIF_BTNNOCLOSE,MSG(MFileFilterMakeTransparent)},
+		{DI_CHECKBOX,5,17,0,17,0,nullptr,nullptr,0,MSG(MFileHardLinksCount)},//    
+		{DI_TEXT,0,18,0,18,0,nullptr,nullptr,DIF_SEPARATOR,L""},//  
+
+		{DI_BUTTON,0,19,0,19,0,nullptr,nullptr,DIF_DEFAULTBUTTON|DIF_CENTERGROUP,MSG(MOk)},
+		{DI_BUTTON,0,19,0,19,0,nullptr,nullptr,DIF_CENTERGROUP|DIF_BTNNOCLOSE,MSG(MFileFilterReset)},
+		{DI_BUTTON,0,19,0,19,0,nullptr,nullptr,DIF_CENTERGROUP,MSG(MFileFilterCancel)},
+		{DI_BUTTON,0,19,0,19,0,nullptr,nullptr,DIF_CENTERGROUP|DIF_BTNNOCLOSE,MSG(MFileFilterMakeTransparent)},
 	};
 	FilterDlgData[0].Data=MSG(ColorConfig?MFileHilightTitle:MFileFilterTitle);
 	MakeDialogItemsEx(FilterDlgData,FilterDlg);
@@ -1032,6 +1073,7 @@
 	FilterDlg[ID_FF_MATCHSIZE].Selected=FF->GetSize(&SizeAbove,&SizeBelow)?1:0;
 	FilterDlg[ID_FF_SIZEFROMEDIT].strData=SizeAbove;
 	FilterDlg[ID_FF_SIZETOEDIT].strData=SizeBelow;
+	FilterDlg[ID_FF_HARDLINKS].Selected=FF->GetHardLinks(nullptr,nullptr)?1:0; //        
 
 	if (!FilterDlg[ID_FF_MATCHSIZE].Selected)
 		for (int i=ID_FF_SIZEFROMSIGN; i <= ID_FF_SIZETOEDIT; i++)
@@ -1151,6 +1193,7 @@
 			FF->SetSize(FilterDlg[ID_FF_MATCHSIZE].Selected!=0,
 			            FilterDlg[ID_FF_SIZEFROMEDIT].strData,
 			            FilterDlg[ID_FF_SIZETOEDIT].strData);
+			FF->SetHardLinks(FilterDlg[ID_FF_HARDLINKS].Selected!=0,0,0); //     
 			bRelative = FilterDlg[ID_FF_DATERELATIVE].Selected!=0;
 
 			LPWSTR TimeBefore = FilterDlg[ID_FF_TIMEBEFOREEDIT].strData.GetBuffer();
Index: filefilterparams.hpp
===================================================================
--- filefilterparams.hpp	(revision 6904)
+++ filefilterparams.hpp	(working copy)
@@ -105,6 +105,13 @@
 			bool Used;
 		} FSize;
 
+		struct //    ,     .       Used
+		{
+			bool Used;
+			unsigned __int64 CountAbove; //    wchar_t      ? 
+			unsigned __int64 CountBelow; 
+		} FHardLinks;
+
 		struct
 		{
 			bool Used;
@@ -131,6 +138,7 @@
 		void SetMask(bool Used, const wchar_t *Mask);
 		void SetDate(bool Used, DWORD DateType, FILETIME DateAfter, FILETIME DateBefore, bool bRelative);
 		void SetSize(bool Used, const wchar_t *SizeAbove, const wchar_t *SizeBelow);
+		void SetHardLinks(bool Used, unsigned __int64 HardLinksAbove, unsigned __int64 HardLinksBelow);
 		void SetAttr(bool Used, DWORD AttrSet, DWORD AttrClear);
 		void SetColors(HighlightDataColor *Colors);
 		void SetSortGroup(int SortGroup) { FHighlight.SortGroup = SortGroup; }
@@ -142,6 +150,7 @@
 		bool  GetMask(const wchar_t **Mask) const;
 		bool  GetDate(DWORD *DateType, FILETIME *DateAfter, FILETIME *DateBefore, bool *bRelative) const;
 		bool  GetSize(const wchar_t **SizeAbove, const wchar_t **SizeBelow) const;
+		bool  GetHardLinks(unsigned __int64 *HardLinksAbove, unsigned __int64 *HardLinksBelow) const;
 		bool  GetAttr(DWORD *AttrSet, DWORD *AttrClear) const;
 		void  GetColors(HighlightDataColor *Colors) const;
 		int   GetMarkChar() const;
