From a69afb06705ea517148bb014817d191ef887fb8e Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Mon, 15 Dec 2014 22:00:37 -0200 Subject: [PATCH 01/11] Travis: Enable tracing on the script to ease troubleshooting --- .travis-build.sh | 1 + .travis-deps.sh | 1 + 2 files changed, 2 insertions(+) diff --git a/.travis-build.sh b/.travis-build.sh index 78e7583a8..b869b8b8f 100644 --- a/.travis-build.sh +++ b/.travis-build.sh @@ -1,6 +1,7 @@ #!/bin/sh set -e +set -x #if OS is linux or is not set if [ "$TRAVIS_OS_NAME" = linux -o -z "$TRAVIS_OS_NAME" ]; then diff --git a/.travis-deps.sh b/.travis-deps.sh index b8e8417b2..c8a06e0a8 100644 --- a/.travis-deps.sh +++ b/.travis-deps.sh @@ -1,6 +1,7 @@ #!/bin/sh set -e +set -x #if OS is linux or is not set if [ "$TRAVIS_OS_NAME" = linux -o -z "$TRAVIS_OS_NAME" ]; then From b5d9f7364e18aa2f596f6c8a466b1544a6c33a59 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Mon, 15 Dec 2014 21:55:28 -0200 Subject: [PATCH 02/11] Travis: Use gcc 4.9 instead of 4.8 since it's getting installed anyway --- .travis-deps.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis-deps.sh b/.travis-deps.sh index c8a06e0a8..8e22a6358 100644 --- a/.travis-deps.sh +++ b/.travis-deps.sh @@ -7,8 +7,8 @@ set -x if [ "$TRAVIS_OS_NAME" = linux -o -z "$TRAVIS_OS_NAME" ]; then sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y sudo apt-get -qq update - sudo apt-get -qq install g++-4.8 xorg-dev libglu1-mesa-dev libxcursor-dev - sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 90 + sudo apt-get -qq install g++-4.9 xorg-dev libglu1-mesa-dev libxcursor-dev + sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.9 90 ( git clone https://github.com/glfw/glfw.git --branch 3.0.4 --depth 1 mkdir glfw/build && cd glfw/build From 731b31fe972be473500db3a130aab79ba21a0c08 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Mon, 15 Dec 2014 22:06:03 -0200 Subject: [PATCH 03/11] Switch to C++14 to use std::make_unique --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 61d5d524a..63738b5ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,8 @@ cmake_minimum_required(VERSION 2.8.11) project(citra) if (NOT MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-attributes") + # -std=c++14 is only supported on very new compilers, so use the old c++1y alias instead. + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y -Wno-attributes") else() # Silence deprecation warnings add_definitions(/D_CRT_SECURE_NO_WARNINGS) From c72ccfa6db41039ef2eb0ce118fabe1b38da841e Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Sun, 14 Dec 2014 04:32:45 -0200 Subject: [PATCH 04/11] HLE: Move kernel/archive.* to service/fs/ --- src/core/CMakeLists.txt | 8 ++++---- src/core/hle/kernel/kernel.cpp | 2 +- src/core/hle/{kernel => service/fs}/archive.cpp | 2 +- src/core/hle/{kernel => service/fs}/archive.h | 0 src/core/hle/service/{ => fs}/fs_user.cpp | 5 ++--- src/core/hle/service/{ => fs}/fs_user.h | 0 src/core/hle/service/service.cpp | 2 +- src/core/loader/3dsx.cpp | 2 +- src/core/loader/loader.cpp | 2 +- 9 files changed, 11 insertions(+), 12 deletions(-) rename src/core/hle/{kernel => service/fs}/archive.cpp (99%) rename src/core/hle/{kernel => service/fs}/archive.h (100%) rename src/core/hle/service/{ => fs}/fs_user.cpp (99%) rename src/core/hle/service/{ => fs}/fs_user.h (100%) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index ab63f54de..18a417475 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -24,7 +24,6 @@ set(SRCS file_sys/directory_romfs.cpp file_sys/directory_sdmc.cpp hle/kernel/address_arbiter.cpp - hle/kernel/archive.cpp hle/kernel/event.cpp hle/kernel/kernel.cpp hle/kernel/mutex.cpp @@ -40,7 +39,8 @@ set(SRCS hle/service/csnd_snd.cpp hle/service/dsp_dsp.cpp hle/service/err_f.cpp - hle/service/fs_user.cpp + hle/service/fs/archive.cpp + hle/service/fs/fs_user.cpp hle/service/frd_u.cpp hle/service/gsp_gpu.cpp hle/service/hid_user.cpp @@ -103,7 +103,6 @@ set(HEADERS file_sys/directory_romfs.h file_sys/directory_sdmc.h hle/kernel/address_arbiter.h - hle/kernel/archive.h hle/kernel/event.h hle/kernel/kernel.h hle/kernel/mutex.h @@ -120,7 +119,8 @@ set(HEADERS hle/service/csnd_snd.h hle/service/dsp_dsp.h hle/service/err_f.h - hle/service/fs_user.h + hle/service/fs/archive.h + hle/service/fs/fs_user.h hle/service/frd_u.h hle/service/gsp_gpu.h hle/service/hid_user.h diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index b38be0a49..95b4dfd68 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -9,7 +9,7 @@ #include "core/core.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/thread.h" -#include "core/hle/kernel/archive.h" +#include "core/hle/service/fs/archive.h" namespace Kernel { diff --git a/src/core/hle/kernel/archive.cpp b/src/core/hle/service/fs/archive.cpp similarity index 99% rename from src/core/hle/kernel/archive.cpp rename to src/core/hle/service/fs/archive.cpp index 0e3eb4564..8889c6339 100644 --- a/src/core/hle/kernel/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -11,7 +11,7 @@ #include "core/file_sys/archive.h" #include "core/file_sys/archive_sdmc.h" #include "core/file_sys/directory.h" -#include "core/hle/kernel/archive.h" +#include "core/hle/service/fs/archive.h" #include "core/hle/kernel/session.h" #include "core/hle/result.h" diff --git a/src/core/hle/kernel/archive.h b/src/core/hle/service/fs/archive.h similarity index 100% rename from src/core/hle/kernel/archive.h rename to src/core/hle/service/fs/archive.h diff --git a/src/core/hle/service/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp similarity index 99% rename from src/core/hle/service/fs_user.cpp rename to src/core/hle/service/fs/fs_user.cpp index 672ba2475..c61b283c9 100644 --- a/src/core/hle/service/fs_user.cpp +++ b/src/core/hle/service/fs/fs_user.cpp @@ -5,10 +5,9 @@ #include "common/common.h" #include "common/string_util.h" -#include "core/hle/kernel/archive.h" -#include "core/hle/kernel/archive.h" +#include "core/hle/service/fs/archive.h" #include "core/hle/result.h" -#include "core/hle/service/fs_user.h" +#include "core/hle/service/fs/fs_user.h" #include "core/settings.h" //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/fs_user.h b/src/core/hle/service/fs/fs_user.h similarity index 100% rename from src/core/hle/service/fs_user.h rename to src/core/hle/service/fs/fs_user.h diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index e6973572b..68d199acc 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -15,7 +15,7 @@ #include "core/hle/service/csnd_snd.h" #include "core/hle/service/dsp_dsp.h" #include "core/hle/service/err_f.h" -#include "core/hle/service/fs_user.h" +#include "core/hle/service/fs/fs_user.h" #include "core/hle/service/frd_u.h" #include "core/hle/service/gsp_gpu.h" #include "core/hle/service/hid_user.h" diff --git a/src/core/loader/3dsx.cpp b/src/core/loader/3dsx.cpp index f48d13530..0437e5374 100644 --- a/src/core/loader/3dsx.cpp +++ b/src/core/loader/3dsx.cpp @@ -8,7 +8,7 @@ #include "core/file_sys/archive_romfs.h" #include "core/loader/elf.h" #include "core/loader/ncch.h" -#include "core/hle/kernel/archive.h" +#include "core/hle/service/fs/archive.h" #include "core/mem_map.h" #include "3dsx.h" diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index 3883e1307..d7786f1b2 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -8,7 +8,7 @@ #include "core/loader/3dsx.h" #include "core/loader/elf.h" #include "core/loader/ncch.h" -#include "core/hle/kernel/archive.h" +#include "core/hle/service/fs/archive.h" #include "core/mem_map.h" //////////////////////////////////////////////////////////////////////////////////////////////////// From ca67bb7945bf358cf38242a04febfd3375760947 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Sun, 14 Dec 2014 05:55:11 -0200 Subject: [PATCH 05/11] HLE: Rename namespaces to match move & fix initialization order --- src/citra_qt/main.cpp | 6 ------ src/core/hle/hle.cpp | 3 +++ src/core/hle/kernel/kernel.cpp | 5 ----- src/core/hle/service/fs/archive.cpp | 9 ++++---- src/core/hle/service/fs/archive.h | 9 ++++---- src/core/hle/service/fs/fs_user.cpp | 32 +++++++++++++++-------------- src/core/hle/service/fs/fs_user.h | 12 ++++++----- src/core/hle/service/service.cpp | 2 +- src/core/loader/loader.cpp | 2 +- src/core/system.cpp | 12 +++++------ 10 files changed, 43 insertions(+), 49 deletions(-) diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index 1299338ac..23d4925b8 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -157,12 +157,6 @@ void GMainWindow::BootGame(std::string filename) LOG_INFO(Frontend, "Citra starting...\n"); System::Init(render_window); - if (Core::Init()) { - LOG_CRITICAL(Frontend, "Core initialization failed, exiting..."); - Core::Stop(); - exit(1); - } - // Load a game or die... if (Loader::ResultStatus::Success != Loader::LoadFile(filename)) { LOG_CRITICAL(Frontend, "Failed to load ROM!"); diff --git a/src/core/hle/hle.cpp b/src/core/hle/hle.cpp index 3f73b5538..cc3d5255a 100644 --- a/src/core/hle/hle.cpp +++ b/src/core/hle/hle.cpp @@ -8,6 +8,7 @@ #include "core/hle/hle.h" #include "core/hle/kernel/thread.h" #include "core/hle/service/service.h" +#include "core/hle/service/fs/archive.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -56,6 +57,7 @@ void RegisterAllModules() { void Init() { Service::Init(); + Service::FS::ArchiveInit(); RegisterAllModules(); @@ -63,6 +65,7 @@ void Init() { } void Shutdown() { + Service::FS::ArchiveShutdown(); Service::Shutdown(); g_module_db.clear(); diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 95b4dfd68..929422b36 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -9,7 +9,6 @@ #include "core/core.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/thread.h" -#include "core/hle/service/fs/archive.h" namespace Kernel { @@ -89,13 +88,11 @@ Object* ObjectPool::CreateByIDType(int type) { /// Initialize the kernel void Init() { Kernel::ThreadingInit(); - Kernel::ArchiveInit(); } /// Shutdown the kernel void Shutdown() { Kernel::ThreadingShutdown(); - Kernel::ArchiveShutdown(); g_object_pool.Clear(); // Free all kernel objects } @@ -106,8 +103,6 @@ void Shutdown() { * @return True on success, otherwise false */ bool LoadExec(u32 entry_point) { - Init(); - Core::g_app_core->SetPC(entry_point); // 0x30 is the typical main thread priority I've seen used so far diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 8889c6339..5893a944b 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -15,10 +15,8 @@ #include "core/hle/kernel/session.h" #include "core/hle/result.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Kernel namespace - -namespace Kernel { +namespace Service { +namespace FS { // Command to access archive file enum class FileCommand : u32 { @@ -423,4 +421,5 @@ void ArchiveShutdown() { g_archive_map.clear(); } -} // namespace Kernel +} // namespace FS +} // namespace Service diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h index b50833a2b..a7ee212d3 100644 --- a/src/core/hle/service/fs/archive.h +++ b/src/core/hle/service/fs/archive.h @@ -10,10 +10,8 @@ #include "core/hle/kernel/kernel.h" #include "core/hle/result.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Kernel namespace - -namespace Kernel { +namespace Service { +namespace FS { /** * Opens an archive @@ -104,4 +102,5 @@ void ArchiveInit(); /// Shutdown archives void ArchiveShutdown(); -} // namespace FileSys +} // namespace FS +} // namespace Service diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp index c61b283c9..76689c6af 100644 --- a/src/core/hle/service/fs/fs_user.cpp +++ b/src/core/hle/service/fs/fs_user.cpp @@ -13,7 +13,8 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// // Namespace FS_User -namespace FS_User { +namespace Service { +namespace FS { static void Initialize(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); @@ -56,7 +57,7 @@ static void OpenFile(Service::Interface* self) { LOG_DEBUG(Service_FS, "path=%s, mode=%d attrs=%u", file_path.DebugStr().c_str(), mode.hex, attributes); - ResultVal handle = Kernel::OpenFileFromArchive(archive_handle, file_path, mode); + ResultVal handle = OpenFileFromArchive(archive_handle, file_path, mode); cmd_buff[1] = handle.Code().raw; if (handle.Succeeded()) { cmd_buff[3] = *handle; @@ -110,7 +111,7 @@ static void OpenFileDirectly(Service::Interface* self) { // TODO(Link Mauve): Check if we should even get a handle for the archive, and don't leak it // TODO(yuriks): Why is there all this duplicate (and seemingly useless) code up here? - ResultVal archive_handle = Kernel::OpenArchive(archive_id); + ResultVal archive_handle = OpenArchive(archive_id); cmd_buff[1] = archive_handle.Code().raw; if (archive_handle.Failed()) { LOG_ERROR(Service_FS, "failed to get a handle for archive"); @@ -119,7 +120,7 @@ static void OpenFileDirectly(Service::Interface* self) { // cmd_buff[2] isn't used according to 3dmoo's implementation. cmd_buff[3] = *archive_handle; - ResultVal handle = Kernel::OpenFileFromArchive(*archive_handle, file_path, mode); + ResultVal handle = OpenFileFromArchive(*archive_handle, file_path, mode); cmd_buff[1] = handle.Code().raw; if (handle.Succeeded()) { cmd_buff[3] = *handle; @@ -154,7 +155,7 @@ void DeleteFile(Service::Interface* self) { LOG_DEBUG(Service_FS, "type=%d size=%d data=%s", filename_type, filename_size, file_path.DebugStr().c_str()); - cmd_buff[1] = Kernel::DeleteFileFromArchive(archive_handle, file_path).raw; + cmd_buff[1] = DeleteFileFromArchive(archive_handle, file_path).raw; } /* @@ -194,7 +195,7 @@ void RenameFile(Service::Interface* self) { src_filename_type, src_filename_size, src_file_path.DebugStr().c_str(), dest_filename_type, dest_filename_size, dest_file_path.DebugStr().c_str()); - cmd_buff[1] = Kernel::RenameFileBetweenArchives(src_archive_handle, src_file_path, dest_archive_handle, dest_file_path).raw; + cmd_buff[1] = RenameFileBetweenArchives(src_archive_handle, src_file_path, dest_archive_handle, dest_file_path).raw; } /* @@ -223,7 +224,7 @@ void DeleteDirectory(Service::Interface* self) { LOG_DEBUG(Service_FS, "type=%d size=%d data=%s", dirname_type, dirname_size, dir_path.DebugStr().c_str()); - cmd_buff[1] = Kernel::DeleteDirectoryFromArchive(archive_handle, dir_path).raw; + cmd_buff[1] = DeleteDirectoryFromArchive(archive_handle, dir_path).raw; } /* @@ -251,7 +252,7 @@ static void CreateDirectory(Service::Interface* self) { LOG_DEBUG(Service_FS, "type=%d size=%d data=%s", dirname_type, dirname_size, dir_path.DebugStr().c_str()); - cmd_buff[1] = Kernel::CreateDirectoryFromArchive(archive_handle, dir_path).raw; + cmd_buff[1] = CreateDirectoryFromArchive(archive_handle, dir_path).raw; } /* @@ -291,7 +292,7 @@ void RenameDirectory(Service::Interface* self) { src_dirname_type, src_dirname_size, src_dir_path.DebugStr().c_str(), dest_dirname_type, dest_dirname_size, dest_dir_path.DebugStr().c_str()); - cmd_buff[1] = Kernel::RenameDirectoryBetweenArchives(src_archive_handle, src_dir_path, dest_archive_handle, dest_dir_path).raw; + cmd_buff[1] = RenameDirectoryBetweenArchives(src_archive_handle, src_dir_path, dest_archive_handle, dest_dir_path).raw; } static void OpenDirectory(Service::Interface* self) { @@ -308,7 +309,7 @@ static void OpenDirectory(Service::Interface* self) { LOG_DEBUG(Service_FS, "type=%d size=%d data=%s", dirname_type, dirname_size, dir_path.DebugStr().c_str()); - ResultVal handle = Kernel::OpenDirectoryFromArchive(archive_handle, dir_path); + ResultVal handle = OpenDirectoryFromArchive(archive_handle, dir_path); cmd_buff[1] = handle.Code().raw; if (handle.Succeeded()) { cmd_buff[3] = *handle; @@ -347,7 +348,7 @@ static void OpenArchive(Service::Interface* self) { return; } - ResultVal handle = Kernel::OpenArchive(archive_id); + ResultVal handle = OpenArchive(archive_id); cmd_buff[1] = handle.Code().raw; if (handle.Succeeded()) { // cmd_buff[2] isn't used according to 3dmoo's implementation. @@ -372,7 +373,7 @@ static void IsSdmcDetected(Service::Interface* self) { LOG_DEBUG(Service_FS, "called"); } -const Interface::FunctionInfo FunctionTable[] = { +const FSUserInterface::FunctionInfo FunctionTable[] = { {0x000100C6, nullptr, "Dummy1"}, {0x040100C4, nullptr, "Control"}, {0x08010002, Initialize, "Initialize"}, @@ -464,11 +465,12 @@ const Interface::FunctionInfo FunctionTable[] = { //////////////////////////////////////////////////////////////////////////////////////////////////// // Interface class -Interface::Interface() { +FSUserInterface::FSUserInterface() { Register(FunctionTable, ARRAY_SIZE(FunctionTable)); } -Interface::~Interface() { +FSUserInterface::~FSUserInterface() { } -} // namespace +} // namespace FS +} // namespace Service diff --git a/src/core/hle/service/fs/fs_user.h b/src/core/hle/service/fs/fs_user.h index 005382540..80e3804e0 100644 --- a/src/core/hle/service/fs/fs_user.h +++ b/src/core/hle/service/fs/fs_user.h @@ -9,15 +9,16 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// // Namespace FS_User -namespace FS_User { +namespace Service { +namespace FS { /// Interface to "fs:USER" service -class Interface : public Service::Interface { +class FSUserInterface : public Service::Interface { public: - Interface(); + FSUserInterface(); - ~Interface(); + ~FSUserInterface(); /** * Gets the string port name used by CTROS for the service @@ -28,4 +29,5 @@ public: } }; -} // namespace +} // namespace FS +} // namespace Service diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 68d199acc..037211e73 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -93,7 +93,7 @@ void Init() { g_manager->AddService(new DSP_DSP::Interface); g_manager->AddService(new ERR_F::Interface); g_manager->AddService(new FRD_U::Interface); - g_manager->AddService(new FS_User::Interface); + g_manager->AddService(new FS::FSUserInterface); g_manager->AddService(new GSP_GPU::Interface); g_manager->AddService(new HID_User::Interface); g_manager->AddService(new IR_RST::Interface); diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index d7786f1b2..6ce752561 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -74,7 +74,7 @@ ResultStatus LoadFile(const std::string& filename) { // Load application and RomFS if (ResultStatus::Success == app_loader.Load()) { - Kernel::CreateArchive(new FileSys::Archive_RomFS(app_loader), "RomFS"); + Service::FS::CreateArchive(new FileSys::Archive_RomFS(app_loader), "RomFS"); return ResultStatus::Success; } break; diff --git a/src/core/system.cpp b/src/core/system.cpp index 43d0eef2c..2885ff45f 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -23,10 +23,10 @@ void Init(EmuWindow* emu_window) { Core::Init(); Memory::Init(); HW::Init(); + Kernel::Init(); HLE::Init(); CoreTiming::Init(); VideoCore::Init(emu_window); - Kernel::Init(); } void RunLoopFor(int cycles) { @@ -37,13 +37,13 @@ void RunLoopUntil(u64 global_cycles) { } void Shutdown() { - Core::Shutdown(); - Memory::Shutdown(); - HW::Shutdown(); - HLE::Shutdown(); - CoreTiming::Shutdown(); VideoCore::Shutdown(); + CoreTiming::Shutdown(); + HLE::Shutdown(); Kernel::Shutdown(); + HW::Shutdown(); + Memory::Shutdown(); + Core::Shutdown(); } } // namespace From f6153679b0781eea084b22f3ceecc74b1fe6b018 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Mon, 15 Dec 2014 02:44:04 -0200 Subject: [PATCH 06/11] Service.FS: Do archive registration using IdCode instead of name --- src/core/file_sys/archive.h | 17 ++--------------- src/core/file_sys/archive_romfs.h | 6 +----- src/core/file_sys/archive_sdmc.h | 6 +----- src/core/hle/service/fs/archive.cpp | 20 ++++++++++---------- src/core/hle/service/fs/archive.h | 19 +++++++++++++++---- src/core/hle/service/fs/fs_user.cpp | 4 ++-- src/core/loader/loader.cpp | 2 +- 7 files changed, 32 insertions(+), 42 deletions(-) diff --git a/src/core/file_sys/archive.h b/src/core/file_sys/archive.h index 27ed23cd0..b7978bfbe 100644 --- a/src/core/file_sys/archive.h +++ b/src/core/file_sys/archive.h @@ -162,25 +162,12 @@ private: class Archive : NonCopyable { public: - /// Supported archive types - enum class IdCode : u32 { - RomFS = 0x00000003, - SaveData = 0x00000004, - ExtSaveData = 0x00000006, - SharedExtSaveData = 0x00000007, - SystemSaveData = 0x00000008, - SDMC = 0x00000009, - SDMCWriteOnly = 0x0000000A, - }; - - Archive() { } virtual ~Archive() { } /** - * Get the IdCode of the archive (e.g. RomFS, SaveData, etc.) - * @return IdCode of the archive + * Get a descriptive name for the archive (e.g. "RomFS", "SaveData", etc.) */ - virtual IdCode GetIdCode() const = 0; + virtual std::string GetName() const = 0; /** * Open a file specified by its path, using the specified mode diff --git a/src/core/file_sys/archive_romfs.h b/src/core/file_sys/archive_romfs.h index 222bdc356..b60fcca99 100644 --- a/src/core/file_sys/archive_romfs.h +++ b/src/core/file_sys/archive_romfs.h @@ -22,11 +22,7 @@ public: Archive_RomFS(const Loader::AppLoader& app_loader); ~Archive_RomFS() override; - /** - * Get the IdCode of the archive (e.g. RomFS, SaveData, etc.) - * @return IdCode of the archive - */ - IdCode GetIdCode() const override { return IdCode::RomFS; } + std::string GetName() const override { return "RomFS"; } /** * Open a file specified by its path, using the specified mode diff --git a/src/core/file_sys/archive_sdmc.h b/src/core/file_sys/archive_sdmc.h index 19f563a62..54c18cb0c 100644 --- a/src/core/file_sys/archive_sdmc.h +++ b/src/core/file_sys/archive_sdmc.h @@ -26,11 +26,7 @@ public: */ bool Initialize(); - /** - * Get the IdCode of the archive (e.g. RomFS, SaveData, etc.) - * @return IdCode of the archive - */ - IdCode GetIdCode() const override { return IdCode::SDMC; } + std::string GetName() const override { return "SDMC"; } /** * Open a file specified by its path, using the specified mode diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 5893a944b..61cbfa73c 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -43,9 +43,9 @@ enum class DirectoryCommand : u32 { class Archive : public Kernel::Session { public: - std::string GetName() const override { return "Archive: " + name; } + std::string GetName() const override { return "Archive: " + backend->GetName(); } - std::string name; ///< Name of archive (optional) + ArchiveIdCode id_code; ///< Id code of the archive FileSys::Archive* backend; ///< Archive backend interface ResultVal SyncRequest() override { @@ -91,7 +91,7 @@ public: case FileCommand::Close: { LOG_TRACE(Service_FS, "Close %s %s", GetTypeName().c_str(), GetName().c_str()); - CloseArchive(backend->GetIdCode()); + CloseArchive(id_code); break; } // Unknown command... @@ -228,9 +228,9 @@ public: //////////////////////////////////////////////////////////////////////////////////////////////////// -std::map g_archive_map; ///< Map of file archives by IdCode +std::map g_archive_map; ///< Map of file archives by IdCode -ResultVal OpenArchive(FileSys::Archive::IdCode id_code) { +ResultVal OpenArchive(ArchiveIdCode id_code) { auto itr = g_archive_map.find(id_code); if (itr == g_archive_map.end()) { return ResultCode(ErrorDescription::NotFound, ErrorModule::FS, @@ -240,7 +240,7 @@ ResultVal OpenArchive(FileSys::Archive::IdCode id_code) { return MakeResult(itr->second); } -ResultCode CloseArchive(FileSys::Archive::IdCode id_code) { +ResultCode CloseArchive(ArchiveIdCode id_code) { auto itr = g_archive_map.find(id_code); if (itr == g_archive_map.end()) { LOG_ERROR(Service_FS, "Cannot close archive %d, does not exist!", (int)id_code); @@ -256,7 +256,7 @@ ResultCode CloseArchive(FileSys::Archive::IdCode id_code) { * @param archive Pointer to the archive to mount */ ResultCode MountArchive(Archive* archive) { - FileSys::Archive::IdCode id_code = archive->backend->GetIdCode(); + ArchiveIdCode id_code = archive->id_code; ResultVal archive_handle = OpenArchive(id_code); if (archive_handle.Succeeded()) { LOG_ERROR(Service_FS, "Cannot mount two archives with the same ID code! (%d)", (int) id_code); @@ -267,10 +267,10 @@ ResultCode MountArchive(Archive* archive) { return RESULT_SUCCESS; } -ResultCode CreateArchive(FileSys::Archive* backend, const std::string& name) { +ResultCode CreateArchive(FileSys::Archive* backend, ArchiveIdCode id_code) { Archive* archive = new Archive; Handle handle = Kernel::g_object_pool.Create(archive); - archive->name = name; + archive->id_code = id_code; archive->backend = backend; ResultCode result = MountArchive(archive); @@ -411,7 +411,7 @@ void ArchiveInit() { std::string sdmc_directory = FileUtil::GetUserPath(D_SDMC_IDX); auto archive = new FileSys::Archive_SDMC(sdmc_directory); if (archive->Initialize()) - CreateArchive(archive, "SDMC"); + CreateArchive(archive, ArchiveIdCode::SDMC); else LOG_ERROR(Service_FS, "Can't instantiate SDMC archive with path %s", sdmc_directory.c_str()); } diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h index a7ee212d3..9a1df5110 100644 --- a/src/core/hle/service/fs/archive.h +++ b/src/core/hle/service/fs/archive.h @@ -13,25 +13,36 @@ namespace Service { namespace FS { +/// Supported archive types +enum class ArchiveIdCode : u32 { + RomFS = 0x00000003, + SaveData = 0x00000004, + ExtSaveData = 0x00000006, + SharedExtSaveData = 0x00000007, + SystemSaveData = 0x00000008, + SDMC = 0x00000009, + SDMCWriteOnly = 0x0000000A, +}; + /** * Opens an archive * @param id_code IdCode of the archive to open * @return Handle to the opened archive */ -ResultVal OpenArchive(FileSys::Archive::IdCode id_code); +ResultVal OpenArchive(ArchiveIdCode id_code); /** * Closes an archive * @param id_code IdCode of the archive to open */ -ResultCode CloseArchive(FileSys::Archive::IdCode id_code); +ResultCode CloseArchive(ArchiveIdCode id_code); /** * Creates an Archive * @param backend File system backend interface to the archive - * @param name Name of Archive + * @param id_code Id code used to access this type of archive */ -ResultCode CreateArchive(FileSys::Archive* backend, const std::string& name); +ResultCode CreateArchive(FileSys::Archive* backend, ArchiveIdCode id_code); /** * Open a File from an Archive diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp index 76689c6af..eda7cb8ab 100644 --- a/src/core/hle/service/fs/fs_user.cpp +++ b/src/core/hle/service/fs/fs_user.cpp @@ -88,7 +88,7 @@ static void OpenFile(Service::Interface* self) { static void OpenFileDirectly(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - auto archive_id = static_cast(cmd_buff[2]); + auto archive_id = static_cast(cmd_buff[2]); auto archivename_type = static_cast(cmd_buff[3]); u32 archivename_size = cmd_buff[4]; auto filename_type = static_cast(cmd_buff[5]); @@ -334,7 +334,7 @@ static void OpenDirectory(Service::Interface* self) { static void OpenArchive(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - auto archive_id = static_cast(cmd_buff[1]); + auto archive_id = static_cast(cmd_buff[1]); auto archivename_type = static_cast(cmd_buff[2]); u32 archivename_size = cmd_buff[3]; u32 archivename_ptr = cmd_buff[5]; diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index 6ce752561..49f8c458d 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -74,7 +74,7 @@ ResultStatus LoadFile(const std::string& filename) { // Load application and RomFS if (ResultStatus::Success == app_loader.Load()) { - Service::FS::CreateArchive(new FileSys::Archive_RomFS(app_loader), "RomFS"); + Service::FS::CreateArchive(new FileSys::Archive_RomFS(app_loader), Service::FS::ArchiveIdCode::RomFS); return ResultStatus::Success; } break; From 82fe821e8734faab6cad29bc0377c2f630c1f876 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Mon, 15 Dec 2014 02:51:38 -0200 Subject: [PATCH 07/11] Service.FS: Rename FileSys::Archive to ArchiveBackend --- src/core/CMakeLists.txt | 2 +- src/core/file_sys/{archive.h => archive_backend.h} | 4 ++-- src/core/file_sys/archive_romfs.h | 4 ++-- src/core/file_sys/archive_sdmc.h | 4 ++-- src/core/hle/service/fs/archive.cpp | 6 +++--- src/core/hle/service/fs/archive.h | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) rename src/core/file_sys/{archive.h => archive_backend.h} (99%) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 18a417475..463f14eee 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -93,7 +93,7 @@ set(HEADERS arm/skyeye_common/vfp/vfp.h arm/skyeye_common/vfp/vfp_helper.h arm/arm_interface.h - file_sys/archive.h + file_sys/archive_backend.h file_sys/archive_romfs.h file_sys/archive_sdmc.h file_sys/file.h diff --git a/src/core/file_sys/archive.h b/src/core/file_sys/archive_backend.h similarity index 99% rename from src/core/file_sys/archive.h rename to src/core/file_sys/archive_backend.h index b7978bfbe..0558698f6 100644 --- a/src/core/file_sys/archive.h +++ b/src/core/file_sys/archive_backend.h @@ -160,9 +160,9 @@ private: std::u16string u16str; }; -class Archive : NonCopyable { +class ArchiveBackend : NonCopyable { public: - virtual ~Archive() { } + virtual ~ArchiveBackend() { } /** * Get a descriptive name for the archive (e.g. "RomFS", "SaveData", etc.) diff --git a/src/core/file_sys/archive_romfs.h b/src/core/file_sys/archive_romfs.h index b60fcca99..91505da49 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.h" +#include "core/file_sys/archive_backend.h" #include "core/loader/loader.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -17,7 +17,7 @@ namespace FileSys { /// File system interface to the RomFS archive -class Archive_RomFS final : public Archive { +class Archive_RomFS final : public ArchiveBackend { public: Archive_RomFS(const Loader::AppLoader& app_loader); ~Archive_RomFS() override; diff --git a/src/core/file_sys/archive_sdmc.h b/src/core/file_sys/archive_sdmc.h index 54c18cb0c..347f3945e 100644 --- a/src/core/file_sys/archive_sdmc.h +++ b/src/core/file_sys/archive_sdmc.h @@ -6,7 +6,7 @@ #include "common/common_types.h" -#include "core/file_sys/archive.h" +#include "core/file_sys/archive_backend.h" #include "core/loader/loader.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -15,7 +15,7 @@ namespace FileSys { /// File system interface to the SDMC archive -class Archive_SDMC final : public Archive { +class Archive_SDMC final : public ArchiveBackend { public: Archive_SDMC(const std::string& mount_point); ~Archive_SDMC() override; diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 61cbfa73c..6ec310a63 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -8,7 +8,7 @@ #include "common/file_util.h" #include "common/math_util.h" -#include "core/file_sys/archive.h" +#include "core/file_sys/archive_backend.h" #include "core/file_sys/archive_sdmc.h" #include "core/file_sys/directory.h" #include "core/hle/service/fs/archive.h" @@ -46,7 +46,7 @@ public: std::string GetName() const override { return "Archive: " + backend->GetName(); } ArchiveIdCode id_code; ///< Id code of the archive - FileSys::Archive* backend; ///< Archive backend interface + FileSys::ArchiveBackend* backend; ///< Archive backend interface ResultVal SyncRequest() override { u32* cmd_buff = Kernel::GetCommandBuffer(); @@ -267,7 +267,7 @@ ResultCode MountArchive(Archive* archive) { return RESULT_SUCCESS; } -ResultCode CreateArchive(FileSys::Archive* backend, ArchiveIdCode id_code) { +ResultCode CreateArchive(FileSys::ArchiveBackend* backend, ArchiveIdCode id_code) { Archive* archive = new Archive; Handle handle = Kernel::g_object_pool.Create(archive); archive->id_code = id_code; diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h index 9a1df5110..2c50dfff0 100644 --- a/src/core/hle/service/fs/archive.h +++ b/src/core/hle/service/fs/archive.h @@ -6,7 +6,7 @@ #include "common/common_types.h" -#include "core/file_sys/archive.h" +#include "core/file_sys/archive_backend.h" #include "core/hle/kernel/kernel.h" #include "core/hle/result.h" @@ -42,7 +42,7 @@ ResultCode CloseArchive(ArchiveIdCode id_code); * @param backend File system backend interface to the archive * @param id_code Id code used to access this type of archive */ -ResultCode CreateArchive(FileSys::Archive* backend, ArchiveIdCode id_code); +ResultCode CreateArchive(FileSys::ArchiveBackend* backend, ArchiveIdCode id_code); /** * Open a File from an Archive From d51afab0bc3a7e06a73f9f51afaf26cf83d87cd2 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Mon, 15 Dec 2014 04:59:29 -0200 Subject: [PATCH 08/11] Service.FS: Rename FileSys::Directory to DirectoryBackend --- src/core/CMakeLists.txt | 2 +- src/core/file_sys/archive_backend.h | 4 ++-- src/core/file_sys/archive_romfs.cpp | 4 ++-- src/core/file_sys/archive_romfs.h | 2 +- src/core/file_sys/archive_sdmc.cpp | 4 ++-- src/core/file_sys/archive_sdmc.h | 2 +- src/core/file_sys/{directory.h => directory_backend.h} | 6 +++--- src/core/file_sys/directory_romfs.h | 4 ++-- src/core/file_sys/directory_sdmc.h | 4 ++-- src/core/hle/service/fs/archive.cpp | 4 ++-- 10 files changed, 18 insertions(+), 18 deletions(-) rename src/core/file_sys/{directory.h => directory_backend.h} (95%) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 463f14eee..c0ebd1c7e 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -99,7 +99,7 @@ set(HEADERS file_sys/file.h file_sys/file_romfs.h file_sys/file_sdmc.h - file_sys/directory.h + file_sys/directory_backend.h file_sys/directory_romfs.h file_sys/directory_sdmc.h hle/kernel/address_arbiter.h diff --git a/src/core/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h index 0558698f6..49a310383 100644 --- a/src/core/file_sys/archive_backend.h +++ b/src/core/file_sys/archive_backend.h @@ -11,7 +11,7 @@ #include "common/bit_field.h" #include "core/file_sys/file.h" -#include "core/file_sys/directory.h" +#include "core/file_sys/directory_backend.h" #include "core/mem_map.h" #include "core/hle/kernel/kernel.h" @@ -219,7 +219,7 @@ public: * @param path Path relative to the archive * @return Opened directory, or nullptr */ - virtual std::unique_ptr OpenDirectory(const Path& path) const = 0; + virtual std::unique_ptr OpenDirectory(const Path& path) const = 0; /** * Read data from the archive diff --git a/src/core/file_sys/archive_romfs.cpp b/src/core/file_sys/archive_romfs.cpp index 74974c2df..8db7d69c5 100644 --- a/src/core/file_sys/archive_romfs.cpp +++ b/src/core/file_sys/archive_romfs.cpp @@ -78,8 +78,8 @@ bool Archive_RomFS::RenameDirectory(const FileSys::Path& src_path, const FileSys * @param path Path relative to the archive * @return Opened directory, or nullptr */ -std::unique_ptr Archive_RomFS::OpenDirectory(const Path& path) const { - return std::unique_ptr(new Directory_RomFS); +std::unique_ptr Archive_RomFS::OpenDirectory(const Path& path) const { + return std::unique_ptr(new Directory_RomFS); } /** diff --git a/src/core/file_sys/archive_romfs.h b/src/core/file_sys/archive_romfs.h index 91505da49..5a8a6b04d 100644 --- a/src/core/file_sys/archive_romfs.h +++ b/src/core/file_sys/archive_romfs.h @@ -74,7 +74,7 @@ public: * @param path Path relative to the archive * @return Opened directory, or nullptr */ - std::unique_ptr OpenDirectory(const Path& path) const override; + std::unique_ptr OpenDirectory(const Path& path) const override; /** * Read data from the archive diff --git a/src/core/file_sys/archive_sdmc.cpp b/src/core/file_sys/archive_sdmc.cpp index 9e524b60e..9d26d2285 100644 --- a/src/core/file_sys/archive_sdmc.cpp +++ b/src/core/file_sys/archive_sdmc.cpp @@ -97,12 +97,12 @@ bool Archive_SDMC::RenameDirectory(const FileSys::Path& src_path, const FileSys: * @param path Path relative to the archive * @return Opened directory, or nullptr */ -std::unique_ptr Archive_SDMC::OpenDirectory(const Path& path) const { +std::unique_ptr Archive_SDMC::OpenDirectory(const Path& path) const { LOG_DEBUG(Service_FS, "called path=%s", path.DebugStr().c_str()); Directory_SDMC* directory = new Directory_SDMC(this, path); if (!directory->Open()) return nullptr; - return std::unique_ptr(directory); + return std::unique_ptr(directory); } /** diff --git a/src/core/file_sys/archive_sdmc.h b/src/core/file_sys/archive_sdmc.h index 347f3945e..f4cb96159 100644 --- a/src/core/file_sys/archive_sdmc.h +++ b/src/core/file_sys/archive_sdmc.h @@ -78,7 +78,7 @@ public: * @param path Path relative to the archive * @return Opened directory, or nullptr */ - std::unique_ptr OpenDirectory(const Path& path) const override; + std::unique_ptr OpenDirectory(const Path& path) const override; /** * Read data from the archive diff --git a/src/core/file_sys/directory.h b/src/core/file_sys/directory_backend.h similarity index 95% rename from src/core/file_sys/directory.h rename to src/core/file_sys/directory_backend.h index 1bb4101d6..188746a6f 100644 --- a/src/core/file_sys/directory.h +++ b/src/core/file_sys/directory_backend.h @@ -36,10 +36,10 @@ static_assert(offsetof(Entry, extension) == 0x216, "Wrong offset for extension i static_assert(offsetof(Entry, is_archive) == 0x21E, "Wrong offset for is_archive in Entry."); static_assert(offsetof(Entry, file_size) == 0x220, "Wrong offset for file_size in Entry."); -class Directory : NonCopyable { +class DirectoryBackend : NonCopyable { public: - Directory() { } - virtual ~Directory() { } + DirectoryBackend() { } + virtual ~DirectoryBackend() { } /** * Open the directory diff --git a/src/core/file_sys/directory_romfs.h b/src/core/file_sys/directory_romfs.h index e2944099e..b775f014d 100644 --- a/src/core/file_sys/directory_romfs.h +++ b/src/core/file_sys/directory_romfs.h @@ -6,7 +6,7 @@ #include "common/common_types.h" -#include "core/file_sys/directory.h" +#include "core/file_sys/directory_backend.h" #include "core/loader/loader.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -14,7 +14,7 @@ namespace FileSys { -class Directory_RomFS final : public Directory { +class Directory_RomFS final : public DirectoryBackend { public: Directory_RomFS(); ~Directory_RomFS() override; diff --git a/src/core/file_sys/directory_sdmc.h b/src/core/file_sys/directory_sdmc.h index 4c08b0d61..407a256ef 100644 --- a/src/core/file_sys/directory_sdmc.h +++ b/src/core/file_sys/directory_sdmc.h @@ -7,7 +7,7 @@ #include "common/common_types.h" #include "common/file_util.h" -#include "core/file_sys/directory.h" +#include "core/file_sys/directory_backend.h" #include "core/file_sys/archive_sdmc.h" #include "core/loader/loader.h" @@ -16,7 +16,7 @@ namespace FileSys { -class Directory_SDMC final : public Directory { +class Directory_SDMC final : public DirectoryBackend { public: Directory_SDMC(); Directory_SDMC(const Archive_SDMC* archive, const Path& path); diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 6ec310a63..9a3725138 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -10,7 +10,7 @@ #include "core/file_sys/archive_backend.h" #include "core/file_sys/archive_sdmc.h" -#include "core/file_sys/directory.h" +#include "core/file_sys/directory_backend.h" #include "core/hle/service/fs/archive.h" #include "core/hle/kernel/session.h" #include "core/hle/result.h" @@ -186,7 +186,7 @@ public: std::string GetName() const override { return "Directory: " + path.DebugStr(); } FileSys::Path path; ///< Path of the directory - std::unique_ptr backend; ///< File backend interface + std::unique_ptr backend; ///< File backend interface ResultVal SyncRequest() override { u32* cmd_buff = Kernel::GetCommandBuffer(); From 0931a42af0c0666dd9fbc20484b399c0e1ad3361 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Mon, 15 Dec 2014 05:03:17 -0200 Subject: [PATCH 09/11] Service.FS: Rename FileSys::File to FileBackend --- src/core/CMakeLists.txt | 2 +- src/core/file_sys/archive_backend.h | 4 ++-- src/core/file_sys/archive_romfs.cpp | 4 ++-- src/core/file_sys/archive_romfs.h | 2 +- src/core/file_sys/archive_sdmc.cpp | 4 ++-- src/core/file_sys/archive_sdmc.h | 2 +- src/core/file_sys/{file.h => file_backend.h} | 6 +++--- src/core/file_sys/file_romfs.h | 4 ++-- src/core/file_sys/file_sdmc.h | 4 ++-- src/core/hle/service/fs/archive.cpp | 2 +- 10 files changed, 17 insertions(+), 17 deletions(-) rename src/core/file_sys/{file.h => file_backend.h} (95%) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index c0ebd1c7e..ce63aab09 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -96,7 +96,7 @@ set(HEADERS file_sys/archive_backend.h file_sys/archive_romfs.h file_sys/archive_sdmc.h - file_sys/file.h + file_sys/file_backend.h file_sys/file_romfs.h file_sys/file_sdmc.h file_sys/directory_backend.h diff --git a/src/core/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h index 49a310383..8d7a6a057 100644 --- a/src/core/file_sys/archive_backend.h +++ b/src/core/file_sys/archive_backend.h @@ -10,7 +10,7 @@ #include "common/string_util.h" #include "common/bit_field.h" -#include "core/file_sys/file.h" +#include "core/file_sys/file_backend.h" #include "core/file_sys/directory_backend.h" #include "core/mem_map.h" @@ -175,7 +175,7 @@ public: * @param mode Mode to open the file with * @return Opened file, or nullptr */ - virtual std::unique_ptr OpenFile(const Path& path, const Mode mode) const = 0; + virtual std::unique_ptr OpenFile(const Path& path, const Mode mode) const = 0; /** * Delete a file specified by its path diff --git a/src/core/file_sys/archive_romfs.cpp b/src/core/file_sys/archive_romfs.cpp index 8db7d69c5..c515e0dd9 100644 --- a/src/core/file_sys/archive_romfs.cpp +++ b/src/core/file_sys/archive_romfs.cpp @@ -29,8 +29,8 @@ Archive_RomFS::~Archive_RomFS() { * @param mode Mode to open the file with * @return Opened file, or nullptr */ -std::unique_ptr Archive_RomFS::OpenFile(const Path& path, const Mode mode) const { - return std::unique_ptr(new File_RomFS); +std::unique_ptr Archive_RomFS::OpenFile(const Path& path, const Mode mode) const { + return std::unique_ptr(new File_RomFS); } /** diff --git a/src/core/file_sys/archive_romfs.h b/src/core/file_sys/archive_romfs.h index 5a8a6b04d..0390821bf 100644 --- a/src/core/file_sys/archive_romfs.h +++ b/src/core/file_sys/archive_romfs.h @@ -30,7 +30,7 @@ public: * @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; + std::unique_ptr OpenFile(const Path& path, const Mode mode) const override; /** * Delete a file specified by its path diff --git a/src/core/file_sys/archive_sdmc.cpp b/src/core/file_sys/archive_sdmc.cpp index 9d26d2285..43252b98b 100644 --- a/src/core/file_sys/archive_sdmc.cpp +++ b/src/core/file_sys/archive_sdmc.cpp @@ -49,12 +49,12 @@ bool Archive_SDMC::Initialize() { * @param mode Mode to open the file with * @return Opened file, or nullptr */ -std::unique_ptr Archive_SDMC::OpenFile(const Path& path, const Mode mode) const { +std::unique_ptr Archive_SDMC::OpenFile(const Path& path, const Mode mode) const { LOG_DEBUG(Service_FS, "called path=%s mode=%u", path.DebugStr().c_str(), mode.hex); File_SDMC* file = new File_SDMC(this, path, mode); if (!file->Open()) return nullptr; - return std::unique_ptr(file); + return std::unique_ptr(file); } /** diff --git a/src/core/file_sys/archive_sdmc.h b/src/core/file_sys/archive_sdmc.h index f4cb96159..5920051f7 100644 --- a/src/core/file_sys/archive_sdmc.h +++ b/src/core/file_sys/archive_sdmc.h @@ -34,7 +34,7 @@ public: * @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; + std::unique_ptr OpenFile(const Path& path, const Mode mode) const override; /** * Delete a file specified by its path diff --git a/src/core/file_sys/file.h b/src/core/file_sys/file_backend.h similarity index 95% rename from src/core/file_sys/file.h rename to src/core/file_sys/file_backend.h index 4013b6c3e..1b81d5fe9 100644 --- a/src/core/file_sys/file.h +++ b/src/core/file_sys/file_backend.h @@ -13,10 +13,10 @@ namespace FileSys { -class File : NonCopyable { +class FileBackend : NonCopyable { public: - File() { } - virtual ~File() { } + FileBackend() { } + virtual ~FileBackend() { } /** * Open the file diff --git a/src/core/file_sys/file_romfs.h b/src/core/file_sys/file_romfs.h index 5196701d3..4ddaafe21 100644 --- a/src/core/file_sys/file_romfs.h +++ b/src/core/file_sys/file_romfs.h @@ -6,7 +6,7 @@ #include "common/common_types.h" -#include "core/file_sys/file.h" +#include "core/file_sys/file_backend.h" #include "core/loader/loader.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -14,7 +14,7 @@ namespace FileSys { -class File_RomFS final : public File { +class File_RomFS final : public FileBackend { public: File_RomFS(); ~File_RomFS() override; diff --git a/src/core/file_sys/file_sdmc.h b/src/core/file_sys/file_sdmc.h index 80b445968..e01548598 100644 --- a/src/core/file_sys/file_sdmc.h +++ b/src/core/file_sys/file_sdmc.h @@ -7,7 +7,7 @@ #include "common/common_types.h" #include "common/file_util.h" -#include "core/file_sys/file.h" +#include "core/file_sys/file_backend.h" #include "core/file_sys/archive_sdmc.h" #include "core/loader/loader.h" @@ -16,7 +16,7 @@ namespace FileSys { -class File_SDMC final : public File { +class File_SDMC final : public FileBackend { public: File_SDMC(); File_SDMC(const Archive_SDMC* archive, const Path& path, const Mode mode); diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 9a3725138..d04e5b2e7 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -112,7 +112,7 @@ public: std::string GetName() const override { return "Path: " + path.DebugStr(); } FileSys::Path path; ///< Path of the file - std::unique_ptr backend; ///< File backend interface + std::unique_ptr backend; ///< File backend interface ResultVal SyncRequest() override { u32* cmd_buff = Kernel::GetCommandBuffer(); From 83e6e4ffec9ca67fbca5536bb0ed7b4876ade0db Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Mon, 15 Dec 2014 06:41:02 -0200 Subject: [PATCH 10/11] FS.Archive: Clean up treatment of archives and their handles - Refactor FS::Archive internals to make Archive creation and lifetime management clearer. - Remove the "Archive as a File" hack. - Implement 64-bit Archive handles. --- src/core/file_sys/archive_backend.h | 30 --- src/core/file_sys/archive_romfs.cpp | 50 +---- src/core/file_sys/archive_romfs.h | 33 +--- src/core/file_sys/archive_sdmc.cpp | 41 ----- src/core/file_sys/archive_sdmc.h | 30 --- src/core/file_sys/file_romfs.cpp | 19 +- src/core/file_sys/file_romfs.h | 8 +- src/core/hle/service/fs/archive.cpp | 274 ++++++++++++---------------- src/core/hle/service/fs/archive.h | 26 +-- src/core/hle/service/fs/fs_user.cpp | 93 ++++++---- src/core/loader/loader.cpp | 2 +- 11 files changed, 208 insertions(+), 398 deletions(-) diff --git a/src/core/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h index 8d7a6a057..18c314884 100644 --- a/src/core/file_sys/archive_backend.h +++ b/src/core/file_sys/archive_backend.h @@ -220,36 +220,6 @@ public: * @return Opened directory, or nullptr */ virtual std::unique_ptr OpenDirectory(const Path& path) const = 0; - - /** - * Read data from the archive - * @param offset Offset in bytes to start reading data from - * @param length Length in bytes of data to read from archive - * @param buffer Buffer to read data into - * @return Number of bytes read - */ - virtual size_t Read(const u64 offset, const u32 length, u8* buffer) const = 0; - - /** - * Write data to the archive - * @param offset Offset in bytes to start writing data to - * @param length Length in bytes of data to write to archive - * @param buffer Buffer to write data from - * @param flush The flush parameters (0 == do not flush) - * @return Number of bytes written - */ - virtual size_t Write(const u64 offset, const u32 length, const u32 flush, u8* buffer) = 0; - - /** - * Get the size of the archive in bytes - * @return Size of the archive in bytes - */ - virtual size_t GetSize() const = 0; - - /** - * Set the size of the archive in bytes - */ - virtual void SetSize(const u64 size) = 0; }; } // namespace FileSys diff --git a/src/core/file_sys/archive_romfs.cpp b/src/core/file_sys/archive_romfs.cpp index c515e0dd9..0709b62a1 100644 --- a/src/core/file_sys/archive_romfs.cpp +++ b/src/core/file_sys/archive_romfs.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2 // Refer to the license.txt file included. +#include + #include "common/common_types.h" #include "core/file_sys/archive_romfs.h" @@ -20,9 +22,6 @@ Archive_RomFS::Archive_RomFS(const Loader::AppLoader& app_loader) { } } -Archive_RomFS::~Archive_RomFS() { -} - /** * Open a file specified by its path, using the specified mode * @param path Path relative to the archive @@ -30,7 +29,7 @@ Archive_RomFS::~Archive_RomFS() { * @return Opened file, or nullptr */ std::unique_ptr Archive_RomFS::OpenFile(const Path& path, const Mode mode) const { - return std::unique_ptr(new File_RomFS); + return std::make_unique(this); } /** @@ -79,48 +78,7 @@ bool Archive_RomFS::RenameDirectory(const FileSys::Path& src_path, const FileSys * @return Opened directory, or nullptr */ std::unique_ptr Archive_RomFS::OpenDirectory(const Path& path) const { - return std::unique_ptr(new Directory_RomFS); -} - -/** - * Read data from the archive - * @param offset Offset in bytes to start reading data from - * @param length Length in bytes of data to read from archive - * @param buffer Buffer to read data into - * @return Number of bytes read - */ -size_t Archive_RomFS::Read(const u64 offset, const u32 length, u8* buffer) const { - LOG_TRACE(Service_FS, "called offset=%llu, length=%d", offset, length); - memcpy(buffer, &raw_data[(u32)offset], length); - return length; -} - -/** - * Write data to the archive - * @param offset Offset in bytes to start writing data to - * @param length Length in bytes of data to write to archive - * @param buffer Buffer to write data from - * @param flush The flush parameters (0 == do not flush) - * @return Number of bytes written - */ -size_t Archive_RomFS::Write(const u64 offset, const u32 length, const u32 flush, u8* buffer) { - LOG_WARNING(Service_FS, "Attempted to write to ROMFS."); - return 0; -} - -/** - * Get the size of the archive in bytes - * @return Size of the archive in bytes - */ -size_t Archive_RomFS::GetSize() const { - return sizeof(u8) * raw_data.size(); -} - -/** - * Set the size of the archive in bytes - */ -void Archive_RomFS::SetSize(const u64 size) { - LOG_WARNING(Service_FS, "Attempted to set the size of ROMFS"); + return std::make_unique(); } } // namespace FileSys diff --git a/src/core/file_sys/archive_romfs.h b/src/core/file_sys/archive_romfs.h index 0390821bf..5b1ee6332 100644 --- a/src/core/file_sys/archive_romfs.h +++ b/src/core/file_sys/archive_romfs.h @@ -20,7 +20,6 @@ namespace FileSys { class Archive_RomFS final : public ArchiveBackend { public: Archive_RomFS(const Loader::AppLoader& app_loader); - ~Archive_RomFS() override; std::string GetName() const override { return "RomFS"; } @@ -76,37 +75,9 @@ public: */ std::unique_ptr OpenDirectory(const Path& path) const override; - /** - * Read data from the archive - * @param offset Offset in bytes to start reading data from - * @param length Length in bytes of data to read from archive - * @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 archive - * @param offset Offset in bytes to start writing data to - * @param length Length in bytes of data to write to archive - * @param buffer Buffer to write data from - * @param flush The flush parameters (0 == do not flush) - * @return Number of bytes written - */ - size_t Write(const u64 offset, const u32 length, const u32 flush, u8* buffer) override; - - /** - * Get the size of the archive in bytes - * @return Size of the archive in bytes - */ - size_t GetSize() const override; - - /** - * Set the size of the archive in bytes - */ - void SetSize(const u64 size) override; - private: + friend class File_RomFS; + std::vector raw_data; }; diff --git a/src/core/file_sys/archive_sdmc.cpp b/src/core/file_sys/archive_sdmc.cpp index 43252b98b..9d58668e0 100644 --- a/src/core/file_sys/archive_sdmc.cpp +++ b/src/core/file_sys/archive_sdmc.cpp @@ -105,47 +105,6 @@ std::unique_ptr Archive_SDMC::OpenDirectory(const Path& path) return std::unique_ptr(directory); } -/** - * Read data from the archive - * @param offset Offset in bytes to start reading archive from - * @param length Length in bytes to read data from archive - * @param buffer Buffer to read data into - * @return Number of bytes read - */ -size_t Archive_SDMC::Read(const u64 offset, const u32 length, u8* buffer) const { - LOG_ERROR(Service_FS, "(UNIMPLEMENTED)"); - return -1; -} - -/** - * Write data to the archive - * @param offset Offset in bytes to start writing data to - * @param length Length in bytes of data to write to archive - * @param buffer Buffer to write data from - * @param flush The flush parameters (0 == do not flush) - * @return Number of bytes written - */ -size_t Archive_SDMC::Write(const u64 offset, const u32 length, const u32 flush, u8* buffer) { - LOG_ERROR(Service_FS, "(UNIMPLEMENTED)"); - return -1; -} - -/** - * Get the size of the archive in bytes - * @return Size of the archive in bytes - */ -size_t Archive_SDMC::GetSize() const { - LOG_ERROR(Service_FS, "(UNIMPLEMENTED)"); - return 0; -} - -/** - * Set the size of the archive in bytes - */ -void Archive_SDMC::SetSize(const u64 size) { - LOG_ERROR(Service_FS, "(UNIMPLEMENTED)"); -} - /** * Getter for the path used for this Archive * @return Mount point of that passthrough archive diff --git a/src/core/file_sys/archive_sdmc.h b/src/core/file_sys/archive_sdmc.h index 5920051f7..059045245 100644 --- a/src/core/file_sys/archive_sdmc.h +++ b/src/core/file_sys/archive_sdmc.h @@ -80,36 +80,6 @@ public: */ std::unique_ptr OpenDirectory(const Path& path) const override; - /** - * Read data from the archive - * @param offset Offset in bytes to start reading archive from - * @param length Length in bytes to read data from archive - * @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 archive - * @param offset Offset in bytes to start writing data to - * @param length Length in bytes of data to write to archive - * @param buffer Buffer to write data from - * @param flush The flush parameters (0 == do not flush) - * @return Number of bytes written - */ - size_t Write(const u64 offset, const u32 length, const u32 flush, u8* buffer) override; - - /** - * Get the size of the archive in bytes - * @return Size of the archive in bytes - */ - size_t GetSize() const override; - - /** - * Set the size of the archive in bytes - */ - void SetSize(const u64 size) override; - /** * Getter for the path used for this Archive * @return Mount point of that passthrough archive diff --git a/src/core/file_sys/file_romfs.cpp b/src/core/file_sys/file_romfs.cpp index b55708df4..5f38c2704 100644 --- a/src/core/file_sys/file_romfs.cpp +++ b/src/core/file_sys/file_romfs.cpp @@ -5,24 +5,19 @@ #include "common/common_types.h" #include "core/file_sys/file_romfs.h" +#include "core/file_sys/archive_romfs.h" //////////////////////////////////////////////////////////////////////////////////////////////////// // FileSys namespace namespace FileSys { -File_RomFS::File_RomFS() { -} - -File_RomFS::~File_RomFS() { -} - /** * Open the file * @return true if the file opened correctly */ bool File_RomFS::Open() { - return false; + return true; } /** @@ -33,7 +28,9 @@ bool File_RomFS::Open() { * @return Number of bytes read */ size_t File_RomFS::Read(const u64 offset, const u32 length, u8* buffer) const { - return -1; + LOG_TRACE(Service_FS, "called offset=%llu, length=%d", offset, length); + memcpy(buffer, &archive->raw_data[(u32)offset], length); + return length; } /** @@ -45,7 +42,8 @@ size_t File_RomFS::Read(const u64 offset, const u32 length, u8* buffer) const { * @return Number of bytes written */ size_t File_RomFS::Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const { - return -1; + LOG_WARNING(Service_FS, "Attempted to write to ROMFS."); + return 0; } /** @@ -53,7 +51,7 @@ size_t File_RomFS::Write(const u64 offset, const u32 length, const u32 flush, co * @return Size of the file in bytes */ size_t File_RomFS::GetSize() const { - return -1; + return sizeof(u8) * archive->raw_data.size(); } /** @@ -62,6 +60,7 @@ size_t File_RomFS::GetSize() const { * @return true if successful */ bool File_RomFS::SetSize(const u64 size) const { + LOG_WARNING(Service_FS, "Attempted to set the size of ROMFS"); return false; } diff --git a/src/core/file_sys/file_romfs.h b/src/core/file_sys/file_romfs.h index 4ddaafe21..09fa2e7e3 100644 --- a/src/core/file_sys/file_romfs.h +++ b/src/core/file_sys/file_romfs.h @@ -14,10 +14,11 @@ namespace FileSys { +class Archive_RomFS; + class File_RomFS final : public FileBackend { public: - File_RomFS(); - ~File_RomFS() override; + File_RomFS(const Archive_RomFS* archive) : archive(archive) {} /** * Open the file @@ -62,6 +63,9 @@ public: * @return true if the file closed correctly */ bool Close() const override; + +private: + const Archive_RomFS* archive; }; } // namespace FileSys diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index d04e5b2e7..a4ee7a156 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -2,7 +2,8 @@ // Licensed under GPLv2 // Refer to the license.txt file included. -#include +#include +#include #include "common/common_types.h" #include "common/file_util.h" @@ -41,74 +42,24 @@ enum class DirectoryCommand : u32 { Close = 0x08020000, }; -class Archive : public Kernel::Session { +class Archive { public: - std::string GetName() const override { return "Archive: " + backend->GetName(); } - - ArchiveIdCode id_code; ///< Id code of the archive - FileSys::ArchiveBackend* backend; ///< Archive backend interface - - ResultVal SyncRequest() override { - u32* cmd_buff = Kernel::GetCommandBuffer(); - FileCommand cmd = static_cast(cmd_buff[0]); - - switch (cmd) { - // Read from archive... - case FileCommand::Read: - { - u64 offset = cmd_buff[1] | ((u64)cmd_buff[2] << 32); - u32 length = cmd_buff[3]; - u32 address = cmd_buff[5]; - - // Number of bytes read - cmd_buff[2] = backend->Read(offset, length, Memory::GetPointer(address)); - break; - } - // Write to archive... - case FileCommand::Write: - { - u64 offset = cmd_buff[1] | ((u64)cmd_buff[2] << 32); - u32 length = cmd_buff[3]; - u32 flush = cmd_buff[4]; - u32 address = cmd_buff[6]; - - // Number of bytes written - cmd_buff[2] = backend->Write(offset, length, flush, Memory::GetPointer(address)); - break; - } - case FileCommand::GetSize: - { - u64 filesize = (u64) backend->GetSize(); - cmd_buff[2] = (u32) filesize; // Lower word - cmd_buff[3] = (u32) (filesize >> 32); // Upper word - break; - } - case FileCommand::SetSize: - { - backend->SetSize(cmd_buff[1] | ((u64)cmd_buff[2] << 32)); - break; - } - case FileCommand::Close: - { - LOG_TRACE(Service_FS, "Close %s %s", GetTypeName().c_str(), GetName().c_str()); - CloseArchive(id_code); - break; - } - // Unknown command... - default: - { - LOG_ERROR(Service_FS, "Unknown command=0x%08X", cmd); - cmd_buff[0] = UnimplementedFunction(ErrorModule::FS).raw; - return MakeResult(false); - } - } - cmd_buff[1] = 0; // No error - return MakeResult(false); + Archive(std::unique_ptr&& backend, ArchiveIdCode id_code) + : backend(std::move(backend)), id_code(id_code) { } + + std::string GetName() const { return "Archive: " + backend->GetName(); } + + ArchiveIdCode id_code; ///< Id code of the archive + std::unique_ptr backend; ///< Archive backend interface }; class File : public Kernel::Session { public: + File(std::unique_ptr&& backend, const FileSys::Path& path) + : backend(std::move(backend)), path(path) { + } + std::string GetName() const override { return "Path: " + path.DebugStr(); } FileSys::Path path; ///< Path of the file @@ -183,6 +134,10 @@ public: class Directory : public Kernel::Session { public: + Directory(std::unique_ptr&& backend, const FileSys::Path& path) + : backend(std::move(backend)), path(path) { + } + std::string GetName() const override { return "Directory: " + path.DebugStr(); } FileSys::Path path; ///< Path of the directory @@ -228,105 +183,95 @@ public: //////////////////////////////////////////////////////////////////////////////////////////////////// -std::map g_archive_map; ///< Map of file archives by IdCode - -ResultVal OpenArchive(ArchiveIdCode id_code) { - auto itr = g_archive_map.find(id_code); - if (itr == g_archive_map.end()) { - return ResultCode(ErrorDescription::NotFound, ErrorModule::FS, - ErrorSummary::NotFound, ErrorLevel::Permanent); - } - - return MakeResult(itr->second); -} - -ResultCode CloseArchive(ArchiveIdCode id_code) { - auto itr = g_archive_map.find(id_code); - if (itr == g_archive_map.end()) { - LOG_ERROR(Service_FS, "Cannot close archive %d, does not exist!", (int)id_code); - return InvalidHandle(ErrorModule::FS); - } - - LOG_TRACE(Service_FS, "Closed archive %d", (int) id_code); - return RESULT_SUCCESS; -} +/** + * Map of registered archives, identified by id code. Once an archive is registered here, it is + * never removed until the FS service is shut down. + */ +static std::unordered_map> id_code_map; /** - * Mounts an archive - * @param archive Pointer to the archive to mount + * Map of active archive handles. Values are pointers to the archives in `idcode_map`. */ -ResultCode MountArchive(Archive* archive) { - ArchiveIdCode id_code = archive->id_code; - ResultVal archive_handle = OpenArchive(id_code); - if (archive_handle.Succeeded()) { - LOG_ERROR(Service_FS, "Cannot mount two archives with the same ID code! (%d)", (int) id_code); - return archive_handle.Code(); - } - g_archive_map[id_code] = archive->GetHandle(); - LOG_TRACE(Service_FS, "Mounted archive %s", archive->GetName().c_str()); - return RESULT_SUCCESS; +static std::unordered_map handle_map; +static ArchiveHandle next_handle; + +static Archive* GetArchive(ArchiveHandle handle) { + auto itr = handle_map.find(handle); + return (itr == handle_map.end()) ? nullptr : itr->second; } -ResultCode CreateArchive(FileSys::ArchiveBackend* backend, ArchiveIdCode id_code) { - Archive* archive = new Archive; - Handle handle = Kernel::g_object_pool.Create(archive); - archive->id_code = id_code; - archive->backend = backend; +ResultVal OpenArchive(ArchiveIdCode id_code) { + LOG_TRACE(Service_FS, "Opening archive with id code 0x%08X", id_code); - ResultCode result = MountArchive(archive); - if (result.IsError()) { - return result; - } - - return RESULT_SUCCESS; -} - -ResultVal OpenFileFromArchive(Handle archive_handle, const FileSys::Path& path, const FileSys::Mode mode) { - // TODO(bunnei): Binary type files get a raw file pointer to the archive. Currently, we create - // the archive file handles at app loading, and then keep them persistent throughout execution. - // Archives file handles are just reused and not actually freed until emulation shut down. - // Verify if real hardware works this way, or if new handles are created each time - if (path.GetType() == FileSys::Binary) - // TODO(bunnei): FixMe - this is a hack to compensate for an incorrect FileSys backend - // design. While the functionally of this is OK, our implementation decision to separate - // normal files from archive file pointers is very likely wrong. - // See https://github.com/citra-emu/citra/issues/205 - return MakeResult(archive_handle); - - File* file = new File; - Handle handle = Kernel::g_object_pool.Create(file); - - Archive* archive = Kernel::g_object_pool.Get(archive_handle); - if (archive == nullptr) { - return InvalidHandle(ErrorModule::FS); - } - file->path = path; - file->backend = archive->backend->OpenFile(path, mode); - - if (!file->backend) { + auto itr = id_code_map.find(id_code); + if (itr == id_code_map.end()) { + // TODO: Verify error against hardware return ResultCode(ErrorDescription::NotFound, ErrorModule::FS, ErrorSummary::NotFound, ErrorLevel::Permanent); } + // This should never even happen in the first place with 64-bit handles, + while (handle_map.count(next_handle) != 0) { + ++next_handle; + } + handle_map.emplace(next_handle, itr->second.get()); + return MakeResult(next_handle++); +} + +ResultCode CloseArchive(ArchiveHandle handle) { + if (handle_map.erase(handle) == 0) + return InvalidHandle(ErrorModule::FS); + else + return RESULT_SUCCESS; +} + +// TODO(yuriks): This might be what the fs:REG service is for. See the Register/Unregister calls in +// http://3dbrew.org/wiki/Filesystem_services#ProgramRegistry_service_.22fs:REG.22 +ResultCode CreateArchive(std::unique_ptr&& backend, ArchiveIdCode id_code) { + auto result = id_code_map.emplace(id_code, std::make_unique(std::move(backend), id_code)); + + bool inserted = result.second; + _dbg_assert_msg_(Service_FS, inserted, "Tried to register more than one archive with same id code"); + + auto& archive = result.first->second; + LOG_DEBUG(Service_FS, "Registered archive %s with id code 0x%08X", archive->GetName().c_str(), id_code); + return RESULT_SUCCESS; +} + +ResultVal OpenFileFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path, const FileSys::Mode mode) { + Archive* archive = GetArchive(archive_handle); + if (archive == nullptr) + return InvalidHandle(ErrorModule::FS); + + std::unique_ptr backend = archive->backend->OpenFile(path, mode); + if (backend == nullptr) { + return ResultCode(ErrorDescription::NotFound, ErrorModule::FS, + ErrorSummary::NotFound, ErrorLevel::Permanent); + } + + auto file = std::make_unique(std::move(backend), path); + Handle handle = Kernel::g_object_pool.Create(file.release()); return MakeResult(handle); } -ResultCode DeleteFileFromArchive(Handle archive_handle, const FileSys::Path& path) { - Archive* archive = Kernel::g_object_pool.GetFast(archive_handle); +ResultCode DeleteFileFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path) { + Archive* archive = GetArchive(archive_handle); if (archive == nullptr) return InvalidHandle(ErrorModule::FS); + if (archive->backend->DeleteFile(path)) return RESULT_SUCCESS; return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description ErrorSummary::Canceled, ErrorLevel::Status); } -ResultCode RenameFileBetweenArchives(Handle src_archive_handle, const FileSys::Path& src_path, - Handle dest_archive_handle, const FileSys::Path& dest_path) { - Archive* src_archive = Kernel::g_object_pool.GetFast(src_archive_handle); - Archive* dest_archive = Kernel::g_object_pool.GetFast(dest_archive_handle); +ResultCode RenameFileBetweenArchives(ArchiveHandle src_archive_handle, const FileSys::Path& src_path, + ArchiveHandle dest_archive_handle, const FileSys::Path& dest_path) { + Archive* src_archive = GetArchive(src_archive_handle); + Archive* dest_archive = GetArchive(dest_archive_handle); if (src_archive == nullptr || dest_archive == nullptr) return InvalidHandle(ErrorModule::FS); + if (src_archive == dest_archive) { if (src_archive->backend->RenameFile(src_path, dest_path)) return RESULT_SUCCESS; @@ -334,36 +279,42 @@ ResultCode RenameFileBetweenArchives(Handle src_archive_handle, const FileSys::P // TODO: Implement renaming across archives return UnimplementedFunction(ErrorModule::FS); } + + // TODO(yuriks): This code probably isn't right, it'll return a Status even if the file didn't + // exist or similar. Verify. return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description ErrorSummary::NothingHappened, ErrorLevel::Status); } -ResultCode DeleteDirectoryFromArchive(Handle archive_handle, const FileSys::Path& path) { - Archive* archive = Kernel::g_object_pool.GetFast(archive_handle); +ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path) { + Archive* archive = GetArchive(archive_handle); if (archive == nullptr) return InvalidHandle(ErrorModule::FS); + if (archive->backend->DeleteDirectory(path)) return RESULT_SUCCESS; return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description ErrorSummary::Canceled, ErrorLevel::Status); } -ResultCode CreateDirectoryFromArchive(Handle archive_handle, const FileSys::Path& path) { - Archive* archive = Kernel::g_object_pool.GetFast(archive_handle); +ResultCode CreateDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path) { + Archive* archive = GetArchive(archive_handle); if (archive == nullptr) return InvalidHandle(ErrorModule::FS); + if (archive->backend->CreateDirectory(path)) return RESULT_SUCCESS; return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description ErrorSummary::Canceled, ErrorLevel::Status); } -ResultCode RenameDirectoryBetweenArchives(Handle src_archive_handle, const FileSys::Path& src_path, - Handle dest_archive_handle, const FileSys::Path& dest_path) { - Archive* src_archive = Kernel::g_object_pool.GetFast(src_archive_handle); - Archive* dest_archive = Kernel::g_object_pool.GetFast(dest_archive_handle); +ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, const FileSys::Path& src_path, + ArchiveHandle dest_archive_handle, const FileSys::Path& dest_path) { + Archive* src_archive = GetArchive(src_archive_handle); + Archive* dest_archive = GetArchive(dest_archive_handle); if (src_archive == nullptr || dest_archive == nullptr) return InvalidHandle(ErrorModule::FS); + if (src_archive == dest_archive) { if (src_archive->backend->RenameDirectory(src_path, dest_path)) return RESULT_SUCCESS; @@ -371,6 +322,9 @@ ResultCode RenameDirectoryBetweenArchives(Handle src_archive_handle, const FileS // TODO: Implement renaming across archives return UnimplementedFunction(ErrorModule::FS); } + + // TODO(yuriks): This code probably isn't right, it'll return a Status even if the file didn't + // exist or similar. Verify. return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description ErrorSummary::NothingHappened, ErrorLevel::Status); } @@ -381,44 +335,42 @@ ResultCode RenameDirectoryBetweenArchives(Handle src_archive_handle, const FileS * @param path Path to the Directory inside of the Archive * @return Opened Directory object */ -ResultVal OpenDirectoryFromArchive(Handle archive_handle, const FileSys::Path& path) { - Directory* directory = new Directory; - Handle handle = Kernel::g_object_pool.Create(directory); - - Archive* archive = Kernel::g_object_pool.Get(archive_handle); - if (archive == nullptr) { +ResultVal OpenDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path) { + Archive* archive = GetArchive(archive_handle); + if (archive == nullptr) return InvalidHandle(ErrorModule::FS); - } - directory->path = path; - directory->backend = archive->backend->OpenDirectory(path); - if (!directory->backend) { + std::unique_ptr backend = archive->backend->OpenDirectory(path); + if (backend == nullptr) { return ResultCode(ErrorDescription::NotFound, ErrorModule::FS, ErrorSummary::NotFound, ErrorLevel::Permanent); } + auto directory = std::make_unique(std::move(backend), path); + Handle handle = Kernel::g_object_pool.Create(directory.release()); return MakeResult(handle); } /// Initialize archives void ArchiveInit() { - g_archive_map.clear(); + next_handle = 1; // TODO(Link Mauve): Add the other archive types (see here for the known types: // http://3dbrew.org/wiki/FS:OpenArchive#Archive_idcodes). Currently the only half-finished // archive type is SDMC, so it is the only one getting exposed. std::string sdmc_directory = FileUtil::GetUserPath(D_SDMC_IDX); - auto archive = new FileSys::Archive_SDMC(sdmc_directory); + auto archive = std::make_unique(sdmc_directory); if (archive->Initialize()) - CreateArchive(archive, ArchiveIdCode::SDMC); + CreateArchive(std::move(archive), ArchiveIdCode::SDMC); else LOG_ERROR(Service_FS, "Can't instantiate SDMC archive with path %s", sdmc_directory.c_str()); } /// Shutdown archives void ArchiveShutdown() { - g_archive_map.clear(); + handle_map.clear(); + id_code_map.clear(); } } // namespace FS diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h index 2c50dfff0..a38de92e3 100644 --- a/src/core/hle/service/fs/archive.h +++ b/src/core/hle/service/fs/archive.h @@ -24,25 +24,27 @@ enum class ArchiveIdCode : u32 { SDMCWriteOnly = 0x0000000A, }; +typedef u64 ArchiveHandle; + /** * Opens an archive * @param id_code IdCode of the archive to open * @return Handle to the opened archive */ -ResultVal OpenArchive(ArchiveIdCode id_code); +ResultVal OpenArchive(ArchiveIdCode id_code); /** * Closes an archive * @param id_code IdCode of the archive to open */ -ResultCode CloseArchive(ArchiveIdCode id_code); +ResultCode CloseArchive(ArchiveHandle handle); /** * Creates an Archive * @param backend File system backend interface to the archive * @param id_code Id code used to access this type of archive */ -ResultCode CreateArchive(FileSys::ArchiveBackend* backend, ArchiveIdCode id_code); +ResultCode CreateArchive(std::unique_ptr&& backend, ArchiveIdCode id_code); /** * Open a File from an Archive @@ -51,7 +53,7 @@ ResultCode CreateArchive(FileSys::ArchiveBackend* backend, ArchiveIdCode id_code * @param mode Mode under which to open the File * @return Handle to the opened File object */ -ResultVal OpenFileFromArchive(Handle archive_handle, const FileSys::Path& path, const FileSys::Mode mode); +ResultVal OpenFileFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path, const FileSys::Mode mode); /** * Delete a File from an Archive @@ -59,7 +61,7 @@ ResultVal OpenFileFromArchive(Handle archive_handle, const FileSys::Path * @param path Path to the File inside of the Archive * @return Whether deletion succeeded */ -ResultCode DeleteFileFromArchive(Handle archive_handle, const FileSys::Path& path); +ResultCode DeleteFileFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path); /** * Rename a File between two Archives @@ -69,8 +71,8 @@ ResultCode DeleteFileFromArchive(Handle archive_handle, const FileSys::Path& pat * @param dest_path Path to the File inside of the destination Archive * @return Whether rename succeeded */ -ResultCode RenameFileBetweenArchives(Handle src_archive_handle, const FileSys::Path& src_path, - Handle dest_archive_handle, const FileSys::Path& dest_path); +ResultCode RenameFileBetweenArchives(ArchiveHandle src_archive_handle, const FileSys::Path& src_path, + ArchiveHandle dest_archive_handle, const FileSys::Path& dest_path); /** * Delete a Directory from an Archive @@ -78,7 +80,7 @@ ResultCode RenameFileBetweenArchives(Handle src_archive_handle, const FileSys::P * @param path Path to the Directory inside of the Archive * @return Whether deletion succeeded */ -ResultCode DeleteDirectoryFromArchive(Handle archive_handle, const FileSys::Path& path); +ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path); /** * Create a Directory from an Archive @@ -86,7 +88,7 @@ ResultCode DeleteDirectoryFromArchive(Handle archive_handle, const FileSys::Path * @param path Path to the Directory inside of the Archive * @return Whether creation of directory succeeded */ -ResultCode CreateDirectoryFromArchive(Handle archive_handle, const FileSys::Path& path); +ResultCode CreateDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path); /** * Rename a Directory between two Archives @@ -96,8 +98,8 @@ ResultCode CreateDirectoryFromArchive(Handle archive_handle, const FileSys::Path * @param dest_path Path to the Directory inside of the destination Archive * @return Whether rename succeeded */ -ResultCode RenameDirectoryBetweenArchives(Handle src_archive_handle, const FileSys::Path& src_path, - Handle dest_archive_handle, const FileSys::Path& dest_path); +ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, const FileSys::Path& src_path, + ArchiveHandle dest_archive_handle, const FileSys::Path& dest_path); /** * Open a Directory from an Archive @@ -105,7 +107,7 @@ ResultCode RenameDirectoryBetweenArchives(Handle src_archive_handle, const FileS * @param path Path to the Directory inside of the Archive * @return Handle to the opened File object */ -ResultVal OpenDirectoryFromArchive(Handle archive_handle, const FileSys::Path& path); +ResultVal OpenDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path); /// Initialize archives void ArchiveInit(); diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp index eda7cb8ab..0f75d5e3a 100644 --- a/src/core/hle/service/fs/fs_user.cpp +++ b/src/core/hle/service/fs/fs_user.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "common/common.h" +#include "common/scope_exit.h" #include "common/string_util.h" #include "core/hle/service/fs/archive.h" @@ -16,6 +17,10 @@ namespace Service { namespace FS { +static ArchiveHandle MakeArchiveHandle(u32 low_word, u32 high_word) { + return (u64)low_word | ((u64)high_word << 32); +} + static void Initialize(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); @@ -62,6 +67,7 @@ static void OpenFile(Service::Interface* self) { if (handle.Succeeded()) { cmd_buff[3] = *handle; } else { + cmd_buff[3] = 0; LOG_ERROR(Service_FS, "failed to get a handle for file %s", file_path.DebugStr().c_str()); } } @@ -106,25 +112,25 @@ static void OpenFileDirectly(Service::Interface* self) { if (archive_path.GetType() != FileSys::Empty) { LOG_ERROR(Service_FS, "archive LowPath type other than empty is currently unsupported"); cmd_buff[1] = UnimplementedFunction(ErrorModule::FS).raw; + cmd_buff[3] = 0; return; } - // TODO(Link Mauve): Check if we should even get a handle for the archive, and don't leak it - // TODO(yuriks): Why is there all this duplicate (and seemingly useless) code up here? - ResultVal archive_handle = OpenArchive(archive_id); - cmd_buff[1] = archive_handle.Code().raw; + ResultVal archive_handle = OpenArchive(archive_id); if (archive_handle.Failed()) { LOG_ERROR(Service_FS, "failed to get a handle for archive"); + cmd_buff[1] = archive_handle.Code().raw; + cmd_buff[3] = 0; return; } - // cmd_buff[2] isn't used according to 3dmoo's implementation. - cmd_buff[3] = *archive_handle; + SCOPE_EXIT({ CloseArchive(*archive_handle); }); ResultVal handle = OpenFileFromArchive(*archive_handle, file_path, mode); cmd_buff[1] = handle.Code().raw; if (handle.Succeeded()) { cmd_buff[3] = *handle; } else { + cmd_buff[3] = 0; LOG_ERROR(Service_FS, "failed to get a handle for file %s", file_path.DebugStr().c_str()); } } @@ -140,12 +146,10 @@ static void OpenFileDirectly(Service::Interface* self) { * Outputs: * 1 : Result of function, 0 on success, otherwise error code */ -void DeleteFile(Service::Interface* self) { +static void DeleteFile(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - // TODO(Link Mauve): cmd_buff[2], aka archive handle lower word, isn't used according to - // 3dmoo's or ctrulib's implementations. Triple check if it's really the case. - Handle archive_handle = static_cast(cmd_buff[3]); + ArchiveHandle archive_handle = MakeArchiveHandle(cmd_buff[2], cmd_buff[3]); auto filename_type = static_cast(cmd_buff[4]); u32 filename_size = cmd_buff[5]; u32 filename_ptr = cmd_buff[7]; @@ -174,15 +178,13 @@ void DeleteFile(Service::Interface* self) { * Outputs: * 1 : Result of function, 0 on success, otherwise error code */ -void RenameFile(Service::Interface* self) { +static void RenameFile(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - // TODO(Link Mauve): cmd_buff[2] and cmd_buff[6], aka archive handle lower word, aren't used according to - // 3dmoo's or ctrulib's implementations. Triple check if it's really the case. - Handle src_archive_handle = static_cast(cmd_buff[3]); + ArchiveHandle src_archive_handle = MakeArchiveHandle(cmd_buff[2], cmd_buff[3]); auto src_filename_type = static_cast(cmd_buff[4]); u32 src_filename_size = cmd_buff[5]; - Handle dest_archive_handle = static_cast(cmd_buff[7]); + ArchiveHandle dest_archive_handle = MakeArchiveHandle(cmd_buff[6], cmd_buff[7]);; auto dest_filename_type = static_cast(cmd_buff[8]); u32 dest_filename_size = cmd_buff[9]; u32 src_filename_ptr = cmd_buff[11]; @@ -209,12 +211,10 @@ void RenameFile(Service::Interface* self) { * Outputs: * 1 : Result of function, 0 on success, otherwise error code */ -void DeleteDirectory(Service::Interface* self) { +static void DeleteDirectory(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - // TODO(Link Mauve): cmd_buff[2], aka archive handle lower word, isn't used according to - // 3dmoo's or ctrulib's implementations. Triple check if it's really the case. - Handle archive_handle = static_cast(cmd_buff[3]); + ArchiveHandle archive_handle = MakeArchiveHandle(cmd_buff[2], cmd_buff[3]); auto dirname_type = static_cast(cmd_buff[4]); u32 dirname_size = cmd_buff[5]; u32 dirname_ptr = cmd_buff[7]; @@ -241,9 +241,7 @@ void DeleteDirectory(Service::Interface* self) { static void CreateDirectory(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - // TODO: cmd_buff[2], aka archive handle lower word, isn't used according to - // 3dmoo's or ctrulib's implementations. Triple check if it's really the case. - Handle archive_handle = static_cast(cmd_buff[3]); + ArchiveHandle archive_handle = MakeArchiveHandle(cmd_buff[2], cmd_buff[3]); auto dirname_type = static_cast(cmd_buff[4]); u32 dirname_size = cmd_buff[5]; u32 dirname_ptr = cmd_buff[8]; @@ -271,15 +269,13 @@ static void CreateDirectory(Service::Interface* self) { * Outputs: * 1 : Result of function, 0 on success, otherwise error code */ -void RenameDirectory(Service::Interface* self) { +static void RenameDirectory(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - // TODO(Link Mauve): cmd_buff[2] and cmd_buff[6], aka archive handle lower word, aren't used according to - // 3dmoo's or ctrulib's implementations. Triple check if it's really the case. - Handle src_archive_handle = static_cast(cmd_buff[3]); + ArchiveHandle src_archive_handle = MakeArchiveHandle(cmd_buff[2], cmd_buff[3]); auto src_dirname_type = static_cast(cmd_buff[4]); u32 src_dirname_size = cmd_buff[5]; - Handle dest_archive_handle = static_cast(cmd_buff[7]); + ArchiveHandle dest_archive_handle = MakeArchiveHandle(cmd_buff[6], cmd_buff[7]); auto dest_dirname_type = static_cast(cmd_buff[8]); u32 dest_dirname_size = cmd_buff[9]; u32 src_dirname_ptr = cmd_buff[11]; @@ -295,12 +291,23 @@ void RenameDirectory(Service::Interface* self) { cmd_buff[1] = RenameDirectoryBetweenArchives(src_archive_handle, src_dir_path, dest_archive_handle, dest_dir_path).raw; } +/** + * FS_User::OpenDirectory service function + * Inputs: + * 1 : Archive handle low word + * 2 : Archive handle high word + * 3 : Low path type + * 4 : Low path size + * 7 : (LowPathSize << 14) | 2 + * 8 : Low path data pointer + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 3 : Directory handle + */ static void OpenDirectory(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - // TODO(Link Mauve): cmd_buff[2], aka archive handle lower word, isn't used according to - // 3dmoo's or ctrulib's implementations. Triple check if it's really the case. - Handle archive_handle = static_cast(cmd_buff[2]); + ArchiveHandle archive_handle = MakeArchiveHandle(cmd_buff[1], cmd_buff[2]); auto dirname_type = static_cast(cmd_buff[3]); u32 dirname_size = cmd_buff[4]; u32 dirname_ptr = cmd_buff[6]; @@ -348,16 +355,34 @@ static void OpenArchive(Service::Interface* self) { return; } - ResultVal handle = OpenArchive(archive_id); + ResultVal handle = OpenArchive(archive_id); cmd_buff[1] = handle.Code().raw; if (handle.Succeeded()) { - // cmd_buff[2] isn't used according to 3dmoo's implementation. - cmd_buff[3] = *handle; + cmd_buff[2] = *handle & 0xFFFFFFFF; + cmd_buff[3] = (*handle >> 32) & 0xFFFFFFFF; } else { + cmd_buff[2] = cmd_buff[3] = 0; LOG_ERROR(Service_FS, "failed to get a handle for archive"); } } +/** + * FS_User::CloseArchive service function + * Inputs: + * 0 : 0x080E0080 + * 1 : Archive handle low word + * 2 : Archive handle high word + * Outputs: + * 0 : ??? TODO(yuriks): Verify return header + * 1 : Result of function, 0 on success, otherwise error code + */ +static void CloseArchive(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + ArchiveHandle archive_handle = MakeArchiveHandle(cmd_buff[1], cmd_buff[2]); + cmd_buff[1] = CloseArchive(archive_handle).raw; +} + /* * FS_User::IsSdmcDetected service function * Outputs: @@ -389,7 +414,7 @@ const FSUserInterface::FunctionInfo FunctionTable[] = { {0x080B0102, OpenDirectory, "OpenDirectory"}, {0x080C00C2, OpenArchive, "OpenArchive"}, {0x080D0144, nullptr, "ControlArchive"}, - {0x080E0080, nullptr, "CloseArchive"}, + {0x080E0080, CloseArchive, "CloseArchive"}, {0x080F0180, nullptr, "FormatThisUserSaveData"}, {0x08100200, nullptr, "CreateSystemSaveData"}, {0x08110040, nullptr, "DeleteSystemSaveData"}, diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index 49f8c458d..463dacca3 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -74,7 +74,7 @@ ResultStatus LoadFile(const std::string& filename) { // Load application and RomFS if (ResultStatus::Success == app_loader.Load()) { - Service::FS::CreateArchive(new FileSys::Archive_RomFS(app_loader), Service::FS::ArchiveIdCode::RomFS); + Service::FS::CreateArchive(std::make_unique(app_loader), Service::FS::ArchiveIdCode::RomFS); return ResultStatus::Success; } break; From 666f6deb47774ad101710f619fb9ac66514b3012 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Mon, 15 Dec 2014 22:06:23 -0200 Subject: [PATCH 11/11] Work around libstdc++'s lack of support for std::hash on enums --- src/core/hle/service/fs/archive.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index a4ee7a156..caf82d556 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -16,6 +16,21 @@ #include "core/hle/kernel/session.h" #include "core/hle/result.h" +// Specializes std::hash for ArchiveIdCode, so that we can use it in std::unordered_map. +// Workaroung for libstdc++ bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60970 +namespace std { + template <> + struct hash { + typedef Service::FS::ArchiveIdCode argument_type; + typedef std::size_t result_type; + + result_type operator()(const argument_type& id_code) const { + typedef std::underlying_type::type Type; + return std::hash()(static_cast(id_code)); + } + }; +} + namespace Service { namespace FS {