Most review changes

This commit is contained in:
Zach Hilman
2018-07-03 11:29:50 -04:00
parent 58642120dc
commit 97aef6dcd1
24 changed files with 152 additions and 148 deletions

View File

@@ -803,12 +803,12 @@ void SplitFilename83(const std::string& filename, std::array<char, 9>& short_nam
std::vector<std::string> SplitPathComponents(const std::string& filename) { std::vector<std::string> SplitPathComponents(const std::string& filename) {
auto copy(filename); auto copy(filename);
std::replace(copy.begin(), copy.end(), '\\', '/'); std::replace(copy.begin(), copy.end(), '\\', '/');
std::vector<std::string> out{}; std::vector<std::string> out;
std::stringstream stream(filename); std::stringstream stream(filename);
std::string item; std::string item;
while (std::getline(stream, item, '/')) while (std::getline(stream, item, '/'))
out.push_back(item); out.push_back(std::move(item));
return out; return out;
} }
@@ -826,16 +826,17 @@ std::string GetParentPath(const std::string& path) {
return out.erase(name_index); return out.erase(name_index);
} }
std::string GetFilename(const std::string& path) { std::string GetFilename(std::string path) {
auto out = path; std::replace(path.begin(), path.end(), '\\', '/');
std::replace(out.begin(), out.end(), '\\', '/'); auto name_index = path.find_last_of('/');
auto name_index = out.find_last_of('/');
if (name_index == std::string::npos) if (name_index == std::string::npos)
return ""; return "";
return out.substr(name_index + 1); return path.substr(name_index + 1);
} }
std::string RemoveTrailingSlash(const std::string& path) { std::string RemoveTrailingSlash(const std::string& path) {
if (path.empty())
return path;
if (path.back() == '\\' || path.back() == '/') if (path.back() == '\\' || path.back() == '/')
return path.substr(0, path.size() - 1); return path.substr(0, path.size() - 1);

View File

@@ -158,7 +158,7 @@ std::vector<std::string> SplitPathComponents(const std::string& filename);
std::string GetParentPath(const std::string& path); std::string GetParentPath(const std::string& path);
// Gets the filename of the path // Gets the filename of the path
std::string GetFilename(const std::string& path); std::string GetFilename(std::string path);
// Removes the final '/' or '\' if one exists // Removes the final '/' or '\' if one exists
std::string RemoveTrailingSlash(const std::string& path); std::string RemoveTrailingSlash(const std::string& path);

View File

@@ -7,15 +7,16 @@
#include "core/file_sys/vfs_offset.h" #include "core/file_sys/vfs_offset.h"
#include "core/loader/loader.h" #include "core/loader/loader.h"
namespace FileSys {
// Media offsets in headers are stored divided by 512. Mult. by this to get real offset. // Media offsets in headers are stored divided by 512. Mult. by this to get real offset.
constexpr u64 MEDIA_OFFSET_MULTIPLIER = 0x200; constexpr u64 MEDIA_OFFSET_MULTIPLIER = 0x200;
constexpr u64 SECTION_HEADER_SIZE = 0x200; constexpr u64 SECTION_HEADER_SIZE = 0x200;
constexpr u64 SECTION_HEADER_OFFSET = 0x400; constexpr u64 SECTION_HEADER_OFFSET = 0x400;
constexpr unsigned IVFC_MAX_LEVEL = 6; constexpr u32 IVFC_MAX_LEVEL = 6;
namespace FileSys {
enum class NCASectionFilesystemType : u8 { PFS0 = 0x2, ROMFS = 0x3 }; enum class NCASectionFilesystemType : u8 { PFS0 = 0x2, ROMFS = 0x3 };
struct NCASectionHeaderBlock { struct NCASectionHeaderBlock {
@@ -66,11 +67,11 @@ NCA::NCA(VirtualFile file_) : file(file_) {
return; return;
} }
int number_sections = std::ptrdiff_t number_sections =
std::count_if(std::begin(header.section_tables), std::end(header.section_tables), std::count_if(std::begin(header.section_tables), std::end(header.section_tables),
[](NCASectionTableEntry entry) { return entry.media_offset > 0; }); [](NCASectionTableEntry entry) { return entry.media_offset > 0; });
for (int i = 0; i < number_sections; ++i) { for (std::ptrdiff_t i = 0; i < number_sections; ++i) {
// Seek to beginning of this section. // Seek to beginning of this section.
NCASectionHeaderBlock block{}; NCASectionHeaderBlock block{};
if (sizeof(NCASectionHeaderBlock) != if (sizeof(NCASectionHeaderBlock) !=

View File

@@ -7,7 +7,7 @@
#include "common/common_funcs.h" #include "common/common_funcs.h"
#include "common/common_types.h" #include "common/common_types.h"
#include "common/swap.h" #include "common/swap.h"
#include "partition_filesystem.h" #include "core/file_sys/partition_filesystem.h"
namespace FileSys { namespace FileSys {
@@ -55,17 +55,6 @@ static bool IsValidNCA(const NCAHeader& header) {
// An implementation of VfsDirectory that represents a Nintendo Content Archive (NCA) conatiner. // An implementation of VfsDirectory that represents a Nintendo Content Archive (NCA) conatiner.
// After construction, use GetStatus to determine if the file is valid and ready to be used. // After construction, use GetStatus to determine if the file is valid and ready to be used.
class NCA : public ReadOnlyVfsDirectory { class NCA : public ReadOnlyVfsDirectory {
std::vector<VirtualDir> dirs{};
std::vector<VirtualFile> files{};
VirtualFile romfs = nullptr;
VirtualDir exefs = nullptr;
VirtualFile file;
NCAHeader header{};
Loader::ResultStatus status{};
public: public:
explicit NCA(VirtualFile file); explicit NCA(VirtualFile file);
Loader::ResultStatus GetStatus() const; Loader::ResultStatus GetStatus() const;
@@ -83,6 +72,18 @@ public:
protected: protected:
bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) override; bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) override;
private:
std::vector<VirtualDir> dirs;
std::vector<VirtualFile> files;
VirtualFile romfs = nullptr;
VirtualDir exefs = nullptr;
VirtualFile file;
NCAHeader header{};
Loader::ResultStatus status{};
}; };
} // namespace FileSys } // namespace FileSys

View File

@@ -6,8 +6,8 @@
#include "common/file_util.h" #include "common/file_util.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "core/file_sys/partition_filesystem.h" #include "core/file_sys/partition_filesystem.h"
#include "core/file_sys/vfs_offset.h"
#include "core/loader/loader.h" #include "core/loader/loader.h"
#include "vfs_offset.h"
namespace FileSys { namespace FileSys {

View File

@@ -14,8 +14,8 @@ std::string VfsFile::GetExtension() const {
size_t index = GetName().find_last_of('.'); size_t index = GetName().find_last_of('.');
if (index == std::string::npos) if (index == std::string::npos)
return ""; return "";
else
return GetName().substr(index + 1); return GetName().substr(index + 1);
} }
VfsDirectory::~VfsDirectory() = default; VfsDirectory::~VfsDirectory() = default;
@@ -41,7 +41,7 @@ std::vector<u8> VfsFile::ReadAllBytes() const {
} }
bool VfsFile::WriteByte(u8 data, size_t offset) { bool VfsFile::WriteByte(u8 data, size_t offset) {
return 1 == Write(&data, 1, offset); return Write(&data, 1, offset) == 1;
} }
size_t VfsFile::WriteBytes(std::vector<u8> data, size_t offset) { size_t VfsFile::WriteBytes(std::vector<u8> data, size_t offset) {
@@ -57,7 +57,7 @@ std::shared_ptr<VfsFile> VfsDirectory::GetFileRelative(const std::string& path)
if (vec.size() == 1) if (vec.size() == 1)
return GetFile(vec[0]); return GetFile(vec[0]);
auto dir = GetSubdirectory(vec[0]); auto dir = GetSubdirectory(vec[0]);
for (auto i = 1u; i < vec.size() - 1; ++i) { for (size_t i = 1; i < vec.size() - 1; ++i) {
if (dir == nullptr) if (dir == nullptr)
return nullptr; return nullptr;
dir = dir->GetSubdirectory(vec[i]); dir = dir->GetSubdirectory(vec[i]);
@@ -82,7 +82,7 @@ std::shared_ptr<VfsDirectory> VfsDirectory::GetDirectoryRelative(const std::stri
// return std::shared_ptr<VfsDirectory>(this); // return std::shared_ptr<VfsDirectory>(this);
return nullptr; return nullptr;
auto dir = GetSubdirectory(vec[0]); auto dir = GetSubdirectory(vec[0]);
for (auto i = 1u; i < vec.size(); ++i) { for (size_t i = 1; i < vec.size(); ++i) {
dir = dir->GetSubdirectory(vec[i]); dir = dir->GetSubdirectory(vec[i]);
} }
return dir; return dir;
@@ -97,19 +97,16 @@ std::shared_ptr<VfsDirectory> VfsDirectory::GetDirectoryAbsolute(const std::stri
std::shared_ptr<VfsFile> VfsDirectory::GetFile(const std::string& name) const { std::shared_ptr<VfsFile> VfsDirectory::GetFile(const std::string& name) const {
const auto& files = GetFiles(); const auto& files = GetFiles();
const auto& iter = std::find_if(files.begin(), files.end(), [&name](const auto& file1) { const auto iter = std::find_if(files.begin(), files.end(),
return name == file1->GetName(); [&name](const auto& file1) { return name == file1->GetName(); });
});
return iter == files.end() ? nullptr : *iter; return iter == files.end() ? nullptr : *iter;
} }
std::shared_ptr<VfsDirectory> VfsDirectory::GetSubdirectory(const std::string& name) const { std::shared_ptr<VfsDirectory> VfsDirectory::GetSubdirectory(const std::string& name) const {
// if (name == "" || name == "." || name == "/" || name == "\\")
// return std::shared_ptr<VfsDirectory>(const_cast<VfsDirectory*>(this));
const auto& subs = GetSubdirectories(); const auto& subs = GetSubdirectories();
const auto& iter = std::find_if( const auto iter = std::find_if(subs.begin(), subs.end(),
subs.begin(), subs.end(), [&name](const auto& file1) { return name == file1->GetName(); }); [&name](const auto& file1) { return name == file1->GetName(); });
return iter == subs.end() ? nullptr : std::move(*iter); return iter == subs.end() ? nullptr : *iter;
} }
bool VfsDirectory::IsRoot() const { bool VfsDirectory::IsRoot() const {
@@ -136,13 +133,15 @@ bool VfsDirectory::DeleteSubdirectoryRecursive(const std::string& name) {
return false; return false;
bool success = true; bool success = true;
for (const auto& file : dir->GetFiles()) for (const auto& file : dir->GetFiles()) {
if (!DeleteFile(file->GetName())) if (!DeleteFile(file->GetName()))
success = false; success = false;
}
for (const auto& sdir : dir->GetSubdirectories()) for (const auto& sdir : dir->GetSubdirectories()) {
if (!dir->DeleteSubdirectoryRecursive(sdir->GetName())) if (!dir->DeleteSubdirectoryRecursive(sdir->GetName()))
success = false; success = false;
}
return success; return success;
} }

View File

@@ -15,14 +15,11 @@
namespace FileSys { namespace FileSys {
struct VfsFile; struct VfsFile;
struct VfsDirectory; struct VfsDirectory;
} // namespace FileSys
// Convenience typedefs to use VfsDirectory and VfsFile // Convenience typedefs to use VfsDirectory and VfsFile
using VirtualDir = std::shared_ptr<FileSys::VfsDirectory>; using VirtualDir = std::shared_ptr<FileSys::VfsDirectory>;
using VirtualFile = std::shared_ptr<FileSys::VfsFile>; using VirtualFile = std::shared_ptr<FileSys::VfsFile>;
namespace FileSys {
// A class representing a file in an abstract filesystem. // A class representing a file in an abstract filesystem.
struct VfsFile : NonCopyable { struct VfsFile : NonCopyable {
virtual ~VfsFile(); virtual ~VfsFile();

View File

@@ -84,9 +84,11 @@ RealVfsDirectory::RealVfsDirectory(const std::string& path_, Mode perms_)
if (!FileUtil::Exists(path) && (perms == Mode::Write || perms == Mode::Append)) if (!FileUtil::Exists(path) && (perms == Mode::Write || perms == Mode::Append))
FileUtil::CreateDir(path); FileUtil::CreateDir(path);
unsigned size; unsigned size;
if (perms != Mode::Append) if (perms != Mode::Append) {
FileUtil::ForeachDirectoryEntry( FileUtil::ForeachDirectoryEntry(
&size, path, [this](auto x1, auto directory, auto filename) { &size, path,
[this](unsigned* entries_out, const std::string& directory,
const std::string& filename) {
std::string full_path = directory + DIR_SEP + filename; std::string full_path = directory + DIR_SEP + filename;
if (FileUtil::IsDirectory(full_path)) if (FileUtil::IsDirectory(full_path))
subdirectories.emplace_back( subdirectories.emplace_back(
@@ -95,6 +97,7 @@ RealVfsDirectory::RealVfsDirectory(const std::string& path_, Mode perms_)
files.emplace_back(std::make_shared<RealVfsFile>(full_path, perms)); files.emplace_back(std::make_shared<RealVfsFile>(full_path, perms));
return true; return true;
}); });
}
} }
std::vector<std::shared_ptr<VfsFile>> RealVfsDirectory::GetFiles() const { std::vector<std::shared_ptr<VfsFile>> RealVfsDirectory::GetFiles() const {
@@ -147,9 +150,6 @@ bool RealVfsDirectory::DeleteFile(const std::string& name) {
} }
bool RealVfsDirectory::Rename(const std::string& name) { bool RealVfsDirectory::Rename(const std::string& name) {
/* TODO(DarkLordZach): cppreference says for files, MSVC docs say for files/dirs.
* Does C rename(const char*, const char*) work on dirs?
*/
return FileUtil::Rename(path, parent_path + DIR_SEP + name); return FileUtil::Rename(path, parent_path + DIR_SEP + name);
} }

View File

@@ -18,14 +18,16 @@
namespace Service::FileSystem { namespace Service::FileSystem {
static VirtualDir GetDirectoryRelativeWrapped(VirtualDir base, const std::string& dir_name) { static FileSys::VirtualDir GetDirectoryRelativeWrapped(FileSys::VirtualDir base,
const std::string& dir_name) {
if (dir_name == "." || dir_name == "" || dir_name == "/" || dir_name == "\\") if (dir_name == "." || dir_name == "" || dir_name == "/" || dir_name == "\\")
return base; return base;
return base->GetDirectoryRelative(dir_name); return base->GetDirectoryRelative(dir_name);
} }
VfsDirectoryServiceWrapper::VfsDirectoryServiceWrapper(VirtualDir backing_) : backing(backing_) {} VfsDirectoryServiceWrapper::VfsDirectoryServiceWrapper(FileSys::VirtualDir backing_)
: backing(backing_) {}
std::string VfsDirectoryServiceWrapper::GetName() const { std::string VfsDirectoryServiceWrapper::GetName() const {
return backing->GetName(); return backing->GetName();
@@ -122,16 +124,16 @@ ResultCode VfsDirectoryServiceWrapper::RenameDirectory(const std::string& src_pa
return ResultCode(-1); return ResultCode(-1);
} }
ResultVal<VirtualFile> VfsDirectoryServiceWrapper::OpenFile(const std::string& path, ResultVal<FileSys::VirtualFile> VfsDirectoryServiceWrapper::OpenFile(const std::string& path,
FileSys::Mode mode) const { FileSys::Mode mode) const {
auto file = backing->GetFileRelative(path); auto file = backing->GetFileRelative(path);
if (file == nullptr) if (file == nullptr)
return FileSys::ERROR_PATH_NOT_FOUND; return FileSys::ERROR_PATH_NOT_FOUND;
// TODO(DarkLordZach): Error checking/result modification with different modes. // TODO(DarkLordZach): Error checking/result modification with different modes.
return MakeResult<VirtualFile>(file); return MakeResult<FileSys::VirtualFile>(file);
} }
ResultVal<VirtualDir> VfsDirectoryServiceWrapper::OpenDirectory(const std::string& path) { ResultVal<FileSys::VirtualDir> VfsDirectoryServiceWrapper::OpenDirectory(const std::string& path) {
auto dir = GetDirectoryRelativeWrapped(backing, path); auto dir = GetDirectoryRelativeWrapped(backing, path);
if (dir == nullptr) if (dir == nullptr)
return ResultCode(-1); return ResultCode(-1);
@@ -141,7 +143,7 @@ ResultVal<VirtualDir> VfsDirectoryServiceWrapper::OpenDirectory(const std::strin
u64 VfsDirectoryServiceWrapper::GetFreeSpaceSize() const { u64 VfsDirectoryServiceWrapper::GetFreeSpaceSize() const {
// TODO(DarkLordZach): Infinite? Actual? Is this actually used productively or...? // TODO(DarkLordZach): Infinite? Actual? Is this actually used productively or...?
if (backing->IsWritable()) if (backing->IsWritable())
return -1; return std::numeric_limits<u64>::max();
return 0; return 0;
} }
@@ -164,7 +166,7 @@ ResultVal<FileSys::EntryType> VfsDirectoryServiceWrapper::GetEntryType(
// registration time. // registration time.
struct SaveDataDeferredFilesystem : DeferredFilesystem { struct SaveDataDeferredFilesystem : DeferredFilesystem {
protected: protected:
VirtualDir CreateFilesystem() override { FileSys::VirtualDir CreateFilesystem() override {
u64 title_id = Core::CurrentProcess()->program_id; u64 title_id = Core::CurrentProcess()->program_id;
// TODO(DarkLordZach): Users // TODO(DarkLordZach): Users
u32 user_id = 0; u32 user_id = 0;
@@ -182,7 +184,7 @@ protected:
* is never removed until UnregisterFileSystems is called. * is never removed until UnregisterFileSystems is called.
*/ */
static boost::container::flat_map<Type, std::unique_ptr<DeferredFilesystem>> filesystem_map; static boost::container::flat_map<Type, std::unique_ptr<DeferredFilesystem>> filesystem_map;
static VirtualFile filesystem_romfs = nullptr; static FileSys::VirtualFile filesystem_romfs = nullptr;
ResultCode RegisterFileSystem(std::unique_ptr<DeferredFilesystem>&& factory, Type type) { ResultCode RegisterFileSystem(std::unique_ptr<DeferredFilesystem>&& factory, Type type) {
auto result = filesystem_map.emplace(type, std::move(factory)); auto result = filesystem_map.emplace(type, std::move(factory));
@@ -195,7 +197,7 @@ ResultCode RegisterFileSystem(std::unique_ptr<DeferredFilesystem>&& factory, Typ
return RESULT_SUCCESS; return RESULT_SUCCESS;
} }
ResultCode RegisterRomFS(VirtualFile filesystem) { ResultCode RegisterRomFS(FileSys::VirtualFile filesystem) {
ASSERT_MSG(filesystem_romfs == nullptr, ASSERT_MSG(filesystem_romfs == nullptr,
"Tried to register more than one system with same id code"); "Tried to register more than one system with same id code");
@@ -205,7 +207,7 @@ ResultCode RegisterRomFS(VirtualFile filesystem) {
return RESULT_SUCCESS; return RESULT_SUCCESS;
} }
ResultVal<VirtualDir> OpenFileSystem(Type type) { ResultVal<FileSys::VirtualDir> OpenFileSystem(Type type) {
LOG_TRACE(Service_FS, "Opening FileSystem with type={}", static_cast<u32>(type)); LOG_TRACE(Service_FS, "Opening FileSystem with type={}", static_cast<u32>(type));
auto itr = filesystem_map.find(type); auto itr = filesystem_map.find(type);
@@ -217,7 +219,7 @@ ResultVal<VirtualDir> OpenFileSystem(Type type) {
return MakeResult(itr->second->Get()); return MakeResult(itr->second->Get());
} }
ResultVal<VirtualFile> OpenRomFS() { ResultVal<FileSys::VirtualFile> OpenRomFS() {
if (filesystem_romfs == nullptr) if (filesystem_romfs == nullptr)
return ResultCode(-1); return ResultCode(-1);
return MakeResult(filesystem_romfs); return MakeResult(filesystem_romfs);

View File

@@ -35,10 +35,8 @@ enum class Type {
// pointers and booleans. This makes using a VfsDirectory with switch services much easier and // pointers and booleans. This makes using a VfsDirectory with switch services much easier and
// avoids repetitive code. // avoids repetitive code.
class VfsDirectoryServiceWrapper { class VfsDirectoryServiceWrapper {
VirtualDir backing;
public: public:
explicit VfsDirectoryServiceWrapper(VirtualDir backing); explicit VfsDirectoryServiceWrapper(FileSys::VirtualDir backing);
/** /**
* Get a descriptive name for the archive (e.g. "RomFS", "SaveData", etc.) * Get a descriptive name for the archive (e.g. "RomFS", "SaveData", etc.)
@@ -103,14 +101,14 @@ public:
* @param mode Mode to open the file with * @param mode Mode to open the file with
* @return Opened file, or error code * @return Opened file, or error code
*/ */
ResultVal<VirtualFile> OpenFile(const std::string& path, FileSys::Mode mode) const; ResultVal<FileSys::VirtualFile> OpenFile(const std::string& path, FileSys::Mode mode) const;
/** /**
* Open a directory specified by its path * Open a directory specified by its path
* @param path Path relative to the archive * @param path Path relative to the archive
* @return Opened directory, or error code * @return Opened directory, or error code
*/ */
ResultVal<VirtualDir> OpenDirectory(const std::string& path); ResultVal<FileSys::VirtualDir> OpenDirectory(const std::string& path);
/** /**
* Get the free space * Get the free space
@@ -123,6 +121,9 @@ public:
* @return The type of the specified path or error code * @return The type of the specified path or error code
*/ */
ResultVal<FileSys::EntryType> GetEntryType(const std::string& path) const; ResultVal<FileSys::EntryType> GetEntryType(const std::string& path) const;
private:
FileSys::VirtualDir backing;
}; };
// A class that deferres the creation of a filesystem until a later time. // A class that deferres the creation of a filesystem until a later time.
@@ -130,26 +131,26 @@ public:
// Construct this with a filesystem (VirtualDir) to avoid the deferrence feature or override the // Construct this with a filesystem (VirtualDir) to avoid the deferrence feature or override the
// CreateFilesystem method which will be called on first use. // CreateFilesystem method which will be called on first use.
struct DeferredFilesystem { struct DeferredFilesystem {
DeferredFilesystem(){}; DeferredFilesystem() = default;
explicit DeferredFilesystem(VirtualDir vfs_directory) : fs(vfs_directory) {} explicit DeferredFilesystem(FileSys::VirtualDir vfs_directory) : fs(std::move(vfs_directory)) {}
VirtualDir Get() { FileSys::VirtualDir Get() {
if (fs == nullptr) if (fs == nullptr)
fs = CreateFilesystem(); fs = CreateFilesystem();
return fs; return fs;
} }
~DeferredFilesystem() = default; virtual ~DeferredFilesystem() = default;
protected: protected:
virtual VirtualDir CreateFilesystem() { virtual FileSys::VirtualDir CreateFilesystem() {
return fs; return fs;
} }
private: private:
VirtualDir fs; FileSys::VirtualDir fs;
}; };
/** /**
@@ -159,7 +160,7 @@ private:
*/ */
ResultCode RegisterFileSystem(std::unique_ptr<DeferredFilesystem>&& fs, Type type); ResultCode RegisterFileSystem(std::unique_ptr<DeferredFilesystem>&& fs, Type type);
ResultCode RegisterRomFS(VirtualFile fs); ResultCode RegisterRomFS(FileSys::VirtualFile fs);
/** /**
* Opens a file system * Opens a file system
@@ -167,9 +168,9 @@ ResultCode RegisterRomFS(VirtualFile fs);
* @param path Path to the file system, used with Binary paths * @param path Path to the file system, used with Binary paths
* @return FileSys::FileSystemBackend interface to the file system * @return FileSys::FileSystemBackend interface to the file system
*/ */
ResultVal<VirtualDir> OpenFileSystem(Type type); ResultVal<FileSys::VirtualDir> OpenFileSystem(Type type);
ResultVal<VirtualFile> OpenRomFS(); ResultVal<FileSys::VirtualFile> OpenRomFS();
/** /**
* Formats a file system * Formats a file system

View File

@@ -19,7 +19,8 @@ namespace Service::FileSystem {
class IStorage final : public ServiceFramework<IStorage> { class IStorage final : public ServiceFramework<IStorage> {
public: public:
IStorage(VirtualFile backend_) : ServiceFramework("IStorage"), backend(backend_) { IStorage(FileSys::VirtualFile backend_)
: ServiceFramework("IStorage"), backend(std::move(backend_)) {
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &IStorage::Read, "Read"}, {1, nullptr, "Write"}, {2, nullptr, "Flush"}, {0, &IStorage::Read, "Read"}, {1, nullptr, "Write"}, {2, nullptr, "Flush"},
{3, nullptr, "SetSize"}, {4, nullptr, "GetSize"}, {5, nullptr, "OperateRange"}, {3, nullptr, "SetSize"}, {4, nullptr, "GetSize"}, {5, nullptr, "OperateRange"},
@@ -28,7 +29,7 @@ public:
} }
private: private:
VirtualFile backend; FileSys::VirtualFile backend;
void Read(Kernel::HLERequestContext& ctx) { void Read(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
@@ -68,7 +69,8 @@ private:
class IFile final : public ServiceFramework<IFile> { class IFile final : public ServiceFramework<IFile> {
public: public:
explicit IFile(VirtualFile backend_) : ServiceFramework("IFile"), backend(backend_) { explicit IFile(FileSys::VirtualFile backend_)
: ServiceFramework("IFile"), backend(std::move(backend_)) {
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &IFile::Read, "Read"}, {1, &IFile::Write, "Write"}, {0, &IFile::Read, "Read"}, {1, &IFile::Write, "Write"},
{2, &IFile::Flush, "Flush"}, {3, &IFile::SetSize, "SetSize"}, {2, &IFile::Flush, "Flush"}, {3, &IFile::SetSize, "SetSize"},
@@ -78,7 +80,7 @@ public:
} }
private: private:
VirtualFile backend; FileSys::VirtualFile backend;
void Read(Kernel::HLERequestContext& ctx) { void Read(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
@@ -180,9 +182,23 @@ private:
} }
}; };
template <typename T>
static void BuildEntryIndex(std::vector<FileSys::Entry>& entries, const std::vector<T>& new_data,
FileSys::EntryType type) {
for (const auto& new_entry : new_data) {
FileSys::Entry entry;
entry.filename[0] = '\0';
std::strncat(entry.filename, new_entry->GetName().c_str(), FileSys::FILENAME_LENGTH - 1);
entry.type = type;
entry.file_size = new_entry->GetSize();
entries.emplace_back(std::move(entry));
}
}
class IDirectory final : public ServiceFramework<IDirectory> { class IDirectory final : public ServiceFramework<IDirectory> {
public: public:
explicit IDirectory(VirtualDir backend_) : ServiceFramework("IDirectory"), backend(backend_) { explicit IDirectory(FileSys::VirtualDir backend_)
: ServiceFramework("IDirectory"), backend(std::move(backend_)) {
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &IDirectory::Read, "Read"}, {0, &IDirectory::Read, "Read"},
{1, &IDirectory::GetEntryCount, "GetEntryCount"}, {1, &IDirectory::GetEntryCount, "GetEntryCount"},
@@ -190,27 +206,12 @@ public:
RegisterHandlers(functions); RegisterHandlers(functions);
// Build entry index now to save time later. // Build entry index now to save time later.
for (const auto& file : backend->GetFiles()) { BuildEntryIndex(entries, backend->GetFiles(), FileSys::File);
FileSys::Entry entry; BuildEntryIndex(entries, backend->GetSubdirectories(), FileSys::Directory);
entry.filename[0] = '\0';
strncat(entry.filename, file->GetName().c_str(), FileSys::FILENAME_LENGTH - 1);
entry.type = FileSys::File;
entry.file_size = file->GetSize();
entries.emplace_back(entry);
}
for (const auto& dir : backend->GetSubdirectories()) {
FileSys::Entry entry;
entry.filename[0] = '\0';
strncat(entry.filename, dir->GetName().c_str(), FileSys::FILENAME_LENGTH - 1);
entry.type = FileSys::Directory;
entry.file_size = dir->GetSize();
entries.emplace_back(entry);
}
} }
private: private:
VirtualDir backend; FileSys::VirtualDir backend;
std::vector<FileSys::Entry> entries; std::vector<FileSys::Entry> entries;
u64 next_entry_index = 0; u64 next_entry_index = 0;
@@ -257,7 +258,7 @@ private:
class IFileSystem final : public ServiceFramework<IFileSystem> { class IFileSystem final : public ServiceFramework<IFileSystem> {
public: public:
explicit IFileSystem(VirtualDir backend) explicit IFileSystem(FileSys::VirtualDir backend)
: ServiceFramework("IFileSystem"), backend(std::move(backend)) { : ServiceFramework("IFileSystem"), backend(std::move(backend)) {
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &IFileSystem::CreateFile, "CreateFile"}, {0, &IFileSystem::CreateFile, "CreateFile"},
@@ -517,7 +518,7 @@ void FSP_SRV::TryLoadRomFS() {
} }
auto res = OpenRomFS(); auto res = OpenRomFS();
if (res.Succeeded()) { if (res.Succeeded()) {
romfs = res.Unwrap(); romfs = std::move(res.Unwrap());
} }
} }

View File

@@ -29,7 +29,7 @@ private:
void OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx); void OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx);
void OpenRomStorage(Kernel::HLERequestContext& ctx); void OpenRomStorage(Kernel::HLERequestContext& ctx);
VirtualFile romfs; FileSys::VirtualFile romfs;
}; };
} // namespace Service::FileSystem } // namespace Service::FileSystem

View File

@@ -45,10 +45,10 @@ static std::string FindRomFS(const std::string& directory) {
return filepath_romfs; return filepath_romfs;
} }
AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(VirtualFile file) AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile file)
: AppLoader(file) {} : AppLoader(std::move(file)) {}
FileType AppLoader_DeconstructedRomDirectory::IdentifyType(VirtualFile file) { FileType AppLoader_DeconstructedRomDirectory::IdentifyType(const FileSys::VirtualFile& file) {
if (FileSys::IsDirectoryExeFS(file->GetContainingDirectory())) { if (FileSys::IsDirectoryExeFS(file->GetContainingDirectory())) {
return FileType::DeconstructedRomDirectory; return FileType::DeconstructedRomDirectory;
} }
@@ -62,8 +62,8 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(
return ResultStatus::ErrorAlreadyLoaded; return ResultStatus::ErrorAlreadyLoaded;
} }
const VirtualDir dir = file->GetContainingDirectory(); const FileSys::VirtualDir dir = file->GetContainingDirectory();
const VirtualFile npdm = dir->GetFile("main.npdm"); const FileSys::VirtualFile npdm = dir->GetFile("main.npdm");
if (npdm == nullptr) if (npdm == nullptr)
return ResultStatus::ErrorInvalidFormat; return ResultStatus::ErrorInvalidFormat;
@@ -83,7 +83,7 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(
for (const auto& module : {"rtld", "main", "subsdk0", "subsdk1", "subsdk2", "subsdk3", for (const auto& module : {"rtld", "main", "subsdk0", "subsdk1", "subsdk2", "subsdk3",
"subsdk4", "subsdk5", "subsdk6", "subsdk7", "sdk"}) { "subsdk4", "subsdk5", "subsdk6", "subsdk7", "sdk"}) {
const VAddr load_addr = next_load_addr; const VAddr load_addr = next_load_addr;
const VirtualFile module_file = dir->GetFile(module); const FileSys::VirtualFile module_file = dir->GetFile(module);
if (module_file != nullptr) if (module_file != nullptr)
next_load_addr = AppLoader_NSO::LoadModule(module_file, load_addr); next_load_addr = AppLoader_NSO::LoadModule(module_file, load_addr);
if (next_load_addr) { if (next_load_addr) {
@@ -103,9 +103,10 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(
// Find the RomFS by searching for a ".romfs" file in this directory // Find the RomFS by searching for a ".romfs" file in this directory
const auto& files = dir->GetFiles(); const auto& files = dir->GetFiles();
const auto romfs_iter = std::find_if(files.begin(), files.end(), [](const VirtualFile& file) { const auto romfs_iter =
return file->GetName().find(".romfs") != std::string::npos; std::find_if(files.begin(), files.end(), [](const FileSys::VirtualFile& file) {
}); return file->GetName().find(".romfs") != std::string::npos;
});
// TODO(DarkLordZach): Identify RomFS if its a subdirectory. // TODO(DarkLordZach): Identify RomFS if its a subdirectory.
const auto romfs = (romfs_iter == files.end()) ? nullptr : *romfs_iter; const auto romfs = (romfs_iter == files.end()) ? nullptr : *romfs_iter;

View File

@@ -20,14 +20,14 @@ namespace Loader {
*/ */
class AppLoader_DeconstructedRomDirectory final : public AppLoader { class AppLoader_DeconstructedRomDirectory final : public AppLoader {
public: public:
AppLoader_DeconstructedRomDirectory(VirtualFile main_file); explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile main_file);
/** /**
* Returns the type of the file * Returns the type of the file
* @param file std::shared_ptr<VfsFile> open file * @param file std::shared_ptr<VfsFile> open file
* @return FileType found, or FileType::Error if this loader doesn't know it * @return FileType found, or FileType::Error if this loader doesn't know it
*/ */
static FileType IdentifyType(VirtualFile file); static FileType IdentifyType(const FileSys::VirtualFile& file);
FileType GetFileType() override { FileType GetFileType() override {
return IdentifyType(file); return IdentifyType(file);

View File

@@ -365,9 +365,9 @@ SectionID ElfReader::GetSectionByName(const char* name, int firstSection) const
namespace Loader { namespace Loader {
AppLoader_ELF::AppLoader_ELF(VirtualFile file) : AppLoader(file) {} AppLoader_ELF::AppLoader_ELF(FileSys::VirtualFile file) : AppLoader(std::move(file)) {}
FileType AppLoader_ELF::IdentifyType(VirtualFile file) { FileType AppLoader_ELF::IdentifyType(const FileSys::VirtualFile& file) {
static constexpr u16 ELF_MACHINE_ARM{0x28}; static constexpr u16 ELF_MACHINE_ARM{0x28};
u32 magic = 0; u32 magic = 0;

View File

@@ -16,14 +16,14 @@ namespace Loader {
/// Loads an ELF/AXF file /// Loads an ELF/AXF file
class AppLoader_ELF final : public AppLoader { class AppLoader_ELF final : public AppLoader {
public: public:
AppLoader_ELF(VirtualFile file); explicit AppLoader_ELF(FileSys::VirtualFile file);
/** /**
* Returns the type of the file * Returns the type of the file
* @param file std::shared_ptr<VfsFile> open file * @param file std::shared_ptr<VfsFile> open file
* @return FileType found, or FileType::Error if this loader doesn't know it * @return FileType found, or FileType::Error if this loader doesn't know it
*/ */
static FileType IdentifyType(VirtualFile file); static FileType IdentifyType(const FileSys::VirtualFile& file);
FileType GetFileType() override { FileType GetFileType() override {
return IdentifyType(file); return IdentifyType(file);

View File

@@ -22,7 +22,7 @@ const std::initializer_list<Kernel::AddressMapping> default_address_mappings = {
{0x1F000000, 0x600000, false}, // entire VRAM {0x1F000000, 0x600000, false}, // entire VRAM
}; };
FileType IdentifyFile(VirtualFile file) { FileType IdentifyFile(FileSys::VirtualFile file) {
FileType type; FileType type;
#define CHECK_TYPE(loader) \ #define CHECK_TYPE(loader) \
@@ -42,7 +42,7 @@ FileType IdentifyFile(VirtualFile file) {
} }
FileType IdentifyFile(const std::string& file_name) { FileType IdentifyFile(const std::string& file_name) {
return IdentifyFile(VirtualFile(std::make_shared<FileSys::RealVfsFile>(file_name))); return IdentifyFile(FileSys::VirtualFile(std::make_shared<FileSys::RealVfsFile>(file_name)));
} }
FileType GuessFromExtension(const std::string& extension_) { FileType GuessFromExtension(const std::string& extension_) {
@@ -88,35 +88,35 @@ const char* GetFileTypeString(FileType type) {
* @param filepath the file full path (with name) * @param filepath the file full path (with name)
* @return std::unique_ptr<AppLoader> a pointer to a loader object; nullptr for unsupported type * @return std::unique_ptr<AppLoader> a pointer to a loader object; nullptr for unsupported type
*/ */
static std::unique_ptr<AppLoader> GetFileLoader(VirtualFile file, FileType type) { static std::unique_ptr<AppLoader> GetFileLoader(FileSys::VirtualFile file, FileType type) {
switch (type) { switch (type) {
// Standard ELF file format. // Standard ELF file format.
case FileType::ELF: case FileType::ELF:
return std::make_unique<AppLoader_ELF>(file); return std::make_unique<AppLoader_ELF>(std::move(file));
// NX NSO file format. // NX NSO file format.
case FileType::NSO: case FileType::NSO:
return std::make_unique<AppLoader_NSO>(file); return std::make_unique<AppLoader_NSO>(std::move(file));
// NX NRO file format. // NX NRO file format.
case FileType::NRO: case FileType::NRO:
return std::make_unique<AppLoader_NRO>(file); return std::make_unique<AppLoader_NRO>(std::move(file));
// NX NCA file format. // NX NCA file format.
case FileType::NCA: case FileType::NCA:
return std::make_unique<AppLoader_NCA>(file); return std::make_unique<AppLoader_NCA>(std::move(file));
// NX deconstructed ROM directory. // NX deconstructed ROM directory.
case FileType::DeconstructedRomDirectory: case FileType::DeconstructedRomDirectory:
return std::make_unique<AppLoader_DeconstructedRomDirectory>(file); return std::make_unique<AppLoader_DeconstructedRomDirectory>(std::move(file));
default: default:
return nullptr; return nullptr;
} }
} }
std::unique_ptr<AppLoader> GetLoader(VirtualFile file) { std::unique_ptr<AppLoader> GetLoader(FileSys::VirtualFile file) {
FileType type = IdentifyFile(file); FileType type = IdentifyFile(file);
FileType filename_type = GuessFromExtension(file->GetExtension()); FileType filename_type = GuessFromExtension(file->GetExtension());
@@ -128,7 +128,7 @@ std::unique_ptr<AppLoader> GetLoader(VirtualFile file) {
LOG_DEBUG(Loader, "Loading file {} as {}...", file->GetName(), GetFileTypeString(type)); LOG_DEBUG(Loader, "Loading file {} as {}...", file->GetName(), GetFileTypeString(type));
return GetFileLoader(file, type); return GetFileLoader(std::move(file), type);
} }
} // namespace Loader } // namespace Loader

View File

@@ -39,7 +39,7 @@ enum class FileType {
* @param file open file * @param file open file
* @return FileType of file * @return FileType of file
*/ */
FileType IdentifyFile(VirtualFile file); FileType IdentifyFile(FileSys::VirtualFile file);
/** /**
* Identifies the type of a bootable file based on the magic value in its header. * Identifies the type of a bootable file based on the magic value in its header.
@@ -79,7 +79,7 @@ enum class ResultStatus {
/// Interface for loading an application /// Interface for loading an application
class AppLoader : NonCopyable { class AppLoader : NonCopyable {
public: public:
AppLoader(VirtualFile file) : file(std::move(file)) {} AppLoader(FileSys::VirtualFile file) : file(std::move(file)) {}
virtual ~AppLoader() {} virtual ~AppLoader() {}
/** /**
@@ -157,7 +157,7 @@ public:
* @param file The file containing the RomFS * @param file The file containing the RomFS
* @return ResultStatus result of function * @return ResultStatus result of function
*/ */
virtual ResultStatus ReadRomFS(VirtualFile& dir) { virtual ResultStatus ReadRomFS(FileSys::VirtualFile& dir) {
return ResultStatus::ErrorNotImplemented; return ResultStatus::ErrorNotImplemented;
} }
@@ -167,7 +167,7 @@ public:
* @param file The file containing the RomFS * @param file The file containing the RomFS
* @return ResultStatus result of function * @return ResultStatus result of function
*/ */
virtual ResultStatus ReadUpdateRomFS(VirtualFile& file) { virtual ResultStatus ReadUpdateRomFS(FileSys::VirtualFile& file) {
return ResultStatus::ErrorNotImplemented; return ResultStatus::ErrorNotImplemented;
} }
@@ -181,7 +181,7 @@ public:
} }
protected: protected:
VirtualFile file; FileSys::VirtualFile file;
bool is_loaded = false; bool is_loaded = false;
}; };
@@ -196,6 +196,6 @@ extern const std::initializer_list<Kernel::AddressMapping> default_address_mappi
* @param filename String filename of bootable file * @param filename String filename of bootable file
* @return best loader for this file * @return best loader for this file
*/ */
std::unique_ptr<AppLoader> GetLoader(VirtualFile file); std::unique_ptr<AppLoader> GetLoader(FileSys::VirtualFile file);
} // namespace Loader } // namespace Loader

View File

@@ -18,9 +18,9 @@
namespace Loader { namespace Loader {
AppLoader_NCA::AppLoader_NCA(VirtualFile file) : AppLoader(file) {} AppLoader_NCA::AppLoader_NCA(FileSys::VirtualFile file) : AppLoader(file) {}
FileType AppLoader_NCA::IdentifyType(VirtualFile file) { FileType AppLoader_NCA::IdentifyType(const FileSys::VirtualFile& file) {
// TODO(DarkLordZach): Assuming everything is decrypted. Add crypto support. // TODO(DarkLordZach): Assuming everything is decrypted. Add crypto support.
FileSys::NCAHeader header{}; FileSys::NCAHeader header{};
if (sizeof(FileSys::NCAHeader) != file->ReadObject(&header)) if (sizeof(FileSys::NCAHeader) != file->ReadObject(&header))

View File

@@ -16,14 +16,14 @@ namespace Loader {
/// Loads an NCA file /// Loads an NCA file
class AppLoader_NCA final : public AppLoader { class AppLoader_NCA final : public AppLoader {
public: public:
AppLoader_NCA(VirtualFile file); explicit AppLoader_NCA(FileSys::VirtualFile file);
/** /**
* Returns the type of the file * Returns the type of the file
* @param file std::shared_ptr<VfsFile> open file * @param file std::shared_ptr<VfsFile> open file
* @return FileType found, or FileType::Error if this loader doesn't know it * @return FileType found, or FileType::Error if this loader doesn't know it
*/ */
static FileType IdentifyType(VirtualFile file); static FileType IdentifyType(const FileSys::VirtualFile& file);
FileType GetFileType() override { FileType GetFileType() override {
return IdentifyType(file); return IdentifyType(file);

View File

@@ -47,9 +47,9 @@ struct ModHeader {
}; };
static_assert(sizeof(ModHeader) == 0x1c, "ModHeader has incorrect size."); static_assert(sizeof(ModHeader) == 0x1c, "ModHeader has incorrect size.");
AppLoader_NRO::AppLoader_NRO(VirtualFile file) : AppLoader(file) {} AppLoader_NRO::AppLoader_NRO(FileSys::VirtualFile file) : AppLoader(file) {}
FileType AppLoader_NRO::IdentifyType(VirtualFile file) { FileType AppLoader_NRO::IdentifyType(const FileSys::VirtualFile& file) {
// Read NSO header // Read NSO header
NroHeader nro_header{}; NroHeader nro_header{};
if (sizeof(NroHeader) != file->ReadObject(&nro_header)) { if (sizeof(NroHeader) != file->ReadObject(&nro_header)) {
@@ -65,7 +65,7 @@ static constexpr u32 PageAlignSize(u32 size) {
return (size + Memory::PAGE_MASK) & ~Memory::PAGE_MASK; return (size + Memory::PAGE_MASK) & ~Memory::PAGE_MASK;
} }
bool AppLoader_NRO::LoadNro(VirtualFile file, VAddr load_base) { bool AppLoader_NRO::LoadNro(FileSys::VirtualFile file, VAddr load_base) {
// Read NSO header // Read NSO header
NroHeader nro_header{}; NroHeader nro_header{};
if (sizeof(NroHeader) != file->ReadObject(&nro_header)) { if (sizeof(NroHeader) != file->ReadObject(&nro_header)) {

View File

@@ -15,14 +15,14 @@ namespace Loader {
/// Loads an NRO file /// Loads an NRO file
class AppLoader_NRO final : public AppLoader, Linker { class AppLoader_NRO final : public AppLoader, Linker {
public: public:
AppLoader_NRO(VirtualFile file); AppLoader_NRO(FileSys::VirtualFile file);
/** /**
* Returns the type of the file * Returns the type of the file
* @param file std::shared_ptr<VfsFile> open file * @param file std::shared_ptr<VfsFile> open file
* @return FileType found, or FileType::Error if this loader doesn't know it * @return FileType found, or FileType::Error if this loader doesn't know it
*/ */
static FileType IdentifyType(VirtualFile file); static FileType IdentifyType(const FileSys::VirtualFile& file);
FileType GetFileType() override { FileType GetFileType() override {
return IdentifyType(file); return IdentifyType(file);
@@ -31,7 +31,7 @@ public:
ResultStatus Load(Kernel::SharedPtr<Kernel::Process>& process) override; ResultStatus Load(Kernel::SharedPtr<Kernel::Process>& process) override;
private: private:
bool LoadNro(VirtualFile file, VAddr load_base); bool LoadNro(FileSys::VirtualFile file, VAddr load_base);
}; };
} // namespace Loader } // namespace Loader

View File

@@ -37,7 +37,7 @@ struct NsoHeader {
std::array<u32_le, 3> segments_compressed_size; std::array<u32_le, 3> segments_compressed_size;
}; };
static_assert(sizeof(NsoHeader) == 0x6c, "NsoHeader has incorrect size."); static_assert(sizeof(NsoHeader) == 0x6c, "NsoHeader has incorrect size.");
static_assert(std::is_trivially_copyable<NsoHeader>::value, "NsoHeader isn't trivially copyable."); static_assert(std::is_trivially_copyable_v<NsoHeader>, "NsoHeader isn't trivially copyable.");
struct ModHeader { struct ModHeader {
u32_le magic; u32_le magic;
@@ -50,9 +50,9 @@ struct ModHeader {
}; };
static_assert(sizeof(ModHeader) == 0x1c, "ModHeader has incorrect size."); static_assert(sizeof(ModHeader) == 0x1c, "ModHeader has incorrect size.");
AppLoader_NSO::AppLoader_NSO(VirtualFile file) : AppLoader(file) {} AppLoader_NSO::AppLoader_NSO(FileSys::VirtualFile file) : AppLoader(std::move(file)) {}
FileType AppLoader_NSO::IdentifyType(VirtualFile file) { FileType AppLoader_NSO::IdentifyType(const FileSys::VirtualFile& file) {
u32 magic = 0; u32 magic = 0;
file->ReadObject(&magic); file->ReadObject(&magic);
@@ -95,7 +95,7 @@ static constexpr u32 PageAlignSize(u32 size) {
return (size + Memory::PAGE_MASK) & ~Memory::PAGE_MASK; return (size + Memory::PAGE_MASK) & ~Memory::PAGE_MASK;
} }
VAddr AppLoader_NSO::LoadModule(VirtualFile file, VAddr load_base) { VAddr AppLoader_NSO::LoadModule(FileSys::VirtualFile file, VAddr load_base) {
if (file == nullptr) if (file == nullptr)
return {}; return {};

View File

@@ -15,20 +15,20 @@ namespace Loader {
/// Loads an NSO file /// Loads an NSO file
class AppLoader_NSO final : public AppLoader, Linker { class AppLoader_NSO final : public AppLoader, Linker {
public: public:
AppLoader_NSO(VirtualFile file); explicit AppLoader_NSO(FileSys::VirtualFile file);
/** /**
* Returns the type of the file * Returns the type of the file
* @param file std::shared_ptr<VfsFile> open file * @param file std::shared_ptr<VfsFile> open file
* @return FileType found, or FileType::Error if this loader doesn't know it * @return FileType found, or FileType::Error if this loader doesn't know it
*/ */
static FileType IdentifyType(VirtualFile file); static FileType IdentifyType(const FileSys::VirtualFile& file);
FileType GetFileType() override { FileType GetFileType() override {
return IdentifyType(file); return IdentifyType(file);
} }
static VAddr LoadModule(VirtualFile file, VAddr load_base); static VAddr LoadModule(FileSys::VirtualFile file, VAddr load_base);
ResultStatus Load(Kernel::SharedPtr<Kernel::Process>& process) override; ResultStatus Load(Kernel::SharedPtr<Kernel::Process>& process) override;
}; };