[+] IReadDir
[+] AuIOFS::ReadDir [*] Fix erroneous return false under fs remove (NT)
This commit is contained in:
parent
2470cbc12a
commit
b8bcab1bdc
@ -9,18 +9,24 @@
|
|||||||
|
|
||||||
namespace Aurora::IO::FS
|
namespace Aurora::IO::FS
|
||||||
{
|
{
|
||||||
|
struct IReadDir;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Lists files with respect to a given partial or full path of a directory
|
Lists files with respect to a given partial or full path of a directory
|
||||||
@param files relative address of an entry
|
@param files relative address of an entry
|
||||||
|
@deprecate use ReadDir
|
||||||
*/
|
*/
|
||||||
AUKN_SYM bool FilesInDirectory(const AuString &string, AuList<AuString> &files);
|
AUKN_SYM bool FilesInDirectory(const AuString &string, AuList<AuString> &files);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Lists directories with respect to a given partial or full path of a directory
|
Lists directories with respect to a given partial or full path of a directory
|
||||||
@param files relative address of an entry
|
@param files relative address of an entry
|
||||||
|
@deprecate use ReadDir
|
||||||
*/
|
*/
|
||||||
AUKN_SYM bool DirsInDirectory(const AuString &string, AuList<AuString> &dirs);
|
AUKN_SYM bool DirsInDirectory(const AuString &string, AuList<AuString> &dirs);
|
||||||
|
|
||||||
|
AUKN_SYM AuSPtr<IReadDir> ReadDir(const AuString &string);
|
||||||
|
|
||||||
AUKN_SYM bool WriteFile(const AuString &path, const Memory::MemoryViewRead &blob);
|
AUKN_SYM bool WriteFile(const AuString &path, const Memory::MemoryViewRead &blob);
|
||||||
AUKN_SYM bool WriteString(const AuString &path, const AuString &str);
|
AUKN_SYM bool WriteString(const AuString &path, const AuString &str);
|
||||||
|
|
||||||
@ -55,4 +61,5 @@ namespace Aurora::IO::FS
|
|||||||
#include "Stat.hpp"
|
#include "Stat.hpp"
|
||||||
#include "IAsyncFileStream.hpp"
|
#include "IAsyncFileStream.hpp"
|
||||||
#include "Async.hpp"
|
#include "Async.hpp"
|
||||||
#include "Watcher.hpp"
|
#include "Watcher.hpp"
|
||||||
|
#include "IReadDir.hpp"
|
22
Include/Aurora/IO/FS/IReadDir.hpp
Normal file
22
Include/Aurora/IO/FS/IReadDir.hpp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/***
|
||||||
|
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||||
|
|
||||||
|
File: IReadDir.hpp
|
||||||
|
Date: 2022-07-22
|
||||||
|
Author: Reece
|
||||||
|
***/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Aurora::IO::FS
|
||||||
|
{
|
||||||
|
struct StatEx : Stat
|
||||||
|
{
|
||||||
|
AuString path;
|
||||||
|
AuString fileName;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IReadDir
|
||||||
|
{
|
||||||
|
virtual StatEx *Next() = 0;
|
||||||
|
};
|
||||||
|
}
|
@ -30,6 +30,4 @@ namespace Aurora::IO
|
|||||||
AUI_METHOD(bool, ApplyRateLimit, ())
|
AUI_METHOD(bool, ApplyRateLimit, ())
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -20,28 +20,150 @@ namespace Aurora::IO::FS
|
|||||||
return CreateDirectoryW(Locale::ConvertFromUTF8(str).c_str(), NULL);
|
return CreateDirectoryW(Locale::ConvertFromUTF8(str).c_str(), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
AUKN_SYM bool FilesInDirectory(const AuString &string, AuList<AuString> &files)
|
struct ReadDirStructure : IReadDir
|
||||||
{
|
{
|
||||||
if (IterateDirEntriesSTL(string, true, files))
|
HANDLE hFind {INVALID_HANDLE_VALUE};
|
||||||
|
WIN32_FIND_DATAW ffd;
|
||||||
|
bool bFirstTick {true};
|
||||||
|
bool bDead {false};
|
||||||
|
StatEx stat;
|
||||||
|
AuString sPath;
|
||||||
|
|
||||||
|
~ReadDirStructure()
|
||||||
{
|
{
|
||||||
return true;
|
::FindClose(this->hFind);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Implement a fast path for NT. std::filesystem is unusably slow
|
virtual StatEx *Next() override
|
||||||
|
{
|
||||||
|
if (!AuExchange(this->bFirstTick, false))
|
||||||
|
{
|
||||||
|
if (::FindNextFileW(this->hFind, &this->ffd) == 0)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
if (this->bDead)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->ffd.cFileName == std::wstring(L".") ||
|
||||||
|
this->ffd.cFileName == std::wstring(L".."))
|
||||||
|
{
|
||||||
|
return Next();
|
||||||
|
}
|
||||||
|
|
||||||
|
stat.exists = true;
|
||||||
|
|
||||||
|
stat.fileName = Locale::ConvertFromWChar(this->ffd.cFileName);
|
||||||
|
if (stat.fileName.empty())
|
||||||
|
{
|
||||||
|
this->bDead = true;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
stat.path = NormalizePathRet(this->sPath + stat.fileName);
|
||||||
|
if (stat.path.empty())
|
||||||
|
{
|
||||||
|
this->bDead = true;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
stat.existsDirectory = this->ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
|
||||||
|
stat.existsFile = !stat.existsDirectory;
|
||||||
|
stat.symLink = this->ffd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT;
|
||||||
|
|
||||||
|
stat.size = AuUInt64(this->ffd.nFileSizeLow) | (AuUInt64(this->ffd.nFileSizeHigh) << 32);
|
||||||
|
|
||||||
|
stat.created = Time::ConvertTimestamp(this->ffd.ftCreationTime);
|
||||||
|
stat.modified = Time::ConvertTimestamp(this->ffd.ftLastWriteTime);
|
||||||
|
stat.accessed = Time::ConvertTimestamp(this->ffd.ftLastAccessTime);
|
||||||
|
|
||||||
|
return &stat;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
AUKN_SYM AuSPtr<IReadDir> ReadDir(const AuString &string)
|
||||||
|
{
|
||||||
|
auto pObj = AuMakeShared<ReadDirStructure>();
|
||||||
|
if (!pObj)
|
||||||
|
{
|
||||||
|
SysPushErrorMem();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!AuIOFS::NormalizePath(pObj->sPath, string))
|
||||||
|
{
|
||||||
|
SysPushErrorMem();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!AuTryInsert(pObj->sPath, '\\'))
|
||||||
|
{
|
||||||
|
SysPushErrorMem();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
pObj->hFind = ::FindFirstFileW(AuLocale::ConvertFromUTF8(pObj->sPath + "*").c_str(), &pObj->ffd);
|
||||||
|
if (INVALID_HANDLE_VALUE == pObj->hFind)
|
||||||
|
{
|
||||||
|
SysPushErrorIO();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return pObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
AUKN_SYM bool FilesInDirectory(const AuString &string, AuList<AuString> &files)
|
||||||
|
{
|
||||||
|
auto itr = ReadDir(string);
|
||||||
|
if (!itr)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SECURITY(): if next fails, its indistinguishable from end of file list, and will return true. it kinda sucks
|
||||||
|
while (auto stat = itr->Next())
|
||||||
|
{
|
||||||
|
if (!stat->existsFile)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!AuTryInsert(files, stat->fileName))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
AUKN_SYM bool DirsInDirectory(const AuString &string, AuList<AuString> &dirs)
|
AUKN_SYM bool DirsInDirectory(const AuString &string, AuList<AuString> &dirs)
|
||||||
{
|
{
|
||||||
if (IterateDirEntriesSTL(string, false, dirs))
|
auto itr = ReadDir(string);
|
||||||
|
if (!itr)
|
||||||
{
|
{
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Implement a fast path for NT. std::filesystem is unusably slow
|
// SECURITY(): if next fails, its indistinguishable from end of file list, and will return true. it kinda sucks
|
||||||
|
while (auto stat = itr->Next())
|
||||||
|
{
|
||||||
|
if (!stat->existsDirectory)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
if (!AuTryInsert(dirs, stat->fileName))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
AUKN_SYM bool WriteFile(const AuString &path, const Memory::MemoryViewRead &blob)
|
AUKN_SYM bool WriteFile(const AuString &path, const Memory::MemoryViewRead &blob)
|
||||||
@ -212,10 +334,16 @@ namespace Aurora::IO::FS
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto translatedPath = Locale::ConvertFromUTF8(NormalizePathRet(path));
|
auto translatedPath = Locale::ConvertFromUTF8(NormalizePathRet(path));
|
||||||
if (!DeleteFileW(translatedPath.c_str()))
|
if (::DeleteFileW(translatedPath.c_str()))
|
||||||
{
|
{
|
||||||
return RemoveDirectoryW(translatedPath.c_str());
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (::RemoveDirectoryW(translatedPath.c_str()))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
|
Loading…
Reference in New Issue
Block a user