summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/file_sys/mode.h6
-rw-r--r--src/core/file_sys/partition_filesystem.cpp6
-rw-r--r--src/core/file_sys/vfs_real.cpp47
-rw-r--r--src/core/hle/ipc_helpers.h34
-rw-r--r--src/core/hle/kernel/hle_ipc.h2
-rw-r--r--src/core/hle/service/filesystem/filesystem.cpp45
6 files changed, 84 insertions, 56 deletions
diff --git a/src/core/file_sys/mode.h b/src/core/file_sys/mode.h
index b4363152a..c95205668 100644
--- a/src/core/file_sys/mode.h
+++ b/src/core/file_sys/mode.h
@@ -11,7 +11,13 @@ namespace FileSys {
enum class Mode : u32 {
Read = 1,
Write = 2,
+ ReadWrite = 3,
Append = 4,
+ WriteAppend = 6,
};
+inline u32 operator&(Mode lhs, Mode rhs) {
+ return static_cast<u32>(lhs) & static_cast<u32>(rhs);
+}
+
} // namespace FileSys
diff --git a/src/core/file_sys/partition_filesystem.cpp b/src/core/file_sys/partition_filesystem.cpp
index 8d2bd9f6b..521e21078 100644
--- a/src/core/file_sys/partition_filesystem.cpp
+++ b/src/core/file_sys/partition_filesystem.cpp
@@ -65,8 +65,8 @@ PartitionFilesystem::PartitionFilesystem(std::shared_ptr<VfsFile> file) {
std::string name(
reinterpret_cast<const char*>(&file_data[strtab_offset + entry.strtab_offset]));
- pfs_files.emplace_back(
- std::make_shared<OffsetVfsFile>(file, entry.size, content_offset + entry.offset, name));
+ pfs_files.emplace_back(std::make_shared<OffsetVfsFile>(
+ file, entry.size, content_offset + entry.offset, std::move(name)));
}
status = Loader::ResultStatus::Success;
@@ -109,7 +109,7 @@ bool PartitionFilesystem::ReplaceFileWithSubdirectory(VirtualFile file, VirtualD
return false;
const std::ptrdiff_t offset = std::distance(pfs_files.begin(), iter);
- pfs_files[offset] = pfs_files.back();
+ pfs_files[offset] = std::move(pfs_files.back());
pfs_files.pop_back();
pfs_dirs.emplace_back(std::move(dir));
diff --git a/src/core/file_sys/vfs_real.cpp b/src/core/file_sys/vfs_real.cpp
index 095fec77e..9ce2e1efa 100644
--- a/src/core/file_sys/vfs_real.cpp
+++ b/src/core/file_sys/vfs_real.cpp
@@ -13,24 +13,31 @@
namespace FileSys {
-static std::string PermissionsToCharArray(Mode perms) {
- std::string out;
- switch (perms) {
- case Mode::Read:
- out += "r";
- break;
- case Mode::Write:
- out += "r+";
- break;
- case Mode::Append:
- out += "a";
- break;
+static std::string ModeFlagsToString(Mode mode) {
+ std::string mode_str;
+
+ // Calculate the correct open mode for the file.
+ if (mode & Mode::Read && mode & Mode::Write) {
+ if (mode & Mode::Append)
+ mode_str = "a+";
+ else
+ mode_str = "r+";
+ } else {
+ if (mode & Mode::Read)
+ mode_str = "r";
+ else if (mode & Mode::Append)
+ mode_str = "a";
+ else if (mode & Mode::Write)
+ mode_str = "w";
}
- return out + "b";
+
+ mode_str += "b";
+
+ return mode_str;
}
RealVfsFile::RealVfsFile(const std::string& path_, Mode perms_)
- : backing(path_, PermissionsToCharArray(perms_).c_str()), path(path_),
+ : backing(path_, ModeFlagsToString(perms_).c_str()), path(path_),
parent_path(FileUtil::GetParentPath(path_)),
path_components(FileUtil::SplitPathComponents(path_)),
parent_components(FileUtil::SliceVector(path_components, 0, path_components.size() - 1)),
@@ -53,11 +60,11 @@ std::shared_ptr<VfsDirectory> RealVfsFile::GetContainingDirectory() const {
}
bool RealVfsFile::IsWritable() const {
- return perms == Mode::Append || perms == Mode::Write;
+ return (perms & Mode::WriteAppend) != 0;
}
bool RealVfsFile::IsReadable() const {
- return perms == Mode::Read || perms == Mode::Write;
+ return (perms & Mode::ReadWrite) != 0;
}
size_t RealVfsFile::Read(u8* data, size_t length, size_t offset) const {
@@ -79,7 +86,7 @@ bool RealVfsFile::Rename(std::string_view name) {
path = (parent_path + DIR_SEP).append(name);
path_components = parent_components;
path_components.push_back(std::move(name_str));
- backing = FileUtil::IOFile(path, PermissionsToCharArray(perms).c_str());
+ backing = FileUtil::IOFile(path, ModeFlagsToString(perms).c_str());
return out;
}
@@ -93,7 +100,7 @@ RealVfsDirectory::RealVfsDirectory(const std::string& path_, Mode perms_)
path_components(FileUtil::SplitPathComponents(path)),
parent_components(FileUtil::SliceVector(path_components, 0, path_components.size() - 1)),
perms(perms_) {
- if (!FileUtil::Exists(path) && (perms == Mode::Write || perms == Mode::Append))
+ if (!FileUtil::Exists(path) && perms & Mode::WriteAppend)
FileUtil::CreateDir(path);
if (perms == Mode::Append)
@@ -120,11 +127,11 @@ std::vector<std::shared_ptr<VfsDirectory>> RealVfsDirectory::GetSubdirectories()
}
bool RealVfsDirectory::IsWritable() const {
- return perms == Mode::Write || perms == Mode::Append;
+ return (perms & Mode::WriteAppend) != 0;
}
bool RealVfsDirectory::IsReadable() const {
- return perms == Mode::Read || perms == Mode::Write;
+ return (perms & Mode::ReadWrite) != 0;
}
std::string RealVfsDirectory::GetName() const {
diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h
index 8b5b06f31..f5bd27a75 100644
--- a/src/core/hle/ipc_helpers.h
+++ b/src/core/hle/ipc_helpers.h
@@ -25,9 +25,9 @@ protected:
ptrdiff_t index = 0;
public:
- RequestHelperBase(u32* command_buffer) : cmdbuf(command_buffer) {}
+ explicit RequestHelperBase(u32* command_buffer) : cmdbuf(command_buffer) {}
- RequestHelperBase(Kernel::HLERequestContext& context)
+ explicit RequestHelperBase(Kernel::HLERequestContext& context)
: context(&context), cmdbuf(context.CommandBuffer()) {}
void Skip(unsigned size_in_words, bool set_to_null) {
@@ -56,13 +56,6 @@ public:
class ResponseBuilder : public RequestHelperBase {
public:
- ResponseBuilder(u32* command_buffer) : RequestHelperBase(command_buffer) {}
-
- u32 normal_params_size{};
- u32 num_handles_to_copy{};
- u32 num_objects_to_move{}; ///< Domain objects or move handles, context dependent
- std::ptrdiff_t datapayload_index{};
-
/// Flags used for customizing the behavior of ResponseBuilder
enum class Flags : u32 {
None = 0,
@@ -71,9 +64,11 @@ public:
AlwaysMoveHandles = 1,
};
- ResponseBuilder(Kernel::HLERequestContext& context, u32 normal_params_size,
- u32 num_handles_to_copy = 0, u32 num_objects_to_move = 0,
- Flags flags = Flags::None)
+ explicit ResponseBuilder(u32* command_buffer) : RequestHelperBase(command_buffer) {}
+
+ explicit ResponseBuilder(Kernel::HLERequestContext& context, u32 normal_params_size,
+ u32 num_handles_to_copy = 0, u32 num_objects_to_move = 0,
+ Flags flags = Flags::None)
: RequestHelperBase(context), normal_params_size(normal_params_size),
num_handles_to_copy(num_handles_to_copy), num_objects_to_move(num_objects_to_move) {
@@ -206,6 +201,12 @@ public:
template <typename... O>
void PushCopyObjects(Kernel::SharedPtr<O>... pointers);
+
+private:
+ u32 normal_params_size{};
+ u32 num_handles_to_copy{};
+ u32 num_objects_to_move{}; ///< Domain objects or move handles, context dependent
+ std::ptrdiff_t datapayload_index{};
};
/// Push ///
@@ -273,9 +274,9 @@ inline void ResponseBuilder::PushMoveObjects(Kernel::SharedPtr<O>... pointers) {
class RequestParser : public RequestHelperBase {
public:
- RequestParser(u32* command_buffer) : RequestHelperBase(command_buffer) {}
+ explicit RequestParser(u32* command_buffer) : RequestHelperBase(command_buffer) {}
- RequestParser(Kernel::HLERequestContext& context) : RequestHelperBase(context) {
+ explicit RequestParser(Kernel::HLERequestContext& context) : RequestHelperBase(context) {
ASSERT_MSG(context.GetDataPayloadOffset(), "context is incomplete");
Skip(context.GetDataPayloadOffset(), false);
// Skip the u64 command id, it's already stored in the context
@@ -285,8 +286,9 @@ public:
ResponseBuilder MakeBuilder(u32 normal_params_size, u32 num_handles_to_copy,
u32 num_handles_to_move,
- ResponseBuilder::Flags flags = ResponseBuilder::Flags::None) {
- return {*context, normal_params_size, num_handles_to_copy, num_handles_to_move, flags};
+ ResponseBuilder::Flags flags = ResponseBuilder::Flags::None) const {
+ return ResponseBuilder{*context, normal_params_size, num_handles_to_copy,
+ num_handles_to_move, flags};
}
template <typename T>
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h
index 01b805df8..84727f748 100644
--- a/src/core/hle/kernel/hle_ipc.h
+++ b/src/core/hle/kernel/hle_ipc.h
@@ -91,7 +91,7 @@ protected:
*/
class HLERequestContext {
public:
- HLERequestContext(SharedPtr<Kernel::ServerSession> session);
+ explicit HLERequestContext(SharedPtr<ServerSession> session);
~HLERequestContext();
/// Returns a pointer to the IPC command buffer for this request.
diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp
index dbfe06cbc..fdd2fda18 100644
--- a/src/core/hle/service/filesystem/filesystem.cpp
+++ b/src/core/hle/service/filesystem/filesystem.cpp
@@ -24,7 +24,8 @@ namespace Service::FileSystem {
constexpr u64 EMULATED_SD_REPORTED_SIZE = 32000000000;
static FileSys::VirtualDir GetDirectoryRelativeWrapped(FileSys::VirtualDir base,
- std::string_view dir_name) {
+ std::string_view dir_name_) {
+ std::string dir_name(FileUtil::SanitizePath(dir_name_));
if (dir_name.empty() || dir_name == "." || dir_name == "/" || dir_name == "\\")
return base;
@@ -38,7 +39,8 @@ std::string VfsDirectoryServiceWrapper::GetName() const {
return backing->GetName();
}
-ResultCode VfsDirectoryServiceWrapper::CreateFile(const std::string& path, u64 size) const {
+ResultCode VfsDirectoryServiceWrapper::CreateFile(const std::string& path_, u64 size) const {
+ std::string path(FileUtil::SanitizePath(path_));
auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path));
auto file = dir->CreateFile(FileUtil::GetFilename(path));
if (file == nullptr) {
@@ -52,7 +54,8 @@ ResultCode VfsDirectoryServiceWrapper::CreateFile(const std::string& path, u64 s
return RESULT_SUCCESS;
}
-ResultCode VfsDirectoryServiceWrapper::DeleteFile(const std::string& path) const {
+ResultCode VfsDirectoryServiceWrapper::DeleteFile(const std::string& path_) const {
+ std::string path(FileUtil::SanitizePath(path_));
auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path));
if (path == "/" || path == "\\") {
// TODO(DarkLordZach): Why do games call this and what should it do? Works as is but...
@@ -60,14 +63,15 @@ 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 (!dir->DeleteFile(FileUtil::GetFilename(path))) {
// TODO(DarkLordZach): Find a better error code for this
return ResultCode(-1);
}
return RESULT_SUCCESS;
}
-ResultCode VfsDirectoryServiceWrapper::CreateDirectory(const std::string& path) const {
+ResultCode VfsDirectoryServiceWrapper::CreateDirectory(const std::string& path_) const {
+ std::string path(FileUtil::SanitizePath(path_));
auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path));
if (dir == nullptr && FileUtil::GetFilename(FileUtil::GetParentPath(path)).empty())
dir = backing;
@@ -79,7 +83,8 @@ ResultCode VfsDirectoryServiceWrapper::CreateDirectory(const std::string& path)
return RESULT_SUCCESS;
}
-ResultCode VfsDirectoryServiceWrapper::DeleteDirectory(const std::string& path) const {
+ResultCode VfsDirectoryServiceWrapper::DeleteDirectory(const std::string& path_) const {
+ std::string path(FileUtil::SanitizePath(path_));
auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path));
if (!dir->DeleteSubdirectory(FileUtil::GetFilename(path))) {
// TODO(DarkLordZach): Find a better error code for this
@@ -88,7 +93,8 @@ ResultCode VfsDirectoryServiceWrapper::DeleteDirectory(const std::string& path)
return RESULT_SUCCESS;
}
-ResultCode VfsDirectoryServiceWrapper::DeleteDirectoryRecursively(const std::string& path) const {
+ResultCode VfsDirectoryServiceWrapper::DeleteDirectoryRecursively(const std::string& path_) const {
+ std::string path(FileUtil::SanitizePath(path_));
auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path));
if (!dir->DeleteSubdirectoryRecursive(FileUtil::GetFilename(path))) {
// TODO(DarkLordZach): Find a better error code for this
@@ -97,8 +103,10 @@ ResultCode VfsDirectoryServiceWrapper::DeleteDirectoryRecursively(const std::str
return RESULT_SUCCESS;
}
-ResultCode VfsDirectoryServiceWrapper::RenameFile(const std::string& src_path,
- const std::string& dest_path) const {
+ResultCode VfsDirectoryServiceWrapper::RenameFile(const std::string& src_path_,
+ const std::string& dest_path_) const {
+ std::string src_path(FileUtil::SanitizePath(src_path_));
+ std::string dest_path(FileUtil::SanitizePath(dest_path_));
auto src = backing->GetFileRelative(src_path);
if (FileUtil::GetParentPath(src_path) == FileUtil::GetParentPath(dest_path)) {
// Use more-optimized vfs implementation rename.
@@ -130,8 +138,10 @@ ResultCode VfsDirectoryServiceWrapper::RenameFile(const std::string& src_path,
return RESULT_SUCCESS;
}
-ResultCode VfsDirectoryServiceWrapper::RenameDirectory(const std::string& src_path,
- const std::string& dest_path) const {
+ResultCode VfsDirectoryServiceWrapper::RenameDirectory(const std::string& src_path_,
+ const std::string& dest_path_) const {
+ std::string src_path(FileUtil::SanitizePath(src_path_));
+ std::string dest_path(FileUtil::SanitizePath(dest_path_));
auto src = GetDirectoryRelativeWrapped(backing, src_path);
if (FileUtil::GetParentPath(src_path) == FileUtil::GetParentPath(dest_path)) {
// Use more-optimized vfs implementation rename.
@@ -154,8 +164,9 @@ ResultCode VfsDirectoryServiceWrapper::RenameDirectory(const std::string& src_pa
return ResultCode(-1);
}
-ResultVal<FileSys::VirtualFile> VfsDirectoryServiceWrapper::OpenFile(const std::string& path,
+ResultVal<FileSys::VirtualFile> VfsDirectoryServiceWrapper::OpenFile(const std::string& path_,
FileSys::Mode mode) const {
+ std::string path(FileUtil::SanitizePath(path_));
auto npath = path;
while (npath.size() > 0 && (npath[0] == '/' || npath[0] == '\\'))
npath = npath.substr(1);
@@ -171,7 +182,8 @@ ResultVal<FileSys::VirtualFile> VfsDirectoryServiceWrapper::OpenFile(const std::
return MakeResult<FileSys::VirtualFile>(file);
}
-ResultVal<FileSys::VirtualDir> VfsDirectoryServiceWrapper::OpenDirectory(const std::string& path) {
+ResultVal<FileSys::VirtualDir> VfsDirectoryServiceWrapper::OpenDirectory(const std::string& path_) {
+ std::string path(FileUtil::SanitizePath(path_));
auto dir = GetDirectoryRelativeWrapped(backing, path);
if (dir == nullptr) {
// TODO(DarkLordZach): Find a better error code for this
@@ -188,7 +200,8 @@ u64 VfsDirectoryServiceWrapper::GetFreeSpaceSize() const {
}
ResultVal<FileSys::EntryType> VfsDirectoryServiceWrapper::GetEntryType(
- const std::string& path) const {
+ const std::string& path_) const {
+ std::string path(FileUtil::SanitizePath(path_));
auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path));
if (dir == nullptr)
return FileSys::ERROR_PATH_NOT_FOUND;
@@ -272,9 +285,9 @@ void RegisterFileSystems() {
sdmc_factory = nullptr;
auto nand_directory = std::make_shared<FileSys::RealVfsDirectory>(
- FileUtil::GetUserPath(FileUtil::UserPath::NANDDir), FileSys::Mode::Write);
+ FileUtil::GetUserPath(FileUtil::UserPath::NANDDir), FileSys::Mode::ReadWrite);
auto sd_directory = std::make_shared<FileSys::RealVfsDirectory>(
- FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir), FileSys::Mode::Write);
+ FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir), FileSys::Mode::ReadWrite);
auto savedata = std::make_unique<FileSys::SaveDataFactory>(std::move(nand_directory));
save_data_factory = std::move(savedata);