Review fixes + other stuff
This commit is contained in:
@@ -17,7 +17,10 @@ constexpr u64 SECTION_HEADER_OFFSET = 0x400;
|
||||
|
||||
constexpr u32 IVFC_MAX_LEVEL = 6;
|
||||
|
||||
enum class NCASectionFilesystemType : u8 { PFS0 = 0x2, ROMFS = 0x3 };
|
||||
enum class NCASectionFilesystemType : u8 {
|
||||
PFS0 = 0x2,
|
||||
ROMFS = 0x3,
|
||||
};
|
||||
|
||||
struct NCASectionHeaderBlock {
|
||||
INSERT_PADDING_BYTES(3);
|
||||
|
||||
@@ -11,7 +11,13 @@
|
||||
|
||||
namespace FileSys {
|
||||
|
||||
enum class NCAContentType : u8 { Program = 0, Meta = 1, Control = 2, Manual = 3, Data = 4 };
|
||||
enum class NCAContentType : u8 {
|
||||
Program = 0,
|
||||
Meta = 1,
|
||||
Control = 2,
|
||||
Manual = 3,
|
||||
Data = 4,
|
||||
};
|
||||
|
||||
struct NCASectionTableEntry {
|
||||
u32_le media_offset;
|
||||
@@ -42,12 +48,12 @@ struct NCAHeader {
|
||||
};
|
||||
static_assert(sizeof(NCAHeader) == 0x400, "NCAHeader has incorrect size.");
|
||||
|
||||
static bool IsDirectoryExeFS(std::shared_ptr<FileSys::VfsDirectory> pfs) {
|
||||
inline bool IsDirectoryExeFS(std::shared_ptr<FileSys::VfsDirectory> pfs) {
|
||||
// According to switchbrew, an exefs must only contain these two files:
|
||||
return pfs->GetFile("main") != nullptr && pfs->GetFile("main.npdm") != nullptr;
|
||||
}
|
||||
|
||||
static bool IsValidNCA(const NCAHeader& header) {
|
||||
inline bool IsValidNCA(const NCAHeader& header) {
|
||||
return header.magic == Common::MakeMagic('N', 'C', 'A', '2') ||
|
||||
header.magic == Common::MakeMagic('N', 'C', 'A', '3');
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace FileSys {
|
||||
namespace ErrCodes {
|
||||
enum {
|
||||
NotFound = 1,
|
||||
SaveDataNotFound = 1002,
|
||||
TitleNotFound = 1002,
|
||||
SdCardNotFound = 2001,
|
||||
RomFSNotFound = 2520,
|
||||
};
|
||||
|
||||
@@ -55,10 +55,10 @@ std::shared_ptr<VfsFile> VfsDirectory::GetFileRelative(const std::string& path)
|
||||
if (vec.size() == 1)
|
||||
return GetFile(vec[0]);
|
||||
auto dir = GetSubdirectory(vec[0]);
|
||||
for (size_t i = 1; i < vec.size() - 1; ++i) {
|
||||
for (size_t component = 1; component < vec.size() - 1; ++component) {
|
||||
if (dir == nullptr)
|
||||
return nullptr;
|
||||
dir = dir->GetSubdirectory(vec[i]);
|
||||
dir = dir->GetSubdirectory(vec[component]);
|
||||
}
|
||||
if (dir == nullptr)
|
||||
return nullptr;
|
||||
@@ -77,13 +77,14 @@ std::shared_ptr<VfsDirectory> VfsDirectory::GetDirectoryRelative(const std::stri
|
||||
vec.erase(std::remove_if(vec.begin(), vec.end(), [](const auto& str) { return str.empty(); }),
|
||||
vec.end());
|
||||
if (vec.empty())
|
||||
// return std::shared_ptr<VfsDirectory>(this);
|
||||
// TODO(DarkLordZach): Return this directory if path is '/' or similar. Can't currently
|
||||
// because of const-ness
|
||||
return nullptr;
|
||||
auto dir = GetSubdirectory(vec[0]);
|
||||
for (size_t i = 1; i < vec.size(); ++i) {
|
||||
for (size_t component = 1; component < vec.size(); ++component) {
|
||||
if (dir == nullptr)
|
||||
return nullptr;
|
||||
dir = dir->GetSubdirectory(vec[i]);
|
||||
dir = dir->GetSubdirectory(vec[component]);
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
@@ -88,20 +88,19 @@ RealVfsDirectory::RealVfsDirectory(const std::string& path_, Mode perms_)
|
||||
if (!FileUtil::Exists(path) && (perms == Mode::Write || perms == Mode::Append))
|
||||
FileUtil::CreateDir(path);
|
||||
unsigned size;
|
||||
if (perms != Mode::Append) {
|
||||
FileUtil::ForeachDirectoryEntry(
|
||||
&size, path,
|
||||
[this](unsigned* entries_out, const std::string& directory,
|
||||
const std::string& filename) {
|
||||
std::string full_path = directory + DIR_SEP + filename;
|
||||
if (FileUtil::IsDirectory(full_path))
|
||||
subdirectories.emplace_back(
|
||||
std::make_shared<RealVfsDirectory>(full_path, perms));
|
||||
else
|
||||
files.emplace_back(std::make_shared<RealVfsFile>(full_path, perms));
|
||||
return true;
|
||||
});
|
||||
}
|
||||
if (perms == Mode::Append)
|
||||
return;
|
||||
|
||||
FileUtil::ForeachDirectoryEntry(
|
||||
&size, path,
|
||||
[this](unsigned* entries_out, const std::string& directory, const std::string& filename) {
|
||||
std::string full_path = directory + DIR_SEP + filename;
|
||||
if (FileUtil::IsDirectory(full_path))
|
||||
subdirectories.emplace_back(std::make_shared<RealVfsDirectory>(full_path, perms));
|
||||
else
|
||||
files.emplace_back(std::make_shared<RealVfsFile>(full_path, perms));
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<VfsFile>> RealVfsDirectory::GetFiles() const {
|
||||
@@ -154,7 +153,7 @@ bool RealVfsDirectory::DeleteFile(const std::string& name) {
|
||||
if (file == nullptr)
|
||||
return false;
|
||||
files.erase(std::find(files.begin(), files.end(), file));
|
||||
auto real_file = dynamic_cast<RealVfsFile*>(file.get());
|
||||
auto real_file = std::static_pointer_cast<RealVfsFile>(file);
|
||||
real_file->Close();
|
||||
return FileUtil::Delete(path + DIR_SEP + name);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma optimize("", off)
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/file_util.h"
|
||||
#include "core/core.h"
|
||||
@@ -39,10 +41,14 @@ std::string VfsDirectoryServiceWrapper::GetName() const {
|
||||
ResultCode VfsDirectoryServiceWrapper::CreateFile(const std::string& path, u64 size) const {
|
||||
auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path));
|
||||
auto file = dir->CreateFile(FileUtil::GetFilename(path));
|
||||
if (file == nullptr)
|
||||
if (file == nullptr) {
|
||||
// TODO(DarkLordZach): Find a better error code for this
|
||||
return ResultCode(-1);
|
||||
if (!file->Resize(size))
|
||||
}
|
||||
if (!file->Resize(size)) {
|
||||
// TODO(DarkLordZach): Find a better error code for this
|
||||
return ResultCode(-1);
|
||||
}
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -54,8 +60,10 @@ ResultCode VfsDirectoryServiceWrapper::DeleteFile(const std::string& path) const
|
||||
}
|
||||
if (dir->GetFile(FileUtil::GetFilename(path)) == nullptr)
|
||||
return FileSys::ERROR_PATH_NOT_FOUND;
|
||||
if (!backing->DeleteFile(FileUtil::GetFilename(path)))
|
||||
if (!backing->DeleteFile(FileUtil::GetFilename(path))) {
|
||||
// TODO(DarkLordZach): Find a better error code for this
|
||||
return ResultCode(-1);
|
||||
}
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -64,22 +72,28 @@ ResultCode VfsDirectoryServiceWrapper::CreateDirectory(const std::string& path)
|
||||
if (dir == nullptr && FileUtil::GetFilename(FileUtil::GetParentPath(path)).empty())
|
||||
dir = backing;
|
||||
auto new_dir = dir->CreateSubdirectory(FileUtil::GetFilename(path));
|
||||
if (new_dir == nullptr)
|
||||
if (new_dir == nullptr) {
|
||||
// TODO(DarkLordZach): Find a better error code for this
|
||||
return ResultCode(-1);
|
||||
}
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ResultCode VfsDirectoryServiceWrapper::DeleteDirectory(const std::string& path) const {
|
||||
auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path));
|
||||
if (!dir->DeleteSubdirectory(FileUtil::GetFilename(path)))
|
||||
if (!dir->DeleteSubdirectory(FileUtil::GetFilename(path))) {
|
||||
// TODO(DarkLordZach): Find a better error code for this
|
||||
return ResultCode(-1);
|
||||
}
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ResultCode VfsDirectoryServiceWrapper::DeleteDirectoryRecursively(const std::string& path) const {
|
||||
auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path));
|
||||
if (!dir->DeleteSubdirectoryRecursive(FileUtil::GetFilename(path)))
|
||||
if (!dir->DeleteSubdirectoryRecursive(FileUtil::GetFilename(path))) {
|
||||
// TODO(DarkLordZach): Find a better error code for this
|
||||
return ResultCode(-1);
|
||||
}
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -90,8 +104,10 @@ ResultCode VfsDirectoryServiceWrapper::RenameFile(const std::string& src_path,
|
||||
// Use more-optimized vfs implementation rename.
|
||||
if (src == nullptr)
|
||||
return FileSys::ERROR_PATH_NOT_FOUND;
|
||||
if (!src->Rename(FileUtil::GetFilename(dest_path)))
|
||||
if (!src->Rename(FileUtil::GetFilename(dest_path))) {
|
||||
// TODO(DarkLordZach): Find a better error code for this
|
||||
return ResultCode(-1);
|
||||
}
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -106,8 +122,10 @@ ResultCode VfsDirectoryServiceWrapper::RenameFile(const std::string& src_path,
|
||||
ASSERT_MSG(dest->WriteBytes(src->ReadAllBytes()) == src->GetSize(),
|
||||
"Could not write all of the bytes but everything else has succeded.");
|
||||
|
||||
if (!src->GetContainingDirectory()->DeleteFile(FileUtil::GetFilename(src_path)))
|
||||
if (!src->GetContainingDirectory()->DeleteFile(FileUtil::GetFilename(src_path))) {
|
||||
// TODO(DarkLordZach): Find a better error code for this
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
@@ -119,8 +137,10 @@ ResultCode VfsDirectoryServiceWrapper::RenameDirectory(const std::string& src_pa
|
||||
// Use more-optimized vfs implementation rename.
|
||||
if (src == nullptr)
|
||||
return FileSys::ERROR_PATH_NOT_FOUND;
|
||||
if (!src->Rename(FileUtil::GetFilename(dest_path)))
|
||||
if (!src->Rename(FileUtil::GetFilename(dest_path))) {
|
||||
// TODO(DarkLordZach): Find a better error code for this
|
||||
return ResultCode(-1);
|
||||
}
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -130,6 +150,7 @@ ResultCode VfsDirectoryServiceWrapper::RenameDirectory(const std::string& src_pa
|
||||
"don't match -- UNIMPLEMENTED",
|
||||
src_path, dest_path);
|
||||
|
||||
// TODO(DarkLordZach): Find a better error code for this
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
@@ -152,8 +173,10 @@ ResultVal<FileSys::VirtualFile> VfsDirectoryServiceWrapper::OpenFile(const std::
|
||||
|
||||
ResultVal<FileSys::VirtualDir> VfsDirectoryServiceWrapper::OpenDirectory(const std::string& path) {
|
||||
auto dir = GetDirectoryRelativeWrapped(backing, path);
|
||||
if (dir == nullptr)
|
||||
if (dir == nullptr) {
|
||||
// TODO(DarkLordZach): Find a better error code for this
|
||||
return ResultCode(-1);
|
||||
}
|
||||
return MakeResult(dir);
|
||||
}
|
||||
|
||||
@@ -220,10 +243,10 @@ ResultVal<FileSys::VirtualFile> OpenRomFS(u64 title_id) {
|
||||
ResultVal<FileSys::VirtualDir> OpenSaveData(FileSys::SaveDataSpaceId space,
|
||||
FileSys::SaveDataDescriptor save_struct) {
|
||||
LOG_TRACE(Service_FS, "Opening Save Data for space_id={:01X}, save_struct={}",
|
||||
static_cast<u8>(space), SaveStructDebugInfo(save_struct));
|
||||
static_cast<u8>(space), save_struct.DebugInfo());
|
||||
|
||||
if (save_data_factory == nullptr) {
|
||||
return ResultCode(ErrorModule::FS, FileSys::ErrCodes::SaveDataNotFound);
|
||||
return ResultCode(ErrorModule::FS, FileSys::ErrCodes::TitleNotFound);
|
||||
}
|
||||
|
||||
return save_data_factory->Open(space, save_struct);
|
||||
|
||||
@@ -21,7 +21,7 @@ enum class StorageId : u8 {
|
||||
GameCard = 2,
|
||||
NandSystem = 3,
|
||||
NandUser = 4,
|
||||
SdCard = 5
|
||||
SdCard = 5,
|
||||
};
|
||||
|
||||
class IStorage final : public ServiceFramework<IStorage> {
|
||||
@@ -59,13 +59,6 @@ private:
|
||||
|
||||
// Read the data from the Storage backend
|
||||
std::vector<u8> output = backend->ReadBytes(length, offset);
|
||||
auto res = MakeResult<size_t>(output.size());
|
||||
if (res.Failed()) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(res.Code());
|
||||
return;
|
||||
}
|
||||
|
||||
// Write the data to memory
|
||||
ctx.WriteBuffer(output);
|
||||
|
||||
@@ -111,19 +104,13 @@ private:
|
||||
|
||||
// Read the data from the Storage backend
|
||||
std::vector<u8> output = backend->ReadBytes(length, offset);
|
||||
auto res = MakeResult<size_t>(output.size());
|
||||
if (res.Failed()) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(res.Code());
|
||||
return;
|
||||
}
|
||||
|
||||
// Write the data to memory
|
||||
ctx.WriteBuffer(output);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(static_cast<u64>(*res));
|
||||
rb.Push(output.size());
|
||||
}
|
||||
|
||||
void Write(Kernel::HLERequestContext& ctx) {
|
||||
@@ -150,14 +137,9 @@ private:
|
||||
data.resize(length);
|
||||
// Write the data to the Storage backend
|
||||
auto res = MakeResult<size_t>(backend->WriteBytes(data, offset));
|
||||
if (res.Failed()) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(res.Code());
|
||||
return;
|
||||
}
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(res.Code());
|
||||
}
|
||||
|
||||
void Flush(Kernel::HLERequestContext& ctx) {
|
||||
@@ -562,7 +544,7 @@ void FSP_SRV::MountSaveData(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
if (dir.Failed()) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 0};
|
||||
rb.Push(ResultCode(ErrorModule::FS, FileSys::ErrCodes::SaveDataNotFound));
|
||||
rb.Push(ResultCode(ErrorModule::FS, FileSys::ErrCodes::TitleNotFound));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -608,26 +590,9 @@ void FSP_SRV::OpenRomStorage(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
LOG_DEBUG(Service_FS, "called with storage_id={:02X}, title_id={:016X}",
|
||||
static_cast<u8>(storage_id), title_id);
|
||||
if (title_id != Core::System::GetInstance().CurrentProcess()->program_id) {
|
||||
LOG_CRITICAL(
|
||||
Service_FS,
|
||||
"Attempting to access RomFS of another title id (current={:016X}, requested={:016X}).",
|
||||
Core::System::GetInstance().CurrentProcess()->program_id, title_id);
|
||||
}
|
||||
|
||||
auto romfs = OpenRomFS(title_id);
|
||||
if (romfs.Failed()) {
|
||||
LOG_CRITICAL(Service_FS, "no file system interface available!");
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultCode(ErrorModule::FS, FileSys::ErrCodes::RomFSNotFound));
|
||||
return;
|
||||
}
|
||||
|
||||
IStorage storage(std::move(romfs.Unwrap()));
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IStorage>(std::move(storage));
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultCode(ErrorModule::FS, FileSys::ErrCodes::TitleNotFound));
|
||||
}
|
||||
|
||||
} // namespace Service::FileSystem
|
||||
|
||||
Reference in New Issue
Block a user