AuroraRuntime/Source/IO/FS/FS.NT.cpp

211 lines
6.1 KiB
C++
Raw Normal View History

2021-06-27 21:25:29 +00:00
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
2021-09-06 10:58:08 +00:00
File: FS.NT.cpp
2021-06-27 21:25:29 +00:00
Date: 2021-6-12
Author: Reece
***/
#include <RuntimeInternal.hpp>
#include "FS.hpp"
#include "FS.Generic.hpp"
#include <Time/Time.hpp>
#if !defined(_AURUNTIME_GENERICFS)
namespace Aurora::IO::FS
{
static const AuUInt64 kFileCopyBlock = 0xFFFF; // 64KiB
2021-06-27 21:25:29 +00:00
bool _MkDir(const AuString &str)
{
return CreateDirectoryW(Locale::ConvertFromUTF8(str).c_str(), NULL);
}
AUKN_SYM bool FilesInDirectory(const AuString &string, AuList<AuString> &files)
{
if (IterateDirEntriesSTL(string, true, files))
{
return true;
}
2021-09-06 10:58:08 +00:00
// TODO: Implement a fast path for NT. std::filesystem is unusably slow
2021-06-27 21:25:29 +00:00
return false;
}
AUKN_SYM bool DirsInDirectory(const AuString &string, AuList<AuString> &dirs)
{
if (IterateDirEntriesSTL(string, false, dirs))
{
return true;
}
2021-09-06 10:58:08 +00:00
// TODO: Implement a fast path for NT. std::filesystem is unusably slow
2021-06-27 21:25:29 +00:00
return false;
}
AUKN_SYM bool WriteFile(const AuString &path, const void *data, size_t length)
{
2021-09-06 10:58:08 +00:00
bool status;
size_t offset;
HANDLE fileHandle;
std::wstring win32Path;
AuString pathNormalized;
status = false;
pathNormalized = NormalizePathRet(path);
win32Path = Locale::ConvertFromUTF8(pathNormalized);
2021-06-27 21:25:29 +00:00
CreateDirectories(pathNormalized, true);
2021-09-06 10:58:08 +00:00
fileHandle = CreateFileW(win32Path.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2021-06-30 16:34:49 +00:00
if (fileHandle == INVALID_HANDLE_VALUE)
2021-06-27 21:25:29 +00:00
{
SysPushErrorIO("Couldn't open handle: {}", path);
return false;
}
2021-09-06 10:58:08 +00:00
offset = 0;
2021-06-27 21:25:29 +00:00
while (length)
{
DWORD written;
int blockSize = std::min(static_cast<AuUInt64>(kFileCopyBlock), static_cast<AuUInt64>(length));
if (!::WriteFile(fileHandle, &reinterpret_cast<const char *>(data)[offset], blockSize, &written, NULL))
{
SysPushErrorIO();
goto out;
}
if (written != blockSize)
{
SysPushErrorIO();
goto out;
}
offset += written;
length -= written;
}
status = true;
out:
AuWin32CloseHandle(fileHandle);
2021-06-27 21:25:29 +00:00
return status;
}
AUKN_SYM bool ReadFile(const AuString &path, AuList<uint8_t> &buffer)
{
2021-09-06 10:58:08 +00:00
std::wstring win32Path;
LARGE_INTEGER length;
bool status;
size_t offset;
status = false;
offset = 0;
win32Path = Locale::ConvertFromUTF8(NormalizePathRet(path));
2021-06-27 21:25:29 +00:00
auto fileHandle = CreateFileW(win32Path.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
2021-06-30 16:34:49 +00:00
if (fileHandle == INVALID_HANDLE_VALUE)
2021-06-27 21:25:29 +00:00
{
SysPushErrorIO("Couldn't open handle: {}", path);
return false;
}
if (!GetFileSizeEx(fileHandle, &length))
{
SysPushErrorIO();
goto out;
}
2021-09-06 10:58:08 +00:00
if (!AuTryResize(buffer, length.QuadPart))
2021-06-27 21:25:29 +00:00
{
SysPushErrorMem();
goto out;
}
while (length.QuadPart)
{
DWORD read;
int blockSize = std::min(static_cast<AuUInt64>(kFileCopyBlock), static_cast<AuUInt64>(length.QuadPart));
if (!::ReadFile(fileHandle, &buffer[offset], blockSize, &read, NULL))
{
LogWarn("ReadFile IO Error: 0x%x {}", GetLastError(), path);
2021-06-27 21:25:29 +00:00
SysPushErrorIO();
goto out;
}
offset += read;
length.QuadPart -= read;
}
status = true;
out:
AuWin32CloseHandle(fileHandle);
2021-06-27 21:25:29 +00:00
return status;
}
AUKN_SYM bool FileExists(const AuString &path)
{
DWORD dwAttrib = GetFileAttributesW(Locale::ConvertFromUTF8(NormalizePathRet(path)).c_str());
2021-09-06 10:58:08 +00:00
return ((dwAttrib != INVALID_FILE_ATTRIBUTES) &&
!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
2021-06-27 21:25:29 +00:00
}
AUKN_SYM bool DirExists(const AuString &path)
{
DWORD dwAttrib = GetFileAttributesW(Locale::ConvertFromUTF8(NormalizePathRet(path)).c_str());
2021-09-06 10:58:08 +00:00
return ((dwAttrib != INVALID_FILE_ATTRIBUTES) &&
2021-06-27 21:25:29 +00:00
(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}
AUKN_SYM bool DirMk(const AuString &path)
{
return CreateDirectories(NormalizePathRet(path), false);
}
AUKN_SYM bool Remove(const AuString &path)
{
return DeleteFileW(Locale::ConvertFromUTF8(NormalizePathRet(path)).c_str());
}
AUKN_SYM bool Relink(const AuString &src, const AuString &dest)
{
return MoveFileW(Locale::ConvertFromUTF8(NormalizePathRet(src)).c_str(), Locale::ConvertFromUTF8(NormalizePathRet(dest)).c_str());
}
AUKN_SYM bool Copy(const AuString &src, const AuString &dest)
{
return CopyFileW(Locale::ConvertFromUTF8(NormalizePathRet(src)).c_str(), Locale::ConvertFromUTF8(NormalizePathRet(dest)).c_str(), true);
}
AUKN_SYM bool StatFile(const AuString &path, Stat &stat)
{
WIN32_FILE_ATTRIBUTE_DATA data;
2021-09-06 10:58:08 +00:00
stat = {};
2021-06-27 21:25:29 +00:00
if (!GetFileAttributesExW(Locale::ConvertFromUTF8(NormalizePathRet(path)).c_str(), GetFileExInfoStandard, &data))
{
stat.exists = false;
return false;
}
stat.exists = true;
stat.existsDirectory = data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
stat.existsFile = !stat.existsDirectory;
stat.symLink = data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT;
stat.size = AuUInt64(data.nFileSizeLow) | (AuUInt64(data.nFileSizeHigh) << 32);
stat.created = Time::ConvertTimestamp(data.ftCreationTime);
stat.modified = Time::ConvertTimestamp(data.ftLastWriteTime);
stat.accessed = Time::ConvertTimestamp(data.ftLastAccessTime);
return true;
}
}
#endif