diff --git a/app/src/main/cpp/skyline/loader/loader.h b/app/src/main/cpp/skyline/loader/loader.h index f45ff635..ea1d6ec8 100644 --- a/app/src/main/cpp/skyline/loader/loader.h +++ b/app/src/main/cpp/skyline/loader/loader.h @@ -26,6 +26,7 @@ namespace skyline::loader { public: std::shared_ptr nacp; //!< The NACP of the current application + std::shared_ptr romFs; //!< The RomFS of the current application /** * @param backing The backing for the NRO diff --git a/app/src/main/cpp/skyline/loader/nro.cpp b/app/src/main/cpp/skyline/loader/nro.cpp index e1edf9bf..f119eabd 100644 --- a/app/src/main/cpp/skyline/loader/nro.cpp +++ b/app/src/main/cpp/skyline/loader/nro.cpp @@ -24,6 +24,9 @@ namespace skyline::loader { NroAssetSection &nacpHeader = assetHeader.nacp; nacp = std::make_shared(std::make_shared(backing, header.size + nacpHeader.offset, nacpHeader.size)); + + NroAssetSection &romFsHeader = assetHeader.romFs; + romFs = std::make_shared(backing, header.size + romFsHeader.offset, romFsHeader.size); } } @@ -83,4 +86,4 @@ namespace skyline::loader { state.os->memory.InitializeRegions(constant::BaseAddress, textSize + rodataSize + dataSize + bssSize + patchSize + padding, memory::AddressSpaceType::AddressSpace39Bit); } -} \ No newline at end of file +} diff --git a/app/src/main/cpp/skyline/loader/nro.h b/app/src/main/cpp/skyline/loader/nro.h index 1b06551d..63c34454 100644 --- a/app/src/main/cpp/skyline/loader/nro.h +++ b/app/src/main/cpp/skyline/loader/nro.h @@ -60,8 +60,8 @@ namespace skyline::loader { u32 magic; //!< The asset section magic "ASET" u32 version; //!< The format version NroAssetSection icon; //!< The header describing the location of the icon - NroAssetSection nacp; //!< The header describing the location of the nacp - NroAssetSection romfs; //!< The header describing the location of the romfs + NroAssetSection nacp; //!< The header describing the location of the NACP + NroAssetSection romFs; //!< The header describing the location of the RomFS } assetHeader{}; /** @@ -87,4 +87,4 @@ namespace skyline::loader { void LoadProcessData(const std::shared_ptr process, const DeviceState &state); }; -} \ No newline at end of file +} diff --git a/app/src/main/cpp/skyline/services/base_service.h b/app/src/main/cpp/skyline/services/base_service.h index eed605f0..f00dbf58 100644 --- a/app/src/main/cpp/skyline/services/base_service.h +++ b/app/src/main/cpp/skyline/services/base_service.h @@ -52,6 +52,7 @@ namespace skyline::service { timesrv_ITimeZoneService, fssrv_IFileSystemProxy, fssrv_IFileSystem, + fssrv_IStorage, nvdrv_INvDrvServices, visrv_IManagerRootService, visrv_IApplicationDisplayService, diff --git a/app/src/main/cpp/skyline/services/fssrv/IFileSystemProxy.cpp b/app/src/main/cpp/skyline/services/fssrv/IFileSystemProxy.cpp index a4407901..4221b64f 100644 --- a/app/src/main/cpp/skyline/services/fssrv/IFileSystemProxy.cpp +++ b/app/src/main/cpp/skyline/services/fssrv/IFileSystemProxy.cpp @@ -1,12 +1,15 @@ // SPDX-License-Identifier: MPL-2.0 // Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/) +#include #include "IFileSystemProxy.h" +#include "IStorage.h" namespace skyline::service::fssrv { IFileSystemProxy::IFileSystemProxy(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager, Service::fssrv_IFileSystemProxy, "fssrv:IFileSystemProxy", { {0x1, SFUNC(IFileSystemProxy::SetCurrentProcess)}, - {0x12, SFUNC(IFileSystemProxy::OpenSdCardFileSystem)} + {0x12, SFUNC(IFileSystemProxy::OpenSdCardFileSystem)}, + {0xc8, SFUNC(IFileSystemProxy::OpenDataStorageByCurrentProcess)} }) {} void IFileSystemProxy::SetCurrentProcess(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { @@ -16,4 +19,11 @@ namespace skyline::service::fssrv { void IFileSystemProxy::OpenSdCardFileSystem(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { manager.RegisterService(std::make_shared(FsType::SdCard, state, manager), session, response); } + + void IFileSystemProxy::OpenDataStorageByCurrentProcess(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { + if (state.loader->romFs) + manager.RegisterService(std::make_shared(state.loader->romFs, state, manager), session, response); + else + throw exception("Tried to call OpenDataStorageByCurrentProcess without a valid RomFS"); + } } diff --git a/app/src/main/cpp/skyline/services/fssrv/IFileSystemProxy.h b/app/src/main/cpp/skyline/services/fssrv/IFileSystemProxy.h index 233e172d..ecd4beed 100644 --- a/app/src/main/cpp/skyline/services/fssrv/IFileSystemProxy.h +++ b/app/src/main/cpp/skyline/services/fssrv/IFileSystemProxy.h @@ -26,5 +26,10 @@ namespace skyline::service::fssrv { * @brief This returns a handle to an instance of #IFileSystem (https://switchbrew.org/wiki/Filesystem_services#IFileSystem) with type SDCard */ void OpenSdCardFileSystem(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response); + + /** + * @brief This returns a handle to an instance of #IStorage (https://switchbrew.org/wiki/Filesystem_services#IStorage) for the application's data storage + */ + void OpenDataStorageByCurrentProcess(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response); }; } diff --git a/app/src/main/cpp/skyline/services/fssrv/IStorage.cpp b/app/src/main/cpp/skyline/services/fssrv/IStorage.cpp new file mode 100644 index 00000000..a0968a9b --- /dev/null +++ b/app/src/main/cpp/skyline/services/fssrv/IStorage.cpp @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/) + +#include +#include "IStorage.h" + +namespace skyline::service::fssrv { + IStorage::IStorage(std::shared_ptr &backing, const DeviceState &state, ServiceManager &manager) : backing(backing), BaseService(state, manager, Service::fssrv_IStorage, "fssrv:IStorage", { + {0x0, SFUNC(IStorage::Read)}, + {0x4, SFUNC(IStorage::GetSize)} + }) {} + + void IStorage::Read(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { + auto offset = request.Pop(); + auto size = request.Pop(); + + backing->Read(state.process->GetPointer(request.outputBuf.at(0).address), offset, size); + } + + void IStorage::GetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { + response.Push(backing->size); + } +} diff --git a/app/src/main/cpp/skyline/services/fssrv/IStorage.h b/app/src/main/cpp/skyline/services/fssrv/IStorage.h new file mode 100644 index 00000000..a5b6b9a8 --- /dev/null +++ b/app/src/main/cpp/skyline/services/fssrv/IStorage.h @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/) + +#pragma once + +#include +#include +#include + +namespace skyline::service::fssrv { + /** + * @brief IStorage is an interface to a raw backing device (https://switchbrew.org/wiki/Filesystem_services#IStorage) + */ + class IStorage : public BaseService { + private: + std::shared_ptr backing; //!< The backing of the IStorage + + public: + IStorage(std::shared_ptr &backing, const DeviceState &state, ServiceManager &manager); + + /** + * @brief This reads a buffer from a region of an IStorage (https://switchbrew.org/wiki/Filesystem_services#Read) + */ + void Read(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response); + + /** + * @brief This obtains the size of an IStorage (https://switchbrew.org/wiki/Filesystem_services#GetSize) + */ + void GetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response); + }; +}