Review fixes + other stuff

This commit is contained in:
Zach Hilman
2018-07-18 13:02:18 -04:00
parent 29528f6ea0
commit 7f68a2fa12
7 changed files with 75 additions and 78 deletions

View File

@@ -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);

View File

@@ -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');
}

View File

@@ -11,7 +11,7 @@ namespace FileSys {
namespace ErrCodes {
enum {
NotFound = 1,
SaveDataNotFound = 1002,
TitleNotFound = 1002,
SdCardNotFound = 2001,
RomFSNotFound = 2520,
};

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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