Skip to content
Permalink
Browse files

scantree skippdir fix, search in alt. streams fix

  • Loading branch information...
alabuzhev committed Sep 30, 2017
1 parent 1e08a78 commit 09ceaf90b5ef9bbfc4df1cbedcc9a307ad69fe4d
Showing with 72 additions and 86 deletions.
  1. +6 −0 far/changelog
  2. +35 −75 far/findfile.cpp
  3. +30 −10 far/scantree.cpp
  4. +1 −1 far/vbuild.m4
@@ -1,3 +1,9 @@
drkns 30.09.2017 23:23:55 +0100 - build 5054

1. С форума: Search stops after folder (symlink) excluded in filter.

2. Уточнение поиска в альтернативных потоках.

zg 01.10.2017 00:05:03 +0300 - build 5053

1. ошибочная посылка DN_CONTROLINPUT с Param1=-1 на любое передвижение мыши, если в первый раз вернули TRUE.
@@ -2185,99 +2185,59 @@ void background_searcher::DoScanTree(const string& strRoot)

while (!Stopped() && ScTree.GetNextName(FindData, strFullName))
{
os::fs::enum_streams StreamsEnumerator(strFullName);
os::fs::enum_streams::const_iterator StreamsIterator;

Sleep(0);
PauseEvent.wait();

bool bContinue=false;
string strFindDataFileName=FindData.strFileName;

// process default stream first
bool ProcessAlternateStreams = false;
while (!Stopped())
const auto& ProcessStream = [&](const string& FullStreamName)
{
auto strFullStreamName = strFullName;

if (ProcessAlternateStreams)
enumFileInFilterType foundType;
if (UseFilter && !m_Owner->GetFilter()->FileInFilter(FindData, &foundType, &FullStreamName))
{
StreamsIterator = StreamsIterator? std::next(StreamsIterator) : StreamsEnumerator.cbegin();

if (StreamsIterator != StreamsEnumerator.cend())
{
const auto& StreamData = *StreamsIterator;

const auto NameBegin = StreamData.cStreamName + 1;
const auto NameEnd = wcschr(NameBegin, L':');
const string_view StreamName(NameBegin, NameEnd? NameEnd - NameBegin : wcslen(NameBegin));

if (StreamName.empty()) // default stream has already been processed
continue;
// сюда заходим, если не попали в фильтр или попали в Exclude-фильтр
if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY && foundType == FIFT_EXCLUDE)
ScTree.SkipDir(); // скипаем только по Exclude-фильтру, т.к. глубже тоже нужно просмотреть
return;
}

append(strFullStreamName, L':', StreamName);
FindData.strFileName = strFindDataFileName + StreamName;
FindData.nFileSize = StreamData.StreamSize.QuadPart;
FindData.dwFileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY;
}
else
{
if (bContinue)
{
break;
}
}
if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
m_Owner->itd->SetFindMessage(FullStreamName);
}

if (UseFilter)
if (IsFileIncluded(nullptr, FullStreamName, FindData.dwFileAttributes, strFullName))
{
enumFileInFilterType foundType;
m_Owner->m_Messages.emplace(FullStreamName, FindData, nullptr, nullptr, nullptr);
}

if (!m_Owner->GetFilter()->FileInFilter(FindData, &foundType, &strFullName))
{
// сюда заходим, если не попали в фильтр или попали в Exclude-фильтр
if ((FindData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) && foundType==FIFT_EXCLUDE)
ScTree.SkipDir(); // скипаем только по Exclude-фильтру, т.к. глубже тоже нужно просмотреть
if (SearchInArchives)
ArchiveSearch(FullStreamName);
};

{
bContinue=true;
// default stream first:
ProcessStream(strFullName);

if (ProcessAlternateStreams)
{
continue;
}
else
{
break;
}
}
}
}
// now the rest:
if (Global->Opt->FindOpt.FindAlternateStreams)
{
const auto FindDataFileName = FindData.strFileName;

if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
for(const auto& StreamData: os::fs::enum_streams(strFullName))
{
m_Owner->itd->SetFindMessage(strFullName);
}
const auto NameBegin = StreamData.cStreamName + 1;
const auto NameEnd = wcschr(NameBegin, L':');
const string_view StreamName(NameBegin, NameEnd? NameEnd - NameBegin : wcslen(NameBegin));

if (IsFileIncluded(nullptr,strFullStreamName,FindData.dwFileAttributes,strFullName))
{
m_Owner->m_Messages.emplace(strFullStreamName, FindData, nullptr, nullptr, nullptr);
}
if (StreamName.empty()) // default stream has already been processed
continue;

ProcessAlternateStreams = Global->Opt->FindOpt.FindAlternateStreams;
if (!ProcessAlternateStreams || StreamsIterator == StreamsEnumerator.cend())
{
break;
}
}
const auto FullStreamName = concat(strFullName, L':', StreamName);
FindData.strFileName = concat(FindDataFileName, L':', StreamName);
FindData.nFileSize = StreamData.StreamSize.QuadPart;
FindData.dwFileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY;

if (bContinue)
{
continue;
ProcessStream(FullStreamName);
}
}

if (SearchInArchives)
ArchiveSearch(strFullName);
}

if (SearchMode!=FINDAREA_SELECTED)
@@ -80,26 +80,31 @@ ScanTree::ScanTree(bool RetUpDir, bool Recurse, int ScanJunction)
Flags.Change(FSCANTREE_SCANSYMLINK, ScanJunction == -1? Global->Opt->ScanJunction.Get() : ScanJunction != 0);
}

ScanTree::~ScanTree()
{
}
ScanTree::~ScanTree() = default;

void ScanTree::SetFindPath(const string& Path,const string& Mask, const DWORD NewScanFlags)
{
ScanItems.clear();
ScanItems.emplace_back();

Flags.Clear(FSCANTREE_FILESFIRST);

strFindMask = Mask;
strFindPath = Path;
strFindPathOriginal = strFindPath;

strFindPathOriginal = Path;
AddEndSlash(strFindPathOriginal);
strFindPath = ConvertNameToReal(strFindPath);
strFindPath = NTPath(strFindPath);
ScanItems.back().RealPath = strFindPath;
ScanItems.back().ActiveDirectories.emplace(strFindPath);

strFindPath = NTPath(ConvertNameToReal(Path));

scantree_item Item;
Item.RealPath = strFindPath;
Item.ActiveDirectories.emplace(strFindPath);

AddEndSlash(strFindPath);
strFindPath += strFindMask;

Flags.Set((Flags.Flags()&0x0000FFFF)|(NewScanFlags&0xFFFF0000));

ScanItems.emplace_back(std::move(Item));
}

bool ScanTree::GetNextName(os::fs::find_data& fdata,string &strFullName)
@@ -249,6 +254,21 @@ void ScanTree::SkipDir()
if (ScanItems.empty())
return;

{
const auto& Current = ScanItems.back();
if (!Flags.Check(FSCANTREE_SCANSYMLINK) &&
Current.Find &&
Current.Iterator != Current.Find->end() &&
(Current.Iterator->dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT)) == (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT)
)
{
// The current item is a directory link but we don't treat it as a directory so it's nothing to skip
// (perhaps it could have been better to add a special flag for this case rather than the quite complex condition above,
// but these flags is already a mess).
return;
}
}

ScanItems.pop_back();

if (ScanItems.empty())
@@ -1 +1 @@
m4_define(BUILD,5053)m4_dnl
m4_define(BUILD,5054)m4_dnl

0 comments on commit 09ceaf9

Please sign in to comment.
You can’t perform that action at this time.