From 13efbdc2014177b84cae82e522b191e2f2f022df Mon Sep 17 00:00:00 2001 From: Subv Date: Wed, 31 Dec 2014 19:36:50 -0500 Subject: [PATCH 1/5] SaveDataCheck: Preliminary work in this archive. This allows Steel Diver to boot further, some files are needed. This is still not ready and needs a big cleanup, this will possibly be delayed until the way we handle archives is fixed (with factory classes instead of ahead-of-time creation of archives) --- src/core/file_sys/archive_romfs.cpp | 25 +++++++++++++++++++ src/core/file_sys/archive_romfs.h | 7 +++--- src/core/hle/service/fs/archive.cpp | 37 ++++++++++++++++++++++++++--- src/core/hle/service/fs/archive.h | 1 + 4 files changed, 63 insertions(+), 7 deletions(-) diff --git a/src/core/file_sys/archive_romfs.cpp b/src/core/file_sys/archive_romfs.cpp index 2fc3831b72..df07eb6571 100644 --- a/src/core/file_sys/archive_romfs.cpp +++ b/src/core/file_sys/archive_romfs.cpp @@ -5,6 +5,7 @@ #include #include "common/common_types.h" +#include "common/file_util.h" #include "common/make_unique.h" #include "core/file_sys/archive_romfs.h" @@ -23,6 +24,10 @@ Archive_RomFS::Archive_RomFS(const Loader::AppLoader& app_loader) { } } +Archive_RomFS::Archive_RomFS(std::string mountp) : mount_point(mountp) { + +} + std::unique_ptr Archive_RomFS::OpenFile(const Path& path, const Mode mode) const { return Common::make_unique(this); } @@ -67,4 +72,24 @@ ResultCode Archive_RomFS::Format(const Path& path) const { return UnimplementedFunction(ErrorModule::FS); } +ResultCode Archive_RomFS::Open(const Path& path) { + if (mount_point.empty()) + return RESULT_SUCCESS; + auto vec = path.AsBinary(); + const u32* data = reinterpret_cast(vec.data()); + std::string file_path = Common::StringFromFormat("%s%08X%08X.bin", mount_point.c_str(), data[1], data[0]); + FileUtil::IOFile file(file_path, "rb"); + + std::fill(raw_data.begin(), raw_data.end(), 0); + + if (!file.IsOpen()) { + return ResultCode(-1); // TODO(Subv): Find the right error code + } + auto size = file.GetSize(); + raw_data.resize(size); + file.ReadBytes(raw_data.data(), size); + file.Close(); + return RESULT_SUCCESS; +} + } // namespace FileSys diff --git a/src/core/file_sys/archive_romfs.h b/src/core/file_sys/archive_romfs.h index d4b1eb7f2c..b657dd38be 100644 --- a/src/core/file_sys/archive_romfs.h +++ b/src/core/file_sys/archive_romfs.h @@ -20,6 +20,7 @@ namespace FileSys { class Archive_RomFS final : public ArchiveBackend { public: Archive_RomFS(const Loader::AppLoader& app_loader); + Archive_RomFS(std::string mount_point); std::string GetName() const override { return "RomFS"; } @@ -83,15 +84,13 @@ public: */ std::unique_ptr OpenDirectory(const Path& path) const override; - ResultCode Open(const Path& path) override { - return RESULT_SUCCESS; - } + ResultCode Open(const Path& path) override; ResultCode Format(const Path& path) const override; private: friend class File_RomFS; - + std::string mount_point; std::vector raw_data; }; diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 9a91bcb8b0..a8383d4e5d 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -10,9 +10,10 @@ #include "common/make_unique.h" #include "common/math_util.h" -#include "core/file_sys/archive_savedata.h" -#include "core/file_sys/archive_extsavedata.h" #include "core/file_sys/archive_backend.h" +#include "core/file_sys/archive_extsavedata.h" +#include "core/file_sys/archive_romfs.h" +#include "core/file_sys/archive_savedata.h" #include "core/file_sys/archive_sdmc.h" #include "core/file_sys/directory_backend.h" #include "core/hle/service/fs/archive.h" @@ -50,6 +51,9 @@ enum class FileCommand : u32 { SetAttributes = 0x08070040, Close = 0x08080000, Flush = 0x08090000, + SetPriority = 0x080A0040, + GetPriority = 0x080B0000, + OpenLinkFile = 0x080C0000, }; // Command to access directory @@ -75,12 +79,13 @@ public: class File : public Kernel::Session { public: File(std::unique_ptr&& backend, const FileSys::Path& path) - : path(path), backend(std::move(backend)) { + : path(path), backend(std::move(backend)), priority(0) { } std::string GetName() const override { return "Path: " + path.DebugStr(); } FileSys::Path path; ///< Path of the file + u32 priority; ///< Priority of the file. TODO(Subv): Find out what this means std::unique_ptr backend; ///< File backend interface ResultVal SyncRequest() override { @@ -145,6 +150,27 @@ public: break; } + case FileCommand::OpenLinkFile: + { + LOG_WARNING(Service_FS, "(STUBBED) File command OpenLinkFile %s", GetName().c_str()); + cmd_buff[3] = GetHandle(); + break; + } + + case FileCommand::SetPriority: + { + priority = cmd_buff[1]; + LOG_TRACE(Service_FS, "SetPriority %u", priority); + break; + } + + case FileCommand::GetPriority: + { + cmd_buff[2] = priority; + LOG_TRACE(Service_FS, "GetPriority"); + break; + } + // Unknown command... default: LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd); @@ -435,6 +461,11 @@ void ArchiveInit() { else LOG_ERROR(Service_FS, "Can't instantiate SharedExtSaveData archive with path %s", sharedextsavedata_directory.c_str()); + + // Create the SaveDataCheck archive, basically a small variation of the RomFS archive + std::string savedatacheck_directory = FileUtil::GetUserPath(D_SAVEDATA_IDX) + "../savedatacheck/"; + auto savedatacheck_archive = Common::make_unique(savedatacheck_directory); + CreateArchive(std::move(savedatacheck_archive), ArchiveIdCode::SaveDataCheck); } /// Shutdown archives diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h index c23b8cc46d..f2e4e4a536 100644 --- a/src/core/hle/service/fs/archive.h +++ b/src/core/hle/service/fs/archive.h @@ -22,6 +22,7 @@ enum class ArchiveIdCode : u32 { SystemSaveData = 0x00000008, SDMC = 0x00000009, SDMCWriteOnly = 0x0000000A, + SaveDataCheck = 0x2345678A, }; typedef u64 ArchiveHandle; From aade417b143a756da10b69747793c707ef8316fd Mon Sep 17 00:00:00 2001 From: Subv Date: Thu, 1 Jan 2015 12:39:27 -0500 Subject: [PATCH 2/5] Archives: Reduced duplicate code in RomFS and SaveCheck. Fixed a few warnings and cleaned up the code --- src/common/common_paths.h | 1 + src/common/file_util.cpp | 2 + src/common/file_util.h | 1 + src/core/CMakeLists.txt | 8 +- src/core/file_sys/archive_backend.h | 3 + src/core/file_sys/archive_romfs.cpp | 70 ---------------- src/core/file_sys/archive_romfs.h | 75 +----------------- src/core/file_sys/archive_savedatacheck.cpp | 41 ++++++++++ src/core/file_sys/archive_savedatacheck.h | 31 ++++++++ src/core/file_sys/directory_romfs.cpp | 32 -------- src/core/file_sys/directory_romfs.h | 43 ---------- src/core/file_sys/file_romfs.cpp | 43 ---------- src/core/file_sys/file_romfs.h | 73 ----------------- src/core/file_sys/ivfc_archive.cpp | 88 +++++++++++++++++++++ src/core/file_sys/ivfc_archive.h | 63 +++++++++++++++ src/core/hle/service/fs/archive.cpp | 7 +- src/core/hle/service/fs/archive.h | 2 +- 17 files changed, 242 insertions(+), 341 deletions(-) create mode 100644 src/core/file_sys/archive_savedatacheck.cpp create mode 100644 src/core/file_sys/archive_savedatacheck.h delete mode 100644 src/core/file_sys/directory_romfs.cpp delete mode 100644 src/core/file_sys/directory_romfs.h delete mode 100644 src/core/file_sys/file_romfs.cpp delete mode 100644 src/core/file_sys/file_romfs.h create mode 100644 src/core/file_sys/ivfc_archive.cpp create mode 100644 src/core/file_sys/ivfc_archive.h diff --git a/src/common/common_paths.h b/src/common/common_paths.h index d3f0702bc4..e692e54924 100644 --- a/src/common/common_paths.h +++ b/src/common/common_paths.h @@ -42,6 +42,7 @@ #define SDMC_DIR "sdmc" #define EXTSAVEDATA_DIR "extsavedata" #define SAVEDATA_DIR "savedata" +#define SAVEDATACHECK_DIR "savedatacheck" #define SYSDATA_DIR "sysdata" #define SYSSAVEDATA_DIR "syssavedata" #define SHADERCACHE_DIR "shader_cache" diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index c44ad4ca1b..0a6cd80c87 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp @@ -678,6 +678,7 @@ const std::string& GetUserPath(const unsigned int DirIDX, const std::string &new paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP; paths[D_EXTSAVEDATA] = paths[D_USER_IDX] + EXTSAVEDATA_DIR DIR_SEP; paths[D_SAVEDATA_IDX] = paths[D_USER_IDX] + SAVEDATA_DIR DIR_SEP; + paths[D_SAVEDATACHECK_IDX] = paths[D_USER_IDX] + SAVEDATACHECK_DIR DIR_SEP; paths[D_SYSDATA_IDX] = paths[D_USER_IDX] + SYSDATA_DIR DIR_SEP; paths[D_SYSSAVEDATA_IDX] = paths[D_USER_IDX] + SYSSAVEDATA_DIR DIR_SEP; paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP; @@ -723,6 +724,7 @@ const std::string& GetUserPath(const unsigned int DirIDX, const std::string &new paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP; paths[D_EXTSAVEDATA] = paths[D_USER_IDX] + EXTSAVEDATA_DIR DIR_SEP; paths[D_SAVEDATA_IDX] = paths[D_USER_IDX] + SAVEDATA_DIR DIR_SEP; + paths[D_SAVEDATACHECK_IDX] = paths[D_USER_IDX] + SAVEDATACHECK_DIR DIR_SEP; paths[D_SYSSAVEDATA_IDX] = paths[D_USER_IDX] + SYSSAVEDATA_DIR DIR_SEP; paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP; paths[D_SHADERS_IDX] = paths[D_USER_IDX] + SHADERS_DIR DIR_SEP; diff --git a/src/common/file_util.h b/src/common/file_util.h index ec24154739..c83ecd87db 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -29,6 +29,7 @@ enum { D_SDMC_IDX, D_EXTSAVEDATA, D_SAVEDATA_IDX, + D_SAVEDATACHECK_IDX, D_SYSDATA_IDX, D_SYSSAVEDATA_IDX, D_HIRESTEXTURES_IDX, diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 89ea70d23e..addcb953cc 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -20,11 +20,11 @@ set(SRCS file_sys/archive_extsavedata.cpp file_sys/archive_romfs.cpp file_sys/archive_savedata.cpp + file_sys/archive_savedatacheck.cpp file_sys/archive_sdmc.cpp file_sys/archive_systemsavedata.cpp file_sys/disk_archive.cpp - file_sys/file_romfs.cpp - file_sys/directory_romfs.cpp + file_sys/ivfc_archive.cpp hle/kernel/address_arbiter.cpp hle/kernel/event.cpp hle/kernel/kernel.cpp @@ -108,13 +108,13 @@ set(HEADERS file_sys/archive_extsavedata.h file_sys/archive_romfs.h file_sys/archive_savedata.h + file_sys/archive_savedatacheck.h file_sys/archive_sdmc.h file_sys/archive_systemsavedata.h file_sys/disk_archive.h file_sys/file_backend.h - file_sys/file_romfs.h + file_sys/ivfc_archive.h file_sys/directory_backend.h - file_sys/directory_romfs.h hle/kernel/address_arbiter.h hle/kernel/event.h hle/kernel/kernel.h diff --git a/src/core/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h index 1612c35c2c..390178f67f 100644 --- a/src/core/file_sys/archive_backend.h +++ b/src/core/file_sys/archive_backend.h @@ -88,6 +88,7 @@ public: const std::string DebugStr() const { switch (GetType()) { case Invalid: + default: return "[Invalid]"; case Empty: return "[Empty]"; @@ -117,6 +118,7 @@ public: return {}; case Invalid: case Binary: + default: // TODO(yuriks): Add assert LOG_ERROR(Service_FS, "LowPathType cannot be converted to string!"); return {}; @@ -159,6 +161,7 @@ public: case Empty: return {}; case Invalid: + default: // TODO(yuriks): Add assert LOG_ERROR(Service_FS, "LowPathType cannot be converted to binary!"); return {}; diff --git a/src/core/file_sys/archive_romfs.cpp b/src/core/file_sys/archive_romfs.cpp index df07eb6571..a30f73d0ea 100644 --- a/src/core/file_sys/archive_romfs.cpp +++ b/src/core/file_sys/archive_romfs.cpp @@ -9,8 +9,6 @@ #include "common/make_unique.h" #include "core/file_sys/archive_romfs.h" -#include "core/file_sys/directory_romfs.h" -#include "core/file_sys/file_romfs.h" //////////////////////////////////////////////////////////////////////////////////////////////////// // FileSys namespace @@ -24,72 +22,4 @@ Archive_RomFS::Archive_RomFS(const Loader::AppLoader& app_loader) { } } -Archive_RomFS::Archive_RomFS(std::string mountp) : mount_point(mountp) { - -} - -std::unique_ptr Archive_RomFS::OpenFile(const Path& path, const Mode mode) const { - return Common::make_unique(this); -} - -bool Archive_RomFS::DeleteFile(const Path& path) const { - LOG_WARNING(Service_FS, "Attempted to delete a file from ROMFS."); - return false; -} - -bool Archive_RomFS::RenameFile(const Path& src_path, const Path& dest_path) const { - LOG_WARNING(Service_FS, "Attempted to rename a file within ROMFS."); - return false; -} - -bool Archive_RomFS::DeleteDirectory(const Path& path) const { - LOG_WARNING(Service_FS, "Attempted to delete a directory from ROMFS."); - return false; -} - -ResultCode Archive_RomFS::CreateFile(const Path& path, u32 size) const { - LOG_WARNING(Service_FS, "Attempted to create a file in ROMFS."); - // TODO: Verify error code - return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, ErrorLevel::Permanent); -} - -bool Archive_RomFS::CreateDirectory(const Path& path) const { - LOG_WARNING(Service_FS, "Attempted to create a directory in ROMFS."); - return false; -} - -bool Archive_RomFS::RenameDirectory(const Path& src_path, const Path& dest_path) const { - LOG_WARNING(Service_FS, "Attempted to rename a file within ROMFS."); - return false; -} - -std::unique_ptr Archive_RomFS::OpenDirectory(const Path& path) const { - return Common::make_unique(); -} - -ResultCode Archive_RomFS::Format(const Path& path) const { - LOG_WARNING(Service_FS, "Attempted to format ROMFS."); - return UnimplementedFunction(ErrorModule::FS); -} - -ResultCode Archive_RomFS::Open(const Path& path) { - if (mount_point.empty()) - return RESULT_SUCCESS; - auto vec = path.AsBinary(); - const u32* data = reinterpret_cast(vec.data()); - std::string file_path = Common::StringFromFormat("%s%08X%08X.bin", mount_point.c_str(), data[1], data[0]); - FileUtil::IOFile file(file_path, "rb"); - - std::fill(raw_data.begin(), raw_data.end(), 0); - - if (!file.IsOpen()) { - return ResultCode(-1); // TODO(Subv): Find the right error code - } - auto size = file.GetSize(); - raw_data.resize(size); - file.ReadBytes(raw_data.data(), size); - file.Close(); - return RESULT_SUCCESS; -} - } // namespace FileSys diff --git a/src/core/file_sys/archive_romfs.h b/src/core/file_sys/archive_romfs.h index b657dd38be..5cb75e04d9 100644 --- a/src/core/file_sys/archive_romfs.h +++ b/src/core/file_sys/archive_romfs.h @@ -8,7 +8,7 @@ #include "common/common_types.h" -#include "core/file_sys/archive_backend.h" +#include "core/file_sys/ivfc_archive.h" #include "core/loader/loader.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -17,81 +17,12 @@ namespace FileSys { /// File system interface to the RomFS archive -class Archive_RomFS final : public ArchiveBackend { +class Archive_RomFS final : public IVFCArchive { public: Archive_RomFS(const Loader::AppLoader& app_loader); - Archive_RomFS(std::string mount_point); std::string GetName() const override { return "RomFS"; } - - /** - * Open a file specified by its path, using the specified mode - * @param path Path relative to the archive - * @param mode Mode to open the file with - * @return Opened file, or nullptr - */ - std::unique_ptr OpenFile(const Path& path, const Mode mode) const override; - - /** - * Delete a file specified by its path - * @param path Path relative to the archive - * @return Whether the file could be deleted - */ - bool DeleteFile(const Path& path) const override; - - /** - * Rename a File specified by its path - * @param src_path Source path relative to the archive - * @param dest_path Destination path relative to the archive - * @return Whether rename succeeded - */ - bool RenameFile(const Path& src_path, const Path& dest_path) const override; - - /** - * Delete a directory specified by its path - * @param path Path relative to the archive - * @return Whether the directory could be deleted - */ - bool DeleteDirectory(const Path& path) const override; - - /** - * Create a file specified by its path - * @param path Path relative to the Archive - * @param size The size of the new file, filled with zeroes - * @return File creation result code - */ - ResultCode CreateFile(const Path& path, u32 size) const override; - - /** - * Create a directory specified by its path - * @param path Path relative to the archive - * @return Whether the directory could be created - */ - bool CreateDirectory(const Path& path) const override; - - /** - * Rename a Directory specified by its path - * @param src_path Source path relative to the archive - * @param dest_path Destination path relative to the archive - * @return Whether rename succeeded - */ - bool RenameDirectory(const Path& src_path, const Path& dest_path) const override; - - /** - * Open a directory specified by its path - * @param path Path relative to the archive - * @return Opened directory, or nullptr - */ - std::unique_ptr OpenDirectory(const Path& path) const override; - - ResultCode Open(const Path& path) override; - - ResultCode Format(const Path& path) const override; - -private: - friend class File_RomFS; - std::string mount_point; - std::vector raw_data; + ResultCode Open(const Path& path) override { return RESULT_SUCCESS; } }; } // namespace FileSys diff --git a/src/core/file_sys/archive_savedatacheck.cpp b/src/core/file_sys/archive_savedatacheck.cpp new file mode 100644 index 0000000000..233158a0ca --- /dev/null +++ b/src/core/file_sys/archive_savedatacheck.cpp @@ -0,0 +1,41 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "common/file_util.h" + +#include "core/file_sys/archive_savedatacheck.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// FileSys namespace + +namespace FileSys { + +Archive_SaveDataCheck::Archive_SaveDataCheck(const std::string& mount_loc) : mount_point(mount_loc) { +} + +ResultCode Archive_SaveDataCheck::Open(const Path& path) { + // TODO(Subv): We should not be overwriting raw_data everytime this function is called, + // but until we use factory classes to create the archives at runtime instead of creating them beforehand + // and allow multiple archives of the same type to be open at the same time without clobbering each other, + // we won't be able to maintain the state of each archive, hence we overwrite it every time it's needed. + // There are a number of problems with this, for example opening a file in this archive, then opening + // this archive again with a different path, will corrupt the previously open file. + auto vec = path.AsBinary(); + const u32* data = reinterpret_cast(vec.data()); + std::string file_path = Common::StringFromFormat("%s%08x%08x.bin", mount_point.c_str(), data[1], data[0]); + FileUtil::IOFile file(file_path, "rb"); + + std::fill(raw_data.begin(), raw_data.end(), 0); + + if (!file.IsOpen()) { + return ResultCode(-1); // TODO(Subv): Find the right error code + } + auto size = file.GetSize(); + raw_data.resize(size); + file.ReadBytes(raw_data.data(), size); + file.Close(); + return RESULT_SUCCESS; +} + +} // namespace FileSys diff --git a/src/core/file_sys/archive_savedatacheck.h b/src/core/file_sys/archive_savedatacheck.h new file mode 100644 index 0000000000..f6e73e8037 --- /dev/null +++ b/src/core/file_sys/archive_savedatacheck.h @@ -0,0 +1,31 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include + +#include "common/common_types.h" + +#include "core/file_sys/ivfc_archive.h" +#include "core/loader/loader.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// FileSys namespace + +namespace FileSys { + +/// File system interface to the SaveDataCheck archive +class Archive_SaveDataCheck final : public IVFCArchive { +public: + Archive_SaveDataCheck(const std::string& mount_point); + + std::string GetName() const override { return "SaveDataCheck"; } + ResultCode Open(const Path& path) override; + +private: + std::string mount_point; +}; + +} // namespace FileSys diff --git a/src/core/file_sys/directory_romfs.cpp b/src/core/file_sys/directory_romfs.cpp deleted file mode 100644 index e130aca17e..0000000000 --- a/src/core/file_sys/directory_romfs.cpp +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2014 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#include "common/common_types.h" - -#include "core/file_sys/directory_romfs.h" - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// FileSys namespace - -namespace FileSys { - -Directory_RomFS::Directory_RomFS() { -} - -Directory_RomFS::~Directory_RomFS() { -} - -bool Directory_RomFS::Open() { - return false; -} - -u32 Directory_RomFS::Read(const u32 count, Entry* entries) { - return 0; -} - -bool Directory_RomFS::Close() const { - return false; -} - -} // namespace FileSys diff --git a/src/core/file_sys/directory_romfs.h b/src/core/file_sys/directory_romfs.h deleted file mode 100644 index 2297f16456..0000000000 --- a/src/core/file_sys/directory_romfs.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2014 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#pragma once - -#include "common/common_types.h" - -#include "core/file_sys/directory_backend.h" -#include "core/loader/loader.h" - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// FileSys namespace - -namespace FileSys { - -class Directory_RomFS final : public DirectoryBackend { -public: - Directory_RomFS(); - ~Directory_RomFS() override; - - /** - * Open the directory - * @return true if the directory opened correctly - */ - bool Open() override; - - /** - * List files contained in the directory - * @param count Number of entries to return at once in entries - * @param entries Buffer to read data into - * @return Number of entries listed - */ - u32 Read(const u32 count, Entry* entries) override; - - /** - * Close the directory - * @return true if the directory closed correctly - */ - bool Close() const override; -}; - -} // namespace FileSys diff --git a/src/core/file_sys/file_romfs.cpp b/src/core/file_sys/file_romfs.cpp deleted file mode 100644 index 7467d6d319..0000000000 --- a/src/core/file_sys/file_romfs.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2014 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#include "common/common_types.h" - -#include "core/file_sys/file_romfs.h" -#include "core/file_sys/archive_romfs.h" - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// FileSys namespace - -namespace FileSys { - -bool File_RomFS::Open() { - return true; -} - -size_t File_RomFS::Read(const u64 offset, const u32 length, u8* buffer) const { - LOG_TRACE(Service_FS, "called offset=%llu, length=%d", offset, length); - memcpy(buffer, &archive->raw_data[(u32)offset], length); - return length; -} - -size_t File_RomFS::Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const { - LOG_WARNING(Service_FS, "Attempted to write to ROMFS."); - return 0; -} - -size_t File_RomFS::GetSize() const { - return sizeof(u8) * archive->raw_data.size(); -} - -bool File_RomFS::SetSize(const u64 size) const { - LOG_WARNING(Service_FS, "Attempted to set the size of ROMFS"); - return false; -} - -bool File_RomFS::Close() const { - return false; -} - -} // namespace FileSys diff --git a/src/core/file_sys/file_romfs.h b/src/core/file_sys/file_romfs.h deleted file mode 100644 index 04d8a16a25..0000000000 --- a/src/core/file_sys/file_romfs.h +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2014 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#pragma once - -#include "common/common_types.h" - -#include "core/file_sys/file_backend.h" -#include "core/loader/loader.h" - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// FileSys namespace - -namespace FileSys { - -class Archive_RomFS; - -class File_RomFS final : public FileBackend { -public: - File_RomFS(const Archive_RomFS* archive) : archive(archive) {} - - /** - * Open the file - * @return true if the file opened correctly - */ - bool Open() override; - - /** - * Read data from the file - * @param offset Offset in bytes to start reading data from - * @param length Length in bytes of data to read from file - * @param buffer Buffer to read data into - * @return Number of bytes read - */ - size_t Read(const u64 offset, const u32 length, u8* buffer) const override; - - /** - * Write data to the file - * @param offset Offset in bytes to start writing data to - * @param length Length in bytes of data to write to file - * @param flush The flush parameters (0 == do not flush) - * @param buffer Buffer to read data from - * @return Number of bytes written - */ - size_t Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const override; - - /** - * Get the size of the file in bytes - * @return Size of the file in bytes - */ - size_t GetSize() const override; - - /** - * Set the size of the file in bytes - * @param size New size of the file - * @return true if successful - */ - bool SetSize(const u64 size) const override; - - /** - * Close the file - * @return true if the file closed correctly - */ - bool Close() const override; - - void Flush() const override { } - -private: - const Archive_RomFS* archive; -}; - -} // namespace FileSys diff --git a/src/core/file_sys/ivfc_archive.cpp b/src/core/file_sys/ivfc_archive.cpp new file mode 100644 index 0000000000..300b95413d --- /dev/null +++ b/src/core/file_sys/ivfc_archive.cpp @@ -0,0 +1,88 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include + +#include "common/common_types.h" +#include "common/file_util.h" +#include "common/make_unique.h" + +#include "core/file_sys/ivfc_archive.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// FileSys namespace + +namespace FileSys { + +IVFCArchive::IVFCArchive() { +} + +std::unique_ptr IVFCArchive::OpenFile(const Path& path, const Mode mode) const { + return Common::make_unique(this); +} + +bool IVFCArchive::DeleteFile(const Path& path) const { + LOG_WARNING(Service_FS, "Attempted to delete a file from an IVFC archive (%s).", GetName().c_str()); + return false; +} + +bool IVFCArchive::RenameFile(const Path& src_path, const Path& dest_path) const { + LOG_WARNING(Service_FS, "Attempted to rename a file within an IVFC archive (%s).", GetName().c_str()); + return false; +} + +bool IVFCArchive::DeleteDirectory(const Path& path) const { + LOG_WARNING(Service_FS, "Attempted to delete a directory from an IVFC archive (%s).", GetName().c_str()); + return false; +} + +ResultCode IVFCArchive::CreateFile(const Path& path, u32 size) const { + LOG_WARNING(Service_FS, "Attempted to create a file in an IVFC archive (%s).", GetName().c_str()); + // TODO: Verify error code + return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, ErrorLevel::Permanent); +} + +bool IVFCArchive::CreateDirectory(const Path& path) const { + LOG_WARNING(Service_FS, "Attempted to create a directory in an IVFC archive (%s).", GetName().c_str()); + return false; +} + +bool IVFCArchive::RenameDirectory(const Path& src_path, const Path& dest_path) const { + LOG_WARNING(Service_FS, "Attempted to rename a file within an IVFC archive (%s).", GetName().c_str()); + return false; +} + +std::unique_ptr IVFCArchive::OpenDirectory(const Path& path) const { + return Common::make_unique(); +} + +ResultCode IVFCArchive::Format(const Path& path) const { + LOG_WARNING(Service_FS, "Attempted to format an IVFC archive (%s).", GetName().c_str()); + // TODO: Verify error code + return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, ErrorLevel::Permanent); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +size_t IVFCFile::Read(const u64 offset, const u32 length, u8* buffer) const { + LOG_TRACE(Service_FS, "called offset=%llu, length=%d", offset, length); + memcpy(buffer, &archive->raw_data[(u32)offset], length); + return length; +} + +size_t IVFCFile::Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const { + LOG_WARNING(Service_FS, "Attempted to write to IVFC file in archive %s.", archive->GetName().c_str()); + return 0; +} + +size_t IVFCFile::GetSize() const { + return sizeof(u8) * archive->raw_data.size(); +} + +bool IVFCFile::SetSize(const u64 size) const { + LOG_WARNING(Service_FS, "Attempted to set the size of an IVFC file in archive %s", archive->GetName().c_str()); + return false; +} + +} // namespace FileSys diff --git a/src/core/file_sys/ivfc_archive.h b/src/core/file_sys/ivfc_archive.h new file mode 100644 index 0000000000..fd9a3042d3 --- /dev/null +++ b/src/core/file_sys/ivfc_archive.h @@ -0,0 +1,63 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include + +#include "common/common_types.h" + +#include "core/file_sys/archive_backend.h" +#include "core/loader/loader.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// FileSys namespace + +namespace FileSys { + +class IVFCArchive : public ArchiveBackend { +public: + IVFCArchive(); + + std::unique_ptr OpenFile(const Path& path, const Mode mode) const override; + bool DeleteFile(const Path& path) const override; + bool RenameFile(const Path& src_path, const Path& dest_path) const override; + bool DeleteDirectory(const Path& path) const override; + ResultCode CreateFile(const Path& path, u32 size) const override; + bool CreateDirectory(const Path& path) const override; + bool RenameDirectory(const Path& src_path, const Path& dest_path) const override; + std::unique_ptr OpenDirectory(const Path& path) const override; + ResultCode Format(const Path& path) const override; + +protected: + friend class IVFCFile; + std::vector raw_data; +}; + +class IVFCFile : public FileBackend { +public: + IVFCFile(const IVFCArchive* archive) : archive(archive) {} + + bool Open() override { return true; } + size_t Read(const u64 offset, const u32 length, u8* buffer) const override; + size_t Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const override; + size_t GetSize() const override; + bool SetSize(const u64 size) const override; + bool Close() const override { return false; } + void Flush() const override { } + +private: + const IVFCArchive* archive; +}; + +class IVFCDirectory : public DirectoryBackend { +public: + IVFCDirectory() { } + + bool Open() override { return false; } + u32 Read(const u32 count, Entry* entries) override { return 0; } + bool Close() const override { return false; } +}; + +} // namespace FileSys diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index a8383d4e5d..f761c6ab9d 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -14,6 +14,7 @@ #include "core/file_sys/archive_extsavedata.h" #include "core/file_sys/archive_romfs.h" #include "core/file_sys/archive_savedata.h" +#include "core/file_sys/archive_savedatacheck.h" #include "core/file_sys/archive_sdmc.h" #include "core/file_sys/directory_backend.h" #include "core/hle/service/fs/archive.h" @@ -353,7 +354,7 @@ ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSy ErrorSummary::Canceled, ErrorLevel::Status); } -ResultCode CreateFileInArchive(Handle archive_handle, const FileSys::Path& path, u32 file_size) { +ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, u32 file_size) { Archive* archive = GetArchive(archive_handle); if (archive == nullptr) return InvalidHandle(ErrorModule::FS); @@ -463,8 +464,8 @@ void ArchiveInit() { sharedextsavedata_directory.c_str()); // Create the SaveDataCheck archive, basically a small variation of the RomFS archive - std::string savedatacheck_directory = FileUtil::GetUserPath(D_SAVEDATA_IDX) + "../savedatacheck/"; - auto savedatacheck_archive = Common::make_unique(savedatacheck_directory); + std::string savedatacheck_directory = FileUtil::GetUserPath(D_SAVEDATACHECK_IDX); + auto savedatacheck_archive = Common::make_unique(savedatacheck_directory); CreateArchive(std::move(savedatacheck_archive), ArchiveIdCode::SaveDataCheck); } diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h index f2e4e4a536..9e9efa019a 100644 --- a/src/core/hle/service/fs/archive.h +++ b/src/core/hle/service/fs/archive.h @@ -91,7 +91,7 @@ ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSy * @param file_size The size of the new file, filled with zeroes * @return File creation result code */ -ResultCode CreateFileInArchive(Handle archive_handle, const FileSys::Path& path, u32 file_size); +ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, u32 file_size); /** * Create a Directory from an Archive From 2f9a2d410db05489ff3fa0bfee32817cb414949f Mon Sep 17 00:00:00 2001 From: Subv Date: Thu, 1 Jan 2015 12:44:38 -0500 Subject: [PATCH 3/5] Archives: Added some documentation to IVFCArchive --- src/core/file_sys/ivfc_archive.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/core/file_sys/ivfc_archive.h b/src/core/file_sys/ivfc_archive.h index fd9a3042d3..a9b34434f6 100644 --- a/src/core/file_sys/ivfc_archive.h +++ b/src/core/file_sys/ivfc_archive.h @@ -16,6 +16,11 @@ namespace FileSys { +/** + * Helper which implements an interface to deal with IVFC images used in some archives + * This should be subclassed by concrete archive types, which will provide the + * input data (load the raw IVFC archive) and override any required methods + */ class IVFCArchive : public ArchiveBackend { public: IVFCArchive(); From 0d03fdec71eae53efebeccca4cd803b04b41cc38 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 2 Jan 2015 21:28:46 -0500 Subject: [PATCH 4/5] SaveDataCheck: Remove unneeded constructor from a class --- src/core/file_sys/ivfc_archive.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/core/file_sys/ivfc_archive.h b/src/core/file_sys/ivfc_archive.h index a9b34434f6..6f4cc86df3 100644 --- a/src/core/file_sys/ivfc_archive.h +++ b/src/core/file_sys/ivfc_archive.h @@ -58,8 +58,6 @@ private: class IVFCDirectory : public DirectoryBackend { public: - IVFCDirectory() { } - bool Open() override { return false; } u32 Read(const u32 count, Entry* entries) override { return 0; } bool Close() const override { return false; } From 22cfa55302dbefdd3099522ae250c0d5723c2869 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 2 Jan 2015 21:39:31 -0500 Subject: [PATCH 5/5] IVFCArchive: Use a critical log to notify of invalid operations. --- src/core/file_sys/ivfc_archive.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/core/file_sys/ivfc_archive.cpp b/src/core/file_sys/ivfc_archive.cpp index 300b95413d..68c3c8b814 100644 --- a/src/core/file_sys/ivfc_archive.cpp +++ b/src/core/file_sys/ivfc_archive.cpp @@ -23,33 +23,33 @@ std::unique_ptr IVFCArchive::OpenFile(const Path& path, const Mode } bool IVFCArchive::DeleteFile(const Path& path) const { - LOG_WARNING(Service_FS, "Attempted to delete a file from an IVFC archive (%s).", GetName().c_str()); + LOG_CRITICAL(Service_FS, "Attempted to delete a file from an IVFC archive (%s).", GetName().c_str()); return false; } bool IVFCArchive::RenameFile(const Path& src_path, const Path& dest_path) const { - LOG_WARNING(Service_FS, "Attempted to rename a file within an IVFC archive (%s).", GetName().c_str()); + LOG_CRITICAL(Service_FS, "Attempted to rename a file within an IVFC archive (%s).", GetName().c_str()); return false; } bool IVFCArchive::DeleteDirectory(const Path& path) const { - LOG_WARNING(Service_FS, "Attempted to delete a directory from an IVFC archive (%s).", GetName().c_str()); + LOG_CRITICAL(Service_FS, "Attempted to delete a directory from an IVFC archive (%s).", GetName().c_str()); return false; } ResultCode IVFCArchive::CreateFile(const Path& path, u32 size) const { - LOG_WARNING(Service_FS, "Attempted to create a file in an IVFC archive (%s).", GetName().c_str()); + LOG_CRITICAL(Service_FS, "Attempted to create a file in an IVFC archive (%s).", GetName().c_str()); // TODO: Verify error code return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, ErrorLevel::Permanent); } bool IVFCArchive::CreateDirectory(const Path& path) const { - LOG_WARNING(Service_FS, "Attempted to create a directory in an IVFC archive (%s).", GetName().c_str()); + LOG_CRITICAL(Service_FS, "Attempted to create a directory in an IVFC archive (%s).", GetName().c_str()); return false; } bool IVFCArchive::RenameDirectory(const Path& src_path, const Path& dest_path) const { - LOG_WARNING(Service_FS, "Attempted to rename a file within an IVFC archive (%s).", GetName().c_str()); + LOG_CRITICAL(Service_FS, "Attempted to rename a file within an IVFC archive (%s).", GetName().c_str()); return false; } @@ -58,7 +58,7 @@ std::unique_ptr IVFCArchive::OpenDirectory(const Path& path) c } ResultCode IVFCArchive::Format(const Path& path) const { - LOG_WARNING(Service_FS, "Attempted to format an IVFC archive (%s).", GetName().c_str()); + LOG_CRITICAL(Service_FS, "Attempted to format an IVFC archive (%s).", GetName().c_str()); // TODO: Verify error code return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, ErrorLevel::Permanent); } @@ -72,7 +72,7 @@ size_t IVFCFile::Read(const u64 offset, const u32 length, u8* buffer) const { } size_t IVFCFile::Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const { - LOG_WARNING(Service_FS, "Attempted to write to IVFC file in archive %s.", archive->GetName().c_str()); + LOG_CRITICAL(Service_FS, "Attempted to write to IVFC file in archive %s.", archive->GetName().c_str()); return 0; } @@ -81,7 +81,7 @@ size_t IVFCFile::GetSize() const { } bool IVFCFile::SetSize(const u64 size) const { - LOG_WARNING(Service_FS, "Attempted to set the size of an IVFC file in archive %s", archive->GetName().c_str()); + LOG_CRITICAL(Service_FS, "Attempted to set the size of an IVFC file in archive %s", archive->GetName().c_str()); return false; }