APT service serialization

This commit is contained in:
Hamish Milne 2019-12-25 21:43:51 +00:00 committed by zhupengfei
parent 3e752002c4
commit 5265c79056
25 changed files with 247 additions and 17 deletions

2
TODO
View file

@ -64,7 +64,7 @@
✔ AC @started(19-12-23 12:48) @done(19-12-24 22:38) @lasted(1d9h50m3s)
✔ ACT @done(19-12-24 23:17)
✔ AM @started(19-12-24 23:17) @done(19-12-24 23:53) @lasted(36m8s)
☐ APT
✔ APT @done(19-12-25 21:41)
☐ BOSS
☐ CAM
☐ CECD

View file

@ -0,0 +1,91 @@
#pragma once
#include <boost/config.hpp>
#include <boost/archive/detail/basic_iarchive.hpp>
#include <optional>
#include <boost/move/utility_core.hpp>
#include <boost/serialization/item_version_type.hpp>
#include <boost/serialization/split_free.hpp>
#include <boost/serialization/level.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/version.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/serialization/detail/stack_constructor.hpp>
#include <boost/serialization/detail/is_default_constructible.hpp>
#include <boost/serialization/force_include.hpp>
// function specializations must be defined in the appropriate
// namespace - boost::serialization
namespace boost {
namespace serialization {
template<class Archive, class T>
void save(
Archive & ar,
const std::optional< T > & t,
const unsigned int /*version*/
){
// It is an inherent limitation to the serialization of optional.hpp
// that the underlying type must be either a pointer or must have a
// default constructor. It's possible that this could change sometime
// in the future, but for now, one will have to work around it. This can
// be done by serialization the optional<T> as optional<T *>
#if ! defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
BOOST_STATIC_ASSERT(
boost::serialization::detail::is_default_constructible<T>::value
|| boost::is_pointer<T>::value
);
#endif
const bool tflag = t.has_value();
ar << boost::serialization::make_nvp("initialized", tflag);
if (tflag){
ar << boost::serialization::make_nvp("value", *t);
}
}
template<class Archive, class T>
void load(
Archive & ar,
std::optional< T > & t,
const unsigned int version
){
bool tflag;
ar >> boost::serialization::make_nvp("initialized", tflag);
if(! tflag){
t.reset();
return;
}
if(0 == version){
boost::serialization::item_version_type item_version(0);
boost::archive::library_version_type library_version(
ar.get_library_version()
);
if(boost::archive::library_version_type(3) < library_version){
ar >> BOOST_SERIALIZATION_NVP(item_version);
}
}
if(! t.has_value())
t = T();
ar >> boost::serialization::make_nvp("value", *t);
}
template<class Archive, class T>
void serialize(
Archive & ar,
std::optional< T > & t,
const unsigned int version
){
boost::serialization::split_free(ar, t, version);
}
template<class T>
struct version<std::optional<T> > {
BOOST_STATIC_CONSTANT(int, value = 1);
};
} // serialization
} // boost

View file

@ -3,4 +3,9 @@ namespace Core {
template <class T>
T& Global();
// Declare explicit specialisation to prevent im
class System;
template <>
System& Global();
} // namespace Core

View file

@ -8,10 +8,11 @@
#include "core/hle/kernel/memory.h"
#include "core/hle/kernel/shared_memory.h"
#include "core/memory.h"
#include "core/global.h"
namespace Kernel {
SharedMemory::SharedMemory(KernelSystem& kernel) : Object(kernel), kernel(kernel) {}
SharedMemory::SharedMemory() : Object(Core::Global<KernelSystem>()), kernel(Core::Global<KernelSystem>()) {}
SharedMemory::~SharedMemory() {
for (const auto& interval : holding_memory) {
kernel.GetMemoryRegion(MemoryRegion::SYSTEM)
@ -27,7 +28,7 @@ SharedMemory::~SharedMemory() {
ResultVal<std::shared_ptr<SharedMemory>> KernelSystem::CreateSharedMemory(
Process* owner_process, u32 size, MemoryPermission permissions,
MemoryPermission other_permissions, VAddr address, MemoryRegion region, std::string name) {
auto shared_memory{std::make_shared<SharedMemory>(*this)};
auto shared_memory{std::make_shared<SharedMemory>()};
shared_memory->owner_process = owner_process;
shared_memory->name = std::move(name);
@ -72,7 +73,7 @@ ResultVal<std::shared_ptr<SharedMemory>> KernelSystem::CreateSharedMemory(
std::shared_ptr<SharedMemory> KernelSystem::CreateSharedMemoryForApplet(
u32 offset, u32 size, MemoryPermission permissions, MemoryPermission other_permissions,
std::string name) {
auto shared_memory{std::make_shared<SharedMemory>(*this)};
auto shared_memory{std::make_shared<SharedMemory>()};
// Allocate memory in heap
MemoryRegionInfo* memory_region = GetMemoryRegion(MemoryRegion::SYSTEM);

View file

@ -16,7 +16,7 @@ namespace Kernel {
class SharedMemory final : public Object {
public:
explicit SharedMemory(KernelSystem& kernel);
explicit SharedMemory();
~SharedMemory() override;
std::string GetTypeName() const override {

View file

@ -14,7 +14,7 @@ public:
explicit AC_I(std::shared_ptr<Module> ac);
private:
SERVICE_SERIALIZATION(AC_I, ac)
SERVICE_SERIALIZATION(AC_I, ac, Module)
};
} // namespace Service::AC

View file

@ -14,7 +14,7 @@ public:
explicit AC_U(std::shared_ptr<Module> ac);
private:
SERVICE_SERIALIZATION(AC_U, ac)
SERVICE_SERIALIZATION(AC_U, ac, Module)
};
} // namespace Service::AC

View file

@ -12,7 +12,7 @@ class ACT_A final : public Module::Interface {
public:
explicit ACT_A(std::shared_ptr<Module> act);
private:
SERVICE_SERIALIZATION(ACT_A, act)
SERVICE_SERIALIZATION(ACT_A, act, Module)
};
} // namespace Service::ACT

View file

@ -12,7 +12,7 @@ class ACT_U final : public Module::Interface {
public:
explicit ACT_U(std::shared_ptr<Module> act);
private:
SERVICE_SERIALIZATION(ACT_U, act)
SERVICE_SERIALIZATION(ACT_U, act, Module)
};
} // namespace Service::ACT

View file

@ -12,7 +12,7 @@ class AM_APP final : public Module::Interface {
public:
explicit AM_APP(std::shared_ptr<Module> am);
private:
SERVICE_SERIALIZATION(AM_APP, am)
SERVICE_SERIALIZATION(AM_APP, am, Module)
};
} // namespace Service::AM

View file

@ -12,7 +12,7 @@ class AM_NET final : public Module::Interface {
public:
explicit AM_NET(std::shared_ptr<Module> am);
private:
SERVICE_SERIALIZATION(AM_NET, am)
SERVICE_SERIALIZATION(AM_NET, am, Module)
};
} // namespace Service::AM

View file

@ -12,7 +12,7 @@ class AM_SYS final : public Module::Interface {
public:
explicit AM_SYS(std::shared_ptr<Module> am);
private:
SERVICE_SERIALIZATION(AM_SYS, am)
SERVICE_SERIALIZATION(AM_SYS, am, Module)
};
} // namespace Service::AM

View file

@ -12,7 +12,7 @@ class AM_U final : public Module::Interface {
public:
explicit AM_U(std::shared_ptr<Module> am);
private:
SERVICE_SERIALIZATION(AM_U, am)
SERVICE_SERIALIZATION(AM_U, am, Module)
};
} // namespace Service::AM

View file

@ -8,9 +8,12 @@
#include <memory>
#include <optional>
#include <vector>
#include <boost/serialization/array.hpp>
#include "common/serialization/optional.h"
#include "core/hle/kernel/event.h"
#include "core/hle/result.h"
#include "core/hle/service/fs/archive.h"
#include "core/global.h"
namespace Core {
class System;
@ -84,6 +87,18 @@ struct MessageParameter {
SignalType signal = SignalType::None;
std::shared_ptr<Kernel::Object> object = nullptr;
std::vector<u8> buffer;
private:
template <class Archive>
void serialize(Archive& ar, const unsigned int)
{
ar & sender_id;
ar & destination_id;
ar & signal;
ar & object;
ar & buffer;
}
friend class boost::serialization::access;
};
/// Holds information about the parameters used in StartLibraryApplet
@ -161,6 +176,17 @@ public:
u64 current_title_id;
FS::MediaType current_media_type;
private:
template <class Archive>
void serialize(Archive& ar, const unsigned int)
{
ar & next_title_id;
ar & next_media_type;
ar & current_title_id;
ar & current_media_type;
}
friend class boost::serialization::access;
};
ApplicationJumpParameters GetApplicationJumpParameters() const {
@ -199,6 +225,21 @@ private:
title_id = 0;
attributes.raw = 0;
}
private:
template <class Archive>
void serialize(Archive& ar, const unsigned int)
{
ar & applet_id;
ar & slot;
ar & title_id;
ar & registered;
ar & loaded;
ar & attributes.raw;
ar & notification_event;
ar & parameter_event;
}
friend class boost::serialization::access;
};
ApplicationJumpParameters app_jump_parameters{};
@ -216,6 +257,25 @@ private:
SignalType library_applet_closing_command;
Core::System& system;
private:
template <class Archive>
void serialize(Archive& ar, const unsigned int)
{
ar & next_parameter;
ar & app_jump_parameters;
ar & applet_slots;
ar & library_applet_closing_command;
}
friend class boost::serialization::access;
};
} // namespace Service::APT
namespace boost::serialization {
template <class Archive>
inline void load_construct_data(Archive& ar, Service::APT::AppletManager* t, const unsigned int)
{
::new(t)Service::APT::AppletManager(Core::Global<Core::System>());
}
}

View file

@ -5,6 +5,7 @@
#include "common/common_paths.h"
#include "common/file_util.h"
#include "common/logging/log.h"
#include "common/archives.h"
#include "core/core.h"
#include "core/file_sys/archive_ncch.h"
#include "core/file_sys/file_backend.h"
@ -26,8 +27,35 @@
#include "core/hw/aes/ccm.h"
#include "core/hw/aes/key.h"
namespace boost::serialization {
template <class Archive>
void load_construct_data(Archive& ar, Service::APT::Module* t, const unsigned int)
{
::new(t)Service::APT::Module(Core::Global<Core::System>());
}
template
void load_construct_data<iarchive>(iarchive& ar, Service::APT::Module* t, const unsigned int);
}
namespace Service::APT {
template <class Archive>
void Module::serialize(Archive& ar, const unsigned int)
{
ar & shared_font_mem;
ar & shared_font_loaded;
ar & shared_font_relocated;
ar & lock;
ar & cpu_percent;
ar & unknown_ns_state_field;
ar & screen_capture_buffer;
ar & screen_capture_post_permission;
ar & applet_manager;
}
SERIALIZE_IMPL(Module)
Module::NSInterface::NSInterface(std::shared_ptr<Module> apt, const char* name, u32 max_session)
: ServiceFramework(name, max_session), apt(std::move(apt)) {}

View file

@ -6,11 +6,15 @@
#include <memory>
#include <vector>
#include <boost/serialization/shared_ptr.hpp>
#include <boost/serialization/vector.hpp>
#include "common/archives.h"
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "common/swap.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/service/service.h"
#include "core/global.h"
namespace Core {
class System;
@ -65,7 +69,7 @@ public:
NSInterface(std::shared_ptr<Module> apt, const char* name, u32 max_session);
~NSInterface();
private:
protected:
std::shared_ptr<Module> apt;
};
@ -601,7 +605,7 @@ public:
*/
void CheckNew3DS(Kernel::HLERequestContext& ctx);
private:
protected:
bool application_reset_prepared{};
std::shared_ptr<Module> apt;
};
@ -630,8 +634,17 @@ private:
ScreencapPostPermission::CleanThePermission; // TODO(JamePeng): verify the initial value
std::shared_ptr<AppletManager> applet_manager;
template <class Archive>
void serialize(Archive& ar, const unsigned int);
friend class boost::serialization::access;
};
void InstallInterfaces(Core::System& system);
} // namespace Service::APT
namespace boost::serialization {
template <class Archive>
void load_construct_data(Archive& ar, Service::APT::Module* t, const unsigned int);
}

View file

@ -3,6 +3,7 @@
// Refer to the license.txt file included.
#include "core/hle/service/apt/apt_a.h"
#include "common/archives.h"
namespace Service::APT {
@ -105,3 +106,5 @@ APT_A::APT_A(std::shared_ptr<Module> apt)
}
} // namespace Service::APT
SERIALIZE_EXPORT_IMPL(Service::APT::APT_A)

View file

@ -11,6 +11,11 @@ namespace Service::APT {
class APT_A final : public Module::APTInterface {
public:
explicit APT_A(std::shared_ptr<Module> apt);
private:
SERVICE_SERIALIZATION(APT_A, apt, Module)
};
} // namespace Service::APT
BOOST_CLASS_EXPORT_KEY(Service::APT::APT_A)
BOOST_SERIALIZATION_CONSTRUCT(Service::APT::APT_A)

View file

@ -3,6 +3,7 @@
// Refer to the license.txt file included.
#include "core/hle/service/apt/apt_s.h"
#include "common/archives.h"
namespace Service::APT {
@ -105,3 +106,5 @@ APT_S::APT_S(std::shared_ptr<Module> apt)
}
} // namespace Service::APT
SERIALIZE_EXPORT_IMPL(Service::APT::APT_S)

View file

@ -18,6 +18,11 @@ namespace Service::APT {
class APT_S final : public Module::APTInterface {
public:
explicit APT_S(std::shared_ptr<Module> apt);
private:
SERVICE_SERIALIZATION(APT_S, apt, Module)
};
} // namespace Service::APT
BOOST_CLASS_EXPORT_KEY(Service::APT::APT_S)
BOOST_SERIALIZATION_CONSTRUCT(Service::APT::APT_S)

View file

@ -3,6 +3,7 @@
// Refer to the license.txt file included.
#include "core/hle/service/apt/apt_u.h"
#include "common/archives.h"
namespace Service::APT {
@ -102,3 +103,5 @@ APT_U::APT_U(std::shared_ptr<Module> apt)
}
} // namespace Service::APT
SERIALIZE_EXPORT_IMPL(Service::APT::APT_U)

View file

@ -18,6 +18,11 @@ namespace Service::APT {
class APT_U final : public Module::APTInterface {
public:
explicit APT_U(std::shared_ptr<Module> apt);
private:
SERVICE_SERIALIZATION(APT_U, apt, Module)
};
} // namespace Service::APT
BOOST_CLASS_EXPORT_KEY(Service::APT::APT_U)
BOOST_SERIALIZATION_CONSTRUCT(Service::APT::APT_U)

View file

@ -3,6 +3,7 @@
// Refer to the license.txt file included.
#include "core/hle/service/apt/ns_s.h"
#include "common/archives.h"
namespace Service::NS {
@ -29,3 +30,5 @@ NS_S::NS_S(std::shared_ptr<Service::APT::Module> apt)
}
} // namespace Service::NS
SERIALIZE_EXPORT_IMPL(Service::NS::NS_S)

View file

@ -14,6 +14,11 @@ namespace Service::NS {
class NS_S final : public Service::APT::Module::NSInterface {
public:
explicit NS_S(std::shared_ptr<Service::APT::Module> apt);
private:
SERVICE_SERIALIZATION(NS_S, apt, Service::APT::Module)
};
} // namespace Service::NS
BOOST_CLASS_EXPORT_KEY(Service::NS::NS_S)
BOOST_SERIALIZATION_CONSTRUCT(Service::NS::NS_S)

View file

@ -199,7 +199,7 @@ extern const std::array<ServiceModuleInfo, 40> service_module_map;
} // namespace Service
#define SERVICE_SERIALIZATION(T, MFIELD) \
#define SERVICE_SERIALIZATION(T, MFIELD, TMODULE) \
template <class Archive> \
void save_construct(Archive& ar, const unsigned int file_version) const \
{ \
@ -209,7 +209,7 @@ extern const std::array<ServiceModuleInfo, 40> service_module_map;
template <class Archive> \
static void load_construct(Archive& ar, T* t, const unsigned int file_version) \
{ \
std::shared_ptr<Module> MFIELD; \
std::shared_ptr<TMODULE> MFIELD; \
ar >> MFIELD; \
::new(t)T(MFIELD); \
} \