[+] Directory awareness in OPLOCK hack of a watcher to bring NT up to Linux possible quality

This commit is contained in:
Reece Wilson 2022-04-11 13:54:29 +01:00
parent 2903a9f6cc
commit a3b36ea651
2 changed files with 65 additions and 10 deletions

View File

@ -53,7 +53,7 @@ namespace Aurora::IO::FS
virtual AuSPtr<Loop::ILoopSource> AsLoopSource() = 0;
virtual AuList<WatchEvent> QueryUpdates() = 0;
virtual AuList<WatchEvent> QueryUpdates() = 0;
};
AUKN_SHARED_API(NewWatcher, IWatcher);

View File

@ -76,7 +76,7 @@ namespace Aurora::IO::FS
AuList<AuTuple<AuString, bool, AuUInt64>> GetCurrentState();
bool CheckDirDelta();
bool CheckDirDelta(NTWatcher *parent);
void Warm();
bool CheckRun(NTWatcher *parent);
bool AddEvent(NTWatcher *parent, EWatchEvent type, const AuString &path);
@ -190,16 +190,68 @@ namespace Aurora::IO::FS
AuList<AuTuple<AuString, bool, AuUInt64>> NTCachedPath::GetCurrentState()
{
return {};
WIN32_FIND_DATAW ffd;
HANDLE hFind {INVALID_HANDLE_VALUE};
AuList<AuTuple<AuString, bool, AuUInt64>> ret;
ret.reserve(this->lastTick.size());
hFind = FindFirstFileW(AuLocale::ConvertFromUTF8(this->strNormalizedPath + "\\*").c_str(), &ffd);
if (INVALID_HANDLE_VALUE == hFind)
{
SysPushErrorIO();
return this->lastTick;
}
do
{
if (ffd.cFileName == std::wstring(L".") ||
ffd.cFileName == std::wstring(L".."))
{
continue;
}
AuTryInsert(ret, AuMakeTuple(AuLocale::ConvertFromWChar(ffd.cFileName), ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY, AuUInt64(ffd.ftLastWriteTime.dwHighDateTime) << AuUInt64(32) | AuUInt64(ffd.ftLastWriteTime.dwLowDateTime)));
}
while (FindNextFileW(hFind, &ffd) != 0);
FindClose(hFind);
return ret;
}
bool NTCachedPath::CheckDirDelta()
bool NTCachedPath::CheckDirDelta(NTWatcher *parent)
{
bool bDidAThing {false};
auto next = GetCurrentState();
auto currentState = next;
auto oldState = AuExchange(this->lastTick, AuMove(next));
return false;
for (auto &old : oldState)
{
if (!AuExists(currentState, old))
{
// FILE WAS DELETED
bDidAThing |= AddEvent(parent, EWatchEvent::eFileDelete, this->strTheCakeIsALie + "\\" + AuGet<0>(old));
}
}
for (auto &newItem : currentState)
{
auto oldItem = AuTryFindByTupleN<0>(oldState, AuGet<0>(newItem));
if (oldItem == oldState.end())
{
// FILE WAS ADDED
bDidAThing |= AddEvent(parent, EWatchEvent::eFileCreate, this->strTheCakeIsALie + "\\" + AuGet<0>(newItem));
}
else if (AuGet<2>(newItem) != AuGet<2>(*oldItem))
{
// FILE WAS MODIFIED
bDidAThing |= AddEvent(parent, EWatchEvent::eFileModify, this->strTheCakeIsALie + "\\" + AuGet<0>(newItem));
}
}
return bDidAThing;
}
bool NTCachedPath::AddEvent(NTWatcher *parent, EWatchEvent type, const AuString &path)
@ -254,7 +306,7 @@ namespace Aurora::IO::FS
}
}
bool bDirChanged = this->bIsDirectory ? CheckDirDelta() : false;
bool bDirChanged = this->bIsDirectory ? CheckDirDelta(parent) : false;
if (!GetFileTime(hFile, NULL, NULL, &curFileTime))
{
@ -442,12 +494,15 @@ namespace Aurora::IO::FS
// Attempt to locate a watcher for the directoy
for (const auto &[base, wptr] : this->cachedWatchers_)
if (!cached.bIsDirectory)
{
if (AuStartsWith(translated, base))
for (const auto &[base, wptr] : this->cachedWatchers_)
{
watcher = wptr.lock();
break;
if (AuStartsWith(translated, base))
{
watcher = wptr.lock();
break;
}
}
}