mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-30 01:04:16 +01:00
Implement IStorage services in Applet Manager
In the case of am, IStorage is used to exchange buffers of data such as application launch parameters or an applets result. It has no relation to fsp-srv's IStorage.
This commit is contained in:
parent
162df93870
commit
8985fe705f
@ -83,6 +83,8 @@ add_library(skyline SHARED
|
|||||||
${source_DIR}/skyline/services/am/controller/ILibraryAppletCreator.cpp
|
${source_DIR}/skyline/services/am/controller/ILibraryAppletCreator.cpp
|
||||||
${source_DIR}/skyline/services/am/controller/ISelfController.cpp
|
${source_DIR}/skyline/services/am/controller/ISelfController.cpp
|
||||||
${source_DIR}/skyline/services/am/controller/IWindowController.cpp
|
${source_DIR}/skyline/services/am/controller/IWindowController.cpp
|
||||||
|
${source_DIR}/skyline/services/am/storage/IStorage.cpp
|
||||||
|
${source_DIR}/skyline/services/am/storage/IStorageAccessor.cpp
|
||||||
${source_DIR}/skyline/services/hid/IHidServer.cpp
|
${source_DIR}/skyline/services/hid/IHidServer.cpp
|
||||||
${source_DIR}/skyline/services/hid/IAppletResource.cpp
|
${source_DIR}/skyline/services/hid/IAppletResource.cpp
|
||||||
${source_DIR}/skyline/services/timesrv/IStaticService.cpp
|
${source_DIR}/skyline/services/timesrv/IStaticService.cpp
|
||||||
|
15
app/src/main/cpp/skyline/services/am/storage/IStorage.cpp
Normal file
15
app/src/main/cpp/skyline/services/am/storage/IStorage.cpp
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||||
|
|
||||||
|
#include "IStorageAccessor.h"
|
||||||
|
#include "IStorage.h"
|
||||||
|
|
||||||
|
namespace skyline::service::am {
|
||||||
|
IStorage::IStorage(const DeviceState &state, ServiceManager &manager, size_t size) : content(size), BaseService(state, manager, Service::am_IStorage, "am:IStorage", {
|
||||||
|
{0x0, SFUNC(IStorage::Open)}
|
||||||
|
}) {}
|
||||||
|
|
||||||
|
void IStorage::Open(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
|
manager.RegisterService(std::make_shared<IStorageAccessor>(state, manager, shared_from_this()), session, response);
|
||||||
|
}
|
||||||
|
}
|
41
app/src/main/cpp/skyline/services/am/storage/IStorage.h
Normal file
41
app/src/main/cpp/skyline/services/am/storage/IStorage.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <services/base_service.h>
|
||||||
|
#include <services/serviceman.h>
|
||||||
|
|
||||||
|
namespace skyline::service::am {
|
||||||
|
/**
|
||||||
|
* @brief IStorage is used to open an IStorageAccessor to access a region of memory (https://switchbrew.org/wiki/Applet_Manager_services#IStorage)
|
||||||
|
*/
|
||||||
|
class IStorage : public BaseService, public std::enable_shared_from_this<IStorage> {
|
||||||
|
private:
|
||||||
|
size_t offset{}; //!< The current offset within the content for pushing data
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::vector<u8> content; //!< The container for this IStorage's contents
|
||||||
|
|
||||||
|
IStorage(const DeviceState &state, ServiceManager &manager, size_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This returns an IStorageAccessor that can read and write data to an IStorage
|
||||||
|
*/
|
||||||
|
void Open(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function writes an object to the storage
|
||||||
|
* @tparam ValueType The type of the object to write
|
||||||
|
* @param value A reference to the object to be written
|
||||||
|
*/
|
||||||
|
template<typename ValueType>
|
||||||
|
inline void Push(const ValueType &value) {
|
||||||
|
if (offset + sizeof(ValueType) > content.size())
|
||||||
|
throw exception("The supplied value cannot fit into the IStorage");
|
||||||
|
|
||||||
|
std::memcpy(content.data() + offset, reinterpret_cast<const u8 *>(&value), sizeof(ValueType));
|
||||||
|
offset += sizeof(ValueType);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||||
|
|
||||||
|
#include <kernel/types/KProcess.h>
|
||||||
|
#include "IStorage.h"
|
||||||
|
#include "IStorageAccessor.h"
|
||||||
|
|
||||||
|
namespace skyline::service::am {
|
||||||
|
IStorageAccessor::IStorageAccessor(const DeviceState &state, ServiceManager &manager, std::shared_ptr<IStorage> parent) : parent(parent), BaseService(state, manager, Service::am_IStorageAccessor, "am:IStorageAccessor", {
|
||||||
|
{0x0, SFUNC(IStorageAccessor::GetSize)},
|
||||||
|
{0xb, SFUNC(IStorageAccessor::Read)}
|
||||||
|
}) {}
|
||||||
|
|
||||||
|
void IStorageAccessor::GetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
|
response.Push<i64>(parent->content.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void IStorageAccessor::Read(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
|
auto offset = request.Pop<i64>();
|
||||||
|
auto size = request.outputBuf.at(0).size;
|
||||||
|
|
||||||
|
if (offset + size > parent->content.size())
|
||||||
|
throw exception("Trying to read past the end of an IStorage");
|
||||||
|
|
||||||
|
if (offset < 0)
|
||||||
|
throw exception("Trying to read before the start of an IStorage");
|
||||||
|
|
||||||
|
state.process->WriteMemory(parent->content.data() + offset, request.outputBuf.at(0).address, size);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <services/base_service.h>
|
||||||
|
#include <services/serviceman.h>
|
||||||
|
|
||||||
|
namespace skyline::service::am {
|
||||||
|
class IStorage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief IStorageAccessor is used read and write to an IStorage (https://switchbrew.org/wiki/Applet_Manager_services#IStorageAccessor)
|
||||||
|
*/
|
||||||
|
class IStorageAccessor : public BaseService {
|
||||||
|
private:
|
||||||
|
std::shared_ptr<IStorage> parent; //!< The parent IStorage of the accessor
|
||||||
|
|
||||||
|
public:
|
||||||
|
IStorageAccessor(const DeviceState &state, ServiceManager &manager, std::shared_ptr<IStorage> parent);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This returns the size of the storage in bytes
|
||||||
|
*/
|
||||||
|
void GetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This returns a buffer containing the contents of the storage at the specified offset
|
||||||
|
*/
|
||||||
|
void Read(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
||||||
|
};
|
||||||
|
}
|
@ -42,6 +42,8 @@ namespace skyline::service {
|
|||||||
am_ILibraryAppletCreator,
|
am_ILibraryAppletCreator,
|
||||||
am_IDebugFunctions,
|
am_IDebugFunctions,
|
||||||
am_IAppletCommonFunctions,
|
am_IAppletCommonFunctions,
|
||||||
|
am_IStorage,
|
||||||
|
am_IStorageAccessor,
|
||||||
audio_IAudioOutManager,
|
audio_IAudioOutManager,
|
||||||
audio_IAudioOut,
|
audio_IAudioOut,
|
||||||
audio_IAudioRendererManager,
|
audio_IAudioRendererManager,
|
||||||
|
Loading…
Reference in New Issue
Block a user